• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

KDEUI

ktimezonewidget.cpp

Go to the documentation of this file.
00001 /*
00002     Copyright (C) 2005, S.R.Haque <srhaque@iee.org>.
00003     Copyright (C) 2009, David Faure <faure@kde.org>
00004     This file is part of the KDE project
00005 
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Library General Public
00008     License version 2, as published by the Free Software Foundation.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public License
00016     along with this library; see the file COPYING.LIB.  If not, write to
00017     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018     Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "ktimezonewidget.h"
00022 
00023 #include <QtCore/QFile>
00024 #include <QtGui/QPixmap>
00025 
00026 #include <kdebug.h>
00027 #include <klocale.h>
00028 #include <kstandarddirs.h>
00029 #include <ksystemtimezone.h>
00030 #include <ktimezone.h>
00031 
00032 class KTimeZoneWidget::Private
00033 {
00034 public:
00035     Private() : itemsCheckable(false), singleSelection(true) {}
00036 
00037     enum Columns
00038     {
00039         CityColumn = 0,
00040         RegionColumn,
00041         CommentColumn
00042     };
00043 
00044     enum Roles
00045     {
00046         ZoneRole = Qt::UserRole + 0xF3A3CB1
00047     };
00048 
00049     bool itemsCheckable;
00050     bool singleSelection;
00051 };
00052 
00053 #ifndef KDE_USE_FINAL
00054 static bool localeLessThan (const QString &a, const QString &b)
00055 {
00056     return QString::localeAwareCompare(a, b) < 0;
00057 }
00058 #endif
00059 
00060 KTimeZoneWidget::KTimeZoneWidget( QWidget *parent, KTimeZones *db )
00061   : QTreeWidget( parent ),
00062     d(new KTimeZoneWidget::Private)
00063 {
00064   // If the user did not provide a timezone database, we'll use the system default.
00065   setRootIsDecorated(false);
00066   setHeaderLabels( QStringList() << i18nc("Define an area in the time zone, like a town area", "Area" ) << i18nc( "Time zone", "Region" ) << i18n( "Comment" ) );
00067 
00068   // Collect zones by localized city names, so that they can be sorted properly.
00069   QStringList cities;
00070   QHash<QString, KTimeZone> zonesByCity;
00071 
00072   if (!db) {
00073       db = KSystemTimeZones::timeZones();
00074 
00075       // add UTC to the defaults default
00076       KTimeZone utc = KTimeZone::utc();
00077       cities.append(utc.name());
00078       zonesByCity.insert(utc.name(), utc);
00079   }
00080 
00081   const KTimeZones::ZoneMap zones = db->zones();
00082   for ( KTimeZones::ZoneMap::ConstIterator it = zones.begin(); it != zones.end(); ++it ) {
00083     const KTimeZone zone = it.value();
00084     const QString continentCity = displayName( zone );
00085     const int separator = continentCity.lastIndexOf('/');
00086     // Make up the localized key that will be used for sorting.
00087     // Example: i18n(Asia/Tokyo) -> key = "i18n(Tokyo)|i18n(Asia)|Asia/Tokyo"
00088     // The zone name is appended to ensure unicity even with equal translations (#174918)
00089     const QString key = continentCity.mid(separator+1) + '|'
00090                    + continentCity.left(separator) + '|' + zone.name();
00091     cities.append( key );
00092     zonesByCity.insert( key, zone );
00093   }
00094   qSort( cities.begin(), cities.end(), localeLessThan );
00095 
00096   foreach ( const QString &key, cities ) {
00097     const KTimeZone zone = zonesByCity.value(key);
00098     const QString tzName = zone.name();
00099     QString comment = zone.comment();
00100 
00101     if ( !comment.isEmpty() )
00102       comment = i18n( comment.toUtf8() );
00103 
00104     // Convert:
00105     //
00106     //  "Europe/London", "GB" -> "London", "Europe/GB".
00107     //  "UTC",           ""   -> "UTC",    "".
00108     QStringList continentCity = displayName( zone ).split( '/' );
00109 
00110     QTreeWidgetItem *listItem = new QTreeWidgetItem( this );
00111     listItem->setText( Private::CityColumn, continentCity[ continentCity.count() - 1 ] );
00112     QString countryName = KGlobal::locale()->countryCodeToName( zone.countryCode() );
00113     if ( countryName.isEmpty() ) {
00114       continentCity[ continentCity.count() - 1 ] = zone.countryCode();
00115     } else {
00116       continentCity[ continentCity.count() - 1 ] = countryName;
00117     }
00118 
00119     listItem->setText( Private::RegionColumn, continentCity.join( QChar('/') ) );
00120     listItem->setText( Private::CommentColumn, comment );
00121     listItem->setData( Private::CityColumn, Private::ZoneRole, tzName ); // store complete path in custom role
00122 
00123     // Locate the flag from /l10n/%1/flag.png.
00124     QString flag = KStandardDirs::locate( "locale", QString( "l10n/%1/flag.png" ).arg( zone.countryCode().toLower() ) );
00125     if ( QFile::exists( flag ) )
00126       listItem->setIcon( Private::RegionColumn, QPixmap( flag ) );
00127   }
00128 }
00129 
00130 KTimeZoneWidget::~KTimeZoneWidget()
00131 {
00132     delete d;
00133 }
00134 
00135 void KTimeZoneWidget::setItemsCheckable(bool enable)
00136 {
00137     d->itemsCheckable = enable;
00138     const int count = topLevelItemCount();
00139     for (int row = 0; row < count; ++row) {
00140         QTreeWidgetItem* listItem = topLevelItem(row);
00141         listItem->setCheckState(Private::CityColumn, Qt::Unchecked);
00142     }
00143     QTreeWidget::setSelectionMode(QAbstractItemView::NoSelection);
00144 }
00145 
00146 bool KTimeZoneWidget::itemsCheckable() const
00147 {
00148     return d->itemsCheckable;
00149 }
00150 
00151 QString KTimeZoneWidget::displayName( const KTimeZone &zone )
00152 {
00153     return i18n( zone.name().toUtf8() ).replace( '_', ' ' );
00154 }
00155 
00156 QStringList KTimeZoneWidget::selection() const
00157 {
00158     QStringList selection;
00159 
00160     // Loop through all entries.
00161     // Do not use selectedItems() because it skips hidden items, making it
00162     // impossible to use a KTreeWidgetSearchLine.
00163     // There is no QTreeWidgetItemConstIterator, hence the const_cast :/
00164     QTreeWidgetItemIterator it(const_cast<KTimeZoneWidget*>(this), d->itemsCheckable ? QTreeWidgetItemIterator::Checked : QTreeWidgetItemIterator::Selected);
00165     for (; *it; ++it) {
00166         selection.append( (*it)->data( Private::CityColumn, Private::ZoneRole ).toString() );
00167     }
00168 
00169     return selection;
00170 }
00171 
00172 void KTimeZoneWidget::setSelected( const QString &zone, bool selected )
00173 {
00174     bool found = false;
00175 
00176     // The code was using findItems( zone, Qt::MatchExactly, Private::ZoneColumn )
00177     // previously, but the underlying model only has 3 columns, the "hidden" column
00178     // wasn't available in there.
00179 
00180     if (!d->itemsCheckable) {
00181         // Runtime compatibility for < 4.3 apps, which don't call the setMultiSelection reimplementation.
00182         d->singleSelection = (QTreeWidget::selectionMode() == QAbstractItemView::SingleSelection);
00183     }
00184 
00185     // Loop through all entries.
00186     const int rowCount = model()->rowCount(QModelIndex());
00187     for (int row = 0; row < rowCount; ++row) {
00188         const QModelIndex index = model()->index(row, Private::CityColumn);
00189         const QString tzName = index.data(Private::ZoneRole).toString();
00190         if (tzName == zone) {
00191 
00192             if (d->singleSelection && selected) {
00193                 clearSelection();
00194             }
00195 
00196             if (d->itemsCheckable) {
00197                 QTreeWidgetItem* listItem = itemFromIndex(index);
00198                 listItem->setCheckState(Private::CityColumn, selected ? Qt::Checked : Qt::Unchecked);
00199             } else {
00200                 selectionModel()->select(index, selected ? (QItemSelectionModel::Select | QItemSelectionModel::Rows) : (QItemSelectionModel::Deselect | QItemSelectionModel::Rows));
00201             }
00202 
00203             // Ensure the selected item is visible as appropriate.
00204             scrollTo( index );
00205 
00206             found = true;
00207 
00208             if (d->singleSelection && selected) {
00209                 break;
00210             }
00211         }
00212     }
00213 
00214     if ( !found )
00215         kDebug() << "No such zone: " << zone;
00216 }
00217 
00218 void KTimeZoneWidget::clearSelection()
00219 {
00220     if (d->itemsCheckable) {
00221         // Un-select all items
00222         const int rowCount = model()->rowCount(QModelIndex());
00223         for (int row = 0; row < rowCount; ++row) {
00224             const QModelIndex index = model()->index(row, 0);
00225             QTreeWidgetItem* listItem = itemFromIndex(index);
00226             listItem->setCheckState(Private::CityColumn, Qt::Unchecked);
00227         }
00228     } else {
00229         QTreeWidget::clearSelection();
00230     }
00231 }
00232 
00233 void KTimeZoneWidget::setSelectionMode(QAbstractItemView::SelectionMode mode)
00234 {
00235     d->singleSelection = (mode == QAbstractItemView::SingleSelection);
00236     if (!d->itemsCheckable) {
00237         QTreeWidget::setSelectionMode(mode);
00238     }
00239 }
00240 
00241 QAbstractItemView::SelectionMode KTimeZoneWidget::selectionMode() const
00242 {
00243     if (d->itemsCheckable) {
00244         return d->singleSelection ? QTreeWidget::SingleSelection : QTreeWidget::MultiSelection;
00245     } else {
00246         return QTreeWidget::selectionMode();
00247     }
00248 }
00249 
00250 #include "ktimezonewidget.moc"

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal