eric6/QScintilla/Editor.py

branch
maintenance
changeset 7322
cd8ee889589f
parent 7286
7eb04391adf7
parent 7310
460a332dcc56
child 7345
bc0ee7fadd03
diff -r 1c17f2191bdd -r cd8ee889589f eric6/QScintilla/Editor.py
--- a/eric6/QScintilla/Editor.py	Thu Oct 03 11:12:50 2019 +0200
+++ b/eric6/QScintilla/Editor.py	Fri Nov 01 16:11:27 2019 +0100
@@ -29,6 +29,7 @@
 
 from .QsciScintillaCompat import QsciScintillaCompat, QSCINTILLA_VERSION
 from .EditorMarkerMap import EditorMarkerMap
+from .SpellChecker import SpellChecker
 
 import Preferences
 import Utilities
@@ -82,6 +83,8 @@
         string is passed as a parameter.
     @signal encodingChanged(str) emitted when the editors encoding was set. The
             encoding name is passed as a parameter.
+    @signal spellLanguageChanged(str) emitted when the editor spell check
+            language was set. The language is passed as a parameter.
     @signal lastEditPositionAvailable() emitted when a last edit position is
         available
     @signal refreshed() emitted to signal a refresh of the editor contents
@@ -110,6 +113,7 @@
     languageChanged = pyqtSignal(str)
     eolChanged = pyqtSignal(str)
     encodingChanged = pyqtSignal(str)
+    spellLanguageChanged = pyqtSignal(str)
     lastEditPositionAvailable = pyqtSignal()
     refreshed = pyqtSignal()
     settingsRead = pyqtSignal()
@@ -173,7 +177,7 @@
         
         self.dbs = dbs
         self.taskViewer = tv
-        self.fileName = fn
+        self.__setFileName(fn)
         self.vm = vm
         self.filetype = filetype
         self.filetypeByFlag = False
@@ -202,6 +206,7 @@
         self.showingNotcoveredMarkers = False
         
         self.lexer_ = None
+        self.apiLanguage = ''
         
         self.__loadEditorConfig()
         
@@ -209,7 +214,6 @@
         self.__lexerReset = False
         self.completer = None
         self.encoding = self.__getEditorConfig("DefaultEncoding")
-        self.apiLanguage = ''
         self.lastModified = 0
         self.line = -1
         self.inReopenPrompt = False
@@ -480,10 +484,13 @@
         if editor is None:
             self.__checkLanguage()
             self.__checkEncoding()
+            self.__checkSpellLanguage()
         else:
             # it's a clone
             self.__languageChanged(editor.apiLanguage, propagate=False)
             self.__encodingChanged(editor.encoding, propagate=False)
+            self.__spellLanguageChanged(editor.getSpellingLanguage(),
+                                        propagate=False)
         
         self.setAcceptDrops(True)
         
@@ -528,6 +535,22 @@
         self.SCN_ZOOM.connect(self.__markerMap.update)
         self.__markerMap.update()
     
+    def __setFileName(self, name):
+        """
+        Private method to set the file name of the current file.
+        
+        @param name name of the current file
+        @type str
+        """
+        self.fileName = name
+        
+        if self.fileName:
+            self.__fileNameExtension = (
+                os.path.splitext(self.fileName)[1][1:].lower()
+            )
+        else:
+            self.__fileNameExtension = ""
+    
     def __registerImages(self):
         """
         Private method to register images for autocompletion lists.
@@ -576,6 +599,7 @@
         editor.languageChanged.connect(self.languageChanged)
         editor.eolChanged.connect(self.__eolChanged)
         editor.encodingChanged.connect(self.__encodingChanged)
+        editor.spellLanguageChanged.connect(self.__spellLanguageChanged)
         
     def removeClone(self, editor):
         """
@@ -589,6 +613,7 @@
             editor.languageChanged.disconnect(self.languageChanged)
             editor.eolChanged.disconnect(self.__eolChanged)
             editor.encodingChanged.disconnect(self.__encodingChanged)
+            editor.spellLanguageChanged.disconnect(self.__spellLanguageChanged)
             self.__clones.remove(editor)
         
     def isClone(self, editor):
@@ -747,6 +772,8 @@
         self.__menus["Eol"] = self.eolMenu
         self.encodingsMenu = self.__initContextMenuEncodings()
         self.__menus["Encodings"] = self.encodingsMenu
+        self.spellLanguagesMenu = self.__initContextMenuSpellLanguages()
+        self.__menus["SpellLanguages"] = self.spellLanguagesMenu
         
         self.menuActs["Undo"] = self.menu.addAction(
             UI.PixmapCache.getIcon("editUndo.png"),
@@ -809,6 +836,8 @@
         self.menuActs["SpellCheckRemove"] = self.menu.addAction(
             self.tr("Remove from dictionary"),
             self.__removeFromSpellingDictionary)
+        self.menuActs["SpellCheckLanguages"] = self.menu.addMenu(
+            self.spellLanguagesMenu)
         self.menu.addSeparator()
         self.menu.addAction(
             self.tr('Shorten empty lines'), self.shortenEmptyLines)
@@ -1126,7 +1155,39 @@
         menu.aboutToShow.connect(self.__showContextMenuEol)
         
         return menu
-        
+    
+    def __initContextMenuSpellLanguages(self):
+        """
+        Private method to setup the spell checking languages context sub menu.
+        
+        @return reference to the generated menu
+        @rtype QMenu
+        """
+        self.supportedSpellLanguages = {}
+        
+        menu = QMenu(self.tr("Spell Check Languages"))
+        
+        self.spellLanguagesActGrp = QActionGroup(self)
+        
+        self.noSpellLanguageAct = menu.addAction(
+            self.tr("No Language"))
+        self.noSpellLanguageAct.setCheckable(True)
+        self.noSpellLanguageAct.setData("")
+        self.spellLanguagesActGrp.addAction(self.noSpellLanguageAct)
+        menu.addSeparator()
+        
+        for language in sorted(SpellChecker.getAvailableLanguages()):
+            act = menu.addAction(language)
+            act.setCheckable(True)
+            act.setData(language)
+            self.supportedSpellLanguages[language] = act
+            self.spellLanguagesActGrp.addAction(act)
+        
+        menu.triggered.connect(self.__spellLanguagesMenuTriggered)
+        menu.aboutToShow.connect(self.__showContextMenuSpellLanguages)
+        
+        return menu
+    
     def __initContextMenuExporters(self):
         """
         Private method used to setup the Exporters context sub menu.
@@ -1597,7 +1658,52 @@
             eol = self.getLineSeparator()
             self.eolChanged.emit(eol)
             self.inEolChanged = False
-        
+    
+    def __showContextMenuSpellLanguages(self):
+        """
+        Private slot handling the aboutToShow signal of the spell check
+        languages context menu.
+        """
+        self.showMenu.emit("SpellLanguage", self.spellLanguagesMenu, self)
+    
+    def __spellLanguagesMenuTriggered(self, act):
+        """
+        Private method to handle the selection of a spell check language.
+        
+        @param act reference to the action that was triggered
+        @type QAction
+        """
+        language = act.data()
+        self.__setSpellingLanguage(language)
+        self.spellLanguageChanged.emit(language)
+    
+    def __checkSpellLanguage(self):
+        """
+        Private slot to check the selected spell check language action.
+        """
+        language = self.getSpellingLanguage()
+        try:
+            self.supportedSpellLanguages[language].setChecked(True)
+        except (AttributeError, KeyError):
+            pass
+    
+    def __spellLanguageChanged(self, language, propagate=True):
+        """
+        Private slot to handle a change of the spell check language.
+        
+        @param language new spell check language
+        @type str
+        @param propagate flag indicating to propagate the change
+        @type bool
+        """
+        self.__setSpellingLanguage(language)
+        self.__checkSpellLanguage(language)
+        
+        if not self.__inSpellLanguageChanged and propagate:
+            self.__inSpellLanguageChanged = True
+            self.spellLanguageChanged.emit(language)
+            self.__inSpellLanguageChanged = False
+    
     def __bindLexer(self, filename, pyname=""):
         """
         Private slot to set the correct lexer depending on language.
@@ -3261,7 +3367,7 @@
         if self.writeFile(fn):
             if saveas:
                 self.__clearBreakpoints(self.fileName)
-            self.fileName = fn
+            self.__setFileName(fn)
             self.setModified(False)
             self.setReadOnly(False)
             self.setWindowTitle(self.fileName)
@@ -3318,7 +3424,7 @@
         """
         self.__clearBreakpoints(fn)
         
-        self.fileName = fn
+        self.__setFileName(fn)
         self.setWindowTitle(self.fileName)
         
         self.__loadEditorConfig()
@@ -5351,13 +5457,13 @@
             self.menuActs["codeInfo"].setEnabled(
                 self.vm.isEditorInfoSupported(self.getLanguage()))
         
-        from .SpellChecker import SpellChecker
         spellingAvailable = SpellChecker.isAvailable()
         self.menuActs["SpellCheck"].setEnabled(spellingAvailable)
         self.menuActs["SpellCheckSelection"].setEnabled(
             spellingAvailable and self.hasSelectedText())
         self.menuActs["SpellCheckRemove"].setEnabled(
             spellingAvailable and self.spellingMenuPos >= 0)
+        self.menuActs["SpellCheckLanguages"].setEnabled(spellingAvailable)
         
         if self.menuActs["OpenRejections"]:
             if self.fileName:
@@ -7548,6 +7654,18 @@
     ## Spell checking related methods
     #######################################################################
     
+    def getSpellingLanguage(self):
+        """
+        Public method to get the current spelling language.
+        
+        @return current spelling language
+        @rtype str
+        """
+        if self.spell:
+            return self.spell.getLanguage()
+        
+        return ""
+    
     def __setSpellingLanguage(self, language, pwl="", pel=""):
         """
         Private slot to set the spell checking language.
@@ -7568,7 +7686,6 @@
             self.__spellCheckStringsOnly = Preferences.getEditor(
                 "SpellCheckStringsOnly")
             if self.spell is None:
-                from .SpellChecker import SpellChecker
                 self.spell = SpellChecker(self, self.spellingIndicator,
                                           checkRegion=self.isSpellCheckRegion)
             self.setSpellingForProject()
@@ -7617,16 +7734,35 @@
         Public method to check, if the given position is within a region, that
         should be spell checked.
         
-        @param pos position to be checked (integer)
-        @return flag indicating pos is in a spell check region (boolean)
+        For files with a configured full text file extension all regions will
+        be regarded as to be checked. Depending on configuration, all unknown
+        files (i.e. those without a file extension) will be checked fully as
+        well.
+        
+        @param pos position to be checked
+        @type int
+        @return flag indicating pos is in a spell check region
+        @rtype bool
         """
         if self.__spellCheckStringsOnly:
-            style = self.styleAt(pos)
-            if self.lexer_ is not None:
-                return (
-                    self.lexer_.isCommentStyle(style) or
-                    self.lexer_.isStringStyle(style)
-                )
+            if (
+                self.__fileNameExtension in
+                Preferences.getEditor("FullSpellCheckExtensions")
+            ):
+                return True
+            elif (
+                not self.__fileNameExtension and
+                Preferences.getEditor("FullSpellCheckUnknown")
+            ):
+                return True
+            else:
+                style = self.styleAt(pos)
+                if self.lexer_ is not None:
+                    return (
+                        self.lexer_.isCommentStyle(style) or
+                        self.lexer_.isStringStyle(style)
+                    )
+        
         return True
     
     @pyqtSlot(int)
@@ -8428,11 +8564,12 @@
         """
         if option in ("TabWidth", "IndentWidth"):
             overrides = Preferences.getEditor("TabIndentOverride")
-            if self.filetype in overrides:
+            language = self.filetype or self.apiLanguage
+            if language in overrides:
                 if option == "TabWidth":
-                    return overrides[self.filetype][0]
+                    return overrides[language][0]
                 elif option == "IndentWidth":
-                    return overrides[self.filetype][1]
+                    return overrides[language][1]
         
         return None
     

eric ide

mercurial