Skip to content

Commit

Permalink
Add editItem() for editing any format
Browse files Browse the repository at this point in the history
Fixes #2672
  • Loading branch information
hluk committed Apr 13, 2024
1 parent 496704b commit e51ff08
Show file tree
Hide file tree
Showing 14 changed files with 116 additions and 78 deletions.
8 changes: 7 additions & 1 deletion docs/scripting-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,13 @@ unlike in GUI, where row numbers start from 1 by default.

.. js:function:: edit([row|text] ...)

Edits items in current tab.
Edits items in the current tab.

Opens external editor if set, otherwise opens internal editor.

.. js:function:: editItem(row, [mimeType, [data]])

Edits specific format for the item.

Opens external editor if set, otherwise opens internal editor.

Expand Down
36 changes: 19 additions & 17 deletions src/gui/clipboardbrowser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,18 +425,18 @@ void ClipboardBrowser::setEditorWidget(ItemEditorWidget *editor, bool changeClip
setHorizontalScrollBarPolicy(scrollbarPolicy);
}

void ClipboardBrowser::editItem(const QModelIndex &index, bool editNotes, bool changeClipboard)
void ClipboardBrowser::editItem(
const QModelIndex &index, const QString &format, bool changeClipboard)
{
if (!index.isValid())
return;

ItemEditorWidget *editor = d.createCustomEditor(this, index, editNotes);
ItemEditorWidget *editor = d.createCustomEditor(this, index, format);
if (editor != nullptr && editor->isValid() ) {
setEditorWidget(editor, changeClipboard);
} else {
delete editor;
if (!editNotes)
openEditor(index);
openEditor(index, format);
}
}

Expand Down Expand Up @@ -1213,19 +1213,21 @@ void ClipboardBrowser::doItemsLayout()
bool ClipboardBrowser::openEditor()
{
const QModelIndexList selected = selectionModel()->selectedRows();
return (selected.size() == 1) ? openEditor( selected.first() )
: openEditor( selectedText().toUtf8() );
return (selected.size() == 1) ? openEditor( selected.first(), mimeText )
: openEditor( {}, mimeText, selectedText().toUtf8() );
}

bool ClipboardBrowser::openEditor(const QByteArray &textData, bool changeClipboard)
bool ClipboardBrowser::openEditor(
const QModelIndex &index, const QString &format, const QByteArray &content, bool changeClipboard)
{
if ( !isLoaded() )
return false;

if ( m_sharedData->editor.isEmpty() )
return false;

QObject *editor = new ItemEditor(textData, mimeText, m_sharedData->editor, this);
auto editor = new ItemEditor(content, format, m_sharedData->editor, this);
editor->setIndex(index);
if ( !startEditor(editor) )
return false;

Expand All @@ -1237,7 +1239,7 @@ bool ClipboardBrowser::openEditor(const QByteArray &textData, bool changeClipboa
return true;
}

bool ClipboardBrowser::openEditor(const QModelIndex &index)
bool ClipboardBrowser::openEditor(const QModelIndex &index, const QString &format)
{
if ( !isLoaded() )
return false;
Expand All @@ -1253,7 +1255,7 @@ bool ClipboardBrowser::openEditor(const QModelIndex &index)
if ( !m_sharedData->editor.trimmed().isEmpty() ) {
const QString text = getTextData(data);
if ( !text.isNull() ) {
auto itemEditor = new ItemEditor( text.toUtf8(), mimeText, m_sharedData->editor, this );
auto itemEditor = new ItemEditor( text.toUtf8(), format, m_sharedData->editor, this );
itemEditor->setIndex(index);
if ( startEditor(itemEditor) )
return true;
Expand All @@ -1272,7 +1274,7 @@ void ClipboardBrowser::editNotes()
scrollTo(ind, PositionAtTop);
emit requestShow(this);

editItem(ind, true);
editItem(ind, mimeItemNotes);
}

void ClipboardBrowser::itemModified(const QByteArray &bytes, const QString &mime, const QModelIndex &index)
Expand Down Expand Up @@ -1357,7 +1359,7 @@ void ClipboardBrowser::moveToClipboard(const QModelIndexList &indexes)
emit changeClipboard(data);
}

void ClipboardBrowser::editNew(const QString &text, bool changeClipboard)
void ClipboardBrowser::editNew(const QString &format, const QByteArray &content, bool changeClipboard)
{
if ( !isLoaded() )
return;
Expand All @@ -1366,11 +1368,11 @@ void ClipboardBrowser::editNew(const QString &text, bool changeClipboard)
filterItems(nullptr);

m_selectNewItems = true;
const bool added = add(text);
const bool added = add( createDataMap(format, content) );
m_selectNewItems = false;

if (added)
editItem(currentIndex(), false, changeClipboard);
editItem(currentIndex(), format, changeClipboard);
}

void ClipboardBrowser::keyPressEvent(QKeyEvent *event)
Expand Down Expand Up @@ -1532,7 +1534,7 @@ void ClipboardBrowser::editSelected()
QModelIndex ind = currentIndex();
if ( ind.isValid() ) {
emit requestShow(this);
editItem(ind);
editItem(ind, mimeText);
}
}
}
Expand Down Expand Up @@ -1797,9 +1799,9 @@ void ClipboardBrowser::setStoreItems(bool store)
::removeItems(m_tabName);
}

void ClipboardBrowser::editRow(int row)
void ClipboardBrowser::editRow(int row, const QString &format)
{
editItem( index(row) );
editItem( index(row), format );
}

void ClipboardBrowser::move(int key)
Expand Down
12 changes: 5 additions & 7 deletions src/gui/clipboardbrowser.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,9 @@ class ClipboardBrowser final : public QListView
/** Show only items matching the regular expression. */
void filterItems(const ItemFilterPtr &filter);
/** Open editor. */
bool openEditor(const QByteArray &textData, bool changeClipboard = false);
bool openEditor(const QModelIndex &index, const QString &format, const QByteArray &content, bool changeClipboard = false);
/** Open editor for an item. */
bool openEditor(const QModelIndex &index);
bool openEditor(const QModelIndex &index, const QString &format);

/** Set current item. */
void setCurrent(int row, bool keepSelection = false, bool setCurrentOnly = false);
Expand All @@ -156,12 +156,10 @@ class ClipboardBrowser final : public QListView
* Create and edit new item.
*/
void editNew(
const QString &text = QString(), //!< Text of new item.
bool changeClipboard = false //!< Change clipboard if item is modified.
);
const QString &format, const QByteArray &content = {}, bool changeClipboard = false);

/** Edit item in given @a row. */
void editRow(int row);
void editRow(int row, const QString &format);

void move(int key);

Expand Down Expand Up @@ -329,7 +327,7 @@ class ClipboardBrowser final : public QListView

void setEditorWidget(ItemEditorWidget *editor, bool changeClipboard = false);

void editItem(const QModelIndex &index, bool editNotes = false, bool changeClipboard = false);
void editItem(const QModelIndex &index, const QString &format, bool changeClipboard = false);

void updateEditorGeometry();

Expand Down
7 changes: 4 additions & 3 deletions src/gui/commandcompleterdocumentation.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ void addDocumentation(AddDocumentationCallback addDocumentation)
addDocumentation("insert", "insert(row, text|Item...)", "Inserts new items to current tab.");
addDocumentation("remove", "remove(row, ...)", "Removes items in current tab.");
addDocumentation("move", "move(row)", "Moves selected items to given row in same tab.");
addDocumentation("edit", "edit([row|text] ...)", "Edits items in current tab.");
addDocumentation("edit", "edit([row|text] ...)", "Edits items in the current tab.");
addDocumentation("editItem", "editItem(row, [mimeType, [data]])", "Edits specific format for the item.");
addDocumentation("read", "read([mimeType])", "Same as `clipboard()`.");
addDocumentation("read", "read(mimeType, row, ...) -> `ByteArray`", "Returns concatenated data from items, or clipboard if row is negative.");
addDocumentation("write", "write(row, mimeType, data, [mimeType, data]...)", "Inserts new item to current tab.");
Expand Down Expand Up @@ -175,8 +176,8 @@ void addDocumentation(AddDocumentationCallback addDocumentation)
addDocumentation("onItemsAdded", "onItemsAdded()", "Called when items are added to a tab.");
addDocumentation("onItemsRemoved", "onItemsRemoved()", "Called when items are being removed from a tab.");
addDocumentation("onItemsChanged", "onItemsChanged()", "Called when data in items change.");
addDocumentation("onTabSelected", "onTabSelected()", "Called when another tab is open.");
addDocumentation("onItemsLoaded", "onItemsLoaded()", "Called when items a loaded to a tab.");
addDocumentation("onTabSelected", "onTabSelected()", "Called when another tab is opened.");
addDocumentation("onItemsLoaded", "onItemsLoaded()", "Called when all items are loaded into a tab.");
addDocumentation("ByteArray", "ByteArray", "Wrapper for QByteArray Qt class.");
addDocumentation("File", "File", "Wrapper for QFile Qt class.");
addDocumentation("Dir", "Dir", "Wrapper for QDir Qt class.");
Expand Down
3 changes: 1 addition & 2 deletions src/gui/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
#include "gui/icons.h"
#include "gui/logdialog.h"
#include "gui/notification.h"
#include "gui/notificationbutton.h"
#include "gui/notificationdaemon.h"
#include "gui/tabdialog.h"
#include "gui/tabicons.h"
Expand Down Expand Up @@ -3813,7 +3812,7 @@ void MainWindow::editNewItem()
showWindow();
if ( !c->isInternalEditorOpen() ) {
c->setFocus();
c->editNew();
c->editNew(mimeText);
}
}

Expand Down
33 changes: 14 additions & 19 deletions src/item/itemdelegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,33 +230,28 @@ void ItemDelegate::updateItemSize(const QModelIndex &index, QSize itemWidgetSize
}

ItemEditorWidget *ItemDelegate::createCustomEditor(
QWidget *parent, const QModelIndex &index, bool editNotes)
QWidget *parent, const QModelIndex &index, const QString &format)
{
bool hasHtml = false;
QString text;
if (editNotes) {
text = index.data(contentType::notes).toString();
} else {
const QVariantMap data = m_sharedData->itemFactory->data(index);
text = getTextData(data, mimeHtml);
if (text.isEmpty()) {
text = getTextData(data);
if (text.isNull())
return nullptr;
} else {
hasHtml = true;
}
}
// Refuse editing non-text data
if ( format != mimeItemNotes && !format.startsWith(QLatin1String("text/")) )
return nullptr;

const QVariantMap data = m_sharedData->itemFactory->data(index);
if ( format != mimeItemNotes && !data.contains(format) )
return nullptr;

auto editorParent = new QWidget(parent);
auto editor = new ItemEditorWidget(index, editNotes, editorParent);
auto editor = new ItemEditorWidget(index, format, editorParent);

connect(editor, &QObject::destroyed, editorParent, &QObject::deleteLater);

if (hasHtml) {
editor->setHtml(text);
// Prefer editing rich text
if ( format == mimeText && data.contains(mimeHtml) ) {
const QString html = getTextData(data, mimeHtml);
editor->setHtml(html);
sanitizeTextDocument(editor->document());
} else {
const QString text = getTextData(data, format);
editor->setPlainText(text);
}

Expand Down
4 changes: 2 additions & 2 deletions src/item/itemdelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ class ItemDelegate final : public QItemDelegate
void setItemSizes(int maxWidth, int idealWidth);

/** Create internal item editor widget. */
ItemEditorWidget *createCustomEditor(QWidget *parent, const QModelIndex &index,
bool editNotes);
ItemEditorWidget *createCustomEditor(
QWidget *parent, const QModelIndex &index, const QString &format);

/**
* Highlight matched text with current search expression, font and color.
Expand Down
10 changes: 5 additions & 5 deletions src/item/itemeditorwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ QAction *addMenuItem(const MenuItem &menuItem, QToolBar *toolBar, ItemEditorWidg

} // namespace

ItemEditorWidget::ItemEditorWidget(const QModelIndex &index, bool editNotes, QWidget *parent)
ItemEditorWidget::ItemEditorWidget(const QModelIndex &index, const QString &format, QWidget *parent)
: QTextEdit(parent)
, m_index(index)
, m_saveOnReturnKey(false)
, m_editNotes(editNotes)
, m_format(format)
{
setFrameShape(QFrame::NoFrame);
setFocusPolicy(Qt::StrongFocus);
Expand Down Expand Up @@ -84,12 +84,12 @@ void ItemEditorWidget::setSaveOnReturnKey(bool enabled)
QVariantMap ItemEditorWidget::data() const
{
QVariantMap data;
if (m_editNotes) {
setTextData( &data, toPlainText(), mimeItemNotes );
} else {
if (m_format == mimeText) {
setTextData( &data, toPlainText(), mimeText );
if ( containsRichText(*document()) )
setTextData( &data, toHtml(), mimeHtml );
} else {
setTextData( &data, toPlainText(), m_format );
}
return data;
}
Expand Down
4 changes: 2 additions & 2 deletions src/item/itemeditorwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class ItemEditorWidget final : public QTextEdit
{
Q_OBJECT
public:
ItemEditorWidget(const QModelIndex &index, bool editNotes, QWidget *parent = nullptr);
ItemEditorWidget(const QModelIndex &index, const QString &format, QWidget *parent = nullptr);

bool isValid() const;

Expand Down Expand Up @@ -77,7 +77,7 @@ class ItemEditorWidget final : public QTextEdit

QPersistentModelIndex m_index;
bool m_saveOnReturnKey;
bool m_editNotes;
QString m_format;
ItemFilterPtr m_filter;
};

Expand Down
44 changes: 37 additions & 7 deletions src/scriptable/scriptable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1138,36 +1138,66 @@ void Scriptable::edit()
m_skipArguments = -1;

QJSValue value;
QString text;
QByteArray content;
int row = -1;

const int len = argumentCount();
for ( int i = 0; i < len; ++i ) {
value = argument(i);
if (i > 0)
text.append(m_inputSeparator);
content.append(m_inputSeparator.toUtf8());
if ( toInt(value, &row) ) {
const QByteArray bytes = row >= 0 ? m_proxy->browserItemData(m_tabName, row, mimeText)
: getClipboardData(mimeText);
text.append( getTextData(bytes) );
content.append(bytes);
} else {
text.append( toString(value) );
content.append( toByteArray(value) );
}
}

bool changeClipboard = row < 0;

if ( !m_proxy->browserOpenEditor(m_tabName, fromString(text), changeClipboard) ) {
if ( !m_proxy->browserOpenEditor(m_tabName, row, mimeText, content, changeClipboard) ) {
m_proxy->showBrowser(m_tabName);
if (len == 1 && row >= 0) {
m_proxy->browserSetCurrent(m_tabName, row);
m_proxy->browserEditRow(m_tabName, row);
m_proxy->browserEditRow(m_tabName, row, mimeText);
} else {
m_proxy->browserEditNew(m_tabName, text, changeClipboard);
m_proxy->browserEditNew(m_tabName, mimeText, content, changeClipboard);
}
}
}

QJSValue Scriptable::editItem()
{
m_skipArguments = 3;

int row;
if ( !toInt(argument(0), &row) ) {
return throwError(argumentError());
}

const auto format = arg(1, mimeText);
const bool changeClipboard = row < 0;
const QByteArray content = argumentCount() > 2
? makeByteArray( argument(2) )
: ( row >= 0
? m_proxy->browserItemData(m_tabName, row, format)
: getClipboardData(format));

if ( !m_proxy->browserOpenEditor(m_tabName, row, format, content, changeClipboard) ) {
m_proxy->showBrowser(m_tabName);
if (row >= 0) {
m_proxy->browserSetCurrent(m_tabName, row);
m_proxy->browserEditRow(m_tabName, row, format);
} else {
m_proxy->browserEditNew(m_tabName, format, content, changeClipboard);
}
}

return {};
}

QJSValue Scriptable::read()
{
m_skipArguments = -1;
Expand Down
1 change: 1 addition & 0 deletions src/scriptable/scriptable.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ public slots:
void insert();
QJSValue remove();
void edit();
QJSValue editItem();
QJSValue move();

QJSValue read();
Expand Down

0 comments on commit e51ff08

Please sign in to comment.