summaryrefslogtreecommitdiffstats
path: root/kopete/kopete/kopeteapplication.cpp
blob: d23c74f7e87358f81c250c549cd3f8b0840b0439 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
/*
    kopete.cpp

    Kopete Instant Messenger Main Class

    Copyright (c) 2001-2002  by Duncan Mac-Vicar Prett   <duncan@kde.org>
    Copyright (c) 2002-2003  by Martijn Klingens         <klingens@kde.org>

    Kopete    (c) 2001-2003  by the Kopete developers    <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * 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.                                   *
    *                                                                       *
    *************************************************************************
*/

#include "kopeteapplication.h"

#include <tqtimer.h>
#include <tqregexp.h>

#include <kconfig.h>
#include <kdebug.h>
#include <klocale.h>
#include <kcmdlineargs.h>
#include <kmessagebox.h>

#include "addaccountwizard.h"
#include "kabcpersistence.h"
#include "kopeteaccount.h"
#include "kopeteaccountmanager.h"
#include "kopetecommandhandler.h"
#include "kopetecontactlist.h"
#include "kopeteglobal.h"
#include "kopetemimesourcefactory.h"
#include "kopetemimetypehandler.h"
#include "kopetepluginmanager.h"
#include "kopeteprotocol.h"
#include "kopetestdaction.h"
#include "kopeteuiglobal.h"
#include "kopetewindow.h"
#include "kopeteprefs.h"
#include "kopeteviewmanager.h"
#include "videodevice.h"

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

KopeteApplication::KopeteApplication()
: KUniqueApplication( true, true, true )
{
	m_isShuttingDown = false;
	m_mainWindow = new KopeteWindow( 0, "mainWindow" );

	Kopete::PluginManager::self();

	Kopete::UI::Global::setMainWidget( m_mainWindow );

	/*
	 * FIXME: This is a workaround for a quite odd problem:
	 * When starting up kopete and the msn plugin gets loaded it can bring up
	 * a messagebox, in case the msg configuration is missing. This messagebox
	 * will result in a TQApplication::enter_loop() call, an event loop is
	 * created. At this point however the loop_level is 0, because this is all
	 * still inside the KopeteApplication constructor, before the exec() call from main.
	 * When the messagebox is finished the loop_level will drop down to zero and
	 * TQApplication thinks the application shuts down (this is usually the case
	 * when the loop_level goes down to zero) . So it emits aboutToQuit(), to
	 * which KApplication is connected and re-emits shutdown() , to which again
	 * KMainWindow (a KopeteWindow instance exists already) is connected. KMainWindow's
	 * shuttingDown() slot calls queryExit() which results in KopeteWindow::queryExit()
	 * calling unloadPlugins() . This of course is wrong and just shouldn't happen.
	 * The workaround is to simply delay the initialization of all this to a point
	 * where the loop_level is already > 0 . That is why I moved all the code from
	 * the constructor to the initialize() method and added this single-shot-timer
	 * setup. (Simon)
	 *
	 * Additionally, it makes the GUI appear less 'blocking' during startup, so
	 * there is a secondary benefit as well here. (Martijn)
	 */
	TQTimer::singleShot( 0, this, TQT_SLOT( slotLoadPlugins() ) );

	m_mimeFactory = new Kopete::MimeSourceFactory;
	TQMimeSourceFactory::addFactory( m_mimeFactory );

	//Create the emoticon installer
	m_emoticonHandler = new Kopete::EmoticonMimeTypeHandler;
}

KopeteApplication::~KopeteApplication()
{
	kdDebug( 14000 ) << k_funcinfo << endl;

	delete m_mainWindow;
	delete m_emoticonHandler;
	delete m_mimeFactory;
	//kdDebug( 14000 ) << k_funcinfo << "Done" << endl;
}

void KopeteApplication::slotLoadPlugins()
{
	// we have to load the address book early, because calling this enters the TQt event loop when there are remote resources.
	// The plugin manager is written with the assumption that Kopete will not reenter the event loop during plugin load,
	// otherwise lots of things break as plugins are loaded, then contacts are added to incompletely initialised MCLVIs
	Kopete::KABCPersistence::self()->addressBook();

	//Create the command handler (looks silly)
	Kopete::CommandHandler::commandHandler();

	//Create the view manager
	KopeteViewManager::viewManager();

	Kopete::AccountManager::self()->load();
	Kopete::ContactList::self()->load();

	KConfig *config = KGlobal::config();

	// Parse command-line arguments
	KCmdLineArgs *args = KCmdLineArgs::parsedArgs();

	bool showConfigDialog = false;

	config->setGroup( "Plugins" );

	/* FIXME: This is crap, if something purged that groups but your accounts
	 * are still working kopete will load the necessary plugins but still show the
	 * stupid accounts dialog (of course empty at that time because account data
	 * gets loaded later on). [mETz - 29.05.2004]
	 */
	if ( !config->hasGroup( "Plugins" ) )
		showConfigDialog = true;

	// Listen to arguments
	/*
	// TODO: conflicts with emoticon installer and the general meaning
	// of %U in kopete.desktop
	if ( args->count() > 0 )
	{
		showConfigDialog = false;
		for ( int i = 0; i < args->count(); i++ )
			Kopete::PluginManager::self()->setPluginEnabled( args->arg( i ), true );
	}
	*/

	// Prevent plugins from loading? (--disable=foo,bar)
	TQStringList disableArgs = TQStringList::split( ',', args->getOption( "disable" ) );
	for ( TQStringList::ConstIterator it = disableArgs.begin(); it != disableArgs.end(); ++it )
	{
		showConfigDialog = false;
		Kopete::PluginManager::self()->setPluginEnabled( *it, false );
	}

	// Load some plugins exclusively? (--load-plugins=foo,bar)
	if ( args->isSet( "load-plugins" ) )
	{
		config->deleteGroup( "Plugins", true );
		showConfigDialog = false;
		TQStringList plugins = TQStringList::split( ',', args->getOption( "load-plugins" ) );
		for ( TQStringList::ConstIterator it = plugins.begin(); it != plugins.end(); ++it )
			Kopete::PluginManager::self()->setPluginEnabled( *it, true );
	}

	config->sync();

	// Disable plugins altogether? (--noplugins)
	if ( !args->isSet( "plugins" ) )
	{
		// If anybody reenables this I'll get a sword and make a nice chop-suy out
		// of your body :P [mETz - 29.05.2004]
		// This screws up kopeterc because there is no way to get the Plugins group back!
		//config->deleteGroup( "Plugins", true );

		showConfigDialog = false;
		// pretend all plugins were loaded :)
		TQTimer::singleShot(0, this, TQT_SLOT( slotAllPluginsLoaded() ));
	}
	else
	{
		Kopete::PluginManager::self()->loadAllPlugins();
	}

	connect( Kopete::PluginManager::self(), TQT_SIGNAL( allPluginsLoaded() ),
		this, TQT_SLOT( slotAllPluginsLoaded() ));

	if( showConfigDialog )
	{
		// No plugins specified. Show the config dialog.
		// FIXME: Although it's a bit stupid it is theoretically possible that a user
		//        explicitly configured Kopete to not load plugins on startup. In this
		//        case we don't want this dialog. We need some other config setting
		//        like a bool hasRunKopeteBefore or so to trigger the loading of the
		//        wizard. Maybe using the last run version number is more useful even
		//        as it also allows for other features. - Martijn
		// FIXME: Possibly we need to influence the showConfigDialog bool based on the
		//        command line arguments processed below. But how exactly? - Martijn
		// NB: the command line args are completely broken atm.  
		// I don't want to fix them for 3.5 as plugin loading will change for KDE4.	- Will
		AddAccountWizard *m_addwizard = new AddAccountWizard( Kopete::UI::Global::mainWidget(), "addAccountWizard", true, true );
		m_addwizard->exec();
		Kopete::AccountManager::self()->save();
	}
}

void KopeteApplication::slotAllPluginsLoaded()
{
	KCmdLineArgs *args = KCmdLineArgs::parsedArgs();

	// --noconnect not specified?
	if ( args->isSet( "connect" )  && KopetePrefs::prefs()->autoConnect() )
		Kopete::AccountManager::self()->connectAll();


	// Handle things like '--autoconnect foo,bar --autoconnect foobar'
	QCStringList connectArgsC = args->getOptionList( "autoconnect" );
	TQStringList connectArgs;

	for ( QCStringList::ConstIterator it = connectArgsC.begin(); it != connectArgsC.end(); ++it )
	{
		TQStringList split = TQStringList::split( ',', TQString::tqfromLatin1( *it ) );

		for ( TQStringList::ConstIterator it2 = split.begin(); it2 != split.end(); ++it2 )
		{
			connectArgs.append( *it2 );
		}
	}
	
	for ( TQStringList::ConstIterator i = connectArgs.begin(); i != connectArgs.end(); ++i )
	{
		TQRegExp rx( TQString::tqfromLatin1( "([^\\|]*)\\|\\|(.*)" ) );
		rx.search( *i );
		TQString protocolId = rx.cap( 1 );
		TQString accountId = rx.cap( 2 );

		if ( accountId.isEmpty() )
		{
			if ( protocolId.isEmpty() )
				accountId = *i;
			else
				continue;
		}

		TQPtrListIterator<Kopete::Account> it( Kopete::AccountManager::self()->accounts() );
		Kopete::Account *account;
		while ( ( account = it.current() ) != 0 )
		{
			++it;

			if ( ( account->accountId() == accountId ) )
			{
				if ( protocolId.isEmpty() || account->protocol()->pluginId() == protocolId )
				{
					account->connect();
					break;
				}
			}
		}
	}

	// Parse any passed URLs/files
	handleURLArgs();
}

int KopeteApplication::newInstance()
{
//	kdDebug(14000) << k_funcinfo << endl;
	handleURLArgs();

	/**
	 * The following three lines work around a problem that
	 * Kopete has since it has multiple main windows so
	 * qapp->mainWidget() returns 0, which breaks the normal
	 * KUniqueApplication::newInstance() behavior that raises
	 * the window when we run a new instance.
	 *
	 * 1. Set the main widget to the contact list window
	 * 2. Call KUniqueApplication::newInstance()
	 * 3. Set the main widget back to 0
	 *
	 * This little workaround fixes the problem. -Matt
	 */

	setMainWidget( m_mainWindow );
	int kUnitqAppReturnCode = KUniqueApplication::newInstance();
	setMainWidget( 0L );

	return kUnitqAppReturnCode;
}

void KopeteApplication::handleURLArgs()
{
	KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
//	kdDebug(14000) << k_funcinfo << "called with " << args->count() << " arguments to handle." << endl;

	if ( args->count() > 0 )
	{
		for ( int i = 0; i < args->count(); i++ )
		{
			KURL u( args->url( i ) );
			if ( !u.isValid() )
				continue;

			Kopete::MimeTypeHandler::dispatchURL( u );
		} // END for()
	} // END args->count() > 0
}

void KopeteApplication::quitKopete()
{
	kdDebug( 14000 ) << k_funcinfo << endl;

	m_isShuttingDown = true;

	// close all windows
	TQPtrListIterator<KMainWindow> it(*KMainWindow::memberList);
	for (it.toFirst(); it.current(); ++it)
	{
		if ( !it.current()->close() )
		{
			m_isShuttingDown = false;
			break;
		}
	}
}


void KopeteApplication::commitData( TQSessionManager &sm )
{
	m_isShuttingDown = true;
	KUniqueApplication::commitData( sm );
}

#include "kopeteapplication.moc"
// vim: set noet ts=4 sts=4 sw=4: