00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <qcursor.h>
00025 #include <qhbox.h>
00026 #include <qlayout.h>
00027 #include <qpushbutton.h>
00028
00029 #include <kaboutdata.h>
00030 #include <kapplication.h>
00031 #include <kdebug.h>
00032 #include <kiconloader.h>
00033 #include <klibloader.h>
00034 #include <klocale.h>
00035 #include <kmessagebox.h>
00036 #include <kprocess.h>
00037 #include <krun.h>
00038 #include <kstdguiitem.h>
00039 #include <kuser.h>
00040
00041 #include "kcmoduleloader.h"
00042 #include "kcmoduleproxy.h"
00043 #include "kcmultidialog.h"
00044 #include "kcmultidialog.moc"
00045
00046 class KCMultiDialog::KCMultiDialogPrivate
00047 {
00048 public:
00049 KCMultiDialogPrivate()
00050 : hasRootKCM( false ), currentModule( 0 )
00051 {}
00052
00053 bool hasRootKCM;
00054 KCModuleProxy* currentModule;
00055 };
00056
00057
00058 KCMultiDialog::KCMultiDialog(QWidget *parent, const char *name, bool modal)
00059 : KDialogBase(IconList, i18n("Configure"), Help | Default |Cancel | Apply |
00060 Ok | User1 | User2, Ok, parent, name, modal, true,
00061 KStdGuiItem::reset(), KStdGuiItem::adminMode())
00062 , dialogface( IconList ), d( new KCMultiDialogPrivate )
00063 {
00064 init();
00065 }
00066
00067 KCMultiDialog::KCMultiDialog( int dialogFace, const QString & caption, QWidget * parent, const char * name, bool modal )
00068 : KDialogBase( dialogFace, caption, Help | Default | Cancel | Apply | Ok |
00069 User1 | User2, Ok, parent, name, modal, true,
00070 KStdGuiItem::reset(), KStdGuiItem::adminMode())
00071 , dialogface( dialogFace ), d( new KCMultiDialogPrivate )
00072 {
00073 init();
00074 }
00075
00076 KCMultiDialog::KCMultiDialog( int dialogFace, const KGuiItem &user2,
00077 const KGuiItem &user3, int buttonMask, const QString &caption,
00078 QWidget *parent, const char *name, bool modal )
00079 : KDialogBase( dialogFace, caption, buttonMask | Help | Default | Cancel |
00080 Apply | Ok | User1, Ok, parent, name, modal, true,
00081 KStdGuiItem::reset(), user2, user3 )
00082 , dialogface( dialogFace ), d( new KCMultiDialogPrivate )
00083 {
00084 kdDebug( 710 ) << "Root modules will not work with this constructor. See the API documentation." << endl;
00085 init();
00086 if ( buttonMask & User2 )
00087 showButton( User2, true );
00088 }
00089
00090 inline void KCMultiDialog::init()
00091 {
00092 connect( this, SIGNAL( finished()), SLOT( dialogClosed()));
00093 showButton( User1, false );
00094 showButton( User2, false );
00095 enableButton(Apply, false);
00096 connect(this, SIGNAL(aboutToShowPage(QWidget *)), this, SLOT(slotAboutToShow(QWidget *)));
00097 setInitialSize(QSize(640,480));
00098 moduleParentComponents.setAutoDelete( true );
00099
00100 }
00101
00102 KCMultiDialog::~KCMultiDialog()
00103 {
00104 OrphanMap::Iterator end2 = m_orphanModules.end();
00105 for( OrphanMap::Iterator it = m_orphanModules.begin(); it != end2; ++it )
00106 delete ( *it );
00107 }
00108
00109 void KCMultiDialog::slotDefault()
00110 {
00111 int curPageIndex = activePageIndex();
00112
00113 ModuleList::Iterator end = m_modules.end();
00114 for( ModuleList::Iterator it = m_modules.begin(); it != end; ++it )
00115 if( pageIndex( ( QWidget * )( *it ).kcm->parent() ) == curPageIndex )
00116 {
00117 ( *it ).kcm->defaults();
00118 clientChanged( true );
00119 return;
00120 }
00121 }
00122
00123 void KCMultiDialog::slotUser1()
00124 {
00125 int curPageIndex = activePageIndex();
00126
00127 ModuleList::Iterator end = m_modules.end();
00128 for( ModuleList::Iterator it = m_modules.begin(); it != end; ++it )
00129 if( pageIndex( ( QWidget * )( *it ).kcm->parent() ) == curPageIndex )
00130 {
00131 ( *it ).kcm->load();
00132 clientChanged( false );
00133 return;
00134 }
00135 }
00136
00137 void KCMultiDialog::apply()
00138 {
00139 QStringList updatedModules;
00140 ModuleList::Iterator end = m_modules.end();
00141 for( ModuleList::Iterator it = m_modules.begin(); it != end; ++it )
00142 {
00143 KCModuleProxy * m = ( *it ).kcm;
00144 if( m->changed() )
00145 {
00146 m->save();
00147 QStringList * names = moduleParentComponents[ m ];
00148 kdDebug(710) << k_funcinfo << *names << " saved and added to the list" << endl;
00149 for( QStringList::ConstIterator it = names->begin(); it != names->end(); ++it )
00150 if( updatedModules.find( *it ) == updatedModules.end() )
00151 updatedModules.append( *it );
00152 }
00153 }
00154 for( QStringList::const_iterator it = updatedModules.begin(); it != updatedModules.end(); ++it )
00155 {
00156 kdDebug(710) << k_funcinfo << *it << " " << ( *it ).latin1() << endl;
00157 emit configCommitted( ( *it ).latin1() );
00158 }
00159 emit configCommitted();
00160 }
00161
00162 void KCMultiDialog::slotApply()
00163 {
00164 QPushButton *button = actionButton(Apply);
00165 if (button)
00166 button->setFocus();
00167 emit applyClicked();
00168 apply();
00169 }
00170
00171
00172 void KCMultiDialog::slotOk()
00173 {
00174 QPushButton *button = actionButton(Ok);
00175 if (button)
00176 button->setFocus();
00177 emit okClicked();
00178 apply();
00179 accept();
00180 }
00181
00182 void KCMultiDialog::slotHelp()
00183 {
00184 QString docPath;
00185
00186 int curPageIndex = activePageIndex();
00187 ModuleList::Iterator end = m_modules.end();
00188 for( ModuleList::Iterator it = m_modules.begin(); it != end; ++it )
00189 if( pageIndex( ( QWidget * )( *it ).kcm->parent() ) == curPageIndex )
00190 {
00191 docPath = ( *it ).kcm->moduleInfo().docPath();
00192 break;
00193 }
00194
00195 KURL url( KURL("help:/"), docPath );
00196
00197 if (url.protocol() == "help" || url.protocol() == "man" || url.protocol() == "info") {
00198 KProcess process;
00199 process << "khelpcenter"
00200 << url.url();
00201 process.start(KProcess::DontCare);
00202 process.detach();
00203 } else {
00204 new KRun(url);
00205 }
00206 }
00207
00208 void KCMultiDialog::clientChanged(bool state)
00209 {
00210 kdDebug( 710 ) << k_funcinfo << state << endl;
00211 ModuleList::Iterator end = m_modules.end();
00212 for( ModuleList::Iterator it = m_modules.begin(); it != end; ++it )
00213 if( ( *it ).kcm->changed() )
00214 {
00215 enableButton( Apply, true );
00216 return;
00217 }
00218 enableButton( Apply, false );
00219 }
00220
00221 void KCMultiDialog::addModule(const QString& path, bool withfallback)
00222 {
00223 QString complete = path;
00224
00225 if( !path.endsWith( ".desktop" ))
00226 complete += ".desktop";
00227
00228 KService::Ptr service = KService::serviceByStorageId( complete );
00229
00230 addModule( KCModuleInfo( service ), QStringList(), withfallback);
00231 }
00232
00233 void KCMultiDialog::addModule(const KCModuleInfo& moduleinfo,
00234 QStringList parentmodulenames, bool withfallback)
00235 {
00236 kdDebug(710) << "KCMultiDialog::addModule "
00237 << moduleinfo.moduleName() << endl;
00238
00239 if( !moduleinfo.service() )
00240 return;
00241
00242 if ( !kapp->authorizeControlModule( moduleinfo.service()->menuId() ))
00243 return;
00244
00245 if( !KCModuleLoader::testModule( moduleinfo ))
00246 return;
00247
00248 QFrame* page = 0;
00249 if (!moduleinfo.service()->noDisplay())
00250 switch( dialogface )
00251 {
00252 case TreeList:
00253 parentmodulenames += moduleinfo.moduleName();
00254 page = addHBoxPage( parentmodulenames, moduleinfo.comment(),
00255 SmallIcon( moduleinfo.icon(),
00256 IconSize( KIcon::Small ) ) );
00257 break;
00258 case IconList:
00259 page = addHBoxPage( moduleinfo.moduleName(),
00260 moduleinfo.comment(), DesktopIcon( moduleinfo.icon(),
00261 KIcon::SizeMedium ) );
00262 break;
00263 case Plain:
00264 page = plainPage();
00265 ( new QHBoxLayout( page ) )->setAutoAdd( true );
00266 break;
00267 default:
00268 kdError( 710 ) << "unsupported dialog face for KCMultiDialog"
00269 << endl;
00270 break;
00271 }
00272 if(!page) {
00273 KCModuleLoader::unloadModule(moduleinfo);
00274 return;
00275 }
00276 KCModuleProxy * module;
00277 if( m_orphanModules.contains( moduleinfo.service() ) )
00278 {
00279
00280
00281 module = m_orphanModules[ moduleinfo.service() ];
00282 m_orphanModules.remove( moduleinfo.service() );
00283 kdDebug( 710 ) << "Use KCModule from the list of orphans for " <<
00284 moduleinfo.moduleName() << ": " << module << endl;
00285
00286 module->reparent( page, 0, QPoint( 0, 0 ), true );
00287
00288 if( module->changed() )
00289 clientChanged( true );
00290
00291 if( activePageIndex() == -1 )
00292 showPage( pageIndex( page ) );
00293 }
00294 else
00295 {
00296 module = new KCModuleProxy( moduleinfo, withfallback, page );
00297 QStringList parentComponents = moduleinfo.service()->property(
00298 "X-KDE-ParentComponents" ).toStringList();
00299 moduleParentComponents.insert( module,
00300 new QStringList( parentComponents ) );
00301
00302 connect(module, SIGNAL(changed(bool)), this, SLOT(clientChanged(bool)));
00303
00304 if( m_modules.count() == 0 )
00305 aboutToShowPage( page );
00306 }
00307 CreatedModule cm;
00308 cm.kcm = module;
00309 cm.service = moduleinfo.service();
00310 m_modules.append( cm );
00311 if ( moduleinfo.needsRootPrivileges() &&
00312 !d->hasRootKCM &&
00313 !KUser().isSuperUser() )
00314 {
00315 d->hasRootKCM = true;
00316 showButton( User2, true );
00317 if( plainPage() )
00318 slotAboutToShow( page );
00319 }
00320 }
00321
00322 void KCMultiDialog::removeAllModules()
00323 {
00324 kdDebug( 710 ) << k_funcinfo << endl;
00325 ModuleList::Iterator end = m_modules.end();
00326 for( ModuleList::Iterator it = m_modules.begin(); it != end; ++it )
00327 {
00328 kdDebug( 710 ) << "remove 2" << endl;
00329 KCModuleProxy * kcm = ( *it ).kcm;
00330 QObject * page = kcm->parent();
00331 kcm->hide();
00332 if( page )
00333 {
00334
00335 kcm->reparent( 0, QPoint( 0, 0 ), false );
00336 delete page;
00337 }
00338 m_orphanModules[ ( *it ).service ] = kcm;
00339 kdDebug( 710 ) << "added KCModule to the list of orphans: " <<
00340 kcm << endl;
00341 }
00342 m_modules.clear();
00343
00344 clientChanged( false );
00345 }
00346
00347 void KCMultiDialog::show()
00348 {
00349 KDialogBase::show();
00350 }
00351
00352 void KCMultiDialog::slotAboutToShow(QWidget *page)
00353 {
00354 kdDebug(710) << k_funcinfo << endl;
00355
00356 QObject * obj = page->child( 0, "KCModuleProxy" );
00357 if( ! obj )
00358 return;
00359
00360 KCModuleProxy * module = ( KCModuleProxy* )obj->qt_cast(
00361 "KCModuleProxy" );
00362 if( ! module )
00363 return;
00364 d->currentModule = module;
00365
00366 enableButton( KDialogBase::Help,
00367 d->currentModule->buttons() & KCModule::Help );
00368 enableButton( KDialogBase::Default,
00369 d->currentModule->buttons() & KCModule::Default );
00370
00371 disconnect( this, SIGNAL(user2Clicked()), 0, 0 );
00372
00373 if (d->currentModule->moduleInfo().needsRootPrivileges())
00374 {
00375 if ( !d->currentModule->rootMode() )
00376 {
00377 enableButton( User2, true );
00378 connect( this, SIGNAL(user2Clicked()), d->currentModule, SLOT( runAsRoot() ));
00379 connect( this, SIGNAL(user2Clicked()), SLOT( disableRModeButton() ));
00380 }
00381 else
00382 enableButton( User2, false);
00383 }
00384 }
00385
00386 void KCMultiDialog::rootExit()
00387 {
00388 enableButton( User2, true);
00389 }
00390
00391 void KCMultiDialog::disableRModeButton()
00392 {
00393 enableButton( User2, false );
00394 connect ( d->currentModule, SIGNAL( childClosed() ), SLOT( rootExit() ));
00395 }
00396
00397 void KCMultiDialog::dialogClosed()
00398 {
00399 kdDebug(710) << k_funcinfo << endl;
00400
00401
00402
00403
00404 ModuleList::Iterator end = m_modules.end();
00405 for( ModuleList::Iterator it = m_modules.begin(); it != end; ++it )
00406 ( *it ).kcm->deleteClient();
00407 }
00408
00409
00410