diff --git a/src/core/song.cpp b/src/core/song.cpp index 5cfaa970a..fa3382437 100644 --- a/src/core/song.cpp +++ b/src/core/song.cpp @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -49,6 +50,7 @@ # include #endif +#include "core/application.h" #include "core/logging.h" #include "core/messagehandler.h" #include "core/mpris_common.h" @@ -259,15 +261,8 @@ qint64 Song::length_nanosec() const { return d->end_ - d->beginning_; } int Song::bitrate() const { return d->bitrate_; } int Song::samplerate() const { return d->samplerate_; } int Song::directory_id() const { return d->directory_id_; } -const QUrl& Song::url() const { - QUrl base = QUrl::fromLocalFile(QCoreApplication::applicationDirPath()); - qLog(Debug) << "Url" << d->url_.toLocalFile(); - qLog(Debug) << "base" << base.toString(); - qLog(Debug) << "absolute" << base.resolved(d->url_).toString(); - QUrl res = base.resolved(d->url_); - return d->url_; -} -const QString& Song::basefilename() const { return d->basefilename_; } +const QUrl& Song::url() const { return d->url_; } +const QString& Song::basefilename() const { return d->basefilename_; } uint Song::mtime() const { return d->mtime_; } uint Song::ctime() const { return d->ctime_; } int Song::filesize() const { return d->filesize_; } @@ -322,7 +317,16 @@ void Song::set_score(int v) { d->score_ = qBound(0, v, 100); } void Song::set_cue_path(const QString& v) { d->cue_path_ = v; } void Song::set_unavailable(bool v) { d->unavailable_ = v; } void Song::set_etag(const QString& etag) { d->etag_ = etag; } -void Song::set_url(const QUrl& v) { d->url_ = v; } + +void Song::set_url(const QUrl& v) { + if (Application::kIsPortable) { + QUrl base = QUrl::fromLocalFile(QCoreApplication::applicationDirPath() + "/"); + d->url_ = base.resolved(v); + } else { + d->url_ = v; + } +} + void Song::set_basefilename(const QString& v) { d->basefilename_ = v; } void Song::set_directory_id(int v) { d->directory_id_ = v; } @@ -422,7 +426,7 @@ void Song::InitFromProtobuf(const pb::tagreader::SongMetadata& pb) { set_length_nanosec(pb.length_nanosec()); d->bitrate_ = pb.bitrate(); d->samplerate_ = pb.samplerate(); - d->url_ = QUrl::fromEncoded(QByteArray(pb.url().data(), pb.url().size())); + set_url(QUrl::fromEncoded(QByteArray(pb.url().data(), pb.url().size()))); d->basefilename_ = QStringFromStdString(pb.basefilename()); d->mtime_ = pb.mtime(); d->ctime_ = pb.ctime(); @@ -504,7 +508,7 @@ void Song::InitFromQuery(const SqlRow& q, bool reliable_metadata, int col) { d->samplerate_ = toint(col + 14); d->directory_id_ = toint(col + 15); - d->url_ = QUrl::fromEncoded(tobytearray(col + 16)); + set_url(QUrl::fromEncoded(tobytearray(col + 16))); d->basefilename_ = QFileInfo(d->url_.toLocalFile()).fileName(); d->mtime_ = toint(col + 17); d->ctime_ = toint(col + 18); @@ -549,7 +553,7 @@ void Song::InitFromQuery(const SqlRow& q, bool reliable_metadata, int col) { } void Song::InitFromFilePartial(const QString& filename) { - d->url_ = QUrl::fromLocalFile(filename); + set_url(QUrl::fromLocalFile(filename)); // We currently rely on filename suffix to know if it's a music file or not. // TODO: I know this is not satisfying, but currently, we rely on TagLib // which seems to have the behavior (filename checks). Someday, it would be @@ -613,9 +617,9 @@ void Song::InitFromLastFM(const lastfm::Track& track) { filename.replace(':', '/'); if (prefix.contains("://")) { - d->url_ = QUrl(prefix + filename); + set_url(QUrl(prefix + filename)); } else { - d->url_ = QUrl::fromLocalFile(prefix + filename); + set_url(QUrl::fromLocalFile(prefix + filename)); } d->basefilename_ = QFileInfo(filename).fileName(); @@ -774,7 +778,14 @@ void Song::BindToQuery(QSqlQuery *query) const { query->bindValue(":samplerate", intval(d->samplerate_)); query->bindValue(":directory", notnullintval(d->directory_id_)); - query->bindValue(":filename", d->url_.toEncoded()); + + if (Application::kIsPortable + && Utilities::UrlOnSameDriveAsClementine(d->url_)) { + query->bindValue(":filename", Utilities::GetRelativePathToClementineBin(d->url_)); + } else { + query->bindValue(":filename", d->url_); + } + query->bindValue(":mtime", notnullintval(d->mtime_)); query->bindValue(":ctime", notnullintval(d->ctime_)); query->bindValue(":filesize", notnullintval(d->filesize_)); diff --git a/src/core/utilities.cpp b/src/core/utilities.cpp index fb48fda00..45fdcb73c 100644 --- a/src/core/utilities.cpp +++ b/src/core/utilities.cpp @@ -620,6 +620,27 @@ QString SystemLanguageName() { return system_language; } +bool UrlOnSameDriveAsClementine(const QUrl &url) { + if (url.scheme() != "file") + return false; + +#ifdef Q_OS_WIN + QUrl appUrl = QUrl::fromLocalFile(QCoreApplication::applicationDirPath()); + if (url.toLocalFile().left(1) == appUrl.toLocalFile().left(1)) + return true; + else + return false; +#else + // Non windows systems have always a / in the path + return true; +#endif +} + +QUrl GetRelativePathToClementineBin(const QUrl& url) { + QDir appPath(QCoreApplication::applicationDirPath()); + return QUrl::fromLocalFile(appPath.relativeFilePath(url.toLocalFile())); +} + } // namespace Utilities diff --git a/src/core/utilities.h b/src/core/utilities.h index edaa54508..5c4eb7948 100644 --- a/src/core/utilities.h +++ b/src/core/utilities.h @@ -104,6 +104,12 @@ namespace Utilities { QStringList Prepend(const QString& text, const QStringList& list); QStringList Updateify(const QStringList& list); + // Check if two urls are on the same drive (mainly for windows) + bool UrlOnSameDriveAsClementine(const QUrl& url); + + // Get relative path to clementine binary + QUrl GetRelativePathToClementineBin(const QUrl& url); + enum ConfigPath { Path_Root, diff --git a/src/library/librarybackend.cpp b/src/library/librarybackend.cpp index a3f16b64f..78c73b396 100644 --- a/src/library/librarybackend.cpp +++ b/src/library/librarybackend.cpp @@ -18,9 +18,11 @@ #include "librarybackend.h" #include "libraryquery.h" #include "sqlrow.h" +#include "core/application.h" #include "core/database.h" #include "core/scopedtransaction.h" #include "core/tagreaderclient.h" +#include "core/utilities.h" #include "smartplaylists/search.h" #include @@ -190,14 +192,21 @@ void LibraryBackend::UpdateTotalSongCount() { } void LibraryBackend::AddDirectory(const QString& path) { - QString canonical_path = path; //QFileInfo(path).canonicalFilePath(); + QString canonical_path = QFileInfo(path).canonicalFilePath(); + QString db_path = canonical_path; + + if (Application::kIsPortable + && Utilities::UrlOnSameDriveAsClementine(QUrl::fromLocalFile(canonical_path))) { + db_path = Utilities::GetRelativePathToClementineBin(QUrl::fromLocalFile(db_path)).toLocalFile(); + qLog(Debug) << "db_path" << db_path; + } QMutexLocker l(db_->Mutex()); QSqlDatabase db(db_->Connect()); QSqlQuery q(QString("INSERT INTO %1 (path, subdirs)" " VALUES (:path, 1)").arg(dirs_table_), db); - q.bindValue(":path", canonical_path); + q.bindValue(":path", db_path); q.exec(); if (db_->CheckErrors(q)) return; diff --git a/src/library/librarydirectorymodel.cpp b/src/library/librarydirectorymodel.cpp index 8376ffef4..2f2394332 100644 --- a/src/library/librarydirectorymodel.cpp +++ b/src/library/librarydirectorymodel.cpp @@ -17,6 +17,7 @@ #include "librarydirectorymodel.h" #include "librarybackend.h" +#include "core/application.h" #include "core/filesystemmusicstorage.h" #include "core/musicstorage.h" #include "core/utilities.h" @@ -35,7 +36,14 @@ LibraryDirectoryModel::~LibraryDirectoryModel() { } void LibraryDirectoryModel::DirectoryDiscovered(const Directory &dir) { - QStandardItem* item = new QStandardItem(dir.path); + QStandardItem* item; + if (Application::kIsPortable + && Utilities::UrlOnSameDriveAsClementine(QUrl::fromLocalFile(dir.path))) { + item = new QStandardItem(Utilities::GetRelativePathToClementineBin( + QUrl::fromLocalFile(dir.path)).toLocalFile()); + } else { + item = new QStandardItem(dir.path); + } item->setData(dir.id, kIdRole); item->setIcon(dir_icon_); storage_ << boost::shared_ptr(new FilesystemMusicStorage(dir.path)); diff --git a/src/library/librarysettingspage.cpp b/src/library/librarysettingspage.cpp index b7f82ec0f..d74ffa499 100644 --- a/src/library/librarysettingspage.cpp +++ b/src/library/librarysettingspage.cpp @@ -68,14 +68,7 @@ void LibrarySettingsPage::Add() { path = QFileDialog::getExistingDirectory(this, tr("Add directory..."), path); if (!path.isNull()) { - if (Application::kIsPortable) { - QDir appPath(QCoreApplication::applicationDirPath()); - QString relativePath = appPath.relativeFilePath(path); - qLog(Debug) << "Relative Path" << relativePath; - dialog()->library_directory_model()->AddDirectory(relativePath); - } else { - dialog()->library_directory_model()->AddDirectory(path); - } + dialog()->library_directory_model()->AddDirectory(path); } settings.setValue("last_path", path);