]> git.saurik.com Git - wxWidgets.git/blame - wxPython/wx/lib/pydocview.py
Disown the config object when calling wx.ConfigBase.Set
[wxWidgets.git] / wxPython / wx / lib / pydocview.py
CommitLineData
d1dc2b32
RD
1#----------------------------------------------------------------------------
2# Name: pydocview.py
3# Purpose: Python extensions to the wxWindows docview framework
4#
3fa8f722 5# Author: Peter Yared, Morgan Hua
d1dc2b32
RD
6#
7# Created: 5/15/03
8# CVS-ID: $Id$
3fa8f722 9# Copyright: (c) 2003-2005 ActiveGrid, Inc.
d1dc2b32
RD
10# License: wxWindows license
11#----------------------------------------------------------------------------
12
13
14import wx
15import wx.lib.docview
16import sys
17import getopt
18from wxPython.lib.rcsizer import RowColSizer
19import os
20import os.path
21import time
22import string
74b89458 23import pickle
74b89458
RD
24import tempfile
25import mmap
d1dc2b32 26_ = wx.GetTranslation
3fa8f722
RD
27if wx.Platform == '__WXMSW__':
28 _WINDOWS = True
29else:
30 _WINDOWS = False
74b89458 31
d1dc2b32
RD
32#----------------------------------------------------------------------------
33# Constants
34#----------------------------------------------------------------------------
35
36VIEW_TOOLBAR_ID = wx.NewId()
37VIEW_STATUSBAR_ID = wx.NewId()
38
39EMBEDDED_WINDOW_TOP = 1
40EMBEDDED_WINDOW_BOTTOM = 2
41EMBEDDED_WINDOW_LEFT = 4
42EMBEDDED_WINDOW_RIGHT = 8
43EMBEDDED_WINDOW_TOPLEFT = 16
44EMBEDDED_WINDOW_BOTTOMLEFT = 32
45EMBEDDED_WINDOW_TOPRIGHT = 64
46EMBEDDED_WINDOW_BOTTOMRIGHT = 128
47EMBEDDED_WINDOW_ALL = EMBEDDED_WINDOW_TOP | EMBEDDED_WINDOW_BOTTOM | EMBEDDED_WINDOW_LEFT | EMBEDDED_WINDOW_RIGHT | \
48 EMBEDDED_WINDOW_TOPLEFT | EMBEDDED_WINDOW_BOTTOMLEFT | EMBEDDED_WINDOW_TOPRIGHT | EMBEDDED_WINDOW_BOTTOMRIGHT
49
50SAVEALL_ID = wx.NewId()
51
52WINDOW_MENU_NUM_ITEMS = 9
53
54
3fa8f722 55class DocFrameMixIn:
d1dc2b32 56 """
3fa8f722
RD
57 Class with common code used by DocMDIParentFrame, DocTabbedParentFrame, and
58 DocSDIFrame.
d1dc2b32 59 """
3fa8f722 60
d1dc2b32
RD
61
62 def GetDocumentManager(self):
d1dc2b32 63 """
3fa8f722 64 Returns the document manager associated with the DocMDIParentFrame.
d1dc2b32 65 """
3fa8f722 66 return self._docManager
d1dc2b32
RD
67
68
3fa8f722 69 def InitializePrintData(self):
d1dc2b32 70 """
3fa8f722 71 Initializes the PrintData that is used when printing.
d1dc2b32 72 """
3fa8f722
RD
73 self._printData = wx.PrintData()
74 self._printData.SetPaperId(wx.PAPER_LETTER)
d1dc2b32
RD
75
76
3fa8f722 77 def CreateDefaultMenuBar(self, sdi=False):
d1dc2b32 78 """
3fa8f722 79 Creates the default MenuBar. Contains File, Edit, View, Tools, and Help menus.
d1dc2b32 80 """
3fa8f722
RD
81 menuBar = wx.MenuBar()
82
83 fileMenu = wx.Menu()
84 fileMenu.Append(wx.ID_NEW, _("&New...\tCtrl+N"), _("Creates a new document"))
85 fileMenu.Append(wx.ID_OPEN, _("&Open...\tCtrl+O"), _("Opens an existing document"))
86 fileMenu.Append(wx.ID_CLOSE, _("&Close"), _("Closes the active document"))
87 if not sdi:
88 fileMenu.Append(wx.ID_CLOSE_ALL, _("Close A&ll"), _("Closes all open documents"))
89 fileMenu.AppendSeparator()
90 fileMenu.Append(wx.ID_SAVE, _("&Save\tCtrl+S"), _("Saves the active document"))
91 fileMenu.Append(wx.ID_SAVEAS, _("Save &As..."), _("Saves the active document with a new name"))
92 fileMenu.Append(SAVEALL_ID, _("Save All\tCtrl+Shift+A"), _("Saves the all active documents"))
93 wx.EVT_MENU(self, SAVEALL_ID, self.ProcessEvent)
94 wx.EVT_UPDATE_UI(self, SAVEALL_ID, self.ProcessUpdateUIEvent)
95 fileMenu.AppendSeparator()
96 fileMenu.Append(wx.ID_PRINT, _("&Print\tCtrl+P"), _("Prints the active document"))
97 fileMenu.Append(wx.ID_PREVIEW, _("Print Pre&view"), _("Displays full pages"))
98 fileMenu.Append(wx.ID_PRINT_SETUP, _("Page Set&up"), _("Changes page layout settings"))
99 fileMenu.AppendSeparator()
100 if wx.Platform == '__WXMAC__':
101 fileMenu.Append(wx.ID_EXIT, _("&Quit"), _("Closes this program"))
102 else:
103 fileMenu.Append(wx.ID_EXIT, _("E&xit"), _("Closes this program"))
104 self._docManager.FileHistoryUseMenu(fileMenu)
105 self._docManager.FileHistoryAddFilesToMenu()
106 menuBar.Append(fileMenu, _("&File"));
d1dc2b32 107
3fa8f722
RD
108 editMenu = wx.Menu()
109 editMenu.Append(wx.ID_UNDO, _("&Undo\tCtrl+Z"), _("Reverses the last action"))
110 editMenu.Append(wx.ID_REDO, _("&Redo\tCtrl+Y"), _("Reverses the last undo"))
111 editMenu.AppendSeparator()
112 #item = wxMenuItem(self.editMenu, wxID_CUT, _("Cu&t\tCtrl+X"), _("Cuts the selection and puts it on the Clipboard"))
113 #item.SetBitmap(getCutBitmap())
114 #editMenu.AppendItem(item)
115 editMenu.Append(wx.ID_CUT, _("Cu&t\tCtrl+X"), _("Cuts the selection and puts it on the Clipboard"))
116 wx.EVT_MENU(self, wx.ID_CUT, self.ProcessEvent)
117 wx.EVT_UPDATE_UI(self, wx.ID_CUT, self.ProcessUpdateUIEvent)
118 editMenu.Append(wx.ID_COPY, _("&Copy\tCtrl+C"), _("Copies the selection and puts it on the Clipboard"))
119 wx.EVT_MENU(self, wx.ID_COPY, self.ProcessEvent)
120 wx.EVT_UPDATE_UI(self, wx.ID_COPY, self.ProcessUpdateUIEvent)
121 editMenu.Append(wx.ID_PASTE, _("&Paste\tCtrl+V"), _("Inserts Clipboard contents"))
122 wx.EVT_MENU(self, wx.ID_PASTE, self.ProcessEvent)
123 wx.EVT_UPDATE_UI(self, wx.ID_PASTE, self.ProcessUpdateUIEvent)
bbf7159c 124 editMenu.Append(wx.ID_CLEAR, _("&Delete"), _("Erases the selection"))
3fa8f722
RD
125 wx.EVT_MENU(self, wx.ID_CLEAR, self.ProcessEvent)
126 wx.EVT_UPDATE_UI(self, wx.ID_CLEAR, self.ProcessUpdateUIEvent)
127 editMenu.AppendSeparator()
128 editMenu.Append(wx.ID_SELECTALL, _("Select A&ll\tCtrl+A"), _("Selects all available data"))
129 wx.EVT_MENU(self, wx.ID_SELECTALL, self.ProcessEvent)
130 wx.EVT_UPDATE_UI(self, wx.ID_SELECTALL, self.ProcessUpdateUIEvent)
131 menuBar.Append(editMenu, _("&Edit"))
132 if sdi:
133 if self.GetDocument() and self.GetDocument().GetCommandProcessor():
134 self.GetDocument().GetCommandProcessor().SetEditMenu(editMenu)
135
136 viewMenu = wx.Menu()
137 viewMenu.AppendCheckItem(VIEW_TOOLBAR_ID, _("&Toolbar"), _("Shows or hides the toolbar"))
138 wx.EVT_MENU(self, VIEW_TOOLBAR_ID, self.OnViewToolBar)
139 wx.EVT_UPDATE_UI(self, VIEW_TOOLBAR_ID, self.OnUpdateViewToolBar)
140 viewMenu.AppendCheckItem(VIEW_STATUSBAR_ID, _("&Status Bar"), _("Shows or hides the status bar"))
141 wx.EVT_MENU(self, VIEW_STATUSBAR_ID, self.OnViewStatusBar)
142 wx.EVT_UPDATE_UI(self, VIEW_STATUSBAR_ID, self.OnUpdateViewStatusBar)
143 menuBar.Append(viewMenu, _("&View"))
d1dc2b32 144
3fa8f722
RD
145 helpMenu = wx.Menu()
146 helpMenu.Append(wx.ID_ABOUT, _("&About" + " " + wx.GetApp().GetAppName()), _("Displays program information, version number, and copyright"))
3fa8f722 147 menuBar.Append(helpMenu, _("&Help"))
d1dc2b32 148
bbf7159c 149 wx.EVT_MENU(self, wx.ID_ABOUT, self.OnAbout)
3fa8f722 150 wx.EVT_UPDATE_UI(self, wx.ID_ABOUT, self.ProcessUpdateUIEvent) # Using ID_ABOUT to update the window menu, the window menu items are not triggering
d1dc2b32 151
3fa8f722
RD
152 if sdi: # TODO: Is this really needed?
153 wx.EVT_COMMAND_FIND_CLOSE(self, -1, self.ProcessEvent)
154
155 return menuBar
d1dc2b32
RD
156
157
3fa8f722 158 def CreateDefaultStatusBar(self):
d1dc2b32 159 """
3fa8f722 160 Creates the default StatusBar.
d1dc2b32 161 """
3fa8f722
RD
162 wx.Frame.CreateStatusBar(self)
163 self.GetStatusBar().Show(wx.ConfigBase_Get().ReadInt("ViewStatusBar", True))
164 self.UpdateStatus()
165 return self.GetStatusBar()
d1dc2b32
RD
166
167
3fa8f722 168 def CreateDefaultToolBar(self):
d1dc2b32 169 """
3fa8f722 170 Creates the default ToolBar.
d1dc2b32 171 """
3fa8f722
RD
172 self._toolBar = self.CreateToolBar(wx.TB_HORIZONTAL | wx.NO_BORDER | wx.TB_FLAT)
173 self._toolBar.AddSimpleTool(wx.ID_NEW, getNewBitmap(), _("New"), _("Creates a new document"))
174 self._toolBar.AddSimpleTool(wx.ID_OPEN, getOpenBitmap(), _("Open"), _("Opens an existing document"))
175 self._toolBar.AddSimpleTool(wx.ID_SAVE, getSaveBitmap(), _("Save"), _("Saves the active document"))
176 self._toolBar.AddSimpleTool(SAVEALL_ID, getSaveAllBitmap(), _("Save All"), _("Saves all the active documents"))
177 self._toolBar.AddSeparator()
178 self._toolBar.AddSimpleTool(wx.ID_PRINT, getPrintBitmap(), _("Print"), _("Displays full pages"))
179 self._toolBar.AddSimpleTool(wx.ID_PREVIEW, getPrintPreviewBitmap(), _("Print Preview"), _("Prints the active document"))
180 self._toolBar.AddSeparator()
181 self._toolBar.AddSimpleTool(wx.ID_CUT, getCutBitmap(), _("Cut"), _("Cuts the selection and puts it on the Clipboard"))
182 self._toolBar.AddSimpleTool(wx.ID_COPY, getCopyBitmap(), _("Copy"), _("Copies the selection and puts it on the Clipboard"))
183 self._toolBar.AddSimpleTool(wx.ID_PASTE, getPasteBitmap(), _("Paste"), _("Inserts Clipboard contents"))
184 self._toolBar.AddSimpleTool(wx.ID_UNDO, getUndoBitmap(), _("Undo"), _("Reverses the last action"))
185 self._toolBar.AddSimpleTool(wx.ID_REDO, getRedoBitmap(), _("Redo"), _("Reverses the last undo"))
186 self._toolBar.Realize()
187 self._toolBar.Show(wx.ConfigBase_Get().ReadInt("ViewToolBar", True))
188
189 return self._toolBar
d1dc2b32
RD
190
191
3fa8f722 192 def OnFileSaveAll(self, event):
d1dc2b32 193 """
3fa8f722 194 Saves all of the currently open documents.
d1dc2b32 195 """
3fa8f722
RD
196 docs = wx.GetApp().GetDocumentManager().GetDocuments()
197 for doc in docs:
198 doc.Save()
d1dc2b32
RD
199
200
3fa8f722 201 def OnAbout(self, event):
d1dc2b32 202 """
3fa8f722 203 Invokes the about dialog.
d1dc2b32 204 """
3fa8f722
RD
205 aboutService = wx.GetApp().GetService(AboutService)
206 if aboutService:
207 aboutService.ShowAbout()
d1dc2b32
RD
208
209
3fa8f722 210 def OnViewToolBar(self, event):
d1dc2b32 211 """
3fa8f722 212 Toggles whether the ToolBar is visible.
d1dc2b32 213 """
3fa8f722
RD
214 self._toolBar.Show(not self._toolBar.IsShown())
215 self._LayoutFrame()
d1dc2b32 216
3fa8f722
RD
217
218 def OnUpdateViewToolBar(self, event):
d1dc2b32 219 """
3fa8f722 220 Updates the View ToolBar menu item.
d1dc2b32 221 """
3fa8f722 222 event.Check(self.GetToolBar().IsShown())
d1dc2b32
RD
223
224
3fa8f722 225 def OnViewStatusBar(self, event):
d1dc2b32 226 """
3fa8f722 227 Toggles whether the StatusBar is visible.
d1dc2b32 228 """
3fa8f722
RD
229 self.GetStatusBar().Show(not self.GetStatusBar().IsShown())
230 self._LayoutFrame()
d1dc2b32
RD
231
232
3fa8f722 233 def OnUpdateViewStatusBar(self, event):
d1dc2b32 234 """
3fa8f722 235 Updates the View StatusBar menu item.
d1dc2b32 236 """
3fa8f722 237 event.Check(self.GetStatusBar().IsShown())
d1dc2b32
RD
238
239
3fa8f722 240 def UpdateStatus(self, message = _("Ready")):
d1dc2b32 241 """
3fa8f722 242 Updates the StatusBar.
d1dc2b32 243 """
3fa8f722
RD
244 # wxBug: Menubar and toolbar help strings don't pop the status text back
245 if self.GetStatusBar().GetStatusText() != message:
246 self.GetStatusBar().PushStatusText(message)
d1dc2b32
RD
247
248
3fa8f722 249class DocMDIParentFrameMixIn:
d1dc2b32 250 """
3fa8f722 251 Class with common code used by DocMDIParentFrame and DocTabbedParentFrame.
d1dc2b32 252 """
3fa8f722 253
d1dc2b32 254
3fa8f722 255 def _GetPosSizeFromConfig(self, pos, size):
d1dc2b32 256 """
3fa8f722 257 Adjusts the position and size of the frame using the saved config position and size.
d1dc2b32 258 """
3fa8f722
RD
259 config = wx.ConfigBase_Get()
260 if pos == wx.DefaultPosition and size == wx.DefaultSize and config.ReadInt("MDIFrameMaximized", False):
261 pos = [0, 0]
262 size = wx.DisplaySize()
263 # wxBug: Need to set to fill screen to get around bug where maximize is leaving shadow of statusbar, check out maximize call at end of this function
264 else:
265 if pos == wx.DefaultPosition:
266 pos = config.ReadInt("MDIFrameXLoc", -1), config.ReadInt("MDIFrameYLoc", -1)
267
268 if wx.Display_GetFromPoint(pos) == -1: # Check if the frame position is offscreen
269 pos = wx.DefaultPosition
270
271 if size == wx.DefaultSize:
272 size = wx.Size(config.ReadInt("MDIFrameXSize", 450), config.ReadInt("MDIFrameYSize", 300))
273 return pos, size
274
275
276 def _InitFrame(self, embeddedWindows):
277 """
278 Initializes the frame and creates the default menubar, toolbar, and status bar.
279 """
280 self._embeddedWindows = []
281 self.SetDropTarget(_DocFrameFileDropTarget(self._docManager, self))
282
283 if wx.GetApp().GetDefaultIcon():
284 self.SetIcon(wx.GetApp().GetDefaultIcon())
285
286 wx.EVT_MENU(self, wx.ID_ABOUT, self.OnAbout)
287 wx.EVT_SIZE(self, self.OnSize)
288
289 self.InitializePrintData()
290
291 toolBar = self.CreateDefaultToolBar()
292 self.SetToolBar(toolBar)
293 menuBar = self.CreateDefaultMenuBar()
294 statusBar = self.CreateDefaultStatusBar()
295
296 config = wx.ConfigBase_Get()
297 if config.ReadInt("MDIFrameMaximized", False):
298 # wxBug: On maximize, statusbar leaves a residual that needs to be refereshed, happens even when user does it
299 self.Maximize()
300
301 self.CreateEmbeddedWindows(embeddedWindows)
302 self._LayoutFrame()
303
bbf7159c
RD
304 if wx.Platform == '__WXMAC__':
305 self.SetMenuBar(menuBar) # wxBug: Have to set the menubar at the very end or the automatic MDI "window" menu doesn't get put in the right place when the services add new menus to the menubar
306
3fa8f722
RD
307 wx.GetApp().SetTopWindow(self) # Need to do this here in case the services are looking for wx.GetApp().GetTopWindow()
308 for service in wx.GetApp().GetServices():
309 service.InstallControls(self, menuBar = menuBar, toolBar = toolBar, statusBar = statusBar)
310 if hasattr(service, "ShowWindow"):
311 service.ShowWindow() # instantiate service windows for correct positioning, we'll hide/show them later based on user preference
312
bbf7159c
RD
313 if wx.Platform != '__WXMAC__':
314 self.SetMenuBar(menuBar) # wxBug: Have to set the menubar at the very end or the automatic MDI "window" menu doesn't get put in the right place when the services add new menus to the menubar
3fa8f722
RD
315
316
317 def ProcessEvent(self, event):
318 """
319 Processes an event, searching event tables and calling zero or more
320 suitable event handler function(s). Note that the ProcessEvent
321 method is called from the wxPython docview framework directly since
322 wxPython does not have a virtual ProcessEvent function.
323 """
324 id = event.GetId()
325 if id == SAVEALL_ID:
326 self.OnFileSaveAll(event)
327 return True
328
329 return wx.GetApp().ProcessEvent(event)
330
331
332 def ProcessUpdateUIEvent(self, event):
333 """
334 Processes a UI event, searching event tables and calling zero or more
335 suitable event handler function(s). Note that the ProcessEvent
336 method is called from the wxPython docview framework directly since
337 wxPython does not have a virtual ProcessEvent function.
338 """
339 id = event.GetId()
340 if id == wx.ID_CUT:
341 event.Enable(False)
342 return True
343 elif id == wx.ID_COPY:
344 event.Enable(False)
345 return True
346 elif id == wx.ID_PASTE:
347 event.Enable(False)
348 return True
349 elif id == wx.ID_CLEAR:
350 event.Enable(False)
351 return True
352 elif id == wx.ID_SELECTALL:
353 event.Enable(False)
354 return True
355 elif id == SAVEALL_ID:
356 filesModified = False
357 docs = wx.GetApp().GetDocumentManager().GetDocuments()
358 for doc in docs:
359 if doc.IsModified():
360 filesModified = True
361 break
362
363 event.Enable(filesModified)
364 return True
365 else:
366 return wx.GetApp().ProcessUpdateUIEvent(event)
367
368
369 def CreateEmbeddedWindows(self, windows = 0):
370 """
371 Create the specified embedded windows around the edges of the frame.
372 """
373 frameSize = self.GetSize() # TODO: GetClientWindow.GetSize is still returning 0,0 since the frame isn't fully constructed yet, so using full frame size
374 defaultHSize = int(frameSize[0] / 6)
375 defaultVSize = int(frameSize[1] / 7)
376 defaultSubVSize = int(frameSize[1] / 2)
377 config = wx.ConfigBase_Get()
378 if windows & (EMBEDDED_WINDOW_LEFT | EMBEDDED_WINDOW_TOPLEFT | EMBEDDED_WINDOW_BOTTOMLEFT):
379 self._leftEmbWindow = self._CreateEmbeddedWindow(self, (config.ReadInt("MDIEmbedLeftSize", defaultHSize), -1), wx.LAYOUT_VERTICAL, wx.LAYOUT_LEFT, visible = config.ReadInt("MDIEmbedLeftVisible", 1), sash = wx.SASH_RIGHT)
380 else:
381 self._leftEmbWindow = None
382 if windows & EMBEDDED_WINDOW_TOPLEFT:
383 self._topLeftEmbWindow = self._CreateEmbeddedWindow(self._leftEmbWindow, (-1, config.ReadInt("MDIEmbedTopLeftSize", defaultSubVSize)), wx.LAYOUT_HORIZONTAL, wx.LAYOUT_TOP, visible = config.ReadInt("MDIEmbedTopLeftVisible", 1), sash = wx.SASH_BOTTOM)
384 else:
385 self._topLeftEmbWindow = None
386 if windows & EMBEDDED_WINDOW_BOTTOMLEFT:
387 self._bottomLeftEmbWindow = self._CreateEmbeddedWindow(self._leftEmbWindow, (-1, config.ReadInt("MDIEmbedBottomLeftSize", defaultSubVSize)), wx.LAYOUT_HORIZONTAL, wx.LAYOUT_BOTTOM, visible = config.ReadInt("MDIEmbedBottomLeftVisible", 1))
388 else:
389 self._bottomLeftEmbWindow = None
390 if windows & (EMBEDDED_WINDOW_RIGHT | EMBEDDED_WINDOW_TOPRIGHT | EMBEDDED_WINDOW_BOTTOMRIGHT):
391 self._rightEmbWindow = self._CreateEmbeddedWindow(self, (config.ReadInt("MDIEmbedRightSize", defaultHSize), -1), wx.LAYOUT_VERTICAL, wx.LAYOUT_RIGHT, visible = config.ReadInt("MDIEmbedRightVisible", 1), sash = wx.SASH_LEFT)
392 else:
393 self._rightEmbWindow = None
394 if windows & EMBEDDED_WINDOW_TOPRIGHT:
395 self._topRightEmbWindow = self._CreateEmbeddedWindow(self._rightEmbWindow, (-1, config.ReadInt("MDIEmbedTopRightSize", defaultSubVSize)), wx.LAYOUT_HORIZONTAL, wx.LAYOUT_TOP, visible = config.ReadInt("MDIEmbedTopRightVisible", 1), sash = wx.SASH_BOTTOM)
396 else:
397 self._topRightEmbWindow = None
398 if windows & EMBEDDED_WINDOW_BOTTOMRIGHT:
399 self._bottomRightEmbWindow = self._CreateEmbeddedWindow(self._rightEmbWindow, (-1, config.ReadInt("MDIEmbedBottomRightSize", defaultSubVSize)), wx.LAYOUT_HORIZONTAL, wx.LAYOUT_BOTTOM, visible = config.ReadInt("MDIEmbedBottomRightVisible", 1))
400 else:
401 self._bottomRightEmbWindow = None
402 if windows & EMBEDDED_WINDOW_TOP:
403 self._topEmbWindow = self._CreateEmbeddedWindow(self, (-1, config.ReadInt("MDIEmbedTopSize", defaultVSize)), wx.LAYOUT_HORIZONTAL, wx.LAYOUT_TOP, visible = config.ReadInt("MDIEmbedTopVisible", 1), sash = wx.SASH_BOTTOM)
404 else:
405 self._topEmbWindow = None
406 if windows & EMBEDDED_WINDOW_BOTTOM:
407 self._bottomEmbWindow = self._CreateEmbeddedWindow(self, (-1, config.ReadInt("MDIEmbedBottomSize", defaultVSize)), wx.LAYOUT_HORIZONTAL, wx.LAYOUT_BOTTOM, visible = config.ReadInt("MDIEmbedBottomVisible", 1), sash = wx.SASH_TOP)
408 else:
409 self._bottomEmbWindow = None
410
411
412 def SaveEmbeddedWindowSizes(self):
413 """
414 Saves the sizes of the embedded windows.
415 """
416 config = wx.ConfigBase_Get()
417 if not self.IsMaximized():
418 config.WriteInt("MDIFrameXLoc", self.GetPositionTuple()[0])
419 config.WriteInt("MDIFrameYLoc", self.GetPositionTuple()[1])
420 config.WriteInt("MDIFrameXSize", self.GetSizeTuple()[0])
421 config.WriteInt("MDIFrameYSize", self.GetSizeTuple()[1])
422 config.WriteInt("MDIFrameMaximized", self.IsMaximized())
423 config.WriteInt("ViewToolBar", self._toolBar.IsShown())
424 config.WriteInt("ViewStatusBar", self.GetStatusBar().IsShown())
425
426 if self._leftEmbWindow:
427 config.WriteInt("MDIEmbedLeftSize", self._leftEmbWindow.GetSize()[0])
428 config.WriteInt("MDIEmbedLeftVisible", self._leftEmbWindow.IsShown())
429 if self._topLeftEmbWindow:
430 if self._topLeftEmbWindow._sizeBeforeHidden:
431 size = self._topLeftEmbWindow._sizeBeforeHidden[1]
432 else:
433 size = self._topLeftEmbWindow.GetSize()[1]
434 config.WriteInt("MDIEmbedTopLeftSize", size)
435 config.WriteInt("MDIEmbedTopLeftVisible", self._topLeftEmbWindow.IsShown())
436 if self._bottomLeftEmbWindow:
437 if self._bottomLeftEmbWindow._sizeBeforeHidden:
438 size = self._bottomLeftEmbWindow._sizeBeforeHidden[1]
439 else:
440 size = self._bottomLeftEmbWindow.GetSize()[1]
441 config.WriteInt("MDIEmbedBottomLeftSize", size)
442 config.WriteInt("MDIEmbedBottomLeftVisible", self._bottomLeftEmbWindow.IsShown())
443 if self._rightEmbWindow:
444 config.WriteInt("MDIEmbedRightSize", self._rightEmbWindow.GetSize()[0])
445 config.WriteInt("MDIEmbedRightVisible", self._rightEmbWindow.IsShown())
446 if self._topRightEmbWindow:
447 if self._topRightEmbWindow._sizeBeforeHidden:
448 size = self._topRightEmbWindow._sizeBeforeHidden[1]
449 else:
450 size = self._topRightEmbWindow.GetSize()[1]
451 config.WriteInt("MDIEmbedTopRightSize", size)
452 config.WriteInt("MDIEmbedTopRightVisible", self._topRightEmbWindow.IsShown())
453 if self._bottomRightEmbWindow:
454 if self._bottomRightEmbWindow._sizeBeforeHidden:
455 size = self._bottomRightEmbWindow._sizeBeforeHidden[1]
456 else:
457 size = self._bottomRightEmbWindow.GetSize()[1]
458 config.WriteInt("MDIEmbedBottomRightSize", size)
459 config.WriteInt("MDIEmbedBottomRightVisible", self._bottomRightEmbWindow.IsShown())
460 if self._topEmbWindow:
461 config.WriteInt("MDIEmbedTopSize", self._topEmbWindow.GetSize()[1])
462 config.WriteInt("MDIEmbedTopVisible", self._topEmbWindow.IsShown())
463 if self._bottomEmbWindow:
464 config.WriteInt("MDIEmbedBottomSize", self._bottomEmbWindow.GetSize()[1])
465 config.WriteInt("MDIEmbedBottomVisible", self._bottomEmbWindow.IsShown())
466
467
468 def GetEmbeddedWindow(self, loc):
469 """
470 Returns the instance of the embedded window specified by the embedded window location constant.
471 """
472 if loc == EMBEDDED_WINDOW_TOP:
473 return self._topEmbWindow
474 elif loc == EMBEDDED_WINDOW_BOTTOM:
475 return self._bottomEmbWindow
476 elif loc == EMBEDDED_WINDOW_LEFT:
477 return self._leftEmbWindow
478 elif loc == EMBEDDED_WINDOW_RIGHT:
479 return self._rightEmbWindow
480 elif loc == EMBEDDED_WINDOW_TOPLEFT:
481 return self._topLeftEmbWindow
482 elif loc == EMBEDDED_WINDOW_BOTTOMLEFT:
483 return self._bottomLeftEmbWindow
484 elif loc == EMBEDDED_WINDOW_TOPRIGHT:
485 return self._topRightEmbWindow
486 elif loc == EMBEDDED_WINDOW_BOTTOMRIGHT:
487 return self._bottomRightEmbWindow
488 return None
489
490
491 def _CreateEmbeddedWindow(self, parent, size, orientation, alignment, visible = True, sash = None):
492 """
493 Creates the embedded window with the specified size, orientation, and alignment. If the
494 window is not visible it will retain the size with which it was last viewed.
495 """
496 window = wx.SashLayoutWindow(parent, wx.NewId(), style = wx.NO_BORDER | wx.SW_3D)
497 window.SetDefaultSize(size)
498 window.SetOrientation(orientation)
499 window.SetAlignment(alignment)
500 if sash != None: # wx.SASH_TOP is 0 so check for None instead of just doing "if sash:"
501 window.SetSashVisible(sash, True)
502 ####
503 def OnEmbeddedWindowSashDrag(event):
504 if event.GetDragStatus() == wx.SASH_STATUS_OUT_OF_RANGE:
505 return
506 sashWindow = event.GetEventObject()
507 if sashWindow.GetAlignment() == wx.LAYOUT_TOP or sashWindow.GetAlignment() == wx.LAYOUT_BOTTOM:
508 size = wx.Size(-1, event.GetDragRect().height)
509 else:
510 size = wx.Size(event.GetDragRect().width, -1)
511 event.GetEventObject().SetDefaultSize(size)
512 self._LayoutFrame()
513 sashWindow.Refresh()
514 if isinstance(sashWindow.GetParent(), wx.SashLayoutWindow):
515 sashWindow.Show()
516 parentSashWindow = sashWindow.GetParent() # Force a refresh
517 parentSashWindow.Layout()
518 parentSashWindow.Refresh()
519 parentSashWindow.SetSize((parentSashWindow.GetSize().width + 1, parentSashWindow.GetSize().height + 1))
520 ####
521 wx.EVT_SASH_DRAGGED(window, window.GetId(), OnEmbeddedWindowSashDrag)
522 window._sizeBeforeHidden = None
523 if not visible:
524 window.Show(False)
525 if isinstance(parent, wx.SashLayoutWindow): # It's a window embedded in another sash window so remember its actual size to show it again
526 window._sizeBeforeHidden = size
527 return window
528
529
530 def ShowEmbeddedWindow(self, window, show = True):
531 """
532 Shows or hides the embedded window specified by the embedded window location constant.
533 """
534 window.Show(show)
535 if isinstance(window.GetParent(), wx.SashLayoutWindow): # It is a parent sashwindow with multiple embedded sashwindows
536 parentSashWindow = window.GetParent()
537 if show: # Make sure it is visible in case all of the subwindows were hidden
538 parentSashWindow.Show()
539 if show and window._sizeBeforeHidden:
540 if window._sizeBeforeHidden[1] == parentSashWindow.GetClientSize()[1]:
541 if window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMLEFT) and self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPLEFT).IsShown():
542 window.SetDefaultSize((window._sizeBeforeHidden[0], window._sizeBeforeHidden[0] - self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPLEFT).GetSize()[1]))
543 elif window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPLEFT) and self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMLEFT).IsShown():
544 window.SetDefaultSize((window._sizeBeforeHidden[0], window._sizeBeforeHidden[0] - self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMLEFT).GetSize()[1]))
545 elif window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMRIGHT) and self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPRIGHT).IsShown():
546 window.SetDefaultSize((window._sizeBeforeHidden[0], window._sizeBeforeHidden[0] - self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPRIGHT).GetSize()[1]))
547 elif window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPRIGHT) and self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMRIGHT).IsShown():
548 window.SetDefaultSize((window._sizeBeforeHidden[0], window._sizeBeforeHidden[0] - self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMRIGHT).GetSize()[1]))
549 else:
550 window.SetDefaultSize(window._sizeBeforeHidden)
551 # If it is not the size of the full parent sashwindow set the other window's size so that if it gets shown it will have a cooresponding size
552 if window._sizeBeforeHidden[1] < parentSashWindow.GetClientSize()[1]:
553 otherWindowSize = (-1, parentSashWindow.GetClientSize()[1] - window._sizeBeforeHidden[1])
554 if window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMLEFT):
555 self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPLEFT).SetDefaultSize(otherWindowSize)
556 elif window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPLEFT):
557 self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMLEFT).SetDefaultSize(otherWindowSize)
558 elif window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMRIGHT):
559 self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPRIGHT).SetDefaultSize(otherWindowSize)
560 elif window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPRIGHT):
561 self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMRIGHT).SetDefaultSize(otherWindowSize)
562
563 if not show:
564 if window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMRIGHT) and not self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPRIGHT).IsShown() \
565 or window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPRIGHT) and not self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMRIGHT).IsShown() \
566 or window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMLEFT) and not self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPLEFT).IsShown() \
567 or window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPLEFT) and not self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMLEFT).IsShown():
568 parentSashWindow.Hide() # Hide the parent sashwindow if all of the children are hidden
569 parentSashWindow.Layout() # Force a refresh
570 parentSashWindow.Refresh()
571 parentSashWindow.SetSize((parentSashWindow.GetSize().width + 1, parentSashWindow.GetSize().height + 1))
572 self._LayoutFrame()
573
574
575 def HideEmbeddedWindow(self):
576 """
577 Hides the embedded window specified by the embedded window location constant.
578 """
579 self.ShowEmbeddedWindow(show = False)
580
581
582class DocTabbedChildFrame(wx.Panel):
583 """
584 The wxDocMDIChildFrame class provides a default frame for displaying
585 documents on separate windows. This class can only be used for MDI child
586 frames.
587
588 The class is part of the document/view framework supported by wxWindows,
589 and cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplate
590 classes.
591 """
592
593
594 def __init__(self, doc, view, frame, id, title, pos = wx.DefaultPosition, size = wx.DefaultSize, style = wx.DEFAULT_FRAME_STYLE, name = "frame"):
595 """
596 Constructor. Note that the event table must be rebuilt for the
597 frame since the EvtHandler is not virtual.
598 """
599 wx.Panel.__init__(self, frame.GetNotebook(), id)
600 self._childDocument = doc
601 self._childView = view
602 frame.AddNotebookPage(self, doc.GetPrintableName())
603 if view:
604 view.SetFrame(self)
605
606
607 def GetIcon(self):
608 """
609 Dummy method since the icon of tabbed frames are managed by the notebook.
610 """
611 return None
612
613
614 def SetIcon(self, icon):
615 """
616 Dummy method since the icon of tabbed frames are managed by the notebook.
617 """
618 pass
619
620
621 def Destroy(self):
622 """
623 Removes the current notebook page.
624 """
625 wx.GetApp().GetTopWindow().RemoveNotebookPage(self)
626
627
628 def SetFocus(self):
629 """
630 Activates the current notebook page.
631 """
632 wx.GetApp().GetTopWindow().ActivateNotebookPage(self)
633
634
635 def Activate(self): # Need this in case there are embedded sash windows and such, OnActivate is not getting called
636 """
637 Activates the current view.
638 """
639 # Called by Project Editor
640 if self._childView:
641 self._childView.Activate(True)
642
643
644 def GetTitle(self):
645 """
646 Returns the frame's title.
647 """
648 wx.GetApp().GetTopWindow().GetNotebookPageTitle(self)
649
650
651 def SetTitle(self, title):
652 """
653 Sets the frame's title.
654 """
655 wx.GetApp().GetTopWindow().SetNotebookPageTitle(self, title)
656
657
658 def ProcessEvent(event):
659 """
660 Processes an event, searching event tables and calling zero or more
661 suitable event handler function(s). Note that the ProcessEvent
662 method is called from the wxPython docview framework directly since
663 wxPython does not have a virtual ProcessEvent function.
664 """
665 if not self._childView or not self._childView.ProcessEvent(event):
666 if not isinstance(event, wx.CommandEvent) or not self.GetParent() or not self.GetParent().ProcessEvent(event):
667 return False
668 else:
669 return True
670 else:
671 return True
672
673
674 def GetDocument(self):
675 """
676 Returns the document associated with this frame.
677 """
678 return self._childDocument
679
680
681 def SetDocument(self, document):
682 """
683 Sets the document for this frame.
684 """
685 self._childDocument = document
686
687
688 def GetView(self):
689 """
690 Returns the view associated with this frame.
691 """
692 return self._childView
693
694
695 def SetView(self, view):
696 """
697 Sets the view for this frame.
698 """
699 self._childView = view
d1dc2b32 700
3fa8f722
RD
701
702class DocTabbedParentFrame(wx.Frame, DocFrameMixIn, DocMDIParentFrameMixIn):
703 """
704 The DocTabbedParentFrame class provides a default top-level frame for
705 applications using the document/view framework. This class can only be
706 used for MDI parent frames that use a tabbed interface.
707
708 It cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplate
709 classes.
710 """
711
712
713 def __init__(self, docManager, frame, id, title, pos = wx.DefaultPosition, size = wx.DefaultSize, style = wx.DEFAULT_FRAME_STYLE, name = "DocTabbedParentFrame", embeddedWindows = 0):
714 """
715 Constructor. Note that the event table must be rebuilt for the
716 frame since the EvtHandler is not virtual.
717 """
718 pos, size = self._GetPosSizeFromConfig(pos, size)
719 wx.Frame.__init__(self, frame, id, title, pos, size, style, name)
720
721 # From docview.MDIParentFrame
d1dc2b32
RD
722 self._docManager = docManager
723
3fa8f722 724 wx.EVT_CLOSE(self, self.OnCloseWindow)
d1dc2b32 725
3fa8f722
RD
726 wx.EVT_MENU(self, wx.ID_EXIT, self.OnExit)
727 wx.EVT_MENU_RANGE(self, wx.ID_FILE1, wx.ID_FILE9, self.OnMRUFile)
d1dc2b32 728
3fa8f722
RD
729 wx.EVT_MENU(self, wx.ID_NEW, self.ProcessEvent)
730 wx.EVT_MENU(self, wx.ID_OPEN, self.ProcessEvent)
731 wx.EVT_MENU(self, wx.ID_CLOSE_ALL, self.ProcessEvent)
732 wx.EVT_MENU(self, wx.ID_CLOSE, self.ProcessEvent)
733 wx.EVT_MENU(self, wx.ID_REVERT, self.ProcessEvent)
734 wx.EVT_MENU(self, wx.ID_SAVE, self.ProcessEvent)
735 wx.EVT_MENU(self, wx.ID_SAVEAS, self.ProcessEvent)
736 wx.EVT_MENU(self, wx.ID_UNDO, self.ProcessEvent)
737 wx.EVT_MENU(self, wx.ID_REDO, self.ProcessEvent)
738 wx.EVT_MENU(self, wx.ID_PRINT, self.ProcessEvent)
739 wx.EVT_MENU(self, wx.ID_PRINT_SETUP, self.ProcessEvent)
740 wx.EVT_MENU(self, wx.ID_PREVIEW, self.ProcessEvent)
741 wx.EVT_MENU(self, wx.ID_ABOUT, self.OnAbout)
d1dc2b32 742
3fa8f722
RD
743 wx.EVT_UPDATE_UI(self, wx.ID_NEW, self.ProcessUpdateUIEvent)
744 wx.EVT_UPDATE_UI(self, wx.ID_OPEN, self.ProcessUpdateUIEvent)
745 wx.EVT_UPDATE_UI(self, wx.ID_CLOSE_ALL, self.ProcessUpdateUIEvent)
746 wx.EVT_UPDATE_UI(self, wx.ID_CLOSE, self.ProcessUpdateUIEvent)
747 wx.EVT_UPDATE_UI(self, wx.ID_REVERT, self.ProcessUpdateUIEvent)
748 wx.EVT_UPDATE_UI(self, wx.ID_SAVE, self.ProcessUpdateUIEvent)
749 wx.EVT_UPDATE_UI(self, wx.ID_SAVEAS, self.ProcessUpdateUIEvent)
750 wx.EVT_UPDATE_UI(self, wx.ID_UNDO, self.ProcessUpdateUIEvent)
751 wx.EVT_UPDATE_UI(self, wx.ID_REDO, self.ProcessUpdateUIEvent)
752 wx.EVT_UPDATE_UI(self, wx.ID_PRINT, self.ProcessUpdateUIEvent)
753 wx.EVT_UPDATE_UI(self, wx.ID_PRINT_SETUP, self.ProcessUpdateUIEvent)
754 wx.EVT_UPDATE_UI(self, wx.ID_PREVIEW, self.ProcessUpdateUIEvent)
755 # End From docview.MDIParentFrame
756
757 self.CreateNotebook()
758 self._InitFrame(embeddedWindows)
759
d1dc2b32 760
3fa8f722 761 def _LayoutFrame(self):
d1dc2b32 762 """
3fa8f722 763 Lays out the frame.
d1dc2b32 764 """
3fa8f722
RD
765 wx.LayoutAlgorithm().LayoutFrame(self, self._notebook)
766
767
768 def CreateNotebook(self):
769 """
770 Creates the notebook to use for the tabbed document interface.
771 """
772 self._notebook = wx.Notebook(self, wx.NewId())
773 # self._notebook.SetSizer(wx.NotebookSizer(self._notebook))
774 wx.EVT_NOTEBOOK_PAGE_CHANGED(self, self._notebook.GetId(), self.OnNotebookPageChanged)
775 wx.EVT_RIGHT_DOWN(self._notebook, self.OnNotebookRightClick)
776
777 templates = wx.GetApp().GetDocumentManager().GetTemplates()
778 iconList = wx.ImageList(16, 16, initialCount = len(templates))
779 self._iconIndexLookup = []
780 for template in templates:
781 icon = template.GetIcon()
782 if icon:
783 if icon.GetHeight() != 16:
784 icon.SetHeight(16) # wxBug: img2py.py uses EmptyIcon which is 32x32
785 if icon.GetWidth() != 16:
786 icon.SetWidth(16) # wxBug: img2py.py uses EmptyIcon which is 32x32
787 iconIndex = iconList.AddIcon(icon)
788 self._iconIndexLookup.append((template, iconIndex))
789
790 icon = getBlankIcon()
791 if icon.GetHeight() != 16:
792 icon.SetHeight(16) # wxBug: img2py.py uses EmptyIcon which is 32x32
793 if icon.GetWidth() != 16:
794 icon.SetWidth(16) # wxBug: img2py.py uses EmptyIcon which is 32x32
795 self._blankIconIndex = iconList.AddIcon(icon)
796 self._notebook.AssignImageList(iconList)
d1dc2b32
RD
797
798
3fa8f722 799 def GetNotebook(self):
d1dc2b32 800 """
3fa8f722 801 Returns the notebook used by the tabbed document interface.
d1dc2b32 802 """
3fa8f722
RD
803 return self._notebook
804
805
806 def GetActiveChild(self):
807 """
808 Returns the active notebook page, which to the framework is treated as
809 a document frame.
810 """
811 index = self._notebook.GetSelection()
812 if index == -1:
813 return None
814 return self._notebook.GetPage(index)
d1dc2b32
RD
815
816
3fa8f722 817 def OnNotebookPageChanged(self, event):
d1dc2b32 818 """
3fa8f722 819 Activates a notebook page's view when it is selected.
d1dc2b32 820 """
3fa8f722
RD
821 index = self._notebook.GetSelection()
822 if index > -1:
823 self._notebook.GetPage(index).GetView().Activate()
d1dc2b32
RD
824
825
3fa8f722
RD
826 def OnNotebookRightClick(self, event):
827 """
828 Handles right clicks for the notebook, enabling users to either close
829 a tab or select from the available documents if the user clicks on the
830 notebook's white space.
831 """
832 index, type = self._notebook.HitTest(event.GetPosition())
833 menu = wx.Menu()
834 x, y = event.GetX(), event.GetY()
835 if index > -1:
836 doc = self._notebook.GetPage(index).GetView().GetDocument()
837 id = wx.NewId()
838 menu.Append(id, _("Close"))
839 def OnRightMenuSelect(event):
840 doc.DeleteAllViews()
841 wx.EVT_MENU(self, id, OnRightMenuSelect)
842 if self._notebook.GetPageCount() > 1:
843 menu.AppendSeparator()
844 tabsMenu = wx.Menu()
845 menu.AppendMenu(wx.NewId(), _("Select Tab"), tabsMenu)
846 else:
847 y = y - 25 # wxBug: It is offsetting click events in the blank notebook area
848 tabsMenu = menu
849
850 if self._notebook.GetPageCount() > 1:
851 selectIDs = {}
852 for i in range(0, self._notebook.GetPageCount()):
853 id = wx.NewId()
854 selectIDs[id] = i
855 tabsMenu.Append(id, self._notebook.GetPageText(i))
856 def OnRightMenuSelect(event):
857 self._notebook.SetSelection(selectIDs[event.GetId()])
858 wx.EVT_MENU(self, id, OnRightMenuSelect)
859
860 self._notebook.PopupMenu(menu, wx.Point(x, y))
861 menu.Destroy()
862
863
864 def AddNotebookPage(self, panel, title):
865 """
866 Adds a document page to the notebook.
867 """
868 self._notebook.AddPage(panel, title)
869 index = self._notebook.GetPageCount() - 1
870 self._notebook.SetSelection(index)
d1dc2b32 871
3fa8f722
RD
872 found = False # Now set the icon
873 template = panel.GetDocument().GetDocumentTemplate()
874 if template:
875 for t, iconIndex in self._iconIndexLookup:
876 if t is template:
877 self._notebook.SetPageImage(index, iconIndex)
878 found = True
879 break
880 if not found:
881 self._notebook.SetPageImage(index, self._blankIconIndex)
882 self._notebook.Layout()
d1dc2b32 883
3fa8f722
RD
884
885 def RemoveNotebookPage(self, panel):
d1dc2b32 886 """
3fa8f722 887 Removes a document page from the notebook.
d1dc2b32 888 """
3fa8f722
RD
889 index = self.GetNotebookPageIndex(panel)
890 if index > -1:
891 self._notebook.DeletePage(index)
892
893
894 def ActivateNotebookPage(self, panel):
895 """
896 Sets the notebook to the specified panel.
897 """
898 index = self.GetNotebookPageIndex(panel)
899 if index > -1:
900 self._notebook.SetSelection(index)
901
902
903 def GetNotebookPageTitle(self, panel):
904 self._notebook.GetPageText(self.GetNotebookPageIndex(panel))
905
906
907 def SetNotebookPageTitle(self, panel, title):
908 self._notebook.SetPageText(self.GetNotebookPageIndex(panel), title)
909
910
911 def GetNotebookPageIndex(self, panel):
912 """
913 Returns the index of particular notebook panel.
914 """
915 index = -1
916 for i in range(self._notebook.GetPageCount()):
917 if self._notebook.GetPage(i) == panel:
918 index = i
919 break
920 return index
921
922
923 def ProcessEvent(self, event):
924 """
925 Processes an event, searching event tables and calling zero or more
926 suitable event handler function(s). Note that the ProcessEvent
927 method is called from the wxPython docview framework directly since
928 wxPython does not have a virtual ProcessEvent function.
929 """
930 if wx.GetApp().ProcessEventBeforeWindows(event):
931 return True
932 if self._docManager and self._docManager.ProcessEvent(event):
933 return True
934 return DocMDIParentFrameMixIn.ProcessEvent(self, event)
935
936
937 def ProcessUpdateUIEvent(self, event):
938 """
939 Processes a UI event, searching event tables and calling zero or more
940 suitable event handler function(s). Note that the ProcessEvent
941 method is called from the wxPython docview framework directly since
942 wxPython does not have a virtual ProcessEvent function.
943 """
944 if wx.GetApp().ProcessUpdateUIEventBeforeWindows(event):
945 return True
946 if self._docManager and self._docManager.ProcessUpdateUIEvent(event):
947 return True
948 return DocMDIParentFrameMixIn.ProcessUpdateUIEvent(self, event)
949
950
951 def OnExit(self, event):
952 """
953 Called when File/Exit is chosen and closes the window.
954 """
955 self.Close()
956
957
958 def OnMRUFile(self, event):
959 """
960 Opens the appropriate file when it is selected from the file history
961 menu.
962 """
963 n = event.GetId() - wx.ID_FILE1
964 filename = self._docManager.GetHistoryFile(n)
965 if filename:
966 self._docManager.CreateDocument(filename, wx.lib.docview.DOC_SILENT)
d1dc2b32 967 else:
3fa8f722
RD
968 self._docManager.RemoveFileFromHistory(n)
969 msgTitle = wx.GetApp().GetAppName()
970 if not msgTitle:
971 msgTitle = _("File Error")
972 wx.MessageBox("The file '%s' doesn't exist and couldn't be opened.\nIt has been removed from the most recently used files list" % FileNameFromPath(file),
973 msgTitle,
974 wx.OK | wx.ICON_EXCLAMATION,
975 self)
d1dc2b32 976
3fa8f722
RD
977
978 def OnSize(self, event):
d1dc2b32 979 """
3fa8f722 980 Called when the frame is resized and lays out the client window.
d1dc2b32 981 """
3fa8f722
RD
982 # Needed in case there are splitpanels around the mdi frame
983 self._LayoutFrame()
d1dc2b32
RD
984
985
3fa8f722
RD
986 def OnCloseWindow(self, event):
987 """
988 Called when the frame is closed. Remembers the frame size.
989 """
990 self.SaveEmbeddedWindowSizes()
991
992 # save and close services last
993 for service in wx.GetApp().GetServices():
994 if not service.OnCloseFrame(event):
995 return
996
997 # From docview.MDIParentFrame
998 if self._docManager.Clear(not event.CanVeto()):
999 self.Destroy()
1000 else:
1001 event.Veto()
1002
1003
1004class DocMDIChildFrame(wx.MDIChildFrame):
d1dc2b32 1005 """
3fa8f722
RD
1006 The wxDocMDIChildFrame class provides a default frame for displaying
1007 documents on separate windows. This class can only be used for MDI child
1008 frames.
1009
1010 The class is part of the document/view framework supported by wxWindows,
1011 and cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplate
1012 classes.
d1dc2b32
RD
1013 """
1014
1015
3fa8f722 1016 def __init__(self, doc, view, frame, id, title, pos = wx.DefaultPosition, size = wx.DefaultSize, style = wx.DEFAULT_FRAME_STYLE, name = "frame"):
d1dc2b32 1017 """
3fa8f722
RD
1018 Constructor. Note that the event table must be rebuilt for the
1019 frame since the EvtHandler is not virtual.
d1dc2b32 1020 """
3fa8f722
RD
1021 wx.MDIChildFrame.__init__(self, frame, id, title, pos, size, style, name)
1022 self._childDocument = doc
1023 self._childView = view
1024 if view:
1025 view.SetFrame(self)
1026 # self.Create(doc, view, frame, id, title, pos, size, style, name)
1027 self._activeEvent = None
1028 self._activated = 0
1029 wx.EVT_ACTIVATE(self, self.OnActivate)
1030 wx.EVT_CLOSE(self, self.OnCloseWindow)
1031
1032 if frame: # wxBug: For some reason the EVT_ACTIVATE event is not getting triggered for the first mdi client window that is opened so we have to do it manually
1033 mdiChildren = filter(lambda x: isinstance(x, wx.MDIChildFrame), frame.GetChildren())
1034 if len(mdiChildren) == 1:
1035 self.Activate()
1036
1037
1038## # Couldn't get this to work, but seems to work fine with single stage construction
1039## def Create(self, doc, view, frame, id, title, pos, size, style, name):
1040## self._childDocument = doc
1041## self._childView = view
1042## if wx.MDIChildFrame.Create(self, frame, id, title, pos, size, style, name):
1043## if view:
1044## view.SetFrame(self)
1045## return True
1046## return False
1047
1048
1049
1050 def Activate(self): # Need this in case there are embedded sash windows and such, OnActivate is not getting called
1051 """
1052 Activates the current view.
1053 """
1054 if self._childView:
1055 self._childView.Activate(True)
1056
1057
1058 def ProcessEvent(event):
1059 """
1060 Processes an event, searching event tables and calling zero or more
1061 suitable event handler function(s). Note that the ProcessEvent
1062 method is called from the wxPython docview framework directly since
1063 wxPython does not have a virtual ProcessEvent function.
1064 """
1065 if self._activeEvent == event:
1066 return False
1067
1068 self._activeEvent = event # Break recursion loops
1069
1070 if self._childView:
1071 self._childView.Activate(True)
1072
1073 if not self._childView or not self._childView.ProcessEvent(event):
1074 if not isinstance(event, wx.CommandEvent) or not self.GetParent() or not self.GetParent().ProcessEvent(event):
1075 ret = False
74b89458 1076 else:
3fa8f722
RD
1077 ret = True
1078 else:
1079 ret = True
74b89458 1080
3fa8f722
RD
1081 self._activeEvent = None
1082 return ret
1083
1084
1085 def OnActivate(self, event):
1086 """
1087 Sets the currently active view to be the frame's view. You may need to
1088 override (but still call) this function in order to set the keyboard
1089 focus for your subwindow.
1090 """
1091 if self._activated != 0:
1092 return True
1093 self._activated += 1
1094 wx.MDIChildFrame.Activate(self)
1095 if event.GetActive() and self._childView:
1096 self._childView.Activate(event.GetActive())
1097 self._activated = 0
1098
1099
1100 def OnCloseWindow(self, event):
1101 """
1102 Closes and deletes the current view and document.
1103 """
1104 if self._childView:
1105 ans = False
1106 if not event.CanVeto():
1107 ans = True
74b89458 1108 else:
3fa8f722
RD
1109 ans = self._childView.Close(deleteWindow = False)
1110
1111 if ans:
1112 self._childView.Activate(False)
1113 self._childView.Destroy()
1114 self._childView = None
1115 if self._childDocument:
1116 self._childDocument.Destroy() # This isn't in the wxWindows codebase but the document needs to be disposed of somehow
1117 self._childDocument = None
1118 self.Destroy()
1119 else:
1120 event.Veto()
1121 else:
1122 event.Veto()
1123
1124
1125 def GetDocument(self):
1126 """
1127 Returns the document associated with this frame.
1128 """
1129 return self._childDocument
1130
1131
1132 def SetDocument(self, document):
1133 """
1134 Sets the document for this frame.
1135 """
1136 self._childDocument = document
1137
1138
1139 def GetView(self):
1140 """
1141 Returns the view associated with this frame.
1142 """
1143 return self._childView
74b89458 1144
74b89458 1145
3fa8f722 1146 def SetView(self, view):
74b89458 1147 """
3fa8f722 1148 Sets the view for this frame.
74b89458 1149 """
3fa8f722
RD
1150 self._childView = view
1151
74b89458 1152
d1dc2b32
RD
1153
1154
3fa8f722
RD
1155
1156class DocService(wx.EvtHandler):
1157 """
1158 An abstract class used to add reusable services to a docview application.
1159 """
1160
1161
1162 def __init__(self):
1163 """Initializes the DocService."""
1164 pass
d1dc2b32
RD
1165
1166
1167 def GetDocumentManager(self):
3fa8f722 1168 """Returns the DocManager for the docview application."""
d1dc2b32
RD
1169 return self._docManager
1170
1171
1172 def SetDocumentManager(self, docManager):
3fa8f722 1173 """Sets the DocManager for the docview application."""
d1dc2b32 1174 self._docManager = docManager
3fa8f722
RD
1175
1176
1177 def InstallControls(self, frame, menuBar = None, toolBar = None, statusBar = None, document = None):
1178 """Called to install controls into the menubar and toolbar of a SDI or MDI window. Override this method for a particular service."""
1179 pass
d1dc2b32
RD
1180
1181
1182 def ProcessEventBeforeWindows(self, event):
1183 """
3fa8f722
RD
1184 Processes an event before the main window has a chance to process the window.
1185 Override this method for a particular service.
d1dc2b32 1186 """
d1dc2b32
RD
1187 return False
1188
1189
1190 def ProcessUpdateUIEventBeforeWindows(self, event):
1191 """
3fa8f722
RD
1192 Processes a UI event before the main window has a chance to process the window.
1193 Override this method for a particular service.
d1dc2b32 1194 """
d1dc2b32
RD
1195 return False
1196
1197
1198 def ProcessEvent(self, event):
1199 """
1200 Processes an event, searching event tables and calling zero or more
1201 suitable event handler function(s). Note that the ProcessEvent
1202 method is called from the wxPython docview framework directly since
1203 wxPython does not have a virtual ProcessEvent function.
1204 """
d1dc2b32
RD
1205 return False
1206
1207
1208 def ProcessUpdateUIEvent(self, event):
1209 """
1210 Processes a UI event, searching event tables and calling zero or more
1211 suitable event handler function(s). Note that the ProcessEvent
1212 method is called from the wxPython docview framework directly since
1213 wxPython does not have a virtual ProcessEvent function.
1214 """
d1dc2b32
RD
1215 return False
1216
1217
3fa8f722 1218 def OnCloseFrame(self, event):
d1dc2b32 1219 """
3fa8f722
RD
1220 Called when the a docview frame is being closed. Override this method
1221 so a service can either do cleanup or veto the frame being closed by
1222 returning false.
d1dc2b32 1223 """
3fa8f722 1224 return True
d1dc2b32
RD
1225
1226
3fa8f722 1227 def OnExit(self):
d1dc2b32 1228 """
3fa8f722
RD
1229 Called when the the docview application is being closed. Override this method
1230 so a service can either do cleanup or veto the frame being closed by
1231 returning false.
d1dc2b32 1232 """
3fa8f722 1233 pass
d1dc2b32
RD
1234
1235
3fa8f722 1236 def GetMenuItemPos(self, menu, id):
d1dc2b32 1237 """
3fa8f722
RD
1238 Utility method used to find the position of a menu item so that services can
1239 easily find where to insert a menu item in InstallControls.
1240 """
1241 menuItems = menu.GetMenuItems()
1242 for i, menuItem in enumerate(menuItems):
1243 if menuItem.GetId() == id:
1244 return i
1245 return i
1246
1247
1248 def GetView(self):
1249 """
1250 Called by WindowMenuService to get views for services that don't
1251 have dedicated documents such as the Outline Service.
d1dc2b32 1252 """
d1dc2b32
RD
1253 return None
1254
1255
3fa8f722
RD
1256class DocOptionsService(DocService):
1257 """
1258 A service that implements an options menu item and an options dialog with
1259 notebook tabs. New tabs can be added by other services by calling the
1260 "AddOptionsPanel" method.
1261 """
1262
1263
1264 def __init__(self, showGeneralOptions=True, allowModeChanges=True):
d1dc2b32 1265 """
3fa8f722
RD
1266 Initializes the options service with the option of suppressing the default
1267 general options pane that is included with the options service by setting
1268 showGeneralOptions to False. It allowModeChanges is set to False, the
1269 default general options pane will allow users to change the document
1270 interface mode between SDI and MDI modes.
d1dc2b32 1271 """
3fa8f722
RD
1272 DocService.__init__(self)
1273 self.ClearOptionsPanels()
1274 self._allowModeChanges = allowModeChanges
1275 self._toolOptionsID = wx.NewId()
1276 if showGeneralOptions:
1277 self.AddOptionsPanel(GeneralOptionsPanel)
d1dc2b32 1278
3fa8f722
RD
1279
1280 def InstallControls(self, frame, menuBar = None, toolBar = None, statusBar = None, document = None):
d1dc2b32 1281 """
3fa8f722 1282 Installs a "Tools" menu with an "Options" menu item.
d1dc2b32 1283 """
3fa8f722
RD
1284 toolsMenuIndex = menuBar.FindMenu(_("&Tools"))
1285 if toolsMenuIndex > -1:
1286 toolsMenu = menuBar.GetMenu(toolsMenuIndex)
d1dc2b32 1287 else:
3fa8f722
RD
1288 toolsMenu = wx.Menu()
1289 if toolsMenuIndex == -1:
1290 formatMenuIndex = menuBar.FindMenu(_("&Format"))
1291 menuBar.Insert(formatMenuIndex + 1, toolsMenu, _("&Tools"))
1292 if toolsMenu:
1293 if toolsMenu.GetMenuItemCount():
1294 toolsMenu.AppendSeparator()
1295 toolsMenu.Append(self._toolOptionsID, _("&Options..."), _("Sets options"))
1296 wx.EVT_MENU(frame, self._toolOptionsID, frame.ProcessEvent)
1297
d1dc2b32 1298
3fa8f722 1299 def ProcessEvent(self, event):
d1dc2b32 1300 """
3fa8f722 1301 Checks to see if the "Options" menu item has been selected.
d1dc2b32 1302 """
3fa8f722
RD
1303 id = event.GetId()
1304 if id == self._toolOptionsID:
1305 self.OnOptions(event)
1306 return True
1307 else:
1308 return False
d1dc2b32
RD
1309
1310
3fa8f722 1311 def GetAllowModeChanges(self):
d1dc2b32 1312 """
3fa8f722
RD
1313 Return true if the default general options pane should allow users to
1314 change the document interface mode between SDI and MDI modes.
d1dc2b32 1315 """
3fa8f722 1316 return self._allowModeChanges
d1dc2b32
RD
1317
1318
3fa8f722 1319 def SetAllowModeChanges(self, allowModeChanges):
d1dc2b32 1320 """
3fa8f722
RD
1321 Set to true if the default general options pane should allow users to
1322 change the document interface mode between SDI and MDI modes.
d1dc2b32 1323 """
3fa8f722 1324 self._allowModeChanges = allowModeChanges
d1dc2b32 1325
d1dc2b32 1326
3fa8f722
RD
1327 def ClearOptionsPanels(self):
1328 """
1329 Clears all of the options panels that have been added into the
1330 options dialog.
1331 """
1332 self._optionsPanels = []
d1dc2b32
RD
1333
1334
3fa8f722 1335 def AddOptionsPanel(self, optionsPanel):
d1dc2b32 1336 """
3fa8f722 1337 Adds an options panel to the options dialog.
d1dc2b32 1338 """
3fa8f722 1339 self._optionsPanels.append(optionsPanel)
d1dc2b32
RD
1340
1341
3fa8f722 1342 def OnOptions(self, event):
d1dc2b32 1343 """
3fa8f722 1344 Shows the options dialog, called when the "Options" menu item is selected.
d1dc2b32 1345 """
3fa8f722
RD
1346 if len(self._optionsPanels) == 0:
1347 return
1348 optionsDialog = OptionsDialog(wx.GetApp().GetTopWindow(), self._optionsPanels, self._docManager)
1349 if optionsDialog.ShowModal() == wx.ID_OK:
1350 optionsDialog.OnOK(optionsDialog) # wxBug: wxDialog should be calling this automatically but doesn't
1351 optionsDialog.Destroy()
1352
1353
1354class OptionsDialog(wx.Dialog):
1355 """
1356 A default options dialog used by the OptionsService that hosts a notebook
1357 tab of options panels.
1358 """
d1dc2b32 1359
d1dc2b32 1360
3fa8f722
RD
1361 def __init__(self, parent, optionsPanelClasses, docManager):
1362 """
1363 Initializes the options dialog with a notebook page that contains new
1364 instances of the passed optionsPanelClasses.
1365 """
bbf7159c 1366 wx.Dialog.__init__(self, parent, -1, _("Options"), size = (570, 365))
d1dc2b32 1367
3fa8f722
RD
1368 self._optionsPanels = []
1369 self._docManager = docManager
1370
1371 HALF_SPACE = 5
1372 SPACE = 10
d1dc2b32 1373
3fa8f722 1374 sizer = wx.BoxSizer(wx.VERTICAL)
d1dc2b32 1375
bbf7159c 1376 optionsNotebook = wx.Notebook(self, -1, size = (560, 325))
3fa8f722
RD
1377 sizer.Add(optionsNotebook, 0, wx.ALL | wx.EXPAND, SPACE)
1378 for optionsPanelClass in optionsPanelClasses:
1379 optionsPanel = optionsPanelClass(optionsNotebook, -1)
1380 self._optionsPanels.append(optionsPanel)
1381 sizer.Add(self.CreateButtonSizer(wx.OK | wx.CANCEL), 0, wx.ALIGN_RIGHT | wx.RIGHT | wx.BOTTOM, HALF_SPACE)
1382 self.SetSizer(sizer)
1383 self.Layout()
bbf7159c
RD
1384 if wx.Platform != '__WXMAC__' or len(optionsPanelClasses) < 6: # wxBug: Notebook tabs are truncated and user can't get to them on the Mac
1385 self.Fit()
3fa8f722
RD
1386 wx.CallAfter(self.DoRefresh)
1387
1388
1389 def DoRefresh(self):
d1dc2b32 1390 """
3fa8f722
RD
1391 wxBug: On Windows XP when using a multiline notebook the default page doesn't get
1392 drawn, but it works when using a single line notebook.
d1dc2b32 1393 """
3fa8f722 1394 self.Refresh()
d1dc2b32
RD
1395
1396
3fa8f722 1397 def GetDocManager(self):
d1dc2b32 1398 """
3fa8f722 1399 Returns the document manager passed to the OptionsDialog constructor.
d1dc2b32 1400 """
3fa8f722 1401 return self._docManager
d1dc2b32
RD
1402
1403
3fa8f722 1404 def OnOK(self, event):
d1dc2b32 1405 """
3fa8f722 1406 Calls the OnOK method of all of the OptionDialog's embedded panels
d1dc2b32 1407 """
3fa8f722
RD
1408 for optionsPanel in self._optionsPanels:
1409 optionsPanel.OnOK(event)
d1dc2b32 1410
d1dc2b32 1411
3fa8f722
RD
1412class GeneralOptionsPanel(wx.Panel):
1413 """
1414 A general options panel that is used in the OptionDialog to configure the
1415 generic properties of a pydocview application, such as "show tips at startup"
1416 and whether to use SDI or MDI for the application.
1417 """
d1dc2b32
RD
1418
1419
3fa8f722 1420 def __init__(self, parent, id):
d1dc2b32 1421 """
3fa8f722
RD
1422 Initializes the panel by adding an "Options" folder tab to the parent notebook and
1423 populating the panel with the generic properties of a pydocview application.
d1dc2b32 1424 """
3fa8f722
RD
1425 wx.Panel.__init__(self, parent, id)
1426 SPACE = 10
1427 HALF_SPACE = 5
1428 config = wx.ConfigBase_Get()
1429 self._showTipsCheckBox = wx.CheckBox(self, -1, _("Show tips at start up"))
1430 self._showTipsCheckBox.SetValue(config.ReadInt("ShowTipAtStartup", True))
1431 if wx.GetApp().GetService(DocOptionsService).GetAllowModeChanges():
1432 choices = [_("Show each document in its own window"), _("Show all documents in a single window with tabs")]
1433 if wx.Platform == "__WXMSW__":
1434 choices.append(_("Show all documents in a single window with child windows"))
1435 self._documentRadioBox = wx.RadioBox(self, -1, _("Document Interface"),
1436 choices = choices,
1437 majorDimension=1,
1438 )
1439 if config.ReadInt("UseWinMDI", False):
1440 self._documentRadioBox.SetSelection(2)
1441 elif config.ReadInt("UseMDI", True):
1442 self._documentRadioBox.SetSelection(1)
1443 else:
1444 self._documentRadioBox.SetSelection(0)
1445 def OnDocumentInterfaceSelect(event):
1446 if not self._documentInterfaceMessageShown:
1447 msgTitle = wx.GetApp().GetAppName()
1448 if not msgTitle:
1449 msgTitle = _("Document Options")
1450 wx.MessageBox("Document interface changes will not appear until the application is restarted.",
1451 msgTitle,
1452 wx.OK | wx.ICON_INFORMATION,
1453 self.GetParent())
1454 self._documentInterfaceMessageShown = True
1455 wx.EVT_RADIOBOX(self, self._documentRadioBox.GetId(), OnDocumentInterfaceSelect)
1456 optionsBorderSizer = wx.BoxSizer(wx.VERTICAL)
1457 optionsSizer = wx.BoxSizer(wx.VERTICAL)
1458 if wx.GetApp().GetService(DocOptionsService).GetAllowModeChanges():
1459 optionsSizer.Add(self._documentRadioBox, 0, wx.ALL, HALF_SPACE)
1460 optionsSizer.Add(self._showTipsCheckBox, 0, wx.ALL, HALF_SPACE)
1461 optionsBorderSizer.Add(optionsSizer, 0, wx.ALL, SPACE)
1462 self.SetSizer(optionsBorderSizer)
1463 self.Layout()
1464 self._documentInterfaceMessageShown = False
1465 parent.AddPage(self, _("Options"))
d1dc2b32
RD
1466
1467
3fa8f722 1468 def OnOK(self, optionsDialog):
d1dc2b32 1469 """
3fa8f722 1470 Updates the config based on the selections in the options panel.
d1dc2b32 1471 """
3fa8f722
RD
1472 config = wx.ConfigBase_Get()
1473 config.WriteInt("ShowTipAtStartup", self._showTipsCheckBox.GetValue())
1474 if wx.GetApp().GetService(DocOptionsService).GetAllowModeChanges():
1475 config.WriteInt("UseMDI", (self._documentRadioBox.GetSelection() == 1))
1476 config.WriteInt("UseWinMDI", (self._documentRadioBox.GetSelection() == 2))
d1dc2b32
RD
1477
1478
3fa8f722
RD
1479class DocApp(wx.PySimpleApp):
1480 """
1481 The DocApp class serves as the base class for pydocview applications and offers
1482 functionality such as services, creation of SDI and MDI frames, show tips,
1483 and a splash screen.
1484 """
1485
1486
1487 def OnInit(self):
d1dc2b32 1488 """
3fa8f722 1489 Initializes the DocApp.
d1dc2b32 1490 """
3fa8f722
RD
1491 self._services = []
1492 self._defaultIcon = None
1493 self._registeredCloseEvent = False
1494 self._useTabbedMDI = True
1495
1496 if not hasattr(self, "_debug"): # only set if not already initialized
1497 self._debug = False
1498 if not hasattr(self, "_singleInstance"): # only set if not already initialized
1499 self._singleInstance = True
1500
1501 # if _singleInstance is TRUE only allow one single instance of app to run.
1502 # When user tries to run a second instance of the app, abort startup,
1503 # But if user also specifies files to open in command line, send message to running app to open those files
1504 if self._singleInstance:
1505 # create shared memory temporary file
1506 if wx.Platform == '__WXMSW__':
1507 tfile = tempfile.TemporaryFile(prefix="ag", suffix="tmp")
1508 fno = tfile.fileno()
1509 self._sharedMemory = mmap.mmap(fno, 1024, "shared_memory")
1510 else:
1511 tfile = file(os.path.join(tempfile.gettempdir(), tempfile.gettempprefix() + self.GetAppName() + '-' + wx.GetUserId() + "AGSharedMemory"), 'w+b')
1512 tfile.write("*")
1513 tfile.seek(1024)
1514 tfile.write(" ")
1515 tfile.flush()
1516 fno = tfile.fileno()
1517 self._sharedMemory = mmap.mmap(fno, 1024)
1518
1519 self._singleInstanceChecker = wx.SingleInstanceChecker(self.GetAppName() + '-' + wx.GetUserId(), tempfile.gettempdir())
1520 if self._singleInstanceChecker.IsAnotherRunning():
1521 # have running single instance open file arguments
1522 data = pickle.dumps(sys.argv[1:])
1523 while 1:
1524 self._sharedMemory.seek(0)
1525 marker = self._sharedMemory.read_byte()
1526 if marker == '\0' or marker == '*': # available buffer
1527 self._sharedMemory.seek(0)
1528 self._sharedMemory.write_byte('-') # set writing marker
1529 self._sharedMemory.write(data) # write files we tried to open to shared memory
1530 self._sharedMemory.seek(0)
1531 self._sharedMemory.write_byte('+') # set finished writing marker
1532 self._sharedMemory.flush()
1533 break
1534 else:
1535 time.sleep(1) # give enough time for buffer to be available
1536
1537 return False
1538 else:
1539 self._timer = wx.PyTimer(self.DoBackgroundListenAndLoad)
1540 self._timer.Start(250)
1541
1542 return True
1543
d1dc2b32 1544
3fa8f722
RD
1545 def OpenMainFrame(self):
1546 docManager = self.GetDocumentManager()
1547 if docManager.GetFlags() & wx.lib.docview.DOC_MDI:
1548 if self.GetUseTabbedMDI():
1549 frame = wx.lib.pydocview.DocTabbedParentFrame(docManager, None, -1, self.GetAppName())
1550 else:
1551 frame = wx.lib.pydocview.DocMDIParentFrame(docManager, None, -1, self.GetAppName())
1552 frame.Show(True)
d1dc2b32 1553
3fa8f722
RD
1554
1555 def DoBackgroundListenAndLoad(self):
d1dc2b32 1556 """
3fa8f722 1557 Open any files specified in the given command line argument passed in via shared memory
d1dc2b32 1558 """
3fa8f722
RD
1559 self._timer.Stop()
1560
1561 self._sharedMemory.seek(0)
1562 if self._sharedMemory.read_byte() == '+': # available data
1563 data = self._sharedMemory.read(1024-1)
1564 self._sharedMemory.seek(0)
1565 self._sharedMemory.write_byte("*") # finished reading, set buffer free marker
1566 self._sharedMemory.flush()
1567 args = pickle.loads(data)
1568 for arg in args:
1569 if arg[0] != '/' and arg[0] != '-' and os.path.exists(arg):
1570 self.GetDocumentManager().CreateDocument(arg, wx.lib.docview.DOC_SILENT)
1571
1572 # force display of running app
1573 topWindow = wx.GetApp().GetTopWindow()
1574 if topWindow.IsIconized():
1575 topWindow.Iconize(False)
1576 else:
1577 topWindow.Raise()
1578
1579
1580 self._timer.Start(1000) # 1 second interval
d1dc2b32
RD
1581
1582
3fa8f722 1583 def OpenCommandLineArgs(self):
74b89458 1584 """
3fa8f722
RD
1585 Called to open files that have been passed to the application from the
1586 command line.
74b89458 1587 """
3fa8f722
RD
1588 args = sys.argv[1:]
1589 for arg in args:
1590 if arg[0] != '/' and arg[0] != '-' and os.path.exists(arg):
1591 self.GetDocumentManager().CreateDocument(arg, wx.lib.docview.DOC_SILENT)
74b89458
RD
1592
1593
3fa8f722 1594 def GetDocumentManager(self):
74b89458 1595 """
3fa8f722 1596 Returns the document manager associated to the DocApp.
74b89458 1597 """
3fa8f722 1598 return self._docManager
74b89458
RD
1599
1600
3fa8f722 1601 def SetDocumentManager(self, docManager):
d1dc2b32 1602 """
3fa8f722
RD
1603 Sets the document manager associated with the DocApp and loads the
1604 DocApp's file history into the document manager.
d1dc2b32 1605 """
3fa8f722
RD
1606 self._docManager = docManager
1607 config = wx.ConfigBase_Get()
1608 self.GetDocumentManager().FileHistoryLoad(config)
d1dc2b32
RD
1609
1610
3fa8f722 1611 def ProcessEventBeforeWindows(self, event):
d1dc2b32 1612 """
3fa8f722
RD
1613 Enables services to process an event before the main window has a chance to
1614 process the window.
d1dc2b32 1615 """
3fa8f722
RD
1616 for service in self._services:
1617 if service.ProcessEventBeforeWindows(event):
1618 return True
1619 return False
d1dc2b32
RD
1620
1621
3fa8f722 1622 def ProcessUpdateUIEventBeforeWindows(self, event):
d1dc2b32 1623 """
3fa8f722
RD
1624 Enables services to process a UI event before the main window has a chance
1625 to process the window.
d1dc2b32 1626 """
3fa8f722
RD
1627 for service in self._services:
1628 if service.ProcessUpdateUIEventBeforeWindows(event):
1629 return True
1630 return False
d1dc2b32
RD
1631
1632
3fa8f722 1633 def ProcessEvent(self, event):
d1dc2b32 1634 """
3fa8f722
RD
1635 Processes an event, searching event tables and calling zero or more
1636 suitable event handler function(s). Note that the ProcessEvent
1637 method is called from the wxPython docview framework directly since
1638 wxPython does not have a virtual ProcessEvent function.
d1dc2b32 1639 """
3fa8f722
RD
1640 for service in self._services:
1641 if service.ProcessEvent(event):
1642 return True
1643 return False
d1dc2b32
RD
1644
1645
3fa8f722 1646 def ProcessUpdateUIEvent(self, event):
d1dc2b32 1647 """
3fa8f722
RD
1648 Processes a UI event, searching event tables and calling zero or more
1649 suitable event handler function(s). Note that the ProcessEvent
1650 method is called from the wxPython docview framework directly since
1651 wxPython does not have a virtual ProcessEvent function.
d1dc2b32 1652 """
3fa8f722
RD
1653 for service in self._services:
1654 if service.ProcessUpdateUIEvent(event):
1655 return True
1656 return False
d1dc2b32
RD
1657
1658
3fa8f722 1659 def InstallService(self, service):
d1dc2b32 1660 """
3fa8f722 1661 Installs an instance of a DocService into the DocApp.
d1dc2b32 1662 """
3fa8f722
RD
1663 service.SetDocumentManager(self._docManager)
1664 self._services.append(service)
1665 return service
d1dc2b32 1666
3fa8f722
RD
1667
1668 def GetServices(self):
d1dc2b32 1669 """
3fa8f722 1670 Returns the DocService instances that have been installed into the DocApp.
d1dc2b32 1671 """
3fa8f722 1672 return self._services
d1dc2b32
RD
1673
1674
3fa8f722 1675 def GetService(self, type):
d1dc2b32 1676 """
3fa8f722
RD
1677 Returns the instance of a particular type of service that has been installed
1678 into the DocApp. For example, "wx.GetApp().GetService(pydocview.OptionsService)"
1679 returns the isntance of the OptionsService that is running within the DocApp.
d1dc2b32 1680 """
3fa8f722
RD
1681 for service in self._services:
1682 if isinstance(service, type):
1683 return service
1684 return None
d1dc2b32 1685
d1dc2b32 1686
3fa8f722 1687 def OnExit(self):
d1dc2b32 1688 """
3fa8f722
RD
1689 Called when the DocApp is exited, enables the installed DocServices to exit
1690 and saves the DocManager's file history.
d1dc2b32 1691 """
3fa8f722
RD
1692 for service in self._services:
1693 service.OnExit()
d1dc2b32 1694 config = wx.ConfigBase_Get()
3fa8f722
RD
1695 self._docManager.FileHistorySave(config)
1696
1697 if hasattr(self, "_singleInstanceChecker"):
1698 del self._singleInstanceChecker
d1dc2b32 1699
3fa8f722
RD
1700
1701 def GetDefaultDocManagerFlags(self):
d1dc2b32 1702 """
3fa8f722 1703 Returns the default flags to use when creating the DocManager.
d1dc2b32 1704 """
d1dc2b32 1705 config = wx.ConfigBase_Get()
3fa8f722
RD
1706 if config.ReadInt("UseMDI", True) or config.ReadInt("UseWinMDI", False):
1707 flags = wx.lib.docview.DOC_MDI | wx.lib.docview.DOC_OPEN_ONCE
1708 if config.ReadInt("UseWinMDI", False):
1709 self.SetUseTabbedMDI(False)
d1dc2b32 1710 else:
3fa8f722
RD
1711 flags = wx.lib.docview.DOC_SDI | wx.lib.docview.DOC_OPEN_ONCE
1712 return flags
d1dc2b32
RD
1713
1714
3fa8f722 1715 def ShowTip(self, frame, tipProvider):
d1dc2b32 1716 """
3fa8f722
RD
1717 Shows the tip window, generally this is called when an application starts.
1718 A wx.TipProvider must be passed.
d1dc2b32
RD
1719 """
1720 config = wx.ConfigBase_Get()
3fa8f722
RD
1721 showTip = config.ReadInt("ShowTipAtStartup", 1)
1722 if showTip:
1723 index = config.ReadInt("TipIndex", 0)
1724 showTipResult = wx.ShowTip(wx.GetApp().GetTopWindow(), tipProvider, showAtStartup = showTip)
1725 if showTipResult != showTip:
1726 config.WriteInt("ShowTipAtStartup", showTipResult)
d1dc2b32
RD
1727
1728
3fa8f722 1729 def GetEditMenu(self, frame):
d1dc2b32 1730 """
3fa8f722
RD
1731 Utility method that finds the Edit menu within the menubar of a frame.
1732 """
1733 menuBar = frame.GetMenuBar()
1734 if not menuBar:
1735 return None
1736 editMenuIndex = menuBar.FindMenu(_("&Edit"))
1737 if editMenuIndex == -1:
1738 return None
1739 return menuBar.GetMenu(editMenuIndex)
d1dc2b32
RD
1740
1741
3fa8f722 1742 def GetUseTabbedMDI(self):
d1dc2b32 1743 """
3fa8f722 1744 Returns True if Windows MDI should use folder tabs instead of child windows.
d1dc2b32 1745 """
3fa8f722
RD
1746 return self._useTabbedMDI
1747
d1dc2b32 1748
3fa8f722 1749 def SetUseTabbedMDI(self, useTabbedMDI):
d1dc2b32 1750 """
3fa8f722 1751 Set to True if Windows MDI should use folder tabs instead of child windows.
d1dc2b32 1752 """
3fa8f722 1753 self._useTabbedMDI = useTabbedMDI
d1dc2b32
RD
1754
1755
3fa8f722 1756 def CreateDocumentFrame(self, view, doc, flags, id = -1, title = "", pos = wx.DefaultPosition, size = wx.DefaultSize, style = wx.DEFAULT_FRAME_STYLE):
d1dc2b32 1757 """
3fa8f722
RD
1758 Called by the DocManager to create and return a new Frame for a Document.
1759 Chooses whether to create an MDIChildFrame or SDI Frame based on the
1760 DocManager's flags.
d1dc2b32 1761 """
3fa8f722
RD
1762 docflags = self.GetDocumentManager().GetFlags()
1763 if docflags & wx.lib.docview.DOC_SDI:
1764 frame = self.CreateSDIDocumentFrame(doc, view, id, title, pos, size, style)
1765 frame.Show()
d1dc2b32 1766
3fa8f722
RD
1767 # wxBug: operating system bug, first window is set to the position of last window closed, ignoring passed in position on frame creation
1768 # also, initial size is incorrect for the same reasons
1769 if frame.GetPosition() != pos:
1770 frame.Move(pos)
1771 if frame.GetSize() != size:
1772 frame.SetSize(size)
d1dc2b32 1773
3fa8f722
RD
1774 if doc and doc.GetCommandProcessor():
1775 doc.GetCommandProcessor().SetEditMenu(self.GetEditMenu(frame))
1776 elif docflags & wx.lib.docview.DOC_MDI:
1777 if self.GetUseTabbedMDI():
1778 frame = self.CreateTabbedDocumentFrame(doc, view, id, title, pos, size, style)
1779 else:
1780 frame = self.CreateMDIDocumentFrame(doc, view, id, title, pos, size, style)
1781 if doc:
1782 if doc.GetDocumentTemplate().GetIcon():
1783 frame.SetIcon(doc.GetDocumentTemplate().GetIcon())
1784 elif wx.GetApp().GetTopWindow().GetIcon():
1785 frame.SetIcon(wx.GetApp().GetTopWindow().GetIcon())
1786 if doc and doc.GetCommandProcessor():
1787 doc.GetCommandProcessor().SetEditMenu(self.GetEditMenu(wx.GetApp().GetTopWindow()))
1788 if not frame.GetIcon() and self._defaultIcon:
1789 frame.SetIcon(self.GetDefaultIcon())
1790 view.SetFrame(frame)
1791 return frame
1792
1793
1794 def CreateSDIDocumentFrame(self, doc, view, id = -1, title = "", pos = wx.DefaultPosition, size = wx.DefaultSize, style = wx.DEFAULT_FRAME_STYLE):
d1dc2b32 1795 """
3fa8f722 1796 Creates and returns an SDI Document Frame.
d1dc2b32 1797 """
3fa8f722
RD
1798 frame = DocSDIFrame(doc, view, None, id, title, pos, size, style)
1799 return frame
d1dc2b32
RD
1800
1801
3fa8f722 1802 def CreateTabbedDocumentFrame(self, doc, view, id = -1, title = "", pos = wx.DefaultPosition, size = wx.DefaultSize, style = wx.DEFAULT_FRAME_STYLE):
d1dc2b32 1803 """
3fa8f722 1804 Creates and returns an MDI Document Frame for a Tabbed MDI view
d1dc2b32 1805 """
3fa8f722
RD
1806 frame = DocTabbedChildFrame(doc, view, wx.GetApp().GetTopWindow(), id, title, pos, size, style)
1807 return frame
d1dc2b32
RD
1808
1809
3fa8f722 1810 def CreateMDIDocumentFrame(self, doc, view, id = -1, title = "", pos = wx.DefaultPosition, size = wx.DefaultSize, style = wx.DEFAULT_FRAME_STYLE):
d1dc2b32 1811 """
3fa8f722 1812 Creates and returns an MDI Document Frame.
d1dc2b32 1813 """
3fa8f722
RD
1814 # if any child windows are maximized, then user must want any new children maximized
1815 # if no children exist, then use the default value from registry
1816 # wxBug: Only current window is maximized, so need to check every child frame
1817 parentFrame = wx.GetApp().GetTopWindow()
1818 childrenMaximized = filter(lambda child: isinstance(child, wx.MDIChildFrame) and child.IsMaximized(), parentFrame.GetChildren())
1819 if childrenMaximized:
1820 maximize = True
1821 else:
1822 children = filter(lambda child: isinstance(child, wx.MDIChildFrame), parentFrame.GetChildren())
1823 if children:
1824 # other windows exist and none are maximized
1825 maximize = False
1826 else:
1827 # get default setting from registry
1828 maximize = wx.ConfigBase_Get().ReadInt("MDIChildFrameMaximized", False)
1829
1830 frame = wx.lib.docview.DocMDIChildFrame(doc, view, wx.GetApp().GetTopWindow(), id, title, pos, size, style)
1831 if maximize: # wxBug: Should already be maximizing new child frames if one is maximized but it's not so we have to force it to
1832 frame.Maximize(True)
d1dc2b32 1833
3fa8f722
RD
1834## wx.EVT_MAXIMIZE(frame, self.OnMaximize) # wxBug: This doesn't work, need to save MDIChildFrameMaximized state on close of windows instead
1835 wx.EVT_CLOSE(frame, self.OnCloseChildWindow)
1836 if not self._registeredCloseEvent:
1837 wx.EVT_CLOSE(parentFrame, self.OnCloseMainWindow) # need to check on this, but only once
1838 self._registeredCloseEvent = True
d1dc2b32 1839
3fa8f722
RD
1840 return frame
1841
1842
1843 def SaveMDIDocumentFrameMaximizedState(self, maximized):
d1dc2b32 1844 """
3fa8f722
RD
1845 Remember in the config whether the MDI Frame is maximized so that it can be restored
1846 on open.
d1dc2b32 1847 """
3fa8f722
RD
1848 config = wx.ConfigBase_Get()
1849 maximizeFlag = config.ReadInt("MDIChildFrameMaximized", False)
1850 if maximized != maximizeFlag:
1851 config.WriteInt("MDIChildFrameMaximized", maximized)
d1dc2b32
RD
1852
1853
3fa8f722 1854 def OnCloseChildWindow(self, event):
d1dc2b32 1855 """
3fa8f722
RD
1856 Called when an MDI Child Frame is closed. Calls SaveMDIDocumentFrameMaximizedState to
1857 remember whether the MDI Frame is maximized so that it can be restored on open.
d1dc2b32 1858 """
3fa8f722
RD
1859 self.SaveMDIDocumentFrameMaximizedState(event.GetEventObject().IsMaximized())
1860 event.Skip()
d1dc2b32 1861
3fa8f722
RD
1862
1863 def OnCloseMainWindow(self, event):
1864 """
1865 Called when the MDI Parent Frame is closed. Remembers whether the MDI Parent Frame is
1866 maximized.
1867 """
1868 children = event.GetEventObject().GetChildren()
1869 childrenMaximized = filter(lambda child: isinstance(child, wx.MDIChildFrame)and child.IsMaximized(), children)
1870 if childrenMaximized:
1871 self.SaveMDIDocumentFrameMaximizedState(True)
d1dc2b32 1872 else:
3fa8f722
RD
1873 childrenNotMaximized = filter(lambda child: isinstance(child, wx.MDIChildFrame), children)
1874
1875 if childrenNotMaximized:
1876 # other windows exist and none are maximized
1877 self.SaveMDIDocumentFrameMaximizedState(False)
1878
1879 event.Skip()
d1dc2b32 1880
d1dc2b32 1881
3fa8f722
RD
1882 def GetDefaultIcon(self):
1883 """
1884 Returns the application's default icon.
1885 """
1886 return self._defaultIcon
d1dc2b32 1887
d1dc2b32 1888
3fa8f722
RD
1889 def SetDefaultIcon(self, icon):
1890 """
1891 Sets the application's default icon.
1892 """
1893 self._defaultIcon = icon
d1dc2b32 1894
d1dc2b32 1895
3fa8f722
RD
1896 def GetDebug(self):
1897 """
1898 Returns True if the application is in debug mode.
1899 """
1900 return self._debug
d1dc2b32
RD
1901
1902
3fa8f722 1903 def SetDebug(self, debug):
d1dc2b32 1904 """
3fa8f722 1905 Sets the application's debug mode.
d1dc2b32 1906 """
3fa8f722 1907 self._debug = debug
d1dc2b32
RD
1908
1909
3fa8f722 1910 def GetSingleInstance(self):
d1dc2b32 1911 """
3fa8f722 1912 Returns True if the application is in single instance mode. Used to determine if multiple instances of the application is allowed to launch.
d1dc2b32 1913 """
3fa8f722
RD
1914 return self._singleInstance
1915
1916
1917 def SetSingleInstance(self, singleInstance):
1918 """
1919 Sets application's single instance mode.
1920 """
1921 self._singleInstance = singleInstance
1922
1923
1924
1925 def CreateChildDocument(self, parentDocument, documentType, objectToEdit, path = ''):
1926 """
1927 Creates a child window of a document that edits an object. The child window
1928 is managed by the parent document frame, so it will be prompted to close if its
1929 parent is closed, etc. Child Documents are useful when there are complicated
1930 Views of a Document and users will need to tunnel into the View.
1931 """
1932 for document in self.GetDocumentManager().GetDocuments()[:]: # Cloning list to make sure we go through all docs even as they are deleted
1933 if isinstance(document, ChildDocument) and document.GetParentDocument() == parentDocument:
1934 if document.GetData() == objectToEdit:
1935 if hasattr(document.GetFirstView().GetFrame(), "SetFocus"):
1936 document.GetFirstView().GetFrame().SetFocus()
1937 return document
1938 for temp in wx.GetApp().GetDocumentManager().GetTemplates():
1939 if temp.GetDocumentType() == documentType:
1940 break
1941 temp = None
1942 newDoc = temp.CreateDocument(path, 0, data = objectToEdit, parentDocument = parentDocument)
1943 newDoc.SetDocumentName(temp.GetDocumentName())
1944 newDoc.SetDocumentTemplate(temp)
1945 if path == '':
1946 newDoc.OnNewDocument()
d1dc2b32 1947 else:
3fa8f722
RD
1948 if not newDoc.OnOpenDocument(path):
1949 newDoc.DeleteAllViews() # Implicitly deleted by DeleteAllViews
1950 return None
1951 return newDoc
d1dc2b32
RD
1952
1953
3fa8f722 1954 def CloseChildDocuments(self, parentDocument):
d1dc2b32 1955 """
3fa8f722 1956 Closes the child windows of a Document.
d1dc2b32 1957 """
3fa8f722
RD
1958 for document in self.GetDocumentManager().GetDocuments()[:]: # Cloning list to make sure we go through all docs even as they are deleted
1959 if isinstance(document, ChildDocument) and document.GetParentDocument() == parentDocument:
1960 if document.GetFirstView().GetFrame():
1961 document.GetFirstView().GetFrame().SetFocus()
1962 if document.GetFirstView().OnClose(deleteWindow = False):
1963 if document.GetFirstView().GetFrame():
1964 document.GetFirstView().GetFrame().Close() # wxBug: Need to do this for some random reason
1965 else:
1966 return False
1967 return True
d1dc2b32 1968
3fa8f722
RD
1969
1970 def IsMDI(self):
1971 """
1972 Returns True if the application is in MDI mode.
1973 """
1974 return self.GetDocumentManager().GetFlags() & wx.lib.docview.DOC_MDI
d1dc2b32
RD
1975
1976
3fa8f722 1977 def IsSDI(self):
d1dc2b32 1978 """
3fa8f722 1979 Returns True if the application is in SDI mode.
d1dc2b32 1980 """
3fa8f722 1981 return self.GetDocumentManager().GetFlags() & wx.lib.docview.DOC_SDI
d1dc2b32 1982
3fa8f722
RD
1983
1984 def ShowSplash(self, image):
d1dc2b32 1985 """
3fa8f722 1986 Shows a splash window with the given image. Input parameter 'image' can either be a wx.Bitmap or a filename.
d1dc2b32 1987 """
3fa8f722
RD
1988 if isinstance(image, wx.Bitmap):
1989 splash_bmp = image
1990 else:
1991 splash_bmp = wx.Image(image).ConvertToBitmap()
1992 self._splash = wx.SplashScreen(splash_bmp,wx.SPLASH_CENTRE_ON_SCREEN | wx.SPLASH_NO_TIMEOUT,0, None, -1)
1993 self._splash.Show()
d1dc2b32 1994
d1dc2b32 1995
3fa8f722
RD
1996 def CloseSplash(self):
1997 """
1998 Closes the splash window.
1999 """
2000 if self._splash:
2001 self._splash.Close(True)
2002
2003
2004class _DocFrameFileDropTarget(wx.FileDropTarget):
2005 """
2006 Class used to handle drops into the document frame.
2007 """
d1dc2b32 2008
3fa8f722
RD
2009 def __init__(self, docManager, docFrame):
2010 """
2011 Initializes the FileDropTarget class with the active docManager and the docFrame.
2012 """
2013 wx.FileDropTarget.__init__(self)
2014 self._docManager = docManager
2015 self._docFrame = docFrame
d1dc2b32
RD
2016
2017
3fa8f722 2018 def OnDropFiles(self, x, y, filenames):
d1dc2b32 2019 """
3fa8f722
RD
2020 Called when files are dropped in the drop target and tells the docManager to open
2021 the files.
d1dc2b32 2022 """
3fa8f722
RD
2023 try:
2024 for file in filenames:
2025 self._docManager.CreateDocument(file, wx.lib.docview.DOC_SILENT)
2026 except:
2027 msgTitle = wx.GetApp().GetAppName()
2028 if not msgTitle:
2029 msgTitle = _("File Error")
2030 wx.MessageBox("Could not open '%s'. '%s'" % (docview.FileNameFromPath(file), sys.exc_value),
2031 msgTitle,
2032 wx.OK | wx.ICON_EXCLAMATION,
2033 self._docManager.FindSuitableParent())
d1dc2b32
RD
2034
2035
3fa8f722
RD
2036class DocMDIParentFrame(wx.lib.docview.DocMDIParentFrame, DocFrameMixIn, DocMDIParentFrameMixIn):
2037 """
2038 The DocMDIParentFrame is the primary frame which the DocApp uses to host MDI child windows. It offers
2039 features such as a default menubar, toolbar, and status bar, and a mechanism to manage embedded windows
2040 on the edges of the DocMDIParentFrame.
2041 """
2042
2043
2044 def __init__(self, docManager, parent, id, title, pos = wx.DefaultPosition, size = wx.DefaultSize, style = wx.DEFAULT_FRAME_STYLE, name = "DocMDIFrame", embeddedWindows = 0):
d1dc2b32 2045 """
3fa8f722
RD
2046 Initializes the DocMDIParentFrame with the default menubar, toolbar, and status bar. Use the
2047 optional embeddedWindows parameter with the embedded window constants to create embedded
2048 windows around the edges of the DocMDIParentFrame.
2049 """
2050 pos, size = self._GetPosSizeFromConfig(pos, size)
2051 wx.lib.docview.DocMDIParentFrame.__init__(self, docManager, parent, id, title, pos, size, style, name)
2052 self._InitFrame(embeddedWindows)
2053
2054
2055 def _LayoutFrame(self):
2056 """
2057 Lays out the frame.
d1dc2b32 2058 """
d1dc2b32
RD
2059 wx.LayoutAlgorithm().LayoutMDIFrame(self)
2060 self.GetClientWindow().Refresh()
3fa8f722
RD
2061
2062
2063 def ProcessEvent(self, event):
2064 """
2065 Processes an event, searching event tables and calling zero or more
2066 suitable event handler function(s). Note that the ProcessEvent
2067 method is called from the wxPython docview framework directly since
2068 wxPython does not have a virtual ProcessEvent function.
2069 """
2070 if wx.GetApp().ProcessEventBeforeWindows(event):
2071 return True
2072 if wx.lib.docview.DocMDIParentFrame.ProcessEvent(self, event):
2073 return True
2074 return DocMDIParentFrameMixIn.ProcessEvent(self, event)
d1dc2b32
RD
2075
2076
3fa8f722 2077 def ProcessUpdateUIEvent(self, event):
d1dc2b32 2078 """
3fa8f722
RD
2079 Processes a UI event, searching event tables and calling zero or more
2080 suitable event handler function(s). Note that the ProcessEvent
2081 method is called from the wxPython docview framework directly since
2082 wxPython does not have a virtual ProcessEvent function.
d1dc2b32 2083 """
3fa8f722
RD
2084 if wx.GetApp().ProcessUpdateUIEventBeforeWindows(event):
2085 return True
2086 if wx.lib.docview.DocMDIParentFrame.ProcessUpdateUIEvent(self, event): # Let the views handle the event before the services
2087 return True
2088 if event.GetId() == wx.ID_ABOUT: # Using ID_ABOUT to update the window menu, the window menu items are not triggering
2089 self.UpdateWindowMenu()
2090 return True
2091 return DocMDIParentFrameMixIn.ProcessUpdateUIEvent(self, event)
d1dc2b32
RD
2092
2093
3fa8f722 2094 def UpdateWindowMenu(self):
d1dc2b32 2095 """
3fa8f722 2096 Updates the WindowMenu on Windows platforms.
d1dc2b32 2097 """
3fa8f722
RD
2098 if wx.Platform == '__WXMSW__':
2099 children = filter(lambda child: isinstance(child, wx.MDIChildFrame), self.GetChildren())
2100 windowCount = len(children)
2101 hasWindow = windowCount >= 1
2102 has2OrMoreWindows = windowCount >= 2
2103
2104 windowMenu = self.GetWindowMenu()
2105 if windowMenu:
2106 windowMenu.Enable(wx.IDM_WINDOWTILE, hasWindow)
2107 windowMenu.Enable(wx.IDM_WINDOWTILEHOR, hasWindow)
2108 windowMenu.Enable(wx.IDM_WINDOWCASCADE, hasWindow)
2109 windowMenu.Enable(wx.IDM_WINDOWICONS, hasWindow)
2110 windowMenu.Enable(wx.IDM_WINDOWTILEVERT, hasWindow)
2111 wx.IDM_WINDOWPREV = 4006 # wxBug: Not defined for some reason
2112 windowMenu.Enable(wx.IDM_WINDOWPREV, has2OrMoreWindows)
2113 windowMenu.Enable(wx.IDM_WINDOWNEXT, has2OrMoreWindows)
2114
d1dc2b32
RD
2115
2116
3fa8f722 2117 def OnSize(self, event):
d1dc2b32 2118 """
3fa8f722 2119 Called when the DocMDIParentFrame is resized and lays out the MDI client window.
d1dc2b32 2120 """
3fa8f722
RD
2121 # Needed in case there are splitpanels around the mdi frame
2122 self._LayoutFrame()
d1dc2b32
RD
2123
2124
3fa8f722 2125 def OnCloseWindow(self, event):
d1dc2b32 2126 """
3fa8f722 2127 Called when the DocMDIParentFrame is closed. Remembers the frame size.
d1dc2b32 2128 """
3fa8f722 2129 self.SaveEmbeddedWindowSizes()
d1dc2b32 2130
3fa8f722
RD
2131 # save and close services last.
2132 for service in wx.GetApp().GetServices():
2133 if not service.OnCloseFrame(event):
2134 return
d1dc2b32 2135
3fa8f722
RD
2136 # save and close documents
2137 # documents with a common view, e.g. project view, should save the document, but not close the window
2138 # and let the service close the window.
2139 wx.lib.docview.DocMDIParentFrame.OnCloseWindow(self, event)
d1dc2b32
RD
2140
2141
3fa8f722 2142class DocSDIFrame(wx.lib.docview.DocChildFrame, DocFrameMixIn):
d1dc2b32
RD
2143 """
2144 The DocSDIFrame host DocManager Document windows. It offers features such as a default menubar,
2145 toolbar, and status bar.
2146 """
2147
2148
2149 def __init__(self, doc, view, parent, id, title, pos = wx.DefaultPosition, size = wx.DefaultSize, style = wx.DEFAULT_FRAME_STYLE, name = "DocSDIFrame"):
2150 """
2151 Initializes the DocSDIFrame with the default menubar, toolbar, and status bar.
2152 """
2153 wx.lib.docview.DocChildFrame.__init__(self, doc, view, parent, id, title, pos, size, style, name)
2154 self._fileMenu = None
2155 if doc:
2156 self._docManager = doc.GetDocumentManager()
2157 else:
2158 self._docManager = None
2159 self.SetDropTarget(_DocFrameFileDropTarget(self._docManager, self))
2160
2161 wx.EVT_MENU(self, wx.ID_ABOUT, self.OnAbout)
2162 wx.EVT_MENU(self, wx.ID_EXIT, self.OnExit)
2163 wx.EVT_MENU_RANGE(self, wx.ID_FILE1, wx.ID_FILE9, self.OnMRUFile)
2164
2165 self.InitializePrintData()
2166
3fa8f722 2167 menuBar = self.CreateDefaultMenuBar(sdi=True)
d1dc2b32
RD
2168 toolBar = self.CreateDefaultToolBar()
2169 self.SetToolBar(toolBar)
2170 statusBar = self.CreateDefaultStatusBar()
2171
2172 for service in wx.GetApp().GetServices():
2173 service.InstallControls(self, menuBar = menuBar, toolBar = toolBar, statusBar = statusBar, document = doc)
2174
2175 self.SetMenuBar(menuBar) # wxBug: Need to do this in SDI to mimic MDI... because have to set the menubar at the very end or the automatic MDI "window" menu doesn't get put in the right place when the services add new menus to the menubar
2176
2177
3fa8f722 2178 def _LayoutFrame(self):
d1dc2b32 2179 """
3fa8f722 2180 Lays out the Frame.
d1dc2b32 2181 """
3fa8f722
RD
2182 self.Layout()
2183
d1dc2b32
RD
2184
2185 def OnExit(self, event):
2186 """
2187 Called when the application is exitting.
2188 """
2189 if self._childView.GetDocumentManager().Clear(force = False):
2190 self.Destroy()
2191 else:
2192 event.Veto()
2193
2194
2195 def OnMRUFile(self, event):
2196 """
2197 Opens the appropriate file when it is selected from the file history
2198 menu.
2199 """
2200 n = event.GetId() - wx.ID_FILE1
2201 filename = self._docManager.GetHistoryFile(n)
2202 if filename:
2203 self._docManager.CreateDocument(filename, wx.lib.docview.DOC_SILENT)
2204 else:
2205 self._docManager.RemoveFileFromHistory(n)
2206 msgTitle = wx.GetApp().GetAppName()
2207 if not msgTitle:
2208 msgTitle = _("File Error")
2209 wx.MessageBox("The file '%s' doesn't exist and couldn't be opened.\nIt has been removed from the most recently used files list" % docview.FileNameFromPath(file),
2210 msgTitle,
2211 wx.OK | wx.ICON_EXCLAMATION,
2212 self)
2213
2214
d1dc2b32
RD
2215 def ProcessEvent(self, event):
2216 """
2217 Processes an event, searching event tables and calling zero or more
2218 suitable event handler function(s). Note that the ProcessEvent
2219 method is called from the wxPython docview framework directly since
2220 wxPython does not have a virtual ProcessEvent function.
2221 """
2222 if wx.GetApp().ProcessEventBeforeWindows(event):
2223 return True
2224 if self._childView:
2225 self._childView.Activate(True)
2226
2227 id = event.GetId()
2228 if id == SAVEALL_ID:
2229 self.OnFileSaveAll(event)
2230 return True
2231
2232 if hasattr(self._childView, "GetDocumentManager") and self._childView.GetDocumentManager().ProcessEvent(event): # Need to call docmanager here since super class relies on DocParentFrame which we are not using
2233 return True
2234 else:
2235 return wx.GetApp().ProcessEvent(event)
2236
2237
2238 def ProcessUpdateUIEvent(self, event):
2239 """
2240 Processes a UI event, searching event tables and calling zero or more
2241 suitable event handler function(s). Note that the ProcessEvent
2242 method is called from the wxPython docview framework directly since
2243 wxPython does not have a virtual ProcessEvent function.
2244 """
2245 if wx.GetApp().ProcessUpdateUIEventBeforeWindows(event):
2246 return True
2247 if self._childView:
2248 if hasattr(self._childView, "GetDocumentManager"):
2249 docMgr = self._childView.GetDocumentManager()
2250 if docMgr:
2251 if docMgr.GetCurrentDocument() != self._childView.GetDocument():
2252 return False
2253 if docMgr.ProcessUpdateUIEvent(event): # Let the views handle the event before the services
2254 return True
2255 id = event.GetId()
2256 if id == wx.ID_CUT:
2257 event.Enable(False)
2258 return True
2259 elif id == wx.ID_COPY:
2260 event.Enable(False)
2261 return True
2262 elif id == wx.ID_PASTE:
2263 event.Enable(False)
2264 return True
2265 elif id == wx.ID_CLEAR:
2266 event.Enable(False)
2267 return True
2268 elif id == wx.ID_SELECTALL:
2269 event.Enable(False)
2270 return True
2271 elif id == SAVEALL_ID:
2272 filesModified = False
2273 docs = wx.GetApp().GetDocumentManager().GetDocuments()
2274 for doc in docs:
2275 if doc.IsModified():
2276 filesModified = True
2277 break
2278
2279 event.Enable(filesModified)
2280 return True
2281 else:
2282 return wx.GetApp().ProcessUpdateUIEvent(event)
2283
2284
d1dc2b32
RD
2285 def OnCloseWindow(self, event):
2286 """
2287 Called when the window is saved. Enables services to help close the frame.
2288 """
2289 for service in wx.GetApp().GetServices():
2290 service.OnCloseFrame(event)
2291 wx.lib.docview.DocChildFrame.OnCloseWindow(self, event)
2292 if self._fileMenu and self._docManager:
2293 self._docManager.FileHistoryRemoveMenu(self._fileMenu)
2294
2295
74b89458
RD
2296class AboutService(DocService):
2297 """
2298 About Dialog Service that installs under the Help menu to show the properties of the current application.
2299 """
2300
3fa8f722 2301 def __init__(self, aboutDialog=None, image=None):
74b89458
RD
2302 """
2303 Initializes the AboutService.
2304 """
2305 if aboutDialog:
2306 self._dlg = aboutDialog
3fa8f722 2307 self._image = None
74b89458
RD
2308 else:
2309 self._dlg = AboutDialog # use default AboutDialog
3fa8f722 2310 self._image = image
74b89458
RD
2311
2312
2313 def ShowAbout(self):
2314 """
2315 Show the AboutDialog
2316 """
3fa8f722
RD
2317 if self._image:
2318 dlg = self._dlg(wx.GetApp().GetTopWindow(), self._image)
2319 else:
2320 dlg = self._dlg(wx.GetApp().GetTopWindow())
74b89458
RD
2321 dlg.CenterOnScreen()
2322 dlg.ShowModal()
2323 dlg.Destroy()
2324
2325
2326 def SetAboutDialog(self, dlg):
2327 """
2328 Customize the AboutDialog
2329 """
2330 self._dlg = dlg
2331
2332
2333class AboutDialog(wx.Dialog):
2334 """
2335 Opens an AboutDialog. Shared by DocMDIParentFrame and DocSDIFrame.
2336 """
2337
3fa8f722 2338 def __init__(self, parent, image=None):
74b89458
RD
2339 """
2340 Initializes the about dialog.
2341 """
2342 wx.Dialog.__init__(self, parent, -1, _("About ") + wx.GetApp().GetAppName(), style = wx.DEFAULT_DIALOG_STYLE)
2343
74b89458 2344 sizer = wx.BoxSizer(wx.VERTICAL)
3fa8f722
RD
2345 if image:
2346 imageItem = wx.StaticBitmap(self, -1, image.ConvertToBitmap(), (0,0), (image.GetWidth(), image.GetHeight()))
2347 sizer.Add(imageItem, 0, wx.ALIGN_CENTER|wx.ALL, 0)
2348 sizer.Add(wx.StaticText(self, -1, wx.GetApp().GetAppName()), 0, wx.ALIGN_CENTRE|wx.ALL, 5)
74b89458
RD
2349
2350 btn = wx.Button(self, wx.ID_OK)
2351 sizer.Add(btn, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
2352
2353 self.SetSizer(sizer)
2354 self.SetAutoLayout(True)
2355 sizer.Fit(self)
2356
2357
2358
d1dc2b32
RD
2359class FilePropertiesService(DocService):
2360 """
74b89458 2361 Service that installs under the File menu to show the properties of the file associated
d1dc2b32
RD
2362 with the current document.
2363 """
2364
2365 PROPERTIES_ID = wx.NewId()
2366
2367
2368 def __init__(self):
2369 """
2370 Initializes the PropertyService.
2371 """
2372 self._customEventHandlers = []
2373
2374
2375 def InstallControls(self, frame, menuBar = None, toolBar = None, statusBar = None, document = None):
2376 """
2377 Installs a File/Properties menu item.
2378 """
2379 fileMenu = menuBar.GetMenu(menuBar.FindMenu(_("&File")))
2380 exitMenuItemPos = self.GetMenuItemPos(fileMenu, wx.ID_EXIT)
2381 fileMenu.InsertSeparator(exitMenuItemPos)
2382 fileMenu.Insert(exitMenuItemPos, FilePropertiesService.PROPERTIES_ID, _("&Properties"), _("Show file properties"))
2383 wx.EVT_MENU(frame, FilePropertiesService.PROPERTIES_ID, self.ProcessEvent)
2384 wx.EVT_UPDATE_UI(frame, FilePropertiesService.PROPERTIES_ID, self.ProcessUpdateUIEvent)
2385
2386
2387 def ProcessEvent(self, event):
2388 """
2389 Detects when the File/Properties menu item is selected.
2390 """
2391 id = event.GetId()
2392 if id == FilePropertiesService.PROPERTIES_ID:
2393 for eventHandler in self._customEventHandlers:
2394 if eventHandler.ProcessEvent(event):
2395 return True
2396
2397 self.ShowPropertiesDialog()
2398 return True
2399 else:
2400 return False
2401
2402
2403 def ProcessUpdateUIEvent(self, event):
2404 """
2405 Updates the File/Properties menu item.
2406 """
2407 id = event.GetId()
2408 if id == FilePropertiesService.PROPERTIES_ID:
2409 for eventHandler in self._customEventHandlers:
2410 if eventHandler.ProcessUpdateUIEvent(event):
2411 return True
2412
2413 event.Enable(wx.GetApp().GetDocumentManager().GetCurrentDocument() != None)
2414 return True
2415 else:
2416 return False
2417
2418
2419 def ShowPropertiesDialog(self, filename = None):
2420 """
2421 Shows the PropertiesDialog for the specified file.
2422 """
2423 if not filename:
2424 filename = wx.GetApp().GetDocumentManager().GetCurrentDocument().GetFilename()
2425
2426 filePropertiesDialog = FilePropertiesDialog(wx.GetApp().GetTopWindow(), filename)
2427 if filePropertiesDialog.ShowModal() == wx.ID_OK:
2428 pass # Handle OK
2429 filePropertiesDialog.Destroy()
2430
2431
2432 def GetCustomEventHandlers(self):
2433 """
2434 Returns the custom event handlers for the PropertyService.
2435 """
2436 return self._customEventHandlers
2437
2438
2439 def AddCustomEventHandler(self, handler):
2440 """
2441 Adds a custom event handlers for the PropertyService. A custom event handler enables
2442 a different dialog to be provided for a particular file.
2443 """
2444 self._customEventHandlers.append(handler)
2445
2446
2447 def RemoveCustomEventHandler(self, handler):
2448 """
2449 Removes a custom event handler from the PropertyService.
2450 """
2451 self._customEventHandlers.remove(handler)
2452
2453
2454 def chopPath(self, text, length = 36):
2455 """
2456 Simple version of textwrap. textwrap.fill() unfortunately chops lines at spaces
2457 and creates odd word boundaries. Instead, we will chop the path without regard to
2458 spaces, but pay attention to path delimiters.
2459 """
74b89458 2460 chopped = ""
d1dc2b32
RD
2461 textLen = len(text)
2462 start = 0
2463
2464 while start < textLen:
2465 end = start + length
2466 if end > textLen:
2467 end = textLen
2468
2469 # see if we can find a delimiter to chop the path
2470 if end < textLen:
2471 lastSep = text.rfind(os.sep, start, end + 1)
2472 if lastSep != -1 and lastSep != start:
2473 end = lastSep
2474
74b89458 2475 if len(chopped):
d1dc2b32
RD
2476 chopped = chopped + '\n' + text[start:end]
2477 else:
2478 chopped = text[start:end]
2479
2480 start = end
2481
2482 return chopped
2483
2484
2485class FilePropertiesDialog(wx.Dialog):
2486 """
2487 Dialog that shows the properties of a file. Invoked by the PropertiesService.
2488 """
2489
2490
2491 def __init__(self, parent, filename):
2492 """
2493 Initializes the properties dialog.
2494 """
2495 wx.Dialog.__init__(self, parent, -1, _("File Properties"), size = (310, 330))
2496
2497 HALF_SPACE = 5
2498 SPACE = 10
2499
2500 filePropertiesService = wx.GetApp().GetService(FilePropertiesService)
2501
74b89458
RD
2502 fileExists = os.path.exists(filename)
2503
d1dc2b32
RD
2504 notebook = wx.Notebook(self, -1)
2505 tab = wx.Panel(notebook, -1)
2506
2507 gridSizer = RowColSizer()
2508
2509 gridSizer.Add(wx.StaticText(tab, -1, _("Filename:")), flag=wx.RIGHT, border=HALF_SPACE, row=0, col=0)
2510 gridSizer.Add(wx.StaticText(tab, -1, os.path.basename(filename)), row=0, col=1)
2511
2512 gridSizer.Add(wx.StaticText(tab, -1, _("Location:")), flag=wx.RIGHT, border=HALF_SPACE, row=1, col=0)
2513 gridSizer.Add(wx.StaticText(tab, -1, filePropertiesService.chopPath(os.path.dirname(filename))), flag=wx.BOTTOM, border=SPACE, row=1, col=1)
2514
2515 gridSizer.Add(wx.StaticText(tab, -1, _("Size:")), flag=wx.RIGHT, border=HALF_SPACE, row=2, col=0)
74b89458
RD
2516 if fileExists:
2517 gridSizer.Add(wx.StaticText(tab, -1, str(os.path.getsize(filename)) + ' ' + _("bytes")), row=2, col=1)
d1dc2b32
RD
2518
2519 lineSizer = wx.BoxSizer(wx.VERTICAL) # let the line expand horizontally without vertical expansion
2520 lineSizer.Add(wx.StaticLine(tab, -1, size = (10,-1)), 0, wx.EXPAND)
2521 gridSizer.Add(lineSizer, flag=wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.TOP, border=HALF_SPACE, row=3, col=0, colspan=2)
2522
2523 gridSizer.Add(wx.StaticText(tab, -1, _("Created:")), flag=wx.RIGHT, border=HALF_SPACE, row=4, col=0)
74b89458
RD
2524 if fileExists:
2525 gridSizer.Add(wx.StaticText(tab, -1, time.ctime(os.path.getctime(filename))), row=4, col=1)
d1dc2b32
RD
2526
2527 gridSizer.Add(wx.StaticText(tab, -1, _("Modified:")), flag=wx.RIGHT, border=HALF_SPACE, row=5, col=0)
74b89458
RD
2528 if fileExists:
2529 gridSizer.Add(wx.StaticText(tab, -1, time.ctime(os.path.getmtime(filename))), row=5, col=1)
d1dc2b32
RD
2530
2531 gridSizer.Add(wx.StaticText(tab, -1, _("Accessed:")), flag=wx.RIGHT, border=HALF_SPACE, row=6, col=0)
74b89458
RD
2532 if fileExists:
2533 gridSizer.Add(wx.StaticText(tab, -1, time.ctime(os.path.getatime(filename))), row=6, col=1)
d1dc2b32
RD
2534
2535 # add a border around the inside of the tab
2536 spacerGrid = wx.BoxSizer(wx.VERTICAL)
2537 spacerGrid.Add(gridSizer, 0, wx.ALL, SPACE);
2538 tab.SetSizer(spacerGrid)
2539 notebook.AddPage(tab, _("General"))
d1dc2b32
RD
2540
2541 sizer = wx.BoxSizer(wx.VERTICAL)
2542 sizer.Add(notebook, 0, wx.ALL | wx.EXPAND, SPACE)
2543 sizer.Add(self.CreateButtonSizer(wx.OK), 0, wx.ALIGN_RIGHT | wx.RIGHT | wx.BOTTOM, HALF_SPACE)
2544
2545 sizer.Fit(self)
2546 self.SetDimensions(-1, -1, 310, -1, wx.SIZE_USE_EXISTING)
2547 self.SetSizer(sizer)
2548 self.Layout()
2549
2550
2551class ChildDocument(wx.lib.docview.Document):
2552 """
2553 A ChildDocument is a document that represents a portion of a Document. The child
2554 document is managed by the parent document, so it will be prompted to close if its
2555 parent is closed, etc. Child Documents are useful when there are complicated
2556 Views of a Document and users will need to tunnel into the View.
2557 """
2558
2559
2560 def GetData(self):
2561 """
2562 Returns the data that the ChildDocument contains.
2563 """
2564 return self._data
2565
2566
2567 def SetData(self, data):
2568 """
2569 Sets the data that the ChildDocument contains.
2570 """
2571 self._data = data
2572
2573
2574 def GetParentDocument(self):
2575 """
2576 Returns the parent Document of the ChildDocument.
2577 """
2578 return self._parentDocument
2579
2580
2581 def SetParentDocument(self, parentDocument):
2582 """
2583 Sets the parent Document of the ChildDocument.
2584 """
2585 self._parentDocument = parentDocument
2586
2587
2588 def OnSaveDocument(self, filename):
2589 """
2590 Called when the ChildDocument is saved and does the minimum such that the
2591 ChildDocument looks like a real Document to the framework.
2592 """
2593 self.SetFilename(filename, True)
2594 self.Modify(False)
2595 self.SetDocumentSaved(True)
2596 return True
2597
2598
2599 def OnOpenDocument(self, filename):
2600 """
2601 Called when the ChildDocument is opened and does the minimum such that the
2602 ChildDocument looks like a real Document to the framework.
2603 """
2604 self.SetFilename(filename, True)
2605 self.Modify(False)
2606 self.SetDocumentSaved(True)
2607 self.UpdateAllViews()
2608 return True
2609
2610
3fa8f722
RD
2611 def Save(self):
2612 """
2613 Called when the ChildDocument is saved and does the minimum such that the
2614 ChildDocument looks like a real Document to the framework.
2615 """
2616 return self.OnSaveDocument(self._documentFile)
2617
2618
2619 def SaveAs(self):
2620 """
2621 Called when the ChildDocument is saved and does the minimum such that the
2622 ChildDocument looks like a real Document to the framework.
2623 """
2624 return self.OnSaveDocument(self._documentFile)
2625
2626
d1dc2b32
RD
2627class ChildDocTemplate(wx.lib.docview.DocTemplate):
2628 """
2629 A ChildDocTemplate is a DocTemplate subclass that enables the creation of ChildDocuments
2630 that represents a portion of a Document. The child document is managed by the parent document,
2631 so it will be prompted to close if its parent is closed, etc. Child Documents are useful
2632 when there are complicated Views of a Document and users will need to tunnel into the View.
2633 """
2634
2635
2636 def __init__(self, manager, description, filter, dir, ext, docTypeName, viewTypeName, docType, viewType, flags = wx.lib.docview.TEMPLATE_INVISIBLE, icon = None):
2637 """
2638 Initializes the ChildDocTemplate.
2639 """
2640 wx.lib.docview.DocTemplate.__init__(self, manager, description, filter, dir, ext, docTypeName, viewTypeName, docType, viewType, flags = flags, icon = icon)
2641
2642
2643 def CreateDocument(self, path, flags, data = None, parentDocument = None):
2644 """
2645 Called when a ChildDocument is to be created and does the minimum such that the
2646 ChildDocument looks like a real Document to the framework.
2647 """
2648 doc = self._docType()
2649 doc.SetFilename(path)
2650 doc.SetData(data)
2651 doc.SetParentDocument(parentDocument)
2652 doc.SetDocumentTemplate(self)
2653 self.GetDocumentManager().AddDocument(doc)
2654 doc.SetCommandProcessor(doc.OnCreateCommandProcessor())
2655 if doc.OnCreate(path, flags):
2656 return doc
2657 else:
2658 if doc in self.GetDocumentManager().GetDocuments():
2659 doc.DeleteAllViews()
2660 return None
2661
2662
2663class WindowMenuService(DocService):
2664 """
2665 The WindowMenuService is a service that implements a standard Window menu that is used
2666 by the DocSDIFrame. The MDIFrame automatically includes a Window menu and does not use
2667 the WindowMenuService.
2668 """
2669
2670
2671 def __init__(self):
2672 """
2673 Initializes the WindowMenu and its globals.
2674 """
2675 self.ARRANGE_WINDOWS_ID = wx.NewId()
2676 self.SELECT_WINDOW_1_ID = wx.NewId()
2677 self.SELECT_WINDOW_2_ID = wx.NewId()
2678 self.SELECT_WINDOW_3_ID = wx.NewId()
2679 self.SELECT_WINDOW_4_ID = wx.NewId()
2680 self.SELECT_WINDOW_5_ID = wx.NewId()
2681 self.SELECT_WINDOW_6_ID = wx.NewId()
2682 self.SELECT_WINDOW_7_ID = wx.NewId()
2683 self.SELECT_WINDOW_8_ID = wx.NewId()
2684 self.SELECT_WINDOW_9_ID = wx.NewId()
2685 self.SELECT_MORE_WINDOWS_ID = wx.NewId()
2686
2687
2688 def InstallControls(self, frame, menuBar = None, toolBar = None, statusBar = None, document = None):
2689 """
2690 Installs the Window menu.
2691 """
2692
2693 if not self.GetDocumentManager().GetFlags() & wx.lib.docview.DOC_SDI:
2694 return # Only need windows menu for SDI mode, MDI frame automatically creates one
2695
3fa8f722
RD
2696 if not _WINDOWS: # Arrange All and window navigation doesn't work on Linux
2697 return
2698
d1dc2b32 2699 windowMenu = wx.Menu()
3fa8f722 2700 item = windowMenu.Append(self.ARRANGE_WINDOWS_ID, _("&Arrange All"), _("Arrange the open windows"))
d1dc2b32
RD
2701 windowMenu.AppendSeparator()
2702
2703 wx.EVT_MENU(frame, self.ARRANGE_WINDOWS_ID, frame.ProcessEvent)
2704 wx.EVT_UPDATE_UI(frame, self.ARRANGE_WINDOWS_ID, frame.ProcessUpdateUIEvent)
2705 wx.EVT_MENU(frame, self.SELECT_WINDOW_1_ID, frame.ProcessEvent) # wxNewId may have been nonsequential, so can't use EVT_MENU_RANGE
2706 wx.EVT_MENU(frame, self.SELECT_WINDOW_2_ID, frame.ProcessEvent)
2707 wx.EVT_MENU(frame, self.SELECT_WINDOW_3_ID, frame.ProcessEvent)
2708 wx.EVT_MENU(frame, self.SELECT_WINDOW_4_ID, frame.ProcessEvent)
2709 wx.EVT_MENU(frame, self.SELECT_WINDOW_5_ID, frame.ProcessEvent)
2710 wx.EVT_MENU(frame, self.SELECT_WINDOW_6_ID, frame.ProcessEvent)
2711 wx.EVT_MENU(frame, self.SELECT_WINDOW_7_ID, frame.ProcessEvent)
2712 wx.EVT_MENU(frame, self.SELECT_WINDOW_8_ID, frame.ProcessEvent)
2713 wx.EVT_MENU(frame, self.SELECT_WINDOW_9_ID, frame.ProcessEvent)
2714 wx.EVT_MENU(frame, self.SELECT_MORE_WINDOWS_ID, frame.ProcessEvent)
2715
2716 helpMenuIndex = menuBar.FindMenu(_("&Help"))
2717 menuBar.Insert(helpMenuIndex, windowMenu, _("&Window"))
2718
2719 self._lastFrameUpdated = None
2720
2721
2722 def ProcessEvent(self, event):
2723 """
2724 Processes a Window menu event.
2725 """
2726 id = event.GetId()
2727 if id == self.ARRANGE_WINDOWS_ID:
2728 self.OnArrangeWindows(event)
2729 return True
2730 elif id == self.SELECT_MORE_WINDOWS_ID:
2731 self.OnSelectMoreWindows(event)
2732 return True
2733 elif id == self.SELECT_WINDOW_1_ID or id == self.SELECT_WINDOW_2_ID or id == self.SELECT_WINDOW_3_ID or id == self.SELECT_WINDOW_4_ID or id == self.SELECT_WINDOW_5_ID or id == self.SELECT_WINDOW_6_ID or id == self.SELECT_WINDOW_7_ID or id == self.SELECT_WINDOW_8_ID or id == self.SELECT_WINDOW_9_ID:
2734 self.OnSelectWindowMenu(event)
2735 return True
2736 else:
2737 return False
2738
2739
2740 def ProcessUpdateUIEvent(self, event):
2741 """
2742 Updates the Window menu items.
2743 """
2744 id = event.GetId()
2745 if id == self.ARRANGE_WINDOWS_ID:
2746 frame = event.GetEventObject()
2747 if not self._lastFrameUpdated or self._lastFrameUpdated != frame:
2748 self.BuildWindowMenu(frame) # It's a new frame, so update the windows menu... this is as if the View::OnActivateMethod had been invoked
2749 self._lastFrameUpdated = frame
2750 return True
2751 else:
2752 return False
2753
2754
2755 def BuildWindowMenu(self, currentFrame):
2756 """
2757 Builds the Window menu and adds menu items for all of the open documents in the DocManager.
2758 """
2759 windowMenuIndex = currentFrame.GetMenuBar().FindMenu(_("&Window"))
2760 windowMenu = currentFrame.GetMenuBar().GetMenu(windowMenuIndex)
2761 ids = self._GetWindowMenuIDList()
2762 frames = self._GetWindowMenuFrameList(currentFrame)
2763 max = WINDOW_MENU_NUM_ITEMS
2764 if max > len(frames):
2765 max = len(frames)
2766 i = 0
2767 for i in range(0, max):
2768 frame = frames[i]
2769 item = windowMenu.FindItemById(ids[i])
2770 label = '&' + str(i + 1) + ' ' + frame.GetTitle()
2771 if not item:
2772 item = windowMenu.AppendCheckItem(ids[i], label)
2773 else:
2774 windowMenu.SetLabel(ids[i], label)
2775 windowMenu.Check(ids[i], (frame == currentFrame))
2776 if len(frames) > WINDOW_MENU_NUM_ITEMS: # Add the more items item
2777 if not windowMenu.FindItemById(self.SELECT_MORE_WINDOWS_ID):
2778 windowMenu.Append(self.SELECT_MORE_WINDOWS_ID, _("&More Windows..."))
2779 else: # Remove any extra items
2780 if windowMenu.FindItemById(self.SELECT_MORE_WINDOWS_ID):
2781 windowMenu.Remove(self.SELECT_MORE_WINDOWS_ID)
2782
2783
2784
2785 for j in range(i + 1, WINDOW_MENU_NUM_ITEMS):
2786 if windowMenu.FindItemById(ids[j]):
2787 windowMenu.Remove(ids[j])
2788
2789
2790 def _GetWindowMenuIDList(self):
2791 """
2792 Returns a list of the Window menu item IDs.
2793 """
2794 return [self.SELECT_WINDOW_1_ID, self.SELECT_WINDOW_2_ID, self.SELECT_WINDOW_3_ID, self.SELECT_WINDOW_4_ID, self.SELECT_WINDOW_5_ID, self.SELECT_WINDOW_6_ID, self.SELECT_WINDOW_7_ID, self.SELECT_WINDOW_8_ID, self.SELECT_WINDOW_9_ID]
2795
2796
2797 def _GetWindowMenuFrameList(self, currentFrame = None):
2798 """
2799 Returns the Frame associated with each menu item in the Window menu.
2800 """
2801 frameList = []
2802 # get list of windows for documents
2803 for doc in self._docManager.GetDocuments():
2804 for view in doc.GetViews():
2805 frame = view.GetFrame()
2806 if frame not in frameList:
2807 if frame == currentFrame and len(frameList) >= WINDOW_MENU_NUM_ITEMS:
2808 frameList.insert(WINDOW_MENU_NUM_ITEMS - 1, frame)
2809 else:
2810 frameList.append(frame)
2811 # get list of windows for general services
2812 for service in wx.GetApp().GetServices():
2813 view = service.GetView()
2814 if view:
2815 frame = view.GetFrame()
2816 if frame not in frameList:
2817 if frame == currentFrame and len(frameList) >= WINDOW_MENU_NUM_ITEMS:
2818 frameList.insert(WINDOW_MENU_NUM_ITEMS - 1, frame)
2819 else:
2820 frameList.append(frame)
2821
2822 return frameList
2823
2824
2825 def OnArrangeWindows(self, event):
2826 """
2827 Called by Window/Arrange and tiles the frames on the desktop.
2828 """
2829 currentFrame = event.GetEventObject()
2830
2831 tempFrame = wx.Frame(None, -1, "", pos = wx.DefaultPosition, size = wx.DefaultSize)
2832 sizex = tempFrame.GetSize()[0]
2833 sizey = tempFrame.GetSize()[1]
2834 tempFrame.Destroy()
2835
2836 posx = 0
2837 posy = 0
2838 delta = 0
2839 frames = self._GetWindowMenuFrameList()
2840 frames.remove(currentFrame)
2841 frames.append(currentFrame) # Make the current frame the last frame so that it is the last one to appear
2842 for frame in frames:
2843 if delta == 0:
2844 delta = frame.GetClientAreaOrigin()[1]
2845 frame.SetPosition((posx, posy))
2846 frame.SetSize((sizex, sizey))
2847 # TODO: Need to loop around if posx + delta + size > displaysize
2848 frame.SetFocus()
2849 posx = posx + delta
2850 posy = posy + delta
2851 if posx + sizex > wx.DisplaySize()[0] or posy + sizey > wx.DisplaySize()[1]:
2852 posx = 0
2853 posy = 0
2854 currentFrame.SetFocus()
2855
2856
2857 def OnSelectWindowMenu(self, event):
2858 """
2859 Called when the Window menu item representing a Frame is selected and brings the selected
2860 Frame to the front of the desktop.
2861 """
2862 id = event.GetId()
2863 index = self._GetWindowMenuIDList().index(id)
2864 if index > -1:
2865 currentFrame = event.GetEventObject()
2866 frame = self._GetWindowMenuFrameList(currentFrame)[index]
2867 if frame:
2868 wx.CallAfter(frame.Raise)
2869
2870
2871 def OnSelectMoreWindows(self, event):
2872 """
2873 Called when the "Window/Select More Windows..." menu item is selected and enables user to
2874 select from the Frames that do not in the Window list. Useful when there are more than
2875 10 open frames in the application.
2876 """
2877 frames = self._GetWindowMenuFrameList() # TODO - make the current window the first one
2878 strings = map(lambda frame: frame.GetTitle(), frames)
2879 # Should preselect the current window, but not supported by wx.GetSingleChoice
2880 res = wx.GetSingleChoiceIndex(_("Select a window to show:"),
2881 _("Select Window"),
2882 strings,
2883 self)
2884 if res == -1:
2885 return
2886 frames[res].SetFocus()
2887
2888
2889#----------------------------------------------------------------------------
2890# File generated by encode_bitmaps.py
2891#----------------------------------------------------------------------------
2892from wx import ImageFromStream, BitmapFromImage
2893import cStringIO
2894
2895#----------------------------------------------------------------------
2896def getNewData():
2897 return \
2898'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2899\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2900\x00\x00[IDAT8\x8d\xed\x93\xb1\n\x001\x08C\x13{\xff\xff\xc7mn\xb8El\x91\x16\
2901\x97\x0e\x97M\x90\x97\x88JZCE\x8f/4\xba\xb2fZc\n\x00\x00i\xcd \t\x8d\xae\x08\
2902\xb1\xad\x9c\x0e\x1eS\x1e\x01\xc8\xcf\xdcC\xa6\x112\xf7\x08:N\xb0\xd2\x0f\
2903\xb8\x010\xdd\x81\xdf\xf1\x8eX\xfd\xc6\xf2\x08/D\xbd\x19(\xc8\xa5\xd9\xfa\
2904\x00\x00\x00\x00IEND\xaeB`\x82'
2905
2906def getNewBitmap():
2907 return BitmapFromImage(getNewImage())
2908
2909def getNewImage():
2910 stream = cStringIO.StringIO(getNewData())
2911 return ImageFromStream(stream)
2912
2913#----------------------------------------------------------------------
2914def getOpenData():
2915 return \
2916'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2917\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2918\x00\x00\x95IDAT8\x8d\xa5\x92\xc1\x12\x03!\x08C\x13\xec\x87\xfb\xe3B\x0f.]\
2919\xb0\x8e[m.\xea\x0c/\x06\x06R\n\xfe\xd1\xeb\xd7B\xd5f~\x17)\xdc2Pm\x16!\x7f\
2920\xab6\xe3i\x0b\x9e\xe8\x93\xc0BD\x86\xdfV0\x00\x90R`\xda\xcc\x0c\x00\x0c\x00\
2921\xc1\x05>\x9a\x87\x19t\x180\x981\xbd\xfd\xe4\xc4Y\x82\xf7\x14\xca\xe7\xb7\
2922\xa6\t\xee6\x1c\xba\xe18\xab\xc1 \xc3\xb5N?L\xaa5\xb5\xd0\x8dw`JaJ\xb0\x0b\
2923\x03!\xc1\t\xdc\xb9k\x0f\x9e\xd1\x0b\x18\xf6\xe0x\x95]\xf2\\\xb2\xd6\x1b}\
2924\x14BL\xb9{t\xc7\x00\x00\x00\x00IEND\xaeB`\x82'
2925
2926def getOpenBitmap():
2927 return BitmapFromImage(getOpenImage())
2928
2929def getOpenImage():
2930 stream = cStringIO.StringIO(getOpenData())
2931 return ImageFromStream(stream)
2932
2933#----------------------------------------------------------------------
2934def getCopyData():
2935 return \
2936'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2937\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2938\x00\x00\x9fIDAT8\x8d\xa5\x93\xdb\x0e\x830\x0cC\xed\x84\xdfF\xeb\xb4\xef\xa6\
2939\xde\x030z\t\x94\tK\x91z\xcb\x01\xbb*i\x8e\'\x9a\x00@yQ\xb4Is\x8e\x00\xb6\
2940\x0f$Uu\x05\x0e\x01\x91$\r!\xa49\x94\x17I\x02\xc9_\xe3:Nq\x93}XL|\xeb\xe9\
2941\x05\xa4p\rH\xa29h^[ Y\xd5\xb9\xb5\x17\x94gu\x19DA\x96\xe0c\xfe^\xcf\xe7Y\
2942\x95\x05\x00M\xf5\x16Z;\x7f\xfdAd\xcf\xee\x1cj\xc1%|\xdan"LL\x19\xda\xe1}\
2943\x90:\x00#\x95_l5\x04\xec\x89\x9f\xef?|\x8d\x97o\xe1\x8e\xbeJ\xfc\xb1\xde\
2944\xea\xf8\xb9\xc4\x00\x00\x00\x00IEND\xaeB`\x82'
2945
2946def getCopyBitmap():
2947 return BitmapFromImage(getCopyImage())
2948
2949def getCopyImage():
2950 stream = cStringIO.StringIO(getCopyData())
2951 return ImageFromStream(stream)
2952
2953#----------------------------------------------------------------------
2954def getPasteData():
2955 return \
2956"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2957\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2958\x00\x00\xa1IDAT8\x8d\xa5\x93\xd9\x0e\xc3 \x0c\x04\xc7\xa6\xbf]\xc5U\xbf\xbb\
2959\xd9>$4\\9\xaa\xacd\t\x0c\x1e/H6\xf3\xc4\x1d=FI\xcd\x1f\x95{\xf3d{\x003O]\
2960\x01\x80\x94/\x0c\x8a\n\xa0\x01\x8a\x88\xdfaD m\x85y\xdd\xde\xc9\x10/\xc9\
2961\xf9\xc0S2\xf3%\xf2\xba\x04\x94\xea\xfe`\xf4\x9c#U\x80\xbd.\x97\x015\xec&\
2962\x00@\x9a\xba\x9c\xd9\x0b\x08\xe0\r4\x9fxU\xd2\x84\xe6\xa7N\x1dl\x1dkGe\xee\
2963\x14\xd0>\xa3\x85\xfc\xe5`\x08]\x87I}\x84\x8e\x04!\xf3\xb48\x18\r\x8bf4\xea\
2964\xde;\xbc9\xce_!\\\\T\xf75'\xd6\x00\x00\x00\x00IEND\xaeB`\x82"
2965
2966def getPasteBitmap():
2967 return BitmapFromImage(getPasteImage())
2968
2969def getPasteImage():
2970 stream = cStringIO.StringIO(getPasteData())
2971 return ImageFromStream(stream)
2972
2973#----------------------------------------------------------------------
2974def getSaveData():
2975 return \
2976'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2977\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2978\x00\x00lIDAT8\x8d\xc5\x93\xe1\n\xc0 \x08\x84=\xed\xc1}\xf1\xcd\xfd\x18B\x98\
2979mX\x83\x1d\x04\x11\xfayV\x02,\xb4#\xde\xca&\xa2\xe6\x1b;\x0f\xab$\x82\x05\
2980\x83\x03U\xbdaf\xe9\xea\x13]\xe5\x16\xa2\xd32\xc0].\x03\xa2Z<PU\x02\x90\xc5\
2981\x0e\xd5S\xc0,p\xa6\xef[xs\xb0t\x89`A|\xff\x12\xe0\x11\xde\x0fS\xe5;\xbb#\
2982\xfc>\x8d\x17\x18\xfd(\xb72\xc2\x06\x00\x00\x00\x00\x00IEND\xaeB`\x82'
2983
2984def getSaveBitmap():
2985 return BitmapFromImage(getSaveImage())
2986
2987def getSaveImage():
2988 stream = cStringIO.StringIO(getSaveData())
2989 return ImageFromStream(stream)
2990
2991#----------------------------------------------------------------------
2992def getSaveAllData():
2993 return \
2994'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
2995\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
2996\x00\x01\tIDAT8\x8d\xa5\x93\xe1m\x830\x10\x85\xdfA\xd7H\x827\xf0\x02\xado\
2997\x04\x8f`Fh\xfb\xb7\xad\xcd&$Y\x80\x11\xcc\x06\x8c\xe0E\xd2\xeb\x8f\x16\x04!\
29988R\xf3\xa4\x93Nw\xd2\xf3\xa7g\x9b\xa8(\xf1\x88\x9er\xcb\xc3~\')%x\xef\xa7Y\
2999\x8c\x11J)\x00\xc0\xf1t&PQn\x163\x0b\x00\x99\xcb{/\x00\xc49\'T\x94(\xfe\x83\
3000\x1dB\x98\xfa\x95\xc1a\xbf\x13\xf9\xbe\xc8\xd7\xe7\x87\x18c\xe0\xbd\x073\xa3\
3001\xaek\x10\x11\xfa\xbe\xcfgPU\x15RJ\x8bSB\x08h\x9af1\xdb$\xc8aw]\x87\xae\xeb\
3002\xd6\x04\xd7i\x1bc\xc0\xccPJ\xa1m[03\x98\x19Z\xeb\x951QQ\xc2\xbc<K\x8c\x11"\
3003\x92\xc5N)M\xbd\xd6\x1a\xafo\xef\x94}\x07#6\x00Xk\x7f\xef\xfdO\xc7\xd3\x19\
3004\xc0,\x83\x10\x02\x88h\xaa1m\xad\xf5M\xf4E\x06s\x93-\xcd\xf1\xef\x1a\x8c\'^c\
3005\xdf5\x18\x95C\xbei`\xad\xc50\x0cp\xce-\x96[\xd8s\xd1\xa3\xdf\xf9\x075\xf1v>\
3006\x92\xcb\xbc\xdd\x00\x00\x00\x00IEND\xaeB`\x82'
3007
3008def getSaveAllBitmap():
3009 return BitmapFromImage(getSaveAllImage())
3010
3011def getSaveAllImage():
3012 stream = cStringIO.StringIO(getSaveAllData())
3013 return ImageFromStream(stream)
3014
3015#----------------------------------------------------------------------
3016def getPrintData():
3017 return \
3018"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
3019\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
3020\x00\x00\xa1IDAT8\x8d\xa5S[\x0e\x02!\x0c\xec\xd0\xbd\xb6\x1a\xf5\xda\x96\xd9\
3021\x0f\xa1V\x96\x00\xbaMHI\xd3y\xf0(\x90T\xce\xc4\xd6+2\x1bg@$E\x97\x80\xd9H\
3022\x8e\xf1\x00\xc6\x0e\xda&''\x05\x80\xab\x1f\x08\xa2\xfa\xcc\xc5\xd0\xc1H\xbd\
3023\n\x89\xbc\xef\xc1\tV\xd5\x91\x14\xcc\xc6\x9a\xa5<#WV\xed\x8d\x18\x94\xc2\
3024\xd1s'\xa2\xb2\xe7\xc2\xf4STAf\xe3\x16\x0bm\xdc\xae\x17'\xbf?\x9e\x0e\x8an\
3025\x86G\xc8\xf6\xf9\x91I\xf5\x8b\xa0\n\xff}\x04w\x80\xa4ng\x06l/QD\x04u\x1aW\
3026\x06(:\xf0\xfd\x99q\xce\xf6\xe2\x0e\xa5\xa2~.\x00=\xb5t\x00\x00\x00\x00IEND\
3027\xaeB`\x82"
3028
3029def getPrintBitmap():
3030 return BitmapFromImage(getPrintImage())
3031
3032def getPrintImage():
3033 stream = cStringIO.StringIO(getPrintData())
3034 return ImageFromStream(stream)
3035
3036#----------------------------------------------------------------------
3037def getPrintPreviewData():
3038 return \
3039'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
3040\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
3041\x00\x00\xa8IDAT8\x8d\x9d\x93K\x0e\xc30\x08Dg \xd7n\xcd\xc1\x9b\xd2E\x83E\\\
3042\xffT$/\x82\xc5\x83\x19\x13\x02p,\x82\xa2\x1c\xde\x01p\xf71\x83\xe4\x14"\xab\
3043\xeeQ\xec\xef\xb3\xdbe{\x82\x0c\xcb\xdf\xc7\xaa{\x86\xb7\xb0-@\xaf(\xc7\xd4\
3044\x03\x9203P\x94\x14\xa5\x99\xa1\xf5b\x08\x88b+\x05~\xbejQ\x0f\xe2\xbd\x00\
3045\xe0\x14\x05\xdc\x9d\xa2\xa0(\xcc\xec\x9b\xbb\xee(\xba~F\xea15a\n(\xcfG\x1d5\
3046d\xe4\xdcTB\xc8\x88\xb1CB\x9b\x9b\x02\x02\x92O@\xaa\x0fXl\xe2\xcd\x0f\xf2g\
3047\xad\x89\x8d\xbf\xf1\x06\xb9V9 \x0c\x1d\xff\xc6\x07\x8aF\x9e\x04\x12\xb5\xf9\
3048O\x00\x00\x00\x00IEND\xaeB`\x82'
3049
3050def getPrintPreviewBitmap():
3051 return BitmapFromImage(getPrintPreviewImage())
3052
3053def getPrintPreviewImage():
3054 stream = cStringIO.StringIO(getPrintPreviewData())
3055 return ImageFromStream(stream)
3056
3057#----------------------------------------------------------------------
3058def getCutData():
3059 return \
3060"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
3061\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
3062\x00\x00rIDAT8\x8d\xad\x93\xc1\x0e\xc0 \x08CW\xdco{\xf2\xbb';\xb18\x07\x9d\
3063\x0b\xe3\xa2\x98\xe6\xb5$\x02H\xd92%\xde\xa3\xf6CY\xff\nH'\xf8\x05`\xb1Y\xfc\
3064\x10\x00)`\xfdR\x82\x15w\n0W\xe6N\x01\xda\xab\x8e\xe7g\xc0\xe8\xae\xbdj\x04\
3065\xda#\xe7;\xa8] \xbb\xbb\tL0\x8bX\xa5?\xd2c\x84\xb9 \r6\x96\x97\x0c\xf362\
3066\xb1k\x90]\xe7\x13\x85\xca7&\xcf\xda\xcdU\x00\x00\x00\x00IEND\xaeB`\x82"
3067
3068def getCutBitmap():
3069 return BitmapFromImage(getCutImage())
3070
3071def getCutImage():
3072 stream = cStringIO.StringIO(getCutData())
3073 return ImageFromStream(stream)
3074
3075#----------------------------------------------------------------------
3076def getUndoData():
3077 return \
3078"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
3079\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
3080\x00\x00lIDAT8\x8d\xed\x92Q\x0b\x800\x08\x84\xd5\xf5\xb7\x07W\xfdo\xed!\xaca\
3081\xb2\x11{\xe9!a\xa0\xc7\xeec\x1ec\x96B3%S\xeeO\x00\x96\xd1\x05\xd3j\xed\x0c\
3082\x10\xad\xdb\xce\x97\xc0R\xe8\x0c\x12\xe6\xbd\xcfQs\x1d\xb8\xf5\xd4\x90\x19#\
3083\xc4\xfbG\x06\xa6\xd5X\x9a'\x0e*\r1\xee\xfd\x1a\xd0\x83\x98V\x03\x1a\xa1\xb7\
3084k<@\x12\xec\xff\x95\xe7\x01\x07L\x0e(\xe5\xa4\xff\x1c\x88\x00\x00\x00\x00IEN\
3085D\xaeB`\x82"
3086
3087def getUndoBitmap():
3088 return BitmapFromImage(getUndoImage())
3089
3090def getUndoImage():
3091 stream = cStringIO.StringIO(getUndoData())
3092 return ImageFromStream(stream)
3093
3094#----------------------------------------------------------------------
3095def getRedoData():
3096 return \
3097"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
3098\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
3099\x00\x00jIDAT8\x8d\xed\x92\xcd\n\xc0 \x0c\x83\x9bv\xaf\xed\x16\xf0\xbd\xd7]&\
3100\xf8\x8f\xe0e\x87\t9$\xb6\x1f\xb5\x08\xa8\xc9\xce\xd1\xad\xeeO\x00\x8e\xdc\\\
3101gp\xb2,\x80FL\tP\x13\xa8\tI\x17\xa1'\x9f$\xd2\xe6\xb9\xef\x86=\xa5\xfb\x1a\
3102\xb8\xbc\x03h\x84\xdf\xc1\xeb|\x19\xd0k.\x00\xe4\xb8h\x94\xbf\xa3\x95\xef$\
3103\xe7\xbbh\xf4\x7f\xe5}\xc0\x03&\x1b&\xe5\xc2\x03!\xa6\x00\x00\x00\x00IEND\
3104\xaeB`\x82"
3105
3106def getRedoBitmap():
3107 return BitmapFromImage(getRedoImage())
3108
3109def getRedoImage():
3110 stream = cStringIO.StringIO(getRedoData())
3111 return ImageFromStream(stream)
3fa8f722
RD
3112
3113#----------------------------------------------------------------------------
3114
3115def getBlankData():
3116 return \
bbf7159c
RD
3117'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
3118\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
3119\x00\x00]IDAT8\x8d\xed\x931\x0e\xc00\x08\x03m\x92\xff\xff8q\x87\xb6C\x11\x89\
3120\xa8X:\xd4\x13\x03:\x1b\x01\xa45T\xd4\xefBsh\xd7Hk\xdc\x02\x00@\x8a\x19$\xa1\
31219\x14A,\x95\xf3\x82G)\xd3\x00\xf24\xf7\x90\x1ev\x07\xee\x1e\xf4:\xc1J?\xe0\
3122\x0b\x80\xc7\x1d\xf8\x1dg\xc4\xea7\x96G8\x00\xa8\x91\x19(\x85#P\x7f\x00\x00\
3123\x00\x00IEND\xaeB`\x82'
3fa8f722
RD
3124
3125
3126def getBlankBitmap():
3127 return BitmapFromImage(getBlankImage())
3128
3129def getBlankImage():
3130 stream = cStringIO.StringIO(getBlankData())
3131 return ImageFromStream(stream)
3132
3133def getBlankIcon():
bbf7159c 3134 return wx.IconFromBitmap(getBlankBitmap())
3fa8f722
RD
3135
3136