File: elementcontainermodel.h

package info (click to toggle)
scram 0.16.2-4
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 8,016 kB
  • sloc: xml: 120,766; cpp: 23,966; python: 1,256; ansic: 100; makefile: 9
file content (216 lines) | stat: -rw-r--r-- 7,174 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
/*
 * Copyright (C) 2017-2018 Olzhas Rakhimov
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, 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 General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/// @file
/// The table model for elements.

#pragma once

#include <cstdint>

#include <unordered_map>
#include <vector>

#include <QAbstractItemModel>
#include <QSortFilterProxyModel>

#include "src/element.h"
#include "src/event.h"

#include "model.h"

namespace scram::gui::model {

/// The base class for models to list elements in a table.
///
/// The model contains the original element pointer for Qt::UserRole.
/// This only applies to top-level indices.
class ElementContainerModel : public QAbstractItemModel
{
    Q_OBJECT

public:
    /// @param[in] parent  The top index (i.e., not valid).
    ///
    /// @returns The number of elements in the list as the row count.
    int rowCount(const QModelIndex &parent) const override;

protected:
    /// @tparam T  The container type of smart pointers to elements.
    ///
    /// @param[in] container  The data container.
    /// @param[in] model  The model managing the proxy Elements.
    /// @param[in,out] parent  The optional owner of this object.
    template <class T>
    explicit ElementContainerModel(const T &container, Model *model,
                                   QObject *parent = nullptr);

    /// Puts the element pointer into the index's internal pointer.
    QModelIndex index(int row, int column,
                      const QModelIndex &parent) const override;

    /// Assumes the table-layout and returns null index.
    QModelIndex parent(const QModelIndex &) const override { return {}; }

    /// @param[in] index  The top row index in this container model.
    ///
    /// @returns The element with the given index (row).
    ///
    /// @pre The index is valid.
    Element *getElement(int index) const;

    /// @param[in] element  The element in this container model.
    ///
    /// @returns The current index (row) of the element.
    ///
    /// @pre The element is in the table.
    int getElementIndex(Element *element) const;

    /// @returns The current elements in the container.
    const std::vector<Element *> &elements() const { return m_elements; }

protected:
    /// Connects of the element change signals to the table modification.
    /// The base implementation only handles signals coming from base element.
    /// The derived classes need to override this function
    /// and append more connections.
    ///
    /// @param[in] element  The element in this container model.
    virtual void connectElement(Element *element);

private:
    /// Adds an elements to the end of this container model.
    void addElement(Element *element);
    /// Removes an element from the container model.
    void removeElement(Element *element);

    std::vector<Element *> m_elements; ///< All the elements in the model.
    std::unordered_map<Element *, int> m_elementToIndex; ///< An element to row.
};

/// The proxy model allows sorting and filtering.
class SortFilterProxyModel : public QSortFilterProxyModel
{
    Q_OBJECT

public:
    using QSortFilterProxyModel::QSortFilterProxyModel;

    /// Keep the row indices sequential.
    QVariant headerData(int section, Qt::Orientation orientation,
                        int role) const override
    {
        return sourceModel()->headerData(section, orientation, role);
    }
};

/// Container model for basic events.
class BasicEventContainerModel : public ElementContainerModel
{
    Q_OBJECT

public:
    using ItemModel = BasicEvent;     ///< The proxy Element type.
    using DataType = mef::BasicEvent; ///< The data Element type.

    /// Constructs from the table of proxy Basic Events in the Model.
    explicit BasicEventContainerModel(Model *model, QObject *parent = nullptr);

    /// Required standard member functions of QAbstractItemModel interface.
    /// @{
    int columnCount(const QModelIndex &parent) const override;
    QVariant headerData(int section, Qt::Orientation orientation,
                        int role) const override;
    QVariant data(const QModelIndex &index, int role) const override;
    /// @}

private:
    void connectElement(Element *element) final;
};

/// Container model for house events.
class HouseEventContainerModel : public ElementContainerModel
{
    Q_OBJECT

public:
    using ItemModel = HouseEvent;     ///< The proxy Element type.
    using DataType = mef::HouseEvent; ///< The data Element type.

    /// Constructs from the table of proxy House Events in the Model.
    explicit HouseEventContainerModel(Model *model, QObject *parent = nullptr);

    /// Required standard member functions of QAbstractItemModel interface.
    /// @{
    int columnCount(const QModelIndex &parent) const override;
    QVariant headerData(int section, Qt::Orientation orientation,
                        int role) const override;
    QVariant data(const QModelIndex &index, int role) const override;
    /// @}

private:
    void connectElement(Element *element) final;
};

/// Tree-view inside table.
class GateContainerModel : public ElementContainerModel
{
    Q_OBJECT

public:
    using ItemModel = Gate;     ///< The proxy Element type.
    using DataType = mef::Gate; ///< The data Element type.

    /// Constructs from the table of proxy Gates in the Model.
    explicit GateContainerModel(Model *model, QObject *parent = nullptr);

    /// The index for children embeds the parent information into the data.
    /// @{
    QModelIndex index(int row, int column,
                      const QModelIndex &parent) const override;
    int columnCount(const QModelIndex &parent) const override;
    int rowCount(const QModelIndex &parent) const override;
    QModelIndex parent(const QModelIndex &index) const override;
    QVariant headerData(int section, Qt::Orientation orientation,
                        int role) const override;
    QVariant data(const QModelIndex &index, int role) const override;
    /// @}

private:
    static const std::uintptr_t m_parentMask = 1; ///< Tagged parent pointer.

    void connectElement(Element *element) final;
};

/// The proxy model specialized for the gate tree-table.
class GateSortFilterProxyModel : public QSortFilterProxyModel
{
    Q_OBJECT

public:
    using QSortFilterProxyModel::QSortFilterProxyModel;

protected:
    /// Accepts only top elements for sorting and filtering.
    /// @{
    bool filterAcceptsRow(int row, const QModelIndex &parent) const override;
    bool lessThan(const QModelIndex &lhs,
                  const QModelIndex &rhs) const override;
    /// @}
};

} // namespace scram::gui::model