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