/[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 392 by jonathan, Mon Feb 10 15:26:30 2003 UTC revision 415 by jonathan, Wed Feb 19 16:52:51 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    
20  from Thuban.Model.classification import Classification  from Thuban.Model.classification import * #Classification, ClassData
21    
22    from Thuban.Model.color import Color
23    
24  from Thuban.Model.layer import SHAPETYPE_ARC, SHAPETYPE_POLYGON, SHAPETYPE_POINT  from Thuban.Model.layer import SHAPETYPE_ARC, SHAPETYPE_POLYGON, SHAPETYPE_POINT
25    
# Line 25  ID_CLASS_TABLE = 40011 Line 28  ID_CLASS_TABLE = 40011
28    
29  ID_CLASSIFY_OK = 4001  ID_CLASSIFY_OK = 4001
30  ID_CLASSIFY_CANCEL = 4002  ID_CLASSIFY_CANCEL = 4002
31    ID_CLASSIFY_ADD = 4003
32    ID_CLASSIFY_GENRANGE = 4004
33    
34    COL_VISUAL = 0
35    COL_VALUE  = 1
36    COL_LABEL  = 2
37    
38    #
39    # this is a silly work around to ensure that the table that is
40    # passed into SetTable is the same that is returned by GetTable
41    #
42    import weakref
43    class ClassGrid(wxGrid):
44    
45        def __init__(self, parent, layer):
46            wxGrid.__init__(self, parent, ID_CLASS_TABLE, size = (300, 150))
47            self.SetTable(
48                ClassTable(layer.GetClassification(), layer.ShapeType(), self),
49                true)
50    
51        def SetCellRenderer(self, row, col):
52            raise ValueError(_("Must not allow setting of renderer in ClassGrid!"))
53    
54        def SetTable(self, object, *attributes):
55            self.tableRef = weakref.ref(object)
56            return wxGrid.SetTable(self, object, *attributes)
57    
58        def GetTable(self):
59            return self.tableRef()
60    
61    
62  class ClassTable(wxPyGridTableBase):  class ClassTable(wxPyGridTableBase):
63    
64      def __init__(self, clinfo):      NUM_COLS = 3
65    
66        __col_labels = [_("Visual"), _("Value"), _("Label")]
67    
68        # this is tied to the values of classification.ClassData
69        __row_labels = [_("Default"), _("Point"), _("Range"), _("Map")]
70    
71        def __init__(self, clazz, shapeType, view = None):
72          wxPyGridTableBase.__init__(self)          wxPyGridTableBase.__init__(self)
73          self.clinfo = copy.deepcopy(clinfo)          self.SetView(view)
74            self.tdata = []
75    
76            self.Reset(clazz, shapeType)
77    
78        def Reset(self, clazz, shapeType):
79    
80            self.GetView().BeginBatch()
81    
82            self.shapeType = shapeType
83            self.renderer = ClassRenderer(self.shapeType)
84    
85            old_tdata = self.tdata
86    
87          self.tdata = []          self.tdata = []
88    
89          self.tdata.append([self.clinfo.DefaultData, 'DEFAULT'])          if clazz is None:
90                clazz = Classification()
91    
92          for value, data in self.clinfo.points.items():          p = clazz.GetDefaultData()
93              self.tdata.append([data, value])          np = ClassDataPoint(classData = p)
94            self.tdata.append([np, 'DEFAULT', np.GetLabel()])
95    
96            for p in clazz.points.values():
97                np = ClassDataPoint(p.GetValue(), classData = p)
98                self.tdata.append([np, np.GetValue(), np.GetLabel()])
99    
100            for p in clazz.ranges:
101                np = ClassDataRange(p.GetMin(), p.GetMax(), classData = p)
102                self.tdata.append([np,
103                                   '%s - %s' % (np.GetMin(), np.GetMax()),
104                                   np.GetLabel()])
105    
106          for range in self.clinfo.ranges:          self.modified = 0
107              self.tdata.append([range[2], '%s-%s' % range[0], range[1]])  
108            #
109            # silly message processing for updates to the number of
110            # rows and columns
111            #
112            curRows = len(old_tdata)
113            newRows = len(self.tdata)
114            if newRows > curRows:
115                msg = wxGridTableMessage(self,
116                            wxGRIDTABLE_NOTIFY_ROWS_APPENDED,
117                            newRows - curRows)    # how many
118                self.GetView().ProcessTableMessage(msg)
119            elif newRows < curRows:
120                msg = wxGridTableMessage(self,
121                            wxGRIDTABLE_NOTIFY_ROWS_DELETED,
122                            curRows - newRows,    # position
123                            curRows - newRows)    # how many
124                self.GetView().ProcessTableMessage(msg)
125    
126            self.GetView().EndBatch()
127    
128        def GetColLabelValue(self, col):
129            return self.__col_labels[col]
130    
131        def GetRowLabelValue(self, row):
132            data = self.tdata[row][COL_VISUAL]
133            type = data.GetType()
134            return self.__row_labels[type]
135    
         self.SetColLabelValue(1, _("Data Values"))  
   
136      def GetNumberRows(self):      def GetNumberRows(self):
137          return len(self.tdata)          return len(self.tdata)
138    
139      def GetNumberCols(self):      def GetNumberCols(self):
140          return 2          return self.NUM_COLS
141    
142      def IsEmptyCell(self, row, col):      def IsEmptyCell(self, row, col):
143          return false          return 0
144    
145      def GetValue(self, row, col):      def GetValue(self, row, col):
146          return self.tdata[row][col]          return self.GetValueAsCustom(row, col, "")
147    
148      def SetValue(self, row, col, value):      def SetValue(self, row, col, value):
149          self.tdata[row][col] = value          self.SetValueAsCustom(row, col, "", value)
150            self.__Modified()
151          
152      def GetValueAsCustom(self, row, col, typeName):      def GetValueAsCustom(self, row, col, typeName):
153          return self.tdata[row][col]          return self.tdata[row][col]
154    
155        def __ParseInput(self, value):
156            """Try to determine what kind of input value is
157               (a single number or a range)
158            """
159    
160            #
161            # first try to take the input as a single number
162            # if there's an exception try to break it into
163            # a range seperated by a '-'. take care to ignore
164            # a leading '-' as that could be for a negative number.
165            # then try to parse the individual parts. if there
166            # is an exception here, let it pass up to the calling
167            # function.
168            #
169            try:
170                return (ClassData.POINT, Str2Num(value))
171            except:
172                i = value.find('-')
173                if i == 0:
174                    i = value.find('-', 1)
175    
176                return (ClassData.RANGE,
177                        Str2Num(value[:i]),
178                        Str2Num(value[i+1:]))
179                
180    
181        def SetValueAsCustom(self, row, col, typeName, value):
182            data = self.tdata[row][COL_VISUAL]
183    
184            if col == COL_VISUAL:
185                self.tdata[row][COL_VISUAL] = value
186            elif col == COL_VALUE:
187                if row != 0: # DefaultData row
188                    type = data.GetType()
189    
190                    if type == ClassData.MAP:
191                        # something special
192                        pass
193                    else: # POINT, RANGE
194                        try:
195                            dataInfo = self.__ParseInput(value)
196                        except: pass
197                            # bad input, ignore the request
198                        else:
199    
200                            if dataInfo[0] == ClassData.POINT:
201                                if type != ClassData.POINT:
202                                    data = ClassDataPoint(classData = data)
203                                data.SetValue(dataInfo[1])
204                                self.tdata[row][COL_VALUE] = data.GetValue()
205                            elif dataInfo[0] == ClassData.RANGE:
206                                if type != ClassData.RANGE:
207                                    data = ClassDataRange(classData = data)
208                                data.SetRange(dataInfo[1], dataInfo[2])
209                                self.tdata[row][COL_VALUE] = \
210                                    "%s - %s" % (data.GetMin(), data.GetMax())
211    
212                            self.tdata[row][COL_VISUAL] = data
213    
214                            # i just want it to redraw!
215                            self.GetView().BeginBatch()
216                            self.GetView().EndBatch()
217    
218            elif col == COL_LABEL:
219                data.SetLabel(value)
220                self.tdata[row][COL_LABEL] = data.GetLabel()
221            else:
222                raise ValueError(_("Invalid column request"))
223    
224            self.__Modified()
225    
226        def GetAttr(self, row, col, someExtraParameter):
227            attr = wxGridCellAttr()
228            #attr = wxPyGridTableBase.GetAttr(self, row, col, someExtraParameter)
229    
230            if col == COL_VISUAL:
231                attr.SetRenderer(ClassRenderer(self.shapeType))
232                attr.SetReadOnly()
233    
234            return attr
235    
236        def GetClassData(self, row):
237            return self.tdata[row][COL_VISUAL]
238    
239        def __Modified(self):
240            self.modified = 1
241    
242        def IsModified(self):
243            return self.modified
244    
245        def AddNewDataRow(self):
246            np = ClassDataPoint()
247            self.tdata.append([np, np.GetValue(), np.GetLabel()])
248            msg = wxGridTableMessage(self, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, 1)
249            self.GetView().ProcessTableMessage(msg)
250            self.GetView().BeginBatch()
251            self.GetView().EndBatch()
252    
253  class Classifier(wxDialog):  class Classifier(wxDialog):
254            
# Line 69  class Classifier(wxDialog): Line 256  class Classifier(wxDialog):
256          wxDialog.__init__(self, parent, -1, _("Classify"),          wxDialog.__init__(self, parent, -1, _("Classify"),
257                            style = wxRESIZE_BORDER)                            style = wxRESIZE_BORDER)
258    
259            self.layer = layer
260    
261          topBox = wxBoxSizer(wxVERTICAL)          topBox = wxBoxSizer(wxVERTICAL)
262    
263            topBox.Add(wxStaticText(self, -1, _("Layer: %s") % layer.Title()),
264                0, wxALIGN_LEFT | wxBOTTOM, 4)
265            topBox.Add(wxStaticText(self, -1, _("Type: %s") % layer.ShapeType()),
266                0, wxALIGN_LEFT | wxBOTTOM, 4)
267    
268          propertyBox = wxBoxSizer(wxHORIZONTAL)          propertyBox = wxBoxSizer(wxHORIZONTAL)
269          propertyBox.Add(wxStaticText(self, -1, _("Property")),          propertyBox.Add(wxStaticText(self, -1, _("Property: ")),
270              0, wxALIGN_CENTER | wxALL, 4)              0, wxALIGN_CENTER | wxALL, 4)
271    
272          self.properties = wxComboBox(self, ID_PROPERTY_SELECT, "",          self.properties = wxComboBox(self, ID_PROPERTY_SELECT, "",
273                                       style = wxCB_READONLY)                                       style = wxCB_READONLY)
274    
275          self.num_cols = layer.table.field_count()          self.num_cols = layer.table.field_count()
276          cur_hilight = 0          self.__cur_prop = -1
277            field = layer.GetClassification().GetField()
278          for i in range(self.num_cols):          for i in range(self.num_cols):
279              type, name, len, decc = layer.table.field_info(i)              type, name, len, decc = layer.table.field_info(i)
280              if name == layer.classification.field:              if name == field:
281                  cur_hilight = i                  self.__cur_prop = i
282              self.properties.Append(name)              self.properties.Append(name)
283                self.properties.SetClientData(i, None)
284    
285          self.properties.SetSelection(cur_hilight)          self.properties.SetSelection(self.__cur_prop)
286          propertyBox.Add(self.properties, 1, wxGROW, 4)          propertyBox.Add(self.properties, 1, wxGROW|wxALL, 0)
287          EVT_COMBOBOX(self, ID_PROPERTY_SELECT, self.OnPropertySelect)          EVT_COMBOBOX(self, ID_PROPERTY_SELECT, self.OnPropertySelect)
288    
289          topBox.Add(propertyBox, 0, wxGROW, 4)          topBox.Add(propertyBox, 0, wxGROW, 4)
# Line 96  class Classifier(wxDialog): Line 292  class Classifier(wxDialog):
292          # Classification data table          # Classification data table
293          #          #
294    
295          self.classTable = wxGrid(self, ID_CLASS_TABLE, size=(300, 150))          controlBox = wxBoxSizer(wxHORIZONTAL)
296            self.classGrid = ClassGrid(self, layer)
297    
298          table = ClassTable(layer.classification)          controlBox.Add(self.classGrid, 1, wxGROW, 0)
         self.classTable.SetTable(table, true)  
         self.classTable.EnableEditing(false)  
         cr = ClassRenderer(layer.ShapeType())  
         for i in range(self.classTable.GetNumberRows()):  
             self.classTable.SetCellRenderer(i, 0, cr)  
299    
300          topBox.Add(self.classTable, 1, wxGROW, 0)          controlButtonBox = wxBoxSizer(wxVERTICAL)
301            controlButtonBox.Add(wxButton(self, ID_CLASSIFY_ADD,
302                _("Add")), 0, wxGROW | wxALL, 4)
303            controlButtonBox.Add(wxButton(self, ID_CLASSIFY_GENRANGE,
304                _("Generate Ranges")), 0, wxGROW | wxALL, 4)
305    
306            controlBox.Add(controlButtonBox, 0, wxGROW, 10)
307            topBox.Add(controlBox, 1, wxGROW, 10)
308    
309            EVT_BUTTON(self, ID_CLASSIFY_ADD, self.OnAdd)
310            EVT_BUTTON(self, ID_CLASSIFY_GENRANGE, self.OnGenRange)
311            EVT_GRID_CELL_LEFT_DCLICK(self.classGrid, self.OnCellDClick)
312    
313          #          #
314          # Control buttons:          # Control buttons:
# Line 125  class Classifier(wxDialog): Line 328  class Classifier(wxDialog):
328          topBox.Fit(self)          topBox.Fit(self)
329          topBox.SetSizeHints(self)          topBox.SetSizeHints(self)
330    
331      def OnPropertySelect(self, event): pass      def __BuildClassification(self, prop):
332    
333            clazz = Classification()
334            clazz.SetField(self.properties.GetStringSelection())
335    
336            numRows = self.classGrid.GetNumberRows()
337    
338            if numRows > 0:
339                table = self.classGrid.GetTable()
340                clazz.SetDefaultData(table.GetClassData(0))
341    
342                for i in range(1, numRows):
343                    clazz.AddClassData(table.GetClassData(i))
344    
345            return clazz
346    
347        def OnPropertySelect(self, event):
348            self.properties.SetClientData(
349                self.__cur_prop, self.__BuildClassification(self.__cur_prop))
350    
351            self.__cur_prop = self.properties.GetSelection()
352            clazz = self.properties.GetClientData(self.__cur_prop)
353            table = self.classGrid.GetTable()
354    
355            table.Reset(clazz, self.layer.ShapeType())
356    
357        def OnOK(self, event):
358            """Put the data from the table into a new Classification and hand
359               it to the layer.
360            """
361    
362            clazz = self.properties.GetClientData(self.__cur_prop)
363    
364            #
365            # only build the classification if there wasn't one to
366            # to begin with or it has been modified
367            #
368            if clazz is None or self.classGrid.GetTable().IsModified():
369                clazz = self.__BuildClassification(self.__cur_prop)
370    
371            clazz.SetLayer(self.layer)
372    
373            self.layer.SetClassification(clazz)
374    
375            self.EndModal(wxID_OK)
376    
377        def OnCancel(self, event):
378            """Do nothing. The layer's current classification stays the same."""
379            self.EndModal(wxID_CANCEL)
380    
381    
382        def OnAdd(self, event):
383            self.classGrid.GetTable().AddNewDataRow()
384            print "Classifier.OnAdd()"
385    
386        def OnGenRange(self, event):
387            print "Classifier.OnGenRange()"
388    
389        def OnCellDClick(self, event):
390            r = event.GetRow()
391            c = event.GetCol()
392            if c == COL_VISUAL:
393                prop = self.classGrid.GetTable().GetValueAsCustom(r, c, None)
394                propDlg = SelectPropertiesDialog(NULL, prop, self.layer.ShapeType())
395                if propDlg.ShowModal() == wxID_OK:
396                    new_prop = propDlg.GetClassData()
397                    prop.SetStroke(new_prop.GetStroke())
398                    prop.SetStrokeWidth(new_prop.GetStrokeWidth())
399                    prop.SetFill(new_prop.GetFill())
400                    self.classGrid.BeginBatch()
401                    self.classGrid.EndBatch()
402                propDlg.Destroy()
403    
404    
405    ID_SELPROP_OK = 4001
406    ID_SELPROP_CANCEL = 4002
407    ID_SELPROP_SPINCTRL = 4002
408    
409    class SelectPropertiesDialog(wxDialog):
410    
411        def __init__(self, parent, prop, shapeType):
412            wxDialog.__init__(self, parent, -1, _("Select Properties"),
413                              style = wxRESIZE_BORDER)
414    
415            topBox = wxBoxSizer(wxVERTICAL)
416    
417            self.prop = ClassData(classData = prop)
418    
419            topBox.Add(wxStaticText(self, -1, _("Stroke Color: ")),
420                0, wxALIGN_LEFT | wxALL, 4)
421    
422            spinBox = wxBoxSizer(wxHORIZONTAL)
423            spinBox.Add(wxStaticText(self, -1, _("Stroke Width: ")),
424                    0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxBOTTOM, 4)
425            self.spinCtrl = wxSpinCtrl(self, ID_SELPROP_SPINCTRL,
426                                       min=1, max=10,
427                                       value=str(prop.GetStrokeWidth()),
428                                       initial=prop.GetStrokeWidth())
429    
430            EVT_SPINCTRL(self, ID_SELPROP_SPINCTRL, self.OnSpin)
431    
432            spinBox.Add(self.spinCtrl, 0, wxALIGN_LEFT | wxALL, 4)
433    
434            topBox.Add(spinBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_BOTTOM, 10)
435    
436            if shapeType != SHAPETYPE_ARC:
437                topBox.Add(wxStaticText(self, -1, _("Fill Color: ")),
438                    0, wxALIGN_LEFT | wxBOTTOM, 4)
439    
440            #
441            # Control buttons:
442            #
443            buttonBox = wxBoxSizer(wxHORIZONTAL)
444            buttonBox.Add(wxButton(self, ID_CLASSIFY_OK, _("OK")),
445                          0, wxALL, 4)
446            buttonBox.Add(wxButton(self, ID_CLASSIFY_CANCEL, _("Cancel")),
447                          0, wxALL, 4)
448            topBox.Add(buttonBox, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_BOTTOM, 10)
449                                                                                    
450            EVT_BUTTON(self, ID_SELPROP_OK, self.OnOK)
451            EVT_BUTTON(self, ID_SELPROP_CANCEL, self.OnCancel)
452                                                                                    
453            self.SetAutoLayout(true)
454            self.SetSizer(topBox)
455            topBox.Fit(self)
456            topBox.SetSizeHints(self)
457    
458      def OnOK(self, event):      def OnOK(self, event):
459          self.EndModal(wxID_OK)          self.EndModal(wxID_OK)
460    
461      def OnCancel(self, event):      def OnCancel(self, event):
462          self.EndModal(wxID_CANCEL)          self.EndModal(wxID_CANCEL)
463    
464        def OnSpin(self, event):
465            self.prop.SetStrokeWidth(self.spinCtrl.GetValue())
466    
467  class ClassRenderer(wxPyGridCellRenderer):      def GetClassData(self):
468            return self.prop
469    
     def __init__(self, shapeType):  
         wxPyGridCellRenderer.__init__(self)  
         self.shapeType = shapeType  
470    
471      def Draw(self, grid, attr, dc, rect, row, col, isSelected):  class ClassDataPreviewer:
472          value = grid.GetTable().GetValueAsCustom(row, col, "")  
473          # XXX: check if value is a dictionary      def Draw(self, dc, rect, data, shapeType):
474          stroke = value.GetStroke()  
475          if stroke is None:          stroke = data.GetStroke()
476            if stroke is Color.None:
477              pen = wxTRANSPARENT_PEN              pen = wxTRANSPARENT_PEN
478          else:          else:
479              pen = wxPen(wxColour(stroke.red * 255,              pen = wxPen(wxColour(stroke.red * 255,
480                                   stroke.green * 255,                                   stroke.green * 255,
481                                   stroke.blue * 255),                                   stroke.blue * 255),
482                          value.GetStrokeWidth(),                          data.GetStrokeWidth(),
483                          wxSOLID)                          wxSOLID)
484    
485          stroke = value.GetFill()          stroke = data.GetFill()
486          if stroke is None:          if stroke is Color.None:
487              brush = wxTRANSPARENT_BRUSH              brush = wxTRANSPARENT_BRUSH
488          else:          else:
489              brush = wxBrush(wxColour(stroke.red * 255,              brush = wxBrush(wxColour(stroke.red * 255,
490                                       stroke.green * 255,                                       stroke.green * 255,
491                                       stroke.blue * 255), wxSOLID)                                       stroke.blue * 255), wxSOLID)
492    
         dc.SetClippingRegion(rect.GetX(), rect.GetY(),  
                              rect.GetWidth(), rect.GetHeight())  
         dc.SetPen(wxPen(wxLIGHT_GREY))  
         dc.SetBrush(wxBrush(wxLIGHT_GREY, wxSOLID))  
         dc.DrawRectangle(rect.GetX(), rect.GetY(),  
                          rect.GetWidth(), rect.GetHeight())  
   
493          dc.SetPen(pen)          dc.SetPen(pen)
494          dc.SetBrush(brush)          dc.SetBrush(brush)
495    
496          if self.shapeType == SHAPETYPE_ARC:          if shapeType == SHAPETYPE_ARC:
497              dc.DrawSpline([wxPoint(rect.GetX(), rect.GetY() + rect.GetHeight()),              dc.DrawSpline([wxPoint(rect.GetX(), rect.GetY() + rect.GetHeight()),
498                             wxPoint(rect.GetX() + rect.GetWidth()/2,                             wxPoint(rect.GetX() + rect.GetWidth()/2,
499                                     rect.GetY() + rect.GetHeight()/4),                                     rect.GetY() + rect.GetHeight()/4),
# Line 179  class ClassRenderer(wxPyGridCellRenderer Line 501  class ClassRenderer(wxPyGridCellRenderer
501                                     rect.GetY() + rect.GetHeight()/4*3),                                     rect.GetY() + rect.GetHeight()/4*3),
502                             wxPoint(rect.GetX() + rect.GetWidth(), rect.GetY())])                             wxPoint(rect.GetX() + rect.GetWidth(), rect.GetY())])
503    
504          elif self.shapeType == SHAPETYPE_POINT or self.shapeType == SHAPETYPE_POLYGON:          elif shapeType == SHAPETYPE_POINT or \
505                 shapeType == SHAPETYPE_POLYGON:
506    
507              dc.DrawCircle(rect.GetX() + rect.GetWidth()/2,              dc.DrawCircle(rect.GetX() + rect.GetWidth()/2,
508                            rect.GetY() + rect.GetHeight()/2,                            rect.GetY() + rect.GetHeight()/2,
509                            (min(rect.GetWidth(), rect.GetHeight())                            (min(rect.GetWidth(), rect.GetHeight())
510                             - value.GetStrokeWidth())/2)                             - data.GetStrokeWidth())/2)
511    
512          dc.DestroyClippingRegion()  class ClassRenderer(wxPyGridCellRenderer):
513    
514        def __init__(self, shapeType):
515            wxPyGridCellRenderer.__init__(self)
516            self.shapeType = shapeType
517    
518        def Draw(self, grid, attr, dc, rect, row, col, isSelected):
519            data = grid.GetTable().GetValueAsCustom(row, col, "")
520    
521    
522            dc.SetClippingRegion(rect.GetX(), rect.GetY(),
523                                 rect.GetWidth(), rect.GetHeight())
524            dc.SetPen(wxPen(wxLIGHT_GREY))
525            dc.SetBrush(wxBrush(wxLIGHT_GREY, wxSOLID))
526            dc.DrawRectangle(rect.GetX(), rect.GetY(),
527                             rect.GetWidth(), rect.GetHeight())
528    
529            ClassDataPreviewer().Draw(dc, rect, data, self.shapeType)
530    
531            if isSelected:
532                dc.SetPen(wxPen(wxColour(0 * 255, 0 * 255, 0 * 255),
533                          4, wxSOLID))
534                dc.SetBrush(wxTRANSPARENT_BRUSH)
535                dc.DrawRectangle(rect.GetX(), rect.GetY(),
536                                 rect.GetWidth(), rect.GetHeight())
537    
538            dc.DestroyClippingRegion()
539    

Legend:
Removed from v.392  
changed lines
  Added in v.415

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26