diff --git a/src/core/musicstorage.h b/src/core/musicstorage.h index bc1813b18..e590f92a3 100644 --- a/src/core/musicstorage.h +++ b/src/core/musicstorage.h @@ -62,9 +62,9 @@ public: virtual TranscodeMode GetTranscodeMode() const { return Transcode_Never; } virtual Song::FileType GetTranscodeFormat() const { return Song::Type_Unknown; } - virtual QList SupportedFiletypes() { return QList(); } + virtual bool GetSupportedFiletypes(QList* ret) { return true; } - virtual void StartCopy() {} + virtual bool StartCopy(QList* supported_types) { return true;} virtual bool CopyToStorage(const CopyJob& job) = 0; virtual void FinishCopy(bool success) {} diff --git a/src/core/organise.cpp b/src/core/organise.cpp index 18e656426..02535b488 100644 --- a/src/core/organise.cpp +++ b/src/core/organise.cpp @@ -72,9 +72,13 @@ void Organise::Start() { void Organise::ProcessSomeFiles() { if (!started_) { transcode_temp_name_.open(); - supported_filetypes_ = destination_->SupportedFiletypes(); - destination_->StartCopy(); + if (!destination_->StartCopy(&supported_filetypes_)) { + // Failed to start - mark everything as failed :( + foreach (const Task& task, tasks_pending_) + files_with_errors_ << task.filename_; + tasks_pending_.clear(); + } started_ = true; } diff --git a/src/devices/afcdevice.cpp b/src/devices/afcdevice.cpp index f822b1dce..c44337497 100644 --- a/src/devices/afcdevice.cpp +++ b/src/devices/afcdevice.cpp @@ -75,9 +75,11 @@ void AfcDevice::CopyFinished(bool success) { QMetaObject::invokeMethod(loader_, "LoadDatabase"); } -void AfcDevice::StartCopy() { - GPodDevice::StartCopy(); +bool AfcDevice::StartCopy(QList* supported_types) { + GPodDevice::StartCopy(supported_types); connection_.reset(new iMobileDeviceConnection(url_.host())); + + return true; } bool AfcDevice::CopyToStorage(const CopyJob& job) { diff --git a/src/devices/afcdevice.h b/src/devices/afcdevice.h index 993480578..0d5cc7243 100644 --- a/src/devices/afcdevice.h +++ b/src/devices/afcdevice.h @@ -43,7 +43,7 @@ public: static QStringList url_schemes() { return QStringList() << "afc"; } - void StartCopy(); + bool StartCopy(QList* supported_types); bool CopyToStorage(const CopyJob& job); void FinishCopy(bool success); diff --git a/src/devices/deviceproperties.cpp b/src/devices/deviceproperties.cpp index 463bf7e1a..b317e0e7c 100644 --- a/src/devices/deviceproperties.cpp +++ b/src/devices/deviceproperties.cpp @@ -174,12 +174,6 @@ void DeviceProperties::UpdateHardwareInfo() { } } -namespace { - typedef QList TypeList; - typedef QFuture DeviceTypesFuture; - typedef QFutureWatcher DeviceTypesFutureWatcher; -} - void DeviceProperties::UpdateFormats() { QString id = index_.data(DeviceManager::Role_UniqueId).toString(); DeviceLister* lister = manager_->GetLister(index_.row()); @@ -222,9 +216,11 @@ void DeviceProperties::UpdateFormats() { if (!updating_formats_) { // Get the device's supported formats list. This takes a long time and it // blocks, so do it in the background. - DeviceTypesFuture future = QtConcurrent::run( - boost::bind(&ConnectedDevice::SupportedFiletypes, device)); - DeviceTypesFutureWatcher* watcher = new DeviceTypesFutureWatcher(this); + supported_formats_.clear(); + + QFuture future = QtConcurrent::run(boost::bind( + &ConnectedDevice::GetSupportedFiletypes, device, &supported_formats_)); + QFutureWatcher* watcher = new QFutureWatcher(this); watcher->setFuture(future); connect(watcher, SIGNAL(finished()), SLOT(UpdateFormatsFinished())); @@ -260,23 +256,25 @@ void DeviceProperties::OpenDevice() { } void DeviceProperties::UpdateFormatsFinished() { - DeviceTypesFutureWatcher* watcher = static_cast(sender()); + QFutureWatcher* watcher = static_cast*>(sender()); watcher->deleteLater(); updating_formats_ = false; - TypeList list = watcher->future().result(); + if (!watcher->future().result()) { + supported_formats_.clear(); + } // Hide widgets if there are no supported types - ui_->supported_formats_container->setVisible(!list.isEmpty()); - ui_->transcode_unsupported->setEnabled(!list.isEmpty()); + ui_->supported_formats_container->setVisible(!supported_formats_.isEmpty()); + ui_->transcode_unsupported->setEnabled(!supported_formats_.isEmpty()); - if (ui_->transcode_unsupported->isChecked() && list.isEmpty()) { + if (ui_->transcode_unsupported->isChecked() && supported_formats_.isEmpty()) { ui_->transcode_off->setChecked(true); } // Populate supported types list ui_->supported_formats->clear(); - foreach (Song::FileType type, list) { + foreach (Song::FileType type, supported_formats_) { QListWidgetItem* item = new QListWidgetItem(Song::TextForFiletype(type)); ui_->supported_formats->addItem(item); } @@ -288,7 +286,7 @@ void DeviceProperties::UpdateFormatsFinished() { if (preset.type_ == Song::Type_Unknown) { // The user hasn't chosen a format for this device yet, so work our way down // a list of some preferred formats, picking the first one that is supported - preset = Transcoder::PresetForFileType(Transcoder::PickBestFormat(list)); + preset = Transcoder::PresetForFileType(Transcoder::PickBestFormat(supported_formats_)); } ui_->transcode_format->setCurrentIndex(ui_->transcode_format->findText(preset.name_)); diff --git a/src/devices/deviceproperties.h b/src/devices/deviceproperties.h index 0a1c6221c..5b7214c56 100644 --- a/src/devices/deviceproperties.h +++ b/src/devices/deviceproperties.h @@ -55,6 +55,7 @@ private: QPersistentModelIndex index_; bool updating_formats_; + QList supported_formats_; }; #endif // DEVICEPROPERTIES_H diff --git a/src/devices/gpoddevice.cpp b/src/devices/gpoddevice.cpp index ada4082f8..8bee4dbf7 100644 --- a/src/devices/gpoddevice.cpp +++ b/src/devices/gpoddevice.cpp @@ -63,7 +63,7 @@ void GPodDevice::LoadFinished(Itdb_iTunesDB* db) { loader_ = NULL; } -void GPodDevice::StartCopy() { +bool GPodDevice::StartCopy(QList* supported_filetypes) { { // Wait for the database to be loaded QMutexLocker l(&db_mutex_); @@ -73,6 +73,10 @@ void GPodDevice::StartCopy() { // Ensure only one "organise files" can be active at any one time db_busy_.lock(); + + if (supported_filetypes) + GetSupportedFiletypes(supported_filetypes); + return true; } Itdb_Track* GPodDevice::AddTrackToITunesDb(const Song& metadata) { @@ -157,7 +161,7 @@ void GPodDevice::FinishCopy(bool success) { } void GPodDevice::StartDelete() { - StartCopy(); + StartCopy(NULL); } bool GPodDevice::RemoveTrackFromITunesDb(const QString& path, const QString& relative_to) { @@ -220,9 +224,8 @@ void GPodDevice::FinishDelete(bool success) { ConnectedDevice::FinishDelete(success); } -QList GPodDevice::SupportedFiletypes() { - QList ret; - ret << Song::Type_Mp4; - ret << Song::Type_Mpeg; - return ret; +bool GPodDevice::GetSupportedFiletypes(QList* ret) { + *ret << Song::Type_Mp4; + *ret << Song::Type_Mpeg; + return true; } diff --git a/src/devices/gpoddevice.h b/src/devices/gpoddevice.h index fe20334b7..0e92f7e9c 100644 --- a/src/devices/gpoddevice.h +++ b/src/devices/gpoddevice.h @@ -41,9 +41,9 @@ public: static QStringList url_schemes() { return QStringList() << "ipod"; } - QList SupportedFiletypes(); + bool GetSupportedFiletypes(QList* ret); - void StartCopy(); + bool StartCopy(QList* supported_types); bool CopyToStorage(const CopyJob& job); void FinishCopy(bool success); diff --git a/src/devices/mtpdevice.cpp b/src/devices/mtpdevice.cpp index 34c039ecd..d7d267326 100644 --- a/src/devices/mtpdevice.cpp +++ b/src/devices/mtpdevice.cpp @@ -66,12 +66,22 @@ void MtpDevice::LoadFinished() { db_busy_.unlock(); } -void MtpDevice::StartCopy() { +bool MtpDevice::StartCopy(QList* supported_types) { // Ensure only one "organise files" can be active at any one time db_busy_.lock(); // Connect to the device connection_.reset(new MtpConnection(url_.host())); + + // Did the caller want a list of supported types? + if (supported_types) { + if (!GetSupportedFiletypes(supported_types, connection_->device())) { + FinishCopy(false); + return false; + } + } + + return true; } static int ProgressCallback(uint64_t const sent, uint64_t const total, @@ -131,7 +141,7 @@ void MtpDevice::FinishCopy(bool success) { } void MtpDevice::StartDelete() { - StartCopy(); + StartCopy(NULL); } bool MtpDevice::DeleteFromStorage(const DeleteJob& job) { @@ -160,40 +170,42 @@ void MtpDevice::FinishDelete(bool success) { FinishCopy(success); } -QList MtpDevice::SupportedFiletypes() { - QList ret; - - uint16_t* list = NULL; - uint16_t length = 0; - +bool MtpDevice::GetSupportedFiletypes(QList* ret) { QMutexLocker l(&db_busy_); MtpConnection connection(url_.host()); if (!connection.is_valid()) { qWarning() << "Error connecting to MTP device, couldn't get list of supported filetypes"; - return ret; + return false; } - if (LIBMTP_Get_Supported_Filetypes(connection.device(), &list, &length) + return GetSupportedFiletypes(ret, connection.device()); +} + +bool MtpDevice::GetSupportedFiletypes(QList* ret, LIBMTP_mtpdevice_t* device) { + uint16_t* list = NULL; + uint16_t length = 0; + + if (LIBMTP_Get_Supported_Filetypes(device, &list, &length) || !list || !length) - return ret; + return false; for (int i=0 ; i MtpDevice::SupportedFiletypes() { } free(list); - return ret; + return true; } diff --git a/src/devices/mtpdevice.h b/src/devices/mtpdevice.h index bcfc9fee7..7624cc1fc 100644 --- a/src/devices/mtpdevice.h +++ b/src/devices/mtpdevice.h @@ -40,9 +40,9 @@ public: void Init(); - QList SupportedFiletypes(); + bool GetSupportedFiletypes(QList* ret); - void StartCopy(); + bool StartCopy(QList* supported_types); bool CopyToStorage(const CopyJob& job); void FinishCopy(bool success); @@ -53,6 +53,9 @@ public: private slots: void LoadFinished(); +private: + bool GetSupportedFiletypes(QList* ret, LIBMTP_mtpdevice_t* device); + private: static bool sInitialisedLibMTP; diff --git a/src/devices/wmdmdevice.cpp b/src/devices/wmdmdevice.cpp index ad6aecaff..e9db17cb1 100644 --- a/src/devices/wmdmdevice.cpp +++ b/src/devices/wmdmdevice.cpp @@ -62,7 +62,7 @@ void WmdmDevice::LoadFinished() { loader_ = NULL; } -void WmdmDevice::StartCopy() { +bool WmdmDevice::StartCopy(QList* supported_types) { // Ensure only one "organise files" can be active at any one time db_busy_.lock(); @@ -82,6 +82,19 @@ void WmdmDevice::StartCopy() { destination->QueryInterface(IID_IWMDMStorage3, (void**)&storage_); destination->Release(); + + // Did the caller want a list of supported filetypes? + if (supported_types) { + IWMDMDevice* device = thread_->GetDeviceByCanonicalName(canonical_name); + if (!GetSupportedFiletypes(supported_types, device)) { + device->Release(); + FinishCopy(false); + return false; + } + device->Release(); + } + + return true; } bool WmdmDevice::CopyToStorage(const CopyJob& job) { @@ -213,15 +226,7 @@ void WmdmDevice::FinishDelete(bool success) { FinishCopy(success); } -QList WmdmDevice::SupportedFiletypes() { - QList ret; - WmdmThread thread; - - // Get the device - WmdmLister* wmdm_lister = static_cast(lister()); - QString canonical_name = wmdm_lister->DeviceCanonicalName(unique_id()); - IWMDMDevice* device = thread.GetDeviceByCanonicalName(canonical_name); - +bool WmdmDevice::GetSupportedFiletypes(QList* ret, IWMDMDevice* device) { // Get a list of supported formats uint32_t format_count = 0; uint32_t mime_count = 0; @@ -231,28 +236,40 @@ QList WmdmDevice::SupportedFiletypes() { if (device->GetFormatSupport( &formats, &format_count, &mime_types, &mime_count)) { qWarning() << "Unable to get a list of supported formats for device" << canonical_name; - device->Release(); - return ret; + return false; } - device->Release(); // Find known mime types for (int i=0 ; i* ret) { + WmdmThread thread; + + // Get the device + WmdmLister* wmdm_lister = static_cast(lister()); + QString canonical_name = wmdm_lister->DeviceCanonicalName(unique_id()); + IWMDMDevice* device = thread.GetDeviceByCanonicalName(canonical_name); + + bool success = GetSupportedFiletypes(ret, device); + device->Release(); + + return success; } diff --git a/src/devices/wmdmdevice.h b/src/devices/wmdmdevice.h index eb0a4b2a2..e547197b2 100644 --- a/src/devices/wmdmdevice.h +++ b/src/devices/wmdmdevice.h @@ -24,6 +24,7 @@ class WmdmLoader; class WmdmThread; +struct IWMDMDevice; struct IWMDMStorage3; struct IWMDMStorageControl3; @@ -40,9 +41,9 @@ public: void Init(); - QList SupportedFiletypes(); + bool GetSupportedFiletypes(QList* ret); - void StartCopy(); + bool StartCopy(QList* supported_types); bool CopyToStorage(const CopyJob& job); void FinishCopy(bool success); @@ -53,6 +54,9 @@ public: private slots: void LoadFinished(); +private: + bool GetSupportedFiletypes(QList* ret, IWMDMDevice* device); + private: QThread* loader_thread_; WmdmLoader* loader_;