Seperate last played values for each playlist
This commit is contained in:
parent
f17a422797
commit
1572124962
@ -175,5 +175,6 @@
|
|||||||
<file>icons/22x22/document-new.png</file>
|
<file>icons/22x22/document-new.png</file>
|
||||||
<file>icons/32x32/document-new.png</file>
|
<file>icons/32x32/document-new.png</file>
|
||||||
<file>icons/48x48/document-new.png</file>
|
<file>icons/48x48/document-new.png</file>
|
||||||
|
<file>schema-10.sql</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
4
data/schema-10.sql
Normal file
4
data/schema-10.sql
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
ALTER TABLE playlists ADD COLUMN last_played INTEGER NOT NULL DEFAULT -1;
|
||||||
|
|
||||||
|
UPDATE schema_version SET version=10;
|
||||||
|
|
@ -27,7 +27,7 @@
|
|||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
|
||||||
const char* Database::kDatabaseFilename = "clementine.db";
|
const char* Database::kDatabaseFilename = "clementine.db";
|
||||||
const int Database::kSchemaVersion = 9;
|
const int Database::kSchemaVersion = 10;
|
||||||
|
|
||||||
int (*Database::_sqlite3_create_function) (
|
int (*Database::_sqlite3_create_function) (
|
||||||
sqlite3*, const char*, int, int, void*,
|
sqlite3*, const char*, int, int, void*,
|
||||||
|
@ -180,7 +180,8 @@ void Player::Next() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Player::NextInternal(Engine::TrackChangeType change) {
|
void Player::NextInternal(Engine::TrackChangeType change) {
|
||||||
if (playlists_->active()->current_item()->options() & PlaylistItem::ContainsMultipleTracks) {
|
if (playlists_->active()->current_item() &&
|
||||||
|
playlists_->active()->current_item()->options() & PlaylistItem::ContainsMultipleTracks) {
|
||||||
// The next track is already being loaded
|
// The next track is already being loaded
|
||||||
if (playlists_->active()->current_item()->Url() == loading_async_)
|
if (playlists_->active()->current_item()->Url() == loading_async_)
|
||||||
return;
|
return;
|
||||||
@ -232,6 +233,7 @@ void Player::PlayPause() {
|
|||||||
|
|
||||||
case Engine::Empty:
|
case Engine::Empty:
|
||||||
case Engine::Idle: {
|
case Engine::Idle: {
|
||||||
|
playlists_->SetActivePlaylist(playlists_->current_index());
|
||||||
if (playlists_->active()->rowCount() == 0)
|
if (playlists_->active()->rowCount() == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -23,6 +23,9 @@ DefaultSettingsProvider::DefaultSettingsProvider() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DefaultSettingsProvider::set_group(const char *group) {
|
void DefaultSettingsProvider::set_group(const char *group) {
|
||||||
|
while (!backend_.group().isEmpty())
|
||||||
|
backend_.endGroup();
|
||||||
|
|
||||||
backend_.beginGroup(group);
|
backend_.beginGroup(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,6 @@
|
|||||||
#include <QtDebug>
|
#include <QtDebug>
|
||||||
#include <QMimeData>
|
#include <QMimeData>
|
||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
#include <QSettings>
|
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QDirIterator>
|
#include <QDirIterator>
|
||||||
#include <QUndoStack>
|
#include <QUndoStack>
|
||||||
@ -45,12 +44,9 @@
|
|||||||
using boost::shared_ptr;
|
using boost::shared_ptr;
|
||||||
|
|
||||||
const char* Playlist::kRowsMimetype = "application/x-clementine-playlist-rows";
|
const char* Playlist::kRowsMimetype = "application/x-clementine-playlist-rows";
|
||||||
const char* Playlist::kSettingsGroup = "Playlist";
|
|
||||||
|
|
||||||
Playlist::Playlist(PlaylistBackend* backend, int id,
|
Playlist::Playlist(PlaylistBackend* backend, int id, QObject *parent)
|
||||||
QObject *parent, SettingsProvider* settings)
|
|
||||||
: QAbstractListModel(parent),
|
: QAbstractListModel(parent),
|
||||||
settings_(settings ? settings : new DefaultSettingsProvider),
|
|
||||||
backend_(backend),
|
backend_(backend),
|
||||||
id_(id),
|
id_(id),
|
||||||
current_is_paused_(false),
|
current_is_paused_(false),
|
||||||
@ -62,8 +58,6 @@ Playlist::Playlist(PlaylistBackend* backend, int id,
|
|||||||
ignore_sorting_(false),
|
ignore_sorting_(false),
|
||||||
undo_stack_(new QUndoStack(this))
|
undo_stack_(new QUndoStack(this))
|
||||||
{
|
{
|
||||||
settings_->set_group(kSettingsGroup);
|
|
||||||
|
|
||||||
connect(this, SIGNAL(rowsInserted(const QModelIndex&, int, int)), SIGNAL(PlaylistChanged()));
|
connect(this, SIGNAL(rowsInserted(const QModelIndex&, int, int)), SIGNAL(PlaylistChanged()));
|
||||||
connect(this, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), SIGNAL(PlaylistChanged()));
|
connect(this, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), SIGNAL(PlaylistChanged()));
|
||||||
|
|
||||||
@ -792,9 +786,7 @@ void Playlist::Save() const {
|
|||||||
if (!backend_)
|
if (!backend_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
backend_->SavePlaylistAsync(id_, items_);
|
backend_->SavePlaylistAsync(id_, items_, last_played_index());
|
||||||
|
|
||||||
settings_->setValue("last_index", last_played_index());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Playlist::Restore() {
|
void Playlist::Restore() {
|
||||||
@ -806,13 +798,15 @@ void Playlist::Restore() {
|
|||||||
|
|
||||||
items_ = backend_->GetPlaylistItems(id_);
|
items_ = backend_->GetPlaylistItems(id_);
|
||||||
|
|
||||||
|
PlaylistBackend::Playlist p = backend_->GetPlaylist(id_);
|
||||||
|
last_played_item_index_ =
|
||||||
|
p.last_played == -1 ? QModelIndex() : index(p.last_played);
|
||||||
|
|
||||||
for (int i=0 ; i<items_.count() ; ++i) {
|
for (int i=0 ; i<items_.count() ; ++i) {
|
||||||
virtual_items_ << i;
|
virtual_items_ << i;
|
||||||
};
|
};
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
last_played_item_index_ = index(settings_->value("last_index", -1).toInt(), 0, QModelIndex());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Playlist::removeRows(int row, int count, const QModelIndex& parent) {
|
bool Playlist::removeRows(int row, int count, const QModelIndex& parent) {
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
|
|
||||||
#include "playlistitem.h"
|
#include "playlistitem.h"
|
||||||
#include "playlistsequence.h"
|
#include "playlistsequence.h"
|
||||||
#include "core/settingsprovider.h"
|
|
||||||
#include "core/song.h"
|
#include "core/song.h"
|
||||||
#include "radio/radioitem.h"
|
#include "radio/radioitem.h"
|
||||||
|
|
||||||
@ -47,8 +46,7 @@ class Playlist : public QAbstractListModel {
|
|||||||
friend class PlaylistUndoCommands::MoveItems;
|
friend class PlaylistUndoCommands::MoveItems;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Playlist(PlaylistBackend* backend, int id,
|
Playlist(PlaylistBackend* backend, int id, QObject* parent = 0);
|
||||||
QObject* parent = 0, SettingsProvider* settings = NULL);
|
|
||||||
~Playlist();
|
~Playlist();
|
||||||
|
|
||||||
enum Column {
|
enum Column {
|
||||||
@ -83,7 +81,6 @@ class Playlist : public QAbstractListModel {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const char* kRowsMimetype;
|
static const char* kRowsMimetype;
|
||||||
static const char* kSettingsGroup;
|
|
||||||
|
|
||||||
static bool CompareItems(int column, Qt::SortOrder order,
|
static bool CompareItems(int column, Qt::SortOrder order,
|
||||||
boost::shared_ptr<PlaylistItem> a,
|
boost::shared_ptr<PlaylistItem> a,
|
||||||
@ -183,8 +180,6 @@ class Playlist : public QAbstractListModel {
|
|||||||
void MoveItemsWithoutUndo(int start, const QList<int>& dest_rows);
|
void MoveItemsWithoutUndo(int start, const QList<int>& dest_rows);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
boost::scoped_ptr<SettingsProvider> settings_;
|
|
||||||
|
|
||||||
PlaylistBackend* backend_;
|
PlaylistBackend* backend_;
|
||||||
int id_;
|
int id_;
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ PlaylistBackend::PlaylistList PlaylistBackend::GetAllPlaylists() {
|
|||||||
|
|
||||||
PlaylistList ret;
|
PlaylistList ret;
|
||||||
|
|
||||||
QSqlQuery q("SELECT ROWID, name FROM playlists", db);
|
QSqlQuery q("SELECT ROWID, name, last_played FROM playlists", db);
|
||||||
q.exec();
|
q.exec();
|
||||||
if (db_->CheckErrors(q.lastError()))
|
if (db_->CheckErrors(q.lastError()))
|
||||||
return ret;
|
return ret;
|
||||||
@ -44,12 +44,33 @@ PlaylistBackend::PlaylistList PlaylistBackend::GetAllPlaylists() {
|
|||||||
Playlist p;
|
Playlist p;
|
||||||
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();
|
||||||
ret << p;
|
ret << p;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PlaylistBackend::Playlist PlaylistBackend::GetPlaylist(int id) {
|
||||||
|
QSqlDatabase db(db_->Connect());
|
||||||
|
|
||||||
|
QSqlQuery q("SELECT ROWID, name, last_played FROM playlists"
|
||||||
|
" WHERE ROWID=:id", db);
|
||||||
|
q.bindValue(":id", id);
|
||||||
|
q.exec();
|
||||||
|
if (db_->CheckErrors(q.lastError()))
|
||||||
|
return Playlist();
|
||||||
|
|
||||||
|
q.next();
|
||||||
|
|
||||||
|
Playlist p;
|
||||||
|
p.id = q.value(0).toInt();
|
||||||
|
p.name = q.value(1).toString();
|
||||||
|
p.last_played = q.value(2).toInt();
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
PlaylistItemList PlaylistBackend::GetPlaylistItems(int playlist) {
|
PlaylistItemList PlaylistBackend::GetPlaylistItems(int playlist) {
|
||||||
QSqlDatabase db(db_->Connect());
|
QSqlDatabase db(db_->Connect());
|
||||||
|
|
||||||
@ -86,13 +107,16 @@ PlaylistItemList PlaylistBackend::GetPlaylistItems(int playlist) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlaylistBackend::SavePlaylistAsync(int playlist, const PlaylistItemList &items) {
|
void PlaylistBackend::SavePlaylistAsync(int playlist, const PlaylistItemList &items,
|
||||||
|
int last_played) {
|
||||||
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlaylistBackend::SavePlaylist(int playlist, const PlaylistItemList& items) {
|
void PlaylistBackend::SavePlaylist(int playlist, const PlaylistItemList& items,
|
||||||
|
int last_played) {
|
||||||
QSqlDatabase db(db_->Connect());
|
QSqlDatabase db(db_->Connect());
|
||||||
|
|
||||||
QSqlQuery clear("DELETE FROM playlist_items WHERE playlist = :playlist", db);
|
QSqlQuery clear("DELETE FROM playlist_items WHERE playlist = :playlist", db);
|
||||||
@ -100,6 +124,8 @@ 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"
|
||||||
|
" WHERE ROWID=:playlist", db);
|
||||||
|
|
||||||
ScopedTransaction transaction(&db);
|
ScopedTransaction transaction(&db);
|
||||||
|
|
||||||
@ -118,6 +144,13 @@ void PlaylistBackend::SavePlaylist(int playlist, const PlaylistItemList& items)
|
|||||||
db_->CheckErrors(insert.lastError());
|
db_->CheckErrors(insert.lastError());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the last played track number
|
||||||
|
update.bindValue(":last_played", last_played);
|
||||||
|
update.bindValue(":id", playlist);
|
||||||
|
update.exec();
|
||||||
|
if (db_->CheckErrors(update.lastError()))
|
||||||
|
return;
|
||||||
|
|
||||||
transaction.Commit();
|
transaction.Commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,19 +33,22 @@ class PlaylistBackend : public QObject {
|
|||||||
struct Playlist {
|
struct Playlist {
|
||||||
int id;
|
int id;
|
||||||
QString name;
|
QString name;
|
||||||
|
int last_played;
|
||||||
};
|
};
|
||||||
typedef QList<Playlist> PlaylistList;
|
typedef QList<Playlist> PlaylistList;
|
||||||
|
|
||||||
PlaylistList GetAllPlaylists();
|
PlaylistList GetAllPlaylists();
|
||||||
|
Playlist GetPlaylist(int id);
|
||||||
PlaylistItemList GetPlaylistItems(int playlist);
|
PlaylistItemList GetPlaylistItems(int playlist);
|
||||||
void SavePlaylistAsync(int playlist, const PlaylistItemList& items);
|
void SavePlaylistAsync(int playlist, const PlaylistItemList& items,
|
||||||
|
int last_played);
|
||||||
|
|
||||||
int CreatePlaylist(const QString& name);
|
int CreatePlaylist(const QString& name);
|
||||||
void RemovePlaylist(int id);
|
void RemovePlaylist(int id);
|
||||||
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);
|
void SavePlaylist(int playlist, const PlaylistItemList& items, int last_played);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Database* db_;
|
Database* db_;
|
||||||
|
@ -102,11 +102,11 @@ void PlaylistManager::Remove(int index) {
|
|||||||
|
|
||||||
playlist_backend_->RemovePlaylist(playlist(index)->id());
|
playlist_backend_->RemovePlaylist(playlist(index)->id());
|
||||||
|
|
||||||
playlists_.takeAt(index);
|
|
||||||
if (index == active_)
|
if (index == active_)
|
||||||
SetActivePlaylist(qMin(0, index-1));
|
SetActivePlaylist(qMax(0, index-1));
|
||||||
if (index == current_)
|
if (index == current_)
|
||||||
SetCurrentPlaylist(qMin(0, index-1));
|
SetCurrentPlaylist(qMax(0, index-1));
|
||||||
|
playlists_.takeAt(index);
|
||||||
|
|
||||||
emit PlaylistRemoved(index);
|
emit PlaylistRemoved(index);
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ namespace {
|
|||||||
class PlaylistTest : public ::testing::Test {
|
class PlaylistTest : public ::testing::Test {
|
||||||
protected:
|
protected:
|
||||||
PlaylistTest()
|
PlaylistTest()
|
||||||
: playlist_(NULL, NULL, new DummySettingsProvider),
|
: playlist_(NULL, NULL),
|
||||||
sequence_(NULL, new DummySettingsProvider)
|
sequence_(NULL, new DummySettingsProvider)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user