Exemplo n.º 1
0
class ZFoldersBrowseView(ZView):

    def __init__(self, parent):
        ZView.__init__(self, parent, wx.ID_ANY)

        self._createWidgets()
        self._layoutWidgets()
        self._populateWidgets()
        self._bindWidgetEvents()

        self._registerAsAccountListener()
    # end __init__()

    def _createWidgets(self):
        self.folderListProvider = ZFolderListProvider()
        self.folderListView = ZListViewEx(self.folderListProvider, self)
    # end _createWidgets()

    def _layoutWidgets(self):
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.folderListView, 1, wx.EXPAND)

        self.SetSizer(sizer)
        self.SetAutoLayout(True)
        self.Layout()
    # end _layoutWidgets()

    def _populateWidgets(self):
        pass
    # end _populateWidgets()

    def _bindWidgetEvents(self):
        self.Bind(ZEVT_VIEW_SELECTION_CHANGED, self.onViewSelection)
        self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.onFolderSelected, self.folderListView)
        self._bindRefreshEvent(self.onZoundryRefresh)
    # end _bindWidgetEvents()

    def onViewSelection(self, event):
        selection = event.getSelection()
        if selection.getType() == IZViewSelectionTypes.BLOG_SELECTION:
            (accountId, blogId) = selection.getData()
            self._refreshListView(accountId, blogId)
        elif selection.getType() == IZViewSelectionTypes.UNPUBLISHED_ACCOUNT_SELECTION:
            self._refreshListView(UNPUBLISHED_ACCOUNT_ID, None)
        elif selection.getType() == IZViewSelectionTypes.ACCOUNT_SELECTION:
            self._refreshListView(None, None)

        event.Skip()
    # end onViewSelection()

    def _refreshListView(self, accountId, blogId):
        self.folderListProvider.setAccountId(accountId)
        self.folderListProvider.setBlogId(blogId)
        self.folderListProvider.refresh()
        self.folderListView.refresh()
        self.folderListView.deselectAll()
    # end _refreshListView()

    def onFolderSelected(self, event):
        folderType = self._getSelectedFolderType()
        if folderType is not None:
            accountId = self.folderListProvider.getAccountId()
            blogId = self.folderListProvider.getBlogId()
            if accountId == UNPUBLISHED_ACCOUNT_ID:
                accountId = None
                blogId = None
            selection = ZViewSelection(folderType, (accountId, blogId))
            fireViewSelectionEvent(selection, self)
        else:
            fireViewUnselectionEvent()
        event.Skip()
    # end onFolderSelected()

    def onZoundryRefresh(self, event):
        self.folderListView.refresh()
        event.Skip()
    # end onZoundryRefresh()

    def onAccountDeleted(self, account):
        if account.getId() == self.folderListProvider.getAccountId():
            self.folderListProvider.setAccountId(None)
            self.folderListProvider.setBlogId(None)
            self.folderListProvider.refresh()
            fireRefreshEvent(self)
    # end onAccountDeleted()

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

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

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

    def _getSelectedFolderType(self):
        itemIndexes = self.folderListView.getSelection()
        if itemIndexes:
            itemIndex = itemIndexes[0]
            return self.folderListProvider.getFolderType(itemIndex)
        return None
Exemplo n.º 2
0
class ZBlogBrowseView(ZView, IZAccountStoreListener):
    def __init__(self, parent):
        ZView.__init__(self, parent, wx.ID_ANY)

        self._createWidgets()
        self._layoutWidgets()
        self._populateWidgets()
        self._bindWidgetEvents()

        self._registerAsAccountListener()

    # end __init__()

    def _createWidgets(self):
        self.blogListProvider = ZBlogListProvider()
        self.blogListView = ZListViewEx(self.blogListProvider, self)

    # end _createWidgets()

    def _layoutWidgets(self):
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.blogListView, 1, wx.EXPAND)

        self.SetSizer(sizer)
        self.SetAutoLayout(True)
        self.Layout()

    # end _layoutWidgets()

    def _populateWidgets(self):
        pass

    # end _populateWidgets()

    def _bindWidgetEvents(self):
        self.Bind(ZEVT_VIEW_SELECTION_CHANGED, self.onViewSelection)
        self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.onBlogSelected,
                  self.blogListView)
        self.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.onBlogRightClick,
                  self.blogListView)
        self._bindRefreshEvent(self.onZoundryRefresh)

    # end _bindWidgetEvents()

    def onBlogRightClick(self, event):
        blog = self._getSelectedBlog()
        if blog is not None:
            menu = self._createBlogCtxMenu(blog)
            self.PopupMenu(menu)
            menu.Destroy()
        event.Skip()

    # end onBlogRightClick()

    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 onViewSelection(self, event):
        selection = event.getSelection()
        if selection.getType() == IZViewSelectionTypes.ACCOUNT_SELECTION:
            accountId = selection.getData()
            self.blogListProvider.setAccountId(accountId)
            self.blogListProvider.refresh()
            self.blogListView.refresh()
            self.blogListView.deselectAll()
        elif selection.getType(
        ) == IZViewSelectionTypes.UNPUBLISHED_ACCOUNT_SELECTION:
            self.blogListProvider.setAccountId(None)
            self.blogListProvider.refresh()
            self.blogListView.refresh()
            self.blogListView.deselectAll()

        event.Skip()

    # end onViewSelection()

    def onBlogSelected(self, event):
        blog = self._getSelectedBlog()
        if blog is not None:
            account = blog.getAccount()
            accountId = account.getId()
            blogId = blog.getId()
            selection = ZViewSelection(IZViewSelectionTypes.BLOG_SELECTION,
                                       (accountId, blogId))
            fireViewSelectionEvent(selection, self)
        else:
            fireViewUnselectionEvent()
        event.Skip()

    # end onBlogSelected()

    def onZoundryRefresh(self, event):
        self.blogListView.refresh()
        event.Skip()

    # end onZoundryRefresh()

    def onAccountChanged(self, account):
        if account.getId() == self.blogListProvider.getAccountId():
            self.blogListProvider.refresh()
            fireRefreshEvent(self)

    # end onAccountChanged()

    def onAccountDeleted(self, account):
        if account.getId() == self.blogListProvider.getAccountId():
            self.blogListProvider.setAccountId(None)
            self.blogListProvider.refresh()
            fireRefreshEvent(self)

    # end onAccountDeleted()

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

    # end _registerAsAccountListener()

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

    # end _unregisterAsAccountListener()

    def destroy(self):
        self._unregisterAsAccountListener()

    # end destroy()

    def _getSelectedBlog(self):
        itemIndexes = self.blogListView.getSelection()
        if itemIndexes:
            itemIndex = itemIndexes[0]
            return self.blogListProvider.getBlogAtIndex(itemIndex)
        return None
Exemplo n.º 3
0
class ZBlogPostsView(ZBoxedView, IZDocumentIndexListener):
    def __init__(self, parent):
        filter = ZDocumentSearchFilter()
        filter.setAccountIdCriteria(
            IZDocumentSearchFilter.UNPUBLISHED_ACCOUNT_ID)
        filter.setBlogIdCriteria(IZDocumentSearchFilter.UNPUBLISHED_BLOG_ID)
        self.model = ZContextInfoPostsModel(filter)
        self.openAction = getApplicationModel().getActionRegistry().findAction(
            IZBlogAppActionIDs.OPEN_BLOG_POST_ACTION)
        self.blogPostContextMenu = ZBlogPostMenuModel()
        self.postsAccelTable = ZBlogPostsListAcceleratorTable(self)
        self.document = None
        self.blog = None
        self.hasFocus = False

        self.indexService = getApplicationModel().getService(
            IZBlogAppServiceIDs.DOCUMENT_INDEX_SERVICE_ID)
        self.docStore = getApplicationModel().getService(
            IZBlogAppServiceIDs.DATA_STORE_SERVICE_ID)
        self.accountStore = getApplicationModel().getService(
            IZBlogAppServiceIDs.ACCOUNT_STORE_SERVICE_ID)

        ZBoxedView.__init__(self, parent)

        self._registerAsIndexListener()

    # end __init__()

    def getViewId(self):
        return IZViewIds.POSTS_LIST_VIEW

    # end getViewId()

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

    # end _getHeaderBitmap()

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

    # end _getHeaderLabel()

    def _createHeaderWidgets(self, parent, widgetList):
        self.viewLabel = wx.StaticText(
            parent, wx.ID_ANY, _extstr(u"postsview.Filter"))  #$NON-NLS-1$
        choices = self._getViewChoices()
        self.viewCombo = wx.ComboBox(parent,
                                     wx.ID_ANY,
                                     _extstr(u"postsview.All"),
                                     style=wx.CB_READONLY,
                                     choices=choices)  #$NON-NLS-1$
        choices = self._getSearchBoxChoices()
        bitmap = getResourceRegistry().getBitmap(
            u"images/perspectives/standard/contextinfo/postsview/search.png"
        )  #$NON-NLS-1$
        self.searchTextBox = ZAdvancedTextBox(parent, bitmap, choices, False)
        self.searchTextBox.setCurrentChoice(SEARCH_TB_TITLE)
        self.searchTextBox.SetSizeHints(220, -1)

        widgetList.append(self.viewLabel)
        widgetList.append(self.viewCombo)
        widgetList.append(self.searchTextBox)

    # end _createHeaderWidgets()

    def _createContentWidgets(self, parent):
        provider = ZBlogEntryListContentProvider(self.model)
        style = wx.LC_VIRTUAL | wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.NO_BORDER
        self.entriesListView = ZListViewEx(provider, parent, style=style)
        self.entriesListView.SetAcceleratorTable(self.postsAccelTable)

    # end _createContentWidgets()

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

    # end _layoutContentWidgets()

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

        self.postsAccelTable.bindTo(self.entriesListView)

        self.Bind(ZEVT_REFRESH, self.onZoundryRefresh, self)
        self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.onEntryActivated,
                  self.entriesListView)
        self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.onEntrySelected,
                  self.entriesListView)
        self.Bind(wx.EVT_LIST_BEGIN_DRAG, self.onEntryBeginDrag,
                  self.entriesListView)
        self.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.onEntryRightClick,
                  self.entriesListView)
        self.Bind(wx.EVT_COMBOBOX, self.onViewCombo, self.viewCombo)
        self.Bind(wx.EVT_TEXT_ENTER, self.onSearchText, self.searchTextBox)
        self.Bind(ZEVT_VIEW_SELECTION_CHANGED, self.onViewSelectionChanged)
        wx.EVT_SET_FOCUS(self.entriesListView, self.onFocus)
        wx.EVT_KILL_FOCUS(self.entriesListView, self.onUnFocus)

    # end _bindWidgetEvents()

    def refreshContent(self, selection):
        isUnselecting = False
        if self.entriesListView.getSelection():
            isUnselecting = True

        (accountId, blogId) = selection.getData()

        filter = ZDocumentSearchFilter()
        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(
                IZDocumentSearchFilter.UNPUBLISHED_ACCOUNT_ID)
            filter.setBlogIdCriteria(
                IZDocumentSearchFilter.UNPUBLISHED_BLOG_ID)

        self.model = ZContextInfoPostsModel(filter)
        self.entriesListView.setContentProvider(
            ZBlogEntryListContentProvider(self.model))
        self.entriesListView.refresh()
        self.entriesListView.deselectAll()
        self.onInvalidSelection()
        if isUnselecting:
            fireViewUnselectionEvent()

    # end refreshContent()

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

    # end onViewSelectionChanged()

    def onFocus(self, event):
        if not self.hasFocus:
            if self.document:
                fireViewSelectionEvent(
                    ZDocumentSelection(self.document, self.blog), self)
            else:
                fireViewUnselectionEvent()
            self.hasFocus = True
        event.Skip()

    # end onFocus()

    def onUnFocus(self, event):
        if self.hasFocus:
            fireViewUnselectionEvent()
            self.hasFocus = False
        event.Skip()

    # end onUnFocus()

    def onViewCombo(self, event):
        choice = event.GetSelection()
        self.model.clearDraftCriteria()
        self.model.clearDateRangeCriteria()
        if choice == VIEW_CHOICE_DRAFTS:
            self.model.setDraftCriteria()
        elif choice == VIEW_CHOICE_PUBLISHED:
            self.model.setDraftCriteria(False)
        elif choice == VIEW_CHOICE_TODAY:
            dateRange = getRangeForToday()
            self.model.setDateRangeCriteria(dateRange.getStartDate(),
                                            dateRange.getEndDate())
        elif choice == VIEW_CHOICE_YESTERDAY:
            dateRange = getRangeForYesterday()
            self.model.setDateRangeCriteria(dateRange.getStartDate(),
                                            dateRange.getEndDate())
        elif choice == VIEW_CHOICE_THISWEEK:
            dateRange = getRangeForThisWeek()
            self.model.setDateRangeCriteria(dateRange.getStartDate(),
                                            dateRange.getEndDate())
        elif choice == VIEW_CHOICE_THISMONTH:
            dateRange = getRangeForThisMonth()
            self.model.setDateRangeCriteria(dateRange.getStartDate(),
                                            dateRange.getEndDate())
        self.model.refresh()
        self.entriesListView.refresh()
        self.entriesListView.deselectAll()
        self.onInvalidSelection()

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

    # end onViewCombo()

    def onSearchText(self, event):
        self.model.setTitleCriteria(event.GetString())
        self.model.refresh()
        self.entriesListView.refresh()
        self.entriesListView.deselectAll()
        self.onInvalidSelection()

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

    # end onSearchText()

    def onEntryBeginDrag(self, event):
        index = event.GetIndex()
        docIDO = self.model.getEntry(index)
        docId = docIDO.getId()

        # FIXME (EPW) also add some sort of custom format for dragging to the Explorer/TextPad (use a composite data object)
        data = wx.DataObjectComposite()
        #        url = self._getUrlFromDocIDO(docIDO)
        #        if url is not None:
        #            data.Add(ZURLDataObject(url))
        data.Add(ZBlogPostDataObjectInternal(docId))
        #        data.Add(wx.TextDataObject(str(convertToUtf8(u"Hello World"))))

        dragSource = wx.DropSource(self)
        dragSource.SetData(data)
        dragSource.DoDragDrop(wx.Drag_CopyOnly)
        event.Skip()

    # end onEntryBeginDrag()

    def _updateModel(self, refreshData):
        (eventType, documentIDO) = refreshData
        shouldRefresh = False
        if eventType == IZDocIndexEvent.DOCINDEX_EVENTTYPE_ADD:
            shouldRefresh = self.model.addEntry(documentIDO)
        elif eventType == IZDocIndexEvent.DOCINDEX_EVENTTYPE_REMOVE:
            shouldRefresh = self.model.removeEntry(documentIDO)
        elif eventType == IZDocIndexEvent.DOCINDEX_EVENTTYPE_UPDATE:
            shouldRefresh = self.model.updateEntry(documentIDO)
        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_DOCUMENT:
            refreshData = (event.getEventType(), event.getDocumentIDO())
            fireRefreshEvent(self, refreshData)

    # end onIndexChange()

    def onZoundryRefresh(self, event):  #@UnusedVariable
        if self._updateModel(event.getData()):
            self.entriesListView.refresh()
            selection = self.entriesListView.getSelection()
            if not selection:
                self.onInvalidSelection()
                fireViewUnselectionEvent()
            else:
                selIdx = selection[0]
                newDocIDO = self.model.getEntry(selIdx)
                newDoc = self.docStore.getDocument(newDocIDO.getId())
                self.document = newDoc
                fireViewSelectionEvent(
                    ZDocumentSelection(self.document, self.blog), self)
        event.Skip()

    # end onZoundryRefresh()

    def onEntryRightClick(self, event):
        index = event.GetIndex()
        docIDO = self.model.getEntry(index)
        blogId = None
        if self.blog is not None:
            blogId = self.blog.getId()
        actionContext = ZBlogPostActionContext(self, docIDO, blogId)
        provider = ZModelBasedMenuContentProvider(self.blogPostContextMenu,
                                                  actionContext)
        handler = ZModelBasedMenuEventHandler(self.blogPostContextMenu,
                                              actionContext)
        menu = ZMenu(self, self.blogPostContextMenu.getRootNode(), provider,
                     handler)
        self.PopupMenu(menu)
        event.Skip()

    # end onEntryRightClick()

    def onEntryActivated(self, event):
        index = event.GetIndex()
        docIDO = self.model.getEntry(index)
        blogId = None
        if self.blog is not None:
            blogId = self.blog.getId()
        actionContext = ZBlogPostActionContext(self, docIDO, blogId)
        self.openAction.runAction(actionContext)
        event.Skip()

    # end onEntryActivated()

    def onEntrySelected(self, event):
        index = event.GetIndex()
        docIDO = self.model.getEntry(index)
        docId = docIDO.getId()
        self.document = self.docStore.getDocument(docId)

        if self.document:
            fireViewSelectionEvent(
                ZDocumentSelection(self.document, self.blog), self)
        else:
            fireViewUnselectionEvent()

        event.Skip()

    # end onEntrySelected()

    def onInvalidSelection(self):
        self.document = None

    # end onInvalidSelection()

    def createActionContext(self):
        docIDO = None
        blogId = None
        selection = self.entriesListView.getSelection()
        if selection:
            index = selection[0]
            docIDO = self.model.getEntry(index)
            if self.blog is not None:
                blogId = self.blog.getId()
        return ZBlogPostActionContext(self, docIDO, blogId)

    # end createActionContext()

    def destroy(self):
        self._unregisterAsIndexListener()

    # end destroy()

    def _getViewChoices(self):
        return [
            _extstr(u"postsview.All"),  #$NON-NLS-1$
            _extstr(u"postsview.Drafts"),  #$NON-NLS-1$
            _extstr(u"postsview.Published"),  #$NON-NLS-1$
            _extstr(u"postsview.Today"),  #$NON-NLS-1$
            u"-----------",  #$NON-NLS-1$
            _extstr(u"postsview.Yesterday"),  #$NON-NLS-1$
            _extstr(u"postsview.ThisWeek"),  #$NON-NLS-1$
            _extstr(u"postsview.ThisMonth")  #$NON-NLS-1$
        ]

    # end _getViewChoices()

    def _getSearchBoxChoices(self):
        return [
            (_extstr(u"postsview.Title"), None, SEARCH_TB_TITLE),  #$NON-NLS-1$
        ]

    # end _getSearchBoxChoices()

    def _getUrlFromDocIDO(self, docIDO):
        url = None
        if self.blog is not None:
            pdIDO = docIDO.getPubDataIDO(self.blog.getId())
            if pdIDO is not None:
                url = pdIDO.getUrl()
        return url

    # end _getUrlFromDocIDO()

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

    # end _registerAsIndexListener()

    def _unregisterAsIndexListener(self):
        self.indexService.removeListener(self)
Exemplo n.º 4
0
class ZFoldersBrowseView(ZView):

    def __init__(self, parent):
        ZView.__init__(self, parent, wx.ID_ANY)

        self._createWidgets()
        self._layoutWidgets()
        self._populateWidgets()
        self._bindWidgetEvents()

        self._registerAsAccountListener()
    # end __init__()

    def _createWidgets(self):
        self.folderListProvider = ZFolderListProvider()
        self.folderListView = ZListViewEx(self.folderListProvider, self)
    # end _createWidgets()

    def _layoutWidgets(self):
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.folderListView, 1, wx.EXPAND)

        self.SetSizer(sizer)
        self.SetAutoLayout(True)
        self.Layout()
    # end _layoutWidgets()

    def _populateWidgets(self):
        pass
    # end _populateWidgets()

    def _bindWidgetEvents(self):
        self.Bind(ZEVT_VIEW_SELECTION_CHANGED, self.onViewSelection)
        self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.onFolderSelected, self.folderListView)
        self._bindRefreshEvent(self.onZoundryRefresh)
    # end _bindWidgetEvents()

    def onViewSelection(self, event):
        selection = event.getSelection()
        if selection.getType() == IZViewSelectionTypes.BLOG_SELECTION:
            (accountId, blogId) = selection.getData()
            self._refreshListView(accountId, blogId)
        elif selection.getType() == IZViewSelectionTypes.UNPUBLISHED_ACCOUNT_SELECTION:
            self._refreshListView(UNPUBLISHED_ACCOUNT_ID, None)
        elif selection.getType() == IZViewSelectionTypes.ACCOUNT_SELECTION:
            self._refreshListView(None, None)

        event.Skip()
    # end onViewSelection()

    def _refreshListView(self, accountId, blogId):
        self.folderListProvider.setAccountId(accountId)
        self.folderListProvider.setBlogId(blogId)
        self.folderListProvider.refresh()
        self.folderListView.refresh()
        self.folderListView.deselectAll()
    # end _refreshListView()

    def onFolderSelected(self, event):
        folderType = self._getSelectedFolderType()
        if folderType is not None:
            accountId = self.folderListProvider.getAccountId()
            blogId = self.folderListProvider.getBlogId()
            if accountId == UNPUBLISHED_ACCOUNT_ID:
                accountId = None
                blogId = None
            selection = ZViewSelection(folderType, (accountId, blogId))
            fireViewSelectionEvent(selection, self)
        else:
            fireViewUnselectionEvent()
        event.Skip()
    # end onFolderSelected()

    def onZoundryRefresh(self, event):
        self.folderListView.refresh()
        event.Skip()
    # end onZoundryRefresh()

    def onAccountDeleted(self, account):
        if account.getId() == self.folderListProvider.getAccountId():
            self.folderListProvider.setAccountId(None)
            self.folderListProvider.setBlogId(None)
            self.folderListProvider.refresh()
            fireRefreshEvent(self)
    # end onAccountDeleted()

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

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

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

    def _getSelectedFolderType(self):
        itemIndexes = self.folderListView.getSelection()
        if itemIndexes:
            itemIndex = itemIndexes[0]
            return self.folderListProvider.getFolderType(itemIndex)
        return None
Exemplo n.º 5
0
class ZTemplateManagerWindow(ZBaseWindow, ZPersistentDialogMixin, IZTemplateServiceListener):

    def __init__(self, parent):
        self.model = ZTemplateManagerModel()
        self.selectedTemplate = None

        style = wx.DEFAULT_FRAME_STYLE | wx.FULL_REPAINT_ON_RESIZE | wx.CLIP_CHILDREN
        ZBaseWindow.__init__(self, parent, _extstr(u"templatemanager.BlogTemplateManager"), name = u"ZTemplateManager", style = style) #$NON-NLS-2$ #$NON-NLS-1$
        ZPersistentDialogMixin.__init__(self, IZBlogAppUserPrefsKeys.TEMPLATE_WINDOW)
        self.Layout()

        self._installListener()
    # end __init__()

    def getModel(self):
        return self.model
    # end getModel()

    def _createWindowWidgets(self, parent):
        self.headerPanel = self._createHeaderPanel(parent)
        self.headerStaticLine = wx.StaticLine(parent, wx.ID_ANY)

        self.splitterWindow = ZSplitterWindow(parent)
        self.splitterWindow.SetSizeHints(700, 600)

        self.topPanel = ZTransparentPanel(self.splitterWindow, wx.ID_ANY)
        self.topStaticBox = wx.StaticBox(self.topPanel, wx.ID_ANY, _extstr(u"templatemanager.Templates")) #$NON-NLS-1$

        provider = ZTemplateListProvider(self.model)
        self.templateList = ZListViewEx(provider, self.topPanel)

        self.addButton = wx.Button(self.topPanel, wx.ID_ANY, _extstr(u"templatemanager.Add")) #$NON-NLS-1$
        self.removeButton = wx.Button(self.topPanel, wx.ID_ANY, _extstr(u"templatemanager.Remove")) #$NON-NLS-1$
        self.removeButton.Enable(False)

        self.preview = ZHTMLViewControl(self.splitterWindow, wx.ID_ANY, style = wx.NO_FULL_REPAINT_ON_RESIZE | wx.SIMPLE_BORDER)

        self.splitterWindow.SetSashSize(10)
        self.splitterWindow.SplitHorizontally(self.topPanel, self.preview, 150)
        self.splitterWindow.SetMinimumPaneSize(100)

        self.statusBar = self._createStatusBar()
        self.SetStatusBar(self.statusBar)
    # end _createWindowWidgets()

    def _createHeaderPanel(self, parent):
        panel = wx.Panel(parent, wx.ID_ANY)
        panel.SetBackgroundColour(wx.WHITE)

        self.headerLink = wx.HyperlinkCtrl(panel, wx.ID_ANY, self._getHeaderTitle(), self._getHeaderHelpURL())
        self.headerLink.SetFont(getDefaultFontBold())
        self.headerMessage = wx.StaticText(panel, wx.ID_ANY, self._getHeaderMessage())
        headerImagePath = self._getHeaderImagePath()
        if not headerImagePath:
            headerImagePath = u"images/dialogs/image/header_image.png" #$NON-NLS-1$
        self.headerIcon = ZStaticBitmap(panel, getResourceRegistry().getBitmap(headerImagePath))

        linkAndMsgSizer = wx.BoxSizer(wx.VERTICAL)
        linkAndMsgSizer.Add(self.headerLink, 0, wx.ALL, 2)
        linkAndMsgSizer.Add(self.headerMessage, 1, wx.EXPAND | wx.ALL, 2)

        sizer = wx.BoxSizer(wx.HORIZONTAL)
        sizer.AddSizer(linkAndMsgSizer, 1, wx.EXPAND | wx.ALL, 5)
        sizer.Add(self.headerIcon, 0, wx.EXPAND | wx.ALL, 10)

        panel.SetAutoLayout(True)
        panel.SetSizer(sizer)

        return panel
    # end _createHeaderPanel()

    def _createStatusBar(self):
        self.statusBarModel = ZStatusBarModel()
        self.statusBarModel.addPane(u"name") #$NON-NLS-1$
        self.statusBarModel.setPaneWidth(u"name", 1) #$NON-NLS-1$
        self.statusBarModel.setPaneText(u"name", u"") #$NON-NLS-1$ #$NON-NLS-2$
        provider = ZStatusBarModelBasedContentProvider(self.statusBarModel)
        statusBar = ZStatusBar(self, provider)
        return statusBar
    # end _createStatusBar()

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

    def _layoutWindowWidgets(self):
        staticBoxSizer = wx.StaticBoxSizer(self.topStaticBox, wx.VERTICAL)
        staticBoxSizer.Add(self.templateList, 1, wx.ALL | wx.EXPAND, 3)
        buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
        buttonSizer.Add(self.addButton, 0, wx.ALL | wx.EXPAND, 2)
        buttonSizer.Add(self.removeButton, 0, wx.ALL | wx.EXPAND, 2)
        staticBoxSizer.AddSizer(buttonSizer, 0, wx.ALL | wx.EXPAND, 2)

        self.topPanel.SetSizer(staticBoxSizer)
        self.topPanel.SetAutoLayout(True)

        sizer = wx.BoxSizer(wx.VERTICAL)

        sizer.Add(self.headerPanel, 0, wx.EXPAND | wx.ALL, 0)
        sizer.Add(self.headerStaticLine, 0, wx.EXPAND | wx.ALL, 0)
        sizer.Add(self.splitterWindow, 1, wx.EXPAND | wx.ALL, 5)

        return sizer
    # end _layoutWindowWidgets()

    def _bindWidgetEvents(self):
        self.Bind(wx.EVT_BUTTON, self.onAdd, self.addButton)
        self.Bind(wx.EVT_BUTTON, self.onRemove, self.removeButton)
        self.Bind(wx.EVT_CLOSE, self.onClose, self)
        self.Bind(ZEVT_REFRESH, self.onRefresh, self)
        self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.onTemplateSelected, self.templateList)
        self.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.onTemplateRightClick, self.templateList)
    # end _bindWidgetEvents()

    def onRefresh(self, event):
        self.templateList.Refresh()
        event.Skip()
    # end onRefresh()

    def onAdd(self, event):
        action = ZAddTemplateFromBlogAction()
        action.runAction(ZTemplateManagerActionContext(self, self.selectedTemplate))
        event.Skip()
    # end onAdd()

    def onRemove(self, event):
        action = ZRemoveTemplateAction()
        action.runAction(ZTemplateManagerActionContext(self, self.selectedTemplate))
        event.Skip()
    # end onRemove()

    def onTemplateSelected(self, event):
        self.selectedTemplate = self.model.getTemplates()[event.GetItem().GetId()]
        self.removeButton.Enable(True)
        self.refresh()
        event.Skip()
    # end onTemplateSelected()

    def onTemplateRightClick(self, event):
        event.Skip()
    # end onTemplateRightClick()

    def _setInitialFocus(self):
        pass
    # end _setInitialFocus()

    def refresh(self):
        self.templateList.refresh()
        self.statusBar.refresh()
        if self.selectedTemplate is not None:
            document = self.model.getSampleDocument()
            xhtmlDoc = applyTemplateToDocument(self.selectedTemplate, document, APPLY_TEMPLATE_MODE_FULL)
            disableTemplatePreviewJavaScript(xhtmlDoc)
        else:
            xhtmlDoc = loadXhtmlDocumentFromString(u"Select a template to view a preview of it.") #$NON-NLS-1$
        self.preview.setXhtmlDocument(xhtmlDoc, False)
    # end refresh()

    def _getHeaderTitle(self):
        return _extstr(u"templatemanager.BlogTemplateManager") #$NON-NLS-1$
    # end _getHeaderTitle()

    def _getHeaderMessage(self):
        return _extstr(u"templatemanager.BlogTemplateManagerDescription") #$NON-NLS-1$
    # end _getHeaderMessage()

    def _getHeaderImagePath(self):
        return u"images/dialogs/template/manager/header_image.png" #$NON-NLS-1$
    # end _getHeaderImagePath()

    def _getHeaderHelpURL(self):
        return u"http://www.zoundry.com" #$NON-NLS-1$
    # end _getHeaderHelpUrl()

    def onClose(self, event):
        global TEMPLATE_MANAGER_WINDOW
        TEMPLATE_MANAGER_WINDOW = None

        self._uninstallListener()

        event.Skip()
    # end onClose()

    def _installListener(self):
        self.model.getService().addListener(self)
    # end _installListener()

    def _uninstallListener(self):
        self.model.getService().removeListener(self)
    # end _uninstallListener()

    def onTemplateCreated(self, template): #@UnusedVariable
        fireUIExecEvent(ZMethodRunnable(self.refresh), self)
    # end onTemplateCreated()

    def onTemplateDeleted(self, template):
        if self.selectedTemplate.getId() == template.getId():
            self.selectedTemplate = None

        self.refresh()
        self.templateList.deselectAll()
        self.removeButton.Enable(False)
    # end onTemplateDeleted()

    def onTemplateModified(self, template): #@UnusedVariable
        fireUIExecEvent(ZMethodRunnable(self.refresh), self)
Exemplo n.º 6
0
class ZBlogPostsView(ZBoxedView, IZDocumentIndexListener):

    def __init__(self, parent):
        filter = ZDocumentSearchFilter()
        filter.setAccountIdCriteria(IZDocumentSearchFilter.UNPUBLISHED_ACCOUNT_ID)
        filter.setBlogIdCriteria(IZDocumentSearchFilter.UNPUBLISHED_BLOG_ID)
        self.model = ZContextInfoPostsModel(filter)
        self.openAction = getApplicationModel().getActionRegistry().findAction(IZBlogAppActionIDs.OPEN_BLOG_POST_ACTION)
        self.blogPostContextMenu = ZBlogPostMenuModel()
        self.postsAccelTable = ZBlogPostsListAcceleratorTable(self)
        self.document = None
        self.blog = None
        self.hasFocus = False

        self.indexService = getApplicationModel().getService(IZBlogAppServiceIDs.DOCUMENT_INDEX_SERVICE_ID)
        self.docStore = getApplicationModel().getService(IZBlogAppServiceIDs.DATA_STORE_SERVICE_ID)
        self.accountStore = getApplicationModel().getService(IZBlogAppServiceIDs.ACCOUNT_STORE_SERVICE_ID)

        ZBoxedView.__init__(self, parent)

        self._registerAsIndexListener()
    # end __init__()

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

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

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

    def _createHeaderWidgets(self, parent, widgetList):
        self.viewLabel = wx.StaticText(parent, wx.ID_ANY, _extstr(u"postsview.Filter")) #$NON-NLS-1$
        choices = self._getViewChoices()
        self.viewCombo = wx.ComboBox(parent, wx.ID_ANY, _extstr(u"postsview.All"), style = wx.CB_READONLY, choices = choices) #$NON-NLS-1$
        choices = self._getSearchBoxChoices()
        bitmap = getResourceRegistry().getBitmap(u"images/perspectives/standard/contextinfo/postsview/search.png") #$NON-NLS-1$
        self.searchTextBox = ZAdvancedTextBox(parent, bitmap, choices, False)
        self.searchTextBox.setCurrentChoice(SEARCH_TB_TITLE)
        self.searchTextBox.SetSizeHints(220, -1)

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

    def _createContentWidgets(self, parent):
        provider = ZBlogEntryListContentProvider(self.model)
        style = wx.LC_VIRTUAL | wx.LC_REPORT | wx.LC_SINGLE_SEL | wx.NO_BORDER
        self.entriesListView = ZListViewEx(provider, parent, style = style)
        self.entriesListView.SetAcceleratorTable(self.postsAccelTable)
    # end _createContentWidgets()

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

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

        self.postsAccelTable.bindTo(self.entriesListView)

        self.Bind(ZEVT_REFRESH, self.onZoundryRefresh, self)
        self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.onEntryActivated, self.entriesListView)
        self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.onEntrySelected, self.entriesListView)
        self.Bind(wx.EVT_LIST_BEGIN_DRAG, self.onEntryBeginDrag, self.entriesListView)
        self.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.onEntryRightClick, self.entriesListView)
        self.Bind(wx.EVT_COMBOBOX, self.onViewCombo, self.viewCombo)
        self.Bind(wx.EVT_TEXT_ENTER, self.onSearchText, self.searchTextBox)
        self.Bind(ZEVT_VIEW_SELECTION_CHANGED, self.onViewSelectionChanged)
        wx.EVT_SET_FOCUS(self.entriesListView, self.onFocus)
        wx.EVT_KILL_FOCUS(self.entriesListView, self.onUnFocus)
    # end _bindWidgetEvents()

    def refreshContent(self, selection):
        isUnselecting = False
        if self.entriesListView.getSelection():
            isUnselecting = True

        (accountId, blogId) = selection.getData()

        filter = ZDocumentSearchFilter()
        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(IZDocumentSearchFilter.UNPUBLISHED_ACCOUNT_ID)
            filter.setBlogIdCriteria(IZDocumentSearchFilter.UNPUBLISHED_BLOG_ID)

        self.model = ZContextInfoPostsModel(filter)
        self.entriesListView.setContentProvider(ZBlogEntryListContentProvider(self.model))
        self.entriesListView.refresh()
        self.entriesListView.deselectAll()
        self.onInvalidSelection()
        if isUnselecting:
            fireViewUnselectionEvent()
    # end refreshContent()

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

    def onFocus(self, event):
        if not self.hasFocus:
            if self.document:
                fireViewSelectionEvent(ZDocumentSelection(self.document, self.blog), self)
            else:
                fireViewUnselectionEvent()
            self.hasFocus = True
        event.Skip()
    # end onFocus()

    def onUnFocus(self, event):
        if self.hasFocus:
            fireViewUnselectionEvent()
            self.hasFocus = False
        event.Skip()
    # end onUnFocus()

    def onViewCombo(self, event):
        choice = event.GetSelection()
        self.model.clearDraftCriteria()
        self.model.clearDateRangeCriteria()
        if choice == VIEW_CHOICE_DRAFTS:
            self.model.setDraftCriteria()
        elif choice == VIEW_CHOICE_PUBLISHED:
            self.model.setDraftCriteria(False)
        elif choice == VIEW_CHOICE_TODAY:
            dateRange = getRangeForToday()
            self.model.setDateRangeCriteria(dateRange.getStartDate(), dateRange.getEndDate())
        elif choice == VIEW_CHOICE_YESTERDAY:
            dateRange = getRangeForYesterday()
            self.model.setDateRangeCriteria(dateRange.getStartDate(), dateRange.getEndDate())
        elif choice == VIEW_CHOICE_THISWEEK:
            dateRange = getRangeForThisWeek()
            self.model.setDateRangeCriteria(dateRange.getStartDate(), dateRange.getEndDate())
        elif choice == VIEW_CHOICE_THISMONTH:
            dateRange = getRangeForThisMonth()
            self.model.setDateRangeCriteria(dateRange.getStartDate(), dateRange.getEndDate())
        self.model.refresh()
        self.entriesListView.refresh()
        self.entriesListView.deselectAll()
        self.onInvalidSelection()

        fireViewEvent(ZViewEvent(VIEWBLOGPOSTSFILTERCHANGEDEVENT, self))
        event.Skip()
    # end onViewCombo()

    def onSearchText(self, event):
        self.model.setTitleCriteria(event.GetString())
        self.model.refresh()
        self.entriesListView.refresh()
        self.entriesListView.deselectAll()
        self.onInvalidSelection()

        fireViewEvent(ZViewEvent(VIEWBLOGPOSTSFILTERCHANGEDEVENT, self))
        event.Skip()
    # end onSearchText()

    def onEntryBeginDrag(self, event):
        index = event.GetIndex()
        docIDO = self.model.getEntry(index)
        docId = docIDO.getId()

        # FIXME (EPW) also add some sort of custom format for dragging to the Explorer/TextPad (use a composite data object)
        data = wx.DataObjectComposite()
#        url = self._getUrlFromDocIDO(docIDO)
#        if url is not None:
#            data.Add(ZURLDataObject(url))
        data.Add(ZBlogPostDataObjectInternal(docId))
#        data.Add(wx.TextDataObject(str(convertToUtf8(u"Hello World"))))

        dragSource = wx.DropSource(self)
        dragSource.SetData(data)
        dragSource.DoDragDrop(wx.Drag_CopyOnly)
        event.Skip()
    # end onEntryBeginDrag()

    def _updateModel(self, refreshData):
        (eventType, documentIDO) = refreshData
        shouldRefresh = False
        if eventType == IZDocIndexEvent.DOCINDEX_EVENTTYPE_ADD:
            shouldRefresh = self.model.addEntry(documentIDO)
        elif eventType == IZDocIndexEvent.DOCINDEX_EVENTTYPE_REMOVE:
            shouldRefresh = self.model.removeEntry(documentIDO)
        elif eventType == IZDocIndexEvent.DOCINDEX_EVENTTYPE_UPDATE:
            shouldRefresh = self.model.updateEntry(documentIDO)
        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_DOCUMENT:
            refreshData = (event.getEventType(), event.getDocumentIDO())
            fireRefreshEvent(self, refreshData)
    # end onIndexChange()

    def onZoundryRefresh(self, event): #@UnusedVariable
        if self._updateModel(event.getData()):
            self.entriesListView.refresh()
            selection = self.entriesListView.getSelection()
            if not selection:
                self.onInvalidSelection()
                fireViewUnselectionEvent()
            else:
                selIdx = selection[0]
                newDocIDO = self.model.getEntry(selIdx)
                newDoc = self.docStore.getDocument(newDocIDO.getId())
                self.document = newDoc
                fireViewSelectionEvent(ZDocumentSelection(self.document, self.blog), self)
        event.Skip()
    # end onZoundryRefresh()

    def onEntryRightClick(self, event):
        index = event.GetIndex()
        docIDO = self.model.getEntry(index)
        blogId = None
        if self.blog is not None:
            blogId = self.blog.getId()
        actionContext = ZBlogPostActionContext(self, docIDO, blogId)
        provider = ZModelBasedMenuContentProvider(self.blogPostContextMenu, actionContext)
        handler = ZModelBasedMenuEventHandler(self.blogPostContextMenu, actionContext)
        menu = ZMenu(self, self.blogPostContextMenu.getRootNode(), provider, handler)
        self.PopupMenu(menu)
        event.Skip()
    # end onEntryRightClick()

    def onEntryActivated(self, event):
        index = event.GetIndex()
        docIDO = self.model.getEntry(index)
        blogId = None
        if self.blog is not None:
            blogId = self.blog.getId()
        actionContext = ZBlogPostActionContext(self, docIDO, blogId)
        self.openAction.runAction(actionContext)
        event.Skip()
    # end onEntryActivated()

    def onEntrySelected(self, event):
        index = event.GetIndex()
        docIDO = self.model.getEntry(index)
        docId = docIDO.getId()
        self.document = self.docStore.getDocument(docId)

        if self.document:
            fireViewSelectionEvent(ZDocumentSelection(self.document, self.blog), self)
        else:
            fireViewUnselectionEvent()

        event.Skip()
    # end onEntrySelected()

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

    def createActionContext(self):
        docIDO = None
        blogId = None
        selection = self.entriesListView.getSelection()
        if selection:
            index = selection[0]
            docIDO = self.model.getEntry(index)
            if self.blog is not None:
                blogId = self.blog.getId()
        return ZBlogPostActionContext(self, docIDO, blogId)
    # end createActionContext()

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

    def _getViewChoices(self):
        return [
                _extstr(u"postsview.All"), #$NON-NLS-1$
                _extstr(u"postsview.Drafts"), #$NON-NLS-1$
                _extstr(u"postsview.Published"), #$NON-NLS-1$
                _extstr(u"postsview.Today"), #$NON-NLS-1$
                u"-----------", #$NON-NLS-1$
                _extstr(u"postsview.Yesterday"), #$NON-NLS-1$
                _extstr(u"postsview.ThisWeek"), #$NON-NLS-1$
                _extstr(u"postsview.ThisMonth") #$NON-NLS-1$
        ]
    # end _getViewChoices()

    def _getSearchBoxChoices(self):
        return [
                (_extstr(u"postsview.Title"), None, SEARCH_TB_TITLE), #$NON-NLS-1$
        ]
    # end _getSearchBoxChoices()

    def _getUrlFromDocIDO(self, docIDO):
        url = None
        if self.blog is not None:
            pdIDO = docIDO.getPubDataIDO(self.blog.getId())
            if pdIDO is not None:
                url = pdIDO.getUrl()
        return url
    # end _getUrlFromDocIDO()

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

    def _unregisterAsIndexListener(self):
        self.indexService.removeListener(self)
Exemplo n.º 7
0
class ZBlogBrowseView(ZView, IZAccountStoreListener):

    def __init__(self, parent):
        ZView.__init__(self, parent, wx.ID_ANY)

        self._createWidgets()
        self._layoutWidgets()
        self._populateWidgets()
        self._bindWidgetEvents()

        self._registerAsAccountListener()
    # end __init__()

    def _createWidgets(self):
        self.blogListProvider = ZBlogListProvider()
        self.blogListView = ZListViewEx(self.blogListProvider, self)
    # end _createWidgets()

    def _layoutWidgets(self):
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.blogListView, 1, wx.EXPAND)

        self.SetSizer(sizer)
        self.SetAutoLayout(True)
        self.Layout()
    # end _layoutWidgets()

    def _populateWidgets(self):
        pass
    # end _populateWidgets()

    def _bindWidgetEvents(self):
        self.Bind(ZEVT_VIEW_SELECTION_CHANGED, self.onViewSelection)
        self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.onBlogSelected, self.blogListView)
        self.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.onBlogRightClick, self.blogListView)
        self._bindRefreshEvent(self.onZoundryRefresh)
    # end _bindWidgetEvents()

    def onBlogRightClick(self, event):
        blog = self._getSelectedBlog()
        if blog is not None:
            menu = self._createBlogCtxMenu(blog)
            self.PopupMenu(menu)
            menu.Destroy()
        event.Skip()
    # end onBlogRightClick()

    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 onViewSelection(self, event):
        selection = event.getSelection()
        if selection.getType() == IZViewSelectionTypes.ACCOUNT_SELECTION:
            accountId = selection.getData()
            self.blogListProvider.setAccountId(accountId)
            self.blogListProvider.refresh()
            self.blogListView.refresh()
            self.blogListView.deselectAll()
        elif selection.getType() == IZViewSelectionTypes.UNPUBLISHED_ACCOUNT_SELECTION:
            self.blogListProvider.setAccountId(None)
            self.blogListProvider.refresh()
            self.blogListView.refresh()
            self.blogListView.deselectAll()

        event.Skip()
    # end onViewSelection()

    def onBlogSelected(self, event):
        blog = self._getSelectedBlog()
        if blog is not None:
            account = blog.getAccount()
            accountId = account.getId()
            blogId = blog.getId()
            selection = ZViewSelection(IZViewSelectionTypes.BLOG_SELECTION, (accountId, blogId))
            fireViewSelectionEvent(selection, self)
        else:
            fireViewUnselectionEvent()
        event.Skip()
    # end onBlogSelected()

    def onZoundryRefresh(self, event):
        self.blogListView.refresh()
        event.Skip()
    # end onZoundryRefresh()

    def onAccountChanged(self, account):
        if account.getId() == self.blogListProvider.getAccountId():
            self.blogListProvider.refresh()
            fireRefreshEvent(self)
    # end onAccountChanged()

    def onAccountDeleted(self, account):
        if account.getId() == self.blogListProvider.getAccountId():
            self.blogListProvider.setAccountId(None)
            self.blogListProvider.refresh()
            fireRefreshEvent(self)
    # end onAccountDeleted()

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

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

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

    def _getSelectedBlog(self):
        itemIndexes = self.blogListView.getSelection()
        if itemIndexes:
            itemIndex = itemIndexes[0]
            return self.blogListProvider.getBlogAtIndex(itemIndex)
        return None