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.
24 #include <QtCore/QFile>
25 #include <QtGui/QIcon>
29 FIXME: how are we supposed to handle stuff like this that is so
30 integrated with QX11Embed on alternate platforms?
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>
46 #include <kiconloader.h>
48 #include <kservicetypetrader.h>
49 #include <kstartupinfo.h>
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()))
74 static KService::Ptr
locateModule(const QByteArray
& module
)
76 QString path
= QFile::decodeName(module
);
78 if (!path
.endsWith(".desktop"))
81 KService::Ptr service
= KService::serviceByStorageId( path
);
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();
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.
117 KCMShellMultiDialog::KCMShellMultiDialog(KPageDialog::FaceType dialogFace
, QWidget
*parent
)
118 : KCMultiDialog(parent
)
120 setFaceType(dialogFace
);
123 QDBusConnection::sessionBus().registerObject("/KCModule/dialog", this, QDBusConnection::ExportScriptableSlots
);
126 void KCMShellMultiDialog::activate( const QByteArray
& asn_id
)
131 KStartupInfo::setNewStartupId( this, asn_id
);
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()
145 connect(QDBusConnection::sessionBus().interface(), SIGNAL(serviceOwnerChanged(QString
,QString
,QString
)),
146 SLOT(appExit(QString
,QString
,QString
)));
150 void KCMShell::appExit(const QString
&appId
, const QString
&oldName
, const QString
&newName
)
155 if( appId
== m_serviceName
&& !oldName
.isEmpty() )
157 kDebug(780) << "'" << appId
<< "' closed, dereferencing.";
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.
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
;
202 for( KService::List::ConstIterator it
= m_modules
.constBegin(); it
!= m_modules
.constEnd(); ++it
)
204 int len
= (*it
)->desktopEntryName().length();
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
;
222 if (args
->count() < 1)
229 KService::List modules
;
230 for (int i
= 0; i
< args
->count(); i
++)
232 KService::Ptr service
= locateModule(args
->arg(i
).toLocal8Bit());
235 modules
.append(service
);
236 if( !serviceName
.isEmpty() )
239 serviceName
+= args
->arg(i
);
243 /* Check if this particular module combination is already running */
244 app
.setServiceName(serviceName
);
245 if( app
.isRunning() ) {
250 KPageDialog::FaceType ftype
= KPageDialog::Plain
;
252 if (modules
.count() < 1) {
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());
263 } else if (modules
.count() == 1) {
264 dlg
->setCaption(modules
.first()->name());
267 for (KService::List::ConstIterator it
= modules
.constBegin(); it
!= modules
.constEnd(); ++it
)
270 if ( !args
->isSet( "icon" ) && modules
.count() == 1)
272 QString iconName
= KCModuleInfo(modules
.first()).icon();
273 dlg
->setWindowIcon( KIcon(iconName
) );
280 // vim: sw=4 et sts=4