Enable dragging and double clicking from the album cover manager to add albums to the playlist

Update issue #169
Status: Fixed
I hadn't forgotten about this, honest... :)
This commit is contained in:
David Sansome 2010-06-12 15:18:16 +00:00
parent efcd2c968a
commit 516f769a75
8 changed files with 233 additions and 20 deletions

View File

@ -104,6 +104,7 @@ set(SOURCES
ui/about.cpp
ui/addstreamdialog.cpp
ui/albumcovermanager.cpp
ui/albumcovermanagerlist.cpp
ui/edittagdialog.cpp
ui/equalizer.cpp
ui/globalshortcutgrabber.cpp
@ -201,6 +202,7 @@ set(HEADERS
ui/about.h
ui/addstreamdialog.h
ui/albumcovermanager.h
ui/albumcovermanagerlist.h
ui/edittagdialog.h
ui/equalizer.h
ui/globalshortcutgrabber.h

View File

@ -57,6 +57,7 @@ AlbumCoverManager::AlbumCoverManager(NetworkAccessManager* network,
missing_covers_(0)
{
ui_->setupUi(this);
ui_->albums->set_cover_manager(this);
// Icons
ui_->action_fetch->setIcon(IconLoader::Load("download"));
@ -66,6 +67,8 @@ AlbumCoverManager::AlbumCoverManager(NetworkAccessManager* network,
ui_->clear->setIcon(IconLoader::Load("edit-clear-locationbar-ltr"));
ui_->view->setIcon(IconLoader::Load("view-choose"));
ui_->fetch->setIcon(IconLoader::Load("download"));
ui_->action_add_to_playlist->setIcon(IconLoader::Load("media-playback-start"));
ui_->action_load->setIcon(IconLoader::Load("media-playback-start"));
// Get a square version of nocover.png
QImage nocover(":/nocover.png");
@ -111,6 +114,9 @@ void AlbumCoverManager::Init() {
context_menu_->addAction(ui_->action_choose_manual);
context_menu_->addSeparator();
context_menu_->addAction(ui_->action_unset_cover);
context_menu_->addSeparator();
context_menu_->addAction(ui_->action_load);
context_menu_->addAction(ui_->action_add_to_playlist);
ui_->albums->installEventFilter(this);
// Connections
@ -127,6 +133,9 @@ void AlbumCoverManager::Init() {
connect(ui_->action_fetch, SIGNAL(triggered()), SLOT(FetchSingleCover()));
connect(ui_->action_choose_manual, SIGNAL(triggered()), SLOT(ChooseManualCover()));
connect(ui_->action_unset_cover, SIGNAL(triggered()), SLOT(UnsetCover()));
connect(ui_->albums, SIGNAL(doubleClicked(QModelIndex)), SLOT(AlbumDoubleClicked(QModelIndex)));
connect(ui_->action_add_to_playlist, SIGNAL(triggered()), SLOT(AddSelectedToPlaylist()));
connect(ui_->action_load, SIGNAL(triggered()), SLOT(LoadSelectedToPlaylist()));
// Restore settings
QSettings s;
@ -239,6 +248,8 @@ void AlbumCoverManager::ArtistChanged(QListWidgetItem* current) {
QListWidgetItem* item = new QListWidgetItem(no_cover_icon_, info.album_name, ui_->albums);
item->setData(Role_ArtistName, info.artist);
item->setData(Role_AlbumName, info.album_name);
item->setData(Qt::TextAlignmentRole, QVariant(Qt::AlignTop | Qt::AlignHCenter));
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled);
if (!info.art_automatic.isEmpty() || !info.art_manual.isEmpty()) {
quint64 id = cover_loader_->Worker()->LoadImageAsync(
@ -497,3 +508,49 @@ void AlbumCoverManager::UnsetCover() {
AlbumCoverLoader::kManuallyUnsetCover);
}
}
SongList AlbumCoverManager::GetSongsInAlbum(const QModelIndex& index) const {
SongList ret;
LibraryQuery q;
q.SetColumnSpec("ROWID," + Song::kColumnSpec);
q.AddWhere("album", index.data(Role_AlbumName).toString());
q.SetOrderBy("disc, track, title");
QString artist = index.data(Role_ArtistName).toString();
q.AddCompilationRequirement(artist.isEmpty());
if (!artist.isEmpty())
q.AddWhere("artist", artist);
if (!backend_->ExecQuery(&q))
return ret;
while (q.Next()) {
Song song;
song.InitFromQuery(q);
ret << song;
}
return ret;
}
SongList AlbumCoverManager::GetSongsInAlbums(const QModelIndexList& indexes) const {
SongList ret;
foreach (const QModelIndex& index, indexes) {
ret << GetSongsInAlbum(index);
}
return ret;
}
void AlbumCoverManager::AlbumDoubleClicked(const QModelIndex &index) {
emit SongsDoubleClicked(GetSongsInAlbum(index));
}
void AlbumCoverManager::AddSelectedToPlaylist() {
emit AddSongsToPlaylist(GetSongsInAlbums(
ui_->albums->selectionModel()->selectedIndexes()));
}
void AlbumCoverManager::LoadSelectedToPlaylist() {
emit LoadSongsToPlaylist(GetSongsInAlbums(
ui_->albums->selectionModel()->selectedIndexes()));
}

View File

@ -19,11 +19,13 @@
#include <QMainWindow>
#include <QIcon>
#include <QModelIndex>
#include "gtest/gtest_prod.h"
#include "core/albumcoverloader.h"
#include "core/backgroundthread.h"
#include "core/song.h"
class LibraryBackend;
class AlbumCoverFetcher;
@ -43,10 +45,19 @@ class AlbumCoverManager : public QMainWindow {
static const char* kSettingsGroup;
void Reset();
LibraryBackend* backend() const { return backend_; }
void Reset();
void Init();
SongList GetSongsInAlbum(const QModelIndex& index) const;
SongList GetSongsInAlbums(const QModelIndexList& indexes) const;
signals:
void AddSongsToPlaylist(const SongList& songs);
void LoadSongsToPlaylist(const SongList& songs);
void SongsDoubleClicked(const SongList& songs);
protected:
void showEvent(QShowEvent *);
void closeEvent(QCloseEvent *);
@ -69,6 +80,11 @@ class AlbumCoverManager : public QMainWindow {
void ChooseManualCover();
void UnsetCover();
// For adding albums to the playlist
void AlbumDoubleClicked(const QModelIndex& index);
void AddSelectedToPlaylist();
void LoadSelectedToPlaylist();
private:
enum ArtistItemType {
All_Artists,

View File

@ -115,7 +115,13 @@
</layout>
</item>
<item>
<widget class="QListWidget" name="albums">
<widget class="AlbumCoverManagerList" name="albums">
<property name="dragEnabled">
<bool>true</bool>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::DragOnly</enum>
</property>
<property name="alternatingRowColors">
<bool>false</bool>
</property>
@ -128,9 +134,6 @@
<height>120</height>
</size>
</property>
<property name="movement">
<enum>QListView::Static</enum>
</property>
<property name="flow">
<enum>QListView::LeftToRight</enum>
</property>
@ -181,6 +184,16 @@
<string>Unset cover</string>
</property>
</action>
<action name="action_load">
<property name="text">
<string>Load</string>
</property>
</action>
<action name="action_add_to_playlist">
<property name="text">
<string>Add to playlist</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
@ -188,6 +201,11 @@
<extends>QLineEdit</extends>
<header>widgets/lineedit.h</header>
</customwidget>
<customwidget>
<class>AlbumCoverManagerList</class>
<extends>QListWidget</extends>
<header>ui/albumcovermanagerlist.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>artists</tabstop>

View File

@ -0,0 +1,57 @@
/* This file is part of Clementine.
Clementine 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 3 of the License, or
(at your option) any later version.
Clementine 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 Clementine. If not, see <http://www.gnu.org/licenses/>.
*/
#include "albumcovermanager.h"
#include "albumcovermanagerlist.h"
#include "playlist/songmimedata.h"
#include <boost/scoped_ptr.hpp>
#include <QUrl>
#include <QtDebug>
AlbumCoverManagerList::AlbumCoverManagerList(QWidget *parent)
: QListWidget(parent),
manager_(NULL)
{
}
QMimeData* AlbumCoverManagerList::mimeData(const QList<QListWidgetItem*> items) const {
// Get songs
SongList songs;
foreach (QListWidgetItem* item, items) {
songs << manager_->GetSongsInAlbum(indexFromItem(item));
}
if (songs.isEmpty())
return NULL;
// Get URLs from the songs
QList<QUrl> urls;
foreach (const Song& song, songs) {
urls << QUrl::fromLocalFile(song.filename());
}
// Get the QAbstractItemModel data so the picture works
boost::scoped_ptr<QMimeData> orig_data(QListWidget::mimeData(items));
SongMimeData* mime_data = new SongMimeData;
mime_data->backend = manager_->backend();
mime_data->songs = songs;
mime_data->setUrls(urls);
mime_data->setData(orig_data->formats()[0], orig_data->data(orig_data->formats()[0]));
return mime_data;
}

View File

@ -0,0 +1,38 @@
/* This file is part of Clementine.
Clementine 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 3 of the License, or
(at your option) any later version.
Clementine 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 Clementine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ALBUMCOVERMANAGERLIST_H
#define ALBUMCOVERMANAGERLIST_H
#include <QListWidget>
class AlbumCoverManager;
class AlbumCoverManagerList : public QListWidget {
Q_OBJECT
public:
AlbumCoverManagerList(QWidget *parent = 0);
void set_cover_manager(AlbumCoverManager* manager) { manager_ = manager; }
protected:
QMimeData* mimeData(const QList<QListWidgetItem*> items) const;
private:
AlbumCoverManager* manager_;
};
#endif // ALBUMCOVERMANAGERLIST_H

View File

@ -215,6 +215,11 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
connect(ui_->file_view, SIGNAL(DoubleClicked(QList<QUrl>)), SLOT(FilesDoubleClicked(QList<QUrl>)));
connect(ui_->file_view, SIGNAL(PathChanged(QString)), SLOT(FilePathChanged(QString)));
// Cover manager connections
connect(cover_manager_.get(), SIGNAL(AddSongsToPlaylist(SongList)), SLOT(AddLibrarySongsToPlaylist(SongList)));
connect(cover_manager_.get(), SIGNAL(LoadSongsToPlaylist(SongList)), SLOT(LoadLibrarySongsToPlaylist(SongList)));
connect(cover_manager_.get(), SIGNAL(SongsDoubleClicked(SongList)), SLOT(LibrarySongsDoubleClicked(SongList)));
// Action connections
connect(ui_->action_next_track, SIGNAL(triggered()), player_, SLOT(Next()));
connect(ui_->action_previous_track, SIGNAL(triggered()), player_, SLOT(Previous()));
@ -542,6 +547,35 @@ void MainWindow::AddFilesToPlaylist(bool clear_first, const QList<QUrl>& urls) {
}
}
void MainWindow::AddLibrarySongsToPlaylist(const SongList &songs) {
AddLibrarySongsToPlaylist(false, songs);
}
void MainWindow::LoadLibrarySongsToPlaylist(const SongList &songs) {
AddLibrarySongsToPlaylist(true, songs);
}
void MainWindow::LibrarySongsDoubleClicked(const SongList &songs) {
AddLibrarySongsToPlaylist(autoclear_playlist_, songs);
}
void MainWindow::AddLibrarySongsToPlaylist(bool clear_first, const SongList &songs) {
if (clear_first)
playlists_->ClearCurrent();
QModelIndex first_song = playlists_->current()->InsertLibraryItems(songs);
if (!playlists_->current()->proxy()->mapFromSource(first_song).isValid()) {
// The first song doesn't match the filter, so don't play it
return;
}
if (first_song.isValid() && player_->GetState() != Engine::Playing) {
playlists_->SetActiveToCurrent();
player_->PlayAt(first_song.row(), Engine::First, true);
}
}
void MainWindow::MediaStopped() {
ui_->action_stop->setEnabled(false);
ui_->action_stop_after_this_track->setEnabled(false);
@ -655,21 +689,7 @@ void MainWindow::AddLibraryItemToPlaylist(bool clear_first, const QModelIndexLis
source_indexes << index;
}
if (clear_first)
playlists_->ClearCurrent();
QModelIndex first_song = playlists_->current()->InsertLibraryItems(
library_->model()->GetChildSongs(source_indexes));
if (!playlists_->current()->proxy()->mapFromSource(first_song).isValid()) {
// The first song doesn't match the filter, so don't play it
return;
}
if (first_song.isValid() && player_->GetState() != Engine::Playing) {
playlists_->SetActiveToCurrent();
player_->PlayAt(first_song.row(), Engine::First, true);
}
AddLibrarySongsToPlaylist(clear_first, library_->model()->GetChildSongs(source_indexes));
}
void MainWindow::VolumeWheelEvent(int delta) {

View File

@ -118,6 +118,10 @@ class MainWindow : public QMainWindow {
void AddFilesToPlaylist(const QList<QUrl>& urls);
void FilesDoubleClicked(const QList<QUrl>& urls);
void LoadLibrarySongsToPlaylist(const SongList& songs);
void AddLibrarySongsToPlaylist(const SongList& songs);
void LibrarySongsDoubleClicked(const SongList& songs);
void VolumeWheelEvent(int delta);
void TrayClicked(QSystemTrayIcon::ActivationReason reason);
@ -149,6 +153,7 @@ class MainWindow : public QMainWindow {
void SaveGeometry();
void AddFilesToPlaylist(bool clear_first, const QList<QUrl>& urls);
void AddLibraryItemToPlaylist(bool clear_first, const QModelIndexList& indexes);
void AddLibrarySongsToPlaylist(bool clear_first, const SongList& songs);
private:
static const int kStateVersion;