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

Revision 1518, 49.5 KB (checked in by wolke, 3 years ago)

add song editor "delete patternSequense" to undostack.

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
647                                QDomNode pMidiEventNode = pMidiEventMapNode.firstChildElement( "midiEvent" );
648                               
649                                while ( !pMidiEventNode.isNull() ) {
650                                       
651                                        if( pMidiEventNode.firstChildElement().nodeValue() == QString("mmcEvent")){
652                                                QString event = pMidiEventNode.firstChildElement("mmcEvent").firstChildElement().nodeValue();
653                                                QString s_action = pMidiEventNode.firstChildElement("action").firstChildElement().nodeValue();
654                                                QString s_param = pMidiEventNode.firstChildElement("parameter").firstChildElement().nodeValue();
655                                                Action* pAction = new Action( s_action );
656                                                pAction->setParameter1( s_param );
657                                                mM->registerMMCEvent(event, pAction);
658                                        }
659
660                                        if( pMidiEventNode.firstChildElement().nodeValue() == QString("noteEvent")){
661                                                QString event = pMidiEventNode.firstChildElement("noteEvent").firstChildElement().nodeValue();
662                                                QString s_action = pMidiEventNode.firstChildElement("action").firstChildElement().nodeValue();
663                                                QString s_param = pMidiEventNode.firstChildElement("parameter").firstChildElement().nodeValue();
664                                                QString s_eventParameter = pMidiEventNode.firstChildElement("eventParameter").firstChildElement().nodeValue();
665                                                Action* pAction = new Action( s_action );
666                                                pAction->setParameter1( s_param );
667                                                mM->registerNoteEvent(s_eventParameter.toInt(), pAction);
668                                        }
669
670                                        if( pMidiEventNode.firstChildElement().nodeValue() == QString("ccEvent") ){
671                                                QString event = pMidiEventNode.firstChildElement("ccEvent").firstChildElement().nodeValue();
672                                                QString s_action = pMidiEventNode.firstChildElement("action").firstChildElement().nodeValue();
673                                                QString s_param = pMidiEventNode.firstChildElement("parameter").firstChildElement().nodeValue();
674                                                QString s_eventParameter = pMidiEventNode.firstChildElement("eventParameter").firstChildElement().nodeValue();
675                                                Action * pAction = new Action( s_action );
676                                                pAction->setParameter1( s_param );
677                                                mM->registerCCEvent( s_eventParameter.toInt(), pAction );
678                                        }
679
680                                        pMidiEventNode = pMidiEventNode.nextSiblingElement( "midiEvent" );
681
682                                }
683                        } else {
684                                WARNINGLOG( "midiMap node not found" );
685                        }
686                       
687                       
688
689                } // rootNode
690                else {
691                        WARNINGLOG( "hydrogen_preferences node not found" );
692                        recreate = true;
693                }
694        } else {
695                if ( bGlobal ) {
696                        WARNINGLOG( "System configuration file not found." );
697                } else {
698                        WARNINGLOG( "Configuration file not found." );
699                        recreate = true;
700                }
701        }
702
703
704        // The preferences file should be recreated?
705        if ( recreate == true ) {
706                WARNINGLOG( "Recreating configuration file." );
707                savePreferences();
708        }
709
710}
711
712
713
714///
715/// Save the preferences file
716///
717void Preferences::savePreferences()
718{
719        //string prefDir = QDir::homePath().append("/.hydrogen").toLocal8Bit().constData();
720        QString filename = m_sPreferencesFilename;
721
722        INFOLOG( "Saving preferences file: " + filename );
723
724        QDomDocument doc;
725        QDomProcessingInstruction header = doc.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"");
726        doc.appendChild( header );
727
728        QDomNode rootNode = doc.createElement( "hydrogen_preferences" );
729
730        // hydrogen version
731        LocalFileMng::writeXmlString( rootNode, "version", QString( get_version().c_str() ) );
732
733        ////// GENERAL ///////
734        LocalFileMng::writeXmlString( rootNode, "restoreLastSong", restoreLastSong ? "true": "false" );
735       
736        LocalFileMng::writeXmlString( rootNode, "patternModePlaysSelected", m_bPatternModePlaysSelected ? "true": "false" );
737
738        LocalFileMng::writeXmlString( rootNode, "useLash", m_bsetLash ? "true": "false" );
739        LocalFileMng::writeXmlString( rootNode, "useTimeLine", __usetimeline ? "true": "false" );
740
741        LocalFileMng::writeXmlString( rootNode, "maxBars", QString::number( maxBars ) );
742
743        LocalFileMng::writeXmlString( rootNode, "preDelete", QString("%1").arg(m_nRecPreDelete) );
744        LocalFileMng::writeXmlString( rootNode, "postDelete", QString("%1").arg(m_nRecPostDelete) );
745
746
747
748        //show development version warning
749        LocalFileMng::writeXmlString( rootNode, "showDevelWarning", m_bShowDevelWarning ? "true": "false" );
750
751        // hear new notes in the pattern editor
752        LocalFileMng::writeXmlString( rootNode, "hearNewNotes", hearNewNotes ? "true": "false" );
753
754        // key/midi event prefs
755        //LocalFileMng::writeXmlString( rootNode, "recordEvents", recordEvents ? "true": "false" );
756        LocalFileMng::writeXmlString( rootNode, "quantizeEvents", quantizeEvents ? "true": "false" );
757
758        //extern executables
759        if ( QFile( m_rubberBandCLIexecutable ).exists() == false ) {
760                m_rubberBandCLIexecutable = "Path to Rubberband-CLI";
761        }
762        LocalFileMng::writeXmlString( rootNode, "path_to_rubberband", QString(m_rubberBandCLIexecutable));
763
764        // Recent used songs
765        QDomNode recentUsedSongsNode = doc.createElement( "recentUsedSongs" );
766        {
767                unsigned nSongs = 5;
768                if ( m_recentFiles.size() < 5 ) {
769                        nSongs = m_recentFiles.size();
770                }
771                for ( unsigned i = 0; i < nSongs; i++ ) {
772                        LocalFileMng::writeXmlString( recentUsedSongsNode, "song", m_recentFiles[ i ] );
773                }
774        }
775        rootNode.appendChild( recentUsedSongsNode );
776       
777        QDomNode recentFXNode = doc.createElement( "recentlyUsedEffects" );
778        {
779                int nFX = 0;
780                QString FXname;
781                foreach( FXname, m_recentFX ) {
782                        LocalFileMng::writeXmlString( recentFXNode, "FX", FXname );
783                        if ( ++nFX > 10 ) break;
784                }
785        }
786        rootNode.appendChild( recentFXNode );
787
788
789        std::list<QString>::const_iterator cur_Server;
790
791        QDomNode serverListNode = doc.createElement( "serverList" );
792        for( cur_Server = sServerList.begin(); cur_Server != sServerList.end(); ++cur_Server ){
793                LocalFileMng::writeXmlString( serverListNode , QString("server") , QString( *cur_Server ) );
794        }
795        rootNode.appendChild( serverListNode );
796
797
798        std::list<QString>::const_iterator cur_patternCategories;
799
800        QDomNode patternCategoriesNode = doc.createElement( "patternCategories" );
801        for( cur_patternCategories = m_patternCategories.begin(); cur_patternCategories != m_patternCategories.end(); ++cur_patternCategories ){
802                LocalFileMng::writeXmlString( patternCategoriesNode , QString("categories") , QString( *cur_patternCategories ) );
803        }
804        rootNode.appendChild( patternCategoriesNode );
805
806
807
808
809        LocalFileMng::writeXmlString( rootNode, "lastNews", m_sLastNews );
810
811
812        //---- AUDIO ENGINE ----
813        QDomNode audioEngineNode = doc.createElement( "audio_engine" );
814        {
815                // audio driver
816                LocalFileMng::writeXmlString( audioEngineNode, "audio_driver", m_sAudioDriver );
817
818                // use metronome
819                LocalFileMng::writeXmlString( audioEngineNode, "use_metronome", m_bUseMetronome ? "true": "false" );
820                LocalFileMng::writeXmlString( audioEngineNode, "metronome_volume", QString("%1").arg( m_fMetronomeVolume ) );
821                LocalFileMng::writeXmlString( audioEngineNode, "maxNotes", QString("%1").arg( m_nMaxNotes ) );
822                LocalFileMng::writeXmlString( audioEngineNode, "buffer_size", QString("%1").arg( m_nBufferSize ) );
823                LocalFileMng::writeXmlString( audioEngineNode, "samplerate", QString("%1").arg( m_nSampleRate ) );
824
825                //// OSS DRIVER ////
826                QDomNode ossDriverNode = doc.createElement( "oss_driver" );
827                {
828                        LocalFileMng::writeXmlString( ossDriverNode, "ossDevice", m_sOSSDevice );
829                }
830                audioEngineNode.appendChild( ossDriverNode );
831
832                //// JACK DRIVER ////
833                QDomNode jackDriverNode = doc.createElement( "jack_driver" );
834                {
835                        LocalFileMng::writeXmlString( jackDriverNode, "jack_port_name_1", m_sJackPortName1 );   // jack port name 1
836                        LocalFileMng::writeXmlString( jackDriverNode, "jack_port_name_2", m_sJackPortName2 );   // jack port name 2
837
838                        // jack transport slave
839                        QString sMode;
840                        if ( m_bJackTransportMode == NO_JACK_TRANSPORT ) {
841                                sMode = "NO_JACK_TRANSPORT";
842                        } else if ( m_bJackTransportMode == USE_JACK_TRANSPORT ) {
843                                sMode = "USE_JACK_TRANSPORT";
844                        }
845                        LocalFileMng::writeXmlString( jackDriverNode, "jack_transport_mode", sMode );
846
847                        //jack time master
848                        QString tmMode;
849                        if ( m_bJackMasterMode == NO_JACK_TIME_MASTER ) {
850                                tmMode = "NO_JACK_TIME_MASTER";
851                        } else if (  m_bJackMasterMode == USE_JACK_TIME_MASTER ) {
852                                tmMode = "NO_JACK_TIME_MASTER";
853                        }
854                        LocalFileMng::writeXmlString( jackDriverNode, "jack_transport_mode_master", tmMode );
855                        //~ jack time master
856
857                        // jack default connection
858                        QString jackConnectDefaultsString = "false";
859                        if ( m_bJackConnectDefaults ) {
860                                jackConnectDefaultsString = "true";
861                        }
862                        LocalFileMng::writeXmlString( jackDriverNode, "jack_connect_defaults", jackConnectDefaultsString );
863
864                        //pre-fader or post-fader track outputs ?
865                        LocalFileMng::writeXmlString( jackDriverNode, "jack_track_output_mode", QString("%1").arg( m_nJackTrackOutputMode ));
866
867                        // jack track outs
868                        QString jackTrackOutsString = "false";
869                        if ( m_bJackTrackOuts ) {
870                                jackTrackOutsString = "true";
871                        }
872                        LocalFileMng::writeXmlString( jackDriverNode, "jack_track_outs", jackTrackOutsString );
873                }
874                audioEngineNode.appendChild( jackDriverNode );
875
876                //// ALSA AUDIO DRIVER ////
877                QDomNode alsaAudioDriverNode = doc.createElement( "alsa_audio_driver" );
878                {
879                        LocalFileMng::writeXmlString( alsaAudioDriverNode, "alsa_audio_device", m_sAlsaAudioDevice );
880                }
881                audioEngineNode.appendChild( alsaAudioDriverNode );
882
883                /// MIDI DRIVER ///
884                QDomNode midiDriverNode = doc.createElement( "midi_driver" );
885                {
886                        LocalFileMng::writeXmlString( midiDriverNode, "driverName", m_sMidiDriver );
887                        LocalFileMng::writeXmlString( midiDriverNode, "port_name", m_sMidiPortName );
888                        LocalFileMng::writeXmlString( midiDriverNode, "channel_filter", QString("%1").arg( m_nMidiChannelFilter ) );
889
890                        if ( m_bMidiNoteOffIgnore ) {
891                                LocalFileMng::writeXmlString( midiDriverNode, "ignore_note_off", "true" );
892                        } else {
893                                LocalFileMng::writeXmlString( midiDriverNode, "ignore_note_off", "false" );
894                        }
895
896                        if ( m_bMidiDiscardNoteAfterAction ) {
897                                LocalFileMng::writeXmlString( midiDriverNode, "discard_note_after_action", "true" );
898                        } else {
899                                LocalFileMng::writeXmlString( midiDriverNode, "discard_note_after_action", "false" );
900                        }
901                }
902                audioEngineNode.appendChild( midiDriverNode );
903
904
905
906        }
907        rootNode.appendChild( audioEngineNode );
908
909        //---- GUI ----
910        QDomNode guiNode = doc.createElement( "gui" );
911        {
912                LocalFileMng::writeXmlString( guiNode, "QTStyle", m_sQTStyle );
913                LocalFileMng::writeXmlString( guiNode, "application_font_family", applicationFontFamily );
914                LocalFileMng::writeXmlString( guiNode, "application_font_pointsize", QString("%1").arg( applicationFontPointSize ) );
915                LocalFileMng::writeXmlString( guiNode, "mixer_font_family", mixerFontFamily );
916                LocalFileMng::writeXmlString( guiNode, "mixer_font_pointsize", QString("%1").arg( mixerFontPointSize ) );
917                LocalFileMng::writeXmlString( guiNode, "mixer_falloff_speed", QString("%1").arg( mixerFalloffSpeed ) );
918                LocalFileMng::writeXmlString( guiNode, "patternEditorGridResolution", QString("%1").arg( m_nPatternEditorGridResolution ) );
919                LocalFileMng::writeXmlString( guiNode, "patternEditorGridHeight", QString("%1").arg( m_nPatternEditorGridHeight ) );
920                LocalFileMng::writeXmlString( guiNode, "patternEditorGridWidth", QString("%1").arg( m_nPatternEditorGridWidth ) );
921                LocalFileMng::writeXmlBool( guiNode, "patternEditorUsingTriplets", m_bPatternEditorUsingTriplets );
922                LocalFileMng::writeXmlBool( guiNode, "showInstrumentPeaks", m_bShowInstrumentPeaks );
923                LocalFileMng::writeXmlBool( guiNode, "isFXTabVisible", m_bIsFXTabVisible );
924
925
926                // MainForm window properties
927                writeWindowProperties( guiNode, "mainForm_properties", mainFormProperties );
928                writeWindowProperties( guiNode, "mixer_properties", mixerProperties );
929                writeWindowProperties( guiNode, "patternEditor_properties", patternEditorProperties );
930                writeWindowProperties( guiNode, "songEditor_properties", songEditorProperties );
931                writeWindowProperties( guiNode, "drumkitManager_properties", drumkitManagerProperties );
932                writeWindowProperties( guiNode, "audioEngineInfo_properties", audioEngineInfoProperties );
933                for ( unsigned nFX = 0; nFX < MAX_FX; nFX++ ) {
934                        QString sNode = QString("ladspaFX_properties%1").arg( nFX );
935                        writeWindowProperties( guiNode, sNode, m_ladspaProperties[nFX] );
936                }
937
938                LocalFileMng::writeXmlBool( guiNode, "followPlayhead", m_bFollowPlayhead );
939
940
941                //beatcounter
942                QString bcMode;
943                        if ( m_bbc == BC_OFF ) {
944                                bcMode = "BC_OFF";
945                        } else if ( m_bbc  == BC_ON ) {
946                                bcMode = "BC_ON";
947                        }
948                        LocalFileMng::writeXmlString( guiNode, "bc", bcMode );
949
950
951               
952                QString setPlay;
953                        if ( m_mmcsetplay == SET_PLAY_OFF ) {
954                                setPlay = "SET_PLAY_OFF";
955                        } else if ( m_mmcsetplay == SET_PLAY_ON ) {
956                                setPlay = "SET_PLAY_ON";
957                        }
958                        LocalFileMng::writeXmlString( guiNode, "setplay", setPlay );
959
960                        LocalFileMng::writeXmlString( guiNode, "countoffset", QString("%1").arg(m_countOffset) );
961                        LocalFileMng::writeXmlString( guiNode, "playoffset", QString("%1").arg(m_startOffset) );
962                //~ beatcounter
963
964
965                //SoundLibraryPanel expand items
966                LocalFileMng::writeXmlString( guiNode, "expandSongItem", __expandSongItem ? "true": "false" );
967                LocalFileMng::writeXmlString( guiNode, "expandPatternItem", __expandPatternItem ? "true": "false" );
968
969                // User interface style
970                writeUIStyle( guiNode );
971        }
972        rootNode.appendChild( guiNode );
973
974        //---- FILES ----
975        QDomNode filesNode = doc.createElement( "files" );
976        {
977                // last used song
978                LocalFileMng::writeXmlString( filesNode, "lastSongFilename", lastSongFilename );
979                LocalFileMng::writeXmlString( filesNode, "defaulteditor", m_sDefaultEditor );
980        }
981        rootNode.appendChild( filesNode );
982
983        MidiMap * mM = MidiMap::get_instance();
984        std::map< QString, Action* > mmcMap = mM->getMMCMap();
985
986        //---- MidiMap ----
987        QDomNode midiEventMapNode = doc.createElement( "midiEventMap" );
988        {
989                std::map< QString, Action* >::iterator dIter( mmcMap.begin() );
990                for( dIter = mmcMap.begin(); dIter != mmcMap.end(); dIter++ ){
991                       
992                        QString event = dIter->first;
993                        Action * pAction = dIter->second;
994
995                        if ( pAction->getType() != "NOTHING" ){
996                                QDomNode midiEventNode = doc.createElement( "midiEvent" );
997
998                                LocalFileMng::writeXmlString( midiEventNode, "mmcEvent" , event );
999                                LocalFileMng::writeXmlString( midiEventNode, "action" , pAction->getType());
1000                                LocalFileMng::writeXmlString( midiEventNode, "parameter" , pAction->getParameter1() );
1001
1002                                midiEventMapNode.appendChild( midiEventNode );
1003                        }
1004                }
1005               
1006                for( int note=0; note < 128; note++ ){
1007                        Action * pAction = mM->getNoteAction( note );
1008                        if( pAction != NULL && pAction->getType() != "NOTHING") {
1009                                QDomNode midiEventNode = doc.createElement( "midiEvent" );
1010                               
1011                                LocalFileMng::writeXmlString( midiEventNode, "noteEvent" , QString("NOTE") );
1012                                LocalFileMng::writeXmlString( midiEventNode, "eventParameter" , QString::number( note ) );
1013                                LocalFileMng::writeXmlString( midiEventNode, "action" , pAction->getType() );
1014                                LocalFileMng::writeXmlString( midiEventNode, "parameter" , pAction->getParameter1() );
1015       
1016
1017                                midiEventMapNode.appendChild(midiEventNode);
1018                        }
1019                }
1020
1021                for( int parameter=0; parameter < 128; parameter++ ){
1022                        Action * pAction = mM->getCCAction( parameter );
1023                        if( pAction != NULL && pAction->getType() != "NOTHING")
1024                        {
1025                                QDomNode midiEventNode = doc.createElement( "midiEvent" );
1026                               
1027                                LocalFileMng::writeXmlString( midiEventNode, "ccEvent" , QString("CC") );
1028                                LocalFileMng::writeXmlString( midiEventNode, "eventParameter" , QString::number( parameter ) );
1029                               
1030
1031                                LocalFileMng::writeXmlString( midiEventNode, "action" , pAction->getType() );
1032
1033                                LocalFileMng::writeXmlString( midiEventNode, "parameter" , pAction->getParameter1() );
1034
1035                                midiEventMapNode.appendChild( midiEventNode );
1036                        }
1037                }
1038        }
1039       
1040        rootNode.appendChild( midiEventMapNode );
1041
1042        doc.appendChild( rootNode );
1043       
1044        QFile file( filename );
1045        if ( !file.open(QIODevice::WriteOnly) )
1046                return;
1047
1048        QTextStream TextStream( &file );
1049        doc.save( TextStream, 1 );
1050
1051        file.close();
1052}
1053
1054
1055
1056///
1057/// Create preferences directory
1058///
1059void Preferences::createPreferencesDirectory()
1060{
1061        QString prefDir = m_sPreferencesDirectory;
1062        INFOLOG( "Creating preference file directory in " + prefDir );
1063
1064        QDir dir;
1065        dir.mkdir( prefDir );
1066}
1067
1068
1069
1070///
1071/// Create data directory
1072///
1073void Preferences::createDataDirectory()
1074{
1075        QString sDir = m_sDataDirectory;
1076        INFOLOG( "Creating data directory in " + sDir );
1077
1078        QDir dir;
1079        dir.mkdir( sDir );
1080//      mkdir(dir.c_str(),S_IRWXU);
1081}
1082
1083void Preferences::createSoundLibraryDirectories()
1084{
1085        QString sDir = m_sDataDirectory;
1086        QString sDrumkitDir;
1087        QString sSongDir;
1088        QString sPatternDir;
1089        QString sPlaylistDir;
1090
1091        INFOLOG( "Creating soundLibrary directories in " + sDir );
1092       
1093        sDrumkitDir = sDir + "/drumkits";
1094        sSongDir = sDir + "/songs";
1095        sPatternDir = sDir + "/patterns";
1096        sPlaylistDir = sDir + "/playlists";
1097
1098        QDir dir;
1099        dir.mkdir( sDrumkitDir );
1100        dir.mkdir( sSongDir );
1101        dir.mkdir( sPatternDir );
1102        dir.mkdir( sPlaylistDir );
1103}
1104
1105
1106void Preferences::setMostRecentFX( QString FX_name )
1107{
1108        int pos = m_recentFX.indexOf( FX_name );
1109       
1110        if ( pos != -1 )
1111                m_recentFX.removeAt( pos );
1112       
1113        m_recentFX.push_front( FX_name );
1114}
1115
1116void Preferences::setRecentFiles( std::vector<QString> recentFiles )
1117{
1118        // find single filenames. (skip duplicates)
1119        std::vector<QString> temp;
1120        for ( unsigned i = 0; i < recentFiles.size(); i++ ) {
1121                QString sFilename = recentFiles[ i ];
1122
1123                bool bExists = false;
1124                for ( unsigned j = 0; j < temp.size(); j++ ) {
1125                        if ( sFilename == temp[ j ] ) {
1126                                bExists = true;
1127                                break;
1128                        }
1129                }
1130                if ( !bExists ) {
1131                        temp.push_back( sFilename );
1132                }
1133        }
1134
1135        m_recentFiles = temp;
1136}
1137
1138
1139
1140/// Read the xml nodes related to window properties
1141WindowProperties Preferences::readWindowProperties( QDomNode parent, const QString& windowName, WindowProperties defaultProp )
1142{
1143        WindowProperties prop = defaultProp;
1144
1145        QDomNode windowPropNode  = parent.firstChildElement( windowName );
1146        if ( windowPropNode.isNull() ) {
1147                WARNINGLOG( "Error reading configuration file: " + windowName + " node not found" );
1148        } else {
1149                prop.visible = LocalFileMng::readXmlBool( windowPropNode, "visible", true );
1150                prop.x = LocalFileMng::readXmlInt( windowPropNode, "x", prop.x );
1151                prop.y = LocalFileMng::readXmlInt( windowPropNode, "y", prop.y );
1152                prop.width = LocalFileMng::readXmlInt( windowPropNode, "width", prop.width );
1153                prop.height = LocalFileMng::readXmlInt( windowPropNode, "height", prop.height );
1154        }
1155
1156        return prop;
1157}
1158
1159
1160
1161/// Write the xml nodes related to window properties
1162void Preferences::writeWindowProperties( QDomNode parent, const QString& windowName, const WindowProperties& prop )
1163{
1164        QDomDocument doc;
1165        QDomNode windowPropNode = doc.createElement( windowName );
1166        if ( prop.visible ) {
1167                LocalFileMng::writeXmlString( windowPropNode, "visible", "true" );
1168        } else {
1169                LocalFileMng::writeXmlString( windowPropNode, "visible", "false" );
1170        }
1171
1172        LocalFileMng::writeXmlString( windowPropNode, "x", QString("%1").arg( prop.x ) );
1173        LocalFileMng::writeXmlString( windowPropNode, "y", QString("%1").arg( prop.y ) );
1174        LocalFileMng::writeXmlString( windowPropNode, "width", QString("%1").arg( prop.width ) );
1175        LocalFileMng::writeXmlString( windowPropNode, "height", QString("%1").arg( prop.height ) );
1176        parent.appendChild( windowPropNode );
1177}
1178
1179
1180
1181void Preferences::writeUIStyle( QDomNode parent )
1182{
1183        QDomDocument doc;
1184        QDomNode node = doc.createElement( "UI_Style" );
1185
1186        // SONG EDITOR
1187        QDomNode songEditorNode = doc.createElement( "songEditor" );
1188        LocalFileMng::writeXmlString( songEditorNode, "backgroundColor", m_pDefaultUIStyle->m_songEditor_backgroundColor.toStringFmt() );
1189        LocalFileMng::writeXmlString( songEditorNode, "alternateRowColor", m_pDefaultUIStyle->m_songEditor_alternateRowColor.toStringFmt() );
1190        LocalFileMng::writeXmlString( songEditorNode, "selectedRowColor", m_pDefaultUIStyle->m_songEditor_selectedRowColor.toStringFmt() );
1191        LocalFileMng::writeXmlString( songEditorNode, "lineColor", m_pDefaultUIStyle->m_songEditor_lineColor.toStringFmt() );
1192        LocalFileMng::writeXmlString( songEditorNode, "textColor", m_pDefaultUIStyle->m_songEditor_textColor.toStringFmt() );
1193        LocalFileMng::writeXmlString( songEditorNode, "pattern1Color", m_pDefaultUIStyle->m_songEditor_pattern1Color.toStringFmt() );
1194        node.appendChild( songEditorNode );
1195
1196        // PATTERN EDITOR
1197        QDomNode patternEditorNode = doc.createElement( "patternEditor" );
1198        LocalFileMng::writeXmlString( patternEditorNode, "backgroundColor", m_pDefaultUIStyle->m_patternEditor_backgroundColor.toStringFmt() );
1199        LocalFileMng::writeXmlString( patternEditorNode, "alternateRowColor", m_pDefaultUIStyle->m_patternEditor_alternateRowColor.toStringFmt() );
1200        LocalFileMng::writeXmlString( patternEditorNode, "selectedRowColor", m_pDefaultUIStyle->m_patternEditor_selectedRowColor.toStringFmt() );
1201        LocalFileMng::writeXmlString( patternEditorNode, "textColor", m_pDefaultUIStyle->m_patternEditor_textColor.toStringFmt() );
1202        LocalFileMng::writeXmlString( patternEditorNode, "noteColor", m_pDefaultUIStyle->m_patternEditor_noteColor.toStringFmt() );
1203
1204        if (m_pDefaultUIStyle->m_patternEditor_noteoffColor.toStringFmt() == "-1,-1,-1" ){
1205                m_pDefaultUIStyle->m_patternEditor_noteoffColor = H2RGBColor( "100, 100, 200" );
1206        }
1207        LocalFileMng::writeXmlString( patternEditorNode, "noteoffColor", m_pDefaultUIStyle->m_patternEditor_noteoffColor.toStringFmt() );
1208
1209        LocalFileMng::writeXmlString( patternEditorNode, "lineColor", m_pDefaultUIStyle->m_patternEditor_lineColor.toStringFmt() );
1210        LocalFileMng::writeXmlString( patternEditorNode, "line1Color", m_pDefaultUIStyle->m_patternEditor_line1Color.toStringFmt() );
1211        LocalFileMng::writeXmlString( patternEditorNode, "line2Color", m_pDefaultUIStyle->m_patternEditor_line2Color.toStringFmt() );
1212        LocalFileMng::writeXmlString( patternEditorNode, "line3Color", m_pDefaultUIStyle->m_patternEditor_line3Color.toStringFmt() );
1213        LocalFileMng::writeXmlString( patternEditorNode, "line4Color", m_pDefaultUIStyle->m_patternEditor_line4Color.toStringFmt() );
1214        LocalFileMng::writeXmlString( patternEditorNode, "line5Color", m_pDefaultUIStyle->m_patternEditor_line5Color.toStringFmt() );
1215        node.appendChild( patternEditorNode );
1216
1217        parent.appendChild( node );
1218}
1219
1220
1221
1222void Preferences::readUIStyle( QDomNode parent )
1223{
1224        // SONG EDITOR
1225        QDomNode pSongEditorNode = parent.firstChildElement( "songEditor" );
1226        if ( !pSongEditorNode.isNull() ) {
1227                m_pDefaultUIStyle->m_songEditor_backgroundColor = H2RGBColor( LocalFileMng::readXmlString( pSongEditorNode, "backgroundColor", m_pDefaultUIStyle->m_songEditor_backgroundColor.toStringFmt() ) );
1228                m_pDefaultUIStyle->m_songEditor_alternateRowColor = H2RGBColor( LocalFileMng::readXmlString( pSongEditorNode, "alternateRowColor", m_pDefaultUIStyle->m_songEditor_alternateRowColor.toStringFmt() ) );
1229                m_pDefaultUIStyle->m_songEditor_selectedRowColor = H2RGBColor( LocalFileMng::readXmlString( pSongEditorNode, "selectedRowColor", m_pDefaultUIStyle->m_songEditor_selectedRowColor.toStringFmt() ) );
1230                m_pDefaultUIStyle->m_songEditor_lineColor = H2RGBColor( LocalFileMng::readXmlString( pSongEditorNode, "lineColor", m_pDefaultUIStyle->m_songEditor_lineColor.toStringFmt() ) );
1231                m_pDefaultUIStyle->m_songEditor_textColor = H2RGBColor( LocalFileMng::readXmlString( pSongEditorNode, "textColor", m_pDefaultUIStyle->m_songEditor_textColor.toStringFmt() ) );
1232                m_pDefaultUIStyle->m_songEditor_pattern1Color = H2RGBColor( LocalFileMng::readXmlString( pSongEditorNode, "pattern1Color", m_pDefaultUIStyle->m_songEditor_pattern1Color.toStringFmt() ) );
1233        } else {
1234                WARNINGLOG( "songEditor node not found" );
1235        }
1236
1237        // PATTERN EDITOR
1238        QDomNode pPatternEditorNode = parent.firstChildElement( "patternEditor" );
1239        if ( !pPatternEditorNode.isNull() ) {
1240                m_pDefaultUIStyle->m_patternEditor_backgroundColor = H2RGBColor( LocalFileMng::readXmlString( pPatternEditorNode, "backgroundColor", m_pDefaultUIStyle->m_patternEditor_backgroundColor.toStringFmt() ) );
1241                m_pDefaultUIStyle->m_patternEditor_alternateRowColor = H2RGBColor( LocalFileMng::readXmlString( pPatternEditorNode, "alternateRowColor", m_pDefaultUIStyle->m_patternEditor_alternateRowColor.toStringFmt() ) );
1242                m_pDefaultUIStyle->m_patternEditor_selectedRowColor = H2RGBColor( LocalFileMng::readXmlString( pPatternEditorNode, "selectedRowColor", m_pDefaultUIStyle->m_patternEditor_selectedRowColor.toStringFmt() ) );
1243                m_pDefaultUIStyle->m_patternEditor_textColor = H2RGBColor( LocalFileMng::readXmlString( pPatternEditorNode, "textColor", m_pDefaultUIStyle->m_patternEditor_textColor.toStringFmt() ) );
1244                m_pDefaultUIStyle->m_patternEditor_noteColor = H2RGBColor( LocalFileMng::readXmlString( pPatternEditorNode, "noteColor", m_pDefaultUIStyle->m_patternEditor_noteColor.toStringFmt() ) );
1245                m_pDefaultUIStyle->m_patternEditor_noteoffColor = H2RGBColor( LocalFileMng::readXmlString( pPatternEditorNode, "noteoffColor", m_pDefaultUIStyle->m_patternEditor_noteoffColor.toStringFmt() ) );
1246                m_pDefaultUIStyle->m_patternEditor_lineColor = H2RGBColor( LocalFileMng::readXmlString( pPatternEditorNode, "lineColor", m_pDefaultUIStyle->m_patternEditor_lineColor.toStringFmt() ) );
1247                m_pDefaultUIStyle->m_patternEditor_line1Color = H2RGBColor( LocalFileMng::readXmlString( pPatternEditorNode, "line1Color", m_pDefaultUIStyle->m_patternEditor_line1Color.toStringFmt() ) );
1248                m_pDefaultUIStyle->m_patternEditor_line2Color = H2RGBColor( LocalFileMng::readXmlString( pPatternEditorNode, "line2Color", m_pDefaultUIStyle->m_patternEditor_line2Color.toStringFmt() ) );
1249                m_pDefaultUIStyle->m_patternEditor_line3Color = H2RGBColor( LocalFileMng::readXmlString( pPatternEditorNode, "line3Color", m_pDefaultUIStyle->m_patternEditor_line3Color.toStringFmt() ) );
1250                m_pDefaultUIStyle->m_patternEditor_line4Color = H2RGBColor( LocalFileMng::readXmlString( pPatternEditorNode, "line4Color", m_pDefaultUIStyle->m_patternEditor_line4Color.toStringFmt() ) );
1251                m_pDefaultUIStyle->m_patternEditor_line5Color = H2RGBColor( LocalFileMng::readXmlString( pPatternEditorNode, "line5Color", m_pDefaultUIStyle->m_patternEditor_line5Color.toStringFmt() ) );
1252        } else {
1253                WARNINGLOG( "patternEditor node not found" );
1254        }
1255}
1256
1257
1258// -----------------------
1259
1260
1261
1262
1263WindowProperties::WindowProperties()
1264                : Object( "WindowProperties" )
1265{
1266//      infoLog( "INIT" );
1267        x = 0;
1268        y = 0;
1269        width = 0;
1270        height = 0;
1271        visible = true;
1272}
1273
1274
1275
1276WindowProperties::~WindowProperties()
1277{
1278//      infoLog( "DESTROY" );
1279}
1280
1281
1282
1283
1284// :::::::::::::::::::::::::::::::
1285
1286
1287
1288UIStyle::UIStyle()
1289                : Object( "UIStyle" )
1290{
1291//      infoLog( "INIT" );
1292}
1293
1294
1295
1296// ::::::::::::::::::::::::::::::::::::::
1297
1298
1299
1300H2RGBColor::H2RGBColor( int r, int g, int b )
1301                : Object( "H2RGBColor" )
1302                , m_red( r )
1303                , m_green( g )
1304                , m_blue( b )
1305{
1306//      infoLog( "INIT" );
1307        m_red %= 256;
1308        m_green %= 256;
1309        m_blue %= 256;
1310}
1311
1312
1313
1314H2RGBColor::~H2RGBColor()
1315{
1316//      infoLog( "DESTROY" );
1317}
1318
1319
1320
1321H2RGBColor::H2RGBColor( const QString& sColor )
1322                : Object( "H2RGBColor" )
1323{
1324//      infoLog( "INIT " + sColor );
1325        QString temp = sColor;
1326
1327        QStringList list = temp.split(",");
1328        m_red = list[0].toInt();
1329        m_green = list[1].toInt();
1330        m_blue = list[2].toInt();
1331
1332        m_red %= 256;
1333        m_green %= 256;
1334        m_blue %= 256;
1335
1336/*
1337        int nPos = temp.indexOf( ',' );
1338        QString sRed = temp.substr( 0, nPos );
1339        temp.erase( 0, nPos + 1 );
1340
1341        nPos = temp.find( ',' );
1342        QString sGreen = temp.substr( 0, nPos );
1343        temp.erase( 0, nPos + 1 );
1344
1345        nPos = temp.find( ',' );
1346        QString sBlue = temp.substr( 0, nPos );
1347
1348        m_red = atoi( sRed.c_str() );
1349        m_green = atoi( sGreen.c_str() );
1350        m_blue = atoi( sBlue.c_str() );
1351*/
1352}
1353
1354
1355
1356QString H2RGBColor::toStringFmt()
1357{
1358        char tmp[255];
1359        sprintf( tmp, "%d,%d,%d", m_red, m_green, m_blue );
1360
1361        //string sRes = to_string( m_red ) + "," + to_string( m_green ) + "," + to_string( m_blue );
1362//      return sRes;
1363
1364        return QString( tmp );
1365}
1366
1367};
Note: See TracBrowser for help on using the browser.