File indexing completed on 2024-04-21 03:56:05

0001 /*
0002     SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.net>
0003     SPDX-FileContributor: Stephen Kelly <stephen@kdab.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #ifndef MODELEVENTLOGGER_H
0009 #define MODELEVENTLOGGER_H
0010 
0011 #include <QAbstractItemModel>
0012 
0013 #include "proxymodeltestsuite_export.h"
0014 
0015 class ModelDumper;
0016 
0017 class PROXYMODELTESTSUITE_EXPORT PersistentChange : public QObject
0018 {
0019     Q_OBJECT
0020 
0021     Q_PROPERTY(QString oldPath READ getOldPath)
0022     Q_PROPERTY(QString newPath READ getNewPath)
0023 
0024 public:
0025     PersistentChange(QObject *parent = nullptr)
0026         : QObject(parent)
0027     {
0028     }
0029     QString getPath(const QList<int> &path) const
0030     {
0031         QString result(QStringLiteral("QList<int>()"));
0032         for (const int part : path) {
0033             result.append(QLatin1String(" << "));
0034             result.append(QString::number(part));
0035         }
0036 
0037         return result;
0038     }
0039     QString getOldPath() const
0040     {
0041         return getPath(oldPath);
0042     }
0043     QString getNewPath() const
0044     {
0045         return getPath(newPath);
0046     }
0047 
0048     QList<int> oldPath;
0049     QList<int> newPath;
0050 };
0051 
0052 class PROXYMODELTESTSUITE_EXPORT ModelEvent : public QObject
0053 {
0054     Q_OBJECT
0055 public:
0056     enum Type {
0057         Init,
0058         RowsInserted,
0059         RowsRemoved,
0060         DataChanged,
0061         LayoutChanged,
0062         ModelReset,
0063     };
0064 
0065 private:
0066     // TODO: See if Q_ENUMS does this:
0067     //   Q_PROPERTY(Type type READ type)
0068 
0069     Q_PROPERTY(QString type READ type)
0070 
0071     Q_PROPERTY(int start READ start)
0072     Q_PROPERTY(int end READ end)
0073     // TODO: custom grantlee plugin.
0074     //   Q_PROPERTY(QList<int> rowAncestors READ rowAncestors)
0075 
0076     Q_PROPERTY(QString rowAncestors READ rowAncestors)
0077     Q_PROPERTY(bool hasInterpretString READ hasInterpretString)
0078     Q_PROPERTY(QString interpretString READ interpretString)
0079     Q_PROPERTY(QVariantList changes READ changes)
0080 
0081 public:
0082     ModelEvent(QObject *parent = nullptr);
0083 
0084     //   Type type() const;
0085     QString type() const;
0086     void setType(Type type);
0087 
0088     int start() const;
0089     void setStart(int start);
0090 
0091     int end() const;
0092     void setEnd(int end);
0093 
0094     QString rowAncestors() const;
0095     //   QList<int> rowAncestors() const;
0096     void setRowAncestors(QList<int> rowAncestors);
0097 
0098     bool hasInterpretString() const;
0099 
0100     QString interpretString() const;
0101     void setInterpretString(const QString &interpretString);
0102 
0103     void setChanges(const QList<PersistentChange *> &changes)
0104     {
0105         m_changedPaths = changes;
0106     }
0107     QVariantList changes() const
0108     {
0109         QVariantList list;
0110         for (PersistentChange *change : std::as_const(m_changedPaths)) {
0111             list.append(QVariant::fromValue(static_cast<QObject *>(change)));
0112         }
0113         return list;
0114     }
0115 
0116 private:
0117     Type m_type;
0118     int m_start;
0119     int m_end;
0120     QList<int> m_rowAncestors;
0121     QString m_interpretString;
0122     QList<PersistentChange *> m_changedPaths;
0123 };
0124 
0125 /**
0126  * @brief A logger for QAbstractItemModel events.
0127  *
0128  * The log creates the same structure as the @p model, and can be compiled
0129  * to reproduce failure cases.
0130  *
0131  * The log is written to a file, see writeLog for the file naming.
0132  */
0133 class PROXYMODELTESTSUITE_EXPORT ModelEventLogger : public QObject
0134 {
0135     Q_OBJECT
0136 public:
0137     ModelEventLogger(QAbstractItemModel *model, QObject *parent = nullptr);
0138     void writeLog();
0139     ~ModelEventLogger() override;
0140 
0141 private:
0142     void persistChildren(const QModelIndex &parent);
0143 
0144 private Q_SLOTS:
0145     void rowsInserted(const QModelIndex &parent, int start, int end);
0146     void rowsRemoved(const QModelIndex &parent, int start, int end);
0147     void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
0148     void layoutAboutToBeChanged();
0149     void layoutChanged();
0150     void modelReset();
0151 
0152 private:
0153     const QAbstractItemModel *const m_model;
0154     ModelDumper *const m_modelDumper;
0155     QVariant m_initEvent;
0156     QVariantList m_events;
0157     QList<QPersistentModelIndex> m_persistentIndexes;
0158     QList<QList<int>> m_oldPaths;
0159     int m_numLogs;
0160     QString m_modelName;
0161 };
0162 
0163 #endif