• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kde-runtime API Reference
  • KDE Home
  • Contact Us
 

KCMShell

  • sources
  • kde-4.14
  • kde-runtime
  • kcmshell
main.cpp
Go to the documentation of this file.
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>
5 
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.
10 
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.
15 
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.
19 
20 */
21 
22 #include "main.h"
23 
24 #include <iostream>
25 
26 #include <QtDBus/QtDBus>
27 
28 #include <KAboutData>
29 #include <KApplication>
30 #include <KAuthorized>
31 #include <KCmdLineArgs>
32 #include <KCModuleInfo>
33 #include <KCMultiDialog>
34 #include <KDebug>
35 #include <KLocale>
36 #include <KServiceTypeTrader>
37 #include <KStartupInfo>
38 #include <KGlobal>
39 #include <KIcon>
40 #include <kdeversion.h>
41 
42 #include "main.moc"
43 
44 using namespace std;
45 
46 KService::List m_modules;
47 
48 static int debugArea() {
49  static int s_area = KDebug::registerArea("kcmshell");
50  return s_area;
51 }
52 
53 static bool caseInsensitiveLessThan(const KService::Ptr s1, const KService::Ptr s2)
54 {
55  const int compare = QString::compare(s1->desktopEntryName(),
56  s2->desktopEntryName(),
57  Qt::CaseInsensitive);
58  return (compare < 0);
59 }
60 
61 static void listModules()
62 {
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)
66  {
67  const KService::Ptr s = (*it);
68  if (!KAuthorized::authorizeControlModule(s->menuId()))
69  continue;
70  m_modules.append(s);
71  }
72 
73  qStableSort(m_modules.begin(), m_modules.end(), caseInsensitiveLessThan);
74 }
75 
76 static KService::Ptr locateModule(const QString& module)
77 {
78  QString path = module;
79 
80  if (!path.endsWith(QLatin1String(".desktop")))
81  path += ".desktop";
82 
83  KService::Ptr service = KService::serviceByStorageId( path );
84  if (!service) {
85  return KService::Ptr();
86  }
87 
88  if (!service->hasServiceType("KCModule")) {
89  // Not a KCModule. E.g. "kcmshell4 akonadi" finds services/kresources/kabc/akonadi.desktop, unrelated.
90  return KService::Ptr();
91  }
92 
93  if ( service->noDisplay() ) {
94  kDebug(debugArea()) << module << " should not be loaded.";
95  return KService::Ptr();
96  }
97 
98  return service;
99 }
100 
101 bool KCMShell::isRunning()
102 {
103  QString owner = QDBusConnection::sessionBus().interface()->serviceOwner(m_serviceName);
104  if( owner == QDBusConnection::sessionBus().baseService() )
105  return false; // We are the one and only.
106 
107  kDebug(debugArea()) << "kcmshell4 with modules '" <<
108  m_serviceName << "' is already running." << endl;
109 
110  QDBusInterface iface(m_serviceName, "/KCModule/dialog", "org.kde.KCMShellMultiDialog");
111  QDBusReply<void> reply = iface.call("activate", kapp->startupId());
112  if (!reply.isValid())
113  {
114  kDebug(debugArea()) << "Calling D-Bus function dialog::activate() failed.";
115  return false; // Error, we have to do it ourselves.
116  }
117 
118  return true;
119 }
120 
121 KCMShellMultiDialog::KCMShellMultiDialog(KPageDialog::FaceType dialogFace, QWidget *parent)
122  : KCMultiDialog(parent)
123 {
124  setFaceType(dialogFace);
125  setModal(true);
126 
127  QDBusConnection::sessionBus().registerObject("/KCModule/dialog", this, QDBusConnection::ExportScriptableSlots);
128 }
129 
130 void KCMShellMultiDialog::activate( const QByteArray& asn_id )
131 {
132  kDebug(debugArea()) ;
133 
134 #ifdef Q_WS_X11
135  KStartupInfo::setNewStartupId( this, asn_id );
136 #endif
137 }
138 
139 void KCMShell::setServiceName(const QString &dbusName )
140 {
141  m_serviceName = QLatin1String( "org.kde.kcmshell_" ) + dbusName;
142  QDBusConnection::sessionBus().registerService(m_serviceName);
143 }
144 
145 void KCMShell::waitForExit()
146 {
147  kDebug(debugArea());
148 
149  QDBusServiceWatcher *watcher = new QDBusServiceWatcher(this);
150  watcher->setConnection(QDBusConnection::sessionBus());
151  watcher->setWatchMode(QDBusServiceWatcher::WatchForOwnerChange);
152  watcher->addWatchedService(m_serviceName);
153  connect(watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)),
154  SLOT(appExit(QString,QString,QString)));
155  exec();
156 }
157 
158 void KCMShell::appExit(const QString &appId, const QString &oldName, const QString &newName)
159 {
160  Q_UNUSED(appId);
161  Q_UNUSED(newName);
162  kDebug(debugArea());
163 
164  if (!oldName.isEmpty())
165  {
166  kDebug(debugArea()) << "'" << appId << "' closed, dereferencing.";
167  KGlobal::deref();
168  }
169 }
170 
171 extern "C" KDE_EXPORT int kdemain(int _argc, char *_argv[])
172 {
173  KAboutData aboutData( "kcmshell", 0, ki18n("KDE Control Module"),
174  KDE_VERSION_STRING,
175  ki18n("A tool to start single KDE control modules"),
176  KAboutData::License_GPL,
177  ki18n("(c) 1999-2004, The KDE Developers") );
178 
179  aboutData.addAuthor(ki18n("Frans Englich"), ki18n("Maintainer"), "frans.englich@kde.org");
180  aboutData.addAuthor(ki18n("Daniel Molkentin"), KLocalizedString(), "molkentin@kde.org");
181  aboutData.addAuthor(ki18n("Matthias Hoelzer-Kluepfel"),KLocalizedString(), "hoelzer@kde.org");
182  aboutData.addAuthor(ki18n("Matthias Elter"),KLocalizedString(), "elter@kde.org");
183  aboutData.addAuthor(ki18n("Matthias Ettrich"),KLocalizedString(), "ettrich@kde.org");
184  aboutData.addAuthor(ki18n("Waldo Bastian"),KLocalizedString(), "bastian@kde.org");
185 
186  KCmdLineArgs::init(_argc, _argv, &aboutData);
187 
188  KCmdLineOptions options;
189  options.add("list", ki18n("List all possible modules"));
190  options.add("+module", ki18n("Configuration module to open"));
191  options.add("lang <language>", ki18n("Specify a particular language"));
192  options.add("silent", ki18n("Do not display main window"));
193  options.add("args <arguments>", ki18n("Arguments for the module"));
194  KCmdLineArgs::addCmdLineOptions( options ); // Add our own options.
195  KCMShell app;
196 
197  const KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
198 
199  const QString lang = args->getOption("lang");
200  if( !lang.isEmpty() ) {
201  KGlobal::setLocale(new KLocale(aboutData.catalogName(), lang));
202  }
203 
204  if (args->isSet("list"))
205  {
206  cout << i18n("The following modules are available:").toLocal8Bit().data() << endl;
207 
208  listModules();
209 
210  int maxLen=0;
211 
212  for( KService::List::ConstIterator it = m_modules.constBegin(); it != m_modules.constEnd(); ++it)
213  {
214  int len = (*it)->desktopEntryName().length();
215  if (len > maxLen)
216  maxLen = len;
217  }
218 
219  for( KService::List::ConstIterator it = m_modules.constBegin(); it != m_modules.constEnd(); ++it)
220  {
221  QString entry("%1 - %2");
222 
223  entry = entry.arg((*it)->desktopEntryName().leftJustified(maxLen, ' '))
224  .arg(!(*it)->comment().isEmpty() ? (*it)->comment()
225  : i18n("No description available"));
226 
227  cout << entry.toLocal8Bit().data() << endl;
228  }
229  return 0;
230  }
231 
232  if (args->count() < 1)
233  {
234  args->usage();
235  return -1;
236  }
237 
238  QString serviceName;
239  KService::List modules;
240  for (int i = 0; i < args->count(); i++)
241  {
242  const QString arg = args->arg(i);
243  KService::Ptr service = locateModule(arg);
244  if (!service) {
245  service = locateModule("kcm_" + arg);
246  }
247  if (!service) {
248  service = locateModule("kcm" + arg);
249  }
250 
251  if (service) {
252  modules.append(service);
253  if( !serviceName.isEmpty() )
254  serviceName += '_';
255  serviceName += args->arg(i);
256  } else {
257  fprintf(stderr, "%s\n", i18n("Could not find module '%1'. See kcmshell4 --list for the full list of modules.", arg).toLocal8Bit().constData());
258  }
259  }
260 
261  /* Check if this particular module combination is already running */
262  app.setServiceName(serviceName);
263  if( app.isRunning() ) {
264  app.waitForExit();
265  return 0;
266  }
267 
268  KPageDialog::FaceType ftype = KPageDialog::Plain;
269 
270  if (modules.count() < 1) {
271  return 0;
272  } else if (modules.count() > 1) {
273  ftype = KPageDialog::List;
274  }
275 
276  QStringList moduleArgs;
277  QString x = args->getOption("args");
278  moduleArgs << x.split(QRegExp(" +"));
279 
280  KCMShellMultiDialog *dlg = new KCMShellMultiDialog(ftype);
281  KCmdLineArgs *kdeargs = KCmdLineArgs::parsedArgs("kde");
282  if (kdeargs && kdeargs->isSet("caption")) {
283  dlg->setCaption(QString());
284  kdeargs->clear();
285  } else if (modules.count() == 1) {
286  dlg->setCaption(modules.first()->name());
287  }
288 
289  for (KService::List::ConstIterator it = modules.constBegin(); it != modules.constEnd(); ++it)
290  dlg->addModule(*it, 0, moduleArgs);
291 
292  if ( !args->isSet( "icon" ) && modules.count() == 1)
293  {
294  QString iconName = KCModuleInfo(modules.first()).icon();
295  dlg->setWindowIcon( KIcon(iconName) );
296  }
297  dlg->exec();
298  delete dlg;
299 
300  return 0;
301 }
302 // vim: sw=4 et sts=4
KCMShell
The KApplication instance for kcmshell.
Definition: main.h:32
QWidget
m_modules
KService::List m_modules
Definition: main.cpp:46
QByteArray
QDBusReply
QString::split
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
QDBusConnection::interface
QDBusConnectionInterface * interface() const
KCMShellMultiDialog::activate
virtual Q_SCRIPTABLE void activate(const QByteArray &asn_id)
Activate a module with id asn_id .
Definition: main.cpp:130
QDBusConnection::registerObject
bool registerObject(const QString &path, QObject *object, QFlags< QDBusConnection::RegisterOption > options)
QDBusReply::isValid
bool isValid() const
QDBusConnection::sessionBus
QDBusConnection sessionBus()
QDBusAbstractInterface::call
QDBusMessage call(const QString &method, const QVariant &arg1, const QVariant &arg2, const QVariant &arg3, const QVariant &arg4, const QVariant &arg5, const QVariant &arg6, const QVariant &arg7, const QVariant &arg8)
kdemain
KDE_EXPORT int kdemain(int _argc, char *_argv[])
Definition: main.cpp:171
main.h
QRegExp
QDBusServiceWatcher::setConnection
void setConnection(const QDBusConnection &connection)
QString::isEmpty
bool isEmpty() const
KCMShell::isRunning
bool isRunning()
Definition: main.cpp:101
KCMShell::setServiceName
void setServiceName(const QString &serviceName)
Sets m_serviceName basically to serviceName, and then registers with D-BUS.
Definition: main.cpp:139
QString::endsWith
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
caseInsensitiveLessThan
static bool caseInsensitiveLessThan(const KService::Ptr s1, const KService::Ptr s2)
Definition: main.cpp:53
KCMShellMultiDialog::KCMShellMultiDialog
KCMShellMultiDialog(KPageDialog::FaceType dialogFace, QWidget *parent=0)
Constructor.
Definition: main.cpp:121
QString
debugArea
static int debugArea()
Definition: main.cpp:48
QStringList
QDBusInterface
QString::toLocal8Bit
QByteArray toLocal8Bit() const
locateModule
static KService::Ptr locateModule(const QString &module)
Definition: main.cpp:76
QLatin1String
QByteArray::data
char * data()
listModules
static void listModules()
Definition: main.cpp:61
KCMShell::waitForExit
void waitForExit()
Waits until the last instance of kcmshell with the same module as this one exits, and then exits...
Definition: main.cpp:145
KCMultiDialog
QDBusServiceWatcher::setWatchMode
void setWatchMode(QFlags< QDBusServiceWatcher::WatchModeFlag > mode)
QString::compare
int compare(const QString &other) const
QDBusConnectionInterface::serviceOwner
QDBusReply< QString > serviceOwner(const QString &name) const
QString::arg
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
KCMShellMultiDialog
Essentially a plain KCMultiDialog, but has the additional functionality of allowing it to be told to ...
Definition: main.h:80
QDBusServiceWatcher::addWatchedService
void addWatchedService(const QString &newService)
QDBusConnection::registerService
bool registerService(const QString &serviceName)
QDBusServiceWatcher
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:08:20 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KCMShell

Skip menu "KCMShell"
  • Main Page
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kde-runtime API Reference

Skip menu "kde-runtime API Reference"
  • KCMShell
  • KNotify
  • Plasma Runtime
  •     PlasmaCore
  •     DragAndDrop
  •     PlasmaComponents
  •     PlasmaExtraComponents
  •     QtExtraComponents

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal