Skip to content

Commit

Permalink
Allow using custom sort functions
Browse files Browse the repository at this point in the history
  • Loading branch information
hluk committed Oct 3, 2022
1 parent cca529a commit 2617745
Show file tree
Hide file tree
Showing 11 changed files with 100 additions and 2 deletions.
23 changes: 23 additions & 0 deletions docs/scripting-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1788,6 +1788,16 @@ Types
sel.invert()
sel.items();
Example - sort items alphabetically:

.. code-block:: js
var sel = ItemSelection().selectAll();
const texts = sel.itemsFormat(mimeText);
sel.sort(function(i,j){
return texts[i] < texts[j];
});
.. js:attribute:: tab

Tab name
Expand Down Expand Up @@ -1871,6 +1881,19 @@ Types
:returns: self
:rtype: ItemSelection

.. js:method:: sort(row)

Sort items with a comparison function.

The comparison function takes two arguments, indexes to the selection,
and returns true only if the item in the selection under the first index
should be sorted above the item under the second index.

Items will be reordered in the tab and in the selection object.

:returns: self
:rtype: ItemSelection

.. js:method:: copy()

Clone the selection object.
Expand Down
5 changes: 5 additions & 0 deletions src/gui/clipboardbrowser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1552,6 +1552,11 @@ void ClipboardBrowser::sortItems(const QModelIndexList &indexes)
m.sortItems(indexes, &alphaSort);
}

void ClipboardBrowser::sortItems(const QList<QPersistentModelIndex> &sorted)
{
m.sortItems(sorted);
}

void ClipboardBrowser::reverseItems(const QModelIndexList &indexes)
{
m.sortItems(indexes, &reverseSort);
Expand Down
2 changes: 2 additions & 0 deletions src/gui/clipboardbrowser.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
class ItemEditorWidget;
class ItemFactory;
class PersistentDisplayItem;
class QPersistentModelIndex;
class QProgressBar;
class QPushButton;

Expand All @@ -65,6 +66,7 @@ class ClipboardBrowser final : public QListView

/** Sort selected items. */
void sortItems(const QModelIndexList &indexes);
void sortItems(const QList<QPersistentModelIndex> &sorted);

/** Reverse order of selected items. */
void reverseItems(const QModelIndexList &indexes);
Expand Down
7 changes: 5 additions & 2 deletions src/item/clipboardmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,10 +219,13 @@ void ClipboardModel::sortItems(const QModelIndexList &indexList, CompareItems *c
{
QList<QPersistentModelIndex> list = validIndeces(indexList);
std::sort( list.begin(), list.end(), compare );
}

int targetRow = topMostRow(list);
void ClipboardModel::sortItems(const QList<QPersistentModelIndex> &sorted)
{
int targetRow = topMostRow(sorted);

for (const auto &ind : list) {
for (const auto &ind : sorted) {
if (ind.isValid()) {
const int sourceRow = ind.row();

Expand Down
1 change: 1 addition & 0 deletions src/item/clipboardmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ class ClipboardModel final : public QAbstractListModel
* Sort items in ascending order.
*/
void sortItems(const QModelIndexList &indexList, CompareItems *compare);
void sortItems(const QList<QPersistentModelIndex> &sorted);

/**
* Find item with given @a hash.
Expand Down
15 changes: 15 additions & 0 deletions src/scriptable/scriptableitemselection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,21 @@ QJSValue ScriptableItemSelection::move(int row)
return m_self;
}

QJSValue ScriptableItemSelection::sort(QJSValue compareFn)
{
const int size = m_proxy->selectionGetSize(m_id);
QVector<int> indexes;
indexes.reserve(size);
for (int i = 0; i < size; ++i)
indexes.append(i);

std::sort( indexes.begin(), indexes.end(), [&](int lhs, int rhs) {
return compareFn.call({lhs, rhs}).toBool();
} );
m_proxy->selectionSort(m_id, indexes);
return m_self;
}

void ScriptableItemSelection::init(const QJSValue &self, ScriptableProxy *proxy, const QString &currentTabName)
{
m_self = self;
Expand Down
2 changes: 2 additions & 0 deletions src/scriptable/scriptableitemselection.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ public slots:

QJSValue move(int row);

QJSValue sort(QJSValue compareFn);

private:
int m_id = -1;
QString m_tabName;
Expand Down
22 changes: 22 additions & 0 deletions src/scriptable/scriptableproxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1991,6 +1991,28 @@ void ScriptableProxy::selectionMove(int id, int row)
selection.browser->move(indexes, row);
}

void ScriptableProxy::selectionSort(int id, const QVector<int> &indexes)
{
INVOKE2(selectionSort, (id, indexes));

auto selection = m_selections.value(id);

QList<QPersistentModelIndex> sorted;
sorted.reserve( indexes.size() );
for (const int i : indexes) {
if (i < 0 || i >= selection.indexes.size())
continue;

const auto index = selection.indexes[i];
if ( index.isValid() )
sorted.append(index);
}
selection.indexes = sorted;

if ( !sorted.isEmpty() )
selection.browser->sortItems(sorted);
}

#ifdef HAS_TESTS
void ScriptableProxy::sendKeys(const QString &expectedWidgetName, const QString &keys, int delay)
{
Expand Down
1 change: 1 addition & 0 deletions src/scriptable/scriptableproxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ public slots:
QVariantList selectionGetItemsFormat(int id, const QString &format);
void selectionSetItemsFormat(int id, const QString &mime, const QVariant &value);
void selectionMove(int id, int row);
void selectionSort(int id, const QVector<int> &indexes);

#ifdef HAS_TESTS
void sendKeys(const QString &expectedWidgetName, const QString &keys, int delay);
Expand Down
23 changes: 23 additions & 0 deletions src/tests/tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2314,6 +2314,29 @@ void Tests::classItemSelectionByteArray()
<< "read(mimeText, 0)", "C");
}

void Tests::classItemSelectionSort()
{
const auto tab1 = testTab(1);
const Args args = Args("tab") << tab1 << "separator" << ",";
const QString outRows("ItemSelection(tab=\"" + tab1 + "\", rows=[%1])\n");
RUN("setCurrentTab" << tab1, "");

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

const auto script = R"(
var sel = ItemSelection().selectAll();
const texts = sel.itemsFormat(mimeText);
sel.sort(function(i,j){
return texts[i] < texts[j];
});
sel.str();
)";
RUN(args << script, outRows.arg("3,2,0,4,1"));
RUN(args << "read(0,1,2,3,4)", "1,2,3,4,5");
RUN(args << "size", "5\n");
}

void Tests::classSettings()
{
TemporaryFile configFile;
Expand Down
1 change: 1 addition & 0 deletions src/tests/tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ private slots:
void classItemSelection();
void classItemSelectionGetCurrent();
void classItemSelectionByteArray();
void classItemSelectionSort();
void classSettings();
void calledWithInstance();

Expand Down

0 comments on commit 2617745

Please sign in to comment.