1 
2 //=============================================================================
3 //  MusE Score
4 //  Linux Music Score Editor
5 //
6 //  Copyright (C) 2008 Werner Schweer and others
7 //
8 //  This program is free software; you can redistribute it and/or modify
9 //  it under the terms of the GNU General Public License version 2.
10 //
11 //  This program is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU General Public License for more details.
15 //
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 //=============================================================================
20 
21 #include "newwizard.h"
22 #include "musescore.h"
23 #include "preferences.h"
24 #include "palette/palettelistview.h"
25 #include "instrdialog.h"
26 #include "templateBrowser.h"
27 #include "extension.h"
28 #include "icons.h"
29 #include "scoreaccessibility.h"
30 
31 #include "libmscore/instrtemplate.h"
32 #include "libmscore/score.h"
33 #include "libmscore/staff.h"
34 #include "libmscore/clef.h"
35 #include "libmscore/part.h"
36 #include "libmscore/drumset.h"
37 #include "libmscore/keysig.h"
38 #include "libmscore/measure.h"
39 #include "libmscore/stafftype.h"
40 #include "libmscore/timesig.h"
41 #include "libmscore/sym.h"
42 
43 namespace Ms {
44 
45 extern Palette* newKeySigPalette();
46 extern void filterInstruments(QTreeWidget *instrumentList, const QString &searchPhrase = QString(""));
47 
48 //---------------------------------------------------------
49 //   TimesigWizard
50 //---------------------------------------------------------
51 
TimesigWizard(QWidget * parent)52 TimesigWizard::TimesigWizard(QWidget* parent)
53    : QWidget(parent)
54       {
55       setupUi(this);
56       connect(tsCommonTime, SIGNAL(toggled(bool)), SLOT(commonTimeToggled(bool)));
57       connect(tsCutTime,    SIGNAL(toggled(bool)), SLOT(cutTimeToggled(bool)));
58       connect(tsFraction,   SIGNAL(toggled(bool)), SLOT(fractionToggled(bool)));
59       pickupMeasure->setChecked(false); // checked in the UI file to enable screen reader on pickup duration controls
60       tempoGroup->setChecked(false);
61 
62       tsCommonTime->setIcon(*icons[int(Icons::timesig_common_ICON)]);
63       tsCutTime->setIcon(*icons[int(Icons::timesig_allabreve_ICON)]);
64       }
65 
66 //---------------------------------------------------------
67 //   measures
68 //---------------------------------------------------------
69 
measures() const70 int TimesigWizard::measures() const
71       {
72       return measureCount->value();
73       }
74 
75 //---------------------------------------------------------
76 //   timesig
77 //---------------------------------------------------------
78 
timesig() const79 Fraction TimesigWizard::timesig() const
80       {
81       if (tsFraction->isChecked())
82             return Fraction(timesigZ->value(), 1 << timesigN->currentIndex());
83       else if (tsCommonTime->isChecked())
84             return Fraction(4, 4);
85       else
86             return Fraction(2, 2);
87       }
88 
89 //---------------------------------------------------------
90 //   pickupMeasure
91 //---------------------------------------------------------
92 
pickup(int * z,int * n) const93 bool TimesigWizard::pickup(int* z, int* n) const
94       {
95       *z = pickupTimesigZ->value();
96       *n = 1 << pickupTimesigN->currentIndex();
97       return pickupMeasure->isChecked();
98       }
99 
100 //---------------------------------------------------------
101 //   tempo
102 //---------------------------------------------------------
103 
tempo(double * t) const104 bool TimesigWizard::tempo(double* t) const
105     {
106     *t = spinboxTempo->value();
107     return tempoGroup->isChecked();
108     }
109 
110 //---------------------------------------------------------
111 //   type
112 //---------------------------------------------------------
113 
type() const114 TimeSigType TimesigWizard::type() const
115       {
116       if (tsFraction->isChecked())
117             return TimeSigType::NORMAL;
118       if (tsCommonTime->isChecked())
119             return TimeSigType::FOUR_FOUR;
120       return TimeSigType::ALLA_BREVE;
121       }
122 
123 //---------------------------------------------------------
124 //   commonTimeToggled
125 //---------------------------------------------------------
126 
commonTimeToggled(bool val)127 void TimesigWizard::commonTimeToggled(bool val)
128       {
129       if (val) {
130             // timesigZ->setValue(4);
131             // timesigN->setValue(4);
132             timesigZ->setEnabled(false);
133             timesigN->setEnabled(false);
134             }
135       }
136 
137 //---------------------------------------------------------
138 //   cutTimeToggled
139 //---------------------------------------------------------
140 
cutTimeToggled(bool val)141 void TimesigWizard::cutTimeToggled(bool val)
142       {
143       if (val) {
144             // timesigZ->setValue(2);
145             // timesigN->setValue(2);
146             timesigZ->setEnabled(false);
147             timesigN->setEnabled(false);
148             }
149       }
150 
151 //---------------------------------------------------------
152 //   fractionToggled
153 //---------------------------------------------------------
154 
fractionToggled(bool val)155 void TimesigWizard::fractionToggled(bool val)
156       {
157       if (val) {
158             timesigZ->setEnabled(true);
159             timesigN->setEnabled(true);
160             }
161       }
162 
163 //---------------------------------------------------------
164 //   TitleWizard
165 //---------------------------------------------------------
166 
TitleWizard(QWidget * parent)167 TitleWizard::TitleWizard(QWidget* parent)
168    : QWidget(parent)
169       {
170       setupUi(this);
171       }
172 
173 //---------------------------------------------------------
174 //   NewWizardInfoPage
175 //---------------------------------------------------------
176 
NewWizardInfoPage(QWidget * parent)177 NewWizardInfoPage::NewWizardInfoPage(QWidget* parent)
178    : QWizardPage(parent)
179       {
180       setTitle(tr("Create New Score"));
181       setSubTitle(tr("Enter score information:"));
182       setAccessibleName(QWizardPage::title());
183       setAccessibleDescription(QWizardPage::subTitle());
184 
185       w = new TitleWizard;
186 
187       QGridLayout* grid = new QGridLayout;
188       grid->addWidget(w, 0, 0);
189       setLayout(grid);
190       }
191 
192 //---------------------------------------------------------
193 //   initializePage
194 //---------------------------------------------------------
195 
initializePage()196 void NewWizardInfoPage::initializePage()
197       {
198       w->title->setText("");
199       w->subtitle->setText("");
200       }
201 
202 //---------------------------------------------------------
203 //   NewWizardInstrumentsPage
204 //---------------------------------------------------------
205 
NewWizardInstrumentsPage(QWidget * parent)206 NewWizardInstrumentsPage::NewWizardInstrumentsPage(QWidget* parent)
207    : QWizardPage(parent)
208       {
209       setFinalPage(true);
210       setTitle(tr("Create New Score"));
211       setSubTitle(tr("Choose instruments on the left to add to instrument list on the right:"));
212       setAccessibleName(title());
213       setAccessibleDescription(subTitle());
214       instrumentsWidget = new InstrumentsWidget;
215       QGridLayout* grid = new QGridLayout;
216       grid->setSpacing(0);
217       grid->setContentsMargins(0, 0, 0, 0);
218       grid->addWidget(instrumentsWidget, 0, 0);
219       setLayout(grid);
220       connect(instrumentsWidget, SIGNAL(completeChanged(bool)), SLOT(setComplete(bool)));
221       }
222 
223 //---------------------------------------------------------
224 //   initializePage
225 //---------------------------------------------------------
226 
initializePage()227 void NewWizardInstrumentsPage::initializePage()
228       {
229       complete = false;
230       instrumentsWidget->init();
231       }
232 
233 //---------------------------------------------------------
234 //   setComplete
235 //---------------------------------------------------------
236 
setComplete(bool val)237 void NewWizardInstrumentsPage::setComplete(bool val)
238       {
239       complete = val;
240       emit completeChanged();
241       }
242 
243 //---------------------------------------------------------
244 //   isComplete
245 //---------------------------------------------------------
246 
isComplete() const247 bool NewWizardInstrumentsPage::isComplete() const
248       {
249       return complete;
250       }
251 
252 //---------------------------------------------------------
253 //   createInstruments
254 //---------------------------------------------------------
255 
createInstruments(Score * s)256 void NewWizardInstrumentsPage::createInstruments(Score* s)
257       {
258       instrumentsWidget->createInstruments(s);
259       s->setScoreOrder(instrumentsWidget->getScoreOrder());
260       }
261 
262 //---------------------------------------------------------
263 //   NewWizardTimesigPage
264 //---------------------------------------------------------
265 
NewWizardTimesigPage(QWidget * parent)266 NewWizardTimesigPage::NewWizardTimesigPage(QWidget* parent)
267    : QWizardPage(parent)
268       {
269       setFinalPage(true);
270       setTitle(tr("Create New Score"));
271       setSubTitle(tr("Choose time signature and tempo:"));
272       setAccessibleName(title());
273       setAccessibleDescription(subTitle());
274 
275       w = new TimesigWizard;
276       QGridLayout* grid = new QGridLayout;
277       grid->addWidget(w, 0, 0);
278       setLayout(grid);
279       }
280 
281 //---------------------------------------------------------
282 //   NewWizardTemplatePage
283 //---------------------------------------------------------
284 
NewWizardTemplatePage(QWidget * parent)285 NewWizardTemplatePage::NewWizardTemplatePage(QWidget* parent)
286    : QWizardPage(parent)
287       {
288       setFinalPage(true);
289       setTitle(tr("Create New Score"));
290       setSubTitle(tr("Choose template file:"));
291       setAccessibleName(title());
292       setAccessibleDescription(subTitle());
293 
294       templateFileBrowser = new TemplateBrowser(this);
295       templateFileBrowser->setStripNumbers(true);
296 
297       QVBoxLayout* layout = new QVBoxLayout;
298       layout->addWidget(templateFileBrowser);
299       setLayout(layout);
300 
301       connect(templateFileBrowser, SIGNAL(scoreSelected(const QString&)), SLOT(templateChanged(const QString&)));
302       connect(templateFileBrowser, SIGNAL(scoreActivated(const QString&)), SLOT(fileAccepted(const QString&)));
303       buildTemplatesList();
304       }
305 
306 //---------------------------------------------------------
307 //   initializePage
308 //---------------------------------------------------------
309 
initializePage()310 void NewWizardTemplatePage::initializePage()
311       {
312 
313       }
314 
315 //---------------------------------------------------------
316 //   buildTemplatesList
317 //---------------------------------------------------------
318 
buildTemplatesList()319 void NewWizardTemplatePage::buildTemplatesList()
320       {
321 
322       QDir dir(mscoreGlobalShare + "/templates");
323       QFileInfoList fil = dir.entryInfoList(QDir::NoDotAndDotDot | QDir::Readable | QDir::Dirs | QDir::Files, QDir::Name);
324       if(fil.isEmpty()){
325           fil.append(QFileInfo(QFile(":data/Empty_Score.mscx")));
326           }
327 
328       QDir myTemplatesDir(preferences.getString(PREF_APP_PATHS_MYTEMPLATES));
329       fil.append(myTemplatesDir.entryInfoList(QDir::NoDotAndDotDot | QDir::Readable | QDir::Dirs | QDir::Files, QDir::Name));
330 
331       // append templates directories from extensions
332       QStringList extensionsDir = Extension::getDirectoriesByType(Extension::templatesDir);
333       for (QString extDir : extensionsDir) {
334             QDir extTemplateDir(extDir);
335             fil.append(extTemplateDir.entryInfoList(QDir::NoDotAndDotDot | QDir::Readable | QDir::Dirs | QDir::Files, QDir::Name));
336             }
337       templateFileBrowser->setScores(fil);
338       }
339 
340 //---------------------------------------------------------
341 //   isComplete
342 //---------------------------------------------------------
343 
isComplete() const344 bool NewWizardTemplatePage::isComplete() const
345       {
346       return !path.isEmpty();
347       }
348 
349 //---------------------------------------------------------
350 //   fileAccepted
351 //---------------------------------------------------------
352 
fileAccepted(const QString & s)353 void NewWizardTemplatePage::fileAccepted(const QString& s)
354       {
355       path = s;
356       templateFileBrowser->show();
357       if (wizard()->currentPage() == this)
358             wizard()->next();
359       }
360 
361 //---------------------------------------------------------
362 //   templateChanged
363 //---------------------------------------------------------
364 
templateChanged(const QString & s)365 void NewWizardTemplatePage::templateChanged(const QString& s)
366       {
367       setFinalPage(QFileInfo(s).completeBaseName() != "00-Blank");
368       path = s;
369       emit completeChanged();
370       }
371 
372 //---------------------------------------------------------
373 //   templatePath
374 //---------------------------------------------------------
375 
templatePath() const376 QString NewWizardTemplatePage::templatePath() const
377       {
378       return path;
379       }
380 
381 //---------------------------------------------------------
382 //   NewWizardKeysigPage
383 //---------------------------------------------------------
384 
NewWizardKeysigPage(QWidget * parent)385 NewWizardKeysigPage::NewWizardKeysigPage(QWidget* parent)
386    : QWizardPage(parent)
387       {
388       setFinalPage(true);
389       setTitle(tr("Create New Score"));
390       setSubTitle(tr("Choose key signature:"));
391       setAccessibleName(title());
392       setAccessibleDescription(subTitle());
393 
394       QGroupBox* b1 = new QGroupBox;
395       b1->setTitle(tr("Key Signature"));
396       b1->setAccessibleName(b1->title());
397       b1->setAccessibleDescription(tr("Choose a key signature"));
398 
399       QVBoxLayout* l1 = new QVBoxLayout;
400       b1->setLayout(l1);
401 
402       _plv = new PaletteListView(mscore->newKeySigPalettePanel());
403       l1->addWidget(_plv);
404       _plv->setCurrentRow(14); // C Major
405 
406       QVBoxLayout* l3 = new QVBoxLayout;
407       l3->addWidget(b1);
408       l3->addStretch(100);
409       setLayout(l3);
410       setFocusPolicy(Qt::StrongFocus);
411       }
412 
413 //---------------------------------------------------------
414 //   keysig
415 //---------------------------------------------------------
416 
keysig() const417 KeySigEvent NewWizardKeysigPage::keysig() const
418       {
419       return static_cast<KeySig*>(_plv->currentElement())->keySigEvent();
420       }
421 
422 //---------------------------------------------------------
423 //   NewWizard
424 //---------------------------------------------------------
425 
NewWizard(QWidget * parent)426 NewWizard::NewWizard(QWidget* parent)
427    : QWizard(parent)
428       {
429       setObjectName("NewWizard");
430       setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint);
431       auto wizardStyleValue = QWizard::ModernStyle; //Modern Winsows look
432 #ifdef Q_OS_MAC
433       wizardStyleValue = QWizard::MacStyle;
434       setOption(QWizard::CancelButtonOnLeft, true);
435 #endif
436       setWizardStyle(wizardStyleValue);
437 
438       setPixmap(QWizard::LogoPixmap, QPixmap(":/data/mscore.png"));
439       setPixmap(QWizard::WatermarkPixmap, QPixmap());
440       setWindowTitle(tr("New Score Wizard"));
441 
442       setOption(QWizard::NoCancelButton, false);
443       setOption(QWizard::HaveFinishButtonOnEarlyPages, true);
444       setOption(QWizard::HaveNextButtonOnLastPage, true);
445 
446       infoPage = new NewWizardInfoPage;
447       instrumentsPage = new NewWizardInstrumentsPage;
448       timesigPage = new NewWizardTimesigPage;
449       templatePage = new NewWizardTemplatePage;
450       keysigPage = new NewWizardKeysigPage;
451 
452 //  enum Page { Invalid = -1, Type, Instruments, Template, Keysig, Timesig};
453 
454       setPage(Page::Type,        infoPage);
455       setPage(Page::Instruments, instrumentsPage);
456       setPage(Page::Template,    templatePage);
457       setPage(Page::Keysig,      keysigPage);
458       setPage(Page::Timesig,     timesigPage);
459 
460       resize(QSize(840, 560)); //ensure default size if no geometry in settings
461       MuseScore::restoreGeometry(this);
462       connect(this, SIGNAL(currentIdChanged(int)), SLOT(idChanged(int)));
463       }
464 
465 //---------------------------------------------------------
466 //   idChanged
467 //---------------------------------------------------------
468 
idChanged(int)469 void NewWizard::idChanged(int /*id*/)
470       {
471 //printf("\n===\nWizard: id changed %d\n", id);
472       }
473 
474 //---------------------------------------------------------
475 //   nextId
476 //---------------------------------------------------------
477 
nextId() const478 int NewWizard::nextId() const
479       {
480       int next;
481       switch (Page(currentId())) {
482             case Page::Type:
483                   next = Page::Template;
484                   break;
485             case Page::Template:
486                   next = emptyScore() ? Page::Instruments : Page::Keysig;
487                   break;
488             case Page::Instruments:
489                   next = Page::Keysig;
490                   break;
491             case Page::Keysig:
492                   next = Page::Timesig;
493                   break;
494             case Page::Timesig:
495             default:
496                   next = Page::Invalid;
497                   break;
498             }
499       return next;
500       }
501 
502 //---------------------------------------------------------
503 //   emptyScore
504 //---------------------------------------------------------
505 
emptyScore() const506 bool NewWizard::emptyScore() const
507       {
508       QString p = templatePage->templatePath();
509       QFileInfo fi(p);
510       bool val = fi.completeBaseName() == "00-Blank";
511       return val;
512       }
513 
514 //---------------------------------------------------------
515 //   updateValues
516 //---------------------------------------------------------
517 
updateValues() const518 void NewWizard::updateValues() const
519       {
520       //p2->buildInstrumentsList();
521       templatePage->buildTemplatesList();
522       }
523 
524 //---------------------------------------------------------
525 //   hideEvent
526 //---------------------------------------------------------
527 
hideEvent(QHideEvent * event)528 void NewWizard::hideEvent(QHideEvent* event)
529       {
530       MuseScore::saveGeometry(this);
531       QWidget::hideEvent(event);
532       }
533 
534 }
535 
536