1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4     Rosegarden
5     A MIDI and audio sequencer and musical notation editor.
6     Copyright 2000-2021 the Rosegarden development team.
7 
8     Other copyrights also apply to some parts of this work.  Please
9     see the AUTHORS file and individual file headers for details.
10 
11     This program is free software; you can redistribute it and/or
12     modify it under the terms of the GNU General Public License as
13     published by the Free Software Foundation; either version 2 of the
14     License, or (at your option) any later version.  See the file
15     COPYING included with this distribution for more information.
16 */
17 
18 
19 #include "NotationConfigurationPage.h"
20 #include <QLayout>
21 
22 #include "misc/Strings.h"
23 #include "misc/ConfigGroups.h"
24 #include "base/Exception.h"
25 #include "base/NotationTypes.h"
26 #include "commands/edit/PasteEventsCommand.h"
27 #include "document/RosegardenDocument.h"
28 #include "gui/editors/notation/HeadersGroup.h"
29 #include "gui/editors/notation/NotationHLayout.h"
30 #include "gui/editors/notation/NoteFontFactory.h"
31 #include "gui/editors/notation/NoteFont.h"
32 #include "gui/editors/notation/NoteFontMap.h"
33 #include "gui/editors/notation/NoteFontViewer.h"
34 #include "gui/editors/notation/NotePixmapFactory.h"
35 #include "gui/editors/notation/NoteStyleFactory.h"
36 #include "gui/widgets/FontRequester.h"
37 #include "TabbedConfigurationPage.h"
38 #include <QComboBox>
39 #include <QSettings>
40 #include <QMessageBox>
41 #include <QCheckBox>
42 #include <QComboBox>
43 #include <QFont>
44 #include <QFrame>
45 #include <QLabel>
46 #include <QObject>
47 #include <QPushButton>
48 #include <QString>
49 #include <QStringList>
50 #include <QTabWidget>
51 #include <QWidget>
52 #include <QHBoxLayout>
53 #include <QToolTip>
54 #include <QGridLayout>
55 #include <algorithm>
56 
57 namespace Rosegarden
58 {
59 
NotationConfigurationPage(QWidget * parent)60 NotationConfigurationPage::NotationConfigurationPage(QWidget *parent) :
61         TabbedConfigurationPage(parent)
62 {
63     QSettings settings;
64     settings.beginGroup(NotationViewConfigGroup);
65 
66     QFrame *frame;
67     QGridLayout *layout;
68 
69     frame = new QFrame(m_tabWidget);
70     frame->setContentsMargins(10, 10, 10, 10);
71     layout = new QGridLayout(frame);
72     layout->setSpacing(5);
73 
74     int row = 0;
75 
76     layout->setRowMinimumHeight(row, 15);
77     ++row;
78 
79     layout->addWidget(new QLabel(tr("Default layout mode"), frame), row, 0);
80 
81     m_layoutMode = new QComboBox(frame);
82     connect(m_layoutMode, SIGNAL(activated(int)), this, SLOT(slotModified()));
83     m_layoutMode->setEditable(false);
84     m_layoutMode->addItem(tr("Linear layout"));
85     m_layoutMode->addItem(tr("Continuous page layout"));
86     m_layoutMode->addItem(tr("Multiple page layout"));
87     int defaultLayoutMode = settings.value("layoutmode", 0).toInt() ;
88     if (defaultLayoutMode >= 0 && defaultLayoutMode <= 2) {
89         m_layoutMode->setCurrentIndex(defaultLayoutMode);
90     }
91     layout->addWidget(m_layoutMode, row, 1, 1, 2);
92     ++row;
93 
94     layout->addWidget(new QLabel(tr("Show track headers (linear layout only)"),
95                                       frame), row, 0);
96 
97     m_showTrackHeaders = new QComboBox(frame);
98     connect(m_showTrackHeaders, SIGNAL(activated(int)), this, SLOT(slotModified()));
99     m_showTrackHeaders->setEditable(false);
100 
101     m_showTrackHeaders->addItem(tr("Never"), HeadersGroup::ShowNever);
102     m_showTrackHeaders->addItem(tr("When needed"), HeadersGroup::ShowWhenNeeded);
103     m_showTrackHeaders->addItem(tr("Always"), HeadersGroup::ShowAlways);
104     int defaultShowTrackHeaders = settings.value("shownotationheader",
105                                                  HeadersGroup::DefaultShowMode).toInt() ;
106     if (HeadersGroup::isValidShowMode(defaultShowTrackHeaders)) {
107         m_showTrackHeaders->setCurrentIndex(defaultShowTrackHeaders);
108     }
109 
110     //$$$ After Thorn, reword this string into better English:
111     m_showTrackHeaders->setToolTip(QString(tr(
112         "\"Always\" and \"Never\" mean what they usually mean\n"
113         "\"When needed\" means \"when staves are too many to all fit"
114         " in the current window\"")));
115 
116     layout->addWidget(m_showTrackHeaders, row, 1, 1, 2);
117     ++row;
118 
119     layout->setRowMinimumHeight(row, 20);
120     ++row;
121 
122     layout->addWidget
123         (new QLabel
124          (tr("Show non-notation events as question marks"), frame),
125          row, 0, 1, 2);
126     m_showUnknowns = new QCheckBox(frame);
127     connect(m_showUnknowns, &QCheckBox::stateChanged, this, &NotationConfigurationPage::slotModified);
128     bool defaultShowUnknowns = qStrToBool(settings.value("showunknowns", "false")) ;
129     m_showUnknowns->setChecked(defaultShowUnknowns);
130     layout->addWidget(m_showUnknowns, row, 2);
131     ++row;
132 
133     layout->addWidget
134         (new QLabel
135          (tr("Show notation-quantized notes in a different color"), frame),
136          row, 0, 1, 2);
137     m_colourQuantize = new QCheckBox(frame);
138     connect(m_colourQuantize, &QCheckBox::stateChanged, this, &NotationConfigurationPage::slotModified);
139     bool defaultColourQuantize = qStrToBool(settings.value("colourquantize", "false")) ;
140     m_colourQuantize->setChecked(defaultColourQuantize);
141     layout->addWidget(m_colourQuantize, row, 2);
142     ++row;
143 
144     layout->addWidget
145         (new QLabel
146          (tr("Show \"invisible\" events in grey"), frame),
147          row, 0, 1, 2);
148     m_showInvisibles = new QCheckBox(frame);
149     connect(m_showInvisibles, &QCheckBox::stateChanged, this, &NotationConfigurationPage::slotModified);
150     bool defaultShowInvisibles = qStrToBool(settings.value("showinvisibles", "true")) ;
151     m_showInvisibles->setChecked(defaultShowInvisibles);
152     layout->addWidget(m_showInvisibles, row, 2);
153     ++row;
154 
155     layout->addWidget
156         (new QLabel
157          (tr("Show notes outside suggested playable range in red"), frame),
158          row, 0, 1, 2);
159     m_showRanges = new QCheckBox(frame);
160     connect(m_showRanges, &QCheckBox::stateChanged, this, &NotationConfigurationPage::slotModified);
161     bool defaultShowRanges = qStrToBool(settings.value("showranges", "true")) ;
162     m_showRanges->setChecked(defaultShowRanges);
163     layout->addWidget(m_showRanges, row, 2);
164     ++row;
165 
166     layout->addWidget
167         (new QLabel
168          (tr("Highlight superimposed notes with a halo effect"), frame),
169          row, 0, 1, 2);
170     m_showCollisions = new QCheckBox(frame);
171     connect(m_showCollisions, &QCheckBox::stateChanged, this, &NotationConfigurationPage::slotModified);
172     bool defaultShowCollisions = qStrToBool(settings.value("showcollisions", "true")) ;
173     m_showCollisions->setChecked(defaultShowCollisions);
174     layout->addWidget(m_showCollisions, row, 2);
175     ++row;
176 
177     layout->setRowMinimumHeight(row, 20);
178     ++row;
179 
180     layout->addWidget
181         (new QLabel
182          (tr("When recording MIDI, split-and-tie long notes at barlines"), frame),
183          row, 0, 1, 2);
184     m_splitAndTie = new QCheckBox(frame);
185     connect(m_splitAndTie, &QCheckBox::stateChanged, this, &NotationConfigurationPage::slotModified);
186     //NB. The split-and-tie feature is turned on by default once more, now that
187     // the matrix and notation editors both handle strings of adjacent tied
188     // notes as though they were a single unit.  This makes more sense when
189     // inserting, say, a whole note that won't fit inside a measure.
190     bool defaultSplitAndTie = qStrToBool(settings.value("quantizemakeviable", "true")) ;
191     m_splitAndTie->setChecked(defaultSplitAndTie);
192     layout->addWidget(m_splitAndTie, row, 2);
193     ++row;
194 
195     layout->setRowStretch(row, 10);
196     frame->setLayout(layout);
197 
198     addTab(frame, tr("Layout"));
199 
200     frame = new QFrame(m_tabWidget);
201     frame->setContentsMargins(10, 10, 10, 10);
202     layout = new QGridLayout(frame);
203     layout->setSpacing(5);
204 
205     row = 0;
206 
207     layout->setRowMinimumHeight(row, 15);
208     ++row;
209 
210     layout->addWidget
211         (new QLabel(tr("Default note style for new notes"), frame),
212          row, 0, 1, 2);
213 
214     layout->setColumnStretch(2, 10);
215 
216     m_noteStyle = new QComboBox(frame);
217     connect(m_noteStyle, SIGNAL(activated(int)), this, SLOT(slotModified()));
218     m_noteStyle->setEditable(false);
219     m_untranslatedNoteStyle.clear();
220 
221     QString defaultStyle = settings.value("style", NoteStyleFactory::DefaultStyle).toString();
222     std::vector<NoteStyleName> styles
223     (NoteStyleFactory::getAvailableStyleNames());
224 
225     for (std::vector<NoteStyleName>::iterator i = styles.begin();
226             i != styles.end(); ++i) {
227 
228         QString styleQName(*i);
229         m_untranslatedNoteStyle.append(styleQName);
230         m_noteStyle->addItem(QObject::tr(styleQName.toUtf8()));
231         if (styleQName == defaultStyle) {
232             m_noteStyle->setCurrentIndex(m_noteStyle->count() - 1);
233         }
234     }
235 
236     layout->addWidget(m_noteStyle, row, 2);
237     ++row;
238 
239     layout->setRowMinimumHeight(row, 20);
240     ++row;
241 
242     layout->addWidget
243     (new QLabel(tr("When inserting notes..."), frame), row, 0);
244 
245     int defaultInsertType = settings.value("inserttype", 0).toInt() ;
246 
247     m_insertType = new QComboBox(frame);
248     connect(m_insertType, SIGNAL(activated(int)), this, SLOT(slotModified()));
249     m_insertType->setEditable(false);
250     m_insertType->addItem
251     (tr("Split notes into ties to make durations match"));
252     m_insertType->addItem(tr("Ignore existing durations"));
253     m_insertType->setCurrentIndex(defaultInsertType);
254 
255     layout->addWidget(m_insertType, row, 1, 1, 2);
256     ++row;
257 
258     bool autoBeam = qStrToBool(settings.value("autobeam", "true")) ;
259 
260     layout->addWidget
261         (new QLabel
262          (tr("Auto-beam on insert when appropriate"), frame),
263          row, 0, 1, 2);
264     m_autoBeam = new QCheckBox(frame);
265     connect(m_autoBeam, &QCheckBox::stateChanged, this, &NotationConfigurationPage::slotModified);
266     m_autoBeam->setChecked(autoBeam);
267     layout->addWidget(m_autoBeam, row, 2, 1, 1);
268 
269     ++row;
270 
271      bool autoCorrect = qStrToBool(settings.value("autotieatbarlines","true"));
272 
273      layout->addWidget(
274              new QLabel
275              (tr("Tie notes at barlines automatically"), frame),
276              row, 0, 1, 2);
277      m_autoTieBarlines = new QCheckBox(frame);
278      connect(m_autoTieBarlines, &QCheckBox::stateChanged, this, &NotationConfigurationPage::slotModified);
279      m_autoTieBarlines->setChecked(autoCorrect);
280      layout->addWidget(m_autoTieBarlines, row, 2, 1, 1);
281 
282      ++row;
283 
284 
285     bool collapse = qStrToBool(settings.value("collapse", "false")) ;
286 
287     layout->addWidget
288         (new QLabel
289          (tr("Collapse rests after erase"), frame),
290          row, 0, 1, 2);
291     m_collapseRests = new QCheckBox(frame);
292     connect(m_collapseRests, &QCheckBox::stateChanged, this, &NotationConfigurationPage::slotModified);
293     m_collapseRests->setChecked(collapse);
294     layout->addWidget(m_collapseRests, row, 2, 1, 1);
295     ++row;
296 
297     layout->setRowMinimumHeight(row, 20);
298     ++row;
299 
300     layout->addWidget
301     (new QLabel(tr("Default paste type"), frame), row, 0);
302 
303     m_pasteType = new QComboBox(frame);
304     connect(m_pasteType, SIGNAL(activated(int)), this, SLOT(slotModified()));
305     m_pasteType->setEditable(false);
306 
307     unsigned int defaultPasteType = settings.value("pastetype",
308             PasteEventsCommand::Restricted).toUInt();
309 
310     PasteEventsCommand::PasteTypeMap pasteTypes =
311         PasteEventsCommand::getPasteTypes();
312 
313     for (PasteEventsCommand::PasteTypeMap::iterator i = pasteTypes.begin();
314             i != pasteTypes.end(); ++i) {
315         m_pasteType->addItem(i->second);
316     }
317 
318     m_pasteType->setCurrentIndex(defaultPasteType);
319     layout->addWidget(m_pasteType, row, 1, 1, 2);
320     ++row;
321 
322     layout->setRowMinimumHeight(row, 20);
323     ++row;
324 
325     bool preview = qStrToBool(settings.value("alwayspreview", "true")) ;
326 
327     QLabel * previewLabel = new QLabel
328          (tr("Always show note preview"), frame);
329     layout->addWidget(previewLabel, row, 0, 1, 2);
330     m_preview = new QCheckBox(frame);
331     connect(m_preview, &QCheckBox::stateChanged, this, &NotationConfigurationPage::slotModified);
332     m_preview->setChecked(preview);
333     QString previewTip(tr(
334         "<p>If checked, a preview of the note or rest is always displayed"
335         " when inserting notes or rests with the mouse</p>"));
336     previewLabel->setToolTip(previewTip);
337     m_preview->setToolTip(previewTip);
338    layout->addWidget(m_preview, row, 2, 1, 1);
339     ++row;
340 
341     bool quickEdit = qStrToBool(settings.value("quickedit", "true"));
342 
343     QLabel * quickEditLabel = new QLabel(
344          tr("Quick mouse entry mode"),
345          frame);
346     layout->addWidget(quickEditLabel, row, 0, 1, 2);
347     m_quickEdit = new QCheckBox(frame);
348     connect(m_quickEdit, &QCheckBox::stateChanged, this, &NotationConfigurationPage::slotModified);
349     m_quickEdit->setChecked(quickEdit);
350     QString quickEditTip(tr(
351         "<p>If checked, the following features are usable while inserting notes"
352         " with the mouse:<ul>"
353         "<li>The mouse wheel selects the note duration</li>"
354         "<li>Shift adds a sharp</li>"
355         "<li>Ctrl adds a flat</li>"
356         "<li>Shift + Ctrl adds a natural</li>"
357         "<li>A mouse mid button click switches between notes and rests</li>"
358         "</ul></p>"));
359     quickEditLabel->setToolTip(quickEditTip);
360     m_quickEdit->setToolTip(quickEditTip);
361     layout->addWidget(m_quickEdit, row, 2, 1, 1);
362     ++row;
363 
364     layout->setRowStretch(row, 10);
365     frame->setLayout(layout);
366 
367     addTab(frame, tr("Editing"));
368 
369     frame = new QFrame(m_tabWidget);
370     frame->setContentsMargins(10, 10, 10, 10);
371     layout = new QGridLayout(frame);
372     layout->setSpacing(5);
373 
374     row = 0;
375 
376     layout->setRowMinimumHeight(row, 15);
377     ++row;
378 
379     layout->addWidget(new QLabel(tr("Accidentals in one octave..."), frame), row, 0);
380     m_accOctavePolicy = new QComboBox(frame);
381     connect(m_accOctavePolicy, SIGNAL(activated(int)), this, SLOT(slotModified()));
382     m_accOctavePolicy->addItem(tr("Affect only that octave"));
383     m_accOctavePolicy->addItem(tr("Require cautionaries in other octaves"));
384     m_accOctavePolicy->addItem(tr("Affect all subsequent octaves"));
385     int accOctaveMode = settings.value("accidentaloctavemode", 1).toInt() ;
386     if (accOctaveMode >= 0 && accOctaveMode < 3) {
387         m_accOctavePolicy->setCurrentIndex(accOctaveMode);
388     }
389     layout->addWidget(m_accOctavePolicy, row, 1);
390     ++row;
391 
392     layout->addWidget(new QLabel(tr("Accidentals in one bar..."), frame), row, 0);
393     m_accBarPolicy = new QComboBox(frame);
394     connect(m_accBarPolicy, SIGNAL(activated(int)), this, SLOT(slotModified()));
395     m_accBarPolicy->addItem(tr("Affect only that bar"));
396     m_accBarPolicy->addItem(tr("Require cautionary resets in following bar"));
397     m_accBarPolicy->addItem(tr("Require explicit resets in following bar"));
398     int accBarMode = settings.value("accidentalbarmode", 0).toInt() ;
399     if (accBarMode >= 0 && accBarMode < 3) {
400         m_accBarPolicy->setCurrentIndex(accBarMode);
401     }
402     layout->addWidget(m_accBarPolicy, row, 1);
403     ++row;
404 
405     layout->addWidget(new QLabel(tr("Key signature cancellation style"), frame), row, 0);
406     m_keySigCancelMode = new QComboBox(frame);
407     connect(m_keySigCancelMode, SIGNAL(activated(int)), this, SLOT(slotModified()));
408     m_keySigCancelMode->addItem(tr("Cancel only when entering C major or A minor"));
409     m_keySigCancelMode->addItem(tr("Cancel whenever removing sharps or flats"));
410     m_keySigCancelMode->addItem(tr("Cancel always"));
411     int cancelMode = settings.value("keysigcancelmode", 1).toInt() ;
412     if (cancelMode >= 0 && cancelMode < 3) {
413         m_keySigCancelMode->setCurrentIndex(cancelMode);
414     }
415     layout->addWidget(m_keySigCancelMode, row, 1);
416     ++row;
417 
418     layout->setRowStretch(row, 10);
419     frame->setLayout(layout);
420 
421     addTab(frame, tr("Accidentals"));
422 
423     row = 0;
424 
425     frame = new QFrame(m_tabWidget);
426     frame->setContentsMargins(10, 10, 10, 10);
427     layout = new QGridLayout(frame);
428     layout->setSpacing(5);
429 
430     layout->addWidget(new QLabel(tr("Notation font"), frame), 0, 0);
431 
432     m_font = new QComboBox(frame);
433     connect(m_font, SIGNAL(activated(int)), this, SLOT(slotModified()));
434 
435     layout->addWidget(m_font, row, 1, 1, 3);
436     m_font->setEditable(false);
437     QObject::connect(m_font, SIGNAL(activated(int)),
438                      this, SLOT(slotFontComboChanged(int)));
439     ++row;
440 
441     QFrame *subFrame = new QFrame(frame);
442     subFrame->setContentsMargins(12, 12, 12, 12);
443     QGridLayout *subLayout = new QGridLayout(subFrame);
444     subLayout->setSpacing(2);
445 
446     QFont font = m_font->font();
447     font.setPointSize((font.pointSize() * 9) / 10);
448 
449     QLabel *originLabel = new QLabel(tr("Origin:"), subFrame);
450     originLabel->setFont(font);
451     subLayout->addWidget(originLabel, 0, 0);
452 
453     QLabel *copyrightLabel = new QLabel(tr("Copyright:"), subFrame);
454     copyrightLabel->setFont(font);
455     subLayout->addWidget(copyrightLabel, 1, 0);
456 
457     QLabel *mappedLabel = new QLabel(tr("Mapped by:"), subFrame);
458     mappedLabel->setFont(font);
459     subLayout->addWidget(mappedLabel, 2, 0);
460 
461     QLabel *typeLabel = new QLabel(tr("Type:"), subFrame);
462     typeLabel->setFont(font);
463     subLayout->addWidget(typeLabel, 3, 0);
464 
465     m_fontOriginLabel = new QLabel(subFrame);
466     m_fontOriginLabel->setWordWrap(true);
467     m_fontOriginLabel->setFont(font);
468     m_fontCopyrightLabel = new QLabel(subFrame);
469     m_fontCopyrightLabel->setWordWrap(true);
470     m_fontCopyrightLabel->setFont(font);
471     m_fontMappedByLabel = new QLabel(subFrame);
472     m_fontMappedByLabel->setFont(font);
473     m_fontTypeLabel = new QLabel(subFrame);
474     m_fontTypeLabel->setFont(font);
475     subLayout->addWidget(m_fontOriginLabel, 0, 1);
476     subLayout->addWidget(m_fontCopyrightLabel, 1, 1);
477     subLayout->addWidget(m_fontMappedByLabel, 2, 1);
478     subLayout->addWidget(m_fontTypeLabel, 3, 1);
479 
480     subLayout->setColumnStretch(1, 10);
481     subFrame->setLayout(subLayout);
482 
483     layout->addWidget(subFrame, row, 0, 1, 4);
484     ++row;
485 
486     layout->addWidget
487         (new QLabel(tr("Font size for single-staff views"), frame),
488          row, 0, 1, 2);
489     m_singleStaffSize = new QComboBox(frame);
490     connect(m_singleStaffSize, SIGNAL(activated(int)), this, SLOT(slotModified()));
491     m_singleStaffSize->setEditable(false);
492     layout->addWidget(m_singleStaffSize, row, 2, 1, 1);
493     ++row;
494 
495     layout->addWidget
496         (new QLabel(tr("Font size for multi-staff views"), frame),
497          row, 0, 1, 2);
498     m_multiStaffSize = new QComboBox(frame);
499     connect(m_multiStaffSize, SIGNAL(activated(int)), this, SLOT(slotModified()));
500     m_multiStaffSize->setEditable(false);
501     layout->addWidget(m_multiStaffSize, row, 2, 1, 1);
502     ++row;
503 
504     slotPopulateFontCombo(false);
505 
506     layout->setRowMinimumHeight(row, 15);
507     ++row;
508 
509     QFont defaultTextFont(NotePixmapFactory::defaultSerifFontFamily);
510 
511     layout->addWidget
512         (new QLabel(tr("Text font"), frame), row, 0);
513     m_textFont = new FontRequester(frame);
514     connect(m_textFont, &FontRequester::fontChanged, this, &NotationConfigurationPage::slotModified);
515     QFont textFont = defaultTextFont;
516     QVariant fv = settings.value("textfont", textFont);
517     if (fv.canConvert<QFont>()) textFont = fv.value<QFont>();
518     m_textFont->setFont(textFont);
519     layout->addWidget(m_textFont, row, 1, 1, 3);
520     ++row;
521 
522     layout->addWidget
523         (new QLabel(tr("Sans-serif font"), frame), row, 0);
524     m_sansFont = new FontRequester(frame);
525     connect(m_sansFont, &FontRequester::fontChanged, this, &NotationConfigurationPage::slotModified);
526     QFont sansFont = defaultTextFont;
527     fv = settings.value("sansfont", sansFont);
528     if (fv.canConvert<QFont>()) sansFont = fv.value<QFont>();
529     m_sansFont->setFont(sansFont);
530     layout->addWidget(m_sansFont, row, 1, 1, 3);
531     ++row;
532 
533     frame->setLayout(layout);
534 
535     addTab(frame, tr("Font"));
536 
537 
538     // Beginning of "Segments" tab
539 
540     frame = new QFrame(m_tabWidget);
541     frame->setContentsMargins(10, 10, 10, 10);
542     layout = new QGridLayout(frame);
543     layout->setSpacing(5);
544 
545     row = 0;
546 
547     layout->setRowMinimumHeight(row, 15);
548     ++row;
549 
550     layout->addWidget
551         (new QLabel
552          (tr("Show repeated segments"), frame),
553          row, 0, 1, 2);
554     m_showRepeated = new QCheckBox(frame);
555     connect(m_showRepeated, &QCheckBox::stateChanged,
556             this, &NotationConfigurationPage::slotModified);
557     bool defaultShowRepeated = qStrToBool(settings.value("showrepeated",
558                                                          "true")) ;
559     m_showRepeated->setChecked(defaultShowRepeated);
560     layout->addWidget(m_showRepeated, row, 2);
561     ++row;
562 
563     layout->addWidget
564         (new QLabel
565          (tr("Allow direct edition of repeated segments"), frame),
566          row, 0, 1, 2);
567     m_editRepeated = new QCheckBox(frame);
568     connect(m_editRepeated, &QCheckBox::stateChanged,
569             this, &NotationConfigurationPage::slotModified);
570     bool defaultEditRepeated = qStrToBool(settings.value("editrepeated",
571                                                          "false")) ;
572     m_editRepeated->setChecked(defaultEditRepeated);
573     layout->addWidget(m_editRepeated, row, 2);
574     ++row;
575 
576     layout->addWidget
577         (new QLabel
578          (tr("Hide redundant clefs and keys"), frame),
579          row, 0, 1, 2);
580     m_hideRedundantClefKey = new QCheckBox(frame);
581     connect(m_hideRedundantClefKey, &QCheckBox::stateChanged,
582             this, &NotationConfigurationPage::slotModified);
583     bool defaultHideRedundantClefKey =
584         qStrToBool(settings.value("hideredundantclefkey", "true")) ;
585     m_hideRedundantClefKey->setChecked(defaultHideRedundantClefKey);
586     layout->addWidget(m_hideRedundantClefKey, row, 2);
587     ++row;
588 
589     layout->addWidget
590         (new QLabel
591          (tr("Distribute verses among repeated segments"), frame),
592          row, 0, 1, 2);
593     m_distributeVerses = new QCheckBox(frame);
594     connect(m_distributeVerses, &QCheckBox::stateChanged,
595             this, &NotationConfigurationPage::slotModified);
596     bool defaultDistributeVerses =
597         qStrToBool(settings.value("distributeverses", "true")) ;
598     m_distributeVerses->setChecked(defaultDistributeVerses);
599     layout->addWidget(m_distributeVerses, row, 2);
600     ++row;
601 
602 
603     layout->setRowStretch(row, 10);
604     frame->setLayout(layout);
605 
606     addTab(frame, tr("Segments"));
607 
608     // End of "Segments" tab
609 
610     settings.endGroup();
611 }
612 
613 void
slotPopulateFontCombo(bool rescan)614 NotationConfigurationPage::slotPopulateFontCombo(bool rescan)
615 {
616     QSettings settings;
617     settings.beginGroup(NotationViewConfigGroup);
618 
619     QString defaultFont = settings.value
620         ("notefont", NoteFontFactory::getDefaultFontName()).toString();
621     settings.endGroup();
622 
623     try {
624         (void)NoteFontFactory::getFont
625             (defaultFont, NoteFontFactory::getDefaultSize(defaultFont));
626     } catch (const Exception &e) {
627         defaultFont = NoteFontFactory::getDefaultFontName();
628     }
629 
630     std::set<QString> fs(NoteFontFactory::getFontNames(rescan));
631     std::vector<QString> f;
632     for (std::set<QString>::const_iterator i = fs.begin(); i != fs.end(); ++i) {
633         f.push_back(*i);
634     }
635     std::sort(f.begin(), f.end());
636 
637     m_untranslatedFont.clear();
638     m_font->clear();
639 
640     for (std::vector<QString>::const_iterator i = f.begin(); i != f.end(); ++i) {
641         QString s(*i);
642         m_untranslatedFont.append(s);
643         m_font->addItem(s);
644         if (s == defaultFont) m_font->setCurrentIndex(m_font->count() - 1);
645     }
646 
647     slotFontComboChanged(m_font->currentIndex());
648 }
649 
650 void
slotFontComboChanged(int index)651 NotationConfigurationPage::slotFontComboChanged(int index)
652 {
653     QString fontStr = m_untranslatedFont[index];
654 
655     QSettings settings;
656     settings.beginGroup(NotationViewConfigGroup);
657 
658     populateSizeCombo
659         (m_singleStaffSize, fontStr,
660          settings.value("singlestaffnotesize",
661                         NoteFontFactory::getDefaultSize(fontStr)).toInt());
662     // I remember Chris talking recently about how the default for multiple
663     // staffs was supposed to be 6 instead of 8 or something like that.
664     // getDefaultMultiSize didn't exist until just now, and this was true in
665     // Classic.  That never would have worked.
666     populateSizeCombo
667         (m_multiStaffSize, fontStr,
668          settings.value("multistaffnotesize",
669                         NoteFontFactory::getDefaultMultiSize(fontStr)).toInt());
670     settings.endGroup();
671 
672     try {
673         NoteFont *noteFont = NoteFontFactory::getFont
674                              (fontStr, NoteFontFactory::getDefaultSize(fontStr));
675         const NoteFontMap &map(noteFont->getNoteFontMap());
676         m_fontOriginLabel->setText(tr(map.getOrigin().toStdString().c_str()));
677         m_fontCopyrightLabel->setText(tr(map.getCopyright().toStdString().c_str()));
678         m_fontMappedByLabel->setText(tr(map.getMappedBy().toStdString().c_str()));
679         if (map.isSmooth()) {
680             m_fontTypeLabel->setText(tr("%1 (smooth)").arg(tr(map.getType().toStdString().c_str())));
681         } else {
682             m_fontTypeLabel->setText(tr("%1 (jaggy)").arg(tr(map.getType().toStdString().c_str())));
683         }
684     } catch (const Exception &f) {
685         QMessageBox::critical(nullptr, tr("Rosegarden"), strtoqstr(f.getMessage()));
686     }
687 }
688 
689 void
populateSizeCombo(QComboBox * combo,QString font,int defaultSize)690 NotationConfigurationPage::populateSizeCombo(QComboBox *combo,
691                                              QString font,
692                                              int defaultSize)
693 {
694     std::vector<int> sizes = NoteFontFactory::getScreenSizes(font);
695     combo->clear();
696 
697     for (std::vector<int>::iterator i = sizes.begin(); i != sizes.end(); ++i) {
698         combo->addItem(QString("%1").arg(*i));
699         if (*i == defaultSize)
700             combo->setCurrentIndex(combo->count() - 1);
701     }
702 }
703 
704 void
apply()705 NotationConfigurationPage::apply()
706 {
707     QSettings settings;
708     settings.beginGroup(NotationViewConfigGroup);
709 
710     settings.setValue("notefont", m_untranslatedFont[m_font->currentIndex()]);
711     settings.setValue("singlestaffnotesize",
712                       m_singleStaffSize->currentText().toUInt());
713     settings.setValue("multistaffnotesize",
714                       m_multiStaffSize->currentText().toUInt());
715     settings.setValue("textfont", m_textFont->getFont());
716     settings.setValue("sansfont", m_sansFont->getFont());
717 
718     settings.setValue("layoutmode", m_layoutMode->currentIndex());
719     settings.setValue("colourquantize", m_colourQuantize->isChecked());
720     settings.setValue("showunknowns", m_showUnknowns->isChecked());
721     settings.setValue("showinvisibles", m_showInvisibles->isChecked());
722     settings.setValue("showranges", m_showRanges->isChecked());
723     settings.setValue("showcollisions", m_showCollisions->isChecked());
724     settings.setValue("shownotationheader",
725                        m_showTrackHeaders->currentIndex());
726     settings.setValue("style", m_untranslatedNoteStyle[m_noteStyle->currentIndex()]);
727     settings.setValue("inserttype", m_insertType->currentIndex());
728     settings.setValue("autobeam", m_autoBeam->isChecked());
729     settings.setValue("autotieatbarlines", m_autoTieBarlines->isChecked());
730     settings.setValue("collapse", m_collapseRests->isChecked());
731     settings.setValue("pastetype", m_pasteType->currentIndex());
732     settings.setValue("alwayspreview", m_preview->isChecked());
733     settings.setValue("quickedit", m_quickEdit->isChecked());
734 
735     settings.setValue("accidentaloctavemode", m_accOctavePolicy->currentIndex());
736     settings.setValue("accidentalbarmode", m_accBarPolicy->currentIndex());
737     settings.setValue("keysigcancelmode", m_keySigCancelMode->currentIndex());
738 
739     settings.setValue("quantizemakeviable", m_splitAndTie->isChecked());
740 
741     settings.setValue("showrepeated", m_showRepeated->isChecked());
742     settings.setValue("editrepeated", m_editRepeated->isChecked());
743     settings.setValue("hideredundantclefkey",
744                        m_hideRedundantClefKey->isChecked());
745     settings.setValue("distributeverses",
746                        m_distributeVerses->isChecked());
747 
748     settings.endGroup();
749 }
750 
751 }
752