From: Manuel Nickschas Date: Tue, 18 Sep 2018 21:37:02 +0000 (+0200) Subject: modernize: Migrate action-related things to PMF connects X-Git-Tag: test-travis-01~126 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=f9efdde7f3a6004af8f834c409cfa6ae1d877692 modernize: Migrate action-related things to PMF connects In our quest to get rid of the deprecated use of slots, refactor Action and ActionCollection to require pointer-to-member-function connects. Ensure nobody accidentally still uses SLOT through a static assertion. Add a convenience function to ActionCollection for adding lists of actions. While we're at it, also rework ActionCollection's optional KDE Frameworks support to simplify things. Adapt the rest of the code accordingly. --- diff --git a/src/qtui/awaylogview.cpp b/src/qtui/awaylogview.cpp index 4ff1adc3..4a6bacc2 100644 --- a/src/qtui/awaylogview.cpp +++ b/src/qtui/awaylogview.cpp @@ -44,13 +44,13 @@ void AwayLogView::addActionsToMenu(QMenu *menu, const QPointF &pos) if (scene()->columnByScenePos(pos) == ChatLineModel::SenderColumn) { menu->addSeparator(); - auto *showNetworkAction = new Action(tr("Show Network Name"), menu, this, SLOT(showFieldsChanged(bool))); + auto *showNetworkAction = new Action(tr("Show Network Name"), menu, this, &AwayLogView::showFieldsChanged); showNetworkAction->setCheckable(true); showNetworkAction->setChecked(filter()->showFields() & ChatMonitorFilter::NetworkField); showNetworkAction->setData(ChatMonitorFilter::NetworkField); menu->addAction(showNetworkAction); - auto *showBufferAction = new Action(tr("Show Buffer Name"), menu, this, SLOT(showFieldsChanged(bool))); + auto *showBufferAction = new Action(tr("Show Buffer Name"), menu, this, &AwayLogView::showFieldsChanged); showBufferAction->setCheckable(true); showBufferAction->setChecked(filter()->showFields() & ChatMonitorFilter::BufferField); showBufferAction->setData(ChatMonitorFilter::BufferField); diff --git a/src/qtui/bufferwidget.cpp b/src/qtui/bufferwidget.cpp index cd93228b..41e98a51 100644 --- a/src/qtui/bufferwidget.cpp +++ b/src/qtui/bufferwidget.cpp @@ -74,29 +74,14 @@ BufferWidget::BufferWidget(QWidget *parent) this, &BufferWidget::scrollToHighlight); ActionCollection *coll = QtUi::actionCollection(); - - auto *zoomInChatview = coll->add("ZoomInChatView", this, SLOT(zoomIn())); - zoomInChatview->setText(tr("Zoom In")); - zoomInChatview->setIcon(icon::get("zoom-in")); - zoomInChatview->setShortcut(QKeySequence::ZoomIn); - - auto *zoomOutChatview = coll->add("ZoomOutChatView", this, SLOT(zoomOut())); - zoomOutChatview->setIcon(icon::get("zoom-out")); - zoomOutChatview->setText(tr("Zoom Out")); - zoomOutChatview->setShortcut(QKeySequence::ZoomOut); - - auto *zoomOriginalChatview = coll->add("ZoomOriginalChatView", this, SLOT(zoomOriginal())); - zoomOriginalChatview->setIcon(icon::get("zoom-original")); - zoomOriginalChatview->setText(tr("Actual Size")); - //zoomOriginalChatview->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_0)); // used for RTS switching - - auto *setMarkerLine = coll->add("SetMarkerLineToBottom", this, SLOT(setMarkerLine())); - setMarkerLine->setText(tr("Set Marker Line")); - setMarkerLine->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_R)); - - auto *jumpToMarkerLine = QtUi::actionCollection("Navigation")->add("JumpToMarkerLine", this, SLOT(jumpToMarkerLine())); - jumpToMarkerLine->setText(tr("Go to Marker Line")); - jumpToMarkerLine->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_K)); + coll->addActions({ + {"ZoomInChatView", new Action{icon::get("zoom-in"), tr("Zoom In"), coll, this, &BufferWidget::zoomIn, QKeySequence::ZoomIn}}, + {"ZoomOutChatView", new Action{icon::get("zoom-out"), tr("Zoom Out"), coll, this, &BufferWidget::zoomOut, QKeySequence::ZoomOut}}, + {"ZoomOriginalChatView", new Action{icon::get("zoom-original"), tr("Actual Size"), coll, this, &BufferWidget::zoomOriginal}}, + {"SetMarkerLineToBottom", new Action{tr("Set Marker Line"), coll, this, [this]() { setMarkerLine(); }, QKeySequence(Qt::CTRL + Qt::Key_R)}} + }); + coll = QtUi::actionCollection("Navigation"); + coll->addAction("JumpToMarkerLine", new Action{tr("Go to Marker Line"), coll, this, [this]() { jumpToMarkerLine(); }, QKeySequence(Qt::CTRL + Qt::Key_K)}); ChatViewSettings s; s.initAndNotify("AutoMarkerLine", this, SLOT(setAutoMarkerLine(QVariant)), true); diff --git a/src/qtui/chatitem.cpp b/src/qtui/chatitem.cpp index d94a2a91..8063a972 100644 --- a/src/qtui/chatitem.cpp +++ b/src/qtui/chatitem.cpp @@ -872,7 +872,7 @@ void ContentsChatItem::addActionsToMenu(QMenu *menu, const QPointF &pos) case Clickable::Url: { privateData()->activeClickable = click; - auto action = new Action{icon::get("edit-copy"), tr("Copy Link Address"), menu, &_actionProxy, SLOT(copyLinkToClipboard())}; + auto action = new Action{icon::get("edit-copy"), tr("Copy Link Address"), menu, &_actionProxy, &ActionProxy::copyLinkToClipboard}; action->setData(QVariant::fromValue(this)); menu->addAction(action); break; diff --git a/src/qtui/chatmonitorview.cpp b/src/qtui/chatmonitorview.cpp index a2740c64..07facb59 100644 --- a/src/qtui/chatmonitorview.cpp +++ b/src/qtui/chatmonitorview.cpp @@ -55,7 +55,7 @@ void ChatMonitorView::addActionsToMenu(QMenu *menu, const QPointF &pos) { ChatView::addActionsToMenu(menu, pos); menu->addSeparator(); - auto showOwnNicksAction = new Action(tr("Show Own Messages"), menu, _filter, SLOT(setShowOwnMessages(bool))); + auto showOwnNicksAction = new Action(tr("Show Own Messages"), menu, _filter, &ChatMonitorFilter::setShowOwnMessages); showOwnNicksAction->setCheckable(true); showOwnNicksAction->setChecked(_filter->showOwnMessages()); menu->addAction(showOwnNicksAction); @@ -63,13 +63,13 @@ void ChatMonitorView::addActionsToMenu(QMenu *menu, const QPointF &pos) if (scene()->columnByScenePos(pos) == ChatLineModel::SenderColumn) { menu->addSeparator(); - auto showNetworkAction = new Action(tr("Show Network Name"), menu, this, SLOT(showFieldsChanged(bool))); + auto showNetworkAction = new Action(tr("Show Network Name"), menu, this, &ChatMonitorView::showFieldsChanged); showNetworkAction->setCheckable(true); showNetworkAction->setChecked(_filter->showFields() & ChatMonitorFilter::NetworkField); showNetworkAction->setData(ChatMonitorFilter::NetworkField); menu->addAction(showNetworkAction); - auto showBufferAction = new Action(tr("Show Buffer Name"), menu, this, SLOT(showFieldsChanged(bool))); + auto showBufferAction = new Action(tr("Show Buffer Name"), menu, this, &ChatMonitorView::showFieldsChanged); showBufferAction->setCheckable(true); showBufferAction->setChecked(_filter->showFields() & ChatMonitorFilter::BufferField); showBufferAction->setData(ChatMonitorFilter::BufferField); @@ -77,7 +77,7 @@ void ChatMonitorView::addActionsToMenu(QMenu *menu, const QPointF &pos) } menu->addSeparator(); - menu->addAction(new Action(icon::get("configure"), tr("Configure..."), menu, this, SLOT(showSettingsPage()))); + menu->addAction(new Action(icon::get("configure"), tr("Configure..."), menu, this, &ChatMonitorView::showSettingsPage)); } diff --git a/src/qtui/chatmonitorview.h b/src/qtui/chatmonitorview.h index 21f84488..05c6e4ed 100644 --- a/src/qtui/chatmonitorview.h +++ b/src/qtui/chatmonitorview.h @@ -32,12 +32,13 @@ class ChatMonitorView : public ChatView public: ChatMonitorView(ChatMonitorFilter *filter, QWidget *parent); + void showFieldsChanged(bool checked); + protected: void addActionsToMenu(QMenu *menu, const QPointF &pos) override; void mouseDoubleClickEvent(QMouseEvent *event) override; private slots: - void showFieldsChanged(bool checked); void showSettingsPage(); virtual void coreConnectionStateChanged(bool connected); diff --git a/src/qtui/chatscene.cpp b/src/qtui/chatscene.cpp index 80e24a60..67d14253 100644 --- a/src/qtui/chatscene.cpp +++ b/src/qtui/chatscene.cpp @@ -828,8 +828,7 @@ void ChatScene::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) // If we have text selected, insert the Copy Selection as first item if (isPosOverSelection(pos)) { QAction *sep = menu.insertSeparator(menu.actions().first()); - QAction *act = new Action(icon::get("edit-copy"), tr("Copy Selection"), &menu, this, - SLOT(selectionToClipboard()), QKeySequence::Copy); + QAction *act = new Action(icon::get("edit-copy"), tr("Copy Selection"), &menu, this, [this]() { selectionToClipboard(); }, QKeySequence::Copy); menu.insertAction(sep, act); QString searchSelectionText = selection(); @@ -837,7 +836,7 @@ void ChatScene::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) searchSelectionText = searchSelectionText.left(_webSearchSelectionTextMaxVisible).append(QString::fromUtf8("…")); searchSelectionText = tr("Search '%1'").arg(searchSelectionText); - QAction *webSearchAction = new Action(icon::get("edit-find"), searchSelectionText, &menu, this, SLOT(webSearchOnSelection())); + QAction *webSearchAction = new Action(icon::get("edit-find"), searchSelectionText, &menu, this, &ChatScene::webSearchOnSelection); menu.insertAction(sep, webSearchAction); } @@ -847,7 +846,7 @@ void ChatScene::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) // show column reset action if columns have been resized in this session or there is at least one very narrow column if ((_firstColHandlePos != _defaultFirstColHandlePos) || (_secondColHandlePos != _defaultSecondColHandlePos) || (_firstColHandlePos <= 10) || (_secondColHandlePos - _firstColHandlePos <= 10)) - menu.addAction(new Action(tr("Reset Column Widths"), &menu, this, SLOT(resetColumnWidths()), 0)); + menu.addAction(new Action(tr("Reset Column Widths"), &menu, this, &ChatScene::resetColumnWidths)); menu.exec(event->screenPos()); } diff --git a/src/qtui/chatviewsearchbar.cpp b/src/qtui/chatviewsearchbar.cpp index 18b0b438..d7e0cfc3 100644 --- a/src/qtui/chatviewsearchbar.cpp +++ b/src/qtui/chatviewsearchbar.cpp @@ -43,9 +43,10 @@ ChatViewSearchBar::ChatViewSearchBar(QWidget *parent) QAction *toggleSearchBar = coll->action("ToggleSearchBar"); connect(toggleSearchBar, &QAction::toggled, this, &QWidget::setVisible); - auto *hideSearchBar = coll->add("HideSearchBar", toggleSearchBar, SLOT(setChecked(bool))); - hideSearchBar->setShortcutConfigurable(false); + auto *hideSearchBar = new Action{{}, this, toggleSearchBar, &QAction::setChecked}; hideSearchBar->setShortcut(Qt::Key_Escape); + hideSearchBar->setShortcutConfigurable(false); + coll->addAction("HideSearchBar", hideSearchBar); connect(ui.hideButton, &QAbstractButton::clicked, toggleSearchBar, &QAction::toggle); connect(ui.searchEditLine, &QLineEdit::textChanged, this, &ChatViewSearchBar::delaySearch); diff --git a/src/qtui/inputwidget.cpp b/src/qtui/inputwidget.cpp index 891501e8..3c566737 100644 --- a/src/qtui/inputwidget.cpp +++ b/src/qtui/inputwidget.cpp @@ -144,11 +144,7 @@ InputWidget::InputWidget(QWidget *parent) setMultiLineEnabled(s.value("EnableMultiLine", true)); ActionCollection *coll = QtUi::actionCollection(); - - auto *activateInputline = coll->add("FocusInputLine"); - connect(activateInputline, &QAction::triggered, this, selectOverload<>(&QWidget::setFocus)); - activateInputline->setText(tr("Focus Input Line")); - activateInputline->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_L)); + coll->addAction("FocusInputLine", new Action{tr("Focus Input Line"), coll, this, selectOverload<>(&QWidget::setFocus), QKeySequence(Qt::CTRL + Qt::Key_L)}); connect(inputLine(), &MultiLineEdit::textEntered, this, &InputWidget::onTextEntered, Qt::QueuedConnection); // make sure the line is already reset, bug #984 connect(inputLine(), &QTextEdit::currentCharFormatChanged, this, &InputWidget::currentCharFormatChanged); diff --git a/src/qtui/mainwin.cpp b/src/qtui/mainwin.cpp index 48bbcce9..727e1f38 100644 --- a/src/qtui/mainwin.cpp +++ b/src/qtui/mainwin.cpp @@ -29,6 +29,7 @@ #include #ifdef HAVE_KF5 +# include # include # include # include @@ -368,137 +369,108 @@ void MainWin::updateIcon() void MainWin::setupActions() { + QAction *action{nullptr}; ActionCollection *coll = QtUi::actionCollection("General", tr("General")); + // File - coll->addAction("ConnectCore", new Action(icon::get("connect-quassel"), tr("&Connect to Core..."), coll, - this, SLOT(showCoreConnectionDlg()))); - coll->addAction("DisconnectCore", new Action(icon::get("disconnect-quassel"), tr("&Disconnect from Core"), coll, - Client::instance(), SLOT(disconnectFromCore()))); - coll->addAction("ChangePassword", new Action(icon::get("dialog-password"), tr("Change &Password..."), coll, - this, SLOT(showPasswordChangeDlg()))); - coll->addAction("CoreInfo", new Action(icon::get("help-about"), tr("Core &Info..."), coll, - this, SLOT(showCoreInfoDlg()))); - coll->addAction("ConfigureNetworks", new Action(icon::get("configure"), tr("Configure &Networks..."), coll, - this, SLOT(on_actionConfigureNetworks_triggered()))); - // QKeySequence::Quit was added in Qt 4.6, and could be used instead. However, that key - // sequence is empty by default on Windows, which would remove Ctrl-Q to quit. It may be best - // to just keep it this way. - // - // See https://doc.qt.io/qt-5/qkeysequence.html - coll->addAction("Quit", new Action(icon::get("application-exit"), tr("&Quit"), coll, - Quassel::instance(), 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, &QAction::toggled, this, &MainWin::on_actionLockLayout_toggled); + coll->addAction("ConfigureBufferViews", new Action(tr("&Configure Chat Lists..."), coll, this, &MainWin::on_actionConfigureViews_triggered)); - coll->addAction("ToggleSearchBar", new Action(icon::get("edit-find"), tr("Show &Search Bar"), coll, - nullptr, nullptr, QKeySequence::Find))->setCheckable(true); - coll->addAction("ShowAwayLog", new Action(tr("Show Away Log"), coll, - this, SLOT(showAwayLog()))); - coll->addAction("ToggleMenuBar", new Action(icon::get("show-menu"), tr("Show &Menubar"), coll, - nullptr, nullptr))->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, - nullptr, nullptr))->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(icon::get("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(icon::get("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(icon::get("configure"), tr("&Configure Quassel..."), coll, - this, SLOT(showSettingsDlg())); - configureQuasselAct->setMenuRole(QAction::PreferencesRole); -#else - QAction *configureQuasselAct = new Action(icon::get("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(icon::get("quassel"), 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(icon::get("tools-report-bug"), tr("Debug &NetworkModel"), coll, - this, SLOT(on_actionDebugNetworkModel_triggered()))); - coll->addAction("DebugBufferViewOverlay", new Action(icon::get("tools-report-bug"), tr("Debug &BufferViewOverlay"), coll, - this, SLOT(on_actionDebugBufferViewOverlay_triggered()))); - coll->addAction("DebugMessageModel", new Action(icon::get("tools-report-bug"), tr("Debug &MessageModel"), coll, - this, SLOT(on_actionDebugMessageModel_triggered()))); - coll->addAction("DebugHotList", new Action(icon::get("tools-report-bug"), tr("Debug &HotList"), coll, - this, SLOT(on_actionDebugHotList_triggered()))); - coll->addAction("DebugLog", new Action(icon::get("tools-report-bug"), tr("Debug &Log"), coll, - this, SLOT(on_actionDebugLog_triggered()))); - coll->addAction("ShowResourceTree", new Action(icon::get("tools-report-bug"), tr("Show &Resource Tree"), coll, - this, SLOT(on_actionShowResourceTree_triggered()))); - coll->addAction("ReloadStyle", new Action(icon::get("view-refresh"), tr("Reload Stylesheet"), coll, - QtUi::style(), SLOT(reload()), QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_R))); - - 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->addAction("FormatApplyColor", new Action( - icon::get("format-text-color"), tr("Apply foreground color"), coll, - this, SLOT(on_inputFormatApplyColor_triggered()), - QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_G))); - - coll->addAction("FormatApplyColorFill", new Action( - icon::get("format-fill-color"), tr("Apply background color"), coll, - this, SLOT(on_inputFormatApplyColorFill_triggered()), - QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_B))); - - coll->addAction("FormatClear", new Action( - icon::get("edit-clear"), tr("Clear formatting"), coll, - this, SLOT(on_inputFormatClear_triggered()), - QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_C))); - - coll->addAction("FormatBold", new Action( - icon::get("format-text-bold"), tr("Toggle bold"), coll, - this, SLOT(on_inputFormatBold_triggered()), - QKeySequence::Bold)); - - coll->addAction("FormatItalic", new Action( - icon::get("format-text-italic"), tr("Toggle italics"), coll, - this, SLOT(on_inputFormatItalic_triggered()), - QKeySequence::Italic)); - - coll->addAction("FormatUnderline", new Action( - icon::get("format-text-underline"), tr("Toggle underline"), coll, - this, SLOT(on_inputFormatUnderline_triggered()), QKeySequence::Underline)); + 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 @@ -509,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(icon::get("go-next-view"), tr("Activate Next Chat List"), coll, - this, SLOT(nextBufferView()), QKeySequence(QKeySequence::Forward))); + this, &MainWin::nextBufferView, QKeySequence(QKeySequence::Forward))); coll->addAction("PreviousBufferView", new Action(icon::get("go-previous-view"), tr("Activate Previous Chat List"), coll, - this, SLOT(previousBufferView()), QKeySequence::Back)); + this, &MainWin::previousBufferView, QKeySequence::Back)); coll->addAction("NextBuffer", new Action(icon::get("go-down"), tr("Go to Next Chat"), coll, - this, SLOT(nextBuffer()), QKeySequence(Qt::ALT + Qt::Key_Down))); + 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, SLOT(previousBuffer()), QKeySequence(Qt::ALT + Qt::Key_Up))); + this, &MainWin::previousBuffer, QKeySequence(Qt::ALT + Qt::Key_Up))); } @@ -605,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 @@ -619,7 +596,11 @@ 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(icon::get("tools-report-bug"), tr("Debug")); diff --git a/src/qtui/mainwin.h b/src/qtui/mainwin.h index bb2972db..2352646d 100644 --- a/src/qtui/mainwin.h +++ b/src/qtui/mainwin.h @@ -266,7 +266,7 @@ private: ChatMonitorView *_chatMonitorView; TopicWidget *_topicWidget; - QAction *_fullScreenAction; + QAction *_fullScreenAction{nullptr}; QMenu *_fileMenu, *_networksMenu, *_viewMenu, *_bufferViewsMenu, *_settingsMenu, *_helpMenu, *_helpDebugMenu; QMenu *_toolbarMenu; QToolBar *_mainToolBar, *_chatViewToolBar, *_nickToolBar; diff --git a/src/qtui/systemtray.cpp b/src/qtui/systemtray.cpp index 250895aa..c85e7bf2 100644 --- a/src/qtui/systemtray.cpp +++ b/src/qtui/systemtray.cpp @@ -40,7 +40,7 @@ SystemTray::SystemTray(QWidget *parent) UiStyleSettings{}.initAndNotify("Icons/InvertTray", this, SLOT(invertTrayIconChanged(QVariant)), false); ActionCollection *coll = QtUi::actionCollection("General"); - _minimizeRestoreAction = new Action(tr("&Minimize"), this, this, SLOT(minimizeRestore())); + _minimizeRestoreAction = new Action(tr("&Minimize"), this, this, &SystemTray::minimizeRestore); _trayMenu = new QMenu(associatedWidget()); _trayMenu->setTitle("Quassel IRC"); diff --git a/src/uisupport/action.cpp b/src/uisupport/action.cpp index a61339a3..2d54af3c 100644 --- a/src/uisupport/action.cpp +++ b/src/uisupport/action.cpp @@ -27,38 +27,23 @@ Action::Action(QObject *parent) : QWidgetAction(parent) { - init(); + setProperty("isShortcutConfigurable", true); + connect(this, &QAction::triggered, this, &Action::slotTriggered); } -Action::Action(const QString &text, QObject *parent, const QObject *receiver, const char *slot, const QKeySequence &shortcut) - : QWidgetAction(parent) +Action::Action(const QString &text, QObject *parent, const QKeySequence &shortcut) + : Action(parent) { - init(); setText(text); setShortcut(shortcut); - if (receiver && slot) - connect(this, SIGNAL(triggered()), receiver, slot); } -Action::Action(const QIcon &icon, const QString &text, QObject *parent, const QObject *receiver, const char *slot, const QKeySequence &shortcut) - : QWidgetAction(parent) +Action::Action(const QIcon &icon, const QString &text, QObject *parent, const QKeySequence &shortcut) + : Action(text, parent, shortcut) { - init(); setIcon(icon); - setText(text); - setShortcut(shortcut); - if (receiver && slot) - connect(this, SIGNAL(triggered()), receiver, slot); -} - - -void Action::init() -{ - connect(this, &QAction::triggered, this, &Action::slotTriggered); - - setProperty("isShortcutConfigurable", true); } diff --git a/src/uisupport/action.h b/src/uisupport/action.h index 8b580a28..6fa2ae24 100644 --- a/src/uisupport/action.h +++ b/src/uisupport/action.h @@ -24,9 +24,13 @@ #include "uisupport-export.h" +#include + #include #include +#include "util.h" + /// A specialized QWidgetAction, enhanced by some KDE features /** This declares/implements a subset of KAction's API (notably we've left out global shortcuts * for now), which should make it easy to plug in KDE support later on. @@ -47,8 +51,25 @@ public : Q_DECLARE_FLAGS(ShortcutTypes, ShortcutType) explicit Action(QObject *parent); - Action(const QString &text, QObject *parent, const QObject *receiver = nullptr, const char *slot = nullptr, const QKeySequence &shortcut = 0); - Action(const QIcon &icon, const QString &text, QObject *parent, const QObject *receiver = nullptr, const char *slot = nullptr, const QKeySequence &shortcut = 0); + Action(const QString &text, QObject *parent, const QKeySequence &shortcut = 0); + Action(const QIcon &icon, const QString &text, QObject *parent, const QKeySequence &shortcut = 0); + + template + Action(const QString &text, QObject *parent, const Receiver *receiver, Slot slot, const QKeySequence &shortcut = 0) + : Action(text, parent, shortcut) + { + static_assert(!std::is_same::value, "Old-style connects not supported"); + + setShortcut(shortcut); + connect(this, &QAction::triggered, receiver, slot); + } + + template + Action(const QIcon &icon, const QString &text, QObject *parent, const Receiver *receiver, Slot slot, const QKeySequence &shortcut = 0) + : Action(text, parent, receiver, slot, shortcut) + { + setIcon(icon); + } QKeySequence shortcut(ShortcutTypes types = ActiveShortcut) const; void setShortcut(const QShortcut &shortcut, ShortcutTypes type = ShortcutTypes(ActiveShortcut | DefaultShortcut)); @@ -60,9 +81,6 @@ public : signals: void triggered(Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers); -private: - void init(); - private slots: void slotTriggered(); }; diff --git a/src/uisupport/actioncollection.cpp b/src/uisupport/actioncollection.cpp index 0ba65ba4..af5c9241 100644 --- a/src/uisupport/actioncollection.cpp +++ b/src/uisupport/actioncollection.cpp @@ -20,8 +20,6 @@ * Parts of this implementation are based on KDE's KActionCollection. * ***************************************************************************/ -#ifndef HAVE_KDE - #include #include #include @@ -31,12 +29,27 @@ #include "action.h" #include "uisettings.h" -ActionCollection::ActionCollection(QObject *parent) : QObject(parent) +void ActionCollection::addActions(const std::vector> &actions) +{ + for (auto &&p : actions) { + addAction(p.first, p.second); + } +} + + +#ifndef HAVE_KDE + +int ActionCollection::count() const { - _connectTriggered = _connectHovered = false; + return actions().count(); } +bool ActionCollection::isEmpty() const +{ + return actions().count(); +} + void ActionCollection::clear() { _actionByName.clear(); @@ -56,25 +69,6 @@ QList ActionCollection::actions() const return _actions; } - -Action *ActionCollection::addAction(const QString &name, Action *action) -{ - QAction *act = addAction(name, static_cast(action)); - Q_UNUSED(act); - Q_ASSERT(act == action); - return action; -} - - -Action *ActionCollection::addAction(const QString &name, const QObject *receiver, const char *member) -{ - auto *a = new Action(this); - if (receiver && member) - connect(a, SIGNAL(triggered(bool)), receiver, member); - return addAction(name, a); -} - - QAction *ActionCollection::addAction(const QString &name, QAction *action) { if (!action) @@ -288,5 +282,4 @@ bool ActionCollection::unlistAction(QAction *action) return true; } - #endif /* HAVE_KDE */ diff --git a/src/uisupport/actioncollection.h b/src/uisupport/actioncollection.h index fa1ef24c..71e01955 100644 --- a/src/uisupport/actioncollection.h +++ b/src/uisupport/actioncollection.h @@ -24,7 +24,12 @@ #include "uisupport-export.h" -#ifndef HAVE_KDE +#include +#include + +#ifdef HAVE_KDE +# include +#endif #include #include @@ -37,13 +42,24 @@ class QWidget; class Action; class QAction; -class UISUPPORT_EXPORT ActionCollection : public QObject +#ifdef HAVE_KDE +using ActionCollectionParent = KActionCollection; +#else +using ActionCollectionParent = QObject; +#endif + +class UISUPPORT_EXPORT ActionCollection : public ActionCollectionParent { Q_OBJECT public: - explicit ActionCollection(QObject *parent); + using ActionCollectionParent::ActionCollectionParent; + + // Convenience function that takes a list of Actions + void addActions(const std::vector> &actions); +// Everything else is defined in KActionCollection +#ifndef HAVE_KDE /// Clears the entire action collection, deleting all actions. void clear(); @@ -65,31 +81,17 @@ public: void readSettings(); void writeSettings() const; - inline int count() const; - inline bool isEmpty() const; + int count() const; + bool isEmpty() const; QAction *action(int index) const; QAction *action(const QString &name) const; QList actions() const; QAction *addAction(const QString &name, QAction *action); - Action *addAction(const QString &name, Action *action); - Action *addAction(const QString &name, const QObject *receiver = nullptr, const char *member = nullptr); void removeAction(QAction *action); QAction *takeAction(QAction *action); - /// Create new action under the given name, add it to the collection and connect its triggered(bool) signal to the specified receiver. - template - ActionType *add(const QString &name, const QObject *receiver = nullptr, const char *member = nullptr) - { - auto *a = new ActionType(this); - if (receiver && member) - connect(a, SIGNAL(triggered(bool)), receiver, member); - addAction(name, a); - return a; - } - - signals: void inserted(QAction *action); void actionHovered(QAction *action); @@ -111,23 +113,8 @@ private: QList _actions; QList _associatedWidgets; - bool _connectHovered; - bool _connectTriggered; -}; - - -int ActionCollection::count() const { return actions().count(); } -bool ActionCollection::isEmpty() const { return actions().count(); } - -#else /* HAVE_KDE */ -# include - -class ActionCollection : public KActionCollection -{ - Q_OBJECT - -public: - explicit ActionCollection(QObject *parent) : KActionCollection(parent) {}; -}; + bool _connectHovered{false}; + bool _connectTriggered{false}; #endif /* HAVE_KDE */ +}; diff --git a/src/uisupport/tabcompleter.cpp b/src/uisupport/tabcompleter.cpp index ae37fd96..cd8209b0 100644 --- a/src/uisupport/tabcompleter.cpp +++ b/src/uisupport/tabcompleter.cpp @@ -46,11 +46,10 @@ TabCompleter::TabCompleter(MultiLineEdit *_lineEdit) _nickSuffix(": ") { // This Action just serves as a container for the custom shortcut and isn't actually handled; - // apparently, using tab as an Action shortcut in an input widget is unreliable on some platforms (e.g. OS/2) + // apparently, using tab as an Action shortcut in an input widget is unreliable on some platforms (e.g. OS/2) _lineEdit->installEventFilter(this); ActionCollection *coll = GraphicalUi::actionCollection("General"); - QAction *a = coll->addAction("TabCompletionKey", new Action(tr("Tab completion"), coll, - this, SLOT(onTabCompletionKey()), QKeySequence(Qt::Key_Tab))); + QAction *a = coll->addAction("TabCompletionKey", new Action(tr("Tab completion"), coll, this, &TabCompleter::onTabCompletionKey, QKeySequence(Qt::Key_Tab))); a->setEnabled(false); // avoid catching the shortcut }