Salome HOME
Delition of objects (Feature #90).
[modules/hydro.git] / src / HYDROData / HYDROData_Entity.cxx
1
2 #include "HYDROData_Entity.h"
3
4 #include "HYDROData_Iterator.h"
5
6 #include <TDataStd_Name.hxx>
7 #include <TDataStd_ByteArray.hxx>
8 #include <TDataStd_UAttribute.hxx>
9 #include <TDataStd_IntegerArray.hxx>
10 #include <TDataStd_BooleanArray.hxx>
11 #include <TDataStd_RealArray.hxx>
12 #include <TDataStd_ReferenceList.hxx>
13
14 #include <TDF_CopyLabel.hxx>
15 #include <TDF_ListIteratorOfLabelList.hxx>
16
17 #include <QColor>
18 #include <QString>
19 #include <QStringList>
20 #include <QVariant>
21
22 static const Standard_GUID GUID_MUST_BE_UPDATED("80f2bb81-3873-4631-8ddd-940d2119f000");
23
24 IMPLEMENT_STANDARD_HANDLE(HYDROData_Entity,MMgt_TShared)
25 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Entity,MMgt_TShared)
26
27 // is equal function for unique object mapping
28 bool IsEqual(const Handle_HYDROData_Entity& theObj1, const Handle_HYDROData_Entity& theObj2)
29 {
30   if ( !theObj1.IsNull() && !theObj2.IsNull() )
31     return theObj1->Label() == theObj2->Label();
32   return false;
33 }
34
35 QString HYDROData_Entity::GetName() const
36 {
37   Handle(TDataStd_Name) aName;
38   if (myLab.FindAttribute(TDataStd_Name::GetID(), aName)) {
39     TCollection_AsciiString aStr(aName->Get());
40     return QString(aStr.ToCString());
41   }
42   return QString();
43 }
44
45 void HYDROData_Entity::SetName(const QString& theName)
46 {
47   TDataStd_Name::Set(myLab, TCollection_ExtendedString(theName.toLatin1().constData()));
48 }
49
50 QStringList HYDROData_Entity::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
51 {
52   QStringList anEmptyList;
53   return anEmptyList;
54 }
55
56 void HYDROData_Entity::Update()
57 {
58 }
59
60 QVariant HYDROData_Entity::GetDataVariant()
61 {
62   return QVariant();
63 }
64
65 void HYDROData_Entity::SetToUpdate(bool theFlag)
66 {
67   if ( theFlag )
68   {
69     TDataStd_UAttribute::Set( myLab, GUID_MUST_BE_UPDATED );
70   }
71   else
72   {
73     myLab.ForgetAttribute( GUID_MUST_BE_UPDATED );
74   }
75 }
76
77 bool HYDROData_Entity::IsMustBeUpdated() const
78 {
79   return myLab.IsAttribute( GUID_MUST_BE_UPDATED );
80 }
81
82 bool HYDROData_Entity::IsRemoved() const
83 {
84   return !myLab.HasAttribute();
85 }
86
87 void HYDROData_Entity::Remove()
88 {
89   return myLab.ForgetAllAttributes( true );
90 }
91
92 bool HYDROData_Entity::CanRemove()
93 {
94   return true;
95 }
96
97 HYDROData_Entity::HYDROData_Entity()
98 {
99 }
100
101 HYDROData_Entity::~HYDROData_Entity()
102 {
103 }
104
105 void HYDROData_Entity::CopyTo(Handle_HYDROData_Entity theDestination) const
106 {
107   TDF_CopyLabel aCopy(myLab, theDestination->Label());
108   aCopy.Perform();
109 }
110
111 Handle(HYDROData_Entity) HYDROData_Entity::GetFatherObject() const
112 {
113   Handle(HYDROData_Entity) aFather;
114
115   if ( !myLab.IsNull() )
116   {
117     TDF_Label aFatherLabel = myLab.Father();
118
119     while ( aFather.IsNull() && !aFatherLabel.IsNull() && !aFatherLabel.IsRoot() )
120     {
121       aFather = HYDROData_Iterator::Object( aFatherLabel );
122       aFatherLabel = aFatherLabel.Father();
123     }
124   }
125
126   return aFather;
127 }
128
129 HYDROData_SequenceOfObjects HYDROData_Entity::GetAllReferenceObjects() const
130 {
131   return HYDROData_SequenceOfObjects();
132 }
133
134 void HYDROData_Entity::SetLabel(TDF_Label theLabel)
135 {
136   myLab = theLabel;
137 }
138
139 void HYDROData_Entity::SaveByteArray(const int theTag, 
140   const char* theData, const int theLen)
141 {
142   TDF_Label aLab = theTag == 0 ? myLab : myLab.FindChild(theTag);
143   // array is empty, remove the attribute
144   if (theLen <= 0) {
145     aLab.ForgetAttribute(TDataStd_ByteArray::GetID());
146     return;
147   }
148   // store data of image in byte array
149   Handle(TDataStd_ByteArray) aData;
150   if (!aLab.FindAttribute(TDataStd_ByteArray::GetID(), aData)) {
151     aData = TDataStd_ByteArray::Set(aLab, 1, theLen);
152   }
153   // copy bytes one by one
154   if (aData->Length() != theLen) {
155     Handle(TColStd_HArray1OfByte) aNewData = new TColStd_HArray1OfByte(1, theLen);
156     for(int a = 0; a < theLen; a++)
157       aNewData->SetValue(a + 1, theData[a]);
158     aData->ChangeArray(aNewData);
159   } else {
160     for(int a = 0; a < theLen; a++)
161       aData->SetValue(a + 1, theData[a]);
162   }
163 }
164
165 const char* HYDROData_Entity::ByteArray(const int theTag, int& theLen) const
166 {
167   TDF_Label aLab = theTag == 0 ? myLab : myLab.FindChild(theTag);
168   Handle(TDataStd_ByteArray) aData;
169   if (!aLab.FindAttribute(TDataStd_ByteArray::GetID(), aData))
170     return NULL; // return empty image if there is no array
171   theLen = aData->Length();
172   if (theLen)
173     return (const char*)(&(aData->InternalArray()->ChangeArray1().ChangeValue(1)));
174   return NULL;
175 }
176
177 int HYDROData_Entity::NbReferenceObjects( const int theTag ) const
178 {
179   Handle(TDataStd_ReferenceList) aRefs = getReferenceList( theTag, false );
180   return aRefs.IsNull() ? 0 : aRefs->Extent();
181 }
182
183 bool HYDROData_Entity::HasReference( const Handle_HYDROData_Entity& theObj,
184                                      const int                      theTag ) const
185 {
186   if ( theObj.IsNull() )
187     return false;
188
189   Handle(TDataStd_ReferenceList) aRefs = getReferenceList( theTag, false );
190   if ( aRefs.IsNull() || aRefs->IsEmpty() )
191     return false;
192
193   TDF_ListIteratorOfLabelList aListIt( aRefs->List() );
194   for ( ; aListIt.More(); aListIt.Next() )
195   {
196     const TDF_Label& aRefLabel = aListIt.Value();
197     if  ( theObj->Label() == aRefLabel )
198       return true;
199   }
200
201   return false;
202 }
203
204 void HYDROData_Entity::AddReferenceObject( const Handle_HYDROData_Entity& theObj,
205                                            const int                      theTag )
206 {
207   if ( theObj.IsNull() )
208     return;
209
210   Handle(TDataStd_ReferenceList) aRefs = getReferenceList( theTag, true );
211   aRefs->Append( theObj->Label() );
212 }
213
214 void HYDROData_Entity::SetReferenceObject( const Handle_HYDROData_Entity& theObj,
215                                            const int                      theTag,
216                                            const int                      theIndex )
217 {
218   if ( theObj.IsNull() )
219   {
220     RemoveReferenceObject( theTag, theIndex );
221     return;
222   }
223
224   Handle(TDataStd_ReferenceList) aRefs = getReferenceList( theTag, true );
225
226   if ( theIndex >= aRefs->Extent() )
227   {
228     aRefs->Append( theObj->Label() );
229   }
230   else if ( theIndex < 0 )
231   {
232     aRefs->Prepend( theObj->Label() );
233   }
234   else
235   {
236     RemoveReferenceObject( theTag, theIndex );
237
238     Handle(HYDROData_Entity) aBeforeObj = GetReferenceObject( theTag, theIndex );
239
240     aRefs = getReferenceList( theTag, true ); // because reference list can be removed
241     if ( !aBeforeObj.IsNull() )
242       aRefs->InsertBefore( theObj->Label(), aBeforeObj->Label() );
243     else 
244       aRefs->Append( theObj->Label() );
245   }
246 }
247
248 void HYDROData_Entity::InsertReferenceObject( const Handle_HYDROData_Entity& theObj,
249                                               const int                      theTag,
250                                               const int                      theBeforeIndex )
251 {
252   if ( theObj.IsNull() )
253     return;
254
255   Handle(TDataStd_ReferenceList) aRefs = getReferenceList( theTag, true );
256
257   if ( theBeforeIndex >= aRefs->Extent() )
258   {
259     aRefs->Append( theObj->Label() );
260   }
261   else if ( theBeforeIndex < 0 )
262   {
263     aRefs->Prepend( theObj->Label() );
264   }
265   else
266   {
267     Handle(HYDROData_Entity) aBeforeObj = GetReferenceObject( theTag, theBeforeIndex );
268     if ( !aBeforeObj.IsNull() )
269       aRefs->InsertBefore( theObj->Label(), aBeforeObj->Label() );
270     else 
271       aRefs->Append( theObj->Label() );
272   }
273 }
274
275 void HYDROData_Entity::SetReferenceObjects( const HYDROData_SequenceOfObjects& theObjects,
276                                             const int                          theTag )
277 {
278   ClearReferenceObjects( theTag );
279   if ( theObjects.IsEmpty() )
280     return;
281
282   HYDROData_SequenceOfObjects::Iterator anIter( theObjects );
283   for ( ; anIter.More(); anIter.Next() )
284     AddReferenceObject( anIter.Value(), theTag );
285 }
286
287 Handle(HYDROData_Entity) HYDROData_Entity::GetReferenceObject( const int theTag,
288                                                                const int theIndex ) const
289 {
290   Handle(HYDROData_Entity) aRes;
291
292   Handle(TDataStd_ReferenceList) aRefs = getReferenceList( theTag, false );
293   if ( aRefs.IsNull() || theIndex < 0 || theIndex >= aRefs->Extent() )
294     return aRes;
295
296   TDF_ListIteratorOfLabelList anIter( aRefs->List() );
297   for ( int anIndex = 0; anIndex != theIndex && anIter.More(); anIter.Next(), ++anIndex );
298
299   const TDF_Label& aRefLabel = anIter.Value();
300   aRes = HYDROData_Iterator::Object( aRefLabel );
301
302   return aRes;
303 }
304
305 HYDROData_SequenceOfObjects HYDROData_Entity::GetReferenceObjects( const int theTag ) const
306 {
307   HYDROData_SequenceOfObjects aRes;
308
309   Handle(TDataStd_ReferenceList) aRefs = getReferenceList( theTag, false );
310   if ( aRefs.IsNull() )
311     return aRes;
312
313   TDF_ListIteratorOfLabelList anIter( aRefs->List() );
314   for ( ; anIter.More(); anIter.Next() )
315   {
316     const TDF_Label& aRefLabel = anIter.Value();
317
318     Handle(HYDROData_Entity) aRefObject = HYDROData_Iterator::Object( aRefLabel );
319     if ( aRefObject.IsNull() )
320       continue;
321
322     aRes.Append( aRefObject );
323   }
324
325   return aRes;
326 }
327
328 void HYDROData_Entity::RemoveReferenceObject( const TDF_Label& theRefLabel,
329                                               const int        theTag )
330 {
331   Handle(TDataStd_ReferenceList) aRefs = getReferenceList( theTag, false );
332   if ( aRefs.IsNull() )
333     return;
334
335   if ( aRefs->Extent() == 1 )
336   { 
337     // remove all if only one
338     ClearReferenceObjects( theTag );
339     return;
340   }
341
342   aRefs->Remove( theRefLabel );
343 }
344
345 void HYDROData_Entity::RemoveReferenceObject( const int theTag,
346                                               const int theIndex )
347 {
348   Handle(TDataStd_ReferenceList) aRefs = getReferenceList( theTag, false );
349   if ( aRefs.IsNull() )
350     return;
351
352   if ( aRefs->Extent() == 1 && theIndex == 0 )
353   { 
354     // remove all if only one
355     ClearReferenceObjects( theTag );
356     return;
357   }
358
359   int anIndex = 0;
360   TDF_ListIteratorOfLabelList anIter( aRefs->List() );
361   for ( ; anIndex != theIndex && anIter.More(); anIter.Next(), ++anIndex );
362
363   if ( anIndex != theIndex || !anIter.More() )
364     return;
365
366   const TDF_Label& aRefLabel = anIter.Value();
367   aRefs->Remove( aRefLabel );
368 }
369
370 void HYDROData_Entity::ClearReferenceObjects( const int theTag )
371 {
372   TDF_Label aSetLabel = theTag == 0 ? myLab : myLab.FindChild( theTag );
373   aSetLabel.ForgetAttribute( TDataStd_ReferenceList::GetID() );
374 }
375
376 Handle(TDataStd_ReferenceList) HYDROData_Entity::getReferenceList( const int theTag,
377                                                                    const bool theIsCreate ) const
378 {
379   TDF_Label aLabel = theTag == 0 ? myLab : myLab.FindChild( theTag );
380
381   Handle(TDataStd_ReferenceList) aRefs;
382   if ( !aLabel.FindAttribute( TDataStd_ReferenceList::GetID(), aRefs ) && theIsCreate )
383     aRefs = TDataStd_ReferenceList::Set( aLabel );
384
385   return aRefs;
386 }
387
388 void HYDROData_Entity::SetColor( const QColor& theColor,
389                                  const int     theTag )
390 {
391   TDF_Label aLabel = theTag == 0 ? myLab : myLab.FindChild( theTag );
392
393   Handle(TDataStd_IntegerArray) aColorArray;
394   if ( !aLabel.FindAttribute( TDataStd_IntegerArray::GetID(), aColorArray ) )
395     aColorArray = TDataStd_IntegerArray::Set( aLabel, 1, 4 );
396
397   aColorArray->SetValue( 1, theColor.red()   );
398   aColorArray->SetValue( 2, theColor.green() );
399   aColorArray->SetValue( 3, theColor.blue()  );
400   aColorArray->SetValue( 4, theColor.alpha() );
401 }
402
403 QColor HYDROData_Entity::GetColor( const QColor& theDefColor,
404                                    const int     theTag ) const
405 {
406   QColor aResColor = theDefColor;
407
408   TDF_Label aLabel = theTag == 0 ? myLab : myLab.FindChild( theTag );
409
410   Handle(TDataStd_IntegerArray) aColorArray;
411   if ( aLabel.FindAttribute( TDataStd_IntegerArray::GetID(), aColorArray ) )
412   {
413     aResColor.setRed(   aColorArray->Value( 1 ) );
414     aResColor.setGreen( aColorArray->Value( 2 ) );
415     aResColor.setBlue(  aColorArray->Value( 3 ) );
416     aResColor.setAlpha( aColorArray->Value( 4 ) );
417   }
418
419   return aResColor;
420 }
421
422 void HYDROData_Entity::setPythonReferenceObject( MapOfTreatedObjects&            theTreatedObjects,
423                                                  QStringList&                    theScript,
424                                                  const Handle(HYDROData_Entity)& theRefObject,
425                                                  const QString&                  theMethod ) const
426 {
427   if ( theRefObject.IsNull() )
428     return;
429
430   QString aRefObjName = theRefObject->GetName();
431   if ( aRefObjName.isEmpty() )
432     return;
433
434   bool anIsToSetObject = true;
435
436   // The definition of reference object must be dumped before this
437   if ( !theTreatedObjects.contains( aRefObjName ) )
438   {
439     // Write definition of reference polyline
440     QStringList aRefObjDump = theRefObject->DumpToPython( theTreatedObjects );
441     if ( ( anIsToSetObject = !aRefObjDump.isEmpty() ) )
442     {
443       QStringList aTmpList = theScript;
444       theScript = aRefObjDump;
445
446       theScript << QString( "" );
447       theScript << aTmpList;
448
449       theTreatedObjects.insert( aRefObjName, theRefObject );
450     }
451   }
452
453   if ( anIsToSetObject )
454   {
455     theScript << QString( "%1.%2( %3 );" )
456                  .arg( GetName() ).arg( theMethod ).arg( aRefObjName );
457   }
458 }
459
460