Salome HOME
Update from BR_V5_DEV 13Feb2009
[modules/gui.git] / src / SUIT / SUIT_DataObjectIterator.cxx
1 //  Copyright (C) 2007-2008  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.
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 #include "SUIT_DataObjectIterator.h"
23
24 /*!
25   Constructor.
26 */
27 SUIT_DataObjectIterator::SUIT_DataObjectIterator( SUIT_DataObject* root, const int det, const bool fromTrueRoot )
28 : myRoot( root ),
29 myDetourType( det ),
30 myCurrentLevel( 0 )
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         myCurrentLevel++;
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 = aParent->myChildren.indexOf( myCurrent );
81           if ( myDetourType == DepthLeft )
82             myCurrent = idx < aParent->myChildren.count() - 1 ? aParent->myChildren[idx + 1] : 0;
83           else
84             myCurrent = idx > 0 ? aParent->myChildren[idx - 1] : 0;
85           if ( !myCurrent )
86           {
87             myCurrent = aParent;
88             myCurrentLevel--;
89           }
90           else
91             exit = true;
92         }
93       }
94       while ( !exit );
95     }
96     else if ( myDetourType == BreadthLeft || myDetourType == BreadthRight )
97     {
98       //Breadth detour algorithm
99       aNext = globalSibling( myCurrent, myDetourType == BreadthLeft );
100       if ( !aNext )
101       {
102         myCurrent = 0;
103         for ( SUIT_DataObject* cur = myExtremeChild; cur && !myCurrent; cur = globalSibling( cur, myDetourType == BreadthLeft ) )
104         {
105           if ( cur->myChildren.count() > 0 )
106           {
107             myExtremeChild = extreme( cur->myChildren, myDetourType == BreadthLeft );
108             myCurrent = myExtremeChild;
109             myCurrentLevel++;
110           }
111         }
112       }
113       else
114         myCurrent = aNext;
115     }
116   }
117 }
118
119 /*!
120   Gets current data object.
121 */
122 SUIT_DataObject* SUIT_DataObjectIterator::current() const
123 {
124   return myCurrent;
125 }
126
127 /*!
128   Gets depth of current lavel.
129 */
130 int SUIT_DataObjectIterator::depth() const
131 {
132   return myCurrentLevel;
133 }
134
135 /*!
136   Gets detour type.
137 */
138 int SUIT_DataObjectIterator::detour() const
139 {
140   return myDetourType;
141 }
142
143 /*!
144   Gets global sibling for object \a obj
145 */
146 SUIT_DataObject* SUIT_DataObjectIterator::globalSibling( SUIT_DataObject* obj, bool next ) const
147 {
148   SUIT_DataObject* par;
149
150   if ( obj && ( par = parent( obj ) ) )
151   {
152     int idx = par->myChildren.indexOf( obj );
153     if ( idx < par->myChildren.count() - 1 )
154       return par->myChildren[idx + 1];
155     else
156     {
157       for ( ; par; par = globalSibling( par, next ) )
158       {
159         if ( par->myChildren.count() > 0 )
160           return extreme( par->myChildren, next );
161       }
162     }
163     return 0;
164   }
165   else
166     return 0;
167 }
168
169 /*!
170  * Gets first or last data object from list.
171  * Get firls, if \a FromLeft == true, else last.
172  */
173 SUIT_DataObject* SUIT_DataObjectIterator::extreme( DataObjectList& aList, bool FromLeft ) const
174 {
175   if ( FromLeft )
176     return aList.first();
177   else
178     return aList.last();
179 }
180
181 /*!
182   Constructor.
183 */
184 SUIT_DataObjectLevelIterator::SUIT_DataObjectLevelIterator( SUIT_DataObject* root,
185                                                             int start, int end, bool LeftToRight )
186 : SUIT_DataObjectIterator( root, LeftToRight ? BreadthLeft : BreadthRight )
187 {
188   myStartLevel = start;
189   if ( end > start )
190     myEndLevel = end;
191   else
192     myEndLevel = myStartLevel;
193
194   while ( current() && depth() < myStartLevel )
195     SUIT_DataObjectIterator::operator++();
196 }
197
198 /*!
199   Increment operator.
200 */
201 void SUIT_DataObjectLevelIterator::operator++()
202 {
203   if ( myCurrent )
204   {
205     SUIT_DataObjectIterator::operator++();
206     if ( depth() > myEndLevel )
207       myCurrent = 0;
208   }
209 }