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