0031918: Application Framework - New binary format for fast reading part of OCAF...
[occt.git] / src / DDocStd / DDocStd_ApplicationCommands.cxx
1 // Created on: 2000-03-01
2 // Created by: Denis PASCAL
3 // Copyright (c) 2000-2014 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 <Draw.hxx>
18 #include <Draw_Interpretor.hxx>
19 #include <Draw_Viewer.hxx>
20 #include <Draw_ProgressIndicator.hxx>
21 #include <DDocStd_DrawDocument.hxx>
22 #include <TDocStd_Application.hxx>
23 #include <TDocStd_Document.hxx>
24 #include <TDataStd_Name.hxx>
25 #include <Draw.hxx>
26 #include <Standard_GUID.hxx>
27 #include <Standard_ExtString.hxx>
28 #include <TCollection_AsciiString.hxx>
29 #include <TCollection_ExtendedString.hxx>
30 #include <TDF.hxx>
31 #include <TDF_Data.hxx>
32 #include <TDF_ChildIterator.hxx>
33 #include <TDF_Tool.hxx> 
34 #include <PCDM_ReaderFilter.hxx>
35
36 #include <OSD_Path.hxx>
37 #include <OSD_OpenFile.hxx>
38 #include <TDocStd_PathParser.hxx>
39 #include <XmlLDrivers.hxx>
40
41 #include <AIS_InteractiveContext.hxx>
42 #include <TPrsStd_AISViewer.hxx>
43 #include <ViewerTest.hxx>
44 #include <V3d_Viewer.hxx>
45
46 #ifndef _WIN32
47 extern Draw_Viewer dout;
48 #else
49 Standard_IMPORT Draw_Viewer dout;
50 #endif
51
52 //=======================================================================
53 //function : ListDocuments
54 //purpose  : 
55 //=======================================================================
56
57 static Standard_Integer DDocStd_ListDocuments (Draw_Interpretor& di,
58                                                Standard_Integer nb,
59                                                const char** /*a*/)
60 {  
61   if (nb == 1) {
62     Handle(TDocStd_Application) A = DDocStd::GetApplication();
63     Handle(TDocStd_Document) D;
64     Standard_Integer nbdoc = A->NbDocuments();
65     for (Standard_Integer i = 1; i <= nbdoc; i++) {
66       A->GetDocument(i,D);
67       di <<"document " << i;
68       if (D->IsSaved()) {
69         di << " name : " << D->GetName();
70         di << " path : " << D->GetPath();
71       }
72       else di << " not saved";
73       di << "\n";
74     }
75     return 0;
76   }
77   di << "DDocStd_ListDocuments : Error\n";
78   return 1; 
79 }
80
81
82 //=======================================================================
83 //function : NewDocument
84 //purpose  : 
85 //=======================================================================
86
87 static Standard_Integer DDocStd_NewDocument (Draw_Interpretor& di,
88                                              Standard_Integer nb,
89                                              const char** a)
90 {    
91   Handle(TDocStd_Document) D; 
92   Handle(DDocStd_DrawDocument) DD;
93   if (nb == 2) {
94     if (!DDocStd::GetDocument(a[1],D,Standard_False)) { 
95       D = new TDocStd_Document("dummy");  
96       DD = new DDocStd_DrawDocument(D);  
97       Draw::Set(a[1],DD);       
98       di << "document (not handled by application)  " << a[1] << " created\n";  
99       DDocStd::ReturnLabel(di,D->Main()); 
100     }    
101     else di << a[1] << " is already a document\n";
102     return 0;
103   }
104   if (nb == 3) {   
105     if (!DDocStd::GetDocument(a[1],D,Standard_False)) {  
106       Handle(TDocStd_Application) A = DDocStd::GetApplication();
107       A->NewDocument(a[2],D);  
108       DD = new DDocStd_DrawDocument(D);  
109       TDataStd_Name::Set(D->GetData()->Root(),a[1]);  
110       Draw::Set(a[1],DD);    
111       di << "document " << a[1] << " created\n";    
112       DDocStd::ReturnLabel(di,D->Main()); 
113     }
114     else di << a[1] << " is already a document\n";
115     return 0;
116   }   
117   di << "DDocStd_NewDocument : Error\n";
118   return 1;
119 }
120
121 //=======================================================================
122 //function : Open
123 //purpose  : 
124 //=======================================================================
125
126 static Standard_Integer DDocStd_Open (Draw_Interpretor& di,
127                                       Standard_Integer nb,
128                                       const char** a)
129 {   
130   if (nb >= 3) {
131     TCollection_ExtendedString path (a[1], Standard_True); 
132     Standard_CString DocName = a[2];
133     Handle(TDocStd_Application) A = DDocStd::GetApplication();
134     Handle(TDocStd_Document) D;
135     PCDM_ReaderStatus theStatus;
136
137     Standard_Boolean anUseStream = Standard_False;
138     Handle(PCDM_ReaderFilter) aFilter = new PCDM_ReaderFilter;
139     for ( Standard_Integer i = 3; i < nb; i++ )
140     {
141       TCollection_AsciiString anArg(a[i]);
142       if (anArg == "-append")
143       {
144         aFilter->Mode() = PCDM_ReaderFilter::AppendMode_Protect;
145       }
146       else if (anArg == "-overwrite")
147       {
148         aFilter->Mode() = PCDM_ReaderFilter::AppendMode_Overwrite;
149       }
150       else if (anArg == "-stream")
151       {
152         di << "standard SEEKABLE stream is used\n";
153         anUseStream = Standard_True;
154       }
155       else if (anArg.StartsWith("-skip"))
156       {
157         TCollection_AsciiString anAttrType = anArg.SubString(6, anArg.Length());
158         aFilter->AddSkipped(anAttrType);
159       }
160       else if (anArg.StartsWith("-read"))
161       {
162         TCollection_AsciiString aValue = anArg.SubString(6, anArg.Length());
163         if (aValue.Value(1) == '0') // path
164         {
165           aFilter->AddPath(aValue);
166         }
167         else // attribute to read
168         {
169           aFilter->AddRead(aValue);
170         }
171       }
172     }
173
174     if (aFilter->IsAppendMode() && !DDocStd::GetDocument(DocName, D, Standard_False))
175     {
176       di << "for append mode document " << DocName << " must be already created\n";
177       return 1;
178     }
179     Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator(di, 1);
180     if (anUseStream)
181     {
182       std::ifstream aFileStream;
183       OSD_OpenStream (aFileStream, path, std::ios::in | std::ios::binary);
184
185       theStatus = A->Open (aFileStream, D, aFilter, aProgress->Start());
186     }
187     else
188     {
189       theStatus = A->Open (path, D, aFilter , aProgress->Start());
190     }
191     if (theStatus == PCDM_RS_OK && !D.IsNull())
192     {
193       if (!aFilter->IsAppendMode())
194       {
195         Handle(DDocStd_DrawDocument) DD = new DDocStd_DrawDocument (D);
196         TDataStd_Name::Set (D->GetData()->Root(), DocName);
197         Draw::Set (DocName, DD);
198       }
199       return 0; 
200     } 
201     else
202     {
203       switch ( theStatus ) {
204       case PCDM_RS_UserBreak: {
205         di << " could not retrieve , user break \n";
206         break;
207       }
208       case PCDM_RS_AlreadyRetrieved: 
209       case PCDM_RS_AlreadyRetrievedAndModified: {
210         di << " already retrieved \n" ;  
211         break;
212       }
213       case PCDM_RS_NoDriver: {
214         di << " could not retrieve , no Driver to make it \n" ;
215         break ;
216       }
217       case PCDM_RS_UnknownDocument:
218       case PCDM_RS_NoModel: {
219         di << " could not retrieve , Unknown Document or No Model \n";
220         break ; 
221       }
222       case PCDM_RS_TypeNotFoundInSchema:
223       case PCDM_RS_UnrecognizedFileFormat: {
224         di << " could not retrieve , Type not found or Unrecognized File Format\n";
225         break ;
226       }
227       case PCDM_RS_PermissionDenied: {
228         di << " could not retrieve , permission denied \n" ;  
229         break;
230       }
231       default:
232         di << " could not retrieve \n" ;  
233         break;
234       }
235       di << "DDocStd_Open : Error\n";
236     }
237   }
238   return 1;
239 }
240
241 //=======================================================================
242 //function : Save
243 //purpose  : 
244 //=======================================================================
245
246 static Standard_Integer DDocStd_Save (Draw_Interpretor& di,
247                                       Standard_Integer nb,
248                                       const char** a)
249 {  
250   if (nb == 2) {
251     Handle(TDocStd_Document) D;    
252     if (!DDocStd::GetDocument(a[1],D)) return 1;
253     Handle(TDocStd_Application) A = DDocStd::GetApplication();
254     if (!D->IsSaved()) {
255       di << "this document has never been saved\n";
256       return 0;
257     }
258
259     Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator(di, 1);
260     A->Save (D, aProgress->Start());
261     return 0; 
262   }
263   di << "DDocStd_Save : Error\n";
264   return 1;
265 }
266
267 //=======================================================================
268 //function : SaveAs
269 //purpose  : 
270 //=======================================================================
271
272 static Standard_Integer DDocStd_SaveAs (Draw_Interpretor& di,
273                                         Standard_Integer nb,
274                                         const char** a)
275 {
276   if (nb >= 3) {
277     Handle(TDocStd_Document) D;    
278     if (!DDocStd::GetDocument(a[1],D)) return 1;  
279     TCollection_ExtendedString path (a[2], Standard_True); 
280     Handle(TDocStd_Application) A = DDocStd::GetApplication();
281     PCDM_StoreStatus theStatus;
282
283     Standard_Boolean anUseStream(Standard_False), isSaveEmptyLabels(Standard_False);
284     for ( Standard_Integer i = 3; i < nb; i++ )
285     {
286       if (!strcmp (a[i], "-stream"))
287       {
288         di << "standard SEEKABLE stream is used\n";
289         anUseStream = Standard_True;
290         break;
291       } else {
292         isSaveEmptyLabels =  ((atoi (a[3])) != 0);
293         D->SetEmptyLabelsSavingMode(isSaveEmptyLabels);
294       }
295     }
296
297     Handle(Draw_ProgressIndicator) aProgress = new Draw_ProgressIndicator(di, 1);
298     if (anUseStream)
299     {
300       std::ofstream aFileStream;
301       OSD_OpenStream (aFileStream, path, std::ios::out | std::ios::binary);
302       theStatus = A->SaveAs (D, aFileStream, aProgress->Start());
303     }
304     else
305     {
306       theStatus = A->SaveAs(D,path, aProgress->Start());
307     }
308
309     if (theStatus != PCDM_SS_OK ) {
310       switch ( theStatus ) {
311       case PCDM_SS_DriverFailure: {
312         di << "Error saving document: Could not store , no driver found to make it\n";
313         break ;
314                                   }
315       case PCDM_SS_WriteFailure: {
316         di << "Error saving document: Write access failure\n";
317         break;
318                                  }
319       case PCDM_SS_Failure: {
320         di << "Error saving document: Write failure\n" ;
321         break;
322                             }
323       case PCDM_SS_Doc_IsNull: {
324         di << "Error saving document: No document to save\n";
325         break ;
326                                }
327       case PCDM_SS_No_Obj: {
328         di << "Error saving document: No objects written\n";
329         break;
330                            }
331       case PCDM_SS_Info_Section_Error: {
332         di << "Error saving document: Write info section failure\n" ;
333         break;
334                                        }
335       case PCDM_SS_UserBreak: {
336         di << "Error saving document: User break \n" ;
337         break;
338       }
339       default:
340         break;
341       }
342       return 1;
343     } else {
344       return 0; 
345     }
346   }
347   di << "DDocStd_SaveAs : Error not enough argument\n";
348   return 1;
349 }
350
351 //=======================================================================
352 //function : Close
353 //purpose  : 
354 //=======================================================================
355
356 static Standard_Integer DDocStd_Close (Draw_Interpretor& theDI,
357                                        Standard_Integer  theArgNb,
358                                        const char**      theArgVec)
359 {   
360   bool toComplain = true;
361   NCollection_List<TCollection_AsciiString> aDocNames;
362   for (Standard_Integer anArgIt = 1; anArgIt < theArgNb; ++anArgIt)
363   {
364     const TCollection_AsciiString anArg (theArgVec[anArgIt]);
365     TCollection_AsciiString anArgCase (anArg);
366     anArgCase.LowerCase();
367     if (anArgCase == "*"
368      || anArgCase == "-all"
369      || anArgCase == "all")
370     {
371       for (NCollection_Map<Handle(Draw_Drawable3D)>::Iterator anIter (Draw::Drawables());
372            anIter.More(); anIter.Next())
373       {
374         if (Handle(DDocStd_DrawDocument) aDrawDocument = Handle(DDocStd_DrawDocument)::DownCast (anIter.Value()))
375         {
376           aDocNames.Append (aDrawDocument->Name());
377         }
378       }
379       if (aDocNames.IsEmpty())
380       {
381         return 0;
382       }
383     }
384     else if (anArgCase == "-silent")
385     {
386       toComplain = false;
387     }
388     else
389     {
390       aDocNames.Append (anArg);
391     }
392   }
393
394   if (aDocNames.IsEmpty())
395   {
396     theDI << "Syntax error: wrong number of arguments";
397     return 1;
398   }
399
400   Handle(TDocStd_Application) aDocApp = DDocStd::GetApplication();
401   for (NCollection_List<TCollection_AsciiString>::Iterator aDocNameIter (aDocNames);
402        aDocNameIter.More(); aDocNameIter.Next())
403   {
404     Standard_CString aDocName = aDocNameIter.Value().ToCString();
405     Handle(TDocStd_Document) aDoc;
406     if (DDocStd::GetDocument (aDocName, aDoc, toComplain))
407     {
408       TDF_Label aRoot = aDoc->GetData()->Root();
409       Handle(TPrsStd_AISViewer) aDocViewer;
410       if (TPrsStd_AISViewer::Find (aRoot, aDocViewer)
411       && !aDocViewer->GetInteractiveContext().IsNull())
412       {
413         Handle(V3d_Viewer) aViewer = aDocViewer->GetInteractiveContext()->CurrentViewer();
414         V3d_ListOfView aViews;
415         for (V3d_ListOfViewIterator aViewIter (aDocViewer->GetInteractiveContext()->CurrentViewer()->DefinedViewIterator()); aViewIter.More(); aViewIter.Next())
416         {
417           aViews.Append (aViewIter.Value());
418         }
419         for (V3d_ListOfViewIterator aViewIter (aViews); aViewIter.More(); aViewIter.Next())
420         {
421           Handle(V3d_View) aView = aViewIter.Value();
422           ViewerTest::RemoveView (aView);
423         }
424       }
425       aDocApp->Close (aDoc);
426     }
427     else if (toComplain)
428     {
429       return 1;
430     }
431
432     if (Handle(Draw_Drawable3D) aDrawable = Draw::GetExisting (aDocName))
433     {
434       dout.RemoveDrawable (aDrawable);
435     }
436     Draw::Set (aDocName, Handle(Draw_Drawable3D)());
437   }
438   return 0;
439 }
440
441 //=======================================================================
442 //function : IsInSession
443 //purpose  : 
444 //=======================================================================
445
446 static Standard_Integer DDocStd_IsInSession (Draw_Interpretor& di,
447                                              Standard_Integer nb,
448                                              const char** a)
449 {   
450   if (nb == 2) {   
451     Handle(TDocStd_Application) A = DDocStd::GetApplication();
452     di << A->IsInSession(a[1]);
453     return 0;
454   }  
455   di << "DDocStd_IsInSession : Error\n";
456   return 1;
457 }
458
459  
460 //=======================================================================
461 //function : OSDPath
462 //purpose  : 
463 //=======================================================================
464
465 static Standard_Integer DDocStd_OSDPath (Draw_Interpretor& di,
466                                          Standard_Integer nb,
467                                          const char** a)
468 {   
469   if (nb == 2) { 
470     OSD_Path path (a[1]);
471     di << "Node      : " << path.Node().ToCString() << "\n";  
472     di << "UserName  : " << path.UserName().ToCString() << "\n"; 
473     di << "Password  : " << path.Password().ToCString() << "\n";  
474     di << "Disk      : " << path.Disk().ToCString() << "\n";
475     di << "Trek      : " << path.Trek().ToCString() << "\n"; 
476     di << "Name      : " << path.Name().ToCString() << "\n";  
477     di << "Extension : " << path.Extension().ToCString() << "\n";
478     return 0;
479   }
480   di << "DDocStd_OSDPath : Error\n";
481   return 1;
482 }
483
484
485 //=======================================================================
486 //function : Path
487 //purpose  : 
488 //=======================================================================
489
490 static Standard_Integer DDocStd_Path (Draw_Interpretor& di,
491                                        Standard_Integer nb,
492                                        const char** a)
493 {   
494   if (nb == 2) { 
495     TDocStd_PathParser path (TCollection_ExtendedString (a[1], Standard_True));
496     di << "Trek      : " << path.Trek() << "\n";  
497     di << "Name      : " << path.Name() << "\n"; 
498     di << "Extension : " << path.Extension() << "\n";
499     di << "Path      : " << path.Path() << "\n";
500     return 0;
501   }
502   di << "DDocStd_Path : Error\n";
503   return 1;
504 }
505
506 //=======================================================================
507 //function : AddComment
508 //purpose  : 
509 //=======================================================================
510 static Standard_Integer DDocStd_AddComment (Draw_Interpretor& di,
511                                             Standard_Integer nb,
512                                             const char** a)
513 {  
514   if (nb == 3) {
515     Handle(TDocStd_Document) D;    
516     if (!DDocStd::GetDocument(a[1],D)) return 1;  
517     TCollection_ExtendedString comment (a[2], Standard_True); 
518 //    Handle(TDocStd_Application) A = DDocStd::GetApplication();
519 //    A->AddComment(D,comment);
520     D->AddComment(comment);
521     return 0; 
522   }
523   di << "DDocStd_AddComment : Wrong arguments number\n";
524   return 1;
525 }
526
527 //=======================================================================
528 //function : PrintComments
529 //purpose  : 
530 //=======================================================================
531 static Standard_Integer DDocStd_PrintComments (Draw_Interpretor& di,
532                                                Standard_Integer nb,
533                                                const char** a)
534 {  
535   if (nb == 2) {
536     Handle(TDocStd_Document) D;    
537     if (!DDocStd::GetDocument(a[1],D)) return 1;  
538
539     TColStd_SequenceOfExtendedString comments;
540     D->Comments(comments);
541
542     for (int i = 1; i <= comments.Length(); i++)
543     {
544       di << comments(i) << "\n";
545     }
546
547     return 0; 
548   }
549   di << "DDocStd_PrintComments : Wrong arguments number\n";
550   return 1;
551 }
552
553 //=======================================================================
554 //function : SetStorageFormatVersion
555 //purpose  : 
556 //=======================================================================
557 static Standard_Integer DDocStd_SetStorageFormatVersion (Draw_Interpretor& ,
558                                                          Standard_Integer nb,
559                                                          const char** a)
560 {  
561   if (nb == 3)
562   {
563     Handle(TDocStd_Document) D;
564     if (!DDocStd::GetDocument(a[1], D)) return 1;
565     const int version = atoi(a[2]);
566     D->ChangeStorageFormatVersion((TDocStd_FormatVersion) version);
567     return 0;
568   }
569   return 1;
570 }
571
572 //=======================================================================
573 //function : GetStorageFormatVersion
574 //purpose  : 
575 //=======================================================================
576 static Standard_Integer DDocStd_GetStorageFormatVersion (Draw_Interpretor& di,
577                                                          Standard_Integer nb,
578                                                          const char** a)
579
580   if (nb == 2) {
581     Handle(TDocStd_Document) D;
582     if (!DDocStd::GetDocument(a[1], D)) return 1;
583     di << D->StorageFormatVersion() << "\n";
584     return 0;
585   }
586   return 1;
587 }
588
589 //=======================================================================
590 //function : ApplicationCommands
591 //purpose  : 
592 //=======================================================================
593
594 void DDocStd::ApplicationCommands(Draw_Interpretor& theCommands) 
595 {
596   
597   static Standard_Boolean done = Standard_False;
598   if (done) return;
599   done = Standard_True;
600
601   const char* g = "DDocStd application commands";
602
603   // user application commands
604   theCommands.Add("ListDocuments",
605                   "ListDocuments",
606                   __FILE__, DDocStd_ListDocuments, g);  
607
608   theCommands.Add("NewDocument",
609                   "NewDocument docname format",
610                   __FILE__, DDocStd_NewDocument, g);  
611
612   theCommands.Add("Open",
613                   "Open path docname [-stream] [-skipAttribute] [-readAttribute] [-readPath] [-append|-overwrite]"
614        "\n\t\t The options are:"
615        "\n\t\t   -stream : opens path as a stream"
616        "\n\t\t   -skipAttribute : class name of the attribute to skip during open, for example -skipTDF_Reference"
617        "\n\t\t   -readAttribute : class name of the attribute to read only during open, for example -readTDataStd_Name loads only such attributes"
618        "\n\t\t   -append : to read file into already existing document once again, append new attributes and don't touch existing"
619        "\n\t\t   -overwrite : to read file into already existing document once again, overwriting existing attributes",
620                   __FILE__, DDocStd_Open, g);   
621
622   theCommands.Add("SaveAs",
623                   "SaveAs DOC path [saveEmptyLabels: 0|1] [-stream]",
624                   __FILE__, DDocStd_SaveAs, g);  
625
626   theCommands.Add("Save",
627                   "Save",
628                   __FILE__, DDocStd_Save, g);  
629
630   theCommands.Add("Close",
631       "Close the specific document or all documents\n"
632       "Close DOC [-silent]"
633       "\n\t\t: Close the specific document."
634       "\n\t\t: -silent not raise an exception or print error message for an empty document \n"
635       "Close *"
636       "\n\t\t: Close all open documents.",
637                   __FILE__, DDocStd_Close, g);   
638
639   theCommands.Add("IsInSession",
640                   "IsInSession path",
641                   __FILE__, DDocStd_IsInSession, g);  
642
643   theCommands.Add("OSDPath",
644                   "OSDPath string",
645                   __FILE__, DDocStd_OSDPath, g);  
646
647   theCommands.Add("Path",
648                   "Path string",
649                   __FILE__, DDocStd_Path, g);
650
651   theCommands.Add("AddComment",
652                   "AddComment Doc string",
653                   __FILE__, DDocStd_AddComment, g);
654
655   theCommands.Add("PrintComments",
656                   "PrintComments Doc",
657                   __FILE__, DDocStd_PrintComments, g);
658
659   theCommands.Add("GetStorageFormatVersion",
660                   "GetStorageFormatVersion Doc"
661           "\nStorage format versions are defined in TDocStd_FormatVersion.hxx file by an enumeration",
662                   __FILE__, DDocStd_GetStorageFormatVersion, g);
663   theCommands.Add("SetStorageFormatVersion",
664                   "SetStorageFormatVersion Doc Version"
665           "\nStorage format versions are defined in TDocStd_FormatVersion.hxx file by an enumeration",
666                   __FILE__, DDocStd_SetStorageFormatVersion, g);
667 }