0026229: Add the possibility in OCAF to open/save a document from/to a stream object
[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 <DDocStd_DrawDocument.hxx>
21 #include <TDocStd_Application.hxx>
22 #include <TDocStd_Document.hxx>
23 #include <TDataStd_Name.hxx>
24 #include <Draw.hxx>
25 #include <Standard_GUID.hxx>
26 #include <Standard_ExtString.hxx>
27 #include <TCollection_AsciiString.hxx>
28 #include <TCollection_ExtendedString.hxx>
29 #include <TDF.hxx>
30 #include <TDF_Data.hxx>
31 #include <TDF_ChildIterator.hxx>
32 #include <TDF_Tool.hxx> 
33
34 #include <OSD_Path.hxx>
35 #include <OSD_OpenFile.hxx>
36 #include <TDocStd_PathParser.hxx>
37
38 #include <AIS_InteractiveContext.hxx>
39 #include <TPrsStd_AISViewer.hxx>
40 #include <ViewerTest.hxx>
41 #include <V3d_Viewer.hxx>
42
43 #ifndef _WIN32
44 extern Draw_Viewer dout;
45 #else
46 Standard_IMPORT Draw_Viewer dout;
47 #endif
48
49 //=======================================================================
50 //function : ListDocuments
51 //purpose  : 
52 //=======================================================================
53
54 static Standard_Integer DDocStd_ListDocuments (Draw_Interpretor& di,
55                                                Standard_Integer nb,
56                                                const char** /*a*/)
57 {  
58   if (nb == 1) {
59     Handle(TDocStd_Application) A;
60     if (!DDocStd::Find(A)) return 1;
61     Handle(TDocStd_Document) D;
62     Standard_Integer nbdoc = A->NbDocuments();
63     for (Standard_Integer i = 1; i <= nbdoc; i++) {
64       A->GetDocument(i,D);
65       di <<"document " << i;
66       if (D->IsSaved()) {
67         TCollection_AsciiString GetNameAsciiString(D->GetName().ToExtString(),'?');
68         TCollection_AsciiString GetPathAsciiString(D->GetPath().ToExtString(),'?');
69         //cout << " name : " << D->GetName();
70         //cout << " path : " << D->GetPath();
71         di << " name : " << GetNameAsciiString.ToCString();
72         di << " path : " << GetPathAsciiString.ToCString();
73       }
74       else di << " not saved";
75       di << "\n";
76     }
77     return 0;
78   }
79   di << "DDocStd_ListDocuments : Error\n";
80   return 1; 
81 }
82
83
84 //=======================================================================
85 //function : NewDocument
86 //purpose  : 
87 //=======================================================================
88
89 static Standard_Integer DDocStd_NewDocument (Draw_Interpretor& di,
90                                              Standard_Integer nb,
91                                              const char** a)
92 {    
93   Handle(TDocStd_Document) D; 
94   Handle(DDocStd_DrawDocument) DD;
95   if (nb == 2) {
96     if (!DDocStd::GetDocument(a[1],D,Standard_False)) { 
97       D = new TDocStd_Document("dummy");  
98       DD = new DDocStd_DrawDocument(D);  
99       Draw::Set(a[1],DD);       
100       di << "document (not handled by application)  " << a[1] << " created\n";  
101       DDocStd::ReturnLabel(di,D->Main()); 
102     }    
103     else di << a[1] << " is already a document\n";
104     return 0;
105   }
106   if (nb == 3) {   
107     if (!DDocStd::GetDocument(a[1],D,Standard_False)) {  
108       Handle(TDocStd_Application) A;
109       if (!DDocStd::Find(A)) return 1;
110       A->NewDocument(a[2],D);  
111       DD = new DDocStd_DrawDocument(D);  
112       TDataStd_Name::Set(D->GetData()->Root(),a[1]);  
113       Draw::Set(a[1],DD);    
114       di << "document " << a[1] << " created\n";    
115       DDocStd::ReturnLabel(di,D->Main()); 
116     }
117     else di << a[1] << " is already a document\n";
118     return 0;
119   }   
120   di << "DDocStd_NewDocument : Error\n";
121   return 1;
122 }
123
124 //=======================================================================
125 //function : Open
126 //purpose  : 
127 //=======================================================================
128
129 static Standard_Integer DDocStd_Open (Draw_Interpretor& di,
130                                       Standard_Integer nb,
131                                       const char** a)
132 {   
133   if (nb >= 3) {
134     TCollection_ExtendedString path (a[1]); 
135     Handle(TDocStd_Application) A;
136     if (!DDocStd::Find(A)) return 1;
137     Handle(TDocStd_Document) D;
138     Standard_Integer insession = A->IsInSession(path);
139     if (insession > 0) {  
140       di <<"document " << insession << "  is already in session\n";
141       return 0;
142     }
143     PCDM_ReaderStatus theStatus;
144
145     Standard_Boolean anUseStream = Standard_False;
146     for ( Standard_Integer i = 3; i < nb; i++ )
147     {
148       if (!strcmp (a[i], "-stream"))
149       {
150         di << "standard SEEKABLE stream is used\n";
151         anUseStream = Standard_True;
152         break;
153       }
154     }
155
156     if (anUseStream)
157     {
158       std::ifstream aFileStream;
159       OSD_OpenStream (aFileStream, path, std::ios::in | std::ios::binary);
160
161       theStatus = A->Open (aFileStream, D);
162     }
163     else
164     {
165       theStatus = A->Open(path,D);
166     }
167     if (theStatus == PCDM_RS_OK && !D.IsNull()) {
168       Handle(DDocStd_DrawDocument) DD = new DDocStd_DrawDocument(D);
169       TDataStd_Name::Set(D->GetData()->Root(),a[2]);
170       Draw::Set(a[2],DD);
171       return 0; 
172     } else {
173       switch ( theStatus ) {
174       case PCDM_RS_AlreadyRetrieved: 
175       case PCDM_RS_AlreadyRetrievedAndModified: {
176         di << " already retrieved \n" ;  
177         break;
178       }
179       case PCDM_RS_NoDriver: {
180         di << " could not retrieve , no Driver to make it \n" ;
181         break ;
182       }
183       case PCDM_RS_UnknownDocument:
184       case PCDM_RS_NoModel: {
185         di << " could not retrieve , Unknown Document or No Model \n";
186         break ; 
187       }
188       case PCDM_RS_TypeNotFoundInSchema:
189       case PCDM_RS_UnrecognizedFileFormat: {
190         di << " could not retrieve , Type not found or Unrecognized File Format\n";
191         break ;
192       }
193       case PCDM_RS_PermissionDenied: {
194         di << " could not retrieve , permission denied \n" ;  
195         break;
196       }
197       default:
198         di << " could not retrieve \n" ;  
199         break;
200       }
201       di << "DDocStd_Open : Error\n";
202     }   
203   }
204   return 1;
205 }
206
207 //=======================================================================
208 //function : Save
209 //purpose  : 
210 //=======================================================================
211
212 static Standard_Integer DDocStd_Save (Draw_Interpretor& di,
213                                       Standard_Integer nb,
214                                       const char** a)
215 {  
216   if (nb == 2) {
217     Handle(TDocStd_Document) D;    
218     if (!DDocStd::GetDocument(a[1],D)) return 1;
219     Handle(TDocStd_Application) A;
220     if (!DDocStd::Find(A)) return 1;  
221     if (!D->IsSaved()) {
222       di << "this document has never been saved\n";
223       return 0;
224     }
225     A->Save(D);
226     return 0; 
227   }
228   di << "DDocStd_Save : Error\n";
229   return 1;
230 }
231
232 //=======================================================================
233 //function : SaveAs
234 //purpose  : 
235 //=======================================================================
236
237 static Standard_Integer DDocStd_SaveAs (Draw_Interpretor& di,
238                                         Standard_Integer nb,
239                                         const char** a)
240 {  
241   if (nb >= 3) {
242     Handle(TDocStd_Document) D;    
243     if (!DDocStd::GetDocument(a[1],D)) return 1;  
244     TCollection_ExtendedString path (a[2]); 
245     Handle(TDocStd_Application) A;
246     if (!DDocStd::Find(A)) return 1;
247     PCDM_StoreStatus theStatus;
248     
249     Standard_Boolean anUseStream = Standard_False;
250     for ( Standard_Integer i = 3; i < nb; i++ )
251     {
252       if (!strcmp (a[i], "-stream"))
253       {
254         di << "standard SEEKABLE stream is used\n";
255         anUseStream = Standard_True;
256         break;
257       }
258     }
259
260     if (anUseStream)
261     {
262       std::ofstream aFileStream;
263       OSD_OpenStream (aFileStream, path, std::ios::out | std::ios::binary);
264       theStatus = A->SaveAs (D, aFileStream);
265     }
266     else
267     {
268       theStatus = A->SaveAs(D,path);
269     }
270     
271     if (theStatus != PCDM_SS_OK ) {
272       switch ( theStatus ) {
273         case PCDM_SS_DriverFailure: {
274           di << "Error saving document: Could not store , no driver found to make it\n";
275           break ;
276         }
277         case PCDM_SS_WriteFailure: {
278           di << "Error saving document: Write access failure\n";
279           break;
280         }
281         case PCDM_SS_Failure: {
282           di << "Error saving document: Write failure\n" ;
283           break;
284         }
285         case PCDM_SS_Doc_IsNull: {
286           di << "Error saving document: No document to save\n";
287           break ;
288         }
289         case PCDM_SS_No_Obj: {
290           di << "Error saving document: No objects written\n";
291           break;
292         }
293         case PCDM_SS_Info_Section_Error: {
294           di << "Error saving document: Write info section failure\n" ;
295           break;
296         }
297         default:
298           break;
299       }
300       return 1;
301     } else {
302       return 0; 
303     }
304   }
305   di << "DDocStd_SaveAs : Error not enough argument\n";
306   return 1;
307 }
308
309 //=======================================================================
310 //function : Close
311 //purpose  : 
312 //=======================================================================
313
314 static Standard_Integer DDocStd_Close (Draw_Interpretor& /*theDI*/,
315                                        Standard_Integer  theArgNb,
316                                        const char**      theArgVec)
317 {   
318   if (theArgNb != 2)
319   {
320     std::cout << "DDocStd_Close : Error\n";
321     return 1;
322   }
323
324   Handle(TDocStd_Document) aDoc;
325   Standard_CString aDocName = theArgVec[1];
326   if (!DDocStd::GetDocument (aDocName, aDoc))
327   {
328     return 1;
329   }
330
331   TDF_Label aRoot = aDoc->GetData()->Root();
332   Handle(TPrsStd_AISViewer) aDocViewer;
333   if (TPrsStd_AISViewer::Find (aRoot, aDocViewer)
334    && !aDocViewer->GetInteractiveContext().IsNull())
335   {
336     Handle(V3d_Viewer) aViewer = aDocViewer->GetInteractiveContext()->CurrentViewer();
337     for (aViewer->InitDefinedViews(); aViewer->MoreDefinedViews(); aViewer->NextDefinedViews())
338     {
339       Handle(V3d_View) aView = aViewer->DefinedView();
340       ViewerTest::RemoveView (aView);
341     }
342   }
343
344   Handle(TDocStd_Application) aDocApp;
345   if (!DDocStd::Find (aDocApp))
346   {
347     return 1;
348   }
349
350   aDocApp->Close (aDoc);
351
352   Handle(Draw_Drawable3D) aDrawable = Draw::Get (aDocName, Standard_False);
353   dout.RemoveDrawable (aDrawable);
354   Draw::Set (theArgVec[1], Handle(Draw_Drawable3D)());
355   return 0;
356 }
357
358 //=======================================================================
359 //function : IsInSession
360 //purpose  : 
361 //=======================================================================
362
363 static Standard_Integer DDocStd_IsInSession (Draw_Interpretor& di,
364                                              Standard_Integer nb,
365                                              const char** a)
366 {   
367   if (nb == 2) {   
368     Handle(TDocStd_Application) A;
369     if (!DDocStd::Find(A)) return 1;
370     di << A->IsInSession(a[1]);
371     return 0;
372   }  
373   di << "DDocStd_IsInSession : Error\n";
374   return 1;
375 }
376
377  
378 //=======================================================================
379 //function : OSDPath
380 //purpose  : 
381 //=======================================================================
382
383 static Standard_Integer DDocStd_OSDPath (Draw_Interpretor& di,
384                                          Standard_Integer nb,
385                                          const char** a)
386 {   
387   if (nb == 2) { 
388     OSD_Path path (a[1]);
389     di << "Node      : " << path.Node().ToCString() << "\n";  
390     di << "UserName  : " << path.UserName().ToCString() << "\n"; 
391     di << "Password  : " << path.Password().ToCString() << "\n";  
392     di << "Disk      : " << path.Disk().ToCString() << "\n";
393     di << "Trek      : " << path.Trek().ToCString() << "\n"; 
394     di << "Name      : " << path.Name().ToCString() << "\n";  
395     di << "Extension : " << path.Extension().ToCString() << "\n";
396     return 0;
397   }
398   di << "DDocStd_OSDPath : Error\n";
399   return 1;
400 }
401
402
403 //=======================================================================
404 //function : Path
405 //purpose  : 
406 //=======================================================================
407
408 static Standard_Integer DDocStd_Path (Draw_Interpretor& di,
409                                        Standard_Integer nb,
410                                        const char** a)
411 {   
412   if (nb == 2) { 
413     TDocStd_PathParser path (a[1]);
414     //cout << "Trek      : " << path.Trek() << endl;  
415     //cout << "Name      : " << path.Name() << endl; 
416     //cout << "Extension : " << path.Extension() << endl;
417     //cout << "Path      : " << path.Path() << endl;
418     TCollection_AsciiString TrekAsciiString(path.Trek().ToExtString(),'?');
419     TCollection_AsciiString NameAsciiString(path.Name().ToExtString(),'?');
420     TCollection_AsciiString ExtensionAsciiString(path.Extension().ToExtString(),'?');
421     TCollection_AsciiString PathAsciiString(path.Path().ToExtString(),'?');
422     di << "Trek      : " << TrekAsciiString.ToCString() << "\n";  
423     di << "Name      : " << NameAsciiString.ToCString() << "\n"; 
424     di << "Extension : " << ExtensionAsciiString.ToCString() << "\n";
425     di << "Path      : " << PathAsciiString.ToCString() << "\n";
426     return 0;
427   }
428   di << "DDocStd_Path : Error\n";
429   return 1;
430 }
431
432 //=======================================================================
433 //function : AddComment
434 //purpose  : 
435 //=======================================================================
436 static Standard_Integer DDocStd_AddComment (Draw_Interpretor& di,
437                                             Standard_Integer nb,
438                                             const char** a)
439 {  
440   if (nb == 3) {
441     Handle(TDocStd_Document) D;    
442     if (!DDocStd::GetDocument(a[1],D)) return 1;  
443     TCollection_ExtendedString comment (a[2]); 
444 //    Handle(TDocStd_Application) A;
445 //    if (!DDocStd::Find(A)) return 1;
446 //    A->AddComment(D,comment);
447     D->AddComment(comment);
448     return 0; 
449   }
450   di << "DDocStd_AddComment : Wrong arguments number\n";
451   return 1;
452 }
453
454 //=======================================================================
455 //function : PrintComments
456 //purpose  : 
457 //=======================================================================
458 static Standard_Integer DDocStd_PrintComments (Draw_Interpretor& di,
459                                                Standard_Integer nb,
460                                                const char** a)
461 {  
462   if (nb == 2) {
463     Handle(TDocStd_Document) D;    
464     if (!DDocStd::GetDocument(a[1],D)) return 1;  
465
466     TColStd_SequenceOfExtendedString comments;
467     D->Comments(comments);
468
469     for (int i = 1; i <= comments.Length(); i++)
470     {
471       //cout << comments(i) << endl;
472       TCollection_AsciiString commentAsciiString(comments(i).ToExtString(),'?');
473       di << commentAsciiString.ToCString() << "\n";
474     }
475
476     return 0; 
477   }
478   di << "DDocStd_PrintComments : Wrong arguments number\n";
479   return 1;
480 }
481
482 //=======================================================================
483 //function : ApplicationCommands
484 //purpose  : 
485 //=======================================================================
486
487 void DDocStd::ApplicationCommands(Draw_Interpretor& theCommands) 
488 {
489   
490   static Standard_Boolean done = Standard_False;
491   if (done) return;
492   done = Standard_True;
493
494   const char* g = "DDocStd application commands";
495
496   // user application commands
497   theCommands.Add("ListDocuments",
498                   "ListDocuments",
499                   __FILE__, DDocStd_ListDocuments, g);  
500
501   theCommands.Add("NewDocument",
502                   "NewDocument docname format",
503                   __FILE__, DDocStd_NewDocument, g);  
504
505   theCommands.Add("Open",
506                   "Open path docname [-stream]",
507                   __FILE__, DDocStd_Open, g);   
508
509   theCommands.Add("SaveAs",
510                   "SaveAs DOC path [-stream]",
511                   __FILE__, DDocStd_SaveAs, g);  
512
513   theCommands.Add("Save",
514                   "Save",
515                   __FILE__, DDocStd_Save, g);  
516
517   theCommands.Add("Close",
518                   "Close DOC",
519                   __FILE__, DDocStd_Close, g);   
520
521   theCommands.Add("IsInSession",
522                   "IsInSession path",
523                   __FILE__, DDocStd_IsInSession, g);  
524
525   theCommands.Add("OSDPath",
526                   "OSDPath string",
527                   __FILE__, DDocStd_OSDPath, g);  
528
529   theCommands.Add("Path",
530                   "Path string",
531                   __FILE__, DDocStd_Path, g);
532
533   theCommands.Add("AddComment",
534                   "AddComment Doc string",
535                   __FILE__, DDocStd_AddComment, g);
536
537   theCommands.Add("PrintComments",
538                   "PrintComments Doc",
539                   __FILE__, DDocStd_PrintComments, g);
540 }