42a90f4d8919100f7b40a592f1db62e8742909b1
[occt.git] / src / XDEDRAW / XDEDRAW_Notes.cxx
1 // Created on: 2017-08-09
2 // Created by: Sergey NIKONOV
3 // Copyright (c) 2016 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <DDocStd.hxx>
17 #include <OSD_File.hxx>
18 #include <OSD_Protection.hxx>
19 #include <TDocStd_Document.hxx>
20 #include <TDF_Tool.hxx>
21 #include <XCAFDoc_AssemblyItemRef.hxx>
22 #include <XCAFDoc_DocumentTool.hxx>
23 #include <XCAFDoc_Note.hxx>
24 #include <XCAFDoc_NoteBalloon.hxx>
25 #include <XCAFDoc_NoteComment.hxx>
26 #include <XCAFDoc_NoteBinData.hxx>
27 #include <XCAFDoc_NotesTool.hxx>
28 #include <XDEDRAW_Notes.hxx>
29
30 struct cmd
31 {
32   const char*      name;
33   Standard_Integer nargsreq;
34   const char*      use;
35 };
36
37 Draw_Interpretor& operator << (Draw_Interpretor& di, const cmd& c)
38 {
39   di << "Use: " << c.use << "\n";
40   return di;
41 }
42
43 Draw_Interpretor& operator << (Draw_Interpretor& di, const TDF_Label& L)
44 {
45   TCollection_AsciiString anEntry;
46   TDF_Tool::Entry(L, anEntry);
47   di << anEntry;
48   return di;
49 }
50
51 Draw_Interpretor& operator << (Draw_Interpretor& di, const Handle(XCAFDoc_Note)& note)
52 {
53   TCollection_AsciiString anEntry;
54   TDF_Tool::Entry(note->Label(), anEntry);
55   di << anEntry;
56   return di;
57 }
58
59 Draw_Interpretor& operator << (Draw_Interpretor& di, const Handle(XCAFDoc_AssemblyItemRef)& ref)
60 {
61   TCollection_AsciiString anEntry;
62   TDF_Tool::Entry(ref->Label(), anEntry);
63   di << anEntry;
64   return di;
65 }
66
67 //=======================================================================
68 //function : noteCount
69 //purpose  : returns number of annotated items, notes and orphan notes
70 //=======================================================================
71 static const cmd XNoteCount = {
72   "XNoteCount", 2, "XNoteCount Doc"
73 };
74 static Standard_Integer
75 noteCount(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
76 {
77   static const cmd& myCommand = XNoteCount;
78
79   if (argc < myCommand.nargsreq)
80   {
81     di << myCommand;
82     return 1;
83   }
84
85   Handle(TDocStd_Document) aDoc;
86   DDocStd::GetDocument(argv[1], aDoc);
87   if (aDoc.IsNull())
88   {
89     return 1;
90   }
91
92   Handle(XCAFDoc_NotesTool) aNotesTool = XCAFDoc_DocumentTool::NotesTool(aDoc->Main());
93
94   di
95     << aNotesTool->NbAnnotatedItems() << " "
96     << aNotesTool->NbNotes() << " "
97     << aNotesTool->NbOrphanNotes()
98     ;
99   return 0;
100 }
101
102 //=======================================================================
103 //function : noteNotes
104 //purpose  : returns list of all notes
105 //=======================================================================
106 static const cmd XNoteNotes = {
107   "XNoteNotes", 2, "XNoteNotes Doc"
108 };
109 static Standard_Integer
110 noteNotes(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
111 {
112   static const cmd& myCommand = XNoteNotes;
113
114   if (argc < myCommand.nargsreq)
115   {
116     di << myCommand;
117     return 1;
118   }
119
120   Handle(TDocStd_Document) aDoc;
121   DDocStd::GetDocument(argv[1], aDoc);
122   if (aDoc.IsNull())
123   {
124     return 1;
125   }
126
127   Handle(XCAFDoc_NotesTool) aNotesTool = XCAFDoc_DocumentTool::NotesTool(aDoc->Main());
128
129   TDF_LabelSequence aNotes;
130   aNotesTool->GetNotes(aNotes);
131   for (TDF_LabelSequence::Iterator anIt(aNotes); anIt.More(); anIt.Next())
132   {
133     Handle(XCAFDoc_Note) aNote = XCAFDoc_Note::Get(anIt.Value());
134     di << aNote << " ";
135   }
136
137   return 0;
138 }
139
140 //=======================================================================
141 //function : noteAnnotations
142 //purpose  : returns list of all notes
143 //=======================================================================
144 static const cmd XNoteAnnotations = {
145   "XNoteAnnotations", 2, "XNoteAnnotations Doc"
146 };
147 static Standard_Integer
148 noteAnnotations(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
149 {
150   static const cmd& myCommand = XNoteAnnotations;
151
152   if (argc < myCommand.nargsreq)
153   {
154     di << myCommand;
155     return 1;
156   }
157
158   Handle(TDocStd_Document) aDoc;
159   DDocStd::GetDocument(argv[1], aDoc);
160   if (aDoc.IsNull())
161   {
162     return 1;
163   }
164
165   Handle(XCAFDoc_NotesTool) aNotesTool = XCAFDoc_DocumentTool::NotesTool(aDoc->Main());
166
167   TDF_LabelSequence aAnnotations;
168   aNotesTool->GetAnnotatedItems(aAnnotations);
169   for (TDF_LabelSequence::Iterator anIt(aAnnotations); anIt.More(); anIt.Next())
170   {
171     Handle(XCAFDoc_AssemblyItemRef) aRef = XCAFDoc_AssemblyItemRef::Get(anIt.Value());
172     di << aRef << " ";
173   }
174
175   return 0;
176 }
177
178 //=======================================================================
179 //function : noteCreateBalloon
180 //purpose  : creates a 'balloon' note and returns a new note entry
181 //=======================================================================
182 static const cmd XNoteCreateBalloon = {
183   "XNoteCreateBalloon", 3, "XNoteCreateBalloon Doc comment [--user name] [--time stamp]"
184 };
185 static Standard_Integer
186 noteCreateBalloon(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
187 {
188   static const cmd& myCommand = XNoteCreateBalloon;
189
190   if (argc < myCommand.nargsreq)
191   {
192     di << myCommand;
193     return 1;
194   }
195
196   Standard_Integer iarg = 0;
197
198   Handle(TDocStd_Document) aDoc;
199   DDocStd::GetDocument(argv[++iarg], aDoc);
200   if (aDoc.IsNull())
201   {
202     return 1;
203   }
204
205   TCollection_ExtendedString aComment = argv[++iarg];
206   TCollection_ExtendedString aUsername, aTimestamp;
207
208   for (++iarg; iarg < argc; ++iarg)
209   {
210     TCollection_AsciiString opt = argv[iarg];
211     if (opt == "--user")
212     {
213       if (++iarg >= argc)
214       {
215         di << "Error: user name is expected.\n" << myCommand;
216         return 1;
217       }
218       aUsername = argv[iarg];
219     }
220     else if (opt == "--time")
221     {
222       if (++iarg >= argc)
223       {
224         di << "Error: timestamp is expected.\n" << myCommand;
225         return 1;
226       }
227       aTimestamp = argv[iarg];
228     }
229   }
230
231   Handle(XCAFDoc_NotesTool) aNotesTool = XCAFDoc_DocumentTool::NotesTool(aDoc->Main());
232   Handle(XCAFDoc_Note) aNote = aNotesTool->CreateBalloon(aUsername, aTimestamp, aComment);
233   if (!aNote)
234   {
235     di << "Error: couldn't create a comment note.\n";
236     return 1;
237   }
238
239   di << aNote;
240   return 0;
241 }
242
243 //=======================================================================
244 //function : noteCreateComment
245 //purpose  : creates a comment note and returns a new note entry
246 //=======================================================================
247 static const cmd XNoteCreateComment = {
248   "XNoteCreateComment", 3, "XNoteCreateComment Doc comment [--user name] [--time stamp]"
249 };
250 static Standard_Integer
251 noteCreateComment(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
252 {
253   static const cmd& myCommand = XNoteCreateComment;
254
255   if (argc < myCommand.nargsreq)
256   {
257     di << myCommand;
258     return 1;
259   }
260
261   Standard_Integer iarg = 0;
262
263   Handle(TDocStd_Document) aDoc;
264   DDocStd::GetDocument(argv[++iarg], aDoc);
265   if (aDoc.IsNull()) 
266   {
267     return 1;
268   }
269
270   TCollection_ExtendedString aComment = argv[++iarg];
271   TCollection_ExtendedString aUsername, aTimestamp;
272
273   for (++iarg; iarg < argc; ++iarg)
274   {
275     TCollection_AsciiString opt = argv[iarg];
276     if (opt == "--user")
277     {
278       if (++iarg >= argc)
279       {
280         di << "Error: user name is expected.\n" << myCommand;
281         return 1;
282       }
283       aUsername = argv[iarg];
284     }
285     else if (opt == "--time")
286     {
287       if (++iarg >= argc)
288       {
289         di << "Error: timestamp is expected.\n" << myCommand;
290         return 1;
291       }
292       aTimestamp = argv[iarg];
293     }
294   }
295
296   Handle(XCAFDoc_NotesTool) aNotesTool = XCAFDoc_DocumentTool::NotesTool(aDoc->Main());
297   Handle(XCAFDoc_Note) aNote = aNotesTool->CreateComment(aUsername, aTimestamp, aComment);
298   if (!aNote)
299   {
300     di << "Error: couldn't create a comment note.\n";
301     return 1;
302   }
303
304   di << aNote;
305   return 0;
306 }
307
308 //=======================================================================
309 //function : noteCreateBinData
310 //purpose  : creates a binary data note and returns a new note entry
311 //=======================================================================
312 static const cmd XNoteCreateBinData = {
313   "XNoteCreateBinData", 5, "XNoteCreateBinData Doc title <--file path | --data data> [--mime type] [--user name] [--time stamp]"
314 };
315 static Standard_Integer
316 noteCreateBinData(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
317 {
318   static const cmd& myCommand = XNoteCreateBinData;
319
320   if (argc < myCommand.nargsreq)
321   {
322     di << myCommand;
323     return 1;
324   }
325
326   Standard_Integer iarg = 0;
327
328   Handle(TDocStd_Document) aDoc;
329   DDocStd::GetDocument(argv[++iarg], aDoc);
330   if (aDoc.IsNull())
331   {
332     return 1;
333   }
334
335   Standard_Boolean aFromFile = Standard_False;
336   Standard_Boolean aFromData = Standard_False;
337   TCollection_ExtendedString aFilename;
338   Handle(TColStd_HArray1OfByte) aData;
339   TCollection_ExtendedString aTitle = argv[++iarg];
340   TCollection_AsciiString aMIMEtype;
341   TCollection_ExtendedString aUsername, aTimestamp;
342
343   for (++iarg; iarg < argc; ++iarg)
344   {
345     TCollection_AsciiString opt = argv[iarg];
346     if (opt == "--file")
347     {
348       if (aFromData)
349       {
350         di << "Error: data can be taken either from a file or a data array.\n" << myCommand;
351         return 1;
352       }
353       if (++iarg >= argc)
354       {
355         di << "Error: file path is expected.\n" << myCommand;
356         return 1;
357       }
358       aFilename = argv[iarg];
359       aFromFile = Standard_True;
360     }
361     else if (opt == "--data")
362     {
363       if (aFromFile)
364       {
365         di << "Error: data can be taken either from a file or a data array.\n" << myCommand;
366         return 1;
367       }
368       if (++iarg >= argc)
369       {
370         di << "Error: data array is expected.\n" << myCommand;
371         return 1;
372       }
373       Standard_SStream ss(std::ios_base::in | std::ios_base::out | std::ios_base::binary);
374       ss << argv[iarg];
375       Standard_Integer len = static_cast<Standard_Integer>(ss.tellp());
376       aData = new TColStd_HArray1OfByte(1, len);
377       for (Standard_Integer i = 1; i <= len && !ss.eof(); ++i)
378       {
379         ss >> aData->ChangeValue(i);
380       }
381       aFromData = Standard_True;
382     }
383     else if (opt == "--mime")
384     {
385       if (++iarg >= argc)
386       {
387         di << "Error: MIME type is expected.\n" << myCommand;
388         return 1;
389       }
390       aMIMEtype = argv[iarg];
391     }
392     else if (opt == "--user")
393     {
394       if (++iarg >= argc)
395       {
396         di << "Error: user name is expected.\n" << myCommand;
397         return 1;
398       }
399       aUsername = argv[iarg];
400     }
401     else if (opt == "--time")
402     {
403       if (++iarg >= argc)
404       {
405         di << "Error: timestamp is expected.\n" << myCommand;
406         return 1;
407       }
408       aTimestamp = argv[iarg];
409     }
410   }
411
412   Handle(XCAFDoc_NotesTool) aNotesTool = XCAFDoc_DocumentTool::NotesTool(aDoc->Main());
413
414   Handle(XCAFDoc_Note) aNote;
415   if (aFromFile)
416   {
417     OSD_Path aPath(aFilename);
418     OSD_File aFile(aPath);
419     aFile.Open(OSD_ReadOnly, OSD_Protection());
420     aNote = aNotesTool->CreateBinData(aUsername, aTimestamp, aTitle, aMIMEtype, aFile);
421   }
422   else if (aFromData)
423   {
424     aNote = aNotesTool->CreateBinData(aUsername, aTimestamp, aTitle, aMIMEtype, aData);
425   }
426   else
427   {
428     di << "Error: data can be taken either from a file or a data array.\n" << myCommand;
429     return 1;
430   }
431
432   if (!aNote)
433   {
434     di << "Error: couldn't create a binary data note.\n";
435     return 1;
436   }
437
438   di << aNote;
439   return 0;
440 }
441
442 //=======================================================================
443 //function : noteDelete
444 //purpose  : deletes a note by the entry
445 //=======================================================================
446 static const cmd XNoteDelete = {
447   "XNoteDelete", 3, "XNoteDelete Doc note"
448 };
449 static Standard_Integer
450 noteDelete(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
451 {
452   static const cmd& myCommand = XNoteDelete;
453
454   if (argc < myCommand.nargsreq)
455   {
456     di << myCommand;
457     return 1;
458   }
459
460   Handle(TDocStd_Document) aDoc;
461   DDocStd::GetDocument(argv[1], aDoc);
462   if (aDoc.IsNull())
463   {
464     return 1;
465   }
466
467   TCollection_ExtendedString anEntry = argv[2];
468
469   TDF_Label aLabel;
470   TDF_Tool::Label(aDoc->GetData(), anEntry, aLabel);
471   if (aLabel.IsNull())
472   {
473     di << anEntry << ": invalid note entry.\n";
474     return 1;
475   }
476
477   Handle(XCAFDoc_NotesTool) aNotesTool = XCAFDoc_DocumentTool::NotesTool(aDoc->Main());
478   if (!aNotesTool->DeleteNote(aLabel))
479   {
480     di << "Error: couldn't delete note.\n";
481     return 1;
482   }
483
484   return 0;
485 }
486
487 //=======================================================================
488 //function : noteDeleteAll
489 //purpose  : deletes all notes
490 //=======================================================================
491 static const cmd XNoteDeleteAll = {
492   "XNoteDeleteAll", 2, "XNoteDeleteAll Doc"
493 };
494 static Standard_Integer
495 noteDeleteAll(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
496 {
497   static const cmd& myCommand = XNoteDeleteAll;
498
499   if (argc < myCommand.nargsreq)
500   {
501     di << myCommand;
502     return 1;
503   }
504
505   Handle(TDocStd_Document) aDoc;
506   DDocStd::GetDocument(argv[1], aDoc);
507   if (aDoc.IsNull())
508   {
509     return 1;
510   }
511
512   Handle(XCAFDoc_NotesTool) aNotesTool = XCAFDoc_DocumentTool::NotesTool(aDoc->Main());
513   Standard_Integer nbDeleted = aNotesTool->DeleteAllNotes();
514
515   di << nbDeleted;
516   return 0;
517 }
518
519 //=======================================================================
520 //function : noteDeleteOrphan
521 //purpose  : deletes all orphan notes
522 //=======================================================================
523 static const cmd XNoteDeleteOrphan = {
524   "XNoteDeleteOrphan", 2, "XNoteDeleteOrphan Doc"
525 };
526 static Standard_Integer
527 noteDeleteOrphan(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
528 {
529   static const cmd& myCommand = XNoteDeleteOrphan;
530
531   if (argc < myCommand.nargsreq)
532   {
533     di << myCommand;
534     return 1;
535   }
536
537   Handle(TDocStd_Document) aDoc;
538   DDocStd::GetDocument(argv[1], aDoc);
539   if (aDoc.IsNull())
540   {
541     return 1;
542   }
543
544   Handle(XCAFDoc_NotesTool) aNotesTool = XCAFDoc_DocumentTool::NotesTool(aDoc->Main());
545   Standard_Integer nbDeleted = aNotesTool->DeleteOrphanNotes();
546
547   di << nbDeleted;
548   return 0;
549 }
550
551 //=======================================================================
552 //function : noteAdd
553 //purpose  : adds a note to a labeled item
554 //=======================================================================
555 static const cmd XNoteAdd = {
556   "XNoteAdd", 4, "XNoteAdd Doc note item [--attr guid | --subshape num]"
557 };
558 static Standard_Integer
559 noteAdd(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
560 {
561   static const cmd& myCommand = XNoteAdd;
562
563   if (argc < myCommand.nargsreq)
564   {
565     di << myCommand;
566     return 1;
567   }
568
569   Standard_Integer iarg = 0;
570
571   Handle(TDocStd_Document) aDoc;
572   DDocStd::GetDocument(argv[++iarg], aDoc);
573   if (aDoc.IsNull())
574   {
575     return 1;
576   }
577
578   TCollection_AsciiString aNoteEntry = argv[++iarg];
579   TCollection_AsciiString anItemEntry = argv[++iarg];
580
581   TDF_Label aNoteLabel;
582   TDF_Tool::Label(aDoc->GetData(), aNoteEntry, aNoteLabel);
583   if (aNoteLabel.IsNull())
584   {
585     di << aNoteEntry << ": invalid note entry.\n";
586     return 1;
587   }
588   XCAFDoc_AssemblyItemId anItemId(anItemEntry);
589   TDF_Label anItemLabel;
590   TDF_Tool::Label(aDoc->GetData(), anItemId.GetPath().Last(), anItemLabel);
591   if (anItemLabel.IsNull())
592   {
593     di << anItemId.ToString() << ": invalid item id.\n";
594     return 1;
595   }
596
597   Standard_GUID aGUID;
598   Standard_Integer aSubshape = 0;
599   Standard_Boolean aHasGUID = Standard_False;
600   Standard_Boolean aHasSubshape = Standard_False;
601   for (++iarg; iarg < argc; ++iarg)
602   {
603     TCollection_AsciiString opt = argv[iarg];
604     if (opt == "--attr")
605     {
606       if (aHasSubshape)
607       {
608         di << "Error: either attribute guid or subshape index must be specified.\n" << myCommand;
609         return 1;
610       }
611       if (++iarg >= argc)
612       {
613         di << "Error: attribute guid is expected.\n" << myCommand;
614         return 1;
615       }
616       TCollection_AsciiString arg = argv[iarg];
617       aGUID = arg.ToCString();
618       aHasGUID = Standard_True;
619     }
620     else if (opt == "--subshape")
621     {
622       if (++iarg >= argc)
623       {
624         di << "Error: subshape index is expected.\n" << myCommand;
625         return 1;
626       }
627       TCollection_AsciiString arg = argv[iarg];
628       if (!arg.IsIntegerValue())
629       {
630         di << "Error: subshape index must be integer value.\n" << myCommand;
631         return 1;
632       }
633       aSubshape = arg.IntegerValue();
634       aHasSubshape = Standard_True;
635     }
636   }
637
638   Handle(XCAFDoc_NotesTool) aNotesTool = XCAFDoc_DocumentTool::NotesTool(aDoc->Main());
639
640   Handle(XCAFDoc_AssemblyItemRef) aRef;
641   if (aHasGUID)
642   {
643     aRef = aNotesTool->AddNoteToAttr(aNoteLabel, anItemId, aGUID);
644   }
645   else if (aHasSubshape)
646   {
647     aRef = aNotesTool->AddNoteToSubshape(aNoteLabel, anItemId, aSubshape);
648   }
649   else
650   {
651     aRef = aNotesTool->AddNote(aNoteLabel, anItemId);
652   }
653
654   if (!aRef)
655   {
656     di << "Error: couldn't add note.\n";
657     return 1;
658   }
659
660   if (aRef->IsOrphan())
661   {
662     di << "Error: annotated item is invalid\n";
663     return 1;
664   }
665
666   di << aRef;
667   return 0;
668 }
669
670 //=======================================================================
671 //function : noteRemove
672 //purpose  : removes a note from a labeled item
673 //=======================================================================
674 static const cmd XNoteRemove = {
675   "XNoteRemove", 4, "XNoteRemove Doc item note [--attr guid | --subshape num] [--del-orphan]"
676 };
677 static Standard_Integer
678 noteRemove(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
679 {
680   static const cmd& myCommand = XNoteRemove;
681
682   if (argc < myCommand.nargsreq)
683   {
684     di << myCommand;
685     return 1;
686   }
687
688   Standard_Integer iarg = 0;
689
690   Handle(TDocStd_Document) aDoc;
691   DDocStd::GetDocument(argv[++iarg], aDoc);
692   if (aDoc.IsNull())
693   {
694     return 1;
695   }
696
697   TCollection_AsciiString anItemEntry = argv[++iarg];
698   TCollection_AsciiString aNoteEntry = argv[++iarg];
699
700   TDF_Label aNoteLabel;
701   TDF_Tool::Label(aDoc->GetData(), aNoteEntry, aNoteLabel);
702   if (aNoteLabel.IsNull())
703   {
704     di << aNoteEntry << ": invalid note entry.\n";
705     return 1;
706   }
707   XCAFDoc_AssemblyItemId anItemId(anItemEntry);
708   TDF_Label anItemLabel;
709   TDF_Tool::Label(aDoc->GetData(), anItemId.GetPath().Last(), anItemLabel);
710   if (anItemLabel.IsNull())
711   {
712     di << anItemId.ToString() << ": invalid item id.\n";
713     return 1;
714   }
715
716   Standard_GUID aGUID;
717   Standard_Integer aSubshape = 0;
718   Standard_Boolean aHasGUID = Standard_False;
719   Standard_Boolean aHasSubshape = Standard_False;
720   Standard_Boolean aDelOrphan = Standard_False;
721   for (++iarg; iarg < argc; ++iarg)
722   {
723     TCollection_AsciiString opt = argv[iarg];
724     if (opt == "--attr")
725     {
726       if (aHasSubshape)
727       {
728         di << "Error: either attribute guid or subshape index must be specified.\n" << myCommand;
729         return 1;
730       }
731       if (++iarg >= argc)
732       {
733         di << "Error: attribute guid is expected.\n" << myCommand;
734         return 1;
735       }
736       TCollection_AsciiString arg = argv[iarg];
737       aGUID = arg.ToCString();
738       aHasGUID = Standard_True;
739     }
740     else if (opt == "--subshape")
741     {
742       if (aHasGUID)
743       {
744         di << "Error: either attribute guid or subshape index must be specified.\n" << myCommand;
745         return 1;
746       }
747       if (++iarg >= argc)
748       {
749         di << "Error: subshape index is expected.\n" << myCommand;
750         return 1;
751       }
752       TCollection_AsciiString arg = argv[iarg];
753       if (!arg.IsIntegerValue())
754       {
755         di << "Error: subshape index must be integer value.\n" << myCommand;
756         return 1;
757       }
758       aSubshape = arg.IntegerValue();
759       aHasSubshape = Standard_True;
760     }
761     else if (opt == "--del-orphan")
762     {
763       aDelOrphan = Standard_True;
764     }
765   }
766
767   Handle(XCAFDoc_NotesTool) aNotesTool = XCAFDoc_DocumentTool::NotesTool(aDoc->Main());
768
769   if (aHasGUID)
770   {
771     di << aNotesTool->RemoveAttrNote(aNoteLabel, anItemId, aGUID, aDelOrphan);
772   }
773   else if (aHasSubshape)
774   {
775     di << aNotesTool->RemoveSubshapeNote(aNoteLabel, anItemId, aSubshape, aDelOrphan);
776   }
777   else
778   {
779     di << aNotesTool->RemoveNote(aNoteLabel, anItemId, aDelOrphan);
780   }
781
782   return 0;
783 }
784
785 //=======================================================================
786 //function : noteRemoveAll
787 //purpose  : removes all notes from a labeled item
788 //=======================================================================
789 static const cmd XNoteRemoveAll = {
790   "XNoteRemoveAll", 3, "XNoteRemoveAll Doc item [--attr guid] [--subshape num] [--del-orphan]"
791 };
792 static Standard_Integer
793 noteRemoveAll(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
794 {
795   static const cmd& myCommand = XNoteRemoveAll;
796
797   if (argc < myCommand.nargsreq)
798   {
799     di << myCommand;
800     return 1;
801   }
802
803   Standard_Integer iarg = 0;
804
805   Handle(TDocStd_Document) aDoc;
806   DDocStd::GetDocument(argv[++iarg], aDoc);
807   if (aDoc.IsNull())
808   {
809     return 1;
810   }
811
812   TCollection_AsciiString anItemEntry = argv[++iarg];
813
814   XCAFDoc_AssemblyItemId anItemId(anItemEntry);
815   TDF_Label anItemLabel;
816   TDF_Tool::Label(aDoc->GetData(), anItemId.GetPath().Last(), anItemLabel);
817   if (anItemLabel.IsNull())
818   {
819     di << anItemId.ToString() << ": invalid item id.\n";
820     return 1;
821   }
822
823   Standard_GUID aGUID;
824   Standard_Integer aSubshape = 0;
825   Standard_Boolean aHasGUID = Standard_False;
826   Standard_Boolean aHasSubshape = Standard_False;
827   Standard_Boolean aDelOrphan = Standard_False;
828   for (++iarg; iarg < argc; ++iarg)
829   {
830     TCollection_AsciiString opt = argv[iarg];
831     if (opt == "--attr")
832     {
833       if (aHasSubshape)
834       {
835         di << "Error: either attribute guid or subshape index must be specified.\n" << myCommand;
836         return 1;
837       }
838       if (++iarg >= argc)
839       {
840         di << "Error: attribute guid is expected.\n" << myCommand;
841         return 1;
842       }
843       TCollection_AsciiString arg = argv[iarg];
844       aGUID = arg.ToCString();
845       aHasGUID = Standard_True;
846     }
847     else if (opt == "--subshape")
848     {
849       if (aHasGUID)
850       {
851         di << "Error: either attribute guid or subshape index must be specified.\n" << myCommand;
852         return 1;
853       }
854       if (++iarg >= argc)
855       {
856         di << "Error: subshape index is expected.\n" << myCommand;
857         return 1;
858       }
859       TCollection_AsciiString arg = argv[iarg];
860       if (!arg.IsIntegerValue())
861       {
862         di << "Error: subshape index must be integer value.\n" << myCommand;
863         return 1;
864       }
865       aSubshape = arg.IntegerValue();
866       aHasSubshape = Standard_True;
867     }
868     else if (opt == "--del-orphan")
869     {
870       aDelOrphan = Standard_True;
871     }
872   }
873
874   Handle(XCAFDoc_NotesTool) aNotesTool = XCAFDoc_DocumentTool::NotesTool(aDoc->Main());
875
876   if (aHasGUID)
877   {
878     di << aNotesTool->RemoveAllAttrNotes(anItemId, aGUID, aDelOrphan);
879   }
880   else if (aHasSubshape)
881   {
882     di << aNotesTool->RemoveAllSubshapeNotes(anItemId, aSubshape, aDelOrphan);
883   }
884   else
885   {
886     di << aNotesTool->RemoveAllNotes(anItemId, aDelOrphan);
887   }
888
889   return 0;
890 }
891
892 //=======================================================================
893 //function : noteFindAnnotated
894 //purpose  : find a label of the annotated item
895 //=======================================================================
896 static const cmd XNoteFindAnnotated = {
897   "XNoteFindAnnotated", 3, "XNoteFindAnnotated Doc item [--attr guid | --subshape num]"
898 };
899 static Standard_Integer
900 noteFindAnnotated(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
901 {
902   static const cmd& myCommand = XNoteFindAnnotated;
903
904   if (argc < myCommand.nargsreq)
905   {
906     di << myCommand;
907     return 1;
908   }
909
910   Standard_Integer iarg = 0;
911
912   Handle(TDocStd_Document) aDoc;
913   DDocStd::GetDocument(argv[++iarg], aDoc);
914   if (aDoc.IsNull())
915   {
916     return 1;
917   }
918
919   TCollection_AsciiString anItemEntry = argv[++iarg];
920
921   XCAFDoc_AssemblyItemId anItemId(anItemEntry);
922   TDF_Label anItemLabel;
923   TDF_Tool::Label(aDoc->GetData(), anItemId.GetPath().Last(), anItemLabel);
924   if (anItemLabel.IsNull())
925   {
926     di << anItemId.ToString() << ": invalid item id.\n";
927     return 1;
928   }
929
930   Standard_GUID aGUID;
931   Standard_Integer aSubshape = 0;
932   Standard_Boolean aHasGUID = Standard_False;
933   Standard_Boolean aHasSubshape = Standard_False;
934   for (++iarg; iarg < argc; ++iarg)
935   {
936     TCollection_AsciiString opt = argv[iarg];
937     if (opt == "--attr")
938     {
939       if (aHasSubshape)
940       {
941         di << "Error: either attribute guid or subshape index must be specified.\n" << myCommand;
942         return 1;
943       }
944       if (++iarg >= argc)
945       {
946         di << "Error: attribute guid is expected.\n" << myCommand;
947         return 1;
948       }
949       TCollection_AsciiString arg = argv[iarg];
950       aGUID = arg.ToCString();
951       aHasGUID = Standard_True;
952     }
953     else if (opt == "--subshape")
954     {
955       if (++iarg >= argc)
956       {
957         di << "Error: subshape index is expected.\n" << myCommand;
958         return 1;
959       }
960       TCollection_AsciiString arg = argv[iarg];
961       if (!arg.IsIntegerValue())
962       {
963         di << "Error: subshape index must be integer value.\n" << myCommand;
964         return 1;
965       }
966       aSubshape = arg.IntegerValue();
967       aHasSubshape = Standard_True;
968     }
969   }
970
971   Handle(XCAFDoc_NotesTool) aNotesTool = XCAFDoc_DocumentTool::NotesTool(aDoc->Main());
972
973   if (aHasGUID)
974   {
975     di << aNotesTool->FindAnnotatedItemAttr(anItemId, aGUID);
976   }
977   else if (aHasSubshape)
978   {
979     di << aNotesTool->FindAnnotatedItemSubshape(anItemId, aSubshape);
980   }
981   else
982   {
983     di << aNotesTool->FindAnnotatedItem(anItemId);
984   }
985
986   return 0;
987 }
988
989 //=======================================================================
990 //function : noteGetNotes
991 //purpose  : get notes of the labeled item
992 //=======================================================================
993 static const cmd XNoteGetNotes = {
994   "XNoteGetNotes", 3, "XNoteGetNotes Doc item [--attr guid | --subshape num]"
995 };
996 static Standard_Integer
997 noteGetNotes(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
998 {
999   static const cmd& myCommand = XNoteGetNotes;
1000
1001   if (argc < myCommand.nargsreq)
1002   {
1003     di << myCommand;
1004     return 1;
1005   }
1006
1007   Standard_Integer iarg = 0;
1008
1009   Handle(TDocStd_Document) aDoc;
1010   DDocStd::GetDocument(argv[++iarg], aDoc);
1011   if (aDoc.IsNull())
1012   {
1013     return 1;
1014   }
1015
1016   TCollection_AsciiString anItemEntry = argv[++iarg];
1017
1018   XCAFDoc_AssemblyItemId anItemId(anItemEntry);
1019   TDF_Label anItemLabel;
1020   TDF_Tool::Label(aDoc->GetData(), anItemId.GetPath().Last(), anItemLabel);
1021   if (anItemLabel.IsNull())
1022   {
1023     di << anItemId.ToString() << ": invalid item id.\n";
1024     return 1;
1025   }
1026
1027   Standard_GUID aGUID;
1028   Standard_Integer aSubshape = 0;
1029   Standard_Boolean aHasGUID = Standard_False;
1030   Standard_Boolean aHasSubshape = Standard_False;
1031   for (++iarg; iarg < argc; ++iarg)
1032   {
1033     TCollection_AsciiString opt = argv[iarg];
1034     if (opt == "--attr")
1035     {
1036       if (aHasSubshape)
1037       {
1038         di << "Error: either attribute guid or subshape index must be specified.\n" << myCommand;
1039         return 1;
1040       }
1041       if (++iarg >= argc)
1042       {
1043         di << "Error: attribute guid is expected.\n" << myCommand;
1044         return 1;
1045       }
1046       TCollection_AsciiString arg = argv[iarg];
1047       aGUID = arg.ToCString();
1048       aHasGUID = Standard_True;
1049     }
1050     else if (opt == "--subshape")
1051     {
1052       if (++iarg >= argc)
1053       {
1054         di << "Error: subshape index is expected.\n" << myCommand;
1055         return 1;
1056       }
1057       TCollection_AsciiString arg = argv[iarg];
1058       if (!arg.IsIntegerValue())
1059       {
1060         di << "Error: subshape index must be integer value.\n" << myCommand;
1061         return 1;
1062       }
1063       aSubshape = arg.IntegerValue();
1064       aHasSubshape = Standard_True;
1065     }
1066   }
1067
1068   Handle(XCAFDoc_NotesTool) aNotesTool = XCAFDoc_DocumentTool::NotesTool(aDoc->Main());
1069
1070   TDF_LabelSequence aNotes;
1071   if (aHasGUID)
1072   {
1073     aNotesTool->GetAttrNotes(anItemId, aGUID, aNotes);
1074   }
1075   else if (aHasSubshape)
1076   {
1077     aNotesTool->GetSubshapeNotes(anItemId, aSubshape, aNotes);
1078   }
1079   else
1080   {
1081     aNotesTool->GetNotes(anItemId, aNotes);
1082   }
1083
1084   for (TDF_LabelSequence::Iterator anIt(aNotes); anIt.More(); anIt.Next())
1085   {
1086     di << anIt.Value() << " ";
1087   }
1088
1089   return 0;
1090 }
1091
1092 //=======================================================================
1093 //function : noteUsername
1094 //purpose  : gets a note username
1095 //=======================================================================
1096 static const cmd XNoteUsername = {
1097   "XNoteUsername", 3, "XNoteUsername Doc note"
1098 };
1099 static Standard_Integer
1100 noteUsername(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1101 {
1102   static const cmd& myCommand = XNoteUsername;
1103
1104   if (argc < myCommand.nargsreq)
1105   {
1106     di << myCommand;
1107     return 1;
1108   }
1109
1110   Standard_Integer iarg = 0;
1111
1112   Handle(TDocStd_Document) aDoc;
1113   DDocStd::GetDocument(argv[++iarg], aDoc);
1114   if (aDoc.IsNull())
1115   {
1116     return 1;
1117   }
1118
1119   TCollection_AsciiString aNoteEntry = argv[++iarg];
1120
1121   TDF_Label aNoteLabel;
1122   TDF_Tool::Label(aDoc->GetData(), aNoteEntry, aNoteLabel);
1123   if (aNoteLabel.IsNull())
1124   {
1125     di << aNoteEntry << ": invalid note entry.\n";
1126     return 1;
1127   }
1128
1129   Handle(XCAFDoc_Note) aNote = XCAFDoc_Note::Get(aNoteLabel);
1130   if (aNote.IsNull())
1131   {
1132     di << aNoteEntry << ": not a note entry.\n";
1133     return 1;
1134   }
1135
1136   di << aNote->UserName();
1137
1138   return 0;
1139 }
1140
1141 //=======================================================================
1142 //function : noteTimestamp
1143 //purpose  : gets a note timestamp
1144 //=======================================================================
1145 static const cmd XNoteTimestamp = {
1146   "XNoteTimestamp", 3, "XNoteTimestamp Doc note"
1147 };
1148 static Standard_Integer
1149 noteTimestamp(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1150 {
1151   static const cmd& myCommand = XNoteTimestamp;
1152
1153   if (argc < myCommand.nargsreq)
1154   {
1155     di << myCommand;
1156     return 1;
1157   }
1158
1159   Standard_Integer iarg = 0;
1160
1161   Handle(TDocStd_Document) aDoc;
1162   DDocStd::GetDocument(argv[++iarg], aDoc);
1163   if (aDoc.IsNull())
1164   {
1165     return 1;
1166   }
1167
1168   TCollection_AsciiString aNoteEntry = argv[++iarg];
1169
1170   TDF_Label aNoteLabel;
1171   TDF_Tool::Label(aDoc->GetData(), aNoteEntry, aNoteLabel);
1172   if (aNoteLabel.IsNull())
1173   {
1174     di << aNoteEntry << ": invalid note entry.\n";
1175     return 1;
1176   }
1177
1178   Handle(XCAFDoc_Note) aNote = XCAFDoc_Note::Get(aNoteLabel);
1179   if (aNote.IsNull())
1180   {
1181     di << aNoteEntry << ": not a note entry.\n";
1182     return 1;
1183   }
1184
1185   di << aNote->TimeStamp();
1186
1187   return 0;
1188 }
1189
1190 //=======================================================================
1191 //function : noteDump
1192 //purpose  : dump a note contents
1193 //=======================================================================
1194 static const cmd XNoteDump = {
1195   "XNoteDump", 3, "XNoteDump Doc note"
1196 };
1197 static Standard_Integer
1198 noteDump(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1199 {
1200   static const cmd& myCommand = XNoteDump;
1201
1202   if (argc < myCommand.nargsreq)
1203   {
1204     di << myCommand;
1205     return 1;
1206   }
1207
1208   Standard_Integer iarg = 0;
1209
1210   Handle(TDocStd_Document) aDoc;
1211   DDocStd::GetDocument(argv[++iarg], aDoc);
1212   if (aDoc.IsNull())
1213   {
1214     return 1;
1215   }
1216
1217   TCollection_AsciiString aNoteEntry = argv[++iarg];
1218
1219   TDF_Label aNoteLabel;
1220   TDF_Tool::Label(aDoc->GetData(), aNoteEntry, aNoteLabel);
1221   if (aNoteLabel.IsNull())
1222   {
1223     di << aNoteEntry << ": invalid note entry.\n";
1224     return 1;
1225   }
1226
1227   Handle(XCAFDoc_Note) aNote = XCAFDoc_Note::Get(aNoteLabel);
1228   if (aNote.IsNull())
1229   {
1230     di << aNoteEntry << ": not a note entry.\n";
1231     return 1;
1232   }
1233
1234   di << "Username  : " << aNote->UserName() << "\n";
1235   di << "Timestamp : " << aNote->TimeStamp() << "\n";
1236   di << "Type      : " << aNote->get_type_name() << "\n";
1237   if (Handle(XCAFDoc_NoteComment) aComment = Handle(XCAFDoc_NoteComment)::DownCast(aNote))
1238   {
1239     di << "Comment   : " << aComment->Comment() << "\n";
1240   }
1241   else if (Handle(XCAFDoc_NoteBalloon) aBalloon = Handle(XCAFDoc_NoteBalloon)::DownCast(aNote))
1242   {
1243     di << "Comment   : " << aBalloon->Comment() << "\n";
1244   }
1245   else if (Handle(XCAFDoc_NoteBinData) aBinData = Handle(XCAFDoc_NoteBinData)::DownCast(aNote))
1246   {
1247     di << "Title     : " << aBinData->Title() << "\n";
1248     di << "MIME type : " << aBinData->MIMEtype() << "\n";
1249     di << "Size      : " << aBinData->Size() << "\n";
1250     static Standard_Integer theMaxLen = 64;
1251     const Handle(TColStd_HArray1OfByte)& aData = aBinData->Data();
1252     if (!aData.IsNull())
1253     {
1254       di << "Data      : ";
1255       Standard_Integer aLen = Min(aData->Length(), theMaxLen);
1256       for (Standard_Integer i = 1; i <= aLen; ++i)
1257       {
1258         Standard_SStream ss; ss << aData->Value(i);
1259         di << ss.str().c_str();
1260       }
1261       if (aData->Length() > theMaxLen)
1262         di << "  ...";
1263       di << "\n";
1264     }
1265   }
1266
1267   Handle(XCAFNoteObjects_NoteObject) aNoteObj = aNote->GetObject();
1268   if (!aNoteObj.IsNull())
1269   {
1270     di << "text point : ";
1271     if (aNoteObj->HasPointText())
1272     {
1273       const gp_Pnt& aP = aNoteObj->GetPointText();
1274       di << "[ " << aP.X() << " " << aP.Y() << " " << aP.Z() << " ]\n";
1275     }
1276     else
1277       di << " not specified\n";
1278     di << "plane : ";
1279     if (aNoteObj->HasPlane())
1280     {
1281       const gp_Ax2& anAx = aNoteObj->GetPlane();
1282       const gp_Pnt& aP = anAx.Location();
1283       di << "P : [ " << aP.X() << " " << aP.Y() << " " << aP.Z() << " ]";
1284       const gp_Dir& aN = anAx.Direction();
1285       di << "N : [ " << aN.X() << " " << aN.Y() << " " << aN.Z() << " ]";
1286     }
1287     di << "attachment point : ";
1288     if (aNoteObj->HasPoint())
1289     {
1290       const gp_Pnt& aP = aNoteObj->GetPoint();
1291       di << "[ " << aP.X() << " " << aP.Y() << " " << aP.Z() << " ]\n";
1292     }
1293     else
1294       di << " not specified\n";
1295     di << "presentation : " << (aNoteObj->GetPresentation().IsNull() ? "no" : "specified");
1296   }
1297
1298   return 0;
1299 }
1300
1301 //=======================================================================
1302 //function : noteIsRefOrphan
1303 //purpose  : checks if a ref is orphan
1304 //=======================================================================
1305 static const cmd XNoteRefDump = {
1306   "XNoteRefDump", 3, "XNoteRefDump Doc ref"
1307 };
1308 static Standard_Integer
1309 noteRefDump(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1310 {
1311   static const cmd& myCommand = XNoteRefDump;
1312
1313   if (argc < myCommand.nargsreq)
1314   {
1315     di << myCommand;
1316     return 1;
1317   }
1318
1319   Standard_Integer iarg = 0;
1320
1321   Handle(TDocStd_Document) aDoc;
1322   DDocStd::GetDocument(argv[++iarg], aDoc);
1323   if (aDoc.IsNull())
1324   {
1325     return 1;
1326   }
1327
1328   TCollection_AsciiString aRefEntry = argv[++iarg];
1329
1330   TDF_Label aRefLabel;
1331   TDF_Tool::Label(aDoc->GetData(), aRefEntry, aRefLabel);
1332   if (aRefLabel.IsNull())
1333   {
1334     di << aRefEntry << ": invalid reference entry.\n";
1335     return 1;
1336   }
1337
1338   Handle(XCAFDoc_AssemblyItemRef) aRef = XCAFDoc_AssemblyItemRef::Get(aRefLabel);
1339   if (aRef.IsNull())
1340   {
1341     di << aRefEntry << ": not a reference entry.\n";
1342     return 1;
1343   }
1344
1345   di << "Item      : " << aRef->GetItem().ToString() << "\n";
1346   if (aRef->HasExtraRef())
1347   {
1348     if (aRef->IsGUID())
1349     {
1350       Standard_SStream ss; 
1351       aRef->GetGUID().ShallowDump(ss);
1352       di << "Attribute : " << ss.str().c_str() << "\n";
1353     }
1354     else if (aRef->IsSubshapeIndex())
1355       di << "Subshape  : " << aRef->GetSubshapeIndex() << "\n";
1356   }
1357   di << "Orphan    : " << (aRef->IsOrphan() ? "yes" : "no") << "\n";
1358
1359   return 0;
1360 }
1361
1362 //=======================================================================
1363 //function : noteIsRefOrphan
1364 //purpose  : checks if a ref is orphan
1365 //=======================================================================
1366 static const cmd XNoteIsRefOrphan = {
1367   "XNoteIsRefOrphan", 3, "XNoteIsRefOrphan Doc ref"
1368 };
1369 static Standard_Integer
1370 noteIsRefOrphan(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
1371 {
1372   static const cmd& myCommand = XNoteIsRefOrphan;
1373
1374   if (argc < myCommand.nargsreq)
1375   {
1376     di << myCommand;
1377     return 1;
1378   }
1379
1380   Standard_Integer iarg = 0;
1381
1382   Handle(TDocStd_Document) aDoc;
1383   DDocStd::GetDocument(argv[++iarg], aDoc);
1384   if (aDoc.IsNull())
1385   {
1386     return 1;
1387   }
1388
1389   TCollection_AsciiString aRefEntry = argv[++iarg];
1390
1391   TDF_Label aRefLabel;
1392   TDF_Tool::Label(aDoc->GetData(), aRefEntry, aRefLabel);
1393   if (aRefLabel.IsNull())
1394   {
1395     di << aRefEntry << ": invalid reference entry.\n";
1396     return 1;
1397   }
1398
1399   Handle(XCAFDoc_AssemblyItemRef) aRef = XCAFDoc_AssemblyItemRef::Get(aRefLabel);
1400   if (aRef.IsNull())
1401   {
1402     di << aRefEntry << ": not a reference entry.\n";
1403     return 1;
1404   }
1405
1406   di << aRef->IsOrphan();
1407
1408   return 0;
1409 }
1410
1411 //=======================================================================
1412 //function : InitCommands
1413 //purpose  : 
1414 //=======================================================================
1415 void XDEDRAW_Notes::InitCommands(Draw_Interpretor& di) 
1416 {
1417   static Standard_Boolean initialized = Standard_False;
1418   if (initialized)
1419   {
1420     return;
1421   }
1422   initialized = Standard_True;
1423   
1424   Standard_CString g = "XDE Notes commands";
1425
1426   di.Add(XNoteCount.name, XNoteCount.use,
1427     __FILE__, noteCount, g);
1428   di.Add(XNoteNotes.name, XNoteNotes.use,
1429     __FILE__, noteNotes, g);
1430   di.Add(XNoteAnnotations.name, XNoteAnnotations.use,
1431     __FILE__, noteAnnotations, g);
1432
1433   di.Add(XNoteCreateBalloon.name, XNoteCreateBalloon.use,
1434     __FILE__, noteCreateBalloon, g);
1435   di.Add(XNoteCreateComment.name, XNoteCreateComment.use,
1436     __FILE__, noteCreateComment, g);
1437   di.Add(XNoteCreateBinData.name, XNoteCreateBinData.use,
1438     __FILE__, noteCreateBinData, g);
1439   di.Add(XNoteDelete.name, XNoteDelete.use,
1440     __FILE__, noteDelete, g);
1441   di.Add(XNoteDeleteAll.name, XNoteDeleteAll.use,
1442     __FILE__, noteDeleteAll, g);
1443   di.Add(XNoteDeleteOrphan.name, XNoteDeleteOrphan.use,
1444     __FILE__, noteDeleteOrphan, g);
1445
1446   di.Add(XNoteAdd.name, XNoteAdd.use,
1447     __FILE__, noteAdd, g);
1448   di.Add(XNoteRemove.name, XNoteRemove.use,
1449     __FILE__, noteRemove, g);
1450   di.Add(XNoteRemoveAll.name, XNoteRemoveAll.use,
1451     __FILE__, noteRemoveAll, g);
1452
1453   di.Add(XNoteFindAnnotated.name, XNoteFindAnnotated.use,
1454     __FILE__, noteFindAnnotated, g);
1455   di.Add(XNoteGetNotes.name, XNoteGetNotes.use,
1456     __FILE__, noteGetNotes, g);
1457
1458   di.Add(XNoteUsername.name, XNoteUsername.use,
1459     __FILE__, noteUsername, g);
1460   di.Add(XNoteTimestamp.name, XNoteTimestamp.use,
1461     __FILE__, noteTimestamp, g);
1462   di.Add(XNoteDump.name, XNoteDump.use,
1463     __FILE__, noteDump, g);
1464
1465   di.Add(XNoteRefDump.name, XNoteRefDump.use,
1466     __FILE__, noteRefDump, g);
1467   di.Add(XNoteIsRefOrphan.name, XNoteIsRefOrphan.use,
1468     __FILE__, noteIsRefOrphan, g);
1469 }