1 //=============================================================================
2 //  MuseScore
3 //  Music Composition & Notation
4 //
5 //  Copyright (C) 2010-2014 Werner Schweer and others
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 "editstafftype.h"
14 #include "libmscore/part.h"
15 #include "libmscore/mscore.h"
16 #include "libmscore/score.h"
17 #include "libmscore/staff.h"
18 #include "libmscore/stringdata.h"
19 #include "musescore.h"
20 #include "navigator.h"
21 #include "scoreview.h"
22 
23 namespace Ms {
24 
25 extern Score::FileError readScore(MasterScore* score, QString name, bool ignoreVersionError);
26 
27 const char* g_groupNames[STAFF_GROUP_MAX] = {
28       QT_TRANSLATE_NOOP("staff group header name", "STANDARD STAFF"),
29       QT_TRANSLATE_NOOP("staff group header name", "PERCUSSION STAFF"),
30       QT_TRANSLATE_NOOP("staff group header name", "TABLATURE STAFF")
31       };
32 
33 //---------------------------------------------------------
34 //   noteHeadSchemes
35 //---------------------------------------------------------
36 
37 NoteHead::Scheme noteHeadSchemes[] = {
38       NoteHead::Scheme::HEAD_NORMAL,
39       NoteHead::Scheme::HEAD_PITCHNAME,
40       NoteHead::Scheme::HEAD_PITCHNAME_GERMAN,
41       NoteHead::Scheme::HEAD_SOLFEGE,
42       NoteHead::Scheme::HEAD_SOLFEGE_FIXED,
43       NoteHead::Scheme::HEAD_SHAPE_NOTE_4,
44       NoteHead::Scheme::HEAD_SHAPE_NOTE_7_AIKIN,
45       NoteHead::Scheme::HEAD_SHAPE_NOTE_7_FUNK,
46       NoteHead::Scheme::HEAD_SHAPE_NOTE_7_WALKER
47       };
48 
49 //---------------------------------------------------------
50 //   EditStaffType
51 //---------------------------------------------------------
52 
EditStaffType(QWidget * parent,Staff * st)53 EditStaffType::EditStaffType(QWidget* parent, Staff* st)
54    : QDialog(parent)
55       {
56       setObjectName("EditStaffType");
57       setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint);
58       setupUi(this);
59 
60       staff     = st;
61       staffType = *staff->staffType(Fraction(0,1));
62       Instrument* instr = staff->part()->instrument(); //tick?
63 
64       // template combo
65 
66       templateCombo->clear();
67       // standard group also as fall-back (but excluded by percussion)
68       bool bStandard    = !(instr != nullptr && instr->drumset() != nullptr);
69       bool bPerc        = (instr != nullptr && instr->drumset() != nullptr);
70       bool bTab         = (instr != nullptr && instr->stringData() != nullptr && instr->stringData()->frettedStrings() > 0);
71       int idx           = 0;
72       for (const StaffType& t : StaffType::presets()) {
73             if ( (t.group() == StaffGroup::STANDARD && bStandard)
74                         || (t.group() == StaffGroup::PERCUSSION && bPerc)
75                         || (t.group() == StaffGroup::TAB && bTab && t.lines() <= instr->stringData()->frettedStrings()))
76                   templateCombo->addItem(t.name(), idx);
77             idx++;
78             }
79       templateCombo->setCurrentIndex(-1);
80 
81       // tab page configuration
82       QList<QString> fontNames = StaffType::fontNames(false);
83       foreach (const QString& fn, fontNames)   // fill fret font name combo
84             fretFontName->addItem(fn);
85       fretFontName->setCurrentIndex(0);
86       fontNames = StaffType::fontNames(true);
87       foreach(const QString& fn, fontNames)   // fill duration font name combo
88             durFontName->addItem(fn);
89       durFontName->setCurrentIndex(0);
90 
91       for (auto i : noteHeadSchemes)
92             noteHeadScheme->addItem(NoteHead::scheme2userName(i), NoteHead::scheme2name(i));
93 
94       // load a sample standard score in preview
95       MasterScore* sc = new MasterScore(MScore::defaultStyle());
96       if (readScore(sc, QString(":/data/std_sample.mscx"), false) == Score::FileError::FILE_NO_ERROR)
97             standardPreview->setScore(sc);
98       else {
99             Q_ASSERT_X(false, "EditStaffType::EditStaffType", "Error in opening sample standard file for preview");
100             }
101 
102       // load a sample tabulature score in preview
103       sc = new MasterScore(MScore::defaultStyle());
104       if (readScore(sc, QString(":/data/tab_sample.mscx"), false) == Score::FileError::FILE_NO_ERROR)
105             tabPreview->setScore(sc);
106       else {
107             Q_ASSERT_X(false, "EditStaffType::EditStaffType", "Error in opening sample tab file for preview");
108             }
109       tabPreview->adjustSize();
110 
111       setValues();
112 
113       connect(name,           SIGNAL(textEdited(const QString&)), SLOT(nameEdited(const QString&)));
114       connect(lines,          SIGNAL(valueChanged(int)),          SLOT(updatePreview()));
115       connect(lineDistance,   SIGNAL(valueChanged(double)),       SLOT(updatePreview()));
116       connect(showBarlines,   SIGNAL(toggled(bool)),              SLOT(updatePreview()));
117       connect(genClef,        SIGNAL(toggled(bool)),              SLOT(updatePreview()));
118       connect(genTimesig,     SIGNAL(toggled(bool)),              SLOT(updatePreview()));
119       connect(noteHeadScheme, SIGNAL(currentIndexChanged(int)),   SLOT(updatePreview()));
120 
121       connect(genKeysigPitched,           SIGNAL(toggled(bool)),  SLOT(updatePreview()));
122       connect(showLedgerLinesPitched,     SIGNAL(toggled(bool)),  SLOT(updatePreview()));
123       connect(stemlessPitched,            SIGNAL(toggled(bool)),  SLOT(updatePreview()));
124       connect(genKeysigPercussion,        SIGNAL(toggled(bool)),  SLOT(updatePreview()));
125       connect(showLedgerLinesPercussion,  SIGNAL(toggled(bool)),  SLOT(updatePreview()));
126       connect(stemlessPercussion,         SIGNAL(toggled(bool)),  SLOT(updatePreview()));
127 
128       connect(noteValuesSymb,       SIGNAL(toggled(bool)),              SLOT(tabStemsToggled(bool)));
129       connect(noteValuesStems,      SIGNAL(toggled(bool)),              SLOT(tabStemsToggled(bool)));
130       connect(valuesRepeatNever,    SIGNAL(toggled(bool)),              SLOT(updatePreview()));
131       connect(valuesRepeatSystem,   SIGNAL(toggled(bool)),              SLOT(updatePreview()));
132       connect(valuesRepeatMeasure,  SIGNAL(toggled(bool)),              SLOT(updatePreview()));
133       connect(valuesRepeatAlways,   SIGNAL(toggled(bool)),              SLOT(updatePreview()));
134       connect(stemBesideRadio,      SIGNAL(toggled(bool)),              SLOT(updatePreview()));
135       connect(stemThroughRadio,     SIGNAL(toggled(bool)),              SLOT(tabStemThroughToggled(bool)));
136       connect(stemAboveRadio,       SIGNAL(toggled(bool)),              SLOT(updatePreview()));
137       connect(stemBelowRadio,       SIGNAL(toggled(bool)),              SLOT(updatePreview()));
138       connect(minimShortRadio,      SIGNAL(toggled(bool)),              SLOT(tabMinimShortToggled(bool)));
139       connect(minimSlashedRadio,    SIGNAL(toggled(bool)),              SLOT(updatePreview()));
140       connect(showRests,            SIGNAL(toggled(bool)),              SLOT(updatePreview()));
141       connect(durFontName,          SIGNAL(currentIndexChanged(int)),   SLOT(durFontNameChanged(int)));
142       connect(durFontSize,          SIGNAL(valueChanged(double)),       SLOT(updatePreview()));
143       connect(durY,                 SIGNAL(valueChanged(double)),       SLOT(updatePreview()));
144       connect(fretFontName,         SIGNAL(currentIndexChanged(int)),   SLOT(fretFontNameChanged(int)));
145       connect(fretFontSize,         SIGNAL(valueChanged(double)),       SLOT(updatePreview()));
146       connect(fretY,                SIGNAL(valueChanged(double)),       SLOT(updatePreview()));
147 
148       connect(linesThroughRadio,    SIGNAL(toggled(bool)),              SLOT(updatePreview()));
149       connect(onLinesRadio,         SIGNAL(toggled(bool)),              SLOT(updatePreview()));
150       connect(showTabFingering,     SIGNAL(toggled(bool)),              SLOT(updatePreview()));
151       connect(upsideDown,           SIGNAL(toggled(bool)),              SLOT(updatePreview()));
152       connect(numbersRadio,         SIGNAL(toggled(bool)),              SLOT(updatePreview()));
153       connect(showBackTied,         SIGNAL(toggled(bool)),              SLOT(updatePreview()));
154 
155       connect(templateReset,        SIGNAL(clicked()),                  SLOT(resetToTemplateClicked()));
156       connect(addToTemplates,       SIGNAL(clicked()),                  SLOT(addToTemplatesClicked()));
157 //      connect(groupCombo,           SIGNAL(currentIndexChanged(int)),   SLOT(staffGroupChanged(int)));
158       addToTemplates->setVisible(false);
159 
160       MuseScore::restoreGeometry(this);
161       }
162 
163 //---------------------------------------------------------
164 //   hideEvent
165 //---------------------------------------------------------
166 
hideEvent(QHideEvent * ev)167 void EditStaffType::hideEvent(QHideEvent* ev)
168       {
169       MuseScore::saveGeometry(this);
170       QWidget::hideEvent(ev);
171       }
172 
173 //---------------------------------------------------------
174 //   staffGroupChanged
175 //---------------------------------------------------------
176 /*
177 void EditStaffType::staffGroupChanged(int n)
178       {
179       int groupIdx = groupCombo->itemData(groupCombo->currentIndex()).toInt();
180       StaffGroup group = StaffGroup(groupIdx);
181       staffType = *StaffType::getDefaultPreset(group); // overwrite with default
182       setValues();
183       }
184 */
185 //---------------------------------------------------------
186 //   setValues
187 //---------------------------------------------------------
188 
setValues()189 void EditStaffType::setValues()
190       {
191       blockSignals(true);
192 
193       StaffGroup group = staffType.group();
194       int i = int(group);
195       stack->setCurrentIndex(i);
196       groupName->setText(qApp->translate("staff group header name", g_groupNames[i]));
197 //      groupCombo->setCurrentIndex(i);
198 
199       name->setText(staffType.name());
200       lines->setValue(staffType.lines());
201       lineDistance->setValue(staffType.lineDistance().val());
202       genClef->setChecked(staffType.genClef());
203       showBarlines->setChecked(staffType.showBarlines());
204       genTimesig->setChecked(staffType.genTimesig());
205 
206       switch (group) {
207             case StaffGroup::STANDARD:
208                   genKeysigPitched->setChecked(staffType.genKeysig());
209                   showLedgerLinesPitched->setChecked(staffType.showLedgerLines());
210                   stemlessPitched->setChecked(staffType.stemless());
211                   noteHeadScheme->setCurrentIndex(int(staffType.noteHeadScheme()));
212                   break;
213 
214             case StaffGroup::TAB:
215                   {
216                   upsideDown->setChecked(staffType.upsideDown());
217                   showTabFingering->setChecked(staffType.showTabFingering());
218                   int idx = fretFontName->findText(staffType.fretFontName(), Qt::MatchFixedString);
219                   if (idx == -1)
220                         idx = 0;          // if name not found, use first name
221                   fretFontName->setCurrentIndex(idx);
222                   fretFontSize->setValue(staffType.fretFontSize());
223                   fretY->setValue(staffType.fretFontUserY());
224 
225                   numbersRadio->setChecked(staffType.useNumbers());
226                   lettersRadio->setChecked(!staffType.useNumbers());
227                   onLinesRadio->setChecked(staffType.onLines());
228                   aboveLinesRadio->setChecked(!staffType.onLines());
229                   linesThroughRadio->setChecked(staffType.linesThrough());
230                   linesBrokenRadio->setChecked(!staffType.linesThrough());
231                   showBackTied->setChecked(staffType.showBackTied());
232 
233                   idx = durFontName->findText(staffType.durationFontName(), Qt::MatchFixedString);
234                   if (idx == -1)
235                         idx = 0;          // if name not found, use first name
236                   durFontName->setCurrentIndex(idx);
237                   durFontSize->setValue(staffType.durationFontSize());
238                   durY->setValue(staffType.durationFontUserY());
239                   // convert combined values of genDurations and slashStyle/stemless into noteValuesx radio buttons
240                   // Sbove/Below, Beside/Through and minim are only used if stems-and-beams
241                   // but set them from stt values anyway, to ensure preset matching
242                   stemAboveRadio->setChecked(!staffType.stemsDown());
243                   stemBelowRadio->setChecked(staffType.stemsDown());
244                   stemBesideRadio->setChecked(!staffType.stemThrough());
245                   stemThroughRadio->setChecked(staffType.stemThrough());
246                   TablatureMinimStyle minimStyle = staffType.minimStyle();
247                   minimNoneRadio->setChecked(minimStyle == TablatureMinimStyle::NONE);
248                   minimShortRadio->setChecked(minimStyle == TablatureMinimStyle::SHORTER);
249                   minimSlashedRadio->setChecked(minimStyle == TablatureMinimStyle::SLASHED);
250                   TablatureSymbolRepeat symRepeat = staffType.symRepeat();
251                   valuesRepeatNever->setChecked(symRepeat == TablatureSymbolRepeat::NEVER);
252                   valuesRepeatSystem->setChecked(symRepeat == TablatureSymbolRepeat::SYSTEM);
253                   valuesRepeatMeasure->setChecked(symRepeat == TablatureSymbolRepeat::MEASURE);
254                   valuesRepeatAlways->setChecked(symRepeat == TablatureSymbolRepeat::ALWAYS);
255                   if (staffType.genDurations()) {
256                         noteValuesNone->setChecked(false);
257                         noteValuesSymb->setChecked(true);
258                         noteValuesStems->setChecked(false);
259                         }
260                   else {
261                         if (staffType.stemless()) {
262                               noteValuesNone->setChecked(true);
263                               noteValuesSymb->setChecked(false);
264                               noteValuesStems->setChecked(false);
265                               }
266                         else {
267                               noteValuesNone->setChecked(false);
268                               noteValuesSymb->setChecked(false);
269                               noteValuesStems->setChecked(true);
270                               }
271                         }
272                   showRests->setChecked(staffType.showRests());
273                   // adjust compatibility across different settings
274                   tabStemThroughCompatibility(stemThroughRadio->isChecked());
275                   tabMinimShortCompatibility(minimShortRadio->isChecked());
276                   tabStemsCompatibility(noteValuesStems->isChecked());
277                   }
278                   break;
279 
280             case StaffGroup::PERCUSSION:
281                   genKeysigPercussion->setChecked(staffType.genKeysig());
282                   showLedgerLinesPercussion->setChecked(staffType.showLedgerLines());
283                   stemlessPercussion->setChecked(staffType.stemless());
284                   break;
285             }
286       updatePreview();
287       blockSignals(false);
288       }
289 
290 //---------------------------------------------------------
291 //   nameEdited
292 //---------------------------------------------------------
293 
nameEdited(const QString &)294 void EditStaffType::nameEdited(const QString& /*s*/)
295       {
296 //      staffTypeList->currentItem()->setText(s);
297       }
298 
299 //=========================================================
300 //   PERCUSSION PAGE METHODS
301 //=========================================================
302 
303 
304 //=========================================================
305 //   TABULATURE PAGE METHODS
306 //=========================================================
307 
308 //---------------------------------------------------------
309 //   Tabulature duration / fret font name changed
310 //
311 //    set depending parameters
312 //---------------------------------------------------------
313 
durFontNameChanged(int idx)314 void EditStaffType::durFontNameChanged(int idx)
315       {
316       qreal size, yOff;
317       if (StaffType::fontData(true, idx, 0, 0, &size, &yOff)) {
318             durFontSize->setValue(size);
319             durY->setValue(yOff);
320             }
321       updatePreview();
322       }
323 
fretFontNameChanged(int idx)324 void EditStaffType::fretFontNameChanged(int idx)
325       {
326       qreal size, yOff;
327       if (StaffType::fontData(false, idx, 0, 0, &size, &yOff)) {
328             fretFontSize->setValue(size);
329             fretY->setValue(yOff);
330             }
331       updatePreview();
332       }
333 
334 //---------------------------------------------------------
335 //   Tabulature note stems toggled
336 //
337 //    enable / disable all controls related to stems
338 //---------------------------------------------------------
339 
tabStemsToggled(bool checked)340 void EditStaffType::tabStemsToggled(bool checked)
341       {
342       tabStemsCompatibility(checked);
343       updatePreview();
344       }
345 
346 //---------------------------------------------------------
347 //   Tabulature "minim short" toggled
348 //
349 //    contra-toggle "stems through"
350 //---------------------------------------------------------
351 
tabMinimShortToggled(bool checked)352 void EditStaffType::tabMinimShortToggled(bool checked)
353       {
354       tabMinimShortCompatibility(checked);
355       updatePreview();
356       }
357 
358 //---------------------------------------------------------
359 //   Tabulature "stems through" toggled
360 //---------------------------------------------------------
361 
tabStemThroughToggled(bool checked)362 void EditStaffType::tabStemThroughToggled(bool checked)
363       {
364       tabStemThroughCompatibility(checked);
365       updatePreview();
366       }
367 
368 //---------------------------------------------------------
369 //   setFromDlg
370 //
371 //    initializes a StaffType from dlg controls
372 //---------------------------------------------------------
373 
setFromDlg()374 void EditStaffType::setFromDlg()
375       {
376       staffType.setName(name->text());
377       staffType.setLines(lines->value());
378       staffType.setLineDistance(Spatium(lineDistance->value()));
379       staffType.setGenClef(genClef->isChecked());
380       staffType.setShowBarlines(showBarlines->isChecked());
381       staffType.setGenTimesig(genTimesig->isChecked());
382       if (staffType.group() == StaffGroup::STANDARD) {
383             staffType.setGenKeysig(genKeysigPitched->isChecked());
384             staffType.setShowLedgerLines(showLedgerLinesPitched->isChecked());
385             staffType.setStemless(stemlessPitched->isChecked());
386             staffType.setNoteHeadScheme(NoteHead::name2scheme(noteHeadScheme->currentData().toString()));
387             }
388       if (staffType.group() == StaffGroup::PERCUSSION) {
389             staffType.setGenKeysig(genKeysigPercussion->isChecked());
390             staffType.setShowLedgerLines(showLedgerLinesPercussion->isChecked());
391             staffType.setStemless(stemlessPercussion->isChecked());
392             }
393       staffType.setDurationFontName(durFontName->currentText());
394       staffType.setDurationFontSize(durFontSize->value());
395       staffType.setDurationFontUserY(durY->value());
396       staffType.setFretFontName(fretFontName->currentText());
397       staffType.setFretFontSize(fretFontSize->value());
398       staffType.setFretFontUserY(fretY->value());
399       staffType.setLinesThrough(linesThroughRadio->isChecked());
400       staffType.setShowBackTied(showBackTied->isChecked());
401       staffType.setMinimStyle(minimNoneRadio->isChecked() ? TablatureMinimStyle::NONE :
402             (minimShortRadio->isChecked() ? TablatureMinimStyle::SHORTER : TablatureMinimStyle::SLASHED));
403       staffType.setSymbolRepeat(valuesRepeatNever->isChecked() ? TablatureSymbolRepeat::NEVER :
404             (valuesRepeatSystem->isChecked() ? TablatureSymbolRepeat::SYSTEM :
405                   valuesRepeatMeasure->isChecked() ? TablatureSymbolRepeat::MEASURE : TablatureSymbolRepeat::ALWAYS));
406       staffType.setOnLines(onLinesRadio->isChecked());
407       staffType.setShowRests(showRests->isChecked());
408       staffType.setUpsideDown(upsideDown->isChecked());
409       staffType.setShowTabFingering(showTabFingering->isChecked());
410       staffType.setUseNumbers(numbersRadio->isChecked());
411       //note values
412       staffType.setStemsDown(stemBelowRadio->isChecked());
413       staffType.setStemsThrough(stemThroughRadio->isChecked());
414       if (staffType.group() == StaffGroup::TAB) {
415             staffType.setGenKeysig(false);
416             staffType.setStemless(true);                   // assume no note values
417             staffType.setGenDurations(false);              //    "     "
418             if (noteValuesSymb->isChecked())
419                   staffType.setGenDurations(true);
420             if (noteValuesStems->isChecked())
421                   staffType.setStemless(false);
422             }
423       }
424 
425 //---------------------------------------------------------
426 //   Block preview signals
427 //---------------------------------------------------------
428 
blockSignals(bool block)429 void EditStaffType::blockSignals(bool block)
430       {
431       stack->blockSignals(block);
432 //      groupCombo->blockSignals(block);
433       lines->blockSignals(block);
434       lineDistance->blockSignals(block);
435       showBarlines->blockSignals(block);
436       genClef->blockSignals(block);
437       genTimesig->blockSignals(block);
438       noteValuesSymb->blockSignals(block);
439       noteValuesStems->blockSignals(block);
440       durFontName->blockSignals(block);
441       durFontSize->blockSignals(block);
442       durY->blockSignals(block);
443       fretFontName->blockSignals(block);
444       fretFontSize->blockSignals(block);
445       fretY->blockSignals(block);
446 
447       numbersRadio->blockSignals(block);
448       linesThroughRadio->blockSignals(block);
449       onLinesRadio->blockSignals(block);
450       showBackTied->blockSignals(block);
451 
452       upsideDown->blockSignals(block);
453       showTabFingering->blockSignals(block);
454       valuesRepeatNever->blockSignals(block);
455       valuesRepeatSystem->blockSignals(block);
456       valuesRepeatMeasure->blockSignals(block);
457       valuesRepeatAlways->blockSignals(block);
458       stemAboveRadio->blockSignals(block);
459       stemBelowRadio->blockSignals(block);
460       stemBesideRadio->blockSignals(block);
461       stemThroughRadio->blockSignals(block);
462       minimShortRadio->blockSignals(block);
463       minimSlashedRadio->blockSignals(block);
464       showRests->blockSignals(block);
465 
466       showLedgerLinesPercussion->blockSignals(block);
467       genKeysigPercussion->blockSignals(block);
468       stemlessPercussion->blockSignals(block);
469       }
470 
471 //---------------------------------------------------------
472 //   Tabulature note stems compatibility
473 //
474 //    Enable / disable all stem-related controls according to "Stems and beams" is checked/unchecked
475 //---------------------------------------------------------
476 
tabStemsCompatibility(bool checked)477 void EditStaffType::tabStemsCompatibility(bool checked)
478       {
479       valuesRepeatNever->setEnabled(noteValuesSymb->isChecked());
480       valuesRepeatSystem->setEnabled(noteValuesSymb->isChecked());
481       valuesRepeatMeasure->setEnabled(noteValuesSymb->isChecked());
482       valuesRepeatAlways->setEnabled(noteValuesSymb->isChecked());
483       stemAboveRadio->setEnabled(checked && !stemThroughRadio->isChecked());
484       stemBelowRadio->setEnabled(checked && !stemThroughRadio->isChecked());
485       stemBesideRadio->setEnabled(checked);
486       stemThroughRadio->setEnabled(checked && !minimShortRadio->isChecked());
487       minimNoneRadio->setEnabled(checked);
488       minimShortRadio->setEnabled(checked && !stemThroughRadio->isChecked());
489       minimSlashedRadio->setEnabled(checked);
490       }
491 
492 //---------------------------------------------------------
493 //   Tabulature "minim short" compatibility
494 //
495 //    Setting "short minim" stems is incompatible with "stems through":
496 //    if checked and "stems through" is checked, move check to "stems beside"
497 //---------------------------------------------------------
498 
tabMinimShortCompatibility(bool checked)499 void EditStaffType::tabMinimShortCompatibility(bool checked)
500       {
501       if (checked) {
502             if(stemThroughRadio->isChecked()) {
503                   stemThroughRadio->setChecked(false);
504                   stemBesideRadio->setChecked(true);
505                   }
506             }
507       // disable / enable "stems through" according "minim short" is checked / unchecked
508       stemThroughRadio->setEnabled(!checked && noteValuesStems->isChecked());
509       }
510 
511 //---------------------------------------------------------
512 //   Tabulature "stems through" compatibility
513 //
514 //    Setting "stems through" is incompatible with "minim short":
515 //    if checking and "minim short" is checked, move check to "minim slashed"
516 //    It also make "Stems above" and "Stems below" meaningless: disable them
517 //---------------------------------------------------------
518 
tabStemThroughCompatibility(bool checked)519 void EditStaffType::tabStemThroughCompatibility(bool checked)
520       {
521       if (checked) {
522             if(minimShortRadio->isChecked()) {
523                   minimShortRadio->setChecked(false);
524                   minimSlashedRadio->setChecked(true);
525                   }
526             }
527       // disable / enable "minim short" and "stems above/below" according "stems through" is checked / unchecked
528       bool enab = !checked && noteValuesStems->isChecked();
529       minimShortRadio->setEnabled(enab);
530       stemAboveRadio->setEnabled(enab);
531       stemBelowRadio->setEnabled(enab);
532       }
533 
534 //---------------------------------------------------------
535 //    updatePreview
536 ///   update staff type in preview score
537 //---------------------------------------------------------
538 
updatePreview()539 void EditStaffType::updatePreview()
540       {
541       setFromDlg();
542       ExampleView* preview = nullptr;
543       if (staffType.group() == StaffGroup::TAB)
544              preview = tabPreview;
545       else if (staffType.group() == StaffGroup::STANDARD)
546              preview = standardPreview;
547       if (preview) {
548             preview->score()->staff(0)->setStaffType(Fraction(0,1), staffType);
549             preview->score()->doLayout();
550             preview->updateAll();
551             preview->update();
552             }
553       }
554 
555 //---------------------------------------------------------
556 //   createUniqueStaffTypeName
557 ///  create unique new name for StaffType
558 //---------------------------------------------------------
559 
createUniqueStaffTypeName(StaffGroup group)560 QString EditStaffType::createUniqueStaffTypeName(StaffGroup group)
561       {
562       QString sn;
563       for (int idx = 1; ; ++idx) {
564             switch (group) {
565                   case StaffGroup::STANDARD:
566                         sn = QString("Standard-%1 [*]").arg(idx);
567                         break;
568                   case StaffGroup::PERCUSSION:
569                         sn = QString("Perc-%1 [*]").arg(idx);
570                         break;
571                   case StaffGroup::TAB:
572                         sn = QString("Tab-%1 [*]").arg(idx);
573                         break;
574                   }
575             bool found = false;
576             for (const StaffType& st : StaffType::presets()) {
577                   if (st.name() == sn) {
578                         found = true;
579                         break;
580                         }
581                   }
582             if (!found)
583                   break;
584             }
585       return sn;
586       }
587 
588 //---------------------------------------------------------
589 //   savePresets
590 //---------------------------------------------------------
591 
savePresets()592 void EditStaffType::savePresets()
593       {
594       qDebug("savePresets");
595       }
596 
597 //---------------------------------------------------------
598 //   loadPresets
599 //---------------------------------------------------------
600 
loadPresets()601 void EditStaffType::loadPresets()
602       {
603       qDebug("loadPresets");
604       }
605 
606 //---------------------------------------------------------
607 //   loadFromTemplate
608 //---------------------------------------------------------
609 /*
610 void EditStaffType::loadFromTemplateClicked()
611       {
612       StaffTypeTemplates stt(staffType);
613       if (stt.exec()) {
614             StaffType* st = stt.staffType();
615             staffType = *st;
616             setValues();
617             updatePreview();
618             }
619       }
620 */
resetToTemplateClicked()621 void EditStaffType::resetToTemplateClicked()
622       {
623       int idx = templateCombo->itemData(templateCombo->currentIndex()).toInt();
624       if (idx >= 0) {
625             staffType = *(StaffType::preset(StaffTypes(idx)));
626             setValues();
627             }
628       }
629 
630 //---------------------------------------------------------
631 //   addToTemplates
632 //---------------------------------------------------------
633 
addToTemplatesClicked()634 void EditStaffType::addToTemplatesClicked()
635       {
636       qDebug("not implemented: add to templates");
637       }
638 
639 //---------------------------------------------------------
640 //   StaffTypeTemplates
641 //---------------------------------------------------------
642 /*
643 StaffTypeTemplates::StaffTypeTemplates(const StaffType& st, QWidget* parent)
644    : QDialog(parent)
645       {
646       setupUi(this);
647 
648       QList<const StaffType*> stl;
649       for (const StaffType& t : StaffType::presets()) {
650             if (t.group() == st.group())
651                   stl.append(&t);
652             }
653       for (const StaffType* t : stl) {
654             QListWidgetItem* item = new QListWidgetItem(t->name());
655             item->setData(Qt::UserRole,
656                QVariant::fromValue<void*>((void*)t)
657                );
658             staffTypeList->addItem(item);
659             }
660       staffTypeList->setCurrentRow(0);
661       }
662 */
663 //---------------------------------------------------------
664 //   staffType
665 //---------------------------------------------------------
666 /*
667 StaffType* StaffTypeTemplates::staffType() const
668       {
669       return (StaffType*)staffTypeList->currentItem()->data(Qt::UserRole).value<void*>();
670       }
671 */
672 }
673 
674