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
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
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)
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)
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)
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