1 // For license of this file, see <project-root-folder>/LICENSE.md.
2
3 #include "gui/toolbars/toolbareditor.h"
4
5 #include "gui/dialogs/formmain.h"
6 #include "gui/toolbars/basetoolbar.h"
7
8 #include <QKeyEvent>
9
ToolBarEditor(QWidget * parent)10 ToolBarEditor::ToolBarEditor(QWidget* parent)
11 : QWidget(parent), m_ui(new Ui::ToolBarEditor), m_toolBar(nullptr) {
12 m_ui->setupUi(this);
13
14 // Create connections.
15 connect(m_ui->m_btnInsertSeparator, &QToolButton::clicked, this, &ToolBarEditor::insertSeparator);
16 connect(m_ui->m_btnInsertSpacer, &QToolButton::clicked, this, &ToolBarEditor::insertSpacer);
17 connect(m_ui->m_btnAddSelectedAction, &QToolButton::clicked, this, &ToolBarEditor::addSelectedAction);
18 connect(m_ui->m_btnDeleteAllActions, &QToolButton::clicked, this, &ToolBarEditor::deleteAllActions);
19 connect(m_ui->m_btnDeleteSelectedAction, &QToolButton::clicked, this, &ToolBarEditor::deleteSelectedAction);
20 connect(m_ui->m_btnMoveActionUp, &QToolButton::clicked, this, &ToolBarEditor::moveActionUp);
21 connect(m_ui->m_btnMoveActionDown, &QToolButton::clicked, this, &ToolBarEditor::moveActionDown);
22 connect(m_ui->m_btnReset, &QToolButton::clicked, this, &ToolBarEditor::resetToolBar);
23 connect(m_ui->m_listAvailableActions, &QListWidget::itemSelectionChanged, this, &ToolBarEditor::updateActionsAvailability);
24 connect(m_ui->m_listActivatedActions, &QListWidget::itemSelectionChanged, this, &ToolBarEditor::updateActionsAvailability);
25 connect(m_ui->m_listActivatedActions, &QListWidget::itemDoubleClicked, this, &ToolBarEditor::deleteSelectedAction);
26 connect(m_ui->m_listAvailableActions, &QListWidget::itemDoubleClicked, this, &ToolBarEditor::addSelectedAction);
27 m_ui->m_listActivatedActions->installEventFilter(this);
28 m_ui->m_btnInsertSeparator->setIcon(qApp->icons()->fromTheme(QSL("insert-object")));
29 m_ui->m_btnInsertSpacer->setIcon(qApp->icons()->fromTheme(QSL("go-jump")));
30 m_ui->m_btnAddSelectedAction->setIcon(qApp->icons()->fromTheme(QSL("go-previous")));
31 m_ui->m_btnDeleteAllActions->setIcon(qApp->icons()->fromTheme(QSL("application-exit")));
32 m_ui->m_btnDeleteSelectedAction->setIcon(qApp->icons()->fromTheme(QSL("go-next")));
33 m_ui->m_btnMoveActionDown->setIcon(qApp->icons()->fromTheme(QSL("down")));
34 m_ui->m_btnMoveActionUp->setIcon(qApp->icons()->fromTheme(QSL("up")));
35 m_ui->m_btnReset->setIcon(qApp->icons()->fromTheme(QSL("reload")));
36 }
37
loadFromToolBar(BaseBar * tool_bar)38 void ToolBarEditor::loadFromToolBar(BaseBar* tool_bar) {
39 m_toolBar = tool_bar;
40
41 QList<QAction*> activated_actions = m_toolBar->activatedActions();
42 QList<QAction*> available_actions = m_toolBar->availableActions();
43
44 loadEditor(activated_actions, available_actions);
45 }
46
saveToolBar()47 void ToolBarEditor::saveToolBar() {
48 QStringList action_names;
49
50 for (int i = 0; i < m_ui->m_listActivatedActions->count(); i++) {
51 action_names.append(m_ui->m_listActivatedActions->item(i)->data(Qt::UserRole).toString());
52 }
53
54 m_toolBar->saveAndSetActions(action_names);
55 }
56
resetToolBar()57 void ToolBarEditor::resetToolBar() {
58 if (m_toolBar != nullptr) {
59 loadEditor(m_toolBar->convertActions(m_toolBar->defaultActions()), m_toolBar->availableActions());
60 emit setupChanged();
61 }
62 }
63
loadEditor(const QList<QAction * > & activated_actions,const QList<QAction * > & available_actions)64 void ToolBarEditor::loadEditor(const QList<QAction*>& activated_actions, const QList<QAction*>& available_actions) {
65 m_ui->m_listActivatedActions->clear();
66 m_ui->m_listAvailableActions->clear();
67
68 for (const QAction* action : activated_actions) {
69 QListWidgetItem* action_item = new QListWidgetItem(action->icon(),
70 action->text().replace('&', QL1S("")),
71 m_ui->m_listActivatedActions);
72
73 if (action->isSeparator()) {
74 action_item->setData(Qt::ItemDataRole::UserRole, SEPARATOR_ACTION_NAME);
75 action_item->setIcon(qApp->icons()->fromTheme(QSL("insert-object")));
76 action_item->setText(tr("Separator"));
77 action_item->setToolTip(tr("Separator"));
78 }
79 else if (action->property("type").isValid()) {
80 action_item->setData(Qt::ItemDataRole::UserRole, action->property("type").toString());
81 action_item->setText(action->property("name").toString());
82 action_item->setToolTip(action_item->text());
83 }
84 else {
85 action_item->setData(Qt::ItemDataRole::UserRole, action->objectName());
86 action_item->setToolTip(action->toolTip());
87 }
88 }
89
90 for (QAction* action : available_actions) {
91 if (!activated_actions.contains(action)) {
92 QListWidgetItem* action_item = new QListWidgetItem(action->icon(),
93 action->text().replace('&', QL1S("")),
94 m_ui->m_listAvailableActions);
95
96 if (action->isSeparator()) {
97 action_item->setData(Qt::ItemDataRole::UserRole, QSL(SEPARATOR_ACTION_NAME));
98 action_item->setText(tr("Separator"));
99 action_item->setToolTip(tr("Separator"));
100 action_item->setIcon(qApp->icons()->fromTheme(QSL("insert-object")));
101 }
102 else if (action->property("type").isValid()) {
103 action_item->setData(Qt::ItemDataRole::UserRole, action->property("type").toString());
104 action_item->setText(action->property("name").toString());
105 action_item->setToolTip(action_item->text());
106 }
107 else {
108 action_item->setData(Qt::ItemDataRole::UserRole, action->objectName());
109 action_item->setToolTip(action->toolTip());
110 }
111 }
112 }
113
114 m_ui->m_listAvailableActions->sortItems(Qt::SortOrder::AscendingOrder);
115 m_ui->m_listAvailableActions->setCurrentRow(m_ui->m_listAvailableActions->count() >= 0 ? 0 : -1);
116 m_ui->m_listActivatedActions->setCurrentRow(m_ui->m_listActivatedActions->count() >= 0 ? 0 : -1);
117 }
118
eventFilter(QObject * object,QEvent * event)119 bool ToolBarEditor::eventFilter(QObject* object, QEvent* event) {
120 if (object == m_ui->m_listActivatedActions) {
121 if (event->type() == QEvent::Type::KeyPress) {
122 const auto* key_event = static_cast<QKeyEvent*>(event);
123
124 if (key_event->key() == Qt::Key::Key_Delete) {
125 deleteSelectedAction();
126 return true;
127 }
128 else if (key_event->key() == Qt::Key::Key_Down &&
129 (key_event->modifiers() & Qt::KeyboardModifier::ControlModifier) == Qt::KeyboardModifier::ControlModifier) {
130 moveActionDown();
131 return true;
132 }
133 else if (key_event->key() == Qt::Key::Key_Up &&
134 (key_event->modifiers() & Qt::KeyboardModifier::ControlModifier) == Qt::KeyboardModifier::ControlModifier) {
135 moveActionUp();
136 return true;
137 }
138 }
139 }
140
141 return false;
142 }
143
updateActionsAvailability()144 void ToolBarEditor::updateActionsAvailability() {
145 m_ui->m_btnDeleteAllActions->setEnabled(m_ui->m_listActivatedActions->count() > 0);
146 m_ui->m_btnDeleteSelectedAction->setEnabled(m_ui->m_listActivatedActions->selectedItems().size() == 1);
147 m_ui->m_btnMoveActionUp->setEnabled(m_ui->m_listActivatedActions->selectedItems().size() == 1 &&
148 m_ui->m_listActivatedActions->currentRow() > 0);
149 m_ui->m_btnMoveActionDown->setEnabled(m_ui->m_listActivatedActions->selectedItems().size() == 1 &&
150 m_ui->m_listActivatedActions->currentRow() < m_ui->m_listActivatedActions->count() - 1);
151 m_ui->m_btnAddSelectedAction->setEnabled(m_ui->m_listAvailableActions->selectedItems().size() > 0);
152 }
153
insertSpacer()154 void ToolBarEditor::insertSpacer() {
155 const int current_row = m_ui->m_listActivatedActions->currentRow();
156 auto* item = new QListWidgetItem(tr("Toolbar spacer"));
157
158 item->setIcon(qApp->icons()->fromTheme(QSL("go-jump")));
159 item->setData(Qt::ItemDataRole::UserRole, SPACER_ACTION_NAME);
160 m_ui->m_listActivatedActions->insertItem(current_row + 1, item);
161 m_ui->m_listActivatedActions->setCurrentRow(current_row + 1);
162 emit setupChanged();
163 }
164
insertSeparator()165 void ToolBarEditor::insertSeparator() {
166 const int current_row = m_ui->m_listActivatedActions->currentRow();
167 QListWidgetItem* item = new QListWidgetItem(tr("Separator"));
168
169 item->setData(Qt::ItemDataRole::UserRole, SEPARATOR_ACTION_NAME);
170 item->setToolTip(tr("Separator"));
171 item->setIcon(qApp->icons()->fromTheme(QSL("insert-object")));
172 m_ui->m_listActivatedActions->insertItem(current_row + 1, item);
173 m_ui->m_listActivatedActions->setCurrentRow(current_row + 1);
174 emit setupChanged();
175 }
176
moveActionDown()177 void ToolBarEditor::moveActionDown() {
178 QList<QListWidgetItem*> items = m_ui->m_listActivatedActions->selectedItems();
179
180 if (items.size() == 1 && m_ui->m_listActivatedActions->currentRow() < m_ui->m_listActivatedActions->count() - 1) {
181 QListWidgetItem* selected_item = items.at(0);
182 int row = m_ui->m_listActivatedActions->row(selected_item);
183
184 m_ui->m_listActivatedActions->takeItem(row++);
185 m_ui->m_listActivatedActions->insertItem(row, selected_item);
186 m_ui->m_listActivatedActions->setCurrentRow(row);
187 emit setupChanged();
188 }
189 }
190
moveActionUp()191 void ToolBarEditor::moveActionUp() {
192 QList<QListWidgetItem*> items = m_ui->m_listActivatedActions->selectedItems();
193
194 if (items.size() == 1 && m_ui->m_listActivatedActions->currentRow() > 0) {
195 QListWidgetItem* selected_item = items.at(0);
196 int row = m_ui->m_listActivatedActions->row(selected_item);
197
198 m_ui->m_listActivatedActions->takeItem(row--);
199 m_ui->m_listActivatedActions->insertItem(row, selected_item);
200 m_ui->m_listActivatedActions->setCurrentRow(row);
201 emit setupChanged();
202 }
203 }
204
addSelectedAction()205 void ToolBarEditor::addSelectedAction() {
206 QList<QListWidgetItem*> items = m_ui->m_listAvailableActions->selectedItems();
207
208 if (items.size() == 1) {
209 QListWidgetItem* selected_item = items.at(0);
210
211 m_ui->m_listActivatedActions->insertItem(
212 m_ui->m_listActivatedActions->currentRow() + 1,
213 m_ui->m_listAvailableActions->takeItem(m_ui->m_listAvailableActions->row(selected_item)));
214 m_ui->m_listActivatedActions->setCurrentRow(m_ui->m_listActivatedActions->currentRow() + 1);
215 emit setupChanged();
216 }
217 }
218
deleteSelectedAction()219 void ToolBarEditor::deleteSelectedAction() {
220 QList<QListWidgetItem*> items = m_ui->m_listActivatedActions->selectedItems();
221
222 if (items.size() == 1) {
223 QListWidgetItem* selected_item = items.at(0);
224 const QString data_item = selected_item->data(Qt::ItemDataRole::UserRole).toString();
225
226 if (data_item == QSL(SEPARATOR_ACTION_NAME) || data_item == QSL(SPACER_ACTION_NAME)) {
227 m_ui->m_listActivatedActions->takeItem(m_ui->m_listActivatedActions->row(selected_item));
228 updateActionsAvailability();
229 }
230 else {
231 m_ui->m_listAvailableActions->insertItem(
232 m_ui->m_listAvailableActions->currentRow() + 1,
233 m_ui->m_listActivatedActions->takeItem(m_ui->m_listActivatedActions->row(selected_item)));
234 m_ui->m_listAvailableActions->sortItems(Qt::SortOrder::AscendingOrder);
235 m_ui->m_listAvailableActions->setCurrentRow(m_ui->m_listAvailableActions->currentRow() + 1);
236 }
237
238 emit setupChanged();
239 }
240 }
241
deleteAllActions()242 void ToolBarEditor::deleteAllActions() {
243 QListWidgetItem* taken_item;
244 QString data_item;
245
246 while ((taken_item = m_ui->m_listActivatedActions->takeItem(0)) != nullptr) {
247 data_item = taken_item->data(Qt::ItemDataRole::UserRole).toString();
248
249 if (data_item != QSL(SEPARATOR_ACTION_NAME) && data_item != QSL(SPACER_ACTION_NAME)) {
250 m_ui->m_listAvailableActions->insertItem(m_ui->m_listAvailableActions->currentRow() + 1, taken_item);
251 }
252 }
253
254 m_ui->m_listAvailableActions->sortItems(Qt::SortOrder::AscendingOrder);
255 updateActionsAvailability();
256 emit setupChanged();
257 }
258