[plasma/plasma-workspace] klipper: Klipper: Split the system tray menu between items and context menu
Jonathan Marten
null at kde.org
Sun Oct 16 18:05:41 BST 2022
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();
More information about the kde-doc-english
mailing list