1 /* 2 remotemodelserver.h 3 4 This file is part of GammaRay, the Qt application inspection and 5 manipulation tool. 6 7 Copyright (C) 2013-2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com 8 Author: Volker Krause <volker.krause@kdab.com> 9 10 Licensees holding valid commercial KDAB GammaRay licenses may use this file in 11 accordance with GammaRay Commercial License Agreement provided with the Software. 12 13 Contact info@kdab.com if any conditions of this licensing are not clear to you. 14 15 This program is free software; you can redistribute it and/or modify 16 it under the terms of the GNU General Public License as published by 17 the Free Software Foundation, either version 2 of the License, or 18 (at your option) any later version. 19 20 This program is distributed in the hope that it will be useful, 21 but WITHOUT ANY WARRANTY; without even the implied warranty of 22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 GNU General Public License for more details. 24 25 You should have received a copy of the GNU General Public License 26 along with this program. If not, see <http://www.gnu.org/licenses/>. 27 */ 28 29 #ifndef GAMMARAY_REMOTEMODELSERVER_H 30 #define GAMMARAY_REMOTEMODELSERVER_H 31 32 #include <common/protocol.h> 33 34 #include <QObject> 35 #include <QPointer> 36 #include <QRegExp> 37 38 QT_BEGIN_NAMESPACE 39 class QBuffer; 40 class QAbstractItemModel; 41 QT_END_NAMESPACE 42 43 namespace GammaRay { 44 class Message; 45 46 /** Provides the server-side interface for a QAbstractItemModel to be used from a separate process. 47 * If the source model is a QSortFilterProxyModel, this also forwards properties for configuring 48 * the proxy behavior, enabling server-side searching and sorting. 49 */ 50 class RemoteModelServer : public QObject 51 { 52 Q_OBJECT 53 Q_PROPERTY(bool dynamicSortFilter READ proxyDynamicSortFilter WRITE setProxyDynamicSortFilter) 54 Q_PROPERTY( 55 Qt::CaseSensitivity filterCaseSensitivity READ proxyFilterCaseSensitivity WRITE setProxyFilterCaseSensitivity) 56 Q_PROPERTY(int filterKeyColumn READ proxyFilterKeyColumn WRITE setProxyFilterKeyColumn) 57 Q_PROPERTY(QRegExp filterRegExp READ proxyFilterRegExp WRITE setProxyFilterRegExp) 58 59 public: 60 /** Registers a new model server object with name @p objectName (must be unique). */ 61 explicit RemoteModelServer(const QString &objectName, QObject *parent = nullptr); 62 ~RemoteModelServer() override; 63 64 /** Returns the source model. */ 65 QAbstractItemModel *model() const; 66 /** Set the source model for this model server instance. */ 67 void setModel(QAbstractItemModel *model); 68 69 public slots: 70 void newRequest(const GammaRay::Message &msg); 71 /** Notifications about an object on the client side (un)monitoring this object. 72 * If no one is watching, we don't send out any change notification to reduce network traffice. 73 */ 74 void modelMonitored(bool monitored = false); 75 76 private: 77 void connectModel(); 78 void disconnectModel(); 79 void sendAddRemoveMessage(Protocol::MessageType type, const QModelIndex &parent, int start, 80 int end); 81 void sendMoveMessage(Protocol::MessageType type, const Protocol::ModelIndex &sourceParent, 82 int sourceStart, int sourceEnd, 83 const Protocol::ModelIndex &destinationParent, int destinationIndex); 84 QMap< int, QVariant > filterItemData(QMap<int, QVariant> &&itemData) const; 85 void sendLayoutChanged( 86 const QVector<Protocol::ModelIndex> &parents = QVector<Protocol::ModelIndex>(), 87 quint32 hint = 0); 88 bool canSerialize(const QVariant &value) const; 89 90 // proxy model settings 91 bool proxyDynamicSortFilter() const; 92 void setProxyDynamicSortFilter(bool dynamicSortFilter); 93 Qt::CaseSensitivity proxyFilterCaseSensitivity() const; 94 void setProxyFilterCaseSensitivity(Qt::CaseSensitivity caseSensitivity); 95 int proxyFilterKeyColumn() const; 96 void setProxyFilterKeyColumn(int column); 97 QRegExp proxyFilterRegExp() const; 98 void setProxyFilterRegExp(const QRegExp ®Exp); 99 100 // unit test hooks 101 static void (*s_registerServerCallback)(); 102 void registerServer(); 103 virtual bool isConnected() const; 104 virtual void sendMessage(const Message &msg) const; 105 friend class FakeRemoteModelServer; 106 107 private slots: 108 void dataChanged(const QModelIndex &begin, const QModelIndex &end, 109 const QVector<int> &roles = QVector<int>()); 110 void headerDataChanged(Qt::Orientation orientation, int first, int last); 111 void rowsInserted(const QModelIndex &parent, int start, int end); 112 void rowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, 113 const QModelIndex &destinationParent, int destinationRow); 114 void rowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, 115 const QModelIndex &destinationParent, int destinationRow); 116 void rowsRemoved(const QModelIndex &parent, int start, int end); 117 void columnsInserted(const QModelIndex &parent, int start, int end); 118 void columnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, 119 const QModelIndex &destinationParent, int destinationColumn); 120 void columnsRemoved(const QModelIndex &parent, int start, int end); 121 void layoutChanged(const QList<QPersistentModelIndex> &parents, 122 QAbstractItemModel::LayoutChangeHint hint); 123 124 void modelReset(); 125 126 void modelDeleted(); 127 128 private: 129 QPointer<QAbstractItemModel> m_model; 130 // those two are used for canSerialize, since recreating the QBuffer is somewhat expensive, 131 // especially since being a QObject triggers all kind of GammaRay internals 132 QByteArray m_dummyData; 133 QBuffer *m_dummyBuffer; 134 // converted model indexes from aboutToBeX signals, needed in cases where the operation changes 135 // the serialized index (move to sub-tree of source parent for example) 136 // as operations can occur nested, we need to have a stack for this 137 QList<Protocol::ModelIndex> m_preOpIndexes; 138 Protocol::ObjectAddress m_myAddress; 139 bool m_monitored; 140 }; 141 } 142 143 #endif 144