0031313: Foundation Classes - Dump improvement for classes
[occt.git] / src / XCAFDoc / XCAFDoc_NotesTool.cxx
1 // Copyright (c) 2017-2018 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 #include <XCAFDoc_NotesTool.hxx>
15
16 #include <Standard_GUID.hxx>
17 #include <NCollection_Map.hxx>
18 #include <TColStd_HArray1OfByte.hxx>
19 #include <TDF_Label.hxx>
20 #include <TDF_LabelMapHasher.hxx>
21 #include <TDF_ChildIDIterator.hxx>
22 #include <TDF_LabelSequence.hxx>
23 #include <TDF_Tool.hxx>
24 #include <XCAFDoc.hxx>
25 #include <XCAFDoc_GraphNode.hxx>
26 #include <XCAFDoc_NoteBalloon.hxx>
27 #include <XCAFDoc_NoteComment.hxx>
28 #include <XCAFDoc_NoteBinData.hxx>
29 #include <XCAFDoc_AssemblyItemRef.hxx>
30
31 namespace {
32
33   XCAFDoc_AssemblyItemId labeledItem(const TDF_Label& theLabel)
34   {
35     TCollection_AsciiString anEntry;
36     TDF_Tool::Entry(theLabel, anEntry);
37     return XCAFDoc_AssemblyItemId(anEntry);
38   }
39
40 }
41
42 IMPLEMENT_STANDARD_RTTIEXT(XCAFDoc_NotesTool, TDF_Attribute)
43
44 enum NotesTool_RootLabels
45 {
46   NotesTool_NotesRoot = 1,
47   NotesTool_AnnotatedItemsRoot
48 };
49
50 // =======================================================================
51 // function : GetID
52 // purpose  :
53 // =======================================================================
54 const Standard_GUID&
55 XCAFDoc_NotesTool::GetID()
56 {
57   static Standard_GUID s_ID("8F8174B1-6125-47a0-B357-61BD2D89380C");
58   return s_ID;
59 }
60
61 // =======================================================================
62 // function : Set
63 // purpose  :
64 // =======================================================================
65 Handle(XCAFDoc_NotesTool)
66 XCAFDoc_NotesTool::Set(const TDF_Label& theLabel)
67 {
68   Handle(XCAFDoc_NotesTool) aTool;
69   if (!theLabel.IsNull() && !theLabel.FindAttribute(XCAFDoc_NotesTool::GetID(), aTool))
70   {
71     aTool = new XCAFDoc_NotesTool();
72     theLabel.AddAttribute(aTool);
73   }
74   return aTool;
75 }
76
77 // =======================================================================
78 // function : XCAFDoc_NotesTool
79 // purpose  :
80 // =======================================================================
81 XCAFDoc_NotesTool::XCAFDoc_NotesTool()
82 {
83 }
84
85 // =======================================================================
86 // function : GetNotesLabel
87 // purpose  :
88 // =======================================================================
89 TDF_Label
90 XCAFDoc_NotesTool::GetNotesLabel() const
91 {
92   return Label().FindChild(NotesTool_NotesRoot);
93 }
94
95 // =======================================================================
96 // function : GetAnnotatedItemsLabel
97 // purpose  :
98 // =======================================================================
99 TDF_Label XCAFDoc_NotesTool::GetAnnotatedItemsLabel() const
100 {
101   return Label().FindChild(NotesTool_AnnotatedItemsRoot);
102 }
103
104 // =======================================================================
105 // function : NbNotes
106 // purpose  :
107 // =======================================================================
108 Standard_Integer
109 XCAFDoc_NotesTool::NbNotes() const
110 {
111   Standard_Integer nbNotes = 0;
112   for (TDF_ChildIterator anIter(GetNotesLabel()); anIter.More(); anIter.Next())
113   {
114     const TDF_Label aLabel = anIter.Value();
115     if (!XCAFDoc_Note::Get(aLabel).IsNull())
116       ++nbNotes;
117   }
118   return nbNotes;
119 }
120
121 // =======================================================================
122 // function : NbAnnotatedItems
123 // purpose  :
124 // =======================================================================
125 Standard_Integer
126 XCAFDoc_NotesTool::NbAnnotatedItems() const
127 {
128   Standard_Integer nbItems = 0;
129   for (TDF_ChildIDIterator anIter(GetAnnotatedItemsLabel(), XCAFDoc_AssemblyItemRef::GetID()); anIter.More(); anIter.Next())
130   {
131       ++nbItems;
132   }
133   return nbItems;
134 }
135
136 // =======================================================================
137 // function : GetNotes
138 // purpose  :
139 // =======================================================================
140 void
141 XCAFDoc_NotesTool::GetNotes(TDF_LabelSequence& theNoteLabels) const
142 {
143   for (TDF_ChildIterator anIter(GetNotesLabel()); anIter.More(); anIter.Next())
144   {
145     const TDF_Label aLabel = anIter.Value();
146     if (!XCAFDoc_Note::Get(aLabel).IsNull())
147       theNoteLabels.Append(aLabel);
148   }
149 }
150
151 // =======================================================================
152 // function : GetAnnotatedItems
153 // purpose  :
154 // =======================================================================
155 void
156 XCAFDoc_NotesTool::GetAnnotatedItems(TDF_LabelSequence& theItemLabels) const
157 {
158   for (TDF_ChildIDIterator anIter(GetAnnotatedItemsLabel(), XCAFDoc_AssemblyItemRef::GetID()); anIter.More(); anIter.Next())
159   {
160     theItemLabels.Append(anIter.Value()->Label());
161   }
162 }
163
164 // =======================================================================
165 // function : IsAnnotatedItem
166 // purpose  :
167 // =======================================================================
168 Standard_Boolean
169 XCAFDoc_NotesTool::IsAnnotatedItem(const XCAFDoc_AssemblyItemId& theItemId) const
170 {
171   return !FindAnnotatedItem(theItemId).IsNull();
172 }
173
174 // =======================================================================
175 // function : IsAnnotatedItem
176 // purpose  :
177 // =======================================================================
178 Standard_Boolean
179 XCAFDoc_NotesTool::IsAnnotatedItem(const TDF_Label& theItemLabel) const
180 {
181   return IsAnnotatedItem(labeledItem(theItemLabel));
182 }
183
184 // =======================================================================
185 // function : FindAnnotatedItem
186 // purpose  :
187 // =======================================================================
188 TDF_Label
189 XCAFDoc_NotesTool::FindAnnotatedItem(const XCAFDoc_AssemblyItemId& theItemId) const
190 {
191   for (TDF_ChildIDIterator anIter(GetAnnotatedItemsLabel(), XCAFDoc_AssemblyItemRef::GetID()); anIter.More(); anIter.Next())
192   {
193     Handle(XCAFDoc_AssemblyItemRef) anItemRef = Handle(XCAFDoc_AssemblyItemRef)::DownCast(anIter.Value());
194     if (!anItemRef.IsNull() && anItemRef->GetItem().IsEqual(theItemId) && !anItemRef->HasExtraRef())
195       return anItemRef->Label();
196   }
197   return TDF_Label();
198 }
199
200 // =======================================================================
201 // function : FindAnnotatedItem
202 // purpose  :
203 // =======================================================================
204 TDF_Label
205 XCAFDoc_NotesTool::FindAnnotatedItem(const TDF_Label& theItemLabel) const
206 {
207   return FindAnnotatedItem(labeledItem(theItemLabel));
208 }
209
210 // =======================================================================
211 // function : FindAnnotatedItemAttr
212 // purpose  :
213 // =======================================================================
214 TDF_Label
215 XCAFDoc_NotesTool::FindAnnotatedItemAttr(const XCAFDoc_AssemblyItemId& theItemId,
216                                          const Standard_GUID&          theGUID) const
217 {
218   for (TDF_ChildIDIterator anIter(GetAnnotatedItemsLabel(), XCAFDoc_AssemblyItemRef::GetID()); anIter.More(); anIter.Next())
219   {
220     Handle(XCAFDoc_AssemblyItemRef) anItemRef = Handle(XCAFDoc_AssemblyItemRef)::DownCast(anIter.Value());
221     if (!anItemRef.IsNull() && anItemRef->GetItem().IsEqual(theItemId) && 
222       anItemRef->HasExtraRef() && anItemRef->GetGUID() == theGUID)
223       return anItemRef->Label();
224   }
225   return TDF_Label();
226 }
227
228 // =======================================================================
229 // function : FindAnnotatedItemAttr
230 // purpose  :
231 // =======================================================================
232 TDF_Label
233 XCAFDoc_NotesTool::FindAnnotatedItemAttr(const TDF_Label&     theItemLabel,
234                                          const Standard_GUID& theGUID) const
235 {
236   return FindAnnotatedItemAttr(labeledItem(theItemLabel), theGUID);
237 }
238
239 // =======================================================================
240 // function : FindAnnotatedItemSubshape
241 // purpose  :
242 // =======================================================================
243 TDF_Label
244 XCAFDoc_NotesTool::FindAnnotatedItemSubshape(const XCAFDoc_AssemblyItemId& theItemId,
245                                              Standard_Integer              theSubshapeIndex) const
246 {
247   for (TDF_ChildIDIterator anIter(GetAnnotatedItemsLabel(), XCAFDoc_AssemblyItemRef::GetID()); anIter.More(); anIter.Next())
248   {
249     Handle(XCAFDoc_AssemblyItemRef) anItemRef = Handle(XCAFDoc_AssemblyItemRef)::DownCast(anIter.Value());
250     if (!anItemRef.IsNull() && anItemRef->GetItem().IsEqual(theItemId) &&
251       anItemRef->HasExtraRef() && anItemRef->GetSubshapeIndex() == theSubshapeIndex)
252       return anItemRef->Label();
253   }
254   return TDF_Label();
255 }
256
257 // =======================================================================
258 // function : FindAnnotatedItemSubshape
259 // purpose  :
260 // =======================================================================
261 TDF_Label
262 XCAFDoc_NotesTool::FindAnnotatedItemSubshape(const TDF_Label& theItemLabel,
263                                              Standard_Integer theSubshapeIndex) const
264 {
265   return FindAnnotatedItemSubshape(labeledItem(theItemLabel), theSubshapeIndex);
266 }
267
268 // =======================================================================
269 // function : CreateComment
270 // purpose  :
271 // =======================================================================
272 Handle(XCAFDoc_Note)
273 XCAFDoc_NotesTool::CreateComment(const TCollection_ExtendedString& theUserName,
274                                  const TCollection_ExtendedString& theTimeStamp,
275                                  const TCollection_ExtendedString& theComment)
276 {
277   TDF_Label aNoteLabel;
278   TDF_TagSource aTag;
279   aNoteLabel = aTag.NewChild(GetNotesLabel());
280   return XCAFDoc_NoteComment::Set(aNoteLabel, theUserName, theTimeStamp, theComment);
281 }
282
283 // =======================================================================
284 // function : CreateBalloon
285 // purpose  :
286 // =======================================================================
287 Handle(XCAFDoc_Note)
288 XCAFDoc_NotesTool::CreateBalloon(const TCollection_ExtendedString& theUserName,
289                                  const TCollection_ExtendedString& theTimeStamp,
290                                  const TCollection_ExtendedString& theComment)
291 {
292   TDF_Label aNoteLabel;
293   TDF_TagSource aTag;
294   aNoteLabel = aTag.NewChild(GetNotesLabel());
295   return XCAFDoc_NoteBalloon::Set(aNoteLabel, theUserName, theTimeStamp, theComment);
296 }
297
298 // =======================================================================
299 // function : CreateBinData
300 // purpose  :
301 // =======================================================================
302 Handle(XCAFDoc_Note)
303 XCAFDoc_NotesTool::CreateBinData(const TCollection_ExtendedString& theUserName,
304                                  const TCollection_ExtendedString& theTimeStamp,
305                                  const TCollection_ExtendedString& theTitle,
306                                  const TCollection_AsciiString&    theMIMEtype,
307                                  OSD_File&                         theFile)
308 {
309   TDF_Label aNoteLabel;
310   TDF_TagSource aTag;
311   aNoteLabel = aTag.NewChild(GetNotesLabel());
312   return XCAFDoc_NoteBinData::Set(aNoteLabel, theUserName, theTimeStamp, theTitle, theMIMEtype, theFile);
313 }
314
315 // =======================================================================
316 // function : CreateBinData
317 // purpose  :
318 // =======================================================================
319 Handle(XCAFDoc_Note)
320 XCAFDoc_NotesTool::CreateBinData(const TCollection_ExtendedString&    theUserName,
321                                  const TCollection_ExtendedString&    theTimeStamp,
322                                  const TCollection_ExtendedString&    theTitle,
323                                  const TCollection_AsciiString&       theMIMEtype,
324                                  const Handle(TColStd_HArray1OfByte)& theData)
325 {
326   TDF_Label aNoteLabel;
327   TDF_TagSource aTag;
328   aNoteLabel = aTag.NewChild(GetNotesLabel());
329   return XCAFDoc_NoteBinData::Set(aNoteLabel, theUserName, theTimeStamp, theTitle, theMIMEtype, theData);
330 }
331
332 // =======================================================================
333 // function : GetNotes
334 // purpose  :
335 // =======================================================================
336 Standard_Integer
337 XCAFDoc_NotesTool::GetNotes(const XCAFDoc_AssemblyItemId& theItemId,
338                             TDF_LabelSequence&            theNoteLabels) const
339 {
340   TDF_Label anAnnotatedItem = FindAnnotatedItem(theItemId);
341   if (anAnnotatedItem.IsNull())
342     return 0;
343
344   Handle(XCAFDoc_GraphNode) aChild;
345   if (!anAnnotatedItem.FindAttribute(XCAFDoc::NoteRefGUID(), aChild))
346     return 0;
347
348   Standard_Integer nbFathers = aChild->NbFathers();
349   for (Standard_Integer iFather = 1; iFather <= nbFathers; ++iFather)
350   {
351     Handle(XCAFDoc_GraphNode) aFather = aChild->GetFather(iFather);
352     theNoteLabels.Append(aFather->Label());
353   }
354
355   return theNoteLabels.Length();
356 }
357
358 // =======================================================================
359 // function : GetNotes
360 // purpose  :
361 // =======================================================================
362 Standard_Integer
363 XCAFDoc_NotesTool::GetNotes(const TDF_Label&   theItemLabel,
364                             TDF_LabelSequence& theNoteLabels) const
365 {
366   return GetNotes(labeledItem(theItemLabel), theNoteLabels);
367 }
368
369 // =======================================================================
370 // function : GetAttrNotes
371 // purpose  :
372 // =======================================================================
373 Standard_Integer
374 XCAFDoc_NotesTool::GetAttrNotes(const XCAFDoc_AssemblyItemId& theItemId,
375                                 const Standard_GUID&          theGUID,
376                                 TDF_LabelSequence&            theNoteLabels) const
377 {
378   TDF_Label anAnnotatedItem = FindAnnotatedItemAttr(theItemId, theGUID);
379   if (anAnnotatedItem.IsNull())
380     return 0;
381
382   Handle(XCAFDoc_GraphNode) aChild;
383   if (!anAnnotatedItem.FindAttribute(XCAFDoc::NoteRefGUID(), aChild))
384     return 0;
385
386   Standard_Integer nbFathers = aChild->NbFathers();
387   for (Standard_Integer iFather = 1; iFather <= nbFathers; ++iFather)
388   {
389     Handle(XCAFDoc_GraphNode) aFather = aChild->GetFather(iFather);
390     theNoteLabels.Append(aFather->Label());
391   }
392
393   return theNoteLabels.Length();
394 }
395
396 // =======================================================================
397 // function : GetAttrNotes
398 // purpose  :
399 // =======================================================================
400 Standard_Integer
401 XCAFDoc_NotesTool::GetAttrNotes(const TDF_Label&     theItemLabel,
402                                 const Standard_GUID& theGUID,
403                                 TDF_LabelSequence&   theNoteLabels) const
404 {
405   return GetAttrNotes(labeledItem(theItemLabel), theGUID, theNoteLabels);
406 }
407
408 // =======================================================================
409 // function : GetSubshapeNotes
410 // purpose  :
411 // =======================================================================
412 Standard_Integer
413 XCAFDoc_NotesTool::GetSubshapeNotes(const XCAFDoc_AssemblyItemId& theItemId,
414                                     Standard_Integer              theSubshapeIndex,
415                                     TDF_LabelSequence&            theNoteLabels) const
416 {
417   TDF_Label anAnnotatedItem = FindAnnotatedItemSubshape(theItemId, theSubshapeIndex);
418   if (anAnnotatedItem.IsNull())
419     return 0;
420
421   Handle(XCAFDoc_GraphNode) aChild;
422   if (!anAnnotatedItem.FindAttribute(XCAFDoc::NoteRefGUID(), aChild))
423     return 0;
424
425   Standard_Integer nbFathers = aChild->NbFathers();
426   for (Standard_Integer iFather = 1; iFather <= nbFathers; ++iFather)
427   {
428     Handle(XCAFDoc_GraphNode) aFather = aChild->GetFather(iFather);
429     theNoteLabels.Append(aFather->Label());
430   }
431
432   return theNoteLabels.Length();
433 }
434
435 // =======================================================================
436 // function : AddNote
437 // purpose  :
438 // =======================================================================
439 Handle(XCAFDoc_AssemblyItemRef)
440 XCAFDoc_NotesTool::AddNote(const TDF_Label&              theNoteLabel,
441                            const XCAFDoc_AssemblyItemId& theItemId)
442 {
443   Handle(XCAFDoc_AssemblyItemRef) anItemRef;
444
445   if (!XCAFDoc_Note::IsMine(theNoteLabel))
446     return anItemRef;
447
448   Handle(XCAFDoc_GraphNode) aChild;
449   TDF_Label anAnnotatedItem = FindAnnotatedItem(theItemId);
450   if (anAnnotatedItem.IsNull())
451   {
452     TDF_TagSource aTag;
453     anAnnotatedItem = aTag.NewChild(GetAnnotatedItemsLabel());
454     if (anAnnotatedItem.IsNull())
455       return anItemRef;
456   }
457
458   if (!anAnnotatedItem.FindAttribute(XCAFDoc::NoteRefGUID(), aChild))
459   {
460     aChild = XCAFDoc_GraphNode::Set(anAnnotatedItem, XCAFDoc::NoteRefGUID());
461     if (aChild.IsNull())
462       return anItemRef;
463   }
464
465   if (!anAnnotatedItem.FindAttribute(XCAFDoc_AssemblyItemRef::GetID(), anItemRef))
466   {
467     anItemRef = XCAFDoc_AssemblyItemRef::Set(anAnnotatedItem, theItemId);
468     if (anItemRef.IsNull())
469       return anItemRef;
470   }
471
472   Handle(XCAFDoc_GraphNode) aFather;
473   if (!theNoteLabel.FindAttribute(XCAFDoc::NoteRefGUID(), aFather))
474   {
475     aFather = XCAFDoc_GraphNode::Set(theNoteLabel, XCAFDoc::NoteRefGUID());
476     if (aFather.IsNull())
477       return anItemRef;
478   }
479
480   aChild->SetFather(aFather);
481   aFather->SetChild(aChild);
482
483   return anItemRef;
484 }
485
486 // =======================================================================
487 // function : AddNote
488 // purpose  :
489 // =======================================================================
490 Handle(XCAFDoc_AssemblyItemRef)
491 XCAFDoc_NotesTool::AddNote(const TDF_Label& theNoteLabel,
492                            const TDF_Label& theItemLabel)
493 {
494   return AddNote(theNoteLabel, labeledItem(theItemLabel));
495 }
496
497 // =======================================================================
498 // function : AddNoteToAttr
499 // purpose  :
500 // =======================================================================
501 Handle(XCAFDoc_AssemblyItemRef)
502 XCAFDoc_NotesTool::AddNoteToAttr(const TDF_Label&              theNoteLabel,
503                                  const XCAFDoc_AssemblyItemId& theItemId,
504                                  const Standard_GUID&          theGUID)
505 {
506   Handle(XCAFDoc_AssemblyItemRef) anItemRef;
507
508   if (!XCAFDoc_Note::IsMine(theNoteLabel))
509     return anItemRef;
510
511   Handle(XCAFDoc_GraphNode) aChild;
512   TDF_Label anAnnotatedItem = FindAnnotatedItemAttr(theItemId, theGUID);
513   if (anAnnotatedItem.IsNull())
514   {
515     TDF_TagSource aTag;
516     anAnnotatedItem = aTag.NewChild(GetAnnotatedItemsLabel());
517     if (anAnnotatedItem.IsNull())
518       return anItemRef;
519   }
520
521   if (!anAnnotatedItem.FindAttribute(XCAFDoc::NoteRefGUID(), aChild))
522   {
523     aChild = XCAFDoc_GraphNode::Set(anAnnotatedItem, XCAFDoc::NoteRefGUID());
524     if (aChild.IsNull())
525       return anItemRef;
526   }
527
528   if (!anAnnotatedItem.FindAttribute(XCAFDoc_AssemblyItemRef::GetID(), anItemRef))
529   {
530     anItemRef = XCAFDoc_AssemblyItemRef::Set(anAnnotatedItem, theItemId);
531     if (anItemRef.IsNull())
532       return anItemRef;
533   }
534
535   Handle(XCAFDoc_GraphNode) aFather;
536   if (!theNoteLabel.FindAttribute(XCAFDoc::NoteRefGUID(), aFather))
537   {
538     aFather = XCAFDoc_GraphNode::Set(theNoteLabel, XCAFDoc::NoteRefGUID());
539     if (aFather.IsNull())
540       return anItemRef;
541   }
542
543   aChild->SetFather(aFather);
544   aFather->SetChild(aChild);
545
546   anItemRef->SetGUID(theGUID);
547
548   return anItemRef;
549 }
550
551 // =======================================================================
552 // function : AddNoteToAttr
553 // purpose  :
554 // =======================================================================
555 Handle(XCAFDoc_AssemblyItemRef)
556 XCAFDoc_NotesTool::AddNoteToAttr(const TDF_Label&     theNoteLabel,
557                                  const TDF_Label&     theItemLabel,
558                                  const Standard_GUID& theGUID)
559 {
560   return AddNoteToAttr(theNoteLabel, labeledItem(theItemLabel), theGUID);
561 }
562
563 // =======================================================================
564 // function : AddNoteToSubshape
565 // purpose  :
566 // =======================================================================
567 Handle(XCAFDoc_AssemblyItemRef)
568 XCAFDoc_NotesTool::AddNoteToSubshape(const TDF_Label&              theNoteLabel,
569                                      const XCAFDoc_AssemblyItemId& theItemId,
570                                      Standard_Integer              theSubshapeIndex)
571 {
572   Handle(XCAFDoc_AssemblyItemRef) anItemRef;
573
574   if (!XCAFDoc_Note::IsMine(theNoteLabel))
575     return anItemRef;
576
577   Handle(XCAFDoc_GraphNode) aChild;
578   TDF_Label anAnnotatedItem = FindAnnotatedItemSubshape(theItemId, theSubshapeIndex);
579   if (anAnnotatedItem.IsNull())
580   {
581     TDF_TagSource aTag;
582     anAnnotatedItem = aTag.NewChild(GetAnnotatedItemsLabel());
583     if (anAnnotatedItem.IsNull())
584       return anItemRef;
585   }
586
587   if (!anAnnotatedItem.FindAttribute(XCAFDoc::NoteRefGUID(), aChild))
588   {
589     aChild = XCAFDoc_GraphNode::Set(anAnnotatedItem, XCAFDoc::NoteRefGUID());
590     if (aChild.IsNull())
591       return anItemRef;
592   }
593
594   if (!anAnnotatedItem.FindAttribute(XCAFDoc_AssemblyItemRef::GetID(), anItemRef))
595   {
596     anItemRef = XCAFDoc_AssemblyItemRef::Set(anAnnotatedItem, theItemId);
597     if (anItemRef.IsNull())
598       return anItemRef;
599   }
600
601   Handle(XCAFDoc_GraphNode) aFather;
602   if (!theNoteLabel.FindAttribute(XCAFDoc::NoteRefGUID(), aFather))
603   {
604     aFather = XCAFDoc_GraphNode::Set(theNoteLabel, XCAFDoc::NoteRefGUID());
605     if (aFather.IsNull())
606       return anItemRef;
607   }
608
609   aChild->SetFather(aFather);
610   aFather->SetChild(aChild);
611
612   anItemRef->SetSubshapeIndex(theSubshapeIndex);
613
614   return anItemRef;
615 }
616
617 // =======================================================================
618 // function : AddNoteToSubshape
619 // purpose  :
620 // =======================================================================
621 Handle(XCAFDoc_AssemblyItemRef)
622 XCAFDoc_NotesTool::AddNoteToSubshape(const TDF_Label& theNoteLabel,
623                                      const TDF_Label& theItemLabel,
624                                      Standard_Integer theSubshapeIndex)
625 {
626   return AddNoteToSubshape(theNoteLabel, labeledItem(theItemLabel), theSubshapeIndex);
627 }
628
629 // =======================================================================
630 // function : RemoveNote
631 // purpose  :
632 // =======================================================================
633 Standard_Boolean
634 XCAFDoc_NotesTool::RemoveNote(const TDF_Label&              theNoteLabel,
635                               const XCAFDoc_AssemblyItemId& theItemId,
636                               Standard_Boolean              theDelIfOrphan)
637 {
638   Handle(XCAFDoc_Note) aNote = XCAFDoc_Note::Get(theNoteLabel);
639
640   if (aNote.IsNull())
641     return Standard_False;
642
643   Handle(XCAFDoc_GraphNode) aFather;
644   if (!theNoteLabel.FindAttribute(XCAFDoc::NoteRefGUID(), aFather))
645     return Standard_False;
646
647   TDF_Label anAnnotatedItem = FindAnnotatedItem(theItemId);
648   if (anAnnotatedItem.IsNull())
649     return Standard_False;
650
651   Handle(XCAFDoc_GraphNode) aChild;
652   if (!anAnnotatedItem.FindAttribute(XCAFDoc::NoteRefGUID(), aChild))
653     return Standard_False;
654
655   aChild->UnSetFather(aFather);
656   if (aChild->NbFathers() == 0)
657     anAnnotatedItem.ForgetAllAttributes();
658
659   if (theDelIfOrphan && aNote->IsOrphan())
660     DeleteNote(theNoteLabel);
661   
662   return Standard_True;
663 }
664
665 // =======================================================================
666 // function : RemoveNote
667 // purpose  :
668 // =======================================================================
669 Standard_Boolean
670 XCAFDoc_NotesTool::RemoveNote(const TDF_Label& theNoteLabel,
671                               const TDF_Label& theItemLabel,
672                               Standard_Boolean theDelIfOrphan)
673 {
674   return RemoveNote(theNoteLabel, labeledItem(theItemLabel), theDelIfOrphan);
675 }
676
677 // =======================================================================
678 // function : RemoveSubshapeNote
679 // purpose  :
680 // =======================================================================
681 Standard_Boolean
682 XCAFDoc_NotesTool::RemoveSubshapeNote(const TDF_Label&              theNoteLabel,
683                                       const XCAFDoc_AssemblyItemId& theItemId,
684                                       Standard_Integer              theSubshapeIndex,
685                                       Standard_Boolean              theDelIfOrphan)
686 {
687   Handle(XCAFDoc_Note) aNote = XCAFDoc_Note::Get(theNoteLabel);
688
689   if (aNote.IsNull())
690     return Standard_False;
691
692   Handle(XCAFDoc_GraphNode) aFather;
693   if (!theNoteLabel.FindAttribute(XCAFDoc::NoteRefGUID(), aFather))
694     return Standard_False;
695
696   TDF_Label anAnnotatedItem = FindAnnotatedItemSubshape(theItemId, theSubshapeIndex);
697   if (anAnnotatedItem.IsNull())
698     return Standard_False;
699
700   Handle(XCAFDoc_GraphNode) aChild;
701   if (!anAnnotatedItem.FindAttribute(XCAFDoc::NoteRefGUID(), aChild))
702     return Standard_False;
703
704   aChild->UnSetFather(aFather);
705   if (aChild->NbFathers() == 0)
706     anAnnotatedItem.ForgetAllAttributes();
707
708   if (theDelIfOrphan && aNote->IsOrphan())
709     DeleteNote(theNoteLabel);
710
711   return Standard_True;
712 }
713
714 // =======================================================================
715 // function : RemoveSubshapeNote
716 // purpose  :
717 // =======================================================================
718 Standard_Boolean
719 XCAFDoc_NotesTool::RemoveSubshapeNote(const TDF_Label& theNoteLabel,
720                                       const TDF_Label& theItemLabel,
721                                       Standard_Integer theSubshapeIndex,
722                                       Standard_Boolean theDelIfOrphan)
723 {
724   return RemoveSubshapeNote(theNoteLabel, labeledItem(theItemLabel), theSubshapeIndex, theDelIfOrphan);
725 }
726
727 // =======================================================================
728 // function : RemoveAttrNote
729 // purpose  :
730 // =======================================================================
731 Standard_Boolean
732 XCAFDoc_NotesTool::RemoveAttrNote(const TDF_Label&              theNoteLabel,
733                                   const XCAFDoc_AssemblyItemId& theItemId,
734                                   const Standard_GUID&          theGUID,
735                                   Standard_Boolean              theDelIfOrphan)
736 {
737   Handle(XCAFDoc_Note) aNote = XCAFDoc_Note::Get(theNoteLabel);
738
739   if (aNote.IsNull())
740     return Standard_False;
741
742   Handle(XCAFDoc_GraphNode) aFather;
743   if (!theNoteLabel.FindAttribute(XCAFDoc::NoteRefGUID(), aFather))
744     return Standard_False;
745
746   TDF_Label anAnnotatedItem = FindAnnotatedItemAttr(theItemId, theGUID);
747   if (anAnnotatedItem.IsNull())
748     return Standard_False;
749
750   Handle(XCAFDoc_GraphNode) aChild;
751   if (!anAnnotatedItem.FindAttribute(XCAFDoc::NoteRefGUID(), aChild))
752     return Standard_False;
753
754   aChild->UnSetFather(aFather);
755   if (aChild->NbFathers() == 0)
756     anAnnotatedItem.ForgetAllAttributes();
757
758   if (theDelIfOrphan && aNote->IsOrphan())
759     DeleteNote(theNoteLabel);
760
761   return Standard_True;
762 }
763
764 // =======================================================================
765 // function : RemoveAttrNote
766 // purpose  :
767 // =======================================================================
768 Standard_Boolean
769 XCAFDoc_NotesTool::RemoveAttrNote(const TDF_Label&     theNoteLabel,
770                                   const TDF_Label&     theItemLabel,
771                                   const Standard_GUID& theGUID,
772                                   Standard_Boolean     theDelIfOrphan)
773 {
774   return RemoveAttrNote(theNoteLabel, labeledItem(theItemLabel), theGUID, theDelIfOrphan);
775 }
776
777 // =======================================================================
778 // function : RemoveAllNotes
779 // purpose  :
780 // =======================================================================
781 Standard_Boolean
782 XCAFDoc_NotesTool::RemoveAllNotes(const XCAFDoc_AssemblyItemId& theItemId,
783                                   Standard_Boolean              theDelIfOrphan)
784 {
785   TDF_Label anAnnotatedItem = FindAnnotatedItem(theItemId);
786   if (anAnnotatedItem.IsNull())
787     return Standard_False;
788
789   Handle(XCAFDoc_GraphNode) aChild;
790   if (!anAnnotatedItem.FindAttribute(XCAFDoc::NoteRefGUID(), aChild))
791     return Standard_False;
792
793   while (aChild->NbFathers() > 0)
794   {
795     Handle(XCAFDoc_GraphNode) aFather = aChild->GetFather(1);
796     Handle(XCAFDoc_Note) aNote = XCAFDoc_Note::Get(aFather->Label());
797     if (!aNote.IsNull())
798     {
799       aFather->UnSetChild(aChild);
800       if (theDelIfOrphan && aNote->IsOrphan())
801         DeleteNote(aFather->Label());
802     }
803   }
804
805   anAnnotatedItem.ForgetAllAttributes();
806
807   return Standard_True;
808 }
809
810 // =======================================================================
811 // function : RemoveAllNotes
812 // purpose  :
813 // =======================================================================
814 Standard_Boolean
815 XCAFDoc_NotesTool::RemoveAllNotes(const TDF_Label& theItemLabel,
816                                   Standard_Boolean theDelIfOrphan)
817 {
818   return RemoveAllNotes(labeledItem(theItemLabel), theDelIfOrphan);
819 }
820
821 // =======================================================================
822 // function : RemoveAllSubshapeNotes
823 // purpose  :
824 // =======================================================================
825 Standard_Boolean
826 XCAFDoc_NotesTool::RemoveAllSubshapeNotes(const XCAFDoc_AssemblyItemId& theItemId,
827                                           Standard_Integer              theSubshapeIndex,
828                                           Standard_Boolean              theDelIfOrphan)
829 {
830   TDF_Label anAnnotatedItem = FindAnnotatedItemSubshape(theItemId, theSubshapeIndex);
831   if (anAnnotatedItem.IsNull())
832     return Standard_False;
833
834   Handle(XCAFDoc_GraphNode) aChild;
835   if (!anAnnotatedItem.FindAttribute(XCAFDoc::NoteRefGUID(), aChild))
836     return Standard_False;
837
838   while (aChild->NbFathers() > 0)
839   {
840     Handle(XCAFDoc_GraphNode) aFather = aChild->GetFather(1);
841     Handle(XCAFDoc_Note) aNote = XCAFDoc_Note::Get(aFather->Label());
842     if (!aNote.IsNull())
843     {
844       aFather->UnSetChild(aChild);
845       if (theDelIfOrphan && aNote->IsOrphan())
846         DeleteNote(aFather->Label());
847     }
848   }
849
850   anAnnotatedItem.ForgetAllAttributes();
851
852   return Standard_True;
853 }
854
855 // =======================================================================
856 // function : RemoveAllAttrNotes
857 // purpose  :
858 // =======================================================================
859 Standard_Boolean
860 XCAFDoc_NotesTool::RemoveAllAttrNotes(const XCAFDoc_AssemblyItemId& theItemId,
861                                       const Standard_GUID&          theGUID,
862                                       Standard_Boolean              theDelIfOrphan)
863 {
864   TDF_Label anAnnotatedItem = FindAnnotatedItemAttr(theItemId, theGUID);
865   if (anAnnotatedItem.IsNull())
866     return Standard_False;
867
868   Handle(XCAFDoc_GraphNode) aChild;
869   if (!anAnnotatedItem.FindAttribute(XCAFDoc::NoteRefGUID(), aChild))
870     return Standard_False;
871
872   while (aChild->NbFathers() > 0)
873   {
874     Handle(XCAFDoc_GraphNode) aFather = aChild->GetFather(1);
875     Handle(XCAFDoc_Note) aNote = XCAFDoc_Note::Get(aFather->Label());
876     if (!aNote.IsNull())
877     {
878       aFather->UnSetChild(aChild);
879       if (theDelIfOrphan && aNote->IsOrphan())
880         DeleteNote(aFather->Label());
881     }
882   }
883
884   anAnnotatedItem.ForgetAllAttributes();
885
886   return Standard_True;
887 }
888
889 // =======================================================================
890 // function : RemoveAllAttrNotes
891 // purpose  :
892 // =======================================================================
893 Standard_Boolean
894 XCAFDoc_NotesTool::RemoveAllAttrNotes(const TDF_Label&     theItemLabel,
895                                       const Standard_GUID& theGUID,
896                                       Standard_Boolean     theDelIfOrphan)
897 {
898   return RemoveAllAttrNotes(labeledItem(theItemLabel), theGUID, theDelIfOrphan);
899 }
900
901 // =======================================================================
902 // function : DeleteNote
903 // purpose  :
904 // =======================================================================
905 Standard_Boolean
906 XCAFDoc_NotesTool::DeleteNote(const TDF_Label& theNoteLabel)
907 {
908   Handle(XCAFDoc_Note) aNote = XCAFDoc_Note::Get(theNoteLabel);
909   if (!aNote.IsNull())
910   {
911     Handle(XCAFDoc_GraphNode) aFather;
912     if (theNoteLabel.FindAttribute(XCAFDoc::NoteRefGUID(), aFather) && !aFather.IsNull())
913     {
914       while (aFather->NbChildren() > 0)
915       {
916         Handle(XCAFDoc_GraphNode) aChild = aFather->GetChild(1);
917         aFather->UnSetChild(aChild);
918         if (aChild->NbFathers() == 0)
919           aChild->Label().ForgetAllAttributes(Standard_True);
920       }
921     }
922     theNoteLabel.ForgetAllAttributes(Standard_True);
923     return Standard_True;
924   }
925   return Standard_False;
926 }
927
928 // =======================================================================
929 // function : DeleteNotes
930 // purpose  :
931 // =======================================================================
932 Standard_Integer
933 XCAFDoc_NotesTool::DeleteNotes(TDF_LabelSequence& theNoteLabels)
934 {
935   Standard_Integer nbNotes = 0;
936   for (TDF_LabelSequence::Iterator anIter(theNoteLabels); anIter.More(); anIter.Next())
937   {
938     if (DeleteNote(anIter.Value()))
939       ++nbNotes;
940   }
941   return nbNotes;
942 }
943
944 // =======================================================================
945 // function : DeleteAllNotes
946 // purpose  :
947 // =======================================================================
948 Standard_Integer
949 XCAFDoc_NotesTool::DeleteAllNotes()
950 {
951   Standard_Integer nbNotes = 0;
952   for (TDF_ChildIterator anIter(GetNotesLabel()); anIter.More(); anIter.Next())
953   {
954     if (DeleteNote(anIter.Value()))
955       ++nbNotes;
956   }
957   return nbNotes;
958 }
959
960 // =======================================================================
961 // function : NbOrphanNotes
962 // purpose  :
963 // =======================================================================
964 Standard_Integer
965 XCAFDoc_NotesTool::NbOrphanNotes() const
966 {
967   Standard_Integer nbNotes = 0;
968   for (TDF_ChildIterator anIter(GetNotesLabel()); anIter.More(); anIter.Next())
969   {
970     const TDF_Label aLabel = anIter.Value();
971     Handle(XCAFDoc_Note) aNote = XCAFDoc_Note::Get(aLabel);
972     if (!aNote.IsNull() && aNote->IsOrphan())
973       ++nbNotes;
974   }
975   return nbNotes;
976 }
977
978 // =======================================================================
979 // function : GetOrphanNotes
980 // purpose  :
981 // =======================================================================
982 void
983 XCAFDoc_NotesTool::GetOrphanNotes(TDF_LabelSequence& theNoteLabels) const
984 {
985   for (TDF_ChildIterator anIter(GetNotesLabel()); anIter.More(); anIter.Next())
986   {
987     const TDF_Label aLabel = anIter.Value();
988     Handle(XCAFDoc_Note) aNote = XCAFDoc_Note::Get(aLabel);
989     if (!aNote.IsNull() && aNote->IsOrphan())
990       theNoteLabels.Append(aLabel);
991   }
992 }
993
994 // =======================================================================
995 // function : DeleteOrphanNotes
996 // purpose  :
997 // =======================================================================
998 Standard_Integer
999 XCAFDoc_NotesTool::DeleteOrphanNotes()
1000 {
1001   Standard_Integer nbNotes = 0;
1002   for (TDF_ChildIterator anIter(GetNotesLabel()); anIter.More(); anIter.Next())
1003   {
1004     const TDF_Label aLabel = anIter.Value();
1005     Handle(XCAFDoc_Note) aNote = XCAFDoc_Note::Get(aLabel);
1006     if (!aNote.IsNull() && aNote->IsOrphan() && DeleteNote(aLabel))
1007       ++nbNotes;
1008   }
1009   return nbNotes;
1010 }
1011
1012 // =======================================================================
1013 // function : ID
1014 // purpose  :
1015 // =======================================================================
1016 const Standard_GUID&
1017 XCAFDoc_NotesTool::ID() const
1018 {
1019   return GetID();
1020 }
1021
1022 // =======================================================================
1023 // function : NewEmpty
1024 // purpose  :
1025 // =======================================================================
1026 Handle(TDF_Attribute)
1027 XCAFDoc_NotesTool::NewEmpty() const
1028 {
1029   return new XCAFDoc_NotesTool();
1030 }
1031
1032 // =======================================================================
1033 // function : Restore
1034 // purpose  :
1035 // =======================================================================
1036 void
1037 XCAFDoc_NotesTool::Restore(const Handle(TDF_Attribute)& /*theAttr*/)
1038 {
1039 }
1040
1041 // =======================================================================
1042 // function : Paste
1043 // purpose  :
1044 // =======================================================================
1045 void
1046 XCAFDoc_NotesTool::Paste(const Handle(TDF_Attribute)&       /*theAttrInto*/,
1047                          const Handle(TDF_RelocationTable)& /*theRT*/) const
1048 {
1049 }
1050
1051 // =======================================================================
1052 // function : Dump
1053 // purpose  :
1054 // =======================================================================
1055 Standard_OStream&
1056 XCAFDoc_NotesTool::Dump(Standard_OStream& theOS) const
1057 {
1058   theOS
1059     << "Notes           : " << NbNotes() << "\n"
1060     << "Annotated items : " << NbAnnotatedItems() << "\n"
1061     ;
1062   return theOS;
1063 }
1064
1065 //=======================================================================
1066 //function : DumpJson
1067 //purpose  : 
1068 //=======================================================================
1069 void XCAFDoc_NotesTool::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
1070 {
1071   OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
1072
1073   OCCT_DUMP_BASE_CLASS (theOStream, theDepth, TDF_Attribute)
1074 }