0029674: Improvements in Inspector tool
[occt.git] / tools / TreeModel / TreeModel_ItemBase.hxx
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
19 #include <Standard.hxx>
20 #include <Standard_Macro.hxx>
21 #include <inspector/TreeModel_ItemRole.hxx>
22
23 #include <Standard_WarningsDisable.hxx>
24 #include <QExplicitlySharedDataPointer>
25 #include <QHash>
26 #include <QMap>
27 #include <QModelIndex>
28 #include <QObject>
29 #include <QPair>
30 #include <QSharedData>
31 #include <QVariant>
32 #include <Standard_WarningsRestore.hxx>
33
34 class TreeModel_ItemBase;
35
36 typedef QExplicitlySharedDataPointer<TreeModel_ItemBase> TreeModel_ItemBasePtr;
37
38 //! \class TreeModel_ItemBase
39 //! \brief Declaration of an abstract interface of model item.
40 //!
41 //! The TreeModel_ItemBase class defines the standard interface that model items must use
42 //! to be able to provide the model information in the tree view architecture.
43 //! It is not supposed to be instantiated directly. Instead, you should subclass it to
44 //! create new items.
45 //!
46 //! The goal of the item is to be an data container of a custom model, based on the
47 //! QAbstractItemModel. It provides the items architecture in order to realize the model
48 //! functionality to find a parent model index by a child index and vise versa.
49 //!
50 //! The item should be created by the model and is saved in the internal pointer of the
51 //! QModelIndex. Only model knows when the index is removed/created. By this cause,
52 //! the item is wrapped in the QExplicitlySharedDataPointer. It is a counter on the pointer
53 //! and if there is no index that refers to the item, it is removed automatically. So,
54 //! there is no necessity to remove the item manually.
55 //!
56 //! The item knows a pointer to the parent item and its position into.
57 //! Some methods of the item should be realized to fill the item content.
58 //! These are: the children count, a child creation and a child data.
59 //!
60 //! The best way of the item using is to request the content of the item from some
61 //! information object without the caching it. But it can be very expensive realisation,
62 //! because method data, for example, is called by the viewer repaint, in other words,
63 //! constantly.
64 //!
65 //! It is possible to cache some information in the item. Do not give it throught the item
66 //! constructor. Realize method Init() to save the values in the item internal fields.
67 //! If the information model is changed, call Reset() for this item, or the item's parent.
68 //! It leads the item to non initialized state and by the next get of the item content,
69 //! call Init() method to fulfill the item content again.
70 class TreeModel_ItemBase : public QSharedData
71 {
72 public:
73
74   //! Destructor
75   virtual ~TreeModel_ItemBase() {}
76
77   //! Gets whether the item is already initialized.The initialized state is thrown down
78   //! by the reset method and get back after the method Init().
79   //!  \return if the item is initialized
80   bool IsInitialized() const { return m_bInitialized; }
81
82   //! Sets the item internal initialized state to the true. If the item has internal values,
83   //! there should be initialized here.
84   virtual void Init() { m_bInitialized = true; }
85
86   //! Resets the item and the child items content. Sets the initialized state to false.
87   //! If the item has internal values, there should be reseted here.
88   Standard_EXPORT virtual void Reset();
89
90   //! Resets the item cached value for the parameter role.
91   //! \param theRole an item role
92   Standard_EXPORT virtual void Reset(int theRole);
93
94   //! Gets the parent of the item, or TreeModel_ItemBasePtr() if it has no parent.
95   //! \return pointer to the item
96   TreeModel_ItemBasePtr Parent() const { return m_pParent; };
97
98   //! Gets the row of the item in the parent
99   //! \return the row position
100   int Row() const { return m_iRow; }
101
102   //! Gets the column of the item in the parent
103   //! \return the column position
104   int Column() const { return m_iColumn; }
105
106   //! Gets a child tree item in the given position. Find an item in the children hash.
107   //! Creates a new child item, if there is no a cached item in the given position and
108   //! if the flag about the creation is true.
109   //! \param theRow the row of the child item
110   //! \param theColumn the column of the child item
111   //! \param isToCreate the flag whether the item should be created if it is not created yet
112   //! \return the child item or TreeModel_ItemBasePtr() if it does not exist
113   Standard_EXPORT TreeModel_ItemBasePtr Child (int theRow, int theColumn, const bool isToCreate = true);
114
115   //! Sets a custom value for the role in an internal cache
116   //! \param theValue a value
117   //! \param theRole a value role
118   void SetCustomData(const QVariant theValue, int theRole) { myCachedValues.insert (theRole, theValue); }
119
120   //! Returns the data stored under the given role for the current item
121   //! \param theIndex the item model index
122   //! \param theRole the item model role
123   virtual QVariant data (const QModelIndex& theIndex, int theRole = Qt::DisplayRole) const
124   { (void)theIndex; return cachedValue(theRole); }
125
126   //! Returns number of rows where the children are
127   //! \return the row count
128   int rowCount() const { return cachedValue(TreeModel_ItemRole_RowCountRole).toInt(); }
129
130 protected:
131
132   //! \param theParent the parent item
133   //! \param theRow the item row positition in the parent item
134   //! \param theColumn the item column positition in the parent item
135   Standard_EXPORT TreeModel_ItemBase (TreeModel_ItemBasePtr theParent, const int theRow, const int theColumn);
136
137   //! Creates a child item in the given position.
138   //! \param theRow the child row position
139   //! \param theColumn the child column position
140   //! \return the created item
141   virtual TreeModel_ItemBasePtr createChild (int theRow, int theColumn) = 0;
142
143   //! Wraps the currrent item by shared pointer
144   //! \return the shared pointer to the current item
145   Standard_EXPORT const TreeModel_ItemBasePtr currentItem();
146
147   //! Returns the cached value for the role. Init the value if it is requested the first time
148   //! By default, it calls initRowCount(TreeModel_ItemRole_RowCountRole) or initValue for the item role
149   //! \param theItemRole a value role
150   //! \return the value
151   Standard_EXPORT QVariant cachedValue (const int theItemRole) const;
152
153   //! \return number of children. It should be reimplemented in child
154   virtual int initRowCount() const = 0;
155
156   //! Return data value for the role. It should be reimplemented in child
157   //! \param theItemRole a value role
158   //! \return the value
159   virtual QVariant initValue (const int theItemRole) const = 0;
160
161 private:
162
163   typedef QHash< QPair<int, int>, TreeModel_ItemBasePtr > PositionToItemHash;
164   PositionToItemHash m_ChildItems; //!< the hash of item children
165
166   QMap<int, QVariant> myCachedValues; //!< cached values, should be cleared by reset
167   TreeModel_ItemBasePtr m_pParent; //!< the parent item
168   int m_iRow;          //!< the item row position in the parent item
169   int m_iColumn;       //!< the item column position in the parent item
170   bool m_bInitialized; //!< the state whether the item content is already initialized
171 };
172
173 //! Returns an explicitly shared pointer to the pointer held by other, using a
174 //! dynamic cast to type X to obtain an internal pointer of the appropriate type.
175 //! If the dynamic_cast fails, the object returned will be null.
176 //! Example of using: 
177 //! TreeModel_ItemBase* aParent;
178 //! TreeModel_CustomItemPtr aParentItem = itemDynamicCast<TreeModel_CustomItem>(aParent);
179 //! \param theItem a source item
180 //! \return a converted item
181 template <class X, class T> QExplicitlySharedDataPointer<X> itemDynamicCast (const QExplicitlySharedDataPointer<T>& theItem)
182 {
183   X* ptr = dynamic_cast<X*> (theItem.data());
184
185   QExplicitlySharedDataPointer<X> result;
186   result = ptr;
187
188   return result;
189 }
190
191 #endif