summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJan Holthuis <jan.holthuis@ruhr-uni-bochum.de>2020-03-09 11:14:37 +0100
committerJan Holthuis <jan.holthuis@ruhr-uni-bochum.de>2020-03-09 11:17:55 +0100
commit20ce76f02f5c67190e5dcc2575656a31083658c6 (patch)
treed933204664affc85cb415fce2355c3f90157427b /src
parent90b1109d32edad4c055c01406e0cfadfb5939b39 (diff)
parent7a3095d87adb27e7d6a162b1cd0f0f376eb474f7 (diff)
Merge branch 'master' of github.com:mixxxdj/mixxx into hotcue-rgb-colors
Diffstat (limited to 'src')
-rw-r--r--src/dialog/dlgabout.cpp15
-rw-r--r--src/engine/controls/cuecontrol.cpp2
-rw-r--r--src/library/autodj/autodjprocessor.cpp20
-rw-r--r--src/library/autodj/autodjprocessor.h2
-rw-r--r--src/library/basesqltablemodel.cpp10
-rw-r--r--src/library/basesqltablemodel.h1
-rw-r--r--src/library/browse/browsetablemodel.cpp12
-rw-r--r--src/library/browse/browsetablemodel.h1
-rw-r--r--src/library/coverart.cpp75
-rw-r--r--src/library/coverart.h15
-rw-r--r--src/library/coverartcache.cpp227
-rw-r--r--src/library/coverartcache.h104
-rw-r--r--src/library/coverartdelegate.cpp96
-rw-r--r--src/library/coverartdelegate.h12
-rw-r--r--src/library/coverartutils.cpp74
-rw-r--r--src/library/coverartutils.h22
-rw-r--r--src/library/dao/trackdao.cpp15
-rw-r--r--src/library/dlgcoverartfullsize.cpp35
-rw-r--r--src/library/dlgcoverartfullsize.h8
-rw-r--r--src/library/dlgtagfetcher.cpp230
-rw-r--r--src/library/dlgtagfetcher.h8
-rw-r--r--src/library/dlgtagfetcher.ui15
-rw-r--r--src/library/dlgtrackinfo.cpp32
-rw-r--r--src/library/dlgtrackinfo.h8
-rw-r--r--src/library/proxytrackmodel.cpp4
-rw-r--r--src/library/proxytrackmodel.h1
-rw-r--r--src/library/trackmodel.h6
-rw-r--r--src/musicbrainz/acoustidclient.cpp205
-rw-r--r--src/musicbrainz/acoustidclient.h64
-rw-r--r--src/musicbrainz/musicbrainz.cpp26
-rw-r--r--src/musicbrainz/musicbrainz.h51
-rw-r--r--src/musicbrainz/musicbrainzclient.cpp303
-rw-r--r--src/musicbrainz/musicbrainzclient.h143
-rw-r--r--src/musicbrainz/musicbrainzxml.cpp511
-rw-r--r--src/musicbrainz/musicbrainzxml.h30
-rw-r--r--src/musicbrainz/network.cpp84
-rw-r--r--src/musicbrainz/network.h50
-rw-r--r--src/musicbrainz/tagfetcher.cpp248
-rw-r--r--src/musicbrainz/tagfetcher.h90
-rw-r--r--src/musicbrainz/web/acoustidlookuptask.cpp225
-rw-r--r--src/musicbrainz/web/acoustidlookuptask.h43
-rw-r--r--src/musicbrainz/web/musicbrainzrecordingstask.cpp225
-rw-r--r--src/musicbrainz/web/musicbrainzrecordingstask.h61
-rw-r--r--src/network/httprequestmethod.h17
-rw-r--r--src/network/httpstatuscode.h64
-rw-r--r--src/network/jsonwebtask.cpp297
-rw-r--r--src/network/jsonwebtask.h104
-rw-r--r--src/network/webtask.cpp267
-rw-r--r--src/network/webtask.h165
-rw-r--r--src/sources/soundsourceproxy.cpp2
-rw-r--r--src/test/autodjprocessor_test.cpp4
-rw-r--r--src/test/coverartcache_test.cpp9
-rw-r--r--src/test/cue_test.cpp49
-rw-r--r--src/test/librarytest.cpp6
-rw-r--r--src/test/librarytest.h3
-rw-r--r--src/test/mixxxtest.cpp7
-rw-r--r--src/test/searchqueryparsertest.cpp4
-rw-r--r--src/test/seratomarkers2test.cpp8
-rw-r--r--src/test/seratomarkerstest.cpp8
-rw-r--r--src/test/seratotagstest.cpp43
-rw-r--r--src/test/tracknumberstest.cpp2
-rw-r--r--src/track/cue.cpp85
-rw-r--r--src/track/cue.h50
-rw-r--r--src/track/cueinfo.cpp19
-rw-r--r--src/track/cueinfo.h25
-rw-r--r--src/track/serato/markers.cpp10
-rw-r--r--src/track/serato/markers.h1
-rw-r--r--src/track/serato/markers2.cpp42
-rw-r--r--src/track/serato/markers2.h40
-rw-r--r--src/track/serato/tags.cpp81
-rw-r--r--src/track/serato/tags.h68
-rw-r--r--src/track/track.cpp45
-rw-r--r--src/track/track.h8
-rw-r--r--src/track/trackinfo.cpp5
-rw-r--r--src/track/trackinfo.h6
-rw-r--r--src/track/trackmetadatataglib.cpp28
-rw-r--r--src/track/tracknumbers.cpp4
-rw-r--r--src/track/tracknumbers.h2
-rw-r--r--src/track/trackrecord.cpp2
-rw-r--r--src/util/compatibility.h11
-rw-r--r--src/widget/wcoverart.cpp54
-rw-r--r--src/widget/wcoverart.h8
-rw-r--r--src/widget/wpushbutton.cpp24
-rw-r--r--src/widget/wpushbutton.h3
-rw-r--r--src/widget/wspinny.cpp42
-rw-r--r--src/widget/wspinny.h8
-rw-r--r--src/widget/wtracktableview.cpp15
87 files changed, 3622 insertions, 1532 deletions
diff --git a/src/dialog/dlgabout.cpp b/src/dialog/dlgabout.cpp
index 3fa55e513e..ec1a7bb851 100644
--- a/src/dialog/dlgabout.cpp
+++ b/src/dialog/dlgabout.cpp
@@ -48,11 +48,13 @@ DlgAbout::DlgAbout(QWidget* parent) : QDialog(parent), Ui::DlgAboutDlg() {
<< "Nicu Badescu"
<< "Uwe Klotz"
<< "Be"
- << "S&eacute;bastien Blaisot";
+ << "S&eacute;bastien Blaisot"
+ << "ronso0"
+ << "Jan Holthuis";
- // This list should contains all contributors committed
- // code to the Mixxx core within the past two years.
- // New Contributors are added at the end.
+ // This list should contains all contributors committed
+ // code to the Mixxx core within the past two years.
+ // New Contributors are added at the end.
QStringList recentContributors;
recentContributors
<< "Stefan N&uuml;rnberger"
@@ -82,7 +84,6 @@ DlgAbout::DlgAbout(QWidget* parent) : QDialog(parent), Ui::DlgAboutDlg() {
<< "Kshitij Gupta"
<< "Thomas Jarosch"
<< "Matthew Nicholson"
- << "ronso0"
<< "Jamie Gifford"
<< "luzpaz"
<< "Sebastian Reu&szlig;e"
@@ -93,11 +94,11 @@ DlgAbout::DlgAbout(QWidget* parent) : QDialog(parent), Ui::DlgAboutDlg() {
<< "Nikolaus Einhauser"
<< "Nik Martin"
<< "Kerrick Staley"
- << "Jan Holthuis"
<< "Raphael Graf"
<< "YunQiang Su"
<< "Sebastian Hasler"
- << "Philip Gottschling";
+ << "Philip Gottschling"
+ << "Cristiano Lacerda";
QStringList specialThanks;
specialThanks
diff --git a/src/engine/controls/cuecontrol.cpp b/src/engine/controls/cuecontrol.cpp
index 0297c7bdfb..ba5a143785 100644
--- a/src/engine/controls/cuecontrol.cpp
+++ b/src/engine/controls/cuecontrol.cpp
@@ -614,7 +614,7 @@ void CueControl::hotcueSet(HotcueControl* pControl, double v) {
double cuePosition = getQuantizedCurrentPosition();
pCue->setStartPosition(cuePosition);
pCue->setHotCue(hotcue);
- pCue->setLabel("");
+ pCue->setLabel();
pCue->setType(mixxx::CueType::HotCue);
ConfigKey autoHotcueColorsKey("[Controls]", "auto_hotcue_colors");
diff --git a/src/library/autodj/autodjprocessor.cpp b/src/library/autodj/autodjprocessor.cpp
index 13ba0bef5c..9f96a1b1d1 100644
--- a/src/library/autodj/autodjprocessor.cpp
+++ b/src/library/autodj/autodjprocessor.cpp
@@ -329,6 +329,18 @@ AutoDJProcessor::AutoDJError AutoDJProcessor::skipNext() {
} else if (!rightDeck.isPlaying()) {
removeLoadedTrackFromTopOfQueue(rightDeck);
loadNextTrackFromQueue(rightDeck);
+ } else {
+ // If both decks are playing remove next track in playlist
+ TrackId nextId = m_pAutoDJTableModel->getTrackId(m_pAutoDJTableModel->index(0, 0));
+ TrackId leftId = leftDeck.getLoadedTrack()->getId();
+ TrackId rightId = rightDeck.getLoadedTrack()->getId();
+ if (nextId == leftId || nextId == rightId) {
+ // One of the playing tracks is still on top of playlist, remove second item
+ m_pAutoDJTableModel->removeTrack(m_pAutoDJTableModel->index(1, 0));
+ } else {
+ m_pAutoDJTableModel->removeTrack(m_pAutoDJTableModel->index(0, 0));
+ }
+ maybeFillRandomTracks();
}
return ADJ_OK;
}
@@ -898,7 +910,11 @@ bool AutoDJProcessor::removeTrackFromTopOfQueue(TrackPointer pTrack) {
m_pAutoDJTableModel->appendTrack(nextId);
}
- // Fill random tracks if configured
+ maybeFillRandomTracks();
+ return true;
+}
+
+void AutoDJProcessor::maybeFillRandomTracks() {
int minAutoDJCrateTracks = m_pConfig->getValueString(
ConfigKey(kConfigKey, "RandomQueueMinimumAllowed")).toInt();
bool randomQueueEnabled = (((m_pConfig->getValueString(
@@ -909,8 +925,6 @@ bool AutoDJProcessor::removeTrackFromTopOfQueue(TrackPointer pTrack) {
qDebug() << "Randomly adding tracks";
emit randomTrackRequested(tracksToAdd);
}
-
- return true;
}
void AutoDJProcessor::playerPlayChanged(DeckAttributes* thisDeck, bool playing) {
diff --git a/src/library/autodj/autodjprocessor.h b/src/library/autodj/autodjprocessor.h
index c03c3b3f6d..ff1f004b8f 100644
--- a/src/library/autodj/autodjprocessor.h
+++ b/src/library/autodj/autodjprocessor.h
@@ -277,7 +277,7 @@ class AutoDJProcessor : public QObject {
// Removes the provided track from the top of the AutoDJ queue if it is
// present.
bool removeTrackFromTopOfQueue(TrackPointer pTrack);
-
+ void maybeFillRandomTracks();
UserSettingsPointer m_pConfig;
PlayerManagerInterface* m_pPlayerManager;
PlaylistTableModel* m_pAutoDJTableModel;
diff --git a/src/library/basesqltablemodel.cpp b/src/library/basesqltablemodel.cpp
index 177c045203..bea29d4dd3 100644
--- a/src/library/basesqltablemodel.cpp
+++ b/src/library/basesqltablemodel.cpp
@@ -943,16 +943,20 @@ TrackPointer BaseSqlTableModel::getTrack(const QModelIndex& index) const {
return m_pTrackCollectionManager->internalCollection()->getTrackById(getTrackId(index));
}
+TrackPointer BaseSqlTableModel::getTrackByRef(
+ const TrackRef& trackRef) const {
+ return m_pTrackCollectionManager->internalCollection()->getTrackByRef(trackRef);
+}
+
QString BaseSqlTableModel::getTrackLocation(const QModelIndex& index) const {
if (!index.isValid()) {
- return "";
+ return QString();
}
QString nativeLocation =
index.sibling(index.row(),
fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_NATIVELOCATION))
.data().toString();
- QString location = QDir::fromNativeSeparators(nativeLocation);
- return location;
+ return QDir::fromNativeSeparators(nativeLocation);
}
void BaseSqlTableModel::trackLoaded(QString group, TrackPointer pTrack) {
diff --git a/src/library/basesqltablemodel.h b/src/library/basesqltablemodel.h
index 017c6df095..55e3e0d38d 100644
--- a/src/library/basesqltablemodel.h
+++ b/src/library/basesqltablemodel.h
@@ -66,6 +66,7 @@ class BaseSqlTableModel : public QAbstractTableModel, public TrackModel {
///////////////////////////////////////////////////////////////////////////
bool isColumnHiddenByDefault(int column) override;
TrackPointer getTrack(const QModelIndex& index) const override;
+ TrackPointer getTrackByRef(const TrackRef& trackRef) const override;
TrackId getTrackId(const QModelIndex& index) const override;
const QLinkedList<int> getTrackRows(TrackId trackId) const override {
return m_trackIdToRows.value(trackId);
diff --git a/src/library/browse/browsetablemodel.cpp b/src/library/browse/browsetablemodel.cpp
index 085bc61810..13ea7d4d2d 100644
--- a/src/library/browse/browsetablemodel.cpp
+++ b/src/library/browse/browsetablemodel.cpp
@@ -154,13 +154,16 @@ void BrowseTableModel::setPath(const MDir& path) {
}
TrackPointer BrowseTableModel::getTrack(const QModelIndex& index) const {
- QString trackLocation = getTrackLocation(index);
- if (m_pRecordingManager->getRecordingLocation() == trackLocation) {
+ return getTrackByRef(TrackRef::fromFileInfo(getTrackLocation(index)));
+}
+
+TrackPointer BrowseTableModel::getTrackByRef(const TrackRef& trackRef) const {
+ if (m_pRecordingManager->getRecordingLocation() == trackRef.getLocation()) {
QMessageBox::critical(
0, tr("Mixxx Library"),
tr("Could not load the following file because"
" it is in use by Mixxx or another application.")
- + "\n" + trackLocation);
+ + "\n" + trackRef.getLocation());
return TrackPointer();
}
// NOTE(uklotzde, 2015-12-08): Accessing tracks from the browse view
@@ -171,8 +174,7 @@ TrackPointer BrowseTableModel::getTrack(const QModelIndex& index) const {
// them edit the tracks in a way that persists across sessions
// and we didn't want to edit the files on disk by default
// unless the user opts in to that.
- return m_pTrackCollectionManager->getOrAddTrack(
- TrackRef::fromFileInfo(trackLocation));
+ return m_pTrackCollectionManager->getOrAddTrack(trackRef);
}
QString BrowseTableModel::getTrackLocation(const QModelIndex& index) const {
diff --git a/src/library/browse/browsetablemodel.h b/src/library/browse/browsetablemodel.h
index 9a2256e746..0b61810f5d 100644
--- a/src/library/browse/browsetablemodel.h
+++ b/src/library/browse/browsetablemodel.h
@@ -51,6 +51,7 @@ class BrowseTableModel final : public QStandardItemModel, public virtual TrackMo
void setPath(const MDir& path);
TrackPointer getTrack(const QModelIndex& index) const override;
+ TrackPointer getTrackByRef(const TrackRef& trackRef) const override;
TrackModel::CapabilitiesFlags getCapabilities() const override;
QString getTrackLocation(const QModelIndex& index) const override;
diff --git a/src/library/coverart.cpp b/src/library/coverart.cpp
index b499cdc3bf..4e2e1ded37 100644
--- a/src/library/coverart.cpp
+++ b/src/library/coverart.cpp
@@ -1,6 +1,5 @@
-#include <QtDebug>
-
#include "library/coverart.h"
+
#include "library/coverartutils.h"
#include "util/debug.h"
#include "util/logger.h"
@@ -98,34 +97,42 @@ QImage CoverInfo::loadImage(
TrackFile(trackLocation),
pTrackLocationToken);
} else if (type == CoverInfo::FILE) {
- VERIFY_OR_DEBUG_ASSERT(!trackLocation.isEmpty()) {
- kLogger.warning()
- << "loadImage"
- << type
- << "cover with empty trackLocation."
- << "Relative paths will not work.";
- SecurityTokenPointer pToken =
- Sandbox::openSecurityToken(
- QFileInfo(coverLocation),
- true);
- return QImage(coverLocation);
+ auto coverFile = QFileInfo(coverLocation);
+ if (coverFile.isRelative()) {
+ VERIFY_OR_DEBUG_ASSERT(!trackLocation.isEmpty()) {
+ // This is not expected to happen, because every track
+ // must have a valid location, i.e. a file path. Most
+ // likely a programming error, but might also be caused
+ // by yet unknown circumstances.
+ kLogger.warning()
+ << "loadImage"
+ << type
+ << "cover with empty track location"
+ << "and relative file path:"
+ << coverFile.filePath();
+ return QImage();
+ }
+ // Compose track directory with relative path
+ const auto trackFile = TrackFile(trackLocation);
+ DEBUG_ASSERT(trackFile.asFileInfo().isAbsolute());
+ coverFile = QFileInfo(
+ trackFile.directory(),
+ coverLocation);
}
-
- const QFileInfo coverFile(
- TrackFile(trackLocation).directory(),
- coverLocation);
- const QString coverFilePath = coverFile.filePath();
+ DEBUG_ASSERT(coverFile.isAbsolute());
if (!coverFile.exists()) {
kLogger.warning()
<< "loadImage"
<< type
<< "cover does not exist:"
- << coverFilePath;
+ << coverFile.filePath();
return QImage();
}
SecurityTokenPointer pToken =
- Sandbox::openSecurityToken(coverFile, true);
- return QImage(coverFilePath);
+ Sandbox::openSecurityToken(
+ coverFile,
+ true);
+ return QImage(coverFile.filePath());
} else if (type == CoverInfo::NONE) {
return QImage();
} else {
@@ -134,6 +141,32 @@ QImage CoverInfo::loadImage(
}
}
+bool CoverInfo::refreshImageHash(
+ const QImage& loadedImage,
+ const SecurityTokenPointer& pTrackLocationToken) {
+ if (CoverImageUtils::isValidHash(hash)) {
+ // Trust that a valid hash has been calculated from the
+ // corresponding image. Otherwise we would refresh all
+ // hashes over and over again.
+ return false;
+ }
+ QImage image = loadedImage;
+ if (loadedImage.isNull()) {
+ image = loadImage(pTrackLocationToken);
+ }
+ if (image.isNull() && type != CoverInfo::NONE) {
+ kLogger.warning()
+ << "Resetting cover info"
+ << *this;
+ reset();
+ return true;
+ }
+ hash = CoverImageUtils::calculateHash(image);
+ DEBUG_ASSERT(image.isNull() || CoverImageUtils::isValidHash(hash));
+ DEBUG_ASSERT(!image.isNull() || hash == CoverImageUtils::defaultHash());
+ return true;
+}
+
bool operator==(const CoverInfo& a, const CoverInfo& b) {
return static_cast<const CoverInfoRelative&>(a) ==
static_cast<const CoverInfoRelative&>(b) &&
diff --git a/src/library/coverart.h b/src/library/coverart.h
index 9a79ecc344..d9179c3d08 100644
--- a/src/library/coverart.h
+++ b/src/library/coverart.h
@@ -52,6 +52,13 @@ class CoverInfoRelative {
CoverInfoRelative(CoverInfoRelative&&) = default;
CoverInfoRelative& operator=(CoverInfoRelative&&) = default;
+ /*non-virtual*/ void reset() {
+ // Slicing when invoked from a subclass is intended!
+ // Only the contents of this base class are supp