X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fqtui%2Fmainwin.cpp;h=727e1f3880ce0d9f4136cb603d73d81dda78f452;hp=eb02b43029d17e43c775b87106fe82c6b9ad1199;hb=f9efdde7f3a6004af8f834c409cfa6ae1d877692;hpb=89175f57858e885d23dac1401f6f14db20ba9002 diff --git a/src/qtui/mainwin.cpp b/src/qtui/mainwin.cpp index eb02b430..727e1f38 100644 --- a/src/qtui/mainwin.cpp +++ b/src/qtui/mainwin.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-2016 by the Quassel Project * + * Copyright (C) 2005-2018 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -24,19 +24,12 @@ #include #include #include +#include #include #include -#ifdef HAVE_KDE4 -# include -# include -# include -# include -# include -# include -#endif - #ifdef HAVE_KF5 +# include # include # include # include @@ -78,9 +71,10 @@ #include "coreinfodlg.h" #include "contextmenuactionprovider.h" #include "debugbufferviewoverlay.h" -#include "debuglogwidget.h" +#include "debuglogdlg.h" #include "debugmessagemodelfilter.h" #include "flatproxymodel.h" +#include "icon.h" #include "inputwidget.h" #include "irclistmodel.h" #include "ircconnectionwizard.h" @@ -93,25 +87,25 @@ #include "qtuisettings.h" #include "qtuistyle.h" #include "receivefiledlg.h" +#include "resourcetreedlg.h" #include "settingsdlg.h" #include "settingspagedlg.h" #include "statusnotifieritem.h" #include "toolbaractionprovider.h" #include "topicwidget.h" +#include "transfermodel.h" #include "verticaldock.h" #ifndef HAVE_KDE # ifdef HAVE_QTMULTIMEDIA # include "qtmultimedianotificationbackend.h" # endif -# ifdef HAVE_PHONON -# include "phononnotificationbackend.h" -# endif # include "systraynotificationbackend.h" # include "taskbarnotificationbackend.h" #else /* HAVE_KDE */ # include "knotificationbackend.h" #endif /* HAVE_KDE */ +#include "systrayanimationnotificationbackend.h" #ifdef HAVE_LIBSNORE @@ -122,10 +116,6 @@ # include "sslinfodlg.h" #endif -#ifdef HAVE_INDICATEQT - #include "indicatornotificationbackend.h" -#endif - #ifdef HAVE_NOTIFICATION_CENTER #include "osxnotificationbackend.h" #endif @@ -144,6 +134,8 @@ #include "settingspages/connectionsettingspage.h" #include "settingspages/coreaccountsettingspage.h" #include "settingspages/coreconnectionsettingspage.h" +#include +#include "settingspages/dccsettingspage.h" #include "settingspages/highlightsettingspage.h" #include "settingspages/identitiessettingspage.h" #include "settingspages/ignorelistsettingspage.h" @@ -170,11 +162,7 @@ MainWin::MainWin(QWidget *parent) #endif _msgProcessorStatusWidget(new MsgProcessorStatusWidget(this)), _coreConnectionStatusWidget(new CoreConnectionStatusWidget(Client::coreConnection(), this)), - _titleSetter(this), - _awayLog(0), - _layoutLoaded(false), - _activeBufferViewIndex(-1), - _aboutToQuit(false) + _titleSetter(this) { setAttribute(Qt::WA_DeleteOnClose, false); // we delete the mainwin manually @@ -188,26 +176,37 @@ MainWin::MainWin(QWidget *parent) setWindowTitle("Quassel IRC"); setWindowIconText("Quassel IRC"); + // Set the default icon for all windows + QApplication::setWindowIcon(icon::get("quassel")); updateIcon(); } void MainWin::init() { - connect(Client::instance(), SIGNAL(networkCreated(NetworkId)), SLOT(clientNetworkCreated(NetworkId))); - connect(Client::instance(), SIGNAL(networkRemoved(NetworkId)), SLOT(clientNetworkRemoved(NetworkId))); - connect(Client::messageModel(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), - SLOT(messagesInserted(const QModelIndex &, int, int))); - connect(GraphicalUi::contextMenuActionProvider(), SIGNAL(showChannelList(NetworkId)), SLOT(showChannelList(NetworkId))); - connect(GraphicalUi::contextMenuActionProvider(), SIGNAL(showIgnoreList(QString)), SLOT(showIgnoreList(QString))); - - connect(Client::coreConnection(), SIGNAL(startCoreSetup(QVariantList)), SLOT(showCoreConfigWizard(QVariantList))); - connect(Client::coreConnection(), SIGNAL(connectionErrorPopup(QString)), SLOT(handleCoreConnectionError(QString))); - connect(Client::coreConnection(), SIGNAL(userAuthenticationRequired(CoreAccount *, bool *, QString)), SLOT(userAuthenticationRequired(CoreAccount *, bool *, QString))); - connect(Client::coreConnection(), SIGNAL(handleNoSslInClient(bool *)), SLOT(handleNoSslInClient(bool *))); - connect(Client::coreConnection(), SIGNAL(handleNoSslInCore(bool *)), SLOT(handleNoSslInCore(bool *))); + connect(Client::instance(), &Client::networkCreated, this, &MainWin::clientNetworkCreated); + connect(Client::instance(), &Client::networkRemoved, this, &MainWin::clientNetworkRemoved); + connect(Client::messageModel(), &QAbstractItemModel::rowsInserted, + this, &MainWin::messagesInserted); + connect(GraphicalUi::contextMenuActionProvider(), + &NetworkModelController::showChannelList, + this, &MainWin::showChannelList); + connect(Client::instance(), + &Client::showChannelList, + this, &MainWin::showChannelList); + connect(GraphicalUi::contextMenuActionProvider(), &NetworkModelController::showNetworkConfig, this, &MainWin::showNetworkConfig); + connect(GraphicalUi::contextMenuActionProvider(), &NetworkModelController::showIgnoreList, this, &MainWin::showIgnoreList); + connect(Client::instance(), &Client::showIgnoreList, this, &MainWin::showIgnoreList); + connect(Client::instance(), &Client::dbUpgradeInProgress, this, &MainWin::showMigrationWarning); + connect(Client::instance(), &Client::exitRequested, this, &MainWin::onExitRequested); + + connect(Client::coreConnection(), &CoreConnection::startCoreSetup, this, &MainWin::showCoreConfigWizard); + connect(Client::coreConnection(), &CoreConnection::connectionErrorPopup, this, &MainWin::handleCoreConnectionError); + connect(Client::coreConnection(), &CoreConnection::userAuthenticationRequired, this, &MainWin::userAuthenticationRequired); + connect(Client::coreConnection(), &CoreConnection::handleNoSslInClient, this, &MainWin::handleNoSslInClient); + connect(Client::coreConnection(), &CoreConnection::handleNoSslInCore, this, &MainWin::handleNoSslInCore); #ifdef HAVE_SSL - connect(Client::coreConnection(), SIGNAL(handleSslErrors(const QSslSocket *, bool *, bool *)), SLOT(handleSslErrors(const QSslSocket *, bool *, bool *))); + connect(Client::coreConnection(), &CoreConnection::handleSslErrors, this, &MainWin::handleSslErrors); #endif // Setup Dock Areas @@ -221,10 +220,11 @@ void MainWin::init() setupActions(); setupBufferWidget(); setupMenus(); + // setupTransferWidget(); not ready yet + setupChatMonitor(); setupTopicWidget(); - setupNickWidget(); setupInputWidget(); - setupChatMonitor(); + setupNickWidget(); setupViewMenuTail(); setupStatusBar(); setupToolBars(); @@ -232,12 +232,12 @@ void MainWin::init() setupTitleSetter(); setupHotList(); + _bufferWidget->setFocusProxy(_inputWidget); + _chatMonitorView->setFocusProxy(_inputWidget); + #ifndef HAVE_KDE # ifdef HAVE_QTMULTIMEDIA QtUi::registerNotificationBackend(new QtMultimediaNotificationBackend(this)); -# endif -# ifdef HAVE_PHONON - QtUi::registerNotificationBackend(new PhononNotificationBackend(this)); # endif QtUi::registerNotificationBackend(new TaskbarNotificationBackend(this)); #else /* HAVE_KDE */ @@ -245,16 +245,15 @@ void MainWin::init() #endif /* HAVE_KDE */ +#ifndef QT_NO_SYSTEMTRAYICON + QtUi::registerNotificationBackend(new SystrayAnimationNotificationBackend(this)); +#endif #ifdef HAVE_LIBSNORE QtUi::registerNotificationBackend(new SnoreNotificationBackend(this)); #elif !defined(QT_NO_SYSTEMTRAYICON) && !defined(HAVE_KDE) QtUi::registerNotificationBackend(new SystrayNotificationBackend(this)); #endif -#ifdef HAVE_INDICATEQT - QtUi::registerNotificationBackend(new IndicatorNotificationBackend(this)); -#endif - #ifdef HAVE_NOTIFICATION_CENTER QtUi::registerNotificationBackend(new OSXNotificationBackend(this)); #endif @@ -266,7 +265,7 @@ void MainWin::init() // we assume that at this point, all configurable actions are defined! QtUi::loadShortcuts(); - connect(bufferWidget(), SIGNAL(currentChanged(BufferId)), SLOT(currentBufferChanged(BufferId))); + connect(bufferWidget(), selectOverload(&AbstractBufferContainer::currentChanged), this, &MainWin::currentBufferChanged); setDisconnectedState(); // Disable menus and stuff @@ -281,25 +280,17 @@ void MainWin::init() // restore locked state of docks QtUi::actionCollection("General")->action("LockLayout")->setChecked(s.value("LockLayout", false).toBool()); - CoreConnection *conn = Client::coreConnection(); - if (!conn->connectToCore()) { - // No autoconnect selected (or no accounts) - showCoreConnectionDlg(); - } -} - - -MainWin::~MainWin() -{ -} + Quassel::registerQuitHandler([this]() { + QtUiSettings s; + saveStateToSettings(s); + saveLayout(); + // Close all open dialogs and the MainWin, so we can safely kill the Client instance afterwards + // Note: This does not quit the application, as quitOnLastWindowClosed is set to false. + // We rely on another quit handler to be registered that actually quits the application. + qApp->closeAllWindows(); + }); - -void MainWin::quit() -{ - QtUiSettings s; - saveStateToSettings(s); - saveLayout(); - QApplication::quit(); + QTimer::singleShot(0, this, &MainWin::doAutoConnect); } @@ -369,109 +360,117 @@ void MainWin::updateIcon() { QIcon icon; if (Client::isConnected()) - icon = QIcon::fromTheme("quassel", QIcon(":/icons/quassel-128.png")); + icon = icon::get("quassel"); else - icon = QIcon::fromTheme("quassel-inactive", QIcon(":/icons/quassel-128.png")); + icon = icon::get("inactive-quassel"); setWindowIcon(icon); - qApp->setWindowIcon(icon); } void MainWin::setupActions() { + QAction *action{nullptr}; ActionCollection *coll = QtUi::actionCollection("General", tr("General")); + // File - coll->addAction("ConnectCore", new Action(QIcon::fromTheme("network-connect"), tr("&Connect to Core..."), coll, - this, SLOT(showCoreConnectionDlg()))); - coll->addAction("DisconnectCore", new Action(QIcon::fromTheme("network-disconnect"), tr("&Disconnect from Core"), coll, - Client::instance(), SLOT(disconnectFromCore()))); - coll->addAction("ChangePassword", new Action(QIcon::fromTheme("dialog-password"), tr("Change &Password..."), coll, - this, SLOT(showPasswordChangeDlg()))); - coll->addAction("CoreInfo", new Action(QIcon::fromTheme("help-about"), tr("Core &Info..."), coll, - this, SLOT(showCoreInfoDlg()))); - coll->addAction("ConfigureNetworks", new Action(QIcon::fromTheme("configure"), tr("Configure &Networks..."), coll, - this, SLOT(on_actionConfigureNetworks_triggered()))); - // FIXME: use QKeySequence::Quit once we depend on Qt 4.6 - coll->addAction("Quit", new Action(QIcon::fromTheme("application-exit"), tr("&Quit"), coll, - this, SLOT(quit()), Qt::CTRL + Qt::Key_Q)); + coll->addActions({ + {"ConnectCore", new Action(icon::get("connect-quassel"), tr("&Connect to Core..."), coll, this, &MainWin::showCoreConnectionDlg)}, + {"DisconnectCore", new Action(icon::get("disconnect-quassel"), tr("&Disconnect from Core"), coll, Client::instance(), &Client::disconnectFromCore)}, + {"ChangePassword", new Action(icon::get("dialog-password"), tr("Change &Password..."), coll, this, &MainWin::showPasswordChangeDlg)}, + {"CoreInfo", new Action(icon::get("help-about"), tr("Core &Info..."), coll, this, &MainWin::showCoreInfoDlg)}, + {"ConfigureNetworks", new Action(icon::get("configure"), tr("Configure &Networks..."), coll, this, &MainWin::on_actionConfigureNetworks_triggered)}, + {"Quit", new Action(icon::get("application-exit"), tr("&Quit"), coll, Quassel::instance(), &Quassel::quit, Qt::CTRL + Qt::Key_Q)} + }); // View - coll->addAction("ConfigureBufferViews", new Action(tr("&Configure Chat Lists..."), coll, - this, SLOT(on_actionConfigureViews_triggered()))); - - QAction *lockAct = coll->addAction("LockLayout", new Action(tr("&Lock Layout"), coll)); - lockAct->setCheckable(true); - connect(lockAct, SIGNAL(toggled(bool)), SLOT(on_actionLockLayout_toggled(bool))); + coll->addAction("ConfigureBufferViews", new Action(tr("&Configure Chat Lists..."), coll, this, &MainWin::on_actionConfigureViews_triggered)); - coll->addAction("ToggleSearchBar", new Action(QIcon::fromTheme("edit-find"), tr("Show &Search Bar"), coll, - 0, 0, QKeySequence::Find))->setCheckable(true); - coll->addAction("ShowAwayLog", new Action(tr("Show Away Log"), coll, - this, SLOT(showAwayLog()))); - coll->addAction("ToggleMenuBar", new Action(QIcon::fromTheme("show-menu"), tr("Show &Menubar"), coll, - 0, 0))->setCheckable(true); + coll->addAction("ToggleSearchBar", new Action(icon::get("edit-find"), tr("Show &Search Bar"), coll, QKeySequence::Find))->setCheckable(true); + coll->addAction("ShowAwayLog", new Action(tr("Show Away Log"), coll, this, &MainWin::showAwayLog)); + coll->addAction("ToggleMenuBar", new Action(icon::get("show-menu"), tr("Show &Menubar"), coll))->setCheckable(true); + coll->addAction("ToggleStatusBar", new Action(tr("Show Status &Bar"), coll))->setCheckable(true); - coll->addAction("ToggleStatusBar", new Action(tr("Show Status &Bar"), coll, - 0, 0))->setCheckable(true); + action = coll->addAction("LockLayout", new Action(tr("&Lock Layout"), coll)); + action->setCheckable(true); + connect(action, &QAction::toggled, this, &MainWin::on_actionLockLayout_toggled); #ifdef HAVE_KDE +#if KCONFIGWIDGETS_VERSION < QT_VERSION_CHECK(5,23,0) _fullScreenAction = KStandardAction::fullScreen(this, SLOT(onFullScreenToggled()), this, coll); #else - _fullScreenAction = new Action(QIcon::fromTheme("view-fullscreen"), tr("&Full Screen Mode"), coll, - this, SLOT(onFullScreenToggled()), QKeySequence(Qt::Key_F11)); + _fullScreenAction = KStandardAction::fullScreen(this, &MainWin::onFullScreenToggled, this, coll); +#endif +#else + _fullScreenAction = new Action(icon::get("view-fullscreen"), tr("&Full Screen Mode"), coll, this, &MainWin::onFullScreenToggled, QKeySequence::FullScreen); _fullScreenAction->setCheckable(true); coll->addAction("ToggleFullScreen", _fullScreenAction); #endif // Settings - QAction *configureShortcutsAct = new Action(QIcon::fromTheme("configure-shortcuts"), tr("Configure &Shortcuts..."), coll, - this, SLOT(showShortcutsDlg())); - configureShortcutsAct->setMenuRole(QAction::NoRole); - coll->addAction("ConfigureShortcuts", configureShortcutsAct); - -#ifdef Q_OS_MAC - QAction *configureQuasselAct = new Action(QIcon::fromTheme("configure"), tr("&Configure Quassel..."), coll, - this, SLOT(showSettingsDlg())); - configureQuasselAct->setMenuRole(QAction::PreferencesRole); -#else - QAction *configureQuasselAct = new Action(QIcon::fromTheme("configure"), tr("&Configure Quassel..."), coll, - this, SLOT(showSettingsDlg()), QKeySequence(Qt::Key_F7)); -#endif - coll->addAction("ConfigureQuassel", configureQuasselAct); + coll->addAction("ConfigureShortcuts", new Action(icon::get("configure-shortcuts"), tr("Configure &Shortcuts..."), coll, + this, &MainWin::showShortcutsDlg))->setMenuRole(QAction::NoRole); + coll->addAction("ConfigureQuassel", new Action(icon::get("configure"), tr("&Configure Quassel..."), coll, + this, &MainWin::showSettingsDlg, QKeySequence(Qt::Key_F7)))->setMenuRole(QAction::PreferencesRole); // Help - QAction *aboutQuasselAct = new Action(QIcon(":/icons/quassel.png"), tr("&About Quassel"), coll, - this, SLOT(showAboutDlg())); - aboutQuasselAct->setMenuRole(QAction::AboutRole); - coll->addAction("AboutQuassel", aboutQuasselAct); - - QAction *aboutQtAct = new Action(QIcon(":/pics/qt-logo.png"), tr("About &Qt"), coll, - qApp, SLOT(aboutQt())); - aboutQtAct->setMenuRole(QAction::AboutQtRole); - coll->addAction("AboutQt", aboutQtAct); - coll->addAction("DebugNetworkModel", new Action(QIcon::fromTheme("tools-report-bug"), tr("Debug &NetworkModel"), coll, - this, SLOT(on_actionDebugNetworkModel_triggered()))); - coll->addAction("DebugBufferViewOverlay", new Action(QIcon::fromTheme("tools-report-bug"), tr("Debug &BufferViewOverlay"), coll, - this, SLOT(on_actionDebugBufferViewOverlay_triggered()))); - coll->addAction("DebugMessageModel", new Action(QIcon::fromTheme("tools-report-bug"), tr("Debug &MessageModel"), coll, - this, SLOT(on_actionDebugMessageModel_triggered()))); - coll->addAction("DebugHotList", new Action(QIcon::fromTheme("tools-report-bug"), tr("Debug &HotList"), coll, - this, SLOT(on_actionDebugHotList_triggered()))); - coll->addAction("DebugLog", new Action(QIcon::fromTheme("tools-report-bug"), tr("Debug &Log"), coll, - this, SLOT(on_actionDebugLog_triggered()))); - coll->addAction("ReloadStyle", new Action(QIcon::fromTheme("view-refresh"), tr("Reload Stylesheet"), coll, - QtUi::style(), SLOT(reload()), QKeySequence::Refresh)); - - coll->addAction("HideCurrentBuffer", new Action(tr("Hide Current Buffer"), coll, - this, SLOT(hideCurrentBuffer()), QKeySequence::Close)); + coll->addAction("AboutQuassel", new Action(icon::get("quassel"), tr("&About Quassel"), coll, this, &MainWin::showAboutDlg))->setMenuRole(QAction::AboutRole); + coll->addAction("AboutQt", new Action(QIcon(":/pics/qt-logo.png"), tr("About &Qt"), coll, qApp, &QApplication::aboutQt))->setMenuRole(QAction::AboutQtRole); + coll->addActions({ + {"DebugNetworkModel", new Action(icon::get("tools-report-bug"), tr("Debug &NetworkModel"), coll, this, &MainWin::on_actionDebugNetworkModel_triggered)}, + {"DebugBufferViewOverlay", new Action(icon::get("tools-report-bug"), tr("Debug &BufferViewOverlay"), coll, this, &MainWin::on_actionDebugBufferViewOverlay_triggered)}, + {"DebugMessageModel", new Action(icon::get("tools-report-bug"), tr("Debug &MessageModel"), coll, this, &MainWin::on_actionDebugMessageModel_triggered)}, + {"DebugHotList", new Action(icon::get("tools-report-bug"), tr("Debug &HotList"), coll, this, &MainWin::on_actionDebugHotList_triggered)}, + {"DebugLog", new Action(icon::get("tools-report-bug"), tr("Debug &Log"), coll, this, &MainWin::on_actionDebugLog_triggered)}, + {"ShowResourceTree", new Action(icon::get("tools-report-bug"), tr("Show &Resource Tree"), coll, this, &MainWin::on_actionShowResourceTree_triggered)}, + {"ReloadStyle", new Action(icon::get("view-refresh"), tr("Reload Stylesheet"), coll, QtUi::style(), &UiStyle::reload, QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_R))} + }); + + // Other + coll->addAction("HideCurrentBuffer", new Action(tr("Hide Current Buffer"), coll, this, &MainWin::hideCurrentBuffer, QKeySequence::Close)); + + // Text formatting + coll = QtUi::actionCollection("TextFormat", tr("Text formatting")); + + coll->addActions({ + {"FormatApplyColor", new Action( + icon::get("format-text-color"), tr("Apply foreground color"), coll, + this, &MainWin::on_inputFormatApplyColor_triggered, + QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_G)) + }, + {"FormatApplyColorFill", new Action( + icon::get("format-fill-color"), tr("Apply background color"), coll, + this, &MainWin::on_inputFormatApplyColorFill_triggered, + QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_B)) + }, + {"FormatClear", new Action( + icon::get("edit-clear"), tr("Clear formatting"), coll, + this, &MainWin::on_inputFormatClear_triggered, + QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_C)) + }, + {"FormatBold", new Action( + icon::get("format-text-bold"), tr("Toggle bold"), coll, + this, &MainWin::on_inputFormatBold_triggered, + QKeySequence::Bold) + }, + {"FormatItalic", new Action( + icon::get("format-text-italic"), tr("Toggle italics"), coll, + this, &MainWin::on_inputFormatItalic_triggered, + QKeySequence::Italic) + }, + {"FormatUnderline", new Action( + icon::get("format-text-underline"), tr("Toggle underline"), coll, + this, &MainWin::on_inputFormatUnderline_triggered, + QKeySequence::Underline) + } + }); // Navigation coll = QtUi::actionCollection("Navigation", tr("Navigation")); - coll->addAction("JumpHotBuffer", new Action(tr("Jump to hot chat"), coll, - this, SLOT(on_jumpHotBuffer_triggered()), QKeySequence(Qt::META + Qt::Key_A))); - - coll->addAction("ActivateBufferFilter", new Action(tr("Activate the buffer search"), coll, - this, SLOT(on_bufferSearch_triggered()), QKeySequence(Qt::CTRL + Qt::Key_S))); + coll->addActions({ + {"JumpHotBuffer", new Action(tr("Jump to hot chat"), coll, this, &MainWin::on_jumpHotBuffer_triggered, QKeySequence(Qt::META + Qt::Key_A))}, + {"ActivateBufferFilter", new Action(tr("Activate the buffer search"), coll, this, &MainWin::on_bufferSearch_triggered, QKeySequence(Qt::CTRL + Qt::Key_S))} + }); // Jump keys #ifdef Q_OS_MAC @@ -482,57 +481,57 @@ void MainWin::setupActions() const int jumpModifier = Qt::AltModifier; #endif - coll->addAction("BindJumpKey0", new Action(tr("Set Quick Access #0"), coll, this, SLOT(bindJumpKey()), + coll->addAction("BindJumpKey0", new Action(tr("Set Quick Access #0"), coll, this, &MainWin::bindJumpKey, QKeySequence(bindModifier + Qt::Key_0)))->setProperty("Index", 0); - coll->addAction("BindJumpKey1", new Action(tr("Set Quick Access #1"), coll, this, SLOT(bindJumpKey()), + coll->addAction("BindJumpKey1", new Action(tr("Set Quick Access #1"), coll, this, &MainWin::bindJumpKey, QKeySequence(bindModifier + Qt::Key_1)))->setProperty("Index", 1); - coll->addAction("BindJumpKey2", new Action(tr("Set Quick Access #2"), coll, this, SLOT(bindJumpKey()), + coll->addAction("BindJumpKey2", new Action(tr("Set Quick Access #2"), coll, this, &MainWin::bindJumpKey, QKeySequence(bindModifier + Qt::Key_2)))->setProperty("Index", 2); - coll->addAction("BindJumpKey3", new Action(tr("Set Quick Access #3"), coll, this, SLOT(bindJumpKey()), + coll->addAction("BindJumpKey3", new Action(tr("Set Quick Access #3"), coll, this, &MainWin::bindJumpKey, QKeySequence(bindModifier + Qt::Key_3)))->setProperty("Index", 3); - coll->addAction("BindJumpKey4", new Action(tr("Set Quick Access #4"), coll, this, SLOT(bindJumpKey()), + coll->addAction("BindJumpKey4", new Action(tr("Set Quick Access #4"), coll, this, &MainWin::bindJumpKey, QKeySequence(bindModifier + Qt::Key_4)))->setProperty("Index", 4); - coll->addAction("BindJumpKey5", new Action(tr("Set Quick Access #5"), coll, this, SLOT(bindJumpKey()), + coll->addAction("BindJumpKey5", new Action(tr("Set Quick Access #5"), coll, this, &MainWin::bindJumpKey, QKeySequence(bindModifier + Qt::Key_5)))->setProperty("Index", 5); - coll->addAction("BindJumpKey6", new Action(tr("Set Quick Access #6"), coll, this, SLOT(bindJumpKey()), + coll->addAction("BindJumpKey6", new Action(tr("Set Quick Access #6"), coll, this, &MainWin::bindJumpKey, QKeySequence(bindModifier + Qt::Key_6)))->setProperty("Index", 6); - coll->addAction("BindJumpKey7", new Action(tr("Set Quick Access #7"), coll, this, SLOT(bindJumpKey()), + coll->addAction("BindJumpKey7", new Action(tr("Set Quick Access #7"), coll, this, &MainWin::bindJumpKey, QKeySequence(bindModifier + Qt::Key_7)))->setProperty("Index", 7); - coll->addAction("BindJumpKey8", new Action(tr("Set Quick Access #8"), coll, this, SLOT(bindJumpKey()), + coll->addAction("BindJumpKey8", new Action(tr("Set Quick Access #8"), coll, this, &MainWin::bindJumpKey, QKeySequence(bindModifier + Qt::Key_8)))->setProperty("Index", 8); - coll->addAction("BindJumpKey9", new Action(tr("Set Quick Access #9"), coll, this, SLOT(bindJumpKey()), + coll->addAction("BindJumpKey9", new Action(tr("Set Quick Access #9"), coll, this, &MainWin::bindJumpKey, QKeySequence(bindModifier + Qt::Key_9)))->setProperty("Index", 9); - coll->addAction("JumpKey0", new Action(tr("Quick Access #0"), coll, this, SLOT(onJumpKey()), + coll->addAction("JumpKey0", new Action(tr("Quick Access #0"), coll, this, &MainWin::onJumpKey, QKeySequence(jumpModifier + Qt::Key_0)))->setProperty("Index", 0); - coll->addAction("JumpKey1", new Action(tr("Quick Access #1"), coll, this, SLOT(onJumpKey()), + coll->addAction("JumpKey1", new Action(tr("Quick Access #1"), coll, this, &MainWin::onJumpKey, QKeySequence(jumpModifier + Qt::Key_1)))->setProperty("Index", 1); - coll->addAction("JumpKey2", new Action(tr("Quick Access #2"), coll, this, SLOT(onJumpKey()), + coll->addAction("JumpKey2", new Action(tr("Quick Access #2"), coll, this, &MainWin::onJumpKey, QKeySequence(jumpModifier + Qt::Key_2)))->setProperty("Index", 2); - coll->addAction("JumpKey3", new Action(tr("Quick Access #3"), coll, this, SLOT(onJumpKey()), + coll->addAction("JumpKey3", new Action(tr("Quick Access #3"), coll, this, &MainWin::onJumpKey, QKeySequence(jumpModifier + Qt::Key_3)))->setProperty("Index", 3); - coll->addAction("JumpKey4", new Action(tr("Quick Access #4"), coll, this, SLOT(onJumpKey()), + coll->addAction("JumpKey4", new Action(tr("Quick Access #4"), coll, this, &MainWin::onJumpKey, QKeySequence(jumpModifier + Qt::Key_4)))->setProperty("Index", 4); - coll->addAction("JumpKey5", new Action(tr("Quick Access #5"), coll, this, SLOT(onJumpKey()), + coll->addAction("JumpKey5", new Action(tr("Quick Access #5"), coll, this, &MainWin::onJumpKey, QKeySequence(jumpModifier + Qt::Key_5)))->setProperty("Index", 5); - coll->addAction("JumpKey6", new Action(tr("Quick Access #6"), coll, this, SLOT(onJumpKey()), + coll->addAction("JumpKey6", new Action(tr("Quick Access #6"), coll, this, &MainWin::onJumpKey, QKeySequence(jumpModifier + Qt::Key_6)))->setProperty("Index", 6); - coll->addAction("JumpKey7", new Action(tr("Quick Access #7"), coll, this, SLOT(onJumpKey()), + coll->addAction("JumpKey7", new Action(tr("Quick Access #7"), coll, this, &MainWin::onJumpKey, QKeySequence(jumpModifier + Qt::Key_7)))->setProperty("Index", 7); - coll->addAction("JumpKey8", new Action(tr("Quick Access #8"), coll, this, SLOT(onJumpKey()), + coll->addAction("JumpKey8", new Action(tr("Quick Access #8"), coll, this, &MainWin::onJumpKey, QKeySequence(jumpModifier + Qt::Key_8)))->setProperty("Index", 8); - coll->addAction("JumpKey9", new Action(tr("Quick Access #9"), coll, this, SLOT(onJumpKey()), + coll->addAction("JumpKey9", new Action(tr("Quick Access #9"), coll, this, &MainWin::onJumpKey, QKeySequence(jumpModifier + Qt::Key_9)))->setProperty("Index", 9); // Buffer navigation - coll->addAction("NextBufferView", new Action(QIcon::fromTheme("go-next-view"), tr("Activate Next Chat List"), coll, - this, SLOT(nextBufferView()), QKeySequence(QKeySequence::Forward))); - coll->addAction("PreviousBufferView", new Action(QIcon::fromTheme("go-previous-view"), tr("Activate Previous Chat List"), coll, - this, SLOT(previousBufferView()), QKeySequence::Back)); - coll->addAction("NextBuffer", new Action(QIcon::fromTheme("go-down"), tr("Go to Next Chat"), coll, - this, SLOT(nextBuffer()), QKeySequence(Qt::ALT + Qt::Key_Down))); - coll->addAction("PreviousBuffer", new Action(QIcon::fromTheme("go-up"), tr("Go to Previous Chat"), coll, - this, SLOT(previousBuffer()), QKeySequence(Qt::ALT + Qt::Key_Up))); + coll->addAction("NextBufferView", new Action(icon::get("go-next-view"), tr("Activate Next Chat List"), coll, + this, &MainWin::nextBufferView, QKeySequence(QKeySequence::Forward))); + coll->addAction("PreviousBufferView", new Action(icon::get("go-previous-view"), tr("Activate Previous Chat List"), coll, + this, &MainWin::previousBufferView, QKeySequence::Back)); + coll->addAction("NextBuffer", new Action(icon::get("go-down"), tr("Go to Next Chat"), coll, + this, &MainWin::nextBuffer, QKeySequence(Qt::ALT + Qt::Key_Down))); + coll->addAction("PreviousBuffer", new Action(icon::get("go-up"), tr("Go to Previous Chat"), coll, + this, &MainWin::previousBuffer, QKeySequence(Qt::ALT + Qt::Key_Up))); } @@ -578,8 +577,13 @@ void MainWin::setupMenus() _settingsMenu = menuBar()->addMenu(tr("&Settings")); #ifdef HAVE_KDE +#if KCONFIGWIDGETS_VERSION < QT_VERSION_CHECK(5,23,0) _settingsMenu->addAction(KStandardAction::configureNotifications(this, SLOT(showNotificationsDlg()), this)); _settingsMenu->addAction(KStandardAction::keyBindings(this, SLOT(showShortcutsDlg()), this)); +#else + _settingsMenu->addAction(KStandardAction::configureNotifications(this, &MainWin::showNotificationsDlg, this)); + _settingsMenu->addAction(KStandardAction::keyBindings(this, &MainWin::showShortcutsDlg, this)); +#endif #else _settingsMenu->addAction(coll->action("ConfigureShortcuts")); #endif @@ -592,15 +596,20 @@ void MainWin::setupMenus() #ifndef HAVE_KDE _helpMenu->addAction(coll->action("AboutQt")); #else +#if KCONFIGWIDGETS_VERSION < QT_VERSION_CHECK(5,23,0) _helpMenu->addAction(KStandardAction::aboutKDE(_kHelpMenu, SLOT(aboutKDE()), this)); +#else + _helpMenu->addAction(KStandardAction::aboutKDE(_kHelpMenu, &KHelpMenu::aboutKDE, this)); +#endif #endif _helpMenu->addSeparator(); - _helpDebugMenu = _helpMenu->addMenu(QIcon::fromTheme("tools-report-bug"), tr("Debug")); + _helpDebugMenu = _helpMenu->addMenu(icon::get("tools-report-bug"), tr("Debug")); _helpDebugMenu->addAction(coll->action("DebugNetworkModel")); _helpDebugMenu->addAction(coll->action("DebugBufferViewOverlay")); _helpDebugMenu->addAction(coll->action("DebugMessageModel")); _helpDebugMenu->addAction(coll->action("DebugHotList")); _helpDebugMenu->addAction(coll->action("DebugLog")); + _helpDebugMenu->addAction(coll->action("ShowResourceTree")); _helpDebugMenu->addSeparator(); _helpDebugMenu->addAction(coll->action("ReloadStyle")); @@ -612,8 +621,8 @@ void MainWin::setupMenus() showMenuBar->setChecked(enabled); enabled ? menuBar()->show() : menuBar()->hide(); - connect(showMenuBar, SIGNAL(toggled(bool)), menuBar(), SLOT(setVisible(bool))); - connect(showMenuBar, SIGNAL(toggled(bool)), this, SLOT(saveMenuBarStatus(bool))); + connect(showMenuBar, &QAction::toggled, menuBar(), &QMenuBar::setVisible); + connect(showMenuBar, &QAction::toggled, this, &MainWin::saveMenuBarStatus); } @@ -638,23 +647,25 @@ void MainWin::addBufferView(ClientBufferViewConfig *config) return; config->setLocked(QtUiSettings().value("LockLayout", false).toBool()); - BufferViewDock *dock = new BufferViewDock(config, this); + auto *dock = new BufferViewDock(config, this); //create the view and initialize it's filter - BufferView *view = new BufferView(dock); + auto *view = new BufferView(dock); view->setFilteredModel(Client::bufferModel(), config); view->installEventFilter(_inputWidget); // for key presses Client::bufferModel()->synchronizeView(view); + dock->setLocked(QtUiSettings().value("LockLayout", false).toBool()); + dock->setWidget(view); dock->setVisible(_layoutLoaded); // don't show before state has been restored addDockWidget(Qt::LeftDockWidgetArea, dock); _bufferViewsMenu->addAction(dock->toggleViewAction()); - connect(dock->toggleViewAction(), SIGNAL(toggled(bool)), this, SLOT(bufferViewToggled(bool))); - connect(dock, SIGNAL(visibilityChanged(bool)), SLOT(bufferViewVisibilityChanged(bool))); + connect(dock->toggleViewAction(), &QAction::toggled, this, &MainWin::bufferViewToggled); + connect(dock, &QDockWidget::visibilityChanged, this, &MainWin::bufferViewVisibilityChanged); _bufferViews.append(dock); if (!activeBufferView()) @@ -696,9 +707,9 @@ void MainWin::bufferViewToggled(bool enabled) // since this isn't our fault and we can't do anything about it, we suppress the resulting calls return; } - QAction *action = qobject_cast(sender()); + auto *action = qobject_cast(sender()); Q_ASSERT(action); - BufferViewDock *dock = qobject_cast(action->parent()); + auto *dock = qobject_cast(action->parent()); Q_ASSERT(dock); // Make sure we don't toggle backlog fetch for a view we've already removed @@ -715,7 +726,7 @@ void MainWin::bufferViewToggled(bool enabled) void MainWin::bufferViewVisibilityChanged(bool visible) { Q_UNUSED(visible); - BufferViewDock *dock = qobject_cast(sender()); + auto *dock = qobject_cast(sender()); Q_ASSERT(dock); if ((!dock->isHidden() && !activeBufferView()) || (dock->isHidden() && dock->isActive())) nextBufferView(); @@ -727,16 +738,16 @@ BufferView *MainWin::allBuffersView() const // "All Buffers" is always the first dock created if (_bufferViews.count() > 0) return _bufferViews[0]->bufferView(); - return 0; + return nullptr; } BufferView *MainWin::activeBufferView() const { if (_activeBufferViewIndex < 0 || _activeBufferViewIndex >= _bufferViews.count()) - return 0; + return nullptr; BufferViewDock *dock = _bufferViews.at(_activeBufferViewIndex); - return dock->isActive() ? dock->bufferView() : 0; + return dock->isActive() ? dock->bufferView() : nullptr; } @@ -765,20 +776,55 @@ void MainWin::changeActiveBufferView(int bufferViewId) void MainWin::showPasswordChangeDlg() { - if((Client::coreFeatures() & Quassel::PasswordChange)) { - PasswordChangeDlg dlg(this); - dlg.exec(); + if(Client::isCoreFeatureEnabled(Quassel::Feature::PasswordChange)) { + PasswordChangeDlg{}.exec(); } else { QMessageBox box(QMessageBox::Warning, tr("Feature Not Supported"), tr("Your Quassel Core does not support this feature"), - QMessageBox::Ok, this); + QMessageBox::Ok); box.setInformativeText(tr("You need a Quassel Core v0.12.0 or newer in order to be able to remotely change your password.")); box.exec(); } } +void MainWin::showMigrationWarning(bool show) +{ + if (show && !_migrationWarning) { + _migrationWarning = new QMessageBox(QMessageBox::Information, + tr("Upgrading..."), + "" + tr("Your database is being upgraded") + "", + QMessageBox::NoButton, this); + _migrationWarning->setInformativeText("

" + + tr("In order to support new features, we need to make changes to your backlog database. This may take a long while.") + + "

" + + tr("Do not exit Quassel until the upgrade is complete!") + + "

"); + _migrationWarning->setStandardButtons(QMessageBox::NoButton); + _migrationWarning->show(); + } + else if (!show && _migrationWarning) { + _migrationWarning->close(); + _migrationWarning->deleteLater(); + _migrationWarning = nullptr; + } +} + + +void MainWin::onExitRequested(const QString &reason) +{ + if (!reason.isEmpty()) { + QMessageBox box(QMessageBox::Critical, + tr("Fatal error"), + "" + tr("Quassel encountered a fatal error and is terminated.") + "", + QMessageBox::Ok); + box.setInformativeText("

" + tr("Reason:") + " " + reason + ""); + box.exec(); + } +} + + void MainWin::changeActiveBufferView(bool backwards) { if (_activeBufferViewIndex >= 0 && _activeBufferViewIndex < _bufferViews.count()) { @@ -849,22 +895,19 @@ void MainWin::hideCurrentBuffer() void MainWin::showNotificationsDlg() { - SettingsPageDlg dlg(new NotificationsSettingsPage(this), this); - dlg.exec(); + SettingsPageDlg{new NotificationsSettingsPage{}}.exec(); } void MainWin::on_actionConfigureNetworks_triggered() { - SettingsPageDlg dlg(new NetworksSettingsPage(this), this); - dlg.exec(); + SettingsPageDlg{new NetworksSettingsPage{}}.exec(); } void MainWin::on_actionConfigureViews_triggered() { - SettingsPageDlg dlg(new BufferViewSettingsPage(this), this); - dlg.exec(); + SettingsPageDlg{new BufferViewSettingsPage{}}.exec(); } @@ -874,11 +917,26 @@ void MainWin::on_actionLockLayout_toggled(bool lock) foreach(VerticalDock *dock, docks) { dock->showTitle(!lock); } + + QList nickdocks = findChildren(); + foreach(NickListDock *nickdock, nickdocks) { + nickdock->setLocked(lock); + } + + QList bufferdocks = findChildren(); + foreach(BufferViewDock *bufferdock, bufferdocks) { + bufferdock->setLocked(lock); + } + if (Client::bufferViewManager()) { foreach(ClientBufferViewConfig *config, Client::bufferViewManager()->clientBufferViewConfigs()) { config->setLocked(lock); } } + + _mainToolBar->setMovable(!lock); + _nickToolBar->setMovable(!lock); + QtUiSettings().setValue("LockLayout", lock); } @@ -889,6 +947,7 @@ void MainWin::setupNickWidget() NickListDock *nickDock = new NickListDock(tr("Nicks"), this); nickDock->setObjectName("NickDock"); nickDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + nickDock->setLocked(QtUiSettings().value("LockLayout", false).toBool()); _nickListWidget = new NickListWidget(nickDock); nickDock->setWidget(_nickListWidget); @@ -898,7 +957,7 @@ void MainWin::setupNickWidget() nickDock->toggleViewAction()->setText(tr("Show Nick List")); // See NickListDock::NickListDock(); - // connect(nickDock->toggleViewAction(), SIGNAL(triggered(bool)), nickListWidget, SLOT(showWidget(bool))); + // connect(nickDock->toggleViewAction(), &NickListDock::triggered, nickListWidget, &QWidget::showWidget); // attach the NickListWidget to the BufferModel and the default selection _nickListWidget->setModel(Client::bufferModel()); @@ -913,9 +972,8 @@ void MainWin::setupChatMonitor() VerticalDock *dock = new VerticalDock(tr("Chat Monitor"), this); dock->setObjectName("ChatMonitorDock"); - ChatMonitorFilter *filter = new ChatMonitorFilter(Client::messageModel(), this); + auto *filter = new ChatMonitorFilter(Client::messageModel(), this); _chatMonitorView = new ChatMonitorView(filter, this); - _chatMonitorView->setFocusProxy(_inputWidget); _chatMonitorView->show(); dock->setWidget(_chatMonitorView); dock->hide(); @@ -942,11 +1000,7 @@ void MainWin::setupInputWidget() _inputWidget->setModel(Client::bufferModel()); _inputWidget->setSelectionModel(Client::bufferModel()->standardSelectionModel()); - _bufferWidget->setFocusProxy(_inputWidget); - _inputWidget->inputLine()->installEventFilter(_bufferWidget); - - connect(_topicWidget, SIGNAL(switchedPlain()), _bufferWidget, SLOT(setFocus())); } @@ -961,6 +1015,8 @@ void MainWin::setupTopicWidget() _topicWidget->setModel(Client::bufferModel()); _topicWidget->setSelectionModel(Client::bufferModel()->standardSelectionModel()); + connect(_topicWidget, &TopicWidget::switchedPlain, _bufferWidget, selectOverload<>(&QWidget::setFocus)); + addDockWidget(Qt::TopDockWidgetArea, dock, Qt::Vertical); _viewMenu->addAction(dock->toggleViewAction()); @@ -968,6 +1024,27 @@ void MainWin::setupTopicWidget() } +void MainWin::setupTransferWidget() +{ + auto dock = new QDockWidget(tr("Transfers"), this); + dock->setObjectName("TransferDock"); + dock->setAllowedAreas(Qt::TopDockWidgetArea|Qt::BottomDockWidgetArea); + + auto view = new QTableView(dock); // to be replaced by the real thing + view->setModel(Client::transferModel()); + dock->setWidget(view); + dock->hide(); // hidden by default + addDockWidget(Qt::TopDockWidgetArea, dock, Qt::Vertical); + + auto action = dock->toggleViewAction(); + action->setText(tr("Show File Transfers")); + action->setIcon(icon::get("download")); + action->setShortcut(QKeySequence(Qt::Key_F6)); + QtUi::actionCollection("General")->addAction("ShowTransferWidget", action); + _viewMenu->addAction(action); +} + + void MainWin::setupViewMenuTail() { _viewMenu->addSeparator(); @@ -999,16 +1076,18 @@ void MainWin::setupStatusBar() showStatusbar->setChecked(enabled); enabled ? statusBar()->show() : statusBar()->hide(); - connect(showStatusbar, SIGNAL(toggled(bool)), statusBar(), SLOT(setVisible(bool))); - connect(showStatusbar, SIGNAL(toggled(bool)), this, SLOT(saveStatusBarStatus(bool))); + connect(showStatusbar, &QAction::toggled, statusBar(), &QWidget::setVisible); + connect(showStatusbar, &QAction::toggled, this, &MainWin::saveStatusBarStatus); - connect(Client::coreConnection(), SIGNAL(connectionMsg(QString)), statusBar(), SLOT(showMessage(QString))); + connect(Client::coreConnection(), &CoreConnection::connectionMsg, statusBar(), [statusBar = statusBar()](auto &&message) { + statusBar->showMessage(message); + }); } void MainWin::setupHotList() { - FlatProxyModel *flatProxy = new FlatProxyModel(this); + auto *flatProxy = new FlatProxyModel(this); flatProxy->setSourceModel(Client::bufferModel()); _bufferHotList = new BufferHotListFilter(flatProxy); } @@ -1037,16 +1116,15 @@ void MainWin::setupSystray() #else _systemTray = new SystemTray(this); // dummy #endif - _systemTray->init(); } void MainWin::setupToolBars() { - connect(_bufferWidget, SIGNAL(currentChanged(QModelIndex)), - QtUi::toolBarActionProvider(), SLOT(currentBufferChanged(QModelIndex))); - connect(_nickListWidget, SIGNAL(nickSelectionChanged(QModelIndexList)), - QtUi::toolBarActionProvider(), SLOT(nickSelectionChanged(QModelIndexList))); + connect(_bufferWidget, selectOverload(&AbstractBufferContainer::currentChanged), + QtUi::toolBarActionProvider(), &ToolBarActionProvider::onCurrentBufferChanged); + connect(_nickListWidget, &NickListWidget::nickSelectionChanged, + QtUi::toolBarActionProvider(), &ToolBarActionProvider::onNickSelectionChanged); #ifdef Q_OS_MAC setUnifiedTitleAndToolBarOnMac(true); @@ -1061,15 +1139,37 @@ void MainWin::setupToolBars() _mainToolBar->setWindowTitle(tr("Main Toolbar")); addToolBar(_mainToolBar); + if (Quassel::runMode() != Quassel::Monolithic) { + ActionCollection *coll = QtUi::actionCollection("General"); + _mainToolBar->addAction(coll->action("ConnectCore")); + _mainToolBar->addAction(coll->action("DisconnectCore")); + } + + _mainToolBar->setMovable(!QtUiSettings().value("LockLayout", false).toBool()); + QtUi::toolBarActionProvider()->addActions(_mainToolBar, ToolBarActionProvider::MainToolBar); _toolbarMenu->addAction(_mainToolBar->toggleViewAction()); +#ifdef HAVE_KDE + _nickToolBar = new KToolBar("NickToolBar", this, Qt::TopToolBarArea, false, true, true); +#else + _nickToolBar = new QToolBar(this); + _nickToolBar->setObjectName("NickToolBar"); +#endif + _nickToolBar->setWindowTitle(tr("Nick Toolbar")); + _nickToolBar->setVisible(false); //default: not visible + addToolBar(_nickToolBar); + _nickToolBar->setMovable(!QtUiSettings().value("LockLayout", false).toBool()); + + QtUi::toolBarActionProvider()->addActions(_nickToolBar, ToolBarActionProvider::NickToolBar); + _toolbarMenu->addAction(_nickToolBar->toggleViewAction()); + #ifdef Q_OS_MAC QtUiSettings uiSettings; bool visible = uiSettings.value("ShowMainToolBar", QVariant(true)).toBool(); _mainToolBar->setVisible(visible); - connect(_mainToolBar, SIGNAL(visibilityChanged(bool)), this, SLOT(saveMainToolBarStatus(bool))); + connect(_mainToolBar, &QToolBar::visibilityChanged, this, &MainWin::saveMainToolBarStatus); #endif } @@ -1084,14 +1184,25 @@ void MainWin::saveMainToolBarStatus(bool enabled) } +void MainWin::doAutoConnect() +{ + if (!Client::coreConnection()->connectToCore()) { + // No autoconnect selected (or no accounts) + showCoreConnectionDlg(); + } +} + + void MainWin::connectedToCore() { Q_CHECK_PTR(Client::bufferViewManager()); - connect(Client::bufferViewManager(), SIGNAL(bufferViewConfigAdded(int)), this, SLOT(addBufferView(int))); - connect(Client::bufferViewManager(), SIGNAL(bufferViewConfigDeleted(int)), this, SLOT(removeBufferView(int))); - connect(Client::bufferViewManager(), SIGNAL(initDone()), this, SLOT(loadLayout())); + connect(Client::bufferViewManager(), &BufferViewManager::bufferViewConfigAdded, this, selectOverload(&MainWin::addBufferView)); + connect(Client::bufferViewManager(), &BufferViewManager::bufferViewConfigDeleted, this, &MainWin::removeBufferView); + connect(Client::bufferViewManager(), &SyncableObject::initDone, this, &MainWin::loadLayout); - connect(Client::transferManager(), SIGNAL(transferAdded(QUuid)), SLOT(showNewTransferDlg(QUuid))); + if (Client::transferManager()) { + connect(Client::transferManager(), &TransferManager::transferAdded, this, &MainWin::showNewTransferDlg); + } setConnectedState(); } @@ -1111,13 +1222,13 @@ void MainWin::setConnectedState() action->setVisible(!Client::internalCore()); } - disconnect(Client::backlogManager(), SIGNAL(updateProgress(int, int)), _msgProcessorStatusWidget, SLOT(setProgress(int, int))); - disconnect(Client::backlogManager(), SIGNAL(messagesRequested(const QString &)), this, SLOT(showStatusBarMessage(const QString &))); - disconnect(Client::backlogManager(), SIGNAL(messagesProcessed(const QString &)), this, SLOT(showStatusBarMessage(const QString &))); + disconnect(Client::backlogManager(), &ClientBacklogManager::updateProgress, _msgProcessorStatusWidget, &MsgProcessorStatusWidget::setProgress); + disconnect(Client::backlogManager(), &ClientBacklogManager::messagesRequested, this, &MainWin::showStatusBarMessage); + disconnect(Client::backlogManager(), &ClientBacklogManager::messagesProcessed, this, &MainWin::showStatusBarMessage); if (!Client::internalCore()) { - connect(Client::backlogManager(), SIGNAL(updateProgress(int, int)), _msgProcessorStatusWidget, SLOT(setProgress(int, int))); - connect(Client::backlogManager(), SIGNAL(messagesRequested(const QString &)), this, SLOT(showStatusBarMessage(const QString &))); - connect(Client::backlogManager(), SIGNAL(messagesProcessed(const QString &)), this, SLOT(showStatusBarMessage(const QString &))); + connect(Client::backlogManager(), &ClientBacklogManager::updateProgress, _msgProcessorStatusWidget, &MsgProcessorStatusWidget::setProgress); + connect(Client::backlogManager(), &ClientBacklogManager::messagesRequested, this, &MainWin::showStatusBarMessage); + connect(Client::backlogManager(), &ClientBacklogManager::messagesProcessed, this, &MainWin::showStatusBarMessage); } // _viewMenu->setEnabled(true); @@ -1234,7 +1345,7 @@ void MainWin::setDisconnectedState() void MainWin::userAuthenticationRequired(CoreAccount *account, bool *valid, const QString &errorMessage) { Q_UNUSED(errorMessage) - CoreConnectAuthDlg dlg(account, this); + CoreConnectAuthDlg dlg(account); *valid = (dlg.exec() == QDialog::Accepted); } @@ -1242,7 +1353,7 @@ void MainWin::userAuthenticationRequired(CoreAccount *account, bool *valid, cons void MainWin::handleNoSslInClient(bool *accepted) { QMessageBox box(QMessageBox::Warning, tr("Unencrypted Connection"), tr("Your client does not support SSL encryption"), - QMessageBox::Ignore|QMessageBox::Cancel, this); + QMessageBox::Ignore|QMessageBox::Cancel); box.setInformativeText(tr("Sensitive data, like passwords, will be transmitted unencrypted to your Quassel core.")); box.setDefaultButton(QMessageBox::Ignore); *accepted = box.exec() == QMessageBox::Ignore; @@ -1252,7 +1363,7 @@ void MainWin::handleNoSslInClient(bool *accepted) void MainWin::handleNoSslInCore(bool *accepted) { QMessageBox box(QMessageBox::Warning, tr("Unencrypted Connection"), tr("Your core does not support SSL encryption"), - QMessageBox::Ignore|QMessageBox::Cancel, this); + QMessageBox::Ignore|QMessageBox::Cancel); box.setInformativeText(tr("Sensitive data, like passwords, will be transmitted unencrypted to your Quassel core.")); box.setDefaultButton(QMessageBox::Ignore); *accepted = box.exec() == QMessageBox::Ignore; @@ -1271,7 +1382,7 @@ void MainWin::handleSslErrors(const QSslSocket *socket, bool *accepted, bool *pe QMessageBox box(QMessageBox::Warning, tr("Untrusted Security Certificate"), tr("The SSL certificate provided by the core at %1 is untrusted for the following reasons:").arg(socket->peerName()), - QMessageBox::Cancel, this); + QMessageBox::Cancel); box.setInformativeText(errorString); box.addButton(tr("Continue"), QMessageBox::AcceptRole); box.setDefaultButton(box.addButton(tr("Show Certificate"), QMessageBox::HelpRole)); @@ -1281,7 +1392,7 @@ void MainWin::handleSslErrors(const QSslSocket *socket, bool *accepted, bool *pe box.exec(); role = box.buttonRole(box.clickedButton()); if (role == QMessageBox::HelpRole) { - SslInfoDlg dlg(socket, this); + SslInfoDlg dlg(socket); dlg.exec(); } } @@ -1292,7 +1403,7 @@ void MainWin::handleSslErrors(const QSslSocket *socket, bool *accepted, bool *pe QMessageBox box2(QMessageBox::Warning, tr("Untrusted Security Certificate"), tr("Would you like to accept this certificate forever without being prompted?"), - 0, this); + 0); box2.setDefaultButton(box2.addButton(tr("Current Session Only"), QMessageBox::NoRole)); box2.addButton(tr("Forever"), QMessageBox::YesRole); box2.exec(); @@ -1311,7 +1422,7 @@ void MainWin::handleCoreConnectionError(const QString &error) void MainWin::showCoreConnectionDlg() { - CoreConnectDlg dlg(this); + CoreConnectDlg dlg; if (dlg.exec() == QDialog::Accepted) { AccountId accId = dlg.selectedAccount(); if (accId.isValid()) @@ -1320,33 +1431,57 @@ void MainWin::showCoreConnectionDlg() } -void MainWin::showCoreConfigWizard(const QVariantList &backends) +void MainWin::showCoreConfigWizard(const QVariantList &backends, const QVariantList &authenticators) { - CoreConfigWizard *wizard = new CoreConfigWizard(Client::coreConnection(), backends, this); + auto *wizard = new CoreConfigWizard(Client::coreConnection(), backends, authenticators, this); wizard->show(); } -void MainWin::showChannelList(NetworkId netId) +void MainWin::showChannelList(NetworkId netId, const QString &channelFilters, bool listImmediately) { - ChannelListDlg *channelListDlg = new ChannelListDlg(); - if (!netId.isValid()) { - QAction *action = qobject_cast(sender()); + auto *action = qobject_cast(sender()); if (action) netId = action->data().value(); + if (!netId.isValid()) { + // We still haven't found a valid network, probably no network selected, e.g. "/list" + // on the client homescreen when no networks are connected. + QMessageBox box(QMessageBox::Information, tr("No network selected"), + QString("%1").arg(tr("No network selected")), + QMessageBox::Ok); + box.setInformativeText(tr("Select a network before trying to view the channel list.")); + box.exec(); + return; + } } + auto *channelListDlg = new ChannelListDlg(this); channelListDlg->setAttribute(Qt::WA_DeleteOnClose); channelListDlg->setNetwork(netId); + if (!channelFilters.isEmpty()) { + channelListDlg->setChannelFilters(channelFilters); + } + if (listImmediately) { + channelListDlg->requestSearch(); + } channelListDlg->show(); } +void MainWin::showNetworkConfig(NetworkId netId) +{ + SettingsPageDlg dlg{new NetworksSettingsPage{}}; + if (netId.isValid()) + qobject_cast(dlg.currentPage())->bufferList_Open(netId); + dlg.exec(); +} + + void MainWin::showIgnoreList(QString newRule) { - SettingsPageDlg dlg(new IgnoreListSettingsPage(this), this); + SettingsPageDlg dlg{new IgnoreListSettingsPage{}}; // prepare config dialog for new rule if (!newRule.isEmpty()) qobject_cast(dlg.currentPage())->editIgnoreRule(newRule); @@ -1356,7 +1491,7 @@ void MainWin::showIgnoreList(QString newRule) void MainWin::showCoreInfoDlg() { - CoreInfoDlg(this).exec(); + CoreInfoDlg{}.exec(); } @@ -1364,10 +1499,10 @@ void MainWin::showAwayLog() { if (_awayLog) return; - AwayLogFilter *filter = new AwayLogFilter(Client::messageModel()); - _awayLog = new AwayLogView(filter, 0); + auto *filter = new AwayLogFilter(Client::messageModel()); + _awayLog = new AwayLogView(filter, nullptr); filter->setParent(_awayLog); - connect(_awayLog, SIGNAL(destroyed()), this, SLOT(awayLogDestroyed())); + connect(_awayLog, &QObject::destroyed, this, &MainWin::awayLogDestroyed); _awayLog->setAttribute(Qt::WA_DeleteOnClose); _awayLog->show(); } @@ -1375,13 +1510,13 @@ void MainWin::showAwayLog() void MainWin::awayLogDestroyed() { - _awayLog = 0; + _awayLog = nullptr; } void MainWin::showSettingsDlg() { - SettingsDlg *dlg = new SettingsDlg(); + auto *dlg = new SettingsDlg(); //Category: Interface dlg->registerSettingsPage(new AppearanceSettingsPage(dlg)); @@ -1396,6 +1531,7 @@ void MainWin::showSettingsDlg() dlg->registerSettingsPage(new SonnetSettingsPage(dlg)); #endif dlg->registerSettingsPage(new HighlightSettingsPage(dlg)); + dlg->registerSettingsPage(new CoreHighlightSettingsPage(dlg)); dlg->registerSettingsPage(new NotificationsSettingsPage(dlg)); dlg->registerSettingsPage(new BacklogSettingsPage(dlg)); @@ -1405,6 +1541,7 @@ void MainWin::showSettingsDlg() dlg->registerSettingsPage(new NetworksSettingsPage(dlg)); dlg->registerSettingsPage(new AliasesSettingsPage(dlg)); dlg->registerSettingsPage(new IgnoreListSettingsPage(dlg)); + // dlg->registerSettingsPage(new DccSettingsPage(dlg)); not ready yet // Category: Remote Cores if (Quassel::runMode() != Quassel::Monolithic) { @@ -1418,20 +1555,19 @@ void MainWin::showSettingsDlg() void MainWin::showAboutDlg() { - AboutDlg(this).exec(); + AboutDlg{}.exec(); } void MainWin::showShortcutsDlg() { #ifdef HAVE_KDE - KShortcutsDialog dlg(KShortcutsEditor::AllActions, KShortcutsEditor::LetterShortcutsDisallowed, this); + KShortcutsDialog dlg(KShortcutsEditor::AllActions, KShortcutsEditor::LetterShortcutsDisallowed); foreach(KActionCollection *coll, QtUi::actionCollections()) dlg.addCollection(coll, coll->property("Category").toString()); dlg.configure(true); #else - SettingsPageDlg dlg(new ShortcutsSettingsPage(QtUi::actionCollections(), this), this); - dlg.exec(); + SettingsPageDlg{new ShortcutsSettingsPage{QtUi::actionCollections()}}.exec(); #endif } @@ -1440,8 +1576,10 @@ void MainWin::showNewTransferDlg(const QUuid &transferId) { auto transfer = Client::transferManager()->transfer(transferId); if (transfer) { - ReceiveFileDlg *dlg = new ReceiveFileDlg(transfer, this); - dlg->show(); + if (transfer->status() == Transfer::Status::New) { + auto *dlg = new ReceiveFileDlg(transfer, this); + dlg->show(); + } } else { qWarning() << "Unknown transfer ID" << transferId; @@ -1508,7 +1646,7 @@ void MainWin::resizeEvent(QResizeEvent *event) void MainWin::closeEvent(QCloseEvent *event) { QtUiSettings s; - QtUiApplication *app = qobject_cast qApp; + auto *app = qobject_cast qApp; Q_ASSERT(app); // On OSX it can happen that the closeEvent occurs twice. (Especially if packaged with Frameworks) // This messes up MainWinState/MainWinHidden save/restore. @@ -1520,7 +1658,7 @@ void MainWin::closeEvent(QCloseEvent *event) else if(!_aboutToQuit) { _aboutToQuit = true; event->accept(); - quit(); + Quassel::instance()->quit(); } else { event->ignore(); @@ -1532,7 +1670,7 @@ void MainWin::messagesInserted(const QModelIndex &parent, int start, int end) { Q_UNUSED(parent); - bool hasFocus = QApplication::activeWindow() != 0; + bool hasFocus = QApplication::activeWindow() != nullptr; for (int i = start; i <= end; i++) { QModelIndex idx = Client::messageModel()->index(i, ChatLineModel::ContentsColumn); @@ -1594,13 +1732,13 @@ void MainWin::currentBufferChanged(BufferId buffer) void MainWin::clientNetworkCreated(NetworkId id) { const Network *net = Client::network(id); - QAction *act = new QAction(net->networkName(), this); + auto *act = new QAction(net->networkName(), this); act->setObjectName(QString("NetworkAction-%1").arg(id.toInt())); act->setData(QVariant::fromValue(id)); - connect(net, SIGNAL(updatedRemotely()), this, SLOT(clientNetworkUpdated())); - connect(act, SIGNAL(triggered()), this, SLOT(connectOrDisconnectFromNet())); + connect(net, &SyncableObject::updatedRemotely, this, &MainWin::clientNetworkUpdated); + connect(act, &QAction::triggered, this, &MainWin::connectOrDisconnectFromNet); - QAction *beforeAction = 0; + QAction *beforeAction = nullptr; foreach(QAction *action, _networksMenu->actions()) { if (!action->data().isValid()) // ignore stock actions continue; @@ -1615,11 +1753,11 @@ void MainWin::clientNetworkCreated(NetworkId id) void MainWin::clientNetworkUpdated() { - const Network *net = qobject_cast(sender()); + const auto *net = qobject_cast(sender()); if (!net) return; - QAction *action = findChild(QString("NetworkAction-%1").arg(net->networkId().toInt())); + auto *action = findChild(QString("NetworkAction-%1").arg(net->networkId().toInt())); if (!action) return; @@ -1627,7 +1765,7 @@ void MainWin::clientNetworkUpdated() switch (net->connectionState()) { case Network::Initialized: - action->setIcon(QIcon::fromTheme("network-connect")); + action->setIcon(icon::get("network-connect")); // if we have no currently selected buffer, jump to the first connecting statusbuffer if (!bufferWidget()->currentBuffer().isValid()) { QModelIndex idx = Client::networkModel()->networkIndex(net->networkId()); @@ -1638,17 +1776,17 @@ void MainWin::clientNetworkUpdated() } break; case Network::Disconnected: - action->setIcon(QIcon::fromTheme("network-disconnect")); + action->setIcon(icon::get("network-disconnect")); break; default: - action->setIcon(QIcon::fromTheme("network-wired")); + action->setIcon(icon::get("network-wired")); } } void MainWin::clientNetworkRemoved(NetworkId id) { - QAction *action = findChild(QString("NetworkAction-%1").arg(id.toInt())); + auto *action = findChild(QString("NetworkAction-%1").arg(id.toInt())); if (!action) return; @@ -1658,7 +1796,7 @@ void MainWin::clientNetworkRemoved(NetworkId id) void MainWin::connectOrDisconnectFromNet() { - QAction *act = qobject_cast(sender()); + auto *act = qobject_cast(sender()); if (!act) return; const Network *net = Client::network(act->data().value()); if (!net) return; @@ -1667,6 +1805,60 @@ void MainWin::connectOrDisconnectFromNet() } +void MainWin::on_inputFormatApplyColor_triggered() +{ + if (!_inputWidget) + return; + + _inputWidget->applyFormatActiveColor(); +} + + +void MainWin::on_inputFormatApplyColorFill_triggered() +{ + if (!_inputWidget) + return; + + _inputWidget->applyFormatActiveColorFill(); +} + + +void MainWin::on_inputFormatClear_triggered() +{ + if (!_inputWidget) + return; + + _inputWidget->clearFormat(); +} + + +void MainWin::on_inputFormatBold_triggered() +{ + if (!_inputWidget) + return; + + _inputWidget->toggleFormatBold(); +} + + +void MainWin::on_inputFormatItalic_triggered() +{ + if (!_inputWidget) + return; + + _inputWidget->toggleFormatItalic(); +} + + +void MainWin::on_inputFormatUnderline_triggered() +{ + if (!_inputWidget) + return; + + _inputWidget->toggleFormatUnderline(); +} + + void MainWin::on_jumpHotBuffer_triggered() { if (!_bufferHotList->rowCount()) @@ -1688,7 +1880,7 @@ void MainWin::on_bufferSearch_triggered() void MainWin::onJumpKey() { - QAction *action = qobject_cast(sender()); + auto *action = qobject_cast(sender()); if (!action || !Client::bufferModel()) return; int idx = action->property("Index").toInt(); @@ -1707,7 +1899,7 @@ void MainWin::onJumpKey() void MainWin::bindJumpKey() { - QAction *action = qobject_cast(sender()); + auto *action = qobject_cast(sender()); if (!action || !Client::bufferModel()) return; int idx = action->property("Index").toInt(); @@ -1719,7 +1911,7 @@ void MainWin::bindJumpKey() void MainWin::on_actionDebugNetworkModel_triggered() { - QTreeView *view = new QTreeView; + auto *view = new QTreeView; view->setAttribute(Qt::WA_DeleteOnClose); view->setWindowTitle("Debug NetworkModel View"); view->setModel(Client::networkModel()); @@ -1736,7 +1928,7 @@ void MainWin::on_actionDebugHotList_triggered() _bufferHotList->invalidate(); _bufferHotList->sort(0, Qt::DescendingOrder); - QTreeView *view = new QTreeView; + auto *view = new QTreeView; view->setAttribute(Qt::WA_DeleteOnClose); view->setModel(_bufferHotList); view->show(); @@ -1745,7 +1937,7 @@ void MainWin::on_actionDebugHotList_triggered() void MainWin::on_actionDebugBufferViewOverlay_triggered() { - DebugBufferViewOverlay *overlay = new DebugBufferViewOverlay(0); + auto *overlay = new DebugBufferViewOverlay(nullptr); overlay->setAttribute(Qt::WA_DeleteOnClose); overlay->show(); } @@ -1753,8 +1945,8 @@ void MainWin::on_actionDebugBufferViewOverlay_triggered() void MainWin::on_actionDebugMessageModel_triggered() { - QTableView *view = new QTableView(0); - DebugMessageModelFilter *filter = new DebugMessageModelFilter(view); + auto *view = new QTableView(nullptr); + auto *filter = new DebugMessageModelFilter(view); filter->setSourceModel(Client::messageModel()); view->setModel(filter); view->setAttribute(Qt::WA_DeleteOnClose, true); @@ -1766,10 +1958,15 @@ void MainWin::on_actionDebugMessageModel_triggered() void MainWin::on_actionDebugLog_triggered() { - DebugLogWidget *logWidget = new DebugLogWidget(0); - logWidget->show(); + auto dlg = new DebugLogDlg(this); // will be deleted on close + dlg->show(); } +void MainWin::on_actionShowResourceTree_triggered() +{ + auto dlg = new ResourceTreeDlg(this); // will be deleted on close + dlg->show(); +} void MainWin::showStatusBarMessage(const QString &message) {