Salome HOME
Copyright update 2022
[modules/gui.git] / src / SUIT / SUIT_DataObjectIterator.cxx
1 // Copyright (C) 2007-2022  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "SUIT_DataObjectIterator.h"
24
25 /*!
26   Constructor.
27 */
28 SUIT_DataObjectIterator::SUIT_DataObjectIterator( SUIT_DataObject* root, const int det, const bool fromTrueRoot )
29 : myRoot( root ),
30 myDetourType( det )
31 {
32   if ( myRoot && fromTrueRoot )
33     myRoot = myRoot->root();
34
35   myCurrent = myExtremeChild = myRoot;
36 }
37
38 /*!
39   Gets parent for object \a obj.
40 */
41 SUIT_DataObject* SUIT_DataObjectIterator::parent( SUIT_DataObject* obj ) const
42 {
43   SUIT_DataObject* result = 0;
44   if ( obj && obj != myRoot )
45     result = obj->parent();
46   return result;
47 }
48
49 /*!
50   Increment operator.
51 */
52 void SUIT_DataObjectIterator::operator++()
53 {
54   SUIT_DataObject* aNext = 0;
55   SUIT_DataObject* aParent = 0;
56
57   bool exit;
58
59   if ( myCurrent )
60   {
61     if ( myDetourType == DepthLeft || myDetourType == DepthRight )
62     {
63             //Depth detour algorithm
64       if ( myCurrent->myChildren.count() > 0 )
65       {
66         myCurrent = extreme( myCurrent->myChildren, myDetourType == DepthLeft );
67         myChildrenIndexes.append(myDetourType == DepthLeft ? 0 : myCurrent->myChildren.size() - 1);
68       }
69       else do
70       {
71         exit = false;
72         aParent = parent( myCurrent );
73         if ( !aParent )
74         {
75           myCurrent = 0; //the tree is passed completely
76           exit = true;
77         }
78         else
79         {
80           int idx = myChildrenIndexes.last();
81           if (myDetourType == DepthLeft && idx < aParent->myChildren.count() - 1) 
82           {
83             myChildrenIndexes.last()++;
84             myCurrent = aParent->myChildren[idx + 1];
85             exit = true;
86           }
87           else if (myDetourType == DepthRight && idx > 0) 
88           {
89             myChildrenIndexes.last()--;
90             myCurrent = aParent->myChildren[idx - 1];
91             exit = true;
92           } else {
93             myCurrent = aParent;
94             myChildrenIndexes.removeLast();
95           }
96         }
97       }
98       while ( !exit );
99     }
100     else if ( myDetourType == BreadthLeft || myDetourType == BreadthRight )
101     {
102       //Breadth detour algorithm
103       aNext = globalSibling( myCurrent, myDetourType == BreadthLeft );
104       if ( !aNext )
105       {
106         myCurrent = 0;
107         for ( SUIT_DataObject* cur = myExtremeChild; cur && !myCurrent; cur = globalSibling( cur, myDetourType == BreadthLeft ) )
108         {
109           if ( cur->myChildren.count() > 0 )
110           {
111             myExtremeChild = extreme( cur->myChildren, myDetourType == BreadthLeft );
112             myCurrent = myExtremeChild;
113             myChildrenIndexes.append(myDetourType == BreadthLeft ? 0 : myCurrent->myChildren.size() - 1);
114           }
115         }
116       }
117       else
118         myCurrent = aNext;
119     }
120   }
121 }
122
123 /*!
124   Gets current data object.
125 */
126 SUIT_DataObject* SUIT_DataObjectIterator::current() const
127 {
128   return myCurrent;
129 }
130
131 /*!
132   Gets depth of current lavel.
133 */
134 int SUIT_DataObjectIterator::depth() const
135 {
136   return myChildrenIndexes.size();
137 }
138
139 /*!
140   Gets detour type.
141 */
142 int SUIT_DataObjectIterator::detour() const
143 {
144   return myDetourType;
145 }
146
147 /*!
148   Gets global sibling for object \a obj
149 */
150 SUIT_DataObject* SUIT_DataObjectIterator::globalSibling( SUIT_DataObject* obj, bool next ) const
151 {
152   SUIT_DataObject* par;
153
154   if ( obj && ( par = parent( obj ) ) )
155   {
156     int idx = par->myChildren.indexOf( obj );
157     if ( idx < par->myChildren.count() - 1 )
158       return par->myChildren[idx + 1];
159     else
160     {
161       for ( ; par; par = globalSibling( par, next ) )
162       {
163         if ( par->myChildren.count() > 0 )
164           return extreme( par->myChildren, next );
165       }
166     }
167     return 0;
168   }
169   else
170     return 0;
171 }
172
173 /*!
174  * Gets first or last data object from list.
175  * Get firls, if \a FromLeft == true, else last.
176  */
177 SUIT_DataObject* SUIT_DataObjectIterator::extreme( DataObjectList& aList, bool FromLeft ) const
178 {
179   if ( FromLeft )
180     return aList.first();
181   else
182     return aList.last();
183 }
184
185 /*!
186   Constructor.
187 */
188 SUIT_DataObjectLevelIterator::SUIT_DataObjectLevelIterator( SUIT_DataObject* root,
189                                                             int start, int end, bool LeftToRight )
190 : SUIT_DataObjectIterator( root, LeftToRight ? BreadthLeft : BreadthRight )
191 {
192   myStartLevel = start;
193   if ( end > start )
194     myEndLevel = end;
195   else
196     myEndLevel = myStartLevel;
197
198   while ( current() && depth() < myStartLevel )
199     SUIT_DataObjectIterator::operator++();
200 }
201
202 /*!
203   Increment operator.
204 */
205 void SUIT_DataObjectLevelIterator::operator++()
206 {
207   if ( myCurrent )
208   {
209     SUIT_DataObjectIterator::operator++();
210     if ( depth() > myEndLevel )
211       myCurrent = 0;
212   }
213 }