00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
00041 #include "auth/kauthaction.h"
00042
00043 #include "kcolorscheme.h"
00044
00045 #include "kcmoduleloader.h"
00046 #include "kcmoduleproxy.h"
00047
00048 void KCMultiDialogPrivate::_k_slotCurrentPageChanged( KPageWidgetItem *item )
00049 {
00050 kDebug(710) ;
00051
00052 if ( !item )
00053 return;
00054
00055 KCModuleProxy *module = 0;
00056 for ( int i = 0; i < modules.count(); ++i ) {
00057 if ( modules[ i ].item == item ) {
00058 module = modules[ i ].kcm;
00059 break;
00060 }
00061 }
00062
00063 if ( !module )
00064 return;
00065 kDebug(710) << "found module for page: " << module->moduleInfo().moduleName();
00066
00067 currentModule = module;
00068
00069 updateButtons(currentModule);
00070 }
00071
00072 void KCMultiDialogPrivate::updateButtons(KCModuleProxy *currentModule)
00073 {
00074 Q_Q(KCMultiDialog);
00075 q->enableButton(KDialog::Help, currentModule->buttons() & KCModule::Help);
00076 q->enableButton(KDialog::Default, currentModule->buttons() & KCModule::Default);
00077
00078 if (q->button(KDialog::Apply))
00079 {
00080 q->disconnect(q, SIGNAL(applyClicked()), q, SLOT(slotApplyClicked()));
00081 q->disconnect(q->button(KDialog::Apply), SIGNAL(authorized(KAuth::Action*)), q, SLOT(slotApplyClicked()));
00082 }
00083
00084 if (q->button(KDialog::Ok))
00085 {
00086 q->disconnect(q, SIGNAL(okClicked()), q, SLOT(slotOkClicked()));
00087 q->disconnect(q->button(KDialog::Ok), SIGNAL(authorized(KAuth::Action*)), q, SLOT(slotOkClicked()));
00088 }
00089
00090 if (currentModule->realModule()->needsAuthorization()) {
00091 if (q->button(KDialog::Apply))
00092 {
00093 q->button(KDialog::Apply)->setAuthAction(currentModule->realModule()->authAction());
00094 q->connect(q->button(KDialog::Apply), SIGNAL(authorized(KAuth::Action*)), SLOT(slotApplyClicked()));
00095 }
00096
00097 if (q->button(KDialog::Ok))
00098 {
00099 q->button(KDialog::Ok)->setAuthAction(currentModule->realModule()->authAction());
00100 q->connect(q->button(KDialog::Ok), SIGNAL(authorized(KAuth::Action*)), SLOT(slotOkClicked()));
00101 }
00102 } else {
00103
00104 if (q->button(KDialog::Apply))
00105 {
00106 q->connect(q, SIGNAL(applyClicked()), SLOT(slotApplyClicked()));
00107 q->button(KDialog::Apply)->setAuthAction(currentModule->realModule()->authAction());
00108 }
00109 if (q->button(KDialog::Ok))
00110 {
00111 q->connect(q, SIGNAL(okClicked()), SLOT(slotOkClicked()));
00112 q->button(KDialog::Ok)->setAuthAction(currentModule->realModule()->authAction());
00113 }
00114 }
00115 }
00116
00117 void KCMultiDialogPrivate::_k_updateHeader(bool use, const QString &message)
00118 {
00119 Q_Q(KCMultiDialog);
00120 KPageWidgetItem *item = q->currentPage();
00121 KCModuleProxy *kcm = qobject_cast<KCModuleProxy*>(item->widget());
00122
00123 if (use) {
00124 item->setHeader( "<b>"+kcm->moduleInfo().comment() + "</b><br><i>" +
00125 message + "</i>" );
00126 item->setIcon( KIcon( kcm->moduleInfo().icon(), 0, QStringList() << "dialog-warning" ) );
00127 } else {
00128 item->setHeader( kcm->moduleInfo().comment() );
00129 item->setIcon( KIcon( kcm->moduleInfo().icon() ) );
00130 }
00131 }
00132
00133 void KCMultiDialogPrivate::_k_clientChanged()
00134 {
00135 Q_Q(KCMultiDialog);
00136 for ( int i = 0; i < modules.count(); ++i ) {
00137 if ( modules[ i ].kcm->changed() ) {
00138 q->enableButton(KDialog::Apply, true);
00139 return;
00140 }
00141 }
00142
00143 q->enableButton(KDialog::Apply, false);
00144 }
00145
00146 void KCMultiDialogPrivate::_k_dialogClosed()
00147 {
00148 kDebug(710) ;
00149
00155 for ( int i = 0; i < modules.count(); ++i )
00156 modules[ i ].kcm->deleteClient();
00157 }
00158
00159 void KCMultiDialogPrivate::init()
00160 {
00161 Q_Q(KCMultiDialog);
00162 q->setFaceType(KPageDialog::Auto);
00163 q->setCaption(i18n("Configure"));
00164 q->setButtons(KDialog::Help | KDialog::Default |KDialog::Cancel | KDialog::Apply | KDialog::Ok | KDialog::User1);
00165 q->setButtonGuiItem(KDialog::User1, KStandardGuiItem::reset());
00166 q->setDefaultButton(KDialog::Ok);
00167 q->setModal(false);
00168 q->showButtonSeparator(true);
00169
00170 q->connect(q, SIGNAL(finished()), SLOT(_k_dialogClosed()));
00171
00172 q->showButton(KDialog::User1, false);
00173 q->enableButton(KDialog::Apply, false);
00174
00175 q->connect(q, SIGNAL(currentPageChanged(KPageWidgetItem*, KPageWidgetItem*)),
00176 SLOT(_k_slotCurrentPageChanged(KPageWidgetItem*)));
00177
00178 q->connect(q, SIGNAL(applyClicked()), SLOT(slotApplyClicked()));
00179 q->connect(q, SIGNAL(okClicked()), SLOT(slotOkClicked()));
00180 q->connect(q, SIGNAL(defaultClicked()), SLOT(slotDefaultClicked()));
00181 q->connect(q, SIGNAL(helpClicked()), SLOT(slotHelpClicked()));
00182 q->connect(q, SIGNAL(user1Clicked()), SLOT(slotUser1Clicked()));
00183
00184 q->setInitialSize(QSize(800, 550));
00185 }
00186
00187 KCMultiDialog::KCMultiDialog( QWidget *parent )
00188 : KPageDialog(*new KCMultiDialogPrivate, NULL, parent)
00189 {
00190 d_func()->init();
00191 }
00192
00193 KCMultiDialog::KCMultiDialog(KPageWidget *pageWidget, QWidget *parent, Qt::WFlags flags)
00194 : KPageDialog(*new KCMultiDialogPrivate, pageWidget, parent, flags)
00195 {
00196 d_func()->init();
00197 }
00198
00199 KCMultiDialog::KCMultiDialog(KCMultiDialogPrivate &dd, KPageWidget *pageWidget, QWidget *parent, Qt::WFlags flags)
00200 : KPageDialog(dd, pageWidget, parent, flags)
00201 {
00202 d_func()->init();
00203 }
00204
00205 KCMultiDialog::~KCMultiDialog()
00206 {
00207 }
00208
00209 void KCMultiDialog::slotDefaultClicked()
00210 {
00211 Q_D(KCMultiDialog);
00212 const KPageWidgetItem *item = currentPage();
00213 if ( !item )
00214 return;
00215
00216 for ( int i = 0; i < d->modules.count(); ++i ) {
00217 if ( d->modules[ i ].item == item ) {
00218 d->modules[ i ].kcm->defaults();
00219 d->_k_clientChanged();
00220 return;
00221 }
00222 }
00223 }
00224
00225 void KCMultiDialog::slotUser1Clicked()
00226 {
00227 const KPageWidgetItem *item = currentPage();
00228 if ( !item )
00229 return;
00230
00231 Q_D(KCMultiDialog);
00232 for ( int i = 0; i < d->modules.count(); ++i ) {
00233 if ( d->modules[ i ].item == item ) {
00234 d->modules[ i ].kcm->load();
00235 d->_k_clientChanged();
00236 return;
00237 }
00238 }
00239 }
00240
00241 void KCMultiDialogPrivate::apply()
00242 {
00243 Q_Q(KCMultiDialog);
00244 QStringList updatedComponents;
00245
00246 foreach (const CreatedModule &module, modules) {
00247 KCModuleProxy *proxy = module.kcm;
00248
00249 if (proxy->changed()) {
00250 proxy->save();
00255 const QStringList componentNames = module.componentNames;
00256 foreach (const QString &componentName, module.componentNames) {
00257 if (!updatedComponents.contains(componentName)) {
00258 updatedComponents.append(componentName);
00259 }
00260 }
00261 }
00262 }
00263
00264
00265 foreach (const QString &name, updatedComponents) {
00266 emit q->configCommitted(name.toLatin1());
00267 }
00268
00269 emit q->configCommitted();
00270 }
00271
00272 void KCMultiDialog::slotApplyClicked()
00273 {
00274 setButtonFocus( Apply );
00275
00276 d_func()->apply();
00277 }
00278
00279
00280 void KCMultiDialog::slotOkClicked()
00281 {
00282 setButtonFocus( Ok );
00283
00284 d_func()->apply();
00285 accept();
00286 }
00287
00288 void KCMultiDialog::slotHelpClicked()
00289 {
00290 const KPageWidgetItem *item = currentPage();
00291 if ( !item )
00292 return;
00293
00294 Q_D(KCMultiDialog);
00295 QString docPath;
00296 for ( int i = 0; i < d->modules.count(); ++i ) {
00297 if ( d->modules[ i ].item == item ) {
00298 docPath = d->modules[ i ].kcm->moduleInfo().docPath();
00299 break;
00300 }
00301 }
00302
00303 KUrl docUrl( KUrl( "help:/" ), docPath );
00304 if ( docUrl.protocol() == "help" || docUrl.protocol() == "man" || docUrl.protocol() == "info" ) {
00305 QProcess::startDetached("khelpcenter", QStringList() << docUrl.url());
00306 } else {
00307 KToolInvocation::invokeBrowser( docUrl.url() );
00308 }
00309 }
00310
00311
00312 KPageWidgetItem* KCMultiDialog::addModule( const QString& path, const QStringList& args )
00313 {
00314 QString complete = path;
00315
00316 if ( !path.endsWith( ".desktop" ) )
00317 complete += ".desktop";
00318
00319 KService::Ptr service = KService::serviceByStorageId( complete );
00320
00321 return addModule( KCModuleInfo( service ), 0, args );
00322 }
00323
00324 KPageWidgetItem* KCMultiDialog::addModule( const KCModuleInfo& moduleInfo,
00325 KPageWidgetItem *parentItem, const QStringList& args )
00326 {
00327 if ( !moduleInfo.service() )
00328 return 0;
00329
00330
00331
00332 if ( moduleInfo.service()->noDisplay() )
00333 return 0;
00334
00335 KCModuleProxy *kcm = new KCModuleProxy(moduleInfo, 0, args);
00336
00337 kDebug(710) << moduleInfo.moduleName();
00338 KPageWidgetItem *item = new KPageWidgetItem(kcm, moduleInfo.moduleName());
00339
00340 if (kcm->useRootOnlyMessage()) {
00341 item->setHeader( "<b>"+moduleInfo.comment() + "</b><br><i>" + kcm->rootOnlyMessage() + "</i>" );
00342 item->setIcon( KIcon( moduleInfo.icon(), 0, QStringList() << "dialog-warning" ) );
00343 } else {
00344 item->setHeader( moduleInfo.comment() );
00345 item->setIcon( KIcon( moduleInfo.icon() ) );
00346 }
00347 item->setProperty("_k_weight", moduleInfo.weight());
00348
00349 bool updateCurrentPage = false;
00350 const KPageWidgetModel *model = qobject_cast<const KPageWidgetModel *>(pageWidget()->model());
00351 Q_ASSERT(model);
00352 if (parentItem) {
00353 const QModelIndex parentIndex = model->index(parentItem);
00354 const int siblingCount = model->rowCount(parentIndex);
00355 int row = 0;
00356 for (; row < siblingCount; ++row) {
00357 KPageWidgetItem *siblingItem = model->item(parentIndex.child(row, 0));
00358 if (siblingItem->property("_k_weight").toInt() > moduleInfo.weight()) {
00359
00360 kDebug(710) << "adding KCM " << item->name() << " before " << siblingItem->name();
00361 insertPage(siblingItem, item);
00362 break;
00363 }
00364 }
00365 if (row >= siblingCount) {
00366
00367 kDebug(710) << "adding KCM " << item->name() << " with parent " << parentItem->name();
00368 addSubPage(parentItem, item);
00369 }
00370 } else {
00371 const int siblingCount = model->rowCount();
00372 int row = 0;
00373 for (; row < siblingCount; ++row) {
00374 KPageWidgetItem *siblingItem = model->item(model->index(row, 0));
00375 if (siblingItem->property("_k_weight").toInt() > moduleInfo.weight()) {
00376
00377 kDebug(710) << "adding KCM " << item->name() << " before " << siblingItem->name();
00378 insertPage(siblingItem, item);
00379 if ( siblingItem == currentPage() )
00380 updateCurrentPage = true;
00381
00382 break;
00383 }
00384 }
00385 if (row == siblingCount) {
00386
00387 kDebug(710) << "adding KCM " << item->name() << " at the top level";
00388 addPage(item);
00389 }
00390 }
00391
00392 connect(kcm, SIGNAL(changed(bool)), this, SLOT(_k_clientChanged()));
00393 connect(kcm->realModule(), SIGNAL(rootOnlyMessageChanged(bool,QString)), this, SLOT(_k_updateHeader(bool,QString)));
00394
00395 Q_D(KCMultiDialog);
00396 KCMultiDialogPrivate::CreatedModule cm;
00397 cm.kcm = kcm;
00398 cm.item = item;
00399 cm.componentNames = moduleInfo.service()->property( "X-KDE-ParentComponents" ).toStringList();
00400 d->modules.append( cm );
00401
00402 if ( d->modules.count() == 1 || updateCurrentPage )
00403 {
00404 setCurrentPage( item );
00405 d->updateButtons(kcm);
00406 }
00407 return item;
00408 }
00409
00410 void KCMultiDialog::clear()
00411 {
00412 Q_D(KCMultiDialog);
00413 kDebug( 710 ) ;
00414
00415 for ( int i = 0; i < d->modules.count(); ++i ) {
00416 removePage( d->modules[ i ].item );
00417 delete d->modules[ i ].kcm;
00418 }
00419
00420 d->modules.clear();
00421
00422 d->_k_clientChanged();
00423 }
00424
00425
00426
00427 #include "kcmultidialog.moc"