/[papo]/gnue/designer/src/schema/VisualEditor.py
ViewVC logotype

Diff of /gnue/designer/src/schema/VisualEditor.py

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

revision 1.3 by charlie, Tue Aug 27 20:39:55 2002 UTC revision 1.4 by styxman, Fri Nov 8 16:46:03 2002 UTC
# Line 29  Line 29 
29    
30  from wxPython.wx import *  from wxPython.wx import *
31  from VisualTable import *  from VisualTable import *
32    from gnue.common.schema.Objects import *
33    from Incubator import *
34    
35  class VisualEditor (wxPanel):  class VisualEditor (wxPanel):
36    def __init__(self, instance, root, parent):    def __init__(self, instance, root, parent):
37      wxPanel.__init__(self,parent,-1)      wxPanel.__init__(self,parent,-1)
38      self.frame = instance      self.frame = instance
39      self.panelColor = wxWHITE #wxNamedColor("blue") # self.GetBackgroundColour()      self.panelColor = self.GetBackgroundColour()
40      self._instance = instance      self._instance = instance
41      self.rootObject = root      self.rootObject = root
42      self.current = root      self.current = root
43      self._app = instance._app      self._app = instance._app
44      self.dragmode = false      self.dragmode = false
45      self.tables=[]      self.tables=[]
46        self.hasNewObj = false
47      self.rootObject.walk(self.inventoryObject)      self.rootObject.walk(self.inventoryObject)
48    
49      self.diagram=wxScrolledWindow(self, -1,      self.diagram=wxScrolledWindow(self, -1,
50                                    style=wxSUNKEN_BORDER)                                    style=wxSUNKEN_BORDER)
51        self.panelheight=100
52        self.panelwidth=200
53        self.diagram.EnableScrolling(true, true)
54        self.redrawBackground()
55        #self.diagram.SetBackgroundColour(wxWHITE)
56      self.calculateTablePositions()      self.calculateTablePositions()
57            
     #self.diagram.SetBackgroundColour(wxWHITE)  
58            
     self.diagram.EnableScrolling(true, true)  
       
     self.diagram.SetScrollbars(20, 20, self.panelwidth / 20,  
                                self.panelheight / 20)  
59                    
60      EVT_PAINT(self.diagram, self.onPaintEvent)      EVT_PAINT(self.diagram, self.onPaintEvent)
61  #    EVT_LEFT_DOWN(self.diagram, self.onLeftClickEvent)  #    EVT_LEFT_DOWN(self.diagram, self.onLeftClickEvent)
# Line 60  class VisualEditor (wxPanel): Line 63  class VisualEditor (wxPanel):
63      EVT_LEFT_UP(self.diagram, self.onMouseEvent)      EVT_LEFT_UP(self.diagram, self.onMouseEvent)
64      EVT_LEFT_DOWN(self.diagram, self.onMouseEvent)      EVT_LEFT_DOWN(self.diagram, self.onMouseEvent)
65      EVT_LEFT_DCLICK(self.diagram, self.onDoubleClickEvent)      EVT_LEFT_DCLICK(self.diagram, self.onDoubleClickEvent)
66        EVT_RIGHT_DOWN(self.diagram, self.onRightClickEvent)
67    
68      Sizer = wxBoxSizer(wxHORIZONTAL)      Sizer = wxBoxSizer(wxHORIZONTAL)
69      #Sizer.Add(self.toolPalette, 0)      #Sizer.Add(self.toolPalette, 0)
# Line 69  class VisualEditor (wxPanel): Line 73  class VisualEditor (wxPanel):
73      self.SetSizer(Sizer)      self.SetSizer(Sizer)
74    
75    def calculateTablePositions(self):    def calculateTablePositions(self):
76        dc = wxPaintDC(self.diagram)        dc = wxMemoryDC()
77        self.diagram.PrepareDC(dc)        self.diagram.PrepareDC(dc)
78        dc.BeginDrawing()        dc.BeginDrawing()
79        x=10        x=10
# Line 89  class VisualEditor (wxPanel): Line 93  class VisualEditor (wxPanel):
93            y=maxy+10            y=maxy+10
94                    
95        dc.EndDrawing()        dc.EndDrawing()
96        self.panelheight=maxy        self.resizeCanvas(maxx,maxy)
       self.panelwidth=maxx  
97                
98        # Rules for better positioning:        # Rules for better positioning:
99        #   tables with most connections in the middle        #   tables with most connections in the middle
100        #   ...        #   ...
101    
102    
103    def inventoryObject(self, object):    def inventoryObject(self, object):
104      if object._type=="GSTable":      if object._type=="GSTable":
105        self.tables.append(VisualTable(object))        self.tables.append(VisualTable(object))
# Line 106  class VisualEditor (wxPanel): Line 110  class VisualEditor (wxPanel):
110        self.current=object        self.current=object
111        self.onPaintEvent(None)        self.onPaintEvent(None)
112    
113      def findFreePosition(self, x,y,w,h):
114        conflict=true
115        while conflict:
116          conflict=false
117          for i in self.tables:
118            if i.isInRectangle(x,y,x+w,y+h):
119              x=i.xpos+i.width+10
120              if x>500:
121                x=10
122                y=i.ypos+i.height+10
123              conflict=true
124        self.resizeCanvas(x+w,y+h)
125        return (x,y)
126    
127    
128      def resizeCanvas(self,xmax,ymax):
129        # resize canvas
130        if xmax>self.panelwidth:
131          self.panelwidth=xmax+10
132          self.diagram.SetScrollbars(20, 20, self.panelwidth / 20,
133                                     self.panelheight / 20)
134        if ymax>self.panelheight:
135          self.panelheight=ymax+10
136          self.diagram.SetScrollbars(20, 20, self.panelwidth / 20,
137                                    self.panelheight / 20)    
138    
139    
140    def onCreateObject (self, object, handler):    def onCreateObject (self, object, handler):
141      pass      if object._type=="GSTable":
142          self.tables.append(VisualTable(object))
143          self.hasNewObj=true
144          self.refresh()      
145          return
146          vTbl=VisualTable(object)      
147          dc = wxClientDC(self.diagram)
148          self.diagram.PrepareDC(dc)  
149          (w,h)=vTbl.calculateDimensions(dc)
150    
151          # position new Table
152          (x,y)=self.findFreePosition(10,10,w,h)
153          vTbl.moveTo(x,y)
154          
155          self.tables.append(vTbl)
156        if object._type=="GSField":
157          self.hasNewObj=true
158          self.onModifyObject(object,None,None)
159          
160    
161    def onModifyObject (self, object, handler, modifications):    def onModifyObject (self, object, handler, modifications):
162      pass      self.refresh()
163        return
164        tbl=object.findParentOfType('GSTable')
165        if tbl!=None:
166          for i in self.tables:
167            if i.instance==tbl:
168              dc = wxClientDC(self.diagram)
169              self.diagram.PrepareDC(dc)  
170              (w,h)=i.calculateDimensions(dc)
171              # check if still freepos
172              (x,y)=self.findFreePosition(i.xpos,i.ypos,w,h)
173              i.moveTo(x,y)
174              i.drawMe(dc,self.current)
175              return
176    
177      def refresh(self):
178        self.diagram.Refresh(true)  
179    
180    def onDeleteObject (self, object, handler):    def onDeleteObject (self, object, handler):
181      pass      if object._type=="GSTable":
182          # search for GSTable and remove the VisualTable assigned to it
183          for vTbl in self.tables:
184            if vTbl.instance==object:
185              self.tables.remove(vTbl)
186              self.refresh()
187    
188        if object._type=="GSField":
189          # search for GSTable and update corresponding vtable
190          tbl=object.findParentOfType("GSTable")
191          for vTbl in self.tables:
192            if vTbl.instance==tbl:
193              dc = wxMemoryDC()
194              vTbl.calculateDimensions(dc)
195              self.refresh()
196                    
197    
198            
199    def onPaintEvent(self, event, clear=false):    def onPaintEvent(self, event, clear=false):
200          if self.hasNewObj:
201            self.calculateTablePositions()
202            self.hasNewObj=false
203        dc = wxPaintDC(self.diagram)        dc = wxPaintDC(self.diagram)
204        self.diagram.PrepareDC(dc)              self.diagram.PrepareDC(dc)
205        dc.BeginDrawing()        dc.BeginDrawing()
206          #dc.Blit(0,0,self.panelheight,self.panelwidth,self.imagedc,0,0)
207          #dc.EndDrawing()
208          #return
209          #dc.BeginDrawing()
210        if clear:        if clear:
211          dc.SetBackground(wxLIGHT_GREY_BRUSH)          dc.SetBackground(self.panelColor)
212          dc.Clear()          dc.Clear()
213        for vTbl in self.tables:        for vTbl in self.tables:
214          vTbl.drawMe(dc,self.current)          vTbl.drawMe(dc,self.current)
215                        
216        dc.EndDrawing()        dc.EndDrawing()
217    
218      def redrawBackground(self):
219        btm=wxEmptyBitmap(self.panelheight,self.panelwidth,-1)
220        dc=wxMemoryDC()
221        dc.SelectObject(btm);
222        for vTbl in self.tables:
223            vTbl.drawMe(dc,self.current)
224        self.imagedc=dc
225    
226    def calculateMousePos(self,event):    def calculateMousePos(self,event):
227      originX, originY = self.diagram.GetViewStart()      originX, originY = self.diagram.GetViewStart()
228      unitX, unitY = self.diagram.GetScrollPixelsPerUnit()      unitX, unitY = self.diagram.GetScrollPixelsPerUnit()
# Line 139  class VisualEditor (wxPanel): Line 235  class VisualEditor (wxPanel):
235      for vTbl in self.tables:      for vTbl in self.tables:
236        object=vTbl.getObjectAt(x,y)        object=vTbl.getObjectAt(x,y)
237        if object != None:        if object != None:
238          self.tables.reverse()          self.tables.reverse()        
239          return object          return object
240      self.tables.reverse()      self.tables.reverse()
241      return None      # in case, that no object is selected, choose root object
242        return self.rootObject
243    
244    def onMouseEvent(self,event):    def onMouseEvent(self,event):
245      if not (event.LeftDown() or event.Dragging() or event.LeftUp()):      if not (event.LeftDown() or event.Dragging() or event.LeftUp()):
# Line 150  class VisualEditor (wxPanel): Line 247  class VisualEditor (wxPanel):
247      if event.LeftDown():      if event.LeftDown():
248        (x,y) = self.calculateMousePos(event)          (x,y) = self.calculateMousePos(event)  
249        object=self.getObjectAt(x,y)        object=self.getObjectAt(x,y)
250        if object != None:        if object._type!='VisualTable':
251          if object._type!='VisualTable':          self._instance.onSetCurrentObject(object, __name__)
252            self._instance.onSetCurrentObject(object, __name__)          return
253            return        else:
254          else:          self.dragx=x-object.xpos
255            self.dragx=x-object.xpos          self.dragy=y-object.ypos
256            self.dragy=y-object.ypos          self.dragobj=object
257            self.dragobj=object          dc = wxClientDC(self.diagram)
258            self.dragmode=true          self.diagram.PrepareDC(dc)
259            self.spriteOn=false
260            self.dragmode=true
261    
262      elif event.LeftUp() and self.dragmode:      elif event.LeftUp() and self.dragmode:
263        self.dragmode=false        self.dragmode=false
264        self.onPaintEvent(None,true)        self.refresh()
265                
266      elif event.Dragging() and self.dragmode:      elif event.Dragging() and self.dragmode:
267        (x,y) = self.calculateMousePos(event)          (x,y) = self.calculateMousePos(event)  
268        dc = wxPaintDC(self.diagram)        dc = wxClientDC(self.diagram)
269        self.diagram.PrepareDC(dc)        self.diagram.PrepareDC(dc)
270        dc.BeginDrawing()        dc.BeginDrawing()
271        dc.SetLogicalFunction(wxXOR)        dc.SetLogicalFunction(wxXOR)
272        self.dragobj.drawMe(dc,self.current)        if self.spriteOn:
273            self.dragobj.drawMe(dc,self.current,true)
274            
275        self.dragobj.moveTo(x-self.dragx,y-self.dragy)        self.dragobj.moveTo(x-self.dragx,y-self.dragy)
276        self.dragobj.drawMe(dc,self.current)        self.spriteOn=true
277  #      dc.drawRec        self.dragobj.drawMe(dc,self.current,true)
278  #     TODO: Begin to use a wxMemoryDC where the screen is drawn, and  
279    #     TODO: implement a way to move tables as a whole and not
280    #     only showing the border of the window.
281    #     one way would be to use a wxMemoryDC to paint into, and
282  #     which is copied into the real window -> no flickering screen  #     which is copied into the real window -> no flickering screen
283  #     when a object should be moved, first delete it, and repaint the  #     when a object should be moved, first delete it, and repaint the
284  #     wxMemoryDC, then you can move it on the real DC and you can  #     wxMemoryDC, then you can move it on the real DC and you can
# Line 182  class VisualEditor (wxPanel): Line 286  class VisualEditor (wxPanel):
286    
287        dc.EndDrawing()        dc.EndDrawing()
288    
289      # in case of a right mouse click show a context menu
290      def onRightClickEvent(self,event):    
291        (x,y) = self.calculateMousePos(event)
292        object=self.getObjectAt(x,y)
293        menu = wxMenu()
294    
295        popup_NEWTABLE =1
296        popup_NEWFIELD =2
297        popup_NEWINDEX =3
298        popup_NEWUINDEX=4
299        popup_EDIT     =5
300        popup_RENAME   =6
301        popup_DUPPL    =7
302        popup_DEL      =8
303    
304        # TODO: Use a generalized popup menu like in the forms designer
305        #       instead of this one. the popup menu in the treeview and
306        #       the visual editor should look the same
307    
308        if object._type=='VisualTable':
309          object=object.instance
310          
311        self._instance.onSetCurrentObject(object, __name__)
312    
313        if object._type=='VisualTable' or object._type=="GSTable":
314          menu.Append(popup_NEWFIELD, "Add Field")
315          EVT_MENU(self,popup_NEWFIELD,self.onAddField)
316          
317        elif object._type=="GSField":
318          menu.Append(popup_NEWINDEX, "Add Index")      
319          EVT_MENU(self,popup_NEWINDEX,self.onAddIndex)
320    
321          menu.Append(popup_NEWUINDEX, "Add Unique Index")      
322          EVT_MENU(self,popup_NEWUINDEX,self.onAddUniqueIndex)
323          
324        else:
325          menu.Append(popup_NEWTABLE, "New Table")
326          EVT_MENU(self,popup_NEWTABLE,self.onNewTable)
327    
328        if object._type!='GSSchema':
329          menu.AppendSeparator()
330          
331          menu.Append(popup_EDIT, "Edit")
332          EVT_MENU(self,popup_EDIT,self.onEdit)
333    
334          menu.Append(popup_RENAME, "Rename")
335          EVT_MENU(self,popup_RENAME,self.onRename)
336                
337          menu.Append(popup_DUPPL, "Duplicate")
338          EVT_MENU(self,popup_DUPPL,self.onDuplicate)
339                
340          menu.Append(popup_DEL, "Delete")
341          EVT_MENU(self,popup_DEL,self.onDelete)
342    
343          
344        clickPt = wxPoint(x + self.diagram.GetPosition().x,
345                            y + self.diagram.GetPosition().y)
346        self.diagram.PopupMenu(menu, clickPt)
347        menu.Destroy()
348    
349      def onNewTable(self,event):
350        dialog = wxTextEntryDialog(self.diagram,'Name of the new table:')
351      
352        if dialog.ShowModal() == wxID_OK:
353          tables=self.rootObject.findChildOfType("GSTables")
354          if tables==None:
355            tables = createObject(self._instance, self.rootObject, 'tables',
356                                  None,None,self.rootObject)
357          createObject(self._instance, self.rootObject, 'table',
358                       None,None,tables,{"name":dialog.GetValue()})
359                
360        dialog.Destroy()
361    
362      def onAddField(self,event):
363        dialog = wxTextEntryDialog(self.diagram,'Name of the new field:')
364      
365        if dialog.ShowModal() == wxID_OK:
366          fields=self.current.findChildOfType("GSFields")          
367          if fields==None:
368            tbl=self.current.findChildOfType("GSTable")
369            fields=createObject(self._instance, self.rootObject,'fields',
370                                None,None,tbl)
371            
372          createObject(self._instance, self.rootObject, 'field',
373                       None,None,fields,{"name":dialog.GetValue(),
374                                         "type":"varchar",
375                                         "size":20})
376    
377        dialog.Destroy()
378      
379      def onAddIndex(self,event):
380        tbl=self.current.findParentOfType("GSTable")          
381        indexes=tbl.findChildOfType("GSIndexes")          
382        if indexes==None:
383          indexes = createObject(self._instance, self.rootObject, 'indexes',
384                                  None,None,tbl)
385        idx=createObject(self._instance, self.rootObject, 'index',
386                     None,None,indexes,
387                     {"name":"%s_%s" % (tbl.name,self.current.name)})        
388        createObject(self._instance, self.rootObject, 'index',
389                     None,None,idx,
390                     {"name":self.current.name})        
391        self.refresh()
392    
393      def onAddUniqueIndex(self,event):
394        tbl=self.current.findParentOfType("GSTable")          
395        indexes=tbl.findChildOfType("GSIndexes")          
396        if indexes==None:
397          indexes = createObject(self._instance, self.rootObject, 'indexes',
398                                  None,None,tbl)
399        idx=createObject(self._instance, self.rootObject, 'index',
400                     None,None,indexes,
401                     {"name":"%s_%s" % (tbl.name,self.current.name),
402                      "unique":"Y"})        
403        createObject(self._instance, self.rootObject, 'index',
404                     None,None,idx,
405                     {"name":self.current.name})        
406        self.refresh()
407    
408    
409      def onAddConstraint(self,event):
410        pass
411    
412      def onRename(self,event):
413        dialog = wxTextEntryDialog(self.diagram,'New Name')
414        if hasattr(self.current,'name'):
415          dialog.SetValue(self.current.name)
416          
417        if dialog.ShowModal() == wxID_OK:
418          self.current.name=dialog.GetValue()
419          self._instance.onModifyObject(self.current,"schema",
420                                        [('name',self.current.name)])
421          self.refresh()
422    
423        dialog.Destroy()
424      
425      def onDuplicate(self,event):
426        pass
427    
428      def onEdit(self,event):
429        print "EDIT occured"
430        pass
431      
432      def onDelete(self,event):
433        deleteObject(self._instance, self.rootObject, self.current, firstRun=1)
434    
435    
436    def onLeftClickEvent(self,event):        def onLeftClickEvent(self,event):    
437      (x,y) = self.calculateMousePos(event)        (x,y) = self.calculateMousePos(event)  

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.4

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26