QScintilla/Editor.py

branch
Py2 comp.
changeset 2677
3d4277929fb3
parent 2574
9d6b6cf31ec6
parent 2659
7f46c5a7ed73
child 2791
a9577f248f04
--- a/QScintilla/Editor.py	Fri May 24 18:39:58 2013 +0200
+++ b/QScintilla/Editor.py	Tue May 28 20:52:12 2013 +0200
@@ -278,6 +278,7 @@
         
         # configure the margins
         self.__setMarginsDisplay()
+        self.linesChanged.connect(self.__resizeLinenoMargin)
         
         self.marginClicked.connect(self.__marginClicked)
         
@@ -1690,6 +1691,7 @@
             return True
         
         if self.filetype == "":
+            # 1) Determine by first line
             line0 = self.text(0)
             if line0.startswith("#!") and \
                ("python2" in line0 or \
@@ -1699,15 +1701,23 @@
             
             if self.fileName is not None:
                 ext = os.path.splitext(self.fileName)[1]
-                if ext in [".py", ".pyw"] and \
-                   Preferences.getProject("DeterminePyFromProject") and \
-                   self.project.isOpen() and \
-                   self.project.isProjectFile(self.fileName):
-                    isProjectPy2 = \
-                        self.project.getProjectLanguage() in ["Python", "Python2"]
-                    if isProjectPy2:
-                        self.filetype = "Python2"
-                    return isProjectPy2
+                if ext in [".py", ".pyw"]:
+                    # 2) .py and .pyw are ambiguous; determine from project
+                    if Preferences.getProject("DeterminePyFromProject") and \
+                       self.project.isOpen() and \
+                       self.project.isProjectFile(self.fileName):
+                        isProjectPy2 = \
+                            self.project.getProjectLanguage() in ["Python", "Python2"]
+                        if isProjectPy2:
+                            self.filetype = "Python2"
+                        return isProjectPy2
+                    else:
+                        # 3) determine by compiling the sources
+                        syntaxError = Utilities.compile(self.fileName,
+                            self.text(), True)[0]
+                        if not syntaxError:
+                            self.filetype = "Python2"
+                            return True
                 
                 if ext in self.dbs.getExtensions('Python2'):
                     self.filetype = "Python2"
@@ -1725,6 +1735,7 @@
             return True
         
         if self.filetype == "":
+            # 1) Determine by first line
             line0 = self.text(0)
             if line0.startswith("#!") and \
                "python3" in line0:
@@ -1733,14 +1744,22 @@
             
             if self.fileName is not None:
                 ext = os.path.splitext(self.fileName)[1]
-                if ext in [".py", ".pyw"] and \
-                   Preferences.getProject("DeterminePyFromProject") and \
-                   self.project.isOpen() and \
-                   self.project.isProjectFile(self.fileName):
-                    isProjectPy3 = self.project.getProjectLanguage() in ["Python3"]
-                    if isProjectPy3:
-                        self.filetype = "Python3"
-                    return isProjectPy3
+                if ext in [".py", ".pyw"]:
+                    # 2) .py and .pyw are ambiguous; determine from project
+                    if Preferences.getProject("DeterminePyFromProject") and \
+                       self.project.isOpen() and \
+                       self.project.isProjectFile(self.fileName):
+                        isProjectPy3 = self.project.getProjectLanguage() in ["Python3"]
+                        if isProjectPy3:
+                            self.filetype = "Python3"
+                        return isProjectPy3
+                    else:
+                        # 3) determine by compiling the sources
+                        syntaxError = Utilities.compile(self.fileName, 
+                            self.text(), False)[0]
+                        if not syntaxError:
+                            self.filetype = "Python3"
+                            return True
                 
                 if ext in self.dbs.getExtensions('Python3'):
                     self.filetype = "Python3"
@@ -3658,7 +3677,6 @@
                     lineNo -= 1
                 else:
                     lineNo += 1
-            
     
     ############################################################################
     ## Setup methods below
@@ -3831,8 +3849,7 @@
         linenoMargin = Preferences.getEditor("LinenoMargin")
         self.setMarginLineNumbers(self.__linenoMargin, linenoMargin)
         if linenoMargin:
-            self.setMarginWidth(self.__linenoMargin,
-                                ' ' + '8' * Preferences.getEditor("LinenoWidth"))
+            self.__resizeLinenoMargin()
         else:
             self.setMarginWidth(self.__linenoMargin, 0)
         
@@ -3854,7 +3871,15 @@
         else:
             self.setMarginWidth(self.__foldMargin, 0)
             self.setFolding(QsciScintilla.NoFoldStyle, self.__foldMargin)
-        
+    
+    def __resizeLinenoMargin(self):
+        """
+        Private slot to resize the line numbers margin.
+        """
+        linenoMargin = Preferences.getEditor("LinenoMargin")
+        if linenoMargin:
+            self.setMarginWidth(self.__linenoMargin, '8' * (len(str(self.lines())) + 1))
+    
     def __setTextDisplay(self):
         """
         Private method to configure the text display.
@@ -3960,6 +3985,8 @@
         if Preferences.getEditor("OverrideEditAreaColours"):
             self.setColor(Preferences.getEditorColour("EditAreaForeground"))
             self.setPaper(Preferences.getEditorColour("EditAreaBackground"))
+        
+        self.setVirtualSpaceOptions(Preferences.getEditor("VirtualSpaceOptions"))
     
     def __setEolMode(self):
         """
@@ -6709,3 +6736,79 @@
                     match = matches[-1]
             line, index = self.lineIndexFromPosition(match.start())
             self.setSelection(line, index + len(match.group(0)), line, index)
+    
+    #######################################################################
+    ## Sort related methods
+    #######################################################################
+    
+    def sortLines(self):
+        """
+        Public slot to sort the lines spanned by a rectangular selection.
+        """
+        if not self.selectionIsRectangle():
+            return
+        
+        from .SortOptionsDialog import SortOptionsDialog
+        dlg = SortOptionsDialog()
+        if dlg.exec_() == QDialog.Accepted:
+            ascending, alnum, caseSensitive = dlg.getData()
+            origStartLine, origStartIndex, origEndLine, origEndIndex = \
+                self.getRectangularSelection()
+            # convert to upper-left to lower-right
+            startLine = min(origStartLine, origEndLine)
+            startIndex = min(origStartIndex, origEndIndex)
+            endLine = max(origStartLine, origEndLine)
+            endIndex = max(origStartIndex, origEndIndex)
+            
+            # step 1: extract the text of the rectangular selection and the lines
+            selText = {}
+            txtLines = {}
+            for line in range(startLine, endLine + 1):
+                txtLines[line] = self.text(line)
+                txt = txtLines[line][startIndex:endIndex].strip()
+                if not alnum:
+                    try:
+                        txt = float(txt)
+                    except ValueError:
+                        E5MessageBox.critical(self,
+                            self.trUtf8("Sort Lines"),
+                            self.trUtf8("""The selection contains illegal data for a"""
+                                        """ numerical sort."""))
+                        return
+                
+                if txt in selText:
+                    selText[txt].append(line)
+                else:
+                    selText[txt] = [line]
+            
+            # step 2: calculate the sort parameters
+            reverse = not ascending
+            if alnum and not caseSensitive:
+                keyFun = str.lower
+            else:
+                keyFun = None
+            
+            # step 3: sort the lines
+            eol = self.getLineSeparator()
+            lastWithEol = True
+            newLines = []
+            for txt in sorted(selText.keys(), key=keyFun, reverse=reverse):
+                for line in selText[txt]:
+                    txt = txtLines[line]
+                    if not txt.endswith(eol):
+                        lastWithEol = False
+                        txt += eol
+                    newLines.append(txt)
+            if not lastWithEol:
+                newLines[-1] = newLines[-1][:-len(eol)]
+            
+            # step 4: replace the lines by the sorted ones
+            self.setSelection(startLine, 0, endLine + 1, 0)
+            self.beginUndoAction()
+            self.replaceSelectedText("".join(newLines))
+            self.endUndoAction()
+            
+            # step 5: reset the rectangular selection
+            self.setRectangularSelection(origStartLine, origStartIndex,
+                                         origEndLine, origEndIndex)
+            self.selectionChanged.emit()

eric ide

mercurial