0027835: Application Framework, BinXCAF - handle correctly faces with NULL surface...
[occt.git] / src / DDocStd / DDocStd_DocumentCommands.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
18 #include <BinDrivers_DocumentStorageDriver.hxx>
19 #include <DDF.hxx>
20 #include <Draw.hxx>
21 #include <Draw_Interpretor.hxx>
22 #include <TDocStd_XLinkTool.hxx>
23 #include <TDF_Reference.hxx>
24 #include <TDocStd_Document.hxx>
25 #include <CDM_Document.hxx>
26 #include <TDocStd_Modified.hxx>
27 #include <TDF_Label.hxx>
28 #include <DDocStd_DrawDocument.hxx>
29 #include <TDocStd_Document.hxx>
30 #include <TDocStd_XLink.hxx>
31 #include <TDocStd_XLinkRoot.hxx>
32 #include <TDocStd_XLinkIterator.hxx>
33 #include <TDocStd_Application.hxx>
34 #include <Draw.hxx>
35 #include <Draw_Interpretor.hxx>
36 #include <TDF_MapIteratorOfLabelMap.hxx>
37 #include <Plugin.hxx>
38 #include <TCollection_ExtendedString.hxx>
39 #include <TDF_Tool.hxx>
40 #include <TDF_ChildIterator.hxx>
41 #include <TDF_Tool.hxx>
42 // pour propagate
43 #include <TDocStd_XLinkTool.hxx>
44
45 #include <OSD_Function.hxx>
46 #include <OSD_SharedLibrary.hxx>
47 #include <OSD_LoadMode.hxx>
48
49 //typedef Standard_Integer (* DFBROWSER_CALL)(const Handle(TDocStd_Document)&);
50 //static DFBROWSER_CALL gDFunc = 0;
51
52 //=======================================================================
53 //function : Main
54 //purpose  : Main (DOC)
55 //=======================================================================
56
57 static Standard_Integer DDocStd_Main (Draw_Interpretor& di,Standard_Integer nb, const char** a)
58 {
59   if (nb == 2) {
60     Handle(TDocStd_Document) DOC;   
61     if (!DDocStd::GetDocument(a[1],DOC)) return 1;
62     DDocStd::ReturnLabel(di,DOC->Main());
63     return 0;
64   }   
65   di << "DDocStd_Main : Error\n";
66   return 1;  
67 }
68
69
70 //=======================================================================
71 //function : Format
72 //purpose  : 
73 //=======================================================================
74
75 static Standard_Integer DDocStd_Format (Draw_Interpretor& di,Standard_Integer n, const char** a)
76
77   Handle(TDocStd_Document) D;
78   if (n == 2) {
79     if (!DDocStd::GetDocument(a[1],D)) return 1;    
80     //cout << "FORMAT : " << D->StorageFormat() << endl;
81     di << "FORMAT : ";
82     Standard_SStream aStream;
83     D->StorageFormat().Print(aStream);
84     di << aStream;
85     di << "\n";
86     return 0;
87   }  
88   if (n == 3) {
89     if (!DDocStd::GetDocument(a[1],D)) return 1;    
90     D->ChangeStorageFormat(a[2]);  
91     return 0;
92   }  
93   di << "DDocStd_Format : Error\n";
94   return 1;
95 }
96
97 //=======================================================================
98 //function : Copy "Copy DOC entry XDOC xentry",
99 //=======================================================================
100
101 static Standard_Integer DDocStd_Copy (Draw_Interpretor& di,Standard_Integer n, const char** a)
102 {
103   if (n == 5) {  
104     Handle(TDocStd_Document) DOC, XDOC;  
105     if (!DDocStd::GetDocument(a[1],DOC)) return 1; 
106     if (!DDocStd::GetDocument(a[3],XDOC)) return 1;
107     TDF_Label L,XL;
108     if (!DDocStd::Find(DOC,a[2],L)) return 1; 
109     if (!DDocStd::Find(XDOC,a[4],XL)) return 1;
110     TDocStd_XLinkTool XLinkTool;
111     XLinkTool.Copy(L,XL);
112     if (!XLinkTool.IsDone()) {
113       di << "DDocStd_XLinkTool : not done\n";
114     }
115     return 0;
116   }  
117   di << "DDocStd_XLinkTool : Error\n";
118   return 1; 
119 }
120
121
122 //=======================================================================
123 //function : CopyWithLink "Copy DOC entry XDOC xentry",
124 //=======================================================================
125
126 static Standard_Integer DDocStd_CopyWithLink (Draw_Interpretor& di,Standard_Integer n, const char** a)
127 {  
128   if (n == 5) {  
129     Handle(TDocStd_Document) DOC, XDOC;  
130     if (!DDocStd::GetDocument(a[1],DOC)) return 1; 
131     if (!DDocStd::GetDocument(a[3],XDOC)) return 1;   
132     TDF_Label L,XL;
133     if (!DDocStd::Find(DOC,a[2],L)) return 1; 
134     if (!DDocStd::Find(XDOC,a[4],XL)) return 1;
135     TDocStd_XLinkTool XLinkTool;
136     XLinkTool.CopyWithLink(L,XL);
137     if (!XLinkTool.IsDone()) {
138       di << "DDocStd_CopyWithLink : not done\n";
139     }
140     return 0;
141   }  
142   di << "DDocStd_CopyWithLink : Error\n";
143   return 1; 
144 }
145
146 //=======================================================================
147 //function : UpdateLink (D,[xrefentry])
148 //=======================================================================
149
150 static Standard_Integer DDocStd_UpdateLink (Draw_Interpretor& di,Standard_Integer nb, const char** a)
151 {  
152   if (nb == 2 || nb == 3) {  
153     Handle(TDocStd_Document) DOC;  
154     if (!DDocStd::GetDocument(a[1],DOC)) return 1; 
155     Handle(TDF_Reference) REF;
156     TDocStd_XLinkTool XLinkTool;  
157     if (nb == 3) {
158       if (!DDocStd::Find(DOC,a[2],TDF_Reference::GetID(),REF)) return 1;
159       XLinkTool.UpdateLink(REF->Label());
160       if (!XLinkTool.IsDone()) {
161         di << "DDocStd_UpdateXLink : not done\n";
162       }
163     }
164     else {
165       for (TDocStd_XLinkIterator xit (DOC); xit.More(); xit.Next()) {
166         XLinkTool.UpdateLink(xit.Value()->Label());
167         if (!XLinkTool.IsDone()) {
168           di << "DDocStd_UpdateXLink : not done\n";
169         }
170       }
171     }
172     return 0;
173   }
174   di << "DDocStd_UpdateXLink : Error\n";
175   return 1; 
176 }
177
178 //=======================================================================
179 //function : UndoLimit
180 //purpose  : 
181 //=======================================================================
182
183 static Standard_Integer DDocStd_UndoLimit (Draw_Interpretor& di,Standard_Integer n, const char** a)
184 {
185   if (n < 2) return 1;
186   
187   Handle(TDocStd_Document) D;
188   if (!DDocStd::GetDocument(a[1],D)) return 1;
189   
190   if (n > 2) {
191     Standard_Integer lim = Draw::Atoi(a[2]);
192     D->SetUndoLimit(lim);
193   }
194   
195   // display current values
196   di << D->GetUndoLimit() << " ";
197   di << D->GetAvailableUndos() << " ";
198   di << D->GetAvailableRedos();
199   return 0;
200 }
201
202 //=======================================================================
203 //function : Undo, Redo
204 //purpose  : Undo (DOC)
205 //=======================================================================
206
207 static Standard_Integer DDocStd_Undo (Draw_Interpretor& di,Standard_Integer n, const char** a)
208 {
209   if (n < 2) return 1;
210   
211   Handle(TDocStd_Document) D;
212   if (!DDocStd::GetDocument(a[1],D)) return 1;
213   
214   Standard_Integer i,step = 1;
215   if (n > 2) {
216     step = Draw::Atoi(a[2]);
217   }
218
219   // test if the command was undo or redo
220   Standard_Boolean undo = a[0][0] == 'U';
221
222   for (i = 1; i <= step; i++) {
223     if (undo) {
224       if (!D->Undo()) di << "Undo not done\n";
225     }
226     else {
227       if (!D->Redo()) di << "Redo not done\n";
228     }
229   }
230   
231   return 0;
232 }
233
234 //=======================================================================
235 //function : NewCommand
236 //purpose  : 
237 //=======================================================================
238
239 static Standard_Integer DDocStd_NewCommand(Draw_Interpretor& /*di*/,Standard_Integer n, const char** a)
240 {
241   if (n < 2) return 1;
242   Handle(TDocStd_Document) D;
243   if (!DDocStd::GetDocument(a[1],D)) return 1;
244   D->NewCommand();
245   return 0;
246 }
247
248 //=======================================================================
249 //function : OpenCommand
250 //purpose  : 
251 //=======================================================================
252
253 static Standard_Integer DDocStd_OpenCommand(Draw_Interpretor& /*di*/,Standard_Integer n, const char** a)
254 {
255   if (n < 2) return 1;
256
257   Handle(TDocStd_Document) D;
258   if (!DDocStd::GetDocument(a[1],D)) return 1;
259   D->OpenCommand();
260   return 0;
261 }
262
263 //=======================================================================
264 //function : AbortCommand
265 //purpose  : 
266 //=======================================================================
267
268 static Standard_Integer DDocStd_AbortCommand(Draw_Interpretor& /*di*/,Standard_Integer n, const char** a)
269 {
270   if (n < 2) return 1;
271   Handle(TDocStd_Document) D;
272   if (!DDocStd::GetDocument(a[1],D)) return 1;
273   D->AbortCommand();
274   return 0;
275 }
276
277 //=======================================================================
278 //function : CommitCommand
279 //purpose  : 
280 //=======================================================================
281
282 static Standard_Integer DDocStd_CommitCommand(Draw_Interpretor& /*di*/,Standard_Integer n, const char** a)
283 {
284   if (n < 2) return 1;
285   Handle(TDocStd_Document) D;
286   if (!DDocStd::GetDocument(a[1],D)) return 1;
287   D->CommitCommand();
288   return 0;
289 }
290
291
292 //=======================================================================
293 //function : DDocStd_DumpDocument
294 //purpose  : DumpDocument (DOC)
295 //=======================================================================
296
297 static Standard_Integer DDocStd_DumpDocument (Draw_Interpretor& di,
298                                               Standard_Integer nb, 
299                                               const char** arg) 
300 {   
301   if (nb == 2) {   
302     Handle(TDocStd_Document) D;       
303     if (!DDocStd::GetDocument(arg[1],D)) return 1;     
304     di << "\n"; 
305     // document name
306     if (D->IsSaved()) 
307       di << "DOCUMENT      : " << TCollection_AsciiString(D->GetName(),'?').ToCString();
308     else 
309       di << "DOCUMENT      : not saved";
310     di << "\n";
311     // format
312     //cout << "FORMAT        : " << D->StorageFormat();
313     di << "FORMAT        : ";
314     Standard_SStream aStream;
315     D->StorageFormat().Print(aStream);
316     di << aStream;
317     di << "\n";
318     // command
319     di << "COMMAND       : ";
320     if (D->HasOpenCommand()) di << " Is Open";
321     else di << " Is Not Open";
322     // undo
323     di << "UNDO          :"; 
324     di << " limit :" << D->GetUndoLimit();
325     di << " undos :" << D->GetAvailableUndos() << " ";  
326     di << " redos :" << D->GetAvailableRedos(); 
327     di << "\n";
328     // cout << "CURRENT :";   
329     //     TCollection_AsciiString string;  
330     //     TDF_Tool::Entry(D->CurrentLabel(),string); 
331     //     cout << string;
332     //     cout << endl;
333     // modified  
334     di << "MODIFIED      : ";
335     if (D->IsModified()) di << "true";
336     else di << "false";  
337     di << "\n"; 
338     if (!TDocStd_Modified::IsEmpty(D->Main())) {
339       di << "MODIFICATIONS : ";     
340       TDF_MapIteratorOfLabelMap it (D->GetModified()); 
341       if (!it.More()) di << "VALID\n"; 
342       else {
343         TCollection_AsciiString string;  
344         for (;it.More();it.Next()) { 
345           TDF_Tool::Entry(it.Key(),string);
346           di << string.ToCString() << " "; 
347         }
348         di << "\n";
349       } 
350     }
351     return 0;
352   } 
353   di << "DDocStd_DumpDocument : Error\n";
354   return 1;
355 }
356
357 //=======================================================================
358 //function : SetModified
359 //purpose  : Set modifications in a document
360 //=======================================================================
361
362 static Standard_Integer DDocStd_SetModified (Draw_Interpretor& di,Standard_Integer n, const char** a)
363 {
364   if (n > 2) {
365     Handle(TDocStd_Document) D;
366     if (!DDocStd::GetDocument(a[1],D)) return 1;
367     TDF_Label L;
368     for (Standard_Integer i = 2; i < n; i++) {
369       if (DDocStd::Find(D,a[i],L)) D->SetModified(L);
370     }
371     return 0; 
372   }
373   di << "DDocStd_SetModified : Error\n";
374   return 1;
375 }
376
377 //=======================================================================
378 //function : Propagate
379 //purpose  : 
380 //=======================================================================
381
382 static Standard_Integer DDocStd_Propagate (Draw_Interpretor& di,Standard_Integer /*n*/, const char** /*a*/)
383 {
384 //   if (n == 2) {
385 //     Handle(TDocStd_Document) D;
386 //     if (!DDocStd::GetDocument(a[1],D)) return 1;
387 //     if (D->IsValid()) {
388 //       cout << "the document is valid" << endl;
389 //       return 0;
390 //     }
391 //     Handle(TDesign_Function) F; 
392 //     if (!D->Main().FindAttribute(TDesign_Function::GetID(),F)) {
393 //       cout << "no function found at main" << endl;
394 //       return 0;
395 //     }
396 //     TFunction_Logbook mdf (Standard_True);   
397 //     for (TDF_MapIteratorOfLabelMap it (D->GetModified());it.More();it.Next()) {
398 //       mdf.SetTouched(it.Key());
399 //     }  
400 //     F->Execute(mdf);
401 //     D->PurgeModified();
402 //     return 0;
403 //   }
404   di << "DDocStd_Propagate : not implemented\n";
405   return 1;
406 }
407
408 //=======================================================================
409 //function : DDocStd_StoreTriangulation
410 //purpose  :
411 //=======================================================================
412
413 static Standard_Integer DDocStd_StoreTriangulation (Draw_Interpretor& theDi,
414                                                     Standard_Integer theNbArgs,
415                                                     const char** theArgVec)
416 {
417   const Handle(TDocStd_Application)& anApp = DDocStd::GetApplication();
418   Handle(BinDrivers_DocumentStorageDriver) aDriverXCaf = Handle(BinDrivers_DocumentStorageDriver)::DownCast(anApp->WriterFromFormat ("BinXCAF"));
419   Handle(BinDrivers_DocumentStorageDriver) aDriverOcaf = Handle(BinDrivers_DocumentStorageDriver)::DownCast(anApp->WriterFromFormat ("BinOcaf"));
420   if (aDriverXCaf.IsNull()
421    || aDriverOcaf.IsNull())
422   {
423     std::cout << "Error: BinXCAF or BinOcaf storage formats are not registered\n";
424     return 1;
425   }
426
427   if (theNbArgs == 1)
428   {
429     theDi << (aDriverXCaf->IsWithTriangles() ? "1" : "0");
430     return 0;
431   }
432   else if (theNbArgs != 2)
433   {
434     std::cout << "Syntax error: wrong number of arguments\n";
435     return 1;
436   }
437
438   const Standard_Boolean toEnable = (Draw::Atoi (theArgVec[1]) != 0);
439   aDriverXCaf->SetWithTriangles (anApp->MessageDriver(), toEnable);
440   aDriverOcaf->SetWithTriangles (anApp->MessageDriver(), toEnable);
441   return 0;
442 }
443
444 //=======================================================================
445 //function : DocumentCommands
446 //purpose  : 
447 //=======================================================================
448
449 void DDocStd::DocumentCommands(Draw_Interpretor& theCommands) 
450 {
451   
452   static Standard_Boolean done = Standard_False;
453   if (done) return;
454   done = Standard_True;
455   
456   
457   const char* g = "DDocStd commands";
458   
459   // Data Framework Access
460   
461   theCommands.Add("Main","Main (DOC)",
462                   __FILE__, DDocStd_Main, g);  
463
464   
465   // DUMP
466   
467   theCommands.Add ("Format", 
468                    "Format (DOC, [format])",
469                    __FILE__, DDocStd_Format, g); 
470
471   theCommands.Add ("DumpDocument", 
472                    "DumpDocument (DOC)",
473                    __FILE__, DDocStd_DumpDocument, g);   
474
475   theCommands.Add ("StoreTriangulation",
476                    "StoreTriangulation [toStore={0|1}]"
477                    "\nSetup BinXCAF/BinOcaf storage drivers to write triangulation",
478                    __FILE__, DDocStd_StoreTriangulation, g);
479
480   // XREF
481
482   theCommands.Add("Copy","Copy DOC entry XDOC xentry",
483                   __FILE__, DDocStd_Copy, g);  
484
485   theCommands.Add("CopyWithLink","CopyWithLink DOC entry XDOC xentry",
486                   __FILE__, DDocStd_CopyWithLink, g);  
487
488   theCommands.Add("UpdateLink","UpdateLink DOC [entry]",
489                   __FILE__, DDocStd_UpdateLink, g);  
490
491
492   // UNDO/REDO
493
494   theCommands.Add("UndoLimit","UndoLimit DOC (Value), return UndoLimit Undos Redos",
495                   __FILE__, DDocStd_UndoLimit, g);
496   
497   theCommands.Add("Undo","Undo DOC (steps = 1)",
498                   __FILE__, DDocStd_Undo, g);
499   
500   theCommands.Add("Redo","Redo DOC (steps = 1)",
501                   __FILE__, DDocStd_Undo, g);
502   
503   theCommands.Add("NewCommand","NewCommand DOC",
504                   __FILE__, DDocStd_NewCommand, g);  
505
506   theCommands.Add("OpenCommand","OpenCommand DOC",
507                   __FILE__, DDocStd_OpenCommand, g);  
508
509   theCommands.Add("AbortCommand","AbortCommand DOC",
510                   __FILE__, DDocStd_AbortCommand, g);    
511
512   theCommands.Add("CommitCommand","CommitCommand DOC",
513                   __FILE__, DDocStd_CommitCommand, g);    
514
515
516   // Modif and Propagation
517
518   theCommands.Add("SetModified","SetModified DOC Label1 Label2 ....",
519                   __FILE__, DDocStd_SetModified, g);
520
521   theCommands.Add("Propagate","Propagate DOC",
522                   __FILE__, DDocStd_Propagate, g);
523
524 }
525