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 <QtCore/QFile>
00025 #include <QtGui/QIcon>
00026
00027 #ifdef Q_WS_X11
00028
00029
00030
00031
00032 #endif
00033
00034
00035 #include <QtDBus/QtDBus>
00036
00037 #include <kaboutdata.h>
00038 #include <kapplication.h>
00039 #include <kauthorized.h>
00040 #include <kcmdlineargs.h>
00041 #include <kcmoduleinfo.h>
00042 #include <kcmoduleloader.h>
00043 #include <kcmoduleproxy.h>
00044 #include <kcmultidialog.h>
00045 #include <kdebug.h>
00046 #include <kiconloader.h>
00047 #include <klocale.h>
00048 #include <kservicetypetrader.h>
00049 #include <kstartupinfo.h>
00050 #include <kglobal.h>
00051
00052 #include "main.h"
00053 #include <kicon.h>
00054 #include "main.moc"
00055
00056 using namespace std;
00057
00058 KService::List m_modules;
00059
00060
00061 static void listModules()
00062 {
00063 const KService::List services = KServiceTypeTrader::self()->query( "KCModule", "[X-KDE-ParentApp] == 'kcontrol' or [X-KDE-ParentApp] == 'kinfocenter'" );
00064 for( KService::List::const_iterator it = services.begin();
00065 it != services.end(); ++it)
00066 {
00067 const KService::Ptr s = (*it);
00068 if (!KAuthorized::authorizeControlModule(s->menuId()))
00069 continue;
00070 m_modules.append(s);
00071 }
00072 }
00073
00074 static KService::Ptr locateModule(const QByteArray& module)
00075 {
00076 QString path = QFile::decodeName(module);
00077
00078 if (!path.endsWith(".desktop"))
00079 path += ".desktop";
00080
00081 KService::Ptr service = KService::serviceByStorageId( path );
00082 if (!service)
00083 {
00084 kWarning(780) << "Could not find module '" << module << "'." ;
00085 return KService::Ptr();
00086 }
00087
00088 if ( service->noDisplay() )
00089 {
00090 kDebug(780) << module << " should not be loaded.";
00091 return KService::Ptr();
00092 }
00093
00094 return service;
00095 }
00096
00097 bool KCMShell::isRunning()
00098 {
00099 QString owner = QDBusConnection::sessionBus().interface()->serviceOwner(m_serviceName);
00100 if( owner == QDBusConnection::sessionBus().baseService() )
00101 return false;
00102
00103 kDebug(780) << "kcmshell4 with modules '" <<
00104 m_serviceName << "' is already running." << endl;
00105
00106 QDBusInterface iface(m_serviceName, "/KCModule/dialog", "org.kde.KCMShellMultiDialog");
00107 QDBusReply<void> reply = iface.call("activate", kapp->startupId());
00108 if (!reply.isValid())
00109 {
00110 kDebug(780) << "Calling D-Bus function dialog::activate() failed.";
00111 return false;
00112 }
00113
00114 return true;
00115 }
00116
00117 KCMShellMultiDialog::KCMShellMultiDialog(KPageDialog::FaceType dialogFace, QWidget *parent)
00118 : KCMultiDialog(parent)
00119 {
00120 setFaceType(dialogFace);
00121 setModal(true);
00122
00123 QDBusConnection::sessionBus().registerObject("/KCModule/dialog", this, QDBusConnection::ExportScriptableSlots);
00124 }
00125
00126 void KCMShellMultiDialog::activate( const QByteArray& asn_id )
00127 {
00128 kDebug(780) ;
00129
00130 #ifdef Q_WS_X11
00131 KStartupInfo::setNewStartupId( this, asn_id );
00132 #endif
00133 }
00134
00135 void KCMShell::setServiceName(const QString &dbusName )
00136 {
00137 m_serviceName = QLatin1String( "org.kde.kcmshell_" ) + dbusName;
00138 QDBusConnection::sessionBus().registerService(m_serviceName);
00139 }
00140
00141 void KCMShell::waitForExit()
00142 {
00143 kDebug(780) ;
00144
00145 connect(QDBusConnection::sessionBus().interface(), SIGNAL(serviceOwnerChanged(QString,QString,QString)),
00146 SLOT(appExit(QString,QString,QString)));
00147 exec();
00148 }
00149
00150 void KCMShell::appExit(const QString &appId, const QString &oldName, const QString &newName)
00151 {
00152 Q_UNUSED(newName);
00153 kDebug(780) ;
00154
00155 if( appId == m_serviceName && !oldName.isEmpty() )
00156 {
00157 kDebug(780) << "'" << appId << "' closed, dereferencing.";
00158 KGlobal::deref();
00159 }
00160 }
00161
00162 extern "C" KDE_EXPORT int kdemain(int _argc, char *_argv[])
00163 {
00164 KAboutData aboutData( "kcmshell", 0, ki18n("KDE Control Module"),
00165 0,
00166 ki18n("A tool to start single KDE control modules"),
00167 KAboutData::License_GPL,
00168 ki18n("(c) 1999-2004, The KDE Developers") );
00169
00170 aboutData.addAuthor(ki18n("Frans Englich"), ki18n("Maintainer"), "frans.englich@kde.org");
00171 aboutData.addAuthor(ki18n("Daniel Molkentin"), KLocalizedString(), "molkentin@kde.org");
00172 aboutData.addAuthor(ki18n("Matthias Hoelzer-Kluepfel"),KLocalizedString(), "hoelzer@kde.org");
00173 aboutData.addAuthor(ki18n("Matthias Elter"),KLocalizedString(), "elter@kde.org");
00174 aboutData.addAuthor(ki18n("Matthias Ettrich"),KLocalizedString(), "ettrich@kde.org");
00175 aboutData.addAuthor(ki18n("Waldo Bastian"),KLocalizedString(), "bastian@kde.org");
00176
00177 KCmdLineArgs::init(_argc, _argv, &aboutData);
00178
00179 KCmdLineOptions options;
00180 options.add("list", ki18n("List all possible modules"));
00181 options.add("+module", ki18n("Configuration module to open"));
00182 options.add("lang <language>", ki18n("Specify a particular language"));
00183 options.add("silent", ki18n("Do not display main window"));
00184 KCmdLineArgs::addCmdLineOptions( options );
00185 KCMShell app;
00186
00187 const KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
00188
00189 const QString lang = args->getOption("lang");
00190 if( !lang.isEmpty() ) {
00191 KGlobal::setLocale(new KLocale(aboutData.catalogName(), lang));
00192 }
00193
00194 if (args->isSet("list"))
00195 {
00196 cout << i18n("The following modules are available:").toLocal8Bit().data() << endl;
00197
00198 listModules();
00199
00200 int maxLen=0;
00201
00202 for( KService::List::ConstIterator it = m_modules.begin(); it != m_modules.end(); ++it)
00203 {
00204 int len = (*it)->desktopEntryName().length();
00205 if (len > maxLen)
00206 maxLen = len;
00207 }
00208
00209 for( KService::List::ConstIterator it = m_modules.begin(); it != m_modules.end(); ++it)
00210 {
00211 QString entry("%1 - %2");
00212
00213 entry = entry.arg((*it)->desktopEntryName().leftJustified(maxLen, ' '))
00214 .arg(!(*it)->comment().isEmpty() ? (*it)->comment()
00215 : i18n("No description available"));
00216
00217 cout << entry.toLocal8Bit().data() << endl;
00218 }
00219 return 0;
00220 }
00221
00222 if (args->count() < 1)
00223 {
00224 args->usage();
00225 return -1;
00226 }
00227
00228 QString serviceName;
00229 KService::List modules;
00230 for (int i = 0; i < args->count(); i++)
00231 {
00232 KService::Ptr service = locateModule(args->arg(i).toLocal8Bit());
00233 if( service )
00234 {
00235 modules.append(service);
00236 if( !serviceName.isEmpty() )
00237 serviceName += '_';
00238
00239 serviceName += args->arg(i);
00240 }
00241 }
00242
00243
00244 app.setServiceName(serviceName);
00245 if( app.isRunning() ) {
00246 app.waitForExit();
00247 return 0;
00248 }
00249
00250 KPageDialog::FaceType ftype = KPageDialog::Plain;
00251
00252 if (modules.count() < 1) {
00253 return 0;
00254 } else if (modules.count() > 1) {
00255 ftype = KPageDialog::List;
00256 }
00257
00258 KCMShellMultiDialog *dlg = new KCMShellMultiDialog(ftype);
00259 KCmdLineArgs *kdeargs = KCmdLineArgs::parsedArgs("kde");
00260 if (kdeargs && kdeargs->isSet("caption")) {
00261 dlg->setCaption(QString());
00262 kdeargs->clear();
00263 } else if (modules.count() == 1) {
00264 dlg->setCaption(modules.first()->name());
00265 }
00266
00267 for (KService::List::ConstIterator it = modules.begin(); it != modules.end(); ++it)
00268 dlg->addModule(*it);
00269
00270 if ( !args->isSet( "icon" ) && modules.count() == 1)
00271 {
00272 QString iconName = KCModuleInfo(modules.first()).icon();
00273 dlg->setWindowIcon( KIcon(iconName) );
00274 }
00275 dlg->exec();
00276 delete dlg;
00277
00278 return 0;
00279 }
00280