/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #ifdef XSID_WB_DEBUG #include #include using namespace std; #endif #ifdef XSID_HAVE_NOTHROW #include #endif using namespace std; #include #include #include #include #include #ifdef XSID_HAVE_TSID #include #endif #ifdef XSID_HAVE_LIRC #include #include #include #endif #include "MainDialog.h" #include "AudioDialog.h" #include "EmuDialog.h" #include "FilterDialog.h" #include "HistoryDialog.h" #include "HVSC_Dialog.h" #include "MixerDialog.h" #include "PlaylistDialog.h" #include "PlaylistEditDialog.h" #include "PlaylistOptDialog.h" #include "StilDialog.h" #include "StilDialog.h" #include "AudioDrivers.h" #include "ConfigC.h" #include "ConfigFile.h" #include "HVSC_Config.h" #include "filenames.h" #include "Playlist.h" #include "PlaylistCheck.h" #include "Player.h" #include "wrapper/SongLength.h" #include "wrapper/EmuWrapper.h" #include "wrapper/SidTuneWrapper.h" #include "widgets/PicButton.h" #include "widgets/TimeLCD.h" #include "images/prev.xpm" #include "images/stop.xpm" #include "images/play.xpm" #include "images/pause.xpm" #include "images/ff.xpm" #include "images/next.xpm" #include "images/stop_p.xpm" #include "images/pause_p.xpm" #include "images/ff_p.xpm" #include "images/prev_l.xpm" #include "images/stop_l.xpm" #include "images/play_l.xpm" #include "images/pause_l.xpm" #include "images/ff_l.xpm" #include "images/next_l.xpm" #include "images/prev_l_p.xpm" #include "images/stop_l_p.xpm" #include "images/play_l_p.xpm" #include "images/next_l_p.xpm" // -------------------------------------------------------------------------- MainDialog::MainDialog(QWidget* parent, const char* name) : MainDialogData(parent,name) { // Init pixmap pointers. prevPic = new QPixmap((const char**)prev_xpm); stopPic = new QPixmap((const char**)stop_xpm); playPic = new QPixmap((const char**)play_xpm); pausePic = new QPixmap((const char**)pause_xpm); ffPic = new QPixmap((const char**)ff_xpm); nextPic = new QPixmap((const char**)next_xpm); stop_pPic = new QPixmap((const char**)stop_p_xpm); pause_pPic = new QPixmap((const char**)pause_p_xpm); ff_pPic = new QPixmap((const char**)ff_p_xpm); prev_lPic = new QPixmap((const char**)prev_l_xpm); stop_lPic = new QPixmap((const char**)stop_l_xpm); play_lPic = new QPixmap((const char**)play_l_xpm); pause_lPic = new QPixmap((const char**)pause_l_xpm); ff_lPic = new QPixmap((const char**)ff_l_xpm); next_lPic = new QPixmap((const char**)next_l_xpm); prev_l_pPic = new QPixmap((const char**)prev_l_p_xpm); stop_l_pPic = new QPixmap((const char**)stop_l_p_xpm); play_l_pPic = new QPixmap((const char**)play_l_p_xpm); next_l_pPic = new QPixmap((const char**)next_l_p_xpm); // Finish dialog setup. setMinimumSize(width(),99); setIcon(*mainIcon); QFont infoField_font( infoField->font() ); infoField_font.setFixedPitch( true ); // infoField_font.setFamily( "Monospace" ); // infoField_font.setStyleHint( QFont::Courier ); // infoField_font.setPointSize( 10 ); infoField->setFont( infoField_font ); infoField->setText(""); QPopupMenu *fileMenu = new QPopupMenu(this); Q_CHECK_PTR( fileMenu ); fileMenu->insertItem( "&Open file(s)", this, SLOT(openFile()), CTRL+Key_O ); fileMenu->insertItem( "&Save as...", this, SLOT(saveAs()), CTRL+Key_S ); fileMenu->insertSeparator(); fileMenu->insertItem( "Exit", this, SLOT(quit()), CTRL+Key_Q ); QPopupMenu *configMenu = new QPopupMenu(this); Q_CHECK_PTR( configMenu ); configMenu->insertItem( "Audio", this, SLOT(openAudioDialog()) ); configMenu->insertItem( "Emulator", this, SLOT(openEmulatorDialog()) ); #ifndef SID_WITH_SIDPLAY2 configMenu->insertItem( "SID filter", this, SLOT(openFilterDialog()) ); #endif configMenu->insertItem( "HVSC", this, SLOT(openHVSC_Dialog()) ); QPopupMenu *playlistAddMenu = new QPopupMenu(this); Q_CHECK_PTR( playlistAddMenu ); playlistAddMenu->insertItem( "Directory", this, SLOT(addDirToPlaylist()) ); playlistAddMenu->insertItem( "Tree", this, SLOT(addTreeToPlaylist()) ); playlistAddMenu->insertItem( "Hotlist", this, SLOT(addHotlistToPlaylist()) ); QPopupMenu *playlistMenu = new QPopupMenu(this); Q_CHECK_PTR( playlistMenu ); playlistMenu->insertItem( "&View", this, SLOT(openPlaylistDialog()), CTRL+Key_V ); playlistMenu->insertItem( "&Edit", this, SLOT(openPlaylistEditDialog()), CTRL+Key_E ); playlistMenu->insertSeparator(); playlistMenu->insertItem( "&Load...", this, SLOT(loadPlaylist()), CTRL+Key_L ); playlistMenu->insertItem( "Save as...", this, SLOT(savePlaylistAs()) ); playlistMenu->insertSeparator(); playlistMenu->insertItem( "&Add tune", this, SLOT(addTuneToPlaylist()), CTRL+Key_A ); playlistMenu->insertItem( "Add...", playlistAddMenu ); playlistMenu->insertSeparator(); playlistMenu->insertItem( "Update", this, SLOT(updatePlaylist()) ); playlistMenu->insertSeparator(); playlistMenu->insertItem( "Options", this, SLOT(openPlaylistOptions()) ); QPopupMenu *hotlistMenu = new QPopupMenu(this); Q_CHECK_PTR( hotlistMenu ); hotlistMenu->insertItem( "&Mark tune", this, SLOT(markTune()), CTRL+Key_M ); hotlistMenu->insertItem( "Mark all", this, SLOT(markPlaylist()) ); hotlistMenu->insertSeparator(); hotlistMenu->insertItem( "Save as...", this, SLOT(saveHotlist()) ); extraMenu = new QPopupMenu(this); Q_CHECK_PTR( extraMenu ); extraMenu->setCheckable(true); stilID = extraMenu->insertItem( "STIL view", this, SLOT(toggleStilDialog()) ); songLenDbID = extraMenu->insertItem( "Songlen DB", this, SLOT(toggleSongLengthDB()) ); extraMenu->insertItem( "History", this, SLOT(openHistoryDialog()) ); #ifndef SID_WITH_SIDPLAY2 extraMenu->insertItem( "Mixer", this, SLOT(openMixerDialog()) ); #endif QPopupMenu *helpMenu = new QPopupMenu(this); Q_CHECK_PTR( helpMenu ); helpMenu->insertItem( "SIDPLAY", this, SLOT(about()), CTRL+Key_H ); helpMenu->insertItem( "Qt", this, SLOT(aboutQt()) ); menuBar = new QMenuBar(this); Q_CHECK_PTR( menuBar ); menuBar->insertItem( "&File", fileMenu ); menuBar->insertItem( "&Config", configMenu ); menuBar->insertItem( "&Playlist", playlistMenu ); menuBar->insertItem( "&Hotlist", hotlistMenu ); menuBar->insertItem( "&Extra", extraMenu ); menuBar->insertSeparator(); menuBar->insertItem( "&About", helpMenu ); timeLCD->setSmallDecimalPoint( FALSE ); timeLCD->setNumDigits( 5 ); timeLCD->setMode( QLCDNumber::DEC ); timeLCD->setSegmentStyle( QLCDNumber::Filled ); timeLCD->setFrameShadow( QLCDNumber::Sunken ); timeLCD->setFrameShape( QLCDNumber::Panel ); #ifdef XSID_HAVE_TSID myTSID = new TSID; // Time SID Manager #endif // The currently active file name. sidFileNameFull = sidFileNameHVSC = ""; hotlist = new Playlist; myFileDlg = 0; // do that when we get access to the config file myAudioDlg = new AudioDialog(this); myEmuDlg = new EmuDialog(this); myFilterDlg = new FilterDialog(this); myMixerDlg = new MixerDialog(this); myHVSC_Dlg = new HVSC_Dialog(this); myHistoryDlg = new HistoryDialog(this); myPlaylistDlg = new PlaylistDialog(this); myPlaylistEditDlg = new PlaylistEditDialog(this); myStilDlg = new StilDialog(); myFilterDlg->connect(myEmuDlg,SIGNAL(changed(const emuConfig&)),myFilterDlg,SLOT(receiveConfig(const emuConfig&))); myEmuDlg->connect(myFilterDlg,SIGNAL(changed(const emuConfig&)),myEmuDlg,SLOT(receiveConfig(const emuConfig&))); connect(myEmuDlg,SIGNAL(changed(const emuConfig&)),this,SLOT(receiveEmuConfig(const emuConfig&))); connect(myFilterDlg,SIGNAL(changed(const emuConfig&)),this,SLOT(receiveEmuConfig(const emuConfig&))); connect(myHVSC_Dlg,SIGNAL(changed(const HVSC_Config&)),this,SLOT(receiveHVSC_Config(const HVSC_Config&))); connect(myMixerDlg,SIGNAL(changed(const MixerConfig&)),this,SLOT(receiveMixerConfig(const MixerConfig&))); connect(myHistoryDlg,SIGNAL(playHistoryItem(const QString&)),this,SLOT(playHistoryFile(const QString&))); playerButtonsOff(); subSongSlider->setFocus(); #ifdef XSID_HAVE_LIRC // set up device lircfh=lirc_init("xsidplay", 1); if(lircfh < 0) { qWarning("could not init LIRC"); } else { if(fcntl(lircfh, F_SETFL, O_NONBLOCK) < 0) qFatal("could not set O_NONBLOCK for LIRC"); else { if(lirc_readconfig(NULL /*configfile*/, &lircConfig, NULL) < 0) qFatal("could not read LIRC config"); else { QSocketNotifier *s=new QSocketNotifier(lircfh, QSocketNotifier::Read, this); Q_CHECK_PTR(s); connect(s, SIGNAL(activated(int)), this, SLOT(lircEvent(int))); } } } #endif } MainDialog::~MainDialog() { delete hotlist; #ifdef XSID_HAVE_TSID delete myTSID; #endif delete next_l_pPic; delete play_l_pPic; delete stop_l_pPic; delete prev_l_pPic; delete next_lPic; delete ff_lPic; delete pause_lPic; delete play_lPic; delete stop_lPic; delete prev_lPic; delete ff_pPic; delete pause_pPic; delete stop_pPic; delete nextPic; delete ffPic; delete pausePic; delete playPic; delete stopPic; delete prevPic; #ifdef XSID_HAVE_LIRC if(lircfh >= 0) { if(lircConfig) lirc_freeconfig(lircConfig); lirc_deinit(); } #endif } void MainDialog::setup(ConfigFile* cfg, const QString& path, Player* p) { config = cfg; configPath = path; player = p; // Receive 'play' and 'stop' signals from player and playlist dialogs. // We are responsible for starting/stopping songs. connect(player,SIGNAL( playListItem(const PlaylistItem&) ),this,SLOT( playPlaylistFile(const PlaylistItem&) )); connect(player,SIGNAL( stopPlaylistPlay() ),this,SLOT( playerButtonsForceStop() )); connect(myPlaylistDlg,SIGNAL( playlistPlayRequest(const PlaylistItem&) ),this,SLOT( playPlaylistFile(const PlaylistItem&) )); connect(myPlaylistEditDlg,SIGNAL( playlistEditPlayRequest(const PlaylistItem&) ),this,SLOT( playPlaylistFile(const PlaylistItem&) )); // Let player receive 'playnewpos' signals from playlist dialog. connect(myPlaylistDlg,SIGNAL( playlistPlayNewPosRequest(int) ),player,SLOT( playNextFromList(int) )); // Let playlist dialog receive 'play' signal from player. // That way it can update the current item. connect(player,SIGNAL( playerPlayRequest(uint) ),myPlaylistDlg,SLOT( newListPos(uint) )); // Let playlist dialog receive signals from playlist editor. // That way it can update the current item or listbox. connect(myPlaylistEditDlg,SIGNAL( playlistEditPlayRequest(uint) ),myPlaylistDlg,SLOT( newListPos(uint) )); connect(myPlaylistEditDlg,SIGNAL( playlistEditDelRequest(uint) ),myPlaylistDlg,SLOT( deleteListPos(uint) )); connect(myPlaylistEditDlg,SIGNAL( playlistEditClearRequest() ),myPlaylistDlg,SLOT( clear() )); connect(myPlaylistEditDlg,SIGNAL( playlistEditUpdateRequest(uint) ),myPlaylistDlg,SLOT( updateListPos(uint) )); // Give player access to a few widgets. player->link(this,timeLCD,myPlaylistDlg); // Give playlist dialogs access to list in player. myPlaylistEditDlg->takeList( player->getPlaylist() ); myPlaylistDlg->takeList( player->getPlaylist() ); myFilterDlg->setConfigDefault( player->getEmuEngine()->getConfigDefault() ); // *not* redundant // Order is important with current implementation. setEmuConfig( config->getEmuConfig() ); myHVSC_Dlg->setConfig( config->getHVSC_Config() ); myStilDlg->setConfig( config->getHVSC_Config() ); config->setGroup( ConfigC::groups[ConfigC::Audio] ); QString audioDriver = config->getString( ConfigC::keys[ConfigC::Driver] ); if ( audioDriver.isEmpty() ) audioDriver = "No Sound"; AudioDrivers::setDriver( audioDriver ); #ifdef XSID_WB_DEBUG cout << AudioDrivers::getName() << endl; #endif setAudioConfig( config->getAudioConfig() ); // HVSC root playlist basedir hack. player->getPlaylist()->setMaxBasePrefix( config->getHVSC_Config().hvscRootPath.absPath() ); // Mixer - Since we do not save the entire MixerConfig to disk, // we copy relevant values from the emuConfig. // The mixer knows the emuConfig constants. MixerConfig newMixerConfig = config->getMixerConfig(); newMixerConfig.channels = player->getEmuEngine()->getConfig().channels; newMixerConfig.mixingMode = player->getEmuEngine()->getConfig().volumeControl; newMixerConfig.panningMode = player->getEmuEngine()->getConfig().autoPanning; myMixerDlg->setConfig(newMixerConfig); // Make sure volume levels get set as well. receiveMixerConfig(newMixerConfig); // Playlist dialog config->setGroup(ConfigC::groups[ConfigC::Playlist]); config->restoreGeom(myPlaylistDlg); playtimeDefault = 0; fadeoutDefault = 3; config->getValue(ConfigC::keys[ConfigC::PlaytimeDefault],playtimeDefault); config->getValue(ConfigC::keys[ConfigC::FadeOutDefault],fadeoutDefault); if ( config->getBool( ConfigC::keys[ConfigC::SongLenDB] )) setSongLenDbEnabled( initSongLengthDB() ); // Playlist editor config->setGroup(ConfigC::groups[ConfigC::PlaylistEditor]); config->restoreGeom(myPlaylistEditDlg); myHistoryDlg->load(configPath+'/'+HISTORY_FILE_NAME); // Misc config->setGroup(ConfigC::groups[ConfigC::Misc]); if ( config->getBool( ConfigC::keys[ConfigC::STIL_Viewer] )) setStilInfoEnabled( initStilViewClass() ); config->getValue( ConfigC::keys[ConfigC::Usage], usage ); // Main window config->setGroup(ConfigC::groups[ConfigC::MainWindow]); config->restoreGeom(this); // Create file selector with defaults from config file. config->setGroup(ConfigC::groups[ConfigC::Selector]); QString cwd = config->getString(ConfigC::keys[ConfigC::Dir]); QString nameFilter = config->getString(ConfigC::keys[ConfigC::NameFilter]); myFileDlg = new QFileDialog(cwd,nameFilter,this,"Selector_file_dialog",false); config->restoreGeom(myFileDlg); myFileDlg->setCaption("SIDPLAY: Sidtune selector"); myFileDlg->setMode(QFileDialog::ExistingFile); myFileDlg->setIcon(*mainIcon); connect(myFileDlg,SIGNAL(fileHighlighted(const QString&)),this,SLOT(playFile(const QString&))); if ( config->getBool(ConfigC::keys[ConfigC::Open]) ) openFile(); } bool MainDialog::writeConfig() { // Misc config->setGroup(ConfigC::groups[ConfigC::Misc]); long int mileage = usage+player->getEmuEngine()->getSecondsTotal(); config->setEntry( ConfigC::keys[ConfigC::Usage], mileage); config->setEntry( ConfigC::keys[ConfigC::STIL_Viewer], isStilInfoEnabled() ); AudioConfig thisAudioConfig = myAudioDlg->getConfig(); // Always save user`s sane fragmentation settings. extern AudioConfig bakAudioConfig; thisAudioConfig.bufSize = bakAudioConfig.bufSize; thisAudioConfig.maxFrags = bakAudioConfig.maxFrags; thisAudioConfig.fragSize = bakAudioConfig.fragSize; config->setAudioConfig(thisAudioConfig); config->setGroup( ConfigC::groups[ConfigC::Audio] ); config->setEntry( ConfigC::keys[ConfigC::Driver], AudioDrivers::getName() ); config->setEmuConfig( player->getEmuEngine()->getConfig() ); config->setHVSC_Config( myHVSC_Dlg->getConfig() ); config->setMixerConfig( myMixerDlg->getConfig() ); // Playlist config->setGroup( ConfigC::groups[ConfigC::Playlist] ); config->saveGeom(myPlaylistDlg); config->setEntry( ConfigC::keys[ConfigC::PlaytimeDefault], playtimeDefault); config->setEntry( ConfigC::keys[ConfigC::FadeOutDefault], fadeoutDefault); config->setEntry( ConfigC::keys[ConfigC::SongLenDB], isSongLenDbEnabled() ); // Playlist editor config->setGroup(ConfigC::groups[ConfigC::PlaylistEditor]); config->saveGeom(myPlaylistEditDlg); // Selector config->setGroup(ConfigC::groups[ConfigC::Selector]); config->saveGeom(myFileDlg); // See playFile(..). //config->setEntry( ConfigC::keys[ConfigC::Dir], myFileDlg->dirPath() ); //qDebug( myFileDlg->dirPath() ); config->setEntry( ConfigC::keys[ConfigC::NameFilter], myFileDlg->selectedFilter() ); config->setEntry( ConfigC::keys[ConfigC::Open], myFileDlg->isVisible() ); // Dialog geometries. config->setGroup(ConfigC::groups[ConfigC::MainWindow]); config->saveGeom(this); bool ret = config->save(); if (!ret) { QMessageBox error; error.setIcon(QMessageBox::Warning); error.setText("Could not save configuration file!"); error.adjustSize(); error.exec(); } return ret; } /* * [ms]: If this way of receiving config data from dialogs (and sending * data to other dialogs) on the fly turns out to be buggy, it * could be changed at any time by turning the dialogs into modal * dialogs and adding common OK/Apply/Cancel buttons. * Currently the worst thing that can happen is that Qt signals * pass on to the next dialog until all dialogs have the same * config. */ void MainDialog::setAudioConfig(const AudioConfig& inConfig) { // Let the audio dialog check/adjust the config. myAudioDlg->setConfig(inConfig); if ( !player->init( myAudioDlg->getConfig() ) ) infoField->setText( player->getErrorStr() ); // Now retrieve the possibly changed config from the driver. AudioConfig goodAudioConfig = player->getAudioConfig(); myAudioDlg->setConfig(goodAudioConfig); // Set dialogs that directly depend on the emuConfig. myEmuDlg->setConfig( player->getEmuEngine()->getConfig() ); myFilterDlg->setConfig( player->getEmuEngine()->getConfig() ); // Here update the dialog buttons according to the settings the // audio driver accepted. myAudioDlg->setButtons(); MixerConfig newMixerConfig = myMixerDlg->getConfig(); // The mixer knows the emuConfig constants. newMixerConfig.channels = player->getEmuEngine()->getConfig().channels; newMixerConfig.mixingMode = player->getEmuEngine()->getConfig().volumeControl; newMixerConfig.panningMode = player->getEmuEngine()->getConfig().autoPanning; myMixerDlg->setConfig(newMixerConfig); // Make sure volume levels get set as well. receiveMixerConfig(newMixerConfig); } void MainDialog::setEmuConfig(const emuConfig& inConfig) { player->getEmuEngine()->setConfig(inConfig); emuConfig myEmuConfig = player->getEmuEngine()->getConfig(); // get a good copy // Set dialogs that directly depend on the emuConfig. // Not: myMixerDlg. myEmuDlg->setConfig(myEmuConfig); myFilterDlg->setConfig(myEmuConfig); } void MainDialog::receiveEmuConfig(const emuConfig& inConfig) { // Save current player state to allow for paused playback. bool wasPlaying = player->isPlaying(); bool wasPaused = player->isPaused(); player->pause(true); player->getEmuEngine()->setConfig(inConfig); emuConfig myEmuConfig = player->getEmuEngine()->getConfig(); // get a good copy // Do not write back emuConfig to any dialog. // But: myFilterDlg->paintFilterFunc(); MixerConfig newMixerConfig = myMixerDlg->getConfig(); // The mixer knows the emuConfig constants. newMixerConfig.channels = myEmuConfig.channels; newMixerConfig.mixingMode = myEmuConfig.volumeControl; newMixerConfig.panningMode = myEmuConfig.autoPanning; myMixerDlg->setConfig(newMixerConfig); if ( wasPlaying && !wasPaused ) player->resume(); } void MainDialog::receiveHVSC_Config(const HVSC_Config& inConfig) { myStilDlg->setConfig(inConfig); if ( isStilInfoEnabled() ) setStilInfoEnabled( initStilViewClass() ); // Hide a possibly open STIL dialog. if ( myStilDlg->isVisible() && !isStilInfoEnabled() ) myStilDlg->hide(); if ( isSongLenDbEnabled() ) setSongLenDbEnabled( initSongLengthDB() ); // HVSC root playlist basedir hack. player->getPlaylist()->setMaxBasePrefix( inConfig.hvscRootPath.absPath() ); } void MainDialog::receiveMixerConfig(const MixerConfig& inConfig) { emuConfig myEmuConfig = player->getEmuEngine()->getConfig(); // get a good copy if ((myEmuConfig.volumeControl!=inConfig.mixingMode) || (myEmuConfig.autoPanning!=inConfig.panningMode)) { myEmuConfig.volumeControl = inConfig.mixingMode; myEmuConfig.autoPanning = inConfig.panningMode; player->getEmuEngine()->setConfig(myEmuConfig); myEmuConfig = player->getEmuEngine()->getConfig(); myEmuDlg->setConfig(myEmuConfig); myFilterDlg->setConfig(myEmuConfig); } for (int v=0; v < MixerDialog::voices; v++) { // In mono mode, set voice volume regardless of whether mixing // mode is active. if (myEmuConfig.channels == SIDEMU_MONO) { player->getEmuEngine()->setVoiceVolume(v+1,255,0, inConfig.volTotal[v]&inConfig.muteMask[v]); } else { if (myEmuConfig.volumeControl == SIDEMU_VOLCONTROL) { player->getEmuEngine()->setVoiceVolume(v+1,inConfig.volHQ[v].l,inConfig.volHQ[v].r, inConfig.volTotal[v]&inConfig.muteMask[v]); } else if ((myEmuConfig.volumeControl==SIDEMU_FULLPANNING) && (myEmuConfig.autoPanning==SIDEMU_NONE)) { player->getEmuEngine()->setVoiceVolume(v+1,inConfig.volFP[v].l,inConfig.volFP[v].r, inConfig.volTotal[v]&inConfig.muteMask[v]); } else // STEREOSURROUND or AUTOPANNING { // Adjust only the master volume level. // This is not clean because we don't use the emuEngine-defaults. if (myEmuConfig.volumeControl == SIDEMU_STEREOSURROUND) { player->getEmuEngine()->setVoiceVolume(v+1,255,255,inConfig.volTotal[v]&inConfig.muteMask[v]); } else { if ((v&1)==0) player->getEmuEngine()->setVoiceVolume(v+1,255,0,inConfig.volTotal[v]&inConfig.muteMask[v]); else player->getEmuEngine()->setVoiceVolume(v+1,0,255,inConfig.volTotal[v]&inConfig.muteMask[v]); } } } } } // -------------------------------------------------------------------------- void MainDialog::closeEvent(QCloseEvent* e) { programExitHook(); e->accept(); myStilDlg->close(); delete myStilDlg; // StilDialog is NOT a child } void MainDialog::resizeEvent(QResizeEvent*) { int w = width(); int h = height(); // 5,80,350,110 (main 358,222) infoField->setGeometry(5,80,w-10,h-102); if ( (h-102)<8 ) infoField->hide(); else if ( !infoField->isVisible() ) infoField->show(); playlistCheckBox->move(16,h-22); // 16,200 loopCheckBox->move(142,h-22); // 142,200 randomCheckBox->move(245,h-22); // 245,200 } void MainDialog::playerButtonsOff() { prevBtn->setPixmap(*prevPic); stopBtn->setPixmap(*stopPic); playBtn->setPixmap(*playPic); ffBtn->setPixmap(*ffPic); nextBtn->setPixmap(*nextPic); } void MainDialog::playerButtonsForceStart() { // Make them look as if playing. setPrevBtnState(); stopBtn->setPixmap(*stop_lPic); playBtn->setPixmap(*pause_lPic); ffBtn->setPixmap(*ff_lPic); setNextBtnState(); } void MainDialog::playerButtonsForceStop() { // Make them look as if stopped. setPrevBtnState(); stopBtn->setPixmap(*stopPic); playBtn->setPixmap(*play_lPic); ffBtn->setPixmap(*ffPic); setNextBtnState(); } void MainDialog::showSidTuneInfo() { QString tmp; if ( player->getSidTuneWrapper()->getInfoStringsNum() == 3 ) { tmp = "Name : "; tmp += player->getSidTuneWrapper()->getInfoString(0); tmp += "\nAuthor : "; tmp += player->getSidTuneWrapper()->getInfoString(1); tmp += "\nCopyright : "; tmp += player->getSidTuneWrapper()->getInfoString(2); } else { for ( int infoi = 0; infoi < player->getSidTuneWrapper()->getInfoStringsNum(); infoi++ ) { if (infoi > 0) tmp += "\n"; tmp += "Info : "; tmp += player->getSidTuneWrapper()->getInfoString(infoi); } } QString tmp2; tmp2.sprintf("\nSongs : %d (Startsong: %d)", player->getSidTuneWrapper()->getSongs(), player->getSidTuneWrapper()->getStartSong() ); tmp += tmp2; #ifdef SID_WITH_SIDPLAY2 tmp2.sprintf("\nSong speed: %s",player->getEmuEngine()->getSpeedString() ); tmp += tmp2; tmp2.sprintf("\nSID model : %s",player->getEmuEngine()->getSidModelString() ); #else tmp2.sprintf("\nSong speed: %s",player->getSidTuneWrapper()->getSpeedString() ); #endif tmp += tmp2; tmp2.sprintf("\nAddresses : $%04x, $%04x, $%04x", player->getSidTuneWrapper()->getLoadAddr(), player->getSidTuneWrapper()->getInitAddr(), player->getSidTuneWrapper()->getPlayAddr() ); tmp += tmp2; tmp2.sprintf("\nFormat : %s",player->getSidTuneWrapper()->getFormatString() ); tmp += tmp2; infoField->setText(tmp); songLCD->display(player->getSidTuneWrapper()->getCurrentSong() ); } void MainDialog::clearSidTuneInfo() { QString tmp = "Name : \n"; tmp += "Author : \n"; tmp += "Copyright : \n"; tmp += "Addresses : \n"; tmp += "Songs : \n"; tmp += "Song speed: \n"; tmp += "Format : \n"; infoField->setText(tmp); } // -------------------------------------------------------------------------- /* * Called before application is quit. */ void MainDialog::programExitHook() { player->stop(); #ifdef XSID_HAVE_TSID addTSID(); // add time last song has been listened to #endif writeConfig(); // ignore return value myHistoryDlg->save(); bool forceExit = false; while ( player->getPlaylist()->isModified() && !forceExit ) { QMessageBox mb( "SIDPLAY", "You are about to quit.\n\n" "Playlist has not been saved yet!\n" "Do you want to save it?", QMessageBox::Information, QMessageBox::Yes | QMessageBox::Default | QMessageBox::Escape, QMessageBox::No, 0); mb.setButtonText( QMessageBox::Yes, "Yes" ); mb.setButtonText( QMessageBox::No, "No" ); switch( mb.exec() ) { case QMessageBox::Yes: savePlaylistAs(); break; case QMessageBox::No: forceExit = true; break; } } forceExit = false; while ( hotlist->isModified() && !forceExit ) { QMessageBox mb( "SIDPLAY", "You are about to quit.\n\n" "Hotlist has not been saved yet!\n" "Do you want to save it?", QMessageBox::Information, QMessageBox::Yes | QMessageBox::Default | QMessageBox::Escape, QMessageBox::No, 0); mb.setButtonText( QMessageBox::Yes, "Yes" ); mb.setButtonText( QMessageBox::No, "No" ); switch( mb.exec() ) { case QMessageBox::Yes: saveHotlist(); break; case QMessageBox::No: forceExit = true; break; } } } void MainDialog::quit() { programExitHook(); qApp->quit(); } void MainDialog::openFile() { if ( myFileDlg!=0 ) { myFileDlg->show(); } } void MainDialog::saveAs() { if ( player->getSidTuneWrapper()->getStatus() ) { // Get last dir from config file. config->setGroup(ConfigC::groups[ConfigC::Selector]); QString lastSaveDir = config->getString(ConfigC::keys[ConfigC::SaveDir]); QString fileName = QFileDialog::getSaveFileName(lastSaveDir); if ( !fileName.isEmpty() && !player->getSidTuneWrapper()->savePSID(fileName,true) ) { QMessageBox error; error.setIcon(QMessageBox::Warning); error.setText("Could not save file!"); error.adjustSize(); error.exec(); } // Determine dir name and save it in config file. int slashPos = fileName.findRev( QDir::separator() ); if ( slashPos >= 0 ) fileName.truncate(slashPos); config->setGroup(ConfigC::groups[ConfigC::Selector]); config->setEntry(ConfigC::keys[ConfigC::SaveDir],fileName); } } // ----------------------------------------------------------- Playlist stuff void MainDialog::loadPlaylist() { bool forceLoad = false; while ( player->getPlaylist()->isModified() && !forceLoad ) { QMessageBox mb( "SIDPLAY", "Playlist has not been saved yet!\n" "Do you want to save it?", QMessageBox::Information, QMessageBox::Yes | QMessageBox::Default | QMessageBox::Escape, QMessageBox::No, 0); mb.setButtonText( QMessageBox::Yes, "Yes" ); mb.setButtonText( QMessageBox::No, "No" ); switch( mb.exec() ) { case QMessageBox::Yes: savePlaylistAs(); break; case QMessageBox::No: forceLoad = true; break; } } QString fileName = QFileDialog::getOpenFileName(fetchLastDir(ConfigC::groups[ConfigC::Playlist]), "*.spl",this,0,"SIDPLAY: Load playlist"); if ( !fileName.isEmpty() ) { QApplication::setOverrideCursor( Qt::waitCursor ); player->getPlaylist()->load(fileName); storeLastDir(ConfigC::groups[ConfigC::Playlist],fileName); QApplication::restoreOverrideCursor(); bool goodList = PlaylistCheck::checkBaseDir( this, player->getPlaylist(), myFileDlg ); if ( !goodList ) player->getPlaylist()->clear(); myPlaylistEditDlg->takeList( player->getPlaylist() ); myPlaylistDlg->takeList( player->getPlaylist() ); if ( goodList ) myPlaylistDlg->show(); } } // slot void MainDialog::savePlaylistAs() { QString fileName = QFileDialog::getSaveFileName(fetchLastDir(ConfigC::groups[ConfigC::Playlist]), "*.spl",this,0,"SIDPLAY: Save playlist"); if ( !fileName.isEmpty() ) { QApplication::setOverrideCursor( Qt::waitCursor ); bool ret = player->getPlaylist()->save(fileName); storeLastDir(ConfigC::groups[ConfigC::Playlist],fileName); QApplication::restoreOverrideCursor(); if (!ret) { QMessageBox error; error.setIcon(QMessageBox::Warning); error.setText("Could not save playlist!"); error.adjustSize(); error.exec(); } } } const QString& MainDialog::fetchLastDir(const char* group) { config->setGroup(group); return config->getString(ConfigC::keys[ConfigC::Dir]); } void MainDialog::storeLastDir(const char* group, const QString& fileName) { QString path = fileName; // Determine dir name and save it in config file. int slashPos = path.findRev( QDir::separator() ); if ( slashPos >= 0 ) path.truncate(slashPos+1); else path = QDir::separator(); config->setGroup(group); config->setEntry(ConfigC::keys[ConfigC::Dir],path); } void MainDialog::openPlaylistDialog() { myPlaylistDlg->show(); } void MainDialog::openPlaylistEditDialog() { myPlaylistEditDlg->show(); } void MainDialog::openPlaylistOptions() { PlaylistOptDialog* myPlaylistOptDlg = new PlaylistOptDialog(this,"Playlist Options Dialog",true); myPlaylistOptDlg->playtimeSpinBox->setValue( playtimeDefault ); myPlaylistOptDlg->fadeoutSpinBox->setValue( fadeoutDefault ); bool oldIsSongLenDbEnabled = isSongLenDbEnabled(); myPlaylistOptDlg->songlenDBcheckbox->setChecked( isSongLenDbEnabled() ); int result = myPlaylistOptDlg->exec(); if ( result==QDialog::Accepted ) { playtimeDefault = myPlaylistOptDlg->playtimeSpinBox->text().toInt(); fadeoutDefault = myPlaylistOptDlg->fadeoutSpinBox->text().toInt(); if ( myPlaylistOptDlg->songlenDBcheckbox->isChecked() && !oldIsSongLenDbEnabled ) { setSongLenDbEnabled( initSongLengthDB() ); } else if ( !myPlaylistOptDlg->songlenDBcheckbox->isChecked() ) { setSongLenDbEnabled( false ); } } delete myPlaylistOptDlg; } // slot void MainDialog::addTuneToPlaylist() { if ( !player->getSidTuneWrapper()->getStatus() ) return; PlaylistItem* item = new PlaylistItem; item->fileNameString = sidFileNameFull; item->titleString = player->getSidTuneWrapper()->getInfoString(0); item->authorString = player->getSidTuneWrapper()->getInfoString(1); item->copyrightString = player->getSidTuneWrapper()->getInfoString(2); item->subtune = player->getSidTuneWrapper()->getCurrentSong(); item->songs = player->getSidTuneWrapper()->getSongs(); item->fadeout = fadeoutDefault; item->time = querySongLengthDB(player->getSidTuneWrapper(), player->getSidTuneWrapper()->getCurrentSong() ); addTuneToPlaylistMain(item); } void MainDialog::addTuneToPlaylistMain(PlaylistItem* item) { QApplication::setOverrideCursor( Qt::waitCursor ); player->getPlaylist()->add(item); myPlaylistDlg->add(item); myPlaylistEditDlg->add(item); QApplication::restoreOverrideCursor(); } void MainDialog::addDirToPlaylist() { addDirMain(false); // not recursive } void MainDialog::addTreeToPlaylist() { addDirMain(true); // recursive } void MainDialog::addDirMain(bool recurse) { QString dirName = QFileDialog::getExistingDirectory(fetchLastDir(ConfigC::groups[ConfigC::Selector]),this,0, "SIDPLAY: Open directory to be added"); if ( dirName.isEmpty() ) { return; // User cancelled. } storeLastDir(ConfigC::groups[ConfigC::Selector],dirName); SidTuneWrapper* mySidLoader = new SidTuneWrapper; // unchecked alloc QApplication::setOverrideCursor( Qt::waitCursor ); addDirTraverse(dirName,recurse,mySidLoader); QApplication::restoreOverrideCursor(); delete mySidLoader; } void MainDialog::addDirTraverse(QString dirName, bool recurse, SidTuneWrapper* mySidLoader) { QDir* startDir = new QDir(dirName); Q_CHECK_PTR(startDir); const QFileInfoList* list = startDir->entryInfoList(); QListIterator it( *list ); // create list iterator for ( it.toFirst(); it.current(); ++it ) { QFileInfo* fi = it.current(); if ( recurse && fi->isDir() && fi->fileName()!="." && fi->fileName()!=".." ) { addDirTraverse(fi->absFilePath(),recurse,mySidLoader); } else if ( fi->isFile() && mySidLoader->open(fi->absFilePath()) ) { PlaylistItem* item = new PlaylistItem; item->fileNameString = fi->absFilePath(); item->titleString = mySidLoader->getInfoString(0); item->authorString = mySidLoader->getInfoString(1); item->copyrightString = mySidLoader->getInfoString(2); item->subtune = mySidLoader->getStartSong(); item->songs = mySidLoader->getSongs(); item->fadeout = fadeoutDefault; item->time = querySongLengthDB(mySidLoader, mySidLoader->getStartSong() ); addTuneToPlaylistMain(item); } } delete startDir; } // slot void MainDialog::updatePlaylist() { PlaylistCheck::updateEntries( this, player->getPlaylist(), myPlaylistDlg, myPlaylistEditDlg, myFileDlg ); } // slot void MainDialog::markTune() { if ( player->getSidTuneWrapper()->getStatus() ) { PlaylistItem* item = new PlaylistItem; item->fileNameString = sidFileNameFull; item->titleString = player->getSidTuneWrapper()->getInfoString(0); item->authorString = player->getSidTuneWrapper()->getInfoString(1); item->copyrightString = player->getSidTuneWrapper()->getInfoString(2); item->subtune = player->getSidTuneWrapper()->getCurrentSong(); item->songs = player->getSidTuneWrapper()->getSongs(); PlaylistItem i = player->getCurPlaylistParams(); item->fadeout = i.fadeout; item->time = i.time; QApplication::setOverrideCursor( Qt::waitCursor ); hotlist->add(item); QApplication::restoreOverrideCursor(); } } // slot void MainDialog::markPlaylist() { QApplication::setOverrideCursor( Qt::waitCursor ); // Add all playlist items to hotlist. QListIterator it(player->getPlaylist()->list); for ( it.toFirst(); it.current(); ++it ) { PlaylistItem* item = new PlaylistItem; *item = *it.current(); hotlist->add(item); } QApplication::restoreOverrideCursor(); } // slot void MainDialog::addHotlistToPlaylist() { QApplication::setOverrideCursor( Qt::waitCursor ); // Add all hotlist list items to playlist. QListIterator it(hotlist->list); for ( it.toFirst(); it.current(); ++it ) { PlaylistItem* item = new PlaylistItem; *item = *it.current(); player->getPlaylist()->add(item); myPlaylistDlg->add(item); myPlaylistEditDlg->add(item); } // Clear hotlist. hotlist->clear(); QApplication::restoreOverrideCursor(); } // slot void MainDialog::saveHotlist() { // We use the last playlist open/save dir. QString fileName = QFileDialog::getSaveFileName(fetchLastDir(ConfigC::groups[ConfigC::Playlist]), "*.spl",this,0,"SIDPLAY: Save hotlist"); if ( !fileName.isEmpty() ) { QApplication::setOverrideCursor( Qt::waitCursor ); bool ret = hotlist->save(fileName); storeLastDir(ConfigC::groups[ConfigC::Playlist],fileName); QApplication::restoreOverrideCursor(); if (!ret) { QMessageBox error; error.setIcon(QMessageBox::Warning); error.setText("Could not save hotlist!"); error.adjustSize(); error.exec(); } } } // -------------------------------------------------------------------------- void MainDialog::about() { QString verCat = "SIDPLAY/X11 Version "; verCat += VERSION; verCat += "\nby Michael Schwendt\n\n"; verCat += player->getEmuEngine()->getVersionString(); verCat += "\n\n"; verCat += mySTIL.getVersion(); #ifdef XSID_HAVE_TSID verCat += "\n"; verCat += myTSID->getTSIDVersion(); #endif verCat += "\nListening mileage: "; long int mileage = usage+player->getEmuEngine()->getSecondsTotal(); int days = mileage/(3600L*24); mileage -= days*(3600L*24); int hours = mileage/3600L; mileage -= hours*3600L; int minutes = mileage/60; mileage -= minutes*60; QString timeCat; timeCat.sprintf("%d days, %d hours, %d minutes",days,hours,minutes); verCat += timeCat; QMessageBox::about(this,"About SIDPLAY",verCat); } void MainDialog::aboutQt() { QMessageBox::aboutQt(this); } void MainDialog::openAudioDialog() { // Save current player state to allow for paused playback. bool wasPlaying = player->isPlaying(); bool wasPaused = player->isPaused(); player->pause(true); AudioDrivers::getDriver()->unload(); myAudioDlg->setConfig( player->getAudioConfig() ); if ( myAudioDlg->exec() == QDialog::Accepted ) { setAudioConfig( myAudioDlg->getConfig() ); } if ( wasPlaying && !wasPaused ) player->resume(); } void MainDialog::openEmulatorDialog() { myEmuDlg->show(); } void MainDialog::openFilterDialog() { myFilterDlg->show(); } void MainDialog::openMixerDialog() { myMixerDlg->show(); } void MainDialog::openHVSC_Dialog() { myHVSC_Dlg->show(); } void MainDialog::openHistoryDialog() { myHistoryDlg->show(); } // -------------------------------------------------------------------------- /* slot */ void MainDialog::setPlaylistEnabled(bool value) { player->enablePlaylist(value); } /* slot */ void MainDialog::setLoopPlayEnabled(bool value) { player->enablePlaylistLoop(value); } /* slot */ void MainDialog::setRandomPlayEnabled(bool value) { player->enablePlaylistRand(value); } /* slot */ void MainDialog::newSubSong(int newSong) { if ( player->getSidTuneWrapper()->getStatus() && newSong>=1 && newSong<=player->getSidTuneWrapper()->getSongs() ) { player->pause(); #ifdef XSID_HAVE_TSID addTSID(); // add time last song has been listened to #endif resetTimeDisplay(); player->initSong(newSong); playlistCheckBox->setChecked(false); player->resume(); if ( player->isReady() ) { showSidTuneInfo(); showStilInfo(); setPrevBtnState(); setNextBtnState(); } } else { player->stop(); playerButtonsOff(); } } void MainDialog::updateSubSongSlider() { if ( player->getSidTuneWrapper()->getStatus() ) { // Block signals here, or otherwise the slider would emit // newValue(int) and activate the new newSubSong(int) slot. subSongSlider->blockSignals(true); subSongSlider->setRange(1,player->getSidTuneWrapper()->getSongs() ); subSongSlider->setSteps(1,1); subSongSlider->setValue(player->getSidTuneWrapper()->getCurrentSong() ); subSongSlider->blockSignals(false); } } void MainDialog::resetTimeDisplay() { player->getEmuEngine()->resetSecondsThisSong(); timeLCD->resetDisplay(); } // ----------------------------------------------------------- Player buttons void MainDialog::prevSongPressed() { if ( player->havePrevSong() ) { prevBtn->setPixmap(*prev_l_pPic); player->pause(); #ifdef XSID_HAVE_TSID addTSID(); // add time last song has been listened to #endif resetTimeDisplay(); player->initPrevSong(); playlistCheckBox->setChecked(false); updateSubSongSlider(); showSidTuneInfo(); showStilInfo(); if ( player->haveSidTune() ) setNextBtnState(); else playerButtonsOff(); player->resume(); } } void MainDialog::prevSongReleased() { setPrevBtnState(); } void MainDialog::setPrevBtnState() { if ( player->havePrevSong() ) prevBtn->setPixmap(*prev_lPic); else prevBtn->setPixmap(*prevPic); } void MainDialog::nextSongPressed() { if ( player->haveNextSong() ) { nextBtn->setPixmap(*next_l_pPic); player->pause(); #ifdef XSID_HAVE_TSID addTSID(); // add time last song has been listened to #endif resetTimeDisplay(); player->initNextSong(); playlistCheckBox->setChecked(false); updateSubSongSlider(); showSidTuneInfo(); showStilInfo(); if ( player->haveSidTune() ) setPrevBtnState(); else playerButtonsOff(); player->resume(); } } void MainDialog::nextSongReleased() { setNextBtnState(); } void MainDialog::setNextBtnState() { if ( player->haveNextSong() ) nextBtn->setPixmap(*next_lPic); else nextBtn->setPixmap(*nextPic); } void MainDialog::stopSongPressed() { if ( player->isReady() && player->isPlaying() ) { stopBtn->setPixmap(*stop_l_pPic); playBtn->setPixmap(*play_lPic); ffBtn->setPixmap(*ffPic); player->stop(); playlistCheckBox->setChecked(false); } } void MainDialog::stopSongReleased() { stopBtn->setPixmap(*stopPic); } void MainDialog::playSongPressed() { if ( !player->haveSidTune() ) return; if ( player->isStopped() ) { playBtn->setPixmap(*play_l_pPic); stopBtn->setPixmap(*stop_lPic); #ifdef XSID_HAVE_TSID addTSID(); // add time last song has been listened to // This catches repeated play back of the same sub-tune. #endif resetTimeDisplay(); player->start(); } else if ( player->isPaused() ) { playBtn->setPixmap(*play_l_pPic); player->resume(); } else if ( player->isPlaying() && !player->isForwarding() ) { playBtn->setPixmap(*pause_pPic); player->pause(); } } void MainDialog::playSongReleased() { if ( !player->haveSidTune() ) return; if ( player->isPaused() ) { playBtn->setPixmap(*play_lPic); ffBtn->setPixmap(*ffPic); } else if ( player->isPlaying() ) { if ( !player->isForwarding() ) { playBtn->setPixmap(*pause_lPic); ffBtn->setPixmap(*ff_lPic); } } else { playerButtonsForceStop(); QMessageBox error; error.setIcon(QMessageBox::Critical); error.setText( player->getErrorStr() ); error.adjustSize(); error.exec(); } } void MainDialog::forwardSongPressed() { if ( player->isForwarding() ) { playBtn->setPixmap(*pause_lPic); ffBtn->setPixmap(*ff_lPic); player->playNormalSpeed(); } else if ( player->isPlaying() && !player->isPaused() ) { playBtn->setPixmap(*pausePic); ffBtn->setPixmap(*ff_pPic); player->playFastForward(); } } void MainDialog::forwardSongReleased() { if ( player->isForwarding() ) ffBtn->setPixmap(*ff_pPic); else if ( player->isPlaying() && !player->isPaused() ) ffBtn->setPixmap(*ff_lPic); } // --------------------------------------------------------------- HVSC stuff void MainDialog::createHVSCfileName(const QString& fileName) { // Is filename anywhere in HVSC tree? if (fileName.find(myHVSC_Dlg->getConfig().hvscRootPath.absPath()) == 0) { // Create filename which is relative to the HVSC root. sidFileNameHVSC = fileName.right(fileName.length()- myHVSC_Dlg->getConfig().hvscRootPath.absPath().length()); } else { sidFileNameHVSC = ""; } } // --------------------------------------------------------------- STIL stuff bool MainDialog::initStilViewClass() { // Let STIL View class perform the check for the STIL database file. if ( mySTIL.setBaseDir( myHVSC_Dlg->getConfig().hvscRootPath.absPath() ) ) return true; QMessageBox error(this, "initStilViewClass() error"); error.setIcon( QMessageBox::Warning ); error.setText( mySTIL.getErrorStr() ); error.adjustSize(); error.exec(); return false; } void MainDialog::toggleStilDialog() { if ( isStilInfoEnabled() ) { // Disable STIL View. setStilInfoEnabled( false ); // Hide a possibly open STIL View dialog. if ( myStilDlg->isVisible() ) myStilDlg->hide(); } else // if !isStilInfoEnabled() { // Enabled STIL View (if init is successful). setStilInfoEnabled( initStilViewClass() ); // Try to show STIL entry for currently active file. showStilInfo(); } } void MainDialog::showStilInfo() { // STIL View not enabled or no HVSC-relative file active? if ( !isStilInfoEnabled() || sidFileNameHVSC.isEmpty() ) { // Nothing to show. Hence hide a possibly open STIL View dialog. myStilDlg->hide(); return; } int song = player->getSidTuneWrapper()->getCurrentSong(); bool stilIsOkay = true; // we want to avoid successive errors // These should be converted to QString as well. char* globalComment; QString stilEntry; char* bugEntry; // Now retrieve the individual STIL entries. if (stilIsOkay) { globalComment = mySTIL.getGlobalComment(sidFileNameHVSC); stilIsOkay = !mySTIL.hasCriticalError(); } if ( stilIsOkay && myHVSC_Dlg->getConfig().showForFile ) { // Get file-specific comment and all entries (STIL::all). stilEntry = mySTIL.getEntry( sidFileNameHVSC, 0 ); stilIsOkay = !mySTIL.hasCriticalError(); } else if ( stilIsOkay ) { // First get the file-global comment. stilEntry = mySTIL.getEntry( sidFileNameHVSC, 0, STIL::comment ); if ( stilIsOkay = !mySTIL.hasCriticalError() ) { // Append STIL entry for current sub-tune 'song'. stilEntry += mySTIL.getEntry( sidFileNameHVSC, song ); stilIsOkay = !mySTIL.hasCriticalError(); } } if (stilIsOkay) { bugEntry = mySTIL.getBug(sidFileNameHVSC,song); stilIsOkay = !mySTIL.hasCriticalError(); } if (stilIsOkay) { myStilDlg->setLabels(globalComment,stilEntry,bugEntry); } else { // Disable STIL View. // Protect the user from any further critical errors. setStilInfoEnabled(false); myStilDlg->hide(); QMessageBox error; error.setIcon(QMessageBox::Critical); error.setText(mySTIL.getErrorStr()); error.adjustSize(); error.exec(); } } // ------------------------------------------------------ Songlength DB stuff bool MainDialog::initSongLengthDB() { QString fileName = configPath + '/' + SONGLENGTHS_DB_FILE_NAME; if ( !QFile::exists(fileName) ) fileName = myHVSC_Dlg->getConfig().hvscRootPath.absPath() + HVSC_DOC_DIR_NAME + '/' + SONGLENGTHS_DB_FILE_NAME; if ( SongLength::init(fileName) ) return true; QMessageBox error; error.setIcon( QMessageBox::Warning ); error.setText( SongLength::getErrorStr() ); error.adjustSize(); error.exec(); return false; } void MainDialog::toggleSongLengthDB() { if ( isSongLenDbEnabled() ) { // Disable songlength database. setSongLenDbEnabled(false); // menu player->enableSongLengthDB(false); } else { // Enable songlength database (if init is successful). setSongLenDbEnabled( player->enableSongLengthDB( initSongLengthDB() )); } } int MainDialog::querySongLengthDB(SidTuneWrapper* pSid, int song) { if ( !isSongLenDbEnabled() ) return playtimeDefault; SongLengthDBitem sli; // No other error handling yet. bool ret = SongLength::getItem( pSid, song, sli ); #ifdef XSID_WB_DEBUG if ( !ret ) cerr << SongLength::getErrorStr() << endl; #endif return sli.playtime; } // ------------------------------------------------------------------- Player void MainDialog::playFile(const QString& fileName) { // A fix for Qt 2.3.0 on Seawolf. QFileDialog::dirPath() cuts off // the last sub-dir, which messes up the recently used dir in // xsidplay.ini. storeLastDir(ConfigC::groups[ConfigC::Selector],fileName); //qDebug(fileName); //qDebug( fetchLastDir(ConfigC::groups[ConfigC::Selector]) ); PlaylistItem pi; // just a dummy playFileMain( fileName, 0, pi, true, false ); } void MainDialog::playHistoryFile(const QString& fileName) { PlaylistItem pi; // just a dummy playFileMain( fileName, 0, pi, false, false ); } void MainDialog::playPlaylistFile(const PlaylistItem& item) { playFileMain( item.fileNameString, item.subtune, item, true, true ); } void MainDialog::playFileMain(const QString& fileName, int song, const PlaylistItem& item, bool putInHistory, bool enablePlaylist) { QFile testFile(fileName); // Who would use '-' for something else than stdin? if ( fileName.isEmpty() || ( fileName!="-" && !testFile.exists() )) return; player->stop(); #ifdef XSID_HAVE_TSID addTSID(); // add time last song has been listened to #endif resetTimeDisplay(); // Make a copy for later use. sidFileNameFull = fileName; createHVSCfileName(fileName); bool loadSucceeded = false; // sidTune::open() does not support standard input. if (fileName == "-") { unsigned char* fileBuf = new unsigned char[SidTuneWrapper::getMaxSidFileLen()]; if (fileBuf == 0) { // If we are out of memory at this point, // it is very unlikely that anything else works. QMessageBox error; error.setIcon(QMessageBox::Critical); error.setText("Out of memory."); error.adjustSize(); error.exec(); return; } unsigned long int fileLen = 0; char datb; while (cin.get(datb) && fileLengetSidTuneWrapper()->load(fileBuf,fileLen); delete[] fileBuf; } else { loadSucceeded = player->getSidTuneWrapper()->open(fileName); } if ( enablePlaylist ) { // Take params from playlist. player->setPlaylistParams( item ); } else { // Not playlist mode. Put in defaults. PlaylistItem pi = player->getCurPlaylistParams(); pi.fadeout = fadeoutDefault; pi.time = playtimeDefault; player->setPlaylistParams(pi); } if ( !loadSucceeded ) { playerButtonsOff(); clearSidTuneInfo(); infoField->setText(player->getSidTuneWrapper()->getStatusString() ); // With too many errors one has to click too much if // message boxes are used here. } else { if ( song == 0 ) song = player->getSidTuneWrapper()->getStartSong(); player->initSong(song); updateSubSongSlider(); showSidTuneInfo(); showStilInfo(); // Add to history if not from there. if ( putInHistory ) { QString tmp = player->getSidTuneWrapper()->getInfoString(0); tmp += " ("; tmp += player->getSidTuneWrapper()->getInfoString(1); tmp += ")"; myHistoryDlg->add(fileName,tmp); } } playlistCheckBox->setChecked(enablePlaylist); if ( player->getSidTuneWrapper()->getStatus() ) { player->start(); if ( player->isPlaying() ) playerButtonsForceStart(); else playerButtonsForceStop(); if ( !player->isReady() ) { QMessageBox error; error.setIcon(QMessageBox::Critical); error.setText( player->getErrorStr() ); error.adjustSize(); error.exec(); } } } // --------------------------------------------------------------------- TSID #ifdef XSID_HAVE_TSID void MainDialog::addTSID() { if ( sidFileNameHVSC.isEmpty() ) return; static int prevTotalSecs = 0; int thisSecs = player->getEmuEngine()->getSecondsTotal() - prevTotalSecs; bool ret = myTSID->addTime( sidFileNameHVSC, thisSecs, player->getSidTuneWrapper()->getCurrentSong() ); #ifdef XSID_WB_DEBUG cout << "TSID: " << sidFileNameHVSC << " / " << thisSecs << " / " << '#' << player->getSidTuneWrapper()->getCurrentSong() << " / return = " << ret << endl; #endif prevTotalSecs = player->getEmuEngine()->getSecondsTotal(); } #endif // --------------------------------------------------------------------- LIRC void MainDialog::lircEvent(int fh) { #ifdef XSID_HAVE_LIRC char *c=0; if(lirc_nextcode(&c) < 0) { qWarning("MainDialog::lircEvent(): error in lirc_nextcode()"); return; } if(c==0) return; char *s=0; if(lirc_code2char(lircConfig, c, &s) < 0) { qWarning("MainDialog::lircEvent(): error in lirc_code2char()"); return; } free(c); if(s==0) return; uint i; QString str=s; if(str=="Play") { emit playSongPressed(); emit playSongReleased(); } else if(str=="Stop") { emit stopSongPressed(); emit stopSongReleased(); } else if(str=="NextSong") { emit nextSongPressed(); emit nextSongReleased(); } else if(str=="PrevSong") { emit prevSongPressed(); emit prevSongReleased(); } else if(str=="Forward") { emit forwardSongPressed(); emit forwardSongReleased(); } else if(str=="Quit") { emit quit(); } else if((i=str.toUInt())) { emit newSubSong(i); } #if 0 emit playerButtonsForceStop(); emit openFile(); emit saveAs(); emit loadPlaylist(); emit savePlaylistAs(); emit saveHotlist(); emit markTune(); emit markPlaylist(); emit openAudioDialog(); emit openEmulatorDialog(); emit openFilterDialog(); emit openHVSC_Dialog(); emit openHistoryDialog(); emit openMixerDialog(); emit openPlaylistDialog(); emit openPlaylistEditDialog(); emit openPlaylistOptions(); emit addTuneToPlaylist(); emit addDirToPlaylist(); emit addTreeToPlaylist(); emit addHotlistToPlaylist(); emit updatePlaylist(); emit toggleStilDialog(); emit toggleSongLengthDB(); emit updateSubSongSlider(); emit setPlaylistEnabled(bool); emit setLoopPlayEnabled(bool); emit setRandomPlayEnabled(bool); #endif #endif // XSID_HAVE_LIRC }