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