--- a/QScintilla/Editor.py Fri May 18 19:41:02 2018 +0200 +++ b/QScintilla/Editor.py Sat May 19 16:38:28 2018 +0200 @@ -1172,7 +1172,7 @@ self.tr('Clear all bookmarks'), self.clearBookmarks) self.bmMarginMenu.aboutToShow.connect( - lambda: self.__showContextMenuMargin(self.bmMarginMenu)) + lambda: self.__showContextMenuMargin(self.bmMarginMenu, False)) # breakpoint margin self.bpMarginMenu = QMenu() @@ -1197,7 +1197,40 @@ self.tr('Clear all breakpoints'), self.__menuClearBreakpoints) self.bpMarginMenu.aboutToShow.connect( - lambda: self.__showContextMenuMargin(self.bpMarginMenu)) + lambda: self.__showContextMenuMargin(self.bpMarginMenu, False)) + + # fold margin + self.foldMarginMenu = QMenu() + + self.marginMenuActs["ToggleAllFolds"] = \ + self.foldMarginMenu.addAction( + self.tr("Toggle all folds"), + self.foldAll) + self.marginMenuActs["ToggleAllFoldsAndChildren"] = \ + self.foldMarginMenu.addAction( + self.tr("Toggle all folds (including children)"), + lambda: self.foldAll(True)) + self.marginMenuActs["ToggleCurrentFold"] = \ + self.foldMarginMenu.addAction( + self.tr("Toggle current fold"), + self.toggleCurrentFold) + self.foldMarginMenu.addSeparator() + self.marginMenuActs["ExpandChildren"] = \ + self.foldMarginMenu.addAction( + self.tr("Expand (including children)"), + self.__contextMenuExpandFoldWithChildren) + self.marginMenuActs["CollapseChildren"] = \ + self.foldMarginMenu.addAction( + self.tr("Collapse (including children)"), + self.__contextMenuCollapseFoldWithChildren) + self.foldMarginMenu.addSeparator() + self.marginMenuActs["ClearAllFolds"] = \ + self.foldMarginMenu.addAction( + self.tr("Clear all folds"), + self.clearFolds) + + self.foldMarginMenu.aboutToShow.connect( + lambda: self.__showContextMenuMargin(self.foldMarginMenu, False)) # indicator margin self.indicMarginMenu = QMenu() @@ -1251,7 +1284,7 @@ self.tr('Clear changes'), self.__reinitOnlineChangeTrace) self.indicMarginMenu.aboutToShow.connect( - lambda: self.__showContextMenuMargin(self.indicMarginMenu)) + lambda: self.__showContextMenuMargin(self.indicMarginMenu, False)) def __initContextMenuUnifiedMargins(self): """ @@ -1332,7 +1365,7 @@ self.marginMenuActs["LMBbreakpoints"].setChecked(True) self.marginMenu.aboutToShow.connect( - lambda: self.__showContextMenuMargin(self.marginMenu)) + lambda: self.__showContextMenuMargin(self.marginMenu, True)) def __exportMenuTriggered(self, act): """ @@ -3313,22 +3346,36 @@ ## Utility methods below ########################################################################### - def ensureVisible(self, line): + def ensureVisible(self, line, expand=False): """ Public slot to ensure, that the specified line is visible. @param line line number to make visible + @type int + @keyparam expand flag indicating to expand all folds + @type bool """ self.ensureLineVisible(line - 1) - - def ensureVisibleTop(self, line): + if expand: + self.SendScintilla(QsciScintilla.SCI_FOLDCHILDREN, line - 1, + QsciScintilla.SC_FOLDACTION_EXPAND) + + def ensureVisibleTop(self, line, expand=False): """ Public slot to ensure, that the specified line is visible at the top of the editor. @param line line number to make visible - """ + @type int + @keyparam expand flag indicating to expand all folds + @type bool + """ + self.ensureVisible(line) self.setFirstVisibleLine(line - 1) + self.ensureCursorVisible() + if expand: + self.SendScintilla(QsciScintilla.SCI_FOLDCHILDREN, line - 1, + QsciScintilla.SC_FOLDACTION_EXPAND) def __marginClicked(self, margin, line, modifiers): """ @@ -4021,20 +4068,25 @@ else: self.__indentLine(True) - def gotoLine(self, line, pos=1, firstVisible=False): + def gotoLine(self, line, pos=1, firstVisible=False, expand=False): """ Public slot to jump to the beginning of a line. - @param line line number to go to (integer) - @keyparam pos position in line to go to (integer) + @param line line number to go to + @type int + @keyparam pos position in line to go to + @type int @keyparam firstVisible flag indicating to make the line the first - visible line (boolean) + visible line + @type bool + @keyparam expand flag indicating to expand all folds + @type bool """ self.setCursorPosition(line - 1, pos - 1) if firstVisible: - self.ensureVisibleTop(line) - else: - self.ensureVisible(line) + self.ensureVisibleTop(line, expand) + else: + self.ensureVisible(line, expand) def __textChanged(self): """ @@ -5215,6 +5267,8 @@ self.bpMarginMenu.popup(evt.globalPos()) elif self.__marginNumber(evt.x()) == self.__indicMargin: self.indicMarginMenu.popup(evt.globalPos()) + elif self.__marginNumber(evt.x()) == self.__foldMargin: + self.foldMarginMenu.popup(evt.globalPos()) def __showContextMenu(self): """ @@ -5376,104 +5430,109 @@ self.showMenu.emit("Graphics", self.graphicsMenu, self) - def __showContextMenuMargin(self, menu): + def __showContextMenuMargin(self, menu, unifiedMenu): """ Private slot handling the aboutToShow signal of the margins context menu. @param menu reference to the menu to be shown @type QMenu - """ - if self.fileName and self.isPyFile(): - self.marginMenuActs["Breakpoint"].setEnabled(True) - self.marginMenuActs["TempBreakpoint"].setEnabled(True) - if self.markersAtLine(self.line) & self.breakpointMask: - self.marginMenuActs["EditBreakpoint"].setEnabled(True) - self.marginMenuActs["EnableBreakpoint"].setEnabled(True) + @param unifiedMenu flag indicating the unified margins menu + @type bool + """ + if unifiedMenu or menu is self.bpMarginMenu: + if self.fileName and self.isPyFile(): + self.marginMenuActs["Breakpoint"].setEnabled(True) + self.marginMenuActs["TempBreakpoint"].setEnabled(True) + if self.markersAtLine(self.line) & self.breakpointMask: + self.marginMenuActs["EditBreakpoint"].setEnabled(True) + self.marginMenuActs["EnableBreakpoint"].setEnabled(True) + else: + self.marginMenuActs["EditBreakpoint"].setEnabled(False) + self.marginMenuActs["EnableBreakpoint"].setEnabled(False) + if self.markersAtLine(self.line) & (1 << self.dbreakpoint): + self.marginMenuActs["EnableBreakpoint"].setText( + self.tr('Enable breakpoint')) + else: + self.marginMenuActs["EnableBreakpoint"].setText( + self.tr('Disable breakpoint')) + if self.breaks: + self.marginMenuActs["NextBreakpoint"].setEnabled(True) + self.marginMenuActs["PreviousBreakpoint"].setEnabled(True) + self.marginMenuActs["ClearBreakpoint"].setEnabled(True) + else: + self.marginMenuActs["NextBreakpoint"].setEnabled(False) + self.marginMenuActs["PreviousBreakpoint"].setEnabled(False) + self.marginMenuActs["ClearBreakpoint"].setEnabled(False) else: + self.marginMenuActs["Breakpoint"].setEnabled(False) + self.marginMenuActs["TempBreakpoint"].setEnabled(False) self.marginMenuActs["EditBreakpoint"].setEnabled(False) self.marginMenuActs["EnableBreakpoint"].setEnabled(False) - if self.markersAtLine(self.line) & (1 << self.dbreakpoint): - self.marginMenuActs["EnableBreakpoint"].setText( - self.tr('Enable breakpoint')) - else: - self.marginMenuActs["EnableBreakpoint"].setText( - self.tr('Disable breakpoint')) - if self.breaks: - self.marginMenuActs["NextBreakpoint"].setEnabled(True) - self.marginMenuActs["PreviousBreakpoint"].setEnabled(True) - self.marginMenuActs["ClearBreakpoint"].setEnabled(True) - else: self.marginMenuActs["NextBreakpoint"].setEnabled(False) self.marginMenuActs["PreviousBreakpoint"].setEnabled(False) self.marginMenuActs["ClearBreakpoint"].setEnabled(False) - else: - self.marginMenuActs["Breakpoint"].setEnabled(False) - self.marginMenuActs["TempBreakpoint"].setEnabled(False) - self.marginMenuActs["EditBreakpoint"].setEnabled(False) - self.marginMenuActs["EnableBreakpoint"].setEnabled(False) - self.marginMenuActs["NextBreakpoint"].setEnabled(False) - self.marginMenuActs["PreviousBreakpoint"].setEnabled(False) - self.marginMenuActs["ClearBreakpoint"].setEnabled(False) + + if unifiedMenu or menu is self.bmMarginMenu: + if self.bookmarks: + self.marginMenuActs["NextBookmark"].setEnabled(True) + self.marginMenuActs["PreviousBookmark"].setEnabled(True) + self.marginMenuActs["ClearBookmark"].setEnabled(True) + else: + self.marginMenuActs["NextBookmark"].setEnabled(False) + self.marginMenuActs["PreviousBookmark"].setEnabled(False) + self.marginMenuActs["ClearBookmark"].setEnabled(False) - if self.bookmarks: - self.marginMenuActs["NextBookmark"].setEnabled(True) - self.marginMenuActs["PreviousBookmark"].setEnabled(True) - self.marginMenuActs["ClearBookmark"].setEnabled(True) - else: - self.marginMenuActs["NextBookmark"].setEnabled(False) - self.marginMenuActs["PreviousBookmark"].setEnabled(False) - self.marginMenuActs["ClearBookmark"].setEnabled(False) - - if len(self.syntaxerrors): - self.marginMenuActs["GotoSyntaxError"].setEnabled(True) - self.marginMenuActs["ClearSyntaxError"].setEnabled(True) - if self.markersAtLine(self.line) & (1 << self.syntaxerror): - self.marginMenuActs["ShowSyntaxError"].setEnabled(True) + if unifiedMenu or menu is self.indicMarginMenu: + if len(self.syntaxerrors): + self.marginMenuActs["GotoSyntaxError"].setEnabled(True) + self.marginMenuActs["ClearSyntaxError"].setEnabled(True) + if self.markersAtLine(self.line) & (1 << self.syntaxerror): + self.marginMenuActs["ShowSyntaxError"].setEnabled(True) + else: + self.marginMenuActs["ShowSyntaxError"].setEnabled(False) else: + self.marginMenuActs["GotoSyntaxError"].setEnabled(False) + self.marginMenuActs["ClearSyntaxError"].setEnabled(False) self.marginMenuActs["ShowSyntaxError"].setEnabled(False) - else: - self.marginMenuActs["GotoSyntaxError"].setEnabled(False) - self.marginMenuActs["ClearSyntaxError"].setEnabled(False) - self.marginMenuActs["ShowSyntaxError"].setEnabled(False) - - if len(self.warnings): - self.marginMenuActs["NextWarningMarker"].setEnabled(True) - self.marginMenuActs["PreviousWarningMarker"].setEnabled(True) - self.marginMenuActs["ClearWarnings"].setEnabled(True) - if self.markersAtLine(self.line) & (1 << self.warning): - self.marginMenuActs["ShowWarning"].setEnabled(True) + + if len(self.warnings): + self.marginMenuActs["NextWarningMarker"].setEnabled(True) + self.marginMenuActs["PreviousWarningMarker"].setEnabled(True) + self.marginMenuActs["ClearWarnings"].setEnabled(True) + if self.markersAtLine(self.line) & (1 << self.warning): + self.marginMenuActs["ShowWarning"].setEnabled(True) + else: + self.marginMenuActs["ShowWarning"].setEnabled(False) else: + self.marginMenuActs["NextWarningMarker"].setEnabled(False) + self.marginMenuActs["PreviousWarningMarker"].setEnabled(False) + self.marginMenuActs["ClearWarnings"].setEnabled(False) self.marginMenuActs["ShowWarning"].setEnabled(False) - else: - self.marginMenuActs["NextWarningMarker"].setEnabled(False) - self.marginMenuActs["PreviousWarningMarker"].setEnabled(False) - self.marginMenuActs["ClearWarnings"].setEnabled(False) - self.marginMenuActs["ShowWarning"].setEnabled(False) - - if self.notcoveredMarkers: - self.marginMenuActs["NextCoverageMarker"].setEnabled(True) - self.marginMenuActs["PreviousCoverageMarker"].setEnabled(True) - else: - self.marginMenuActs["NextCoverageMarker"].setEnabled(False) - self.marginMenuActs["PreviousCoverageMarker"].setEnabled(False) - - if self.__hasTaskMarkers: - self.marginMenuActs["PreviousTaskMarker"].setEnabled(True) - self.marginMenuActs["NextTaskMarker"].setEnabled(True) - else: - self.marginMenuActs["PreviousTaskMarker"].setEnabled(False) - self.marginMenuActs["NextTaskMarker"].setEnabled(False) - - if self.__hasChangeMarkers: - self.marginMenuActs["PreviousChangeMarker"].setEnabled(True) - self.marginMenuActs["NextChangeMarker"].setEnabled(True) - self.marginMenuActs["ClearChangeMarkers"].setEnabled(True) + + if self.notcoveredMarkers: + self.marginMenuActs["NextCoverageMarker"].setEnabled(True) + self.marginMenuActs["PreviousCoverageMarker"].setEnabled(True) + else: + self.marginMenuActs["NextCoverageMarker"].setEnabled(False) + self.marginMenuActs["PreviousCoverageMarker"].setEnabled(False) - else: - self.marginMenuActs["PreviousChangeMarker"].setEnabled(False) - self.marginMenuActs["NextChangeMarker"].setEnabled(False) - self.marginMenuActs["ClearChangeMarkers"].setEnabled(False) + if self.__hasTaskMarkers: + self.marginMenuActs["PreviousTaskMarker"].setEnabled(True) + self.marginMenuActs["NextTaskMarker"].setEnabled(True) + else: + self.marginMenuActs["PreviousTaskMarker"].setEnabled(False) + self.marginMenuActs["NextTaskMarker"].setEnabled(False) + + if self.__hasChangeMarkers: + self.marginMenuActs["PreviousChangeMarker"].setEnabled(True) + self.marginMenuActs["NextChangeMarker"].setEnabled(True) + self.marginMenuActs["ClearChangeMarkers"].setEnabled(True) + + else: + self.marginMenuActs["PreviousChangeMarker"].setEnabled(False) + self.marginMenuActs["NextChangeMarker"].setEnabled(False) + self.marginMenuActs["ClearChangeMarkers"].setEnabled(False) self.showMenu.emit("Margin", menu, self) @@ -6437,6 +6496,55 @@ self.__setAnnotation(line) ################################################################# + ## Fold handling methods + ################################################################# + + def toggleCurrentFold(self): + """ + Public slot to toggle the fold containing the current line. + """ + line, index = self.getCursorPosition() + self.foldLine(line) + + def expandFoldWithChildren(self, line=-1): + """ + Public slot to expand the current fold including its children. + + @param line number of line to be expanded + @type int + """ + if line == -1: + line, index = self.getCursorPosition() + + self.SendScintilla(QsciScintilla.SCI_FOLDCHILDREN, line, + QsciScintilla.SC_FOLDACTION_EXPAND) + + def collapseFoldWithChildren(self, line=-1): + """ + Public slot to collapse the current fold including its children. + + @param line number of line to be expanded + @type int + """ + if line == -1: + line, index = self.getCursorPosition() + + self.SendScintilla(QsciScintilla.SCI_FOLDCHILDREN, line, + QsciScintilla.SC_FOLDACTION_CONTRACT) + + def __contextMenuExpandFoldWithChildren(self): + """ + Private slot to handle the context menu expand with children action. + """ + self.expandFoldWithChildren(self.line) + + def __contextMenuCollapseFoldWithChildren(self): + """ + Private slot to handle the context menu collapse with children action. + """ + self.collapseFoldWithChildren(self.line) + + ################################################################# ## Macro handling methods #################################################################