Skip to content

Commit

Permalink
Apply display commands to tray menu items too
Browse files Browse the repository at this point in the history
In the display command, the format stored in `mimeDisplayItemInMenu`
indicates whether the display item data are related to a menu item
instead of an item list.

Fixes hluk/copyq-commands#79
  • Loading branch information
hluk committed Dec 9, 2023
1 parent 6ebfa1b commit 8d80c90
Show file tree
Hide file tree
Showing 11 changed files with 106 additions and 21 deletions.
5 changes: 5 additions & 0 deletions docs/scripting-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2161,6 +2161,11 @@ These MIME types values are assigned to global variables prefixed with
Valid only in automatic commands.

.. js:data:: mimeDisplayItemInMenu

Set to "1" for display commands if the item data is related to a menu item
instead of an item list.

Selected Items
--------------

Expand Down
1 change: 1 addition & 0 deletions src/common/mimetypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ const QLatin1String mimeHidden(COPYQ_MIME_PREFIX "hidden");
const QLatin1String mimeShortcut(COPYQ_MIME_PREFIX "shortcut");
const QLatin1String mimeColor(COPYQ_MIME_PREFIX "color");
const QLatin1String mimeOutputTab(COPYQ_MIME_PREFIX "output-tab");
const QLatin1String mimeDisplayItemInMenu(COPYQ_MIME_PREFIX "display-item-in-menu");
1 change: 1 addition & 0 deletions src/common/mimetypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ extern const QLatin1String mimeHidden;
extern const QLatin1String mimeShortcut;
extern const QLatin1String mimeColor;
extern const QLatin1String mimeOutputTab;
extern const QLatin1String mimeDisplayItemInMenu;
10 changes: 8 additions & 2 deletions src/gui/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1836,8 +1836,14 @@ void MainWindow::addMenuItems(TrayMenu *menu, ClipboardBrowserPlaceholder *place
const QModelIndex index = c->model()->index(i, 0);
if ( !searchText.isEmpty() && !menuItemMatches(index, searchText) )
continue;
const QVariantMap data = index.data(contentType::data).toMap();
menu->addClipboardItemAction(data, m_options.trayImages);
QVariantMap data = index.data(contentType::data).toMap();
QAction *act = menu->addClipboardItemAction(data, m_options.trayImages);
if ( !m_displayCommands.isEmpty() ) {
data.insert(mimeCurrentTab, c->tabName());
data.insert(mimeDisplayItemInMenu, QByteArrayLiteral("1"));
PersistentDisplayItem item(act, data);
onItemWidgetCreated(item);
}
++itemCount;
}
}
Expand Down
43 changes: 30 additions & 13 deletions src/gui/traymenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

namespace {

const char propertyTextFormat[] = "CopyQ_text_format";

const QIcon iconClipboard() { return getIcon("clipboard", IconPaste); }

bool canActivate(const QAction &action)
Expand Down Expand Up @@ -65,7 +67,29 @@ TrayMenu::TrayMenu(QWidget *parent)
setAttribute(Qt::WA_InputMethodEnabled);
}

void TrayMenu::addClipboardItemAction(const QVariantMap &data, bool showImages)
void TrayMenu::updateTextFromData(QAction *act, const QVariantMap &data)
{
const QString format = act->property(propertyTextFormat).toString();
const QString label = textLabelForData( data, act->font(), format, true );
act->setText(label);
}

bool TrayMenu::updateIconFromData(QAction *act, const QVariantMap &data)
{
if ( !act->parentWidget() )
return false;

const QString icon = data.value(mimeIcon).toString();
const QString tag = data.value(COPYQ_MIME_PREFIX "item-tag").toString();
if ( icon.isEmpty() && tag.isEmpty() )
return false;

const QColor color = getDefaultIconColor(*act->parentWidget());
act->setIcon( iconFromFile(icon, tag, color) );
return true;
}

QAction *TrayMenu::addClipboardItemAction(const QVariantMap &data, bool showImages)
{
// Show search text at top of the menu.
if ( m_clipboardItemActionCount == 0 && m_searchText.isEmpty() )
Expand All @@ -86,15 +110,15 @@ void TrayMenu::addClipboardItemAction(const QVariantMap &data, bool showImages)
format = tr("&%1. %2",
"Key hint (number shortcut) for items in tray menu (%1 is number, %2 is item label)")
.arg(rowNumber);
act->setProperty(propertyTextFormat, format);
}

m_clipboardItemActionCount++;

const QString label = textLabelForData( data, act->font(), format, true );
act->setText(label);
updateTextFromData(act, data);

// Menu item icon from image.
if (showImages) {
if (!updateIconFromData(act, data) && showImages) {
const QStringList formats = data.keys();
static const QRegularExpression reImage("^image/.*");
const int imageIndex = formats.indexOf(reImage);
Expand All @@ -117,16 +141,9 @@ void TrayMenu::addClipboardItemAction(const QVariantMap &data, bool showImages)
}
}

if ( act->icon().isNull() ) {
const QString icon = data.value(mimeIcon).toString();
if ( !icon.isEmpty() ) {
const QColor color = getDefaultIconColor(*this);
const QString tag = data.value(COPYQ_MIME_PREFIX "item-tag").toString();
act->setIcon( iconFromFile(icon, tag, color) );
}
}

connect(act, &QAction::triggered, this, &TrayMenu::onClipboardItemActionTriggered);

return act;
}

void TrayMenu::clearClipboardItems()
Expand Down
5 changes: 4 additions & 1 deletion src/gui/traymenu.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@ class TrayMenu final : public QMenu
public:
explicit TrayMenu(QWidget *parent = nullptr);

static void updateTextFromData(QAction *act, const QVariantMap &data);
static bool updateIconFromData(QAction *act, const QVariantMap &data);

/**
* Add clipboard item action with number key hint.
*
* Triggering this action emits clipboardItemActionTriggered() signal.
*/
void addClipboardItemAction(const QVariantMap &data, bool showImages);
QAction *addClipboardItemAction(const QVariantMap &data, bool showImages);

void clearClipboardItems();

Expand Down
25 changes: 20 additions & 5 deletions src/item/persistentdisplayitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

#include "persistentdisplayitem.h"

#include "gui/traymenu.h"
#include "item/itemdelegate.h"

#include <QAction>

PersistentDisplayItem::PersistentDisplayItem(ItemDelegate *delegate,
const QVariantMap &data,
QWidget *widget)
Expand All @@ -13,16 +16,28 @@ PersistentDisplayItem::PersistentDisplayItem(ItemDelegate *delegate,
{
}

bool PersistentDisplayItem::isValid()
PersistentDisplayItem::PersistentDisplayItem(QAction *action, const QVariantMap &data)
: m_data(data)
, m_action(action)
{
if ( m_widget.isNull() || m_delegate.isNull() )
return false;
}

return !m_delegate->invalidateHidden( m_widget.data() );
bool PersistentDisplayItem::isValid()
{
return !m_action.isNull() || (
!m_widget.isNull() && !m_delegate.isNull()
&& !m_delegate->invalidateHidden(m_widget.data()) );
}

void PersistentDisplayItem::setData(const QVariantMap &data)
{
if ( !data.isEmpty() && isValid() && m_delegate && data != m_data )
if ( data.isEmpty() || data == m_data )
return;

if ( !m_action.isNull() ) {
TrayMenu::updateTextFromData(m_action, data);
TrayMenu::updateIconFromData(m_action, data);
} else if ( !m_widget.isNull() && !m_delegate.isNull() ) {
m_delegate->updateWidget(m_widget, data);
}
}
4 changes: 4 additions & 0 deletions src/item/persistentdisplayitem.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <QVariantMap>

class ItemDelegate;
class QAction;
class QModelIndex;
class QWidget;
class QString;
Expand All @@ -26,6 +27,8 @@ class PersistentDisplayItem final
PersistentDisplayItem(
ItemDelegate *delegate, const QVariantMap &data, QWidget *widget);

PersistentDisplayItem(QAction *action, const QVariantMap &data);

/**
* Returns display data of the item.
*
Expand All @@ -48,6 +51,7 @@ class PersistentDisplayItem final
private:
QVariantMap m_data;
QPointer<QWidget> m_widget;
QPointer<QAction> m_action;
QPointer<ItemDelegate> m_delegate;
};

Expand Down
2 changes: 2 additions & 0 deletions src/scriptable/scriptable.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class Scriptable final : public QObject
Q_PROPERTY(QJSValue mimeShortcut READ getMimeShortcut CONSTANT)
Q_PROPERTY(QJSValue mimeColor READ getMimeColor CONSTANT)
Q_PROPERTY(QJSValue mimeOutputTab READ getMimeOutputTab CONSTANT)
Q_PROPERTY(QJSValue mimeDisplayItemInMenu READ getMimeDisplayItemInMenu CONSTANT)

Q_PROPERTY(QJSValue plugins READ getPlugins CONSTANT)

Expand Down Expand Up @@ -134,6 +135,7 @@ class Scriptable final : public QObject
QJSValue getMimeShortcut() const { return mimeShortcut; }
QJSValue getMimeColor() const { return mimeColor; }
QJSValue getMimeOutputTab() const { return mimeOutputTab; }
QJSValue getMimeDisplayItemInMenu() const { return mimeDisplayItemInMenu; }

QJSValue getPlugins();

Expand Down
30 changes: 30 additions & 0 deletions src/tests/tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3986,6 +3986,36 @@ void Tests::displayCommand()
.toUtf8() );
}

void Tests::displayCommandForMenu()
{
const auto tab = testTab(1);
const auto args = Args("tab") << tab << "separator" << ",";
const auto script = QString(R"(
setCommands([{
display: true,
cmd: 'copyq:'
+ 'currentTab = str(data(mimeCurrentTab));'
+ 'inMenu = str(data(mimeDisplayItemInMenu));'
+ 'if (inMenu != "1" || currentTab != "%1") abort();'
+ 'text = str(data(mimeText));'
+ 'setData(mimeText, "display:" + text);'
+ 'setData(mimeIcon, String.fromCharCode(0xF328));'
+ 'setData("application/x-copyq-item-tag", "TAG");'
+ 'tab(tab()[0]);'
+ 'old = str(read(0));'
+ 'add(old + "|" + text);'
}])
)").arg(tab);

RUN("config" << "tray_tab" << tab, tab + "\n");
RUN("config" << "tray_tab_is_current" << "false", "false\n");
RUN(script, "");

RUN(args << "add(1,2,3,4,5)", "");
RUN("menu", "");
WAIT_ON_OUTPUT("read(0)", "|5|4|3|2|1");
}

void Tests::synchronizeInternalCommands()
{
// Keep internal commands synced with the latest version
Expand Down
1 change: 1 addition & 0 deletions src/tests/tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ private slots:
void scriptCommandEndingWithComment();
void scriptCommandWithError();
void displayCommand();
void displayCommandForMenu();

void synchronizeInternalCommands();

Expand Down

0 comments on commit 8d80c90

Please sign in to comment.