root/branches/undo/libs/hydrogen/src/preferences.cpp @ 1604

Revision 1604, 49.2 KB (checked in by wolke, 3 years ago)

merge rev 1601:1603 from trunk

Line 
1/*
2 * Hydrogen
3 * Copyright(c) 2002-2008 by Alex >Comix< Cominu [comix@users.sourceforge.net]
4 *
5 * http://www.hydrogen-music.org
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY, without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 *
21 */
22
23#include <stdlib.h>
24#include <hydrogen/Preferences.h>
25
26#include <hydrogen/LocalFileMng.h>
27
28#ifndef WIN32
29#include <pwd.h>
30#include <unistd.h>
31#endif
32#include <sys/types.h>
33#include <sys/stat.h>
34#include <stdlib.h>
35#include <fstream>
36#include <iostream>
37#include <cstdio>
38#include <list>
39#include <hydrogen/midiMap.h>
40
41#include <hydrogen/data_path.h>
42#include "config.h"
43#include "version.h"
44
45#include <QDir>
46#include <QApplication>
47
48namespace H2Core
49{
50
51Preferences* Preferences::__instance = NULL;
52
53void Preferences::create_instance()
54{
55        if ( __instance == 0 ) {
56                __instance = new Preferences;
57        }
58}
59
60
61Preferences::Preferences()
62                : Object( "Preferences" )
63                , demoPath( QString( DataPath::get_data_path() ) + "/demo_songs/" )
64                , m_sLastNews( "" )
65{
66        __instance = this;
67        INFOLOG( "INIT" );
68       
69        //Default jack track-outputs are post fader
70        m_nJackTrackOutputMode = POST_FADER;
71        m_bJackTrackOuts = false;
72        // switch to enable / disable lash, only on h2 startup
73        m_brestartLash = false;
74        m_bsetLash = false;
75
76        //init pre delete default
77        m_nRecPreDelete = 0;
78        m_nRecPostDelete = 0;
79
80        //server list
81        std::list<QString> sServerList;
82
83//      //musicCategories
84//      std::list<QString> m_musicCategories;
85
86        //rubberband bpm change queue
87        m_useTheRubberbandBpmChangeEvent = false;
88
89        QString rubberBandCLIPath = getenv( "PATH" );
90        QStringList rubberBandCLIPathList = rubberBandCLIPath.split(":");//linx use ":" as seperator. maybe windows and osx use other seperators
91
92        //find the Rubberband-CLI in system env
93        //if this fails a second test will check individual user settings
94        for(int i = 0; i < rubberBandCLIPathList.size(); ++i){
95                m_rubberBandCLIexecutable = rubberBandCLIPathList[i] + "/rubberband";
96                if ( QFile( m_rubberBandCLIexecutable ).exists() == true ){
97                        readPrefFileforotherplaces = false;
98                        break;
99                }else
100                {
101                        m_rubberBandCLIexecutable = "Path to Rubberband-CLI";   
102                        readPrefFileforotherplaces = true;
103                }
104        }
105
106        char * ladpath = getenv( "LADSPA_PATH" );       // read the Environment variable LADSPA_PATH
107        if ( ladpath ) {
108                INFOLOG( "Found LADSPA_PATH enviroment variable" );
109                QString sLadspaPath = QString::fromLocal8Bit(ladpath);
110                int pos;
111                while ( ( pos = sLadspaPath.indexOf( ":" ) ) != -1 ) {
112                        QString sPath = sLadspaPath.left( pos );
113                        m_ladspaPathVect.push_back( sPath );
114                        sLadspaPath = sLadspaPath.mid( pos + 1, sLadspaPath.length() );
115                }
116                m_ladspaPathVect.push_back( sLadspaPath );
117        } else {
118#ifdef Q_OS_MACX
119                m_ladspaPathVect.push_back( qApp->applicationDirPath() + "/../Resources/plugins" );
120                m_ladspaPathVect.push_back( "/Library/Audio/Plug-Ins/LADSPA/" );
121                m_ladspaPathVect.push_back( QDir::homePath().append( "/Library/Audio/Plug-Ins/LADSPA" ));
122#else
123                m_ladspaPathVect.push_back( "/usr/lib/ladspa" );
124                m_ladspaPathVect.push_back( "/usr/local/lib/ladspa" );
125#endif
126
127        }
128
129       
130
131
132        m_pDefaultUIStyle = new UIStyle();
133
134#ifdef Q_OS_MACX
135        m_sPreferencesFilename = QDir::homePath().append( "/Library/Application Support/Hydrogen/hydrogen.conf" );
136        m_sPreferencesDirectory = QDir::homePath().append( "/Library/Application Support/Hydrogen/" );
137        m_sDataDirectory = QDir::homePath().append( "/Library/Application Support/Hydrogen/data/" );
138#else
139        m_sPreferencesFilename = QDir::homePath().append( "/.hydrogen/hydrogen.conf" );
140        m_sPreferencesDirectory = QDir::homePath().append( "/.hydrogen/" );
141        m_sDataDirectory = QDir::homePath().append( "/.hydrogen/data/" );
142        m_sTmpDirectory = QDir::homePath().append( "/.hydrogen/tmp/" );
143        if ( !QDir(m_sTmpDirectory).exists() ) {
144                QDir(m_sTmpDirectory).mkdir( m_sTmpDirectory );// create the tmp directory
145        }
146#endif
147
148        __lastspatternDirectory = QDir::homePath();
149        __lastsampleDirectory = QDir::homePath(); //audio file browser
150        __playsamplesonclicking = false; // audio file browser
151        __playselectedinstrument = false; // midi keyboard and keyboard play only selected instrument
152
153        //      __rightclickedpattereditor
154        //      0 = note length
155        //      1 = note off"
156        //      2 = edit velocity
157        //      3 = edit pan
158        //      4 = edit lead lag
159        __rightclickedpattereditor = 0; //right click into pattern editor add note-off-note or edit note-length
160
161        recordEvents = false; // not recording by default
162        destructiveRecord = false; // not destructively recording by default
163        punchInPos = 0;
164        punchOutPos = -1;
165
166        __expandSongItem = true; //SoundLibraryPanel
167        __expandPatternItem = true; //SoundLibraryPanel
168        __usetimeline = false;          // use timeline
169 
170
171        /////////////////////////////////////////////////////////////////////////
172        /////////////////// DEFAULT SETTINGS ////////////////////////////////////
173        /////////////////////////////////////////////////////////////////////////
174        m_bFollowPlayhead = true;
175        // SEE ABOVE: m_brestartLash
176        // SEE ABOVE: m_bsetLash
177
178        m_bbc = false;
179        m_mmcsetplay = false;
180       
181        m_countOffset = 0;  // beatcounter
182        m_startOffset = 0;  // beatcounter
183
184        sServerList.push_back( QString("http://www.hydrogen-music.org/feeds/drumkit_list.php") );
185        m_patternCategories.push_back( QString("not_categorized") );
186
187        //___ audio engine properties ___
188        m_sAudioDriver = QString("Auto");
189        m_bUseMetronome = false;
190        m_fMetronomeVolume = 0.5;
191        m_nMaxNotes = 256;
192        m_nBufferSize = 1024;
193        m_nSampleRate = 44100;
194
195        //___ oss driver properties ___
196        m_sOSSDevice = QString("/dev/dsp");
197
198        //___ MIDI Driver properties
199        m_sMidiDriver = QString("ALSA");
200        m_sMidiPortName = QString("None");
201        m_nMidiChannelFilter = -1;
202        m_bMidiNoteOffIgnore = false;
203        m_bMidiDiscardNoteAfterAction = false;
204
205        //___  alsa audio driver properties ___
206        m_sAlsaAudioDevice = QString("hw:0");
207
208        //___  jack driver properties ___
209        m_sJackPortName1 = QString("alsa_pcm:playback_1");
210        m_sJackPortName2 = QString("alsa_pcm:playback_2");
211        m_bJackTransportMode = true;
212        m_bJackConnectDefaults = true;
213        m_bJackTrackOuts = false;
214        m_nJackTrackOutputMode = 0;
215        m_bJackMasterMode = false ;
216
217        // None: m_sDefaultEditor;
218        // SEE ABOVE: m_sDataDirectory
219        // SEE ABOVE: demoPath
220
221        //___ General properties ___
222        m_bPatternModePlaysSelected = true;
223        restoreLastSong = true;
224        m_bUseLash = false;
225        m_bShowDevelWarning = false;
226        // NONE: lastSongFilename;
227        hearNewNotes = true;
228        // NONE: m_recentFiles;
229        // NONE: m_recentFX;
230        // NONE: m_ladspaPathVect;
231        quantizeEvents = true;
232        recordEvents = false;
233        m_sLastNews = QString("-");
234
235        //___ GUI properties ___
236        m_sQTStyle = "Plastique";
237        applicationFontFamily = "Lucida Grande";
238        applicationFontPointSize = 10;
239        mixerFontFamily = "Lucida Grande";
240        mixerFontPointSize = 11;
241        mixerFalloffSpeed = 1.1;
242        m_nPatternEditorGridResolution = 8;
243        m_bPatternEditorUsingTriplets = false;
244        m_bShowInstrumentPeaks = true;
245        m_bIsFXTabVisible = true;
246        m_nPatternEditorGridHeight = 21;
247        m_nPatternEditorGridWidth = 3;
248        mainFormProperties.set(0, 0, 1000, 700, true);
249        mixerProperties.set(10, 350, 829, 276, true);
250        patternEditorProperties.set(280, 100, 706, 439, true);
251        songEditorProperties.set(10, 10, 600, 250, true);
252        drumkitManagerProperties.set(500, 20, 526, 437, true);
253        audioEngineInfoProperties.set(720, 120, 0, 0, false);
254        m_ladspaProperties[0].set(2, 20, 0, 0, false);
255        m_ladspaProperties[1].set(2, 20, 0, 0, false);
256        m_ladspaProperties[2].set(2, 20, 0, 0, false);
257        m_ladspaProperties[3].set(2, 20, 0, 0, false);
258
259        UIStyle* uis = m_pDefaultUIStyle;
260        uis->m_songEditor_backgroundColor = H2RGBColor(95, 101, 117);
261        uis->m_songEditor_alternateRowColor = H2RGBColor(128, 134, 152);
262        uis->m_songEditor_selectedRowColor = H2RGBColor(128, 134, 152);
263        uis->m_songEditor_lineColor = H2RGBColor(72, 76, 88);
264        uis->m_songEditor_textColor = H2RGBColor(196, 201, 214);
265        uis->m_songEditor_pattern1Color = H2RGBColor(97, 167, 251);
266        uis->m_patternEditor_backgroundColor = H2RGBColor(167, 168, 163);
267        uis->m_patternEditor_alternateRowColor = H2RGBColor(167, 168, 163);
268        uis->m_patternEditor_selectedRowColor = H2RGBColor(207, 208, 200);
269        uis->m_patternEditor_textColor = H2RGBColor(40, 40, 40);
270        uis->m_patternEditor_noteColor = H2RGBColor(40, 40, 40);
271        uis->m_patternEditor_lineColor = H2RGBColor(65, 65, 65);
272        uis->m_patternEditor_line1Color = H2RGBColor(75, 75, 75);
273        uis->m_patternEditor_line2Color = H2RGBColor(95, 95, 95);
274        uis->m_patternEditor_line3Color = H2RGBColor(115, 115, 115);
275        uis->m_patternEditor_line4Color = H2RGBColor(125, 125, 125);
276        uis->m_patternEditor_line5Color = H2RGBColor(135, 135, 135);
277       
278        /////////////////////////////////////////////////////////////////////////
279        //////////////// END OF DEFAULT SETTINGS ////////////////////////////////
280        /////////////////////////////////////////////////////////////////////////
281
282        loadPreferences( true );        // Global settings
283        loadPreferences( false );       // User settings
284}
285
286
287
288Preferences::~Preferences()
289{
290        savePreferences();
291
292        INFOLOG( "DESTROY" );
293        __instance = NULL;
294        delete m_pDefaultUIStyle;
295}
296
297
298
299
300
301
302///
303/// Load the preferences file
304///
305void Preferences::loadPreferences( bool bGlobal )
306{
307        bool recreate = false;  // configuration file must be recreated?
308
309        QString sPreferencesDirectory;
310        QString sPreferencesFilename;
311        QString sDataDirectory;
312        if ( bGlobal ) {
313                sPreferencesDirectory = DataPath::get_data_path();
314                sPreferencesFilename = sPreferencesDirectory + "/hydrogen.default.conf";
315                INFOLOG( "Loading preferences file (GLOBAL) [" + sPreferencesFilename + "]" );
316        } else {
317                sPreferencesFilename = m_sPreferencesFilename;
318                sPreferencesDirectory = m_sPreferencesDirectory;
319                sDataDirectory = QDir::homePath().append( "/.hydrogen/data" );
320                INFOLOG( "Loading preferences file (USER) [" + sPreferencesFilename + "]" );
321
322
323        }
324
325
326
327        // preferences directory exists?
328        QDir prefDir( sPreferencesDirectory );
329        if ( !prefDir.exists() ) {
330                if ( bGlobal ) {
331                        WARNINGLOG( "System configuration directory '" + sPreferencesDirectory + "' not found." );
332                } else {
333                        ERRORLOG( "Configuration directory '" + sPreferencesDirectory + "' not found." );
334                        createPreferencesDirectory();
335                }
336        }
337
338        // data directory exists?
339        QDir dataDir( sDataDirectory );
340        if ( !dataDir.exists() ) {
341                WARNINGLOG( "Data directory not found." );
342                createDataDirectory();
343        }
344
345        // soundLibrary directory exists?
346        QString sDir = sDataDirectory;
347        QString sDrumkitDir;
348        QString sSongDir;
349        QString sPatternDir;
350
351        INFOLOG( "Creating soundLibrary directories in " + sDir );
352       
353        sDrumkitDir = sDir + "/drumkits";
354        sSongDir = sDir + "/songs";
355        sPatternDir = sDir + "/patterns";
356       
357        QDir drumkitDir( sDrumkitDir );
358        QDir songDir( sSongDir );
359        QDir patternDir( sPatternDir );
360       
361        if ( ! drumkitDir.exists() || ! songDir.exists() || ! patternDir.exists() )
362        {
363                createSoundLibraryDirectories();
364        }
365       
366        // pref file exists?
367        std::ifstream input( sPreferencesFilename.toLocal8Bit() , std::ios::in | std::ios::binary );
368        if ( input ) {
369
370                // read preferences file
371                QDomDocument doc = LocalFileMng::openXmlDocument( sPreferencesFilename );
372                QDomNode rootNode = doc.firstChildElement( "hydrogen_preferences" );
373               
374                if ( !rootNode.isNull() ) {
375
376                        // version
377                        QString version = LocalFileMng::readXmlString( rootNode, "version", "" );
378                        if ( version.isEmpty() ) {
379                                recreate = true;
380                        }
381
382                        //////// GENERAL ///////////
383                        //m_sLadspaPath = LocalFileMng::readXmlString( this, rootNode, "ladspaPath", m_sLadspaPath );
384                        m_bShowDevelWarning = LocalFileMng::readXmlBool( rootNode, "showDevelWarning", m_bShowDevelWarning );
385                        restoreLastSong = LocalFileMng::readXmlBool( rootNode, "restoreLastSong", restoreLastSong );
386                        m_bPatternModePlaysSelected = LocalFileMng::readXmlBool( rootNode, "patternModePlaysSelected", TRUE );
387                        m_bUseLash = LocalFileMng::readXmlBool( rootNode, "useLash", FALSE );
388                        __usetimeline = LocalFileMng::readXmlBool( rootNode, "useTimeLine", __usetimeline );
389                        maxBars = LocalFileMng::readXmlInt( rootNode, "maxBars", 400 );
390
391                        //restore the right m_bsetlash value
392                        m_bsetLash = m_bUseLash;
393
394                        m_nRecPreDelete = LocalFileMng::readXmlInt( rootNode, "preDelete", 0 );
395                        m_nRecPostDelete = LocalFileMng::readXmlInt( rootNode, "postDelete", 0 );
396
397                        hearNewNotes = LocalFileMng::readXmlBool( rootNode, "hearNewNotes", hearNewNotes );
398                        quantizeEvents = LocalFileMng::readXmlBool( rootNode, "quantizeEvents", quantizeEvents );
399                       
400                        //rubberband
401                        if( readPrefFileforotherplaces ){
402                                //this scond test will check individual user settings
403                                QString test = LocalFileMng::readXmlString( rootNode, "path_to_rubberband", "");
404                                if ( QFile( test ).exists() == true ){
405                                        m_rubberBandCLIexecutable = test;
406                                }else
407                                {
408                                        m_rubberBandCLIexecutable = "Path to Rubberband-CLI";   
409                                }
410                        }
411
412                        QDomNode pRecentUsedSongsNode = rootNode.firstChildElement( "recentUsedSongs" );
413                        if ( !pRecentUsedSongsNode.isNull() ) {
414                                QDomElement pSongElement = pRecentUsedSongsNode.firstChildElement( "song" );
415                                while( !pSongElement.isNull() && !pSongElement.text().isEmpty() ){
416                                        m_recentFiles.push_back( pSongElement.text() );
417                                        pSongElement = pSongElement.nextSiblingElement( "song" );
418                                }
419                               
420                        } else {
421                                WARNINGLOG( "recentUsedSongs node not found" );
422                        }
423
424                        QDomNode pRecentFXNode = rootNode.firstChildElement( "recentlyUsedEffects" );
425                        if ( ! pRecentFXNode.isNull() ) {
426                                QDomElement pFXElement = pRecentFXNode.firstChildElement( "FX" );
427                                while ( !pFXElement.isNull()  && ! pFXElement.text().isEmpty()) {
428                                        m_recentFX.push_back( pFXElement.text() );
429                                        pFXElement = pFXElement.nextSiblingElement( "FX" );
430                                }
431                        } else {
432                                WARNINGLOG( "recentlyUsedEffects node not found" );
433                        }
434
435                        sServerList.clear();
436                        QDomNode pServerListNode = rootNode.firstChildElement( "serverList" );
437                        if ( !pServerListNode.isNull() ) {
438                                QDomElement pServerElement = pServerListNode.firstChildElement( "server" );
439                                while ( !pServerElement.isNull() && !pServerElement.text().isEmpty() ) {
440                                        sServerList.push_back( pServerElement.text() );
441                                        pServerElement = pServerElement.nextSiblingElement( "server" );
442                                }
443                        } else {
444                                WARNINGLOG( "serverList node not found" );
445                        }
446
447                        m_patternCategories.clear();
448                        QDomNode pPatternCategoriesNode = rootNode.firstChildElement( "patternCategories" );
449                        if ( !pPatternCategoriesNode.isNull() ) {
450                                QDomElement pPatternCategoriesElement = pPatternCategoriesNode.firstChildElement( "categories" );
451                                while ( !pPatternCategoriesElement.isNull() && !pPatternCategoriesElement.text().isEmpty() ) {
452                                        m_patternCategories.push_back( pPatternCategoriesElement.text() );
453                                        pPatternCategoriesElement = pPatternCategoriesElement.nextSiblingElement( "categories" );
454                                }
455                        } else {
456                                WARNINGLOG( "patternCategories node not found" );
457                        }
458
459
460
461                        m_sLastNews = LocalFileMng::readXmlString( rootNode, "lastNews", "-", true );
462
463                        /////////////// AUDIO ENGINE //////////////
464                        QDomNode audioEngineNode = rootNode.firstChildElement( "audio_engine" );
465                        if ( audioEngineNode.isNull() ) {
466                                WARNINGLOG( "audio_engine node not found" );
467                                recreate = true;
468                        } else {
469                                m_sAudioDriver = LocalFileMng::readXmlString( audioEngineNode, "audio_driver", m_sAudioDriver );
470                                m_bUseMetronome = LocalFileMng::readXmlBool( audioEngineNode, "use_metronome", m_bUseMetronome );
471                                m_fMetronomeVolume = LocalFileMng::readXmlFloat( audioEngineNode, "metronome_volume", 0.5f );
472                                m_nMaxNotes = LocalFileMng::readXmlInt( audioEngineNode, "maxNotes", m_nMaxNotes );
473                                m_nBufferSize = LocalFileMng::readXmlInt( audioEngineNode, "buffer_size", m_nBufferSize );
474                                m_nSampleRate = LocalFileMng::readXmlInt( audioEngineNode, "samplerate", m_nSampleRate );
475
476                                //// OSS DRIVER ////
477                                QDomNode ossDriverNode = audioEngineNode.firstChildElement( "oss_driver" );
478                                if ( ossDriverNode.isNull()  ) {
479                                        WARNINGLOG( "oss_driver node not found" );
480                                        recreate = true;
481                                } else {
482                                        m_sOSSDevice = LocalFileMng::readXmlString( ossDriverNode, "ossDevice", m_sOSSDevice );
483                                }
484
485                                //// JACK DRIVER ////
486                                QDomNode jackDriverNode = audioEngineNode.firstChildElement( "jack_driver" );
487                                if ( jackDriverNode.isNull() ) {
488                                        WARNINGLOG( "jack_driver node not found" );
489                                        recreate = true;
490                                } else {
491                                        m_sJackPortName1 = LocalFileMng::readXmlString( jackDriverNode, "jack_port_name_1", m_sJackPortName1 );
492                                        m_sJackPortName2 = LocalFileMng::readXmlString( jackDriverNode, "jack_port_name_2", m_sJackPortName2 );
493                                        QString sMode = LocalFileMng::readXmlString( jackDriverNode, "jack_transport_mode", "NO_JACK_TRANSPORT" );
494                                        if ( sMode == "NO_JACK_TRANSPORT" ) {
495                                                m_bJackTransportMode = NO_JACK_TRANSPORT;
496                                        } else if ( sMode == "USE_JACK_TRANSPORT" ) {
497                                                m_bJackTransportMode = USE_JACK_TRANSPORT;
498                                        }
499                                       
500                                        //jack time master
501                                        QString tmMode = LocalFileMng::readXmlString( jackDriverNode, "jack_transport_mode_master", "NO_JACK_TIME_MASTER" );
502                                        if ( tmMode == "NO_JACK_TIME_MASTER" ) {
503                                                m_bJackMasterMode = NO_JACK_TIME_MASTER;
504                                        } else if ( tmMode == "USE_JACK_TIME_MASTER" ) {
505                                                m_bJackMasterMode = USE_JACK_TIME_MASTER;
506                                        }
507                                        //~ jack time master
508
509                                        m_bJackTrackOuts = LocalFileMng::readXmlBool( jackDriverNode, "jack_track_outs", m_bJackTrackOuts );
510                                        m_bJackConnectDefaults = LocalFileMng::readXmlBool( jackDriverNode, "jack_connect_defaults", m_bJackConnectDefaults );
511
512                                        m_nJackTrackOutputMode = LocalFileMng::readXmlInt( jackDriverNode, "jack_track_output_mode", m_nJackTrackOutputMode );
513                                }
514
515
516                                /// ALSA AUDIO DRIVER ///
517                                QDomNode alsaAudioDriverNode = audioEngineNode.firstChildElement( "alsa_audio_driver" );
518                                if ( alsaAudioDriverNode.isNull() ) {
519                                        WARNINGLOG( "alsa_audio_driver node not found" );
520                                        recreate = true;
521                                } else {
522                                        m_sAlsaAudioDevice = LocalFileMng::readXmlString( alsaAudioDriverNode, "alsa_audio_device", m_sAlsaAudioDevice );
523                                }
524
525                                /// MIDI DRIVER ///
526                                QDomNode midiDriverNode = audioEngineNode.firstChildElement( "midi_driver" );
527                                if ( midiDriverNode.isNull() ) {
528                                        WARNINGLOG( "midi_driver node not found" );
529                                        recreate = true;
530                                } else {
531                                        m_sMidiDriver = LocalFileMng::readXmlString( midiDriverNode, "driverName", "ALSA" );
532                                        m_sMidiPortName = LocalFileMng::readXmlString( midiDriverNode, "port_name", "None" );
533                                        m_nMidiChannelFilter = LocalFileMng::readXmlInt( midiDriverNode, "channel_filter", -1 );
534                                        m_bMidiNoteOffIgnore = LocalFileMng::readXmlBool( midiDriverNode, "ignore_note_off", true );
535                                }
536
537
538
539                        }
540
541                        /////////////// GUI //////////////
542                        QDomNode guiNode = rootNode.firstChildElement( "gui" );
543                        if ( guiNode.isNull() ) {
544                                WARNINGLOG( "gui node not found" );
545                                recreate = true;
546                        } else {
547                                // QT Style
548                                m_sQTStyle = LocalFileMng::readXmlString( guiNode, "QTStyle", m_sQTStyle, true );
549
550                                // Application font family
551                                applicationFontFamily = LocalFileMng::readXmlString( guiNode, "application_font_family", applicationFontFamily );
552
553                                // Application font pointSize
554                                applicationFontPointSize = LocalFileMng::readXmlInt( guiNode, "application_font_pointsize", applicationFontPointSize );
555
556                                // mixer font family
557                                mixerFontFamily = LocalFileMng::readXmlString( guiNode, "mixer_font_family", mixerFontFamily );
558
559                                // mixer font pointSize
560                                mixerFontPointSize = LocalFileMng::readXmlInt( guiNode, "mixer_font_pointsize", mixerFontPointSize );
561
562                                // Mixer falloff speed
563                                mixerFalloffSpeed = LocalFileMng::readXmlFloat( guiNode, "mixer_falloff_speed", 1.1f );
564
565                                // pattern editor grid resolution
566                                m_nPatternEditorGridResolution = LocalFileMng::readXmlInt( guiNode, "patternEditorGridResolution", m_nPatternEditorGridResolution );
567                                m_bPatternEditorUsingTriplets = LocalFileMng::readXmlBool( guiNode, "patternEditorUsingTriplets", m_bPatternEditorUsingTriplets );
568                                m_bShowInstrumentPeaks = LocalFileMng::readXmlBool( guiNode, "showInstrumentPeaks", m_bShowInstrumentPeaks );
569                                m_bIsFXTabVisible = LocalFileMng::readXmlBool( guiNode, "isFXTabVisible", m_bIsFXTabVisible );
570
571
572                                // pattern editor grid height
573                                m_nPatternEditorGridHeight = LocalFileMng::readXmlInt( guiNode, "patternEditorGridHeight", m_nPatternEditorGridHeight );
574
575                                // pattern editor grid width
576                                m_nPatternEditorGridWidth = LocalFileMng::readXmlInt( guiNode, "patternEditorGridWidth", m_nPatternEditorGridWidth );
577
578                                // mainForm window properties
579                                setMainFormProperties( readWindowProperties( guiNode, "mainForm_properties", mainFormProperties ) );
580                                setMixerProperties( readWindowProperties( guiNode, "mixer_properties", mixerProperties ) );
581                                setPatternEditorProperties( readWindowProperties( guiNode, "patternEditor_properties", patternEditorProperties ) );
582                                setSongEditorProperties( readWindowProperties( guiNode, "songEditor_properties", songEditorProperties ) );
583                                setAudioEngineInfoProperties( readWindowProperties( guiNode, "audioEngineInfo_properties", audioEngineInfoProperties ) );
584
585
586
587                                m_bFollowPlayhead = LocalFileMng::readXmlBool( guiNode, "followPlayhead", true );
588
589
590                                //beatcounter
591                                QString bcMode = LocalFileMng::readXmlString( guiNode, "bc", "BC_OFF" );
592                                        if ( bcMode == "BC_OFF" ) {
593                                                m_bbc = BC_OFF;
594                                        } else if ( bcMode == "BC_ON" ) {
595                                                m_bbc = BC_ON;
596                                        }
597
598
599                                QString setPlay = LocalFileMng::readXmlString( guiNode, "setplay", "SET_PLAY_OFF" );
600                                        if ( setPlay == "SET_PLAY_OFF" ) {
601                                                m_mmcsetplay = SET_PLAY_OFF;
602                                        } else if ( setPlay == "SET_PLAY_ON" ) {
603                                                m_mmcsetplay = SET_PLAY_ON;
604                                        }
605                               
606                                m_countOffset = LocalFileMng::readXmlInt( guiNode, "countoffset", 0 );
607                                m_startOffset = LocalFileMng::readXmlInt( guiNode, "playoffset", 0 );
608                               
609                                //~ beatcounter
610
611                                //SoundLibraryPanel expand items
612                                __expandSongItem = LocalFileMng::readXmlBool( guiNode, "expandSongItem", __expandSongItem );
613                                __expandPatternItem = LocalFileMng::readXmlBool( guiNode, "expandPatternItem", __expandPatternItem );
614
615                                for ( unsigned nFX = 0; nFX < MAX_FX; nFX++ ) {
616                                        QString sNodeName = QString("ladspaFX_properties%1").arg( nFX );
617                                        setLadspaProperties( nFX, readWindowProperties( guiNode, sNodeName, m_ladspaProperties[nFX] ) );
618                                }
619
620                                QDomNode pUIStyle = guiNode.firstChildElement( "UI_Style" );
621                                if ( !pUIStyle.isNull() ) {
622                                        readUIStyle( pUIStyle );
623                                } else {
624                                        WARNINGLOG( "UI_Style node not found" );
625                                        recreate = true;
626                                }
627                        }
628
629                        /////////////// FILES //////////////
630                        QDomNode filesNode = rootNode.firstChildElement( "files" );
631                        if ( filesNode.isNull() ) {
632                                WARNINGLOG( "files node not found" );
633                                recreate = true;
634                        } else {
635                                // last used song
636                                lastSongFilename = LocalFileMng::readXmlString( filesNode, "lastSongFilename", lastSongFilename, true );
637                                m_sDefaultEditor = LocalFileMng::readXmlString( filesNode, "defaulteditor", m_sDefaultEditor, true );
638                        }
639
640                        MidiMap::reset_instance();
641                        MidiMap* mM = MidiMap::get_instance();
642                       
643                       
644                        QDomNode pMidiEventMapNode = rootNode.firstChildElement( "midiEventMap" );
645                        if ( !pMidiEventMapNode.isNull() ) {
646                                QDomNode pMidiEventNode = pMidiEventMapNode.firstChildElement( "midiEvent" );
647                                while ( !pMidiEventNode.isNull() ) {
648                                        if( pMidiEventNode.firstChildElement().nodeName() == QString("mmcEvent")){
649                                                QString event = pMidiEventNode.firstChildElement("mmcEvent").text();
650                                                QString s_action = pMidiEventNode.firstChildElement("action").text();
651                                                QString s_param = pMidiEventNode.firstChildElement("parameter").text();
652
653                                                Action* pAction = new Action( s_action );
654                                                pAction->setParameter1( s_param );
655                                                mM->registerMMCEvent(event, pAction);
656                                        }
657
658                                        if( pMidiEventNode.firstChildElement().nodeName() == QString("noteEvent")){
659                                                QString event = pMidiEventNode.firstChildElement("noteEvent").text();
660                                                QString s_action = pMidiEventNode.firstChildElement("action").text();
661                                                QString s_param = pMidiEventNode.firstChildElement("parameter").text();
662                                                QString s_eventParameter = pMidiEventNode.firstChildElement("eventParameter").text();
663                                                Action* pAction = new Action( s_action );
664                                                pAction->setParameter1( s_param );
665                                                mM->registerNoteEvent(s_eventParameter.toInt(), pAction);
666                                        }
667
668                                        if( pMidiEventNode.firstChildElement().nodeName() == QString("ccEvent") ){
669                                                QString event = pMidiEventNode.firstChildElement("ccEvent").text();
670                                                QString s_action = pMidiEventNode.firstChildElement("action").text();
671                                                QString s_param = pMidiEventNode.firstChildElement("parameter").text();
672                                                QString s_eventParameter = pMidiEventNode.firstChildElement("eventParameter").text();
673                                                Action * pAction = new Action( s_action );
674                                                pAction->setParameter1( s_param );
675                                                mM->registerCCEvent( s_eventParameter.toInt(), pAction );
676                                        }
677
678                                        pMidiEventNode = pMidiEventNode.nextSiblingElement( "midiEvent" );
679
680                                }
681
682                        } else {
683                                WARNINGLOG( "midiMap node not found" );
684                        }
685                       
686                       
687
688                } // rootNode
689                else {
690                        WARNINGLOG( "hydrogen_preferences node not found" );
691                        recreate = true;
692                }
693        } else {
694                if ( bGlobal ) {
695                        WARNINGLOG( "System configuration file not found." );
696                } else {
697                        WARNINGLOG( "Configuration file not found." );
698                        recreate = true;
699                }
700        }
701
702
703        // The preferences file should be recreated?
704        if ( recreate == true ) {
705                WARNINGLOG( "Recreating configuration file." );
706                savePreferences();
707        }
708}
709
710
711
712///
713/// Save the preferences file
714///
715void Preferences::savePreferences()
716{
717        //string prefDir = QDir::homePath().append("/.hydrogen").toLocal8Bit().constData();
718        QString filename = m_sPreferencesFilename;
719
720        INFOLOG( "Saving preferences file: " + filename );
721
722        QDomDocument doc;
723        QDomProcessingInstruction header = doc.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"");
724        doc.appendChild( header );
725
726        QDomNode rootNode = doc.createElement( "hydrogen_preferences" );
727
728        // hydrogen version
729        LocalFileMng::writeXmlString( rootNode, "version", QString( get_version().c_str() ) );
730
731        ////// GENERAL ///////
732        LocalFileMng::writeXmlString( rootNode, "restoreLastSong", restoreLastSong ? "true": "false" );
733       
734        LocalFileMng::writeXmlString( rootNode, "patternModePlaysSelected", m_bPatternModePlaysSelected ? "true": "false" );
735
736        LocalFileMng::writeXmlString( rootNode, "useLash", m_bsetLash ? "true": "false" );
737        LocalFileMng::writeXmlString( rootNode, "useTimeLine", __usetimeline ? "true": "false" );
738
739        LocalFileMng::writeXmlString( rootNode, "maxBars", QString::number( maxBars ) );
740
741        LocalFileMng::writeXmlString( rootNode, "preDelete", QString("%1").arg(m_nRecPreDelete) );
742        LocalFileMng::writeXmlString( rootNode, "postDelete", QString("%1").arg(m_nRecPostDelete) );
743
744
745
746        //show development version warning
747        LocalFileMng::writeXmlString( rootNode, "showDevelWarning", m_bShowDevelWarning ? "true": "false" );
748
749        // hear new notes in the pattern editor
750        LocalFileMng::writeXmlString( rootNode, "hearNewNotes", hearNewNotes ? "true": "false" );
751
752        // key/midi event prefs
753        //LocalFileMng::writeXmlString( rootNode, "recordEvents", recordEvents ? "true": "false" );
754        LocalFileMng::writeXmlString( rootNode, "quantizeEvents", quantizeEvents ? "true": "false" );
755
756        //extern executables
757        if ( QFile( m_rubberBandCLIexecutable ).exists() == false ) {
758                m_rubberBandCLIexecutable = "Path to Rubberband-CLI";
759        }
760        LocalFileMng::writeXmlString( rootNode, "path_to_rubberband", QString(m_rubberBandCLIexecutable));
761
762        // Recent used songs
763        QDomNode recentUsedSongsNode = doc.createElement( "recentUsedSongs" );
764        {
765                unsigned nSongs = 5;
766                if ( m_recentFiles.size() < 5 ) {
767                        nSongs = m_recentFiles.size();
768                }
769                for ( unsigned i = 0; i < nSongs; i++ ) {
770                        LocalFileMng::writeXmlString( recentUsedSongsNode, "song", m_recentFiles[ i ] );
771                }
772        }
773        rootNode.appendChild( recentUsedSongsNode );
774       
775        QDomNode recentFXNode = doc.createElement( "recentlyUsedEffects" );
776        {
777                int nFX = 0;
778                QString FXname;
779                foreach( FXname, m_recentFX ) {
780                        LocalFileMng::writeXmlString( recentFXNode, "FX", FXname );
781                        if ( ++nFX > 10 ) break;
782                }
783        }
784        rootNode.appendChild( recentFXNode );
785
786
787        std::list<QString>::const_iterator cur_Server;
788
789        QDomNode serverListNode = doc.createElement( "serverList" );
790        for( cur_Server = sServerList.begin(); cur_Server != sServerList.end(); ++cur_Server ){
791                LocalFileMng::writeXmlString( serverListNode , QString("server") , QString( *cur_Server ) );
792        }
793        rootNode.appendChild( serverListNode );
794
795
796        std::list<QString>::const_iterator cur_patternCategories;
797
798        QDomNode patternCategoriesNode = doc.createElement( "patternCategories" );
799        for( cur_patternCategories = m_patternCategories.begin(); cur_patternCategories != m_patternCategories.end(); ++cur_patternCategories ){
800                LocalFileMng::writeXmlString( patternCategoriesNode , QString("categories") , QString( *cur_patternCategories ) );
801        }
802        rootNode.appendChild( patternCategoriesNode );
803
804
805
806
807        LocalFileMng::writeXmlString( rootNode, "lastNews", m_sLastNews );
808
809
810        //---- AUDIO ENGINE ----
811        QDomNode audioEngineNode = doc.createElement( "audio_engine" );
812        {
813                // audio driver
814                LocalFileMng::writeXmlString( audioEngineNode, "audio_driver", m_sAudioDriver );
815
816                // use metronome
817                LocalFileMng::writeXmlString( audioEngineNode, "use_metronome", m_bUseMetronome ? "true": "false" );
818                LocalFileMng::writeXmlString( audioEngineNode, "metronome_volume", QString("%1").arg( m_fMetronomeVolume ) );
819                LocalFileMng::writeXmlString( audioEngineNode, "maxNotes", QString("%1").arg( m_nMaxNotes ) );
820                LocalFileMng::writeXmlString( audioEngineNode, "buffer_size", QString("%1").arg( m_nBufferSize ) );
821                LocalFileMng::writeXmlString( audioEngineNode, "samplerate", QString("%1").arg( m_nSampleRate ) );
822
823                //// OSS DRIVER ////
824                QDomNode ossDriverNode = doc.createElement( "oss_driver" );
825                {
826                        LocalFileMng::writeXmlString( ossDriverNode, "ossDevice", m_sOSSDevice );
827                }
828                audioEngineNode.appendChild( ossDriverNode );
829
830                //// JACK DRIVER ////
831                QDomNode jackDriverNode = doc.createElement( "jack_driver" );
832                {
833                        LocalFileMng::writeXmlString( jackDriverNode, "jack_port_name_1", m_sJackPortName1 );   // jack port name 1
834                        LocalFileMng::writeXmlString( jackDriverNode, "jack_port_name_2", m_sJackPortName2 );   // jack port name 2
835
836                        // jack transport slave
837                        QString sMode;
838                        if ( m_bJackTransportMode == NO_JACK_TRANSPORT ) {
839                                sMode = "NO_JACK_TRANSPORT";
840                        } else if ( m_bJackTransportMode == USE_JACK_TRANSPORT ) {
841                                sMode = "USE_JACK_TRANSPORT";
842                        }
843                        LocalFileMng::writeXmlString( jackDriverNode, "jack_transport_mode", sMode );
844
845                        //jack time master
846                        QString tmMode;
847                        if ( m_bJackMasterMode == NO_JACK_TIME_MASTER ) {
848                                tmMode = "NO_JACK_TIME_MASTER";
849                        } else if (  m_bJackMasterMode == USE_JACK_TIME_MASTER ) {
850                                tmMode = "NO_JACK_TIME_MASTER";
851                        }
852                        LocalFileMng::writeXmlString( jackDriverNode, "jack_transport_mode_master", tmMode );
853                        //~ jack time master
854
855                        // jack default connection
856                        QString jackConnectDefaultsString = "false";
857                        if ( m_bJackConnectDefaults ) {
858                                jackConnectDefaultsString = "true";
859                        }
860                        LocalFileMng::writeXmlString( jackDriverNode, "jack_connect_defaults", jackConnectDefaultsString );
861
862                        //pre-fader or post-fader track outputs ?
863                        LocalFileMng::writeXmlString( jackDriverNode, "jack_track_output_mode", QString("%1").arg( m_nJackTrackOutputMode ));
864
865                        // jack track outs
866                        QString jackTrackOutsString = "false";
867                        if ( m_bJackTrackOuts ) {
868                                jackTrackOutsString = "true";
869                        }
870                        LocalFileMng::writeXmlString( jackDriverNode, "jack_track_outs", jackTrackOutsString );
871                }
872                audioEngineNode.appendChild( jackDriverNode );
873
874                //// ALSA AUDIO DRIVER ////
875                QDomNode alsaAudioDriverNode = doc.createElement( "alsa_audio_driver" );
876                {
877                        LocalFileMng::writeXmlString( alsaAudioDriverNode, "alsa_audio_device", m_sAlsaAudioDevice );
878                }
879                audioEngineNode.appendChild( alsaAudioDriverNode );
880
881                /// MIDI DRIVER ///
882                QDomNode midiDriverNode = doc.createElement( "midi_driver" );
883                {
884                        LocalFileMng::writeXmlString( midiDriverNode, "driverName", m_sMidiDriver );
885                        LocalFileMng::writeXmlString( midiDriverNode, "port_name", m_sMidiPortName );
886                        LocalFileMng::writeXmlString( midiDriverNode, "channel_filter", QString("%1").arg( m_nMidiChannelFilter ) );
887
888                        if ( m_bMidiNoteOffIgnore ) {
889                                LocalFileMng::writeXmlString( midiDriverNode, "ignore_note_off", "true" );
890                        } else {
891                                LocalFileMng::writeXmlString( midiDriverNode, "ignore_note_off", "false" );
892                        }
893
894                        if ( m_bMidiDiscardNoteAfterAction ) {
895                                LocalFileMng::writeXmlString( midiDriverNode, "discard_note_after_action", "true" );
896                        } else {
897                                LocalFileMng::writeXmlString( midiDriverNode, "discard_note_after_action", "false" );
898                        }
899                }
900                audioEngineNode.appendChild( midiDriverNode );
901
902
903
904        }
905        rootNode.appendChild( audioEngineNode );
906
907        //---- GUI ----
908        QDomNode guiNode = doc.createElement( "gui" );
909        {
910                LocalFileMng::writeXmlString( guiNode, "QTStyle", m_sQTStyle );
911                LocalFileMng::writeXmlString( guiNode, "application_font_family", applicationFontFamily );
912                LocalFileMng::writeXmlString( guiNode, "application_font_pointsize", QString("%1").arg( applicationFontPointSize ) );
913                LocalFileMng::writeXmlString( guiNode, "mixer_font_family", mixerFontFamily );
914                LocalFileMng::writeXmlString( guiNode, "mixer_font_pointsize", QString("%1").arg( mixerFontPointSize ) );
915                LocalFileMng::writeXmlString( guiNode, "mixer_falloff_speed", QString("%1").arg( mixerFalloffSpeed ) );
916                LocalFileMng::writeXmlString( guiNode, "patternEditorGridResolution", QString("%1").arg( m_nPatternEditorGridResolution ) );
917                LocalFileMng::writeXmlString( guiNode, "patternEditorGridHeight", QString("%1").arg( m_nPatternEditorGridHeight ) );
918                LocalFileMng::writeXmlString( guiNode, "patternEditorGridWidth", QString("%1").arg( m_nPatternEditorGridWidth ) );
919                LocalFileMng::writeXmlBool( guiNode, "patternEditorUsingTriplets", m_bPatternEditorUsingTriplets );
920                LocalFileMng::writeXmlBool( guiNode, "showInstrumentPeaks", m_bShowInstrumentPeaks );
921                LocalFileMng::writeXmlBool( guiNode, "isFXTabVisible", m_bIsFXTabVisible );
922
923
924                // MainForm window properties
925                writeWindowProperties( guiNode, "mainForm_properties", mainFormProperties );
926                writeWindowProperties( guiNode, "mixer_properties", mixerProperties );
927                writeWindowProperties( guiNode, "patternEditor_properties", patternEditorProperties );
928                writeWindowProperties( guiNode, "songEditor_properties", songEditorProperties );
929                writeWindowProperties( guiNode, "drumkitManager_properties", drumkitManagerProperties );
930                writeWindowProperties( guiNode, "audioEngineInfo_properties", audioEngineInfoProperties );
931                for ( unsigned nFX = 0; nFX < MAX_FX; nFX++ ) {
932                        QString sNode = QString("ladspaFX_properties%1").arg( nFX );
933                        writeWindowProperties( guiNode, sNode, m_ladspaProperties[nFX] );
934                }
935
936                LocalFileMng::writeXmlBool( guiNode, "followPlayhead", m_bFollowPlayhead );
937
938
939                //beatcounter
940                QString bcMode;
941                        if ( m_bbc == BC_OFF ) {
942                                bcMode = "BC_OFF";
943                        } else if ( m_bbc  == BC_ON ) {
944                                bcMode = "BC_ON";
945                        }
946                        LocalFileMng::writeXmlString( guiNode, "bc", bcMode );
947
948
949               
950                QString setPlay;
951                        if ( m_mmcsetplay == SET_PLAY_OFF ) {
952                                setPlay = "SET_PLAY_OFF";
953                        } else if ( m_mmcsetplay == SET_PLAY_ON ) {
954                                setPlay = "SET_PLAY_ON";
955                        }
956                        LocalFileMng::writeXmlString( guiNode, "setplay", setPlay );
957
958                        LocalFileMng::writeXmlString( guiNode, "countoffset", QString("%1").arg(m_countOffset) );
959                        LocalFileMng::writeXmlString( guiNode, "playoffset", QString("%1").arg(m_startOffset) );
960                //~ beatcounter
961
962
963                //SoundLibraryPanel expand items
964                LocalFileMng::writeXmlString( guiNode, "expandSongItem", __expandSongItem ? "true": "false" );
965                LocalFileMng::writeXmlString( guiNode, "expandPatternItem", __expandPatternItem ? "true": "false" );
966
967                // User interface style
968                writeUIStyle( guiNode );
969        }
970        rootNode.appendChild( guiNode );
971
972        //---- FILES ----
973        QDomNode filesNode = doc.createElement( "files" );
974        {
975                // last used song
976                LocalFileMng::writeXmlString( filesNode, "lastSongFilename", lastSongFilename );
977                LocalFileMng::writeXmlString( filesNode, "defaulteditor", m_sDefaultEditor );
978        }
979        rootNode.appendChild( filesNode );
980
981        MidiMap * mM = MidiMap::get_instance();
982        std::map< QString, Action* > mmcMap = mM->getMMCMap();
983
984        //---- MidiMap ----
985        QDomNode midiEventMapNode = doc.createElement( "midiEventMap" );
986
987        std::map< QString, Action* >::iterator dIter( mmcMap.begin() );
988        for( dIter = mmcMap.begin(); dIter != mmcMap.end(); dIter++ ){
989            QString event = dIter->first;
990            Action * pAction = dIter->second;
991            if ( pAction->getType() != "NOTHING" ){
992                    QDomNode midiEventNode = doc.createElement( "midiEvent" );
993
994                    LocalFileMng::writeXmlString( midiEventNode, "mmcEvent" , event );
995                    LocalFileMng::writeXmlString( midiEventNode, "action" , pAction->getType());
996                    LocalFileMng::writeXmlString( midiEventNode, "parameter" , pAction->getParameter1() );
997
998                    midiEventMapNode.appendChild( midiEventNode );
999            }
1000        }
1001               
1002        for( int note=0; note < 128; note++ ){
1003            Action * pAction = mM->getNoteAction( note );
1004            if( pAction != NULL && pAction->getType() != "NOTHING") {
1005                QDomNode midiEventNode = doc.createElement( "midiEvent" );
1006
1007                LocalFileMng::writeXmlString( midiEventNode, "noteEvent" , QString("NOTE") );
1008                LocalFileMng::writeXmlString( midiEventNode, "eventParameter" , QString::number( note ) );
1009                LocalFileMng::writeXmlString( midiEventNode, "action" , pAction->getType() );
1010                LocalFileMng::writeXmlString( midiEventNode, "parameter" , pAction->getParameter1() );
1011       
1012
1013                midiEventMapNode.appendChild(midiEventNode);
1014            }
1015        }
1016
1017                for( int parameter=0; parameter < 128; parameter++ ){
1018                        Action * pAction = mM->getCCAction( parameter );
1019                        if( pAction != NULL && pAction->getType() != "NOTHING")
1020                        {
1021                                QDomNode midiEventNode = doc.createElement( "midiEvent" );
1022                               
1023                                LocalFileMng::writeXmlString( midiEventNode, "ccEvent" , QString("CC") );
1024                                LocalFileMng::writeXmlString( midiEventNode, "eventParameter" , QString::number( parameter ) );
1025                               
1026
1027                                LocalFileMng::writeXmlString( midiEventNode, "action" , pAction->getType() );
1028
1029                                LocalFileMng::writeXmlString( midiEventNode, "parameter" , pAction->getParameter1() );
1030
1031                                midiEventMapNode.appendChild( midiEventNode );
1032                        }
1033                }
1034
1035       
1036        rootNode.appendChild( midiEventMapNode );
1037
1038        doc.appendChild( rootNode );
1039       
1040        QFile file( filename );
1041        if ( !file.open(QIODevice::WriteOnly) )
1042                return;
1043
1044        QTextStream TextStream( &file );
1045        doc.save( TextStream, 1 );
1046
1047        file.close();
1048}
1049
1050
1051
1052///
1053/// Create preferences directory
1054///
1055void Preferences::createPreferencesDirectory()
1056{
1057        QString prefDir = m_sPreferencesDirectory;
1058        INFOLOG( "Creating preference file directory in " + prefDir );
1059
1060        QDir dir;
1061        dir.mkdir( prefDir );
1062}
1063
1064
1065
1066///
1067/// Create data directory
1068///
1069void Preferences::createDataDirectory()
1070{
1071        QString sDir = m_sDataDirectory;
1072        INFOLOG( "Creating data directory in " + sDir );
1073
1074        QDir dir;
1075        dir.mkdir( sDir );
1076//      mkdir(dir.c_str(),S_IRWXU);
1077}
1078
1079void Preferences::createSoundLibraryDirectories()
1080{
1081        QString sDir = m_sDataDirectory;
1082        QString sDrumkitDir;
1083        QString sSongDir;
1084        QString sPatternDir;
1085        QString sPlaylistDir;
1086
1087        INFOLOG( "Creating soundLibrary directories in " + sDir );
1088       
1089        sDrumkitDir = sDir + "/drumkits";
1090        sSongDir = sDir + "/songs";
1091        sPatternDir = sDir + "/patterns";
1092        sPlaylistDir = sDir + "/playlists";
1093
1094        QDir dir;
1095        dir.mkdir( sDrumkitDir );
1096        dir.mkdir( sSongDir );
1097        dir.mkdir( sPatternDir );
1098        dir.mkdir( sPlaylistDir );
1099}
1100
1101
1102void Preferences::setMostRecentFX( QString FX_name )
1103{
1104        int pos = m_recentFX.indexOf( FX_name );
1105       
1106        if ( pos != -1 )
1107                m_recentFX.removeAt( pos );
1108       
1109        m_recentFX.push_front( FX_name );
1110}
1111
1112void Preferences::setRecentFiles( std::vector<QString> recentFiles )
1113{
1114        // find single filenames. (skip duplicates)
1115        std::vector<QString> temp;
1116        for ( unsigned i = 0; i < recentFiles.size(); i++ ) {
1117                QString sFilename = recentFiles[ i ];
1118
1119                bool bExists = false;
1120                for ( unsigned j = 0; j < temp.size(); j++ ) {
1121                        if ( sFilename == temp[ j ] ) {
1122                                bExists = true;
1123                                break;
1124                        }
1125                }
1126                if ( !bExists ) {
1127                        temp.push_back( sFilename );
1128                }
1129        }
1130
1131        m_recentFiles = temp;
1132}
1133
1134
1135
1136/// Read the xml nodes related to window properties
1137WindowProperties Preferences::readWindowProperties( QDomNode parent, const QString& windowName, WindowProperties defaultProp )
1138{
1139        WindowProperties prop = defaultProp;
1140
1141        QDomNode windowPropNode  = parent.firstChildElement( windowName );
1142        if ( windowPropNode.isNull() ) {
1143                WARNINGLOG( "Error reading configuration file: " + windowName + " node not found" );
1144        } else {
1145                prop.visible = LocalFileMng::readXmlBool( windowPropNode, "visible", true );
1146                prop.x = LocalFileMng::readXmlInt( windowPropNode, "x", prop.x );
1147                prop.y = LocalFileMng::readXmlInt( windowPropNode, "y", prop.y );
1148                prop.width = LocalFileMng::readXmlInt( windowPropNode, "width", prop.width );
1149                prop.height = LocalFileMng::readXmlInt( windowPropNode, "height", prop.height );
1150        }
1151
1152        return prop;
1153}
1154
1155
1156
1157/// Write the xml nodes related to window properties
1158void Preferences::writeWindowProperties( QDomNode parent, const QString& windowName, const WindowProperties& prop )
1159{
1160        QDomDocument doc;
1161        QDomNode windowPropNode = doc.createElement( windowName );
1162        if ( prop.visible ) {
1163                LocalFileMng::writeXmlString( windowPropNode, "visible", "true" );
1164        } else {
1165                LocalFileMng::writeXmlString( windowPropNode, "visible", "false" );
1166        }
1167
1168        LocalFileMng::writeXmlString( windowPropNode, "x", QString("%1").arg( prop.x ) );
1169        LocalFileMng::writeXmlString( windowPropNode, "y", QString("%1").arg( prop.y ) );
1170        LocalFileMng::writeXmlString( windowPropNode, "width", QString("%1").arg( prop.width ) );
1171        LocalFileMng::writeXmlString( windowPropNode, "height", QString("%1").arg( prop.height ) );
1172        parent.appendChild( windowPropNode );
1173}
1174
1175
1176
1177void Preferences::writeUIStyle( QDomNode parent )
1178{
1179        QDomDocument doc;
1180        QDomNode node = doc.createElement( "UI_Style" );
1181
1182        // SONG EDITOR
1183        QDomNode songEditorNode = doc.createElement( "songEditor" );
1184        LocalFileMng::writeXmlString( songEditorNode, "backgroundColor", m_pDefaultUIStyle->m_songEditor_backgroundColor.toStringFmt() );
1185        LocalFileMng::writeXmlString( songEditorNode, "alternateRowColor", m_pDefaultUIStyle->m_songEditor_alternateRowColor.toStringFmt() );
1186        LocalFileMng::writeXmlString( songEditorNode, "selectedRowColor", m_pDefaultUIStyle->m_songEditor_selectedRowColor.toStringFmt() );
1187        LocalFileMng::writeXmlString( songEditorNode, "lineColor", m_pDefaultUIStyle->m_songEditor_lineColor.toStringFmt() );
1188        LocalFileMng::writeXmlString( songEditorNode, "textColor", m_pDefaultUIStyle->m_songEditor_textColor.toStringFmt() );
1189        LocalFileMng::writeXmlString( songEditorNode, "pattern1Color", m_pDefaultUIStyle->m_songEditor_pattern1Color.toStringFmt() );
1190        node.appendChild( songEditorNode );
1191
1192        // PATTERN EDITOR
1193        QDomNode patternEditorNode = doc.createElement( "patternEditor" );
1194        LocalFileMng::writeXmlString( patternEditorNode, "backgroundColor", m_pDefaultUIStyle->m_patternEditor_backgroundColor.toStringFmt() );
1195        LocalFileMng::writeXmlString( patternEditorNode, "alternateRowColor", m_pDefaultUIStyle->m_patternEditor_alternateRowColor.toStringFmt() );
1196        LocalFileMng::writeXmlString( patternEditorNode, "selectedRowColor", m_pDefaultUIStyle->m_patternEditor_selectedRowColor.toStringFmt() );
1197        LocalFileMng::writeXmlString( patternEditorNode, "textColor", m_pDefaultUIStyle->m_patternEditor_textColor.toStringFmt() );
1198        LocalFileMng::writeXmlString( patternEditorNode, "noteColor", m_pDefaultUIStyle->m_patternEditor_noteColor.toStringFmt() );
1199
1200        if (m_pDefaultUIStyle->m_patternEditor_noteoffColor.toStringFmt() == "-1,-1,-1" ){
1201                m_pDefaultUIStyle->m_patternEditor_noteoffColor = H2RGBColor( "100, 100, 200" );
1202        }
1203        LocalFileMng::writeXmlString( patternEditorNode, "noteoffColor", m_pDefaultUIStyle->m_patternEditor_noteoffColor.toStringFmt() );
1204
1205        LocalFileMng::writeXmlString( patternEditorNode, "lineColor", m_pDefaultUIStyle->m_patternEditor_lineColor.toStringFmt() );
1206        LocalFileMng::writeXmlString( patternEditorNode, "line1Color", m_pDefaultUIStyle->m_patternEditor_line1Color.toStringFmt() );
1207        LocalFileMng::writeXmlString( patternEditorNode, "line2Color", m_pDefaultUIStyle->m_patternEditor_line2Color.toStringFmt() );
1208        LocalFileMng::writeXmlString( patternEditorNode, "line3Color", m_pDefaultUIStyle->m_patternEditor_line3Color.toStringFmt() );
1209        LocalFileMng::writeXmlString( patternEditorNode, "line4Color", m_pDefaultUIStyle->m_patternEditor_line4Color.toStringFmt() );
1210        LocalFileMng::writeXmlString( patternEditorNode, "line5Color", m_pDefaultUIStyle->m_patternEditor_line5Color.toStringFmt() );
1211        node.appendChild( patternEditorNode );
1212
1213        parent.appendChild( node );
1214}
1215
1216
1217
1218void Preferences::readUIStyle( QDomNode parent )
1219{
1220        // SONG EDITOR
1221        QDomNode pSongEditorNode = parent.firstChildElement( "songEditor" );
1222        if ( !pSongEditorNode.isNull() ) {
1223                m_pDefaultUIStyle->m_songEditor_backgroundColor = H2RGBColor( LocalFileMng::readXmlString( pSongEditorNode, "backgroundColor", m_pDefaultUIStyle->m_songEditor_backgroundColor.toStringFmt() ) );
1224                m_pDefaultUIStyle->m_songEditor_alternateRowColor = H2RGBColor( LocalFileMng::readXmlString( pSongEditorNode, "alternateRowColor", m_pDefaultUIStyle->m_songEditor_alternateRowColor.toStringFmt() ) );
1225                m_pDefaultUIStyle->m_songEditor_selectedRowColor = H2RGBColor( LocalFileMng::readXmlString( pSongEditorNode, "selectedRowColor", m_pDefaultUIStyle->m_songEditor_selectedRowColor.toStringFmt() ) );
1226                m_pDefaultUIStyle->m_songEditor_lineColor = H2RGBColor( LocalFileMng::readXmlString( pSongEditorNode, "lineColor", m_pDefaultUIStyle->m_songEditor_lineColor.toStringFmt() ) );
1227                m_pDefaultUIStyle->m_songEditor_textColor = H2RGBColor( LocalFileMng::readXmlString( pSongEditorNode, "textColor", m_pDefaultUIStyle->m_songEditor_textColor.toStringFmt() ) );
1228                m_pDefaultUIStyle->m_songEditor_pattern1Color = H2RGBColor( LocalFileMng::readXmlString( pSongEditorNode, "pattern1Color", m_pDefaultUIStyle->m_songEditor_pattern1Color.toStringFmt() ) );
1229        } else {
1230                WARNINGLOG( "songEditor node not found" );
1231        }
1232
1233        // PATTERN EDITOR
1234        QDomNode pPatternEditorNode = parent.firstChildElement( "patternEditor" );
1235        if ( !pPatternEditorNode.isNull() ) {
1236                m_pDefaultUIStyle->m_patternEditor_backgroundColor = H2RGBColor( LocalFileMng::readXmlString( pPatternEditorNode, "backgroundColor", m_pDefaultUIStyle->m_patternEditor_backgroundColor.toStringFmt() ) );
1237                m_pDefaultUIStyle->m_patternEditor_alternateRowColor = H2RGBColor( LocalFileMng::readXmlString( pPatternEditorNode, "alternateRowColor", m_pDefaultUIStyle->m_patternEditor_alternateRowColor.toStringFmt() ) );
1238                m_pDefaultUIStyle->m_patternEditor_selectedRowColor = H2RGBColor( LocalFileMng::readXmlString( pPatternEditorNode, "selectedRowColor", m_pDefaultUIStyle->m_patternEditor_selectedRowColor.toStringFmt() ) );
1239                m_pDefaultUIStyle->m_patternEditor_textColor = H2RGBColor( LocalFileMng::readXmlString( pPatternEditorNode, "textColor", m_pDefaultUIStyle->m_patternEditor_textColor.toStringFmt() ) );
1240                m_pDefaultUIStyle->m_patternEditor_noteColor = H2RGBColor( LocalFileMng::readXmlString( pPatternEditorNode, "noteColor", m_pDefaultUIStyle->m_patternEditor_noteColor.toStringFmt() ) );
1241                m_pDefaultUIStyle->m_patternEditor_noteoffColor = H2RGBColor( LocalFileMng::readXmlString( pPatternEditorNode, "noteoffColor", m_pDefaultUIStyle->m_patternEditor_noteoffColor.toStringFmt() ) );
1242                m_pDefaultUIStyle->m_patternEditor_lineColor = H2RGBColor( LocalFileMng::readXmlString( pPatternEditorNode, "lineColor", m_pDefaultUIStyle->m_patternEditor_lineColor.toStringFmt() ) );
1243                m_pDefaultUIStyle->m_patternEditor_line1Color = H2RGBColor( LocalFileMng::readXmlString( pPatternEditorNode, "line1Color", m_pDefaultUIStyle->m_patternEditor_line1Color.toStringFmt() ) );
1244                m_pDefaultUIStyle->m_patternEditor_line2Color = H2RGBColor( LocalFileMng::readXmlString( pPatternEditorNode, "line2Color", m_pDefaultUIStyle->m_patternEditor_line2Color.toStringFmt() ) );
1245                m_pDefaultUIStyle->m_patternEditor_line3Color = H2RGBColor( LocalFileMng::readXmlString( pPatternEditorNode, "line3Color", m_pDefaultUIStyle->m_patternEditor_line3Color.toStringFmt() ) );
1246                m_pDefaultUIStyle->m_patternEditor_line4Color = H2RGBColor( LocalFileMng::readXmlString( pPatternEditorNode, "line4Color", m_pDefaultUIStyle->m_patternEditor_line4Color.toStringFmt() ) );
1247                m_pDefaultUIStyle->m_patternEditor_line5Color = H2RGBColor( LocalFileMng::readXmlString( pPatternEditorNode, "line5Color", m_pDefaultUIStyle->m_patternEditor_line5Color.toStringFmt() ) );
1248        } else {
1249                WARNINGLOG( "patternEditor node not found" );
1250        }
1251}
1252
1253
1254// -----------------------
1255
1256
1257
1258
1259WindowProperties::WindowProperties()
1260                : Object( "WindowProperties" )
1261{
1262//      infoLog( "INIT" );
1263        x = 0;
1264        y = 0;
1265        width = 0;
1266        height = 0;
1267        visible = true;
1268}
1269
1270
1271
1272WindowProperties::~WindowProperties()
1273{
1274//      infoLog( "DESTROY" );
1275}
1276
1277
1278
1279
1280// :::::::::::::::::::::::::::::::
1281
1282
1283
1284UIStyle::UIStyle()
1285                : Object( "UIStyle" )
1286{
1287//      infoLog( "INIT" );
1288}
1289
1290
1291
1292// ::::::::::::::::::::::::::::::::::::::
1293
1294
1295
1296H2RGBColor::H2RGBColor( int r, int g, int b )
1297                : Object( "H2RGBColor" )
1298                , m_red( r )
1299                , m_green( g )
1300                , m_blue( b )
1301{
1302//      infoLog( "INIT" );
1303        m_red %= 256;
1304        m_green %= 256;
1305        m_blue %= 256;
1306}
1307
1308
1309
1310H2RGBColor::~H2RGBColor()
1311{
1312//      infoLog( "DESTROY" );
1313}
1314
1315
1316
1317H2RGBColor::H2RGBColor( const QString& sColor )
1318                : Object( "H2RGBColor" )
1319{
1320//      infoLog( "INIT " + sColor );
1321        QString temp = sColor;
1322
1323        QStringList list = temp.split(",");
1324        m_red = list[0].toInt();
1325        m_green = list[1].toInt();
1326        m_blue = list[2].toInt();
1327
1328        m_red %= 256;
1329        m_green %= 256;
1330        m_blue %= 256;
1331
1332/*
1333        int nPos = temp.indexOf( ',' );
1334        QString sRed = temp.substr( 0, nPos );
1335        temp.erase( 0, nPos + 1 );
1336
1337        nPos = temp.find( ',' );
1338        QString sGreen = temp.substr( 0, nPos );
1339        temp.erase( 0, nPos + 1 );
1340
1341        nPos = temp.find( ',' );
1342        QString sBlue = temp.substr( 0, nPos );
1343
1344        m_red = atoi( sRed.c_str() );
1345        m_green = atoi( sGreen.c_str() );
1346        m_blue = atoi( sBlue.c_str() );
1347*/
1348}
1349
1350
1351
1352QString H2RGBColor::toStringFmt()
1353{
1354        char tmp[255];
1355        sprintf( tmp, "%d,%d,%d", m_red, m_green, m_blue );
1356
1357        //string sRes = to_string( m_red ) + "," + to_string( m_green ) + "," + to_string( m_blue );
1358//      return sRes;
1359
1360        return QString( tmp );
1361}
1362
1363};
Note: See TracBrowser for help on using the browser.