QScintilla/Editor.py

changeset 6297
85e20e9b4d55
parent 6285
045dc4c38701
child 6299
feb3cf2cbde3
--- 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
     #################################################################
     

eric ide

mercurial