diff --git a/src/application.cpp b/src/application.cpp index 0a3fe97b..afe13390 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -1,1397 +1,1409 @@ /* 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. */ /* Copyright (C) 2002 Dario Abatianni Copyright (C) 2005 Ismail Donmez Copyright (C) 2005 Peter Simonsson Copyright (C) 2005 John Tapsell Copyright (C) 2005-2008 Eike Hein */ #include "application.h" #include "connectionmanager.h" #include "scriptlauncher.h" #include "transfermanager.h" #include "viewcontainer.h" #include "urlcatcher.h" #include "highlight.h" #include "server.h" #include "sound.h" #include "quickconnectdialog.h" #include "dbus.h" #include "servergroupsettings.h" #include "serversettings.h" #include "channel.h" #include "images.h" #include "notificationhandler.h" #include "awaymanager.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include +#include +#include using namespace Konversation; Application::Application(int &argc, char **argv) : QApplication(argc, argv) { mainWindow = 0; m_restartScheduled = false; m_connectionManager = 0; m_awayManager = 0; m_scriptLauncher = 0; quickConnectDialog = 0; osd = 0; m_wallet = NULL; m_images = 0; m_sound = 0; m_dccTransferManager = 0; m_notificationHandler = 0; m_urlModel = 0; dbusObject = 0; identDBus = 0; m_networkConfigurationManager = 0; } Application::~Application() { qDebug(); if (!m_images) return; // Nothing to do, newInstance() has never been called. stashQueueRates(); Preferences::self()->save(); // FIXME i can't figure out why this isn't in saveOptions --argonel saveOptions(false); // Delete m_dccTransferManager here as its destructor depends on the main loop being in tact which it // won't be if if we wait till Qt starts deleting parent pointers. delete m_dccTransferManager; delete m_images; delete m_sound; //delete dbusObject; //delete prefsDCOP; //delete identDBus; delete osd; osd = 0; closeWallet(); delete m_networkConfigurationManager; if (m_restartScheduled) implementRestart(); } void Application::implementRestart() { #if 0 // FIXME KF5 Port: --restart QStringList argumentList; KCmdLineArgs* args = KCmdLineArgs::parsedArgs(); argumentList = args->allArguments(); // Pop off the executable name. May not be the first argument in argv // everywhere, so verify first. if (QFileInfo(argumentList.first()) == QFileInfo(QCoreApplication::applicationFilePath())) argumentList.removeFirst(); // Don't round-trip --restart. argumentList.removeAll(QStringLiteral("--restart")); // Avoid accumulating multiple --startupdelay arguments across multiple // uses of restart(). if (argumentList.contains(QStringLiteral("--startupdelay"))) { int index = argumentList.lastIndexOf(QStringLiteral("--startupdelay")); if (index < argumentList.count() - 1 && !argumentList.at(index + 1).startsWith(QLatin1Char('-'))) { QString delayArgument = argumentList.at(index + 1); bool ok; uint delay = delayArgument.toUInt(&ok, 10); // If the argument is invalid or too low, raise to at least 2000 msecs. if (!ok || delay < 2000) argumentList.replace(index + 1, QStringLiteral("2000")); } } else argumentList << QStringLiteral("--startupdelay") << QStringLiteral("2000"); KProcess::startDetached(QCoreApplication::applicationFilePath(), argumentList); #endif } void Application::newInstance(QCommandLineParser *args) { QString url; if (args->positionalArguments().count() > 0) url = args->positionalArguments().at(0); if (!mainWindow) { connect(this, &Application::aboutToQuit, this, &Application::prepareShutdown); m_connectionManager = new ConnectionManager(this); m_awayManager = new AwayManager(this); connect(m_connectionManager, &ConnectionManager::identityOnline, m_awayManager, &AwayManager::identityOnline); connect(m_connectionManager, &ConnectionManager::identityOffline, m_awayManager, &AwayManager::identityOffline); connect(m_connectionManager, &ConnectionManager::connectionChangedAwayState, m_awayManager, &AwayManager::updateGlobalAwayAction); m_networkConfigurationManager = new QNetworkConfigurationManager(); connect(m_networkConfigurationManager, SIGNAL(onlineStateChanged(bool)), m_connectionManager, SLOT(onOnlineStateChanged(bool))); m_scriptLauncher = new ScriptLauncher(this); // an instance of DccTransferManager needs to be created before GUI class instances' creation. m_dccTransferManager = new DCC::TransferManager(this); // make sure all vars are initialized properly quickConnectDialog = 0; // Sound object used to play sound is created when needed. m_sound = NULL; // initialize OSD display here, so we can read the Preferences::properly osd = new OSDWidget( QStringLiteral("Konversation") ); Preferences::self(); readOptions(); // Images object providing LEDs, NickIcons m_images = new Images(); m_urlModel = new QStandardItemModel(0, 3, this); // Auto-alias scripts. This adds any missing aliases QStringList aliasList(Preferences::self()->aliasList()); const QStringList scripts(Preferences::defaultAliasList()); bool changed = false; for ( QStringList::ConstIterator it = scripts.constBegin(); it != scripts.constEnd(); ++it ) { if(!aliasList.contains(*it)) { changed = true; aliasList.append(*it); } } if(changed) Preferences::self()->setAliasList(aliasList); // open main window mainWindow = new MainWindow(); connect(mainWindow.data(), &MainWindow::showQuickConnectDialog, this, &Application::openQuickConnectDialog); connect(Preferences::self(), &Preferences::updateTrayIcon, mainWindow.data(), &MainWindow::updateTrayIcon); connect(mainWindow.data(), &MainWindow::endNotification, osd, &OSDWidget::hide); // take care of user style changes, setting back colors and stuff // apply GUI settings emit appearanceChanged(); if (Preferences::self()->showTrayIcon() && Preferences::self()->hideToTrayOnStartup()) mainWindow->hide(); else mainWindow->show(); bool openServerList = Preferences::self()->showServerList(); // handle autoconnect on startup Konversation::ServerGroupHash serverGroups = Preferences::serverGroupHash(); if (!args->isSet(QStringLiteral("noautoconnect")) && url.isEmpty() && !args->isSet(QStringLiteral("server"))) { QList serversToAutoconnect; QHashIterator it(serverGroups); while(it.hasNext()) { it.next(); if (it.value()->autoConnectEnabled()) { openServerList = false; serversToAutoconnect << it.value(); } } std::sort(serversToAutoconnect.begin(), serversToAutoconnect.end(), [] (const ServerGroupSettingsPtr &left, const ServerGroupSettingsPtr &right) { return left->sortIndex() < right->sortIndex(); }); for (QList::iterator it = serversToAutoconnect.begin(); it != serversToAutoconnect.end(); ++it) { m_connectionManager->connectTo(Konversation::CreateNewConnection, (*it)->id()); } } if (openServerList) mainWindow->openServerList(); connect(this, SIGNAL(serverGroupsChanged(Konversation::ServerGroupSettingsPtr)), this, SLOT(saveOptions())); // prepare dbus interface dbusObject = new Konversation::DBus(this); QDBusConnection::sessionBus().registerObject(QStringLiteral("/irc"), dbusObject, QDBusConnection::ExportNonScriptableSlots); identDBus = new Konversation::IdentDBus(this); QDBusConnection::sessionBus().registerObject(QStringLiteral("/identity"), identDBus, QDBusConnection::ExportNonScriptableSlots); if (dbusObject) { connect(dbusObject,SIGNAL (dbusMultiServerRaw(QString)), this,SLOT (dbusMultiServerRaw(QString)) ); connect(dbusObject,SIGNAL (dbusRaw(QString,QString)), this,SLOT (dbusRaw(QString,QString)) ); connect(dbusObject,SIGNAL (dbusSay(QString,QString,QString)), this,SLOT (dbusSay(QString,QString,QString)) ); connect(dbusObject,SIGNAL (dbusInfo(QString)), this,SLOT (dbusInfo(QString)) ); connect(dbusObject,SIGNAL (dbusInsertMarkerLine()), mainWindow,SIGNAL(insertMarkerLine())); connect(dbusObject, SIGNAL(connectTo(Konversation::ConnectionFlag,QString,QString,QString,QString,QString,bool)), m_connectionManager, SLOT(connectTo(Konversation::ConnectionFlag,QString,QString,QString,QString,QString,bool))); } m_notificationHandler = new Konversation::NotificationHandler(this); connect(this, &Application::appearanceChanged, this, &Application::updateProxySettings); } #if 0 //FIXME KF5 Port: --restart else if (args->isSet(QStringLiteral("restart"))) { restart(); return; } #endif if (!url.isEmpty()) getConnectionManager()->connectTo(Konversation::SilentlyReuseConnection, url); else if (args->isSet(QStringLiteral("server"))) { getConnectionManager()->connectTo(Konversation::SilentlyReuseConnection, args->value(QStringLiteral("server")), args->value(QStringLiteral("port")), args->value(QStringLiteral("password")), args->value(QStringLiteral("nick")), args->value(QStringLiteral("channel")), args->isSet(QStringLiteral("ssl"))); } return; } Application* Application::instance() { return static_cast(QApplication::instance()); } void Application::restart() { m_restartScheduled = true; mainWindow->quitProgram(); } void Application::prepareShutdown() { if (mainWindow) mainWindow->getViewContainer()->prepareShutdown(); if (m_awayManager) { m_awayManager->blockSignals(true); delete m_awayManager; m_awayManager = 0; } if (m_connectionManager) { m_connectionManager->quitServers(); m_connectionManager->blockSignals(true); delete m_connectionManager; m_connectionManager = 0; } } bool Application::event(QEvent* event) { if (event->type() == QEvent::ApplicationPaletteChange || event->type() == QEvent::ApplicationFontChange) { emit appearanceChanged(); } return QApplication::event(event); } void Application::showQueueTuner(bool p) { getMainWindow()->getViewContainer()->showQueueTuner(p); } void Application::dbusMultiServerRaw(const QString &command) { sendMultiServerCommand(command.section(QLatin1Char(' '), 0,0), command.section(QLatin1Char(' '), 1)); } void Application::dbusRaw(const QString& connection, const QString &command) { Server* server = getConnectionManager()->getServerByName(connection, ConnectionManager::MatchByIdThenName); if (server) server->dbusRaw(command); } void Application::dbusSay(const QString& connection, const QString& target, const QString& command) { Server* server = getConnectionManager()->getServerByName(connection, ConnectionManager::MatchByIdThenName); if (server) server->dbusSay(target, command); } void Application::dbusInfo(const QString& string) { mainWindow->getViewContainer()->appendToFrontmost(i18n("D-Bus"), string, 0); } void Application::readOptions() { // get standard config file // read nickname sorting order for channel nick lists KConfigGroup cgSortNicknames(KSharedConfig::openConfig()->group("Sort Nicknames")); QString sortOrder=cgSortNicknames.readEntry("SortOrder"); QStringList sortOrderList=sortOrder.split(QString()); sortOrderList.sort(); if (sortOrderList.join(QString())!=QStringLiteral("-hopqv")) { sortOrder=Preferences::defaultNicknameSortingOrder(); Preferences::self()->setSortOrder(sortOrder); } // Identity list QStringList identityList=KSharedConfig::openConfig()->groupList().filter(QRegExp(QStringLiteral("Identity [0-9]+"))); if (!identityList.isEmpty()) { Preferences::clearIdentityList(); for(int index=0;indexgroup(identityList[index])); newIdentity->setName(cgIdentity.readEntry("Name")); newIdentity->setIdent(cgIdentity.readEntry("Ident")); newIdentity->setRealName(cgIdentity.readEntry("Realname")); newIdentity->setNicknameList(cgIdentity.readEntry("Nicknames",QStringList())); newIdentity->setAuthType(cgIdentity.readEntry("AuthType", "nickserv")); newIdentity->setAuthPassword(cgIdentity.readEntry("Password")); newIdentity->setNickservNickname(cgIdentity.readEntry("Bot")); newIdentity->setNickservCommand(cgIdentity.readEntry("NickservCommand", "identify")); newIdentity->setSaslAccount(cgIdentity.readEntry("SaslAccount")); newIdentity->setPemClientCertFile(cgIdentity.readEntry("PemClientCertFile", QUrl())); newIdentity->setInsertRememberLineOnAway(cgIdentity.readEntry("InsertRememberLineOnAway", false)); newIdentity->setRunAwayCommands(cgIdentity.readEntry("ShowAwayMessage", false)); newIdentity->setAwayCommand(cgIdentity.readEntry("AwayMessage")); newIdentity->setReturnCommand(cgIdentity.readEntry("ReturnMessage")); newIdentity->setAutomaticAway(cgIdentity.readEntry("AutomaticAway", false)); newIdentity->setAwayInactivity(cgIdentity.readEntry("AwayInactivity", 10)); newIdentity->setAutomaticUnaway(cgIdentity.readEntry("AutomaticUnaway", false)); newIdentity->setQuitReason(cgIdentity.readEntry("QuitReason")); newIdentity->setPartReason(cgIdentity.readEntry("PartReason")); newIdentity->setKickReason(cgIdentity.readEntry("KickReason")); newIdentity->setShellCommand(cgIdentity.readEntry("PreShellCommand")); newIdentity->setCodecName(cgIdentity.readEntry("Codec")); newIdentity->setAwayMessage(cgIdentity.readEntry("AwayReason")); newIdentity->setAwayNickname(cgIdentity.readEntry("AwayNick")); Preferences::addIdentity(newIdentity); } } osd->setEnabled(Preferences::self()->useOSD()); //How to load the font from the text? osd->setFont(Preferences::self()->oSDFont()); osd->setDuration(Preferences::self()->oSDDuration()); osd->setScreen(Preferences::self()->oSDScreen()); osd->setShadow(Preferences::self()->oSDDrawShadow()); osd->setOffset(Preferences::self()->oSDOffsetX(), Preferences::self()->oSDOffsetY()); osd->setAlignment((OSDWidget::Alignment)Preferences::self()->oSDAlignment()); if(Preferences::self()->oSDUseCustomColors()) { osd->setTextColor(Preferences::self()->oSDTextColor()); QPalette p = osd->palette(); p.setColor(osd->backgroundRole(), Preferences::self()->oSDBackgroundColor()); osd->setPalette(p); } // Check if there is old server list config //TODO FIXME why are we doing this here? KConfigGroup cgServerList(KSharedConfig::openConfig()->group("Server List")); // Read the new server settings QStringList groups = KSharedConfig::openConfig()->groupList().filter(QRegExp(QStringLiteral("ServerGroup [0-9]+"))); QMap notifyList; QList sgKeys; if(!groups.isEmpty()) { Konversation::ServerGroupHash serverGroups; QStringList::iterator it; QStringList tmp1; QStringList::iterator it2; int index = 0; Konversation::ChannelList channelHistory; Konversation::ServerSettings server; Konversation::ChannelSettings channel; for (it = groups.begin(); it != groups.end(); ++it) { KConfigGroup cgServerGroup(KSharedConfig::openConfig()->group(*it)); Konversation::ServerGroupSettingsPtr serverGroup(new Konversation::ServerGroupSettings); serverGroup->setName(cgServerGroup.readEntry("Name")); serverGroup->setSortIndex(groups.at(index).section(' ', -1).toInt() ); serverGroup->setIdentityId(Preferences::identityByName(cgServerGroup.readEntry("Identity"))->id()); serverGroup->setConnectCommands(cgServerGroup.readEntry("ConnectCommands")); serverGroup->setAutoConnectEnabled(cgServerGroup.readEntry("AutoConnect", false)); serverGroup->setNotificationsEnabled(cgServerGroup.readEntry("EnableNotifications", true)); serverGroup->setExpanded(cgServerGroup.readEntry("Expanded", false)); notifyList.insert((*serverGroup).id(), cgServerGroup.readEntry("NotifyList", QString()).split(QLatin1Char(' '), QString::SkipEmptyParts)); tmp1 = cgServerGroup.readEntry("ServerList", QStringList()); for (it2 = tmp1.begin(); it2 != tmp1.end(); ++it2) { KConfigGroup cgServer(KSharedConfig::openConfig()->group(*it2)); server.setHost(cgServer.readEntry("Server")); server.setPort(cgServer.readEntry("Port", 0)); server.setPassword(cgServer.readEntry("Password")); server.setSSLEnabled(cgServer.readEntry("SSLEnabled", false)); server.setBypassProxy(cgServer.readEntry("BypassProxy", false)); serverGroup->addServer(server); } //config->setGroup((*it)); tmp1 = cgServerGroup.readEntry("AutoJoinChannels", QStringList()); for (it2 = tmp1.begin(); it2 != tmp1.end(); ++it2) { KConfigGroup cgJoin(KSharedConfig::openConfig()->group(*it2)); if (!cgJoin.readEntry("Name").isEmpty()) { channel.setName(cgJoin.readEntry("Name")); channel.setPassword(cgJoin.readEntry("Password")); serverGroup->addChannel(channel); } } //config->setGroup((*it)); tmp1 = cgServerGroup.readEntry("ChannelHistory", QStringList()); channelHistory.clear(); for (it2 = tmp1.begin(); it2 != tmp1.end(); ++it2) { KConfigGroup cgChanHistory(KSharedConfig::openConfig()->group(*it2)); if (!cgChanHistory.readEntry("Name").isEmpty()) { channel.setName(cgChanHistory.readEntry("Name")); channel.setPassword(cgChanHistory.readEntry("Password")); channel.setNotificationsEnabled(cgChanHistory.readEntry("EnableNotifications", true)); channelHistory.append(channel); } } serverGroup->setChannelHistory(channelHistory); serverGroups.insert(serverGroup->id(), serverGroup); sgKeys.append(serverGroup->id()); index++; } Preferences::setServerGroupHash(serverGroups); } // Notify Settings and lists. Must follow Server List. Preferences::setNotifyList(notifyList); Preferences::self()->setNotifyDelay(Preferences::self()->notifyDelay()); Preferences::self()->setUseNotify(Preferences::self()->useNotify()); // Quick Buttons List // if there are button definitions in the config file, remove default buttons if (KSharedConfig::openConfig()->hasGroup("Button List")) Preferences::clearQuickButtonList(); KConfigGroup cgQuickButtons(KSharedConfig::openConfig()->group("Button List")); // Read all default buttons QStringList buttonList(Preferences::quickButtonList()); // Read all quick buttons int index=0; while (cgQuickButtons.hasKey(QString(QStringLiteral("Button%1")).arg(index))) { buttonList.append(cgQuickButtons.readEntry(QString(QStringLiteral("Button%1")).arg(index++))); } // while // Put back the changed button list Preferences::setQuickButtonList(buttonList); // Autoreplace List // if there are autoreplace definitions in the config file, remove default entries if (KSharedConfig::openConfig()->hasGroup("Autoreplace List")) Preferences::clearAutoreplaceList(); KConfigGroup cgAutoreplace(KSharedConfig::openConfig()->group("Autoreplace List")); // Read all default entries QList autoreplaceList(Preferences::autoreplaceList()); // Read all entries index=0; // legacy code for old autoreplace format 4/6/09 QString autoReplaceString(QStringLiteral("Autoreplace")); while (cgAutoreplace.hasKey(autoReplaceString + QString::number(index))) { // read entry and get length of the string QString entry=cgAutoreplace.readEntry(autoReplaceString + QString::number(index++)); int length=entry.length()-1; // if there's a "#" in the end, strip it (used to preserve blanks at the end of the replacement text) // there should always be one, but older versions did not do it, so we check first if (entry.at(length)==QLatin1Char('#')) entry=entry.left(length); QString regex = entry.section(QLatin1Char(','),0,0); QString direction = entry.section(QLatin1Char(','),1,1); QString pattern = entry.section(QLatin1Char(','),2,2); QString replace = entry.section(QLatin1Char(','),3); // add entry to internal list autoreplaceList.append(QStringList() << regex << direction << pattern << replace); } // while //end legacy code for old autoreplace format index=0; //new code for autoreplace config QString indexString(QString::number(index)); QString regexString(QStringLiteral("Regex")); QString directString(QStringLiteral("Direction")); QString patternString(QStringLiteral("Pattern")); QString replaceString(QStringLiteral("Replace")); while (cgAutoreplace.hasKey(patternString + indexString)) { QString pattern = cgAutoreplace.readEntry(patternString + indexString); QString regex = cgAutoreplace.readEntry(regexString + indexString, QStringLiteral("0")); QString direction = cgAutoreplace.readEntry(directString + indexString, QStringLiteral("o")); QString replace = cgAutoreplace.readEntry(replaceString + indexString, QString()); if (replace.length()>0) { int repLen=replace.length()-1; if (replace.at(repLen)==QLatin1Char('#')) replace=replace.left(repLen); } if (pattern.length()>0) { int patLen=pattern.length()-1; if (pattern.at(patLen)==QLatin1Char('#')) pattern=pattern.left(patLen); } index++; indexString = QString::number(index); autoreplaceList.append(QStringList() << regex << direction << pattern << replace); } // Put back the changed autoreplace list Preferences::setAutoreplaceList(autoreplaceList); //TODO FIXME I assume this is in the group, but I have a hunch we just don't care about <1.0.1 // Highlight List KConfigGroup cgDefault(KSharedConfig::openConfig()->group("")); if (cgDefault.hasKey("Highlight")) // Stay compatible with versions < 0.14 { QString highlight=cgDefault.readEntry("Highlight"); QStringList hiList = highlight.split(QLatin1Char(' '), QString::SkipEmptyParts); for (int hiIndex=0; hiIndex < hiList.count(); hiIndex+=2) { Preferences::addHighlight(hiList[hiIndex], false, QString(QLatin1Char('#')+hiList[hiIndex+1]), QString(), QString(), QString(), true); } cgDefault.deleteEntry("Highlight"); } else { int i = 0; while (KSharedConfig::openConfig()->hasGroup(QString(QStringLiteral("Highlight%1")).arg(i))) { KConfigGroup cgHilight(KSharedConfig::openConfig()->group(QString(QStringLiteral("Highlight%1")).arg(i))); Preferences::addHighlight( cgHilight.readEntry("Pattern"), cgHilight.readEntry("RegExp", false), cgHilight.readEntry("Color", QColor(Qt::black)), cgHilight.readPathEntry("Sound", QString()), cgHilight.readEntry("AutoText"), cgHilight.readEntry("ChatWindows"), cgHilight.readEntry("Notify", true) ); i++; } } // Ignore List KConfigGroup cgIgnoreList(KSharedConfig::openConfig()->group("Ignore List")); // Remove all default entries if there is at least one Ignore in the Preferences::file if (cgIgnoreList.hasKey("Ignore0")) Preferences::clearIgnoreList(); // Read all ignores index=0; while (cgIgnoreList.hasKey(QString(QStringLiteral("Ignore%1")).arg(index))) { Preferences::addIgnore(cgIgnoreList.readEntry(QString(QStringLiteral("Ignore%1")).arg(index++))); } // Aliases KConfigGroup cgAliases(KSharedConfig::openConfig()->group("Aliases")); QStringList newList=cgAliases.readEntry("AliasList", QStringList()); if (!newList.isEmpty()) Preferences::self()->setAliasList(newList); // Channel Encodings //Legacy channel encodings read in Jun. 29, 2009 KConfigGroup cgChannelEncodings(KSharedConfig::openConfig()->group("Channel Encodings")); QMap channelEncodingEntries=cgChannelEncodings.entryMap(); QRegExp re(QStringLiteral("^(.+) ([^\\s]+)$")); QList channelEncodingEntryKeys=channelEncodingEntries.keys(); for(QList::const_iterator itStr=channelEncodingEntryKeys.constBegin(); itStr != channelEncodingEntryKeys.constEnd(); ++itStr) { if(re.indexIn(*itStr) > -1) { Preferences::setChannelEncoding(re.cap(1),re.cap(2),channelEncodingEntries[*itStr]); } } //End legacy channel encodings read in Jun 29, 2009 KConfigGroup cgEncodings(KSharedConfig::openConfig()->group("Encodings")); QMap encodingEntries=cgEncodings.entryMap(); QList encodingEntryKeys=encodingEntries.keys(); QRegExp reg(QStringLiteral("^([^\\s]+) ([^\\s]+)\\s?([^\\s]*)$")); for(QList::const_iterator itStr=encodingEntryKeys.constBegin(); itStr != encodingEntryKeys.constEnd(); ++itStr) { if(reg.indexIn(*itStr) > -1) { if(reg.cap(1) == QStringLiteral("ServerGroup") && !reg.cap(3).isEmpty()) Preferences::setChannelEncoding(sgKeys.at(reg.cap(2).toInt()), reg.cap(3), encodingEntries[*itStr]); else Preferences::setChannelEncoding(reg.cap(1), reg.cap(2), encodingEntries[*itStr]); } } // Spell Checking Languages KConfigGroup cgSpellCheckingLanguages(KSharedConfig::openConfig()->group("Spell Checking Languages")); QMap spellCheckingLanguageEntries=cgSpellCheckingLanguages.entryMap(); QList spellCheckingLanguageEntryKeys=spellCheckingLanguageEntries.keys(); for (QList::const_iterator itStr=spellCheckingLanguageEntryKeys.constBegin(); itStr != spellCheckingLanguageEntryKeys.constEnd(); ++itStr) { if (reg.indexIn(*itStr) > -1) { if (reg.cap(1) == QStringLiteral("ServerGroup") && !reg.cap(3).isEmpty()) { ServerGroupSettingsPtr serverGroup = Preferences::serverGroupById(sgKeys.at(reg.cap(2).toInt())); if (serverGroup) Preferences::setSpellCheckingLanguage(serverGroup, reg.cap(3), spellCheckingLanguageEntries[*itStr]); } else Preferences::setSpellCheckingLanguage(reg.cap(1), reg.cap(2), spellCheckingLanguageEntries[*itStr]); } } fetchQueueRates(); updateProxySettings(); } void Application::saveOptions(bool updateGUI) { // template: KConfigGroup (KSharedConfig::openConfig()->group( )); //KConfig* config=KSharedConfig::openConfig(); // Should be handled in NicklistBehaviorConfigController now // config->setGroup("Sort Nicknames"); // Clean up identity list QStringList identities=KSharedConfig::openConfig()->groupList().filter(QRegExp(QStringLiteral("Identity [0-9]+"))); if (identities.count()) { // remove old identity list from Preferences::file to keep numbering under control for (int index=0; index < identities.count(); index++) KSharedConfig::openConfig()->deleteGroup(identities[index]); } IdentityList identityList = Preferences::identityList(); int index = 0; for (IdentityList::ConstIterator it = identityList.constBegin(); it != identityList.constEnd(); ++it) { IdentityPtr identity = (*it); KConfigGroup cgIdentity(KSharedConfig::openConfig()->group(QString(QStringLiteral("Identity %1")).arg(index))); cgIdentity.writeEntry("Name",identity->getName()); cgIdentity.writeEntry("Ident",identity->getIdent()); cgIdentity.writeEntry("Realname",identity->getRealName()); cgIdentity.writeEntry("Nicknames",identity->getNicknameList()); cgIdentity.writeEntry("AuthType",identity->getAuthType()); cgIdentity.writeEntry("Password",identity->getAuthPassword()); cgIdentity.writeEntry("Bot",identity->getNickservNickname()); cgIdentity.writeEntry("NickservCommand",identity->getNickservCommand()); cgIdentity.writeEntry("SaslAccount",identity->getSaslAccount()); cgIdentity.writeEntry("PemClientCertFile", identity->getPemClientCertFile().toString()); cgIdentity.writeEntry("InsertRememberLineOnAway", identity->getInsertRememberLineOnAway()); cgIdentity.writeEntry("ShowAwayMessage",identity->getRunAwayCommands()); cgIdentity.writeEntry("AwayMessage",identity->getAwayCommand()); cgIdentity.writeEntry("ReturnMessage",identity->getReturnCommand()); cgIdentity.writeEntry("AutomaticAway", identity->getAutomaticAway()); cgIdentity.writeEntry("AwayInactivity", identity->getAwayInactivity()); cgIdentity.writeEntry("AutomaticUnaway", identity->getAutomaticUnaway()); cgIdentity.writeEntry("QuitReason",identity->getQuitReason()); cgIdentity.writeEntry("PartReason",identity->getPartReason()); cgIdentity.writeEntry("KickReason",identity->getKickReason()); cgIdentity.writeEntry("PreShellCommand",identity->getShellCommand()); cgIdentity.writeEntry("Codec",identity->getCodecName()); cgIdentity.writeEntry("AwayReason",identity->getAwayMessage()); cgIdentity.writeEntry("AwayNick", identity->getAwayNickname()); index++; } // endfor // Remove the old servergroups from the config QStringList groups = KSharedConfig::openConfig()->groupList().filter(QRegExp(QStringLiteral("ServerGroup [0-9]+"))); if (groups.count()) { QStringList::iterator it; for(it = groups.begin(); it != groups.end(); ++it) { KSharedConfig::openConfig()->deleteGroup((*it)); } } // Remove the old servers from the config groups = KSharedConfig::openConfig()->groupList().filter(QRegExp(QStringLiteral("Server [0-9]+"))); if (groups.count()) { QStringList::iterator it; for(it = groups.begin(); it != groups.end(); ++it) { KSharedConfig::openConfig()->deleteGroup((*it)); } } // Remove the old channels from the config groups = KSharedConfig::openConfig()->groupList().filter(QRegExp(QStringLiteral("Channel [0-9]+"))); if (groups.count()) { QStringList::iterator it; for(it = groups.begin(); it != groups.end(); ++it) { KSharedConfig::openConfig()->deleteGroup((*it)); } } // Add the new servergroups to the config Konversation::ServerGroupHash serverGroupHash = Preferences::serverGroupHash(); QHashIterator hashIt(serverGroupHash); QMap sortedServerGroupMap; // Make the indices in the group headers reflect the server list dialog sorting. while (hashIt.hasNext()) { hashIt.next(); sortedServerGroupMap.insert(hashIt.value()->sortIndex(), hashIt.value()); } QMapIterator it(sortedServerGroupMap); index = 0; int index2 = 0; int index3 = 0; int width = 0; QList keys = serverGroupHash.keys(); for(int i=0; i sgKeys; while(it.hasNext()) { it.next(); serverlist = (it.value())->serverList(); servers.clear(); sgKeys.append(it.value()->id()); for(it2 = serverlist.begin(); it2 != serverlist.end(); ++it2) { groupName = QString(QStringLiteral("Server %1")).arg(index2); servers.append(groupName); KConfigGroup cgServer(KSharedConfig::openConfig()->group(groupName)); cgServer.writeEntry("Server", (*it2).host()); cgServer.writeEntry("Port", (*it2).port()); cgServer.writeEntry("Password", (*it2).password()); cgServer.writeEntry("SSLEnabled", (*it2).SSLEnabled()); cgServer.writeEntry("BypassProxy", (*it2).bypassProxy()); index2++; } channelList = it.value()->channelList(); channels.clear(); for(it3 = channelList.begin(); it3 != channelList.end(); ++it3) { groupName = QString(QStringLiteral("Channel %1")).arg(index3); channels.append(groupName); KConfigGroup cgChannel(KSharedConfig::openConfig()->group(groupName)); cgChannel.writeEntry("Name", (*it3).name()); cgChannel.writeEntry("Password", (*it3).password()); index3++; } channelList = it.value()->channelHistory(); channelHistory.clear(); for(it3 = channelList.begin(); it3 != channelList.end(); ++it3) { // TODO FIXME: is it just me or is this broken? groupName = QString(QStringLiteral("Channel %1")).arg(index3); channelHistory.append(groupName); KConfigGroup cgChannelHistory(KSharedConfig::openConfig()->group(groupName)); cgChannelHistory.writeEntry("Name", (*it3).name()); cgChannelHistory.writeEntry("Password", (*it3).password()); cgChannelHistory.writeEntry("EnableNotifications", (*it3).enableNotifications()); index3++; } QString sgn = QString(QStringLiteral("ServerGroup %1")).arg(QString::number(index).rightJustified(width,QLatin1Char('0'))); KConfigGroup cgServerGroup(KSharedConfig::openConfig()->group(sgn)); cgServerGroup.writeEntry("Name", it.value()->name()); cgServerGroup.writeEntry("Identity", it.value()->identity()->getName()); cgServerGroup.writeEntry("ServerList", servers); cgServerGroup.writeEntry("AutoJoinChannels", channels); cgServerGroup.writeEntry("ConnectCommands", it.value()->connectCommands()); cgServerGroup.writeEntry("AutoConnect", it.value()->autoConnectEnabled()); cgServerGroup.writeEntry("ChannelHistory", channelHistory); cgServerGroup.writeEntry("EnableNotifications", it.value()->enableNotifications()); cgServerGroup.writeEntry("Expanded", it.value()->expanded()); cgServerGroup.writeEntry("NotifyList",Preferences::notifyStringByGroupId(it.value()->id())); index++; } KSharedConfig::openConfig()->deleteGroup("Server List"); // Ignore List KSharedConfig::openConfig()->deleteGroup("Ignore List"); KConfigGroup cgIgnoreList(KSharedConfig::openConfig()->group("Ignore List")); QList ignoreList=Preferences::ignoreList(); for (int i = 0; i < ignoreList.size(); ++i) { cgIgnoreList.writeEntry(QString(QStringLiteral("Ignore%1")).arg(i),QString(QStringLiteral("%1,%2")).arg(ignoreList.at(i)->getName()).arg(ignoreList.at(i)->getFlags())); } // Channel Encodings // remove all entries once KSharedConfig::openConfig()->deleteGroup("Channel Encodings"); // legacy Jun 29, 2009 KSharedConfig::openConfig()->deleteGroup("Encodings"); KConfigGroup cgEncoding(KSharedConfig::openConfig()->group("Encodings")); QList encServers=Preferences::channelEncodingsServerGroupIdList(); //i have no idea these would need to be sorted //encServers.sort(); QList::iterator encServer; for ( encServer = encServers.begin(); encServer != encServers.end(); ++encServer ) { Konversation::ServerGroupSettingsPtr sgsp = Preferences::serverGroupById(*encServer); if ( sgsp ) // sgsp == 0 when the entry is of QuickConnect or something? { QStringList encChannels=Preferences::channelEncodingsChannelList(*encServer); //ditto //encChannels.sort(); QStringList::iterator encChannel; for ( encChannel = encChannels.begin(); encChannel != encChannels.end(); ++encChannel ) { QString enc = Preferences::channelEncoding(*encServer, *encChannel); QString key = QLatin1Char(' ') + (*encChannel); if(sgKeys.contains(*encServer)) key.prepend(QStringLiteral("ServerGroup ")+QString::number(sgKeys.indexOf(*encServer))); else key.prepend(sgsp->name()); cgEncoding.writeEntry(key, enc); } } } // Spell Checking Languages KSharedConfig::openConfig()->deleteGroup("Spell Checking Languages"); KConfigGroup cgSpellCheckingLanguages(KSharedConfig::openConfig()->group("Spell Checking Languages")); QHashIterator > i(Preferences::serverGroupSpellCheckingLanguages()); while (i.hasNext()) { i.next(); QHashIterator i2(i.value()); while (i2.hasNext()) { i2.next(); int serverGroupIndex = sgKeys.indexOf(i.key()->id()); if (serverGroupIndex != -1) cgSpellCheckingLanguages.writeEntry(QStringLiteral("ServerGroup ") + QString::number(serverGroupIndex) + QLatin1Char(' ') + i2.key(), i2.value()); } } QHashIterator > i3(Preferences::serverSpellCheckingLanguages()); while (i3.hasNext()) { i3.next(); QHashIterator i4(i3.value()); while (i4.hasNext()) { i4.next(); cgSpellCheckingLanguages.writeEntry(i3.key() + QLatin1Char(' ') + i4.key(), i4.value()); } } KSharedConfig::openConfig()->sync(); if(updateGUI) emit appearanceChanged(); } void Application::fetchQueueRates() { //The following rate was found in the rc for all queues, which were deliberately bad numbers chosen for debugging. //Its possible that the static array was constructed or deconstructed at the wrong time, and so those values saved //in the rc. When reading the values out of the rc, we must check to see if they're this specific value, //and if so, reset to defaults. --argonel IRCQueue::EmptyingRate shit(6, 50000, IRCQueue::EmptyingRate::Lines); int bad = 0; for (int i=0; i <= countOfQueues(); i++) { QList r = Preferences::self()->queueRate(i); staticrates[i] = IRCQueue::EmptyingRate(r[0], r[1]*1000, IRCQueue::EmptyingRate::RateType(r[2])); if (staticrates[i] == shit) bad++; } if (bad == 3) resetQueueRates(); } void Application::stashQueueRates() { for (int i=0; i <= countOfQueues(); i++) { QList r; r.append(staticrates[i].m_rate); r.append(staticrates[i].m_interval / 1000); r.append(int(staticrates[i].m_type)); Preferences::self()->setQueueRate(i, r); } } void Application::resetQueueRates() { for (int i=0; i <= countOfQueues(); i++) { Preferences::self()->queueRateItem(i)->setDefault(); QList r=Preferences::self()->queueRate(i); staticrates[i]=IRCQueue::EmptyingRate(r[0], r[1]*1000, IRCQueue::EmptyingRate::RateType(r[2])); } } void Application::storeUrl(const QString& origin, const QString& newUrl, const QDateTime& dateTime) { QString url(newUrl); url = url.replace(QStringLiteral("&"), QStringLiteral("&")); QList existing = m_urlModel->findItems(url, Qt::MatchExactly, 1); foreach(QStandardItem* item, existing) { if (m_urlModel->item(item->row(), 0)->data(Qt::DisplayRole).toString() == origin) m_urlModel->removeRow(item->row()); } m_urlModel->insertRow(0); m_urlModel->setData(m_urlModel->index(0, 0), origin, Qt::DisplayRole); m_urlModel->setData(m_urlModel->index(0, 1), url, Qt::DisplayRole); UrlDateItem* dateItem = new UrlDateItem(dateTime); m_urlModel->setItem(0, 2, dateItem); } void Application::openQuickConnectDialog() { quickConnectDialog = new QuickConnectDialog(mainWindow); connect(quickConnectDialog, SIGNAL(connectClicked(Konversation::ConnectionFlag,QString,QString,QString,QString,QString,bool)), m_connectionManager, SLOT(connectTo(Konversation::ConnectionFlag,QString,QString,QString,QString,QString,bool))); quickConnectDialog->show(); } void Application::sendMultiServerCommand(const QString& command, const QString& parameter) { const QList serverList = getConnectionManager()->getServerList(); foreach (Server* server, serverList) server->executeMultiServerCommand(command, parameter); } void Application::splitNick_Server(const QString& nick_server, QString &ircnick, QString &serverOrGroup) { //kaddresbook uses the utf separator 0xE120, so treat that as a separator as well QString nickServer = nick_server; nickServer.replace(QChar(0xE120), QStringLiteral("@")); ircnick = nickServer.section(QLatin1Char('@'),0,0); serverOrGroup = nickServer.section(QLatin1Char('@'),1); } NickInfoPtr Application::getNickInfo(const QString &ircnick, const QString &serverOrGroup) { const QList serverList = getConnectionManager()->getServerList(); NickInfoPtr nickInfo; QString lserverOrGroup = serverOrGroup.toLower(); foreach (Server* lookServer, serverList) { if (lserverOrGroup.isEmpty() || lookServer->getServerName().toLower()==lserverOrGroup || lookServer->getDisplayName().toLower()==lserverOrGroup) { nickInfo = lookServer->getNickInfo(ircnick); if (nickInfo) return nickInfo; //If we found one } } return (NickInfoPtr)0; } // auto replace on input/output QPair Application::doAutoreplace(const QString& text, bool output, int cursorPos) { // get autoreplace list QList autoreplaceList=Preferences::autoreplaceList(); // working copy QString line=text; // loop through the list of replacement patterns for (int index=0;index -1 && cursorPos >= index) { if (cursorPos < index + captures[0].length()) cursorPos = newIndex; else { if (captures[0].length() > replaceWith.length()) cursorPos -= captures[0].length() - replaceWith.length(); else cursorPos += replaceWith.length() - captures[0].length(); } } index = newIndex; } } while (index >= 0 && index < line.length()); } else { QRegExp needleReg(pattern); needleReg.setPatternSyntax(QRegExp::FixedString); int index=line.indexOf(needleReg); while (index>=0) { int length,nextLength,patLen,repLen; patLen=pattern.length(); repLen=replacement.length(); length=index; length+=patLen; nextLength=length; //nextlength is used to account for the replacement taking up less space QChar before,after; if (index!=0) before = line.at(index-1); if (line.length() > length) after = line.at(length); if (index==0 || before.isSpace() || before.isPunct()) { if (line.length() == length || after.isSpace() || after.isPunct()) { // allow for var expansion in autoreplace replacement = Konversation::doVarExpansion(replacement); line.replace(index,patLen,replacement); nextLength = index+repLen; } } if (cursorPos > -1 && cursorPos >= index) { if (cursorPos < length) cursorPos = nextLength; else { if (patLen > repLen) cursorPos -= patLen - repLen; else cursorPos += repLen - patLen; } } index=line.indexOf(needleReg,nextLength); } } } } return QPair(line, cursorPos); } void Application::doInlineAutoreplace(KTextEdit* textEdit) { QTextCursor cursor(textEdit->document()); cursor.beginEditBlock(); const QPair& replace = Application::instance()->doAutoreplace(textEdit->toPlainText(), true, textEdit->textCursor().position()); cursor.select(QTextCursor::Document); cursor.insertText(replace.first); cursor.setPosition(replace.second); cursor.endEditBlock(); textEdit->setTextCursor(cursor); } void Application::openUrl(const QString& url) { if (!Preferences::self()->useCustomBrowser() || url.startsWith(QLatin1String("mailto:")) || url.startsWith(QLatin1String("amarok:"))) { if (url.startsWith(QLatin1String("irc://")) || url.startsWith(QLatin1String("ircs://"))) Application::instance()->getConnectionManager()->connectTo(Konversation::SilentlyReuseConnection, url); else if (url.startsWith(QLatin1String("mailto:"))) QDesktopServices::openUrl(QUrl(url)); else #ifndef Q_OS_WIN new KRun(QUrl(url), Application::instance()->getMainWindow()); #else QDesktopServices::openUrl(QUrl::fromUserInput(url)); #endif } else { QHash map; map.insert(QLatin1Char('u'), url); const QString cmd = KMacroExpander::expandMacrosShellQuote(Preferences::self()->webBrowserCmd(), map); const QStringList args = KShell::splitArgs(cmd); if (!args.isEmpty()) { KProcess::startDetached(args); return; } } } Konversation::Sound* Application::sound() { if (!m_sound) m_sound = new Konversation::Sound; return m_sound; } void Application::updateProxySettings() { if (Preferences::self()->proxyEnabled()) { QNetworkProxy proxy; if (Preferences::self()->proxyType() == Preferences::Socksv5Proxy) { proxy.setType(QNetworkProxy::Socks5Proxy); } else { proxy.setType(QNetworkProxy::HttpProxy); } proxy.setHostName(Preferences::self()->proxyAddress()); proxy.setPort(Preferences::self()->proxyPort()); proxy.setUser(Preferences::self()->proxyUsername()); QString password; if(wallet()) { int ret = wallet()->readPassword(QStringLiteral("ProxyPassword"), password); if(ret != 0) { qCritical() << "Failed to read the proxy password from the wallet, error code:" << ret; } } proxy.setPassword(password); QNetworkProxy::setApplicationProxy(proxy); } else { QNetworkProxy::setApplicationProxy(QNetworkProxy::DefaultProxy); } } KWallet::Wallet* Application::wallet() { if(!m_wallet) { WId winid = 0; if(mainWindow) winid = mainWindow->winId(); m_wallet = KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(), winid); if(!m_wallet) return NULL; connect(m_wallet, &KWallet::Wallet::walletClosed, this, &Application::closeWallet); if(!m_wallet->hasFolder(QStringLiteral("Konversation"))) { if(!m_wallet->createFolder(QStringLiteral("Konversation"))) { qCritical() << "Failed to create folder Konversation in the network wallet."; closeWallet(); return NULL; } } if(!m_wallet->setFolder(QStringLiteral("Konversation"))) { qCritical() << "Failed to set active folder to Konversation in the network wallet."; closeWallet(); return NULL; } } return m_wallet; } void Application::closeWallet() { delete m_wallet; m_wallet = NULL; } +void Application::handleActivate(const QStringList& arguments) +{ + m_commandLineParser->parse(arguments); + + newInstance(m_commandLineParser); + + KStartupInfo::setNewStartupId(mainWindow, KStartupInfo::startupId()); + KWindowSystem::forceActiveWindow(mainWindow->winId()); +} + // kate: space-indent on; tab-width 4; indent-width 4; mixed-indent off; replace-tabs on; // vim: set et sw=4 ts=4 cino=l1,cs,U1: diff --git a/src/application.h b/src/application.h index b1ac1825..e87f98d0 100644 --- a/src/application.h +++ b/src/application.h @@ -1,199 +1,207 @@ /* 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. */ /* Copyright (C) 2002 Dario Abatianni Copyright (C) 2005 Ismail Donmez Copyright (C) 2005 Peter Simonsson Copyright (C) 2005 John Tapsell Copyright (C) 2005-2008 Eike Hein */ #ifndef APPLICATION_H #define APPLICATION_H #include #include #include "preferences.h" #include "mainwindow.h" #include "server.h" #include "osd.h" #include "identity.h" #include "ircqueue.h" #include class ConnectionManager; class AwayManager; class ScriptLauncher; class Server; class QuickConnectDialog; class Images; class ServerGroupSettings; class QStandardItemModel; class QCommandLineParser; class KTextEdit; namespace Konversation { class DBus; class IdentDBus; class Sound; class NotificationHandler; namespace DCC { class TransferManager; } } namespace KWallet { class Wallet; } class Application : public QApplication { Q_OBJECT public: /** This function in general shouldn't be called, because in the future there * may be multiple windows. * However, in some situations we have messageboxes that aren't targeted for * any particular main window, such as general errors from dcop calls. * * Note to any MDI developer - get this to return any of the windows, or some * 'main' one. */ MainWindow* getMainWindow() { return mainWindow; } ConnectionManager* getConnectionManager() { return m_connectionManager; } AwayManager* getAwayManager() { return m_awayManager; } ScriptLauncher* getScriptLauncher() { return m_scriptLauncher; } Konversation::DCC::TransferManager* getDccTransferManager() { return m_dccTransferManager; } // HACK void showQueueTuner(bool); // URL-Catcher QStandardItemModel* getUrlModel() { return m_urlModel; } Application(int &argc, char **argv); ~Application(); static Application* instance(); /** For D-Bus, a user can be specified as user@irc.server.net * or user\@servergroup or using the unicode separator symbol 0xE120 instead * of the "@". This function takes a string like the above examples, and * modifies ircnick and serverOrGroup to contain the split up string. If * the string doesn't have an @ or 0xE120, ircnick is set to the * nick_server, and serverOrGroup is set to empty. * Behaviour is undefined for serverOrGroup if multiple @ or 0xE120 are found. * @param nick_server A string containting ircnick and possibly servername or server group * @param ircnick This is modified to contain the ircnick * @param serverOrGroup This is modified to contain the servername, servergroup or an empty string. */ static void splitNick_Server(const QString& nick_server, QString &ircnick, QString &serverOrGroup); /** Tries to find a nickinfo for a given ircnick on a given ircserver. * @param ircnick The case-insensitive ircnick of the person you want to find. e.g. "johnflux" * @param serverOrGroup The case-insensitive server name (e.g. "irc.kde.org") or server group name (e.g. "freenode"), or null to search all servers * @return A nickinfo for this user and server if one is found. */ NickInfoPtr getNickInfo(const QString &ircnick, const QString &serverOrGroup); OSDWidget* osd; Konversation::Sound* sound(); IRCQueue::EmptyingRate staticrates[Server::_QueueListSize]; Images* images() { return m_images; } Konversation::NotificationHandler* notificationHandler() const { return m_notificationHandler; } // auto replacement for input or output lines QPair doAutoreplace(const QString& text, bool output, int cursorPos = -1); // inline auto replacement for input lines void doInlineAutoreplace(KTextEdit* textEdit); void newInstance(QCommandLineParser *args); static void openUrl(const QString& url); /// The wallet used to store passwords. Opens the wallet if it's closed. KWallet::Wallet* wallet(); void abortScheduledRestart() { m_restartScheduled = false; } + /// The command line parser is needed for handling parsing arguments on new activations. + void setCommandLineParser(QCommandLineParser *parser) { m_commandLineParser = parser; } + QCommandLineParser *commandLineParser() const { return m_commandLineParser; } + Q_SIGNALS: void serverGroupsChanged(const Konversation::ServerGroupSettingsPtr serverGroup); void appearanceChanged(); // FIXME TODO: Rather than relying on this catch-all, consumers should be rewritten to catch appropriate QEvents. public Q_SLOTS: void restart(); void readOptions(); void saveOptions(bool updateGUI=true); void fetchQueueRates(); ///< on Application::readOptions() void stashQueueRates(); ///< on application exit void resetQueueRates(); ///< when QueueTuner says to int countOfQueues() { return Server::_QueueListSize-1; } void prepareShutdown(); void storeUrl(const QString& origin, const QString& newUrl, const QDateTime& dateTime); + void handleActivate(const QStringList& arguments); + protected Q_SLOTS: void openQuickConnectDialog(); void dbusMultiServerRaw(const QString &command); void dbusRaw(const QString& connection, const QString &command); void dbusSay(const QString& connection, const QString& target, const QString& command); void dbusInfo(const QString& string); void sendMultiServerCommand(const QString& command, const QString& parameter); void updateProxySettings(); void closeWallet(); protected: bool event(QEvent* event); private: void implementRestart(); ConnectionManager* m_connectionManager; AwayManager* m_awayManager; Konversation::DCC::TransferManager* m_dccTransferManager; ScriptLauncher* m_scriptLauncher; QStandardItemModel* m_urlModel; Konversation::DBus* dbusObject; Konversation::IdentDBus* identDBus; QPointer mainWindow; Konversation::Sound* m_sound; QuickConnectDialog* quickConnectDialog; Images* m_images; bool m_restartScheduled; Konversation::NotificationHandler* m_notificationHandler; KWallet::Wallet* m_wallet; QNetworkConfigurationManager* m_networkConfigurationManager; + + QCommandLineParser *m_commandLineParser; }; #endif // kate: space-indent on; tab-width 4; indent-width 4; mixed-indent off; replace-tabs on; // vim: set et sw=4 ts=4 cino=l1,cs,U1: diff --git a/src/main.cpp b/src/main.cpp index 35f68be1..23ef6404 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,163 +1,164 @@ /* 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. */ /* Where it all began ... begin: Die Jan 15 05:59:05 CET 2002 copyright: (C) 2002 by Dario Abatianni email: eisfuchs@tigress.com */ #include "application.h" #include "version.h" #include "commit.h" #include #include #include #include #include #include #include #define HACKSTR(x) #x #define STRHACK(x) HACKSTR(x) int main(int argc, char* argv[]) { Application app(argc, argv); // Migrate pre-existing (4.x) configuration QStringList configFiles; configFiles.append(QLatin1String("konversationrc")); configFiles.append(QLatin1String("konversation.notifyrc")); Kdelibs4ConfigMigrator migrate(QLatin1String("konversation")); migrate.setConfigFiles(configFiles); migrate.setUiFiles(QStringList() << QLatin1String("konversationui.rc")); migrate.migrate(); KLocalizedString::setApplicationDomain("konversation"); KAboutData aboutData("konversation", i18n("Konversation"), KONVI_VERSION " #" STRHACK(COMMIT), i18n("A user-friendly IRC client"), KAboutLicense::GPL, i18n("(C) 2002-2016 by the Konversation team"), i18n("Konversation is a client for the Internet Relay Chat (IRC) protocol.\n\n" "Meet friends on the net, make new acquaintances and lose yourself in talk about your favorite subject."), QStringLiteral("http://konversation.kde.org/")); aboutData.addAuthor(i18n("Dario Abatianni"),i18n("Original Author, Project Founder"),"eisfuchs@tigress.com"); aboutData.addAuthor(i18n("Peter Simonsson"),i18n("Maintainer"),"peter.simonsson@gmail.com"); aboutData.addAuthor(i18n("Eike Hein"),i18n("Maintainer, Release Manager, User interface, Connection management, Protocol handling, Auto-away"),"hein@kde.org"); aboutData.addAuthor(i18n("Shintaro Matsuoka"),i18n("DCC, Encoding handling, OSD positioning"),"shin@shoegazed.org"); aboutData.addAuthor(i18n("Eli MacKenzie"),i18n("Protocol handling, Input line"),"argonel@gmail.com"); aboutData.addAuthor(i18n("İsmail Dönmez"),i18n("Blowfish, SSL support, KNetwork port, Colored nicks, Nicklist themes"),"ismail@kde.org"); aboutData.addAuthor(i18n("John Tapsell"),i18n("Refactoring, KAddressBook/Kontact integration"), "john@geola.co.uk"); aboutData.addAuthor(i18n("Bernd Buschinski"),i18n("DCC port to KDE 4, various DCC improvements"), "b.buschinski@web.de"); aboutData.addCredit(i18n("Olivier Bédard"),i18n("Website hosting")); aboutData.addCredit(i18n("Jędrzej Lisowski"),i18n("Website maintenance"),"yesoos@gmail.com"); aboutData.addCredit(i18n("Christian Muehlhaeuser"),i18n("Multiple modes extension, Close widget placement, OSD functionality"),"chris@chris.de"); aboutData.addCredit(i18n("Gary Cramblitt"),i18n("Documentation, Watched Nicks improvements, Custom web browser extension"),"garycramblitt@comcast.net"); aboutData.addCredit(i18n("Matthias Gierlings"),i18n("Color configurator, Highlight dialog"),"gismore@users.sourceforge.net"); aboutData.addCredit(i18n("Alex Zepeda"),i18n("DCOP interface"),"garbanzo@hooked.net"); aboutData.addCredit(i18n("Stanislav Karchebny"),i18n("Non-Latin1-Encodings"),"berkus@users.sourceforge.net"); aboutData.addCredit(i18n("Mickael Marchand"),i18n("Konsole part view"),"marchand@kde.org"); aboutData.addCredit(i18n("Michael Goettsche"),i18n("Quick connect, Ported new OSD, other features and bugfixes"),"michael.goettsche@kdemail.net"); aboutData.addCredit(i18n("Benjamin Meyer"),i18n("A Handful of fixes and code cleanup"),"ben+konversation@meyerhome.net"); aboutData.addCredit(i18n("Jakub Stachowski"),i18n("Drag&Drop improvements"),"qbast@go2.pl"); aboutData.addCredit(i18n("Sebastian Sariego"),i18n("Artwork"),"segfault@kde.cl"); aboutData.addCredit(i18n("Renchi Raju"),i18n("Firefox style searchbar")); aboutData.addCredit(i18n("Michael Kreitzer"),i18n("Raw modes, Tab grouping per server, Ban list"),"mrgrim@gr1m.org"); aboutData.addCredit(i18n("Frauke Oster"),i18n("System tray patch"),"frauke@frsv.de"); aboutData.addCredit(i18n("Lucijan Busch"),i18n("Bug fixes"),"lucijan@kde.org"); aboutData.addCredit(i18n("Sascha Cunz"),i18n("Extended user modes patch"),"mail@sacu.de"); aboutData.addCredit(i18n("Steve Wollkind"),i18n("Close visible tab with shortcut patch"),"steve@njord.org"); aboutData.addCredit(i18n("Thomas Nagy"),i18n("Cycle tabs with mouse scroll wheel"),"thomas.nagy@eleve.emn.fr"); aboutData.addCredit(i18n("Tobias Olry"),i18n("Channel ownership mode patch"),"tobias.olry@web.de"); aboutData.addCredit(i18n("Ruud Nabben"),i18n("Option to enable IRC color filtering"),"r.nabben@gawab.com"); aboutData.addCredit(i18n("Lothar Braun"),i18n("Bug fixes"),"mail@lobraun.de"); aboutData.addCredit(i18n("Ivor Hewitt"),i18n("Bug fixes, OSD work, clearing topics"),"ivor@ivor.org"); aboutData.addCredit(i18n("Emil Obermayr"),i18n("Sysinfo script"),"nobs@tigress.com"); aboutData.addCredit(i18n("Stanislav Nikolov"),i18n("Bug fixes"),"valsinats@gmail.com"); aboutData.addCredit(i18n("Juan Carlos Torres"),i18n("Auto-join context menu"),"carlosdgtorres@gmail.com"); aboutData.addCredit(i18n("Travis McHenry"),i18n("Various fixes, ported encryption to QCA2, added DH1080 key exchange support."),"tmchenryaz@cox.net"); aboutData.addCredit(i18n("Modestas Vainius"),i18n("Bug fixes and enhancements."),"modestas@vainius.eu"); aboutData.addCredit(i18n("Abdurrahman AVCI"),i18n("Various bug fixes and enhancements."),"abdurrahmanavci@gmail.com"); aboutData.addCredit(i18n("Martin Blumenstingl"),i18n("KStatusNotifierItem support, KIdleTime support, other enhancements"),"darklight.xdarklight@googlemail.com"); KAboutData::setApplicationData(aboutData); KCrash::initialize(); app.setApplicationName(aboutData.componentName()); app.setOrganizationDomain(aboutData.organizationDomain()); app.setApplicationVersion(aboutData.version()); app.setApplicationDisplayName(aboutData.displayName()); app.setWindowIcon(QIcon::fromTheme(QLatin1String("konversation"))); app.setAttribute(Qt::AA_UseHighDpiPixmaps, true); QCommandLineParser cmdLineParser; cmdLineParser.addHelpOption(); cmdLineParser.addVersionOption(); cmdLineParser.addPositionalArgument(QStringLiteral("url"), i18n("irc:// URL or server hostname")); cmdLineParser.addOption(QCommandLineOption(QStringLiteral("server"), i18n("Server to connect"), i18n("server"))); cmdLineParser.addOption(QCommandLineOption(QStringLiteral("port"), i18n("Port to use"), i18n("port"), "6667")); cmdLineParser.addOption(QCommandLineOption(QStringLiteral("channel"), i18n("Channel to join after connection"), i18n("channel"))); cmdLineParser.addOption(QCommandLineOption(QStringLiteral("nick"), i18n("Nickname to use"), i18n("nickname"))); cmdLineParser.addOption(QCommandLineOption(QStringLiteral("password"), i18n("Password for connection"), i18n("password"))); cmdLineParser.addOption(QCommandLineOption(QStringLiteral("ssl"), i18n("Use SSL for connection"))); cmdLineParser.addOption(QCommandLineOption(QStringLiteral("noautoconnect"), i18n("Disable auto-connecting to any IRC networks"))); cmdLineParser.addOption(QCommandLineOption(QStringLiteral("startupdelay"), i18n("Delay D-Bus activity and UI creation by the specified amount of milliseconds"), i18n("msec"), "2000")); // cmdLineParser.addOption(QCommandLineOption(QStringLiteral("restart"), i18n("Quits and restarts Konversation (if running, otherwise has no effect)"))); FIXME KF5 Port: --restart #ifndef QT_NO_DEBUG cmdLineParser.addOption(QCommandLineOption(QStringLiteral("nui"), i18n("Sets KUniqueApplication::NonUniqueInstance (debug only, use with caution)"))); #endif aboutData.setupCommandLine(&cmdLineParser); cmdLineParser.process(app); if (cmdLineParser.isSet(QStringLiteral("startupdelay"))) { bool ok; ulong delay = cmdLineParser.value(QStringLiteral("startupdelay")).toULong(&ok); if (ok) { QMutex dummy; dummy.lock(); QWaitCondition waitCondition; waitCondition.wait(&dummy, delay); } } KDBusService::StartupOptions startOptions = KDBusService::Unique; #ifndef QT_NO_DEBUG if (cmdLineParser.isSet(QStringLiteral("nui"))) startOptions = KDBusService::Multiple; #endif KDBusService dbusService(startOptions); aboutData.processCommandLine(&cmdLineParser); app.newInstance(&cmdLineParser); + app.setCommandLineParser(&cmdLineParser); QObject::connect(&dbusService, &KDBusService::activateRequested, - app.instance()->getMainWindow(), &MainWindow::activateAndRaiseWindow, - Qt::DirectConnection); + &app, &Application::handleActivate, + Qt::DirectConnection); return app.exec(); }