Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Canonical URL/URI for track objects #2162

Merged
merged 3 commits into from
Jun 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/library/basesqltablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
#include "track/trackmetadata.h"
#include "util/db/dbconnection.h"
#include "util/duration.h"
#include "util/dnd.h"
#include "util/assert.h"
#include "util/performancetimer.h"

Expand Down Expand Up @@ -1094,7 +1093,7 @@ QMimeData* BaseSqlTableModel::mimeData(const QModelIndexList &indexes) const {
continue;
}
rows.insert(index.row());
QUrl url = DragAndDropHelper::urlFromLocation(getTrackLocation(index));
QUrl url = TrackRef::locationUrl(getTrackLocation(index));
if (!url.isValid()) {
qDebug() << this << "ERROR: invalid url" << url;
continue;
Expand Down
3 changes: 1 addition & 2 deletions src/library/browse/browsetablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#include "mixer/playermanager.h"
#include "control/controlobject.h"
#include "library/dao/trackdao.h"
#include "util/dnd.h"

BrowseTableModel::BrowseTableModel(QObject* parent,
TrackCollection* pTrackCollection,
Expand Down Expand Up @@ -243,7 +242,7 @@ QMimeData* BrowseTableModel::mimeData(const QModelIndexList &indexes) const {
if (index.isValid()) {
if (!rows.contains(index.row())) {
rows.push_back(index.row());
QUrl url = DragAndDropHelper::urlFromLocation(getTrackLocation(index));
QUrl url = TrackRef::locationUrl(getTrackLocation(index));
if (!url.isValid()) {
qDebug() << "ERROR invalid url" << url;
continue;
Expand Down
25 changes: 2 additions & 23 deletions src/sources/soundsourceproxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,27 +51,6 @@ namespace {

const mixxx::Logger kLogger("SoundSourceProxy");

QUrl getCanonicalUrlForTrack(const Track* pTrack) {
if (pTrack == nullptr) {
// Missing track
return QUrl();
}
const QString canonicalLocation(pTrack->getCanonicalLocation());
if (canonicalLocation.isEmpty()) {
// Corresponding file is missing or inaccessible
//
// NOTE(uklotzde): Special case handling is required for Qt 4.8!
// Creating an URL from an empty local file in Qt 4.8 will result
// in an URL with the string "file:" instead of an empty URL.
//
// TODO(XXX): This is no longer required for Qt 5.x
// http://doc.qt.io/qt-5/qurl.html#fromLocalFile
// "An empty localFile leads to an empty URL (since Qt 5.4)."
return QUrl();
}
return QUrl::fromLocalFile(canonicalLocation);
}

} // anonymous namespace

// static
Expand Down Expand Up @@ -229,7 +208,7 @@ Track::ExportMetadataResult
SoundSourceProxy::exportTrackMetadataBeforeSaving(Track* pTrack) {
DEBUG_ASSERT(pTrack);
mixxx::MetadataSourcePointer pMetadataSource =
SoundSourceProxy(getCanonicalUrlForTrack(pTrack)).m_pSoundSource;
SoundSourceProxy(pTrack->getCanonicalLocationUrl()).m_pSoundSource;
if (pMetadataSource) {
return pTrack->exportMetadata(pMetadataSource);
} else {
Expand All @@ -243,7 +222,7 @@ SoundSourceProxy::exportTrackMetadataBeforeSaving(Track* pTrack) {
SoundSourceProxy::SoundSourceProxy(
TrackPointer pTrack)
: m_pTrack(std::move(pTrack)),
m_url(getCanonicalUrlForTrack(m_pTrack.get())),
m_url(m_pTrack ? m_pTrack->getCanonicalLocationUrl() : QUrl()),
m_soundSourceProviderRegistrations(findSoundSourceProviderRegistrations(m_url)),
m_soundSourceProviderRegistrationIndex(0) {
initSoundSource();
Expand Down
32 changes: 32 additions & 0 deletions src/track/track.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,38 @@ QString Track::getCanonicalLocation() const {
return loc;
}

QUrl Track::getLocationUrl() const {
// Copying QFileInfo is thread-safe due to "implicit sharing"
// (copy-on write). But operating on a single instance of QFileInfo
// might not be thread-safe due to internal caching!
QMutexLocker lock(&m_qMutex);
return TrackRef::locationUrl(m_fileInfo);
}

QUrl Track::getCanonicalLocationUrl() const {
// Copying QFileInfo is thread-safe due to "implicit sharing"
// (copy-on write). But operating on a single instance of QFileInfo
// might not be thread-safe due to internal caching!
QMutexLocker lock(&m_qMutex);
return TrackRef::canonicalLocationUrl(m_fileInfo);
}

QString Track::getLocationUri() const {
// Copying QFileInfo is thread-safe due to "implicit sharing"
// (copy-on write). But operating on a single instance of QFileInfo
// might not be thread-safe due to internal caching!
QMutexLocker lock(&m_qMutex);
return TrackRef::locationUri(m_fileInfo);
}

QString Track::getCanonicalLocationUri() const {
// Copying QFileInfo is thread-safe due to "implicit sharing"
// (copy-on write). But operating on a single instance of QFileInfo
// might not be thread-safe due to internal caching!
QMutexLocker lock(&m_qMutex);
return TrackRef::canonicalLocationUri(m_fileInfo);
}

QString Track::getDirectory() const {
// Copying QFileInfo is thread-safe due to "implicit sharing"
// (copy-on write). But operating on a single instance of QFileInfo
Expand Down
7 changes: 7 additions & 0 deletions src/track/track.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <QList>
#include <QMutex>
#include <QObject>
#include <QUrl>

#include "track/beats.h"
#include "track/cue.h"
Expand All @@ -21,6 +22,8 @@ class Track;
typedef std::shared_ptr<Track> TrackPointer;
typedef std::weak_ptr<Track> TrackWeakPointer;

Q_DECLARE_METATYPE(TrackPointer);

class Track : public QObject {
Q_OBJECT

Expand Down Expand Up @@ -79,7 +82,11 @@ class Track : public QObject {
// Accessors for various stats of the file on disk.
// Returns absolute path to the file, including the filename.
QString getLocation() const;
QUrl getLocationUrl() const;
QString getLocationUri() const;
QString getCanonicalLocation() const;
QUrl getCanonicalLocationUrl() const;
QString getCanonicalLocationUri() const;
// Returns the absolute path to the directory containing the file
QString getDirectory() const;
// Returns the name of the file.
Expand Down
44 changes: 44 additions & 0 deletions src/track/trackref.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,50 @@
#include "track/trackref.h"


namespace {

inline
QUrl urlFromLocalFilePath(const QString& localFilePath) {
#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
return QUrl::fromLocalFile(localFilePath);
#else
if (localFilePath.isEmpty()) {
return QUrl();
} else {
return QUrl::fromLocalFile(localFilePath);
}
#endif
}

inline
QString urlToString(const QUrl& url) {
return url.toEncoded(
QUrl::StripTrailingSlash |
QUrl::NormalizePathSegments);
}

} // anonymous namespace

//static
QUrl TrackRef::locationUrl(const QFileInfo& fileInfo) {
return urlFromLocalFilePath(location(fileInfo));
}

//static
QUrl TrackRef::canonicalLocationUrl(const QFileInfo& fileInfo) {
return urlFromLocalFilePath(canonicalLocation(fileInfo));
}

//static
QString TrackRef::locationUri(const QFileInfo& fileInfo) {
return urlToString(locationUrl(fileInfo));
}

//static
QString TrackRef::canonicalLocationUri(const QFileInfo& fileInfo) {
return urlToString(canonicalLocationUrl(fileInfo));
}

bool TrackRef::verifyConsistency() const {
// Class invariant: The location can only be set together with
// at least one of the other members!
Expand Down
7 changes: 7 additions & 0 deletions src/track/trackref.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@


#include <QFileInfo>
#include <QUrl>

#include "track/trackid.h"

Expand All @@ -29,6 +30,12 @@ class TrackRef {
return fileInfo.canonicalFilePath();
}

static QUrl locationUrl(const QFileInfo& fileInfo);
static QUrl canonicalLocationUrl(const QFileInfo& fileInfo);

static QString locationUri(const QFileInfo& fileInfo);
static QString canonicalLocationUri(const QFileInfo& fileInfo);

// Converts a QFileInfo and an optional TrackId into a TrackRef. This
// involves obtaining the file-related track properties from QFileInfo
// (see above) and should used consciously!
Expand Down