Greatly improve performance when rendering entry view (#9398)

* Fixes #9390
* Create one QCollator per entry view instead of creating one on every sort request. This greatly improves the speed of sorting and displaying entries.
* Rewrite recursive multiple placeholder replacement to use QRegularExpression
This commit is contained in:
Jonathan White 2023-05-07 11:35:20 -04:00 committed by GitHub
parent 16b3d32ca5
commit 44b152eb70
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 16 additions and 12 deletions

View File

@ -997,19 +997,19 @@ void Entry::updateModifiedSinceBegin()
QString Entry::resolveMultiplePlaceholdersRecursive(const QString& str, int maxDepth) const QString Entry::resolveMultiplePlaceholdersRecursive(const QString& str, int maxDepth) const
{ {
static QRegularExpression placeholderRegEx("(\\{[^\\}]+?\\})", QRegularExpression::CaseInsensitiveOption);
if (maxDepth <= 0) { if (maxDepth <= 0) {
qWarning("Maximum depth of replacement has been reached. Entry uuid: %s", uuid().toString().toLatin1().data()); qWarning("Maximum depth of replacement has been reached. Entry uuid: %s", uuid().toString().toLatin1().data());
return str; return str;
} }
QString result = str; QString result = str;
QRegExp placeholderRegEx("(\\{[^\\}]+\\})", Qt::CaseInsensitive, QRegExp::RegExp2); auto matches = placeholderRegEx.globalMatch(str);
placeholderRegEx.setMinimal(true); while (matches.hasNext()) {
int pos = 0; auto match = matches.next();
while ((pos = placeholderRegEx.indexIn(str, pos)) != -1) { const auto found = match.captured(1);
const QString found = placeholderRegEx.cap(1);
result.replace(found, resolvePlaceholderRecursive(found, maxDepth - 1)); result.replace(found, resolvePlaceholderRecursive(found, maxDepth - 1));
pos += placeholderRegEx.matchedLength();
} }
if (result != str) { if (result != str) {

View File

@ -16,11 +16,11 @@
*/ */
#include "SortFilterHideProxyModel.h" #include "SortFilterHideProxyModel.h"
#include <QCollator>
SortFilterHideProxyModel::SortFilterHideProxyModel(QObject* parent) SortFilterHideProxyModel::SortFilterHideProxyModel(QObject* parent)
: QSortFilterProxyModel(parent) : QSortFilterProxyModel(parent)
{ {
m_collator.setNumericMode(true);
} }
Qt::DropActions SortFilterHideProxyModel::supportedDragActions() const Qt::DropActions SortFilterHideProxyModel::supportedDragActions() const
@ -38,7 +38,7 @@ void SortFilterHideProxyModel::hideColumn(int column, bool hide)
bool SortFilterHideProxyModel::filterAcceptsColumn(int sourceColumn, const QModelIndex& sourceParent) const bool SortFilterHideProxyModel::filterAcceptsColumn(int sourceColumn, const QModelIndex& sourceParent) const
{ {
Q_UNUSED(sourceParent); Q_UNUSED(sourceParent)
return sourceColumn >= m_hiddenColumns.size() || !m_hiddenColumns.at(sourceColumn); return sourceColumn >= m_hiddenColumns.size() || !m_hiddenColumns.at(sourceColumn);
} }
@ -48,9 +48,7 @@ bool SortFilterHideProxyModel::lessThan(const QModelIndex& left, const QModelInd
auto leftData = sourceModel()->data(left, sortRole()); auto leftData = sourceModel()->data(left, sortRole());
auto rightData = sourceModel()->data(right, sortRole()); auto rightData = sourceModel()->data(right, sortRole());
if (leftData.type() == QVariant::String) { if (leftData.type() == QVariant::String) {
QCollator sorter; return m_collator.compare(leftData.toString(), rightData.toString()) < 0;
sorter.setNumericMode(true);
return sorter.compare(leftData.toString(), rightData.toString()) < 0;
} }
return QSortFilterProxyModel::lessThan(left, right); return QSortFilterProxyModel::lessThan(left, right);

View File

@ -19,6 +19,7 @@
#define KEEPASSX_SORTFILTERHIDEPROXYMODEL_H #define KEEPASSX_SORTFILTERHIDEPROXYMODEL_H
#include <QBitArray> #include <QBitArray>
#include <QCollator>
#include <QSortFilterProxyModel> #include <QSortFilterProxyModel>
class SortFilterHideProxyModel : public QSortFilterProxyModel class SortFilterHideProxyModel : public QSortFilterProxyModel
@ -36,6 +37,7 @@ protected:
private: private:
QBitArray m_hiddenColumns; QBitArray m_hiddenColumns;
QCollator m_collator;
}; };
#endif // KEEPASSX_SORTFILTERHIDEPROXYMODEL_H #endif // KEEPASSX_SORTFILTERHIDEPROXYMODEL_H

View File

@ -355,7 +355,11 @@ bool KeeAgentSettings::inEntryAttachments(const EntryAttachments* attachments)
*/ */
bool KeeAgentSettings::fromEntry(const Entry* entry) bool KeeAgentSettings::fromEntry(const Entry* entry)
{ {
return fromXml(entry->attachments()->value("KeeAgent.settings")); const auto attachments = entry->attachments();
if (attachments->hasKey("KeeAgent.settings")) {
return fromXml(attachments->value("KeeAgent.settings"));
}
return false;
} }
/** /**