eric7/EricWidgets/EricSpellCheckedTextEdit.py

branch
eric7
changeset 8432
074407b4c107
parent 8431
bed315a45088
child 8629
1b58dc890b87
--- a/eric7/EricWidgets/EricSpellCheckedTextEdit.py	Thu Jun 17 18:56:21 2021 +0200
+++ b/eric7/EricWidgets/EricSpellCheckedTextEdit.py	Sat Jun 19 12:17:17 2021 +0200
@@ -26,8 +26,6 @@
 )
 from PyQt6.QtWidgets import QMenu, QTextEdit, QPlainTextEdit
 
-# TODO: add user dictionaries with respective menu entries
-
 if ENCHANT_AVAILABLE:
     class SpellCheckMixin():
         """
@@ -91,6 +89,7 @@
             # Add a submenu for setting the spell-check language and
             # document format.
             menu.addSeparator()
+            self.__addRemoveEntry(self.__cursorForPosition(pos), menu)
             menu.addMenu(self.__createLanguagesMenu(menu))
             menu.addMenu(self.__createFormatsMenu(menu))
             
@@ -132,12 +131,35 @@
                 act = spellMenu.addAction(word)
                 act.setData((cursor, word))
             
-            # Only return the menu if it's non-empty
-            if spellMenu.actions():
-                spellMenu.triggered.connect(self.__correctWord)
-                return spellMenu
+            if suggestions:
+                spellMenu.addSeparator()
+            
+            # add management entry
+            act = spellMenu.addAction(QCoreApplication.translate(
+                "SpellCheckMixin", "Add to Dictionary"))
+            act.setData((cursor, text, "add"))
             
-            return None
+            spellMenu.triggered.connect(self.__spellMenuTriggered)
+            return spellMenu
+        
+        def __addRemoveEntry(self, cursor, menu):
+            """
+            Private method to create a menu entry to remove the word at the
+            menu position.
+            
+            @param cursor reference to the text cursor for the misspelled word
+            @type QTextCursor
+            @param menu reference to the context menu
+            @type QMenu
+            """
+            if cursor is None:
+                return
+            
+            text = cursor.selectedText()
+            menu.addAction(QCoreApplication.translate(
+                "SpellCheckMixin",
+                "Remove '{0}' from Dictionary").format(text),
+                lambda: self.__addToUserDict(text, "remove"))
         
         def __createLanguagesMenu(self, parent=None):
             """
@@ -162,7 +184,6 @@
                 act.setData(language)
                 languageMenu.addAction(act)
             
-            # TODO: add action to add a word to the lists
             languageMenu.triggered.connect(self.__setLanguage)
             return languageMenu
         
@@ -196,6 +217,24 @@
             formatMenu.triggered.connect(self.__setFormat)
             return formatMenu
         
+        def __cursorForPosition(self, pos):
+            """
+            Private method to create a text cursor selecting the word at the
+            given position.
+            
+            @param pos position of the misspelled word
+            @type QPoint
+            @return text cursor for the word
+            @rtype QTextCursor
+            """
+            cursor = self.cursorForPosition(pos)
+            cursor.select(QTextCursor.SelectionType.WordUnderCursor)
+            
+            if cursor.hasSelection():
+                return cursor
+            else:
+                return None
+        
         def __cursorForMisspelling(self, pos):
             """
             Private method to create a text cursor selecting the misspelled
@@ -226,21 +265,55 @@
             else:
                 return None
         
-        @pyqtSlot(QAction)
-        def __correctWord(self, act):
+        def __correctWord(self, cursor, word):
+            """
+            Private method to replace some misspelled text.
+            
+            @param cursor reference to the text cursor for the misspelled word
+            @type QTextCursor
+            @param word replacement text
+            @type str
+            """
+            cursor.beginEditBlock()
+            cursor.removeSelectedText()
+            cursor.insertText(word)
+            cursor.endEditBlock()
+        
+        def __addToUserDict(self, word, command):
             """
-            Private slot to correct the misspelled word with the selected
-            correction.
+            Private method to add a word to the user word or exclude list.
+            
+            @param word text to be added
+            @type str
+            @param command command indicating the user dictionary type
+            @type str
+            """
+            if word:
+                dictionary = self.__highlighter.dict()
+                if command == "add":
+                    dictionary.add(word)
+                elif command == "remove":
+                    dictionary.remove(word)
+                
+                self.__highlighter.rehighlight()
+        
+        @pyqtSlot(QAction)
+        def __spellMenuTriggered(self, act):
+            """
+            Private slot to handle a selection of the spell menu.
             
             @param act reference to the selected action
             @type QAction
             """
-            cursor, word = act.data()
+            data = act.data()
+            if len(data) == 2:
+                # replace the misspelled word
+                self.__correctWord(*data)
             
-            cursor.beginEditBlock()
-            cursor.removeSelectedText()
-            cursor.insertText(word)
-            cursor.endEditBlock()
+            elif len(data) == 3:
+                # dictionary management action
+                _, word, command = data
+                self.__addToUserDict(word, command)
         
         @pyqtSlot(QAction)
         def __setLanguage(self, act):
@@ -300,7 +373,7 @@
             self.__highlighter.setDict(spellDict)
         
         @classmethod
-        def setDefaultLanguage(cls, language, pwl="", pel=""):
+        def setDefaultLanguage(cls, language, pwl=None, pel=None):
             """
             Class method to set the default spell-check language.
             
@@ -308,7 +381,7 @@
             @type str
             @param pwl file name of the personal word list
             @type str
-            @param pel name of the personal exclude list
+            @param pel file name of the personal exclude list
             @type str
             """
             with contextlib.suppress(DictNotFoundError):
@@ -467,10 +540,16 @@
 
 if __name__ == '__main__':
     import sys
+    import os
     from PyQt6.QtWidgets import QApplication
     
     if ENCHANT_AVAILABLE:
-        SpellCheckMixin.setDefaultLanguage("en_US")
+        dictPath = os.path.expanduser(os.path.join("~", ".eric7", "spelling"))
+        SpellCheckMixin.setDefaultLanguage(
+            "en_US",
+            os.path.join(dictPath, "pwl.dic"),
+            os.path.join(dictPath, "pel.dic")
+        )
     
     app = QApplication(sys.argv)
     spellEdit = EricSpellCheckedPlainTextEdit()

eric ide

mercurial