class SvnProjectHelper(VcsProjectHelper): """ Class implementing the VCS project helper for Subversion. """ def __init__(self, vcsObject, projectObject, parent=None, name=None): """ Constructor @param vcsObject reference to the vcs object @param projectObject reference to the project object @param parent parent widget (QWidget) @param name name of this object (string) """ VcsProjectHelper.__init__(self, vcsObject, projectObject, parent, name) def getActions(self): """ Public method to get a list of all actions. @return list of all actions (list of E5Action) """ return self.actions[:] def initActions(self): """ Public method to generate the action objects. """ self.vcsNewAct = E5Action(self.tr('New from repository'), UI.PixmapCache.getIcon("vcsCheckout.png"), self.tr('&New from repository...'), 0, 0, self, 'subversion_new') self.vcsNewAct.setStatusTip( self.tr('Create a new project from the VCS repository')) self.vcsNewAct.setWhatsThis( self.tr("""<b>New from repository</b>""" """<p>This creates a new local project from the VCS""" """ repository.</p>""")) self.vcsNewAct.triggered.connect(self._vcsCheckout) self.actions.append(self.vcsNewAct) self.vcsUpdateAct = E5Action(self.tr('Update from repository'), UI.PixmapCache.getIcon("vcsUpdate.png"), self.tr('&Update from repository'), 0, 0, self, 'subversion_update') self.vcsUpdateAct.setStatusTip( self.tr('Update the local project from the VCS repository')) self.vcsUpdateAct.setWhatsThis( self.tr("""<b>Update from repository</b>""" """<p>This updates the local project from the VCS""" """ repository.</p>""")) self.vcsUpdateAct.triggered.connect(self._vcsUpdate) self.actions.append(self.vcsUpdateAct) self.vcsCommitAct = E5Action( self.tr('Commit changes to repository'), UI.PixmapCache.getIcon("vcsCommit.png"), self.tr('&Commit changes to repository...'), 0, 0, self, 'subversion_commit') self.vcsCommitAct.setStatusTip( self.tr( 'Commit changes to the local project to the VCS repository')) self.vcsCommitAct.setWhatsThis( self.tr( """<b>Commit changes to repository</b>""" """<p>This commits changes to the local project to the VCS""" """ repository.</p>""")) self.vcsCommitAct.triggered.connect(self._vcsCommit) self.actions.append(self.vcsCommitAct) self.svnLogBrowserAct = E5Action(self.tr('Show log browser'), UI.PixmapCache.getIcon("vcsLog.png"), self.tr('Show log browser'), 0, 0, self, 'subversion_log_browser') self.svnLogBrowserAct.setStatusTip( self.tr('Show a dialog to browse the log of the local project')) self.svnLogBrowserAct.setWhatsThis( self. tr("""<b>Show log browser</b>""" """<p>This shows a dialog to browse the log of the local""" """ project. A limited number of entries is shown first. More""" """ can be retrieved later on.</p>""")) self.svnLogBrowserAct.triggered.connect(self._vcsLogBrowser) self.actions.append(self.svnLogBrowserAct) self.vcsDiffAct = E5Action(self.tr('Show differences'), UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show &difference'), 0, 0, self, 'subversion_diff') self.vcsDiffAct.setStatusTip( self.tr( 'Show the difference of the local project to the repository')) self.vcsDiffAct.setWhatsThis( self.tr("""<b>Show differences</b>""" """<p>This shows differences of the local project to the""" """ repository.</p>""")) self.vcsDiffAct.triggered.connect(self._vcsDiff) self.actions.append(self.vcsDiffAct) self.svnExtDiffAct = E5Action(self.tr('Show differences (extended)'), UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (extended)'), 0, 0, self, 'subversion_extendeddiff') self.svnExtDiffAct.setStatusTip( self. tr('Show the difference of revisions of the project to the repository' )) self.svnExtDiffAct.setWhatsThis( self.tr("""<b>Show differences (extended)</b>""" """<p>This shows differences of selectable revisions of""" """ the project.</p>""")) self.svnExtDiffAct.triggered.connect(self.__svnExtendedDiff) self.actions.append(self.svnExtDiffAct) self.svnUrlDiffAct = E5Action(self.tr('Show differences (URLs)'), UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (URLs)'), 0, 0, self, 'subversion_urldiff') self.svnUrlDiffAct.setStatusTip( self. tr('Show the difference of the project between two repository URLs' )) self.svnUrlDiffAct.setWhatsThis( self.tr("""<b>Show differences (URLs)</b>""" """<p>This shows differences of the project between""" """ two repository URLs.</p>""")) self.svnUrlDiffAct.triggered.connect(self.__svnUrlDiff) self.actions.append(self.svnUrlDiffAct) self.vcsStatusAct = E5Action(self.tr('Show status'), UI.PixmapCache.getIcon("vcsStatus.png"), self.tr('Show &status'), 0, 0, self, 'subversion_status') self.vcsStatusAct.setStatusTip( self.tr('Show the status of the local project')) self.vcsStatusAct.setWhatsThis( self.tr("""<b>Show status</b>""" """<p>This shows the status of the local project.</p>""")) self.vcsStatusAct.triggered.connect(self._vcsStatus) self.actions.append(self.vcsStatusAct) self.svnChangeListsAct = E5Action( self.tr('Show change lists'), UI.PixmapCache.getIcon("vcsChangeLists.png"), self.tr('Show change lists'), 0, 0, self, 'subversion_changelists') self.svnChangeListsAct.setStatusTip( self. tr('Show the change lists and associated files of the local project' )) self.svnChangeListsAct.setWhatsThis( self. tr("""<b>Show change lists</b>""" """<p>This shows the change lists and associated files of the""" """ local project.</p>""")) self.svnChangeListsAct.triggered.connect(self.__svnChangeLists) self.actions.append(self.svnChangeListsAct) self.vcsTagAct = E5Action(self.tr('Tag in repository'), UI.PixmapCache.getIcon("vcsTag.png"), self.tr('&Tag in repository...'), 0, 0, self, 'subversion_tag') self.vcsTagAct.setStatusTip( self.tr('Tag the local project in the repository')) self.vcsTagAct.setWhatsThis( self.tr( """<b>Tag in repository</b>""" """<p>This tags the local project in the repository.</p>""")) self.vcsTagAct.triggered.connect(self._vcsTag) self.actions.append(self.vcsTagAct) self.vcsExportAct = E5Action(self.tr('Export from repository'), UI.PixmapCache.getIcon("vcsExport.png"), self.tr('&Export from repository...'), 0, 0, self, 'subversion_export') self.vcsExportAct.setStatusTip( self.tr('Export a project from the repository')) self.vcsExportAct.setWhatsThis( self.tr("""<b>Export from repository</b>""" """<p>This exports a project from the repository.</p>""")) self.vcsExportAct.triggered.connect(self._vcsExport) self.actions.append(self.vcsExportAct) self.vcsPropsAct = E5Action(self.tr('Command options'), self.tr('Command &options...'), 0, 0, self, 'subversion_options') self.vcsPropsAct.setStatusTip(self.tr('Show the VCS command options')) self.vcsPropsAct.setWhatsThis( self. tr("""<b>Command options...</b>""" """<p>This shows a dialog to edit the VCS command options.</p>""" )) self.vcsPropsAct.triggered.connect(self._vcsCommandOptions) self.actions.append(self.vcsPropsAct) self.vcsRevertAct = E5Action(self.tr('Revert changes'), UI.PixmapCache.getIcon("vcsRevert.png"), self.tr('Re&vert changes'), 0, 0, self, 'subversion_revert') self.vcsRevertAct.setStatusTip( self.tr('Revert all changes made to the local project')) self.vcsRevertAct.setWhatsThis( self. tr("""<b>Revert changes</b>""" """<p>This reverts all changes made to the local project.</p>""" )) self.vcsRevertAct.triggered.connect(self._vcsRevert) self.actions.append(self.vcsRevertAct) self.vcsMergeAct = E5Action(self.tr('Merge'), UI.PixmapCache.getIcon("vcsMerge.png"), self.tr('Mer&ge changes...'), 0, 0, self, 'subversion_merge') self.vcsMergeAct.setStatusTip( self.tr('Merge changes of a tag/revision into the local project')) self.vcsMergeAct.setWhatsThis( self.tr( """<b>Merge</b>""" """<p>This merges changes of a tag/revision into the local""" """ project.</p>""")) self.vcsMergeAct.triggered.connect(self._vcsMerge) self.actions.append(self.vcsMergeAct) self.vcsSwitchAct = E5Action(self.tr('Switch'), UI.PixmapCache.getIcon("vcsSwitch.png"), self.tr('S&witch...'), 0, 0, self, 'subversion_switch') self.vcsSwitchAct.setStatusTip( self.tr('Switch the local copy to another tag/branch')) self.vcsSwitchAct.setWhatsThis( self. tr("""<b>Switch</b>""" """<p>This switches the local copy to another tag/branch.</p>""" )) self.vcsSwitchAct.triggered.connect(self._vcsSwitch) self.actions.append(self.vcsSwitchAct) self.vcsResolveAct = E5Action(self.tr('Conflicts resolved'), self.tr('Con&flicts resolved'), 0, 0, self, 'subversion_resolve') self.vcsResolveAct.setStatusTip( self.tr('Mark all conflicts of the local project as resolved')) self.vcsResolveAct.setWhatsThis( self.tr("""<b>Conflicts resolved</b>""" """<p>This marks all conflicts of the local project as""" """ resolved.</p>""")) self.vcsResolveAct.triggered.connect(self.__svnResolve) self.actions.append(self.vcsResolveAct) self.vcsCleanupAct = E5Action(self.tr('Cleanup'), self.tr('Cleanu&p'), 0, 0, self, 'subversion_cleanup') self.vcsCleanupAct.setStatusTip(self.tr('Cleanup the local project')) self.vcsCleanupAct.setWhatsThis( self.tr( """<b>Cleanup</b>""" """<p>This performs a cleanup of the local project.</p>""")) self.vcsCleanupAct.triggered.connect(self._vcsCleanup) self.actions.append(self.vcsCleanupAct) self.vcsCommandAct = E5Action(self.tr('Execute command'), self.tr('E&xecute command...'), 0, 0, self, 'subversion_command') self.vcsCommandAct.setStatusTip( self.tr('Execute an arbitrary VCS command')) self.vcsCommandAct.setWhatsThis( self. tr("""<b>Execute command</b>""" """<p>This opens a dialog to enter an arbitrary VCS command.</p>""" )) self.vcsCommandAct.triggered.connect(self._vcsCommand) self.actions.append(self.vcsCommandAct) self.svnTagListAct = E5Action(self.tr('List tags'), self.tr('List tags...'), 0, 0, self, 'subversion_list_tags') self.svnTagListAct.setStatusTip(self.tr('List tags of the project')) self.svnTagListAct.setWhatsThis( self.tr("""<b>List tags</b>""" """<p>This lists the tags of the project.</p>""")) self.svnTagListAct.triggered.connect(self.__svnTagList) self.actions.append(self.svnTagListAct) self.svnBranchListAct = E5Action(self.tr('List branches'), self.tr('List branches...'), 0, 0, self, 'subversion_list_branches') self.svnBranchListAct.setStatusTip( self.tr('List branches of the project')) self.svnBranchListAct.setWhatsThis( self.tr("""<b>List branches</b>""" """<p>This lists the branches of the project.</p>""")) self.svnBranchListAct.triggered.connect(self.__svnBranchList) self.actions.append(self.svnBranchListAct) self.svnListAct = E5Action(self.tr('List repository contents'), self.tr('List repository contents...'), 0, 0, self, 'subversion_contents') self.svnListAct.setStatusTip( self.tr('Lists the contents of the repository')) self.svnListAct.setWhatsThis( self.tr("""<b>List repository contents</b>""" """<p>This lists the contents of the repository.</p>""")) self.svnListAct.triggered.connect(self.__svnTagList) self.actions.append(self.svnListAct) self.svnPropSetAct = E5Action(self.tr('Set Property'), self.tr('Set Property...'), 0, 0, self, 'subversion_property_set') self.svnPropSetAct.setStatusTip( self.tr('Set a property for the project files')) self.svnPropSetAct.setWhatsThis( self.tr("""<b>Set Property</b>""" """<p>This sets a property for the project files.</p>""")) self.svnPropSetAct.triggered.connect(self.__svnPropSet) self.actions.append(self.svnPropSetAct) self.svnPropListAct = E5Action(self.tr('List Properties'), self.tr('List Properties...'), 0, 0, self, 'subversion_property_list') self.svnPropListAct.setStatusTip( self.tr('List properties of the project files')) self.svnPropListAct.setWhatsThis( self.tr( """<b>List Properties</b>""" """<p>This lists the properties of the project files.</p>""")) self.svnPropListAct.triggered.connect(self.__svnPropList) self.actions.append(self.svnPropListAct) self.svnPropDelAct = E5Action(self.tr('Delete Property'), self.tr('Delete Property...'), 0, 0, self, 'subversion_property_delete') self.svnPropDelAct.setStatusTip( self.tr('Delete a property for the project files')) self.svnPropDelAct.setWhatsThis( self.tr( """<b>Delete Property</b>""" """<p>This deletes a property for the project files.</p>""")) self.svnPropDelAct.triggered.connect(self.__svnPropDel) self.actions.append(self.svnPropDelAct) self.svnRelocateAct = E5Action(self.tr('Relocate'), UI.PixmapCache.getIcon("vcsSwitch.png"), self.tr('Relocate...'), 0, 0, self, 'subversion_relocate') self.svnRelocateAct.setStatusTip( self.tr('Relocate the working copy to a new repository URL')) self.svnRelocateAct.setWhatsThis( self.tr( """<b>Relocate</b>""" """<p>This relocates the working copy to a new repository""" """ URL.</p>""")) self.svnRelocateAct.triggered.connect(self.__svnRelocate) self.actions.append(self.svnRelocateAct) self.svnRepoBrowserAct = E5Action( self.tr('Repository Browser'), UI.PixmapCache.getIcon("vcsRepoBrowser.png"), self.tr('Repository Browser...'), 0, 0, self, 'subversion_repo_browser') self.svnRepoBrowserAct.setStatusTip( self.tr('Show the Repository Browser dialog')) self.svnRepoBrowserAct.setWhatsThis( self.tr("""<b>Repository Browser</b>""" """<p>This shows the Repository Browser dialog.</p>""")) self.svnRepoBrowserAct.triggered.connect(self.__svnRepoBrowser) self.actions.append(self.svnRepoBrowserAct) self.svnConfigAct = E5Action(self.tr('Configure'), self.tr('Configure...'), 0, 0, self, 'subversion_configure') self.svnConfigAct.setStatusTip( self. tr('Show the configuration dialog with the Subversion page selected' )) self.svnConfigAct.setWhatsThis( self.tr( """<b>Configure</b>""" """<p>Show the configuration dialog with the Subversion page""" """ selected.</p>""")) self.svnConfigAct.triggered.connect(self.__svnConfigure) self.actions.append(self.svnConfigAct) self.svnUpgradeAct = E5Action(self.tr('Upgrade'), self.tr('Upgrade...'), 0, 0, self, 'subversion_upgrade') self.svnUpgradeAct.setStatusTip( self.tr('Upgrade the working copy to the current format')) self.svnUpgradeAct.setWhatsThis( self.tr( """<b>Upgrade</b>""" """<p>Upgrades the working copy to the current format.</p>""")) self.svnUpgradeAct.triggered.connect(self.__svnUpgrade) self.actions.append(self.svnUpgradeAct) def initMenu(self, menu): """ Public method to generate the VCS menu. @param menu reference to the menu to be populated (QMenu) """ menu.clear() act = menu.addAction( UI.PixmapCache.getIcon( os.path.join("VcsPlugins", "vcsSubversion", "icons", "subversion.png")), self.vcs.vcsName(), self._vcsInfoDisplay) font = act.font() font.setBold(True) act.setFont(font) menu.addSeparator() menu.addAction(self.vcsUpdateAct) menu.addAction(self.vcsCommitAct) menu.addSeparator() menu.addAction(self.vcsTagAct) if self.vcs.otherData["standardLayout"]: menu.addAction(self.svnTagListAct) menu.addAction(self.svnBranchListAct) else: menu.addAction(self.svnListAct) menu.addSeparator() menu.addAction(self.svnLogBrowserAct) menu.addSeparator() menu.addAction(self.vcsStatusAct) menu.addAction(self.svnChangeListsAct) menu.addSeparator() menu.addAction(self.vcsDiffAct) menu.addAction(self.svnExtDiffAct) menu.addAction(self.svnUrlDiffAct) menu.addSeparator() menu.addAction(self.vcsRevertAct) menu.addAction(self.vcsMergeAct) menu.addAction(self.vcsResolveAct) menu.addSeparator() menu.addAction(self.svnRelocateAct) menu.addAction(self.vcsSwitchAct) menu.addSeparator() menu.addAction(self.svnPropSetAct) menu.addAction(self.svnPropListAct) menu.addAction(self.svnPropDelAct) menu.addSeparator() menu.addAction(self.vcsCleanupAct) menu.addSeparator() menu.addAction(self.vcsCommandAct) menu.addAction(self.svnRepoBrowserAct) menu.addAction(self.svnUpgradeAct) menu.addSeparator() menu.addAction(self.vcsPropsAct) menu.addSeparator() menu.addAction(self.svnConfigAct) menu.addSeparator() menu.addAction(self.vcsNewAct) menu.addAction(self.vcsExportAct) def initToolbar(self, ui, toolbarManager): """ Public slot to initialize the VCS toolbar. @param ui reference to the main window (UserInterface) @param toolbarManager reference to a toolbar manager object (E5ToolBarManager) """ self.__toolbar = QToolBar(self.tr("Subversion (svn)"), ui) self.__toolbar.setIconSize(UI.Config.ToolBarIconSize) self.__toolbar.setObjectName("SubversionToolbar") self.__toolbar.setToolTip(self.tr('Subversion (svn)')) self.__toolbar.addAction(self.svnLogBrowserAct) self.__toolbar.addAction(self.vcsStatusAct) self.__toolbar.addSeparator() self.__toolbar.addAction(self.vcsDiffAct) self.__toolbar.addSeparator() self.__toolbar.addAction(self.svnRepoBrowserAct) self.__toolbar.addAction(self.vcsNewAct) self.__toolbar.addAction(self.vcsExportAct) self.__toolbar.addSeparator() title = self.__toolbar.windowTitle() toolbarManager.addToolBar(self.__toolbar, title) toolbarManager.addAction(self.vcsUpdateAct, title) toolbarManager.addAction(self.vcsCommitAct, title) toolbarManager.addAction(self.svnExtDiffAct, title) toolbarManager.addAction(self.svnUrlDiffAct, title) toolbarManager.addAction(self.svnChangeListsAct, title) toolbarManager.addAction(self.vcsTagAct, title) toolbarManager.addAction(self.vcsRevertAct, title) toolbarManager.addAction(self.vcsMergeAct, title) toolbarManager.addAction(self.vcsSwitchAct, title) toolbarManager.addAction(self.svnRelocateAct, title) self.__toolbar.setEnabled(False) self.__toolbar.setVisible(False) ui.registerToolbar("subversion", self.__toolbar.windowTitle(), self.__toolbar) ui.addToolBar(self.__toolbar) def removeToolbar(self, ui, toolbarManager): """ Public method to remove a toolbar created by initToolbar(). @param ui reference to the main window (UserInterface) @param toolbarManager reference to a toolbar manager object (E5ToolBarManager) """ ui.removeToolBar(self.__toolbar) ui.unregisterToolbar("subversion") title = self.__toolbar.windowTitle() toolbarManager.removeCategoryActions(title) toolbarManager.removeToolBar(self.__toolbar) self.__toolbar.deleteLater() self.__toolbar = None def __svnResolve(self): """ Private slot used to resolve conflicts of the local project. """ self.vcs.svnResolve(self.project.ppath) def __svnPropList(self): """ Private slot used to list the properties of the project files. """ self.vcs.svnListProps(self.project.ppath, True) def __svnPropSet(self): """ Private slot used to set a property for the project files. """ self.vcs.svnSetProp(self.project.ppath, True) def __svnPropDel(self): """ Private slot used to delete a property for the project files. """ self.vcs.svnDelProp(self.project.ppath, True) def __svnTagList(self): """ Private slot used to list the tags of the project. """ self.vcs.svnListTagBranch(self.project.ppath, True) def __svnBranchList(self): """ Private slot used to list the branches of the project. """ self.vcs.svnListTagBranch(self.project.ppath, False) def __svnExtendedDiff(self): """ Private slot used to perform a svn diff with the selection of revisions. """ self.vcs.svnExtendedDiff(self.project.ppath) def __svnUrlDiff(self): """ Private slot used to perform a svn diff with the selection of repository URLs. """ self.vcs.svnUrlDiff(self.project.ppath) def __svnRelocate(self): """ Private slot used to relocate the working copy to a new repository URL. """ self.vcs.svnRelocate(self.project.ppath) def __svnRepoBrowser(self): """ Private slot to open the repository browser. """ self.vcs.svnRepoBrowser(projectPath=self.project.ppath) def __svnConfigure(self): """ Private slot to open the configuration dialog. """ e5App().getObject("UserInterface").showPreferences( "zzz_subversionPage") def __svnChangeLists(self): """ Private slot used to show a list of change lists. """ self.vcs.svnShowChangelists(self.project.ppath) def __svnUpgrade(self): """ Private slot used to upgrade the working copy format. """ self.vcs.svnUpgrade(self.project.ppath)
class SvnProjectHelper(VcsProjectHelper): """ Class implementing the VCS project helper for Subversion. """ def __init__(self, vcsObject, projectObject, parent=None, name=None): """ Constructor @param vcsObject reference to the vcs object @param projectObject reference to the project object @param parent parent widget (QWidget) @param name name of this object (string) """ VcsProjectHelper.__init__(self, vcsObject, projectObject, parent, name) def getActions(self): """ Public method to get a list of all actions. @return list of all actions (list of E5Action) """ return self.actions[:] def initActions(self): """ Public method to generate the action objects. """ self.vcsNewAct = E5Action( self.tr('New from repository'), UI.PixmapCache.getIcon("vcsCheckout.png"), self.tr('&New from repository...'), 0, 0, self, 'subversion_new') self.vcsNewAct.setStatusTip(self.tr( 'Create a new project from the VCS repository' )) self.vcsNewAct.setWhatsThis(self.tr( """<b>New from repository</b>""" """<p>This creates a new local project from the VCS""" """ repository.</p>""" )) self.vcsNewAct.triggered.connect(self._vcsCheckout) self.actions.append(self.vcsNewAct) self.vcsUpdateAct = E5Action( self.tr('Update from repository'), UI.PixmapCache.getIcon("vcsUpdate.png"), self.tr('&Update from repository'), 0, 0, self, 'subversion_update') self.vcsUpdateAct.setStatusTip(self.tr( 'Update the local project from the VCS repository' )) self.vcsUpdateAct.setWhatsThis(self.tr( """<b>Update from repository</b>""" """<p>This updates the local project from the VCS""" """ repository.</p>""" )) self.vcsUpdateAct.triggered.connect(self._vcsUpdate) self.actions.append(self.vcsUpdateAct) self.vcsCommitAct = E5Action( self.tr('Commit changes to repository'), UI.PixmapCache.getIcon("vcsCommit.png"), self.tr('&Commit changes to repository...'), 0, 0, self, 'subversion_commit') self.vcsCommitAct.setStatusTip(self.tr( 'Commit changes to the local project to the VCS repository' )) self.vcsCommitAct.setWhatsThis(self.tr( """<b>Commit changes to repository</b>""" """<p>This commits changes to the local project to the VCS""" """ repository.</p>""" )) self.vcsCommitAct.triggered.connect(self._vcsCommit) self.actions.append(self.vcsCommitAct) self.vcsLogAct = E5Action( self.tr('Show log'), UI.PixmapCache.getIcon("vcsLog.png"), self.tr('Show &log'), 0, 0, self, 'subversion_log') self.vcsLogAct.setStatusTip(self.tr( 'Show the log of the local project' )) self.vcsLogAct.setWhatsThis(self.tr( """<b>Show log</b>""" """<p>This shows the log of the local project.</p>""" )) self.vcsLogAct.triggered.connect(self._vcsLog) self.actions.append(self.vcsLogAct) self.svnLogBrowserAct = E5Action( self.tr('Show log browser'), UI.PixmapCache.getIcon("vcsLog.png"), self.tr('Show log browser'), 0, 0, self, 'subversion_log_browser') self.svnLogBrowserAct.setStatusTip(self.tr( 'Show a dialog to browse the log of the local project' )) self.svnLogBrowserAct.setWhatsThis(self.tr( """<b>Show log browser</b>""" """<p>This shows a dialog to browse the log of the local""" """ project. A limited number of entries is shown first. More""" """ can be retrieved later on.</p>""" )) self.svnLogBrowserAct.triggered.connect(self._vcsLogBrowser) self.actions.append(self.svnLogBrowserAct) self.vcsDiffAct = E5Action( self.tr('Show differences'), UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show &difference'), 0, 0, self, 'subversion_diff') self.vcsDiffAct.setStatusTip(self.tr( 'Show the difference of the local project to the repository' )) self.vcsDiffAct.setWhatsThis(self.tr( """<b>Show differences</b>""" """<p>This shows differences of the local project to the""" """ repository.</p>""" )) self.vcsDiffAct.triggered.connect(self._vcsDiff) self.actions.append(self.vcsDiffAct) self.svnExtDiffAct = E5Action( self.tr('Show differences (extended)'), UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (extended)'), 0, 0, self, 'subversion_extendeddiff') self.svnExtDiffAct.setStatusTip(self.tr( 'Show the difference of revisions of the project to the repository' )) self.svnExtDiffAct.setWhatsThis(self.tr( """<b>Show differences (extended)</b>""" """<p>This shows differences of selectable revisions of""" """ the project.</p>""" )) self.svnExtDiffAct.triggered.connect(self.__svnExtendedDiff) self.actions.append(self.svnExtDiffAct) self.svnUrlDiffAct = E5Action( self.tr('Show differences (URLs)'), UI.PixmapCache.getIcon("vcsDiff.png"), self.tr('Show differences (URLs)'), 0, 0, self, 'subversion_urldiff') self.svnUrlDiffAct.setStatusTip(self.tr( 'Show the difference of the project between two repository URLs' )) self.svnUrlDiffAct.setWhatsThis(self.tr( """<b>Show differences (URLs)</b>""" """<p>This shows differences of the project between""" """ two repository URLs.</p>""" )) self.svnUrlDiffAct.triggered.connect(self.__svnUrlDiff) self.actions.append(self.svnUrlDiffAct) self.vcsStatusAct = E5Action( self.tr('Show status'), UI.PixmapCache.getIcon("vcsStatus.png"), self.tr('Show &status'), 0, 0, self, 'subversion_status') self.vcsStatusAct.setStatusTip(self.tr( 'Show the status of the local project' )) self.vcsStatusAct.setWhatsThis(self.tr( """<b>Show status</b>""" """<p>This shows the status of the local project.</p>""" )) self.vcsStatusAct.triggered.connect(self._vcsStatus) self.actions.append(self.vcsStatusAct) self.svnChangeListsAct = E5Action( self.tr('Show change lists'), UI.PixmapCache.getIcon("vcsChangeLists.png"), self.tr('Show change lists'), 0, 0, self, 'subversion_changelists') self.svnChangeListsAct.setStatusTip(self.tr( 'Show the change lists and associated files of the local project' )) self.svnChangeListsAct.setWhatsThis(self.tr( """<b>Show change lists</b>""" """<p>This shows the change lists and associated files of the""" """ local project.</p>""" )) self.svnChangeListsAct.triggered.connect(self.__svnChangeLists) self.actions.append(self.svnChangeListsAct) self.vcsTagAct = E5Action( self.tr('Tag in repository'), UI.PixmapCache.getIcon("vcsTag.png"), self.tr('&Tag in repository...'), 0, 0, self, 'subversion_tag') self.vcsTagAct.setStatusTip(self.tr( 'Tag the local project in the repository' )) self.vcsTagAct.setWhatsThis(self.tr( """<b>Tag in repository</b>""" """<p>This tags the local project in the repository.</p>""" )) self.vcsTagAct.triggered.connect(self._vcsTag) self.actions.append(self.vcsTagAct) self.vcsExportAct = E5Action( self.tr('Export from repository'), UI.PixmapCache.getIcon("vcsExport.png"), self.tr('&Export from repository...'), 0, 0, self, 'subversion_export') self.vcsExportAct.setStatusTip(self.tr( 'Export a project from the repository' )) self.vcsExportAct.setWhatsThis(self.tr( """<b>Export from repository</b>""" """<p>This exports a project from the repository.</p>""" )) self.vcsExportAct.triggered.connect(self._vcsExport) self.actions.append(self.vcsExportAct) self.vcsPropsAct = E5Action( self.tr('Command options'), self.tr('Command &options...'), 0, 0, self, 'subversion_options') self.vcsPropsAct.setStatusTip(self.tr( 'Show the VCS command options')) self.vcsPropsAct.setWhatsThis(self.tr( """<b>Command options...</b>""" """<p>This shows a dialog to edit the VCS command options.</p>""" )) self.vcsPropsAct.triggered.connect(self._vcsCommandOptions) self.actions.append(self.vcsPropsAct) self.vcsRevertAct = E5Action( self.tr('Revert changes'), UI.PixmapCache.getIcon("vcsRevert.png"), self.tr('Re&vert changes'), 0, 0, self, 'subversion_revert') self.vcsRevertAct.setStatusTip(self.tr( 'Revert all changes made to the local project' )) self.vcsRevertAct.setWhatsThis(self.tr( """<b>Revert changes</b>""" """<p>This reverts all changes made to the local project.</p>""" )) self.vcsRevertAct.triggered.connect(self._vcsRevert) self.actions.append(self.vcsRevertAct) self.vcsMergeAct = E5Action( self.tr('Merge'), UI.PixmapCache.getIcon("vcsMerge.png"), self.tr('Mer&ge changes...'), 0, 0, self, 'subversion_merge') self.vcsMergeAct.setStatusTip(self.tr( 'Merge changes of a tag/revision into the local project' )) self.vcsMergeAct.setWhatsThis(self.tr( """<b>Merge</b>""" """<p>This merges changes of a tag/revision into the local""" """ project.</p>""" )) self.vcsMergeAct.triggered.connect(self._vcsMerge) self.actions.append(self.vcsMergeAct) self.vcsSwitchAct = E5Action( self.tr('Switch'), UI.PixmapCache.getIcon("vcsSwitch.png"), self.tr('S&witch...'), 0, 0, self, 'subversion_switch') self.vcsSwitchAct.setStatusTip(self.tr( 'Switch the local copy to another tag/branch' )) self.vcsSwitchAct.setWhatsThis(self.tr( """<b>Switch</b>""" """<p>This switches the local copy to another tag/branch.</p>""" )) self.vcsSwitchAct.triggered.connect(self._vcsSwitch) self.actions.append(self.vcsSwitchAct) self.vcsResolveAct = E5Action( self.tr('Conflicts resolved'), self.tr('Con&flicts resolved'), 0, 0, self, 'subversion_resolve') self.vcsResolveAct.setStatusTip(self.tr( 'Mark all conflicts of the local project as resolved' )) self.vcsResolveAct.setWhatsThis(self.tr( """<b>Conflicts resolved</b>""" """<p>This marks all conflicts of the local project as""" """ resolved.</p>""" )) self.vcsResolveAct.triggered.connect(self.__svnResolve) self.actions.append(self.vcsResolveAct) self.vcsCleanupAct = E5Action( self.tr('Cleanup'), self.tr('Cleanu&p'), 0, 0, self, 'subversion_cleanup') self.vcsCleanupAct.setStatusTip(self.tr( 'Cleanup the local project' )) self.vcsCleanupAct.setWhatsThis(self.tr( """<b>Cleanup</b>""" """<p>This performs a cleanup of the local project.</p>""" )) self.vcsCleanupAct.triggered.connect(self._vcsCleanup) self.actions.append(self.vcsCleanupAct) self.vcsCommandAct = E5Action( self.tr('Execute command'), self.tr('E&xecute command...'), 0, 0, self, 'subversion_command') self.vcsCommandAct.setStatusTip(self.tr( 'Execute an arbitrary VCS command' )) self.vcsCommandAct.setWhatsThis(self.tr( """<b>Execute command</b>""" """<p>This opens a dialog to enter an arbitrary VCS command.</p>""" )) self.vcsCommandAct.triggered.connect(self._vcsCommand) self.actions.append(self.vcsCommandAct) self.svnTagListAct = E5Action( self.tr('List tags'), self.tr('List tags...'), 0, 0, self, 'subversion_list_tags') self.svnTagListAct.setStatusTip(self.tr( 'List tags of the project' )) self.svnTagListAct.setWhatsThis(self.tr( """<b>List tags</b>""" """<p>This lists the tags of the project.</p>""" )) self.svnTagListAct.triggered.connect(self.__svnTagList) self.actions.append(self.svnTagListAct) self.svnBranchListAct = E5Action( self.tr('List branches'), self.tr('List branches...'), 0, 0, self, 'subversion_list_branches') self.svnBranchListAct.setStatusTip(self.tr( 'List branches of the project' )) self.svnBranchListAct.setWhatsThis(self.tr( """<b>List branches</b>""" """<p>This lists the branches of the project.</p>""" )) self.svnBranchListAct.triggered.connect(self.__svnBranchList) self.actions.append(self.svnBranchListAct) self.svnListAct = E5Action( self.tr('List repository contents'), self.tr('List repository contents...'), 0, 0, self, 'subversion_contents') self.svnListAct.setStatusTip(self.tr( 'Lists the contents of the repository' )) self.svnListAct.setWhatsThis(self.tr( """<b>List repository contents</b>""" """<p>This lists the contents of the repository.</p>""" )) self.svnListAct.triggered.connect(self.__svnTagList) self.actions.append(self.svnListAct) self.svnPropSetAct = E5Action( self.tr('Set Property'), self.tr('Set Property...'), 0, 0, self, 'subversion_property_set') self.svnPropSetAct.setStatusTip(self.tr( 'Set a property for the project files' )) self.svnPropSetAct.setWhatsThis(self.tr( """<b>Set Property</b>""" """<p>This sets a property for the project files.</p>""" )) self.svnPropSetAct.triggered.connect(self.__svnPropSet) self.actions.append(self.svnPropSetAct) self.svnPropListAct = E5Action( self.tr('List Properties'), self.tr('List Properties...'), 0, 0, self, 'subversion_property_list') self.svnPropListAct.setStatusTip(self.tr( 'List properties of the project files' )) self.svnPropListAct.setWhatsThis(self.tr( """<b>List Properties</b>""" """<p>This lists the properties of the project files.</p>""" )) self.svnPropListAct.triggered.connect(self.__svnPropList) self.actions.append(self.svnPropListAct) self.svnPropDelAct = E5Action( self.tr('Delete Property'), self.tr('Delete Property...'), 0, 0, self, 'subversion_property_delete') self.svnPropDelAct.setStatusTip(self.tr( 'Delete a property for the project files' )) self.svnPropDelAct.setWhatsThis(self.tr( """<b>Delete Property</b>""" """<p>This deletes a property for the project files.</p>""" )) self.svnPropDelAct.triggered.connect(self.__svnPropDel) self.actions.append(self.svnPropDelAct) self.svnRelocateAct = E5Action( self.tr('Relocate'), UI.PixmapCache.getIcon("vcsSwitch.png"), self.tr('Relocate...'), 0, 0, self, 'subversion_relocate') self.svnRelocateAct.setStatusTip(self.tr( 'Relocate the working copy to a new repository URL' )) self.svnRelocateAct.setWhatsThis(self.tr( """<b>Relocate</b>""" """<p>This relocates the working copy to a new repository""" """ URL.</p>""" )) self.svnRelocateAct.triggered.connect(self.__svnRelocate) self.actions.append(self.svnRelocateAct) self.svnRepoBrowserAct = E5Action( self.tr('Repository Browser'), UI.PixmapCache.getIcon("vcsRepoBrowser.png"), self.tr('Repository Browser...'), 0, 0, self, 'subversion_repo_browser') self.svnRepoBrowserAct.setStatusTip(self.tr( 'Show the Repository Browser dialog' )) self.svnRepoBrowserAct.setWhatsThis(self.tr( """<b>Repository Browser</b>""" """<p>This shows the Repository Browser dialog.</p>""" )) self.svnRepoBrowserAct.triggered.connect(self.__svnRepoBrowser) self.actions.append(self.svnRepoBrowserAct) self.svnConfigAct = E5Action( self.tr('Configure'), self.tr('Configure...'), 0, 0, self, 'subversion_configure') self.svnConfigAct.setStatusTip(self.tr( 'Show the configuration dialog with the Subversion page selected' )) self.svnConfigAct.setWhatsThis(self.tr( """<b>Configure</b>""" """<p>Show the configuration dialog with the Subversion page""" """ selected.</p>""" )) self.svnConfigAct.triggered.connect(self.__svnConfigure) self.actions.append(self.svnConfigAct) self.svnUpgradeAct = E5Action( self.tr('Upgrade'), self.tr('Upgrade...'), 0, 0, self, 'subversion_upgrade') self.svnUpgradeAct.setStatusTip(self.tr( 'Upgrade the working copy to the current format' )) self.svnUpgradeAct.setWhatsThis(self.tr( """<b>Upgrade</b>""" """<p>Upgrades the working copy to the current format.</p>""" )) self.svnUpgradeAct.triggered.connect(self.__svnUpgrade) self.actions.append(self.svnUpgradeAct) def initMenu(self, menu): """ Public method to generate the VCS menu. @param menu reference to the menu to be populated (QMenu) """ menu.clear() act = menu.addAction( UI.PixmapCache.getIcon( os.path.join("VcsPlugins", "vcsSubversion", "icons", "subversion.png")), self.vcs.vcsName(), self._vcsInfoDisplay) font = act.font() font.setBold(True) act.setFont(font) menu.addSeparator() menu.addAction(self.vcsUpdateAct) menu.addAction(self.vcsCommitAct) menu.addSeparator() menu.addAction(self.vcsTagAct) if self.vcs.otherData["standardLayout"]: menu.addAction(self.svnTagListAct) menu.addAction(self.svnBranchListAct) else: menu.addAction(self.svnListAct) menu.addSeparator() menu.addAction(self.vcsLogAct) menu.addAction(self.svnLogBrowserAct) menu.addSeparator() menu.addAction(self.vcsStatusAct) menu.addAction(self.svnChangeListsAct) menu.addSeparator() menu.addAction(self.vcsDiffAct) menu.addAction(self.svnExtDiffAct) menu.addAction(self.svnUrlDiffAct) menu.addSeparator() menu.addAction(self.vcsRevertAct) menu.addAction(self.vcsMergeAct) menu.addAction(self.vcsResolveAct) menu.addSeparator() menu.addAction(self.svnRelocateAct) menu.addAction(self.vcsSwitchAct) menu.addSeparator() menu.addAction(self.svnPropSetAct) menu.addAction(self.svnPropListAct) menu.addAction(self.svnPropDelAct) menu.addSeparator() menu.addAction(self.vcsCleanupAct) menu.addSeparator() menu.addAction(self.vcsCommandAct) menu.addAction(self.svnRepoBrowserAct) menu.addAction(self.svnUpgradeAct) menu.addSeparator() menu.addAction(self.vcsPropsAct) menu.addSeparator() menu.addAction(self.svnConfigAct) menu.addSeparator() menu.addAction(self.vcsNewAct) menu.addAction(self.vcsExportAct) def initToolbar(self, ui, toolbarManager): """ Public slot to initialize the VCS toolbar. @param ui reference to the main window (UserInterface) @param toolbarManager reference to a toolbar manager object (E5ToolBarManager) """ self.__toolbar = QToolBar(self.tr("Subversion (svn)"), ui) self.__toolbar.setIconSize(UI.Config.ToolBarIconSize) self.__toolbar.setObjectName("SubversionToolbar") self.__toolbar.setToolTip(self.tr('Subversion (svn)')) self.__toolbar.addAction(self.svnLogBrowserAct) self.__toolbar.addAction(self.vcsStatusAct) self.__toolbar.addSeparator() self.__toolbar.addAction(self.vcsDiffAct) self.__toolbar.addSeparator() self.__toolbar.addAction(self.svnRepoBrowserAct) self.__toolbar.addAction(self.vcsNewAct) self.__toolbar.addAction(self.vcsExportAct) self.__toolbar.addSeparator() title = self.__toolbar.windowTitle() toolbarManager.addToolBar(self.__toolbar, title) toolbarManager.addAction(self.vcsUpdateAct, title) toolbarManager.addAction(self.vcsCommitAct, title) toolbarManager.addAction(self.vcsLogAct, title) toolbarManager.addAction(self.svnExtDiffAct, title) toolbarManager.addAction(self.svnUrlDiffAct, title) toolbarManager.addAction(self.svnChangeListsAct, title) toolbarManager.addAction(self.vcsTagAct, title) toolbarManager.addAction(self.vcsRevertAct, title) toolbarManager.addAction(self.vcsMergeAct, title) toolbarManager.addAction(self.vcsSwitchAct, title) toolbarManager.addAction(self.svnRelocateAct, title) self.__toolbar.setEnabled(False) self.__toolbar.setVisible(False) ui.registerToolbar("subversion", self.__toolbar.windowTitle(), self.__toolbar) ui.addToolBar(self.__toolbar) def removeToolbar(self, ui, toolbarManager): """ Public method to remove a toolbar created by initToolbar(). @param ui reference to the main window (UserInterface) @param toolbarManager reference to a toolbar manager object (E5ToolBarManager) """ ui.removeToolBar(self.__toolbar) ui.unregisterToolbar("subversion") title = self.__toolbar.windowTitle() toolbarManager.removeCategoryActions(title) toolbarManager.removeToolBar(self.__toolbar) self.__toolbar.deleteLater() self.__toolbar = None def __svnResolve(self): """ Private slot used to resolve conflicts of the local project. """ self.vcs.svnResolve(self.project.ppath) def __svnPropList(self): """ Private slot used to list the properties of the project files. """ self.vcs.svnListProps(self.project.ppath, True) def __svnPropSet(self): """ Private slot used to set a property for the project files. """ self.vcs.svnSetProp(self.project.ppath, True) def __svnPropDel(self): """ Private slot used to delete a property for the project files. """ self.vcs.svnDelProp(self.project.ppath, True) def __svnTagList(self): """ Private slot used to list the tags of the project. """ self.vcs.svnListTagBranch(self.project.ppath, True) def __svnBranchList(self): """ Private slot used to list the branches of the project. """ self.vcs.svnListTagBranch(self.project.ppath, False) def __svnExtendedDiff(self): """ Private slot used to perform a svn diff with the selection of revisions. """ self.vcs.svnExtendedDiff(self.project.ppath) def __svnUrlDiff(self): """ Private slot used to perform a svn diff with the selection of repository URLs. """ self.vcs.svnUrlDiff(self.project.ppath) def __svnRelocate(self): """ Private slot used to relocate the working copy to a new repository URL. """ self.vcs.svnRelocate(self.project.ppath) def __svnRepoBrowser(self): """ Private slot to open the repository browser. """ self.vcs.svnRepoBrowser(projectPath=self.project.ppath) def __svnConfigure(self): """ Private slot to open the configuration dialog. """ e5App().getObject("UserInterface")\ .showPreferences("zzz_subversionPage") def __svnChangeLists(self): """ Private slot used to show a list of change lists. """ self.vcs.svnShowChangelists(self.project.ppath) def __svnUpgrade(self): """ Private slot used to upgrade the working copy format. """ self.vcs.svnUpgrade(self.project.ppath)
class Window(QWidget): def __init__(self): QWidget.__init__(self) self._layout = QVBoxLayout() remove_layout_spaces(self._layout) self.setLayout(self._layout) self._central_widget = QWidget() self._layout.addWidget(self._central_widget) self._webviews_layout = ViewGridLayout(self) remove_layout_spaces(self._webviews_layout) self._central_widget.setLayout(self._webviews_layout) self._minibuffer = Minibuffer(self) self._layout.addWidget(self._minibuffer) self.fullscreen_window = None self.quit_if_last_closed = True WINDOWS_HANDLER.register_window(self) self._toolbar = None if window_toolbar_on_startup.value: self.toggle_toolbar() # remove the toolbar update callback if it was set self.destroyed.connect(lambda: hooks.webbuffer_current_changed. remove_if_exists(self._update_toolbar)) def _update_toolbar(self, buffer): if buffer.view().main_window != self: return self._toolbar.clear() self._toolbar.addAction(buffer.action(buffer.Back)) self._toolbar.addAction(buffer.action(buffer.Forward)) self._toolbar.addSeparator() self._toolbar.addAction(buffer.action(buffer.Stop)) self._toolbar.addAction(buffer.action(buffer.Reload)) def toggle_toolbar(self): if self._toolbar is None: hooks.webbuffer_current_changed.add(self._update_toolbar) self._toolbar = QToolBar() self._layout.insertWidget(0, self._toolbar) current_view = self.current_webview() if current_view and current_view.buffer(): self._update_toolbar(current_view.buffer()) else: hooks.webbuffer_current_changed.remove(self._update_toolbar) self._layout.removeWidget(self._toolbar) self._toolbar.deleteLater() self._toolbar = None def _change_current_webview(self, webview): self.current_webview().show_focused(False) if len(self.webviews()) > 1: webview.show_focused(True) self._webviews_layout.set_current_view(webview) def current_webview(self): return self._webviews_layout.current_view() def webviews(self): return self._webviews_layout.views() def create_webview_on_right(self): return self._webviews_layout.split_view(ViewGridLayout.VERTICAL) def create_webview_on_bottom(self): return self._webviews_layout.split_view(ViewGridLayout.HORIZONTAL) def _delete_webview(self, webview): self._webviews_layout.removeWidget(webview) webview.deleteLater() def minibuffer(self): return self._minibuffer def other_view(self): """switch to the next view""" views = self.webviews() index = views.index(self.current_webview()) index = index + 1 if index >= len(views): index = 0 views[index].set_current() def close_view(self, view): """close the given view""" views = self.webviews() if len(views) == 1: return # can't delete a single view if view == self.current_webview(): self.other_view() self._delete_webview(view) # do not show the window focused if there is one left if len(self.webviews()) == 1: self.current_webview().show_focused(True) def close_other_views(self): """close all views but the current one""" view = self.current_webview() # to remove more than one item correctly, the iteration must # be done on a shallow copy of the list for other in list(self.webviews()): if view != other: self._delete_webview(other) # do not show the window focused if there is one left if len(self.webviews()) == 1: self.current_webview().show_focused(False) def update_title(self, title): if title: self.setWindowTitle("{} - Webmacs".format(title)) else: self.setWindowTitle("Webmacs") def dump_state(self): return { "geometry": self.geometry().getRect(), "window-state": int(self.windowState()), "view-layout": self._webviews_layout.dump_state(), } def restore_state(self, data, version): self.setGeometry(QRect(*data["geometry"])) self.setWindowState(Qt.WindowStates(data["window-state"])) self._webviews_layout.restore_state(data["view-layout"])
class MultiLayerSelect: """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value("locale/userLocale")[0:2] locale_path = os.path.join(self.plugin_dir, "i18n", "MultiLayerSelect_{}.qm".format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) QCoreApplication.installTranslator(self.translator) # Init settings self.settings = QSettings() self.settings.beginGroup("plugins/multilayerselect") def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # pylint: disable=invalid-name return QCoreApplication.translate("MultiLayerSelect", message) def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" # pylint: disable=invalid-name # Create settings dialog self.settings_dialog = SettingsDialog(self.settings, self.iface.mainWindow()) self.expression_dialog = None try: QgsProject.instance().selectionColorChanged.connect( self.on_color_changed) QgsProject.instance().selectionColorChanged.connect( self.settings_dialog.on_project_color_changed) except AttributeError: # QGIS < 3.10 self.settings_dialog.colorChanged.connect(self.on_color_changed) QgsProject.instance().readProject.connect( self.settings_dialog.on_project_color_changed) self.settings_dialog.settingsChanged.connect(self.on_settings_changed) self.toolbar = QToolBar("Multilayer Select", self.iface.mainWindow()) self.toolbar.setObjectName("MultiSelectToolbar") self.about_action = QAction( QIcon(":/plugins/multilayerselect/icons/about.svg"), self.tr("About"), parent=self.iface.mainWindow(), ) self.about_action.triggered.connect(self.show_about) self.settings_action = QAction( QIcon(":/images/themes/default/console/iconSettingsConsole.svg"), self.tr("Settings"), parent=self.iface.mainWindow(), ) self.settings_action.setObjectName("actionMultiLayerSelectSettings") self.settings_action.setToolTip( self.tr("<b>Multilayer Select Settings</b>")) self.settings_action.triggered.connect(self.show_settings) self.plugin_menu = self.iface.pluginMenu().addMenu( QIcon(":/plugins/multilayerselect/icons/icon.svg"), "Multilayer Select") self.plugin_menu.addAction(self.about_action) self.plugin_menu.addAction(self.settings_action) self.selection_tool_button = QToolButton(self.toolbar) self.selection_tool_button.setPopupMode(QToolButton.MenuButtonPopup) self.selection_tool_button.setObjectName("selectionToolButton") self.advanced_selection_tool_button = QToolButton(self.toolbar) self.advanced_selection_tool_button.setPopupMode( QToolButton.MenuButtonPopup) self.advanced_selection_tool_button.setObjectName( "advancedSelectionToolButton") self.select_rect_tool = MultiSelectionAreaTool(self.iface.mapCanvas()) self.select_polygon_tool = MultiSelectionPolygonTool( self.iface.mapCanvas()) self.select_freehand_tool = MultiSelectionFreehandTool( self.iface.mapCanvas()) self.select_radius_tool = MultiSelectionRadiusTool( self.iface.mapCanvas()) self.actions_settings = [ SelectAction( text=self.tr("Select Features"), tooltip=self.tr( "<b>Select Features by area or single click</b>"), icon=":/plugins/multilayerselect/icons/selectRectangle.svg", objectname="actionMultiSelectByRectangle", tool=self.select_rect_tool, ), SelectAction( text=self.tr("Select Features by Polygon"), icon=":/plugins/multilayerselect/icons/selectPolygon.svg", objectname="actionMultiSelectByPolygon", tool=self.select_polygon_tool, ), SelectAction( text=self.tr("Select Features by Freehand"), icon=":/plugins/multilayerselect/icons/selectFreehand.svg", objectname="actionMultiSelectByFreehand", tool=self.select_freehand_tool, ), SelectAction( text=self.tr("Select Features by Radius"), icon=":/plugins/multilayerselect/icons/selectRadius.svg", objectname="actionMultiSelectByRadius", tool=self.select_radius_tool, ), ] def on_select_tool(tool, action): self.selection_tool_button.setDefaultAction(action) if self.embedded_selection_tool_button: self.embedded_selection_tool_button.setDefaultAction(action) self.iface.mapCanvas().setMapTool(tool) self.select_actions = [] for select_action in self.actions_settings: action = QAction(select_action.text) action.setToolTip(select_action.tooltip) action.setObjectName(select_action.objectname) action.setCheckable(True) select_action.tool.setAction(action) action.triggered.connect( partial(on_select_tool, select_action.tool, action)) self.selection_tool_button.addAction(action) if not self.selection_tool_button.defaultAction(): self.selection_tool_button.setDefaultAction(action) self.select_actions.append(action) self.toolbar.addWidget(self.selection_tool_button) self.select_all_action = QAction( self.tr("Select all features from all layers"), ) self.select_all_action.setToolTip("<b>{}</b>".format( self.select_all_action.text())) self.select_all_action.setObjectName("actionMultiSelectAll") self.select_all_action.triggered.connect(self.select_all) self.advanced_selection_tool_button.addAction(self.select_all_action) self.advanced_selection_tool_button.setDefaultAction( self.select_all_action) self.invert_all_action = QAction( self.tr("Invert selection for all layers"), ) self.invert_all_action.setToolTip("<b>{}</b>".format( self.invert_all_action.text())) self.invert_all_action.setObjectName("actionMultiSelectInvert") self.invert_all_action.triggered.connect(self.invert_all) self.advanced_selection_tool_button.addAction(self.invert_all_action) self.select_by_expr_action = QAction( QIcon(":/images/themes/default/mIconExpressionSelect.svg"), self.tr("Select Features by Expression..."), ) self.select_by_expr_action.setToolTip("<b>{}</b>".format( self.select_by_expr_action.text())) self.select_by_expr_action.setObjectName("actionMultiSelectExpr") self.select_by_expr_action.triggered.connect(self.select_by_expression) self.advanced_selection_tool_button.addAction( self.select_by_expr_action) self.toolbar.addWidget(self.advanced_selection_tool_button) self.deselect_all_action = QAction( self.tr("Deselect features from all layers")) self.deselect_all_action.setToolTip("<b>{}</b>".format( self.deselect_all_action.text())) self.deselect_all_action.setObjectName("actionDeselectAll") self.deselect_all_action.triggered.connect(self.deselect_all) self.toolbar.addAction(self.deselect_all_action) self.toolbar.addAction(self.settings_action) self.iface.mainWindow().addToolBar(self.toolbar) # Embedded actions self.embedded_selection_tool_button_action = None self.embedded_selection_tool_button = None self.embedded_advanced_tool_button_action = None self.embedded_advanced_tool_button = None self.on_color_changed() self.on_settings_changed() def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" # Delete Settings dialog self.settings_dialog.deleteLater() # Remove menu from plugins menu self.iface.pluginMenu().removeAction(self.plugin_menu.menuAction()) self.select_freehand_tool.deleteLater() self.select_polygon_tool.deleteLater() self.select_radius_tool.deleteLater() self.select_rect_tool.deleteLater() self.iface.mainWindow().removeToolBar(self.toolbar) self.toolbar.deleteLater() self.replace_default_action(False) try: QgsProject.instance().selectionColorChanged.disconnect( self.on_color_changed) QgsProject.instance().selectionColorChanged.disconnect( self.settings_dialog.on_project_color_changed) except AttributeError: # QGIS < 3.10 pass def show_about(self): """ Show the about dialog """ # Used to display plugin icon in the about message box bogus = QWidget(self.iface.mainWindow()) bogus.setWindowIcon(QIcon(":/plugins/multilayerselect/icons/icon.svg")) cfg = configparser.ConfigParser() cfg.read(os.path.join(os.path.dirname(__file__), "metadata.txt")) version = cfg.get("general", "version") homepage = cfg.get("general", "homepage") tracker = cfg.get("general", "tracker") repository = cfg.get("general", "repository") QMessageBox.about( bogus, self.tr("About Multilayer Select"), "<b>Version</b> {3}<br><br>" "<b>{4}</b> : <a href={0}>GitHub</a><br>" "<b>{5}</b> : <a href={1}>GitHub</a><br>" "<b>{6}</b> : <a href={2}>GitHub Pages</a>".format( repository, tracker, homepage, version, self.tr("Source code"), self.tr("Report issues"), self.tr("Documentation"), ), ) bogus.deleteLater() def show_settings(self): """ Show the settings dialog """ geometry = self.settings_dialog.geometry() # The first time the dialog is shown (y=0), explicitely set its geometry # which allow to restore the geometry on subsequent calls if geometry.y() == 0: self.settings_dialog.show() self.settings_dialog.raise_() self.settings_dialog.setGeometry(self.settings_dialog.geometry()) return self.settings_dialog.show() self.settings_dialog.raise_() def on_color_changed(self): """ Called when the selection color has changed. Replace every icon """ color = self.iface.mapCanvas().selectionColor() color = QColor.fromHsv(color.hue(), color.saturation() * 0.9, color.value() * 0.95, color.alpha()) for i in range(len(self.select_actions)): path = self.actions_settings[i].icon icon = create_icon(path, color) self.select_actions[i].setIcon(icon) icon = create_icon(":/plugins/multilayerselect/icons/deselectAll.svg", color) self.deselect_all_action.setIcon(icon) icon = select_all_icon(color) self.select_all_action.setIcon(icon) icon = invert_selection_icon(color) self.invert_all_action.setIcon(icon) icon = expression_select_icon(color) self.select_by_expr_action.setIcon(icon) def on_settings_changed(self): """ Called when any setting has changed """ if self.settings.value("show_settings", True, bool): self.toolbar.addAction(self.settings_action) else: self.toolbar.removeAction(self.settings_action) self.replace_default_action( self.settings.value("replace_actions", False, bool)) def deselect_all(self): """ Deselect every feature """ for layer in QgsProject.instance().mapLayers().values(): if isinstance(layer, QgsVectorLayer): layer.removeSelection() update_status_message() def select_all(self): """ Select all the features from every vector layer """ for layer in vector_layers(): layer.selectAll() self.advanced_selection_tool_button.setDefaultAction( self.select_all_action) if self.embedded_advanced_tool_button: self.embedded_advanced_tool_button.setDefaultAction( self.select_all_action) update_status_message() def invert_all(self): """ Invert the selection of every vector layer """ for layer in vector_layers(): layer.invertSelection() self.advanced_selection_tool_button.setDefaultAction( self.invert_all_action) if self.embedded_advanced_tool_button: self.embedded_advanced_tool_button.setDefaultAction( self.invert_all_action) update_status_message() def select_by_expression(self): """ Create and open the Expression builder dialog""" if self.expression_dialog: self.expression_dialog.deleteLater() self.expression_dialog = MultiLayerSelectionExpressionBuilder() self.expression_dialog.show() self.advanced_selection_tool_button.setDefaultAction( self.select_by_expr_action) if self.embedded_advanced_tool_button: self.embedded_advanced_tool_button.setDefaultAction( self.select_by_expr_action) update_status_message() def replace_default_action(self, value): """Replace the default QGIS selection action with the multilayer ones Args: value (bool): If true, replace the actions, else put the multi actions inside their own toolbar """ toolbar = self.iface.attributesToolBar() main_window = self.iface.mainWindow() main_window.findChild(QAction, "ActionSelect").setVisible(not value) main_window.findChild(QAction, "ActionSelection").setVisible(not value) main_window.findChild(QAction, "mActionDeselectAll").setVisible(not value) actiontable = main_window.findChild(QAction, "mActionOpenTable") actionform = main_window.findChild(QAction, "mActionSelectByForm") # Remove the multi layer tool buttons from the QGIS attribute toolbar toolbar.removeAction(self.embedded_selection_tool_button_action) toolbar.removeAction(self.embedded_advanced_tool_button_action) if value: # Create the QToolButtons that will be added to the default toolbar self.embedded_selection_tool_button = QToolButton() self.embedded_selection_tool_button.setPopupMode( QToolButton.MenuButtonPopup) # Add selection tools action to the button (Rect, Polygon, Radius, Freehand) self.embedded_selection_tool_button.addActions(self.select_actions) self.embedded_selection_tool_button.setDefaultAction( self.select_actions[0]) self.embedded_advanced_tool_button = QToolButton() self.embedded_advanced_tool_button.setPopupMode( QToolButton.MenuButtonPopup) # Add Invert, Select All, Select from value and Select from expressions self.embedded_advanced_tool_button.addAction( self.select_all_action) self.embedded_advanced_tool_button.setDefaultAction( self.select_all_action) self.embedded_advanced_tool_button.addAction( self.invert_all_action) self.embedded_advanced_tool_button.addAction( self.select_by_expr_action) self.embedded_advanced_tool_button.addAction(actionform) self.embedded_selection_tool_button_action = toolbar.insertWidget( actiontable, self.embedded_selection_tool_button) self.embedded_advanced_tool_button_action = toolbar.insertWidget( actiontable, self.embedded_advanced_tool_button) # Add the deselect all action toolbar.insertAction(actiontable, self.deselect_all_action) # If the settigns is enabled add the show settings action if self.settings.value("show_settings", True, bool): toolbar.insertAction(actiontable, self.settings_action) else: toolbar.removeAction(self.settings_action) self.toolbar.hide() else: # Remove the multi actions from the default toolbar, and show # the custom toolbar self.embedded_selection_tool_button = None self.embedded_advanced_tool_button = None toolbar.removeAction(self.deselect_all_action) toolbar.removeAction(self.settings_action) self.toolbar.show()
class ListLayout(QWidget, CueLayout): NAME = 'List Layout' DESCRIPTION = ''' This layout organize the cues in a list: <ul> <li>Unlimited cues; <li>Side panel with playing media-cues; <li>Cues can be moved in the list; <li>Keyboard control; </ul>''' HEADER = ['', 'Cue', 'Duration', 'Progress'] # I need to redefine those from CueLayout key_pressed = CueLayout.key_pressed cue_added = CueLayout.cue_added cue_removed = CueLayout.cue_removed focus_changed = CueLayout.focus_changed def __init__(self, app, **kwds): super().__init__(**kwds) self.mainWindow = app.mainWindow self.menuLayout = self.mainWindow.menuLayout self._cue_items = [] self._playing_widgets = {} self._context_item = None self._show_dbmeter = config['ListLayout']['ShowDbMeters'] == 'True' self._show_seek = config['ListLayout']['ShowSeek'] == 'True' self._accurate_time = config['ListLayout']['ShowAccurate'] == 'True' self._auto_next = config['ListLayout']['AutoNext'] == 'True' # Add layout-specific menus self.showDbMeterAction = QAction(self) self.showDbMeterAction.setCheckable(True) self.showDbMeterAction.setChecked(self._show_dbmeter) self.showDbMeterAction.triggered.connect(self.set_dbmeter_visible) self.showSeekAction = QAction(self) self.showSeekAction.setCheckable(True) self.showSeekAction.setChecked(self._show_seek) self.showSeekAction.triggered.connect(self.set_seek_visible) self.accurateTimingAction = QAction(self) self.accurateTimingAction.setCheckable(True) self.accurateTimingAction.setChecked(self._accurate_time) self.accurateTimingAction.triggered.connect(self.set_accurate_time) self.autoNextAction = QAction(self) self.autoNextAction.setCheckable(True) self.autoNextAction.setChecked(self._auto_next) self.autoNextAction.triggered.connect(self.set_auto_next) self.menuLayout.addAction(self.showDbMeterAction) self.menuLayout.addAction(self.showSeekAction) self.menuLayout.addAction(self.accurateTimingAction) self.menuLayout.addAction(self.autoNextAction) # Add a toolbar to MainWindow self.toolBar = QToolBar(self.mainWindow) self.toolBar.setContextMenuPolicy(QtCore.Qt.PreventContextMenu) self.playAction = QAction(self) self.playAction.setIcon(QIcon.fromTheme("media-playback-start")) self.playAction.triggered.connect(self.play_current) self.pauseAction = QAction(self) self.pauseAction.setIcon(QIcon.fromTheme("media-playback-pause")) self.pauseAction.triggered.connect(self.pause_current) self.stopAction = QAction(self) self.stopAction.setIcon(QIcon.fromTheme("media-playback-stop")) self.stopAction.triggered.connect(self.stop_current) self.stopAllAction = QAction(self) self.stopAllAction.font().setBold(True) self.stopAllAction.triggered.connect(self.stop_all) self.pauseAllAction = QAction(self) self.pauseAllAction.font().setBold(True) self.pauseAllAction.triggered.connect(self.pause_all) self.restartAllAction = QAction(self) self.restartAllAction.font().setBold(True) self.restartAllAction.triggered.connect(self.restart_all) self.toolBar.addAction(self.playAction) self.toolBar.addAction(self.pauseAction) self.toolBar.addAction(self.stopAction) self.toolBar.addSeparator() self.toolBar.addAction(self.stopAllAction) self.toolBar.addAction(self.pauseAllAction) self.toolBar.addAction(self.restartAllAction) self.mainWindow.addToolBar(self.toolBar) self.hLayout = QHBoxLayout(self) self.hLayout.setContentsMargins(5, 5, 5, 5) # On the left (cue list) self.listView = ListWidget(self) self.listView.context_event.connect(self.context_event) self.listView.key_event.connect(self.onKeyPressEvent) self.listView.drop_move_event.connect(self.move_cue_at) self.listView.drop_copy_event.connect(self._copy_cue_at) self.listView.setHeaderLabels(self.HEADER) self.listView.header().setSectionResizeMode(QHeaderView.Fixed) self.listView.header().setSectionResizeMode(self.HEADER.index('Cue'), QHeaderView.Stretch) self.listView.setColumnWidth(0, 40) self.hLayout.addWidget(self.listView) self.vLayout = QVBoxLayout() self.vLayout.setContentsMargins(0, 0, 0, 0) self.vLayout.setSpacing(2) # On the right (playing media-cues) self.label = QLabel('Playing', self) self.label.setAlignment(QtCore.Qt.AlignCenter) self.label.setStyleSheet('font-size: 17pt; font-weight: bold;') self.vLayout.addWidget(self.label) self.playView = QListWidget(self) self.playView.setMinimumWidth(300) self.playView.setMaximumWidth(300) self.playView.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn) self.playView.setFocusPolicy(QtCore.Qt.NoFocus) self.playView.setSelectionMode(QAbstractItemView.NoSelection) self.vLayout.addWidget(self.playView) self.hLayout.addLayout(self.vLayout) # Add cue preferences widgets self.add_settings_section(MediaCueGeneral, MediaCue) self.add_settings_section(Appearance) # Context menu actions self.edit_action = QAction(self) self.edit_action.triggered.connect(self.edit_context_cue) self.remove_action = QAction(self) self.remove_action.triggered.connect(self.remove_context_cue) self.select_action = QAction(self) self.select_action.triggered.connect(self.select_context_cue) self.add_context_item(self.edit_action) self.sep1 = self.add_context_separator() self.add_context_item(self.remove_action) self.add_context_item(self.select_action) self.retranslateUi() def retranslateUi(self): self.showDbMeterAction.setText("Show Db-meters") self.showSeekAction.setText("Show seek bars") self.accurateTimingAction.setText('Accurate timing') self.autoNextAction.setText('Auto select next cue') self.playAction.setText("Go") self.pauseAction.setText("Pause") self.stopAction.setText("Stop") self.stopAllAction.setText("Stop All") self.pauseAllAction.setText("Pause All") self.restartAllAction.setText("Restart All") self.edit_action.setText('Edit option') self.remove_action.setText('Remove') self.select_action.setText('Select') def current_cue(self): item = self.current_item() if item is not None: return item.cue def current_item(self): if len(self._cue_items) > 0: return self._cue_items[self.listView.currentIndex().row()] def select_context_cue(self): self._context_item.select() def __add_cue__(self, cue, index): if isinstance(cue, MediaCue): item = MediaItem(cue, self.listView) # Use weak-references for avoid cyclic-references with lambda(s) wself = weakref.ref(self) wcue = weakref.ref(cue) cue.media.on_play.connect(lambda: wself().show_playing(wcue())) cue.media.interrupted.connect(lambda: wself().hide_playing(wcue())) cue.media.stopped.connect(lambda: wself().hide_playing(wcue())) cue.media.error.connect(lambda: wself().hide_playing(wcue())) cue.media.eos.connect(lambda: wself().hide_playing(wcue())) elif isinstance(cue, ActionCue): item = ActionItem(cue) item.cue = cue else: raise Exception('Cue type not supported') item.setFlags(item.flags() & ~QtCore.Qt.ItemIsDropEnabled) if index is None or (index < 0 or index >= len(self._cue_items)): cue['index'] = len(self._cue_items) self.listView.addTopLevelItem(item) self._cue_items.append(item) else: self.listView.insertTopLevelItem(index, item) self._cue_items.insert(index, item) for n in range(index, len(self._cue_items)): self._cue_items[n].cue['index'] = n if isinstance(item, MediaItem): item.init() if len(self._cue_items) == 1: self.listView.setCurrentItem(item) self.listView.setFocus() self.listView.resizeColumnToContents(1) self.cue_added.emit(cue) def set_accurate_time(self, enable): self._accurate_time = enable for i in range(self.playView.count()): widget = self.playView.itemWidget(self.playView.item(i)) widget.set_accurate_time(enable) for item in self._cue_items: if isinstance(item, MediaItem): item.set_accurate_time(enable) def set_auto_next(self, enable): self._auto_next = enable def set_seek_visible(self, visible): self._show_seek = visible for i in range(self.playView.count()): widget = self.playView.itemWidget(self.playView.item(i)) widget.set_seek_visible(visible) def set_dbmeter_visible(self, visible): self._show_dbmeter = visible for i in range(self.playView.count()): widget = self.playView.itemWidget(self.playView.item(i)) widget.set_dbmeter_visible(visible) def show_playing(self, cue): if cue not in self._playing_widgets: media_time = self._cue_items[cue['index']].media_time widget = PlayingMediaWidget(cue, media_time, self.playView) widget.set_dbmeter_visible(self._show_dbmeter) widget.set_seek_visible(self._show_seek) widget.set_accurate_time(self._accurate_time) list_item = QListWidgetItem() list_item.setSizeHint(widget.size()) self.playView.addItem(list_item) self.playView.setItemWidget(list_item, widget) self._playing_widgets[cue] = list_item def hide_playing(self, cue): if cue in self._playing_widgets: list_item = self._playing_widgets.pop(cue) widget = self.playView.itemWidget(list_item) row = self.playView.indexFromItem(list_item).row() self.playView.removeItemWidget(list_item) self.playView.takeItem(row) widget.destroy_widget() def onKeyPressEvent(self, e): if e.key() == QtCore.Qt.Key_Space: if qApp.keyboardModifiers() == Qt.ShiftModifier: cue = self.current_cue() if cue is not None: self.edit_cue(cue) elif qApp.keyboardModifiers() == Qt.ControlModifier: item = self.current_item() if item is not None: item.select() else: cue = self.current_cue() if cue is not None: cue.execute() if self._auto_next: nextitem = self.listView.currentIndex().row() + 1 if nextitem < self.listView.topLevelItemCount(): nextitem = self.listView.topLevelItem(nextitem) self.listView.setCurrentItem(nextitem) else: self.key_pressed.emit(e) e.accept() def play_current(self): cue = self.current_cue() if isinstance(cue, MediaCue): cue.media.play() else: cue.execute() def pause_current(self): cue = self.current_cue() if isinstance(cue, MediaCue): cue.media.pause() def stop_current(self): cue = self.current_cue() if isinstance(cue, MediaCue): cue.media.stop() def context_event(self, event): item = self.listView.itemAt(event.pos()) if item is not None: index = self.listView.indexOfTopLevelItem(item) self._context_item = self._cue_items[index] self.show_context_menu(event.globalPos()) event.accept() def remove_context_cue(self): self.remove_cue(self.get_context_cue()) def edit_context_cue(self): self.edit_cue(self.get_context_cue()) def stop_all(self): for item in self._cue_items: if isinstance(item.cue, MediaCue): item.cue.media.stop() def pause_all(self): for item in self._cue_items: if isinstance(item.cue, MediaCue): item.cue.media.pause() def restart_all(self): for item in self._cue_items: if isinstance(item.cue, MediaCue): if item.cue.media.state == Media.PAUSED: item.cue.media.play() def __remove_cue__(self, cue): index = cue['index'] self.listView.takeTopLevelItem(index) self._cue_items.pop(index) if isinstance(cue, MediaCue): cue.media.interrupt() if cue in self._playing_widgets: self.hide_playing(self._playing_widgets[cue]) for item in self._cue_items[index:]: item.cue['index'] = item.cue['index'] - 1 cue.finalize() self.cue_removed.emit(cue) def move_cue_at(self, old_index, index): self.move_cue(self._cue_items[old_index].cue, index) def _copy_cue_at(self, old_index, index): newcue = CueFactory.clone_cue(self._cue_items[old_index].cue) self.add_cue(newcue, index) def __move_cue__(self, cue, index): item = self._cue_items.pop(cue['index']) self._cue_items.insert(index, item) self.listView.setCurrentItem(item) if isinstance(item, MediaItem): item.init() for n, item in enumerate(self._cue_items): item.cue['index'] = n def get_cues(self, cue_class=Cue): # i -> item return [i.cue for i in self._cue_items if isinstance(i.cue, cue_class)] def get_cue_at(self, index): if index < len(self._cue_items): return self._cue_items[index].cue def get_cue_by_id(self, cue_id): for item in self._cue_items: if item.cue.cue_id() == cue_id: return item.cue def get_selected_cues(self, cue_class=Cue): cues = [] for item in self._cue_items: if item.selected and isinstance(item.cue, cue_class): cues.append(item.cue) return cues def clear_layout(self): while len(self._cue_items) > 0: self.__remove_cue__(self._cue_items[-1].cue) def destroy_layout(self): self.clear_layout() self.menuLayout.clear() self.mainWindow.removeToolBar(self.toolBar) self.toolBar.deleteLater() # Remove context-items self.remove_context_item(self.edit_action) self.remove_context_item(self.sep1) self.remove_context_item(self.remove_action) self.remove_context_item(self.select_action) # Remove settings-sections self.remove_settings_section(Appearance) self.remove_settings_section(MediaCueGeneral) # !! Delete the layout references !! self.deleteLater() def get_context_cue(self): return self._context_item.cue def select_all(self): for item in self._cue_items: if not item.selected: item.select() def deselect_all(self): for item in self._cue_items: if item.selected: item.select() def invert_selection(self): for item in self._cue_items: item.select()