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