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

Revision 2190, 13.7 KB (checked in by mauser, 2 years ago)

[undo]removed debugging code

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