Git commit b906f72d2a0d14a8081ba7bf9420441930412018 by Jonathan Marten. Committed on 16/10/2022 at 17:05. Pushed by marten into branch 'master'.
Klipper: Split the system tray menu between items and context menu As suggested a long time ago in the referenced bug and duplicates, but never implemented for the traditional Klipper. Makes the system tray popup smaller, especially if the user has configured a large number of history entries, and makes the traditional Klipper work in the same way as the Plasma applet: left click = history items, right click = context menu. Add icons to some actions Change text for action "show-on-mouse-pos" to reflect what it now does Change "KDE" -> "Plasma" in about text Eliminate redundant member variable KlipperPopup::m_nHistoryItems BUG:93649 I18N: GUI: M +27 -11 klipper/klipper.cpp M +6 -0 klipper/klipper.h M +13 -35 klipper/klipperpopup.cpp M +2 -24 klipper/klipperpopup.h M +1 -1 klipper/main.cpp M +1 -1 klipper/tray.cpp https://invent.kde.org/plasma/plasma-workspace/commit/b906f72d2a0d14a8081ba7bf9420441930412018 diff --git a/klipper/klipper.cpp b/klipper/klipper.cpp index e2ee6e2345..ee2fea2c16 100644 --- a/klipper/klipper.cpp +++ b/klipper/klipper.cpp @@ -25,8 +25,10 @@ #include <QSaveFile> #include <QtConcurrent> +#include <KAboutData> #include <KActionCollection> #include <KGlobalAccel> +#include <KHelpMenu> #include <KLocalizedString> #include <KMessageBox> #include <KNotification> @@ -140,7 +142,6 @@ Klipper::Klipper(QObject *parent, const KSharedConfigPtr &config, KlipperMode mo m_history = new History(this); m_popup = new KlipperPopup(m_history); m_popup->setWindowFlags(m_popup->windowFlags() | Qt::FramelessWindowHint); - m_popup->setShowHelp(m_mode == KlipperMode::Standalone); connect(m_history, &History::changed, this, &Klipper::slotHistoryChanged); connect(m_history, &History::changed, m_popup, &KlipperPopup::slotHistoryChanged); connect(m_history, &History::topIsUserSelectedSet, m_popup, &KlipperPopup::slotTopIsUserSelectedSet); @@ -192,8 +193,8 @@ Klipper::Klipper(QObject *parent, const KSharedConfigPtr &config, KlipperMode mo m_repeatAction = m_collection->addAction(QStringLiteral("repeat_action")); m_repeatAction->setText(i18nc("@action:inmenu", "Manually Invoke Action on Current Clipboard")); + m_repeatAction->setIcon(QIcon::fromTheme(QStringLiteral("open-menu-symbolic"))); KGlobalAccel::setGlobalShortcut(m_repeatAction, QKeySequence(Qt::META | Qt::CTRL | Qt::Key_R)); - connect(m_repeatAction, &QAction::triggered, this, &Klipper::slotRepeatAction); // add an edit-possibility @@ -208,6 +209,7 @@ Klipper::Klipper(QObject *parent, const KSharedConfigPtr &config, KlipperMode mo // add barcode for mobile phones m_showBarcodeAction = m_collection->addAction(QStringLiteral("show-barcode")); m_showBarcodeAction->setText(i18nc("@action:inmenu", "&Show Barcodeā¦")); + m_showBarcodeAction->setIcon(QIcon::fromTheme(QStringLiteral("view-barcode-qr"))); KGlobalAccel::setGlobalShortcut(m_showBarcodeAction, QKeySequence()); connect(m_showBarcodeAction, &QAction::triggered, this, [this]() { showBarcode(m_history->first()); @@ -216,16 +218,19 @@ Klipper::Klipper(QObject *parent, const KSharedConfigPtr &config, KlipperMode mo // Cycle through history m_cycleNextAction = m_collection->addAction(QStringLiteral("cycleNextAction")); m_cycleNextAction->setText(i18nc("@action:inmenu", "Next History Item")); + m_cycleNextAction->setIcon(QIcon::fromTheme(QStringLiteral("go-next"))); KGlobalAccel::setGlobalShortcut(m_cycleNextAction, QKeySequence()); connect(m_cycleNextAction, &QAction::triggered, this, &Klipper::slotCycleNext); m_cyclePrevAction = m_collection->addAction(QStringLiteral("cyclePrevAction")); m_cyclePrevAction->setText(i18nc("@action:inmenu", "Previous History Item")); + m_cyclePrevAction->setIcon(QIcon::fromTheme(QStringLiteral("go-previous"))); KGlobalAccel::setGlobalShortcut(m_cyclePrevAction, QKeySequence()); connect(m_cyclePrevAction, &QAction::triggered, this, &Klipper::slotCyclePrev); - // Action to show Klipper popup on mouse position + // Action to show items popup on mouse position m_showOnMousePos = m_collection->addAction(QStringLiteral("show-on-mouse-pos")); - m_showOnMousePos->setText(i18nc("@action:inmenu", "Open Klipper at Mouse Position")); + m_showOnMousePos->setText(i18nc("@action:inmenu", "Show Items at Mouse Position")); + m_showOnMousePos->setIcon(QIcon::fromTheme(QStringLiteral("view-list-text"))); KGlobalAccel::setGlobalShortcut(m_showOnMousePos, QKeySequence(Qt::META | Qt::Key_V)); connect(m_showOnMousePos, &QAction::triggered, this, &Klipper::slotPopupMenu); @@ -233,14 +238,25 @@ Klipper::Klipper(QObject *parent, const KSharedConfigPtr &config, KlipperMode mo connect(m_popup, &QMenu::aboutToShow, this, &Klipper::slotStartShowTimer); if (m_mode == KlipperMode::Standalone) { - m_popup->plugAction(m_toggleURLGrabAction); - m_popup->plugAction(m_clearHistoryAction); - m_popup->plugAction(m_configureAction); - m_popup->plugAction(m_repeatAction); - m_popup->plugAction(m_editAction); - m_popup->plugAction(m_showBarcodeAction); + // system tray popup menu + m_actionsPopup = new QMenu; + m_actionsPopup->addSection(QIcon::fromTheme(QStringLiteral("klipper")), + i18nc("%1 is application display name", "%1 - Clipboard Tool", QGuiApplication::applicationDisplayName())); + m_actionsPopup->addAction(m_toggleURLGrabAction); + m_actionsPopup->addAction(m_clearHistoryAction); + m_actionsPopup->addAction(m_configureAction); + m_actionsPopup->addAction(m_repeatAction); + m_actionsPopup->addAction(m_editAction); + m_actionsPopup->addAction(m_showBarcodeAction); + + m_actionsPopup->addSeparator(); + + QMenu *helpMenu = (new KHelpMenu(m_actionsPopup, KAboutData::applicationData(), false))->menu(); + helpMenu->setIcon(QIcon::fromTheme(QStringLiteral("help-contents"))); + m_actionsPopup->addMenu(helpMenu); + Q_ASSERT(m_quitAction); - m_popup->plugAction(m_quitAction); + m_actionsPopup->addAction(m_quitAction); } // session manager interaction diff --git a/klipper/klipper.h b/klipper/klipper.h index 306c55538b..614fd05391 100644 --- a/klipper/klipper.h +++ b/klipper/klipper.h @@ -90,6 +90,11 @@ public: void saveSettings() const; + QMenu *actionsPopup() const + { + return m_actionsPopup; + } + KlipperPopup *popup() { return m_popup; @@ -230,6 +235,7 @@ private: bool blockFetchingNewData(); QString cycleText() const; KActionCollection *m_collection; + QMenu *m_actionsPopup; KlipperMode m_mode; QTimer *m_saveFileTimer = nullptr; QPointer<KNotification> m_notification; diff --git a/klipper/klipperpopup.cpp b/klipper/klipperpopup.cpp index c7ca11117e..0f1d8849f4 100644 --- a/klipper/klipperpopup.cpp +++ b/klipper/klipperpopup.cpp @@ -25,6 +25,7 @@ namespace { +// Index 0 is the menu header, index 1 is the search widget. static const int TOP_HISTORY_ITEM_INDEX = 2; } @@ -58,12 +59,9 @@ kdbgstream &operator<<(kdbgstream &stream, const QKeyEvent &e) KlipperPopup::KlipperPopup(History *history) : m_dirty(true) , m_history(history) - , m_helpMenu(nullptr) , m_popupProxy(nullptr) , m_filterWidget(nullptr) , m_filterWidgetAction(nullptr) - , m_nHistoryItems(0) - , m_showHelp(true) , m_lastEvent(nullptr) { ensurePolished(); @@ -81,10 +79,6 @@ KlipperPopup::KlipperPopup(History *history) connect(this, &KlipperPopup::aboutToShow, this, &KlipperPopup::slotAboutToShow); } -KlipperPopup::~KlipperPopup() -{ -} - void KlipperPopup::slotAboutToShow() { if (m_filterWidget) { @@ -98,7 +92,7 @@ void KlipperPopup::slotAboutToShow() void KlipperPopup::ensureClean() { - // If the history is unchanged since last menu build, the is no reason + // If the history is unchanged since last menu build, there is no reason // to rebuild it, if (m_dirty) { rebuild(); @@ -107,7 +101,8 @@ void KlipperPopup::ensureClean() void KlipperPopup::buildFromScratch() { - addSection(QIcon::fromTheme(QStringLiteral("klipper")), i18n("Klipper - Clipboard Tool")); + addSection(QIcon::fromTheme(QStringLiteral("klipper")), + i18nc("%1 is application display name", "%1 - Clipboard Items", QGuiApplication::applicationDisplayName())); m_filterWidget = new KLineEdit(this); m_filterWidget->setFocusPolicy(Qt::NoFocus); @@ -116,18 +111,7 @@ void KlipperPopup::buildFromScratch() m_filterWidgetAction->setDefaultWidget(m_filterWidget); addAction(m_filterWidgetAction); - addSeparator(); - for (int i = 0; i < m_actions.count(); i++) { - if (i + 1 == m_actions.count() && m_showHelp) { - if (!m_helpMenu) { - m_helpMenu = new KHelpMenu(this, i18n("KDE cut & paste history utility"), false); - } - addMenu(m_helpMenu->menu())->setIcon(QIcon::fromTheme(QStringLiteral("help-contents"))); - addSeparator(); - } - - addAction(m_actions.at(i)); - } + Q_ASSERT(actions().count() == TOP_HISTORY_ITEM_INDEX); } void KlipperPopup::showStatus(const QString &errorText) @@ -142,9 +126,7 @@ void KlipperPopup::showStatus(const QString &errorText) } else { // there is an error palette.setColor(m_filterWidget->foregroundRole(), colorScheme.foreground(KColorScheme::NegativeText).color()); palette.setColor(m_filterWidget->backgroundRole(), colorScheme.background(KColorScheme::NegativeBackground).color()); - insertAction(actions().at(TOP_HISTORY_ITEM_INDEX), new QAction(errorText, this)); - - ++m_nHistoryItems; // account for the added error item + addAction(new QAction(errorText, this)); } m_filterWidget->setPalette(palette); @@ -155,13 +137,11 @@ void KlipperPopup::rebuild(const QString &filter) if (actions().isEmpty()) { buildFromScratch(); } else { - for (int i = 0; i < m_nHistoryItems; i++) { - Q_ASSERT(TOP_HISTORY_ITEM_INDEX < actions().count()); - + while (actions().count() > TOP_HISTORY_ITEM_INDEX) { // The old actions allocated by KlipperPopup::rebuild() // and PopupProxy::tryInsertItem() are deleted here when // the menu is rebuilt. - QAction *action = actions().at(TOP_HISTORY_ITEM_INDEX); + QAction *action = actions().last(); removeAction(action); action->deleteLater(); } @@ -185,10 +165,9 @@ void KlipperPopup::rebuild(const QString &filter) QString errorText; if (!filterexp.isValid()) { errorText = i18n("Invalid regular expression, %1", filterexp.errorString()); - m_nHistoryItems = 0; } else { - m_nHistoryItems = m_popupProxy->buildParent(TOP_HISTORY_ITEM_INDEX, filterexp); - if (m_nHistoryItems == 0) { + const int nHistoryItems = m_popupProxy->buildParent(TOP_HISTORY_ITEM_INDEX, filterexp); + if (nHistoryItems == 0) { if (m_history->empty()) { errorText = i18n("Clipboard is empty"); } else { @@ -209,19 +188,18 @@ void KlipperPopup::rebuild(const QString &filter) void KlipperPopup::slotTopIsUserSelectedSet() { - if (!m_dirty && m_nHistoryItems > 0 && history()->topIsUserSelected()) { + if (!m_dirty && actions().count() > TOP_HISTORY_ITEM_INDEX && history()->topIsUserSelected()) { QAction *topAction = actions().at(TOP_HISTORY_ITEM_INDEX); topAction->setCheckable(true); topAction->setChecked(true); } } -void KlipperPopup::plugAction(QAction *action) +void KlipperPopup::showEvent(QShowEvent *e) { - m_actions.append(action); + popup(QCursor::pos()); } -/* virtual */ void KlipperPopup::keyPressEvent(QKeyEvent *e) { // Most events are send down directly to the m_filterWidget. diff --git a/klipper/klipperpopup.h b/klipper/klipperpopup.h index 047c562aa0..be578bf1a2 100644 --- a/klipper/klipperpopup.h +++ b/klipper/klipperpopup.h @@ -13,7 +13,6 @@ class QAction; class QWidgetAction; class QKeyEvent; -class KHelpMenu; class KLineEdit; class PopupProxy; @@ -29,8 +28,7 @@ class KlipperPopup : public QMenu public: explicit KlipperPopup(History *history); - ~KlipperPopup() override; - void plugAction(QAction *action); + ~KlipperPopup() override = default; /** * Normally, the popupmenu is only rebuilt just before showing. @@ -48,10 +46,6 @@ public: return m_history; } - void setShowHelp(bool show) - { - m_showHelp = show; - } public Q_SLOTS: void slotHistoryChanged() { @@ -71,6 +65,7 @@ private: protected: void keyPressEvent(QKeyEvent *e) override; + void showEvent(QShowEvent *e) override; private: bool m_dirty : 1; // true if menu contents needs to be rebuild. @@ -80,16 +75,6 @@ private: */ History *m_history; - /** - * The help menu - */ - KHelpMenu *m_helpMenu; - - /** - * (unowned) actions to plug into the primary popup menu - */ - QList<QAction *> m_actions; - /** * Proxy helper object used to track history items */ @@ -105,13 +90,6 @@ private: */ QWidgetAction *m_filterWidgetAction; - /** - * The current number of history items in the clipboard - */ - int m_nHistoryItems; - - bool m_showHelp; - /** * The last event which was received. Used to avoid an infinite event loop */ diff --git a/klipper/main.cpp b/klipper/main.cpp index b58ba9e74e..1cd711caba 100644 --- a/klipper/main.cpp +++ b/klipper/main.cpp @@ -26,7 +26,7 @@ int main(int argc, char *argv[]) KAboutData aboutData(QStringLiteral("klipper"), i18n("Klipper"), QStringLiteral(KLIPPER_VERSION_STRING), - i18n("KDE cut & paste history utility"), + i18n("Plasma cut & paste history utility"), KAboutLicense::GPL, i18n("(c) 1998, Andrew Stanley-Jones\n" "1998-2002, Carsten Pfeiffer\n" diff --git a/klipper/tray.cpp b/klipper/tray.cpp index 174d0d18b0..8453ee3608 100644 --- a/klipper/tray.cpp +++ b/klipper/tray.cpp @@ -28,7 +28,7 @@ KlipperTray::KlipperTray() setStandardActionsEnabled(false); m_klipper = new Klipper(this, KSharedConfig::openConfig()); - setContextMenu(m_klipper->popup()); + setContextMenu(m_klipper->actionsPopup()); setAssociatedWidget(m_klipper->popup()); connect(m_klipper->history(), &History::changed, this, &KlipperTray::slotSetToolTipFromHistory); slotSetToolTipFromHistory();
