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

KUtils

kcmultidialog.cpp

Go to the documentation of this file.
00001 /*
00002    Copyright (c) 2000 Matthias Elter <elter@kde.org>
00003    Copyright (c) 2003 Daniel Molkentin <molkentin@kde.org>
00004    Copyright (c) 2003,2006 Matthias Kretz <kretz@kde.org>
00005    Copyright (c) 2004 Frans Englich <frans.englich@telia.com>
00006    Copyright (c) 2006 Tobias Koenig <tokoe@kde.org>
00007 
00008    This library is free software; you can redistribute it and/or
00009    modify it under the terms of the GNU Library General Public
00010    License as published by the Free Software Foundation; either
00011    version 2 of the License, or (at your option) any later version.
00012 
00013    This library is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016    Library General Public License for more details.
00017 
00018    You should have received a copy of the GNU Library General Public License
00019    along with this library; see the file COPYING.LIB.  If not, write to
00020    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00021    Boston, MA 02110-1301, USA.
00022 
00023 */
00024 
00025 #include "kcmultidialog.h"
00026 #include "kcmultidialog_p.h"
00027 
00028 #include <QtCore/QStringList>
00029 #include <QtCore/QProcess>
00030 
00031 #include <kauthorized.h>
00032 #include <kguiitem.h>
00033 #include <khbox.h>
00034 #include <kicon.h>
00035 #include <klocale.h>
00036 #include <kpagewidgetmodel.h>
00037 #include <kpushbutton.h>
00038 #include <ktoolinvocation.h>
00039 #include <kdebug.h>
00040 #include <kmessagebox.h>
00041 
00042 #include "auth/kauthaction.h"
00043 
00044 #include "kcolorscheme.h"
00045 
00046 #include "kcmoduleloader.h"
00047 #include "kcmoduleproxy.h"
00048 
00049 bool KCMultiDialogPrivate::resolveChanges(KCModuleProxy *currentProxy)
00050 {
00051     Q_Q(KCMultiDialog);
00052     if( !currentProxy || !currentProxy->changed() ) {
00053         return true;
00054     }
00055 
00056     // Let the user decide
00057     const int queryUser = KMessageBox::warningYesNoCancel(
00058         q,
00059         i18n("The settings of the current module have changed.\n"
00060              "Do you want to apply the changes or discard them?"),
00061         i18n("Apply Settings"),
00062         KStandardGuiItem::apply(),
00063         KStandardGuiItem::discard(),
00064         KStandardGuiItem::cancel());
00065 
00066     switch (queryUser) {
00067         case KMessageBox::Yes:
00068             return moduleSave(currentProxy);
00069 
00070         case KMessageBox::No:
00071             currentProxy->load();
00072             return true;
00073 
00074         case KMessageBox::Cancel:
00075             return false;
00076 
00077         default:
00078             Q_ASSERT(false);
00079             return false;
00080     }
00081 }
00082 
00083 void KCMultiDialogPrivate::_k_slotCurrentPageChanged( KPageWidgetItem *current, KPageWidgetItem *previous )
00084 {
00085     Q_Q(KCMultiDialog);
00086     kDebug(710);
00087 
00088     q->blockSignals(true);
00089     q->setCurrentPage(previous);
00090 
00091     KCModuleProxy *previousModule = 0;
00092     for ( int i = 0; i < modules.count(); ++i ) {
00093         if ( modules[ i ].item == previous ) {
00094             previousModule = modules[ i ].kcm;
00095             break;
00096         }
00097     }
00098 
00099     if( resolveChanges(previousModule) ) {
00100         q->setCurrentPage(current);
00101     }
00102     q->blockSignals(false);
00103 
00104     // We need to get the state of the now active module
00105     _k_clientChanged();
00106 }
00107 
00108 void KCMultiDialogPrivate::_k_clientChanged()
00109 {
00110     Q_Q(KCMultiDialog);
00111     kDebug(710);
00112     // Get the current module
00113     KCModuleProxy *activeModule = 0;
00114     for ( int i = 0; i < modules.count(); ++i ) {
00115         if ( modules[ i ].item == q->currentPage() ) {
00116             activeModule = modules[ i ].kcm;
00117             break;
00118         }
00119     }
00120 
00121     bool change = false;
00122     if (activeModule) {
00123         change = activeModule->changed();
00124 
00125         if (q->button(KDialog::Apply)) {
00126             q->disconnect(q, SIGNAL(applyClicked()), q, SLOT(slotApplyClicked()));
00127             q->disconnect(q->button(KDialog::Apply), SIGNAL(authorized(KAuth::Action*)), q, SLOT(slotApplyClicked()));
00128             q->button(KDialog::Apply)->setEnabled(change);
00129         }
00130 
00131         if (q->button(KDialog::Ok)) {
00132             q->disconnect(q, SIGNAL(okClicked()), q, SLOT(slotOkClicked()));
00133             q->disconnect(q->button(KDialog::Ok), SIGNAL(authorized(KAuth::Action*)), q, SLOT(slotOkClicked()));
00134         }
00135 
00136         if (activeModule->realModule()->needsAuthorization()) {
00137             if (q->button(KDialog::Apply)) {
00138                 q->button(KDialog::Apply)->setAuthAction(activeModule->realModule()->authAction());
00139                 activeModule->realModule()->authAction()->setParentWidget(activeModule->realModule());
00140                 q->connect(q->button(KDialog::Apply), SIGNAL(authorized(KAuth::Action*)), SLOT(slotApplyClicked()));
00141             }
00142 
00143             if (q->button(KDialog::Ok)) {
00144                 q->button(KDialog::Ok)->setAuthAction(activeModule->realModule()->authAction());
00145                 activeModule->realModule()->authAction()->setParentWidget(activeModule->realModule());
00146                 q->connect(q->button(KDialog::Ok), SIGNAL(authorized(KAuth::Action*)), SLOT(slotOkClicked()));
00147             }
00148         } else {
00149             if (q->button(KDialog::Apply)) {
00150                 q->connect(q, SIGNAL(applyClicked()), SLOT(slotApplyClicked()));
00151                 q->button(KDialog::Apply)->setAuthAction(0);
00152             }
00153 
00154             if (q->button(KDialog::Ok)) {
00155                 q->connect(q, SIGNAL(okClicked()), SLOT(slotOkClicked()));
00156                 q->button(KDialog::Ok)->setAuthAction(0);
00157             }
00158         }
00159     }
00160 
00161     if (q->button(KDialog::Reset)) {
00162         q->button(KDialog::Reset)->setEnabled(change);
00163     }
00164 
00165     if (q->button(KDialog::Apply)) {
00166         q->button(KDialog::Apply)->setEnabled(change);
00167     }
00168 
00169     if (activeModule) {
00170         q->enableButton(KDialog::Help,    activeModule->buttons() & KCModule::Help);
00171         q->enableButton(KDialog::Default, activeModule->buttons() & KCModule::Default);
00172     }
00173 }
00174 
00175 void KCMultiDialogPrivate::_k_updateHeader(bool use, const QString &message)
00176 {
00177     Q_Q(KCMultiDialog);
00178     KPageWidgetItem *item = q->currentPage();
00179     KCModuleProxy *kcm = qobject_cast<KCModuleProxy*>(item->widget());
00180 
00181     if (use) {
00182         item->setHeader( "<b>"+kcm->moduleInfo().comment() + "</b><br><i>" +
00183                          message + "</i>" );
00184         item->setIcon( KIcon( kcm->moduleInfo().icon(), 0, QStringList() << "dialog-warning" ) );
00185     } else {
00186         item->setHeader( kcm->moduleInfo().comment() );
00187         item->setIcon( KIcon( kcm->moduleInfo().icon() ) );
00188     }
00189 }
00190 
00191 void KCMultiDialogPrivate::_k_dialogClosed()
00192 {
00193   kDebug(710) ;
00194 
00200   for ( int i = 0; i < modules.count(); ++i )
00201     modules[ i ].kcm->deleteClient();
00202 }
00203 
00204 void KCMultiDialogPrivate::init()
00205 {
00206     Q_Q(KCMultiDialog);
00207     q->setFaceType(KPageDialog::Auto);
00208     q->setCaption(i18n("Configure"));
00209     q->setButtons(KDialog::Help | KDialog::Default |KDialog::Cancel | KDialog::Apply | KDialog::Ok | KDialog::Reset);
00210 
00211     q->setModal(false);
00212 
00213     q->connect(q, SIGNAL(finished()), SLOT(_k_dialogClosed()));
00214     q->connect(q, SIGNAL(applyClicked()), SLOT(slotApplyClicked()));
00215     q->connect(q, SIGNAL(okClicked()), SLOT(slotOkClicked()));
00216     q->connect(q, SIGNAL(defaultClicked()), SLOT(slotDefaultClicked()));
00217     q->connect(q, SIGNAL(helpClicked()), SLOT(slotHelpClicked()));
00218     q->connect(q, SIGNAL(user1Clicked()), SLOT(slotUser1Clicked()));
00219     q->connect(q, SIGNAL(resetClicked()), SLOT(slotUser1Clicked()));
00220 
00221     q->connect(q, SIGNAL(currentPageChanged(KPageWidgetItem*, KPageWidgetItem*)),
00222             SLOT(_k_slotCurrentPageChanged(KPageWidgetItem*, KPageWidgetItem*)));
00223 
00224     q->setInitialSize(QSize(800, 550));
00225 }
00226 
00227 KCMultiDialog::KCMultiDialog( QWidget *parent )
00228     : KPageDialog(*new KCMultiDialogPrivate, NULL, parent)
00229 {
00230     d_func()->init();
00231 }
00232 
00233 KCMultiDialog::KCMultiDialog(KPageWidget *pageWidget, QWidget *parent, Qt::WFlags flags)
00234     : KPageDialog(*new KCMultiDialogPrivate, pageWidget, parent, flags)
00235 {
00236     d_func()->init();
00237 }
00238 
00239 KCMultiDialog::KCMultiDialog(KCMultiDialogPrivate &dd, KPageWidget *pageWidget, QWidget *parent, Qt::WFlags flags)
00240     : KPageDialog(dd, pageWidget, parent, flags)
00241 {
00242     d_func()->init();
00243 }
00244 
00245 KCMultiDialog::~KCMultiDialog()
00246 {
00247 }
00248 
00249 void KCMultiDialog::slotDefaultClicked()
00250 {
00251     Q_D(KCMultiDialog);
00252   const KPageWidgetItem *item = currentPage();
00253   if ( !item )
00254     return;
00255 
00256   for ( int i = 0; i < d->modules.count(); ++i ) {
00257     if ( d->modules[ i ].item == item ) {
00258       d->modules[ i ].kcm->defaults();
00259             d->_k_clientChanged();
00260       return;
00261     }
00262   }
00263 }
00264 
00265 void KCMultiDialog::slotUser1Clicked()
00266 {
00267   const KPageWidgetItem *item = currentPage();
00268   if ( !item )
00269     return;
00270 
00271     Q_D(KCMultiDialog);
00272   for ( int i = 0; i < d->modules.count(); ++i ) {
00273     if ( d->modules[ i ].item == item ) {
00274       d->modules[ i ].kcm->load();
00275             d->_k_clientChanged();
00276       return;
00277     }
00278   }
00279 }
00280 
00281 bool KCMultiDialogPrivate::moduleSave(KCModuleProxy *module)
00282 {
00283     if( !module ) {
00284         return false;
00285     }
00286 
00287     module->save();
00288     return true;
00289 }
00290 
00291 void KCMultiDialogPrivate::apply()
00292 {
00293     Q_Q(KCMultiDialog);
00294     QStringList updatedComponents;
00295 
00296     foreach (const CreatedModule &module, modules) {
00297         KCModuleProxy *proxy = module.kcm;
00298 
00299         if (proxy->changed()) {
00300             proxy->save();
00305             const QStringList componentNames = module.componentNames;
00306             foreach (const QString &componentName, module.componentNames) {
00307                 if (!updatedComponents.contains(componentName)) {
00308                     updatedComponents.append(componentName);
00309                 }
00310             }
00311         }
00312     }
00313 
00314     // Send the configCommitted signal for every updated component.
00315     foreach (const QString &name, updatedComponents) {
00316         emit q->configCommitted(name.toLatin1());
00317     }
00318 
00319     emit q->configCommitted();
00320 }
00321 
00322 void KCMultiDialog::slotApplyClicked()
00323 {
00324   setButtonFocus( Apply );
00325 
00326     d_func()->apply();
00327 }
00328 
00329 
00330 void KCMultiDialog::slotOkClicked()
00331 {
00332   setButtonFocus( Ok );
00333 
00334     d_func()->apply();
00335   accept();
00336 }
00337 
00338 void KCMultiDialog::slotHelpClicked()
00339 {
00340   const KPageWidgetItem *item = currentPage();
00341   if ( !item )
00342     return;
00343 
00344     Q_D(KCMultiDialog);
00345   QString docPath;
00346   for ( int i = 0; i < d->modules.count(); ++i ) {
00347     if ( d->modules[ i ].item == item ) {
00348       docPath = d->modules[ i ].kcm->moduleInfo().docPath();
00349       break;
00350     }
00351   }
00352 
00353   KUrl docUrl( KUrl( "help:/" ), docPath );
00354   if ( docUrl.protocol() == "help" || docUrl.protocol() == "man" || docUrl.protocol() == "info" ) {
00355     QProcess::startDetached("khelpcenter", QStringList() << docUrl.url());
00356   } else {
00357     KToolInvocation::invokeBrowser( docUrl.url() );
00358   }
00359 }
00360 
00361 
00362 KPageWidgetItem* KCMultiDialog::addModule( const QString& path, const QStringList& args )
00363 {
00364   QString complete = path;
00365 
00366   if ( !path.endsWith( QLatin1String(".desktop") ) )
00367     complete += ".desktop";
00368 
00369   KService::Ptr service = KService::serviceByStorageId( complete );
00370 
00371   return addModule( KCModuleInfo( service ), 0, args );
00372 }
00373 
00374 KPageWidgetItem* KCMultiDialog::addModule( const KCModuleInfo& moduleInfo,
00375                                            KPageWidgetItem *parentItem, const QStringList& args )
00376 {
00377   if ( !moduleInfo.service() )
00378     return 0;
00379 
00380   //KAuthorized::authorizeControlModule( moduleInfo.service()->menuId() ) is
00381   //checked in noDisplay already
00382   if ( moduleInfo.service()->noDisplay() )
00383     return 0;
00384 
00385     KCModuleProxy *kcm = new KCModuleProxy(moduleInfo, 0, args);
00386 
00387     kDebug(710) << moduleInfo.moduleName();
00388     KPageWidgetItem *item = new KPageWidgetItem(kcm, moduleInfo.moduleName());
00389 
00390     if (kcm->useRootOnlyMessage()) {
00391         item->setHeader( "<b>"+moduleInfo.comment() + "</b><br><i>" + kcm->rootOnlyMessage() + "</i>" );
00392         item->setIcon( KIcon( moduleInfo.icon(), 0, QStringList() << "dialog-warning" ) );
00393     } else {
00394         item->setHeader( moduleInfo.comment() );
00395         item->setIcon( KIcon( moduleInfo.icon() ) );
00396     }
00397     item->setProperty("_k_weight", moduleInfo.weight());
00398 
00399     bool updateCurrentPage = false;
00400     const KPageWidgetModel *model = qobject_cast<const KPageWidgetModel *>(pageWidget()->model());
00401     Q_ASSERT(model);
00402     if (parentItem) {
00403         const QModelIndex parentIndex = model->index(parentItem);
00404         const int siblingCount = model->rowCount(parentIndex);
00405         int row = 0;
00406         for (; row < siblingCount; ++row) {
00407             KPageWidgetItem *siblingItem = model->item(parentIndex.child(row, 0));
00408             if (siblingItem->property("_k_weight").toInt() > moduleInfo.weight()) {
00409                 // the item we found is heavier than the new module
00410                 kDebug(710) << "adding KCM " << item->name() << " before " << siblingItem->name();
00411                 insertPage(siblingItem, item);
00412                 break;
00413             }
00414         }
00415         if (row >= siblingCount) {
00416             // the new module is either the first or the heaviest item
00417             kDebug(710) << "adding KCM " << item->name() << " with parent " << parentItem->name();
00418             addSubPage(parentItem, item);
00419         }
00420     } else {
00421         const int siblingCount = model->rowCount();
00422         int row = 0;
00423         for (; row < siblingCount; ++row) {
00424             KPageWidgetItem *siblingItem = model->item(model->index(row, 0));
00425             if (siblingItem->property("_k_weight").toInt() > moduleInfo.weight()) {
00426                 // the item we found is heavier than the new module
00427                 kDebug(710) << "adding KCM " << item->name() << " before " << siblingItem->name();
00428                 insertPage(siblingItem, item);
00429                 if ( siblingItem == currentPage() )
00430                     updateCurrentPage = true;
00431 
00432                 break;
00433             }
00434         }
00435         if (row == siblingCount) {
00436             // the new module is either the first or the heaviest item
00437             kDebug(710) << "adding KCM " << item->name() << " at the top level";
00438             addPage(item);
00439         }
00440     }
00441 
00442     connect(kcm, SIGNAL(changed(bool)), this, SLOT(_k_clientChanged()));
00443     connect(kcm->realModule(), SIGNAL(rootOnlyMessageChanged(bool,QString)), this, SLOT(_k_updateHeader(bool,QString)));
00444 
00445     Q_D(KCMultiDialog);
00446   KCMultiDialogPrivate::CreatedModule cm;
00447   cm.kcm = kcm;
00448   cm.item = item;
00449   cm.componentNames = moduleInfo.service()->property( "X-KDE-ParentComponents" ).toStringList();
00450   d->modules.append( cm );
00451 
00452   if ( d->modules.count() == 1 || updateCurrentPage )
00453   {
00454     setCurrentPage( item );
00455     d->_k_clientChanged();
00456   }
00457   return item;
00458 }
00459 
00460 void KCMultiDialog::clear()
00461 {
00462     Q_D(KCMultiDialog);
00463   kDebug( 710 ) ;
00464 
00465   for ( int i = 0; i < d->modules.count(); ++i ) {
00466     removePage( d->modules[ i ].item );
00467     delete d->modules[ i ].kcm;
00468   }
00469 
00470   d->modules.clear();
00471 
00472     d->_k_clientChanged();
00473 }
00474 
00475 void KCMultiDialog::setButtons(ButtonCodes buttonMask)
00476 {
00477     KPageDialog::setButtons(buttonMask);
00478 
00479     // Set Auto-Default mode ( KDE Bug #211187 )
00480     if (buttonMask & KDialog::Ok) {
00481         button(KDialog::Ok)->setAutoDefault(true);
00482     }
00483     if (buttonMask & KDialog::Apply) {
00484         button(KDialog::Apply)->setAutoDefault(true);
00485     }
00486     if (buttonMask & KDialog::Default) {
00487         button(KDialog::Default)->setAutoDefault(true);
00488     }
00489     if (buttonMask & KDialog::Reset) {
00490         button(KDialog::Reset)->setAutoDefault(true);
00491     }
00492     if (buttonMask & KDialog::Cancel) {
00493         button(KDialog::Cancel)->setAutoDefault(true);
00494     }
00495     if (buttonMask & KDialog::Help) {
00496         button(KDialog::Help)->setAutoDefault(true);
00497     }
00498 
00499     // Old Reset Button
00500     enableButton(KDialog::User1, false);
00501     enableButton(KDialog::Reset, false);
00502     enableButton(KDialog::Apply, false);
00503 }
00504 
00505 
00506 #include "kcmultidialog.moc"

KUtils

Skip menu "KUtils"
  • Main Page
  • 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