main.cpp
00001 /* 00002 Copyright (c) 1999 Matthias Hoelzer-Kluepfel <hoelzer@kde.org> 00003 Copyright (c) 2000 Matthias Elter <elter@kde.org> 00004 Copyright (c) 2004 Frans Englich <frans.englich@telia.com> 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program; if not, write to the Free Software 00018 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 00020 */ 00021 00022 #include <iostream> 00023 00024 #include <tqcstring.h> 00025 #include <tqfile.h> 00026 00027 #include <dcopclient.h> 00028 #include <qxembed.h> 00029 00030 #include <kaboutdata.h> 00031 #include <kapplication.h> 00032 #include <kcmdlineargs.h> 00033 #include <kcmoduleinfo.h> 00034 #include <kcmoduleloader.h> 00035 #include <kcmoduleproxy.h> 00036 #include <kcmultidialog.h> 00037 #include <kdebug.h> 00038 #include <kdialogbase.h> 00039 #include <kiconloader.h> 00040 #include <klocale.h> 00041 #include <kservice.h> 00042 #include <kservicegroup.h> 00043 #include <kstartupinfo.h> 00044 #include <kwin.h> 00045 #include <kglobal.h> 00046 00047 #include "main.h" 00048 #include "main.moc" 00049 00050 using namespace std; 00051 00052 KService::List m_modules; 00053 00054 static KCmdLineOptions options[] = 00055 { 00056 { "list", I18N_NOOP("List all possible modules"), 0}, 00057 { "+module", I18N_NOOP("Configuration module to open"), 0 }, 00058 { "lang <language>", I18N_NOOP("Specify a particular language"), 0 }, 00059 { "embed <id>", I18N_NOOP("Embeds the module with buttons in window with id <id>"), 0 }, 00060 { "embed-proxy <id>", I18N_NOOP("Embeds the module without buttons in window with id <id>"), 0 }, 00061 { "silent", I18N_NOOP("Do not display main window"), 0 }, 00062 KCmdLineLastOption 00063 }; 00064 00065 static void listModules(const TQString &baseGroup) 00066 { 00067 00068 KServiceGroup::Ptr group = KServiceGroup::group(baseGroup); 00069 00070 if (!group || !group->isValid()) 00071 return; 00072 00073 KServiceGroup::List list = group->entries(true, true); 00074 00075 for( KServiceGroup::List::ConstIterator it = list.begin(); 00076 it != list.end(); it++) 00077 { 00078 KSycocaEntry *p = (*it); 00079 if (p->isType(KST_KService)) 00080 { 00081 KService *s = static_cast<KService*>(p); 00082 if (!kapp->authorizeControlModule(s->menuId())) 00083 continue; 00084 m_modules.append(s); 00085 } 00086 else if (p->isType(KST_KServiceGroup)) 00087 listModules(p->entryPath()); 00088 } 00089 } 00090 00091 static KService::Ptr locateModule(const TQCString& module) 00092 { 00093 TQString path = TQFile::decodeName(module); 00094 00095 if (!path.endsWith(".desktop")) 00096 path += ".desktop"; 00097 00098 KService::Ptr service = KService::serviceByStorageId( path ); 00099 if (!service) 00100 { 00101 kdWarning(780) << "Could not find module '" << module << "'." << endl; 00102 return 0; 00103 } 00104 00105 // avoid finding random non-kde applications 00106 if ( module.left( 4 ) != "kde-" && service->library().isEmpty() ) 00107 return locateModule( "kde-" + module ); 00108 00109 if(!KCModuleLoader::testModule( module )) 00110 { 00111 kdDebug(780) << "According to \"" << module << "\"'s test function, it should Not be loaded." << endl; 00112 return 0; 00113 } 00114 00115 return service; 00116 } 00117 00118 bool KCMShell::isRunning() 00119 { 00120 if( dcopClient()->appId() == m_dcopName ) 00121 return false; // We are the one and only. 00122 00123 kdDebug(780) << "kcmshell with modules '" << 00124 m_dcopName << "' is already running." << endl; 00125 00126 dcopClient()->attach(); // Reregister as anonymous 00127 dcopClient()->setNotifications(true); 00128 00129 TQByteArray data; 00130 TQDataStream str( data, IO_WriteOnly ); 00131 str << kapp->startupId(); 00132 TQCString replyType; 00133 TQByteArray replyData; 00134 if (!dcopClient()->call(m_dcopName, "dialog", "activate(TQCString)", 00135 data, replyType, replyData)) 00136 { 00137 kdDebug(780) << "Calling DCOP function dialog::activate() failed." << endl; 00138 return false; // Error, we have to do it ourselves. 00139 } 00140 00141 return true; 00142 } 00143 00144 KCMShellMultiDialog::KCMShellMultiDialog( int dialogFace, const TQString& caption, 00145 TQWidget *parent, const char *name, bool modal) 00146 : KCMultiDialog( dialogFace, caption, parent, name, modal ), 00147 DCOPObject("dialog") 00148 { 00149 } 00150 00151 void KCMShellMultiDialog::activate( TQCString asn_id ) 00152 { 00153 kdDebug(780) << k_funcinfo << endl; 00154 00155 KStartupInfo::setNewStartupId( this, asn_id ); 00156 } 00157 00158 void KCMShell::setDCOPName(const TQCString &dcopName, bool rootMode ) 00159 { 00160 m_dcopName = "kcmshell_"; 00161 if( rootMode ) 00162 m_dcopName += "rootMode_"; 00163 00164 m_dcopName += dcopName; 00165 00166 dcopClient()->registerAs(m_dcopName, false); 00167 } 00168 00169 void KCMShell::waitForExit() 00170 { 00171 kdDebug(780) << k_funcinfo << endl; 00172 00173 connect(dcopClient(), TQT_SIGNAL(applicationRemoved(const TQCString&)), 00174 TQT_SLOT( appExit(const TQCString&) )); 00175 exec(); 00176 } 00177 00178 void KCMShell::appExit(const TQCString &appId) 00179 { 00180 kdDebug(780) << k_funcinfo << endl; 00181 00182 if( appId == m_dcopName ) 00183 { 00184 kdDebug(780) << "'" << appId << "' closed, dereferencing." << endl; 00185 deref(); 00186 } 00187 } 00188 00189 static void setIcon(TQWidget *w, const TQString &iconName) 00190 { 00191 TQPixmap icon = DesktopIcon(iconName); 00192 TQPixmap miniIcon = SmallIcon(iconName); 00193 w->setIcon( icon ); //standard X11 00194 #if defined Q_WS_X11 && ! defined K_WS_QTONLY 00195 KWin::setIcons(w->winId(), icon, miniIcon ); 00196 #endif 00197 } 00198 00199 extern "C" KDE_EXPORT int kdemain(int _argc, char *_argv[]) 00200 { 00201 KAboutData aboutData( "kcmshell", I18N_NOOP("KDE Control Module"), 00202 0, 00203 I18N_NOOP("A tool to start single KDE control modules"), 00204 KAboutData::License_GPL, 00205 I18N_NOOP("(c) 1999-2004, The KDE Developers") ); 00206 00207 aboutData.addAuthor("Frans Englich", I18N_NOOP("Maintainer"), "frans.englich@kde.org"); 00208 aboutData.addAuthor("Daniel Molkentin", 0, "molkentin@kde.org"); 00209 aboutData.addAuthor("Matthias Hoelzer-Kluepfel",0, "hoelzer@kde.org"); 00210 aboutData.addAuthor("Matthias Elter",0, "elter@kde.org"); 00211 aboutData.addAuthor("Matthias Ettrich",0, "ettrich@kde.org"); 00212 aboutData.addAuthor("Waldo Bastian",0, "bastian@kde.org"); 00213 00214 KGlobal::locale()->setMainCatalogue("kcmshell"); 00215 00216 KCmdLineArgs::init(_argc, _argv, &aboutData); 00217 KCmdLineArgs::addCmdLineOptions( options ); // Add our own options. 00218 KCMShell app; 00219 00220 const KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); 00221 00222 const TQCString lang = args->getOption("lang"); 00223 if( !lang.isNull() ) 00224 KGlobal::locale()->setLanguage(lang); 00225 00226 if (args->isSet("list")) 00227 { 00228 cout << static_cast<const char *>(i18n("The following modules are available:").local8Bit()) << endl; 00229 00230 listModules( "Settings/" ); 00231 00232 int maxLen=0; 00233 00234 for (KService::List::ConstIterator it = m_modules.begin(); it != m_modules.end(); ++it) 00235 { 00236 int len = (*it)->desktopEntryName().length(); 00237 if (len > maxLen) 00238 maxLen = len; 00239 } 00240 00241 TQStringList module_list; 00242 for (KService::List::ConstIterator it = m_modules.begin(); it != m_modules.end(); ++it) 00243 { 00244 module_list.append(TQString("%1 - %2") 00245 .arg((*it)->desktopEntryName().leftJustify(maxLen, ' ')) 00246 .arg(!(*it)->comment().isEmpty() ? (*it)->comment() : i18n("No description available"))); 00247 } 00248 module_list.sort(); 00249 00250 for (TQStringList::Iterator it=module_list.begin(); it!=module_list.end(); ++it) 00251 { 00252 cout << static_cast<const char *>((*it).local8Bit()) << endl; 00253 } 00254 return 0; 00255 } 00256 00257 if (args->count() < 1) 00258 { 00259 args->usage(); 00260 return -1; 00261 } 00262 00263 TQCString dcopName; 00264 KService::List modules; 00265 for (int i = 0; i < args->count(); i++) 00266 { 00267 KService::Ptr service = locateModule(args->arg(i)); 00268 if( service ) 00269 { 00270 modules.append(service); 00271 if( !dcopName.isEmpty() ) 00272 dcopName += "_"; 00273 00274 dcopName += args->arg(i); 00275 } 00276 } 00277 00278 /* Check if this particular module combination is already running, but 00279 * allow the same module to run when embedding(root mode) */ 00280 app.setDCOPName(dcopName, 00281 ( args->isSet( "embed-proxy" ) || args->isSet( "embed" ))); 00282 if( app.isRunning() ) 00283 { 00284 app.waitForExit(); 00285 return 0; 00286 } 00287 00288 KDialogBase::DialogType dtype = KDialogBase::Plain; 00289 00290 if ( modules.count() < 1 ) 00291 return 0; 00292 else if( modules.count() > 1 ) 00293 dtype = KDialogBase::IconList; 00294 00295 bool idValid; 00296 int id; 00297 00298 if ( args->isSet( "embed-proxy" )) 00299 { 00300 id = args->getOption( "embed-proxy" ).toInt(&idValid); 00301 if( idValid ) 00302 { 00303 KCModuleProxy *module = new KCModuleProxy( modules.first()->desktopEntryName() ); 00304 module->realModule(); 00305 QXEmbed::embedClientIntoWindow( module, id); 00306 app.exec(); 00307 delete module; 00308 } 00309 else 00310 kdDebug(780) << "Supplied id '" << id << "' is not valid." << endl; 00311 00312 return 0; 00313 00314 } 00315 00316 KCMShellMultiDialog *dlg = new KCMShellMultiDialog( dtype, 00317 i18n("Configure - %1").arg(kapp->caption()), 0, "", true ); 00318 00319 for (KService::List::ConstIterator it = modules.begin(); it != modules.end(); ++it) 00320 dlg->addModule(KCModuleInfo(*it)); 00321 00322 if ( args->isSet( "embed" )) 00323 { 00324 id = args->getOption( "embed" ).toInt(&idValid); 00325 if( idValid ) 00326 { 00327 QXEmbed::embedClientIntoWindow( dlg, id ); 00328 dlg->exec(); 00329 delete dlg; 00330 } 00331 else 00332 kdDebug(780) << "Supplied id '" << id << "' is not valid." << endl; 00333 00334 } 00335 else 00336 { 00337 00338 if (kapp->iconName() != kapp->name()) 00339 setIcon(dlg, kapp->iconName()); 00340 else if ( modules.count() == 1 ) 00341 setIcon(dlg, KCModuleInfo( modules.first()).icon()); 00342 00343 dlg->exec(); 00344 delete dlg; 00345 } 00346 00347 return 0; 00348 } 00349 // vim: sw=4 et sts=4