KDEUI
klanguagebutton.cpp
Go to the documentation of this file.
00001 /* 00002 * Copyright (c) 1999-2003 Hans Petter Bieker <bieker@kde.org> 00003 * (c) 2007 David Jarvie <software@astrojar.org.uk> 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Library General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2 of the License, or (at your option) any later version. 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 "klanguagebutton.moc" 00022 00023 #include <QtGui/QMenu> 00024 #include <QtGui/QLayout> 00025 #include <QtGui/QPushButton> 00026 #include <QtGui/QMenuItem> 00027 00028 #include <klocale.h> 00029 #include <kstandarddirs.h> 00030 #include <kdebug.h> 00031 #include <kconfiggroup.h> 00032 00033 static void checkInsertPos( QMenu *popup, const QString &str, int &index ) 00034 { 00035 if ( index != -1 ) 00036 return; 00037 00038 int a = 0; 00039 const QList<QAction*> actions = popup->actions(); 00040 int b = actions.count(); 00041 00042 while ( a < b ) 00043 { 00044 int w = ( a + b ) / 2; 00045 QAction *ac = actions[ w ]; 00046 int j = str.localeAwareCompare( ac->text() ); 00047 if ( j > 0 ) 00048 a = w + 1; 00049 else 00050 b = w; 00051 } 00052 00053 index = a; // it doesn't really matter ... a == b here. 00054 00055 Q_ASSERT( a == b ); 00056 } 00057 00058 class KLanguageButtonPrivate 00059 { 00060 public: 00061 KLanguageButtonPrivate( KLanguageButton *parent); 00062 ~KLanguageButtonPrivate() { delete button; delete popup; } 00063 void setCurrentItem( QAction* ); 00064 void clear(); 00065 QAction *findAction(const QString &data) const; 00066 00067 QPushButton *button; 00068 QStringList ids; 00069 QMenu *popup; 00070 QString current; 00071 const KLocale *locale; 00072 bool staticText : 1; 00073 bool showCodes : 1; 00074 }; 00075 00076 KLanguageButton::KLanguageButton( QWidget * parent ) 00077 : QWidget( parent ), 00078 d( new KLanguageButtonPrivate(this) ) 00079 { 00080 } 00081 00082 KLanguageButton::KLanguageButton( const QString & text, QWidget * parent ) 00083 : QWidget( parent ), 00084 d( new KLanguageButtonPrivate(this) ) 00085 { 00086 setText(text); 00087 } 00088 00089 KLanguageButtonPrivate::KLanguageButtonPrivate( KLanguageButton *parent ) 00090 : button(new QPushButton(parent)), 00091 popup(new QMenu(parent)), 00092 locale(0), 00093 staticText(false), 00094 showCodes(false) 00095 { 00096 QHBoxLayout *layout = new QHBoxLayout( parent ); 00097 layout->setMargin(0); 00098 layout->addWidget( button ); 00099 00100 parent->setFocusProxy( button ); 00101 parent->setFocusPolicy( button->focusPolicy() ); 00102 00103 button->setMenu( popup ); 00104 00105 QObject::connect( popup, SIGNAL(triggered(QAction*)), parent, SLOT(slotTriggered(QAction*)) ); 00106 QObject::connect( popup, SIGNAL(hovered(QAction*)), parent, SLOT(slotHovered(QAction*)) ); 00107 } 00108 00109 KLanguageButton::~KLanguageButton() 00110 { 00111 delete d; 00112 } 00113 00114 void KLanguageButton::setText(const QString & text) 00115 { 00116 d->staticText = true; 00117 d->button->setText(text); 00118 } 00119 00120 void KLanguageButton::setLocale( const KLocale *locale ) 00121 { 00122 d->locale = locale; 00123 } 00124 00125 void KLanguageButton::showLanguageCodes( bool show ) 00126 { 00127 d->showCodes = show; 00128 } 00129 00130 void KLanguageButton::insertLanguage( const QString &languageCode, const QString &name, int index ) 00131 { 00132 QString text; 00133 bool showCodes = d->showCodes; 00134 if (name.isEmpty()) 00135 { 00136 text = languageCode; 00137 const KLocale *locale = d->locale ? d->locale : KGlobal::locale(); 00138 if (locale) 00139 text = locale->languageCodeToName(languageCode); 00140 else 00141 showCodes = false; 00142 } 00143 else 00144 text = name; 00145 if (showCodes) 00146 text += QLatin1String( " (" ) + languageCode + QLatin1Char(')'); 00147 00148 checkInsertPos( d->popup, text, index ); 00149 QAction *a = new QAction(QIcon(), text, this); 00150 a->setData(languageCode); 00151 if ( index >= 0 && index < d->popup->actions().count()-1) 00152 d->popup->insertAction(d->popup->actions()[index], a); 00153 else 00154 d->popup->addAction(a); 00155 d->ids.append(languageCode); 00156 } 00157 00158 void KLanguageButton::insertSeparator( int index ) 00159 { 00160 if ( index >= 0 && index < d->popup->actions().count()-1) 00161 d->popup->insertSeparator(d->popup->actions()[index]); 00162 else 00163 d->popup->addSeparator(); 00164 } 00165 00166 void KLanguageButton::loadAllLanguages() 00167 { 00168 QStringList langlist = KGlobal::dirs()->findAllResources("locale", 00169 QString::fromLatin1("*/entry.desktop")); 00170 langlist.sort(); 00171 for (int i = 0, count = langlist.count(); i < count; ++i) 00172 { 00173 QString fpath = langlist[i].left(langlist[i].length() - 14); 00174 QString code = fpath.mid(fpath.lastIndexOf('/') + 1); 00175 KConfig entry(langlist[i], KConfig::SimpleConfig); 00176 KConfigGroup group(&entry, "KCM Locale"); 00177 QString name = group.readEntry("Name", i18n("without name")); 00178 insertLanguage(code, name); 00179 } 00180 00181 const KLocale *locale = d->locale ? d->locale : KGlobal::locale(); 00182 setCurrentItem(locale ? locale->language() : KLocale::defaultLanguage()); 00183 } 00184 00185 void KLanguageButton::slotTriggered( QAction *a ) 00186 { 00187 //kDebug() << "slotTriggered" << index; 00188 if (!a) 00189 return; 00190 00191 d->setCurrentItem( a ); 00192 00193 // Forward event from popup menu as if it was emitted from this widget: 00194 emit activated( d->current ); 00195 } 00196 00197 void KLanguageButton::slotHovered( QAction *a ) 00198 { 00199 //kDebug() << "slotHovered" << index; 00200 00201 emit highlighted(a->data().toString()); 00202 } 00203 00204 int KLanguageButton::count() const 00205 { 00206 return d->ids.count(); 00207 } 00208 00209 void KLanguageButton::clear() 00210 { 00211 d->clear(); 00212 } 00213 00214 void KLanguageButtonPrivate::clear() 00215 { 00216 ids.clear(); 00217 popup->clear(); 00218 00219 if ( !staticText ) { 00220 button->setText( QString() ); 00221 } 00222 } 00223 00224 bool KLanguageButton::contains( const QString &languageCode ) const 00225 { 00226 return d->ids.contains( languageCode ); 00227 } 00228 00229 QString KLanguageButton::current() const 00230 { 00231 return d->current.isEmpty() ? QLatin1String("en") : d->current; 00232 } 00233 00234 QAction *KLanguageButtonPrivate::findAction(const QString& data) const 00235 { 00236 foreach(QAction *a, popup->actions()) { 00237 if (!a->data().toString().compare(data)) 00238 return a; 00239 } 00240 return 0; 00241 } 00242 00243 void KLanguageButton::setCurrentItem( const QString & languageCode ) 00244 { 00245 if (!d->ids.count()) 00246 return; 00247 QAction *a; 00248 if (d->ids.indexOf(languageCode) < 0) 00249 a = d->findAction(d->ids[0]); 00250 else 00251 a = d->findAction(languageCode); 00252 if (a) 00253 d->setCurrentItem(a); 00254 } 00255 00256 void KLanguageButtonPrivate::setCurrentItem( QAction *a ) 00257 { 00258 if (!a->data().isValid()) 00259 return; 00260 current = a->data().toString(); 00261 00262 if ( !staticText ) { 00263 button->setText( a->text() ); 00264 } 00265 }
KDE 4.6 API Reference