diff --git a/data/data.qrc b/data/data.qrc
index 549ebafd9..39cac4902 100644
--- a/data/data.qrc
+++ b/data/data.qrc
@@ -286,5 +286,6 @@
icons/48x48/folder.png
smartplaylistsearchterm.css
schema/schema-19.sql
+ schema/schema-20.sql
diff --git a/src/core/database.cpp b/src/core/database.cpp
index 033c74cb3..20b8c682f 100644
--- a/src/core/database.cpp
+++ b/src/core/database.cpp
@@ -30,7 +30,7 @@
#include
const char* Database::kDatabaseFilename = "clementine.db";
-const int Database::kSchemaVersion = 19;
+const int Database::kSchemaVersion = 20;
const char* Database::kMagicAllSongsTables = "%allsongstables";
int Database::sNextConnectionId = 1;
diff --git a/src/main.cpp b/src/main.cpp
index 0721d1e1b..99971f3c6 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -32,6 +32,7 @@
#include "engines/enginebase.h"
#include "library/directory.h"
#include "radio/lastfmservice.h"
+#include "smartplaylists/generator.h"
#include "ui/equalizer.h"
#include "ui/iconloader.h"
#include "ui/mainwindow.h"
@@ -126,6 +127,7 @@ int main(int argc, char *argv[]) {
qRegisterMetaType("const char*");
qRegisterMetaType("QNetworkReply*");
qRegisterMetaType("QNetworkReply**");
+ qRegisterMetaType("smart_playlists::GeneratorPtr");
#ifdef HAVE_GSTREAMER
qRegisterMetaType("GstBuffer*");
diff --git a/src/playlist/playlist.cpp b/src/playlist/playlist.cpp
index c77390910..ddddca1cd 100644
--- a/src/playlist/playlist.cpp
+++ b/src/playlist/playlist.cpp
@@ -52,6 +52,7 @@
#include
+using smart_playlists::Generator;
using smart_playlists::GeneratorInserter;
using smart_playlists::GeneratorPtr;
@@ -640,13 +641,18 @@ void Playlist::InsertSmartPlaylist(GeneratorPtr generator, int pos, bool play_no
inserter->Load(this, pos, play_now, generator);
if (generator->is_dynamic()) {
- dynamic_playlist_ = generator;
- playlist_sequence_->SetUsingDynamicPlaylist(true);
- ShuffleModeChanged(PlaylistSequence::Shuffle_Off);
- emit DynamicModeChanged(true);
+ TurnOnDynamicPlaylist(generator);
}
}
+void Playlist::TurnOnDynamicPlaylist(GeneratorPtr gen) {
+ dynamic_playlist_ = gen;
+ playlist_sequence_->SetUsingDynamicPlaylist(true);
+ ShuffleModeChanged(PlaylistSequence::Shuffle_Off);
+ emit DynamicModeChanged(true);
+ Save();
+}
+
void Playlist::MoveItemsWithoutUndo(const QList &source_rows, int pos) {
layoutAboutToBeChanged();
PlaylistItemList moved_items;
@@ -991,7 +997,7 @@ void Playlist::Save() const {
if (!backend_)
return;
- backend_->SavePlaylistAsync(id_, items_, last_played_index());
+ backend_->SavePlaylistAsync(id_, items_, last_played_index(), dynamic_playlist_);
}
namespace {
@@ -1023,6 +1029,15 @@ void Playlist::ItemsLoaded() {
last_played_item_index_ =
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) {
@@ -1161,6 +1176,7 @@ void Playlist::TurnOffDynamicPlaylist() {
ShuffleModeChanged(playlist_sequence_->shuffle_mode());
}
emit DynamicModeChanged(false);
+ Save();
}
void Playlist::RepopulateDynamicPlaylist() {
diff --git a/src/playlist/playlist.h b/src/playlist/playlist.h
index 7cd7fa2d6..1e44fc085 100644
--- a/src/playlist/playlist.h
+++ b/src/playlist/playlist.h
@@ -208,6 +208,7 @@ class Playlist : public QAbstractListModel {
int NextVirtualIndex(int i) const;
int PreviousVirtualIndex(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
// our friends in PlaylistUndoCommands
diff --git a/src/playlist/playlistbackend.cpp b/src/playlist/playlistbackend.cpp
index e5e20eb0b..52b981ae7 100644
--- a/src/playlist/playlistbackend.cpp
+++ b/src/playlist/playlistbackend.cpp
@@ -20,11 +20,14 @@
#include "core/scopedtransaction.h"
#include "core/song.h"
#include "library/sqlrow.h"
+#include "smartplaylists/generator.h"
#include
#include
#include
+using smart_playlists::GeneratorPtr;
+
using boost::shared_ptr;
PlaylistBackend::PlaylistBackend(QObject* parent)
@@ -58,7 +61,9 @@ PlaylistBackend::Playlist PlaylistBackend::GetPlaylist(int id) {
QMutexLocker l(db_->Mutex());
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);
q.bindValue(":id", id);
q.exec();
@@ -71,6 +76,8 @@ PlaylistBackend::Playlist PlaylistBackend::GetPlaylist(int id) {
p.id = q.value(0).toInt();
p.name = q.value(1).toString();
p.last_played = q.value(2).toInt();
+ p.dynamic_type = q.value(3).toString();
+ p.dynamic_data = q.value(4).toByteArray();
return p;
}
@@ -118,15 +125,16 @@ PlaylistItemPtr PlaylistBackend::NewSongFromQuery(const SqlRow& row) {
}
void PlaylistBackend::SavePlaylistAsync(int playlist, const PlaylistItemList &items,
- int last_played) {
+ int last_played, GeneratorPtr dynamic) {
metaObject()->invokeMethod(this, "SavePlaylist", Qt::QueuedConnection,
Q_ARG(int, playlist),
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,
- int last_played) {
+ int last_played, GeneratorPtr dynamic) {
QMutexLocker l(db_->Mutex());
QSqlDatabase db(db_->Connect());
@@ -135,7 +143,10 @@ void PlaylistBackend::SavePlaylist(int playlist, const PlaylistItemList& items,
" (playlist, type, library_id, url, title, artist, album,"
" length, radio_service)"
" 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);
ScopedTransaction transaction(&db);
@@ -157,7 +168,14 @@ void PlaylistBackend::SavePlaylist(int playlist, const PlaylistItemList& items,
// Update the last played track number
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();
if (db_->CheckErrors(update.lastError()))
return;
diff --git a/src/playlist/playlistbackend.h b/src/playlist/playlistbackend.h
index b0fb27f30..c82b8ac17 100644
--- a/src/playlist/playlistbackend.h
+++ b/src/playlist/playlistbackend.h
@@ -23,6 +23,7 @@
#include
#include "playlistitem.h"
+#include "smartplaylists/generator_fwd.h"
#include
@@ -39,6 +40,8 @@ class PlaylistBackend : public QObject {
int id;
QString name;
int last_played;
+ QString dynamic_type;
+ QByteArray dynamic_data;
};
typedef QList PlaylistList;
typedef QFuture PlaylistItemFuture;
@@ -47,7 +50,7 @@ class PlaylistBackend : public QObject {
Playlist GetPlaylist(int id);
PlaylistItemFuture GetPlaylistItems(int playlist);
void SavePlaylistAsync(int playlist, const PlaylistItemList& items,
- int last_played);
+ int last_played, smart_playlists::GeneratorPtr dynamic);
void SetPlaylistOrder(const QList& ids);
int CreatePlaylist(const QString& name);
@@ -55,7 +58,8 @@ class PlaylistBackend : public QObject {
void RenamePlaylist(int id, const QString& new_name);
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:
static PlaylistItemPtr NewSongFromQuery(const SqlRow& row);