1 //=============================================================================
2 // MuseScore
3 // Music Composition & Notation
4 //
5 // Copyright (C) 2016 Werner Schweer
6 //
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License version 2
9 // as published by the Free Software Foundation and appearing in
10 // the file LICENCE.GPL
11 //=============================================================================
12
13 #include "toolbarEditor.h"
14 #include "musescore.h"
15 #include "workspace.h"
16 #include "icons.h"
17
18 namespace Ms {
19
20 static const char* toolbars[] = {
21 QT_TRANSLATE_NOOP("toolbar", "Note Input"),
22 QT_TRANSLATE_NOOP("toolbar", "File Operations"),
23 QT_TRANSLATE_NOOP("toolbar", "Playback Controls")
24 };
25
26 //---------------------------------------------------------
27 // showToolbarEditor
28 //---------------------------------------------------------
29
showToolbarEditor()30 void MuseScore::showToolbarEditor()
31 {
32 if (!editToolbars) {
33 editToolbars = new ToolbarEditor(this);
34 }
35 editToolbars->init();
36 editToolbars->show();
37 }
38
39 //---------------------------------------------------------
40 // ToolbarEditor
41 //---------------------------------------------------------
42
ToolbarEditor(QWidget * parent)43 ToolbarEditor::ToolbarEditor(QWidget* parent)
44 : AbstractDialog(parent)
45 {
46 setObjectName("ToolbarEditor");
47 setupUi(this);
48
49 for (auto i : toolbars)
50 toolbarList->addItem(qApp->translate("toolbar", i));
51 toolbarList->setCurrentRow(0);
52
53 new_toolbars = new std::vector<std::list<const char*>*>();
54 new_toolbars->push_back(mscore->noteInputMenuEntries());
55 new_toolbars->push_back(mscore->fileOperationEntries());
56 new_toolbars->push_back(mscore->playbackControlEntries());
57
58 connect(toolbarList, SIGNAL(currentRowChanged(int)), SLOT(toolbarChanged(int)));
59 connect(add, SIGNAL(clicked()), SLOT(addAction()));
60 connect(remove, SIGNAL(clicked()), SLOT(removeAction()));
61 connect(up, SIGNAL(clicked()), SLOT(upAction()));
62 connect(down, SIGNAL(clicked()), SLOT(downAction()));
63 connect(buttonBox, SIGNAL(accepted()), SLOT(accepted()));
64
65 up->setIcon(*icons[int(Icons::arrowUp_ICON)]);
66 down->setIcon(*icons[int(Icons::arrowDown_ICON)]);
67 add->setIcon(*icons[int(Icons::goPrevious_ICON)]);
68 remove->setIcon(*icons[int(Icons::goNext_ICON)]);
69
70 MuseScore::restoreGeometry(this);
71 }
72
73 //---------------------------------------------------------
74 // init
75 //---------------------------------------------------------
76
init()77 void ToolbarEditor::init()
78 {
79 for (int i = 0; i < toolbarList->count(); i++)
80 toolbarList->item(i)->setText(qApp->translate("toolbar", toolbars[i]));
81
82 QString name = WorkspacesManager::currentWorkspace()->name();
83 bool writable = !WorkspacesManager::currentWorkspace()->readOnly();
84 if (!writable) {
85 name += " " + tr("(not changeable)");
86 }
87 add->setEnabled(writable);
88 remove->setEnabled(writable);
89 up->setEnabled(writable);
90 down->setEnabled(writable);
91 workspaceName->setText(name);
92
93 // Syncs the editor with the current toolbars
94 new_toolbars->at(0) = mscore->noteInputMenuEntries();
95 new_toolbars->at(1) = mscore->fileOperationEntries();
96 new_toolbars->at(2) = mscore->playbackControlEntries();
97 toolbarChanged(toolbarList->currentRow()); // populate lists
98 }
99
100 //---------------------------------------------------------
101 // retranslate
102 //---------------------------------------------------------
103
retranslate()104 void ToolbarEditor::retranslate()
105 {
106 retranslateUi(this);
107 init();
108 }
109
110 //---------------------------------------------------------
111 // accepted
112 //---------------------------------------------------------
113
accepted()114 void ToolbarEditor::accepted()
115 {
116 if (WorkspacesManager::currentWorkspace()->readOnly())
117 return;
118 // Updates the toolbars
119 mscore->setNoteInputMenuEntries(*(new_toolbars->at(0)));
120 mscore->setFileOperationEntries(*(new_toolbars->at(1)));
121 mscore->setPlaybackControlEntries(*(new_toolbars->at(2)));
122 mscore->populateNoteInputMenu();
123 mscore->populateFileOperations();
124 mscore->populatePlaybackControls();
125 WorkspacesManager::currentWorkspace()->setDirty(true);
126 }
127
128 //---------------------------------------------------------
129 // populateLists
130 //---------------------------------------------------------
131
populateLists(const std::list<const char * > & all,std::list<const char * > * current)132 void ToolbarEditor::populateLists(const std::list<const char*>& all, std::list<const char*>* current)
133 {
134 actionList->clear();
135 availableList->clear();
136 for (auto i : *current) {
137 QAction* a = getAction(i);
138 QListWidgetItem* item = nullptr;
139 QString id = QString(i);
140 if (a)
141 // Remove '&', because text contains '&' signs for mnemonics,
142 // but in a QListWidgetItem, you get the '&' instead of the mnemonic.
143 item = new QListWidgetItem(a->icon(), a->text().remove('&'));
144 else if (id.isEmpty())
145 item = new QListWidgetItem(tr("Separator"));
146 else
147 item = new QListWidgetItem(id);
148 item->setData(Qt::UserRole, QVariant::fromValue((void*)i));
149 actionList->addItem(item);
150 }
151 for (auto i : all) {
152 bool found = false;
153 for (auto k : *current) {
154 if (strcmp(k, i) == 0) {
155 found = true;
156 break;
157 }
158 }
159 if (!found) {
160 QAction* a = getAction(i);
161 QListWidgetItem* item = nullptr;
162 QString id = QString(i);
163 if (a)
164 item = new QListWidgetItem(a->icon(), a->text().remove('&'));
165 else if (!id.isEmpty())
166 item = new QListWidgetItem(id);
167 if (item) {
168 item->setData(Qt::UserRole, QVariant::fromValue((void*)i));
169 availableList->addItem(item);
170 }
171 }
172 }
173 QListWidgetItem* item = new QListWidgetItem(tr("Separator"));
174 item->setData(Qt::UserRole, QVariant::fromValue((void*)""));
175 availableList->addItem(item);
176 }
177
178 //---------------------------------------------------------
179 // isSeparator
180 //---------------------------------------------------------
181
isSeparator(QListWidgetItem * item) const182 bool ToolbarEditor::isSeparator(QListWidgetItem* item) const
183 {
184 return !*(const char*)(item->data(Qt::UserRole).value<void*>());
185 }
186
187 //---------------------------------------------------------
188 // addAction
189 //---------------------------------------------------------
190
addAction()191 void ToolbarEditor::addAction()
192 {
193 int cr = availableList->currentRow();
194 if (cr == -1)
195 return;
196 QListWidgetItem* item = availableList->item(cr);
197
198 if (isSeparator(item)) {
199 QListWidgetItem* nitem = new QListWidgetItem(item->text());
200 nitem->setData(Qt::UserRole, QVariant::fromValue((void*)""));
201 item = nitem;
202 }
203 else
204 item = availableList->takeItem(cr);
205 cr = actionList->currentRow();
206 if (cr == -1)
207 actionList->addItem(item);
208 else
209 actionList->insertItem(cr, item);
210 updateNewToolbar(toolbarList->currentRow());
211 }
212
213 //---------------------------------------------------------
214 // removeAction
215 //---------------------------------------------------------
216
removeAction()217 void ToolbarEditor::removeAction()
218 {
219 int cr = actionList->currentRow();
220 if (cr == -1)
221 return;
222 QListWidgetItem* item = actionList->takeItem(cr);
223 if (!isSeparator(item))
224 availableList->addItem(item);
225 updateNewToolbar(toolbarList->currentRow());
226 }
227
228 //---------------------------------------------------------
229 // upAction
230 //---------------------------------------------------------
231
upAction()232 void ToolbarEditor::upAction()
233 {
234 int cr = actionList->currentRow();
235 if (cr <= 0)
236 return;
237 QListWidgetItem* item = actionList->takeItem(cr);
238 actionList->insertItem(cr - 1, item);
239 actionList->setCurrentRow(cr - 1);
240 updateNewToolbar(toolbarList->currentRow());
241 }
242
243 //---------------------------------------------------------
244 // downAction
245 //---------------------------------------------------------
246
downAction()247 void ToolbarEditor::downAction()
248 {
249 int cr = actionList->currentRow();
250 if (cr == -1 || cr == actionList->count()-1)
251 return;
252 QListWidgetItem* item = actionList->takeItem(cr);
253 actionList->insertItem(cr + 1, item);
254 actionList->setCurrentRow(cr + 1);
255 updateNewToolbar(toolbarList->currentRow());
256 }
257
258 //---------------------------------------------------------
259 // toolbarChanged
260 //---------------------------------------------------------
261
toolbarChanged(int tb)262 void ToolbarEditor::toolbarChanged(int tb)
263 {
264 switch (tb) {
265 case 0: // NoteInput
266 populateLists(MuseScore::allNoteInputMenuEntries(), new_toolbars->at(tb));
267 break;
268 case 1: //FileOperations
269 populateLists(MuseScore::allFileOperationEntries(), new_toolbars->at(tb));
270 break;
271 case 2: //PlaybackControls
272 populateLists(MuseScore::allPlaybackControlEntries(), new_toolbars->at(tb));
273 }
274 }
275
276 //---------------------------------------------------------
277 // hideEvent
278 //---------------------------------------------------------
279
hideEvent(QHideEvent * event)280 void ToolbarEditor::hideEvent(QHideEvent* event)
281 {
282 MuseScore::saveGeometry(this);
283 QWidget::hideEvent(event);
284 }
285
286 //---------------------------------------------------------
287 // updateNewToolbar
288 //---------------------------------------------------------
289
updateNewToolbar(int toolbar_to_update)290 void ToolbarEditor::updateNewToolbar(int toolbar_to_update) {
291 // Updates the current toolbar to the actionList
292 std::list<const char*> *toolbar_action_list = new std::list<const char*>();
293 for (int i = 0; i < actionList->count(); ++i) {
294 QListWidgetItem* a = actionList->item(i);
295 toolbar_action_list->push_back((const char*)(a->data(Qt::UserRole).value<void*>()));
296 }
297 new_toolbars->at(toolbar_to_update) = toolbar_action_list;
298 }
299
300 } // namespace Ms
301
302