Exemplo n.º 1
0
 def _createMenuBar(self):
     # FIXME (EPW) this should be supplied by the perspective
     menuContext = ZMenuActionContext(self)
     menuBarModel = ZBlogAppMainMenuBarModel(self.perspectives)
     provider = ZModelBasedMenuContentProvider(menuBarModel, menuContext)
     eventHandler = ZModelBasedMenuEventHandler(menuBarModel, menuContext)
     self.menuBar = ZMenuBar(self, provider, eventHandler)
     self.SetMenuBar(self.menuBar)
Exemplo n.º 2
0
 def _updateMenuBar(self, editor):
     menuBarModel = editor.getMenuBarModel()
     menuContext = editor.getMenuActionContext()
     contentProvider = ZModelBasedMenuContentProvider(menuBarModel, menuContext)
     eventHandler = ZModelBasedMenuEventHandler(menuBarModel, menuContext)
     if self.menuBar is None:
         self.menuBar = ZMenuBar(self, contentProvider, eventHandler)
         self.SetMenuBar(self.menuBar)
         self.Layout()
     else:
         self.menuBar.setContentProvider(contentProvider, eventHandler)
Exemplo n.º 3
0
 def _createMenuBar(self):
     # FIXME (EPW) this should be supplied by the perspective
     menuContext = ZMenuActionContext(self)
     menuBarModel = ZBlogAppMainMenuBarModel(self.perspectives)
     provider = ZModelBasedMenuContentProvider(menuBarModel, menuContext)
     eventHandler = ZModelBasedMenuEventHandler(menuBarModel, menuContext)
     self.menuBar = ZMenuBar(self, provider, eventHandler)
     self.SetMenuBar(self.menuBar)
Exemplo n.º 4
0
class _ZEditorWindow(IZEditorWindow, ZBaseWindow, IZTabContainerListener, ZPersistentDialogMixin):

    def __init__(self):
        self.editorFactory = ZEditorFactory()
        self.menuBar = None
        self.toolBar = None
        self.statusBar = None
        self.editors = []
        self.tabToEditorMap = {}
        self.parent = None

        ZBaseWindow.__init__(self, self.parent, u"", name = u"ZEditorWindow", size = wx.Size(640, 550)) #$NON-NLS-2$ #$NON-NLS-1$
        ZPersistentDialogMixin.__init__(self, IZBlogAppUserPrefsKeys.EDITOR_WINDOW, False)

        self.Layout()
    # end __init__()

    def _createWindowWidgets(self, parent):
        self.toolBarParent = parent
        self.toolBar = ZPersistentToolBar(IZBlogAppUserPrefsKeys.EDITOR_WINDOW_TOOLBAR, None, None, parent, ZToolBar.STYLE_SHOW_TEXT)
        self.tbStaticLine = wx.StaticLine(parent)
        self.tabContainer = ZTabContainer(parent)
        self.tabContainer.setListener(self)
    # end _createWindowWidgets()

    def _populateWindowWidgets(self):
        self.SetIcons(getResourceRegistry().getIconBundle(ICON_IMAGES))
    # end _populateWindowWidgets()

    def _layoutWindowWidgets(self):
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.toolBar, 0, wx.EXPAND)
        sizer.Add(self.tbStaticLine, 0, wx.EXPAND)
        sizer.Add(self.tabContainer, 1, wx.EXPAND | wx.TOP, 5)
        return sizer
    # end _layoutWindowWidgets()

    def _bindWidgetEvents(self):
        self.Bind(wx.EVT_CLOSE, self.onClose, self)
        self.Bind(ZEVT_TOOLBAR_RESIZE, self.onToolBarResize, self.toolBar)

        self.Bind(ZEVT_EDITOR_CLOSE, self.onEditorClose)
        self.Bind(ZEVT_EDITOR_TITLE_CHANGED, self.onEditorTitleChanged)
        self.Bind(ZEVT_EDITOR_DIRTY, self.onEditorDirty)
        self.Bind(ZEVT_EDITOR_STATUS_BAR_CHANGED, self.onEditorStatusBarChanged)
        self.Bind(ZEVT_EDITOR_MENU_BAR_CHANGED, self.onEditorMenuBarChanged)
        self.Bind(ZEVT_EDITOR_TOOL_BAR_CHANGED, self.onEditorToolBarChanged)
    # end _bindWidgetEvents()

    def openDocument(self, document):
        editor = self.findEditor(document.getId())
        # If not already editing this document, create a new one.
        if editor is None:
            editor = self.editorFactory.createEditor(self.tabContainer, document)
            self._addEditor(editor)
            tabId = self.tabContainer.addTab(ZTabInfo(document.getTitle(), editor.getBitmap()), editor)
            self.tabToEditorMap[tabId] = editor

        # Bring the given editor into focus.
        self._focusOnEditor(editor)
        self.Raise()
        return editor
    # end openDocument()

    def findEditor(self, documentId):
        if documentId is None:
            return None
        for editor in self.editors:
            if editor.getDocumentId() == documentId:
                return editor
        return None
    # end findEditor()

    def closeEditor(self, editor):
        tabId = self._findTabIdForEditor(editor)
        self.tabContainer.removeTab(tabId)
        del self.tabToEditorMap[tabId]
        editor.destroy()
        self.editors.remove(editor)

        if len(self.editors) == 0:
            self.Close()
    # end closeEditor()

    def _addEditor(self, editor):
        self.editors.append(editor)
    # end _addEditor()

    def _focusOnEditor(self, editor):
        tabId = self._findTabIdForEditor(editor)
        if tabId is not None:
            self.tabContainer.selectTab(tabId)
            self.tabContainer.SetFocus()
    # end _focusOnEditor()

    def _findTabIdForEditor(self, editor):
        for (tabId, teditor) in self.tabToEditorMap.items():
            if editor == teditor:
                return tabId
        return None
    # end _findTabIdForEditor()

    def _findEditorByTabId(self, tabId):
        if tabId in self.tabToEditorMap:
            return self.tabToEditorMap[tabId]
        return None
    # end _findEditorByTabId()

    def _getSelectedEditor(self):
        tabId = self.tabContainer.getSelectedTabId()
        return self._findEditorByTabId(tabId)
    # end _getSelectedEditor()

    def getEditors(self):
        return self.editors
    # end getEditors()

    def close(self):
        u"""close() -> boolean
        Called to close the window.  Returns True if the 
        close succeeded, False otherwise.""" #$NON-NLS-1$
        for editor in self.editors:
            if editor.isDirty():
                rval = ZShowYesNoCancelMessage(self, _extstr(u"editorwin.SaveDocumentMessage") % editor.getTitle(), _extstr(u"editorwin.SaveDocument")) #$NON-NLS-2$ #$NON-NLS-1$
                if rval == wx.ID_CANCEL:
                    return False
                elif rval == wx.ID_YES:
                    editor.save()
                elif rval == wx.ID_NO:
                    pass
        for editor in self.editors:
            editor.destroy()
        self.editors = []
        return True
    # end close()

    def onEditorTitleChanged(self, event):
        selEditor = self._getSelectedEditor()
        editor = event.getEditor()
        if selEditor == editor:
            title = self._getEditorTitle(editor)
            self.SetTitle(title)
            tabId = self._findTabIdForEditor(editor)
            self.tabContainer.setTabName(tabId, title)
        event.Skip()
    # end onEditorTitleChanged()

    def onEditorClose(self, event):
        if self.onEditorClosing(event.getEditor()):
            self.closeEditor(event.getEditor())
        event.Skip()
    # end onEditorClose()

    def onEditorDirty(self, event):
        selEditor = self._getSelectedEditor()
        editor = event.getEditor()
        if selEditor == editor:
            title = self._getEditorTitle(editor)
            self.SetTitle(title)
            tabId = self._findTabIdForEditor(editor)
            self.tabContainer.setTabName(tabId, title)
        event.Skip()
    # end onEditorDirty()

    def onEditorStatusBarChanged(self, event):
        selEditor = self._getSelectedEditor()
        editor = event.getEditor()
        if selEditor == editor:
            self.statusBar.refresh()
        event.Skip()
    # end onEditorStatusBarChanged()

    def onEditorMenuBarChanged(self, event):
        selEditor = self._getSelectedEditor()
        editor = event.getEditor()
        if selEditor == editor:
            self.menuBar.refresh()
        event.Skip()
    # end onEditorMenuBarChanged()

    def onEditorToolBarChanged(self, event):
        selEditor = self._getSelectedEditor()
        editor = event.getEditor()
        if selEditor == editor:
            self.toolBar.refresh()
        event.Skip()
    # end onEditorToolBarChanged()

    def onEditorClosing(self, editor):
        u"""Returns True or False based on dirty status of editor
        and user input.  Returns False if the close should be veto'd.""" #$NON-NLS-1$
        if editor.isDirty():
            rval = ZShowYesNoCancelMessage(self, _extstr(u"editorwin.SaveDocumentMessage") % editor.getTitle(), _extstr(u"editorwin.SaveDocument")) #$NON-NLS-2$ #$NON-NLS-1$
            if rval == wx.ID_CANCEL:
                return False
            elif rval == wx.ID_YES:
                editor.save()
            elif rval == wx.ID_NO:
                pass
        return True
    # end onEditorClosing()

    def onToolBarResize(self, event):
        self.toolBarParent.Layout()
        event.Skip()
    # end onToolBarResize()

    def onClose(self, event):
        if self.close():
            global EDITOR_WINDOW
            EDITOR_WINDOW = None
            event.Skip()
        else:
            event.Veto()
    # end onClose()

    def onTabClosing(self, tabId):
        u"""Should return True to prevent the tab from being closed.""" #$NON-NLS-1$
        editor = self._findEditorByTabId(tabId)
        cancelClose = not self.onEditorClosing(editor)
        if not cancelClose:
            editor.destroy()
        return cancelClose
    # end onTabClosing()

    def onTabClosed(self, tabId):
        editor = self._findEditorByTabId(tabId)
        if editor is not None:
            del self.tabToEditorMap[tabId]
            self.editors.remove(editor)

        if len(self.editors) == 0:
            self.Close()
    # end onTabClosed()

    def onTabSelectionChanged(self, fromTabId, toTabId): #@UnusedVariable
        editor = self._findEditorByTabId(toTabId)
        if editor is not None:
            self.SetTitle(self._getEditorTitle(editor))
            self._updateMenuBar(editor)
            self._updateToolBar(editor)
            self._updateStatusBar(editor)
    # end onTabSelectionChanged()

    def _updateMenuBar(self, editor):
        menuBarModel = editor.getMenuBarModel()
        menuContext = editor.getMenuActionContext()
        contentProvider = ZModelBasedMenuContentProvider(menuBarModel, menuContext)
        eventHandler = ZModelBasedMenuEventHandler(menuBarModel, menuContext)
        if self.menuBar is None:
            self.menuBar = ZMenuBar(self, contentProvider, eventHandler)
            self.SetMenuBar(self.menuBar)
            self.Layout()
        else:
            self.menuBar.setContentProvider(contentProvider, eventHandler)
    # end _updateMenuBar()

    def _updateToolBar(self, editor):
        toolBarModel = editor.getToolBarModel()
        toolContext = editor.getToolBarActionContext()
        contentProvider = ZModelBasedToolBarContentProvider(toolBarModel, toolContext)
        eventHandler = ZModelBasedToolBarEventHandler(toolBarModel, toolContext)
        self.toolBar.setContentProvider(contentProvider, eventHandler)
        self.Layout()
    # end _updateToolBar()

    def _updateStatusBar(self, editor):
        statusBarModel = editor.getStatusBarModel()
        provider = ZStatusBarModelBasedContentProvider(statusBarModel)
        if self.statusBar is None:
            self.statusBar = ZStatusBar(self, provider)
            self.SetStatusBar(self.statusBar)
            self.Layout()
        else:
            self.statusBar.setContentProvider(provider)
            self.statusBar.refresh()
    # end _updateStatusBar()
    
    def _getEditorTitle(self, editor):
        title = editor.getTitle()
        if not title:
            title = u"(%s)" % _extstr(u"editorwin.No_Title") #$NON-NLS-1$ #$NON-NLS-2$
        if editor.isDirty():
            title = u"* " + title #$NON-NLS-1$
        return title
Exemplo n.º 5
0
class ZRavenApplicationWindow(ZBaseWindow, IZSingletonServiceListener):

    def __init__(self):
        self.perspectives = self._loadPerspectives()
        self.perspectiveId = self._getStartupPerspective()
        self.perspective = self._createPerspective(self.perspectiveId)
        self.startupActions = self._loadStartupActions()
        self.shutdownActions = self._loadShutdownActions()
        self.iconBundle = getResourceRegistry().getIconBundle(ICON_IMAGES)
        self.trayIconPrefs = ZRavenTrayIconPrefsAccessor()
        self.trayIcon = None

        size = self._getWindowSize()
        pos = self._getWindowPos()
        ZBaseWindow.__init__(self, None, u"Zoundry Raven", size = size, pos = pos) #$NON-NLS-1$

        userPrefs = getApplicationModel().getUserProfile().getPreferences()
        isMax = userPrefs.getUserPreferenceBool(IZBlogAppUserPrefsKeys.APPWIN_MAXIMIZED, False)
        if isMax:
            self.Maximize()

        self.SetIcons(self.iconBundle)
        self.Show(True)

        self._createTrayIcon()
        if self.trayIconPrefs.isAlwaysShowTrayIcon():
            self._showTrayIcon()

        self._registerAsSingletonListener()
        self._doCmdLineBlogThis()

        fireUIExecEvent(ZStartupActionRunner(self), self)
    # end __init__()

    def _registerAsSingletonListener(self):
        service = getApplicationModel().getService(IZBlogAppServiceIDs.SINGLETON_SERVICE_ID)
        service.addListener(self)
    # end _registerAsSingletonListener()

    def _doCmdLineBlogThis(self):
        blogThisInfo = checkCmdLineForBlogThis()
        if blogThisInfo is not None:
            self.onBlogThis(blogThisInfo)
    # end _doCmdLineBlogThis()

    def _loadStartupActions(self):
        pluginReg = getApplicationModel().getPluginRegistry()
        extensions = pluginReg.getExtensions(IZBlogAppExtensionPoints.ZEP_STARTUP_ACTION)
        return map(ZExtensionPointBaseDef, extensions)
    # end _loadStartupActions()

    def _loadShutdownActions(self):
        pluginReg = getApplicationModel().getPluginRegistry()
        extensions = pluginReg.getExtensions(IZBlogAppExtensionPoints.ZEP_SHUTDOWN_ACTION)
        return map(ZExtensionPointBaseDef, extensions)
    # end _loadShutdownActions()

    def _loadPerspectives(self):
        pluginReg = getApplicationModel().getPluginRegistry()
        extensions = pluginReg.getExtensions(IZBlogAppExtensionPoints.ZEP_ZOUNDRY_PERSPECTIVE)
        return map(ZPerspectiveDef, extensions)
    # end _loadPerspectives()

    def _createTrayIcon(self):
        self.trayIcon = ZRavenTrayIcon(self)
    # end _createTrayIcon()

    def _showTrayIcon(self):
        if not self.trayIcon.IsIconInstalled():
            self.trayIcon.SetIcon(self.iconBundle.GetIcon(wx.Size(16, 16)), _extstr(u"ZoundryRaven")) #$NON-NLS-1$
    # end _showTrayIcon()

    def _hideTrayIcon(self):
        if self.trayIcon.IsIconInstalled():
            self.trayIcon.RemoveIcon()
    # end _hideTrayIcon()

    def _destroyTrayIcon(self):
        self.trayIcon.Destroy()
        del self.trayIcon
    # end _destroyTrayIcon()

    # Gets the perspective def for the given ID.
    def _getPerspectiveDef(self, perspectiveId):
        for pdef in self.perspectives:
            if pdef.getId() == perspectiveId:
                return pdef
        return None
    # end _getPerspectiveDef()

    def _getStartupPerspective(self):
        userPrefs = getApplicationModel().getUserProfile().getPreferences()
        return userPrefs.getUserPreference(IZBlogAppUserPrefsKeys.APPWIN_DEFAULT_PERSPECTIVE, PERSPECTIVE_DEFAULT)
    # end _getStartupPerspective()

    def _createPerspective(self, perspectiveId):
        pdef = self._getPerspectiveDef(perspectiveId)
        if not pdef:
            pdef = self._getPerspectiveDef(PERSPECTIVE_DEFAULT)
        if not pdef:
            raise ZBlogAppException(_extstr(u"appwindow.FailedToLoadDefaultPerspective")) #$NON-NLS-1$
        pclass = pdef.getClass()
        perspective = pclass()
        return perspective
    # end _createPerspective()

    def _getWindowSize(self):
        userPrefs = getApplicationModel().getUserProfile().getPreferences()
        width = userPrefs.getUserPreferenceInt(IZBlogAppUserPrefsKeys.APPWIN_WIDTH, 800)
        height = userPrefs.getUserPreferenceInt(IZBlogAppUserPrefsKeys.APPWIN_HEIGHT, 600)

        if width < 100:
            width = 800
        if height < 100:
            width = 600

        return wx.Size(width, height)
    # end _getWindowSize()

    def _getWindowPos(self):
        userPrefs = getApplicationModel().getUserProfile().getPreferences()
        posX = userPrefs.getUserPreferenceInt(IZBlogAppUserPrefsKeys.APPWIN_X, -1)
        posY = userPrefs.getUserPreferenceInt(IZBlogAppUserPrefsKeys.APPWIN_Y, -1)

        if posX < 0:
            posX = -1
        if posY < 0:
            posY = -1
        displaySize = wx.GetDisplaySize()
        if posX >= displaySize.GetWidth() - 50:
            posX = -1
        if posY >= displaySize.GetHeight() - 50:
            posY = -1

        if posX != -1 and posY != -1:
            return wx.Point(posX, posY)
        return wx.DefaultPosition
    # end _getWindowPos()

    def _createWidgets(self):
        self._createMenuBar()
        self._createStatusBar()
        self._createPerspectiveUI()
        self._createAcceleratorTable()
    # end _createWidgets()

    def _createMenuBar(self):
        # FIXME (EPW) this should be supplied by the perspective
        menuContext = ZMenuActionContext(self)
        menuBarModel = ZBlogAppMainMenuBarModel(self.perspectives)
        provider = ZModelBasedMenuContentProvider(menuBarModel, menuContext)
        eventHandler = ZModelBasedMenuEventHandler(menuBarModel, menuContext)
        self.menuBar = ZMenuBar(self, provider, eventHandler)
        self.SetMenuBar(self.menuBar)
    # end _createMenuBar()

    def _createStatusBar(self):
        # FIXME (EPW) this should be supplied by the perspective
        self.statusBar = self.CreateStatusBar()
#        self.statusBar = ZRavenApplicationStatusBar(self)
        self.SetStatusBar(self.statusBar)
    # end _createStatusBar()

    def _createPerspectiveUI(self):
        self.panel = self.perspective.createUIPanel(self)
    # end _createPerspectiveUI()

    def _createAcceleratorTable(self):
        self.acceleratorTable = ZRavenAppWindowAcceleratorTable()
        self.SetAcceleratorTable(self.acceleratorTable)
    # end _createAcceleratorTable()

    def _bindWidgetEvents(self):
        self.Bind(wx.EVT_CLOSE, self.onClose)
        self.Bind(wx.EVT_ICONIZE, self.onIconize)
        self.acceleratorTable.bindTo(self)
    # end _bindWidgetEvents()

    def getCurrentPerspectiveId(self):
        return self.perspectiveId
    # end getCurrentPerspectiveId()

    def onPerspectiveSwitch(self, perspectiveId):
        self.perspective.destroy()
        self.DestroyChildren()
        self.perspective = self._createPerspective(perspectiveId)
        self._createPerspectiveUI()
        self.perspectiveId = perspectiveId

        self._layoutWidgets()

        userPrefs = getApplicationModel().getUserProfile().getPreferences()
        userPrefs.setUserPreference(IZBlogAppUserPrefsKeys.APPWIN_DEFAULT_PERSPECTIVE, perspectiveId)

        self.menuBar.refresh()
    # end onPerspectiveSwitch()

    def onIconize(self, event):
        if event.Iconized():
            if self.trayIconPrefs.isHideWhenMinimized():
                self._showTrayIcon()
                self.Show(False)
        else:
            self.Show(True)
        event.Skip()
    # end onIconize()

    def restoreFromMinimize(self):
        self.Show(True)
        self.Iconize(False)
        if not self.trayIconPrefs.isAlwaysShowTrayIcon():
            self._hideTrayIcon()
    # end restoreFromMinimize()

    def onClose(self, event):
        # Run all of the shutdown actions - if they all succeed, then exit.
        try:
            if self._runShutdownActions():
                self.perspective.destroy()
                self._destroyTrayIcon()
                event.Skip()
            else:
                event.Veto()
        except Exception, e:
            ZShowExceptionMessage(self, e)
            event.Skip()
Exemplo n.º 6
0
class ZRavenApplicationWindow(ZBaseWindow, IZSingletonServiceListener):
    def __init__(self):
        self.perspectives = self._loadPerspectives()
        self.perspectiveId = self._getStartupPerspective()
        self.perspective = self._createPerspective(self.perspectiveId)
        self.startupActions = self._loadStartupActions()
        self.shutdownActions = self._loadShutdownActions()
        self.iconBundle = getResourceRegistry().getIconBundle(ICON_IMAGES)
        self.trayIconPrefs = ZRavenTrayIconPrefsAccessor()
        self.trayIcon = None

        size = self._getWindowSize()
        pos = self._getWindowPos()
        ZBaseWindow.__init__(self, None, u"Zoundry Raven", size=size,
                             pos=pos)  #$NON-NLS-1$

        userPrefs = getApplicationModel().getUserProfile().getPreferences()
        isMax = userPrefs.getUserPreferenceBool(
            IZBlogAppUserPrefsKeys.APPWIN_MAXIMIZED, False)
        if isMax:
            self.Maximize()

        self.SetIcons(self.iconBundle)
        self.Show(True)

        self._createTrayIcon()
        if self.trayIconPrefs.isAlwaysShowTrayIcon():
            self._showTrayIcon()

        self._registerAsSingletonListener()
        self._doCmdLineBlogThis()

        fireUIExecEvent(ZStartupActionRunner(self), self)

    # end __init__()

    def _registerAsSingletonListener(self):
        service = getApplicationModel().getService(
            IZBlogAppServiceIDs.SINGLETON_SERVICE_ID)
        service.addListener(self)

    # end _registerAsSingletonListener()

    def _doCmdLineBlogThis(self):
        blogThisInfo = checkCmdLineForBlogThis()
        if blogThisInfo is not None:
            self.onBlogThis(blogThisInfo)

    # end _doCmdLineBlogThis()

    def _loadStartupActions(self):
        pluginReg = getApplicationModel().getPluginRegistry()
        extensions = pluginReg.getExtensions(
            IZBlogAppExtensionPoints.ZEP_STARTUP_ACTION)
        return map(ZExtensionPointBaseDef, extensions)

    # end _loadStartupActions()

    def _loadShutdownActions(self):
        pluginReg = getApplicationModel().getPluginRegistry()
        extensions = pluginReg.getExtensions(
            IZBlogAppExtensionPoints.ZEP_SHUTDOWN_ACTION)
        return map(ZExtensionPointBaseDef, extensions)

    # end _loadShutdownActions()

    def _loadPerspectives(self):
        pluginReg = getApplicationModel().getPluginRegistry()
        extensions = pluginReg.getExtensions(
            IZBlogAppExtensionPoints.ZEP_ZOUNDRY_PERSPECTIVE)
        return map(ZPerspectiveDef, extensions)

    # end _loadPerspectives()

    def _createTrayIcon(self):
        self.trayIcon = ZRavenTrayIcon(self)

    # end _createTrayIcon()

    def _showTrayIcon(self):
        if not self.trayIcon.IsIconInstalled():
            self.trayIcon.SetIcon(self.iconBundle.GetIcon(wx.Size(16, 16)),
                                  _extstr(u"ZoundryRaven"))  #$NON-NLS-1$

    # end _showTrayIcon()

    def _hideTrayIcon(self):
        if self.trayIcon.IsIconInstalled():
            self.trayIcon.RemoveIcon()

    # end _hideTrayIcon()

    def _destroyTrayIcon(self):
        self.trayIcon.Destroy()
        del self.trayIcon

    # end _destroyTrayIcon()

    # Gets the perspective def for the given ID.
    def _getPerspectiveDef(self, perspectiveId):
        for pdef in self.perspectives:
            if pdef.getId() == perspectiveId:
                return pdef
        return None

    # end _getPerspectiveDef()

    def _getStartupPerspective(self):
        userPrefs = getApplicationModel().getUserProfile().getPreferences()
        return userPrefs.getUserPreference(
            IZBlogAppUserPrefsKeys.APPWIN_DEFAULT_PERSPECTIVE,
            PERSPECTIVE_DEFAULT)

    # end _getStartupPerspective()

    def _createPerspective(self, perspectiveId):
        pdef = self._getPerspectiveDef(perspectiveId)
        if not pdef:
            pdef = self._getPerspectiveDef(PERSPECTIVE_DEFAULT)
        if not pdef:
            raise ZBlogAppException(
                _extstr(
                    u"appwindow.FailedToLoadDefaultPerspective"))  #$NON-NLS-1$
        pclass = pdef.getClass()
        perspective = pclass()
        return perspective

    # end _createPerspective()

    def _getWindowSize(self):
        userPrefs = getApplicationModel().getUserProfile().getPreferences()
        width = userPrefs.getUserPreferenceInt(
            IZBlogAppUserPrefsKeys.APPWIN_WIDTH, 800)
        height = userPrefs.getUserPreferenceInt(
            IZBlogAppUserPrefsKeys.APPWIN_HEIGHT, 600)

        if width < 100:
            width = 800
        if height < 100:
            width = 600

        return wx.Size(width, height)

    # end _getWindowSize()

    def _getWindowPos(self):
        userPrefs = getApplicationModel().getUserProfile().getPreferences()
        posX = userPrefs.getUserPreferenceInt(IZBlogAppUserPrefsKeys.APPWIN_X,
                                              -1)
        posY = userPrefs.getUserPreferenceInt(IZBlogAppUserPrefsKeys.APPWIN_Y,
                                              -1)

        if posX < 0:
            posX = -1
        if posY < 0:
            posY = -1
        displaySize = wx.GetDisplaySize()
        if posX >= displaySize.GetWidth() - 50:
            posX = -1
        if posY >= displaySize.GetHeight() - 50:
            posY = -1

        if posX != -1 and posY != -1:
            return wx.Point(posX, posY)
        return wx.DefaultPosition

    # end _getWindowPos()

    def _createWidgets(self):
        self._createMenuBar()
        self._createStatusBar()
        self._createPerspectiveUI()
        self._createAcceleratorTable()

    # end _createWidgets()

    def _createMenuBar(self):
        # FIXME (EPW) this should be supplied by the perspective
        menuContext = ZMenuActionContext(self)
        menuBarModel = ZBlogAppMainMenuBarModel(self.perspectives)
        provider = ZModelBasedMenuContentProvider(menuBarModel, menuContext)
        eventHandler = ZModelBasedMenuEventHandler(menuBarModel, menuContext)
        self.menuBar = ZMenuBar(self, provider, eventHandler)
        self.SetMenuBar(self.menuBar)

    # end _createMenuBar()

    def _createStatusBar(self):
        # FIXME (EPW) this should be supplied by the perspective
        self.statusBar = self.CreateStatusBar()
        #        self.statusBar = ZRavenApplicationStatusBar(self)
        self.SetStatusBar(self.statusBar)

    # end _createStatusBar()

    def _createPerspectiveUI(self):
        self.panel = self.perspective.createUIPanel(self)

    # end _createPerspectiveUI()

    def _createAcceleratorTable(self):
        self.acceleratorTable = ZRavenAppWindowAcceleratorTable()
        self.SetAcceleratorTable(self.acceleratorTable)

    # end _createAcceleratorTable()

    def _bindWidgetEvents(self):
        self.Bind(wx.EVT_CLOSE, self.onClose)
        self.Bind(wx.EVT_ICONIZE, self.onIconize)
        self.acceleratorTable.bindTo(self)

    # end _bindWidgetEvents()

    def getCurrentPerspectiveId(self):
        return self.perspectiveId

    # end getCurrentPerspectiveId()

    def onPerspectiveSwitch(self, perspectiveId):
        self.perspective.destroy()
        self.DestroyChildren()
        self.perspective = self._createPerspective(perspectiveId)
        self._createPerspectiveUI()
        self.perspectiveId = perspectiveId

        self._layoutWidgets()

        userPrefs = getApplicationModel().getUserProfile().getPreferences()
        userPrefs.setUserPreference(
            IZBlogAppUserPrefsKeys.APPWIN_DEFAULT_PERSPECTIVE, perspectiveId)

        self.menuBar.refresh()

    # end onPerspectiveSwitch()

    def onIconize(self, event):
        if event.Iconized():
            if self.trayIconPrefs.isHideWhenMinimized():
                self._showTrayIcon()
                self.Show(False)
        else:
            self.Show(True)
        event.Skip()

    # end onIconize()

    def restoreFromMinimize(self):
        self.Show(True)
        self.Iconize(False)
        if not self.trayIconPrefs.isAlwaysShowTrayIcon():
            self._hideTrayIcon()

    # end restoreFromMinimize()

    def onClose(self, event):
        # Run all of the shutdown actions - if they all succeed, then exit.
        try:
            if self._runShutdownActions():
                self.perspective.destroy()
                self._destroyTrayIcon()
                event.Skip()
            else:
                event.Veto()
        except Exception, e:
            ZShowExceptionMessage(self, e)
            event.Skip()