├── certinfo.ico
├── screenshot.png
├── src
├── certinfo.png
├── qml.qrc
├── qt5.qrc
├── qt6.qrc
├── thirdparty
│ └── SortFilterProxyModel
│ │ ├── qvariantlessthan.h
│ │ ├── filters
│ │ ├── alloffilter.h
│ │ ├── anyoffilter.h
│ │ ├── rolefilter.h
│ │ ├── valuefilter.h
│ │ ├── filtercontainerfilter.cpp
│ │ ├── filtercontainerfilter.h
│ │ ├── indexfilter.h
│ │ ├── alloffilter.cpp
│ │ ├── expressionfilter.h
│ │ ├── regexpfilter.h
│ │ ├── filter.h
│ │ ├── filtersqmltypes.cpp
│ │ ├── rolefilter.cpp
│ │ ├── rangefilter.h
│ │ ├── anyoffilter.cpp
│ │ ├── valuefilter.cpp
│ │ ├── filtercontainer.h
│ │ ├── filter.cpp
│ │ ├── regexpfilter.cpp
│ │ ├── indexfilter.cpp
│ │ ├── filtercontainer.cpp
│ │ ├── rangefilter.cpp
│ │ └── expressionfilter.cpp
│ │ ├── utils
│ │ ├── utils.h
│ │ └── utils.cpp
│ │ ├── proxyroles
│ │ ├── filterrole.h
│ │ ├── singlerole.h
│ │ ├── proxyrolesqmltypes.cpp
│ │ ├── joinrole.h
│ │ ├── proxyrole.h
│ │ ├── expressionrole.h
│ │ ├── regexprole.h
│ │ ├── proxyrole.cpp
│ │ ├── singlerole.cpp
│ │ ├── proxyrolecontainer.h
│ │ ├── filterrole.cpp
│ │ ├── switchrole.h
│ │ ├── proxyrolecontainer.cpp
│ │ ├── joinrole.cpp
│ │ ├── regexprole.cpp
│ │ ├── expressionrole.cpp
│ │ └── switchrole.cpp
│ │ ├── sorters
│ │ ├── rolesorter.h
│ │ ├── sortersqmltypes.cpp
│ │ ├── filtersorter.h
│ │ ├── expressionsorter.h
│ │ ├── stringsorter.h
│ │ ├── sorter.h
│ │ ├── sortercontainer.h
│ │ ├── rolesorter.cpp
│ │ ├── filtersorter.cpp
│ │ ├── stringsorter.cpp
│ │ ├── sorter.cpp
│ │ ├── sortercontainer.cpp
│ │ └── expressionsorter.cpp
│ │ ├── LICENSE
│ │ ├── SortFilterProxyModel.pri
│ │ ├── qvariantlessthan.cpp
│ │ ├── README.md
│ │ └── qqmlsortfilterproxymodel.h
├── +qt5
│ ├── ExportFileDialog.qml
│ └── ImportHostsFileDialog.qml
├── +qt6
│ ├── ExportFileDialog.qml
│ └── ImportHostsFileDialog.qml
├── listmodel
│ ├── domaincountlistmodel.h
│ ├── domaincountlistmodel.cpp
│ ├── caissuerlistmodel.h
│ ├── qabstractlistmodelwithrowcountsignal.h
│ ├── caissuerlistmodel.cpp
│ └── genericlistmodel.h
├── ca
│ ├── caprocessor.h
│ ├── caconcurrentgatherer.h
│ ├── certificate.h
│ └── caprocessor.cpp
├── versioncheck
│ ├── versioncheck.h
│ └── versioncheck.cpp
├── domainsources
│ ├── domainslisttextfile.h
│ ├── browserhistorydb.h
│ ├── domainslisttextfile.cpp
│ └── browserhistorydb.cpp
├── FoldableCertInfo.qml
└── main.cpp
├── README.md
├── flake.nix
├── nix
└── derivation.nix
├── .github
└── workflows
│ └── qmake.yml
├── .gitignore
├── flake.lock
├── CertInfo.pro
└── setup.iss
/certinfo.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaymiiOrg/CertInfo/master/certinfo.ico
--------------------------------------------------------------------------------
/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaymiiOrg/CertInfo/master/screenshot.png
--------------------------------------------------------------------------------
/src/certinfo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RaymiiOrg/CertInfo/master/src/certinfo.png
--------------------------------------------------------------------------------
/src/qml.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | main.qml
4 | FoldableCertInfo.qml
5 | certinfo.png
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/qt5.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | +qt5/ExportFileDialog.qml
4 | +qt5/ImportHostsFileDialog.qml
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/qt6.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | +qt6/ExportFileDialog.qml
4 | +qt6/ImportHostsFileDialog.qml
5 |
6 |
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CertInfo
2 |
3 | Which Root Certificate should you trust? Find out with CertInfo
4 |
5 | Please see [my site for more information](https://raymii.org/s/software/Which_Root_Certificates_Should_You_Trust_CertInfo.html)
6 |
7 |
8 |
9 | 
10 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/qvariantlessthan.h:
--------------------------------------------------------------------------------
1 | #ifndef QVARIANTLESSTHAN_H
2 | #define QVARIANTLESSTHAN_H
3 |
4 | #include
5 |
6 | namespace qqsfpm {
7 |
8 | bool lessThan(const QVariant &lhs, const QVariant &rhs);
9 |
10 | } // namespace qqsfpm
11 |
12 | #endif // QVARIANTLESSTHAN_H
13 |
--------------------------------------------------------------------------------
/src/+qt5/ExportFileDialog.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.15
2 | import QtQuick.Dialogs 1.3
3 |
4 | FileDialog {
5 | required property var proc
6 | id: root
7 | title: "Export results to which file"
8 | selectExisting: false
9 | nameFilters: [ "text file (*.txt)", "All files (*)" ]
10 | onAccepted: {
11 | proc.exportToText(root.fileUrl)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/+qt6/ExportFileDialog.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.15
2 | import QtQuick.Dialogs
3 |
4 | FileDialog {
5 | required property var proc
6 | id: root
7 | title: "Export results to which file"
8 | fileMode: FileDialog.SaveFile
9 | nameFilters: [ "text file (*.txt)", "All files (*)" ]
10 | onAccepted: {
11 | proc.exportToText(root.selectedFile)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/filters/alloffilter.h:
--------------------------------------------------------------------------------
1 | #ifndef ALLOFFILTER_H
2 | #define ALLOFFILTER_H
3 |
4 | #include "filtercontainerfilter.h"
5 |
6 | namespace qqsfpm {
7 |
8 | class AllOfFilter : public FilterContainerFilter {
9 | Q_OBJECT
10 |
11 | public:
12 | using FilterContainerFilter::FilterContainerFilter;
13 |
14 | protected:
15 | bool filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const override;
16 | };
17 |
18 | }
19 |
20 | #endif // ALLOFFILTER_H
21 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/filters/anyoffilter.h:
--------------------------------------------------------------------------------
1 | #ifndef ANYOFFILTER_H
2 | #define ANYOFFILTER_H
3 |
4 | #include "filtercontainerfilter.h"
5 |
6 | namespace qqsfpm {
7 |
8 | class AnyOfFilter : public FilterContainerFilter {
9 | Q_OBJECT
10 |
11 | public:
12 | using FilterContainerFilter::FilterContainerFilter;
13 |
14 | protected:
15 | bool filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const override;
16 | };
17 |
18 | }
19 |
20 | #endif // ANYOFFILTER_H
21 |
--------------------------------------------------------------------------------
/flake.nix:
--------------------------------------------------------------------------------
1 | {
2 | description = "A very basic flake";
3 |
4 | inputs = {
5 | nixpkgs.url = github:NixOS/nixpkgs/nixpkgs-unstable;
6 | flake-utils.url = "github:numtide/flake-utils";
7 | };
8 |
9 | outputs = {
10 | self,
11 | nixpkgs,
12 | flake-utils,
13 | }:
14 | flake-utils.lib.eachDefaultSystem (system: let
15 | pkgs = nixpkgs.legacyPackages.${system};
16 | in {
17 | defaultPackage =
18 | pkgs.qt6.callPackage ./nix/derivation.nix {
19 | };
20 | });
21 | }
22 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/utils/utils.h:
--------------------------------------------------------------------------------
1 | #ifndef UTILS_H
2 | #define UTILS_H
3 |
4 | #include
5 |
6 | namespace qqsfpm {
7 |
8 | int compareVariants(const QVariant &lhs, const QVariant &rhs);
9 |
10 | inline bool operator<(const QVariant &lhs, const QVariant &rhs) { return compareVariants(lhs, rhs) < 0; }
11 | inline bool operator<=(const QVariant &lhs, const QVariant &rhs) { return compareVariants(lhs, rhs) <= 0; }
12 | inline bool operator>(const QVariant &lhs, const QVariant &rhs) { return compareVariants(lhs, rhs) > 0; }
13 | inline bool operator>=(const QVariant &lhs, const QVariant &rhs) { return compareVariants(lhs, rhs) >= 0; }
14 |
15 | }
16 |
17 | #endif // UTILS_H
18 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/filters/rolefilter.h:
--------------------------------------------------------------------------------
1 | #ifndef ROLEFILTER_H
2 | #define ROLEFILTER_H
3 |
4 | #include "filter.h"
5 |
6 | namespace qqsfpm {
7 |
8 | class RoleFilter : public Filter
9 | {
10 | Q_OBJECT
11 | Q_PROPERTY(QString roleName READ roleName WRITE setRoleName NOTIFY roleNameChanged)
12 |
13 | public:
14 | using Filter::Filter;
15 |
16 | const QString& roleName() const;
17 | void setRoleName(const QString& roleName);
18 |
19 | Q_SIGNALS:
20 | void roleNameChanged();
21 |
22 | protected:
23 | QVariant sourceData(const QModelIndex &sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const;
24 |
25 | private:
26 | QString m_roleName;
27 | };
28 |
29 | }
30 |
31 | #endif // ROLEFILTER_H
32 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/filters/valuefilter.h:
--------------------------------------------------------------------------------
1 | #ifndef VALUEFILTER_H
2 | #define VALUEFILTER_H
3 |
4 | #include "rolefilter.h"
5 | #include
6 |
7 | namespace qqsfpm {
8 |
9 | class ValueFilter : public RoleFilter {
10 | Q_OBJECT
11 | Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged)
12 |
13 | public:
14 | using RoleFilter::RoleFilter;
15 |
16 | const QVariant& value() const;
17 | void setValue(const QVariant& value);
18 |
19 | protected:
20 | bool filterRow(const QModelIndex &sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const override;
21 |
22 | Q_SIGNALS:
23 | void valueChanged();
24 |
25 | private:
26 | QVariant m_value;
27 | };
28 |
29 | }
30 |
31 | #endif // VALUEFILTER_H
32 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/filters/filtercontainerfilter.cpp:
--------------------------------------------------------------------------------
1 | #include "filtercontainerfilter.h"
2 |
3 | namespace qqsfpm {
4 |
5 | void FilterContainerFilter::proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel)
6 | {
7 | for (Filter* filter : m_filters)
8 | filter->proxyModelCompleted(proxyModel);
9 | }
10 |
11 | void FilterContainerFilter::onFilterAppended(Filter* filter)
12 | {
13 | connect(filter, &Filter::invalidated, this, &FilterContainerFilter::invalidate);
14 | invalidate();
15 | }
16 |
17 | void FilterContainerFilter::onFilterRemoved(Filter* filter)
18 | {
19 | Q_UNUSED(filter)
20 | invalidate();
21 | }
22 |
23 | void qqsfpm::FilterContainerFilter::onFiltersCleared()
24 | {
25 | invalidate();
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/proxyroles/filterrole.h:
--------------------------------------------------------------------------------
1 | #ifndef FILTERROLE_H
2 | #define FILTERROLE_H
3 |
4 | #include "singlerole.h"
5 | #include "filters/filtercontainer.h"
6 |
7 | namespace qqsfpm {
8 |
9 | class FilterRole : public SingleRole, public FilterContainer
10 | {
11 | Q_OBJECT
12 | Q_INTERFACES(qqsfpm::FilterContainer)
13 | Q_PROPERTY(QQmlListProperty filters READ filtersListProperty)
14 | Q_CLASSINFO("DefaultProperty", "filters")
15 |
16 | public:
17 | using SingleRole::SingleRole;
18 |
19 | private:
20 | void onFilterAppended(Filter* filter) override;
21 | void onFilterRemoved(Filter* filter) override;
22 | void onFiltersCleared() override;
23 |
24 | QVariant data(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) override;
25 | };
26 |
27 | }
28 |
29 | #endif // FILTERROLE_H
30 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/proxyroles/singlerole.h:
--------------------------------------------------------------------------------
1 | #ifndef SINGLEROLE_H
2 | #define SINGLEROLE_H
3 |
4 | #include "proxyrole.h"
5 |
6 | namespace qqsfpm {
7 |
8 | class SingleRole : public ProxyRole
9 | {
10 | Q_OBJECT
11 | Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
12 |
13 | public:
14 | using ProxyRole::ProxyRole;
15 |
16 | QString name() const;
17 | void setName(const QString& name);
18 |
19 | QStringList names() override;
20 |
21 | Q_SIGNALS:
22 | void nameChanged();
23 |
24 | private:
25 | QString m_name;
26 |
27 | private:
28 | QVariant data(const QModelIndex &sourceIndex, const QQmlSortFilterProxyModel &proxyModel, const QString &name) final;
29 | virtual QVariant data(const QModelIndex &sourceIndex, const QQmlSortFilterProxyModel &proxyModel) = 0;
30 | };
31 |
32 | }
33 |
34 | #endif // SINGLEROLE_H
35 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/sorters/rolesorter.h:
--------------------------------------------------------------------------------
1 | #ifndef ROLESORTER_H
2 | #define ROLESORTER_H
3 |
4 | #include "sorter.h"
5 |
6 | namespace qqsfpm {
7 |
8 | class RoleSorter : public Sorter
9 | {
10 | Q_OBJECT
11 | Q_PROPERTY(QString roleName READ roleName WRITE setRoleName NOTIFY roleNameChanged)
12 |
13 | public:
14 | using Sorter::Sorter;
15 |
16 | const QString& roleName() const;
17 | void setRoleName(const QString& roleName);
18 |
19 | Q_SIGNALS:
20 | void roleNameChanged();
21 |
22 | protected:
23 | QPair sourceData(const QModelIndex &sourceLeft, const QModelIndex& sourceRight, const QQmlSortFilterProxyModel& proxyModel) const;
24 | int compare(const QModelIndex& sourceLeft, const QModelIndex& sourceRight, const QQmlSortFilterProxyModel& proxyModel) const override;
25 |
26 | private:
27 | QString m_roleName;
28 | };
29 |
30 | }
31 |
32 | #endif // ROLESORTER_H
33 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/filters/filtercontainerfilter.h:
--------------------------------------------------------------------------------
1 | #ifndef FILTERCONTAINERFILTER_H
2 | #define FILTERCONTAINERFILTER_H
3 |
4 | #include "filter.h"
5 | #include "filtercontainer.h"
6 |
7 | namespace qqsfpm {
8 |
9 | class FilterContainerFilter : public Filter, public FilterContainer {
10 | Q_OBJECT
11 | Q_INTERFACES(qqsfpm::FilterContainer)
12 | Q_PROPERTY(QQmlListProperty filters READ filtersListProperty NOTIFY filtersChanged)
13 | Q_CLASSINFO("DefaultProperty", "filters")
14 |
15 | public:
16 | using Filter::Filter;
17 |
18 | void proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel) override;
19 |
20 | Q_SIGNALS:
21 | void filtersChanged();
22 |
23 | private:
24 | void onFilterAppended(Filter* filter) override;
25 | void onFilterRemoved(Filter* filter) override;
26 | void onFiltersCleared() override;
27 | };
28 |
29 | }
30 |
31 | #endif // FILTERCONTAINERFILTER_H
32 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/proxyroles/proxyrolesqmltypes.cpp:
--------------------------------------------------------------------------------
1 | #include "proxyrole.h"
2 | #include "joinrole.h"
3 | #include "switchrole.h"
4 | #include "expressionrole.h"
5 | #include "regexprole.h"
6 | #include "filterrole.h"
7 | #include
8 | #include
9 |
10 | namespace qqsfpm {
11 |
12 | void registerProxyRoleTypes() {
13 | qmlRegisterUncreatableType("SortFilterProxyModel", 0, 2, "ProxyRole", "ProxyRole is an abstract class");
14 | qmlRegisterType("SortFilterProxyModel", 0, 2, "JoinRole");
15 | qmlRegisterType("SortFilterProxyModel", 0, 2, "SwitchRole");
16 | qmlRegisterType("SortFilterProxyModel", 0, 2, "ExpressionRole");
17 | qmlRegisterType("SortFilterProxyModel", 0, 2, "RegExpRole");
18 | qmlRegisterType("SortFilterProxyModel", 0, 2, "FilterRole");
19 | }
20 |
21 | Q_COREAPP_STARTUP_FUNCTION(registerProxyRoleTypes)
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/proxyroles/joinrole.h:
--------------------------------------------------------------------------------
1 | #ifndef JOINROLE_H
2 | #define JOINROLE_H
3 |
4 | #include "singlerole.h"
5 |
6 | namespace qqsfpm {
7 |
8 | class JoinRole : public SingleRole
9 | {
10 | Q_OBJECT
11 | Q_PROPERTY(QStringList roleNames READ roleNames WRITE setRoleNames NOTIFY roleNamesChanged)
12 | Q_PROPERTY(QString separator READ separator WRITE setSeparator NOTIFY separatorChanged)
13 |
14 | public:
15 | using SingleRole::SingleRole;
16 |
17 | QStringList roleNames() const;
18 | void setRoleNames(const QStringList& roleNames);
19 |
20 | QString separator() const;
21 | void setSeparator(const QString& separator);
22 |
23 | Q_SIGNALS:
24 | void roleNamesChanged();
25 |
26 | void separatorChanged();
27 |
28 | private:
29 | QStringList m_roleNames;
30 | QVariant data(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) override;
31 | QString m_separator = " ";
32 | };
33 |
34 | }
35 |
36 | #endif // JOINROLE_H
37 |
--------------------------------------------------------------------------------
/nix/derivation.nix:
--------------------------------------------------------------------------------
1 | {
2 | stdenv,
3 | qtbase,
4 | qtdeclarative,
5 | qmake,
6 | wrapQtAppsHook,
7 | lib,
8 | }:
9 | stdenv.mkDerivation {
10 | pname = "CertInfo";
11 | version = "1.0";
12 |
13 | src = ../.;
14 |
15 | buildInputs = [qtbase qtdeclarative];
16 | nativeBuildInputs = [wrapQtAppsHook qmake];
17 |
18 | # Wrapping the inside of the app bundles, avoiding double-wrapping
19 | dontWrapQtApps = stdenv.hostPlatform.isDarwin;
20 |
21 | postInstall = lib.optionalString stdenv.hostPlatform.isDarwin ''
22 | mkdir -p $out/Applications
23 | mv $out/{bin,Applications}/CertInfo.app
24 | ln -s $out/{Applications/CertInfo.app/Contents/MacOS,bin}/CertInfo
25 | wrapQtApp $out/Applications/CertInfo.app/Contents/MacOS/CertInfo
26 | '';
27 |
28 | postPatch = ''
29 | substituteInPlace src/versioncheck/versioncheck.cpp \
30 | --replace 'VersionCheck.h' 'versioncheck.h'
31 | substituteInPlace CertInfo.pro \
32 | --replace '/opt/$${TARGET}/bin' '$$PREFIX/bin'
33 | '';
34 | }
35 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/proxyroles/proxyrole.h:
--------------------------------------------------------------------------------
1 | #ifndef PROXYROLE_H
2 | #define PROXYROLE_H
3 |
4 | #include
5 | #include
6 |
7 | namespace qqsfpm {
8 |
9 | class QQmlSortFilterProxyModel;
10 |
11 | class ProxyRole : public QObject
12 | {
13 | Q_OBJECT
14 |
15 | public:
16 | using QObject::QObject;
17 | virtual ~ProxyRole() = default;
18 |
19 | QVariant roleData(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel, const QString& name);
20 | virtual void proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel);
21 |
22 | virtual QStringList names() = 0;
23 |
24 | protected:
25 | void invalidate();
26 |
27 | Q_SIGNALS:
28 | void invalidated();
29 | void namesAboutToBeChanged();
30 | void namesChanged();
31 |
32 | private:
33 | virtual QVariant data(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel, const QString& name) = 0;
34 |
35 | QMutex m_mutex;
36 | };
37 |
38 | }
39 |
40 | #endif // PROXYROLE_H
41 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/sorters/sortersqmltypes.cpp:
--------------------------------------------------------------------------------
1 | #include "sorter.h"
2 | #include "rolesorter.h"
3 | #include "stringsorter.h"
4 | #include "filtersorter.h"
5 | #include "expressionsorter.h"
6 | #include "sortercontainer.h"
7 | #include
8 | #include
9 |
10 | namespace qqsfpm {
11 |
12 | void registerSorterTypes() {
13 | qmlRegisterUncreatableType("SortFilterProxyModel", 0, 2, "Sorter", "Sorter is an abstract class");
14 | qmlRegisterType("SortFilterProxyModel", 0, 2, "RoleSorter");
15 | qmlRegisterType("SortFilterProxyModel", 0, 2, "StringSorter");
16 | qmlRegisterType("SortFilterProxyModel", 0, 2, "FilterSorter");
17 | qmlRegisterType("SortFilterProxyModel", 0, 2, "ExpressionSorter");
18 | qmlRegisterUncreatableType("SortFilterProxyModel", 0, 2, "SorterContainer", "SorterContainer can only be used as an attaching type");
19 | }
20 |
21 | Q_COREAPP_STARTUP_FUNCTION(registerSorterTypes)
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/listmodel/domaincountlistmodel.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 Remy van Elst https://raymii.org
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, version 3.
7 | *
8 | * This program is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 | * General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | #pragma once
18 |
19 | #include "genericlistmodel.h"
20 | #include
21 |
22 | typedef QPair QIntPair;
23 |
24 | class domainCountListModel : public GenericListModel
25 | {
26 | Q_OBJECT
27 | public:
28 | domainCountListModel(QObject* parent = nullptr);
29 | };
30 |
--------------------------------------------------------------------------------
/src/listmodel/domaincountlistmodel.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 Remy van Elst https://raymii.org
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, version 3.
7 | *
8 | * This program is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 | * General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 |
18 | #include "domaincountlistmodel.h"
19 |
20 | domainCountListModel::domainCountListModel(QObject* parent) : GenericListModel(parent)
21 | {
22 | addSelector("domain", [](const QIntPair &m) { return m.first; });
23 | addSelector("count", [](const QIntPair &m) { return m.second; });
24 | }
25 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/filters/indexfilter.h:
--------------------------------------------------------------------------------
1 | #ifndef INDEXFILTER_H
2 | #define INDEXFILTER_H
3 |
4 | #include "filter.h"
5 | #include
6 |
7 | namespace qqsfpm {
8 |
9 | class IndexFilter: public Filter {
10 | Q_OBJECT
11 | Q_PROPERTY(QVariant minimumIndex READ minimumIndex WRITE setMinimumIndex NOTIFY minimumIndexChanged)
12 | Q_PROPERTY(QVariant maximumIndex READ maximumIndex WRITE setMaximumIndex NOTIFY maximumIndexChanged)
13 |
14 | public:
15 | using Filter::Filter;
16 |
17 | const QVariant& minimumIndex() const;
18 | void setMinimumIndex(const QVariant& minimumIndex);
19 |
20 | const QVariant& maximumIndex() const;
21 | void setMaximumIndex(const QVariant& maximumIndex);
22 |
23 | protected:
24 | bool filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const override;
25 |
26 | Q_SIGNALS:
27 | void minimumIndexChanged();
28 | void maximumIndexChanged();
29 |
30 | private:
31 | QVariant m_minimumIndex;
32 | QVariant m_maximumIndex;
33 | };
34 |
35 | }
36 |
37 | #endif // INDEXFILTER_H
38 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 | Copyright (c) 2016 Pierre-Yves Siret
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5 |
6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7 |
8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/sorters/filtersorter.h:
--------------------------------------------------------------------------------
1 | #ifndef FILTERSORTER_H
2 | #define FILTERSORTER_H
3 |
4 | #include "sorter.h"
5 | #include "filters/filtercontainer.h"
6 |
7 | namespace qqsfpm {
8 |
9 | class FilterSorter : public Sorter, public FilterContainer
10 | {
11 | Q_OBJECT
12 | Q_INTERFACES(qqsfpm::FilterContainer)
13 | Q_PROPERTY(QQmlListProperty filters READ filtersListProperty)
14 | Q_CLASSINFO("DefaultProperty", "filters")
15 |
16 | public:
17 | using Sorter::Sorter;
18 |
19 | protected:
20 | int compare(const QModelIndex &sourceLeft, const QModelIndex &sourceRight, const QQmlSortFilterProxyModel &proxyModel) const override;
21 |
22 | private:
23 | void proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel) override;
24 | void onFilterAppended(Filter *filter) override;
25 | void onFilterRemoved(Filter *filter) override;
26 | void onFiltersCleared() override;
27 |
28 | bool indexIsAccepted(const QModelIndex &sourceIndex, const QQmlSortFilterProxyModel &proxyModel) const;
29 | };
30 |
31 | }
32 |
33 | #endif // FILTERSORTER_H
34 |
--------------------------------------------------------------------------------
/src/+qt6/ImportHostsFileDialog.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.15
2 | import QtQuick.Dialogs
3 |
4 | FileDialog {
5 | property bool isFirefox: false
6 | property bool isTextFile: false
7 | required property var db
8 | required property var txt
9 | id: root
10 | title: isTextFile ? "Choose a txt file with one domain per line" : isFirefox ? "Please choose the Firefox places.sqlite file" : "Please choose the Chrome/Edge History file"
11 | nameFilters: isTextFile ? [ "text file (*.txt)", "All files (*)" ] : isFirefox ? [ "places.sqlite (places.sqlite)", "All files (*)" ] : [ "History (History)", "All files (*)" ]
12 | onAccepted: {
13 | txt.hostnames = ""
14 | db.hostnames = ""
15 | if(root.isTextFile) {
16 | txt.getHostnamesFromTextFile(root.selectedFile)
17 | } else {
18 | if(!db.openDb(root.selectedFile)) {
19 | infoText.text = "Error opening db file!"
20 | } else {
21 | db.isFirefox = root.isFirefox;
22 | db.getHostnamesFromDb();
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/+qt5/ImportHostsFileDialog.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.15
2 | import QtQuick.Dialogs 1.3
3 |
4 | FileDialog {
5 | property bool isFirefox: false
6 | property bool isTextFile: false
7 | required property var db
8 | required property var txt
9 | id: root
10 | title: isTextFile ? "Choose a txt file with one domain per line" : isFirefox ? "Please choose the Firefox places.sqlite file" : "Please choose the Chrome/Edge History file"
11 | nameFilters: isTextFile ? [ "text file (*.txt)", "All files (*)" ] : isFirefox ? [ "places.sqlite (places.sqlite)", "All files (*)" ] : [ "History (History)", "All files (*)" ]
12 | folder: shortcuts.home
13 | onAccepted: {
14 | txt.hostnames = ""
15 | db.hostnames = ""
16 | if(root.isTextFile) {
17 | txt.getHostnamesFromTextFile(root.fileUrl)
18 | } else {
19 | if(!db.openDb(root.fileUrl)) {
20 | infoText.text = "Error opening db file!"
21 | } else {
22 | db.isFirefox = root.isFirefox;
23 | db.getHostnamesFromDb();
24 | }
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/filters/alloffilter.cpp:
--------------------------------------------------------------------------------
1 | #include "alloffilter.h"
2 |
3 | namespace qqsfpm {
4 |
5 | /*!
6 | \qmltype AllOf
7 | \inherits Filter
8 | \inqmlmodule SortFilterProxyModel
9 | \ingroup Filters
10 | \ingroup FilterContainer
11 | \brief Filter container accepting rows accepted by all its child filters.
12 |
13 | The AllOf type is a \l Filter container that accepts rows if all of its contained (and enabled) filters accept them, or if it has no filter.
14 |
15 | Using it as a top level filter has the same effect as putting all its child filters as top level filters. It can however be usefull to use an AllOf filter when nested in an AnyOf filter.
16 | \sa FilterContainer
17 | */
18 | bool AllOfFilter::filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const
19 | {
20 | //return true if all filters return false, or if there is no filter.
21 | return std::all_of(m_filters.begin(), m_filters.end(),
22 | [&sourceIndex, &proxyModel] (Filter* filter) {
23 | return filter->filterAcceptsRow(sourceIndex, proxyModel);
24 | }
25 | );
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/proxyroles/expressionrole.h:
--------------------------------------------------------------------------------
1 | #ifndef EXPRESSIONROLE_H
2 | #define EXPRESSIONROLE_H
3 |
4 | #include "singlerole.h"
5 | #include
6 |
7 | class QQmlExpression;
8 |
9 | namespace qqsfpm {
10 |
11 | class ExpressionRole : public SingleRole
12 | {
13 | Q_OBJECT
14 | Q_PROPERTY(QQmlScriptString expression READ expression WRITE setExpression NOTIFY expressionChanged)
15 |
16 | public:
17 | using SingleRole::SingleRole;
18 |
19 | const QQmlScriptString& expression() const;
20 | void setExpression(const QQmlScriptString& scriptString);
21 |
22 | void proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel) override;
23 |
24 | Q_SIGNALS:
25 | void expressionChanged();
26 |
27 | private:
28 | QVariant data(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) override;
29 | void updateContext(const QQmlSortFilterProxyModel& proxyModel);
30 | void updateExpression();
31 |
32 | QQmlScriptString m_scriptString;
33 | QQmlExpression* m_expression = nullptr;
34 | QQmlContext* m_context = nullptr;
35 | };
36 |
37 | }
38 |
39 | #endif // EXPRESSIONROLE_H
40 |
--------------------------------------------------------------------------------
/src/listmodel/caissuerlistmodel.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 Remy van Elst https://raymii.org
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, version 3.
7 | *
8 | * This program is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 | * General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | #pragma once
18 |
19 | #include "src/ca/certificate.h"
20 | #include "genericlistmodel.h"
21 | #include
22 | #include
23 |
24 | class CACertificateListModel : public GenericListModel
25 | {
26 | Q_OBJECT
27 | public:
28 | CACertificateListModel(QObject* parent = nullptr);
29 | void addOrUpdateItem(const Certificate& itemToAdd, const QString& findBySubject);
30 | };
31 |
32 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/filters/expressionfilter.h:
--------------------------------------------------------------------------------
1 | #ifndef EXPRESSIONFILTER_H
2 | #define EXPRESSIONFILTER_H
3 |
4 | #include "filter.h"
5 | #include
6 |
7 | class QQmlExpression;
8 |
9 | namespace qqsfpm {
10 |
11 | class ExpressionFilter : public Filter
12 | {
13 | Q_OBJECT
14 | Q_PROPERTY(QQmlScriptString expression READ expression WRITE setExpression NOTIFY expressionChanged)
15 |
16 | public:
17 | using Filter::Filter;
18 |
19 | const QQmlScriptString& expression() const;
20 | void setExpression(const QQmlScriptString& scriptString);
21 |
22 | void proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel) override;
23 |
24 | protected:
25 | bool filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const override;
26 |
27 | Q_SIGNALS:
28 | void expressionChanged();
29 |
30 | private:
31 | void updateContext(const QQmlSortFilterProxyModel& proxyModel);
32 | void updateExpression();
33 |
34 | QQmlScriptString m_scriptString;
35 | QQmlExpression* m_expression = nullptr;
36 | QQmlContext* m_context = nullptr;
37 | };
38 |
39 | }
40 |
41 | #endif // EXPRESSIONFILTER_H
42 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/filters/regexpfilter.h:
--------------------------------------------------------------------------------
1 | #ifndef REGEXPFILTER_H
2 | #define REGEXPFILTER_H
3 |
4 | #include "rolefilter.h"
5 |
6 | #include
7 |
8 | namespace qqsfpm {
9 |
10 | class RegExpFilter : public RoleFilter {
11 | Q_OBJECT
12 | Q_PROPERTY(QString pattern READ pattern WRITE setPattern NOTIFY patternChanged)
13 | Q_PROPERTY(Qt::CaseSensitivity caseSensitivity READ caseSensitivity WRITE setCaseSensitivity NOTIFY caseSensitivityChanged)
14 |
15 | public:
16 | using RoleFilter::RoleFilter;
17 |
18 | RegExpFilter();
19 |
20 | QString pattern() const;
21 | void setPattern(const QString& pattern);
22 |
23 | Qt::CaseSensitivity caseSensitivity() const;
24 | void setCaseSensitivity(Qt::CaseSensitivity caseSensitivity);
25 |
26 | protected:
27 | bool filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const override;
28 |
29 | Q_SIGNALS:
30 | void patternChanged();
31 | void caseSensitivityChanged();
32 |
33 | private:
34 | QRegularExpression m_regExp;
35 | Qt::CaseSensitivity m_caseSensitivity;
36 | QString m_pattern = m_regExp.pattern();
37 | };
38 |
39 | }
40 |
41 | #endif // REGEXPFILTER_H
42 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/sorters/expressionsorter.h:
--------------------------------------------------------------------------------
1 | #ifndef EXPRESSIONSORTER_H
2 | #define EXPRESSIONSORTER_H
3 |
4 | #include "sorter.h"
5 | #include
6 |
7 | class QQmlExpression;
8 |
9 | namespace qqsfpm {
10 |
11 | class QQmlSortFilterProxyModel;
12 |
13 | class ExpressionSorter : public Sorter
14 | {
15 | Q_OBJECT
16 | Q_PROPERTY(QQmlScriptString expression READ expression WRITE setExpression NOTIFY expressionChanged)
17 |
18 | public:
19 | using Sorter::Sorter;
20 |
21 | const QQmlScriptString& expression() const;
22 | void setExpression(const QQmlScriptString& scriptString);
23 |
24 | void proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel) override;
25 |
26 | Q_SIGNALS:
27 | void expressionChanged();
28 |
29 | protected:
30 | int compare(const QModelIndex& sourceLeft, const QModelIndex& sourceRight, const QQmlSortFilterProxyModel& proxyModel) const override;
31 |
32 | private:
33 | void updateContext(const QQmlSortFilterProxyModel& proxyModel);
34 | void updateExpression();
35 |
36 | QQmlScriptString m_scriptString;
37 | QQmlExpression* m_expression = nullptr;
38 | QQmlContext* m_context = nullptr;
39 | };
40 |
41 | }
42 |
43 | #endif // EXPRESSIONSORTER_H
44 |
--------------------------------------------------------------------------------
/.github/workflows/qmake.yml:
--------------------------------------------------------------------------------
1 | # This starter workflow is for a CMake project running on a single platform. There is a different starter workflow if you need cross-platform coverage.
2 | # See: https://github.com/actions/starter-workflows/blob/main/ci/cmake-multi-platform.yml
3 | name: CMake on a single platform
4 |
5 | on:
6 | push:
7 | branches: [ "master", "citest" ]
8 | pull_request:
9 | branches: [ "master", "citest" ]
10 |
11 | env:
12 | # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
13 | BUILD_TYPE: Release
14 |
15 | jobs:
16 | build:
17 | runs-on: ubuntu-latest
18 |
19 | steps:
20 | - uses: actions/checkout@v3
21 |
22 | - name: install qt
23 | run: sudo apt-get update && sudo apt-get -qy install qtdeclarative5-dev qtbase5-dev qt5-qmake qtquickcontrols2-5-dev software-properties-common qttools5-dev-tools qtbase5-dev libqt5svg5-dev qtdeclarative5-dev-tools qml-module-qtquick-controls
24 |
25 | - name: Build folder
26 | run: mkdir -p build
27 |
28 | - name: Configure QMake
29 | working-directory: ${{github.workspace}}/build
30 | run: qmake ../CertInfo.pro CONFIG+=qtquickcompiler
31 |
32 | - name: Build
33 | working-directory: ${{github.workspace}}/build
34 | run: make -j
35 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/filters/filter.h:
--------------------------------------------------------------------------------
1 | #ifndef FILTER_H
2 | #define FILTER_H
3 |
4 | #include
5 |
6 | namespace qqsfpm {
7 |
8 | class QQmlSortFilterProxyModel;
9 |
10 | class Filter : public QObject
11 | {
12 | Q_OBJECT
13 | Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
14 | Q_PROPERTY(bool inverted READ inverted WRITE setInverted NOTIFY invertedChanged)
15 |
16 | public:
17 | explicit Filter(QObject *parent = nullptr);
18 | virtual ~Filter() = default;
19 |
20 | bool enabled() const;
21 | void setEnabled(bool enabled);
22 |
23 | bool inverted() const;
24 | void setInverted(bool inverted);
25 |
26 | bool filterAcceptsRow(const QModelIndex &sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const;
27 |
28 | virtual void proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel);
29 |
30 | Q_SIGNALS:
31 | void enabledChanged();
32 | void invertedChanged();
33 | void invalidated();
34 |
35 | protected:
36 | virtual bool filterRow(const QModelIndex &sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const = 0;
37 | void invalidate();
38 |
39 | private:
40 | bool m_enabled = true;
41 | bool m_inverted = false;
42 | };
43 |
44 | }
45 |
46 | #endif // FILTER_H
47 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/filters/filtersqmltypes.cpp:
--------------------------------------------------------------------------------
1 | #include "filter.h"
2 | #include "valuefilter.h"
3 | #include "indexfilter.h"
4 | #include "regexpfilter.h"
5 | #include "rangefilter.h"
6 | #include "expressionfilter.h"
7 | #include "anyoffilter.h"
8 | #include "alloffilter.h"
9 | #include
10 | #include
11 |
12 | namespace qqsfpm {
13 |
14 | void registerFiltersTypes() {
15 | qmlRegisterUncreatableType("SortFilterProxyModel", 0, 2, "Filter", "Filter is an abstract class");
16 | qmlRegisterType("SortFilterProxyModel", 0, 2, "ValueFilter");
17 | qmlRegisterType("SortFilterProxyModel", 0, 2, "IndexFilter");
18 | qmlRegisterType("SortFilterProxyModel", 0, 2, "RegExpFilter");
19 | qmlRegisterType("SortFilterProxyModel", 0, 2, "RangeFilter");
20 | qmlRegisterType("SortFilterProxyModel", 0, 2, "ExpressionFilter");
21 | qmlRegisterType("SortFilterProxyModel", 0, 2, "AnyOf");
22 | qmlRegisterType("SortFilterProxyModel", 0, 2, "AllOf");
23 | qmlRegisterUncreatableType("SortFilterProxyModel", 0, 2, "FilterContainer", "FilterContainer can only be used as an attaching type");
24 | }
25 |
26 | Q_COREAPP_STARTUP_FUNCTION(registerFiltersTypes)
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #
2 | *.sqlite
3 | history
4 | History
5 | # ---> Qt
6 | # C++ objects and libs
7 | *.slo
8 | *.lo
9 | *.o
10 | *.a
11 | *.la
12 | *.lai
13 | *.so
14 | *.so.*
15 | *.dll
16 | *.dylib
17 |
18 | # Qt-es
19 | object_script.*.Release
20 | object_script.*.Debug
21 | *_plugin_import.cpp
22 | /.qmake.cache
23 | /.qmake.stash
24 | *.pro.user
25 | *.pro.user.*
26 | *.qbs.user
27 | *.qbs.user.*
28 | *.moc
29 | moc_*.cpp
30 | moc_*.h
31 | qrc_*.cpp
32 | ui_*.h
33 | *.qmlc
34 | *.jsc
35 | Makefile*
36 | *build-*
37 | *.qm
38 | *.prl
39 |
40 | # Qt unit tests
41 | target_wrapper.*
42 |
43 | # QtCreator
44 | *.autosave
45 |
46 | # QtCreator Qml
47 | *.qmlproject.user
48 | *.qmlproject.user.*
49 |
50 | # QtCreator CMake
51 | CMakeLists.txt.user*
52 |
53 | # QtCreator 4.8< compilation database
54 | compile_commands.json
55 |
56 | # QtCreator local machine specific files for imported projects
57 | *creator.user*
58 |
59 | *_qmlcache.qrc
60 |
61 | # ---> C++
62 | # Prerequisites
63 | *.d
64 |
65 | # Compiled Object files
66 | *.slo
67 | *.lo
68 | *.o
69 | *.obj
70 |
71 | # Precompiled Headers
72 | *.gch
73 | *.pch
74 |
75 | # Compiled Dynamic libraries
76 | *.so
77 | *.dylib
78 | *.dll
79 |
80 | # Fortran module files
81 | *.mod
82 | *.smod
83 |
84 | # Compiled Static libraries
85 | *.lai
86 | *.la
87 | *.a
88 | *.lib
89 |
90 | # Executables
91 | *.exe
92 | *.out
93 | *.app
94 |
95 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/proxyroles/regexprole.h:
--------------------------------------------------------------------------------
1 | #ifndef REGEXPROLE_H
2 | #define REGEXPROLE_H
3 |
4 | #include "proxyrole.h"
5 | #include
6 |
7 | namespace qqsfpm {
8 |
9 | class RegExpRole : public ProxyRole
10 | {
11 | Q_OBJECT
12 | Q_PROPERTY(QString roleName READ roleName WRITE setRoleName NOTIFY roleNameChanged)
13 | Q_PROPERTY(QString pattern READ pattern WRITE setPattern NOTIFY patternChanged)
14 | Q_PROPERTY(Qt::CaseSensitivity caseSensitivity READ caseSensitivity WRITE setCaseSensitivity NOTIFY caseSensitivityChanged)
15 |
16 | public:
17 | using ProxyRole::ProxyRole;
18 |
19 | QString roleName() const;
20 | void setRoleName(const QString& roleName);
21 |
22 | QString pattern() const;
23 | void setPattern(const QString& pattern);
24 |
25 | Qt::CaseSensitivity caseSensitivity() const;
26 | void setCaseSensitivity(Qt::CaseSensitivity caseSensitivity);
27 |
28 | QStringList names() override;
29 |
30 | Q_SIGNALS:
31 | void roleNameChanged();
32 | void patternChanged();
33 | void caseSensitivityChanged();
34 |
35 | private:
36 | QString m_roleName;
37 | QRegularExpression m_regularExpression;
38 | QVariant data(const QModelIndex &sourceIndex, const QQmlSortFilterProxyModel &proxyModel, const QString &name) override;
39 | };
40 |
41 | }
42 |
43 | #endif // REGEXPROLE_H
44 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/filters/rolefilter.cpp:
--------------------------------------------------------------------------------
1 | #include "rolefilter.h"
2 | #include "qqmlsortfilterproxymodel.h"
3 |
4 | namespace qqsfpm {
5 |
6 | /*!
7 | \qmltype RoleFilter
8 | \qmlabstract
9 | \inherits Filter
10 | \inqmlmodule SortFilterProxyModel
11 | \ingroup Filters
12 | \brief Base type for filters based on a source model role.
13 |
14 | The RoleFilter type cannot be used directly in a QML file.
15 | It exists to provide a set of common properties and methods,
16 | available across all the other filter types that inherit from it.
17 | Attempting to use the RoleFilter type directly will result in an error.
18 | */
19 |
20 | /*!
21 | \qmlproperty string RoleFilter::roleName
22 |
23 | This property holds the role name that the filter is using to query the source model's data when filtering items.
24 | */
25 | const QString& RoleFilter::roleName() const
26 | {
27 | return m_roleName;
28 | }
29 |
30 | void RoleFilter::setRoleName(const QString& roleName)
31 | {
32 | if (m_roleName == roleName)
33 | return;
34 |
35 | m_roleName = roleName;
36 | Q_EMIT roleNameChanged();
37 | invalidate();
38 | }
39 |
40 | QVariant RoleFilter::sourceData(const QModelIndex &sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const
41 | {
42 | return proxyModel.sourceData(sourceIndex, m_roleName);
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/proxyroles/proxyrole.cpp:
--------------------------------------------------------------------------------
1 | #include "proxyrole.h"
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include "filters/filter.h"
9 | #include "qqmlsortfilterproxymodel.h"
10 |
11 | namespace qqsfpm {
12 |
13 | /*!
14 | \qmltype ProxyRole
15 | \inqmlmodule SortFilterProxyModel
16 | \ingroup ProxyRoles
17 | \brief Base type for the \l SortFilterProxyModel proxy roles.
18 |
19 | The ProxyRole type cannot be used directly in a QML file.
20 | It exists to provide a set of common properties and methods,
21 | available across all the other proxy role types that inherit from it.
22 | Attempting to use the ProxyRole type directly will result in an error.
23 | */
24 |
25 | QVariant ProxyRole::roleData(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel, const QString &name)
26 | {
27 | if (m_mutex.tryLock()) {
28 | QVariant result = data(sourceIndex, proxyModel, name);
29 | m_mutex.unlock();
30 | return result;
31 | } else {
32 | return {};
33 | }
34 | }
35 |
36 | void ProxyRole::proxyModelCompleted(const QQmlSortFilterProxyModel &proxyModel)
37 | {
38 | Q_UNUSED(proxyModel)
39 | }
40 |
41 | void ProxyRole::invalidate()
42 | {
43 | Q_EMIT invalidated();
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/proxyroles/singlerole.cpp:
--------------------------------------------------------------------------------
1 | #include "singlerole.h"
2 | #include
3 |
4 | namespace qqsfpm {
5 |
6 | /*!
7 | \qmltype SingleRole
8 | \qmlabstract
9 | \inherits ProxyRole
10 | \inqmlmodule SortFilterProxyModel
11 | \ingroup ProxyRoles
12 | \brief Base type for the \l SortFilterProxyModel proxy roles defining a single role.
13 |
14 | SingleRole is a convenience base class for proxy roles who define a single role.
15 | It cannot be used directly in a QML file.
16 | It exists to provide a set of common properties and methods,
17 | available across all the other proxy role types that inherit from it.
18 | Attempting to use the SingleRole type directly will result in an error.
19 | */
20 | /*!
21 | \qmlproperty string SingleRole::name
22 |
23 | This property holds the role name of the proxy role.
24 | */
25 | QString SingleRole::name() const
26 | {
27 | return m_name;
28 | }
29 |
30 | void SingleRole::setName(const QString& name)
31 | {
32 | if (m_name == name)
33 | return;
34 |
35 | Q_EMIT namesAboutToBeChanged();
36 | m_name = name;
37 | Q_EMIT nameChanged();
38 | Q_EMIT namesChanged();
39 | }
40 |
41 | QStringList SingleRole::names()
42 | {
43 | return QStringList { m_name };
44 | }
45 |
46 | QVariant SingleRole::data(const QModelIndex &sourceIndex, const QQmlSortFilterProxyModel &proxyModel, const QString &name)
47 | {
48 | Q_UNUSED(name);
49 | return data(sourceIndex, proxyModel);
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/sorters/stringsorter.h:
--------------------------------------------------------------------------------
1 | #ifndef STRINGSORTER_H
2 | #define STRINGSORTER_H
3 |
4 | #include "rolesorter.h"
5 | #include
6 |
7 | namespace qqsfpm {
8 |
9 | class StringSorter : public RoleSorter
10 | {
11 | Q_OBJECT
12 | Q_PROPERTY(Qt::CaseSensitivity caseSensitivity READ caseSensitivity WRITE setCaseSensitivity NOTIFY caseSensitivityChanged)
13 | Q_PROPERTY(bool ignorePunctation READ ignorePunctation WRITE setIgnorePunctation NOTIFY ignorePunctationChanged)
14 | Q_PROPERTY(QLocale locale READ locale WRITE setLocale NOTIFY localeChanged)
15 | Q_PROPERTY(bool numericMode READ numericMode WRITE setNumericMode NOTIFY numericModeChanged)
16 |
17 | public:
18 | using RoleSorter::RoleSorter;
19 |
20 | Qt::CaseSensitivity caseSensitivity() const;
21 | void setCaseSensitivity(Qt::CaseSensitivity caseSensitivity);
22 |
23 | bool ignorePunctation() const;
24 | void setIgnorePunctation(bool ignorePunctation);
25 |
26 | QLocale locale() const;
27 | void setLocale(const QLocale& locale);
28 |
29 | bool numericMode() const;
30 | void setNumericMode(bool numericMode);
31 |
32 | Q_SIGNALS:
33 | void caseSensitivityChanged();
34 | void ignorePunctationChanged();
35 | void localeChanged();
36 | void numericModeChanged();
37 |
38 | protected:
39 | int compare(const QModelIndex& sourceLeft, const QModelIndex& sourceRight, const QQmlSortFilterProxyModel& proxyModel) const override;
40 |
41 | private:
42 | QCollator m_collator;
43 | };
44 |
45 | }
46 |
47 | #endif // STRINGSORTER_H
48 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/proxyroles/proxyrolecontainer.h:
--------------------------------------------------------------------------------
1 | #ifndef PROXYROLECONTAINER_H
2 | #define PROXYROLECONTAINER_H
3 |
4 | #include
5 | #include
6 |
7 | namespace qqsfpm {
8 |
9 | class ProxyRole;
10 | class QQmlSortFilterProxyModel;
11 |
12 | class ProxyRoleContainer {
13 | public:
14 | virtual ~ProxyRoleContainer() = default;
15 |
16 | QList proxyRoles() const;
17 | void appendProxyRole(ProxyRole* proxyRole);
18 | void removeProxyRole(ProxyRole* proxyRole);
19 | void clearProxyRoles();
20 |
21 | QQmlListProperty proxyRolesListProperty();
22 |
23 | protected:
24 | QList m_proxyRoles;
25 |
26 | private:
27 | virtual void onProxyRoleAppended(ProxyRole* proxyRole) = 0;
28 | virtual void onProxyRoleRemoved(ProxyRole* proxyRole) = 0;
29 | virtual void onProxyRolesCleared() = 0;
30 |
31 | #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
32 | using sizetype = int;
33 | #else
34 | using sizetype = qsizetype;
35 | #endif
36 |
37 | static void append_proxyRole(QQmlListProperty* list, ProxyRole* proxyRole);
38 | static sizetype count_proxyRole(QQmlListProperty* list);
39 | static ProxyRole* at_proxyRole(QQmlListProperty* list, sizetype index);
40 | static void clear_proxyRoles(QQmlListProperty* list);
41 | };
42 |
43 | }
44 |
45 | #define ProxyRoleContainer_iid "fr.grecko.SortFilterProxyModel.ProxyRoleContainer"
46 | Q_DECLARE_INTERFACE(qqsfpm::ProxyRoleContainer, ProxyRoleContainer_iid)
47 |
48 | #endif // PROXYROLECONTAINER_H
49 |
--------------------------------------------------------------------------------
/src/ca/caprocessor.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 Remy van Elst https://raymii.org
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, version 3.
7 | *
8 | * This program is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 | * General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | #pragma once
18 |
19 | #include "certificate.h"
20 |
21 | #include
22 | #include
23 | #include
24 |
25 | class QNetworkReply;
26 |
27 | class CAProcessor : public QObject
28 | {
29 | Q_OBJECT
30 | public:
31 | explicit CAProcessor(QObject *parent = nullptr);
32 |
33 | static QList getCertificate(const QString& domain);
34 | static bool isCA(const QSslCertificate& cert);
35 |
36 | static Certificate parseQSslCertificateToCertificate(const QSslCertificate& cert);
37 |
38 | signals:
39 |
40 | private slots:
41 | static void ignoreSslErrors(QNetworkReply* reply);
42 |
43 | private:
44 | static void extractSubject(const QSslCertificate& cert, Certificate& out_issuer);
45 | static void extractCertificate(const QSslCertificate& cert, Certificate& out_issuer);
46 | };
47 |
48 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/filters/rangefilter.h:
--------------------------------------------------------------------------------
1 | #ifndef RANGEFILTER_H
2 | #define RANGEFILTER_H
3 |
4 | #include "rolefilter.h"
5 | #include
6 |
7 | namespace qqsfpm {
8 |
9 | class RangeFilter : public RoleFilter
10 | {
11 | Q_OBJECT
12 | Q_PROPERTY(QVariant minimumValue READ minimumValue WRITE setMinimumValue NOTIFY minimumValueChanged)
13 | Q_PROPERTY(bool minimumInclusive READ minimumInclusive WRITE setMinimumInclusive NOTIFY minimumInclusiveChanged)
14 | Q_PROPERTY(QVariant maximumValue READ maximumValue WRITE setMaximumValue NOTIFY maximumValueChanged)
15 | Q_PROPERTY(bool maximumInclusive READ maximumInclusive WRITE setMaximumInclusive NOTIFY maximumInclusiveChanged)
16 |
17 | public:
18 | using RoleFilter::RoleFilter;
19 |
20 | QVariant minimumValue() const;
21 | void setMinimumValue(QVariant minimumValue);
22 | bool minimumInclusive() const;
23 | void setMinimumInclusive(bool minimumInclusive);
24 |
25 | QVariant maximumValue() const;
26 | void setMaximumValue(QVariant maximumValue);
27 | bool maximumInclusive() const;
28 | void setMaximumInclusive(bool maximumInclusive);
29 |
30 | protected:
31 | bool filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const override;
32 |
33 | Q_SIGNALS:
34 | void minimumValueChanged();
35 | void minimumInclusiveChanged();
36 | void maximumValueChanged();
37 | void maximumInclusiveChanged();
38 |
39 | private:
40 | QVariant m_minimumValue;
41 | bool m_minimumInclusive = true;
42 | QVariant m_maximumValue;
43 | bool m_maximumInclusive = true;
44 | };
45 |
46 | }
47 |
48 | #endif // RANGEFILTER_H
49 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/filters/anyoffilter.cpp:
--------------------------------------------------------------------------------
1 | #include "anyoffilter.h"
2 |
3 | namespace qqsfpm {
4 |
5 | /*!
6 | \qmltype AnyOf
7 | \inherits Filter
8 | \inqmlmodule SortFilterProxyModel
9 | \ingroup Filters
10 | \ingroup FilterContainer
11 | \brief Filter container accepting rows accepted by at least one of its child filters.
12 |
13 | The AnyOf type is a \l Filter container that accepts rows if any of its contained (and enabled) filters accept them.
14 |
15 | In the following example, only the rows where the \c firstName role or the \c lastName role match the text entered in the \c nameTextField will be accepted :
16 | \code
17 | TextField {
18 | id: nameTextField
19 | }
20 |
21 | SortFilterProxyModel {
22 | sourceModel: contactModel
23 | filters: AnyOf {
24 | RegExpFilter {
25 | roleName: "lastName"
26 | pattern: nameTextField.text
27 | caseSensitivity: Qt.CaseInsensitive
28 | }
29 | RegExpFilter {
30 | roleName: "firstName"
31 | pattern: nameTextField.text
32 | caseSensitivity: Qt.CaseInsensitive
33 | }
34 | }
35 | }
36 | \endcode
37 | \sa FilterContainer
38 | */
39 | bool AnyOfFilter::filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const
40 | {
41 | //return true if any of the enabled filters return true
42 | return std::any_of(m_filters.begin(), m_filters.end(),
43 | [&sourceIndex, &proxyModel] (Filter* filter) {
44 | return filter->enabled() && filter->filterAcceptsRow(sourceIndex, proxyModel);
45 | }
46 | );
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/flake.lock:
--------------------------------------------------------------------------------
1 | {
2 | "nodes": {
3 | "flake-utils": {
4 | "inputs": {
5 | "systems": "systems"
6 | },
7 | "locked": {
8 | "lastModified": 1681202837,
9 | "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
10 | "owner": "numtide",
11 | "repo": "flake-utils",
12 | "rev": "cfacdce06f30d2b68473a46042957675eebb3401",
13 | "type": "github"
14 | },
15 | "original": {
16 | "owner": "numtide",
17 | "repo": "flake-utils",
18 | "type": "github"
19 | }
20 | },
21 | "nixpkgs": {
22 | "locked": {
23 | "lastModified": 1704008649,
24 | "narHash": "sha256-rGPSWjXTXTurQN9beuHdyJhB8O761w1Zc5BqSSmHvoM=",
25 | "owner": "NixOS",
26 | "repo": "nixpkgs",
27 | "rev": "d44d59d2b5bd694cd9d996fd8c51d03e3e9ba7f7",
28 | "type": "github"
29 | },
30 | "original": {
31 | "owner": "NixOS",
32 | "ref": "nixpkgs-unstable",
33 | "repo": "nixpkgs",
34 | "type": "github"
35 | }
36 | },
37 | "root": {
38 | "inputs": {
39 | "flake-utils": "flake-utils",
40 | "nixpkgs": "nixpkgs"
41 | }
42 | },
43 | "systems": {
44 | "locked": {
45 | "lastModified": 1681028828,
46 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
47 | "owner": "nix-systems",
48 | "repo": "default",
49 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
50 | "type": "github"
51 | },
52 | "original": {
53 | "owner": "nix-systems",
54 | "repo": "default",
55 | "type": "github"
56 | }
57 | }
58 | },
59 | "root": "root",
60 | "version": 7
61 | }
62 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/sorters/sorter.h:
--------------------------------------------------------------------------------
1 | #ifndef SORTER_H
2 | #define SORTER_H
3 |
4 | #include
5 |
6 | namespace qqsfpm {
7 |
8 | class QQmlSortFilterProxyModel;
9 |
10 | class Sorter : public QObject
11 | {
12 | Q_OBJECT
13 | Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
14 | Q_PROPERTY(bool ascendingOrder READ ascendingOrder WRITE setAscendingOrder NOTIFY sortOrderChanged)
15 | Q_PROPERTY(Qt::SortOrder sortOrder READ sortOrder WRITE setSortOrder NOTIFY sortOrderChanged)
16 | Q_PROPERTY(int priority READ priority WRITE setPriority NOTIFY priorityChanged)
17 |
18 | public:
19 | Sorter(QObject* parent = nullptr);
20 | virtual ~Sorter() = 0;
21 |
22 | bool enabled() const;
23 | void setEnabled(bool enabled);
24 |
25 | bool ascendingOrder() const;
26 | void setAscendingOrder(bool ascendingOrder);
27 |
28 | Qt::SortOrder sortOrder() const;
29 | void setSortOrder(Qt::SortOrder sortOrder);
30 |
31 | int priority() const;
32 | void setPriority(int priority);
33 |
34 | int compareRows(const QModelIndex& source_left, const QModelIndex& source_right, const QQmlSortFilterProxyModel& proxyModel) const;
35 |
36 | virtual void proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel);
37 |
38 | Q_SIGNALS:
39 | void enabledChanged();
40 | void sortOrderChanged();
41 | void priorityChanged();
42 |
43 | void invalidated();
44 |
45 | protected:
46 | virtual int compare(const QModelIndex& sourceLeft, const QModelIndex& sourceRight, const QQmlSortFilterProxyModel& proxyModel) const;
47 | virtual bool lessThan(const QModelIndex& sourceLeft, const QModelIndex& sourceRight, const QQmlSortFilterProxyModel& proxyModel) const;
48 | void invalidate();
49 |
50 | private:
51 | bool m_enabled = true;
52 | Qt::SortOrder m_sortOrder = Qt::AscendingOrder;
53 | int m_priority = 0;
54 | };
55 |
56 | }
57 |
58 | #endif // SORTER_H
59 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/proxyroles/filterrole.cpp:
--------------------------------------------------------------------------------
1 | #include "filterrole.h"
2 | #include "filters/filter.h"
3 |
4 | namespace qqsfpm {
5 |
6 | /*!
7 | \qmltype FilterRole
8 | \inherits SingleRole
9 | \inqmlmodule SortFilterProxyModel
10 | \ingroup ProxyRoles
11 | \ingroup FilterContainer
12 | \brief A role resolving to \c true for rows matching all its filters.
13 |
14 | A FilterRole is a \l ProxyRole that returns \c true for rows matching all its filters.
15 |
16 | In the following example, the \c isAdult role will be equal to \c true if the \c age role is superior or equal to 18.
17 | \code
18 | SortFilterProxyModel {
19 | sourceModel: personModel
20 | proxyRoles: FilterRole {
21 | name: "isAdult"
22 | RangeFilter { roleName: "age"; minimumValue: 18; minimumInclusive: true }
23 | }
24 | }
25 | \endcode
26 | \sa FilterContainer
27 | */
28 |
29 | /*!
30 | \qmlproperty list FilterRole::filters
31 | \default
32 |
33 | This property holds the list of filters for this filter role.
34 | The data of this role will be equal to the \c true if all its filters match the model row, \c false otherwise.
35 |
36 | \sa Filter, FilterContainer
37 | */
38 |
39 | void FilterRole::onFilterAppended(Filter* filter)
40 | {
41 | connect(filter, &Filter::invalidated, this, &FilterRole::invalidate);
42 | invalidate();
43 | }
44 |
45 | void FilterRole::onFilterRemoved(Filter* filter)
46 | {
47 | disconnect(filter, &Filter::invalidated, this, &FilterRole::invalidate);
48 | invalidate();
49 | }
50 |
51 | void FilterRole::onFiltersCleared()
52 | {
53 | invalidate();
54 | }
55 |
56 | QVariant FilterRole::data(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel)
57 | {
58 | return std::all_of(m_filters.begin(), m_filters.end(),
59 | [&] (Filter* filter) {
60 | return filter->filterAcceptsRow(sourceIndex, proxyModel);
61 | }
62 | );
63 | }
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/filters/valuefilter.cpp:
--------------------------------------------------------------------------------
1 | #include "valuefilter.h"
2 |
3 | namespace qqsfpm {
4 |
5 | /*!
6 | \qmltype ValueFilter
7 | \inherits RoleFilter
8 | \inqmlmodule SortFilterProxyModel
9 | \ingroup Filters
10 | \brief Filters rows matching exactly a value.
11 |
12 | A ValueFilter is a simple \l RoleFilter that accepts rows matching exactly the filter's value
13 |
14 | In the following example, only rows with their \c favorite role set to \c true will be accepted when the checkbox is checked :
15 | \code
16 | CheckBox {
17 | id: showOnlyFavoriteCheckBox
18 | }
19 |
20 | SortFilterProxyModel {
21 | sourceModel: contactModel
22 | filters: ValueFilter {
23 | roleName: "favorite"
24 | value: true
25 | enabled: showOnlyFavoriteCheckBox.checked
26 | }
27 | }
28 | \endcode
29 |
30 | */
31 |
32 | /*!
33 | \qmlproperty variant ValueFilter::value
34 |
35 | This property holds the value used to filter the contents of the source model.
36 | */
37 | const QVariant &ValueFilter::value() const
38 | {
39 | return m_value;
40 | }
41 |
42 | void ValueFilter::setValue(const QVariant& value)
43 | {
44 | if (m_value == value)
45 | return;
46 |
47 | m_value = value;
48 | Q_EMIT valueChanged();
49 | invalidate();
50 | }
51 |
52 | bool ValueFilter::filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const
53 | {
54 | QVariant srcData = sourceData(sourceIndex, proxyModel);
55 | #if QT_VERSION > QT_VERSION_CHECK(6, 0, 0)
56 | // Implicitly convert the types. This was the behavior in Qt5 and makes QML
57 | // interop much easier, e.g. when comparing QByteArray against QString
58 | if (srcData.metaType() != m_value.metaType()) {
59 | QVariant converted = srcData;
60 | if (converted.convert(m_value.metaType())) {
61 | srcData = converted;
62 | }
63 | }
64 | #endif
65 | return !m_value.isValid() || m_value == srcData;
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/src/listmodel/qabstractlistmodelwithrowcountsignal.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 Remy van Elst https://raymii.org
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, version 3.
7 | *
8 | * This program is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 | * General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 | #pragma once
17 |
18 | #include
19 |
20 |
21 | class QAbstractListModelWithRowCountSignal : public QAbstractListModel
22 | {
23 | Q_OBJECT
24 | Q_PROPERTY(int rowCount READ rowCount NOTIFY rowCountChanged)
25 |
26 | public:
27 | virtual ~QAbstractListModelWithRowCountSignal() = default;
28 |
29 | protected:
30 | QAbstractListModelWithRowCountSignal(QObject *parent = nullptr) :
31 | QAbstractListModel(parent)
32 | {
33 | QObject::connect(this, &QAbstractListModel::rowsInserted, this, &QAbstractListModelWithRowCountSignal::rowCountChanged);
34 | QObject::connect(this, &QAbstractListModel::rowsRemoved, this, &QAbstractListModelWithRowCountSignal::rowCountChanged);
35 | QObject::connect(this, &QAbstractListModel::modelReset, this, &QAbstractListModelWithRowCountSignal::rowCountChanged);
36 | QObject::connect(this, &QAbstractListModel::layoutChanged, this, &QAbstractListModelWithRowCountSignal::rowCountChanged);
37 | QObject::connect(this, &QAbstractListModel::rowsMoved, this, &QAbstractListModelWithRowCountSignal::rowCountChanged);
38 | QObject::connect(this, &QAbstractListModel::dataChanged, this, &QAbstractListModelWithRowCountSignal::rowCountChanged);
39 | }
40 |
41 | signals:
42 | void rowCountChanged();
43 | };
44 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/proxyroles/switchrole.h:
--------------------------------------------------------------------------------
1 | #ifndef SWITCHROLE_H
2 | #define SWITCHROLE_H
3 |
4 | #include "singlerole.h"
5 | #include "filters/filtercontainer.h"
6 | #include
7 |
8 | namespace qqsfpm {
9 |
10 | class SwitchRoleAttached : public QObject
11 | {
12 | Q_OBJECT
13 | Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged)
14 | public:
15 | SwitchRoleAttached(QObject* parent);
16 |
17 | QVariant value() const;
18 | void setValue(QVariant value);
19 |
20 | Q_SIGNALS:
21 | void valueChanged();
22 |
23 | private:
24 | QVariant m_value;
25 | };
26 |
27 | class SwitchRole : public SingleRole, public FilterContainer
28 | {
29 | Q_OBJECT
30 | Q_INTERFACES(qqsfpm::FilterContainer)
31 | Q_PROPERTY(QString defaultRoleName READ defaultRoleName WRITE setDefaultRoleName NOTIFY defaultRoleNameChanged)
32 | Q_PROPERTY(QVariant defaultValue READ defaultValue WRITE setDefaultValue NOTIFY defaultValueChanged)
33 | Q_PROPERTY(QQmlListProperty filters READ filtersListProperty)
34 | Q_CLASSINFO("DefaultProperty", "filters")
35 |
36 | public:
37 | using SingleRole::SingleRole;
38 |
39 | QString defaultRoleName() const;
40 | void setDefaultRoleName(const QString& defaultRoleName);
41 |
42 | QVariant defaultValue() const;
43 | void setDefaultValue(const QVariant& defaultValue);
44 |
45 | void proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel) override;
46 |
47 | static SwitchRoleAttached* qmlAttachedProperties(QObject* object);
48 |
49 | Q_SIGNALS:
50 | void defaultRoleNameChanged();
51 | void defaultValueChanged();
52 |
53 | private:
54 | QVariant data(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) override;
55 |
56 | void onFilterAppended(Filter *filter) override;
57 | void onFilterRemoved(Filter *filter) override;
58 | void onFiltersCleared() override;
59 |
60 | QString m_defaultRoleName;
61 | QVariant m_defaultValue;
62 | };
63 |
64 | }
65 |
66 | QML_DECLARE_TYPEINFO(qqsfpm::SwitchRole, QML_HAS_ATTACHED_PROPERTIES)
67 |
68 | #endif // SWITCHROLE_H
69 |
--------------------------------------------------------------------------------
/src/versioncheck/versioncheck.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 Remy van Elst
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, version 3.
7 | *
8 | * This program is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 | * General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | *
16 | */
17 |
18 | #pragma once
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 |
27 | class VersionCheck : public QObject
28 | {
29 | Q_OBJECT
30 | Q_PROPERTY(QString currentVersion READ currentVersion WRITE setCurrentVersion NOTIFY currentVersionChanged)
31 | Q_PROPERTY(bool newVersionAvailable READ newVersionAvailable NOTIFY newVersionAvailableChanged FINAL)
32 |
33 | public:
34 | explicit VersionCheck(QObject *parent = nullptr);
35 |
36 | //properties
37 | const QString ¤tVersion() const;
38 | bool newVersionAvailable() const;
39 |
40 | signals:
41 | void currentVersionChanged(const QString ¤tVersion);
42 | void newVersionAvailableChanged();
43 |
44 | public slots:
45 |
46 | void setCurrentVersion(const QString &newCurrentVersion);
47 | void slotFinished();
48 | void getCurrentVersion();
49 | void setNewVersionAvailable(bool newNewVersionAvailable);
50 |
51 | private:
52 | QNetworkAccessManager* _manager;
53 |
54 | QTimer* _timer;
55 | QString _currentVersion;
56 | QUrl _url = QUrl("http://update.leafnode.nl/certinfo.txt");
57 | void checkVersionOutput(const QString& newVersion);
58 | bool m_newVersionAvailable;
59 |
60 | static inline const QRegularExpression versionNumberFormat = QRegularExpression("[0-9]{4}\\.[0-9]{2}\\.[0-9]\\.[0-9]"); // 2022.01.0.0
61 |
62 |
63 |
64 | };
65 |
66 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/filters/filtercontainer.h:
--------------------------------------------------------------------------------
1 | #ifndef FILTERCONTAINER_H
2 | #define FILTERCONTAINER_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | namespace qqsfpm {
10 |
11 | class Filter;
12 | class QQmlSortFilterProxyModel;
13 |
14 | class FilterContainer {
15 | public:
16 | virtual ~FilterContainer() = default;
17 |
18 | QList filters() const;
19 | void appendFilter(Filter* filter);
20 | void removeFilter(Filter* filter);
21 | void clearFilters();
22 |
23 | QQmlListProperty filtersListProperty();
24 |
25 | protected:
26 | QList m_filters;
27 |
28 | private:
29 | virtual void onFilterAppended(Filter* filter) = 0;
30 | virtual void onFilterRemoved(Filter* filter) = 0;
31 | virtual void onFiltersCleared() = 0;
32 |
33 | #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
34 | using sizetype = int;
35 | #else
36 | using sizetype = qsizetype;
37 | #endif
38 |
39 | static void append_filter(QQmlListProperty* list, Filter* filter);
40 | static sizetype count_filter(QQmlListProperty* list);
41 | static Filter* at_filter(QQmlListProperty* list, sizetype index);
42 | static void clear_filters(QQmlListProperty* list);
43 | };
44 |
45 | class FilterContainerAttached : public QObject
46 | {
47 | Q_OBJECT
48 | Q_PROPERTY(QObject* container READ container WRITE setContainer NOTIFY containerChanged)
49 |
50 | public:
51 | FilterContainerAttached(QObject* object);
52 | ~FilterContainerAttached();
53 |
54 | QObject* container() const;
55 | void setContainer(QObject* object);
56 |
57 | static FilterContainerAttached* qmlAttachedProperties(QObject* object);
58 |
59 | Q_SIGNALS:
60 | void containerChanged();
61 |
62 | private:
63 | QPointer m_container = nullptr;
64 | Filter* m_filter = nullptr;
65 | };
66 |
67 | }
68 |
69 | #define FilterContainer_iid "fr.grecko.SortFilterProxyModel.FilterContainer"
70 | Q_DECLARE_INTERFACE(qqsfpm::FilterContainer, FilterContainer_iid)
71 |
72 | QML_DECLARE_TYPEINFO(qqsfpm::FilterContainerAttached, QML_HAS_ATTACHED_PROPERTIES)
73 |
74 | #endif // FILTERCONTAINER_H
75 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/proxyroles/proxyrolecontainer.cpp:
--------------------------------------------------------------------------------
1 | #include "proxyrolecontainer.h"
2 |
3 | namespace qqsfpm {
4 |
5 | QList ProxyRoleContainer::proxyRoles() const
6 | {
7 | return m_proxyRoles;
8 | }
9 |
10 | void ProxyRoleContainer::appendProxyRole(ProxyRole* proxyRole)
11 | {
12 | m_proxyRoles.append(proxyRole);
13 | onProxyRoleAppended(proxyRole);
14 | }
15 |
16 | void ProxyRoleContainer::removeProxyRole(ProxyRole* proxyRole)
17 | {
18 | m_proxyRoles.removeOne(proxyRole);
19 | onProxyRoleRemoved(proxyRole);
20 | }
21 |
22 | void ProxyRoleContainer::clearProxyRoles()
23 | {
24 | m_proxyRoles.clear();
25 | onProxyRolesCleared();
26 | }
27 |
28 | QQmlListProperty ProxyRoleContainer::proxyRolesListProperty()
29 | {
30 | return QQmlListProperty(reinterpret_cast(this), &m_proxyRoles,
31 | &ProxyRoleContainer::append_proxyRole,
32 | &ProxyRoleContainer::count_proxyRole,
33 | &ProxyRoleContainer::at_proxyRole,
34 | &ProxyRoleContainer::clear_proxyRoles);
35 | }
36 |
37 | void ProxyRoleContainer::append_proxyRole(QQmlListProperty* list, ProxyRole* proxyRole)
38 | {
39 | if (!proxyRole)
40 | return;
41 |
42 | ProxyRoleContainer* that = reinterpret_cast(list->object);
43 | that->appendProxyRole(proxyRole);
44 | }
45 |
46 | qqsfpm::ProxyRoleContainer::sizetype ProxyRoleContainer::count_proxyRole(QQmlListProperty* list)
47 | {
48 | QList* ProxyRoles = static_cast*>(list->data);
49 | return ProxyRoles->count();
50 | }
51 |
52 | ProxyRole* ProxyRoleContainer::at_proxyRole(QQmlListProperty* list, qqsfpm::ProxyRoleContainer::sizetype index)
53 | {
54 | QList* ProxyRoles = static_cast*>(list->data);
55 | return ProxyRoles->at(index);
56 | }
57 |
58 | void ProxyRoleContainer::clear_proxyRoles(QQmlListProperty *list)
59 | {
60 | ProxyRoleContainer* that = reinterpret_cast(list->object);
61 | that->clearProxyRoles();
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/sorters/sortercontainer.h:
--------------------------------------------------------------------------------
1 | #ifndef SORTERSSORTERCONTAINER_H
2 | #define SORTERSSORTERCONTAINER_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | namespace qqsfpm {
10 |
11 | class Sorter;
12 | class QQmlSortFilterProxyModel;
13 |
14 | class SorterContainer {
15 | public:
16 | virtual ~SorterContainer() = default;
17 |
18 | QList sorters() const;
19 | void appendSorter(Sorter* sorter);
20 | void removeSorter(Sorter* sorter);
21 | void clearSorters();
22 |
23 | QQmlListProperty sortersListProperty();
24 |
25 | protected:
26 | QList m_sorters;
27 |
28 | private:
29 | virtual void onSorterAppended(Sorter* sorter) = 0;
30 | virtual void onSorterRemoved(Sorter* sorter) = 0;
31 | virtual void onSortersCleared() = 0;
32 |
33 | #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
34 | using sizetype = int;
35 | #else
36 | using sizetype = qsizetype;
37 | #endif
38 |
39 | static void append_sorter(QQmlListProperty* list, Sorter* sorter);
40 | static sizetype count_sorter(QQmlListProperty* list);
41 | static Sorter* at_sorter(QQmlListProperty* list, sizetype index);
42 | static void clear_sorters(QQmlListProperty* list);
43 | };
44 |
45 | class SorterContainerAttached : public QObject
46 | {
47 | Q_OBJECT
48 | Q_PROPERTY(QObject* container READ container WRITE setContainer NOTIFY containerChanged)
49 |
50 | public:
51 | SorterContainerAttached(QObject* object);
52 | ~SorterContainerAttached();
53 |
54 | QObject* container() const;
55 | void setContainer(QObject* object);
56 |
57 | static SorterContainerAttached* qmlAttachedProperties(QObject* object);
58 |
59 | Q_SIGNALS:
60 | void containerChanged();
61 |
62 | private:
63 | QPointer m_container = nullptr;
64 | Sorter* m_sorter = nullptr;
65 | };
66 |
67 | }
68 |
69 | #define SorterContainer_iid "fr.grecko.SortFilterProxyModel.SorterContainer"
70 | Q_DECLARE_INTERFACE(qqsfpm::SorterContainer, SorterContainer_iid)
71 |
72 | QML_DECLARE_TYPEINFO(qqsfpm::SorterContainerAttached, QML_HAS_ATTACHED_PROPERTIES)
73 |
74 | #endif // SORTERSSORTERCONTAINER_H
75 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/sorters/rolesorter.cpp:
--------------------------------------------------------------------------------
1 | #include "rolesorter.h"
2 | #include "qqmlsortfilterproxymodel.h"
3 |
4 | #include "qvariantlessthan.h"
5 |
6 |
7 |
8 |
9 | namespace qqsfpm {
10 |
11 | /*!
12 | \qmltype RoleSorter
13 | \inherits Sorter
14 | \inqmlmodule SortFilterProxyModel
15 | \ingroup Sorters
16 | \brief Sorts rows based on a source model role.
17 |
18 | A RoleSorter is a simple \l Sorter that sorts rows based on a source model role.
19 |
20 | In the following example, rows with be sorted by their \c lastName role :
21 | \code
22 | SortFilterProxyModel {
23 | sourceModel: contactModel
24 | sorters: RoleSorter { roleName: "lastName" }
25 | }
26 | \endcode
27 | */
28 |
29 | /*!
30 | \qmlproperty string RoleSorter::roleName
31 |
32 | This property holds the role name that the sorter is using to query the source model's data when sorting items.
33 | */
34 | const QString& RoleSorter::roleName() const
35 | {
36 | return m_roleName;
37 | }
38 |
39 | void RoleSorter::setRoleName(const QString& roleName)
40 | {
41 | if (m_roleName == roleName)
42 | return;
43 |
44 | m_roleName = roleName;
45 | Q_EMIT roleNameChanged();
46 | invalidate();
47 | }
48 |
49 | QPair RoleSorter::sourceData(const QModelIndex &sourceLeft, const QModelIndex& sourceRight, const QQmlSortFilterProxyModel& proxyModel) const
50 | {
51 | QPair pair;
52 | int role = proxyModel.roleForName(m_roleName);
53 |
54 | if (role == -1)
55 | return pair;
56 |
57 | pair.first = proxyModel.sourceData(sourceLeft, role);
58 | pair.second = proxyModel.sourceData(sourceRight, role);
59 | return pair;
60 | }
61 |
62 | int RoleSorter::compare(const QModelIndex &sourceLeft, const QModelIndex& sourceRight, const QQmlSortFilterProxyModel& proxyModel) const
63 | {
64 |
65 | QPair pair = sourceData(sourceLeft, sourceRight, proxyModel);
66 | QVariant leftValue = pair.first;
67 | QVariant rightValue = pair.second;
68 | if (qqsfpm::lessThan(leftValue, rightValue))
69 | return -1;
70 | if (qqsfpm::lessThan(rightValue, leftValue))
71 | return 1;
72 | return 0;
73 |
74 | }
75 |
76 |
77 | }
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/filters/filter.cpp:
--------------------------------------------------------------------------------
1 | #include "filter.h"
2 | #include "qqmlsortfilterproxymodel.h"
3 |
4 | namespace qqsfpm {
5 |
6 | /*!
7 | \qmltype Filter
8 | \qmlabstract
9 | \inqmlmodule SortFilterProxyModel
10 | \ingroup Filters
11 | \brief Base type for the \l SortFilterProxyModel filters.
12 |
13 | The Filter type cannot be used directly in a QML file.
14 | It exists to provide a set of common properties and methods,
15 | available across all the other filter types that inherit from it.
16 | Attempting to use the Filter type directly will result in an error.
17 | */
18 |
19 | Filter::Filter(QObject *parent) : QObject(parent)
20 | {
21 | }
22 |
23 | /*!
24 | \qmlproperty bool Filter::enabled
25 |
26 | This property holds whether the filter is enabled.
27 | A disabled filter will accept every rows unconditionally (even if it's inverted).
28 |
29 | By default, filters are enabled.
30 | */
31 | bool Filter::enabled() const
32 | {
33 | return m_enabled;
34 | }
35 |
36 | void Filter::setEnabled(bool enabled)
37 | {
38 | if (m_enabled == enabled)
39 | return;
40 |
41 | m_enabled = enabled;
42 | Q_EMIT enabledChanged();
43 | Q_EMIT invalidated();
44 | }
45 |
46 | /*!
47 | \qmlproperty bool Filter::inverted
48 |
49 | This property holds whether the filter is inverted.
50 | When a filter is inverted, a row normally accepted would be rejected, and vice-versa.
51 |
52 | By default, filters are not inverted.
53 | */
54 | bool Filter::inverted() const
55 | {
56 | return m_inverted;
57 | }
58 |
59 | void Filter::setInverted(bool inverted)
60 | {
61 | if (m_inverted == inverted)
62 | return;
63 |
64 | m_inverted = inverted;
65 | Q_EMIT invertedChanged();
66 | invalidate();
67 | }
68 |
69 | bool Filter::filterAcceptsRow(const QModelIndex &sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const
70 | {
71 | return !m_enabled || filterRow(sourceIndex, proxyModel) ^ m_inverted;
72 | }
73 |
74 | void Filter::proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel)
75 | {
76 | Q_UNUSED(proxyModel)
77 | }
78 |
79 | void Filter::invalidate()
80 | {
81 | if (m_enabled)
82 | Q_EMIT invalidated();
83 | }
84 |
85 | }
86 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/proxyroles/joinrole.cpp:
--------------------------------------------------------------------------------
1 | #include "joinrole.h"
2 | #include "qqmlsortfilterproxymodel.h"
3 |
4 | namespace qqsfpm {
5 |
6 | /*!
7 | \qmltype JoinRole
8 | \inherits SingleRole
9 | \inqmlmodule SortFilterProxyModel
10 | \ingroup ProxyRoles
11 | \brief a role made from concatenating other roles.
12 |
13 | A JoinRole is a simple \l ProxyRole that concatenates other roles.
14 |
15 | In the following example, the \c fullName role is computed by the concatenation of the \c firstName role and the \c lastName role separated by a space :
16 | \code
17 | SortFilterProxyModel {
18 | sourceModel: contactModel
19 | proxyRoles: JoinRole {
20 | name: "fullName"
21 | roleNames: ["firstName", "lastName"]
22 | }
23 | }
24 | \endcode
25 |
26 | */
27 |
28 | /*!
29 | \qmlproperty list JoinRole::roleNames
30 |
31 | This property holds the role names that are joined by this role.
32 | */
33 | QStringList JoinRole::roleNames() const
34 | {
35 | return m_roleNames;
36 | }
37 |
38 | void JoinRole::setRoleNames(const QStringList& roleNames)
39 | {
40 | if (m_roleNames == roleNames)
41 | return;
42 |
43 | m_roleNames = roleNames;
44 | Q_EMIT roleNamesChanged();
45 | invalidate();
46 | }
47 |
48 | /*!
49 | \qmlproperty string JoinRole::separator
50 |
51 | This property holds the separator that is used to join the roles specified in \l roleNames.
52 |
53 | By default, it's a space.
54 | */
55 | QString JoinRole::separator() const
56 | {
57 | return m_separator;
58 | }
59 |
60 | void JoinRole::setSeparator(const QString& separator)
61 | {
62 | if (m_separator == separator)
63 | return;
64 |
65 | m_separator = separator;
66 | Q_EMIT separatorChanged();
67 | invalidate();
68 | }
69 |
70 | QVariant JoinRole::data(const QModelIndex &sourceIndex, const QQmlSortFilterProxyModel& proxyModel)
71 | {
72 | QString result;
73 |
74 | for (const QString& roleName : m_roleNames)
75 | result += proxyModel.sourceData(sourceIndex, roleName).toString() + m_separator;
76 |
77 | if (!m_roleNames.isEmpty())
78 | result.chop(m_separator.length());
79 |
80 | return result;
81 | }
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/src/domainsources/domainslisttextfile.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 Remy van Elst https://raymii.org
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, version 3.
7 | *
8 | * This program is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 | * General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | #pragma once
18 |
19 |
20 | #include "src/listmodel/domaincountlistmodel.h"
21 |
22 | #include
23 | #include
24 | #include
25 |
26 | typedef QPair QIntPair;
27 |
28 |
29 | class DomainsListTextFile : public QObject
30 | {
31 | Q_OBJECT
32 | Q_PROPERTY(domainCountListModel* domains READ domains NOTIFY domainsChanged FINAL)
33 | Q_PROPERTY(QStringList hostnames READ hostnames WRITE setHostnames NOTIFY hostnamesChanged FINAL)
34 | Q_PROPERTY(QString textFileName READ textFileName WRITE setTextFileName NOTIFY textFileNameChanged FINAL)
35 | Q_PROPERTY(QString lastError READ lastError WRITE setLastError NOTIFY lastErrorChanged FINAL)
36 |
37 | public:
38 | explicit DomainsListTextFile(QObject *parent = nullptr);
39 |
40 | Q_INVOKABLE void getHostnamesFromTextFile(const QUrl path);
41 |
42 | QStringList hostnames() const;
43 |
44 | QString textFileName() const;
45 | void setTextFileName(const QString &newTextFileName);
46 |
47 | domainCountListModel *domains() const;
48 |
49 | QString lastError() const;
50 | void setLastError(const QString &newLastError);
51 |
52 | void setHostnames(const QStringList &newHostnames);
53 |
54 | signals:
55 | void hostnamesChanged();
56 | void textFileNameChanged();
57 |
58 | void domainsChanged();
59 |
60 | void lastErrorChanged();
61 |
62 | private:
63 | QStringList m_hostnames;
64 | QString m_textFileName;
65 | domainCountListModel *m_domains = nullptr;
66 | QString m_lastError;
67 | };
68 |
69 |
--------------------------------------------------------------------------------
/CertInfo.pro:
--------------------------------------------------------------------------------
1 | QT += quick sql widgets quickcontrols2
2 |
3 | # You can make your code fail to compile if it uses deprecated APIs.
4 | # In order to do so, uncomment the following line.
5 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
6 |
7 | QMAKE_CXXFLAGS = -Wno-deprecated-declarations
8 |
9 | VERSION = 2024.01.2.0 # major.minor.patch.build
10 | DEFINES += APP_VERSION=\\\"$$VERSION\\\"
11 | QMAKE_TARGET_PRODUCT = "CertInfo"
12 | QMAKE_TARGET_COMPANY = "Sparkling Network"
13 | QMAKE_TARGET_DESCRIPTION = "Which root certificates should you trust? by Remy van Elst, https://raymii.org"
14 | QMAKE_TARGET_COPYRIGHT = "Remy van Elst - Licensed under the GNU GPLv3"
15 |
16 | RC_ICONS = certinfo.ico
17 |
18 | HEADERS += \
19 | src/ca/caconcurrentgatherer.h \
20 | src/ca/certificate.h \
21 | src/domainsources/browserhistorydb.h \
22 | src/listmodel/caissuerlistmodel.h \
23 | src/ca/caprocessor.h \
24 | src/listmodel/domaincountlistmodel.h \
25 | src/domainsources/domainslisttextfile.h \
26 | src/listmodel/genericlistmodel.h \
27 | src/listmodel/qabstractlistmodelwithrowcountsignal.h \
28 | src/versioncheck/versioncheck.h
29 |
30 | SOURCES += \
31 | src/ca/caconcurrentgatherer.cpp \
32 | src/domainsources/browserhistorydb.cpp \
33 | src/listmodel/caissuerlistmodel.cpp \
34 | src/ca/caprocessor.cpp \
35 | src/listmodel/domaincountlistmodel.cpp \
36 | src/domainsources/domainslisttextfile.cpp \
37 | src/main.cpp \
38 | src/versioncheck/versioncheck.cpp
39 |
40 | CONFIG += c++17
41 |
42 | RESOURCES += src/qml.qrc
43 |
44 | contains(QT_MAJOR_VERSION, 6) {
45 | RESOURCES += src/qt6.qrc
46 | }
47 |
48 | contains(QT_MAJOR_VERSION, 5) {
49 | RESOURCES += src/qt5.qrc
50 | }
51 |
52 | # Additional import path used to resolve QML modules in Qt Creator's code model
53 | QML_IMPORT_PATH =
54 |
55 | # Additional import path used to resolve QML modules just for Qt Quick Designer
56 | QML_DESIGNER_IMPORT_PATH =
57 |
58 | # Default rules for deployment.
59 | qnx: target.path = /tmp/$${TARGET}/bin
60 | else: unix:!android: target.path = /opt/$${TARGET}/bin
61 | !isEmpty(target.path): INSTALLS += target
62 |
63 |
64 | include(src/thirdparty/SortFilterProxyModel/SortFilterProxyModel.pri)
65 |
66 | DISTFILES += \
67 | README.md \
68 | certinfo.ico
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/sorters/filtersorter.cpp:
--------------------------------------------------------------------------------
1 | #include "filtersorter.h"
2 | #include "filters/filter.h"
3 |
4 | namespace qqsfpm {
5 |
6 | /*!
7 | \qmltype FilterSorter
8 | \inherits Sorter
9 | \inqmlmodule SortFilterProxyModel
10 | \ingroup Sorters
11 | \ingroup FilterContainer
12 | \brief Sorts rows based on if they match filters.
13 |
14 | A FilterSorter is a \l Sorter that orders row matching its filters before the rows not matching the filters.
15 |
16 | In the following example, rows with their \c favorite role set to \c true will be ordered at the beginning :
17 | \code
18 | SortFilterProxyModel {
19 | sourceModel: contactModel
20 | sorters: FilterSorter {
21 | ValueFilter { roleName: "favorite"; value: true }
22 | }
23 | }
24 | \endcode
25 | \sa FilterContainer
26 | */
27 |
28 | /*!
29 | \qmlproperty list FilterSorter::filters
30 | \default
31 |
32 | This property holds the list of filters for this filter sorter.
33 | If a row match all this FilterSorter's filters, it will be ordered before rows not matching all the filters.
34 |
35 | \sa Filter, FilterContainer
36 | */
37 |
38 | int FilterSorter::compare(const QModelIndex& sourceLeft, const QModelIndex& sourceRight, const QQmlSortFilterProxyModel &proxyModel) const
39 | {
40 | bool leftIsAccepted = indexIsAccepted(sourceLeft, proxyModel);
41 | bool rightIsAccepted = indexIsAccepted(sourceRight, proxyModel);
42 |
43 | if (leftIsAccepted == rightIsAccepted)
44 | return 0;
45 |
46 | return leftIsAccepted ? -1 : 1;
47 | }
48 |
49 | void FilterSorter::proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel)
50 | {
51 | for (Filter* filter : m_filters)
52 | filter->proxyModelCompleted(proxyModel);
53 | }
54 |
55 | void FilterSorter::onFilterAppended(Filter* filter)
56 | {
57 | connect(filter, &Filter::invalidated, this, &FilterSorter::invalidate);
58 | invalidate();
59 | }
60 |
61 | void FilterSorter::onFilterRemoved(Filter* filter)
62 | {
63 | disconnect(filter, &Filter::invalidated, this, &FilterSorter::invalidate);
64 | invalidate();
65 | }
66 |
67 | void FilterSorter::onFiltersCleared()
68 | {
69 | invalidate();
70 | }
71 |
72 | bool FilterSorter::indexIsAccepted(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const
73 | {
74 | return std::all_of(m_filters.begin(), m_filters.end(),
75 | [&] (Filter* filter) {
76 | return filter->filterAcceptsRow(sourceIndex, proxyModel);
77 | }
78 | );
79 | }
80 |
81 | }
82 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/SortFilterProxyModel.pri:
--------------------------------------------------------------------------------
1 | !contains( CONFIG, c\+\+1[147] ): warning("SortFilterProxyModel needs at least c++11, add CONFIG += c++11 to your .pro")
2 |
3 | INCLUDEPATH += $$PWD
4 |
5 | HEADERS += $$PWD/qqmlsortfilterproxymodel.h \
6 | $$PWD/qvariantlessthan.h \
7 | $$PWD/filters/filter.h \
8 | $$PWD/filters/filtercontainer.h \
9 | $$PWD/filters/rolefilter.h \
10 | $$PWD/filters/valuefilter.h \
11 | $$PWD/filters/indexfilter.h \
12 | $$PWD/filters/regexpfilter.h \
13 | $$PWD/filters/rangefilter.h \
14 | $$PWD/filters/expressionfilter.h \
15 | $$PWD/filters/filtercontainerfilter.h \
16 | $$PWD/filters/anyoffilter.h \
17 | $$PWD/filters/alloffilter.h \
18 | $$PWD/sorters/sorter.h \
19 | $$PWD/sorters/sortercontainer.h \
20 | $$PWD/sorters/rolesorter.h \
21 | $$PWD/sorters/stringsorter.h \
22 | $$PWD/sorters/expressionsorter.h \
23 | $$PWD/proxyroles/proxyrole.h \
24 | $$PWD/proxyroles/proxyrolecontainer.h \
25 | $$PWD/proxyroles/joinrole.h \
26 | $$PWD/proxyroles/switchrole.h \
27 | $$PWD/proxyroles/expressionrole.h \
28 | $$PWD/proxyroles/singlerole.h \
29 | $$PWD/proxyroles/regexprole.h \
30 | $$PWD/sorters/filtersorter.h \
31 | $$PWD/proxyroles/filterrole.h \
32 | $$PWD/utils/utils.h
33 |
34 | SOURCES += $$PWD/qqmlsortfilterproxymodel.cpp \
35 | $$PWD/qvariantlessthan.cpp \
36 | $$PWD/filters/filter.cpp \
37 | $$PWD/filters/filtercontainer.cpp \
38 | $$PWD/filters/rolefilter.cpp \
39 | $$PWD/filters/valuefilter.cpp \
40 | $$PWD/filters/indexfilter.cpp \
41 | $$PWD/filters/regexpfilter.cpp \
42 | $$PWD/filters/rangefilter.cpp \
43 | $$PWD/filters/expressionfilter.cpp \
44 | $$PWD/filters/filtercontainerfilter.cpp \
45 | $$PWD/filters/anyoffilter.cpp \
46 | $$PWD/filters/alloffilter.cpp \
47 | $$PWD/filters/filtersqmltypes.cpp \
48 | $$PWD/sorters/sorter.cpp \
49 | $$PWD/sorters/sortercontainer.cpp \
50 | $$PWD/sorters/rolesorter.cpp \
51 | $$PWD/sorters/stringsorter.cpp \
52 | $$PWD/sorters/expressionsorter.cpp \
53 | $$PWD/sorters/sortersqmltypes.cpp \
54 | $$PWD/proxyroles/proxyrole.cpp \
55 | $$PWD/proxyroles/proxyrolecontainer.cpp \
56 | $$PWD/proxyroles/joinrole.cpp \
57 | $$PWD/proxyroles/switchrole.cpp \
58 | $$PWD/proxyroles/expressionrole.cpp \
59 | $$PWD/proxyroles/proxyrolesqmltypes.cpp \
60 | $$PWD/proxyroles/singlerole.cpp \
61 | $$PWD/proxyroles/regexprole.cpp \
62 | $$PWD/sorters/filtersorter.cpp \
63 | $$PWD/proxyroles/filterrole.cpp \
64 | $$PWD/utils/utils.cpp
65 |
--------------------------------------------------------------------------------
/src/domainsources/browserhistorydb.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 Remy van Elst https://raymii.org
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, version 3.
7 | *
8 | * This program is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 | * General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | #pragma once
18 |
19 | #include "src/listmodel/domaincountlistmodel.h"
20 |
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 | typedef QPair QIntPair;
27 |
28 | class BrowserHistoryDb : public QObject
29 | {
30 | Q_OBJECT
31 | Q_PROPERTY(domainCountListModel* domains READ domains NOTIFY domainsChanged FINAL)
32 | Q_PROPERTY(QStringList hostnames READ hostnames WRITE setHostnames NOTIFY hostnamesChanged FINAL)
33 | Q_PROPERTY(QString dbFileName READ dbFileName WRITE setDbFileName NOTIFY dbFileNameChanged FINAL)
34 | Q_PROPERTY(bool isFirefox READ isFirefox WRITE setIsFirefox NOTIFY isFirefoxChanged FINAL)
35 | Q_PROPERTY(QString lastDbError READ lastDbError WRITE setLastDbError NOTIFY lastDbErrorChanged FINAL)
36 |
37 | public:
38 | explicit BrowserHistoryDb(QObject *parent = nullptr);
39 |
40 | Q_INVOKABLE bool openDb(const QUrl path);
41 | Q_INVOKABLE void getHostnamesFromDb();
42 |
43 | QStringList hostnames() const;
44 | void setHostnames(const QStringList &newHostnames);
45 |
46 | QString dbFileName() const;
47 | void setDbFileName(const QString &newDbFileName);
48 |
49 | QString lastDbError() const;
50 | void setLastDbError(const QString &newLastDbError);
51 |
52 | domainCountListModel *domains() const;
53 |
54 | bool isFirefox() const;
55 | void setIsFirefox(bool newIsFirefox);
56 |
57 | signals:
58 |
59 | void hostnamesChanged();
60 | void dbFileNameChanged();
61 | void lastDbErrorChanged();
62 | void domainsChanged();
63 | void isFirefoxChanged();
64 |
65 | private:
66 | QSqlDatabase _db;
67 | QString firefoxQuery();
68 | QString chromeQuery();
69 | QStringList m_hostnames;
70 | QString m_dbFileName;
71 | QString m_lastDbError;
72 | domainCountListModel *m_domains = nullptr;
73 | bool m_isFirefox;
74 | };
75 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/filters/regexpfilter.cpp:
--------------------------------------------------------------------------------
1 | #include "regexpfilter.h"
2 | #include
3 |
4 | namespace qqsfpm {
5 |
6 | /*!
7 | \qmltype RegExpFilter
8 | \inherits RoleFilter
9 | \inqmlmodule SortFilterProxyModel
10 | \ingroup Filters
11 | \brief Filters rows matching a regular expression.
12 |
13 | A RegExpFilter is a \l RoleFilter that accepts rows matching a regular rexpression.
14 |
15 | In the following example, only rows with their \c lastName role beggining with the content of textfield the will be accepted:
16 | \code
17 | TextField {
18 | id: nameTextField
19 | }
20 |
21 | SortFilterProxyModel {
22 | sourceModel: contactModel
23 | filters: RegExpFilter {
24 | roleName: "lastName"
25 | pattern: "^" + nameTextField.displayText
26 | }
27 | }
28 | \endcode
29 | */
30 |
31 | /*!
32 | \qmlproperty bool RegExpFilter::pattern
33 |
34 | The pattern used to filter the contents of the source model.
35 |
36 | \sa syntax
37 | */
38 | RegExpFilter::RegExpFilter() :
39 | m_caseSensitivity(m_regExp.patternOptions().testFlag(
40 | QRegularExpression::CaseInsensitiveOption) ? Qt::CaseInsensitive : Qt::CaseSensitive)
41 | {
42 | }
43 |
44 | QString RegExpFilter::pattern() const
45 | {
46 | return m_pattern;
47 | }
48 |
49 | void RegExpFilter::setPattern(const QString& pattern)
50 | {
51 | if (m_pattern == pattern)
52 | return;
53 |
54 | m_pattern = pattern;
55 | m_regExp.setPattern(pattern);
56 | Q_EMIT patternChanged();
57 | invalidate();
58 | }
59 |
60 | /*!
61 | \qmlproperty Qt::CaseSensitivity RegExpFilter::caseSensitivity
62 |
63 | This property holds the caseSensitivity of the filter.
64 | */
65 | Qt::CaseSensitivity RegExpFilter::caseSensitivity() const
66 | {
67 | return m_caseSensitivity;
68 | }
69 |
70 | void RegExpFilter::setCaseSensitivity(Qt::CaseSensitivity caseSensitivity)
71 | {
72 | if (m_caseSensitivity == caseSensitivity)
73 | return;
74 |
75 | m_caseSensitivity = caseSensitivity;
76 | QRegularExpression::PatternOptions patternOptions = m_regExp.patternOptions();
77 | if (caseSensitivity == Qt::CaseInsensitive)
78 | patternOptions.setFlag(QRegularExpression::CaseInsensitiveOption);
79 | m_regExp.setPatternOptions(patternOptions);
80 | Q_EMIT caseSensitivityChanged();
81 | invalidate();
82 | }
83 |
84 | bool RegExpFilter::filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const
85 | {
86 | const QString string = sourceData(sourceIndex, proxyModel).toString();
87 | return m_regExp.match(string).hasMatch();
88 | }
89 |
90 | }
91 |
--------------------------------------------------------------------------------
/src/FoldableCertInfo.qml:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 Remy van Elst https://raymii.org
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, version 3.
7 | *
8 | * This program is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 | * General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 |
18 | import QtQuick 2.15
19 | import QtQuick.Controls 2.15
20 |
21 | Column {
22 | id: root
23 | default property alias children: content.children
24 | property var modelData
25 | property string title: modelData.subject
26 | property color titleBgColor: "#e0e0e0"
27 | property color titleBgColorPressed: "#cfcfcf"
28 | property color titleBorderColor: titleBgColor
29 | property bool collapsed: true
30 |
31 | Button {
32 | id: header
33 | anchors.left: parent.left
34 | width: parent.width
35 | clip: true
36 | height: 48
37 | contentItem: Text {
38 | height: parent.height
39 | anchors.margins: 5
40 | width: parent.width
41 | text: root.title
42 | horizontalAlignment : Text.AlignLeft
43 | minimumPixelSize: 12
44 | fontSizeMode: Text.Fit
45 | wrapMode: Text.WordWrap
46 | elide: Text.ElideMiddle
47 | }
48 |
49 | onClicked: root.collapsed = !root.collapsed
50 | background: Rectangle {
51 | color: parent.down ? titleBgColorPressed : titleBgColor
52 | border.color: titleBorderColor
53 | border.width: 1
54 | radius: 2
55 | }
56 | }
57 |
58 | Pane {
59 | id: contentPane
60 |
61 | visible: height > 0
62 | height: !root.collapsed ? implicitHeight : 0
63 |
64 | Behavior on height {
65 | NumberAnimation {
66 | easing.type: Easing.InOutQuad
67 | duration: 200
68 | }
69 | }
70 |
71 | clip: true
72 | anchors.left: parent.left
73 | anchors.right: parent.right
74 |
75 | Column {
76 | id: content
77 | anchors.right: parent.right
78 | anchors.left: parent.left
79 | spacing: 10
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/listmodel/caissuerlistmodel.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 Remy van Elst https://raymii.org
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, version 3.
7 | *
8 | * This program is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 | * General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 |
18 | #include "caissuerlistmodel.h"
19 |
20 | CACertificateListModel::CACertificateListModel(QObject* parent) : GenericListModel(parent)
21 | {
22 | addSelector("subject", [](const Certificate &i) { return i.subject; });
23 | addSelector("subjectInfo", [](const Certificate &i) { return QVariant::fromValue(i.subjectInfo); });
24 | addSelector("string", [](const Certificate &i) { return QString::fromStdString(i.toString()); });
25 | addSelector("issuer", [](const Certificate &i) { return i.issuer; });
26 | addSelector("issuerInfo", [](const Certificate &i) { return QVariant::fromValue(i.issuerInfo); });
27 | addSelector("validFromDate", [](const Certificate &i) { return i.validFromDate.toString(); });
28 | addSelector("validUntilDate", [](const Certificate &i) { return i.validUntilDate.toString(); });
29 | addSelector("count", [](const Certificate &i) { return i.count; });
30 | addSelector("isca", [](const Certificate &i) { return i.isCA; });
31 | addSelector("istrustedrootca", [](const Certificate &i) { return i.isSystemTrustedRootCA; });
32 | addSelector("domains", [](const Certificate &i) { return i.domains.join(" "); });
33 | addSelector("subjectAlternativeNames", [](const Certificate &i) { return i.subjectAlternativeNames.join(" "); });
34 | addSelector("isselfsigned", [](const Certificate &i) { return i.isSelfSigned; });
35 | addSelector("errors", [](const Certificate &i) { return i.errors.join(" "); });
36 | }
37 |
38 | void CACertificateListModel::addOrUpdateItem(const Certificate &item, const QString& findBySubject)
39 | {
40 | auto it = std::find_if(m_listObjects.begin(), m_listObjects.end(), [&findBySubject](const Certificate& c){ return c.subject == findBySubject;});
41 | if(it != m_listObjects.end())
42 | {
43 | int index = std::distance(m_listObjects.begin(), it);
44 | updateRow(index, item);
45 | } else {
46 | addRow(item);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/setup.iss:
--------------------------------------------------------------------------------
1 | ; Script generated by the Inno Setup Script Wizard.
2 | ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
3 |
4 | ; build deploy on windows
5 | ; \qt5\5.15.2\mingw81_32\bin\qtenv2.bat
6 | ; cd \Users\user\git\build-CertInfo-Desktop_Qt_5_15_2_MinGW_32_bit-Release\release
7 | ; \qt5\5.15.2\mingw81_32\bin\windeployqt.exe CertInfo.exe --qmldir \Users\user\git\CertInfo\src\
8 |
9 | #define MyAppName "CertInfo"
10 | #define MyAppVersion "2024.01"
11 | #define MyAppPublisher "Sparkling Network"
12 | #define MyAppURL "https://raymii.org/"
13 | #define MyAppExeName "CertInfo.exe"
14 |
15 | [Setup]
16 | ; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
17 | ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
18 | AppId={{67E9D8A9-58D4-4989-B54D-09E39CA26C65}}
19 | AppName={#MyAppName}
20 | AppVersion={#MyAppVersion}
21 | ;AppVerName={#MyAppName} {#MyAppVersion}
22 | AppPublisher={#MyAppPublisher}
23 | AppPublisherURL={#MyAppURL}
24 | AppSupportURL={#MyAppURL}
25 | AppUpdatesURL={#MyAppURL}
26 | DefaultDirName={autopf}\{#MyAppName}
27 | DefaultGroupName={#MyAppName}
28 | LicenseFile=C:\Users\user\git\CertInfo\LICENSE
29 | ; Uncomment the following line to run in non administrative install mode (install for current user only.)
30 | ;PrivilegesRequired=lowest
31 | PrivilegesRequiredOverridesAllowed=dialog
32 | OutputDir=C:\Users\user\git\setup
33 | OutputBaseFilename=CertInfoSetup
34 | SetupIconFile=C:\Users\user\git\CertInfo\certinfo.ico
35 | Compression=lzma
36 | SolidCompression=yes
37 | WizardStyle=modern
38 |
39 | [Languages]
40 | Name: "english"; MessagesFile: "compiler:Default.isl"
41 |
42 | [Tasks]
43 | Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
44 |
45 | [Files]
46 | Source: "C:\Users\user\git\build-CertInfo-Desktop_Qt_5_15_2_MinGW_32_bit-Release\release\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
47 | Source: "C:\Users\user\git\build-CertInfo-Desktop_Qt_5_15_2_MinGW_32_bit-Release\release\*"; DestDir: "{app}"; Excludes: "*.cpp,*.o,moc*"; Flags: ignoreversion recursesubdirs createallsubdirs
48 | Source: "C:\Qt5\Tools\OpenSSL\Win_x86\bin\*.dll"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
49 | Source: "C:\windows\system32\msvcr100.dll"; DestDir: "{app}";
50 | ; NOTE: Don't use "Flags: ignoreversion" on any shared system files
51 |
52 | [Icons]
53 | Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
54 | Name: "{group}\{cm:ProgramOnTheWeb,{#MyAppName}}"; Filename: "{#MyAppURL}"
55 | Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
56 | Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
57 |
58 | [Run]
59 | Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
60 |
61 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/utils/utils.cpp:
--------------------------------------------------------------------------------
1 | #include "utils.h"
2 | #include
3 | #include
4 |
5 | namespace qqsfpm {
6 |
7 | int compareVariants(const QVariant &lhs, const QVariant &rhs)
8 | {
9 | #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) // qt 5
10 | // Do the QString check first because otherwise the canConvert check will get hit for strings.
11 | if (static_cast(lhs.type()) == QMetaType::QString && static_cast(rhs.type()) == QMetaType::QString) {
12 | const auto lhsValue = lhs.toString();
13 | const auto rhsValue = rhs.toString();
14 | if (lhsValue == rhsValue)
15 | return 0;
16 | return lhsValue.compare(rhsValue, Qt::CaseInsensitive);
17 | } else if (static_cast(lhs.type()) == QMetaType::Bool && static_cast(rhs.type()) == QMetaType::Bool) {
18 | const auto lhsValue = lhs.toBool();
19 | const auto rhsValue = rhs.toBool();
20 | if (lhsValue == rhsValue)
21 | return 0;
22 | // false < true.
23 | return !lhsValue ? -1 : 1;
24 | } else if (static_cast(lhs.type()) == QMetaType::QDate && static_cast(rhs.type()) == QMetaType::QDate) {
25 | const auto lhsValue = lhs.toDate();
26 | const auto rhsValue = rhs.toDate();
27 | if (lhsValue == rhsValue)
28 | return 0;
29 | return lhsValue < rhsValue ? -1 : 1;
30 | } else if (static_cast(lhs.type()) == QMetaType::QDateTime && static_cast(rhs.type()) == QMetaType::QDateTime) {
31 | const auto lhsValue = lhs.toDateTime();
32 | const auto rhsValue = rhs.toDateTime();
33 | if (lhsValue == rhsValue)
34 | return 0;
35 | return lhsValue < rhsValue ? -1 : 1;
36 | } else if (static_cast(lhs.type()) == QMetaType::QStringList && static_cast(rhs.type()) == QMetaType::QStringList) {
37 | const auto lhsValue = lhs.toStringList();
38 | const auto rhsValue = rhs.toStringList();
39 | if (lhsValue == rhsValue)
40 | return 0;
41 | return lhsValue < rhsValue ? -1 : 1;
42 | } else if (lhs.canConvert() && rhs.canConvert()) {
43 | const auto lhsValue = lhs.toInt();
44 | const auto rhsValue = rhs.toInt();
45 | if (lhsValue == rhsValue)
46 | return 0;
47 | return lhsValue < rhsValue ? -1 : 1;
48 | } else if (lhs.canConvert() && rhs.canConvert()) {
49 | const auto lhsValue = lhs.toReal();
50 | const auto rhsValue = rhs.toReal();
51 | if (qFuzzyCompare(lhsValue, rhsValue))
52 | return 0;
53 | return lhsValue < rhsValue ? -1 : 1;
54 | }
55 |
56 | qWarning() << "Don't know how to compare" << lhs << "against" << rhs << "- returning 0";
57 | return 0;
58 | #else
59 | return QPartialOrdering::Less == QVariant::compare(lhs, rhs);
60 | #endif
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/qvariantlessthan.cpp:
--------------------------------------------------------------------------------
1 | #include "qvariantlessthan.h"
2 |
3 | #include
4 |
5 | namespace qqsfpm {
6 |
7 | /*!
8 | \brief Less-than operator for generic QVariants
9 |
10 | Since Qt 5.15 deprecated the less-than operator of QVariant, we
11 | have to provide our own implementation. On older Qt versions,
12 | use the original implementation.
13 |
14 | Includes special implementations for numberic types, char, date and
15 | time. Everything else is converted to String and compared then.
16 | */
17 | bool lessThan(const QVariant &lhs, const QVariant &rhs)
18 | {
19 | #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
20 | return lhs < rhs;
21 | #else
22 | static const auto numericTypes = QVector{
23 | QMetaType::Int,
24 | QMetaType::UInt,
25 | QMetaType::LongLong,
26 | QMetaType::ULongLong,
27 | QMetaType::Float,
28 | QMetaType::Double,
29 | };
30 | static const auto unsignedTypes = QVector{
31 | QMetaType::UInt,
32 | QMetaType::ULongLong,
33 | };
34 | static const auto dateTimeTypes = QVector{
35 | QMetaType::QDate,
36 | QMetaType::QTime,
37 | QMetaType::QDateTime,
38 | };
39 |
40 | const auto lt = static_cast(lhs.userType());
41 | const auto rt = static_cast(rhs.userType());
42 | if (numericTypes.contains(lt) && numericTypes.contains(rt)) {
43 | if (lt == QMetaType::Double || lt == QMetaType::Float
44 | || rt == QMetaType::Double || rt == QMetaType::Float) {
45 | return lhs.toDouble() < rhs.toDouble();
46 | } else {
47 | const auto ul = unsignedTypes.contains(lt);
48 | const auto ur = unsignedTypes.contains(rt);
49 | if (ul && ur) {
50 | return lhs.toULongLong() < rhs.toULongLong();
51 | } else if (!ul && !ur) {
52 | return lhs.toLongLong() < rhs.toLongLong();
53 | } else if (ul) {
54 | const auto r = rhs.toLongLong();
55 | return r > 0 &&
56 | lhs.toULongLong() < static_cast(r);
57 | } else {
58 | const auto l = lhs.toLongLong();
59 | return l < 0 ||
60 | static_cast(l) < rhs.toULongLong();
61 | }
62 | }
63 | } else if (dateTimeTypes.contains(lt) && dateTimeTypes.contains(rt)) {
64 | if (lt == QMetaType::QDate && rt == QMetaType::QDate) {
65 | return lhs.toDate() < rhs.toDate();
66 | } else if (lt == QMetaType::QTime && rt == QMetaType::QTime) {
67 | return lhs.toTime() < rhs.toTime();
68 | } else {
69 | return lhs.toDateTime() < rhs.toDateTime();
70 | }
71 | } else if (lt == QMetaType::Char && rt == QMetaType::Char) {
72 | return lhs.toChar() < rhs.toChar();
73 | } else {
74 | return lhs.toString() < rhs.toString();
75 | }
76 | #endif
77 | }
78 |
79 | } // namespace qqsfpm
80 |
--------------------------------------------------------------------------------
/src/main.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 Remy van Elst https://raymii.org
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, version 3.
7 | *
8 | * This program is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 | * General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 |
18 | #include "src/ca/caconcurrentgatherer.h"
19 | #include "src/domainsources/browserhistorydb.h"
20 | #include "src/domainsources/domainslisttextfile.h"
21 | #include "src/versioncheck/versioncheck.h"
22 |
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 |
31 | void destroy(QObject*);
32 |
33 |
34 | int main(int argc, char *argv[])
35 | {
36 | #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
37 | QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
38 | #endif
39 | QGuiApplication app(argc, argv);
40 |
41 | app.setOrganizationName("Sparkling Network");
42 | app.setOrganizationDomain("raymii.org");
43 | app.setApplicationName("FF Cert Cleanup");
44 | app.setWindowIcon(QIcon(":/certinfo.png"));
45 | app.setApplicationVersion(APP_VERSION);
46 |
47 | qmlRegisterType("org.raymii.BrowserHistoryDB", 1, 0, "BrowserHistoryDB");
48 | qmlRegisterType("org.raymii.DomainsListTextFile", 1, 0, "DomainsListTextFile");
49 | qmlRegisterType("org.raymii.CAConcurrentGatherer", 1, 0, "CAConcurrentGatherer");
50 | qmlRegisterType("org.raymii.VersionCheck", 1, 0, "VersionCheck");
51 |
52 | QStringList selectors;
53 | #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
54 | selectors << "qt5";
55 | #else
56 | selectors << "qt6";
57 | QQuickStyle::setStyle("Material");
58 | #endif
59 |
60 |
61 |
62 |
63 | QQmlApplicationEngine* engine = new QQmlApplicationEngine;
64 | QQmlFileSelector* selector = new QQmlFileSelector(engine);
65 | selector->setExtraSelectors(selectors);
66 |
67 | const QUrl url(QStringLiteral("qrc:/main.qml"));
68 | QObject::connect(engine, &QQmlApplicationEngine::objectCreated,
69 | &app, [url](QObject *obj, const QUrl &objUrl) {
70 | if (!obj && url == objUrl)
71 | QCoreApplication::exit(-1);
72 | }, Qt::QueuedConnection);
73 | engine->load(url);
74 |
75 | int appExecResult = app.exec();
76 |
77 | destroy(engine);
78 |
79 | return appExecResult;
80 | }
81 |
82 | void destroy(QObject* object)
83 | {
84 | QEventLoop eventloop;
85 | QObject::connect(object, &QObject::destroyed, &eventloop, &QEventLoop::quit);
86 | object->deleteLater();
87 | eventloop.exec();
88 | }
89 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/filters/indexfilter.cpp:
--------------------------------------------------------------------------------
1 | #include "indexfilter.h"
2 | #include "qqmlsortfilterproxymodel.h"
3 |
4 | namespace qqsfpm {
5 |
6 | /*!
7 | \qmltype IndexFilter
8 | \inherits Filter
9 | \inqmlmodule SortFilterProxyModel
10 | \ingroup Filters
11 | \brief Filters rows based on their source index.
12 |
13 | An IndexFilter is a filter allowing contents to be filtered based on their source model index.
14 |
15 | In the following example, only the first row of the source model will be accepted:
16 | \code
17 | SortFilterProxyModel {
18 | sourceModel: contactModel
19 | filters: IndexFilter {
20 | maximumIndex: 0
21 | }
22 | }
23 | \endcode
24 | */
25 |
26 | /*!
27 | \qmlproperty int IndexFilter::minimumIndex
28 |
29 | This property holds the minimumIndex of the filter.
30 | Rows with a source index lower than \c minimumIndex will be rejected.
31 |
32 | If \c minimumIndex is negative, it is counted from the end of the source model, meaning that :
33 | \code
34 | minimumIndex: -1
35 | \endcode
36 | is equivalent to :
37 | \code
38 | minimumIndex: sourceModel.count - 1
39 | \endcode
40 | By default, no value is set.
41 | */
42 | const QVariant& IndexFilter::minimumIndex() const
43 | {
44 | return m_minimumIndex;
45 | }
46 |
47 | void IndexFilter::setMinimumIndex(const QVariant& minimumIndex)
48 | {
49 | if (m_minimumIndex == minimumIndex)
50 | return;
51 |
52 | m_minimumIndex = minimumIndex;
53 | Q_EMIT minimumIndexChanged();
54 | invalidate();
55 | }
56 |
57 | /*!
58 | \qmlproperty int IndexFilter::maximumIndex
59 |
60 | This property holds the maximumIndex of the filter.
61 | Rows with a source index higher than \c maximumIndex will be rejected.
62 |
63 | If \c maximumIndex is negative, it is counted from the end of the source model, meaning that:
64 | \code
65 | maximumIndex: -1
66 | \endcode
67 | is equivalent to :
68 | \code
69 | maximumIndex: sourceModel.count - 1
70 | \endcode
71 | By default, no value is set.
72 | */
73 | const QVariant& IndexFilter::maximumIndex() const
74 | {
75 | return m_maximumIndex;
76 | }
77 |
78 | void IndexFilter::setMaximumIndex(const QVariant& maximumIndex)
79 | {
80 | if (m_maximumIndex == maximumIndex)
81 | return;
82 |
83 | m_maximumIndex = maximumIndex;
84 | Q_EMIT maximumIndexChanged();
85 | invalidate();
86 | }
87 |
88 | bool IndexFilter::filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const
89 | {
90 | int sourceRowCount = proxyModel.sourceModel()->rowCount();
91 | int sourceRow = sourceIndex.row();
92 |
93 | bool minimumIsValid;
94 | int minimum = m_minimumIndex.toInt(&minimumIsValid);
95 | if (minimumIsValid) {
96 | int actualMinimum = minimum < 0 ? sourceRowCount + minimum : minimum;
97 | if (sourceRow < actualMinimum)
98 | return false;
99 | }
100 |
101 | bool maximumIsValid;
102 | int maximum = m_maximumIndex.toInt(&maximumIsValid);
103 | if (maximumIsValid) {
104 | int actualMaximum = maximum < 0 ? sourceRowCount + maximum : maximum;
105 | if (sourceRow > actualMaximum)
106 | return false;
107 | }
108 |
109 | return true;
110 | }
111 |
112 | }
113 |
--------------------------------------------------------------------------------
/src/domainsources/domainslisttextfile.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 Remy van Elst https://raymii.org
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, version 3.
7 | *
8 | * This program is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 | * General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 |
18 | #include "domainslisttextfile.h"
19 | #include
20 | #include
21 | #include
22 |
23 | DomainsListTextFile::DomainsListTextFile(QObject *parent)
24 | : QObject{parent}
25 | {
26 | m_domains = new domainCountListModel(this);
27 | }
28 |
29 | void DomainsListTextFile::getHostnamesFromTextFile(const QUrl path)
30 | {
31 | setTextFileName(path.toLocalFile());
32 |
33 | QStringList hostnames;
34 | QMap countsHash;
35 | QList countsList;
36 |
37 | QFile file(textFileName());
38 | if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
39 | setLastError(file.errorString());
40 | }
41 |
42 | QTextStream in(&file);
43 | while (!in.atEnd()) {
44 | QString line = in.readLine();
45 | if(!line.isEmpty()) {
46 | countsHash[line]++;
47 | }
48 | }
49 |
50 | file.close();
51 |
52 | QMap::iterator i;
53 | for(i = countsHash.begin(); i != countsHash.end(); ++i) {
54 | countsList.push_back({i.key(), i.value()});
55 | }
56 |
57 | std::sort(countsList.begin(), countsList.end(), [](const QIntPair& a, const QIntPair& b) { return a.second > b.second; });
58 |
59 | for(i = countsHash.begin(); i != countsHash.end(); ++i) {
60 | hostnames.push_back(i.key());
61 | }
62 | setHostnames(hostnames);
63 | m_domains->updateFromQList(countsList);
64 | }
65 |
66 | QStringList DomainsListTextFile::hostnames() const
67 | {
68 | return m_hostnames;
69 | }
70 |
71 | QString DomainsListTextFile::textFileName() const
72 | {
73 | return m_textFileName;
74 | }
75 |
76 | void DomainsListTextFile::setTextFileName(const QString &newTextFileName)
77 | {
78 | if (m_textFileName == newTextFileName)
79 | return;
80 | m_textFileName = newTextFileName;
81 | emit textFileNameChanged();
82 | }
83 |
84 | domainCountListModel *DomainsListTextFile::domains() const
85 | {
86 | return m_domains;
87 | }
88 |
89 | QString DomainsListTextFile::lastError() const
90 | {
91 | return m_lastError;
92 | }
93 |
94 | void DomainsListTextFile::setLastError(const QString &newLastError)
95 | {
96 | if (m_lastError == newLastError)
97 | return;
98 | m_lastError = newLastError;
99 | emit lastErrorChanged();
100 | }
101 |
102 | void DomainsListTextFile::setHostnames(const QStringList &newHostnames)
103 | {
104 | if (m_hostnames == newHostnames)
105 | return;
106 | m_hostnames = newHostnames;
107 | emit hostnamesChanged();
108 | }
109 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/proxyroles/regexprole.cpp:
--------------------------------------------------------------------------------
1 | #include "regexprole.h"
2 | #include "qqmlsortfilterproxymodel.h"
3 | #include
4 |
5 | namespace qqsfpm {
6 |
7 | /*!
8 | \qmltype RegExpRole
9 | \inherits ProxyRole
10 | \inqmlmodule SortFilterProxyModel
11 | \ingroup ProxyRoles
12 | \brief A ProxyRole extracting data from a source role via a regular expression.
13 |
14 | A RegExpRole is a \l ProxyRole that provides a role for each named capture group of its regular expression \l pattern.
15 |
16 | In the following example, the \c date role of the source model will be extracted in 3 roles in the proxy moodel: \c year, \c month and \c day.
17 | \code
18 | SortFilterProxyModel {
19 | sourceModel: eventModel
20 | proxyRoles: RegExpRole {
21 | roleName: "date"
22 | pattern: "(?\\d{4})-(?\\d{2})-(?\\d{2})"
23 | }
24 | }
25 | \endcode
26 | */
27 |
28 | /*!
29 | \qmlproperty QString RegExpRole::roleName
30 |
31 | This property holds the role name that the RegExpRole is using to query the source model's data to extract new roles from.
32 | */
33 | QString RegExpRole::roleName() const
34 | {
35 | return m_roleName;
36 | }
37 |
38 | void RegExpRole::setRoleName(const QString& roleName)
39 | {
40 | if (m_roleName == roleName)
41 | return;
42 |
43 | m_roleName = roleName;
44 | Q_EMIT roleNameChanged();
45 | }
46 |
47 | /*!
48 | \qmlproperty QString RegExpRole::pattern
49 |
50 | This property holds the pattern of the regular expression of this RegExpRole.
51 | The RegExpRole will expose a role for each of the named capture group of the pattern.
52 | */
53 | QString RegExpRole::pattern() const
54 | {
55 | return m_regularExpression.pattern();
56 | }
57 |
58 | void RegExpRole::setPattern(const QString& pattern)
59 | {
60 | if (m_regularExpression.pattern() == pattern)
61 | return;
62 |
63 | Q_EMIT namesAboutToBeChanged();
64 | m_regularExpression.setPattern(pattern);
65 | invalidate();
66 | Q_EMIT patternChanged();
67 | Q_EMIT namesChanged();
68 | }
69 |
70 | /*!
71 | \qmlproperty Qt::CaseSensitivity RegExpRole::caseSensitivity
72 |
73 | This property holds the caseSensitivity of the regular expression.
74 | */
75 | Qt::CaseSensitivity RegExpRole::caseSensitivity() const
76 | {
77 | return m_regularExpression.patternOptions() & QRegularExpression::CaseInsensitiveOption ?
78 | Qt::CaseInsensitive : Qt::CaseSensitive;
79 | }
80 |
81 | void RegExpRole::setCaseSensitivity(Qt::CaseSensitivity caseSensitivity)
82 | {
83 | if (this->caseSensitivity() == caseSensitivity)
84 | return;
85 |
86 | m_regularExpression.setPatternOptions(m_regularExpression.patternOptions() ^ QRegularExpression::CaseInsensitiveOption); //toggle the option
87 | Q_EMIT caseSensitivityChanged();
88 | }
89 |
90 | QStringList RegExpRole::names()
91 | {
92 | QStringList nameCaptureGroups = m_regularExpression.namedCaptureGroups();
93 | nameCaptureGroups.removeAll("");
94 | return nameCaptureGroups;
95 | }
96 |
97 | QVariant RegExpRole::data(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel, const QString &name)
98 | {
99 | QString text = proxyModel.sourceData(sourceIndex, m_roleName).toString();
100 | QRegularExpressionMatch match = m_regularExpression.match(text);
101 | return match.hasMatch() ? (match.captured(name)) : QVariant{};
102 | }
103 |
104 | }
105 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/sorters/stringsorter.cpp:
--------------------------------------------------------------------------------
1 | #include "stringsorter.h"
2 |
3 | namespace qqsfpm {
4 |
5 | /*!
6 | \qmltype StringSorter
7 | \inherits RoleSorter
8 | \inqmlmodule SortFilterProxyModel
9 | \ingroup Sorters
10 | \brief Sorts rows based on a source model string role.
11 |
12 | \l StringSorter is a specialized \l RoleSorter that sorts rows based on a source model string role.
13 | \l StringSorter compares strings according to a localized collation algorithm.
14 |
15 | In the following example, rows with be sorted by their \c lastName role :
16 | \code
17 | SortFilterProxyModel {
18 | sourceModel: contactModel
19 | sorters: StringSorter { roleName: "lastName" }
20 | }
21 | \endcode
22 | */
23 |
24 | /*!
25 | \qmlproperty Qt.CaseSensitivity StringSorter::caseSensitivity
26 |
27 | This property holds the case sensitivity of the sorter.
28 | */
29 | Qt::CaseSensitivity StringSorter::caseSensitivity() const
30 | {
31 | return m_collator.caseSensitivity();
32 | }
33 |
34 | void StringSorter::setCaseSensitivity(Qt::CaseSensitivity caseSensitivity)
35 | {
36 | if (m_collator.caseSensitivity() == caseSensitivity)
37 | return;
38 |
39 | m_collator.setCaseSensitivity(caseSensitivity);
40 | Q_EMIT caseSensitivityChanged();
41 | invalidate();
42 | }
43 |
44 | /*!
45 | \qmlproperty bool StringSorter::ignorePunctation
46 |
47 | This property holds whether the sorter ignores punctation.
48 | if \c ignorePunctuation is \c true, punctuation characters and symbols are ignored when determining sort order.
49 |
50 | \note This property is not currently supported on Apple platforms or if Qt is configured to not use ICU on Linux.
51 | */
52 | bool StringSorter::ignorePunctation() const
53 | {
54 | return m_collator.ignorePunctuation();
55 | }
56 |
57 | void StringSorter::setIgnorePunctation(bool ignorePunctation)
58 | {
59 | if (m_collator.ignorePunctuation() == ignorePunctation)
60 | return;
61 |
62 | m_collator.setIgnorePunctuation(ignorePunctation);
63 | Q_EMIT ignorePunctationChanged();
64 | invalidate();
65 | }
66 |
67 | /*!
68 | \qmlproperty Locale StringSorter::locale
69 |
70 | This property holds the locale of the sorter.
71 | */
72 | QLocale StringSorter::locale() const
73 | {
74 | return m_collator.locale();
75 | }
76 |
77 | void StringSorter::setLocale(const QLocale &locale)
78 | {
79 | if (m_collator.locale() == locale)
80 | return;
81 |
82 | m_collator.setLocale(locale);
83 | Q_EMIT localeChanged();
84 | invalidate();
85 | }
86 |
87 | /*!
88 | \qmlproperty bool StringSorter::numericMode
89 |
90 | This property holds whether the numeric mode of the sorter is enabled.
91 | This will enable proper sorting of numeric digits, so that e.g. 100 sorts after 99.
92 | By default this mode is off.
93 | */
94 | bool StringSorter::numericMode() const
95 | {
96 | return m_collator.numericMode();
97 | }
98 |
99 | void StringSorter::setNumericMode(bool numericMode)
100 | {
101 | if (m_collator.numericMode() == numericMode)
102 | return;
103 |
104 | m_collator.setNumericMode(numericMode);
105 | Q_EMIT numericModeChanged();
106 | invalidate();
107 | }
108 |
109 | int StringSorter::compare(const QModelIndex &sourceLeft, const QModelIndex &sourceRight, const QQmlSortFilterProxyModel& proxyModel) const
110 | {
111 | QPair pair = sourceData(sourceLeft, sourceRight, proxyModel);
112 | QString leftValue = pair.first.toString();
113 | QString rightValue = pair.second.toString();
114 | return m_collator.compare(leftValue, rightValue);
115 | }
116 |
117 | }
118 |
--------------------------------------------------------------------------------
/src/ca/caconcurrentgatherer.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 Remy van Elst https://raymii.org
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, version 3.
7 | *
8 | * This program is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 | * General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | #pragma once
18 |
19 | #include "src/listmodel/caissuerlistmodel.h"
20 |
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 |
28 | typedef QPair QIntPair;
29 |
30 | class CAConcurrentGatherer : public QObject
31 | {
32 | Q_OBJECT
33 | Q_PROPERTY(bool stop READ stop WRITE setStop NOTIFY stopChanged FINAL)
34 | Q_PROPERTY(QStringList hostnames READ hostnames WRITE setHostnames NOTIFY hostnamesChanged FINAL)
35 | Q_PROPERTY(CACertificateListModel* issuersCounted READ issuersCounted NOTIFY issuersCountedChanged FINAL)
36 | Q_PROPERTY(CACertificateListModel* notInUseSystemRootCAs READ notInUseSystemRootCAs NOTIFY notInUseSystemRootCAsChanged FINAL)
37 | Q_PROPERTY(bool busy READ busy WRITE setBusy NOTIFY busyChanged FINAL)
38 | Q_PROPERTY(QString statusText READ statusText WRITE setStatusText NOTIFY statusTextChanged FINAL)
39 | Q_PROPERTY(int progress READ progress WRITE setProgress NOTIFY progressChanged FINAL)
40 | Q_PROPERTY(int privateProgress READ privateProgress WRITE setPrivateProgress NOTIFY privateProgressChanged FINAL)
41 |
42 | public:
43 | explicit CAConcurrentGatherer(QObject *parent = nullptr);
44 |
45 | Q_INVOKABLE void clear();
46 | Q_INVOKABLE void startGatherCertificatesInBackground();
47 | Q_INVOKABLE void exportToText(const QUrl& path);
48 |
49 | QStringList hostnames() const;
50 | void setHostnames(const QStringList &newHostnames);
51 |
52 | CACertificateListModel *issuersCounted() const;
53 |
54 | CACertificateListModel *notInUseSystemRootCAs() const;
55 |
56 | bool busy() const;
57 | void setBusy(bool newBusy);
58 |
59 | QString statusText() const;
60 | void setStatusText(const QString &newStatusText);
61 |
62 | int progress() const;
63 | void setProgress(int newProgress);
64 |
65 | int privateProgress() const;
66 | void setPrivateProgress(int newPrivateProgress);
67 |
68 | bool stop() const;
69 | void setStop(bool newStop);
70 |
71 | signals:
72 | void hostnamesChanged();
73 | void issuersCountedChanged();
74 | void threadBucketFinished();
75 | void allThreadsFinished();
76 | void busyChanged();
77 | void statusTextChanged();
78 | void progressChanged();
79 | void privateProgressChanged(int newProgress);
80 | void notInUseSystemRootCAsChanged();
81 | void stopChanged();
82 |
83 | private slots:
84 | void onThreadBucketFinished();
85 | void onAllThreadsFinished();
86 |
87 | private:
88 | bool _busy = false;
89 | QStringList m_hostnames;
90 | void gatherCertificates();
91 | void checkNonInUseSystemRootCAs();
92 | QList _systemCerts;
93 | QList _notInUseSystemRootCAList;
94 | QHash resultHash;
95 | QList resultList;
96 | CACertificateListModel *m_issuersCounted = nullptr;
97 | CACertificateListModel *_notInUseSystemRootCAs = nullptr;
98 | QString m_statusText;
99 | int m_progress;
100 | int m_privateProgress;
101 | std::atomic m_stop = false;
102 | };
103 |
104 | Q_DECLARE_METATYPE(QIntPair)
105 |
--------------------------------------------------------------------------------
/src/versioncheck/versioncheck.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022 Remy van Elst
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, version 3.
7 | *
8 | * This program is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 | * General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | *
16 | */
17 |
18 | #include "versioncheck.h"
19 | #include
20 | #include
21 | #include
22 |
23 | VersionCheck::VersionCheck(QObject *parent) : QObject(parent)
24 | {
25 | _manager = new QNetworkAccessManager(this);
26 | _timer = new QTimer(this);
27 |
28 | int updateCheckInterval = QRandomGenerator::global()->bounded(80000, 300000);
29 |
30 | _timer->setInterval(updateCheckInterval);
31 | QObject::connect(_timer, &QTimer::timeout, this, &VersionCheck::getCurrentVersion);
32 | _timer->start();
33 |
34 | QObject::connect(this, &VersionCheck::currentVersionChanged, this, &VersionCheck::checkVersionOutput);
35 |
36 | getCurrentVersion();
37 | }
38 |
39 | void VersionCheck::getCurrentVersion()
40 | {
41 | auto _request = QScopedPointer(new QNetworkRequest());
42 | _request->setUrl(_url);
43 | _request->setTransferTimeout(5000);
44 | QString ua = "CertInfo v" + QString(APP_VERSION) + " " + QGuiApplication::platformName() + "; ";
45 |
46 | _request->setRawHeader("User-Agent", ua.toUtf8());
47 | _request->setRawHeader("Version", QString(APP_VERSION).toUtf8());
48 |
49 | QNetworkReply *reply = _manager->get(*_request);
50 | QObject::connect(reply, &QNetworkReply::finished, this, &VersionCheck::slotFinished);
51 | }
52 |
53 | const QString &VersionCheck::currentVersion() const
54 | {
55 | return _currentVersion;
56 | }
57 |
58 | bool VersionCheck::newVersionAvailable() const
59 | {
60 | return m_newVersionAvailable;
61 | }
62 |
63 | void VersionCheck::setCurrentVersion(const QString &newCurrentVersion)
64 | {
65 | if (_currentVersion == newCurrentVersion)
66 | return;
67 | _currentVersion = newCurrentVersion;
68 | emit currentVersionChanged(_currentVersion);
69 | }
70 |
71 | void VersionCheck::slotFinished()
72 | {
73 | QNetworkReply *reply = dynamic_cast(sender());
74 | if(reply != nullptr) {
75 | QString output = reply->readAll();
76 | if(output.contains(versionNumberFormat)) {
77 | setCurrentVersion(output);
78 | }
79 | reply->deleteLater();
80 | }
81 | }
82 |
83 |
84 | void VersionCheck::checkVersionOutput(const QString &newVersion)
85 | {
86 | bool updateAvailable = false;
87 |
88 | QString thisVersionString = APP_VERSION;
89 | thisVersionString.remove(QChar('.'), Qt::CaseInsensitive);
90 |
91 | QString newVersionString = newVersion;
92 | newVersionString.remove(QChar('.'), Qt::CaseInsensitive);
93 |
94 | bool thisVersionToLLSuccess = false;
95 | unsigned long long thisVersionNumber = thisVersionString.toULongLong(&thisVersionToLLSuccess);
96 |
97 | bool newVersionToLLSuccess = false;
98 | unsigned long long newVersionNumber = newVersionString.toULongLong(&newVersionToLLSuccess);
99 |
100 | if(newVersionToLLSuccess && thisVersionToLLSuccess)
101 | {
102 | if(newVersionNumber > thisVersionNumber) {
103 | updateAvailable = true;
104 | }
105 | }
106 |
107 | setNewVersionAvailable(updateAvailable);
108 | }
109 |
110 | void VersionCheck::setNewVersionAvailable(bool newNewVersionAvailable)
111 | {
112 | if (m_newVersionAvailable == newNewVersionAvailable)
113 | return;
114 | m_newVersionAvailable = newNewVersionAvailable;
115 | emit newVersionAvailableChanged();
116 | }
117 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/sorters/sorter.cpp:
--------------------------------------------------------------------------------
1 | #include "sorter.h"
2 | #include "qqmlsortfilterproxymodel.h"
3 |
4 | namespace qqsfpm {
5 |
6 | /*!
7 | \qmltype Sorter
8 | \qmlabstract
9 | \inqmlmodule SortFilterProxyModel
10 | \ingroup Sorters
11 | \brief Base type for the \l SortFilterProxyModel sorters.
12 |
13 | The Sorter type cannot be used directly in a QML file.
14 | It exists to provide a set of common properties and methods,
15 | available across all the other sorters types that inherit from it.
16 | Attempting to use the Sorter type directly will result in an error.
17 | */
18 |
19 | Sorter::Sorter(QObject *parent) : QObject(parent)
20 | {
21 | }
22 |
23 | Sorter::~Sorter() = default;
24 |
25 | /*!
26 | \qmlproperty bool Sorter::enabled
27 |
28 | This property holds whether the sorter is enabled.
29 | A disabled sorter will not change the order of the rows.
30 |
31 | By default, sorters are enabled.
32 | */
33 | bool Sorter::enabled() const
34 | {
35 | return m_enabled;
36 | }
37 |
38 | void Sorter::setEnabled(bool enabled)
39 | {
40 | if (m_enabled == enabled)
41 | return;
42 |
43 | m_enabled = enabled;
44 | Q_EMIT enabledChanged();
45 | Q_EMIT invalidated();
46 | }
47 |
48 | bool Sorter::ascendingOrder() const
49 | {
50 | return sortOrder() == Qt::AscendingOrder;
51 | }
52 |
53 | void Sorter::setAscendingOrder(bool ascendingOrder)
54 | {
55 | setSortOrder(ascendingOrder ? Qt::AscendingOrder : Qt::DescendingOrder);
56 | }
57 |
58 |
59 | /*!
60 | \qmlproperty Qt::SortOrder Sorter::sortOrder
61 |
62 | This property holds the sort order of this sorter.
63 |
64 | \value Qt.AscendingOrder The items are sorted ascending e.g. starts with 'AAA' ends with 'ZZZ' in Latin-1 locales
65 | \value Qt.DescendingOrder The items are sorted descending e.g. starts with 'ZZZ' ends with 'AAA' in Latin-1 locales
66 |
67 | By default, sorting is in ascending order.
68 | */
69 | Qt::SortOrder Sorter::sortOrder() const
70 | {
71 | return m_sortOrder;
72 | }
73 |
74 | void Sorter::setSortOrder(Qt::SortOrder sortOrder)
75 | {
76 | if (m_sortOrder == sortOrder)
77 | return;
78 |
79 | m_sortOrder = sortOrder;
80 | Q_EMIT sortOrderChanged();
81 | invalidate();
82 | }
83 |
84 | /*!
85 | \qmlproperty int Sorter::priority
86 |
87 | This property holds the sort priority of this sorter.
88 | Sorters with a higher priority are applied first.
89 | In case of equal priority, Sorters are ordered by their insertion order.
90 |
91 | By default, the priority is 0.
92 | */
93 | int Sorter::priority() const
94 | {
95 | return m_priority;
96 | }
97 |
98 | void Sorter::setPriority(int priority)
99 | {
100 | if (m_priority == priority)
101 | return;
102 |
103 | m_priority = priority;
104 | Q_EMIT priorityChanged();
105 | invalidate();
106 | }
107 |
108 | int Sorter::compareRows(const QModelIndex &source_left, const QModelIndex &source_right, const QQmlSortFilterProxyModel& proxyModel) const
109 | {
110 | int comparison = compare(source_left, source_right, proxyModel);
111 | return (m_sortOrder == Qt::AscendingOrder) ? comparison : -comparison;
112 | }
113 |
114 | int Sorter::compare(const QModelIndex &sourceLeft, const QModelIndex &sourceRight, const QQmlSortFilterProxyModel& proxyModel) const
115 | {
116 | if (lessThan(sourceLeft, sourceRight, proxyModel))
117 | return -1;
118 | if (lessThan(sourceRight, sourceLeft, proxyModel))
119 | return 1;
120 | return 0;
121 | }
122 |
123 | void Sorter::proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel)
124 | {
125 | Q_UNUSED(proxyModel)
126 | }
127 |
128 | bool Sorter::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight, const QQmlSortFilterProxyModel& proxyModel) const
129 | {
130 | Q_UNUSED(sourceLeft)
131 | Q_UNUSED(sourceRight)
132 | Q_UNUSED(proxyModel)
133 | return false;
134 | }
135 |
136 | void Sorter::invalidate()
137 | {
138 | if (m_enabled)
139 | Q_EMIT invalidated();
140 | }
141 |
142 | }
143 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/filters/filtercontainer.cpp:
--------------------------------------------------------------------------------
1 | #include "filtercontainer.h"
2 | #include "filter.h"
3 | #include
4 |
5 | namespace qqsfpm {
6 |
7 | /*!
8 | \qmltype FilterContainer
9 | \qmlabstract
10 | \inqmlmodule SortFilterProxyModel
11 | \ingroup FilterAttached
12 | \brief Abstract interface for types containing \l {Filter}{Filters}.
13 |
14 | \section2 Types implementing this interface:
15 | \annotatedlist FilterContainer
16 | */
17 |
18 | QList FilterContainer::filters() const
19 | {
20 | return m_filters;
21 | }
22 |
23 | void FilterContainer::appendFilter(Filter* filter)
24 | {
25 | m_filters.append(filter);
26 | onFilterAppended(filter);
27 | }
28 |
29 | void FilterContainer::removeFilter(Filter* filter)
30 | {
31 | m_filters.removeOne(filter);
32 | onFilterRemoved(filter);
33 | }
34 |
35 | void FilterContainer::clearFilters()
36 | {
37 | m_filters.clear();
38 | onFiltersCleared();
39 | }
40 |
41 | QQmlListProperty FilterContainer::filtersListProperty()
42 | {
43 | return QQmlListProperty(reinterpret_cast(this), &m_filters,
44 | &FilterContainer::append_filter,
45 | &FilterContainer::count_filter,
46 | &FilterContainer::at_filter,
47 | &FilterContainer::clear_filters);
48 | }
49 |
50 | void FilterContainer::append_filter(QQmlListProperty* list, Filter* filter)
51 | {
52 | if (!filter)
53 | return;
54 |
55 | FilterContainer* that = reinterpret_cast(list->object);
56 | that->appendFilter(filter);
57 | }
58 |
59 | qqsfpm::FilterContainer::sizetype FilterContainer::count_filter(QQmlListProperty* list)
60 | {
61 | QList* filters = static_cast*>(list->data);
62 | return filters->count();
63 | }
64 |
65 | Filter* FilterContainer::at_filter(QQmlListProperty* list, qqsfpm::FilterContainer::sizetype index)
66 | {
67 | QList* filters = static_cast*>(list->data);
68 | return filters->at(index);
69 | }
70 |
71 | void FilterContainer::clear_filters(QQmlListProperty *list)
72 | {
73 | FilterContainer* that = reinterpret_cast(list->object);
74 | that->clearFilters();
75 | }
76 |
77 | FilterContainerAttached::FilterContainerAttached(QObject* object) : QObject(object),
78 | m_filter(qobject_cast(object))
79 | {
80 | if (!m_filter)
81 | qmlWarning(object) << "FilterContainer must be attached to a Filter";
82 | }
83 |
84 | FilterContainerAttached::~FilterContainerAttached()
85 | {
86 | if (m_filter && m_container) {
87 | FilterContainer* container = qobject_cast(m_container.data());
88 | container->removeFilter(m_filter);
89 | }
90 | }
91 |
92 | /*!
93 | \qmlattachedproperty bool FilterContainer::container
94 | This attached property allows you to include in a \l FilterContainer a \l Filter that
95 | has been instantiated outside of the \l FilterContainer, for example in an Instantiator.
96 | */
97 | QObject* FilterContainerAttached::container() const
98 | {
99 | return m_container;
100 | }
101 |
102 | void FilterContainerAttached::setContainer(QObject* object)
103 | {
104 | if (m_container == object)
105 | return;
106 |
107 | FilterContainer* container = qobject_cast(object);
108 | if (object && !container)
109 | qmlWarning(parent()) << "container must inherits from FilterContainer, " << object->metaObject()->className() << " provided";
110 |
111 | if (m_container && m_filter)
112 | qobject_cast(m_container.data())->removeFilter(m_filter);
113 |
114 | m_container = container ? object : nullptr;
115 | if (container && m_filter)
116 | container->appendFilter(m_filter);
117 |
118 | Q_EMIT containerChanged();
119 | }
120 |
121 | FilterContainerAttached* FilterContainerAttached::qmlAttachedProperties(QObject* object)
122 | {
123 | return new FilterContainerAttached(object);
124 | }
125 |
126 | }
127 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/sorters/sortercontainer.cpp:
--------------------------------------------------------------------------------
1 | #include "sortercontainer.h"
2 | #include "sorter.h"
3 | #include
4 |
5 | namespace qqsfpm {
6 |
7 | /*!
8 | \qmltype SorterContainer
9 | \qmlabstract
10 | \inqmlmodule SortFilterProxyModel
11 | \ingroup SorterAttached
12 | \brief Abstract interface for types containing \l {Sorter}{Sorters}.
13 |
14 | \section2 Types implementing this interface:
15 | \annotatedlist SorterContainer
16 | */
17 |
18 | QList SorterContainer::sorters() const
19 | {
20 | return m_sorters;
21 | }
22 |
23 | void SorterContainer::appendSorter(Sorter* sorter)
24 | {
25 | m_sorters.append(sorter);
26 | onSorterAppended(sorter);
27 | }
28 |
29 | void SorterContainer::removeSorter(Sorter *sorter)
30 | {
31 | m_sorters.removeOne(sorter);
32 | onSorterRemoved(sorter);
33 | }
34 |
35 | void SorterContainer::clearSorters()
36 | {
37 | m_sorters.clear();
38 | onSortersCleared();
39 | }
40 |
41 | QQmlListProperty SorterContainer::sortersListProperty()
42 | {
43 | return QQmlListProperty(reinterpret_cast(this), &m_sorters,
44 | &SorterContainer::append_sorter,
45 | &SorterContainer::count_sorter,
46 | &SorterContainer::at_sorter,
47 | &SorterContainer::clear_sorters);
48 | }
49 |
50 | void SorterContainer::append_sorter(QQmlListProperty* list, Sorter* sorter)
51 | {
52 | if (!sorter)
53 | return;
54 |
55 | SorterContainer* that = reinterpret_cast(list->object);
56 | that->appendSorter(sorter);
57 | }
58 |
59 | SorterContainer::sizetype SorterContainer::count_sorter(QQmlListProperty* list)
60 | {
61 | QList* sorters = static_cast*>(list->data);
62 | return sorters->count();
63 | }
64 |
65 | Sorter* SorterContainer::at_sorter(QQmlListProperty* list, qqsfpm::SorterContainer::sizetype index)
66 | {
67 | QList* sorters = static_cast*>(list->data);
68 | return sorters->at(index);
69 | }
70 |
71 | void SorterContainer::clear_sorters(QQmlListProperty *list)
72 | {
73 | SorterContainer* that = reinterpret_cast(list->object);
74 | that->clearSorters();
75 | }
76 |
77 | SorterContainerAttached::SorterContainerAttached(QObject* object) : QObject(object),
78 | m_sorter(qobject_cast(object))
79 | {
80 | if (!m_sorter)
81 | qmlWarning(object) << "SorterContainerAttached must be attached to a Sorter";
82 | }
83 |
84 | SorterContainerAttached::~SorterContainerAttached()
85 | {
86 | if (m_sorter && m_container) {
87 | SorterContainer* container = qobject_cast(m_container.data());
88 | container->removeSorter(m_sorter);
89 | }
90 | }
91 |
92 | /*!
93 | \qmlattachedproperty bool SorterContainer::container
94 | This attached property allows you to include in a \l SorterContainer a \l Sorter that
95 | has been instantiated outside of the \l SorterContainer, for example in an Instantiator.
96 | */
97 | QObject* SorterContainerAttached::container() const
98 | {
99 | return m_container;
100 | }
101 |
102 | void SorterContainerAttached::setContainer(QObject* object)
103 | {
104 | if (m_container == object)
105 | return;
106 |
107 | SorterContainer* container = qobject_cast(object);
108 | if (object && !container)
109 | qmlWarning(parent()) << "container must inherits from SorterContainer, " << object->metaObject()->className() << " provided";
110 |
111 | if (m_container && m_sorter)
112 | qobject_cast(m_container.data())->removeSorter(m_sorter);
113 |
114 | m_container = container ? object : nullptr;
115 | if (container && m_sorter)
116 | container->appendSorter(m_sorter);
117 |
118 | Q_EMIT containerChanged();
119 | }
120 |
121 | SorterContainerAttached* SorterContainerAttached::qmlAttachedProperties(QObject* object)
122 | {
123 | return new SorterContainerAttached(object);
124 | }
125 |
126 | }
127 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/filters/rangefilter.cpp:
--------------------------------------------------------------------------------
1 | #include "rangefilter.h"
2 |
3 | #include "qvariantlessthan.h"
4 |
5 |
6 |
7 |
8 | namespace qqsfpm {
9 |
10 | /*!
11 | \qmltype RangeFilter
12 | \inherits RoleFilter
13 | \inqmlmodule SortFilterProxyModel
14 | \ingroup Filters
15 | \brief Filters rows between boundary values.
16 |
17 | A RangeFilter is a \l RoleFilter that accepts rows if their data is between the filter's minimum and maximum value.
18 |
19 | In the following example, only rows with their \c price role set to a value between the tow boundary of the slider will be accepted :
20 | \code
21 | RangeSlider {
22 | id: priceRangeSlider
23 | }
24 |
25 | SortFilterProxyModel {
26 | sourceModel: priceModel
27 | filters: RangeFilter {
28 | roleName: "price"
29 | minimumValue: priceRangeSlider.first.value
30 | maximumValue: priceRangeSlider.second.value
31 | }
32 | }
33 | \endcode
34 | */
35 |
36 | /*!
37 | \qmlproperty int RangeFilter::minimumValue
38 |
39 | This property holds the minimumValue of the filter.
40 | Rows with a value lower than \c minimumValue will be rejected.
41 |
42 | By default, no value is set.
43 |
44 | \sa minimumInclusive
45 | */
46 | QVariant RangeFilter::minimumValue() const
47 | {
48 | return m_minimumValue;
49 | }
50 |
51 | void RangeFilter::setMinimumValue(QVariant minimumValue)
52 | {
53 | if (m_minimumValue == minimumValue)
54 | return;
55 |
56 | m_minimumValue = minimumValue;
57 | Q_EMIT minimumValueChanged();
58 | invalidate();
59 | }
60 |
61 | /*!
62 | \qmlproperty int RangeFilter::minimumInclusive
63 |
64 | This property holds whether the \l minimumValue is inclusive.
65 |
66 | By default, the \l minimumValue is inclusive.
67 |
68 | \sa minimumValue
69 | */
70 | bool RangeFilter::minimumInclusive() const
71 | {
72 | return m_minimumInclusive;
73 | }
74 |
75 | void RangeFilter::setMinimumInclusive(bool minimumInclusive)
76 | {
77 | if (m_minimumInclusive == minimumInclusive)
78 | return;
79 |
80 | m_minimumInclusive = minimumInclusive;
81 | Q_EMIT minimumInclusiveChanged();
82 | invalidate();
83 | }
84 |
85 | /*!
86 | \qmlproperty int RangeFilter::maximumValue
87 |
88 | This property holds the maximumValue of the filter.
89 | Rows with a value higher than \c maximumValue will be rejected.
90 |
91 | By default, no value is set.
92 |
93 | \sa maximumInclusive
94 | */
95 | QVariant RangeFilter::maximumValue() const
96 | {
97 | return m_maximumValue;
98 | }
99 |
100 | void RangeFilter::setMaximumValue(QVariant maximumValue)
101 | {
102 | if (m_maximumValue == maximumValue)
103 | return;
104 |
105 | m_maximumValue = maximumValue;
106 | Q_EMIT maximumValueChanged();
107 | invalidate();
108 | }
109 |
110 | /*!
111 | \qmlproperty int RangeFilter::maximumInclusive
112 |
113 | This property holds whether the \l minimumValue is inclusive.
114 |
115 | By default, the \l minimumValue is inclusive.
116 |
117 | \sa minimumValue
118 | */
119 | bool RangeFilter::maximumInclusive() const
120 | {
121 | return m_maximumInclusive;
122 | }
123 |
124 | void RangeFilter::setMaximumInclusive(bool maximumInclusive)
125 | {
126 | if (m_maximumInclusive == maximumInclusive)
127 | return;
128 |
129 | m_maximumInclusive = maximumInclusive;
130 | Q_EMIT maximumInclusiveChanged();
131 | invalidate();
132 | }
133 |
134 | bool RangeFilter::filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const
135 | {
136 | const QVariant value = sourceData(sourceIndex, proxyModel);
137 | bool lessThanMin = m_minimumValue.isValid() &&
138 | (m_minimumInclusive ? qqsfpm::lessThan(value, m_minimumValue)
139 | : !qqsfpm::lessThan(m_minimumValue, value));
140 | bool moreThanMax = m_maximumValue.isValid() &&
141 | (m_maximumInclusive ? qqsfpm::lessThan(m_maximumValue, value)
142 | : !qqsfpm::lessThan(value, m_maximumValue));
143 | return !(lessThanMin || moreThanMax);
144 | }
145 |
146 | }
147 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/proxyroles/expressionrole.cpp:
--------------------------------------------------------------------------------
1 | #include "expressionrole.h"
2 | #include "qqmlsortfilterproxymodel.h"
3 | #include
4 |
5 | namespace qqsfpm {
6 |
7 | /*!
8 | \qmltype ExpressionRole
9 | \inherits SingleRole
10 | \inqmlmodule SortFilterProxyModel
11 | \ingroup ProxyRoles
12 | \brief A custom role computed from a javascript expression.
13 |
14 | An ExpressionRole is a \l ProxyRole allowing to implement a custom role based on a javascript expression.
15 |
16 | In the following example, the \c c role is computed by adding the \c a role and \c b role of the model :
17 | \code
18 | SortFilterProxyModel {
19 | sourceModel: numberModel
20 | proxyRoles: ExpressionRole {
21 | name: "c"
22 | expression: model.a + model.b
23 | }
24 | }
25 | \endcode
26 | */
27 |
28 | /*!
29 | \qmlproperty expression ExpressionRole::expression
30 |
31 | An expression to implement a custom role.
32 | It has the same syntax has a \l {http://doc.qt.io/qt-5/qtqml-syntax-propertybinding.html} {Property Binding} except it will be evaluated for each of the source model's rows.
33 | The data for this role will be the retuned valued of the expression.
34 | Data for each row is exposed like for a delegate of a QML View.
35 |
36 | This expression is reevaluated for a row every time its model data changes.
37 | When an external property (not \c index or in \c model) the expression depends on changes, the expression is reevaluated for every row of the source model.
38 | To capture the properties the expression depends on, the expression is first executed with invalid data and each property access is detected by the QML engine.
39 | This means that if a property is not accessed because of a conditional, it won't be captured and the expression won't be reevaluted when this property changes.
40 |
41 | A workaround to this problem is to access all the properties the expressions depends unconditionally at the beggining of the expression.
42 | */
43 | const QQmlScriptString& ExpressionRole::expression() const
44 | {
45 | return m_scriptString;
46 | }
47 |
48 | void ExpressionRole::setExpression(const QQmlScriptString& scriptString)
49 | {
50 | if (m_scriptString == scriptString)
51 | return;
52 |
53 | m_scriptString = scriptString;
54 | updateExpression();
55 |
56 | Q_EMIT expressionChanged();
57 | invalidate();
58 | }
59 |
60 | void ExpressionRole::proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel)
61 | {
62 | updateContext(proxyModel);
63 | }
64 |
65 | QVariant ExpressionRole::data(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel)
66 | {
67 | if (!m_scriptString.isEmpty()) {
68 | QVariantMap modelMap;
69 | QHash roles = proxyModel.roleNames();
70 |
71 | QQmlContext context(qmlContext(this));
72 | auto addToContext = [&] (const QString &name, const QVariant& value) {
73 | context.setContextProperty(name, value);
74 | modelMap.insert(name, value);
75 | };
76 |
77 | for (auto it = roles.cbegin(); it != roles.cend(); ++it)
78 | addToContext(it.value(), proxyModel.sourceData(sourceIndex, it.key()));
79 | addToContext("index", sourceIndex.row());
80 |
81 | context.setContextProperty("model", modelMap);
82 |
83 | QQmlExpression expression(m_scriptString, &context);
84 | QVariant result = expression.evaluate();
85 |
86 | if (expression.hasError()) {
87 | qWarning() << expression.error();
88 | return true;
89 | }
90 | return result;
91 | }
92 | return QVariant();
93 | }
94 |
95 | void ExpressionRole::updateContext(const QQmlSortFilterProxyModel& proxyModel)
96 | {
97 | delete m_context;
98 | m_context = new QQmlContext(qmlContext(this), this);
99 | // what about roles changes ?
100 | QVariantMap modelMap;
101 |
102 | auto addToContext = [&] (const QString &name, const QVariant& value) {
103 | m_context->setContextProperty(name, value);
104 | modelMap.insert(name, value);
105 | };
106 |
107 | for (const QByteArray& roleName : proxyModel.roleNames().values())
108 | addToContext(roleName, QVariant());
109 |
110 | addToContext("index", -1);
111 |
112 | m_context->setContextProperty("model", modelMap);
113 | updateExpression();
114 | }
115 |
116 | void ExpressionRole::updateExpression()
117 | {
118 | if (!m_context)
119 | return;
120 |
121 | delete m_expression;
122 | m_expression = new QQmlExpression(m_scriptString, m_context, 0, this);
123 | connect(m_expression, &QQmlExpression::valueChanged, this, &ExpressionRole::invalidate);
124 | m_expression->setNotifyOnValueChanged(true);
125 | m_expression->evaluate();
126 | }
127 |
128 | }
129 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/filters/expressionfilter.cpp:
--------------------------------------------------------------------------------
1 | #include "expressionfilter.h"
2 | #include "qqmlsortfilterproxymodel.h"
3 | #include
4 |
5 | namespace qqsfpm {
6 |
7 | /*!
8 | \qmltype ExpressionFilter
9 | \inherits Filter
10 | \inqmlmodule SortFilterProxyModel
11 | \ingroup Filters
12 | \brief Filters row with a custom filtering.
13 |
14 | An ExpressionFilter is a \l Filter allowing to implement custom filtering based on a javascript expression.
15 | */
16 |
17 | /*!
18 | \qmlproperty expression ExpressionFilter::expression
19 |
20 | An expression to implement custom filtering, it must evaluate to a boolean.
21 | It has the same syntax has a \l {http://doc.qt.io/qt-5/qtqml-syntax-propertybinding.html} {Property Binding} except it will be evaluated for each of the source model's rows.
22 | Rows that have their expression evaluating to \c true will be accepted by the model.
23 | Data for each row is exposed like for a delegate of a QML View.
24 |
25 | This expression is reevaluated for a row every time its model data changes.
26 | When an external property (not \c index or in \c model) the expression depends on changes, the expression is reevaluated for every row of the source model.
27 | To capture the properties the expression depends on, the expression is first executed with invalid data and each property access is detected by the QML engine.
28 | This means that if a property is not accessed because of a conditional, it won't be captured and the expression won't be reevaluted when this property changes.
29 |
30 | A workaround to this problem is to access all the properties the expressions depends unconditionally at the beggining of the expression.
31 | */
32 | const QQmlScriptString& ExpressionFilter::expression() const
33 | {
34 | return m_scriptString;
35 | }
36 |
37 | void ExpressionFilter::setExpression(const QQmlScriptString& scriptString)
38 | {
39 | if (m_scriptString == scriptString)
40 | return;
41 |
42 | m_scriptString = scriptString;
43 | updateExpression();
44 |
45 | Q_EMIT expressionChanged();
46 | invalidate();
47 | }
48 |
49 | void ExpressionFilter::proxyModelCompleted(const QQmlSortFilterProxyModel& proxyModel)
50 | {
51 | updateContext(proxyModel);
52 | }
53 |
54 | bool ExpressionFilter::filterRow(const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel) const
55 | {
56 | if (!m_scriptString.isEmpty()) {
57 | QVariantMap modelMap;
58 | QHash roles = proxyModel.roleNames();
59 |
60 | QQmlContext context(qmlContext(this));
61 | auto addToContext = [&] (const QString &name, const QVariant& value) {
62 | context.setContextProperty(name, value);
63 | modelMap.insert(name, value);
64 | };
65 |
66 | for (auto it = roles.cbegin(); it != roles.cend(); ++it)
67 | addToContext(it.value(), proxyModel.sourceData(sourceIndex, it.key()));
68 | addToContext("index", sourceIndex.row());
69 |
70 | context.setContextProperty("model", modelMap);
71 |
72 | QQmlExpression expression(m_scriptString, &context);
73 | QVariant variantResult = expression.evaluate();
74 |
75 | if (expression.hasError()) {
76 | qWarning() << expression.error();
77 | return true;
78 | }
79 | if (variantResult.canConvert()) {
80 | return variantResult.toBool();
81 | } else {
82 | qWarning("%s:%i:%i : Can't convert result to bool",
83 | expression.sourceFile().toUtf8().data(),
84 | expression.lineNumber(),
85 | expression.columnNumber());
86 | return true;
87 | }
88 | }
89 | return true;
90 | }
91 |
92 | void ExpressionFilter::updateContext(const QQmlSortFilterProxyModel& proxyModel)
93 | {
94 | delete m_context;
95 | m_context = new QQmlContext(qmlContext(this), this);
96 | // what about roles changes ?
97 | QVariantMap modelMap;
98 |
99 | auto addToContext = [&] (const QString &name, const QVariant& value) {
100 | m_context->setContextProperty(name, value);
101 | modelMap.insert(name, value);
102 | };
103 |
104 | for (const QByteArray& roleName : proxyModel.roleNames().values())
105 | addToContext(roleName, QVariant());
106 |
107 | addToContext("index", -1);
108 |
109 | m_context->setContextProperty("model", modelMap);
110 | updateExpression();
111 | }
112 |
113 | void ExpressionFilter::updateExpression()
114 | {
115 | if (!m_context)
116 | return;
117 |
118 | delete m_expression;
119 | m_expression = new QQmlExpression(m_scriptString, m_context, 0, this);
120 | connect(m_expression, &QQmlExpression::valueChanged, this, &ExpressionFilter::invalidate);
121 | m_expression->setNotifyOnValueChanged(true);
122 | m_expression->evaluate();
123 | }
124 |
125 | }
126 |
--------------------------------------------------------------------------------
/src/domainsources/browserhistorydb.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2023 Remy van Elst https://raymii.org
3 | *
4 | * This program is free software: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation, version 3.
7 | *
8 | * This program is distributed in the hope that it will be useful, but
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 | * General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 |
18 | #include "browserhistorydb.h"
19 |
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 | BrowserHistoryDb::BrowserHistoryDb(QObject *parent)
27 | : QObject{parent}
28 | {
29 | m_domains = new domainCountListModel(this);
30 | }
31 |
32 | bool BrowserHistoryDb::openDb(const QUrl path)
33 | {
34 |
35 | _db = QSqlDatabase::addDatabase("QSQLITE");
36 | setDbFileName(path.toLocalFile());
37 | _db.setDatabaseName(dbFileName());
38 |
39 | if(!_db.open()) {
40 | setLastDbError(_db.lastError().text());
41 | return false;
42 | } else {
43 | return true;
44 | }
45 |
46 | }
47 |
48 | void BrowserHistoryDb::getHostnamesFromDb()
49 | {
50 | if(!_db.isOpen())
51 | return;
52 |
53 | QStringList hostnames;
54 | QHash countsHash;
55 | QList countsList;
56 |
57 | QSqlQuery query;
58 | if(isFirefox())
59 | query.prepare(firefoxQuery());
60 | else
61 | query.prepare(chromeQuery());
62 |
63 | query.exec();
64 |
65 | while(query.next()) {
66 | QString host = query.value(0).toString();
67 | int count = query.value(1).toInt();
68 | if(isFirefox()) {
69 | host.chop(1); // remove dot
70 | std::reverse(host.begin(), host.end());
71 | }
72 | hostnames.push_back(host);
73 | countsHash[host] = count;
74 | }
75 | setLastDbError(query.lastError().text());
76 | setHostnames(hostnames);
77 |
78 | QHash::iterator i;
79 | for(i = countsHash.begin(); i != countsHash.end(); ++i) {
80 | countsList.push_back({i.key(), i.value()});
81 | }
82 |
83 | std::sort(countsList.begin(), countsList.end(), [](const QIntPair& a, const QIntPair& b) { return a.second > b.second; });
84 | m_domains->updateFromQList(countsList);
85 | }
86 |
87 | QString BrowserHistoryDb::firefoxQuery()
88 | {
89 | // Most visited domain names, hostnames are reversed.
90 | return "SELECT p.rev_host, count(*)"
91 | " FROM moz_places p"
92 | " JOIN moz_historyvisits v ON v.place_id = p.id"
93 | " WHERE p.url LIKE 'https%' "
94 | " GROUP BY p.rev_host ORDER BY count(*) desc ;";
95 | }
96 |
97 | QString BrowserHistoryDb::chromeQuery()
98 | {
99 | return "SELECT"
100 | " SUBSTR(SUBSTR(url, INSTR(url, '//') + 2), 0, INSTR(SUBSTR(url, INSTR(url, '//') + 2), '/')) AS domain,"
101 | " SUM(visit_count) AS total_visits"
102 | " FROM urls"
103 | " WHERE url LIKE 'https%'"
104 | " GROUP BY domain"
105 | " ORDER BY total_visits DESC;";
106 | }
107 |
108 | bool BrowserHistoryDb::isFirefox() const
109 | {
110 | return m_isFirefox;
111 | }
112 |
113 | void BrowserHistoryDb::setIsFirefox(bool newIsFirefox)
114 | {
115 | if (m_isFirefox == newIsFirefox)
116 | return;
117 | m_isFirefox = newIsFirefox;
118 | emit isFirefoxChanged();
119 | }
120 |
121 |
122 |
123 |
124 | QStringList BrowserHistoryDb::hostnames() const
125 | {
126 | return m_hostnames;
127 | }
128 |
129 | void BrowserHistoryDb::setHostnames(const QStringList &newHostnames)
130 | {
131 | if (m_hostnames == newHostnames)
132 | return;
133 | m_hostnames = newHostnames;
134 | emit hostnamesChanged();
135 | }
136 |
137 | QString BrowserHistoryDb::dbFileName() const
138 | {
139 | return m_dbFileName;
140 | }
141 |
142 | void BrowserHistoryDb::setDbFileName(const QString &newDbFileName)
143 | {
144 | if (m_dbFileName == newDbFileName)
145 | return;
146 | m_dbFileName = newDbFileName;
147 | emit dbFileNameChanged();
148 | }
149 |
150 | QString BrowserHistoryDb::lastDbError() const
151 | {
152 | return m_lastDbError;
153 | }
154 |
155 | void BrowserHistoryDb::setLastDbError(const QString &newLastDbError)
156 | {
157 | if (m_lastDbError == newLastDbError)
158 | return;
159 | m_lastDbError = newLastDbError;
160 | emit lastDbErrorChanged();
161 | }
162 |
163 | domainCountListModel *BrowserHistoryDb::domains() const
164 | {
165 | return m_domains;
166 | }
167 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/README.md:
--------------------------------------------------------------------------------
1 | SortFilterProxyModel
2 | ====================
3 |
4 | SortFilterProxyModel is an implementation of `QSortFilterProxyModel` conveniently exposed for QML.
5 |
6 | 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.
7 | A github actions workflow compiles the code to make sure it keeps compiling on both versions.
8 |
9 | Install
10 | -------
11 | ##### With [qpm](https://qpm.io) :
12 | 1. `qpm install fr.grecko.sortfilterproxymodel`
13 | 2. add `include(vendor/vendor.pri)` in your .pro if it is not already done
14 | 3. `import SortFilterProxyModel 0.2` to use this library in your QML files
15 |
16 | ##### Without qpm :
17 | 1. clone or download this repository
18 | 2. * `qmake` add `include (/SortFilterProxyModel.pri)` in your `.pro`
19 | * `CMake` add $ to the sources of your executable target in your cmake project
20 | 3. `import SortFilterProxyModel 0.2` to use this library in your QML files
21 |
22 | Sample Usage
23 | ------------
24 |
25 | - You can do simple filtering and sorting with SortFilterProxyModel:
26 | ```qml
27 | import QtQuick 2.2
28 | import QtQuick.Controls 1.2
29 | import SortFilterProxyModel 0.2
30 |
31 | ApplicationWindow {
32 | visible: true
33 | width: 640
34 | height: 480
35 |
36 | ListModel {
37 | id: personModel
38 | ListElement {
39 | firstName: "Erwan"
40 | lastName: "Castex"
41 | favorite: true
42 | }
43 | // ...
44 | }
45 |
46 | TextField {
47 | id: textField
48 | anchors { top: parent.top; left: parent.left; right: parent.right }
49 | height: implicitHeight
50 | }
51 |
52 | SortFilterProxyModel {
53 | id: personProxyModel
54 | sourceModel: personModel
55 | filters: RegExpFilter {
56 | roleName: "lastName"
57 | pattern: textField.text
58 | caseSensitivity: Qt.CaseInsensitive
59 | }
60 | sorters: StringSorter { roleName: "firstName" }
61 | }
62 |
63 | ListView {
64 | anchors { top: textField.bottom; bottom: parent.bottom; left: parent.left; right: parent.right }
65 | model: personProxyModel
66 | delegate: Text { text: model.firstName + " " + model.lastName}
67 | }
68 | }
69 | ```
70 | Here the `ListView` will only show elements that contains the content of the `TextField` in their `lastName` role.
71 |
72 | - But you can also achieve more complex filtering or sorting with multiple `filters` and `sorters`:
73 | ```qml
74 | SortFilterProxyModel {
75 | id: personProxyModel
76 | sourceModel: personModel
77 | filters: [
78 | ValueFilter {
79 | enabled: onlyShowFavoritesCheckbox.checked
80 | roleName: "favorite"
81 | value: true
82 | },
83 | AnyOf {
84 | RegExpFilter {
85 | roleName: "lastName"
86 | pattern: textField.text
87 | caseSensitivity: Qt.CaseInsensitive
88 | }
89 | RegExpFilter {
90 | roleName: "firstName"
91 | pattern: textField.text
92 | caseSensitivity: Qt.CaseInsensitive
93 | }
94 | }
95 | ]
96 | sorters: [
97 | RoleSorter { roleName: "favorite"; sortOrder: Qt.DescendingOrder },
98 | StringSorter { roleName: "firstName" },
99 | StringSorter { roleName: "lastName" }
100 | ]
101 | }
102 |
103 | CheckBox {
104 | id:onlyShowFavoritesCheckbox
105 | }
106 | ```
107 | This will show in the corresponding `ListView` only the elements where the `firstName` or the `lastName` match the text entered in the `textField`, and if the `onlyShowFavoritesCheckbox` is checked it will aditionnally filter the elements where `favorite` is `true`.
108 | The favorited elements will be shown first and all the elements are sorted by `firstName` and then `lastName`.
109 |
110 | Showcase Application
111 | --------------------
112 | You can find an application showcasing this library here: https://github.com/oKcerG/SFPMShowcase
113 |
114 | License
115 | -------
116 | This library is licensed under the MIT License.
117 |
118 | Documentation
119 | -------------
120 | This component is a subclass of [`QSortFilterProxyModel`](http://doc.qt.io/qt-5/qsortfilterproxymodel.html), to use it, you need to set the `sourceModel` property to a [`QAbstractItemModel*`](http://doc.qt.io/qt-5/qabstractitemmodel.html) with correct role names.
121 | This means you can use it with custom c++ models or `ListModel`, but not with JavaScript models like arrays, integers or object instances.
122 |
123 | The complete documentation reference is available here: https://okcerg.github.io/SortFilterProxyModel/
124 |
125 | Contributing
126 | ------------
127 | Don't hesitate to open an issue about a suggestion, a bug, a lack of clarity in the documentation, etc.
128 |
129 | Pull requests are also welcome, if it's a important change you should open an issue first though.
130 |
--------------------------------------------------------------------------------
/src/thirdparty/SortFilterProxyModel/proxyroles/switchrole.cpp:
--------------------------------------------------------------------------------
1 | #include "switchrole.h"
2 | #include "qqmlsortfilterproxymodel.h"
3 | #include "filters/filter.h"
4 | #include
5 |
6 | namespace qqsfpm {
7 |
8 | /*!
9 | \qmltype SwitchRole
10 | \inherits SingleRole
11 | \inqmlmodule SortFilterProxyModel
12 | \ingroup ProxyRoles
13 | \ingroup FilterContainer
14 | \brief A role using \l Filter to conditionnaly compute its data.
15 |
16 | A SwitchRole is a \l ProxyRole that computes its data with the help of \l Filter.
17 | Each top level filters specified in the \l SwitchRole is evaluated on the rows of the model, if a \l Filter evaluates to true, the data of the \l SwitchRole for this row will be the one of the attached \l {value} {SwitchRole.value} property.
18 | If no top level filters evaluate to true, the data will default to the one of the \l defaultRoleName (or the \l defaultValue if no \l defaultRoleName is specified).
19 |
20 | In the following example, the \c favoriteOrFirstNameSection role is equal to \c * if the \c favorite role of a row is true, otherwise it's the same as the \c firstName role :
21 | \code
22 | SortFilterProxyModel {
23 | sourceModel: contactModel
24 | proxyRoles: SwitchRole {
25 | name: "favoriteOrFirstNameSection"
26 | filters: ValueFilter {
27 | roleName: "favorite"
28 | value: true
29 | SwitchRole.value: "*"
30 | }
31 | defaultRoleName: "firstName"
32 | }
33 | }
34 | \endcode
35 | \sa FilterContainer
36 | */
37 | SwitchRoleAttached::SwitchRoleAttached(QObject* parent) : QObject (parent)
38 | {
39 | if (!qobject_cast