Salome HOME
Remove extra includes.
[modules/hydro.git] / src / HYDROData / HYDROData_Entity.cxx
1
2 #include "HYDROData_Entity.h"
3
4 #include "HYDROData_Iterator.h"
5 #include "HYDROData_Tool.h"
6
7 #include <TDataStd_Name.hxx>
8 #include <TDataStd_ByteArray.hxx>
9 #include <TDataStd_UAttribute.hxx>
10 #include <TDataStd_IntegerArray.hxx>
11 #include <TDataStd_BooleanArray.hxx>
12 #include <TDataStd_Integer.hxx>
13 #include <TDataStd_RealArray.hxx>
14 #include <TDataStd_ReferenceList.hxx>
15
16 #include <TDF_CopyLabel.hxx>
17 #include <TDF_ListIteratorOfLabelList.hxx>
18
19 #include <QColor>
20 #include <QString>
21 #include <QStringList>
22 #include <QVariant>
23
24 static const Standard_GUID GUID_MUST_BE_UPDATED("80f2bb81-3873-4631-8ddd-940d2119f000");
25
26 IMPLEMENT_STANDARD_HANDLE(HYDROData_Entity,MMgt_TShared)
27 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Entity,MMgt_TShared)
28
29 // is equal function for unique object mapping
30 bool IsEqual(const Handle_HYDROData_Entity& theObj1, const Handle_HYDROData_Entity& theObj2)
31 {
32   if ( !theObj1.IsNull() && !theObj2.IsNull() )
33     return theObj1->Label() == theObj2->Label();
34   return false;
35 }
36
37 QString HYDROData_Entity::GetName() const
38 {
39   Handle(TDataStd_Name) aName;
40   if (myLab.FindAttribute(TDataStd_Name::GetID(), aName)) {
41     TCollection_AsciiString aStr(aName->Get());
42     return QString(aStr.ToCString());
43   }
44   return QString();
45 }
46
47 QString HYDROData_Entity::GetObjPyName() const
48 {
49   QString aName = GetName();
50   aName.replace(QRegExp("[\\W]"), "_");
51
52   return aName;
53 }
54
55 void HYDROData_Entity::SetName(const QString& theName)
56 {
57   TDataStd_Name::Set(myLab, TCollection_ExtendedString(theName.toLatin1().constData()));
58 }
59
60 QStringList HYDROData_Entity::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
61 {
62   QStringList anEmptyList;
63   return anEmptyList;
64 }
65
66 void HYDROData_Entity::Update()
67 {
68   SetToUpdate( false );
69 }
70
71 void HYDROData_Entity::UpdateLocalCS( double theDx, double theDy )
72 {
73   //On the base level no actions are necessary
74 }
75
76 bool HYDROData_Entity::IsHas2dPrs() const
77 {
78   return false;
79 }
80
81 void HYDROData_Entity::Show()
82 {
83   if ( !IsHas2dPrs() )
84     return;
85
86   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
87   if ( aDocument.IsNull() )
88     return;
89
90   aDocument->Show( this );
91 }
92
93 QVariant HYDROData_Entity::GetDataVariant()
94 {
95   return QVariant();
96 }
97
98 void HYDROData_Entity::SetToUpdate( bool theFlag )
99 {
100   if ( IsMustBeUpdated() == theFlag )
101     return;
102
103   if ( theFlag )
104   {
105     TDataStd_UAttribute::Set( myLab, GUID_MUST_BE_UPDATED );
106
107     Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
108     if ( !aDocument.IsNull() )
109     {
110       // Change the states of this and all depended objects
111       HYDROData_Tool::SetMustBeUpdatedObjects( aDocument );
112     }
113   }
114   else
115   {
116     myLab.ForgetAttribute( GUID_MUST_BE_UPDATED );
117   }
118 }
119
120 bool HYDROData_Entity::IsMustBeUpdated() const
121 {
122   return myLab.IsAttribute( GUID_MUST_BE_UPDATED );
123 }
124
125 bool HYDROData_Entity::CanBeUpdated() const
126 {
127   return true;
128 }
129
130 bool HYDROData_Entity::IsRemoved() const
131 {
132   return !myLab.HasAttribute();
133 }
134
135 void HYDROData_Entity::Remove()
136 {
137   return myLab.ForgetAllAttributes( true );
138 }
139
140 bool HYDROData_Entity::CanRemove()
141 {
142   return true;
143 }
144
145 HYDROData_Entity::HYDROData_Entity()
146 {
147 }
148
149 HYDROData_Entity::~HYDROData_Entity()
150 {
151 }
152
153 void HYDROData_Entity::CopyTo( const Handle(HYDROData_Entity)& theDestination ) const
154 {
155   TDF_CopyLabel aCopy(myLab, theDestination->Label());
156   aCopy.Perform();
157 }
158
159 Handle(HYDROData_Entity) HYDROData_Entity::GetFatherObject() const
160 {
161   Handle(HYDROData_Entity) aFather;
162
163   if ( !myLab.IsNull() )
164   {
165     TDF_Label aFatherLabel = myLab.Father();
166
167     while ( aFather.IsNull() && !aFatherLabel.IsNull() && !aFatherLabel.IsRoot() )
168     {
169       aFather = HYDROData_Iterator::Object( aFatherLabel );
170       aFatherLabel = aFatherLabel.Father();
171     }
172   }
173
174   return aFather;
175 }
176
177 HYDROData_SequenceOfObjects HYDROData_Entity::GetAllReferenceObjects() const
178 {
179   return HYDROData_SequenceOfObjects();
180 }
181
182 Standard_Boolean HYDROData_Entity::GetZLevel( Standard_Integer& theLevel ) const
183 {
184   theLevel = -1;
185
186   TDF_Label aLabel = myLab.FindChild( DataTag_ZLevel, false );
187   if ( !aLabel.IsNull() )
188   {
189     Handle(TDataStd_Integer) anIntVal;
190     if ( aLabel.FindAttribute( TDataStd_Integer::GetID(), anIntVal ) )
191     {
192       theLevel = anIntVal->Get();
193       return Standard_True;
194     }
195   }
196
197   return Standard_False;
198 }
199
200 void HYDROData_Entity::SetZLevel( const Standard_Integer& theLevel )
201 {
202   TDataStd_Integer::Set( myLab.FindChild( DataTag_ZLevel ), theLevel );
203 }
204
205 void HYDROData_Entity::RemoveZLevel()
206 {
207   TDF_Label aLabel = myLab.FindChild( DataTag_ZLevel, false );
208   if ( !aLabel.IsNull() )
209     aLabel.ForgetAllAttributes();
210 }
211
212 void HYDROData_Entity::SetLabel( const TDF_Label& theLabel )
213 {
214   myLab = theLabel;
215 }
216
217 void HYDROData_Entity::SaveByteArray( const int   theTag, 
218                                       const char* theData,
219                                       const int   theLen )
220 {
221   TDF_Label aLab = theTag == 0 ? myLab : myLab.FindChild(theTag);
222   // array is empty, remove the attribute
223   if (theLen <= 0) {
224     aLab.ForgetAttribute(TDataStd_ByteArray::GetID());
225     return;
226   }
227   // store data of image in byte array
228   Handle(TDataStd_ByteArray) aData;
229   if (!aLab.FindAttribute(TDataStd_ByteArray::GetID(), aData)) {
230     aData = TDataStd_ByteArray::Set(aLab, 1, theLen);
231   }
232   // copy bytes one by one
233   if (aData->Length() != theLen) {
234     Handle(TColStd_HArray1OfByte) aNewData = new TColStd_HArray1OfByte(1, theLen);
235     for(int a = 0; a < theLen; a++)
236       aNewData->SetValue(a + 1, theData[a]);
237     aData->ChangeArray(aNewData);
238   } else {
239     for(int a = 0; a < theLen; a++)
240       aData->SetValue(a + 1, theData[a]);
241   }
242 }
243
244 const char* HYDROData_Entity::ByteArray(const int theTag, int& theLen) const
245 {
246   TDF_Label aLab = theTag == 0 ? myLab : myLab.FindChild(theTag);
247   Handle(TDataStd_ByteArray) aData;
248   if (!aLab.FindAttribute(TDataStd_ByteArray::GetID(), aData))
249     return NULL; // return empty image if there is no array
250   theLen = aData->Length();
251   if (theLen)
252     return (const char*)(&(aData->InternalArray()->ChangeArray1().ChangeValue(1)));
253   return NULL;
254 }
255
256 int HYDROData_Entity::NbReferenceObjects( const int theTag ) const
257 {
258   Handle(TDataStd_ReferenceList) aRefs = getReferenceList( theTag, false );
259   return aRefs.IsNull() ? 0 : aRefs->Extent();
260 }
261
262 bool HYDROData_Entity::HasReference( const Handle_HYDROData_Entity& theObj,
263                                      const int                      theTag ) const
264 {
265   if ( theObj.IsNull() )
266     return false;
267
268   Handle(TDataStd_ReferenceList) aRefs = getReferenceList( theTag, false );
269   if ( aRefs.IsNull() || aRefs->IsEmpty() )
270     return false;
271
272   TDF_ListIteratorOfLabelList aListIt( aRefs->List() );
273   for ( ; aListIt.More(); aListIt.Next() )
274   {
275     const TDF_Label& aRefLabel = aListIt.Value();
276     if  ( theObj->Label() == aRefLabel )
277       return true;
278   }
279
280   return false;
281 }
282
283 void HYDROData_Entity::AddReferenceObject( const Handle_HYDROData_Entity& theObj,
284                                            const int                      theTag )
285 {
286   if ( theObj.IsNull() )
287     return;
288
289   Handle(TDataStd_ReferenceList) aRefs = getReferenceList( theTag, true );
290   aRefs->Append( theObj->Label() );
291 }
292
293 void HYDROData_Entity::SetReferenceObject( const Handle_HYDROData_Entity& theObj,
294                                            const int                      theTag,
295                                            const int                      theIndex )
296 {
297   if ( theObj.IsNull() )
298   {
299     RemoveReferenceObject( theTag, theIndex );
300     return;
301   }
302
303   Handle(TDataStd_ReferenceList) aRefs = getReferenceList( theTag, true );
304
305   if ( theIndex >= aRefs->Extent() )
306   {
307     aRefs->Append( theObj->Label() );
308   }
309   else if ( theIndex < 0 )
310   {
311     aRefs->Prepend( theObj->Label() );
312   }
313   else
314   {
315     RemoveReferenceObject( theTag, theIndex );
316
317     Handle(HYDROData_Entity) aBeforeObj = GetReferenceObject( theTag, theIndex );
318
319     aRefs = getReferenceList( theTag, true ); // because reference list can be removed
320     if ( !aBeforeObj.IsNull() )
321       aRefs->InsertBefore( theObj->Label(), aBeforeObj->Label() );
322     else 
323       aRefs->Append( theObj->Label() );
324   }
325 }
326
327 void HYDROData_Entity::InsertReferenceObject( const Handle_HYDROData_Entity& theObj,
328                                               const int                      theTag,
329                                               const int                      theBeforeIndex )
330 {
331   if ( theObj.IsNull() )
332     return;
333
334   Handle(TDataStd_ReferenceList) aRefs = getReferenceList( theTag, true );
335
336   if ( theBeforeIndex >= aRefs->Extent() )
337   {
338     aRefs->Append( theObj->Label() );
339   }
340   else if ( theBeforeIndex < 0 )
341   {
342     aRefs->Prepend( theObj->Label() );
343   }
344   else
345   {
346     Handle(HYDROData_Entity) aBeforeObj = GetReferenceObject( theTag, theBeforeIndex );
347     if ( !aBeforeObj.IsNull() )
348       aRefs->InsertBefore( theObj->Label(), aBeforeObj->Label() );
349     else 
350       aRefs->Append( theObj->Label() );
351   }
352 }
353
354 void HYDROData_Entity::SetReferenceObjects( const HYDROData_SequenceOfObjects& theObjects,
355                                             const int                          theTag )
356 {
357   ClearReferenceObjects( theTag );
358   if ( theObjects.IsEmpty() )
359     return;
360
361   HYDROData_SequenceOfObjects::Iterator anIter( theObjects );
362   for ( ; anIter.More(); anIter.Next() )
363     AddReferenceObject( anIter.Value(), theTag );
364 }
365
366 Handle(HYDROData_Entity) HYDROData_Entity::GetReferenceObject( const int theTag,
367                                                                const int theIndex ) const
368 {
369   Handle(HYDROData_Entity) aRes;
370
371   Handle(TDataStd_ReferenceList) aRefs = getReferenceList( theTag, false );
372   if ( aRefs.IsNull() || theIndex < 0 || theIndex >= aRefs->Extent() )
373     return aRes;
374
375   TDF_ListIteratorOfLabelList anIter( aRefs->List() );
376   for ( int anIndex = 0; anIndex != theIndex && anIter.More(); anIter.Next(), ++anIndex );
377
378   const TDF_Label& aRefLabel = anIter.Value();
379   aRes = HYDROData_Iterator::Object( aRefLabel );
380
381   return aRes;
382 }
383
384 HYDROData_SequenceOfObjects HYDROData_Entity::GetReferenceObjects( const int theTag ) const
385 {
386   HYDROData_SequenceOfObjects aRes;
387
388   Handle(TDataStd_ReferenceList) aRefs = getReferenceList( theTag, false );
389   if ( aRefs.IsNull() )
390     return aRes;
391
392   TDF_ListIteratorOfLabelList anIter( aRefs->List() );
393   for ( ; anIter.More(); anIter.Next() )
394   {
395     const TDF_Label& aRefLabel = anIter.Value();
396
397     Handle(HYDROData_Entity) aRefObject = HYDROData_Iterator::Object( aRefLabel );
398     if ( aRefObject.IsNull() )
399       continue;
400
401     aRes.Append( aRefObject );
402   }
403
404   return aRes;
405 }
406
407 void HYDROData_Entity::RemoveReferenceObject( const TDF_Label& theRefLabel,
408                                               const int        theTag )
409 {
410   Handle(TDataStd_ReferenceList) aRefs = getReferenceList( theTag, false );
411   if ( aRefs.IsNull() )
412     return;
413
414   if ( aRefs->Extent() == 1 )
415   { 
416     // remove all if only one
417     ClearReferenceObjects( theTag );
418     return;
419   }
420
421   aRefs->Remove( theRefLabel );
422 }
423
424 void HYDROData_Entity::RemoveReferenceObject( const int theTag,
425                                               const int theIndex )
426 {
427   Handle(TDataStd_ReferenceList) aRefs = getReferenceList( theTag, false );
428   if ( aRefs.IsNull() )
429     return;
430
431   if ( aRefs->Extent() == 1 && theIndex == 0 )
432   { 
433     // remove all if only one
434     ClearReferenceObjects( theTag );
435     return;
436   }
437
438   int anIndex = 0;
439   TDF_ListIteratorOfLabelList anIter( aRefs->List() );
440   for ( ; anIndex != theIndex && anIter.More(); anIter.Next(), ++anIndex );
441
442   if ( anIndex != theIndex || !anIter.More() )
443     return;
444
445   const TDF_Label& aRefLabel = anIter.Value();
446   aRefs->Remove( aRefLabel );
447 }
448
449 void HYDROData_Entity::ClearReferenceObjects( const int theTag )
450 {
451   TDF_Label aSetLabel = theTag == 0 ? myLab : myLab.FindChild( theTag );
452   aSetLabel.ForgetAttribute( TDataStd_ReferenceList::GetID() );
453 }
454
455 Handle(TDataStd_ReferenceList) HYDROData_Entity::getReferenceList( const int theTag,
456                                                                    const bool theIsCreate ) const
457 {
458   TDF_Label aLabel = theTag == 0 ? myLab : myLab.FindChild( theTag );
459
460   Handle(TDataStd_ReferenceList) aRefs;
461   if ( !aLabel.FindAttribute( TDataStd_ReferenceList::GetID(), aRefs ) && theIsCreate )
462     aRefs = TDataStd_ReferenceList::Set( aLabel );
463
464   return aRefs;
465 }
466
467 void HYDROData_Entity::SetColor( const QColor& theColor,
468                                  const int     theTag )
469 {
470   TDF_Label aLabel = theTag == 0 ? myLab : myLab.FindChild( theTag );
471
472   Handle(TDataStd_IntegerArray) aColorArray;
473   if ( !aLabel.FindAttribute( TDataStd_IntegerArray::GetID(), aColorArray ) )
474     aColorArray = TDataStd_IntegerArray::Set( aLabel, 1, 4 );
475
476   aColorArray->SetValue( 1, theColor.red()   );
477   aColorArray->SetValue( 2, theColor.green() );
478   aColorArray->SetValue( 3, theColor.blue()  );
479   aColorArray->SetValue( 4, theColor.alpha() );
480 }
481
482 QColor HYDROData_Entity::GetColor( const QColor& theDefColor,
483                                    const int     theTag ) const
484 {
485   QColor aResColor = theDefColor;
486
487   TDF_Label aLabel = theTag == 0 ? myLab : myLab.FindChild( theTag );
488
489   Handle(TDataStd_IntegerArray) aColorArray;
490   if ( aLabel.FindAttribute( TDataStd_IntegerArray::GetID(), aColorArray ) )
491   {
492     aResColor.setRed(   aColorArray->Value( 1 ) );
493     aResColor.setGreen( aColorArray->Value( 2 ) );
494     aResColor.setBlue(  aColorArray->Value( 3 ) );
495     aResColor.setAlpha( aColorArray->Value( 4 ) );
496   }
497
498   return aResColor;
499 }
500
501 QStringList HYDROData_Entity::dumpObjectCreation( MapOfTreatedObjects& theTreatedObjects ) const
502 {
503   QStringList aResList;
504
505   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
506   if ( aDocument.IsNull() )
507     return aResList;
508
509   QString aDocName = aDocument->GetDocPyName();
510   QString aName = GetObjPyName();
511
512   aResList << QString( "%1 = %2.CreateObject( %3 );" )
513               .arg( aName ).arg( aDocName ).arg( getPyTypeID() );
514   aResList << QString( "%1.SetName( \"%2\" );" )
515               .arg( aName ).arg( GetName() );
516   aResList << QString( "" );
517
518   if ( IsHas2dPrs() )
519   {
520     // Dump object z-level in viewer
521     Standard_Integer anObjZLevel = -1;
522     if ( GetZLevel( anObjZLevel ) )
523     {
524       aResList << QString( "%1.SetZLevel( %2 );" )
525                   .arg( aName ).arg( anObjZLevel );
526       aResList << QString( "" );
527     }
528   }
529
530   return aResList;
531 }
532
533 QString HYDROData_Entity::getPyTypeID() const
534 {
535   switch( GetKind() )
536   {
537     case KIND_IMAGE:             return "KIND_IMAGE";
538     case KIND_POLYLINE:          return "KIND_POLYLINE";
539     case KIND_BATHYMETRY:        return "KIND_BATHYMETRY";
540     case KIND_ALTITUDE:          return "KIND_ALTITUDE";
541     case KIND_IMMERSIBLE_ZONE:   return "KIND_IMMERSIBLE_ZONE";
542     case KIND_RIVER:             return "KIND_RIVER";
543     case KIND_STREAM:            return "KIND_STREAM";
544     case KIND_CONFLUENCE:        return "KIND_CONFLUENCE";
545     case KIND_CHANNEL:           return "KIND_CHANNEL";
546     case KIND_OBSTACLE:          return "KIND_OBSTACLE";
547     case KIND_DIGUE:             return "KIND_DIGUE";
548     case KIND_PROFILE:           return "KIND_PROFILE";
549     case KIND_PROFILEUZ:         return "KIND_PROFILEUZ";
550     case KIND_POLYLINEXY:        return "KIND_POLYLINEXY";
551     case KIND_CALCULATION:       return "KIND_CALCULATION";
552     case KIND_ZONE:              return "KIND_ZONE";
553     case KIND_REGION:            return "KIND_REGION";
554     case KIND_VISUAL_STATE:      return "KIND_VISUAL_STATE";
555     case KIND_ARTIFICIAL_OBJECT: return "KIND_ARTIFICIAL_OBJECT";
556     case KIND_NATURAL_OBJECT:    return "KIND_NATURAL_OBJECT";
557     case KIND_DUMMY_3D:          return "KIND_DUMMY_3D";
558     case KIND_SHAPES_GROUP:      return "KIND_SHAPES_GROUP";
559     case KIND_SPLITTED_GROUP:    return "KIND_SPLITTED_GROUP";
560     case KIND_STREAM_ALTITUDE:   return "KIND_STREAM_ALTITUDE";
561     case KIND_OBSTACLE_ALTITUDE: return "KIND_OBSTACLE_ALTITUDE";
562     default:                     return "KIND_UNKNOWN"; ///! Unrecognized object
563   }
564 }
565
566 void HYDROData_Entity::setPythonReferenceObject( MapOfTreatedObjects&            theTreatedObjects,
567                                                  QStringList&                    theScript,
568                                                  const Handle(HYDROData_Entity)& theRefObject,
569                                                  const QString&                  theMethod ) const
570 {
571   if ( !checkObjectPythonDefinition( theTreatedObjects, theScript, theRefObject ) )
572     return;
573
574   QString aRefObjName = theRefObject->GetObjPyName();
575
576   QString anObjName = GetObjPyName();
577   theScript << QString( "%1.%2( %3 );" )
578                .arg( anObjName ).arg( theMethod ).arg( aRefObjName );
579 }
580
581 bool HYDROData_Entity::checkObjectPythonDefinition( MapOfTreatedObjects&            theTreatedObjects,
582                                                     QStringList&                    theScript,
583                                                     const Handle(HYDROData_Entity)& theRefObject ) const
584 {
585   if ( theRefObject.IsNull() )
586     return false;
587
588   QString aRefObjName = theRefObject->GetName();
589   if ( aRefObjName.isEmpty() )
590     return false;
591
592   if ( theTreatedObjects.contains( aRefObjName ) )
593     return true;
594
595   // The definition of reference object must be dumped before this
596   QStringList aRefObjDump = theRefObject->DumpToPython( theTreatedObjects );
597   if ( aRefObjDump.isEmpty() )
598     return false;
599
600   QStringList aTmpList = theScript;
601   theScript = aRefObjDump;
602
603   theScript << QString( "" );
604   theScript << aTmpList;
605
606   theTreatedObjects.insert( aRefObjName, theRefObject );
607
608   return true;
609 }
610
611 void HYDROData_Entity::setPythonObjectColor( QStringList&         theScript,
612                                              const QColor&        theColor,
613                                              const QColor&        theDefaultColor,
614                                              const QString&       theMethod ) const
615 {
616   if ( theColor == theDefaultColor )
617     return; //Do not set the color for object if it like default
618
619   QString anObjName = GetObjPyName();
620   theScript << QString( "%1.%2( QColor( %3, %4, %5, %6 ) );" )
621               .arg( anObjName ).arg( theMethod )
622               .arg( theColor.red()  ).arg( theColor.green() )
623               .arg( theColor.blue() ).arg( theColor.alpha() );
624 }
625
626 void HYDROData_Entity::findPythonReferenceObject( MapOfTreatedObjects& theTreatedObjects,
627                                                   QStringList& theScript ) const
628 {
629   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
630   if ( aDocument.IsNull() )
631     return;
632     
633   theScript << QString( "%1 = %2.FindObjectByName( \"%3\" );" ).arg( GetObjPyName() )
634                                                                .arg( aDocument->GetDocPyName() )
635                                                                .arg( GetName() );
636 }