Version: 8.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
SUIT_TreeSync.h
Go to the documentation of this file.
1 // Copyright (C) 2007-2016 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 // File : SUIT_TreeSync.h
24 // Author : Alexander SOLOVYOV
25 //
26 #ifndef SUIT_TREESYNC_H
27 #define SUIT_TREESYNC_H
28 
29 #include <QList>
30 
41 template <class SrcItem, class TrgItem>
42 struct DiffItem
43 {
44  SrcItem mySrc;
45  TrgItem myTrg;
46 };
47 
48 
49 //
50 // Function prototypes.
51 //
52 
53 template <class SrcItem, class TrgItem, class TreeData>
54 TrgItem synchronize( const SrcItem&, const TrgItem&, const TreeData& );
55 
56 template <class SrcItem, class TrgItem, class TreeData>
58  const TrgItem&,
59  const TreeData& );
60 
61 template <class SrcItem, class TrgItem, class TreeData>
62 TrgItem createSubTree( const SrcItem&, const TrgItem&, const TrgItem&, const TreeData& );
63 
64 template <class SrcItem, class TrgItem, class TreeData>
65 const typename QList<TrgItem>::const_iterator findEqual( const SrcItem& it,
66  const typename QList<TrgItem>::const_iterator& first,
67  const typename QList<TrgItem>::const_iterator& last,
68  const TreeData& td );
69 
70 
71 //
72 // Function imlpementation.
73 //
74 
117 template <class SrcItem, class TrgItem, class TreeData>
118 TrgItem synchronize( const SrcItem& r1, const TrgItem& r2, const TreeData& td )
119 {
120  if ( td.isEqual( r1, r2 ) ) {
121  // update items themselves
122  td.updateItem( r1, r2 );
123 
124  // iterate through children
126 
127  typename QList< DiffItem< SrcItem, TrgItem > >::const_iterator anIt = d.begin(), aLast = d.end();
128  TrgItem lastItem = td.nullTrg();
129 
130  for ( ; anIt != aLast; anIt++ ) {
131  const DiffItem<SrcItem,TrgItem>& item = *anIt;
132  if ( item.mySrc == td.nullSrc() ) {
133  if ( item.myTrg == td.nullTrg() )
134  qDebug( "error: both null" );
135  else
136  // delete item
137  td.deleteItemWithChildren( item.myTrg );
138  }
139  else {
140  if ( item.myTrg == td.nullTrg() ) {
141  // add item (recursively)
142  TrgItem nitem = createSubTree( item.mySrc, r2, lastItem, td );
143  if ( nitem != td.nullTrg() )
144  lastItem = nitem;
145  }
146  else {
147  // update item
148  synchronize( item.mySrc, item.myTrg, td );
149  lastItem = item.myTrg;
150  }
151  }
152  }
153  return r2;
154  }
155  else {
156  TrgItem new_r2 = td.nullTrg();
157  if ( r1 != td.nullSrc() ) {
158  // add new item (recursively)
159  new_r2 = createSubTree( r1, td.parent( r2 ), r2, td );
160  }
161  if ( r2 != td.nullTrg() ) {
162  // delete old one (if it is not null)
163  td.deleteItemWithChildren( r2 );
164  }
165  return new_r2;
166  }
167 }
168 
179 template <class SrcItem, class TrgItem, class TreeData>
180 const typename QList<TrgItem>::const_iterator findEqual( const SrcItem& it,
181  const typename QList<TrgItem>::const_iterator& first,
182  const typename QList<TrgItem>::const_iterator& last,
183  const TreeData& td )
184 {
185  typename QList<TrgItem>::const_iterator cur = first;
186  for ( ; cur != last; cur++ ) {
187  if ( td.isEqual( it, *cur ) )
188  return cur;
189  }
190  return last;
191 }
192 
201 template <class SrcItem, class TrgItem, class TreeData>
202 QList< DiffItem<SrcItem,TrgItem> > diffSiblings( const SrcItem& src, const TrgItem& trg,
203  const TreeData& td )
204 {
205  //if( src==td.nullSrc() || trg==td.nullTrg() )
206  // return;
207 
209 
210  QList<SrcItem> src_ch = td.children( src );
211  QList<TrgItem> trg_ch = td.children( trg );
212 
213  typename QList<SrcItem>::const_iterator src_it = src_ch.begin(), src_last = src_ch.end();
214  typename QList<TrgItem>::const_iterator cur = trg_ch.begin(), trg_last = trg_ch.end();
215 
216  for ( ; src_it != src_last; src_it++ ) {
217  typename QList<TrgItem>::const_iterator f =
218  findEqual<SrcItem, TrgItem, TreeData>( *src_it, cur, trg_last, td );
219  if ( f != trg_last ) {
220  // target is found
221  // mark all items before found one as "to be deleted"
222  for ( typename QList<TrgItem>::const_iterator it = cur; it != f; it++ ) {
224  ndiff.mySrc = td.nullSrc();
225  ndiff.myTrg = *it; // delete item
226  d.append( ndiff );
227  }
228  cur = f;
230  ndiff.mySrc = *src_it;
231  ndiff.myTrg = *cur; // update this (found) item
232  d.append( ndiff );
233  cur++;
234  }
235  else {
236  // target is not found
238  ndiff.mySrc = *src_it;
239  ndiff.myTrg = td.nullTrg(); // add item
240  d.append( ndiff );
241  }
242  }
243  // delete rest items
244  for ( ; cur != trg_last; cur++ ) {
246  ndiff.mySrc = td.nullSrc();
247  ndiff.myTrg = *cur; // delete item
248  d.append( ndiff );
249  }
250 
251  return d;
252 }
253 
263 template <class SrcItem, class TrgItem, class TreeData>
264 TrgItem createSubTree( const SrcItem& src, const TrgItem& parent,
265  const TrgItem& after, const TreeData& td )
266 {
267  if ( src == td.nullSrc() )
268  return td.nullTrg();
269 
270  TrgItem nitem = td.createItem( src, parent, after );
271  if ( nitem == td.nullTrg() )
272  return nitem;
273 
274  QList<SrcItem> ch = td.children( src );
275  typename QList<SrcItem>::const_iterator anIt = ch.begin(), aLast = ch.end();
276  TrgItem last = td.nullTrg();
277  for( ; anIt != aLast; anIt++ )
278  last = createSubTree( *anIt, nitem, last, td );
279 
280  return nitem;
281 }
282 
283 #endif // SUIT_TREESYNC_H