/* * Cantata * * Copyright (c) 2011 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 "mpdconnection.h" #include "mpdparseutils.h" #include "covers.h" #include "musiclibraryitemalbum.h" #include "musiclibraryitemsong.h" #include "mainwindow.h" #include #include #ifdef ENABLE_KDE_SUPPORT #include #include #include #include #else #include #endif LibraryPage::LibraryPage(MainWindow *p) : QWidget(p) { setupUi(this); addToPlaylist->setDefaultAction(p->addToPlaylistAction); replacePlaylist->setDefaultAction(p->replacePlaylistAction); libraryUpdate->setDefaultAction(p->updateDbAction); addToPlaylist->setAutoRaise(true); replacePlaylist->setAutoRaise(true); libraryUpdate->setAutoRaise(true); addToPlaylist->setEnabled(false); replacePlaylist->setEnabled(false); view->addAction(p->addToPlaylistAction); view->addAction(p->replacePlaylistAction); view->addAction(p->addToStoredPlaylistAction); connect(this, SIGNAL(add(const QStringList &)), MPDConnection::self(), SLOT(add(const QStringList &))); connect(this, SIGNAL(addSongsToPlaylist(const QString &, const QStringList &)), MPDConnection::self(), SLOT(addToPlaylist(const QString &, const QStringList &))); connect(genreCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(searchItems())); connect(MPDConnection::self(), SIGNAL(musicLibraryUpdated(MusicLibraryItemRoot *, QDateTime)), &model, SLOT(updateMusicLibrary(MusicLibraryItemRoot *, QDateTime))); connect(Covers::self(), SIGNAL(cover(const QString &, const QString &, const QImage &)), &model, SLOT(setCover(const QString &, const QString &, const QImage &))); connect(&model, SIGNAL(updateGenres(const QStringList &)), this, SLOT(updateGenres(const QStringList &))); connect(this, SIGNAL(listAllInfo(const QDateTime &)), MPDConnection::self(), SLOT(listAllInfo(const QDateTime &))); connect(view, SIGNAL(itemsSelected(bool)), addToPlaylist, SLOT(setEnabled(bool))); connect(view, SIGNAL(itemsSelected(bool)), replacePlaylist, SLOT(setEnabled(bool))); connect(view, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(itemDoubleClicked(const QModelIndex &))); connect(view, SIGNAL(searchItems()), this, SLOT(searchItems())); proxy.setSourceModel(&model); #ifdef ENABLE_KDE_SUPPORT view->setTopText(i18n("Library")); #else view->setTopText(tr("Library")); #endif view->setModel(&proxy); view->init(p->replacePlaylistAction, p->addToPlaylistAction); } LibraryPage::~LibraryPage() { } void LibraryPage::refresh(Refresh type) { view->setLevel(0); if (RefreshForce==type) { model.clearUpdateTime(); } if (RefreshFromCache!=type || !model.fromXML(MPDStats::self()->dbUpdate())) { emit listAllInfo(MPDStats::self()->dbUpdate()); } } void LibraryPage::clear() { model.clear(); view->setLevel(0); } void LibraryPage::addSelectionToPlaylist(const QString &name) { QStringList files; MusicLibraryItem *item; MusicLibraryItemSong *songItem; QModelIndexList selected = view->selectedIndexes(); // Loop over the selection. Only add files. foreach (const QModelIndex &idx, selected) { item = static_cast(proxy.mapToSource(idx).internalPointer()); switch (item->type()) { case MusicLibraryItem::Type_Artist: { for (quint32 i = 0; ; i++) { const QModelIndex album = idx.child(i , 0); if (!album.isValid()) break; for (quint32 j = 0; ; j++) { const QModelIndex track = album.child(j, 0); if (!track.isValid()) break; const QModelIndex mappedSongIndex = proxy.mapToSource(track); songItem = static_cast(mappedSongIndex.internalPointer()); const QString fileName = songItem->file(); if (!fileName.isEmpty() && !files.contains(fileName)) files.append(fileName); } } break; } case MusicLibraryItem::Type_Album: { for (quint32 i = 0; ; i++) { QModelIndex track = idx.child(i, 0); if (!track.isValid()) break; const QModelIndex mappedSongIndex = proxy.mapToSource(track); songItem = static_cast(mappedSongIndex.internalPointer()); const QString fileName = songItem->file(); if (!fileName.isEmpty() && !files.contains(fileName)) files.append(fileName); } break; } case MusicLibraryItem::Type_Song: { const QString fileName = static_cast(item)->file(); if (!fileName.isEmpty() && !files.contains(fileName)) files.append(fileName); break; } default: break; } } if (!files.isEmpty()) { if (name.isEmpty()) { emit add(files); } else { emit addSongsToPlaylist(name, files); } view->clearSelection(); } } void LibraryPage::itemDoubleClicked(const QModelIndex &) { const QModelIndexList selected = view->selectedIndexes(); if (1!=selected.size()) { return; //doubleclick should only have one selected item } MusicLibraryItem *item = static_cast(proxy.mapToSource(selected.at(0)).internalPointer()); if (MusicLibraryItem::Type_Song==item->type()) { addSelectionToPlaylist(); } } void LibraryPage::searchItems() { proxy.setFilterGenre(0==genreCombo->currentIndex() ? QString() : genreCombo->currentText()); proxy.setFilterRegExp(view->searchText()); } void LibraryPage::updateGenres(const QStringList &genres) { QStringList entries; #ifdef ENABLE_KDE_SUPPORT entries << i18n("All Genres"); #else entries << tr("All Genres"); #endif entries+=genres; bool diff=genreCombo->count() != entries.count(); if (!diff) { // Check items... for (int i=1; icount() && !diff; ++i) { if (genreCombo->itemText(i) != entries.at(i)) { diff=true; } } } if (!diff) { return; } QString currentFilter = genreCombo->currentIndex() ? genreCombo->currentText() : QString(); genreCombo->clear(); if (genres.count()<2) { genreCombo->setCurrentIndex(0); } else { genreCombo->addItems(entries); if (!currentFilter.isEmpty()) { bool found=false; for (int i=1; icount() && !found; ++i) { if (genreCombo->itemText(i) == currentFilter) { genreCombo->setCurrentIndex(i); found=true; } } if (!found) { genreCombo->setCurrentIndex(0); } } } }