14bbbdcb |
1 | // Created on: 2017-06-16 |
2 | // Created by: Natalia ERMOLAEVA |
3 | // Copyright (c) 2017 OPEN CASCADE SAS |
4 | // |
5 | // This file is part of Open CASCADE Technology software library. |
6 | // |
7 | // This library is free software; you can redistribute it and/or modify it under |
8 | // the terms of the GNU Lesser General Public License version 2.1 as published |
9 | // by the Free Software Foundation, with special exception defined in the file |
10 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
11 | // distribution for complete text of the license and disclaimer of any warranty. |
12 | // |
13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. |
15 | |
16 | #ifndef TreeModel_ItemBase_H |
17 | #define TreeModel_ItemBase_H |
18 | |
6b63dc83 |
19 | #include <NCollection_List.hxx> |
14bbbdcb |
20 | #include <Standard.hxx> |
21 | #include <Standard_Macro.hxx> |
7e1c1e48 |
22 | #include <Standard_Handle.hxx> |
23 | #include <Standard_OStream.hxx> |
24 | #include <Standard_SStream.hxx> |
25 | |
0cb512c0 |
26 | #include <inspector/TreeModel_ItemRole.hxx> |
14bbbdcb |
27 | |
130eb114 |
28 | #include <Standard_WarningsDisable.hxx> |
14bbbdcb |
29 | #include <QExplicitlySharedDataPointer> |
30 | #include <QHash> |
31 | #include <QMap> |
32 | #include <QModelIndex> |
33 | #include <QObject> |
34 | #include <QPair> |
35 | #include <QSharedData> |
36 | #include <QVariant> |
130eb114 |
37 | #include <Standard_WarningsRestore.hxx> |
14bbbdcb |
38 | |
39 | class TreeModel_ItemBase; |
7e1c1e48 |
40 | class TreeModel_ItemProperties; |
14bbbdcb |
41 | |
42 | typedef QExplicitlySharedDataPointer<TreeModel_ItemBase> TreeModel_ItemBasePtr; |
43 | |
44 | //! \class TreeModel_ItemBase |
45 | //! \brief Declaration of an abstract interface of model item. |
46 | //! |
47 | //! The TreeModel_ItemBase class defines the standard interface that model items must use |
48 | //! to be able to provide the model information in the tree view architecture. |
49 | //! It is not supposed to be instantiated directly. Instead, you should subclass it to |
50 | //! create new items. |
51 | //! |
52 | //! The goal of the item is to be an data container of a custom model, based on the |
53 | //! QAbstractItemModel. It provides the items architecture in order to realize the model |
54 | //! functionality to find a parent model index by a child index and vise versa. |
55 | //! |
56 | //! The item should be created by the model and is saved in the internal pointer of the |
57 | //! QModelIndex. Only model knows when the index is removed/created. By this cause, |
58 | //! the item is wrapped in the QExplicitlySharedDataPointer. It is a counter on the pointer |
59 | //! and if there is no index that refers to the item, it is removed automatically. So, |
60 | //! there is no necessity to remove the item manually. |
61 | //! |
62 | //! The item knows a pointer to the parent item and its position into. |
63 | //! Some methods of the item should be realized to fill the item content. |
64 | //! These are: the children count, a child creation and a child data. |
65 | //! |
66 | //! The best way of the item using is to request the content of the item from some |
67 | //! information object without the caching it. But it can be very expensive realisation, |
68 | //! because method data, for example, is called by the viewer repaint, in other words, |
69 | //! constantly. |
70 | //! |
71 | //! It is possible to cache some information in the item. Do not give it throught the item |
72 | //! constructor. Realize method Init() to save the values in the item internal fields. |
73 | //! If the information model is changed, call Reset() for this item, or the item's parent. |
74 | //! It leads the item to non initialized state and by the next get of the item content, |
75 | //! call Init() method to fulfill the item content again. |
76 | class TreeModel_ItemBase : public QSharedData |
77 | { |
78 | public: |
79 | |
80 | //! Destructor |
81 | virtual ~TreeModel_ItemBase() {} |
82 | |
83 | //! Gets whether the item is already initialized.The initialized state is thrown down |
84 | //! by the reset method and get back after the method Init(). |
85 | //! \return if the item is initialized |
86 | bool IsInitialized() const { return m_bInitialized; } |
87 | |
88 | //! Sets the item internal initialized state to the true. If the item has internal values, |
89 | //! there should be initialized here. |
7e1c1e48 |
90 | Standard_EXPORT virtual void Init(); |
91 | |
92 | //! Returns data object of the item. |
93 | //! \return object |
94 | Standard_EXPORT virtual const Handle(Standard_Transient)& Object() const; |
14bbbdcb |
95 | |
96 | //! Resets the item and the child items content. Sets the initialized state to false. |
97 | //! If the item has internal values, there should be reseted here. |
98 | Standard_EXPORT virtual void Reset(); |
99 | |
6822a3be |
100 | //! Resets the item cached value for the parameter role. |
101 | //! \param theRole an item role |
102 | Standard_EXPORT virtual void Reset(int theRole); |
103 | |
7e1c1e48 |
104 | //! Returns stream value of the item to fulfill property panel. |
105 | //! \return stream value or dummy |
106 | const Standard_SStream& Stream() const { return myStream; } |
107 | |
108 | //! Returns stream value of the item to fulfill property panel. |
109 | //! \return stream value or dummy |
110 | virtual bool SetStream (const Standard_SStream& theSStream, Standard_Integer& theStartPos, |
111 | Standard_Integer& theLastPos) const |
112 | { (void)theSStream; (void)theStartPos; (void)theLastPos; return false; } |
113 | |
14bbbdcb |
114 | //! Gets the parent of the item, or TreeModel_ItemBasePtr() if it has no parent. |
115 | //! \return pointer to the item |
116 | TreeModel_ItemBasePtr Parent() const { return m_pParent; }; |
117 | |
118 | //! Gets the row of the item in the parent |
119 | //! \return the row position |
120 | int Row() const { return m_iRow; } |
121 | |
122 | //! Gets the column of the item in the parent |
123 | //! \return the column position |
124 | int Column() const { return m_iColumn; } |
125 | |
126 | //! Gets a child tree item in the given position. Find an item in the children hash. |
127 | //! Creates a new child item, if there is no a cached item in the given position and |
128 | //! if the flag about the creation is true. |
129 | //! \param theRow the row of the child item |
130 | //! \param theColumn the column of the child item |
131 | //! \param isToCreate the flag whether the item should be created if it is not created yet |
132 | //! \return the child item or TreeModel_ItemBasePtr() if it does not exist |
133 | Standard_EXPORT TreeModel_ItemBasePtr Child (int theRow, int theColumn, const bool isToCreate = true); |
134 | |
6822a3be |
135 | //! Sets a custom value for the role in an internal cache |
136 | //! \param theValue a value |
137 | //! \param theRole a value role |
7e1c1e48 |
138 | void SetCustomData(const QVariant& theValue, int theRole) { myCachedValues.insert (theRole, theValue); } |
6822a3be |
139 | |
14bbbdcb |
140 | //! Returns the data stored under the given role for the current item |
141 | //! \param theIndex the item model index |
142 | //! \param theRole the item model role |
143 | virtual QVariant data (const QModelIndex& theIndex, int theRole = Qt::DisplayRole) const |
144 | { (void)theIndex; return cachedValue(theRole); } |
145 | |
146 | //! Returns number of rows where the children are |
147 | //! \return the row count |
148 | int rowCount() const { return cachedValue(TreeModel_ItemRole_RowCountRole).toInt(); } |
149 | |
7e1c1e48 |
150 | //! Returns the item properties |
151 | const Handle(TreeModel_ItemProperties)& Properties() const { return myProperties; } |
152 | |
6b63dc83 |
153 | Standard_EXPORT virtual void Presentations (NCollection_List<Handle(Standard_Transient)>& thePresentations); |
14bbbdcb |
154 | protected: |
155 | |
156 | //! \param theParent the parent item |
7e1c1e48 |
157 | //! \param theRow the item row position in the parent item |
158 | //! \param theColumn the item column position in the parent item |
14bbbdcb |
159 | Standard_EXPORT TreeModel_ItemBase (TreeModel_ItemBasePtr theParent, const int theRow, const int theColumn); |
160 | |
7e1c1e48 |
161 | //! Initializes the current item. It creates a backup of the specific item information |
162 | virtual void initItem() const {} |
163 | |
14bbbdcb |
164 | //! Creates a child item in the given position. |
165 | //! \param theRow the child row position |
166 | //! \param theColumn the child column position |
167 | //! \return the created item |
7e1c1e48 |
168 | virtual TreeModel_ItemBasePtr createChild (int theRow, int theColumn) |
169 | { (void)theRow; (void)theColumn; return TreeModel_ItemBasePtr(); } |
14bbbdcb |
170 | |
171 | //! Wraps the currrent item by shared pointer |
172 | //! \return the shared pointer to the current item |
173 | Standard_EXPORT const TreeModel_ItemBasePtr currentItem(); |
174 | |
175 | //! Returns the cached value for the role. Init the value if it is requested the first time |
176 | //! By default, it calls initRowCount(TreeModel_ItemRole_RowCountRole) or initValue for the item role |
177 | //! \param theItemRole a value role |
178 | //! \return the value |
179 | Standard_EXPORT QVariant cachedValue (const int theItemRole) const; |
180 | |
181 | //! \return number of children. It should be reimplemented in child |
182 | virtual int initRowCount() const = 0; |
183 | |
7e1c1e48 |
184 | //! \return number of children. It should be reimplemented in child |
185 | Standard_EXPORT int initStreamRowCount(); |
186 | |
187 | //! Returns data value for the role. It should be reimplemented in child |
14bbbdcb |
188 | //! \param theItemRole a value role |
189 | //! \return the value |
7e1c1e48 |
190 | Standard_EXPORT virtual QVariant initValue (const int theItemRole) const; |
191 | |
192 | //! Returns stream value of the item to fulfill property panel. |
193 | //! \return stream value or dummy |
194 | virtual void initStream (Standard_OStream& theOStream) const { (void)theOStream; } |
195 | |
196 | protected: |
197 | Handle(TreeModel_ItemProperties) myProperties; //!< the properties |
198 | int m_iStreamChildren; //!< the count of stream items |
199 | Standard_SStream myStream; //!< stream value |
14bbbdcb |
200 | |
201 | private: |
202 | |
203 | typedef QHash< QPair<int, int>, TreeModel_ItemBasePtr > PositionToItemHash; |
204 | PositionToItemHash m_ChildItems; //!< the hash of item children |
205 | |
7e1c1e48 |
206 | mutable QMap<int, QVariant> myCachedValues; //!< cached values, should be cleared by reset |
14bbbdcb |
207 | TreeModel_ItemBasePtr m_pParent; //!< the parent item |
208 | int m_iRow; //!< the item row position in the parent item |
209 | int m_iColumn; //!< the item column position in the parent item |
210 | bool m_bInitialized; //!< the state whether the item content is already initialized |
211 | }; |
212 | |
213 | //! Returns an explicitly shared pointer to the pointer held by other, using a |
214 | //! dynamic cast to type X to obtain an internal pointer of the appropriate type. |
215 | //! If the dynamic_cast fails, the object returned will be null. |
216 | //! Example of using: |
217 | //! TreeModel_ItemBase* aParent; |
218 | //! TreeModel_CustomItemPtr aParentItem = itemDynamicCast<TreeModel_CustomItem>(aParent); |
219 | //! \param theItem a source item |
220 | //! \return a converted item |
221 | template <class X, class T> QExplicitlySharedDataPointer<X> itemDynamicCast (const QExplicitlySharedDataPointer<T>& theItem) |
222 | { |
223 | X* ptr = dynamic_cast<X*> (theItem.data()); |
224 | |
225 | QExplicitlySharedDataPointer<X> result; |
226 | result = ptr; |
227 | |
228 | return result; |
229 | } |
230 | |
231 | #endif |