3866 3976 3977: Two 'spell' entries; remove Enchant dependency (patch by Tim Lyons)
svn: r17563
This commit is contained in:
parent
cbe4a1805f
commit
ff638d041b
8
README
8
README
@ -33,10 +33,8 @@ The following packages are *STRONGLY RECOMMENDED* to be installed:
|
||||
Obtain it from: http://tilloy.net/dev/pyexiv2/download.html
|
||||
|
||||
The following packages are optional
|
||||
python gtkspell
|
||||
python enchant Enable spell checking in the notes, gtkspell contains the
|
||||
libraries, enchant is needed to query the installed languages.
|
||||
Both must be present for spell check to activate
|
||||
python gtkspell Enable spell checking in the notes, gtkspell contains the
|
||||
libraries.
|
||||
|
||||
ttf-freefont More font support in the reports
|
||||
|
||||
@ -62,6 +60,8 @@ The following packages are optional
|
||||
It can be in python-gnome2-extras or python-gtkhtml2
|
||||
depending on distributions.
|
||||
|
||||
No longer needed in 3.3:
|
||||
python-enchant Enchant
|
||||
No longer needed in 3.2:
|
||||
python glade bindings
|
||||
No longer needed in 3.1:
|
||||
|
255
src/Spell.py
255
src/Spell.py
@ -50,12 +50,6 @@ LOG = logging.getLogger(".Spell")
|
||||
#-------------------------------------------------------------------------
|
||||
import gtk
|
||||
|
||||
try:
|
||||
import enchant
|
||||
HAVE_ENCHANT = True
|
||||
except ImportError:
|
||||
HAVE_ENCHANT = False
|
||||
|
||||
try:
|
||||
import gtkspell
|
||||
HAVE_GTKSPELL = True
|
||||
@ -78,236 +72,63 @@ import config
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
# All official dictionaries available for GNU Aspell.
|
||||
# ftp://ftp.gnu.org/gnu/aspell/dict/0index.html
|
||||
LANGUAGES = {
|
||||
'af': _('Afrikaans'),
|
||||
'am': _('Amharic'),
|
||||
'ar': _('Arabic'),
|
||||
'az': _('Azerbaijani'),
|
||||
'be': _('Belarusian'),
|
||||
'bg': _('Bulgarian'),
|
||||
'bn': _('Bengali'),
|
||||
'br': _('Breton'),
|
||||
'ca': _('Catalan'),
|
||||
'cs': _('Czech'),
|
||||
'csb': _('Kashubian'),
|
||||
'cy': _('Welsh'),
|
||||
'da': _('Danish'),
|
||||
'de': _('German'),
|
||||
'de-alt': _('German - Old Spelling'),
|
||||
'el': _('Greek'),
|
||||
'en': _('English'),
|
||||
'eo': _('Esperanto'),
|
||||
'es': _('Spanish'),
|
||||
'et': _('Estonian'),
|
||||
'fa': _('Persian'),
|
||||
'fi': _('Finnish'),
|
||||
'fo': _('Faroese'),
|
||||
'fr': _('French'),
|
||||
'fy': _('Frisian'),
|
||||
'ga': _('Irish'),
|
||||
'gd': _('Scottish Gaelic'),
|
||||
'gl': _('Galician'),
|
||||
'gu': _('Gujarati'),
|
||||
'gv': _('Manx Gaelic'),
|
||||
'he': _('Hebrew'),
|
||||
'hi': _('Hindi'),
|
||||
'hil': _('Hiligaynon'),
|
||||
'hr': _('Croatian'),
|
||||
'hsb': _('Upper Sorbian'),
|
||||
'hu': _('Hungarian'),
|
||||
'hy': _('Armenian'),
|
||||
'ia': _('Interlingua'),
|
||||
'id': _('Indonesian'),
|
||||
'is': _('Icelandic'),
|
||||
'it': _('Italian'),
|
||||
'ku': _('Kurdi'),
|
||||
'la': _('Latin'),
|
||||
'lt': _('Lithuanian'),
|
||||
'lv': _('Latvian'),
|
||||
'mg': _('Malagasy'),
|
||||
'mi': _('Maori'),
|
||||
'mk': _('Macedonian'),
|
||||
'mn': _('Mongolian'),
|
||||
'mr': _('Marathi'),
|
||||
'ms': _('Malay'),
|
||||
'mt': _('Maltese'),
|
||||
'nb': _('Norwegian Bokmal'),
|
||||
'nds': _('Low Saxon'),
|
||||
'nl': _('Dutch'),
|
||||
'nn': _('Norwegian Nynorsk'),
|
||||
'ny': _('Chichewa'),
|
||||
'or': _('Oriya'),
|
||||
'pa': _('Punjabi'),
|
||||
'pl': _('Polish'),
|
||||
'pt': _('Portuguese'),
|
||||
'pt_BR': _('Brazilian Portuguese'),
|
||||
'pt_PT': _('Portuguese'),
|
||||
'qu': _('Quechua'),
|
||||
'ro': _('Romanian'),
|
||||
'ru': _('Russian'),
|
||||
'rw': _('Kinyarwanda'),
|
||||
'sc': _('Sardinian'),
|
||||
'sk': _('Slovak'),
|
||||
'sl': _('Slovenian'),
|
||||
'sr': _('Serbian'),
|
||||
'sv': _('Swedish'),
|
||||
'sw': _('Swahili'),
|
||||
'ta': _('Tamil'),
|
||||
'te': _('Telugu'),
|
||||
'tet': _('Tetum'),
|
||||
'tl': _('Tagalog'),
|
||||
'tn': _('Setswana'),
|
||||
'tr': _('Turkish'),
|
||||
'uk': _('Ukrainian'),
|
||||
'uz': _('Uzbek'),
|
||||
'vi': _('Vietnamese'),
|
||||
'wa': _('Walloon'),
|
||||
'yi': _('Yiddish'),
|
||||
'zu': _('Zulu'),
|
||||
}
|
||||
|
||||
class Spell(object):
|
||||
"""Attach a gtkspell instance to the passed TextView instance.
|
||||
"""
|
||||
lang = locale.getlocale()[0] or "en"
|
||||
_installed_languages = {'off': _('None')}
|
||||
_spellcheck_options = {'off': _('Off')}
|
||||
|
||||
if HAVE_GTKSPELL:
|
||||
_spellcheck_options['on'] = _('On')
|
||||
|
||||
if HAVE_ENCHANT and HAVE_GTKSPELL:
|
||||
#gtkspell depends on enchant but has no api to query the installed
|
||||
#languages. Hence, we use enchant to do this if available.
|
||||
for language in enchant.list_languages():
|
||||
try:
|
||||
name = LANGUAGES[language]
|
||||
except KeyError:
|
||||
name = language
|
||||
if name == language:
|
||||
parts = name.split('_')
|
||||
if len(parts) == 2:
|
||||
try:
|
||||
name = LANGUAGES[parts[0]]
|
||||
name += ': ' + parts[1]
|
||||
except KeyError:
|
||||
pass
|
||||
_installed_languages[language] = " ".join(name.split('_'))
|
||||
|
||||
elif not HAVE_ENCHANT and HAVE_GTKSPELL:
|
||||
# if lang is None, default to en:
|
||||
tested = False
|
||||
#we try a hack to get the locale language.
|
||||
for (lang_code, lang_name) in LANGUAGES.items():
|
||||
# if this lang is the current locale:
|
||||
if (lang == lang_code):
|
||||
tested = True
|
||||
# if it is english, we know it works:
|
||||
if lang == "en":
|
||||
_installed_languages[lang] = lang_name
|
||||
print _("Warning: spelling checker language limited to "
|
||||
"locale 'en'; install pyenchant/python-enchant "
|
||||
"for better options.")
|
||||
elif locale.getlocale()[1] == "UTF8":
|
||||
# Only worked with UTF8 versions of language.
|
||||
# But, we need to test it:
|
||||
try:
|
||||
#work around gtkspell bug with tv
|
||||
tv = gtk.TextView()
|
||||
gtkspell.Spell(tv).set_language(lang_code)
|
||||
_installed_languages[lang_code] = lang_name
|
||||
print _("Warning: spelling checker language limited to "
|
||||
"locale '%s'; install pyenchant/python-enchant "
|
||||
"for better options.") % lang
|
||||
except:
|
||||
# FIXME: this does not work anymore since 10/2008!!!
|
||||
# if pyenchant is installed we can avoid it, otherwise
|
||||
# perhaps future gtkspell3 will offer a solution.
|
||||
print _("Warning: spelling checker disabled; "
|
||||
"install pyenchant/python-enchant to enable.")
|
||||
# if we matched, we're done looking
|
||||
break
|
||||
if not tested:
|
||||
# if we didn't see a match on lang, then there is no spell check
|
||||
print _("Warning: spelling checker disabled; "
|
||||
"install pyenchant/python-enchant to enable.")
|
||||
|
||||
def __init__(self, textview):
|
||||
self.textview = textview
|
||||
|
||||
if self.lang and config.get('behavior.spellcheck'):
|
||||
# if LANG is not a correct key (pt_BR or pt_PT),
|
||||
# try only the language part of LANG
|
||||
if self.lang not in self._installed_languages:
|
||||
self.lang = self.lang.split('_')[0]
|
||||
# if this still doesn't work we fall back to 'off'
|
||||
if self.lang not in self._installed_languages:
|
||||
self.lang = 'off'
|
||||
if HAVE_GTKSPELL and config.get('behavior.spellcheck'):
|
||||
self.spellcheck = 'on'
|
||||
else:
|
||||
self.lang = 'off'
|
||||
self.spellcheck = 'off'
|
||||
|
||||
self._active_language = 'off'
|
||||
self.__real_set_active_language(self.lang)
|
||||
self._active_spellcheck = 'off'
|
||||
self.__real_set_active_spellcheck(self.spellcheck)
|
||||
|
||||
# Private
|
||||
|
||||
def __real_set_active_language(self, lang_code):
|
||||
"""Set the active language by it's code."""
|
||||
if self._active_language == 'off':
|
||||
if lang_code == 'off':
|
||||
def __real_set_active_spellcheck(self, spellcheck_code):
|
||||
"""Set active spellcheck by its code."""
|
||||
if self._active_spellcheck == 'off':
|
||||
if spellcheck_code == 'off':
|
||||
return
|
||||
else:
|
||||
gtkspell_spell = gtkspell.Spell(self.textview)
|
||||
try:
|
||||
gtkspell_spell = gtkspell.Spell(self.textview)
|
||||
self._active_spellcheck = spellcheck_code
|
||||
except:
|
||||
# attaching the spellchecker will fail if
|
||||
# the language does not exist
|
||||
# and presumably if there is no dictionary
|
||||
pass
|
||||
else:
|
||||
gtkspell_spell = gtkspell.get_from_text_view(self.textview)
|
||||
if lang_code == 'off':
|
||||
gtkspell_spell.detach()
|
||||
self._active_language = lang_code
|
||||
if spellcheck_code == 'on':
|
||||
return
|
||||
try:
|
||||
gtkspell_spell.set_language(lang_code)
|
||||
self._active_language = lang_code
|
||||
except RuntimeError:
|
||||
#This catches error with old gtkspell versions that generate
|
||||
#this exception if dict cannot be loaded.
|
||||
gtkspell_spell.detach()
|
||||
self._active_language = 'off'
|
||||
|
||||
else:
|
||||
gtkspell_spell = gtkspell.get_from_text_view(self.textview)
|
||||
gtkspell_spell.detach()
|
||||
self._active_spellcheck = spellcheck_code
|
||||
|
||||
# Public API
|
||||
|
||||
def get_all_languages(self):
|
||||
"""Get the list of installed language names."""
|
||||
langs = self._installed_languages.values()
|
||||
langs.sort(sort_languages)
|
||||
return langs
|
||||
def get_all_spellchecks(self):
|
||||
"""Get the list of installed spellcheck names."""
|
||||
return self._spellcheck_options.values()
|
||||
|
||||
def set_active_language(self, language):
|
||||
"""Set active language by it's name."""
|
||||
for code, name in self._installed_languages.items():
|
||||
if name == language:
|
||||
self.__real_set_active_language(code)
|
||||
def set_active_spellcheck(self, spellcheck):
|
||||
"""Set active spellcheck by it's name."""
|
||||
for code, name in self._spellcheck_options.items():
|
||||
if name == spellcheck:
|
||||
self.__real_set_active_spellcheck(code)
|
||||
return
|
||||
|
||||
def get_active_language(self):
|
||||
"""Get the name of the active language."""
|
||||
return self._installed_languages[self._active_language]
|
||||
def get_active_spellcheck(self):
|
||||
"""Get the name of the active spellcheck."""
|
||||
return self._spellcheck_options[self._active_spellcheck]
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# sort_languages
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def sort_languages(lang_a, lang_b):
|
||||
"""Put language names in alphabetical order.
|
||||
|
||||
Except 'None', which should be always the first.
|
||||
|
||||
"""
|
||||
if lang_a == _('None'):
|
||||
return -1
|
||||
if lang_b == _('None'):
|
||||
return 1
|
||||
if lang_a < lang_b:
|
||||
return -1
|
||||
if lang_a > lang_b:
|
||||
return 1
|
||||
return 0
|
||||
|
@ -359,12 +359,12 @@ class StyledTextEditor(gtk.TextView):
|
||||
"""Signal handler.
|
||||
|
||||
Insert extra menuitems:
|
||||
1. Insert language selector submenu for spell checking.
|
||||
1. Insert spellcheck selector submenu for spell checking.
|
||||
2. Insert extra menus depending on ULR match result.
|
||||
|
||||
"""
|
||||
# spell checker submenu
|
||||
spell_menu = gtk.MenuItem(_('Spell'))
|
||||
spell_menu = gtk.MenuItem(_('Spellcheck'))
|
||||
spell_menu.set_submenu(self._create_spell_menu())
|
||||
spell_menu.show_all()
|
||||
menu.prepend(spell_menu)
|
||||
@ -548,22 +548,22 @@ class StyledTextEditor(gtk.TextView):
|
||||
"[a-z0-9-]*(\\.[a-z0-9][a-z0-9-]*)+", MAIL)
|
||||
|
||||
def _create_spell_menu(self):
|
||||
"""Create a menu with all the installed languages.
|
||||
"""Create a menu with all the installed spellchecks.
|
||||
|
||||
It is called each time the popup menu is opened. Each language
|
||||
forms a radio menu item, and the selected language is set as active.
|
||||
It is called each time the popup menu is opened. Each spellcheck
|
||||
forms a radio menu item, and the selected spellcheck is set as active.
|
||||
|
||||
@returns: menu containing all the installed languages.
|
||||
@returns: menu containing all the installed spellchecks.
|
||||
@returntype: gtk.Menu
|
||||
|
||||
"""
|
||||
active_language = self.spellcheck.get_active_language()
|
||||
active_spellcheck = self.spellcheck.get_active_spellcheck()
|
||||
|
||||
menu = gtk.Menu()
|
||||
group = None
|
||||
for lang in self.spellcheck.get_all_languages():
|
||||
for lang in self.spellcheck.get_all_spellchecks():
|
||||
menuitem = gtk.RadioMenuItem(group, lang)
|
||||
menuitem.set_active(lang == active_language)
|
||||
menuitem.set_active(lang == active_spellcheck)
|
||||
menuitem.connect('activate', self._spell_change_cb, lang)
|
||||
menu.append(menuitem)
|
||||
|
||||
@ -705,9 +705,9 @@ class StyledTextEditor(gtk.TextView):
|
||||
action.set_value(style_value)
|
||||
self._internal_style_change = False
|
||||
|
||||
def _spell_change_cb(self, menuitem, language):
|
||||
"""Set spell checker language according to user selection."""
|
||||
self.spellcheck.set_active_language(language)
|
||||
def _spell_change_cb(self, menuitem, spellcheck):
|
||||
"""Set spell checker spellcheck according to user selection."""
|
||||
self.spellcheck.set_active_spellcheck(spellcheck)
|
||||
|
||||
def _open_url_cb(self, menuitem, url, flavor):
|
||||
"""Open the URL in a browser."""
|
||||
|
Loading…
Reference in New Issue
Block a user