--- a/QScintilla/Editor.py Tue May 01 12:04:30 2018 +0200 +++ b/QScintilla/Editor.py Sat Jun 02 12:44:41 2018 +0200 @@ -29,7 +29,7 @@ from E5Gui import E5FileDialog, E5MessageBox from E5Utilities.E5Cache import E5Cache -from .QsciScintillaCompat import QsciScintillaCompat, QSCINTILLA_VERSION +from .QsciScintillaCompat import QsciScintillaCompat from .EditorMarkerMap import EditorMarkerMap import Preferences @@ -273,12 +273,6 @@ self.cursorPositionChanged.connect(self.__cursorPositionChanged) self.modificationAttempted.connect(self.__modificationReadOnly) - # margins layout - if QSCINTILLA_VERSION() >= 0x020301: - self.__unifiedMargins = Preferences.getEditor("UnifiedMargins") - else: - self.__unifiedMargins = True - # define the margins markers self.__changeMarkerSaved = self.markerDefine( self.__createChangeMarkerPixmap( @@ -416,7 +410,8 @@ self.__acWatchdog.timeout.connect(self.autoCompleteQScintilla) self.userListActivated.connect(self.__completionListSelected) - self.SCN_CHARADDED.connect(self.__charAddedPermanent) + self.SCN_CHARADDED.connect(self.__charAdded) + self.SCN_AUTOCCANCELLED.connect(self.__autocompletionCancelled) self.__completionListHookFunctions = {} self.__completionListAsyncHookFunctions = {} @@ -1149,16 +1144,6 @@ """ self.marginMenuActs = {} - if self.__unifiedMargins: - self.__initContextMenuUnifiedMargins() - else: - self.__initContextMenuSeparateMargins() - - def __initContextMenuSeparateMargins(self): - """ - Private method used to setup the context menu for the separated - margins. - """ # bookmark margin self.bmMarginMenu = QMenu() @@ -1199,6 +1184,39 @@ self.bpMarginMenu.aboutToShow.connect( lambda: self.__showContextMenuMargin(self.bpMarginMenu)) + # 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)) + # indicator margin self.indicMarginMenu = QMenu() @@ -1253,87 +1271,6 @@ self.indicMarginMenu.aboutToShow.connect( lambda: self.__showContextMenuMargin(self.indicMarginMenu)) - def __initContextMenuUnifiedMargins(self): - """ - Private method used to setup the context menu for the unified margins. - """ - self.marginMenu = QMenu() - - self.marginMenu.addAction( - self.tr('Toggle bookmark'), self.menuToggleBookmark) - self.marginMenuActs["NextBookmark"] = self.marginMenu.addAction( - self.tr('Next bookmark'), self.nextBookmark) - self.marginMenuActs["PreviousBookmark"] = self.marginMenu.addAction( - self.tr('Previous bookmark'), self.previousBookmark) - self.marginMenuActs["ClearBookmark"] = self.marginMenu.addAction( - self.tr('Clear all bookmarks'), self.clearBookmarks) - self.marginMenu.addSeparator() - self.marginMenuActs["GotoSyntaxError"] = self.marginMenu.addAction( - self.tr('Goto syntax error'), self.gotoSyntaxError) - self.marginMenuActs["ShowSyntaxError"] = self.marginMenu.addAction( - self.tr('Show syntax error message'), self.__showSyntaxError) - self.marginMenuActs["ClearSyntaxError"] = self.marginMenu.addAction( - self.tr('Clear syntax error'), self.clearSyntaxError) - self.marginMenu.addSeparator() - self.marginMenuActs["NextWarningMarker"] = self.marginMenu.addAction( - self.tr("Next warning"), self.nextWarning) - self.marginMenuActs["PreviousWarningMarker"] = \ - self.marginMenu.addAction( - self.tr("Previous warning"), self.previousWarning) - self.marginMenuActs["ShowWarning"] = self.marginMenu.addAction( - self.tr('Show warning message'), self.__showWarning) - self.marginMenuActs["ClearWarnings"] = self.marginMenu.addAction( - self.tr('Clear warnings'), self.clearWarnings) - self.marginMenu.addSeparator() - self.marginMenuActs["Breakpoint"] = self.marginMenu.addAction( - self.tr('Toggle breakpoint'), self.menuToggleBreakpoint) - self.marginMenuActs["TempBreakpoint"] = self.marginMenu.addAction( - self.tr('Toggle temporary breakpoint'), - self.__menuToggleTemporaryBreakpoint) - self.marginMenuActs["EditBreakpoint"] = self.marginMenu.addAction( - self.tr('Edit breakpoint...'), self.menuEditBreakpoint) - self.marginMenuActs["EnableBreakpoint"] = self.marginMenu.addAction( - self.tr('Enable breakpoint'), - self.__menuToggleBreakpointEnabled) - self.marginMenuActs["NextBreakpoint"] = self.marginMenu.addAction( - self.tr('Next breakpoint'), self.menuNextBreakpoint) - self.marginMenuActs["PreviousBreakpoint"] = self.marginMenu.addAction( - self.tr('Previous breakpoint'), self.menuPreviousBreakpoint) - self.marginMenuActs["ClearBreakpoint"] = self.marginMenu.addAction( - self.tr('Clear all breakpoints'), self.__menuClearBreakpoints) - self.marginMenu.addSeparator() - self.marginMenuActs["NextCoverageMarker"] = self.marginMenu.addAction( - self.tr('Next uncovered line'), self.nextUncovered) - self.marginMenuActs["PreviousCoverageMarker"] = \ - self.marginMenu.addAction( - self.tr('Previous uncovered line'), self.previousUncovered) - self.marginMenu.addSeparator() - self.marginMenuActs["NextTaskMarker"] = self.marginMenu.addAction( - self.tr('Next task'), self.nextTask) - self.marginMenuActs["PreviousTaskMarker"] = self.marginMenu.addAction( - self.tr('Previous task'), self.previousTask) - self.marginMenu.addSeparator() - self.marginMenuActs["NextChangeMarker"] = self.marginMenu.addAction( - self.tr('Next change'), self.nextChange) - self.marginMenuActs["PreviousChangeMarker"] = \ - self.marginMenu.addAction( - self.tr('Previous change'), self.previousChange) - self.marginMenuActs["ClearChangeMarkers"] = \ - self.marginMenu.addAction( - self.tr('Clear changes'), self.__reinitOnlineChangeTrace) - self.marginMenu.addSeparator() - self.marginMenuActs["LMBbookmarks"] = self.marginMenu.addAction( - self.tr('LMB toggles bookmarks'), self.__lmBbookmarks) - self.marginMenuActs["LMBbookmarks"].setCheckable(True) - self.marginMenuActs["LMBbookmarks"].setChecked(False) - self.marginMenuActs["LMBbreakpoints"] = self.marginMenu.addAction( - self.tr('LMB toggles breakpoints'), self.__lmBbreakpoints) - self.marginMenuActs["LMBbreakpoints"].setCheckable(True) - self.marginMenuActs["LMBbreakpoints"].setChecked(True) - - self.marginMenu.aboutToShow.connect( - lambda: self.__showContextMenuMargin(self.marginMenu)) - def __exportMenuTriggered(self, act): """ Private method to handle the selection of an export format. @@ -2358,6 +2295,7 @@ self.breakpointModel.setBreakPointByIndex( index, self.fileName, ln, (cond, temp, enabled, ignorecount)) + break self.line = -1 @@ -3313,22 +3251,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): """ @@ -3338,33 +3290,15 @@ @param line line number of the click (integer) @param modifiers keyboard modifiers (Qt.KeyboardModifiers) """ - if self.__unifiedMargins: - if margin == 1: - if modifiers & Qt.KeyboardModifiers(Qt.ShiftModifier): - if self.marginMenuActs["LMBbreakpoints"].isChecked(): - self.toggleBookmark(line + 1) - else: - self.__toggleBreakpoint(line + 1) - elif modifiers & Qt.KeyboardModifiers(Qt.ControlModifier): - if self.markersAtLine(line) & (1 << self.syntaxerror): - self.__showSyntaxError(line) - elif self.markersAtLine(line) & (1 << self.warning): - self.__showWarning(line) - else: - if self.marginMenuActs["LMBbreakpoints"].isChecked(): - self.__toggleBreakpoint(line + 1) - else: - self.toggleBookmark(line + 1) - else: - if margin == self.__bmMargin: - self.toggleBookmark(line + 1) - elif margin == self.__bpMargin: - self.__toggleBreakpoint(line + 1) - elif margin == self.__indicMargin: - if self.markersAtLine(line) & (1 << self.syntaxerror): - self.__showSyntaxError(line) - elif self.markersAtLine(line) & (1 << self.warning): - self.__showWarning(line) + if margin == self.__bmMargin: + self.toggleBookmark(line + 1) + elif margin == self.__bpMargin: + self.__toggleBreakpoint(line + 1) + elif margin == self.__indicMargin: + if self.markersAtLine(line) & (1 << self.syntaxerror): + self.__showSyntaxError(line) + elif self.markersAtLine(line) & (1 << self.warning): + self.__showWarning(line) def handleMonospacedEnable(self): """ @@ -4021,20 +3955,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) + self.ensureVisibleTop(line, expand) else: - self.ensureVisible(line) + self.ensureVisible(line, expand) def __textChanged(self): """ @@ -4142,10 +4081,6 @@ if self.completer is not None: self.completer.readSettings() - # set the margins layout - if QSCINTILLA_VERSION() >= 0x020301: - self.__unifiedMargins = Preferences.getEditor("UnifiedMargins") - # set the line marker colours or pixmap if Preferences.getEditor("LineMarkersBackground"): self.markerDefine(QsciScintilla.Background, self.currentline) @@ -4223,6 +4158,8 @@ # refresh the annotations display self.__refreshAnnotations() + self.__markerMap.setMapPosition( + Preferences.getEditor("ShowMarkerMapOnRight")) self.__markerMap.initColors() self.settingsRead.emit() @@ -4259,60 +4196,37 @@ self.setMarginSensitivity(margin, False) # set marker margin(s) settings - if self.__unifiedMargins: - margin1Mask = (1 << self.breakpoint) | \ - (1 << self.cbreakpoint) | \ - (1 << self.tbreakpoint) | \ - (1 << self.tcbreakpoint) | \ - (1 << self.dbreakpoint) | \ - (1 << self.currentline) | \ - (1 << self.errorline) | \ - (1 << self.bookmark) | \ - (1 << self.syntaxerror) | \ + self.__bmMargin = 0 + self.__linenoMargin = 1 + self.__bpMargin = 2 + self.__foldMargin = 3 + self.__indicMargin = 4 + + marginBmMask = (1 << self.bookmark) + self.setMarginWidth(self.__bmMargin, 16) + self.setMarginSensitivity(self.__bmMargin, True) + self.setMarginMarkerMask(self.__bmMargin, marginBmMask) + + marginBpMask = (1 << self.breakpoint) | \ + (1 << self.cbreakpoint) | \ + (1 << self.tbreakpoint) | \ + (1 << self.tcbreakpoint) | \ + (1 << self.dbreakpoint) + self.setMarginWidth(self.__bpMargin, 16) + self.setMarginSensitivity(self.__bpMargin, True) + self.setMarginMarkerMask(self.__bpMargin, marginBpMask) + + marginIndicMask = (1 << self.syntaxerror) | \ (1 << self.notcovered) | \ (1 << self.taskmarker) | \ (1 << self.warning) | \ (1 << self.__changeMarkerUnsaved) | \ - (1 << self.__changeMarkerSaved) - self.setMarginWidth(1, 16) - self.setMarginSensitivity(1, True) - self.setMarginMarkerMask(1, margin1Mask) - - self.__linenoMargin = 0 - self.__foldMargin = 2 - else: - - self.__bmMargin = 0 - self.__linenoMargin = 1 - self.__bpMargin = 2 - self.__foldMargin = 3 - self.__indicMargin = 4 - - marginBmMask = (1 << self.bookmark) - self.setMarginWidth(self.__bmMargin, 16) - self.setMarginSensitivity(self.__bmMargin, True) - self.setMarginMarkerMask(self.__bmMargin, marginBmMask) - - marginBpMask = (1 << self.breakpoint) | \ - (1 << self.cbreakpoint) | \ - (1 << self.tbreakpoint) | \ - (1 << self.tcbreakpoint) | \ - (1 << self.dbreakpoint) - self.setMarginWidth(self.__bpMargin, 16) - self.setMarginSensitivity(self.__bpMargin, True) - self.setMarginMarkerMask(self.__bpMargin, marginBpMask) - - marginIndicMask = (1 << self.syntaxerror) | \ - (1 << self.notcovered) | \ - (1 << self.taskmarker) | \ - (1 << self.warning) | \ - (1 << self.__changeMarkerUnsaved) | \ - (1 << self.__changeMarkerSaved) | \ - (1 << self.currentline) | \ - (1 << self.errorline) - self.setMarginWidth(self.__indicMargin, 16) - self.setMarginSensitivity(self.__indicMargin, True) - self.setMarginMarkerMask(self.__indicMargin, marginIndicMask) + (1 << self.__changeMarkerSaved) | \ + (1 << self.currentline) | \ + (1 << self.errorline) + self.setMarginWidth(self.__indicMargin, 16) + self.setMarginSensitivity(self.__indicMargin, True) + self.setMarginMarkerMask(self.__indicMargin, marginIndicMask) # set linenumber margin settings linenoMargin = Preferences.getEditor("LinenoMargin") @@ -4507,6 +4421,7 @@ Preferences.getEditor("AutoCompletionCaseSensitivity")) self.setAutoCompletionReplaceWord( Preferences.getEditor("AutoCompletionReplaceWord")) + self.setAutoCompletionThreshold(0) try: self.setAutoCompletionUseSingle( Preferences.getEditor("AutoCompletionShowSingle")) @@ -4520,16 +4435,9 @@ self.setAutoCompletionSource(QsciScintilla.AcsAPIs) else: self.setAutoCompletionSource(QsciScintilla.AcsAll) - if Preferences.getEditor("AutoCompletionEnabled"): - if not self.__completionListHookFunctions and \ - not self.__completionListAsyncHookFunctions: - self.setAutoCompletionThreshold( - Preferences.getEditor("AutoCompletionThreshold")) - else: - self.setAutoCompletionThreshold(0) - else: - self.setAutoCompletionThreshold(-1) - self.setAutoCompletionSource(QsciScintilla.AcsNone) + + self.maxLines = Preferences.getEditor("AutoCompletionMaxLines") + self.maxChars = Preferences.getEditor("AutoCompletionMaxChars") def __setCallTips(self): """ @@ -4601,8 +4509,6 @@ (boolean) """ if enable: - self.setAutoCompletionThreshold( - Preferences.getEditor("AutoCompletionThreshold")) autoCompletionSource = \ Preferences.getEditor("AutoCompletionSource") if autoCompletionSource == QsciScintilla.AcsDocument: @@ -4611,10 +4517,7 @@ self.setAutoCompletionSource(QsciScintilla.AcsAPIs) else: self.setAutoCompletionSource(QsciScintilla.AcsAll) - else: - self.setAutoCompletionThreshold(-1) - self.setAutoCompletionSource(QsciScintilla.AcsNone) - + def __toggleAutoCompletionEnable(self): """ Private slot to handle the Enable Autocompletion context menu entry. @@ -4634,8 +4537,13 @@ @param charNumber value of the character entered (integer) """ + char = chr(charNumber) + # update code documentation viewer + if char == "(" and \ + Preferences.getDocuViewer("ShowInfoOnOpenParenthesis"): + self.vm.showEditorInfo(self) + if self.isListActive(): - char = chr(charNumber) if self.__isStartChar(char): self.cancelList() self.autoComplete(auto=True, context=True) @@ -4718,13 +4626,6 @@ .format(key)) return - if not self.__completionListHookFunctions and \ - not self.__completionListAsyncHookFunctions: - if self.autoCompletionThreshold() > 0: - self.setAutoCompletionThreshold(0) - self.SCN_CHARADDED.connect(self.__charAdded) - self.SCN_AUTOCCANCELLED.connect(self.__autocompletionCancelled) - if asynchroneous: self.__completionListAsyncHookFunctions[key] = func else: @@ -4742,14 +4643,6 @@ del self.__completionListHookFunctions[key] elif key in self.__completionListAsyncHookFunctions: del self.__completionListAsyncHookFunctions[key] - - if not self.__completionListHookFunctions and \ - not self.__completionListAsyncHookFunctions: - self.SCN_CHARADDED.disconnect(self.__charAdded) - self.SCN_AUTOCCANCELLED.disconnect(self.__autocompletionCancelled) - if self.autoCompletionThreshold() == 0: - self.setAutoCompletionThreshold( - Preferences.getEditor("AutoCompletionThreshold")) def getCompletionListHook(self, key): """ @@ -4771,7 +4664,7 @@ (boolean) @keyparam context flag indicating to complete a context (boolean) """ - if auto and self.autoCompletionThreshold() == -1: + if auto and not Preferences.getEditor("AutoCompletionEnabled"): # auto-completion is disabled return @@ -5148,20 +5041,6 @@ ## Methods needed by the code documentation viewer ################################################################# - def __charAddedPermanent(self, charNumber): - """ - Private slot called to handle the user entering a character. - - Note: This slot is always connected independent of the auto-completion - and calltips handling __charAdded() slot. - - @param charNumber value of the character entered (integer) - """ - char = chr(charNumber) - if char == "(" and \ - Preferences.getDocuViewer("ShowInfoOnOpenParenthesis"): - self.vm.showEditorInfo(self) - def __showCodeInfo(self): """ Private slot to handle the context menu action to show code info. @@ -5203,16 +5082,15 @@ self.menu.popup(evt.globalPos()) else: self.line = self.lineAt(evt.pos()) - if self.__unifiedMargins: - self.marginMenu.popup(evt.globalPos()) - else: - if self.__marginNumber(evt.x()) in [self.__bmMargin, - self.__linenoMargin]: - self.bmMarginMenu.popup(evt.globalPos()) - elif self.__marginNumber(evt.x()) == self.__bpMargin: - self.bpMarginMenu.popup(evt.globalPos()) - elif self.__marginNumber(evt.x()) == self.__indicMargin: - self.indicMarginMenu.popup(evt.globalPos()) + if self.__marginNumber(evt.x()) in [self.__bmMargin, + self.__linenoMargin]: + self.bmMarginMenu.popup(evt.globalPos()) + elif self.__marginNumber(evt.x()) == self.__bpMargin: + 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): """ @@ -5333,7 +5211,7 @@ (self.project.isPy3Project() or self.project.isPy2Project()) - # now check ourself + # now check ourselves fn = self.getFileName() if fn is not None: tfn = Utilities.getTestFileName(fn) @@ -5382,96 +5260,86 @@ @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) - 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) - self.marginMenuActs["NextBreakpoint"].setEnabled(False) - self.marginMenuActs["PreviousBreakpoint"].setEnabled(False) - self.marginMenuActs["ClearBreakpoint"].setEnabled(False) + if menu is self.bpMarginMenu: + supportsDebugger = bool(self.fileName and self.isPyFile()) + hasBreakpoints = bool(self.breaks) + hasBreakpoint = bool( + self.markersAtLine(self.line) & self.breakpointMask) - 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) + self.marginMenuActs["Breakpoint"].setEnabled(supportsDebugger) + self.marginMenuActs["TempBreakpoint"].setEnabled(supportsDebugger) + self.marginMenuActs["NextBreakpoint"].setEnabled( + supportsDebugger and hasBreakpoints) + self.marginMenuActs["PreviousBreakpoint"].setEnabled( + supportsDebugger and hasBreakpoints) + self.marginMenuActs["ClearBreakpoint"].setEnabled( + supportsDebugger and hasBreakpoints) + self.marginMenuActs["EditBreakpoint"].setEnabled( + supportsDebugger and hasBreakpoint) + self.marginMenuActs["EnableBreakpoint"].setEnabled( + supportsDebugger and hasBreakpoint) + if supportsDebugger: + 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 menu is self.bmMarginMenu: + hasBookmarks = bool(self.bookmarks) - if len(self.syntaxerrors): - self.marginMenuActs["GotoSyntaxError"].setEnabled(True) - self.marginMenuActs["ClearSyntaxError"].setEnabled(True) - if self.markersAtLine(self.line) & (1 << self.syntaxerror): + self.marginMenuActs["NextBookmark"].setEnabled(hasBookmarks) + self.marginMenuActs["PreviousBookmark"].setEnabled(hasBookmarks) + self.marginMenuActs["ClearBookmark"].setEnabled(hasBookmarks) + + if menu is self.foldMarginMenu: + isFoldHeader = bool(self.SendScintilla( + QsciScintilla.SCI_GETFOLDLEVEL, self.line) & + QsciScintilla.SC_FOLDLEVELHEADERFLAG) + + self.marginMenuActs["ExpandChildren"].setEnabled(isFoldHeader) + self.marginMenuActs["CollapseChildren"].setEnabled(isFoldHeader) + + if menu is self.indicMarginMenu: + hasSyntaxErrors = bool(self.syntaxerrors) + hasWarnings = bool(self.warnings) + hasNotCoveredMarkers = bool(self.notcoveredMarkers) + + self.marginMenuActs["GotoSyntaxError"].setEnabled(hasSyntaxErrors) + self.marginMenuActs["ClearSyntaxError"].setEnabled(hasSyntaxErrors) + if hasSyntaxErrors and \ + 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) - - 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["NextWarningMarker"].setEnabled(hasWarnings) + self.marginMenuActs["PreviousWarningMarker"].setEnabled( + hasWarnings) + self.marginMenuActs["ClearWarnings"].setEnabled(hasWarnings) + if hasWarnings and \ + 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) - - 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) + + self.marginMenuActs["NextCoverageMarker"].setEnabled( + hasNotCoveredMarkers) + self.marginMenuActs["PreviousCoverageMarker"].setEnabled( + hasNotCoveredMarkers) - else: - self.marginMenuActs["PreviousChangeMarker"].setEnabled(False) - self.marginMenuActs["NextChangeMarker"].setEnabled(False) - self.marginMenuActs["ClearChangeMarkers"].setEnabled(False) + self.marginMenuActs["PreviousTaskMarker"].setEnabled( + self.__hasTaskMarkers) + self.marginMenuActs["NextTaskMarker"].setEnabled( + self.__hasTaskMarkers) + + self.marginMenuActs["PreviousChangeMarker"].setEnabled( + self.__hasChangeMarkers) + self.marginMenuActs["NextChangeMarker"].setEnabled( + self.__hasChangeMarkers) + self.marginMenuActs["ClearChangeMarkers"].setEnabled( + self.__hasChangeMarkers) self.showMenu.emit("Margin", menu, self) @@ -5756,7 +5624,7 @@ if os.path.isfile(tf): files.append(tf) - # now check, if there are coverage files belonging to ourself + # now check, if there are coverage files belonging to ourselves fn = self.getFileName() if fn is not None: tfn = Utilities.getTestFileName(fn) @@ -5934,7 +5802,7 @@ if os.path.isfile(tf): files.append(tf) - # now check, if there are profile files belonging to ourself + # now check, if there are profile files belonging to ourselves fn = self.getFileName() if fn is not None: tfn = Utilities.getTestFileName(fn) @@ -6435,6 +6303,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 #################################################################