/* This file is part of Clementine. Copyright 2010, David Sansome 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 . */ #include "devicelister.h" #include "wmdmdevice.h" #include "wmdmlister.h" #include "wmdmloader.h" #include "wmdmthread.h" #include "core/taskmanager.h" #include "library/librarybackend.h" #include #include #include #include WmdmLoader::WmdmLoader(TaskManager* task_manager, LibraryBackend* backend, boost::shared_ptr device) : QObject(NULL), device_(device), task_manager_(task_manager), backend_(backend) { original_thread_ = thread(); } WmdmLoader::~WmdmLoader() { } void WmdmLoader::LoadDatabase() { int task_id = task_manager_->StartTask(tr("Loading Windows Media device")); emit TaskStarted(task_id); boost::scoped_ptr thread(new WmdmThread); // Get the device's canonical name boost::shared_ptr connected_device = boost::static_pointer_cast(device_); WmdmLister* lister = static_cast(connected_device->lister()); QString canonical_name = lister->DeviceCanonicalName(connected_device->unique_id()); IWMDMStorage* storage = thread->GetRootStorage(canonical_name); QStringList path_components; RecursiveExploreStorage(storage, &path_components); storage->Release(); thread.reset(); // Need to remove all the existing songs in the database first backend_->DeleteSongs(backend_->FindSongsInDirectory(1)); // Add the songs we've just loaded backend_->AddOrUpdateSongs(songs_); task_manager_->SetTaskFinished(task_id); emit LoadFinished(); } void WmdmLoader::RecursiveExploreStorage(IWMDMStorage* parent, QStringList* path_components) { IWMDMEnumStorage* child_it = NULL; parent->EnumStorage(&child_it); IWMDMStorage* child = NULL; ULONG num_retreived = 0; while (child_it->Next(1, &child, &num_retreived) == S_OK && num_retreived == 1) { const int kMaxLen = 255; wchar_t name[kMaxLen]; child->GetName(name, kMaxLen); DWORD attributes = 0; _WAVEFORMATEX audio_format; child->GetAttributes(&attributes, &audio_format); path_components->append(QString::fromWCharArray(name)); if (attributes & WMDM_FILE_ATTR_FILE) { LoadFile(child, path_components); } else if (attributes & WMDM_FILE_ATTR_FOLDER) { RecursiveExploreStorage(child, path_components); } path_components->removeLast(); child->Release(); } child_it->Release(); } void WmdmLoader::LoadFile(IWMDMStorage* file, const QStringList* path_components) { // Convert to a IWMDMStorage3 so we can get metadata IWMDMStorage3* storage3 = NULL; if (file->QueryInterface(IID_IWMDMStorage3, (void**) &storage3)) return; // Get the metadata interface IWMDMMetaData* metadata = NULL; if (storage3->GetMetadata(&metadata)) { storage3->Release(); return; } storage3->Release(); // Store the metadata in here Song song; song.InitFromWmdm(metadata); song.set_directory_id(1); song.set_filename(path_components->join("/")); metadata->Release(); if (song.is_valid()) songs_ << song; }