diff options
author | Jan Holthuis <jan.holthuis@ruhr-uni-bochum.de> | 2020-03-09 11:14:37 +0100 |
---|---|---|
committer | Jan Holthuis <jan.holthuis@ruhr-uni-bochum.de> | 2020-03-09 11:17:55 +0100 |
commit | 20ce76f02f5c67190e5dcc2575656a31083658c6 (patch) | |
tree | d933204664affc85cb415fce2355c3f90157427b /src | |
parent | 90b1109d32edad4c055c01406e0cfadfb5939b39 (diff) | |
parent | 7a3095d87adb27e7d6a162b1cd0f0f376eb474f7 (diff) |
Merge branch 'master' of github.com:mixxxdj/mixxx into hotcue-rgb-colors
Diffstat (limited to 'src')
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ébastien Blaisot"; + << "Sé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ü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ß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 |