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