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