File indexing completed on 2024-11-24 03:56:26
0001 /* 0002 * SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best> 0003 * 0004 * SPDX-License-Identifier: GPL-3.0-or-later 0005 */ 0006 0007 #pragma once 0008 #include <QDebug> 0009 #include <QAbstractItemModel> 0010 0011 namespace app::debug { 0012 0013 namespace detail { 0014 0015 inline void print_model_column(const QAbstractItemModel* model, int i, bool flags, const std::vector<int>& roles, const QModelIndex& index, int indent) 0016 { 0017 auto logger = qDebug(); 0018 logger.noquote(); 0019 auto colindex = model->index(index.row(), i, index.parent()); 0020 for ( int role : roles ) 0021 { 0022 logger << QString(4*indent, ' ') << " *" << model->data(colindex, role); 0023 if ( flags ) 0024 logger << model->flags(colindex); 0025 } 0026 } 0027 0028 struct DebugSlot 0029 { 0030 QString prefix; 0031 QString signal; 0032 0033 template<class T> 0034 decltype(std::declval<QDebug&>() << std::declval<T>()) print(QDebug& stream, T&& t, bool) 0035 { 0036 return stream << std::forward<T>(t); 0037 } 0038 0039 template<class T> 0040 void print(QDebug&, T&&, ...){} 0041 void print_all(QDebug&) {} 0042 0043 template<class T, class... Args> 0044 void print_all(QDebug& stream, T&& t, Args&&... args) 0045 { 0046 print(stream, std::forward<T>(t), true); 0047 print_all(stream, std::forward<Args>(args)...); 0048 } 0049 0050 template<class... Args> 0051 void operator()(Args&&... args) 0052 { 0053 auto stream = qDebug(); 0054 if ( !prefix.isEmpty() ) 0055 stream << prefix; 0056 stream << signal; 0057 print_all(stream, std::forward<Args>(args)...); 0058 } 0059 }; 0060 0061 } // namespace detail 0062 0063 inline void print_model_row(const QAbstractItemModel* model, const QModelIndex& index, const std::vector<int>& columns = {}, bool flags = false, const std::vector<int>& roles = {Qt::DisplayRole}, int indent = 0) 0064 { 0065 int rows = model->rowCount(index); 0066 int cols = model->columnCount(index); 0067 0068 qDebug().noquote() << QString(4*indent, ' ') << index << "rows" << rows << "cols" << cols << "ptr" << index.internalId(); 0069 0070 if ( columns.empty() ) 0071 { 0072 for ( int i = 0; i < cols; i++ ) 0073 detail::print_model_column(model, i, flags, roles, index, indent); 0074 } 0075 else 0076 { 0077 for ( int i : columns ) 0078 detail::print_model_column(model, i, flags, roles, index, indent); 0079 } 0080 } 0081 0082 inline void print_model(const QAbstractItemModel* model, const std::vector<int>& columns = {}, bool flags = false, const std::vector<int>& roles = {Qt::DisplayRole}, const QModelIndex& index = {}, int indent = 0) 0083 { 0084 print_model_row(model, index, columns, flags, roles, indent); 0085 for ( int i = 0; i < model->rowCount(index); i++ ) 0086 { 0087 QModelIndex ci = model->index(i, 0, index); 0088 if ( !ci.isValid() ) 0089 qDebug().noquote() << QString(4*(indent+1), ' ') << "invalid"; 0090 else 0091 print_model(model, columns, flags, roles, ci, indent+1); 0092 } 0093 } 0094 0095 inline void connect_debug(QAbstractItemModel* model, const QString& prefix) 0096 { 0097 QObject::connect(model, &QAbstractItemModel::columnsAboutToBeInserted, model, detail::DebugSlot{prefix, "columnsAboutToBeInserted"}); 0098 QObject::connect(model, &QAbstractItemModel::columnsAboutToBeMoved, model, detail::DebugSlot{prefix, "columnsAboutToBeMoved"}); 0099 QObject::connect(model, &QAbstractItemModel::columnsAboutToBeRemoved, model, detail::DebugSlot{prefix, "columnsAboutToBeRemoved"}); 0100 QObject::connect(model, &QAbstractItemModel::columnsInserted, model, detail::DebugSlot{prefix, "columnsInserted"}); 0101 QObject::connect(model, &QAbstractItemModel::columnsMoved, model, detail::DebugSlot{prefix, "columnsMoved"}); 0102 QObject::connect(model, &QAbstractItemModel::columnsRemoved, model, detail::DebugSlot{prefix, "columnsRemoved"}); 0103 QObject::connect(model, &QAbstractItemModel::dataChanged, model, detail::DebugSlot{prefix, "dataChanged"}); 0104 QObject::connect(model, &QAbstractItemModel::headerDataChanged, model, detail::DebugSlot{prefix, "headerDataChanged"}); 0105 QObject::connect(model, &QAbstractItemModel::layoutAboutToBeChanged, model, detail::DebugSlot{prefix, "layoutAboutToBeChanged"}); 0106 QObject::connect(model, &QAbstractItemModel::layoutChanged, model, detail::DebugSlot{prefix, "layoutChanged"}); 0107 QObject::connect(model, &QAbstractItemModel::modelAboutToBeReset, model, detail::DebugSlot{prefix, "modelAboutToBeReset"}); 0108 QObject::connect(model, &QAbstractItemModel::modelReset, model, detail::DebugSlot{prefix, "modelReset"}); 0109 QObject::connect(model, &QAbstractItemModel::rowsAboutToBeInserted, model, detail::DebugSlot{prefix, "rowsAboutToBeInserted"}); 0110 QObject::connect(model, &QAbstractItemModel::rowsAboutToBeMoved, model, detail::DebugSlot{prefix, "rowsAboutToBeMoved"}); 0111 QObject::connect(model, &QAbstractItemModel::rowsAboutToBeRemoved, model, detail::DebugSlot{prefix, "rowsAboutToBeRemoved"}); 0112 QObject::connect(model, &QAbstractItemModel::rowsInserted, model, detail::DebugSlot{prefix, "rowsInserted"}); 0113 QObject::connect(model, &QAbstractItemModel::rowsMoved, model, detail::DebugSlot{prefix, "rowsMoved"}); 0114 QObject::connect(model, &QAbstractItemModel::rowsRemoved, model, detail::DebugSlot{prefix, "rowsRemoved"}); 0115 } 0116 0117 } // namespace app::debug