diff --git a/ChangeLog b/ChangeLog index 4c7f041c8..cabd5d332 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2007-07-17 Zsolt Foldvari + * src/Spell.py: + * src/Editors/_EditNote.py: + * src/glade/gramps.glade: + Improved spell check support. + 2007-07-16 Alex Roitman * ChangeLog.old: Add pre-2007 logs. * ChangeLog: Remove pre-2007 logs (move to ChangeLog.old). diff --git a/src/Editors/_EditNote.py b/src/Editors/_EditNote.py index 61aac9c90..04f7e4a53 100644 --- a/src/Editors/_EditNote.py +++ b/src/Editors/_EditNote.py @@ -230,7 +230,24 @@ class EditNote(EditPrimary): self.text.connect('populate-popup', self.on_textview_populate_popup) - self.spellcheck = Spell.Spell(self.text) + # setup spell checking interface + spellcheck = Spell.Spell(self.text) + liststore = gtk.ListStore(gobject.TYPE_STRING) + cell = gtk.CellRendererText() + lang_selector = self.top.get_widget('spell') + lang_selector.set_model(liststore) + lang_selector.pack_start(cell, True) + lang_selector.add_attribute(cell, 'text', 0) + act_lang = spellcheck.get_active_language() + idx = 0 + for lang in spellcheck.get_all_languages(): + lang_selector.append_text(lang) + if lang == act_lang: + act_idx = idx + idx = idx + 1 + lang_selector.set_active(act_idx) + lang_selector.connect('changed', self.on_spell_change, spellcheck) + #lang_selector.set_sensitive(Config.get(Config.SPELLCHECK)) # create a formatting toolbar if not self.dbstate.db.readonly: @@ -242,7 +259,7 @@ class EditNote(EditPrimary): toolbar = uimanager.get_widget('/ToolBar') toolbar.set_style(gtk.TOOLBAR_ICONS) vbox = self.top.get_widget('container') - vbox.pack_start(toolbar, False) + vbox.pack_start(toolbar) # setup initial values for textview and buffer if self.obj: @@ -327,6 +344,11 @@ class EditNote(EditPrimary): open_menu.show() menu.prepend(open_menu) + def on_spell_change(self, combobox, spell): + """Set spell checker language according to user selection.""" + lang = combobox.get_active_text() + spell.set_active_language(lang) + def open_url_cb(self, menuitem, url, flavor): if not url: return diff --git a/src/Spell.py b/src/Spell.py index 5165689b0..6210c2b38 100644 --- a/src/Spell.py +++ b/src/Spell.py @@ -27,50 +27,141 @@ present, we default to no spell checking. """ +#------------------------------------------------------------------------- +# +# Python classes +# +#------------------------------------------------------------------------- +from gettext import gettext as _ +import locale + +#------------------------------------------------------------------------- +# +# Set up logging +# +#------------------------------------------------------------------------- +import logging +log = logging.getLogger(".Spell") + +#------------------------------------------------------------------------- +# +# GTK libraries +# +#------------------------------------------------------------------------- +import gtk +try: + import gtkspell + HAVE_GTKSPELL = True +except ImportError: + log.warn(_("Spelling checker is not installed")) + HAVE_GTKSPELL = False + +#------------------------------------------------------------------------- +# +# GRAMPS classes +# +#------------------------------------------------------------------------- import Config -from gettext import gettext as _ - -#----------------------------------------------------------- +#------------------------------------------------------------------------- # -# Attempt to instantiate a gtkspell instance to check for -# any errors. If it succeeds, set a success flag so that we -# know to use the spelling check in the future +# Constants # -#------------------------------------------------------------ +#------------------------------------------------------------------------- +LANGUAGES = { + 'da': _('Danish'), + 'de': _('German'), + 'en': _('English'), + 'es': _('Spanish'), + 'fi': _('Finnish'), + 'fr': _('French'), + 'it': _('Italian'), + 'la': _('Latin'), + 'nl': _('Dutch'), + 'nn': _('Norwegian'), + 'ru': _('Russian'), + 'sv': _('Swedish'), +} -success = False -try: - import gtk - import gtkspell - import locale - - lang = locale.getlocale()[0] - if lang == None: - print _("Spelling checker cannot be used without language set.") - print _("Set your locale appropriately to use spelling checker.") - else: - gtkspell.Spell(gtk.TextView()).set_language(lang) - success = True -except ImportError, msg: - print _("Spelling checker is not installed") -except TypeError,msg: - print "Spell.py: ", msg -except RuntimeError,msg: - print "Spell.py: ", msg -except SystemError,msg: - msg = _("Spelling checker is not available for %s") % lang - print "Spell.py: %s" % msg - -#----------------------------------------------------------- -# -# Spell - if the initial test succeeded, attach a gtkspell -# instance to the passed TextView instance -# -#------------------------------------------------------------ class Spell: + """Attach a gtkspell instance to the passed TextView instance. + """ + _LANG = locale.getlocale()[0] + + _installed_languages = {'off': _('None')} - def __init__(self,obj): - if success and Config.get(Config.SPELLCHECK): - self.spell = gtkspell.Spell(obj) - self.spell.set_language(locale.getlocale()[0]) + if HAVE_GTKSPELL: + for lang_code, lang_name in LANGUAGES.items(): + try: + gtkspell.Spell(gtk.TextView()).set_language(lang_code) + _installed_languages[lang_code] = lang_name + except RuntimeError: + pass + + def __init__(self, textview): + self.textview = textview + + if self._LANG and Config.get(Config.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.keys(): + 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.keys(): + self._LANG = 'off' + else: + self._LANG = 'off' + + self._active_language = 'off' + self._real_set_active_language(self._LANG) + + 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': + return + else: + gtkspell_spell = gtkspell.Spell(self.textview) + else: + gtkspell_spell = gtkspell.get_from_text_view(self.textview) + if lang_code == 'off': + gtkspell_spell.detach() + self._active_language = lang_code + return + + gtkspell_spell.set_language(lang_code) + self._active_language = lang_code + + def _sort_languages(self, 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 + + + def get_all_languages(self): + """Get the list of installed language names.""" + langs = self._installed_languages.values() + langs.sort(self._sort_languages) + return langs + + 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) + return + + def get_active_language(self): + """Get the name of the active language.""" + return self._installed_languages[self._active_language] diff --git a/src/glade/gramps.glade b/src/glade/gramps.glade index 2f67c5034..f64ffd646 100644 --- a/src/glade/gramps.glade +++ b/src/glade/gramps.glade @@ -15201,7 +15201,7 @@ Very High 0 - + 6 True False @@ -15243,6 +15243,75 @@ Very High GTK_PACK_END + + + + True + False + 6 + + + + + + + + True + False + 6 + + + + True + Spelling: + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + True + + + 0 + True + True + + + + + 0 + False + True + GTK_PACK_END + + + + + 0 + False + True + + 0