summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorUwe Klotz <uklotz@mixxx.org>2021-10-15 12:53:22 +0200
committerUwe Klotz <uklotz@mixxx.org>2021-10-15 12:53:22 +0200
commitc5030825a1b12af06bd481021b883bb1e85ba5ad (patch)
tree9ee48dcd9f9b32ccd9a08ae8dd2eff0648c31689 /src
parent8dfe5f60ff169b27f5d2c62e5c8b7cd456ab34f3 (diff)
parent79915d51e7d7e3e69f0cd2a381a8b89e9b6cb8cc (diff)
Merge branch 'main' of git@github.com:mixxxdj/mixxx.git into track-metadata-sync
Diffstat (limited to 'src')
-rw-r--r--src/controllers/controlpickermenu.cpp4
-rw-r--r--src/coreservices.cpp7
-rw-r--r--src/dialog/dlgkeywheel.cpp7
-rw-r--r--src/encoder/encoderfdkaac.cpp14
-rw-r--r--src/engine/controls/bpmcontrol.cpp36
-rw-r--r--src/engine/controls/loopingcontrol.cpp6
-rw-r--r--src/engine/sync/enginesync.cpp13
-rw-r--r--src/library/dao/playlistdao.cpp2
-rw-r--r--src/library/dlgtrackinfo.cpp28
-rw-r--r--src/library/dlgtrackinfo.h1
-rw-r--r--src/library/library.h5
-rw-r--r--src/library/parsercsv.cpp13
-rw-r--r--src/library/parserm3u.cpp125
-rw-r--r--src/library/parserm3u.h6
-rw-r--r--src/library/sidebarmodel.cpp11
-rw-r--r--src/library/sidebarmodel.h1
-rw-r--r--src/library/trackset/setlogfeature.cpp2
-rw-r--r--src/main.cpp12
-rw-r--r--src/mixer/basetrackplayer.h1
-rw-r--r--src/mixer/playermanager.cpp64
-rw-r--r--src/mixer/playermanager.h1
-rw-r--r--src/mixxxapplication.cpp6
-rw-r--r--src/mixxxapplication.h2
-rw-r--r--src/mixxxmainwindow.cpp38
-rw-r--r--src/preferences/broadcastsettings.cpp2
-rw-r--r--src/preferences/broadcastsettingsmodel.cpp4
-rw-r--r--src/preferences/configobject.cpp9
-rw-r--r--src/preferences/dialog/dlgprefsounditem.cpp12
-rw-r--r--src/qml/qmlcontrolproxy.h2
-rw-r--r--src/qml/qmllibraryproxy.cpp5
-rw-r--r--src/qml/qmllibraryproxy.h5
-rw-r--r--src/soundio/soundmanagerconfig.cpp3
-rw-r--r--src/sources/soundsource.cpp2
-rw-r--r--src/test/beatgridtest.cpp12
-rw-r--r--src/test/beatmaptest.cpp12
-rw-r--r--src/test/controller_mapping_validation_test.cpp3
-rw-r--r--src/test/soundproxy_test.cpp24
-rw-r--r--src/track/beatgrid.cpp17
-rw-r--r--src/track/beatgrid.h6
-rw-r--r--src/track/beatmap.cpp14
-rw-r--r--src/track/beatmap.h6
-rw-r--r--src/track/beats.h16
-rw-r--r--src/track/keyfactory.cpp2
-rw-r--r--src/track/keys.h4
-rw-r--r--src/track/serato/tags.cpp2
-rw-r--r--src/track/track.cpp10
-rw-r--r--src/util/cache.cpp8
-rw-r--r--src/util/db/dbid.cpp4
-rw-r--r--src/util/db/dbid.h2
-rw-r--r--src/util/desktophelper.h2
-rw-r--r--src/util/movinginterquartilemean.h1
-rw-r--r--src/util/versionstore.cpp4
-rw-r--r--src/waveform/visualsmanager.h16
-rw-r--r--src/widget/wtrackmenu.cpp6
54 files changed, 342 insertions, 278 deletions
diff --git a/src/controllers/controlpickermenu.cpp b/src/controllers/controlpickermenu.cpp
index ecef8b161e..973264201d 100644
--- a/src/controllers/controlpickermenu.cpp
+++ b/src/controllers/controlpickermenu.cpp
@@ -874,10 +874,10 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent)
for (int iSamplerNumber = 1; iSamplerNumber <= iNumSamplers;
++iSamplerNumber) {
// PlayerManager::groupForSampler is 0-indexed.
- QString playerGroup = PlayerManager::groupForSampler(iSamplerNumber - 1);
+ QString samplerGroup = PlayerManager::groupForSampler(iSamplerNumber - 1);
// TODO(owen): Fix bad i18n here.
addControl(effectUnitGroup,
- QString("group_%1_enable").arg(playerGroup),
+ QString("group_%1_enable").arg(samplerGroup),
assignString + m_samplerStr.arg(iSamplerNumber),
assignString + m_samplerStr.arg(iSamplerNumber),
effectUnitGroups,
diff --git a/src/coreservices.cpp b/src/coreservices.cpp
index eddcf83598..3abfef8045 100644
--- a/src/coreservices.cpp
+++ b/src/coreservices.cpp
@@ -3,6 +3,7 @@
#include <QApplication>
#include <QFileDialog>
#include <QPushButton>
+#include <QStandardPaths>
#ifdef __BROADCAST__
#include "broadcast/broadcastmanager.h"
@@ -42,7 +43,7 @@
#include "util/sandbox.h"
#endif
-#if defined(Q_OS_LINUX)
+#if defined(Q_OS_LINUX) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
#include <X11/Xlib.h>
#include <X11/Xlibint.h>
@@ -74,7 +75,7 @@ void clearHelper(std::shared_ptr<T>& ref_ptr, const char* name) {
// hack around https://gitlab.freedesktop.org/xorg/lib/libx11/issues/25
// https://bugs.launchpad.net/mixxx/+bug/1805559
-#if defined(Q_OS_LINUX)
+#if defined(Q_OS_LINUX) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
typedef Bool (*WireToErrorType)(Display*, XErrorEvent*, xError*);
constexpr int NUM_HANDLERS = 256;
@@ -218,7 +219,7 @@ void CoreServices::initialize(QApplication* pApp) {
VersionStore::logBuildDetails();
-#if defined(Q_OS_LINUX)
+#if defined(Q_OS_LINUX) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
// XESetWireToError will segfault if running as a Wayland client
if (pApp->platformName() == QLatin1String("xcb")) {
for (auto i = 0; i < NUM_HANDLERS; ++i) {
diff --git a/src/dialog/dlgkeywheel.cpp b/src/dialog/dlgkeywheel.cpp
index e05e075f55..af1126f021 100644
--- a/src/dialog/dlgkeywheel.cpp
+++ b/src/dialog/dlgkeywheel.cpp
@@ -155,7 +155,12 @@ void DlgKeywheel::updateSvg() {
if (text.isText()) {
QDomText textNode = text.toText();
- ChromaticKey key = static_cast<ChromaticKey>(id.midRef(2).toInt());
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ const int keyInt = QStringView(id).sliced(2).toInt();
+#else
+ const int keyInt = id.midRef(2).toInt();
+#endif
+ ChromaticKey key = static_cast<ChromaticKey>(keyInt);
QString keyString = KeyUtils::keyToString(key, m_notation);
textNode.setData(keyString);
}
diff --git a/src/encoder/encoderfdkaac.cpp b/src/encoder/encoderfdkaac.cpp
index fef01f1de7..49871386d7 100644
--- a/src/encoder/encoderfdkaac.cpp
+++ b/src/encoder/encoderfdkaac.cpp
@@ -165,7 +165,7 @@ EncoderFdkAac::~EncoderFdkAac() {
}
delete[] m_pAacDataBuffer;
- delete m_pFifoChunkBuffer;
+ delete[] m_pFifoChunkBuffer;
delete m_pInputFifo;
}
@@ -283,6 +283,10 @@ int EncoderFdkAac::initEncoder(mixxx::audio::SampleRate sampleRate, QString* pUs
// This initializes the encoder handle but not the encoder itself.
// Actual encoder init is done below.
aacEncOpen(&m_aacEnc, 0, m_channels);
+ VERIFY_OR_DEBUG_ASSERT(!m_pAacDataBuffer) {
+ delete[] m_pAacDataBuffer;
+ m_pAacDataBuffer = nullptr;
+ }
m_pAacDataBuffer = new unsigned char[kOutBufferBits * m_channels]();
// AAC Object Type: specifies "mode": AAC-LC, HE-AAC, HE-AACv2, DAB AAC, etc...
@@ -345,8 +349,16 @@ int EncoderFdkAac::initEncoder(mixxx::audio::SampleRate sampleRate, QString* pUs
// This is set to the buffer size of the sidechain engine because
// Recording (which uses this engine) sends more samples at once to the encoder than
// the Live Broadcasting implementation
+ VERIFY_OR_DEBUG_ASSERT(!m_pInputFifo) {
+ delete m_pInputFifo;
+ m_pInputFifo = nullptr;
+ }
m_pInputFifo = new FIFO<SAMPLE>(EngineSideChain::SIDECHAIN_BUFFER_SIZE * 2);
+ VERIFY_OR_DEBUG_ASSERT(!m_pFifoChunkBuffer) {
+ delete[] m_pFifoChunkBuffer;
+ m_pFifoChunkBuffer = nullptr;
+ }
m_pFifoChunkBuffer = new SAMPLE[m_readRequired * sizeof(SAMPLE)]();
return 0;
}
diff --git a/src/engine/controls/bpmcontrol.cpp b/src/engine/controls/bpmcontrol.cpp
index 76dc2a591e..bc3383ae10 100644
--- a/src/engine/controls/bpmcontrol.cpp
+++ b/src/engine/controls/bpmcontrol.cpp
@@ -162,7 +162,11 @@ void BpmControl::adjustBeatsBpm(double deltaBpm) {
const auto centerBpm = mixxx::Bpm(math_max(kBpmAdjustMin, bpm.value() + deltaBpm));
mixxx::Bpm adjustedBpm = BeatUtils::roundBpmWithinRange(
centerBpm - kBpmAdjustStep / 2, centerBpm, centerBpm + kBpmAdjustStep / 2);
- pTrack->trySetBeats(pBeats->setBpm(adjustedBpm));
+ const auto newBeats = pBeats->trySetBpm(adjustedBpm);
+ if (!newBeats) {
+ return;
+ }
+ pTrack->trySetBeats(*newBeats);
}
void BpmControl::slotAdjustBeatsFaster(double v) {
@@ -191,7 +195,10 @@ void BpmControl::slotTranslateBeatsEarlier(double v) {
if (pBeats) {
const double sampleOffset = frameInfo().sampleRate * -0.01;
const mixxx::audio::FrameDiff_t frameOffset = sampleOffset / mixxx::kEngineChannelCount;
- pTrack->trySetBeats(pBeats->translate(frameOffset));
+ const auto translatedBeats = pBeats->tryTranslate(frameOffset);
+ if (translatedBeats) {
+ pTrack->trySetBeats(*translatedBeats);
+ }
}
}
@@ -208,7 +215,10 @@ void BpmControl::slotTranslateBeatsLater(double v) {
// TODO(rryan): Track::frameInfo is possibly inaccurate!
const double sampleOffset = frameInfo().sampleRate * 0.01;
const mixxx::audio::FrameDiff_t frameOffset = sampleOffset / mixxx::kEngineChannelCount;
- pTrack->trySetBeats(pBeats->translate(frameOffset));
+ const auto translatedBeats = pBeats->tryTranslate(frameOffset);
+ if (translatedBeats) {
+ pTrack->trySetBeats(*translatedBeats);
+ }
}
}
@@ -245,7 +255,11 @@ void BpmControl::slotTapFilter(double averageLength, int numSamples) {
averageBpm = BeatUtils::roundBpmWithinRange(averageBpm - kBpmTabRounding,
averageBpm,
averageBpm + kBpmTabRounding);
- pTrack->trySetBeats(pBeats->setBpm(averageBpm));
+ const auto newBeats = pBeats->trySetBpm(averageBpm);
+ if (!newBeats) {
+ return;
+ }
+ pTrack->trySetBeats(*newBeats);
}
// static
@@ -961,8 +975,11 @@ void BpmControl::slotBeatsTranslate(double v) {
if (pBeats) {
const auto currentPosition = frameInfo().currentPosition.toLowerFrameBoundary();
const auto closestBeat = pBeats->findClosestBeat(currentPosition);
- const mixxx::audio::FrameDiff_t delta = currentPosition - closestBeat;
- pTrack->trySetBeats(pBeats->translate(delta));
+ const mixxx::audio::FrameDiff_t frameOffset = currentPosition - closestBeat;
+ const auto translatedBeats = pBeats->tryTranslate(frameOffset);
+ if (translatedBeats) {
+ pTrack->trySetBeats(*translatedBeats);
+ }
}
}
@@ -980,8 +997,11 @@ void BpmControl::slotBeatsTranslateMatchAlignment(double v) {
// otherwise it will always return 0 if sync lock is active.
m_dUserOffset.setValue(0.0);
- const mixxx::audio::FrameDiff_t frameOffset = getPhaseOffset(frameInfo().currentPosition);
- pTrack->trySetBeats(pBeats->translate(-frameOffset));
+ const mixxx::audio::FrameDiff_t frameOffset = -getPhaseOffset(frameInfo().currentPosition);
+ const auto translatedBeats = pBeats->tryTranslate(frameOffset);
+ if (translatedBeats) {
+ pTrack->trySetBeats(*translatedBeats);
+ }
}
}
diff --git a/src/engine/controls/loopingcontrol.cpp b/src/engine/controls/loopingcontrol.cpp
index 2f449e5df2..069fc80284 100644
--- a/src/engine/controls/loopingcontrol.cpp
+++ b/src/engine/controls/loopingcontrol.cpp
@@ -1124,7 +1124,11 @@ void LoopingControl::slotBeatLoopDeactivate(BeatLoopingControl* pBeatLoopControl
void LoopingControl::slotBeatLoopDeactivateRoll(BeatLoopingControl* pBeatLoopControl) {
pBeatLoopControl->deactivate();
const double size = pBeatLoopControl->getSize();
- auto* i = m_activeLoopRolls.begin();
+ // clang-tidy wants auto to be auto* because QStack inherits from QVector
+ // and QVector::iterator is a pointer type in Qt5, but QStack inherits
+ // from QList in Qt6 so QStack::iterator is not a pointer type in Qt6.
+ // NOLINTNEXTLINE(readability-qualified-auto)
+ auto i = m_activeLoopRolls.begin();
while (i != m_activeLoopRolls.end()) {
if (size == *i) {
i = m_activeLoopRolls.erase(i);
diff --git a/src/engine/sync/enginesync.cpp b/src/engine/sync/enginesync.cpp
index 78a111f159..f8c564da52 100644
--- a/src/engine/sync/enginesync.cpp
+++ b/src/engine/sync/enginesync.cpp
@@ -369,10 +369,10 @@ void EngineSync::notifyPlayingAudible(Syncable* pSyncable, bool playingAudible)
} else {
Syncable* pOnlyPlayer = getUniquePlayingSyncedDeck();
if (pOnlyPlayer) {
- // Even if we didn't change leader, if there is only one player (us), then we should
- // update the beat distance.
+ // Even if we didn't change leader, if there is only one player, then we should
+ // reinit leader params.
pOnlyPlayer->notifyUniquePlaying();
- updateLeaderBeatDistance(pOnlyPlayer, pOnlyPlayer->getBeatDistance());
+ reinitLeaderParams(pOnlyPlayer);
}
}
}
@@ -446,6 +446,9 @@ void EngineSync::notifyBeatDistanceChanged(Syncable* pSyncable, double beatDista
<< pSyncable->getGroup() << beatDistance;
}
if (pSyncable != m_pInternalClock) {
+ if (getUniquePlayingSyncedDeck() == pSyncable) {
+ updateLeaderBeatDistance(pSyncable, beatDistance);
+ }
return;
}
@@ -654,6 +657,10 @@ void EngineSync::reinitLeaderParams(Syncable* pSource) {
mixxx::Bpm bpm = pSource->getBpm();
if (!bpm.isValid()) {
bpm = baseBpm;
+ if (!bpm.isValid()) {
+ // This happens if the deck is the only playing one but the track has no beats
+ return;
+ }
}
if (kLogger.traceEnabled()) {
kLogger.trace() << "BaseSyncableListener::reinitLeaderParams, source is"
diff --git a/src/library/dao/playlistdao.cpp b/src/library/dao/playlistdao.cpp
index c3ed470cce..beefa35028 100644
--- a/src/library/dao/playlistdao.cpp
+++ b/src/library/dao/playlistdao.cpp
@@ -966,7 +966,7 @@ void PlaylistDAO::shuffleTracks(const int playlistId,
QHash<int, TrackId> trackPositionIds = allIds;
QList<int> newPositions = positions;
- const int searchDistance = math_max(trackPositionIds.count() / 4, 1);
+ const int searchDistance = math_max(static_cast<int>(trackPositionIds.count()) / 4, 1);
qDebug() << "Shuffling Tracks";
qDebug() << "*** Search Distance: " << searchDistance;
diff --git a/src/library/dlgtrackinfo.cpp b/src/library/dlgtrackinfo.cpp
index 21aacb01c5..c33d3e7b36 100644
--- a/src/library/dlgtrackinfo.cpp
+++ b/src/library/dlgtrackinfo.cpp
@@ -520,33 +520,35 @@ void DlgTrackInfo::clear() {
}
void DlgTrackInfo::slotBpmDouble() {
- m_pBeatsClone = m_pBeatsClone->scale(mixxx::Beats::BpmScale::Double);
- updateSpinBpmFromBeats();
+ slotBpmScale(mixxx::Beats::BpmScale::Double);
}
void DlgTrackInfo::slotBpmHalve() {
- m_pBeatsClone = m_pBeatsClone->scale(mixxx::Beats::BpmScale::Halve);
- updateSpinBpmFromBeats();
+ slotBpmScale(mixxx::Beats::BpmScale::Halve);
}
void DlgTrackInfo::slotBpmTwoThirds() {
- m_pBeatsClone = m_pBeatsClone->scale(mixxx::Beats::BpmScale::TwoThirds);
- updateSpinBpmFromBeats();
+ slotBpmScale(mixxx::Beats::BpmScale::TwoThirds);
}
void DlgTrackInfo::slotBpmThreeFourth() {
- m_pBeatsClone = m_pBeatsClone->scale(mixxx::Beats::BpmScale::ThreeFourths);
- updateSpinBpmFromBeats();
+ slotBpmScale(mixxx::Beats::BpmScale::ThreeFourths);
}
void DlgTrackInfo::slotBpmFourThirds() {
- m_pBeatsClone = m_pBeatsClone->scale(mixxx::Beats::BpmScale::FourThirds);
- updateSpinBpmFromBeats();
+ slotBpmScale(mixxx::Beats::BpmScale::FourThirds);
}
void DlgTrackInfo::slotBpmThreeHalves() {
- m_pBeatsClone = m_pBeatsClone->scale(mixxx::Beats::BpmScale::ThreeHalves);
- updateSpinBpmFromBeats();
+ slotBpmScale(mixxx::Beats::BpmScale::ThreeHalves);
+}
+
+void DlgTrackInfo::slotBpmScale(mixxx::Beats::BpmScale bpmScale) {
+ const auto scaledBeats = m_pBeatsClone->tryScale(bpmScale);
+ if (scaledBeats) {
+ m_pBeatsClone = *scaledBeats;
+ updateSpinBpmFromBeats();
+ }
}
void DlgTrackInfo::slotBpmClear() {
@@ -610,7 +612,7 @@ void DlgTrackInfo::slotSpinBpmValueChanged(double value) {
if (oldValue == bpm) {
return;
}
- m_pBeatsClone = m_pBeatsClone->setBpm(bpm);
+ m_pBeatsClone = m_pBeatsClone->trySetBpm(bpm).value_or(m_pBeatsClone);
}
updateSpinBpmFromBeats();
diff --git a/src/library/dlgtrackinfo.h b/src/library/dlgtrackinfo.h
index 2cb9d01011..b1a6be573e 100644
--- a/src/library/dlgtrackinfo.h
+++ b/src/library/dlgtrackinfo.h
@@ -57,6 +57,7 @@ class DlgTrackInfo : public QDialog, public Ui::DlgTrackInfo {
void slotBpmThreeFourth();
void slotBpmFourThirds();
void slotBpmThreeHalves();
+ void slotBpmScale(mixxx::Beats::BpmScale bpmScale);
void slotBpmClear();
void slotBpmConstChanged(int state);
void slotBpmTap(double averageLength, int numSamples);
diff --git a/src/library/library.h b/src/library/library.h
index 3c6cf53291..83dda1bb1c 100644
--- a/src/library/library.h
+++ b/src/library/library.h
@@ -75,11 +75,6 @@ class Library: public QObject {
/// Needed for exposing models to QML
LibraryTableModel* trackTableModel() const;
- /// Needed for exposing sidebar to QML
- SidebarModel* sidebarModel() const {
- return m_pSidebarModel.get();
- }
-
int getTrackTableRowHeight() const {
return m_iTrackTableRowHeight;
}
diff --git a/src/library/parsercsv.cpp b/src/library/parsercsv.cpp
index 41f411d6f1..f34e5ea2d6 100644
--- a/src/library/parsercsv.cpp
+++ b/src/library/parsercsv.cpp
@@ -50,7 +50,7 @@ QList<QString> ParserCsv::parse(const QString& sFilename) {
for (int i = 1; i < tokens.size(); ++i) {
if (loc_coll < tokens[i].size()) {
// Todo: check if path is relative
- QFileInfo fi = tokens[i][loc_coll];
+ QFileInfo fi(tokens[i][loc_coll]);
if (fi.isRelative()) {
// add base path
qDebug() << "is relative" << basepath << fi.filePath();
@@ -140,9 +140,14 @@ bool ParserCsv::writeCSVFile(const QString &file_str, BaseSqlTableModel* pPlayli
qDebug() << "Basepath: " << base;
QTextStream out(&file);
- out.setCodec("UTF-8"); // rfc4180: Common usage of CSV is US-ASCII ...
- // Using UTF-8 to get around codepage issues
- // and it's the default encoding in Ooo Calc
+ // rfc4180: Common usage of CSV is US-ASCII ...
+ // Using UTF-8 to get around codepage issues
+ // and it's the default encoding in Ooo Calc
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ DEBUG_ASSERT(out.encoding() == QStringConverter::Utf8);
+#else
+ out.setCodec("UTF-8");
+#endif
// writing header section
bool first = true;
diff --git a/src/library/parserm3u.cpp b/src/library/parserm3u.cpp
index 797dd88d7d..d07c2a326e 100644
--- a/src/library/parserm3u.cpp
+++ b/src/library/parserm3u.cpp
@@ -21,6 +21,12 @@
#include "moc_parserm3u.cpp"
+namespace {
+// according to http://en.wikipedia.org/wiki/M3U the default encoding of m3u is Windows-1252
+// see also http://tools.ietf.org/html/draft-pantos-http-live-streaming-07
+const char* kStandardM3uTextEncoding = "Windows-1250";
+} // anonymous namespace
+
/**
ToDo:
- parse ALL information from the pls file if available ,
@@ -45,15 +51,15 @@ ParserM3u::~ParserM3u()
}
-QList<QString> ParserM3u::parse(const QString& sFilename) {
- clearLocations();
+QList<QString> ParserM3u::parse(const QString& filename) {
+ QList<QString> paths;
- QFile file(sFilename);
+ QFile file(filename);
if (!file.open(QIODevice::ReadOnly)) {
qWarning()
<< "Failed to open playlist file"
- << sFilename;
- return m_sLocations;
+ << filename;
+ return paths;
}
// Unfortunately QTextStream does not handle <CR> (=\r or asci value 13) line breaks.
@@ -63,49 +69,36 @@ QList<QString> ParserM3u::parse(const QString& sFilename) {
// Using QFile::readAll() we obtain the complete content of the playlist as a ByteArray.
// We replace any '\r' with '\n' if applicaple
// This ensures that playlists from iTunes on OS X can be parsed
- QByteArray ba = file.readAll();
+ QByteArray byteArray = file.readAll();
//detect encoding
- bool isCRLF_encoded = ba.contains("\r\n");
- bool isCR_encoded = ba.contains("\r");
+ bool isCRLF_encoded = byteArray.contains("\r\n");
+ bool isCR_encoded = byteArray.contains("\r");
if (isCR_encoded && !isCRLF_encoded) {
- ba.replace('\r', '\n');
+ byteArray.replace('\r', '\n');
}
- QTextStream textstream(ba.constData());
- if (isUtf8(ba.constData())) {
- textstream.setCodec("UTF-8");
+ QString fileContents;
+ if (isUtf8(byteArray.constData())) {
+ fileContents = QString::fromUtf8(byteArray);
} else {
- textstream.setCodec("windows-1252");
+ // FIXME: replace deprecated QTextCodec with direct usage of libicu
+ fileContents = QTextCodec::codecForName(kStandardM3uTextEncoding)
+ ->toUnicode(byteArray);
}
- const auto basePath = sFilename.section('/', 0, -2);
- while (!textstream.atEnd()) {
- QString sLine = getFilePath(&textstream, basePath);
- if (sLine.isEmpty()) {
- continue;
- }
- m_sLocations.append(sLine);
- }
-
- return m_sLocations;
-}
-
-QString ParserM3u::getFilePath(QTextStream* stream, const QString& basePath) {
- QString textline;
- while (!(textline = stream->readLine().trimmed()).isEmpty()) {
- if (textline.startsWith("#")) {
- // Skip comments
- continue;
- }
- auto trackFile = playlistEntryToFileInfo(textline, basePath);
+ QFileInfo fileInfo(filename);
+ const QStringList fileLines = fileContents.split('\n');
+ for (const QString& line : fileLines) {
+ auto trackFile = playlistEntryToFileInfo(line, fileInfo.canonicalPath());
if (trackFile.checkFileExists()) {
- return trackFile.location();
+ paths.append(trackFile.location());
+ } else {
+ qInfo() << "File" << trackFile.location() << "from M3U playlist"
+ << filename << "does not exist.";
}
- // We couldn't match this to a real file so ignore it
- qWarning() << trackFile << "not found";
}
- // Signal we reached the end
- return QString();
+
+ return paths;
}
bool ParserM3u::writeM3UFile(const QString &file_str, const QList<QString> &items, bool useRelativePath) {
@@ -122,26 +115,25 @@ bool ParserM3u::writeM3UFile(const QString &file_str, const QList<QString> &item
// On Windows \n will produce a <CR><CL> (=\r\n)<