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