1 #----------------------------------------------------------------------------
3 # Purpose: Basic Reusable Service View for wx.lib.pydocview
9 # Copyright: (c) 2004-2005 ActiveGrid, Inc.
10 # License: wxWindows License
11 #----------------------------------------------------------------------------
15 import wx
.lib
.pydocview
19 FLOATING_MINIFRAME
= -1
22 class ServiceView(wx
.EvtHandler
):
23 """ Basic Service View.
27 #----------------------------------------------------------------------------
29 #----------------------------------------------------------------------------
31 def __init__(self
, service
):
32 wx
.EvtHandler
.__init
__(self
)
33 self
._viewFrame
= None
34 self
._service
= service
36 self
._embeddedWindow
= None
40 wx
.EvtHandler
.Destroy(self
)
44 return self
._viewFrame
47 def SetFrame(self
, frame
):
48 self
._viewFrame
= frame
51 def _CreateControl(self
, parent
, id):
59 def SetControl(self
, control
):
60 self
._control
= control
63 def OnCreate(self
, doc
, flags
):
64 config
= wx
.ConfigBase_Get()
65 windowLoc
= self
._service
.GetEmbeddedWindowLocation()
66 if windowLoc
== FLOATING_MINIFRAME
:
67 pos
= config
.ReadInt(self
._service
.GetServiceName() + "FrameXLoc", -1), config
.ReadInt(self
._service
.GetServiceName() + "FrameYLoc", -1)
68 # make sure frame is visible
69 screenWidth
= wx
.SystemSettings
.GetMetric(wx
.SYS_SCREEN_X
)
70 screenHeight
= wx
.SystemSettings
.GetMetric(wx
.SYS_SCREEN_Y
)
71 if pos
[0] < 0 or pos
[0] >= screenWidth
or pos
[1] < 0 or pos
[1] >= screenHeight
:
72 pos
= wx
.DefaultPosition
74 size
= wx
.Size(config
.ReadInt(self
._service
.GetServiceName() + "FrameXSize", -1), config
.ReadInt(self
._service
.GetServiceName() + "FrameYSize", -1))
75 title
= _(self
._service
.GetServiceName())
76 if wx
.GetApp().GetDocumentManager().GetFlags() & wx
.lib
.docview
.DOC_SDI
and wx
.GetApp().GetAppName():
77 title
= title
+ " - " + wx
.GetApp().GetAppName()
78 frame
= wx
.MiniFrame(wx
.GetApp().GetTopWindow(), -1, title
, pos
= pos
, size
= size
, style
= wx
.CLOSE_BOX|wx
.CAPTION|wx
.SYSTEM_MENU
)
79 wx
.EVT_CLOSE(frame
, self
.OnCloseWindow
)
80 elif wx
.GetApp().IsMDI():
81 self
._embeddedWindow
= wx
.GetApp().GetTopWindow().GetEmbeddedWindow(windowLoc
)
82 frame
= self
._embeddedWindow
84 pos
= config
.ReadInt(self
._service
.GetServiceName() + "FrameXLoc", -1), config
.ReadInt(self
._service
.GetServiceName() + "FrameYLoc", -1)
85 # make sure frame is visible
86 screenWidth
= wx
.SystemSettings
.GetMetric(wx
.SYS_SCREEN_X
)
87 screenHeight
= wx
.SystemSettings
.GetMetric(wx
.SYS_SCREEN_Y
)
88 if pos
[0] < 0 or pos
[0] >= screenWidth
or pos
[1] < 0 or pos
[1] >= screenHeight
:
89 pos
= wx
.DefaultPosition
91 size
= wx
.Size(config
.ReadInt(self
._service
.GetServiceName() + "FrameXSize", -1), config
.ReadInt(self
._service
.GetServiceName() + "FrameYSize", -1))
92 title
= _(self
._service
.GetServiceName())
93 if wx
.GetApp().GetDocumentManager().GetFlags() & wx
.lib
.docview
.DOC_SDI
and wx
.GetApp().GetAppName():
94 title
= title
+ " - " + wx
.GetApp().GetAppName()
95 frame
= wx
.GetApp().CreateDocumentFrame(self
, doc
, flags
, pos
= pos
, size
= size
)
97 if config
.ReadInt(self
._service
.GetServiceName() + "FrameMaximized", False):
99 wx
.EVT_CLOSE(frame
, self
.OnCloseWindow
)
102 sizer
= wx
.BoxSizer(wx
.VERTICAL
)
104 windowLoc
= self
._service
.GetEmbeddedWindowLocation()
105 if self
._embeddedWindow
or windowLoc
== FLOATING_MINIFRAME
:
106 if (self
._service
.GetEmbeddedWindowLocation() == wx
.lib
.pydocview
.EMBEDDED_WINDOW_BOTTOM
):
107 if ServiceView
.bottomTab
== None:
108 ServiceView
.bottomTab
= wx
.Notebook(frame
, wx
.NewId(), (0,0), (100,100), wx
.LB_DEFAULT
, "Bottom Tab")
109 wx
.EVT_RIGHT_DOWN(ServiceView
.bottomTab
, self
.OnNotebookRightClick
)
110 wx
.EVT_MIDDLE_DOWN(ServiceView
.bottomTab
, self
.OnNotebookMiddleClick
)
111 sizer
.Add(ServiceView
.bottomTab
, 1, wx
.TOP|wx
.EXPAND
, 4)
112 def OnFrameResize(event
):
113 ServiceView
.bottomTab
.SetSize(ServiceView
.bottomTab
.GetParent().GetSize())
114 frame
.Bind(wx
.EVT_SIZE
, OnFrameResize
)
116 self
._control
= self
._CreateControl
(ServiceView
.bottomTab
, wx
.NewId())
117 if self
._control
!= None:
118 ServiceView
.bottomTab
.AddPage(self
._control
, self
._service
.GetServiceName())
119 ServiceView
.bottomTab
.Layout()
122 self
._control
= self
._CreateControl
(frame
, wx
.NewId())
123 sizer
.Add(self
._control
)
126 self
._control
= self
._CreateControl
(frame
, wx
.NewId())
127 sizer
.Add(self
._control
, 1, wx
.EXPAND
, 0)
128 frame
.SetSizer(sizer
)
134 def OnNotebookMiddleClick(self
, event
):
135 index
, type = ServiceView
.bottomTab
.HitTest(event
.GetPosition())
136 # 0 tab is always message. This code assumes the rest are run/debug windows
138 page
= ServiceView
.bottomTab
.GetPage(index
)
139 if hasattr(page
, 'StopAndRemoveUI'):
140 page
.StopAndRemoveUI(event
)
143 def OnNotebookRightClick(self
, event
):
144 index
, type = ServiceView
.bottomTab
.HitTest(event
.GetPosition())
146 x
, y
= event
.GetX(), event
.GetY()
147 # 0 tab is always message. This code assumes the rest are run/debug windows
149 page
= ServiceView
.bottomTab
.GetPage(index
)
151 menu
.Append(id, _("Close"))
152 def OnRightMenuSelect(event
):
153 if hasattr(page
, 'StopAndRemoveUI'):
154 page
.StopAndRemoveUI(event
)
155 wx
.EVT_MENU(ServiceView
.bottomTab
, id, OnRightMenuSelect
)
156 if ServiceView
.bottomTab
.GetPageCount() > 1:
158 menu
.Append(id, _("Close All but \"Message\""))
159 def OnRightMenuSelect(event
):
160 for i
in range(ServiceView
.bottomTab
.GetPageCount()-1, 0, -1): # Go from len-1 to 1
161 page
= ServiceView
.bottomTab
.GetPage(i
)
162 if hasattr(page
, 'StopAndRemoveUI'):
163 page
.StopAndRemoveUI(event
)
164 wx
.EVT_MENU(ServiceView
.bottomTab
, id, OnRightMenuSelect
)
166 ServiceView
.bottomTab
.PopupMenu(menu
, wx
.Point(x
, y
))
170 def OnCloseWindow(self
, event
):
171 frame
= self
.GetFrame()
172 config
= wx
.ConfigBase_Get()
173 if frame
and not self
._embeddedWindow
:
174 if not frame
.IsMaximized():
175 config
.WriteInt(self
._service
.GetServiceName() + "FrameXLoc", frame
.GetPositionTuple()[0])
176 config
.WriteInt(self
._service
.GetServiceName() + "FrameYLoc", frame
.GetPositionTuple()[1])
177 config
.WriteInt(self
._service
.GetServiceName() + "FrameXSize", frame
.GetSizeTuple()[0])
178 config
.WriteInt(self
._service
.GetServiceName() + "FrameYSize", frame
.GetSizeTuple()[1])
179 config
.WriteInt(self
._service
.GetServiceName() + "FrameMaximized", frame
.IsMaximized())
181 if not self
._embeddedWindow
:
182 windowLoc
= self
._service
.GetEmbeddedWindowLocation()
183 if windowLoc
== FLOATING_MINIFRAME
:
184 # don't destroy it, just hide it
187 # 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
188 frame
.OnCloseWindow(event
)
191 def Activate(self
, activate
= True):
192 """ Dummy function for SDI mode """
196 def Close(self
, deleteWindow
= True):
198 Closes the view by calling OnClose. If deleteWindow is true, this
199 function should delete the window associated with the view.
207 #----------------------------------------------------------------------------
209 #----------------------------------------------------------------------------
211 def SetCallback(self
, callback
):
212 """ Sets in the event table for a doubleclick to invoke the given callback.
213 Additional calls to this method overwrites the previous entry and only the last set callback will be invoked.
215 wx
.stc
.EVT_STC_DOUBLECLICK(self
.GetControl(), self
.GetControl().GetId(), callback
)
218 #----------------------------------------------------------------------------
220 #----------------------------------------------------------------------------
223 if not self
.GetFrame():
225 return self
.GetFrame().IsShown()
232 def Show(self
, show
= True):
234 self
.GetFrame().Show(show
)
235 if self
._embeddedWindow
:
236 mdiParentFrame
= wx
.GetApp().GetTopWindow()
237 mdiParentFrame
.ShowEmbeddedWindow(self
.GetFrame(), show
)
240 class Service(wx
.lib
.pydocview
.DocService
):
243 #----------------------------------------------------------------------------
245 #----------------------------------------------------------------------------
246 SHOW_WINDOW
= wx
.NewId() # keep this line for each subclass, need unique ID for each Service
249 def __init__(self
, serviceName
, embeddedWindowLocation
= wx
.lib
.pydocview
.EMBEDDED_WINDOW_LEFT
):
250 self
._serviceName
= serviceName
251 self
._embeddedWindowLocation
= embeddedWindowLocation
255 def GetEmbeddedWindowLocation(self
):
256 return self
._embeddedWindowLocation
259 def SetEmbeddedWindowLocation(self
, embeddedWindowLocation
):
260 self
._embeddedWindowLocation
= embeddedWindowLocation
263 def InstallControls(self
, frame
, menuBar
= None, toolBar
= None, statusBar
= None, document
= None):
264 viewMenu
= menuBar
.GetMenu(menuBar
.FindMenu(_("&View")))
265 menuItemPos
= self
.GetMenuItemPos(viewMenu
, viewMenu
.FindItem(_("&Status Bar"))) + 1
267 viewMenu
.InsertCheckItem(menuItemPos
, self
.SHOW_WINDOW
, self
.GetMenuString(), self
.GetMenuDescr())
268 wx
.EVT_MENU(frame
, self
.SHOW_WINDOW
, frame
.ProcessEvent
)
269 wx
.EVT_UPDATE_UI(frame
, self
.SHOW_WINDOW
, frame
.ProcessUpdateUIEvent
)
274 def GetServiceName(self
):
275 """ String used to save out Service View configuration information """
276 return self
._serviceName
279 def GetMenuString(self
):
280 """ Need to override this method to provide menu item for showing Service View """
281 return _(self
.GetServiceName())
284 def GetMenuDescr(self
):
285 """ Need to override this method to provide menu item for showing Service View """
286 return _("Show or hides the %s window") % self
.GetMenuString()
289 #----------------------------------------------------------------------------
290 # Event Processing Methods
291 #----------------------------------------------------------------------------
293 def ProcessEvent(self
, event
):
295 if id == self
.SHOW_WINDOW
:
296 self
.ToggleWindow(event
)
302 def ProcessUpdateUIEvent(self
, event
):
304 if id == self
.SHOW_WINDOW
:
305 event
.Check(self
._view
!= None and self
._view
.IsShown())
312 #----------------------------------------------------------------------------
314 #----------------------------------------------------------------------------
316 def _CreateView(self
):
317 """ This method needs to be overridden with corresponding ServiceView """
318 return ServiceView(self
)
322 # Window Menu Service Method
326 def SetView(self
, view
):
330 def ShowWindow(self
, show
= True):
333 if not self
._view
.IsShown():
336 view
= self
._CreateView
()
337 view
.OnCreate(None, flags
= 0)
341 if self
._view
.IsShown():
345 def HideWindow(self
):
346 self
.ShowWindow(False)
349 def ToggleWindow(self
, event
):
350 show
= event
.IsChecked()
351 wx
.ConfigBase_Get().WriteInt(self
.GetServiceName()+"Shown", show
)
352 self
.ShowWindow(show
)
355 def OnCloseFrame(self
, event
):
359 if wx
.GetApp().IsMDI():
360 self
._view
.OnCloseWindow(event
)
361 # This is called when any SDI frame is closed, so need to check if message window is closing or some other window
362 elif self
._view
== event
.GetEventObject().GetView():