diff --git a/src/device/connecteddevice.cpp b/src/device/connecteddevice.cpp index e4963feab..0e9756929 100644 --- a/src/device/connecteddevice.cpp +++ b/src/device/connecteddevice.cpp @@ -99,6 +99,8 @@ void ConnectedDevice::InitBackendDirectory(const QString &mount_point, bool firs } +void ConnectedDevice::ConnectAsync() { emit ConnectFinished(unique_id_, true); } + void ConnectedDevice::Eject() { DeviceInfo *info = manager_->FindDeviceById(unique_id_); diff --git a/src/device/connecteddevice.h b/src/device/connecteddevice.h index 65b5b2535..8648afe28 100644 --- a/src/device/connecteddevice.h +++ b/src/device/connecteddevice.h @@ -50,6 +50,7 @@ class ConnectedDevice : public QObject, ~ConnectedDevice(); virtual bool Init() = 0; + virtual void ConnectAsync(); // For some devices (e.g. CD devices) we don't have callbacks to be notified when something change: // we can call this method to refresh device's state virtual void Refresh() {} @@ -71,6 +72,7 @@ class ConnectedDevice : public QObject, signals: void TaskStarted(int id); void SongCountUpdated(int count); + void ConnectFinished(const QString& id, bool success); protected: void InitBackendDirectory(const QString &mount_point, bool first_time, bool rewrite_path = true); diff --git a/src/device/devicemanager.cpp b/src/device/devicemanager.cpp index 1d4bf9e57..e6f3f5cac 100644 --- a/src/device/devicemanager.cpp +++ b/src/device/devicemanager.cpp @@ -548,12 +548,29 @@ std::shared_ptr DeviceManager::Connect(DeviceInfo *info) { connect(info->device_.get(), SIGNAL(TaskStarted(int)), SLOT(DeviceTaskStarted(int))); connect(info->device_.get(), SIGNAL(SongCountUpdated(int)), SLOT(DeviceSongCountUpdated(int))); - - emit DeviceConnected(idx); + connect(info->device_.get(), SIGNAL(ConnectFinished(const QString&, bool)), SLOT(DeviceConnectFinished(const QString&, bool))); + ret->ConnectAsync(); return ret; } +void DeviceManager::DeviceConnectFinished(const QString &id, bool success) { + + DeviceInfo *info = FindDeviceById(id); + if (!info) return; + + QModelIndex idx = ItemToIndex(info); + if (!idx.isValid()) return; + + if (success) { + emit DeviceConnected(idx); + } + else { + info->device_.reset(); + } + +} + DeviceInfo *DeviceManager::GetDevice(QModelIndex idx) const { DeviceInfo *info = IndexToItem(idx); diff --git a/src/device/devicemanager.h b/src/device/devicemanager.h index 8063bf7fe..2404514b7 100644 --- a/src/device/devicemanager.h +++ b/src/device/devicemanager.h @@ -125,6 +125,7 @@ class DeviceManager : public SimpleTreeModel { void TasksChanged(); void DeviceSongCountUpdated(int count); void LoadAllDevices(); + void DeviceConnectFinished(const QString &id, bool success); protected: void LazyPopulate(DeviceInfo *item) { LazyPopulate(item, true); } diff --git a/src/device/gpoddevice.cpp b/src/device/gpoddevice.cpp index d5976faca..5e051a3aa 100644 --- a/src/device/gpoddevice.cpp +++ b/src/device/gpoddevice.cpp @@ -59,11 +59,10 @@ bool GPodDevice::Init() { loader_ = new GPodLoader(url_.path(), app_->task_manager(), backend_, shared_from_this()); loader_->moveToThread(loader_thread_); - connect(loader_, SIGNAL(Error(QString)), SIGNAL(Error(QString))); + connect(loader_, SIGNAL(Error(QString)), SLOT(LoaderError(QString))); connect(loader_, SIGNAL(TaskStarted(int)), SIGNAL(TaskStarted(int))); - connect(loader_, SIGNAL(LoadFinished(Itdb_iTunesDB*)), SLOT(LoadFinished(Itdb_iTunesDB*))); + connect(loader_, SIGNAL(LoadFinished(Itdb_iTunesDB*, bool)), SLOT(LoadFinished(Itdb_iTunesDB*, bool))); connect(loader_thread_, SIGNAL(started()), loader_, SLOT(LoadDatabase())); - loader_thread_->start(); return true; @@ -71,7 +70,13 @@ bool GPodDevice::Init() { GPodDevice::~GPodDevice() {} -void GPodDevice::LoadFinished(Itdb_iTunesDB *db) { +void GPodDevice::ConnectAsync() { + + loader_thread_->start(); + +} + +void GPodDevice::LoadFinished(Itdb_iTunesDB *db, bool success) { QMutexLocker l(&db_mutex_); db_ = db; @@ -87,8 +92,12 @@ void GPodDevice::LoadFinished(Itdb_iTunesDB *db) { loader_->deleteLater(); loader_ = nullptr; + emit ConnectFinished(unique_id_, success); + } +void GPodDevice::LoaderError(const QString &message) { app_->AddError(message); } + bool GPodDevice::StartCopy(QList *supported_filetypes) { { diff --git a/src/device/gpoddevice.h b/src/device/gpoddevice.h index 70c58ee8f..084b7ed06 100644 --- a/src/device/gpoddevice.h +++ b/src/device/gpoddevice.h @@ -46,19 +46,19 @@ class GPodLoader; class GPodDevice : public ConnectedDevice, public virtual MusicStorage { Q_OBJECT - - signals: - void Error(const QString &message); public: Q_INVOKABLE GPodDevice( const QUrl &url, DeviceLister *lister, - const QString &unique_id, DeviceManager *manager, + const QString &unique_id, + DeviceManager *manager, Application *app, - int database_id, bool first_time); + int database_id, + bool first_time); ~GPodDevice(); bool Init(); + void ConnectAsync(); static QStringList url_schemes() { return QStringList() << "ipod"; } @@ -73,7 +73,8 @@ class GPodDevice : public ConnectedDevice, public virtual MusicStorage { void FinishDelete(bool success); protected slots: - void LoadFinished(Itdb_iTunesDB *db); + void LoadFinished(Itdb_iTunesDB *db, bool success); + void LoaderError(const QString& message); protected: Itdb_Track *AddTrackToITunesDb(const Song &metadata); diff --git a/src/device/gpodloader.cpp b/src/device/gpodloader.cpp index 7a954e525..6b9431d0e 100644 --- a/src/device/gpodloader.cpp +++ b/src/device/gpodloader.cpp @@ -52,6 +52,17 @@ void GPodLoader::LoadDatabase() { int task_id = task_manager_->StartTask(tr("Loading iPod database")); emit TaskStarted(task_id); + Itdb_iTunesDB *db = TryLoad(); + + moveToThread(original_thread_); + + task_manager_->SetTaskFinished(task_id); + emit LoadFinished(db, db); + +} + +Itdb_iTunesDB *GPodLoader::TryLoad() { + // Load the iTunes database GError *error = nullptr; Itdb_iTunesDB *db = itdb_parse(QDir::toNativeSeparators(mount_point_).toLocal8Bit(), &error); @@ -62,12 +73,12 @@ void GPodLoader::LoadDatabase() { qLog(Error) << "loading database failed:" << error->message; emit Error(QString::fromUtf8(error->message)); g_error_free(error); - } else { + } + else { emit Error(tr("An error occurred loading the iTunes database")); } - task_manager_->SetTaskFinished(task_id); - return; + return db; } // Convert all the tracks from libgpod structs into Song classes @@ -91,10 +102,6 @@ void GPodLoader::LoadDatabase() { // Add the songs we've just loaded backend_->AddOrUpdateSongs(songs); - moveToThread(original_thread_); - - task_manager_->SetTaskFinished(task_id); - emit LoadFinished(db); + return db; } - diff --git a/src/device/gpodloader.h b/src/device/gpodloader.h index d20418b54..9718e839a 100644 --- a/src/device/gpodloader.h +++ b/src/device/gpodloader.h @@ -52,7 +52,10 @@ class GPodLoader : public QObject { signals: void Error(const QString &message); void TaskStarted(int task_id); - void LoadFinished(Itdb_iTunesDB *db); + void LoadFinished(Itdb_iTunesDB *db, bool success); + + private: + Itdb_iTunesDB *TryLoad(); private: std::shared_ptr device_; diff --git a/src/device/mtpdevice.cpp b/src/device/mtpdevice.cpp index a5d95d1bb..ab5237584 100644 --- a/src/device/mtpdevice.cpp +++ b/src/device/mtpdevice.cpp @@ -64,36 +64,39 @@ MtpDevice::~MtpDevice() {} bool MtpDevice::Init() { InitBackendDirectory("/", first_time_, false); + model_->Init(); loader_ = new MtpLoader(url_, app_->task_manager(), backend_, shared_from_this()); - if (!loader_->Init()) { - delete loader_; - loader_ = nullptr; - return false; - } - model_->Init(); + loader_->moveToThread(loader_thread_); - connect(loader_, SIGNAL(Error(QString)), SIGNAL(Error(QString))); + connect(loader_, SIGNAL(Error(QString)), SLOT(LoaderError(QString))); connect(loader_, SIGNAL(TaskStarted(int)), SIGNAL(TaskStarted(int))); - connect(loader_, SIGNAL(LoadFinished()), SLOT(LoadFinished())); + connect(loader_, SIGNAL(LoadFinished(bool)), SLOT(LoadFinished(bool))); connect(loader_thread_, SIGNAL(started()), loader_, SLOT(LoadDatabase())); - db_busy_.lock(); - loader_thread_->start(); - return true; } -void MtpDevice::LoadFinished() { +void MtpDevice::ConnectAsync() { + + db_busy_.lock(); + loader_thread_->start(); + +} + +void MtpDevice::LoadFinished(bool success) { loader_->deleteLater(); loader_ = nullptr; db_busy_.unlock(); + emit ConnectFinished(unique_id_, success); } +void MtpDevice::LoaderError(const QString& message) { app_->AddError(message); } + bool MtpDevice::StartCopy(QList *supported_types) { // Ensure only one "organise files" can be active at any one time diff --git a/src/device/mtpdevice.h b/src/device/mtpdevice.h index 6ccf7c555..adadbd15d 100644 --- a/src/device/mtpdevice.h +++ b/src/device/mtpdevice.h @@ -54,6 +54,7 @@ class MtpDevice : public ConnectedDevice { static QStringList url_schemes() { return QStringList() << "mtp" << "gphoto2"; } bool Init(); + void ConnectAsync(); bool GetSupportedFiletypes(QList* ret); int GetFreeSpace(); @@ -68,7 +69,8 @@ class MtpDevice : public ConnectedDevice { void FinishDelete(bool success); private slots: - void LoadFinished(); + void LoadFinished(bool success); + void LoaderError(const QString& message); private: bool GetSupportedFiletypes(QList *ret, LIBMTP_mtpdevice_struct *device); diff --git a/src/device/mtploader.cpp b/src/device/mtploader.cpp index 8a2dddc76..58cc72478 100644 --- a/src/device/mtploader.cpp +++ b/src/device/mtploader.cpp @@ -40,34 +40,35 @@ MtpLoader::MtpLoader(const QUrl &url, TaskManager *task_manager, CollectionBacke original_thread_ = thread(); } -MtpLoader::~MtpLoader() { - delete connection_; -} +MtpLoader::~MtpLoader() {} -bool MtpLoader::Init() { - connection_ = new MtpConnection(url_); - return connection_->is_valid(); -} +bool MtpLoader::Init() { return true; } void MtpLoader::LoadDatabase() { int task_id = task_manager_->StartTask(tr("Loading MTP device")); emit TaskStarted(task_id); - TryLoad(); + bool success = TryLoad(); moveToThread(original_thread_); task_manager_->SetTaskFinished(task_id); - emit LoadFinished(); + emit LoadFinished(success); } bool MtpLoader::TryLoad() { + MtpConnection dev(url_); + if (!dev.is_valid()) { + emit Error(tr("Error connecting MTP device")); + return false; + } + // Load the list of songs on the device SongList songs; - LIBMTP_track_t* tracks = LIBMTP_Get_Tracklisting_With_Callback(connection_->device(), nullptr, nullptr); + LIBMTP_track_t* tracks = LIBMTP_Get_Tracklisting_With_Callback(dev.device(), nullptr, nullptr); while (tracks) { LIBMTP_track_t *track = tracks; diff --git a/src/device/mtploader.h b/src/device/mtploader.h index 8e52ba7e4..3f03297c4 100644 --- a/src/device/mtploader.h +++ b/src/device/mtploader.h @@ -51,7 +51,7 @@ class MtpLoader : public QObject { signals: void Error(const QString &message); void TaskStarted(int task_id); - void LoadFinished(); + void LoadFinished(bool success); private: bool TryLoad();