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 #include "MusicXMLOptionsDialog.h"
19 
20 #include "misc/ConfigGroups.h"
21 #include "document/RosegardenDocument.h"
22 #include "gui/configuration/HeadersConfigurationPage.h"
23 #include "misc/Strings.h"
24 #include "misc/Debug.h"
25 
26 #include <QApplication>
27 #include <QCheckBox>
28 #include <QComboBox>
29 #include <QDialog>
30 #include <QDialogButtonBox>
31 #include <QUrl>
32 #include <QDesktopServices>
33 #include <QFrame>
34 #include <QGridLayout>
35 #include <QGroupBox>
36 #include <QLabel>
37 #include <QLayout>
38 #include <QSettings>
39 #include <QString>
40 #include <QTabWidget>
41 #include <QToolTip>
42 #include <QVBoxLayout>
43 #include <QWidget>
44 #include <QLocale>
45 
46 #include <iostream>
47 
48 
49 namespace Rosegarden
50 {
51 
MusicXMLOptionsDialog(QWidget * parent,RosegardenDocument * doc,QString windowCaption,QString)52 MusicXMLOptionsDialog::MusicXMLOptionsDialog(QWidget *parent,
53                                              RosegardenDocument *doc,
54                                              QString windowCaption,
55                                              QString /* heading */) :
56                        QDialog(parent),
57                        m_doc(doc)
58 {
59     setModal(true);
60     setWindowTitle((windowCaption == "" ? tr("MusicXML Export") : windowCaption));
61 
62     QGridLayout *metaGridLayout = new QGridLayout;
63 
64     QWidget *mainbox = new QWidget(this);
65     QVBoxLayout *mainboxLayout = new QVBoxLayout;
66     metaGridLayout->addWidget(mainbox, 0, 0);
67 
68     //
69     // Arrange options in "Layout" and "Headers" tabs.
70     //
71 
72     QTabWidget *tabWidget = new QTabWidget(mainbox);
73     mainboxLayout->addWidget(tabWidget);
74 
75     QFrame *layoutFrame = new QFrame();
76     tabWidget->addTab(layoutFrame, tr("Layout"));
77 
78     layoutFrame->setContentsMargins(5, 5, 5, 5);
79     QGridLayout *layoutGrid = new QGridLayout;
80     layoutGrid->setSpacing(5);
81 
82     m_headersPage = new HeadersConfigurationPage(this, m_doc);
83     tabWidget->addTab(m_headersPage, tr("Headers"));
84 
85     //
86     // MusicXML export: Basic options
87     //
88 
89     QGroupBox *basicOptionsBox = new QGroupBox(tr("Basic options"), layoutFrame);
90     QVBoxLayout *basicOptionsBoxLayout = new QVBoxLayout;
91 
92     layoutGrid->addWidget(basicOptionsBox, 0, 0);
93     QFrame *frameBasic = new QFrame(basicOptionsBox);
94     frameBasic->setContentsMargins(10, 10, 10, 10);
95     QGridLayout *layoutBasic = new QGridLayout;
96     layoutBasic->setSpacing(5);
97     basicOptionsBoxLayout->addWidget(frameBasic);
98 
99     frameBasic->setMinimumWidth(250);
100 
101     layoutBasic->addWidget(new QLabel(tr("Export content"), frameBasic), 0, 0);
102     m_mxmlExportSelection = new QComboBox(frameBasic);
103     m_mxmlExportSelection->setToolTip(tr("<qt>Choose which tracks or segments to export</qt>"));
104     m_mxmlExportSelection->addItem(tr("All tracks"));
105     m_mxmlExportSelection->addItem(tr("Non-muted tracks"));
106     m_mxmlExportSelection->addItem(tr("Selected track"));
107     m_mxmlExportSelection->addItem(tr("Selected segments"));
108     layoutBasic->addWidget(m_mxmlExportSelection, 0, 1);
109 
110     m_mxmlExportStaffGroup = new QCheckBox(tr("Export track staff brackets"), frameBasic);
111     layoutBasic->addWidget(m_mxmlExportStaffGroup, 1, 0, 1, 2);
112     m_mxmlExportStaffGroup->setToolTip(tr("<qt>Track staff brackets are found in the <b>Track Parameters</b> box, and may be used to group staffs in various ways</qt>"));
113 
114     //
115     // MusicXML export: Advanced options
116     //
117 
118     QGroupBox *specificOptionsBox = new QGroupBox(tr("Advanced/Experimental options"), layoutFrame);
119     QVBoxLayout *specificOptionsBoxLayout = new QVBoxLayout;
120     layoutGrid->addWidget(specificOptionsBox, 2, 0);
121 
122     QFrame *frameAdvanced = new QFrame(specificOptionsBox);
123     frameAdvanced->setContentsMargins(10, 10, 10, 10);
124     QGridLayout *layoutAdvanced = new QGridLayout;
125     layoutAdvanced->setSpacing(5);
126     specificOptionsBoxLayout->addWidget(frameAdvanced);
127 
128     // Music XML version/
129     layoutAdvanced->addWidget(new QLabel(tr("Compatibility level"), frameBasic), 0, 0);
130     m_mxmlVersion = new QComboBox(frameAdvanced);
131     m_mxmlVersion->setToolTip(tr("<qt>Set the MusicXML version you want export</qt>"));
132     m_mxmlVersion->addItem("MusicXML 1.1");
133     m_mxmlVersion->addItem("MusicXML 2.0");
134     m_mxmlVersion->setSizeAdjustPolicy(QComboBox::AdjustToContents);
135     layoutAdvanced->addWidget(m_mxmlVersion, 0, 1);
136 
137     // part-wise or score-wise score.
138     layoutAdvanced->addWidget(new QLabel(tr("MusicXML type"), frameBasic), 1, 0);
139     m_mxmlDTDType = new QComboBox(frameBasic);
140     m_mxmlDTDType->setToolTip(tr("<qt><p>Choose the format of the MusicXML file.</p><p>The &quot;partwise&quot; format contains &quot;part&quot; elements that contain &quot;measure&quot; elements.  The &quot;timewise&quot; format reverses this ordering.</p></qt>"));
141     m_mxmlDTDType->addItem("partwise");
142     m_mxmlDTDType->addItem("timewise");
143     m_mxmlDTDType->setMinimumWidth(150);
144     layoutAdvanced->addWidget(m_mxmlDTDType, 1, 1);
145 
146     layoutAdvanced->addWidget(new QLabel(tr("Export grand staff instrument"), frameAdvanced), 2, 0);
147     m_mxmlMultiStave = new QComboBox(frameAdvanced);
148     m_mxmlMultiStave->addItem(tr("None"));
149     m_mxmlMultiStave->addItem("{[--  --]}");
150     m_mxmlMultiStave->addItem("{--  --}");
151     layoutAdvanced->addWidget(m_mxmlMultiStave, 2, 1);
152     m_mxmlMultiStave->setToolTip(tr("<qt>Choose which bracket will create a grand staff system</qt>"));
153 
154     m_mxmlExportPercussion = new QComboBox(frameAdvanced);
155     m_mxmlExportPercussion->addItem(tr("Don't export percussion tracks"));
156     m_mxmlExportPercussion->addItem("Export percussion as notes");
157     m_mxmlExportPercussion->addItem("Export percussion as percussion (experimental)");
158 
159     layoutAdvanced->addWidget(m_mxmlExportPercussion, 3, 0, 1, 2);
160     m_mxmlExportPercussion->setToolTip(
161         tr("<qt><p>Exporting percussion is still experimental.</p>Percussion can be exported &quot;as notes&quot; or &quot;as percussion.&quot;  When exporting &quot;as notes&quot; a percussion track is handled as a normal track.</p><p>If a track is exported &quot;as percussion&quot; it will be exported as a MusicXML percussion part. Since Rosegarden doesn't have percussion notation, MusicXML Export tries to convert the percussion track to percussion notation. This option is still <b>experimental</b>.</p></qt>"));
162 
163     m_mxmlUseOctaveShift = new QCheckBox(tr("Use \"<octave-shift>\" for transposing instruments"),
164                                          frameAdvanced);
165     layoutAdvanced->addWidget(m_mxmlUseOctaveShift, 4, 0, 1, 2);
166     m_mxmlUseOctaveShift->setToolTip(
167         tr("<qt><p>Some transposing instruments (like a tenor or baritone sax) transpose over more than one octave.  For such large transpositions some tools require an &quot;&lt;octave-shift&gt;&quot; element while other tools do not support this element at all.</p><p>When importing the MusicXML file into another tool, check transposing instruments carefully in both concert and notated pitch. When this is not correct toggling this option might help.</p></qt>"));
168 
169     layoutGrid->setRowStretch(4, 10);
170 
171     basicOptionsBox->setLayout(basicOptionsBoxLayout);
172     specificOptionsBox->setLayout(specificOptionsBoxLayout);
173 
174     layoutFrame->setLayout(layoutGrid);
175 
176     frameAdvanced->setLayout(layoutAdvanced);
177     frameBasic->setLayout(layoutBasic);
178 
179     mainbox->setLayout(mainboxLayout);
180 
181     QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Apply |
182                                                        QDialogButtonBox::Ok |
183                                                        QDialogButtonBox::Cancel |
184                                                        QDialogButtonBox::Help);
185     metaGridLayout->addWidget(buttonBox, 1, 0);
186     metaGridLayout->setRowStretch(0, 10);
187 
188     setLayout(metaGridLayout);
189 
190 
191     connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
192     connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
193     connect(buttonBox, &QDialogButtonBox::helpRequested, this, &MusicXMLOptionsDialog::help);
194 
195     populateDefaultValues();
196 
197     resize(minimumSizeHint());
198 }
199 
200 void
help()201 MusicXMLOptionsDialog::help()
202 {
203     // TRANSLATORS: if the manual is translated into your language, you can
204     // change the two-letter language code in this URL to point to your language
205     // version, eg. "http://rosegardenmusic.com/wiki/doc:manual-es" for the
206     // Spanish version. If your language doesn't yet have a translation, feel
207     // free to create one.
208     QString helpURL = tr("http://rosegardenmusic.com/wiki/doc:manual-musicxmlexportoptions-en");
209     QDesktopServices::openUrl(QUrl(helpURL));
210 }
211 
212 
213 void
populateDefaultValues()214 MusicXMLOptionsDialog::populateDefaultValues()
215 {
216     QSettings settings;
217     settings.beginGroup(MusicXMLExportConfigGroup);
218 
219     m_mxmlVersion->setCurrentIndex(settings.value("mxmlversion", 0).toUInt());
220     m_mxmlDTDType->setCurrentIndex(settings.value("mxmldtdtype", 0).toUInt());
221     m_mxmlExportSelection->setCurrentIndex(
222             settings.value("mxmlexportselection", 1).toUInt());
223     m_mxmlExportStaffGroup->setChecked(settings.value(
224             "mxmlexportstaffgroup", "true").toBool());
225     m_mxmlExportPercussion->setCurrentIndex(settings.value(
226             "mxmlexportpercussion", 0).toUInt());
227     m_mxmlUseOctaveShift->setChecked(settings.value(
228             "mxmluseoctaveshift", "true").toBool());
229     m_mxmlMultiStave->setCurrentIndex(settings.value("mxmlmultistave", 0).toUInt());
230 
231     settings.endGroup();
232 }
233 
234 
235 void
slotApply()236 MusicXMLOptionsDialog::slotApply()
237 {
238     QSettings settings;
239     settings.beginGroup(MusicXMLExportConfigGroup);
240 
241     settings.setValue("mxmlversion", m_mxmlVersion->currentIndex());
242     settings.setValue("mxmldtdtype", m_mxmlDTDType->currentIndex());
243     settings.setValue("mxmlexportselection", m_mxmlExportSelection->currentIndex());
244     settings.setValue("mxmlmultistave", m_mxmlMultiStave->currentIndex());
245     settings.setValue("mxmlexportstaffgroup", m_mxmlExportStaffGroup->isChecked());
246     settings.setValue("mxmlexportpercussion", m_mxmlExportPercussion->currentIndex());
247     settings.setValue("mxmluseoctaveshift", m_mxmlUseOctaveShift->isChecked());
248 
249     settings.endGroup();
250 
251     //! NOTE Does this sets the "document changed" flag???
252     //! apparantly! Why??????
253     //
254     // If you edit the headers, those are stored in the document, so the
255     // document might have changed when you have something to apply.  This could
256     // probably be handled in a more fine-grained and robust manner. -dmm
257     m_headersPage->apply();
258 }
259 
260 void
accept()261 MusicXMLOptionsDialog::accept()
262 {
263     slotApply();
264     QDialog::accept();
265 }
266 
267 }
268