mirror of
https://github.com/clementine-player/Clementine
synced 2025-01-30 11:04:57 +01:00
Remember whether a dynamic playlist was active between restarts
This commit is contained in:
parent
6f889947c8
commit
5969e2b3d7
@ -286,5 +286,6 @@
|
|||||||
<file>icons/48x48/folder.png</file>
|
<file>icons/48x48/folder.png</file>
|
||||||
<file>smartplaylistsearchterm.css</file>
|
<file>smartplaylistsearchterm.css</file>
|
||||||
<file>schema/schema-19.sql</file>
|
<file>schema/schema-19.sql</file>
|
||||||
|
<file>schema/schema-20.sql</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
|
||||||
const char* Database::kDatabaseFilename = "clementine.db";
|
const char* Database::kDatabaseFilename = "clementine.db";
|
||||||
const int Database::kSchemaVersion = 19;
|
const int Database::kSchemaVersion = 20;
|
||||||
const char* Database::kMagicAllSongsTables = "%allsongstables";
|
const char* Database::kMagicAllSongsTables = "%allsongstables";
|
||||||
|
|
||||||
int Database::sNextConnectionId = 1;
|
int Database::sNextConnectionId = 1;
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "engines/enginebase.h"
|
#include "engines/enginebase.h"
|
||||||
#include "library/directory.h"
|
#include "library/directory.h"
|
||||||
#include "radio/lastfmservice.h"
|
#include "radio/lastfmservice.h"
|
||||||
|
#include "smartplaylists/generator.h"
|
||||||
#include "ui/equalizer.h"
|
#include "ui/equalizer.h"
|
||||||
#include "ui/iconloader.h"
|
#include "ui/iconloader.h"
|
||||||
#include "ui/mainwindow.h"
|
#include "ui/mainwindow.h"
|
||||||
@ -126,6 +127,7 @@ int main(int argc, char *argv[]) {
|
|||||||
qRegisterMetaType<const char*>("const char*");
|
qRegisterMetaType<const char*>("const char*");
|
||||||
qRegisterMetaType<QNetworkReply*>("QNetworkReply*");
|
qRegisterMetaType<QNetworkReply*>("QNetworkReply*");
|
||||||
qRegisterMetaType<QNetworkReply**>("QNetworkReply**");
|
qRegisterMetaType<QNetworkReply**>("QNetworkReply**");
|
||||||
|
qRegisterMetaType<smart_playlists::GeneratorPtr>("smart_playlists::GeneratorPtr");
|
||||||
|
|
||||||
#ifdef HAVE_GSTREAMER
|
#ifdef HAVE_GSTREAMER
|
||||||
qRegisterMetaType<GstBuffer*>("GstBuffer*");
|
qRegisterMetaType<GstBuffer*>("GstBuffer*");
|
||||||
|
@ -52,6 +52,7 @@
|
|||||||
|
|
||||||
#include <lastfm/ScrobblePoint>
|
#include <lastfm/ScrobblePoint>
|
||||||
|
|
||||||
|
using smart_playlists::Generator;
|
||||||
using smart_playlists::GeneratorInserter;
|
using smart_playlists::GeneratorInserter;
|
||||||
using smart_playlists::GeneratorPtr;
|
using smart_playlists::GeneratorPtr;
|
||||||
|
|
||||||
@ -640,11 +641,16 @@ void Playlist::InsertSmartPlaylist(GeneratorPtr generator, int pos, bool play_no
|
|||||||
inserter->Load(this, pos, play_now, generator);
|
inserter->Load(this, pos, play_now, generator);
|
||||||
|
|
||||||
if (generator->is_dynamic()) {
|
if (generator->is_dynamic()) {
|
||||||
dynamic_playlist_ = generator;
|
TurnOnDynamicPlaylist(generator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Playlist::TurnOnDynamicPlaylist(GeneratorPtr gen) {
|
||||||
|
dynamic_playlist_ = gen;
|
||||||
playlist_sequence_->SetUsingDynamicPlaylist(true);
|
playlist_sequence_->SetUsingDynamicPlaylist(true);
|
||||||
ShuffleModeChanged(PlaylistSequence::Shuffle_Off);
|
ShuffleModeChanged(PlaylistSequence::Shuffle_Off);
|
||||||
emit DynamicModeChanged(true);
|
emit DynamicModeChanged(true);
|
||||||
}
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Playlist::MoveItemsWithoutUndo(const QList<int> &source_rows, int pos) {
|
void Playlist::MoveItemsWithoutUndo(const QList<int> &source_rows, int pos) {
|
||||||
@ -991,7 +997,7 @@ void Playlist::Save() const {
|
|||||||
if (!backend_)
|
if (!backend_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
backend_->SavePlaylistAsync(id_, items_, last_played_index());
|
backend_->SavePlaylistAsync(id_, items_, last_played_index(), dynamic_playlist_);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -1023,6 +1029,15 @@ void Playlist::ItemsLoaded() {
|
|||||||
|
|
||||||
last_played_item_index_ =
|
last_played_item_index_ =
|
||||||
p.last_played == -1 ? QModelIndex() : index(p.last_played);
|
p.last_played == -1 ? QModelIndex() : index(p.last_played);
|
||||||
|
|
||||||
|
if (!p.dynamic_type.isEmpty()) {
|
||||||
|
GeneratorPtr gen = Generator::Create(p.dynamic_type);
|
||||||
|
if (gen) {
|
||||||
|
gen->set_library(library_);
|
||||||
|
gen->Load(p.dynamic_data);
|
||||||
|
TurnOnDynamicPlaylist(gen);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Playlist::removeRows(int row, int count, const QModelIndex& parent) {
|
bool Playlist::removeRows(int row, int count, const QModelIndex& parent) {
|
||||||
@ -1161,6 +1176,7 @@ void Playlist::TurnOffDynamicPlaylist() {
|
|||||||
ShuffleModeChanged(playlist_sequence_->shuffle_mode());
|
ShuffleModeChanged(playlist_sequence_->shuffle_mode());
|
||||||
}
|
}
|
||||||
emit DynamicModeChanged(false);
|
emit DynamicModeChanged(false);
|
||||||
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Playlist::RepopulateDynamicPlaylist() {
|
void Playlist::RepopulateDynamicPlaylist() {
|
||||||
|
@ -208,6 +208,7 @@ class Playlist : public QAbstractListModel {
|
|||||||
int NextVirtualIndex(int i) const;
|
int NextVirtualIndex(int i) const;
|
||||||
int PreviousVirtualIndex(int i) const;
|
int PreviousVirtualIndex(int i) const;
|
||||||
bool FilterContainsVirtualIndex(int i) const;
|
bool FilterContainsVirtualIndex(int i) const;
|
||||||
|
void TurnOnDynamicPlaylist(smart_playlists::GeneratorPtr gen);
|
||||||
|
|
||||||
// Modify the playlist without changing the undo stack. These are used by
|
// Modify the playlist without changing the undo stack. These are used by
|
||||||
// our friends in PlaylistUndoCommands
|
// our friends in PlaylistUndoCommands
|
||||||
|
@ -20,11 +20,14 @@
|
|||||||
#include "core/scopedtransaction.h"
|
#include "core/scopedtransaction.h"
|
||||||
#include "core/song.h"
|
#include "core/song.h"
|
||||||
#include "library/sqlrow.h"
|
#include "library/sqlrow.h"
|
||||||
|
#include "smartplaylists/generator.h"
|
||||||
|
|
||||||
#include <QSqlQuery>
|
#include <QSqlQuery>
|
||||||
#include <QtConcurrentMap>
|
#include <QtConcurrentMap>
|
||||||
#include <QtDebug>
|
#include <QtDebug>
|
||||||
|
|
||||||
|
using smart_playlists::GeneratorPtr;
|
||||||
|
|
||||||
using boost::shared_ptr;
|
using boost::shared_ptr;
|
||||||
|
|
||||||
PlaylistBackend::PlaylistBackend(QObject* parent)
|
PlaylistBackend::PlaylistBackend(QObject* parent)
|
||||||
@ -58,7 +61,9 @@ PlaylistBackend::Playlist PlaylistBackend::GetPlaylist(int id) {
|
|||||||
QMutexLocker l(db_->Mutex());
|
QMutexLocker l(db_->Mutex());
|
||||||
QSqlDatabase db(db_->Connect());
|
QSqlDatabase db(db_->Connect());
|
||||||
|
|
||||||
QSqlQuery q("SELECT ROWID, name, last_played FROM playlists"
|
QSqlQuery q("SELECT ROWID, name, last_played, dynamic_playlist_type,"
|
||||||
|
" dynamic_playlist_data"
|
||||||
|
" FROM playlists"
|
||||||
" WHERE ROWID=:id", db);
|
" WHERE ROWID=:id", db);
|
||||||
q.bindValue(":id", id);
|
q.bindValue(":id", id);
|
||||||
q.exec();
|
q.exec();
|
||||||
@ -71,6 +76,8 @@ PlaylistBackend::Playlist PlaylistBackend::GetPlaylist(int id) {
|
|||||||
p.id = q.value(0).toInt();
|
p.id = q.value(0).toInt();
|
||||||
p.name = q.value(1).toString();
|
p.name = q.value(1).toString();
|
||||||
p.last_played = q.value(2).toInt();
|
p.last_played = q.value(2).toInt();
|
||||||
|
p.dynamic_type = q.value(3).toString();
|
||||||
|
p.dynamic_data = q.value(4).toByteArray();
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@ -118,15 +125,16 @@ PlaylistItemPtr PlaylistBackend::NewSongFromQuery(const SqlRow& row) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PlaylistBackend::SavePlaylistAsync(int playlist, const PlaylistItemList &items,
|
void PlaylistBackend::SavePlaylistAsync(int playlist, const PlaylistItemList &items,
|
||||||
int last_played) {
|
int last_played, GeneratorPtr dynamic) {
|
||||||
metaObject()->invokeMethod(this, "SavePlaylist", Qt::QueuedConnection,
|
metaObject()->invokeMethod(this, "SavePlaylist", Qt::QueuedConnection,
|
||||||
Q_ARG(int, playlist),
|
Q_ARG(int, playlist),
|
||||||
Q_ARG(PlaylistItemList, items),
|
Q_ARG(PlaylistItemList, items),
|
||||||
Q_ARG(int, last_played));
|
Q_ARG(int, last_played),
|
||||||
|
Q_ARG(smart_playlists::GeneratorPtr, dynamic));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlaylistBackend::SavePlaylist(int playlist, const PlaylistItemList& items,
|
void PlaylistBackend::SavePlaylist(int playlist, const PlaylistItemList& items,
|
||||||
int last_played) {
|
int last_played, GeneratorPtr dynamic) {
|
||||||
QMutexLocker l(db_->Mutex());
|
QMutexLocker l(db_->Mutex());
|
||||||
QSqlDatabase db(db_->Connect());
|
QSqlDatabase db(db_->Connect());
|
||||||
|
|
||||||
@ -135,7 +143,10 @@ void PlaylistBackend::SavePlaylist(int playlist, const PlaylistItemList& items,
|
|||||||
" (playlist, type, library_id, url, title, artist, album,"
|
" (playlist, type, library_id, url, title, artist, album,"
|
||||||
" length, radio_service)"
|
" length, radio_service)"
|
||||||
" VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", db);
|
" VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", db);
|
||||||
QSqlQuery update("UPDATE playlists SET last_played=:last_played"
|
QSqlQuery update("UPDATE playlists SET "
|
||||||
|
" last_played=:last_played,"
|
||||||
|
" dynamic_playlist_type=:dynamic_type,"
|
||||||
|
" dynamic_playlist_data=:dynamic_data"
|
||||||
" WHERE ROWID=:playlist", db);
|
" WHERE ROWID=:playlist", db);
|
||||||
|
|
||||||
ScopedTransaction transaction(&db);
|
ScopedTransaction transaction(&db);
|
||||||
@ -157,7 +168,14 @@ void PlaylistBackend::SavePlaylist(int playlist, const PlaylistItemList& items,
|
|||||||
|
|
||||||
// Update the last played track number
|
// Update the last played track number
|
||||||
update.bindValue(":last_played", last_played);
|
update.bindValue(":last_played", last_played);
|
||||||
update.bindValue(":id", playlist);
|
if (dynamic) {
|
||||||
|
update.bindValue(":dynamic_type", dynamic->type());
|
||||||
|
update.bindValue(":dynamic_data", dynamic->Save());
|
||||||
|
} else {
|
||||||
|
update.bindValue(":dynamic_type", QString());
|
||||||
|
update.bindValue(":dynamic_data", QByteArray());
|
||||||
|
}
|
||||||
|
update.bindValue(":playlist", playlist);
|
||||||
update.exec();
|
update.exec();
|
||||||
if (db_->CheckErrors(update.lastError()))
|
if (db_->CheckErrors(update.lastError()))
|
||||||
return;
|
return;
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
#include "playlistitem.h"
|
#include "playlistitem.h"
|
||||||
|
#include "smartplaylists/generator_fwd.h"
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
@ -39,6 +40,8 @@ class PlaylistBackend : public QObject {
|
|||||||
int id;
|
int id;
|
||||||
QString name;
|
QString name;
|
||||||
int last_played;
|
int last_played;
|
||||||
|
QString dynamic_type;
|
||||||
|
QByteArray dynamic_data;
|
||||||
};
|
};
|
||||||
typedef QList<Playlist> PlaylistList;
|
typedef QList<Playlist> PlaylistList;
|
||||||
typedef QFuture<PlaylistItemPtr> PlaylistItemFuture;
|
typedef QFuture<PlaylistItemPtr> PlaylistItemFuture;
|
||||||
@ -47,7 +50,7 @@ class PlaylistBackend : public QObject {
|
|||||||
Playlist GetPlaylist(int id);
|
Playlist GetPlaylist(int id);
|
||||||
PlaylistItemFuture GetPlaylistItems(int playlist);
|
PlaylistItemFuture GetPlaylistItems(int playlist);
|
||||||
void SavePlaylistAsync(int playlist, const PlaylistItemList& items,
|
void SavePlaylistAsync(int playlist, const PlaylistItemList& items,
|
||||||
int last_played);
|
int last_played, smart_playlists::GeneratorPtr dynamic);
|
||||||
void SetPlaylistOrder(const QList<int>& ids);
|
void SetPlaylistOrder(const QList<int>& ids);
|
||||||
|
|
||||||
int CreatePlaylist(const QString& name);
|
int CreatePlaylist(const QString& name);
|
||||||
@ -55,7 +58,8 @@ class PlaylistBackend : public QObject {
|
|||||||
void RenamePlaylist(int id, const QString& new_name);
|
void RenamePlaylist(int id, const QString& new_name);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void SavePlaylist(int playlist, const PlaylistItemList& items, int last_played);
|
void SavePlaylist(int playlist, const PlaylistItemList& items,
|
||||||
|
int last_played, smart_playlists::GeneratorPtr dynamic);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static PlaylistItemPtr NewSongFromQuery(const SqlRow& row);
|
static PlaylistItemPtr NewSongFromQuery(const SqlRow& row);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user