]> git.saurik.com Git - wxWidgets.git/blame - wxPython/wx/lib/pydocview.py
Add line control points before the end point
[wxWidgets.git] / wxPython / wx / lib / pydocview.py
CommitLineData
d1dc2b32
RD
1#----------------------------------------------------------------------------
2# Name: pydocview.py
3# Purpose: Python extensions to the wxWindows docview framework
4#
3fa8f722 5# Author: Peter Yared, Morgan Hua
d1dc2b32
RD
6#
7# Created: 5/15/03
8# CVS-ID: $Id$
3fa8f722 9# Copyright: (c) 2003-2005 ActiveGrid, Inc.
d1dc2b32
RD
10# License: wxWindows license
11#----------------------------------------------------------------------------
12
13
14import wx
15import wx.lib.docview
16import sys
17import getopt
18from wxPython.lib.rcsizer import RowColSizer
19import os
20import os.path
21import time
22import string
74b89458 23import pickle
74b89458
RD
24import tempfile
25import mmap
d1dc2b32 26_ = wx.GetTranslation
3fa8f722
RD
27if wx.Platform == '__WXMSW__':
28 _WINDOWS = True
29else:
30 _WINDOWS = False
74b89458 31
d1dc2b32
RD
32#----------------------------------------------------------------------------
33# Constants
34#----------------------------------------------------------------------------
35
36VIEW_TOOLBAR_ID = wx.NewId()
37VIEW_STATUSBAR_ID = wx.NewId()
38
39EMBEDDED_WINDOW_TOP = 1
40EMBEDDED_WINDOW_BOTTOM = 2
41EMBEDDED_WINDOW_LEFT = 4
42EMBEDDED_WINDOW_RIGHT = 8
43EMBEDDED_WINDOW_TOPLEFT = 16
44EMBEDDED_WINDOW_BOTTOMLEFT = 32
45EMBEDDED_WINDOW_TOPRIGHT = 64
46EMBEDDED_WINDOW_BOTTOMRIGHT = 128
47EMBEDDED_WINDOW_ALL = EMBEDDED_WINDOW_TOP | EMBEDDED_WINDOW_BOTTOM | EMBEDDED_WINDOW_LEFT | EMBEDDED_WINDOW_RIGHT | \
48 EMBEDDED_WINDOW_TOPLEFT | EMBEDDED_WINDOW_BOTTOMLEFT | EMBEDDED_WINDOW_TOPRIGHT | EMBEDDED_WINDOW_BOTTOMRIGHT
49
50SAVEALL_ID = wx.NewId()
51
52WINDOW_MENU_NUM_ITEMS = 9
53
54
3fa8f722 55class DocFrameMixIn:
d1dc2b32 56 """
3fa8f722
RD
57 Class with common code used by DocMDIParentFrame, DocTabbedParentFrame, and
58 DocSDIFrame.
d1dc2b32 59 """
3fa8f722 60
d1dc2b32
RD
61
62 def GetDocumentManager(self):
d1dc2b32 63 """
3fa8f722 64 Returns the document manager associated with the DocMDIParentFrame.
d1dc2b32 65 """
3fa8f722 66 return self._docManager
d1dc2b32
RD
67
68
3fa8f722 69 def InitializePrintData(self):
d1dc2b32 70 """
3fa8f722 71 Initializes the PrintData that is used when printing.
d1dc2b32 72 """
3fa8f722
RD
73 self._printData = wx.PrintData()
74 self._printData.SetPaperId(wx.PAPER_LETTER)
d1dc2b32
RD
75
76
3fa8f722 77 def CreateDefaultMenuBar(self, sdi=False):
d1dc2b32 78 """
3fa8f722 79 Creates the default MenuBar. Contains File, Edit, View, Tools, and Help menus.
d1dc2b32 80 """
3fa8f722
RD
81 menuBar = wx.MenuBar()
82
83 fileMenu = wx.Menu()
84 fileMenu.Append(wx.ID_NEW, _("&New...\tCtrl+N"), _("Creates a new document"))
85 fileMenu.Append(wx.ID_OPEN, _("&Open...\tCtrl+O"), _("Opens an existing document"))
86 fileMenu.Append(wx.ID_CLOSE, _("&Close"), _("Closes the active document"))
87 if not sdi:
88 fileMenu.Append(wx.ID_CLOSE_ALL, _("Close A&ll"), _("Closes all open documents"))
89 fileMenu.AppendSeparator()
90 fileMenu.Append(wx.ID_SAVE, _("&Save\tCtrl+S"), _("Saves the active document"))
91 fileMenu.Append(wx.ID_SAVEAS, _("Save &As..."), _("Saves the active document with a new name"))
92 fileMenu.Append(SAVEALL_ID, _("Save All\tCtrl+Shift+A"), _("Saves the all active documents"))
93 wx.EVT_MENU(self, SAVEALL_ID, self.ProcessEvent)
94 wx.EVT_UPDATE_UI(self, SAVEALL_ID, self.ProcessUpdateUIEvent)
95 fileMenu.AppendSeparator()
96 fileMenu.Append(wx.ID_PRINT, _("&Print\tCtrl+P"), _("Prints the active document"))
97 fileMenu.Append(wx.ID_PREVIEW, _("Print Pre&view"), _("Displays full pages"))
98 fileMenu.Append(wx.ID_PRINT_SETUP, _("Page Set&up"), _("Changes page layout settings"))
99 fileMenu.AppendSeparator()
100 if wx.Platform == '__WXMAC__':
101 fileMenu.Append(wx.ID_EXIT, _("&Quit"), _("Closes this program"))
102 else:
103 fileMenu.Append(wx.ID_EXIT, _("E&xit"), _("Closes this program"))
104 self._docManager.FileHistoryUseMenu(fileMenu)
105 self._docManager.FileHistoryAddFilesToMenu()
106 menuBar.Append(fileMenu, _("&File"));
d1dc2b32 107
3fa8f722
RD
108 editMenu = wx.Menu()
109 editMenu.Append(wx.ID_UNDO, _("&Undo\tCtrl+Z"), _("Reverses the last action"))
110 editMenu.Append(wx.ID_REDO, _("&Redo\tCtrl+Y"), _("Reverses the last undo"))
111 editMenu.AppendSeparator()
112 #item = wxMenuItem(self.editMenu, wxID_CUT, _("Cu&t\tCtrl+X"), _("Cuts the selection and puts it on the Clipboard"))
113 #item.SetBitmap(getCutBitmap())
114 #editMenu.AppendItem(item)
115 editMenu.Append(wx.ID_CUT, _("Cu&t\tCtrl+X"), _("Cuts the selection and puts it on the Clipboard"))
116 wx.EVT_MENU(self, wx.ID_CUT, self.ProcessEvent)
117 wx.EVT_UPDATE_UI(self, wx.ID_CUT, self.ProcessUpdateUIEvent)
118 editMenu.Append(wx.ID_COPY, _("&Copy\tCtrl+C"), _("Copies the selection and puts it on the Clipboard"))
119 wx.EVT_MENU(self, wx.ID_COPY, self.ProcessEvent)
120 wx.EVT_UPDATE_UI(self, wx.ID_COPY, self.ProcessUpdateUIEvent)
121 editMenu.Append(wx.ID_PASTE, _("&Paste\tCtrl+V"), _("Inserts Clipboard contents"))
122 wx.EVT_MENU(self, wx.ID_PASTE, self.ProcessEvent)
123 wx.EVT_UPDATE_UI(self, wx.ID_PASTE, self.ProcessUpdateUIEvent)
bbf7159c 124 editMenu.Append(wx.ID_CLEAR, _("&Delete"), _("Erases the selection"))
3fa8f722
RD
125 wx.EVT_MENU(self, wx.ID_CLEAR, self.ProcessEvent)
126 wx.EVT_UPDATE_UI(self, wx.ID_CLEAR, self.ProcessUpdateUIEvent)
127 editMenu.AppendSeparator()
128 editMenu.Append(wx.ID_SELECTALL, _("Select A&ll\tCtrl+A"), _("Selects all available data"))
129 wx.EVT_MENU(self, wx.ID_SELECTALL, self.ProcessEvent)
130 wx.EVT_UPDATE_UI(self, wx.ID_SELECTALL, self.ProcessUpdateUIEvent)
131 menuBar.Append(editMenu, _("&Edit"))
132 if sdi:
133 if self.GetDocument() and self.GetDocument().GetCommandProcessor():
134 self.GetDocument().GetCommandProcessor().SetEditMenu(editMenu)
135
136 viewMenu = wx.Menu()
137 viewMenu.AppendCheckItem(VIEW_TOOLBAR_ID, _("&Toolbar"), _("Shows or hides the toolbar"))
138 wx.EVT_MENU(self, VIEW_TOOLBAR_ID, self.OnViewToolBar)
139 wx.EVT_UPDATE_UI(self, VIEW_TOOLBAR_ID, self.OnUpdateViewToolBar)
140 viewMenu.AppendCheckItem(VIEW_STATUSBAR_ID, _("&Status Bar"), _("Shows or hides the status bar"))
141 wx.EVT_MENU(self, VIEW_STATUSBAR_ID, self.OnViewStatusBar)
142 wx.EVT_UPDATE_UI(self, VIEW_STATUSBAR_ID, self.OnUpdateViewStatusBar)
143 menuBar.Append(viewMenu, _("&View"))
d1dc2b32 144
3fa8f722
RD
145 helpMenu = wx.Menu()
146 helpMenu.Append(wx.ID_ABOUT, _("&About" + " " + wx.GetApp().GetAppName()), _("Displays program information, version number, and copyright"))
3fa8f722 147 menuBar.Append(helpMenu, _("&Help"))
d1dc2b32 148
bbf7159c 149 wx.EVT_MENU(self, wx.ID_ABOUT, self.OnAbout)
3fa8f722 150 wx.EVT_UPDATE_UI(self, wx.ID_ABOUT, self.ProcessUpdateUIEvent) # Using ID_ABOUT to update the window menu, the window menu items are not triggering
d1dc2b32 151
3fa8f722
RD
152 if sdi: # TODO: Is this really needed?
153 wx.EVT_COMMAND_FIND_CLOSE(self, -1, self.ProcessEvent)
154
155 return menuBar
d1dc2b32
RD
156
157
3fa8f722 158 def CreateDefaultStatusBar(self):
d1dc2b32 159 """
3fa8f722 160 Creates the default StatusBar.
d1dc2b32 161 """
3fa8f722
RD
162 wx.Frame.CreateStatusBar(self)
163 self.GetStatusBar().Show(wx.ConfigBase_Get().ReadInt("ViewStatusBar", True))
164 self.UpdateStatus()
165 return self.GetStatusBar()
d1dc2b32
RD
166
167
3fa8f722 168 def CreateDefaultToolBar(self):
d1dc2b32 169 """
3fa8f722 170 Creates the default ToolBar.
d1dc2b32 171 """
3fa8f722
RD
172 self._toolBar = self.CreateToolBar(wx.TB_HORIZONTAL | wx.NO_BORDER | wx.TB_FLAT)
173 self._toolBar.AddSimpleTool(wx.ID_NEW, getNewBitmap(), _("New"), _("Creates a new document"))
174 self._toolBar.AddSimpleTool(wx.ID_OPEN, getOpenBitmap(), _("Open"), _("Opens an existing document"))
175 self._toolBar.AddSimpleTool(wx.ID_SAVE, getSaveBitmap(), _("Save"), _("Saves the active document"))
176 self._toolBar.AddSimpleTool(SAVEALL_ID, getSaveAllBitmap(), _("Save All"), _("Saves all the active documents"))
177 self._toolBar.AddSeparator()
178 self._toolBar.AddSimpleTool(wx.ID_PRINT, getPrintBitmap(), _("Print"), _("Displays full pages"))
179 self._toolBar.AddSimpleTool(wx.ID_PREVIEW, getPrintPreviewBitmap(), _("Print Preview"), _("Prints the active document"))
180 self._toolBar.AddSeparator()
181 self._toolBar.AddSimpleTool(wx.ID_CUT, getCutBitmap(), _("Cut"), _("Cuts the selection and puts it on the Clipboard"))
182 self._toolBar.AddSimpleTool(wx.ID_COPY, getCopyBitmap(), _("Copy"), _("Copies the selection and puts it on the Clipboard"))
183 self._toolBar.AddSimpleTool(wx.ID_PASTE, getPasteBitmap(), _("Paste"), _("Inserts Clipboard contents"))
184 self._toolBar.AddSimpleTool(wx.ID_UNDO, getUndoBitmap(), _("Undo"), _("Reverses the last action"))
185 self._toolBar.AddSimpleTool(wx.ID_REDO, getRedoBitmap(), _("Redo"), _("Reverses the last undo"))
186 self._toolBar.Realize()
187 self._toolBar.Show(wx.ConfigBase_Get().ReadInt("ViewToolBar", True))
188
189 return self._toolBar
d1dc2b32
RD
190
191
3fa8f722 192 def OnFileSaveAll(self, event):
d1dc2b32 193 """
3fa8f722 194 Saves all of the currently open documents.
d1dc2b32 195 """
3fa8f722
RD
196 docs = wx.GetApp().GetDocumentManager().GetDocuments()
197 for doc in docs:
198 doc.Save()
d1dc2b32
RD
199
200
3fa8f722 201 def OnAbout(self, event):
d1dc2b32 202 """
3fa8f722 203 Invokes the about dialog.
d1dc2b32 204 """
3fa8f722
RD
205 aboutService = wx.GetApp().GetService(AboutService)
206 if aboutService:
207 aboutService.ShowAbout()
d1dc2b32
RD
208
209
3fa8f722 210 def OnViewToolBar(self, event):
d1dc2b32 211 """
3fa8f722 212 Toggles whether the ToolBar is visible.
d1dc2b32 213 """
3fa8f722
RD
214 self._toolBar.Show(not self._toolBar.IsShown())
215 self._LayoutFrame()
d1dc2b32 216
3fa8f722
RD
217
218 def OnUpdateViewToolBar(self, event):
d1dc2b32 219 """
3fa8f722 220 Updates the View ToolBar menu item.
d1dc2b32 221 """
3fa8f722 222 event.Check(self.GetToolBar().IsShown())
d1dc2b32
RD
223
224
3fa8f722 225 def OnViewStatusBar(self, event):
d1dc2b32 226 """
3fa8f722 227 Toggles whether the StatusBar is visible.
d1dc2b32 228 """
3fa8f722
RD
229 self.GetStatusBar().Show(not self.GetStatusBar().IsShown())
230 self._LayoutFrame()
d1dc2b32
RD
231
232
3fa8f722 233 def OnUpdateViewStatusBar(self, event):
d1dc2b32 234 """
3fa8f722 235 Updates the View StatusBar menu item.
d1dc2b32 236 """
3fa8f722 237 event.Check(self.GetStatusBar().IsShown())
d1dc2b32
RD
238
239
3fa8f722 240 def UpdateStatus(self, message = _("Ready")):
d1dc2b32 241 """
3fa8f722 242 Updates the StatusBar.
d1dc2b32 243 """
3fa8f722
RD
244 # wxBug: Menubar and toolbar help strings don't pop the status text back
245 if self.GetStatusBar().GetStatusText() != message:
246 self.GetStatusBar().PushStatusText(message)
d1dc2b32
RD
247
248
3fa8f722 249class DocMDIParentFrameMixIn:
d1dc2b32 250 """
3fa8f722 251 Class with common code used by DocMDIParentFrame and DocTabbedParentFrame.
d1dc2b32 252 """
3fa8f722 253
d1dc2b32 254
3fa8f722 255 def _GetPosSizeFromConfig(self, pos, size):
d1dc2b32 256 """
3fa8f722 257 Adjusts the position and size of the frame using the saved config position and size.
d1dc2b32 258 """
3fa8f722
RD
259 config = wx.ConfigBase_Get()
260 if pos == wx.DefaultPosition and size == wx.DefaultSize and config.ReadInt("MDIFrameMaximized", False):
261 pos = [0, 0]
262 size = wx.DisplaySize()
263 # wxBug: Need to set to fill screen to get around bug where maximize is leaving shadow of statusbar, check out maximize call at end of this function
264 else:
265 if pos == wx.DefaultPosition:
266 pos = config.ReadInt("MDIFrameXLoc", -1), config.ReadInt("MDIFrameYLoc", -1)
267
268 if wx.Display_GetFromPoint(pos) == -1: # Check if the frame position is offscreen
269 pos = wx.DefaultPosition
270
271 if size == wx.DefaultSize:
272 size = wx.Size(config.ReadInt("MDIFrameXSize", 450), config.ReadInt("MDIFrameYSize", 300))
273 return pos, size
274
275
276 def _InitFrame(self, embeddedWindows):
277 """
278 Initializes the frame and creates the default menubar, toolbar, and status bar.
279 """
280 self._embeddedWindows = []
281 self.SetDropTarget(_DocFrameFileDropTarget(self._docManager, self))
282
283 if wx.GetApp().GetDefaultIcon():
284 self.SetIcon(wx.GetApp().GetDefaultIcon())
285
286 wx.EVT_MENU(self, wx.ID_ABOUT, self.OnAbout)
287 wx.EVT_SIZE(self, self.OnSize)
288
289 self.InitializePrintData()
290
291 toolBar = self.CreateDefaultToolBar()
292 self.SetToolBar(toolBar)
293 menuBar = self.CreateDefaultMenuBar()
294 statusBar = self.CreateDefaultStatusBar()
295
296 config = wx.ConfigBase_Get()
297 if config.ReadInt("MDIFrameMaximized", False):
298 # wxBug: On maximize, statusbar leaves a residual that needs to be refereshed, happens even when user does it
299 self.Maximize()
300
301 self.CreateEmbeddedWindows(embeddedWindows)
302 self._LayoutFrame()
303
bbf7159c
RD
304 if wx.Platform == '__WXMAC__':
305 self.SetMenuBar(menuBar) # wxBug: Have to set the menubar at the very end or the automatic MDI "window" menu doesn't get put in the right place when the services add new menus to the menubar
306
3fa8f722
RD
307 wx.GetApp().SetTopWindow(self) # Need to do this here in case the services are looking for wx.GetApp().GetTopWindow()
308 for service in wx.GetApp().GetServices():
309 service.InstallControls(self, menuBar = menuBar, toolBar = toolBar, statusBar = statusBar)
310 if hasattr(service, "ShowWindow"):
311 service.ShowWindow() # instantiate service windows for correct positioning, we'll hide/show them later based on user preference
312
bbf7159c
RD
313 if wx.Platform != '__WXMAC__':
314 self.SetMenuBar(menuBar) # wxBug: Have to set the menubar at the very end or the automatic MDI "window" menu doesn't get put in the right place when the services add new menus to the menubar
3fa8f722
RD
315
316
317 def ProcessEvent(self, event):
318 """
319 Processes an event, searching event tables and calling zero or more
320 suitable event handler function(s). Note that the ProcessEvent
321 method is called from the wxPython docview framework directly since
322 wxPython does not have a virtual ProcessEvent function.
323 """
324 id = event.GetId()
325 if id == SAVEALL_ID:
326 self.OnFileSaveAll(event)
327 return True
328
329 return wx.GetApp().ProcessEvent(event)
330
331
332 def ProcessUpdateUIEvent(self, event):
333 """
334 Processes a UI event, searching event tables and calling zero or more
335 suitable event handler function(s). Note that the ProcessEvent
336 method is called from the wxPython docview framework directly since
337 wxPython does not have a virtual ProcessEvent function.
338 """
339 id = event.GetId()
340 if id == wx.ID_CUT:
341 event.Enable(False)
342 return True
343 elif id == wx.ID_COPY:
344 event.Enable(False)
345 return True
346 elif id == wx.ID_PASTE:
347 event.Enable(False)
348 return True
349 elif id == wx.ID_CLEAR:
350 event.Enable(False)
351 return True
352 elif id == wx.ID_SELECTALL:
353 event.Enable(False)
354 return True
355 elif id == SAVEALL_ID:
356 filesModified = False
357 docs = wx.GetApp().GetDocumentManager().GetDocuments()
358 for doc in docs:
359 if doc.IsModified():
360 filesModified = True
361 break
362
363 event.Enable(filesModified)
364 return True
365 else:
366 return wx.GetApp().ProcessUpdateUIEvent(event)
367
368
369 def CreateEmbeddedWindows(self, windows = 0):
370 """
371 Create the specified embedded windows around the edges of the frame.
372 """
373 frameSize = self.GetSize() # TODO: GetClientWindow.GetSize is still returning 0,0 since the frame isn't fully constructed yet, so using full frame size
374 defaultHSize = int(frameSize[0] / 6)
375 defaultVSize = int(frameSize[1] / 7)
376 defaultSubVSize = int(frameSize[1] / 2)
377 config = wx.ConfigBase_Get()
378 if windows & (EMBEDDED_WINDOW_LEFT | EMBEDDED_WINDOW_TOPLEFT | EMBEDDED_WINDOW_BOTTOMLEFT):
379 self._leftEmbWindow = self._CreateEmbeddedWindow(self, (config.ReadInt("MDIEmbedLeftSize", defaultHSize), -1), wx.LAYOUT_VERTICAL, wx.LAYOUT_LEFT, visible = config.ReadInt("MDIEmbedLeftVisible", 1), sash = wx.SASH_RIGHT)
380 else:
381 self._leftEmbWindow = None
382 if windows & EMBEDDED_WINDOW_TOPLEFT:
383 self._topLeftEmbWindow = self._CreateEmbeddedWindow(self._leftEmbWindow, (-1, config.ReadInt("MDIEmbedTopLeftSize", defaultSubVSize)), wx.LAYOUT_HORIZONTAL, wx.LAYOUT_TOP, visible = config.ReadInt("MDIEmbedTopLeftVisible", 1), sash = wx.SASH_BOTTOM)
384 else:
385 self._topLeftEmbWindow = None
386 if windows & EMBEDDED_WINDOW_BOTTOMLEFT:
387 self._bottomLeftEmbWindow = self._CreateEmbeddedWindow(self._leftEmbWindow, (-1, config.ReadInt("MDIEmbedBottomLeftSize", defaultSubVSize)), wx.LAYOUT_HORIZONTAL, wx.LAYOUT_BOTTOM, visible = config.ReadInt("MDIEmbedBottomLeftVisible", 1))
388 else:
389 self._bottomLeftEmbWindow = None
390 if windows & (EMBEDDED_WINDOW_RIGHT | EMBEDDED_WINDOW_TOPRIGHT | EMBEDDED_WINDOW_BOTTOMRIGHT):
391 self._rightEmbWindow = self._CreateEmbeddedWindow(self, (config.ReadInt("MDIEmbedRightSize", defaultHSize), -1), wx.LAYOUT_VERTICAL, wx.LAYOUT_RIGHT, visible = config.ReadInt("MDIEmbedRightVisible", 1), sash = wx.SASH_LEFT)
392 else:
393 self._rightEmbWindow = None
394 if windows & EMBEDDED_WINDOW_TOPRIGHT:
395 self._topRightEmbWindow = self._CreateEmbeddedWindow(self._rightEmbWindow, (-1, config.ReadInt("MDIEmbedTopRightSize", defaultSubVSize)), wx.LAYOUT_HORIZONTAL, wx.LAYOUT_TOP, visible = config.ReadInt("MDIEmbedTopRightVisible", 1), sash = wx.SASH_BOTTOM)
396 else:
397 self._topRightEmbWindow = None
398 if windows & EMBEDDED_WINDOW_BOTTOMRIGHT:
399 self._bottomRightEmbWindow = self._CreateEmbeddedWindow(self._rightEmbWindow, (-1, config.ReadInt("MDIEmbedBottomRightSize", defaultSubVSize)), wx.LAYOUT_HORIZONTAL, wx.LAYOUT_BOTTOM, visible = config.ReadInt("MDIEmbedBottomRightVisible", 1))
400 else:
401 self._bottomRightEmbWindow = None
402 if windows & EMBEDDED_WINDOW_TOP:
403 self._topEmbWindow = self._CreateEmbeddedWindow(self, (-1, config.ReadInt("MDIEmbedTopSize", defaultVSize)), wx.LAYOUT_HORIZONTAL, wx.LAYOUT_TOP, visible = config.ReadInt("MDIEmbedTopVisible", 1), sash = wx.SASH_BOTTOM)
404 else:
405 self._topEmbWindow = None
406 if windows & EMBEDDED_WINDOW_BOTTOM:
407 self._bottomEmbWindow = self._CreateEmbeddedWindow(self, (-1, config.ReadInt("MDIEmbedBottomSize", defaultVSize)), wx.LAYOUT_HORIZONTAL, wx.LAYOUT_BOTTOM, visible = config.ReadInt("MDIEmbedBottomVisible", 1), sash = wx.SASH_TOP)
408 else:
409 self._bottomEmbWindow = None
410
411
412 def SaveEmbeddedWindowSizes(self):
413 """
414 Saves the sizes of the embedded windows.
415 """
416 config = wx.ConfigBase_Get()
417 if not self.IsMaximized():
418 config.WriteInt("MDIFrameXLoc", self.GetPositionTuple()[0])
419 config.WriteInt("MDIFrameYLoc", self.GetPositionTuple()[1])
420 config.WriteInt("MDIFrameXSize", self.GetSizeTuple()[0])
421 config.WriteInt("MDIFrameYSize", self.GetSizeTuple()[1])
422 config.WriteInt("MDIFrameMaximized", self.IsMaximized())
423 config.WriteInt("ViewToolBar", self._toolBar.IsShown())
424 config.WriteInt("ViewStatusBar", self.GetStatusBar().IsShown())
425
426 if self._leftEmbWindow:
427 config.WriteInt("MDIEmbedLeftSize", self._leftEmbWindow.GetSize()[0])
428 config.WriteInt("MDIEmbedLeftVisible", self._leftEmbWindow.IsShown())
429 if self._topLeftEmbWindow:
430 if self._topLeftEmbWindow._sizeBeforeHidden:
431 size = self._topLeftEmbWindow._sizeBeforeHidden[1]
432 else:
433 size = self._topLeftEmbWindow.GetSize()[1]
434 config.WriteInt("MDIEmbedTopLeftSize", size)
435 config.WriteInt("MDIEmbedTopLeftVisible", self._topLeftEmbWindow.IsShown())
436 if self._bottomLeftEmbWindow:
437 if self._bottomLeftEmbWindow._sizeBeforeHidden:
438 size = self._bottomLeftEmbWindow._sizeBeforeHidden[1]
439 else:
440 size = self._bottomLeftEmbWindow.GetSize()[1]
441 config.WriteInt("MDIEmbedBottomLeftSize", size)
442 config.WriteInt("MDIEmbedBottomLeftVisible", self._bottomLeftEmbWindow.IsShown())
443 if self._rightEmbWindow:
444 config.WriteInt("MDIEmbedRightSize", self._rightEmbWindow.GetSize()[0])
445 config.WriteInt("MDIEmbedRightVisible", self._rightEmbWindow.IsShown())
446 if self._topRightEmbWindow:
447 if self._topRightEmbWindow._sizeBeforeHidden:
448 size = self._topRightEmbWindow._sizeBeforeHidden[1]
449 else:
450 size = self._topRightEmbWindow.GetSize()[1]
451 config.WriteInt("MDIEmbedTopRightSize", size)
452 config.WriteInt("MDIEmbedTopRightVisible", self._topRightEmbWindow.IsShown())
453 if self._bottomRightEmbWindow:
454 if self._bottomRightEmbWindow._sizeBeforeHidden:
455 size = self._bottomRightEmbWindow._sizeBeforeHidden[1]
456 else:
457 size = self._bottomRightEmbWindow.GetSize()[1]
458 config.WriteInt("MDIEmbedBottomRightSize", size)
459 config.WriteInt("MDIEmbedBottomRightVisible", self._bottomRightEmbWindow.IsShown())
460 if self._topEmbWindow:
461 config.WriteInt("MDIEmbedTopSize", self._topEmbWindow.GetSize()[1])
462 config.WriteInt("MDIEmbedTopVisible", self._topEmbWindow.IsShown())
463 if self._bottomEmbWindow:
464 config.WriteInt("MDIEmbedBottomSize", self._bottomEmbWindow.GetSize()[1])
465 config.WriteInt("MDIEmbedBottomVisible", self._bottomEmbWindow.IsShown())
466
467
468 def GetEmbeddedWindow(self, loc):
469 """
470 Returns the instance of the embedded window specified by the embedded window location constant.
471 """
472 if loc == EMBEDDED_WINDOW_TOP:
473 return self._topEmbWindow
474 elif loc == EMBEDDED_WINDOW_BOTTOM:
475 return self._bottomEmbWindow
476 elif loc == EMBEDDED_WINDOW_LEFT:
477 return self._leftEmbWindow
478 elif loc == EMBEDDED_WINDOW_RIGHT:
479 return self._rightEmbWindow
480 elif loc == EMBEDDED_WINDOW_TOPLEFT:
481 return self._topLeftEmbWindow
482 elif loc == EMBEDDED_WINDOW_BOTTOMLEFT:
483 return self._bottomLeftEmbWindow
484 elif loc == EMBEDDED_WINDOW_TOPRIGHT:
485 return self._topRightEmbWindow
486 elif loc == EMBEDDED_WINDOW_BOTTOMRIGHT:
487 return self._bottomRightEmbWindow
488 return None
489
490
491 def _CreateEmbeddedWindow(self, parent, size, orientation, alignment, visible = True, sash = None):
492 """
493 Creates the embedded window with the specified size, orientation, and alignment. If the
494 window is not visible it will retain the size with which it was last viewed.
495 """
496 window = wx.SashLayoutWindow(parent, wx.NewId(), style = wx.NO_BORDER | wx.SW_3D)
497 window.SetDefaultSize(size)
498 window.SetOrientation(orientation)
499 window.SetAlignment(alignment)
500 if sash != None: # wx.SASH_TOP is 0 so check for None instead of just doing "if sash:"
501 window.SetSashVisible(sash, True)
502 ####
503 def OnEmbeddedWindowSashDrag(event):
504 if event.GetDragStatus() == wx.SASH_STATUS_OUT_OF_RANGE:
505 return
506 sashWindow = event.GetEventObject()
507 if sashWindow.GetAlignment() == wx.LAYOUT_TOP or sashWindow.GetAlignment() == wx.LAYOUT_BOTTOM:
508 size = wx.Size(-1, event.GetDragRect().height)
509 else:
510 size = wx.Size(event.GetDragRect().width, -1)
511 event.GetEventObject().SetDefaultSize(size)
512 self._LayoutFrame()
513 sashWindow.Refresh()
514 if isinstance(sashWindow.GetParent(), wx.SashLayoutWindow):
515 sashWindow.Show()
516 parentSashWindow = sashWindow.GetParent() # Force a refresh
517 parentSashWindow.Layout()
518 parentSashWindow.Refresh()
519 parentSashWindow.SetSize((parentSashWindow.GetSize().width + 1, parentSashWindow.GetSize().height + 1))
520 ####
521 wx.EVT_SASH_DRAGGED(window, window.GetId(), OnEmbeddedWindowSashDrag)
522 window._sizeBeforeHidden = None
523 if not visible:
524 window.Show(False)
525 if isinstance(parent, wx.SashLayoutWindow): # It's a window embedded in another sash window so remember its actual size to show it again
526 window._sizeBeforeHidden = size
527 return window
528
529
530 def ShowEmbeddedWindow(self, window, show = True):
531 """
532 Shows or hides the embedded window specified by the embedded window location constant.
533 """
534 window.Show(show)
535 if isinstance(window.GetParent(), wx.SashLayoutWindow): # It is a parent sashwindow with multiple embedded sashwindows
536 parentSashWindow = window.GetParent()
537 if show: # Make sure it is visible in case all of the subwindows were hidden
538 parentSashWindow.Show()
539 if show and window._sizeBeforeHidden:
540 if window._sizeBeforeHidden[1] == parentSashWindow.GetClientSize()[1]:
541 if window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMLEFT) and self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPLEFT).IsShown():
542 window.SetDefaultSize((window._sizeBeforeHidden[0], window._sizeBeforeHidden[0] - self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPLEFT).GetSize()[1]))
543 elif window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPLEFT) and self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMLEFT).IsShown():
544 window.SetDefaultSize((window._sizeBeforeHidden[0], window._sizeBeforeHidden[0] - self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMLEFT).GetSize()[1]))
545 elif window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMRIGHT) and self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPRIGHT).IsShown():
546 window.SetDefaultSize((window._sizeBeforeHidden[0], window._sizeBeforeHidden[0] - self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPRIGHT).GetSize()[1]))
547 elif window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPRIGHT) and self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMRIGHT).IsShown():
548 window.SetDefaultSize((window._sizeBeforeHidden[0], window._sizeBeforeHidden[0] - self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMRIGHT).GetSize()[1]))
549 else:
550 window.SetDefaultSize(window._sizeBeforeHidden)
551 # If it is not the size of the full parent sashwindow set the other window's size so that if it gets shown it will have a cooresponding size
552 if window._sizeBeforeHidden[1] < parentSashWindow.GetClientSize()[1]:
553 otherWindowSize = (-1, parentSashWindow.GetClientSize()[1] - window._sizeBeforeHidden[1])
554 if window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMLEFT):
555 self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPLEFT).SetDefaultSize(otherWindowSize)
556 elif window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPLEFT):
557 self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMLEFT).SetDefaultSize(otherWindowSize)
558 elif window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMRIGHT):
559 self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPRIGHT).SetDefaultSize(otherWindowSize)
560 elif window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPRIGHT):
561 self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMRIGHT).SetDefaultSize(otherWindowSize)
562
563 if not show:
564 if window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMRIGHT) and not self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPRIGHT).IsShown() \
565 or window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPRIGHT) and not self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMRIGHT).IsShown() \
566 or window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMLEFT) and not self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPLEFT).IsShown() \
567 or window == self.GetEmbeddedWindow(EMBEDDED_WINDOW_TOPLEFT) and not self.GetEmbeddedWindow(EMBEDDED_WINDOW_BOTTOMLEFT).IsShown():
568 parentSashWindow.Hide() # Hide the parent sashwindow if all of the children are hidden
569 parentSashWindow.Layout() # Force a refresh
570 parentSashWindow.Refresh()
571 parentSashWindow.SetSize((parentSashWindow.GetSize().width + 1, parentSashWindow.GetSize().height + 1))
572 self._LayoutFrame()
573
574
575 def HideEmbeddedWindow(self):
576 """
577 Hides the embedded window specified by the embedded window location constant.
578 """
579 self.ShowEmbeddedWindow(show = False)
580
581
582class DocTabbedChildFrame(wx.Panel):
583 """
584 The wxDocMDIChildFrame class provides a default frame for displaying
585 documents on separate windows. This class can only be used for MDI child
586 frames.
587
588 The class is part of the document/view framework supported by wxWindows,
589 and cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplate
590 classes.
591 """
592
593
594 def __init__(self, doc, view, frame, id, title, pos = wx.DefaultPosition, size = wx.DefaultSize, style = wx.DEFAULT_FRAME_STYLE, name = "frame"):
595 """
596 Constructor. Note that the event table must be rebuilt for the
597 frame since the EvtHandler is not virtual.
598 """
599 wx.Panel.__init__(self, frame.GetNotebook(), id)
600 self._childDocument = doc
601 self._childView = view
602 frame.AddNotebookPage(self, doc.GetPrintableName())
603 if view:
604 view.SetFrame(self)
605
606
607 def GetIcon(self):
608 """
609 Dummy method since the icon of tabbed frames are managed by the notebook.
610 """
611 return None
612
613
614 def SetIcon(self, icon):
615 """
616 Dummy method since the icon of tabbed frames are managed by the notebook.
617 """
618 pass
619
620
621 def Destroy(self):
622 """
623 Removes the current notebook page.
624 """
625 wx.GetApp().GetTopWindow().RemoveNotebookPage(self)
626
627
628 def SetFocus(self):
629 """
630 Activates the current notebook page.
631 """
632 wx.GetApp().GetTopWindow().ActivateNotebookPage(self)
633
634
635 def Activate(self): # Need this in case there are embedded sash windows and such, OnActivate is not getting called
636 """
637 Activates the current view.
638 """
639 # Called by Project Editor
640 if self._childView:
641 self._childView.Activate(True)
642
643
644 def GetTitle(self):
645 """
646 Returns the frame's title.
647 """
648 wx.GetApp().GetTopWindow().GetNotebookPageTitle(self)
649
650
651 def SetTitle(self, title):
652 """
653 Sets the frame's title.
654 """
655 wx.GetApp().GetTopWindow().SetNotebookPageTitle(self, title)
656
657
658 def ProcessEvent(event):
659 """
660 Processes an event, searching event tables and calling zero or more
661 suitable event handler function(s). Note that the ProcessEvent
662 method is called from the wxPython docview framework directly since
663 wxPython does not have a virtual ProcessEvent function.
664 """
665 if not self._childView or not self._childView.ProcessEvent(event):
666 if not isinstance(event, wx.CommandEvent) or not self.GetParent() or not self.GetParent().ProcessEvent(event):
667 return False
668 else:
669 return True
670 else:
671 return True
672
673
674 def GetDocument(self):
675 """
676 Returns the document associated with this frame.
677 """
678 return self._childDocument
679
680
681 def SetDocument(self, document):
682 """
683 Sets the document for this frame.
684 """
685 self._childDocument = document
686
687
688 def GetView(self):
689 """
690 Returns the view associated with this frame.
691 """
692 return self._childView
693
694
695 def SetView(self, view):
696 """
697 Sets the view for this frame.
698 """
699 self._childView = view
d1dc2b32 700
3fa8f722
RD
701
702class DocTabbedParentFrame(wx.Frame, DocFrameMixIn, DocMDIParentFrameMixIn):
703 """
704 The DocTabbedParentFrame class provides a default top-level frame for
705 applications using the document/view framework. This class can only be
706 used for MDI parent frames that use a tabbed interface.
707
708 It cooperates with the wxView, wxDocument, wxDocManager and wxDocTemplate
709 classes.
710 """
711
712
713 def __init__(self, docManager, frame, id, title, pos = wx.DefaultPosition, size = wx.DefaultSize, style = wx.DEFAULT_FRAME_STYLE, name = "DocTabbedParentFrame", embeddedWindows = 0):
714 """
715 Constructor. Note that the event table must be rebuilt for the
716 frame since the EvtHandler is not virtual.
717 """
718 pos, size = self._GetPosSizeFromConfig(pos, size)
719 wx.Frame.__init__(self, frame, id, title, pos, size, style, name)
720
721 # From docview.MDIParentFrame
d1dc2b32
RD
722 self._docManager = docManager
723
3fa8f722 724 wx.EVT_CLOSE(self, self.OnCloseWindow)
d1dc2b32 725
3fa8f722
RD
726 wx.EVT_MENU(self, wx.ID_EXIT, self.OnExit)
727 wx.EVT_MENU_RANGE(self, wx.ID_FILE1, wx.ID_FILE9, self.OnMRUFile)
d1dc2b32 728
3fa8f722
RD
729 wx.EVT_MENU(self, wx.ID_NEW, self.ProcessEvent)
730 wx.EVT_MENU(self, wx.ID_OPEN, self.ProcessEvent)
731 wx.EVT_MENU(self, wx.ID_CLOSE_ALL, self.ProcessEvent)
732 wx.EVT_MENU(self, wx.ID_CLOSE, self.ProcessEvent)
733 wx.EVT_MENU(self, wx.ID_REVERT, self.ProcessEvent)
734 wx.EVT_MENU(self, wx.ID_SAVE, self.ProcessEvent)
735 wx.EVT_MENU(self, wx.ID_SAVEAS, self.ProcessEvent)
736 wx.EVT_MENU(self, wx.ID_UNDO, self.ProcessEvent)
737 wx.EVT_MENU(self, wx.ID_REDO, self.ProcessEvent)
738 wx.EVT_MENU(self, wx.ID_PRINT, self.ProcessEvent)
739 wx.EVT_MENU(self, wx.ID_PRINT_SETUP, self.ProcessEvent)
740 wx.EVT_MENU(self, wx.ID_PREVIEW, self.ProcessEvent)
741 wx.EVT_MENU(self, wx.ID_ABOUT, self.OnAbout)
d1dc2b32 742
3fa8f722
RD
743 wx.EVT_UPDATE_UI(self, wx.ID_NEW, self.ProcessUpdateUIEvent)
744 wx.EVT_UPDATE_UI(self, wx.ID_OPEN, self.ProcessUpdateUIEvent)
745 wx.EVT_UPDATE_UI(self, wx.ID_CLOSE_ALL, self.ProcessUpdateUIEvent)
746 wx.EVT_UPDATE_UI(self, wx.ID_CLOSE, self.ProcessUpdateUIEvent)
747 wx.EVT_UPDATE_UI(self, wx.ID_REVERT, self.ProcessUpdateUIEvent)
748 wx.EVT_UPDATE_UI(self, wx.ID_SAVE, self.ProcessUpdateUIEvent)
749 wx.EVT_UPDATE_UI(self, wx.ID_SAVEAS, self.ProcessUpdateUIEvent)
750 wx.EVT_UPDATE_UI(self, wx.ID_UNDO, self.ProcessUpdateUIEvent)
751 wx.EVT_UPDATE_UI(self, wx.ID_REDO, self.ProcessUpdateUIEvent)
752 wx.EVT_UPDATE_UI(self, wx.ID_PRINT, self.ProcessUpdateUIEvent)
753 wx.EVT_UPDATE_UI(self, wx.ID_PRINT_SETUP, self.ProcessUpdateUIEvent)
754 wx.EVT_UPDATE_UI(self, wx.ID_PREVIEW, self.ProcessUpdateUIEvent)
755 # End From docview.MDIParentFrame
756
757 self.CreateNotebook()
758 self._InitFrame(embeddedWindows)
759
d1dc2b32 760
3fa8f722 761 def _LayoutFrame(self):
d1dc2b32 762 """
3fa8f722 763 Lays out the frame.
d1dc2b32 764 """
3fa8f722
RD
765 wx.LayoutAlgorithm().LayoutFrame(self, self._notebook)
766
767
768 def CreateNotebook(self):
769 """
770 Creates the notebook to use for the tabbed document interface.
771 """
772 self._notebook = wx.Notebook(self, wx.NewId())
773 # self._notebook.SetSizer(wx.NotebookSizer(self._notebook))
774 wx.EVT_NOTEBOOK_PAGE_CHANGED(self, self._notebook.GetId(), self.OnNotebookPageChanged)
775 wx.EVT_RIGHT_DOWN(self._notebook, self.OnNotebookRightClick)
776
777 templates = wx.GetApp().GetDocumentManager().GetTemplates()
778 iconList = wx.ImageList(16, 16, initialCount = len(templates))
779 self._iconIndexLookup = []
780 for template in templates:
781 icon = template.GetIcon()
782 if icon:
b792147d
RD
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
3fa8f722
RD
788 iconIndex = iconList.AddIcon(icon)
789 self._iconIndexLookup.append((template, iconIndex))
790
791 icon = getBlankIcon()
b792147d
RD
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"
3fa8f722
RD
797 self._blankIconIndex = iconList.AddIcon(icon)
798 self._notebook.AssignImageList(iconList)
d1dc2b32
RD
799
800
3fa8f722 801 def GetNotebook(self):
d1dc2b32 802 """
3fa8f722 803 Returns the notebook used by the tabbed document interface.
d1dc2b32 804 """
3fa8f722
RD
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)
d1dc2b32
RD
817
818
3fa8f722 819 def OnNotebookPageChanged(self, event):
d1dc2b32 820 """
3fa8f722 821 Activates a notebook page's view when it is selected.
d1dc2b32 822 """
3fa8f722
RD
823 index = self._notebook.GetSelection()
824 if index > -1:
825 self._notebook.GetPage(index).GetView().Activate()
d1dc2b32
RD
826
827
3fa8f722
RD
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)
d1dc2b32 873
3fa8f722
RD
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()
d1dc2b32 885
3fa8f722
RD
886
887 def RemoveNotebookPage(self, panel):
d1dc2b32 888 """
3fa8f722 889 Removes a document page from the notebook.
d1dc2b32 890 """
3fa8f722
RD
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)
d1dc2b32 969 else:
3fa8f722
RD
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)
d1dc2b32 978
3fa8f722
RD
979
980 def OnSize(self, event):
d1dc2b32 981 """
3fa8f722 982 Called when the frame is resized and lays out the client window.
d1dc2b32 983 """
3fa8f722
RD
984 # Needed in case there are splitpanels around the mdi frame
985 self._LayoutFrame()
d1dc2b32
RD
986
987
3fa8f722
RD
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
1006class DocMDIChildFrame(wx.MDIChildFrame):
d1dc2b32 1007 """
3fa8f722
RD
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.
d1dc2b32
RD
1015 """
1016
1017
3fa8f722 1018 def __init__(self, doc, view, frame, id, title, pos = wx.DefaultPosition, size = wx.DefaultSize, style = wx.DEFAULT_FRAME_STYLE, name = "frame"):
d1dc2b32 1019 """
3fa8f722
RD
1020 Constructor. Note that the event table must be rebuilt for the
1021 frame since the EvtHandler is not virtual.
d1dc2b32 1022 """
3fa8f722
RD
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
74b89458 1078 else:
3fa8f722
RD
1079 ret = True
1080 else:
1081 ret = True
74b89458 1082
3fa8f722
RD
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
74b89458 1110 else:
3fa8f722
RD
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
74b89458 1146
74b89458 1147
3fa8f722 1148 def SetView(self, view):
74b89458 1149 """
3fa8f722 1150 Sets the view for this frame.
74b89458 1151 """
3fa8f722
RD
1152 self._childView = view
1153
74b89458 1154
d1dc2b32
RD
1155
1156
3fa8f722
RD
1157
1158class 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
d1dc2b32
RD
1167
1168
1169 def GetDocumentManager(self):
3fa8f722 1170 """Returns the DocManager for the docview application."""
d1dc2b32
RD
1171 return self._docManager
1172
1173
1174 def SetDocumentManager(self, docManager):
3fa8f722 1175 """Sets the DocManager for the docview application."""
d1dc2b32 1176 self._docManager = docManager
3fa8f722
RD
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
d1dc2b32
RD
1182
1183
1184 def ProcessEventBeforeWindows(self, event):
1185 """
3fa8f722
RD
1186 Processes an event before the main window has a chance to process the window.
1187 Override this method for a particular service.
d1dc2b32 1188 """
d1dc2b32
RD
1189 return False
1190
1191
1192 def ProcessUpdateUIEventBeforeWindows(self, event):
1193 """
3fa8f722
RD
1194 Processes a UI event before the main window has a chance to process the window.
1195 Override this method for a particular service.
d1dc2b32 1196 """
d1dc2b32
RD
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 """
d1dc2b32
RD
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 """
d1dc2b32
RD
1217 return False
1218
1219
3fa8f722 1220 def OnCloseFrame(self, event):
d1dc2b32 1221 """
3fa8f722
RD
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.
d1dc2b32 1225 """
3fa8f722 1226 return True
d1dc2b32
RD
1227
1228
3fa8f722 1229 def OnExit(self):
d1dc2b32 1230 """
3fa8f722
RD
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.
d1dc2b32 1234 """
3fa8f722 1235 pass
d1dc2b32
RD
1236
1237
3fa8f722 1238 def GetMenuItemPos(self, menu, id):
d1dc2b32 1239 """
3fa8f722
RD
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.
d1dc2b32 1254 """
d1dc2b32
RD
1255 return None
1256
1257
3fa8f722
RD
1258class 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):
d1dc2b32 1267 """
3fa8f722
RD
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.
d1dc2b32 1273 """
3fa8f722
RD
1274 DocService.__init__(self)
1275 self.ClearOptionsPanels()
1276 self._allowModeChanges = allowModeChanges
1277 self._toolOptionsID = wx.NewId()
1278 if showGeneralOptions:
1279 self.AddOptionsPanel(GeneralOptionsPanel)
d1dc2b32 1280
3fa8f722
RD
1281
1282 def InstallControls(self, frame, menuBar = None, toolBar = None, statusBar = None, document = None):
d1dc2b32 1283 """
3fa8f722 1284 Installs a "Tools" menu with an "Options" menu item.
d1dc2b32 1285 """
3fa8f722
RD
1286 toolsMenuIndex = menuBar.FindMenu(_("&Tools"))
1287 if toolsMenuIndex > -1:
1288 toolsMenu = menuBar.GetMenu(toolsMenuIndex)
d1dc2b32 1289 else:
3fa8f722
RD
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
d1dc2b32 1300
3fa8f722 1301 def ProcessEvent(self, event):
d1dc2b32 1302 """
3fa8f722 1303 Checks to see if the "Options" menu item has been selected.
d1dc2b32 1304 """
3fa8f722
RD
1305 id = event.GetId()
1306 if id == self._toolOptionsID:
1307 self.OnOptions(event)
1308 return True
1309 else:
1310 return False
d1dc2b32
RD
1311
1312
3fa8f722 1313 def GetAllowModeChanges(self):
d1dc2b32 1314 """
3fa8f722
RD
1315 Return true if the default general options pane should allow users to
1316 change the document interface mode between SDI and MDI modes.
d1dc2b32 1317 """
3fa8f722 1318 return self._allowModeChanges
d1dc2b32
RD
1319
1320
3fa8f722 1321 def SetAllowModeChanges(self, allowModeChanges):
d1dc2b32 1322 """
3fa8f722
RD
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.
d1dc2b32 1325 """
3fa8f722 1326 self._allowModeChanges = allowModeChanges
d1dc2b32 1327
d1dc2b32 1328
3fa8f722
RD
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 = []
d1dc2b32
RD
1335
1336
3fa8f722 1337 def AddOptionsPanel(self, optionsPanel):
d1dc2b32 1338 """
3fa8f722 1339 Adds an options panel to the options dialog.
d1dc2b32 1340 """
3fa8f722 1341 self._optionsPanels.append(optionsPanel)
d1dc2b32
RD
1342
1343
3fa8f722 1344 def OnOptions(self, event):
d1dc2b32 1345 """
3fa8f722 1346 Shows the options dialog, called when the "Options" menu item is selected.
d1dc2b32 1347 """
3fa8f722
RD
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
1356class OptionsDialog(wx.Dialog):
1357 """
1358 A default options dialog used by the OptionsService that hosts a notebook
1359 tab of options panels.
1360 """
d1dc2b32 1361
d1dc2b32 1362
3fa8f722
RD
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 """
bbf7159c 1368 wx.Dialog.__init__(self, parent, -1, _("Options"), size = (570, 365))
d1dc2b32 1369
3fa8f722
RD
1370 self._optionsPanels = []
1371 self._docManager = docManager
1372
1373 HALF_SPACE = 5
1374 SPACE = 10
d1dc2b32 1375
3fa8f722 1376 sizer = wx.BoxSizer(wx.VERTICAL)
d1dc2b32 1377
bbf7159c 1378 optionsNotebook = wx.Notebook(self, -1, size = (560, 325))
3fa8f722
RD
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()
bbf7159c
RD
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()
3fa8f722
RD
1388 wx.CallAfter(self.DoRefresh)
1389
1390
1391 def DoRefresh(self):
d1dc2b32 1392 """
3fa8f722
RD
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.
d1dc2b32 1395 """
3fa8f722 1396 self.Refresh()
d1dc2b32
RD
1397
1398
3fa8f722 1399 def GetDocManager(self):
d1dc2b32 1400 """
3fa8f722 1401 Returns the document manager passed to the OptionsDialog constructor.
d1dc2b32 1402 """
3fa8f722 1403 return self._docManager
d1dc2b32
RD
1404
1405
3fa8f722 1406 def OnOK(self, event):
d1dc2b32 1407 """
3fa8f722 1408 Calls the OnOK method of all of the OptionDialog's embedded panels
d1dc2b32 1409 """
3fa8f722
RD
1410 for optionsPanel in self._optionsPanels:
1411 optionsPanel.OnOK(event)
d1dc2b32 1412
d1dc2b32 1413
3fa8f722
RD
1414class 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 """
d1dc2b32
RD
1420
1421
3fa8f722 1422 def __init__(self, parent, id):
d1dc2b32 1423 """
3fa8f722
RD
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.
d1dc2b32 1426 """
3fa8f722
RD
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"))
d1dc2b32
RD
1468
1469
3fa8f722 1470 def OnOK(self, optionsDialog):
d1dc2b32 1471 """
3fa8f722 1472 Updates the config based on the selections in the options panel.
d1dc2b32 1473 """
3fa8f722
RD
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))
d1dc2b32
RD
1479
1480
3fa8f722
RD
1481class 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):
d1dc2b32 1490 """
3fa8f722 1491 Initializes the DocApp.
d1dc2b32 1492 """
3fa8f722
RD
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
d1dc2b32 1546
3fa8f722
RD
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)
d1dc2b32 1555
3fa8f722
RD
1556
1557 def DoBackgroundListenAndLoad(self):
d1dc2b32 1558 """
3fa8f722 1559 Open any files specified in the given command line argument passed in via shared memory
d1dc2b32 1560 """
3fa8f722
RD
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
d1dc2b32
RD
1583
1584
3fa8f722 1585 def OpenCommandLineArgs(self):
74b89458 1586 """
3fa8f722
RD
1587 Called to open files that have been passed to the application from the
1588 command line.
74b89458 1589 """
3fa8f722
RD
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)
74b89458
RD
1594
1595
3fa8f722 1596 def GetDocumentManager(self):
74b89458 1597 """
3fa8f722 1598 Returns the document manager associated to the DocApp.
74b89458 1599 """
3fa8f722 1600 return self._docManager
74b89458
RD
1601
1602
3fa8f722 1603 def SetDocumentManager(self, docManager):
d1dc2b32 1604 """
3fa8f722
RD
1605 Sets the document manager associated with the DocApp and loads the
1606 DocApp's file history into the document manager.
d1dc2b32 1607 """
3fa8f722
RD
1608 self._docManager = docManager
1609 config = wx.ConfigBase_Get()
1610 self.GetDocumentManager().FileHistoryLoad(config)
d1dc2b32
RD
1611
1612
3fa8f722 1613 def ProcessEventBeforeWindows(self, event):
d1dc2b32 1614 """
3fa8f722
RD
1615 Enables services to process an event before the main window has a chance to
1616 process the window.
d1dc2b32 1617 """
3fa8f722
RD
1618 for service in self._services:
1619 if service.ProcessEventBeforeWindows(event):
1620 return True
1621 return False
d1dc2b32
RD
1622
1623
3fa8f722 1624 def ProcessUpdateUIEventBeforeWindows(self, event):
d1dc2b32 1625 """
3fa8f722
RD
1626 Enables services to process a UI event before the main window has a chance
1627 to process the window.
d1dc2b32 1628 """
3fa8f722
RD
1629 for service in self._services:
1630 if service.ProcessUpdateUIEventBeforeWindows(event):
1631 return True
1632 return False
d1dc2b32
RD
1633
1634
3fa8f722 1635 def ProcessEvent(self, event):
d1dc2b32 1636 """
3fa8f722
RD
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.
d1dc2b32 1641 """
3fa8f722
RD
1642 for service in self._services:
1643 if service.ProcessEvent(event):
1644 return True
1645 return False
d1dc2b32
RD
1646
1647
3fa8f722 1648 def ProcessUpdateUIEvent(self, event):
d1dc2b32 1649 """
3fa8f722
RD
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.
d1dc2b32 1654 """
3fa8f722
RD
1655 for service in self._services:
1656 if service.ProcessUpdateUIEvent(event):
1657 return True
1658 return False
d1dc2b32
RD
1659
1660
3fa8f722 1661 def InstallService(self, service):
d1dc2b32 1662 """
3fa8f722 1663 Installs an instance of a DocService into the DocApp.
d1dc2b32 1664 """
3fa8f722
RD
1665 service.SetDocumentManager(self._docManager)
1666 self._services.append(service)
1667 return service
d1dc2b32 1668
3fa8f722
RD
1669
1670 def GetServices(self):
d1dc2b32 1671 """
3fa8f722 1672 Returns the DocService instances that have been installed into the DocApp.
d1dc2b32 1673 """
3fa8f722 1674 return self._services
d1dc2b32
RD
1675
1676
3fa8f722 1677 def GetService(self, type):
d1dc2b32 1678 """
3fa8f722
RD
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.
d1dc2b32 1682 """
3fa8f722
RD
1683 for service in self._services:
1684 if isinstance(service, type):
1685 return service
1686 return None
d1dc2b32 1687
d1dc2b32 1688
3fa8f722 1689 def OnExit(self):
d1dc2b32 1690 """
3fa8f722
RD
1691 Called when the DocApp is exited, enables the installed DocServices to exit
1692 and saves the DocManager's file history.
d1dc2b32 1693 """
3fa8f722
RD
1694 for service in self._services:
1695 service.OnExit()
d1dc2b32 1696 config = wx.ConfigBase_Get()
3fa8f722
RD
1697 self._docManager.FileHistorySave(config)
1698
1699 if hasattr(self, "_singleInstanceChecker"):
1700 del self._singleInstanceChecker
d1dc2b32 1701
3fa8f722
RD
1702
1703 def GetDefaultDocManagerFlags(self):
d1dc2b32 1704 """
3fa8f722 1705 Returns the default flags to use when creating the DocManager.
d1dc2b32 1706 """
d1dc2b32 1707 config = wx.ConfigBase_Get()
3fa8f722
RD
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)
d1dc2b32 1712 else:
3fa8f722
RD
1713 flags = wx.lib.docview.DOC_SDI | wx.lib.docview.DOC_OPEN_ONCE
1714 return flags
d1dc2b32
RD
1715
1716
3fa8f722 1717 def ShowTip(self, frame, tipProvider):
d1dc2b32 1718 """
3fa8f722
RD
1719 Shows the tip window, generally this is called when an application starts.
1720 A wx.TipProvider must be passed.
d1dc2b32
RD
1721 """
1722 config = wx.ConfigBase_Get()
3fa8f722
RD
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)
d1dc2b32
RD
1729
1730
3fa8f722 1731 def GetEditMenu(self, frame):
d1dc2b32 1732 """
3fa8f722
RD
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)
d1dc2b32
RD
1742
1743
3fa8f722 1744 def GetUseTabbedMDI(self):
d1dc2b32 1745 """
3fa8f722 1746 Returns True if Windows MDI should use folder tabs instead of child windows.
d1dc2b32 1747 """
3fa8f722
RD
1748 return self._useTabbedMDI
1749
d1dc2b32 1750
3fa8f722 1751 def SetUseTabbedMDI(self, useTabbedMDI):
d1dc2b32 1752 """
3fa8f722 1753 Set to True if Windows MDI should use folder tabs instead of child windows.
d1dc2b32 1754 """
3fa8f722 1755 self._useTabbedMDI = useTabbedMDI
d1dc2b32
RD
1756
1757
3fa8f722 1758 def CreateDocumentFrame(self, view, doc, flags, id = -1, title = "", pos = wx.DefaultPosition, size = wx.DefaultSize, style = wx.DEFAULT_FRAME_STYLE):
d1dc2b32 1759 """
3fa8f722
RD
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.
d1dc2b32 1763 """
3fa8f722
RD
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()
d1dc2b32 1768
3fa8f722
RD
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)
d1dc2b32 1775
3fa8f722
RD
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):
d1dc2b32 1797 """
3fa8f722 1798 Creates and returns an SDI Document Frame.
d1dc2b32 1799 """
3fa8f722
RD
1800 frame = DocSDIFrame(doc, view, None, id, title, pos, size, style)
1801 return frame
d1dc2b32
RD
1802
1803
3fa8f722 1804 def CreateTabbedDocumentFrame(self, doc, view, id = -1, title = "", pos = wx.DefaultPosition, size = wx.DefaultSize, style = wx.DEFAULT_FRAME_STYLE):
d1dc2b32 1805 """
3fa8f722 1806 Creates and returns an MDI Document Frame for a Tabbed MDI view
d1dc2b32 1807 """
3fa8f722
RD
1808 frame = DocTabbedChildFrame(doc, view, wx.GetApp().GetTopWindow(), id, title, pos, size, style)
1809 return frame
d1dc2b32
RD
1810
1811
3fa8f722 1812 def CreateMDIDocumentFrame(self, doc, view, id = -1, title = "", pos = wx.DefaultPosition, size = wx.DefaultSize, style = wx.DEFAULT_FRAME_STYLE):
d1dc2b32 1813 """
3fa8f722 1814 Creates and returns an MDI Document Frame.
d1dc2b32 1815 """
3fa8f722
RD
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)
d1dc2b32 1835
3fa8f722
RD
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
d1dc2b32 1841
3fa8f722
RD
1842 return frame
1843
1844
1845 def SaveMDIDocumentFrameMaximizedState(self, maximized):
d1dc2b32 1846 """
3fa8f722
RD
1847 Remember in the config whether the MDI Frame is maximized so that it can be restored
1848 on open.
d1dc2b32 1849 """
3fa8f722
RD
1850 config = wx.ConfigBase_Get()
1851 maximizeFlag = config.ReadInt("MDIChildFrameMaximized", False)
1852 if maximized != maximizeFlag:
1853 config.WriteInt("MDIChildFrameMaximized", maximized)
d1dc2b32
RD
1854
1855
3fa8f722 1856 def OnCloseChildWindow(self, event):
d1dc2b32 1857 """
3fa8f722
RD
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.
d1dc2b32 1860 """
3fa8f722
RD
1861 self.SaveMDIDocumentFrameMaximizedState(event.GetEventObject().IsMaximized())
1862 event.Skip()
d1dc2b32 1863
3fa8f722
RD
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)
d1dc2b32 1874 else:
3fa8f722
RD
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()
d1dc2b32 1882
d1dc2b32 1883
3fa8f722
RD
1884 def GetDefaultIcon(self):
1885 """
1886 Returns the application's default icon.
1887 """
1888 return self._defaultIcon
d1dc2b32 1889
d1dc2b32 1890
3fa8f722
RD
1891 def SetDefaultIcon(self, icon):
1892 """
1893 Sets the application's default icon.
1894 """
1895 self._defaultIcon = icon
d1dc2b32 1896
d1dc2b32 1897
3fa8f722
RD
1898 def GetDebug(self):
1899 """
1900 Returns True if the application is in debug mode.
1901 """
1902 return self._debug
d1dc2b32
RD
1903
1904
3fa8f722 1905 def SetDebug(self, debug):
d1dc2b32 1906 """
3fa8f722 1907 Sets the application's debug mode.
d1dc2b32 1908 """
3fa8f722 1909 self._debug = debug
d1dc2b32
RD
1910
1911
3fa8f722 1912 def GetSingleInstance(self):
d1dc2b32 1913 """
3fa8f722 1914 Returns True if the application is in single instance mode. Used to determine if multiple instances of the application is allowed to launch.
d1dc2b32 1915 """
3fa8f722
RD
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()
d1dc2b32 1949 else:
3fa8f722
RD
1950 if not newDoc.OnOpenDocument(path):
1951 newDoc.DeleteAllViews() # Implicitly deleted by DeleteAllViews
1952 return None
1953 return newDoc
d1dc2b32
RD
1954
1955
3fa8f722 1956 def CloseChildDocuments(self, parentDocument):
d1dc2b32 1957 """
3fa8f722 1958 Closes the child windows of a Document.
d1dc2b32 1959 """
3fa8f722
RD
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
d1dc2b32 1970
3fa8f722
RD
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
d1dc2b32
RD
1977
1978
3fa8f722 1979 def IsSDI(self):
d1dc2b32 1980 """
3fa8f722 1981 Returns True if the application is in SDI mode.
d1dc2b32 1982 """
3fa8f722 1983 return self.GetDocumentManager().GetFlags() & wx.lib.docview.DOC_SDI
d1dc2b32 1984
3fa8f722
RD
1985
1986 def ShowSplash(self, image):
d1dc2b32 1987 """
3fa8f722 1988 Shows a splash window with the given image. Input parameter 'image' can either be a wx.Bitmap or a filename.
d1dc2b32 1989 """
3fa8f722
RD
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()
d1dc2b32 1996
d1dc2b32 1997
3fa8f722
RD
1998 def CloseSplash(self):
1999 """
2000 Closes the splash window.
2001 """
2002 if self._splash:
2003 self._splash.Close(True)
2004
2005
2006class _DocFrameFileDropTarget(wx.FileDropTarget):
2007 """
2008 Class used to handle drops into the document frame.
2009 """
d1dc2b32 2010
3fa8f722
RD
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
d1dc2b32
RD
2018
2019
3fa8f722 2020 def OnDropFiles(self, x, y, filenames):
d1dc2b32 2021 """
3fa8f722
RD
2022 Called when files are dropped in the drop target and tells the docManager to open
2023 the files.
d1dc2b32 2024 """
3fa8f722
RD
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())
d1dc2b32
RD
2036
2037
3fa8f722
RD
2038class 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):
d1dc2b32 2047 """
3fa8f722
RD
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.
d1dc2b32 2060 """
d1dc2b32
RD
2061 wx.LayoutAlgorithm().LayoutMDIFrame(self)
2062 self.GetClientWindow().Refresh()
3fa8f722
RD
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)
d1dc2b32
RD
2077
2078
3fa8f722 2079 def ProcessUpdateUIEvent(self, event):
d1dc2b32 2080 """
3fa8f722
RD
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.
d1dc2b32 2085 """
3fa8f722
RD
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)
d1dc2b32
RD
2094
2095
3fa8f722 2096 def UpdateWindowMenu(self):
d1dc2b32 2097 """
3fa8f722 2098 Updates the WindowMenu on Windows platforms.
d1dc2b32 2099 """
3fa8f722
RD
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
d1dc2b32
RD
2117
2118
3fa8f722 2119 def OnSize(self, event):
d1dc2b32 2120 """
3fa8f722 2121 Called when the DocMDIParentFrame is resized and lays out the MDI client window.
d1dc2b32 2122 """
3fa8f722
RD
2123 # Needed in case there are splitpanels around the mdi frame
2124 self._LayoutFrame()
d1dc2b32
RD
2125
2126
3fa8f722 2127 def OnCloseWindow(self, event):
d1dc2b32 2128 """
3fa8f722 2129 Called when the DocMDIParentFrame is closed. Remembers the frame size.
d1dc2b32 2130 """
3fa8f722 2131 self.SaveEmbeddedWindowSizes()
d1dc2b32 2132
3fa8f722
RD
2133 # save and close services last.
2134 for service in wx.GetApp().GetServices():
2135 if not service.OnCloseFrame(event):
2136 return
d1dc2b32 2137
3fa8f722
RD
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)
d1dc2b32
RD
2142
2143
3fa8f722 2144class DocSDIFrame(wx.lib.docview.DocChildFrame, DocFrameMixIn):
d1dc2b32
RD
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
3fa8f722 2169 menuBar = self.CreateDefaultMenuBar(sdi=True)
d1dc2b32
RD
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
3fa8f722 2180 def _LayoutFrame(self):
d1dc2b32 2181 """
3fa8f722 2182 Lays out the Frame.
d1dc2b32 2183 """
3fa8f722
RD
2184 self.Layout()
2185
d1dc2b32
RD
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
d1dc2b32
RD
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
d1dc2b32
RD
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
74b89458
RD
2298class AboutService(DocService):
2299 """
2300 About Dialog Service that installs under the Help menu to show the properties of the current application.
2301 """
2302
3fa8f722 2303 def __init__(self, aboutDialog=None, image=None):
74b89458
RD
2304 """
2305 Initializes the AboutService.
2306 """
2307 if aboutDialog:
2308 self._dlg = aboutDialog
3fa8f722 2309 self._image = None
74b89458
RD
2310 else:
2311 self._dlg = AboutDialog # use default AboutDialog
3fa8f722 2312 self._image = image
74b89458
RD
2313
2314
2315 def ShowAbout(self):
2316 """
2317 Show the AboutDialog
2318 """
3fa8f722
RD
2319 if self._image:
2320 dlg = self._dlg(wx.GetApp().GetTopWindow(), self._image)
2321 else:
2322 dlg = self._dlg(wx.GetApp().GetTopWindow())
74b89458
RD
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
2335class AboutDialog(wx.Dialog):
2336 """
2337 Opens an AboutDialog. Shared by DocMDIParentFrame and DocSDIFrame.
2338 """
2339
3fa8f722 2340 def __init__(self, parent, image=None):
74b89458
RD
2341 """
2342 Initializes the about dialog.
2343 """
2344 wx.Dialog.__init__(self, parent, -1, _("About ") + wx.GetApp().GetAppName(), style = wx.DEFAULT_DIALOG_STYLE)
2345
74b89458 2346 sizer = wx.BoxSizer(wx.VERTICAL)
3fa8f722
RD
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)
74b89458
RD
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
d1dc2b32
RD
2361class FilePropertiesService(DocService):
2362 """
74b89458 2363 Service that installs under the File menu to show the properties of the file associated
d1dc2b32
RD
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 """
74b89458 2462 chopped = ""
d1dc2b32
RD
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
74b89458 2477 if len(chopped):
d1dc2b32
RD
2478 chopped = chopped + '\n' + text[start:end]
2479 else:
2480 chopped = text[start:end]
2481
2482 start = end
2483
2484 return chopped
2485
2486
2487class 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
74b89458
RD
2504 fileExists = os.path.exists(filename)
2505
d1dc2b32
RD
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)
74b89458
RD
2518 if fileExists:
2519 gridSizer.Add(wx.StaticText(tab, -1, str(os.path.getsize(filename)) + ' ' + _("bytes")), row=2, col=1)
d1dc2b32
RD
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)
74b89458
RD
2526 if fileExists:
2527 gridSizer.Add(wx.StaticText(tab, -1, time.ctime(os.path.getctime(filename))), row=4, col=1)
d1dc2b32
RD
2528
2529 gridSizer.Add(wx.StaticText(tab, -1, _("Modified:")), flag=wx.RIGHT, border=HALF_SPACE, row=5, col=0)
74b89458
RD
2530 if fileExists:
2531 gridSizer.Add(wx.StaticText(tab, -1, time.ctime(os.path.getmtime(filename))), row=5, col=1)
d1dc2b32
RD
2532
2533 gridSizer.Add(wx.StaticText(tab, -1, _("Accessed:")), flag=wx.RIGHT, border=HALF_SPACE, row=6, col=0)
74b89458
RD
2534 if fileExists:
2535 gridSizer.Add(wx.StaticText(tab, -1, time.ctime(os.path.getatime(filename))), row=6, col=1)
d1dc2b32
RD
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"))
d1dc2b32
RD
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
2553class 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
3fa8f722
RD
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
d1dc2b32
RD
2629class 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
2665class 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
3fa8f722
RD
2698 if not _WINDOWS: # Arrange All and window navigation doesn't work on Linux
2699 return
2700
d1dc2b32 2701 windowMenu = wx.Menu()
3fa8f722 2702 item = windowMenu.Append(self.ARRANGE_WINDOWS_ID, _("&Arrange All"), _("Arrange the open windows"))
d1dc2b32
RD
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#----------------------------------------------------------------------------
2894from wx import ImageFromStream, BitmapFromImage
2895import cStringIO
2896
2897#----------------------------------------------------------------------
2898def 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
2908def getNewBitmap():
2909 return BitmapFromImage(getNewImage())
2910
2911def getNewImage():
2912 stream = cStringIO.StringIO(getNewData())
2913 return ImageFromStream(stream)
2914
2915#----------------------------------------------------------------------
2916def 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
2928def getOpenBitmap():
2929 return BitmapFromImage(getOpenImage())
2930
2931def getOpenImage():
2932 stream = cStringIO.StringIO(getOpenData())
2933 return ImageFromStream(stream)
2934
2935#----------------------------------------------------------------------
2936def 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
2948def getCopyBitmap():
2949 return BitmapFromImage(getCopyImage())
2950
2951def getCopyImage():
2952 stream = cStringIO.StringIO(getCopyData())
2953 return ImageFromStream(stream)
2954
2955#----------------------------------------------------------------------
2956def 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
2968def getPasteBitmap():
2969 return BitmapFromImage(getPasteImage())
2970
2971def getPasteImage():
2972 stream = cStringIO.StringIO(getPasteData())
2973 return ImageFromStream(stream)
2974
2975#----------------------------------------------------------------------
2976def 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\
2981mX\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
2986def getSaveBitmap():
2987 return BitmapFromImage(getSaveImage())
2988
2989def getSaveImage():
2990 stream = cStringIO.StringIO(getSaveData())
2991 return ImageFromStream(stream)
2992
2993#----------------------------------------------------------------------
2994def 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!\
30008R\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
3010def getSaveAllBitmap():
3011 return BitmapFromImage(getSaveAllImage())
3012
3013def getSaveAllImage():
3014 stream = cStringIO.StringIO(getSaveAllData())
3015 return ImageFromStream(stream)
3016
3017#----------------------------------------------------------------------
3018def 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
3031def getPrintBitmap():
3032 return BitmapFromImage(getPrintImage())
3033
3034def getPrintImage():
3035 stream = cStringIO.StringIO(getPrintData())
3036 return ImageFromStream(stream)
3037
3038#----------------------------------------------------------------------
3039def 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\
3048d\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\
3050O\x00\x00\x00\x00IEND\xaeB`\x82'
3051
3052def getPrintPreviewBitmap():
3053 return BitmapFromImage(getPrintPreviewImage())
3054
3055def getPrintPreviewImage():
3056 stream = cStringIO.StringIO(getPrintPreviewData())
3057 return ImageFromStream(stream)
3058
3059#----------------------------------------------------------------------
3060def 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
3070def getCutBitmap():
3071 return BitmapFromImage(getCutImage())
3072
3073def getCutImage():
3074 stream = cStringIO.StringIO(getCutData())
3075 return ImageFromStream(stream)
3076
3077#----------------------------------------------------------------------
3078def 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\
3086k<@\x12\xec\xff\x95\xe7\x01\x07L\x0e(\xe5\xa4\xff\x1c\x88\x00\x00\x00\x00IEN\
3087D\xaeB`\x82"
3088
3089def getUndoBitmap():
3090 return BitmapFromImage(getUndoImage())
3091
3092def getUndoImage():
3093 stream = cStringIO.StringIO(getUndoData())
3094 return ImageFromStream(stream)
3095
3096#----------------------------------------------------------------------
3097def 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\\\
3103gp\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
3108def getRedoBitmap():
3109 return BitmapFromImage(getRedoImage())
3110
3111def getRedoImage():
3112 stream = cStringIO.StringIO(getRedoData())
3113 return ImageFromStream(stream)
3fa8f722
RD
3114
3115#----------------------------------------------------------------------------
3116
3117def getBlankData():
3118 return \
bbf7159c
RD
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\
31239\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'
3fa8f722
RD
3126
3127
3128def getBlankBitmap():
3129 return BitmapFromImage(getBlankImage())
3130
3131def getBlankImage():
3132 stream = cStringIO.StringIO(getBlankData())
3133 return ImageFromStream(stream)
3134
3135def getBlankIcon():
bbf7159c 3136 return wx.IconFromBitmap(getBlankBitmap())
3fa8f722
RD
3137
3138