Version: 9.16.0
SUIT_TreeSync.h
Go to the documentation of this file.
1// Copyright (C) 2007-2026 CEA, EDF, 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
41template <class SrcItem, class TrgItem>
43{
44 SrcItem mySrc;
45 TrgItem myTrg;
46};
47
48
49//
50// Function prototypes.
51//
52
53template <class SrcItem, class TrgItem, class TreeData>
54TrgItem synchronize( const SrcItem&, const TrgItem&, const TreeData& );
55
56template <class SrcItem, class TrgItem, class TreeData>
58 const TrgItem&,
59 const TreeData& );
60
61template <class SrcItem, class TrgItem, class TreeData>
62TrgItem createSubTree( const SrcItem&, const TrgItem&, const TrgItem&, const TreeData& );
63
64template <class SrcItem, class TrgItem, class TreeData>
65const 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
117template <class SrcItem, class TrgItem, class TreeData>
118TrgItem 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 {
135#ifdef _DEBUG_
136 qDebug( "error: both null" );
137#endif
138 }
139 else
140 // delete item
141 td.deleteItemWithChildren( item.myTrg );
142 }
143 else {
144 if ( item.myTrg == td.nullTrg() ) {
145 // add item (recursively)
146 TrgItem nitem = createSubTree( item.mySrc, r2, lastItem, td );
147 if ( nitem != td.nullTrg() )
148 lastItem = nitem;
149 }
150 else {
151 // update item
152 synchronize( item.mySrc, item.myTrg, td );
153 lastItem = item.myTrg;
154 }
155 }
156 }
157 return r2;
158 }
159 else {
160 TrgItem new_r2 = td.nullTrg();
161 if ( r1 != td.nullSrc() ) {
162 // add new item (recursively)
163 new_r2 = createSubTree( r1, td.parent( r2 ), r2, td );
164 }
165 if ( r2 != td.nullTrg() ) {
166 // delete old one (if it is not null)
167 td.deleteItemWithChildren( r2 );
168 }
169 return new_r2;
170 }
171}
172
183template <class SrcItem, class TrgItem, class TreeData>
184const typename QList<TrgItem>::const_iterator findEqual( const SrcItem& it,
185 const typename QList<TrgItem>::const_iterator& first,
186 const typename QList<TrgItem>::const_iterator& last,
187 const TreeData& td )
188{
189 typename QList<TrgItem>::const_iterator cur = first;
190 for ( ; cur != last; cur++ ) {
191 if ( td.isEqual( it, *cur ) )
192 return cur;
193 }
194 return last;
195}
196
205template <class SrcItem, class TrgItem, class TreeData>
206QList< DiffItem<SrcItem,TrgItem> > diffSiblings( const SrcItem& src, const TrgItem& trg,
207 const TreeData& td )
208{
209 //if( src==td.nullSrc() || trg==td.nullTrg() )
210 // return;
211
213
214 QList<SrcItem> src_ch = td.children( src );
215 QList<TrgItem> trg_ch = td.children( trg );
216
217 typename QList<SrcItem>::const_iterator src_it = src_ch.begin(), src_last = src_ch.end();
218 typename QList<TrgItem>::const_iterator cur = trg_ch.begin(), trg_last = trg_ch.end();
219
220 for ( ; src_it != src_last; src_it++ ) {
222 findEqual<SrcItem, TrgItem, TreeData>( *src_it, cur, trg_last, td );
223 if ( f != trg_last ) {
224 // target is found
225 // mark all items before found one as "to be deleted"
226 for ( typename QList<TrgItem>::const_iterator it = cur; it != f; it++ ) {
228 ndiff.mySrc = td.nullSrc();
229 ndiff.myTrg = *it; // delete item
230 d.append( ndiff );
231 }
232 cur = f;
234 ndiff.mySrc = *src_it;
235 ndiff.myTrg = *cur; // update this (found) item
236 d.append( ndiff );
237 cur++;
238 }
239 else {
240 // target is not found
242 ndiff.mySrc = *src_it;
243 ndiff.myTrg = td.nullTrg(); // add item
244 d.append( ndiff );
245 }
246 }
247 // delete rest items
248 for ( ; cur != trg_last; cur++ ) {
250 ndiff.mySrc = td.nullSrc();
251 ndiff.myTrg = *cur; // delete item
252 d.append( ndiff );
253 }
254
255 return d;
256}
257
267template <class SrcItem, class TrgItem, class TreeData>
268TrgItem createSubTree( const SrcItem& src, const TrgItem& parent,
269 const TrgItem& after, const TreeData& td )
270{
271 if ( src == td.nullSrc() )
272 return td.nullTrg();
273
274 TrgItem nitem = td.createItem( src, parent, after );
275 if ( nitem == td.nullTrg() )
276 return nitem;
277
278 QList<SrcItem> ch = td.children( src );
279 typename QList<SrcItem>::const_iterator anIt = ch.begin(), aLast = ch.end();
280 TrgItem last = td.nullTrg();
281 for( ; anIt != aLast; anIt++ )
282 last = createSubTree( *anIt, nitem, last, td );
283
284 return nitem;
285}
286
287#endif // SUIT_TREESYNC_H
TrgItem synchronize(const SrcItem &, const TrgItem &, const TreeData &)
Synchronize two data trees by recurive comparing of the corresponding items.
Definition: SUIT_TreeSync.h:118
QList< DiffItem< SrcItem, TrgItem > > diffSiblings(const SrcItem &, const TrgItem &, const TreeData &)
Compare children of the source and target trees to find differences.
Definition: SUIT_TreeSync.h:206
const QList< TrgItem >::const_iterator findEqual(const SrcItem &it, const typename QList< TrgItem >::const_iterator &first, const typename QList< TrgItem >::const_iterator &last, const TreeData &td)
Find the item in the target tree which correspond to the specified source tree item.
Definition: SUIT_TreeSync.h:184
TrgItem createSubTree(const SrcItem &, const TrgItem &, const TrgItem &, const TreeData &)
Create an item with all its children recursively in the target tree.
Definition: SUIT_TreeSync.h:268
The structure representing difference between source and destination items.
Definition: SUIT_TreeSync.h:43
SrcItem mySrc
source tree item
Definition: SUIT_TreeSync.h:44
TrgItem myTrg
target tree item
Definition: SUIT_TreeSync.h:45