Skip to content

Commit

Permalink
Implement own lessThan(QVariant, QVariant)
Browse files Browse the repository at this point in the history
Qt 5.15 deprecated the operator<(QVariant, QVariant). Do get rid of the
warning and to prepare for the eventual removal of the operator,
implement our own needs in a lessThan() function.

The function is based on the description of
QSortFilterProxyModel::lessThan().

Fixes oKcerG#77
  • Loading branch information
olafmandel committed Oct 27, 2020
1 parent 6678acc commit 0c5917e
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 4 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) # This is to find generated *.moc and *.h file

add_library(SortFilterProxyModel OBJECT
qqmlsortfilterproxymodel.cpp
qvariantlessthan.cpp
filters/filter.cpp
filters/filtercontainer.cpp
filters/rolefilter.cpp
Expand Down
2 changes: 2 additions & 0 deletions SortFilterProxyModel.pri
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
INCLUDEPATH += $$PWD

HEADERS += $$PWD/qqmlsortfilterproxymodel.h \
$$PWD/qvariantlessthan.h \
$$PWD/filters/filter.h \
$$PWD/filters/filtercontainer.h \
$$PWD/filters/rolefilter.h \
Expand Down Expand Up @@ -30,6 +31,7 @@ HEADERS += $$PWD/qqmlsortfilterproxymodel.h \
$$PWD/proxyroles/filterrole.h

SOURCES += $$PWD/qqmlsortfilterproxymodel.cpp \
$$PWD/qvariantlessthan.cpp \
$$PWD/filters/filter.cpp \
$$PWD/filters/filtercontainer.cpp \
$$PWD/filters/rolefilter.cpp \
Expand Down
7 changes: 5 additions & 2 deletions filters/rangefilter.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "rangefilter.h"
#include "qvariantlessthan.h"

namespace qqsfpm {

Expand Down Expand Up @@ -130,9 +131,11 @@ bool RangeFilter::filterRow(const QModelIndex& sourceIndex, const QQmlSortFilter
{
QVariant value = sourceData(sourceIndex, proxyModel);
bool lessThanMin = m_minimumValue.isValid() &&
(m_minimumInclusive ? value < m_minimumValue : value <= m_minimumValue);
(m_minimumInclusive ? qqsfpm::lessThan(value, m_minimumValue)
: !qqsfpm::lessThan(m_minimumValue, value));
bool moreThanMax = m_maximumValue.isValid() &&
(m_maximumInclusive ? value > m_maximumValue : value >= m_maximumValue);
(m_maximumInclusive ? qqsfpm::lessThan(m_maximumValue, value)
: !qqsfpm::lessThan(value, m_maximumValue));
return !(lessThanMin || moreThanMax);
}

Expand Down
79 changes: 79 additions & 0 deletions qvariantlessthan.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#include "qvariantlessthan.h"

#include <QDateTime>

namespace qqsfpm {

/*!
\brief Less-than operator for generic QVariants
Since Qt 5.15 deprecated the less-than operator of QVariant, we
have to provide our own implementation. On older Qt versions,
use the original implementation.
Includes special implementations for numberic types, char, date and
time. Everything else is converted to String and compared then.
*/
bool lessThan(const QVariant &lhs, const QVariant &rhs)
{
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
return lhs < rhs;
#else
static const auto numericTypes = QVector<QMetaType::Type>{
QMetaType::Int,
QMetaType::UInt,
QMetaType::LongLong,
QMetaType::ULongLong,
QMetaType::Float,
QMetaType::Double,
};
static const auto unsignedTypes = QVector<QMetaType::Type>{
QMetaType::UInt,
QMetaType::ULongLong,
};
static const auto dateTimeTypes = QVector<QMetaType::Type>{
QMetaType::QDate,
QMetaType::QTime,
QMetaType::QDateTime,
};

const auto lt = static_cast<QMetaType::Type>(lhs.type());
const auto rt = static_cast<QMetaType::Type>(rhs.type());
if (numericTypes.contains(lt) && numericTypes.contains(rt)) {
if (lt == QMetaType::Double || lt == QMetaType::Float
|| rt == QMetaType::Double || rt == QMetaType::Float) {
return lhs.toDouble() < rhs.toDouble();
} else {
const auto ul = unsignedTypes.contains(lt);
const auto ur = unsignedTypes.contains(rt);
if (ul && ur) {
return lhs.toULongLong() < rhs.toULongLong();
} else if (!ul && !ur) {
return lhs.toLongLong() < rhs.toLongLong();
} else if (ul) {
const auto r = rhs.toLongLong();
return r > 0 &&
lhs.toULongLong() < static_cast<unsigned long long>(r);
} else {
const auto l = lhs.toLongLong();
return l < 0 ||
static_cast<unsigned long long>(l) < rhs.toULongLong();
}
}
} else if (dateTimeTypes.contains(lt) && dateTimeTypes.contains(rt)) {
if (lt == QMetaType::QDate && rt == QMetaType::QDate) {
return lhs.toDate() < rhs.toDate();
} else if (lt == QMetaType::QTime && rt == QMetaType::QTime) {
return lhs.toTime() < rhs.toTime();
} else {
return lhs.toDateTime() < rhs.toDateTime();
}
} else if (lt == QMetaType::Char && rt == QMetaType::Char) {
return lhs.toChar() < rhs.toChar();
} else {
return lhs.toString() < rhs.toString();
}
#endif
}

} // namespace qqsfpm
12 changes: 12 additions & 0 deletions qvariantlessthan.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef QVARIANTLESSTHAN_H
#define QVARIANTLESSTHAN_H

#include <QVariant>

namespace qqsfpm {

bool lessThan(const QVariant &lhs, const QVariant &rhs);

} // namespace qqsfpm

#endif // QVARIANTLESSTHAN_H
5 changes: 3 additions & 2 deletions sorters/rolesorter.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "rolesorter.h"
#include "qqmlsortfilterproxymodel.h"
#include "qvariantlessthan.h"

namespace qqsfpm {

Expand Down Expand Up @@ -59,9 +60,9 @@ int RoleSorter::compare(const QModelIndex &sourceLeft, const QModelIndex& source
QPair<QVariant, QVariant> pair = sourceData(sourceLeft, sourceRight, proxyModel);
QVariant leftValue = pair.first;
QVariant rightValue = pair.second;
if (leftValue < rightValue)
if (qqsfpm::lessThan(leftValue, rightValue))
return -1;
if (leftValue > rightValue)
if (qqsfpm::lessThan(rightValue, leftValue))
return 1;
return 0;
}
Expand Down

0 comments on commit 0c5917e

Please sign in to comment.