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