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.
This commit is contained in:
Jim Broadus 2020-01-25 13:13:57 -08:00
parent fdb3f7ac37
commit 03dae637f0
10 changed files with 54 additions and 28 deletions

View File

@ -72,6 +72,7 @@ void RegisterMetaTypes() {
qRegisterMetaType<GstElement*>("GstElement*");
qRegisterMetaType<GstEngine::OutputDetails>("GstEngine::OutputDetails");
qRegisterMetaType<GstEnginePipeline*>("GstEnginePipeline*");
qRegisterMetaType<DirectoryManager*>("DirectoryManager*");
qRegisterMetaType<PlaylistItemList>("PlaylistItemList");
qRegisterMetaType<PlaylistItemPtr>("PlaylistItemPtr");
qRegisterMetaType<PodcastEpisodeList>("PodcastEpisodeList");

View File

@ -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_);
}
}

View File

@ -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<LibraryBackend> backend_;
DirectoryManager* directory_manager_;
LibraryModel* model_;
int song_count_;

View File

@ -39,6 +39,17 @@ Q_DECLARE_METATYPE(Directory)
typedef QList<Directory> 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) {}

View File

@ -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(); }

View File

@ -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<LibraryBackend> backend_;
std::shared_ptr<DirectoryManager> directory_manager_;
LibraryModel* model_;
LibraryDirectoryModel* dir_model_;

View File

@ -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<int>& 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());

View File

@ -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);

View File

@ -25,10 +25,12 @@
#include "ui/iconloader.h"
LibraryDirectoryModel::LibraryDirectoryModel(
std::shared_ptr<LibraryBackend> backend, QObject* parent)
std::shared_ptr<LibraryBackend> backend,
std::shared_ptr<DirectoryManager> 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) {

View File

@ -32,6 +32,7 @@ class LibraryDirectoryModel : public QStandardItemModel {
public:
LibraryDirectoryModel(std::shared_ptr<LibraryBackend> backend,
std::shared_ptr<DirectoryManager> directory_manager,
QObject* parent = nullptr);
~LibraryDirectoryModel();
@ -51,6 +52,7 @@ class LibraryDirectoryModel : public QStandardItemModel {
QIcon dir_icon_;
std::shared_ptr<LibraryBackend> backend_;
std::shared_ptr<DirectoryManager> directory_manager_;
QList<std::shared_ptr<MusicStorage>> storage_;
};