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