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