Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Qt6 & Qt5 version #100

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
0c5917e
Implement own lessThan(QVariant, QVariant)
olafmandel Oct 27, 2020
fe50203
Port to Qt 6
mitchcurtis May 14, 2022
1873b48
Update CMakeListst.txt for Qt 6
mitchcurtis Jul 9, 2022
f336b3c
cmake: fix c++17 build requirement for msc
atraczyk Aug 3, 2022
994900b
Merge pull request #1 from atraczyk/qt-6
mitchcurtis Aug 4, 2022
f288149
Fix build with ASAN on Linux
mitchcurtis Aug 18, 2022
0a6e205
ExpressionRole: Apply source-get optimization and possibly cache result
msarehn Feb 9, 2021
c2cc5ce
Use QHash instead of QMap for faster lookups
msarehn Mar 11, 2021
5b05eec
Fix clazy warnings
msarehn Mar 11, 2021
9d92bda
Support both Qt5 and Qt6
msarehn Sep 5, 2022
1cd6231
ValueFilter: Restore QVariant comparison behavior from Qt5
msarehn Nov 5, 2022
783b803
Fix Qt6 deprecation warnings about QVariant::type()
olafmandel Jan 9, 2023
1c316c7
Merge pull request #1 from RaymiiOrg/qt6
RaymiiOrg Jul 17, 2023
25075a9
Merge branch 'master' into QVariant-lessThan
RaymiiOrg Jul 17, 2023
3cecb2f
Merge pull request #2 from RaymiiOrg/QVariant-lessThan
RaymiiOrg Jul 17, 2023
33faea0
Merge pull request #3 from MenloSystems/fix-clazy-warnings
RaymiiOrg Jul 17, 2023
5176c19
Merge pull request #4 from MenloSystems/ExpressionRole-caching
RaymiiOrg Jul 17, 2023
41271ab
Create github actions file for Qt5
Jul 18, 2023
31bea0a
Revert "Merge pull request #4 from MenloSystems/ExpressionRole-caching"
Jul 18, 2023
82820b8
Fix after revert
RaymiiOrg Jul 18, 2023
34162af
Fix C++ 17 compile warning
Jul 18, 2023
909278f
Make QVariant compare work with Qt 5.15 and 6.5
Jul 18, 2023
3f390de
Update readme, add Qt6 actions build
Jul 18, 2023
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
44 changes: 44 additions & 0 deletions .github/workflows/cmake-qt5.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: CMake-Qt5

on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]

env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release

jobs:
build:
# The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac.
# You can convert this to a matrix build if you need cross-platform coverage.
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Install Qt
uses: jurplel/[email protected]
with:
cache: 'true'
cache-key-prefix: 'install-qt-action'
version: '5.15.2'

- name: Configure CMake
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}

- name: Build
# Build your program with the given configuration
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}

- name: Test
working-directory: ${{github.workspace}}/build
# Execute tests defined by the CMake configuration.
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: ctest -C ${{env.BUILD_TYPE}}

44 changes: 44 additions & 0 deletions .github/workflows/cmake-qt6.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: CMake-Qt6

on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]

env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release

jobs:
build:
# The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac.
# You can convert this to a matrix build if you need cross-platform coverage.
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Install Qt
uses: jurplel/[email protected]
with:
cache: 'true'
cache-key-prefix: 'install-qt-action6'
version: '6.5.0'

- name: Configure CMake
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DQT_VERSION_MAJOR=6

- name: Build
# Build your program with the given configuration
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}

- name: Test
working-directory: ${{github.workspace}}/build
# Execute tests defined by the CMake configuration.
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: ctest -C ${{env.BUILD_TYPE}}

33 changes: 25 additions & 8 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
cmake_minimum_required(VERSION 3.1)
cmake_minimum_required(VERSION 3.14)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

find_package(Qt5 REQUIRED
if (NOT QT_VERSION_MAJOR)
set(QT_VERSION_MAJOR 5)
endif()

find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS
Core
Qml
)
)

set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON) # This is to find generated *.moc and *.h files in build dir

add_library(SortFilterProxyModel OBJECT
qqmlsortfilterproxymodel.cpp
qvariantlessthan.cpp
filters/filter.cpp
filters/filtercontainer.cpp
filters/rolefilter.cpp
Expand Down Expand Up @@ -40,10 +45,22 @@ add_library(SortFilterProxyModel OBJECT
proxyroles/regexprole.cpp
sorters/filtersorter.cpp
proxyroles/filterrole.cpp
)
utils/utils.cpp
utils/utils.h
)

target_link_libraries(SortFilterProxyModel
PRIVATE
Qt::Core
Qt::Qml
)

if ((MSVC) AND (MSVC_VERSION GREATER_EQUAL 1914))
target_compile_options(SortFilterProxyModel PUBLIC "/Zc:__cplusplus")
endif()

target_include_directories(SortFilterProxyModel PUBLIC
${CMAKE_CURRENT_LIST_DIR}
$<TARGET_PROPERTY:Qt5::Core,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:Qt5::Qml,INTERFACE_INCLUDE_DIRECTORIES>
)
$<TARGET_PROPERTY:Qt::Core,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:Qt::Qml,INTERFACE_INCLUDE_DIRECTORIES>
)
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ SortFilterProxyModel

SortFilterProxyModel is an implementation of `QSortFilterProxyModel` conveniently exposed for QML.

This is a fork that combines the Qt6 port of [MenloSystems/SortFilterProxyModel](https://github.com/MenloSystems/SortFilterProxyModel) with a few of my own fixes to compile and run under both Qt 5.15 and 6.5.
A github actions workflow compiles the code to make sure it keeps compiling on both versions.

Install
-------
##### With [qpm](https://qpm.io) :
Expand Down
10 changes: 7 additions & 3 deletions SortFilterProxyModel.pri
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
!contains( CONFIG, c\+\+1[14] ): warning("SortFilterProxyModel needs at least c++11, add CONFIG += c++11 to your .pro")
!contains( CONFIG, c\+\+1[147] ): warning("SortFilterProxyModel needs at least c++11, add CONFIG += c++11 to your .pro")

INCLUDEPATH += $$PWD

HEADERS += $$PWD/qqmlsortfilterproxymodel.h \
$$PWD/qvariantlessthan.h \
$$PWD/filters/filter.h \
$$PWD/filters/filtercontainer.h \
$$PWD/filters/rolefilter.h \
Expand All @@ -27,9 +28,11 @@ HEADERS += $$PWD/qqmlsortfilterproxymodel.h \
$$PWD/proxyroles/singlerole.h \
$$PWD/proxyroles/regexprole.h \
$$PWD/sorters/filtersorter.h \
$$PWD/proxyroles/filterrole.h
$$PWD/proxyroles/filterrole.h \
$$PWD/utils/utils.h

SOURCES += $$PWD/qqmlsortfilterproxymodel.cpp \
$$PWD/qvariantlessthan.cpp \
$$PWD/filters/filter.cpp \
$$PWD/filters/filtercontainer.cpp \
$$PWD/filters/rolefilter.cpp \
Expand Down Expand Up @@ -57,4 +60,5 @@ SOURCES += $$PWD/qqmlsortfilterproxymodel.cpp \
$$PWD/proxyroles/singlerole.cpp \
$$PWD/proxyroles/regexprole.cpp \
$$PWD/sorters/filtersorter.cpp \
$$PWD/proxyroles/filterrole.cpp
$$PWD/proxyroles/filterrole.cpp \
$$PWD/utils/utils.cpp
2 changes: 2 additions & 0 deletions SortFilterProxyModel.qbs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ Group {
"sorters/sortersqmltypes.cpp",
"sorters/stringsorter.cpp",
"sorters/stringsorter.h",
"utils/utils.cpp",
"utils/utils.h",
"qqmlsortfilterproxymodel.cpp",
"qqmlsortfilterproxymodel.h"
]
Expand Down
4 changes: 2 additions & 2 deletions filters/filtercontainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ void FilterContainer::append_filter(QQmlListProperty<Filter>* list, Filter* filt
that->appendFilter(filter);
}

int FilterContainer::count_filter(QQmlListProperty<Filter>* list)
qqsfpm::FilterContainer::sizetype FilterContainer::count_filter(QQmlListProperty<Filter>* list)
{
QList<Filter*>* filters = static_cast<QList<Filter*>*>(list->data);
return filters->count();
}

Filter* FilterContainer::at_filter(QQmlListProperty<Filter>* list, int index)
Filter* FilterContainer::at_filter(QQmlListProperty<Filter>* list, qqsfpm::FilterContainer::sizetype index)
{
QList<Filter*>* filters = static_cast<QList<Filter*>*>(list->data);
return filters->at(index);
Expand Down
10 changes: 8 additions & 2 deletions filters/filtercontainer.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,15 @@ class FilterContainer {
virtual void onFilterRemoved(Filter* filter) = 0;
virtual void onFiltersCleared() = 0;

#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
using sizetype = int;
#else
using sizetype = qsizetype;
#endif

static void append_filter(QQmlListProperty<Filter>* list, Filter* filter);
static int count_filter(QQmlListProperty<Filter>* list);
static Filter* at_filter(QQmlListProperty<Filter>* list, int index);
static sizetype count_filter(QQmlListProperty<Filter>* list);
static Filter* at_filter(QQmlListProperty<Filter>* list, sizetype index);
static void clear_filters(QQmlListProperty<Filter>* list);
};

Expand Down
13 changes: 10 additions & 3 deletions filters/rangefilter.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
#include "rangefilter.h"

#include "qvariantlessthan.h"




namespace qqsfpm {

/*!
Expand Down Expand Up @@ -128,11 +133,13 @@ void RangeFilter::setMaximumInclusive(bool maximumInclusive)

bool RangeFilter::filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const
{
QVariant value = sourceData(sourceIndex, proxyModel);
const 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
47 changes: 12 additions & 35 deletions filters/regexpfilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ namespace qqsfpm {

\sa syntax
*/
RegExpFilter::RegExpFilter() :
m_caseSensitivity(m_regExp.patternOptions().testFlag(
QRegularExpression::CaseInsensitiveOption) ? Qt::CaseInsensitive : Qt::CaseSensitive)
{
}

QString RegExpFilter::pattern() const
{
return m_pattern;
Expand All @@ -51,38 +57,6 @@ void RegExpFilter::setPattern(const QString& pattern)
invalidate();
}

/*!
\qmlproperty enum RegExpFilter::syntax

The pattern used to filter the contents of the source model.

Only the source model's value having their \l RoleFilter::roleName data matching this \l pattern with the specified \l syntax will be kept.

\value RegExpFilter.RegExp A rich Perl-like pattern matching syntax. This is the default.
\value RegExpFilter.Wildcard This provides a simple pattern matching syntax similar to that used by shells (command interpreters) for "file globbing".
\value RegExpFilter.FixedString The pattern is a fixed string. This is equivalent to using the RegExp pattern on a string in which all metacharacters are escaped.
\value RegExpFilter.RegExp2 Like RegExp, but with greedy quantifiers.
\value RegExpFilter.WildcardUnix This is similar to Wildcard but with the behavior of a Unix shell. The wildcard characters can be escaped with the character "\".
\value RegExpFilter.W3CXmlSchema11 The pattern is a regular expression as defined by the W3C XML Schema 1.1 specification.

\sa pattern
*/
RegExpFilter::PatternSyntax RegExpFilter::syntax() const
{
return m_syntax;
}

void RegExpFilter::setSyntax(RegExpFilter::PatternSyntax syntax)
{
if (m_syntax == syntax)
return;

m_syntax = syntax;
m_regExp.setPatternSyntax(static_cast<QRegExp::PatternSyntax>(syntax));
Q_EMIT syntaxChanged();
invalidate();
}

/*!
\qmlproperty Qt::CaseSensitivity RegExpFilter::caseSensitivity

Expand All @@ -99,15 +73,18 @@ void RegExpFilter::setCaseSensitivity(Qt::CaseSensitivity caseSensitivity)
return;

m_caseSensitivity = caseSensitivity;
m_regExp.setCaseSensitivity(caseSensitivity);
QRegularExpression::PatternOptions patternOptions = m_regExp.patternOptions();
if (caseSensitivity == Qt::CaseInsensitive)
patternOptions.setFlag(QRegularExpression::CaseInsensitiveOption);
m_regExp.setPatternOptions(patternOptions);
Q_EMIT caseSensitivityChanged();
invalidate();
}

bool RegExpFilter::filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const
{
QString string = sourceData(sourceIndex, proxyModel).toString();
return m_regExp.indexIn(string) != -1;
const QString string = sourceData(sourceIndex, proxyModel).toString();
return m_regExp.match(string).hasMatch();
}

}
23 changes: 6 additions & 17 deletions filters/regexpfilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,23 @@

#include "rolefilter.h"

#include <QRegularExpression>

namespace qqsfpm {

class RegExpFilter : public RoleFilter {
Q_OBJECT
Q_PROPERTY(QString pattern READ pattern WRITE setPattern NOTIFY patternChanged)
Q_PROPERTY(PatternSyntax syntax READ syntax WRITE setSyntax NOTIFY syntaxChanged)
Q_PROPERTY(Qt::CaseSensitivity caseSensitivity READ caseSensitivity WRITE setCaseSensitivity NOTIFY caseSensitivityChanged)

public:
enum PatternSyntax {
RegExp = QRegExp::RegExp,
Wildcard = QRegExp::Wildcard,
FixedString = QRegExp::FixedString,
RegExp2 = QRegExp::RegExp2,
WildcardUnix = QRegExp::WildcardUnix,
W3CXmlSchema11 = QRegExp::W3CXmlSchema11 };
Q_ENUMS(PatternSyntax)

using RoleFilter::RoleFilter;

RegExpFilter();

QString pattern() const;
void setPattern(const QString& pattern);

PatternSyntax syntax() const;
void setSyntax(PatternSyntax syntax);

Qt::CaseSensitivity caseSensitivity() const;
void setCaseSensitivity(Qt::CaseSensitivity caseSensitivity);

Expand All @@ -37,13 +28,11 @@ class RegExpFilter : public RoleFilter {

Q_SIGNALS:
void patternChanged();
void syntaxChanged();
void caseSensitivityChanged();

private:
QRegExp m_regExp;
Qt::CaseSensitivity m_caseSensitivity = m_regExp.caseSensitivity();
PatternSyntax m_syntax = static_cast<PatternSyntax>(m_regExp.patternSyntax());
QRegularExpression m_regExp;
Qt::CaseSensitivity m_caseSensitivity;
QString m_pattern = m_regExp.pattern();
};

Expand Down
Loading