kontact Library API Documentation

uniqueapphandler.cpp

00001 /*
00002    This file is part of KDE Kontact.
00003 
00004    Copyright (c) 2003 David Faure <faure@kde.org>
00005 
00006    This library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Library General Public
00008    License as published by the Free Software Foundation; either
00009    version 2 of the License, or (at your option) any later version.
00010 
00011    This library 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 GNU
00014    Library General Public License for more details.
00015 
00016    You should have received a copy of the GNU Library General Public License
00017    along with this library; see the file COPYING.LIB.  If not, write to
00018    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00019    Boston, MA 02111-1307, USA.
00020 */
00021 
00022 #include "uniqueapphandler.h"
00023 #include <kstartupinfo.h>
00024 #include <kapplication.h>
00025 #include <kcmdlineargs.h>
00026 #include "core.h"
00027 #include <kwin.h>
00028 #include <dcopclient.h>
00029 #include <kdebug.h>
00030 
00031 /*
00032  Test plan for the various cases of interaction between standalone apps and kontact:
00033 
00034  1) start kontact, select "Mail".
00035  1a) type "korganizer" -> it switches to korganizer
00036  1b) type "kmail" -> it switches to kmail
00037  1c) type "kaddressbook" -> it switches to kaddressbook
00038  1d) type "kmail foo@kde.org" -> it opens a kmail composer, without switching
00039  1e) type "knode" -> it switches to knode
00040  1f) type "kaddressbook --new-contact" -> it opens a kaddressbook contact window
00041  1g) type "knode news://foobar/group" -> it pops up "can't resolve hostname"
00042 
00043  2) close kontact. Launch kmail. Launch kontact again.
00044  2a) click "Mail" icon -> kontact doesn't load a part, but activates the kmail window
00045  2b) type "kmail foo@kde.org" -> standalone kmail opens composer.
00046  2c) close kmail, click "Mail" icon -> kontact loads the kmail part.
00047  2d) type "kmail" -> kontact is brought to front
00048 
00049  3) close kontact. Launch korganizer, then kontact.
00050  3a) both Todo and Calendar activate the running korganizer.
00051  3b) type "korganizer" -> standalone korganizer is brought to front
00052  3c) close korganizer, click Calendar or Todo -> kontact loads part.
00053  3d) type "korganizer" -> kontact is brought to front
00054 
00055  4) close kontact. Launch kaddressbook, then kontact.
00056  4a) "Contacts" icon activate the running kaddressbook.
00057  4b) type "kaddressbook" -> standalone kaddressbook is brought to front
00058  4c) close kaddressbook, type "kaddressbook -a foo@kde.org" -> kontact loads part and opens editor
00059  4d) type "kaddressbook" -> kontact is brought to front
00060 
00061  5) close kontact. Launch knode, then kontact.
00062  5a) "News" icon activate the running knode.
00063  5b) type "knode" -> standalone knode is brought to front
00064  5c) close knode, type "knode news://foobar/group" -> kontact loads knode and pops up msgbox
00065  5d) type "knode" -> kontact is brought to front
00066 
00067 */
00068 
00069 namespace Kontact {
00070 
00071 int UniqueAppHandler::newInstance()
00072 {
00073     // This bit is duplicated from KUniqueApplication::newInstance()
00074     if ( kapp->mainWidget() )
00075     {
00076       kapp->mainWidget()->show();
00077       KWin::forceActiveWindow( kapp->mainWidget()->winId() );
00078       KStartupInfo::appStarted();
00079     }
00080 
00081     // Then ensure the part appears in kontact
00082     mPlugin->core()->selectPlugin( mPlugin );
00083     return 0;
00084 }
00085 
00086 bool UniqueAppHandler::process(const QCString &fun, const QByteArray &data, QCString& replyType, QByteArray &replyData)
00087 {
00088     if ( fun == "newInstance()" ) {
00089        replyType = "int";
00090 
00091        KCmdLineArgs::reset(); // forget options defined by other "applications"
00092        loadCommandLineOptions();
00093 
00094        // This bit is duplicated from KUniqueApplication::processDelayed()
00095        QDataStream ds(data, IO_ReadOnly);
00096        KCmdLineArgs::loadAppArgs(ds);
00097        if( !ds.atEnd()) // backwards compatibility
00098        {
00099            QCString asn_id;
00100            ds >> asn_id;
00101            kapp->setStartupId( asn_id );
00102        }
00103 
00104        QDataStream _replyStream( replyData, IO_WriteOnly );
00105        _replyStream << newInstance( );
00106     } else {
00107         return DCOPObject::process( fun, data, replyType, replyData );
00108     }
00109     return true;
00110 }
00111 
00112 QCStringList UniqueAppHandler::interfaces()
00113 {
00114     QCStringList ifaces = DCOPObject::interfaces();
00115     ifaces += "Kontact::UniqueAppHandler";
00116     return ifaces;
00117 }
00118 
00119 QCStringList UniqueAppHandler::functions()
00120 {
00121     QCStringList funcs = DCOPObject::functions();
00122     funcs << "int newInstance()";
00123     return funcs;
00124 }
00125 
00126 UniqueAppWatcher::UniqueAppWatcher( UniqueAppHandlerFactoryBase* factory, Plugin* plugin )
00127     : QObject( plugin ), mFactory( factory ), mPlugin( plugin )
00128 {
00129     // The app is running standalone if 1) that name is known to DCOP
00130     mRunningStandalone = kapp->dcopClient()->isApplicationRegistered( plugin->name() );
00131     // and 2) it's not registered by kontact (e.g. in another plugin)
00132     if ( mRunningStandalone && kapp->dcopClient()->findLocalClient( plugin->name() ) )
00133         mRunningStandalone = false;
00134 
00135     if ( mRunningStandalone ) {
00136         kapp->dcopClient()->setNotifications( true );
00137         connect( kapp->dcopClient(), SIGNAL( applicationRemoved( const QCString&)),
00138                  this, SLOT( unregisteredFromDCOP( const QCString& )) );
00139     } else {
00140         mFactory->createHandler( mPlugin );
00141     }
00142 }
00143 
00144 UniqueAppWatcher::~UniqueAppWatcher()
00145 {
00146     if ( mRunningStandalone )
00147         kapp->dcopClient()->setNotifications( false );
00148     delete mFactory;
00149 }
00150 
00151 void UniqueAppWatcher::unregisteredFromDCOP( const QCString& appId )
00152 {
00153     if ( appId == mPlugin->name() && mRunningStandalone ) {
00154         disconnect( kapp->dcopClient(), SIGNAL( applicationRemoved( const QCString&)),
00155                     this, SLOT( unregisteredFromDCOP( const QCString& )) );
00156         kdDebug() << k_funcinfo << appId << endl;
00157         mFactory->createHandler( mPlugin );
00158         kapp->dcopClient()->setNotifications( false );
00159         mRunningStandalone = false;
00160     }
00161 }
00162 
00163 } // namespace
00164 
00165 #include "uniqueapphandler.moc"
KDE Logo
This file is part of the documentation for kontact Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat May 1 11:39:00 2004 by doxygen 1.2.15 written by Dimitri van Heesch, © 1997-2003