00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <iostream>
00023
00024 #include <qcstring.h>
00025 #include <qfile.h>
00026
00027 #include <dcopclient.h>
00028 #include <qxembed.h>
00029
00030 #include <kaboutdata.h>
00031 #include <kapplication.h>
00032 #include <kcmdlineargs.h>
00033 #include <kcmoduleinfo.h>
00034 #include <kcmoduleloader.h>
00035 #include <kcmoduleproxy.h>
00036 #include <kcmultidialog.h>
00037 #include <kdebug.h>
00038 #include <kdialogbase.h>
00039 #include <kiconloader.h>
00040 #include <klocale.h>
00041 #include <kservice.h>
00042 #include <kservicegroup.h>
00043 #include <kstartupinfo.h>
00044 #include <kwin.h>
00045 #include <kglobal.h>
00046
00047 #include "main.h"
00048 #include "main.moc"
00049
00050 using namespace std;
00051
00052 KService::List m_modules;
00053
00054 static KCmdLineOptions options[] =
00055 {
00056 { "list", I18N_NOOP("List all possible modules"), 0},
00057 { "+module", I18N_NOOP("Configuration module to open"), 0 },
00058 { "lang <language>", I18N_NOOP("Specify a particular language"), 0 },
00059 { "embed <id>", I18N_NOOP("Embeds the module with buttons in window with id <id>"), 0 },
00060 { "embed-proxy <id>", I18N_NOOP("Embeds the module without buttons in window with id <id>"), 0 },
00061 { "silent", I18N_NOOP("Do not display main window"), 0 },
00062 KCmdLineLastOption
00063 };
00064
00065 static void listModules(const QString &baseGroup)
00066 {
00067
00068 KServiceGroup::Ptr group = KServiceGroup::group(baseGroup);
00069
00070 if (!group || !group->isValid())
00071 return;
00072
00073 KServiceGroup::List list = group->entries(true, true);
00074
00075 for( KServiceGroup::List::ConstIterator it = list.begin();
00076 it != list.end(); it++)
00077 {
00078 KSycocaEntry *p = (*it);
00079 if (p->isType(KST_KService))
00080 {
00081 KService *s = static_cast<KService*>(p);
00082 if (!kapp->authorizeControlModule(s->menuId()))
00083 continue;
00084 m_modules.append(s);
00085 }
00086 else if (p->isType(KST_KServiceGroup))
00087 listModules(p->entryPath());
00088 }
00089 }
00090
00091 static KService::Ptr locateModule(const QCString& module)
00092 {
00093 QString path = QFile::decodeName(module);
00094
00095 if (!path.endsWith(".desktop"))
00096 path += ".desktop";
00097
00098 KService::Ptr service = KService::serviceByStorageId( path );
00099 if (!service)
00100 {
00101 kdWarning(780) << "Could not find module '" << module << "'." << endl;
00102 return 0;
00103 }
00104
00105
00106 if ( module.left( 4 ) != "kde-" && service->library().isEmpty() )
00107 return locateModule( "kde-" + module );
00108
00109 if(!KCModuleLoader::testModule( module ))
00110 {
00111 kdDebug(780) << "According to \"" << module << "\"'s test function, it should Not be loaded." << endl;
00112 return 0;
00113 }
00114
00115 return service;
00116 }
00117
00118 bool KCMShell::isRunning()
00119 {
00120 if( dcopClient()->appId() == m_dcopName )
00121 return false;
00122
00123 kdDebug(780) << "kcmshell with modules '" <<
00124 m_dcopName << "' is already running." << endl;
00125
00126 dcopClient()->attach();
00127 dcopClient()->setNotifications(true);
00128
00129 QByteArray data;
00130 QDataStream str( data, IO_WriteOnly );
00131 str << kapp->startupId();
00132 QCString replyType;
00133 QByteArray replyData;
00134 if (!dcopClient()->call(m_dcopName, "dialog", "activate(QCString)",
00135 data, replyType, replyData))
00136 {
00137 kdDebug(780) << "Calling DCOP function dialog::activate() failed." << endl;
00138 return false;
00139 }
00140
00141 return true;
00142 }
00143
00144 KCMShellMultiDialog::KCMShellMultiDialog( int dialogFace, const QString& caption,
00145 QWidget *parent, const char *name, bool modal)
00146 : KCMultiDialog( dialogFace, caption, parent, name, modal ),
00147 DCOPObject("dialog")
00148 {
00149 }
00150
00151 void KCMShellMultiDialog::activate( QCString asn_id )
00152 {
00153 kdDebug(780) << k_funcinfo << endl;
00154
00155 KStartupInfo::setNewStartupId( this, asn_id );
00156 }
00157
00158 void KCMShell::setDCOPName(const QCString &dcopName, bool rootMode )
00159 {
00160 m_dcopName = "kcmshell_";
00161 if( rootMode )
00162 m_dcopName += "rootMode_";
00163
00164 m_dcopName += dcopName;
00165
00166 dcopClient()->registerAs(m_dcopName, false);
00167 }
00168
00169 void KCMShell::waitForExit()
00170 {
00171 kdDebug(780) << k_funcinfo << endl;
00172
00173 connect(dcopClient(), SIGNAL(applicationRemoved(const QCString&)),
00174 SLOT( appExit(const QCString&) ));
00175 exec();
00176 }
00177
00178 void KCMShell::appExit(const QCString &appId)
00179 {
00180 kdDebug(780) << k_funcinfo << endl;
00181
00182 if( appId == m_dcopName )
00183 {
00184 kdDebug(780) << "'" << appId << "' closed, dereferencing." << endl;
00185 deref();
00186 }
00187 }
00188
00189 static void setIcon(QWidget *w, const QString &iconName)
00190 {
00191 QPixmap icon = DesktopIcon(iconName);
00192 QPixmap miniIcon = SmallIcon(iconName);
00193 w->setIcon( icon );
00194 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00195 KWin::setIcons(w->winId(), icon, miniIcon );
00196 #endif
00197 }
00198
00199 extern "C" KDE_EXPORT int kdemain(int _argc, char *_argv[])
00200 {
00201 KAboutData aboutData( "kcmshell", I18N_NOOP("KDE Control Module"),
00202 0,
00203 I18N_NOOP("A tool to start single KDE control modules"),
00204 KAboutData::License_GPL,
00205 I18N_NOOP("(c) 1999-2004, The KDE Developers") );
00206
00207 aboutData.addAuthor("Frans Englich", I18N_NOOP("Maintainer"), "frans.englich@kde.org");
00208 aboutData.addAuthor("Daniel Molkentin", 0, "molkentin@kde.org");
00209 aboutData.addAuthor("Matthias Hoelzer-Kluepfel",0, "hoelzer@kde.org");
00210 aboutData.addAuthor("Matthias Elter",0, "elter@kde.org");
00211 aboutData.addAuthor("Matthias Ettrich",0, "ettrich@kde.org");
00212 aboutData.addAuthor("Waldo Bastian",0, "bastian@kde.org");
00213
00214 KGlobal::locale()->setMainCatalogue("kcmshell");
00215
00216 KCmdLineArgs::init(_argc, _argv, &aboutData);
00217 KCmdLineArgs::addCmdLineOptions( options );
00218 KCMShell app;
00219
00220 const KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
00221
00222 const QCString lang = args->getOption("lang");
00223 if( !lang.isNull() )
00224 KGlobal::locale()->setLanguage(lang);
00225
00226 if (args->isSet("list"))
00227 {
00228 cout << i18n("The following modules are available:").local8Bit() << endl;
00229
00230 listModules( "Settings/" );
00231
00232 int maxLen=0;
00233
00234 for( KService::List::ConstIterator it = m_modules.begin(); it != m_modules.end(); ++it)
00235 {
00236 int len = (*it)->desktopEntryName().length();
00237 if (len > maxLen)
00238 maxLen = len;
00239 }
00240
00241 for( KService::List::ConstIterator it = m_modules.begin(); it != m_modules.end(); ++it)
00242 {
00243 QString entry("%1 - %2");
00244
00245 entry = entry.arg((*it)->desktopEntryName().leftJustify(maxLen, ' '))
00246 .arg(!(*it)->comment().isEmpty() ? (*it)->comment()
00247 : i18n("No description available"));
00248
00249 cout << entry.local8Bit() << endl;
00250 }
00251 return 0;
00252 }
00253
00254 if (args->count() < 1)
00255 {
00256 args->usage();
00257 return -1;
00258 }
00259
00260 QCString dcopName;
00261 KService::List modules;
00262 for (int i = 0; i < args->count(); i++)
00263 {
00264 KService::Ptr service = locateModule(args->arg(i));
00265 if( service )
00266 {
00267 modules.append(service);
00268 if( !dcopName.isEmpty() )
00269 dcopName += "_";
00270
00271 dcopName += args->arg(i);
00272 }
00273 }
00274
00275
00276
00277 app.setDCOPName(dcopName,
00278 ( args->isSet( "embed-proxy" ) || args->isSet( "embed" )));
00279 if( app.isRunning() )
00280 {
00281 app.waitForExit();
00282 return 0;
00283 }
00284
00285 KDialogBase::DialogType dtype = KDialogBase::Plain;
00286
00287 if ( modules.count() < 1 )
00288 return 0;
00289 else if( modules.count() > 1 )
00290 dtype = KDialogBase::IconList;
00291
00292 bool idValid;
00293 int id;
00294
00295 if ( args->isSet( "embed-proxy" ))
00296 {
00297 id = args->getOption( "embed-proxy" ).toInt(&idValid);
00298 if( idValid )
00299 {
00300 KCModuleProxy *module = new KCModuleProxy( modules.first()->desktopEntryName() );
00301 module->realModule();
00302 QXEmbed::embedClientIntoWindow( module, id);
00303 app.exec();
00304 delete module;
00305 }
00306 else
00307 kdDebug(780) << "Supplied id '" << id << "' is not valid." << endl;
00308
00309 return 0;
00310
00311 }
00312
00313 KCMShellMultiDialog *dlg = new KCMShellMultiDialog( dtype,
00314 i18n("Configure - %1").arg(kapp->caption()), 0, "", true );
00315
00316 for (KService::List::ConstIterator it = modules.begin(); it != modules.end(); ++it)
00317 dlg->addModule(KCModuleInfo(*it));
00318
00319 if ( args->isSet( "embed" ))
00320 {
00321 id = args->getOption( "embed" ).toInt(&idValid);
00322 if( idValid )
00323 {
00324 QXEmbed::embedClientIntoWindow( dlg, id );
00325 dlg->exec();
00326 delete dlg;
00327 }
00328 else
00329 kdDebug(780) << "Supplied id '" << id << "' is not valid." << endl;
00330
00331 }
00332 else
00333 {
00334
00335 if (kapp->iconName() != kapp->name())
00336 setIcon(dlg, kapp->iconName());
00337 else if ( modules.count() == 1 )
00338 setIcon(dlg, KCModuleInfo( modules.first()).icon());
00339
00340 dlg->exec();
00341 delete dlg;
00342 }
00343
00344 return 0;
00345 }
00346