/[thuban]/trunk/thuban/Thuban/UI/classifier.py
ViewVC logotype

Diff of /trunk/thuban/Thuban/UI/classifier.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 379 by jonathan, Tue Jan 28 12:54:01 2003 UTC revision 444 by jonathan, Thu Feb 27 16:02:59 2003 UTC
# Line 15  from wxPython.wx import * Line 15  from wxPython.wx import *
15  from wxPython.grid import *  from wxPython.grid import *
16    
17  from Thuban import _  from Thuban import _
18    from Thuban.common import *
19    from Thuban.UI.common import *
20    
21    from Thuban.Model.classification import * #Classification, ClassData
22    
23    from Thuban.Model.color import Color
24    
25    from Thuban.Model.layer import SHAPETYPE_ARC, SHAPETYPE_POLYGON, SHAPETYPE_POINT
26    
27  ID_PROPERTY_SELECT = 4010  ID_PROPERTY_SELECT = 4010
28  ID_CLASS_TABLE = 40011  ID_CLASS_TABLE = 40011
29    
30  ID_CLASSIFY_OK = 4001  ID_CLASSIFY_OK = 4001
31  ID_CLASSIFY_CANCEL = 4002  ID_CLASSIFY_CANCEL = 4002
32    ID_CLASSIFY_ADD = 4003
33    ID_CLASSIFY_GENRANGE = 4004
34    
35    COL_VISUAL = 0
36    COL_VALUE  = 1
37    COL_LABEL  = 2
38    
39    #
40    # this is a silly work around to ensure that the table that is
41    # passed into SetTable is the same that is returned by GetTable
42    #
43    import weakref
44    class ClassGrid(wxGrid):
45    
46        def __init__(self, parent, layer):
47            wxGrid.__init__(self, parent, ID_CLASS_TABLE, size = (300, 150))
48            self.SetTable(
49                ClassTable(layer.GetClassification(), layer.ShapeType(), self),
50                true)
51    
52        def SetCellRenderer(self, row, col):
53            raise ValueError(_("Must not allow setting of renderer in ClassGrid!"))
54    
55        def SetTable(self, object, *attributes):
56            self.tableRef = weakref.ref(object)
57            return wxGrid.SetTable(self, object, *attributes)
58    
59        def GetTable(self):
60            return self.tableRef()
61    
62    
63  class ClassTable(wxPyGridTableBase):  class ClassTable(wxPyGridTableBase):
64    
65      def __init__(self, clinfo):      NUM_COLS = 3
66    
67        __col_labels = [_("Visual"), _("Value"), _("Label")]
68    
69        def __init__(self, clazz, shapeType, view = None):
70          wxPyGridTableBase.__init__(self)          wxPyGridTableBase.__init__(self)
71          self.clinfo = copy.deepcopy(clinfo)          self.SetView(view)
72            self.tdata = []
73    
74            self.Reset(clazz, shapeType)
75    
76        def Reset(self, clazz, shapeType):
77    
78            self.GetView().BeginBatch()
79    
80            self.shapeType = shapeType
81            self.renderer = ClassRenderer(self.shapeType)
82    
83            old_tdata = self.tdata
84    
85          self.tdata = []          self.tdata = []
86    
87          for value, data in self.clinfo.points.items():          if clazz is None:
88              self.tdata.append([data, value])              clazz = Classification()
89    
90          for range in self.clinfo.ranges:  #       p = clazz.GetDefaultGroup()
91              self.tdata.append([range[2], '%s-%s' % range[0], range[1]])  #       np = ClassDataDefault(classData = p)
92    #       self.tdata.append([np, 'DEFAULT', np.GetLabel()])
93    
94    #       for p in clazz.points.values():
95    #           np = ClassDataPoint(p.GetValue(), classData = p)
96    #           self.tdata.append([np, np.GetValue(), np.GetLabel()])
97    
98    #       for p in clazz.ranges:
99    #           np = ClassDataRange(p.GetMin(), p.GetMax(), classData = p)
100    #           self.tdata.append([np,
101    #                              '%s - %s' % (np.GetMin(), np.GetMax()),
102    #                              np.GetLabel()])
103    
104            i = 0
105            for p in clazz:
106                np = copy.copy(p)
107                self.__SetRow(i, np)
108                i += 1
109    
         self.SetColLabelValue(1, _("Data Values"))  
110    
111            self.modified = 0
112    
113            #
114            # silly message processing for updates to the number of
115            # rows and columns
116            #
117            curRows = len(old_tdata)
118            newRows = len(self.tdata)
119            if newRows > curRows:
120                msg = wxGridTableMessage(self,
121                            wxGRIDTABLE_NOTIFY_ROWS_APPENDED,
122                            newRows - curRows)    # how many
123                self.GetView().ProcessTableMessage(msg)
124            elif newRows < curRows:
125                msg = wxGridTableMessage(self,
126                            wxGRIDTABLE_NOTIFY_ROWS_DELETED,
127                            curRows - newRows,    # position
128                            curRows - newRows)    # how many
129                self.GetView().ProcessTableMessage(msg)
130    
131            self.GetView().EndBatch()
132    
133        def __SetRow(self, row, group):
134    
135            if isinstance(group, ClassGroupDefault):
136                data = [group, 'DEFAULT', group.GetLabel()]
137            elif isinstance(group, ClassGroupSingleton):
138                data = [group, group.GetValue(), group.GetLabel()]
139            elif isinstance(group, ClassGroupRange):
140                data = [group,
141                        '%s - %s' % (group.GetMin(), group.GetMax()),
142                        group.GetLabel()]
143    
144            if row >= len(self.tdata):
145                self.tdata.append(data)
146            else:
147                self.tdata[row] = data
148    
149        def GetColLabelValue(self, col):
150            return self.__col_labels[col]
151    
152        def GetRowLabelValue(self, row):
153            data = self.tdata[row][COL_VISUAL]
154            if isinstance(data, ClassGroupDefault): return _("Default")
155            if isinstance(data, ClassGroupSingleton): return _("Singleton")
156            if isinstance(data, ClassGroupRange): return _("Range")
157            if isinstance(data, ClassGroupMap): return _("Map")
158    
159      def GetNumberRows(self):      def GetNumberRows(self):
160          return len(self.tdata)          return len(self.tdata)
161    
162      def GetNumberCols(self):      def GetNumberCols(self):
163          return 2          return self.NUM_COLS
164    
165      def IsEmptyCell(self, row, col):      def IsEmptyCell(self, row, col):
166          return false          return 0
167    
168      def GetValue(self, row, col):      def GetValue(self, row, col):
169          return self.tdata[row][col]          return self.GetValueAsCustom(row, col, "")
170    
171      def SetValue(self, row, col, value):      def SetValue(self, row, col, value):
172          pass          self.SetValueAsCustom(row, col, "", value)
173                self.__Modified()
174          
175        def GetValueAsCustom(self, row, col, typeName):
176            return self.tdata[row][col]
177    
178        def __ParseInput(self, value):
179            """Try to determine what kind of input value is
180               (a single number or a range)
181            """
182    
183            #
184            # first try to take the input as a single number
185            # if there's an exception try to break it into
186            # a range seperated by a '-'. take care to ignore
187            # a leading '-' as that could be for a negative number.
188            # then try to parse the individual parts. if there
189            # is an exception here, let it pass up to the calling
190            # function.
191            #
192            try:
193                return (Str2Num(value),)
194            except:
195                i = value.find('-')
196                if i == 0:
197                    i = value.find('-', 1)
198    
199                return (Str2Num(value[:i]), Str2Num(value[i+1:]))
200                
201    
202        def SetValueAsCustom(self, row, col, typeName, value):
203            data = self.tdata[row][COL_VISUAL]
204    
205            if col == COL_VISUAL:
206                self.tdata[row][COL_VISUAL] = value
207            elif col == COL_VALUE:
208                if row != 0: # DefaultData row
209    
210                    if isinstance(data, ClassGroupMap):
211                        # something special
212                        pass
213                    else: # POINT, RANGE
214                        try:
215                            dataInfo = self.__ParseInput(value)
216                        except: pass
217                            # bad input, ignore the request
218                        else:
219    
220                            ndata = data
221                            if len(dataInfo) == 1:
222                                if not isinstance(data, ClassGroupSingleton):
223                                    ndata = ClassGroupSingleton(prop = data)
224                                ndata.SetValue(dataInfo[0])
225                            elif len(dataInfo) == 2:
226                                if not isinstance(data, ClassGroupRange):
227                                    data = ClassDataRange(classData = data)
228                                data.SetRange(dataInfo[0], dataInfo[1])
229    
230                            ndata.SetLabel(data.GetLabel())
231                            self.__SetRow(row, ndata)
232    
233                            #self.tdata[row][COL_VISUAL] = data
234    
235                            self.GetView().Refresh()
236    
237            elif col == COL_LABEL:
238                data.SetLabel(value)
239                self.tdata[row][COL_LABEL] = data.GetLabel()
240            else:
241                raise ValueError(_("Invalid column request"))
242    
243            self.__Modified()
244    
245        def GetAttr(self, row, col, someExtraParameter):
246            attr = wxGridCellAttr()
247            #attr = wxPyGridTableBase.GetAttr(self, row, col, someExtraParameter)
248    
249            if col == COL_VISUAL:
250                attr.SetRenderer(ClassRenderer(self.shapeType))
251                attr.SetReadOnly()
252    
253            return attr
254    
255        def GetClassGroup(self, row):
256            return self.tdata[row][COL_VISUAL]
257    
258        def __Modified(self):
259            self.modified = 1
260    
261        def IsModified(self):
262            return self.modified
263    
264        def AddNewDataRow(self):
265            np = ClassDataPoint()
266            self.tdata.append([np, np.GetValue(), np.GetLabel()])
267            msg = wxGridTableMessage(self, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1)
268            self.GetView().ProcessTableMessage(msg)
269            self.GetView().Refresh()
270    
271  class Classifier(wxDialog):  class Classifier(wxDialog):
272            
# Line 61  class Classifier(wxDialog): Line 274  class Classifier(wxDialog):
274          wxDialog.__init__(self, parent, -1, _("Classify"),          wxDialog.__init__(self, parent, -1, _("Classify"),
275                            style = wxRESIZE_BORDER)                            style = wxRESIZE_BORDER)
276    
277            self.layer = layer
278    
279          topBox = wxBoxSizer(wxVERTICAL)          topBox = wxBoxSizer(wxVERTICAL)
280    
281            topBox.Add(wxStaticText(self, -1, _("Layer: %s") % layer.Title()),
282                0, wxALIGN_LEFT | wxBOTTOM, 4)
283            topBox.Add(wxStaticText(self, -1, _("Type: %s") % layer.ShapeType()),
284                0, wxALIGN_LEFT | wxBOTTOM, 4)
285    
286          propertyBox = wxBoxSizer(wxHORIZONTAL)          propertyBox = wxBoxSizer(wxHORIZONTAL)
287          propertyBox.Add(wxStaticText(self, -1, _("Property")),          propertyBox.Add(wxStaticText(self, -1, _("Property: ")),
288              0, wxALIGN_CENTER | wxALL, 4)              0, wxALIGN_CENTER | wxALL, 4)
289    
290          self.properties = wxComboBox(self, ID_PROPERTY_SELECT, "",          self.properties = wxComboBox(self, ID_PROPERTY_SELECT, "",
291                                       style = wxCB_READONLY)                                       style = wxCB_READONLY)
292    
293          self.num_cols = layer.table.field_count()          self.num_cols = layer.table.field_count()
294          cur_hilight = 0          # just assume the first field in case one hasn't been
295            # specified in the file.
296            self.__cur_prop = 0
297            field = layer.GetClassification().GetField()
298          for i in range(self.num_cols):          for i in range(self.num_cols):
299              type, name, len, decc = layer.table.field_info(i)              type, name, len, decc = layer.table.field_info(i)
300              if name == layer.classification.field:              if name == field:
301                  cur_hilight = i                  self.__cur_prop = i
302              self.properties.Append(name)              self.properties.Append(name)
303                self.properties.SetClientData(i, None)
304    
305          self.properties.SetSelection(cur_hilight)          self.properties.SetSelection(self.__cur_prop)
306          propertyBox.Add(self.properties, 0, wxGROW, 4)          propertyBox.Add(self.properties, 1, wxGROW|wxALL, 0)
307          EVT_COMBOBOX(self, ID_PROPERTY_SELECT, self.OnPropertySelect)          EVT_COMBOBOX(self, ID_PROPERTY_SELECT, self.OnPropertySelect)
308    
309          topBox.Add(propertyBox, 0, wxGROW, 4)          topBox.Add(propertyBox, 0, wxGROW, 4)
# Line 88  class Classifier(wxDialog): Line 312  class Classifier(wxDialog):
312          # Classification data table          # Classification data table
313          #          #
314    
315          self.classTable = wxGrid(self, ID_CLASS_TABLE, size=(300, 150))          controlBox = wxBoxSizer(wxHORIZONTAL)
316            self.classGrid = ClassGrid(self, layer)
317    
318          table = ClassTable(layer.classification)          controlBox.Add(self.classGrid, 1, wxGROW, 0)
         self.classTable.SetTable(table, true)  
319    
320          topBox.Add(self.classTable, 0, wxGROW, 0)          controlButtonBox = wxBoxSizer(wxVERTICAL)
321            controlButtonBox.Add(wxButton(self, ID_CLASSIFY_ADD,
322                _("Add")), 0, wxGROW | wxALL, 4)
323            controlButtonBox.Add(wxButton(self, ID_CLASSIFY_GENRANGE,
324                _("Generate Ranges")), 0, wxGROW | wxALL, 4)
325    
326            controlBox.Add(controlButtonBox, 0, wxGROW, 10)
327            topBox.Add(controlBox, 1, wxGROW, 10)
328    
329            EVT_BUTTON(self, ID_CLASSIFY_ADD, self.OnAdd)
330            EVT_BUTTON(self, ID_CLASSIFY_GENRANGE, self.OnGenRange)
331            EVT_GRID_CELL_LEFT_DCLICK(self.classGrid, self.OnCellDClick)
332    
333          #          #
334          # Control buttons:          # Control buttons:
# Line 113  class Classifier(wxDialog): Line 348  class Classifier(wxDialog):
348          topBox.Fit(self)          topBox.Fit(self)
349          topBox.SetSizeHints(self)          topBox.SetSizeHints(self)
350    
351      def OnPropertySelect(self, event): pass      def __BuildClassification(self, prop):
352    
353            clazz = Classification()
354            clazz.SetField(self.properties.GetStringSelection())
355    
356            numRows = self.classGrid.GetNumberRows()
357    
358            if numRows > 0:
359                table = self.classGrid.GetTable()
360                clazz.SetDefaultGroup(table.GetClassGroup(0))
361    
362                for i in range(1, numRows):
363                    clazz.AddGroup(table.GetClassGroup(i))
364    
365            return clazz
366    
367        def OnPropertySelect(self, event):
368            self.properties.SetClientData(
369                self.__cur_prop, self.__BuildClassification(self.__cur_prop))
370    
371            self.__cur_prop = self.properties.GetSelection()
372            clazz = self.properties.GetClientData(self.__cur_prop)
373            table = self.classGrid.GetTable()
374    
375            table.Reset(clazz, self.layer.ShapeType())
376    
377      def OnOK(self, event):      def OnOK(self, event):
378            """Put the data from the table into a new Classification and hand
379               it to the layer.
380            """
381    
382            clazz = self.properties.GetClientData(self.__cur_prop)
383    
384            #
385            # only build the classification if there wasn't one to
386            # to begin with or it has been modified
387            #
388            if clazz is None or self.classGrid.GetTable().IsModified():
389                clazz = self.__BuildClassification(self.__cur_prop)
390    
391            clazz.SetLayer(self.layer)
392    
393            self.layer.SetClassification(clazz)
394    
395          self.EndModal(wxID_OK)          self.EndModal(wxID_OK)
396    
397      def OnCancel(self, event):      def OnCancel(self, event):
398            """Do nothing. The layer's current classification stays the same."""
399          self.EndModal(wxID_CANCEL)          self.EndModal(wxID_CANCEL)
400    
401    
402        def OnAdd(self, event):
403            self.classGrid.GetTable().AddNewDataRow()
404            print "Classifier.OnAdd()"
405    
406        def OnGenRange(self, event):
407            print "Classifier.OnGenRange()"
408    
409        def OnCellDClick(self, event):
410            r = event.GetRow()
411            c = event.GetCol()
412            if c == COL_VISUAL:
413                # XXX: getting the properties is only possible with non-Maps!!!
414                group = self.classGrid.GetTable().GetValueAsCustom(r, c, None)
415                prop = group.GetProperties()
416                propDlg = SelectPropertiesDialog(NULL, prop, self.layer.ShapeType())
417                if propDlg.ShowModal() == wxID_OK:
418                    new_prop = propDlg.GetClassGroupProperties()
419                    prop.SetStroke(new_prop.GetStroke())
420                    prop.SetStrokeWidth(new_prop.GetStrokeWidth())
421                    prop.SetFill(new_prop.GetFill())
422                    self.classGrid.Refresh()
423                propDlg.Destroy()
424    
425    
426    ID_SELPROP_OK = 4001
427    ID_SELPROP_CANCEL = 4002
428    ID_SELPROP_SPINCTRL = 4002
429    ID_SELPROP_PREVIEW = 4003
430    ID_SELPROP_STROKECLR = 4004
431    ID_SELPROP_FILLCLR = 4005
432    
433    class SelectPropertiesDialog(wxDialog):
434    
435        def __init__(self, parent, prop, shapeType):
436            wxDialog.__init__(self, parent, -1, _("Select Properties"),
437                              style = wxRESIZE_BORDER)
438    
439            self.prop = ClassGroupProperties(prop)
440    
441            topBox = wxBoxSizer(wxVERTICAL)
442    
443            itemBox = wxBoxSizer(wxHORIZONTAL)
444    
445            # preview box
446            previewBox = wxBoxSizer(wxVERTICAL)
447            previewBox.Add(wxStaticText(self, -1, _("Preview:")),
448                0, wxALIGN_LEFT | wxALL, 4)
449            self.previewer = ClassDataPreviewer(None, self.prop, shapeType,
450                                                self, ID_SELPROP_PREVIEW, (40, 40))
451            previewBox.Add(self.previewer, 1, wxGROW, 15)
452    
453            itemBox.Add(previewBox, 1, wxALIGN_LEFT | wxALL | wxGROW, 0)
454    
455            # control box
456            ctrlBox = wxBoxSizer(wxVERTICAL)
457            ctrlBox.Add(
458                wxButton(self, ID_SELPROP_STROKECLR, "Change Stroke Color"),
459                0, wxALIGN_CENTER_HORIZONTAL | wxALL | wxGROW, 4)
460            EVT_BUTTON(self, ID_SELPROP_STROKECLR, self.OnChangeStrokeColor)
461    
462            if shapeType != SHAPETYPE_ARC:
463                ctrlBox.Add(
464                    wxButton(self, ID_SELPROP_FILLCLR, "Change Fill Color"),
465                    0, wxALIGN_LEFT | wxALL | wxGROW, 4)
466                EVT_BUTTON(self, ID_SELPROP_FILLCLR, self.OnChangeFillColor)
467    
468            spinBox = wxBoxSizer(wxHORIZONTAL)
469            spinBox.Add(wxStaticText(self, -1, _("Stroke Width: ")),
470                    0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 4)
471            self.spinCtrl = wxSpinCtrl(self, ID_SELPROP_SPINCTRL,
472                                       min=1, max=10,
473                                       value=str(prop.GetStrokeWidth()),
474                                       initial=prop.GetStrokeWidth())
475    
476            EVT_SPINCTRL(self, ID_SELPROP_SPINCTRL, self.OnSpin)
477    
478            spinBox.Add(self.spinCtrl, 0, wxALIGN_LEFT | wxALL, 4)
479    
480            ctrlBox.Add(spinBox, 0, wxALIGN_RIGHT | wxALL, 0)
481            itemBox.Add(ctrlBox, 0, wxALIGN_RIGHT | wxALL | wxGROW, 0)
482            topBox.Add(itemBox, 1, wxALIGN_LEFT | wxALL | wxGROW, 0)
483    
484    
485            #
486            # Control buttons:
487            #
488            buttonBox = wxBoxSizer(wxHORIZONTAL)
489            buttonBox.Add(wxButton(self, ID_CLASSIFY_OK, _("OK")),
490                          0, wxALL, 4)
491            buttonBox.Add(wxButton(self, ID_CLASSIFY_CANCEL, _("Cancel")),
492                          0, wxALL, 4)
493            topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_BOTTOM, 10)
494                                                                                    
495            EVT_BUTTON(self, ID_SELPROP_OK, self.OnOK)
496            EVT_BUTTON(self, ID_SELPROP_CANCEL, self.OnCancel)
497                                                                                    
498            self.SetAutoLayout(true)
499            self.SetSizer(topBox)
500            topBox.Fit(self)
501            topBox.SetSizeHints(self)
502    
503        def OnOK(self, event):
504            self.EndModal(wxID_OK)
505    
506        def OnCancel(self, event):
507            self.EndModal(wxID_CANCEL)
508    
509        def OnSpin(self, event):
510            self.prop.SetStrokeWidth(self.spinCtrl.GetValue())
511            self.previewer.Refresh()
512    
513        def __GetColor(self, cur):
514            dialog = wxColourDialog(self)
515            dialog.GetColourData().SetColour(Color2wxColour(cur))
516            ret = None
517            if dialog.ShowModal() == wxID_OK:
518                ret = wxColour2Color(dialog.GetColourData().GetColour())
519    
520            dialog.Destroy()
521    
522            return ret
523            
524        def OnChangeStrokeColor(self, event):
525            clr = self.__GetColor(self.prop.GetStroke())
526            if clr is not None:
527                self.prop.SetStroke(clr)
528            self.previewer.Refresh() # XXX: work around, see ClassDataPreviewer
529    
530        def OnChangeFillColor(self, event):
531            clr = self.__GetColor(self.prop.GetFill())
532            if clr is not None:
533                self.prop.SetFill(clr)
534            self.previewer.Refresh() # XXX: work around, see ClassDataPreviewer
535    
536        def GetClassGroupProperties(self):
537            return self.prop
538    
539    
540    class ClassDataPreviewer(wxWindow):
541    
542        def __init__(self, rect, prop, shapeType,
543                           parent = None, id = -1, size = wxDefaultSize):
544            if parent is not None:
545                wxWindow.__init__(self, parent, id, size=size)
546                EVT_PAINT(self, self.OnPaint)
547    
548            self.rect = rect
549            self.prop = prop
550            self.shapeType = shapeType
551    
552        def OnPaint(self, event):
553            dc = wxPaintDC(self)
554    
555            # XXX: this doesn't seem to be having an effect:
556            dc.DestroyClippingRegion()
557    
558            self.Draw(dc, None)
559    
560        def Draw(self, dc, rect, prop = None, shapeType = None):
561    
562            if prop is None: prop = self.prop
563            if shapeType is None: shapeType = self.shapeType
564    
565            if rect is None:
566                x = y = 0
567                w, h = self.GetClientSizeTuple()
568            else:
569                x = rect.GetX()
570                y = rect.GetY()
571                w = rect.GetWidth()
572                h = rect.GetHeight()
573    
574            stroke = prop.GetStroke()
575            if stroke is Color.None:
576                pen = wxTRANSPARENT_PEN
577            else:
578                pen = wxPen(Color2wxColour(stroke),
579                            prop.GetStrokeWidth(),
580                            wxSOLID)
581    
582            stroke = prop.GetFill()
583            if stroke is Color.None:
584                brush = wxTRANSPARENT_BRUSH
585            else:
586                brush = wxBrush(Color2wxColour(stroke), wxSOLID)
587    
588            dc.SetPen(pen)
589            dc.SetBrush(brush)
590    
591            if shapeType == SHAPETYPE_ARC:
592                dc.DrawSpline([wxPoint(x, y + h),
593                               wxPoint(x + w/2, y + h/4),
594                               wxPoint(x + w/2, y + h/4*3),
595                               wxPoint(x + w, y)])
596    
597            elif shapeType == SHAPETYPE_POINT or \
598                 shapeType == SHAPETYPE_POLYGON:
599    
600                dc.DrawCircle(x + w/2, y + h/2,
601                              (min(w, h) - prop.GetStrokeWidth())/2)
602    
603    class ClassRenderer(wxPyGridCellRenderer):
604    
605        def __init__(self, shapeType):
606            wxPyGridCellRenderer.__init__(self)
607            self.previewer = ClassDataPreviewer(None, None, shapeType)
608    
609        def Draw(self, grid, attr, dc, rect, row, col, isSelected):
610            data = grid.GetTable().GetValueAsCustom(row, col, "")
611    
612    
613            dc.SetClippingRegion(rect.GetX(), rect.GetY(),
614                                 rect.GetWidth(), rect.GetHeight())
615            dc.SetPen(wxPen(wxLIGHT_GREY))
616            dc.SetBrush(wxBrush(wxLIGHT_GREY, wxSOLID))
617            dc.DrawRectangle(rect.GetX(), rect.GetY(),
618                             rect.GetWidth(), rect.GetHeight())
619    
620            if not isinstance(data, ClassGroupMap):
621                self.previewer.Draw(dc, rect, data.GetProperties())
622    
623            if isSelected:
624                dc.SetPen(wxPen(wxColour(0 * 255, 0 * 255, 0 * 255),
625                          4, wxSOLID))
626                dc.SetBrush(wxTRANSPARENT_BRUSH)
627                dc.DrawRectangle(rect.GetX(), rect.GetY(),
628                                 rect.GetWidth(), rect.GetHeight())
629    
630            dc.DestroyClippingRegion()
631    

Legend:
Removed from v.379  
changed lines
  Added in v.444

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26