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