diff options
Diffstat (limited to 'tdecmshell')
-rw-r--r-- | tdecmshell/CMakeLists.txt | 41 | ||||
-rw-r--r-- | tdecmshell/Makefile.am | 39 | ||||
-rw-r--r-- | tdecmshell/main.cpp | 350 | ||||
-rw-r--r-- | tdecmshell/main.h | 104 |
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__ |