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