mirror of
https://github.com/clementine-player/Clementine
synced 2025-01-30 19:15:08 +01:00
Add a MusicStorage interface that can be used to abstract away the details of copying a file to a device.
This commit is contained in:
parent
d108841e36
commit
62616304d8
@ -35,11 +35,13 @@ set(SOURCES
|
|||||||
core/backgroundthread.cpp
|
core/backgroundthread.cpp
|
||||||
core/commandlineoptions.cpp
|
core/commandlineoptions.cpp
|
||||||
core/database.cpp
|
core/database.cpp
|
||||||
|
core/filesystemmusicstorage.cpp
|
||||||
core/fht.cpp
|
core/fht.cpp
|
||||||
core/globalshortcutbackend.cpp
|
core/globalshortcutbackend.cpp
|
||||||
core/globalshortcuts.cpp
|
core/globalshortcuts.cpp
|
||||||
core/gnomeglobalshortcutbackend.cpp
|
core/gnomeglobalshortcutbackend.cpp
|
||||||
core/mergedproxymodel.cpp
|
core/mergedproxymodel.cpp
|
||||||
|
core/musicstorage.cpp
|
||||||
core/networkaccessmanager.cpp
|
core/networkaccessmanager.cpp
|
||||||
core/organise.cpp
|
core/organise.cpp
|
||||||
core/organiseformat.cpp
|
core/organiseformat.cpp
|
||||||
|
49
src/core/filesystemmusicstorage.cpp
Normal file
49
src/core/filesystemmusicstorage.cpp
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/* This file is part of Clementine.
|
||||||
|
|
||||||
|
Clementine 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.
|
||||||
|
|
||||||
|
Clementine 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 Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "filesystemmusicstorage.h"
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
|
#include <QFile>
|
||||||
|
|
||||||
|
FilesystemMusicStorage::FilesystemMusicStorage(const QString& root)
|
||||||
|
: root_(root)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FilesystemMusicStorage::CopyToStorage(
|
||||||
|
const QString& source, const QString& destination,
|
||||||
|
const Song&, bool overwrite, bool remove_original) {
|
||||||
|
const QString dest_filename = root_ + "/" + destination;
|
||||||
|
|
||||||
|
// Don't do anything if the destination is the same as the source
|
||||||
|
if (source == dest_filename)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Create directories as required
|
||||||
|
QDir dir;
|
||||||
|
dir.mkpath(dest_filename.section('/', 0, -2));
|
||||||
|
|
||||||
|
// Remove the destination file if it exists and we want to overwrite
|
||||||
|
if (overwrite && QFile::exists(dest_filename))
|
||||||
|
QFile::remove(dest_filename);
|
||||||
|
|
||||||
|
// Copy or move
|
||||||
|
if (remove_original)
|
||||||
|
return QFile::rename(source, dest_filename);
|
||||||
|
else
|
||||||
|
return QFile::copy(source, dest_filename);
|
||||||
|
}
|
35
src/core/filesystemmusicstorage.h
Normal file
35
src/core/filesystemmusicstorage.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/* This file is part of Clementine.
|
||||||
|
|
||||||
|
Clementine 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.
|
||||||
|
|
||||||
|
Clementine 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 Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FILESYSTEMMUSICSTORAGE_H
|
||||||
|
#define FILESYSTEMMUSICSTORAGE_H
|
||||||
|
|
||||||
|
#include "musicstorage.h"
|
||||||
|
|
||||||
|
class FilesystemMusicStorage : public MusicStorage {
|
||||||
|
public:
|
||||||
|
FilesystemMusicStorage(const QString& root);
|
||||||
|
|
||||||
|
QString LocalPath() const { return root_; }
|
||||||
|
|
||||||
|
bool CopyToStorage(const QString &source, const QString &destination,
|
||||||
|
const Song &metadata, bool overwrite, bool remove_original);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString root_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FILESYSTEMMUSICSTORAGE_H
|
21
src/core/musicstorage.cpp
Normal file
21
src/core/musicstorage.cpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/* This file is part of Clementine.
|
||||||
|
|
||||||
|
Clementine 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.
|
||||||
|
|
||||||
|
Clementine 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 Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "musicstorage.h"
|
||||||
|
|
||||||
|
MusicStorage::MusicStorage()
|
||||||
|
{
|
||||||
|
}
|
40
src/core/musicstorage.h
Normal file
40
src/core/musicstorage.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/* This file is part of Clementine.
|
||||||
|
|
||||||
|
Clementine 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.
|
||||||
|
|
||||||
|
Clementine 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 Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MUSICSTORAGE_H
|
||||||
|
#define MUSICSTORAGE_H
|
||||||
|
|
||||||
|
#include "song.h"
|
||||||
|
|
||||||
|
#include <QMetaType>
|
||||||
|
|
||||||
|
class MusicStorage {
|
||||||
|
public:
|
||||||
|
MusicStorage();
|
||||||
|
virtual ~MusicStorage() {}
|
||||||
|
|
||||||
|
static const int kStorageRole = Qt::UserRole + 100;
|
||||||
|
|
||||||
|
virtual QString LocalPath() const { return QString(); }
|
||||||
|
|
||||||
|
virtual bool CopyToStorage(const QString& source, const QString& destination,
|
||||||
|
const Song& metadata, bool overwrite,
|
||||||
|
bool remove_original) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(MusicStorage*);
|
||||||
|
|
||||||
|
#endif // MUSICSTORAGE_H
|
@ -14,6 +14,7 @@
|
|||||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "musicstorage.h"
|
||||||
#include "organise.h"
|
#include "organise.h"
|
||||||
#include "taskmanager.h"
|
#include "taskmanager.h"
|
||||||
|
|
||||||
@ -24,7 +25,7 @@
|
|||||||
|
|
||||||
const int Organise::kBatchSize = 10;
|
const int Organise::kBatchSize = 10;
|
||||||
|
|
||||||
Organise::Organise(TaskManager* task_manager, const QString &destination,
|
Organise::Organise(TaskManager* task_manager, MusicStorage* destination,
|
||||||
const OrganiseFormat &format, bool copy, bool overwrite,
|
const OrganiseFormat &format, bool copy, bool overwrite,
|
||||||
const QStringList& files)
|
const QStringList& files)
|
||||||
: thread_(NULL),
|
: thread_(NULL),
|
||||||
@ -95,25 +96,8 @@ void Organise::ProcessSomeFiles() {
|
|||||||
if (!song.is_valid())
|
if (!song.is_valid())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Get the destination filename
|
destination_->CopyToStorage(filename, format_.GetFilenameForSong(song),
|
||||||
QString dest_filename = destination_ + "/" + format_.GetFilenameForSong(song);
|
song, overwrite_, !copy_);
|
||||||
|
|
||||||
// Don't do anything if the destination is the same as the source
|
|
||||||
if (filename == dest_filename)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Create directories as required
|
|
||||||
dir.mkpath(dest_filename.section('/', 0, -2));
|
|
||||||
|
|
||||||
// Remove the destination file if it exists and we want to overwrite
|
|
||||||
if (overwrite_ && QFile::exists(dest_filename))
|
|
||||||
QFile::remove(dest_filename);
|
|
||||||
|
|
||||||
// Copy or move
|
|
||||||
if (copy_)
|
|
||||||
QFile::copy(filename, dest_filename);
|
|
||||||
else
|
|
||||||
QFile::rename(filename, dest_filename);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QTimer::singleShot(0, this, SLOT(ProcessSomeFiles()));
|
QTimer::singleShot(0, this, SLOT(ProcessSomeFiles()));
|
||||||
|
@ -21,13 +21,14 @@
|
|||||||
|
|
||||||
#include "organiseformat.h"
|
#include "organiseformat.h"
|
||||||
|
|
||||||
|
class MusicStorage;
|
||||||
class TaskManager;
|
class TaskManager;
|
||||||
|
|
||||||
class Organise : public QObject {
|
class Organise : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Organise(TaskManager* task_manager, const QString& destination,
|
Organise(TaskManager* task_manager, MusicStorage* destination,
|
||||||
const OrganiseFormat& format, bool copy, bool overwrite,
|
const OrganiseFormat& format, bool copy, bool overwrite,
|
||||||
const QStringList& files);
|
const QStringList& files);
|
||||||
|
|
||||||
@ -42,8 +43,8 @@ private:
|
|||||||
QThread* thread_;
|
QThread* thread_;
|
||||||
QThread* original_thread_;
|
QThread* original_thread_;
|
||||||
TaskManager* task_manager_;
|
TaskManager* task_manager_;
|
||||||
|
MusicStorage* destination_;
|
||||||
|
|
||||||
const QString destination_;
|
|
||||||
const OrganiseFormat format_;
|
const OrganiseFormat format_;
|
||||||
const bool copy_;
|
const bool copy_;
|
||||||
const bool overwrite_;
|
const bool overwrite_;
|
||||||
|
@ -26,6 +26,7 @@ class DeviceLister;
|
|||||||
class DeviceManager;
|
class DeviceManager;
|
||||||
class LibraryBackend;
|
class LibraryBackend;
|
||||||
class LibraryModel;
|
class LibraryModel;
|
||||||
|
class MusicStorage;
|
||||||
|
|
||||||
class ConnectedDevice : public QObject {
|
class ConnectedDevice : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -40,6 +41,8 @@ public:
|
|||||||
QString unique_id() const { return unique_id_; }
|
QString unique_id() const { return unique_id_; }
|
||||||
LibraryModel* model() const { return model_; }
|
LibraryModel* model() const { return model_; }
|
||||||
|
|
||||||
|
virtual MusicStorage* storage() = 0;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void TaskStarted(int id);
|
void TaskStarted(int id);
|
||||||
void Error(const QString& message);
|
void Error(const QString& message);
|
||||||
|
@ -27,11 +27,25 @@
|
|||||||
|
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
|
||||||
const int DeviceManager::kDeviceIconSize = 32;
|
const int DeviceManager::kDeviceIconSize = 32;
|
||||||
const int DeviceManager::kDeviceIconOverlaySize = 16;
|
const int DeviceManager::kDeviceIconOverlaySize = 16;
|
||||||
|
|
||||||
|
DeviceStateFilterModel::DeviceStateFilterModel(QObject *parent,
|
||||||
|
DeviceManager::State state)
|
||||||
|
: QSortFilterProxyModel(parent),
|
||||||
|
state_(state)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeviceStateFilterModel::filterAcceptsRow(int row, const QModelIndex&) const {
|
||||||
|
return sourceModel()->index(row, 0).data(DeviceManager::Role_State).toInt()
|
||||||
|
== state_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DeviceManager::DeviceInfo::DeviceInfo()
|
DeviceManager::DeviceInfo::DeviceInfo()
|
||||||
: database_id_(-1),
|
: database_id_(-1),
|
||||||
task_percentage_(-1)
|
task_percentage_(-1)
|
||||||
@ -132,6 +146,10 @@ DeviceManager::DeviceManager(BackgroundThread<Database>* database,
|
|||||||
devices_ << info;
|
devices_ << info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This proxy model only shows connected devices
|
||||||
|
connected_devices_model_ = new DeviceStateFilterModel(this);
|
||||||
|
connected_devices_model_->setSourceModel(this);
|
||||||
|
|
||||||
#ifdef Q_WS_X11
|
#ifdef Q_WS_X11
|
||||||
AddLister(new DeviceKitLister);
|
AddLister(new DeviceKitLister);
|
||||||
#endif
|
#endif
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include <QAbstractListModel>
|
#include <QAbstractListModel>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
@ -47,6 +48,8 @@ public:
|
|||||||
Role_FreeSpace,
|
Role_FreeSpace,
|
||||||
Role_IconName,
|
Role_IconName,
|
||||||
Role_UpdatingPercentage,
|
Role_UpdatingPercentage,
|
||||||
|
|
||||||
|
LastRole,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum State {
|
enum State {
|
||||||
@ -61,6 +64,8 @@ public:
|
|||||||
BackgroundThread<Database>* database() const { return database_; }
|
BackgroundThread<Database>* database() const { return database_; }
|
||||||
TaskManager* task_manager() const { return task_manager_; }
|
TaskManager* task_manager() const { return task_manager_; }
|
||||||
|
|
||||||
|
QAbstractItemModel* connected_devices_model() const { return connected_devices_model_; }
|
||||||
|
|
||||||
// Get info about devices
|
// Get info about devices
|
||||||
int GetDatabaseId(int row) const;
|
int GetDatabaseId(int row) const;
|
||||||
DeviceLister* GetLister(int row) const;
|
DeviceLister* GetLister(int row) const;
|
||||||
@ -150,6 +155,8 @@ private:
|
|||||||
DeviceDatabaseBackend* backend_;
|
DeviceDatabaseBackend* backend_;
|
||||||
TaskManager* task_manager_;
|
TaskManager* task_manager_;
|
||||||
|
|
||||||
|
QSortFilterProxyModel* connected_devices_model_;
|
||||||
|
|
||||||
QIcon not_connected_overlay_;
|
QIcon not_connected_overlay_;
|
||||||
|
|
||||||
QList<DeviceLister*> listers_;
|
QList<DeviceLister*> listers_;
|
||||||
@ -161,6 +168,20 @@ private:
|
|||||||
QMap<int, QPersistentModelIndex> active_tasks_;
|
QMap<int, QPersistentModelIndex> active_tasks_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class DeviceStateFilterModel : public QSortFilterProxyModel {
|
||||||
|
public:
|
||||||
|
DeviceStateFilterModel(QObject* parent, DeviceManager::State state =
|
||||||
|
DeviceManager::State_Connected);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool filterAcceptsRow(int row, const QModelIndex& parent) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
DeviceManager::State state_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void DeviceManager::AddDeviceClass() {
|
void DeviceManager::AddDeviceClass() {
|
||||||
QStringList schemes = T::url_schemes();
|
QStringList schemes = T::url_schemes();
|
||||||
|
@ -177,7 +177,7 @@ void DeviceView::SetLibrary(LibraryModel* library) {
|
|||||||
library_ = library;
|
library_ = library;
|
||||||
|
|
||||||
organise_dialog_.reset(new OrganiseDialog(manager_->task_manager()));
|
organise_dialog_.reset(new OrganiseDialog(manager_->task_manager()));
|
||||||
organise_dialog_->AddDirectoryModel(library_->directory_model());
|
organise_dialog_->SetDestinationModel(library_->directory_model());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceView::contextMenuEvent(QContextMenuEvent* e) {
|
void DeviceView::contextMenuEvent(QContextMenuEvent* e) {
|
||||||
|
@ -28,6 +28,7 @@ FilesystemDevice::FilesystemDevice(
|
|||||||
const QString& unique_id, DeviceManager* manager,
|
const QString& unique_id, DeviceManager* manager,
|
||||||
int database_id, bool first_time)
|
int database_id, bool first_time)
|
||||||
: ConnectedDevice(url, lister, unique_id, manager, database_id, first_time),
|
: ConnectedDevice(url, lister, unique_id, manager, database_id, first_time),
|
||||||
|
FilesystemMusicStorage(url.toLocalFile()),
|
||||||
watcher_(new BackgroundThreadImplementation<LibraryWatcher, LibraryWatcher>(this))
|
watcher_(new BackgroundThreadImplementation<LibraryWatcher, LibraryWatcher>(this))
|
||||||
{
|
{
|
||||||
// Create the library watcher
|
// Create the library watcher
|
||||||
|
@ -19,11 +19,12 @@
|
|||||||
|
|
||||||
#include "connecteddevice.h"
|
#include "connecteddevice.h"
|
||||||
#include "core/backgroundthread.h"
|
#include "core/backgroundthread.h"
|
||||||
|
#include "core/filesystemmusicstorage.h"
|
||||||
|
|
||||||
class DeviceManager;
|
class DeviceManager;
|
||||||
class LibraryWatcher;
|
class LibraryWatcher;
|
||||||
|
|
||||||
class FilesystemDevice : public ConnectedDevice {
|
class FilesystemDevice : public ConnectedDevice, public FilesystemMusicStorage {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -35,6 +36,8 @@ public:
|
|||||||
|
|
||||||
static QStringList url_schemes() { return QStringList() << "file"; }
|
static QStringList url_schemes() { return QStringList() << "file"; }
|
||||||
|
|
||||||
|
MusicStorage* storage() { return this; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BackgroundThread<LibraryWatcher>* watcher_;
|
BackgroundThread<LibraryWatcher>* watcher_;
|
||||||
};
|
};
|
||||||
|
@ -47,3 +47,10 @@ GPodDevice::~GPodDevice() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GPodDevice::CopyToStorage(
|
||||||
|
const QString &source, const QString &destination,
|
||||||
|
const Song &metadata, bool overwrite, bool remove_original)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -18,10 +18,11 @@
|
|||||||
#define GPODDEVICE_H
|
#define GPODDEVICE_H
|
||||||
|
|
||||||
#include "connecteddevice.h"
|
#include "connecteddevice.h"
|
||||||
|
#include "core/musicstorage.h"
|
||||||
|
|
||||||
class GPodLoader;
|
class GPodLoader;
|
||||||
|
|
||||||
class GPodDevice : public ConnectedDevice {
|
class GPodDevice : public ConnectedDevice, public MusicStorage {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -33,6 +34,11 @@ public:
|
|||||||
|
|
||||||
static QStringList url_schemes() { return QStringList() << "ipod"; }
|
static QStringList url_schemes() { return QStringList() << "ipod"; }
|
||||||
|
|
||||||
|
MusicStorage* storage() { return this; }
|
||||||
|
|
||||||
|
bool CopyToStorage(const QString &source, const QString &destination,
|
||||||
|
const Song &metadata, bool overwrite, bool remove_original);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QThread* loader_thread_;
|
QThread* loader_thread_;
|
||||||
GPodLoader* loader_;
|
GPodLoader* loader_;
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
#include "librarydirectorymodel.h"
|
#include "librarydirectorymodel.h"
|
||||||
#include "librarybackend.h"
|
#include "librarybackend.h"
|
||||||
|
#include "core/filesystemmusicstorage.h"
|
||||||
|
#include "core/musicstorage.h"
|
||||||
#include "ui/iconloader.h"
|
#include "ui/iconloader.h"
|
||||||
|
|
||||||
LibraryDirectoryModel::LibraryDirectoryModel(LibraryBackend* backend, QObject* parent)
|
LibraryDirectoryModel::LibraryDirectoryModel(LibraryBackend* backend, QObject* parent)
|
||||||
@ -27,10 +29,15 @@ LibraryDirectoryModel::LibraryDirectoryModel(LibraryBackend* backend, QObject* p
|
|||||||
connect(backend_, SIGNAL(DirectoryDeleted(Directory)), SLOT(DirectoryDeleted(Directory)));
|
connect(backend_, SIGNAL(DirectoryDeleted(Directory)), SLOT(DirectoryDeleted(Directory)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LibraryDirectoryModel::~LibraryDirectoryModel() {
|
||||||
|
qDeleteAll(storage_);
|
||||||
|
}
|
||||||
|
|
||||||
void LibraryDirectoryModel::DirectoryDiscovered(const Directory &dir) {
|
void LibraryDirectoryModel::DirectoryDiscovered(const Directory &dir) {
|
||||||
QStandardItem* item = new QStandardItem(dir.path);
|
QStandardItem* item = new QStandardItem(dir.path);
|
||||||
item->setData(dir.id, kIdRole);
|
item->setData(dir.id, kIdRole);
|
||||||
item->setIcon(dir_icon_);
|
item->setIcon(dir_icon_);
|
||||||
|
storage_ << new FilesystemMusicStorage(dir.path);
|
||||||
appendRow(item);
|
appendRow(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,6 +45,7 @@ void LibraryDirectoryModel::DirectoryDeleted(const Directory &dir) {
|
|||||||
for (int i=0 ; i<rowCount() ; ++i) {
|
for (int i=0 ; i<rowCount() ; ++i) {
|
||||||
if (item(i, 0)->data(kIdRole).toInt() == dir.id) {
|
if (item(i, 0)->data(kIdRole).toInt() == dir.id) {
|
||||||
removeRow(i);
|
removeRow(i);
|
||||||
|
delete storage_.takeAt(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,3 +68,11 @@ void LibraryDirectoryModel::RemoveDirectory(const QModelIndex& index) {
|
|||||||
|
|
||||||
backend_->RemoveDirectory(dir);
|
backend_->RemoveDirectory(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVariant LibraryDirectoryModel::data(const QModelIndex &index, int role) const {
|
||||||
|
if (role == MusicStorage::kStorageRole) {
|
||||||
|
return QVariant::fromValue(storage_[index.row()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return QStandardItemModel::data(index, role);
|
||||||
|
}
|
||||||
|
@ -23,17 +23,21 @@
|
|||||||
#include "directory.h"
|
#include "directory.h"
|
||||||
|
|
||||||
class LibraryBackend;
|
class LibraryBackend;
|
||||||
|
class MusicStorage;
|
||||||
|
|
||||||
class LibraryDirectoryModel : public QStandardItemModel {
|
class LibraryDirectoryModel : public QStandardItemModel {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LibraryDirectoryModel(LibraryBackend* backend, QObject* parent = 0);
|
LibraryDirectoryModel(LibraryBackend* backend, QObject* parent = 0);
|
||||||
|
~LibraryDirectoryModel();
|
||||||
|
|
||||||
// To be called by GUIs
|
// To be called by GUIs
|
||||||
void AddDirectory(const QString& path);
|
void AddDirectory(const QString& path);
|
||||||
void RemoveDirectory(const QModelIndex& index);
|
void RemoveDirectory(const QModelIndex& index);
|
||||||
|
|
||||||
|
QVariant data(const QModelIndex &index, int role) const;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
// To be called by the backend
|
// To be called by the backend
|
||||||
void DirectoryDiscovered(const Directory& directories);
|
void DirectoryDiscovered(const Directory& directories);
|
||||||
@ -44,6 +48,7 @@ class LibraryDirectoryModel : public QStandardItemModel {
|
|||||||
|
|
||||||
QIcon dir_icon_;
|
QIcon dir_icon_;
|
||||||
LibraryBackend* backend_;
|
LibraryBackend* backend_;
|
||||||
|
QList<MusicStorage*> storage_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LIBRARYDIRECTORYMODEL_H
|
#endif // LIBRARYDIRECTORYMODEL_H
|
||||||
|
@ -41,7 +41,7 @@ class LibraryModel : public SimpleTreeModel<LibraryItem> {
|
|||||||
LibraryModel(LibraryBackend* backend, QObject* parent = 0);
|
LibraryModel(LibraryBackend* backend, QObject* parent = 0);
|
||||||
~LibraryModel();
|
~LibraryModel();
|
||||||
|
|
||||||
enum {
|
enum Role {
|
||||||
Role_Type = Qt::UserRole + 1,
|
Role_Type = Qt::UserRole + 1,
|
||||||
Role_ContainerType,
|
Role_ContainerType,
|
||||||
Role_SortText,
|
Role_SortText,
|
||||||
|
@ -118,7 +118,7 @@ void LibraryView::ReloadSettings() {
|
|||||||
|
|
||||||
void LibraryView::SetTaskManager(TaskManager *task_manager) {
|
void LibraryView::SetTaskManager(TaskManager *task_manager) {
|
||||||
organise_dialog_.reset(new OrganiseDialog(task_manager));
|
organise_dialog_.reset(new OrganiseDialog(task_manager));
|
||||||
organise_dialog_->AddDirectoryModel(library_->directory_model());
|
organise_dialog_->SetDestinationModel(library_->directory_model());
|
||||||
}
|
}
|
||||||
|
|
||||||
void LibraryView::SetLibrary(LibraryModel *library) {
|
void LibraryView::SetLibrary(LibraryModel *library) {
|
||||||
|
@ -203,7 +203,7 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
|
|||||||
ui_->devices_view->SetDeviceManager(devices_);
|
ui_->devices_view->SetDeviceManager(devices_);
|
||||||
ui_->devices_view->SetLibrary(library_->model());
|
ui_->devices_view->SetLibrary(library_->model());
|
||||||
|
|
||||||
organise_dialog_->AddDirectoryModel(library_->model()->directory_model());
|
organise_dialog_->SetDestinationModel(library_->model()->directory_model());
|
||||||
|
|
||||||
cover_manager_->Init();
|
cover_manager_->Init();
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "organisedialog.h"
|
#include "organisedialog.h"
|
||||||
#include "ui_organisedialog.h"
|
#include "ui_organisedialog.h"
|
||||||
|
#include "core/musicstorage.h"
|
||||||
#include "core/organise.h"
|
#include "core/organise.h"
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
@ -87,9 +88,7 @@ OrganiseDialog::~OrganiseDialog() {
|
|||||||
delete ui_;
|
delete ui_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OrganiseDialog::AddDirectoryModel(QAbstractItemModel *model) {
|
void OrganiseDialog::SetDestinationModel(QAbstractItemModel *model) {
|
||||||
// TODO: Add this model to a proxy model that merges different models
|
|
||||||
// together, eg. from the local library and also removable devices.
|
|
||||||
ui_->destination->setModel(model);
|
ui_->destination->setModel(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,6 +147,15 @@ void OrganiseDialog::InsertTag(const QString &tag) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OrganiseDialog::UpdatePreviews() {
|
void OrganiseDialog::UpdatePreviews() {
|
||||||
|
const QModelIndex destination = ui_->destination->model()->index(
|
||||||
|
ui_->destination->currentIndex(), 0);
|
||||||
|
if (!destination.isValid())
|
||||||
|
return;
|
||||||
|
const MusicStorage* storage =
|
||||||
|
destination.data(MusicStorage::kStorageRole).value<MusicStorage*>();
|
||||||
|
|
||||||
|
const bool has_local_destination = !storage->LocalPath().isEmpty();
|
||||||
|
|
||||||
// Update the format object
|
// Update the format object
|
||||||
format_.set_format(ui_->naming->toPlainText());
|
format_.set_format(ui_->naming->toPlainText());
|
||||||
format_.set_replace_non_ascii(ui_->replace_ascii->isChecked());
|
format_.set_replace_non_ascii(ui_->replace_ascii->isChecked());
|
||||||
@ -155,16 +163,19 @@ void OrganiseDialog::UpdatePreviews() {
|
|||||||
format_.set_replace_the(ui_->replace_the->isChecked());
|
format_.set_replace_the(ui_->replace_the->isChecked());
|
||||||
|
|
||||||
const bool format_valid = format_.IsValid();
|
const bool format_valid = format_.IsValid();
|
||||||
ui_->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(
|
ui_->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(format_valid);
|
||||||
format_valid && !ui_->destination->currentText().isEmpty());
|
|
||||||
if (!format_valid)
|
if (!format_valid)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Update the previews
|
||||||
ui_->preview->clear();
|
ui_->preview->clear();
|
||||||
foreach (const Song& song, preview_songs_) {
|
ui_->preview->setVisible(has_local_destination);
|
||||||
QString filename = ui_->destination->currentText() + "/" +
|
if (has_local_destination) {
|
||||||
format_.GetFilenameForSong(song);
|
foreach (const Song& song, preview_songs_) {
|
||||||
ui_->preview->addItem(QDir::toNativeSeparators(filename));
|
QString filename = storage->LocalPath() + "/" +
|
||||||
|
format_.GetFilenameForSong(song);
|
||||||
|
ui_->preview->addItem(QDir::toNativeSeparators(filename));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,9 +213,14 @@ void OrganiseDialog::accept() {
|
|||||||
s.setValue("overwrite", ui_->overwrite->isChecked());
|
s.setValue("overwrite", ui_->overwrite->isChecked());
|
||||||
s.setValue("destination", ui_->destination->currentText());
|
s.setValue("destination", ui_->destination->currentText());
|
||||||
|
|
||||||
|
const QModelIndex destination = ui_->destination->model()->index(
|
||||||
|
ui_->destination->currentIndex(), 0);
|
||||||
|
MusicStorage* storage =
|
||||||
|
destination.data(MusicStorage::kStorageRole).value<MusicStorage*>();
|
||||||
|
|
||||||
// It deletes itself when it's finished.
|
// It deletes itself when it's finished.
|
||||||
Organise* organise = new Organise(
|
Organise* organise = new Organise(
|
||||||
task_manager_, ui_->destination->currentText(), format_,
|
task_manager_, storage, format_,
|
||||||
!ui_->move->isChecked(), ui_->overwrite->isChecked(), filenames_);
|
!ui_->move->isChecked(), ui_->overwrite->isChecked(), filenames_);
|
||||||
organise->Start();
|
organise->Start();
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ public:
|
|||||||
static const char* kDefaultFormat;
|
static const char* kDefaultFormat;
|
||||||
static const char* kSettingsGroup;
|
static const char* kSettingsGroup;
|
||||||
|
|
||||||
void AddDirectoryModel(QAbstractItemModel* model);
|
void SetDestinationModel(QAbstractItemModel* model);
|
||||||
|
|
||||||
void SetUrls(const QList<QUrl>& urls);
|
void SetUrls(const QList<QUrl>& urls);
|
||||||
void SetFilenames(const QStringList& filenames);
|
void SetFilenames(const QStringList& filenames);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user