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