0031875: Draw Harness, ViewerTest - command vaspects -mostContinuity lacks g1 and...
[occt.git] / src / TDocStd / TDocStd_Application.cxx
1 // Created on: 1999-06-30
2 // Created by: Denis PASCAL
3 // Copyright (c) 1999-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <TDocStd_Application.hxx>
18
19 #include <CDF_Directory.hxx>
20 #include <CDF_DirectoryIterator.hxx>
21 #include <CDF_Store.hxx>
22 #include <PCDM_RetrievalDriver.hxx>
23 #include <PCDM_StorageDriver.hxx>
24 #include <Plugin.hxx>
25 #include <Plugin_Failure.hxx>
26 #include <Resource_Manager.hxx>
27 #include <Standard_DomainError.hxx>
28 #include <Standard_Dump.hxx>
29 #include <Standard_ErrorHandler.hxx>
30 #include <Standard_NoSuchObject.hxx>
31 #include <Standard_NotImplemented.hxx>
32 #include <TCollection_ExtendedString.hxx>
33 #include <TDocStd_Document.hxx>
34 #include <TDocStd_Owner.hxx>
35 #include <TDocStd_PathParser.hxx>
36 #include <OSD_Thread.hxx>
37
38 IMPLEMENT_STANDARD_RTTIEXT(TDocStd_Application,CDF_Application)
39
40 // TDocStd_Owner attribute have pointer of closed TDocStd_Document
41 //=======================================================================
42 //function : TDocStd_Application
43 //purpose  :
44 //=======================================================================
45 TDocStd_Application::TDocStd_Application()
46         : myIsDriverLoaded (Standard_True)
47 {
48   if(myMetaDataDriver.IsNull())
49     myIsDriverLoaded = Standard_False;
50 }
51
52 //=======================================================================
53 //function : IsDriverLoaded
54 //purpose  :
55 //=======================================================================
56 Standard_Boolean TDocStd_Application::IsDriverLoaded() const
57 {
58   return myIsDriverLoaded;
59 }
60
61 //=======================================================================
62 //function : Resources
63 //purpose  :
64 //=======================================================================
65
66 Handle(Resource_Manager)  TDocStd_Application::Resources()  {
67   if (myResources.IsNull()) {
68     myResources = new Resource_Manager(ResourcesName());
69   }
70   return myResources;
71 }
72
73 //=======================================================================
74 //function : ResourcesName
75 //purpose  :
76 //=======================================================================
77
78 Standard_CString TDocStd_Application::ResourcesName()
79 {
80   return "";
81 }
82
83 //=======================================================================
84 //function : DefineFormat
85 //purpose  : 
86 //=======================================================================
87 void TDocStd_Application::DefineFormat (const TCollection_AsciiString& theFormat,
88                                         const TCollection_AsciiString& theDescription,
89                                         const TCollection_AsciiString& theExtension,
90                                         const Handle(PCDM_RetrievalDriver)& theReader,
91                                         const Handle(PCDM_StorageDriver)& theWriter)
92 {
93   // register resources for CDM mechanics to work
94   Handle(Resource_Manager) aResources = Resources();
95   aResources->SetResource ((theFormat + ".Description"  ).ToCString(), theDescription.ToCString());
96   aResources->SetResource ((theFormat + ".FileExtension").ToCString(), theExtension.ToCString());
97   aResources->SetResource ((theExtension + ".FileFormat").ToCString(), theFormat.ToCString());
98
99   // set format ID in the drivers to allow them putting it in
100   // the OCAF documents opened by these drivers
101   if (!theReader.IsNull())
102     theReader->SetFormat(theFormat);
103   if (!theWriter.IsNull())
104     theWriter->SetFormat(theFormat);
105
106   // register drivers
107   myReaders.Add(theFormat, theReader);
108   myWriters.Add(theFormat, theWriter);
109 }
110
111 //=======================================================================
112 //function : ReadingFormats
113 //purpose  :
114 //=======================================================================
115
116 void TDocStd_Application::ReadingFormats(TColStd_SequenceOfAsciiString &theFormats)
117 {
118         theFormats.Clear();
119
120   NCollection_IndexedDataMap<TCollection_ExtendedString, Handle(PCDM_RetrievalDriver)>::Iterator
121     anIter(myReaders);
122   for (; anIter.More(); anIter.Next()) {
123     Handle(PCDM_RetrievalDriver) aDriver = anIter.Value();
124     if (aDriver.IsNull() == Standard_False) {
125       theFormats.Append(anIter.Key());
126     }
127   }
128 }
129
130 //=======================================================================
131 //function : WritingFormats
132 //purpose  :
133 //=======================================================================
134
135 void TDocStd_Application::WritingFormats(TColStd_SequenceOfAsciiString &theFormats)
136 {
137   theFormats.Clear();
138
139   NCollection_IndexedDataMap<TCollection_ExtendedString, Handle(PCDM_StorageDriver)>::Iterator
140     anIter(myWriters);
141   for (; anIter.More(); anIter.Next()) {
142     Handle(PCDM_StorageDriver) aDriver = anIter.Value();
143     if (aDriver.IsNull() == Standard_False) {
144       theFormats.Append(anIter.Key());
145     }
146   }
147 }
148
149 //=======================================================================
150 //function : NbDocuments
151 //purpose  :
152 //=======================================================================
153
154 Standard_Integer TDocStd_Application::NbDocuments() const
155 {
156   return myDirectory->Length();
157 }
158
159 //=======================================================================
160 //function : GetDocument
161 //purpose  :
162 //=======================================================================
163
164 void TDocStd_Application::GetDocument(const Standard_Integer index,Handle(TDocStd_Document)& aDoc) const
165 {
166   CDF_DirectoryIterator it (myDirectory);
167   Standard_Integer current = 0;
168   for (;it.MoreDocument();it.NextDocument()) {
169     current++;
170     if (index == current) {
171       Handle(TDocStd_Document) D =
172         Handle(TDocStd_Document)::DownCast(it.Document());
173       aDoc = D;
174       return;
175     }
176   }
177 }
178
179 //=======================================================================
180 //function : NewDocument
181 //purpose  :
182 //=======================================================================
183
184 void TDocStd_Application::NewDocument(const TCollection_ExtendedString& format,Handle(TDocStd_Document)& aDoc)
185 {
186   Handle(TDocStd_Document) D = new TDocStd_Document(format);
187   InitDocument (D);
188   CDF_Application::Open(D); // add the document in the session
189   aDoc = D;
190 }
191
192 //=======================================================================
193 //function : InitDocument
194 //purpose  : do nothing
195 //=======================================================================
196
197 void TDocStd_Application::InitDocument(const Handle(TDocStd_Document)& /*aDoc*/) const
198 {
199 }
200
201 //=======================================================================
202 //function : Close
203 //purpose  :
204 //=======================================================================
205
206 void TDocStd_Application::Close(const Handle(TDocStd_Document)& aDoc)
207 {
208   if (aDoc.IsNull())
209   {
210     return;
211   }
212
213   Handle(TDocStd_Owner) Owner;
214   if (aDoc->Main().Root().FindAttribute(TDocStd_Owner::GetID(),Owner)) {
215     Handle(TDocStd_Document) emptyDoc;
216     Owner->SetDocument(emptyDoc);
217   }
218   aDoc->BeforeClose();
219   CDF_Application::Close(aDoc);
220 }
221
222 //=======================================================================
223 //function : IsInSession
224 //purpose  :
225 //=======================================================================
226
227 Standard_Integer TDocStd_Application::IsInSession (const TCollection_ExtendedString& path) const
228 {
229     TCollection_ExtendedString unifiedPath(path);
230     unifiedPath.ChangeAll('/', '|');
231     unifiedPath.ChangeAll('\\', '|');
232
233     Standard_Integer nbdoc = NbDocuments();
234     Handle(TDocStd_Document) D;
235     for (Standard_Integer i = 1; i <= nbdoc; i++) 
236     {
237         GetDocument(i,D);
238         if (D->IsSaved()) 
239         {
240             TCollection_ExtendedString unifiedDocPath(D->GetPath());
241             unifiedDocPath.ChangeAll('/', '|');
242             unifiedDocPath.ChangeAll('\\', '|');
243
244             if (unifiedPath == unifiedDocPath) 
245                 return i;
246         }
247     }
248     return 0;
249 }
250
251 //=======================================================================
252 //function : Open
253 //purpose  :
254 //=======================================================================
255
256 PCDM_ReaderStatus TDocStd_Application::Open (const TCollection_ExtendedString& path, 
257                                              Handle(TDocStd_Document)& aDoc, 
258                                              const Message_ProgressRange& theRange)
259 {
260   PCDM_ReaderStatus status = PCDM_RS_DriverFailure;
261   TDocStd_PathParser tool (path);
262   TCollection_ExtendedString directory = tool.Trek();
263   TCollection_ExtendedString file = tool.Name();
264   file += ".";
265   file += tool.Extension();
266   status = CanRetrieve(directory, file);
267
268   if (status != PCDM_RS_OK)
269   {
270     return status;
271   }
272
273   try
274   {
275     OCC_CATCH_SIGNALS
276     Handle(TDocStd_Document) D =
277       Handle(TDocStd_Document)::DownCast(Retrieve(directory, file, Standard_True, theRange));
278     CDF_Application::Open(D);
279     aDoc = D;
280   }
281   catch (Standard_Failure const& anException)
282   {
283     //    status = GetRetrieveStatus();
284     if (!MessageDriver().IsNull())
285     {
286       //      Standard_SStream aMsg;
287       //      aMsg << Standard_Failure::Caught() << std::endl;
288       //      std::cout << "TDocStd_Application::Open(): " << aMsg.rdbuf()->str() << std::endl;
289       TCollection_ExtendedString aString (anException.GetMessageString());
290       MessageDriver()->Send(aString.ToExtString(), Message_Fail);
291     }
292   }
293   status = GetRetrieveStatus();
294 #ifdef OCCT_DEBUG
295   std::cout << "TDocStd_Application::Open(): The status = " << status << std::endl;
296 #endif
297   return status;
298 }
299
300 //=======================================================================
301 //function : Open
302 //purpose  :
303 //=======================================================================
304 PCDM_ReaderStatus TDocStd_Application::Open (Standard_IStream& theIStream,
305                                              Handle(TDocStd_Document)& theDoc,
306                                              const Message_ProgressRange& theRange)
307
308   try
309   {
310     OCC_CATCH_SIGNALS
311     Handle(TDocStd_Document) D = Handle(TDocStd_Document)::DownCast(Read(theIStream, theRange));
312
313     if (!D.IsNull())
314     {
315       CDF_Application::Open(D);
316       theDoc = D;
317     }
318   }
319
320   catch (Standard_Failure const& anException)
321   {
322     if (!MessageDriver().IsNull())
323     {
324       TCollection_ExtendedString aFailureMessage (anException.GetMessageString());
325       MessageDriver()->Send (aFailureMessage.ToExtString(), Message_Fail);
326     }
327   }
328   return GetRetrieveStatus();
329 }
330
331 //=======================================================================
332 //function : SaveAs
333 //purpose  :
334 //=======================================================================
335
336 PCDM_StoreStatus TDocStd_Application::SaveAs (const Handle(TDocStd_Document)& D, 
337                                               const TCollection_ExtendedString& path,
338                                               const Message_ProgressRange& theRange)
339 {
340   TDocStd_PathParser tool (path);
341   TCollection_ExtendedString directory = tool.Trek();
342   TCollection_ExtendedString file = tool.Name();
343   file+=".";
344   file+=tool.Extension();
345   D->Open(this);
346   CDF_Store storer (D);
347   if (!storer.SetFolder(directory))
348   {
349     TCollection_ExtendedString aMsg ("TDocStd_Application::SaveAs() - folder ");
350     aMsg += directory;
351     aMsg += " does not exist";
352     if(!MessageDriver().IsNull())
353       MessageDriver()->Send(aMsg.ToExtString(), Message_Fail);
354     return storer.StoreStatus(); //CDF_SS_Failure;
355   }
356   storer.SetName (file);
357   try {
358     OCC_CATCH_SIGNALS
359     storer.Realize (theRange);
360   }
361   catch (Standard_Failure const& anException) {
362     if (!MessageDriver().IsNull()) {
363       TCollection_ExtendedString aString (anException.GetMessageString());
364       MessageDriver()->Send(aString.ToExtString(), Message_Fail);
365     }
366   }
367   if(storer.StoreStatus() == PCDM_SS_OK)
368     D->SetSaved();
369 #ifdef OCCT_DEBUG
370   std::cout<<"TDocStd_Application::SaveAs(): The status = "<<storer.StoreStatus()<<std::endl;
371 #endif
372   return storer.StoreStatus();
373 }
374
375 //=======================================================================
376 //function : SaveAs
377 //purpose  :
378 //=======================================================================
379 PCDM_StoreStatus TDocStd_Application::SaveAs(const Handle(TDocStd_Document)& theDoc, 
380                                              Standard_OStream& theOStream,
381                                              const Message_ProgressRange& theRange)
382 {
383   try
384   {
385     Handle(PCDM_StorageDriver) aDocStorageDriver = WriterFromFormat(theDoc->StorageFormat());
386
387     if (aDocStorageDriver.IsNull())
388     {
389       return PCDM_SS_DriverFailure;
390     }
391
392     aDocStorageDriver->SetFormat(theDoc->StorageFormat());
393     aDocStorageDriver->Write(theDoc, theOStream, theRange);
394
395     if (aDocStorageDriver->GetStoreStatus() == PCDM_SS_OK)
396     {
397       theDoc->SetSaved();
398     }
399
400     return aDocStorageDriver->GetStoreStatus();
401   }
402   catch (Standard_Failure const& anException)
403   {
404     if (!MessageDriver().IsNull())
405     {
406       TCollection_ExtendedString aString(anException.GetMessageString());
407       MessageDriver()->Send(aString.ToExtString(), Message_Fail);
408     }
409   }
410   return PCDM_SS_Failure;
411 }
412
413 //=======================================================================
414 //function : Save
415 //purpose  :
416 //=======================================================================
417
418 PCDM_StoreStatus TDocStd_Application::Save (const Handle(TDocStd_Document)& D,
419                                             const Message_ProgressRange&    theRange)
420 {
421   PCDM_StoreStatus status = PCDM_SS_OK;
422   if (D->IsSaved()) {
423     CDF_Store storer (D);
424     try{
425       OCC_CATCH_SIGNALS
426       storer.Realize (theRange);
427     }
428     catch (Standard_Failure const& anException) {
429       if (!MessageDriver().IsNull()) {
430         TCollection_ExtendedString aString (anException.GetMessageString());
431         MessageDriver()->Send(aString.ToExtString(), Message_Fail);
432       }
433     }
434     if(storer.StoreStatus() == PCDM_SS_OK)
435       D->SetSaved();
436     status = storer.StoreStatus();
437   } else {
438     if(!MessageDriver().IsNull()) {
439       TCollection_ExtendedString aMsg("Document has not been saved yet");
440       MessageDriver()->Send(aMsg.ToExtString(), Message_Fail);
441     }
442     status = PCDM_SS_Failure;
443   }
444 #ifdef OCCT_DEBUG
445   std::cout<<"TDocStd_Application::Save(): The status = "<<status<<std::endl;
446 #endif
447   return status;
448 }
449
450 //=======================================================================
451 //function : SaveAs
452 //purpose  : 
453 //=======================================================================
454
455 PCDM_StoreStatus TDocStd_Application::SaveAs(const Handle(TDocStd_Document)& D,
456                                              const TCollection_ExtendedString& path,
457                                              TCollection_ExtendedString& theStatusMessage,
458                                              const Message_ProgressRange& theRange)
459
460   TDocStd_PathParser tool (path);
461   PCDM_StoreStatus aStatus = PCDM_SS_Failure;
462   TCollection_ExtendedString directory = tool.Trek();   
463   TCollection_ExtendedString file = tool.Name();   
464   file+=".";   
465   file+=tool.Extension();
466   D->Open(this);
467   CDF_Store storer (D);  
468   if (storer.SetFolder(directory)) {
469     storer.SetName (file);
470     try {
471       OCC_CATCH_SIGNALS
472       storer.Realize (theRange);
473     }
474     catch (Standard_Failure const& anException) {
475       if (!MessageDriver().IsNull()) {
476         TCollection_ExtendedString aString (anException.GetMessageString());
477         MessageDriver()->Send(aString.ToExtString(), Message_Fail);
478       }
479     }
480     if(storer.StoreStatus() == PCDM_SS_OK)
481       D->SetSaved();
482     theStatusMessage = storer.AssociatedStatusText();
483     aStatus = storer.StoreStatus();
484   } else {
485     theStatusMessage =
486       TCollection_ExtendedString("TDocStd_Application::SaveAs"
487                                  ": No such directory ") + directory;
488     aStatus = PCDM_SS_Failure;
489   }
490   return aStatus;
491 }
492
493 //=======================================================================
494 //function : SaveAs
495 //purpose  : 
496 //=======================================================================
497
498 PCDM_StoreStatus TDocStd_Application::SaveAs (const Handle(TDocStd_Document)& theDoc,
499                                               Standard_OStream&               theOStream,
500                                               TCollection_ExtendedString&     theStatusMessage,
501                                               const Message_ProgressRange&    theRange)
502
503   try
504   {
505     Handle(PCDM_StorageDriver) aDocStorageDriver = WriterFromFormat (theDoc->StorageFormat());
506     if (aDocStorageDriver.IsNull())
507     {
508       theStatusMessage = TCollection_ExtendedString("TDocStd_Application::SaveAs: no storage driver");
509       return PCDM_SS_DriverFailure;
510     }
511
512     aDocStorageDriver->SetFormat(theDoc->StorageFormat());
513     aDocStorageDriver->Write(theDoc, theOStream, theRange);
514         
515     if (aDocStorageDriver->GetStoreStatus() == PCDM_SS_OK)
516     {
517       theDoc->SetSaved();
518     }
519
520     return aDocStorageDriver->GetStoreStatus();
521   }
522   catch (Standard_Failure const& anException)
523   {
524     if (!MessageDriver().IsNull())
525     {
526       TCollection_ExtendedString aString(anException.GetMessageString());
527       MessageDriver()->Send(aString.ToExtString(), Message_Fail);
528     }
529   }
530   return PCDM_SS_Failure;
531 }
532
533 //=======================================================================
534 //function : Save
535 //purpose  : 
536 //=======================================================================
537
538 PCDM_StoreStatus TDocStd_Application::Save (const Handle(TDocStd_Document)& D,
539                                             TCollection_ExtendedString&     theStatusMessage, 
540                                             const Message_ProgressRange&    theRange)
541 {  
542   PCDM_StoreStatus status = PCDM_SS_OK;
543   if (D->IsSaved()) {  
544     CDF_Store storer (D);  
545     try {
546       OCC_CATCH_SIGNALS
547       storer.Realize (theRange);
548     }
549     catch (Standard_Failure const& anException) {
550       if (!MessageDriver().IsNull()) {
551         TCollection_ExtendedString aString (anException.GetMessageString());
552         MessageDriver()->Send(aString.ToExtString(), Message_Fail);
553       }
554     }
555     if(storer.StoreStatus() == PCDM_SS_OK)
556       D->SetSaved();
557     status = storer.StoreStatus();
558     theStatusMessage = storer.AssociatedStatusText();
559   } else {
560     theStatusMessage = "TDocStd_Application::the document has not been saved yet";
561     status = PCDM_SS_Failure;
562   }
563   return status;
564 }
565
566
567 //=======================================================================
568 //function : OnOpenTransaction
569 //purpose  : 
570 //=======================================================================
571
572 void TDocStd_Application::OnOpenTransaction (const Handle(TDocStd_Document)&)
573 {
574   // nothing to do on this level
575 }
576
577 //=======================================================================
578 //function : OnAbortTransaction
579 //purpose  : 
580 //=======================================================================
581
582 void TDocStd_Application::OnAbortTransaction (const Handle(TDocStd_Document)&)
583 {
584   // nothing to do on this level
585 }
586
587 //=======================================================================
588 //function : OnCommitTransaction
589 //purpose  : 
590 //=======================================================================
591
592 void TDocStd_Application::OnCommitTransaction (const Handle(TDocStd_Document)&)
593 {
594   // nothing to do on this level
595 }
596
597 //=======================================================================
598 //function : DumpJson
599 //purpose  : 
600 //=======================================================================
601 void TDocStd_Application::DumpJson (Standard_OStream& theOStream, Standard_Integer) const
602 {
603   OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
604
605   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsDriverLoaded)
606 }