office-gobmx/svx/source/unodraw/recoveryui.cxx
2012-02-05 10:50:31 +01:00

401 lines
13 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
*
* 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.
*
************************************************************************/
//===============================================
// includes
#include "recoveryui.hxx"
#include "docrecovery.hxx"
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/frame/XFramesSupplier.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
#include <osl/file.hxx>
#include <rtl/bootstrap.hxx>
#include <comphelper/configurationhelper.hxx>
#include <vcl/svapp.hxx>
#include <boost/scoped_ptr.hpp>
//===============================================
// const
#define IMPLEMENTATIONNAME_RECOVERYUI ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.svx.RecoveryUI"))
#define SERVICENAME_RECOVERYUI ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.dialog.RecoveryUI"))
//===============================================
// namespace
namespace svx
{
namespace css = ::com::sun::star;
namespace svxdr = ::svx::DocRecovery;
using namespace ::rtl;
using namespace ::osl;
//===============================================
RecoveryUI::RecoveryUI(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
: m_xSMGR (xSMGR )
, m_pParentWindow(0 )
, m_eJob (RecoveryUI::E_JOB_UNKNOWN)
{
}
//===============================================
RecoveryUI::~RecoveryUI()
{
}
//===============================================
::rtl::OUString SAL_CALL RecoveryUI::getImplementationName()
throw(css::uno::RuntimeException)
{
return RecoveryUI::st_getImplementationName();
}
//===============================================
sal_Bool SAL_CALL RecoveryUI::supportsService(const ::rtl::OUString& sServiceName)
throw(css::uno::RuntimeException)
{
const css::uno::Sequence< ::rtl::OUString > lServices = RecoveryUI::st_getSupportedServiceNames();
sal_Int32 c = lServices.getLength();
sal_Int32 i = 0;
for (i=0; i<c; ++i)
{
const ::rtl::OUString& sSupportedService = lServices[i];
if (sSupportedService.equals(sServiceName))
return sal_True;
}
return sal_False;
}
//===============================================
css::uno::Sequence< ::rtl::OUString > SAL_CALL RecoveryUI::getSupportedServiceNames()
throw(css::uno::RuntimeException)
{
return RecoveryUI::st_getSupportedServiceNames();
}
//===============================================
css::uno::Any SAL_CALL RecoveryUI::dispatchWithReturnValue(const css::util::URL& aURL,
const css::uno::Sequence< css::beans::PropertyValue >& )
throw(css::uno::RuntimeException)
{
// Internaly we use VCL ... every call into vcl based code must
// be guarded by locking the global solar mutex.
::SolarMutexGuard aSolarLock;
css::uno::Any aRet;
RecoveryUI::EJob eJob = impl_classifyJob(aURL);
// TODO think about outside arguments
switch(eJob)
{
case RecoveryUI::E_DO_EMERGENCY_SAVE :
{
sal_Bool bRet = impl_doEmergencySave();
aRet <<= bRet;
break;
}
case RecoveryUI::E_DO_RECOVERY :
impl_doRecovery();
break;
case RecoveryUI::E_DO_CRASHREPORT :
impl_doCrashReport();
break;
default :
break;
}
return aRet;
}
//===============================================
void SAL_CALL RecoveryUI::dispatch(const css::util::URL& aURL ,
const css::uno::Sequence< css::beans::PropertyValue >& lArguments)
throw(css::uno::RuntimeException)
{
// recycle this method :-)
dispatchWithReturnValue(aURL, lArguments);
}
//===============================================
void SAL_CALL RecoveryUI::addStatusListener(const css::uno::Reference< css::frame::XStatusListener >&, const css::util::URL& ) throw(css::uno::RuntimeException)
{
// TODO
OSL_FAIL("RecoveryUI::addStatusListener()\nNot implemented yet!");
}
//===============================================
void SAL_CALL RecoveryUI::removeStatusListener(const css::uno::Reference< css::frame::XStatusListener >&, const css::util::URL& )
throw(css::uno::RuntimeException)
{
// TODO
OSL_FAIL("RecoveryUI::removeStatusListener()\nNot implemented yet!");
}
//===============================================
::rtl::OUString RecoveryUI::st_getImplementationName()
{
static ::rtl::OUString IMPLEMENTATIONNAME = IMPLEMENTATIONNAME_RECOVERYUI;
return IMPLEMENTATIONNAME;
}
//===============================================
css::uno::Sequence< ::rtl::OUString > RecoveryUI::st_getSupportedServiceNames()
{
css::uno::Sequence< ::rtl::OUString > lServiceNames(1); lServiceNames.getArray() [0] = SERVICENAME_RECOVERYUI;
return lServiceNames;
}
//===============================================
css::uno::Reference< css::uno::XInterface > SAL_CALL RecoveryUI::st_createInstance(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
{
RecoveryUI* pNew = new RecoveryUI(xSMGR);
return css::uno::Reference< css::uno::XInterface >(static_cast< css::lang::XServiceInfo* >(pNew));
}
//===============================================
static OUString GetCrashConfigDir()
{
#if defined(WNT)
OUString ustrValue = OUString(RTL_CONSTASCII_USTRINGPARAM("${$BRAND_BASE_DIR/program/bootstrap.ini:UserInstallation}"));
#elif defined(MACOSX)
OUString ustrValue = OUString(RTL_CONSTASCII_USTRINGPARAM("~"));
#else
OUString ustrValue = OUString(RTL_CONSTASCII_USTRINGPARAM("$SYSUSERCONFIG"));
#endif
Bootstrap::expandMacros( ustrValue );
#if defined(WNT)
ustrValue += OUString(RTL_CONSTASCII_USTRINGPARAM("/user/crashdata"));
#endif
return ustrValue;
}
//===============================================
#if defined(WNT)
#define LCKFILE "crashdat.lck"
#else
#define LCKFILE ".crash_report_unsent"
#endif
static OUString GetUnsentURL()
{
OUString aURL = GetCrashConfigDir();
aURL += OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) );
aURL += OUString( RTL_CONSTASCII_USTRINGPARAM( LCKFILE ) );
return aURL;
}
//===============================================
static bool new_crash_pending()
{
OUString aUnsentURL = GetUnsentURL();
File aFile( aUnsentURL );
if ( FileBase::E_None == aFile.open( osl_File_OpenFlag_Read ) )
{
aFile.close();
return true;
}
return false;
}
//===============================================
static bool delete_pending_crash()
{
OUString aUnsentURL = GetUnsentURL();
return ( FileBase::E_None == File::remove( aUnsentURL ) );
}
RecoveryUI::EJob RecoveryUI::impl_classifyJob(const css::util::URL& aURL)
{
m_eJob = RecoveryUI::E_JOB_UNKNOWN;
if (aURL.Protocol.equals(RECOVERY_CMDPART_PROTOCOL))
{
if (aURL.Path.equals(RECOVERY_CMDPART_DO_EMERGENCY_SAVE))
m_eJob = RecoveryUI::E_DO_EMERGENCY_SAVE;
else
if (aURL.Path.equals(RECOVERY_CMDPART_DO_RECOVERY))
m_eJob = RecoveryUI::E_DO_RECOVERY;
else
if (aURL.Path.equals(RECOVERY_CMDPART_DO_CRASHREPORT))
m_eJob = RecoveryUI::E_DO_CRASHREPORT;
}
return m_eJob;
}
//===============================================
sal_Bool RecoveryUI::impl_doEmergencySave()
{
// create core service, which implements the real "emergency save" algorithm.
svxdr::RecoveryCore* pCore = new svxdr::RecoveryCore(m_xSMGR, sal_True);
css::uno::Reference< css::frame::XStatusListener > xCore(pCore);
// create all needed dialogs for this operation
// and bind it to the used core service
svxdr::TabDialog4Recovery* pWizard = new svxdr::TabDialog4Recovery(m_pParentWindow);
svxdr::IExtendedTabPage* pPage1 = new svxdr::SaveDialog (pWizard, pCore );
pWizard->addTabPage(pPage1);
// start the wizard
short nRet = pWizard->Execute();
delete pPage1 ;
delete pWizard;
return (nRet==DLG_RET_OK_AUTOLUNCH);
}
//===============================================
void RecoveryUI::impl_doRecovery()
{
sal_Bool bRecoveryOnly( sal_False );
::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_False);
css::uno::Any aVal = ::comphelper::ConfigurationHelper::readDirectKey(
m_xSMGR,
CFG_PACKAGE_RECOVERY,
CFG_PATH_CRASHREPORTER,
CFG_ENTRY_ENABLED,
::comphelper::ConfigurationHelper::E_READONLY);
aVal >>= bCrashRepEnabled;
bRecoveryOnly = !bCrashRepEnabled;
// create core service, which implements the real "emergency save" algorithm.
svxdr::RecoveryCore* pCore = new svxdr::RecoveryCore(m_xSMGR, sal_False);
css::uno::Reference< css::frame::XStatusListener > xCore(pCore);
// create all needed dialogs for this operation
// and bind it to the used core service
boost::scoped_ptr<svxdr::TabDialog4Recovery> xWizard(new svxdr::TabDialog4Recovery(m_pParentWindow));
svxdr::IExtendedTabPage* pPage1 = new svxdr::RecoveryDialog(xWizard.get(), pCore );
svxdr::IExtendedTabPage* pPage2 = 0;
svxdr::IExtendedTabPage* pPage3 = 0;
xWizard->addTabPage(pPage1);
if ( !bRecoveryOnly && new_crash_pending() )
{
pPage2 = new svxdr::ErrorRepWelcomeDialog(xWizard.get());
pPage3 = new svxdr::ErrorRepSendDialog(xWizard.get());
xWizard->addTabPage(pPage2);
xWizard->addTabPage(pPage3);
}
// start the wizard
xWizard->Execute();
impl_showAllRecoveredDocs();
delete pPage3 ;
delete pPage2 ;
delete pPage1 ;
delete_pending_crash();
}
//===============================================
void RecoveryUI::impl_doCrashReport()
{
if ( new_crash_pending() )
{
svxdr::TabDialog4Recovery* pWizard = new svxdr::TabDialog4Recovery (m_pParentWindow );
svxdr::IExtendedTabPage* pPage1 = new svxdr::ErrorRepWelcomeDialog(pWizard, sal_False);
svxdr::IExtendedTabPage* pPage2 = new svxdr::ErrorRepSendDialog (pWizard );
pWizard->addTabPage(pPage1);
pWizard->addTabPage(pPage2);
// start the wizard
pWizard->Execute();
delete pPage2 ;
delete pPage1 ;
delete pWizard;
delete_pending_crash();
}
}
//===============================================
void RecoveryUI::impl_showAllRecoveredDocs()
{
css::uno::Reference< css::frame::XFramesSupplier > xDesktop(
m_xSMGR->createInstance(SERVICENAME_DESKTOP),
css::uno::UNO_QUERY_THROW);
css::uno::Reference< css::container::XIndexAccess > xTaskContainer(
xDesktop->getFrames(),
css::uno::UNO_QUERY_THROW);
sal_Int32 c = xTaskContainer->getCount();
sal_Int32 i = 0;
for (i=0; i<c; ++i)
{
try
{
css::uno::Reference< css::frame::XFrame > xTask;
xTaskContainer->getByIndex(i) >>= xTask;
if (!xTask.is())
continue;
css::uno::Reference< css::awt::XWindow > xWindow = xTask->getContainerWindow();
if (!xWindow.is())
continue;
xWindow->setVisible(sal_True);
}
catch(const css::uno::RuntimeException&)
{ throw; }
catch(const css::uno::Exception&)
{ continue; }
}
}
} // namespace svx
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */