delay a few things on startup, such as setting the visibility mode, which ensures...
[personal-kdebase.git] / runtime / kcmshell / main.cpp
blob9a19211078c0befc2cd6be463a494f6bf3e57a94
1 /*
2 Copyright (c) 1999 Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
3 Copyright (c) 2000 Matthias Elter <elter@kde.org>
4 Copyright (c) 2004 Frans Englich <frans.englich@telia.com>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #include <iostream>
24 #include <QtCore/QFile>
25 #include <QtGui/QIcon>
27 #ifdef Q_WS_X11
29 FIXME: how are we supposed to handle stuff like this that is so
30 integrated with QX11Embed on alternate platforms?
32 #endif
35 #include <QtDBus/QtDBus>
37 #include <kaboutdata.h>
38 #include <kapplication.h>
39 #include <kauthorized.h>
40 #include <kcmdlineargs.h>
41 #include <kcmoduleinfo.h>
42 #include <kcmoduleloader.h>
43 #include <kcmoduleproxy.h>
44 #include <kcmultidialog.h>
45 #include <kdebug.h>
46 #include <kiconloader.h>
47 #include <klocale.h>
48 #include <kservicetypetrader.h>
49 #include <kstartupinfo.h>
50 #include <kglobal.h>
52 #include "main.h"
53 #include <kicon.h>
54 #include "main.moc"
56 using namespace std;
58 KService::List m_modules;
61 static void listModules()
63 const KService::List services = KServiceTypeTrader::self()->query( "KCModule", "[X-KDE-ParentApp] == 'kcontrol' or [X-KDE-ParentApp] == 'kinfocenter'" );
64 for( KService::List::const_iterator it = services.begin();
65 it != services.end(); ++it)
67 const KService::Ptr s = (*it);
68 if (!KAuthorized::authorizeControlModule(s->menuId()))
69 continue;
70 m_modules.append(s);
74 static KService::Ptr locateModule(const QByteArray& module)
76 QString path = QFile::decodeName(module);
78 if (!path.endsWith(".desktop"))
79 path += ".desktop";
81 KService::Ptr service = KService::serviceByStorageId( path );
82 if (!service)
84 kWarning(780) << "Could not find module '" << module << "'." ;
85 return KService::Ptr();
88 if ( service->noDisplay() )
90 kDebug(780) << module << " should not be loaded.";
91 return KService::Ptr();
94 return service;
97 bool KCMShell::isRunning()
99 QString owner = QDBusConnection::sessionBus().interface()->serviceOwner(m_serviceName);
100 if( owner == QDBusConnection::sessionBus().baseService() )
101 return false; // We are the one and only.
103 kDebug(780) << "kcmshell4 with modules '" <<
104 m_serviceName << "' is already running." << endl;
106 QDBusInterface iface(m_serviceName, "/KCModule/dialog", "org.kde.KCMShellMultiDialog");
107 QDBusReply<void> reply = iface.call("activate", kapp->startupId());
108 if (!reply.isValid())
110 kDebug(780) << "Calling D-Bus function dialog::activate() failed.";
111 return false; // Error, we have to do it ourselves.
114 return true;
117 KCMShellMultiDialog::KCMShellMultiDialog(KPageDialog::FaceType dialogFace, QWidget *parent)
118 : KCMultiDialog(parent)
120 setFaceType(dialogFace);
121 setModal(true);
123 QDBusConnection::sessionBus().registerObject("/KCModule/dialog", this, QDBusConnection::ExportScriptableSlots);
126 void KCMShellMultiDialog::activate( const QByteArray& asn_id )
128 kDebug(780) ;
130 #ifdef Q_WS_X11
131 KStartupInfo::setNewStartupId( this, asn_id );
132 #endif
135 void KCMShell::setServiceName(const QString &dbusName )
137 m_serviceName = QLatin1String( "org.kde.kcmshell_" ) + dbusName;
138 QDBusConnection::sessionBus().registerService(m_serviceName);
141 void KCMShell::waitForExit()
143 kDebug(780) ;
145 connect(QDBusConnection::sessionBus().interface(), SIGNAL(serviceOwnerChanged(QString,QString,QString)),
146 SLOT(appExit(QString,QString,QString)));
147 exec();
150 void KCMShell::appExit(const QString &appId, const QString &oldName, const QString &newName)
152 Q_UNUSED(newName);
153 kDebug(780) ;
155 if( appId == m_serviceName && !oldName.isEmpty() )
157 kDebug(780) << "'" << appId << "' closed, dereferencing.";
158 KGlobal::deref();
162 extern "C" KDE_EXPORT int kdemain(int _argc, char *_argv[])
164 KAboutData aboutData( "kcmshell", 0, ki18n("KDE Control Module"),
166 ki18n("A tool to start single KDE control modules"),
167 KAboutData::License_GPL,
168 ki18n("(c) 1999-2004, The KDE Developers") );
170 aboutData.addAuthor(ki18n("Frans Englich"), ki18n("Maintainer"), "frans.englich@kde.org");
171 aboutData.addAuthor(ki18n("Daniel Molkentin"), KLocalizedString(), "molkentin@kde.org");
172 aboutData.addAuthor(ki18n("Matthias Hoelzer-Kluepfel"),KLocalizedString(), "hoelzer@kde.org");
173 aboutData.addAuthor(ki18n("Matthias Elter"),KLocalizedString(), "elter@kde.org");
174 aboutData.addAuthor(ki18n("Matthias Ettrich"),KLocalizedString(), "ettrich@kde.org");
175 aboutData.addAuthor(ki18n("Waldo Bastian"),KLocalizedString(), "bastian@kde.org");
177 KCmdLineArgs::init(_argc, _argv, &aboutData);
179 KCmdLineOptions options;
180 options.add("list", ki18n("List all possible modules"));
181 options.add("+module", ki18n("Configuration module to open"));
182 options.add("lang <language>", ki18n("Specify a particular language"));
183 options.add("silent", ki18n("Do not display main window"));
184 KCmdLineArgs::addCmdLineOptions( options ); // Add our own options.
185 KCMShell app;
187 const KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
189 const QString lang = args->getOption("lang");
190 if( !lang.isEmpty() ) {
191 KGlobal::setLocale(new KLocale(aboutData.catalogName(), lang));
194 if (args->isSet("list"))
196 cout << i18n("The following modules are available:").toLocal8Bit().data() << endl;
198 listModules();
200 int maxLen=0;
202 for( KService::List::ConstIterator it = m_modules.constBegin(); it != m_modules.constEnd(); ++it)
204 int len = (*it)->desktopEntryName().length();
205 if (len > maxLen)
206 maxLen = len;
209 for( KService::List::ConstIterator it = m_modules.constBegin(); it != m_modules.constEnd(); ++it)
211 QString entry("%1 - %2");
213 entry = entry.arg((*it)->desktopEntryName().leftJustified(maxLen, ' '))
214 .arg(!(*it)->comment().isEmpty() ? (*it)->comment()
215 : i18n("No description available"));
217 cout << entry.toLocal8Bit().data() << endl;
219 return 0;
222 if (args->count() < 1)
224 args->usage();
225 return -1;
228 QString serviceName;
229 KService::List modules;
230 for (int i = 0; i < args->count(); i++)
232 KService::Ptr service = locateModule(args->arg(i).toLocal8Bit());
233 if( service )
235 modules.append(service);
236 if( !serviceName.isEmpty() )
237 serviceName += '_';
239 serviceName += args->arg(i);
243 /* Check if this particular module combination is already running */
244 app.setServiceName(serviceName);
245 if( app.isRunning() ) {
246 app.waitForExit();
247 return 0;
250 KPageDialog::FaceType ftype = KPageDialog::Plain;
252 if (modules.count() < 1) {
253 return 0;
254 } else if (modules.count() > 1) {
255 ftype = KPageDialog::List;
258 KCMShellMultiDialog *dlg = new KCMShellMultiDialog(ftype);
259 KCmdLineArgs *kdeargs = KCmdLineArgs::parsedArgs("kde");
260 if (kdeargs && kdeargs->isSet("caption")) {
261 dlg->setCaption(QString());
262 kdeargs->clear();
263 } else if (modules.count() == 1) {
264 dlg->setCaption(modules.first()->name());
267 for (KService::List::ConstIterator it = modules.constBegin(); it != modules.constEnd(); ++it)
268 dlg->addModule(*it);
270 if ( !args->isSet( "icon" ) && modules.count() == 1)
272 QString iconName = KCModuleInfo(modules.first()).icon();
273 dlg->setWindowIcon( KIcon(iconName) );
275 dlg->exec();
276 delete dlg;
278 return 0;
280 // vim: sw=4 et sts=4