02b800ce7c
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
|
|
|