-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: vendor ksortfilterproxymodel from KItemModels
暂时自带 KItemModels,以方便 Qt 6 移植。 Log:
- Loading branch information
Showing
7 changed files
with
452 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,3 +37,10 @@ License: GPL-3.0-or-later | |
Files: *.deepin.dde.*.xml */org.desktopspec.*.xml | ||
Copyright: UnionTech Software Technology Co., Ltd. | ||
License: GPL-3.0-or-later | ||
|
||
# vendored from KItemModels | ||
Files: src/quick/ksortfilterproxymodel.cpp src/quick/ksortfilterproxymodel.h | ||
Copyright: 2010, Marco Martin <[email protected]> | ||
2019, David Edmundson <[email protected]> | ||
License: LGPL-2.0-or-later | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,263 @@ | ||
/* | ||
* Copyright 2010 by Marco Martin <[email protected]> | ||
* Copyright 2019 by David Edmundson <[email protected]> | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU Library General Public License as | ||
* published by the Free Software Foundation; either version 2, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details | ||
* | ||
* You should have received a copy of the GNU Library General Public | ||
* License along with this program; if not, write to the | ||
* Free Software Foundation, Inc., | ||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
*/ | ||
|
||
#include "ksortfilterproxymodel.h" | ||
|
||
#include <QQmlContext> | ||
#include <QQmlEngine> | ||
|
||
// This is just an ECM-based logging category thing | ||
//#include "kitemmodels_debug.h" | ||
#include <QLoggingCategory> | ||
Q_DECLARE_LOGGING_CATEGORY(KITEMMODELS_LOG) | ||
Q_LOGGING_CATEGORY(KITEMMODELS_LOG, "kf.itemmodels.core", QtInfoMsg) | ||
|
||
KSortFilterProxyModel::KSortFilterProxyModel(QObject *parent) | ||
: QSortFilterProxyModel(parent) | ||
{ | ||
setDynamicSortFilter(true); | ||
connect(this, &KSortFilterProxyModel::modelReset, this, &KSortFilterProxyModel::rowCountChanged); | ||
connect(this, &KSortFilterProxyModel::rowsInserted, this, &KSortFilterProxyModel::rowCountChanged); | ||
connect(this, &KSortFilterProxyModel::rowsRemoved, this, &KSortFilterProxyModel::rowCountChanged); | ||
// NOTE: some models actually fill their roleNames() only when they get some actual data, this works around the bad behavior | ||
connect(this, &KSortFilterProxyModel::rowCountChanged, this, &KSortFilterProxyModel::syncRoleNames); | ||
|
||
connect(this, &KSortFilterProxyModel::filterRoleChanged, this, [this](int role) { | ||
const QString roleName = QString::fromUtf8(roleNames().value(role)); | ||
if (m_filterRoleName != roleName) { | ||
m_filterRoleName = roleName; | ||
Q_EMIT filterRoleNameChanged(); | ||
} | ||
}); | ||
|
||
connect(this, &KSortFilterProxyModel::sortRoleChanged, this, [this](int role) { | ||
const QString roleName = QString::fromUtf8(roleNames().value(role)); | ||
if (m_sortRoleName != roleName) { | ||
m_sortRoleName = roleName; | ||
Q_EMIT sortRoleNameChanged(); | ||
} | ||
}); | ||
} | ||
|
||
KSortFilterProxyModel::~KSortFilterProxyModel() | ||
{ | ||
} | ||
|
||
void KSortFilterProxyModel::syncRoleNames() | ||
{ | ||
if (!sourceModel()) { | ||
return; | ||
} | ||
|
||
m_roleIds.clear(); | ||
const QHash<int, QByteArray> rNames = roleNames(); | ||
m_roleIds.reserve(rNames.count()); | ||
for (auto i = rNames.constBegin(); i != rNames.constEnd(); ++i) { | ||
m_roleIds[QString::fromUtf8(i.value())] = i.key(); | ||
} | ||
|
||
setFilterRoleName(m_filterRoleName); | ||
setSortRoleName(m_sortRoleName); | ||
} | ||
|
||
int KSortFilterProxyModel::roleNameToId(const QString &name) const | ||
{ | ||
return m_roleIds.value(name, Qt::DisplayRole); | ||
} | ||
|
||
void KSortFilterProxyModel::setModel(QAbstractItemModel *model) | ||
{ | ||
if (model == sourceModel()) { | ||
return; | ||
} | ||
|
||
QSortFilterProxyModel::setSourceModel(model); | ||
|
||
if (m_componentCompleted) { | ||
syncRoleNames(); | ||
setFilterRoleName(m_filterRoleName); | ||
setSortRoleName(m_sortRoleName); | ||
} | ||
} | ||
|
||
bool KSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const | ||
{ | ||
if (m_filterRowCallback.isCallable()) { | ||
QJSEngine *engine = qjsEngine(this); | ||
QJSValueList args = {QJSValue(source_row), engine->toScriptValue(source_parent)}; | ||
|
||
QJSValue result = const_cast<KSortFilterProxyModel *>(this)->m_filterRowCallback.call(args); | ||
if (result.isError()) { | ||
qCWarning(KITEMMODELS_LOG) << "Row filter callback produced an error:"; | ||
qCWarning(KITEMMODELS_LOG) << result.toString(); | ||
return true; | ||
} else { | ||
return result.toBool(); | ||
} | ||
} | ||
|
||
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent); | ||
} | ||
|
||
bool KSortFilterProxyModel::filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const | ||
{ | ||
if (m_filterColumnCallback.isCallable()) { | ||
QJSEngine *engine = qjsEngine(this); | ||
QJSValueList args = {QJSValue(source_column), engine->toScriptValue(source_parent)}; | ||
|
||
QJSValue result = const_cast<KSortFilterProxyModel *>(this)->m_filterColumnCallback.call(args); | ||
if (result.isError()) { | ||
qCWarning(KITEMMODELS_LOG) << "Row filter callback produced an error:"; | ||
qCWarning(KITEMMODELS_LOG) << result.toString(); | ||
return true; | ||
} else { | ||
return result.toBool(); | ||
} | ||
} | ||
|
||
return QSortFilterProxyModel::filterAcceptsColumn(source_column, source_parent); | ||
} | ||
|
||
void KSortFilterProxyModel::setFilterString(const QString &filterString) | ||
{ | ||
if (filterString == m_filterString) { | ||
return; | ||
} | ||
m_filterString = filterString; | ||
QSortFilterProxyModel::setFilterFixedString(filterString); | ||
Q_EMIT filterStringChanged(); | ||
} | ||
|
||
QString KSortFilterProxyModel::filterString() const | ||
{ | ||
return m_filterString; | ||
} | ||
|
||
QJSValue KSortFilterProxyModel::filterRowCallback() const | ||
{ | ||
return m_filterRowCallback; | ||
} | ||
|
||
void KSortFilterProxyModel::setFilterRowCallback(const QJSValue &callback) | ||
{ | ||
if (m_filterRowCallback.strictlyEquals(callback)) { | ||
return; | ||
} | ||
|
||
if (!callback.isNull() && !callback.isCallable()) { | ||
return; | ||
} | ||
|
||
m_filterRowCallback = callback; | ||
invalidateFilter(); | ||
|
||
Q_EMIT filterRowCallbackChanged(callback); | ||
} | ||
|
||
void KSortFilterProxyModel::setFilterColumnCallback(const QJSValue &callback) | ||
{ | ||
if (m_filterColumnCallback.strictlyEquals(callback)) { | ||
return; | ||
} | ||
|
||
if (!callback.isNull() && !callback.isCallable()) { | ||
return; | ||
} | ||
|
||
m_filterColumnCallback = callback; | ||
invalidateFilter(); | ||
|
||
Q_EMIT filterColumnCallbackChanged(callback); | ||
} | ||
|
||
QJSValue KSortFilterProxyModel::filterColumnCallback() const | ||
{ | ||
return m_filterColumnCallback; | ||
} | ||
|
||
void KSortFilterProxyModel::setFilterRoleName(const QString &roleName) | ||
{ | ||
QSortFilterProxyModel::setFilterRole(roleNameToId(roleName)); | ||
if (roleName != m_filterRoleName) { | ||
m_filterRoleName = roleName; | ||
Q_EMIT filterRoleNameChanged(); | ||
} | ||
} | ||
|
||
QString KSortFilterProxyModel::filterRoleName() const | ||
{ | ||
return m_filterRoleName; | ||
} | ||
|
||
void KSortFilterProxyModel::setSortRoleName(const QString &roleName) | ||
{ | ||
if (roleName.isEmpty()) { | ||
sort(-1, Qt::AscendingOrder); | ||
} else if (sourceModel()) { | ||
QSortFilterProxyModel::setSortRole(roleNameToId(roleName)); | ||
sort(std::max(sortColumn(), 0), sortOrder()); | ||
} | ||
|
||
if (roleName != m_sortRoleName) { | ||
m_sortRoleName = roleName; | ||
Q_EMIT sortRoleNameChanged(); | ||
} | ||
} | ||
|
||
QString KSortFilterProxyModel::sortRoleName() const | ||
{ | ||
return m_sortRoleName; | ||
} | ||
|
||
void KSortFilterProxyModel::setSortOrder(const Qt::SortOrder order) | ||
{ | ||
sort(std::max(sortColumn(), 0), order); | ||
Q_EMIT sortOrderChanged(); | ||
} | ||
|
||
void KSortFilterProxyModel::setSortColumn(int column) | ||
{ | ||
if (column == sortColumn()) { | ||
return; | ||
} | ||
sort(column, sortOrder()); | ||
Q_EMIT sortColumnChanged(); | ||
} | ||
|
||
void KSortFilterProxyModel::classBegin() | ||
{ | ||
} | ||
|
||
void KSortFilterProxyModel::componentComplete() | ||
{ | ||
m_componentCompleted = true; | ||
if (sourceModel()) { | ||
syncRoleNames(); | ||
setFilterRoleName(m_filterRoleName); | ||
setSortRoleName(m_sortRoleName); | ||
} | ||
} | ||
|
||
void KSortFilterProxyModel::invalidateFilter() | ||
{ | ||
QSortFilterProxyModel::invalidateFilter(); | ||
} | ||
|
||
#include "moc_ksortfilterproxymodel.cpp" |
Oops, something went wrong.