summaryrefslogtreecommitdiffstats
path: root/tdecmshell
diff options
context:
space:
mode:
Diffstat (limited to 'tdecmshell')
-rw-r--r--tdecmshell/CMakeLists.txt41
-rw-r--r--tdecmshell/Makefile.am39
-rw-r--r--tdecmshell/main.cpp350
-rw-r--r--tdecmshell/main.h104
4 files changed, 534 insertions, 0 deletions
diff --git a/tdecmshell/CMakeLists.txt b/tdecmshell/CMakeLists.txt
new file mode 100644
index 000000000..2b07bbdcc
--- /dev/null
+++ b/tdecmshell/CMakeLists.txt
@@ -0,0 +1,41 @@
+#################################################
+#
+# (C) 2010 Serghei Amelian
+# serghei (DOT) amelian (AT) gmail.com
+#
+# Improvements and feedback are welcome
+#
+# This file is released under GPL >= 2
+#
+#################################################
+
+include_directories(
+ ${TQT_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}/tdecore
+ ${CMAKE_SOURCE_DIR}/dcop
+ ${CMAKE_SOURCE_DIR}/tdecore
+ ${CMAKE_SOURCE_DIR}/tdeui
+ ${CMAKE_SOURCE_DIR}/tdeio
+ ${CMAKE_SOURCE_DIR}/tdeio/tdeio
+ ${CMAKE_SOURCE_DIR}/tdeutils
+)
+
+link_directories(
+ ${TQT_LIBRARY_DIRS}
+)
+
+
+##### tdecmshell ##################################
+
+set( target tdecmshell )
+
+set( ${target}_SRCS
+ main.cpp main.skel
+)
+
+tde_add_tdeinit_executable( ${target} AUTOMOC
+ SOURCES ${${target}_SRCS}
+ LINK tdeutils-shared
+ DEPENDENCIES dcopidl
+)
diff --git a/tdecmshell/Makefile.am b/tdecmshell/Makefile.am
new file mode 100644
index 000000000..a6e1d2d74
--- /dev/null
+++ b/tdecmshell/Makefile.am
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 1999 Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
+# Copyright (c) 2000 Matthias Elter <elter@kde.org>
+# Copyright (c) 2004 Frans Englich <frans.englich@telia.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+
+AM_CPPFLAGS = -I$(top_srcdir)/tdeutils $(all_includes)
+METASOURCES = AUTO
+
+lib_LTLIBRARIES =
+bin_PROGRAMS =
+tdeinit_LTLIBRARIES = tdecmshell.la
+
+tdecmshell_la_SOURCES = main.cpp main.skel
+tdecmshell_la_LIBADD = ../tdeutils/libtdeutils.la $(LIB_QT) $(LIB_TDEUI) $(top_builddir)/dcop/libDCOP.la $(LIB_TDECORE) $(LIB_KFILE)
+tdecmshell_la_LDFLAGS = $(all_libraries) -module -avoid-version
+
+noinst_HEADERS = main.h
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/tdecmshell.pot
+
+
+include $(top_srcdir)/admin/Doxyfile.am
+
diff --git a/tdecmshell/main.cpp b/tdecmshell/main.cpp
new file mode 100644
index 000000000..358b00ccb
--- /dev/null
+++ b/tdecmshell/main.cpp
@@ -0,0 +1,350 @@
+/*
+ Copyright (c) 1999 Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
+ Copyright (c) 2000 Matthias Elter <elter@kde.org>
+ Copyright (c) 2004 Frans Englich <frans.englich@telia.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <iostream>
+
+#include <tqcstring.h>
+#include <tqfile.h>
+
+#include <dcopclient.h>
+#include <qxembed.h>
+
+#include <kaboutdata.h>
+#include <kapplication.h>
+#include <kcmdlineargs.h>
+#include <tdecmoduleinfo.h>
+#include <tdecmoduleloader.h>
+#include <tdecmoduleproxy.h>
+#include <kcmultidialog.h>
+#include <kdebug.h>
+#include <kdialogbase.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kservice.h>
+#include <kservicegroup.h>
+#include <kstartupinfo.h>
+#include <twin.h>
+#include <kglobal.h>
+
+#include "main.h"
+#include "main.moc"
+
+using namespace std;
+
+KService::List m_modules;
+
+static KCmdLineOptions options[] =
+{
+ { "list", I18N_NOOP("List all possible modules"), 0},
+ { "+module", I18N_NOOP("Configuration module to open"), 0 },
+ { "lang <language>", I18N_NOOP("Specify a particular language"), 0 },
+ { "embed <id>", I18N_NOOP("Embeds the module with buttons in window with id <id>"), 0 },
+ { "embed-proxy <id>", I18N_NOOP("Embeds the module without buttons in window with id <id>"), 0 },
+ { "silent", I18N_NOOP("Do not display main window"), 0 },
+ KCmdLineLastOption
+};
+
+static void listModules(const TQString &baseGroup)
+{
+
+ KServiceGroup::Ptr group = KServiceGroup::group(baseGroup);
+
+ if (!group || !group->isValid())
+ return;
+
+ KServiceGroup::List list = group->entries(true, true);
+
+ for( KServiceGroup::List::ConstIterator it = list.begin();
+ it != list.end(); it++)
+ {
+ KSycocaEntry *p = (*it);
+ if (p->isType(KST_KService))
+ {
+ KService *s = static_cast<KService*>(p);
+ if (!kapp->authorizeControlModule(s->menuId()))
+ continue;
+ m_modules.append(s);
+ }
+ else if (p->isType(KST_KServiceGroup))
+ listModules(p->entryPath());
+ }
+}
+
+static KService::Ptr locateModule(const TQCString& module)
+{
+ TQString path = TQFile::decodeName(module);
+
+ if (!path.endsWith(".desktop"))
+ path += ".desktop";
+
+ KService::Ptr service = KService::serviceByStorageId( path );
+ if (!service)
+ {
+ kdWarning(780) << "Could not find module '" << module << "'." << endl;
+ return 0;
+ }
+
+ // avoid finding random non-TDE applications
+ if ( module.left( 4 ) != "kde-" && service->library().isEmpty() )
+ return locateModule( "kde-" + module );
+
+ if(!TDECModuleLoader::testModule( module ))
+ {
+ kdDebug(780) << "According to \"" << module << "\"'s test function, it should Not be loaded." << endl;
+ return 0;
+ }
+
+ return service;
+}
+
+bool KCMShell::isRunning()
+{
+ if( dcopClient()->appId() == m_dcopName )
+ return false; // We are the one and only.
+
+ kdDebug(780) << "tdecmshell with modules '" <<
+ m_dcopName << "' is already running." << endl;
+
+ dcopClient()->attach(); // Reregister as anonymous
+ dcopClient()->setNotifications(true);
+
+ TQByteArray data;
+ TQDataStream str( data, IO_WriteOnly );
+ str << kapp->startupId();
+ TQCString replyType;
+ TQByteArray replyData;
+ if (!dcopClient()->call(m_dcopName, "dialog", "activate(TQCString)",
+ data, replyType, replyData))
+ {
+ kdDebug(780) << "Calling DCOP function dialog::activate() failed." << endl;
+ return false; // Error, we have to do it ourselves.
+ }
+
+ return true;
+}
+
+KCMShellMultiDialog::KCMShellMultiDialog( int dialogFace, const TQString& caption,
+ TQWidget *parent, const char *name, bool modal)
+ : KCMultiDialog( dialogFace, caption, parent, name, modal ),
+ DCOPObject("dialog")
+{
+}
+
+void KCMShellMultiDialog::activate( TQCString asn_id )
+{
+ kdDebug(780) << k_funcinfo << endl;
+
+ KStartupInfo::setNewStartupId( this, asn_id );
+}
+
+void KCMShell::setDCOPName(const TQCString &dcopName, bool rootMode )
+{
+ m_dcopName = "tdecmshell_";
+ if( rootMode )
+ m_dcopName += "rootMode_";
+
+ m_dcopName += dcopName;
+
+ dcopClient()->registerAs(m_dcopName, false);
+}
+
+void KCMShell::waitForExit()
+{
+ kdDebug(780) << k_funcinfo << endl;
+
+ connect(dcopClient(), TQT_SIGNAL(applicationRemoved(const TQCString&)),
+ TQT_SLOT( appExit(const TQCString&) ));
+ exec();
+}
+
+void KCMShell::appExit(const TQCString &appId)
+{
+ kdDebug(780) << k_funcinfo << endl;
+
+ if( appId == m_dcopName )
+ {
+ kdDebug(780) << "'" << appId << "' closed, dereferencing." << endl;
+ deref();
+ }
+}
+
+static void setIcon(TQWidget *w, const TQString &iconName)
+{
+ TQPixmap icon = DesktopIcon(iconName);
+ TQPixmap miniIcon = SmallIcon(iconName);
+ w->setIcon( icon ); //standard X11
+#if defined Q_WS_X11 && ! defined K_WS_QTONLY
+ KWin::setIcons(w->winId(), icon, miniIcon );
+#endif
+}
+
+extern "C" KDE_EXPORT int kdemain(int _argc, char *_argv[])
+{
+ TDEAboutData aboutData( "tdecmshell", I18N_NOOP("TDE Control Module"),
+ 0,
+ I18N_NOOP("A tool to start single TDE control modules"),
+ TDEAboutData::License_GPL,
+ I18N_NOOP("(c) 1999-2004, The KDE Developers") );
+
+ aboutData.addAuthor("Frans Englich", I18N_NOOP("Maintainer"), "frans.englich@kde.org");
+ aboutData.addAuthor("Daniel Molkentin", 0, "molkentin@kde.org");
+ aboutData.addAuthor("Matthias Hoelzer-Kluepfel",0, "hoelzer@kde.org");
+ aboutData.addAuthor("Matthias Elter",0, "elter@kde.org");
+ aboutData.addAuthor("Matthias Ettrich",0, "ettrich@kde.org");
+ aboutData.addAuthor("Waldo Bastian",0, "bastian@kde.org");
+
+ TDEGlobal::locale()->setMainCatalogue("tdecmshell");
+
+ TDECmdLineArgs::init(_argc, _argv, &aboutData);
+ TDECmdLineArgs::addCmdLineOptions( options ); // Add our own options.
+ KCMShell app;
+
+ const TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs();
+
+ const TQCString lang = args->getOption("lang");
+ if( !lang.isNull() )
+ TDEGlobal::locale()->setLanguage(lang);
+
+ if (args->isSet("list"))
+ {
+ cout << static_cast<const char *>(i18n("The following modules are available:").local8Bit()) << endl;
+
+ listModules( "Settings/" );
+
+ int maxLen=0;
+
+ for( KService::List::ConstIterator it = m_modules.begin(); it != m_modules.end(); ++it)
+ {
+ int len = (*it)->desktopEntryName().length();
+ if (len > maxLen)
+ maxLen = len;
+ }
+
+ for( KService::List::ConstIterator it = m_modules.begin(); it != m_modules.end(); ++it)
+ {
+ TQString entry("%1 - %2");
+
+ entry = entry.arg((*it)->desktopEntryName().leftJustify(maxLen, ' '))
+ .arg(!(*it)->comment().isEmpty() ? (*it)->comment()
+ : i18n("No description available"));
+
+ cout << static_cast<const char *>(entry.local8Bit()) << endl;
+ }
+ return 0;
+ }
+
+ if (args->count() < 1)
+ {
+ args->usage();
+ return -1;
+ }
+
+ TQCString dcopName;
+ KService::List modules;
+ for (int i = 0; i < args->count(); i++)
+ {
+ KService::Ptr service = locateModule(args->arg(i));
+ if( service )
+ {
+ modules.append(service);
+ if( !dcopName.isEmpty() )
+ dcopName += "_";
+
+ dcopName += args->arg(i);
+ }
+ }
+
+ /* Check if this particular module combination is already running, but
+ * allow the same module to run when embedding(root mode) */
+ app.setDCOPName(dcopName,
+ ( args->isSet( "embed-proxy" ) || args->isSet( "embed" )));
+ if( app.isRunning() )
+ {
+ app.waitForExit();
+ return 0;
+ }
+
+ //KDialogBase::DialogType dtype = KDialogBase::Plain; // FIXME
+ KDialogBase::DialogType dtype = KDialogBase::IconList; // Work around a bug whereby several kcontrol modules (such as displayconfig) use an incorrect size when loaded with tdecmshell in the Plain mode
+ // This bug is possibly related to kcmultidialog.cpp:266 [( new TQHBoxLayout( page ) )->setAutoAdd( true );]
+ // In fact, this method of display may be preferable to the Plain mode from a UX perspective,
+ // as the icon shows the user what the active kcontrol module is called.
+
+ if ( modules.count() < 1 )
+ return 0;
+ else if( modules.count() > 1 )
+ dtype = KDialogBase::IconList;
+
+ bool idValid;
+ int id;
+
+ if ( args->isSet( "embed-proxy" ))
+ {
+ id = args->getOption( "embed-proxy" ).toInt(&idValid);
+ if( idValid )
+ {
+ TDECModuleProxy *module = new TDECModuleProxy( modules.first()->desktopEntryName() );
+ module->realModule();
+ QXEmbed::embedClientIntoWindow( module, id);
+ app.exec();
+ delete module;
+ }
+ else
+ kdDebug(780) << "Supplied id '" << id << "' is not valid." << endl;
+
+ return 0;
+
+ }
+
+ KCMShellMultiDialog *dlg = new KCMShellMultiDialog( dtype,
+ i18n("Configure - %1").arg(kapp->caption()), 0, "", true );
+
+ for (KService::List::ConstIterator it = modules.begin(); it != modules.end(); ++it)
+ dlg->addModule(TDECModuleInfo(*it));
+
+ if ( args->isSet( "embed" ))
+ {
+ id = args->getOption( "embed" ).toInt(&idValid);
+ if( idValid )
+ {
+ QXEmbed::embedClientIntoWindow( dlg, id );
+ dlg->exec();
+ delete dlg;
+ }
+ else
+ kdDebug(780) << "Supplied id '" << id << "' is not valid." << endl;
+
+ }
+ else
+ {
+
+ if (kapp->iconName() != kapp->name())
+ setIcon(dlg, kapp->iconName());
+ else if ( modules.count() == 1 )
+ setIcon(dlg, TDECModuleInfo( modules.first()).icon());
+
+ dlg->exec();
+ delete dlg;
+ }
+
+ return 0;
+}
+// vim: sw=4 et sts=4
diff --git a/tdecmshell/main.h b/tdecmshell/main.h
new file mode 100644
index 000000000..f135c2a33
--- /dev/null
+++ b/tdecmshell/main.h
@@ -0,0 +1,104 @@
+/*
+ Copyright (c) 2001 Waldo Bastian <bastian@kde.org>
+ Copyright (c) 2004 Frans Englich <frans.englich@telia.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef __tdecmshell_h__
+#define __tdecmshell_h__
+
+#include <dcopobject.h>
+
+#include <kapplication.h>
+#include <kcmultidialog.h>
+
+/**
+ * The TDEApplication instance for tdecmshell.
+ */
+class KCMShell : public TDEApplication
+{
+ Q_OBJECT
+
+public:
+
+ /**
+ * Sets m_dcopName basically to @p dcopName,
+ * and then registers with DCOP.
+ *
+ * @param dcopName name to set the DCOP name to
+ * @param rootMode true if the tdecmshell is embedding
+ */
+ void setDCOPName(const TQCString &dcopName, bool rootMode );
+
+ /**
+ * Waits until the last instance of tdecmshell with the same
+ * module as this one exits, and then exits.
+ */
+ void waitForExit();
+
+ /**
+ * @return true if the shell is running
+ */
+ bool isRunning();
+
+private slots:
+
+ /**
+ */
+ void appExit( const TQCString &appId );
+
+private:
+
+ /**
+ * The DCOP name which actually is registered.
+ * For example "tdecmshell_mouse".
+ */
+ TQCString m_dcopName;
+
+};
+
+
+/**
+ * Essentially a plain KCMultiDialog, but has the additional functionality
+ * of allowing it to be told to request windows focus.
+ *
+ * @author Waldo Bastian <bastian@kde.org>
+ */
+class KCMShellMultiDialog : public KCMultiDialog, public DCOPObject
+{
+ Q_OBJECT
+ K_DCOP
+
+public:
+
+ /**
+ */
+ KCMShellMultiDialog( int dialogFace, const TQString& caption,
+ TQWidget *parent=0, const char *name=0, bool modal=false);
+
+k_dcop:
+
+ /**
+ */
+ virtual void activate( TQCString asn_id );
+
+};
+
+
+// vim: sw=4 et sts=4
+#endif //__tdecmshell_h__