1 //=========================================================
2 //  MusE
3 //  Linux Music Editor
4 //  $Id: conf.cpp,v 1.33.2.18 2009/12/01 03:52:40 terminator356 Exp $
5 //
6 //  (C) Copyright 1999-2003 Werner Schweer (ws@seh.de)
7 //
8 //  This program is free software; you can redistribute it and/or
9 //  modify it under the terms of the GNU General Public License
10 //  as published by the Free Software Foundation; version 2 of
11 //  the License, or (at your option) any later version.
12 //
13 //  This program is distributed in the hope that it will be useful,
14 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 //  GNU General Public License for more details.
17 //
18 //  You should have received a copy of the GNU General Public License
19 //  along with this program; if not, write to the Free Software
20 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 //
22 //=========================================================
23 
24 #include <QFile>
25 #include <QMessageBox>
26 #include <QString>
27 #include <QByteArray>
28 
29 #include <sndfile.h>
30 #include <errno.h>
31 #include <stdio.h>
32 
33 #include "app.h"
34 #include "transport.h"
35 #include "icons.h"
36 #include "globals.h"
37 #include "functions.h"
38 #include "drumedit.h"
39 #include "pianoroll.h"
40 #include "scoreedit.h"
41 #include "master/masteredit.h"
42 //#include "listedit.h"
43 #include "cliplist/cliplist.h"
44 #include "arrangerview.h"
45 #include "marker/markerview.h"
46 //#include "master/lmaster.h"
47 #include "bigtime.h"
48 //#include "arranger.h"
49 #include "conf.h"
50 #include "gconfig.h"
51 #include "pitchedit.h"
52 #include "midiport.h"
53 #include "mididev.h"
54 #include "instruments/minstrument.h"
55 #include "driver/audiodev.h"
56 #include "driver/jackmidi.h"
57 #include "driver/alsamidi.h"
58 #include "waveedit.h"
59 #include "midi_consts.h"
60 #include "midisyncimpl.h"
61 #include "midifilterimpl.h"
62 #include "midictrl.h"
63 #include "ctrlcombo.h"
64 #include "genset.h"
65 #include "midiitransform.h"
66 #include "synth.h"
67 #include "audio.h"
68 #include "sync.h"
69 #include "wave.h"
70 #include "midiseq.h"
71 #include "amixer.h"
72 #include "track.h"
73 #include "plugin.h"
74 #include "audio_convert/audio_converter_settings_group.h"
75 #include "filedialog.h"
76 #include "al/al.h"
77 #include "shortcuts.h"
78 #include "synthdialog.h"
79 
80 namespace MusECore {
81 
82 extern void writeMidiTransforms(int level, Xml& xml);
83 extern void readMidiTransform(Xml&);
84 
85 extern void writeMidiInputTransforms(int level, Xml& xml);
86 extern void readMidiInputTransform(Xml&);
87 
88 //---------------------------------------------------------
89 //   readController
90 //---------------------------------------------------------
91 
readController(Xml & xml,int midiPort,int channel)92 static void readController(Xml& xml, int midiPort, int channel)
93       {
94       int id = 0;
95       int val = CTRL_VAL_UNKNOWN;
96 
97       for (;;) {
98             Xml::Token token = xml.parse();
99             QString tag = xml.s1();
100             switch (token) {
101                   case Xml::TagStart:
102                         if (tag == "val")
103                               val = xml.parseInt();
104                         else
105                               xml.unknown("controller");
106                         break;
107                   case Xml::Attribut:
108                         if (tag == "id")
109                               id = xml.s2().toInt();
110                         break;
111                   case Xml::TagEnd:
112                         if (tag == "controller") {
113                               MidiPort* port = &MusEGlobal::midiPorts[midiPort];
114                               val = port->limitValToInstrCtlRange(id, val, channel);
115                               // The value here will actually be sent to the device LATER, in MidiPort::setMidiDevice()
116                               port->setHwCtrlState(channel, id, val);
117                               return;
118                               }
119                   default:
120                         return;
121                   }
122             }
123       }
124 
125 //---------------------------------------------------------
126 //   readPortChannel
127 //---------------------------------------------------------
128 
readPortChannel(Xml & xml,int midiPort)129 static void readPortChannel(Xml& xml, int midiPort)
130       {
131       int idx = 0;  //torbenh
132       for (;;) {
133             Xml::Token token = xml.parse();
134             if (token == Xml::Error || token == Xml::End)
135                   break;
136             QString tag = xml.s1();
137             switch (token) {
138                   case Xml::TagStart:
139                         if (tag == "controller") {
140                               readController(xml, midiPort, idx);
141                               }
142                         else
143                               xml.unknown("MidiDevice");
144                         break;
145                   case Xml::Attribut:
146                         if (tag == "idx")
147                               idx = xml.s2().toInt();
148                         break;
149                   case Xml::TagEnd:
150                         if (tag == "channel")
151                               return;
152                   default:
153                         break;
154                   }
155             }
156       }
157 
158 //---------------------------------------------------------
159 //   readConfigMidiDevice
160 //---------------------------------------------------------
161 
readConfigMidiDevice(Xml & xml)162 static void readConfigMidiDevice(Xml& xml)
163       {
164       QString device;
165       int rwFlags = 3;
166       int openFlags = 1;
167       int type = MidiDevice::ALSA_MIDI;
168 
169       for (;;) {
170             Xml::Token token = xml.parse();
171             if (token == Xml::Error || token == Xml::End)
172                   break;
173             QString tag = xml.s1();
174             switch (token) {
175                   case Xml::TagStart:
176                         if (tag == "name")
177                               device = xml.parse1();
178                         else if (tag == "type")
179                               type = xml.parseInt();
180                         else if (tag == "openFlags")
181                               openFlags = xml.parseInt();
182                         else if (tag == "rwFlags")             // Jack midi devs need this.
183                               rwFlags = xml.parseInt();
184                         else
185                               xml.unknown("MidiDevice");
186                         break;
187                   case Xml::Attribut:
188                         break;
189                   case Xml::TagEnd:
190                         if (tag == "mididevice") {
191                               MidiDevice* dev = MusEGlobal::midiDevices.find(device, type);
192 
193                               if(!dev)
194                               {
195                                 if(type == MidiDevice::JACK_MIDI)
196                                 {
197                                   if(MusEGlobal::debugMsg)
198                                     fprintf(stderr, "readConfigMidiDevice: creating jack midi device %s with rwFlags:%d\n", device.toLatin1().constData(), rwFlags);
199                                   dev = MidiJackDevice::createJackMidiDevice(device, rwFlags);
200                                 }
201 #ifdef ALSA_SUPPORT
202                                 else
203                                 if(type == MidiDevice::ALSA_MIDI)
204                                 {
205                                   if(MusEGlobal::debugMsg)
206                                     fprintf(stderr, "readConfigMidiDevice: creating ALSA midi device %s with rwFlags:%d\n", device.toLatin1().constData(), rwFlags);
207                                   dev = MidiAlsaDevice::createAlsaMidiDevice(device, rwFlags);
208                                 }
209 #endif
210                               }
211 
212                               if(MusEGlobal::debugMsg && !dev)
213                                 fprintf(stderr, "readConfigMidiDevice: device not found %s\n", device.toLatin1().constData());
214 
215                               if (dev) {
216                                     dev->setOpenFlags(openFlags);
217                                     }
218                               return;
219                               }
220                   default:
221                         break;
222                   }
223             }
224       }
225 
226 //---------------------------------------------------------
227 //   readConfigMidiPort
228 //---------------------------------------------------------
229 
readConfigMidiPort(Xml & xml,bool onlyReadChannelState)230 static void readConfigMidiPort(Xml& xml, bool onlyReadChannelState)
231       {
232       int idx = 0;
233       QString device;
234 
235       // Let's be bold. New users have been confused by generic midi not enabling any patches and controllers.
236       // I had said this may cause HW problems by sending out GM sysEx when really the HW might not be GM.
237       // But this really needs to be done, one way or another.
238       // FIXME: TODO: Make this user-configurable!
239       QString instrument("GM");
240 
241       int rwFlags = 3;
242       int openFlags = 1;
243       int dic = -1;
244       int doc = -1;
245       int trackIdx = -1;
246 
247       MidiSyncInfo tmpSi;
248       int type = MidiDevice::ALSA_MIDI;
249       bool pre_mididevice_ver_found = false;
250 
251       for (;;) {
252             Xml::Token token = xml.parse();
253             if (token == Xml::Error || token == Xml::End)
254                   break;
255             QString tag = xml.s1();
256             switch (token) {
257                   case Xml::TagStart:
258 
259                         // onlyReadChannelState added so it doesn't overwrite midi ports.   p4.0.41 Tim.
260                         // Try to keep the controller information. But, this may need to be moved below.
261                         // Also may want to try to keep sync info, but that's a bit risky, so let's not for now.
262                         if (tag == "channel") {
263                               readPortChannel(xml, idx);
264                               break;
265                               }
266                         else if (onlyReadChannelState){
267                               xml.skip(tag);
268                               break;
269                               }
270 
271                         if (tag == "name")
272                               device = xml.parse1();
273                         else if (tag == "type")
274                         {
275                               pre_mididevice_ver_found = true;
276                               type = xml.parseInt();
277                         }
278                         else if (tag == "record") {         // old
279                               pre_mididevice_ver_found = true;
280                               bool f = xml.parseInt();
281                               if (f)
282                                     openFlags |= 2;
283                               }
284                         else if (tag == "openFlags")
285                         {
286                               pre_mididevice_ver_found = true;
287                               openFlags = xml.parseInt();
288                         }
289                         else if (tag == "rwFlags")             // Jack midi devs need this.
290                         {
291                               pre_mididevice_ver_found = true;
292                               rwFlags = xml.parseInt();
293                         }
294                         else if (tag == "defaultInChans")
295                               dic = xml.parseInt();
296                         else if (tag == "defaultOutChans")
297                               doc = xml.parseInt();
298                         else if (tag == "midiSyncInfo")
299                               tmpSi.read(xml);
300                         else if (tag == "instrument") {
301                               instrument = xml.parse1();
302                               //MusEGlobal::midiPorts[idx].setInstrument(    // Moved below
303                               //   registerMidiInstrument(instrument)
304                               //   );
305                               }
306                         else if (tag == "trackIdx") {
307                               trackIdx = xml.parseInt();
308                               }
309                         else if (tag == "midithru")
310                         {
311                               pre_mididevice_ver_found = true;
312                               xml.parseInt(); // obsolete
313                         }
314                         //else if (tag == "channel") {
315                         //      readPortChannel(xml, idx);   // Moved above
316                         //      }
317                         else
318                               xml.unknown("MidiDevice");
319                         break;
320                   case Xml::Attribut:
321                         if (tag == "idx") {
322                               idx = xml.s2().toInt();
323                               }
324                         break;
325                   case Xml::TagEnd:
326                         if (tag == "midiport") {
327 
328                               if(onlyReadChannelState)      // p4.0.41
329                                 return;
330 
331                               if (idx < 0 || idx >= MusECore::MIDI_PORTS) {
332                                     fprintf(stderr, "bad midi port %d (>%d)\n",
333                                        idx, MusECore::MIDI_PORTS);
334                                     idx = 0;
335                                     }
336 
337                               MidiDevice* dev = MusEGlobal::midiDevices.find(device, pre_mididevice_ver_found ? type : -1);
338 
339                               if(!dev && type == MidiDevice::JACK_MIDI)
340                               {
341                                 if(MusEGlobal::debugMsg)
342                                   fprintf(stderr, "readConfigMidiPort: creating jack midi device %s with rwFlags:%d\n", device.toLatin1().constData(), rwFlags);
343                                 dev = MidiJackDevice::createJackMidiDevice(device, rwFlags);
344                               }
345 
346                               if(MusEGlobal::debugMsg && !dev)
347                                 fprintf(stderr, "readConfigMidiPort: device not found %s\n", device.toLatin1().constData());
348 
349                               MidiPort* mp = &MusEGlobal::midiPorts[idx];
350 
351                               mp->setDefaultOutChannels(0); // reset output channel to take care of the case where no default is specified
352 
353                               // Just set the generic instrument for now.
354                               mp->changeInstrument(genericMidiInstrument);
355                               // Set references to be resolved later...
356                               mp->setTmpFileRefs(trackIdx, instrument);
357 
358                               if(dic != -1)                      // p4.0.17 Leave them alone unless set by song.
359                                 mp->setDefaultInChannels(dic);
360                               if(doc != -1)
361                                 // p4.0.17 Turn on if and when multiple output routes supported.
362                                 #if 0
363                                 mp->setDefaultOutChannels(doc);
364                                 #else
365                                 setPortExclusiveDefOutChan(idx, doc);
366                                 #endif
367 
368                               mp->syncInfo().copyParams(tmpSi);
369                               // p3.3.50 Indicate the port was found in the song file, even if no device is assigned to it.
370                               mp->setFoundInSongFile(true);
371 
372                               if (dev) {
373                                     if(pre_mididevice_ver_found)
374                                       dev->setOpenFlags(openFlags);
375                                     MusEGlobal::audio->msgSetMidiDevice(mp, dev);
376                                     }
377 
378                               return;
379                               }
380                   default:
381                         break;
382                   }
383             }
384       }
385 
386 //---------------------------------------------------------
387 //   loadConfigMetronom
388 //---------------------------------------------------------
389 
loadConfigMetronom(Xml & xml,MetronomeSettings * metro_settings)390 static void loadConfigMetronom(Xml& xml, MetronomeSettings* metro_settings)
391       {
392       for (;;) {
393             Xml::Token token = xml.parse();
394             if (token == Xml::Error || token == Xml::End)
395                   break;
396             QString tag = xml.s1();
397             switch (token) {
398                   case Xml::TagStart:
399                         if (tag == "premeasures")
400                               metro_settings->preMeasures = xml.parseInt();
401                         else if (tag == "measurepitch")
402                               metro_settings->measureClickNote = xml.parseInt();
403                         else if (tag == "measurevelo")
404                               metro_settings->measureClickVelo = xml.parseInt();
405                         else if (tag == "beatpitch")
406                               metro_settings->beatClickNote = xml.parseInt();
407                         else if (tag == "beatvelo")
408                               metro_settings->beatClickVelo = xml.parseInt();
409                         else if (tag == "accentpitch1")
410                               metro_settings->accentClick1 = xml.parseInt();
411                         else if (tag == "accentpitch2")
412                               metro_settings->accentClick2 = xml.parseInt();
413                         else if (tag == "accentvelo1")
414                               metro_settings->accentClick1Velo = xml.parseInt();
415                         else if (tag == "accentvelo2")
416                               metro_settings->accentClick2Velo = xml.parseInt();
417                         else if (tag == "channel")
418                               metro_settings->clickChan = xml.parseInt();
419                         else if (tag == "port")
420                               metro_settings->clickPort = xml.parseInt();
421                         else if (tag == "precountEnable")
422                               metro_settings->precountEnableFlag = xml.parseInt();
423                         else if (tag == "fromMastertrack")
424                               metro_settings->precountFromMastertrackFlag = xml.parseInt();
425                         else if (tag == "signatureZ")
426                               metro_settings->precountSigZ = xml.parseInt();
427                         else if (tag == "signatureN")
428                               metro_settings->precountSigN = xml.parseInt();
429                         else if (tag == "precountOnPlay")
430                               metro_settings->precountOnPlay = xml.parseInt();
431                         else if (tag == "precountMuteMetronome")
432                               metro_settings->precountMuteMetronome = xml.parseInt();
433                         else if (tag == "prerecord")
434                               metro_settings->precountPrerecord = xml.parseInt();
435                         else if (tag == "preroll")
436                               metro_settings->precountPreroll = xml.parseInt();
437                         else if (tag == "midiClickEnable")
438                               metro_settings->midiClickFlag = xml.parseInt();
439                         else if (tag == "audioClickEnable")
440                               metro_settings->audioClickFlag = xml.parseInt();
441                         else if (tag == "audioClickVolume")
442                               metro_settings->audioClickVolume = xml.parseFloat();
443                         else if (tag == "measClickVolume")
444                               metro_settings->measClickVolume = xml.parseFloat();
445                         else if (tag == "beatClickVolume")
446                               metro_settings->beatClickVolume = xml.parseFloat();
447                         else if (tag == "accent1ClickVolume")
448                               metro_settings->accent1ClickVolume = xml.parseFloat();
449                         else if (tag == "accent2ClickVolume")
450                               metro_settings->accent2ClickVolume = xml.parseFloat();
451                         else if (tag == "clickSamples")
452                               metro_settings->clickSamples = (MetronomeSettings::ClickSamples)xml.parseInt();
453                         else if (tag == "beatSample")
454                               metro_settings->beatSample = xml.parse1();
455                         else if (tag == "measSample")
456                               metro_settings->measSample = xml.parse1();
457                         else if (tag == "accent1Sample")
458                               metro_settings->accent1Sample = xml.parse1();
459                         else if (tag == "accent2Sample")
460                               metro_settings->accent2Sample = xml.parse1();
461                         else if (tag == "metroUseSongSettings")
462                               MusEGlobal::metroUseSongSettings = xml.parseInt();
463                         else if (tag == "metroAccPresets")
464                               MusEGlobal::metroAccentPresets.read(xml);
465                         else if (tag == "metroAccMap")
466                         {
467                               if(metro_settings->metroAccentsMap)
468                                 metro_settings->metroAccentsMap->read(xml);
469                         }
470                         else
471                               xml.unknown("Metronome");
472                         break;
473                   case Xml::TagEnd:
474                         if (tag == "metronom")
475                               return;
476                   default:
477                         break;
478                   }
479             }
480       }
481 
482 //---------------------------------------------------------
483 //   readSeqConfiguration
484 //---------------------------------------------------------
485 
readSeqConfiguration(Xml & xml,MetronomeSettings * metro_settings,bool skipMidiPorts)486 static void readSeqConfiguration(Xml& xml, MetronomeSettings* metro_settings, bool skipMidiPorts)
487       {
488       for (;;) {
489             Xml::Token token = xml.parse();
490             if (token == Xml::Error || token == Xml::End)
491                   break;
492             const QString& tag = xml.s1();
493             switch (token) {
494                   case Xml::TagStart:
495                         if (tag == "metronom")
496                               loadConfigMetronom(xml, metro_settings);
497                         else if (tag == "mididevice")
498                               readConfigMidiDevice(xml);
499                         else if (tag == "midiport")
500                               readConfigMidiPort(xml, skipMidiPorts);
501 
502                         else if (tag == "rcStop")
503                               MusEGlobal::rcStopNote = xml.parseInt();
504                         else if (tag == "rcEnable")
505                               MusEGlobal::rcEnable = xml.parseInt();
506                         else if (tag == "rcRecord")
507                               MusEGlobal::rcRecordNote = xml.parseInt();
508                         else if (tag == "rcGotoLeft")
509                               MusEGlobal::rcGotoLeftMarkNote = xml.parseInt();
510                         else if (tag == "rcPlay")
511                               MusEGlobal::rcPlayNote = xml.parseInt();
512                         else if (tag == "rcSteprec")
513                               MusEGlobal::rcSteprecNote = xml.parseInt();
514                         else if (tag == "rcForward")
515                             MusEGlobal::rcForwardNote = xml.parseInt();
516                         else if (tag == "rcRewind")
517                             MusEGlobal::rcBackwardNote = xml.parseInt();
518 
519                         else if (tag == "rcEnableCC")
520                             MusEGlobal::rcEnableCC = xml.parseInt();
521                         else if (tag == "rcStopCC")
522                             MusEGlobal::rcStopCC = xml.parseInt();
523                         else if (tag == "rcRecordCC")
524                             MusEGlobal::rcRecordCC = xml.parseInt();
525                         else if (tag == "rcGotoLeftCC")
526                             MusEGlobal::rcGotoLeftMarkCC = xml.parseInt();
527                         else if (tag == "rcPlayCC")
528                             MusEGlobal::rcPlayCC = xml.parseInt();
529 //                        else if (tag == "rcInsertRest")
530 //                            MusEGlobal::rcInsertPauseCC = xml.parseInt();
531                         else if (tag == "rcForwardCC")
532                             MusEGlobal::rcForwardCC = xml.parseInt();
533                         else if (tag == "rcRewindCC")
534                             MusEGlobal::rcBackwardCC = xml.parseInt();
535                         else
536                               xml.unknown("Seq");
537                         break;
538                   case Xml::TagEnd:
539                         if (tag == "sequencer") {
540                               return;
541                               }
542                   default:
543                         break;
544                   }
545             }
546       }
547 
548 //---------------------------------------------------------
549 //   readConfiguration
550 //---------------------------------------------------------
551 
readConfiguration(Xml & xml,bool doReadMidiPortConfig,bool doReadGlobalConfig)552 void readConfiguration(Xml& xml, bool doReadMidiPortConfig, bool doReadGlobalConfig)
553       {
554       if (doReadGlobalConfig) doReadMidiPortConfig=true;
555 
556       int mixers = 0;
557       for (;;) {
558             Xml::Token token = xml.parse();
559             if (token == Xml::Error || token == Xml::End)
560                   break;
561             QString tag = xml.s1();
562             switch (token) {
563                   case Xml::TagStart:
564                         /* the reading of configuration is split in two; read
565                            "sequencer" and read ALL. The reason is that it is
566                            possible to load a song without configuration. In
567                            this case the <configuration> chapter in the song
568                            file should be skipped. However the sub part
569                            <sequencer> contains elements that are necessary
570                            to preserve composition consistency. Mainly
571                            midiport configuration and VOLUME.
572                         */
573                         if (tag == "sequencer") {
574                               readSeqConfiguration(xml,
575                                 doReadGlobalConfig ? &MusEGlobal::metroGlobalSettings : &MusEGlobal::metroSongSettings,
576                                 !doReadMidiPortConfig);
577                               break;
578                               }
579                         else if (tag == "waveTracksVisible")
580                                  WaveTrack::setVisible((bool)xml.parseInt());
581                         else if (tag == "auxTracksVisible")
582                                  AudioAux::setVisible((bool)xml.parseInt());
583                         else if (tag == "groupTracksVisible")
584                                  AudioGroup::setVisible((bool)xml.parseInt());
585                         else if (tag == "midiTracksVisible")
586                                  MidiTrack::setVisible((bool)xml.parseInt());
587                         else if (tag == "inputTracksVisible")
588                                  AudioInput::setVisible((bool)xml.parseInt());
589                         else if (tag == "outputTracksVisible")
590                                  AudioOutput::setVisible((bool)xml.parseInt());
591                         else if (tag == "synthTracksVisible")
592                                  SynthI::setVisible((bool)xml.parseInt());
593                         else if (tag == "bigtimeVisible")
594                               MusEGlobal::config.bigTimeVisible = xml.parseInt();
595                         else if (tag == "transportVisible")
596                               MusEGlobal::config.transportVisible = xml.parseInt();
597                         else if (tag == "mixer1Visible")
598                               MusEGlobal::config.mixer1Visible = xml.parseInt();
599                         else if (tag == "mixer2Visible")
600                               MusEGlobal::config.mixer2Visible = xml.parseInt();
601                         else if (tag == "markerVisible")
602                               // I thought this was obsolete (done by song's toplevel list), but
603                               // it's obviously needed. (flo)
604                               MusEGlobal::config.markerVisible = xml.parseInt();
605 //                        else if (tag == "arrangerVisible")
606 //                              // same here.
607 //                              MusEGlobal::config.arrangerVisible = xml.parseInt();
608                         else if (tag == "geometryTransport")
609                               MusEGlobal::config.geometryTransport = readGeometry(xml, tag);
610                         else if (tag == "geometryBigTime")
611                               MusEGlobal::config.geometryBigTime = readGeometry(xml, tag);
612                         else if (tag == "Mixer") {
613                               if(mixers == 0)
614                                 MusEGlobal::config.mixer1.read(xml);
615                               else
616                                 MusEGlobal::config.mixer2.read(xml);
617                               ++mixers;
618                               }
619                         else if (tag == "geometryMain")
620                               MusEGlobal::config.geometryMain = readGeometry(xml, tag);
621                         else if (tag == "trackHeight")
622                                  MusEGlobal::config.trackHeight = xml.parseInt();
623 
624 
625                         else if (doReadMidiPortConfig==false) {
626                               xml.skip(tag);
627                               break;
628                               }
629 
630 
631 
632 
633 
634                         else if (tag == "midiInputDevice")
635                               MusEGlobal::midiInputPorts = xml.parseInt();
636                         else if (tag == "midiInputChannel")
637                               MusEGlobal::midiInputChannel = xml.parseInt();
638                         else if (tag == "midiRecordType")
639                               MusEGlobal::midiRecordType = xml.parseInt();
640                         else if (tag == "midiThruType")
641                               MusEGlobal::midiThruType = xml.parseInt();
642                         else if (tag == "midiFilterCtrl1")
643                               MusEGlobal::midiFilterCtrl1 = xml.parseInt();
644                         else if (tag == "midiFilterCtrl2")
645                               MusEGlobal::midiFilterCtrl2 = xml.parseInt();
646                         else if (tag == "midiFilterCtrl3")
647                               MusEGlobal::midiFilterCtrl3 = xml.parseInt();
648                         else if (tag == "midiFilterCtrl4")
649                               MusEGlobal::midiFilterCtrl4 = xml.parseInt();
650                         else if (tag == "mtctype")
651                         {
652                               MusEGlobal::mtcType= xml.parseInt();
653                               // Make sure the AL namespace variables mirror our variables.
654                               AL::mtcType = MusEGlobal::mtcType;
655                         }
656                         else if (tag == "sendClockDelay")
657                               MusEGlobal::syncSendFirstClockDelay = xml.parseUInt();
658                         else if (tag == "extSync")
659                                 MusEGlobal::extSyncFlag = xml.parseInt();
660                         else if (tag == "useJackTransport")
661                                 MusEGlobal::config.useJackTransport = xml.parseInt();
662                         else if (tag == "timebaseMaster")
663                               {
664                                 MusEGlobal::config.timebaseMaster = xml.parseInt();
665 
666                                 // Set this one-time flag to true so that when setMaster is called,
667                                 //  it forces master. audioDevice may be NULL, esp. at startup,
668                                 //  so this flag is necessary for the next valid call to setMaster.
669                                 MusEGlobal::timebaseMasterForceFlag = true;
670                                 if(MusEGlobal::audioDevice)
671                                   // Force it.
672                                   MusEGlobal::audioDevice->setMaster(MusEGlobal::config.timebaseMaster, true);
673                               }
674                         else if (tag == "syncRecFilterPreset")
675                               {
676                               int p = xml.parseInt();
677                               if(p >= 0 && p < MidiSyncInfo::TYPE_END)
678                               {
679                                 MusEGlobal::syncRecFilterPreset = MidiSyncInfo::SyncRecFilterPresetType(p);
680                                 MusEGlobal::midiSyncContainer.setSyncRecFilterPreset(MusEGlobal::syncRecFilterPreset);
681                               }
682                               }
683                         else if (tag == "syncRecTempoValQuant")
684                               {
685                                 double qv = xml.parseDouble();
686                                 MusEGlobal::syncRecTempoValQuant = qv;
687                                 MusEGlobal::midiSyncContainer.setRecTempoValQuant(qv);
688                               }
689                         else if (tag == "mtcoffset") {
690                               QString qs(xml.parse1());
691                               QByteArray ba = qs.toLatin1();
692                               const char* str = ba.constData();
693                               int h, m, s, f, sf;
694                               sscanf(str, "%d:%d:%d:%d:%d", &h, &m, &s, &f, &sf);
695                               MusEGlobal::mtcOffset = MTC(h, m, s, f, sf);
696                               }
697                         else if (tag == "midiTransform")
698                               readMidiTransform(xml);
699                         else if (tag == "midiInputTransform")
700                               readMidiInputTransform(xml);
701 
702                         // don't insert else if(...) clauses between
703                         // this line and "Global config stuff begins here".
704                         else if (!doReadGlobalConfig) {
705                               xml.skip(tag);
706                               break;
707                               }
708 
709                         // ---- Global and/or per-song config stuff ends here ----
710 
711 
712 
713                         // ---- Global config stuff begins here ----
714 
715                         else if (tag == "pluginLadspaPathList")
716 // QString::*EmptyParts is deprecated, use Qt::*EmptyParts, new as of 5.14.
717 #if QT_VERSION >= 0x050e00
718                               MusEGlobal::config.pluginLadspaPathList = xml.parse1().split(":", Qt::SkipEmptyParts);
719 #else
720                               MusEGlobal::config.pluginLadspaPathList = xml.parse1().split(":", QString::SkipEmptyParts);
721 #endif
722                         else if (tag == "pluginDssiPathList")
723 #if QT_VERSION >= 0x050e00
724                               MusEGlobal::config.pluginDssiPathList = xml.parse1().split(":", Qt::SkipEmptyParts);
725 #else
726                               MusEGlobal::config.pluginDssiPathList = xml.parse1().split(":", QString::SkipEmptyParts);
727 #endif
728                         // Obsolete. Replaced with one below.
729                         else if (tag == "pluginVstPathList")
730                               xml.parse1();
731                         else if (tag == "pluginVstsPathList")
732 #if QT_VERSION >= 0x050e00
733                               MusEGlobal::config.pluginVstPathList = xml.parse1().split(":", Qt::SkipEmptyParts);
734 #else
735                               MusEGlobal::config.pluginVstPathList = xml.parse1().split(":", QString::SkipEmptyParts);
736 #endif
737                         // Obsolete. Replaced with one below.
738                         else if (tag == "pluginLinuxVstPathList")
739                               xml.parse1();
740                         else if (tag == "pluginLinuxVstsPathList")
741 #if QT_VERSION >= 0x050e00
742                               MusEGlobal::config.pluginLinuxVstPathList = xml.parse1().split(":", Qt::SkipEmptyParts);
743 #else
744                               MusEGlobal::config.pluginLinuxVstPathList = xml.parse1().split(":", QString::SkipEmptyParts);
745 #endif
746                         else if (tag == "pluginLv2PathList")
747 #if QT_VERSION >= 0x050e00
748                               MusEGlobal::config.pluginLv2PathList = xml.parse1().split(":", Qt::SkipEmptyParts);
749 #else
750                               MusEGlobal::config.pluginLv2PathList = xml.parse1().split(":", QString::SkipEmptyParts);
751 #endif
752                         else if (tag == "pluginCacheTriggerRescan")
753                               MusEGlobal::config.pluginCacheTriggerRescan = xml.parseInt();
754 
755                         else if (tag == "audioConverterSettingsGroup")
756                         {
757                               if(MusEGlobal::defaultAudioConverterSettings)
758                                 MusEGlobal::defaultAudioConverterSettings->read(xml, &MusEGlobal::audioConverterPluginList);
759                         }
760 
761                         else if (tag == "preferredRouteNameOrAlias")
762                               MusEGlobal::config.preferredRouteNameOrAlias = static_cast<MusEGlobal::RouteNameAliasPreference>(xml.parseInt());
763                         else if (tag == "routerExpandVertically")
764                               MusEGlobal::config.routerExpandVertically = xml.parseInt();
765                         else if (tag == "routerGroupingChannels")
766                         {
767                               MusEGlobal::config.routerGroupingChannels = xml.parseInt();
768                               // TODO: For now we only support maximum two channels grouping. Zero is an error.
769                               if(MusEGlobal::config.routerGroupingChannels < 1)
770                                 MusEGlobal::config.routerGroupingChannels = 1;
771                               if(MusEGlobal::config.routerGroupingChannels > 2)
772                                 MusEGlobal::config.routerGroupingChannels = 2;
773                         }
774 //                        else if (tag == "qtStyle")
775 //                              MusEGlobal::config.style = xml.parse1();
776                         else if (tag == "autoSave")
777                               MusEGlobal::config.autoSave = xml.parseInt();
778                         else if (tag == "scrollableSubMenus")
779                               MusEGlobal::config.scrollableSubMenus = xml.parseInt();
780                         else if (tag == "liveWaveUpdate")
781                               MusEGlobal::config.liveWaveUpdate = xml.parseInt();
782                         else if (tag == "audioEffectsRackVisibleItems")
783                               MusEGlobal::config.audioEffectsRackVisibleItems = xml.parseInt();
784                         else if (tag == "preferKnobsVsSliders")
785                               MusEGlobal::config.preferKnobsVsSliders = xml.parseInt();
786                         else if (tag == "showControlValues")
787                               MusEGlobal::config.showControlValues = xml.parseInt();
788                         else if (tag == "monitorOnRecord")
789                               MusEGlobal::config.monitorOnRecord = xml.parseInt();
790                         else if (tag == "lineEditStyleHack")
791                               MusEGlobal::config.lineEditStyleHack = xml.parseInt();
792                         else if (tag == "preferMidiVolumeDb")
793                               MusEGlobal::config.preferMidiVolumeDb = xml.parseInt();
794                         else if (tag == "midiCtrlGraphMergeErase")
795                               MusEGlobal::config.midiCtrlGraphMergeErase = xml.parseInt();
796                         else if (tag == "midiCtrlGraphMergeEraseInclusive")
797                               MusEGlobal::config.midiCtrlGraphMergeEraseInclusive = xml.parseInt();
798                         else if (tag == "midiCtrlGraphMergeEraseWysiwyg")
799                               MusEGlobal::config.midiCtrlGraphMergeEraseWysiwyg = xml.parseInt();
800                         else if (tag == "museTheme")
801                               MusEGlobal::config.theme = xml.parse1();
802                         else if (tag == "useOldStyleStopShortCut")
803                               MusEGlobal::config.useOldStyleStopShortCut = xml.parseInt();
804                         else if (tag == "useRewindOnStop")
805                               MusEGlobal::config.useRewindOnStop = xml.parseInt();
806                         else if (tag == "moveArmedCheckBox")
807                               MusEGlobal::config.moveArmedCheckBox = xml.parseInt();
808                         else if (tag == "externalWavEditor")
809                               MusEGlobal::config.externalWavEditor = xml.parse1();
810 //                        else if (tag == "font0")
811 //                              MusEGlobal::config.fonts[0].fromString(xml.parse1());
812                         else if (tag == "font1")
813                               MusEGlobal::config.fonts[1].fromString(xml.parse1());
814                         else if (tag == "font2")
815                               MusEGlobal::config.fonts[2].fromString(xml.parse1());
816                         else if (tag == "font3")
817                               MusEGlobal::config.fonts[3].fromString(xml.parse1());
818                         else if (tag == "font4")
819                               MusEGlobal::config.fonts[4].fromString(xml.parse1());
820                         else if (tag == "font5")
821                               MusEGlobal::config.fonts[5].fromString(xml.parse1());
822                         else if (tag == "font6")
823                               MusEGlobal::config.fonts[6].fromString(xml.parse1());
824                         else if (tag == "autoAdjustFontSize")
825                               MusEGlobal::config.autoAdjustFontSize = xml.parseInt();
826                         else if (tag == "globalAlphaBlend")
827                             MusEGlobal::config.globalAlphaBlend = xml.parseInt();
828                         else if (tag == "palette0")
829                               MusEGlobal::config.palette[0] = readColor(xml);
830                         else if (tag == "palette1")
831                               MusEGlobal::config.palette[1] = readColor(xml);
832                         else if (tag == "palette2")
833                               MusEGlobal::config.palette[2] = readColor(xml);
834                         else if (tag == "palette3")
835                               MusEGlobal::config.palette[3] = readColor(xml);
836                         else if (tag == "palette4")
837                               MusEGlobal::config.palette[4] = readColor(xml);
838                         else if (tag == "palette5")
839                               MusEGlobal::config.palette[5] = readColor(xml);
840                         else if (tag == "palette6")
841                               MusEGlobal::config.palette[6] = readColor(xml);
842                         else if (tag == "palette7")
843                               MusEGlobal::config.palette[7] = readColor(xml);
844                         else if (tag == "palette8")
845                               MusEGlobal::config.palette[8] = readColor(xml);
846                         else if (tag == "palette9")
847                               MusEGlobal::config.palette[9] = readColor(xml);
848                         else if (tag == "palette10")
849                               MusEGlobal::config.palette[10] = readColor(xml);
850                         else if (tag == "palette11")
851                               MusEGlobal::config.palette[11] = readColor(xml);
852                         else if (tag == "palette12")
853                               MusEGlobal::config.palette[12] = readColor(xml);
854                         else if (tag == "palette13")
855                               MusEGlobal::config.palette[13] = readColor(xml);
856                         else if (tag == "palette14")
857                               MusEGlobal::config.palette[14] = readColor(xml);
858                         else if (tag == "palette15")
859                               MusEGlobal::config.palette[15] = readColor(xml);
860 
861                         else if (tag == "partColor0")
862                               MusEGlobal::config.partColors[0] = readColor(xml);
863                         else if (tag == "partColor1")
864                               MusEGlobal::config.partColors[1] = readColor(xml);
865                         else if (tag == "partColor2")
866                               MusEGlobal::config.partColors[2] = readColor(xml);
867                         else if (tag == "partColor3")
868                               MusEGlobal::config.partColors[3] = readColor(xml);
869                         else if (tag == "partColor4")
870                               MusEGlobal::config.partColors[4] = readColor(xml);
871                         else if (tag == "partColor5")
872                               MusEGlobal::config.partColors[5] = readColor(xml);
873                         else if (tag == "partColor6")
874                               MusEGlobal::config.partColors[6] = readColor(xml);
875                         else if (tag == "partColor7")
876                               MusEGlobal::config.partColors[7] = readColor(xml);
877                         else if (tag == "partColor8")
878                               MusEGlobal::config.partColors[8] = readColor(xml);
879                         else if (tag == "partColor9")
880                               MusEGlobal::config.partColors[9] = readColor(xml);
881                         else if (tag == "partColor10")
882                               MusEGlobal::config.partColors[10] = readColor(xml);
883                         else if (tag == "partColor11")
884                               MusEGlobal::config.partColors[11] = readColor(xml);
885                         else if (tag == "partColor12")
886                               MusEGlobal::config.partColors[12] = readColor(xml);
887                         else if (tag == "partColor13")
888                               MusEGlobal::config.partColors[13] = readColor(xml);
889                         else if (tag == "partColor14")
890                               MusEGlobal::config.partColors[14] = readColor(xml);
891                         else if (tag == "partColor15")
892                               MusEGlobal::config.partColors[15] = readColor(xml);
893                         else if (tag == "partColor16")
894                               MusEGlobal::config.partColors[16] = readColor(xml);
895                         else if (tag == "partColor17")
896                               MusEGlobal::config.partColors[17] = readColor(xml);
897 
898                         else if (tag == "partColorName0")
899                               MusEGlobal::config.partColorNames[0] = xml.parse1();
900                         else if (tag == "partColorName1")
901                               MusEGlobal::config.partColorNames[1] = xml.parse1();
902                         else if (tag == "partColorName2")
903                               MusEGlobal::config.partColorNames[2] = xml.parse1();
904                         else if (tag == "partColorName3")
905                               MusEGlobal::config.partColorNames[3] = xml.parse1();
906                         else if (tag == "partColorName4")
907                               MusEGlobal::config.partColorNames[4] = xml.parse1();
908                         else if (tag == "partColorName5")
909                               MusEGlobal::config.partColorNames[5] = xml.parse1();
910                         else if (tag == "partColorName6")
911                               MusEGlobal::config.partColorNames[6] = xml.parse1();
912                         else if (tag == "partColorName7")
913                               MusEGlobal::config.partColorNames[7] = xml.parse1();
914                         else if (tag == "partColorName8")
915                               MusEGlobal::config.partColorNames[8] = xml.parse1();
916                         else if (tag == "partColorName9")
917                               MusEGlobal::config.partColorNames[9] = xml.parse1();
918                         else if (tag == "partColorName10")
919                               MusEGlobal::config.partColorNames[10] = xml.parse1();
920                         else if (tag == "partColorName11")
921                               MusEGlobal::config.partColorNames[11] = xml.parse1();
922                         else if (tag == "partColorName12")
923                               MusEGlobal::config.partColorNames[12] = xml.parse1();
924                         else if (tag == "partColorName13")
925                               MusEGlobal::config.partColorNames[13] = xml.parse1();
926                         else if (tag == "partColorName14")
927                               MusEGlobal::config.partColorNames[14] = xml.parse1();
928                         else if (tag == "partColorName15")
929                               MusEGlobal::config.partColorNames[15] = xml.parse1();
930                         else if (tag == "partColorName16")
931                               MusEGlobal::config.partColorNames[16] = xml.parse1();
932                         else if (tag == "partColorName17")
933                               MusEGlobal::config.partColorNames[17] = xml.parse1();
934 
935                         else if (tag == "partCanvasBg")
936                               MusEGlobal::config.partCanvasBg = readColor(xml);
937                         else if (tag == "dummyPartColor")
938                             MusEGlobal::config.dummyPartColor = readColor(xml);
939                         else if (tag == "partCanvasFineRaster")
940                               MusEGlobal::config.partCanvasFineRasterColor = readColor(xml);
941                         else if (tag == "partCanvasBeatRaster")
942                               MusEGlobal::config.partCanvasBeatRasterColor = readColor(xml);
943                         else if (tag == "partCanvasCoarseRaster")
944                               MusEGlobal::config.partCanvasCoarseRasterColor = readColor(xml);
945                         else if (tag == "trackBg")
946                               MusEGlobal::config.trackBg = readColor(xml);
947                         else if (tag == "selectTrackBg")
948                               MusEGlobal::config.selectTrackBg = readColor(xml);
949                         else if (tag == "selectTrackFg")
950                               MusEGlobal::config.selectTrackFg = readColor(xml);
951                         else if (tag == "selectTrackCurBg")
952                             MusEGlobal::config.selectTrackCurBg = readColor(xml);
953                         else if (tag == "trackSectionDividerColor")
954                               MusEGlobal::config.trackSectionDividerColor = readColor(xml);
955 //                        else if (tag == "mixerBg")
956 //                              MusEGlobal::config.mixerBg = readColor(xml);
957                         else if (tag == "midiTrackLabelBg")
958                               MusEGlobal::config.midiTrackLabelBg = readColor(xml);
959 // Obsolete. There is only 'New' drum tracks now.
960                         else if (tag == "drumTrackLabelBg2")
961                               /*MusEGlobal::config.drumTrackLabelBg =*/ readColor(xml);
962                         else if (tag == "newDrumTrackLabelBg2")
963                               MusEGlobal::config.newDrumTrackLabelBg = readColor(xml);
964                         else if (tag == "waveTrackLabelBg")
965                               MusEGlobal::config.waveTrackLabelBg = readColor(xml);
966                         else if (tag == "outputTrackLabelBg")
967                               MusEGlobal::config.outputTrackLabelBg = readColor(xml);
968                         else if (tag == "inputTrackLabelBg")
969                               MusEGlobal::config.inputTrackLabelBg = readColor(xml);
970                         else if (tag == "groupTrackLabelBg")
971                               MusEGlobal::config.groupTrackLabelBg = readColor(xml);
972                         else if (tag == "auxTrackLabelBg2")
973                               MusEGlobal::config.auxTrackLabelBg = readColor(xml);
974                         else if (tag == "synthTrackLabelBg")
975                               MusEGlobal::config.synthTrackLabelBg = readColor(xml);
976 
977                         else if (tag == "midiTrackBg")
978                               MusEGlobal::config.midiTrackBg = readColor(xml);
979                         else if (tag == "ctrlGraphFg")
980                               MusEGlobal::config.ctrlGraphFg = readColor(xml);
981                         else if (tag == "ctrlGraphSel")
982                             MusEGlobal::config.ctrlGraphSel = readColor(xml);
983                         else if (tag == "drumTrackBg")
984                               MusEGlobal::config.drumTrackBg = readColor(xml);
985                         else if (tag == "newDrumTrackBg")
986                               MusEGlobal::config.newDrumTrackBg = readColor(xml);
987                         else if (tag == "waveTrackBg")
988                               MusEGlobal::config.waveTrackBg = readColor(xml);
989                         else if (tag == "outputTrackBg")
990                               MusEGlobal::config.outputTrackBg = readColor(xml);
991                         else if (tag == "inputTrackBg")
992                               MusEGlobal::config.inputTrackBg = readColor(xml);
993                         else if (tag == "groupTrackBg")
994                               MusEGlobal::config.groupTrackBg = readColor(xml);
995                         else if (tag == "auxTrackBg")
996                               MusEGlobal::config.auxTrackBg = readColor(xml);
997                         else if (tag == "synthTrackBg")
998                               MusEGlobal::config.synthTrackBg = readColor(xml);
999 
1000                         else if (tag == "sliderBarDefaultColor")
1001                               MusEGlobal::config.sliderBarColor = readColor(xml);
1002                         else if (tag == "sliderDefaultColor2")
1003                               MusEGlobal::config.sliderBackgroundColor = readColor(xml);
1004                         else if (tag == "panSliderColor2")
1005                               MusEGlobal::config.panSliderColor = readColor(xml);
1006                         else if (tag == "gainSliderColor2")
1007                               MusEGlobal::config.gainSliderColor = readColor(xml);
1008                         else if (tag == "auxSliderColor2")
1009                               MusEGlobal::config.auxSliderColor = readColor(xml);
1010                         else if (tag == "audioVolumeSliderColor2")
1011                               MusEGlobal::config.audioVolumeSliderColor = readColor(xml);
1012                         else if (tag == "midiVolumeSliderColor2")
1013                               MusEGlobal::config.midiVolumeSliderColor = readColor(xml);
1014                         else if (tag == "audioVolumeHandleColor")
1015                             MusEGlobal::config.audioVolumeHandleColor = readColor(xml);
1016                         else if (tag == "midiVolumeHandleColor")
1017                             MusEGlobal::config.midiVolumeHandleColor = readColor(xml);
1018                         else if (tag == "audioControllerSliderDefaultColor2")
1019                               MusEGlobal::config.audioControllerSliderColor = readColor(xml);
1020                         else if (tag == "audioPropertySliderDefaultColor2")
1021                               MusEGlobal::config.audioPropertySliderColor = readColor(xml);
1022                         else if (tag == "midiControllerSliderDefaultColor2")
1023                               MusEGlobal::config.midiControllerSliderColor = readColor(xml);
1024                         else if (tag == "midiPropertySliderDefaultColor2")
1025                               MusEGlobal::config.midiPropertySliderColor = readColor(xml);
1026                         else if (tag == "midiPatchReadoutColor")
1027                               MusEGlobal::config.midiPatchReadoutColor = readColor(xml);
1028                         else if (tag == "knobFontColor")
1029                             MusEGlobal::config.knobFontColor = readColor(xml);
1030 
1031                         else if (tag == "audioMeterPrimaryColor")
1032                               MusEGlobal::config.audioMeterPrimaryColor = readColor(xml);
1033                         else if (tag == "midiMeterPrimaryColor")
1034                               MusEGlobal::config.midiMeterPrimaryColor = readColor(xml);
1035                         else if (tag == "meterBackgroundColor")
1036                             MusEGlobal::config.meterBackgroundColor = readColor(xml);
1037 
1038                         else if (tag == "rackItemBackgroundColor")
1039                             MusEGlobal::config.rackItemBackgroundColor = readColor(xml);
1040                         else if (tag == "rackItemBgActiveColor")
1041                             MusEGlobal::config.rackItemBgActiveColor = readColor(xml);
1042                         else if (tag == "rackItemFontColor")
1043                             MusEGlobal::config.rackItemFontColor = readColor(xml);
1044                         else if (tag == "rackItemFontActiveColor")
1045                             MusEGlobal::config.rackItemFontActiveColor = readColor(xml);
1046                         else if (tag == "rackItemBorderColor")
1047                             MusEGlobal::config.rackItemBorderColor = readColor(xml);
1048                         else if (tag == "rackItemFontColorHover")
1049                             MusEGlobal::config.rackItemFontColorHover = readColor(xml);
1050 
1051                         else if (tag == "midiInstrumentBackgroundColor")
1052                             MusEGlobal::config.midiInstrumentBackgroundColor = readColor(xml);
1053                         else if (tag == "midiInstrumentBgActiveColor")
1054                             MusEGlobal::config.midiInstrumentBgActiveColor = readColor(xml);
1055                         else if (tag == "midiInstrumentFontColor")
1056                             MusEGlobal::config.midiInstrumentFontColor = readColor(xml);
1057                         else if (tag == "midiInstrumentFontActiveColor")
1058                             MusEGlobal::config.midiInstrumentFontActiveColor = readColor(xml);
1059                         else if (tag == "midiInstrumentBorderColor")
1060                             MusEGlobal::config.midiInstrumentBorderColor = readColor(xml);
1061 
1062                         else if (tag == "extendedMidi")
1063                               MusEGlobal::config.extendedMidi = xml.parseInt();
1064                         else if (tag == "midiExportDivision")
1065                               MusEGlobal::config.midiDivision = xml.parseInt();
1066                         else if (tag == "copyright")
1067                               MusEGlobal::config.copyright = xml.parse1();
1068                         else if (tag == "smfFormat")
1069                               MusEGlobal::config.smfFormat = xml.parseInt();
1070                         else if (tag == "exp2ByteTimeSigs")
1071                               MusEGlobal::config.exp2ByteTimeSigs = xml.parseInt();
1072                         else if (tag == "expOptimNoteOffs")
1073                               MusEGlobal::config.expOptimNoteOffs = xml.parseInt();
1074                         else if (tag == "expRunningStatus")
1075                               MusEGlobal::config.expRunningStatus = xml.parseInt();
1076                         else if (tag == "importMidiSplitParts")
1077                               MusEGlobal::config.importMidiSplitParts = xml.parseInt();
1078                         else if (tag == "importDevNameMetas")
1079                               MusEGlobal::config.importDevNameMetas = xml.parseInt();
1080                         else if (tag == "useLastEditedEvent")
1081                               MusEGlobal::config.useLastEditedEvent = xml.parseInt();
1082                         else if (tag == "importInstrNameMetas")
1083                               MusEGlobal::config.importInstrNameMetas = xml.parseInt();
1084                         else if (tag == "exportPortsDevices")
1085                               MusEGlobal::config.exportPortsDevices = xml.parseInt();
1086                         else if (tag == "exportPortDeviceSMF0")
1087                               MusEGlobal::config.exportPortDeviceSMF0 = xml.parseInt();
1088                         else if (tag == "exportDrumMapOverrides")
1089                               MusEGlobal::config.exportDrumMapOverrides = xml.parseInt();
1090                         else if (tag == "exportChannelOverridesToNewTrack")
1091                               MusEGlobal::config.exportChannelOverridesToNewTrack = xml.parseInt();
1092                         else if (tag == "exportModeInstr")
1093                               MusEGlobal::config.exportModeInstr = xml.parseInt();
1094                         else if (tag == "importMidiDefaultInstr")
1095                               MusEGlobal::config.importMidiDefaultInstr = xml.parse1();
1096 
1097                         else if (tag == "showSplashScreen")
1098                               MusEGlobal::config.showSplashScreen = xml.parseInt();
1099                         else if (tag == "canvasShowPartType")
1100                               MusEGlobal::config.canvasShowPartType = xml.parseInt();
1101                         else if (tag == "canvasShowPartEvent")
1102                               MusEGlobal::config.canvasShowPartEvent = xml.parseInt();
1103                         else if (tag == "canvasShowGrid")
1104                               MusEGlobal::config.canvasShowGrid = xml.parseInt();
1105                         else if (tag == "canvasShowGridHorizontalAlways")
1106                               MusEGlobal::config.canvasShowGridHorizontalAlways = xml.parseInt();
1107                         else if (tag == "canvasShowGridBeatsAlways")
1108                               MusEGlobal::config.canvasShowGridBeatsAlways = xml.parseInt();
1109                         else if (tag == "useTrackColorForParts")
1110                               MusEGlobal::config.useTrackColorForParts = xml.parseInt();
1111                         else if (tag == "canvasBgPixmap")
1112                               MusEGlobal::config.canvasBgPixmap = xml.parse1();
1113                         else if (tag == "canvasCustomBgList")
1114 #if QT_VERSION >= 0x050e00
1115                               MusEGlobal::config.canvasCustomBgList = xml.parse1().split(";", Qt::SkipEmptyParts);
1116 #else
1117                               MusEGlobal::config.canvasCustomBgList = xml.parse1().split(";", QString::SkipEmptyParts);
1118 #endif
1119                         else if (tag == "bigtimeForegroundcolor")
1120                               MusEGlobal::config.bigTimeForegroundColor = readColor(xml);
1121                         else if (tag == "bigtimeBackgroundcolor")
1122                               MusEGlobal::config.bigTimeBackgroundColor = readColor(xml);
1123                         else if (tag == "transportHandleColor")
1124                               MusEGlobal::config.transportHandleColor = readColor(xml);
1125                         else if (tag == "waveEditBackgroundColor")
1126                               MusEGlobal::config.waveEditBackgroundColor = readColor(xml);
1127                         else if (tag == "rulerBackgroundColor")
1128                               MusEGlobal::config.rulerBg = readColor(xml);
1129                         else if (tag == "rulerForegroundColor")
1130                               MusEGlobal::config.rulerFg = readColor(xml);
1131                         else if (tag == "rulerCurrentColor")
1132                               MusEGlobal::config.rulerCurrent = readColor(xml);
1133 
1134                         else if (tag == "waveNonselectedPart")
1135                               MusEGlobal::config.waveNonselectedPart = readColor(xml);
1136                         else if (tag == "wavePeakColor")
1137                               MusEGlobal::config.wavePeakColor = readColor(xml);
1138                         else if (tag == "waveRmsColor")
1139                               MusEGlobal::config.waveRmsColor = readColor(xml);
1140                         else if (tag == "wavePeakColorSelected")
1141                               MusEGlobal::config.wavePeakColorSelected = readColor(xml);
1142                         else if (tag == "waveRmsColorSelected")
1143                               MusEGlobal::config.waveRmsColorSelected = readColor(xml);
1144 
1145                         else if (tag == "partWaveColorPeak")
1146                               MusEGlobal::config.partWaveColorPeak = readColor(xml);
1147                         else if (tag == "partWaveColorRms")
1148                               MusEGlobal::config.partWaveColorRms = readColor(xml);
1149                         else if (tag == "partMidiDarkEventColor")
1150                               MusEGlobal::config.partMidiDarkEventColor = readColor(xml);
1151                         else if (tag == "partMidiLightEventColor")
1152                               MusEGlobal::config.partMidiLightEventColor = readColor(xml);
1153 
1154                         else if (tag == "midiCanvasBackgroundColor")
1155                               MusEGlobal::config.midiCanvasBg = readColor(xml);
1156 
1157                         else if (tag == "midiCanvasFineColor")
1158                               MusEGlobal::config.midiCanvasFineColor = readColor(xml);
1159 
1160                         else if (tag == "midiCanvasBeatColor")
1161                               MusEGlobal::config.midiCanvasBeatColor = readColor(xml);
1162 
1163                         else if (tag == "midiCanvasBarColor")
1164                               MusEGlobal::config.midiCanvasBarColor = readColor(xml);
1165 
1166                         else if (tag == "midiItemColor")
1167                             MusEGlobal::config.midiItemColor = readColor(xml);
1168                         else if (tag == "midiItemSelectedColor")
1169                             MusEGlobal::config.midiItemSelectedColor = readColor(xml);
1170 
1171                         else if (tag == "midiDividerColor")
1172                             MusEGlobal::config.midiDividerColor = readColor(xml);
1173 
1174                         else if (tag == "midiControllerViewBackgroundColor")
1175                               MusEGlobal::config.midiControllerViewBg = readColor(xml);
1176 
1177                         else if (tag == "drumListBackgroundColor")
1178                               MusEGlobal::config.drumListBg = readColor(xml);
1179                         else if (tag == "drumListFont")
1180                             MusEGlobal::config.drumListFont = readColor(xml);
1181                         else if (tag == "drumListSel")
1182                             MusEGlobal::config.drumListSel = readColor(xml);
1183                         else if (tag == "drumListSelFont")
1184                             MusEGlobal::config.drumListSelFont = readColor(xml);
1185 
1186                         else if (tag == "pianoCurrentKey")
1187                             MusEGlobal::config.pianoCurrentKey = readColor(xml);
1188                         else if (tag == "pianoPressedKey")
1189                             MusEGlobal::config.pianoPressedKey = readColor(xml);
1190                         else if (tag == "pianoSelectedKey")
1191                             MusEGlobal::config.pianoSelectedKey = readColor(xml);
1192 
1193                         else if (tag == "markerColor")
1194                             MusEGlobal::config.markerColor = readColor(xml);
1195                         else if (tag == "rangeMarkerColor")
1196                             MusEGlobal::config.rangeMarkerColor = readColor(xml);
1197                         else if (tag == "positionMarkerColor")
1198                             MusEGlobal::config.positionMarkerColor = readColor(xml);
1199                         else if (tag == "currentPositionColor")
1200                             MusEGlobal::config.currentPositionColor = readColor(xml);
1201 
1202 
1203 
1204                         else if (tag == "maxAliasedPointSize")
1205                               MusEGlobal::config.maxAliasedPointSize = xml.parseInt();
1206 
1207                         else if (tag == "iconSize")
1208                             MusEGlobal::config.iconSize = xml.parseInt();
1209 
1210                         else if (tag == "cursorSize")
1211                             MusEGlobal::config.cursorSize = xml.parseInt();
1212 
1213                         else if (tag == "trackGradientStrength")
1214                             MusEGlobal::config.trackGradientStrength = xml.parseInt();
1215 
1216                         else if (tag == "partGradientStrength")
1217                             MusEGlobal::config.partGradientStrength = xml.parseInt();
1218 
1219                         else if (tag == "cascadeStylesheets")
1220                             MusEGlobal::config.cascadeStylesheets = xml.parseInt();
1221 
1222                         else if (tag == "showIconsInMenus")
1223                             MusEGlobal::config.showIconsInMenus = xml.parseInt();
1224 
1225                         else if (tag == "useNativeStandardDialogs")
1226                             MusEGlobal::config.useNativeStandardDialogs = xml.parseInt();
1227 
1228                         //else if (tag == "midiSyncInfo")
1229                         //      readConfigMidiSyncInfo(xml);
1230                         /* Obsolete. done by song's toplevel list. arrangerview also handles arranger.
1231                         else if (tag == "arranger") {
1232                               if (MusEGlobal::muse && MusEGlobal::muse->arranger())
1233                                     MusEGlobal::muse->arranger()->readStatus(xml);
1234                               else
1235                                     xml.skip(tag);
1236                               }
1237                         */
1238                         else if (tag == "drumedit")
1239                               MusEGui::DrumEdit::readConfiguration(xml);
1240                         else if (tag == "pianoroll")
1241                               MusEGui::PianoRoll::readConfiguration(xml);
1242                         else if (tag == "scoreedit")
1243                               MusEGui::ScoreEdit::read_configuration(xml);
1244                         else if (tag == "masteredit")
1245                               MusEGui::MasterEdit::readConfiguration(xml);
1246                         else if (tag == "waveedit")
1247                               MusEGui::WaveEdit::readConfiguration(xml);
1248 //                        else if (tag == "listedit")
1249 //                              MusEGui::ListEdit::readConfiguration(xml);
1250 //                        else if (tag == "lmaster")
1251 //                              MusEGui::LMaster::readConfiguration(xml);
1252                         else if (tag == "arrangerview")
1253                               MusEGui::ArrangerView::readConfiguration(xml);
1254 
1255                         else if (tag == "dialogs")
1256                               MusEGui::read_function_dialog_config(xml);
1257                         else if (tag == "shortcuts")
1258                               MusEGui::readShortCuts(xml);
1259                         else if (tag == "enableAlsaMidiDriver")
1260                               MusEGlobal::config.enableAlsaMidiDriver = xml.parseInt();
1261                         else if (tag == "division")
1262                         {
1263                               MusEGlobal::config.division = xml.parseInt();
1264                               // Make sure the AL namespace variable mirrors our variable.
1265                               AL::division = MusEGlobal::config.division;
1266                         }
1267                         else if (tag == "guiDivision")  // Obsolete. Was never used.
1268                               xml.parseInt();
1269                         else if (tag == "rtcTicks")
1270                               MusEGlobal::config.rtcTicks = xml.parseInt();
1271                         else if (tag == "curMidiSyncInPort")
1272                               MusEGlobal::config.curMidiSyncInPort = xml.parseInt();
1273                         else if (tag == "midiSendInit")
1274                               MusEGlobal::config.midiSendInit = xml.parseInt();
1275                         else if (tag == "warnInitPending")
1276                               MusEGlobal::config.warnInitPending = xml.parseInt();
1277                         else if (tag == "midiSendCtlDefaults")
1278                               MusEGlobal::config.midiSendCtlDefaults = xml.parseInt();
1279                         else if (tag == "midiSendNullParameters")
1280                               MusEGlobal::config.midiSendNullParameters = xml.parseInt();
1281                         else if (tag == "midiOptimizeControllers")
1282                               MusEGlobal::config.midiOptimizeControllers = xml.parseInt();
1283                         else if (tag == "warnIfBadTiming")
1284                               MusEGlobal::config.warnIfBadTiming = xml.parseInt();
1285                         else if (tag == "warnOnFileVersions")
1286                               MusEGlobal::config.warnOnFileVersions = xml.parseInt();
1287                         else if (tag == "lv2UiBehavior")
1288                               MusEGlobal::config.lv2UiBehavior = static_cast<MusEGlobal::CONF_LV2_UI_BEHAVIOR>(xml.parseInt());
1289                         else if (tag == "minMeter")
1290                               MusEGlobal::config.minMeter = xml.parseInt();
1291                         else if (tag == "minSlider")
1292                               MusEGlobal::config.minSlider = xml.parseDouble();
1293                         else if (tag == "freewheelMode")
1294                               MusEGlobal::config.freewheelMode = xml.parseInt();
1295                         else if (tag == "denormalProtection")
1296                               MusEGlobal::config.useDenormalBias = xml.parseInt();
1297                         else if (tag == "didYouKnow")
1298                               MusEGlobal::config.showDidYouKnow = xml.parseInt();
1299                         else if (tag == "outputLimiter")
1300                               MusEGlobal::config.useOutputLimiter = xml.parseInt();
1301                         else if (tag == "vstInPlace")
1302                               MusEGlobal::config.vstInPlace = xml.parseInt();
1303                         else if (tag == "deviceAudioSampleRate")
1304                               MusEGlobal::config.deviceAudioSampleRate = xml.parseInt();
1305                         else if (tag == "deviceAudioBufSize")
1306                               MusEGlobal::config.deviceAudioBufSize = xml.parseInt();
1307                         else if (tag == "deviceAudioBackend")
1308                               MusEGlobal::config.deviceAudioBackend = xml.parseInt();
1309 
1310                         else if (tag == "enableLatencyCorrection")
1311                               MusEGlobal::config.enableLatencyCorrection = xml.parseInt();
1312                         else if (tag == "correctUnterminatedInBranchLatency")
1313                               MusEGlobal::config.correctUnterminatedInBranchLatency = xml.parseInt();
1314                         else if (tag == "correctUnterminatedOutBranchLatency")
1315                               MusEGlobal::config.correctUnterminatedOutBranchLatency = xml.parseInt();
1316                         else if (tag == "monitoringAffectsLatency")
1317                               MusEGlobal::config.monitoringAffectsLatency = xml.parseInt();
1318                         else if (tag == "commonProjectLatency")
1319                               MusEGlobal::config.commonProjectLatency = xml.parseInt();
1320 
1321                         else if (tag == "minControlProcessPeriod")
1322                               MusEGlobal::config.minControlProcessPeriod = xml.parseUInt();
1323                         else if (tag == "guiRefresh")
1324                               MusEGlobal::config.guiRefresh = xml.parseInt();
1325                         else if (tag == "userInstrumentsDir")                        // Obsolete
1326                               MusEGlobal::config.userInstrumentsDir = xml.parse1();  // Keep for compatibility
1327                         else if (tag == "startMode")
1328                               MusEGlobal::config.startMode = xml.parseInt();
1329                         else if (tag == "startSong")
1330                               MusEGlobal::config.startSong = xml.parse1();
1331                         else if (tag == "startSongLoadConfig")
1332                               MusEGlobal::config.startSongLoadConfig = xml.parseInt();
1333                         else if (tag == "newDrumRecordCondition")
1334                               MusEGlobal::config.newDrumRecordCondition = MusECore::newDrumRecordCondition_t(xml.parseInt());
1335                         else if (tag == "projectBaseFolder")
1336                               MusEGlobal::config.projectBaseFolder = xml.parse1();
1337                         else if (tag == "projectStoreInFolder")
1338                               MusEGlobal::config.projectStoreInFolder = xml.parseInt();
1339                         else if (tag == "useProjectSaveDialog")
1340                               MusEGlobal::config.useProjectSaveDialog = xml.parseInt();
1341                         else if (tag == "popupsDefaultStayOpen")
1342                               MusEGlobal::config.popupsDefaultStayOpen = xml.parseInt();
1343                         else if (tag == "leftMouseButtonCanDecrease")
1344                               MusEGlobal::config.leftMouseButtonCanDecrease = xml.parseInt();
1345 //                        else if (tag == "rangeMarkerWithoutMMB")
1346 //                            MusEGlobal::config.rangeMarkerWithoutMMB = xml.parseInt();
1347                         else if (tag == "addHiddenTracks")
1348                               MusEGlobal::config.addHiddenTracks = xml.parseInt();
1349                         else if (tag == "drumTrackPreference")
1350                               // Obsolete. There is only 'New' drum tracks now.
1351                               // drumTrackPreference is fixed until it is removed some day...
1352                               //MusEGlobal::config.drumTrackPreference = (MusEGlobal::drumTrackPreference_t) xml.parseInt();
1353                               xml.parseInt();
1354 
1355 #ifdef _USE_INSTRUMENT_OVERRIDES_
1356                         else if (tag == "drummapOverrides")
1357                               MusEGlobal::workingDrumMapInstrumentList.read(xml);
1358 #endif
1359 
1360                         else if (tag == "unhideTracks")
1361                               MusEGlobal::config.unhideTracks = xml.parseInt();
1362                         else if (tag == "smartFocus")
1363                               MusEGlobal::config.smartFocus = xml.parseInt();
1364                         else if (tag == "borderlessMouse")
1365                               MusEGlobal::config.borderlessMouse = xml.parseInt();
1366                         else if (tag == "velocityPerNote")
1367                               MusEGlobal::config.velocityPerNote = xml.parseInt();
1368                         else if (tag == "plugin_groups")
1369                               MusEGlobal::readPluginGroupConfiguration(xml);
1370                         else if (tag == "synthDialogFavorites")
1371                             MusEGui::SynthDialog::readFavConfiguration(xml);
1372                         else if (tag == "mixdownPath")
1373                               MusEGlobal::config.mixdownPath = xml.parse1();
1374                         else if (tag == "showNoteNamesInPianoRoll")
1375                               MusEGlobal::config.showNoteNamesInPianoRoll = xml.parseInt();
1376                         else if (tag == "showNoteTooltips")
1377                             MusEGlobal::config.showNoteTooltips = xml.parseInt();
1378                         else if (tag == "showTimeScaleBeatNumbers")
1379                             MusEGlobal::config.showTimeScaleBeatNumbers = xml.parseInt();
1380                         else if (tag == "noPluginScaling")
1381                               MusEGlobal::config.noPluginScaling = xml.parseInt();
1382 //                        else if (tag == "openMDIWinMaximized")
1383 //                            MusEGlobal::config.openMDIWinMaximized = xml.parseInt();
1384                         else if (tag == "keepTransportWindowOnTop")
1385                             MusEGlobal::config.keepTransportWindowOnTop = xml.parseInt();
1386                         else if (tag == "showStatusBar")
1387                             MusEGlobal::config.showStatusBar = xml.parseInt();
1388 
1389 
1390                         // ---- the following only skips obsolete entries ----
1391                         else if ((tag == "arranger") || (tag == "geometryPianoroll") || (tag == "geometryDrumedit"))
1392                               xml.skip(tag);
1393                         else if ((tag == "lmaster") || (tag == "listedit"))
1394                             xml.skip(tag);
1395                         else if (tag == "mixerVisible")
1396                               xml.skip(tag);
1397                         else if (tag == "geometryMixer")
1398                               xml.skip(tag);
1399                         else if (tag == "txDeviceId")
1400                                 xml.parseInt();
1401                         else if (tag == "rxDeviceId")
1402                                 xml.parseInt();
1403                         else if (tag == "txSyncPort")
1404                                 xml.parseInt();
1405                         else if (tag == "rxSyncPort")
1406                                 xml.parseInt();
1407                         else if (tag == "syncgentype")
1408                               xml.parseInt();
1409                         else if (tag == "genMTCSync")
1410                               xml.parseInt();
1411                         else if (tag == "genMCSync")
1412                               xml.parseInt();
1413                         else if (tag == "genMMC")
1414                               xml.parseInt();
1415                         else if (tag == "acceptMTC")
1416                               xml.parseInt();
1417                         else if (tag == "acceptMMC")
1418                               xml.parseInt();
1419                         else if (tag == "acceptMC")
1420                               xml.parseInt();
1421                         else if ((tag == "samplerate") || (tag == "segmentsize") || (tag == "segmentcount"))
1422                               xml.parseInt();
1423                         else
1424                               xml.unknown("configuration");
1425                         break;
1426                   case Xml::Text:
1427                         fprintf(stderr, "text <%s>\n", xml.s1().toLatin1().constData());
1428                         break;
1429                   case Xml::Attribut:
1430                         if (doReadMidiPortConfig==false)
1431                               break;
1432                         else if (tag == "version") {
1433                               int major = xml.s2().section('.', 0, 0).toInt();
1434                               int minor = xml.s2().section('.', 1, 1).toInt();
1435                               xml.setVersion(major, minor);
1436                               }
1437                         break;
1438                   case Xml::TagEnd:
1439                         if (tag == "configuration") {
1440                               return;
1441                               }
1442                         break;
1443                   case Xml::Proc:
1444                   default:
1445                         break;
1446                   }
1447             }
1448       }
1449 
1450 //---------------------------------------------------------
1451 //   readConfiguration
1452 //---------------------------------------------------------
readConfiguration()1453 bool readConfiguration()
1454 {
1455     return readConfiguration(nullptr);
1456 }
1457 
readConfiguration(const char * configFile)1458 bool readConfiguration(const char *configFile)
1459       {
1460       QByteArray ba;
1461       if (configFile == nullptr)
1462       {
1463         ba = MusEGlobal::configName.toLatin1();
1464         configFile = ba.constData();
1465       }
1466 
1467       fprintf(stderr, "Config File <%s>\n", configFile);
1468       FILE* f = fopen(configFile, "r");
1469       if (f == nullptr) {
1470             if (MusEGlobal::debugMsg || MusEGlobal::debugMode)
1471                   fprintf(stderr, "NO Config File <%s> found\n", configFile);
1472 
1473             if (MusEGlobal::config.userInstrumentsDir.isEmpty())
1474                   MusEGlobal::config.userInstrumentsDir = MusEGlobal::configPath + "/instruments";
1475             return true;
1476             }
1477       Xml xml(f);
1478       bool skipmode = true;
1479       for (;;) {
1480             Xml::Token token = xml.parse();
1481             const QString& tag = xml.s1();
1482             switch (token) {
1483                   case Xml::Error:
1484                   case Xml::End:
1485                         goto read_conf_end;
1486                   case Xml::TagStart:
1487                         if (skipmode && tag == "muse")
1488                               skipmode = false;
1489                         else if (skipmode)
1490                               break;
1491                         else if (tag == "configuration")
1492                               readConfiguration(xml,true, true /* read global config as well */);
1493                         else
1494                               xml.unknown("muse config");
1495                         break;
1496                   case Xml::Attribut:
1497                         if (tag == "version") {
1498                               int major = xml.s2().section('.', 0, 0).toInt();
1499                               int minor = xml.s2().section('.', 1, 1).toInt();
1500                               xml.setVersion(major, minor);
1501                               }
1502                         break;
1503                   case Xml::TagEnd:
1504                         if(!xml.isVersionEqualToLatest())
1505                         {
1506                           fprintf(stderr, "\n***WARNING***\nLoaded config file version is %d.%d\nCurrent version is %d.%d\n"
1507                                   "Conversions may be applied!\n\n",
1508                                   xml.majorVersion(), xml.minorVersion(),
1509                                   xml.latestMajorVersion(), xml.latestMinorVersion());
1510                         }
1511                         if (!skipmode && tag == "muse") {
1512                               fclose(f);
1513                               return false;
1514                               }
1515                   default:
1516                         break;
1517                   }
1518             }
1519 
1520 read_conf_end:
1521       fclose(f);
1522       return true;
1523       }
1524 
1525 //---------------------------------------------------------
1526 //   writeMetronomeConfiguration
1527 //---------------------------------------------------------
1528 
writeMetronomeConfiguration(int level,Xml & xml,bool is_global)1529 static void writeMetronomeConfiguration(int level, Xml& xml, bool is_global)
1530       {
1531       MusECore::MetronomeSettings* metro_settings =
1532         is_global ? &MusEGlobal::metroGlobalSettings : &MusEGlobal::metroSongSettings;
1533 
1534       xml.tag(level++, "metronom");
1535       xml.intTag(level, "premeasures", metro_settings->preMeasures);
1536       xml.intTag(level, "measurepitch", metro_settings->measureClickNote);
1537       xml.intTag(level, "measurevelo", metro_settings->measureClickVelo);
1538       xml.intTag(level, "beatpitch", metro_settings->beatClickNote);
1539       xml.intTag(level, "beatvelo", metro_settings->beatClickVelo);
1540       xml.intTag(level, "accentpitch1", metro_settings->accentClick1);
1541       xml.intTag(level, "accentpitch2", metro_settings->accentClick2);
1542       xml.intTag(level, "accentvelo1", metro_settings->accentClick1Velo);
1543       xml.intTag(level, "accentvelo2", metro_settings->accentClick2Velo);
1544       xml.intTag(level, "channel", metro_settings->clickChan);
1545       xml.intTag(level, "port", metro_settings->clickPort);
1546 
1547       // Write the global metroUseSongSettings - ONLY if saving song configuration.
1548       if(!is_global)
1549         xml.intTag(level, "metroUseSongSettings", MusEGlobal::metroUseSongSettings);
1550       // Write either the global or song accents map.
1551       if(metro_settings->metroAccentsMap)
1552         metro_settings->metroAccentsMap->write(level, xml);
1553       // Write the global user accent presets - ONLY if saving global configuration.
1554       if(is_global)
1555         MusEGlobal::metroAccentPresets.write(level, xml, MusECore::MetroAccentsStruct::UserPreset);
1556 
1557       xml.intTag(level, "precountEnable", metro_settings->precountEnableFlag);
1558       xml.intTag(level, "fromMastertrack", metro_settings->precountFromMastertrackFlag);
1559       xml.intTag(level, "signatureZ", metro_settings->precountSigZ);
1560       xml.intTag(level, "signatureN", metro_settings->precountSigN);
1561       xml.intTag(level, "precountOnPlay", metro_settings->precountOnPlay);
1562       xml.intTag(level, "precountMuteMetronome", metro_settings->precountMuteMetronome);
1563       xml.intTag(level, "prerecord", metro_settings->precountPrerecord);
1564       xml.intTag(level, "preroll", metro_settings->precountPreroll);
1565       xml.intTag(level, "midiClickEnable", metro_settings->midiClickFlag);
1566       xml.intTag(level, "audioClickEnable", metro_settings->audioClickFlag);
1567       xml.floatTag(level, "audioClickVolume", metro_settings->audioClickVolume);
1568       xml.floatTag(level, "measClickVolume", metro_settings->measClickVolume);
1569       xml.floatTag(level, "beatClickVolume", metro_settings->beatClickVolume);
1570       xml.floatTag(level, "accent1ClickVolume", metro_settings->accent1ClickVolume);
1571       xml.floatTag(level, "accent2ClickVolume", metro_settings->accent2ClickVolume);
1572       xml.intTag(level, "clickSamples", metro_settings->clickSamples);
1573       xml.strTag(level, "beatSample", metro_settings->beatSample);
1574       xml.strTag(level, "measSample", metro_settings->measSample);
1575       xml.strTag(level, "accent1Sample", metro_settings->accent1Sample);
1576       xml.strTag(level, "accent2Sample", metro_settings->accent2Sample);
1577       xml.tag(level--, "/metronom");
1578       }
1579 
1580 //---------------------------------------------------------
1581 //   writeSeqConfiguration
1582 //---------------------------------------------------------
1583 
writeSeqConfiguration(int level,Xml & xml,bool writePortInfo)1584 static void writeSeqConfiguration(int level, Xml& xml, bool writePortInfo)
1585       {
1586       xml.tag(level++, "sequencer");
1587 
1588       // If writePortInfo is true we are writing SONG configuration,
1589       //  and if writePortInfo is NOT true we are writing GLOBAL configuration.
1590       // Write the global user accent presets - ONLY if saving global configuration.
1591       writeMetronomeConfiguration(level, xml, !writePortInfo);
1592 
1593       xml.intTag(level, "rcEnable",   MusEGlobal::rcEnable);
1594       xml.intTag(level, "rcStop",     MusEGlobal::rcStopNote);
1595       xml.intTag(level, "rcRecord",   MusEGlobal::rcRecordNote);
1596       xml.intTag(level, "rcGotoLeft", MusEGlobal::rcGotoLeftMarkNote);
1597       xml.intTag(level, "rcPlay",     MusEGlobal::rcPlayNote);
1598       xml.intTag(level, "rcSteprec",  MusEGlobal::rcSteprecNote);
1599       xml.intTag(level, "rcForward",  MusEGlobal::rcForwardNote);
1600       xml.intTag(level, "rcRewind",   MusEGlobal::rcBackwardNote);
1601 
1602       xml.intTag(level, "rcEnableCC",   MusEGlobal::rcEnableCC);
1603       xml.intTag(level, "rcStopCC",     MusEGlobal::rcStopCC);
1604       xml.intTag(level, "rcRecordCC",   MusEGlobal::rcRecordCC);
1605       xml.intTag(level, "rcGotoLeftCC", MusEGlobal::rcGotoLeftMarkCC);
1606       xml.intTag(level, "rcPlayCC",     MusEGlobal::rcPlayCC);
1607 //      xml.intTag(level, "rcInsertRest", MusEGlobal::rcInsertPauseCC);
1608       xml.intTag(level, "rcForwardCC",  MusEGlobal::rcForwardCC);
1609       xml.intTag(level, "rcRewindCC",   MusEGlobal::rcBackwardCC);
1610 
1611       if (writePortInfo) {
1612             for(iMidiDevice imd = MusEGlobal::midiDevices.begin(); imd != MusEGlobal::midiDevices.end(); ++imd)
1613             {
1614               MidiDevice* dev = *imd;
1615               // TODO: For now, support only jack midi devices here. ALSA devices are different.
1616               //if(dev->deviceType() != MidiDevice::JACK_MIDI)
1617               if(dev->deviceType() != MidiDevice::JACK_MIDI && dev->deviceType() != MidiDevice::ALSA_MIDI)
1618                 continue;
1619 
1620               xml.tag(level++, "mididevice");
1621               xml.strTag(level, "name",   dev->name());
1622 
1623               if(dev->deviceType() != MidiDevice::ALSA_MIDI)
1624                 xml.intTag(level, "type", dev->deviceType());
1625 
1626               // Synths will not have been created yet when this is read! So, synthIs now store their own openFlags.
1627               if(dev->openFlags() != 1)
1628                 xml.intTag(level, "openFlags", dev->openFlags());
1629 
1630               if(dev->deviceType() == MidiDevice::JACK_MIDI)
1631                 xml.intTag(level, "rwFlags", dev->rwFlags());   // Need this. Jack midi devs are created by app.   p4.0.41
1632 
1633               xml.etag(level--, "mididevice");
1634             }
1635 
1636             //
1637             // write information about all midi ports, their assigned
1638             // instruments and all managed midi controllers
1639             //
1640             for (int i = 0; i < MusECore::MIDI_PORTS; ++i) {
1641                   bool used = false;
1642                   MidiPort* mport = &MusEGlobal::midiPorts[i];
1643                   MidiDevice* dev = mport->device();
1644                   // Route check by Tim. Port can now be used for routing even if no device.
1645                   // Also, check for other non-defaults and save port, to preserve settings even if no device.
1646                   if(!mport->noInRoute() || !mport->noOutRoute() ||
1647                   // p4.0.17 Since MidiPort:: and MidiDevice::writeRouting() ignore ports with no device, ignore them here, too.
1648                   // This prevents bogus routes from being saved and propagated in the med file.
1649                   // Hmm tough decision, should we save if no device? That would preserve routes in case user upgrades HW,
1650                   //  or ALSA reorders or renames devices etc etc, then we have at least kept the track <-> port routes.
1651                      mport->defaultInChannels() != (1<<MusECore::MUSE_MIDI_CHANNELS)-1 ||   // p4.0.17 Default is now to connect to all channels.
1652                      mport->defaultOutChannels() ||
1653                      (!mport->instrument()->iname().isEmpty() && mport->instrument()->midiType() != MT_GM) ||
1654                      !mport->syncInfo().isDefault())
1655                     used = true;
1656                   else
1657                   {
1658                     MidiTrackList* tl = MusEGlobal::song->midis();
1659                     for (iMidiTrack it = tl->begin(); it != tl->end(); ++it)
1660                     {
1661                       MidiTrack* t = *it;
1662                       if (t->outPort() == i)
1663                       {
1664                         used = true;
1665                         break;
1666                       }
1667                     }
1668                   }
1669 
1670                   if (!used && !dev)
1671                         continue;
1672                   xml.tag(level++, "midiport idx=\"%d\"", i);
1673 
1674                   if(mport->defaultInChannels() != (1<<MusECore::MUSE_MIDI_CHANNELS)-1)     // p4.0.17 Default is now to connect to all channels.
1675                     xml.intTag(level, "defaultInChans", mport->defaultInChannels());
1676                   if(mport->defaultOutChannels())
1677                     xml.intTag(level, "defaultOutChans", mport->defaultOutChannels());
1678 
1679                   const MidiInstrument* mi = mport->instrument();
1680                   // FIXME: TODO: Make this user configurable.
1681                   if(mi && !mi->iname().isEmpty() && mi->iname() != "GM")
1682                   {
1683                     if(mi->isSynti())
1684                     {
1685                       // The instrument is a synthesizer. Store a reference to
1686                       //  the synthesizer track so it can be looked up upon loading.
1687                       const SynthI* si = static_cast<const SynthI*>(mi);
1688                       const int idx = MusEGlobal::song->tracks()->index(si);
1689                       if(idx >= 0)
1690                         xml.intTag(level, "trackIdx", idx);
1691                     }
1692                     else
1693                     {
1694                       // The instrument is not a synthesizer, it is one of our own
1695                       //  (loaded from an *.idf file). Just store a string identifier,
1696                       //  since we don't have unique indexes for .idf instruments. TODO ???
1697                       xml.strTag(level, "instrument", mi->iname());
1698                     }
1699                   }
1700 
1701                   if (dev) {
1702                         xml.strTag(level, "name",   dev->name());
1703                         }
1704                   mport->syncInfo().write(level, xml);
1705                   // write out registered controller for all channels
1706                   MidiCtrlValListList* vll = mport->controller();
1707                   for (int k = 0; k < MusECore::MUSE_MIDI_CHANNELS; ++k) {
1708                         int min = k << 24;
1709                         int max = min + 0x100000;
1710                         bool found = false;
1711                         iMidiCtrlValList s = vll->lower_bound(min);
1712                         iMidiCtrlValList e = vll->lower_bound(max);
1713                         if (s != e) {
1714                               for (iMidiCtrlValList i = s; i != e; ++i) {
1715                                     int ctl = i->second->num();
1716                                     if(mport->drumController(ctl))  // Including internals like polyaftertouch
1717                                       ctl |= 0xff;
1718                                     // Don't bother saving these empty controllers since they are already always added!
1719                                     if(defaultManagedMidiController.find(ctl) != defaultManagedMidiController.end()
1720                                         && i->second->hwVal() == CTRL_VAL_UNKNOWN)
1721                                       continue;
1722                                     if(!found)
1723                                     {
1724                                       xml.tag(level++, "channel idx=\"%d\"", k);
1725                                       found = true;
1726                                     }
1727                                     xml.tag(level++, "controller id=\"%d\"", i->second->num());
1728                                     if (i->second->hwVal() != CTRL_VAL_UNKNOWN)
1729                                           xml.intTag(level, "val", i->second->hwVal());
1730                                     xml.etag(level--, "controller");
1731                                     }
1732                               }
1733                         if(found)
1734                           xml.etag(level--, "channel");
1735                         }
1736                   xml.etag(level--, "midiport");
1737                   }
1738             }
1739       xml.tag(level, "/sequencer");
1740       }
1741 
1742 
writeConfigurationColors(int level,MusECore::Xml & xml,bool partColorNames)1743 void writeConfigurationColors(int level, MusECore::Xml& xml, bool partColorNames)
1744 {
1745      for (int i = 0; i < 16; ++i) {
1746             xml.colorTag(level, QString("palette") + QString::number(i), MusEGlobal::config.palette[i]);
1747             }
1748 
1749       for (int i = 0; i < NUM_PARTCOLORS; ++i) {
1750             xml.colorTag(level, QString("partColor") + QString::number(i), MusEGlobal::config.partColors[i]);
1751             }
1752 
1753       if(partColorNames)
1754       {
1755         for (int i = 0; i < NUM_PARTCOLORS; ++i) {
1756               xml.strTag(level, QString("partColorName") + QString::number(i), MusEGlobal::config.partColorNames[i]);
1757               }
1758       }
1759 
1760       xml.colorTag(level, "partCanvasBg",  MusEGlobal::config.partCanvasBg);
1761       xml.colorTag(level, "dummyPartColor",  MusEGlobal::config.dummyPartColor);
1762       xml.colorTag(level, "partCanvasCoarseRaster",  MusEGlobal::config.partCanvasCoarseRasterColor);
1763       xml.colorTag(level, "partCanvasBeatRaster",  MusEGlobal::config.partCanvasBeatRasterColor);
1764       xml.colorTag(level, "partCanvasFineRaster",  MusEGlobal::config.partCanvasFineRasterColor);
1765 
1766       xml.colorTag(level, "trackBg",       MusEGlobal::config.trackBg);
1767       xml.colorTag(level, "selectTrackBg", MusEGlobal::config.selectTrackBg);
1768       xml.colorTag(level, "selectTrackFg", MusEGlobal::config.selectTrackFg);
1769       xml.colorTag(level, "selectTrackCurBg", MusEGlobal::config.selectTrackCurBg);
1770       xml.colorTag(level, "trackSectionDividerColor", MusEGlobal::config.trackSectionDividerColor);
1771 
1772 //      xml.colorTag(level, "mixerBg",            MusEGlobal::config.mixerBg);
1773       xml.colorTag(level, "midiTrackLabelBg",   MusEGlobal::config.midiTrackLabelBg);
1774       xml.colorTag(level, "newDrumTrackLabelBg2",MusEGlobal::config.newDrumTrackLabelBg);
1775       xml.colorTag(level, "waveTrackLabelBg",   MusEGlobal::config.waveTrackLabelBg);
1776       xml.colorTag(level, "outputTrackLabelBg", MusEGlobal::config.outputTrackLabelBg);
1777       xml.colorTag(level, "inputTrackLabelBg",  MusEGlobal::config.inputTrackLabelBg);
1778       xml.colorTag(level, "groupTrackLabelBg",  MusEGlobal::config.groupTrackLabelBg);
1779       xml.colorTag(level, "auxTrackLabelBg2",   MusEGlobal::config.auxTrackLabelBg);
1780       xml.colorTag(level, "synthTrackLabelBg",  MusEGlobal::config.synthTrackLabelBg);
1781 
1782       xml.colorTag(level, "midiTrackBg",   MusEGlobal::config.midiTrackBg);
1783       xml.colorTag(level, "ctrlGraphFg",   MusEGlobal::config.ctrlGraphFg);
1784       xml.colorTag(level, "ctrlGraphSel",  MusEGlobal::config.ctrlGraphSel);
1785       xml.colorTag(level, "drumTrackBg",   MusEGlobal::config.drumTrackBg);
1786       xml.colorTag(level, "newDrumTrackBg",MusEGlobal::config.newDrumTrackBg);
1787       xml.colorTag(level, "waveTrackBg",   MusEGlobal::config.waveTrackBg);
1788       xml.colorTag(level, "outputTrackBg", MusEGlobal::config.outputTrackBg);
1789       xml.colorTag(level, "inputTrackBg",  MusEGlobal::config.inputTrackBg);
1790       xml.colorTag(level, "groupTrackBg",  MusEGlobal::config.groupTrackBg);
1791       xml.colorTag(level, "auxTrackBg",    MusEGlobal::config.auxTrackBg);
1792       xml.colorTag(level, "synthTrackBg",  MusEGlobal::config.synthTrackBg);
1793 
1794       xml.colorTag(level, "sliderBarDefaultColor",  MusEGlobal::config.sliderBarColor);
1795       xml.colorTag(level, "sliderDefaultColor2",  MusEGlobal::config.sliderBackgroundColor);
1796       xml.colorTag(level, "panSliderColor2",  MusEGlobal::config.panSliderColor);
1797       xml.colorTag(level, "gainSliderColor2",  MusEGlobal::config.gainSliderColor);
1798       xml.colorTag(level, "auxSliderColor2",  MusEGlobal::config.auxSliderColor);
1799       xml.colorTag(level, "audioVolumeSliderColor2",  MusEGlobal::config.audioVolumeSliderColor);
1800       xml.colorTag(level, "midiVolumeSliderColor2",  MusEGlobal::config.midiVolumeSliderColor);
1801       xml.colorTag(level, "audioVolumeHandleColor",  MusEGlobal::config.audioVolumeHandleColor);
1802       xml.colorTag(level, "midiVolumeHandleColor",  MusEGlobal::config.midiVolumeHandleColor);
1803       xml.colorTag(level, "audioControllerSliderDefaultColor2",  MusEGlobal::config.audioControllerSliderColor);
1804       xml.colorTag(level, "audioPropertySliderDefaultColor2",  MusEGlobal::config.audioPropertySliderColor);
1805       xml.colorTag(level, "midiControllerSliderDefaultColor2",  MusEGlobal::config.midiControllerSliderColor);
1806       xml.colorTag(level, "midiPropertySliderDefaultColor2",  MusEGlobal::config.midiPropertySliderColor);
1807       xml.colorTag(level, "midiPatchReadoutColor",  MusEGlobal::config.midiPatchReadoutColor);
1808       xml.colorTag(level, "knobFontColor",  MusEGlobal::config.knobFontColor);
1809       xml.colorTag(level, "audioMeterPrimaryColor",  MusEGlobal::config.audioMeterPrimaryColor);
1810       xml.colorTag(level, "midiMeterPrimaryColor",  MusEGlobal::config.midiMeterPrimaryColor);
1811       xml.colorTag(level, "meterBackgroundColor",  MusEGlobal::config.meterBackgroundColor);
1812 
1813       xml.colorTag(level, "rackItemBackgroundColor",  MusEGlobal::config.rackItemBackgroundColor);
1814       xml.colorTag(level, "rackItemBgActiveColor",  MusEGlobal::config.rackItemBgActiveColor);
1815       xml.colorTag(level, "rackItemFontColor",  MusEGlobal::config.rackItemFontColor);
1816       xml.colorTag(level, "rackItemFontActiveColor",  MusEGlobal::config.rackItemFontActiveColor);
1817       xml.colorTag(level, "rackItemBorderColor",  MusEGlobal::config.rackItemBorderColor);
1818       xml.colorTag(level, "rackItemFontColorHover",  MusEGlobal::config.rackItemFontColorHover);
1819 
1820       xml.colorTag(level, "midiInstrumentBackgroundColor",  MusEGlobal::config.midiInstrumentBackgroundColor);
1821       xml.colorTag(level, "midiInstrumentBgActiveColor",  MusEGlobal::config.midiInstrumentBgActiveColor);
1822       xml.colorTag(level, "midiInstrumentFontColor",  MusEGlobal::config.midiInstrumentFontColor);
1823       xml.colorTag(level, "midiInstrumentFontActiveColor",  MusEGlobal::config.midiInstrumentFontActiveColor);
1824       xml.colorTag(level, "midiInstrumentBorderColor",  MusEGlobal::config.midiInstrumentBorderColor);
1825 
1826       xml.colorTag(level, "transportHandleColor",  MusEGlobal::config.transportHandleColor);
1827       xml.colorTag(level, "bigtimeForegroundcolor", MusEGlobal::config.bigTimeForegroundColor);
1828       xml.colorTag(level, "bigtimeBackgroundcolor", MusEGlobal::config.bigTimeBackgroundColor);
1829       xml.colorTag(level, "waveEditBackgroundColor", MusEGlobal::config.waveEditBackgroundColor);
1830       xml.colorTag(level, "rulerBackgroundColor", MusEGlobal::config.rulerBg);
1831       xml.colorTag(level, "rulerForegroundColor", MusEGlobal::config.rulerFg);
1832       xml.colorTag(level, "rulerCurrentColor", MusEGlobal::config.rulerCurrent);
1833 
1834       xml.colorTag(level, "waveNonselectedPart", MusEGlobal::config.waveNonselectedPart);
1835       xml.colorTag(level, "wavePeakColor", MusEGlobal::config.wavePeakColor);
1836       xml.colorTag(level, "waveRmsColor", MusEGlobal::config.waveRmsColor);
1837       xml.colorTag(level, "wavePeakColorSelected", MusEGlobal::config.wavePeakColorSelected);
1838       xml.colorTag(level, "waveRmsColorSelected", MusEGlobal::config.waveRmsColorSelected);
1839 
1840       xml.colorTag(level, "partWaveColorPeak", MusEGlobal::config.partWaveColorPeak);
1841       xml.colorTag(level, "partWaveColorRms", MusEGlobal::config.partWaveColorRms);
1842       xml.colorTag(level, "partMidiDarkEventColor", MusEGlobal::config.partMidiDarkEventColor);
1843       xml.colorTag(level, "partMidiLightEventColor", MusEGlobal::config.partMidiLightEventColor);
1844 
1845       xml.colorTag(level, "midiCanvasBackgroundColor", MusEGlobal::config.midiCanvasBg);
1846       xml.colorTag(level, "midiCanvasFineColor", MusEGlobal::config.midiCanvasFineColor);
1847       xml.colorTag(level, "midiCanvasBeatColor", MusEGlobal::config.midiCanvasBeatColor);
1848       xml.colorTag(level, "midiCanvasBarColor", MusEGlobal::config.midiCanvasBarColor);
1849       xml.colorTag(level, "midiDividerColor", MusEGlobal::config.midiDividerColor);
1850 
1851       xml.colorTag(level, "midiItemColor", MusEGlobal::config.midiItemColor);
1852       xml.colorTag(level, "midiItemSelectedColor", MusEGlobal::config.midiItemSelectedColor);
1853 
1854       xml.colorTag(level, "midiControllerViewBackgroundColor", MusEGlobal::config.midiControllerViewBg);
1855       xml.colorTag(level, "drumListBackgroundColor", MusEGlobal::config.drumListBg);
1856       xml.colorTag(level, "drumListFont", MusEGlobal::config.drumListFont);
1857       xml.colorTag(level, "drumListSel", MusEGlobal::config.drumListSel);
1858       xml.colorTag(level, "drumListSelFont", MusEGlobal::config.drumListSelFont);
1859 
1860       xml.colorTag(level, "pianoCurrentKey", MusEGlobal::config.pianoCurrentKey);
1861       xml.colorTag(level, "pianoPressedKey", MusEGlobal::config.pianoPressedKey);
1862       xml.colorTag(level, "pianoSelectedKey", MusEGlobal::config.pianoSelectedKey);
1863 
1864       xml.colorTag(level, "markerColor", MusEGlobal::config.markerColor);
1865       xml.colorTag(level, "rangeMarkerColor", MusEGlobal::config.rangeMarkerColor);
1866       xml.colorTag(level, "positionMarkerColor", MusEGlobal::config.positionMarkerColor);
1867       xml.colorTag(level, "currentPositionColor", MusEGlobal::config.currentPositionColor);
1868 }
1869 
1870 
1871 } // namespace MusECore
1872 
1873 namespace MusEGui {
1874 
1875 //---------------------------------------------------------
1876 //   writeGlobalConfiguration
1877 //---------------------------------------------------------
1878 
writeGlobalConfiguration() const1879 void MusE::writeGlobalConfiguration() const
1880       {
1881       FILE* f = fopen(MusEGlobal::configName.toLatin1().constData(), "w");
1882       if (f == nullptr) {
1883             fprintf(stderr, "save configuration to <%s> failed: %s\n",
1884                MusEGlobal::configName.toLatin1().constData(), strerror(errno));
1885             return;
1886             }
1887       MusECore::Xml xml(f);
1888       xml.header();
1889       xml.nput(0, "<muse version=\"%d.%d\">\n", xml.latestMajorVersion(), xml.latestMinorVersion());
1890       writeGlobalConfiguration(1, xml);
1891       xml.tag(1, "/muse");
1892       fclose(f);
1893       }
1894 
loadConfigurationColors(QWidget * parent)1895 bool MusE::loadConfigurationColors(QWidget* parent)
1896 {
1897   if(!parent)
1898     parent = this;
1899   //QString file = QFileDialog::getOpenFileName(parent, tr("Load configuration colors"), QString(), tr("MusE color configuration files *.cfc (*.cfc)"));
1900   QString file = MusEGui::getOpenFileName(QString("themes"), MusEGlobal::colors_config_file_pattern, this,
1901                                                tr("Load configuration colors"), nullptr, MusEGui::MFileDialog::GLOBAL_VIEW);
1902 
1903   if(file.isEmpty())
1904     return false;
1905 
1906   if(QMessageBox::question(parent, QString("MusE"),
1907       tr("Color settings will immediately be replaced with any found in the file.\nAre you sure you want to proceed?"), tr("&Ok"), tr("&Cancel"),
1908       QString(), 0, 1 ) == 1)
1909     return false;
1910 
1911   // Read, and return if error.
1912   if(MusECore::readConfiguration(file.toLatin1().constData()))   // True if error.
1913   {
1914     fprintf(stderr, "MusE::loadConfigurationColors failed\n");
1915     return false;
1916   }
1917   // Notify app, and write into configuration file.
1918   // Save settings. Use simple version - do NOT set style or stylesheet, this has nothing to do with that.
1919   changeConfig(false);
1920   return true;
1921 }
1922 
saveConfigurationColors(QWidget * parent)1923 bool MusE::saveConfigurationColors(QWidget* parent)
1924 {
1925   if(!parent)
1926     parent = this;
1927   QString file = MusEGui::getSaveFileName(QString("themes"), MusEGlobal::colors_config_file_pattern, this,
1928                                                tr("Save configuration colors"), nullptr, MusEGui::MFileDialog::USER_VIEW);
1929 
1930   if(file.isEmpty())
1931     return false;
1932 
1933 // redundant, this is already done by the file dialog itself (kybos)
1934 //  if(QFile::exists(file))
1935 //  {
1936 //    if(QMessageBox::question(parent, QString("MusE"),
1937 //        tr("File exists.\nDo you want to overwrite it?"), tr("&Ok"), tr("&Cancel"),
1938 //        QString(), 0, 1 ) == 1)
1939 //      return false;
1940 //  }
1941 
1942   FILE* f = fopen(file.toLatin1().constData(), "w");
1943   if (f == nullptr)
1944   {
1945     fprintf(stderr, "save configuration colors to <%s> failed: %s\n",
1946         file.toLatin1().constData(), strerror(errno));
1947     return false;
1948   }
1949   MusECore::Xml xml(f);
1950   xml.header();
1951   xml.nput(0, "<muse version=\"%d.%d\">\n", xml.latestMajorVersion(), xml.latestMinorVersion());
1952   xml.tag(1, "configuration");
1953   MusECore::writeConfigurationColors(2, xml, false); // Don't save part colour names.
1954   xml.etag(1, "configuration");
1955   xml.tag(0, "/muse");
1956   fclose(f);
1957   return true;
1958 }
1959 
writeGlobalConfiguration(int level,MusECore::Xml & xml) const1960 void MusE::writeGlobalConfiguration(int level, MusECore::Xml& xml) const
1961       {
1962       xml.tag(level++, "configuration");
1963 
1964       xml.strTag(level, "pluginLadspaPathList", MusEGlobal::config.pluginLadspaPathList.join(":"));
1965       xml.strTag(level, "pluginDssiPathList", MusEGlobal::config.pluginDssiPathList.join(":"));
1966       xml.strTag(level, "pluginVstsPathList", MusEGlobal::config.pluginVstPathList.join(":"));
1967       xml.strTag(level, "pluginLinuxVstsPathList", MusEGlobal::config.pluginLinuxVstPathList.join(":"));
1968       xml.strTag(level, "pluginLv2PathList", MusEGlobal::config.pluginLv2PathList.join(":"));
1969 
1970       if(MusEGlobal::defaultAudioConverterSettings)
1971         MusEGlobal::defaultAudioConverterSettings->write(level, xml, &MusEGlobal::audioConverterPluginList);
1972 
1973       xml.intTag(level, "pluginCacheTriggerRescan", MusEGlobal::config.pluginCacheTriggerRescan);
1974 
1975       xml.intTag(level, "enableAlsaMidiDriver", MusEGlobal::config.enableAlsaMidiDriver);
1976       xml.intTag(level, "division", MusEGlobal::config.division);
1977       xml.intTag(level, "rtcTicks", MusEGlobal::config.rtcTicks);
1978       xml.intTag(level, "curMidiSyncInPort", MusEGlobal::config.curMidiSyncInPort);
1979       xml.intTag(level, "midiSendInit", MusEGlobal::config.midiSendInit);
1980       xml.intTag(level, "warnInitPending", MusEGlobal::config.warnInitPending);
1981       xml.intTag(level, "midiSendCtlDefaults", MusEGlobal::config.midiSendCtlDefaults);
1982       xml.intTag(level, "midiSendNullParameters", MusEGlobal::config.midiSendNullParameters);
1983       xml.intTag(level, "midiOptimizeControllers", MusEGlobal::config.midiOptimizeControllers);
1984       xml.intTag(level, "warnIfBadTiming", MusEGlobal::config.warnIfBadTiming);
1985       xml.intTag(level, "warnOnFileVersions", MusEGlobal::config.warnOnFileVersions);
1986       xml.intTag(level, "minMeter", MusEGlobal::config.minMeter);
1987       xml.doubleTag(level, "minSlider", MusEGlobal::config.minSlider);
1988       xml.intTag(level, "freewheelMode", MusEGlobal::config.freewheelMode);
1989       xml.intTag(level, "denormalProtection", MusEGlobal::config.useDenormalBias);
1990       xml.intTag(level, "didYouKnow", MusEGlobal::config.showDidYouKnow);
1991       xml.intTag(level, "outputLimiter", MusEGlobal::config.useOutputLimiter);
1992       xml.intTag(level, "vstInPlace", MusEGlobal::config.vstInPlace);
1993 
1994       xml.intTag(level, "deviceAudioBufSize", MusEGlobal::config.deviceAudioBufSize);
1995       xml.intTag(level, "deviceAudioSampleRate", MusEGlobal::config.deviceAudioSampleRate);
1996       xml.intTag(level, "deviceAudioBackend", MusEGlobal::config.deviceAudioBackend);
1997 
1998       xml.intTag(level, "enableLatencyCorrection", MusEGlobal::config.enableLatencyCorrection);
1999       xml.intTag(level, "correctUnterminatedInBranchLatency", MusEGlobal::config.correctUnterminatedInBranchLatency);
2000       xml.intTag(level, "correctUnterminatedOutBranchLatency", MusEGlobal::config.correctUnterminatedOutBranchLatency);
2001       xml.intTag(level, "monitoringAffectsLatency", MusEGlobal::config.monitoringAffectsLatency);
2002       xml.intTag(level, "commonProjectLatency", MusEGlobal::config.commonProjectLatency);
2003 
2004       xml.uintTag(level, "minControlProcessPeriod", MusEGlobal::config.minControlProcessPeriod);
2005       xml.intTag(level, "guiRefresh", MusEGlobal::config.guiRefresh);
2006 
2007       xml.intTag(level, "extendedMidi", MusEGlobal::config.extendedMidi);
2008       xml.intTag(level, "midiExportDivision", MusEGlobal::config.midiDivision);
2009       xml.strTag(level, "copyright", MusEGlobal::config.copyright);
2010       xml.intTag(level, "smfFormat", MusEGlobal::config.smfFormat);
2011       xml.intTag(level, "expRunningStatus", MusEGlobal::config.expRunningStatus);
2012       xml.intTag(level, "exp2ByteTimeSigs", MusEGlobal::config.exp2ByteTimeSigs);
2013       xml.intTag(level, "expOptimNoteOffs", MusEGlobal::config.expOptimNoteOffs);
2014       xml.intTag(level, "importMidiSplitParts", MusEGlobal::config.importMidiSplitParts);
2015       xml.intTag(level, "importDevNameMetas", MusEGlobal::config.importDevNameMetas);
2016       xml.intTag(level, "useLastEditedEvent", MusEGlobal::config.useLastEditedEvent);
2017       xml.intTag(level, "importInstrNameMetas", MusEGlobal::config.importInstrNameMetas);
2018       xml.intTag(level, "exportPortsDevices", MusEGlobal::config.exportPortsDevices);
2019       xml.intTag(level, "exportPortDeviceSMF0", MusEGlobal::config.exportPortDeviceSMF0);
2020       xml.intTag(level, "exportDrumMapOverrides", MusEGlobal::config.exportDrumMapOverrides);
2021       xml.intTag(level, "exportChannelOverridesToNewTrack", MusEGlobal::config.exportChannelOverridesToNewTrack);
2022       xml.intTag(level, "exportModeInstr", MusEGlobal::config.exportModeInstr);
2023       xml.strTag(level, "importMidiDefaultInstr", MusEGlobal::config.importMidiDefaultInstr);
2024       xml.intTag(level, "startMode", MusEGlobal::config.startMode);
2025       xml.strTag(level, "startSong", MusEGlobal::config.startSong);
2026       xml.intTag(level, "startSongLoadConfig", MusEGlobal::config.startSongLoadConfig);
2027       xml.intTag(level, "newDrumRecordCondition", MusEGlobal::config.newDrumRecordCondition);
2028       xml.strTag(level, "projectBaseFolder", MusEGlobal::config.projectBaseFolder);
2029       xml.intTag(level, "projectStoreInFolder", MusEGlobal::config.projectStoreInFolder);
2030       xml.intTag(level, "useProjectSaveDialog", MusEGlobal::config.useProjectSaveDialog);
2031       xml.intTag(level, "midiInputDevice", MusEGlobal::midiInputPorts);
2032       xml.intTag(level, "midiInputChannel", MusEGlobal::midiInputChannel);
2033       xml.intTag(level, "midiRecordType", MusEGlobal::midiRecordType);
2034       xml.intTag(level, "midiThruType", MusEGlobal::midiThruType);
2035       xml.intTag(level, "midiFilterCtrl1", MusEGlobal::midiFilterCtrl1);
2036       xml.intTag(level, "midiFilterCtrl2", MusEGlobal::midiFilterCtrl2);
2037       xml.intTag(level, "midiFilterCtrl3", MusEGlobal::midiFilterCtrl3);
2038       xml.intTag(level, "midiFilterCtrl4", MusEGlobal::midiFilterCtrl4);
2039 
2040       xml.intTag(level, "preferredRouteNameOrAlias", static_cast<int>(MusEGlobal::config.preferredRouteNameOrAlias));
2041       xml.intTag(level, "routerExpandVertically", MusEGlobal::config.routerExpandVertically);
2042       xml.intTag(level, "routerGroupingChannels", MusEGlobal::config.routerGroupingChannels);
2043 
2044 //      xml.strTag(level, "qtStyle", MusEGlobal::config.style);
2045       xml.intTag(level, "autoSave", MusEGlobal::config.autoSave);
2046       xml.strTag(level, "museTheme", MusEGlobal::config.theme);
2047       xml.strTag(level, "externalWavEditor", MusEGlobal::config.externalWavEditor);
2048       xml.intTag(level, "useOldStyleStopShortCut", MusEGlobal::config.useOldStyleStopShortCut);
2049       xml.intTag(level, "useRewindOnStop", MusEGlobal::config.useRewindOnStop);
2050       xml.intTag(level, "moveArmedCheckBox", MusEGlobal::config.moveArmedCheckBox);
2051       xml.intTag(level, "popupsDefaultStayOpen", MusEGlobal::config.popupsDefaultStayOpen);
2052       xml.intTag(level, "leftMouseButtonCanDecrease", MusEGlobal::config.leftMouseButtonCanDecrease);
2053 //      xml.intTag(level, "rangeMarkerWithoutMMB", MusEGlobal::config.rangeMarkerWithoutMMB);
2054       xml.intTag(level, "smartFocus", MusEGlobal::config.smartFocus);
2055       xml.intTag(level, "borderlessMouse", MusEGlobal::config.borderlessMouse);
2056       xml.intTag(level, "velocityPerNote", MusEGlobal::config.velocityPerNote);
2057 
2058       xml.intTag(level, "unhideTracks", MusEGlobal::config.unhideTracks);
2059       xml.intTag(level, "addHiddenTracks", MusEGlobal::config.addHiddenTracks);
2060       // Obsolete. There is only 'New' drum tracks now.
2061       // drumTrackPreference is fixed until it is removed some day...
2062       //xml.intTag(level, "drumTrackPreference", MusEGlobal::config.drumTrackPreference);
2063 
2064 #ifdef _USE_INSTRUMENT_OVERRIDES_
2065       MusECore::midiInstruments.writeDrummapOverrides(level, xml);
2066 #endif
2067 
2068       xml.intTag(level, "waveTracksVisible",  MusECore::WaveTrack::visible());
2069       xml.intTag(level, "auxTracksVisible",  MusECore::AudioAux::visible());
2070       xml.intTag(level, "groupTracksVisible",  MusECore::AudioGroup::visible());
2071       xml.intTag(level, "midiTracksVisible",  MusECore::MidiTrack::visible());
2072       xml.intTag(level, "inputTracksVisible",  MusECore::AudioInput::visible());
2073       xml.intTag(level, "outputTracksVisible",  MusECore::AudioOutput::visible());
2074       xml.intTag(level, "synthTracksVisible",  MusECore::SynthI::visible());
2075       xml.intTag(level, "trackHeight",  MusEGlobal::config.trackHeight);
2076       xml.intTag(level, "scrollableSubMenus", MusEGlobal::config.scrollableSubMenus);
2077       xml.intTag(level, "liveWaveUpdate", MusEGlobal::config.liveWaveUpdate);
2078       xml.intTag(level, "audioEffectsRackVisibleItems", MusEGlobal::config.audioEffectsRackVisibleItems);
2079       xml.intTag(level, "preferKnobsVsSliders", MusEGlobal::config.preferKnobsVsSliders);
2080       xml.intTag(level, "showControlValues", MusEGlobal::config.showControlValues);
2081       xml.intTag(level, "monitorOnRecord", MusEGlobal::config.monitorOnRecord);
2082       xml.intTag(level, "lineEditStyleHack", MusEGlobal::config.lineEditStyleHack);
2083       xml.intTag(level, "preferMidiVolumeDb", MusEGlobal::config.preferMidiVolumeDb);
2084       xml.intTag(level, "midiCtrlGraphMergeErase", MusEGlobal::config.midiCtrlGraphMergeErase);
2085       xml.intTag(level, "midiCtrlGraphMergeEraseInclusive", MusEGlobal::config.midiCtrlGraphMergeEraseInclusive);
2086       xml.intTag(level, "midiCtrlGraphMergeEraseWysiwyg", MusEGlobal::config.midiCtrlGraphMergeEraseWysiwyg);
2087       xml.intTag(level, "lv2UiBehavior", static_cast<int>(MusEGlobal::config.lv2UiBehavior));
2088       xml.strTag(level, "mixdownPath", MusEGlobal::config.mixdownPath);
2089       xml.intTag(level, "showNoteNamesInPianoRoll", MusEGlobal::config.showNoteNamesInPianoRoll);
2090       xml.intTag(level, "showNoteTooltips", MusEGlobal::config.showNoteTooltips);
2091       xml.intTag(level, "showTimeScaleBeatNumbers", MusEGlobal::config.showTimeScaleBeatNumbers);
2092       xml.intTag(level, "noPluginScaling", MusEGlobal::config.noPluginScaling);
2093 //      xml.intTag(level, "openMDIWinMaximized", MusEGlobal::config.openMDIWinMaximized);
2094       xml.intTag(level, "keepTransportWindowOnTop", MusEGlobal::config.keepTransportWindowOnTop);
2095       xml.intTag(level, "showStatusBar", MusEGlobal::config.showStatusBar);
2096 
2097       for (int i = 1; i < NUM_FONTS; ++i) {
2098 //          for (int i = 0; i < NUM_FONTS; ++i) {
2099             xml.strTag(level, QString("font") + QString::number(i), MusEGlobal::config.fonts[i].toString());
2100             }
2101       xml.intTag(level, "autoAdjustFontSize", MusEGlobal::config.autoAdjustFontSize);
2102 
2103       xml.intTag(level, "globalAlphaBlend", MusEGlobal::config.globalAlphaBlend);
2104 
2105 //      MusECore::writeConfigurationColors(level, xml);
2106 
2107       xml.intTag(level, "mtctype", MusEGlobal::mtcType);
2108       xml.nput(level, "<mtcoffset>%02d:%02d:%02d:%02d:%02d</mtcoffset>\n",
2109         MusEGlobal::mtcOffset.h(), MusEGlobal::mtcOffset.m(), MusEGlobal::mtcOffset.s(),
2110         MusEGlobal::mtcOffset.f(), MusEGlobal::mtcOffset.sf());
2111       xml.intTag(level, "extSync", MusEGlobal::extSyncFlag);
2112       xml.intTag(level, "useJackTransport", MusEGlobal::config.useJackTransport);
2113       xml.intTag(level, "timebaseMaster", MusEGlobal::config.timebaseMaster);
2114 
2115       xml.qrectTag(level, "geometryMain",      MusEGlobal::config.geometryMain);
2116       xml.qrectTag(level, "geometryTransport", MusEGlobal::config.geometryTransport);
2117       xml.qrectTag(level, "geometryBigTime",   MusEGlobal::config.geometryBigTime);
2118 
2119       xml.intTag(level, "bigtimeVisible", MusEGlobal::config.bigTimeVisible);
2120       xml.intTag(level, "transportVisible", MusEGlobal::config.transportVisible);
2121 
2122       xml.intTag(level, "mixer1Visible", MusEGlobal::config.mixer1Visible);
2123       xml.intTag(level, "mixer2Visible", MusEGlobal::config.mixer2Visible);
2124       // True = Write global config.
2125       MusEGlobal::config.mixer1.write(level, xml, true);
2126       MusEGlobal::config.mixer2.write(level, xml, true);
2127 
2128       xml.intTag(level, "showSplashScreen", MusEGlobal::config.showSplashScreen);
2129       xml.intTag(level, "canvasShowPartType", MusEGlobal::config.canvasShowPartType);
2130       xml.intTag(level, "canvasShowPartEvent", MusEGlobal::config.canvasShowPartEvent);
2131       xml.intTag(level, "canvasShowGrid", MusEGlobal::config.canvasShowGrid);
2132       xml.intTag(level, "canvasShowGridHorizontalAlways", MusEGlobal::config.canvasShowGridHorizontalAlways);
2133       xml.intTag(level, "canvasShowGridBeatsAlways", MusEGlobal::config.canvasShowGridBeatsAlways);
2134       xml.intTag(level, "useTrackColorForParts", MusEGlobal::config.useTrackColorForParts);
2135       xml.strTag(level, "canvasBgPixmap", MusEGlobal::config.canvasBgPixmap);
2136       xml.strTag(level, "canvasCustomBgList", MusEGlobal::config.canvasCustomBgList.join(";"));
2137 
2138       xml.intTag(level, "maxAliasedPointSize", MusEGlobal::config.maxAliasedPointSize);
2139 
2140       xml.intTag(level, "iconSize", MusEGlobal::config.iconSize);
2141       xml.intTag(level, "cursorSize", MusEGlobal::config.cursorSize);
2142       xml.intTag(level, "trackGradientStrength", MusEGlobal::config.trackGradientStrength);
2143       xml.intTag(level, "partGradientStrength", MusEGlobal::config.partGradientStrength);
2144       xml.intTag(level, "cascadeStylesheets", MusEGlobal::config.cascadeStylesheets);
2145       xml.intTag(level, "showIconsInMenus", MusEGlobal::config.showIconsInMenus);
2146       xml.intTag(level, "useNativeStandardDialogs", MusEGlobal::config.useNativeStandardDialogs);
2147 
2148       MusEGlobal::writePluginGroupConfiguration(level, xml);
2149       MusEGui::SynthDialog::writeFavConfiguration(level, xml);
2150 
2151       writeSeqConfiguration(level, xml, false);
2152 
2153       MusEGui::DrumEdit::writeConfiguration(level, xml);
2154       MusEGui::PianoRoll::writeConfiguration(level, xml);
2155       MusEGui::ScoreEdit::write_configuration(level, xml);
2156       MusEGui::MasterEdit::writeConfiguration(level, xml);
2157       MusEGui::WaveEdit::writeConfiguration(level, xml);
2158 //      MusEGui::ListEdit::writeConfiguration(level, xml);
2159 //      MusEGui::LMaster::writeConfiguration(level, xml);
2160       arrangerView->writeConfiguration(level, xml);
2161 
2162       MusEGui::write_function_dialog_config(level, xml);
2163 
2164       MusEGui::writeShortCuts(level, xml);
2165       xml.etag(level, "configuration");
2166       }
2167 
2168 //---------------------------------------------------------
2169 //   writeConfiguration
2170 //    write song specific configuration
2171 //---------------------------------------------------------
2172 
writeConfiguration(int level,MusECore::Xml & xml) const2173 void MusE::writeConfiguration(int level, MusECore::Xml& xml) const
2174       {
2175       xml.tag(level++, "configuration");
2176 
2177       xml.intTag(level, "midiInputDevice",  MusEGlobal::midiInputPorts);
2178       xml.intTag(level, "midiInputChannel", MusEGlobal::midiInputChannel);
2179       xml.intTag(level, "midiRecordType",   MusEGlobal::midiRecordType);
2180       xml.intTag(level, "midiThruType",     MusEGlobal::midiThruType);
2181       xml.intTag(level, "midiFilterCtrl1",  MusEGlobal::midiFilterCtrl1);
2182       xml.intTag(level, "midiFilterCtrl2",  MusEGlobal::midiFilterCtrl2);
2183       xml.intTag(level, "midiFilterCtrl3",  MusEGlobal::midiFilterCtrl3);
2184       xml.intTag(level, "midiFilterCtrl4",  MusEGlobal::midiFilterCtrl4);
2185 
2186       xml.intTag(level, "mtctype", MusEGlobal::mtcType);
2187       xml.nput(level, "<mtcoffset>%02d:%02d:%02d:%02d:%02d</mtcoffset>\n",
2188         MusEGlobal::mtcOffset.h(), MusEGlobal::mtcOffset.m(), MusEGlobal::mtcOffset.s(),
2189         MusEGlobal::mtcOffset.f(), MusEGlobal::mtcOffset.sf());
2190       xml.uintTag(level, "sendClockDelay", MusEGlobal::syncSendFirstClockDelay);
2191       xml.intTag(level, "useJackTransport", MusEGlobal::config.useJackTransport);
2192       xml.intTag(level, "timebaseMaster", MusEGlobal::config.timebaseMaster);
2193       xml.intTag(level, "syncRecFilterPreset", MusEGlobal::syncRecFilterPreset);
2194       xml.doubleTag(level, "syncRecTempoValQuant", MusEGlobal::syncRecTempoValQuant);
2195       xml.intTag(level, "extSync", MusEGlobal::extSyncFlag);
2196 
2197       xml.intTag(level, "bigtimeVisible",   viewBigtimeAction->isChecked());
2198       xml.intTag(level, "transportVisible", viewTransportAction->isChecked());
2199 
2200       xml.geometryTag(level, "geometryMain", this); // FINDME: maybe remove this? do we want
2201                                                     // the main win to jump around when loading?
2202       if (transport)
2203             xml.geometryTag(level, "geometryTransport", transport);
2204       if (bigtime)
2205             xml.geometryTag(level, "geometryBigTime", bigtime);
2206 
2207       // i thought this was obsolete, but it seems to be necessary (flo)
2208       xml.intTag(level, "markerVisible", viewMarkerAction->isChecked());
2209       // but storing the geometry IS obsolete. this is really
2210       // done by TopLevel::writeConfiguration
2211 
2212       xml.intTag(level, "mixer1Visible",    viewMixerAAction->isChecked());
2213       xml.intTag(level, "mixer2Visible",    viewMixerBAction->isChecked());
2214       // False = Write song-specific config.
2215       MusEGlobal::config.mixer1.write(level, xml, false);
2216       MusEGlobal::config.mixer2.write(level, xml, false);
2217 
2218       writeSeqConfiguration(level, xml, true);
2219 
2220       MusEGui::write_function_dialog_config(level, xml);
2221 
2222       writeMidiTransforms(level, xml);
2223       writeMidiInputTransforms(level, xml);
2224       xml.etag(level, "configuration");
2225       }
2226 
2227 //---------------------------------------------------------
2228 //   configMidiSync
2229 //---------------------------------------------------------
2230 
configMidiSync()2231 void MusE::configMidiSync()
2232       {
2233       if (!midiSyncConfig)
2234         // NOTE: For deleting parentless dialogs and widgets, please add them to MusE::deleteParentlessDialogs().
2235         midiSyncConfig = new MusEGui::MidiSyncConfig;
2236 
2237       if (midiSyncConfig->isVisible()) {
2238           midiSyncConfig->raise();
2239           midiSyncConfig->activateWindow();
2240           }
2241       else
2242             midiSyncConfig->show();
2243       }
2244 
2245 //---------------------------------------------------------
2246 //   configMidiFile
2247 //---------------------------------------------------------
2248 
configMidiFile()2249 void MusE::configMidiFile()
2250       {
2251       if (!midiFileConfig)
2252             // NOTE: For deleting parentless dialogs and widgets, please add them to MusE::deleteParentlessDialogs().
2253             midiFileConfig = new MusEGui::MidiFileConfig();
2254       midiFileConfig->updateValues();
2255 
2256       if (midiFileConfig->isVisible()) {
2257           midiFileConfig->raise();
2258           midiFileConfig->activateWindow();
2259           }
2260       else
2261           midiFileConfig->show();
2262       }
2263 
2264 //---------------------------------------------------------
2265 //   configGlobalSettings
2266 //---------------------------------------------------------
2267 
configGlobalSettings()2268 void MusE::configGlobalSettings()
2269       {
2270       if (!globalSettingsConfig)
2271           // NOTE: For deleting parentless dialogs and widgets, please add them to MusE::deleteParentlessDialogs().
2272           globalSettingsConfig = new MusEGui::GlobalSettingsConfig();
2273 
2274       if (globalSettingsConfig->isVisible()) {
2275           globalSettingsConfig->raise();
2276           globalSettingsConfig->activateWindow();
2277           }
2278       else
2279           globalSettingsConfig->show();
2280       }
2281 
2282 
2283 //---------------------------------------------------------
2284 //   MidiFileConfig
2285 //    config properties of exported midi files
2286 //---------------------------------------------------------
2287 
MidiFileConfig(QWidget * parent)2288 MidiFileConfig::MidiFileConfig(QWidget* parent)
2289   : QDialog(parent), ConfigMidiFileBase()
2290       {
2291       setupUi(this);
2292       connect(buttonOk, SIGNAL(clicked()), SLOT(okClicked()));
2293       connect(buttonCancel, SIGNAL(clicked()), SLOT(cancelClicked()));
2294       }
2295 
2296 //---------------------------------------------------------
2297 //   updateValues
2298 //---------------------------------------------------------
2299 
updateValues()2300 void MidiFileConfig::updateValues()
2301       {
2302       importDefaultInstr->clear();
2303       for(MusECore::iMidiInstrument i = MusECore::midiInstruments.begin(); i != MusECore::midiInstruments.end(); ++i)
2304         if(!(*i)->isSynti())                            // Sorry, no synths for now.
2305           importDefaultInstr->addItem((*i)->iname());
2306       int idx = importDefaultInstr->findText(MusEGlobal::config.importMidiDefaultInstr);
2307       if(idx != -1)
2308         importDefaultInstr->setCurrentIndex(idx);
2309 
2310       QString defInstr = importDefaultInstr->currentText();
2311       if(!defInstr.isEmpty())
2312         MusEGlobal::config.importMidiDefaultInstr = defInstr;
2313 
2314       int divisionIdx = 2;
2315       switch(MusEGlobal::config.midiDivision) {
2316             case 96:  divisionIdx = 0; break;
2317             case 192:  divisionIdx = 1; break;
2318             case 384:  divisionIdx = 2; break;
2319             }
2320       divisionCombo->setCurrentIndex(divisionIdx);
2321       formatCombo->setCurrentIndex(MusEGlobal::config.smfFormat);
2322       extendedFormat->setChecked(MusEGlobal::config.extendedMidi);
2323       copyrightEdit->setText(MusEGlobal::config.copyright);
2324       runningStatus->setChecked(MusEGlobal::config.expRunningStatus);
2325       optNoteOffs->setChecked(MusEGlobal::config.expOptimNoteOffs);
2326       twoByteTimeSigs->setChecked(MusEGlobal::config.exp2ByteTimeSigs);
2327       splitPartsCheckBox->setChecked(MusEGlobal::config.importMidiSplitParts);
2328 // Obsolete. There is only 'New' drum tracks now.
2329 //       newDrumsCheckbox->setChecked(MusEGlobal::config.importMidiNewStyleDrum);
2330 //       oldDrumsCheckbox->setChecked(!MusEGlobal::config.importMidiNewStyleDrum);
2331       importDevNameMetas->setChecked(MusEGlobal::config.importDevNameMetas);
2332       importInstrNameMetas->setChecked(MusEGlobal::config.importInstrNameMetas);
2333       exportPortDeviceSMF0->setChecked(MusEGlobal::config.exportPortDeviceSMF0);
2334       drumMapOverrides->setChecked(MusEGlobal::config.exportDrumMapOverrides);
2335       channelOverridesToNewTrack->setChecked(MusEGlobal::config.exportChannelOverridesToNewTrack);
2336       exportPortMetas->setChecked(MusEGlobal::config.exportPortsDevices & MusEGlobal::PORT_NUM_META);
2337       exportDeviceNameMetas->setChecked(MusEGlobal::config.exportPortsDevices & MusEGlobal::DEVICE_NAME_META);
2338       exportModeSysexes->setChecked(MusEGlobal::config.exportModeInstr & MusEGlobal::MODE_SYSEX);
2339       exportInstrumentNames->setChecked(MusEGlobal::config.exportModeInstr & MusEGlobal::INSTRUMENT_NAME_META);
2340 
2341       }
2342 
2343 //---------------------------------------------------------
2344 //   okClicked
2345 //---------------------------------------------------------
2346 
okClicked()2347 void MidiFileConfig::okClicked()
2348       {
2349       QString defInstr = importDefaultInstr->currentText();
2350       if(!defInstr.isEmpty())
2351         MusEGlobal::config.importMidiDefaultInstr = defInstr;
2352 
2353       int divisionIdx = divisionCombo->currentIndex();
2354 
2355       int divisions[3] = { 96, 192, 384 };
2356       if (divisionIdx >= 0 && divisionIdx < 3)
2357             MusEGlobal::config.midiDivision = divisions[divisionIdx];
2358       MusEGlobal::config.extendedMidi = extendedFormat->isChecked();
2359       MusEGlobal::config.smfFormat    = formatCombo->currentIndex();
2360       MusEGlobal::config.copyright    = copyrightEdit->text();
2361       MusEGlobal::config.expRunningStatus = runningStatus->isChecked();
2362       MusEGlobal::config.expOptimNoteOffs = optNoteOffs->isChecked();
2363       MusEGlobal::config.exp2ByteTimeSigs = twoByteTimeSigs->isChecked();
2364       MusEGlobal::config.importMidiSplitParts = splitPartsCheckBox->isChecked();
2365 // Obsolete. There is only 'New' drum tracks now.
2366 //       MusEGlobal::config.importMidiNewStyleDrum = newDrumsCheckbox->isChecked();
2367 
2368       MusEGlobal::config.importDevNameMetas = importDevNameMetas->isChecked();
2369       MusEGlobal::config.importInstrNameMetas = importInstrNameMetas->isChecked();
2370       MusEGlobal::config.exportPortDeviceSMF0 = exportPortDeviceSMF0->isChecked();
2371       MusEGlobal::config.exportDrumMapOverrides = drumMapOverrides->isChecked();
2372       MusEGlobal::config.exportChannelOverridesToNewTrack = channelOverridesToNewTrack->isChecked();
2373 
2374       MusEGlobal::config.exportPortsDevices = 0;
2375       if(exportPortMetas->isChecked())
2376         MusEGlobal::config.exportPortsDevices |= MusEGlobal::PORT_NUM_META;
2377       if(exportDeviceNameMetas->isChecked())
2378         MusEGlobal::config.exportPortsDevices |= MusEGlobal::DEVICE_NAME_META;
2379 
2380       MusEGlobal::config.exportModeInstr = 0;
2381       if(exportModeSysexes->isChecked())
2382         MusEGlobal::config.exportModeInstr |= MusEGlobal::MODE_SYSEX;
2383       if(exportInstrumentNames->isChecked())
2384         MusEGlobal::config.exportModeInstr |= MusEGlobal::INSTRUMENT_NAME_META;
2385 
2386       // Save settings. Use simple version - do NOT set style or stylesheet, this has nothing to do with that.
2387       MusEGlobal::muse->changeConfig(true);  // write config file
2388       close();
2389       }
2390 
2391 //---------------------------------------------------------
2392 //   cancelClicked
2393 //---------------------------------------------------------
2394 
cancelClicked()2395 void MidiFileConfig::cancelClicked()
2396       {
2397       close();
2398       }
2399 
2400 } // namespace MusEGui
2401 
2402 
2403 namespace MusEGlobal {
2404 
2405 //---------------------------------------------------------
2406 //   write
2407 //---------------------------------------------------------
2408 
write(int level,MusECore::Xml & xml) const2409 void StripConfig::write(int level, MusECore::Xml& xml) const
2410       {
2411       if(_serial < 0)
2412         return;
2413       // Do NOT save if there is no corresponding track.
2414       const MusECore::TrackList* tl = song->tracks();
2415       const int idx = tl->indexOfSerial(_serial);
2416       if(idx < 0)
2417         return;
2418       xml.nput(level, "<StripConfig trackIdx=\"%d\"", idx);
2419 
2420       xml.nput(level, " visible=\"%d\"", _visible);
2421       if(_width >= 0)
2422         xml.nput(level, " width=\"%d\"", _width);
2423       xml.put(" />");
2424 
2425       //xml.put(">");
2426       //level++;
2427       // TODO: Anything else to add? ...
2428       //xml.etag(level, "StripConfig");
2429       }
2430 
2431 //---------------------------------------------------------
2432 //   read
2433 //---------------------------------------------------------
2434 
read(MusECore::Xml & xml)2435 void StripConfig::read(MusECore::Xml& xml)
2436       {
2437       for (;;) {
2438             MusECore::Xml::Token token(xml.parse());
2439             const QString& tag(xml.s1());
2440             switch (token) {
2441                   case MusECore::Xml::Error:
2442                   case MusECore::Xml::End:
2443                         return;
2444                   case MusECore::Xml::TagStart:
2445                           xml.unknown("StripConfig");
2446                         break;
2447                   case MusECore::Xml::Attribut:
2448                         if (tag == "trackIdx") {
2449                               _tmpFileIdx = xml.s2().toInt();
2450                               }
2451                         else if (tag == "visible") {
2452                               _visible = xml.s2().toInt();
2453                               }
2454                         else if (tag == "width") {
2455                               _width = xml.s2().toInt();
2456                               }
2457                         break;
2458                   case MusECore::Xml::TagEnd:
2459                         if (tag == "StripConfig")
2460                             return;
2461                   default:
2462                         break;
2463                   }
2464             }
2465 
2466       }
2467 
2468 //---------------------------------------------------------
2469 //   write
2470 //---------------------------------------------------------
2471 
write(int level,MusECore::Xml & xml,bool global) const2472 void MixerConfig::write(int level, MusECore::Xml& xml, bool global) const
2473       {
2474       xml.tag(level++, "Mixer");
2475 
2476       xml.strTag(level, "name", name);
2477 
2478       xml.qrectTag(level, "geometry", geometry);
2479 
2480       xml.intTag(level, "showMidiTracks",   showMidiTracks);
2481       xml.intTag(level, "showDrumTracks",   showDrumTracks);
2482       xml.intTag(level, "showNewDrumTracks",   showNewDrumTracks);
2483       xml.intTag(level, "showInputTracks",  showInputTracks);
2484       xml.intTag(level, "showOutputTracks", showOutputTracks);
2485       xml.intTag(level, "showWaveTracks",   showWaveTracks);
2486       xml.intTag(level, "showGroupTracks",  showGroupTracks);
2487       xml.intTag(level, "showAuxTracks",    showAuxTracks);
2488       xml.intTag(level, "showSyntiTracks",  showSyntiTracks);
2489 
2490       xml.intTag(level, "displayOrder", displayOrder);
2491 
2492       // Specific to song file.
2493       if(!global)
2494       {
2495         if(!stripConfigList.empty())
2496         {
2497           const int sz = stripConfigList.size();
2498           for(int i = 0; i < sz; ++i)
2499             stripConfigList.at(i).write(level, xml);
2500         }
2501       }
2502 
2503       xml.etag(level, "Mixer");
2504       }
2505 
2506 //---------------------------------------------------------
2507 //   read
2508 //---------------------------------------------------------
2509 
read(MusECore::Xml & xml)2510 void MixerConfig::read(MusECore::Xml& xml)
2511       {
2512       bool ignore_next_visible = false;
2513       for (;;) {
2514             MusECore::Xml::Token token(xml.parse());
2515             const QString& tag(xml.s1());
2516             switch (token) {
2517                   case MusECore::Xml::Error:
2518                   case MusECore::Xml::End:
2519                         return;
2520                   case MusECore::Xml::TagStart:
2521                         if (tag == "name")
2522                               name = xml.parse1();
2523                         else if (tag == "geometry")
2524                               geometry = readGeometry(xml, tag);
2525                         else if (tag == "showMidiTracks")
2526                               showMidiTracks = xml.parseInt();
2527                         else if (tag == "showDrumTracks")
2528                               showDrumTracks = xml.parseInt();
2529                         else if (tag == "showNewDrumTracks")
2530                               showNewDrumTracks = xml.parseInt();
2531                         else if (tag == "showInputTracks")
2532                               showInputTracks = xml.parseInt();
2533                         else if (tag == "showOutputTracks")
2534                               showOutputTracks = xml.parseInt();
2535                         else if (tag == "showWaveTracks")
2536                               showWaveTracks = xml.parseInt();
2537                         else if (tag == "showGroupTracks")
2538                               showGroupTracks = xml.parseInt();
2539                         else if (tag == "showAuxTracks")
2540                               showAuxTracks = xml.parseInt();
2541                         else if (tag == "showSyntiTracks")
2542                               showSyntiTracks = xml.parseInt();
2543                         else if (tag == "displayOrder")
2544                               displayOrder = (DisplayOrder)xml.parseInt();
2545                         // Obsolete. Support old songs.
2546                         else if (tag == "StripName")
2547                         {
2548                           const QString s = xml.parse1();
2549                           // Protection from duplicates in song file, observed (old flaws?).
2550                           if(stripOrder.contains(s))
2551                             ignore_next_visible = true;
2552                           else
2553                             stripOrder.append(s);
2554                         }
2555                         // Obsolete. Support old songs.
2556                         else if (tag == "StripVisible")
2557                         {
2558                           // Protection from duplicates in song file, observed (old flaws?).
2559                           if(ignore_next_visible)
2560                           {
2561                             xml.parseInt();
2562                             ignore_next_visible = false;
2563                           }
2564                           else
2565                           {
2566                             stripVisibility.append(xml.parseInt() == 0 ? false : true );
2567                           }
2568                         }
2569                         else if (tag == "StripConfig") {
2570                               StripConfig sc;
2571                               sc.read(xml);
2572                               if(sc._tmpFileIdx >= 0)
2573                                 stripConfigList.append(sc);
2574                         }
2575                         else
2576                               xml.unknown("Mixer");
2577                         break;
2578                   case MusECore::Xml::TagEnd:
2579                         if (tag == "Mixer")
2580                             return;
2581                   default:
2582                         break;
2583                   }
2584             }
2585 
2586       }
2587 
2588 } // namespace MusEGlobal
2589 
2590