diff --git a/kopete/kopeteapplication.cpp b/kopete/kopeteapplication.cpp index cc04d0153..36c727b33 100644 --- a/kopete/kopeteapplication.cpp +++ b/kopete/kopeteapplication.cpp @@ -1,391 +1,393 @@ /* kopete.cpp Kopete Instant Messenger Main Class Copyright (c) 2001-2002 by Duncan Mac-Vicar Prett Copyright (c) 2002-2003 by Martijn Klingens Kopete (c) 2001-2003 by the Kopete developers ************************************************************************* * * * 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 #include #include #include #include #include #include #include #include "addaccountwizard.h" #include "kabcpersistence.h" #include "kopeteaccount.h" #include "kopeteaccountmanager.h" #include "kopetestatusmanager.h" #include "kopetestatusitems.h" #include "kopetebehaviorsettings.h" #include "kopetecommandhandler.h" #include "kopetecontactlist.h" #include "kopeteglobal.h" //#include "kopetefileengine.h" #include "kopetemimetypehandler.h" #include "kopetepluginmanager.h" #include "kopeteprotocol.h" #include "kopetestdaction.h" #include "kopeteuiglobal.h" #include "kopetewindow.h" #include "kopeteviewmanager.h" #include "kopeteidentitymanager.h" #include "kopetedbusinterface.h" KopeteApplication::KopeteApplication(int &argc, char *argv[]) - : QApplication(argc, argv) + : QApplication(argc, argv), + m_isShuttingDown(false) { - m_isShuttingDown = false; - KLocalizedString::setApplicationDomain("kopete"); +} +void KopeteApplication::initializeUI() +{ //Create the identity manager Kopete::IdentityManager::self()->load(); m_mainWindow = new KopeteWindow(0); 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 QApplication::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 * QApplication 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 * KXmlGuiWindow (a KopeteWindow instance exists already) is connected. KXmlGuiWindow'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) */ QTimer::singleShot(0, this, SLOT(slotLoadPlugins())); //NOTE : QAbstractFileEngine and QAbstractFileEngineHandler deprecated in Qt5 //m_fileEngineHandler = new Kopete::FileEngineHandler(); //Create the emoticon installer m_emoticonHandler = new Kopete::EmoticonMimeTypeHandler; //Create the DBus interface for org.kde.kopete new KopeteDBusInterface(this); } KopeteApplication::~KopeteApplication() { kDebug(14000); if (!m_isShuttingDown) { // destruct was called without proper shutdown, dbus quit maybe? m_isShuttingDown = true; // close all windows QList members = KMainWindow::memberList(); QList::iterator it, itEnd = members.end(); for (it = members.begin(); it != itEnd; ++it) { (*it)->close(); } // destroy all plugins until KopeteApplication is alive Kopete::PluginList list = Kopete::PluginManager::self()->loadedPlugins(); foreach (Kopete::Plugin *plugin, list) { delete plugin; } // shutdown plugin manager Kopete::PluginManager::self()->shutdown(); } //delete m_fileEngineHandler; delete m_emoticonHandler; //kDebug( 14000 ) << "Done"; } void KopeteApplication::slotLoadPlugins() { // we have to load the address book early, because calling this enters the Qt 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(); // the account manager should be created after the identity manager is created Kopete::AccountManager::self()->load(); Kopete::ContactList::self()->load(); KSharedConfig::Ptr config = KSharedConfig::openConfig(); // Parse command-line arguments //FIXME KF5 KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); bool showConfigDialog = false; KConfigGroup pluginsGroup = config->group("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 (!pluginsGroup.exists()) { 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) #if 0//FIXME KF5 foreach (const QString &disableArg, args->getOption("disable").split(',')) { showConfigDialog = false; Kopete::PluginManager::self()->setPluginEnabled(disableArg, false); } // Load some plugins exclusively? (--load-plugins=foo,bar) if (args->isSet("load-plugins")) { pluginsGroup.deleteGroup(KConfigBase::Global); showConfigDialog = false; foreach (const QString &plugin, args->getOption("load-plugins").split(',')) { Kopete::PluginManager::self()->setPluginEnabled(plugin, true); } } #endif config->sync(); // Disable plugins altogether? (--noplugins) if (/*!args->isSet("plugins")*/0) { //KF5 FIXME // 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 :) QTimer::singleShot(0, this, SLOT(slotAllPluginsLoaded())); } else { Kopete::PluginManager::self()->loadAllPlugins(); } connect(Kopete::PluginManager::self(), SIGNAL(allPluginsLoaded()), this, 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(), true); m_addwizard->exec(); Kopete::AccountManager::self()->save(); } } void KopeteApplication::slotAllPluginsLoaded() { //FIXME KF5 KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); //FIXME: this should probably ask for the identities to connect instead of all accounts // --noconnect not specified? Kopete::OnlineStatusManager::Category initStatus = Kopete::OnlineStatusManager::self()->initialStatus(); Kopete::OnlineStatusManager::Category setStatus = Kopete::OnlineStatusManager::Offline; #if 0 //FIXME if (args->isSet("connect") && initStatus != Kopete::OnlineStatusManager::Offline && (Solid::Networking::status() == Solid::Networking::Unknown || Solid::Networking::status() == Solid::Networking::Connected)) { setStatus = initStatus; } #endif QList statusList = Kopete::StatusManager::self()->getRootGroup()->childList(); QString message, title; bool found = false; //find first Status for OnlineStatus for (QList ::ConstIterator it = statusList.constBegin(); it != statusList.constEnd(); ++it) { if (!(*it)->isGroup() && (*it)->category() == setStatus) { title = (*it)->title(); message = (static_cast (*it))->message(); //if it is not group, it status found = true; break; } } if (found) { if (setStatus != Kopete::OnlineStatusManager::Offline) { Kopete::AccountManager::self()->setOnlineStatus(initStatus, Kopete::StatusMessage(title, message), Kopete::AccountManager::ConnectIfOffline); } Kopete::StatusManager::self()->setGlobalStatus(setStatus, Kopete::StatusMessage(title, message)); } else { if (setStatus != Kopete::OnlineStatusManager::Offline) { Kopete::AccountManager::self()->setOnlineStatus(initStatus, QString(), Kopete::AccountManager::ConnectIfOffline); } } kDebug(14000)<< "initial status set in config: " << initStatus; //FIXME KF5 #if 0 QStringList connectArgs = args->getOptionList("autoconnect"); // toConnect will contain all the protocols to connect to QStringList toConnect; for (QStringList::ConstIterator i = connectArgs.constBegin(); i != connectArgs.constEnd(); ++i) { foreach (const QString &connectArg, (*i).split(',')) { toConnect.append(connectArg); } } for (QStringList::ConstIterator i = toConnect.constBegin(); i != toConnect.constEnd(); ++i) { QRegExp rx(QLatin1String("([^\\|]*)\\|\\|(.*)")); rx.indexIn(*i); QString protocolId = rx.cap(1); QString accountId = rx.cap(2); if (accountId.isEmpty()) { if (protocolId.isEmpty()) { accountId = *i; } else { continue; } } QListIterator it(Kopete::AccountManager::self()->accounts()); Kopete::Account *account; while (it.hasNext()) { account = it.next(); if ((account->accountId() == accountId)) { if (protocolId.isEmpty() || account->protocol()->pluginId() == protocolId) { account->connect(); break; } } } } // Parse any passed URLs/files handleURLArgs(); #endif } #if 0 int KopeteApplication::newInstance() { // kDebug(14000) ; handleURLArgs(); return KUniqueApplication::newInstance(); } #endif void KopeteApplication::handleURLArgs() { #if 0 KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); // kDebug(14000) << "called with " << args->count() << " arguments to handle."; if (args->count() > 0) { for (int i = 0; i < args->count(); i++) { QUrl u(args->url(i)); if (!u.isValid()) { continue; } Kopete::MimeTypeHandler::dispatchURL(u); } // END for() } // END args->count() > 0 #endif } void KopeteApplication::quitKopete() { kDebug(14000); m_isShuttingDown = true; // close all windows QList members = KMainWindow::memberList(); QList::iterator it, itEnd = members.end(); for (it = members.begin(); it != itEnd; ++it) { if (!(*it)->close()) { m_isShuttingDown = false; return; } } // destroy all plugins until KopeteApplication is alive const Kopete::PluginList &list = Kopete::PluginManager::self()->loadedPlugins(); foreach (Kopete::Plugin *plugin, list) { delete plugin; } // shutdown plugin manager Kopete::PluginManager::self()->shutdown(); if (m_mainWindow) { m_mainWindow->deleteLater(); m_mainWindow = 0; } } void KopeteApplication::commitData(QSessionManager &sm) { m_isShuttingDown = true; QGuiApplication::saveStateRequest(sm); } // vim: set noet ts=4 sts=4 sw=4: diff --git a/kopete/kopeteapplication.h b/kopete/kopeteapplication.h index 45713e107..697b0f8ca 100644 --- a/kopete/kopeteapplication.h +++ b/kopete/kopeteapplication.h @@ -1,91 +1,93 @@ /* kopete.h Kopete Instant Messenger Main Class Copyright (c) 2001-2002 by Duncan Mac-Vicar Prett Kopete (c) 2002-2003 by the Kopete developers ************************************************************************* * * * 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. * * * ************************************************************************* */ #ifndef KOPETEAPPLICATION_H #define KOPETEAPPLICATION_H #include #include class KopeteWindow; class QSessionManager; namespace Kopete { class MimeTypeHandler; class FileEngineHandler; } /** * @author Duncan Mac-Vicar P. */ class KopeteApplication : public QApplication { Q_OBJECT public: KopeteApplication(int &argc, char *argv[]); ~KopeteApplication(); + void initializeUI(); + /** * Method to return whether or not we're shutting down * or not at this point. */ bool isShuttingDown() const { return m_isShuttingDown; } //FIXME int newInstance() Q_DECL_OVERRIDE; public Q_SLOTS: /** * Quit Kopete, closing all the windows, which causes application shutdown * This method marks Kopete as 'shutting down' to avoid * showing the message box that Kopete will be left running in the * system tray before calling qApp->quit(). */ void quitKopete(); virtual void commitData(QSessionManager &sm); /** * Load all plugins */ void slotLoadPlugins(); private Q_SLOTS: /** * auto-connect */ void slotAllPluginsLoaded(); private: // The main window might get deleted behind our back (W_DestructiveClose), // so use a guarded pointer QPointer m_mainWindow; bool m_isShuttingDown; Kopete::MimeTypeHandler *m_emoticonHandler; //NOTE: QAbstractFileEngine and QAbstractFileEngineHandler deprecated in Qt5 //Kopete::FileEngineHandler *m_fileEngineHandler; private: void handleURLArgs(); }; #endif // vim: set noet ts=4 sts=4 sw=4: diff --git a/kopete/main.cpp b/kopete/main.cpp index 33abe823f..def61ac74 100644 --- a/kopete/main.cpp +++ b/kopete/main.cpp @@ -1,123 +1,126 @@ /* Kopete , The KDE Instant Messenger Copyright (c) 2001-2002 by Duncan Mac-Vicar Prett Viva Chile Mierda! Started at Wed Dec 26 03:12:10 CLST 2001, Santiago de Chile Kopete (c) 2002-2008 by the Kopete developers ************************************************************************* * * * 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 #include #include #include #include #include #include #include "kopeteapplication.h" #include "kopeteversion.h" static const char description[] = I18N_NOOP("Kopete, the KDE Instant Messenger"); int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); KopeteApplication kopete(argc, argv); + KLocalizedString::setApplicationDomain("kopete"); kopete.setAttribute(Qt::AA_UseHighDpiPixmaps, true); KCrash::initialize(); KAboutData aboutData(QStringLiteral("kopete"), i18n("Kopete"), QStringLiteral(KOPETE_VERSION_STRING), i18n(description), KAboutLicense::GPL, i18n("(c) 2001-2004, Duncan Mac-Vicar Prett\n(c) 2002-2017, Kopete Development Team"), i18n("kopete-devel@kde.org"), "http://kopete.kde.org"); aboutData.addAuthor(i18n("Pali Rohár"), i18n("Developer and maintainer"), "pali.rohar@gmail.com"); aboutData.addAuthor(i18n("Laurent Montel"), i18n("Porting to KF5"), "montel@kde.org"); aboutData.addAuthor(i18n("Duncan Mac-Vicar Prett"), i18n("Developer and Project founder"), "duncan@kde.org", "http://www.mac-vicar.org/~duncan"); aboutData.addAuthor(i18n("Andre Duffeck"), i18n("Developer, Yahoo plugin maintainer"), "duffeck@kde.org"); aboutData.addAuthor(i18n("Andy Goossens"), i18n("Developer"), "andygoossens@telenet.be"); aboutData.addAuthor(i18n("Chris Howells"), i18n("Developer, Connection status plugin author"), "howells@kde.org", "http://chrishowells.co.uk"); aboutData.addAuthor(i18n("Cláudio da Silveira Pinheiro"), i18n("Developer, Video device support"), "taupter@gmail.com", "http://taupter.homelinux.org"); aboutData.addAuthor(i18n("Gregg Edghill"), i18n("Developer, MSN"), "gregg.edghill@gmail.com"); aboutData.addAuthor(i18n("Grzegorz Jaskiewicz"), i18n("Developer, Gadu plugin maintainer"), "gj@pointblue.com.pl"); aboutData.addAuthor(i18n("Gustavo Pichorim Boiko"), i18n("Developer"), "gustavo.boiko@kdemail.net"); aboutData.addAuthor(i18n("Jason Keirstead"), i18n("Developer"), "jason@keirstead.org", "http://www.keirstead.org"); aboutData.addAuthor(i18n("Matt Rogers"), i18n("Lead Developer, AIM and ICQ plugin maintainer"), "mattr@kde.org"); aboutData.addAuthor(i18n("Michel Hermier"), i18n("IRC plugin maintainer"), "michel.hermier@wanadoo.fr"); aboutData.addAuthor(i18n("Michaël Larouche"), i18n("Lead Developer, Telepathy and Messenger plugin maintainer"), "larouche@kde.org", "http://www.tehbisnatch.org/"); aboutData.addAuthor(i18n("Olivier Goffart"), i18n("Lead Developer, MSN plugin maintainer"), "ogoffart@kde.org"); aboutData.addAuthor(i18n("Ollivier Lapeyre Johann"), i18n("Artist / Developer, Artwork maintainer"), "johann.ollivierlapeyre@gmail.com"); aboutData.addAuthor(i18n("Richard Smith"), i18n("Developer, UI maintainer"), "kde@metafoo.co.uk"); aboutData.addAuthor(i18n("Tiago Salem Herrmann"), i18n("Developer, WLM plugin maintainer"), "tiagosh@gmail.com"); aboutData.addAuthor(i18n("Till Gerken"), i18n("Developer, Jabber plugin maintainer"), "till@tantalo.net"); aboutData.addAuthor(i18n("Will Stephenson"), i18n("Lead Developer, GroupWise maintainer"), "wstephenson@kde.org"); aboutData.addAuthor(i18n("Rafael Fernández López"), i18n("Developer"), "ereslibre@kde.org"); aboutData.addAuthor(i18n("Roman Jarosz"), i18n("Developer, AIM and ICQ"), "kedgedev@centrum.cz"); aboutData.addAuthor(i18n("Charles Connell"), i18n("Developer"), "charles@connells.org"); aboutData.addAuthor(i18n("Tejas Dinkar"), i18n("Developer, Bonjour Plugin Maintainer"), "tejas@gja.in", "http://www.gja.in"); aboutData.addCredit(i18n("Vally8"), i18n("Konki style author"), "vally8@gmail.com", "http://vally8.free.fr/"); aboutData.addCredit(i18n("Tm_T"), i18n("Hacker style author"), "jussi.kekkonen@gmail.com"); aboutData.addCredit(i18n("Luciash d' Being"), i18n("Kopete's icon author")); aboutData.addCredit(i18n("Steve Cable"), i18n("Sounds")); aboutData.addCredit(i18n("Jessica Hall"), i18n("Kopete Docugoddess, Bug and Patch Testing.")); aboutData.addCredit(i18n("Justin Karneges"), i18n("Iris Jabber Backend Library")); aboutData.addCredit(i18n("Tom Linsky"), i18n("OscarSocket author"), "twl6@po.cwru.edu"); aboutData.addCredit(i18n("Olaf Lueg"), i18n("Kmerlin MSN code")); aboutData.addCredit(i18n("Chetan Reddy"), i18n("Former developer"), "chetan13@gmail.com"); aboutData.addCredit(i18n("Nick Betcher"), i18n("Former developer, project co-founder"), "nbetcher@kde.org"); aboutData.addCredit(i18n("Ryan Cumming"), i18n("Former developer"), "ryan@kde.org"); aboutData.addCredit(i18n("Stefan Gehn"), i18n("Former developer"), "metz@gehn.net", "http://metz.gehn.net"); aboutData.addCredit(i18n("Martijn Klingens"), i18n("Former developer"), "klingens@kde.org"); aboutData.addCredit(i18n("Andres Krapf"), i18n("Former developer"), "dae@chez.com"); aboutData.addCredit(i18n("Carsten Pfeiffer"), i18n("Misc bugfixes and enhancements"), "pfeiffer@kde.org"); aboutData.addCredit(i18n("Zack Rusin"), i18n("Former developer, original Gadu plugin author"), "zack@kde.org"); aboutData.addCredit(i18n("Richard Stellingwerff"), i18n("Former developer"), "remenic@linuxfromscratch.org"); aboutData.addCredit(i18n("Daniel Stone"), i18n("Former developer, Jabber plugin author"), "daniel@fooishbar.org", "http://fooishbar.org"); aboutData.addCredit(i18n("Chris TenHarmsel"), i18n("Former developer, Oscar plugin"), "chris@tenharmsel.com"); aboutData.addCredit(i18n("Hendrik vom Lehn"), i18n("Former developer"), "hennevl@hennevl.de", "http://www.hennevl.de"); aboutData.addCredit(i18n("Gav Wood"), i18n("Former developer and WinPopup maintainer"), "gav@indigoarchive.net"); aboutData.setTranslator(i18nc("NAME OF TRANSLATORS", "Your names"), i18nc("EMAIL OF TRANSLATORS", "Your emails")); KAboutData::setApplicationData(aboutData); + QCommandLineParser parser; parser.addVersionOption(); parser.addHelpOption(); parser.addOption(QCommandLineOption(QStringList() << QLatin1String("noplugins"), i18n("Do not load plugins. This option overrides all other options."))); parser.addOption(QCommandLineOption(QStringList() << QLatin1String("noconnect"), i18n("Disable auto-connection"))); parser.addOption(QCommandLineOption(QStringList() << QLatin1String("!+[URL]"), i18n("URLs to pass to kopete / emoticon themes to install"))); parser.addOption(QCommandLineOption(QStringList() << QLatin1String("autoconnect"), i18n("Auto-connect the specified accounts. Use a comma-separated list\n" "to auto-connect multiple accounts."))); parser.addOption(QCommandLineOption(QStringList() << QLatin1String("disable"), i18n("Do not load the specified plugin. Use a comma-separated list\n" "to disable multiple plugins."))); parser.addOption(QCommandLineOption(QStringList() << QLatin1String("load-plugins"), i18n("Load only the specified plugins. Use a comma-separated list\n" "to load multiple plugins. This option has no effect when\n" "--noplugins is set and overrides all other plugin related\n" "command line options."))); aboutData.setupCommandLine(&parser); parser.process(kopete); aboutData.processCommandLine(&parser); - KDBusService service(KDBusService::Unique); + kopete.initializeUI(); + return kopete.exec(); } // vim: set noet ts=4 sts=4 sw=4: