Esempio n. 1
0
 def _createContentWidgets(self, parent):
     self.treeImageList = self._createTreeImageList()
     self.treeProvider = ZTreeNodeBasedContentProvider(
         self.model.getNavigatorTreeRoot(), self.treeImageList)
     treeStyle = wx.NO_BORDER | wx.TR_HIDE_ROOT | wx.TR_LINES_AT_ROOT | wx.TR_SINGLE | wx.TR_HAS_BUTTONS
     self.treeView = ZTreeView(self.treeProvider, parent, style=treeStyle)
     dropTarget = ZNavigatorViewDropTarget(self.treeView, self)
     self.treeView.SetDropTarget(dropTarget)
Esempio n. 2
0
 def _createContentWidgets(self, parent):
     self.treeImageList = self._createTreeImageList()
     self.treeProvider = ZTreeNodeBasedContentProvider(self.model.getNavigatorTreeRoot(), self.treeImageList)
     treeStyle = wx.NO_BORDER | wx.TR_HIDE_ROOT | wx.TR_LINES_AT_ROOT | wx.TR_SINGLE | wx.TR_HAS_BUTTONS
     self.treeView = ZTreeView(self.treeProvider, parent, style = treeStyle)
     dropTarget = ZNavigatorViewDropTarget(self.treeView, self)
     self.treeView.SetDropTarget(dropTarget)
Esempio n. 3
0
    def _createLeftTreePanel(self):
        panel = ZTransparentPanel(self.splitterWindow,
                                  wx.ID_ANY,
                                  style=wx.NO_BORDER)

        # Create the prefs tree view.
        provider = self._createTreeProvider()
        treeStyle = wx.NO_BORDER | wx.TR_HIDE_ROOT | wx.TR_LINES_AT_ROOT | wx.TR_SINGLE | wx.TR_HAS_BUTTONS
        self.prefsTreeView = ZTreeView(provider, panel, style=treeStyle)
        self.prefsTreeView.refresh()

        self.treeButtons = self._createTreeButtons(panel)

        # Create a little static vertical line (aesthetic only)
        self.middleStaticLine = wx.StaticLine(panel, style=wx.LI_VERTICAL)

        return panel
Esempio n. 4
0
    def _createLeftTreePanel(self):
        panel = ZTransparentPanel(self.splitterWindow, wx.ID_ANY, style = wx.NO_BORDER)

        # Create the prefs tree view.
        provider = self._createTreeProvider()
        treeStyle = wx.NO_BORDER | wx.TR_HIDE_ROOT | wx.TR_LINES_AT_ROOT | wx.TR_SINGLE | wx.TR_HAS_BUTTONS
        self.prefsTreeView = ZTreeView(provider, panel, style = treeStyle)
        self.prefsTreeView.refresh()
        
        self.treeButtons = self._createTreeButtons(panel)

        # Create a little static vertical line (aesthetic only)
        self.middleStaticLine = wx.StaticLine(panel, style = wx.LI_VERTICAL)

        return panel
Esempio n. 5
0
class ZNavigatorView(ZBoxedView, IZAccountStoreListener, IZDocumentIndexListener):

    def __init__(self, parent):
        self.indexEventQueue = Queue()
        self.accountEventQueue = Queue()
        self.model = None

        ZBoxedView.__init__(self, parent)

        self.treeView.refresh()
        self._restoreTreeSelection()
    # end __init__()

    def getViewId(self):
        return IZViewIds.NAVIGATOR_VIEW
    # end getViewId()

    def _getHeaderBitmap(self):
        return getResourceRegistry().getBitmap(u"images/perspectives/standard/navigator/navigator.png") #$NON-NLS-1$
    # end _getHeaderBitmap()

    def _getHeaderLabel(self):
        return _extstr(u"navigator.AccountNavigator") #$NON-NLS-1$
    # end _getHeaderLabel()

    def _createHeaderWidgets(self, parent, widgetList):
        # Register for events before creating the model so that we don't miss any.
        # Register for events after init'ing WX!
        self._registerAsListener()
        self.model = ZNavigatorModel()

        # Collapse All button
        bitmap = getResourceRegistry().getBitmap(u"images/perspectives/standard/navigator/collapseAll.png") #$NON-NLS-1$
        self.collapseAllButton = ZImageButton(parent, bitmap, False, None, True)
        self.collapseAllButton.SetToolTipString(_extstr(u"navigator.CollapseAllTooltip")) #$NON-NLS-1$
        # Dashboard button
        bitmap = getResourceRegistry().getBitmap(u"images/perspectives/standard/dashboard.png") #$NON-NLS-1$
        self.dashboardButton = ZImageButton(parent, bitmap, False, None, True)
        self.dashboardButton.SetToolTipString(_extstr(u"navigator.DashboardTooltip")) #$NON-NLS-1$

        widgetList.append(self.collapseAllButton)
        widgetList.append(self.dashboardButton)
    # end _createHeaderWidgets()

    def _createContentWidgets(self, parent):
        self.treeImageList = self._createTreeImageList()
        self.treeProvider = ZTreeNodeBasedContentProvider(self.model.getNavigatorTreeRoot(), self.treeImageList)
        treeStyle = wx.NO_BORDER | wx.TR_HIDE_ROOT | wx.TR_LINES_AT_ROOT | wx.TR_SINGLE | wx.TR_HAS_BUTTONS
        self.treeView = ZTreeView(self.treeProvider, parent, style = treeStyle)
        dropTarget = ZNavigatorViewDropTarget(self.treeView, self)
        self.treeView.SetDropTarget(dropTarget)
    # end _createContentWidgets()

    def _layoutContentWidgets(self):
        box = wx.BoxSizer(wx.VERTICAL)
        box.Add(self.treeView, 1, wx.EXPAND)

        return box
    # end _layoutContentWidgets()

    def _createTreeImageList(self):
        registry = getResourceRegistry()
        imgList = ZMappedImageList()
        for img in [u"unpublished", u"account", u"blog", u"posts", u"links", u"images", u"tags"]: #$NON-NLS-1$ #$NON-NLS-2$ #$NON-NLS-3$ #$NON-NLS-4$ #$NON-NLS-5$ #$NON-NLS-6$ #$NON-NLS-7$ #$NON-NLS-8$
            imgList.addImage(img, registry.getBitmap(u"images/perspectives/standard/navigator/%s.png" % img)) #$NON-NLS-1$

        return imgList
    # end _createTreeImageList()

    def _bindWidgetEvents(self):
        ZBoxedView._bindWidgetEvents(self)

        self.Bind(wx.EVT_TREE_SEL_CHANGED, self.onSelectionChanged, self.treeView)
        self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.onItemRightClick, self.treeView)
        self.Bind(wx.EVT_BUTTON, self.onDashboardButton, self.dashboardButton)
        self.Bind(wx.EVT_BUTTON, self.onCollapseAllButton, self.collapseAllButton)
        self.Bind(ZEVT_REFRESH, self.onZoundryRefresh, self)

        wx.EVT_SET_FOCUS(self.treeView, self.onFocus)
        wx.EVT_KILL_FOCUS(self.treeView, self.onUnFocus)
    # end _bindWidgetEvents()

    def onFocus(self, event):
        selection = self._getCurrentSelection()
        if selection:
            fireViewSelectionEvent(selection, self)
        event.Skip()
    # end onFocus()

    def onUnFocus(self, event):
        selection = self._getCurrentSelection()
        if selection:
            fireViewUnselectionEvent()
        event.Skip()
    # end onUnFocus()

    def onDashboardButton(self, event):
        self.treeView.UnselectAll()
        fireViewSelectionEvent(ZViewSelection(IZViewSelectionTypes.UNPUBLISHED_ACCOUNT_SELECTION, None), self)
        event.Skip()
    # end onDashboardButton()

    def onCollapseAllButton(self, event):
        self.treeView.UnselectAll()
        self.treeView.collapseAll()
        fireViewSelectionEvent(ZViewSelection(IZViewSelectionTypes.UNPUBLISHED_ACCOUNT_SELECTION, None), self)
        event.Skip()
    # end onCollapseAllButton()

    def onItemRightClick(self, event):
        itemId = event.GetItem()
        node = self.treeView.GetPyData(itemId)
        nodeType = node.getType()
        if nodeType == NODE_TYPE_ACCOUNT:
            account = node.getAccount()
            menu = self._createAccountCtxMenu(account)
            self.PopupMenu(menu)
            menu.Destroy()
        if nodeType == NODE_TYPE_BLOG:
            blog = node.getBlog()
            menu = self._createBlogCtxMenu(blog)
            self.PopupMenu(menu)
            menu.Destroy()
        event.Skip()
    # end onItemRightClick()

    def _createAccountCtxMenu(self, account):
        menuContext = ZAccountMenuActionContext(self, account)
        menuModel = ZBlogAccountMenuModel()
        provider = ZModelBasedMenuContentProvider(menuModel, menuContext)
        eventHandler = ZModelBasedMenuEventHandler(menuModel, menuContext)
        return ZMenu(self, menuModel.getRootNode(), provider, eventHandler)
    # end _createAccountCtxMenu()

    def _createBlogCtxMenu(self, blog):
        menuContext = ZBlogMenuActionContext(self, blog)
        menuModel = ZBlogMenuModel()
        provider = ZModelBasedMenuContentProvider(menuModel, menuContext)
        eventHandler = ZModelBasedMenuEventHandler(menuModel, menuContext)
        return ZMenu(self, menuModel.getRootNode(), provider, eventHandler)
    # end _createBlogCtxMenu()

    def onSelectionChanged(self, event):
        selection = self._getCurrentSelection()
        if selection:
            fireViewSelectionEvent(selection, self)
        else:
            fireViewUnselectionEvent()
        event.Skip()
    # end _onSelectionChanged()

    def onAccountAdded(self, account):
        self.accountEventQueue.put( (ACCOUNT_EVENT_ADD, account) )
        self.model.addAccount(account)
        fireRefreshEvent(self)
    # end onAccountAdded()

    def onAccountChanged(self, account):
        self.accountEventQueue.put( (ACCOUNT_EVENT_UPDATE, account) )
        self.model.updateAccount(account)
        fireRefreshEvent(self)
    # end onAccountChange()

    def onAccountDeleted(self, account):
        self.accountEventQueue.put( (ACCOUNT_EVENT_DELETE, account) )
        self.model.removeAccount(account)
        fireRefreshEvent(self)
    # end onAccountDeleted()

    def onIndexChange(self, event):
        shouldRefresh = event.getEventType() == IZDocIndexEvent.DOCINDEX_EVENTTYPE_ADD or \
                        event.getEventType() == IZDocIndexEvent.DOCINDEX_EVENTTYPE_REMOVE
        if shouldRefresh:
            self.indexEventQueue.put(event)
            fireRefreshEvent(self)
    # end onIndexChange()

    def onBlogEntryDropped(self, blogId, node):
        getLoggerService().debug(u"Dropped blog entry '%s' onto blog node '%s'." % (blogId, node.getBlog().getId())) #$NON-NLS-1$
        ZShowNotYetImplementedMessage(self)
    # end onBlogEntryDropped()

    def onZoundryRefresh(self, event): #@UnusedVariable
        nodesToRefresh = self._getNodesToRefresh()
        self.treeView.refresh(nodesToRefresh)
    # end onZoundryRefresh()

    # Gets the list of nodes to refresh based on the current queue of index events.
    def _getNodesToRefresh(self):
        nodesToRefresh = []

        # If there are any account events, refresh the whole tree
        if not self.accountEventQueue.empty():
            # Clear out the account event queue
            while not self.accountEventQueue.empty():
                self.accountEventQueue.get()
            return None

        # If there are index events, then we can refresh only parts of the tree
        while not self.indexEventQueue.empty():
            event = self.indexEventQueue.get()
            dirtyNodes = None
            if event.getEventType() == IZDocIndexEvent.DOCINDEX_EVENTTYPE_ADD:
                if event.getDataType() == IZDocIndexEvent.DOCINDEX_DATATYPE_DOCUMENT:
                    dirtyNodes = self.model.addDocumentIDO(event.getDocumentIDO())
                elif event.getDataType() == IZDocIndexEvent.DOCINDEX_DATATYPE_IMAGE:
                    dirtyNodes = self.model.addImageIDO(event.getImageIDO())
                elif event.getDataType() == IZDocIndexEvent.DOCINDEX_DATATYPE_LINK:
                    dirtyNodes = self.model.addLinkIDO(event.getLinkIDO())
                elif event.getDataType() == IZDocIndexEvent.DOCINDEX_DATATYPE_TAG:
                    dirtyNodes = self.model.addTagIDO(event.getTagIDO())

            elif event.getEventType() == IZDocIndexEvent.DOCINDEX_EVENTTYPE_REMOVE:
                if event.getDataType() == IZDocIndexEvent.DOCINDEX_DATATYPE_DOCUMENT:
                    dirtyNodes = self.model.removeDocumentIDO(event.getDocumentIDO())
                elif event.getDataType() == IZDocIndexEvent.DOCINDEX_DATATYPE_IMAGE:
                    dirtyNodes = self.model.removeImageIDO(event.getImageIDO())
                elif event.getDataType() == IZDocIndexEvent.DOCINDEX_DATATYPE_LINK:
                    dirtyNodes = self.model.removeLinkIDO(event.getLinkIDO())
                elif event.getDataType() == IZDocIndexEvent.DOCINDEX_DATATYPE_TAG:
                    dirtyNodes = self.model.removeTagIDO(event.getTagIDO())
            if dirtyNodes is not None:
                nodesToRefresh.extend(dirtyNodes)

        return nodesToRefresh
    # end _getNodesToRefresh()

    def _getCurrentSelection(self):
        treeIDs = self.treeView.GetSelections()
        nodes = map(self.treeView.GetPyData, treeIDs)
        # Just return the 1st node - currently multi-selection is disabled.
        for node in nodes:
            return createViewSelection(node)

        return None
    # end _getCurrentSelection()

    def destroy(self):
        self._saveTreeLayout()

        self._unregisterAsListener()
    # end destroy()

    def _saveTreeLayout(self):
        visitor = ZTreeLayoutSaveVisitor()
        self.treeView.accept(visitor)
        self._saveTreeSelection()

        # Save the properties
        getApplicationModel().getUserProfile().getProperties().save()
    # end _saveTreeLayout()

    def _saveTreeSelection(self):
        nodes = self.treeView.getSelectedNodes()
        hashValue = 0
        if nodes:
            node = nodes[0]
            hashValue = node.hashCode()
        userPrefs = getApplicationModel().getUserProfile().getPreferences()
        userPrefs.setUserPreference(IZBlogAppUserPrefsKeys.NAVIGATOR_VIEW_SELECTION, unicode(hashValue))
    # end _saveTreeSelection()

    def _restoreTreeSelection(self):
        userPrefs = getApplicationModel().getUserProfile().getPreferences()
        hashValue = userPrefs.getUserPreferenceInt(IZBlogAppUserPrefsKeys.NAVIGATOR_VIEW_SELECTION, 0)
        if hashValue != 0:
            visitor = ZTreeSelectionRestoreVisitor(self, hashValue)
            self.treeView.accept(visitor)
    # end _restoreTreeSelection()

    def _registerAsListener(self):
        self._registerAsAccountListener()
        self._registerAsIndexListener()
    # end _registerAsListener()

    def _unregisterAsListener(self):
        self._unregisterAsAccountListener()
        self._unregisterAsIndexListener()
    # end _unregisterAsListener()

    def _registerAsAccountListener(self):
        engine = getApplicationModel().getEngine()
        accountStore = engine.getService(IZBlogAppServiceIDs.ACCOUNT_STORE_SERVICE_ID)
        accountStore.addListener(self)
    # end _registerAsAccountListener()

    def _unregisterAsAccountListener(self):
        engine = getApplicationModel().getEngine()
        accountStore = engine.getService(IZBlogAppServiceIDs.ACCOUNT_STORE_SERVICE_ID)
        accountStore.removeListener(self)
    # end _unregisterAsAccountListener()

    def _registerAsIndexListener(self):
        engine = getApplicationModel().getEngine()
        accountStore = engine.getService(IZBlogAppServiceIDs.DOCUMENT_INDEX_SERVICE_ID)
        accountStore.addListener(self)
    # end _registerAsIndexListener()

    def _unregisterAsIndexListener(self):
        engine = getApplicationModel().getEngine()
        accountStore = engine.getService(IZBlogAppServiceIDs.DOCUMENT_INDEX_SERVICE_ID)
        accountStore.removeListener(self)
Esempio n. 6
0
class ZLinksView(ZBoxedView, IZDocumentIndexListener):
    def __init__(self, parent):
        self.link = None
        self.blog = None
        self.indexService = getApplicationModel().getService(
            IZBlogAppServiceIDs.DOCUMENT_INDEX_SERVICE_ID)
        self.accountStore = getApplicationModel().getService(
            IZBlogAppServiceIDs.ACCOUNT_STORE_SERVICE_ID)
        self.model = ZContextInfoLinksModel(ZLinkSearchFilter())
        self.openLinkAction = getApplicationModel().getActionRegistry(
        ).findAction(IZAppActionIDs.OPEN_LINK_ACTION)

        ZBoxedView.__init__(self, parent)

        self._registerAsIndexListener()

        self.validSelection = False

    # end __init__()

    def getViewId(self):
        return IZViewIds.LINKS_LIST_VIEW

    # end getViewId()

    def _getHeaderBitmap(self):
        return getResourceRegistry().getBitmap(
            u"images/perspectives/standard/links.png")  #$NON-NLS-1$

    # end _getHeaderBitmap()

    def _getHeaderLabel(self):
        return _extstr(u"linksview.Links")  #$NON-NLS-1$

    # end _getHeaderLabel()

    def _createHeaderWidgets(self, parent, widgetList):
        choices = self._getSearchBoxChoices()
        bitmap = getResourceRegistry().getBitmap(
            u"images/perspectives/standard/contextinfo/linksview/search.png"
        )  #$NON-NLS-1$
        self.searchTextBox = ZAdvancedTextBox(parent, bitmap, choices, False)
        self.searchTextBox.setCurrentChoice(SEARCH_HOST)
        self.searchTextBox.SetSizeHints(220, -1)

        widgetList.append(self.searchTextBox)

    # end _createHeaderWidgets()

    def _createContentWidgets(self, parent):
        treeStyle = wx.TR_HIDE_ROOT | wx.TR_LINES_AT_ROOT | wx.TR_SINGLE | wx.TR_HAS_BUTTONS | wx.NO_BORDER
        provider = ZLinkTreeContentProvider(self.model)
        self.linksTreeView = ZTreeView(provider, parent, style=treeStyle)

    # end _createContentWidgets()

    def _layoutContentWidgets(self):
        box = wx.BoxSizer(wx.VERTICAL)
        box.Add(self.linksTreeView, 1, wx.EXPAND)
        return box

    # end _layoutContentWidgets()

    def _bindWidgetEvents(self):
        ZBoxedView._bindWidgetEvents(self)

        self.Bind(ZEVT_REFRESH, self.onZoundryRefresh, self)
        self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.onLinkActivated,
                  self.linksTreeView)
        self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.onLinkRightClick,
                  self.linksTreeView)
        self.Bind(wx.EVT_TREE_SEL_CHANGED, self.onLinkSelected,
                  self.linksTreeView)
        #        self.Bind(wx.EVT_LIST_BEGIN_DRAG, self.onEntryBeginDrag, self.linksTreeView)
        self.Bind(wx.EVT_TEXT_ENTER, self.onSearchText, self.searchTextBox)
        self.Bind(ZEVT_VIEW_SELECTION_CHANGED, self.onViewSelectionChanged)
        wx.EVT_SET_FOCUS(self.linksTreeView, self.onFocus)
        wx.EVT_KILL_FOCUS(self.linksTreeView, self.onUnFocus)

    # end _bindWidgetEvents()

    def refreshContent(self, selection):
        (accountId, blogId) = selection.getData()

        filter = ZLinkSearchFilter()
        if blogId is not None:
            account = self.accountStore.getAccountById(accountId)
            self.blog = account.getBlogById(blogId)
            filter.setAccountIdCriteria(accountId)
            filter.setBlogIdCriteria(blogId)
        else:
            self.blog = None
            filter.setAccountIdCriteria(
                IZLinkSearchFilter.UNPUBLISHED_ACCOUNT_ID)
            filter.setBlogIdCriteria(IZLinkSearchFilter.UNPUBLISHED_BLOG_ID)

        self.model = ZContextInfoLinksModel(filter)
        self.linksTreeView.setContentProvider(
            ZLinkTreeContentProvider(self.model))
        self.linksTreeView.refresh()
        self.linksTreeView.deselectAll()
        self.onInvalidSelection()
        fireViewUnselectionEvent()

    # end refreshContent()

    def onViewSelectionChanged(self, event):
        if event.getSelection().getType(
        ) == IZViewSelectionTypes.BLOG_LINKS_SELECTION:
            self.refreshContent(event.getSelection())

    # end onViewSelectionChanged()

    def onFocus(self, event):
        if self.link:
            fireViewSelectionEvent(ZLinkSelection(self.link, self.blog), self)
        else:
            fireViewUnselectionEvent()
        event.Skip()

    # end onFocus()

    def onUnFocus(self, event):
        fireViewUnselectionEvent()
        event.Skip()

    # end onUnFocus()

    def onSearchText(self, event):
        self.model.setHostCriteria(event.GetString())
        self.model.refresh()
        self.linksTreeView.clear()
        self.linksTreeView.refresh()
        self.linksTreeView.deselectAll()
        self.onInvalidSelection()

        fireViewEvent(ZViewEvent(VIEWLINKSFILTERCHANGEDEVENT, self))
        event.Skip()

    # end onSearchText()
#
#    def onEntryBeginDrag(self, event):
#        index = event.GetIndex()
#        docIDO = self.model.getEntry(index)
#        docId = docIDO.getId()
#
#        # FIXME also add some sort of custom format for dragging to the Explorer/TextPad (use a composite data object)
#        data = ZBlogPostDataObjectInternal(docId)
#        dragSource = wx.DropSource(self)
#        dragSource.SetData(data)
#        dragSource.DoDragDrop(wx.Drag_CopyOnly)
#        event.Skip()
#    # end onEntryBeginDrag()

    def _updateModel(self, refreshData):
        (eventType, linkIDO) = refreshData
        shouldRefresh = False
        if eventType == IZDocIndexEvent.DOCINDEX_EVENTTYPE_ADD:
            shouldRefresh = self.model.addLink(linkIDO)
        elif eventType == IZDocIndexEvent.DOCINDEX_EVENTTYPE_REMOVE:
            shouldRefresh = self.model.removeLink(linkIDO)
        elif eventType == IZDocIndexEvent.DOCINDEX_EVENTTYPE_UPDATE:
            shouldRefresh = self.model.updateLink(linkIDO)
        return shouldRefresh

    # end _updateModel()

    # This is the only method that can happen on a non-UI thread.  It will
    # gather up the needed data, then fire a "refresh ui" event.  That event
    # will get picked up by the UI thread and the view will refresh.
    def onIndexChange(self, event):
        if event.getDataType() == IZDocIndexEvent.DOCINDEX_DATATYPE_LINK:
            refreshData = (event.getEventType(), event.getLinkIDO())
            fireRefreshEvent(self, refreshData)

    # end onIndexChange()

    def onZoundryRefresh(self, event):
        if self._updateModel(event.getData()):
            self.linksTreeView.refresh()
        event.Skip()

    # end onZoundryRefresh()

    def onLinkActivated(self, event):
        node = self.linksTreeView.GetPyData(event.GetItem())
        if isinstance(node, ZLinkIDONode):
            link = node.getLinkIDO()
            context = ZLinkIDOActionContext(self, link)
            self.openLinkAction.runAction(context)
        event.Skip

    # end onLinkActivated()

    def onLinkRightClick(self, event):
        node = self.linksTreeView.GetPyData(event.GetItem())
        if isinstance(node, ZLinkIDONode):
            link = node.getLinkIDO()
            context = ZLinkIDOActionContext(self, link)
            menuModel = ZLinkMenuModel()
            menu = ZModelBasedMenu(menuModel, context, self)
            self.PopupMenu(menu)
            menu.Destroy()
        event.Skip()

    # end onLinkRightClick()

    def onLinkSelected(self, event):
        node = self.linksTreeView.GetPyData(event.GetItem())
        if isinstance(node, ZLinkIDONode):
            self.link = node.getLinkIDO()

            if self.link:
                fireViewSelectionEvent(ZLinkSelection(self.link, self.blog),
                                       self)
            else:
                fireViewUnselectionEvent()
        event.Skip()

    # end onLinkSelected()

    def onInvalidSelection(self):
        self.link = None

    # end onInvalidSelection()

    def destroy(self):
        self._unregisterAsIndexListener()

    # end destroy()

    def _registerAsIndexListener(self):
        self.indexService.addListener(self)

    # end _registerAsIndexListener()

    def _unregisterAsIndexListener(self):
        self.indexService.removeListener(self)

    # end _unregisterAsIndexListener()

    def _getSearchBoxChoices(self):
        return [
            (u"Host", None, SEARCH_HOST),  #$NON-NLS-1$
        ]
Esempio n. 7
0
 def _createContentWidgets(self, parent):
     treeStyle = wx.TR_HIDE_ROOT | wx.TR_LINES_AT_ROOT | wx.TR_SINGLE | wx.TR_HAS_BUTTONS | wx.NO_BORDER
     provider = ZLinkTreeContentProvider(self.model)
     self.linksTreeView = ZTreeView(provider, parent, style=treeStyle)
Esempio n. 8
0
class ZNavigatorView(ZBoxedView, IZAccountStoreListener,
                     IZDocumentIndexListener):
    def __init__(self, parent):
        self.indexEventQueue = Queue()
        self.accountEventQueue = Queue()
        self.model = None

        ZBoxedView.__init__(self, parent)

        self.treeView.refresh()
        self._restoreTreeSelection()

    # end __init__()

    def getViewId(self):
        return IZViewIds.NAVIGATOR_VIEW

    # end getViewId()

    def _getHeaderBitmap(self):
        return getResourceRegistry().getBitmap(
            u"images/perspectives/standard/navigator/navigator.png"
        )  #$NON-NLS-1$

    # end _getHeaderBitmap()

    def _getHeaderLabel(self):
        return _extstr(u"navigator.AccountNavigator")  #$NON-NLS-1$

    # end _getHeaderLabel()

    def _createHeaderWidgets(self, parent, widgetList):
        # Register for events before creating the model so that we don't miss any.
        # Register for events after init'ing WX!
        self._registerAsListener()
        self.model = ZNavigatorModel()

        # Collapse All button
        bitmap = getResourceRegistry().getBitmap(
            u"images/perspectives/standard/navigator/collapseAll.png"
        )  #$NON-NLS-1$
        self.collapseAllButton = ZImageButton(parent, bitmap, False, None,
                                              True)
        self.collapseAllButton.SetToolTipString(
            _extstr(u"navigator.CollapseAllTooltip"))  #$NON-NLS-1$
        # Dashboard button
        bitmap = getResourceRegistry().getBitmap(
            u"images/perspectives/standard/dashboard.png")  #$NON-NLS-1$
        self.dashboardButton = ZImageButton(parent, bitmap, False, None, True)
        self.dashboardButton.SetToolTipString(
            _extstr(u"navigator.DashboardTooltip"))  #$NON-NLS-1$

        widgetList.append(self.collapseAllButton)
        widgetList.append(self.dashboardButton)

    # end _createHeaderWidgets()

    def _createContentWidgets(self, parent):
        self.treeImageList = self._createTreeImageList()
        self.treeProvider = ZTreeNodeBasedContentProvider(
            self.model.getNavigatorTreeRoot(), self.treeImageList)
        treeStyle = wx.NO_BORDER | wx.TR_HIDE_ROOT | wx.TR_LINES_AT_ROOT | wx.TR_SINGLE | wx.TR_HAS_BUTTONS
        self.treeView = ZTreeView(self.treeProvider, parent, style=treeStyle)
        dropTarget = ZNavigatorViewDropTarget(self.treeView, self)
        self.treeView.SetDropTarget(dropTarget)

    # end _createContentWidgets()

    def _layoutContentWidgets(self):
        box = wx.BoxSizer(wx.VERTICAL)
        box.Add(self.treeView, 1, wx.EXPAND)

        return box

    # end _layoutContentWidgets()

    def _createTreeImageList(self):
        registry = getResourceRegistry()
        imgList = ZMappedImageList()
        for img in [
                u"unpublished", u"account", u"blog", u"posts", u"links",
                u"images", u"tags"
        ]:  #$NON-NLS-1$ #$NON-NLS-2$ #$NON-NLS-3$ #$NON-NLS-4$ #$NON-NLS-5$ #$NON-NLS-6$ #$NON-NLS-7$ #$NON-NLS-8$
            imgList.addImage(
                img,
                registry.getBitmap(
                    u"images/perspectives/standard/navigator/%s.png" %
                    img))  #$NON-NLS-1$

        return imgList

    # end _createTreeImageList()

    def _bindWidgetEvents(self):
        ZBoxedView._bindWidgetEvents(self)

        self.Bind(wx.EVT_TREE_SEL_CHANGED, self.onSelectionChanged,
                  self.treeView)
        self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.onItemRightClick,
                  self.treeView)
        self.Bind(wx.EVT_BUTTON, self.onDashboardButton, self.dashboardButton)
        self.Bind(wx.EVT_BUTTON, self.onCollapseAllButton,
                  self.collapseAllButton)
        self.Bind(ZEVT_REFRESH, self.onZoundryRefresh, self)

        wx.EVT_SET_FOCUS(self.treeView, self.onFocus)
        wx.EVT_KILL_FOCUS(self.treeView, self.onUnFocus)

    # end _bindWidgetEvents()

    def onFocus(self, event):
        selection = self._getCurrentSelection()
        if selection:
            fireViewSelectionEvent(selection, self)
        event.Skip()

    # end onFocus()

    def onUnFocus(self, event):
        selection = self._getCurrentSelection()
        if selection:
            fireViewUnselectionEvent()
        event.Skip()

    # end onUnFocus()

    def onDashboardButton(self, event):
        self.treeView.UnselectAll()
        fireViewSelectionEvent(
            ZViewSelection(IZViewSelectionTypes.UNPUBLISHED_ACCOUNT_SELECTION,
                           None), self)
        event.Skip()

    # end onDashboardButton()

    def onCollapseAllButton(self, event):
        self.treeView.UnselectAll()
        self.treeView.collapseAll()
        fireViewSelectionEvent(
            ZViewSelection(IZViewSelectionTypes.UNPUBLISHED_ACCOUNT_SELECTION,
                           None), self)
        event.Skip()

    # end onCollapseAllButton()

    def onItemRightClick(self, event):
        itemId = event.GetItem()
        node = self.treeView.GetPyData(itemId)
        nodeType = node.getType()
        if nodeType == NODE_TYPE_ACCOUNT:
            account = node.getAccount()
            menu = self._createAccountCtxMenu(account)
            self.PopupMenu(menu)
            menu.Destroy()
        if nodeType == NODE_TYPE_BLOG:
            blog = node.getBlog()
            menu = self._createBlogCtxMenu(blog)
            self.PopupMenu(menu)
            menu.Destroy()
        event.Skip()

    # end onItemRightClick()

    def _createAccountCtxMenu(self, account):
        menuContext = ZAccountMenuActionContext(self, account)
        menuModel = ZBlogAccountMenuModel()
        provider = ZModelBasedMenuContentProvider(menuModel, menuContext)
        eventHandler = ZModelBasedMenuEventHandler(menuModel, menuContext)
        return ZMenu(self, menuModel.getRootNode(), provider, eventHandler)

    # end _createAccountCtxMenu()

    def _createBlogCtxMenu(self, blog):
        menuContext = ZBlogMenuActionContext(self, blog)
        menuModel = ZBlogMenuModel()
        provider = ZModelBasedMenuContentProvider(menuModel, menuContext)
        eventHandler = ZModelBasedMenuEventHandler(menuModel, menuContext)
        return ZMenu(self, menuModel.getRootNode(), provider, eventHandler)

    # end _createBlogCtxMenu()

    def onSelectionChanged(self, event):
        selection = self._getCurrentSelection()
        if selection:
            fireViewSelectionEvent(selection, self)
        else:
            fireViewUnselectionEvent()
        event.Skip()

    # end _onSelectionChanged()

    def onAccountAdded(self, account):
        self.accountEventQueue.put((ACCOUNT_EVENT_ADD, account))
        self.model.addAccount(account)
        fireRefreshEvent(self)

    # end onAccountAdded()

    def onAccountChanged(self, account):
        self.accountEventQueue.put((ACCOUNT_EVENT_UPDATE, account))
        self.model.updateAccount(account)
        fireRefreshEvent(self)

    # end onAccountChange()

    def onAccountDeleted(self, account):
        self.accountEventQueue.put((ACCOUNT_EVENT_DELETE, account))
        self.model.removeAccount(account)
        fireRefreshEvent(self)

    # end onAccountDeleted()

    def onIndexChange(self, event):
        shouldRefresh = event.getEventType() == IZDocIndexEvent.DOCINDEX_EVENTTYPE_ADD or \
                        event.getEventType() == IZDocIndexEvent.DOCINDEX_EVENTTYPE_REMOVE
        if shouldRefresh:
            self.indexEventQueue.put(event)
            fireRefreshEvent(self)

    # end onIndexChange()

    def onBlogEntryDropped(self, blogId, node):
        getLoggerService().debug(
            u"Dropped blog entry '%s' onto blog node '%s'." %
            (blogId, node.getBlog().getId()))  #$NON-NLS-1$
        ZShowNotYetImplementedMessage(self)

    # end onBlogEntryDropped()

    def onZoundryRefresh(self, event):  #@UnusedVariable
        nodesToRefresh = self._getNodesToRefresh()
        self.treeView.refresh(nodesToRefresh)

    # end onZoundryRefresh()

    # Gets the list of nodes to refresh based on the current queue of index events.
    def _getNodesToRefresh(self):
        nodesToRefresh = []

        # If there are any account events, refresh the whole tree
        if not self.accountEventQueue.empty():
            # Clear out the account event queue
            while not self.accountEventQueue.empty():
                self.accountEventQueue.get()
            return None

        # If there are index events, then we can refresh only parts of the tree
        while not self.indexEventQueue.empty():
            event = self.indexEventQueue.get()
            dirtyNodes = None
            if event.getEventType() == IZDocIndexEvent.DOCINDEX_EVENTTYPE_ADD:
                if event.getDataType(
                ) == IZDocIndexEvent.DOCINDEX_DATATYPE_DOCUMENT:
                    dirtyNodes = self.model.addDocumentIDO(
                        event.getDocumentIDO())
                elif event.getDataType(
                ) == IZDocIndexEvent.DOCINDEX_DATATYPE_IMAGE:
                    dirtyNodes = self.model.addImageIDO(event.getImageIDO())
                elif event.getDataType(
                ) == IZDocIndexEvent.DOCINDEX_DATATYPE_LINK:
                    dirtyNodes = self.model.addLinkIDO(event.getLinkIDO())
                elif event.getDataType(
                ) == IZDocIndexEvent.DOCINDEX_DATATYPE_TAG:
                    dirtyNodes = self.model.addTagIDO(event.getTagIDO())

            elif event.getEventType(
            ) == IZDocIndexEvent.DOCINDEX_EVENTTYPE_REMOVE:
                if event.getDataType(
                ) == IZDocIndexEvent.DOCINDEX_DATATYPE_DOCUMENT:
                    dirtyNodes = self.model.removeDocumentIDO(
                        event.getDocumentIDO())
                elif event.getDataType(
                ) == IZDocIndexEvent.DOCINDEX_DATATYPE_IMAGE:
                    dirtyNodes = self.model.removeImageIDO(event.getImageIDO())
                elif event.getDataType(
                ) == IZDocIndexEvent.DOCINDEX_DATATYPE_LINK:
                    dirtyNodes = self.model.removeLinkIDO(event.getLinkIDO())
                elif event.getDataType(
                ) == IZDocIndexEvent.DOCINDEX_DATATYPE_TAG:
                    dirtyNodes = self.model.removeTagIDO(event.getTagIDO())
            if dirtyNodes is not None:
                nodesToRefresh.extend(dirtyNodes)

        return nodesToRefresh

    # end _getNodesToRefresh()

    def _getCurrentSelection(self):
        treeIDs = self.treeView.GetSelections()
        nodes = map(self.treeView.GetPyData, treeIDs)
        # Just return the 1st node - currently multi-selection is disabled.
        for node in nodes:
            return createViewSelection(node)

        return None

    # end _getCurrentSelection()

    def destroy(self):
        self._saveTreeLayout()

        self._unregisterAsListener()

    # end destroy()

    def _saveTreeLayout(self):
        visitor = ZTreeLayoutSaveVisitor()
        self.treeView.accept(visitor)
        self._saveTreeSelection()

        # Save the properties
        getApplicationModel().getUserProfile().getProperties().save()

    # end _saveTreeLayout()

    def _saveTreeSelection(self):
        nodes = self.treeView.getSelectedNodes()
        hashValue = 0
        if nodes:
            node = nodes[0]
            hashValue = node.hashCode()
        userPrefs = getApplicationModel().getUserProfile().getPreferences()
        userPrefs.setUserPreference(
            IZBlogAppUserPrefsKeys.NAVIGATOR_VIEW_SELECTION,
            unicode(hashValue))

    # end _saveTreeSelection()

    def _restoreTreeSelection(self):
        userPrefs = getApplicationModel().getUserProfile().getPreferences()
        hashValue = userPrefs.getUserPreferenceInt(
            IZBlogAppUserPrefsKeys.NAVIGATOR_VIEW_SELECTION, 0)
        if hashValue != 0:
            visitor = ZTreeSelectionRestoreVisitor(self, hashValue)
            self.treeView.accept(visitor)

    # end _restoreTreeSelection()

    def _registerAsListener(self):
        self._registerAsAccountListener()
        self._registerAsIndexListener()

    # end _registerAsListener()

    def _unregisterAsListener(self):
        self._unregisterAsAccountListener()
        self._unregisterAsIndexListener()

    # end _unregisterAsListener()

    def _registerAsAccountListener(self):
        engine = getApplicationModel().getEngine()
        accountStore = engine.getService(
            IZBlogAppServiceIDs.ACCOUNT_STORE_SERVICE_ID)
        accountStore.addListener(self)

    # end _registerAsAccountListener()

    def _unregisterAsAccountListener(self):
        engine = getApplicationModel().getEngine()
        accountStore = engine.getService(
            IZBlogAppServiceIDs.ACCOUNT_STORE_SERVICE_ID)
        accountStore.removeListener(self)

    # end _unregisterAsAccountListener()

    def _registerAsIndexListener(self):
        engine = getApplicationModel().getEngine()
        accountStore = engine.getService(
            IZBlogAppServiceIDs.DOCUMENT_INDEX_SERVICE_ID)
        accountStore.addListener(self)

    # end _registerAsIndexListener()

    def _unregisterAsIndexListener(self):
        engine = getApplicationModel().getEngine()
        accountStore = engine.getService(
            IZBlogAppServiceIDs.DOCUMENT_INDEX_SERVICE_ID)
        accountStore.removeListener(self)
Esempio n. 9
0
class ZLinksView(ZBoxedView, IZDocumentIndexListener):

    def __init__(self, parent):
        self.link = None
        self.blog = None
        self.indexService = getApplicationModel().getService(IZBlogAppServiceIDs.DOCUMENT_INDEX_SERVICE_ID)
        self.accountStore = getApplicationModel().getService(IZBlogAppServiceIDs.ACCOUNT_STORE_SERVICE_ID)
        self.model = ZContextInfoLinksModel(ZLinkSearchFilter())
        self.openLinkAction = getApplicationModel().getActionRegistry().findAction(IZAppActionIDs.OPEN_LINK_ACTION)

        ZBoxedView.__init__(self, parent)

        self._registerAsIndexListener()

        self.validSelection = False
    # end __init__()

    def getViewId(self):
        return IZViewIds.LINKS_LIST_VIEW
    # end getViewId()

    def _getHeaderBitmap(self):
        return getResourceRegistry().getBitmap(u"images/perspectives/standard/links.png") #$NON-NLS-1$
    # end _getHeaderBitmap()

    def _getHeaderLabel(self):
        return _extstr(u"linksview.Links") #$NON-NLS-1$
    # end _getHeaderLabel()

    def _createHeaderWidgets(self, parent, widgetList):
        choices = self._getSearchBoxChoices()
        bitmap = getResourceRegistry().getBitmap(u"images/perspectives/standard/contextinfo/linksview/search.png") #$NON-NLS-1$
        self.searchTextBox = ZAdvancedTextBox(parent, bitmap, choices, False)
        self.searchTextBox.setCurrentChoice(SEARCH_HOST)
        self.searchTextBox.SetSizeHints(220, -1)

        widgetList.append(self.searchTextBox)
    # end _createHeaderWidgets()

    def _createContentWidgets(self, parent):
        treeStyle = wx.TR_HIDE_ROOT | wx.TR_LINES_AT_ROOT | wx.TR_SINGLE | wx.TR_HAS_BUTTONS | wx.NO_BORDER
        provider = ZLinkTreeContentProvider(self.model)
        self.linksTreeView = ZTreeView(provider, parent, style = treeStyle)
    # end _createContentWidgets()

    def _layoutContentWidgets(self):
        box = wx.BoxSizer(wx.VERTICAL)
        box.Add(self.linksTreeView, 1, wx.EXPAND)
        return box
    # end _layoutContentWidgets()

    def _bindWidgetEvents(self):
        ZBoxedView._bindWidgetEvents(self)

        self.Bind(ZEVT_REFRESH, self.onZoundryRefresh, self)
        self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.onLinkActivated, self.linksTreeView)
        self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.onLinkRightClick, self.linksTreeView)
        self.Bind(wx.EVT_TREE_SEL_CHANGED, self.onLinkSelected, self.linksTreeView)
#        self.Bind(wx.EVT_LIST_BEGIN_DRAG, self.onEntryBeginDrag, self.linksTreeView)
        self.Bind(wx.EVT_TEXT_ENTER, self.onSearchText, self.searchTextBox)
        self.Bind(ZEVT_VIEW_SELECTION_CHANGED, self.onViewSelectionChanged)
        wx.EVT_SET_FOCUS(self.linksTreeView, self.onFocus)
        wx.EVT_KILL_FOCUS(self.linksTreeView, self.onUnFocus)
    # end _bindWidgetEvents()

    def refreshContent(self, selection):
        (accountId, blogId) = selection.getData()

        filter = ZLinkSearchFilter()
        if blogId is not None:
            account = self.accountStore.getAccountById(accountId)
            self.blog = account.getBlogById(blogId)
            filter.setAccountIdCriteria(accountId)
            filter.setBlogIdCriteria(blogId)
        else:
            self.blog = None
            filter.setAccountIdCriteria(IZLinkSearchFilter.UNPUBLISHED_ACCOUNT_ID)
            filter.setBlogIdCriteria(IZLinkSearchFilter.UNPUBLISHED_BLOG_ID)

        self.model = ZContextInfoLinksModel(filter)
        self.linksTreeView.setContentProvider(ZLinkTreeContentProvider(self.model))
        self.linksTreeView.refresh()
        self.linksTreeView.deselectAll()
        self.onInvalidSelection()
        fireViewUnselectionEvent()
    # end refreshContent()

    def onViewSelectionChanged(self, event):
        if event.getSelection().getType() == IZViewSelectionTypes.BLOG_LINKS_SELECTION:
            self.refreshContent(event.getSelection())
    # end onViewSelectionChanged()

    def onFocus(self, event):
        if self.link:
            fireViewSelectionEvent(ZLinkSelection(self.link, self.blog), self)
        else:
            fireViewUnselectionEvent()
        event.Skip()
    # end onFocus()

    def onUnFocus(self, event):
        fireViewUnselectionEvent()
        event.Skip()
    # end onUnFocus()

    def onSearchText(self, event):
        self.model.setHostCriteria(event.GetString())
        self.model.refresh()
        self.linksTreeView.clear()
        self.linksTreeView.refresh()
        self.linksTreeView.deselectAll()
        self.onInvalidSelection()
        
        fireViewEvent(ZViewEvent(VIEWLINKSFILTERCHANGEDEVENT, self))
        event.Skip()
    # end onSearchText()
#
#    def onEntryBeginDrag(self, event):
#        index = event.GetIndex()
#        docIDO = self.model.getEntry(index)
#        docId = docIDO.getId()
#
#        # FIXME also add some sort of custom format for dragging to the Explorer/TextPad (use a composite data object)
#        data = ZBlogPostDataObjectInternal(docId)
#        dragSource = wx.DropSource(self)
#        dragSource.SetData(data)
#        dragSource.DoDragDrop(wx.Drag_CopyOnly)
#        event.Skip()
#    # end onEntryBeginDrag()

    def _updateModel(self, refreshData):
        (eventType, linkIDO) = refreshData
        shouldRefresh = False
        if eventType == IZDocIndexEvent.DOCINDEX_EVENTTYPE_ADD:
            shouldRefresh = self.model.addLink(linkIDO)
        elif eventType == IZDocIndexEvent.DOCINDEX_EVENTTYPE_REMOVE:
            shouldRefresh = self.model.removeLink(linkIDO)
        elif eventType == IZDocIndexEvent.DOCINDEX_EVENTTYPE_UPDATE:
            shouldRefresh = self.model.updateLink(linkIDO)
        return shouldRefresh
    # end _updateModel()

    # This is the only method that can happen on a non-UI thread.  It will
    # gather up the needed data, then fire a "refresh ui" event.  That event
    # will get picked up by the UI thread and the view will refresh.
    def onIndexChange(self, event):
        if event.getDataType() == IZDocIndexEvent.DOCINDEX_DATATYPE_LINK:
            refreshData = (event.getEventType(), event.getLinkIDO())
            fireRefreshEvent(self, refreshData)
    # end onIndexChange()

    def onZoundryRefresh(self, event):
        if self._updateModel(event.getData()):
            self.linksTreeView.refresh()
        event.Skip()
    # end onZoundryRefresh()

    def onLinkActivated(self, event):
        node = self.linksTreeView.GetPyData(event.GetItem())
        if isinstance(node, ZLinkIDONode):
            link = node.getLinkIDO()
            context = ZLinkIDOActionContext(self, link)
            self.openLinkAction.runAction(context)
        event.Skip
    # end onLinkActivated()

    def onLinkRightClick(self, event):
        node = self.linksTreeView.GetPyData(event.GetItem())
        if isinstance(node, ZLinkIDONode):
            link = node.getLinkIDO()
            context = ZLinkIDOActionContext(self, link)
            menuModel = ZLinkMenuModel()
            menu = ZModelBasedMenu(menuModel, context, self)
            self.PopupMenu(menu)
            menu.Destroy()
        event.Skip()
    # end onLinkRightClick()

    def onLinkSelected(self, event):
        node = self.linksTreeView.GetPyData(event.GetItem())
        if isinstance(node, ZLinkIDONode):
            self.link = node.getLinkIDO()

            if self.link:
                fireViewSelectionEvent(ZLinkSelection(self.link, self.blog), self)
            else:
                fireViewUnselectionEvent()
        event.Skip()
    # end onLinkSelected()

    def onInvalidSelection(self):
        self.link = None
    # end onInvalidSelection()

    def destroy(self):
        self._unregisterAsIndexListener()
    # end destroy()

    def _registerAsIndexListener(self):
        self.indexService.addListener(self)
    # end _registerAsIndexListener()

    def _unregisterAsIndexListener(self):
        self.indexService.removeListener(self)
    # end _unregisterAsIndexListener()

    def _getSearchBoxChoices(self):
        return [
                (u"Host", None, SEARCH_HOST), #$NON-NLS-1$
        ]
Esempio n. 10
0
 def _createContentWidgets(self, parent):
     treeStyle = wx.TR_HIDE_ROOT | wx.TR_LINES_AT_ROOT | wx.TR_SINGLE | wx.TR_HAS_BUTTONS | wx.NO_BORDER
     provider = ZLinkTreeContentProvider(self.model)
     self.linksTreeView = ZTreeView(provider, parent, style = treeStyle)
Esempio n. 11
0
class ZPreferencesDialog(ZHeaderDialog):
    def __init__(self, parent, jumpToPageId=None):
        self.currentSelection = None
        self.currentPage = None
        self.currentPageId = None
        self.pageCache = {}
        style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER
        title = self._getDialogTitle()
        size = self._getInitialSize()

        ZHeaderDialog.__init__(self,
                               parent,
                               wx.ID_ANY,
                               title,
                               name=u"PrefsDialog",
                               style=style,
                               size=size)  #$NON-NLS-1$

        self._enableButtons(False)
        self.jumpToPage(jumpToPageId)
        self.prefsTreeView.SetFocus()

    # end __init__()

    def _getNonHeaderContentBorder(self):
        return 0

    # end _getNonHeaderContentBorder()

    def _createNonHeaderWidgets(self):
        self.splitterWindow = ZSplitterWindow(self)
        self.splitterWindow.SetMinimumPaneSize(100)
        self.splitterWindow.SetSashSize(3)

        self.leftPanel = self._createLeftTreePanel()
        self.currentPage = self._createDefaultPage()
        self.currentPageId = None

        self.splitterWindow.SplitVertically(self.leftPanel, self.currentPage,
                                            175)

        self.lowerStaticLine = wx.StaticLine(self)

    # end _createNonHeaderWidgets()

    def _createLeftTreePanel(self):
        panel = ZTransparentPanel(self.splitterWindow,
                                  wx.ID_ANY,
                                  style=wx.NO_BORDER)

        # Create the prefs tree view.
        provider = self._createTreeProvider()
        treeStyle = wx.NO_BORDER | wx.TR_HIDE_ROOT | wx.TR_LINES_AT_ROOT | wx.TR_SINGLE | wx.TR_HAS_BUTTONS
        self.prefsTreeView = ZTreeView(provider, panel, style=treeStyle)
        self.prefsTreeView.refresh()

        self.treeButtons = self._createTreeButtons(panel)

        # Create a little static vertical line (aesthetic only)
        self.middleStaticLine = wx.StaticLine(panel, style=wx.LI_VERTICAL)

        return panel

    # end _createLeftTreePanel()

    def _createTreeButtons(self, parent):  #@UnusedVariable
        return []

    # end _createTreeButtons()

    # This is the page created when no pref page is selected.
    def _createDefaultPage(self):
        defaultPrefPage = ZDefaultPreferencePage(self.splitterWindow)
        return defaultPrefPage

    # end _createDefaultPage()

    def _populateNonHeaderWidgets(self):
        self._enableApplyButton(False)

    # end _populateNonHeaderWidgets()

    def _layoutNonHeaderWidgets(self):
        treeSizer = wx.BoxSizer(wx.VERTICAL)
        treeSizer.Add(self.prefsTreeView, 1, wx.EXPAND)
        for button in self.treeButtons:
            treeSizer.Add(button, 0, wx.EXPAND | wx.ALL, 2)

        leftPanelSizer = wx.BoxSizer(wx.HORIZONTAL)
        leftPanelSizer.Add(treeSizer, 1, wx.EXPAND)
        leftPanelSizer.Add(self.middleStaticLine, 0, wx.EXPAND)
        self.leftPanel.SetAutoLayout(True)
        self.leftPanel.SetSizer(leftPanelSizer)
        self.leftPanel.Layout()

        verticalSizer = wx.BoxSizer(wx.VERTICAL)
        verticalSizer.Add(self.splitterWindow, 1, wx.EXPAND)
        verticalSizer.Add(self.lowerStaticLine, 0, wx.EXPAND)
        return verticalSizer

    # end _layoutNonHeaderWidgets()

    def _bindWidgetEvents(self):
        self.Bind(wx.EVT_TREE_SEL_CHANGED, self.onTreeItemSelected,
                  self.prefsTreeView)
        self.Bind(wx.EVT_TREE_SEL_CHANGING, self.onTreeItemChanging,
                  self.prefsTreeView)

        self._bindOkButton(self.onOK)
        self._bindCancelButton(self.onCancel)
        self._bindApplyButton(self.onApply)

    # end _bindWidgetEvents()

    def onTreeItemChanging(self, event):
        if self.currentPage is not None:
            if self.currentPage.isDirty():
                # FIXME (EPW) provide override for this message and title
                if not ZShowYesNoMessage(
                        self, _extstr(u"prefsdialog.PrefPageSwitchMessage"),
                        _extstr(u"prefsdialog.DiscardChanges")
                ):  #$NON-NLS-2$ #$NON-NLS-1$
                    event.Veto()
                    return
                else:
                    self.currentPage.rollback()
        event.Skip()

    # end onTreeItemChanging()

    def onTreeItemSelected(self, event):
        node = self.prefsTreeView.GetPyData(event.GetItem())
        self.currentSelection = node
        self._updateHeader()
        self._changePreferencePage()

        event.Skip()

    # end onTreeItemSelected()

    # This method is called when the user is changing to a new preference page.
    def _changePreferencePage(self):
        oldPage = self.currentPage
        oldPage.Show(False)

        if self.currentSelection is None:
            self.currentPage = self._createDefaultPage()
            self.currentPage.Show(True)
        elif self.currentSelection in self.pageCache:
            self.currentPage = self.pageCache[self.currentSelection]
            self.currentPage.Show(True)
        else:
            # Construct the preference page.
            self.currentPage = self._createPrefPage(self.splitterWindow,
                                                    self.currentSelection)
            self.currentPage.setPrefsDialog(self)

            # Create, populate, layout the page.
            self.currentPage.createWidgets()
            self.currentPage.bindWidgetEvents()
            self.currentPage.populateWidgets()
            self.currentPage.layoutWidgets()
            self.pageCache[self.currentSelection] = self.currentPage
        # Call rollback here, which should clear out the page's session
        # and force it to update its visual state (this is useful when one
        # pref page's initial visual state depends on another page's data,
        # which may have changed since this page was created).
        self.currentPage.rollback()

        self.currentPageId = self._resolveNodeId(self.currentSelection)

        self.splitterWindow.ReplaceWindow(oldPage, self.currentPage)
        self.splitterWindow.Layout()
        self.currentPage.Layout()

    # end _changePreferencePage()

    def _getButtonTypes(self):
        return ZBaseDialog.OK_BUTTON | ZBaseDialog.CANCEL_BUTTON | ZBaseDialog.APPLY_BUTTON

    # end _getButtonTypes()

    # Called by the active pref page when the user changes something.
    def onPrefPageChange(self):
        if self.currentPage is not None:
            if self.currentPage.isDirty() and self.currentPage.isValid():
                self._enableButtons(True)
            else:
                self._enableButtons(False)

    # end onPrefPageChange()

    def _enableButtons(self, enabled=True):
        self._enableOkButton(enabled)
        self._enableApplyButton(enabled)
        cancelButton = self.FindWindowById(wx.ID_CANCEL)
        if enabled:
            cancelButton.SetLabel(_extstr(u"Cancel"))  #$NON-NLS-1$
        else:
            cancelButton.SetLabel(_extstr(u"Close"))  #$NON-NLS-1$

    # end _enableButtons()

    def onOK(self, event):
        try:
            self.currentPage.apply()
            self._destroyPages()
        except Exception, e:
            ZShowExceptionMessage(self, e)
        event.Skip()
Esempio n. 12
0
class ZPreferencesDialog(ZHeaderDialog):

    def __init__(self, parent, jumpToPageId = None):
        self.currentSelection = None
        self.currentPage = None
        self.currentPageId = None
        self.pageCache = {}
        style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER
        title = self._getDialogTitle()
        size = self._getInitialSize()
        
        ZHeaderDialog.__init__(self, parent, wx.ID_ANY, title, name = u"PrefsDialog", style = style, size = size) #$NON-NLS-1$

        self._enableButtons(False)
        self.jumpToPage(jumpToPageId)
        self.prefsTreeView.SetFocus()
    # end __init__()
    
    def _getNonHeaderContentBorder(self):
        return 0
    # end _getNonHeaderContentBorder()

    def _createNonHeaderWidgets(self):
        self.splitterWindow = ZSplitterWindow(self)
        self.splitterWindow.SetMinimumPaneSize(100)
        self.splitterWindow.SetSashSize(3)

        self.leftPanel = self._createLeftTreePanel()
        self.currentPage = self._createDefaultPage()
        self.currentPageId = None

        self.splitterWindow.SplitVertically(self.leftPanel, self.currentPage, 175)

        self.lowerStaticLine = wx.StaticLine(self)
    # end _createNonHeaderWidgets()

    def _createLeftTreePanel(self):
        panel = ZTransparentPanel(self.splitterWindow, wx.ID_ANY, style = wx.NO_BORDER)

        # Create the prefs tree view.
        provider = self._createTreeProvider()
        treeStyle = wx.NO_BORDER | wx.TR_HIDE_ROOT | wx.TR_LINES_AT_ROOT | wx.TR_SINGLE | wx.TR_HAS_BUTTONS
        self.prefsTreeView = ZTreeView(provider, panel, style = treeStyle)
        self.prefsTreeView.refresh()
        
        self.treeButtons = self._createTreeButtons(panel)

        # Create a little static vertical line (aesthetic only)
        self.middleStaticLine = wx.StaticLine(panel, style = wx.LI_VERTICAL)

        return panel
    # end _createLeftTreePanel()
    
    def _createTreeButtons(self, parent): #@UnusedVariable
        return []
    # end _createTreeButtons()

    # This is the page created when no pref page is selected.
    def _createDefaultPage(self):
        defaultPrefPage = ZDefaultPreferencePage(self.splitterWindow)
        return defaultPrefPage
    # end _createDefaultPage()

    def _populateNonHeaderWidgets(self):
        self._enableApplyButton(False)
    # end _populateNonHeaderWidgets()

    def _layoutNonHeaderWidgets(self):
        treeSizer = wx.BoxSizer(wx.VERTICAL)
        treeSizer.Add(self.prefsTreeView, 1, wx.EXPAND)
        for button in self.treeButtons:
            treeSizer.Add(button, 0, wx.EXPAND | wx.ALL, 2)
        
        leftPanelSizer = wx.BoxSizer(wx.HORIZONTAL)
        leftPanelSizer.Add(treeSizer, 1, wx.EXPAND)
        leftPanelSizer.Add(self.middleStaticLine, 0, wx.EXPAND)
        self.leftPanel.SetAutoLayout(True)
        self.leftPanel.SetSizer(leftPanelSizer)
        self.leftPanel.Layout()

        verticalSizer = wx.BoxSizer(wx.VERTICAL)
        verticalSizer.Add(self.splitterWindow, 1, wx.EXPAND)
        verticalSizer.Add(self.lowerStaticLine, 0, wx.EXPAND)
        return verticalSizer
    # end _layoutNonHeaderWidgets()

    def _bindWidgetEvents(self):
        self.Bind(wx.EVT_TREE_SEL_CHANGED, self.onTreeItemSelected, self.prefsTreeView)
        self.Bind(wx.EVT_TREE_SEL_CHANGING, self.onTreeItemChanging, self.prefsTreeView)

        self._bindOkButton(self.onOK)
        self._bindCancelButton(self.onCancel)
        self._bindApplyButton(self.onApply)
    # end _bindWidgetEvents()

    def onTreeItemChanging(self, event):
        if self.currentPage is not None:
            if self.currentPage.isDirty():
                # FIXME (EPW) provide override for this message and title
                if not ZShowYesNoMessage(self, _extstr(u"prefsdialog.PrefPageSwitchMessage"), _extstr(u"prefsdialog.DiscardChanges")): #$NON-NLS-2$ #$NON-NLS-1$
                    event.Veto()
                    return
                else:
                    self.currentPage.rollback()
        event.Skip()
    # end onTreeItemChanging()

    def onTreeItemSelected(self, event):
        node = self.prefsTreeView.GetPyData(event.GetItem())
        self.currentSelection = node
        self._updateHeader()
        self._changePreferencePage()

        event.Skip()
    # end onTreeItemSelected()

    # This method is called when the user is changing to a new preference page.
    def _changePreferencePage(self):
        oldPage = self.currentPage
        oldPage.Show(False)

        if self.currentSelection is None:
            self.currentPage = self._createDefaultPage()
            self.currentPage.Show(True)
        elif self.currentSelection in self.pageCache:
            self.currentPage = self.pageCache[self.currentSelection]
            self.currentPage.Show(True)
        else:
            # Construct the preference page.
            self.currentPage = self._createPrefPage(self.splitterWindow, self.currentSelection)
            self.currentPage.setPrefsDialog(self)

            # Create, populate, layout the page.
            self.currentPage.createWidgets()
            self.currentPage.bindWidgetEvents()
            self.currentPage.populateWidgets()
            self.currentPage.layoutWidgets()
            self.pageCache[self.currentSelection] = self.currentPage
        # Call rollback here, which should clear out the page's session
        # and force it to update its visual state (this is useful when one
        # pref page's initial visual state depends on another page's data, 
        # which may have changed since this page was created).
        self.currentPage.rollback()

        self.currentPageId = self._resolveNodeId(self.currentSelection)
        
        self.splitterWindow.ReplaceWindow(oldPage, self.currentPage)
        self.splitterWindow.Layout()
        self.currentPage.Layout()
    # end _changePreferencePage()

    def _getButtonTypes(self):
        return ZBaseDialog.OK_BUTTON | ZBaseDialog.CANCEL_BUTTON | ZBaseDialog.APPLY_BUTTON
    # end _getButtonTypes()

    # Called by the active pref page when the user changes something.
    def onPrefPageChange(self):
        if self.currentPage is not None:
            if self.currentPage.isDirty() and self.currentPage.isValid():
                self._enableButtons(True)
            else:
                self._enableButtons(False)
    # end onPrefPageChange()

    def _enableButtons(self, enabled = True):
        self._enableOkButton(enabled)
        self._enableApplyButton(enabled)
        cancelButton = self.FindWindowById(wx.ID_CANCEL)
        if enabled:
            cancelButton.SetLabel(_extstr(u"Cancel")) #$NON-NLS-1$
        else:
            cancelButton.SetLabel(_extstr(u"Close")) #$NON-NLS-1$
    # end _enableButtons()

    def onOK(self, event):
        try:
            self.currentPage.apply()
            self._destroyPages()
        except Exception, e:
            ZShowExceptionMessage(self, e)
        event.Skip()