/* * Cantata * * Copyright (c) 2011-2012 Craig Drummond * */ /* * Copyright (c) 2008 Sander Knopper (sander AT knopper DOT tk) and * Roeland Douma (roeland AT rullzer DOT com) * * This file is part of QtMPC. * * QtMPC 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. * * QtMPC 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 QtMPC. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include #ifdef ENABLE_KDE_SUPPORT #include #include #include #include #include #include #include #include #include #include #include #include #else #include #include "networkproxyfactory.h" #endif #include "localize.h" #include "mainwindow.h" #ifdef PHONON_FOUND #include #endif #include "messagebox.h" #include "inputdialog.h" #include "playlistsmodel.h" #include "covers.h" #include "preferencesdialog.h" #include "mpdconnection.h" #include "mpdstats.h" #include "mpdstatus.h" #include "mpdparseutils.h" #include "settings.h" #include "config.h" #include "utils.h" #include "musiclibrarymodel.h" #include "musiclibraryitemalbum.h" #include "librarypage.h" #include "albumspage.h" #include "folderpage.h" #include "streamspage.h" #include "lyricspage.h" #include "infopage.h" #include "serverinfopage.h" #include "trackorganiser.h" #ifdef ENABLE_DEVICES_SUPPORT #include "devicespage.h" #include "devicesmodel.h" #include "actiondialog.h" #include "syncdialog.h" #endif #ifdef ENABLE_REPLAYGAIN_SUPPORT #include "rgdialog.h" #endif #include "tageditor.h" #include "streamsmodel.h" #include "playlistspage.h" #include "fancytabwidget.h" #include "timeslider.h" #ifndef Q_OS_WIN #include "mpris.h" #include "dockmanager.h" #include "dynamicpage.h" #include "dynamic.h" #include "cantataadaptor.h" #endif #include "messagewidget.h" #include "httpserver.h" #include "groupedview.h" #include "debugtimer.h" #ifdef ENABLE_KDE_SUPPORT #include #define Icon(X) KIcon(X) #define getMediaIcon(X) KIcon(X) #else #include #define Icon(X) QIcon::fromTheme(X) static QIcon getMediaIcon(const char *name) { static QList modes=QList() << QIcon::Normal << QIcon::Disabled << QIcon::Active << QIcon::Selected; QIcon icn; QIcon icon=QIcon::fromTheme(name); foreach (QIcon::Mode mode, modes) { icn.addPixmap(icon.pixmap(QSize(64, 64), mode).scaled(QSize(28, 28), Qt::KeepAspectRatio, Qt::SmoothTransformation), mode); icn.addPixmap(icon.pixmap(QSize(22, 22), mode), mode); } return icn; } #endif static QPixmap createSingleIconPixmap(int size, QColor &col, double opacity) { QPixmap pix(size, size); pix.fill(Qt::transparent); QPainter p(&pix); QFont font(QLatin1String("sans")); font.setBold(false); font.setItalic(false); font.setPixelSize(size*0.9); p.setFont(font); p.setPen(col); p.setOpacity(opacity); p.setRenderHint(QPainter::Antialiasing, true); p.drawText(QRect(0, 1, size, size), QLatin1String("1"), QTextOption(Qt::AlignHCenter|Qt::AlignVCenter)); p.drawText(QRect(1, 1, size, size), QLatin1String("1"), QTextOption(Qt::AlignHCenter|Qt::AlignVCenter)); p.drawText(QRect(-1, 1, size, size), QLatin1String("1"), QTextOption(Qt::AlignHCenter|Qt::AlignVCenter)); p.setRenderHint(QPainter::Antialiasing, false); p.end(); return pix; } static QIcon createSingleIcon() { QIcon icon; QColor col=QColor(Qt::black); icon.addPixmap(createSingleIconPixmap(16, col, 100.0)); icon.addPixmap(createSingleIconPixmap(22, col, 100.0)); icon.addPixmap(createSingleIconPixmap(16, col, 50.0), QIcon::Disabled); icon.addPixmap(createSingleIconPixmap(22, col, 50.0), QIcon::Disabled); col=QColor(48, 48, 48); icon.addPixmap(createSingleIconPixmap(16, col, 100.0), QIcon::Active); icon.addPixmap(createSingleIconPixmap(22, col, 100.0), QIcon::Active); return icon; } enum Tabs { TAB_LIBRARY = 0x01, TAB_FOLDERS = 0x02, TAB_STREAMS = 0x04 }; class ProxyStyle : public QProxyStyle { public: ProxyStyle() : QProxyStyle() { setBaseStyle(qApp->style()); } int styleHint(StyleHint stylehint, const QStyleOption *opt, const QWidget *widget, QStyleHintReturn *returnData) const { if(stylehint==QStyle::SH_Slider_AbsoluteSetButtons){ return Qt::LeftButton|QProxyStyle::styleHint(stylehint, opt, widget ,returnData); }else{ return QProxyStyle::styleHint(stylehint, opt, widget, returnData); } } }; DeleteKeyEventHandler::DeleteKeyEventHandler(QAbstractItemView *v, QAction *a) : QObject(v) , view(v) , act(a) { } bool DeleteKeyEventHandler::eventFilter(QObject *obj, QEvent *event) { if (view->hasFocus() && QEvent::KeyRelease==event->type() && static_cast(event)->matches(QKeySequence::Delete)) { act->trigger(); return true; } return QObject::eventFilter(obj, event); } VolumeSliderEventHandler::VolumeSliderEventHandler(MainWindow *w) : QObject(w) , window(w) { } bool VolumeSliderEventHandler::eventFilter(QObject *obj, QEvent *event) { if (event->type() == QEvent::Wheel) { int numDegrees = static_cast(event)->delta() / 8; int numSteps = numDegrees / 15; if (numSteps > 0) { for (int i = 0; i < numSteps; ++i) window->increaseVolumeAction->trigger(); } else { for (int i = 0; i > numSteps; --i) window->decreaseVolumeAction->trigger(); } return true; } return QObject::eventFilter(obj, event); } VolumeControl::VolumeControl(QWidget *parent) : QMenu(parent) { QFrame *w = new QFrame(this); slider = new QSlider(w); QLabel *increase = new QLabel(QLatin1String("+"), w); QLabel *decrease = new QLabel(QLatin1String("-"), w); increase->setAlignment(Qt::AlignHCenter); decrease->setAlignment(Qt::AlignHCenter); QVBoxLayout *l = new QVBoxLayout(w); l->setMargin(3); l->setSpacing(0); l->addWidget(increase); l->addWidget(slider); l->addWidget(decrease); QHBoxLayout *layout = new QHBoxLayout(this); layout->setMargin(0); layout->addWidget(w); connect(slider, SIGNAL(valueChanged(int)), SIGNAL(valueChanged(int))); slider->setMinimumHeight(192); slider->setMaximumHeight(192); slider->setOrientation(Qt::Vertical); slider->setMinimum(0); slider->setMaximum(100); slider->setPageStep(5); adjustSize(); } VolumeControl::~VolumeControl() { } void VolumeControl::installSliderEventFilter(QObject *filter) { slider->installEventFilter(filter); } void VolumeControl::increaseVolume() { slider->triggerAction(QAbstractSlider::SliderPageStepAdd); } void VolumeControl::decreaseVolume() { slider->triggerAction(QAbstractSlider::SliderPageStepSub); } void VolumeControl::setValue(int v) { slider->setValue(v); } CoverEventHandler::CoverEventHandler(MainWindow *w) : QObject(w), window(w) { } bool CoverEventHandler::eventFilter(QObject *obj, QEvent *event) { switch(event->type()) { case QEvent::MouseButtonPress: if (Qt::LeftButton==static_cast(event)->button()) { pressed=true; } break; case QEvent::MouseButtonRelease: if (pressed && Qt::LeftButton==static_cast(event)->button()) { window->expandInterfaceAction->trigger(); } pressed=false; break; default: break; } return QObject::eventFilter(obj, event); } MainWindow::MainWindow(QWidget *parent) #ifdef ENABLE_KDE_SUPPORT : KXmlGuiWindow(parent) #else : QMainWindow(parent) #endif , loaded(0) , lastState(MPDState_Inactive) , songTime(0) , lastSongId(-1) , autoScrollPlayQueue(true) , draggingPositionSlider(false) , trayItem(0) #ifdef ENABLE_KDE_SUPPORT , notification(0) #endif , lyricsNeedUpdating(false) #ifdef ENABLE_WEBKIT , infoNeedsUpdating(false) #endif #ifndef Q_OS_WIN , dock(0) , mpris(0) #endif , playQueueSearchTimer(0) , usingProxy(false) , connectedState(CS_Init) , volumeFade(0) , origVolume(0) , lastVolume(0) , stopState(StopState_None) #ifdef PHONON_FOUND , phononStreamEnabled(false) , phononStream(0) #endif { #ifndef Q_OS_WIN new CantataAdaptor(this); QDBusConnection::sessionBus().registerObject("/cantata", this); #endif setMinimumHeight(256); QWidget *widget = new QWidget(this); setupUi(widget); setCentralWidget(widget); QMenu *mainMenu=new QMenu(this); messageWidget->hide(); // Need to set these values here, as used in library/device loading... MPDParseUtils::setGroupSingle(Settings::self()->groupSingle()); MPDParseUtils::setGroupMultiple(Settings::self()->groupMultiple()); #ifndef ENABLE_KDE_SUPPORT setWindowIcon(QIcon(":/icons/cantata.svg")); QNetworkProxyFactory::setApplicationProxyFactory(NetworkProxyFactory::Instance()); #endif #ifdef ENABLE_KDE_SUPPORT prefAction=KStandardAction::preferences(this, SLOT(showPreferencesDialog()), actionCollection()); quitAction=KStandardAction::quit(kapp, SLOT(quit()), actionCollection()); smallPlaybackButtonsAction = actionCollection()->addAction("smallplaybackbuttons"); smallPlaybackButtonsAction->setText(i18n("Small Playback Buttons")); smallControlButtonsAction = actionCollection()->addAction("smallcontrolbuttons"); smallControlButtonsAction->setText(i18n("Small Control Buttons")); connectAction = actionCollection()->addAction("connect"); connectAction->setText(i18n("Connect")); connectionsAction = actionCollection()->addAction("connections"); connectionsAction->setText(i18n("Connection")); outputsAction = actionCollection()->addAction("outputs"); outputsAction->setText(i18n("Outputs")); refreshAction = actionCollection()->addAction("refresh"); refreshAction->setText(i18n("Refresh Database")); prevTrackAction = actionCollection()->addAction("prevtrack"); prevTrackAction->setText(i18n("Previous Track")); prevTrackAction->setGlobalShortcut(KShortcut(Qt::META + Qt::Key_Left)); nextTrackAction = actionCollection()->addAction("nexttrack"); nextTrackAction->setText(i18n("Next Track")); nextTrackAction->setGlobalShortcut(KShortcut(Qt::META + Qt::Key_Right)); playPauseTrackAction = actionCollection()->addAction("playpausetrack"); playPauseTrackAction->setText(i18n("Play/Pause")); playPauseTrackAction->setGlobalShortcut(KShortcut(Qt::META + Qt::Key_C)); stopTrackAction = actionCollection()->addAction("stoptrack"); stopTrackAction->setText(i18n("Stop")); stopTrackAction->setGlobalShortcut(KShortcut(Qt::META + Qt::Key_X)); increaseVolumeAction = actionCollection()->addAction("increasevolume"); increaseVolumeAction->setText(i18n("Increase Volume")); increaseVolumeAction->setGlobalShortcut(KShortcut(Qt::META + Qt::Key_Up)); decreaseVolumeAction = actionCollection()->addAction("decreasevolume"); decreaseVolumeAction->setText(i18n("Decrease Volume")); decreaseVolumeAction->setGlobalShortcut(KShortcut(Qt::META + Qt::Key_Down)); addToPlayQueueAction = actionCollection()->addAction("addtoplaylist"); addToPlayQueueAction->setText(i18n("Add To Play Queue")); addToStoredPlaylistAction = actionCollection()->addAction("addtostoredplaylist"); addToStoredPlaylistAction->setText(i18n("Add To Playlist")); #ifdef ENABLE_DEVICES_SUPPORT copyToDeviceAction = actionCollection()->addAction("copytodevice"); copyToDeviceAction->setText(i18n("Copy To Device")); copyToDeviceAction->setIcon(Icon("multimedia-player")); deleteSongsAction = actionCollection()->addAction("deletesongs"); #endif organiseFilesAction = actionCollection()->addAction("organizefiles"); #ifdef ENABLE_REPLAYGAIN_SUPPORT replaygainAction = actionCollection()->addAction("replaygain"); #endif removeAction = actionCollection()->addAction("removeitems"); removeAction->setText(i18n("Remove")); replacePlayQueueAction = actionCollection()->addAction("replaceplaylist"); replacePlayQueueAction->setText(i18n("Replace Play Queue")); removeFromPlayQueueAction = actionCollection()->addAction("removefromplaylist"); removeFromPlayQueueAction->setText(i18n("Remove From Play Queue")); copyTrackInfoAction = actionCollection()->addAction("copytrackinfo"); copyTrackInfoAction->setText(i18n("Copy Track Info")); copyTrackInfoAction->setShortcut(QKeySequence::Copy); cropPlayQueueAction = actionCollection()->addAction("cropplaylist"); cropPlayQueueAction->setText(i18n("Crop")); shufflePlayQueueAction = actionCollection()->addAction("shuffleplaylist"); shufflePlayQueueAction->setText(i18n("Shuffle")); savePlayQueueAction = actionCollection()->addAction("saveplaylist"); savePlayQueueAction->setText(i18n("Save As")); clearPlayQueueAction = actionCollection()->addAction("clearplaylist"); clearPlayQueueAction->setText(i18n("Clear")); expandInterfaceAction = actionCollection()->addAction("expandinterface"); expandInterfaceAction->setText(i18n("Expanded Interface")); randomPlayQueueAction = actionCollection()->addAction("randomplaylist"); randomPlayQueueAction->setText(i18n("Random")); repeatPlayQueueAction = actionCollection()->addAction("repeatplaylist"); repeatPlayQueueAction->setText(i18n("Repeat")); singlePlayQueueAction = actionCollection()->addAction("singleplaylist"); singlePlayQueueAction->setText(i18n("Single")); singlePlayQueueAction->setWhatsThis(i18n("When 'Single' is activated, playback is stopped after current song, or song is repeated if 'Repeat' is enabled.")); consumePlayQueueAction = actionCollection()->addAction("consumeplaylist"); consumePlayQueueAction->setText(i18n("Consume")); consumePlayQueueAction->setWhatsThis(i18n("When consume is activated, a song is removed from the play queue after it has been played.")); #ifdef PHONON_FOUND streamPlayAction = actionCollection()->addAction("streamplay"); streamPlayAction->setText(i18n("Play Stream")); streamPlayAction->setWhatsThis(i18n("When 'Play Stream' is activated, the enabled stream is played locally.")); #endif locateTrackAction = actionCollection()->addAction("locatetrack"); locateTrackAction->setText(i18n("Locate In Library")); // burnAction = actionCollection()->addAction("burn"); // burnAction->setText(i18n("Burn To CD/DVD")); // // createAudioCdAction = actionCollection()->addAction("createaudiocd"); // createAudioCdAction->setText(i18n("Create Audio CD")); // // createDataCdAction = actionCollection()->addAction("createdatacd"); // createDataCdAction->setText(i18n("Create Data CD/DVD")); editTagsAction = actionCollection()->addAction("edittags"); editTagsAction->setText(i18n("Edit Tags")); editPlayQueueTagsAction = actionCollection()->addAction("editpqtags"); editPlayQueueTagsAction->setText(i18n("Edit Song Tags")); libraryTabAction = actionCollection()->addAction("showlibrarytab"); libraryTabAction->setText(i18n("Library")); albumsTabAction = actionCollection()->addAction("showalbumstab"); albumsTabAction->setText(i18n("Albums")); foldersTabAction = actionCollection()->addAction("showfolderstab"); foldersTabAction->setText(i18n("Folders")); playlistsTabAction = actionCollection()->addAction("showplayliststab"); playlistsTabAction->setText(i18n("Playlists")); #ifndef Q_OS_WIN dynamicTabAction = actionCollection()->addAction("showdynamictab"); dynamicTabAction->setText(i18n("Dynamic")); #endif lyricsTabAction = actionCollection()->addAction("showlyricstab"); lyricsTabAction->setText(i18n("Lyrics")); streamsTabAction = actionCollection()->addAction("showstreamstab"); streamsTabAction->setText(i18n("Streams")); #ifdef ENABLE_WEBKIT infoTabAction = actionCollection()->addAction("showinfotab"); infoTabAction->setText(i18n("Info")); #endif // ENABLE_WEBKIT serverInfoTabAction = actionCollection()->addAction("showserverinfotab"); serverInfoTabAction->setText(i18n("Server Info")); #ifdef ENABLE_DEVICES_SUPPORT devicesTabAction = actionCollection()->addAction("showdevicestab"); devicesTabAction->setText(i18n("Devices")); #endif // ENABLE_DEVICES_SUPPORT searchAction = actionCollection()->addAction("search"); searchAction->setText(i18n("Search")); expandAllAction = actionCollection()->addAction("expandall"); expandAllAction->setText(i18n("Expand All")); collapseAllAction = actionCollection()->addAction("collapseall"); collapseAllAction->setText(i18n("Collapse All")); #else quitAction = new QAction(tr("&Quit"), this); connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); quitAction->setIcon(Icon("application-exit")); quitAction->setShortcut(QKeySequence::Quit); smallPlaybackButtonsAction = new QAction(tr("Small Playback Buttons"), this); smallControlButtonsAction = new QAction(tr("Small Control Buttons"), this); refreshAction = new QAction(tr("Refresh"), this); connectAction = new QAction(tr("Connect"), this); connectionsAction = new QAction(tr("Connections"), this); outputsAction = new QAction(tr("Outputs"), this); prevTrackAction = new QAction(tr("Previous Track"), this); nextTrackAction = new QAction(tr("Next Track"), this); playPauseTrackAction = new QAction(tr("Play/Pause"), this); stopTrackAction = new QAction(tr("Stop"), this); increaseVolumeAction = new QAction(tr("Increase Volume"), this); decreaseVolumeAction = new QAction(tr("Decrease Volume"), this); addToPlayQueueAction = new QAction(tr("Add To Play Queue"), this); addToStoredPlaylistAction = new QAction(tr("Add To Playlist"), this); organiseFilesAction = new QAction(this); #ifdef ENABLE_REPLAYGAIN_SUPPORT replaygainAction = new QAction(this); #endif removeAction = new QAction(tr("Remove"), this); replacePlayQueueAction = new QAction(tr("Replace Play Queue"), this); removeFromPlayQueueAction = new QAction(tr("Remove From Play Queue"), this); copyTrackInfoAction = new QAction(tr("Copy Track Info"), this); copyTrackInfoAction->setShortcut(QKeySequence::Copy); cropPlayQueueAction = new QAction(tr("Crop"), this); shufflePlayQueueAction = new QAction(tr("Shuffle"), this); savePlayQueueAction = new QAction(tr("Save As"), this); clearPlayQueueAction = new QAction(tr("Clear"), this); expandInterfaceAction = new QAction(tr("Expanded Interface"), this); randomPlayQueueAction = new QAction(tr("Random"), this); repeatPlayQueueAction = new QAction(tr("Repeat"), this); singlePlayQueueAction = new QAction(tr("Single"), this); singlePlayQueueAction->setWhatsThis(tr("When single is activated, playback is stopped after current song, or song is repeated if the 'repeat' mode is enabled.")); consumePlayQueueAction = new QAction(tr("Consume"), this); consumePlayQueueAction->setWhatsThis(tr("When consume is activated, a song is removed from the play queue after it has been played.")); #ifdef PHONON_FOUND streamPlayAction= new QAction(tr("Play Stream"), this); streamPlayAction->setWhatsThis(tr("When 'Play Stream' is activated, the enabled stream is played locally.")); #endif locateTrackAction = new QAction(tr("Locate In Library"), this); // burnAction = new QAction(tr("Burn To CD/DVD"), this); // createAudioCdAction = new QAction(tr("Create Audio CD"), this); // createDataCdAction = new QAction(tr("Create Data CD"), this); editTagsAction = new QAction(tr("Edit Tags"), this); editPlayQueueTagsAction = new QAction(tr("Edit Song Tags"), this); searchAction = new QAction(tr("Search"), this); expandAllAction = new QAction(tr("Expand All"), this); collapseAllAction = new QAction(tr("Collapse All"), this); libraryTabAction = new QAction(tr("Library"), this); albumsTabAction = new QAction(tr("Albums"), this); foldersTabAction = new QAction(tr("Folders"), this); playlistsTabAction = new QAction(tr("Playlists"), this); #ifndef Q_OS_WIN dynamicTabAction = new QAction(tr("Dynamic"), this); #endif lyricsTabAction = new QAction(tr("Lyrics"), this); streamsTabAction = new QAction(tr("Streams"), this); #ifdef ENABLE_WEBKIT infoTabAction = new QAction(tr("Info"), this); #endif // ENABLE_WEBKIT serverInfoTabAction = new QAction(tr("Server Info"), this); #endif // ENABLE_KDE_SUPPORT int pageKey=Qt::Key_1; libraryTabAction->setShortcut(Qt::AltModifier+(pageKey++)); albumsTabAction->setShortcut(Qt::AltModifier+(pageKey++)); foldersTabAction->setShortcut(Qt::AltModifier+(pageKey++)); playlistsTabAction->setShortcut(Qt::AltModifier+(pageKey++)); #ifndef Q_OS_WIN dynamicTabAction->setShortcut(Qt::AltModifier+(pageKey++)); #endif streamsTabAction->setShortcut(Qt::AltModifier+(pageKey++)); lyricsTabAction->setShortcut(Qt::AltModifier+(pageKey++)); #ifdef ENABLE_WEBKIT infoTabAction->setShortcut(Qt::AltModifier+(pageKey++)); #endif // ENABLE_WEBKIT serverInfoTabAction->setShortcut(Qt::AltModifier+(pageKey++)); #ifdef ENABLE_DEVICES_SUPPORT devicesTabAction->setShortcut(Qt::AltModifier+(pageKey++)); #endif // ENABLE_DEVICES_SUPPORT searchAction->setShortcut(Qt::ControlModifier+Qt::Key_F); expandAllAction->setShortcut(Qt::ControlModifier+Qt::Key_Plus); collapseAllAction->setShortcut(Qt::ControlModifier+Qt::Key_Minus); // Setup event handler for volume adjustment volumeSliderEventHandler = new VolumeSliderEventHandler(this); volumeControl = new VolumeControl(volumeButton); volumeControl->installSliderEventFilter(volumeSliderEventHandler); volumeButton->installEventFilter(volumeSliderEventHandler); positionSlider->setStyle(new ProxyStyle()); playbackPlay = getMediaIcon("media-playback-start"); playbackPause = getMediaIcon("media-playback-pause"); randomPlayQueueAction->setIcon(Icon("media-playlist-shuffle")); locateTrackAction->setIcon(Icon("edit-find")); #ifdef ENABLE_KDE_SUPPORT consumePlayQueueAction->setIcon(Icon("cantata-view-media-consume")); repeatPlayQueueAction->setIcon(Icon("cantata-view-media-repeat")); // randomPlayQueueAction->setIcon(Icon("cantata-view-media-shuffle")); // shufflePlayQueueAction->setIcon(Icon("cantata-view-media-shuffle")); #else QIcon consumeIcon(":consume16.png"); consumeIcon.addFile(":consume22.png"); QIcon repeatIcon(":repeat16.png"); repeatIcon.addFile(":repeat22.png"); // QIcon shuffleIcon(":shuffle16.png"); // repeatIcon.addFile(":shuffle22.png"); consumePlayQueueAction->setIcon(consumeIcon); repeatPlayQueueAction->setIcon(repeatIcon); // randomPlayQueueAction->setIcon(shuffleIcon); // shufflePlayQueueAction->setIcon(shuffleIcon); #endif singlePlayQueueAction->setIcon(createSingleIcon()); #ifdef PHONON_FOUND streamPlayAction->setIcon(Icon(DEFAULT_STREAM_ICON)); #endif removeAction->setIcon(Icon("list-remove")); addToPlayQueueAction->setIcon(Icon("list-add")); replacePlayQueueAction->setIcon(Icon("media-playback-start")); // burnAction->setIcon(Icon("tools-media-optical-burn")); // createDataCdAction->setIcon(Icon("media-optical")); // createAudioCdAction->setIcon(Icon(DEFAULT_ALBUM_ICON)); editTagsAction->setIcon(Icon("document-edit")); editPlayQueueTagsAction->setIcon(Icon("document-edit")); // QMenu *cdMenu=new QMenu(this); // cdMenu->addAction(createAudioCdAction); // cdMenu->addAction(createDataCdAction); // burnAction->setMenu(cdMenu); // #ifdef ENABLE_KDE_SUPPORT // if (KStandardDirs::findExe("k3b").isEmpty()) { // burnAction->setVisible(false); // } // #endif prevTrackAction->setIcon(getMediaIcon("media-skip-backward")); nextTrackAction->setIcon(getMediaIcon("media-skip-forward")); playPauseTrackAction->setIcon(playbackPlay); stopTrackAction->setIcon(getMediaIcon("media-playback-stop")); removeFromPlayQueueAction->setIcon(Icon("list-remove")); clearPlayQueueAction->setIcon(Icon("edit-clear-list")); savePlayQueueAction->setIcon(Icon("document-save-as")); expandInterfaceAction->setIcon(Icon("view-media-playlist")); refreshAction->setIcon(Icon("view-refresh")); connectAction->setIcon(Icon("network-connect")); connectionsAction->setIcon(Icon("network-server")); outputsAction->setIcon(Icon("speaker")); connectionsAction->setMenu(new QMenu(this)); connectionsGroup=new QActionGroup(connectionsAction->menu()); outputsAction->setMenu(new QMenu(this)); outputsAction->setVisible(false); #ifdef ENABLE_KDE_SUPPORT libraryTabAction->setIcon(Icon("cantata-view-media-library")); #else QIcon libraryIcon(":lib16.png"); libraryIcon.addFile(":lib32.png"); libraryTabAction->setIcon(libraryIcon); #endif albumsTabAction->setIcon(Icon(DEFAULT_ALBUM_ICON)); foldersTabAction->setIcon(Icon("inode-directory")); playlistsTabAction->setIcon(Icon("view-media-playlist")); #ifndef Q_OS_WIN dynamicTabAction->setIcon(Icon("media-playlist-shuffle")); #endif lyricsTabAction->setIcon(Icon("view-media-lyrics")); streamsTabAction->setIcon(Icon(DEFAULT_STREAM_ICON)); #ifdef ENABLE_WEBKIT #ifdef ENABLE_KDE_SUPPORT infoTabAction->setIcon(Icon("cantata-view-wikipedia")); #else // ENABLE_KDE_SUPPORT QIcon wikiIcon(":wiki16.png"); wikiIcon.addFile(":wiki32.png"); infoTabAction->setIcon(wikiIcon); #endif // ENABLE_KDE_SUPPORT #endif serverInfoTabAction->setIcon(Icon("server-database")); #ifdef ENABLE_DEVICES_SUPPORT devicesTabAction->setIcon(Icon("multimedia-player")); copyToDeviceAction->setMenu(DevicesModel::self()->menu()); deleteSongsAction->setIcon(Icon("edit-delete")); deleteSongsAction->setText(i18n("Delete Songs")); #endif organiseFilesAction->setIcon(Icon("inode-directory")); organiseFilesAction->setText(i18n("Organize Files")); searchAction->setIcon(Icon("edit-find")); #ifdef ENABLE_REPLAYGAIN_SUPPORT replaygainAction->setIcon(Icon("audio-x-generic")); replaygainAction->setText(i18n("ReplayGain")); #endif addToStoredPlaylistAction->setMenu(PlaylistsModel::self()->menu()); addToStoredPlaylistAction->setIcon(playlistsTabAction->icon()); menuButton->setIcon(Icon("configure")); volumeButton->setIcon(Icon("audio-volume-high")); menuButton->setMenu(mainMenu); menuButton->setPopupMode(QToolButton::InstantPopup); playPauseTrackButton->setDefaultAction(playPauseTrackAction); stopTrackButton->setDefaultAction(stopTrackAction); nextTrackButton->setDefaultAction(nextTrackAction); prevTrackButton->setDefaultAction(prevTrackAction); libraryPage = new LibraryPage(this); albumsPage = new AlbumsPage(this); folderPage = new FolderPage(this); playlistsPage = new PlaylistsPage(this); #ifndef Q_OS_WIN dynamicPage = new DynamicPage(this); #endif streamsPage = new StreamsPage(this); lyricsPage = new LyricsPage(this); #ifdef ENABLE_WEBKIT infoPage = new InfoPage(this); #endif serverInfoPage = new ServerInfoPage(this); #ifdef ENABLE_DEVICES_SUPPORT devicesPage = new DevicesPage(this); #endif connect(MusicLibraryModel::self(), SIGNAL(updateGenres(const QSet &)), albumsPage, SLOT(updateGenres(const QSet &))); setVisible(true); savePlayQueuePushButton->setDefaultAction(savePlayQueueAction); removeAllFromPlayQueuePushButton->setDefaultAction(clearPlayQueueAction); randomPushButton->setDefaultAction(randomPlayQueueAction); repeatPushButton->setDefaultAction(repeatPlayQueueAction); singlePushButton->setDefaultAction(singlePlayQueueAction); consumePushButton->setDefaultAction(consumePlayQueueAction); #ifdef PHONON_FOUND streamButton->setDefaultAction(streamPlayAction); #else streamButton->setVisible(false); #endif QStringList hiddenPages=Settings::self()->hiddenPages(); tabWidget->AddTab(libraryPage, libraryTabAction->icon(), libraryTabAction->text(), !hiddenPages.contains(libraryPage->metaObject()->className())); tabWidget->AddTab(albumsPage, albumsTabAction->icon(), albumsTabAction->text(), !hiddenPages.contains(albumsPage->metaObject()->className())); tabWidget->AddTab(folderPage, foldersTabAction->icon(), foldersTabAction->text(), !hiddenPages.contains(folderPage->metaObject()->className())); tabWidget->AddTab(playlistsPage, playlistsTabAction->icon(), playlistsTabAction->text(), !hiddenPages.contains(playlistsPage->metaObject()->className())); #ifndef Q_OS_WIN tabWidget->AddTab(dynamicPage, dynamicTabAction->icon(), dynamicTabAction->text(), !hiddenPages.contains(dynamicPage->metaObject()->className())); #endif tabWidget->AddTab(streamsPage, streamsTabAction->icon(), streamsTabAction->text(), !hiddenPages.contains(streamsPage->metaObject()->className())); tabWidget->AddTab(lyricsPage, lyricsTabAction->icon(), lyricsTabAction->text(), !hiddenPages.contains(lyricsPage->metaObject()->className())); #ifdef ENABLE_WEBKIT tabWidget->AddTab(infoPage, infoTabAction->icon(), infoTabAction->text(), !hiddenPages.contains(infoPage->metaObject()->className())); #endif tabWidget->AddTab(serverInfoPage, serverInfoTabAction->icon(), serverInfoTabAction->text(), !hiddenPages.contains(serverInfoPage->metaObject()->className())); #ifdef ENABLE_DEVICES_SUPPORT tabWidget->AddTab(devicesPage, devicesTabAction->icon(), devicesTabAction->text(), !hiddenPages.contains(devicesPage->metaObject()->className())); DevicesModel::self()->setEnabled(!hiddenPages.contains(devicesPage->metaObject()->className())); copyToDeviceAction->setVisible(DevicesModel::self()->isEnabled()); #endif AlbumsModel::self()->setEnabled(!hiddenPages.contains(albumsPage->metaObject()->className())); folderPage->setEnabled(!hiddenPages.contains(folderPage->metaObject()->className())); streamsPage->setEnabled(!hiddenPages.contains(streamsPage->metaObject()->className())); tabWidget->SetMode(FancyTabWidget::Mode_LargeSidebar); expandInterfaceAction->setCheckable(true); randomPlayQueueAction->setCheckable(true); repeatPlayQueueAction->setCheckable(true); singlePlayQueueAction->setCheckable(true); consumePlayQueueAction->setCheckable(true); #ifdef PHONON_FOUND streamPlayAction->setCheckable(true); #endif searchPlayQueueLineEdit->setPlaceholderText(i18n("Search Play Queue...")); QList playbackBtns; QList controlBtns; QList btns; playbackBtns << prevTrackButton << stopTrackButton << playPauseTrackButton << nextTrackButton; controlBtns << volumeButton << menuButton << streamButton; btns << repeatPushButton << singlePushButton << randomPushButton << savePlayQueuePushButton << removeAllFromPlayQueuePushButton << consumePushButton; foreach (QToolButton *b, btns) { initButton(b); } smallControlButtonsAction->setCheckable(true); smallControlButtonsAction->setChecked(Settings::self()->smallControlButtons()); controlBtnsMenu = new QMenu(this); controlBtnsMenu->addAction(smallControlButtonsAction); connect(smallControlButtonsAction, SIGNAL(triggered(bool)), SLOT(setControlButtonsSize(bool))); foreach (QToolButton *b, controlBtns) { b->setAutoRaise(true); b->setContextMenuPolicy(Qt::CustomContextMenu); connect(b, SIGNAL(customContextMenuRequested(const QPoint &)), SLOT(controlButtonsMenu())); } smallPlaybackButtonsAction->setCheckable(true); smallPlaybackButtonsAction->setChecked(Settings::self()->smallPlaybackButtons()); playbackBtnsMenu = new QMenu(this); playbackBtnsMenu->addAction(smallPlaybackButtonsAction); connect(smallPlaybackButtonsAction, SIGNAL(triggered(bool)), SLOT(setPlaybackButtonsSize(bool))); foreach (QToolButton *b, playbackBtns) { b->setAutoRaise(true); b->setContextMenuPolicy(Qt::CustomContextMenu); connect(b, SIGNAL(customContextMenuRequested(const QPoint &)), SLOT(playbackButtonsMenu())); } setPlaybackButtonsSize(Settings::self()->smallPlaybackButtons()); setControlButtonsSize(Settings::self()->smallControlButtons()); trackLabel->setText(QString()); artistLabel->setText(QString()); expandInterfaceAction->setChecked(Settings::self()->showPlaylist()); randomPlayQueueAction->setChecked(false); repeatPlayQueueAction->setChecked(false); singlePlayQueueAction->setChecked(false); consumePlayQueueAction->setChecked(false); #ifdef PHONON_FOUND streamPlayAction->setChecked(false); #endif MusicLibraryItemAlbum::setCoverSize((MusicLibraryItemAlbum::CoverSize)Settings::self()->libraryCoverSize()); MusicLibraryItemAlbum::setShowDate(Settings::self()->libraryYear()); AlbumsModel::setCoverSize((MusicLibraryItemAlbum::CoverSize)Settings::self()->albumsCoverSize()); tabWidget->SetMode((FancyTabWidget::Mode)Settings::self()->sidebar()); setupTrayIcon(); expandedSize=Settings::self()->mainWindowSize(); collapsedSize=Settings::self()->mainWindowCollapsedSize(); if (!expandedSize.isEmpty()) { resize(expandedSize); } togglePlayQueue(); if (expandInterfaceAction->isChecked()) { if (!expandedSize.isEmpty()) { resize(expandedSize); } } else { if (!collapsedSize.isEmpty()) { resize(collapsedSize); } } #ifdef ENABLE_KDE_SUPPORT setupGUI(KXmlGuiWindow::Keys | KXmlGuiWindow::Save | KXmlGuiWindow::Create); menuBar()->setVisible(false); #endif mainMenu->addAction(expandInterfaceAction); mainMenu->addAction(connectionsAction); mainMenu->addAction(outputsAction); QAction *menuAct=mainMenu->addAction(tr("Configure Cantata..."), this, SLOT(showPreferencesDialog())); menuAct->setIcon(Icon("configure")); #ifdef ENABLE_KDE_SUPPORT mainMenu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::KeyBindings))); mainMenu->addSeparator(); mainMenu->addMenu(helpMenu()); #else prefAction=menuAct; mainMenu->addSeparator(); // QMenu *menu=new QMenu(tr("Help"), this); // QAction *menuAct=menu->addAction(tr("About Cantata..."), this, SLOT(showAboutDialog())); menuAct=mainMenu->addAction(tr("About Cantata..."), this, SLOT(showAboutDialog())); menuAct->setIcon(windowIcon()); // mainMenu->addMenu(menu); #endif mainMenu->addSeparator(); mainMenu->addAction(quitAction); coverWidget->installEventFilter(new CoverEventHandler(this)); dynamicLabel->setVisible(false); connect(MPDConnection::self(), SIGNAL(playlistLoaded(const QString &)), SLOT(songLoaded())); connect(MPDConnection::self(), SIGNAL(added(const QStringList &)), SLOT(songLoaded())); connect(MPDConnection::self(), SIGNAL(outputsUpdated(const QList &)), this, SLOT(outputsUpdated(const QList &))); connect(this, SIGNAL(enableOutput(int, bool)), MPDConnection::self(), SLOT(enableOutput(int, bool))); connect(this, SIGNAL(outputs()), MPDConnection::self(), SLOT(outputs())); connect(this, SIGNAL(removeSongs(const QList &)), MPDConnection::self(), SLOT(removeSongs(const QList &))); connect(this, SIGNAL(pause(bool)), MPDConnection::self(), SLOT(setPause(bool))); connect(this, SIGNAL(play()), MPDConnection::self(), SLOT(startPlayingSong())); connect(this, SIGNAL(stop()), MPDConnection::self(), SLOT(stopPlaying())); connect(this, SIGNAL(getStatus()), MPDConnection::self(), SLOT(getStatus())); connect(this, SIGNAL(getStats()), MPDConnection::self(), SLOT(getStats())); connect(this, SIGNAL(clear()), MPDConnection::self(), SLOT(clear())); connect(this, SIGNAL(playListInfo()), MPDConnection::self(), SLOT(playListInfo())); connect(this, SIGNAL(currentSong()), MPDConnection::self(), SLOT(currentSong())); connect(this, SIGNAL(setSeekId(quint32, quint32)), MPDConnection::self(), SLOT(setSeekId(quint32, quint32))); connect(this, SIGNAL(startPlayingSongId(quint32)), MPDConnection::self(), SLOT(startPlayingSongId(quint32))); connect(this, SIGNAL(setDetails(const MPDConnectionDetails &)), MPDConnection::self(), SLOT(setDetails(const MPDConnectionDetails &))); connect(&playQueueModel, SIGNAL(statsUpdated(int, int, int, quint32)), this, SLOT(updatePlayQueueStats(int, int, int, quint32))); playQueueProxyModel.setSourceModel(&playQueueModel); playQueue->setModel(&playQueueModel); playQueue->addAction(removeFromPlayQueueAction); playQueue->addAction(clearPlayQueueAction); playQueue->addAction(savePlayQueueAction); playQueue->addAction(cropPlayQueueAction); playQueue->addAction(shufflePlayQueueAction); Action *sep=new Action(this); sep->setSeparator(true); playQueue->addAction(sep); playQueue->addAction(locateTrackAction); playQueue->addAction(editPlayQueueTagsAction); //playQueue->addAction(copyTrackInfoAction); playQueue->tree()->installEventFilter(new DeleteKeyEventHandler(playQueue->tree(), removeFromPlayQueueAction)); playQueue->list()->installEventFilter(new DeleteKeyEventHandler(playQueue->list(), removeFromPlayQueueAction)); connect(playQueue, SIGNAL(itemsSelected(bool)), SLOT(playQueueItemsSelected(bool))); connect(streamsPage, SIGNAL(add(const QStringList &, bool)), &playQueueModel, SLOT(addItems(const QStringList &, bool))); playQueueModel.setGrouped(Settings::self()->playQueueGrouped()); playQueue->setGrouped(Settings::self()->playQueueGrouped()); playQueue->setAutoExpand(Settings::self()->playQueueAutoExpand()); playQueue->setStartClosed(Settings::self()->playQueueStartClosed()); playlistsPage->setStartClosed(Settings::self()->playListsStartClosed()); connect(MPDConnection::self(), SIGNAL(statsUpdated(const MPDStats &)), this, SLOT(updateStats())); connect(MPDStatus::self(), SIGNAL(updated()), this, SLOT(updateStatus())); connect(MPDConnection::self(), SIGNAL(playlistUpdated(const QList &)), this, SLOT(updatePlayQueue(const QList &))); connect(MPDConnection::self(), SIGNAL(currentSongUpdated(const Song &)), this, SLOT(updateCurrentSong(const Song &))); connect(MPDConnection::self(), SIGNAL(storedPlayListUpdated()), MPDConnection::self(), SLOT(listPlaylists())); connect(MPDConnection::self(), SIGNAL(stateChanged(bool)), SLOT(mpdConnectionStateChanged(bool))); connect(MPDConnection::self(), SIGNAL(error(const QString &, bool)), SLOT(showError(const QString &, bool))); connect(MPDConnection::self(), SIGNAL(dirChanged()), SLOT(checkMpdDir())); #ifndef Q_OS_WIN connect(Dynamic::self(), SIGNAL(error(const QString &)), SLOT(showError(const QString &))); connect(Dynamic::self(), SIGNAL(running(bool)), dynamicLabel, SLOT(setVisible(bool))); #endif connect(refreshAction, SIGNAL(triggered(bool)), this, SLOT(refresh())); connect(refreshAction, SIGNAL(triggered(bool)), MPDConnection::self(), SLOT(update())); connect(connectAction, SIGNAL(triggered(bool)), this, SLOT(connectToMpd())); connect(prevTrackAction, SIGNAL(triggered(bool)), MPDConnection::self(), SLOT(goToPrevious())); connect(nextTrackAction, SIGNAL(triggered(bool)), MPDConnection::self(), SLOT(goToNext())); connect(playPauseTrackAction, SIGNAL(triggered(bool)), this, SLOT(playPauseTrack())); connect(stopTrackAction, SIGNAL(triggered(bool)), this, SLOT(stopTrack())); connect(volumeControl, SIGNAL(valueChanged(int)), MPDConnection::self(), SLOT(setVolume(int))); connect(this, SIGNAL(setVolume(int)), MPDConnection::self(), SLOT(setVolume(int))); connect(increaseVolumeAction, SIGNAL(triggered(bool)), this, SLOT(increaseVolume())); connect(decreaseVolumeAction, SIGNAL(triggered(bool)), this, SLOT(decreaseVolume())); connect(increaseVolumeAction, SIGNAL(triggered(bool)), volumeControl, SLOT(increaseVolume())); connect(decreaseVolumeAction, SIGNAL(triggered(bool)), volumeControl, SLOT(decreaseVolume())); connect(positionSlider, SIGNAL(sliderPressed()), this, SLOT(positionSliderPressed())); connect(positionSlider, SIGNAL(sliderReleased()), this, SLOT(setPosition())); connect(positionSlider, SIGNAL(sliderReleased()), this, SLOT(positionSliderReleased())); connect(randomPlayQueueAction, SIGNAL(triggered(bool)), MPDConnection::self(), SLOT(setRandom(bool))); connect(repeatPlayQueueAction, SIGNAL(triggered(bool)), MPDConnection::self(), SLOT(setRepeat(bool))); connect(singlePlayQueueAction, SIGNAL(triggered(bool)), MPDConnection::self(), SLOT(setSingle(bool))); connect(consumePlayQueueAction, SIGNAL(triggered(bool)), MPDConnection::self(), SLOT(setConsume(bool))); #ifdef PHONON_FOUND connect(streamPlayAction, SIGNAL(triggered(bool)), this, SLOT(toggleStream(bool))); #endif connect(searchPlayQueueLineEdit, SIGNAL(returnPressed()), this, SLOT(searchPlayQueue())); connect(searchPlayQueueLineEdit, SIGNAL(textChanged(const QString)), this, SLOT(searchPlayQueue())); connect(playQueue, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(playQueueItemActivated(const QModelIndex &))); connect(removeAction, SIGNAL(activated()), this, SLOT(removeItems())); connect(addToPlayQueueAction, SIGNAL(activated()), this, SLOT(addToPlayQueue())); connect(replacePlayQueueAction, SIGNAL(activated()), this, SLOT(replacePlayQueue())); connect(removeFromPlayQueueAction, SIGNAL(activated()), this, SLOT(removeFromPlayQueue())); connect(clearPlayQueueAction, SIGNAL(activated()), searchPlayQueueLineEdit, SLOT(clear())); connect(clearPlayQueueAction, SIGNAL(activated()), MPDConnection::self(), SLOT(clear())); connect(copyTrackInfoAction, SIGNAL(activated()), this, SLOT(copyTrackInfo())); connect(cropPlayQueueAction, SIGNAL(activated()), this, SLOT(cropPlayQueue())); connect(shufflePlayQueueAction, SIGNAL(activated()), MPDConnection::self(), SLOT(shuffle())); connect(expandInterfaceAction, SIGNAL(activated()), this, SLOT(togglePlayQueue())); connect(positionSlider, SIGNAL(valueChanged(int)), this, SLOT(updatePosition())); connect(volumeButton, SIGNAL(clicked()), SLOT(showVolumeControl())); // connect(createDataCdAction, SIGNAL(activated()), this, SLOT(createDataCd())); // connect(createAudioCdAction, SIGNAL(activated()), this, SLOT(createAudioCd())); connect(editTagsAction, SIGNAL(activated()), this, SLOT(editTags())); connect(editPlayQueueTagsAction, SIGNAL(activated()), this, SLOT(editPlayQueueTags())); connect(locateTrackAction, SIGNAL(activated()), this, SLOT(locateTrack())); connect(libraryTabAction, SIGNAL(activated()), this, SLOT(showLibraryTab())); connect(albumsTabAction, SIGNAL(activated()), this, SLOT(showAlbumsTab())); connect(foldersTabAction, SIGNAL(activated()), this, SLOT(showFoldersTab())); connect(playlistsTabAction, SIGNAL(activated()), this, SLOT(showPlaylistsTab())); #ifndef Q_OS_WIN connect(dynamicTabAction, SIGNAL(activated()), this, SLOT(showDynamicTab())); #endif connect(lyricsTabAction, SIGNAL(activated()), this, SLOT(showLyricsTab())); connect(streamsTabAction, SIGNAL(activated()), this, SLOT(showStreamsTab())); #ifdef ENABLE_WEBKIT connect(infoTabAction, SIGNAL(activated()), this, SLOT(showInfoTab())); #endif connect(serverInfoTabAction, SIGNAL(activated()), this, SLOT(showServerInfoTab())); connect(searchAction, SIGNAL(activated()), this, SLOT(focusSearch())); connect(expandAllAction, SIGNAL(activated()), this, SLOT(expandAll())); connect(collapseAllAction, SIGNAL(activated()), this, SLOT(collapseAll())); #ifdef ENABLE_DEVICES_SUPPORT connect(devicesTabAction, SIGNAL(activated()), this, SLOT(showDevicesTab())); connect(DevicesModel::self(), SIGNAL(addToDevice(const QString &)), this, SLOT(addToDevice(const QString &))); connect(DevicesModel::self(), SIGNAL(error(const QString &)), this, SLOT(showError(const QString &))); connect(libraryPage, SIGNAL(addToDevice(const QString &, const QString &, const QList &)), SLOT(copyToDevice(const QString &, const QString &, const QList &))); connect(albumsPage, SIGNAL(addToDevice(const QString &, const QString &, const QList &)), SLOT(copyToDevice(const QString &, const QString &, const QList &))); connect(folderPage, SIGNAL(addToDevice(const QString &, const QString &, const QList &)), SLOT(copyToDevice(const QString &, const QString &, const QList &))); connect(devicesPage, SIGNAL(addToDevice(const QString &, const QString &, const QList &)), SLOT(copyToDevice(const QString &, const QString &, const QList &))); connect(deleteSongsAction, SIGNAL(triggered()), SLOT(deleteSongs())); connect(devicesPage, SIGNAL(deleteSongs(const QString &, const QList &)), SLOT(deleteSongs(const QString &, const QList &))); connect(libraryPage, SIGNAL(deleteSongs(const QString &, const QList &)), SLOT(deleteSongs(const QString &, const QList &))); connect(albumsPage, SIGNAL(deleteSongs(const QString &, const QList &)), SLOT(deleteSongs(const QString &, const QList &))); connect(folderPage, SIGNAL(deleteSongs(const QString &, const QList &)), SLOT(deleteSongs(const QString &, const QList &))); #endif connect(organiseFilesAction, SIGNAL(triggered()), SLOT(organiseFiles())); #ifdef ENABLE_REPLAYGAIN_SUPPORT connect(replaygainAction, SIGNAL(triggered()), SLOT(replayGain())); #endif connect(PlaylistsModel::self(), SIGNAL(addToNew()), this, SLOT(addToNewStoredPlaylist())); connect(PlaylistsModel::self(), SIGNAL(addToExisting(const QString &)), this, SLOT(addToExistingStoredPlaylist(const QString &))); connect(playlistsPage, SIGNAL(add(const QStringList &, bool)), &playQueueModel, SLOT(addItems(const QStringList &, bool))); connect(coverWidget, SIGNAL(coverImage(const QImage &)), lyricsPage, SLOT(setImage(const QImage &))); QByteArray state=Settings::self()->splitterState(); if (state.isEmpty()) { QList sizes; sizes << 250 << 500; splitter->setSizes(sizes); resize(800, 600); } else { splitter->restoreState(Settings::self()->splitterState()); } toggleSplitterAutoHide(Settings::self()->splitterAutoHide()); playQueueItemsSelected(false); playQueue->setFocus(); playQueue->initHeader(); mpdThread=new QThread(this); MPDConnection::self()->moveToThread(mpdThread); mpdThread->start(); connectToMpd(); #if defined ENABLE_REMOTE_DEVICES && defined ENABLE_DEVICES_SUPPORT DevicesModel::self()->loadRemote(); #endif QString page=Settings::self()->page(); for (int i=0; icount(); ++i) { if (tabWidget->widget(i)->metaObject()->className()==page) { tabWidget->SetCurrentIndex(i); break; } } connect(tabWidget, SIGNAL(CurrentChanged(int)), this, SLOT(currentTabChanged(int))); connect(tabWidget, SIGNAL(TabToggled(int)), this, SLOT(tabToggled(int))); connect(tabWidget, SIGNAL(AutoHideChanged(bool)), this, SLOT(toggleSplitterAutoHide(bool))); connect(tabWidget, SIGNAL(ModeChanged(FancyTabWidget::Mode)), this, SLOT(sidebarModeChanged())); connect(messageWidget, SIGNAL(visible(bool)), this, SLOT(messageWidgetVisibility(bool))); readSettings(); updateConnectionsMenu(); fadeStop=Settings::self()->stopFadeDuration()>Settings::MinFade; playlistsPage->refresh(); #ifndef Q_OS_WIN toggleMpris(); if (Settings::self()->dockManager()) { QTimer::singleShot(250, this, SLOT(toggleDockManager())); } #endif } MainWindow::~MainWindow() { #ifndef Q_OS_WIN if (dock) { dock->setIcon(QString()); } #endif Settings::self()->saveMainWindowSize(splitter->isVisible() ? size() : expandedSize); Settings::self()->saveMainWindowCollapsedSize(splitter->isVisible() ? collapsedSize : size()); #if defined ENABLE_REMOTE_DEVICES && defined ENABLE_DEVICES_SUPPORT DevicesModel::self()->unmountRemote(); #endif #ifdef PHONON_FOUND Settings::self()->savePlayStream(streamPlayAction->isChecked()); #endif Settings::self()->saveShowPlaylist(expandInterfaceAction->isChecked()); Settings::self()->saveSplitterState(splitter->saveState()); Settings::self()->saveSidebar((int)(tabWidget->mode())); Settings::self()->savePage(tabWidget->currentWidget()->metaObject()->className()); Settings::self()->saveSmallPlaybackButtons(smallPlaybackButtonsAction->isChecked()); Settings::self()->saveSmallControlButtons(smallControlButtonsAction->isChecked()); Settings::self()->saveSplitterAutoHide(splitter->isAutoHideEnabled()); playQueue->saveHeader(); QStringList hiddenPages; for (int i=0; icount(); ++i) { if (!tabWidget->isEnabled(i)) { QWidget *w=tabWidget->widget(i); if (w) { hiddenPages << w->metaObject()->className(); } } } Settings::self()->saveHiddenPages(hiddenPages); streamsPage->save(); lyricsPage->saveSettings(); #ifdef ENABLE_WEBKIT infoPage->save(); #endif Settings::self()->save(true); disconnect(MPDConnection::self(), 0, 0, 0); #ifndef Q_OS_WIN if (Settings::self()->stopDynamizerOnExit() || Settings::self()->stopOnExit()) { Dynamic::self()->stop(); } #endif if (Settings::self()->stopOnExit() || (fadeWhenStop() && StopState_Stopping==stopState)) { emit stop(); Utils::sleep(); } Utils::stopThread(mpdThread); Covers::self()->stop(); } void MainWindow::load(const QList &urls) { QStringList useable; bool haveHttp=HttpServer::self()->isAlive(); bool alwaysUseHttp=haveHttp && Settings::self()->alwaysUseHttp(); bool mpdLocal=MPDConnection::self()->getDetails().isLocal(); bool allowLocal=haveHttp || mpdLocal; foreach (QUrl u, urls) { if (QLatin1String("http")==u.scheme()) { useable.append(u.toString()); } else if (allowLocal && (u.scheme().isEmpty() || QLatin1String("file")==u.scheme())) { if (alwaysUseHttp || !mpdLocal) { useable.append(HttpServer::self()->encodeUrl(u.path())); } else { useable.append(u.toString()); } } } if (useable.count()) { playQueueModel.addItems(useable, playQueueModel.rowCount(), false); } } const QDateTime & MainWindow::getDbUpdate() const { return serverInfoPage->getDbUpdate(); } void MainWindow::playbackButtonsMenu() { playbackBtnsMenu->exec(QCursor::pos()); } void MainWindow::controlButtonsMenu() { controlBtnsMenu->exec(QCursor::pos()); } void MainWindow::setPlaybackButtonsSize(bool small) { QList playbackBtns; playbackBtns << prevTrackButton << stopTrackButton << playPauseTrackButton << nextTrackButton; foreach (QToolButton *b, playbackBtns) { b->setToolButtonStyle(Qt::ToolButtonIconOnly); // #ifdef ENABLE_KDE_SUPPORT b->setIconSize(small ? QSize(22, 22) : QSize(28, 28)); b->setMinimumSize(small ? QSize(26, 26) : QSize(32, 32)); b->setMaximumSize(small ? QSize(26, 26) : QSize(32, 32)); // #else // b->setIconSize(small ? QSize(24, 24) : QSize(28, 28)); // b->setMinimumSize(small ? QSize(26, 26) : QSize(36, 36)); // b->setMaximumSize(small ? QSize(26, 26) : QSize(36, 36)); // #endif } } void MainWindow::setControlButtonsSize(bool small) { QList controlBtns; controlBtns << volumeButton << menuButton; #ifdef PHONON_FOUND controlBtns << streamButton; #endif foreach (QToolButton *b, controlBtns) { b->setMinimumSize(small ? QSize(22, 22) : QSize(26, 26)); b->setMaximumSize(small ? QSize(22, 22) : QSize(26, 26)); b->setToolButtonStyle(Qt::ToolButtonIconOnly); #ifdef ENABLE_KDE_SUPPORT b->setIconSize(small ? QSize(16, 16) : QSize(22, 22)); #else b->setIconSize(small ? QSize(18, 18) : QSize(22, 22)); #endif } } void MainWindow::songLoaded() { // was song was loaded from commandline when empty... bool isInitial=-1==playQueueModel.currentSong() && MPDState_Inactive==lastState && MPDState_Inactive==MPDStatus::self()->state(); if (MPDState_Stopped==MPDStatus::self()->state() || isInitial) { stopVolumeFade(); if (isInitial) { emit play(); } } } void MainWindow::showError(const QString &message, bool showActions) { #ifndef Q_OS_WIN if (QLatin1String("NO_SONGS")==message) { messageWidget->setError(i18n("Failed to locate any songs matching the dynamic playlist rules.")); } else #endif { messageWidget->setError(message); } if (showActions) { messageWidget->addAction(prefAction); messageWidget->addAction(connectAction); } else { messageWidget->removeAction(prefAction); messageWidget->removeAction(connectAction); } } void MainWindow::showInformation(const QString &message) { messageWidget->setInformation(message); messageWidget->removeAction(prefAction); messageWidget->removeAction(connectAction); } void MainWindow::messageWidgetVisibility(bool v) { if (v && !splitter->isVisible()) { expandInterfaceAction->trigger(); } } void MainWindow::mpdConnectionStateChanged(bool connected) { if (connected) { messageWidget->hide(); if (CS_Connected!=connectedState) { emit getStatus(); emit getStats(); emit playListInfo(); emit outputs(); if (CS_Init!=connectedState) { loaded=0; currentTabChanged(tabWidget->current_index()); } connectedState=CS_Connected; } } else { libraryPage->clear(); albumsPage->clear(); folderPage->clear(); playlistsPage->clear(); playQueueModel.clear(); lyricsPage->text->clear(); serverInfoPage->clear(); connectedState=CS_Disconnected; outputsAction->setVisible(false); } } void MainWindow::keyPressEvent(QKeyEvent *event) { if ((Qt::Key_Enter==event->key() || Qt::Key_Return==event->key()) && playQueue->hasFocus() && !playQueue->selectionModel()->selectedRows().isEmpty()) { //play the first selected song QModelIndexList selection=playQueue->selectionModel()->selectedRows(); qSort(selection); playQueueItemActivated(selection.first()); } } void MainWindow::closeEvent(QCloseEvent *event) { if (trayItem) { lastPos=pos(); hide(); } else qApp->quit(); event->ignore(); } void MainWindow::showVolumeControl() { // qWarning() << volumeControl->pos().x() << volumeControl->pos().y() // << volumeButton->pos().x() << volumeButton->pos().y() // << volumeButton->mapToGlobal(volumeButton->pos()).x() << volumeButton->mapToGlobal(volumeButton->pos()).y(); // volumeControl->move(); volumeControl->popup(volumeButton->mapToGlobal(QPoint((volumeButton->width()-volumeControl->width())/2, volumeButton->height()))); } void MainWindow::playQueueItemsSelected(bool s) { if (playQueue->model()->rowCount()) { playQueue->setContextMenuPolicy(Qt::ActionsContextMenu); removeFromPlayQueueAction->setEnabled(s); copyTrackInfoAction->setEnabled(s); clearPlayQueueAction->setEnabled(true); cropPlayQueueAction->setEnabled(playQueue->haveUnSelectedItems()); shufflePlayQueueAction->setEnabled(true); } } void MainWindow::connectToMpd(const MPDConnectionDetails &details) { messageWidget->hide(); if (!MPDConnection::self()->isConnected() || details!=MPDConnection::self()->getDetails()) { libraryPage->clear(); albumsPage->clear(); folderPage->clear(); playlistsPage->clear(); playQueueModel.clear(); lyricsPage->text->clear(); serverInfoPage->clear(); #ifndef Q_OS_WIN Dynamic::self()->stop(); #endif showInformation(i18n("Connecting to %1").arg(details.description())); outputsAction->setVisible(false); connectedState=CS_Disconnected; emit setDetails(details); } } void MainWindow::connectToMpd() { connectToMpd(Settings::self()->connectionDetails()); } void MainWindow::refresh() { MusicLibraryModel::self()->removeCache(); lastDbUpdate=QDateTime(); emit getStats(); } #define DIALOG_ERROR MessageBox::error(this, i18n("Action is not currently possible, due to other open dialogs.")); return void MainWindow::showPreferencesDialog() { static bool showing=false; if (!showing) { if (0!=TagEditor::instanceCount()) { DIALOG_ERROR; } #ifdef ENABLE_DEVICES_SUPPORT if (0!=ActionDialog::instanceCount() || 0!=TrackOrganiser::instanceCount() || 0!=SyncDialog::instanceCount()) { DIALOG_ERROR; } #endif #ifdef ENABLE_REPLAYGAIN_SUPPORT if (0!=RgDialog::instanceCount()) { DIALOG_ERROR; } #endif showing=true; PreferencesDialog pref(this, lyricsPage); connect(&pref, SIGNAL(settingsSaved()), this, SLOT(updateSettings())); connect(&pref, SIGNAL(connectTo(const MPDConnectionDetails &)), this, SLOT(connectToMpd(const MPDConnectionDetails &))); pref.exec(); updateConnectionsMenu(); showing=false; } } void MainWindow::checkMpdDir() { editPlayQueueTagsAction->setEnabled(MPDConnection::self()->getDetails().dirReadable); organiseFilesAction->setEnabled(editPlayQueueTagsAction->isEnabled()); #ifdef ENABLE_DEVICES_SUPPORT copyToDeviceAction->setEnabled(editPlayQueueTagsAction->isEnabled()); deleteSongsAction->setEnabled(editPlayQueueTagsAction->isEnabled()); // burnAction->setEnabled(copyToDeviceAction->isEnabled()); #endif #ifdef ENABLE_REPLAYGAIN_SUPPORT replaygainAction->setEnabled(editPlayQueueTagsAction->isEnabled()); #endif switch (tabWidget->current_index()) { #ifdef ENABLE_DEVICES_SUPPORT case PAGE_DEVICES: devicesPage->controlActions(); break; #endif case PAGE_LIBRARY: libraryPage->controlActions(); break; case PAGE_ALBUMS: albumsPage->controlActions(); break; case PAGE_FOLDERS: folderPage->controlActions(); break; case PAGE_PLAYLISTS: playlistsPage->controlActions(); break; #ifndef Q_OS_WIN case PAGE_DYNAMIC: dynamicPage->controlActions(); break; #endif case PAGE_STREAMS: streamsPage->controlActions(); break; case PAGE_LYRICS: break; #ifdef ENABLE_WEBKIT case PAGE_INFO: break; #endif case PAGE_SERVER_INFO: break; default: break; } } void MainWindow::outputsUpdated(const QList &outputs) { if (outputs.count()<2) { outputsAction->setVisible(false); } else { outputsAction->setVisible(true); QSet mpd; QSet menuItems; QMenu *menu=outputsAction->menu(); foreach (const Output &o, outputs) { mpd.insert(o.name); } foreach (QAction *act, menu->actions()) { menuItems.insert(act->data().toString()); } if (menuItems!=mpd) { menu->clear(); QList out=outputs; qSort(out); foreach (const Output &o, out) { QAction *act=menu->addAction(o.name, this, SLOT(toggleOutput())); act->setData(o.id); act->setCheckable(true); act->setChecked(o.enabled); } } else { foreach (const Output &o, outputs) { foreach (QAction *act, menu->actions()) { if (Utils::strippedText(act->text())==o.name) { act->setChecked(o.enabled); break; } } } } } } void MainWindow::updateConnectionsMenu() { QList connections=Settings::self()->allConnections(); if (connections.count()<2) { connectionsAction->setVisible(false); } else { connectionsAction->setVisible(true); QSet cfg; QSet menuItems; QMenu *menu=connectionsAction->menu(); foreach (const MPDConnectionDetails &d, connections) { cfg.insert(d.name); } foreach (QAction *act, menu->actions()) { menuItems.insert(act->data().toString()); } if (menuItems!=cfg) { menu->clear(); qSort(connections); QString current=Settings::self()->currentConnection(); foreach (const MPDConnectionDetails &d, connections) { QAction *act=menu->addAction(d.name.isEmpty() ? i18n("Default") : d.name, this, SLOT(changeConnection())); act->setData(d.name); act->setCheckable(true); act->setChecked(d.name==current); act->setActionGroup(connectionsGroup); } } } } void MainWindow::readSettings() { checkMpdDir(); Covers::self()->setSaveInMpdDir(Settings::self()->storeCoversInMpdDir()); HttpServer::self()->setPort(Settings::self()->enableHttp() ? Settings::self()->httpPort() : 0); #ifdef ENABLE_DEVICES_SUPPORT deleteSongsAction->setVisible(Settings::self()->showDeleteAction()); #endif lyricsPage->setEnabledProviders(Settings::self()->lyricProviders()); MPDParseUtils::setGroupSingle(Settings::self()->groupSingle()); MPDParseUtils::setGroupMultiple(Settings::self()->groupMultiple()); albumsPage->setView(Settings::self()->albumsView()); AlbumsModel::self()->setAlbumSort(Settings::self()->albumSort()); #ifdef PHONON_FOUND streamButton->setVisible(!Settings::self()->streamUrl().isEmpty()); streamPlayAction->setChecked(Settings::self()->playStream()); if (phononStream && streamButton->isVisible()) { phononStream->setCurrentSource(Settings::self()->streamUrl()); } #endif libraryPage->setView(Settings::self()->libraryView()); MusicLibraryModel::self()->setUseArtistImages(Settings::self()->libraryArtistImage()); playlistsPage->setView(Settings::self()->playlistsView()); streamsPage->setView(0==Settings::self()->streamsView()); folderPage->setView(0==Settings::self()->folderView()); #ifdef ENABLE_DEVICES_SUPPORT devicesPage->setView(0==Settings::self()->devicesView()); #endif setupTrayIcon(); #ifndef Q_OS_WIN toggleDockManager(); toggleMpris(); #endif autoScrollPlayQueue=Settings::self()->playQueueScroll(); updateWindowTitle(); } void MainWindow::updateSettings() { int stopFadeDuration=Settings::self()->stopFadeDuration(); fadeStop=stopFadeDuration>Settings::MinFade; if (volumeFade) { volumeFade->setDuration(stopFadeDuration); } connectToMpd(); Settings::self()->save(); bool useLibSizeForAl=Settings::self()->albumsView()!=ItemView::Mode_IconTop; bool diffLibCovers=((int)MusicLibraryItemAlbum::currentCoverSize())!=Settings::self()->libraryCoverSize() || (libraryPage->viewMode()==ItemView::Mode_IconTop || Settings::self()->libraryView()!=ItemView::Mode_IconTop) || (libraryPage->viewMode()!=ItemView::Mode_IconTop && Settings::self()->libraryView()==ItemView::Mode_IconTop) || Settings::self()->libraryArtistImage()!=MusicLibraryModel::self()->useArtistImages(); bool diffAlCovers=((int)AlbumsModel::currentCoverSize())!=Settings::self()->albumsCoverSize() || albumsPage->viewMode()!=Settings::self()->albumsView() || useLibSizeForAl!=AlbumsModel::useLibrarySizes(); bool diffLibYear=MusicLibraryItemAlbum::showDate()!=Settings::self()->libraryYear(); bool diffGrouping=MPDParseUtils::groupSingle()!=Settings::self()->groupSingle() || MPDParseUtils::groupMultiple()!=Settings::self()->groupMultiple(); readSettings(); if (diffLibCovers) { MusicLibraryItemAlbum::setCoverSize((MusicLibraryItemAlbum::CoverSize)Settings::self()->libraryCoverSize()); } if (diffLibYear) { MusicLibraryItemAlbum::setShowDate(Settings::self()->libraryYear()); } if (diffAlCovers) { AlbumsModel::setCoverSize((MusicLibraryItemAlbum::CoverSize)Settings::self()->albumsCoverSize()); } AlbumsModel::setUseLibrarySizes(useLibSizeForAl); if (diffAlCovers || diffGrouping) { albumsPage->clear(); } if (diffLibCovers || diffAlCovers || diffLibYear || diffGrouping) { refresh(); } bool wasAutoExpand=playQueue->isAutoExpand(); bool wasStartClosed=playQueue->isStartClosed(); playQueue->setAutoExpand(Settings::self()->playQueueAutoExpand()); playQueue->setStartClosed(Settings::self()->playQueueStartClosed()); if (Settings::self()->playQueueGrouped()!=playQueueModel.isGrouped() || (playQueueModel.isGrouped() && (wasAutoExpand!=playQueue->isAutoExpand() || wasStartClosed!=playQueue->isStartClosed())) ) { playQueueModel.setGrouped(Settings::self()->playQueueGrouped()); playQueue->setGrouped(Settings::self()->playQueueGrouped()); playQueue->updateRows(usingProxy ? playQueueModel.rowCount()+10 : playQueueModel.currentSongRow(), !usingProxy && autoScrollPlayQueue && MPDState_Playing==MPDStatus::self()->state()); } wasStartClosed=playlistsPage->isStartClosed(); playlistsPage->setStartClosed(Settings::self()->playListsStartClosed()); if (ItemView::Mode_GroupedTree==Settings::self()->playlistsView() && wasStartClosed!=playlistsPage->isStartClosed()) { playlistsPage->updateRows(); } if (Settings::self()->lyricsBgnd()!=lyricsPage->bgndImageEnabled()) { lyricsPage->setBgndImageEnabled(Settings::self()->lyricsBgnd()); if (lyricsPage->bgndImageEnabled() && !coverWidget->isEmpty()) { Covers::Image img=Covers::self()->get(coverWidget->song()); if (!img.img.isNull()) { lyricsPage->setImage(img.img); } } } } void MainWindow::toggleOutput() { QAction *act=qobject_cast(sender()); if (act) { emit enableOutput(act->data().toInt(), act->isChecked()); } } void MainWindow::changeConnection() { bool allowChange=true; if (0!=TagEditor::instanceCount()) { allowChange=false; } #ifdef ENABLE_DEVICES_SUPPORT if (0!=ActionDialog::instanceCount() || 0!=TrackOrganiser::instanceCount() || 0!=SyncDialog::instanceCount()) { allowChange=false; } #endif #ifdef ENABLE_REPLAYGAIN_SUPPORT if (0!=RgDialog::instanceCount()) { allowChange=false; } #endif if (allowChange) { QAction *act=qobject_cast(sender()); if (act) { Settings::self()->saveCurrentConnection(act->data().toString()); connectToMpd(); } } else { QString current=Settings::self()->currentConnection(); foreach (QAction *act, connectionsAction->menu()->actions()) { if (act->data().toString()==current) { act->setChecked(true); } break; } } } #ifndef ENABLE_KDE_SUPPORT void MainWindow::showAboutDialog() { QMessageBox::about(this, tr("About Cantata"), tr("Simple GUI front-end for MPD.

(c) Craig Drummond 2011-2012.
Released under the GPLv2

Based upon QtMPC - (C) 2007-2010 The QtMPC Authors")); } #endif #ifdef PHONON_FOUND void MainWindow::toggleStream(bool s) { MPDStatus * const status = MPDStatus::self(); phononStreamEnabled = s; if (!s){ if (phononStream) { phononStream->stop(); } } else { if (phononStream) { switch (status->state()) { case MPDState_Playing: phononStream->play(); break; case MPDState_Inactive: case MPDState_Stopped: phononStream->stop(); break; case MPDState_Paused: phononStream->pause(); default: break; } } else { phononStream=new Phonon::MediaObject(this); Phonon::createPath(phononStream, new Phonon::AudioOutput(Phonon::MusicCategory, this)); phononStream->setCurrentSource(Settings::self()->streamUrl()); } } } #endif void MainWindow::positionSliderPressed() { draggingPositionSlider = true; } void MainWindow::positionSliderReleased() { draggingPositionSlider = false; } void MainWindow::stopTrack() { if (!fadeWhenStop() || MPDState_Paused==MPDStatus::self()->state() || 0==volume) { emit stop(); } stopTrackAction->setEnabled(false); nextTrackAction->setEnabled(false); prevTrackAction->setEnabled(false); startVolumeFade(/*true*/); } void MainWindow::startVolumeFade(/*bool stop*/) { if (!fadeWhenStop()) { return; } stopState=/*stop ? */StopState_Stopping/* : StopState_Pausing*/; if (!volumeFade) { volumeFade = new QPropertyAnimation(this, "volume"); volumeFade->setDuration(Settings::self()->stopFadeDuration()); } origVolume=volume; lastVolume=volume; volumeFade->setStartValue(volume); volumeFade->setEndValue(-1); volumeFade->start(); } void MainWindow::stopVolumeFade() { if (stopState) { stopState=StopState_None; volumeFade->stop(); setMpdVolume(-1); } } void MainWindow::setMpdVolume(int v) { if (-1==v) { if (StopState_Stopping==stopState) { emit stop(); } /*else if (StopState_Pausing==stopState) { emit pause(true); }*/ stopState=StopState_None; volume=origVolume; emit setVolume(origVolume); } else if (lastVolume!=v) { emit setVolume(v); lastVolume=v; } } void MainWindow::playPauseTrack() { MPDStatus * const status = MPDStatus::self(); if (MPDState_Playing==status->state()) { /*if (fadeWhenStop()) { startVolumeFade(false); } else*/ { emit pause(true); } } else if (MPDState_Paused==status->state()) { stopVolumeFade(); emit pause(false); } else { stopVolumeFade(); if (-1!=playQueueModel.currentSong() && -1!=playQueueModel.currentSongRow()) { emit startPlayingSongId(playQueueModel.currentSong()); } else { emit play(); } } } void MainWindow::setPosition() { emit setSeekId(MPDStatus::self()->songId(), positionSlider->value()); } void MainWindow::increaseVolume() { volumeControl->sliderWidget()->triggerAction(QAbstractSlider::SliderPageStepAdd); } void MainWindow::decreaseVolume() { volumeControl->sliderWidget()->triggerAction(QAbstractSlider::SliderPageStepSub); } void MainWindow::searchPlayQueue() { if (searchPlayQueueLineEdit->text().isEmpty()) { if (playQueueSearchTimer) { playQueueSearchTimer->stop(); } realSearchPlayQueue(); } else { if (!playQueueSearchTimer) { playQueueSearchTimer=new QTimer(this); playQueueSearchTimer->setSingleShot(true); connect(playQueueSearchTimer, SIGNAL(timeout()), SLOT(realSearchPlayQueue())); } playQueueSearchTimer->start(250); } } void MainWindow::realSearchPlayQueue() { QList selectedSongIds; if (playQueueSearchTimer) { playQueueSearchTimer->stop(); } QString filter=searchPlayQueueLineEdit->text().trimmed(); if (filter.length()<2) { if (usingProxy) { if (playQueue->selectionModel()->hasSelection()) { QModelIndexList items = playQueue->selectionModel()->selectedRows(); foreach (const QModelIndex &index, items) { selectedSongIds.append(playQueueModel.getIdByRow(playQueueProxyModel.mapToSource(index).row())); } } playQueue->setModel(&playQueueModel); usingProxy=false; playQueue->setFilterActive(false); playQueue->updateRows(playQueueModel.currentSongRow(), autoScrollPlayQueue && MPDState_Playing==MPDStatus::self()->state()); scrollPlayQueue(); } } else if (filter!=playQueueProxyModel.filterRegExp().pattern()) { if (!usingProxy) { if (playQueue->selectionModel()->hasSelection()) { QModelIndexList items = playQueue->selectionModel()->selectedRows(); foreach (const QModelIndex &index, items) { selectedSongIds.append(playQueueModel.getIdByRow(index.row())); } } playQueue->setModel(&playQueueProxyModel); usingProxy=true; playQueue->updateRows(playQueueModel.rowCount()+10, false); playQueue->setFilterActive(true); } } playQueueProxyModel.update(filter); if (selectedSongIds.size() > 0) { foreach (qint32 i, selectedSongIds) { qint32 row = playQueueModel.getRowById(i); playQueue->selectionModel()->select(usingProxy ? playQueueProxyModel.mapFromSource(playQueueModel.index(row, 0)) : playQueueModel.index(row, 0), QItemSelectionModel::Select | QItemSelectionModel::Rows); } } } void MainWindow::updatePlayQueue(const QList &songs) { TF_DEBUG playPauseTrackAction->setEnabled(!songs.isEmpty()); nextTrackAction->setEnabled(stopTrackAction->isEnabled() && songs.count()>1); prevTrackAction->setEnabled(stopTrackAction->isEnabled() && songs.count()>1); playQueueModel.update(songs); playQueue->updateRows(usingProxy ? playQueueModel.rowCount()+10 : playQueueModel.currentSongRow(), false); /*if (1==songs.count() && MPDState_Playing==MPDStatus::self()->state()) { updateCurrentSong(songs.at(0)); } else*/ if (0==songs.count()) { updateCurrentSong(Song()); } } bool MainWindow::currentIsStream() const { return playQueueModel.rowCount() && -1!=current.id && current.isStream(); } void MainWindow::updateWindowTitle() { MPDStatus * const status = MPDStatus::self(); bool stopped=MPDState_Stopped==status->state() || MPDState_Inactive==status->state(); bool multipleConnections=connectionsAction->isVisible(); QString connection=MPDConnection::self()->getDetails().name; if (multipleConnections && connection.isEmpty()) { connection=i18n("Default"); } if (stopped) { setWindowTitle(multipleConnections ? i18n("Cantata (%1)").arg(connection) : "Cantata"); } else if (current.artist.isEmpty()) { if (trackLabel->text().isEmpty()) { setWindowTitle(multipleConnections ? i18n("Cantata (%1)").arg(connection) : "Cantata"); } else { #ifdef ENABLE_KDE_SUPPORT setWindowTitle(multipleConnections ? i18nc("track :: Cantata (connection)", "%1 :: Cantata (%2)", trackLabel->text(), connection) : i18nc("track :: Cantata", "%1 :: Cantata", trackLabel->text())); #else setWindowTitle(multipleConnections ? tr("%1 :: Cantata (%2)").arg(trackLabel->text()).arg(connection) : tr("%1 :: Cantata").arg(trackLabel->text())); #endif } } else { #ifdef ENABLE_KDE_SUPPORT setWindowTitle(multipleConnections ? i18nc("track - artist :: Cantata (connection)", "%1 - %2 :: Cantata (%3)", trackLabel->text(), current.artist,connection) : i18nc("track - artist :: Cantata", "%1 - %2 :: Cantata", trackLabel->text(), current.artist)); #else setWindowTitle(multipleConnections ? tr("%1 - %2 :: Cantata (%3)").arg(trackLabel->text()).arg(current.artist).arg(connection) : tr("%1 - %2 :: Cantata").arg(trackLabel->text()).arg(current.artist)); #endif } } void MainWindow::updateCurrentSong(const Song &song) { if (fadeWhenStop() && StopState_None!=stopState) { if (StopState_Stopping==stopState) { emit stop(); } /*else if (StopState_Pausing==stopState) { emit pause(true); }*/ } current=song; if (current.isCantataStream()) { Song mod=HttpServer::self()->decodeUrl(current.file); if (!mod.title.isEmpty()) { current=mod; current.id=song.id; // current.file="XXX"; } } positionSlider->setEnabled(-1!=current.id && !currentIsStream()); coverWidget->update(current); if (current.name.isEmpty()) { trackLabel->setText(current.title); } else { trackLabel->setText(QString("%1 (%2)").arg(current.title).arg(current.name)); } if (current.album.isEmpty()) { artistLabel->setText(current.artist); } else { QString album=current.album; if (current.year>0) { album+=QString(" (%1)").arg(current.year); } #ifdef ENABLE_KDE_SUPPORT artistLabel->setText(i18nc("artist - album", "%1 - %2", current.artist, album)); #else artistLabel->setText(tr("%1 - %2").arg(current.artist).arg(album)); #endif } playQueueModel.updateCurrentSong(current.id); playQueue->updateRows(usingProxy ? playQueueModel.rowCount()+10 : playQueueModel.getRowById(current.id), !usingProxy && autoScrollPlayQueue && MPDState_Playing==MPDStatus::self()->state()); scrollPlayQueue(); updateWindowTitle(); if (PAGE_LYRICS==tabWidget->current_index()) { lyricsPage->update(song); } else { lyricsNeedUpdating=true; } #ifdef ENABLE_WEBKIT if (PAGE_INFO==tabWidget->current_index()) { infoPage->update(song); } else { infoNeedsUpdating=true; } #endif if (Settings::self()->showPopups() || trayItem) { if (!current.title.isEmpty() && !current.artist.isEmpty() && !current.album.isEmpty()) { #ifdef ENABLE_KDE_SUPPORT QPixmap *coverPixmap = 0; const QString text(i18n("" "" "" "" "" "" "
Artist:%1
Album:%2
Song:%3
Track:%4
Length:%5
").arg(current.artist).arg(current.album).arg(current.title) .arg(current.track).arg(Song::formattedTime(current.time))); if (coverWidget->isValid()) { coverPixmap = const_cast(coverWidget->pixmap()); } if (Settings::self()->showPopups()) { if (notification) { notification->close(); } notification = new KNotification("CurrentTrackChanged", this); connect(notification, SIGNAL(closed()), this, SLOT(notificationClosed())); notification->setText(text); if (coverPixmap) { notification->setPixmap(*coverPixmap); } notification->sendEvent(); } if (trayItem) { trayItem->setToolTip("cantata", i18n("Cantata"), text); // Use the cover as icon pixmap. if (coverPixmap) { trayItem->setToolTipIconByPixmap(*coverPixmap); } } #else // The pure Qt implementation needs both, the tray icon // and the setting checked. if (Settings::self()->showPopups() && trayItem) { const QString text=tr("Album: %1\n" "Track: %2\n" "Length: %3").arg(current.album).arg(current.track).arg(Song::formattedTime(current.time)); trayItem->showMessage(tr("%1 - %2").arg(current.artist).arg(current.title), text, QSystemTrayIcon::Information, 5000); } #endif } else if (trayItem) { #ifdef ENABLE_KDE_SUPPORT trayItem->setToolTip("cantata", i18n("Cantata"), QString()); #endif } } } void MainWindow::scrollPlayQueue() { if (autoScrollPlayQueue && MPDState_Playing==MPDStatus::self()->state() && !playQueueModel.isGrouped()) { qint32 row=playQueueModel.currentSongRow(); if (row>=0) { QModelIndex idx=usingProxy ? playQueueProxyModel.mapFromSource(playQueueModel.index(row, 0)) : playQueueModel.index(row, 0); playQueue->scrollTo(idx, QAbstractItemView::PositionAtCenter); } } } void MainWindow::updateStats() { /* * Check if remote db is more recent than local one * Also update the dirview */ if (!lastDbUpdate.isValid() || serverInfoPage->getDbUpdate() > lastDbUpdate) { loaded|=TAB_LIBRARY|TAB_FOLDERS; if (!lastDbUpdate.isValid()) { libraryPage->clear(); //albumsPage->clear(); folderPage->clear(); playlistsPage->clear(); } libraryPage->refresh(); folderPage->refresh(); playlistsPage->refresh(); } lastDbUpdate = serverInfoPage->getDbUpdate(); } void MainWindow::updateStatus() { MPDStatus * const status = MPDStatus::self(); if (!draggingPositionSlider) { if (MPDState_Stopped==status->state() || MPDState_Inactive==status->state()) { positionSlider->setValue(0); } else { positionSlider->setRange(0, status->timeTotal()); positionSlider->setValue(status->timeElapsed()); } } if (!stopState) { volume=status->volume(); if (volume<0) { volumeButton->setEnabled(false); volumeButton->setToolTip(i18n("Volume Disabled")); volumeControl->setToolTip(i18n("Volume Disabled")); volumeControl->setValue(0); } else { volumeButton->setEnabled(true); volumeButton->setToolTip(i18n("Volume %1%").arg(volume)); volumeControl->setToolTip(i18n("Volume %1%").arg(volume)); volumeControl->setValue(volume); } if (volume<=0) { volumeButton->setIcon(Icon("audio-volume-muted")); } else if (volume<=33) { volumeButton->setIcon(Icon("audio-volume-low")); } else if (volume<=67) { volumeButton->setIcon(Icon("audio-volume-medium")); } else { volumeButton->setIcon(Icon("audio-volume-high")); } } randomPlayQueueAction->setChecked(status->random()); repeatPlayQueueAction->setChecked(status->repeat()); singlePlayQueueAction->setChecked(status->single()); consumePlayQueueAction->setChecked(status->consume()); QString timeElapsedFormattedString; if (status->timeElapsed()<172800 && (!currentIsStream() || (status->timeTotal()>0 && status->timeElapsed()<=status->timeTotal()))) { if (status->state() == MPDState_Stopped || status->state() == MPDState_Inactive) { timeElapsedFormattedString = "0:00 / 0:00"; } else { timeElapsedFormattedString += Song::formattedTime(status->timeElapsed()); timeElapsedFormattedString += " / "; timeElapsedFormattedString += Song::formattedTime(status->timeTotal()); songTime = status->timeTotal(); } } songTimeElapsedLabel->setText(timeElapsedFormattedString); playQueueModel.setState(status->state()); switch (status->state()) { case MPDState_Playing: #ifdef PHONON_FOUND if (phononStreamEnabled && phononStream) { phononStream->play(); } #endif playPauseTrackAction->setIcon(playbackPause); playPauseTrackAction->setEnabled(0!=playQueueModel.rowCount()); //playPauseTrackButton->setChecked(false); if (StopState_Stopping!=stopState) { stopTrackAction->setEnabled(true); nextTrackAction->setEnabled(true); prevTrackAction->setEnabled(true); } positionSlider->startTimer(); if (trayItem) { #ifdef ENABLE_KDE_SUPPORT trayItem->setIconByName("media-playback-start"); #else trayItem->setIcon(playbackPlay); #endif } break; case MPDState_Inactive: case MPDState_Stopped: #ifdef PHONON_FOUND if (phononStreamEnabled && phononStream) { phononStream->stop(); } #endif playPauseTrackAction->setIcon(playbackPlay); playPauseTrackAction->setEnabled(0!=playQueueModel.rowCount()); stopTrackAction->setEnabled(false); nextTrackAction->setEnabled(false); prevTrackAction->setEnabled(false); if (!playPauseTrackAction->isEnabled()) { trackLabel->setText(QString()); artistLabel->setText(QString()); current=Song(); coverWidget->update(current); } current.id=0; updateWindowTitle(); if (trayItem) { #ifdef ENABLE_KDE_SUPPORT trayItem->setIconByName("cantata"); trayItem->setToolTip("cantata", i18n("Cantata"), "Playback stopped"); #else trayItem->setIcon(windowIcon()); #endif } positionSlider->stopTimer(); break; case MPDState_Paused: #ifdef PHONON_FOUND if (phononStreamEnabled && phononStream) { phononStream->pause(); } #endif playPauseTrackAction->setIcon(playbackPlay); playPauseTrackAction->setEnabled(0!=playQueueModel.rowCount()); stopTrackAction->setEnabled(0!=playQueueModel.rowCount()); nextTrackAction->setEnabled(playQueueModel.rowCount()>1); prevTrackAction->setEnabled(playQueueModel.rowCount()>1); if (trayItem) { #ifdef ENABLE_KDE_SUPPORT trayItem->setIconByName("media-playback-pause"); #else trayItem->setIcon(playbackPause); #endif } positionSlider->stopTimer(); break; default: qDebug("Invalid state"); break; } // Check if song has changed or we're playing again after being stopped // and update song info if needed if (lastState == MPDState_Inactive || (lastState == MPDState_Stopped && status->state() == MPDState_Playing) || lastSongId != status->songId()) { emit currentSong(); } // Update status info lastState = status->state(); lastSongId = status->songId(); } void MainWindow::playQueueItemActivated(const QModelIndex &index) { emit startPlayingSongId(playQueueModel.getIdByRow(usingProxy ? playQueueProxyModel.mapToSource(index).row() : index.row())); } void MainWindow::removeFromPlayQueue() { const QModelIndexList items = playQueue->selectedIndexes(); QModelIndex sourceIndex; QList toBeRemoved; if (items.isEmpty()) { return; } foreach (const QModelIndex &idx, items) { toBeRemoved.append(playQueueModel.getIdByRow(usingProxy ? playQueueProxyModel.mapToSource(idx).row() : idx.row())); } emit removeSongs(toBeRemoved); } void MainWindow::replacePlayQueue() { // emit clear(); // emit getStatus(); addToPlayQueue(true); } void MainWindow::addToPlayQueue() { addToPlayQueue(false); } void MainWindow::addToPlayQueue(bool replace) { searchPlayQueueLineEdit->clear(); if (libraryPage->isVisible()) { libraryPage->addSelectionToPlaylist(QString(), replace); } else if (albumsPage->isVisible()) { albumsPage->addSelectionToPlaylist(QString(), replace); } else if (folderPage->isVisible()) { folderPage->addSelectionToPlaylist(QString(), replace); } else if (playlistsPage->isVisible()) { playlistsPage->addSelectionToPlaylist(replace); } else if (streamsPage->isVisible()) { streamsPage->addSelectionToPlaylist(replace); } } void MainWindow::addToNewStoredPlaylist() { for(;;) { QString name = InputDialog::getText(i18n("Playlist Name"), i18n("Enter a name for the playlist:"), QString(), 0, this); if (PlaylistsModel::self()->exists(name)) { switch(MessageBox::warningYesNoCancel(this, i18n("A playlist named %1 already exists!
Add to that playlist?").arg(name), i18n("Existing Playlist"))) { case MessageBox::Cancel: return; case MessageBox::Yes: break; case MessageBox::No: default: continue; } } if (!name.isEmpty()) { addToExistingStoredPlaylist(name); } break; } } void MainWindow::addToExistingStoredPlaylist(const QString &name) { if (libraryPage->isVisible()) { libraryPage->addSelectionToPlaylist(name); } else if (albumsPage->isVisible()) { albumsPage->addSelectionToPlaylist(name); } else if (folderPage->isVisible()) { folderPage->addSelectionToPlaylist(name); } } void MainWindow::removeItems() { if (playlistsPage->isVisible()) { playlistsPage->removeItems(); } else if (streamsPage->isVisible()) { streamsPage->removeItems(); } } void MainWindow::updatePlayQueueStats(int artists, int albums, int songs, quint32 time) { if (0==time) { playQueueStatsLabel->setText(QString()); return; } QString status; #ifdef ENABLE_KDE_SUPPORT status+=i18np("1 Artist, ", "%1 Artists, ", artists); status+=i18np("1 Album, ", "%1 Albums, ", albums); status+=i18np("1 Track", "%1 Tracks", songs); #else status += QString::number(artists)+QString(1==artists ? tr(" Artist,") : tr(" Artists, ")); status += QString::number(albums)+QString(1==albums ? tr(" Album,") : tr(" Albums, ")); status += QString::number(songs)+QString(1==songs ? tr(" Track") : tr(" Tracks")); #endif status += " ("; status += MPDParseUtils::formatDuration(time); status += ")"; playQueueStatsLabel->setText(status); } void MainWindow::updatePosition() { if (positionSlider->value()<172800) { QString timeElapsedFormattedString; if (positionSlider->value() != positionSlider->maximum()) { timeElapsedFormattedString += Song::formattedTime(positionSlider->value()); timeElapsedFormattedString += " / "; timeElapsedFormattedString += Song::formattedTime(songTime); songTimeElapsedLabel->setText(timeElapsedFormattedString); } } } void MainWindow::copyTrackInfo() { const QModelIndexList items = playQueue->selectedIndexes(); if (items.isEmpty()) { return; } QString txt; QTextStream str(&txt); foreach (const QModelIndex &idx, items) { Song s = playQueueModel.getSongByRow(usingProxy ? playQueueProxyModel.mapToSource(idx).row() : idx.row()); if (!s.isEmpty()) { if (!txt.isEmpty()) { str << QChar('\n'); } str << s.format(); } } QApplication::clipboard()->setText(txt); } int MainWindow::calcMinHeight() { if (FancyTabWidget::Mode_LargeSidebar==tabWidget->mode()) { return coverWidget->height()+(tabWidget->visibleCount()*(32+fontMetrics().height()+4)); } else if (FancyTabWidget::Mode_IconOnlyLargeSidebar==tabWidget->mode()) { return coverWidget->height()+(tabWidget->visibleCount()*(32+6)); } return 256; } void MainWindow::togglePlayQueue() { if (!expandInterfaceAction->isChecked() && messageWidget->isVisible()) { expandInterfaceAction->trigger(); return; } if (splitter->isVisible()==expandInterfaceAction->isChecked()) { setMinimumHeight(calcMinHeight()); return; } static bool lastMax=false; bool showing=expandInterfaceAction->isChecked(); QPoint p(isVisible() ? pos() : QPoint()); int compactHeight=0; if (!showing) { setMinimumHeight(0); lastMax=isMaximized(); expandedSize=size(); int spacing=style()->layoutSpacing(QSizePolicy::DefaultType, QSizePolicy::DefaultType, Qt::Vertical); // For some reason height is always larger than it needs to be - so fix this to cover height +4 compactHeight=qMax(qMax(playPauseTrackButton->height(), trackLabel->height()+artistLabel->height())+ songTimeElapsedLabel->height()+positionSlider->height()+(spacing*3), coverWidget->height()+spacing); } else { collapsedSize=size(); setMinimumHeight(calcMinHeight()); setMaximumHeight(65535); } int prevWidth=size().width(); splitter->setVisible(showing); if (!showing) { setWindowState(windowState()&~Qt::WindowMaximized); } QApplication::processEvents(); adjustSize(); if (showing) { bool adjustWidth=size().width()!=expandedSize.width(); bool adjustHeight=size().height()!=expandedSize.height(); if (adjustWidth || adjustHeight) { resize(adjustWidth ? expandedSize.width() : size().width(), adjustHeight ? expandedSize.height() : size().height()); } if (messageWidget->isVisible()) { messageWidget->adjustSize(); QApplication::processEvents(); } if (lastMax) { showMaximized(); } } else { // Widths also sometimes expands, so make sure this is no larger than it was before... resize(collapsedSize.isValid() ? collapsedSize.width() : (size().width()>prevWidth ? prevWidth : size().width()), compactHeight); setMinimumHeight(size().height()); setMaximumHeight(size().height()); } if (!p.isNull()) { move(p); } } void MainWindow::sidebarModeChanged() { if (splitter->isVisible()) { setMinimumHeight(calcMinHeight()); } } /* * Crop playqueue * Do this by taking the set off all song id's and subtracting from that * the set of selected song id's. Feed that list to emit removeSongs */ void MainWindow::cropPlayQueue() { QSet songs = playQueueModel.getSongIdSet(); QSet selected; const QModelIndexList items = playQueue->selectedIndexes(); if (items.isEmpty()) { return; } foreach (const QModelIndex &idx, items) { selected << playQueueModel.getIdByRow(usingProxy ? playQueueProxyModel.mapToSource(idx).row() : idx.row()); } QList toBeRemoved = (songs - selected).toList(); emit removeSongs(toBeRemoved); } // Tray Icon // void MainWindow::setupTrayIcon() { if (!Settings::self()->useSystemTray()) { if (trayItem) { trayItem->deleteLater(); trayItem=0; trayItemMenu->deleteLater(); trayItemMenu=0; } return; } if (trayItem) { return; } #ifdef ENABLE_KDE_SUPPORT trayItem = new KStatusNotifierItem(this); trayItem->setCategory(KStatusNotifierItem::ApplicationStatus); trayItem->setTitle(i18n("Cantata")); trayItem->setIconByName("cantata"); trayItem->setToolTip("cantata", i18n("Cantata"), QString()); trayItemMenu = new KMenu(this); trayItemMenu->addAction(prevTrackAction); trayItemMenu->addAction(playPauseTrackAction); trayItemMenu->addAction(stopTrackAction); trayItemMenu->addAction(nextTrackAction); trayItem->setContextMenu(trayItemMenu); connect(trayItem, SIGNAL(scrollRequested(int, Qt::Orientation)), this, SLOT(trayItemScrollRequested(int, Qt::Orientation))); connect(trayItem, SIGNAL(secondaryActivateRequested(const QPoint &)), this, SLOT(playPauseTrack())); #else if (!QSystemTrayIcon::isSystemTrayAvailable()) { trayItem = NULL; return; } trayItem = new QSystemTrayIcon(this); trayItem->installEventFilter(volumeSliderEventHandler); trayItemMenu = new QMenu(this); trayItemMenu->addAction(prevTrackAction); trayItemMenu->addAction(playPauseTrackAction); trayItemMenu->addAction(stopTrackAction); trayItemMenu->addAction(nextTrackAction); trayItemMenu->addSeparator(); trayItemMenu->addAction(quitAction); trayItem->setContextMenu(trayItemMenu); trayItem->setIcon(windowIcon()); trayItem->setToolTip(tr("Cantata")); trayItem->show(); connect(trayItem, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayItemClicked(QSystemTrayIcon::ActivationReason))); #endif } #ifdef ENABLE_KDE_SUPPORT void MainWindow::trayItemScrollRequested(int delta, Qt::Orientation orientation) { if (Qt::Vertical==orientation) { if (delta>0) { increaseVolumeAction->trigger(); } else if(delta<0) { decreaseVolumeAction->trigger(); } } } void MainWindow::notificationClosed() { if (sender() == notification) { notification=0; } } #else void MainWindow::trayItemClicked(QSystemTrayIcon::ActivationReason reason) { switch (reason) { case QSystemTrayIcon::Trigger: if (isHidden()) { showNormal(); if (!lastPos.isNull()) { move(lastPos); } } else { hide(); } default: break; } } #endif void MainWindow::currentTabChanged(int index) { switch(index) { #ifdef ENABLE_DEVICES_SUPPORT case PAGE_DEVICES: // Need library to be loaded to check if song exists... devicesPage->controlActions(); break; #endif case PAGE_LIBRARY: case PAGE_ALBUMS: // Albums shares refresh with library... if (!(loaded&TAB_LIBRARY)) { loaded|=TAB_LIBRARY; libraryPage->refresh(); } if (PAGE_LIBRARY==index) { libraryPage->controlActions(); } else { // AlbumsModel::self()->getCovers(); albumsPage->controlActions(); } break; case PAGE_FOLDERS: if (!(loaded&TAB_FOLDERS)) { loaded|=TAB_FOLDERS; folderPage->refresh(); } folderPage->controlActions(); break; case PAGE_PLAYLISTS: playlistsPage->controlActions(); break; #ifndef Q_OS_WIN case PAGE_DYNAMIC: dynamicPage->controlActions(); break; #endif case PAGE_STREAMS: if (!(loaded&TAB_STREAMS)) { loaded|=TAB_STREAMS; streamsPage->refresh(); } streamsPage->controlActions(); break; case PAGE_LYRICS: if (lyricsNeedUpdating) { lyricsPage->update(current); lyricsNeedUpdating=false; } break; #ifdef ENABLE_WEBKIT case PAGE_INFO: if (infoNeedsUpdating) { infoPage->update(current); infoNeedsUpdating=false; } break; #endif case PAGE_SERVER_INFO: break; default: break; } } void MainWindow::tabToggled(int index) { switch (index) { case PAGE_LIBRARY: locateTrackAction->setVisible(tabWidget->isEnabled(index)); break; case PAGE_ALBUMS: AlbumsModel::self()->setEnabled(!AlbumsModel::self()->isEnabled()); break; case PAGE_FOLDERS: folderPage->setEnabled(!folderPage->isEnabled()); break; case PAGE_STREAMS: streamsPage->setEnabled(!streamsPage->isEnabled()); break; #ifdef ENABLE_DEVICES_SUPPORT case PAGE_DEVICES: DevicesModel::self()->setEnabled(!DevicesModel::self()->isEnabled()); copyToDeviceAction->setVisible(DevicesModel::self()->isEnabled()); break; #endif default: break; } sidebarModeChanged(); } void MainWindow::toggleSplitterAutoHide(bool ah) { splitter->setAutoHideEnabled(ah); splitter->setAutohidable(0, ah); } void MainWindow::locateTrack() { if (!libraryPage->isVisible()) { showLibraryTab(); } libraryPage->showSongs(playQueue->selectedSongs()); } void MainWindow::showPage(const QString &page, bool focusSearch) { QString p=page.toLower(); if (QLatin1String("library")==p) { showTab(MainWindow::PAGE_LIBRARY); } else if (QLatin1String("albums")==p) { showTab(MainWindow::PAGE_ALBUMS); } else if (QLatin1String("folders")==p) { showTab(MainWindow::PAGE_FOLDERS); } else if (QLatin1String("playlists")==p) { showTab(MainWindow::PAGE_PLAYLISTS); } #ifndef Q_OS_WIN else if (QLatin1String("dynamic")==p) { showTab(MainWindow::PAGE_DYNAMIC); } #endif else if (QLatin1String("streams")==p) { showTab(MainWindow::PAGE_STREAMS); } else if (QLatin1String("lyrics")==p) { showTab(MainWindow::PAGE_LYRICS); } else if (QLatin1String("info")==p) { showTab(MainWindow::PAGE_INFO); } else if (QLatin1String("serverinfo")==p) { showTab(MainWindow::PAGE_SERVER_INFO); } #ifdef ENABLE_KDE_SUPPORT else if (QLatin1String("devices")==p) { showTab(MainWindow::PAGE_DEVICES); } #endif if (focusSearch) { focusTabSearch(); } } #ifndef Q_OS_WIN void MainWindow::dynamicStatus(const QString &message) { Dynamic::self()->helperMessage(message); } #endif void MainWindow::showTab(int page) { tabWidget->SetCurrentIndex(page); } void MainWindow::focusSearch() { if (searchPlayQueueLineEdit->hasFocus()) { return; } if (playQueue->hasFocus()) { searchPlayQueueLineEdit->setFocus(); } else { focusTabSearch(); } } void MainWindow::focusTabSearch() { if (libraryPage->isVisible()) { libraryPage->focusSearch(); } else if (albumsPage->isVisible()) { albumsPage->focusSearch(); } else if (folderPage->isVisible()) { folderPage->focusSearch(); } else if (playlistsPage->isVisible()) { playlistsPage->focusSearch(); } #ifndef Q_OS_WIN else if (dynamicPage->isVisible()) { dynamicPage->focusSearch(); } #endif else if (streamsPage->isVisible()) { streamsPage->focusSearch(); } #ifdef ENABLE_DEVICES_SUPPORT else if (devicesPage->isVisible()) { devicesPage->focusSearch(); } #endif } bool MainWindow::fadeWhenStop() const { return fadeStop && volumeButton->isEnabled(); } void MainWindow::expandAll() { QWidget *f=QApplication::focusWidget(); if (f && qobject_cast(f) && !qobject_cast(f)) { static_cast(f)->expandAll(); } } void MainWindow::collapseAll() { QWidget *f=QApplication::focusWidget(); if (f && qobject_cast(f) && !qobject_cast(f)) { static_cast(f)->collapseAll(); } } #ifndef Q_OS_WIN void MainWindow::toggleMpris() { bool on=Settings::self()->mpris(); if (on) { if (!mpris) { mpris=new Mpris(this); } } else { if (mpris) { mpris->deleteLater(); mpris=0; } } } void MainWindow::toggleDockManager() { if (!dock) { dock=new DockManager(this); connect(coverWidget, SIGNAL(coverFile(const QString &)), dock, SLOT(setIcon(const QString &))); } bool wasEnabled=dock->enabled(); dock->setEnabled(Settings::self()->dockManager()); if (dock->enabled() && !wasEnabled && !coverWidget->fileName().isEmpty()) { dock->setIcon(coverWidget->fileName()); } } #endif // void MainWindow::createDataCd() // { // callK3b("data"); // } // // void MainWindow::createAudioCd() // { // callK3b("audiocd"); // } // // void MainWindow::callK3b(const QString &type) // { // QStringList files; // if (libraryPage->isVisible()) { // files=libraryPage->selectedFiles(); // } else if (albumsPage->isVisible()) { // files=albumsPage->selectedFiles(); // } else if (folderPage->isVisible()) { // files=folderPage->selectedFiles(); // } else if (playlistsPage->isVisible()) { // files=playlistsPage->selectedFiles(); // } // #ifdef ENABLE_DEVICES_SUPPORT // else if (devicesPage->isVisible()) { // QList songs=devicesPage->selectedSongs(); // foreach (const Song &s, songs) { // files.append(s.file); // } // } // #endif // // if (!files.isEmpty()) { // QStringList args; // args << QLatin1String("--")+type; // foreach (const QString &f, files) { // args << Settings::self()->mpdDir()+f; // } // // QProcess *proc=new QProcess(this); // connect(proc, SIGNAL(finished(int, QProcess::ExitStatus)), proc, SLOT(deleteLater())); // proc->start(QLatin1String("k3b"), args); // } // } void MainWindow::editTags() { QList songs; if (libraryPage->isVisible()) { songs=libraryPage->selectedSongs(); } else if (albumsPage->isVisible()) { songs=albumsPage->selectedSongs(); } else if (folderPage->isVisible()) { songs=folderPage->selectedSongs(); } #ifdef ENABLE_DEVICES_SUPPORT else if (devicesPage->isVisible()) { songs=devicesPage->selectedSongs(); } #endif editTags(songs, false); } void MainWindow::editPlayQueueTags() { editTags(playQueue->selectedSongs(), true); } void MainWindow::editTags(const QList &songs, bool isPlayQueue) { if (songs.isEmpty() || 0!=TagEditor::instanceCount()) { return; } #ifdef ENABLE_DEVICES_SUPPORT if (0!=ActionDialog::instanceCount() || 0!=TrackOrganiser::instanceCount() || 0!=SyncDialog::instanceCount()) { DIALOG_ERROR; } #endif #ifdef ENABLE_REPLAYGAIN_SUPPORT if (0!=RgDialog::instanceCount()) { DIALOG_ERROR; } #endif QSet artists; QSet albumArtists; QSet albums; QSet genres; #ifdef ENABLE_DEVICES_SUPPORT QString udi; if (!isPlayQueue && devicesPage->isVisible()) { DevicesModel::self()->getDetails(artists, albumArtists, albums, genres); udi=devicesPage->activeFsDeviceUdi(); if (udi.isEmpty()) { return; } } else #else Q_UNUSED(isPlayQueue) #endif MusicLibraryModel::self()->getDetails(artists, albumArtists, albums, genres); TagEditor *dlg=new TagEditor(this, songs, artists, albumArtists, albums, genres #ifdef ENABLE_DEVICES_SUPPORT , udi #endif ); dlg->show(); } void MainWindow::organiseFiles() { if (0!=TrackOrganiser::instanceCount()) { return; } if (0!=TagEditor::instanceCount()) { DIALOG_ERROR; } #ifdef ENABLE_DEVICES_SUPPORT if (0!=ActionDialog::instanceCount() || 0!=SyncDialog::instanceCount()) { DIALOG_ERROR; } #endif #ifdef ENABLE_REPLAYGAIN_SUPPORT if (0!=RgDialog::instanceCount()) { DIALOG_ERROR; } #endif QList songs; if (libraryPage->isVisible()) { songs=libraryPage->selectedSongs(); } else if (albumsPage->isVisible()) { songs=albumsPage->selectedSongs(); } else if (folderPage->isVisible()) { songs=folderPage->selectedSongs(); } #ifdef ENABLE_DEVICES_SUPPORT else if (devicesPage->isVisible()) { songs=devicesPage->selectedSongs(); } #endif if (!songs.isEmpty()) { QString udi; #ifdef ENABLE_DEVICES_SUPPORT if (devicesPage->isVisible()) { udi=devicesPage->activeFsDeviceUdi(); if (udi.isEmpty()) { return; } } #endif TrackOrganiser *dlg=new TrackOrganiser(this); dlg->show(songs, udi); } } #ifdef ENABLE_DEVICES_SUPPORT void MainWindow::addToDevice(const QString &udi) { if (libraryPage->isVisible()) { libraryPage->addSelectionToDevice(udi); } else if (albumsPage->isVisible()) { albumsPage->addSelectionToDevice(udi); } else if (folderPage->isVisible()) { folderPage->addSelectionToDevice(udi); } } void MainWindow::deleteSongs() { if (!deleteSongsAction->isVisible()) { return; } if (libraryPage->isVisible()) { libraryPage->deleteSongs(); } else if (albumsPage->isVisible()) { albumsPage->deleteSongs(); } else if (folderPage->isVisible()) { folderPage->deleteSongs(); } else if (devicesPage->isVisible()) { devicesPage->deleteSongs(); } } void MainWindow::copyToDevice(const QString &from, const QString &to, const QList &songs) { if (songs.isEmpty() || 0!=ActionDialog::instanceCount()) { return; } if (0!=TagEditor::instanceCount()) { DIALOG_ERROR; } #ifdef ENABLE_DEVICES_SUPPORT if (0!=TrackOrganiser::instanceCount() || 0!=SyncDialog::instanceCount()) { DIALOG_ERROR; } #endif #ifdef ENABLE_REPLAYGAIN_SUPPORT if (0!=RgDialog::instanceCount()) { DIALOG_ERROR; } #endif ActionDialog *dlg=new ActionDialog(this); dlg->copy(from, to, songs); } void MainWindow::deleteSongs(const QString &from, const QList &songs) { if (songs.isEmpty() || 0!=ActionDialog::instanceCount()) { return; } if (0!=TagEditor::instanceCount()) { DIALOG_ERROR; } #ifdef ENABLE_DEVICES_SUPPORT if (0!=TrackOrganiser::instanceCount() || 0!=SyncDialog::instanceCount()) { DIALOG_ERROR; } #endif #ifdef ENABLE_REPLAYGAIN_SUPPORT if (0!=RgDialog::instanceCount()) { DIALOG_ERROR; } #endif ActionDialog *dlg=new ActionDialog(this); dlg->remove(from, songs); } #endif #ifdef ENABLE_REPLAYGAIN_SUPPORT void MainWindow::replayGain() { if (0!=RgDialog::instanceCount()) { return; } if (0!=TagEditor::instanceCount() || 0!=TrackOrganiser::instanceCount()) { DIALOG_ERROR; } #ifdef ENABLE_DEVICES_SUPPORT if (0!=ActionDialog::instanceCount() || 0!=SyncDialog::instanceCount()) { DIALOG_ERROR; } #endif QList songs; if (libraryPage->isVisible()) { songs=libraryPage->selectedSongs(); } else if (albumsPage->isVisible()) { songs=albumsPage->selectedSongs(); } else if (folderPage->isVisible()) { songs=folderPage->selectedSongs(); } #ifdef ENABLE_DEVICES_SUPPORT else if (devicesPage->isVisible()) { songs=devicesPage->selectedSongs(); } #endif if (!songs.isEmpty()) { QString udi; #ifdef ENABLE_DEVICES_SUPPORT if (devicesPage->isVisible()) { udi=devicesPage->activeFsDeviceUdi(); if (udi.isEmpty()) { return; } } #endif RgDialog *dlg=new RgDialog(this); dlg->show(songs, udi); } } #endif