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 information 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 information 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 : 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 immediately. 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 immediately 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 : E_USER_AUTO_SAVE = 2048
218 : };
219 :
220 : //---------------------------------------
221 : /** @short combine different information about one office document. */
222 0 : struct TDocumentInfo
223 : {
224 : public:
225 :
226 : //-------------------------------
227 0 : TDocumentInfo()
228 : : DocumentState (E_UNKNOWN)
229 : , UsedForSaving (sal_False)
230 : , ListenForModify (sal_False)
231 : , IgnoreClosing (sal_False)
232 0 : , ID (-1 )
233 0 : {}
234 :
235 : //-------------------------------
236 : /** @short points to the document. */
237 : css::uno::Reference< css::frame::XModel > Document;
238 :
239 : //-------------------------------
240 : /** @short knows, if the document is realy modified since the last autosave,
241 : or was postponed, because it was an active one etcpp...
242 :
243 : @descr Because we have no CHANGE TRACKING mechanism, based on office document,
244 : we implements it by ourself. We listen for MODIFIED events
245 : of each document and update this state flag here.
246 :
247 : Further we postpone saving of active documents, e.g. if the user
248 : works currently on it. We wait for an idle period then ...
249 : */
250 : sal_Int32 DocumentState;
251 :
252 : //-------------------------------
253 : /** Because our applications not ready for concurrent save requests at the same time,
254 : we have supress our own AutoSave for the moment, a document will be already saved
255 : by others.
256 : */
257 : sal_Bool UsedForSaving;
258 :
259 : //-------------------------------
260 : /** For every user action, which modifies a document (e.g. key input) we get
261 : a notification as XModifyListener. That seams to be a "performance issue" .-)
262 : So we decided to listen for such modify events only for the time in which the document
263 : was stored as temp. file and was not modified again by the user.
264 : */
265 : sal_Bool ListenForModify;
266 :
267 : //-------------------------------
268 : /** For SessionSave we must close all open documents by ourself.
269 : But because we are listen for documents events, we get some ...
270 : and deregister these documents from our configuration.
271 : That's why we mark these documents as "Closed by ourself" so we can
272 : ignore these "OnUnload" or disposing() events .-)
273 : */
274 : sal_Bool IgnoreClosing;
275 :
276 : //-------------------------------
277 : /** TODO: document me */
278 : OUString OrgURL;
279 : OUString FactoryURL;
280 : OUString TemplateURL;
281 :
282 : OUString OldTempURL;
283 : OUString NewTempURL;
284 :
285 : OUString AppModule; // e.g. com.sun.star.text.TextDocument - used to identify app module
286 : OUString FactoryService; // the service to create a document of the module
287 : OUString RealFilter; // real filter, which was used at loading time
288 : OUString DefaultFilter; // supports saving of the default format without loosing data
289 : OUString Extension; // file extension of the default filter
290 : OUString Title; // can be used as "DisplayName" on every recovery UI!
291 : ::com::sun::star::uno::Sequence< OUString >
292 : ViewNames; // names of the view which were active at emergency-save time
293 :
294 : sal_Int32 ID;
295 : };
296 :
297 : //---------------------------------------
298 : /** @short used to know every currently open document. */
299 : typedef ::std::vector< TDocumentInfo > TDocumentList;
300 :
301 : //___________________________________________
302 : // member
303 :
304 : private:
305 :
306 : //---------------------------------------
307 : /** @short the global uno service manager.
308 : @descr Must be used to create own needed services.
309 : */
310 : css::uno::Reference< css::uno::XComponentContext > m_xContext;
311 :
312 : //---------------------------------------
313 : /** @short points to the underlying recovery configuration.
314 : @descr This instance does not cache - it calls directly the
315 : configuration API!
316 : */
317 : css::uno::Reference< css::container::XNameAccess > m_xRecoveryCFG;
318 :
319 : //---------------------------------------
320 : /** @short proxy weak binding to forward Events to ourself without
321 : an ownership cycle
322 : */
323 : css::uno::Reference< css::util::XChangesListener > m_xRecoveryCFGListener;
324 :
325 : //---------------------------------------
326 : /** @short points to the used configuration package or.openoffice.Setup
327 : @descr This instance does not cache - it calls directly the
328 : configuration API!
329 : */
330 : css::uno::Reference< css::container::XNameAccess > m_xModuleCFG;
331 :
332 : //---------------------------------------
333 : /** @short holds the global event broadcaster alive,
334 : where we listen for new created documents.
335 : */
336 : css::uno::Reference< css::frame::XGlobalEventBroadcaster > m_xNewDocBroadcaster;
337 :
338 : //---------------------------------------
339 : /** @short proxy weak binding to forward Events to ourself without
340 : an ownership cycle
341 : */
342 : css::uno::Reference< css::document::XEventListener > m_xNewDocBroadcasterListener;
343 :
344 : //---------------------------------------
345 : /** @short because we stop/restart listening sometimes, it's a good idea to know
346 : if we already registered as listener .-)
347 : */
348 : sal_Bool m_bListenForDocEvents;
349 : sal_Bool m_bListenForConfigChanges;
350 :
351 : //---------------------------------------
352 : /** @short specify the time intervall between two save actions.
353 : @descr Time is measured in [min].
354 : */
355 : sal_Int32 m_nAutoSaveTimeIntervall;
356 :
357 : //---------------------------------------
358 : /** @short for an asynchronous operation we must know, if there is
359 : at least one running job (may be asynchronous!).
360 : */
361 : sal_Int32 m_eJob;
362 :
363 : //---------------------------------------
364 : /** @short the timer, which is used to be informed about the next
365 : saving time ...
366 : */
367 : Timer m_aTimer;
368 :
369 : //---------------------------------------
370 : /** @short make our dispatch asynchronous ... if required to do so! */
371 : ::vcl::EventPoster m_aAsyncDispatcher;
372 :
373 : //---------------------------------------
374 : /** @see DispatchParams
375 : */
376 : DispatchParams m_aDispatchParams;
377 :
378 : //---------------------------------------
379 : /** @short indicates, which time period is currently used by the
380 : internal timer.
381 : */
382 : ETimerType m_eTimerType;
383 :
384 : //---------------------------------------
385 : /** @short this cache is used to hold all information about
386 : recovery/emergency save documents alive.
387 : */
388 : TDocumentList m_lDocCache;
389 :
390 : //---------------------------------------
391 : // TODO document me
392 : sal_Int32 m_nIdPool;
393 :
394 : //---------------------------------------
395 : /** @short contains all status listener registered at this instance.
396 : */
397 : ListenerHash m_lListener;
398 :
399 : /** @descr This member is used to prevent us against re-entrance problems.
400 : A mutex cant help to prevent us from concurrent using of members
401 : inside the same thread. But e.g. our internaly used stl structures
402 : are not threadsafe ... and furthermore they cant be used at the same time
403 : for iteration and add/remove requests!
404 : So we have to detect such states and ... show a warning.
405 : May be there will be a better solution next time ... (copying the cache temp.
406 : bevor using).
407 :
408 : And further it's not possible to use a simple boolean value here.
409 : Because if more then one operation iterates over the same stl container ...
410 : (only to modify it's elements but dont add new or removing existing ones!)
411 : it should be possible doing so. But we must guarantee that the last operation reset
412 : this lock ... not the first one ! So we use a "ref count" mechanism for that."
413 : */
414 : sal_Int32 m_nDocCacheLock;
415 :
416 : /** @descr These members are used to check the minimum disc space, which must exists
417 : to start the corresponding operation.
418 : */
419 : sal_Int32 m_nMinSpaceDocSave;
420 : sal_Int32 m_nMinSpaceConfigSave;
421 :
422 : //---------------------------------------
423 : /** @short special debug option to make testing faster.
424 :
425 : @descr We dont interpret the timer unit as [min] ...
426 : we use [ms] instead of that. Further we dont
427 : wait 10 s for user idle ...
428 : */
429 : #if OSL_DEBUG_LEVEL > 1
430 : sal_Bool m_dbg_bMakeItFaster;
431 : #endif
432 :
433 : //---------------------------------------
434 : // HACK ... TODO
435 : css::uno::Reference< css::task::XStatusIndicator > m_xExternalProgress;
436 :
437 : //___________________________________________
438 : // interface
439 :
440 : public:
441 :
442 : AutoRecovery(const css::uno::Reference< css::uno::XComponentContext >& xContext);
443 : virtual ~AutoRecovery( );
444 :
445 : // XInterface, XTypeProvider, XServiceInfo
446 : FWK_DECLARE_XINTERFACE
447 : FWK_DECLARE_XTYPEPROVIDER
448 : DECLARE_XSERVICEINFO
449 :
450 : //---------------------------------------
451 : // css.frame.XDispatch
452 : virtual void SAL_CALL dispatch(const css::util::URL& aURL ,
453 : const css::uno::Sequence< css::beans::PropertyValue >& lArguments)
454 : throw(css::uno::RuntimeException);
455 :
456 : virtual void SAL_CALL addStatusListener(const css::uno::Reference< css::frame::XStatusListener >& xListener,
457 : const css::util::URL& aURL )
458 : throw(css::uno::RuntimeException);
459 :
460 : virtual void SAL_CALL removeStatusListener(const css::uno::Reference< css::frame::XStatusListener >& xListener,
461 : const css::util::URL& aURL )
462 : throw(css::uno::RuntimeException);
463 :
464 : //---------------------------------------
465 : // css.document.XEventListener
466 : /** @short informs about created/opened documents.
467 :
468 : @descr Every new opened/created document will be saved internaly
469 : so it can be checked if its modified. This modified state
470 : is used later to decide, if it must be saved or not.
471 :
472 : @param aEvent
473 : points to the new created/opened document.
474 : */
475 : virtual void SAL_CALL notifyEvent(const css::document::EventObject& aEvent)
476 : throw(css::uno::RuntimeException);
477 :
478 : //---------------------------------------
479 : // css.util.XChangesListener
480 : virtual void SAL_CALL changesOccurred(const css::util::ChangesEvent& aEvent)
481 : throw(css::uno::RuntimeException);
482 :
483 : //---------------------------------------
484 : // css.util.XModifyListener
485 : virtual void SAL_CALL modified(const css::lang::EventObject& aEvent)
486 : throw(css::uno::RuntimeException);
487 :
488 : //---------------------------------------
489 : // css.lang.XEventListener
490 : using cppu::OPropertySetHelper::disposing;
491 : virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent)
492 : throw(css::uno::RuntimeException);
493 :
494 : //___________________________________________
495 : // helper
496 :
497 : protected:
498 :
499 : //---------------------------------------
500 : // OPropertySetHelper
501 :
502 : virtual sal_Bool SAL_CALL convertFastPropertyValue( css::uno::Any& aConvertedValue,
503 : css::uno::Any& aOldValue ,
504 : sal_Int32 nHandle ,
505 : const css::uno::Any& aValue )
506 : throw(css::lang::IllegalArgumentException);
507 :
508 : virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle,
509 : const css::uno::Any& aValue )
510 : throw(css::uno::Exception);
511 : using cppu::OPropertySetHelper::getFastPropertyValue;
512 : virtual void SAL_CALL getFastPropertyValue(css::uno::Any& aValue ,
513 : sal_Int32 nHandle) const;
514 :
515 : virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
516 :
517 : virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo()
518 : throw(css::uno::RuntimeException);
519 : //___________________________________________
520 : // helper
521 :
522 : private:
523 :
524 : //---------------------------------------
525 : /** @short open the underlying configuration.
526 :
527 : @descr This method must be called everytimes
528 : a configuartion call is needed. Because
529 : method works together with the member
530 : m_xCFG, open it on demand and cache it
531 : afterwards.
532 :
533 : @return [com.sun.star.container.XNameAccess]
534 : the configuration object
535 :
536 : @throw [com.sun.star.uno.RuntimeException]
537 : if config could not be opened successfully!
538 :
539 : @threadsafe
540 : */
541 : css::uno::Reference< css::container::XNameAccess > implts_openConfig();
542 :
543 : //---------------------------------------
544 : /** @short read the underlying configuration.
545 :
546 : @descr After that we know the initial state - means:
547 : - if AutoSave was enabled by the user
548 : - which time intervall has to be used
549 : - which recovery entries may already exists
550 :
551 : @throw [com.sun.star.uno.RuntimeException]
552 : if config could not be opened or readed successfully!
553 :
554 : @threadsafe
555 : */
556 : void implts_readConfig();
557 :
558 : //---------------------------------------
559 : /** @short read the underlying configuration...
560 :
561 : @descr ... but only keys related to the AutoSave mechanism.
562 : Means: State and Timer intervall.
563 : E.g. the recovery list isnt adressed here.
564 :
565 : @throw [com.sun.star.uno.RuntimeException]
566 : if config could not be opened or readed successfully!
567 :
568 : @threadsafe
569 : */
570 : void implts_readAutoSaveConfig();
571 :
572 : //---------------------------------------
573 : // TODO document me
574 : void implts_flushConfigItem(const AutoRecovery::TDocumentInfo& rInfo ,
575 : sal_Bool bRemoveIt = sal_False);
576 :
577 : //---------------------------------------
578 : // TODO document me
579 : void implts_startListening();
580 : void implts_startModifyListeningOnDoc(AutoRecovery::TDocumentInfo& rInfo);
581 :
582 : //---------------------------------------
583 : // TODO document me
584 : void implts_stopListening();
585 : void implts_stopModifyListeningOnDoc(AutoRecovery::TDocumentInfo& rInfo);
586 :
587 : //---------------------------------------
588 : /** @short stops and may be(!) restarts the timer.
589 :
590 : @descr A running timer is stopped everytimes here.
591 : But starting depends from the different internal
592 : timer variables (e.g. AutoSaveEnabled, AutoSaveTimeIntervall,
593 : TimerType etcpp.)
594 :
595 : @throw [com.sun.star.uno.RuntimeException]
596 : if timer could not be stopped or started!
597 :
598 : @threadsafe
599 : */
600 : void implts_updateTimer();
601 :
602 : //---------------------------------------
603 : /** @short stop the timer.
604 :
605 : @descr Double calls will be ignored - means we do
606 : nothing here, if the timer is already disabled.
607 :
608 : @throw [com.sun.star.uno.RuntimeException]
609 : if timer could not be stopped!
610 :
611 : @threadsafe
612 : */
613 : void implts_stopTimer();
614 :
615 : //---------------------------------------
616 : /** @short callback of our internal timer.
617 : */
618 : DECL_LINK(implts_timerExpired, void*);
619 :
620 : //---------------------------------------
621 : /** @short makes our dispatch() method asynchronous!
622 : */
623 : DECL_LINK(implts_asyncDispatch, void*);
624 :
625 : //---------------------------------------
626 : /** @short implements the dispatch real. */
627 : void implts_dispatch(const DispatchParams& aParams);
628 :
629 : //---------------------------------------
630 : /** @short validate new detected document and add it into the internal
631 : document list.
632 :
633 : @descr This method should be called only, if its clear that a new
634 : document was opened/created during office runtime.
635 : This method checks, if its a top level document (means not an embedded one).
636 : Only such top level documents can be recognized by this auto save mechanism.
637 :
638 : @param xDocument
639 : the new document, which should be checked and registered.
640 :
641 : @threadsafe
642 : */
643 : void implts_registerDocument(const css::uno::Reference< css::frame::XModel >& xDocument);
644 :
645 : //---------------------------------------
646 : /** @short remove the specified document from our internal document list.
647 :
648 : @param xDocument
649 : the new document, which should be deregistered.
650 :
651 : @param bStopListening
652 : sal_False: must be used in case this method is called withion disposing() of the document,
653 : where it make no sense to deregister our listener. The container dies ...
654 : sal_True : must be used in case this method is used on "dergistration" of this document, where
655 : we must deregister our listener .-)
656 :
657 : @threadsafe
658 : */
659 : void implts_deregisterDocument(const css::uno::Reference< css::frame::XModel >& xDocument ,
660 : sal_Bool bStopListening = sal_True);
661 :
662 : //---------------------------------------
663 : // TODO document me
664 : void implts_markDocumentModifiedAgainstLastBackup(const css::uno::Reference< css::frame::XModel >& xDocument);
665 :
666 : //---------------------------------------
667 : // TODO document me
668 : void implts_updateModifiedState(const css::uno::Reference< css::frame::XModel >& xDocument);
669 :
670 : //---------------------------------------
671 : // TODO document me
672 : void implts_updateDocumentUsedForSavingState(const css::uno::Reference< css::frame::XModel >& xDocument ,
673 : sal_Bool bSaveInProgress);
674 :
675 : //---------------------------------------
676 : // TODO document me
677 : void implts_markDocumentAsSaved(const css::uno::Reference< css::frame::XModel >& xDocument);
678 :
679 : //---------------------------------------
680 : /** @short search a document inside given list.
681 :
682 : @param rList
683 : reference to a vector, which can contain such
684 : document.
685 :
686 : @param xDocument
687 : the document, which should be located inside the
688 : given list.
689 :
690 : @return [TDocumentList::iterator]
691 : which points to the located document.
692 : If document does not exists - its set to
693 : rList.end()!
694 : */
695 : static TDocumentList::iterator impl_searchDocument( AutoRecovery::TDocumentList& rList ,
696 : const css::uno::Reference< css::frame::XModel >& xDocument);
697 :
698 : //---------------------------------------
699 : /** TODO document me */
700 : void implts_changeAllDocVisibility(sal_Bool bVisible);
701 : void implts_prepareSessionShutdown();
702 :
703 : //---------------------------------------
704 : /** @short save all current opened documents to a specific
705 : backup directory.
706 :
707 : @descr Only realy changed documents will be saved here.
708 :
709 : Further this method returns a suggestion, if and how it should
710 : be called again. May be some documents was not saved yet
711 : and must wait for an user idle period ...
712 :
713 : @param bAllowUserIdleLoop
714 : Because this method is used for different uses cases, it must
715 : know, which actions are allowed or not.
716 : AUTO_SAVE =>
717 : If a document is the most active one, saving it
718 : will be postponed if there exists other unsaved
719 : documents. This feature was implemented, because
720 : we dont wish to disturb the user on it's work.
721 : ... bAllowUserIdleLoop should be set to sal_True
722 : EMERGENCY_SAVE / SESSION_SAVE =>
723 : Here we must finish our work ASAP! It's not allowed
724 : to postpone any document.
725 : ... bAllowUserIdleLoop must(!) be set to sal_False
726 :
727 : @param pParams
728 : sometimes this method is required inside an external dispatch request.
729 : The it contains some special environment variables, which overwrites
730 : our normal environment.
731 : AutoSave => pParams == 0
732 : SessionSave/CrashSave => pParams != 0
733 :
734 : @return A suggestion, how the timer (if its not already disabled!)
735 : should be restarted to full fill the requirements.
736 :
737 : @threadsafe
738 : */
739 : AutoRecovery::ETimerType implts_saveDocs( sal_Bool bAllowUserIdleLoop,
740 : sal_Bool bRemoveLockFiles,
741 : const DispatchParams* pParams = 0);
742 :
743 : //---------------------------------------
744 : /** @short save one of the current documents to a specific
745 : backup directory.
746 :
747 : @descr It:
748 : - defines a new(!) unique temp file name
749 : - save the new temp file
750 : - remove the old temp file
751 : - patch the given info struct
752 : - and return errors.
753 :
754 : It does not:
755 : - patch the configuration.
756 :
757 : Note further: It paches the info struct
758 : more then ones. E.g. the new temp URL is set
759 : before the file is saved. And the old URL is removed
760 : only if removing oft he old file was successfully.
761 : If this method returns without an exception - everything
762 : was OK. Otherwhise the info struct can be analyzed to
763 : get more information, e.g. when the problem occures.
764 :
765 : @param sBackupPath
766 : the base path for saving such temp files.
767 :
768 : @param rInfo
769 : points to an information structure, where
770 : e.g. the document, its modified state, the count
771 : of autosave-retries etcpp. exists.
772 : Its used also to return the new temp file name
773 : and some other state values!
774 :
775 : @threadsafe
776 : */
777 : void implts_saveOneDoc(const OUString& sBackupPath ,
778 : AutoRecovery::TDocumentInfo& rInfo ,
779 : const css::uno::Reference< css::task::XStatusIndicator >& xExternalProgress);
780 :
781 : //---------------------------------------
782 : /** @short recovery all documents, which was saved during
783 : a crash before.
784 :
785 : @return A suggestion, how this method must be called back!
786 :
787 : @threadsafe
788 : */
789 : AutoRecovery::ETimerType implts_openDocs(const DispatchParams& aParams);
790 :
791 : //---------------------------------------
792 : // TODO document me
793 : void implts_openOneDoc(const OUString& sURL ,
794 : ::comphelper::MediaDescriptor& lDescriptor,
795 : AutoRecovery::TDocumentInfo& rInfo );
796 :
797 : //---------------------------------------
798 : // TODO document me
799 : void implts_generateNewTempURL(const OUString& sBackupPath ,
800 : ::comphelper::MediaDescriptor& rMediaDescriptor,
801 : AutoRecovery::TDocumentInfo& rInfo );
802 :
803 : //---------------------------------------
804 : /** @short notifies all interested listener about the current state
805 : of the currently running operation.
806 :
807 : @descr We support different set's of functions. AUTO_SAVE, EMERGENCY_SAVE,
808 : AUTO_RECOVERY, FAILURE_SAVE ... etcpp.
809 : Listener can register itself for any type of supported
810 : functionality ... but not for document URL's in special.
811 :
812 : @param eJob
813 : is used to know, which set of listener we must notify.
814 :
815 : @param aEvent
816 : describe the event more in detail.
817 :
818 : @threadsafe
819 : */
820 : void implts_informListener( sal_Int32 eJob ,
821 : const css::frame::FeatureStateEvent& aEvent);
822 :
823 : //---------------------------------------
824 : /** short create a feature event struct, which can be send
825 : to any interested listener.
826 :
827 : @param eJob
828 : describe the current running operation
829 : AUTOSAVE, EMERGENCYSAVE, RECOVERY
830 :
831 : @param sEventType
832 : describe the type of this event
833 : START, STOP, UPDATE
834 :
835 : @param pInfo
836 : if sOperation is an update, this parameter must be different from NULL
837 : and is used to send information regarding the current handled document.
838 :
839 : @return [css::frame::FeatureStateEvent]
840 : the event structure for sending.
841 : */
842 : static css::frame::FeatureStateEvent implst_createFeatureStateEvent( sal_Int32 eJob ,
843 : const OUString& sEventType,
844 : AutoRecovery::TDocumentInfo* pInfo );
845 :
846 :
847 : class ListenerInformer
848 : {
849 : private:
850 : AutoRecovery &m_rRecovery;
851 : sal_Int32 m_eJob;
852 : bool m_bStopped;
853 : public:
854 0 : ListenerInformer(AutoRecovery &rRecovery, sal_Int32 eJob)
855 0 : : m_rRecovery(rRecovery), m_eJob(eJob), m_bStopped(false)
856 : {
857 0 : }
858 : void start();
859 : void stop();
860 0 : ~ListenerInformer()
861 : {
862 0 : stop();
863 0 : }
864 : };
865 :
866 : //---------------------------------------
867 :
868 : // TODO document me
869 : void implts_resetHandleStates(sal_Bool bLoadCache);
870 :
871 : //---------------------------------------
872 : // TODO document me
873 : void implts_specifyDefaultFilterAndExtension(AutoRecovery::TDocumentInfo& rInfo);
874 :
875 : //---------------------------------------
876 : // TODO document me
877 : void implts_specifyAppModuleAndFactory(AutoRecovery::TDocumentInfo& rInfo);
878 :
879 : /** retrieves the names of all active views of the given document
880 : @param rInfo
881 : the document info, whose <code>Document</code> member must not be <NULL/>.
882 : */
883 : void implts_collectActiveViewNames( AutoRecovery::TDocumentInfo& rInfo );
884 :
885 : /** updates the configuration so that for all documents, their current view/names are stored
886 : */
887 : void implts_persistAllActiveViewNames();
888 :
889 : //---------------------------------------
890 : // TODO document me
891 : void implts_prepareEmergencySave();
892 :
893 : //---------------------------------------
894 : // TODO document me
895 : void implts_doEmergencySave(const DispatchParams& aParams);
896 :
897 : //---------------------------------------
898 : // TODO document me
899 : void implts_doRecovery(const DispatchParams& aParams);
900 :
901 : //---------------------------------------
902 : // TODO document me
903 : void implts_doSessionSave(const DispatchParams& aParams);
904 :
905 : //---------------------------------------
906 : // TODO document me
907 : void implts_doSessionQuietQuit(const DispatchParams& aParams);
908 :
909 : //---------------------------------------
910 : // TODO document me
911 : void implts_doSessionRestore(const DispatchParams& aParams);
912 :
913 : //---------------------------------------
914 : // TODO document me
915 : void implts_backupWorkingEntry(const DispatchParams& aParams);
916 :
917 : //---------------------------------------
918 : // TODO document me
919 : void implts_cleanUpWorkingEntry(const DispatchParams& aParams);
920 :
921 : //---------------------------------------
922 : /** try to make sure that all changed config items (not our used
923 : config access only) will be flushed back to disc.
924 :
925 : E.g. our svtools::ConfigItems() has to be flushed explicitly .-(
926 :
927 : Note: This method cant fail. Flushing of config entries is an
928 : optional feature. Errors can be ignored.
929 : */
930 : void impl_flushALLConfigChanges();
931 :
932 : //---------------------------------------
933 : // TODO document me
934 : AutoRecovery::EFailureSafeResult implts_copyFile(const OUString& sSource ,
935 : const OUString& sTargetPath,
936 : const OUString& sTargetName);
937 :
938 : //---------------------------------------
939 : /** @short converts m_eJob into a job description, which
940 : can be used to inform an outside listener
941 : about the current running operation
942 :
943 : @param eJob
944 : describe the current running operation
945 : AUTOSAVE, EMERGENCYSAVE, RECOVERY
946 :
947 : @return [string]
948 : a suitable job description of form:
949 : vnd.sun.star.autorecovery:/do...
950 : */
951 : static OUString implst_getJobDescription(sal_Int32 eJob);
952 :
953 : //---------------------------------------
954 : /** @short mape the given URL to an internal int representation.
955 :
956 : @param aURL
957 : the url, which describe the next starting or may be already running
958 : operation.
959 :
960 : @return [long]
961 : the internal int representation
962 : see enum EJob
963 : */
964 : static sal_Int32 implst_classifyJob(const css::util::URL& aURL);
965 :
966 : /// TODO
967 : void implts_verifyCacheAgainstDesktopDocumentList();
968 :
969 : /// TODO document me
970 : sal_Bool impl_enoughDiscSpace(sal_Int32 nRequiredSpace);
971 :
972 : /// TODO document me
973 : static void impl_showFullDiscError();
974 :
975 : //---------------------------------------
976 : /** @short try to create/use a progress and set it inside the
977 : environment.
978 :
979 : @descr The problem behind: There exists different use case of this method.
980 : a) An external progress is provided by our CrashSave or Recovery dialog.
981 : b) We must create our own progress e.g. for an AutoSave
982 : c) Sometimes our application filters dont use the progress
983 : provided by the MediaDescriptor. They uses the Frame everytime to create
984 : it's own progress. So we implemented a HACK for these and now we set
985 : an InterceptedProgress there for the time WE use this frame for loading/storing documents .-)
986 :
987 : @param xNewFrame
988 : must be set only in case WE create a new frame (e.g. for loading documents
989 : on session restore or recovery). Then search for a frame using rInfo.Document must
990 : be supressed and xFrame must be preferred instead .-)
991 :
992 : @param rInfo
993 : used e.g. to find the frame corresponding to a document.
994 : This frame must be used to create a new progress e.g. for an AutoSave.
995 :
996 : @param rArgs
997 : is used to set the new created progress as parameter on these set.
998 : */
999 : void impl_establishProgress(const AutoRecovery::TDocumentInfo& rInfo ,
1000 : ::comphelper::MediaDescriptor& rArgs ,
1001 : const css::uno::Reference< css::frame::XFrame >& xNewFrame);
1002 :
1003 : void impl_forgetProgress(const AutoRecovery::TDocumentInfo& rInfo ,
1004 : ::comphelper::MediaDescriptor& rArgs ,
1005 : const css::uno::Reference< css::frame::XFrame >& xNewFrame);
1006 :
1007 : //---------------------------------------
1008 : /** try to remove the specified file from disc.
1009 :
1010 : Every URL supported by our UCB component can be used here.
1011 : Further it doesnt matter if the file realy exists or not.
1012 : Because removing a non exsistent file will have the same
1013 : result at the end ... a non existing file .-)
1014 :
1015 : On the other side removing of files from disc is an optional
1016 : feature. If we are not able doing so ... its not a real problem.
1017 : Ok - users disc place will be samller then ... but we should produce
1018 : a crash during crash save because we cant delete a temporary file only !
1019 :
1020 : @param sURL
1021 : the url of the file, which should be removed.
1022 : */
1023 : void st_impl_removeFile(const OUString& sURL);
1024 :
1025 : //---------------------------------------
1026 : /** try to remove ".lock" file from disc if office will be terminated
1027 : not using the offical way .-)
1028 :
1029 : This method has to be handled "optional". So every error inside
1030 : has to be ignored ! This method CANT FAIL ... it can forget something only .-)
1031 : */
1032 : void st_impl_removeLockFile();
1033 : };
1034 :
1035 : } // namespace framework
1036 :
1037 : #endif // __FRAMEWORK_SERVICES_AUTORECOVERY_HXX_
1038 :
1039 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|