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 if(!KCModuleLoader::testModule( module ))
00106 {
00107 kdDebug(780) << "According to \"" << module << "\"'s test function, it should Not be loaded." << endl;
00108 return 0;
00109 }
00110
00111 return service;
00112 }
00113
00114 bool KCMShell::isRunning()
00115 {
00116 if( dcopClient()->appId() == m_dcopName )
00117 return false;
00118
00119 kdDebug(780) << "kcmshell with modules '" <<
00120 m_dcopName << "' is already running." << endl;
00121
00122 dcopClient()->attach();
00123 dcopClient()->setNotifications(true);
00124
00125 QByteArray data;
00126 QDataStream str( data, IO_WriteOnly );
00127 str << kapp->startupId();
00128 QCString replyType;
00129 QByteArray replyData;
00130 if (!dcopClient()->call(m_dcopName, "dialog", "activate(QCString)",
00131 data, replyType, replyData))
00132 {
00133 kdDebug(780) << "Calling DCOP function dialog::activate() failed." << endl;
00134 return false;
00135 }
00136
00137 return true;
00138 }
00139
00140 KCMShellMultiDialog::KCMShellMultiDialog( int dialogFace, const QString& caption,
00141 QWidget *parent, const char *name, bool modal)
00142 : KCMultiDialog( dialogFace, caption, parent, name, modal ),
00143 DCOPObject("dialog")
00144 {
00145 }
00146
00147 void KCMShellMultiDialog::activate( QCString asn_id )
00148 {
00149 kdDebug(780) << k_funcinfo << endl;
00150
00151 KStartupInfo::setNewStartupId( this, asn_id );
00152 }
00153
00154 void KCMShell::setDCOPName(const QCString &dcopName, bool rootMode )
00155 {
00156 m_dcopName = "kcmshell_";
00157 if( rootMode )
00158 m_dcopName += "rootMode_";
00159
00160 m_dcopName += dcopName;
00161
00162 dcopClient()->registerAs(m_dcopName, false);
00163 }
00164
00165 void KCMShell::waitForExit()
00166 {
00167 kdDebug(780) << k_funcinfo << endl;
00168
00169 connect(dcopClient(), SIGNAL(applicationRemoved(const QCString&)),
00170 SLOT( appExit(const QCString&) ));
00171 exec();
00172 }
00173
00174 void KCMShell::appExit(const QCString &appId)
00175 {
00176 kdDebug(780) << k_funcinfo << endl;
00177
00178 if( appId == m_dcopName )
00179 {
00180 kdDebug(780) << "'" << appId << "' closed, dereferencing." << endl;
00181 deref();
00182 }
00183 }
00184
00185 static void setIcon(QWidget *w, const QString &iconName)
00186 {
00187 QPixmap icon = DesktopIcon(iconName);
00188 QPixmap miniIcon = SmallIcon(iconName);
00189 w->setIcon( icon );
00190 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00191 KWin::setIcons(w->winId(), icon, miniIcon );
00192 #endif
00193 }
00194
00195 extern "C" KDE_EXPORT int kdemain(int _argc, char *_argv[])
00196 {
00197 KAboutData aboutData( "kcmshell", I18N_NOOP("KDE Control Module"),
00198 0,
00199 I18N_NOOP("A tool to start single KDE control modules"),
00200 KAboutData::License_GPL,
00201 I18N_NOOP("(c) 1999-2004, The KDE Developers") );
00202
00203 aboutData.addAuthor("Frans Englich", I18N_NOOP("Maintainer"), "frans.englich@kde.org");
00204 aboutData.addAuthor("Daniel Molkentin", 0, "molkentin@kde.org");
00205 aboutData.addAuthor("Matthias Hoelzer-Kluepfel",0, "hoelzer@kde.org");
00206 aboutData.addAuthor("Matthias Elter",0, "elter@kde.org");
00207 aboutData.addAuthor("Matthias Ettrich",0, "ettrich@kde.org");
00208 aboutData.addAuthor("Waldo Bastian",0, "bastian@kde.org");
00209
00210 KGlobal::locale()->setMainCatalogue("kcmshell");
00211
00212 KCmdLineArgs::init(_argc, _argv, &aboutData);
00213 KCmdLineArgs::addCmdLineOptions( options );
00214 KCMShell app;
00215
00216 const KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
00217
00218 const QCString lang = args->getOption("lang");
00219 if( !lang.isNull() )
00220 KGlobal::locale()->setLanguage(lang);
00221
00222 if (args->isSet("list"))
00223 {
00224 cout << i18n("The following modules are available:").local8Bit() << endl;
00225
00226 listModules( "Settings/" );
00227
00228 int maxLen=0;
00229
00230 for( KService::List::ConstIterator it = m_modules.begin(); it != m_modules.end(); ++it)
00231 {
00232 int len = (*it)->desktopEntryName().length();
00233 if (len > maxLen)
00234 maxLen = len;
00235 }
00236
00237 for( KService::List::ConstIterator it = m_modules.begin(); it != m_modules.end(); ++it)
00238 {
00239 QString entry("%1 - %2");
00240
00241 entry = entry.arg((*it)->desktopEntryName().leftJustify(maxLen, ' '))
00242 .arg(!(*it)->comment().isEmpty() ? (*it)->comment()
00243 : i18n("No description available"));
00244
00245 cout << entry.local8Bit() << endl;
00246 }
00247 return 0;
00248 }
00249
00250 if (args->count() < 1)
00251 {
00252 args->usage();
00253 return -1;
00254 }
00255
00256 QCString dcopName;
00257 KService::List modules;
00258 for (int i = 0; i < args->count(); i++)
00259 {
00260 KService::Ptr service = locateModule(args->arg(i));
00261 if( service )
00262 {
00263 modules.append(service);
00264 if( !dcopName.isEmpty() )
00265 dcopName += "_";
00266
00267 dcopName += args->arg(i);
00268 }
00269 }
00270
00271
00272
00273 app.setDCOPName(dcopName,
00274 ( args->isSet( "embed-proxy" ) || args->isSet( "embed" )));
00275 if( app.isRunning() )
00276 {
00277 app.waitForExit();
00278 return 0;
00279 }
00280
00281 KDialogBase::DialogType dtype = KDialogBase::Plain;
00282
00283 if ( modules.count() < 1 )
00284 return 0;
00285 else if( modules.count() > 1 )
00286 dtype = KDialogBase::IconList;
00287
00288 bool idValid;
00289 int id;
00290
00291 if ( args->isSet( "embed-proxy" ))
00292 {
00293 id = args->getOption( "embed-proxy" ).toInt(&idValid);
00294 if( idValid )
00295 {
00296 KCModuleProxy *module = new KCModuleProxy( modules.first()->desktopEntryName() );
00297 module->realModule();
00298 QXEmbed::embedClientIntoWindow( module, id);
00299 app.exec();
00300 delete module;
00301 }
00302 else
00303 kdDebug(780) << "Supplied id '" << id << "' is not valid." << endl;
00304
00305 return 0;
00306
00307 }
00308
00309 KCMShellMultiDialog *dlg = new KCMShellMultiDialog( dtype,
00310 i18n("Configure - %1").arg(kapp->caption()), 0, "", true );
00311
00312 for (KService::List::ConstIterator it = modules.begin(); it != modules.end(); ++it)
00313 dlg->addModule(KCModuleInfo(*it));
00314
00315 if ( args->isSet( "embed" ))
00316 {
00317 id = args->getOption( "embed" ).toInt(&idValid);
00318 if( idValid )
00319 {
00320 QXEmbed::embedClientIntoWindow( dlg, id );
00321 dlg->exec();
00322 delete dlg;
00323 }
00324 else
00325 kdDebug(780) << "Supplied id '" << id << "' is not valid." << endl;
00326
00327 }
00328 else
00329 {
00330
00331 if (kapp->iconName() != kapp->name())
00332 setIcon(dlg, kapp->iconName());
00333 else if ( modules.count() == 1 )
00334 setIcon(dlg, KCModuleInfo( modules.first()).icon());
00335
00336 dlg->exec();
00337 delete dlg;
00338 }
00339
00340 return 0;
00341 }
00342