Skip to content
Open
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
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1388,6 +1388,7 @@ add_library(
src/library/coverart.cpp
src/library/coverartcache.cpp
src/library/coverartutils.cpp
src/library/dateformatbroadcaster.cpp
src/library/dao/analysisdao.cpp
src/library/dao/autodjcratesdao.cpp
src/library/dao/cuedao.cpp
Expand Down
36 changes: 35 additions & 1 deletion src/library/basetracktablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "base/Pitch.h"
#include "library/coverartcache.h"
#include "library/dao/trackschema.h"
#include "library/dateformatbroadcaster.h"
#include "library/starrating.h"
#include "library/tabledelegates/bpmdelegate.h"
#include "library/tabledelegates/checkboxdelegate.h"
Expand Down Expand Up @@ -111,15 +112,42 @@ void BaseTrackTableModel::setKeyColorPalette(const ColorPalette& palette) {
bool BaseTrackTableModel::s_bApplyPlayedTrackColor =
kApplyPlayedTrackColorDefault;

// static
void BaseTrackTableModel::setApplyPlayedTrackColor(bool apply) {
s_bApplyPlayedTrackColor = apply;
}

const QString BaseTrackTableModel::kDateFormatDefault = QString();
QString BaseTrackTableModel::s_dateFormat = BaseTrackTableModel::kDateFormatDefault;

// static
void BaseTrackTableModel::setDateFormat(const QString& format) {
s_dateFormat = format;
if (format != s_dateFormat) {
s_dateFormat = format;
auto* broadcaster = DateFormatChangedBroadcaster::instance();
emit broadcaster->dateFormatChanged();
}
}

void BaseTrackTableModel::slotEmitDataChangedForDateColumns() {
// Notify the view to update.
// These are the columns that use s_dateFormat
QList<int> columns;
columns.append(fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_DATETIMEADDED));
columns.append(fieldIndex(ColumnCache::COLUMN_PLAYLISTTRACKSTABLE_DATETIMEADDED));
columns.append(fieldIndex(ColumnCache::COLUMN_LIBRARYTABLE_LAST_PLAYED_AT));
const QVector<int> roles{Qt::DisplayRole};
QModelIndex topLeft;
QModelIndex bottomRight;
for (int i : columns) {
if (i == -1) {
// Skip if a certain model doesn't have this column
continue;
}
topLeft = index(0, i);
bottomRight = index(rowCount() - 1, i);
emit dataChanged(topLeft, bottomRight, roles);
}
}

BaseTrackTableModel::BaseTrackTableModel(
Expand Down Expand Up @@ -148,6 +176,12 @@ BaseTrackTableModel::BaseTrackTableModel(
this,
&BaseTrackTableModel::slotCoverFound);
}

auto* dateFormatBroadcaster = DateFormatChangedBroadcaster::instance();
connect(dateFormatBroadcaster,
&DateFormatChangedBroadcaster::dateFormatChanged,
this,
&BaseTrackTableModel::slotEmitDataChangedForDateColumns);
}

void BaseTrackTableModel::initTableColumnsAndHeaderProperties(
Expand Down
7 changes: 7 additions & 0 deletions src/library/basetracktablemodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,9 @@ class BaseTrackTableModel : public QAbstractTableModel, public TrackModel {

static const QString kDateFormatDefault;
static void setDateFormat(const QString& format);
static QString dateFormat() {
return s_dateFormat;
}

protected:
// Build a map from the column names to their indices
Expand Down Expand Up @@ -277,6 +280,10 @@ class BaseTrackTableModel : public QAbstractTableModel, public TrackModel {
const CoverInfo& coverInfo,
const QPixmap& pixmap);

/// Called via signal from DateFormatChangedBroadcaster,
/// will tell the view(s) to repaint date columns when visible
void slotEmitDataChangedForDateColumns();

private:
QVariant rawSiblingValue(
const QModelIndex& index,
Expand Down
6 changes: 6 additions & 0 deletions src/library/dateformatbroadcaster.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include "library/dateformatbroadcaster.h"

#include "moc_dateformatbroadcaster.cpp"

DateFormatChangedBroadcaster::DateFormatChangedBroadcaster() {
}
19 changes: 19 additions & 0 deletions src/library/dateformatbroadcaster.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once

#include <QObject>

#include "util/singleton.h"

class DateFormatChangedBroadcaster
: public QObject,
public Singleton<DateFormatChangedBroadcaster> {
Q_OBJECT
public:
signals:
void dateFormatChanged();

protected:
DateFormatChangedBroadcaster();
~DateFormatChangedBroadcaster() override = default;
friend class Singleton<DateFormatChangedBroadcaster>;
};
7 changes: 6 additions & 1 deletion src/library/library.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "library/autodj/autodjfeature.h"
#include "library/banshee/bansheefeature.h"
#include "library/browse/browsefeature.h"
#include "library/dateformatbroadcaster.h"
#ifdef __ENGINEPRIME__
#include "library/export/libraryexporter.h"
#endif
Expand Down Expand Up @@ -76,6 +77,8 @@ Library::Library(
mixxx::library::prefs::kKeyNotationConfigKey)) {
qRegisterMetaType<LibraryRemovalType>("LibraryRemovalType");

DateFormatChangedBroadcaster::createInstance();

connect(m_pTrackCollectionManager,
&TrackCollectionManager::libraryScanFinished,
this,
Expand Down Expand Up @@ -269,7 +272,9 @@ Library::Library(
kEditMetadataSelectedClickDefault);
}

Library::~Library() = default;
Library::~Library() {
DateFormatChangedBroadcaster::destroy();
}

TrackCollectionManager* Library::trackCollectionManager() const {
// Cannot be implemented inline due to forward declarations
Expand Down
41 changes: 35 additions & 6 deletions src/library/searchquery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <QLocale>
#include <QRegularExpression>

#include "library/basetracktablemodel.h"
#include "library/dao/trackschema.h"
#include "library/queryutil.h"
#include "library/trackset/crate/crateschema.h"
Expand Down Expand Up @@ -900,24 +901,52 @@ DateAddedFilterNode::DateAddedFilterNode(const QString& argument)

QDateTime DateAddedFilterNode::parseDate(const QString& dateStr) const {
// Try ISO format first (YYYY-MM-DD)
// This is used by the "New" filter of the Analyze feature
qWarning() << "--> parse date" << dateStr;
QDate date = QDate::fromString(dateStr, Qt::ISODate);

if (!date.isValid()) {
// Try user date format set in library preferences
const QString dateFormat = BaseTrackTableModel::dateFormat();
qWarning() << "--> invalid, try Lib format" << dateFormat;
#if QT_VERSION < QT_VERSION_CHECK(6, 7, 0)
date = QDate::fromString(dateStr, dateFormat);
Comment on lines +909 to +913

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, fixed

Comment thread
ronso0 marked this conversation as resolved.
// The Mixxx project was started in 2001 :)
if (date.isValid() && date.year() < 2000) {
qWarning() << "--> -> year" << date.year() << "< 2000, add 100";
date = date.addYears(100);
qWarning() << "--> -> year < 2000, add 100" << date;
}
#else
date = QDate::fromString(dateStr, dateFormat, 2000);
#endif
}

if (!date.isValid()) {
qWarning() << "--> invalid, try locale format"
<< QLocale().dateFormat(QLocale::ShortFormat);
// Maybe custom user format is too esoteric, or user picked
// their locale's format.
// Fall back to locale-specific short format
#if QT_VERSION < QT_VERSION_CHECK(6, 7, 0)
// If the year component has only two digits Qt assumes the base year is 1900.
date = QLocale().toDate(dateStr, QLocale::ShortFormat);
// The Mixxx project was started in 2001 :)
if (date.isValid() && date.year() < 2000) {
qWarning() << "--> -> year" << date.year() << "< 2000, add 100";
date = date.addYears(100);
}
#else
date = QLocale().toDate(dateStr, QLocale::ShortFormat, 20);
// With Qt 6.7+ we need to specify the base year.
date = QLocale().toDate(dateStr, QLocale::ShortFormat, 2001);
Comment on lines +909 to +941

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, there is NO date filter test. And I'm not motivated to write one atm.
Let's stick to manual testing (and Copilot) whenever the date filter is touched.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And I have no clue how to involve BaseTrackTableModel into the test 🤷‍♂️

#endif
}
if (!date.isValid()) {
qWarning() << "--> invalid, return";
return {};
}
qWarning() << "--> valid date:" << date;

if (date.year() < 2000) {
date = date.addYears(100);
}

// Return local date/time, don't convert to UTC, yet
return QDateTime(date, QTime(0, 0)).toUTC();
}

Expand Down
67 changes: 35 additions & 32 deletions src/preferences/dialog/dlgpreflibrary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,39 +341,39 @@ void DlgPrefLibrary::slotUpdate() {
checkBox_show_serato->setChecked(m_pConfig->getValue(
ConfigKey("[Library]", "ShowSeratoLibrary"), true));

QString dateFormat = m_pConfig->getValue(
m_dateFormat = m_pConfig->getValue(
kDateFormatConfigKey,
BaseTrackTableModel::kDateFormatDefault);
qWarning() << "slotUpdate, dateformat:" << m_dateFormat;
Comment thread
ronso0 marked this conversation as resolved.

// Determine the matching preset or custom
BaseTrackTableModel::DateFormat preset = BaseTrackTableModel::DateFormat::Custom;
if (dateFormat.isEmpty()) {
if (m_dateFormat.isEmpty()) {
preset = BaseTrackTableModel::DateFormat::Native;
} else if (dateFormat == QStringLiteral("yyyy-MM-dd")) {
} else if (m_dateFormat == QStringLiteral("yyyy-MM-dd")) {
preset = BaseTrackTableModel::DateFormat::ISO8601;
} else if (dateFormat == QStringLiteral("d/M/yy")) {
} else if (m_dateFormat == QStringLiteral("d/M/yy")) {
preset = BaseTrackTableModel::DateFormat::RegionalShort;
} else if (dateFormat == QStringLiteral("dd.MM.yyyy")) {
} else if (m_dateFormat == QStringLiteral("dd.MM.yyyy")) {
preset = BaseTrackTableModel::DateFormat::RegionalLong;
} else {
m_lastCustomDateFormat = m_dateFormat;
qWarning() << "-> type: Custom";
qWarning() << "-> store last custom format:" << m_lastCustomDateFormat;
}

int dateIndex = comboBox_dateFormat->findData(QVariant::fromValue(preset));
qWarning() << "-> idx:" << dateIndex;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these warnings look more like debug comments. The mixxx warning log is already very noisy, try to be efficient and minimal in your logging output, with as few lines as possible and identifying information in the line about what's being logged. Probably these can all be totally removed.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's from the TRACE commit which is of course removed before merge.

The other commits look good?
Did you test it?

if (dateIndex != -1) {
qWarning() << "-> setCurrIdx";
const QSignalBlocker signalBlocker(comboBox_dateFormat);
comboBox_dateFormat->setCurrentIndex(dateIndex);
slotDateFormatIndexChanged(dateIndex);
}

if (preset == BaseTrackTableModel::DateFormat::Custom) {
comboBox_dateFormat->setEditable(true);
comboBox_dateFormat->setEditText(dateFormat);
m_lastCustomDateFormat = dateFormat;
} else {
comboBox_dateFormat->setEditable(false);
}

updateDateFormatPreview(dateFormat);

// Ensure the static member is updated on startup/load
BaseTrackTableModel::setDateFormat(dateFormat);
// Ensure the format is applied to the library view on startup/load
BaseTrackTableModel::setDateFormat(m_dateFormat);
updateDateFormatPreview();

switch (m_pConfig->getValue<int>(
kTrackDoubleClickActionConfigKey,
Expand Down Expand Up @@ -664,6 +664,9 @@ void DlgPrefLibrary::slotApply() {
m_iOriginalTrackTableRowHeight = rowHeight;
}

m_pConfig->setValue(kDateFormatConfigKey, m_dateFormat);
BaseTrackTableModel::setDateFormat(m_dateFormat);

BaseTrackTableModel::setApplyPlayedTrackColor(
checkbox_played_track_color->isChecked());
m_pConfig->set(
Expand Down Expand Up @@ -782,20 +785,21 @@ void DlgPrefLibrary::setSeratoMetadataEnabled(bool shouldSyncTrackMetadata) {
}

void DlgPrefLibrary::slotDateFormatIndexChanged(int index) {
qWarning() << " slotDateFormatIndexChanged" << index;
auto type = comboBox_dateFormat->itemData(index)
.value<BaseTrackTableModel::DateFormat>();

QString format;
if (type == BaseTrackTableModel::DateFormat::Custom) {
// Enable editing for Custom
if (!comboBox_dateFormat->isEditable()) {
comboBox_dateFormat->setEditable(true);
comboBox_dateFormat->setEditText(m_lastCustomDateFormat);
}
qWarning() << " -> Custom, format:" << m_lastCustomDateFormat;
// Enable editing for Custom and set the custom format string
comboBox_dateFormat->setEditable(true);
comboBox_dateFormat->setEditText(m_lastCustomDateFormat);
format = m_lastCustomDateFormat;
qWarning() << " -> box text: " << comboBox_dateFormat->currentText();
} else {
// Disable editing for Presets
comboBox_dateFormat->setEditable(false);

QString format;
switch (type) {
case BaseTrackTableModel::DateFormat::Native:
format = QString();
Expand All @@ -813,12 +817,13 @@ void DlgPrefLibrary::slotDateFormatIndexChanged(int index) {
// Should not happen here given the if/else above
break;
}
slotDateFormatChanged(format);
}
slotDateFormatChanged(format);
}

void DlgPrefLibrary::slotDateFormatChanged(const QString& text) {
QString format = text;
qWarning() << " slotDateFormatChanged, text:" << text;
Comment thread
ronso0 marked this conversation as resolved.
m_dateFormat = text;
// If not editable, we are in a Preset mode, but 'text' might be the Item
// Label (e.g. "Native ...") depending on how this was called. However, our
// slotDateFormatIndexChanged calls this explicitly with the correct format
Expand All @@ -831,16 +836,14 @@ void DlgPrefLibrary::slotDateFormatChanged(const QString& text) {
auto type = comboBox_dateFormat->itemData(index)
.value<BaseTrackTableModel::DateFormat>();
if (type == BaseTrackTableModel::DateFormat::Custom) {
m_lastCustomDateFormat = format;
m_lastCustomDateFormat = m_dateFormat;
}
}
}
updateDateFormatPreview();
}

void DlgPrefLibrary::updateDateFormatPreview(const QString& format) {
const QString previewStr = mixxx::formatDate(QDate::currentDate(), format);
void DlgPrefLibrary::updateDateFormatPreview() {
const QString previewStr = mixxx::formatDate(QDate::currentDate(), m_dateFormat);
label_dateFormatPreview->setText(previewStr);

m_pConfig->setValue(kDateFormatConfigKey, format);
BaseTrackTableModel::setDateFormat(format);
}
3 changes: 2 additions & 1 deletion src/preferences/dialog/dlgpreflibrary.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class DlgPrefLibrary : public DlgPreferencePage, public Ui::DlgPrefLibraryDlg {
void resetLibraryFont();
void updateSearchLineEditHistoryOptions();
void setSeratoMetadataEnabled(bool shouldSyncTrackMetadata);
void updateDateFormatPreview(const QString& format);
void updateDateFormatPreview();

QStandardItemModel m_dirListModel;
UserSettingsPointer m_pConfig;
Expand All @@ -87,5 +87,6 @@ class DlgPrefLibrary : public DlgPreferencePage, public Ui::DlgPrefLibraryDlg {
// Listen to rate range changes in order to update the fuzzy BPM range
parented_ptr<ControlProxy> m_pRateRangeDeck1;

QString m_dateFormat;
QString m_lastCustomDateFormat;
};
3 changes: 3 additions & 0 deletions src/test/librarytest.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "test/librarytest.h"

#include "library/coverartcache.h"
#include "library/dateformatbroadcaster.h"
#include "library/library_prefs.h"
#include "track/track.h"

Expand Down Expand Up @@ -35,10 +36,12 @@ LibraryTest::LibraryTest()
m_pTrackCollectionManager(newTrackCollectionManager(config(), dbConnectionPooler())),
m_keyNotationCO(mixxx::library::prefs::kKeyNotationConfigKey) {
CoverArtCache::createInstance();
DateFormatChangedBroadcaster::createInstance();
}

LibraryTest::~LibraryTest() {
CoverArtCache::destroy();
DateFormatChangedBroadcaster::destroy();
}

TrackPointer LibraryTest::getOrAddTrackByLocation(
Expand Down
Loading