Added code to limit the search function of the editor to rectangular selections as well.

Sun, 19 May 2013 20:54:04 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sun, 19 May 2013 20:54:04 +0200
changeset 2660
5b834d76f617
parent 2659
7f46c5a7ed73
child 2661
0fd6f92ab2dd

Added code to limit the search function of the editor to rectangular selections as well.

QScintilla/SearchReplaceWidget.py file | annotate | diff | comparison | revisions
--- a/QScintilla/SearchReplaceWidget.py	Sun May 19 15:39:12 2013 +0200
+++ b/QScintilla/SearchReplaceWidget.py	Sun May 19 20:54:04 2013 +0200
@@ -144,9 +144,33 @@
         self.havefound = False
         self.__pos = None
         self.__findBackwards = False
-        self.__selection = None
+        self.__selections = []
         self.__finding = False
-
+    
+    def __selectionBoundary(self, selections=None):
+        """
+        Private method to calculate the current selection boundary.
+        
+        @param selections optional parameter giving the selections to
+            calculate the boundary for (list of tuples of four integer)
+        @return tuple of start line and index and end line and index
+            (tuple of four integer)
+        """
+        if selections is None:
+            selections = self.__selections
+        if selections:
+            lineNumbers = [sel[0] for sel in selections] + \
+                          [sel[2] for sel in selections]
+            indexNumbers = [sel[1] for sel in selections] + \
+                           [sel[3] for sel in selections]
+            startLine, startIndex, endLine, endIndex = (
+                min(lineNumbers), min(indexNumbers),
+                max(lineNumbers), max(indexNumbers))
+        else:
+            startLine, startIndex, endLine, endIndex = -1, -1, -1, -1
+        
+        return startLine, startIndex, endLine, endIndex
+    
     def on_findtextCombo_editTextChanged(self, txt):
         """
         Private slot to enable/disable the find buttons.
@@ -263,10 +287,7 @@
         lineTo = -1
         indexTo = -1
         if self.ui.selectionCheckBox.isChecked():
-            lineFrom = self.__selection[0]
-            indexFrom = self.__selection[1]
-            lineTo = self.__selection[2]
-            indexTo = self.__selection[3]
+            lineFrom, indexFrom, lineTo, indexTo = self.__selectionBoundary()
         
         aw.clearSearchIndicators()
         ok = aw.findFirstTarget(txt,
@@ -278,7 +299,21 @@
             tgtPos, tgtLen = aw.getFoundTarget()
             if tgtLen == 0:
                 break
-            aw.setSearchIndicator(tgtPos, tgtLen)
+            if len(self.__selections) > 1:
+                lineFrom, indexFrom = aw.lineIndexFromPosition(tgtPos)
+                lineTo, indexTo = aw.lineIndexFromPosition(tgtPos + tgtLen)
+                for sel in self.__selections:
+                    if lineFrom == sel[0] and \
+                       indexFrom >= sel[1] and \
+                       indexTo <= sel[3]:
+                        indicate = True
+                        break
+                else:
+                    indicate = False
+            else:
+                indicate = True
+            if indicate:
+                aw.setSearchIndicator(tgtPos, tgtLen)
             ok = aw.findNextTarget()
     
     def __findNextPrev(self, txt, backwards):
@@ -299,12 +334,12 @@
         
         ok = True
         lineFrom, indexFrom, lineTo, indexTo = aw.getSelection()
+        boundary = self.__selectionBoundary()
         if backwards:
             if self.ui.selectionCheckBox.isChecked() and \
-               (lineFrom, indexFrom, lineTo, indexTo) == self.__selection:
+               (lineFrom, indexFrom, lineTo, indexTo) == boundary:
                 # initial call
-                line = self.__selection[2]
-                index = self.__selection[3]
+                line, index = boundary[2:]
             else:
                 if (lineFrom, indexFrom) == (-1, -1):
                     # no selection present
@@ -314,18 +349,17 @@
                     line = lineFrom
                     index = indexFrom - 1
             if self.ui.selectionCheckBox.isChecked() and \
-               line == self.__selection[0] and \
+               line == boundary[0] and \
                index >= 0 and \
-               index < self.__selection[1]:
+               index < boundary[1]:
                 ok = False
             
             if ok and index < 0:
                 line -= 1
                 if self.ui.selectionCheckBox.isChecked():
-                    if line < self.__selection[0]:
+                    if line < boundary[0]:
                         if self.ui.wrapCheckBox.isChecked():
-                            line = self.__selection[2]
-                            index = self.__selection[3]
+                            line, index = boundary[2:]
                         else:
                             ok = False
                     else:
@@ -341,10 +375,9 @@
                         index = aw.lineLength(line)
         else:
             if self.ui.selectionCheckBox.isChecked() and \
-               (lineFrom, indexFrom, lineTo, indexTo) == self.__selection:
+               (lineFrom, indexFrom, lineTo, indexTo) == boundary:
                 # initial call
-                line = self.__selection[0]
-                index = self.__selection[1]
+                line, index = boundary[:2]
             else:
                 line = lineTo
                 index = indexTo
@@ -360,19 +393,44 @@
         
         if ok and self.ui.selectionCheckBox.isChecked():
             lineFrom, indexFrom, lineTo, indexTo = aw.getSelection()
-            if (lineFrom == self.__selection[0] and indexFrom >= self.__selection[1]) or \
-               (lineFrom > self.__selection[0] and lineFrom < self.__selection[2]) or \
-               (lineFrom == self.__selection[2] and indexFrom <= self.__selection[3]):
+            if len(self.__selections) > 1:
+                for sel in self.__selections:
+                    if lineFrom == sel[0] and \
+                       indexFrom >= sel[1] and \
+                       indexTo <= sel[3]:
+                        ok = True
+                        break
+                else:
+                    ok = False
+            elif (lineFrom == boundary[0] and indexFrom >= boundary[1]) or \
+               (lineFrom > boundary[0] and lineFrom < boundary[2]) or \
+               (lineFrom == boundary[2] and indexFrom <= boundary[3]):
                 ok = True
             else:
-                if self.ui.wrapCheckBox.isChecked():
-                    # try it again
-                    if backwards:
-                        line = self.__selection[2]
-                        index = self.__selection[3]
+                ok = False
+            if not ok and len(self.__selections) > 1:
+                # try again
+                while not ok and \
+                      ((backwards and lineFrom >= boundary[0]) or \
+                       (not backwards and lineFrom <= boundary[2])):
+                    for ind in range(len(self.__selections)):
+                        if lineFrom == self.__selections[ind][0]:
+                            after = indexTo > self.__selections[ind][3]
+                            if backwards:
+                                if after:
+                                    line, index = self.__selections[ind][2:]
+                                else:
+                                    if ind > 0:
+                                        line, index = self.__selections[ind - 1][2:]
+                            else:
+                                if after:
+                                    if ind < len(self.__selections) - 1:
+                                        line, index = self.__selections[ind + 1][:2]
+                                else:
+                                    line, index = self.__selections[ind][:2]
+                            break
                     else:
-                        line = self.__selection[0]
-                        index = self.__selection[1]
+                        break
                     ok = aw.findFirst(txt,
                         self.ui.regexpCheckBox.isChecked(),
                         self.ui.caseCheckBox.isChecked(),
@@ -382,23 +440,52 @@
                         line, index)
                     if ok:
                         lineFrom, indexFrom, lineTo, indexTo = aw.getSelection()
-                        if (lineFrom == self.__selection[0] and \
-                            indexFrom >= self.__selection[1]) or \
-                           (lineFrom > self.__selection[0] and \
-                            lineFrom < self.__selection[2]) or \
-                           (lineFrom == self.__selection[2] \
-                            and indexFrom <= self.__selection[3]):
+                        if lineFrom < boundary[0] or lineFrom > boundary[2] or \
+                           indexFrom < boundary[1] or indexFrom > boundary[3] or \
+                           indexTo < boundary[1] or indexTo > boundary[3]:
+                            ok = False
+                            break
+            if not ok:
+                if self.ui.wrapCheckBox.isChecked():
+                    # try it again
+                    if backwards:
+                        line, index = boundary[2:]
+                    else:
+                        line, index = boundary[:2]
+                    ok = aw.findFirst(txt,
+                        self.ui.regexpCheckBox.isChecked(),
+                        self.ui.caseCheckBox.isChecked(),
+                        self.ui.wordCheckBox.isChecked(),
+                        self.ui.wrapCheckBox.isChecked(),
+                        not backwards,
+                        line, index)
+                    if ok:
+                        lineFrom, indexFrom, lineTo, indexTo = aw.getSelection()
+                        if len(self.__selections) > 1:
+                            for sel in self.__selections:
+                                if lineFrom == sel[0] and \
+                                   indexFrom >= sel[1] and \
+                                   indexTo <= sel[3]:
+                                    ok = True
+                                    break
+                            else:
+                                ok = False
+                        elif (lineFrom == boundary[0] and \
+                            indexFrom >= boundary[1]) or \
+                           (lineFrom > boundary[0] and \
+                            lineFrom < boundary[2]) or \
+                           (lineFrom == boundary[2] \
+                            and indexFrom <= boundary[3]):
                             ok = True
                         else:
                             ok = False
-                            aw.selectAll(False)
-                            aw.setCursorPosition(cline, cindex)
-                            aw.ensureCursorVisible()
                 else:
                     ok = False
-                    aw.selectAll(False)
-                    aw.setCursorPosition(cline, cindex)
-                    aw.ensureCursorVisible()
+            
+            if not ok:
+                aw.selectAll(False)
+                aw.setCursorPosition(cline, cindex)
+                aw.ensureCursorVisible()
         
         self.__finding = False
         
@@ -454,17 +541,18 @@
         @param editor reference to the editor (Editor)
         """
         if not self.__finding:
-            if editor.hasSelectedText() and not editor.selectionIsRectangle():
-                line1, index1, line2, index2 = editor.getSelection()
+            if editor.hasSelectedText():
+                selections = editor.getSelections()
+                line1, index1, line2, index2 = self.__selectionBoundary(selections)
                 if line1 != line2:
                     self.ui.selectionCheckBox.setEnabled(True)
                     self.ui.selectionCheckBox.setChecked(True)
-                    self.__selection = (line1, index1, line2, index2)
+                    self.__selections = selections
                     return
             
             self.ui.selectionCheckBox.setEnabled(False)
             self.ui.selectionCheckBox.setChecked(False)
-            self.__selection = None
+            self.__selections = []
 
     @pyqtSlot()
     def on_replaceButton_clicked(self):
@@ -548,9 +636,9 @@
         
         aw = self.viewmanager.activeWindow()
         cline, cindex = aw.getCursorPosition()
+        boundary = self.__selectionBoundary()
         if self.ui.selectionCheckBox.isChecked():
-            line = self.__selection[0]
-            index = self.__selection[1]
+            line, index = boundary[:2]
         else:
             line = 0
             index = 0
@@ -562,9 +650,9 @@
         
         if ok and self.ui.selectionCheckBox.isChecked():
             lineFrom, indexFrom, lineTo, indexTo = aw.getSelection()
-            if (lineFrom == self.__selection[0] and indexFrom >= self.__selection[1]) or \
-               (lineFrom > self.__selection[0] and lineFrom < self.__selection[2]) or \
-               (lineFrom == self.__selection[2] and indexFrom <= self.__selection[3]):
+            if (lineFrom == boundary[0] and indexFrom >= boundary[1]) or \
+               (lineFrom > boundary[0] and lineFrom < boundary[2]) or \
+               (lineFrom == boundary[2] and indexFrom <= boundary[3]):
                 ok = True
             else:
                 ok = False

eric ide

mercurial