diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index df6cafe1..70ae52de 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,273 +1,280 @@ include(ECMAddAppIcon) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/config) include_directories(config dcc irc viewer upnp) set(core_SRCS #==================================== #=== Application config/preferences.cpp application.cpp dbus.cpp mainwindow.cpp main.cpp common.cpp sound.cpp ssllabel.cpp statusbar.cpp bookmarkhandler.cpp scriptlauncher.cpp konsolepanel.cpp notificationhandler.cpp awaymanager.cpp connectionmanager.cpp connectionsettings.cpp identity.cpp identitydialog.cpp identitymodel.cpp #=== GUI urlcatcher.cpp queuetuner.cpp quickconnectdialog.cpp ) set (irc_SRCS #== IRC irc/server.cpp irc/query.cpp irc/channel.cpp irc/channellistpanel.cpp irc/channelnick.cpp irc/modebutton.cpp irc/joinchanneldialog.cpp irc/invitedialog.cpp irc/topichistorymodel.cpp irc/irccharsets.cpp irc/nick.cpp irc/nickinfo.cpp irc/nicklistview.cpp irc/nicksonline.cpp irc/nicksonlineitem.cpp #=== Server irc/inputfilter.cpp irc/outputfilter.cpp irc/outputfilterresolvejob.cpp irc/ircqueue.cpp irc/servergroupdialog.cpp irc/servergroupsettings.cpp irc/serverison.cpp irc/serverlistdialog.cpp irc/serverlistview.cpp irc/serversettings.cpp irc/messagemodel.cpp # WIPQTQUICK irc/usermodel.cpp # WIPQTQUICK ) ki18n_wrap_ui(irc_SRCS irc/channellistpanelui.ui irc/channeldialogui.ui irc/joinchannelui.ui irc/serverdialogui.ui irc/servergroupdialogui.ui irc/serverlistdialogui.ui irc/invitedialog.ui ) #=== Configuration dialog pages set(config_SRCS config/configdialog.cpp config/settingsdialog.cpp config/settingspage.cpp config/alias_config.cpp config/autoreplace_config.cpp config/dcc_config.cpp config/highlight_config.cpp config/ignore_config.cpp config/nicklistbehavior_config.cpp config/osd_config.cpp config/tabs_config.cpp config/theme_config.cpp config/quickbuttons_config.cpp config/warnings_config.cpp config/connectionbehavior_config.cpp config/highlighttreewidget.cpp ) ki18n_wrap_ui(config_SRCS config/alias_configui.ui config/autoreplace_configui.ui config/chatwindowappearance_config.ui config/chatwindowbehaviour_config.ui config/colorsappearance_config.ui config/connectionbehavior_config.ui config/dcc_configui.ui config/fontappearance_config.ui config/generalbehavior_configui.ui config/highlight_configui.ui config/ignore_configui.ui config/log_config.ui config/nicklistbehavior_configui.ui config/osd_configui.ui config/quickbuttons_configui.ui config/tabnotifications_config.ui config/tabs_configui.ui config/theme_configui.ui config/warnings_configui.ui config/watchednicknames_configui.ui ) #=== Viewer set(viewer_SRCS viewer/ircinput.cpp viewer/ircview.cpp viewer/chatwindow.cpp viewer/rawlog.cpp viewer/statuspanel.cpp viewer/ircviewbox.cpp viewer/viewcontainer.cpp viewer/pasteeditor.cpp viewer/highlight.cpp viewer/highlightviewitem.cpp viewer/ignore.cpp viewer/ignorelistviewitem.cpp viewer/irccolorchooser.cpp viewer/logfilereader.cpp viewer/insertchardialog.cpp viewer/osd.cpp viewer/topiclabel.cpp viewer/awaylabel.cpp viewer/editnotifydialog.cpp viewer/emoticons.cpp viewer/images.cpp viewer/quickbutton.cpp viewer/searchbar.cpp viewer/irccontextmenus.cpp - viewer/trayicon.cpp viewer/viewspringloader.cpp viewer/channeloptionsdialog.cpp viewer/topicedit.cpp viewer/topichistoryview.cpp viewer/viewtree.cpp viewer/completer.cpp viewer/inputhistorymodel.cpp viewer/qclipboardwrapper.cpp viewer/actioncollectionmodel.cpp ) +if(NOT ANDROID) + list(APPEND viewer_SRCS viewer/trayicon.cpp) +endif() + ki18n_wrap_ui(viewer_SRCS viewer/channeloptionsui.ui viewer/irccolorchooserui.ui viewer/pasteeditor.ui ) #=== DCC set(dcc_SRCS dcc/chat.cpp dcc/chatcontainer.cpp dcc/dcccommon.cpp dcc/dccfiledialog.cpp dcc/recipientdialog.cpp dcc/resumedialog.cpp dcc/transfer.cpp dcc/transferdetailedinfopanel.cpp dcc/transfermanager.cpp dcc/transferpanel.cpp dcc/transferrecv.cpp dcc/transfersend.cpp dcc/transferlistmodel.cpp dcc/transferview.cpp dcc/whiteboard.cpp dcc/whiteboardcolorchooser.cpp dcc/whiteboardfontchooser.cpp dcc/whiteboardglobals.cpp dcc/whiteboardpaintarea.cpp dcc/whiteboardtoolbar.cpp ) ki18n_wrap_ui(dcc_SRCS dcc/transferdetailedinfopanelui.ui dcc/transferdetailedtimeinfopanelui.ui dcc/whiteboardtoolbarui.ui dcc/whiteboardfontchooserui.ui ) if (Qca-qt5_FOUND) set(cipher_SRCS cipher.cpp) endif (Qca-qt5_FOUND) set(upnp_SRCS upnp/soap.cpp upnp/upnpdescriptionparser.cpp upnp/upnpmcastsocket.cpp upnp/upnprouter.cpp ) set (completed_SRCS ${core_SRCS} ${irc_SRCS} ${viewer_SRCS} ${config_SRCS} ${cipher_SRCS} ${upnp_SRCS} ${dcc_SRCS}) set (konversation_SRCS ${completed_SRCS}) ki18n_wrap_ui(konversation_SRCS identitydialog.ui queuetunerbase.ui viewer/searchbarbase.ui ) kconfig_add_kcfg_files(konversation_SRCS config/preferences_base.kcfgc) # Sets the icon on Windows and OSX file(GLOB ICONS_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/../data/images/icons/*apps-konversation.png") ecm_add_app_icon(konversation_SRCS ICONS ${ICONS_SRCS}) add_executable(konversation ${konversation_SRCS}) target_link_libraries(konversation Qt5::Widgets Qt5::Quick # WIPQTQUICK Qt5::QuickWidgets # WIPQTQUICK KF5::Archive KF5::Bookmarks KF5::ConfigWidgets KF5::Crash KF5::Emoticons KF5::I18n KF5::IdleTime KF5::NotifyConfig KF5::KIOFileWidgets KF5::KIOWidgets KF5::Parts KF5::Solid KF5::WidgetsAddons KF5::GlobalAccel KF5::DBusAddons KF5::CoreAddons KF5::Notifications KF5::WindowSystem KF5::IconThemes KF5::ItemViews KF5::ItemModels # WIPQTQUICK Destructuring ViewContainer to flat list Phonon::phonon4qt5) if(USE_QRC) target_compile_definitions(konversation PRIVATE -DUSE_QRC) target_sources(konversation PRIVATE qtquick/uipackages/default.qrc) else() target_link_libraries(konversation KF5::Package) endif() if(TARGET KF5::Wallet) target_link_libraries(konversation KF5::Wallet) endif() if (Qca-qt5_FOUND) target_link_libraries(konversation qca-qt5) endif () if (WIN32) target_link_libraries(konversation ws2_32) # for symbols from winsock2.h: ntohl, etc. endif() +if (ANDROID) + target_link_libraries(konversation KF5::Kirigami2) +endif() + install(TARGETS konversation ${INSTALL_TARGETS_DEFAULT_ARGS}) add_subdirectory(qtquick) diff --git a/src/application.cpp b/src/application.cpp index 713eb9e0..a9654ffe 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -1,1590 +1,1594 @@ /* 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 "messagemodel.h" // WIPQTQUICK #include "usermodel.h" // WIPQTQUICK #include "identitymodel.h" // WIPQTQUICK #include "completer.h" // WIPQTQUICK #include "inputhistorymodel.h" // WIPQTQUICK #include "irccontextmenus.h" // WIPQTQUICK #include "qclipboardwrapper.h" // WIPQTQUICK #include "statusbar.h" // WIPQTQUICK #include "trayicon.h" // WIPQTQUICK #include "actioncollectionmodel.h" // WIPQTQUICK #include #include #include #include #include #include #include #include #include #include #include // WIPQTQUICK #include // WIPQTQUICK #include // WIPQTQUICK #include // WIPQTQUICK #include // WIPQTQUICK #include #include #include #include #ifdef WITH_KWALLET #include #endif #include #include #include #ifndef USE_QRC #include // WIPQTQUICK #endif #include // WIPQTQUICK using namespace Konversation; Application::Application(int &argc, char **argv) : QApplication(argc, argv) { mainWindow = nullptr; m_restartScheduled = false; m_connectionManager = nullptr; m_awayManager = nullptr; m_scriptLauncher = nullptr; quickConnectDialog = nullptr; osd = nullptr; m_images = nullptr; m_sound = nullptr; m_dccTransferManager = nullptr; m_notificationHandler = nullptr; m_urlModel = nullptr; dbusObject = nullptr; identDBus = nullptr; m_networkConfigurationManager = nullptr; } 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 = nullptr; closeWallet(); delete m_networkConfigurationManager; if (m_restartScheduled) implementRestart(); } void Application::implementRestart() { // Pop off the executable name. May not be the first argument in argv // everywhere, so verify first. if (QFileInfo(m_restartArguments.first()) == QFileInfo(QCoreApplication::applicationFilePath())) m_restartArguments.removeFirst(); // Don't round-trip --restart. m_restartArguments.removeAll(QStringLiteral("--restart")); // Avoid accumulating multiple --startupdelay arguments across multiple // uses of restart(). if (m_restartArguments.contains(QStringLiteral("--startupdelay"))) { int index = m_restartArguments.lastIndexOf(QStringLiteral("--startupdelay")); if (index < m_restartArguments.count() - 1 && !m_restartArguments.at(index + 1).startsWith(QLatin1Char('-'))) { QString delayArgument = m_restartArguments.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) m_restartArguments.replace(index + 1, QStringLiteral("2000")); } } else m_restartArguments << QStringLiteral("--startupdelay") << QStringLiteral("2000"); KProcess::startDetached(QCoreApplication::applicationFilePath(), m_restartArguments); } void Application::newInstance(QCommandLineParser *args) { QString url; if (args->positionalArguments().count() > 1) url = args->positionalArguments().at(1); 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 = nullptr; // Sound object used to play sound is created when needed. m_sound = nullptr; // 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(); mainWindow->hide(); // WIPQTQUICK 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(); // BEGIN WIPQTQUICK mainWindow->hide(); m_identityModel = new IdentityModel(this); m_messageModel = new MessageModel(this); m_filteredMessageModel = new FilteredMessageModel(this); m_filteredMessageModel->setSourceModel(m_messageModel); m_filteredUserModel = new FilteredUserModel(this); m_completer = new Completer(this); m_completer->setSourceModel(m_filteredUserModel); m_inputHistoryModel = new InputHistoryModel(this); m_filteredInputHistoryModel = new FilteredInputHistoryModel(this); m_filteredInputHistoryModel->setSourceModel(m_inputHistoryModel); // Filter on the new view. connect(mainWindow->getViewContainer(), &ViewContainer::viewChanged, this, [this](const QModelIndex &idx) { if (mainWindow->getCloseApp()) { return; } m_filteredMessageModel->setFilterView(static_cast(idx.internalPointer())); m_filteredUserModel->setFilterView(static_cast(idx.internalPointer())); m_completer->setContextView(static_cast(idx.internalPointer())); } ); // Update filter when ViewContainer resets. QObject::connect(mainWindow->getViewContainer(), &QAbstractItemModel::modelAboutToBeReset, this, [this]() { m_filteredMessageModel->setFilterView(nullptr); } ); m_viewListModel = new KDescendantsProxyModel(this); m_viewListModel->setSourceModel(mainWindow->getViewContainer()); +#ifndef Q_OS_ANDROID QObject::connect(mainWindow->systemTrayIcon(), &KStatusNotifierItem::activateRequested, this, [this](bool active, const QPoint &pos) { Q_UNUSED(pos) if (active) { getQuickMainWindow()->show(); } else { getQuickMainWindow()->hide(); } } ); +#endif qputenv("QT_QUICK_CONTROLS_STYLE", "org.kde.desktop"); m_qmlEngine = new QQmlApplicationEngine(this); // register common enums needed in QML qRegisterMetaType("Konversation::ConnectionState"); // C++ -> QML signal qmlRegisterUncreatableMetaObject(Konversation::staticMetaObject, "org.kde.konversation", 1, 0, "Konversation", "Enums only"); qmlRegisterUncreatableType("org.kde.konversation", 1, 0, "MessageModel", ""); qmlRegisterUncreatableType("org.kde.konversation", 1, 0, "InputHistoryModel", ""); qmlRegisterUncreatableType("org.kde.konversation", 1, 0, "IrcContextMenus", ""); // setup qml context m_qmlEngine->rootContext()->setContextProperty(QStringLiteral("konvApp"), Application::instance()); m_qmlEngine->rootContext()->setContextProperty(QStringLiteral("viewModel"), mainWindow->getViewContainer()); m_qmlEngine->rootContext()->setContextProperty(QStringLiteral("viewListModel"), m_viewListModel); m_qmlEngine->rootContext()->setContextProperty(QStringLiteral("messageModel"), m_filteredMessageModel); m_qmlEngine->rootContext()->setContextProperty(QStringLiteral("userModel"), m_filteredUserModel); m_qmlEngine->rootContext()->setContextProperty(QStringLiteral("identityModel"), m_identityModel); m_qmlEngine->rootContext()->setContextProperty(QStringLiteral("completer"), m_completer); m_qmlEngine->rootContext()->setContextProperty(QStringLiteral("inputHistoryModel"), m_filteredInputHistoryModel); m_qmlEngine->rootContext()->setContextProperty(QStringLiteral("shortcutsModel"), mainWindow->getActionCollectionModel()); m_qmlEngine->rootContext()->setContextProperty(QStringLiteral("contextMenus"), IrcContextMenus::self()); m_qmlEngine->rootContext()->setContextProperty(QStringLiteral("clipboard"), new QClipboardWrapper(this)); loadUiPackage(args->value(QStringLiteral("uipackage"))); if (Preferences::self()->showTrayIcon() && Preferences::self()->hideToTrayOnStartup()) getQuickMainWindow()->hide(); else getQuickMainWindow()->show(); // END: WIPQTQUICK 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 (auto & it : serversToAutoconnect) { 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); } else if (args->isSet(QStringLiteral("restart"))) { restart(); return; } 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()); } bool Application::loadUiPackage(const QString &packageName) { if (packageName.isEmpty()) { qDebug() << "Error loading UI package: Package name is empty. Doing nothing."; return false; } QLatin1Literal packageNamePrefix("org.kde.konversation.uipackages."); QString fixedName(packageName.startsWith(packageNamePrefix) ? packageName : packageNamePrefix + packageName); #ifndef USE_QRC KPackage::Package p = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Konversation/UiPackage"), fixedName); if (!p.isValid()) { qDebug() << "Error loading UI package: Package" << packageName << "is invalid."; qDebug() << "Available Qt Quick UI packages for Konversation (name / id):"; auto plist = KPackage::PackageLoader::self()->listPackages(QStringLiteral("Konversation/UiPackage")); for (const auto &pkg : plist) { qDebug() << " " << pkg.name() << "/" << pkg.pluginId(); } return false; } #endif if (m_qmlEngine->rootObjects().count()) { qDebug() << "Unloading current UI package:" << m_currentUiPackage; // Close the window. static_cast(m_qmlEngine->rootObjects().first())->close(); // Delete the root object. qDeleteAll(m_qmlEngine->rootObjects()); // Clear the component cache. m_qmlEngine->clearComponentCache(); } #ifdef USE_QRC m_qmlEngine->load(QUrl("qrc:/default/contents/main.qml")); #else m_qmlEngine->load(QUrl::fromLocalFile(p.filePath("window"))); #endif m_currentUiPackage = fixedName; QObject::connect(m_qmlEngine->rootObjects().first(), SIGNAL(openServerList()), mainWindow, SLOT(openServerList())); QObject::connect(m_qmlEngine->rootObjects().first(), SIGNAL(openIdentities()), mainWindow, SLOT(openIdentitiesDialog())); QObject::connect(m_qmlEngine->rootObjects().first(), SIGNAL(showLegacyMainWindow()), mainWindow, SLOT(show())); QObject::connect(m_qmlEngine->rootObjects().first(), SIGNAL(openLegacyConfigDialog()), mainWindow, SLOT(openPrefsDialog())); QObject::connect(m_qmlEngine->rootObjects().first(), SIGNAL(quitApp()), mainWindow, SLOT(quitProgram())); +#ifndef Q_OS_ANDROID QObject::connect(m_qmlEngine->rootObjects().first(), SIGNAL(endNotification()), mainWindow->systemTrayIcon(), SLOT(endNotification())); +#endif QObject::connect(m_qmlEngine->rootObjects().first(), SIGNAL(setStatusBarTempText(QString)), mainWindow->getStatusBar(), SLOT(setMainLabelTempText(QString))); QObject::connect(m_qmlEngine->rootObjects().first(), SIGNAL(clearStatusBarTempText()), mainWindow->getStatusBar(), SLOT(clearMainLabelTempText())); return true; } QWindow* Application::getQuickMainWindow() { return static_cast(m_qmlEngine->rootObjects().first()); } 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 = nullptr; } if (m_connectionManager) { m_connectionManager->quitServers(); m_connectionManager->blockSignals(true); delete m_connectionManager; m_connectionManager = nullptr; } } 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, nullptr); } 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) nullptr; } // auto replace on input/output QVariantList 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); } } } } QVariantList ret; ret << line << cursorPos; return ret; } void Application::doInlineAutoreplace(KTextEdit* textEdit) { QTextCursor cursor(textEdit->document()); cursor.beginEditBlock(); const QVariantList& replace = Application::instance()->doAutoreplace(textEdit->toPlainText(), true, textEdit->textCursor().position()); cursor.select(QTextCursor::Document); cursor.insertText(replace[0].toString()); cursor.setPosition(replace[1].toInt()); 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()); #ifdef WITH_KWALLET 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); #endif QNetworkProxy::setApplicationProxy(proxy); } else { QNetworkProxy::setApplicationProxy(QNetworkProxy::DefaultProxy); } } #ifdef WITH_KWALLET 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 nullptr; 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 nullptr; } } if(!m_wallet->setFolder(QStringLiteral("Konversation"))) { qCritical() << "Failed to set active folder to Konversation in the network wallet."; closeWallet(); return nullptr; } } return m_wallet; } #endif void Application::closeWallet() { #ifdef WITH_KWALLET delete m_wallet; m_wallet = nullptr; #endif } void Application::handleActivate(const QStringList& arguments) { m_commandLineParser->parse(QStringList(applicationFilePath()) << arguments); if(m_commandLineParser->isSet(QStringLiteral("restart"))) { m_restartArguments = arguments; } newInstance(m_commandLineParser); KStartupInfo::setNewStartupId(mainWindow, KStartupInfo::startupId()); mainWindow->show(); mainWindow->raise(); } // 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/awaymanager.cpp b/src/awaymanager.cpp index c1e1f7f9..55dd62c4 100644 --- a/src/awaymanager.cpp +++ b/src/awaymanager.cpp @@ -1,352 +1,354 @@ /* 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) 1999 Martin R. Jones Copyright (C) 2008 Eike Hein Copyright (C) 2010 Martin Blumenstingl */ #include "awaymanager.h" #include "application.h" #include "connectionmanager.h" #include "server.h" #include "preferences.h" #include "trayicon.h" #include #include #include #include AwayManager::AwayManager(QObject* parent) : QObject(parent) { m_connectionManager = Application::instance()->getConnectionManager(); connect(KIdleTime::instance(), SIGNAL(resumingFromIdle()), this, SLOT(resumeFromIdle())); connect(KIdleTime::instance(), SIGNAL(timeoutReached(int)), this, SLOT(idleTimeoutReached(int))); // Catch the first "resume event" (= user input) so we correctly catch the first // resume event in case the user is already idle on startup). KIdleTime::instance()->catchNextResumeEvent(); } AwayManager::~AwayManager() = default; int AwayManager::minutesToMilliseconds(int minutes) { return minutes * 60 * 1000; } void AwayManager::identitiesChanged() { QHash newIdentityWithIdleTimeMapping; const QList serverList = m_connectionManager->getServerList(); foreach (Server* server, serverList) { IdentityPtr identity = server->getIdentity(); int identityId = identity->id(); // Calculate the auto-away time in milliseconds. int identityIdleTime = minutesToMilliseconds(identity->getAwayInactivity()); if (identity && identity->getAutomaticAway() && server->isConnected()) newIdentityWithIdleTimeMapping[identityId] = identityIdleTime; } m_identitiesWithIdleTimesOnAutoAway = newIdentityWithIdleTimeMapping; identitiesOnAutoAwayChanged(); } void AwayManager::identityOnline(int identityId) { IdentityPtr identity = Preferences::identityById(identityId); if (identity && identity->getAutomaticAway() && !m_identitiesWithIdleTimesOnAutoAway.contains(identityId)) { m_identitiesWithIdleTimesOnAutoAway[identityId] = minutesToMilliseconds(identity->getAwayInactivity()); // Notify the AwayManager implementation that a user which has auto-away enabled is not online. identityOnAutoAwayWentOnline(identityId); } } void AwayManager::identityOffline(int identityId) { if (m_identitiesWithIdleTimesOnAutoAway.remove(identityId)) // Notify the AwayManager implementation that a user which has auto-away enabled is now offline. identityOnAutoAwayWentOffline(identityId); } void AwayManager::implementManagedAway(int identityId) { const QList serverList = m_connectionManager->getServerList(); foreach (Server* server, serverList) { if (server->getIdentity()->id() == identityId && server->isConnected() && !server->isAway()) server->requestAway(); } } void AwayManager::setManagedIdentitiesAway() { QHash::ConstIterator itr = m_identitiesWithIdleTimesOnAutoAway.constBegin(); for (; itr != m_identitiesWithIdleTimesOnAutoAway.constEnd(); ++itr) implementManagedAway(itr.key()); } void AwayManager::implementManagedUnaway(const QList& identityList) { const QList serverList = m_connectionManager->getServerList(); foreach (Server* server, serverList) { IdentityPtr identity = server->getIdentity(); if (identityList.contains(identity->id()) && identity->getAutomaticUnaway() && server->isConnected() && server->isAway()) { server->requestUnaway(); } } } void AwayManager::setManagedIdentitiesUnaway() { // Set the "not away" status for all identities which have // auto-away enabled. implementManagedUnaway(m_identitiesWithIdleTimesOnAutoAway.keys()); } void AwayManager::requestAllAway(const QString& reason) { const QList serverList = m_connectionManager->getServerList(); foreach (Server* server, serverList) if (server->isConnected()) server->requestAway(reason); } void AwayManager::requestAllUnaway() { const QList serverList = m_connectionManager->getServerList(); foreach (Server* server, serverList) if (server->isConnected() && server->isAway()) server->requestUnaway(); } void AwayManager::setGlobalAway(bool away) { if (away) requestAllAway(); else requestAllUnaway(); } void AwayManager::updateGlobalAwayAction(bool away) { // Regardless of any implementation: If the given parameter indicates // that the user is not away we should simulate user activity to // ensure that the away-status of the user is really reset. if (!away) simulateUserActivity(); Application* konvApp = Application::instance(); KToggleAction* awayAction = qobject_cast(konvApp->getMainWindow()->actionCollection()->action(QStringLiteral("toggle_away"))); +#ifndef Q_OS_ANDROID Konversation::TrayIcon* trayIcon = konvApp->getMainWindow()->systemTrayIcon(); if (!awayAction) return; if (away) { const QList serverList = m_connectionManager->getServerList(); int awayCount = 0; foreach (Server* server, serverList) { if (server->isAway()) awayCount++; } if (awayCount == serverList.count()) { awayAction->setChecked(true); awayAction->setIcon(QIcon::fromTheme(QStringLiteral("im-user"))); if (trayIcon) trayIcon->setAway(true); } } else { awayAction->setChecked(false); awayAction->setIcon(QIcon::fromTheme(QStringLiteral("im-user-away"))); if (trayIcon) trayIcon->setAway(false); } +#endif } int AwayManager::calculateRemainingTime(int identityId) { // Get the idle time for the identity. int identityIdleTimeout = m_identitiesWithIdleTimesOnAutoAway[identityId]; // The remaining time until the user will be marked as "auto-away". int remainingTime = identityIdleTimeout - KIdleTime::instance()->idleTime(); return remainingTime; } void AwayManager::implementUpdateIdleTimeout(int identityId) { const QHash idleTimeouts = KIdleTime::instance()->idleTimeouts(); // calculate the remaining time until the user will be marked as away. int remainingTime = calculateRemainingTime(identityId); // Check if the user should be away right now. if (remainingTime <= 0) { implementMarkIdentityAway(identityId); // Since the user is away right now the next auto-away should occur // in X minutes (where X is the timeout which the user has // configured for the identity). remainingTime = m_identitiesWithIdleTimesOnAutoAway[identityId]; } // Get the timer which is currently active for the identity. int timerId = m_timerForIdentity.key(identityId, -1); // Checks if we already have a timer for the given identity. // If we already have a timer we need to make sure that we're always // waiting for the remaining time. if (idleTimeouts[timerId] != remainingTime) { // Remove the idle timeout. implementRemoveIdleTimeout(timerId); // Then also reset the timer ID (as the timer does not exist anymore). timerId = -1; } // Check if we already have a timer. if (timerId == -1) // If not create a new timer. implementAddIdleTimeout(identityId, remainingTime); } void AwayManager::implementAddIdleTimeout(int identityId, int idleTime) { // Create a new timer. int newTimerId = KIdleTime::instance()->addIdleTimeout(idleTime); // Make sure we keep track of the identity <-> KIdleTimer mapping. m_timerForIdentity[newTimerId] = identityId; } void AwayManager::implementRemoveIdleTimeout(int timerId) { // Make sure we got a valid timer ID. if (timerId != -1) { // Remove the idle timeout. KIdleTime::instance()->removeIdleTimeout(timerId); // Also remove the timer/identity mapping from our hashtable. m_timerForIdentity.remove(timerId); } } void AwayManager::implementMarkIdentityAway(int identityId) { // Mark the current identity as away. implementManagedAway(identityId); // As at least one identity is away we have to catch the next // resume event. KIdleTime::instance()->catchNextResumeEvent(); } void AwayManager::simulateUserActivity() { // Tell KIdleTime that it should reset the user's idle status. KIdleTime::instance()->simulateUserActivity(); } void AwayManager::resumeFromIdle() { // We are not idle anymore. setManagedIdentitiesUnaway(); QHash::ConstIterator itr = m_identitiesWithIdleTimesOnAutoAway.constBegin(); for (; itr != m_identitiesWithIdleTimesOnAutoAway.constEnd(); ++itr) // Update the idle timeout for the identity to the configured timeout. // This is needed in case the timer is not set to fire after the full // away time but a shorter time (for example if the user was away on startup // we want the timer to fire after "configured away-time" minus "time the user // is already idle"). Then the timer's interval is wrong. // Now (if needed) we simply remove the old timer and add a new one with the // correct interval. implementUpdateIdleTimeout(itr.key()); } void AwayManager::idleTimeoutReached(int timerId) { // Get the identity ID for the given timer ID. int identityId = m_timerForIdentity[timerId]; // Mark the identity as away. implementMarkIdentityAway(identityId); } void AwayManager::identitiesOnAutoAwayChanged() { const QList serverList = m_connectionManager->getServerList(); // Since the list of identities has changed we want to drop all timers. KIdleTime::instance()->removeAllIdleTimeouts(); // Also clear the list of identity <-> timer mappings. m_timerForIdentity.clear(); foreach (Server* server, serverList) { IdentityPtr identity = server->getIdentity(); int identityId = identity->id(); // Only add idle timeouts for identities which have auto-away // enabled. if (m_identitiesWithIdleTimesOnAutoAway.contains(identityId)) // Update the idle timeout for the current identity. implementUpdateIdleTimeout(identityId); } } void AwayManager::identityOnAutoAwayWentOnline(int identityId) { // Simply update the idle timeout for the identity (this will // take care of all necessary calculations). implementUpdateIdleTimeout(identityId); } void AwayManager::identityOnAutoAwayWentOffline(int identityId) { // Get the timer for the given identity. int timerId = m_timerForIdentity.key(identityId, -1); // Then remove the timer. implementRemoveIdleTimeout(timerId); } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index fc684ee8..d030fbe2 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1,963 +1,974 @@ /* 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 "mainwindow.h" #include "application.h" #include "settingsdialog.h" #include "viewcontainer.h" #include "statusbar.h" #include "bookmarkhandler.h" #include "trayicon.h" #include "serverlistdialog.h" #include "identitydialog.h" #include "notificationhandler.h" #include "irccharsets.h" #include "connectionmanager.h" #include "awaymanager.h" #include "transfermanager.h" #include "messagemodel.h" // WIPQTQUICK #include "actioncollectionmodel.h" // WIPQTQUICK #include #include #include #include #include #include // WIPQTQUICK #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // WIPQTQUICK MainWindow::MainWindow() : KXmlGuiWindow(nullptr) // WIPQTQUICK { m_hasDirtySettings = false; m_closeApp = false; m_serverListDialog = nullptr; +#ifndef Q_OS_ANDROID m_trayIcon = nullptr; +#endif m_settingsDialog = nullptr; m_viewContainer = new ViewContainer(this); setCentralWidget(m_viewContainer->getWidget()); //used for event compression. See header file for resetHasDirtySettings() connect(Application::instance(), SIGNAL(appearanceChanged()), this, SLOT(resetHasDirtySettings())); connect(Application::instance(), SIGNAL(appearanceChanged()), this, SLOT(updateTrayIcon())); // Set up view container connect(Application::instance(), SIGNAL(appearanceChanged()), m_viewContainer, SLOT(updateAppearance())); connect(Application::instance(), SIGNAL(serverGroupsChanged(Konversation::ServerGroupSettingsPtr)), m_viewContainer, SLOT(updateViews(Konversation::ServerGroupSettingsPtr))); connect(m_viewContainer, SIGNAL(autoJoinToggled(Konversation::ServerGroupSettingsPtr)), Application::instance(), SIGNAL(serverGroupsChanged(Konversation::ServerGroupSettingsPtr))); connect(m_viewContainer, SIGNAL(autoConnectOnStartupToggled(Konversation::ServerGroupSettingsPtr)), Application::instance(), SIGNAL(serverGroupsChanged(Konversation::ServerGroupSettingsPtr))); connect(m_viewContainer, SIGNAL(setWindowCaption(QString)), this, SLOT(setCaption(QString))); connect(Application::instance()->getConnectionManager(), &ConnectionManager::connectionChangedState, m_viewContainer, &ViewContainer::connectionStateChanged); connect(this, SIGNAL(triggerRememberLine()), m_viewContainer, SLOT(insertRememberLine())); connect(this, SIGNAL(triggerRememberLines(Server*)), m_viewContainer, SLOT(insertRememberLines(Server*))); connect(this, SIGNAL(cancelRememberLine()), m_viewContainer, SLOT(cancelRememberLine())); connect(this, SIGNAL(insertMarkerLine()), m_viewContainer, SLOT(insertMarkerLine())); // Set up status bar m_statusBar = new Konversation::StatusBar(this); connect(Application::instance(), SIGNAL(appearanceChanged()), m_statusBar, SLOT(updateAppearance())); createStandardStatusBarAction(); connect(m_viewContainer, SIGNAL(resetStatusBar()), m_statusBar, SLOT(resetStatusBar())); connect(m_viewContainer, SIGNAL(setStatusBarTempText(QString)), m_statusBar, SLOT(setMainLabelTempText(QString))); connect(m_viewContainer, SIGNAL(clearStatusBarTempText()), m_statusBar, SLOT(clearMainLabelTempText())); connect(m_viewContainer, SIGNAL(setStatusBarInfoLabel(QString)), m_statusBar, SLOT(updateInfoLabel(QString))); connect(m_viewContainer, SIGNAL(clearStatusBarInfoLabel()), m_statusBar, SLOT(clearInfoLabel())); connect(m_viewContainer, SIGNAL(setStatusBarLagLabelShown(bool)), m_statusBar, SLOT(setLagLabelShown(bool))); connect(m_viewContainer, SIGNAL(updateStatusBarLagLabel(Server*,int)), m_statusBar, SLOT(updateLagLabel(Server*,int))); connect(m_viewContainer, SIGNAL(resetStatusBarLagLabel(Server*)), m_statusBar, SLOT(resetLagLabel(Server*))); connect(m_viewContainer, SIGNAL(setStatusBarLagLabelTooLongLag(Server*,int)), m_statusBar, SLOT(setTooLongLag(Server*,int))); connect(m_viewContainer, SIGNAL(updateStatusBarSSLLabel(Server*)), m_statusBar, SLOT(updateSSLLabel(Server*))); connect(m_viewContainer, SIGNAL(removeStatusBarSSLLabel()), m_statusBar, SLOT(removeSSLLabel())); // Actions KStandardAction::quit(this,SLOT(quitProgram()),actionCollection()); m_showMenuBarAction = KStandardAction::showMenubar(this, SLOT(toggleMenubar()), actionCollection()); setStandardToolBarMenuEnabled(true); KStandardAction::configureToolbars(this, SLOT(configureToolbars()), actionCollection()); KStandardAction::keyBindings(this, SLOT(openKeyBindings()), actionCollection()); KStandardAction::preferences(this, SLOT(openPrefsDialog()), actionCollection()); KStandardAction::configureNotifications(this, SLOT(openNotifications()), actionCollection()); QAction* action; action=new QAction(this); action->setText(i18n("Restart")); action->setIcon(QIcon::fromTheme(QStringLiteral("system-reboot"))); action->setStatusTip(i18n("Quit and restart the application")); connect(action, SIGNAL(triggered()), Application::instance(), SLOT(restart())); actionCollection()->addAction(QStringLiteral("restart"), action); action=new QAction(this); action->setText(i18n("&Server List...")); action->setIcon(QIcon::fromTheme(QStringLiteral("network-server"))); actionCollection()->setDefaultShortcut(action, QKeySequence(QStringLiteral("F2"))); action->setStatusTip(i18n("Manage networks and servers")); connect(action, SIGNAL(triggered()), SLOT(openServerList())); actionCollection()->addAction(QStringLiteral("open_server_list"), action); action=new QAction(this); action->setText(i18n("Quick &Connect...")); action->setIcon(QIcon::fromTheme(QStringLiteral("network-connect"))); actionCollection()->setDefaultShortcut(action,QKeySequence(QStringLiteral("F7"))); action->setStatusTip(i18n("Type in the address of a new IRC server to connect to")); connect(action, SIGNAL(triggered()), SLOT(openQuickConnectDialog())); actionCollection()->addAction(QStringLiteral("quick_connect_dialog"), action); action=new QAction(this); action->setText(i18n("&Reconnect")); action->setIcon(QIcon::fromTheme(QStringLiteral("view-refresh"))); action->setEnabled(false); action->setStatusTip(i18n("Reconnect to the current server.")); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(reconnectFrontServer())); actionCollection()->addAction(QStringLiteral("reconnect_server"), action); action=new QAction(this); action->setText(i18n("&Disconnect")); action->setIcon(QIcon::fromTheme(QStringLiteral("network-disconnect"))); action->setEnabled(false); action->setStatusTip(i18n("Disconnect from the current server.")); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(disconnectFrontServer())); actionCollection()->addAction(QStringLiteral("disconnect_server"), action); action=new QAction(this); action->setText(i18n("&Identities...")); action->setIcon(QIcon::fromTheme(QStringLiteral("user-identity"))); actionCollection()->setDefaultShortcut(action,QKeySequence(QStringLiteral("F8"))); action->setStatusTip(i18n("Manage your nick, away and other identity settings")); connect(action, SIGNAL(triggered()), SLOT(openIdentitiesDialog())); actionCollection()->addAction(QStringLiteral("identities_dialog"), action); action=new KToggleAction(this); action->setText(i18n("&Watched Nicks")); action->setIcon(QIcon::fromTheme(QStringLiteral("im-user"))); actionCollection()->setDefaultShortcut(action,QKeySequence(QStringLiteral("F4"))); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(openNicksOnlinePanel())); actionCollection()->addAction(QStringLiteral("open_nicksonline_window"), action); action=new KToggleAction(this); action->setText(i18n("&DCC Status")); action->setIcon(QIcon::fromTheme(QStringLiteral("arrow-right-double"))); actionCollection()->setDefaultShortcut(action,QKeySequence(QStringLiteral("F9"))); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(toggleDccPanel())); actionCollection()->addAction(QStringLiteral("open_dccstatus_window"), action); action=new QAction(this); action->setText(i18n("&Open Logfile")); action->setIcon(QIcon::fromTheme(QStringLiteral("view-history"))); actionCollection()->setDefaultShortcut(action,QKeySequence(QStringLiteral("Ctrl+O"))); action->setEnabled(false); action->setStatusTip(i18n("Open the known history for this channel in a new tab")); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(openLogFile())); actionCollection()->addAction(QStringLiteral("open_logfile"), action); action=new QAction(this); action->setText(i18n("&Channel Settings...")); action->setIcon(QIcon::fromTheme(QStringLiteral("configure"))); action->setEnabled(false); action->setStatusTip(i18n("Open the channel settings dialog for this tab")); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(openChannelSettings())); actionCollection()->addAction(QStringLiteral("channel_settings"), action); action=new KToggleAction(this); action->setText(i18n("Channel &List")); action->setIcon(QIcon::fromTheme(QStringLiteral("view-list-text"))); actionCollection()->setDefaultShortcut(action,QKeySequence(QStringLiteral("F5"))); action->setEnabled(false); action->setStatusTip(i18n("Show a list of all the known channels on this server")); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(openChannelList())); actionCollection()->addAction(QStringLiteral("open_channel_list"), action); action=new KToggleAction(this); action->setText(i18n("&URL Catcher")); action->setIcon(QIcon::fromTheme(QStringLiteral("text-html"))); actionCollection()->setDefaultShortcut(action, QKeySequence(QStringLiteral("F6"))); action->setStatusTip(i18n("List all URLs that have been mentioned recently in a new tab")); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(addUrlCatcher())); actionCollection()->addAction(QStringLiteral("open_url_catcher"), action); if (KAuthorized::authorize(QStringLiteral("shell_access"))) { action=new QAction(this); action->setText(i18n("New &Konsole")); action->setIcon(QIcon::fromTheme(QStringLiteral("utilities-terminal"))); action->setStatusTip(i18n("Open a terminal in a new tab")); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(addKonsolePanel())); actionCollection()->addAction(QStringLiteral("open_konsole"), action); } // Actions to navigate through the different pages QList nextShortcut = KStandardShortcut::tabNext(); QList prevShortcut = KStandardShortcut::tabPrev(); QString nextIcon, prevIcon; if (QApplication::isRightToLeft()) { prevShortcut.append(QKeySequence(QStringLiteral("Alt+Right"))); nextShortcut.append(QKeySequence(QStringLiteral("Alt+Left"))); nextIcon=QStringLiteral("go-previous-view"); prevIcon=QStringLiteral("go-next-view"); } else { nextShortcut.append(QKeySequence(QStringLiteral("Alt+Right"))); prevShortcut.append(QKeySequence(QStringLiteral("Alt+Left"))); nextIcon=QStringLiteral("go-next-view"); prevIcon=QStringLiteral("go-previous-view"); } action=new QAction(this); action->setText(i18n("&Next Tab")); action->setIcon(QIcon::fromTheme(nextIcon)); actionCollection()->setDefaultShortcuts(action,nextShortcut); action->setEnabled(false); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(showNextView())); actionCollection()->addAction(QStringLiteral("next_tab"), action); action=new QAction(this); action->setText(i18n("&Previous Tab")); action->setIcon(QIcon::fromTheme(prevIcon)); actionCollection()->setDefaultShortcuts(action, prevShortcut); action->setEnabled(false); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(showPreviousView())); actionCollection()->addAction(QStringLiteral("previous_tab"), action); action=new QAction(this); action->setText(i18n("Close &Tab")); action->setIcon(QIcon::fromTheme(QStringLiteral("tab-close-other"))); actionCollection()->setDefaultShortcut(action,QKeySequence(QStringLiteral("Ctrl+w"))); action->setEnabled(false); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(closeCurrentView())); actionCollection()->addAction(QStringLiteral("close_tab"), action); action=new QAction(this); action->setText(i18n("Last Focused Tab")); actionCollection()->setDefaultShortcut(action,QKeySequence(QStringLiteral("Alt+Space"))); action->setEnabled(false); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(showLastFocusedView())); actionCollection()->addAction(QStringLiteral("last_focused_tab"), action); action=new QAction(this); action->setText(i18n("Next Active Tab")); actionCollection()->setDefaultShortcut(action,QKeySequence(QStringLiteral("Ctrl+Alt+Space"))); action->setEnabled(false); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(showNextActiveView())); actionCollection()->addAction(QStringLiteral("next_active_tab"), action); KGlobalAccel::setGlobalShortcut(action, QList()); if (Preferences::self()->tabPlacement()==Preferences::Left) { action=new QAction(this); action->setText(i18n("Move Tab Up")); action->setIcon(QIcon::fromTheme(QStringLiteral("arrow-up"))); actionCollection()->setDefaultShortcut(action,QKeySequence(QStringLiteral("Alt+Shift+Left"))); action->setEnabled(false); action->setStatusTip(i18n("Move this tab")); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(moveViewLeft())); actionCollection()->addAction(QStringLiteral("move_tab_left"), action); action->setEnabled(false); action->setStatusTip(i18n("Move this tab")); action=new QAction(this); action->setText(i18n("Move Tab Down")); action->setIcon(QIcon::fromTheme(QStringLiteral("arrow-down"))); actionCollection()->setDefaultShortcut(action, QKeySequence(QStringLiteral("Alt+Shift+Right"))); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(moveViewRight())); actionCollection()->addAction(QStringLiteral("move_tab_right"), action); } else { if (QApplication::isRightToLeft()) { action=new QAction(this); action->setText(i18n("Move Tab Right")); action->setIcon(QIcon::fromTheme(QStringLiteral("arrow-right"))); actionCollection()->setDefaultShortcut(action, QKeySequence(QStringLiteral("Alt+Shift+Right"))); action->setEnabled(false); action->setStatusTip(i18n("Move this tab")); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(moveViewLeft())); actionCollection()->addAction(QStringLiteral("move_tab_left"), action); action=new QAction(this); action->setText(i18n("Move Tab Left")); action->setIcon(QIcon::fromTheme(QStringLiteral("arrow-left"))); actionCollection()->setDefaultShortcut(action, QKeySequence(QStringLiteral("Alt+Shift+Left"))); action->setEnabled(false); action->setStatusTip(i18n("Move this tab")); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(moveViewRight())); actionCollection()->addAction(QStringLiteral("move_tab_right"), action); } else { action=new QAction(this); action->setText(i18n("Move Tab Left")); action->setIcon(QIcon::fromTheme(QStringLiteral("arrow-left"))); actionCollection()->setDefaultShortcut(action, QKeySequence(QStringLiteral("Alt+Shift+Left"))); action->setEnabled(false); action->setStatusTip(i18n("Move this tab")); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(moveViewLeft())); actionCollection()->addAction(QStringLiteral("move_tab_left"), action); action=new QAction(this); action->setText(i18n("Move Tab Right")); action->setIcon(QIcon::fromTheme(QStringLiteral("arrow-right"))); actionCollection()->setDefaultShortcut(action, QKeySequence(QStringLiteral("Alt+Shift+Right"))); action->setEnabled(false); action->setStatusTip(i18n("Move this tab")); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(moveViewRight())); actionCollection()->addAction(QStringLiteral("move_tab_right"), action); } } action->setEnabled(false); action=new QAction(this); action->setText(i18n("Rejoin Channel")); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(rejoinChannel())); actionCollection()->addAction(QStringLiteral("rejoin_channel"), action); action->setEnabled(false); action=new KToggleAction(this); action->setText(i18n("Enable Notifications")); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(toggleViewNotifications())); actionCollection()->addAction(QStringLiteral("tab_notifications"), action); action->setEnabled(false); action=new KToggleAction(this); action->setText(i18n("Join on Connect")); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(toggleAutoJoin())); actionCollection()->addAction(QStringLiteral("tab_autojoin"), action); action=new KToggleAction(this); action->setText(i18n("Connect at Startup")); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(toggleConnectOnStartup())); actionCollection()->addAction(QStringLiteral("tab_autoconnect"), action); QStringList encodingDescs = Konversation::IRCCharsets::self()->availableEncodingDescriptiveNames(); encodingDescs.prepend(i18n("Default")); KSelectAction* selectAction = new KSelectAction(this); selectAction->setEditable(false); selectAction->setItems(encodingDescs); selectAction->setEnabled(false); selectAction->setText(i18n("Set Encoding")); selectAction->setIcon(QIcon::fromTheme(QStringLiteral("character-set"))); connect(selectAction, SIGNAL(triggered(int)), m_viewContainer, SLOT(changeViewCharset(int))); actionCollection()->addAction(QStringLiteral("tab_encoding"), selectAction); QSignalMapper* tabSelectionMapper = new QSignalMapper(this); connect(tabSelectionMapper, SIGNAL(mapped(int)), m_viewContainer, SLOT(goToView(int))); for (uint i = 1; i <= 10; ++i) { action=new QAction(this); action->setText(i18n("Go to Tab %1",i)); actionCollection()->setDefaultShortcut(action,QKeySequence(QString(QStringLiteral("Alt+%1")).arg(i%10))); connect(action, SIGNAL(triggered()), tabSelectionMapper, SLOT(map())); actionCollection()->addAction(QString(QStringLiteral("go_to_tab_%1")).arg(i), action); tabSelectionMapper->setMapping(action, i-1); } action=new QAction(this); action->setText(i18n("Clear &Marker Lines")); actionCollection()->setDefaultShortcut(action,QKeySequence(QStringLiteral("Ctrl+Shift+R"))); action->setEnabled(false); action->setStatusTip(i18n("Clear marker lines in the current tab")); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(clearViewLines())); actionCollection()->addAction(QStringLiteral("clear_lines"), action); action=new QAction(this); action->setText(i18n("Enlarge Font Size")); actionCollection()->setDefaultShortcuts(action, KStandardShortcut::zoomIn()); action->setEnabled(false); action->setIcon(QIcon::fromTheme(QStringLiteral("zoom-in"))); action->setStatusTip(i18n("Increase the current font size")); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(zoomIn())); actionCollection()->addAction(QStringLiteral("increase_font"), action); action=new QAction(this); action->setText(i18n("Reset Font Size")); actionCollection()->setDefaultShortcut(action, QKeySequence(QStringLiteral("Ctrl+0"))); action->setEnabled(false); action->setIcon(QIcon::fromTheme(QStringLiteral("zoom-original"))); action->setStatusTip(i18n("Reset the current font size to settings values")); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(resetFont())); actionCollection()->addAction(QStringLiteral("reset_font"), action); action=new QAction(this); action->setText(i18n("Decrease Font Size")); actionCollection()->setDefaultShortcuts(action, KStandardShortcut::zoomOut()); action->setEnabled(false); action->setIcon(QIcon::fromTheme(QStringLiteral("zoom-out"))); action->setStatusTip(i18n("Decrease the current font size")); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(zoomOut())); actionCollection()->addAction(QStringLiteral("shrink_font"), action); action=new QAction(this); action->setText(i18n("&Clear Window")); actionCollection()->setDefaultShortcut(action,QKeySequence(QStringLiteral("Ctrl+L"))); action->setEnabled(false); action->setStatusTip(i18n("Clear the contents of the current tab")); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(clearView())); actionCollection()->addAction(QStringLiteral("clear_window"), action); action=new QAction(this); action->setText(i18n("Clear &All Windows")); actionCollection()->setDefaultShortcut(action,QKeySequence(QStringLiteral("Ctrl+Shift+L"))); action->setEnabled(false); action->setStatusTip(i18n("Clear the contents of all open tabs")); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(clearAllViews())); actionCollection()->addAction(QStringLiteral("clear_tabs"), action); KToggleAction* awayAction = new KToggleAction(this); awayAction->setText(i18n("Global Away")); actionCollection()->setDefaultShortcut(awayAction,QKeySequence(QStringLiteral("Ctrl+Shift+A"))); awayAction->setEnabled(false); awayAction->setIcon(QIcon::fromTheme(QStringLiteral("im-user-away"))); connect(awayAction, SIGNAL(triggered(bool)), Application::instance()->getAwayManager(), SLOT(setGlobalAway(bool))); actionCollection()->addAction(QStringLiteral("toggle_away"), awayAction); action=new QAction(this); action->setText(i18n("&Join Channel...")); action->setIcon(QIcon::fromTheme(QStringLiteral("irc-join-channel"))); actionCollection()->setDefaultShortcut(action,QKeySequence(QStringLiteral("Ctrl+J"))); action->setEnabled(false); action->setStatusTip(i18n("Join a new channel on this server")); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(showJoinChannelDialog())); actionCollection()->addAction(QStringLiteral("join_channel"), action); action = KStandardAction::find(m_viewContainer, SLOT(findText()), actionCollection()); action->setEnabled(false); action = KStandardAction::findNext(m_viewContainer, SLOT(findNextText()), actionCollection()); action->setEnabled(false); action = KStandardAction::findPrev(m_viewContainer, SLOT(findPrevText()), actionCollection()); action->setEnabled(false); action=new QAction(this); action->setText(i18n("&IRC Color...")); action->setIcon(QIcon::fromTheme(QStringLiteral("format-text-color"))); actionCollection()->setDefaultShortcut(action,QKeySequence(QStringLiteral("Ctrl+K"))); action->setEnabled(false); action->setStatusTip(i18n("Set the color of your current IRC message")); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(insertIRCColor())); actionCollection()->addAction(QStringLiteral("irc_colors"), action); action=new QAction(this); action->setText(i18n("&Marker Line")); actionCollection()->setDefaultShortcut(action,QKeySequence(QStringLiteral("Ctrl+R"))); action->setEnabled(false); action->setStatusTip(i18n("Insert a horizontal line into the current tab that only you can see")); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(insertMarkerLine())); actionCollection()->addAction(QStringLiteral("insert_marker_line"), action); action=new QAction(this); action->setText(i18n("Special &Character...")); action->setIcon(QIcon::fromTheme(QStringLiteral("character-set"))); actionCollection()->setDefaultShortcut(action,QKeySequence(QStringLiteral("Alt+Shift+C"))); action->setEnabled(false); action->setStatusTip(i18n("Insert any character into your current IRC message")); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(insertCharacter())); actionCollection()->addAction(QStringLiteral("insert_character"), action); action=new QAction(this); action->setText(i18n("Auto Replace")); action->setEnabled(false); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(doAutoReplace())); actionCollection()->addAction(QStringLiteral("auto_replace"), action); action=new QAction(this); action->setText(i18n("Focus Input Box")); actionCollection()->setDefaultShortcut(action,QKeySequence(Qt::Key_Escape)); action->setEnabled(false); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(focusInputBox())); actionCollection()->addAction(QStringLiteral("focus_input_box"), action); action=new QAction(this); action->setText(i18n("Close &All Open Queries")); actionCollection()->setDefaultShortcut(action,QKeySequence(QStringLiteral("F11"))); action->setEnabled(false); connect(action, SIGNAL(triggered()), m_viewContainer, SLOT(closeQueries())); actionCollection()->addAction(QStringLiteral("close_queries"), action); KToggleAction* toggleChannelNickListsAction = new KToggleAction(this); if (Preferences::self()->showNickList()) toggleChannelNickListsAction->setChecked(true); toggleChannelNickListsAction->setText(i18n("Show Nicklist")); actionCollection()->setDefaultShortcut(toggleChannelNickListsAction, QKeySequence(QStringLiteral("Ctrl+H"))); connect(toggleChannelNickListsAction, SIGNAL(triggered()), m_viewContainer, SLOT(toggleChannelNicklists())); actionCollection()->addAction(QStringLiteral("hide_nicknamelist"), toggleChannelNickListsAction); action=new QAction(this); action->setText(i18n("Show/Hide Konversation")); connect(action, SIGNAL(triggered()), this, SLOT(toggleVisibility())); actionCollection()->addAction(QStringLiteral("toggle_mainwindow_visibility"), action); KGlobalAccel::setGlobalShortcut(action, QList()); action=new KToggleAction(this); action->setEnabled(true); action->setChecked(Preferences::self()->useOSD()); action->setText(i18n("Enable On Screen Display")); action->setIcon(QIcon::fromTheme(QStringLiteral("video-display"))); connect(action, SIGNAL(triggered(bool)), Preferences::self(), SLOT(slotSetUseOSD(bool))); actionCollection()->addAction(QStringLiteral("toggle_osd"), action); // Bookmarks action=new QAction(this); action->setText(i18n("Bookmarks")); QMenu *menu = new QMenu(this); action->setMenu(menu); new KonviBookmarkHandler(menu, this); actionCollection()->addAction(QStringLiteral("bookmarks") , action); // BEGIN WIPQTQUICK m_actionCollectionModel = new ActionCollectionModel(this); m_actionCollectionModel->setActionCollection(actionCollection()); // END WIPQTQUICK // decide whether to show the tray icon or not updateTrayIcon(); createGUI(); setAutoSaveSettings(); // Apply menubar show/hide pref m_showMenuBarAction->setChecked(Preferences::self()->showMenuBar()); toggleMenubar(true); if (Preferences::self()->useNotify() && Preferences::self()->openWatchedNicksAtStartup()) m_viewContainer->openNicksOnlinePanel(); } MainWindow::~MainWindow() { +#ifndef Q_OS_ANDROID delete m_trayIcon; // WIPQTQUICK m_trayIcon = nullptr; // WIPQTQUICK +#endif } QSize MainWindow::sizeHint() const { return QSize(700, 500); // Give the app a sane default size } int MainWindow::confirmQuit() { Application* konvApp = Application::instance(); if (konvApp->getConnectionManager()->connectionCount() == 0) return KMessageBox::Continue; int result = KMessageBox::Cancel; if (!KMessageBox::shouldBeShownContinue(QStringLiteral("systemtrayquitKonversation")) && konvApp->getDccTransferManager()->hasActiveTransfers()) { result = KMessageBox::warningContinueCancel( this, i18n("You have active DCC file transfers. Are you sure you want to quit Konversation?"), i18n("Confirm Quit"), KStandardGuiItem::quit(), KStandardGuiItem::cancel(), QStringLiteral("QuitWithActiveDccTransfers")); } else { result = KMessageBox::warningContinueCancel( this, i18n("Are you sure you want to quit Konversation?"), i18n("Confirm Quit"), KStandardGuiItem::quit(), KStandardGuiItem::cancel(), QStringLiteral("systemtrayquitKonversation")); } if (result != KMessageBox::Continue) konvApp->abortScheduledRestart(); return result; } void MainWindow::activateAndRaiseWindow() { +#ifndef Q_OS_ANDROID if (isMinimized()) KWindowSystem::unminimizeWindow(winId()); else if (Preferences::self()->showTrayIcon() && !isVisible()) m_trayIcon->restore(); KWindowSystem::setOnDesktop(winId(), KWindowSystem::currentDesktop()); KWindowSystem::activateWindow(winId()); +#endif } void MainWindow::quitProgram() { +#ifndef Q_OS_ANDROID if (Preferences::self()->showTrayIcon() && sender() != m_trayIcon && confirmQuit() == KMessageBox::Cancel) return; +#endif // will call queryClose() Application::instance()->getQuickMainWindow()->close(); // WIPQTQUICK m_closeApp = true; Application::instance()->getMessageModel()->clear(); // WIPQTQUICK Application::instance()->getViewListModel()->setSourceModel(nullptr); // WIPQTQUICK close(); } bool MainWindow::queryClose() { Application* konvApp = Application::instance(); if (!konvApp->isSavingSession()) { +#ifndef Q_OS_ANDROID if (sender() == m_trayIcon) m_closeApp = true; - +#endif if (Preferences::self()->showTrayIcon() && !m_closeApp) { bool doit = KMessageBox::warningContinueCancel(this, i18n("

Closing the main window will keep Konversation running in the system tray. " "Use Quit from the Konversation menu to quit the application.

"), i18n("Docking in System Tray"), KStandardGuiItem::cont(), KStandardGuiItem::cancel(), QLatin1String("HideOnCloseInfo")) == KMessageBox::Continue; if (doit) hide(); return false; } if (!Preferences::self()->showTrayIcon() && confirmQuit() == KMessageBox::Cancel) return false; } konvApp->prepareShutdown(); return true; } void MainWindow::hideEvent(QHideEvent *e) { emit triggerRememberLine(); m_statusBar->clearMainLabelTempText(); KXmlGuiWindow::hideEvent(e); } void MainWindow::showEvent(QShowEvent *e) { emit cancelRememberLine(); KXmlGuiWindow::showEvent(e); } void MainWindow::leaveEvent(QEvent* e) { m_statusBar->clearMainLabelTempText(); KXmlGuiWindow::leaveEvent(e); } bool MainWindow::event(QEvent* e) { if (e->type() == QEvent::StyleChange) { QMetaObject::invokeMethod(Application::instance(), "appearanceChanged"); } else if (e->type() == QEvent::WindowActivate) { emit endNotification(); emit cancelRememberLine(); } else if(e->type() == QEvent::WindowDeactivate) { m_statusBar->clearMainLabelTempText(); if (qApp->activeModalWidget() == nullptr) emit triggerRememberLine(); } return KXmlGuiWindow::event(e); } void MainWindow::settingsChangedSlot() { // This is for compressing the events. m_hasDirtySettings is set to true // when the settings have changed, then set to false when the app reacts to it // via the appearanceChanged signal. This prevents a series of settingsChanged signals // causing the app expensively rereading its settings many times. // The appearanceChanged signal is connected to resetHasDirtySettings to reset this bool if (!m_hasDirtySettings) { QTimer::singleShot(0, Application::instance(), SIGNAL(appearanceChanged())); m_hasDirtySettings = true; } } void MainWindow::resetHasDirtySettings() { m_hasDirtySettings = false; } void MainWindow::updateTrayIcon() { +#ifndef Q_OS_ANDROID if (Preferences::self()->showTrayIcon()) { if (!m_trayIcon) { // set up system tray m_trayIcon = new Konversation::TrayIcon(); connect(this, SIGNAL(endNotification()), m_trayIcon, SLOT(endNotification())); connect(KIconLoader::global(), SIGNAL(iconChanged(int)), m_trayIcon, SLOT(updateAppearance())); QMenu *trayMenu = qobject_cast(m_trayIcon->contextMenu()); trayMenu->addAction(actionCollection()->action(QLatin1String(KStandardAction::name(KStandardAction::Preferences)))); trayMenu->addAction(actionCollection()->action(QLatin1String(KStandardAction::name(KStandardAction::ConfigureNotifications)))); trayMenu->addAction(actionCollection()->action(QStringLiteral("toggle_away"))); } m_trayIcon->setNotificationEnabled(Preferences::self()->trayNotify()); } else { delete m_trayIcon; m_trayIcon = nullptr; } +#endif } void MainWindow::toggleMenubar(bool dontShowWarning) { if (m_showMenuBarAction->isChecked()) menuBar()->show(); else { bool doit = true; if (!dontShowWarning) { QString accel = m_showMenuBarAction->shortcut().toString(); doit = KMessageBox::warningContinueCancel(this, i18n("This will hide the menu bar completely. You can show it again by typing %1.", accel), i18n("Hide menu bar"), KStandardGuiItem::cont(), KStandardGuiItem::cancel(), QLatin1String("HideMenuBarWarning")) == KMessageBox::Continue; } if (doit) menuBar()->hide(); else m_showMenuBarAction->setChecked (true); } Preferences::self()->setShowMenuBar(m_showMenuBarAction->isChecked()); } void MainWindow::focusAndShowErrorMessage(const QString &errorMsg) { show(); KWindowSystem::demandAttention(winId()); KWindowSystem::activateWindow(winId()); KMessageBox::error(this, errorMsg); } void MainWindow::openPrefsDialog() { //An instance of your dialog could be already created and could be cached, //in which case you want to display the cached dialog instead of creating //another one if (!m_settingsDialog) { m_settingsDialog = new KonviSettingsDialog(this); // BEGIN WIPQTQUICK m_settingsDialog->winId(); // ensure to create native window m_settingsDialog->windowHandle()->setTransientParent(Application::instance()->getQuickMainWindow()); m_settingsDialog->show(); // END WIPQTQUICK //User edited the configuration - update your local copies of the //configuration data connect(m_settingsDialog, SIGNAL(settingsChanged(QString)), this, SLOT(settingsChangedSlot())); } m_settingsDialog->show(); } void MainWindow::openKeyBindings() { // Change a number of action names to make them friendlier for the shortcut list. actionCollection()->action(QStringLiteral("tab_notifications"))->setText(i18n("Toggle Notifications")); actionCollection()->action(QStringLiteral("toggle_away"))->setText(i18n("Toggle Away Globally")); actionCollection()->action(QStringLiteral("irc_colors"))->setText(i18n("Insert &IRC Color...")); actionCollection()->action(QStringLiteral("insert_character"))->setText(i18n("Insert Special &Character...")); actionCollection()->action(QStringLiteral("insert_marker_line"))->setText(i18n("Insert &Marker Line")); QString openChannelListString = actionCollection()->action(QStringLiteral("open_channel_list"))->text(); actionCollection()->action(QStringLiteral("open_channel_list"))->setText(i18n("&Channel List")); QString openLogFileString = actionCollection()->action(QStringLiteral("open_logfile"))->text(); actionCollection()->action(QStringLiteral("open_logfile"))->setText(i18n("&Open Logfile")); // Open shortcut configuration dialog. KShortcutsDialog::configure(actionCollection()); // Reset action names. actionCollection()->action(QStringLiteral("tab_notifications"))->setText(i18n("Enable Notifications")); actionCollection()->action(QStringLiteral("toggle_away"))->setText(i18n("Set &Away Globally")); actionCollection()->action(QStringLiteral("irc_colors"))->setText(i18n("&IRC Color...")); actionCollection()->action(QStringLiteral("insert_character"))->setText(i18n("Special &Character...")); actionCollection()->action(QStringLiteral("insert_marker_line"))->setText(i18n("&Marker Line")); actionCollection()->action(QStringLiteral("open_channel_list"))->setText(openChannelListString); actionCollection()->action(QStringLiteral("open_logfile"))->setText(openLogFileString); } void MainWindow::openServerList() { if (!m_serverListDialog) { m_serverListDialog = new Konversation::ServerListDialog(i18n("Server List"), this); Application* konvApp = Application::instance(); // BEGIN WIPQTQUICK m_serverListDialog->winId(); // ensure to create native window m_serverListDialog->windowHandle()->setTransientParent(Application::instance()->getQuickMainWindow()); // END WIPQTQUICK connect(m_serverListDialog, SIGNAL(serverGroupsChanged(Konversation::ServerGroupSettingsPtr)), konvApp, SIGNAL(serverGroupsChanged(Konversation::ServerGroupSettingsPtr))); connect(konvApp, SIGNAL(serverGroupsChanged(Konversation::ServerGroupSettingsPtr)), m_serverListDialog, SLOT(updateServerList())); connect(m_serverListDialog, SIGNAL(connectTo(Konversation::ConnectionFlag,int)), konvApp->getConnectionManager(), SLOT(connectTo(Konversation::ConnectionFlag,int))); connect(m_serverListDialog, SIGNAL(connectTo(Konversation::ConnectionFlag,ConnectionSettings)), konvApp->getConnectionManager(), SLOT(connectTo(Konversation::ConnectionFlag,ConnectionSettings))); connect(konvApp->getConnectionManager(), SIGNAL(closeServerList()), m_serverListDialog, SLOT(reject())); } m_serverListDialog->show(); } void MainWindow::openQuickConnectDialog() { emit showQuickConnectDialog(); } void MainWindow::openIdentitiesDialog() { QPointer dlg = new Konversation::IdentityDialog(this); // BEGIN WIPQTQUICK dlg->winId(); // ensure to create native window dlg->windowHandle()->setTransientParent(Application::instance()->getQuickMainWindow()); // END WIPQTQUICK if (dlg->exec() == QDialog::Accepted) { if (m_serverListDialog) m_serverListDialog->updateServerList(); m_viewContainer->updateViewEncoding(m_viewContainer->getFrontView()); } delete dlg; } IdentityPtr MainWindow::editIdentity(IdentityPtr identity) { IdentityPtr newIdentity; QPointer dlg = new Konversation::IdentityDialog(this); // BEGIN WIPQTQUICK dlg->winId(); // ensure to create native window dlg->windowHandle()->setTransientParent(Application::instance()->getQuickMainWindow()); // END WIPQTQUICK newIdentity = dlg->setCurrentIdentity(identity); if ((dlg->exec() == QDialog::Accepted) && m_serverListDialog) { m_serverListDialog->updateServerList(); delete dlg; return newIdentity; } else { delete dlg; return IdentityPtr(); } } void MainWindow::openNotifications() { (void) KNotifyConfigWidget::configure(this); } void MainWindow::notifyAction(int connectionId, const QString& nick) { Application* konvApp = Application::instance(); Server* server = konvApp->getConnectionManager()->getServerByConnectionId(connectionId); if (server) server->notifyAction(nick); } // TODO: Let an own class handle notify things void MainWindow::setOnlineList(Server* notifyServer,const QStringList& /*list*/, bool /*changed*/) { emit nicksNowOnline(notifyServer); // FIXME if (changed && nicksOnlinePanel) newText(nicksOnlinePanel, QString::null, true); } void MainWindow::toggleVisibility() { // BEGIN WIPQTQUICK if (Application::instance()->getQuickMainWindow()->isActive()) { if (Preferences::self()->showTrayIcon()) Application::instance()->getQuickMainWindow()->hide(); else Application::instance()->getQuickMainWindow()->showMinimized(); } else { Application::instance()->getQuickMainWindow()->show(); Application::instance()->getQuickMainWindow()->requestActivate(); } // END WIPQTQUICK } diff --git a/src/mainwindow.h b/src/mainwindow.h index 4effd27b..8d3ac418 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -1,144 +1,146 @@ /* 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 MAINWINDOW_H #define MAINWINDOW_H #include "common.h" #include "preferences.h" #include "ssllabel.h" #include "server.h" #include #include class QQmlApplicationEngine; // WIPQTQUICK class QStackedWidget; // WIPQTQUICK class KToggleAction; class Server; class KonviSettingsDialog; class ViewContainer; class ActionCollectionModel; // WIPQTQUICK namespace Konversation { class ServerListDialog; class TrayIcon; class StatusBar; } class MainWindow : public KXmlGuiWindow { Q_OBJECT public: MainWindow(); // WIPQTQUICK ~MainWindow() override; ViewContainer* getViewContainer() { return m_viewContainer; } ActionCollectionModel* getActionCollectionModel() { return m_actionCollectionModel; } // WIPQTQUICK Konversation::StatusBar* getStatusBar() { return m_statusBar; } // WIPQTQUICK bool getCloseApp() { return m_closeApp; } // WIPQTQUICK +#ifndef Q_OS_ANDROID Konversation::TrayIcon* systemTrayIcon() const { return m_trayIcon; } - +#endif /** Some errors need to be shown, even when konversation is minimized. */ void focusAndShowErrorMessage(const QString &errorMsg); Q_SIGNALS: void showQuickConnectDialog(); void nicksNowOnline(Server*); void endNotification(); void serverStateChanged(Server* server, Konversation::ConnectionState state); void triggerRememberLine(); void triggerRememberLines(Server*); void cancelRememberLine(); void insertMarkerLine(); public Q_SLOTS: void activateAndRaiseWindow(); void quitProgram(); void updateTrayIcon(); void openServerList(); void openIdentitiesDialog(); IdentityPtr editIdentity(IdentityPtr identity); void setOnlineList(Server* notifyServer,const QStringList& list, bool changed); protected Q_SLOTS: /** This is connected to the preferences settingsChanged signal and acts to compress * multiple successively settingsChanged() signals into a single output * appearanceChanged() signal. * * Do not connect to the settingsChanged signal elsewhere. If you want to know when * the settings have changed, connect to: * KonversationApplication::instance(), SIGNAL(appearanceChanged()) */ void settingsChangedSlot(); /** This is connected to the appearanceChanged signal. * @see settingsChangedSlot() */ void resetHasDirtySettings(); void toggleMenubar(bool dontShowWarning = false); void openPrefsDialog(); void openKeyBindings(); void openQuickConnectDialog(); // it seems that moc does not honor #ifs in compile so we create an // empty slot in our .cpp file rather than #if this slot out void openNotifications(); void notifyAction(int connectionId,const QString& nick); void toggleVisibility(); void showEvent(QShowEvent* e) Q_DECL_OVERRIDE; void hideEvent(QHideEvent* e) Q_DECL_OVERRIDE; void leaveEvent(QEvent* e) Q_DECL_OVERRIDE; protected: QSize sizeHint() const Q_DECL_OVERRIDE; int confirmQuit(); bool queryClose() Q_DECL_OVERRIDE; bool event(QEvent* e) Q_DECL_OVERRIDE; ViewContainer* m_viewContainer; Konversation::StatusBar* m_statusBar; +#ifndef Q_OS_ANDROID Konversation::TrayIcon* m_trayIcon; - +#endif KToggleAction* m_showMenuBarAction; KonviSettingsDialog *m_settingsDialog; Konversation::ServerListDialog* m_serverListDialog; /** @see settingsChangedSlot() */ bool m_hasDirtySettings; bool m_closeApp; ActionCollectionModel *m_actionCollectionModel; // WIPQTQUICK }; #endif /* MAINWINDOW_H */ diff --git a/src/notificationhandler.cpp b/src/notificationhandler.cpp index 047e3300..0da165fe 100644 --- a/src/notificationhandler.cpp +++ b/src/notificationhandler.cpp @@ -1,453 +1,453 @@ /* 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) 2004 by Peter Simonsson email: psn@linux.se */ #include "notificationhandler.h" #include "common.h" #include "chatwindow.h" #include "application.h" #include "mainwindow.h" #include "viewcontainer.h" #include "trayicon.h" #include "server.h" #include "transfer.h" #include #include #include #include namespace Konversation { NotificationHandler::NotificationHandler(Application* parent) : QObject(parent) { m_mainWindow = parent->getMainWindow(); m_quickMainWindow = parent->getQuickMainWindow(); } NotificationHandler::~NotificationHandler() = default; void NotificationHandler::message(ChatWindow* chatWin, const QString& fromNick, const QString& message) { if (!chatWin || !chatWin->notificationsEnabled()) return; if (Preferences::self()->disableNotifyWhileAway() && chatWin->getServer() && chatWin->getServer()->isAway()) return; bool osd = Preferences::self()->oSDShowChannel() && ((!m_quickMainWindow->isActive() && !m_mainWindow->isActiveWindow()) || (chatWin != m_mainWindow->getViewContainer()->getFrontView())); QString eventTitle = i18nc("Notification title; see Event/message in konversation.notifyrc", "New message from %1 in %2", fromNick, chatWin->getName()); KNotification* msg; if (message.isEmpty()) { msg = KNotification::event(QLatin1String("message"), eventTitle, QStringLiteral("<%1>").arg(fromNick), QPixmap(), m_mainWindow); if (osd) { Application* konvApp = Application::instance(); konvApp->osd->show(QLatin1Char('(') + chatWin->getName() + QStringLiteral(") <") + fromNick + QLatin1Char('>')); } } else { QString cleanedMessage = removeIrcMarkup(message); QString forKNotify = cleanedMessage.toHtmlEscaped(); msg = KNotification::event(QLatin1String("message"), eventTitle, QString(QStringLiteral("<%1> %2")).arg(fromNick).arg(forKNotify), QPixmap(), m_mainWindow); if (osd) { Application* konvApp = Application::instance(); konvApp->osd->show(QLatin1Char('(') + chatWin->getName() + QStringLiteral(") <") + fromNick + QStringLiteral("> ") + cleanedMessage); } } msg->setDefaultAction(i18n("Open")); connect(msg, static_cast(&KNotification::activated), chatWin, &ChatWindow::activateView); if (!Preferences::self()->trayNotifyOnlyOwnNick()) { startTrayNotification(chatWin); } } void NotificationHandler::nick(ChatWindow* chatWin, const QString& fromNick, const QString& message) { if (!chatWin || !chatWin->notificationsEnabled()) return; if (Preferences::self()->disableNotifyWhileAway() && chatWin->getServer() && chatWin->getServer()->isAway()) return; bool osd = (Preferences::self()->oSDShowChannel() || Preferences::self()->oSDShowOwnNick()) && ((!m_quickMainWindow->isActive() && !m_mainWindow->isActiveWindow()) || (chatWin != m_mainWindow->getViewContainer()->getFrontView())); QString eventTitle = i18nc("Notification title; see Event/nick in konversation.notifyrc", "Your nick was mentioned by %1 in %2", fromNick, chatWin->getName()); KNotification* msg; if (message.isEmpty()) { msg = KNotification::event(QLatin1String("nick"), eventTitle, QString(QStringLiteral("<%1>")).arg(fromNick), QPixmap(), m_mainWindow); if (osd) { Application* konvApp = Application::instance(); konvApp->osd->show(i18n("[HighLight] (%1) <%2>", chatWin->getName(), fromNick)); } } else { QString cleanedMessage = removeIrcMarkup(message); QString forKNotify = cleanedMessage.toHtmlEscaped(); msg = KNotification::event(QLatin1String("nick"), eventTitle, QString(QStringLiteral("<%1> %2")).arg(fromNick).arg(forKNotify), QPixmap(), m_mainWindow); if (osd) { Application* konvApp = Application::instance(); konvApp->osd->show(i18n("[HighLight] (%1) <%2> %3", chatWin->getName(), fromNick, cleanedMessage)); } } msg->setDefaultAction(i18n("Open")); connect(msg, static_cast(&KNotification::activated), chatWin, &ChatWindow::activateView); startTrayNotification(chatWin); } void NotificationHandler::queryMessage(ChatWindow* chatWin, const QString& fromNick, const QString& message) { if (!chatWin || !chatWin->notificationsEnabled()) return; if (Preferences::self()->disableNotifyWhileAway() && chatWin->getServer() && chatWin->getServer()->isAway()) return; bool osd = Preferences::self()->oSDShowQuery() && ((!m_quickMainWindow->isActive() && !m_mainWindow->isActiveWindow()) || (chatWin != m_mainWindow->getViewContainer()->getFrontView())); QString eventTitle = i18nc("Notification title; see Event/message in konversation.notifyrc", "New query message from %1", chatWin->getName()); KNotification* msg; if (message.isEmpty()) // TODO document how this can happen, seems nonsensical { msg = KNotification::event(QLatin1String("queryMessage"), eventTitle, QString(QStringLiteral("<%1>")).arg(fromNick), QPixmap(), m_mainWindow); if (osd) { Application* konvApp = Application::instance(); konvApp->osd->show(i18n("[Query] <%1>", fromNick)); } } else { QString cleanedMessage = removeIrcMarkup(message); QString forKNotify = cleanedMessage.toHtmlEscaped(); msg = KNotification::event(QLatin1String("queryMessage"), eventTitle, QString(QStringLiteral("<%1> %2")).arg(fromNick).arg(forKNotify), QPixmap(), m_mainWindow); if (osd) { Application* konvApp = Application::instance(); konvApp->osd->show(i18n("[Query] <%1> %2", fromNick, cleanedMessage)); } } msg->setDefaultAction(i18n("Open")); connect(msg, static_cast(&KNotification::activated), chatWin, &ChatWindow::activateView); startTrayNotification(chatWin); } void NotificationHandler::startTrayNotification(ChatWindow* chatWin) { if (!chatWin || !chatWin->notificationsEnabled()) return; if (!chatWin->getServer() || (Preferences::self()->disableNotifyWhileAway() && chatWin->getServer()->isAway())) return; qDebug() << m_quickMainWindow->isActive(); - +#ifndef Q_OS_ANDROID if (((!m_quickMainWindow->isActive() && !m_mainWindow->isActiveWindow())) && chatWin->getServer()->isConnected() && m_mainWindow->systemTrayIcon()) { qDebug() << "starting"; m_mainWindow->systemTrayIcon()->startNotification(); } - +#endif } void NotificationHandler::join(ChatWindow* chatWin, const QString& nick) { if (!chatWin || !chatWin->notificationsEnabled()) return; if (Preferences::self()->disableNotifyWhileAway() && chatWin->getServer() && chatWin->getServer()->isAway()) return; KNotification::event(QLatin1String("join"), i18n("%1 joined %2",nick, chatWin->getName()), QPixmap(), m_mainWindow); // OnScreen Message if(Preferences::self()->oSDShowChannelEvent() && ((!m_quickMainWindow->isActive() && !m_mainWindow->isActiveWindow()) || (chatWin != m_mainWindow->getViewContainer()->getFrontView()))) { Application* konvApp = Application::instance(); konvApp->osd->show(i18n("%1 joined %2",nick, chatWin->getName())); } } void NotificationHandler::part(ChatWindow* chatWin, const QString& nick) { if (!chatWin || !chatWin->notificationsEnabled()) return; if (Preferences::self()->disableNotifyWhileAway() && chatWin->getServer() && chatWin->getServer()->isAway()) return; KNotification::event(QLatin1String("part"), i18n("%1 parted %2",nick, chatWin->getName()), QPixmap(), m_mainWindow); // OnScreen Message if(Preferences::self()->oSDShowChannelEvent() && ((!m_quickMainWindow->isActive() && !m_mainWindow->isActiveWindow()) || (chatWin != m_mainWindow->getViewContainer()->getFrontView()))) { Application* konvApp = Application::instance(); konvApp->osd->show(i18n("%1 parted %2",nick, chatWin->getName())); } } void NotificationHandler::quit(ChatWindow* chatWin, const QString& nick) { if (!chatWin || !chatWin->notificationsEnabled()) return; if (Preferences::self()->disableNotifyWhileAway() && chatWin->getServer() && chatWin->getServer()->isAway()) return; KNotification::event(QLatin1String("part"), i18n("%1 quit %2",nick, chatWin->getServer()->getServerName()), QPixmap(), m_mainWindow); } void NotificationHandler::nickChange(ChatWindow* chatWin, const QString& oldNick, const QString& newNick) { if (!chatWin || !chatWin->notificationsEnabled()) return; if (Preferences::self()->disableNotifyWhileAway() && chatWin->getServer() && chatWin->getServer()->isAway()) return; KNotification::event(QLatin1String("nickchange"), i18n("%1 changed nickname to %2",oldNick, newNick), QPixmap(), m_mainWindow); } void NotificationHandler::dccIncoming(ChatWindow* chatWin, const QString& fromNick) { if (!chatWin || !chatWin->notificationsEnabled()) return; if (Preferences::self()->disableNotifyWhileAway() && chatWin->getServer() && chatWin->getServer()->isAway()) return; KNotification::event(QLatin1String("dcc_incoming"), i18n("%1 wants to send a file to you",fromNick), QPixmap(), m_mainWindow); } void NotificationHandler::dccError(ChatWindow* chatWin, const QString& error) { if (!chatWin || !chatWin->notificationsEnabled()) return; if (Preferences::self()->disableNotifyWhileAway() && chatWin->getServer() && chatWin->getServer()->isAway()) return; KNotification::event(QLatin1String("dcc_error"), i18n("An error has occurred in a DCC transfer: %1",error), QPixmap(), m_mainWindow); } void NotificationHandler::dccTransferDone(ChatWindow* chatWin, const QString& file, DCC::Transfer* transfer) { if (!chatWin || !chatWin->notificationsEnabled()) return; if (Preferences::self()->disableNotifyWhileAway() && chatWin->getServer() && chatWin->getServer()->isAway()) return; if (transfer->getType() == DCC::Transfer::Send) { KNotification::event(QLatin1String("dcctransfer_done"), i18nc("%1 - filename","%1 File Transfer is complete",file), QPixmap(), m_mainWindow); } else { KNotification *notification = new KNotification(QStringLiteral("dcctransfer_done"), m_mainWindow); notification->setText(i18nc("%1 - filename","%1 File Transfer is complete", file)); //notification->setPixmap( QPixmap() ); notification->setActions(QStringList(i18nc("Opens the file from the finished dcc transfer", "Open"))); connect(notification, SIGNAL(activated(unsigned)), transfer, SLOT(runFile())); notification->sendEvent(); } } void NotificationHandler::mode(ChatWindow* chatWin, const QString& nick, const QString& subject, const QString& change) { if (!chatWin || !chatWin->notificationsEnabled()) return; if (Preferences::self()->disableNotifyWhileAway() && chatWin->getServer() && chatWin->getServer()->isAway()) return; KNotification *ev=new KNotification(QStringLiteral("mode"), m_mainWindow); ev->setText(i18n("%1 changed modes in %2: %3", nick, subject, change)); ev->sendEvent(); } void NotificationHandler::query(ChatWindow* chatWin, const QString& fromNick) { if (!chatWin || !chatWin->notificationsEnabled()) return; if (Preferences::self()->disableNotifyWhileAway() && chatWin->getServer() && chatWin->getServer()->isAway()) return; startTrayNotification(chatWin); KNotification *ev=new KNotification(QStringLiteral("query"), m_mainWindow); ev->setText(i18n("%1 has started a conversation (query) with you.",fromNick)); ev->sendEvent(); } void NotificationHandler::nickOnline(ChatWindow* chatWin, const QString& nick) { if (!chatWin) return; if (Preferences::self()->disableNotifyWhileAway() && chatWin->getServer() && chatWin->getServer()->isAway()) return; KNotification *ev=new KNotification(QStringLiteral("notify"), m_mainWindow); ev->setText(i18n("%1 is online (%2).", nick, chatWin->getServer()->getServerName())); ev->sendEvent(); } void NotificationHandler::nickOffline(ChatWindow* chatWin, const QString& nick) { if (!chatWin) return; if (Preferences::self()->disableNotifyWhileAway() && chatWin->getServer() && chatWin->getServer()->isAway()) return; KNotification *ev=new KNotification(QStringLiteral("notify"), m_mainWindow); ev->setText(i18n("%1 went offline (%2).", nick, chatWin->getServer()->getServerName())); ev->sendEvent(); } void NotificationHandler::kick(ChatWindow* chatWin, const QString& channel,const QString& nick) { if (!chatWin || !chatWin->notificationsEnabled()) return; if (Preferences::self()->disableNotifyWhileAway() && chatWin->getServer() && chatWin->getServer()->isAway()) return; KNotification *ev=new KNotification(QStringLiteral("kick"), m_mainWindow); ev->setText(i18n("You are kicked by %1 from %2", nick, channel)); ev->sendEvent(); } void NotificationHandler::dccChat(ChatWindow* chatWin, const QString& nick) { if (!chatWin || !chatWin->notificationsEnabled()) return; if (Preferences::self()->disableNotifyWhileAway() && chatWin->getServer() && chatWin->getServer()->isAway()) return; KNotification *ev=new KNotification(QStringLiteral("dccChat"), m_mainWindow); ev->setText(i18n("%1 started a DCC chat with you", nick)); ev->sendEvent(); } void NotificationHandler::highlight(ChatWindow* chatWin, const QString& fromNick, const QString& message) { if (!chatWin || !chatWin->notificationsEnabled()) return; if (Preferences::self()->disableNotifyWhileAway() && chatWin->getServer() && chatWin->getServer()->isAway()) return; startTrayNotification(chatWin); QString cleanedMessage = removeIrcMarkup(message); QString forKNotify = cleanedMessage.toHtmlEscaped(); if(fromNick.isEmpty()) // TODO document this one too { QString eventTitle = i18nc("Notification title; see Event/highlight in konversation.notifyrc", "Highlight triggered in %1", chatWin->getName()); KNotification::event(QLatin1String("highlight"), eventTitle, QString(QStringLiteral("(%1) *** %2")).arg(chatWin->getName()).arg(forKNotify), QPixmap(), m_mainWindow); } else { QString eventTitle = i18nc("Notification title; see Event/highlight in konversation.notifyrc", "Highlight triggered by %2 in %1", chatWin->getName(), fromNick); KNotification::event(QLatin1String("highlight"), eventTitle, QString(QStringLiteral("(%1) <%2> %3")).arg(chatWin->getName()).arg(fromNick).arg(forKNotify), QPixmap(), m_mainWindow); } if(Preferences::self()->oSDShowOwnNick() && ((!m_quickMainWindow->isActive() && !m_mainWindow->isActiveWindow()) || (chatWin != m_mainWindow->getViewContainer()->getFrontView()))) { Application* konvApp = Application::instance(); // if there was no nick associated, this must be a command message, so don't try displaying // an empty nick in <> if(fromNick.isEmpty()) konvApp->osd->show(i18n("[HighLight] (%1) *** %2",chatWin->getName(),cleanedMessage)); // normal highlight message else konvApp->osd->show(i18n("[HighLight] (%1) <%2> %3",chatWin->getName(),fromNick,cleanedMessage)); } } void NotificationHandler::connectionFailure(ChatWindow* chatWin, const QString& server) { if (!chatWin || !chatWin->notificationsEnabled()) return; KNotification *ev=new KNotification(QStringLiteral("connectionFailure"), m_mainWindow); ev->setText(i18n("Failed to connect to %1", server)); ev->sendEvent(); } void NotificationHandler::channelJoin(ChatWindow* chatWin, const QString& channel) { if (!chatWin || !chatWin->notificationsEnabled()) return; if (Preferences::self()->disableNotifyWhileAway() && chatWin->getServer() && chatWin->getServer()->isAway()) return; KNotification::event(QLatin1String("channelJoin"), i18n("You have joined %1.",channel), QPixmap(), m_mainWindow); } }