18 |
from Thuban.Model.table import FIELDTYPE_INT, FIELDTYPE_DOUBLE, \ |
from Thuban.Model.table import FIELDTYPE_INT, FIELDTYPE_DOUBLE, \ |
19 |
FIELDTYPE_STRING, table_to_dbf, table_to_csv |
FIELDTYPE_STRING, table_to_dbf, table_to_csv |
20 |
import view |
import view |
21 |
from dialogs import NonModalDialog |
from dialogs import NonModalNonParentDialog |
22 |
from messages import SHAPES_SELECTED |
|
23 |
|
from messages import SHAPES_SELECTED, SESSION_REPLACED |
24 |
|
from Thuban.Model.messages import TABLE_REMOVED |
25 |
|
|
26 |
wx_value_type_map = {FIELDTYPE_INT: wxGRID_VALUE_NUMBER, |
wx_value_type_map = {FIELDTYPE_INT: wxGRID_VALUE_NUMBER, |
27 |
FIELDTYPE_DOUBLE: wxGRID_VALUE_FLOAT, |
FIELDTYPE_DOUBLE: wxGRID_VALUE_FLOAT, |
102 |
return self.CanGetValueAs(row, col, typeName) |
return self.CanGetValueAs(row, col, typeName) |
103 |
|
|
104 |
|
|
105 |
|
|
106 |
|
class NullRenderer(wxPyGridCellRenderer): |
107 |
|
|
108 |
|
"""Renderer that draws NULL as a gray rectangle |
109 |
|
|
110 |
|
Other values are delegated to a normal renderer which is given as |
111 |
|
the parameter to the constructor. |
112 |
|
""" |
113 |
|
|
114 |
|
def __init__(self, non_null_renderer): |
115 |
|
wxPyGridCellRenderer.__init__(self) |
116 |
|
self.non_null_renderer = non_null_renderer |
117 |
|
|
118 |
|
def Draw(self, grid, attr, dc, rect, row, col, isSelected): |
119 |
|
value = grid.table.GetValue(row, col) |
120 |
|
if value is None: |
121 |
|
dc.SetBackgroundMode(wxSOLID) |
122 |
|
dc.SetBrush(wxBrush(wxColour(192, 192, 192), wxSOLID)) |
123 |
|
dc.SetPen(wxTRANSPARENT_PEN) |
124 |
|
dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height) |
125 |
|
else: |
126 |
|
self.non_null_renderer.Draw(grid, attr, dc, rect, row, col, |
127 |
|
isSelected) |
128 |
|
|
129 |
|
def GetBestSize(self, grid, attr, dc, row, col): |
130 |
|
self.non_null_renderer.GetBestSize(grid, attr, dc, row, col) |
131 |
|
|
132 |
|
def Clone(self): |
133 |
|
return NullRenderer(self.non_null_renderer) |
134 |
|
|
135 |
|
|
136 |
class TableGrid(wxGrid, Publisher): |
class TableGrid(wxGrid, Publisher): |
137 |
|
|
138 |
"""A grid view for a Thuban table |
"""A grid view for a Thuban table |
168 |
|
|
169 |
self.SetSelectionMode(wxGrid.wxGridSelectRows) |
self.SetSelectionMode(wxGrid.wxGridSelectRows) |
170 |
|
|
|
#EVT_GRID_RANGE_SELECT(self, None) |
|
|
#EVT_GRID_SELECT_CELL(self, None) |
|
|
#EVT_GRID_RANGE_SELECT(self, self.OnRangeSelect) |
|
|
#EVT_GRID_SELECT_CELL(self, self.OnSelectCell) |
|
|
|
|
171 |
self.ToggleEventListeners(True) |
self.ToggleEventListeners(True) |
172 |
|
|
173 |
|
# Replace the normal renderers with our own versions which |
174 |
|
# render NULL/None values specially |
175 |
|
self.RegisterDataType(wxGRID_VALUE_STRING, |
176 |
|
NullRenderer(wxGridCellStringRenderer()), None) |
177 |
|
self.RegisterDataType(wxGRID_VALUE_NUMBER, |
178 |
|
NullRenderer(wxGridCellNumberRenderer()), None) |
179 |
|
self.RegisterDataType(wxGRID_VALUE_FLOAT, |
180 |
|
NullRenderer(wxGridCellFloatRenderer()), None) |
181 |
|
|
182 |
def SetTableObject(self, table): |
def SetTableObject(self, table): |
183 |
self.table.SetTable(table) |
self.table.SetTable(table) |
184 |
|
|
273 |
self.allow_messages() |
self.allow_messages() |
274 |
|
|
275 |
|
|
276 |
class TableFrame(NonModalDialog): |
class TableFrame(NonModalNonParentDialog): |
277 |
|
|
278 |
"""Frame that displays a Thuban table in a grid view""" |
"""Frame that displays a Thuban table in a grid view""" |
279 |
|
|
280 |
def __init__(self, parent, name, title, table): |
def __init__(self, parent, name, title, table): |
281 |
NonModalDialog.__init__(self, parent, name, title) |
NonModalNonParentDialog.__init__(self, parent, name, title) |
282 |
self.table = table |
self.table = table |
283 |
self.grid = self.make_grid(self.table) |
self.grid = self.make_grid(self.table) |
284 |
|
self.app = self.parent.application |
285 |
|
self.app.Subscribe(SESSION_REPLACED, self.close_on_session_replaced) |
286 |
|
self.session = self.app.Session() |
287 |
|
self.session.Subscribe(TABLE_REMOVED, self.close_on_table_removed) |
288 |
|
|
289 |
def make_grid(self, table): |
def make_grid(self, table): |
290 |
"""Return the table grid to use in the frame. |
"""Return the table grid to use in the frame. |
294 |
""" |
""" |
295 |
return TableGrid(self, table) |
return TableGrid(self, table) |
296 |
|
|
297 |
|
def OnClose(self, event): |
298 |
|
self.app.Unsubscribe(SESSION_REPLACED, self.close_on_session_replaced) |
299 |
|
self.session.Unsubscribe(TABLE_REMOVED, self.close_on_table_removed) |
300 |
|
NonModalNonParentDialog.OnClose(self, event) |
301 |
|
|
302 |
|
def close_on_session_replaced(self, *args): |
303 |
|
"""Subscriber for the SESSION_REPLACED messages. |
304 |
|
|
305 |
|
The table frame is tied to a session so close the window when |
306 |
|
the session changes. |
307 |
|
""" |
308 |
|
self.Close() |
309 |
|
|
310 |
|
def close_on_table_removed(self, table): |
311 |
|
"""Subscriber for the TABLE_REMOVED messages. |
312 |
|
|
313 |
|
The table frame is tied to a particular table so close the |
314 |
|
window when the table is removed. |
315 |
|
""" |
316 |
|
if table is self.table: |
317 |
|
self.Close() |
318 |
|
|
319 |
|
|
320 |
ID_QUERY = 4001 |
ID_QUERY = 4001 |
321 |
ID_EXPORT = 4002 |
ID_EXPORT = 4002 |
325 |
"""Frame that displays a table in a grid view and offers user actions |
"""Frame that displays a table in a grid view and offers user actions |
326 |
selection and export |
selection and export |
327 |
|
|
328 |
A LayerTableFrame is TableFrame whose selection is connected to the |
A QueryTableFrame is TableFrame whose selection is connected to the |
329 |
selected object in a map. |
selected object in a map. |
330 |
""" |
""" |
331 |
|
|
358 |
|
|
359 |
topBox = wxBoxSizer(wxVERTICAL) |
topBox = wxBoxSizer(wxVERTICAL) |
360 |
|
|
361 |
sizer = wxStaticBoxSizer(wxStaticBox(self, -1, _("Selection")), |
sizer = wxStaticBoxSizer(wxStaticBox(self, -1, |
362 |
|
_("Selection")), |
363 |
wxHORIZONTAL) |
wxHORIZONTAL) |
364 |
sizer.Add(self.combo_fields, 1, wxEXPAND|wxALL, 4) |
sizer.Add(self.combo_fields, 1, wxEXPAND|wxALL, 4) |
365 |
sizer.Add(self.choice_comp, 0, wxALL, 4) |
sizer.Add(self.choice_comp, 0, wxALL, 4) |
516 |
def OnClose(self, event): |
def OnClose(self, event): |
517 |
"""Override the derived method to first unsubscribed.""" |
"""Override the derived method to first unsubscribed.""" |
518 |
self.parent.Unsubscribe(SHAPES_SELECTED, self.select_shapes) |
self.parent.Unsubscribe(SHAPES_SELECTED, self.select_shapes) |
519 |
|
self.grid.Unsubscribe(ROW_SELECTED, self.rows_selected) |
520 |
QueryTableFrame.OnClose(self, event) |
QueryTableFrame.OnClose(self, event) |
521 |
|
|
522 |
def select_shapes(self, layer, shapes): |
def select_shapes(self, layer, shapes): |