LCOV - code coverage report
Current view: top level - svx/source/dialog - docrecovery.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 1 683 0.1 %
Date: 2015-06-13 12:38:46 Functions: 2 87 2.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <config_folders.h>
      21             : 
      22             : #include <sal/macros.h>
      23             : 
      24             : #include <svx/dialmgr.hxx>
      25             : #include <svx/dialogs.hrc>
      26             : #include "docrecovery.hxx"
      27             : #include "docrecovery.hrc"
      28             : 
      29             : #include <comphelper/processfactory.hxx>
      30             : #include <comphelper/sequenceashashmap.hxx>
      31             : #include <comphelper/string.hxx>
      32             : #include <svtools/imagemgr.hxx>
      33             : #include <vcl/xtextedt.hxx>
      34             : #include <vcl/settings.hxx>
      35             : #include <tools/urlobj.hxx>
      36             : #include <vcl/layout.hxx>
      37             : #include <vcl/svapp.hxx>
      38             : #include <rtl/ustrbuf.hxx>
      39             : #include <vcl/scrbar.hxx>
      40             : 
      41             : #include <toolkit/helper/vclunohelper.hxx>
      42             : 
      43             : #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
      44             : #include <com/sun/star/lang/XInitialization.hpp>
      45             : #include <com/sun/star/beans/NamedValue.hpp>
      46             : #include <com/sun/star/util/URL.hpp>
      47             : #include <com/sun/star/util/XURLTransformer.hpp>
      48             : #include <com/sun/star/frame/theAutoRecovery.hpp>
      49             : #include <com/sun/star/frame/XDispatch.hpp>
      50             : #include <com/sun/star/awt/XWindow.hpp>
      51             : #include <com/sun/star/ui/dialogs/FolderPicker.hpp>
      52             : #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
      53             : #include <com/sun/star/util/URLTransformer.hpp>
      54             : #include <osl/file.hxx>
      55             : #include <osl/security.hxx>
      56             : #include <rtl/bootstrap.hxx>
      57             : #include <unotools/pathoptions.hxx>
      58             : #include <unotools/localfilehelper.hxx>
      59             : #include "svtools/treelistentry.hxx"
      60             : #include <officecfg/Office/Recovery.hxx>
      61             : #include <boost/scoped_ptr.hpp>
      62             : 
      63             : namespace svx{
      64             :     namespace DocRecovery{
      65             : 
      66             : using namespace ::osl;
      67             : 
      68           0 : RecoveryCore::RecoveryCore(const css::uno::Reference< css::uno::XComponentContext >& rxContext,
      69             :                                  bool                                            bUsedForSaving)
      70             :     : m_xContext        ( rxContext    )
      71             :     , m_pListener       ( 0            )
      72           0 :     , m_bListenForSaving(bUsedForSaving)
      73             : {
      74           0 :     impl_startListening();
      75           0 : }
      76             : 
      77             : 
      78           0 : RecoveryCore::~RecoveryCore()
      79             : {
      80           0 :     impl_stopListening();
      81           0 : }
      82             : 
      83             : 
      84           0 : css::uno::Reference< css::uno::XComponentContext > RecoveryCore::getComponentContext()
      85             : {
      86           0 :     return m_xContext;
      87             : }
      88             : 
      89             : 
      90           0 : TURLList& RecoveryCore::getURLListAccess()
      91             : {
      92           0 :     return m_lURLs;
      93             : }
      94             : 
      95             : 
      96           0 : bool RecoveryCore::isBrokenTempEntry(const TURLInfo& rInfo)
      97             : {
      98           0 :     if (rInfo.TempURL.isEmpty())
      99           0 :         return false;
     100             : 
     101             :     // Note: If the original files was recovery ... but a temp file
     102             :     // exists ... an error inside the temp file exists!
     103           0 :     if (
     104           0 :         !(rInfo.RecoveryState == E_RECOVERY_FAILED            ) &&
     105           0 :         !(rInfo.RecoveryState == E_ORIGINAL_DOCUMENT_RECOVERED)
     106             :        )
     107           0 :        return false;
     108             : 
     109           0 :     return true;
     110             : }
     111             : 
     112             : 
     113           0 : void RecoveryCore::saveBrokenTempEntries(const OUString& rPath)
     114             : {
     115           0 :     if (rPath.isEmpty())
     116           0 :         return;
     117             : 
     118           0 :     if (!m_xRealCore.is())
     119           0 :         return;
     120             : 
     121             :     // prepare all needed parameters for the following dispatch() request.
     122           0 :     css::util::URL aCopyURL = impl_getParsedURL(RECOVERY_CMD_DO_ENTRY_BACKUP);
     123           0 :     css::uno::Sequence< css::beans::PropertyValue > lCopyArgs(3);
     124           0 :     lCopyArgs[0].Name    = PROP_DISPATCHASYNCHRON;
     125           0 :     lCopyArgs[0].Value <<= sal_False;
     126           0 :     lCopyArgs[1].Name    = PROP_SAVEPATH;
     127           0 :     lCopyArgs[1].Value <<= rPath;
     128           0 :     lCopyArgs[2].Name    = PROP_ENTRYID;
     129             :     // lCopyArgs[2].Value will be changed during next loop ...
     130             : 
     131             :     // work on a copied list only ...
     132             :     // Reason: We will get notifications from the core for every
     133             :     // changed or removed element. And that will change our m_lURLs list.
     134             :     // That's not a good idea, if we use a stl iterator inbetween .-)
     135           0 :     TURLList lURLs = m_lURLs;
     136           0 :     TURLList::const_iterator pIt;
     137           0 :     for (  pIt  = lURLs.begin();
     138           0 :            pIt != lURLs.end()  ;
     139             :          ++pIt                 )
     140             :     {
     141           0 :         const TURLInfo& rInfo = *pIt;
     142           0 :         if (!RecoveryCore::isBrokenTempEntry(rInfo))
     143           0 :             continue;
     144             : 
     145           0 :         lCopyArgs[2].Value <<= rInfo.ID;
     146           0 :         m_xRealCore->dispatch(aCopyURL, lCopyArgs);
     147           0 :     }
     148             : }
     149             : 
     150             : 
     151           0 : void RecoveryCore::saveAllTempEntries(const OUString& rPath)
     152             : {
     153           0 :     if (rPath.isEmpty())
     154           0 :         return;
     155             : 
     156           0 :     if (!m_xRealCore.is())
     157           0 :         return;
     158             : 
     159             :     // prepare all needed parameters for the following dispatch() request.
     160           0 :     css::util::URL aCopyURL = impl_getParsedURL(RECOVERY_CMD_DO_ENTRY_BACKUP);
     161           0 :     css::uno::Sequence< css::beans::PropertyValue > lCopyArgs(3);
     162           0 :     lCopyArgs[0].Name    = PROP_DISPATCHASYNCHRON;
     163           0 :     lCopyArgs[0].Value <<= sal_False;
     164           0 :     lCopyArgs[1].Name    = PROP_SAVEPATH;
     165           0 :     lCopyArgs[1].Value <<= rPath;
     166           0 :     lCopyArgs[2].Name    = PROP_ENTRYID;
     167             :     // lCopyArgs[2].Value will be changed during next loop ...
     168             : 
     169             :     // work on a copied list only ...
     170             :     // Reason: We will get notifications from the core for every
     171             :     // changed or removed element. And that will change our m_lURLs list.
     172             :     // That's not a good idea, if we use a stl iterator inbetween .-)
     173           0 :     TURLList lURLs = m_lURLs;
     174           0 :     TURLList::const_iterator pIt;
     175           0 :     for (  pIt  = lURLs.begin();
     176           0 :            pIt != lURLs.end()  ;
     177             :          ++pIt                 )
     178             :     {
     179           0 :         const TURLInfo& rInfo = *pIt;
     180           0 :         if (rInfo.TempURL.isEmpty())
     181           0 :             continue;
     182             : 
     183           0 :         lCopyArgs[2].Value <<= rInfo.ID;
     184           0 :         m_xRealCore->dispatch(aCopyURL, lCopyArgs);
     185           0 :     }
     186             : }
     187             : 
     188             : 
     189           0 : void RecoveryCore::forgetBrokenTempEntries()
     190             : {
     191           0 :     if (!m_xRealCore.is())
     192           0 :         return;
     193             : 
     194           0 :     css::util::URL aRemoveURL = impl_getParsedURL(RECOVERY_CMD_DO_ENTRY_CLEANUP);
     195           0 :     css::uno::Sequence< css::beans::PropertyValue > lRemoveArgs(2);
     196           0 :     lRemoveArgs[0].Name    = PROP_DISPATCHASYNCHRON;
     197           0 :     lRemoveArgs[0].Value <<= sal_False;
     198           0 :     lRemoveArgs[1].Name    = PROP_ENTRYID;
     199             :     // lRemoveArgs[1].Value will be changed during next loop ...
     200             : 
     201             :     // work on a copied list only ...
     202             :     // Reason: We will get notifications from the core for every
     203             :     // changed or removed element. And that will change our m_lURLs list.
     204             :     // That's not a good idea, if we use a stl iterator inbetween .-)
     205           0 :     TURLList lURLs = m_lURLs;
     206           0 :     TURLList::const_iterator pIt;
     207           0 :     for (  pIt  = lURLs.begin();
     208           0 :            pIt != lURLs.end()  ;
     209             :          ++pIt                 )
     210             :     {
     211           0 :         const TURLInfo& rInfo = *pIt;
     212           0 :         if (!RecoveryCore::isBrokenTempEntry(rInfo))
     213           0 :             continue;
     214             : 
     215           0 :         lRemoveArgs[1].Value <<= rInfo.ID;
     216           0 :         m_xRealCore->dispatch(aRemoveURL, lRemoveArgs);
     217           0 :     }
     218             : }
     219             : 
     220             : 
     221           0 : void RecoveryCore::forgetAllRecoveryEntries()
     222             : {
     223           0 :     if (!m_xRealCore.is())
     224           0 :         return;
     225             : 
     226           0 :     css::util::URL aRemoveURL = impl_getParsedURL(RECOVERY_CMD_DO_ENTRY_CLEANUP);
     227           0 :     css::uno::Sequence< css::beans::PropertyValue > lRemoveArgs(2);
     228           0 :     lRemoveArgs[0].Name    = PROP_DISPATCHASYNCHRON;
     229           0 :     lRemoveArgs[0].Value <<= sal_False;
     230           0 :     lRemoveArgs[1].Name    = PROP_ENTRYID;
     231             :     // lRemoveArgs[1].Value will be changed during next loop ...
     232             : 
     233             :     // work on a copied list only ...
     234             :     // Reason: We will get notifications from the core for every
     235             :     // changed or removed element. And that will change our m_lURLs list.
     236             :     // That's not a good idea, if we use a stl iterator inbetween .-)
     237           0 :     TURLList lURLs = m_lURLs;
     238           0 :     TURLList::const_iterator pIt;
     239           0 :     for (  pIt  = lURLs.begin();
     240           0 :            pIt != lURLs.end()  ;
     241             :          ++pIt                 )
     242             :     {
     243           0 :         const TURLInfo& rInfo = *pIt;
     244           0 :         lRemoveArgs[1].Value <<= rInfo.ID;
     245           0 :         m_xRealCore->dispatch(aRemoveURL, lRemoveArgs);
     246           0 :     }
     247             : }
     248             : 
     249             : 
     250           0 : void RecoveryCore::forgetBrokenRecoveryEntries()
     251             : {
     252           0 :     if (!m_xRealCore.is())
     253           0 :         return;
     254             : 
     255           0 :     css::util::URL aRemoveURL = impl_getParsedURL(RECOVERY_CMD_DO_ENTRY_CLEANUP);
     256           0 :     css::uno::Sequence< css::beans::PropertyValue > lRemoveArgs(2);
     257           0 :     lRemoveArgs[0].Name    = PROP_DISPATCHASYNCHRON;
     258           0 :     lRemoveArgs[0].Value <<= sal_False;
     259           0 :     lRemoveArgs[1].Name    = PROP_ENTRYID;
     260             :     // lRemoveArgs[1].Value will be changed during next loop ...
     261             : 
     262             :     // work on a copied list only ...
     263             :     // Reason: We will get notifications from the core for every
     264             :     // changed or removed element. And that will change our m_lURLs list.
     265             :     // That's not a good idea, if we use a stl iterator inbetween .-)
     266           0 :     TURLList lURLs = m_lURLs;
     267           0 :     TURLList::const_iterator pIt;
     268           0 :     for (  pIt  = lURLs.begin();
     269           0 :            pIt != lURLs.end()  ;
     270             :          ++pIt                 )
     271             :     {
     272           0 :         const TURLInfo& rInfo = *pIt;
     273           0 :         if (!RecoveryCore::isBrokenTempEntry(rInfo))
     274           0 :             continue;
     275             : 
     276           0 :         lRemoveArgs[1].Value <<= rInfo.ID;
     277           0 :         m_xRealCore->dispatch(aRemoveURL, lRemoveArgs);
     278           0 :     }
     279             : }
     280             : 
     281             : 
     282           0 : void RecoveryCore::setProgressHandler(const css::uno::Reference< css::task::XStatusIndicator >& xProgress)
     283             : {
     284           0 :     m_xProgress = xProgress;
     285           0 : }
     286             : 
     287             : 
     288           0 : void RecoveryCore::setUpdateListener(IRecoveryUpdateListener* pListener)
     289             : {
     290           0 :     m_pListener = pListener;
     291           0 : }
     292             : 
     293             : 
     294           0 : void RecoveryCore::doEmergencySavePrepare()
     295             : {
     296           0 :     if (!m_xRealCore.is())
     297           0 :         return;
     298             : 
     299           0 :     css::util::URL aURL = impl_getParsedURL(RECOVERY_CMD_DO_PREPARE_EMERGENCY_SAVE);
     300             : 
     301           0 :     css::uno::Sequence< css::beans::PropertyValue > lArgs(1);
     302           0 :     lArgs[0].Name    = PROP_DISPATCHASYNCHRON;
     303           0 :     lArgs[0].Value <<= sal_False;
     304             : 
     305           0 :     m_xRealCore->dispatch(aURL, lArgs);
     306             : }
     307             : 
     308             : 
     309           0 : void RecoveryCore::doEmergencySave()
     310             : {
     311           0 :     if (!m_xRealCore.is())
     312           0 :         return;
     313             : 
     314           0 :     css::util::URL aURL = impl_getParsedURL(RECOVERY_CMD_DO_EMERGENCY_SAVE);
     315             : 
     316           0 :     css::uno::Sequence< css::beans::PropertyValue > lArgs(2);
     317           0 :     lArgs[0].Name    = PROP_STATUSINDICATOR;
     318           0 :     lArgs[0].Value <<= m_xProgress;
     319           0 :     lArgs[1].Name    = PROP_DISPATCHASYNCHRON;
     320           0 :     lArgs[1].Value <<= sal_True;
     321             : 
     322           0 :     m_xRealCore->dispatch(aURL, lArgs);
     323             : }
     324             : 
     325             : 
     326           0 : void RecoveryCore::doRecovery()
     327             : {
     328           0 :     if (!m_xRealCore.is())
     329           0 :         return;
     330             : 
     331           0 :     css::util::URL aURL = impl_getParsedURL(RECOVERY_CMD_DO_RECOVERY);
     332             : 
     333           0 :     css::uno::Sequence< css::beans::PropertyValue > lArgs(2);
     334           0 :     lArgs[0].Name    = PROP_STATUSINDICATOR;
     335           0 :     lArgs[0].Value <<= m_xProgress;
     336           0 :     lArgs[1].Name    = PROP_DISPATCHASYNCHRON;
     337           0 :     lArgs[1].Value <<= sal_True;
     338             : 
     339           0 :     m_xRealCore->dispatch(aURL, lArgs);
     340             : }
     341             : 
     342             : 
     343           0 : ERecoveryState RecoveryCore::mapDocState2RecoverState(sal_Int32 eDocState)
     344             : {
     345             :     // ???
     346           0 :     ERecoveryState eRecState = E_NOT_RECOVERED_YET;
     347             : 
     348             :     /* Attention:
     349             :         Some of the following states can occur at the
     350             :         same time. So we have to check for the "worst case" first!
     351             : 
     352             :         DAMAGED -> INCOMPLETE -> HANDLED
     353             :      */
     354             : 
     355             :     // running ...
     356           0 :     if (
     357           0 :         ((eDocState & E_TRY_LOAD_BACKUP  ) == E_TRY_LOAD_BACKUP  ) ||
     358           0 :         ((eDocState & E_TRY_LOAD_ORIGINAL) == E_TRY_LOAD_ORIGINAL)
     359             :        )
     360           0 :         eRecState = E_RECOVERY_IS_IN_PROGRESS;
     361             :     // red
     362           0 :     else if ((eDocState & E_DAMAGED) == E_DAMAGED)
     363           0 :         eRecState = E_RECOVERY_FAILED;
     364             :     // yellow
     365           0 :     else if ((eDocState & E_INCOMPLETE) == E_INCOMPLETE)
     366           0 :         eRecState = E_ORIGINAL_DOCUMENT_RECOVERED;
     367             :     // green
     368           0 :     else if ((eDocState & E_SUCCEDED) == E_SUCCEDED)
     369           0 :         eRecState = E_SUCCESSFULLY_RECOVERED;
     370             : 
     371           0 :     return eRecState;
     372             : }
     373             : 
     374             : 
     375           0 : void SAL_CALL RecoveryCore::statusChanged(const css::frame::FeatureStateEvent& aEvent)
     376             :     throw(css::uno::RuntimeException, std::exception)
     377             : {
     378             :     // a) special notification about start/stop async dispatch!
     379             :     //    FeatureDescriptor = "start" || "stop"
     380           0 :     if (aEvent.FeatureDescriptor == RECOVERY_OPERATIONSTATE_START)
     381             :     {
     382           0 :         if (m_pListener)
     383           0 :             m_pListener->start();
     384           0 :         return;
     385             :     }
     386             : 
     387           0 :     if (aEvent.FeatureDescriptor == RECOVERY_OPERATIONSTATE_STOP)
     388             :     {
     389           0 :         if (m_pListener)
     390           0 :             m_pListener->end();
     391           0 :         return;
     392             :     }
     393             : 
     394             :     // b) normal notification about changed items
     395             :     //    FeatureDescriptor = "Update"
     396             :     //    State             = Lits of information [seq< NamedValue >]
     397           0 :     if (aEvent.FeatureDescriptor != RECOVERY_OPERATIONSTATE_UPDATE)
     398           0 :         return;
     399             : 
     400           0 :     ::comphelper::SequenceAsHashMap lInfo(aEvent.State);
     401           0 :     TURLInfo                        aNew;
     402             : 
     403           0 :     aNew.ID          = lInfo.getUnpackedValueOrDefault(STATEPROP_ID         , (sal_Int32)0     );
     404           0 :     aNew.DocState    = lInfo.getUnpackedValueOrDefault(STATEPROP_STATE      , (sal_Int32)0     );
     405           0 :     aNew.OrgURL      = lInfo.getUnpackedValueOrDefault(STATEPROP_ORGURL     , OUString());
     406           0 :     aNew.TempURL     = lInfo.getUnpackedValueOrDefault(STATEPROP_TEMPURL    , OUString());
     407           0 :     aNew.FactoryURL  = lInfo.getUnpackedValueOrDefault(STATEPROP_FACTORYURL , OUString());
     408           0 :     aNew.TemplateURL = lInfo.getUnpackedValueOrDefault(STATEPROP_TEMPLATEURL, OUString());
     409           0 :     aNew.DisplayName = lInfo.getUnpackedValueOrDefault(STATEPROP_TITLE      , OUString());
     410           0 :     aNew.Module      = lInfo.getUnpackedValueOrDefault(STATEPROP_MODULE     , OUString());
     411             : 
     412           0 :     if (aNew.OrgURL.isEmpty()) {
     413             :         // If there is no file URL, the window title is used for the display name.
     414             :         // Remove any unwanted elements such as " - LibreOffice Writer".
     415           0 :         sal_Int32 i = aNew.DisplayName.indexOf(" - ");
     416           0 :         if (i > 0)
     417           0 :             aNew.DisplayName = aNew.DisplayName.copy(0, i);
     418             :     } else {
     419             :         // If there is a file URL, parse out the filename part as the display name.
     420           0 :         INetURLObject aOrgURL(aNew.OrgURL);
     421           0 :         aNew.DisplayName = aOrgURL.getName(INetURLObject::LAST_SEGMENT, true,
     422           0 :                                            INetURLObject::DECODE_WITH_CHARSET);
     423             :     }
     424             : 
     425             :     // search for already existing items and update her nState value ...
     426           0 :     TURLList::iterator pIt;
     427           0 :     for (  pIt  = m_lURLs.begin();
     428           0 :            pIt != m_lURLs.end()  ;
     429             :          ++pIt                   )
     430             :     {
     431           0 :         TURLInfo& aOld = *pIt;
     432           0 :         if (aOld.ID == aNew.ID)
     433             :         {
     434             :             // change existing
     435           0 :             aOld.DocState      = aNew.DocState;
     436           0 :             aOld.RecoveryState = RecoveryCore::mapDocState2RecoverState(aOld.DocState);
     437           0 :             if (m_pListener)
     438             :             {
     439           0 :                 m_pListener->updateItems();
     440           0 :                 m_pListener->stepNext(&aOld);
     441             :             }
     442           0 :             return;
     443             :         }
     444             :     }
     445             : 
     446             :     // append as new one
     447             :     // TODO think about mmatching Module name to a corresponding icon
     448           0 :     OUString sURL = aNew.OrgURL;
     449           0 :     if (sURL.isEmpty())
     450           0 :         sURL = aNew.FactoryURL;
     451           0 :     if (sURL.isEmpty())
     452           0 :         sURL = aNew.TempURL;
     453           0 :     if (sURL.isEmpty())
     454           0 :         sURL = aNew.TemplateURL;
     455           0 :     INetURLObject aURL(sURL);
     456           0 :     aNew.StandardImage = SvFileInformationManager::GetFileImage(aURL, false);
     457             : 
     458             :     /* set the right UI state for this item to NOT_RECOVERED_YET ... because nDocState shows the state of
     459             :        the last emergency save operation before and is interessting for the used recovery core service only ...
     460             :        for now! But if there is a further notification for this item (see lines above!) we must
     461             :        map the doc state to an UI state. */
     462           0 :     aNew.RecoveryState = E_NOT_RECOVERED_YET;
     463             : 
     464           0 :     m_lURLs.push_back(aNew);
     465             : 
     466           0 :     if (m_pListener)
     467           0 :         m_pListener->updateItems();
     468             : }
     469             : 
     470             : 
     471           0 : void SAL_CALL RecoveryCore::disposing(const css::lang::EventObject& /*aEvent*/)
     472             :     throw(css::uno::RuntimeException, std::exception)
     473             : {
     474           0 :     m_xRealCore.clear();
     475           0 : }
     476             : 
     477             : 
     478           0 : void RecoveryCore::impl_startListening()
     479             : {
     480             :     // listening already initialized ?
     481           0 :     if (m_xRealCore.is())
     482           0 :         return;
     483           0 :     m_xRealCore = css::frame::theAutoRecovery::get(m_xContext);
     484             : 
     485           0 :     css::util::URL aURL;
     486           0 :     if (m_bListenForSaving)
     487           0 :         aURL.Complete = RECOVERY_CMD_DO_EMERGENCY_SAVE;
     488             :     else
     489           0 :         aURL.Complete = RECOVERY_CMD_DO_RECOVERY;
     490           0 :     css::uno::Reference< css::util::XURLTransformer > xParser(css::util::URLTransformer::create(m_xContext));
     491           0 :     xParser->parseStrict(aURL);
     492             : 
     493             :     /* Note: addStatusListener() call us synchronous back ... so we
     494             :              will get the complete list of currently open documents! */
     495           0 :     m_xRealCore->addStatusListener(static_cast< css::frame::XStatusListener* >(this), aURL);
     496             : }
     497             : 
     498             : 
     499           0 : void RecoveryCore::impl_stopListening()
     500             : {
     501             :     // Ignore it, if this instance doesn't listen currently
     502           0 :     if (!m_xRealCore.is())
     503           0 :         return;
     504             : 
     505           0 :     css::util::URL aURL;
     506           0 :     if (m_bListenForSaving)
     507           0 :         aURL.Complete = RECOVERY_CMD_DO_EMERGENCY_SAVE;
     508             :     else
     509           0 :         aURL.Complete = RECOVERY_CMD_DO_RECOVERY;
     510           0 :     css::uno::Reference< css::util::XURLTransformer > xParser(css::util::URLTransformer::create(m_xContext));
     511           0 :     xParser->parseStrict(aURL);
     512             : 
     513           0 :     m_xRealCore->removeStatusListener(static_cast< css::frame::XStatusListener* >(this), aURL);
     514           0 :     m_xRealCore.clear();
     515             : }
     516             : 
     517             : 
     518           0 : css::util::URL RecoveryCore::impl_getParsedURL(const OUString& sURL)
     519             : {
     520           0 :     css::util::URL aURL;
     521           0 :     aURL.Complete = sURL;
     522             : 
     523           0 :     css::uno::Reference< css::util::XURLTransformer > xParser(css::util::URLTransformer::create(m_xContext));
     524           0 :     xParser->parseStrict(aURL);
     525             : 
     526           0 :     return aURL;
     527             : }
     528             : 
     529           0 : PluginProgressWindow::PluginProgressWindow(      vcl::Window*                                       pParent  ,
     530             :                                            const css::uno::Reference< css::lang::XComponent >& xProgress)
     531             :     : Window     (pParent  )
     532           0 :     , m_xProgress(xProgress)
     533             : {
     534           0 :     Show();
     535           0 :     Size aParentSize = pParent->GetSizePixel();
     536             :     // align the progressbar to its parent
     537           0 :     setPosSizePixel( -9, 0, aParentSize.Width() + 15, aParentSize.Height() - 4 );
     538           0 : }
     539             : 
     540           0 : PluginProgressWindow::~PluginProgressWindow()
     541             : {
     542           0 :     disposeOnce();
     543           0 : }
     544             : 
     545           0 : void PluginProgressWindow::dispose()
     546             : {
     547           0 :     if (m_xProgress.is())
     548           0 :         m_xProgress->dispose();
     549           0 :     vcl::Window::dispose();
     550           0 : }
     551             : 
     552             : 
     553           0 : PluginProgress::PluginProgress(      vcl::Window*                                             pParent,
     554           0 :                                const css::uno::Reference< css::uno::XComponentContext >& xContext  )
     555             : {
     556           0 :     m_pPlugProgressWindow = VclPtr<PluginProgressWindow>::Create(pParent, static_cast< css::lang::XComponent* >(this));
     557           0 :     css::uno::Reference< css::awt::XWindow > xProgressWindow = VCLUnoHelper::GetInterface(m_pPlugProgressWindow);
     558           0 :     m_xProgressFactory = css::task::StatusIndicatorFactory::createWithWindow(xContext, xProgressWindow, sal_False/*DisableReschedule*/, sal_True/*AllowParentShow*/);
     559           0 :     m_xProgress = m_xProgressFactory->createStatusIndicator();
     560           0 : }
     561             : 
     562             : 
     563           0 : PluginProgress::~PluginProgress()
     564             : {
     565           0 : }
     566             : 
     567             : 
     568           0 : void SAL_CALL PluginProgress::dispose()
     569             :     throw(css::uno::RuntimeException, std::exception)
     570             : {
     571             :     // m_pPluginProgressWindow was deleted ...
     572             :     // So the internal pointer of this progress
     573             :     // weill be dead!
     574           0 :     m_xProgress.clear();
     575           0 : }
     576             : 
     577             : 
     578           0 : void SAL_CALL PluginProgress::addEventListener(const css::uno::Reference< css::lang::XEventListener >& )
     579             :     throw(css::uno::RuntimeException, std::exception)
     580             : {
     581           0 : }
     582             : 
     583             : 
     584           0 : void SAL_CALL PluginProgress::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& )
     585             :     throw(css::uno::RuntimeException, std::exception)
     586             : {
     587           0 : }
     588             : 
     589             : 
     590           0 : void SAL_CALL PluginProgress::start(const OUString&,
     591             :                                           sal_Int32        nRange)
     592             :     throw(css::uno::RuntimeException, std::exception)
     593             : {
     594           0 :     if (m_xProgress.is())
     595           0 :         m_xProgress->start(OUString(), nRange);
     596           0 : }
     597             : 
     598             : 
     599           0 : void SAL_CALL PluginProgress::end()
     600             :     throw(css::uno::RuntimeException, std::exception)
     601             : {
     602           0 :     if (m_xProgress.is())
     603           0 :         m_xProgress->end();
     604           0 : }
     605             : 
     606             : 
     607           0 : void SAL_CALL PluginProgress::setText(const OUString& sText)
     608             :     throw(css::uno::RuntimeException, std::exception)
     609             : {
     610           0 :     if (m_xProgress.is())
     611           0 :         m_xProgress->setText(sText);
     612           0 : }
     613             : 
     614             : 
     615           0 : void SAL_CALL PluginProgress::setValue(sal_Int32 nValue)
     616             :     throw(css::uno::RuntimeException, std::exception)
     617             : {
     618           0 :     if (m_xProgress.is())
     619           0 :         m_xProgress->setValue(nValue);
     620           0 : }
     621             : 
     622             : 
     623           0 : void SAL_CALL PluginProgress::reset()
     624             :     throw(css::uno::RuntimeException, std::exception)
     625             : {
     626           0 :     if (m_xProgress.is())
     627           0 :         m_xProgress->reset();
     628           0 : }
     629             : 
     630             : 
     631           0 : SaveDialog::SaveDialog(vcl::Window* pParent, RecoveryCore* pCore)
     632             :     : Dialog(pParent, "DocRecoverySaveDialog",
     633             :         "svx/ui/docrecoverysavedialog.ui")
     634           0 :     , m_pCore(pCore)
     635             : {
     636           0 :     get(m_pTitleFT, "title");
     637           0 :     get(m_pFileListLB, "filelist");
     638           0 :     m_pFileListLB->set_height_request(m_pFileListLB->GetTextHeight() * 10);
     639           0 :     m_pFileListLB->set_width_request(m_pFileListLB->approximate_char_width() * 72);
     640           0 :     get(m_pOkBtn, "ok");
     641             : 
     642             :     // Prepare the office for the following crash save step.
     643             :     // E.g. hide all open windows so the user can't influence our
     644             :     // operation .-)
     645           0 :     m_pCore->doEmergencySavePrepare();
     646             : 
     647           0 :     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
     648           0 :     m_pTitleFT->SetBackground(rStyleSettings.GetWindowColor());
     649           0 :     m_pTitleFT->set_height_request(m_pTitleFT->get_preferred_size().Height() + 48);
     650             : 
     651           0 :     m_pOkBtn->SetClickHdl( LINK( this, SaveDialog, OKButtonHdl ) );
     652           0 :     m_pFileListLB->SetControlBackground( rStyleSettings.GetDialogColor() );
     653             : 
     654             :     // fill listbox with current open documents
     655           0 :     m_pFileListLB->Clear();
     656             : 
     657           0 :     TURLList&                pURLs = m_pCore->getURLListAccess();
     658           0 :     TURLList::const_iterator pIt;
     659             : 
     660           0 :     for (  pIt  = pURLs.begin();
     661           0 :            pIt != pURLs.end()  ;
     662             :          ++pIt                  )
     663             :     {
     664           0 :         const TURLInfo& rInfo = *pIt;
     665           0 :         m_pFileListLB->InsertEntry( rInfo.DisplayName, rInfo.StandardImage );
     666             :     }
     667           0 : }
     668             : 
     669           0 : SaveDialog::~SaveDialog()
     670             : {
     671           0 :     disposeOnce();
     672           0 : }
     673             : 
     674           0 : void SaveDialog::dispose()
     675             : {
     676           0 :     m_pTitleFT.clear();
     677           0 :     m_pFileListLB.clear();
     678           0 :     m_pOkBtn.clear();
     679           0 :     Dialog::dispose();
     680           0 : }
     681             : 
     682           0 : IMPL_LINK_NOARG(SaveDialog, OKButtonHdl)
     683             : {
     684             :     // start crash-save with progress
     685           0 :     ScopedVclPtrInstance< SaveProgressDialog > pProgress(this, m_pCore);
     686           0 :     short nResult = pProgress->Execute();
     687           0 :     pProgress.reset();
     688             : 
     689             :     // if "CANCEL" => return "CANCEL"
     690             :     // if "OK"     => "AUTOLUNCH" always !
     691           0 :     if (nResult == DLG_RET_OK)
     692           0 :         nResult = DLG_RET_OK_AUTOLUNCH;
     693             : 
     694           0 :     EndDialog(nResult);
     695           0 :     return 0;
     696             : }
     697             : 
     698           0 : SaveProgressDialog::SaveProgressDialog(vcl::Window* pParent, RecoveryCore* pCore)
     699             :     : ModalDialog(pParent, "DocRecoveryProgressDialog",
     700             :         "svx/ui/docrecoveryprogressdialog.ui")
     701           0 :     , m_pCore(pCore)
     702             : {
     703           0 :     get(m_pProgrParent, "progress");
     704           0 :     Size aSize(LogicToPixel(Size(SAVEPROGR_CONTROLWIDTH, PROGR_HEIGHT)));
     705           0 :     m_pProgrParent->set_width_request(aSize.Width());
     706           0 :     m_pProgrParent->set_height_request(aSize.Height());
     707             : 
     708           0 :     PluginProgress* pProgress   = new PluginProgress(m_pProgrParent, pCore->getComponentContext());
     709           0 :     m_xProgress = css::uno::Reference< css::task::XStatusIndicator >(static_cast< css::task::XStatusIndicator* >(pProgress), css::uno::UNO_QUERY_THROW);
     710           0 : }
     711             : 
     712           0 : SaveProgressDialog::~SaveProgressDialog()
     713             : {
     714           0 :     disposeOnce();
     715           0 : }
     716             : 
     717           0 : void SaveProgressDialog::dispose()
     718             : {
     719           0 :     m_pProgrParent.clear();
     720           0 :     ModalDialog::dispose();
     721           0 : }
     722             : 
     723           0 : short SaveProgressDialog::Execute()
     724             : {
     725           0 :     ::SolarMutexGuard aLock;
     726             : 
     727           0 :     m_pCore->setProgressHandler(m_xProgress);
     728           0 :     m_pCore->setUpdateListener(this);
     729           0 :     m_pCore->doEmergencySave();
     730           0 :     short nRet = ModalDialog::Execute();
     731           0 :     m_pCore->setUpdateListener(0);
     732           0 :     return nRet;
     733             : }
     734             : 
     735           0 : void SaveProgressDialog::updateItems()
     736             : {
     737           0 : }
     738             : 
     739             : 
     740           0 : void SaveProgressDialog::stepNext(TURLInfo* )
     741             : {
     742             :     /* TODO
     743             : 
     744             :        if m_pCore would have a member m_mCurrentItem, you could see,
     745             :        who is current, who is next ... You can show this information
     746             :        in progress report FixText
     747             :     */
     748           0 : }
     749             : 
     750             : 
     751           0 : void SaveProgressDialog::start()
     752             : {
     753           0 : }
     754             : 
     755             : 
     756           0 : void SaveProgressDialog::end()
     757             : {
     758           0 :     EndDialog(DLG_RET_OK);
     759           0 : }
     760             : 
     761             : 
     762           0 : RecovDocListEntry::RecovDocListEntry(      SvTreeListEntry* pEntry,
     763             :                                            sal_uInt16       nFlags,
     764             :                                      const OUString&        sText )
     765           0 :     : SvLBoxString( pEntry, nFlags, sText )
     766             : {
     767           0 : }
     768             : 
     769             : 
     770           0 : void RecovDocListEntry::Paint(const Point& aPos, SvTreeListBox& aDevice, vcl::RenderContext& rRenderContext,
     771             :                               const SvViewDataEntry* /*pView*/, const SvTreeListEntry& rEntry)
     772             : {
     773           0 :     const Image* pImg = 0;
     774           0 :     const OUString* pTxt = 0;
     775           0 :     RecovDocList* pList = static_cast<RecovDocList*>(&aDevice);
     776             : 
     777           0 :     TURLInfo* pInfo = static_cast<TURLInfo*>(rEntry.GetUserData());
     778           0 :     switch (pInfo->RecoveryState)
     779             :     {
     780             :         case E_SUCCESSFULLY_RECOVERED:
     781             :         {
     782           0 :             pImg = &pList->m_aGreenCheckImg;
     783           0 :             pTxt = &pList->m_aSuccessRecovStr;
     784             :         }
     785           0 :         break;
     786             : 
     787             :         case E_ORIGINAL_DOCUMENT_RECOVERED: // TODO must be renamed into ORIGINAL DOCUMENT recovered! Because its marked as yellow
     788             :         {
     789           0 :             pImg = &pList->m_aYellowCheckImg;
     790           0 :             pTxt = &pList->m_aOrigDocRecovStr;
     791             :         }
     792           0 :         break;
     793             : 
     794             :         case E_RECOVERY_FAILED:
     795             :         {
     796           0 :             pImg = &pList->m_aRedCrossImg;
     797           0 :             pTxt = &pList->m_aRecovFailedStr;
     798             :         }
     799           0 :         break;
     800             : 
     801             :         case E_RECOVERY_IS_IN_PROGRESS:
     802             :         {
     803           0 :             pImg = 0;
     804           0 :             pTxt = &pList->m_aRecovInProgrStr;
     805             :         }
     806           0 :         break;
     807             : 
     808             :         case E_NOT_RECOVERED_YET:
     809             :         {
     810           0 :             pImg = 0;
     811           0 :             pTxt = &pList->m_aNotRecovYetStr;
     812             :         }
     813           0 :         break;
     814             :     }
     815             : 
     816           0 :     if (pImg)
     817           0 :         rRenderContext.DrawImage(aPos, *pImg);
     818             : 
     819           0 :     if (pTxt)
     820             :     {
     821           0 :         Point aPnt(aPos);
     822           0 :         aPnt.X() += pList->m_aGreenCheckImg.GetSizePixel().Width();
     823           0 :         aPnt.X() += 10;
     824           0 :         rRenderContext.DrawText(aPnt, *pTxt);
     825             :     }
     826           0 : }
     827             : 
     828           0 : RecovDocList::RecovDocList(SvSimpleTableContainer& rParent, ResMgr &rResMgr)
     829             :     : SvSimpleTable      ( rParent )
     830             :     , m_aGreenCheckImg    ( ResId(RID_SVXIMG_GREENCHECK, rResMgr ) )
     831             :     , m_aYellowCheckImg   ( ResId(RID_SVXIMG_YELLOWCHECK, rResMgr ) )
     832             :     , m_aRedCrossImg      ( ResId(RID_SVXIMG_REDCROSS, rResMgr ) )
     833             :     , m_aSuccessRecovStr  ( ResId(RID_SVXSTR_SUCCESSRECOV, rResMgr ) )
     834             :     , m_aOrigDocRecovStr  ( ResId(RID_SVXSTR_ORIGDOCRECOV, rResMgr ) )
     835             :     , m_aRecovFailedStr   ( ResId(RID_SVXSTR_RECOVFAILED, rResMgr ) )
     836             :     , m_aRecovInProgrStr  ( ResId(RID_SVXSTR_RECOVINPROGR, rResMgr ) )
     837           0 :     , m_aNotRecovYetStr   ( ResId(RID_SVXSTR_NOTRECOVYET, rResMgr ) )
     838             : {
     839           0 : }
     840             : 
     841           0 : void RecovDocList::InitEntry(SvTreeListEntry* pEntry,
     842             :                              const OUString& rText,
     843             :                              const Image& rImage1,
     844             :                              const Image& rImage2,
     845             :                              SvLBoxButtonKind eButtonKind)
     846             : {
     847           0 :     SvTabListBox::InitEntry(pEntry, rText, rImage1, rImage2, eButtonKind);
     848             :     DBG_ASSERT( TabCount() == 2, "*RecovDocList::InitEntry(): structure missmatch" );
     849             : 
     850           0 :     SvLBoxString*       pCol = static_cast<SvLBoxString*>(pEntry->GetItem(2));
     851           0 :     RecovDocListEntry*  p    = new RecovDocListEntry(pEntry, 0, pCol->GetText());
     852           0 :     pEntry->ReplaceItem(p, 2);
     853           0 : }
     854             : 
     855             : 
     856           0 : short impl_askUserForWizardCancel(vcl::Window* pParent, sal_Int16 nRes)
     857             : {
     858           0 :     ScopedVclPtrInstance< MessageDialog > aQuery(pParent, SVX_RES(nRes), VCL_MESSAGE_QUESTION, VCL_BUTTONS_YES_NO);
     859           0 :     if (aQuery->Execute() == RET_YES)
     860           0 :         return DLG_RET_OK;
     861             :     else
     862           0 :         return DLG_RET_CANCEL;
     863             : }
     864             : 
     865           0 : RecoveryDialog::RecoveryDialog(vcl::Window* pParent, RecoveryCore* pCore)
     866             :     : Dialog(pParent, "DocRecoveryRecoverDialog",
     867             :         "svx/ui/docrecoveryrecoverdialog.ui")
     868           0 :     , m_aTitleRecoveryInProgress(SVX_RESSTR(RID_SVXSTR_RECOVERY_INPROGRESS))
     869           0 :     , m_aRecoveryOnlyFinish (SVX_RESSTR(RID_SVXSTR_RECOVERYONLY_FINISH))
     870           0 :     , m_aRecoveryOnlyFinishDescr(SVX_RESSTR(RID_SVXSTR_RECOVERYONLY_FINISH_DESCR))
     871             :     , m_pCore(pCore)
     872             :     , m_eRecoveryState(RecoveryDialog::E_RECOVERY_PREPARED)
     873             :     , m_bWaitForCore(false)
     874           0 :     , m_bWasRecoveryStarted(false)
     875             : {
     876           0 :     get(m_pTitleFT, "title");
     877           0 :     get(m_pDescrFT, "desc");
     878           0 :     get(m_pProgrParent, "progress");
     879           0 :     m_pProgrParent->set_height_request(LogicToPixel(Size(0, PROGR_HEIGHT), MAP_APPFONT).Height());
     880           0 :     get(m_pNextBtn, "next");
     881           0 :     get(m_pCancelBtn, "cancel");
     882             : 
     883           0 :     SvSimpleTableContainer* pFileListLBContainer = get<SvSimpleTableContainer>("filelist");
     884           0 :     Size aSize(LogicToPixel(Size(RECOV_CONTROLWIDTH, RECOV_FILELISTHEIGHT), MAP_APPFONT));
     885           0 :     pFileListLBContainer->set_width_request(aSize.Width());
     886           0 :     pFileListLBContainer->set_height_request(aSize.Height());
     887           0 :     m_pFileListLB = VclPtr<RecovDocList>::Create(*pFileListLBContainer, DIALOG_MGR());
     888             : 
     889             :     static long nTabs[] = { 2, 0, 40*RECOV_CONTROLWIDTH/100 };
     890           0 :     m_pFileListLB->SetTabs( &nTabs[0] );
     891           0 :     m_pFileListLB->InsertHeaderEntry(get<FixedText>("nameft")->GetText() + "\t" + get<FixedText>("statusft")->GetText());
     892             : 
     893           0 :     PluginProgress* pProgress   = new PluginProgress(m_pProgrParent, pCore->getComponentContext());
     894           0 :     m_xProgress = css::uno::Reference< css::task::XStatusIndicator >(static_cast< css::task::XStatusIndicator* >(pProgress), css::uno::UNO_QUERY_THROW);
     895             : 
     896           0 :     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
     897           0 :     m_pTitleFT->SetBackground(rStyleSettings.GetWindowColor());
     898           0 :     m_pTitleFT->set_height_request(m_pTitleFT->get_preferred_size().Height() + 48);
     899             : 
     900           0 :     m_pFileListLB->SetBackground( rStyleSettings.GetDialogColor() );
     901             : 
     902           0 :     m_pNextBtn->Enable(true);
     903           0 :     m_pNextBtn->SetClickHdl( LINK( this, RecoveryDialog, NextButtonHdl ) );
     904           0 :     m_pCancelBtn->SetClickHdl( LINK( this, RecoveryDialog, CancelButtonHdl ) );
     905             : 
     906             :     // fill list box first time
     907           0 :     TURLList&                pURLList = m_pCore->getURLListAccess();
     908           0 :     TURLList::const_iterator pIt;
     909           0 :     for (  pIt  = pURLList.begin();
     910           0 :            pIt != pURLList.end()  ;
     911             :          ++pIt                     )
     912             :     {
     913           0 :         const TURLInfo& rInfo = *pIt;
     914             : 
     915           0 :         OUString sName( rInfo.DisplayName );
     916           0 :         sName += "\t";
     917           0 :         sName += impl_getStatusString( rInfo );
     918           0 :         SvTreeListEntry* pEntry = m_pFileListLB->InsertEntry(sName, rInfo.StandardImage, rInfo.StandardImage);
     919           0 :         pEntry->SetUserData(const_cast<TURLInfo *>(&rInfo));
     920           0 :     }
     921             : 
     922             :     // mark first item
     923           0 :     SvTreeListEntry* pFirst = m_pFileListLB->First();
     924           0 :     if (pFirst)
     925           0 :         m_pFileListLB->SetCursor(pFirst, true);
     926           0 : }
     927             : 
     928           0 : RecoveryDialog::~RecoveryDialog()
     929             : {
     930           0 :     disposeOnce();
     931           0 : }
     932             : 
     933           0 : void RecoveryDialog::dispose()
     934             : {
     935           0 :     m_pFileListLB.disposeAndClear();
     936           0 :     m_pTitleFT.clear();
     937           0 :     m_pDescrFT.clear();
     938           0 :     m_pProgrParent.clear();
     939           0 :     m_pNextBtn.clear();
     940           0 :     m_pCancelBtn.clear();
     941           0 :     Dialog::dispose();
     942           0 : }
     943             : 
     944           0 : short RecoveryDialog::execute()
     945             : {
     946           0 :     ::SolarMutexGuard aSolarLock;
     947             : 
     948           0 :     switch (m_eRecoveryState)
     949             :     {
     950             :         case RecoveryDialog::E_RECOVERY_IN_PROGRESS :
     951             :              {
     952             :                 // user decided to start recovery ...
     953           0 :                 m_bWasRecoveryStarted = true;
     954             :                 // do it asynchronous (to allow repaints)
     955             :                 // and wait for this asynchronous operation.
     956           0 :                 m_pDescrFT->SetText( m_aTitleRecoveryInProgress );
     957           0 :                 m_pNextBtn->Enable(false);
     958           0 :                 m_pCancelBtn->Enable(false);
     959           0 :                 m_pCore->setProgressHandler(m_xProgress);
     960           0 :                 m_pCore->setUpdateListener(this);
     961           0 :                 m_pCore->doRecovery();
     962             : 
     963           0 :                 m_bWaitForCore = true;
     964           0 :                 while(m_bWaitForCore)
     965           0 :                     Application::Yield();
     966             : 
     967           0 :                 m_pCore->setUpdateListener(0);
     968           0 :                 m_eRecoveryState = RecoveryDialog::E_RECOVERY_CORE_DONE;
     969           0 :                 return execute();
     970             :              }
     971             : 
     972             :         case RecoveryDialog::E_RECOVERY_CORE_DONE :
     973             :              {
     974             :                  // the core finished it's task.
     975             :                  // let the user decide the next step.
     976           0 :                  m_pDescrFT->SetText(m_aRecoveryOnlyFinishDescr);
     977           0 :                  m_pNextBtn->SetText(m_aRecoveryOnlyFinish);
     978           0 :                  m_pNextBtn->Enable(true);
     979           0 :                  m_pCancelBtn->Enable(false);
     980           0 :                  return 0;
     981             :              }
     982             : 
     983             :         case RecoveryDialog::E_RECOVERY_DONE :
     984             :              {
     985             :                  // All documents was reovered.
     986             :                  // User decided to step to the "next" wizard page.
     987             :                  // Do it ... but check first, if there exist some
     988             :                  // failed recovery documents. They must be saved to
     989             :                  // a user selected directrory.
     990           0 :                  short                 nRet                  = DLG_RET_UNKNOWN;
     991           0 :                  ScopedVclPtrInstance< BrokenRecoveryDialog > pBrokenRecoveryDialog(this, m_pCore, !m_bWasRecoveryStarted);
     992           0 :                  OUString              sSaveDir              = pBrokenRecoveryDialog->getSaveDirURL(); // get the default dir
     993           0 :                  if (pBrokenRecoveryDialog->isExecutionNeeded())
     994             :                  {
     995           0 :                      nRet = pBrokenRecoveryDialog->Execute();
     996           0 :                      sSaveDir = pBrokenRecoveryDialog->getSaveDirURL();
     997             :                  }
     998           0 :                  pBrokenRecoveryDialog.reset();
     999             : 
    1000           0 :                  switch(nRet)
    1001             :                  {
    1002             :                      // no broken temp files exists
    1003             :                      // step to the next wizard page
    1004             :                      case DLG_RET_UNKNOWN :
    1005             :                           {
    1006           0 :                               m_eRecoveryState = RecoveryDialog::E_RECOVERY_HANDLED;
    1007           0 :                               return DLG_RET_OK;
    1008             :                           }
    1009             : 
    1010             :                      // user decided to save the broken temp files
    1011             :                      // do and forget it
    1012             :                      // step to the next wizard page
    1013             :                      case DLG_RET_OK :
    1014             :                           {
    1015           0 :                               m_pCore->saveBrokenTempEntries(sSaveDir);
    1016           0 :                               m_pCore->forgetBrokenTempEntries();
    1017           0 :                               m_eRecoveryState = RecoveryDialog::E_RECOVERY_HANDLED;
    1018           0 :                               return DLG_RET_OK;
    1019             :                           }
    1020             : 
    1021             :                      // user decided to ignore broken temp files.
    1022             :                      // Ask it again ... may be this decision was wrong.
    1023             :                      // Results:
    1024             :                      //     IGNORE => remove broken temp files
    1025             :                      //            => step to the next wizard page
    1026             :                      //     CANCEL => step back to the recovery page
    1027             :                      case DLG_RET_CANCEL :
    1028             :                           {
    1029             :                               // TODO ask user ...
    1030           0 :                               m_pCore->forgetBrokenTempEntries();
    1031           0 :                               m_eRecoveryState = RecoveryDialog::E_RECOVERY_HANDLED;
    1032           0 :                               return DLG_RET_OK;
    1033             :                           }
    1034             :                  }
    1035             : 
    1036           0 :                  m_eRecoveryState = RecoveryDialog::E_RECOVERY_HANDLED;
    1037           0 :                  return DLG_RET_OK;
    1038             :              }
    1039             : 
    1040             :         case RecoveryDialog::E_RECOVERY_CANCELED :
    1041             :              {
    1042             :                  // "YES" => break recovery
    1043             :                  // But there exist different states, where "cancel" can be called.
    1044             :                  // Handle it different.
    1045           0 :                  if (m_bWasRecoveryStarted)
    1046           0 :                      m_eRecoveryState = RecoveryDialog::E_RECOVERY_CANCELED_AFTERWARDS;
    1047             :                  else
    1048           0 :                      m_eRecoveryState = RecoveryDialog::E_RECOVERY_CANCELED_BEFORE;
    1049           0 :                  return execute();
    1050             :              }
    1051             : 
    1052             :         case RecoveryDialog::E_RECOVERY_CANCELED_BEFORE :
    1053             :         case RecoveryDialog::E_RECOVERY_CANCELED_AFTERWARDS :
    1054             :              {
    1055             :                  // We have to check if there exists some temp. files.
    1056             :                  // They should be saved to a user defined location.
    1057             :                  // If no temp files exists or user decided to ignore it ...
    1058             :                  // we have to remove all recovery/session data anyway!
    1059           0 :                  short                 nRet                  = DLG_RET_UNKNOWN;
    1060           0 :                  ScopedVclPtrInstance< BrokenRecoveryDialog > pBrokenRecoveryDialog(this, m_pCore, !m_bWasRecoveryStarted);
    1061           0 :                  OUString              sSaveDir              = pBrokenRecoveryDialog->getSaveDirURL(); // get the default save location
    1062             : 
    1063             :                  // dialog itself checks if there is a need to copy files for this mode.
    1064             :                  // It uses the information m_bWasRecoveryStarted doing so.
    1065           0 :                  if (pBrokenRecoveryDialog->isExecutionNeeded())
    1066             :                  {
    1067           0 :                      nRet     = pBrokenRecoveryDialog->Execute();
    1068           0 :                      sSaveDir = pBrokenRecoveryDialog->getSaveDirURL();
    1069             :                  }
    1070           0 :                  pBrokenRecoveryDialog.reset();
    1071             : 
    1072             :                  // Possible states:
    1073             :                  // a) nRet == DLG_RET_UNKNOWN
    1074             :                  //         dialog was not shown ...
    1075             :                  //         because there exists no temp file for copy.
    1076             :                  //         => remove all recovery data
    1077             :                  // b) nRet == DLG_RET_OK
    1078             :                  //         dialog was shown ...
    1079             :                  //         user decided to save temp files
    1080             :                  //         => save all OR broken temp files (depends from the time, where cancel was called)
    1081             :                  //         => remove all recovery data
    1082             :                  // c) nRet == DLG_RET_CANCEL
    1083             :                  //         dialog was shown ...
    1084             :                  //         user decided to ignore temp files
    1085             :                  //         => remove all recovery data
    1086             :                  // => a)/c) are the same ... b) has one additional operation
    1087             : 
    1088             :                  // b)
    1089           0 :                  if (nRet == DLG_RET_OK)
    1090             :                  {
    1091           0 :                      if (m_bWasRecoveryStarted)
    1092           0 :                          m_pCore->saveBrokenTempEntries(sSaveDir);
    1093             :                      else
    1094           0 :                          m_pCore->saveAllTempEntries(sSaveDir);
    1095             :                  }
    1096             : 
    1097             :                  // a,b,c)
    1098           0 :                  if (m_bWasRecoveryStarted)
    1099           0 :                     m_pCore->forgetBrokenRecoveryEntries();
    1100             :                  else
    1101           0 :                     m_pCore->forgetAllRecoveryEntries();
    1102           0 :                  m_eRecoveryState = RecoveryDialog::E_RECOVERY_HANDLED;
    1103             : 
    1104             :                  // THERE IS NO WAY BACK. see impl_askUserForWizardCancel()!
    1105           0 :                  return DLG_RET_CANCEL;
    1106             :              }
    1107             :     }
    1108             : 
    1109             :     // should never be reached .-)
    1110             :     OSL_FAIL("Should never be reached!");
    1111           0 :     return DLG_RET_OK;
    1112             : }
    1113             : 
    1114           0 : void RecoveryDialog::start()
    1115             : {
    1116           0 : }
    1117             : 
    1118           0 : void RecoveryDialog::updateItems()
    1119             : {
    1120           0 :     sal_uIntPtr c = m_pFileListLB->GetEntryCount();
    1121           0 :     sal_uIntPtr i = 0;
    1122           0 :     for ( i=0; i<c; ++i )
    1123             :     {
    1124           0 :         SvTreeListEntry* pEntry = m_pFileListLB->GetEntry(i);
    1125           0 :         if ( !pEntry )
    1126           0 :             continue;
    1127             : 
    1128           0 :         TURLInfo* pInfo = static_cast<TURLInfo*>(pEntry->GetUserData());
    1129           0 :         if ( !pInfo )
    1130           0 :             continue;
    1131             : 
    1132           0 :         OUString sStatus = impl_getStatusString( *pInfo );
    1133           0 :         if ( !sStatus.isEmpty() )
    1134           0 :             m_pFileListLB->SetEntryText( sStatus, pEntry, 1 );
    1135           0 :     }
    1136             : 
    1137           0 :     m_pFileListLB->Invalidate();
    1138           0 :     m_pFileListLB->Update();
    1139           0 : }
    1140             : 
    1141             : 
    1142           0 : void RecoveryDialog::stepNext(TURLInfo* pItem)
    1143             : {
    1144           0 :     sal_uIntPtr c = m_pFileListLB->GetEntryCount();
    1145           0 :     sal_uIntPtr i = 0;
    1146           0 :     for (i=0; i<c; ++i)
    1147             :     {
    1148           0 :         SvTreeListEntry* pEntry = m_pFileListLB->GetEntry(i);
    1149           0 :         if (!pEntry)
    1150           0 :             continue;
    1151             : 
    1152           0 :         TURLInfo* pInfo = static_cast<TURLInfo*>(pEntry->GetUserData());
    1153           0 :         if (pInfo->ID != pItem->ID)
    1154           0 :             continue;
    1155             : 
    1156           0 :         m_pFileListLB->SetCursor(pEntry, true);
    1157           0 :         m_pFileListLB->MakeVisible(pEntry);
    1158           0 :         m_pFileListLB->Invalidate();
    1159           0 :         m_pFileListLB->Update();
    1160           0 :         break;
    1161             :     }
    1162           0 : }
    1163             : 
    1164           0 : void RecoveryDialog::end()
    1165             : {
    1166           0 :     m_bWaitForCore = false;
    1167           0 : }
    1168             : 
    1169           0 : IMPL_LINK_NOARG(RecoveryDialog, NextButtonHdl)
    1170             : {
    1171           0 :     switch (m_eRecoveryState)
    1172             :     {
    1173             :         case RecoveryDialog::E_RECOVERY_PREPARED:
    1174           0 :             m_eRecoveryState = RecoveryDialog::E_RECOVERY_IN_PROGRESS;
    1175           0 :             execute();
    1176           0 :         break;
    1177             :         case RecoveryDialog::E_RECOVERY_CORE_DONE:
    1178           0 :             m_eRecoveryState = RecoveryDialog::E_RECOVERY_DONE;
    1179           0 :             execute();
    1180           0 :         break;
    1181             :     }
    1182             : 
    1183           0 :     if (m_eRecoveryState == RecoveryDialog::E_RECOVERY_HANDLED)
    1184             :     {
    1185           0 :         EndDialog(DLG_RET_OK);
    1186           0 :         return DLG_RET_OK;
    1187             :     }
    1188             : 
    1189           0 :     return 0;
    1190             : }
    1191             : 
    1192           0 : IMPL_LINK_NOARG(RecoveryDialog, CancelButtonHdl)
    1193             : {
    1194           0 :     switch (m_eRecoveryState)
    1195             :     {
    1196             :         case RecoveryDialog::E_RECOVERY_PREPARED:
    1197           0 :             if (impl_askUserForWizardCancel(this, RID_SVXSTR_QUERY_EXIT_RECOVERY) != DLG_RET_CANCEL)
    1198             :             {
    1199           0 :                 m_eRecoveryState = RecoveryDialog::E_RECOVERY_CANCELED;
    1200           0 :                 execute();
    1201             :             }
    1202           0 :             break;
    1203             :         case RecoveryDialog::E_RECOVERY_CORE_DONE:
    1204           0 :             m_eRecoveryState = RecoveryDialog::E_RECOVERY_CANCELED;
    1205           0 :             execute();
    1206           0 :             break;
    1207             :     }
    1208             : 
    1209           0 :     if (m_eRecoveryState == RecoveryDialog::E_RECOVERY_HANDLED)
    1210             :     {
    1211           0 :         EndDialog(DLG_RET_CANCEL);
    1212           0 :         return DLG_RET_CANCEL;
    1213             :     }
    1214             : 
    1215           0 :     return 0;
    1216             : }
    1217             : 
    1218           0 : OUString RecoveryDialog::impl_getStatusString( const TURLInfo& rInfo ) const
    1219             : {
    1220           0 :     OUString sStatus;
    1221           0 :     switch ( rInfo.RecoveryState )
    1222             :     {
    1223             :         case E_SUCCESSFULLY_RECOVERED :
    1224           0 :             sStatus = m_pFileListLB->m_aSuccessRecovStr;
    1225           0 :             break;
    1226             :         case E_ORIGINAL_DOCUMENT_RECOVERED :
    1227           0 :             sStatus = m_pFileListLB->m_aOrigDocRecovStr;
    1228           0 :             break;
    1229             :         case E_RECOVERY_FAILED :
    1230           0 :             sStatus = m_pFileListLB->m_aRecovFailedStr;
    1231           0 :             break;
    1232             :         case E_RECOVERY_IS_IN_PROGRESS :
    1233           0 :             sStatus = m_pFileListLB->m_aRecovInProgrStr;
    1234           0 :             break;
    1235             :         case E_NOT_RECOVERED_YET :
    1236           0 :             sStatus = m_pFileListLB->m_aNotRecovYetStr;
    1237           0 :             break;
    1238             :         default:
    1239           0 :             break;
    1240             :     }
    1241           0 :     return sStatus;
    1242             : }
    1243             : 
    1244           0 : BrokenRecoveryDialog::BrokenRecoveryDialog(vcl::Window*       pParent        ,
    1245             :                                            RecoveryCore* pCore          ,
    1246             :                                            bool      bBeforeRecovery)
    1247             :     : ModalDialog   ( pParent, "DocRecoveryBrokenDialog", "svx/ui/docrecoverybrokendialog.ui" )
    1248             :     , m_pCore       ( pCore                                               )
    1249             :     , m_bBeforeRecovery (bBeforeRecovery)
    1250           0 :     , m_bExecutionNeeded(false)
    1251             : {
    1252           0 :     get(m_pFileListLB, "filelist");
    1253           0 :     get(m_pSaveDirED, "savedir");
    1254           0 :     get(m_pSaveDirBtn, "change");
    1255           0 :     get(m_pOkBtn, "save");
    1256           0 :     get(m_pCancelBtn, "cancel");
    1257             : 
    1258           0 :     m_pSaveDirBtn->SetClickHdl( LINK( this, BrokenRecoveryDialog, SaveButtonHdl ) );
    1259           0 :     m_pOkBtn->SetClickHdl( LINK( this, BrokenRecoveryDialog, OkButtonHdl ) );
    1260           0 :     m_pCancelBtn->SetClickHdl( LINK( this, BrokenRecoveryDialog, CancelButtonHdl ) );
    1261             : 
    1262           0 :     m_sSavePath = SvtPathOptions().GetWorkPath();
    1263           0 :     INetURLObject aObj( m_sSavePath );
    1264           0 :     OUString sPath;
    1265           0 :     ::utl::LocalFileHelper::ConvertURLToSystemPath( aObj.GetMainURL( INetURLObject::NO_DECODE ), sPath );
    1266           0 :     m_pSaveDirED->SetText( sPath );
    1267             : 
    1268           0 :     impl_refresh();
    1269           0 : }
    1270             : 
    1271           0 : BrokenRecoveryDialog::~BrokenRecoveryDialog()
    1272             : {
    1273           0 :     disposeOnce();
    1274           0 : }
    1275             : 
    1276           0 : void BrokenRecoveryDialog::dispose()
    1277             : {
    1278           0 :     m_pFileListLB.clear();
    1279           0 :     m_pSaveDirED.clear();
    1280           0 :     m_pSaveDirBtn.clear();
    1281           0 :     m_pOkBtn.clear();
    1282           0 :     m_pCancelBtn.clear();
    1283           0 :     ModalDialog::dispose();
    1284           0 : }
    1285             : 
    1286             : 
    1287           0 : void BrokenRecoveryDialog::impl_refresh()
    1288             : {
    1289           0 :                              m_bExecutionNeeded = false;
    1290           0 :     TURLList&                pURLList           = m_pCore->getURLListAccess();
    1291           0 :     TURLList::const_iterator pIt;
    1292           0 :     for (  pIt  = pURLList.begin();
    1293           0 :            pIt != pURLList.end()  ;
    1294             :          ++pIt                     )
    1295             :     {
    1296           0 :         const TURLInfo& rInfo = *pIt;
    1297             : 
    1298           0 :         if (m_bBeforeRecovery)
    1299             :         {
    1300             :             // "Cancel" before recovery ->
    1301             :             // search for any temp files!
    1302           0 :             if (rInfo.TempURL.isEmpty())
    1303           0 :                 continue;
    1304             :         }
    1305             :         else
    1306             :         {
    1307             :             // "Cancel" after recovery ->
    1308             :             // search for broken temp files
    1309           0 :             if (!RecoveryCore::isBrokenTempEntry(rInfo))
    1310           0 :                 continue;
    1311             :         }
    1312             : 
    1313           0 :         m_bExecutionNeeded = true;
    1314             : 
    1315           0 :         sal_uInt16 nPos = m_pFileListLB->InsertEntry(rInfo.DisplayName, rInfo.StandardImage );
    1316           0 :         m_pFileListLB->SetEntryData( nPos, const_cast<TURLInfo *>(&rInfo) );
    1317             :     }
    1318           0 :     m_sSavePath.clear();
    1319           0 :     m_pOkBtn->GrabFocus();
    1320           0 : }
    1321             : 
    1322             : 
    1323           0 : bool BrokenRecoveryDialog::isExecutionNeeded()
    1324             : {
    1325           0 :     return m_bExecutionNeeded;
    1326             : }
    1327             : 
    1328             : 
    1329           0 : OUString BrokenRecoveryDialog::getSaveDirURL()
    1330             : {
    1331           0 :     return m_sSavePath;
    1332             : }
    1333             : 
    1334             : 
    1335           0 : IMPL_LINK_NOARG(BrokenRecoveryDialog, OkButtonHdl)
    1336             : {
    1337           0 :     OUString sPhysicalPath = comphelper::string::strip(m_pSaveDirED->GetText(), ' ');
    1338           0 :     OUString sURL;
    1339           0 :     ::utl::LocalFileHelper::ConvertPhysicalNameToURL( sPhysicalPath, sURL );
    1340           0 :     m_sSavePath = sURL;
    1341           0 :     while (m_sSavePath.isEmpty())
    1342           0 :         impl_askForSavePath();
    1343             : 
    1344           0 :     EndDialog(DLG_RET_OK);
    1345           0 :     return 0;
    1346             : }
    1347             : 
    1348             : 
    1349           0 : IMPL_LINK_NOARG(BrokenRecoveryDialog, CancelButtonHdl)
    1350             : {
    1351           0 :     EndDialog(DLG_RET_CANCEL);
    1352           0 :     return 0;
    1353             : }
    1354             : 
    1355             : 
    1356           0 : IMPL_LINK_NOARG(BrokenRecoveryDialog, SaveButtonHdl)
    1357             : {
    1358           0 :     impl_askForSavePath();
    1359           0 :     return 0;
    1360             : }
    1361             : 
    1362             : 
    1363           0 : void BrokenRecoveryDialog::impl_askForSavePath()
    1364             : {
    1365             :     css::uno::Reference< css::ui::dialogs::XFolderPicker2 > xFolderPicker =
    1366           0 :         css::ui::dialogs::FolderPicker::create( m_pCore->getComponentContext() );
    1367             : 
    1368           0 :     INetURLObject aURL(m_sSavePath, INetProtocol::File);
    1369           0 :     xFolderPicker->setDisplayDirectory(aURL.GetMainURL(INetURLObject::NO_DECODE));
    1370           0 :     short nRet = xFolderPicker->execute();
    1371           0 :     if (nRet == css::ui::dialogs::ExecutableDialogResults::OK)
    1372             :     {
    1373           0 :         m_sSavePath = xFolderPicker->getDirectory();
    1374           0 :         OUString sPath;
    1375           0 :         ::utl::LocalFileHelper::ConvertURLToSystemPath( m_sSavePath, sPath );
    1376           0 :         m_pSaveDirED->SetText( sPath );
    1377           0 :     }
    1378           0 : }
    1379             : 
    1380             :     }
    1381         390 : }
    1382             : 
    1383             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11