/*************************************************************************** begin : Mon Feb 4 23:40:41 EST 2002 copyright : (C) 2002 - 2004 by Scott Wheeler email : wheeler@kde.org ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #include #include #include #include #include #include #include "juk.h" #include "slideraction.h" #include "statuslabel.h" #include "splashscreen.h" #include "systemtray.h" #include "keydialog.h" #include "tagguesserconfigdlg.h" #include "filerenamerconfigdlg.h" #include "actioncollection.h" #include "cache.h" #include "playlistsplitter.h" #include "collectionlist.h" #include "covermanager.h" #include "tagtransactionmanager.h" using namespace ActionCollection; //////////////////////////////////////////////////////////////////////////////// // public members //////////////////////////////////////////////////////////////////////////////// JuK::JuK(TQWidget *parent, const char *name) : TDEMainWindow(parent, name, WDestructiveClose), m_player(PlayerManager::instance()), m_shuttingDown(false) { // Expect segfaults if you change this order. readSettings(); if(m_showSplash && !m_startDocked && Cache::cacheFileExists()) { SplashScreen::instance()->show(); kapp->processEvents(); } setupActions(); setupLayout(); if(TQApplication::reverseLayout()) setupGUI(ToolBar | Save | Create, "jukui-rtl.rc"); else setupGUI(ToolBar | Save | Create); readConfig(); setupSystemTray(); setupGlobalAccels(); createDirs(); SplashScreen::finishedLoading(); TQTimer::singleShot(0, CollectionList::instance(), TQT_SLOT(slotCheckCache())); TQTimer::singleShot(0, TQT_TQOBJECT(this), TQT_SLOT(slotProcessArgs())); m_sliderAction->slotUpdateOrientation(); } JuK::~JuK() { kdDebug(65432) << k_funcinfo << endl; } TDEActionCollection *JuK::actionCollection() const { return ActionCollection::actions(); } //////////////////////////////////////////////////////////////////////////////// // private members //////////////////////////////////////////////////////////////////////////////// void JuK::setupLayout() { new TagTransactionManager(this); m_splitter = new PlaylistSplitter(this, "playlistSplitter"); setCentralWidget(m_splitter); m_statusLabel = new StatusLabel(m_splitter->playlist(), statusBar()); connect(CollectionList::instance(), TQT_SIGNAL(signalCollectionChanged()), m_statusLabel, TQT_SLOT(updateData())); statusBar()->addWidget(m_statusLabel, 1); PlayerManager::instance()->setStatusLabel(m_statusLabel); m_splitter->setFocus(); resize(750, 500); } void JuK::setupActions() { ActionCollection::actions()->setWidget(this); KStdAction::quit(TQT_TQOBJECT(this), TQT_SLOT(slotQuit()), ActionCollection::actions()); KStdAction::undo(TQT_TQOBJECT(this), TQT_SLOT(slotUndo()), ActionCollection::actions()); KStdAction::cut(TQT_TQOBJECT(kapp), TQT_SLOT(cut()), ActionCollection::actions()); KStdAction::copy(TQT_TQOBJECT(kapp), TQT_SLOT(copy()), ActionCollection::actions()); KStdAction::paste(TQT_TQOBJECT(kapp), TQT_SLOT(paste()), ActionCollection::actions()); KStdAction::clear(TQT_TQOBJECT(kapp), TQT_SLOT(clear()), ActionCollection::actions()); KStdAction::selectAll(TQT_TQOBJECT(kapp), TQT_SLOT(selectAll()), ActionCollection::actions()); new TDEAction(i18n("Remove From Playlist"), "edit_remove", 0, TQT_TQOBJECT(kapp), TQT_SLOT(clear()), ActionCollection::actions(), "removeFromPlaylist"); TDEActionMenu *actionMenu = new TDEActionMenu(i18n("&Random Play"), "roll", ActionCollection::actions(), "actionMenu"); actionMenu->setDelayed(false); TDERadioAction *ka = new TDERadioAction(i18n("&Disable Random Play"), "player_playlist", 0, ActionCollection::actions(), "disableRandomPlay"); ka->setExclusiveGroup("randomPlayGroup"); actionMenu->insert(ka); m_randomPlayAction = new TDERadioAction(i18n("Use &Random Play"), "roll", 0, ActionCollection::actions(), "randomPlay"); m_randomPlayAction->setExclusiveGroup("randomPlayGroup"); actionMenu->insert(m_randomPlayAction); ka = new TDERadioAction(i18n("Use &Album Random Play"), "roll", 0, ActionCollection::actions(), "albumRandomPlay"); ka->setExclusiveGroup("randomPlayGroup"); connect(ka, TQT_SIGNAL(toggled(bool)), TQT_SLOT(slotCheckAlbumNextAction(bool))); actionMenu->insert(ka); new TDEAction(i18n("&Play"), "media-playback-start", 0, TQT_TQOBJECT(m_player), TQT_SLOT(play()), ActionCollection::actions(), "play"); new TDEAction(i18n("P&ause"), "media-playback-pause", 0, TQT_TQOBJECT(m_player), TQT_SLOT(pause()), ActionCollection::actions(), "pause"); new TDEAction(i18n("&Stop"), "media-playback-stop", 0, TQT_TQOBJECT(m_player), TQT_SLOT(stop()), ActionCollection::actions(), "stop"); new TDEToolBarPopupAction(i18n("previous track", "Previous"), "media-skip-backward", TDEShortcut(), TQT_TQOBJECT(m_player), TQT_SLOT(back()), ActionCollection::actions(), "back"); new TDEAction(i18n("next track", "&Next"), "media-skip-forward", TDEShortcut(), TQT_TQOBJECT(m_player), TQT_SLOT(forward()), ActionCollection::actions(), "forward"); new TDEToggleAction(i18n("&Loop Playlist"), 0, TDEShortcut(), ActionCollection::actions(), "loopPlaylist"); TDEToggleAction *resizeColumnAction = new TDEToggleAction(i18n("&Resize Playlist Columns Manually"), TDEShortcut(), ActionCollection::actions(), "resizeColumnsManually"); resizeColumnAction->setCheckedState(i18n("&Resize Column Headers Automatically")); // the following are not visible by default new TDEAction(i18n("Mute"), "mute", 0, TQT_TQOBJECT(m_player), TQT_SLOT(mute()), ActionCollection::actions(), "mute"); new TDEAction(i18n("Volume Up"), "volumeUp", 0, TQT_TQOBJECT(m_player), TQT_SLOT(volumeUp()), ActionCollection::actions(), "volumeUp"); new TDEAction(i18n("Volume Down"), "volumeDown", 0, TQT_TQOBJECT(m_player), TQT_SLOT(volumeDown()), ActionCollection::actions(), "volumeDown"); new TDEAction(i18n("Play / Pause"), "playPause", 0, TQT_TQOBJECT(m_player), TQT_SLOT(playPause()), ActionCollection::actions(), "playPause"); new TDEAction(i18n("Seek Forward"), "seekForward", 0, TQT_TQOBJECT(m_player), TQT_SLOT(seekForward()), ActionCollection::actions(), "seekForward"); new TDEAction(i18n("Seek Back"), "seekBack", 0, TQT_TQOBJECT(m_player), TQT_SLOT(seekBack()), ActionCollection::actions(), "seekBack"); ////////////////////////////////////////////////// // settings menu ////////////////////////////////////////////////// m_toggleSplashAction = new TDEToggleAction(i18n("Show Splash Screen on Startup"), TDEShortcut(), ActionCollection::actions(), "showSplashScreen"); m_toggleSplashAction->setCheckedState(i18n("Hide Splash Screen on Startup")); m_toggleSystemTrayAction = new TDEToggleAction(i18n("&Dock in System Tray"), TDEShortcut(), ActionCollection::actions(), "toggleSystemTray"); m_toggleDockOnCloseAction = new TDEToggleAction(i18n("&Stay in System Tray on Close"), TDEShortcut(), ActionCollection::actions(), "dockOnClose"); m_togglePopupsAction = new TDEToggleAction(i18n("Popup &Track Announcement"), TDEShortcut(), TQT_TQOBJECT(this), 0, ActionCollection::actions(), "togglePopups"); new TDEToggleAction(i18n("Save &Play Queue on Exit"), TDEShortcut(), TQT_TQOBJECT(this), 0, ActionCollection::actions(), "saveUpcomingTracks"); connect(m_toggleSystemTrayAction, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotToggleSystemTray(bool))); m_outputSelectAction = PlayerManager::playerSelectAction(ActionCollection::actions()); if(m_outputSelectAction) m_outputSelectAction->setCurrentItem(0); new TDEAction(i18n("&Tag Guesser..."), 0, 0, TQT_TQOBJECT(this), TQT_SLOT(slotConfigureTagGuesser()), ActionCollection::actions(), "tagGuesserConfig"); new TDEAction(i18n("&File Renamer..."), 0, 0, TQT_TQOBJECT(this), TQT_SLOT(slotConfigureFileRenamer()), ActionCollection::actions(), "fileRenamerConfig"); KStdAction::keyBindings(TQT_TQOBJECT(this), TQT_SLOT(slotEditKeys()), ActionCollection::actions()); ////////////////////////////////////////////////// // just in the toolbar ////////////////////////////////////////////////// m_sliderAction = new SliderAction(i18n("Track Position"), ActionCollection::actions(), "trackPositionAction"); } void JuK::setupSystemTray() { if(m_toggleSystemTrayAction && m_toggleSystemTrayAction->isChecked()) { m_systemTray = new SystemTray(this, "systemTray"); m_systemTray->show(); m_toggleDockOnCloseAction->setEnabled(true); m_togglePopupsAction->setEnabled(true); connect(m_systemTray, TQT_SIGNAL(quitSelected()), TQT_TQOBJECT(this), TQT_SLOT(slotAboutToQuit())); } else { m_systemTray = 0; m_toggleDockOnCloseAction->setEnabled(false); m_togglePopupsAction->setEnabled(false); } } void JuK::setupGlobalAccels() { m_accel = new TDEGlobalAccel(TQT_TQOBJECT(this)); KeyDialog::insert(m_accel, "Play", i18n("Play"), action("play"), TQT_SLOT(activate())); KeyDialog::insert(m_accel, "PlayPause", i18n("Play / Pause"), action("playPause"), TQT_SLOT(activate())); KeyDialog::insert(m_accel, "Stop", i18n("Stop Playing"), action("stop"), TQT_SLOT(activate())); KeyDialog::insert(m_accel, "Back", i18n("Back"), action("back"), TQT_SLOT(activate())); KeyDialog::insert(m_accel, "Forward", i18n("Forward"), action("forward"), TQT_SLOT(activate())); KeyDialog::insert(m_accel, "SeekBack", i18n("Seek Back"), action("seekBack"), TQT_SLOT(activate())); KeyDialog::insert(m_accel, "SeekForward", i18n("Seek Forward"), action("seekForward"), TQT_SLOT(activate())); KeyDialog::insert(m_accel, "VolumeUp", i18n("Volume Up"), action("volumeUp"), TQT_SLOT(activate())); KeyDialog::insert(m_accel, "VolumeDown", i18n("Volume Down"), action("volumeDown"), TQT_SLOT(activate())); KeyDialog::insert(m_accel, "Mute", i18n("Mute"), action("mute"), TQT_SLOT(activate())); KeyDialog::insert(m_accel, "ShowHide", i18n("Show / Hide"), TQT_TQOBJECT(this), TQT_SLOT(slotShowHide())); KeyDialog::insert(m_accel, "ForwardAlbum", i18n("Play Next Album"), action("forwardAlbum"), TQT_SLOT(activate())); m_accel->setConfigGroup("Shortcuts"); m_accel->readSettings(); m_accel->updateConnections(); } void JuK::slotProcessArgs() { TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); TQStringList files; for(int i = 0; i < args->count(); i++) files.append(args->arg(i)); CollectionList::instance()->addFiles(files); } void JuK::createDirs() { TQDir dir(TDEGlobal::dirs()->saveLocation("data", kapp->instanceName() + '/')); if (!dir.exists("covers", false)) dir.mkdir("covers", false); dir.cd("covers"); if (!dir.exists("large", false)) dir.mkdir("large", false); } void JuK::keyPressEvent(TQKeyEvent *e) { if (e->key() >= TQt::Key_Back && e->key() <= TQt::Key_MediaLast) e->accept(); TDEMainWindow::keyPressEvent(e); } /** * These are settings that need to be know before setting up the GUI. */ void JuK::readSettings() { TDEConfigGroup config(TDEGlobal::config(), "Settings"); m_showSplash = config.readBoolEntry("ShowSplashScreen", true); m_startDocked = config.readBoolEntry("StartDocked", false); } void JuK::readConfig() { // player settings TDEConfigGroup playerConfig(TDEGlobal::config(), "Player"); if(m_sliderAction->volumeSlider()) { int maxVolume = m_sliderAction->volumeSlider()->maxValue(); int volume = playerConfig.readNumEntry("Volume", maxVolume); m_sliderAction->volumeSlider()->setVolume(volume); } // Default to no random play ActionCollection::action("disableRandomPlay")->setChecked(true); TQString randomPlayMode = playerConfig.readEntry("RandomPlay", "Disabled"); if(randomPlayMode == "true" || randomPlayMode == "Normal") m_randomPlayAction->setChecked(true); else if(randomPlayMode == "AlbumRandomPlay") ActionCollection::action("albumRandomPlay")->setChecked(true); bool loopPlaylist = playerConfig.readBoolEntry("LoopPlaylist", false); ActionCollection::action("loopPlaylist")->setChecked(loopPlaylist); // general settings TDEConfigGroup settingsConfig(TDEGlobal::config(), "Settings"); bool dockInSystemTray = settingsConfig.readBoolEntry("DockInSystemTray", true); m_toggleSystemTrayAction->setChecked(dockInSystemTray); bool dockOnClose = settingsConfig.readBoolEntry("DockOnClose", true); m_toggleDockOnCloseAction->setChecked(dockOnClose); bool showPopups = settingsConfig.readBoolEntry("TrackPopup", false); m_togglePopupsAction->setChecked(showPopups); if(m_outputSelectAction) m_outputSelectAction->setCurrentItem(settingsConfig.readNumEntry("MediaSystem", 0)); m_toggleSplashAction->setChecked(m_showSplash); } void JuK::saveConfig() { // player settings TDEConfigGroup playerConfig(TDEGlobal::config(), "Player"); if (m_sliderAction->volumeSlider()) { playerConfig.writeEntry("Volume", m_sliderAction->volumeSlider()->volume()); } playerConfig.writeEntry("RandomPlay", m_randomPlayAction->isChecked()); TDEToggleAction *a = ActionCollection::action("loopPlaylist"); playerConfig.writeEntry("LoopPlaylist", a->isChecked()); a = ActionCollection::action("albumRandomPlay"); if(a->isChecked()) playerConfig.writeEntry("RandomPlay", "AlbumRandomPlay"); else if(m_randomPlayAction->isChecked()) playerConfig.writeEntry("RandomPlay", "Normal"); else playerConfig.writeEntry("RandomPlay", "Disabled"); // general settings TDEConfigGroup settingsConfig(TDEGlobal::config(), "Settings"); settingsConfig.writeEntry("ShowSplashScreen", m_toggleSplashAction->isChecked()); settingsConfig.writeEntry("StartDocked", m_startDocked); settingsConfig.writeEntry("DockInSystemTray", m_toggleSystemTrayAction->isChecked()); settingsConfig.writeEntry("DockOnClose", m_toggleDockOnCloseAction->isChecked()); settingsConfig.writeEntry("TrackPopup", m_togglePopupsAction->isChecked()); if(m_outputSelectAction) settingsConfig.writeEntry("MediaSystem", m_outputSelectAction->currentItem()); TDEGlobal::config()->sync(); } bool JuK::queryExit() { m_startDocked = !isVisible(); kdDebug(65432) << k_funcinfo << endl; hide(); action("stop")->activate(); delete m_systemTray; m_systemTray = 0; CoverManager::shutdown(); Cache::instance()->save(); saveConfig(); delete m_splitter; m_splitter = 0; return true; } bool JuK::queryClose() { kdDebug(65432) << k_funcinfo << endl; if(!m_shuttingDown && !kapp->sessionSaving() && m_systemTray && m_toggleDockOnCloseAction->isChecked()) { KMessageBox::information(this, i18n("Closing the main window will keep JuK running in the system tray. " "Use Quit from the File menu to quit the application."), i18n("Docking in System Tray"), "hideOnCloseInfo"); hide(); return false; } else return true; } //////////////////////////////////////////////////////////////////////////////// // private slot definitions //////////////////////////////////////////////////////////////////////////////// void JuK::slotShowHide() { setShown(!isShown()); } void JuK::slotAboutToQuit() { m_shuttingDown = true; } void JuK::slotQuit() { kdDebug(65432) << k_funcinfo << endl; m_shuttingDown = true; kapp->quit(); } //////////////////////////////////////////////////////////////////////////////// // settings menu //////////////////////////////////////////////////////////////////////////////// void JuK::slotToggleSystemTray(bool enabled) { if(enabled && !m_systemTray) setupSystemTray(); else if(!enabled && m_systemTray) { delete m_systemTray; m_systemTray = 0; m_toggleDockOnCloseAction->setEnabled(false); m_togglePopupsAction->setEnabled(false); } } void JuK::slotEditKeys() { KeyDialog::configure(m_accel, ActionCollection::actions(), this); } void JuK::slotConfigureTagGuesser() { TagGuesserConfigDlg(this).exec(); } void JuK::slotConfigureFileRenamer() { FileRenamerConfigDlg(this).exec(); } void JuK::slotUndo() { TagTransactionManager::instance()->undo(); } void JuK::slotCheckAlbumNextAction(bool albumRandomEnabled) { // If album random play is enabled, then enable the Play Next Album action // unless we're not playing right now. if(albumRandomEnabled && !m_player->playing()) albumRandomEnabled = false; action("forwardAlbum")->setEnabled(albumRandomEnabled); } #include "juk.moc"