xref: /trunk/main/framework/inc/services/autorecovery.hxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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 CrashSave/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 
456         virtual void SAL_CALL addStatusListener(const css::uno::Reference< css::frame::XStatusListener >& xListener,
457                                                 const css::util::URL&                                     aURL     );
458 
459         virtual void SAL_CALL removeStatusListener(const css::uno::Reference< css::frame::XStatusListener >& xListener,
460                                                    const css::util::URL&                                     aURL     );
461 
462         //---------------------------------------
463         // css.document.XEventListener
464         /** @short  informs about created/opened documents.
465 
466             @descr  Every new opened/created document will be saved internally
467                     so it can be checked if it's modified. This modified state
468                     is used later to decide, if it must be saved or not.
469 
470             @param  aEvent
471                     points to the new created/opened document.
472          */
473         virtual void SAL_CALL notifyEvent(const css::document::EventObject& aEvent);
474 
475         //---------------------------------------
476         // css.util.XChangesListener
477         virtual void SAL_CALL changesOccurred(const css::util::ChangesEvent& aEvent);
478 
479         //---------------------------------------
480         // css.util.XModifyListener
481         virtual void SAL_CALL modified(const css::lang::EventObject& aEvent);
482 
483         //---------------------------------------
484         // css.lang.XEventListener
485         using cppu::OPropertySetHelper::disposing;
486         virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent);
487 
488     //___________________________________________
489     // helper
490 
491     protected:
492 
493         //---------------------------------------
494         // OPropertySetHelper
495 
496         virtual sal_Bool SAL_CALL convertFastPropertyValue(      css::uno::Any& aConvertedValue,
497                                                                  css::uno::Any& aOldValue      ,
498                                                                  sal_Int32      nHandle        ,
499                                                            const css::uno::Any& aValue         );
500 
501         virtual void SAL_CALL setFastPropertyValue_NoBroadcast(      sal_Int32      nHandle,
502                                                                const css::uno::Any& aValue );
503         using cppu::OPropertySetHelper::getFastPropertyValue;
504         virtual void SAL_CALL getFastPropertyValue(css::uno::Any& aValue ,
505                                                    sal_Int32      nHandle) const;
506 
507         virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
508 
509         virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo();
510     //___________________________________________
511     // helper
512 
513     private:
514 
515         //---------------------------------------
516         /** @short  open the underlying configuration.
517 
518             @descr  This method must be called every time
519                     a configuration call is needed. Because
520                     method works together with the member
521                     m_xCFG, open it on demand and cache it
522                     afterwards.
523 
524             @return [com.sun.star.container.XNameAccess]
525                     the configuration object
526 
527             @throw  [com.sun.star.uno.RuntimeException]
528                     if config could not be opened successfully!
529 
530             @threadsafe
531           */
532         css::uno::Reference< css::container::XNameAccess > implts_openConfig();
533 
534         //---------------------------------------
535         /** @short  read the underlying configuration.
536 
537             @descr  After that we know the initial state - means:
538                     - if AutoSave was enabled by the user
539                     - which time intervall has to be used
540                     - which recovery entries may already exist
541 
542             @throw  [com.sun.star.uno.RuntimeException]
543                     if config could not be opened or read successfully!
544 
545             @threadsafe
546           */
547         void implts_readConfig();
548 
549         //---------------------------------------
550         /** @short  read the underlying configuration...
551 
552             @descr  ... but only keys related to the AutoSave mechanism.
553                     Means: State and Timer intervall.
554                     E.g. the recovery list isn't addressed here.
555 
556             @throw  [com.sun.star.uno.RuntimeException]
557                     if config could not be opened or readed successfully!
558 
559             @threadsafe
560           */
561         void implts_readAutoSaveConfig();
562 
563         //---------------------------------------
564         // TODO document me
565         void implts_flushConfigItem(const AutoRecovery::TDocumentInfo& rInfo                ,
566                                           sal_Bool                     bRemoveIt = sal_False);
567 
568         //---------------------------------------
569         // TODO document me
570         void implts_startListening();
571         void implts_startModifyListeningOnDoc(AutoRecovery::TDocumentInfo& rInfo);
572 
573         //---------------------------------------
574         // TODO document me
575         void implts_stopListening();
576         void implts_stopModifyListeningOnDoc(AutoRecovery::TDocumentInfo& rInfo);
577 
578         //---------------------------------------
579         /** @short  stops and may be(!) restarts the timer.
580 
581             @descr  A running timer is stopped everytimes here.
582                     But starting depends from the different internal
583                     timer variables (e.g. AutoSaveEnabled, AutoSaveTimeIntervall,
584                     TimerType etcpp.)
585 
586             @throw  [com.sun.star.uno.RuntimeException]
587                     if timer could not be stopped or started!
588 
589             @threadsafe
590          */
591         void implts_updateTimer();
592 
593         //---------------------------------------
594         /** @short  stop the timer.
595 
596             @descr  Double calls will be ignored - means we do
597                     nothing here, if the timer is already disabled.
598 
599             @throw  [com.sun.star.uno.RuntimeException]
600                     if timer could not be stopped!
601 
602             @threadsafe
603          */
604         void implts_stopTimer();
605 
606         //---------------------------------------
607         /** @short  callback of our internal timer.
608          */
609         DECL_LINK(implts_timerExpired, void*);
610 
611         //---------------------------------------
612         /** @short  makes our dispatch() method asynchronous!
613          */
614         DECL_LINK(implts_asyncDispatch, void*);
615 
616         //---------------------------------------
617         /** @short  implements the dispatch real. */
618         void implts_dispatch(const DispatchParams& aParams);
619 
620         //---------------------------------------
621         /** @short  validate new detected document and add it into the internal
622                     document list.
623 
624             @descr  This method should be called only, if its clear that a new
625                     document was opened/created during office runtime.
626                     This method checks, if its a top level document (means not an embedded one).
627                     Only such top level documents can be recognized by this auto save mechanism.
628 
629             @param  xDocument
630                     the new document, which should be checked and registered.
631 
632             @threadsafe
633          */
634         void implts_registerDocument(const css::uno::Reference< css::frame::XModel >& xDocument);
635 
636         //---------------------------------------
637         /** @short  remove the specified document from our internal document list.
638 
639             @param  xDocument
640                     the new document, which should be deregistered.
641 
642             @param  bStopListening
643                     sal_False: must be used in case this method is called within disposing() of the document,
644                            where it make no sense to deregister our listener. The container dies ...
645                     sal_True : must be used in case this method is used on "deregistration" of this document, where
646                            we must deregister our listener .-)
647 
648             @threadsafe
649          */
650         void implts_deregisterDocument(const css::uno::Reference< css::frame::XModel >& xDocument                ,
651                                              sal_Bool                                   bStopListening = sal_True);
652 
653         //---------------------------------------
654         // TODO document me
655         void implts_markDocumentModifiedAgainstLastBackup(const css::uno::Reference< css::frame::XModel >& xDocument);
656 
657         //---------------------------------------
658         // TODO document me
659         void implts_updateModifiedState(const css::uno::Reference< css::frame::XModel >& xDocument);
660 
661         //---------------------------------------
662         // TODO document me
663         void implts_updateDocumentUsedForSavingState(const css::uno::Reference< css::frame::XModel >& xDocument      ,
664                                                            sal_Bool                                   bSaveInProgress);
665 
666         //---------------------------------------
667         // TODO document me
668         void implts_markDocumentAsSaved(const css::uno::Reference< css::frame::XModel >& xDocument);
669 
670         //---------------------------------------
671         /** @short  search a document inside given list.
672 
673             @param  rList
674                     reference to a vector, which can contain such
675                     document.
676 
677             @param  xDocument
678                     the document, which should be located inside the
679                     given list.
680 
681             @return [TDocumentList::iterator]
682                     which points to the located document.
683                     If document does not exists - its set to
684                     rList.end()!
685          */
686         static TDocumentList::iterator impl_searchDocument(      AutoRecovery::TDocumentList&               rList    ,
687                                                            const css::uno::Reference< css::frame::XModel >& xDocument);
688 
689         //---------------------------------------
690         /** TODO document me */
691         void implts_changeAllDocVisibility(sal_Bool bVisible);
692         void implts_prepareSessionShutdown();
693 
694         //---------------------------------------
695         /** @short  save all current opened documents to a specific
696                     backup directory.
697 
698             @descr  Only really changed documents will be saved here.
699 
700                     Further this method returns a suggestion, if and how it should
701                     be called again. May be some documents was not saved yet
702                     and must wait for an user idle period ...
703 
704             @param  bAllowUserIdleLoop
705                     Because this method is used for different uses cases, it must
706                     know, which actions are allowed or not.
707                     AUTO_SAVE =>
708                                  If a document is the most active one, saving it
709                                  will be postponed if there exists other unsaved
710                                  documents. This feature was implemented, because
711                                  we don't wish to disturb the user on its work.
712                                  ... bAllowUserIdleLoop should be set to sal_True
713                     EMERGENCY_SAVE / SESSION_SAVE =>
714                                  Here we must finish our work ASAP! It's not allowed
715                                  to postpone any document.
716                                  ... bAllowUserIdleLoop must(!) be set to sal_False
717 
718             @param  pParams
719                     sometimes this method is required inside an external dispatch request.
720                     It contains some special environment variables, which overwrites
721                     our normal environment.
722                     AutoSave              => pParams == 0
723                     SessionSave/CrashSave => pParams != 0
724 
725             @return A suggestion, how the timer (if it's not already disabled!)
726                     should be restarted to fulfill the requirements.
727 
728             @threadsafe
729          */
730         AutoRecovery::ETimerType implts_saveDocs(      sal_Bool        bAllowUserIdleLoop,
731                                                        sal_Bool        bRemoveLockFiles,
732                                                  const DispatchParams* pParams        = 0);
733 
734         //---------------------------------------
735         /** @short  save one of the current documents to a specific
736                     backup directory.
737 
738             @descr  It:
739                     - defines a new(!) unique temp file name
740                     - save the new temp file
741                     - remove the old temp file
742                     - patch the given info struct
743                     - and return errors.
744 
745                     It does not:
746                     - patch the configuration.
747 
748                     Note further: It paches the info struct
749                     more than once. E.g. the new temp URL is set
750                     before the file is saved. And the old URL is removed
751                     only if removing of the old file was successfully.
752                     If this method returns without an exception - everything
753                     was OK. Otherwise the info struct can be analyzed to
754                     get more information, e.g. when the problem occurs.
755 
756             @param  sBackupPath
757                     the base path for saving such temp files.
758 
759             @param  rInfo
760                     points to an informations structure, where
761                     e.g. the document, its modified state, the count
762                     of autosave-retries etcpp. exists.
763                     It's used also to return the new temp file name
764                     and some other state values!
765 
766             @threadsafe
767           */
768         void implts_saveOneDoc(const ::rtl::OUString&                                    sBackupPath      ,
769                                      AutoRecovery::TDocumentInfo&                        rInfo            ,
770                                const css::uno::Reference< css::task::XStatusIndicator >& xExternalProgress);
771 
772         //---------------------------------------
773         /** @short  recovery all documents, which was saved during
774                     a crash before.
775 
776             @return A suggestion, how this method must be called back!
777 
778             @threadsafe
779          */
780         AutoRecovery::ETimerType implts_openDocs(const DispatchParams& aParams);
781 
782         //---------------------------------------
783         // TODO document me
784         void implts_openOneDoc(const ::rtl::OUString&               sURL       ,
785                                      ::comphelper::MediaDescriptor& lDescriptor,
786                                      AutoRecovery::TDocumentInfo&   rInfo      );
787 
788         //---------------------------------------
789         // TODO document me
790         void implts_generateNewTempURL(const ::rtl::OUString&               sBackupPath     ,
791                                              ::comphelper::MediaDescriptor& rMediaDescriptor,
792                                              AutoRecovery::TDocumentInfo&   rInfo           );
793 
794         //---------------------------------------
795         /** @short  notifies all interested listener about the current state
796                     of the currently running operation.
797 
798             @descr  We support different sets of functions. AUTO_SAVE, EMERGENCY_SAVE,
799                     AUTO_RECOVERY, FAILURE_SAVE ... etcpp.
800                     Listener can register itself for any type of supported
801                     functionality ... but not for document URL's in special.
802 
803             @param  eJob
804                     is used to know, which set of listener we must notify.
805 
806             @param  aEvent
807                     describe the event more in detail.
808 
809             @threadsafe
810           */
811         void implts_informListener(      sal_Int32                      eJob  ,
812                                    const css::frame::FeatureStateEvent& aEvent);
813 
814         //---------------------------------------
815         /** short   create a feature event struct, which can be send
816                     to any interested listener.
817 
818             @param  eJob
819                     describe the current running operation
820                     AUTOSAVE, EMERGENCYSAVE, RECOVERY
821 
822             @param  sEventType
823                     describe the type of this event
824                     START, STOP, UPDATE
825 
826             @param  pInfo
827                     if sOperation is an update, this parameter must be different from NULL
828                     and is used to send informations regarding the current handled document.
829 
830             @return [css::frame::FeatureStateEvent]
831                     the event structure for sending.
832          */
833         static css::frame::FeatureStateEvent implst_createFeatureStateEvent(      sal_Int32                    eJob      ,
834                                                                             const ::rtl::OUString&             sEventType,
835                                                                                   AutoRecovery::TDocumentInfo* pInfo     );
836 
837         //---------------------------------------
838 
839         // TODO document me
840         void implts_resetHandleStates(sal_Bool bLoadCache);
841 
842         //---------------------------------------
843         // TODO document me
844         void implts_specifyDefaultFilterAndExtension(AutoRecovery::TDocumentInfo& rInfo);
845 
846         //---------------------------------------
847         // TODO document me
848         void implts_specifyAppModuleAndFactory(AutoRecovery::TDocumentInfo& rInfo);
849 
850         /** retrieves the names of all active views of the given document
851             @param rInfo
852                 the document info, whose <code>Document</code> member must not be <NULL/>.
853         */
854         void implts_collectActiveViewNames( AutoRecovery::TDocumentInfo& rInfo );
855 
856         /** updates the configuration so that for all documents, their current view/names are stored
857         */
858         void implts_persistAllActiveViewNames();
859 
860         //---------------------------------------
861         // TODO document me
862         void implts_prepareEmergencySave();
863 
864         //---------------------------------------
865         // TODO document me
866         void implts_doEmergencySave(const DispatchParams& aParams);
867 
868         //---------------------------------------
869         // TODO document me
870         void implts_doRecovery(const DispatchParams& aParams);
871 
872         //---------------------------------------
873         // TODO document me
874         void implts_doSessionSave(const DispatchParams& aParams);
875 
876         //---------------------------------------
877         // TODO document me
878         void implts_doSessionQuietQuit(const DispatchParams& aParams);
879 
880         //---------------------------------------
881         // TODO document me
882         void implts_doSessionRestore(const DispatchParams& aParams);
883 
884         //---------------------------------------
885         // TODO document me
886         void implts_backupWorkingEntry(const DispatchParams& aParams);
887 
888         //---------------------------------------
889         // TODO document me
890         void implts_cleanUpWorkingEntry(const DispatchParams& aParams);
891 
892         //---------------------------------------
893         /** try to make sure that all changed config items (not our used
894             config access only) will be flushed back to disc.
895 
896             E.g. our svtools::ConfigItems() has to be flushed explicitly .-(
897 
898             Note: This method can't fail. Flushing of config entries is an
899                   optional feature. Errors can be ignored.
900          */
901         void impl_flushALLConfigChanges();
902 
903         //---------------------------------------
904         // TODO document me
905         AutoRecovery::EFailureSafeResult implts_copyFile(const ::rtl::OUString& sSource    ,
906                                                          const ::rtl::OUString& sTargetPath,
907                                                          const ::rtl::OUString& sTargetName);
908 
909         //---------------------------------------
910         /** @short  converts m_eJob into a job description, which
911                     can be used to inform an outside listener
912                     about the current running operation
913 
914             @param  eJob
915                     describe the current running operation
916                     AUTOSAVE, EMERGENCYSAVE, RECOVERY
917 
918             @return [string]
919                     a suitable job description of form:
920                         vnd.sun.star.autorecovery:/do...
921          */
922         static ::rtl::OUString implst_getJobDescription(sal_Int32 eJob);
923 
924         //---------------------------------------
925         /** @short  mape the given URL to an internal int representation.
926 
927             @param  aURL
928                     the url, which describe the next starting or may be already running
929                     operation.
930 
931             @return [long]
932                     the internal int representation
933                     see enum EJob
934          */
935         static sal_Int32 implst_classifyJob(const css::util::URL& aURL);
936 
937         /// TODO
938         void implts_verifyCacheAgainstDesktopDocumentList();
939 
940         /// TODO document me
941         sal_Bool impl_enoughDiscSpace(sal_Int32 nRequiredSpace);
942 
943         /// TODO document me
944         static void impl_showFullDiscError();
945 
946         //---------------------------------------
947         /** @short  try to create/use a progress and set it inside the
948                     environment.
949 
950             @descr  The problem behind: There exist different use cases of this method.
951                     a) An external progress is provided by our CrashSave or Recovery dialog.
952                     b) We must create our own progress e.g. for an AutoSave
953                     c) Sometimes our application filters don't use the progress
954                        provided by the MediaDescriptor. They use the Frame every time to create
955                        its own progress. So we implemented a HACK for these and now we set
956                        an InterceptedProgress there for the time WE use this frame for loading/storing documents .-)
957 
958             @param  xNewFrame
959                     must be set only in case WE create a new frame (e.g. for loading documents
960                     on session restore or recovery). Then search for a frame using rInfo.Document must
961                     be suppressed and xFrame must be preferred instead .-)
962 
963             @param  rInfo
964                     used e.g. to find the frame corresponding to a document.
965                     This frame must be used to create a new progress e.g. for an AutoSave.
966 
967             @param  rArgs
968                     is used to set the new created progress as parameter on these set.
969          */
970         void impl_establishProgress(const AutoRecovery::TDocumentInfo&               rInfo    ,
971                                           ::comphelper::MediaDescriptor&             rArgs    ,
972                                     const css::uno::Reference< css::frame::XFrame >& xNewFrame);
973 
974         void impl_forgetProgress(const AutoRecovery::TDocumentInfo&               rInfo    ,
975                                        ::comphelper::MediaDescriptor&             rArgs    ,
976                                  const css::uno::Reference< css::frame::XFrame >& xNewFrame);
977 
978         //---------------------------------------
979         /** try to remove the specified file from disc.
980 
981             Every URL supported by our UCB component can be used here.
982             Further it doesn't matter if the file really exists or not.
983             Because removing a non existent file will have the same
984             result at the end ... a non existing file .-)
985 
986             On the other side removing of files from disc is an optional
987             feature. If we are not able doing so ... it's not a real problem.
988             Ok - users disc place will be smaller then ... but we should produce
989             a crash during crash save because we can't delete a temporary file only !
990 
991             @param  sURL
992                     the url of the file, which should be removed.
993          */
994         static void st_impl_removeFile(const ::rtl::OUString& sURL);
995 
996         //---------------------------------------
997         /** try to remove ".lock" file from disc if office will be terminated
998             not using the official way .-)
999 
1000             This method has to be handled "optional". So every error inside
1001             has to be ignored ! This method CAN'T FAIL ... it can forget something only .-)
1002          */
1003         static void st_impl_removeLockFile();
1004 };
1005 
1006 } // namespace framework
1007 
1008 #endif // __FRAMEWORK_SERVICES_AUTORECOVERY_HXX_
1009