/* * Cantata * * Copyright (c) 2011-2014 Craig Drummond * * ---- * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "librarypage.h" #include "mpd-interface/mpdconnection.h" #include "mpd-interface/mpdstats.h" #include "covers.h" #include "support/localize.h" #include "support/messagebox.h" #include "settings.h" #include "stdactions.h" #include "support/utils.h" #include "models/mpdlibrarymodel.h" LibraryPage::LibraryPage(QWidget *p) : QWidget(p) { setupUi(this); addToPlayQueue->setDefaultAction(StdActions::self()->addToPlayQueueAction); replacePlayQueue->setDefaultAction(StdActions::self()->replacePlayQueueAction); view->addAction(StdActions::self()->addToPlayQueueAction); view->addAction(StdActions::self()->replacePlayQueueAction); view->addAction(StdActions::self()->addWithPriorityAction); view->addAction(StdActions::self()->addToStoredPlaylistAction); #ifdef TAGLIB_FOUND #ifdef ENABLE_DEVICES_SUPPORT view->addAction(StdActions::self()->copyToDeviceAction); #endif view->addAction(StdActions::self()->organiseFilesAction); view->addAction(StdActions::self()->editTagsAction); #ifdef ENABLE_REPLAYGAIN_SUPPORT view->addAction(StdActions::self()->replaygainAction); #endif view->addAction(StdActions::self()->setCoverAction); #ifdef ENABLE_DEVICES_SUPPORT view->addSeparator(); view->addAction(StdActions::self()->deleteSongsAction); #endif #endif // TAGLIB_FOUND connect(this, SIGNAL(add(const QStringList &, bool, quint8)), MPDConnection::self(), SLOT(add(const QStringList &, bool, quint8))); connect(this, SIGNAL(addSongsToPlaylist(const QString &, const QStringList &)), MPDConnection::self(), SLOT(addToPlaylist(const QString &, const QStringList &))); connect(MPDConnection::self(), SIGNAL(updatingLibrary(time_t)), view, SLOT(updating())); connect(MPDConnection::self(), SIGNAL(updatedLibrary()), view, SLOT(updated())); connect(MPDConnection::self(), SIGNAL(updatingDatabase()), view, SLOT(updating())); connect(MPDConnection::self(), SIGNAL(updatedDatabase()), view, SLOT(updated())); connect(this, SIGNAL(loadLibrary()), MPDConnection::self(), SLOT(loadLibrary())); connect(view, SIGNAL(itemsSelected(bool)), this, SLOT(controlActions())); connect(view, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(itemDoubleClicked(const QModelIndex &))); connect(view, SIGNAL(searchItems()), this, SLOT(searchItems())); view->setModel(MpdLibraryModel::self()); view->load(metaObject()->className()); } LibraryPage::~LibraryPage() { view->save(metaObject()->className()); } void LibraryPage::showEvent(QShowEvent *e) { view->focusView(); QWidget::showEvent(e); } void LibraryPage::clear() { MpdLibraryModel::self()->clear(); view->goToTop(); } static inline QString nameKey(const QString &artist, const QString &album) { return '{'+artist+"}{"+album+'}'; } QStringList LibraryPage::selectedFiles(bool allowPlaylists) const { QModelIndexList selected = view->selectedIndexes(); if (selected.isEmpty()) { return QStringList(); } return MpdLibraryModel::self()->filenames(selected, allowPlaylists); } QList LibraryPage::selectedSongs(bool allowPlaylists) const { QModelIndexList selected = view->selectedIndexes(); if (selected.isEmpty()) { return QList(); } return MpdLibraryModel::self()->songs(selected, allowPlaylists); } Song LibraryPage::coverRequest() const { QModelIndexList selected = view->selectedIndexes(false); // Dont need sorted selection here... if (1==selected.count()) { QList songs=MpdLibraryModel::self()->songs(QModelIndexList() << selected.first(), false); if (!songs.isEmpty()) { Song s=songs.at(0); if (SqlLibraryModel::T_Artist==static_cast(selected.first().internalPointer())->getType() && !s.useComposer()) { s.setArtistImageRequest(); } return s; } } return Song(); } void LibraryPage::addSelectionToPlaylist(const QString &name, bool replace, quint8 priorty) { QStringList files=selectedFiles(name.isEmpty()); if (!files.isEmpty()) { if (name.isEmpty()) { emit add(files, replace, priorty); } else { emit addSongsToPlaylist(name, files); } view->clearSelection(); } } #ifdef ENABLE_DEVICES_SUPPORT void LibraryPage::addSelectionToDevice(const QString &udi) { QList songs=selectedSongs(); if (!songs.isEmpty()) { emit addToDevice(QString(), udi, songs); view->clearSelection(); } } void LibraryPage::deleteSongs() { QList songs=selectedSongs(); if (!songs.isEmpty()) { if (MessageBox::Yes==MessageBox::warningYesNo(this, i18n("Are you sure you wish to delete the selected songs?\n\nThis cannot be undone."), i18n("Delete Songs"), StdGuiItem::del(), StdGuiItem::cancel())) { emit deleteSongs(QString(), songs); } view->clearSelection(); } } #endif void LibraryPage::showSongs(const QList &songs) { // Filter out non-mpd file songs... QList sngs; foreach (const Song &s, songs) { if (!s.file.isEmpty() && !s.file.contains(":/") && !s.file.startsWith('/')) { sngs.append(s); } } if (sngs.isEmpty()) { return; } view->clearSearchText(); bool first=true; foreach (const Song &s, sngs) { QModelIndex idx=MpdLibraryModel::self()->findSongIndex(s); if (idx.isValid()) { if (ItemView::Mode_SimpleTree==view->viewMode() || ItemView::Mode_DetailedTree==view->viewMode() || first) { view->showIndex(idx, first); } if (first) { first=false; } if (ItemView::Mode_SimpleTree!=view->viewMode() && ItemView::Mode_DetailedTree!=view->viewMode()) { return; } } } } void LibraryPage::showArtist(const QString &artist) { view->clearSearchText(); QModelIndex idx=MpdLibraryModel::self()->findArtistIndex(artist); if (idx.isValid()) { view->showIndex(idx, true); if (ItemView::Mode_SimpleTree==view->viewMode() || ItemView::Mode_DetailedTree==view->viewMode()) { view->setExpanded(idx); } } } void LibraryPage::showAlbum(const QString &artist, const QString &album) { view->clearSearchText(); QModelIndex idx=MpdLibraryModel::self()->findAlbumIndex(artist, album); if (idx.isValid()) { view->showIndex(idx, true); if (ItemView::Mode_SimpleTree==view->viewMode() || ItemView::Mode_DetailedTree==view->viewMode()) { view->setExpanded(idx.parent()); view->setExpanded(idx); } } } void LibraryPage::itemDoubleClicked(const QModelIndex &) { const QModelIndexList selected = view->selectedIndexes(false); // Dont need sorted selection here... if (1!=selected.size()) { return; //doubleclick should only have one selected item } SqlLibraryModel::Item *item = static_cast(selected.at(0).internalPointer()); if (SqlLibraryModel::T_Track==item->getType()) { addSelectionToPlaylist(); } } void LibraryPage::searchItems() { MpdLibraryModel::self()->search(view->searchText()); } void LibraryPage::controlActions() { QModelIndexList selected=view->selectedIndexes(false); // Dont need sorted selection here... bool enable=selected.count()>0; StdActions::self()->addToPlayQueueAction->setEnabled(enable); StdActions::self()->addWithPriorityAction->setEnabled(enable); StdActions::self()->replacePlayQueueAction->setEnabled(enable); StdActions::self()->addToStoredPlaylistAction->setEnabled(enable); #ifdef TAGLIB_FOUND StdActions::self()->organiseFilesAction->setEnabled(enable && MPDConnection::self()->getDetails().dirReadable); StdActions::self()->editTagsAction->setEnabled(StdActions::self()->organiseFilesAction->isEnabled()); #ifdef ENABLE_REPLAYGAIN_SUPPORT StdActions::self()->replaygainAction->setEnabled(StdActions::self()->organiseFilesAction->isEnabled()); #endif #ifdef ENABLE_DEVICES_SUPPORT StdActions::self()->deleteSongsAction->setEnabled(StdActions::self()->organiseFilesAction->isEnabled()); StdActions::self()->copyToDeviceAction->setEnabled(StdActions::self()->organiseFilesAction->isEnabled()); #endif #endif // TAGLIB_FOUND if (1==selected.count()) { SqlLibraryModel::Item *item=static_cast(selected.at(0).internalPointer()); SqlLibraryModel::Type type=item->getType(); StdActions::self()->setCoverAction->setEnabled((SqlLibraryModel::T_Artist==type/* && !static_cast(item)->isComposer()*/) || SqlLibraryModel::T_Album==type); } else { StdActions::self()->setCoverAction->setEnabled(false); } bool allowRandomAlbum=!selected.isEmpty(); if (allowRandomAlbum) { foreach (const QModelIndex &idx, selected) { if (SqlLibraryModel::T_Track==static_cast(idx.internalPointer())->getType()) { allowRandomAlbum=false; break; } } } }