diff options
Diffstat (limited to 'svx/source/dialog/docrecovery.cxx')
-rw-r--r-- | svx/source/dialog/docrecovery.cxx | 2181 |
1 files changed, 2181 insertions, 0 deletions
diff --git a/svx/source/dialog/docrecovery.cxx b/svx/source/dialog/docrecovery.cxx new file mode 100644 index 000000000000..1b77364b6c7e --- /dev/null +++ b/svx/source/dialog/docrecovery.cxx @@ -0,0 +1,2181 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/dialmgr.hxx> + +#include <svx/dialogs.hrc> +#include "docrecovery.hxx" +#include "docrecovery.hrc" + +#include <comphelper/processfactory.hxx> +#include <comphelper/sequenceashashmap.hxx> +#include <comphelper/configurationhelper.hxx> +#include <svtools/imagemgr.hxx> +#include <svtools/xtextedt.hxx> +#include <tools/urlobj.hxx> +#include <vcl/msgbox.hxx> +#include <vcl/svapp.hxx> +#include <rtl/ustrbuf.hxx> +#include <vcl/scrbar.hxx> + +#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_ +#include <toolkit/unohlp.hxx> +#endif + +//#include "com/sun/star/lang/XMultiServiceFactory.hpp" +#include <com/sun/star/task/XStatusIndicatorFactory.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +//#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/util/URL.hpp> +#include <com/sun/star/util/XURLTransformer.hpp> +#include <com/sun/star/frame/XDispatch.hpp> +#include <com/sun/star/awt/XWindow.hpp> +#include <com/sun/star/ui/dialogs/XFolderPicker.hpp> +#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp> +#include <osl/file.hxx> +#include <osl/security.hxx> +#include <rtl/bootstrap.hxx> +#include <unotools/pathoptions.hxx> +#include <unotools/localfilehelper.hxx> + +#define RET_BACK 100 + +//=============================================== +// namespace +namespace svx{ + namespace DocRecovery{ + +namespace css = ::com::sun::star; + +using namespace ::rtl; +using namespace ::osl; + +//=============================================== +TabDialog4Recovery::TabDialog4Recovery(Window* pParent) + : TabDialog (pParent, SVX_RES( RID_SVX_TABDLG_DOCRECOVERY )) + , m_pActualPage(m_lTabPages.begin() ) +{ +} + +//=============================================== +TabDialog4Recovery::~TabDialog4Recovery() +{ + m_lTabPages.clear(); +} + +//=============================================== +void TabDialog4Recovery::addTabPage(IExtendedTabPage* pPage) +{ + if (pPage) + m_lTabPages.push_back(pPage); +} + +//=============================================== +short TabDialog4Recovery::Execute() +{ + ::vos::OGuard aLock(Application::GetSolarMutex()); + + Show(); + m_pActualPage = m_lTabPages.begin(); + while(sal_True) + { + IExtendedTabPage* pPage = *m_pActualPage; + SetViewWindow(pPage); + pPage->Show(); + pPage->setDefButton(); + short nRet = pPage->execute(); + pPage->Hide(); + + switch(nRet) + { + case DLG_RET_OK : + { + ++m_pActualPage; + if (m_pActualPage == m_lTabPages.end()) + return nRet; + } + break; + + case DLG_RET_BACK : + { + if (m_pActualPage != m_lTabPages.begin()) + --m_pActualPage; + } + break; + + case DLG_RET_UNKNOWN : + case DLG_RET_CANCEL : + case DLG_RET_OK_AUTOLUNCH : + return nRet; + } + } +} + +//=============================================== +RecoveryCore::RecoveryCore(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR , + sal_Bool bUsedForSaving) + : m_xSMGR ( xSMGR ) + , m_pListener ( 0 ) + , m_bListenForSaving(bUsedForSaving) +{ + impl_startListening(); +} + +//=============================================== +RecoveryCore::~RecoveryCore() +{ + impl_stopListening(); +} + +//=============================================== +css::uno::Reference< css::lang::XMultiServiceFactory > RecoveryCore::getSMGR() +{ + return m_xSMGR; +} + +//=============================================== +TURLList* RecoveryCore::getURLListAccess() +{ + return &m_lURLs; +} + +//=============================================== +sal_Bool RecoveryCore::existsBrokenTempEntries() +{ + TURLList::const_iterator pIt; + for ( pIt = m_lURLs.begin(); + pIt != m_lURLs.end() ; + ++pIt ) + { + const TURLInfo& rInfo = *pIt; + if (RecoveryCore::isBrokenTempEntry(rInfo)) + return sal_True; + } + + return sal_False; +} + +//=============================================== +sal_Bool RecoveryCore::existsNonRecoveredEntries() +{ + TURLList::const_iterator pIt; + for ( pIt = m_lURLs.begin(); + pIt != m_lURLs.end() ; + ++pIt ) + { + const TURLInfo& rInfo = *pIt; + if (rInfo.RecoveryState == E_NOT_RECOVERED_YET) + return sal_True; + } + + return sal_False; +} + +//=============================================== +sal_Bool RecoveryCore::isBrokenTempEntry(const TURLInfo& rInfo) +{ + if (!rInfo.TempURL.getLength()) + return sal_False; + + // Note: If the original files was recovery ... but a temp file + // exists ... an error inside the temp file exists! + if ( + !(rInfo.RecoveryState == E_RECOVERY_FAILED ) && + !(rInfo.RecoveryState == E_ORIGINAL_DOCUMENT_RECOVERED) + ) + return sal_False; + + return sal_True; +} + +//=============================================== +void RecoveryCore::saveBrokenTempEntries(const ::rtl::OUString& sPath) +{ + if (!sPath.getLength()) + return; + + if (!m_xRealCore.is()) + return; + + // prepare all needed parameters for the following dispatch() request. + css::util::URL aCopyURL = impl_getParsedURL(RECOVERY_CMD_DO_ENTRY_BACKUP); + css::uno::Sequence< css::beans::PropertyValue > lCopyArgs(3); + lCopyArgs[0].Name = PROP_DISPATCHASYNCHRON; + lCopyArgs[0].Value <<= sal_False; + lCopyArgs[1].Name = PROP_SAVEPATH; + lCopyArgs[1].Value <<= sPath; + lCopyArgs[2].Name = PROP_ENTRYID; + // lCopyArgs[2].Value will be changed during next loop ... + + // work on a copied list only ... + // Reason: We will get notifications from the core for every + // changed or removed element. And that will change our m_lURLs list. + // That's not a good idea, if we use a stl iterator inbetween .-) + TURLList lURLs = m_lURLs; + TURLList::const_iterator pIt; + for ( pIt = lURLs.begin(); + pIt != lURLs.end() ; + ++pIt ) + { + const TURLInfo& rInfo = *pIt; + if (!RecoveryCore::isBrokenTempEntry(rInfo)) + continue; + + lCopyArgs[2].Value <<= rInfo.ID; + m_xRealCore->dispatch(aCopyURL, lCopyArgs); + } +} + +//=============================================== +void RecoveryCore::saveAllTempEntries(const ::rtl::OUString& sPath) +{ + if (!sPath.getLength()) + return; + + if (!m_xRealCore.is()) + return; + + // prepare all needed parameters for the following dispatch() request. + css::util::URL aCopyURL = impl_getParsedURL(RECOVERY_CMD_DO_ENTRY_BACKUP); + css::uno::Sequence< css::beans::PropertyValue > lCopyArgs(3); + lCopyArgs[0].Name = PROP_DISPATCHASYNCHRON; + lCopyArgs[0].Value <<= sal_False; + lCopyArgs[1].Name = PROP_SAVEPATH; + lCopyArgs[1].Value <<= sPath; + lCopyArgs[2].Name = PROP_ENTRYID; + // lCopyArgs[2].Value will be changed during next loop ... + + // work on a copied list only ... + // Reason: We will get notifications from the core for every + // changed or removed element. And that will change our m_lURLs list. + // That's not a good idea, if we use a stl iterator inbetween .-) + TURLList lURLs = m_lURLs; + TURLList::const_iterator pIt; + for ( pIt = lURLs.begin(); + pIt != lURLs.end() ; + ++pIt ) + { + const TURLInfo& rInfo = *pIt; + if (!rInfo.TempURL.getLength()) + continue; + + lCopyArgs[2].Value <<= rInfo.ID; + m_xRealCore->dispatch(aCopyURL, lCopyArgs); + } +} + +//=============================================== +void RecoveryCore::forgetBrokenTempEntries() +{ + if (!m_xRealCore.is()) + return; + + css::util::URL aRemoveURL = impl_getParsedURL(RECOVERY_CMD_DO_ENTRY_CLEANUP); + css::uno::Sequence< css::beans::PropertyValue > lRemoveArgs(2); + lRemoveArgs[0].Name = PROP_DISPATCHASYNCHRON; + lRemoveArgs[0].Value <<= sal_False; + lRemoveArgs[1].Name = PROP_ENTRYID; + // lRemoveArgs[1].Value will be changed during next loop ... + + // work on a copied list only ... + // Reason: We will get notifications from the core for every + // changed or removed element. And that will change our m_lURLs list. + // That's not a good idea, if we use a stl iterator inbetween .-) + TURLList lURLs = m_lURLs; + TURLList::const_iterator pIt; + for ( pIt = lURLs.begin(); + pIt != lURLs.end() ; + ++pIt ) + { + const TURLInfo& rInfo = *pIt; + if (!RecoveryCore::isBrokenTempEntry(rInfo)) + continue; + + lRemoveArgs[1].Value <<= rInfo.ID; + m_xRealCore->dispatch(aRemoveURL, lRemoveArgs); + } +} + +//=============================================== +void RecoveryCore::forgetAllRecoveryEntries() +{ + if (!m_xRealCore.is()) + return; + + css::util::URL aRemoveURL = impl_getParsedURL(RECOVERY_CMD_DO_ENTRY_CLEANUP); + css::uno::Sequence< css::beans::PropertyValue > lRemoveArgs(2); + lRemoveArgs[0].Name = PROP_DISPATCHASYNCHRON; + lRemoveArgs[0].Value <<= sal_False; + lRemoveArgs[1].Name = PROP_ENTRYID; + // lRemoveArgs[1].Value will be changed during next loop ... + + // work on a copied list only ... + // Reason: We will get notifications from the core for every + // changed or removed element. And that will change our m_lURLs list. + // That's not a good idea, if we use a stl iterator inbetween .-) + TURLList lURLs = m_lURLs; + TURLList::const_iterator pIt; + for ( pIt = lURLs.begin(); + pIt != lURLs.end() ; + ++pIt ) + { + const TURLInfo& rInfo = *pIt; + lRemoveArgs[1].Value <<= rInfo.ID; + m_xRealCore->dispatch(aRemoveURL, lRemoveArgs); + } +} + +//=============================================== +void RecoveryCore::forgetBrokenRecoveryEntries() +{ + if (!m_xRealCore.is()) + return; + + css::util::URL aRemoveURL = impl_getParsedURL(RECOVERY_CMD_DO_ENTRY_CLEANUP); + css::uno::Sequence< css::beans::PropertyValue > lRemoveArgs(2); + lRemoveArgs[0].Name = PROP_DISPATCHASYNCHRON; + lRemoveArgs[0].Value <<= sal_False; + lRemoveArgs[1].Name = PROP_ENTRYID; + // lRemoveArgs[1].Value will be changed during next loop ... + + // work on a copied list only ... + // Reason: We will get notifications from the core for every + // changed or removed element. And that will change our m_lURLs list. + // That's not a good idea, if we use a stl iterator inbetween .-) + TURLList lURLs = m_lURLs; + TURLList::const_iterator pIt; + for ( pIt = lURLs.begin(); + pIt != lURLs.end() ; + ++pIt ) + { + const TURLInfo& rInfo = *pIt; + if (!RecoveryCore::isBrokenTempEntry(rInfo)) + continue; + + lRemoveArgs[1].Value <<= rInfo.ID; + m_xRealCore->dispatch(aRemoveURL, lRemoveArgs); + } +} + +//=============================================== +void RecoveryCore::setProgressHandler(const css::uno::Reference< css::task::XStatusIndicator >& xProgress) +{ + m_xProgress = xProgress; +} + +//=============================================== +void RecoveryCore::setUpdateListener(IRecoveryUpdateListener* pListener) +{ + m_pListener = pListener; +} + +//=============================================== +void RecoveryCore::doEmergencySavePrepare() +{ + if (!m_xRealCore.is()) + return; + + css::util::URL aURL = impl_getParsedURL(RECOVERY_CMD_DO_PREPARE_EMERGENCY_SAVE); + + css::uno::Sequence< css::beans::PropertyValue > lArgs(1); + lArgs[0].Name = PROP_DISPATCHASYNCHRON; + lArgs[0].Value <<= sal_False; + + m_xRealCore->dispatch(aURL, lArgs); +} + +//=============================================== +void RecoveryCore::doEmergencySave() +{ + if (!m_xRealCore.is()) + return; + + css::util::URL aURL = impl_getParsedURL(RECOVERY_CMD_DO_EMERGENCY_SAVE); + + css::uno::Sequence< css::beans::PropertyValue > lArgs(2); + lArgs[0].Name = PROP_STATUSINDICATOR; + lArgs[0].Value <<= m_xProgress; + lArgs[1].Name = PROP_DISPATCHASYNCHRON; + lArgs[1].Value <<= sal_True; + + m_xRealCore->dispatch(aURL, lArgs); +} + +//=============================================== +void RecoveryCore::doRecovery() +{ + if (!m_xRealCore.is()) + return; + + css::util::URL aURL = impl_getParsedURL(RECOVERY_CMD_DO_RECOVERY); + + css::uno::Sequence< css::beans::PropertyValue > lArgs(2); + lArgs[0].Name = PROP_STATUSINDICATOR; + lArgs[0].Value <<= m_xProgress; + lArgs[1].Name = PROP_DISPATCHASYNCHRON; + lArgs[1].Value <<= sal_True; + + m_xRealCore->dispatch(aURL, lArgs); +} + +//=============================================== +ERecoveryState RecoveryCore::mapDocState2RecoverState(sal_Int32 eDocState) +{ + // ??? + ERecoveryState eRecState = E_NOT_RECOVERED_YET; + + /* Attention: + Some of the following states can occure at the + same time. So we have to check for the "worst case" first! + + DAMAGED -> INCOMPLETE -> HANDLED + */ + + // running ... + if ( + ((eDocState & E_TRY_LOAD_BACKUP ) == E_TRY_LOAD_BACKUP ) || + ((eDocState & E_TRY_LOAD_ORIGINAL) == E_TRY_LOAD_ORIGINAL) + ) + eRecState = E_RECOVERY_IS_IN_PROGRESS; + // red + else + if ((eDocState & E_DAMAGED) == E_DAMAGED) + eRecState = E_RECOVERY_FAILED; + // yellow + else + if ((eDocState & E_INCOMPLETE) == E_INCOMPLETE) + eRecState = E_ORIGINAL_DOCUMENT_RECOVERED; + // green + else + if ((eDocState & E_SUCCEDED) == E_SUCCEDED) + eRecState = E_SUCCESSFULLY_RECOVERED; + + return eRecState; +} + +//=============================================== +void SAL_CALL RecoveryCore::statusChanged(const css::frame::FeatureStateEvent& aEvent) + throw(css::uno::RuntimeException) +{ + // a) special notification about start/stop async dispatch! + // FeatureDescriptor = "start" || "stop" + if (aEvent.FeatureDescriptor.equals(RECOVERY_OPERATIONSTATE_START)) + { + if (m_pListener) + m_pListener->start(); + return; + } + + if (aEvent.FeatureDescriptor.equals(RECOVERY_OPERATIONSTATE_STOP)) + { + if (m_pListener) + m_pListener->end(); + return; + } + + // b) normal notification about changed items + // FeatureDescriptor = "Update" + // State = Lits of informations [seq< NamedValue >] + if (! aEvent.FeatureDescriptor.equals(RECOVERY_OPERATIONSTATE_UPDATE)) + return; + + ::comphelper::SequenceAsHashMap lInfo(aEvent.State); + TURLInfo aNew; + + aNew.ID = lInfo.getUnpackedValueOrDefault(STATEPROP_ID , (sal_Int32)0 ); + aNew.DocState = lInfo.getUnpackedValueOrDefault(STATEPROP_STATE , (sal_Int32)0 ); + aNew.OrgURL = lInfo.getUnpackedValueOrDefault(STATEPROP_ORGURL , ::rtl::OUString()); + aNew.TempURL = lInfo.getUnpackedValueOrDefault(STATEPROP_TEMPURL , ::rtl::OUString()); + aNew.FactoryURL = lInfo.getUnpackedValueOrDefault(STATEPROP_FACTORYURL , ::rtl::OUString()); + aNew.TemplateURL = lInfo.getUnpackedValueOrDefault(STATEPROP_TEMPLATEURL, ::rtl::OUString()); + aNew.DisplayName = lInfo.getUnpackedValueOrDefault(STATEPROP_TITLE , ::rtl::OUString()); + aNew.Module = lInfo.getUnpackedValueOrDefault(STATEPROP_MODULE , ::rtl::OUString()); + + // search for already existing items and update her nState value ... + TURLList::iterator pIt; + for ( pIt = m_lURLs.begin(); + pIt != m_lURLs.end() ; + ++pIt ) + { + TURLInfo& aOld = *pIt; + if (aOld.ID == aNew.ID) + { + // change existing + aOld.DocState = aNew.DocState; + aOld.RecoveryState = RecoveryCore::mapDocState2RecoverState(aOld.DocState); + if (m_pListener) + { + m_pListener->updateItems(); + m_pListener->stepNext(&aOld); + } + return; + } + } + + // append as new one + // TODO think about mmatching Module name to a corresponding icon + String sURL = aNew.OrgURL; + if (!sURL.Len()) + sURL = aNew.FactoryURL; + if (!sURL.Len()) + sURL = aNew.TempURL; + if (!sURL.Len()) + sURL = aNew.TemplateURL; + INetURLObject aURL(sURL); + aNew.StandardImage = SvFileInformationManager::GetFileImage(aURL, false, false); + aNew.HCImage = SvFileInformationManager::GetFileImage(aURL, false, true ); + + /* set the right UI state for this item to NOT_RECOVERED_YET ... because nDocState shows the state of + the last emergency save operation before and is interessting for the used recovery core service only ... + for now! But if there is a further notification for this item (see lines above!) we must + map the doc state to an UI state. */ + aNew.RecoveryState = E_NOT_RECOVERED_YET; + + // patch DisplayName! Because the document title contain more then the file name ... + sal_Int32 i = aNew.DisplayName.indexOf(::rtl::OUString::createFromAscii(" - ")); + if (i > 0) + aNew.DisplayName = aNew.DisplayName.copy(0, i); + + m_lURLs.push_back(aNew); + + if (m_pListener) + m_pListener->updateItems(); +} + +//=============================================== +void SAL_CALL RecoveryCore::disposing(const css::lang::EventObject& /*aEvent*/) + throw(css::uno::RuntimeException) +{ + m_xRealCore.clear(); +} + +//=============================================== +void RecoveryCore::impl_startListening() +{ + // listening already initialized ? + if (m_xRealCore.is()) + return; + m_xRealCore = css::uno::Reference< css::frame::XDispatch >(m_xSMGR->createInstance(SERVICENAME_RECOVERYCORE), css::uno::UNO_QUERY_THROW); + + css::util::URL aURL; + if (m_bListenForSaving) + aURL.Complete = RECOVERY_CMD_DO_EMERGENCY_SAVE; + else + aURL.Complete = RECOVERY_CMD_DO_RECOVERY; + css::uno::Reference< css::util::XURLTransformer > xParser(m_xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY_THROW); + xParser->parseStrict(aURL); + + /* Note: addStatusListener() call us synchronous back ... so we + will get the complete list of currently open documents! */ + m_xRealCore->addStatusListener(static_cast< css::frame::XStatusListener* >(this), aURL); +} + +//=============================================== +void RecoveryCore::impl_stopListening() +{ + // Ignore it, if this instance doesnt listen currently + if (!m_xRealCore.is()) + return; + + css::util::URL aURL; + if (m_bListenForSaving) + aURL.Complete = RECOVERY_CMD_DO_EMERGENCY_SAVE; + else + aURL.Complete = RECOVERY_CMD_DO_RECOVERY; + css::uno::Reference< css::util::XURLTransformer > xParser(m_xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY_THROW); + xParser->parseStrict(aURL); + + m_xRealCore->removeStatusListener(static_cast< css::frame::XStatusListener* >(this), aURL); + m_xRealCore.clear(); +} + +//=============================================== +css::util::URL RecoveryCore::impl_getParsedURL(const ::rtl::OUString& sURL) +{ + css::util::URL aURL; + aURL.Complete = sURL; + + css::uno::Reference< css::util::XURLTransformer > xParser(m_xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY_THROW); + xParser->parseStrict(aURL); + + return aURL; +} + +//=============================================== +PluginProgressWindow::PluginProgressWindow( Window* pParent , + const css::uno::Reference< css::lang::XComponent >& xProgress) + : Window (pParent ) + , m_xProgress(xProgress) +{ + Show(); + Size aParentSize = pParent->GetSizePixel(); + // align the progressbar to its parent + SetPosSizePixel( -9, 0, aParentSize.Width() + 15, aParentSize.Height() - 4 ); +} + +//=============================================== +PluginProgressWindow::~PluginProgressWindow() +{ + if (m_xProgress.is()) + m_xProgress->dispose(); +} + +//=============================================== +PluginProgress::PluginProgress( Window* pParent, + const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ) +{ + m_pPlugProgressWindow = new PluginProgressWindow(pParent, static_cast< css::lang::XComponent* >(this)); + css::uno::Reference< css::awt::XWindow > xProgressWindow = VCLUnoHelper::GetInterface(m_pPlugProgressWindow); + m_xProgressFactory = css::uno::Reference< css::task::XStatusIndicatorFactory >(xSMGR->createInstance(SERVICENAME_PROGRESSFACTORY), css::uno::UNO_QUERY_THROW); + css::uno::Reference< css::lang::XInitialization > xInit(m_xProgressFactory, css::uno::UNO_QUERY_THROW); + + css::uno::Sequence< css::uno::Any > lArgs(2); + css::beans::NamedValue aProp; + aProp.Name = PROP_PARENTWINDOW; + aProp.Value <<= xProgressWindow; + lArgs[0] <<= aProp; + aProp.Name = PROP_ALLOWPARENTSHOW; + aProp.Value <<= sal_True; + lArgs[1] <<= aProp; + + xInit->initialize(lArgs); + + m_xProgress = m_xProgressFactory->createStatusIndicator(); +} + +//=============================================== +PluginProgress::~PluginProgress() +{ +} + +//=============================================== +Window* PluginProgress::getPlugWindow() +{ + return m_pPlugProgressWindow; +} + +//=============================================== +void SAL_CALL PluginProgress::dispose() + throw(css::uno::RuntimeException) +{ + // m_pPluginProgressWindow was deleted ... + // So the internal pointer of this progress + // weill be dead! + m_xProgress.clear(); +} + +//=============================================== +void SAL_CALL PluginProgress::addEventListener(const css::uno::Reference< css::lang::XEventListener >& ) + throw(css::uno::RuntimeException) +{ +} + +//=============================================== +void SAL_CALL PluginProgress::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& ) + throw(css::uno::RuntimeException) +{ +} + +//=============================================== +void SAL_CALL PluginProgress::start(const ::rtl::OUString&, + sal_Int32 nRange) + throw(css::uno::RuntimeException) +{ + if (m_xProgress.is()) + m_xProgress->start(::rtl::OUString(), nRange); +} + +//=============================================== +void SAL_CALL PluginProgress::end() + throw(css::uno::RuntimeException) +{ + if (m_xProgress.is()) + m_xProgress->end(); +} + +//=============================================== +void SAL_CALL PluginProgress::setText(const ::rtl::OUString& sText) + throw(css::uno::RuntimeException) +{ + if (m_xProgress.is()) + m_xProgress->setText(sText); +} + +//=============================================== +void SAL_CALL PluginProgress::setValue(sal_Int32 nValue) + throw(css::uno::RuntimeException) +{ + if (m_xProgress.is()) + m_xProgress->setValue(nValue); +} + +//=============================================== +void SAL_CALL PluginProgress::reset() + throw(css::uno::RuntimeException) +{ + if (m_xProgress.is()) + m_xProgress->reset(); +} + +//=============================================== +SaveDialog::SaveDialog(Window* pParent, + RecoveryCore* pCore ) + : IExtendedTabPage( pParent, SVX_RES( RID_SVXPAGE_DOCRECOVERY_SAVE ) ) + , m_aTitleWin ( this , SVX_RES ( WIN_SAVE_TITLE ) ) + , m_aTitleFT ( this , SVX_RES ( FT_SAVE_TITLE ) ) + , m_aTitleFL ( this , SVX_RES ( FL_SAVE_TITLE ) ) + , m_aDescrFT ( this , SVX_RES ( FT_SAVE_DESCR ) ) + , m_aFileListFT ( this , SVX_RES ( FT_SAVE_FILELIST ) ) + , m_aFileListLB ( this , SVX_RES ( LB_SAVE_FILELIST ) ) + , m_aBottomFL ( this , SVX_RES ( FL_SAVE_BOTTOM ) ) + , m_aOkBtn ( this , SVX_RES ( BT_SAVE_OK ) ) + , m_pCore ( pCore ) +{ + FreeResource(); + + // Prepare the office for the following crash save step. + // E.g. hide all open widows so the user cant influence our + // operation .-) + m_pCore->doEmergencySavePrepare(); + + const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); + Wallpaper aBackground(rStyleSettings.GetWindowColor()); + m_aTitleWin.SetBackground(aBackground); + m_aTitleFT.SetBackground (aBackground); + + Font aFont(m_aTitleFT.GetFont()); + aFont.SetWeight(WEIGHT_BOLD); + m_aTitleFT.SetFont(aFont); + + m_aOkBtn.SetClickHdl( LINK( this, SaveDialog, OKButtonHdl ) ); +// m_aFileListLB.EnableInput( sal_False ); + m_aFileListLB.SetControlBackground( rStyleSettings.GetDialogColor() ); + + // fill listbox with current open documents + m_aFileListLB.Clear(); + + TURLList* pURLs = m_pCore->getURLListAccess(); + TURLList::const_iterator pIt; + + for ( pIt = pURLs->begin(); + pIt != pURLs->end() ; + ++pIt ) + { + const TURLInfo& rInfo = *pIt; + m_aFileListLB.InsertEntry( rInfo.DisplayName, rInfo.StandardImage ); + } +} + +//=============================================== +SaveDialog::~SaveDialog() +{ +} + +//=============================================== +IMPL_LINK( SaveDialog, OKButtonHdl, void*, EMPTYARG ) +{ + m_nResult = DLG_RET_OK; + return 0; +} + +//=============================================== +short SaveDialog::execute() +{ + ::vos::OGuard aLock(Application::GetSolarMutex()); + + // wait for user input "OK" + m_nResult = DLG_RET_UNKNOWN; + while(m_nResult == DLG_RET_UNKNOWN) + Application::Yield(); + + // start crash-save with progress + if (m_nResult == DLG_RET_OK) + { + SaveProgressDialog* pProgress = new SaveProgressDialog(this, m_pCore); + m_nResult = pProgress->Execute(); + delete pProgress; + } + // if "CANCEL" => return "CANCEL" + // if "OK" => "AUTOLUNCH" always ! + if (m_nResult == DLG_RET_OK) + m_nResult = DLG_RET_OK_AUTOLUNCH; + + return m_nResult; +} + +//=============================================== +void SaveDialog::setDefButton() +{ + m_aOkBtn.GrabFocus(); +} + +//=============================================== +SaveProgressDialog::SaveProgressDialog(Window* pParent, + RecoveryCore* pCore ) + : ModalDialog ( pParent , SVX_RES( RID_SVX_MDLG_DOCRECOVERY_PROGR ) ) + , m_aHintFT ( this , SVX_RES ( FT_SAVEPROGR_HINT ) ) + , m_aProgrFT ( this , SVX_RES ( FT_SAVEPROGR_PROGR ) ) + , m_aProgrParent( this , SVX_RES ( WIN_SAVEPROGR_PROGR ) ) + , m_pCore ( pCore ) +{ + FreeResource(); + PluginProgress* pProgress = new PluginProgress( &m_aProgrParent, pCore->getSMGR() ); + m_xProgress = css::uno::Reference< css::task::XStatusIndicator >(static_cast< css::task::XStatusIndicator* >(pProgress), css::uno::UNO_QUERY_THROW); +// m_aProgrBaseTxt = m_aProgrFT.GetText(); +} + +//=============================================== +SaveProgressDialog::~SaveProgressDialog() +{ +} + +//=============================================== +short SaveProgressDialog::Execute() +{ + ::vos::OGuard aLock(Application::GetSolarMutex()); + + m_pCore->setProgressHandler(m_xProgress); + m_pCore->setUpdateListener(this); + m_pCore->doEmergencySave(); + short nRet = ModalDialog::Execute(); + m_pCore->setUpdateListener(0); + return nRet; +} + +//=============================================== +void SaveProgressDialog::updateItems() +{ +} + +//=============================================== +void SaveProgressDialog::stepNext(TURLInfo* ) +{ + /* TODO + + wenn die m_pCore noch ein Member m_nCurrentItem haette + koennte man dort erkennen, wer gerade drann war, wer demnaechst + dran ist ... Diese Info kann man dann in unserem Progress FixText anzeigen ... + */ +} + +//=============================================== +void SaveProgressDialog::start() +{ +} + +//=============================================== +void SaveProgressDialog::end() +{ + EndDialog(DLG_RET_OK); +} + +//=============================================== +RecovDocListEntry::RecovDocListEntry( SvLBoxEntry* pEntry, + USHORT nFlags, + const String& sText ) + : SvLBoxString( pEntry, nFlags, sText ) +{ +} + +//=============================================== +void RecovDocListEntry::Paint(const Point& aPos , + SvLBox& aDevice, + USHORT /*nFlags */, + SvLBoxEntry* pEntry ) +{ + const Image* pImg = 0; + const String* pTxt = 0; + RecovDocList* pList = static_cast< RecovDocList* >(&aDevice); + + BOOL bHC = aDevice.GetSettings().GetStyleSettings().GetHighContrastMode(); + + TURLInfo* pInfo = (TURLInfo*)pEntry->GetUserData(); + switch(pInfo->RecoveryState) + { + case E_SUCCESSFULLY_RECOVERED : + { + pImg = &pList->m_aGreenCheckImg; + if (bHC) + pImg = &pList->m_aGreenCheckImgHC; + pTxt = &pList->m_aSuccessRecovStr; + } + break; + + case E_ORIGINAL_DOCUMENT_RECOVERED : // TODO must be renamed into ORIGINAL DOCUMENT recovered! Because its marked as yellow + { + pImg = &pList->m_aYellowCheckImg; + if (bHC) + pImg = &pList->m_aYellowCheckImgHC; + pTxt = &pList->m_aOrigDocRecovStr; + } + break; + + case E_RECOVERY_FAILED : + { + pImg = &pList->m_aRedCrossImg; + if (bHC) + pImg = &pList->m_aRedCrossImgHC; + pTxt = &pList->m_aRecovFailedStr; + } + break; + + case E_RECOVERY_IS_IN_PROGRESS : + { + pImg = 0; + pTxt = &pList->m_aRecovInProgrStr; + } + break; + + case E_NOT_RECOVERED_YET : + { + pImg = 0; + pTxt = &pList->m_aNotRecovYetStr; + } + break; + } + + if (pImg) + aDevice.DrawImage(aPos, *pImg); + + if (pTxt) + { + ::rtl::OUString sT1(*pTxt); + + Point aPnt(aPos); + aPnt.X() += pList->m_aGreenCheckImg.GetSizePixel().Width(); + aPnt.X() += 10; + aDevice.DrawText(aPnt, *pTxt); + } +} +//=============================================== +RecovDocList::RecovDocList( Window* pParent, + const ResId& rResId ) + : SvxSimpleTable ( pParent, rResId ) + , m_aGreenCheckImg ( ResId(IMG_GREENCHECK,*rResId.GetResMgr() ) ) + , m_aYellowCheckImg ( ResId(IMG_YELLOWCHECK,*rResId.GetResMgr() ) ) + , m_aRedCrossImg ( ResId(IMG_REDCROSS,*rResId.GetResMgr() ) ) + , m_aGreenCheckImgHC ( ResId(IMG_GREENCHECK_HC,*rResId.GetResMgr() ) ) + , m_aYellowCheckImgHC ( ResId(IMG_YELLOWCHECK_HC,*rResId.GetResMgr() ) ) + , m_aRedCrossImgHC ( ResId(IMG_REDCROSS_HC,*rResId.GetResMgr() ) ) + , m_aSuccessRecovStr ( ResId(STR_SUCCESSRECOV,*rResId.GetResMgr() ) ) + , m_aOrigDocRecovStr ( ResId(STR_ORIGDOCRECOV,*rResId.GetResMgr() ) ) + , m_aRecovFailedStr ( ResId(STR_RECOVFAILED,*rResId.GetResMgr() ) ) + , m_aRecovInProgrStr ( ResId(STR_RECOVINPROGR,*rResId.GetResMgr() ) ) + , m_aNotRecovYetStr ( ResId(STR_NOTRECOVYET,*rResId.GetResMgr() ) ) +{ + //SetEntryHeight( short( maGreenCheckImg.GetSizePixel().Height() ) ); +} + +//=============================================== +RecovDocList::~RecovDocList() +{ +} + +//=============================================== +void RecovDocList::InitEntry( SvLBoxEntry* pEntry , + const XubString& sText , + const Image& aImage1, + const Image& aImage2, + SvLBoxButtonKind eButtonKind) +{ + SvTabListBox::InitEntry(pEntry, sText, aImage1, aImage2, eButtonKind); + DBG_ASSERT( TabCount() == 2, "*RecovDocList::InitEntry(): structure missmatch" ); + + SvLBoxString* pCol = (SvLBoxString*)pEntry->GetItem(2); + RecovDocListEntry* p = new RecovDocListEntry(pEntry, 0, pCol->GetText()); + pEntry->ReplaceItem(p, 2); +} + +//=============================================== +short impl_askUserForWizardCancel(Window* pParent, sal_Int16 nRes) +{ + QueryBox aQuery(pParent, SVX_RES(nRes)); + if (aQuery.Execute() == RET_YES) + return DLG_RET_OK; + else + return DLG_RET_CANCEL; +} + +//=============================================== +RecoveryDialog::RecoveryDialog(Window* pParent, + RecoveryCore* pCore ) + : IExtendedTabPage( pParent , SVX_RES( RID_SVXPAGE_DOCRECOVERY_RECOVER ) ) + , m_aTitleWin ( this , SVX_RES ( WIN_RECOV_TITLE ) ) + , m_aTitleFT ( this , SVX_RES ( FT_RECOV_TITLE ) ) + , m_aTitleFL ( this , SVX_RES ( FL_RECOV_TITLE ) ) + , m_aDescrFT ( this , SVX_RES ( FT_RECOV_DESCR ) ) + , m_aProgressFT ( this , SVX_RES ( FT_RECOV_PROGR ) ) + , m_aProgrParent ( this , SVX_RES ( WIN_RECOV_PROGR ) ) + , m_aFileListFT ( this , SVX_RES ( FT_RECOV_FILELIST ) ) + , m_aFileListLB ( this , SVX_RES ( LB_RECOV_FILELIST ) ) + , m_aBottomFL ( this , SVX_RES ( FL_RECOV_BOTTOM ) ) + , m_aNextBtn ( this , SVX_RES ( BTN_RECOV_NEXT ) ) + , m_aCancelBtn ( this , SVX_RES ( BTN_RECOV_CANCEL ) ) + , m_aNextStr ( SVX_RES ( STR_RECOVERY_NEXT ) ) + , m_aTitleRecoveryInProgress( SVX_RES ( STR_RECOVERY_INPROGRESS ) ) + , m_aTitleRecoveryReport( SVX_RES ( STR_RECOVERY_REPORT ) ) + , m_aRecoveryOnlyFinish ( SVX_RES ( STR_RECOVERYONLY_FINISH ) ) + , m_aRecoveryOnlyFinishDescr( SVX_RES ( STR_RECOVERYONLY_FINISH_DESCR ) ) + , m_pDefButton ( NULL ) + , m_pCore ( pCore ) + , m_eRecoveryState (RecoveryDialog::E_RECOVERY_PREPARED) + , m_bWaitForUser (sal_False) + , m_bWaitForCore (sal_False) + , m_bUserDecideNext (sal_False) + , m_bWasRecoveryStarted (sal_False) + , m_bRecoveryOnly (sal_False) +{ + static long nTabs[] = { 2, 0, 40*RECOV_CONTROLWIDTH/100 }; + m_aFileListLB.SetTabs( &nTabs[0] ); + m_aFileListLB.InsertHeaderEntry( String( SVX_RES( STR_HEADERBAR ) ) ); + + FreeResource(); + + ::rtl::OUString CFG_PACKAGE_RECOVERY( RTL_CONSTASCII_USTRINGPARAM ( "org.openoffice.Office.Recovery/" )); + ::rtl::OUString CFG_PATH_CRASHREPORTER( RTL_CONSTASCII_USTRINGPARAM( "CrashReporter" )); + ::rtl::OUString CFG_ENTRY_ENABLED( RTL_CONSTASCII_USTRINGPARAM ( "Enabled" )); + + sal_Bool bCrashRepEnabled( sal_True ); + css::uno::Any aVal = ::comphelper::ConfigurationHelper::readDirectKey( + pCore->getSMGR(), + CFG_PACKAGE_RECOVERY, + CFG_PATH_CRASHREPORTER, + CFG_ENTRY_ENABLED, + ::comphelper::ConfigurationHelper::E_READONLY); + aVal >>= bCrashRepEnabled; + m_bRecoveryOnly = !bCrashRepEnabled; + + PluginProgress* pProgress = new PluginProgress( &m_aProgrParent, pCore->getSMGR() ); + m_xProgress = css::uno::Reference< css::task::XStatusIndicator >(static_cast< css::task::XStatusIndicator* >(pProgress), css::uno::UNO_QUERY_THROW); + + const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); + Wallpaper aBackground( rStyleSettings.GetWindowColor() ); + m_aTitleWin.SetBackground(aBackground); + m_aTitleFT.SetBackground (aBackground); + + Font aFont(m_aTitleFT.GetFont()); + aFont.SetWeight(WEIGHT_BOLD); + m_aTitleFT.SetFont(aFont); + + m_aFileListLB.SetBackground( rStyleSettings.GetDialogColor() ); + + m_aNextBtn.Enable(TRUE); + m_aNextBtn.SetClickHdl( LINK( this, RecoveryDialog, NextButtonHdl ) ); + m_aCancelBtn.SetClickHdl( LINK( this, RecoveryDialog, CancelButtonHdl ) ); + + // fill list box first time + TURLList* pURLList = m_pCore->getURLListAccess(); + TURLList::const_iterator pIt; + for ( pIt = pURLList->begin(); + pIt != pURLList->end() ; + ++pIt ) + { + const TURLInfo& rInfo = *pIt; + + String sName( rInfo.DisplayName ); + sName += '\t'; + sName += impl_getStatusString( rInfo ); + SvLBoxEntry* pEntry = m_aFileListLB.InsertEntry(sName, rInfo.StandardImage, rInfo.StandardImage); + pEntry->SetUserData((void*)&rInfo); + m_aFileListLB.SetExpandedEntryBmp (pEntry, rInfo.HCImage, BMP_COLOR_HIGHCONTRAST); + m_aFileListLB.SetCollapsedEntryBmp(pEntry, rInfo.HCImage, BMP_COLOR_HIGHCONTRAST); + } + + // mark first item + SvLBoxEntry* pFirst = m_aFileListLB.First(); + if (pFirst) + m_aFileListLB.SetCursor(pFirst, sal_True); +} + +//=============================================== +RecoveryDialog::~RecoveryDialog() +{ +} + +//=============================================== +short RecoveryDialog::execute() +{ + ::vos::OGuard aSolarLock(Application::GetSolarMutex()); + + switch(m_eRecoveryState) + { + case RecoveryDialog::E_RECOVERY_PREPARED : + { + // Dialog was started first time ... + // wait for user decision ("start" or "cancel" recovery) + // This decision will be made inside the NextBtn handler. + m_aNextBtn.Enable(TRUE); + m_aCancelBtn.Enable(TRUE); + m_bWaitForUser = sal_True; + while(m_bWaitForUser) + Application::Yield(); + if (m_bUserDecideNext) + m_eRecoveryState = RecoveryDialog::E_RECOVERY_IN_PROGRESS; + else + m_eRecoveryState = RecoveryDialog::E_RECOVERY_CANCELED; + return execute(); + } + + case RecoveryDialog::E_RECOVERY_IN_PROGRESS : + { + // user decided to start recovery ... + m_bWasRecoveryStarted = sal_True; + // do it asynchronous (to allow repaints) + // and wait for this asynchronous operation. + m_aDescrFT.SetText( m_aTitleRecoveryInProgress ); + m_aNextBtn.Enable(FALSE); + m_aCancelBtn.Enable(FALSE); + m_pCore->setProgressHandler(m_xProgress); + m_pCore->setUpdateListener(this); + m_pCore->doRecovery(); + + m_bWaitForCore = sal_True; + while(m_bWaitForCore) + Application::Yield(); + + m_pCore->setUpdateListener(0); + m_eRecoveryState = RecoveryDialog::E_RECOVERY_CORE_DONE; + return execute(); + } + + case RecoveryDialog::E_RECOVERY_CORE_DONE : + { + // the core finished it's task. + // let the user decide the next step. + if ( m_bRecoveryOnly ) + { + m_aDescrFT.SetText(m_aRecoveryOnlyFinishDescr); + m_aNextBtn.SetText(m_aRecoveryOnlyFinish); + m_aNextBtn.Enable(TRUE); + m_aCancelBtn.Enable(FALSE); + } + else + { + m_aDescrFT.SetText(m_aTitleRecoveryReport); + m_aNextBtn.SetText(m_aNextStr); + m_aNextBtn.Enable(TRUE); + m_aCancelBtn.Enable(TRUE); + } + + m_bWaitForUser = sal_True; + while(m_bWaitForUser) + Application::Yield(); + + if (m_bUserDecideNext) + m_eRecoveryState = RecoveryDialog::E_RECOVERY_DONE; + else + m_eRecoveryState = RecoveryDialog::E_RECOVERY_CANCELED; + return execute(); + } + + case RecoveryDialog::E_RECOVERY_DONE : + { + // All documents was reovered. + // User decided to step to the "next" wizard page. + // Do it ... but check first, if there exist some + // failed recovery documents. They must be saved to + // a user selected directrory. + short nRet = DLG_RET_UNKNOWN; + BrokenRecoveryDialog* pBrokenRecoveryDialog = new BrokenRecoveryDialog(this, m_pCore, !m_bWasRecoveryStarted); + String sSaveDir = pBrokenRecoveryDialog->getSaveDirURL(); // get the default dir + if (pBrokenRecoveryDialog->isExecutionNeeded()) + { + nRet = pBrokenRecoveryDialog->Execute(); + sSaveDir = pBrokenRecoveryDialog->getSaveDirURL(); + } + delete pBrokenRecoveryDialog; + + switch(nRet) + { + // no broken temp files exists + // step to the next wizard page + case DLG_RET_UNKNOWN : + { + m_eRecoveryState = RecoveryDialog::E_RECOVERY_HANDLED; + return DLG_RET_OK; + } + + // user decided to save the broken temp files + // do and forget it + // step to the next wizard page + case DLG_RET_OK : + { + m_pCore->saveBrokenTempEntries(sSaveDir); + m_pCore->forgetBrokenTempEntries(); + m_eRecoveryState = RecoveryDialog::E_RECOVERY_HANDLED; + return DLG_RET_OK; + } + + // user decided to ignore broken temp files. + // Ask it again ... may be this decision was wrong. + // Results: + // IGNORE => remove broken temp files + // => step to the next wizard page + // CANCEL => step back to the recovery page + case DLG_RET_CANCEL : + { + // TODO ask user ... + m_pCore->forgetBrokenTempEntries(); + m_eRecoveryState = RecoveryDialog::E_RECOVERY_HANDLED; + return DLG_RET_OK; + } + } + + m_eRecoveryState = RecoveryDialog::E_RECOVERY_HANDLED; + return DLG_RET_OK; + } + + case RecoveryDialog::E_RECOVERY_CANCELED : + { + // "YES" => break recovery + // But there exist different states, where "cancel" can be called. + // Handle it different. + if (m_bWasRecoveryStarted) + m_eRecoveryState = RecoveryDialog::E_RECOVERY_CANCELED_AFTERWARDS; + else + m_eRecoveryState = RecoveryDialog::E_RECOVERY_CANCELED_BEFORE; + return execute(); + } + + case RecoveryDialog::E_RECOVERY_CANCELED_BEFORE : + case RecoveryDialog::E_RECOVERY_CANCELED_AFTERWARDS : + { + // We have to check if there exists some temp. files. + // They should be saved to a user defined location. + // If no temp files exists or user decided to ignore it ... + // we have to remove all recovery/session data anyway! + short nRet = DLG_RET_UNKNOWN; + BrokenRecoveryDialog* pBrokenRecoveryDialog = new BrokenRecoveryDialog(this, m_pCore, !m_bWasRecoveryStarted); + String sSaveDir = pBrokenRecoveryDialog->getSaveDirURL(); // get the default save location + + // dialog itself checks if there is a need to copy files for this mode. + // It uses the information m_bWasRecoveryStarted doing so. + if (pBrokenRecoveryDialog->isExecutionNeeded()) + { + nRet = pBrokenRecoveryDialog->Execute(); + sSaveDir = pBrokenRecoveryDialog->getSaveDirURL(); + } + delete pBrokenRecoveryDialog; + + // Possible states: + // a) nRet == DLG_RET_UNKNOWN + // dialog was not shown ... + // because there exists no temp file for copy. + // => remove all recovery data + // b) nRet == DLG_RET_OK + // dialog was shown ... + // user decided to save temp files + // => save all OR broken temp files (depends from the time, where cancel was called) + // => remove all recovery data + // c) nRet == DLG_RET_CANCEL + // dialog was shown ... + // user decided to ignore temp files + // => remove all recovery data + // => a)/c) are the same ... b) has one additional operation + + // b) + if (nRet == DLG_RET_OK) + { + if (m_bWasRecoveryStarted) + m_pCore->saveBrokenTempEntries(sSaveDir); + else + m_pCore->saveAllTempEntries(sSaveDir); + } + + // a,b,c) + if (m_bWasRecoveryStarted) + m_pCore->forgetBrokenRecoveryEntries(); + else + m_pCore->forgetAllRecoveryEntries(); + m_eRecoveryState = RecoveryDialog::E_RECOVERY_HANDLED; + + // THERE IS NO WAY BACK. see impl_askUserForWizardCancel()! + return DLG_RET_CANCEL; + } + + case RecoveryDialog::E_RECOVERY_HANDLED : + { + m_bWaitForUser = sal_True; + while(m_bWaitForUser) + Application::Yield(); + + // TODO: show BrokenRecoveryDialog again, ift he user + // doesnt accepted it last time. + + if (m_bUserDecideNext) + return DLG_RET_OK; + else + return DLG_RET_CANCEL; + } + } + + // should never be reached .-) + DBG_ERROR("Should never be reached!"); + return DLG_RET_OK; +} + +//=============================================== +void RecoveryDialog::setDefButton() +{ + if ( m_aNextBtn.IsEnabled() ) + m_aNextBtn.GrabFocus(); + else + m_pDefButton = &m_aNextBtn; +} + +//=============================================== +void RecoveryDialog::start() +{ +} + +//=============================================== +void RecoveryDialog::updateItems() +{ + ULONG c = m_aFileListLB.GetEntryCount(); + ULONG i = 0; + for ( i=0; i<c; ++i ) + { + SvLBoxEntry* pEntry = m_aFileListLB.GetEntry(i); + if ( !pEntry ) + continue; + + TURLInfo* pInfo = (TURLInfo*)pEntry->GetUserData(); + if ( !pInfo ) + continue; + + String sStatus = impl_getStatusString( *pInfo ); + if ( sStatus.Len() > 0 ) + m_aFileListLB.SetEntryText( sStatus, pEntry, 1 ); + } + + m_aFileListLB.Invalidate(); + m_aFileListLB.Update(); +} + +//=============================================== +void RecoveryDialog::stepNext(TURLInfo* pItem) +{ + ULONG c = m_aFileListLB.GetEntryCount(); + ULONG i = 0; + for (i=0; i<c; ++i) + { + SvLBoxEntry* pEntry = m_aFileListLB.GetEntry(i); + if (!pEntry) + continue; + + TURLInfo* pInfo = (TURLInfo*)pEntry->GetUserData(); + if (pInfo->ID != pItem->ID) + continue; + + m_aFileListLB.SetCursor(pEntry, sal_True); + m_aFileListLB.MakeVisible(pEntry); + m_aFileListLB.Invalidate(); + m_aFileListLB.Update(); + break; + } +} + +//=============================================== +void RecoveryDialog::end() +{ + if ( m_pDefButton ) + { + m_pDefButton->GrabFocus(); + m_pDefButton = NULL; + } + m_bWaitForCore = sal_False; +} + +//=============================================== +IMPL_LINK( RecoveryDialog, NextButtonHdl, void*, EMPTYARG ) +{ + m_bUserDecideNext = sal_True; + m_bWaitForUser = sal_False; + return 0; +} + +//=============================================== +IMPL_LINK( RecoveryDialog, CancelButtonHdl, void*, EMPTYARG ) +{ + if (m_eRecoveryState == RecoveryDialog::E_RECOVERY_PREPARED) + { + if (impl_askUserForWizardCancel(this, RID_SVXQB_EXIT_RECOVERY) == DLG_RET_CANCEL) + return 0; + } + m_bUserDecideNext = sal_False; + m_bWaitForUser = sal_False; + return 0; +} + +//=============================================== +void RecoveryDialog::impl_refreshDocList() +{ +} + +//=============================================== +String RecoveryDialog::impl_getStatusString( const TURLInfo& rInfo ) const +{ + String sStatus; + switch ( rInfo.RecoveryState ) + { + case E_SUCCESSFULLY_RECOVERED : + sStatus = m_aFileListLB.m_aSuccessRecovStr; + break; + case E_ORIGINAL_DOCUMENT_RECOVERED : + sStatus = m_aFileListLB.m_aOrigDocRecovStr; + break; + case E_RECOVERY_FAILED : + sStatus = m_aFileListLB.m_aRecovFailedStr; + break; + case E_RECOVERY_IS_IN_PROGRESS : + sStatus = m_aFileListLB.m_aRecovInProgrStr; + break; + case E_NOT_RECOVERED_YET : + sStatus = m_aFileListLB.m_aNotRecovYetStr; + break; + default: + break; + } + return sStatus; +} + +//=============================================== +BrokenRecoveryDialog::BrokenRecoveryDialog(Window* pParent , + RecoveryCore* pCore , + sal_Bool bBeforeRecovery) + : ModalDialog ( pParent, SVX_RES( RID_SVX_MDLG_DOCRECOVERY_BROKEN ) ) + , m_aDescrFT ( this , SVX_RES( FT_BROKEN_DESCR ) ) + , m_aFileListFT ( this , SVX_RES( FT_BROKEN_FILELIST ) ) + , m_aFileListLB ( this , SVX_RES( LB_BROKEN_FILELIST ) ) + , m_aSaveDirFT ( this , SVX_RES( FT_BROKEN_SAVEDIR ) ) + , m_aSaveDirED ( this , SVX_RES( ED_BROKEN_SAVEDIR ) ) + , m_aSaveDirBtn ( this , SVX_RES( BTN_BROKEN_SAVEDIR ) ) + , m_aBottomFL ( this , SVX_RES( FL_BROKEN_BOTTOM ) ) + , m_aOkBtn ( this , SVX_RES( BTN_BROKEN_OK ) ) + , m_aCancelBtn ( this , SVX_RES( BTN_BROKEN_CANCEL ) ) + , m_pCore ( pCore ) + , m_bBeforeRecovery (bBeforeRecovery) + , m_bExecutionNeeded(sal_False) +{ + FreeResource(); + + m_aSaveDirBtn.SetClickHdl( LINK( this, BrokenRecoveryDialog, SaveButtonHdl ) ); + m_aOkBtn.SetClickHdl( LINK( this, BrokenRecoveryDialog, OkButtonHdl ) ); + m_aCancelBtn.SetClickHdl( LINK( this, BrokenRecoveryDialog, CancelButtonHdl ) ); + + m_sSavePath = SvtPathOptions().GetWorkPath(); + INetURLObject aObj( m_sSavePath ); + String sPath; + ::utl::LocalFileHelper::ConvertURLToSystemPath( aObj.GetMainURL( INetURLObject::NO_DECODE ), sPath ); + m_aSaveDirED.SetText( sPath ); + + impl_refresh(); +} + +//=============================================== +BrokenRecoveryDialog::~BrokenRecoveryDialog() +{ +} + +//=============================================== +void BrokenRecoveryDialog::impl_refresh() +{ + m_bExecutionNeeded = sal_False; + TURLList* pURLList = m_pCore->getURLListAccess(); + TURLList::const_iterator pIt; + for ( pIt = pURLList->begin(); + pIt != pURLList->end() ; + ++pIt ) + { + const TURLInfo& rInfo = *pIt; + + if (m_bBeforeRecovery) + { + // "Cancel" before recovery -> + // search for any temp files! + if (!rInfo.TempURL.getLength()) + continue; + } + else + { + // "Cancel" after recovery -> + // search for broken temp files + if (!RecoveryCore::isBrokenTempEntry(rInfo)) + continue; + } + + m_bExecutionNeeded = sal_True; + + USHORT nPos = m_aFileListLB.InsertEntry(rInfo.DisplayName, rInfo.StandardImage ); + m_aFileListLB.SetEntryData( nPos, (void*)&rInfo ); + } + m_sSavePath = ::rtl::OUString(); + m_aOkBtn.GrabFocus(); +} + +//=============================================== +sal_Bool BrokenRecoveryDialog::isExecutionNeeded() +{ + return m_bExecutionNeeded; +} + +//=============================================== +::rtl::OUString BrokenRecoveryDialog::getSaveDirURL() +{ + return m_sSavePath; +} + +//=============================================== +IMPL_LINK( BrokenRecoveryDialog, OkButtonHdl, void*, EMPTYARG ) +{ + String sPhysicalPath = m_aSaveDirED.GetText().EraseLeadingChars().EraseTrailingChars(); + String sURL; + ::utl::LocalFileHelper::ConvertPhysicalNameToURL( sPhysicalPath, sURL ); + m_sSavePath = sURL; + while (!m_sSavePath.getLength()) + impl_askForSavePath(); + + EndDialog(DLG_RET_OK); + return 0; +} + +//=============================================== +IMPL_LINK( BrokenRecoveryDialog, CancelButtonHdl, void*, EMPTYARG ) +{ + EndDialog(DLG_RET_CANCEL); + return 0; +} + +//=============================================== +IMPL_LINK( BrokenRecoveryDialog, SaveButtonHdl, void*, EMPTYARG ) +{ + impl_askForSavePath(); + return 0; +} + +//=============================================== +void BrokenRecoveryDialog::impl_askForSavePath() +{ + css::uno::Reference< css::ui::dialogs::XFolderPicker > xFolderPicker( + m_pCore->getSMGR()->createInstance(SERVICENAME_FOLDERPICKER), css::uno::UNO_QUERY_THROW); + + INetURLObject aURL(m_sSavePath, INET_PROT_FILE); + xFolderPicker->setDisplayDirectory(aURL.GetMainURL(INetURLObject::NO_DECODE)); + short nRet = xFolderPicker->execute(); + if (nRet == css::ui::dialogs::ExecutableDialogResults::OK) + { + m_sSavePath = xFolderPicker->getDirectory(); + String sPath; + ::utl::LocalFileHelper::ConvertURLToSystemPath( m_sSavePath, sPath ); + m_aSaveDirED.SetText( sPath ); + } +} + +//=============================================== + /////////////////////////////////////////////////////////////////////// + // Error Report Welcome Dialog + /////////////////////////////////////////////////////////////////////// + + ErrorRepWelcomeDialog::ErrorRepWelcomeDialog( Window* _pParent, sal_Bool _bAllowBack ) + :IExtendedTabPage ( _pParent, SVX_RES( RID_SVXPAGE_ERR_REP_WELCOME ) ) + ,maTitleWin ( this, SVX_RES( WIN_RECOV_TITLE ) ) + ,maTitleFT ( this, SVX_RES( FT_RECOV_TITLE ) ) + ,maTitleFL ( this, SVX_RES( FL_RECOV_TITLE ) ) + ,maDescrFT ( this, SVX_RES( FT_RECOV_DESCR ) ) + ,maBottomFL ( this, SVX_RES( FL_RECOV_BOTTOM ) ) + ,maPrevBtn ( this, SVX_RES( BTN_RECOV_PREV ) ) + ,maNextBtn ( this, SVX_RES( BTN_RECOV_NEXT ) ) + ,maCancelBtn ( this, SVX_RES( BTN_RECOV_CANCEL ) ) + { + FreeResource(); + + Wallpaper aBack( GetSettings().GetStyleSettings().GetWindowColor() ); + maTitleWin.SetBackground( aBack ); + maTitleFT.SetBackground( aBack ); + + Font aFnt( maTitleFT.GetFont() ); + aFnt.SetWeight( WEIGHT_BOLD ); + maTitleFT.SetFont( aFnt ); + + maPrevBtn.SetClickHdl( LINK( this, ErrorRepWelcomeDialog, PrevBtnHdl ) ); + maPrevBtn.Enable( _bAllowBack ); + + maNextBtn.SetClickHdl( LINK( this, ErrorRepWelcomeDialog, NextBtnHdl ) ); + maNextBtn.Enable( sal_True ); + + maCancelBtn.SetClickHdl( LINK( this, ErrorRepWelcomeDialog, CancelBtnHdl ) ); + maCancelBtn.Enable( sal_True ); + } + + ErrorRepWelcomeDialog::~ErrorRepWelcomeDialog() + { + } + + IMPL_LINK( ErrorRepWelcomeDialog, PrevBtnHdl, void*, EMPTYARG ) + { + m_nResult = DLG_RET_BACK; + return 0; + } + + IMPL_LINK( ErrorRepWelcomeDialog, NextBtnHdl, void*, EMPTYARG ) + { + m_nResult = DLG_RET_OK; + return 0; + } + + IMPL_LINK( ErrorRepWelcomeDialog, CancelBtnHdl, void*, EMPTYARG ) + { + m_nResult = DLG_RET_CANCEL; + return 0; + } + + short ErrorRepWelcomeDialog::execute() + { + ::vos::OGuard aLock(Application::GetSolarMutex()); + Show(); + m_nResult = DLG_RET_UNKNOWN; + while(m_nResult == DLG_RET_UNKNOWN) + Application::Yield(); + return m_nResult; + } + + void ErrorRepWelcomeDialog::setDefButton() + { + maNextBtn.GrabFocus(); + } + + /////////////////////////////////////////////////////////////////////// + // Error Report Send Dialog and its MultiLineEdit + /////////////////////////////////////////////////////////////////////// + + ErrorDescriptionEdit::ErrorDescriptionEdit( Window* pParent, const ResId& rResId ) : + + MultiLineEdit( pParent, rResId ) + + { + SetModifyHdl( LINK( this, ErrorDescriptionEdit, ModifyHdl ) ); + if ( GetVScrollBar() ) + GetVScrollBar()->Hide(); + } + + ErrorDescriptionEdit::~ErrorDescriptionEdit() + { + } + + IMPL_LINK( ErrorDescriptionEdit, ModifyHdl, void*, EMPTYARG ) + { + if ( !GetVScrollBar() ) + return 0; + + ExtTextEngine* pTextEngine = GetTextEngine(); + DBG_ASSERT( pTextEngine, "no text engine" ); + + ULONG i, nParaCount = pTextEngine->GetParagraphCount(); + USHORT nLineCount = 0; + + for ( i = 0; i < nParaCount; ++i ) + nLineCount = nLineCount + pTextEngine->GetLineCount(i); + + USHORT nVisCols = 0, nVisLines = 0; + GetMaxVisColumnsAndLines( nVisCols, nVisLines ); + GetVScrollBar()->Show( nLineCount > nVisLines ); + + return 0; + } + + ErrorRepSendDialog::ErrorRepSendDialog( Window* _pParent ) + :IExtendedTabPage ( _pParent, SVX_RES( RID_SVXPAGE_ERR_REP_SEND ) ) + ,maTitleWin ( this, SVX_RES( WIN_RECOV_TITLE ) ) + ,maTitleFT ( this, SVX_RES( FT_RECOV_TITLE ) ) + ,maTitleFL ( this, SVX_RES( FL_RECOV_TITLE ) ) + ,maDescrFT ( this, SVX_RES( FT_RECOV_DESCR ) ) + + ,maDocTypeFT ( this, SVX_RES( FT_ERRSEND_DOCTYPE ) ) + ,maDocTypeED ( this, SVX_RES( ED_ERRSEND_DOCTYPE ) ) + ,maUsingFT ( this, SVX_RES( FT_ERRSEND_USING ) ) + ,maUsingML ( this, SVX_RES( ML_ERRSEND_USING ) ) + ,maShowRepBtn ( this, SVX_RES( BTN_ERRSEND_SHOWREP ) ) + ,maOptBtn ( this, SVX_RES( BTN_ERRSEND_OPT ) ) + ,maContactCB ( this, SVX_RES( CB_ERRSEND_CONTACT ) ) + ,maEMailAddrFT ( this, SVX_RES( FT_ERRSEND_EMAILADDR ) ) + ,maEMailAddrED ( this, SVX_RES( ED_ERRSEND_EMAILADDR ) ) + + ,maBottomFL ( this, SVX_RES( FL_RECOV_BOTTOM ) ) + ,maPrevBtn ( this, SVX_RES( BTN_RECOV_PREV ) ) + ,maNextBtn ( this, SVX_RES( BTN_RECOV_NEXT ) ) + ,maCancelBtn ( this, SVX_RES( BTN_RECOV_CANCEL ) ) + { + FreeResource(); + + initControls(); + + Wallpaper aBack( GetSettings().GetStyleSettings().GetWindowColor() ); + maTitleWin.SetBackground( aBack ); + maTitleFT.SetBackground( aBack ); + + Font aFnt( maTitleFT.GetFont() ); + aFnt.SetWeight( WEIGHT_BOLD ); + maTitleFT.SetFont( aFnt ); + + maShowRepBtn.SetClickHdl( LINK( this, ErrorRepSendDialog, ShowRepBtnHdl ) ); + maOptBtn.SetClickHdl( LINK( this, ErrorRepSendDialog, OptBtnHdl ) ); + maContactCB.SetClickHdl( LINK( this, ErrorRepSendDialog, ContactCBHdl ) ); + maPrevBtn.SetClickHdl( LINK( this, ErrorRepSendDialog, PrevBtnHdl ) ); + maNextBtn.SetClickHdl( LINK( this, ErrorRepSendDialog, SendBtnHdl ) ); + maCancelBtn.SetClickHdl( LINK( this, ErrorRepSendDialog, CancelBtnHdl ) ); + + ReadParams(); + + /* + maDocTypeED.SetText( maParams.maSubject ); + maUsingML.SetText( maParams.maBody ); + maContactCB.Check( maParams.mbAllowContact ); + maEMailAddrED.SetText( maParams.maReturnAddress ); + */ + ContactCBHdl( 0 ); + } + + ErrorRepSendDialog::~ErrorRepSendDialog() + { + } + + short ErrorRepSendDialog::execute() + { + ::vos::OGuard aLock(Application::GetSolarMutex()); + Show(); + m_nResult = DLG_RET_UNKNOWN; + while(m_nResult == DLG_RET_UNKNOWN) + Application::Yield(); + return m_nResult; + } + + void ErrorRepSendDialog::setDefButton() + { + // set first focus + maDocTypeED.GrabFocus(); + } + + IMPL_LINK( ErrorRepSendDialog, PrevBtnHdl, void*, EMPTYARG ) + { + m_nResult = DLG_RET_BACK; + return 0; + } + + IMPL_LINK( ErrorRepSendDialog, CancelBtnHdl, void*, EMPTYARG ) + { + m_nResult = DLG_RET_CANCEL; + return 0; + } + + IMPL_LINK( ErrorRepSendDialog, SendBtnHdl, void*, EMPTYARG ) + { + + SaveParams(); + SendReport(); + + m_nResult = DLG_RET_OK; + return 0; + } + + IMPL_LINK( ErrorRepSendDialog, ShowRepBtnHdl, void*, EMPTYARG ) + { + ErrorRepPreviewDialog aDlg( this ); + aDlg.Execute(); + return 0; + } + + IMPL_LINK( ErrorRepSendDialog, OptBtnHdl, void*, EMPTYARG ) + { + ErrorRepOptionsDialog aDlg( this, maParams ); + aDlg.Execute(); + return 0; + } + + IMPL_LINK( ErrorRepSendDialog, ContactCBHdl, void*, EMPTYARG ) + { + bool bCheck = maContactCB.IsChecked(); + maEMailAddrFT.Enable( bCheck ); + maEMailAddrED.Enable( bCheck ); + return 0; + } + + void ErrorRepSendDialog::initControls() + { + // if the text is too short for two lines, insert a newline + String sText = maDocTypeFT.GetText(); + if ( maDocTypeFT.GetCtrlTextWidth( sText ) <= maDocTypeFT.GetSizePixel().Width() ) + { + sText.Insert( '\n', 0 ); + maDocTypeFT.SetText( sText ); + } + + // if the button text is too wide, then broaden the button + sText = maShowRepBtn.GetText(); + long nTxtW = maShowRepBtn.GetCtrlTextWidth( sText ); + long nBtnW = maShowRepBtn.GetSizePixel().Width(); + if ( nTxtW >= nBtnW ) + { + const long nMinDelta = 10; + long nDelta = Max( nTxtW - nBtnW, nMinDelta ); + sal_uInt32 i = 0; + Window* pWins[] = + { + &maShowRepBtn, &maOptBtn, + &maDescrFT, &maDocTypeFT, &maDocTypeED, &maUsingFT, + &maUsingML, &maContactCB, &maEMailAddrFT, &maEMailAddrED + }; + // the first two buttons need a new size (wider) and position (more left) + Window** pCurrent = pWins; + const sal_uInt32 nBtnCount = 2; + for ( ; i < nBtnCount; ++i, ++pCurrent ) + { + Size aNewSize = (*pCurrent)->GetSizePixel(); + aNewSize.Width() += nDelta; + (*pCurrent)->SetSizePixel( aNewSize ); + Point aNewPos = (*pCurrent)->GetPosPixel(); + aNewPos.X() -= nDelta; + (*pCurrent)->SetPosPixel( aNewPos ); + } + + // loop through all the other windows and adjust their size + for ( ; i < sizeof( pWins ) / sizeof( pWins[ 0 ] ); ++i, ++pCurrent ) + { + Size aSize = (*pCurrent)->GetSizePixel(); + aSize.Width() -= nDelta; + (*pCurrent)->SetSizePixel( aSize ); + } + } + } + + String ErrorRepSendDialog::GetDocType( void ) const + { + return maDocTypeED.GetText(); + } + + String ErrorRepSendDialog::GetUsing( void ) const + { + return maUsingML.GetText(); + } + + bool ErrorRepSendDialog::IsContactAllowed( void ) const + { + return maContactCB.IsChecked(); + } + + String ErrorRepSendDialog::GetEMailAddress( void ) const + { + return maEMailAddrED.GetText(); + } + + + /////////////////////////////////////////////////////////////////////// + // Error Report Options Dialog + /////////////////////////////////////////////////////////////////////// + + ErrorRepOptionsDialog::ErrorRepOptionsDialog( Window* _pParent, ErrorRepParams& _rParams ) + :ModalDialog ( _pParent, SVX_RES( RID_SVX_MDLG_ERR_REP_OPTIONS ) ) + ,maProxyFL( this, SVX_RES( FL_ERROPT_PROXY ) ) + ,maSystemBtn( this, SVX_RES( BTN_ERROPT_SYSTEM ) ) + ,maDirectBtn( this, SVX_RES( BTN_ERROPT_DIRECT ) ) + ,maManualBtn( this, SVX_RES( BTN_ERROPT_MANUAL ) ) + ,maProxyServerFT( this, SVX_RES( FT_ERROPT_PROXYSERVER ) ) + ,maProxyServerEd( this, SVX_RES( ED_ERROPT_PROXYSERVER ) ) + ,maProxyPortFT( this, SVX_RES( FT_ERROPT_PROXYPORT ) ) + ,maProxyPortEd( this, SVX_RES( ED_ERROPT_PROXYPORT ) ) + ,maDescriptionFT( this, SVX_RES( FT_ERROPT_DESCRIPTION ) ) + ,maButtonsFL( this, SVX_RES( FL_ERROPT_BUTTONS ) ) + ,maOKBtn( this, SVX_RES( BTN_ERROPT_OK ) ) + ,maCancelBtn( this, SVX_RES( BTN_ERROPT_CANCEL ) ) + ,mrParams( _rParams ) + { + FreeResource(); + + maManualBtn.SetToggleHdl( LINK( this, ErrorRepOptionsDialog, ManualBtnHdl ) ); + maCancelBtn.SetClickHdl( LINK( this, ErrorRepOptionsDialog, CancelBtnHdl ) ); + maOKBtn.SetClickHdl( LINK( this, ErrorRepOptionsDialog, OKBtnHdl ) ); + + maProxyServerEd.SetText( mrParams.maHTTPProxyServer ); + maProxyPortEd.SetText( mrParams.maHTTPProxyPort ); + +#ifndef WNT + // no "Use system settings" button on non windows systems + // so hide this button + maSystemBtn.Hide(); + long nDelta = maDirectBtn.GetPosPixel().Y() - maSystemBtn.GetPosPixel().Y(); + // and loop through all these controls and adjust their position + Window* pWins[] = + { + &maDirectBtn, &maManualBtn, &maProxyServerFT, + &maProxyServerEd, &maProxyPortFT, &maProxyPortEd, &maDescriptionFT + }; + Window** pCurrent = pWins; + for ( sal_uInt32 i = 0; i < sizeof( pWins ) / sizeof( pWins[ 0 ] ); ++i, ++pCurrent ) + { + Point aPos = (*pCurrent)->GetPosPixel(); + aPos.Y() -= nDelta; + (*pCurrent)->SetPosPixel( aPos ); + } +#endif + + + switch ( mrParams.miHTTPConnectionType ) + { + default: +#ifdef WNT + case 0: + maSystemBtn.Check( TRUE ); + break; +#endif + case 1: + maDirectBtn.Check( TRUE ); + break; + case 2: + maManualBtn.Check( TRUE ); + break; + } + + ManualBtnHdl( 0 ); + } + + ErrorRepOptionsDialog::~ErrorRepOptionsDialog() + { + } + + IMPL_LINK( ErrorRepOptionsDialog, ManualBtnHdl, void*, EMPTYARG ) + { + bool bCheck = maManualBtn.IsChecked(); + maProxyServerFT.Enable( bCheck ); + maProxyServerEd.Enable( bCheck ); + maProxyPortFT.Enable( bCheck ); + maProxyPortEd.Enable( bCheck ); + return 0; + } + + IMPL_LINK( ErrorRepOptionsDialog, OKBtnHdl, void*, EMPTYARG ) + { + if ( maManualBtn.IsChecked() ) + mrParams.miHTTPConnectionType = 2; + else if ( maDirectBtn.IsChecked() ) + mrParams.miHTTPConnectionType = 1; + else if ( maSystemBtn.IsChecked() ) + mrParams.miHTTPConnectionType = 0; + + mrParams.maHTTPProxyServer = maProxyServerEd.GetText(); + mrParams.maHTTPProxyPort = maProxyPortEd.GetText(); + + EndDialog(DLG_RET_OK); + return 0; + } + + IMPL_LINK( ErrorRepOptionsDialog, CancelBtnHdl, void*, EMPTYARG ) + { + EndDialog(DLG_RET_CANCEL); + return 0; + } + + /////////////////////////////////////////////////////////////////////// + // Error Report Edit (MultiLineEdit with fixed font) + /////////////////////////////////////////////////////////////////////// + + ErrorRepEdit::ErrorRepEdit( Window* pParent, const ResId& rResId ) : + ExtMultiLineEdit( pParent, rResId ) + { + // fixed font for error report + Color aColor = GetTextColor(); + + Font aFont = OutputDevice::GetDefaultFont( + DEFAULTFONT_FIXED, LANGUAGE_SYSTEM, DEFAULTFONT_FLAGS_ONLYONE ); + + // Set font color because the default font color is transparent !!! + aFont.SetColor( aColor ); + + GetTextEngine()->SetFont( aFont ); + + // no blinking cursor and a little left margin + EnableCursor( FALSE ); + SetLeftMargin( 4 ); + } + + ErrorRepEdit::~ErrorRepEdit() + { + } + + /////////////////////////////////////////////////////////////////////// + // Error Report Preview Dialog + /////////////////////////////////////////////////////////////////////// + + + static ::rtl::OUString GetCrashConfigDir() + { + +#if defined(WNT) || defined(OS2) + OUString ustrValue = OUString::createFromAscii("${$BRAND_BASE_DIR/program/bootstrap.ini:UserInstallation}"); +#elif defined( MACOSX ) + OUString ustrValue = OUString::createFromAscii("~"); +#else + OUString ustrValue = OUString::createFromAscii("$SYSUSERCONFIG"); +#endif + Bootstrap::expandMacros( ustrValue ); + +#if defined(WNT) || defined(OS2) + ustrValue += OUString::createFromAscii("/user/crashdata"); +#endif + return ustrValue; + } + +#if defined(WNT) || defined(OS2) +#define CHKFILE "crashdat.chk" +#define STKFILE "crashdat.stk" +#define PRVFILE "crashdat.prv" +#else +#define CHKFILE ".crash_report_checksum" +#define STKFILE ".crash_report_frames" +#define PRVFILE ".crash_report_preview" +#endif + +// static ::rtl::OUString GetChecksumURL() +// { +// ::rtl::OUString aURL = GetCrashConfigDir(); + +// aURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) ); +// aURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CHKFILE ) ); + +// return aURL; +// } + +// static ::rtl::OUString GetStackURL() +// { +// ::rtl::OUString aURL = GetCrashConfigDir(); + +// aURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) ); +// aURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( STKFILE ) ); + +// return aURL; +// } + + static ::rtl::OUString GetPreviewURL() + { + ::rtl::OUString aURL = GetCrashConfigDir(); + + aURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) ); + aURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( PRVFILE ) ); + + return aURL; + } + + static String LoadCrashFile( const ::rtl::OUString &rURL ) + { + String aFileContent; + ::osl::File aFile( rURL ); + + printf( "Loading %s:", OString( rURL.getStr(), rURL.getLength(), osl_getThreadTextEncoding() ).getStr() ); + if ( ::osl::FileBase::E_None == aFile.open( OpenFlag_Read ) ) + { + ::rtl::OString aContent; + ::osl::FileBase::RC result; + sal_uInt64 aBytesRead; + + do + { + sal_Char aBuffer[256]; + + result = aFile.read( aBuffer, sizeof(aBuffer), aBytesRead ); + + if ( ::osl::FileBase::E_None == result ) + { + ::rtl::OString aTemp( aBuffer, static_cast< xub_StrLen >( aBytesRead ) ); + aContent += aTemp; + } + } while ( ::osl::FileBase::E_None == result && aBytesRead ); + + ::rtl::OUString ustrContent( aContent.getStr(), aContent.getLength(), RTL_TEXTENCODING_UTF8 ); + aFileContent = ustrContent; + + aFile.close(); + + printf( "SUCCEEDED\n" ); + } + else + printf( "FAILED\n" ); + + return aFileContent; + } + + + + ErrorRepPreviewDialog::ErrorRepPreviewDialog( Window* _pParent ) + :ModalDialog ( _pParent, SVX_RES( RID_SVX_MDLG_ERR_REP_PREVIEW ) ) + ,maContentML( this, SVX_RES( ML_ERRPREVIEW_CONTENT ) ) + ,maOKBtn( this, SVX_RES( BTN_ERRPREVIEW_OK ) ) + + { + FreeResource(); + + mnMinHeight = ( maContentML.GetSizePixel().Height() / 2 ); + + String aPreview = LoadCrashFile( GetPreviewURL() ); + ErrorRepSendDialog *pMainDlg = (ErrorRepSendDialog *)_pParent; + + String aSeperator = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\r\n\r\n================\r\n\r\n" ) ); + + String aContent = pMainDlg->GetDocType(); + if ( aContent.Len() > 0 ) + aContent += aSeperator; + aContent += pMainDlg->GetUsing(); + if ( aContent.Len() > 0 ) + aContent += aSeperator; + aContent += aPreview; + + maContentML.SetText( aContent ); + } + + ErrorRepPreviewDialog::~ErrorRepPreviewDialog() + { + } + + void ErrorRepPreviewDialog::Resize() + { + Size a3Sz = LogicToPixel( Size( 3, 3 ), MAP_APPFONT ); + Size aWinSz = GetSizePixel(); + Size aBtnSz = maOKBtn.GetSizePixel(); + Point aEditPnt = maContentML.GetPosPixel(); + + long nNewHeight = Max( aWinSz.Height() - aEditPnt.Y() - 3 * a3Sz.Height() - aBtnSz.Height(), mnMinHeight ); + long nNewWidth = aWinSz.Width() - 4 * a3Sz.Width(); + + Size aNewSize( nNewWidth, nNewHeight ); + maContentML.SetSizePixel( aNewSize ); + Point aNewPoint( Max( aEditPnt.X() + aNewSize.Width() - aBtnSz.Width(), aEditPnt.X() ), + aEditPnt.Y() + aNewSize.Height() + a3Sz.Height() ); + maOKBtn.SetPosPixel( aNewPoint ); + } + } // namespace DocRecovery +} // namespace svx + |