diff options
Diffstat (limited to 'kcontrol/locale/localetime.cpp')
-rw-r--r-- | kcontrol/locale/localetime.cpp | 556 |
1 files changed, 556 insertions, 0 deletions
diff --git a/kcontrol/locale/localetime.cpp b/kcontrol/locale/localetime.cpp new file mode 100644 index 000000000..ea077ac89 --- /dev/null +++ b/kcontrol/locale/localetime.cpp @@ -0,0 +1,556 @@ +/* + * localetime.cpp + * + * 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 <qcheckbox.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qwhatsthis.h> +#include <qcombobox.h> +#include <qvaluevector.h> + +#include <kdialog.h> +#include <ksimpleconfig.h> +#include <kstandarddirs.h> +#include <kdebug.h> +#include <kcalendarsystem.h> + +#include "toplevel.h" +#include "localetime.h" +#include "localetime.moc" + +class StringPair +{ +public: + QChar storeName; + QString userName; + + static StringPair find( const QValueList <StringPair> &list, const QChar &c) + { + for ( QValueList<StringPair>::ConstIterator it = list.begin(); + it != list.end(); + ++it ) + if ((*it).storeName==c) return (*it); + + StringPair r; + return r; + } + +}; + +/* Sort the string pairs with qHeapSort in the order we want + ( relative to the userName value and with "MESCORTO" before "MES" ) + */ +bool operator< (const StringPair &p1, const StringPair &p2) +{ + return ! (p1.userName<p2.userName); +} + +bool operator<= (const StringPair &p1, const StringPair &p2) +{ + return ! (p1.userName<=p2.userName); +} + +bool operator> (const StringPair &p1, const StringPair &p2) +{ + return ! (p1.userName>p2.userName); +} + +bool operator>= (const StringPair &p1, const StringPair &p2) +{ + return ! (p1.userName>=p2.userName); +} + +StringPair KLocaleConfigTime::buildStringPair(const QChar &c, const QString &s) const +{ + StringPair pair; + pair.storeName=c; + pair.userName=s; + return pair; +} + +QValueList<StringPair> KLocaleConfigTime::timeMap() const +{ + QValueList < StringPair > list; + list+=buildStringPair('H',m_locale->translate("HH")); + list+=buildStringPair('k',m_locale->translate("hH")); + list+=buildStringPair('I',m_locale->translate("PH")); + list+=buildStringPair('l',m_locale->translate("pH")); + list+=buildStringPair('M',m_locale->translate("Minute", "MM")); + list+=buildStringPair('S',m_locale->translate("SS")); + list+=buildStringPair('p',m_locale->translate("AMPM")); + + qHeapSort( list ); + + return list; +} + +QValueList <StringPair> KLocaleConfigTime::dateMap() const +{ + QValueList < StringPair > list; + list+=buildStringPair('Y',m_locale->translate("YYYY")); + list+=buildStringPair('y',m_locale->translate("YY")); + list+=buildStringPair('n',m_locale->translate("mM")); + list+=buildStringPair('m',m_locale->translate("Month", "MM")); + list+=buildStringPair('b',m_locale->translate("SHORTMONTH")); + list+=buildStringPair('B',m_locale->translate("MONTH")); + list+=buildStringPair('e',m_locale->translate("dD")); + list+=buildStringPair('d',m_locale->translate("DD")); + list+=buildStringPair('a',m_locale->translate("SHORTWEEKDAY")); + list+=buildStringPair('A',m_locale->translate("WEEKDAY")); + + qHeapSort( list ); + + return list; +} + +QString KLocaleConfigTime::userToStore(const QValueList<StringPair> & list, + const QString & userFormat) const +{ + QString result; + + for ( uint pos = 0; pos < userFormat.length(); ++pos ) + { + bool bFound = false; + for ( QValueList<StringPair>::ConstIterator it = list.begin(); + it != list.end() && !bFound; + ++it ) + { + QString s = (*it).userName; + + if ( userFormat.mid( pos, s.length() ) == s ) + { + result += '%'; + result += (*it).storeName; + + pos += s.length() - 1; + + bFound = true; + } + } + + if ( !bFound ) + { + QChar c = userFormat.at( pos ); + if ( c == '%' ) + result += c; + + result += c; + } + } + + return result; +} + +QString KLocaleConfigTime::storeToUser(const QValueList<StringPair> & list, + const QString & storeFormat) const +{ + QString result; + + bool escaped = false; + for ( uint pos = 0; pos < storeFormat.length(); ++pos ) + { + QChar c = storeFormat.at(pos); + if ( escaped ) + { + StringPair it = StringPair::find( list, c ); + if ( !it.userName.isEmpty() ) + result += it.userName; + else + result += c; + + escaped = false; + } + else if ( c == '%' ) + escaped = true; + else + result += c; + } + + return result; +} + +KLocaleConfigTime::KLocaleConfigTime(KLocale *_locale, + QWidget *parent, const char*name) + : QWidget(parent, name), + m_locale(_locale) +{ + // Time + QGridLayout *lay = new QGridLayout(this, 7, 2, + KDialog::marginHint(), + KDialog::spacingHint()); + lay->setAutoAdd(TRUE); + + m_labCalendarSystem = new QLabel(this, I18N_NOOP("Calendar system:")); + m_comboCalendarSystem = new QComboBox(false, this); + connect(m_comboCalendarSystem, SIGNAL(activated(int)), + this, SLOT(slotCalendarSystemChanged(int))); + QStringList tmpCalendars; + tmpCalendars << QString::null << QString::null; + m_comboCalendarSystem->insertStringList(tmpCalendars); + + m_labTimeFmt = new QLabel(this, I18N_NOOP("Time format:")); + m_comboTimeFmt = new QComboBox(true, this); + //m_edTimeFmt = m_comboTimeFmt->lineEdit(); + //m_edTimeFmt = new QLineEdit(this); + connect( m_comboTimeFmt, SIGNAL( textChanged(const QString &) ), + this, SLOT( slotTimeFmtChanged(const QString &) ) ); + + m_labDateFmt = new QLabel(this, I18N_NOOP("Date format:")); + m_comboDateFmt = new QComboBox(true, this); + connect( m_comboDateFmt, SIGNAL( textChanged(const QString &) ), + this, SLOT( slotDateFmtChanged(const QString &) ) ); + + m_labDateFmtShort = new QLabel(this, I18N_NOOP("Short date format:")); + m_comboDateFmtShort = new QComboBox(true, this); + connect( m_comboDateFmtShort, SIGNAL( textChanged(const QString &) ), + this, SLOT( slotDateFmtShortChanged(const QString &) ) ); + + m_labWeekStartDay = new QLabel(this, I18N_NOOP("First day of the week:")); + m_comboWeekStartDay = new QComboBox(false, this); + connect (m_comboWeekStartDay, SIGNAL(activated(int)), + this, SLOT(slotWeekStartDayChanged(int))); + + updateWeekDayNames(); + + m_chDateMonthNamePossessive = new QCheckBox(this, I18N_NOOP("Use declined form of month name")); + connect( m_chDateMonthNamePossessive, SIGNAL( clicked() ), + SLOT( slotDateMonthNamePossChanged() ) ); + + lay->setColStretch(1, 1); +} + +KLocaleConfigTime::~KLocaleConfigTime() +{ +} + +void KLocaleConfigTime::save() +{ + // temperary use of our locale as the global locale + KLocale *lsave = KGlobal::_locale; + KGlobal::_locale = m_locale; + + KConfig *config = KGlobal::config(); + KConfigGroupSaver saver(config, "Locale"); + + KSimpleConfig ent(locate("locale", + QString::fromLatin1("l10n/%1/entry.desktop") + .arg(m_locale->country())), true); + ent.setGroup("KCM Locale"); + + QString str; + + str = ent.readEntry("CalendarSystem", QString::fromLatin1("gregorian")); + config->deleteEntry("CalendarSystem", false, true); + if (str != m_locale->calendarType()) + config->writeEntry("CalendarSystem", m_locale->calendarType(), true, true); + + str = ent.readEntry("TimeFormat", QString::fromLatin1("%H:%M:%S")); + config->deleteEntry("TimeFormat", false, true); + if (str != m_locale->timeFormat()) + config->writeEntry("TimeFormat", m_locale->timeFormat(), true, true); + + str = ent.readEntry("DateFormat", QString::fromLatin1("%A %d %B %Y")); + config->deleteEntry("DateFormat", false, true); + if (str != m_locale->dateFormat()) + config->writeEntry("DateFormat", m_locale->dateFormat(), true, true); + + str = ent.readEntry("DateFormatShort", QString::fromLatin1("%Y-%m-%d")); + config->deleteEntry("DateFormatShort", false, true); + if (str != m_locale->dateFormatShort()) + config->writeEntry("DateFormatShort", + m_locale->dateFormatShort(), true, true); + + int firstDay; + firstDay = ent.readNumEntry("WeekStartDay", 1); + config->deleteEntry("WeekStartDay", false, true); + if (firstDay != m_locale->weekStartDay()) + config->writeEntry("WeekStartDay", m_locale->weekStartDay(), true, true); + + if ( m_locale->nounDeclension() ) + { + bool b; + b = ent.readBoolEntry("DateMonthNamePossessive", false); + config->deleteEntry("DateMonthNamePossessive", false, true); + if (b != m_locale->dateMonthNamePossessive()) + config->writeEntry("DateMonthNamePossessive", + m_locale->dateMonthNamePossessive(), true, true); + } + + config->sync(); + + // restore the old global locale + KGlobal::_locale = lsave; +} + +void KLocaleConfigTime::showEvent( QShowEvent *e ) +{ + // This option makes sense only for languages where nouns are declined + if ( !m_locale->nounDeclension() ) + m_chDateMonthNamePossessive->hide(); + QWidget::showEvent( e ); +} + +void KLocaleConfigTime::slotCalendarSystemChanged(int calendarSystem) +{ + kdDebug() << "CalendarSystem: " << calendarSystem << endl; + + typedef QValueVector<QString> CalendarVector; + CalendarVector calendars(4); + calendars[0] = "gregorian"; + calendars[1] = "hijri"; + calendars[2] = "hebrew"; + calendars[3] = "jalali"; + + QString calendarType; + bool ok; + calendarType = calendars.at(calendarSystem, &ok); + if ( !ok ) + calendarType = calendars.first(); + + m_locale->setCalendar(calendarType); + + updateWeekDayNames(); + emit localeChanged(); +} + +void KLocaleConfigTime::slotLocaleChanged() +{ + typedef QValueVector<QString> CalendarVector; + CalendarVector calendars(4); + calendars[0] = "gregorian"; + calendars[1] = "hijri"; + calendars[2] = "hebrew"; + calendars[3] = "jalali"; + + QString calendarType = m_locale->calendarType(); + int calendarSystem = 0; + + CalendarVector::iterator it = qFind(calendars.begin(), calendars.end(), +calendarType); + if ( it != calendars.end() ) + calendarSystem = it - calendars.begin(); + + kdDebug() << "calSys: " << calendarSystem << ": " << calendarType << endl; + m_comboCalendarSystem->setCurrentItem( calendarSystem ); + + // m_edTimeFmt->setText( m_locale->timeFormat() ); + m_comboTimeFmt->setEditText( storeToUser( timeMap(), + m_locale->timeFormat() ) ); + // m_edDateFmt->setText( m_locale->dateFormat() ); + m_comboDateFmt->setEditText( storeToUser( dateMap(), + m_locale->dateFormat() ) ); + //m_edDateFmtShort->setText( m_locale->dateFormatShort() ); + m_comboDateFmtShort->setEditText( storeToUser( dateMap(), + m_locale->dateFormatShort() ) ); + m_comboWeekStartDay->setCurrentItem( m_locale->weekStartDay() - 1 ); + + if ( m_locale->nounDeclension() ) + m_chDateMonthNamePossessive->setChecked( m_locale->dateMonthNamePossessive() ); + + kdDebug(173) << "converting: " << m_locale->timeFormat() << endl; + kdDebug(173) << storeToUser(timeMap(), + m_locale->timeFormat()) << endl; + kdDebug(173) << userToStore(timeMap(), + QString::fromLatin1("HH:MM:SS AMPM test")) << endl; + +} + +void KLocaleConfigTime::slotTimeFmtChanged(const QString &t) +{ + // m_locale->setTimeFormat(t); + m_locale->setTimeFormat( userToStore( timeMap(), t ) ); + + emit localeChanged(); +} + +void KLocaleConfigTime::slotDateFmtChanged(const QString &t) +{ + // m_locale->setDateFormat(t); + m_locale->setDateFormat( userToStore( dateMap(), t ) ); + emit localeChanged(); +} + +void KLocaleConfigTime::slotDateFmtShortChanged(const QString &t) +{ + //m_locale->setDateFormatShort(t); + m_locale->setDateFormatShort( userToStore( dateMap(), t ) ); + emit localeChanged(); +} + +void KLocaleConfigTime::slotWeekStartDayChanged(int firstDay) { + kdDebug(173) << k_funcinfo << "first day is now: " << firstDay << endl; + m_locale->setWeekStartDay(m_comboWeekStartDay->currentItem() + 1); + emit localeChanged(); +} + +void KLocaleConfigTime::slotDateMonthNamePossChanged() +{ + if (m_locale->nounDeclension()) + { + m_locale->setDateMonthNamePossessive(m_chDateMonthNamePossessive->isChecked()); + emit localeChanged(); + } +} + +void KLocaleConfigTime::slotTranslate() +{ + QString str; + + QString sep = QString::fromLatin1("\n"); + + QString old; + + // clear() and insertStringList also changes the current item, so + // we better use save and restore here.. + old = m_comboTimeFmt->currentText(); + m_comboTimeFmt->clear(); + str = i18n("some reasonable time formats for the language", + "HH:MM:SS\n" + "pH:MM:SS AMPM"); + m_comboTimeFmt->insertStringList(QStringList::split(sep, str)); + m_comboTimeFmt->setEditText(old); + + old = m_comboDateFmt->currentText(); + m_comboDateFmt->clear(); + str = i18n("some reasonable date formats for the language", + "WEEKDAY MONTH dD YYYY\n" + "SHORTWEEKDAY MONTH dD YYYY"); + m_comboDateFmt->insertStringList(QStringList::split(sep, str)); + m_comboDateFmt->setEditText(old); + + old = m_comboDateFmtShort->currentText(); + m_comboDateFmtShort->clear(); + str = i18n("some reasonable short date formats for the language", + "YYYY-MM-DD\n" + "dD.mM.YYYY\n" + "DD.MM.YYYY"); + m_comboDateFmtShort->insertStringList(QStringList::split(sep, str)); + m_comboDateFmtShort->setEditText(old); + + updateWeekDayNames(); + + while ( m_comboCalendarSystem->count() < 4 ) + m_comboCalendarSystem->insertItem(QString::null); + m_comboCalendarSystem->changeItem + (m_locale->translate("Calendar System Gregorian", "Gregorian"), 0); + m_comboCalendarSystem->changeItem + (m_locale->translate("Calendar System Hijri", "Hijri"), 1); + m_comboCalendarSystem->changeItem + (m_locale->translate("Calendar System Hebrew", "Hebrew"), 2); + m_comboCalendarSystem->changeItem + (m_locale->translate("Calendar System Jalali", "Jalali"), 3); + + str = m_locale->translate + ("<p>The text in this textbox will be used to format " + "time strings. The sequences below will be replaced:</p>" + "<table>" + "<tr><td><b>HH</b></td><td>The hour as a decimal number using a 24-hour " + "clock (00-23).</td></tr>" + "<tr><td><b>hH</b></td><td>The hour (24-hour clock) as a decimal number " + "(0-23).</td></tr>" + "<tr><td><b>PH</b></td><td>The hour as a decimal number using a 12-hour " + "clock (01-12).</td></tr>" + "<tr><td><b>pH</b></td><td>The hour (12-hour clock) as a decimal number " + "(1-12).</td></tr>" + "<tr><td><b>MM</b></td><td>The minutes as a decimal number (00-59)." + "</td><tr>" + "<tr><td><b>SS</b></td><td>The seconds as a decimal number (00-59)." + "</td></tr>" + "<tr><td><b>AMPM</b></td><td>Either \"am\" or \"pm\" according to the " + "given time value. Noon is treated as \"pm\" and midnight as \"am\"." + "</td></tr>" + "</table>"); + QWhatsThis::add( m_labTimeFmt, str ); + QWhatsThis::add( m_comboTimeFmt, str ); + + QString datecodes = m_locale->translate( + "<table>" + "<tr><td><b>YYYY</b></td><td>The year with century as a decimal number." + "</td></tr>" + "<tr><td><b>YY</b></td><td>The year without century as a decimal number " + "(00-99).</td></tr>" + "<tr><td><b>MM</b></td><td>The month as a decimal number (01-12)." + "</td></tr>" + "<tr><td><b>mM</b></td><td>The month as a decimal number (1-12).</td></tr>" + "<tr><td><b>SHORTMONTH</b></td><td>The first three characters of the month name. " + "</td></tr>" + "<tr><td><b>MONTH</b></td><td>The full month name.</td></tr>" + "<tr><td><b>DD</b></td><td>The day of month as a decimal number (01-31)." + "</td></tr>" + "<tr><td><b>dD</b></td><td>The day of month as a decimal number (1-31)." + "</td></tr>" + "<tr><td><b>SHORTWEEKDAY</b></td><td>The first three characters of the weekday name." + "</td></tr>" + "<tr><td><b>WEEKDAY</b></td><td>The full weekday name.</td></tr>" + "</table>"); + + str = m_locale->translate + ( "<p>The text in this textbox will be used to format long " + "dates. The sequences below will be replaced:</p>") + datecodes; + QWhatsThis::add( m_labDateFmt, str ); + QWhatsThis::add( m_comboDateFmt, str ); + + str = m_locale->translate + ( "<p>The text in this textbox will be used to format short " + "dates. For instance, this is used when listing files. " + "The sequences below will be replaced:</p>") + datecodes; + QWhatsThis::add( m_labDateFmtShort, str ); + QWhatsThis::add( m_comboDateFmtShort, str ); + + str = m_locale->translate + ("<p>This option determines which day will be considered as " + "the first one of the week.</p>"); + QWhatsThis::add( m_comboWeekStartDay, str ); + + if ( m_locale->nounDeclension() ) + { + str = m_locale->translate + ("<p>This option determines whether possessive form of month " + "names should be used in dates.</p>"); + QWhatsThis::add( m_chDateMonthNamePossessive, str ); + } +} + +void KLocaleConfigTime::updateWeekDayNames() +{ + const KCalendarSystem * calendar = m_locale->calendar(); + + for ( int i = 1; ; ++i ) + { + QString str = calendar->weekDayName(i); + bool outsideComboList = m_comboWeekStartDay->count() < i; + + if ( str.isNull() ) + { + if ( outsideComboList ) + break; + else + m_comboWeekStartDay->removeItem(i - 1); + } + + if ( outsideComboList ) + m_comboWeekStartDay->insertItem(str, i - 1); + else + m_comboWeekStartDay->changeItem(str, i - 1); + } +} |