/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #ifndef INCLUDED_SVX_SOURCE_INC_DOCRECOVERY_HXX #define INCLUDED_SVX_SOURCE_INC_DOCRECOVERY_HXX #include #include #include #include #include #include #include #include #define RECOVERY_CMDPART_PROTOCOL "vnd.sun.star.autorecovery:" #define RECOVERY_CMDPART_DO_EMERGENCY_SAVE "/doEmergencySave" #define RECOVERY_CMDPART_DO_RECOVERY "/doAutoRecovery" #define RECOVERY_CMDPART_DO_BRINGTOFRONT "/doBringToFront" inline constexpr OUString RECOVERY_CMD_DO_PREPARE_EMERGENCY_SAVE = u"vnd.sun.star.autorecovery:/doPrepareEmergencySave"_ustr; inline constexpr OUString RECOVERY_CMD_DO_EMERGENCY_SAVE = u"vnd.sun.star.autorecovery:/doEmergencySave"_ustr; inline constexpr OUString RECOVERY_CMD_DO_RECOVERY = u"vnd.sun.star.autorecovery:/doAutoRecovery"_ustr; inline constexpr OUString RECOVERY_CMD_DO_ENTRY_BACKUP = u"vnd.sun.star.autorecovery:/doEntryBackup"_ustr; inline constexpr OUString RECOVERY_CMD_DO_ENTRY_CLEANUP = u"vnd.sun.star.autorecovery:/doEntryCleanUp"_ustr; inline constexpr OUString PROP_STATUSINDICATOR = u"StatusIndicator"_ustr; inline constexpr OUString PROP_DISPATCHASYNCHRON = u"DispatchAsynchron"_ustr; inline constexpr OUString PROP_SAVEPATH = u"SavePath"_ustr; inline constexpr OUString PROP_ENTRYID = u"EntryID"_ustr; inline constexpr OUString STATEPROP_ID = u"ID"_ustr; inline constexpr OUString STATEPROP_STATE = u"DocumentState"_ustr; inline constexpr OUString STATEPROP_ORGURL = u"OriginalURL"_ustr; inline constexpr OUString STATEPROP_TEMPURL = u"TempURL"_ustr; inline constexpr OUString STATEPROP_FACTORYURL = u"FactoryURL"_ustr; inline constexpr OUString STATEPROP_TEMPLATEURL = u"TemplateURL"_ustr; inline constexpr OUString STATEPROP_TITLE = u"Title"_ustr; inline constexpr OUString STATEPROP_MODULE = u"Module"_ustr; #define RECOVERY_OPERATIONSTATE_START "start" #define RECOVERY_OPERATIONSTATE_STOP "stop" #define RECOVERY_OPERATIONSTATE_UPDATE "update" #define DLG_RET_UNKNOWN -1 #define DLG_RET_OK RET_OK #define DLG_RET_CANCEL RET_CANCEL #define DLG_RET_OK_AUTOLAUNCH 101 // request a restart enum class EDocStates { /* TEMP STATES */ /// default state, if a document was new created or loaded Unknown = 0x000, /** an action was started (saving/loading) ... Can be interesting later if the process may be was interrupted by an exception. */ TryLoadBackup = 0x010, TryLoadOriginal = 0x020, /* FINAL STATES */ /// the Auto/Emergency saved document isn't usable any longer Damaged = 0x040, /// the Auto/Emergency saved document is not really up-to-date (some changes can be missing) Incomplete = 0x080, /// the Auto/Emergency saved document was processed successfully Succeeded = 0x200 }; namespace o3tl { template<> struct typed_flags : is_typed_flags {}; } namespace svx{ namespace DocRecovery{ enum ERecoveryState { E_SUCCESSFULLY_RECOVERED, E_ORIGINAL_DOCUMENT_RECOVERED, E_RECOVERY_FAILED, E_RECOVERY_IS_IN_PROGRESS, E_NOT_RECOVERED_YET, E_WILL_BE_DISCARDED, }; struct TURLInfo { public: /// unique ID, which is specified by the underlying autorecovery core! sal_Int32 ID; /// the full qualified document URL OUString OrgURL; /// the full qualified URL of the temp. file (if it's exists) OUString TempURL; /// a may be existing factory URL (e.g. for untitled documents) OUString FactoryURL; /// may be the document base on a template file !? OUString TemplateURL; /// the pure file name, without path, disc etcpp. OUString DisplayName; /// the application module, where this document was loaded OUString Module; /// state info as e.g. VALID, CORRUPTED, NON EXISTING ... EDocStates DocState; /// ui representation for DocState! ERecoveryState RecoveryState; /// standard icon OUString StandardImageId; /// user choice to discard bool ShouldDiscard; public: TURLInfo() : ID (-1 ) , DocState (EDocStates::Unknown) , RecoveryState(E_NOT_RECOVERED_YET) , ShouldDiscard(false) {} }; typedef ::std::vector< TURLInfo > TURLList; class IRecoveryUpdateListener { public: // inform listener about changed items, which should be refreshed virtual void updateItems() = 0; // inform listener about ending of the asynchronous recovery operation virtual void end() = 0; // TODO virtual void stepNext(TURLInfo* pItem) = 0; protected: ~IRecoveryUpdateListener() {} }; class RecoveryCore final : public ::cppu::WeakImplHelper< css::frame::XStatusListener > { // types, const public: // member private: /// TODO css::uno::Reference< css::uno::XComponentContext > m_xContext; /// TODO css::uno::Reference< css::frame::XDispatch > m_xRealCore; /// TODO css::uno::Reference< css::task::XStatusIndicator > m_xProgress; /// TODO TURLList m_lURLs; /// TODO IRecoveryUpdateListener* m_pListener; /** @short knows the reason, why we listen on our internal m_xRealCore member. @descr Because we listen for different operations on the core dispatch implementation, we must know, which URL we have to use for deregistration! */ bool m_bListenForSaving; // native interface public: /** @short TODO */ RecoveryCore(css::uno::Reference< css::uno::XComponentContext > xContext, bool bUsedForSaving); /** @short TODO */ virtual ~RecoveryCore() override; /** @short TODO */ const css::uno::Reference< css::uno::XComponentContext >& getComponentContext() const; /** @short TODO */ TURLList& getURLListAccess(); /** @short TODO */ static bool isBrokenTempEntry(const TURLInfo& rInfo); void saveBrokenTempEntries(const OUString& sSaveDir); void saveAllTempEntries(const OUString& sSaveDir); void forgetBrokenTempEntries(); void forgetAllRecoveryEntries(); void forgetBrokenRecoveryEntries(); void forgetAllRecoveryEntriesMarkedForDiscard(); /** @short TODO */ void setProgressHandler(const css::uno::Reference< css::task::XStatusIndicator >& xProgress); /** @short TODO */ void setUpdateListener(IRecoveryUpdateListener* pListener); /** @short TODO */ void doEmergencySavePrepare(); void doEmergencySave(); void doRecovery(); /** @short TODO */ static ERecoveryState mapDocState2RecoverState(EDocStates eDocState); // uno interface public: // css.frame.XStatusListener virtual void SAL_CALL statusChanged(const css::frame::FeatureStateEvent& aEvent) override; // css.lang.XEventListener virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent) override; // helper private: /** @short starts listening on the internal EmergencySave/AutoRecovery core. */ void impl_startListening(); /** @short stop listening on the internal EmergencySave/AutoRecovery core. */ void impl_stopListening(); /** @short TODO */ css::util::URL impl_getParsedURL(const OUString& sURL); }; class PluginProgress final : public ::cppu::WeakImplHelper { // member private: weld::ProgressBar* m_pProgressBar; int m_nRange; // native interface public: PluginProgress(weld::ProgressBar* pProgressBar); virtual ~PluginProgress() override; // uno interface public: // XStatusIndicator virtual void SAL_CALL start(const OUString& sText, sal_Int32 nRange) override; virtual void SAL_CALL end() override; virtual void SAL_CALL setText(const OUString& sText) override; virtual void SAL_CALL setValue(sal_Int32 nValue) override; virtual void SAL_CALL reset() override; // XComponent virtual void SAL_CALL dispose() override; virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener >& xListener) override; virtual void SAL_CALL removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener) override; }; class SaveDialog final : public weld::GenericDialogController { // member private: RecoveryCore* m_pCore; std::unique_ptr m_xFileListLB; std::unique_ptr m_xOkBtn; // interface public: /** @short create all child controls of this dialog. @descr The dialog isn't shown nor it starts any action by itself! @param pParent can point to a parent window. If it's set to 0, the defmodal-dialog-parent is used automatically. @param pCore provides access to the recovery core service and the current list of open documents, which should be shown inside this dialog. */ SaveDialog(weld::Window* pParent, RecoveryCore* pCore); virtual ~SaveDialog() override; DECL_LINK(OKButtonHdl, weld::Button&, void); }; class SaveProgressDialog final : public weld::GenericDialogController , public IRecoveryUpdateListener { // member private: // @short TODO RecoveryCore* m_pCore; std::unique_ptr m_xProgressBar; // @short TODO rtl::Reference< PluginProgress > m_xProgress; // interface public: /** @short create all child controls of this dialog. @descr The dialog isn't shown nor it starts any action by itself! @param pParent can point to a parent window. If it's set to 0, the defmodal-dialog-parent is used automatically. @param pCore used to start emergency save. */ SaveProgressDialog(weld::Window* pParent, RecoveryCore* pCore); virtual ~SaveProgressDialog() override; /** @short start the emergency save operation. */ virtual short run() override; // IRecoveryUpdateListener virtual void updateItems() override; virtual void stepNext(TURLInfo* pItem) override; virtual void end() override; }; class RecoveryDialog final : public weld::GenericDialogController , public IRecoveryUpdateListener { // member private: OUString m_aTitleRecoveryInProgress; OUString m_aRecoveryOnlyFinish; OUString m_aRecoveryOnlyFinishDescr; RecoveryCore* m_pCore; rtl::Reference< PluginProgress > m_xProgress; enum EInternalRecoveryState { E_RECOVERY_PREPARED, // dialog started... recovery prepared E_RECOVERY_IN_PROGRESS, // recovery core still in progress E_RECOVERY_CORE_DONE, // recovery core finished it's task E_RECOVERY_DONE, // user clicked "next" button E_RECOVERY_CANCELED, // user clicked "cancel" button E_RECOVERY_CANCELED_BEFORE, // user clicked "cancel" button before recovery was started E_RECOVERY_CANCELED_AFTERWARDS, // user clicked "cancel" button after recovery was finished E_RECOVERY_HANDLED // the recovery wizard page was shown already... and will be shown now again... }; sal_Int32 m_eRecoveryState; bool m_bWaitForCore; bool m_bWasRecoveryStarted; int m_aToggleCount; OUString m_aSuccessRecovStr; OUString m_aOrigDocRecovStr; OUString m_aRecovFailedStr; OUString m_aRecovInProgrStr; OUString m_aNotRecovYetStr; OUString m_aWillBeDiscStr; std::unique_ptr m_xDescrFT; std::unique_ptr m_xProgressBar; std::unique_ptr m_xFileListLB; std::unique_ptr m_xNextBtn; std::unique_ptr m_xCancelBtn; // member public: /** @short TODO */ RecoveryDialog(weld::Window* pParent, RecoveryCore* pCore); virtual ~RecoveryDialog() override; // IRecoveryUpdateListener virtual void updateItems() override; virtual void stepNext(TURLInfo* pItem) override; virtual void end() override; bool allSuccessfullyRecovered(); short execute(); // helper private: DECL_LINK(NextButtonHdl, weld::Button&, void); DECL_LINK(CancelButtonHdl, weld::Button&, void); DECL_LINK(ToggleRowHdl, const weld::TreeView::iter_col&, void); OUString impl_getStatusString( const TURLInfo& rInfo ) const; static OUString impl_getStatusImage( const TURLInfo& rInfo ); void impl_updateItemDescription(int row, const TriState& rState); }; class BrokenRecoveryDialog final : public weld::GenericDialogController { // member private: OUString m_sSavePath; RecoveryCore* m_pCore; bool const m_bBeforeRecovery; bool m_bExecutionNeeded; std::unique_ptr m_xFileListLB; std::unique_ptr m_xSaveDirED; std::unique_ptr m_xSaveDirBtn; std::unique_ptr m_xOkBtn; std::unique_ptr m_xCancelBtn; // interface public: /** @short TODO */ BrokenRecoveryDialog(weld::Window* pParent, RecoveryCore* pCore, bool bBeforeRecovery); virtual ~BrokenRecoveryDialog() override; /** @short TODO */ bool isExecutionNeeded() const; /** @short TODO */ const OUString& getSaveDirURL() const; // helper private: /** @short TODO */ void impl_refresh(); /** @short TODO */ DECL_LINK(SaveButtonHdl, weld::Button&, void); /** @short TODO */ DECL_LINK(OkButtonHdl, weld::Button&, void); /** @short TODO */ DECL_LINK(CancelButtonHdl, weld::Button&, void); /** @short TODO */ void impl_askForSavePath(); }; } } #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */