1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef __FRAMEWORK_SERVICES_AUTORECOVERY_HXX_
25 #define __FRAMEWORK_SERVICES_AUTORECOVERY_HXX_
26 
27 //_______________________________________________
28 // own includes
29 
30 #include <threadhelp/threadhelpbase.hxx>
31 #include <macros/xinterface.hxx>
32 #include <macros/xtypeprovider.hxx>
33 #include <macros/xserviceinfo.hxx>
34 #include <general.h>
35 #include <stdtypes.h>
36 
37 //_______________________________________________
38 // interface includes
39 #include <com/sun/star/uno/XInterface.hpp>
40 #include <com/sun/star/lang/XTypeProvider.hpp>
41 #include <com/sun/star/lang/XServiceInfo.hpp>
42 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
43 #include <com/sun/star/frame/XDispatch.hpp>
44 #include <com/sun/star/container/XNameAccess.hpp>
45 #include <com/sun/star/document/XEventListener.hpp>
46 #include <com/sun/star/document/XEventBroadcaster.hpp>
47 #include <com/sun/star/frame/XModel.hpp>
48 #include <com/sun/star/util/XChangesListener.hpp>
49 #include <com/sun/star/task/XStatusIndicator.hpp>
50 #include <com/sun/star/util/XModifyListener.hpp>
51 
52 //_______________________________________________
53 // other includes
54 #include <comphelper/mediadescriptor.hxx>
55 #include <vcl/timer.hxx>
56 #include <vcl/evntpost.hxx>
57 #include <cppuhelper/interfacecontainer.hxx>
58 #include <cppuhelper/propshlp.hxx>
59 #include <cppuhelper/weak.hxx>
60 
61 //_______________________________________________
62 // definition
63 
64 #ifndef css
65 namespace css = ::com::sun::star;
66 #endif
67 
68 namespace framework
69 {
70 
71 //---------------------------------------
72 /** @short  hold all needed informations for an asynchronous dispatch alive.
73 
74     @descr  Because some operations are forced to be executed asynchronously
75             (e.g. requested by our CreashSave/Recovery dialog) ... we must make sure
76             that these informations won't be set as "normal" members of our AutoRecovery
77             instance. Otherwise they can disturb our normal AutoSave-timer handling.
78             e.g. it can be unclear then, which progress has to be used for storing documents ...
79  */
80 struct DispatchParams
81 {
82     public:
83          DispatchParams();
84          DispatchParams(const ::comphelper::SequenceAsHashMap&             lArgs ,
85                         const css::uno::Reference< css::uno::XInterface >& xOwner);
86          DispatchParams(const DispatchParams& rCopy);
87         ~DispatchParams();
88 
89          DispatchParams& operator=(const DispatchParams& rCopy);
90          void forget();
91 
92     public:
93 
94         //---------------------------------------
95         /** @short  can be set from outside and is provided to
96                     our internal started operations.
97 
98             @descr  Normally we use the normal status indicator
99                     of the document windows to show a progress.
100                     But in case we are used by any special UI,
101                     it can provide its own status indicator object
102                     to us - so we use it instead of the normal one.
103          */
104         css::uno::Reference< css::task::XStatusIndicator > m_xProgress;
105 
106         //---------------------------------------
107         /** TODO document me */
108         ::rtl::OUString m_sSavePath;
109 
110         //---------------------------------------
111         /** @short  define the current cache entry, which should be used for current
112                     backup or cleanUp operation ... which is may be done asynchronous */
113         sal_Int32 m_nWorkingEntryID;
114 
115         //---------------------------------------
116         /** @short  used for asyncoperations, to prevent us from dying.
117 
118             @descr  If our dispatch() method was forced to start the
119                     internal operation asynchronous ... we send an event
120                     to start and return immediately. But we must be sure that
121                     our instance live if the event callback reach us.
122                     So we hold an uno reference to ourself.
123          */
124         css::uno::Reference< css::uno::XInterface > m_xHoldRefForAsyncOpAlive;
125 };
126 
127 //_______________________________________________
128 /**
129     implements the functionality of AutoSave and AutoRecovery
130     of documents - including features of an EmergencySave in
131     case a GPF occurs.
132  */
133 class AutoRecovery  : public  css::lang::XTypeProvider
134                     , public  css::lang::XServiceInfo
135                     , public  css::frame::XDispatch
136                     , public  css::document::XEventListener         // => css.lang.XEventListener
137                     , public  css::util::XChangesListener           // => css.lang.XEventListener
138                     , public  css::util::XModifyListener            // => css.lang.XEventListener
139                     // attention! Must be the first base class to guarantee right initialize lock ...
140                     , private ThreadHelpBase
141                     , public  ::cppu::OBroadcastHelper
142                     , public  ::cppu::OPropertySetHelper            // => XPropertySet, XFastPropertySet, XMultiPropertySet
143                     , public  ::cppu::OWeakObject
144 {
145     //___________________________________________
146     // types
147 
148     public:
149 
150         /** These values are used as flags and represent the current state of a document.
151             Every state of the life time of a document has to be recognized here.
152 
153             @attention  Do not change (means reorganize) already used numbers.
154                         There exists some code inside SVX, which uses the same numbers,
155                         to analyze such document states.
156                         Not the best design ... but may be it will be changed later .-)
157         */
158         enum EDocStates
159         {
160             /* TEMP STATES */
161 
162             /// default state, if a document was new created or loaded
163             E_UNKNOWN = 0,
164             /// modified against the original file
165             E_MODIFIED = 1,
166             /// an active document can be postponed to be saved later.
167             E_POSTPONED = 2,
168             /// was already handled during one AutoSave/Recovery session.
169             E_HANDLED = 4,
170             /** an action was started (saving/loading) ... Can be interesting later if the process may be was interrupted by an exception. */
171             E_TRY_SAVE = 8,
172             E_TRY_LOAD_BACKUP = 16,
173             E_TRY_LOAD_ORIGINAL = 32,
174 
175             /* FINAL STATES */
176 
177             /// the Auto/Emergency saved document isn't useable any longer
178             E_DAMAGED = 64,
179             /// the Auto/Emergency saved document isn't really up-to-date (some changes can be missing)
180             E_INCOMPLETE = 128,
181             /// the Auto/Emergency saved document was processed successfully
182             E_SUCCEDED = 512
183         };
184 
185         /** @short  indicates the results of a FAILURE_SAFE operation
186 
187             @descr  We must know, which reason was the real one in case
188                     we couldn't copy a "failure document" to a user specified path.
189                     We must know, if we can forget our cache entry or not.
190          */
191         enum EFailureSafeResult
192         {
193             E_COPIED,
194             E_ORIGINAL_FILE_MISSING,
195             E_WRONG_TARGET_PATH
196         };
197 
198         // TODO document me
199         enum ETimerType
200         {
201             /** the timer shouldn't be used next time */
202             E_DONT_START_TIMER,
203             /** timer (was/must be) started with normal AutoSaveTimeIntervall */
204             E_NORMAL_AUTOSAVE_INTERVALL,
205             /** timer must be started with special short time intervall,
206                 to poll for an user idle period */
207             E_POLL_FOR_USER_IDLE,
208             /** timer mst be started with a very(!) short time intervall,
209                 to poll for the end of an user action, which does not allow saving documents in general */
210             E_POLL_TILL_AUTOSAVE_IS_ALLOWED,
211             /** dont start the timer - but calls the same action then before immediately again! */
212             E_CALL_ME_BACK
213         };
214 
215         // TODO document me ... flag field
216         // Emergency_Save and Recovery overwrites Auto_Save!
217         enum EJob
218         {
219             E_NO_JOB                    =   0,
220             E_AUTO_SAVE                 =   1,
221             E_EMERGENCY_SAVE            =   2,
222             E_RECOVERY                  =   4,
223             E_ENTRY_BACKUP              =   8,
224             E_ENTRY_CLEANUP             =  16,
225             E_PREPARE_EMERGENCY_SAVE    =  32,
226             E_SESSION_SAVE              =  64,
227             E_SESSION_RESTORE           = 128,
228             E_DISABLE_AUTORECOVERY      = 256,
229             E_SET_AUTOSAVE_STATE        = 512,
230             E_SESSION_QUIET_QUIT        = 1024
231         };
232 
233         //---------------------------------------
234         /** @short  combine different informations about one office document. */
235         struct TDocumentInfo
236         {
237             public:
238 
239                 //-------------------------------
TDocumentInfoframework::AutoRecovery::TDocumentInfo240                 TDocumentInfo()
241 					: DocumentState   (E_UNKNOWN)
242                     , UsedForSaving   (sal_False)
243                     , ListenForModify (sal_False)
244                     , IgnoreClosing   (sal_False)
245                     , ID              (-1       )
246                 {}
247 
248                 //-------------------------------
249                 /** @short  points to the document. */
250                 css::uno::Reference< css::frame::XModel > Document;
251 
252                 //-------------------------------
253                 /** @short  knows, if the document is really modified since the last autosave,
254                             or was postponed, because it was an active one etcpp...
255 
256                     @descr  Because we have no CHANGE TRACKING mechanism, based on office document,
257                             we implement it by ourself. We listen for MODIFIED events
258                             of each document and update this state flag here.
259 
260                             Further we postpone saving of active documents, e.g. if the user
261                             works currently on it. We wait for an idle period then ...
262                  */
263                 sal_Int32 DocumentState;
264 
265                 //-------------------------------
266                 /** Because our applications not ready for concurrent save requests at the same time,
267                     we have suppress our own AutoSave for the moment, a document will be already saved
268                     by others.
269                  */
270                 sal_Bool UsedForSaving;
271 
272                 //-------------------------------
273                 /** For every user action, which modifies a document (e.g. key input) we get
274                     a notification as XModifyListener. That seems to be a "performance issue" .-)
275                     So we decided to listen for such modify events only for the time in which the document
276                     was stored as temp. file and was not modified again by the user.
277                 */
278                 sal_Bool ListenForModify;
279 
280                 //-------------------------------
281                 /** For SessionSave we must close all open documents by ourself.
282                     But because we are listen for documents events, we get some ...
283                     and deregister these documents from our configuration.
284                     That's why we mark these documents as "Closed by ourself" so we can
285                     ignore these "OnUnload" or disposing() events .-)
286                 */
287                 sal_Bool IgnoreClosing;
288 
289                 //-------------------------------
290                 /** TODO: document me */
291                 ::rtl::OUString OrgURL;
292                 ::rtl::OUString FactoryURL;
293                 ::rtl::OUString TemplateURL;
294 
295                 ::rtl::OUString OldTempURL;
296                 ::rtl::OUString NewTempURL;
297 
298                 ::rtl::OUString AppModule;      // e.g. com.sun.star.text.TextDocument - used to identify app module
299                 ::rtl::OUString FactoryService; // the service to create a document of the module
300                 ::rtl::OUString RealFilter;     // real filter, which was used at loading time
301                 ::rtl::OUString DefaultFilter;  // supports saving of the default format without losing data
302                 ::rtl::OUString Extension;      // file extension of the default filter
303                 ::rtl::OUString Title;          // can be used as "DisplayName" on every recovery UI!
304                 ::com::sun::star::uno::Sequence< ::rtl::OUString >
305                                 ViewNames;      // names of the view which were active at emergency-save time
306 
307                 sal_Int32 ID;
308         };
309 
310         //---------------------------------------
311         /** @short  used to know every currently open document. */
312         typedef ::std::vector< TDocumentInfo > TDocumentList;
313 
314     //___________________________________________
315     // member
316 
317     private:
318 
319         //---------------------------------------
320         /** @short  the global uno service manager.
321             @descr  Must be used to create own needed services.
322          */
323         css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR;
324 
325         //---------------------------------------
326         /** @short  points to the underlying recovery configuration.
327             @descr  This instance does not cache - it calls directly the
328                     configuration API!
329           */
330         css::uno::Reference< css::container::XNameAccess > m_xRecoveryCFG;
331 
332         //---------------------------------------
333         /** @short  points to the used configuration package or.openoffice.Setup
334             @descr  This instance does not cache - it calls directly the
335                     configuration API!
336           */
337         css::uno::Reference< css::container::XNameAccess > m_xModuleCFG;
338 
339         //---------------------------------------
340         /** @short  holds the global event broadcaster alive,
341                     where we listen for new created documents.
342           */
343         css::uno::Reference< css::document::XEventBroadcaster > m_xNewDocBroadcaster;
344 
345         //---------------------------------------
346         /** @short  because we stop/restart listening sometimes, it's a good idea to know
347                     if we already registered as listener .-)
348         */
349         sal_Bool m_bListenForDocEvents;
350         sal_Bool m_bListenForConfigChanges;
351 
352         //---------------------------------------
353         /** @short  specify the time intervall between two save actions.
354             @descr  Time is measured in [min].
355          */
356         sal_Int32 m_nAutoSaveTimeIntervall;
357 
358         //---------------------------------------
359         /** @short  for an asynchronous operation we must know, if there is
360                     at least one running job (may be asynchronous!).
361          */
362         sal_Int32 m_eJob;
363 
364         //---------------------------------------
365         /** @short  the timer, which is used to be informed about the next
366                     saving time ...
367          */
368         Timer m_aTimer;
369 
370         //---------------------------------------
371         /** @short  make our dispatch asynchronous ... if required to do so! */
372         ::vcl::EventPoster m_aAsyncDispatcher;
373 
374         //---------------------------------------
375         /** @see    DispatchParams
376          */
377         DispatchParams m_aDispatchParams;
378 
379         //---------------------------------------
380         /** @short  indicates, which time period is currently used by the
381                     internal timer.
382          */
383         ETimerType m_eTimerType;
384 
385         //---------------------------------------
386         /** @short  this cache is used to hold all informations about
387                     recovery/emergency save documents alive.
388          */
389         TDocumentList m_lDocCache;
390 
391         //---------------------------------------
392         // TODO document me
393         sal_Int32 m_nIdPool;
394 
395         //---------------------------------------
396         /** @short  contains all status listener registered at this instance.
397          */
398         ListenerHash m_lListener;
399 
400         /** @descr  This member is used to prevent us against re-entrance problems.
401                     A mutex can't help to prevent us from concurrent using of members
402                     inside the same thread. But e.g. our internally used stl structures
403                     are not threadsafe ... and furthermore they can't be used at the same time
404                     for iteration and add/remove requests!
405                     So we have to detect such states and ... show a warning.
406                     May be there will be a better solution next time ... (copying the cache temp.
407                     before using).
408 
409                     And further it's not possible to use a simple boolean value here.
410                     Because if more than one operation iterates over the same stl container ...
411                     (only to modify its elements but don't add new or remove existing ones!)
412                     it should be possible doing so. But we must guarantee that the last operation resets
413                     this lock ... not the first one ! So we use a "ref count" mechanism for that."
414          */
415         sal_Int32 m_nDocCacheLock;
416 
417         /** @descr  These members are used to check the minimum disc space, which must exists
418                     to start the corresponding operation.
419          */
420         sal_Int32 m_nMinSpaceDocSave;
421         sal_Int32 m_nMinSpaceConfigSave;
422 
423         //---------------------------------------
424         /** @short  special debug option to make testing faster.
425 
426             @descr  We don't interpret the timer unit as [min] ...
427                     we use [ms] instead of that. Further we don't
428                     wait 10 s for user idle ...
429          */
430         #if OSL_DEBUG_LEVEL > 1
431         sal_Bool m_dbg_bMakeItFaster;
432         #endif
433 
434         //---------------------------------------
435         // HACK ... TODO
436         css::uno::Reference< css::task::XStatusIndicator > m_xExternalProgress;
437 
438     //___________________________________________
439     // interface
440 
441     public:
442 
443                  AutoRecovery(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR);
444         virtual ~AutoRecovery(                                                                   );
445 
446         // XInterface, XTypeProvider, XServiceInfo
447         FWK_DECLARE_XINTERFACE
448         FWK_DECLARE_XTYPEPROVIDER
449         DECLARE_XSERVICEINFO
450 
451         //---------------------------------------
452         // css.frame.XDispatch
453         virtual void SAL_CALL dispatch(const css::util::URL&                                  aURL      ,
454                                        const css::uno::Sequence< css::beans::PropertyValue >& lArguments)
455             throw(css::uno::RuntimeException);
456 
457         virtual void SAL_CALL addStatusListener(const css::uno::Reference< css::frame::XStatusListener >& xListener,
458                                                 const css::util::URL&                                     aURL     )
459             throw(css::uno::RuntimeException);
460 
461         virtual void SAL_CALL removeStatusListener(const css::uno::Reference< css::frame::XStatusListener >& xListener,
462                                                    const css::util::URL&                                     aURL     )
463             throw(css::uno::RuntimeException);
464 
465         //---------------------------------------
466         // css.document.XEventListener
467         /** @short  informs about created/opened documents.
468 
469             @descr  Every new opened/created document will be saved internally
470                     so it can be checked if it's modified. This modified state
471                     is used later to decide, if it must be saved or not.
472 
473             @param  aEvent
474                     points to the new created/opened document.
475          */
476         virtual void SAL_CALL notifyEvent(const css::document::EventObject& aEvent)
477             throw(css::uno::RuntimeException);
478 
479         //---------------------------------------
480         // css.util.XChangesListener
481         virtual void SAL_CALL changesOccurred(const css::util::ChangesEvent& aEvent)
482             throw(css::uno::RuntimeException);
483 
484         //---------------------------------------
485         // css.util.XModifyListener
486         virtual void SAL_CALL modified(const css::lang::EventObject& aEvent)
487             throw(css::uno::RuntimeException);
488 
489         //---------------------------------------
490         // css.lang.XEventListener
491         using cppu::OPropertySetHelper::disposing;
492         virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent)
493             throw(css::uno::RuntimeException);
494 
495     //___________________________________________
496     // helper
497 
498 	protected:
499 
500         //---------------------------------------
501 		// OPropertySetHelper
502 
503 		virtual sal_Bool SAL_CALL convertFastPropertyValue(      css::uno::Any& aConvertedValue,
504                                                                  css::uno::Any&	aOldValue      ,
505                                                                  sal_Int32		nHandle        ,
506                                                            const css::uno::Any&	aValue         )
507             throw(css::lang::IllegalArgumentException);
508 
509 		virtual void SAL_CALL setFastPropertyValue_NoBroadcast(      sal_Int32      nHandle,
510                                                                const css::uno::Any& aValue )
511             throw(css::uno::Exception);
512         using cppu::OPropertySetHelper::getFastPropertyValue;
513 		virtual void SAL_CALL getFastPropertyValue(css::uno::Any& aValue ,
514                                                    sal_Int32      nHandle) const;
515 
516 		virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
517 
518 		virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo()
519             throw(css::uno::RuntimeException);
520     //___________________________________________
521     // helper
522 
523     private:
524 
525         //---------------------------------------
526         /** @short  open the underlying configuration.
527 
528             @descr  This method must be called every time
529                     a configuartion call is needed. Because
530                     method works together with the member
531                     m_xCFG, open it on demand and cache it
532                     afterwards.
533 
534             @return [com.sun.star.container.XNameAccess]
535                     the configuration object
536 
537             @throw  [com.sun.star.uno.RuntimeException]
538                     if config could not be opened successfully!
539 
540             @threadsafe
541           */
542         css::uno::Reference< css::container::XNameAccess > implts_openConfig();
543 
544         //---------------------------------------
545         /** @short  read the underlying configuration.
546 
547             @descr  After that we know the initial state - means:
548                     - if AutoSave was enabled by the user
549                     - which time intervall has to be used
550                     - which recovery entries may already exist
551 
552             @throw  [com.sun.star.uno.RuntimeException]
553                     if config could not be opened or read successfully!
554 
555             @threadsafe
556           */
557         void implts_readConfig();
558 
559         //---------------------------------------
560         /** @short  read the underlying configuration...
561 
562             @descr  ... but only keys related to the AutoSave mechanism.
563                     Means: State and Timer intervall.
564                     E.g. the recovery list isn't addressed here.
565 
566             @throw  [com.sun.star.uno.RuntimeException]
567                     if config could not be opened or readed successfully!
568 
569             @threadsafe
570           */
571         void implts_readAutoSaveConfig();
572 
573         //---------------------------------------
574         // TODO document me
575         void implts_flushConfigItem(const AutoRecovery::TDocumentInfo& rInfo                ,
576                                           sal_Bool                     bRemoveIt = sal_False);
577 
578         //---------------------------------------
579         // TODO document me
580         void implts_startListening();
581         void implts_startModifyListeningOnDoc(AutoRecovery::TDocumentInfo& rInfo);
582 
583         //---------------------------------------
584         // TODO document me
585         void implts_stopListening();
586         void implts_stopModifyListeningOnDoc(AutoRecovery::TDocumentInfo& rInfo);
587 
588         //---------------------------------------
589         /** @short  stops and may be(!) restarts the timer.
590 
591             @descr  A running timer is stopped everytimes here.
592                     But starting depends from the different internal
593                     timer variables (e.g. AutoSaveEnabled, AutoSaveTimeIntervall,
594                     TimerType etcpp.)
595 
596             @throw  [com.sun.star.uno.RuntimeException]
597                     if timer could not be stopped or started!
598 
599             @threadsafe
600          */
601         void implts_updateTimer();
602 
603         //---------------------------------------
604         /** @short  stop the timer.
605 
606             @descr  Double calls will be ignored - means we do
607                     nothing here, if the timer is already disabled.
608 
609             @throw  [com.sun.star.uno.RuntimeException]
610                     if timer could not be stopped!
611 
612             @threadsafe
613          */
614         void implts_stopTimer();
615 
616         //---------------------------------------
617         /** @short  callback of our internal timer.
618          */
619         DECL_LINK(implts_timerExpired, void*);
620 
621         //---------------------------------------
622         /** @short  makes our dispatch() method asynchronous!
623          */
624         DECL_LINK(implts_asyncDispatch, void*);
625 
626         //---------------------------------------
627         /** @short  implements the dispatch real. */
628         void implts_dispatch(const DispatchParams& aParams);
629 
630         //---------------------------------------
631         /** @short  validate new detected document and add it into the internal
632                     document list.
633 
634             @descr  This method should be called only, if its clear that a new
635                     document was opened/created during office runtime.
636                     This method checks, if its a top level document (means not an embedded one).
637                     Only such top level documents can be recognized by this auto save mechanism.
638 
639             @param  xDocument
640                     the new document, which should be checked and registered.
641 
642             @threadsafe
643          */
644         void implts_registerDocument(const css::uno::Reference< css::frame::XModel >& xDocument);
645 
646         //---------------------------------------
647         /** @short  remove the specified document from our internal document list.
648 
649             @param  xDocument
650                     the new document, which should be deregistered.
651 
652             @param  bStopListening
653                     sal_False: must be used in case this method is called withion disposing() of the document,
654                            where it make no sense to deregister our listener. The container dies ...
655                     sal_True : must be used in case this method is used on "dergistration" of this document, where
656                            we must deregister our listener .-)
657 
658             @threadsafe
659          */
660         void implts_deregisterDocument(const css::uno::Reference< css::frame::XModel >& xDocument                ,
661                                              sal_Bool                                   bStopListening = sal_True);
662 
663         //---------------------------------------
664         // TODO document me
665         void implts_markDocumentModifiedAgainstLastBackup(const css::uno::Reference< css::frame::XModel >& xDocument);
666 
667         //---------------------------------------
668         // TODO document me
669         void implts_updateModifiedState(const css::uno::Reference< css::frame::XModel >& xDocument);
670 
671         //---------------------------------------
672         // TODO document me
673         void implts_updateDocumentUsedForSavingState(const css::uno::Reference< css::frame::XModel >& xDocument      ,
674                                                            sal_Bool                                   bSaveInProgress);
675 
676         //---------------------------------------
677         // TODO document me
678         void implts_markDocumentAsSaved(const css::uno::Reference< css::frame::XModel >& xDocument);
679 
680         //---------------------------------------
681         /** @short  search a document inside given list.
682 
683             @param  rList
684                     reference to a vector, which can contain such
685                     document.
686 
687             @param  xDocument
688                     the document, which should be located inside the
689                     given list.
690 
691             @return [TDocumentList::iterator]
692                     which points to the located document.
693                     If document does not exists - its set to
694                     rList.end()!
695          */
696         static TDocumentList::iterator impl_searchDocument(      AutoRecovery::TDocumentList&               rList    ,
697                                                            const css::uno::Reference< css::frame::XModel >& xDocument);
698 
699         //---------------------------------------
700         /** TODO document me */
701         void implts_changeAllDocVisibility(sal_Bool bVisible);
702         void implts_prepareSessionShutdown();
703 
704         //---------------------------------------
705         /** @short  save all current opened documents to a specific
706                     backup directory.
707 
708             @descr  Only really changed documents will be saved here.
709 
710                     Further this method returns a suggestion, if and how it should
711                     be called again. May be some documents was not saved yet
712                     and must wait for an user idle period ...
713 
714             @param  bAllowUserIdleLoop
715                     Because this method is used for different uses cases, it must
716                     know, which actions are allowed or not.
717                     AUTO_SAVE =>
718                                  If a document is the most active one, saving it
719                                  will be postponed if there exists other unsaved
720                                  documents. This feature was implemented, because
721                                  we don't wish to disturb the user on its work.
722                                  ... bAllowUserIdleLoop should be set to sal_True
723                     EMERGENCY_SAVE / SESSION_SAVE =>
724                                  Here we must finish our work ASAP! It's not allowed
725                                  to postpone any document.
726                                  ... bAllowUserIdleLoop must(!) be set to sal_False
727 
728             @param  pParams
729                     sometimes this method is required inside an external dispatch request.
730                     It contains some special environment variables, which overwrites
731                     our normal environment.
732                     AutoSave              => pParams == 0
733                     SessionSave/CrashSave => pParams != 0
734 
735             @return A suggestion, how the timer (if it's not already disabled!)
736                     should be restarted to fulfill the requirements.
737 
738             @threadsafe
739          */
740         AutoRecovery::ETimerType implts_saveDocs(      sal_Bool        bAllowUserIdleLoop,
741                                                        sal_Bool        bRemoveLockFiles,
742                                                  const DispatchParams* pParams        = 0);
743 
744         //---------------------------------------
745         /** @short  save one of the current documents to a specific
746                     backup directory.
747 
748             @descr  It:
749                     - defines a new(!) unique temp file name
750                     - save the new temp file
751                     - remove the old temp file
752                     - patch the given info struct
753                     - and return errors.
754 
755                     It does not:
756                     - patch the configuration.
757 
758                     Note further: It paches the info struct
759                     more than once. E.g. the new temp URL is set
760                     before the file is saved. And the old URL is removed
761                     only if removing of the old file was successfully.
762                     If this method returns without an exception - everything
763                     was OK. Otherwise the info struct can be analyzed to
764                     get more information, e.g. when the problem occurs.
765 
766             @param  sBackupPath
767                     the base path for saving such temp files.
768 
769             @param  rInfo
770                     points to an informations structure, where
771                     e.g. the document, its modified state, the count
772                     of autosave-retries etcpp. exists.
773                     It's used also to return the new temp file name
774                     and some other state values!
775 
776             @threadsafe
777           */
778         void implts_saveOneDoc(const ::rtl::OUString&                                    sBackupPath      ,
779                                      AutoRecovery::TDocumentInfo&                        rInfo            ,
780                                const css::uno::Reference< css::task::XStatusIndicator >& xExternalProgress);
781 
782         //---------------------------------------
783         /** @short  recovery all documents, which was saved during
784                     a crash before.
785 
786             @return A suggestion, how this method must be called back!
787 
788             @threadsafe
789          */
790         AutoRecovery::ETimerType implts_openDocs(const DispatchParams& aParams);
791 
792         //---------------------------------------
793         // TODO document me
794         void implts_openOneDoc(const ::rtl::OUString&               sURL       ,
795                                      ::comphelper::MediaDescriptor& lDescriptor,
796                                      AutoRecovery::TDocumentInfo&   rInfo      );
797 
798         //---------------------------------------
799         // TODO document me
800         void implts_generateNewTempURL(const ::rtl::OUString&               sBackupPath     ,
801                                              ::comphelper::MediaDescriptor& rMediaDescriptor,
802                                              AutoRecovery::TDocumentInfo&   rInfo           );
803 
804         //---------------------------------------
805         /** @short  notifies all interested listener about the current state
806                     of the currently running operation.
807 
808             @descr  We support different sets of functions. AUTO_SAVE, EMERGENCY_SAVE,
809                     AUTO_RECOVERY, FAILURE_SAVE ... etcpp.
810                     Listener can register itself for any type of supported
811                     functionality ... but not for document URL's in special.
812 
813             @param  eJob
814                     is used to know, which set of listener we must notify.
815 
816             @param  aEvent
817                     describe the event more in detail.
818 
819             @threadsafe
820           */
821         void implts_informListener(      sal_Int32                      eJob  ,
822                                    const css::frame::FeatureStateEvent& aEvent);
823 
824         //---------------------------------------
825         /** short   create a feature event struct, which can be send
826                     to any interested listener.
827 
828             @param  eJob
829                     describe the current running operation
830                     AUTOSAVE, EMERGENCYSAVE, RECOVERY
831 
832             @param  sEventType
833                     describe the type of this event
834                     START, STOP, UPDATE
835 
836             @param  pInfo
837                     if sOperation is an update, this parameter must be different from NULL
838                     and is used to send informations regarding the current handled document.
839 
840             @return [css::frame::FeatureStateEvent]
841                     the event structure for sending.
842          */
843         static css::frame::FeatureStateEvent implst_createFeatureStateEvent(      sal_Int32                    eJob      ,
844                                                                             const ::rtl::OUString&             sEventType,
845                                                                                   AutoRecovery::TDocumentInfo* pInfo     );
846 
847         //---------------------------------------
848 
849         // TODO document me
850         void implts_resetHandleStates(sal_Bool bLoadCache);
851 
852         //---------------------------------------
853         // TODO document me
854         void implts_specifyDefaultFilterAndExtension(AutoRecovery::TDocumentInfo& rInfo);
855 
856         //---------------------------------------
857         // TODO document me
858         void implts_specifyAppModuleAndFactory(AutoRecovery::TDocumentInfo& rInfo);
859 
860         /** retrieves the names of all active views of the given document
861             @param rInfo
862                 the document info, whose <code>Document</code> member must not be <NULL/>.
863         */
864         void implts_collectActiveViewNames( AutoRecovery::TDocumentInfo& rInfo );
865 
866         /** updates the configuration so that for all documents, their current view/names are stored
867         */
868         void implts_persistAllActiveViewNames();
869 
870         //---------------------------------------
871         // TODO document me
872         void implts_prepareEmergencySave();
873 
874         //---------------------------------------
875         // TODO document me
876         void implts_doEmergencySave(const DispatchParams& aParams);
877 
878         //---------------------------------------
879         // TODO document me
880         void implts_doRecovery(const DispatchParams& aParams);
881 
882         //---------------------------------------
883         // TODO document me
884         void implts_doSessionSave(const DispatchParams& aParams);
885 
886         //---------------------------------------
887         // TODO document me
888         void implts_doSessionQuietQuit(const DispatchParams& aParams);
889 
890         //---------------------------------------
891         // TODO document me
892         void implts_doSessionRestore(const DispatchParams& aParams);
893 
894         //---------------------------------------
895         // TODO document me
896         void implts_backupWorkingEntry(const DispatchParams& aParams);
897 
898         //---------------------------------------
899         // TODO document me
900         void implts_cleanUpWorkingEntry(const DispatchParams& aParams);
901 
902         //---------------------------------------
903         /** try to make sure that all changed config items (not our used
904             config access only) will be flushed back to disc.
905 
906             E.g. our svtools::ConfigItems() has to be flushed explicitly .-(
907 
908             Note: This method can't fail. Flushing of config entries is an
909                   optional feature. Errors can be ignored.
910          */
911         void impl_flushALLConfigChanges();
912 
913         //---------------------------------------
914         // TODO document me
915         AutoRecovery::EFailureSafeResult implts_copyFile(const ::rtl::OUString& sSource    ,
916                                                          const ::rtl::OUString& sTargetPath,
917                                                          const ::rtl::OUString& sTargetName);
918 
919         //---------------------------------------
920         /** @short  converts m_eJob into a job description, which
921                     can be used to inform an outside listener
922                     about the current running operation
923 
924             @param  eJob
925                     describe the current running operation
926                     AUTOSAVE, EMERGENCYSAVE, RECOVERY
927 
928             @return [string]
929                     a suitable job description of form:
930                         vnd.sun.star.autorecovery:/do...
931          */
932         static ::rtl::OUString implst_getJobDescription(sal_Int32 eJob);
933 
934         //---------------------------------------
935         /** @short  mape the given URL to an internal int representation.
936 
937             @param  aURL
938                     the url, which describe the next starting or may be already running
939                     operation.
940 
941             @return [long]
942                     the internal int representation
943                     see enum EJob
944          */
945         static sal_Int32 implst_classifyJob(const css::util::URL& aURL);
946 
947         /// TODO
948         void implts_verifyCacheAgainstDesktopDocumentList();
949 
950         /// TODO document me
951         sal_Bool impl_enoughDiscSpace(sal_Int32 nRequiredSpace);
952 
953         /// TODO document me
954         static void impl_showFullDiscError();
955 
956         //---------------------------------------
957         /** @short  try to create/use a progress and set it inside the
958                     environment.
959 
960             @descr  The problem behind: There exist different use cases of this method.
961                     a) An external progress is provided by our CrashSave or Recovery dialog.
962                     b) We must create our own progress e.g. for an AutoSave
963                     c) Sometimes our application filters don't use the progress
964                        provided by the MediaDescriptor. They use the Frame every time to create
965                        its own progress. So we implemented a HACK for these and now we set
966                        an InterceptedProgress there for the time WE use this frame for loading/storing documents .-)
967 
968             @param  xNewFrame
969                     must be set only in case WE create a new frame (e.g. for loading documents
970                     on session restore or recovery). Then search for a frame using rInfo.Document must
971                     be suppressed and xFrame must be preferred instead .-)
972 
973             @param  rInfo
974                     used e.g. to find the frame corresponding to a document.
975                     This frame must be used to create a new progress e.g. for an AutoSave.
976 
977             @param  rArgs
978                     is used to set the new created progress as parameter on these set.
979          */
980         void impl_establishProgress(const AutoRecovery::TDocumentInfo&               rInfo    ,
981                                           ::comphelper::MediaDescriptor&             rArgs    ,
982                                     const css::uno::Reference< css::frame::XFrame >& xNewFrame);
983 
984         void impl_forgetProgress(const AutoRecovery::TDocumentInfo&               rInfo    ,
985                                        ::comphelper::MediaDescriptor&             rArgs    ,
986                                  const css::uno::Reference< css::frame::XFrame >& xNewFrame);
987 
988         //---------------------------------------
989         /** try to remove the specified file from disc.
990 
991             Every URL supported by our UCB component can be used here.
992             Further it doesn't matter if the file really exists or not.
993             Because removing a non exsistent file will have the same
994             result at the end ... a non existing file .-)
995 
996             On the other side removing of files from disc is an optional
997             feature. If we are not able doing so ... it's not a real problem.
998             Ok - users disc place will be smaller then ... but we should produce
999             a crash during crash save because we can't delete a temporary file only !
1000 
1001             @param  sURL
1002                     the url of the file, which should be removed.
1003          */
1004         static void st_impl_removeFile(const ::rtl::OUString& sURL);
1005 
1006         //---------------------------------------
1007         /** try to remove ".lock" file from disc if office will be terminated
1008             not using the official way .-)
1009 
1010             This method has to be handled "optional". So every error inside
1011             has to be ignored ! This method CAN'T FAIL ... it can forget something only .-)
1012          */
1013         static void st_impl_removeLockFile();
1014 };
1015 
1016 } // namespace framework
1017 
1018 #endif // __FRAMEWORK_SERVICES_AUTORECOVERY_HXX_
1019