root/branches/undo/src/gui/src/HydrogenApp.cpp @ 2186

Revision 2186, 12.8 KB (checked in by mauser, 2 years ago)

[undo]turned tempory directory cleanup message from ERRORLOG to INFOLOG

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 <hydrogen/config.h>
24#include <hydrogen/version.h>
25
26#include "HydrogenApp.h"
27#include "Skin.h"
28#include "PreferencesDialog.h"
29#include "MainForm.h"
30#include "PlayerControl.h"
31#include "AudioEngineInfoForm.h"
32#include "HelpBrowser.h"
33#include "LadspaFXProperties.h"
34#include "InstrumentRack.h"
35
36#include "PatternEditor/PatternEditorPanel.h"
37#include "InstrumentEditor/InstrumentEditorPanel.h"
38#include "SongEditor/SongEditor.h"
39#include "SongEditor/SongEditorPanel.h"
40#include "PlaylistEditor/PlaylistDialog.h"
41#include "SampleEditor/SampleEditor.h"
42#include "Director.h"
43
44#include "Mixer/Mixer.h"
45#include "Mixer/MixerLine.h"
46
47#include <hydrogen/hydrogen.h>
48#include <hydrogen/event_queue.h>
49#include <hydrogen/fx/LadspaFX.h>
50#include <hydrogen/Preferences.h>
51//#include <hydrogen/sample.h>
52
53#include <QtGui>
54//#include <QDir>
55
56using namespace H2Core;
57
58HydrogenApp* HydrogenApp::m_pInstance = NULL;
59const char* HydrogenApp::__class_name = "HydrogenApp";
60
61HydrogenApp::HydrogenApp( MainForm *pMainForm, Song *pFirstSong )
62 : Object( __class_name )
63 , m_pMainForm( pMainForm )
64 , m_pMixer( NULL )
65 , m_pPatternEditorPanel( NULL )
66 , m_pAudioEngineInfoForm( NULL )
67 , m_pSongEditorPanel( NULL )
68 , m_pHelpBrowser( NULL )
69 , m_pFirstTimeInfo( NULL )
70 , m_pPlayerControl( NULL )
71 , m_pPlaylistDialog( NULL )
72 , m_pSampleEditor( NULL )
73 , m_pDirector( NULL )
74
75{
76        m_pInstance = this;
77
78        m_pEventQueueTimer = new QTimer(this);
79        connect( m_pEventQueueTimer, SIGNAL( timeout() ), this, SLOT( onEventQueueTimer() ) );
80        m_pEventQueueTimer->start(50);  // update at 20 fps
81
82
83        // Create the audio engine :)
84        Hydrogen::create_instance();
85        Hydrogen::get_instance()->setSong( pFirstSong );
86        Preferences::get_instance()->setLastSongFilename( pFirstSong->get_filename() );
87
88        //setup the undo stack
89        m_undoStack = new QUndoStack( this );
90
91        // set initial title
92        QString qsSongName( pFirstSong->__name );
93        if( qsSongName == "Untitled Song" && !pFirstSong->get_filename().isEmpty() ){
94                qsSongName = pFirstSong->get_filename();
95                qsSongName = qsSongName.section( '/', -1 );
96        }
97
98        setWindowTitle( qsSongName  );
99
100        Preferences *pPref = Preferences::get_instance();
101
102        setupSinglePanedInterface();
103
104        // restore audio engine form properties
105        m_pAudioEngineInfoForm = new AudioEngineInfoForm( 0 );
106        WindowProperties audioEngineInfoProp = pPref->getAudioEngineInfoProperties();
107        m_pAudioEngineInfoForm->move( audioEngineInfoProp.x, audioEngineInfoProp.y );
108        if ( audioEngineInfoProp.visible ) {
109                m_pAudioEngineInfoForm->show();
110        }
111        else {
112                m_pAudioEngineInfoForm->hide();
113        }
114       
115        m_pPlaylistDialog = new PlaylistDialog( 0 );
116        m_pDirector = new Director( 0 );
117//      m_pSampleEditor = new SampleEditor( 0 );
118       
119        showInfoSplash();       // First time information
120}
121
122
123
124HydrogenApp::~HydrogenApp()
125{
126        INFOLOG( "[~HydrogenApp]" );
127        m_pEventQueueTimer->stop();
128
129        //delete the undo tmp directory
130        QString dataDir = Preferences::get_instance()->getTmpDirectory();
131        QString cmd = QString( "rm -rf \"" ) + dataDir + "\"";
132        INFOLOG( cmd );
133        if ( system( cmd.toLocal8Bit() ) != 0 ) {
134                ERRORLOG( "Error executing '" + cmd + "'" );
135        }
136
137        delete m_pHelpBrowser;
138        delete m_pAudioEngineInfoForm;
139        delete m_pMixer;
140        delete m_pPlaylistDialog;
141        delete m_pDirector;
142        delete m_pSampleEditor;
143
144        Hydrogen *engine = Hydrogen::get_instance();
145        if (engine) {
146                H2Core::Song * song = engine->getSong();
147                // Hydrogen calls removeSong on from its destructor, so here we just delete the objects:
148                delete engine;
149                delete song;
150        }
151
152        #ifdef H2CORE_HAVE_LADSPA
153        for (uint nFX = 0; nFX < MAX_FX; nFX++) {
154                delete m_pLadspaFXProperties[nFX];
155        }
156        #endif
157       
158}
159
160
161
162/// Return an HydrogenApp m_pInstance
163HydrogenApp* HydrogenApp::get_instance() {
164        if (m_pInstance == NULL) {
165                std::cerr << "Error! HydrogenApp::get_instance (m_pInstance = NULL)" << std::endl;
166        }
167        return m_pInstance;
168}
169
170
171
172
173void HydrogenApp::setupSinglePanedInterface()
174{
175        Preferences *pPref = Preferences::get_instance();
176
177        // MAINFORM
178        WindowProperties mainFormProp = pPref->getMainFormProperties();
179        m_pMainForm->resize( mainFormProp.width, mainFormProp.height );
180        m_pMainForm->move( mainFormProp.x, mainFormProp.y );
181
182        QSplitter *pSplitter = new QSplitter( NULL );
183        pSplitter->setOrientation( Qt::Vertical );
184        pSplitter->setOpaqueResize( true );
185
186        // SONG EDITOR
187        m_pSongEditorPanel = new SongEditorPanel( pSplitter );
188        WindowProperties songEditorProp = pPref->getSongEditorProperties();
189        m_pSongEditorPanel->resize( songEditorProp.width, songEditorProp.height );
190
191        // this HBox will contain the InstrumentRack and the Pattern editor
192        QWidget *pSouthPanel = new QWidget( pSplitter );
193        QHBoxLayout *pEditorHBox = new QHBoxLayout();
194        pEditorHBox->setSpacing( 5 );
195        pEditorHBox->setMargin( 0 );
196        pSouthPanel->setLayout( pEditorHBox );
197
198        // INSTRUMENT RACK
199        m_pInstrumentRack = new InstrumentRack( NULL );
200
201        // PATTERN EDITOR
202        m_pPatternEditorPanel = new PatternEditorPanel( NULL );
203        WindowProperties patternEditorProp = pPref->getPatternEditorProperties();
204        m_pPatternEditorPanel->resize( patternEditorProp.width, patternEditorProp.height );
205
206        pEditorHBox->addWidget( m_pPatternEditorPanel );
207        pEditorHBox->addWidget( m_pInstrumentRack );
208
209        // PLayer control
210        m_pPlayerControl = new PlayerControl( NULL );
211
212
213        QWidget *mainArea = new QWidget( m_pMainForm ); // this is the main widget
214        m_pMainForm->setCentralWidget( mainArea );
215
216        // LAYOUT!!
217        QVBoxLayout *pMainVBox = new QVBoxLayout();
218        pMainVBox->setSpacing( 5 );
219        pMainVBox->setMargin( 0 );
220        pMainVBox->addWidget( m_pPlayerControl );
221        pMainVBox->addWidget( pSplitter );
222
223        mainArea->setLayout( pMainVBox );
224
225
226
227
228        // MIXER
229        m_pMixer = new Mixer(0);
230        WindowProperties mixerProp = pPref->getMixerProperties();
231        m_pMixer->resize( mixerProp.width, mixerProp.height );
232        m_pMixer->move( mixerProp.x, mixerProp.y );
233        m_pMixer->updateMixer();
234        if ( mixerProp.visible ) {
235                m_pMixer->show();
236        }
237        else {
238                m_pMixer->hide();
239        }
240
241
242        // HELP BROWSER
243        QString sDocPath = QString( DataPath::get_data_path() ) + "/doc";
244        QString sDocURI = sDocPath + "/manual.html";
245        m_pHelpBrowser = new SimpleHTMLBrowser( NULL, sDocPath, sDocURI, SimpleHTMLBrowser::MANUAL );
246
247#ifdef H2CORE_HAVE_LADSPA
248        // LADSPA FX
249        for (uint nFX = 0; nFX < MAX_FX; nFX++) {
250                m_pLadspaFXProperties[nFX] = new LadspaFXProperties( NULL, nFX );
251                m_pLadspaFXProperties[nFX]->hide();
252                WindowProperties prop = pPref->getLadspaProperties(nFX);
253                m_pLadspaFXProperties[nFX]->move( prop.x, prop.y );
254                if ( prop.visible ) {
255                        m_pLadspaFXProperties[nFX]->show();
256                }
257                else {
258                        m_pLadspaFXProperties[nFX]->hide();
259                }
260        }
261#endif
262
263//      m_pMainForm->showMaximized();
264}
265
266
267void HydrogenApp::closeFXProperties()
268{
269#ifdef H2CORE_HAVE_LADSPA
270        for (uint nFX = 0; nFX < MAX_FX; nFX++) {
271                m_pLadspaFXProperties[nFX]->close();
272        }
273#endif
274}
275
276
277
278void HydrogenApp::setSong(Song* song)
279{
280
281
282        Song* oldSong = (Hydrogen::get_instance())->getSong();
283        if (oldSong != NULL) {
284                (Hydrogen::get_instance())->removeSong();
285                delete oldSong;
286                oldSong = NULL;
287        }
288
289        Hydrogen::get_instance()->setSong( song );
290        Preferences::get_instance()->setLastSongFilename( song->get_filename() );
291
292        m_pSongEditorPanel->updateAll();
293        m_pPatternEditorPanel->updateSLnameLabel();
294
295        QString songName( song->__name );
296        if( songName == "Untitled Song" && !song->get_filename().isEmpty() ){
297                songName = song->get_filename();
298                songName = songName.section( '/', -1 );
299        }
300        setWindowTitle( songName  );
301
302        m_pMainForm->updateRecentUsedSongList();
303}
304
305
306
307void HydrogenApp::showMixer(bool show)
308{
309        m_pMixer->setVisible( show );
310}
311
312
313
314void HydrogenApp::showPreferencesDialog()
315{
316        PreferencesDialog preferencesDialog(m_pMainForm);
317        preferencesDialog.exec();
318}
319
320
321
322
323void HydrogenApp::setStatusBarMessage( const QString& msg, int msec )
324{
325        getPlayerControl()->showMessage( msg, msec );
326}
327
328void HydrogenApp::setWindowTitle( const QString& title){
329    m_pMainForm->setWindowTitle( ( "Hydrogen " + QString( get_version().c_str()) + QString( " - " ) + title ) );
330}
331
332void HydrogenApp::setScrollStatusBarMessage( const QString& msg, int msec, bool test )
333{
334        getPlayerControl()->showScrollMessage( msg, msec , test);
335}
336
337
338
339void HydrogenApp::showAudioEngineInfoForm()
340{
341        m_pAudioEngineInfoForm->hide();
342        m_pAudioEngineInfoForm->show();
343}
344
345void HydrogenApp::showPlaylistDialog()
346{
347        m_pPlaylistDialog->hide();
348        m_pPlaylistDialog->show();
349}
350
351
352void HydrogenApp::showDirector()
353{
354        m_pDirector->hide();
355        m_pDirector->show();
356}
357
358
359void HydrogenApp::showSampleEditor( QString name, int mSelectedLayer )
360{
361
362        if ( m_pSampleEditor ){
363                QApplication::setOverrideCursor(Qt::WaitCursor);
364                m_pSampleEditor->close();
365                delete m_pSampleEditor;
366                m_pSampleEditor = NULL;
367                QApplication::restoreOverrideCursor();
368        }
369        QApplication::setOverrideCursor(Qt::WaitCursor);       
370        m_pSampleEditor = new SampleEditor( 0, mSelectedLayer, name );
371        m_pSampleEditor->show();
372        QApplication::restoreOverrideCursor();
373}
374
375
376
377void HydrogenApp::showInfoSplash()
378{
379        QString sDocPath( DataPath::get_data_path().append( "/doc/infoSplash" ) );
380
381        QDir dir(sDocPath);
382        if ( !dir.exists() ) {
383                ERRORLOG( QString("[showInfoSplash] Directory ").append( sDocPath ).append( " not found." ) );
384                return;
385        }
386
387        QString sFilename;
388        int nNewsID = 0;
389        QFileInfoList list = dir.entryInfoList();
390
391        for ( int i =0; i < list.size(); ++i ) {
392                QString sFile = list.at( i ).fileName();
393
394                if ( sFile == "." || sFile == ".." ) {
395                        continue;
396                }
397
398                int nPos = sFile.lastIndexOf( "-" );
399                QString sNewsID = sFile.mid( nPos + 1, sFile.length() - nPos - 1 );
400                int nID = sNewsID.toInt();
401                if ( nID > nNewsID ) {
402                        sFilename = sFile;
403                }
404//              INFOLOG( "news: " + sFilename + " id: " + sNewsID );
405        }
406        INFOLOG( "[showInfoSplash] Selected news: " + sFilename );
407
408        QString sLastRead = Preferences::get_instance()->getLastNews();
409        if ( sLastRead != sFilename && !sFilename.isEmpty() ) {
410                QString sDocURI = sDocPath;
411                sDocURI.append( "/" ).append( sFilename );
412                SimpleHTMLBrowser *m_pFirstTimeInfo = new SimpleHTMLBrowser( m_pMainForm, sDocPath, sDocURI, SimpleHTMLBrowser::WELCOME );
413                if ( m_pFirstTimeInfo->exec() == QDialog::Accepted ) {
414                        Preferences::get_instance()->setLastNews( sFilename );
415                }
416        }
417}
418
419void HydrogenApp::onDrumkitLoad( QString name ){
420        setStatusBarMessage( trUtf8( "Drumkit loaded: [%1]" ).arg( name ), 2000 );
421        m_pPatternEditorPanel->updateSLnameLabel( );
422}
423
424void HydrogenApp::enableDestructiveRecMode(){
425        m_pPatternEditorPanel->displayorHidePrePostCB();
426}
427
428
429void HydrogenApp::onEventQueueTimer()
430{
431        // use the timer to do schedule instrument slaughter;
432        EventQueue *pQueue = EventQueue::get_instance();
433
434        Event event;
435        while ( ( event = pQueue->pop_event() ).type != EVENT_NONE ) {
436                for (int i = 0; i < (int)m_eventListeners.size(); i++ ) {
437                        EventListener *pListener = m_eventListeners[ i ];
438
439                        switch ( event.type ) {
440                                case EVENT_STATE:
441                                        pListener->stateChangedEvent( event.value );
442                                        break;
443
444                                case EVENT_PATTERN_CHANGED:
445                                        pListener->patternChangedEvent();
446                                        break;
447
448                                case EVENT_PATTERN_MODIFIED:
449                                        pListener->patternModifiedEvent();
450                                        break;
451
452                                case EVENT_SELECTED_PATTERN_CHANGED:
453                                        pListener->selectedPatternChangedEvent();
454                                        break;
455
456                                case EVENT_SELECTED_INSTRUMENT_CHANGED:
457                                        pListener->selectedInstrumentChangedEvent();
458                                        break;
459
460                                case EVENT_MIDI_ACTIVITY:
461                                        pListener->midiActivityEvent();
462                                        break;
463
464                                case EVENT_NOTEON:
465                                        pListener->noteOnEvent( event.value );
466                                        break;
467
468                                case EVENT_ERROR:
469                                        pListener->errorEvent( event.value );
470                                        break;
471
472                                case EVENT_XRUN:
473                                        pListener->XRunEvent();
474                                        break;
475
476                                case EVENT_METRONOME:
477                                        pListener->metronomeEvent( event.value );
478                                        break;
479
480                                case EVENT_RECALCULATERUBBERBAND:
481                                        pListener->rubberbandbpmchangeEvent();
482                                        break;
483
484                                case EVENT_PROGRESS:
485                                        pListener->progressEvent( event.value );
486                                        break;
487
488                                default:
489                                        ERRORLOG( QString("[onEventQueueTimer] Unhandled event: %1").arg( event.type ) );
490                        }
491
492                }
493        }
494}
495
496
497void HydrogenApp::addEventListener( EventListener* pListener )
498{
499        if (pListener) {
500                m_eventListeners.push_back( pListener );
501        }
502}
503
504
505void HydrogenApp::removeEventListener( EventListener* pListener )
506{
507        for ( uint i = 0; i < m_eventListeners.size(); i++ ) {
508                if ( pListener == m_eventListeners[ i ] ) {
509                        m_eventListeners.erase( m_eventListeners.begin() + i );
510                }
511        }
512}
513
Note: See TracBrowser for help on using the browser.