Playlist fixes
- Fix bug resetting playlist view columns to show all when using more than one playlist. - Add queue to play next
This commit is contained in:
@@ -458,6 +458,7 @@ void CollectionView::contextMenuEvent(QContextMenuEvent *e) {
|
|||||||
|
|
||||||
context_menu_->addSeparator();
|
context_menu_->addSeparator();
|
||||||
add_to_playlist_enqueue_ = context_menu_->addAction(IconLoader::Load("go-next"), tr("Queue track"), this, SLOT(AddToPlaylistEnqueue()));
|
add_to_playlist_enqueue_ = context_menu_->addAction(IconLoader::Load("go-next"), tr("Queue track"), this, SLOT(AddToPlaylistEnqueue()));
|
||||||
|
add_to_playlist_enqueue_next_ = context_menu_->addAction(IconLoader::Load("go-next"), tr("Queue to play next"), this, SLOT(AddToPlaylistEnqueueNext()));
|
||||||
|
|
||||||
#ifdef HAVE_GSTREAMER
|
#ifdef HAVE_GSTREAMER
|
||||||
context_menu_->addSeparator();
|
context_menu_->addSeparator();
|
||||||
@@ -616,6 +617,16 @@ void CollectionView::AddToPlaylistEnqueue() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CollectionView::AddToPlaylistEnqueueNext() {
|
||||||
|
|
||||||
|
QMimeData *data = model()->mimeData(selectedIndexes());
|
||||||
|
if (MimeData *mime_data = qobject_cast<MimeData*>(data)) {
|
||||||
|
mime_data->enqueue_next_now_ = true;
|
||||||
|
}
|
||||||
|
emit AddToPlaylistSignal(data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void CollectionView::OpenInNewPlaylist() {
|
void CollectionView::OpenInNewPlaylist() {
|
||||||
|
|
||||||
QMimeData *data = model()->mimeData(selectedIndexes());
|
QMimeData *data = model()->mimeData(selectedIndexes());
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ signals:
|
|||||||
void Load();
|
void Load();
|
||||||
void AddToPlaylist();
|
void AddToPlaylist();
|
||||||
void AddToPlaylistEnqueue();
|
void AddToPlaylistEnqueue();
|
||||||
|
void AddToPlaylistEnqueueNext();
|
||||||
void OpenInNewPlaylist();
|
void OpenInNewPlaylist();
|
||||||
#ifdef HAVE_GSTREAMER
|
#ifdef HAVE_GSTREAMER
|
||||||
void Organise();
|
void Organise();
|
||||||
@@ -148,6 +149,7 @@ signals:
|
|||||||
QAction *load_;
|
QAction *load_;
|
||||||
QAction *add_to_playlist_;
|
QAction *add_to_playlist_;
|
||||||
QAction *add_to_playlist_enqueue_;
|
QAction *add_to_playlist_enqueue_;
|
||||||
|
QAction *add_to_playlist_enqueue_next_;
|
||||||
QAction *open_in_new_playlist_;
|
QAction *open_in_new_playlist_;
|
||||||
#ifdef HAVE_GSTREAMER
|
#ifdef HAVE_GSTREAMER
|
||||||
QAction *organise_;
|
QAction *organise_;
|
||||||
|
|||||||
@@ -544,6 +544,10 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
|
|||||||
playlist_queue_->setVisible(false);
|
playlist_queue_->setVisible(false);
|
||||||
playlist_queue_->setShortcut(QKeySequence("Ctrl+D"));
|
playlist_queue_->setShortcut(QKeySequence("Ctrl+D"));
|
||||||
ui_->playlist->addAction(playlist_queue_);
|
ui_->playlist->addAction(playlist_queue_);
|
||||||
|
playlist_queue_play_next_ = playlist_menu_->addAction(IconLoader::Load("go-next"), tr("Queue selected tracks to play next"), this, SLOT(PlaylistQueuePlayNext()));
|
||||||
|
playlist_queue_play_next_->setShortcut(QKeySequence("Ctrl+Shift+D"));
|
||||||
|
playlist_queue_play_next_->setVisible(false);
|
||||||
|
ui_->playlist->addAction(playlist_queue_play_next_);
|
||||||
playlist_skip_ = playlist_menu_->addAction(IconLoader::Load("media-forward"), tr("Toggle skip status"), this, SLOT(PlaylistSkip()));
|
playlist_skip_ = playlist_menu_->addAction(IconLoader::Load("media-forward"), tr("Toggle skip status"), this, SLOT(PlaylistSkip()));
|
||||||
playlist_skip_->setVisible(false);
|
playlist_skip_->setVisible(false);
|
||||||
ui_->playlist->addAction(playlist_skip_);
|
ui_->playlist->addAction(playlist_skip_);
|
||||||
@@ -1401,10 +1405,12 @@ void MainWindow::PlaylistRightClick(const QPoint &global_pos, const QModelIndex
|
|||||||
|
|
||||||
if (selected < 1) {
|
if (selected < 1) {
|
||||||
playlist_queue_->setVisible(false);
|
playlist_queue_->setVisible(false);
|
||||||
|
playlist_queue_play_next_->setVisible(false);
|
||||||
playlist_skip_->setVisible(false);
|
playlist_skip_->setVisible(false);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
playlist_queue_->setVisible(true);
|
playlist_queue_->setVisible(true);
|
||||||
|
playlist_queue_play_next_->setVisible(true);
|
||||||
playlist_skip_->setVisible(true);
|
playlist_skip_->setVisible(true);
|
||||||
if (in_queue == 1 && not_in_queue == 0) playlist_queue_->setText(tr("Dequeue track"));
|
if (in_queue == 1 && not_in_queue == 0) playlist_queue_->setText(tr("Dequeue track"));
|
||||||
else if (in_queue > 1 && not_in_queue == 0) playlist_queue_->setText(tr("Dequeue selected tracks"));
|
else if (in_queue > 1 && not_in_queue == 0) playlist_queue_->setText(tr("Dequeue selected tracks"));
|
||||||
@@ -1412,6 +1418,11 @@ void MainWindow::PlaylistRightClick(const QPoint &global_pos, const QModelIndex
|
|||||||
else if (in_queue == 0 && not_in_queue > 1) playlist_queue_->setText(tr("Queue selected tracks"));
|
else if (in_queue == 0 && not_in_queue > 1) playlist_queue_->setText(tr("Queue selected tracks"));
|
||||||
else playlist_queue_->setText(tr("Toggle queue status"));
|
else playlist_queue_->setText(tr("Toggle queue status"));
|
||||||
|
|
||||||
|
if (selected > 1)
|
||||||
|
playlist_queue_play_next_->setText(tr("Queue selected tracks to play next"));
|
||||||
|
else
|
||||||
|
playlist_queue_play_next_->setText(tr("Queue to play next"));
|
||||||
|
|
||||||
if (in_skipped == 1 && not_in_skipped == 0) playlist_skip_->setText(tr("Unskip track"));
|
if (in_skipped == 1 && not_in_skipped == 0) playlist_skip_->setText(tr("Unskip track"));
|
||||||
else if (in_skipped > 1 && not_in_skipped == 0) playlist_skip_->setText(tr("Unskip selected tracks"));
|
else if (in_skipped > 1 && not_in_skipped == 0) playlist_skip_->setText(tr("Unskip selected tracks"));
|
||||||
else if (in_skipped == 0 && not_in_skipped == 1) playlist_skip_->setText(tr("Skip track"));
|
else if (in_skipped == 0 && not_in_skipped == 1) playlist_skip_->setText(tr("Skip track"));
|
||||||
@@ -2037,6 +2048,15 @@ void MainWindow::PlaylistQueue() {
|
|||||||
app_->playlist_manager()->current()->queue()->ToggleTracks(indexes);
|
app_->playlist_manager()->current()->queue()->ToggleTracks(indexes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::PlaylistQueuePlayNext() {
|
||||||
|
QModelIndexList indexes;
|
||||||
|
for (const QModelIndex& proxy_index : ui_->playlist->view()->selectionModel()->selectedRows()) {
|
||||||
|
indexes << app_->playlist_manager()->current()->proxy()->mapToSource(proxy_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
app_->playlist_manager()->current()->queue()->InsertFirst(indexes);
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::PlaylistSkip() {
|
void MainWindow::PlaylistSkip() {
|
||||||
|
|
||||||
QModelIndexList indexes;
|
QModelIndexList indexes;
|
||||||
|
|||||||
@@ -168,6 +168,7 @@ signals:
|
|||||||
void PlaylistPlay();
|
void PlaylistPlay();
|
||||||
void PlaylistStopAfter();
|
void PlaylistStopAfter();
|
||||||
void PlaylistQueue();
|
void PlaylistQueue();
|
||||||
|
void PlaylistQueuePlayNext();
|
||||||
void PlaylistSkip();
|
void PlaylistSkip();
|
||||||
void PlaylistRemoveCurrent();
|
void PlaylistRemoveCurrent();
|
||||||
void PlaylistEditFinished(const QModelIndex& index);
|
void PlaylistEditFinished(const QModelIndex& index);
|
||||||
@@ -360,6 +361,7 @@ signals:
|
|||||||
#endif
|
#endif
|
||||||
QAction *playlist_open_in_browser_;
|
QAction *playlist_open_in_browser_;
|
||||||
QAction *playlist_queue_;
|
QAction *playlist_queue_;
|
||||||
|
QAction* playlist_queue_play_next_;
|
||||||
QAction *playlist_skip_;
|
QAction *playlist_skip_;
|
||||||
QAction *playlist_add_to_another_;
|
QAction *playlist_add_to_another_;
|
||||||
QList<QAction*> playlistitem_actions_;
|
QList<QAction*> playlistitem_actions_;
|
||||||
|
|||||||
@@ -31,11 +31,12 @@ class MimeData : public QMimeData {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MimeData(bool clear = false, bool play_now = false, bool enqueue = false, bool open_in_new_playlist = false)
|
MimeData(bool clear = false, bool play_now = false, bool enqueue = false, bool enqueue_next_now = false, bool open_in_new_playlist = false)
|
||||||
: override_user_settings_(false),
|
: override_user_settings_(false),
|
||||||
clear_first_(clear),
|
clear_first_(clear),
|
||||||
play_now_(play_now),
|
play_now_(play_now),
|
||||||
enqueue_now_(enqueue),
|
enqueue_now_(enqueue),
|
||||||
|
enqueue_next_now_(enqueue_next_now),
|
||||||
open_in_new_playlist_(open_in_new_playlist),
|
open_in_new_playlist_(open_in_new_playlist),
|
||||||
name_for_new_playlist_(QString()),
|
name_for_new_playlist_(QString()),
|
||||||
from_doubleclick_(false) {}
|
from_doubleclick_(false) {}
|
||||||
|
|||||||
@@ -657,7 +657,7 @@ bool Playlist::dropMimeData(const QMimeData *data, Qt::DropAction action, int ro
|
|||||||
// Dragged from a collection
|
// Dragged from a collection
|
||||||
// We want to check if these songs are from the actual local file backend, if they are we treat them differently.
|
// We want to check if these songs are from the actual local file backend, if they are we treat them differently.
|
||||||
if (song_data->backend && song_data->backend->songs_table() == SCollection::kSongsTable)
|
if (song_data->backend && song_data->backend->songs_table() == SCollection::kSongsTable)
|
||||||
InsertSongItems<CollectionPlaylistItem>(song_data->songs, row, play_now, enqueue_now);
|
InsertSongItems<CollectionPlaylistItem>(song_data->songs, row, play_now, enqueue_now, enqueue_next_now);
|
||||||
else
|
else
|
||||||
InsertSongItems<SongPlaylistItem>(song_data->songs, row, play_now, enqueue_now, enqueue_next_now);
|
InsertSongItems<SongPlaylistItem>(song_data->songs, row, play_now, enqueue_now, enqueue_next_now);
|
||||||
}
|
}
|
||||||
@@ -700,7 +700,7 @@ bool Playlist::dropMimeData(const QMimeData *data, Qt::DropAction action, int ro
|
|||||||
|
|
||||||
if (items.count() > kUndoItemLimit) {
|
if (items.count() > kUndoItemLimit) {
|
||||||
// Too big to keep in the undo stack. Also clear the stack because it might have been invalidated.
|
// Too big to keep in the undo stack. Also clear the stack because it might have been invalidated.
|
||||||
InsertItemsWithoutUndo(items, row, false);
|
InsertItemsWithoutUndo(items, row, false, false);
|
||||||
undo_stack_->clear();
|
undo_stack_->clear();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -718,11 +718,11 @@ bool Playlist::dropMimeData(const QMimeData *data, Qt::DropAction action, int ro
|
|||||||
else if (data->hasFormat(kCddaMimeType)) {
|
else if (data->hasFormat(kCddaMimeType)) {
|
||||||
SongLoaderInserter *inserter = new SongLoaderInserter(task_manager_, collection_, backend_->app()->player());
|
SongLoaderInserter *inserter = new SongLoaderInserter(task_manager_, collection_, backend_->app()->player());
|
||||||
connect(inserter, SIGNAL(Error(QString)), SIGNAL(Error(QString)));
|
connect(inserter, SIGNAL(Error(QString)), SIGNAL(Error(QString)));
|
||||||
inserter->LoadAudioCD(this, row, play_now, enqueue_now);
|
inserter->LoadAudioCD(this, row, play_now, enqueue_now, enqueue_next_now);
|
||||||
}
|
}
|
||||||
else if (data->hasUrls()) {
|
else if (data->hasUrls()) {
|
||||||
// URL list dragged from the file list or some other app
|
// URL list dragged from the file list or some other app
|
||||||
InsertUrls(data->urls(), row, play_now, enqueue_now);
|
InsertUrls(data->urls(), row, play_now, enqueue_now, enqueue_next_now);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -734,7 +734,7 @@ void Playlist::InsertUrls(const QList<QUrl> &urls, int pos, bool play_now, bool
|
|||||||
SongLoaderInserter *inserter = new SongLoaderInserter(task_manager_, collection_, backend_->app()->player());
|
SongLoaderInserter *inserter = new SongLoaderInserter(task_manager_, collection_, backend_->app()->player());
|
||||||
connect(inserter, SIGNAL(Error(QString)), SIGNAL(Error(QString)));
|
connect(inserter, SIGNAL(Error(QString)), SIGNAL(Error(QString)));
|
||||||
|
|
||||||
inserter->Load(this, pos, play_now, enqueue, urls);
|
inserter->Load(this, pos, play_now, enqueue, enqueue_next, urls);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -891,17 +891,17 @@ void Playlist::InsertItems(const PlaylistItemList &itemsIn, int pos, bool play_n
|
|||||||
|
|
||||||
if (items.count() > kUndoItemLimit) {
|
if (items.count() > kUndoItemLimit) {
|
||||||
// Too big to keep in the undo stack. Also clear the stack because it might have been invalidated.
|
// Too big to keep in the undo stack. Also clear the stack because it might have been invalidated.
|
||||||
InsertItemsWithoutUndo(items, pos, enqueue);
|
InsertItemsWithoutUndo(items, pos, enqueue, enqueue_next);
|
||||||
undo_stack_->clear();
|
undo_stack_->clear();
|
||||||
} else {
|
} else {
|
||||||
undo_stack_->push(new PlaylistUndoCommands::InsertItems(this, items, pos, enqueue));
|
undo_stack_->push(new PlaylistUndoCommands::InsertItems(this, items, pos, enqueue, enqueue_next));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (play_now) emit PlayRequested(index(start, 0));
|
if (play_now) emit PlayRequested(index(start, 0));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Playlist::InsertItemsWithoutUndo(const PlaylistItemList &items, int pos, bool enqueue) {
|
void Playlist::InsertItemsWithoutUndo(const PlaylistItemList &items, int pos, bool enqueue, bool enqueue_next) {
|
||||||
|
|
||||||
if (items.isEmpty()) return;
|
if (items.isEmpty()) return;
|
||||||
|
|
||||||
@@ -937,6 +937,14 @@ void Playlist::InsertItemsWithoutUndo(const PlaylistItemList &items, int pos, bo
|
|||||||
queue_->ToggleTracks(indexes);
|
queue_->ToggleTracks(indexes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (enqueue_next) {
|
||||||
|
QModelIndexList indexes;
|
||||||
|
for (int i = start; i <= end; ++i) {
|
||||||
|
indexes << index(i, 0);
|
||||||
|
}
|
||||||
|
queue_->InsertFirst(indexes);
|
||||||
|
}
|
||||||
|
|
||||||
Save();
|
Save();
|
||||||
ReshuffleIndices();
|
ReshuffleIndices();
|
||||||
|
|
||||||
@@ -1110,6 +1118,7 @@ bool Playlist::CompareItems(int column, Qt::SortOrder order, shared_ptr<Playlist
|
|||||||
|
|
||||||
case Column_Comment: strcmp(comment);
|
case Column_Comment: strcmp(comment);
|
||||||
case Column_Source: cmp(source);
|
case Column_Source: cmp(source);
|
||||||
|
default: qLog(Error) << "No such column" << column;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef cmp
|
#undef cmp
|
||||||
@@ -1165,7 +1174,7 @@ QString Playlist::column_name(Column column) {
|
|||||||
|
|
||||||
case Column_Comment: return tr("Comment");
|
case Column_Comment: return tr("Comment");
|
||||||
case Column_Source: return tr("Source");
|
case Column_Source: return tr("Source");
|
||||||
default: return QString();
|
default: qLog(Error) << "No such column" << column;;
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
@@ -1263,10 +1272,6 @@ void Playlist::Save() const {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//namespace {
|
|
||||||
//typedef QFutureWatcher<QList<PlaylistItemPtr>> PlaylistItemFutureWatcher;
|
|
||||||
//}
|
|
||||||
|
|
||||||
void Playlist::Restore() {
|
void Playlist::Restore() {
|
||||||
|
|
||||||
if (!backend_) return;
|
if (!backend_) return;
|
||||||
@@ -1824,7 +1829,7 @@ void Playlist::RemoveDeletedSongs() {
|
|||||||
PlaylistItemPtr item = items_[row];
|
PlaylistItemPtr item = items_[row];
|
||||||
Song song = item->Metadata();
|
Song song = item->Metadata();
|
||||||
|
|
||||||
if (!QFile::exists(song.url().toLocalFile())) {
|
if (!song.is_stream() && !QFile::exists(song.url().toLocalFile())) {
|
||||||
rows_to_remove.append(row);
|
rows_to_remove.append(row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -308,7 +308,7 @@ private:
|
|||||||
void InsertSongItems(const SongList &songs, int pos, bool play_now, bool enqueue, bool enqueue_next = false);
|
void InsertSongItems(const SongList &songs, int pos, bool play_now, bool enqueue, bool enqueue_next = false);
|
||||||
|
|
||||||
// Modify the playlist without changing the undo stack. These are used by our friends in PlaylistUndoCommands
|
// Modify the playlist without changing the undo stack. These are used by our friends in PlaylistUndoCommands
|
||||||
void InsertItemsWithoutUndo(const PlaylistItemList &items, int pos, bool enqueue = false);
|
void InsertItemsWithoutUndo(const PlaylistItemList &items, int pos, bool enqueue = false, bool enqueue_next = false);
|
||||||
PlaylistItemList RemoveItemsWithoutUndo(int pos, int count);
|
PlaylistItemList RemoveItemsWithoutUndo(int pos, int count);
|
||||||
void MoveItemsWithoutUndo(const QList<int> &source_rows, int pos);
|
void MoveItemsWithoutUndo(const QList<int> &source_rows, int pos);
|
||||||
void MoveItemWithoutUndo(int source, int dest);
|
void MoveItemWithoutUndo(int source, int dest);
|
||||||
|
|||||||
@@ -45,28 +45,29 @@ PlaylistFilter::PlaylistFilter(QObject *parent)
|
|||||||
column_names_["artist"] = Playlist::Column_Artist;
|
column_names_["artist"] = Playlist::Column_Artist;
|
||||||
column_names_["album"] = Playlist::Column_Album;
|
column_names_["album"] = Playlist::Column_Album;
|
||||||
column_names_["albumartist"] = Playlist::Column_AlbumArtist;
|
column_names_["albumartist"] = Playlist::Column_AlbumArtist;
|
||||||
column_names_["composer"] = Playlist::Column_Composer;
|
|
||||||
column_names_["performer"] = Playlist::Column_Performer;
|
column_names_["performer"] = Playlist::Column_Performer;
|
||||||
column_names_["grouping"] = Playlist::Column_Grouping;
|
column_names_["composer"] = Playlist::Column_Composer;
|
||||||
column_names_["length"] = Playlist::Column_Length;
|
|
||||||
column_names_["track"] = Playlist::Column_Track;
|
|
||||||
column_names_["disc"] = Playlist::Column_Disc;
|
|
||||||
column_names_["year"] = Playlist::Column_Year;
|
column_names_["year"] = Playlist::Column_Year;
|
||||||
column_names_["originalyear"] = Playlist::Column_OriginalYear;
|
column_names_["originalyear"] = Playlist::Column_OriginalYear;
|
||||||
|
column_names_["track"] = Playlist::Column_Track;
|
||||||
|
column_names_["disc"] = Playlist::Column_Disc;
|
||||||
|
column_names_["length"] = Playlist::Column_Length;
|
||||||
column_names_["genre"] = Playlist::Column_Genre;
|
column_names_["genre"] = Playlist::Column_Genre;
|
||||||
column_names_["comment"] = Playlist::Column_Comment;
|
|
||||||
column_names_["bitrate"] = Playlist::Column_Bitrate;
|
|
||||||
column_names_["samplerate"] = Playlist::Column_Samplerate;
|
column_names_["samplerate"] = Playlist::Column_Samplerate;
|
||||||
column_names_["bitdepth"] = Playlist::Column_Bitdepth;
|
column_names_["bitdepth"] = Playlist::Column_Bitdepth;
|
||||||
|
column_names_["bitrate"] = Playlist::Column_Bitrate;
|
||||||
column_names_["filename"] = Playlist::Column_Filename;
|
column_names_["filename"] = Playlist::Column_Filename;
|
||||||
|
column_names_["grouping"] = Playlist::Column_Grouping;
|
||||||
|
column_names_["comment"] = Playlist::Column_Comment;
|
||||||
|
|
||||||
numerical_columns_ << Playlist::Column_Length
|
numerical_columns_ << Playlist::Column_Year
|
||||||
|
<< Playlist::Column_OriginalYear
|
||||||
<< Playlist::Column_Track
|
<< Playlist::Column_Track
|
||||||
<< Playlist::Column_Disc
|
<< Playlist::Column_Disc
|
||||||
<< Playlist::Column_Year
|
<< Playlist::Column_Length
|
||||||
<< Playlist::Column_Bitrate
|
|
||||||
<< Playlist::Column_Samplerate
|
<< Playlist::Column_Samplerate
|
||||||
<< Playlist::Column_Bitdepth;
|
<< Playlist::Column_Bitdepth
|
||||||
|
<< Playlist::Column_Bitrate;
|
||||||
}
|
}
|
||||||
|
|
||||||
PlaylistFilter::~PlaylistFilter() {
|
PlaylistFilter::~PlaylistFilter() {
|
||||||
|
|||||||
@@ -36,17 +36,18 @@ namespace PlaylistUndoCommands {
|
|||||||
Base::Base(Playlist* playlist) : QUndoCommand(0), playlist_(playlist) {}
|
Base::Base(Playlist* playlist) : QUndoCommand(0), playlist_(playlist) {}
|
||||||
|
|
||||||
|
|
||||||
InsertItems::InsertItems(Playlist *playlist, const PlaylistItemList &items, int pos, bool enqueue)
|
InsertItems::InsertItems(Playlist *playlist, const PlaylistItemList &items, int pos, bool enqueue, bool enqueue_next)
|
||||||
: Base(playlist),
|
: Base(playlist),
|
||||||
items_(items),
|
items_(items),
|
||||||
pos_(pos),
|
pos_(pos),
|
||||||
enqueue_(enqueue)
|
enqueue_(enqueue),
|
||||||
|
enqueue_next_(enqueue_next)
|
||||||
{
|
{
|
||||||
setText(tr("add %n songs", "", items_.count()));
|
setText(tr("add %n songs", "", items_.count()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void InsertItems::redo() {
|
void InsertItems::redo() {
|
||||||
playlist_->InsertItemsWithoutUndo(items_, pos_, enqueue_);
|
playlist_->InsertItemsWithoutUndo(items_, pos_, enqueue_, enqueue_next_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InsertItems::undo() {
|
void InsertItems::undo() {
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ namespace PlaylistUndoCommands {
|
|||||||
|
|
||||||
class InsertItems : public Base {
|
class InsertItems : public Base {
|
||||||
public:
|
public:
|
||||||
InsertItems(Playlist *playlist, const PlaylistItemList &items, int pos, bool enqueue = false);
|
InsertItems(Playlist *playlist, const PlaylistItemList &items, int pos, bool enqueue = false, bool enqueue_next = false);
|
||||||
|
|
||||||
void undo();
|
void undo();
|
||||||
void redo();
|
void redo();
|
||||||
@@ -64,6 +64,7 @@ namespace PlaylistUndoCommands {
|
|||||||
PlaylistItemList items_;
|
PlaylistItemList items_;
|
||||||
int pos_;
|
int pos_;
|
||||||
bool enqueue_;
|
bool enqueue_;
|
||||||
|
bool enqueue_next_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RemoveItems : public Base {
|
class RemoveItems : public Base {
|
||||||
|
|||||||
@@ -80,7 +80,6 @@
|
|||||||
|
|
||||||
using std::sort;
|
using std::sort;
|
||||||
|
|
||||||
const int PlaylistView::kStateVersion = 6;
|
|
||||||
const int PlaylistView::kGlowIntensitySteps = 24;
|
const int PlaylistView::kGlowIntensitySteps = 24;
|
||||||
const int PlaylistView::kAutoscrollGraceTimeout = 30; // seconds
|
const int PlaylistView::kAutoscrollGraceTimeout = 30; // seconds
|
||||||
const int PlaylistView::kDropIndicatorWidth = 2;
|
const int PlaylistView::kDropIndicatorWidth = 2;
|
||||||
@@ -135,8 +134,8 @@ PlaylistView::PlaylistView(QWidget *parent)
|
|||||||
style_(new PlaylistProxyStyle(style())),
|
style_(new PlaylistProxyStyle(style())),
|
||||||
playlist_(nullptr),
|
playlist_(nullptr),
|
||||||
header_(new PlaylistHeader(Qt::Horizontal, this, this)),
|
header_(new PlaylistHeader(Qt::Horizontal, this, this)),
|
||||||
|
initialized_(false),
|
||||||
setting_initial_header_layout_(false),
|
setting_initial_header_layout_(false),
|
||||||
upgrading_from_qheaderview_(false),
|
|
||||||
read_only_settings_(true),
|
read_only_settings_(true),
|
||||||
header_loaded_(false),
|
header_loaded_(false),
|
||||||
background_initialized_(false),
|
background_initialized_(false),
|
||||||
@@ -159,19 +158,18 @@ PlaylistView::PlaylistView(QWidget *parent)
|
|||||||
currenttrack_pause_(":/pictures/currenttrack_pause.png"),
|
currenttrack_pause_(":/pictures/currenttrack_pause.png"),
|
||||||
cached_current_row_row_(-1),
|
cached_current_row_row_(-1),
|
||||||
drop_indicator_row_(-1),
|
drop_indicator_row_(-1),
|
||||||
drag_over_(false)
|
drag_over_(false) {
|
||||||
{
|
|
||||||
|
|
||||||
setHeader(header_);
|
setHeader(header_);
|
||||||
header_->setSectionsMovable(true);
|
header_->setSectionsMovable(true);
|
||||||
setStyle(style_);
|
setStyle(style_);
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
|
|
||||||
|
|
||||||
connect(header_, SIGNAL(sectionResized(int,int,int)), SLOT(SaveGeometry()));
|
connect(header_, SIGNAL(sectionResized(int,int,int)), SLOT(SaveGeometry()));
|
||||||
connect(header_, SIGNAL(sectionMoved(int,int,int)), SLOT(SaveGeometry()));
|
connect(header_, SIGNAL(sectionMoved(int,int,int)), SLOT(SaveGeometry()));
|
||||||
connect(header_, SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), SLOT(SaveGeometry()));
|
connect(header_, SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), SLOT(SaveGeometry()));
|
||||||
connect(header_, SIGNAL(SectionVisibilityChanged(int,bool)), SLOT(SaveGeometry()));
|
connect(header_, SIGNAL(SectionVisibilityChanged(int,bool)), SLOT(SaveGeometry()));
|
||||||
|
|
||||||
connect(header_, SIGNAL(sectionResized(int,int,int)), SLOT(InvalidateCachedCurrentPixmap()));
|
connect(header_, SIGNAL(sectionResized(int,int,int)), SLOT(InvalidateCachedCurrentPixmap()));
|
||||||
connect(header_, SIGNAL(sectionMoved(int,int,int)), SLOT(InvalidateCachedCurrentPixmap()));
|
connect(header_, SIGNAL(sectionMoved(int,int,int)), SLOT(InvalidateCachedCurrentPixmap()));
|
||||||
connect(header_, SIGNAL(SectionVisibilityChanged(int,bool)), SLOT(InvalidateCachedCurrentPixmap()));
|
connect(header_, SIGNAL(SectionVisibilityChanged(int,bool)), SLOT(InvalidateCachedCurrentPixmap()));
|
||||||
@@ -196,6 +194,8 @@ PlaylistView::PlaylistView(QWidget *parent)
|
|||||||
connect(fade_animation_, SIGNAL(valueChanged(qreal)), SLOT(FadePreviousBackgroundImage(qreal)));
|
connect(fade_animation_, SIGNAL(valueChanged(qreal)), SLOT(FadePreviousBackgroundImage(qreal)));
|
||||||
fade_animation_->setDirection(QTimeLine::Backward); // 1.0 -> 0.0
|
fade_animation_->setDirection(QTimeLine::Backward); // 1.0 -> 0.0
|
||||||
|
|
||||||
|
initialized_ = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PlaylistView::~PlaylistView() {
|
PlaylistView::~PlaylistView() {
|
||||||
@@ -253,7 +253,7 @@ void PlaylistView::SetPlaylist(Playlist *playlist) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
playlist_ = playlist;
|
playlist_ = playlist;
|
||||||
if (!header_loaded_) LoadGeometry();
|
LoadGeometry();
|
||||||
ReloadSettings();
|
ReloadSettings();
|
||||||
setFocus();
|
setFocus();
|
||||||
read_only_settings_ = false;
|
read_only_settings_ = false;
|
||||||
@@ -285,7 +285,6 @@ void PlaylistView::setModel(QAbstractItemModel *m) {
|
|||||||
void PlaylistView::LoadGeometry() {
|
void PlaylistView::LoadGeometry() {
|
||||||
|
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
header_loaded_ = true;
|
|
||||||
settings.beginGroup(Playlist::kSettingsGroup);
|
settings.beginGroup(Playlist::kSettingsGroup);
|
||||||
|
|
||||||
QByteArray state(settings.value("state").toByteArray());
|
QByteArray state(settings.value("state").toByteArray());
|
||||||
@@ -317,7 +316,7 @@ void PlaylistView::LoadGeometry() {
|
|||||||
setting_initial_header_layout_ = true;
|
setting_initial_header_layout_ = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
upgrading_from_qheaderview_ = true;
|
setting_initial_header_layout_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,11 +332,13 @@ void PlaylistView::LoadGeometry() {
|
|||||||
header_->ShowSection(Playlist::Column_Title);
|
header_->ShowSection(Playlist::Column_Title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
header_loaded_ = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlaylistView::SaveGeometry() {
|
void PlaylistView::SaveGeometry() {
|
||||||
|
|
||||||
if (read_only_settings_) return;
|
if (!initialized_ || read_only_settings_) return;
|
||||||
|
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
settings.beginGroup(Playlist::kSettingsGroup);
|
settings.beginGroup(Playlist::kSettingsGroup);
|
||||||
@@ -929,11 +930,10 @@ void PlaylistView::ReloadSettings() {
|
|||||||
glow_enabled_ = s.value("glow_effect", true).toBool();
|
glow_enabled_ = s.value("glow_effect", true).toBool();
|
||||||
s.endGroup();
|
s.endGroup();
|
||||||
|
|
||||||
if (setting_initial_header_layout_ || upgrading_from_qheaderview_) {
|
if (setting_initial_header_layout_) {
|
||||||
s.beginGroup(Playlist::kSettingsGroup);
|
s.beginGroup(Playlist::kSettingsGroup);
|
||||||
header_->SetStretchEnabled(s.value("stretch", true).toBool());
|
header_->SetStretchEnabled(s.value("stretch", true).toBool());
|
||||||
s.endGroup();
|
s.endGroup();
|
||||||
upgrading_from_qheaderview_ = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currently_glowing_ && glow_enabled_ && isVisible()) StartGlowing();
|
if (currently_glowing_ && glow_enabled_ && isVisible()) StartGlowing();
|
||||||
@@ -1035,7 +1035,7 @@ void PlaylistView::ReloadSettings() {
|
|||||||
|
|
||||||
void PlaylistView::SaveSettings() {
|
void PlaylistView::SaveSettings() {
|
||||||
|
|
||||||
if (read_only_settings_) return;
|
if (!initialized_ || read_only_settings_) return;
|
||||||
|
|
||||||
QSettings s;
|
QSettings s;
|
||||||
|
|
||||||
@@ -1054,6 +1054,7 @@ void PlaylistView::SaveSettings() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PlaylistView::StretchChanged(bool stretch) {
|
void PlaylistView::StretchChanged(bool stretch) {
|
||||||
|
if (!initialized_) return;
|
||||||
setHorizontalScrollBarPolicy(stretch ? Qt::ScrollBarAlwaysOff : Qt::ScrollBarAsNeeded);
|
setHorizontalScrollBarPolicy(stretch ? Qt::ScrollBarAlwaysOff : Qt::ScrollBarAsNeeded);
|
||||||
SaveGeometry();
|
SaveGeometry();
|
||||||
}
|
}
|
||||||
@@ -1084,17 +1085,17 @@ ColumnAlignmentMap PlaylistView::DefaultColumnAlignment() {
|
|||||||
|
|
||||||
ColumnAlignmentMap ret;
|
ColumnAlignmentMap ret;
|
||||||
|
|
||||||
ret[Playlist::Column_Length] =
|
ret[Playlist::Column_Year] =
|
||||||
|
ret[Playlist::Column_OriginalYear] =
|
||||||
ret[Playlist::Column_Track] =
|
ret[Playlist::Column_Track] =
|
||||||
ret[Playlist::Column_Disc] =
|
ret[Playlist::Column_Disc] =
|
||||||
ret[Playlist::Column_Year] =
|
ret[Playlist::Column_Length] =
|
||||||
ret[Playlist::Column_Bitrate] =
|
|
||||||
ret[Playlist::Column_Samplerate] =
|
ret[Playlist::Column_Samplerate] =
|
||||||
ret[Playlist::Column_Bitdepth] =
|
ret[Playlist::Column_Bitdepth] =
|
||||||
|
ret[Playlist::Column_Bitrate] =
|
||||||
ret[Playlist::Column_Filesize] =
|
ret[Playlist::Column_Filesize] =
|
||||||
ret[Playlist::Column_PlayCount] =
|
ret[Playlist::Column_PlayCount] =
|
||||||
ret[Playlist::Column_SkipCount] =
|
ret[Playlist::Column_SkipCount] =
|
||||||
ret[Playlist::Column_OriginalYear] =
|
|
||||||
(Qt::AlignRight | Qt::AlignVCenter);
|
(Qt::AlignRight | Qt::AlignVCenter);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -99,7 +99,6 @@ class PlaylistView : public QTreeView {
|
|||||||
PlaylistView(QWidget *parent = nullptr);
|
PlaylistView(QWidget *parent = nullptr);
|
||||||
~PlaylistView();
|
~PlaylistView();
|
||||||
|
|
||||||
static const int kStateVersion;
|
|
||||||
// Constants for settings: are persistent, values should not be changed
|
// Constants for settings: are persistent, values should not be changed
|
||||||
static const char *kSettingBackgroundImageType;
|
static const char *kSettingBackgroundImageType;
|
||||||
static const char *kSettingBackgroundImageFilename;
|
static const char *kSettingBackgroundImageFilename;
|
||||||
@@ -214,8 +213,8 @@ class PlaylistView : public QTreeView {
|
|||||||
PlaylistProxyStyle *style_;
|
PlaylistProxyStyle *style_;
|
||||||
Playlist *playlist_;
|
Playlist *playlist_;
|
||||||
PlaylistHeader *header_;
|
PlaylistHeader *header_;
|
||||||
|
bool initialized_;
|
||||||
bool setting_initial_header_layout_;
|
bool setting_initial_header_layout_;
|
||||||
bool upgrading_from_qheaderview_;
|
|
||||||
bool read_only_settings_;
|
bool read_only_settings_;
|
||||||
bool header_loaded_;
|
bool header_loaded_;
|
||||||
|
|
||||||
|
|||||||
@@ -43,12 +43,13 @@ SongLoaderInserter::SongLoaderInserter(TaskManager *task_manager, CollectionBack
|
|||||||
|
|
||||||
SongLoaderInserter::~SongLoaderInserter() { qDeleteAll(pending_); }
|
SongLoaderInserter::~SongLoaderInserter() { qDeleteAll(pending_); }
|
||||||
|
|
||||||
void SongLoaderInserter::Load(Playlist *destination, int row, bool play_now, bool enqueue, const QList<QUrl> &urls) {
|
void SongLoaderInserter::Load(Playlist *destination, int row, bool play_now, bool enqueue, bool enqueue_next, const QList<QUrl> &urls) {
|
||||||
|
|
||||||
destination_ = destination;
|
destination_ = destination;
|
||||||
row_ = row;
|
row_ = row;
|
||||||
play_now_ = play_now;
|
play_now_ = play_now;
|
||||||
enqueue_ = enqueue;
|
enqueue_ = enqueue;
|
||||||
|
enqueue_next_ = enqueue_next;
|
||||||
|
|
||||||
connect(destination, SIGNAL(destroyed()), SLOT(DestinationDestroyed()));
|
connect(destination, SIGNAL(destroyed()), SLOT(DestinationDestroyed()));
|
||||||
connect(this, SIGNAL(PreloadFinished()), SLOT(InsertSongs()));
|
connect(this, SIGNAL(PreloadFinished()), SLOT(InsertSongs()));
|
||||||
@@ -84,12 +85,13 @@ void SongLoaderInserter::Load(Playlist *destination, int row, bool play_now, boo
|
|||||||
// First, we add tracks (without metadata) into the playlist
|
// First, we add tracks (without metadata) into the playlist
|
||||||
// In the meantime, MusicBrainz will be queried to get songs' metadata.
|
// In the meantime, MusicBrainz will be queried to get songs' metadata.
|
||||||
// AudioCDTagsLoaded will be called next, and playlist's items will be updated.
|
// AudioCDTagsLoaded will be called next, and playlist's items will be updated.
|
||||||
void SongLoaderInserter::LoadAudioCD(Playlist *destination, int row, bool play_now, bool enqueue) {
|
void SongLoaderInserter::LoadAudioCD(Playlist *destination, int row, bool play_now, bool enqueue, bool enqueue_next) {
|
||||||
|
|
||||||
destination_ = destination;
|
destination_ = destination;
|
||||||
row_ = row;
|
row_ = row;
|
||||||
play_now_ = play_now;
|
play_now_ = play_now;
|
||||||
enqueue_ = enqueue;
|
enqueue_ = enqueue;
|
||||||
|
enqueue_next_ = enqueue_next;
|
||||||
|
|
||||||
SongLoader *loader = new SongLoader(collection_, player_, this);
|
SongLoader *loader = new SongLoader(collection_, player_, this);
|
||||||
NewClosure(loader, SIGNAL(AudioCDTracksLoaded()), this, SLOT(AudioCDTracksLoaded(SongLoader*)), loader);
|
NewClosure(loader, SIGNAL(AudioCDTracksLoaded()), this, SLOT(AudioCDTracksLoaded(SongLoader*)), loader);
|
||||||
@@ -128,7 +130,7 @@ void SongLoaderInserter::AudioCDTagsLoaded(bool success) {
|
|||||||
void SongLoaderInserter::InsertSongs() {
|
void SongLoaderInserter::InsertSongs() {
|
||||||
// Insert songs (that haven't been completely loaded) to allow user to see and play them while not loaded completely
|
// Insert songs (that haven't been completely loaded) to allow user to see and play them while not loaded completely
|
||||||
if (destination_) {
|
if (destination_) {
|
||||||
destination_->InsertSongsOrCollectionItems(songs_, row_, play_now_, enqueue_);
|
destination_->InsertSongsOrCollectionItems(songs_, row_, play_now_, enqueue_, enqueue_next_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ class SongLoaderInserter : public QObject {
|
|||||||
SongLoaderInserter(TaskManager *task_manager, CollectionBackendInterface *collection, const Player *player);
|
SongLoaderInserter(TaskManager *task_manager, CollectionBackendInterface *collection, const Player *player);
|
||||||
~SongLoaderInserter();
|
~SongLoaderInserter();
|
||||||
|
|
||||||
void Load(Playlist *destination, int row, bool play_now, bool enqueue, const QList<QUrl> &urls);
|
void Load(Playlist *destination, int row, bool play_now, bool enqueue, bool enqueue_next, const QList<QUrl> &urls);
|
||||||
void LoadAudioCD(Playlist *destination, int row, bool play_now, bool enqueue);
|
void LoadAudioCD(Playlist *destination, int row, bool play_now, bool enqueue, bool enqueue_next);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void Error(const QString &message);
|
void Error(const QString &message);
|
||||||
@@ -68,6 +68,7 @@ signals:
|
|||||||
int row_;
|
int row_;
|
||||||
bool play_now_;
|
bool play_now_;
|
||||||
bool enqueue_;
|
bool enqueue_;
|
||||||
|
bool enqueue_next_;
|
||||||
|
|
||||||
SongList songs_;
|
SongList songs_;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user