From 03dae637f0ce3632f096044272ec7353a13ce570 Mon Sep 17 00:00:00 2001 From: Jim Broadus Date: Sat, 25 Jan 2020 13:13:57 -0800 Subject: [PATCH] Add a management class for creating Directory objects. Create a DirectorManager class that is owned by the Library or Device objects and provided to methods that need to create Directory objects. This will allow information to be provided through the Directory object. For example: - If the directory is on a removable device. - A mount point that may change on future uses. - Whether paths should be relative or absolute. --- src/core/metatypes.cpp | 1 + src/devices/connecteddevice.cpp | 11 ++++++----- src/devices/connecteddevice.h | 4 +++- src/library/directory.h | 11 +++++++++++ src/library/library.cpp | 5 +++-- src/library/library.h | 2 ++ src/library/librarybackend.cpp | 23 +++++++++++++---------- src/library/librarybackend.h | 15 ++++++++------- src/library/librarydirectorymodel.cpp | 8 +++++--- src/library/librarydirectorymodel.h | 2 ++ 10 files changed, 54 insertions(+), 28 deletions(-) diff --git a/src/core/metatypes.cpp b/src/core/metatypes.cpp index e8fc6efbe..6d000906d 100644 --- a/src/core/metatypes.cpp +++ b/src/core/metatypes.cpp @@ -72,6 +72,7 @@ void RegisterMetaTypes() { qRegisterMetaType("GstElement*"); qRegisterMetaType("GstEngine::OutputDetails"); qRegisterMetaType("GstEnginePipeline*"); + qRegisterMetaType("DirectoryManager*"); qRegisterMetaType("PlaylistItemList"); qRegisterMetaType("PlaylistItemPtr"); qRegisterMetaType("PodcastEpisodeList"); diff --git a/src/devices/connecteddevice.cpp b/src/devices/connecteddevice.cpp index 8ea584e1d..6dba78fcf 100644 --- a/src/devices/connecteddevice.cpp +++ b/src/devices/connecteddevice.cpp @@ -40,6 +40,7 @@ ConnectedDevice::ConnectedDevice(const QUrl& url, DeviceLister* lister, unique_id_(unique_id), database_id_(database_id), manager_(manager), + directory_manager_(new DirectoryManager), model_(nullptr), song_count_(0) { qLog(Info) << "connected" << url << unique_id << first_time; @@ -61,12 +62,12 @@ ConnectedDevice::ConnectedDevice(const QUrl& url, DeviceLister* lister, model_ = new LibraryModel(backend_, app_, this); } -ConnectedDevice::~ConnectedDevice() {} +ConnectedDevice::~ConnectedDevice() { delete directory_manager_; } void ConnectedDevice::InitBackendDirectory(const QString& mount_point, bool first_time, bool rewrite_path) { - if (first_time || backend_->GetAllDirectories().isEmpty()) { - backend_->AddDirectory(mount_point); + if (first_time || backend_->GetAllDirectories(directory_manager_).isEmpty()) { + backend_->AddDirectory(directory_manager_, mount_point); } else { if (rewrite_path) { // This is a bit of a hack. The device might not be mounted at the same @@ -76,7 +77,7 @@ void ConnectedDevice::InitBackendDirectory(const QString& mount_point, // Get the directory it was mounted at last time. Devices only have one // directory (the root). - Directory dir = backend_->GetAllDirectories()[0]; + Directory dir = backend_->GetAllDirectories(directory_manager_)[0]; if (dir.path != mount_point) { // The directory is different, commence the munging. qLog(Info) << "Changing path from" << dir.path << "to" << mount_point; @@ -85,7 +86,7 @@ void ConnectedDevice::InitBackendDirectory(const QString& mount_point, } // Load the directory properly now - backend_->LoadDirectoriesAsync(); + backend_->LoadDirectoriesAsync(directory_manager_); } } diff --git a/src/devices/connecteddevice.h b/src/devices/connecteddevice.h index d18f9c2cd..049c26457 100644 --- a/src/devices/connecteddevice.h +++ b/src/devices/connecteddevice.h @@ -30,6 +30,7 @@ class Application; class Database; class DeviceLister; class DeviceManager; +class DirectoryManager; class LibraryBackend; class LibraryModel; @@ -42,7 +43,7 @@ class ConnectedDevice : public QObject, ConnectedDevice(const QUrl& url, DeviceLister* lister, const QString& unique_id, DeviceManager* manager, Application* app, int database_id, bool first_time); - ~ConnectedDevice(); + virtual ~ConnectedDevice(); virtual void Init() = 0; virtual void ConnectAsync(); @@ -84,6 +85,7 @@ class ConnectedDevice : public QObject, DeviceManager* manager_; std::shared_ptr backend_; + DirectoryManager* directory_manager_; LibraryModel* model_; int song_count_; diff --git a/src/library/directory.h b/src/library/directory.h index cc28650d5..ddb220cb9 100644 --- a/src/library/directory.h +++ b/src/library/directory.h @@ -39,6 +39,17 @@ Q_DECLARE_METATYPE(Directory) typedef QList DirectoryList; Q_DECLARE_METATYPE(DirectoryList) +struct DirectoryManager { + DirectoryManager() {} + virtual ~DirectoryManager() {} + virtual Directory GetDirectory(const QString& path) const { + Directory dir; + dir.path = path; + return dir; + } +}; +Q_DECLARE_METATYPE(DirectoryManager) + struct Subdirectory { Subdirectory() : directory_id(-1), mtime(0) {} diff --git a/src/library/library.cpp b/src/library/library.cpp index da4a829fb..00750bcfd 100644 --- a/src/library/library.cpp +++ b/src/library/library.cpp @@ -39,6 +39,7 @@ Library::Library(Application* app, QObject* parent) : QObject(parent), app_(app), backend_(nullptr), + directory_manager_(new DirectoryManager), model_(nullptr), watcher_(nullptr), watcher_thread_(nullptr), @@ -57,7 +58,7 @@ Library::Library(Application* app, QObject* parent) using smart_playlists::SearchTerm; model_ = new LibraryModel(backend_, app_, this); - dir_model_ = new LibraryDirectoryModel(backend_, this); + dir_model_ = new LibraryDirectoryModel(backend_, directory_manager_, this); model_->set_show_smart_playlists(true); model_->set_default_smart_playlists( LibraryModel::DefaultGenerators() @@ -172,7 +173,7 @@ void Library::Init() { connect(app_->player(), SIGNAL(Stopped()), SLOT(Stopped())); // This will start the watcher checking for updates - backend_->LoadDirectoriesAsync(); + backend_->LoadDirectoriesAsync(directory_manager_.get()); } void Library::IncrementalScan() { watcher_->IncrementalScanAsync(); } diff --git a/src/library/library.h b/src/library/library.h index 90c55d735..27f127037 100644 --- a/src/library/library.h +++ b/src/library/library.h @@ -27,6 +27,7 @@ class Application; class Database; +class DirectoryManager; class LibraryBackend; class LibraryModel; class LibraryDirectoryModel; @@ -80,6 +81,7 @@ class Library : public QObject { private: Application* app_; std::shared_ptr backend_; + std::shared_ptr directory_manager_; LibraryModel* model_; LibraryDirectoryModel* dir_model_; diff --git a/src/library/librarybackend.cpp b/src/library/librarybackend.cpp index a40dca910..3a87f505a 100644 --- a/src/library/librarybackend.cpp +++ b/src/library/librarybackend.cpp @@ -63,8 +63,9 @@ void LibraryBackend::Init(Database* db, const QString& songs_table, subdirs_table_ = subdirs_table; } -void LibraryBackend::LoadDirectoriesAsync() { - metaObject()->invokeMethod(this, "LoadDirectories", Qt::QueuedConnection); +void LibraryBackend::LoadDirectoriesAsync(DirectoryManager* directory_manager) { + metaObject()->invokeMethod(this, "LoadDirectories", Qt::QueuedConnection, + Q_ARG(DirectoryManager*, directory_manager)); } void LibraryBackend::UpdateTotalSongCountAsync() { @@ -99,8 +100,8 @@ void LibraryBackend::UpdateSongsRatingAsync(const QList& ids, Q_ARG(float, rating)); } -void LibraryBackend::LoadDirectories() { - DirectoryList dirs = GetAllDirectories(); +void LibraryBackend::LoadDirectories(DirectoryManager* info) { + DirectoryList dirs = GetAllDirectories(info); QMutexLocker l(db_->Mutex()); QSqlDatabase db(db_->Connect()); @@ -155,7 +156,9 @@ void LibraryBackend::ChangeDirPath(int id, const QString& old_path, t.Commit(); } -DirectoryList LibraryBackend::GetAllDirectories() { +DirectoryList LibraryBackend::GetAllDirectories( + DirectoryManager* directory_manager) { + Q_ASSERT(directory_manager); QMutexLocker l(db_->Mutex()); QSqlDatabase db(db_->Connect()); @@ -167,9 +170,8 @@ DirectoryList LibraryBackend::GetAllDirectories() { if (db_->CheckErrors(q)) return ret; while (q.next()) { - Directory dir; + Directory dir = directory_manager->GetDirectory(q.value(1).toString()); dir.id = q.value(0).toInt(); - dir.path = q.value(1).toString(); ret << dir; } @@ -217,7 +219,9 @@ void LibraryBackend::UpdateTotalSongCount() { emit TotalSongCountUpdated(q.value(0).toInt()); } -void LibraryBackend::AddDirectory(const QString& path) { +void LibraryBackend::AddDirectory(DirectoryManager* directory_manager, + const QString& path) { + Q_ASSERT(directory_manager); QString canonical_path = QFileInfo(path).canonicalFilePath(); QString db_path = canonical_path; @@ -238,8 +242,7 @@ void LibraryBackend::AddDirectory(const QString& path) { q.exec(); if (db_->CheckErrors(q)) return; - Directory dir; - dir.path = canonical_path; + Directory dir = directory_manager->GetDirectory(canonical_path); dir.id = q.lastInsertId().toInt(); emit DirectoryDiscovered(dir, SubdirectoryList()); diff --git a/src/library/librarybackend.h b/src/library/librarybackend.h index 1f965eafe..7a9088830 100644 --- a/src/library/librarybackend.h +++ b/src/library/librarybackend.h @@ -69,14 +69,14 @@ class LibraryBackendInterface : public QObject { virtual QString songs_table() const = 0; // Get a list of directories in the library. Emits DirectoriesDiscovered. - virtual void LoadDirectoriesAsync() = 0; + virtual void LoadDirectoriesAsync(DirectoryManager* directory_manager) = 0; // Counts the songs in the library. Emits TotalSongCountUpdated virtual void UpdateTotalSongCountAsync() = 0; virtual SongList FindSongsInDirectory(int id) = 0; virtual SubdirectoryList SubdirsInDirectory(int id) = 0; - virtual DirectoryList GetAllDirectories() = 0; + virtual DirectoryList GetAllDirectories(DirectoryManager* info) = 0; virtual void ChangeDirPath(int id, const QString& old_path, const QString& new_path) = 0; @@ -118,7 +118,8 @@ class LibraryBackendInterface : public QObject { // songs. virtual Song GetSongByUrl(const QUrl& url, qint64 beginning = 0) = 0; - virtual void AddDirectory(const QString& path) = 0; + virtual void AddDirectory(DirectoryManager* directory_manager, + const QString& path) = 0; virtual void RemoveDirectory(int dir_id) = 0; virtual bool ExecQuery(LibraryQuery* q) = 0; @@ -142,14 +143,14 @@ class LibraryBackend : public LibraryBackendInterface { QString subdirs_table() const { return subdirs_table_; } // Get a list of directories in the library. Emits DirectoriesDiscovered. - void LoadDirectoriesAsync(); + void LoadDirectoriesAsync(DirectoryManager* directory_manager); // Counts the songs in the library. Emits TotalSongCountUpdated void UpdateTotalSongCountAsync(); SongList FindSongsInDirectory(int id); SubdirectoryList SubdirsInDirectory(int id); - DirectoryList GetAllDirectories(); + DirectoryList GetAllDirectories(DirectoryManager* directory_manager); void ChangeDirPath(int id, const QString& old_path, const QString& new_path); QStringList GetAll(const QString& column, @@ -186,7 +187,7 @@ class LibraryBackend : public LibraryBackendInterface { SongList GetSongsByUrl(const QUrl& url); Song GetSongByUrl(const QUrl& url, qint64 beginning = 0); - void AddDirectory(const QString& path); + void AddDirectory(DirectoryManager* directory_manager, const QString& path); void RemoveDirectory(int dir_id); bool ExecQuery(LibraryQuery* q); @@ -203,7 +204,7 @@ class LibraryBackend : public LibraryBackendInterface { void DeleteAll(); public slots: - void LoadDirectories(); + void LoadDirectories(DirectoryManager* directory_manager); void UpdateTotalSongCount(); void AddOrUpdateSongs(const SongList& songs); void UpdateMTimesOnly(const SongList& songs); diff --git a/src/library/librarydirectorymodel.cpp b/src/library/librarydirectorymodel.cpp index 4bba7339f..6e8a4430a 100644 --- a/src/library/librarydirectorymodel.cpp +++ b/src/library/librarydirectorymodel.cpp @@ -25,10 +25,12 @@ #include "ui/iconloader.h" LibraryDirectoryModel::LibraryDirectoryModel( - std::shared_ptr backend, QObject* parent) + std::shared_ptr backend, + std::shared_ptr directory_manager, QObject* parent) : QStandardItemModel(parent), dir_icon_(IconLoader::Load("document-open-folder", IconLoader::Base)), - backend_(backend) { + backend_(backend), + directory_manager_(directory_manager) { connect(backend_.get(), SIGNAL(DirectoryDiscovered(Directory, SubdirectoryList)), SLOT(DirectoryDiscovered(Directory))); @@ -67,7 +69,7 @@ void LibraryDirectoryModel::DirectoryDeleted(int dir_id) { void LibraryDirectoryModel::AddDirectory(const QString& path) { if (!backend_) return; - backend_->AddDirectory(path); + backend_->AddDirectory(directory_manager_.get(), path); } void LibraryDirectoryModel::RemoveDirectory(const QModelIndex& index) { diff --git a/src/library/librarydirectorymodel.h b/src/library/librarydirectorymodel.h index 85d6ac7be..ad416149c 100644 --- a/src/library/librarydirectorymodel.h +++ b/src/library/librarydirectorymodel.h @@ -32,6 +32,7 @@ class LibraryDirectoryModel : public QStandardItemModel { public: LibraryDirectoryModel(std::shared_ptr backend, + std::shared_ptr directory_manager, QObject* parent = nullptr); ~LibraryDirectoryModel(); @@ -51,6 +52,7 @@ class LibraryDirectoryModel : public QStandardItemModel { QIcon dir_icon_; std::shared_ptr backend_; + std::shared_ptr directory_manager_; QList> storage_; };