2005-08-18 11:28:28 +05:30
|
|
|
#
|
|
|
|
# Gramps - a GTK+/GNOME based genealogy program
|
|
|
|
#
|
2006-05-02 02:41:26 +05:30
|
|
|
# Copyright (C) 2005-2006 Donald N. Allingham
|
2005-08-18 11:28:28 +05:30
|
|
|
#
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program; if not, write to the Free Software
|
|
|
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
#
|
|
|
|
|
|
|
|
# $Id$
|
|
|
|
|
|
|
|
"""
|
|
|
|
Provide an interface to the gtkspell interface. This requires
|
|
|
|
python-gnome-extras package. If the gtkspell package is not
|
|
|
|
present, we default to no spell checking.
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
2007-07-17 19:10:29 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# Python classes
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
2006-04-07 03:32:46 +05:30
|
|
|
from gettext import gettext as _
|
2007-07-17 19:10:29 +05:30
|
|
|
import locale
|
2005-12-06 12:08:09 +05:30
|
|
|
|
2007-07-17 19:10:29 +05:30
|
|
|
#-------------------------------------------------------------------------
|
2005-12-06 12:08:09 +05:30
|
|
|
#
|
2007-07-17 19:10:29 +05:30
|
|
|
# Set up logging
|
2005-12-06 12:08:09 +05:30
|
|
|
#
|
2007-07-17 19:10:29 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
import logging
|
2007-07-23 02:33:52 +05:30
|
|
|
LOG = logging.getLogger(".Spell")
|
2005-12-06 12:08:09 +05:30
|
|
|
|
2007-07-17 19:10:29 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# GTK libraries
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
import gtk
|
2007-09-08 09:50:59 +05:30
|
|
|
|
2009-03-05 17:40:47 +05:30
|
|
|
try:
|
|
|
|
import enchant
|
|
|
|
HAVE_ENCHANT = True
|
|
|
|
except ImportError:
|
|
|
|
HAVE_ENCHANT = False
|
|
|
|
|
2005-12-06 12:08:09 +05:30
|
|
|
try:
|
|
|
|
import gtkspell
|
2007-07-17 19:10:29 +05:30
|
|
|
HAVE_GTKSPELL = True
|
|
|
|
except ImportError:
|
|
|
|
HAVE_GTKSPELL = False
|
2009-03-05 17:40:47 +05:30
|
|
|
|
|
|
|
if not HAVE_GTKSPELL:
|
2007-09-08 10:00:36 +05:30
|
|
|
LOG.warn(_("Spelling checker is not installed"))
|
2005-12-06 12:08:09 +05:30
|
|
|
|
2007-07-17 19:10:29 +05:30
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# GRAMPS classes
|
|
|
|
#
|
|
|
|
#-------------------------------------------------------------------------
|
2009-10-08 06:42:51 +05:30
|
|
|
import config
|
2005-12-06 12:08:09 +05:30
|
|
|
|
2007-07-17 19:10:29 +05:30
|
|
|
#-------------------------------------------------------------------------
|
2005-12-06 12:08:09 +05:30
|
|
|
#
|
2007-07-17 19:10:29 +05:30
|
|
|
# Constants
|
2005-12-06 12:08:09 +05:30
|
|
|
#
|
2007-07-17 19:10:29 +05:30
|
|
|
#-------------------------------------------------------------------------
|
2007-07-18 01:53:48 +05:30
|
|
|
|
|
|
|
# All official dictionaries available for GNU Aspell.
|
|
|
|
# ftp://ftp.gnu.org/gnu/aspell/dict/0index.html
|
2007-07-17 19:10:29 +05:30
|
|
|
LANGUAGES = {
|
2007-07-18 01:53:48 +05:30
|
|
|
'af': _('Afrikaans'),
|
|
|
|
'am': _('Amharic'),
|
|
|
|
'ar': _('Arabic'),
|
|
|
|
'az': _('Azerbaijani'),
|
|
|
|
'be': _('Belarusian'),
|
|
|
|
'bg': _('Bulgarian'),
|
|
|
|
'bn': _('Bengali'),
|
|
|
|
'br': _('Breton'),
|
|
|
|
'ca': _('Catalan'),
|
|
|
|
'cs': _('Czech'),
|
|
|
|
'csb': _('Kashubian'),
|
|
|
|
'cy': _('Welsh'),
|
2007-07-17 19:10:29 +05:30
|
|
|
'da': _('Danish'),
|
|
|
|
'de': _('German'),
|
2007-07-18 01:53:48 +05:30
|
|
|
'de-alt': _('German - Old Spelling'),
|
|
|
|
'el': _('Greek'),
|
2007-07-17 19:10:29 +05:30
|
|
|
'en': _('English'),
|
2007-07-18 01:53:48 +05:30
|
|
|
'eo': _('Esperanto'),
|
2007-07-17 19:10:29 +05:30
|
|
|
'es': _('Spanish'),
|
2007-07-18 01:53:48 +05:30
|
|
|
'et': _('Estonian'),
|
|
|
|
'fa': _('Persian'),
|
2007-07-17 19:10:29 +05:30
|
|
|
'fi': _('Finnish'),
|
2007-07-18 01:53:48 +05:30
|
|
|
'fo': _('Faroese'),
|
2007-07-17 19:10:29 +05:30
|
|
|
'fr': _('French'),
|
2007-07-18 01:53:48 +05:30
|
|
|
'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'),
|
2007-07-17 19:10:29 +05:30
|
|
|
'it': _('Italian'),
|
2007-07-18 01:53:48 +05:30
|
|
|
'ku': _('Kurdi'),
|
2007-07-17 19:10:29 +05:30
|
|
|
'la': _('Latin'),
|
2007-07-18 01:53:48 +05:30
|
|
|
'lt': _('Lithuanian'),
|
|
|
|
'lv': _('Latvian'),
|
|
|
|
'mg': _('Malagasy'),
|
|
|
|
'mi': _('Maori'),
|
|
|
|
'mk': _('Macedonian'),
|
|
|
|
'mn': _('Mongolian'),
|
|
|
|
'mr': _('Marathi'),
|
|
|
|
'ms': _('Malay'),
|
|
|
|
'mt': _('Maltese'),
|
|
|
|
'nb': _('Norwegian Bokmal'),
|
|
|
|
'nds': _('Low Saxon'),
|
2007-07-17 19:10:29 +05:30
|
|
|
'nl': _('Dutch'),
|
2007-07-18 01:53:48 +05:30
|
|
|
'nn': _('Norwegian Nynorsk'),
|
|
|
|
'ny': _('Chichewa'),
|
|
|
|
'or': _('Oriya'),
|
|
|
|
'pa': _('Punjabi'),
|
|
|
|
'pl': _('Polish'),
|
|
|
|
'pt': _('Portuguese'),
|
|
|
|
'pt_BR': _('Brazilian Portuguese'),
|
|
|
|
'pt_PT': _('Portuguese'),
|
|
|
|
'qu': _('Quechua'),
|
|
|
|
'ro': _('Romanian'),
|
2007-07-17 19:10:29 +05:30
|
|
|
'ru': _('Russian'),
|
2007-07-18 01:53:48 +05:30
|
|
|
'rw': _('Kinyarwanda'),
|
|
|
|
'sc': _('Sardinian'),
|
|
|
|
'sk': _('Slovak'),
|
|
|
|
'sl': _('Slovenian'),
|
|
|
|
'sr': _('Serbian'),
|
2007-07-17 19:10:29 +05:30
|
|
|
'sv': _('Swedish'),
|
2007-07-18 01:53:48 +05:30
|
|
|
'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'),
|
2007-07-17 19:10:29 +05:30
|
|
|
}
|
|
|
|
|
2009-05-21 22:49:50 +05:30
|
|
|
class Spell(object):
|
2007-07-17 19:10:29 +05:30
|
|
|
"""Attach a gtkspell instance to the passed TextView instance.
|
|
|
|
"""
|
2007-07-23 02:33:52 +05:30
|
|
|
lang = locale.getlocale()[0]
|
2007-07-17 19:10:29 +05:30
|
|
|
_installed_languages = {'off': _('None')}
|
2009-03-05 17:40:47 +05:30
|
|
|
|
|
|
|
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('_'))
|
2007-07-17 19:10:29 +05:30
|
|
|
|
2009-03-05 17:40:47 +05:30
|
|
|
elif not HAVE_ENCHANT and HAVE_GTKSPELL:
|
2009-11-12 08:28:33 +05:30
|
|
|
# if lang is None, default to en:
|
|
|
|
if lang == None:
|
|
|
|
locale_lang_code = "en"
|
|
|
|
else:
|
|
|
|
locale_lang_code = lang
|
|
|
|
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 (locale_lang_code == lang_code):
|
|
|
|
tested = True
|
|
|
|
# if it is english, we know it works:
|
|
|
|
if locale_lang_code == "en":
|
|
|
|
_installed_languages[locale_lang_code] = lang_name
|
|
|
|
print _("Warning: spelling checker language limited to "
|
|
|
|
"locale '%s'; install pyenchant/python-enchant "
|
|
|
|
"for better options.") % "en"
|
|
|
|
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.")
|
2007-07-17 19:10:29 +05:30
|
|
|
|
|
|
|
def __init__(self, textview):
|
|
|
|
self.textview = textview
|
|
|
|
|
2009-10-08 06:42:51 +05:30
|
|
|
if self.lang and config.get('behavior.spellcheck'):
|
2007-07-17 19:10:29 +05:30
|
|
|
# if LANG is not a correct key (pt_BR or pt_PT),
|
|
|
|
# try only the language part of LANG
|
2009-05-23 00:13:40 +05:30
|
|
|
if self.lang not in self._installed_languages:
|
2007-07-23 02:33:52 +05:30
|
|
|
self.lang = self.lang.split('_')[0]
|
2007-07-17 19:10:29 +05:30
|
|
|
# if this still doesn't work we fall back to 'off'
|
2009-05-23 00:13:40 +05:30
|
|
|
if self.lang not in self._installed_languages:
|
2007-07-23 02:33:52 +05:30
|
|
|
self.lang = 'off'
|
2007-07-17 19:10:29 +05:30
|
|
|
else:
|
2007-07-23 02:33:52 +05:30
|
|
|
self.lang = 'off'
|
2007-07-17 19:10:29 +05:30
|
|
|
|
|
|
|
self._active_language = 'off'
|
2007-07-27 15:54:09 +05:30
|
|
|
self.__real_set_active_language(self.lang)
|
2005-12-06 12:08:09 +05:30
|
|
|
|
2007-07-27 15:54:09 +05:30
|
|
|
# Private
|
|
|
|
|
|
|
|
def __real_set_active_language(self, lang_code):
|
2007-07-17 19:10:29 +05:30
|
|
|
"""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
|
2009-03-08 15:05:52 +05:30
|
|
|
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.
|
2009-03-11 17:23:52 +05:30
|
|
|
gtkspell_spell.detach()
|
2009-03-08 15:05:52 +05:30
|
|
|
self._active_language = 'off'
|
2007-07-27 15:54:09 +05:30
|
|
|
|
|
|
|
# Public API
|
|
|
|
|
2007-07-17 19:10:29 +05:30
|
|
|
def get_all_languages(self):
|
|
|
|
"""Get the list of installed language names."""
|
|
|
|
langs = self._installed_languages.values()
|
2007-09-08 09:50:59 +05:30
|
|
|
langs.sort(sort_languages)
|
2007-07-17 19:10:29 +05:30
|
|
|
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:
|
2007-07-27 15:54:09 +05:30
|
|
|
self.__real_set_active_language(code)
|
2007-07-17 19:10:29 +05:30
|
|
|
return
|
|
|
|
|
|
|
|
def get_active_language(self):
|
|
|
|
"""Get the name of the active language."""
|
|
|
|
return self._installed_languages[self._active_language]
|
2007-07-23 02:33:52 +05:30
|
|
|
|
2007-09-08 09:50:59 +05:30
|
|
|
|
|
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# 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
|