4 Kopete Instant Messenger Main Class
6 Copyright (c) 2001-2002 by Duncan Mac-Vicar Prett <duncan@kde.org>
7 Copyright (c) 2002-2003 by Martijn Klingens <klingens@kde.org>
9 Kopete (c) 2001-2003 by the Kopete developers <kopete-devel@kde.org>
11 *************************************************************************
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * (at your option) any later version. *
18 *************************************************************************
21 #include "kopeteapplication.h"
30 #include <kcmdlineargs.h>
31 #include <kmessagebox.h>
32 #include <solid/networking.h>
34 #include "addaccountwizard.h"
35 #include "kabcpersistence.h"
36 #include "kopeteaccount.h"
37 #include "kopeteaccountmanager.h"
38 #include "kopetebehaviorsettings.h"
39 #include "kopetecommandhandler.h"
40 #include "kopetecontactlist.h"
41 #include "kopeteglobal.h"
42 #include "kopetefileengine.h"
43 #include "kopetemimetypehandler.h"
44 #include "kopetepluginmanager.h"
45 #include "kopeteprotocol.h"
46 #include "kopetestdaction.h"
47 #include "kopeteuiglobal.h"
48 #include "kopetewindow.h"
49 #include "kopeteviewmanager.h"
50 #include "kopeteidentitymanager.h"
51 #include "kopetedbusinterface.h"
53 KopeteApplication::KopeteApplication()
54 : KUniqueApplication( true, true )
56 setQuitOnLastWindowClosed( false );
57 m_isShuttingDown
= false;
59 //Create the identity manager
60 Kopete::IdentityManager::self()->load();
62 m_mainWindow
= new KopeteWindow( 0 );
64 Kopete::PluginManager::self();
66 Kopete::UI::Global::setMainWidget( m_mainWindow
);
69 * FIXME: This is a workaround for a quite odd problem:
70 * When starting up kopete and the msn plugin gets loaded it can bring up
71 * a messagebox, in case the msg configuration is missing. This messagebox
72 * will result in a QApplication::enter_loop() call, an event loop is
73 * created. At this point however the loop_level is 0, because this is all
74 * still inside the KopeteApplication constructor, before the exec() call from main.
75 * When the messagebox is finished the loop_level will drop down to zero and
76 * QApplication thinks the application shuts down (this is usually the case
77 * when the loop_level goes down to zero) . So it emits aboutToQuit(), to
78 * which KApplication is connected and re-emits shutdown() , to which again
79 * KXmlGuiWindow (a KopeteWindow instance exists already) is connected. KXmlGuiWindow's
80 * shuttingDown() slot calls queryExit() which results in KopeteWindow::queryExit()
81 * calling unloadPlugins() . This of course is wrong and just shouldn't happen.
82 * The workaround is to simply delay the initialization of all this to a point
83 * where the loop_level is already > 0 . That is why I moved all the code from
84 * the constructor to the initialize() method and added this single-shot-timer
87 * Additionally, it makes the GUI appear less 'blocking' during startup, so
88 * there is a secondary benefit as well here. (Martijn)
90 QTimer::singleShot( 0, this, SLOT( slotLoadPlugins() ) );
92 m_fileEngineHandler
= new Kopete::FileEngineHandler();
94 //Create the emoticon installer
95 m_emoticonHandler
= new Kopete::EmoticonMimeTypeHandler
;
97 //Create the DBus interface for org.kde.kopete
98 new KopeteDBusInterface(this);
101 KopeteApplication::~KopeteApplication()
105 delete m_fileEngineHandler
;
106 delete m_emoticonHandler
;
107 //kDebug( 14000 ) << "Done";
110 void KopeteApplication::slotLoadPlugins()
112 // we have to load the address book early, because calling this enters the Qt event loop when there are remote resources.
113 // The plugin manager is written with the assumption that Kopete will not reenter the event loop during plugin load,
114 // otherwise lots of things break as plugins are loaded, then contacts are added to incompletely initialised MCLVIs
115 Kopete::KABCPersistence::self()->addressBook();
117 //Create the command handler (looks silly)
118 Kopete::CommandHandler::commandHandler();
120 //Create the view manager
121 KopeteViewManager::viewManager();
123 // the account manager should be created after the identity manager is created
124 Kopete::AccountManager::self()->load();
125 Kopete::ContactList::self()->load();
127 KSharedConfig::Ptr config
= KGlobal::config();
129 // Parse command-line arguments
130 KCmdLineArgs
*args
= KCmdLineArgs::parsedArgs();
132 bool showConfigDialog
= false;
134 KConfigGroup pluginsGroup
= config
->group( "Plugins" );
136 /* FIXME: This is crap, if something purged that groups but your accounts
137 * are still working kopete will load the necessary plugins but still show the
138 * stupid accounts dialog (of course empty at that time because account data
139 * gets loaded later on). [mETz - 29.05.2004]
141 if ( !pluginsGroup
.exists() )
142 showConfigDialog
= true;
144 // Listen to arguments
146 // TODO: conflicts with emoticon installer and the general meaning
147 // of %U in kopete.desktop
148 if ( args->count() > 0 )
150 showConfigDialog = false;
151 for ( int i = 0; i < args->count(); i++ )
152 Kopete::PluginManager::self()->setPluginEnabled( args->arg( i ), true );
156 // Prevent plugins from loading? (--disable=foo,bar)
157 foreach ( const QString
&disableArg
, args
->getOption( "disable" ).split( ',' ))
159 showConfigDialog
= false;
160 Kopete::PluginManager::self()->setPluginEnabled( disableArg
, false );
163 // Load some plugins exclusively? (--load-plugins=foo,bar)
164 if ( args
->isSet( "load-plugins" ) )
166 pluginsGroup
.deleteGroup( KConfigBase::Global
);
167 showConfigDialog
= false;
168 foreach ( const QString
&plugin
, args
->getOption( "load-plugins" ).split( ',' ))
169 Kopete::PluginManager::self()->setPluginEnabled( plugin
, true );
174 // Disable plugins altogether? (--noplugins)
175 if ( !args
->isSet( "plugins" ) )
177 // If anybody reenables this I'll get a sword and make a nice chop-suy out
178 // of your body :P [mETz - 29.05.2004]
179 // This screws up kopeterc because there is no way to get the Plugins group back!
180 //config->deleteGroup( "Plugins", true );
182 showConfigDialog
= false;
183 // pretend all plugins were loaded :)
184 QTimer::singleShot(0, this, SLOT( slotAllPluginsLoaded() ));
188 Kopete::PluginManager::self()->loadAllPlugins();
191 connect( Kopete::PluginManager::self(), SIGNAL( allPluginsLoaded() ),
192 this, SLOT( slotAllPluginsLoaded() ));
194 if( showConfigDialog
)
196 // No plugins specified. Show the config dialog.
197 // FIXME: Although it's a bit stupid it is theoretically possible that a user
198 // explicitly configured Kopete to not load plugins on startup. In this
199 // case we don't want this dialog. We need some other config setting
200 // like a bool hasRunKopeteBefore or so to trigger the loading of the
201 // wizard. Maybe using the last run version number is more useful even
202 // as it also allows for other features. - Martijn
203 // FIXME: Possibly we need to influence the showConfigDialog bool based on the
204 // command line arguments processed below. But how exactly? - Martijn
205 // NB: the command line args are completely broken atm.
206 // I don't want to fix them for 3.5 as plugin loading will change for KDE4. - Will
207 AddAccountWizard
*m_addwizard
= new AddAccountWizard( Kopete::UI::Global::mainWidget(), true );
209 Kopete::AccountManager::self()->save();
214 void KopeteApplication::slotAllPluginsLoaded()
216 KCmdLineArgs
*args
= KCmdLineArgs::parsedArgs();
218 //FIXME: this should probably ask for the identities to connect instead of all accounts
219 // --noconnect not specified?
221 Kopete::OnlineStatusManager::Category initStatus
= Kopete::OnlineStatusManager::self()->initialStatus();
223 if ( args
->isSet( "connect" ) && initStatus
!= Kopete::OnlineStatusManager::Offline
&&
224 ( Solid::Networking::status() == Solid::Networking::Unknown
||
225 Solid::Networking::status() == Solid::Networking::Connected
) ){
227 Kopete::AccountManager::self()->setOnlineStatus( initStatus
, QString(), Kopete::AccountManager::ConnectIfOffline
);
231 kDebug(14000)<< "initial status set in config: " << initStatus
;
233 QStringList connectArgs
= args
->getOptionList( "autoconnect" );
235 // toConnect will contain all the protocols to connect to
236 QStringList toConnect
;
238 for ( QStringList::ConstIterator i
= connectArgs
.constBegin(); i
!= connectArgs
.constEnd(); ++i
)
240 foreach ( const QString
&connectArg
, (*i
).split(','))
241 toConnect
.append( connectArg
);
244 for ( QStringList::ConstIterator i
= toConnect
.constBegin(); i
!= toConnect
.constEnd(); ++i
)
246 QRegExp
rx( QLatin1String( "([^\\|]*)\\|\\|(.*)" ) );
248 QString protocolId
= rx
.cap( 1 );
249 QString accountId
= rx
.cap( 2 );
251 if ( accountId
.isEmpty() )
253 if ( protocolId
.isEmpty() )
259 QListIterator
<Kopete::Account
*> it( Kopete::AccountManager::self()->accounts() );
260 Kopete::Account
*account
;
261 while ( it
.hasNext() )
264 if ( ( account
->accountId() == accountId
) )
266 if ( protocolId
.isEmpty() || account
->protocol()->pluginId() == protocolId
)
275 // Parse any passed URLs/files
281 int KopeteApplication::newInstance()
286 return KUniqueApplication::newInstance();
289 void KopeteApplication::handleURLArgs()
291 KCmdLineArgs
*args
= KCmdLineArgs::parsedArgs();
292 // kDebug(14000) << "called with " << args->count() << " arguments to handle.";
294 if ( args
->count() > 0 )
296 for ( int i
= 0; i
< args
->count(); i
++ )
298 KUrl
u( args
->url( i
) );
302 Kopete::MimeTypeHandler::dispatchURL( u
);
304 } // END args->count() > 0
308 void KopeteApplication::quitKopete()
312 m_isShuttingDown
= true;
315 QList
<KMainWindow
*> members
= KMainWindow::memberList();
316 QList
<KMainWindow
*>::iterator it
, itEnd
= members
.end();
317 for ( it
= members
.begin(); it
!= itEnd
; ++it
)
319 if ( !(*it
)->close() )
321 m_isShuttingDown
= false;
326 if ( m_isShuttingDown
&& m_mainWindow
)
328 m_mainWindow
->deleteLater();
334 void KopeteApplication::commitData( QSessionManager
&sm
)
336 m_isShuttingDown
= true;
337 KUniqueApplication::commitData( sm
);
340 #include "kopeteapplication.moc"
341 // vim: set noet ts=4 sts=4 sw=4: