20#include <config_features.h>
31#include <com/sun/star/ucb/NameClash.hpp>
32#include <com/sun/star/container/XNameAccess.hpp>
33#include <com/sun/star/configuration/theDefaultProvider.hpp>
34#include <com/sun/star/frame/Desktop.hpp>
35#include <com/sun/star/frame/theGlobalEventBroadcaster.hpp>
36#include <com/sun/star/frame/XLoadable.hpp>
37#include <com/sun/star/frame/XModel3.hpp>
38#include <com/sun/star/frame/ModuleManager.hpp>
39#include <com/sun/star/frame/XTitle.hpp>
40#include <com/sun/star/frame/XFrame.hpp>
41#include <com/sun/star/frame/XController.hpp>
42#include <com/sun/star/frame/XModel.hpp>
43#include <com/sun/star/frame/XStorable.hpp>
44#include <com/sun/star/util/XModifiable.hpp>
45#include <com/sun/star/util/URLTransformer.hpp>
46#include <com/sun/star/util/XURLTransformer.hpp>
47#include <com/sun/star/frame/XDesktop.hpp>
48#include <com/sun/star/container/XNameContainer.hpp>
49#include <com/sun/star/util/XChangesNotifier.hpp>
50#include <com/sun/star/beans/XPropertySet.hpp>
51#include <com/sun/star/beans/PropertyAttribute.hpp>
52#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
53#include <com/sun/star/document/XDocumentRecovery2.hpp>
54#include <com/sun/star/document/XExtendedFilterDetection.hpp>
55#include <com/sun/star/util/XCloseable.hpp>
56#include <com/sun/star/awt/XWindow2.hpp>
57#include <com/sun/star/task/XStatusIndicatorFactory.hpp>
58#include <com/sun/star/task/ErrorCodeIOException.hpp>
59#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
60#include <com/sun/star/lang/XTypeProvider.hpp>
61#include <com/sun/star/lang/XServiceInfo.hpp>
62#include <com/sun/star/lang/XSingleServiceFactory.hpp>
63#include <com/sun/star/frame/XDispatch.hpp>
64#include <com/sun/star/document/XDocumentEventListener.hpp>
65#include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
66#include <com/sun/star/util/XChangesListener.hpp>
67#include <com/sun/star/task/XStatusIndicator.hpp>
68#include <com/sun/star/util/XModifyListener.hpp>
95#include <osl/file.hxx>
101#include <officecfg/Office/Common.hxx>
102#include <officecfg/Office/Recovery.hxx>
103#include <officecfg/Setup.hxx>
105using namespace css::uno;
106using namespace css::document;
107using namespace css::frame;
108using namespace css::lang;
125 DispatchParams(const ::comphelper::SequenceAsHashMap& lArgs ,
126 const css::uno::Reference< css::uno::XInterface >& xOwner);
141 css::uno::Reference< css::task::XStatusIndicator > m_xProgress;
144 OUString m_sSavePath;
148 sal_Int32 m_nWorkingEntryID;
158 css::uno::Reference< css::uno::XInterface > m_xHoldRefForAsyncOpAlive;
169enum class DocState: sal_Int32
212 PrepareEmergencySave = 32,
214 SessionRestore = 128,
215 DisableAutorecovery = 256,
216 SetAutosaveState = 512,
217 SessionQuietQuit = 1024,
232typedef ::cppu::WeakComponentImplHelper<
233 css::lang::XServiceInfo,
234 css::frame::XDispatch,
235 css::document::XDocumentEventListener,
236 css::util::XChangesListener,
237 css::util::XModifyListener >
241 ,
public AutoRecovery_BASE
251 enum EFailureSafeResult
254 E_ORIGINAL_FILE_MISSING,
264 E_NORMAL_AUTOSAVE_INTERVALL,
267 E_POLL_FOR_USER_IDLE,
270 E_POLL_TILL_AUTOSAVE_IS_ALLOWED,
281 : DocumentState (DocState::
Unknown)
282 , UsedForSaving (false)
283 , ListenForModify (false)
284 , IgnoreClosing (false)
289 css::uno::Reference< css::frame::XModel >
Document;
301 DocState DocumentState;
314 bool ListenForModify;
327 OUString TemplateURL;
333 OUString FactoryService;
335 OUString DefaultFilter;
338 css::uno::Sequence< OUString >
345 typedef ::std::vector< TDocumentInfo > TDocumentList;
354 css::uno::Reference< css::uno::XComponentContext >
m_xContext;
360 css::uno::Reference< css::container::XNameAccess > m_xRecoveryCFG;
365 css::uno::Reference< css::util::XChangesListener > m_xRecoveryCFGListener;
371 css::uno::Reference< css::container::XNameAccess > m_xModuleCFG;
376 css::uno::Reference< css::frame::XGlobalEventBroadcaster > m_xNewDocBroadcaster;
381 css::uno::Reference< css::document::XDocumentEventListener > m_xNewDocBroadcasterListener;
386 bool m_bListenForDocEvents;
387 bool m_bListenForConfigChanges;
401 std::unique_ptr<vcl::EventPoster> m_xAsyncDispatcher;
405 DispatchParams m_aDispatchParams;
410 ETimerType m_eTimerType;
415 TDocumentList m_lDocCache;
439 sal_Int32 m_nDocCacheLock;
444 sal_Int32 m_nMinSpaceDocSave;
445 sal_Int32 m_nMinSpaceConfigSave;
451 explicit AutoRecovery(css::uno::Reference< css::uno::XComponentContext > xContext);
452 virtual ~AutoRecovery( )
override;
456 return "com.sun.star.comp.framework.AutoRecovery";
466 return {
"com.sun.star.frame.AutoRecovery"};
470 virtual void SAL_CALL acquire() noexcept
override
472 virtual void SAL_CALL release() noexcept
override
474 virtual css::uno::Any SAL_CALL
queryInterface(
const css::uno::Type& type)
override;
477 void initListeners();
480 virtual css::uno::Sequence< css::uno::Type > SAL_CALL
getTypes( )
override;
483 virtual void SAL_CALL dispatch(
const css::util::URL& aURL ,
484 const css::uno::Sequence< css::beans::PropertyValue >& lArguments)
override;
486 virtual void SAL_CALL addStatusListener(
const css::uno::Reference< css::frame::XStatusListener >& xListener,
487 const css::util::URL& aURL )
override;
489 virtual void SAL_CALL removeStatusListener(
const css::uno::Reference< css::frame::XStatusListener >& xListener,
490 const css::util::URL& aURL )
override;
502 virtual void SAL_CALL documentEventOccured(
const css::document::DocumentEvent& aEvent)
override;
505 virtual void SAL_CALL changesOccurred(
const css::util::ChangesEvent& aEvent)
override;
508 virtual void SAL_CALL modified(
const css::lang::EventObject& aEvent)
override;
511 virtual void SAL_CALL
disposing(
const css::lang::EventObject& aEvent)
override;
518 css::uno::Any& aOldValue ,
520 const css::uno::Any& aValue )
override;
523 const css::uno::Any& aValue )
override;
526 sal_Int32 nHandle)
const override;
528 virtual ::cppu::IPropertyArrayHelper& SAL_CALL
getInfoHelper()
override;
530 virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo()
override;
533 virtual void SAL_CALL
disposing() final override;
548 void implts_openConfig();
562 void implts_readConfig();
575 void implts_readAutoSaveConfig();
578 void implts_flushConfigItem(const AutoRecovery::TDocumentInfo& rInfo ,
579 bool bRemoveIt = false);
582 void implts_startListening();
583 void implts_startModifyListeningOnDoc(AutoRecovery::TDocumentInfo& rInfo);
586 void implts_stopListening();
587 void implts_stopModifyListeningOnDoc(AutoRecovery::TDocumentInfo& rInfo);
601 void implts_updateTimer();
613 void implts_stopTimer();
617 DECL_LINK(implts_timerExpired,
Timer*,
void);
624 void implts_dispatch(const DispatchParams& aParams);
639 void implts_registerDocument(const css::
uno::Reference< css::frame::XModel3 >& xDocument);
654 void implts_deregisterDocument(const css::
uno::Reference< css::frame::XModel >& xDocument ,
655 bool bStopListening = true);
658 void implts_markDocumentModifiedAgainstLastBackup(const css::
uno::Reference< css::frame::XModel >& xDocument);
661 void implts_updateModifiedState(const css::
uno::Reference< css::frame::XModel >& xDocument);
664 void implts_updateDocumentUsedForSavingState(const css::
uno::Reference< css::frame::XModel >& xDocument ,
665 bool bSaveInProgress);
668 void implts_markDocumentAsSaved(const css::
uno::Reference< css::frame::XModel >& xDocument);
685 static TDocumentList::iterator impl_searchDocument( AutoRecovery::TDocumentList& rList ,
686 const css::
uno::Reference< css::frame::XModel >& xDocument);
689 void implts_changeAllDocVisibility(
bool bVisible);
690 void implts_prepareSessionShutdown();
727 AutoRecovery::ETimerType implts_saveDocs(
bool bAllowUserIdleLoop,
728 bool bRemoveLockFiles,
729 const DispatchParams* pParams =
nullptr);
764 void implts_saveOneDoc(const OUString& sBackupPath ,
765 AutoRecovery::TDocumentInfo& rInfo ,
766 const css::
uno::Reference< css::task::XStatusIndicator >& xExternalProgress);
775 AutoRecovery::ETimerType implts_openDocs(const DispatchParams& aParams);
778 void implts_openOneDoc(const OUString& sURL ,
779 utl::MediaDescriptor& lDescriptor,
780 AutoRecovery::TDocumentInfo& rInfo );
783 void implts_generateNewTempURL(const OUString& sBackupPath ,
784 utl::MediaDescriptor& rMediaDescriptor,
785 AutoRecovery::TDocumentInfo& rInfo );
803 void implts_informListener(
Job eJob ,
804 const css::frame::FeatureStateEvent& aEvent);
824 static css::frame::FeatureStateEvent implst_createFeatureStateEvent(
Job eJob ,
825 const OUString& sEventType,
826 AutoRecovery::TDocumentInfo const * pInfo );
828 class ListenerInformer
831 AutoRecovery &m_rRecovery;
835 ListenerInformer(AutoRecovery &rRecovery,
Job eJob)
836 : m_rRecovery(rRecovery), m_eJob(eJob), m_bStopped(false)
848 void implts_resetHandleStates();
851 void implts_specifyDefaultFilterAndExtension(AutoRecovery::TDocumentInfo& rInfo);
854 void implts_specifyAppModuleAndFactory(AutoRecovery::TDocumentInfo& rInfo);
860 void implts_collectActiveViewNames( AutoRecovery::TDocumentInfo& rInfo );
864 void implts_persistAllActiveViewNames();
867 void implts_prepareEmergencySave();
870 void implts_doEmergencySave(
const DispatchParams& aParams);
873 void implts_doRecovery(
const DispatchParams& aParams);
876 void implts_doSessionSave(
const DispatchParams& aParams);
879 void implts_doSessionQuietQuit();
882 void implts_doSessionRestore(
const DispatchParams& aParams);
885 void implts_backupWorkingEntry(
const DispatchParams& aParams);
888 void implts_cleanUpWorkingEntry(
const DispatchParams& aParams);
898 void impl_flushALLConfigChanges();
901 AutoRecovery::EFailureSafeResult implts_copyFile(
const OUString& sSource ,
902 const OUString& sTargetPath,
903 const OUString& sTargetName);
917 static OUString implst_getJobDescription(
Job eJob);
929 static Job implst_classifyJob(
const css::util::URL& aURL);
932 void implts_verifyCacheAgainstDesktopDocumentList();
935 bool impl_enoughDiscSpace(sal_Int32 nRequiredSpace);
938 static void impl_showFullDiscError();
963 void impl_establishProgress(
const AutoRecovery::TDocumentInfo& rInfo ,
965 const css::uno::Reference< css::frame::XFrame >& xNewFrame);
967 void impl_forgetProgress(
const AutoRecovery::TDocumentInfo& rInfo ,
969 const css::uno::Reference< css::frame::XFrame >& xNewFrame);
986 void st_impl_removeFile(
const OUString& sURL);
994 void st_impl_removeLockFile();
998constexpr OUStringLiteral CFG_PACKAGE_RECOVERY =
u"/org.openoffice.Office.Recovery";
1000const char CFG_ENTRY_AUTOSAVE_ENABLED[] =
"AutoSave/Enabled";
1001const char CFG_ENTRY_AUTOSAVE_USERAUTOSAVE_ENABLED[] =
"AutoSave/UserAutoSaveEnabled";
1003constexpr OUStringLiteral CFG_ENTRY_REALDEFAULTFILTER =
u"ooSetupFactoryActualFilter";
1005constexpr OUStringLiteral CFG_ENTRY_PROP_TEMPURL =
u"TempURL";
1006constexpr OUStringLiteral CFG_ENTRY_PROP_ORIGINALURL =
u"OriginalURL";
1007constexpr OUStringLiteral CFG_ENTRY_PROP_TEMPLATEURL =
u"TemplateURL";
1008constexpr OUStringLiteral CFG_ENTRY_PROP_FACTORYURL =
u"FactoryURL";
1009constexpr OUStringLiteral CFG_ENTRY_PROP_MODULE =
u"Module";
1010constexpr OUStringLiteral CFG_ENTRY_PROP_DOCUMENTSTATE =
u"DocumentState";
1011constexpr OUStringLiteral CFG_ENTRY_PROP_FILTER =
u"Filter";
1012constexpr OUStringLiteral CFG_ENTRY_PROP_TITLE =
u"Title";
1013constexpr OUStringLiteral CFG_ENTRY_PROP_ID =
u"ID";
1014constexpr OUStringLiteral CFG_ENTRY_PROP_VIEWNAMES =
u"ViewNames";
1016constexpr OUStringLiteral FILTER_PROP_TYPE =
u"Type";
1017constexpr OUStringLiteral TYPE_PROP_EXTENSIONS =
u"Extensions";
1020constexpr OUStringLiteral CFG_ENTRY_PROP_EMPTYDOCUMENTURL =
u"ooSetupFactoryEmptyDocumentURL";
1021constexpr OUStringLiteral CFG_ENTRY_PROP_FACTORYSERVICE =
u"ooSetupFactoryDocumentService";
1023const char EVENT_ON_NEW[] =
"OnNew";
1024const char EVENT_ON_LOAD[] =
"OnLoad";
1025const char EVENT_ON_UNLOAD[] =
"OnUnload";
1026const char EVENT_ON_MODIFYCHANGED[] =
"OnModifyChanged";
1027const char EVENT_ON_SAVE[] =
"OnSave";
1028const char EVENT_ON_SAVEAS[] =
"OnSaveAs";
1029const char EVENT_ON_SAVETO[] =
"OnCopyTo";
1030const char EVENT_ON_SAVEDONE[] =
"OnSaveDone";
1031const char EVENT_ON_SAVEASDONE[] =
"OnSaveAsDone";
1032const char EVENT_ON_SAVETODONE[] =
"OnCopyToDone";
1033const char EVENT_ON_SAVEFAILED[] =
"OnSaveFailed";
1034const char EVENT_ON_SAVEASFAILED[] =
"OnSaveAsFailed";
1035const char EVENT_ON_SAVETOFAILED[] =
"OnCopyToFailed";
1037constexpr OUStringLiteral RECOVERY_ITEM_BASE_IDENTIFIER =
u"recovery_item_";
1039const char CMD_PROTOCOL[] =
"vnd.sun.star.autorecovery:";
1041const char CMD_DO_AUTO_SAVE[] =
"/doAutoSave";
1042const char CMD_DO_PREPARE_EMERGENCY_SAVE[] =
"/doPrepareEmergencySave";
1043const char CMD_DO_EMERGENCY_SAVE[] =
"/doEmergencySave";
1044const char CMD_DO_RECOVERY[] =
"/doAutoRecovery";
1045const char CMD_DO_ENTRY_BACKUP[] =
"/doEntryBackup";
1046const char CMD_DO_ENTRY_CLEANUP[] =
"/doEntryCleanUp";
1047const char CMD_DO_SESSION_SAVE[] =
"/doSessionSave";
1048const char CMD_DO_SESSION_QUIET_QUIT[] =
"/doSessionQuietQuit";
1049const char CMD_DO_SESSION_RESTORE[] =
"/doSessionRestore";
1050const char CMD_DO_DISABLE_RECOVERY[] =
"/disableRecovery";
1051const char CMD_DO_SET_AUTOSAVE_STATE[] =
"/setAutoSaveState";
1053constexpr OUStringLiteral REFERRER_USER =
u"private:user";
1055constexpr OUStringLiteral PROP_DISPATCH_ASYNCHRON =
u"DispatchAsynchron";
1056constexpr OUStringLiteral PROP_PROGRESS =
u"StatusIndicator";
1058constexpr OUStringLiteral PROP_ENTRY_ID =
u"EntryID";
1059constexpr OUStringLiteral PROP_AUTOSAVE_STATE =
u"AutoSaveState";
1061constexpr OUStringLiteral OPERATION_START =
u"start";
1062constexpr OUStringLiteral OPERATION_STOP =
u"stop";
1063constexpr OUStringLiteral OPERATION_UPDATE =
u"update";
1065const sal_Int32 MIN_DISCSPACE_DOCSAVE = 5;
1066const sal_Int32 MIN_DISCSPACE_CONFIGSAVE = 1;
1067const sal_Int32 RETRY_STORE_ON_FULL_DISC_FOREVER = 300;
1068const sal_Int32 RETRY_STORE_ON_MIGHT_FULL_DISC_USEFULL = 3;
1069const sal_Int32 GIVE_UP_RETRY = 1;
1071#define SAVE_IN_PROGRESS true
1072#define SAVE_FINISHED false
1074#define LOCK_FOR_CACHE_ADD_REMOVE true
1075#define LOCK_FOR_CACHE_USE false
1077#define MIN_TIME_FOR_USER_IDLE 10000
1094 css::uno::Reference< css::uno::XInterface > m_xOwner;
1097 osl::Mutex& m_rSharedMutex;
1100 sal_Int32& m_rCacheLock;
1104 bool m_bLockedByThisGuard;
1108 CacheLockGuard(AutoRecovery*
pOwner ,
1109 osl::Mutex& rMutex ,
1110 sal_Int32& rCacheLock ,
1111 bool bLockForAddRemoveVectorItems);
1114 void lock(
bool bLockForAddRemoveVectorItems);
1118CacheLockGuard::CacheLockGuard(AutoRecovery* pOwner ,
1119 osl::Mutex& rMutex ,
1120 sal_Int32& rCacheLock ,
1121 bool bLockForAddRemoveVectorItems)
1122 : m_xOwner (static_cast< css::frame::XDispatch* >(
pOwner))
1123 , m_rSharedMutex (rMutex )
1124 , m_rCacheLock (rCacheLock )
1125 , m_bLockedByThisGuard(false )
1127 lock(bLockForAddRemoveVectorItems);
1130CacheLockGuard::~CacheLockGuard()
1136void CacheLockGuard::lock(
bool bLockForAddRemoveVectorItems)
1139 osl::MutexGuard g(m_rSharedMutex);
1141 if (m_bLockedByThisGuard)
1154 if ( (m_rCacheLock > 0) && bLockForAddRemoveVectorItems )
1156 OSL_FAIL(
"Re-entrance problem detected. Using of an stl structure in combination with iteration, adding, removing of elements etcpp.");
1157 throw css::uno::RuntimeException(
1158 "Re-entrance problem detected. Using of an stl structure in combination with iteration, adding, removing of elements etcpp.",
1163 m_bLockedByThisGuard =
true;
1167void CacheLockGuard::unlock()
1170 osl::MutexGuard g(m_rSharedMutex);
1172 if ( ! m_bLockedByThisGuard)
1176 m_bLockedByThisGuard =
false;
1178 if (m_rCacheLock < 0)
1180 OSL_FAIL(
"Wrong using of member m_nDocCacheLock detected. A ref counted value shouldn't reach values <0 .-)");
1181 throw css::uno::RuntimeException(
1182 "Wrong using of member m_nDocCacheLock detected. A ref counted value shouldn't reach values <0 .-)",
1188DispatchParams::DispatchParams()
1189 : m_nWorkingEntryID(-1)
1193DispatchParams::DispatchParams(const ::comphelper::SequenceAsHashMap& lArgs ,
1194 const css::uno::Reference< css::uno::XInterface >& xOwner)
1196 m_nWorkingEntryID = lArgs.getUnpackedValueOrDefault(PROP_ENTRY_ID, sal_Int32(-1) );
1197 m_xProgress = lArgs.getUnpackedValueOrDefault(PROP_PROGRESS, css::uno::Reference< css::task::XStatusIndicator >());
1198 m_sSavePath = lArgs.getUnpackedValueOrDefault(PROP_SAVEPATH, OUString() );
1199 m_xHoldRefForAsyncOpAlive = xOwner;
1202void DispatchParams::forget()
1204 m_sSavePath.clear();
1205 m_nWorkingEntryID = -1;
1206 m_xProgress.clear();
1207 m_xHoldRefForAsyncOpAlive.clear();
1210AutoRecovery::AutoRecovery(css::uno::Reference< css::uno::XComponentContext > xContext)
1212 , ::
cppu::OPropertySetHelper(
cppu::WeakComponentImplHelperBase::rBHelper)
1214 , m_bListenForDocEvents (false )
1215 , m_bListenForConfigChanges (false )
1216 , m_eJob (
Job::NoJob)
1217 , m_aTimer(
"framework::AutoRecovery m_aTimer" )
1218 , m_xAsyncDispatcher (new
vcl::EventPoster(
LINK( this, AutoRecovery, implts_asyncDispatch ) ))
1219 , m_eTimerType (E_DONT_START_TIMER )
1221 , m_lListener (
cppu::WeakComponentImplHelperBase::rBHelper.rMutex)
1222 , m_nDocCacheLock (0 )
1223 , m_nMinSpaceDocSave (MIN_DISCSPACE_DOCSAVE )
1224 , m_nMinSpaceConfigSave (MIN_DISCSPACE_CONFIGSAVE )
1228void AutoRecovery::initListeners()
1231 implts_readConfig();
1233 implts_startListening();
1238 m_aTimer.SetInvokeHandler(
LINK(
this, AutoRecovery, implts_timerExpired));
1241AutoRecovery::~AutoRecovery()
1243 assert(!m_aTimer.IsActive());
1246void AutoRecovery::disposing()
1250 m_xAsyncDispatcher.reset();
1253Any SAL_CALL AutoRecovery::queryInterface(
const css::uno::Type& _rType )
1255 Any aRet = AutoRecovery_BASE::queryInterface( _rType );
1256 if ( !aRet.hasValue() )
1257 aRet = OPropertySetHelper::queryInterface( _rType );
1261Sequence< css::uno::Type > SAL_CALL AutoRecovery::getTypes( )
1264 AutoRecovery_BASE::getTypes(),
1269void SAL_CALL AutoRecovery::dispatch(
const css::util::URL& aURL ,
1270 const css::uno::Sequence< css::beans::PropertyValue >& lArguments)
1272 SAL_INFO(
"fwk.autorecovery",
"AutoRecovery::dispatch() starts ..." <<
aURL.Complete);
1275 Job eNewJob = AutoRecovery::implst_classifyJob(aURL);
1276 if (eNewJob == Job::NoJob)
1280 DispatchParams aParams;
1282 osl::ClearableMutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
1287 ( m_eJob != Job::NoJob ) &&
1288 ((m_eJob & Job::AutoSave ) != Job::AutoSave)
1291 SAL_INFO(
"fwk.autorecovery",
"AutoRecovery::dispatch(): There is already an asynchronous dispatch() running. New request will be ignored!");
1299 if ((eNewJob & Job::DisableAutorecovery) == Job::DisableAutorecovery)
1304 implts_stopListening();
1310 if ((eNewJob & Job::SetAutosaveState) == Job::SetAutosaveState)
1312 bool bOn = lArgs.getUnpackedValueOrDefault(PROP_AUTOSAVE_STATE,
true);
1317 implts_readAutoSaveConfig();
1319 implts_updateTimer();
1322 implts_startListening();
1327 m_eJob &=
~Job::AutoSave;
1328 m_eTimerType = AutoRecovery::E_DONT_START_TIMER;
1335 bAsync = lArgs.getUnpackedValueOrDefault(PROP_DISPATCH_ASYNCHRON,
false);
1336 aParams = DispatchParams(lArgs,
static_cast< css::frame::XDispatch*
>(
this));
1340 m_aDispatchParams = aParams;
1345 m_xAsyncDispatcher->Post();
1347 implts_dispatch(aParams);
1350void AutoRecovery::ListenerInformer::start()
1352 m_rRecovery.implts_informListener(m_eJob,
1353 AutoRecovery::implst_createFeatureStateEvent(m_eJob, OPERATION_START,
nullptr));
1356void AutoRecovery::ListenerInformer::stop()
1360 m_rRecovery.implts_informListener(m_eJob,
1361 AutoRecovery::implst_createFeatureStateEvent(m_eJob, OPERATION_STOP,
nullptr));
1365void AutoRecovery::implts_dispatch(
const DispatchParams& aParams)
1369 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
1375 bool bWasAutoSaveActive = ((eJob & Job::AutoSave) == Job::AutoSave);
1376 bool bWasUserAutoSaveActive =
1377 ((eJob & Job::UserAutoSave) == Job::UserAutoSave);
1384 bool bAllowAutoSaveReactivation =
true;
1387 implts_stopListening();
1389 ListenerInformer aListenerInformer(*
this, eJob);
1390 aListenerInformer.start();
1397 ((eJob & Job::PrepareEmergencySave) == Job::PrepareEmergencySave) &&
1398 ((eJob & Job::DisableAutorecovery ) != Job::DisableAutorecovery )
1401 SAL_INFO(
"fwk.autorecovery",
"... prepare emergency save ...");
1402 bAllowAutoSaveReactivation =
false;
1403 implts_prepareEmergencySave();
1407 ((eJob & Job::EmergencySave ) == Job::EmergencySave ) &&
1408 ((eJob & Job::DisableAutorecovery) != Job::DisableAutorecovery)
1411 SAL_INFO(
"fwk.autorecovery",
"... do emergency save ...");
1412 bAllowAutoSaveReactivation =
false;
1413 implts_doEmergencySave(aParams);
1417 ((eJob & Job::Recovery ) == Job::Recovery ) &&
1418 ((eJob & Job::DisableAutorecovery) != Job::DisableAutorecovery)
1421 SAL_INFO(
"fwk.autorecovery",
"... do recovery ...");
1422 implts_doRecovery(aParams);
1426 ((eJob & Job::SessionSave ) == Job::SessionSave ) &&
1427 ((eJob & Job::DisableAutorecovery) != Job::DisableAutorecovery)
1430 SAL_INFO(
"fwk.autorecovery",
"... do session save ...");
1431 bAllowAutoSaveReactivation =
false;
1432 implts_doSessionSave(aParams);
1436 ((eJob & Job::SessionQuietQuit ) == Job::SessionQuietQuit ) &&
1437 ((eJob & Job::DisableAutorecovery) != Job::DisableAutorecovery)
1440 SAL_INFO(
"fwk.autorecovery",
"... do session quiet quit ...");
1441 bAllowAutoSaveReactivation =
false;
1442 implts_doSessionQuietQuit();
1446 ((eJob & Job::SessionRestore ) == Job::SessionRestore ) &&
1447 ((eJob & Job::DisableAutorecovery) != Job::DisableAutorecovery)
1450 SAL_INFO(
"fwk.autorecovery",
"... do session restore ...");
1451 implts_doSessionRestore(aParams);
1455 ((eJob & Job::EntryBackup ) == Job::EntryBackup ) &&
1456 ((eJob & Job::DisableAutorecovery) != Job::DisableAutorecovery)
1458 implts_backupWorkingEntry(aParams);
1461 ((eJob & Job::EntryCleanup ) == Job::EntryCleanup ) &&
1462 ((eJob & Job::DisableAutorecovery) != Job::DisableAutorecovery)
1464 implts_cleanUpWorkingEntry(aParams);
1466 catch(
const css::uno::RuntimeException&)
1470 catch(
const css::uno::Exception&)
1475 aListenerInformer.stop();
1478 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
1479 m_eJob = Job::NoJob;
1480 if ( bAllowAutoSaveReactivation && bWasAutoSaveActive )
1482 m_eJob |= Job::AutoSave;
1484 if (bWasUserAutoSaveActive)
1486 m_eJob |= Job::UserAutoSave;
1493 implts_updateTimer();
1495 if (bAllowAutoSaveReactivation)
1496 implts_startListening();
1499void SAL_CALL AutoRecovery::addStatusListener(
const css::uno::Reference< css::frame::XStatusListener >& xListener,
1500 const css::util::URL& aURL )
1502 if (!xListener.is())
1503 throw css::uno::RuntimeException(
"Invalid listener reference.",
static_cast< css::frame::XDispatch*
>(
this));
1505 m_lListener.addInterface(
aURL.Complete, xListener);
1508 CacheLockGuard aCacheLock(
this, cppu::WeakComponentImplHelperBase::rBHelper.rMutex, m_nDocCacheLock,
LOCK_FOR_CACHE_USE);
1511 osl::ResettableMutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
1513 for (
auto const& elem : m_lDocCache)
1515 css::frame::FeatureStateEvent
aEvent = AutoRecovery::implst_createFeatureStateEvent(m_eJob, OPERATION_UPDATE, &elem);
1519 xListener->statusChanged(aEvent);
1527void SAL_CALL AutoRecovery::removeStatusListener(
const css::uno::Reference< css::frame::XStatusListener >& xListener,
1528 const css::util::URL& aURL )
1530 if (!xListener.is())
1531 throw css::uno::RuntimeException(
"Invalid listener reference.",
static_cast< css::frame::XDispatch*
>(
this));
1533 m_lListener.removeInterface(
aURL.Complete, xListener);
1536void SAL_CALL AutoRecovery::documentEventOccured(
const css::document::DocumentEvent& aEvent)
1538 css::uno::Reference< css::frame::XModel3 > xDocument(
aEvent.Source, css::uno::UNO_QUERY);
1542 (
aEvent.EventName == EVENT_ON_NEW) ||
1543 (
aEvent.EventName == EVENT_ON_LOAD)
1546 implts_registerDocument(xDocument);
1549 else if (
aEvent.EventName == EVENT_ON_MODIFYCHANGED )
1551 implts_updateModifiedState(xDocument);
1559 (
aEvent.EventName == EVENT_ON_SAVE) ||
1560 (
aEvent.EventName == EVENT_ON_SAVEAS) ||
1561 (
aEvent.EventName == EVENT_ON_SAVETO)
1568 (
aEvent.EventName == EVENT_ON_SAVEDONE) ||
1569 (
aEvent.EventName == EVENT_ON_SAVEASDONE)
1573 implts_markDocumentAsSaved(xDocument);
1574 implts_updateDocumentUsedForSavingState(xDocument,
SAVE_FINISHED);
1581 else if (
aEvent.EventName == EVENT_ON_SAVETODONE )
1583 implts_updateDocumentUsedForSavingState(xDocument,
SAVE_FINISHED);
1590 (
aEvent.EventName == EVENT_ON_SAVEFAILED) ||
1591 (
aEvent.EventName == EVENT_ON_SAVEASFAILED) ||
1592 (
aEvent.EventName == EVENT_ON_SAVETOFAILED)
1595 implts_updateDocumentUsedForSavingState(xDocument,
SAVE_FINISHED);
1598 else if (
aEvent.EventName == EVENT_ON_UNLOAD )
1600 implts_deregisterDocument(xDocument);
1604void SAL_CALL AutoRecovery::changesOccurred(
const css::util::ChangesEvent& aEvent)
1606 const css::uno::Sequence< css::util::ElementChange > lChanges (
aEvent.Changes);
1607 const css::util::ElementChange* pChanges = lChanges.getConstArray();
1609 sal_Int32 c = lChanges.getLength();
1613 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
1618 if ((m_eJob & Job::DisableAutorecovery) == Job::DisableAutorecovery)
1624 pChanges[
i].Accessor >>= sPath;
1626 if ( sPath == CFG_ENTRY_AUTOSAVE_ENABLED )
1628 bool bEnabled =
false;
1629 if (pChanges[i].Element >>= bEnabled)
1633 m_eJob |= Job::AutoSave;
1634 m_eTimerType = AutoRecovery::E_NORMAL_AUTOSAVE_INTERVALL;
1638 m_eJob &=
~Job::AutoSave;
1639 m_eTimerType = AutoRecovery::E_DONT_START_TIMER;
1643 else if (sPath == CFG_ENTRY_AUTOSAVE_USERAUTOSAVE_ENABLED)
1645 bool bEnabled =
false;
1646 if (pChanges[i].Element >>= bEnabled)
1649 m_eJob |= Job::UserAutoSave;
1651 m_eJob &=
~Job::UserAutoSave;
1661 implts_updateTimer();
1664void SAL_CALL AutoRecovery::modified(
const css::lang::EventObject& aEvent)
1666 css::uno::Reference< css::frame::XModel > xDocument(
aEvent.Source, css::uno::UNO_QUERY);
1667 if (! xDocument.is())
1670 implts_markDocumentModifiedAgainstLastBackup(xDocument);
1673void SAL_CALL AutoRecovery::disposing(
const css::lang::EventObject& aEvent)
1676 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
1678 if (
aEvent.Source == m_xNewDocBroadcaster)
1680 m_xNewDocBroadcaster.clear();
1684 if (
aEvent.Source == m_xRecoveryCFG)
1686 m_xRecoveryCFG.clear();
1693 css::uno::Reference< css::frame::XModel > xDocument(
aEvent.Source, css::uno::UNO_QUERY);
1696 implts_deregisterDocument(xDocument,
false);
1703void AutoRecovery::implts_openConfig()
1706 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
1708 if (m_xRecoveryCFG.is())
1712 css::uno::Reference<css::lang::XMultiServiceFactory> xConfigProvider(
1713 css::configuration::theDefaultProvider::get(
m_xContext));
1715 std::vector<css::uno::Any> lParams;
1716 css::beans::PropertyValue aParam;
1719 aParam.Name =
"nodepath";
1720 aParam.Value <<= OUString(CFG_PACKAGE_RECOVERY);
1721 lParams.push_back(css::uno::Any(aParam));
1724 css::uno::Reference<css::container::XNameAccess> xCFG(
1725 xConfigProvider->createInstanceWithArguments(
1726 "com.sun.star.configuration.ConfigurationAccess",
1728 css::uno::UNO_QUERY);
1730 sal_Int32 nMinSpaceDocSave = MIN_DISCSPACE_DOCSAVE;
1731 sal_Int32 nMinSpaceConfigSave = MIN_DISCSPACE_CONFIGSAVE;
1735 nMinSpaceDocSave = officecfg::Office::Recovery::AutoSave::MinSpaceDocSave::get();
1736 nMinSpaceConfigSave = officecfg::Office::Recovery::AutoSave::MinSpaceConfigSave::get();
1738 catch(
const css::uno::Exception&)
1742 nMinSpaceDocSave = MIN_DISCSPACE_DOCSAVE;
1743 nMinSpaceConfigSave = MIN_DISCSPACE_CONFIGSAVE;
1747 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
1748 m_xRecoveryCFG = xCFG;
1749 m_nMinSpaceDocSave = nMinSpaceDocSave;
1750 m_nMinSpaceConfigSave = nMinSpaceConfigSave;
1754void AutoRecovery::implts_readAutoSaveConfig()
1756 implts_openConfig();
1759 bool bEnabled(officecfg::Office::Recovery::AutoSave::Enabled::get());
1762 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
1765 bool bUserEnabled(officecfg::Office::Recovery::AutoSave::UserAutoSaveEnabled::get());
1767 m_eJob |= Job::AutoSave;
1768 m_eTimerType = AutoRecovery::E_NORMAL_AUTOSAVE_INTERVALL;
1772 m_eJob |= Job::UserAutoSave;
1776 m_eJob &=
~Job::UserAutoSave;
1781 m_eJob &=
~Job::AutoSave;
1782 m_eTimerType = AutoRecovery::E_DONT_START_TIMER;
1787void AutoRecovery::implts_readConfig()
1789 implts_readAutoSaveConfig();
1792 CacheLockGuard aCacheLock(
this, cppu::WeakComponentImplHelperBase::rBHelper.rMutex, m_nDocCacheLock,
LOCK_FOR_CACHE_ADD_REMOVE);
1795 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
1797 m_lDocCache.clear();
1801 aCacheLock.unlock();
1804 css::uno::Reference<css::container::XNameAccess> xRecoveryList(
1805 officecfg::Office::Recovery::RecoveryList::get());
1806 const css::uno::Sequence< OUString > lItems = xRecoveryList->getElementNames();
1807 const OUString* pItems = lItems.getConstArray();
1808 sal_Int32 c = lItems.getLength();
1816 css::uno::Reference< css::beans::XPropertySet > xItem;
1817 xRecoveryList->getByName(pItems[i]) >>= xItem;
1821 AutoRecovery::TDocumentInfo aInfo;
1822 aInfo.NewTempURL.clear();
1823 aInfo.Document.clear();
1824 xItem->getPropertyValue(CFG_ENTRY_PROP_ORIGINALURL) >>= aInfo.OrgURL;
1825 xItem->getPropertyValue(CFG_ENTRY_PROP_TEMPURL) >>= aInfo.OldTempURL;
1826 xItem->getPropertyValue(CFG_ENTRY_PROP_TEMPLATEURL) >>= aInfo.TemplateURL;
1827 xItem->getPropertyValue(CFG_ENTRY_PROP_FILTER) >>= aInfo.RealFilter;
1829 xItem->getPropertyValue(CFG_ENTRY_PROP_DOCUMENTSTATE) >>= tmp;
1830 aInfo.DocumentState = DocState(tmp);
1831 xItem->getPropertyValue(CFG_ENTRY_PROP_MODULE) >>= aInfo.AppModule;
1832 xItem->getPropertyValue(CFG_ENTRY_PROP_TITLE) >>= aInfo.Title;
1833 xItem->getPropertyValue(CFG_ENTRY_PROP_VIEWNAMES) >>= aInfo.ViewNames;
1834 implts_specifyAppModuleAndFactory(aInfo);
1835 implts_specifyDefaultFilterAndExtension(aInfo);
1837 if (pItems[i].startsWith(RECOVERY_ITEM_BASE_IDENTIFIER))
1839 std::u16string_view sID = pItems[
i].subView(RECOVERY_ITEM_BASE_IDENTIFIER.getLength());
1842 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
1843 if (aInfo.ID > m_nIdPool)
1845 m_nIdPool = aInfo.ID+1;
1846 SAL_WARN_IF(m_nIdPool<0,
"fwk.autorecovery",
"AutoRecovery::implts_readConfig(): Overflow of IDPool detected!");
1851 SAL_INFO(
"fwk.autorecovery",
"AutoRecovery::implts_readConfig(): Who changed numbering of recovery items? Cache will be inconsistent then! I do not know, what will happen next time .-)");
1854 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
1855 m_lDocCache.push_back(aInfo);
1859 aCacheLock.unlock();
1862 implts_updateTimer();
1865void AutoRecovery::implts_specifyDefaultFilterAndExtension(AutoRecovery::TDocumentInfo& rInfo)
1867 if (rInfo.AppModule.isEmpty())
1869 throw css::uno::RuntimeException(
1870 "Can not find out the default filter and its extension, if no application module is known!",
1871 static_cast< css::frame::XDispatch*
>(
this));
1874 css::uno::Reference< css::container::XNameAccess> xCFG;
1876 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
1877 xCFG = m_xModuleCFG;
1884 implts_openConfig();
1886 xCFG.set(officecfg::Setup::Office::Factories::get(),
1887 css::uno::UNO_SET_THROW);
1890 osl::MutexGuard g2(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
1891 m_xModuleCFG = xCFG;
1895 css::uno::Reference< css::container::XNameAccess > xModuleProps(
1896 xCFG->getByName(rInfo.AppModule),
1897 css::uno::UNO_QUERY_THROW);
1899 xModuleProps->getByName(CFG_ENTRY_REALDEFAULTFILTER) >>= rInfo.DefaultFilter;
1901 css::uno::Reference< css::container::XNameAccess > xFilterCFG(
1902 m_xContext->getServiceManager()->createInstanceWithContext(
1903 "com.sun.star.document.FilterFactory",
m_xContext), css::uno::UNO_QUERY_THROW);
1904 css::uno::Reference< css::container::XNameAccess > xTypeCFG(
1905 m_xContext->getServiceManager()->createInstanceWithContext(
1906 "com.sun.star.document.TypeDetection",
m_xContext), css::uno::UNO_QUERY_THROW);
1909 OUString sTypeRegistration = lFilterProps.getUnpackedValueOrDefault(FILTER_PROP_TYPE, OUString());
1911 css::uno::Sequence< OUString > lExtensions = lTypeProps.getUnpackedValueOrDefault(TYPE_PROP_EXTENSIONS, css::uno::Sequence< OUString >());
1912 if (lExtensions.hasElements())
1914 rInfo.Extension =
"." + lExtensions[0];
1917 rInfo.Extension =
".unknown";
1919 catch(
const css::uno::Exception&)
1921 rInfo.DefaultFilter.clear();
1922 rInfo.Extension.clear();
1926void AutoRecovery::implts_specifyAppModuleAndFactory(AutoRecovery::TDocumentInfo& rInfo)
1929 !rInfo.AppModule.isEmpty() || rInfo.Document.is(),
1930 "Can not find out the application module nor its factory URL, if no application module (or a suitable) document is known!",
1933 css::uno::Reference< css::frame::XModuleManager2 > xManager = ModuleManager::create(
m_xContext);
1935 if (rInfo.AppModule.isEmpty())
1936 rInfo.AppModule = xManager->identify(rInfo.Document);
1939 lModuleDescription[CFG_ENTRY_PROP_EMPTYDOCUMENTURL] >>= rInfo.FactoryURL;
1940 lModuleDescription[CFG_ENTRY_PROP_FACTORYSERVICE] >>= rInfo.FactoryService;
1943void AutoRecovery::implts_collectActiveViewNames( AutoRecovery::TDocumentInfo& i_rInfo )
1945 ENSURE_OR_THROW2( i_rInfo.Document.is(),
"need at document, at the very least", *
this );
1947 i_rInfo.ViewNames.realloc(0);
1950 ::std::vector< OUString > aViewNames;
1951 const Reference< XModel2 >
xModel( i_rInfo.Document, UNO_QUERY );
1954 const Reference< css::container::XEnumeration > xEnumControllers(
xModel->getControllers() );
1955 while ( xEnumControllers->hasMoreElements() )
1957 const Reference< XController2 >
xController( xEnumControllers->nextElement(), UNO_QUERY );
1961 OSL_ENSURE( !sViewName.isEmpty(),
"AutoRecovery::implts_collectActiveViewNames: (no XController2 ->) no view name -> no recovery of this view!" );
1963 if ( !sViewName.isEmpty() )
1964 aViewNames.push_back( sViewName );
1968 i_rInfo.ViewNames.realloc( aViewNames.size() );
1969 ::std::copy( aViewNames.begin(), aViewNames.end(), i_rInfo.ViewNames.getArray() );
1972void AutoRecovery::implts_persistAllActiveViewNames()
1974 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
1977 for (
auto & elem : m_lDocCache)
1979 implts_collectActiveViewNames(elem);
1980 implts_flushConfigItem(elem);
1984void AutoRecovery::implts_flushConfigItem(
const AutoRecovery::TDocumentInfo& rInfo,
bool bRemoveIt)
1986 std::shared_ptr<comphelper::ConfigurationChanges> batch(
1991 implts_openConfig();
1993 css::uno::Reference<css::container::XNameAccess> xCheck(
1994 officecfg::Office::Recovery::RecoveryList::get(batch));
1996 css::uno::Reference< css::container::XNameContainer > xModify(xCheck, css::uno::UNO_QUERY_THROW);
1997 css::uno::Reference< css::lang::XSingleServiceFactory > xCreate(xCheck, css::uno::UNO_QUERY_THROW);
1999 OUString sID = RECOVERY_ITEM_BASE_IDENTIFIER + OUString::number(rInfo.ID);
2009 xModify->removeByName(sID);
2011 catch(
const css::container::NoSuchElementException&)
2019 css::uno::Reference< css::beans::XPropertySet > xSet;
2020 bool bNew = !xCheck->hasByName(sID);
2022 xSet.set(xCreate->createInstance(), css::uno::UNO_QUERY_THROW);
2024 xCheck->getByName(sID) >>= xSet;
2026 xSet->setPropertyValue(CFG_ENTRY_PROP_ORIGINALURL, css::uno::Any(rInfo.OrgURL ));
2027 xSet->setPropertyValue(CFG_ENTRY_PROP_TEMPURL, css::uno::Any(rInfo.OldTempURL ));
2028 xSet->setPropertyValue(CFG_ENTRY_PROP_TEMPLATEURL, css::uno::Any(rInfo.TemplateURL ));
2029 xSet->setPropertyValue(CFG_ENTRY_PROP_FILTER, css::uno::Any(rInfo.RealFilter));
2030 xSet->setPropertyValue(CFG_ENTRY_PROP_DOCUMENTSTATE, css::uno::Any(sal_Int32(rInfo.DocumentState)));
2031 xSet->setPropertyValue(CFG_ENTRY_PROP_MODULE, css::uno::Any(rInfo.AppModule));
2032 xSet->setPropertyValue(CFG_ENTRY_PROP_TITLE, css::uno::Any(rInfo.Title));
2033 xSet->setPropertyValue(CFG_ENTRY_PROP_VIEWNAMES, css::uno::Any(rInfo.ViewNames));
2036 xModify->insertByName(sID, css::uno::Any(xSet));
2039 catch(
const css::uno::RuntimeException&)
2043 catch(
const css::uno::Exception&)
2048 sal_Int32 nRetry = RETRY_STORE_ON_FULL_DISC_FOREVER;
2055#ifdef TRIGGER_FULL_DISC_CHECK
2056 throw css::uno::Exception(
"trigger full disk check");
2061 catch(
const css::uno::Exception&)
2067 sal_Int32 nMinSpaceConfigSave;
2069 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
2070 nMinSpaceConfigSave = m_nMinSpaceConfigSave;
2073 if (! impl_enoughDiscSpace(nMinSpaceConfigSave))
2074 AutoRecovery::impl_showFullDiscError();
2075 else if (nRetry > RETRY_STORE_ON_MIGHT_FULL_DISC_USEFULL)
2076 nRetry = RETRY_STORE_ON_MIGHT_FULL_DISC_USEFULL;
2077 else if (nRetry <= GIVE_UP_RETRY)
2086void AutoRecovery::implts_startListening()
2088 css::uno::Reference< css::util::XChangesNotifier > xCFG;
2089 css::uno::Reference< css::frame::XGlobalEventBroadcaster > xBroadcaster;
2090 bool bListenForDocEvents;
2091 bool bListenForConfigChanges;
2093 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
2094 xCFG.set (m_xRecoveryCFG, css::uno::UNO_QUERY);
2095 xBroadcaster = m_xNewDocBroadcaster;
2096 bListenForDocEvents = m_bListenForDocEvents;
2097 bListenForConfigChanges = m_bListenForConfigChanges;
2102 (! bListenForConfigChanges)
2105 css::uno::Reference<css::util::XChangesListener>
const xListener(
2107 xCFG->addChangesListener(xListener);
2109 osl::MutexGuard g2(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
2110 m_xRecoveryCFGListener = xListener;
2111 m_bListenForConfigChanges =
true;
2115 if (!xBroadcaster.is())
2117 xBroadcaster = css::frame::theGlobalEventBroadcaster::get(
m_xContext);
2119 osl::MutexGuard g2(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
2120 m_xNewDocBroadcaster = xBroadcaster;
2125 ( xBroadcaster.is() ) &&
2126 (! bListenForDocEvents)
2129 css::uno::Reference<css::document::XDocumentEventListener>
const
2131 xBroadcaster->addDocumentEventListener(xListener);
2133 osl::MutexGuard g2(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
2134 m_xNewDocBroadcasterListener = xListener;
2135 m_bListenForDocEvents =
true;
2140void AutoRecovery::implts_stopListening()
2142 css::uno::Reference< css::util::XChangesNotifier > xCFG;
2143 css::uno::Reference< css::document::XDocumentEventBroadcaster > xGlobalEventBroadcaster;
2145 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
2149 xCFG.set (m_xRecoveryCFG , css::uno::UNO_QUERY);
2150 xGlobalEventBroadcaster = m_xNewDocBroadcaster;
2153 if (xGlobalEventBroadcaster.is() && m_bListenForDocEvents)
2155 xGlobalEventBroadcaster->removeDocumentEventListener(m_xNewDocBroadcasterListener);
2156 m_bListenForDocEvents =
false;
2159 if (xCFG.is() && m_bListenForConfigChanges)
2161 xCFG->removeChangesListener(m_xRecoveryCFGListener);
2162 m_bListenForConfigChanges =
false;
2166void AutoRecovery::implts_startModifyListeningOnDoc(AutoRecovery::TDocumentInfo& rInfo)
2168 if (rInfo.ListenForModify)
2171 css::uno::Reference< css::util::XModifyBroadcaster > xBroadcaster(rInfo.Document, css::uno::UNO_QUERY);
2172 if (xBroadcaster.is())
2174 css::uno::Reference< css::util::XModifyListener > xThis(
this);
2175 xBroadcaster->addModifyListener(xThis);
2176 rInfo.ListenForModify =
true;
2180void AutoRecovery::implts_stopModifyListeningOnDoc(AutoRecovery::TDocumentInfo& rInfo)
2182 if (! rInfo.ListenForModify)
2185 css::uno::Reference< css::util::XModifyBroadcaster > xBroadcaster(rInfo.Document, css::uno::UNO_QUERY);
2186 if (xBroadcaster.is())
2188 css::uno::Reference< css::util::XModifyListener > xThis(
this);
2189 xBroadcaster->removeModifyListener(xThis);
2190 rInfo.ListenForModify =
false;
2194void AutoRecovery::implts_updateTimer()
2198 sal_Int64 nMilliSeconds = 0;
2201 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
2204 (m_eJob == Job::NoJob ) ||
2205 (m_eTimerType == AutoRecovery::E_DONT_START_TIMER)
2209 if (m_eTimerType == AutoRecovery::E_NORMAL_AUTOSAVE_INTERVALL)
2211 const sal_Int64 nConfiguredAutoSaveInterval
2212 = officecfg::Office::Recovery::AutoSave::TimeIntervall::get()
2214 nMilliSeconds = nConfiguredAutoSaveInterval;
2218 for (
const auto& docInfo : m_lDocCache)
2220 if (
auto xDocRecovery2 = docInfo.Document.query<XDocumentRecovery2>())
2222 sal_Int64 nDirtyDuration = xDocRecovery2->getModifiedStateDuration();
2223 if (nDirtyDuration < 0)
2225 if (nDirtyDuration > nConfiguredAutoSaveInterval)
2226 nDirtyDuration = nConfiguredAutoSaveInterval;
2229 = std::min(nMilliSeconds, nConfiguredAutoSaveInterval - nDirtyDuration);
2233 else if (m_eTimerType == AutoRecovery::E_POLL_FOR_USER_IDLE)
2237 else if (m_eTimerType == AutoRecovery::E_POLL_TILL_AUTOSAVE_IS_ALLOWED)
2238 nMilliSeconds = 300;
2244 m_aTimer.SetTimeout(nMilliSeconds);
2248void AutoRecovery::implts_stopTimer()
2252 if (!m_aTimer.IsActive())
2265 css::uno::Reference< css::uno::XInterface > xSelfHold(
static_cast< css::lang::XTypeProvider*
>(
this));
2275 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
2276 if ((m_eJob & Job::DisableAutorecovery) == Job::DisableAutorecovery)
2284 if (bAutoSaveNotAllowed)
2287 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
2288 m_eTimerType = AutoRecovery::E_POLL_TILL_AUTOSAVE_IS_ALLOWED;
2290 implts_updateTimer();
2298 osl::ClearableMutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
2300 if (m_eTimerType == AutoRecovery::E_POLL_FOR_USER_IDLE)
2306 implts_updateTimer();
2313 implts_informListener(Job::AutoSave,
2314 AutoRecovery::implst_createFeatureStateEvent(Job::AutoSave, OPERATION_START,
nullptr));
2319 AutoRecovery::ETimerType eSuggestedTimer = implts_saveDocs(
true,
false);
2328 (eSuggestedTimer == AutoRecovery::E_DONT_START_TIMER ) ||
2329 (eSuggestedTimer == AutoRecovery::E_NORMAL_AUTOSAVE_INTERVALL)
2332 implts_resetHandleStates();
2335 implts_informListener(Job::AutoSave,
2336 AutoRecovery::implst_createFeatureStateEvent(Job::AutoSave, OPERATION_STOP,
nullptr));
2340 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
2341 m_eTimerType = eSuggestedTimer;
2344 implts_updateTimer();
2346 catch(
const css::uno::Exception&)
2353 DispatchParams aParams;
2355 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
2356 aParams = m_aDispatchParams;
2357 css::uno::Reference< css::uno::XInterface > xHoldRefForMethodAlive = aParams.m_xHoldRefForAsyncOpAlive;
2358 m_aDispatchParams.forget();
2363 implts_dispatch(aParams);
2370void AutoRecovery::implts_registerDocument(
const css::uno::Reference< css::frame::XModel3 > & xDocument)
2373 if (!xDocument.is())
2376 CacheLockGuard aCacheLock(
this, cppu::WeakComponentImplHelperBase::rBHelper.rMutex, m_nDocCacheLock,
LOCK_FOR_CACHE_USE);
2383 AutoRecovery::TDocumentList::iterator pIt = AutoRecovery::impl_searchDocument(m_lDocCache, xDocument);
2384 if (pIt != m_lDocCache.end())
2389 implts_updateModifiedState(xDocument);
2393 aCacheLock.unlock();
2395 utl::MediaDescriptor lDescriptor(xDocument->getArgs2( { utl::MediaDescriptor::PROP_FILTERNAME, utl::MediaDescriptor::PROP_NOAUTOSAVE } ));
2405 css::uno::Reference< css::frame::XController >
xController = xDocument->getCurrentController();
2412 css::uno::Reference< css::frame::XDesktop > xDesktop (
xFrame->getCreator(), css::uno::UNO_QUERY);
2417 Reference< XDocumentRecovery > xDocRecovery( xDocument, UNO_QUERY );
2418 if ( !xDocRecovery.is() )
2423 AutoRecovery::TDocumentInfo aNew;
2424 aNew.Document = xDocument;
2427 css::uno::Reference< css::frame::XStorable > xDoc(aNew.Document, css::uno::UNO_QUERY_THROW);
2428 aNew.OrgURL = xDoc->getLocation();
2430 css::uno::Reference< css::frame::XTitle > xTitle(aNew.Document, css::uno::UNO_QUERY_THROW);
2431 aNew.Title = xTitle->getTitle ();
2434 implts_specifyAppModuleAndFactory(aNew);
2440 (aNew.OrgURL.isEmpty()) &&
2441 (aNew.FactoryURL.isEmpty())
2444 OSL_FAIL(
"AutoRecovery::implts_registerDocument: this should not happen anymore!" );
2453 implts_specifyDefaultFilterAndExtension(aNew);
2458 css::uno::Reference< css::document::XDocumentPropertiesSupplier > xSupplier(aNew.Document, css::uno::UNO_QUERY);
2461 css::uno::Reference< css::document::XDocumentProperties > xDocProps(xSupplier->getDocumentProperties(), css::uno::UNO_SET_THROW);
2462 aNew.TemplateURL = xDocProps->getTemplateURL();
2465 css::uno::Reference< css::util::XModifiable > xModifyCheck(xDocument, css::uno::UNO_QUERY_THROW);
2466 if (xModifyCheck->isModified())
2468 aNew.DocumentState |= DocState::Modified;
2473 AutoRecovery::TDocumentInfo aInfo;
2475 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
2479 aNew.ID = m_nIdPool;
2480 SAL_WARN_IF(m_nIdPool<0,
"fwk.autorecovery",
"AutoRecovery::implts_registerDocument(): Overflow of ID pool detected.");
2481 m_lDocCache.push_back(aNew);
2483 AutoRecovery::TDocumentList::iterator pIt1 = AutoRecovery::impl_searchDocument(m_lDocCache, xDocument);
2488 implts_flushConfigItem(aInfo);
2489 implts_startModifyListeningOnDoc(aInfo);
2491 aCacheLock.unlock();
2494void AutoRecovery::implts_deregisterDocument(
const css::uno::Reference< css::frame::XModel >& xDocument ,
2495 bool bStopListening)
2497 AutoRecovery::TDocumentInfo aInfo;
2499 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
2503 CacheLockGuard aCacheLock(
this, cppu::WeakComponentImplHelperBase::rBHelper.rMutex, m_nDocCacheLock,
LOCK_FOR_CACHE_USE);
2505 AutoRecovery::TDocumentList::iterator pIt = AutoRecovery::impl_searchDocument(m_lDocCache, xDocument);
2506 if (pIt == m_lDocCache.end())
2511 aCacheLock.unlock();
2517 if (aInfo.IgnoreClosing)
2520 CacheLockGuard aCacheLock2(
this, cppu::WeakComponentImplHelperBase::rBHelper.rMutex, m_nDocCacheLock,
LOCK_FOR_CACHE_ADD_REMOVE);
2521 pIt = AutoRecovery::impl_searchDocument(m_lDocCache, xDocument);
2522 if (pIt != m_lDocCache.end())
2523 m_lDocCache.erase(pIt);
2524 pIt = m_lDocCache.end();
2525 aCacheLock2.unlock();
2534 implts_stopModifyListeningOnDoc(aInfo);
2536 AutoRecovery::st_impl_removeFile(aInfo.OldTempURL);
2537 AutoRecovery::st_impl_removeFile(aInfo.NewTempURL);
2538 implts_flushConfigItem(aInfo,
true);
2541void AutoRecovery::implts_markDocumentModifiedAgainstLastBackup(
const css::uno::Reference< css::frame::XModel >& xDocument)
2543 CacheLockGuard aCacheLock(
this, cppu::WeakComponentImplHelperBase::rBHelper.rMutex, m_nDocCacheLock,
LOCK_FOR_CACHE_USE);
2546 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
2548 AutoRecovery::TDocumentList::iterator pIt = AutoRecovery::impl_searchDocument(m_lDocCache, xDocument);
2549 if (pIt != m_lDocCache.end())
2556 implts_stopModifyListeningOnDoc(*pIt);
2562void AutoRecovery::implts_updateModifiedState(
const css::uno::Reference< css::frame::XModel >& xDocument)
2565 bool bModified =
true;
2566 css::uno::Reference< css::util::XModifiable > xModify(xDocument, css::uno::UNO_QUERY);
2568 bModified = xModify->isModified();
2570 CacheLockGuard aCacheLock(
this, cppu::WeakComponentImplHelperBase::rBHelper.rMutex, m_nDocCacheLock,
LOCK_FOR_CACHE_USE);
2573 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
2575 AutoRecovery::TDocumentList::iterator pIt = AutoRecovery::impl_searchDocument(m_lDocCache, xDocument);
2576 if (pIt != m_lDocCache.end())
2578 AutoRecovery::TDocumentInfo& rInfo = *pIt;
2582 rInfo.DocumentState |= DocState::Modified;
2586 rInfo.DocumentState &= ~DocState::Modified;
2593void AutoRecovery::implts_updateDocumentUsedForSavingState(
const css::uno::Reference< css::frame::XModel >& xDocument ,
2594 bool bSaveInProgress)
2596 CacheLockGuard aCacheLock(
this, cppu::WeakComponentImplHelperBase::rBHelper.rMutex, m_nDocCacheLock,
LOCK_FOR_CACHE_USE);
2599 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
2601 AutoRecovery::TDocumentList::iterator pIt = AutoRecovery::impl_searchDocument(m_lDocCache, xDocument);
2602 if (pIt == m_lDocCache.end())
2604 AutoRecovery::TDocumentInfo& rInfo = *pIt;
2605 rInfo.UsedForSaving = bSaveInProgress;
2610void AutoRecovery::implts_markDocumentAsSaved(
const css::uno::Reference< css::frame::XModel >& xDocument)
2612 CacheLockGuard aCacheLock(
this, cppu::WeakComponentImplHelperBase::rBHelper.rMutex, m_nDocCacheLock,
LOCK_FOR_CACHE_USE);
2614 AutoRecovery::TDocumentInfo aInfo;
2615 OUString sRemoveURL1;
2616 OUString sRemoveURL2;
2618 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
2620 AutoRecovery::TDocumentList::iterator pIt = AutoRecovery::impl_searchDocument(m_lDocCache, xDocument);
2621 if (pIt == m_lDocCache.end())
2631 aInfo.DocumentState = DocState::Unknown;
2633 css::uno::Reference< css::frame::XStorable > xDoc(aInfo.Document, css::uno::UNO_QUERY);
2634 aInfo.OrgURL = xDoc->getLocation();
2641 sRemoveURL1 = aInfo.OldTempURL;
2642 sRemoveURL2 = aInfo.NewTempURL;
2643 aInfo.OldTempURL.clear();
2644 aInfo.NewTempURL.clear();
2649 css::uno::Reference< css::frame::XTitle > xDocTitle(xDocument, css::uno::UNO_QUERY);
2650 if (xDocTitle.is ())
2651 aInfo.Title = xDocTitle->getTitle ();
2655 if (aInfo.Title.isEmpty())
2659 aInfo.UsedForSaving =
false;
2665 implts_flushConfigItem(aInfo);
2667 aCacheLock.unlock();
2669 AutoRecovery::st_impl_removeFile(sRemoveURL1);
2670 AutoRecovery::st_impl_removeFile(sRemoveURL2);
2673AutoRecovery::TDocumentList::iterator AutoRecovery::impl_searchDocument( AutoRecovery::TDocumentList& rList ,
2674 const css::uno::Reference< css::frame::XModel >& xDocument)
2676 return std::find_if(rList.begin(), rList.end(),
2677 [&xDocument](
const AutoRecovery::TDocumentInfo& rInfo) { return rInfo.Document == xDocument; });
2680void lcl_changeVisibility(
const css::uno::Reference< css::frame::XFramesSupplier >& i_rFrames,
bool i_bVisible )
2682 css::uno::Reference< css::container::XIndexAccess > xFramesContainer = i_rFrames->getFrames();
2683 const sal_Int32
count = xFramesContainer->getCount();
2686 for ( sal_Int32 i=0;
i <
count; ++
i )
2688 aElement = xFramesContainer->getByIndex(i);
2690 css::uno::Reference< css::frame::XFramesSupplier > xFramesSupp( aElement, css::uno::UNO_QUERY );
2691 if ( xFramesSupp.is() )
2692 lcl_changeVisibility( xFramesSupp, i_bVisible );
2694 css::uno::Reference< css::frame::XFrame >
xFrame( aElement, css::uno::UNO_QUERY );
2698 css::uno::Reference< css::awt::XWindow > xWindow(
xFrame->getContainerWindow(), UNO_SET_THROW );
2699 xWindow->setVisible( i_bVisible );
2703void AutoRecovery::implts_changeAllDocVisibility(
bool bVisible)
2705 css::uno::Reference< css::frame::XFramesSupplier > xDesktop = css::frame::Desktop::create(
m_xContext);
2706 lcl_changeVisibility( xDesktop,
bVisible );
2712void lc_removeLockFile(AutoRecovery::TDocumentInfo
const & rInfo)
2714#if !HAVE_FEATURE_MULTIUSER_ENVIRONMENT || HAVE_FEATURE_MACOSX_SANDBOX
2717 if ( !rInfo.Document.is() )
2722 css::uno::Reference< css::frame::XStorable > xStore(rInfo.Document, css::uno::UNO_QUERY_THROW);
2723 OUString
aURL = xStore->getLocation();
2724 if ( !
aURL.isEmpty() )
2727 aLockFile.RemoveFile();
2730 catch(
const css::uno::Exception& )
2736void AutoRecovery::implts_prepareSessionShutdown()
2738 SAL_INFO(
"fwk.autorecovery",
"AutoRecovery::implts_prepareSessionShutdown() starts ...");
2744 CacheLockGuard aCacheLock(
this, cppu::WeakComponentImplHelperBase::rBHelper.rMutex, m_nDocCacheLock,
LOCK_FOR_CACHE_USE);
2746 for (
auto & info : m_lDocCache)
2750 lc_removeLockFile( info );
2757 info.IgnoreClosing =
true;
2761 implts_stopModifyListeningOnDoc(info);
2766 if ((m_eJob & Job::SessionSave) != Job::SessionSave)
2768 css::uno::Reference< css::util::XModifiable > xModify(info.Document, css::uno::UNO_QUERY);
2770 xModify->setModified(
false);
2773 css::uno::Reference< css::util::XCloseable > xClose(info.Document, css::uno::UNO_QUERY);
2778 xClose->close(
false);
2780 catch(
const css::uno::Exception&)
2786 info.Document.clear();
2791 aCacheLock.unlock();
2811bool lc_checkIfSaveForbiddenByArguments(AutoRecovery::TDocumentInfo
const & rInfo)
2813 if (! rInfo.Document.is())
2822AutoRecovery::ETimerType AutoRecovery::implts_saveDocs(
bool bAllowUserIdleLoop,
2823 bool bRemoveLockFiles,
2824 const DispatchParams* pParams )
2826 css::uno::Reference< css::task::XStatusIndicator > xExternalProgress;
2828 xExternalProgress = pParams->m_xProgress;
2830 css::uno::Reference< css::frame::XDesktop2 > xDesktop = css::frame::Desktop::create(
m_xContext);
2833 css::uno::Reference< css::frame::XController > xActiveController;
2834 css::uno::Reference< css::frame::XModel > xActiveModel;
2835 css::uno::Reference< css::frame::XFrame > xActiveFrame = xDesktop->getActiveFrame();
2836 if (xActiveFrame.is())
2837 xActiveController = xActiveFrame->getController();
2838 if (xActiveController.is())
2839 xActiveModel = xActiveController->getModel();
2848 AutoRecovery::ETimerType eTimer = AutoRecovery::E_NORMAL_AUTOSAVE_INTERVALL;
2852 CacheLockGuard aCacheLock(
this, cppu::WeakComponentImplHelperBase::rBHelper.rMutex, m_nDocCacheLock,
LOCK_FOR_CACHE_USE);
2854 const sal_Int64 nConfiguredAutoSaveInterval
2855 = officecfg::Office::Recovery::AutoSave::TimeIntervall::get()
2859 osl::ResettableMutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
2865 ::std::vector< AutoRecovery::TDocumentList::iterator > lDangerousDocs;
2867 AutoRecovery::TDocumentList::iterator pIt;
2868 for ( pIt = m_lDocCache.begin();
2869 pIt != m_lDocCache.end();
2872 AutoRecovery::TDocumentInfo aInfo = *pIt;
2875 if ( bRemoveLockFiles )
2876 lc_removeLockFile( aInfo );
2879 if (lc_checkIfSaveForbiddenByArguments(aInfo))
2885 if ((aInfo.DocumentState & DocState::Handled) == DocState::Handled)
2890 Reference< XDocumentRecovery > xDocRecover( aInfo.Document, UNO_QUERY_THROW );
2891 if ( !xDocRecover->wasModifiedSinceLastSave() )
2893 aInfo.DocumentState |= DocState::Handled;
2897 if (
auto xDocRecovery2 = xDocRecover.query<XDocumentRecovery2>())
2899 const sal_Int64 nDirtyDuration = xDocRecovery2->getModifiedStateDuration();
2902 if (nDirtyDuration + 999 < nConfiguredAutoSaveInterval)
2904 aInfo.DocumentState |= DocState::Handled;
2928 if (aInfo.UsedForSaving)
2930 if ((eJob & Job::EmergencySave) == Job::EmergencySave)
2932 lDangerousDocs.push_back(pIt);
2936 if ((eJob & Job::SessionSave) == Job::SessionSave)
2941 if ((eJob & Job::AutoSave) == Job::AutoSave)
2943 eTimer = AutoRecovery::E_POLL_TILL_AUTOSAVE_IS_ALLOWED;
2944 aInfo.DocumentState |= DocState::Postponed;
2953 bool bActive = (xActiveModel == aInfo.Document);
2954 bool bWasPostponed = ((aInfo.DocumentState & DocState::Postponed) == DocState::Postponed);
2961 aInfo.DocumentState |= DocState::Postponed;
2966 eTimer = AutoRecovery::E_POLL_FOR_USER_IDLE;
2967 if (!bAllowUserIdleLoop)
2968 eTimer = AutoRecovery::E_CALL_ME_BACK;
2976 implts_saveOneDoc(sBackupPath, aInfo, xExternalProgress);
2977 implts_informListener(eJob, AutoRecovery::implst_createFeatureStateEvent(eJob, OPERATION_UPDATE, &aInfo));
2986 for (
auto const& dangerousDoc : lDangerousDocs)
2989 AutoRecovery::TDocumentInfo aInfo = *pIt;
2994 implts_saveOneDoc(sBackupPath, aInfo, xExternalProgress);
2995 implts_informListener(eJob, AutoRecovery::implst_createFeatureStateEvent(eJob, OPERATION_UPDATE, &aInfo));
3007void AutoRecovery::implts_saveOneDoc(
const OUString& sBackupPath ,
3008 AutoRecovery::TDocumentInfo& rInfo ,
3009 const css::uno::Reference< css::task::XStatusIndicator >& xExternalProgress)
3016 if (!rInfo.Document.is())
3020 implts_generateNewTempURL(sBackupPath, lOldArgs, rInfo);
3025 css::uno::Sequence< css::beans::NamedValue > aEncryptionData =
3027 css::uno::Sequence< css::beans::NamedValue >());
3028 if (aEncryptionData.hasElements())
3033 if (!rInfo.DefaultFilter.isEmpty())
3037 if (xExternalProgress.is())
3039 impl_establishProgress(rInfo, lNewArgs, css::uno::Reference< css::frame::XFrame >());
3050 Reference< XDocumentRecovery > xDocRecover(rInfo.Document, css::uno::UNO_QUERY_THROW);
3054 rInfo.DocumentState |= DocState::TrySave;
3055 implts_flushConfigItem(rInfo);
3064 if ((m_eJob & Job::UserAutoSave) == Job::UserAutoSave && !rInfo.OrgURL.isEmpty())
3066 Reference< XStorable > xDocSave(rInfo.Document, css::uno::UNO_QUERY_THROW);
3070 catch(
const css::uno::Exception&)
3074 sal_Int32 nRetry = RETRY_STORE_ON_FULL_DISC_FOREVER;
3075 bool bError =
false;
3080 xDocRecover->storeToRecoveryFile( rInfo.NewTempURL, lNewArgs.getAsConstPropertyValueList() );
3082#ifdef TRIGGER_FULL_DISC_CHECK
3083 throw css::uno::Exception(
"trigger full disk check");
3090 catch(
const css::uno::Exception& rException)
3095 if ( rException.Message.startsWith(
"SfxBaseModel::impl_store") )
3097 const css::task::ErrorCodeIOException& pErrorCodeIOException =
3098 static_cast<const css::task::ErrorCodeIOException&
>(rException);
3111 sal_Int32 nMinSpaceDocSave;
3113 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
3114 nMinSpaceDocSave = m_nMinSpaceDocSave;
3117 if (! impl_enoughDiscSpace(nMinSpaceDocSave))
3118 AutoRecovery::impl_showFullDiscError();
3119 else if (nRetry > RETRY_STORE_ON_MIGHT_FULL_DISC_USEFULL)
3120 nRetry = RETRY_STORE_ON_MIGHT_FULL_DISC_USEFULL;
3121 else if (nRetry <= GIVE_UP_RETRY)
3125 AutoRecovery::st_impl_removeFile(rInfo.NewTempURL);
3139 rInfo.DocumentState &= ~DocState::TrySave;
3140 rInfo.DocumentState |= DocState::Handled;
3141 rInfo.DocumentState |= DocState::Succeeded;
3146 rInfo.NewTempURL.clear();
3147 rInfo.DocumentState &= ~DocState::TrySave;
3148 rInfo.DocumentState |= DocState::Handled;
3149 rInfo.DocumentState |= DocState::Incomplete;
3153 impl_forgetProgress(rInfo, lNewArgs, css::uno::Reference< css::frame::XFrame >());
3158 OUString sRemoveFile = rInfo.OldTempURL;
3159 rInfo.OldTempURL = rInfo.NewTempURL;
3160 rInfo.NewTempURL.clear();
3162 implts_flushConfigItem(rInfo);
3165 implts_startModifyListeningOnDoc(rInfo);
3167 AutoRecovery::st_impl_removeFile(sRemoveFile);
3170AutoRecovery::ETimerType AutoRecovery::implts_openDocs(
const DispatchParams& aParams)
3172 AutoRecovery::ETimerType eTimer = AutoRecovery::E_DONT_START_TIMER;
3174 CacheLockGuard aCacheLock(
this, cppu::WeakComponentImplHelperBase::rBHelper.rMutex, m_nDocCacheLock,
LOCK_FOR_CACHE_USE);
3177 osl::ResettableMutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
3180 for (
auto & info : m_lDocCache)
3185 if ((info.DocumentState & DocState::Handled) == DocState::Handled)
3189 if ((info.DocumentState & DocState::Damaged) == DocState::Damaged)
3198 implts_informListener(eJob,
3199 AutoRecovery::implst_createFeatureStateEvent(eJob, OPERATION_UPDATE, &info));
3214 if (aParams.m_xProgress.is())
3217 bool bBackupWasTried = (
3218 ((info.DocumentState & DocState::TryLoadBackup ) == DocState::TryLoadBackup) ||
3219 ((info.DocumentState & DocState::Incomplete ) == DocState::Incomplete )
3221 bool bOriginalWasTried = ((info.DocumentState & DocState::TryLoadOriginal) == DocState::TryLoadOriginal);
3223 if (bBackupWasTried)
3225 if (!bOriginalWasTried)
3227 info.DocumentState |= DocState::Incomplete;
3232 info.DocumentState |= DocState::Damaged;
3237 OUString sLoadOriginalURL;
3238 OUString sLoadBackupURL;
3240 if (!bBackupWasTried)
3241 sLoadBackupURL = info.OldTempURL;
3243 if (!info.OrgURL.isEmpty())
3245 sLoadOriginalURL = info.OrgURL;
3247 else if (!info.TemplateURL.isEmpty())
3249 sLoadOriginalURL = info.TemplateURL;
3253 else if (!info.FactoryURL.isEmpty())
3255 sLoadOriginalURL = info.FactoryURL;
3262 if (!sLoadBackupURL.isEmpty())
3264 sURL = sLoadBackupURL;
3265 info.DocumentState |= DocState::TryLoadBackup;
3268 else if (!sLoadOriginalURL.isEmpty())
3270 sURL = sLoadOriginalURL;
3271 info.DocumentState |= DocState::TryLoadOriginal;
3276 LoadEnv::initializeUIDefaults(
m_xContext, lDescriptor,
true,
nullptr );
3281 implts_flushConfigItem(info);
3282 implts_informListener(eJob,
3283 AutoRecovery::implst_createFeatureStateEvent(eJob, OPERATION_UPDATE, &info));
3287 implts_openOneDoc(sURL, lDescriptor, info);
3289 catch(
const css::uno::Exception&)
3291 info.DocumentState &= ~DocState::TryLoadBackup;
3292 info.DocumentState &= ~DocState::TryLoadOriginal;
3293 if (!sLoadBackupURL.isEmpty())
3295 info.DocumentState |= DocState::Incomplete;
3296 eTimer = AutoRecovery::E_CALL_ME_BACK;
3300 info.DocumentState |= DocState::Handled;
3301 info.DocumentState |= DocState::Damaged;
3304 implts_flushConfigItem(info,
true);
3305 implts_informListener(eJob,
3306 AutoRecovery::implst_createFeatureStateEvent(eJob, OPERATION_UPDATE, &info));
3314 if (!info.RealFilter.isEmpty())
3318 info.Document->attachResource(info.Document->getURL(), lPatchDescriptor.getAsConstPropertyValueList());
3324 css::uno::Reference< css::util::XModifiable > xModify(info.Document, css::uno::UNO_QUERY);
3327 bool bModified = ((info.DocumentState & DocState::Modified) == DocState::Modified);
3328 xModify->setModified(bModified);
3331 info.DocumentState &= ~DocState::TryLoadBackup;
3332 info.DocumentState &= ~DocState::TryLoadOriginal;
3333 info.DocumentState |= DocState::Handled;
3334 info.DocumentState |= DocState::Succeeded;
3336 implts_flushConfigItem(info);
3337 implts_informListener(eJob,
3338 AutoRecovery::implst_createFeatureStateEvent(eJob, OPERATION_UPDATE, &info));
3347 implts_startModifyListeningOnDoc(info);
3359void AutoRecovery::implts_openOneDoc(
const OUString& sURL ,
3361 AutoRecovery::TDocumentInfo& rInfo )
3363 css::uno::Reference< css::frame::XDesktop2 > xDesktop = css::frame::Desktop::create(
m_xContext);
3365 ::std::vector< Reference< XComponent > > aCleanup;
3369 Reference< XModel2 >
xModel(
m_xContext->getServiceManager()->createInstanceWithContext(
3370 rInfo.FactoryService,
m_xContext), UNO_QUERY_THROW);
3371 aCleanup.emplace_back(
xModel.get() );
3375 if ( (rInfo.DocumentState & DocState::TryLoadOriginal) == DocState::TryLoadOriginal)
3380 if ( sURL == rInfo.FactoryURL )
3383 ENSURE_OR_THROW( ( rInfo.DocumentState & DocState::Modified ) == DocState(0),
3384 "unexpected document state" );
3385 Reference< XLoadable > xModelLoad( xModel, UNO_QUERY_THROW );
3386 xModelLoad->initNew();
3389 xModel->attachResource( sURL, lDescriptor.getAsConstPropertyValueList() );
3393 OUString sFilterName;
3395 if (!sFilterName.isEmpty()
3396 && ( sFilterName ==
"Calc MS Excel 2007 XML"
3397 || sFilterName ==
"Impress MS PowerPoint 2007 XML"
3398 || sFilterName ==
"MS Word 2007 XML"))
3407 Reference< css::document::XExtendedFilterDetection > xDetection(
3408 m_xContext->getServiceManager()->createInstanceWithContext(
3409 "com.sun.star.comp.oox.FormatDetector",
m_xContext),
3412 Sequence< css::beans::PropertyValue > aDescriptorSeq = lDescriptor.getAsConstPropertyValueList();
3413 OUString
sType = xDetection->detect(aDescriptorSeq);
3415 OUString sNewFilterName;
3417 if (!
sType.isEmpty() && sNewFilterName == sFilterName)
3420 lDescriptor = aDescriptorSeq;
3425 Reference< XDocumentRecovery > xDocRecover( xModel, UNO_QUERY_THROW );
3426 xDocRecover->recoverFromFile(
3429 lDescriptor.getAsConstPropertyValueList()
3437 ::std::vector< OUString > aViewsToRestore( std::cbegin(rInfo.ViewNames), std::cend(rInfo.ViewNames) );
3439 if ( aViewsToRestore.empty() )
3440 aViewsToRestore.emplace_back( );
3442 for (
auto const& viewToRestore : aViewsToRestore)
3446 aCleanup.emplace_back(xTargetFrame.get() );
3450 if ( viewToRestore.getLength() )
3452 xController.set(
xModel->createViewController( viewToRestore, Sequence< css::beans::PropertyValue >(), xTargetFrame ), UNO_SET_THROW );
3456 xController.set(
xModel->createDefaultViewController( xTargetFrame ), UNO_SET_THROW );
3463 rInfo.Document =
xModel.get();
3465 catch(
const css::uno::RuntimeException&)
3469 catch(
const css::uno::Exception&)
3471 Any aCaughtException( ::cppu::getCaughtException() );
3474 for (
auto const& component : aCleanup)
3476 css::uno::Reference< css::util::XCloseable > xClose(component, css::uno::UNO_QUERY);
3478 xClose->close(
true );
3480 component->dispose();
3484 throw css::lang::WrappedTargetException(
3485 "Recovery of \"" + sURL +
"\" failed.",
3486 static_cast< css::frame::XDispatch*
>(
this),
3492void AutoRecovery::implts_generateNewTempURL(
const OUString& sBackupPath ,
3494 AutoRecovery::TDocumentInfo& rInfo )
3504 OUStringBuffer sUniqueName;
3505 if (!rInfo.OrgURL.isEmpty())
3507 css::uno::Reference< css::util::XURLTransformer > xParser(css::util::URLTransformer::create(
m_xContext));
3508 css::util::URL
aURL;
3509 aURL.Complete = rInfo.OrgURL;
3510 xParser->parseStrict(aURL);
3511 sUniqueName.append(
aURL.Name);
3513 else if (!rInfo.FactoryURL.isEmpty())
3514 sUniqueName.append(
"untitled");
3515 sUniqueName.append(
"_");
3519 rInfo.NewTempURL = ::utl::CreateTempURL(sUniqueName,
true, rInfo.Extension, &sBackupPath,
true);
3522void AutoRecovery::implts_informListener(
Job eJob ,
3523 const css::frame::FeatureStateEvent& aEvent)
3527 OUString sJob = AutoRecovery::implst_getJobDescription(eJob);
3530 pListenerForURL = m_lListener.getContainer(sJob);
3531 if(pListenerForURL ==
nullptr)
3535 while(pIt.hasMoreElements())
3539 pIt.next()->statusChanged(aEvent);
3541 catch(
const css::uno::RuntimeException&)
3548OUString AutoRecovery::implst_getJobDescription(
Job eJob)
3551 OUStringBuffer sFeature(256);
3552 sFeature.append(CMD_PROTOCOL);
3560 if ((eJob & Job::PrepareEmergencySave) == Job::PrepareEmergencySave)
3561 sFeature.append(CMD_DO_PREPARE_EMERGENCY_SAVE);
3562 else if ((eJob & Job::EmergencySave) == Job::EmergencySave)
3563 sFeature.append(CMD_DO_EMERGENCY_SAVE);
3564 else if ((eJob & Job::Recovery) == Job::Recovery)
3565 sFeature.append(CMD_DO_RECOVERY);
3566 else if ((eJob & Job::SessionSave) == Job::SessionSave)
3567 sFeature.append(CMD_DO_SESSION_SAVE);
3568 else if ((eJob & Job::SessionQuietQuit) == Job::SessionQuietQuit)
3569 sFeature.append(CMD_DO_SESSION_QUIET_QUIT);
3570 else if ((eJob & Job::SessionRestore) == Job::SessionRestore)
3571 sFeature.append(CMD_DO_SESSION_RESTORE);
3572 else if ((eJob & Job::EntryBackup) == Job::EntryBackup)
3573 sFeature.append(CMD_DO_ENTRY_BACKUP);
3574 else if ((eJob & Job::EntryCleanup) == Job::EntryCleanup)
3575 sFeature.append(CMD_DO_ENTRY_CLEANUP);
3576 else if ((eJob & Job::AutoSave) == Job::AutoSave)
3577 sFeature.append(CMD_DO_AUTO_SAVE);
3578 else if ( eJob != Job::NoJob )
3579 SAL_INFO(
"fwk.autorecovery",
"AutoRecovery::implst_getJobDescription(): Invalid job identifier detected.");
3581 return sFeature.makeStringAndClear();
3584Job AutoRecovery::implst_classifyJob(
const css::util::URL& aURL)
3586 if (
aURL.Protocol == CMD_PROTOCOL )
3588 if (
aURL.Path == CMD_DO_PREPARE_EMERGENCY_SAVE )
3589 return Job::PrepareEmergencySave;
3590 else if (
aURL.Path == CMD_DO_EMERGENCY_SAVE )
3591 return Job::EmergencySave;
3592 else if (
aURL.Path == CMD_DO_RECOVERY )
3593 return Job::Recovery;
3594 else if (
aURL.Path == CMD_DO_ENTRY_BACKUP )
3595 return Job::EntryBackup;
3596 else if (
aURL.Path == CMD_DO_ENTRY_CLEANUP )
3597 return Job::EntryCleanup;
3598 else if (
aURL.Path == CMD_DO_SESSION_SAVE )
3599 return Job::SessionSave;
3600 else if (
aURL.Path == CMD_DO_SESSION_QUIET_QUIT )
3601 return Job::SessionQuietQuit;
3602 else if (
aURL.Path == CMD_DO_SESSION_RESTORE )
3603 return Job::SessionRestore;
3604 else if (
aURL.Path == CMD_DO_DISABLE_RECOVERY )
3605 return Job::DisableAutorecovery;
3606 else if (
aURL.Path == CMD_DO_SET_AUTOSAVE_STATE )
3607 return Job::SetAutosaveState;
3610 SAL_INFO(
"fwk.autorecovery",
"AutoRecovery::implts_classifyJob(): Invalid URL (protocol).");
3614css::frame::FeatureStateEvent AutoRecovery::implst_createFeatureStateEvent(
Job eJob ,
3615 const OUString& sEventType,
3616 AutoRecovery::TDocumentInfo
const * pInfo )
3618 css::frame::FeatureStateEvent
aEvent;
3619 aEvent.FeatureURL.Complete = AutoRecovery::implst_getJobDescription(eJob);
3622 if (pInfo && sEventType == OPERATION_UPDATE)
3626 aInfo.
put( CFG_ENTRY_PROP_ID, pInfo->ID );
3627 aInfo.
put( CFG_ENTRY_PROP_ORIGINALURL, pInfo->OrgURL );
3628 aInfo.
put( CFG_ENTRY_PROP_FACTORYURL, pInfo->FactoryURL );
3629 aInfo.
put( CFG_ENTRY_PROP_TEMPLATEURL, pInfo->TemplateURL );
3630 aInfo.
put( CFG_ENTRY_PROP_TEMPURL, pInfo->OldTempURL.isEmpty() ? pInfo->NewTempURL : pInfo->OldTempURL );
3631 aInfo.
put( CFG_ENTRY_PROP_MODULE, pInfo->AppModule);
3632 aInfo.
put( CFG_ENTRY_PROP_TITLE, pInfo->Title);
3633 aInfo.
put( CFG_ENTRY_PROP_VIEWNAMES, pInfo->ViewNames);
3634 aInfo.
put( CFG_ENTRY_PROP_DOCUMENTSTATE, sal_Int32(pInfo->DocumentState));
3642void AutoRecovery::implts_resetHandleStates()
3644 CacheLockGuard aCacheLock(
this, cppu::WeakComponentImplHelperBase::rBHelper.rMutex, m_nDocCacheLock,
LOCK_FOR_CACHE_USE);
3647 osl::ResettableMutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
3649 for (
auto & info : m_lDocCache)
3651 info.DocumentState &= ~DocState::Handled;
3652 info.DocumentState &= ~DocState::Postponed;
3656 implts_flushConfigItem(info);
3663void AutoRecovery::implts_prepareEmergencySave()
3666 implts_verifyCacheAgainstDesktopDocumentList();
3669 implts_changeAllDocVisibility(
false);
3672void AutoRecovery::implts_doEmergencySave(
const DispatchParams& aParams)
3678 std::shared_ptr<comphelper::ConfigurationChanges> batch(
3680 officecfg::Office::Recovery::RecoveryInfo::Crashed::set(
true, batch);
3684 implts_persistAllActiveViewNames();
3694 bool const bAllowUserIdleLoop =
false;
3695 AutoRecovery::ETimerType eSuggestedTimer = AutoRecovery::E_DONT_START_TIMER;
3698 eSuggestedTimer = implts_saveDocs(bAllowUserIdleLoop,
true, &aParams);
3700 while(eSuggestedTimer == AutoRecovery::E_CALL_ME_BACK);
3707 implts_resetHandleStates();
3710 impl_flushALLConfigChanges();
3715 AutoRecovery::st_impl_removeLockFile();
3718void AutoRecovery::implts_doRecovery(
const DispatchParams& aParams)
3720 AutoRecovery::ETimerType eSuggestedTimer = AutoRecovery::E_DONT_START_TIMER;
3723 eSuggestedTimer = implts_openDocs(aParams);
3725 while(eSuggestedTimer == AutoRecovery::E_CALL_ME_BACK);
3732 implts_resetHandleStates();
3735 std::shared_ptr<comphelper::ConfigurationChanges> batch(
3737 officecfg::Office::Recovery::RecoveryInfo::Crashed::set(
false, batch);
3741void AutoRecovery::implts_doSessionSave(
const DispatchParams& aParams)
3743 SAL_INFO(
"fwk.autorecovery",
"AutoRecovery::implts_doSessionSave()");
3746 implts_verifyCacheAgainstDesktopDocumentList();
3749 implts_persistAllActiveViewNames();
3759 bool const bAllowUserIdleLoop =
false;
3760 AutoRecovery::ETimerType eSuggestedTimer = AutoRecovery::E_DONT_START_TIMER;
3764 eSuggestedTimer = implts_saveDocs(bAllowUserIdleLoop,
false, &aParams);
3766 while(eSuggestedTimer == AutoRecovery::E_CALL_ME_BACK);
3773 implts_resetHandleStates();
3776 impl_flushALLConfigChanges();
3779void AutoRecovery::implts_doSessionQuietQuit()
3781 SAL_INFO(
"fwk.autorecovery",
"AutoRecovery::implts_doSessionQuietQuit()");
3789 AutoRecovery::st_impl_removeLockFile();
3793 implts_prepareSessionShutdown();
3797 std::shared_ptr<comphelper::ConfigurationChanges> batch(
3799 officecfg::Office::Recovery::RecoveryInfo::SessionData::set(
true, batch);
3803 impl_flushALLConfigChanges();
3806void AutoRecovery::implts_doSessionRestore(
const DispatchParams& aParams)
3808 SAL_INFO(
"fwk.autorecovery",
"AutoRecovery::implts_doSessionRestore() ...");
3810 AutoRecovery::ETimerType eSuggestedTimer = AutoRecovery::E_DONT_START_TIMER;
3813 eSuggestedTimer = implts_openDocs(aParams);
3815 while(eSuggestedTimer == AutoRecovery::E_CALL_ME_BACK);
3822 implts_resetHandleStates();
3825 implts_changeAllDocVisibility(
true);
3828 SAL_INFO(
"fwk.autorecovery",
"... reset config key 'SessionData'");
3829 std::shared_ptr<comphelper::ConfigurationChanges> batch(
3831 officecfg::Office::Recovery::RecoveryInfo::SessionData::set(
false, batch);
3834 SAL_INFO(
"fwk.autorecovery",
"... AutoRecovery::implts_doSessionRestore()");
3837void AutoRecovery::implts_backupWorkingEntry(
const DispatchParams& aParams)
3839 CacheLockGuard aCacheLock(
this, cppu::WeakComponentImplHelperBase::rBHelper.rMutex, m_nDocCacheLock,
LOCK_FOR_CACHE_USE);
3841 for (
auto const& info : m_lDocCache)
3843 if (info.ID != aParams.m_nWorkingEntryID)
3846 OUString sSourceURL;
3848 if (!info.OldTempURL.isEmpty())
3849 sSourceURL = info.OldTempURL;
3850 else if (!info.NewTempURL.isEmpty())
3851 sSourceURL = info.NewTempURL;
3852 else if (!info.OrgURL.isEmpty())
3853 sSourceURL = info.OrgURL;
3859 implts_copyFile(sSourceURL, aParams.m_sSavePath, aParser.getName());
3869void AutoRecovery::implts_cleanUpWorkingEntry(
const DispatchParams& aParams)
3871 CacheLockGuard aCacheLock(
this, cppu::WeakComponentImplHelperBase::rBHelper.rMutex, m_nDocCacheLock,
LOCK_FOR_CACHE_ADD_REMOVE);
3873 AutoRecovery::TDocumentList::iterator pIt = std::find_if(m_lDocCache.begin(), m_lDocCache.end(),
3874 [&aParams](
const AutoRecovery::TDocumentInfo& rInfo) { return rInfo.ID == aParams.m_nWorkingEntryID; });
3875 if (pIt != m_lDocCache.end())
3877 AutoRecovery::TDocumentInfo& rInfo = *pIt;
3878 AutoRecovery::st_impl_removeFile(rInfo.OldTempURL);
3879 AutoRecovery::st_impl_removeFile(rInfo.NewTempURL);
3880 implts_flushConfigItem(rInfo,
true);
3882 m_lDocCache.erase(pIt);
3886AutoRecovery::EFailureSafeResult AutoRecovery::implts_copyFile(
const OUString& sSource ,
3887 const OUString& sTargetPath,
3888 const OUString& sTargetName)
3893 css::uno::Reference< css::ucb::XCommandEnvironment > xEnvironment;
3902 catch(
const css::uno::Exception&)
3904 return AutoRecovery::E_WRONG_TARGET_PATH;
3907 sal_Int32 nNameClash;
3908 nNameClash = css::ucb::NameClash::RENAME;
3914 return AutoRecovery::E_ORIGINAL_FILE_MISSING;
3917 catch(
const css::uno::Exception&)
3919 return AutoRecovery::E_ORIGINAL_FILE_MISSING;
3922 return AutoRecovery::E_COPIED;
3925sal_Bool SAL_CALL AutoRecovery::convertFastPropertyValue( css::uno::Any& ,
3928 const css::uno::Any& )
3934void SAL_CALL AutoRecovery::setFastPropertyValue_NoBroadcast( sal_Int32 ,
3935 const css::uno::Any& )
3940void SAL_CALL AutoRecovery::getFastPropertyValue(css::uno::Any& aValue ,
3941 sal_Int32 nHandle)
const
3947 bool bSessionData = officecfg::Office::Recovery::RecoveryInfo::SessionData::get();
3948 bool bRecoveryData = !m_lDocCache.empty();
3953 bRecoveryData =
false;
3955 aValue <<= bRecoveryData;
3960 aValue <<= officecfg::Office::Recovery::RecoveryInfo::Crashed::get();
3964 aValue <<= officecfg::Office::Recovery::RecoveryInfo::SessionData::get();
3969css::uno::Sequence< css::beans::Property > impl_getStaticPropertyDescriptor()
3981 static ::cppu::OPropertyArrayHelper ourInfoHelper(impl_getStaticPropertyDescriptor(),
true);
3983 return ourInfoHelper;
3986css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL AutoRecovery::getPropertySetInfo()
3988 static css::uno::Reference< css::beans::XPropertySetInfo > xInfo(
3994void AutoRecovery::implts_verifyCacheAgainstDesktopDocumentList()
3996 SAL_INFO(
"fwk.autorecovery",
"AutoRecovery::implts_verifyCacheAgainstDesktopDocumentList() ...");
3999 css::uno::Reference< css::frame::XDesktop2 > xDesktop = css::frame::Desktop::create(
m_xContext);
4001 css::uno::Reference< css::container::XIndexAccess > xContainer(
4002 xDesktop->getFrames(),
4003 css::uno::UNO_QUERY_THROW);
4006 sal_Int32 c = xContainer->getCount();
4010 css::uno::Reference< css::frame::XFrame >
xFrame;
4013 xContainer->getByIndex(i) >>=
xFrame;
4019 catch(
const css::lang::IndexOutOfBoundsException&)
4026 css::uno::Reference< css::awt::XWindow2 > xVisibleCheck(
4027 xFrame->getContainerWindow(),
4028 css::uno::UNO_QUERY);
4030 (!xVisibleCheck.is() ) ||
4031 (!xVisibleCheck->isVisible())
4039 css::uno::Reference< css::frame::XController >
xController;
4040 css::uno::Reference< css::frame::XModel3 >
xModel;
4052 implts_registerDocument(xModel);
4055 catch(
const css::uno::RuntimeException&)
4059 catch(
const css::uno::Exception&)
4063 SAL_INFO(
"fwk.autorecovery",
"... AutoRecovery::implts_verifyCacheAgainstDesktopDocumentList()");
4066bool AutoRecovery::impl_enoughDiscSpace(sal_Int32 nRequiredSpace)
4068#ifdef SIMULATE_FULL_DISC
4078 ::osl::VolumeInfo aInfo (osl_VolumeInfo_Mask_FreeSpace);
4079 ::osl::FileBase::RC aRC = ::osl::Directory::getVolumeInfo(sBackupPath, aInfo);
4082 (aInfo.isValid(osl_VolumeInfo_Mask_FreeSpace)) &&
4083 (aRC == ::osl::FileBase::E_None )
4086 nFreeSpace = aInfo.getFreeSpace();
4089 sal_uInt64 nFreeMB = nFreeSpace/1048576;
4094void AutoRecovery::impl_showFullDiscError()
4096 OUString sBtn(
FwkResId(STR_FULL_DISC_RETRY_BUTTON));
4097 OUString sMsg(
FwkResId(STR_FULL_DISC_MSG));
4102 OUString sBackupPath = aConverter.getFSysPath(FSysStyle::Detect, &aDelimiter);
4103 if (sBackupPath.getLength() < 1)
4104 sBackupPath = sBackupURL;
4107 VclMessageType::Error, VclButtonsType::NONE,
4108 sMsg.replaceAll(
"%PATH", sBackupPath)));
4109 xBox->add_button(sBtn, RET_OK);
4113void AutoRecovery::impl_establishProgress(
const AutoRecovery::TDocumentInfo& rInfo ,
4115 const css::uno::Reference< css::frame::XFrame >& xNewFrame)
4122 css::uno::Reference< css::frame::XFrame >
xFrame = xNewFrame;
4125 (rInfo.Document.is())
4128 css::uno::Reference< css::frame::XController >
xController = rInfo.Document->getCurrentController();
4135 css::uno::Reference< css::task::XStatusIndicator > xInternalProgress;
4136 css::uno::Reference< css::task::XStatusIndicator > xExternalProgress = rArgs.getUnpackedValueOrDefault(
4138 css::uno::Reference< css::task::XStatusIndicator >() );
4144 (! xExternalProgress.is()) &&
4148 css::uno::Reference< css::task::XStatusIndicatorFactory > xProgressFactory(xFrame, css::uno::UNO_QUERY);
4149 if (xProgressFactory.is())
4150 xInternalProgress = xProgressFactory->createStatusIndicator();
4164 (xExternalProgress.is()) &&
4168 css::uno::Reference< css::beans::XPropertySet > xFrameProps(xFrame, css::uno::UNO_QUERY);
4169 if (xFrameProps.is())
4178void AutoRecovery::impl_forgetProgress(
const AutoRecovery::TDocumentInfo& rInfo ,
4180 const css::uno::Reference< css::frame::XFrame >& xNewFrame)
4187 css::uno::Reference< css::frame::XFrame >
xFrame = xNewFrame;
4190 (rInfo.Document.is())
4193 css::uno::Reference< css::frame::XController >
xController = rInfo.Document->getCurrentController();
4199 css::uno::Reference< css::beans::XPropertySet > xFrameProps(xFrame, css::uno::UNO_QUERY);
4200 if (xFrameProps.is())
4205 if (pArg != rArgs.end())
4212void AutoRecovery::impl_flushALLConfigChanges()
4220 catch(
const css::uno::Exception&)
4225void AutoRecovery::st_impl_removeFile(
const OUString& sURL)
4227 if ( sURL.isEmpty())
4233 aContent.executeCommand(
"delete", css::uno::Any(
true));
4235 catch(
const css::uno::Exception&)
4240void AutoRecovery::st_impl_removeLockFile()
4247 OUString sLockURL = sUserURL +
"/.lock";
4248 AutoRecovery::st_impl_removeFile(sLockURL);
4250 catch(
const css::uno::Exception&)
4257extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
4259 css::uno::XComponentContext *context,
4260 css::uno::Sequence<css::uno::Any>
const &)
4264 xAutoRecovery->initListeners();
4266 return cppu::acquire(xAutoRecovery.get());
#define LOCK_FOR_CACHE_ADD_REMOVE
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_framework_AutoRecovery_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
#define MIN_TIME_FOR_USER_IDLE
#define LOCK_FOR_CACHE_USE
static bool IsUICaptured()
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, const ILibreOfficeKitNotifier *pNotifier=nullptr)
static sal_uInt64 GetLastInputInterval()
static std::shared_ptr< ConfigurationChanges > create()
bool put(const OUString &_rValueName, const VALUE_TYPE &_rValue)
css::uno::Sequence< css::beans::PropertyValue > getPropertyValues() const
static css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL createPropertySetInfo(IPropertyArrayHelper &rProperties)
virtual css::uno::Any SAL_CALL getFastPropertyValue(sal_Int32 nHandle) SAL_OVERRIDE
virtual IPropertyArrayHelper &SAL_CALL getInfoHelper()=0
virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const css::uno::Any &rValue)=0
void SAL_CALL disposing()
virtual sal_Bool SAL_CALL convertFastPropertyValue(css::uno::Any &rConvertedValue, css::uno::Any &rOldValue, sal_Int32 nHandle, const css::uno::Any &rValue)=0
css::uno::Sequence< css::uno::Type > getTypes()
virtual void SAL_CALL acquire() SAL_NOEXCEPT SAL_OVERRIDE
virtual void SAL_CALL release() SAL_NOEXCEPT SAL_OVERRIDE
it represent a job; execute it and control its lifetime
void transferContent(const Content &rSourceContent, InsertOperation eOperation, const OUString &rTitle, const sal_Int32 nNameClashAction, const OUString &rMimeType=OUString(), bool bMajorVersion=false, const OUString &rCommentVersion=OUString(), OUString *pResultURL=nullptr, const OUString &rDocumentId=OUString()) const
static bool create(const OUString &rURL, const css::uno::Reference< css::ucb::XCommandEnvironment > &rEnv, const css::uno::Reference< css::uno::XComponentContext > &rCtx, Content &rContent)
static PathStatus locateUserInstallation(OUString &_rURL)
static void storeConfigItems()
#define ENSURE_OR_THROW(c, m)
#define ENSURE_OR_THROW2(c, m, ifc)
constexpr OUStringLiteral PROP_SAVEPATH
OUString FwkResId(TranslateId aId)
css::uno::Reference< css::uno::XComponentContext > m_xContext
#define LINK(Instance, Class, Member)
#define SAL_WARN_IF(condition, area, stream)
#define SAL_INFO(area, stream)
css::uno::Sequence< T > concatSequences(const css::uno::Sequence< T > &rS1, const Ss &... rSn)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
std::shared_ptr< osl::Mutex > const & lock()
css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType, Interface1 *p1)
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
constexpr OUStringLiteral FRAME_PROPNAME_ASCII_INDICATORINTERCEPTION
constexpr OUStringLiteral SPECIALTARGET_BLANK
IMPL_LINK_NOARG(CloseDispatcher, impl_asyncCallback, LinkParamNone *, void)
asynchronous callback @descr We start all actions inside this object asynchronous (see comments there...
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
void ConnectFrameControllerModel(const css::uno::Reference< css::frame::XFrame > &xFrame, const css::uno::Reference< css::frame::XController2 > &xController, const css::uno::Reference< css::frame::XModel > &xModel)
#define AUTORECOVERY_PROPHANDLE_EXISTS_RECOVERYDATA
#define AUTORECOVERY_PROPNAME_EXISTS_RECOVERYDATA
#define AUTORECOVERY_PROPNAME_CRASHED
#define AUTORECOVERY_PROPHANDLE_CRASHED
#define AUTORECOVERY_PROPNAME_EXISTS_SESSIONDATA
#define AUTORECOVERY_PROPHANDLE_EXISTS_SESSIONDATA
#define ERRCODE_SFX_WRONGPASSWORD
Reference< XController > xController
Reference< XFrame > xFrame
Reference< XModel > xModel
constexpr OUStringLiteral sEventType