eric7/EricWidgets/EricSpellCheckedTextEdit.py

branch
eric7
changeset 8428
2deec2f8a9ab
parent 8427
5ccf32f95805
child 8431
bed315a45088
--- a/eric7/EricWidgets/EricSpellCheckedTextEdit.py	Tue Jun 15 19:42:36 2021 +0200
+++ b/eric7/EricWidgets/EricSpellCheckedTextEdit.py	Wed Jun 16 17:47:50 2021 +0200
@@ -8,12 +8,16 @@
 checking.
 """
 
-import sys
+import contextlib
 
-import enchant
-from enchant import tokenize
-from enchant.errors import TokenizerNotFoundError, DictNotFoundError
-from enchant.utils import trim_suggestions
+try:
+    import enchant
+    import enchant.tokenize
+    from enchant.errors import TokenizerNotFoundError, DictNotFoundError
+    from enchant.utils import trim_suggestions
+    ENCHANT_AVAILABLE = True
+except ImportError:
+    ENCHANT_AVAILABLE = False
 
 from PyQt6.QtCore import pyqtSlot, Qt, QCoreApplication
 from PyQt6.QtGui import (
@@ -24,395 +28,429 @@
 
 # TODO: add user dictionaries with respective menu entries
 
-
-class SpellCheckMixin():
-    """
-    Class implementing the spell-check mixin for the widget classes.
-    """
-    # don't show more than this to keep the menu manageable
-    MaxSuggestions = 20
-    
-    def __init__(self):
+if ENCHANT_AVAILABLE:
+    class SpellCheckMixin():
         """
-        Constructor
+        Class implementing the spell-check mixin for the widget classes.
         """
-        self.__highlighter = EnchantHighlighter(self.document())
-        try:
-            # Start with a default dictionary based on the current locale.
-            spellDict = enchant.Dict()
-        except DictNotFoundError:
-            # Use English dictionary if no locale dictionary is available.
-            spellDict = enchant.Dict("en")
-        self.__highlighter.setDict(spellDict)
-    
-    def contextMenuEvent(self, evt):
-        """
-        Protected method to handle context menu events to add a spelling
-        suggestions submenu.
+        # don't show more than this to keep the menu manageable
+        MaxSuggestions = 20
+        
+        # default language to be used when no other is set
+        DefaultLanguage = None
         
-        @param evt reference to the context menu event
-        @type QContextMenuEvent
-        """
-        menu = self.__createSpellcheckContextMenu(evt.pos())
-        menu.exec(evt.globalPos())
-    
-    def __createSpellcheckContextMenu(self, pos):
-        """
-        Private method to create the spell-check context menu.
+        def __init__(self):
+            """
+            Constructor
+            """
+            self.__highlighter = EnchantHighlighter(self.document())
+            try:
+                # Start with a default dictionary based on the current locale.
+                spellDict = (
+                    enchant.Dict(SpellCheckMixin.DefaultLanguage)
+                    if bool(SpellCheckMixin.DefaultLanguage) else
+                    enchant.Dict()
+                )
+            except DictNotFoundError:
+                # Use English dictionary if no locale dictionary is available
+                # or the default one could not be found.
+                spellDict = enchant.Dict("en")
+            self.__highlighter.setDict(spellDict)
+        
+        def contextMenuEvent(self, evt):
+            """
+            Protected method to handle context menu events to add a spelling
+            suggestions submenu.
+            
+            @param evt reference to the context menu event
+            @type QContextMenuEvent
+            """
+            menu = self.__createSpellcheckContextMenu(evt.pos())
+            menu.exec(evt.globalPos())
         
-        @param pos position of the mouse pointer
-        @type QPoint
-        @return context menu with additional spell-check entries
-        @rtype QMenu
-        """
-        menu = self.createStandardContextMenu(pos)
-        
-        # Add a submenu for setting the spell-check language and
-        # document format.
-        menu.addSeparator()
-        menu.addMenu(self.__createLanguagesMenu(menu))
-        menu.addMenu(self.__createFormatsMenu(menu))
-        
-        # Try to retrieve a menu of corrections for the right-clicked word
-        spellMenu = self.__createCorrectionsMenu(
-            self.__cursorForMisspelling(pos), menu)
+        def __createSpellcheckContextMenu(self, pos):
+            """
+            Private method to create the spell-check context menu.
+            
+            @param pos position of the mouse pointer
+            @type QPoint
+            @return context menu with additional spell-check entries
+            @rtype QMenu
+            """
+            menu = self.createStandardContextMenu(pos)
+            
+            # Add a submenu for setting the spell-check language and
+            # document format.
+            menu.addSeparator()
+            menu.addMenu(self.__createLanguagesMenu(menu))
+            menu.addMenu(self.__createFormatsMenu(menu))
+            
+            # Try to retrieve a menu of corrections for the right-clicked word
+            spellMenu = self.__createCorrectionsMenu(
+                self.__cursorForMisspelling(pos), menu)
+            
+            if spellMenu:
+                menu.insertSeparator(menu.actions()[0])
+                menu.insertMenu(menu.actions()[0], spellMenu)
+            
+            return menu
         
-        if spellMenu:
-            menu.insertSeparator(menu.actions()[0])
-            menu.insertMenu(menu.actions()[0], spellMenu)
-        
-        return menu
-    
-    def __createCorrectionsMenu(self, cursor, parent=None):
-        """
-        Private method to create a menu for corrections of the selected word.
-        
-        @param cursor reference to the text cursor
-        @type QTextCursor
-        @param parent reference to the parent widget (defaults to None)
-        @type QWidget (optional)
-        @return menu with corrections
-        @rtype QMenu
-        """
-        if cursor is None:
+        def __createCorrectionsMenu(self, cursor, parent=None):
+            """
+            Private method to create a menu for corrections of the selected
+            word.
+            
+            @param cursor reference to the text cursor
+            @type QTextCursor
+            @param parent reference to the parent widget (defaults to None)
+            @type QWidget (optional)
+            @return menu with corrections
+            @rtype QMenu
+            """
+            if cursor is None:
+                return None
+            
+            text = cursor.selectedText()
+            suggestions = trim_suggestions(
+                text, self.__highlighter.dict().suggest(text),
+                SpellCheckMixin.MaxSuggestions)
+            
+            spellMenu = QMenu(
+                QCoreApplication.translate("SpellCheckMixin",
+                                           "Spelling Suggestions"),
+                parent)
+            for word in suggestions:
+                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
+            
             return None
         
-        text = cursor.selectedText()
-        suggestions = trim_suggestions(text,
-                                       self.__highlighter.dict().suggest(text),
-                                       SpellCheckMixin.MaxSuggestions)
-        
-        spellMenu = QMenu(
-            QCoreApplication.translate("SpellCheckMixin",
-                                       "Spelling Suggestions"),
-            parent)
-        for word in suggestions:
-            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
-        
-        return None
-    
-    def __createLanguagesMenu(self, parent=None):
-        """
-        Private method to create a menu for selecting the spell-check language.
-        
-        @param parent reference to the parent widget (defaults to None)
-        @type QWidget (optional)
-        @return menu with spell-check languages
-        @rtype QMenu
-        """
-        curLanguage = self.__highlighter.dict().tag
-        languageMenu = QMenu(
-            QCoreApplication.translate("SpellCheckMixin", "Language"),
-            parent)
-        languageActions = QActionGroup(languageMenu)
+        def __createLanguagesMenu(self, parent=None):
+            """
+            Private method to create a menu for selecting the spell-check
+            language.
+            
+            @param parent reference to the parent widget (defaults to None)
+            @type QWidget (optional)
+            @return menu with spell-check languages
+            @rtype QMenu
+            """
+            curLanguage = self.__highlighter.dict().tag.lower()
+            languageMenu = QMenu(
+                QCoreApplication.translate("SpellCheckMixin", "Language"),
+                parent)
+            languageActions = QActionGroup(languageMenu)
+            
+            for language in sorted(enchant.list_languages()):
+                act = QAction(language, languageActions)
+                act.setCheckable(True)
+                act.setChecked(language.lower() == curLanguage)
+                act.setData(language)
+                languageMenu.addAction(act)
+            
+            languageMenu.triggered.connect(self.__setLanguage)
+            return languageMenu
         
-        for language in enchant.list_languages():
-            act = QAction(language, languageActions)
-            act.setCheckable(True)
-            act.setChecked(language == curLanguage)
-            act.setData(language)
-            languageMenu.addAction(act)
-        
-        languageMenu.triggered.connect(self.__setLanguage)
-        return languageMenu
-    
-    def __createFormatsMenu(self, parent=None):
-        """
-        Private method to create a menu for selecting the document format.
-        
-        @param parent reference to the parent widget (defaults to None)
-        @type QWidget (optional)
-        @return menu with document formats
-        @rtype QMenu
-        """
-        formatMenu = QMenu(
-            QCoreApplication.translate("SpellCheckMixin", "Format"),
-            parent)
-        formatActions = QActionGroup(formatMenu)
-        
-        curFormat = self.__highlighter.chunkers()
-        for name, chunkers in (
-            (QCoreApplication.translate("SpellCheckMixin", "Text"),
-             []),
-            (QCoreApplication.translate("SpellCheckMixin", "HTML"),
-             [tokenize.HTMLChunker])
-        ):
-            act = QAction(name, formatActions)
-            act.setCheckable(True)
-            act.setChecked(chunkers == curFormat)
-            act.setData(chunkers)
-            formatMenu.addAction(act)
+        def __createFormatsMenu(self, parent=None):
+            """
+            Private method to create a menu for selecting the document format.
+            
+            @param parent reference to the parent widget (defaults to None)
+            @type QWidget (optional)
+            @return menu with document formats
+            @rtype QMenu
+            """
+            formatMenu = QMenu(
+                QCoreApplication.translate("SpellCheckMixin", "Format"),
+                parent)
+            formatActions = QActionGroup(formatMenu)
+            
+            curFormat = self.__highlighter.chunkers()
+            for name, chunkers in (
+                (QCoreApplication.translate("SpellCheckMixin", "Text"),
+                 []),
+                (QCoreApplication.translate("SpellCheckMixin", "HTML"),
+                 [enchant.tokenize.HTMLChunker])
+            ):
+                act = QAction(name, formatActions)
+                act.setCheckable(True)
+                act.setChecked(chunkers == curFormat)
+                act.setData(chunkers)
+                formatMenu.addAction(act)
+            
+            formatMenu.triggered.connect(self.__setFormat)
+            return formatMenu
         
-        formatMenu.triggered.connect(self.__setFormat)
-        return formatMenu
-    
-    def __cursorForMisspelling(self, pos):
-        """
-        Private method to create a text cursor selecting the misspelled word.
-        
-        @param pos position of the misspelled word
-        @type QPoint
-        @return text cursor for the misspelled word
-        @rtype QTextCursor
-        """
-        cursor = self.cursorForPosition(pos)
-        misspelledWords = getattr(cursor.block().userData(), "misspelled", [])
+        def __cursorForMisspelling(self, pos):
+            """
+            Private method to create a text cursor selecting the misspelled
+            word.
+            
+            @param pos position of the misspelled word
+            @type QPoint
+            @return text cursor for the misspelled word
+            @rtype QTextCursor
+            """
+            cursor = self.cursorForPosition(pos)
+            misspelledWords = getattr(cursor.block().userData(),
+                                      "misspelled", [])
+            
+            # If the cursor is within a misspelling, select the word
+            for (start, end) in misspelledWords:
+                if start <= cursor.positionInBlock() <= end:
+                    blockPosition = cursor.block().position()
+                    
+                    cursor.setPosition(blockPosition + start,
+                                       QTextCursor.MoveMode.MoveAnchor)
+                    cursor.setPosition(blockPosition + end,
+                                       QTextCursor.MoveMode.KeepAnchor)
+                    break
+            
+            if cursor.hasSelection():
+                return cursor
+            else:
+                return None
         
-        # If the cursor is within a misspelling, select the word
-        for (start, end) in misspelledWords:
-            if start <= cursor.positionInBlock() <= end:
-                blockPosition = cursor.block().position()
-                
-                cursor.setPosition(blockPosition + start,
-                                   QTextCursor.MoveMode.MoveAnchor)
-                cursor.setPosition(blockPosition + end,
-                                   QTextCursor.MoveMode.KeepAnchor)
-                break
+        @pyqtSlot(QAction)
+        def __correctWord(self, act):
+            """
+            Private slot to correct the misspelled word with the selected
+            correction.
+            
+            @param act reference to the selected action
+            @type QAction
+            """
+            cursor, word = act.data()
+            
+            cursor.beginEditBlock()
+            cursor.removeSelectedText()
+            cursor.insertText(word)
+            cursor.endEditBlock()
         
-        if cursor.hasSelection():
-            return cursor
-        else:
-            return None
-    
-    @pyqtSlot(QAction)
-    def __correctWord(self, act):
-        """
-        Private slot to correct the misspelled word with the selected
-        correction.
-        
-        @param act reference to the selected action
-        @type QAction
-        """
-        cursor, word = act.data()
+        @pyqtSlot(QAction)
+        def __setLanguage(self, act):
+            """
+            Private slot to set the selected language.
+            
+            @param act reference to the selected action
+            @type QAction
+            """
+            language = act.data()
+            self.__highlighter.setDict(enchant.Dict(language))
         
-        cursor.beginEditBlock()
-        cursor.removeSelectedText()
-        cursor.insertText(word)
-        cursor.endEditBlock()
-    
-    @pyqtSlot(QAction)
-    def __setLanguage(self, act):
-        """
-        Private slot to set the selected language.
+        @pyqtSlot(QAction)
+        def __setFormat(self, act):
+            """
+            Private slot to set the selected document format.
+            
+            @param act reference to the selected action
+            @type QAction
+            """
+            chunkers = act.data()
+            self.__highlighter.setChunkers(chunkers)
         
-        @param act reference to the selected action
-        @type QAction
-        """
-        language = act.data()
-        self.__highlighter.setDict(enchant.Dict(language))
-    
-    @pyqtSlot(QAction)
-    def __setFormat(self, act):
-        """
-        Private slot to set the selected document format.
+        def setFormat(self, formatName):
+            """
+            Public method to set the document format.
+            
+            @param formatName name of the document format
+            @type str
+            """
+            self.__highlighter.setChunkers(
+                [enchant.tokenize.HTMLChunker]
+                if format == "html" else
+                []
+            )
         
-        @param act reference to the selected action
-        @type QAction
-        """
-        chunkers = act.data()
-        self.__highlighter.setChunkers(chunkers)
-    
-    def setFormat(self, formatName):
-        """
-        Public method to set the document format.
+        def dict(self):
+            """
+            Public method to get a reference to the dictionary in use.
+            
+            @return reference to the current dictionary
+            @rtype enchant.Dict
+            """
+            return self.__highlighter.dict()
         
-        @param formatName name of the document format
-        @type str
-        """
-        self.__highlighter.setChunkers(
-            [tokenize.HTMLChunker]
-            if format == "html" else
-            []
-        )
-    
-    def dict(self):
+        def setDict(self, spellDict):
+            """
+            Public method to set the dictionary to be used.
+            
+            @param spellDict reference to the spell-check dictionary
+            @type emchant.Dict
+            """
+            self.__highlighter.setDict(spellDict)
+        
+        @classmethod
+        def setDefaultLanguage(cls, language):
+            """
+            Class method to set the default spell-check language.
+            
+            @param language language to be set as default
+            @type str
+            """
+            with contextlib.suppress(DictNotFoundError):
+                # set default language only, if a dictionary is available
+                enchant.Dict(language)
+                cls.DefaultLanguage = language
+
+    class EnchantHighlighter(QSyntaxHighlighter):
         """
-        Public method to get a reference to the dictionary in use.
-        
-        @return reference to the current dictionary
-        @rtype enchant.Dict
-        """
-        return self.__highlighter.dict()
-    
-    def setDict(self, spellDict):
-        """
-        Public method to set the dictionary to be used.
-        
-        @param spellDict reference to the spell-check dictionary
-        @type emchant.Dict
-        """
-        self.__highlighter.setDict(spellDict)
-
-
-class EnchantHighlighter(QSyntaxHighlighter):
-    """
-    Class implementing a QSyntaxHighlighter subclass that consults a
-    pyEnchant dictionary to highlight misspelled words.
-    """
-    TokenFilters = (tokenize.EmailFilter, tokenize.URLFilter)
-
-    # Define the spell-check style once and just assign it as necessary
-    ErrorFormat = QTextCharFormat()
-    ErrorFormat.setUnderlineColor(Qt.GlobalColor.red)
-    ErrorFormat.setUnderlineStyle(
-        QTextCharFormat.UnderlineStyle.SpellCheckUnderline)
-    
-    def __init__(self, *args):
-        """
-        Constructor
-        
-        @param *args list of arguments for the QSyntaxHighlighter
-        @type list
-        """
-        QSyntaxHighlighter.__init__(self, *args)
-        
-        self.__spellDict = None
-        self.__chunkers = []
-    
-    def chunkers(self):
-        """
-        Public method to get the chunkers in use.
-        
-        @return list of chunkers in use
-        @rtype list
-        """
-        return self.__chunkers
-    
-    def setChunkers(self, chunkers):
-        """
-        Public method to set the chunkers to be used.
-        
-        @param chunkers chunkers to be used
-        @type list
-        """
-        self.__chunkers = chunkers
-        self.setDict(self.dict())
-    
-    def dict(self):
-        """
-        Public method to get the spelling dictionary in use.
-        
-        @return spelling dictionary
-        @rtype enchant.Dict
-        """
-        return self.__spellDict
-    
-    def setDict(self, spellDict):
-        """
-        Public method to set the spelling dictionary to be used.
-        
-        @param spellDict spelling dictionary
-        @type enchant.Dict
+        Class implementing a QSyntaxHighlighter subclass that consults a
+        pyEnchant dictionary to highlight misspelled words.
         """
-        try:
-            self.__tokenizer = tokenize.get_tokenizer(
-                spellDict.tag,
-                chunkers=self.__chunkers,
-                filters=EnchantHighlighter.TokenFilters)
-        except TokenizerNotFoundError:
-            # Fall back to the "good for most euro languages" English tokenizer
-            self.__tokenizer = tokenize.get_tokenizer(
-                chunkers=self.__chunkers,
-                filters=EnchantHighlighter.TokenFilters)
-        self.__spellDict = spellDict
-        
-        self.rehighlight()
-    
-    def highlightBlock(self, text):
-        """
-        Public method to apply the text highlight.
-        
-        @param text text to be spell-checked
-        @type str
-        """
-        """Overridden QSyntaxHighlighter method to apply the highlight"""
-        if not self.__spellDict:
-            return
-        
-        # Build a list of all misspelled words and highlight them
-        misspellings = []
-        for (word, pos) in self.__tokenizer(text):
-            if not self.__spellDict.check(word):
-                self.setFormat(pos, len(word), EnchantHighlighter.ErrorFormat)
-                misspellings.append((pos, pos + len(word)))
-        
-        # Store the list so the context menu can reuse this tokenization pass
-        # (Block-relative values so editing other blocks won't invalidate them)
-        data = QTextBlockUserData()
-        data.misspelled = misspellings
-        self.setCurrentBlockUserData(data)
-
+        TokenFilters = (enchant.tokenize.EmailFilter,
+                        enchant.tokenize.URLFilter)
 
-class EricSpellCheckedPlainTextEdit(QPlainTextEdit, SpellCheckMixin):
-    """
-    Class implementing a QPlainTextEdit with built-in spell checker.
-    """
-    def __init__(self, *args):
-        """
-        Constructor
+        # Define the spell-check style once and just assign it as necessary
+        ErrorFormat = QTextCharFormat()
+        ErrorFormat.setUnderlineColor(Qt.GlobalColor.red)
+        ErrorFormat.setUnderlineStyle(
+            QTextCharFormat.UnderlineStyle.SpellCheckUnderline)
+        
+        def __init__(self, *args):
+            """
+            Constructor
+            
+            @param *args list of arguments for the QSyntaxHighlighter
+            @type list
+            """
+            QSyntaxHighlighter.__init__(self, *args)
+            
+            self.__spellDict = None
+            self.__chunkers = []
+        
+        def chunkers(self):
+            """
+            Public method to get the chunkers in use.
+            
+            @return list of chunkers in use
+            @rtype list
+            """
+            return self.__chunkers
+        
+        def setChunkers(self, chunkers):
+            """
+            Public method to set the chunkers to be used.
+            
+            @param chunkers chunkers to be used
+            @type list
+            """
+            self.__chunkers = chunkers
+            self.setDict(self.dict())
+        
+        def dict(self):
+            """
+            Public method to get the spelling dictionary in use.
+            
+            @return spelling dictionary
+            @rtype enchant.Dict
+            """
+            return self.__spellDict
         
-        @param *args list of arguments for the QPlainTextEdit constructor.
-        @type list
-        """
-        QPlainTextEdit.__init__(self, *args)
-        SpellCheckMixin.__init__(self)
-
+        def setDict(self, spellDict):
+            """
+            Public method to set the spelling dictionary to be used.
+            
+            @param spellDict spelling dictionary
+            @type enchant.Dict
+            """
+            try:
+                self.__tokenizer = enchant.tokenize.get_tokenizer(
+                    spellDict.tag,
+                    chunkers=self.__chunkers,
+                    filters=EnchantHighlighter.TokenFilters)
+            except TokenizerNotFoundError:
+                # Fall back to the "good for most euro languages"
+                # English tokenizer
+                self.__tokenizer = enchant.tokenize.get_tokenizer(
+                    chunkers=self.__chunkers,
+                    filters=EnchantHighlighter.TokenFilters)
+            self.__spellDict = spellDict
+            
+            self.rehighlight()
+        
+        def highlightBlock(self, text):
+            """
+            Public method to apply the text highlight.
+            
+            @param text text to be spell-checked
+            @type str
+            """
+            """Overridden QSyntaxHighlighter method to apply the highlight"""
+            if not self.__spellDict:
+                return
+            
+            # Build a list of all misspelled words and highlight them
+            misspellings = []
+            for (word, pos) in self.__tokenizer(text):
+                if not self.__spellDict.check(word):
+                    self.setFormat(pos, len(word),
+                                   EnchantHighlighter.ErrorFormat)
+                    misspellings.append((pos, pos + len(word)))
+            
+            # Store the list so the context menu can reuse this tokenization
+            # pass (Block-relative values so editing other blocks won't
+            # invalidate them)
+            data = QTextBlockUserData()
+            data.misspelled = misspellings
+            self.setCurrentBlockUserData(data)
 
-class EricSpellCheckedTextEdit(QTextEdit, SpellCheckMixin):
-    """
-    Class implementing a QTextEdit with built-in spell checker.
-    """
-    def __init__(self, *args):
+    class EricSpellCheckedPlainTextEdit(QPlainTextEdit, SpellCheckMixin):
+        """
+        Class implementing a QPlainTextEdit with built-in spell checker.
         """
-        Constructor
-        
-        @param *args list of arguments for the QPlainTextEdit constructor.
-        @type list
+        def __init__(self, *args):
+            """
+            Constructor
+            
+            @param *args list of arguments for the QPlainTextEdit constructor.
+            @type list
+            """
+            QPlainTextEdit.__init__(self, *args)
+            SpellCheckMixin.__init__(self)
+
+    class EricSpellCheckedTextEdit(QTextEdit, SpellCheckMixin):
+        """
+        Class implementing a QTextEdit with built-in spell checker.
         """
-        QTextEdit.__init__(self, *args)
-        SpellCheckMixin.__init__(self)
+        def __init__(self, *args):
+            """
+            Constructor
+            
+            @param *args list of arguments for the QPlainTextEdit constructor.
+            @type list
+            """
+            QTextEdit.__init__(self, *args)
+            SpellCheckMixin.__init__(self)
+            
+            self.setFormat("html")
         
-        self.setFormat("html")
-    
-    def setAcceptRichText(self, accept):
-        """
-        Public method to set the text edit mode.
-        
-        @param accept flag indicating to accept rich text
-        @type bool
-        """
-        QTextEdit.setAcceptRichText(accept)
-        self.setFormat("html" if accept else "text")
+        def setAcceptRichText(self, accept):
+            """
+            Public method to set the text edit mode.
+            
+            @param accept flag indicating to accept rich text
+            @type bool
+            """
+            QTextEdit.setAcceptRichText(self, accept)
+            self.setFormat("html" if accept else "text")
+else:
+    # enchant not available
+    EricSpellCheckedPlainTextEdit = QPlainTextEdit
+    EricSpellCheckedTextEdit = QTextEdit
 
 if __name__ == '__main__':
+    import sys
     from PyQt6.QtWidgets import QApplication
     
+    if ENCHANT_AVAILABLE:
+        SpellCheckMixin.setDefaultLanguage("en_US")
+    
     app = QApplication(sys.argv)
     spellEdit = EricSpellCheckedPlainTextEdit()
     spellEdit.show()

eric ide

mercurial