def get_spellcheck_config(): """ Create TinyMCE spellchecker config based on Django settings :return: spellchecker parameters for TinyMCE :rtype: dict """ config = {} if mce_settings.USE_SPELLCHECKER: from enchant import list_languages enchant_languages = list_languages() if settings.DEBUG: logger.info('Enchant languages: {0}'.format(enchant_languages)) lang_names = [] for lang, name in settings.LANGUAGES: lang = convert_language_code(lang) if lang not in enchant_languages: lang = lang[:2] if lang not in enchant_languages: logger.warning('Missing {0} spellchecker dictionary!'.format(lang)) continue if config.get('spellchecker_language') is None: config['spellchecker_language'] = lang lang_names.append('{0}={1}'.format(name, lang)) config['spellchecker_languages'] = ','.join(lang_names) return config
def __init__(self): # This method is only called once per process, but that is no problem # since the enchant languange list should not change. Don't use this # method for anything that should run every time the task is called. # See http://docs.celeryproject.org/en/latest/userguide/tasks.html#instantiation # for more information. self.checkers = {lang: SpellChecker(lang) for lang in enchant.list_languages()}
def __init__(self, args): """ Constructor """ QMainWindow.__init__(self) self.setupUi(self) self.text = None self.path = "" self.lang_actions = {} for lang in enchant.list_languages(): action = self.menuLanguages.addAction(lang) action.setCheckable(True) action.triggered.connect(self.on_languageChanged) self.lang_actions[lang] = action self.spell_dict = enchant.Dict() self.lang_actions[self.spell_dict.tag].setChecked(True) self.current_language = self.spell_dict.tag self.lexers = self.get_lexers() self.setChanged(False) self.search = None self.spell_checker = None if len(args) > 1: self.path = args[1] self.open() self.textEdit.textChanged.connect(self.on_textChanged)
def get_language_config(): """ Creates a language configuration for TinyMCE4 based on Django project settings :return: language- and locale-related parameters for TinyMCE 4 :rtype: dict """ config = {"language": get_language()[:2]} if get_language_bidi(): config["directionality"] = "rtl" else: config["directionality"] = "ltr" if mce_settings.USE_SPELLCHECKER: from enchant import list_languages enchant_languages = list_languages() logger.debug("Enchant languages: {0}".format(enchant_languages)) lang_names = [] for lang, name in settings.LANGUAGES: lang = convert_language_code(lang) if lang not in enchant_languages: lang = lang[:2] if lang not in enchant_languages: logger.error("Missing {0} spellchecker dictionary!".format(lang)) continue if config.get("spellchecker_language") is None: config["spellchecker_language"] = lang lang_names.append("{0}={1}".format(name, lang)) config["spellchecker_languages"] = ",".join(lang_names) return config
def languages(self): """ @raise ImportError: if pyenchant is not installed """ import enchant return enchant.list_languages()
def __init__(self, parent): self.parent = parent wx.Panel.__init__(self, parent, -1) self.pref = Globals.pref self.sizer = sizer = ui.VBox(padding=0, namebinding='widget').create(self).auto_layout() h = sizer.add(ui.HBox) h.add(ui.Label(tr("Replace with") + ':')) h.add(ui.Text('', size=(150, -1)), name='text') h.add(ui.Button(tr('Start')), name='btnRun').bind('click', self.OnRun) h.add(ui.Button(tr('Replace')), name='btnReplace').bind('click', self.OnReplace) h.add(ui.Button(tr('Replace All')), name='btnReplaceAll').bind('click', self.OnReplaceAll) h.add(ui.Button(tr('Ignore')), name='btnIgnore').bind('click', self.OnIgnore) h.add(ui.Button(tr('Ignore All')), name='btnIgnoreAll').bind('click', self.OnIgnoreAll) h.add(ui.Button(tr('Add')), name='btnAdd').bind('click', self.OnAdd) h = sizer.add(ui.HBox, proportion=1) h.add(ui.Label(tr("Suggest") + ':')) h.add(ui.ListBox(size=(250, -1)), name='list').binds( (wx.EVT_LISTBOX, self._OnReplSelect), (wx.EVT_LISTBOX_DCLICK, self.OnReplace), ) h.add(ui.Label(tr("Available Dict") + ':')) h.add(ui.ListBox(size=(100, -1), choices=enchant.list_languages()), name='dict_list').bind( wx.EVT_LISTBOX, self.OnDictSelect ) sizer.auto_fit(0) self.init() self._DisableButtons()
def initSpellchecker(self): # TODO: disable spellchecker icon in case of not working enchant try: import enchant spellDictDir = settings.get('spellchecker:directory') if spellDictDir: if enchant.__ver_major__ >= 1 and enchant.__ver_minor__ >= 6: enchant.set_param("enchant.myspell.dictionary.path", spellDictDir) else: print("Your pyenchant version is to old. Please " \ "upgrade to version 1.6.0 or higher, if you want " \ "to use spellchecker.") return None spellLang = settings.get('spellchecker:lang') if spellLang in enchant.list_languages(): # enchant.dict_exists(spellLang) do now work for me on linux... self.dict = enchant.Dict(spellLang) else: # try dictionary based on the current locale try: self.dict = enchant.Dict() settings.set('spellchecker:lang', self.dict.tag) except: # we don not have working dictionary... return None if self.dict: self.usePWL(self.dict) except: print("can not start spellchecker!!!") import traceback traceback.print_exc() return None
def enchant_and_dicts_available(): """Return ``True`` if :mod:`enchant` and dictionaries are available.""" try: import enchant return bool(enchant.list_languages()) except Exception: return False
def get_language_config(): """ Creates a language configuration for TinyMCE4 based on Django project settings :return: language- and locale-related parameters for TinyMCE 4 :rtype: dict """ config = {"language": get_language()[:2]} if get_language_bidi(): config["directionality"] = "rtl" else: config["directionality"] = "ltr" if mce_settings.USE_SPELLCHECKER: from enchant import list_languages enchant_languages = list_languages() logger.debug("Enchant languages: {0}".format(enchant_languages)) lang_names = [] for lang, name in settings.LANGUAGES: lang = convert_language_code(lang) if lang not in enchant_languages: lang = lang[:2] if lang not in enchant_languages: logger.error( "Missing {0} spellchecker dictionary!".format(lang)) continue if config.get("spellchecker_language") is None: config["spellchecker_language"] = lang lang_names.append("{0}={1}".format(name, lang)) config["spellchecker_languages"] = ",".join(lang_names) return config
def get_enchant_base_languages_dict(): """Get ordered dictionary of enchant base languages. locale_language, then "en", then the rest. """ global enchant_base_languages_dict if enchant_base_languages_dict is None: def get_language_sub_tag(tag): return tag.split("_")[0] enchant_base_languages_dict = OrderedDict() enchant_languages = sorted(enchant.list_languages()) for full_tag in [get_locale_language(), "en_US"]: sub_tag = get_language_sub_tag(full_tag) if sub_tag not in enchant_base_languages_dict: for tag in [full_tag, sub_tag]: try: index = enchant_languages.index(tag) except ValueError: pass else: enchant_base_languages_dict[sub_tag] = tag del enchant_languages[index] break for tag in enchant_languages: sub_tag = get_language_sub_tag(tag) if sub_tag not in enchant_base_languages_dict: enchant_base_languages_dict[sub_tag] = tag return enchant_base_languages_dict
def TLGuessLanguages(text): if not TEHasEnchant: return TLDico[TLPreferences['DFT_WRITING_LANGUAGE']] a = str(text[:min(len(text), TLPreferences['GUESS_NB_CHAR'])]) a = [a] splitter = "\n .,;!?" for c in splitter: a_tmp = [w.split(c) for w in a] a = [w1 for w2 in a_tmp for w1 in w2] a = [w for w in a if len(w) > 0] k_max = TLPreferences['DFT_WRITING_LANGUAGE'] i_max = 0 for k, v in list(TLDico.items()): if v.code_enchant in enchant.list_languages(): d = enchant.Dict(v.code_enchant) i = 0 for w in a: if d.check(w): i += 1 if i > i_max: i_max = i k_max = k return k_max
def test_spell_check(self): import enchant languages = enchant.list_languages() lang = "en_US" if lang not in languages: lang = lang[:2] if lang not in languages: raise RuntimeError( "Enchant package does not have English spellckecker dictionary!" ) text = "The quick brown fox jumps over the lazy dog." data = {"id": "0", "params": {"lang": lang, "text": text}} response = self.client.post( reverse("tinymce-spellchecker"), data=json.dumps(data), content_type="application/json", ) self.assertTrue("result" in json.loads(response.content.decode("utf-8"))) text = "The quik brown fox jumps ower the lazy dog." data["params"]["text"] = text response = self.client.post( reverse("tinymce-spellchecker"), data=json.dumps(data), content_type="application/json", ) result = json.loads(response.content.decode("utf-8"))["result"] self.assertEqual(len(result), 2)
def list_languages(): pyenchant_langs = e.list_languages() supported_langs = list() for l in ENCHANT_LANG_MAP: pyel = ENCHANT_LANG_MAP[l] if pyel in pyenchant_langs: supported_langs.append(l) return supported_langs
def __init__(self,language): ''' Constructor ''' if enchant.dict_exists(language): self.dictionnary = enchant.Dict(language) else: availableDicos = '[%s]' % ', '.join(map(str, enchant.list_languages())) sys.exit("No dictionary installed for {}, the available dictionaries are: {}".format(language,availableDicos))
def _populate_store(self, store): """Add all available languages to `store`.""" try: locales = set(enchant.list_languages()) except enchant.Error: return for locale in locales: try: enchant.Dict(locale).check("gaupol") except enchant.Error: continue try: name = aeidon.locales.code_to_name(locale) except LookupError: name = locale store.append((locale, name))
def dlg_select_dict(): items = sorted(enchant.list_languages()) global op_lang if op_lang in items: focused = items.index(op_lang) else: focused = -1 res = dlg_menu(MENU_LIST, '\n'.join(items), focused) if res is None: return return items[res]
def __init__(self): # This method is only called once per process, but that is no problem # since the enchant languange list should not change. Don't use this # method for anything that should run every time the task is called. # See http://docs.celeryproject.org/en/latest/userguide/tasks.html#instantiation # for more information. self.checkers = { lang: SpellChecker(lang) for lang in enchant.list_languages() }
def _populate_store(self, store): """Add all available languages to `store`.""" locales = [] with aeidon.util.silent(Exception): import enchant locales = enchant.list_languages() for locale in locales: with aeidon.util.silent(enchant.Error): enchant.Dict(locale).check("gaupol") name = aeidon.locales.code_to_name(locale) store.append((locale, name))
def getAvailableLanguages(cls): """ Class method to get all available languages. @return list of available languages (list of strings) """ try: return enchant.list_languages() except NameError: pass return []
def verify_pyenchant(): w('Enchant (spell checker)... ') try: import enchant w(os.linesep) backends = ', '.join([x.name for x in enchant.Broker().describe()]) print(' available backends: %s' % backends) langs = ', '.join(enchant.list_languages()) print(' available languages: %s' % langs) except ImportError: w('FAIL' + os.linesep)
def available_languages(): result = [] if Gspell: for lang in Gspell.Language.get_available(): result.append((lang.get_name(), lang.get_code())) elif enchant: languages = enchant.list_languages() languages.sort() for lang in languages: result.append((lang, lang)) return result
def setup_prefs(self): for item in EDITOR_PREFS: self.ui.__dict__[item[CHK]].setChecked( common.editor_config.get_pref(item[CFG], item[DEFAULT])) # And our spellcheck language has to be handled manually. self.ui.cboSpellCheckLang.clear() self.ui.cboSpellCheckLang.addItems(enchant.list_languages()) lang_index = self.ui.cboSpellCheckLang.findText( common.editor_config.spell_check_lang, Qt.Qt.MatchContains) self.ui.cboSpellCheckLang.setCurrentIndex(lang_index)
def isAvailable(cls): """ Class method to check, if spellchecking is available. @return flag indicating availability (boolean) """ if Preferences.getEditor("SpellCheckingEnabled"): try: return len(enchant.list_languages()) > 0 except (NameError, AttributeError): pass return False
def index(): form = LetterForm() results = '' # test for invalid language coce valid_languages = True if form.languages.data is None: language_codes = [] else: language_codes = re.findall("[^\s]+", form.languages.data) for code in language_codes: if code not in enchant.list_languages(): valid_languages = False if form.validate_on_submit() and (valid_languages): print "Request Submitted (" + form.letters.data + ", " + form.languages.data + ")" # get results result_dict = unscrambler.unscramble(form.letters.data, language_codes) print "Unscrambled Results:", result_dict # make human readable and embed in page results = '' for lang in result_dict.keys(): freq_dict = {i: [] for i in range(2, len(form.letters.data) + 1)} for word in result_dict[lang]: freq_dict[len(word)].append(word) results += "<h3>" + lang + ":</h3>" + '<br>'.join([ ', '.join(sorted(freq_dict[i])) for i in range(2, len(form.letters.data) + 1) ]) else: results = "<h3>Unable to Run Query</h3> Check number of letters and language codes" # write page and pass relevant values return render_template('index.html', form=form, results=results, languages=enchant.list_languages())
def check_errors(self, langs, text): errors = [] for lang in langs: if lang in enchant.list_languages(): chkr = SpellChecker(lang) chkr.set_text(text) errors_set = set() for err in chkr: errors_set.add(err.word) errors.append(errors_set) return set.intersection(*errors)
def setup_prefs(self): for item in EDITOR_PREFS_CHK: self.ui.__dict__[item[CHK]].setChecked(common.editor_config.get_pref(item[CFG], item[DEFAULT])) for item in EDITOR_PREFS_TXT: self.ui.__dict__[item[TEXT]].setText(common.editor_config.get_pref(item[CFG])) # And our spellcheck language has to be handled manually. self.ui.cboSpellCheckLang.clear() self.ui.cboSpellCheckLang.addItems(enchant.list_languages()) lang_index = self.ui.cboSpellCheckLang.findText(common.editor_config.spell_check_lang, Qt.Qt.MatchContains) self.ui.cboSpellCheckLang.setCurrentIndex(lang_index)
def print_enchant_backends_and_languages(): """ Check if PyEnchant is installed. """ w('Enchant (spell checker)... ') try: import enchant w(os.linesep) backends = ', '.join([x.name for x in enchant.Broker().describe()]) print(' available backends: %s' % backends) langs = ', '.join(enchant.list_languages()) print(' available languages: %s' % langs) except ImportError: w('FAIL' + os.linesep)
def getAvailableLanguages(cls): """Return a list of supported languages. Pyenchant supplies a list of its supported languages, so this is just a simple wrapper around its C{list_languages} function. Each item in the list is a text string indicating the locale name, e.g. en_US, ru, ru_RU, eo, es_ES, etc. @return: a list of text strings indicating the supported languages """ try: return enchant.list_languages() except NameError: pass return []
def _populate_store(self, store): """Add all available languages to `store`.""" locales = [] with aeidon.util.silent(Exception): import enchant locales = enchant.list_languages() for locale in locales: with aeidon.util.silent(enchant.Error): if len(locales) < 100: # Some locales don't actually work, so initialize and check # a word to test. With a lot of locales, e.g. with Flatpak, # this cumulates to an unbearable amount of time. enchant.Dict(locale).check("gaupol") name = aeidon.locales.code_to_name(locale) store.append((locale, name))
def select_language(): available_languages = enchant.list_languages() selected_language = None print(highlight("Please select a language: ", 0)) print(available_languages) for i, s in enumerate(available_languages): print(i, '-', s) while not selected_language: try: n = int(input('? ')) selected_language = available_languages[n] except (IndexError, ValueError): print(highlight('You did not select a language!\n',1)) print("You selected %s.\n" % highlight(selected_language, 2)) return selected_language
def contextMenuEvent(self, event): """ Provide the context menu for the text edit region. """ popup_menu = self.createStandardContextMenu() # Select the word under the cursor. cursor = self.textCursor() # only select text if not already selected if not cursor.hasSelection(): cursor.select(QtGui.QTextCursor.WordUnderCursor) self.setTextCursor(cursor) # Add menu with available languages. if ENCHANT_AVAILABLE: lang_menu = QtWidgets.QMenu( translate('OpenLP.SpellTextEdit', 'Language:')) for lang in enchant.list_languages(): action = create_action(lang_menu, lang, text=lang, checked=lang == self.dictionary.tag) lang_menu.addAction(action) popup_menu.insertSeparator(popup_menu.actions()[0]) popup_menu.insertMenu(popup_menu.actions()[0], lang_menu) lang_menu.triggered.connect(self.set_language) # Check if the selected word is misspelled and offer spelling suggestions if it is. if ENCHANT_AVAILABLE and self.textCursor().hasSelection(): text = self.textCursor().selectedText() if not self.dictionary.check(text): spell_menu = QtWidgets.QMenu( translate('OpenLP.SpellTextEdit', 'Spelling Suggestions')) for word in self.dictionary.suggest(text): action = SpellAction(word, spell_menu) action.correct.connect(self.correct_word) spell_menu.addAction(action) # Only add the spelling suggests to the menu if there are suggestions. if spell_menu.actions(): popup_menu.insertMenu(popup_menu.actions()[0], spell_menu) tag_menu = QtWidgets.QMenu( translate('OpenLP.SpellTextEdit', 'Formatting Tags')) if self.formatting_tags_allowed: for html in FormattingTags.get_html_tags(): action = SpellAction(html['desc'], tag_menu) action.correct.connect(self.html_tag) tag_menu.addAction(action) popup_menu.insertSeparator(popup_menu.actions()[0]) popup_menu.insertMenu(popup_menu.actions()[0], tag_menu) popup_menu.exec(event.globalPos())
def main(): base_path = os.getcwd() grid_path = os.path.join(base_path, 'grid.txt') pwl_path = os.path.join(base_path, 'personal_word_list.txt') config_path = os.path.join(base_path, 'config.txt') config_dict = get_config_params(config_path) try: arg = sys.argv[1] except IndexError: sys.exit('No action provided: [open, hint, solve]') language = 'en_US' if 'lang' in config_dict: language = config_dict['lang'] if arg == 'open': webbrowser.open(grid_path) elif arg == 'hint': solver = WordbrainSolver(grid_path, pwl_path, lang=language) solver.hint() elif arg == 'solve': solver = WordbrainSolver(grid_path, pwl_path, lang=language) solver.solve() elif arg == 'languages': available_langs = enchant.list_languages() for num,lang in enumerate(available_langs): print('{} {}'.format(num, lang)) print('Choose a language. Type the number of the language you want.') language_num = raw_input() while not process_lang_input(language_num, len(available_langs)): language_num = raw_input() chosen_language = available_langs[int(language_num)] write_config_param(config_path, 'lang', chosen_language) elif arg == 'help': print_help_message() else: sys.exit('Unrecognized argument: {}'.format(arg))
def get_spellchecker_languages(directory = None): """ Check if spellchecker is installed and provide list of languages """ try: import enchant if (directory): enchant.set_param("enchant.myspell.dictionary.path", directory) langs = enchant.list_languages() return sorted(langs) except: print "can not start spellchecker!!!" import traceback traceback.print_exc() return None
def contextMenuEvent(self, event): """ Provide the context menu for the text edit region. """ popupMenu = self.createStandardContextMenu() # Select the word under the cursor. cursor = self.textCursor() # only select text if not already selected if not cursor.hasSelection(): cursor.select(QtGui.QTextCursor.WordUnderCursor) self.setTextCursor(cursor) # Add menu with available languages. if ENCHANT_AVAILABLE: lang_menu = QtGui.QMenu( translate('OpenLP.SpellTextEdit', 'Language:')) for lang in enchant.list_languages(): action = create_action(lang_menu, lang, text=lang, checked=lang == self.dictionary.tag) lang_menu.addAction(action) popupMenu.insertSeparator(popupMenu.actions()[0]) popupMenu.insertMenu(popupMenu.actions()[0], lang_menu) QtCore.QObject.connect(lang_menu, QtCore.SIGNAL(u'triggered(QAction*)'), self.setLanguage) # Check if the selected word is misspelled and offer spelling # suggestions if it is. if ENCHANT_AVAILABLE and self.textCursor().hasSelection(): text = self.textCursor().selectedText() if not self.dictionary.check(text): spell_menu = QtGui.QMenu(translate('OpenLP.SpellTextEdit', 'Spelling Suggestions')) for word in self.dictionary.suggest(text): action = SpellAction(word, spell_menu) action.correct.connect(self.correctWord) spell_menu.addAction(action) # Only add the spelling suggests to the menu if there are # suggestions. if spell_menu.actions(): popupMenu.insertMenu(popupMenu.actions()[0], spell_menu) tagMenu = QtGui.QMenu(translate('OpenLP.SpellTextEdit', 'Formatting Tags')) if self.formattingTagsAllowed: for html in FormattingTags.get_html_tags(): action = SpellAction(html[u'desc'], tagMenu) action.correct.connect(self.htmlTag) tagMenu.addAction(action) popupMenu.insertSeparator(popupMenu.actions()[0]) popupMenu.insertMenu(popupMenu.actions()[0], tagMenu) popupMenu.exec_(event.globalPos())
def test_spell_check(self): import enchant languages = enchant.list_languages() lang = 'en_US' if lang not in languages: lang = lang[:2] if lang not in languages: raise LookupError('Enchant package does not have English spellckecker dictionary!') text = 'The quick brown fox jumps over the lazy dog.' data = {'id': '0', 'params': {'lang': lang, 'text': text}} response = self.client.post(reverse('tinymce-spellchecker'), data=json.dumps(data), content_type='application/json') self.assertTrue('result' in json.loads(response.content.decode('utf-8'))) text = 'The quik brown fox jumps ower the lazy dog.' data['params']['text'] = text response = self.client.post(reverse('tinymce-spellchecker'), data=json.dumps(data), content_type='application/json') result = json.loads(response.content.decode('utf-8'))['result'] self.assertEqual(len(result), 2)
def spell(self, channel, sender, line): if len(line.split()) == 2: lang, word = line.split() try: d = enchant.Dict(lang) except enchant.errors.DictNotFoundError: return 'Languages: ' + ', '.join(enchant.list_languages()) return sugg(d, word) if len(line.split()) == 1: d = enchant.Dict('en_US') return sugg(d, line) if not line: return 'Usage: [language] {<word for suggestions> | <sentence>}' words = line.split() if enchant.dict_exists(words[0]): c = enchant.checker.SpellChecker(words.pop(0)) else: c = enchant.checker.SpellChecker('en_US') c.set_text(' '.join(words)) return 'Unknown words: ' + ', '.join([i.word for i in c])
def __init__(self, parent): super(NoteEditor, self).__init__(parent) self.highlighter = Highlighter( self.document() ) # the language dictionary to be used self.dictionary = None self.highlighter.setDictionary(self.dictionary) # create dictionary selector menu self.dictionarySelector = QMenu("&Dictionary") self.dictionaryActions = QActionGroup(self) self.noDicitionaryAction = self.dictionaryActions.addAction("None") self.noDicitionaryAction.setCheckable(True) self.dictionarySelector.addAction(self.noDicitionaryAction) self.defaultDicitionaryAction = self.dictionaryActions.addAction("Default") self.defaultDicitionaryAction.setCheckable(True) self.dictionarySelector.addAction(self.defaultDicitionaryAction) self.dictionarySelector.addSeparator() for lang in enchant.list_languages(): langAction = self.dictionaryActions.addAction(lang) langAction.setCheckable(True) self.dictionarySelector.addAction(langAction) # connect signal to change language dictionary and set the default language self.dictionaryActions.triggered.connect(self.changeDictionary) self.defaultDicitionaryAction.trigger() # configure the custom context menu for spelling suggestions self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.showContextMenu) # settings self.noteFilePath = "" #stores path to the file being edited self.setFont(QFont("Monospace")) tabWidth = QFontMetrics( self.currentCharFormat().font() ).width(" ")#get the width of four spaces self.setTabStopWidth(tabWidth) #set the default tab width to be that of four spaces
def contextMenuEvent(self, event): popup_menu = self.createStandardContextMenu() # Select the word under the cursor. cursor = self.textCursor() cursor.select(QtGui.QTextCursor.WordUnderCursor) self.setTextCursor(cursor) # Check if the selected word is misspelled and offer spelling # suggestions if it is. if enchant and self.spelldict: top_action = popup_menu.actions()[0] if self.textCursor().hasSelection(): text = unicode(self.textCursor().selectedText()) if not self.spelldict.check(text): suggestions = self.spelldict.suggest(text) if len(suggestions) != 0: popup_menu.insertSeparator(popup_menu.actions()[0]) for suggest in suggestions: self._menu_action(suggest, popup_menu, self.correctWord, after=top_action) popup_menu.insertSeparator(top_action) add_action = QtGui.QAction("Add to dictionary", self) add_action.triggered.connect(lambda: self.addWord(text)) popup_menu.insertAction(top_action, add_action) spell_menu = QtGui.QMenu(popup_menu) spell_menu.setTitle('Spellcheck') popup_menu.insertMenu(top_action, spell_menu) for lang in enchant.list_languages(): self._menu_action(lang, spell_menu, self.initDict, checked=(lang == self.spelldict.tag)) toggle = self._menu_action('Check spelling', spell_menu, self.toggleDict, checked=(self.spelldict is not False)) spell_menu.insertSeparator(toggle) elif enchant: toggle = self._menu_action('Check spelling', popup_menu, self.toggleDict, checked=False) popup_menu.insertSeparator(toggle) popup_menu.exec_(event.globalPos())