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
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:

View File

@ -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

View File

@ -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."""