Refactoring
This commit is contained in:
@@ -58,15 +58,16 @@
|
||||
#include <QSettings>
|
||||
#include <QTimer>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/application.h"
|
||||
#include "includes/shared_ptr.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/mimedata.h"
|
||||
#include "core/song.h"
|
||||
#include "core/settings.h"
|
||||
#include "utilities/timeconstants.h"
|
||||
#include "core/songmimedata.h"
|
||||
#include "constants/timeconstants.h"
|
||||
#include "constants/playlistsettings.h"
|
||||
#include "tagreader/tagreaderclient.h"
|
||||
#include "collection/collection.h"
|
||||
#include "collection/collectionlibrary.h"
|
||||
#include "collection/collectionbackend.h"
|
||||
#include "collection/collectionplaylistitem.h"
|
||||
#include "covermanager/albumcoverloaderresult.h"
|
||||
@@ -78,10 +79,14 @@
|
||||
#include "playlistbackend.h"
|
||||
#include "playlistfilter.h"
|
||||
#include "playlistitemmimedata.h"
|
||||
#include "playlistundocommands.h"
|
||||
#include "songloaderinserter.h"
|
||||
#include "songmimedata.h"
|
||||
#include "songplaylistitem.h"
|
||||
#include "playlistundocommandinsertitems.h"
|
||||
#include "playlistundocommandremoveitems.h"
|
||||
#include "playlistundocommandmoveitems.h"
|
||||
#include "playlistundocommandreorderitems.h"
|
||||
#include "playlistundocommandsortitems.h"
|
||||
#include "playlistundocommandshuffleitems.h"
|
||||
|
||||
#include "smartplaylists/playlistgenerator.h"
|
||||
#include "smartplaylists/playlistgeneratorinserter.h"
|
||||
@@ -98,7 +103,6 @@ using std::make_shared;
|
||||
using namespace std::chrono_literals;
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
const char *Playlist::kSettingsGroup = "Playlist";
|
||||
const char *Playlist::kCddaMimeType = "x-content/audio-cdda";
|
||||
const char *Playlist::kRowsMimetype = "application/x-strawberry-playlist-rows";
|
||||
const char *Playlist::kPlayNowMimetype = "application/x-strawberry-play-now";
|
||||
@@ -120,15 +124,25 @@ constexpr int kMaxPlayedIndexes = 100;
|
||||
|
||||
} // namespace
|
||||
|
||||
Playlist::Playlist(SharedPtr<PlaylistBackend> backend, SharedPtr<TaskManager> task_manager, SharedPtr<CollectionBackend> collection_backend, const int id, const QString &special_type, const bool favorite, QObject *parent)
|
||||
Playlist::Playlist(const SharedPtr<TaskManager> task_manager,
|
||||
const SharedPtr<UrlHandlers> url_handlers,
|
||||
const SharedPtr<PlaylistBackend> playlist_backend,
|
||||
const SharedPtr<CollectionBackend> collection_backend,
|
||||
const SharedPtr<TagReaderClient> tagreader_client,
|
||||
const int id,
|
||||
const QString &special_type,
|
||||
const bool favorite,
|
||||
QObject *parent)
|
||||
: QAbstractListModel(parent),
|
||||
is_loading_(false),
|
||||
filter_(new PlaylistFilter(this)),
|
||||
queue_(new Queue(this, this)),
|
||||
timer_save_(new QTimer(this)),
|
||||
backend_(backend),
|
||||
task_manager_(task_manager),
|
||||
url_handlers_(url_handlers),
|
||||
playlist_backend_(playlist_backend),
|
||||
collection_backend_(collection_backend),
|
||||
tagreader_client_(tagreader_client),
|
||||
id_(id),
|
||||
favorite_(favorite),
|
||||
current_is_paused_(false),
|
||||
@@ -418,7 +432,7 @@ bool Playlist::setData(const QModelIndex &idx, const QVariant &value, const int
|
||||
if (!set_column_value(song, static_cast<Column>(idx.column()), value)) return false;
|
||||
|
||||
if (song.url().isLocalFile()) {
|
||||
TagReaderReplyPtr reply = TagReaderClient::Instance()->WriteFileAsync(song.url().toLocalFile(), song);
|
||||
TagReaderReplyPtr reply = tagreader_client_->WriteFileAsync(song.url().toLocalFile(), song);
|
||||
QPersistentModelIndex persistent_index = QPersistentModelIndex(idx);
|
||||
QObject::connect(&*reply, &TagReaderReply::Finished, this, [this, reply, persistent_index, item]() { SongSaveComplete(reply, persistent_index, item->OriginalMetadata()); }, Qt::QueuedConnection);
|
||||
}
|
||||
@@ -813,7 +827,7 @@ bool Playlist::dropMimeData(const QMimeData *data, Qt::DropAction action, const
|
||||
if (const SongMimeData *song_data = qobject_cast<const SongMimeData*>(data)) {
|
||||
// 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.
|
||||
if (song_data->backend && song_data->backend->songs_table() == QLatin1String(SCollection::kSongsTable)) {
|
||||
if (song_data->backend && song_data->backend->songs_table() == QLatin1String(CollectionLibrary::kSongsTable)) {
|
||||
InsertSongItems<CollectionPlaylistItem>(song_data->songs, row, play_now, enqueue_now, enqueue_next_now);
|
||||
}
|
||||
else {
|
||||
@@ -856,7 +870,7 @@ bool Playlist::dropMimeData(const QMimeData *data, Qt::DropAction action, const
|
||||
|
||||
if (source_playlist == this) {
|
||||
// Dragged from this playlist - rearrange the items
|
||||
undo_stack_->push(new PlaylistUndoCommands::MoveItems(this, source_rows, row));
|
||||
undo_stack_->push(new PlaylistUndoCommandMoveItems(this, source_rows, row));
|
||||
}
|
||||
else if (pid == own_pid) {
|
||||
// Drag from a different playlist
|
||||
@@ -870,19 +884,19 @@ bool Playlist::dropMimeData(const QMimeData *data, Qt::DropAction action, const
|
||||
undo_stack_->clear();
|
||||
}
|
||||
else {
|
||||
undo_stack_->push(new PlaylistUndoCommands::InsertItems(this, items, row));
|
||||
undo_stack_->push(new PlaylistUndoCommandInsertItems(this, items, row));
|
||||
}
|
||||
|
||||
// Remove the items from the source playlist if it was a move event
|
||||
if (action == Qt::MoveAction) {
|
||||
for (const int i : std::as_const(source_rows)) {
|
||||
source_playlist->undo_stack()->push(new PlaylistUndoCommands::RemoveItems(source_playlist, i, 1));
|
||||
source_playlist->undo_stack()->push(new PlaylistUndoCommandRemoveItems(source_playlist, i, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (data->hasFormat(QLatin1String(kCddaMimeType))) {
|
||||
SongLoaderInserter *inserter = new SongLoaderInserter(task_manager_, collection_backend_, backend_->app()->player());
|
||||
SongLoaderInserter *inserter = new SongLoaderInserter(task_manager_, tagreader_client_, url_handlers_, collection_backend_);
|
||||
QObject::connect(inserter, &SongLoaderInserter::Error, this, &Playlist::Error);
|
||||
inserter->LoadAudioCD(this, row, play_now, enqueue_now, enqueue_next_now);
|
||||
}
|
||||
@@ -897,7 +911,7 @@ bool Playlist::dropMimeData(const QMimeData *data, Qt::DropAction action, const
|
||||
|
||||
void Playlist::InsertUrls(const QList<QUrl> &urls, const int pos, const bool play_now, const bool enqueue, const bool enqueue_next) {
|
||||
|
||||
SongLoaderInserter *inserter = new SongLoaderInserter(task_manager_, collection_backend_, backend_->app()->player());
|
||||
SongLoaderInserter *inserter = new SongLoaderInserter(task_manager_, tagreader_client_, url_handlers_, collection_backend_);
|
||||
QObject::connect(inserter, &SongLoaderInserter::Error, this, &Playlist::Error);
|
||||
|
||||
inserter->Load(this, pos, play_now, enqueue, enqueue_next, urls);
|
||||
@@ -1095,7 +1109,7 @@ void Playlist::InsertItems(const PlaylistItemPtrList &itemsIn, const int pos, co
|
||||
undo_stack_->clear();
|
||||
}
|
||||
else {
|
||||
undo_stack_->push(new PlaylistUndoCommands::InsertItems(this, items, pos, enqueue, enqueue_next));
|
||||
undo_stack_->push(new PlaylistUndoCommandInsertItems(this, items, pos, enqueue, enqueue_next));
|
||||
}
|
||||
|
||||
if (play_now) Q_EMIT PlayRequested(index(start, 0), AutoScroll::Maybe);
|
||||
@@ -1254,7 +1268,7 @@ void Playlist::UpdateItems(SongList songs) {
|
||||
// Also update undo actions
|
||||
for (int y = 0; y < undo_stack_->count(); y++) {
|
||||
QUndoCommand *undo_action = const_cast<QUndoCommand*>(undo_stack_->command(i));
|
||||
PlaylistUndoCommands::InsertItems *undo_action_insert = dynamic_cast<PlaylistUndoCommands::InsertItems*>(undo_action);
|
||||
PlaylistUndoCommandInsertItems *undo_action_insert = dynamic_cast<PlaylistUndoCommandInsertItems*>(undo_action);
|
||||
if (undo_action_insert) {
|
||||
bool found_and_updated = undo_action_insert->UpdateItem(new_item);
|
||||
if (found_and_updated) break;
|
||||
@@ -1464,7 +1478,7 @@ void Playlist::sort(const int column_number, const Qt::SortOrder order) {
|
||||
std::stable_sort(begin, new_items.end(), std::bind(&Playlist::CompareItems, column, order, std::placeholders::_1, std::placeholders::_2));
|
||||
}
|
||||
|
||||
undo_stack_->push(new PlaylistUndoCommands::SortItems(this, column, order, new_items));
|
||||
undo_stack_->push(new PlaylistUndoCommandSortItems(this, column, order, new_items));
|
||||
|
||||
}
|
||||
|
||||
@@ -1541,7 +1555,7 @@ void Playlist::ScheduleSaveAsync() {
|
||||
|
||||
void Playlist::ScheduleSave() {
|
||||
|
||||
if (!backend_ || is_loading_) return;
|
||||
if (!playlist_backend_ || is_loading_) return;
|
||||
|
||||
timer_save_->start();
|
||||
|
||||
@@ -1549,22 +1563,22 @@ void Playlist::ScheduleSave() {
|
||||
|
||||
void Playlist::Save() {
|
||||
|
||||
if (!backend_ || is_loading_) return;
|
||||
if (!playlist_backend_ || is_loading_) return;
|
||||
|
||||
backend_->SavePlaylistAsync(id_, items_, last_played_row(), dynamic_playlist_);
|
||||
playlist_backend_->SavePlaylistAsync(id_, items_, last_played_row(), dynamic_playlist_);
|
||||
|
||||
}
|
||||
|
||||
void Playlist::Restore() {
|
||||
|
||||
if (!backend_) return;
|
||||
if (!playlist_backend_) return;
|
||||
|
||||
items_.clear();
|
||||
virtual_items_.clear();
|
||||
collection_items_by_id_.clear();
|
||||
|
||||
cancel_restore_ = false;
|
||||
QFuture<PlaylistItemPtrList> future = QtConcurrent::run(&PlaylistBackend::GetPlaylistItems, backend_, id_);
|
||||
QFuture<PlaylistItemPtrList> future = QtConcurrent::run(&PlaylistBackend::GetPlaylistItems, playlist_backend_, id_);
|
||||
QFutureWatcher<PlaylistItemPtrList> *watcher = new QFutureWatcher<PlaylistItemPtrList>();
|
||||
QObject::connect(watcher, &QFutureWatcher<PlaylistItemPtrList>::finished, this, &Playlist::ItemsLoaded);
|
||||
watcher->setFuture(future);
|
||||
@@ -1593,7 +1607,7 @@ void Playlist::ItemsLoaded() {
|
||||
InsertItems(items, 0);
|
||||
is_loading_ = false;
|
||||
|
||||
PlaylistBackend::Playlist p = backend_->GetPlaylist(id_);
|
||||
PlaylistBackend::Playlist p = playlist_backend_->GetPlaylist(id_);
|
||||
|
||||
// The newly loaded list of items might be shorter than it was before so look out for a bad last_played index
|
||||
last_played_item_index_ = p.last_played == -1 || p.last_played >= rowCount() ? QModelIndex() : index(p.last_played);
|
||||
@@ -1617,8 +1631,8 @@ void Playlist::ItemsLoaded() {
|
||||
Q_EMIT RestoreFinished();
|
||||
|
||||
Settings s;
|
||||
s.beginGroup(kSettingsGroup);
|
||||
bool greyout = s.value("greyout_songs_startup", true).toBool();
|
||||
s.beginGroup(PlaylistSettings::kSettingsGroup);
|
||||
bool greyout = s.value(PlaylistSettings::kGreyoutSongsStartup, true).toBool();
|
||||
s.endGroup();
|
||||
|
||||
// Should we gray out deleted songs asynchronously on startup?
|
||||
@@ -1667,7 +1681,7 @@ bool Playlist::removeRows(const int row, const int count, const QModelIndex &par
|
||||
undo_stack_->clear();
|
||||
}
|
||||
else {
|
||||
undo_stack_->push(new PlaylistUndoCommands::RemoveItems(this, row, count));
|
||||
undo_stack_->push(new PlaylistUndoCommandRemoveItems(this, row, count));
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -1839,7 +1853,7 @@ void Playlist::Clear() {
|
||||
undo_stack_->clear();
|
||||
}
|
||||
else {
|
||||
undo_stack_->push(new PlaylistUndoCommands::RemoveItems(this, 0, count));
|
||||
undo_stack_->push(new PlaylistUndoCommandRemoveItems(this, 0, count));
|
||||
}
|
||||
|
||||
TurnOffDynamicPlaylist();
|
||||
@@ -1942,7 +1956,7 @@ void Playlist::Shuffle() {
|
||||
std::swap(new_items[i], new_items[new_pos]);
|
||||
}
|
||||
|
||||
undo_stack_->push(new PlaylistUndoCommands::ShuffleItems(this, new_items));
|
||||
undo_stack_->push(new PlaylistUndoCommandShuffleItems(this, new_items));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
#include <QColor>
|
||||
#include <QRgb>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "includes/shared_ptr.h"
|
||||
#include "core/song.h"
|
||||
#include "tagreader/tagreaderclient.h"
|
||||
#include "covermanager/albumcoverloaderresult.h"
|
||||
@@ -54,11 +54,12 @@ class QMimeData;
|
||||
class QUndoStack;
|
||||
class QTimer;
|
||||
|
||||
class TaskManager;
|
||||
class UrlHandlers;
|
||||
class CollectionBackend;
|
||||
class PlaylistBackend;
|
||||
class PlaylistFilter;
|
||||
class Queue;
|
||||
class TaskManager;
|
||||
class RadioService;
|
||||
|
||||
namespace PlaylistUndoCommands {
|
||||
@@ -77,13 +78,22 @@ Q_DECLARE_METATYPE(ColumnAlignmentMap)
|
||||
class Playlist : public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
|
||||
friend class PlaylistUndoCommands::InsertItems;
|
||||
friend class PlaylistUndoCommands::RemoveItems;
|
||||
friend class PlaylistUndoCommands::MoveItems;
|
||||
friend class PlaylistUndoCommands::ReOrderItems;
|
||||
friend class PlaylistUndoCommandInsertItems;
|
||||
friend class PlaylistUndoCommandRemoveItems;
|
||||
friend class PlaylistUndoCommandMoveItems;
|
||||
friend class PlaylistUndoCommandReOrderItems;
|
||||
|
||||
public:
|
||||
explicit Playlist(SharedPtr<PlaylistBackend> playlist_backend, SharedPtr<TaskManager> task_manager, SharedPtr<CollectionBackend> collection_backend, const int id, const QString &special_type = QString(), const bool favorite = false, QObject *parent = nullptr);
|
||||
explicit Playlist(const SharedPtr<TaskManager> task_manager,
|
||||
const SharedPtr<UrlHandlers> url_handlers,
|
||||
const SharedPtr<PlaylistBackend> playlist_backend,
|
||||
const SharedPtr<CollectionBackend> collection_backend,
|
||||
const SharedPtr<TagReaderClient> tagreader_client,
|
||||
const int id,
|
||||
const QString &special_type = QString(),
|
||||
const bool favorite = false,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
~Playlist() override;
|
||||
|
||||
void SkipTracks(const QModelIndexList &source_indexes);
|
||||
@@ -141,7 +151,6 @@ class Playlist : public QAbstractListModel {
|
||||
Always
|
||||
};
|
||||
|
||||
static const char *kSettingsGroup;
|
||||
static const char *kCddaMimeType;
|
||||
static const char *kRowsMimetype;
|
||||
static const char *kPlayNowMimetype;
|
||||
@@ -364,9 +373,12 @@ class Playlist : public QAbstractListModel {
|
||||
|
||||
QList<QModelIndex> temp_dequeue_change_indexes_;
|
||||
|
||||
SharedPtr<PlaylistBackend> backend_;
|
||||
SharedPtr<TaskManager> task_manager_;
|
||||
SharedPtr<CollectionBackend> collection_backend_;
|
||||
const SharedPtr<TaskManager> task_manager_;
|
||||
const SharedPtr<UrlHandlers> url_handlers_;
|
||||
const SharedPtr<PlaylistBackend> playlist_backend_;
|
||||
const SharedPtr<CollectionBackend> collection_backend_;
|
||||
const SharedPtr<TagReaderClient> tagreader_client_;
|
||||
|
||||
int id_;
|
||||
QString ui_path_;
|
||||
bool favorite_;
|
||||
|
||||
@@ -38,8 +38,7 @@
|
||||
#include <QUrl>
|
||||
#include <QSqlDatabase>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/application.h"
|
||||
#include "includes/shared_ptr.h"
|
||||
#include "core/database.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/scopedtransaction.h"
|
||||
@@ -60,10 +59,14 @@ namespace {
|
||||
constexpr int kSongTableJoins = 2;
|
||||
}
|
||||
|
||||
PlaylistBackend::PlaylistBackend(Application *app, QObject *parent)
|
||||
PlaylistBackend::PlaylistBackend(const SharedPtr<Database> database,
|
||||
const SharedPtr<TagReaderClient> tagreader_client,
|
||||
const SharedPtr<CollectionBackend> collection_backend,
|
||||
QObject *parent)
|
||||
: QObject(parent),
|
||||
app_(app),
|
||||
db_(app_->database()),
|
||||
database_(database),
|
||||
tagreader_client_(tagreader_client),
|
||||
collection_backend_(collection_backend),
|
||||
original_thread_(nullptr) {
|
||||
|
||||
setObjectName(QLatin1String(metaObject()->className()));
|
||||
@@ -74,9 +77,9 @@ PlaylistBackend::PlaylistBackend(Application *app, QObject *parent)
|
||||
|
||||
void PlaylistBackend::Close() {
|
||||
|
||||
if (db_) {
|
||||
QMutexLocker l(db_->Mutex());
|
||||
db_->Close();
|
||||
if (database_) {
|
||||
QMutexLocker l(database_->Mutex());
|
||||
database_->Close();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -108,8 +111,8 @@ PlaylistBackend::PlaylistList PlaylistBackend::GetAllFavoritePlaylists() {
|
||||
|
||||
PlaylistBackend::PlaylistList PlaylistBackend::GetPlaylists(const GetPlaylistsFlags flags) {
|
||||
|
||||
QMutexLocker l(db_->Mutex());
|
||||
QSqlDatabase db(db_->Connect());
|
||||
QMutexLocker l(database_->Mutex());
|
||||
QSqlDatabase db(database_->Connect());
|
||||
|
||||
PlaylistList ret;
|
||||
|
||||
@@ -128,7 +131,7 @@ PlaylistBackend::PlaylistList PlaylistBackend::GetPlaylists(const GetPlaylistsFl
|
||||
SqlQuery q(db);
|
||||
q.prepare(u"SELECT ROWID, name, last_played, special_type, ui_path, is_favorite, dynamic_playlist_type, dynamic_playlist_data, dynamic_playlist_backend FROM playlists "_s + condition + u" ORDER BY ui_order"_s);
|
||||
if (!q.Exec()) {
|
||||
db_->ReportErrors(q);
|
||||
database_->ReportErrors(q);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -152,15 +155,15 @@ PlaylistBackend::PlaylistList PlaylistBackend::GetPlaylists(const GetPlaylistsFl
|
||||
|
||||
PlaylistBackend::Playlist PlaylistBackend::GetPlaylist(const int id) {
|
||||
|
||||
QMutexLocker l(db_->Mutex());
|
||||
QSqlDatabase db(db_->Connect());
|
||||
QMutexLocker l(database_->Mutex());
|
||||
QSqlDatabase db(database_->Connect());
|
||||
|
||||
SqlQuery q(db);
|
||||
q.prepare(u"SELECT ROWID, name, last_played, special_type, ui_path, is_favorite, dynamic_playlist_type, dynamic_playlist_data, dynamic_playlist_backend FROM playlists WHERE ROWID=:id"_s);
|
||||
|
||||
q.BindValue(u":id"_s, id);
|
||||
if (!q.Exec()) {
|
||||
db_->ReportErrors(q);
|
||||
database_->ReportErrors(q);
|
||||
return Playlist();
|
||||
}
|
||||
|
||||
@@ -187,8 +190,8 @@ PlaylistItemPtrList PlaylistBackend::GetPlaylistItems(const int playlist) {
|
||||
|
||||
{
|
||||
|
||||
QMutexLocker l(db_->Mutex());
|
||||
QSqlDatabase db(db_->Connect());
|
||||
QMutexLocker l(database_->Mutex());
|
||||
QSqlDatabase db(database_->Connect());
|
||||
|
||||
QString query = QStringLiteral("SELECT %1, %2, p.type FROM playlist_items AS p LEFT JOIN songs ON p.collection_id = songs.ROWID WHERE p.playlist = :playlist").arg(Song::JoinSpec(QStringLiteral("songs")), Song::JoinSpec(QStringLiteral("p")));
|
||||
|
||||
@@ -198,7 +201,7 @@ PlaylistItemPtrList PlaylistBackend::GetPlaylistItems(const int playlist) {
|
||||
q.prepare(query);
|
||||
q.BindValue(u":playlist"_s, playlist);
|
||||
if (!q.Exec()) {
|
||||
db_->ReportErrors(q);
|
||||
database_->ReportErrors(q);
|
||||
return PlaylistItemPtrList();
|
||||
}
|
||||
|
||||
@@ -223,8 +226,8 @@ SongList PlaylistBackend::GetPlaylistSongs(const int playlist) {
|
||||
SongList songs;
|
||||
|
||||
{
|
||||
QMutexLocker l(db_->Mutex());
|
||||
QSqlDatabase db(db_->Connect());
|
||||
QMutexLocker l(database_->Mutex());
|
||||
QSqlDatabase db(database_->Connect());
|
||||
|
||||
QString query = QStringLiteral("SELECT %1, %2, p.type FROM playlist_items AS p LEFT JOIN songs ON p.collection_id = songs.ROWID WHERE p.playlist = :playlist").arg(Song::JoinSpec(u"songs"_s), Song::JoinSpec(u"p"_s));
|
||||
|
||||
@@ -234,7 +237,7 @@ SongList PlaylistBackend::GetPlaylistSongs(const int playlist) {
|
||||
q.prepare(query);
|
||||
q.BindValue(u":playlist"_s, playlist);
|
||||
if (!q.Exec()) {
|
||||
db_->ReportErrors(q);
|
||||
database_->ReportErrors(q);
|
||||
return SongList();
|
||||
}
|
||||
|
||||
@@ -282,7 +285,7 @@ PlaylistItemPtr PlaylistBackend::RestoreCueData(PlaylistItemPtr item, SharedPtr<
|
||||
// We need collection to run a CueParser; also, this method applies only to file-type PlaylistItems
|
||||
if (item->source() != Song::Source::LocalFile) return item;
|
||||
|
||||
CueParser cue_parser(app_->collection_backend());
|
||||
CueParser cue_parser(tagreader_client_, collection_backend_);
|
||||
|
||||
Song song = item->Metadata();
|
||||
// We're only interested in .cue songs here
|
||||
@@ -334,8 +337,8 @@ void PlaylistBackend::SavePlaylistAsync(int playlist, const PlaylistItemPtrList
|
||||
|
||||
void PlaylistBackend::SavePlaylist(int playlist, const PlaylistItemPtrList &items, int last_played, PlaylistGeneratorPtr dynamic) {
|
||||
|
||||
QMutexLocker l(db_->Mutex());
|
||||
QSqlDatabase db(db_->Connect());
|
||||
QMutexLocker l(database_->Mutex());
|
||||
QSqlDatabase db(database_->Connect());
|
||||
|
||||
qLog(Debug) << "Saving playlist" << playlist;
|
||||
|
||||
@@ -347,7 +350,7 @@ void PlaylistBackend::SavePlaylist(int playlist, const PlaylistItemPtrList &item
|
||||
q.prepare(u"DELETE FROM playlist_items WHERE playlist = :playlist"_s);
|
||||
q.BindValue(u":playlist"_s, playlist);
|
||||
if (!q.Exec()) {
|
||||
db_->ReportErrors(q);
|
||||
database_->ReportErrors(q);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -360,7 +363,7 @@ void PlaylistBackend::SavePlaylist(int playlist, const PlaylistItemPtrList &item
|
||||
item->BindToQuery(&q);
|
||||
|
||||
if (!q.Exec()) {
|
||||
db_->ReportErrors(q);
|
||||
database_->ReportErrors(q);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -382,7 +385,7 @@ void PlaylistBackend::SavePlaylist(int playlist, const PlaylistItemPtrList &item
|
||||
}
|
||||
q.BindValue(u":playlist"_s, playlist);
|
||||
if (!q.Exec()) {
|
||||
db_->ReportErrors(q);
|
||||
database_->ReportErrors(q);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -393,15 +396,15 @@ void PlaylistBackend::SavePlaylist(int playlist, const PlaylistItemPtrList &item
|
||||
|
||||
int PlaylistBackend::CreatePlaylist(const QString &name, const QString &special_type) {
|
||||
|
||||
QMutexLocker l(db_->Mutex());
|
||||
QSqlDatabase db(db_->Connect());
|
||||
QMutexLocker l(database_->Mutex());
|
||||
QSqlDatabase db(database_->Connect());
|
||||
|
||||
SqlQuery q(db);
|
||||
q.prepare(u"INSERT INTO playlists (name, special_type) VALUES (:name, :special_type)"_s);
|
||||
q.BindValue(u":name"_s, name);
|
||||
q.BindValue(u":special_type"_s, special_type);
|
||||
if (!q.Exec()) {
|
||||
db_->ReportErrors(q);
|
||||
database_->ReportErrors(q);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -411,8 +414,8 @@ int PlaylistBackend::CreatePlaylist(const QString &name, const QString &special_
|
||||
|
||||
void PlaylistBackend::RemovePlaylist(int id) {
|
||||
|
||||
QMutexLocker l(db_->Mutex());
|
||||
QSqlDatabase db(db_->Connect());
|
||||
QMutexLocker l(database_->Mutex());
|
||||
QSqlDatabase db(database_->Connect());
|
||||
|
||||
ScopedTransaction transaction(&db);
|
||||
|
||||
@@ -421,7 +424,7 @@ void PlaylistBackend::RemovePlaylist(int id) {
|
||||
q.prepare(u"DELETE FROM playlists WHERE ROWID=:id"_s);
|
||||
q.BindValue(u":id"_s, id);
|
||||
if (!q.Exec()) {
|
||||
db_->ReportErrors(q);
|
||||
database_->ReportErrors(q);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -431,7 +434,7 @@ void PlaylistBackend::RemovePlaylist(int id) {
|
||||
q.prepare(u"DELETE FROM playlist_items WHERE playlist=:id"_s);
|
||||
q.BindValue(u":id"_s, id);
|
||||
if (!q.Exec()) {
|
||||
db_->ReportErrors(q);
|
||||
database_->ReportErrors(q);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -442,44 +445,44 @@ void PlaylistBackend::RemovePlaylist(int id) {
|
||||
|
||||
void PlaylistBackend::RenamePlaylist(const int id, const QString &new_name) {
|
||||
|
||||
QMutexLocker l(db_->Mutex());
|
||||
QSqlDatabase db(db_->Connect());
|
||||
QMutexLocker l(database_->Mutex());
|
||||
QSqlDatabase db(database_->Connect());
|
||||
SqlQuery q(db);
|
||||
q.prepare(u"UPDATE playlists SET name=:name WHERE ROWID=:id"_s);
|
||||
q.BindValue(u":name"_s, new_name);
|
||||
q.BindValue(u":id"_s, id);
|
||||
|
||||
if (!q.Exec()) {
|
||||
db_->ReportErrors(q);
|
||||
database_->ReportErrors(q);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void PlaylistBackend::FavoritePlaylist(const int id, const bool is_favorite) {
|
||||
|
||||
QMutexLocker l(db_->Mutex());
|
||||
QSqlDatabase db(db_->Connect());
|
||||
QMutexLocker l(database_->Mutex());
|
||||
QSqlDatabase db(database_->Connect());
|
||||
SqlQuery q(db);
|
||||
q.prepare(u"UPDATE playlists SET is_favorite=:is_favorite WHERE ROWID=:id"_s);
|
||||
q.BindValue(u":is_favorite"_s, is_favorite ? 1 : 0);
|
||||
q.BindValue(u":id"_s, id);
|
||||
|
||||
if (!q.Exec()) {
|
||||
db_->ReportErrors(q);
|
||||
database_->ReportErrors(q);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void PlaylistBackend::SetPlaylistOrder(const QList<int> &ids) {
|
||||
|
||||
QMutexLocker l(db_->Mutex());
|
||||
QSqlDatabase db(db_->Connect());
|
||||
QMutexLocker l(database_->Mutex());
|
||||
QSqlDatabase db(database_->Connect());
|
||||
ScopedTransaction transaction(&db);
|
||||
|
||||
SqlQuery q(db);
|
||||
q.prepare(u"UPDATE playlists SET ui_order=-1"_s);
|
||||
if (!q.Exec()) {
|
||||
db_->ReportErrors(q);
|
||||
database_->ReportErrors(q);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -488,7 +491,7 @@ void PlaylistBackend::SetPlaylistOrder(const QList<int> &ids) {
|
||||
q.BindValue(u":index"_s, i);
|
||||
q.BindValue(u":id"_s, ids[i]);
|
||||
if (!q.Exec()) {
|
||||
db_->ReportErrors(q);
|
||||
database_->ReportErrors(q);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -499,8 +502,8 @@ void PlaylistBackend::SetPlaylistOrder(const QList<int> &ids) {
|
||||
|
||||
void PlaylistBackend::SetPlaylistUiPath(const int id, const QString &path) {
|
||||
|
||||
QMutexLocker l(db_->Mutex());
|
||||
QSqlDatabase db(db_->Connect());
|
||||
QMutexLocker l(database_->Mutex());
|
||||
QSqlDatabase db(database_->Connect());
|
||||
SqlQuery q(db);
|
||||
q.prepare(u"UPDATE playlists SET ui_path=:path WHERE ROWID=:id"_s);
|
||||
|
||||
@@ -509,7 +512,7 @@ void PlaylistBackend::SetPlaylistUiPath(const int id, const QString &path) {
|
||||
q.BindValue(u":path"_s, path);
|
||||
q.BindValue(u":id"_s, id);
|
||||
if (!q.Exec()) {
|
||||
db_->ReportErrors(q);
|
||||
database_->ReportErrors(q);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,24 +30,25 @@
|
||||
#include <QList>
|
||||
#include <QSet>
|
||||
#include <QString>
|
||||
#include <QSqlQuery>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "includes/shared_ptr.h"
|
||||
#include "core/song.h"
|
||||
#include "core/sqlquery.h"
|
||||
#include "core/sqlrow.h"
|
||||
#include "playlistitem.h"
|
||||
#include "smartplaylists/playlistgenerator.h"
|
||||
|
||||
class QThread;
|
||||
class Application;
|
||||
class Database;
|
||||
class TagReaderClient;
|
||||
|
||||
class PlaylistBackend : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Q_INVOKABLE explicit PlaylistBackend(Application *app, QObject *parent = nullptr);
|
||||
Q_INVOKABLE explicit PlaylistBackend(const SharedPtr<Database> database,
|
||||
const SharedPtr<TagReaderClient> tagreader_client,
|
||||
const SharedPtr<CollectionBackend> collection_backend,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
struct Playlist {
|
||||
Playlist() : id(-1), favorite(false), last_played(0) {}
|
||||
@@ -84,8 +85,6 @@ class PlaylistBackend : public QObject {
|
||||
void FavoritePlaylist(const int id, bool is_favorite);
|
||||
void RemovePlaylist(const int id);
|
||||
|
||||
Application *app() const { return app_; }
|
||||
|
||||
public Q_SLOTS:
|
||||
void Exit();
|
||||
void SavePlaylist(const int playlist, const PlaylistItemPtrList &items, const int last_played, PlaylistGeneratorPtr dynamic);
|
||||
@@ -110,8 +109,9 @@ class PlaylistBackend : public QObject {
|
||||
};
|
||||
PlaylistList GetPlaylists(const GetPlaylistsFlags flags);
|
||||
|
||||
Application *app_;
|
||||
SharedPtr<Database> db_;
|
||||
const SharedPtr<Database> database_;
|
||||
const SharedPtr<TagReaderClient> tagreader_client_;
|
||||
const SharedPtr<CollectionBackend> collection_backend_;
|
||||
QThread *original_thread_;
|
||||
};
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
#include <QtEvents>
|
||||
#include <QSettings>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "includes/shared_ptr.h"
|
||||
#include "core/iconloader.h"
|
||||
#include "core/settings.h"
|
||||
#include "filterparser/filterparser.h"
|
||||
@@ -59,7 +59,7 @@
|
||||
#include "playlistparsers/playlistparser.h"
|
||||
#include "ui_playlistcontainer.h"
|
||||
#include "widgets/searchfield.h"
|
||||
#include "settings/appearancesettingspage.h"
|
||||
#include "constants/appearancesettings.h"
|
||||
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
@@ -245,8 +245,8 @@ void PlaylistContainer::SetViewModel(Playlist *playlist, const int scroll_positi
|
||||
void PlaylistContainer::ReloadSettings() {
|
||||
|
||||
Settings s;
|
||||
s.beginGroup(AppearanceSettingsPage::kSettingsGroup);
|
||||
int iconsize = s.value(AppearanceSettingsPage::kIconSizePlaylistButtons, 20).toInt();
|
||||
s.beginGroup(AppearanceSettings::kSettingsGroup);
|
||||
int iconsize = s.value(AppearanceSettings::kIconSizePlaylistButtons, 20).toInt();
|
||||
s.endGroup();
|
||||
|
||||
ui_->create_new->setIconSize(QSize(iconsize, iconsize));
|
||||
|
||||
@@ -44,7 +44,7 @@ class PlaylistView;
|
||||
|
||||
class Ui_PlaylistContainer;
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "includes/shared_ptr.h"
|
||||
#include "core/settings.h"
|
||||
|
||||
class PlaylistContainer : public QWidget {
|
||||
|
||||
@@ -27,12 +27,12 @@
|
||||
#include "playlist/playlist.h"
|
||||
#include "playlist/playlistitem.h"
|
||||
#include "filterparser/filterparser.h"
|
||||
#include "filterparser/filtertree.h"
|
||||
#include "filterparser/filtertreenop.h"
|
||||
#include "playlistfilter.h"
|
||||
|
||||
PlaylistFilter::PlaylistFilter(QObject *parent)
|
||||
: QSortFilterProxyModel(parent),
|
||||
filter_tree_(new NopFilter),
|
||||
filter_tree_(new FilterTreeNop),
|
||||
query_hash_(0) {
|
||||
|
||||
setDynamicSortFilter(true);
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
#include "core/settings.h"
|
||||
#include "widgets/stretchheaderview.h"
|
||||
#include "settings/playlistsettingspage.h"
|
||||
#include "constants/playlistsettings.h"
|
||||
|
||||
PlaylistHeader::PlaylistHeader(Qt::Orientation orientation, PlaylistView *view, QWidget *parent)
|
||||
: StretchHeaderView(orientation, parent),
|
||||
@@ -83,8 +83,8 @@ PlaylistHeader::PlaylistHeader(Qt::Orientation orientation, PlaylistView *view,
|
||||
QObject::connect(this, &PlaylistHeader::StretchEnabledChanged, action_stretch_, &QAction::setChecked);
|
||||
|
||||
Settings s;
|
||||
s.beginGroup(PlaylistSettingsPage::kSettingsGroup);
|
||||
action_rating_lock_->setChecked(s.value("rating_locked", false).toBool());
|
||||
s.beginGroup(PlaylistSettings::kSettingsGroup);
|
||||
action_rating_lock_->setChecked(s.value(PlaylistSettings::kRatingLocked, false).toBool());
|
||||
s.endGroup();
|
||||
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
#include <QUrl>
|
||||
#include <QColor>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "includes/shared_ptr.h"
|
||||
#include "core/song.h"
|
||||
|
||||
class QAction;
|
||||
|
||||
@@ -46,9 +46,7 @@
|
||||
#include <QContextMenuEvent>
|
||||
#include <QMimeData>
|
||||
|
||||
#include "core/application.h"
|
||||
#include "core/iconloader.h"
|
||||
#include "core/player.h"
|
||||
#include "core/settings.h"
|
||||
#include "playlist.h"
|
||||
#include "playlistbackend.h"
|
||||
@@ -59,7 +57,7 @@
|
||||
#include "playlistmanager.h"
|
||||
#include "ui_playlistlistcontainer.h"
|
||||
#include "organize/organizedialog.h"
|
||||
#include "settings/appearancesettingspage.h"
|
||||
#include "constants/appearancesettings.h"
|
||||
#ifndef Q_OS_WIN
|
||||
# include "device/devicemanager.h"
|
||||
# include "device/devicestatefiltermodel.h"
|
||||
@@ -70,7 +68,6 @@ using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
PlaylistListContainer::PlaylistListContainer(QWidget *parent)
|
||||
: QWidget(parent),
|
||||
app_(nullptr),
|
||||
ui_(new Ui_PlaylistListContainer),
|
||||
menu_(nullptr),
|
||||
action_new_folder_(new QAction(this)),
|
||||
@@ -123,26 +120,28 @@ PlaylistListContainer::PlaylistListContainer(QWidget *parent)
|
||||
|
||||
PlaylistListContainer::~PlaylistListContainer() { delete ui_; }
|
||||
|
||||
void PlaylistListContainer::SetApplication(Application *app) {
|
||||
void PlaylistListContainer::Init(const SharedPtr<TaskManager> task_manager,
|
||||
const SharedPtr<TagReaderClient> tagreader_client,
|
||||
const SharedPtr<PlaylistManager> playlist_manager,
|
||||
const SharedPtr<PlaylistBackend> playlist_backend,
|
||||
const SharedPtr<DeviceManager> device_manager) {
|
||||
|
||||
app_ = app;
|
||||
PlaylistManager *manager = &*app_->playlist_manager();
|
||||
Player *player = &*app_->player();
|
||||
task_manager_ = task_manager;
|
||||
tagreader_client_ = tagreader_client;
|
||||
playlist_manager_ = playlist_manager;
|
||||
playlist_backend_ = playlist_backend;
|
||||
device_manager_ = device_manager;
|
||||
|
||||
QObject::connect(manager, &PlaylistManager::PlaylistAdded, this, &PlaylistListContainer::AddPlaylist);
|
||||
QObject::connect(manager, &PlaylistManager::PlaylistFavorited, this, &PlaylistListContainer::PlaylistFavoriteStateChanged);
|
||||
QObject::connect(manager, &PlaylistManager::PlaylistRenamed, this, &PlaylistListContainer::PlaylistRenamed);
|
||||
QObject::connect(manager, &PlaylistManager::CurrentChanged, this, &PlaylistListContainer::CurrentChanged);
|
||||
QObject::connect(manager, &PlaylistManager::ActiveChanged, this, &PlaylistListContainer::ActiveChanged);
|
||||
QObject::connect(&*playlist_manager, &PlaylistManager::PlaylistAdded, this, &PlaylistListContainer::AddPlaylist);
|
||||
QObject::connect(&*playlist_manager, &PlaylistManager::PlaylistFavorited, this, &PlaylistListContainer::PlaylistFavoriteStateChanged);
|
||||
QObject::connect(&*playlist_manager, &PlaylistManager::PlaylistRenamed, this, &PlaylistListContainer::PlaylistRenamed);
|
||||
QObject::connect(&*playlist_manager, &PlaylistManager::CurrentChanged, this, &PlaylistListContainer::CurrentChanged);
|
||||
QObject::connect(&*playlist_manager, &PlaylistManager::ActiveChanged, this, &PlaylistListContainer::ActiveChanged);
|
||||
|
||||
QObject::connect(model_, &PlaylistListModel::PlaylistRenamed, manager, &PlaylistManager::Rename);
|
||||
|
||||
QObject::connect(player, &Player::Paused, this, &PlaylistListContainer::ActivePaused);
|
||||
QObject::connect(player, &Player::Playing, this, &PlaylistListContainer::ActivePlaying);
|
||||
QObject::connect(player, &Player::Stopped, this, &PlaylistListContainer::ActiveStopped);
|
||||
QObject::connect(model_, &PlaylistListModel::PlaylistRenamed, &*playlist_manager, &PlaylistManager::Rename);
|
||||
|
||||
// Get all playlists, even ones that are hidden in the UI.
|
||||
const QList<PlaylistBackend::Playlist> playlists = app->playlist_backend()->GetAllFavoritePlaylists();
|
||||
const QList<PlaylistBackend::Playlist> playlists = playlist_backend->GetAllFavoritePlaylists();
|
||||
for (const PlaylistBackend::Playlist &p : playlists) {
|
||||
QStandardItem *playlist_item = model_->NewPlaylist(p.name, p.id);
|
||||
QStandardItem *parent_folder = model_->FolderByPath(p.ui_path);
|
||||
@@ -154,8 +153,8 @@ void PlaylistListContainer::SetApplication(Application *app) {
|
||||
void PlaylistListContainer::ReloadSettings() {
|
||||
|
||||
Settings s;
|
||||
s.beginGroup(AppearanceSettingsPage::kSettingsGroup);
|
||||
int iconsize = s.value(AppearanceSettingsPage::kIconSizeLeftPanelButtons, 22).toInt();
|
||||
s.beginGroup(AppearanceSettings::kSettingsGroup);
|
||||
int iconsize = s.value(AppearanceSettings::kIconSizeLeftPanelButtons, 22).toInt();
|
||||
s.endGroup();
|
||||
|
||||
ui_->new_folder->setIconSize(QSize(iconsize, iconsize));
|
||||
@@ -236,7 +235,7 @@ void PlaylistListContainer::AddPlaylist(const int id, const QString &name, const
|
||||
return;
|
||||
}
|
||||
|
||||
const QString &ui_path = app_->playlist_manager()->playlist(id)->ui_path();
|
||||
const QString &ui_path = playlist_manager_->playlist(id)->ui_path();
|
||||
|
||||
QStandardItem *playlist_item = model_->NewPlaylist(name, id);
|
||||
QStandardItem *parent_folder = model_->FolderByPath(ui_path);
|
||||
@@ -280,7 +279,7 @@ void PlaylistListContainer::SavePlaylist() {
|
||||
const int playlist_id = idx.data(PlaylistListModel::Role_PlaylistId).toInt();
|
||||
QStandardItem *item = model_->PlaylistById(playlist_id);
|
||||
QString playlist_name = item ? item->text() : tr("Playlist");
|
||||
app_->playlist_manager()->SaveWithUI(playlist_id, playlist_name);
|
||||
playlist_manager_->SaveWithUI(playlist_id, playlist_name);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -288,7 +287,7 @@ void PlaylistListContainer::SavePlaylist() {
|
||||
void PlaylistListContainer::PlaylistFavoriteStateChanged(const int id, const bool favorite) {
|
||||
|
||||
if (favorite) {
|
||||
const QString &name = app_->playlist_manager()->GetPlaylistName(id);
|
||||
const QString &name = playlist_manager_->GetPlaylistName(id);
|
||||
AddPlaylist(id, name, favorite);
|
||||
}
|
||||
else {
|
||||
@@ -330,8 +329,8 @@ void PlaylistListContainer::CurrentChanged(Playlist *new_playlist) {
|
||||
void PlaylistListContainer::PlaylistPathChanged(const int id, const QString &new_path) {
|
||||
|
||||
// Update the path in the database
|
||||
app_->playlist_backend()->SetPlaylistUiPath(id, new_path);
|
||||
Playlist *playlist = app_->playlist_manager()->playlist(id);
|
||||
playlist_backend_->SetPlaylistUiPath(id, new_path);
|
||||
Playlist *playlist = playlist_manager_->playlist(id);
|
||||
// Check the playlist exists (if it's not opened it's not in the manager)
|
||||
if (playlist) {
|
||||
playlist->set_ui_path(new_path);
|
||||
@@ -351,7 +350,7 @@ void PlaylistListContainer::ItemDoubleClicked(const QModelIndex &proxy_idx) {
|
||||
|
||||
// Is it a playlist?
|
||||
if (idx.data(PlaylistListModel::Role_Type).toInt() == PlaylistListModel::Type_Playlist) {
|
||||
app_->playlist_manager()->SetCurrentOrOpen(idx.data(PlaylistListModel::Role_PlaylistId).toInt());
|
||||
playlist_manager_->SetCurrentOrOpen(idx.data(PlaylistListModel::Role_PlaylistId).toInt());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -363,8 +362,8 @@ void PlaylistListContainer::ItemMimeDataDropped(const QModelIndex &proxy_idx, co
|
||||
|
||||
// Drop playlist rows if type is playlist and it's not active, to prevent selfcopy
|
||||
int playlis_id = idx.data(PlaylistListModel::Role_PlaylistId).toInt();
|
||||
if (idx.data(PlaylistListModel::Role_Type).toInt() == PlaylistListModel::Type_Playlist && playlis_id != app_->playlist_manager()->active_id()) {
|
||||
app_->playlist_manager()->playlist(playlis_id)->dropMimeData(q_mimedata, Qt::CopyAction, -1, 0, QModelIndex());
|
||||
if (idx.data(PlaylistListModel::Role_Type).toInt() == PlaylistListModel::Type_Playlist && playlis_id != playlist_manager_->active_id()) {
|
||||
playlist_manager_->playlist(playlis_id)->dropMimeData(q_mimedata, Qt::CopyAction, -1, 0, QModelIndex());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -382,7 +381,7 @@ void PlaylistListContainer::CopyToDevice() {
|
||||
if (idx.data(PlaylistListModel::Role_Type).toInt() == PlaylistListModel::Type_Playlist) {
|
||||
const int playlist_id = idx.data(PlaylistListModel::Role_PlaylistId).toInt();
|
||||
|
||||
Playlist *playlist = app_->playlist_manager()->playlist(playlist_id);
|
||||
Playlist *playlist = playlist_manager_->playlist(playlist_id);
|
||||
if (!playlist) {
|
||||
QMessageBox::critical(this, tr("Copy to device"), tr("Playlist must be open first."));
|
||||
return;
|
||||
@@ -393,9 +392,9 @@ void PlaylistListContainer::CopyToDevice() {
|
||||
|
||||
// Reuse the organize dialog, but set the detail about the playlist name
|
||||
if (!organize_dialog_) {
|
||||
organize_dialog_ = make_unique<OrganizeDialog>(app_->task_manager(), nullptr, this);
|
||||
organize_dialog_ = make_unique<OrganizeDialog>(task_manager_, tagreader_client_, nullptr, this);
|
||||
}
|
||||
organize_dialog_->SetDestinationModel(app_->device_manager()->connected_devices_model(), true);
|
||||
organize_dialog_->SetDestinationModel(device_manager_->connected_devices_model(), true);
|
||||
organize_dialog_->SetCopy(true);
|
||||
organize_dialog_->SetPlaylist(playlist_name);
|
||||
organize_dialog_->SetSongs(playlist->GetAllSongs());
|
||||
@@ -444,7 +443,7 @@ void PlaylistListContainer::Delete() {
|
||||
|
||||
// Unfavorite the playlists
|
||||
for (const int id : std::as_const(ids)) {
|
||||
app_->playlist_manager()->Favorite(id, false);
|
||||
playlist_manager_->Favorite(id, false);
|
||||
}
|
||||
|
||||
// Delete the top-level folders.
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
#include <QIcon>
|
||||
#include <QModelIndex>
|
||||
|
||||
#include "core/scoped_ptr.h"
|
||||
#include "includes/scoped_ptr.h"
|
||||
#include "includes/shared_ptr.h"
|
||||
|
||||
class QStandardItem;
|
||||
class QSortFilterProxyModel;
|
||||
@@ -39,7 +40,11 @@ class QAction;
|
||||
class QContextMenuEvent;
|
||||
class QShowEvent;
|
||||
|
||||
class Application;
|
||||
class TaskManager;
|
||||
class TagReaderClient;
|
||||
class DeviceManager;
|
||||
class PlaylistManager;
|
||||
class PlaylistBackend;
|
||||
class Playlist;
|
||||
class PlaylistListModel;
|
||||
class Ui_PlaylistListContainer;
|
||||
@@ -52,13 +57,24 @@ class PlaylistListContainer : public QWidget {
|
||||
explicit PlaylistListContainer(QWidget *parent = nullptr);
|
||||
~PlaylistListContainer() override;
|
||||
|
||||
void SetApplication(Application *app);
|
||||
void Init(const SharedPtr<TaskManager> task_manager,
|
||||
const SharedPtr<TagReaderClient> tagreader_client,
|
||||
const SharedPtr<PlaylistManager> playlist_manager,
|
||||
const SharedPtr<PlaylistBackend> playlist_backend,
|
||||
const SharedPtr<DeviceManager> device_manager);
|
||||
|
||||
void ReloadSettings();
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *e) override;
|
||||
void contextMenuEvent(QContextMenuEvent *e) override;
|
||||
|
||||
public Q_SLOTS:
|
||||
// From the Player
|
||||
void ActivePlaying();
|
||||
void ActivePaused();
|
||||
void ActiveStopped();
|
||||
|
||||
private Q_SLOTS:
|
||||
// From the UI
|
||||
void NewFolderClicked();
|
||||
@@ -77,11 +93,6 @@ class PlaylistListContainer : public QWidget {
|
||||
void CurrentChanged(Playlist *new_playlist);
|
||||
void ActiveChanged(Playlist *new_playlist);
|
||||
|
||||
// From the Player
|
||||
void ActivePlaying();
|
||||
void ActivePaused();
|
||||
void ActiveStopped();
|
||||
|
||||
void ItemsSelectedChanged(const bool selected);
|
||||
|
||||
void SavePlaylist();
|
||||
@@ -97,7 +108,12 @@ class PlaylistListContainer : public QWidget {
|
||||
|
||||
void UpdateActiveIcon(int id, const QIcon &icon);
|
||||
|
||||
Application *app_;
|
||||
SharedPtr<TaskManager> task_manager_;
|
||||
SharedPtr<TagReaderClient> tagreader_client_;
|
||||
SharedPtr<PlaylistManager> playlist_manager_;
|
||||
SharedPtr<PlaylistBackend> playlist_backend_;
|
||||
SharedPtr<DeviceManager> device_manager_;
|
||||
|
||||
Ui_PlaylistListContainer *ui_;
|
||||
QMenu *menu_;
|
||||
|
||||
|
||||
@@ -42,15 +42,13 @@
|
||||
#include <QSettings>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/application.h"
|
||||
#include "core/player.h"
|
||||
#include "includes/shared_ptr.h"
|
||||
#include "core/settings.h"
|
||||
#include "utilities/filenameconstants.h"
|
||||
#include "constants/filenameconstants.h"
|
||||
#include "utilities/timeutils.h"
|
||||
#include "collection/collectionbackend.h"
|
||||
#include "covermanager/currentalbumcoverloader.h"
|
||||
#include "settings/playlistsettingspage.h"
|
||||
#include "constants/playlistsettings.h"
|
||||
#include "playlist.h"
|
||||
#include "playlistbackend.h"
|
||||
#include "playlistcontainer.h"
|
||||
@@ -65,11 +63,20 @@ using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
class ParserBase;
|
||||
|
||||
PlaylistManager::PlaylistManager(Application *app, QObject *parent)
|
||||
: PlaylistManagerInterface(app, parent),
|
||||
app_(app),
|
||||
playlist_backend_(nullptr),
|
||||
collection_backend_(nullptr),
|
||||
PlaylistManager::PlaylistManager(const SharedPtr<TaskManager> task_manager,
|
||||
const SharedPtr<TagReaderClient> tagreader_client,
|
||||
const SharedPtr<UrlHandlers> url_handlers,
|
||||
const SharedPtr<PlaylistBackend> playlist_backend,
|
||||
const SharedPtr<CollectionBackend> collection_backend,
|
||||
const SharedPtr<CurrentAlbumCoverLoader> current_albumcover_loader,
|
||||
QObject *parent)
|
||||
: PlaylistManagerInterface(parent),
|
||||
task_manager_(task_manager),
|
||||
tagreader_client_(tagreader_client),
|
||||
url_handlers_(url_handlers),
|
||||
playlist_backend_(playlist_backend),
|
||||
collection_backend_(collection_backend),
|
||||
current_albumcover_loader_(current_albumcover_loader),
|
||||
sequence_(nullptr),
|
||||
parser_(nullptr),
|
||||
playlist_container_(nullptr),
|
||||
@@ -79,10 +86,6 @@ PlaylistManager::PlaylistManager(Application *app, QObject *parent)
|
||||
|
||||
setObjectName(QLatin1String(metaObject()->className()));
|
||||
|
||||
QObject::connect(&*app_->player(), &Player::Paused, this, &PlaylistManager::SetActivePaused);
|
||||
QObject::connect(&*app_->player(), &Player::Playing, this, &PlaylistManager::SetActivePlaying);
|
||||
QObject::connect(&*app_->player(), &Player::Stopped, this, &PlaylistManager::SetActiveStopped);
|
||||
|
||||
}
|
||||
|
||||
PlaylistManager::~PlaylistManager() {
|
||||
@@ -92,21 +95,20 @@ PlaylistManager::~PlaylistManager() {
|
||||
|
||||
}
|
||||
|
||||
void PlaylistManager::Init(SharedPtr<CollectionBackend> collection_backend, SharedPtr<PlaylistBackend> playlist_backend, PlaylistSequence *sequence, PlaylistContainer *playlist_container) {
|
||||
void PlaylistManager::Init(PlaylistSequence *sequence, PlaylistContainer *playlist_container) {
|
||||
|
||||
collection_backend_ = collection_backend;
|
||||
playlist_backend_ = playlist_backend;
|
||||
sequence_ = sequence;
|
||||
parser_ = new PlaylistParser(collection_backend, this);
|
||||
playlist_container_ = playlist_container;
|
||||
|
||||
parser_ = new PlaylistParser(tagreader_client_, collection_backend_, this);
|
||||
|
||||
QObject::connect(&*collection_backend_, &CollectionBackend::SongsChanged, this, &PlaylistManager::UpdateCollectionSongs);
|
||||
QObject::connect(&*collection_backend_, &CollectionBackend::SongsStatisticsChanged, this, &PlaylistManager::UpdateCollectionSongs);
|
||||
QObject::connect(&*collection_backend_, &CollectionBackend::SongsRatingChanged, this, &PlaylistManager::UpdateCollectionSongs);
|
||||
|
||||
QObject::connect(parser_, &PlaylistParser::Error, this, &PlaylistManager::Error);
|
||||
|
||||
const PlaylistBackend::PlaylistList playlists = playlist_backend->GetAllOpenPlaylists();
|
||||
const PlaylistBackend::PlaylistList playlists = playlist_backend_->GetAllOpenPlaylists();
|
||||
for (const PlaylistBackend::Playlist &p : playlists) {
|
||||
++playlists_loading_;
|
||||
Playlist *ret = AddPlaylist(p.id, p.name, p.special_type, p.ui_path, p.favorite);
|
||||
@@ -153,7 +155,7 @@ QItemSelection PlaylistManager::selection(const int id) const {
|
||||
|
||||
Playlist *PlaylistManager::AddPlaylist(const int id, const QString &name, const QString &special_type, const QString &ui_path, const bool favorite) {
|
||||
|
||||
Playlist *ret = new Playlist(playlist_backend_, app_->task_manager(), collection_backend_, id, special_type, favorite);
|
||||
Playlist *ret = new Playlist(task_manager_, url_handlers_, playlist_backend_, collection_backend_, tagreader_client_, id, special_type, favorite);
|
||||
ret->set_sequence(sequence_);
|
||||
ret->set_ui_path(ui_path);
|
||||
|
||||
@@ -165,7 +167,7 @@ Playlist *PlaylistManager::AddPlaylist(const int id, const QString &name, const
|
||||
QObject::connect(ret, &Playlist::Error, this, &PlaylistManager::Error);
|
||||
QObject::connect(ret, &Playlist::PlayRequested, this, &PlaylistManager::PlayRequested);
|
||||
QObject::connect(playlist_container_->view(), &PlaylistView::ColumnAlignmentChanged, ret, &Playlist::SetColumnAlignment);
|
||||
QObject::connect(&*app_->current_albumcover_loader(), &CurrentAlbumCoverLoader::AlbumCoverLoaded, ret, &Playlist::AlbumCoverLoaded);
|
||||
QObject::connect(&*current_albumcover_loader_, &CurrentAlbumCoverLoader::AlbumCoverLoaded, ret, &Playlist::AlbumCoverLoaded);
|
||||
|
||||
playlists_[id] = Data(ret, name);
|
||||
|
||||
@@ -219,7 +221,7 @@ void PlaylistManager::Load(const QString &filename) {
|
||||
|
||||
}
|
||||
|
||||
void PlaylistManager::Save(const int id, const QString &filename, const PlaylistSettingsPage::PathType path_type) {
|
||||
void PlaylistManager::Save(const int id, const QString &filename, const PlaylistSettings::PathType path_type) {
|
||||
|
||||
if (playlists_.contains(id)) {
|
||||
parser_->Save(playlist(id)->GetAllSongs(), filename, path_type);
|
||||
@@ -237,7 +239,7 @@ void PlaylistManager::Save(const int id, const QString &filename, const Playlist
|
||||
|
||||
}
|
||||
|
||||
void PlaylistManager::ItemsLoadedForSavePlaylist(const SongList &songs, const QString &filename, const PlaylistSettingsPage::PathType path_type) {
|
||||
void PlaylistManager::ItemsLoadedForSavePlaylist(const SongList &songs, const QString &filename, const PlaylistSettings::PathType path_type) {
|
||||
|
||||
parser_->Save(songs, filename, path_type);
|
||||
|
||||
@@ -246,10 +248,10 @@ void PlaylistManager::ItemsLoadedForSavePlaylist(const SongList &songs, const QS
|
||||
void PlaylistManager::SaveWithUI(const int id, const QString &playlist_name) {
|
||||
|
||||
Settings s;
|
||||
s.beginGroup(Playlist::kSettingsGroup);
|
||||
QString last_save_filter = s.value("last_save_filter", parser()->default_filter()).toString();
|
||||
QString last_save_path = s.value("last_save_path", QDir::homePath()).toString();
|
||||
QString last_save_extension = s.value("last_save_extension", parser()->default_extension()).toString();
|
||||
s.beginGroup(PlaylistSettings::kSettingsGroup);
|
||||
QString last_save_filter = s.value(PlaylistSettings::kLastSaveFilter, parser()->default_filter()).toString();
|
||||
QString last_save_path = s.value(PlaylistSettings::kLastSavePath, QDir::homePath()).toString();
|
||||
QString last_save_extension = s.value(PlaylistSettings::kLastSaveExtension, parser()->default_extension()).toString();
|
||||
s.endGroup();
|
||||
|
||||
QString suggested_filename = playlist_name;
|
||||
@@ -265,20 +267,20 @@ void PlaylistManager::SaveWithUI(const int id, const QString &playlist_name) {
|
||||
QMessageBox::warning(nullptr, tr("Unknown playlist extension"), tr("Unknown file extension for playlist."));
|
||||
}
|
||||
|
||||
s.beginGroup(PlaylistSettingsPage::kSettingsGroup);
|
||||
PlaylistSettingsPage::PathType path_type = static_cast<PlaylistSettingsPage::PathType>(s.value("path_type", static_cast<int>(PlaylistSettingsPage::PathType::Automatic)).toInt());
|
||||
s.beginGroup(PlaylistSettings::kSettingsGroup);
|
||||
PlaylistSettings::PathType path_type = static_cast<PlaylistSettings::PathType>(s.value(PlaylistSettings::kPathType, static_cast<int>(PlaylistSettings::PathType::Automatic)).toInt());
|
||||
s.endGroup();
|
||||
if (path_type == PlaylistSettingsPage::PathType::Ask_User) {
|
||||
if (path_type == PlaylistSettings::PathType::Ask_User) {
|
||||
PlaylistSaveOptionsDialog optionsdialog;
|
||||
optionsdialog.setModal(true);
|
||||
if (optionsdialog.exec() != QDialog::Accepted) return;
|
||||
path_type = optionsdialog.path_type();
|
||||
}
|
||||
|
||||
s.beginGroup(Playlist::kSettingsGroup);
|
||||
s.setValue("last_save_filter", last_save_filter);
|
||||
s.setValue("last_save_path", fileinfo.path());
|
||||
s.setValue("last_save_extension", fileinfo.suffix());
|
||||
s.beginGroup(PlaylistSettings::kSettingsGroup);
|
||||
s.setValue(PlaylistSettings::kLastSaveFilter, last_save_filter);
|
||||
s.setValue(PlaylistSettings::kLastSavePath, fileinfo.path());
|
||||
s.setValue(PlaylistSettings::kLastSaveExtension, fileinfo.suffix());
|
||||
s.endGroup();
|
||||
|
||||
Save(id == -1 ? current_id() : id, filename, path_type);
|
||||
@@ -541,45 +543,6 @@ void PlaylistManager::RemoveDeletedSongs() {
|
||||
|
||||
}
|
||||
|
||||
QString PlaylistManager::GetNameForNewPlaylist(const SongList &songs) {
|
||||
|
||||
if (songs.isEmpty()) {
|
||||
return tr("Playlist");
|
||||
}
|
||||
|
||||
QSet<QString> artists;
|
||||
QSet<QString> albums;
|
||||
artists.reserve(songs.count());
|
||||
albums.reserve(songs.count());
|
||||
for (const Song &song : songs) {
|
||||
artists << (song.effective_albumartist().isEmpty() ? tr("Unknown") : song.effective_albumartist());
|
||||
albums << (song.album().isEmpty() ? tr("Unknown") : song.album());
|
||||
|
||||
if (artists.size() > 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool various_artists = artists.size() > 1;
|
||||
|
||||
QString result;
|
||||
if (various_artists) {
|
||||
result = tr("Various artists");
|
||||
}
|
||||
else {
|
||||
QStringList artist_names = artists.values();
|
||||
result = artist_names.first();
|
||||
}
|
||||
|
||||
if (!various_artists && albums.size() == 1) {
|
||||
QStringList album_names = albums.values();
|
||||
result += " - "_L1 + album_names.first();
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
void PlaylistManager::Open(const int id) {
|
||||
|
||||
if (playlists_.contains(id)) {
|
||||
@@ -642,10 +605,10 @@ void PlaylistManager::SaveAllPlaylists() {
|
||||
if (extension.isEmpty()) extension = parser()->default_extension();
|
||||
|
||||
Settings s;
|
||||
s.beginGroup(PlaylistSettingsPage::kSettingsGroup);
|
||||
PlaylistSettingsPage::PathType path_type = static_cast<PlaylistSettingsPage::PathType>(s.value("path_type", static_cast<int>(PlaylistSettingsPage::PathType::Automatic)).toInt());
|
||||
s.beginGroup(PlaylistSettings::kSettingsGroup);
|
||||
PlaylistSettings::PathType path_type = static_cast<PlaylistSettings::PathType>(s.value(PlaylistSettings::kPathType, static_cast<int>(PlaylistSettings::PathType::Automatic)).toInt());
|
||||
s.endGroup();
|
||||
if (path_type == PlaylistSettingsPage::PathType::Ask_User) {
|
||||
if (path_type == PlaylistSettings::PathType::Ask_User) {
|
||||
PlaylistSaveOptionsDialog optionsdialog;
|
||||
optionsdialog.setModal(true);
|
||||
if (optionsdialog.exec() != QDialog::Accepted) return;
|
||||
|
||||
@@ -27,125 +27,40 @@
|
||||
#include <QtGlobal>
|
||||
#include <QObject>
|
||||
#include <QItemSelectionModel>
|
||||
#include <QFuture>
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
#include <QUrl>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "includes/shared_ptr.h"
|
||||
#include "core/song.h"
|
||||
#include "settings/playlistsettingspage.h"
|
||||
#include "constants/playlistsettings.h"
|
||||
#include "playlistmanagerinterface.h"
|
||||
#include "playlist.h"
|
||||
#include "smartplaylists/playlistgenerator.h"
|
||||
|
||||
class QModelIndex;
|
||||
|
||||
class Application;
|
||||
class TaskManager;
|
||||
class TagReaderClient;
|
||||
class UrlHandlers;
|
||||
class CollectionBackend;
|
||||
class CurrentAlbumCoverLoader;
|
||||
class PlaylistBackend;
|
||||
class PlaylistContainer;
|
||||
class PlaylistParser;
|
||||
class PlaylistSequence;
|
||||
|
||||
class PlaylistManagerInterface : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PlaylistManagerInterface(Application *app, QObject *parent) : QObject(parent) { Q_UNUSED(app); }
|
||||
|
||||
virtual int current_id() const = 0;
|
||||
virtual int active_id() const = 0;
|
||||
|
||||
virtual QList<int> playlist_ids() const = 0;
|
||||
virtual QString playlist_name(const int id) const = 0;
|
||||
virtual Playlist *playlist(const int id) const = 0;
|
||||
virtual Playlist *current() const = 0;
|
||||
virtual Playlist *active() const = 0;
|
||||
|
||||
// Returns the collection of playlists managed by this PlaylistManager.
|
||||
virtual QList<Playlist*> GetAllPlaylists() const = 0;
|
||||
// Grays out and reloads all deleted songs in all playlists.
|
||||
virtual void InvalidateDeletedSongs() = 0;
|
||||
// Removes all deleted songs from all playlists.
|
||||
virtual void RemoveDeletedSongs() = 0;
|
||||
|
||||
virtual QItemSelection selection(const int id) const = 0;
|
||||
virtual QItemSelection current_selection() const = 0;
|
||||
virtual QItemSelection active_selection() const = 0;
|
||||
|
||||
virtual QString GetPlaylistName(const int index) const = 0;
|
||||
|
||||
virtual SharedPtr<CollectionBackend> collection_backend() const = 0;
|
||||
virtual SharedPtr<PlaylistBackend> playlist_backend() const = 0;
|
||||
virtual PlaylistSequence *sequence() const = 0;
|
||||
virtual PlaylistParser *parser() const = 0;
|
||||
virtual PlaylistContainer *playlist_container() const = 0;
|
||||
|
||||
virtual void PlaySmartPlaylist(PlaylistGeneratorPtr generator, const bool as_new, const bool clear) = 0;
|
||||
|
||||
public Q_SLOTS:
|
||||
virtual void New(const QString &name, const SongList &songs = SongList(), const QString &special_type = QString()) = 0;
|
||||
virtual void Load(const QString &filename) = 0;
|
||||
virtual void Save(const int id, const QString &filename, const PlaylistSettingsPage::PathType path_type) = 0;
|
||||
virtual void Rename(const int id, const QString &new_name) = 0;
|
||||
virtual void Delete(const int id) = 0;
|
||||
virtual bool Close(const int id) = 0;
|
||||
virtual void Open(const int id) = 0;
|
||||
virtual void ChangePlaylistOrder(const QList<int> &ids) = 0;
|
||||
|
||||
virtual void SongChangeRequestProcessed(const QUrl &url, const bool valid) = 0;
|
||||
|
||||
virtual void SetCurrentPlaylist(const int id) = 0;
|
||||
virtual void SetActivePlaylist(const int id) = 0;
|
||||
virtual void SetActiveToCurrent() = 0;
|
||||
|
||||
virtual void SelectionChanged(const QItemSelection &selection) = 0;
|
||||
|
||||
// Convenience slots that defer to either current() or active()
|
||||
virtual void ClearCurrent() = 0;
|
||||
virtual void ShuffleCurrent() = 0;
|
||||
virtual void RemoveDuplicatesCurrent() = 0;
|
||||
virtual void RemoveUnavailableCurrent() = 0;
|
||||
virtual void SetActivePlaying() = 0;
|
||||
virtual void SetActivePaused() = 0;
|
||||
virtual void SetActiveStopped() = 0;
|
||||
|
||||
// Rate current song using 0.0 - 1.0 scale.
|
||||
virtual void RateCurrentSong(const float rating) = 0;
|
||||
// Rate current song using 0 - 5 scale.
|
||||
virtual void RateCurrentSong2(const int rating) = 0;
|
||||
|
||||
Q_SIGNALS:
|
||||
void PlaylistManagerInitialized();
|
||||
void AllPlaylistsLoaded();
|
||||
|
||||
void PlaylistAdded(const int id, const QString &name, const bool favorite);
|
||||
void PlaylistDeleted(const int id);
|
||||
void PlaylistClosed(const int id);
|
||||
void PlaylistRenamed(const int id, const QString &new_name);
|
||||
void PlaylistFavorited(const int id, const bool favorite);
|
||||
void CurrentChanged(Playlist *new_playlist, const int scroll_position = 0);
|
||||
void ActiveChanged(Playlist *new_playlist);
|
||||
|
||||
void Error(const QString &message);
|
||||
void SummaryTextChanged(const QString &summary);
|
||||
|
||||
// Forwarded from individual playlists
|
||||
void CurrentSongChanged(const Song &song);
|
||||
void CurrentSongMetadataChanged(const Song &song);
|
||||
|
||||
// Signals that one of manager's playlists has changed (new items, new ordering etc.) - the argument shows which.
|
||||
void PlaylistChanged(Playlist *playlist);
|
||||
void EditingFinished(const int playlist_id, const QModelIndex idx);
|
||||
void PlayRequested(const QModelIndex idx, const Playlist::AutoScroll autoscroll);
|
||||
};
|
||||
|
||||
class PlaylistManager : public PlaylistManagerInterface {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PlaylistManager(Application *app, QObject *parent = nullptr);
|
||||
explicit PlaylistManager(const SharedPtr<TaskManager> task_manager,
|
||||
const SharedPtr<TagReaderClient> tagreader_client,
|
||||
const SharedPtr<UrlHandlers> url_handlers,
|
||||
const SharedPtr<PlaylistBackend> playlist_backend,
|
||||
const SharedPtr<CollectionBackend> collection_backend,
|
||||
const SharedPtr<CurrentAlbumCoverLoader> current_albumcover_loader,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
~PlaylistManager() override;
|
||||
|
||||
int current_id() const override { return current_; }
|
||||
@@ -166,9 +81,6 @@ class PlaylistManager : public PlaylistManagerInterface {
|
||||
// Returns true if the playlist is open
|
||||
bool IsPlaylistOpen(const int id);
|
||||
|
||||
// Returns a pretty automatic name for playlist created from the given list of songs.
|
||||
static QString GetNameForNewPlaylist(const SongList &songs);
|
||||
|
||||
QItemSelection selection(const int id) const override;
|
||||
QItemSelection current_selection() const override { return selection(current_id()); }
|
||||
QItemSelection active_selection() const override { return selection(active_id()); }
|
||||
@@ -176,7 +88,7 @@ class PlaylistManager : public PlaylistManagerInterface {
|
||||
QString GetPlaylistName(const int index) const override { return playlists_[index].name; }
|
||||
bool IsPlaylistFavorite(const int index) const { return playlists_[index].p->is_favorite(); }
|
||||
|
||||
void Init(SharedPtr<CollectionBackend> collection_backend, SharedPtr<PlaylistBackend> playlist_backend, PlaylistSequence *sequence, PlaylistContainer *playlist_container);
|
||||
void Init(PlaylistSequence *sequence, PlaylistContainer *playlist_container);
|
||||
|
||||
SharedPtr<CollectionBackend> collection_backend() const override { return collection_backend_; }
|
||||
SharedPtr<PlaylistBackend> playlist_backend() const override { return playlist_backend_; }
|
||||
@@ -187,7 +99,7 @@ class PlaylistManager : public PlaylistManagerInterface {
|
||||
public Q_SLOTS:
|
||||
void New(const QString &name, const SongList &songs = SongList(), const QString &special_type = QString()) override;
|
||||
void Load(const QString &filename) override;
|
||||
void Save(const int id, const QString &filename, const PlaylistSettingsPage::PathType path_type) override;
|
||||
void Save(const int id, const QString &filename, const PlaylistSettings::PathType path_type) override;
|
||||
// Display a file dialog to let user choose a file before saving the file
|
||||
void SaveWithUI(const int id, const QString &playlist_name);
|
||||
void Rename(const int id, const QString &new_name) override;
|
||||
@@ -230,15 +142,15 @@ class PlaylistManager : public PlaylistManagerInterface {
|
||||
|
||||
void SaveAllPlaylists();
|
||||
|
||||
private Q_SLOTS:
|
||||
void SetActivePlaying() override;
|
||||
void SetActivePaused() override;
|
||||
void SetActiveStopped() override;
|
||||
|
||||
private Q_SLOTS:
|
||||
void OneOfPlaylistsChanged();
|
||||
void UpdateSummaryText();
|
||||
void UpdateCollectionSongs(const SongList &songs);
|
||||
void ItemsLoadedForSavePlaylist(const SongList &songs, const QString &filename, const PlaylistSettingsPage::PathType path_type);
|
||||
void ItemsLoadedForSavePlaylist(const SongList &songs, const QString &filename, const PlaylistSettings::PathType path_type);
|
||||
void PlaylistLoaded();
|
||||
|
||||
private:
|
||||
@@ -253,9 +165,12 @@ class PlaylistManager : public PlaylistManagerInterface {
|
||||
int scroll_position;
|
||||
};
|
||||
|
||||
Application *app_;
|
||||
SharedPtr<PlaylistBackend> playlist_backend_;
|
||||
SharedPtr<CollectionBackend> collection_backend_;
|
||||
const SharedPtr<TaskManager> task_manager_;
|
||||
const SharedPtr<TagReaderClient> tagreader_client_;
|
||||
const SharedPtr<UrlHandlers> url_handlers_;
|
||||
const SharedPtr<PlaylistBackend> playlist_backend_;
|
||||
const SharedPtr<CollectionBackend> collection_backend_;
|
||||
const SharedPtr<CurrentAlbumCoverLoader> current_albumcover_loader_;
|
||||
PlaylistSequence *sequence_;
|
||||
PlaylistParser *parser_;
|
||||
PlaylistContainer *playlist_container_;
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "songmimedata.h"
|
||||
#include "playlistmanagerinterface.h"
|
||||
|
||||
SongMimeData::SongMimeData(QObject *parent) : backend(nullptr) {
|
||||
Q_UNUSED(parent);
|
||||
}
|
||||
PlaylistManagerInterface::PlaylistManagerInterface(QObject *parent) : QObject(parent) {}
|
||||
138
src/playlist/playlistmanagerinterface.h
Normal file
138
src/playlist/playlistmanagerinterface.h
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* This file was part of Clementine.
|
||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry 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.
|
||||
*
|
||||
* Strawberry 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 Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PLAYLISTMANAGERINTERFACE_H
|
||||
#define PLAYLISTMANAGERINTERFACE_H
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QObject>
|
||||
#include <QItemSelectionModel>
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
#include <QUrl>
|
||||
|
||||
#include "includes/shared_ptr.h"
|
||||
#include "constants/playlistsettings.h"
|
||||
#include "playlist.h"
|
||||
#include "smartplaylists/playlistgenerator.h"
|
||||
|
||||
class QModelIndex;
|
||||
class CollectionBackend;
|
||||
class CurrentAlbumCoverLoader;
|
||||
class PlaylistBackend;
|
||||
class PlaylistContainer;
|
||||
class PlaylistParser;
|
||||
class PlaylistSequence;
|
||||
|
||||
class PlaylistManagerInterface : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PlaylistManagerInterface(QObject *parent);
|
||||
|
||||
virtual int current_id() const = 0;
|
||||
virtual int active_id() const = 0;
|
||||
|
||||
virtual QList<int> playlist_ids() const = 0;
|
||||
virtual QString playlist_name(const int id) const = 0;
|
||||
virtual Playlist *playlist(const int id) const = 0;
|
||||
virtual Playlist *current() const = 0;
|
||||
virtual Playlist *active() const = 0;
|
||||
|
||||
// Returns the collection of playlists managed by this PlaylistManager.
|
||||
virtual QList<Playlist*> GetAllPlaylists() const = 0;
|
||||
// Grays out and reloads all deleted songs in all playlists.
|
||||
virtual void InvalidateDeletedSongs() = 0;
|
||||
// Removes all deleted songs from all playlists.
|
||||
virtual void RemoveDeletedSongs() = 0;
|
||||
|
||||
virtual QItemSelection selection(const int id) const = 0;
|
||||
virtual QItemSelection current_selection() const = 0;
|
||||
virtual QItemSelection active_selection() const = 0;
|
||||
|
||||
virtual QString GetPlaylistName(const int index) const = 0;
|
||||
|
||||
virtual SharedPtr<CollectionBackend> collection_backend() const = 0;
|
||||
virtual SharedPtr<PlaylistBackend> playlist_backend() const = 0;
|
||||
virtual PlaylistSequence *sequence() const = 0;
|
||||
virtual PlaylistParser *parser() const = 0;
|
||||
virtual PlaylistContainer *playlist_container() const = 0;
|
||||
|
||||
virtual void PlaySmartPlaylist(PlaylistGeneratorPtr generator, const bool as_new, const bool clear) = 0;
|
||||
|
||||
public Q_SLOTS:
|
||||
virtual void New(const QString &name, const SongList &songs = SongList(), const QString &special_type = QString()) = 0;
|
||||
virtual void Load(const QString &filename) = 0;
|
||||
virtual void Save(const int id, const QString &filename, const PlaylistSettings::PathType path_type) = 0;
|
||||
virtual void Rename(const int id, const QString &new_name) = 0;
|
||||
virtual void Delete(const int id) = 0;
|
||||
virtual bool Close(const int id) = 0;
|
||||
virtual void Open(const int id) = 0;
|
||||
virtual void ChangePlaylistOrder(const QList<int> &ids) = 0;
|
||||
|
||||
virtual void SongChangeRequestProcessed(const QUrl &url, const bool valid) = 0;
|
||||
|
||||
virtual void SetCurrentPlaylist(const int id) = 0;
|
||||
virtual void SetActivePlaylist(const int id) = 0;
|
||||
virtual void SetActiveToCurrent() = 0;
|
||||
|
||||
virtual void SelectionChanged(const QItemSelection &selection) = 0;
|
||||
|
||||
// Convenience slots that defer to either current() or active()
|
||||
virtual void ClearCurrent() = 0;
|
||||
virtual void ShuffleCurrent() = 0;
|
||||
virtual void RemoveDuplicatesCurrent() = 0;
|
||||
virtual void RemoveUnavailableCurrent() = 0;
|
||||
virtual void SetActivePlaying() = 0;
|
||||
virtual void SetActivePaused() = 0;
|
||||
virtual void SetActiveStopped() = 0;
|
||||
|
||||
// Rate current song using 0.0 - 1.0 scale.
|
||||
virtual void RateCurrentSong(const float rating) = 0;
|
||||
// Rate current song using 0 - 5 scale.
|
||||
virtual void RateCurrentSong2(const int rating) = 0;
|
||||
|
||||
Q_SIGNALS:
|
||||
void PlaylistManagerInitialized();
|
||||
void AllPlaylistsLoaded();
|
||||
|
||||
void PlaylistAdded(const int id, const QString &name, const bool favorite);
|
||||
void PlaylistDeleted(const int id);
|
||||
void PlaylistClosed(const int id);
|
||||
void PlaylistRenamed(const int id, const QString &new_name);
|
||||
void PlaylistFavorited(const int id, const bool favorite);
|
||||
void CurrentChanged(Playlist *new_playlist, const int scroll_position = 0);
|
||||
void ActiveChanged(Playlist *new_playlist);
|
||||
|
||||
void Error(const QString &message);
|
||||
void SummaryTextChanged(const QString &summary);
|
||||
|
||||
// Forwarded from individual playlists
|
||||
void CurrentSongChanged(const Song &song);
|
||||
void CurrentSongMetadataChanged(const Song &song);
|
||||
|
||||
// Signals that one of manager's playlists has changed (new items, new ordering etc.) - the argument shows which.
|
||||
void PlaylistChanged(Playlist *playlist);
|
||||
void EditingFinished(const int playlist_id, const QModelIndex idx);
|
||||
void PlayRequested(const QModelIndex idx, const Playlist::AutoScroll autoscroll);
|
||||
};
|
||||
|
||||
#endif // PLAYLISTMANAGERINTERFACE_H
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <QCommonStyle>
|
||||
#include <QString>
|
||||
|
||||
#include "core/scoped_ptr.h"
|
||||
#include "includes/scoped_ptr.h"
|
||||
|
||||
class QPainter;
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <QSettings>
|
||||
|
||||
#include "core/settings.h"
|
||||
#include "settings/playlistsettingspage.h"
|
||||
#include "constants/playlistsettings.h"
|
||||
#include "playlistsaveoptionsdialog.h"
|
||||
#include "ui_playlistsaveoptionsdialog.h"
|
||||
|
||||
@@ -38,9 +38,9 @@ PlaylistSaveOptionsDialog::PlaylistSaveOptionsDialog(QWidget *parent) : QDialog(
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->filePaths->addItem(tr("Automatic"), QVariant::fromValue(PlaylistSettingsPage::PathType::Automatic));
|
||||
ui->filePaths->addItem(tr("Relative"), QVariant::fromValue(PlaylistSettingsPage::PathType::Relative));
|
||||
ui->filePaths->addItem(tr("Absolute"), QVariant::fromValue(PlaylistSettingsPage::PathType::Absolute));
|
||||
ui->filePaths->addItem(tr("Automatic"), QVariant::fromValue(PlaylistSettings::PathType::Automatic));
|
||||
ui->filePaths->addItem(tr("Relative"), QVariant::fromValue(PlaylistSettings::PathType::Relative));
|
||||
ui->filePaths->addItem(tr("Absolute"), QVariant::fromValue(PlaylistSettings::PathType::Absolute));
|
||||
|
||||
}
|
||||
|
||||
@@ -50,8 +50,8 @@ void PlaylistSaveOptionsDialog::accept() {
|
||||
|
||||
if (ui->remember_user_choice->isChecked()) {
|
||||
Settings s;
|
||||
s.beginGroup(PlaylistSettingsPage::kSettingsGroup);
|
||||
s.setValue("path_type", ui->filePaths->itemData(ui->filePaths->currentIndex()).toInt());
|
||||
s.beginGroup(PlaylistSettings::kSettingsGroup);
|
||||
s.setValue(PlaylistSettings::kPathType, ui->filePaths->itemData(ui->filePaths->currentIndex()).toInt());
|
||||
s.endGroup();
|
||||
}
|
||||
|
||||
@@ -59,6 +59,6 @@ void PlaylistSaveOptionsDialog::accept() {
|
||||
|
||||
}
|
||||
|
||||
PlaylistSettingsPage::PathType PlaylistSaveOptionsDialog::path_type() const {
|
||||
return ui->filePaths->itemData(ui->filePaths->currentIndex()).value<PlaylistSettingsPage::PathType>();
|
||||
PlaylistSettings::PathType PlaylistSaveOptionsDialog::path_type() const {
|
||||
return ui->filePaths->itemData(ui->filePaths->currentIndex()).value<PlaylistSettings::PathType>();
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include <QDialog>
|
||||
#include <QString>
|
||||
|
||||
#include "settings/playlistsettingspage.h"
|
||||
#include "constants/playlistsettings.h"
|
||||
|
||||
class QWidget;
|
||||
|
||||
@@ -43,7 +43,7 @@ class PlaylistSaveOptionsDialog : public QDialog {
|
||||
~PlaylistSaveOptionsDialog() override;
|
||||
|
||||
void accept() override;
|
||||
PlaylistSettingsPage::PathType path_type() const;
|
||||
PlaylistSettings::PathType path_type() const;
|
||||
|
||||
private:
|
||||
static const char *kSettingsGroup;
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include <QIcon>
|
||||
#include <QPixmap>
|
||||
|
||||
#include "core/scoped_ptr.h"
|
||||
#include "includes/scoped_ptr.h"
|
||||
|
||||
class QMenu;
|
||||
class QAction;
|
||||
|
||||
@@ -43,8 +43,8 @@
|
||||
#include <QtEvents>
|
||||
#include <QSettings>
|
||||
|
||||
#include "includes/shared_ptr.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/iconloader.h"
|
||||
#include "core/mimedata.h"
|
||||
#include "core/settings.h"
|
||||
|
||||
@@ -46,7 +46,7 @@ class QTimerEvent;
|
||||
class PlaylistManager;
|
||||
class RenameTabLineEdit;
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "includes/shared_ptr.h"
|
||||
|
||||
class PlaylistTabBar : public QTabBar {
|
||||
Q_OBJECT
|
||||
|
||||
25
src/playlist/playlistundocommandbase.cpp
Normal file
25
src/playlist/playlistundocommandbase.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2020-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry 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.
|
||||
*
|
||||
* Strawberry 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 Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QUndoCommand>
|
||||
|
||||
#include "playlist.h"
|
||||
#include "playlistundocommandbase.h"
|
||||
|
||||
PlaylistUndoCommandBase::PlaylistUndoCommandBase(Playlist *playlist) : QUndoCommand(nullptr), playlist_(playlist) {}
|
||||
39
src/playlist/playlistundocommandbase.h
Normal file
39
src/playlist/playlistundocommandbase.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2020-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry 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.
|
||||
*
|
||||
* Strawberry 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 Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PLAYLISTUNDOCOMMANDBASE_H
|
||||
#define PLAYLISTUNDOCOMMANDBASE_H
|
||||
|
||||
#include <QUndoCommand>
|
||||
|
||||
class Playlist;
|
||||
|
||||
class PlaylistUndoCommandBase : public QUndoCommand {
|
||||
public:
|
||||
explicit PlaylistUndoCommandBase(Playlist *playlist);
|
||||
|
||||
enum class Type {
|
||||
RemoveItems = 0,
|
||||
};
|
||||
|
||||
protected:
|
||||
Playlist *playlist_;
|
||||
};
|
||||
|
||||
#endif // PLAYLISTUNDOCOMMANDBASE_H
|
||||
58
src/playlist/playlistundocommandinsertitems.cpp
Normal file
58
src/playlist/playlistundocommandinsertitems.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2020-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry 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.
|
||||
*
|
||||
* Strawberry 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 Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "playlistundocommandinsertitems.h"
|
||||
#include "playlist.h"
|
||||
|
||||
PlaylistUndoCommandInsertItems::PlaylistUndoCommandInsertItems(Playlist *playlist, const PlaylistItemPtrList &items, const int pos, const bool enqueue, const bool enqueue_next)
|
||||
: PlaylistUndoCommandBase(playlist),
|
||||
items_(items),
|
||||
pos_(pos),
|
||||
enqueue_(enqueue),
|
||||
enqueue_next_(enqueue_next) {
|
||||
|
||||
setText(QObject::tr("add %n songs", "", static_cast<int>(items_.count())));
|
||||
|
||||
}
|
||||
|
||||
void PlaylistUndoCommandInsertItems::redo() {
|
||||
playlist_->InsertItemsWithoutUndo(items_, pos_, enqueue_, enqueue_next_);
|
||||
}
|
||||
|
||||
void PlaylistUndoCommandInsertItems::undo() {
|
||||
|
||||
const int start = pos_ == -1 ? static_cast<int>(playlist_->rowCount() - items_.count()) : pos_;
|
||||
playlist_->RemoveItemsWithoutUndo(start, static_cast<int>(items_.count()));
|
||||
|
||||
}
|
||||
|
||||
bool PlaylistUndoCommandInsertItems::UpdateItem(const PlaylistItemPtr &updated_item) {
|
||||
|
||||
for (int i = 0; i < items_.size(); i++) {
|
||||
PlaylistItemPtr item = items_.value(i);
|
||||
if (item->Metadata().url() == updated_item->Metadata().url()) {
|
||||
items_[i] = updated_item;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
44
src/playlist/playlistundocommandinsertitems.h
Normal file
44
src/playlist/playlistundocommandinsertitems.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2020-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry 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.
|
||||
*
|
||||
* Strawberry 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 Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PLAYLISTUNDOCOMMANDINSERTITEMS_H
|
||||
#define PLAYLISTUNDOCOMMANDINSERTITEMS_H
|
||||
|
||||
#include "playlistundocommandbase.h"
|
||||
#include "playlistitem.h"
|
||||
|
||||
class PlaylistUndoCommandInsertItems : public PlaylistUndoCommandBase {
|
||||
public:
|
||||
explicit PlaylistUndoCommandInsertItems(Playlist *playlist, const PlaylistItemPtrList &items, const int pos, const bool enqueue = false, const bool enqueue_next = false);
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
// When load is async, items have already been pushed, so we need to update them.
|
||||
// This function try to find the equivalent item, and replace it with the new (completely loaded) one.
|
||||
// Return true if the was found (and updated), false otherwise
|
||||
bool UpdateItem(const PlaylistItemPtr &updated_item);
|
||||
|
||||
private:
|
||||
PlaylistItemPtrList items_;
|
||||
int pos_;
|
||||
bool enqueue_;
|
||||
bool enqueue_next_;
|
||||
};
|
||||
|
||||
#endif // PLAYLISTUNDOCOMMANDINSERTITEMS_H
|
||||
40
src/playlist/playlistundocommandmoveitems.cpp
Normal file
40
src/playlist/playlistundocommandmoveitems.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2020-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry 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.
|
||||
*
|
||||
* Strawberry 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 Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "playlist.h"
|
||||
#include "playlistundocommandmoveitems.h"
|
||||
|
||||
PlaylistUndoCommandMoveItems::PlaylistUndoCommandMoveItems(Playlist *playlist, const QList<int> &source_rows, const int pos)
|
||||
: PlaylistUndoCommandBase(playlist),
|
||||
source_rows_(source_rows),
|
||||
pos_(pos) {
|
||||
|
||||
setText(QObject::tr("move %n songs", "", static_cast<int>(source_rows.count())));
|
||||
|
||||
}
|
||||
|
||||
void PlaylistUndoCommandMoveItems::redo() {
|
||||
playlist_->MoveItemsWithoutUndo(source_rows_, pos_);
|
||||
}
|
||||
|
||||
void PlaylistUndoCommandMoveItems::undo() {
|
||||
playlist_->MoveItemsWithoutUndo(pos_, source_rows_);
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* This file was part of Clementine.
|
||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
* Copyright 2020-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -19,26 +17,25 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SONGMIMEDATA_H
|
||||
#define SONGMIMEDATA_H
|
||||
#ifndef PLAYLISTUNDOCOMMANDMOVEITEMS_H
|
||||
#define PLAYLISTUNDOCOMMANDMOVEITEMS_H
|
||||
|
||||
#include "config.h"
|
||||
#include <QList>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/mimedata.h"
|
||||
#include "core/song.h"
|
||||
#include "playlistundocommandbase.h"
|
||||
|
||||
class CollectionBackendInterface;
|
||||
|
||||
class SongMimeData : public MimeData {
|
||||
Q_OBJECT
|
||||
class Playlist;
|
||||
|
||||
class PlaylistUndoCommandMoveItems : public PlaylistUndoCommandBase {
|
||||
public:
|
||||
explicit SongMimeData(QObject *parent = nullptr);
|
||||
explicit PlaylistUndoCommandMoveItems(Playlist *playlist, const QList<int> &source_rows, const int pos);
|
||||
|
||||
SharedPtr<CollectionBackendInterface> backend;
|
||||
SongList songs;
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
|
||||
private:
|
||||
QList<int> source_rows_;
|
||||
int pos_;
|
||||
};
|
||||
|
||||
#endif // SONGMIMEDATA_H
|
||||
|
||||
#endif // PLAYLISTUNDOCOMMANDMOVEITEMS_H
|
||||
58
src/playlist/playlistundocommandremoveitems.cpp
Normal file
58
src/playlist/playlistundocommandremoveitems.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2020-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry 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.
|
||||
*
|
||||
* Strawberry 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 Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "playlist.h"
|
||||
#include "playlistundocommandremoveitems.h"
|
||||
|
||||
PlaylistUndoCommandRemoveItems::PlaylistUndoCommandRemoveItems(Playlist *playlist, const int pos, const int count) : PlaylistUndoCommandBase(playlist) {
|
||||
setText(QObject::tr("remove %n songs", "", count));
|
||||
|
||||
ranges_ << Range(pos, count);
|
||||
}
|
||||
|
||||
void PlaylistUndoCommandRemoveItems::redo() {
|
||||
|
||||
for (int i = 0; i < ranges_.count(); ++i) {
|
||||
ranges_[i].items_ = playlist_->RemoveItemsWithoutUndo(ranges_[i].pos_, ranges_[i].count_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void PlaylistUndoCommandRemoveItems::undo() {
|
||||
|
||||
for (int i = static_cast<int>(ranges_.count() - 1); i >= 0; --i) {
|
||||
playlist_->InsertItemsWithoutUndo(ranges_[i].items_, ranges_[i].pos_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool PlaylistUndoCommandRemoveItems::mergeWith(const QUndoCommand *other) {
|
||||
|
||||
const PlaylistUndoCommandRemoveItems *remove_command = static_cast<const PlaylistUndoCommandRemoveItems*>(other);
|
||||
ranges_.append(remove_command->ranges_);
|
||||
|
||||
int sum = 0;
|
||||
for (const Range &range : std::as_const(ranges_)) sum += range.count_;
|
||||
setText(QObject::tr("remove %n songs", "", sum));
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
49
src/playlist/playlistundocommandremoveitems.h
Normal file
49
src/playlist/playlistundocommandremoveitems.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2020-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry 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.
|
||||
*
|
||||
* Strawberry 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 Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PLAYLISTUNDOCOMMANDREMOVEITEMS_H
|
||||
#define PLAYLISTUNDOCOMMANDREMOVEITEMS_H
|
||||
|
||||
#include <QList>
|
||||
|
||||
#include "playlistundocommandbase.h"
|
||||
#include "playlistitem.h"
|
||||
|
||||
class PlaylistUndoCommandRemoveItems : public PlaylistUndoCommandBase {
|
||||
public:
|
||||
explicit PlaylistUndoCommandRemoveItems(Playlist *playlist, const int pos, const int count);
|
||||
|
||||
int id() const override { return static_cast<int>(PlaylistUndoCommandBase::Type::RemoveItems); }
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
bool mergeWith(const QUndoCommand *other) override;
|
||||
|
||||
private:
|
||||
struct Range {
|
||||
Range(const int pos, const int count) : pos_(pos), count_(count) {}
|
||||
int pos_;
|
||||
int count_;
|
||||
PlaylistItemPtrList items_;
|
||||
};
|
||||
|
||||
QList<Range> ranges_;
|
||||
};
|
||||
|
||||
#endif // PLAYLISTUNDOCOMMANDREMOVEITEMS_H
|
||||
28
src/playlist/playlistundocommandreorderitems.cpp
Normal file
28
src/playlist/playlistundocommandreorderitems.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2020-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry 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.
|
||||
*
|
||||
* Strawberry 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 Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "playlist.h"
|
||||
#include "playlistundocommandreorderitems.h"
|
||||
|
||||
PlaylistUndoCommandReOrderItems::PlaylistUndoCommandReOrderItems(Playlist *playlist, const PlaylistItemPtrList &new_items)
|
||||
: PlaylistUndoCommandBase(playlist), old_items_(playlist->items_), new_items_(new_items) {}
|
||||
|
||||
void PlaylistUndoCommandReOrderItems::undo() { playlist_->ReOrderWithoutUndo(old_items_); }
|
||||
|
||||
void PlaylistUndoCommandReOrderItems::redo() { playlist_->ReOrderWithoutUndo(new_items_); }
|
||||
40
src/playlist/playlistundocommandreorderitems.h
Normal file
40
src/playlist/playlistundocommandreorderitems.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2020-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry 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.
|
||||
*
|
||||
* Strawberry 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 Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PLAYLISTUNDOCOMMANDREORDERITEMS_H
|
||||
#define PLAYLISTUNDOCOMMANDREORDERITEMS_H
|
||||
|
||||
#include "playlistundocommandbase.h"
|
||||
#include "playlistitem.h"
|
||||
|
||||
class Playlist;
|
||||
|
||||
class PlaylistUndoCommandReOrderItems : public PlaylistUndoCommandBase {
|
||||
public:
|
||||
explicit PlaylistUndoCommandReOrderItems(Playlist *playlist, const PlaylistItemPtrList &new_items);
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
|
||||
private:
|
||||
PlaylistItemPtrList old_items_;
|
||||
PlaylistItemPtrList new_items_;
|
||||
};
|
||||
|
||||
#endif // PLAYLISTUNDOCOMMANDREORDERITEMS_H
|
||||
@@ -1,149 +0,0 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* This file was part of Clementine.
|
||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
*
|
||||
* Strawberry 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.
|
||||
*
|
||||
* Strawberry 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 Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QList>
|
||||
#include <QUndoStack>
|
||||
|
||||
#include "playlist.h"
|
||||
#include "playlistitem.h"
|
||||
#include "playlistundocommands.h"
|
||||
|
||||
namespace PlaylistUndoCommands {
|
||||
|
||||
Base::Base(Playlist *playlist) : QUndoCommand(nullptr), playlist_(playlist) {}
|
||||
|
||||
InsertItems::InsertItems(Playlist *playlist, const PlaylistItemPtrList &items, const int pos, const bool enqueue, const bool enqueue_next)
|
||||
: Base(playlist),
|
||||
items_(items),
|
||||
pos_(pos),
|
||||
enqueue_(enqueue),
|
||||
enqueue_next_(enqueue_next) {
|
||||
|
||||
setText(tr("add %n songs", "", static_cast<int>(items_.count())));
|
||||
|
||||
}
|
||||
|
||||
void InsertItems::redo() {
|
||||
playlist_->InsertItemsWithoutUndo(items_, pos_, enqueue_, enqueue_next_);
|
||||
}
|
||||
|
||||
void InsertItems::undo() {
|
||||
const int start = pos_ == -1 ? static_cast<int>(playlist_->rowCount() - items_.count()) : pos_;
|
||||
playlist_->RemoveItemsWithoutUndo(start, static_cast<int>(items_.count()));
|
||||
}
|
||||
|
||||
bool InsertItems::UpdateItem(const PlaylistItemPtr &updated_item) {
|
||||
|
||||
for (int i = 0; i < items_.size(); i++) {
|
||||
PlaylistItemPtr item = items_.value(i);
|
||||
if (item->Metadata().url() == updated_item->Metadata().url()) {
|
||||
items_[i] = updated_item;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
RemoveItems::RemoveItems(Playlist *playlist, const int pos, const int count) : Base(playlist) {
|
||||
setText(tr("remove %n songs", "", count));
|
||||
|
||||
ranges_ << Range(pos, count);
|
||||
}
|
||||
|
||||
void RemoveItems::redo() {
|
||||
|
||||
for (int i = 0; i < ranges_.count(); ++i) {
|
||||
ranges_[i].items_ = playlist_->RemoveItemsWithoutUndo(ranges_[i].pos_, ranges_[i].count_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void RemoveItems::undo() {
|
||||
|
||||
for (int i = static_cast<int>(ranges_.count() - 1); i >= 0; --i) {
|
||||
playlist_->InsertItemsWithoutUndo(ranges_[i].items_, ranges_[i].pos_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool RemoveItems::mergeWith(const QUndoCommand *other) {
|
||||
|
||||
const RemoveItems *remove_command = static_cast<const RemoveItems*>(other);
|
||||
ranges_.append(remove_command->ranges_);
|
||||
|
||||
int sum = 0;
|
||||
for (const Range &range : std::as_const(ranges_)) sum += range.count_;
|
||||
setText(tr("remove %n songs", "", sum));
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
MoveItems::MoveItems(Playlist *playlist, const QList<int> &source_rows, const int pos)
|
||||
: Base(playlist),
|
||||
source_rows_(source_rows),
|
||||
pos_(pos) {
|
||||
|
||||
setText(tr("move %n songs", "", static_cast<int>(source_rows.count())));
|
||||
|
||||
}
|
||||
|
||||
void MoveItems::redo() {
|
||||
playlist_->MoveItemsWithoutUndo(source_rows_, pos_);
|
||||
}
|
||||
|
||||
void MoveItems::undo() {
|
||||
playlist_->MoveItemsWithoutUndo(pos_, source_rows_);
|
||||
}
|
||||
|
||||
ReOrderItems::ReOrderItems(Playlist *playlist, const PlaylistItemPtrList &new_items)
|
||||
: Base(playlist), old_items_(playlist->items_), new_items_(new_items) {}
|
||||
|
||||
void ReOrderItems::undo() { playlist_->ReOrderWithoutUndo(old_items_); }
|
||||
|
||||
void ReOrderItems::redo() { playlist_->ReOrderWithoutUndo(new_items_); }
|
||||
|
||||
SortItems::SortItems(Playlist *playlist, const Playlist::Column column, const Qt::SortOrder order, const PlaylistItemPtrList &new_items)
|
||||
: ReOrderItems(playlist, new_items) {
|
||||
|
||||
Q_UNUSED(column);
|
||||
Q_UNUSED(order);
|
||||
|
||||
setText(tr("sort songs"));
|
||||
|
||||
}
|
||||
|
||||
|
||||
ShuffleItems::ShuffleItems(Playlist *playlist, const PlaylistItemPtrList &new_items)
|
||||
: ReOrderItems(playlist, new_items) {
|
||||
|
||||
setText(tr("shuffle songs"));
|
||||
|
||||
}
|
||||
|
||||
} // namespace PlaylistUndoCommands
|
||||
@@ -1,125 +0,0 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* This file was part of Clementine.
|
||||
* Copyright 2010, David Sansome <me@davidsansome.com>
|
||||
*
|
||||
* Strawberry 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.
|
||||
*
|
||||
* Strawberry 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 Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PLAYLISTUNDOCOMMANDS_H
|
||||
#define PLAYLISTUNDOCOMMANDS_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QList>
|
||||
#include <QUndoStack>
|
||||
|
||||
#include "playlist.h"
|
||||
#include "playlistitem.h"
|
||||
|
||||
namespace PlaylistUndoCommands {
|
||||
|
||||
enum Types {
|
||||
Type_RemoveItems = 0,
|
||||
};
|
||||
|
||||
class Base : public QUndoCommand {
|
||||
Q_DECLARE_TR_FUNCTIONS(PlaylistUndoCommands)
|
||||
|
||||
public:
|
||||
explicit Base(Playlist *playlist);
|
||||
|
||||
protected:
|
||||
Playlist *playlist_;
|
||||
};
|
||||
|
||||
class InsertItems : public Base {
|
||||
public:
|
||||
explicit InsertItems(Playlist *playlist, const PlaylistItemPtrList &items, const int pos, const bool enqueue = false, const bool enqueue_next = false);
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
// When load is async, items have already been pushed, so we need to update them.
|
||||
// This function try to find the equivalent item, and replace it with the new (completely loaded) one.
|
||||
// Return true if the was found (and updated), false otherwise
|
||||
bool UpdateItem(const PlaylistItemPtr &updated_item);
|
||||
|
||||
private:
|
||||
PlaylistItemPtrList items_;
|
||||
int pos_;
|
||||
bool enqueue_;
|
||||
bool enqueue_next_;
|
||||
};
|
||||
|
||||
class RemoveItems : public Base {
|
||||
public:
|
||||
explicit RemoveItems(Playlist *playlist, const int pos, const int count);
|
||||
|
||||
int id() const override { return Type_RemoveItems; }
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
bool mergeWith(const QUndoCommand *other) override;
|
||||
|
||||
private:
|
||||
struct Range {
|
||||
Range(const int pos, const int count) : pos_(pos), count_(count) {}
|
||||
int pos_;
|
||||
int count_;
|
||||
PlaylistItemPtrList items_;
|
||||
};
|
||||
|
||||
QList<Range> ranges_;
|
||||
};
|
||||
|
||||
class MoveItems : public Base {
|
||||
public:
|
||||
explicit MoveItems(Playlist *playlist, const QList<int> &source_rows, const int pos);
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
|
||||
private:
|
||||
QList<int> source_rows_;
|
||||
int pos_;
|
||||
};
|
||||
|
||||
class ReOrderItems : public Base {
|
||||
public:
|
||||
explicit ReOrderItems(Playlist *playlist, const PlaylistItemPtrList &new_items);
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
|
||||
private:
|
||||
PlaylistItemPtrList old_items_;
|
||||
PlaylistItemPtrList new_items_;
|
||||
};
|
||||
|
||||
class SortItems : public ReOrderItems {
|
||||
public:
|
||||
explicit SortItems(Playlist *playlist, const Playlist::Column column, const Qt::SortOrder order, const PlaylistItemPtrList &new_items);
|
||||
|
||||
};
|
||||
|
||||
class ShuffleItems : public ReOrderItems {
|
||||
public:
|
||||
explicit ShuffleItems(Playlist *playlist, const PlaylistItemPtrList &new_items);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // PLAYLISTUNDOCOMMANDS_H
|
||||
30
src/playlist/playlistundocommandshuffleitems.cpp
Normal file
30
src/playlist/playlistundocommandshuffleitems.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2020-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry 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.
|
||||
*
|
||||
* Strawberry 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 Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "playlist.h"
|
||||
#include "playlistundocommandshuffleitems.h"
|
||||
|
||||
PlaylistUndoCommandShuffleItems::PlaylistUndoCommandShuffleItems(Playlist *playlist, const PlaylistItemPtrList &new_items)
|
||||
: PlaylistUndoCommandReOrderItems(playlist, new_items) {
|
||||
|
||||
setText(QObject::tr("shuffle songs"));
|
||||
|
||||
}
|
||||
33
src/playlist/playlistundocommandshuffleitems.h
Normal file
33
src/playlist/playlistundocommandshuffleitems.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2020-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry 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.
|
||||
*
|
||||
* Strawberry 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 Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PLAYLISTUNDOCOMMANDSHUFFLEITEMS_H
|
||||
#define PLAYLISTUNDOCOMMANDSHUFFLEITEMS_H
|
||||
|
||||
#include "playlistundocommandreorderitems.h"
|
||||
#include "playlistitem.h"
|
||||
|
||||
class Playlist;
|
||||
|
||||
class PlaylistUndoCommandShuffleItems : public PlaylistUndoCommandReOrderItems {
|
||||
public:
|
||||
explicit PlaylistUndoCommandShuffleItems(Playlist *playlist, const PlaylistItemPtrList &new_items);
|
||||
};
|
||||
|
||||
#endif // PLAYLISTUNDOCOMMANDSHUFFLEITEMS_H
|
||||
33
src/playlist/playlistundocommandsortitems.cpp
Normal file
33
src/playlist/playlistundocommandsortitems.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2020-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry 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.
|
||||
*
|
||||
* Strawberry 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 Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "playlist.h"
|
||||
#include "playlistundocommandsortitems.h"
|
||||
|
||||
PlaylistUndoCommandSortItems::PlaylistUndoCommandSortItems(Playlist *playlist, const Playlist::Column column, const Qt::SortOrder order, const PlaylistItemPtrList &new_items)
|
||||
: PlaylistUndoCommandReOrderItems(playlist, new_items) {
|
||||
|
||||
Q_UNUSED(column);
|
||||
Q_UNUSED(order);
|
||||
|
||||
setText(QObject::tr("sort songs"));
|
||||
|
||||
}
|
||||
32
src/playlist/playlistundocommandsortitems.h
Normal file
32
src/playlist/playlistundocommandsortitems.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Strawberry Music Player
|
||||
* Copyright 2020-2024, Jonas Kvinge <jonas@jkvinge.net>
|
||||
*
|
||||
* Strawberry 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.
|
||||
*
|
||||
* Strawberry 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 Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PLAYLISTUNDOCOMMANDSORTITEMS_H
|
||||
#define PLAYLISTUNDOCOMMANDSORTITEMS_H
|
||||
|
||||
#include "playlistundocommandreorderitems.h"
|
||||
#include "playlist.h"
|
||||
#include "playlistitem.h"
|
||||
|
||||
class PlaylistUndoCommandSortItems : public PlaylistUndoCommandReOrderItems {
|
||||
public:
|
||||
explicit PlaylistUndoCommandSortItems(Playlist *playlist, const Playlist::Column column, const Qt::SortOrder order, const PlaylistItemPtrList &new_items);
|
||||
};
|
||||
|
||||
#endif // PLAYLISTUNDOCOMMANDSORTITEMS_H
|
||||
@@ -59,11 +59,10 @@
|
||||
#include <QtEvents>
|
||||
#include <QSettings>
|
||||
|
||||
#include "core/application.h"
|
||||
#include "core/player.h"
|
||||
#include "core/qt_blurimage.h"
|
||||
#include "includes/qt_blurimage.h"
|
||||
#include "core/song.h"
|
||||
#include "core/settings.h"
|
||||
#include "core/player.h"
|
||||
#include "playlistmanager.h"
|
||||
#include "playlist.h"
|
||||
#include "playlistdelegates.h"
|
||||
@@ -73,8 +72,8 @@
|
||||
#include "playlistproxystyle.h"
|
||||
#include "covermanager/currentalbumcoverloader.h"
|
||||
#include "covermanager/albumcoverloaderresult.h"
|
||||
#include "settings/appearancesettingspage.h"
|
||||
#include "settings/playlistsettingspage.h"
|
||||
#include "constants/appearancesettings.h"
|
||||
#include "constants/playlistsettings.h"
|
||||
#include "dynamicplaylistcontrols.h"
|
||||
|
||||
#ifdef HAVE_MOODBAR
|
||||
@@ -92,18 +91,17 @@ constexpr int kDropIndicatorGradientWidth = 5;
|
||||
|
||||
PlaylistView::PlaylistView(QWidget *parent)
|
||||
: QTreeView(parent),
|
||||
app_(nullptr),
|
||||
style_(new PlaylistProxyStyle(QApplication::style()->name())),
|
||||
playlist_(nullptr),
|
||||
header_(new PlaylistHeader(Qt::Horizontal, this, this)),
|
||||
background_image_type_(AppearanceSettingsPage::BackgroundImageType::Default),
|
||||
background_image_position_(AppearanceSettingsPage::BackgroundImagePosition::BottomRight),
|
||||
background_image_type_(AppearanceSettings::BackgroundImageType::Default),
|
||||
background_image_position_(AppearanceSettings::BackgroundImagePosition::BottomRight),
|
||||
background_image_maxsize_(0),
|
||||
background_image_stretch_(false),
|
||||
background_image_do_not_cut_(true),
|
||||
background_image_keep_aspect_ratio_(true),
|
||||
blur_radius_(AppearanceSettingsPage::kDefaultBlurRadius),
|
||||
opacity_level_(AppearanceSettingsPage::kDefaultOpacityLevel),
|
||||
blur_radius_(AppearanceSettings::kDefaultBlurRadius),
|
||||
opacity_level_(AppearanceSettings::kDefaultOpacityLevel),
|
||||
background_initialized_(false),
|
||||
set_initial_header_layout_(false),
|
||||
header_state_loaded_(false),
|
||||
@@ -187,18 +185,30 @@ PlaylistView::~PlaylistView() {
|
||||
style_->deleteLater();
|
||||
}
|
||||
|
||||
void PlaylistView::Init(Application *app) {
|
||||
void PlaylistView::Init(const SharedPtr<Player> player,
|
||||
const SharedPtr<PlaylistManager> playlist_manager,
|
||||
const SharedPtr<CollectionBackend> collection_backend,
|
||||
#ifdef HAVE_MOODBAR
|
||||
const SharedPtr<MoodbarLoader> moodbar_loader,
|
||||
#endif
|
||||
const SharedPtr<CurrentAlbumCoverLoader> current_albumcover_loader) {
|
||||
|
||||
Q_ASSERT(app);
|
||||
app_ = app;
|
||||
player_ = player;
|
||||
playlist_manager_ = playlist_manager;
|
||||
collection_backend_ = collection_backend;
|
||||
current_albumcover_loader_ = current_albumcover_loader;
|
||||
|
||||
#ifdef HAVE_MOODBAR
|
||||
moodbar_loader_ = moodbar_loader;
|
||||
#endif
|
||||
|
||||
SetItemDelegates();
|
||||
|
||||
QObject::connect(&*app_->playlist_manager(), &PlaylistManager::CurrentSongChanged, this, &PlaylistView::SongChanged);
|
||||
QObject::connect(&*app_->current_albumcover_loader(), &CurrentAlbumCoverLoader::AlbumCoverLoaded, this, &PlaylistView::AlbumCoverLoaded);
|
||||
QObject::connect(&*app_->player(), &Player::Playing, this, &PlaylistView::StartGlowing);
|
||||
QObject::connect(&*app_->player(), &Player::Paused, this, &PlaylistView::StopGlowing);
|
||||
QObject::connect(&*app_->player(), &Player::Stopped, this, &PlaylistView::Stopped);
|
||||
QObject::connect(&*playlist_manager, &PlaylistManager::CurrentSongChanged, this, &PlaylistView::SongChanged);
|
||||
QObject::connect(&*current_albumcover_loader_, &CurrentAlbumCoverLoader::AlbumCoverLoaded, this, &PlaylistView::AlbumCoverLoaded);
|
||||
QObject::connect(&*player, &Player::Playing, this, &PlaylistView::StartGlowing);
|
||||
QObject::connect(&*player, &Player::Paused, this, &PlaylistView::StopGlowing);
|
||||
QObject::connect(&*player, &Player::Stopped, this, &PlaylistView::Stopped);
|
||||
|
||||
}
|
||||
|
||||
@@ -207,13 +217,13 @@ void PlaylistView::SetItemDelegates() {
|
||||
setItemDelegate(new PlaylistDelegateBase(this));
|
||||
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::Title), new TextItemDelegate(this));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::Album), new TagCompletionItemDelegate(this, app_->collection_backend(), Playlist::Column::Album));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::Artist), new TagCompletionItemDelegate(this, app_->collection_backend(), Playlist::Column::Artist));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::AlbumArtist), new TagCompletionItemDelegate(this, app_->collection_backend(), Playlist::Column::AlbumArtist));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::Genre), new TagCompletionItemDelegate(this, app_->collection_backend(), Playlist::Column::Genre));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::Composer), new TagCompletionItemDelegate(this, app_->collection_backend(), Playlist::Column::Composer));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::Performer), new TagCompletionItemDelegate(this, app_->collection_backend(), Playlist::Column::Performer));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::Grouping), new TagCompletionItemDelegate(this, app_->collection_backend(), Playlist::Column::Grouping));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::Album), new TagCompletionItemDelegate(this, collection_backend_, Playlist::Column::Album));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::Artist), new TagCompletionItemDelegate(this, collection_backend_, Playlist::Column::Artist));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::AlbumArtist), new TagCompletionItemDelegate(this, collection_backend_, Playlist::Column::AlbumArtist));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::Genre), new TagCompletionItemDelegate(this, collection_backend_, Playlist::Column::Genre));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::Composer), new TagCompletionItemDelegate(this, collection_backend_, Playlist::Column::Composer));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::Performer), new TagCompletionItemDelegate(this, collection_backend_, Playlist::Column::Performer));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::Grouping), new TagCompletionItemDelegate(this, collection_backend_, Playlist::Column::Grouping));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::Length), new LengthItemDelegate(this));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::Filesize), new SizeItemDelegate(this));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::Filetype), new FileTypeItemDelegate(this));
|
||||
@@ -230,7 +240,7 @@ void PlaylistView::SetItemDelegates() {
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::Source), new SongSourceDelegate(this));
|
||||
|
||||
#ifdef HAVE_MOODBAR
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::Mood), new MoodbarItemDelegate(app_, this, this));
|
||||
setItemDelegateForColumn(static_cast<int>(Playlist::Column::Mood), new MoodbarItemDelegate(moodbar_loader_, this, this));
|
||||
#endif
|
||||
|
||||
rating_delegate_ = new RatingItemDelegate(this);
|
||||
@@ -293,12 +303,12 @@ void PlaylistView::SetPlaylist(Playlist *playlist) {
|
||||
void PlaylistView::LoadHeaderState() {
|
||||
|
||||
Settings s;
|
||||
s.beginGroup(Playlist::kSettingsGroup);
|
||||
if (s.contains("state")) {
|
||||
header_state_version_ = s.value("state_version", 0).toInt();
|
||||
header_state_ = s.value("state").toByteArray();
|
||||
s.beginGroup(PlaylistSettings::kSettingsGroup);
|
||||
if (s.contains(PlaylistSettings::kState)) {
|
||||
header_state_version_ = s.value(PlaylistSettings::kStateVersion, 0).toInt();
|
||||
header_state_ = s.value(PlaylistSettings::kState).toByteArray();
|
||||
}
|
||||
if (s.contains("column_alignments")) column_alignment_ = s.value("column_alignments").value<ColumnAlignmentMap>();
|
||||
if (s.contains(PlaylistSettings::kColumnAlignments)) column_alignment_ = s.value(PlaylistSettings::kColumnAlignments).value<ColumnAlignmentMap>();
|
||||
s.endGroup();
|
||||
|
||||
if (column_alignment_.isEmpty()) {
|
||||
@@ -851,10 +861,10 @@ void PlaylistView::mousePressEvent(QMouseEvent *event) {
|
||||
if (idx.isValid()) {
|
||||
switch (event->button()) {
|
||||
case Qt::XButton1:
|
||||
app_->player()->Previous();
|
||||
player_->Previous();
|
||||
break;
|
||||
case Qt::XButton2:
|
||||
app_->player()->Next();
|
||||
player_->Next();
|
||||
break;
|
||||
case Qt::LeftButton:{
|
||||
if (idx.data(Playlist::Role_CanSetRating).toBool() && !rating_locked_) {
|
||||
@@ -972,7 +982,7 @@ void PlaylistView::paintEvent(QPaintEvent *event) {
|
||||
// The cached pixmap gets invalidated in dragLeaveEvent, dropEvent and scrollContentsBy.
|
||||
|
||||
// Draw background
|
||||
if (background_image_type_ == AppearanceSettingsPage::BackgroundImageType::Custom || background_image_type_ == AppearanceSettingsPage::BackgroundImageType::Album) {
|
||||
if (background_image_type_ == AppearanceSettings::BackgroundImageType::Custom || background_image_type_ == AppearanceSettings::BackgroundImageType::Album) {
|
||||
if (!background_image_.isNull() || !previous_background_image_.isNull()) {
|
||||
QPainter background_painter(viewport());
|
||||
|
||||
@@ -1023,23 +1033,23 @@ void PlaylistView::paintEvent(QPaintEvent *event) {
|
||||
background_painter.setOpacity(1.0 - previous_background_image_opacity_);
|
||||
}
|
||||
switch (background_image_position_) {
|
||||
case AppearanceSettingsPage::BackgroundImagePosition::UpperLeft:
|
||||
case AppearanceSettings::BackgroundImagePosition::UpperLeft:
|
||||
current_background_image_x_ = 0;
|
||||
current_background_image_y_ = 0;
|
||||
break;
|
||||
case AppearanceSettingsPage::BackgroundImagePosition::UpperRight:
|
||||
case AppearanceSettings::BackgroundImagePosition::UpperRight:
|
||||
current_background_image_x_ = (pb_width - cached_scaled_background_image_.width());
|
||||
current_background_image_y_ = 0;
|
||||
break;
|
||||
case AppearanceSettingsPage::BackgroundImagePosition::Middle:
|
||||
case AppearanceSettings::BackgroundImagePosition::Middle:
|
||||
current_background_image_x_ = ((pb_width - cached_scaled_background_image_.width()) / 2);
|
||||
current_background_image_y_ = ((pb_height - cached_scaled_background_image_.height()) / 2);
|
||||
break;
|
||||
case AppearanceSettingsPage::BackgroundImagePosition::BottomLeft:
|
||||
case AppearanceSettings::BackgroundImagePosition::BottomLeft:
|
||||
current_background_image_x_ = 0;
|
||||
current_background_image_y_ = (pb_height - cached_scaled_background_image_.height());
|
||||
break;
|
||||
case AppearanceSettingsPage::BackgroundImagePosition::BottomRight:
|
||||
case AppearanceSettings::BackgroundImagePosition::BottomRight:
|
||||
default:
|
||||
current_background_image_x_ = (pb_width - cached_scaled_background_image_.width());
|
||||
current_background_image_y_ = (pb_height - cached_scaled_background_image_.height());
|
||||
@@ -1169,32 +1179,32 @@ void PlaylistView::ReloadSettings() {
|
||||
|
||||
Settings s;
|
||||
|
||||
s.beginGroup(PlaylistSettingsPage::kSettingsGroup);
|
||||
bars_enabled_ = s.value("show_bars", true).toBool();
|
||||
s.beginGroup(PlaylistSettings::kSettingsGroup);
|
||||
bars_enabled_ = s.value(PlaylistSettings::kShowBars, true).toBool();
|
||||
#ifdef Q_OS_MACOS
|
||||
bool glow_effect = false;
|
||||
#else
|
||||
bool glow_effect = true;
|
||||
#endif
|
||||
glow_enabled_ = bars_enabled_ && s.value("glow_effect", glow_effect).toBool();
|
||||
bool editmetadatainline = s.value("editmetadatainline", false).toBool();
|
||||
select_track_ = s.value("select_track", false).toBool();
|
||||
auto_sort_ = s.value("auto_sort", false).toBool();
|
||||
setAlternatingRowColors(s.value("alternating_row_colors", true).toBool());
|
||||
glow_enabled_ = bars_enabled_ && s.value(PlaylistSettings::kGlowEffect, glow_effect).toBool();
|
||||
bool editmetadatainline = s.value(PlaylistSettings::kEditMetadataInline, false).toBool();
|
||||
select_track_ = s.value(PlaylistSettings::kSelectTrack, false).toBool();
|
||||
auto_sort_ = s.value(PlaylistSettings::kAutoSort, false).toBool();
|
||||
setAlternatingRowColors(s.value(PlaylistSettings::kAlternatingRowColors, true).toBool());
|
||||
s.endGroup();
|
||||
|
||||
s.beginGroup(AppearanceSettingsPage::kSettingsGroup);
|
||||
QVariant background_image_type_var = s.value(AppearanceSettingsPage::kBackgroundImageType);
|
||||
QVariant background_image_position_var = s.value(AppearanceSettingsPage::kBackgroundImagePosition);
|
||||
int background_image_maxsize = s.value(AppearanceSettingsPage::kBackgroundImageMaxSize).toInt();
|
||||
s.beginGroup(AppearanceSettings::kSettingsGroup);
|
||||
QVariant background_image_type_var = s.value(AppearanceSettings::kBackgroundImageType);
|
||||
QVariant background_image_position_var = s.value(AppearanceSettings::kBackgroundImagePosition);
|
||||
int background_image_maxsize = s.value(AppearanceSettings::kBackgroundImageMaxSize).toInt();
|
||||
if (background_image_maxsize <= 10) background_image_maxsize = 9000;
|
||||
QString background_image_filename = s.value(AppearanceSettingsPage::kBackgroundImageFilename).toString();
|
||||
bool background_image_stretch = s.value(AppearanceSettingsPage::kBackgroundImageStretch, false).toBool();
|
||||
bool background_image_do_not_cut = s.value(AppearanceSettingsPage::kBackgroundImageDoNotCut, true).toBool();
|
||||
bool background_image_keep_aspect_ratio = s.value(AppearanceSettingsPage::kBackgroundImageKeepAspectRatio, true).toBool();
|
||||
int blur_radius = s.value(AppearanceSettingsPage::kBlurRadius, AppearanceSettingsPage::kDefaultBlurRadius).toInt();
|
||||
int opacity_level = s.value(AppearanceSettingsPage::kOpacityLevel, AppearanceSettingsPage::kDefaultOpacityLevel).toInt();
|
||||
QColor playlist_playing_song_color = s.value(AppearanceSettingsPage::kPlaylistPlayingSongColor).value<QColor>();
|
||||
QString background_image_filename = s.value(AppearanceSettings::kBackgroundImageFilename).toString();
|
||||
bool background_image_stretch = s.value(AppearanceSettings::kBackgroundImageStretch, false).toBool();
|
||||
bool background_image_do_not_cut = s.value(AppearanceSettings::kBackgroundImageDoNotCut, true).toBool();
|
||||
bool background_image_keep_aspect_ratio = s.value(AppearanceSettings::kBackgroundImageKeepAspectRatio, true).toBool();
|
||||
int blur_radius = s.value(AppearanceSettings::kBlurRadius, AppearanceSettings::kDefaultBlurRadius).toInt();
|
||||
int opacity_level = s.value(AppearanceSettings::kOpacityLevel, AppearanceSettings::kDefaultOpacityLevel).toInt();
|
||||
QColor playlist_playing_song_color = s.value(AppearanceSettings::kPlaylistPlayingSongColor).value<QColor>();
|
||||
if (playlist_playing_song_color != playlist_playing_song_color_) {
|
||||
row_height_ = -1;
|
||||
}
|
||||
@@ -1205,20 +1215,20 @@ void PlaylistView::ReloadSettings() {
|
||||
if (!glow_enabled_) StopGlowing();
|
||||
|
||||
// Background:
|
||||
AppearanceSettingsPage::BackgroundImageType background_image_type(AppearanceSettingsPage::BackgroundImageType::Default);
|
||||
AppearanceSettings::BackgroundImageType background_image_type(AppearanceSettings::BackgroundImageType::Default);
|
||||
if (background_image_type_var.isValid()) {
|
||||
background_image_type = static_cast<AppearanceSettingsPage::BackgroundImageType>(background_image_type_var.toInt());
|
||||
background_image_type = static_cast<AppearanceSettings::BackgroundImageType>(background_image_type_var.toInt());
|
||||
}
|
||||
else {
|
||||
background_image_type = AppearanceSettingsPage::BackgroundImageType::Default;
|
||||
background_image_type = AppearanceSettings::BackgroundImageType::Default;
|
||||
}
|
||||
|
||||
AppearanceSettingsPage::BackgroundImagePosition background_image_position(AppearanceSettingsPage::BackgroundImagePosition::BottomRight);
|
||||
AppearanceSettings::BackgroundImagePosition background_image_position(AppearanceSettings::BackgroundImagePosition::BottomRight);
|
||||
if (background_image_position_var.isValid()) {
|
||||
background_image_position = static_cast<AppearanceSettingsPage::BackgroundImagePosition>(background_image_position_var.toInt());
|
||||
background_image_position = static_cast<AppearanceSettings::BackgroundImagePosition>(background_image_position_var.toInt());
|
||||
}
|
||||
else {
|
||||
background_image_position = AppearanceSettingsPage::BackgroundImagePosition::BottomRight;
|
||||
background_image_position = AppearanceSettings::BackgroundImagePosition::BottomRight;
|
||||
}
|
||||
|
||||
// Check if background properties have changed.
|
||||
@@ -1250,10 +1260,10 @@ void PlaylistView::ReloadSettings() {
|
||||
blur_radius_ = blur_radius;
|
||||
opacity_level_ = opacity_level;
|
||||
|
||||
if (background_image_type_ == AppearanceSettingsPage::BackgroundImageType::Custom) {
|
||||
if (background_image_type_ == AppearanceSettings::BackgroundImageType::Custom) {
|
||||
set_background_image(QImage(background_image_filename));
|
||||
}
|
||||
else if (background_image_type_ == AppearanceSettingsPage::BackgroundImageType::Album) {
|
||||
else if (background_image_type_ == AppearanceSettings::BackgroundImageType::Album) {
|
||||
set_background_image(current_song_cover_art_);
|
||||
}
|
||||
else {
|
||||
@@ -1263,8 +1273,8 @@ void PlaylistView::ReloadSettings() {
|
||||
cached_scaled_background_image_ = QPixmap();
|
||||
previous_background_image_ = QPixmap();
|
||||
}
|
||||
setProperty("default_background_enabled", background_image_type_ == AppearanceSettingsPage::BackgroundImageType::Default);
|
||||
setProperty("strawbs_background_enabled", background_image_type_ == AppearanceSettingsPage::BackgroundImageType::Strawbs);
|
||||
setProperty("default_background_enabled", background_image_type_ == AppearanceSettings::BackgroundImageType::Default);
|
||||
setProperty("strawbs_background_enabled", background_image_type_ == AppearanceSettings::BackgroundImageType::Strawbs);
|
||||
Q_EMIT BackgroundPropertyChanged();
|
||||
force_background_redraw_ = true;
|
||||
}
|
||||
@@ -1283,11 +1293,11 @@ void PlaylistView::SaveSettings() {
|
||||
if (!header_state_loaded_ || read_only_settings_) return;
|
||||
|
||||
Settings s;
|
||||
s.beginGroup(Playlist::kSettingsGroup);
|
||||
s.beginGroup(PlaylistSettings::kSettingsGroup);
|
||||
s.setValue("state_version", header_state_version_);
|
||||
s.setValue("state", header_->SaveState());
|
||||
s.setValue("column_alignments", QVariant::fromValue<ColumnAlignmentMap>(column_alignment_));
|
||||
s.setValue("rating_locked", rating_locked_);
|
||||
s.setValue(PlaylistSettings::kRatingLocked, rating_locked_);
|
||||
s.endGroup();
|
||||
|
||||
}
|
||||
@@ -1424,7 +1434,7 @@ void PlaylistView::AlbumCoverLoaded(const Song &song, const AlbumCoverLoaderResu
|
||||
|
||||
current_song_cover_art_ = result.album_cover.image;
|
||||
|
||||
if (background_image_type_ == AppearanceSettingsPage::BackgroundImageType::Album) {
|
||||
if (background_image_type_ == AppearanceSettings::BackgroundImageType::Album) {
|
||||
set_background_image(result.success && result.type != AlbumCoverLoaderResult::Type::None && result.type != AlbumCoverLoaderResult::Type::Unset ? current_song_cover_art_ : QImage());
|
||||
force_background_redraw_ = true;
|
||||
update();
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
#include "core/song.h"
|
||||
#include "covermanager/albumcoverloaderresult.h"
|
||||
#include "settings/appearancesettingspage.h"
|
||||
#include "constants/appearancesettings.h"
|
||||
#include "playlist.h"
|
||||
|
||||
class QWidget;
|
||||
@@ -66,13 +66,19 @@ class QMouseEvent;
|
||||
class QPaintEvent;
|
||||
class QTimerEvent;
|
||||
|
||||
class Application;
|
||||
class Player;
|
||||
class CollectionBackend;
|
||||
class PlaylistManager;
|
||||
class CurrentAlbumCoverLoader;
|
||||
class PlaylistHeader;
|
||||
class PlaylistProxyStyle;
|
||||
class DynamicPlaylistControls;
|
||||
class RatingItemDelegate;
|
||||
|
||||
#ifdef HAVE_MOODBAR
|
||||
class MoodbarLoader;
|
||||
#endif
|
||||
|
||||
class PlaylistView : public QTreeView {
|
||||
Q_OBJECT
|
||||
|
||||
@@ -82,7 +88,14 @@ class PlaylistView : public QTreeView {
|
||||
|
||||
static ColumnAlignmentMap DefaultColumnAlignment();
|
||||
|
||||
void Init(Application *app);
|
||||
void Init(const SharedPtr<Player> player,
|
||||
const SharedPtr<PlaylistManager> playlist_manager,
|
||||
const SharedPtr<CollectionBackend> collection_backend,
|
||||
#ifdef HAVE_MOODBAR
|
||||
const SharedPtr<MoodbarLoader> moodbar_loader,
|
||||
#endif
|
||||
const SharedPtr<CurrentAlbumCoverLoader> current_albumcover_loader);
|
||||
|
||||
void SetItemDelegates();
|
||||
void SetPlaylist(Playlist *playlist);
|
||||
void RemoveSelected();
|
||||
@@ -90,7 +103,7 @@ class PlaylistView : public QTreeView {
|
||||
void SetReadOnlySettings(const bool read_only) { read_only_settings_ = read_only; }
|
||||
|
||||
Playlist *playlist() const { return playlist_; }
|
||||
AppearanceSettingsPage::BackgroundImageType background_image_type() const { return background_image_type_; }
|
||||
AppearanceSettings::BackgroundImageType background_image_type() const { return background_image_type_; }
|
||||
Qt::Alignment column_alignment(int section) const;
|
||||
|
||||
void ResetHeaderState();
|
||||
@@ -175,7 +188,7 @@ class PlaylistView : public QTreeView {
|
||||
void LoadTinyPlayPausePixmaps(const int desired_size);
|
||||
void UpdateCachedCurrentRowPixmap(QStyleOptionViewItem option, const QModelIndex &idx);
|
||||
|
||||
void set_background_image_type(AppearanceSettingsPage::BackgroundImageType bg) {
|
||||
void set_background_image_type(AppearanceSettings::BackgroundImageType bg) {
|
||||
background_image_type_ = bg;
|
||||
Q_EMIT BackgroundPropertyChanged(); // clazy:exclude=incorrect-emit
|
||||
}
|
||||
@@ -192,15 +205,22 @@ class PlaylistView : public QTreeView {
|
||||
|
||||
void RepositionDynamicControls();
|
||||
|
||||
Application *app_;
|
||||
SharedPtr<Player> player_;
|
||||
SharedPtr<PlaylistManager> playlist_manager_;
|
||||
SharedPtr<CollectionBackend> collection_backend_;
|
||||
SharedPtr<CurrentAlbumCoverLoader> current_albumcover_loader_;
|
||||
#ifdef HAVE_MOODBAR
|
||||
SharedPtr<MoodbarLoader> moodbar_loader_;
|
||||
#endif
|
||||
|
||||
PlaylistProxyStyle *style_;
|
||||
Playlist *playlist_;
|
||||
PlaylistHeader *header_;
|
||||
|
||||
qreal device_pixel_ratio_;
|
||||
AppearanceSettingsPage::BackgroundImageType background_image_type_;
|
||||
AppearanceSettings::BackgroundImageType background_image_type_;
|
||||
QString background_image_filename_;
|
||||
AppearanceSettingsPage::BackgroundImagePosition background_image_position_;
|
||||
AppearanceSettings::BackgroundImagePosition background_image_position_;
|
||||
int background_image_maxsize_;
|
||||
bool background_image_stretch_;
|
||||
bool background_image_do_not_cut_;
|
||||
|
||||
@@ -28,23 +28,29 @@
|
||||
#include <QList>
|
||||
#include <QUrl>
|
||||
|
||||
#include "includes/shared_ptr.h"
|
||||
#include "core/logging.h"
|
||||
#include "core/shared_ptr.h"
|
||||
#include "core/songloader.h"
|
||||
#include "core/urlhandlers.h"
|
||||
#include "core/taskmanager.h"
|
||||
#include "core/songloader.h"
|
||||
#include "playlist.h"
|
||||
#include "songloaderinserter.h"
|
||||
|
||||
SongLoaderInserter::SongLoaderInserter(SharedPtr<TaskManager> task_manager, SharedPtr<CollectionBackendInterface> collection_backend, const SharedPtr<Player> player, QObject *parent)
|
||||
SongLoaderInserter::SongLoaderInserter(const SharedPtr<TaskManager> task_manager,
|
||||
const SharedPtr<TagReaderClient> tagreader_client,
|
||||
const SharedPtr<UrlHandlers> url_handlers,
|
||||
const SharedPtr<CollectionBackendInterface> collection_backend,
|
||||
QObject *parent)
|
||||
: QObject(parent),
|
||||
task_manager_(task_manager),
|
||||
tagreader_client_(tagreader_client),
|
||||
url_handlers_(url_handlers),
|
||||
collection_backend_(collection_backend),
|
||||
destination_(nullptr),
|
||||
row_(-1),
|
||||
play_now_(true),
|
||||
enqueue_(false),
|
||||
enqueue_next_(false),
|
||||
collection_backend_(collection_backend),
|
||||
player_(player) {}
|
||||
enqueue_next_(false) {}
|
||||
|
||||
SongLoaderInserter::~SongLoaderInserter() { qDeleteAll(pending_); }
|
||||
|
||||
@@ -61,7 +67,7 @@ void SongLoaderInserter::Load(Playlist *destination, int row, bool play_now, boo
|
||||
QObject::connect(this, &SongLoaderInserter::EffectiveLoadFinished, destination, &Playlist::UpdateItems);
|
||||
|
||||
for (const QUrl &url : urls) {
|
||||
SongLoader *loader = new SongLoader(collection_backend_, player_, this);
|
||||
SongLoader *loader = new SongLoader(url_handlers_, collection_backend_, tagreader_client_, this);
|
||||
|
||||
SongLoader::Result ret = loader->Load(url);
|
||||
|
||||
@@ -103,7 +109,7 @@ void SongLoaderInserter::LoadAudioCD(Playlist *destination, int row, bool play_n
|
||||
enqueue_ = enqueue;
|
||||
enqueue_next_ = enqueue_next;
|
||||
|
||||
SongLoader *loader = new SongLoader(collection_backend_, player_, this);
|
||||
SongLoader *loader = new SongLoader(url_handlers_, collection_backend_, tagreader_client_, this);
|
||||
QObject::connect(loader, &SongLoader::AudioCDTracksLoadFinished, this, [this, loader]() { AudioCDTracksLoadFinished(loader); });
|
||||
QObject::connect(loader, &SongLoader::LoadAudioCDFinished, this, &SongLoaderInserter::AudioCDTagsLoaded);
|
||||
qLog(Info) << "Loading audio CD...";
|
||||
|
||||
@@ -29,12 +29,14 @@
|
||||
#include <QString>
|
||||
#include <QUrl>
|
||||
|
||||
#include "core/shared_ptr.h"
|
||||
#include "includes/shared_ptr.h"
|
||||
#include "core/song.h"
|
||||
|
||||
class Player;
|
||||
class SongLoader;
|
||||
class TaskManager;
|
||||
class UrlHandlers;
|
||||
class Player;
|
||||
class TagReaderClient;
|
||||
class SongLoader;
|
||||
class CollectionBackendInterface;
|
||||
class Playlist;
|
||||
|
||||
@@ -42,7 +44,12 @@ class SongLoaderInserter : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SongLoaderInserter(SharedPtr<TaskManager> task_manager, SharedPtr<CollectionBackendInterface> collection_backend, const SharedPtr<Player> player, QObject *parent = nullptr);
|
||||
explicit SongLoaderInserter(const SharedPtr<TaskManager> task_manager,
|
||||
const SharedPtr<TagReaderClient> tagreader_client,
|
||||
const SharedPtr<UrlHandlers> url_handlers,
|
||||
const SharedPtr<CollectionBackendInterface> collection_backend,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
~SongLoaderInserter() override;
|
||||
|
||||
void Load(Playlist *destination, int row, bool play_now, bool enqueue, bool enqueue_next, const QList<QUrl> &urls);
|
||||
@@ -63,7 +70,10 @@ class SongLoaderInserter : public QObject {
|
||||
void AsyncLoad();
|
||||
|
||||
private:
|
||||
SharedPtr<TaskManager> task_manager_;
|
||||
const SharedPtr<TaskManager> task_manager_;
|
||||
const SharedPtr<TagReaderClient> tagreader_client_;
|
||||
const SharedPtr<UrlHandlers> url_handlers_;
|
||||
const SharedPtr<CollectionBackendInterface> collection_backend_;
|
||||
|
||||
Playlist *destination_;
|
||||
int row_;
|
||||
@@ -74,8 +84,6 @@ class SongLoaderInserter : public QObject {
|
||||
SongList songs_;
|
||||
|
||||
QList<SongLoader*> pending_;
|
||||
SharedPtr<CollectionBackendInterface> collection_backend_;
|
||||
const SharedPtr<Player> player_;
|
||||
};
|
||||
|
||||
#endif // SONGLOADERINSERTER_H
|
||||
|
||||
Reference in New Issue
Block a user