Kirigami-addons

actionsmodel.cpp
1// SPDX-FileCopyrightText: 2021 Waqar Ahmed <waqar.17a@gmail.com>
2// SPDX-License-Identifier: LGPL-2.0-or-later
3
4#include "actionsmodel_p.h"
5
6#include <KLocalizedString>
7
8#include <QAction>
9
10#include <unordered_set>
11
12KCommandBarModel::KCommandBarModel(QObject *parent)
13 : QAbstractTableModel(parent)
14{
15}
16
17void fillRows(QList<KCommandBarModel::Item> &rows, const QString &title, const QList<QAction *> &actions, std::unordered_set<QAction *> &uniqueActions)
18{
19 for (const auto &action : actions) {
20 // We don't want disabled actions
21 if (!action->isEnabled()) {
22 continue;
23 }
24
25 if (uniqueActions.insert(action).second) {
26 rows.push_back(KCommandBarModel::Item{title, action, -1});
27 }
28 }
29}
30
31void KCommandBarModel::refresh(const QList<ActionGroup> &actionGroups)
32{
33 QSet<QString> groupNames;
34 int totalActions = std::accumulate(actionGroups.begin(), actionGroups.end(), 0, [&groupNames](int a, const ActionGroup &ag) {
35 groupNames << ag.name;
36 return ag.actions.count() + a;
37 });
38 m_hasMultipleGroup = groupNames.count() > 1;
39
40 QList<Item> temp_rows;
41 std::unordered_set<QAction *> uniqueActions;
42 temp_rows.reserve(totalActions);
43 int actionGroupIdx = 0;
44 for (const auto &ag : actionGroups) {
45 const auto &agActions = ag.actions;
46 fillRows(temp_rows, ag.name, agActions, uniqueActions);
47
48 actionGroupIdx++;
49 }
50
51 /**
52 * For each action in last triggered actions,
53 * - Find it in the actions
54 * - Use the score variable to set its score
55 *
56 * Items in m_lastTriggered are stored in descending order
57 * by their usage i.e., the first item in the vector is the most
58 * recently invoked action.
59 *
60 * Here we traverse them in reverse order, i.e., from least recent to
61 * most recent and then assign a score to them in a way that most recent
62 * ends up having the highest score. Thus when proxy model does the sorting
63 * later, most recent item will end up on the top
64 */
65 int score = 0;
66 std::for_each(m_lastTriggered.crbegin(), m_lastTriggered.crend(), [&score, &temp_rows](const QString &act) {
67 auto it = std::find_if(temp_rows.begin(), temp_rows.end(), [act](const KCommandBarModel::Item &i) {
68 return i.action->text() == act;
69 });
70 if (it != temp_rows.end()) {
71 it->score = score++;
72 }
73 });
74
75 beginResetModel();
76 m_rows = std::move(temp_rows);
77 endResetModel();
78}
79
80QVariant KCommandBarModel::data(const QModelIndex &index, int role) const
81{
82 if (!index.isValid()) {
83 return {};
84 }
85
86 const auto &entry = m_rows[index.row()];
87 const int col = index.column();
88
89 switch (role) {
90 case Qt::DisplayRole:
91 case DisplayNameRole:
92 if (col == 0) {
93 QString actionText = KLocalizedString::removeAcceleratorMarker(entry.action->text());
94 if (m_hasMultipleGroup) {
95 const QString groupName = KLocalizedString::removeAcceleratorMarker(entry.groupName);
96 return QString(groupName + QStringLiteral(": ") + actionText);
97 } else {
98 return actionText;
99 }
100 } else {
101 return entry.action->shortcut().toString(QKeySequence::NativeText);
102 }
103 case ShortcutRole:
104 return entry.action->shortcut().toString(QKeySequence::NativeText);
106 if (col == 0) {
107 return entry.action->icon().name();
108 }
109 break;
111 if (col == 0) {
112 return Qt::AlignLeft;
113 } else {
114 return Qt::AlignRight;
115 }
116 case Qt::UserRole: {
117 return QVariant::fromValue(entry.action);
118 }
119 case Role::Score:
120 return entry.score;
121 }
122
123 return {};
124}
125
126void KCommandBarModel::actionTriggered(const QString &name)
127{
128 if (m_lastTriggered.size() == 6) {
129 m_lastTriggered.pop_back();
130 }
131 m_lastTriggered.push_front(name);
132}
133
134QStringList KCommandBarModel::lastUsedActions() const
135{
136 return m_lastTriggered;
137}
138
139void KCommandBarModel::setLastUsedActions(const QStringList &actionNames)
140{
141 m_lastTriggered = actionNames;
142
143 while (m_lastTriggered.size() > 6) {
144 m_lastTriggered.pop_back();
145 }
146}
147
148QHash<int, QByteArray> KCommandBarModel::roleNames() const
149{
150 auto roles = QAbstractTableModel::roleNames();
151 roles[Qt::UserRole] = QByteArrayLiteral("qaction");
152 roles[Score] = QByteArrayLiteral("score");
153 roles[ShortcutRole] = QByteArrayLiteral("shortcut");
154 roles[DisplayNameRole] = QByteArrayLiteral("displayName");
155 return roles;
156}
157
158#include "moc_actionsmodel_p.cpp"
static QString removeAcceleratorMarker(const QString &label)
virtual QHash< int, QByteArray > roleNames() const const
iterator begin()
iterator end()
void push_back(parameter_type value)
void reserve(qsizetype size)
int column() const const
bool isValid() const const
int row() const const
qsizetype count() const const
AlignLeft
DisplayRole
QVariant fromValue(T &&value)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Oct 11 2024 12:10:34 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.