diff options
Diffstat (limited to 'kcontrol/locale/kcmlocale.cpp')
-rw-r--r-- | kcontrol/locale/kcmlocale.cpp | 473 |
1 files changed, 473 insertions, 0 deletions
diff --git a/kcontrol/locale/kcmlocale.cpp b/kcontrol/locale/kcmlocale.cpp new file mode 100644 index 000000000..5d746212e --- /dev/null +++ b/kcontrol/locale/kcmlocale.cpp @@ -0,0 +1,473 @@ +/* + * locale.cpp + * + * Copyright (c) 1998 Matthias Hoelzer (hoelzer@physik.uni-wuerzburg.de) + * Copyright (c) 1999 Preston Brown <pbrown@kde.org> + * Copyright (c) 1999-2003 Hans Petter Bieker <bieker@kde.org> + * + * Requires the Qt widget libraries, available at no cost at + * http://www.troll.no/ + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <qhbox.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qlistbox.h> +#include <qpushbutton.h> +#include <qtooltip.h> +#include <qwhatsthis.h> + +#include <kdebug.h> +#include <kdialog.h> +#include <kiconloader.h> +#include <klanguagebutton.h> +#include <ksimpleconfig.h> +#include <kstandarddirs.h> + +#include "kcmlocale.h" +#include "kcmlocale.moc" +#include "toplevel.h" + +KLocaleConfig::KLocaleConfig(KLocale *locale, + QWidget *parent, const char *name) + : QWidget (parent, name), + m_locale(locale) +{ + QGridLayout *lay = new QGridLayout(this, 3, 3, + KDialog::marginHint(), + KDialog::spacingHint()); + + m_labCountry = new QLabel(this, I18N_NOOP("Country or region:")); + m_comboCountry = new KLanguageButton( this ); + m_labCountry->setBuddy(m_comboCountry); + connect( m_comboCountry, SIGNAL(activated(const QString &)), + this, SLOT(changedCountry(const QString &)) ); + + m_labLang = new QLabel(this, I18N_NOOP("Languages:")); + m_labLang->setAlignment( AlignTop ); + + m_languages = new QListBox(this); + connect(m_languages, SIGNAL(selectionChanged()), + SLOT(slotCheckButtons())); + + QWidget * vb = new QWidget(this); + QVBoxLayout * boxlay = new QVBoxLayout(vb, 0, KDialog::spacingHint()); + m_addLanguage = new KLanguageButton(QString::null, vb, I18N_NOOP("Add Language")); + boxlay->add(m_addLanguage); + connect(m_addLanguage, SIGNAL(activated(const QString &)), + SLOT(slotAddLanguage(const QString &))); + m_removeLanguage = new QPushButton(vb, I18N_NOOP("Remove Language")); + m_upButton = new QPushButton(vb, I18N_NOOP("Move Up")); + m_downButton = new QPushButton(vb, I18N_NOOP("Move Down")); + boxlay->add(m_removeLanguage); + boxlay->add(m_upButton); + boxlay->add(m_downButton); + connect(m_removeLanguage, SIGNAL(clicked()), + SLOT(slotRemoveLanguage())); + connect(m_upButton, SIGNAL(clicked()), + SLOT(slotLanguageUp())); + connect(m_downButton, SIGNAL(clicked()), + SLOT(slotLanguageDown())); + boxlay->insertStretch(-1); + + // #### HPB: This should be implemented for KDE 3 + // new QLabel(this, I18N_NOOP("Encoding:")); + //QComboBox * cb = new QComboBox( this ); + //cb->insertStringList( KGlobal::charsets()->descriptiveEncodingNames() ); + + lay->addMultiCellWidget(m_labCountry, 0, 0, 0, 1); + lay->addWidget(m_comboCountry, 0, 2); + lay->addWidget(m_labLang, 1, 0); + lay->addWidget(m_languages, 1, 1); + lay->addWidget(vb, 1, 2); + + lay->setRowStretch(2, 5); + + lay->setColStretch(1, 1); + lay->setColStretch(2, 1); +} + +void KLocaleConfig::slotAddLanguage(const QString & code) +{ + QStringList languageList = m_locale->languageList(); + + int pos = m_languages->currentItem(); + if ( pos < 0 ) + pos = 0; + + // If it's already in list, just move it (delete the old, then insert a new) + int oldPos = languageList.findIndex( code ); + if ( oldPos != -1 ) + languageList.remove( languageList.at(oldPos) ); + + if ( oldPos != -1 && oldPos < pos ) + --pos; + + QStringList::Iterator it = languageList.at( pos ); + + languageList.insert( it, code ); + + m_locale->setLanguage( languageList ); + + emit localeChanged(); + if ( pos == 0 ) + emit languageChanged(); +} + +void KLocaleConfig::slotRemoveLanguage() +{ + QStringList languageList = m_locale->languageList(); + int pos = m_languages->currentItem(); + + QStringList::Iterator it = languageList.at( pos ); + + if ( it != languageList.end() ) + { + languageList.remove( it ); + + m_locale->setLanguage( languageList ); + + emit localeChanged(); + if ( pos == 0 ) + emit languageChanged(); + } +} + +void KLocaleConfig::slotLanguageUp() +{ + QStringList languageList = m_locale->languageList(); + int pos = m_languages->currentItem(); + + QStringList::Iterator it1 = languageList.at( pos - 1 ); + QStringList::Iterator it2 = languageList.at( pos ); + + if ( it1 != languageList.end() && it2 != languageList.end() ) + { + QString str = *it1; + *it1 = *it2; + *it2 = str; + + m_locale->setLanguage( languageList ); + + emit localeChanged(); + if ( pos == 1 ) // at the lang before the top + emit languageChanged(); + } +} + +void KLocaleConfig::slotLanguageDown() +{ + QStringList languageList = m_locale->languageList(); + int pos = m_languages->currentItem(); + + QStringList::Iterator it1 = languageList.at( pos ); + QStringList::Iterator it2 = languageList.at( pos + 1 ); + + if ( it1 != languageList.end() && it2 != languageList.end() ) + { + QString str = *it1; + *it1 = *it2; + *it2 = str; + + m_locale->setLanguage( languageList ); + + emit localeChanged(); + if ( pos == 0 ) // at the top + emit languageChanged(); + } +} + +void KLocaleConfig::loadLanguageList() +{ + // temperary use of our locale as the global locale + KLocale *lsave = KGlobal::_locale; + KGlobal::_locale = m_locale; + + // clear the list + m_addLanguage->clear(); + + QStringList first = languageList(); + + QStringList prilang; + // add the primary languages for the country to the list + for ( QStringList::ConstIterator it = first.begin(); + it != first.end(); + ++it ) + { + QString str = locate("locale", QString::fromLatin1("%1/entry.desktop") + .arg(*it)); + if (!str.isNull()) + prilang << str; + } + + // add all languages to the list + QStringList alllang = KGlobal::dirs()->findAllResources("locale", + QString::fromLatin1("*/entry.desktop"), + false, true); + QStringList langlist = prilang; + if (langlist.count() > 0) + langlist << QString::null; // separator + langlist += alllang; + + int menu_index = -2; + QString submenu; // we are working on this menu + for ( QStringList::ConstIterator it = langlist.begin(); + it != langlist.end(); ++it ) + { + if ((*it).isNull()) + { + m_addLanguage->insertSeparator(); + submenu = QString::fromLatin1("other"); + m_addLanguage->insertSubmenu(m_locale->translate("Other"), + submenu, QString::null, -1); + menu_index = -2; // first entries should _not_ be sorted + continue; + } + KSimpleConfig entry(*it); + entry.setGroup("KCM Locale"); + QString name = entry.readEntry("Name", + m_locale->translate("without name")); + + QString tag = *it; + int index = tag.findRev('/'); + tag = tag.left(index); + index = tag.findRev('/'); + tag = tag.mid(index + 1); + m_addLanguage->insertItem(name, tag, submenu, menu_index); + } + + // restore the old global locale + KGlobal::_locale = lsave; +} + +void KLocaleConfig::loadCountryList() +{ + // temperary use of our locale as the global locale + KLocale *lsave = KGlobal::_locale; + KGlobal::_locale = m_locale; + + QString sub = QString::fromLatin1("l10n/"); + + // clear the list + m_comboCountry->clear(); + + QStringList regionlist = KGlobal::dirs()->findAllResources("locale", + sub + QString::fromLatin1("*.desktop"), + false, true ); + + for ( QStringList::ConstIterator it = regionlist.begin(); + it != regionlist.end(); + ++it ) + { + QString tag = *it; + int index; + + index = tag.findRev('/'); + if (index != -1) + tag = tag.mid(index + 1); + + index = tag.findRev('.'); + if (index != -1) + tag.truncate(index); + + KSimpleConfig entry(*it); + entry.setGroup("KCM Locale"); + QString name = entry.readEntry("Name", + m_locale->translate("without name")); + + QString map( locate( "locale", + QString::fromLatin1( "l10n/%1.png" ) + .arg(tag) ) ); + QIconSet icon; + if ( !map.isNull() ) + icon = KGlobal::iconLoader()->loadIconSet(map, KIcon::Small); + m_comboCountry->insertSubmenu( icon, name, tag, sub, -2 ); + } + + // add all languages to the list + QStringList countrylist = KGlobal::dirs()->findAllResources + ("locale", sub + QString::fromLatin1("*/entry.desktop"), false, true); + + for ( QStringList::ConstIterator it = countrylist.begin(); + it != countrylist.end(); ++it ) + { + KSimpleConfig entry(*it); + entry.setGroup("KCM Locale"); + QString name = entry.readEntry("Name", + m_locale->translate("without name")); + QString submenu = entry.readEntry("Region"); + + QString tag = *it; + int index = tag.findRev('/'); + tag.truncate(index); + index = tag.findRev('/'); + tag = tag.mid(index + 1); + int menu_index = submenu.isEmpty() ? -1 : -2; + + QString flag( locate( "locale", + QString::fromLatin1( "l10n/%1/flag.png" ) + .arg(tag) ) ); + QIconSet icon( KGlobal::iconLoader()->loadIconSet(flag, KIcon::Small) ); + m_comboCountry->insertItem( icon, name, tag, submenu, menu_index ); + } + + // restore the old global locale + KGlobal::_locale = lsave; +} + +void KLocaleConfig::readLocale(const QString &path, QString &name, + const QString &sub) const +{ + // temperary use of our locale as the global locale + KLocale *lsave = KGlobal::_locale; + KGlobal::_locale = m_locale; + + // read the name + QString filepath = QString::fromLatin1("%1%2/entry.desktop") + .arg(sub) + .arg(path); + + KSimpleConfig entry(locate("locale", filepath)); + entry.setGroup("KCM Locale"); + name = entry.readEntry("Name"); + + // restore the old global locale + KGlobal::_locale = lsave; +} + +void KLocaleConfig::save() +{ + KConfigBase *config = KGlobal::config(); + + config->setGroup("Locale"); + + config->writeEntry("Country", m_locale->country(), true, true); + if ( m_locale->languageList().isEmpty() ) + config->writeEntry("Language", QString::fromLatin1(""), true, true); + else + config->writeEntry("Language", + m_locale->languageList(), ':', true, true); + + config->sync(); +} + +void KLocaleConfig::slotCheckButtons() +{ + m_removeLanguage->setEnabled( m_languages->currentItem() != -1 ); + m_upButton->setEnabled( m_languages->currentItem() > 0 ); + m_downButton->setEnabled( m_languages->currentItem() != -1 && + m_languages->currentItem() < (signed)(m_languages->count() - 1) ); +} + +void KLocaleConfig::slotLocaleChanged() +{ + loadLanguageList(); + loadCountryList(); + + // update language widget + m_languages->clear(); + QStringList languageList = m_locale->languageList(); + for ( QStringList::Iterator it = languageList.begin(); + it != languageList.end(); + ++it ) + { + QString name; + readLocale(*it, name, QString::null); + + m_languages->insertItem(name); + } + slotCheckButtons(); + + m_comboCountry->setCurrentItem( m_locale->country() ); +} + +void KLocaleConfig::slotTranslate() +{ + kdDebug() << "slotTranslate()" << endl; + + QToolTip::add(m_comboCountry, m_locale->translate + ( "This is where you live. KDE will use the defaults for " + "this country or region.") ); + QToolTip::add(m_addLanguage, m_locale->translate + ( "This will add a language to the list. If the language is already " + "in the list, the old one will be moved instead." ) ); + + QToolTip::add(m_removeLanguage, m_locale->translate + ( "This will remove the highlighted language from the list." ) ); + + QToolTip::add(m_languages, m_locale->translate + ( "KDE programs will be displayed in the first available language in " + "this list.\nIf none of the languages are available, US English " + "will be used.") ); + + QString str; + + str = m_locale->translate + ( "Here you can choose your country or region. The settings " + "for languages, numbers etc. will automatically switch to the " + "corresponding values." ); + QWhatsThis::add( m_labCountry, str ); + QWhatsThis::add( m_comboCountry, str ); + + str = m_locale->translate + ( "Here you can choose the languages that will be used by KDE. If the " + "first language in the list is not available, the second will be used, " + "etc. If only US English is available, no translations " + "have been installed. You can get translation packages for many " + "languages from the place you got KDE from.<p>" + "Note that some applications may not be translated to your languages; " + "in this case, they will automatically fall back to US English." ); + QWhatsThis::add( m_labLang, str ); + QWhatsThis::add( m_languages, str ); + QWhatsThis::add( m_addLanguage, str ); + QWhatsThis::add( m_removeLanguage, str ); +} + +QStringList KLocaleConfig::languageList() const +{ + QString fileName = locate("locale", + QString::fromLatin1("l10n/%1/entry.desktop") + .arg(m_locale->country())); + + KSimpleConfig entry(fileName); + entry.setGroup("KCM Locale"); + + return entry.readListEntry("Languages"); +} + +void KLocaleConfig::changedCountry(const QString & code) +{ + m_locale->setCountry(code); + + // change to the preferred languages in that country, installed only + QStringList languages = languageList(); + QStringList newLanguageList; + for ( QStringList::Iterator it = languages.begin(); + it != languages.end(); + ++it ) + { + QString name; + readLocale(*it, name, QString::null); + + if (!name.isEmpty()) + newLanguageList += *it; + } + m_locale->setLanguage( newLanguageList ); + + emit localeChanged(); + emit languageChanged(); +} |