3866 3976 3977: Two 'spell' entries; remove Enchant dependency (patch by Tim Lyons)

svn: r17563
This commit is contained in:
Jérôme Rapinat 2011-05-26 08:05:04 +00:00
parent cbe4a1805f
commit ff638d041b
3 changed files with 54 additions and 233 deletions

8
README
View File

@ -33,10 +33,8 @@ The following packages are *STRONGLY RECOMMENDED* to be installed:
Obtain it from: http://tilloy.net/dev/pyexiv2/download.html Obtain it from: http://tilloy.net/dev/pyexiv2/download.html
The following packages are optional The following packages are optional
python gtkspell python gtkspell Enable spell checking in the notes, gtkspell contains the
python enchant Enable spell checking in the notes, gtkspell contains the libraries.
libraries, enchant is needed to query the installed languages.
Both must be present for spell check to activate
ttf-freefont More font support in the reports 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 It can be in python-gnome2-extras or python-gtkhtml2
depending on distributions. depending on distributions.
No longer needed in 3.3:
python-enchant Enchant
No longer needed in 3.2: No longer needed in 3.2:
python glade bindings python glade bindings
No longer needed in 3.1: No longer needed in 3.1:

View File

@ -50,12 +50,6 @@ LOG = logging.getLogger(".Spell")
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import gtk import gtk
try:
import enchant
HAVE_ENCHANT = True
except ImportError:
HAVE_ENCHANT = False
try: try:
import gtkspell import gtkspell
HAVE_GTKSPELL = True 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): class Spell(object):
"""Attach a gtkspell instance to the passed TextView instance. """Attach a gtkspell instance to the passed TextView instance.
""" """
lang = locale.getlocale()[0] or "en" _spellcheck_options = {'off': _('Off')}
_installed_languages = {'off': _('None')}
if HAVE_ENCHANT and HAVE_GTKSPELL: if HAVE_GTKSPELL:
#gtkspell depends on enchant but has no api to query the installed _spellcheck_options['on'] = _('On')
#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): def __init__(self, textview):
self.textview = textview self.textview = textview
if self.lang and config.get('behavior.spellcheck'): if HAVE_GTKSPELL and config.get('behavior.spellcheck'):
# if LANG is not a correct key (pt_BR or pt_PT), self.spellcheck = 'on'
# 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'
else: else:
self.lang = 'off' self.spellcheck = 'off'
self._active_language = 'off' self._active_spellcheck = 'off'
self.__real_set_active_language(self.lang) self.__real_set_active_spellcheck(self.spellcheck)
# Private # Private
def __real_set_active_language(self, lang_code): def __real_set_active_spellcheck(self, spellcheck_code):
"""Set the active language by it's code.""" """Set active spellcheck by its code."""
if self._active_language == 'off': if self._active_spellcheck == 'off':
if lang_code == 'off': if spellcheck_code == 'off':
return return
else: 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: else:
gtkspell_spell = gtkspell.get_from_text_view(self.textview) if spellcheck_code == 'on':
if lang_code == 'off':
gtkspell_spell.detach()
self._active_language = lang_code
return return
try: else:
gtkspell_spell.set_language(lang_code) gtkspell_spell = gtkspell.get_from_text_view(self.textview)
self._active_language = lang_code gtkspell_spell.detach()
except RuntimeError: self._active_spellcheck = spellcheck_code
#This catches error with old gtkspell versions that generate
#this exception if dict cannot be loaded.
gtkspell_spell.detach()
self._active_language = 'off'
# Public API # Public API
def get_all_languages(self): def get_all_spellchecks(self):
"""Get the list of installed language names.""" """Get the list of installed spellcheck names."""
langs = self._installed_languages.values() return self._spellcheck_options.values()
langs.sort(sort_languages)
return langs
def set_active_language(self, language): def set_active_spellcheck(self, spellcheck):
"""Set active language by it's name.""" """Set active spellcheck by it's name."""
for code, name in self._installed_languages.items(): for code, name in self._spellcheck_options.items():
if name == language: if name == spellcheck:
self.__real_set_active_language(code) self.__real_set_active_spellcheck(code)
return return
def get_active_language(self): def get_active_spellcheck(self):
"""Get the name of the active language.""" """Get the name of the active spellcheck."""
return self._installed_languages[self._active_language] 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

View File

@ -359,12 +359,12 @@ class StyledTextEditor(gtk.TextView):
"""Signal handler. """Signal handler.
Insert extra menuitems: 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. 2. Insert extra menus depending on ULR match result.
""" """
# spell checker submenu # spell checker submenu
spell_menu = gtk.MenuItem(_('Spell')) spell_menu = gtk.MenuItem(_('Spellcheck'))
spell_menu.set_submenu(self._create_spell_menu()) spell_menu.set_submenu(self._create_spell_menu())
spell_menu.show_all() spell_menu.show_all()
menu.prepend(spell_menu) menu.prepend(spell_menu)
@ -548,22 +548,22 @@ class StyledTextEditor(gtk.TextView):
"[a-z0-9-]*(\\.[a-z0-9][a-z0-9-]*)+", MAIL) "[a-z0-9-]*(\\.[a-z0-9][a-z0-9-]*)+", MAIL)
def _create_spell_menu(self): 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 It is called each time the popup menu is opened. Each spellcheck
forms a radio menu item, and the selected language is set as active. 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 @returntype: gtk.Menu
""" """
active_language = self.spellcheck.get_active_language() active_spellcheck = self.spellcheck.get_active_spellcheck()
menu = gtk.Menu() menu = gtk.Menu()
group = None group = None
for lang in self.spellcheck.get_all_languages(): for lang in self.spellcheck.get_all_spellchecks():
menuitem = gtk.RadioMenuItem(group, lang) 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) menuitem.connect('activate', self._spell_change_cb, lang)
menu.append(menuitem) menu.append(menuitem)
@ -705,9 +705,9 @@ class StyledTextEditor(gtk.TextView):
action.set_value(style_value) action.set_value(style_value)
self._internal_style_change = False self._internal_style_change = False
def _spell_change_cb(self, menuitem, language): def _spell_change_cb(self, menuitem, spellcheck):
"""Set spell checker language according to user selection.""" """Set spell checker spellcheck according to user selection."""
self.spellcheck.set_active_language(language) self.spellcheck.set_active_spellcheck(spellcheck)
def _open_url_cb(self, menuitem, url, flavor): def _open_url_cb(self, menuitem, url, flavor):
"""Open the URL in a browser.""" """Open the URL in a browser."""