git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@36607 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			367 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			367 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #----------------------------------------------------------------------------
 | |
| # Name:         Service.py
 | |
| # Purpose:      Basic Reusable Service View for wx.lib.pydocview
 | |
| #
 | |
| # Author:       Morgan Hua
 | |
| #
 | |
| # Created:      11/4/04
 | |
| # CVS-ID:       $Id$
 | |
| # Copyright:    (c) 2004-2005 ActiveGrid, Inc.
 | |
| # License:      wxWindows License
 | |
| #----------------------------------------------------------------------------
 | |
| 
 | |
| import wx
 | |
| import wx.lib.docview
 | |
| import wx.lib.pydocview
 | |
| _ = wx.GetTranslation
 | |
| 
 | |
| 
 | |
| FLOATING_MINIFRAME = -1
 | |
| 
 | |
| 
 | |
| class ServiceView(wx.EvtHandler):
 | |
|     """ Basic Service View.
 | |
|     """
 | |
|     bottomTab = None
 | |
|     
 | |
|     #----------------------------------------------------------------------------
 | |
|     # Overridden methods
 | |
|     #----------------------------------------------------------------------------
 | |
| 
 | |
|     def __init__(self, service):
 | |
|         wx.EvtHandler.__init__(self)
 | |
|         self._viewFrame = None
 | |
|         self._service = service
 | |
|         self._control = None
 | |
|         self._embeddedWindow = None
 | |
| 
 | |
| 
 | |
|     def Destroy(self):
 | |
|         wx.EvtHandler.Destroy(self)
 | |
| 
 | |
| 
 | |
|     def GetFrame(self):
 | |
|         return self._viewFrame
 | |
| 
 | |
| 
 | |
|     def SetFrame(self, frame):
 | |
|         self._viewFrame = frame
 | |
| 
 | |
| 
 | |
|     def _CreateControl(self, parent, id):
 | |
|         return None
 | |
|         
 | |
|     
 | |
|     def GetControl(self):
 | |
|         return self._control
 | |
| 
 | |
| 
 | |
|     def SetControl(self, control):
 | |
|         self._control = control
 | |
| 
 | |
| 
 | |
|     def OnCreate(self, doc, flags):
 | |
|         config = wx.ConfigBase_Get()
 | |
|         windowLoc = self._service.GetEmbeddedWindowLocation()
 | |
|         if windowLoc == FLOATING_MINIFRAME:
 | |
|             pos = config.ReadInt(self._service.GetServiceName() + "FrameXLoc", -1), config.ReadInt(self._service.GetServiceName() + "FrameYLoc", -1)
 | |
|             # make sure frame is visible
 | |
|             screenWidth = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_X)
 | |
|             screenHeight = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_Y)
 | |
|             if pos[0] < 0 or pos[0] >= screenWidth or pos[1] < 0 or pos[1] >= screenHeight:
 | |
|                 pos = wx.DefaultPosition
 | |
| 
 | |
|             size = wx.Size(config.ReadInt(self._service.GetServiceName() + "FrameXSize", -1), config.ReadInt(self._service.GetServiceName() + "FrameYSize", -1))
 | |
|             title = _(self._service.GetServiceName())
 | |
|             if wx.GetApp().GetDocumentManager().GetFlags() & wx.lib.docview.DOC_SDI and wx.GetApp().GetAppName():
 | |
|                 title =  title + " - " + wx.GetApp().GetAppName()
 | |
|             frame = wx.MiniFrame(wx.GetApp().GetTopWindow(), -1, title, pos = pos, size = size, style = wx.CLOSE_BOX|wx.CAPTION|wx.SYSTEM_MENU)
 | |
|             wx.EVT_CLOSE(frame, self.OnCloseWindow)
 | |
|         elif wx.GetApp().IsMDI():
 | |
|             self._embeddedWindow = wx.GetApp().GetTopWindow().GetEmbeddedWindow(windowLoc)
 | |
|             frame = self._embeddedWindow
 | |
|         else:
 | |
|             pos = config.ReadInt(self._service.GetServiceName() + "FrameXLoc", -1), config.ReadInt(self._service.GetServiceName() + "FrameYLoc", -1)
 | |
|             # make sure frame is visible
 | |
|             screenWidth = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_X)
 | |
|             screenHeight = wx.SystemSettings.GetMetric(wx.SYS_SCREEN_Y)
 | |
|             if pos[0] < 0 or pos[0] >= screenWidth or pos[1] < 0 or pos[1] >= screenHeight:
 | |
|                 pos = wx.DefaultPosition
 | |
| 
 | |
|             size = wx.Size(config.ReadInt(self._service.GetServiceName() + "FrameXSize", -1), config.ReadInt(self._service.GetServiceName() + "FrameYSize", -1))
 | |
|             title = _(self._service.GetServiceName())
 | |
|             if wx.GetApp().GetDocumentManager().GetFlags() & wx.lib.docview.DOC_SDI and wx.GetApp().GetAppName():
 | |
|                 title =  title + " - " + wx.GetApp().GetAppName()
 | |
|             frame = wx.GetApp().CreateDocumentFrame(self, doc, flags, pos = pos, size = size)
 | |
|             frame.SetTitle(title)
 | |
|             if config.ReadInt(self._service.GetServiceName() + "FrameMaximized", False):
 | |
|                 frame.Maximize(True)
 | |
|             wx.EVT_CLOSE(frame, self.OnCloseWindow)
 | |
| 
 | |
|         self.SetFrame(frame)
 | |
|         sizer = wx.BoxSizer(wx.VERTICAL)
 | |
|         
 | |
|         windowLoc = self._service.GetEmbeddedWindowLocation()
 | |
|         if self._embeddedWindow or windowLoc == FLOATING_MINIFRAME:
 | |
|             if (self._service.GetEmbeddedWindowLocation() == wx.lib.pydocview.EMBEDDED_WINDOW_BOTTOM):
 | |
|                 if ServiceView.bottomTab == None:
 | |
|                     ServiceView.bottomTab = wx.Notebook(frame, wx.NewId(), (0,0), (100,100), wx.LB_DEFAULT, "Bottom Tab")
 | |
|                     wx.EVT_RIGHT_DOWN(ServiceView.bottomTab, self.OnNotebookRightClick)
 | |
|                     wx.EVT_MIDDLE_DOWN(ServiceView.bottomTab, self.OnNotebookMiddleClick)
 | |
|                     sizer.Add(ServiceView.bottomTab, 1, wx.TOP|wx.EXPAND, 4)
 | |
|                     def OnFrameResize(event):
 | |
|                         ServiceView.bottomTab.SetSize(ServiceView.bottomTab.GetParent().GetSize())
 | |
|                     frame.Bind(wx.EVT_SIZE, OnFrameResize)
 | |
|                 # Factor this out.
 | |
|                 self._control = self._CreateControl(ServiceView.bottomTab, wx.NewId())
 | |
|                 if self._control != None:
 | |
|                     ServiceView.bottomTab.AddPage(self._control, self._service.GetServiceName())
 | |
|                 ServiceView.bottomTab.Layout()
 | |
|             else:
 | |
|                 # Factor this out.
 | |
|                 self._control = self._CreateControl(frame, wx.NewId())
 | |
|                 sizer.Add(self._control)
 | |
|         else:
 | |
|             # Factor this out.
 | |
|             self._control = self._CreateControl(frame, wx.NewId())
 | |
|             sizer.Add(self._control, 1, wx.EXPAND, 0)
 | |
|         frame.SetSizer(sizer)
 | |
|         frame.Layout()
 | |
|         self.Activate()
 | |
|         return True
 | |
| 
 | |
| 
 | |
|     def OnNotebookMiddleClick(self, event):
 | |
|         index, type = ServiceView.bottomTab.HitTest(event.GetPosition())
 | |
|         # 0 tab is always message. This code assumes the rest are run/debug windows
 | |
|         if index > 0:
 | |
|             page = ServiceView.bottomTab.GetPage(index)
 | |
|             if hasattr(page, 'StopAndRemoveUI'):
 | |
|                 page.StopAndRemoveUI(event)
 | |
|  
 | |
|        
 | |
|     def OnNotebookRightClick(self, event):
 | |
|         index, type = ServiceView.bottomTab.HitTest(event.GetPosition())
 | |
|         menu = wx.Menu()
 | |
|         x, y = event.GetX(), event.GetY()
 | |
|         # 0 tab is always message. This code assumes the rest are run/debug windows
 | |
|         if index > 0:
 | |
|             page = ServiceView.bottomTab.GetPage(index)
 | |
|             id = wx.NewId()
 | |
|             menu.Append(id, _("Close"))
 | |
|             def OnRightMenuSelect(event):
 | |
|                 if hasattr(page, 'StopAndRemoveUI'):
 | |
|                     page.StopAndRemoveUI(event)
 | |
|             wx.EVT_MENU(ServiceView.bottomTab, id, OnRightMenuSelect)
 | |
|             if ServiceView.bottomTab.GetPageCount() > 1:
 | |
|                 id = wx.NewId()
 | |
|                 menu.Append(id, _("Close All but \"Message\""))
 | |
|                 def OnRightMenuSelect(event):
 | |
|                     for i in range(ServiceView.bottomTab.GetPageCount()-1, 0, -1): # Go from len-1 to 1
 | |
|                         page = ServiceView.bottomTab.GetPage(i)
 | |
|                         if hasattr(page, 'StopAndRemoveUI'):
 | |
|                             page.StopAndRemoveUI(event)
 | |
|                 wx.EVT_MENU(ServiceView.bottomTab, id, OnRightMenuSelect)
 | |
|         
 | |
|         ServiceView.bottomTab.PopupMenu(menu, wx.Point(x, y))
 | |
|         menu.Destroy()
 | |
| 
 | |
|         
 | |
|     def OnCloseWindow(self, event):
 | |
|         frame = self.GetFrame()
 | |
|         config = wx.ConfigBase_Get()
 | |
|         if frame and not self._embeddedWindow:
 | |
|             if not frame.IsMaximized():
 | |
|                 config.WriteInt(self._service.GetServiceName() + "FrameXLoc", frame.GetPositionTuple()[0])
 | |
|                 config.WriteInt(self._service.GetServiceName() + "FrameYLoc", frame.GetPositionTuple()[1])
 | |
|                 config.WriteInt(self._service.GetServiceName() + "FrameXSize", frame.GetSizeTuple()[0])
 | |
|                 config.WriteInt(self._service.GetServiceName() + "FrameYSize", frame.GetSizeTuple()[1])
 | |
|             config.WriteInt(self._service.GetServiceName() + "FrameMaximized", frame.IsMaximized())
 | |
| 
 | |
|         if not self._embeddedWindow:
 | |
|             windowLoc = self._service.GetEmbeddedWindowLocation()
 | |
|             if windowLoc == FLOATING_MINIFRAME:
 | |
|                 # don't destroy it, just hide it
 | |
|                 frame.Hide()
 | |
|             else:
 | |
|                 # Call the original OnCloseWindow, could have subclassed SDIDocFrame and MDIDocFrame but this is easier since it will work for both SDI and MDI frames without subclassing both
 | |
|                 frame.OnCloseWindow(event)
 | |
| 
 | |
| 
 | |
|     def Activate(self, activate = True):
 | |
|         """ Dummy function for SDI mode """
 | |
|         pass
 | |
| 
 | |
| 
 | |
|     def Close(self, deleteWindow = True):
 | |
|         """
 | |
|         Closes the view by calling OnClose. If deleteWindow is true, this
 | |
|         function should delete the window associated with the view.
 | |
|         """
 | |
|         if deleteWindow:
 | |
|             self.Destroy()
 | |
| 
 | |
|         return True
 | |
| 
 | |
| 
 | |
|     #----------------------------------------------------------------------------
 | |
|     # Callback Methods
 | |
|     #----------------------------------------------------------------------------
 | |
| 
 | |
|     def SetCallback(self, callback):
 | |
|         """ Sets in the event table for a doubleclick to invoke the given callback.
 | |
|             Additional calls to this method overwrites the previous entry and only the last set callback will be invoked.
 | |
|         """
 | |
|         wx.stc.EVT_STC_DOUBLECLICK(self.GetControl(), self.GetControl().GetId(), callback)
 | |
| 
 | |
| 
 | |
|     #----------------------------------------------------------------------------
 | |
|     # Display Methods
 | |
|     #----------------------------------------------------------------------------
 | |
| 
 | |
|     def IsShown(self):
 | |
|         if not self.GetFrame():
 | |
|             return False
 | |
|         return self.GetFrame().IsShown()
 | |
| 
 | |
| 
 | |
|     def Hide(self):
 | |
|         self.Show(False)
 | |
| 
 | |
| 
 | |
|     def Show(self, show = True):
 | |
|         if self.GetFrame():
 | |
|             self.GetFrame().Show(show)
 | |
|             if self._embeddedWindow:
 | |
|                 mdiParentFrame = wx.GetApp().GetTopWindow()
 | |
|                 mdiParentFrame.ShowEmbeddedWindow(self.GetFrame(), show)
 | |
| 
 | |
| 
 | |
| class Service(wx.lib.pydocview.DocService):
 | |
| 
 | |
| 
 | |
|     #----------------------------------------------------------------------------
 | |
|     # Constants
 | |
|     #----------------------------------------------------------------------------
 | |
|     SHOW_WINDOW = wx.NewId()  # keep this line for each subclass, need unique ID for each Service
 | |
| 
 | |
| 
 | |
|     def __init__(self, serviceName, embeddedWindowLocation = wx.lib.pydocview.EMBEDDED_WINDOW_LEFT):
 | |
|         self._serviceName = serviceName
 | |
|         self._embeddedWindowLocation = embeddedWindowLocation
 | |
|         self._view = None
 | |
| 
 | |
| 
 | |
|     def GetEmbeddedWindowLocation(self):
 | |
|         return self._embeddedWindowLocation
 | |
| 
 | |
| 
 | |
|     def SetEmbeddedWindowLocation(self, embeddedWindowLocation):
 | |
|         self._embeddedWindowLocation = embeddedWindowLocation
 | |
| 
 | |
| 
 | |
|     def InstallControls(self, frame, menuBar = None, toolBar = None, statusBar = None, document = None):
 | |
|         viewMenu = menuBar.GetMenu(menuBar.FindMenu(_("&View")))
 | |
|         menuItemPos = self.GetMenuItemPos(viewMenu, viewMenu.FindItem(_("&Status Bar"))) + 1
 | |
| 
 | |
|         viewMenu.InsertCheckItem(menuItemPos, self.SHOW_WINDOW, self.GetMenuString(), self.GetMenuDescr())
 | |
|         wx.EVT_MENU(frame, self.SHOW_WINDOW, frame.ProcessEvent)
 | |
|         wx.EVT_UPDATE_UI(frame, self.SHOW_WINDOW, frame.ProcessUpdateUIEvent)
 | |
| 
 | |
|         return True
 | |
| 
 | |
| 
 | |
|     def GetServiceName(self):
 | |
|         """ String used to save out Service View configuration information """
 | |
|         return self._serviceName
 | |
| 
 | |
| 
 | |
|     def GetMenuString(self):
 | |
|         """ Need to override this method to provide menu item for showing Service View """
 | |
|         return _(self.GetServiceName())
 | |
| 
 | |
| 
 | |
|     def GetMenuDescr(self):
 | |
|         """ Need to override this method to provide menu item for showing Service View """
 | |
|         return _("Show or hides the %s window") % self.GetMenuString()
 | |
| 
 | |
| 
 | |
|     #----------------------------------------------------------------------------
 | |
|     # Event Processing Methods
 | |
|     #----------------------------------------------------------------------------
 | |
| 
 | |
|     def ProcessEvent(self, event):
 | |
|         id = event.GetId()
 | |
|         if id == self.SHOW_WINDOW:
 | |
|             self.ToggleWindow(event)
 | |
|             return True
 | |
|         else:
 | |
|             return False
 | |
| 
 | |
| 
 | |
|     def ProcessUpdateUIEvent(self, event):
 | |
|         id = event.GetId()
 | |
|         if id == self.SHOW_WINDOW:
 | |
|             event.Check(self._view != None and self._view.IsShown())
 | |
|             event.Enable(True)
 | |
|             return True
 | |
|         else:
 | |
|             return False
 | |
| 
 | |
| 
 | |
|     #----------------------------------------------------------------------------
 | |
|     # View Methods
 | |
|     #----------------------------------------------------------------------------
 | |
| 
 | |
|     def _CreateView(self):
 | |
|         """ This method needs to be overridden with corresponding ServiceView """
 | |
|         return ServiceView(self)
 | |
| 
 | |
| 
 | |
|     def GetView(self):
 | |
|         # Window Menu Service Method
 | |
|         return self._view
 | |
| 
 | |
| 
 | |
|     def SetView(self, view):
 | |
|         self._view = view
 | |
| 
 | |
| 
 | |
|     def ShowWindow(self, show = True):
 | |
|         if show:
 | |
|             if self._view:
 | |
|                 if not self._view.IsShown():
 | |
|                     self._view.Show()
 | |
|             else:
 | |
|                 view = self._CreateView()
 | |
|                 view.OnCreate(None, flags = 0)
 | |
|                 self.SetView(view)
 | |
|         else:
 | |
|             if self._view:
 | |
|                 if self._view.IsShown():
 | |
|                     self._view.Hide()
 | |
| 
 | |
| 
 | |
|     def HideWindow(self):
 | |
|         self.ShowWindow(False)
 | |
| 
 | |
| 
 | |
|     def ToggleWindow(self, event):
 | |
|         show = event.IsChecked()
 | |
|         wx.ConfigBase_Get().WriteInt(self.GetServiceName()+"Shown", show)
 | |
|         self.ShowWindow(show)
 | |
| 
 | |
| 
 | |
|     def OnCloseFrame(self, event):
 | |
|         if not self._view:
 | |
|             return True
 | |
| 
 | |
|         if wx.GetApp().IsMDI():
 | |
|             self._view.OnCloseWindow(event)
 | |
|         # This is called when any SDI frame is closed, so need to check if message window is closing or some other window
 | |
|         elif self._view == event.GetEventObject().GetView():
 | |
|             self.SetView(None)
 | |
|         
 | |
|         return True
 | |
|         
 |