blob: 8c4c89c95059686a9d416a889670dd7160bd49a5 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_desktop.hxx"
#include "dp_gui_updatedata.hxx"
#include "sal/config.h"
#include "osl/file.hxx"
#include "osl/conditn.hxx"
#include "cppuhelper/exc_hlp.hxx"
#include "tools/resid.hxx"
#include "tools/resmgr.hxx"
#include "tools/solar.h"
#include "tools/string.hxx"
#include "vcl/dialog.hxx"
#include "vcl/msgbox.hxx"
#include "vcl/svapp.hxx"
#include "vos/mutex.hxx"
#include "vcl/dialog.hxx"
#include "cppuhelper/implbase3.hxx"
#include "com/sun/star/beans/PropertyValue.hpp"
#include "com/sun/star/beans/NamedValue.hpp"
#include "com/sun/star/xml/dom/XElement.hpp"
#include "com/sun/star/xml/dom/XNode.hpp"
#include "com/sun/star/xml/dom/XNodeList.hpp"
#include "com/sun/star/ucb/NameClash.hpp"
#include "com/sun/star/ucb/InteractiveAugmentedIOException.hpp"
#include "com/sun/star/ucb/XCommandEnvironment.hpp"
#include "com/sun/star/ucb/XProgressHandler.hpp"
#include "com/sun/star/deployment/XExtensionManager.hpp"
#include "com/sun/star/deployment/ExtensionManager.hpp"
#include "com/sun/star/deployment/XUpdateInformationProvider.hpp"
#include "com/sun/star/deployment/DependencyException.hpp"
#include "com/sun/star/deployment/LicenseException.hpp"
#include "com/sun/star/deployment/VersionException.hpp"
#include "com/sun/star/deployment/ui/LicenseDialog.hpp"
#include "com/sun/star/task/XInteractionHandler.hpp"
#include "com/sun/star/ui/dialogs/XExecutableDialog.hpp"
#include "com/sun/star/ui/dialogs/ExecutableDialogResults.hpp"
#include "com/sun/star/task/XInteractionAbort.hpp"
#include "com/sun/star/task/XInteractionApprove.hpp"
#include "dp_descriptioninfoset.hxx"
#include "dp_gui.hrc"
#include "dp_gui_updateinstalldialog.hxx"
#include "dp_gui_shared.hxx"
#include "dp_gui_updatedata.hxx"
#include "dp_ucb.h"
#include "dp_misc.h"
#include "dp_version.hxx"
#include "dp_gui_thread.hxx"
#include "dp_gui_extensioncmdqueue.hxx"
#include "ucbhelper/content.hxx"
#include "osl/mutex.hxx"
#include "vos/mutex.hxx"
#include "rtl/ref.hxx"
#include "com/sun/star/uno/Sequence.h"
#include "comphelper/anytostring.hxx"
#include "toolkit/helper/vclunohelper.hxx"
#include <vector>
class Window;
namespace cssu = ::com::sun::star::uno;
namespace css = ::com::sun::star;
using ::rtl::OUString;
namespace dp_gui {
class UpdateInstallDialog::Thread: public dp_gui::Thread {
friend class UpdateCommandEnv;
public:
Thread(cssu::Reference< cssu::XComponentContext > ctx,
UpdateInstallDialog & dialog, std::vector< dp_gui::UpdateData > & aVecUpdateData);
void stop();
private:
Thread(Thread &); // not defined
void operator =(Thread &); // not defined
virtual ~Thread();
virtual void execute();
void downloadExtensions();
void download(::rtl::OUString const & aUrls, UpdateData & aUpdatData);
void installExtensions();
void removeTempDownloads();
UpdateInstallDialog & m_dialog;
cssu::Reference< css::deployment::XUpdateInformationProvider >
m_updateInformation;
// guarded by Application::GetSolarMutex():
cssu::Reference< css::task::XAbortChannel > m_abort;
cssu::Reference< cssu::XComponentContext > m_xComponentContext;
std::vector< dp_gui::UpdateData > & m_aVecUpdateData;
::rtl::Reference<UpdateCommandEnv> m_updateCmdEnv;
//A folder which is created in the temp directory in which then the updates are downloaded
::rtl::OUString m_sDownloadFolder;
bool m_stop;
};
class UpdateCommandEnv
: public ::cppu::WeakImplHelper3< css::ucb::XCommandEnvironment,
css::task::XInteractionHandler,
css::ucb::XProgressHandler >
{
friend class UpdateInstallDialog::Thread;
UpdateInstallDialog & m_updateDialog;
::rtl::Reference<UpdateInstallDialog::Thread> m_installThread;
cssu::Reference< cssu::XComponentContext > m_xContext;
public:
virtual ~UpdateCommandEnv();
UpdateCommandEnv( cssu::Reference< cssu::XComponentContext > const & xCtx,
UpdateInstallDialog & updateDialog,
::rtl::Reference<UpdateInstallDialog::Thread>const & thread);
// XCommandEnvironment
virtual cssu::Reference<css::task::XInteractionHandler > SAL_CALL
getInteractionHandler() throw (cssu::RuntimeException);
virtual cssu::Reference<css::ucb::XProgressHandler >
SAL_CALL getProgressHandler() throw (cssu::RuntimeException);
// XInteractionHandler
virtual void SAL_CALL handle(
cssu::Reference<css::task::XInteractionRequest > const & xRequest )
throw (cssu::RuntimeException);
// XProgressHandler
virtual void SAL_CALL push( cssu::Any const & Status )
throw (cssu::RuntimeException);
virtual void SAL_CALL update( cssu::Any const & Status )
throw (cssu::RuntimeException);
virtual void SAL_CALL pop() throw (cssu::RuntimeException);
};
UpdateInstallDialog::Thread::Thread(
cssu::Reference< cssu::XComponentContext> xCtx,
UpdateInstallDialog & dialog,
std::vector< dp_gui::UpdateData > & aVecUpdateData):
m_dialog(dialog),
m_xComponentContext(xCtx),
m_aVecUpdateData(aVecUpdateData),
m_updateCmdEnv(new UpdateCommandEnv(xCtx, m_dialog, this)),
m_stop(false)
{}
void UpdateInstallDialog::Thread::stop() {
cssu::Reference< css::task::XAbortChannel > abort;
{
vos::OGuard g(Application::GetSolarMutex());
abort = m_abort;
m_stop = true;
}
if (abort.is()) {
abort->sendAbort();
}
}
UpdateInstallDialog::Thread::~Thread() {}
void UpdateInstallDialog::Thread::execute()
{
try {
downloadExtensions();
installExtensions();
}
catch (...)
{
}
//clean up the temp directories
try {
removeTempDownloads();
} catch( ... ) {
}
{
//make sure m_dialog is still alive
::vos::OGuard g(Application::GetSolarMutex());
if (! m_stop)
m_dialog.updateDone();
}
//UpdateCommandEnv keeps a reference to Thread and prevents destruction. Therefore remove it.
m_updateCmdEnv->m_installThread.clear();
}
UpdateInstallDialog::UpdateInstallDialog(
Window * parent,
std::vector<dp_gui::UpdateData> & aVecUpdateData,
cssu::Reference< cssu::XComponentContext > const & xCtx):
ModalDialog(
parent,
DpGuiResId(RID_DLG_UPDATEINSTALL)),
m_thread(new Thread(xCtx, *this, aVecUpdateData)),
m_xComponentContext(xCtx),
m_bError(false),
m_bNoEntry(true),
m_bActivated(false),
m_sInstalling(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_INSTALLING))),
m_sFinished(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_FINISHED))),
m_sNoErrors(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_NO_ERRORS))),
m_sErrorDownload(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_ERROR_DOWNLOAD))),
m_sErrorInstallation(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_ERROR_INSTALLATION))),
m_sErrorLicenseDeclined(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_ERROR_LIC_DECLINED))),
m_sNoInstall(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_EXTENSION_NOINSTALL))),
m_sThisErrorOccurred(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_THIS_ERROR_OCCURRED))),
m_ft_action(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_DOWNLOADING)),
m_statusbar(this,DpGuiResId(RID_DLG_UPDATE_INSTALL_STATUSBAR)),
m_ft_extension_name(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_EXTENSION_NAME)),
m_ft_results(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_RESULTS)),
m_mle_info(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_INFO)),
m_line(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_LINE)),
m_help(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_HELP)),
m_ok(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_OK)),
m_cancel(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_ABORT))
{
FreeResource();
m_xExtensionManager = css::deployment::ExtensionManager::get( xCtx );
m_cancel.SetClickHdl(LINK(this, UpdateInstallDialog, cancelHandler));
m_mle_info.EnableCursor(sal_False);
if ( ! dp_misc::office_is_running())
m_help.Disable();
}
UpdateInstallDialog::~UpdateInstallDialog() {}
sal_Bool UpdateInstallDialog::Close()
{
m_thread->stop();
return ModalDialog::Close();
}
short UpdateInstallDialog::Execute()
{
m_thread->launch();
return ModalDialog::Execute();
}
// make sure the solar mutex is locked before calling
void UpdateInstallDialog::updateDone()
{
if (!m_bError)
m_mle_info.InsertText(m_sNoErrors);
m_ok.Enable();
m_ok.GrabFocus();
m_cancel.Disable();
}
// make sure the solar mutex is locked before calling
//sets an error message in the text area
void UpdateInstallDialog::setError(INSTALL_ERROR err, ::rtl::OUString const & sExtension,
OUString const & exceptionMessage)
{
String sError;
m_bError = true;
switch (err)
{
case ERROR_DOWNLOAD:
sError = m_sErrorDownload;
break;
case ERROR_INSTALLATION:
sError = m_sErrorInstallation;
break;
case ERROR_LICENSE_DECLINED:
sError = m_sErrorLicenseDeclined;
break;
default:
OSL_ASSERT(0);
}
sError.SearchAndReplace(String(OUSTR("%NAME")), String(sExtension), 0);
//We want to have an empty line between the error messages. However,
//there shall be no empty line after the last entry.
if (m_bNoEntry)
m_bNoEntry = false;
else
m_mle_info.InsertText(OUSTR("\n"));
m_mle_info.InsertText(sError);
//Insert more information about the error
if (exceptionMessage.getLength())
m_mle_info.InsertText(m_sThisErrorOccurred + exceptionMessage + OUSTR("\n"));
m_mle_info.InsertText(m_sNoInstall);
m_mle_info.InsertText(OUSTR("\n"));
}
void UpdateInstallDialog::setError(OUString const & exceptionMessage)
{
m_bError = true;
m_mle_info.InsertText(exceptionMessage + OUSTR("\n"));
}
IMPL_LINK(UpdateInstallDialog, cancelHandler, void *, EMPTYARG)
{
m_thread->stop();
EndDialog(RET_CANCEL);
return 0;
}
//------------------------------------------------------------------------------------------------
void UpdateInstallDialog::Thread::downloadExtensions()
{
try
{
//create the download directory in the temp folder
OUString sTempDir;
if (::osl::FileBase::getTempDirURL(sTempDir) != ::osl::FileBase::E_None)
throw cssu::Exception(OUSTR("Could not get URL for the temp directory. No extensions will be installed."), 0);
//create a unique name for the directory
OUString tempEntry, destFolder;
if (::osl::File::createTempFile(&sTempDir, 0, &tempEntry ) != ::osl::File::E_None)
throw cssu::Exception(OUSTR("Could not create a temporary file in ") + sTempDir +
OUSTR(". No extensions will be installed"), 0 );
tempEntry = tempEntry.copy( tempEntry.lastIndexOf( '/' ) + 1 );
destFolder = dp_misc::makeURL( sTempDir, tempEntry );
destFolder += OUSTR("_");
m_sDownloadFolder = destFolder;
try
{
dp_misc::create_folder(0, destFolder, m_updateCmdEnv.get(), true );
} catch (cssu::Exception & e)
{
throw cssu::Exception(e.Message + OUSTR(" No extensions will be installed."), 0);
}
sal_uInt16 count = 0;
typedef std::vector<UpdateData>::iterator It;
for (It i = m_aVecUpdateData.begin(); i != m_aVecUpdateData.end(); i++)
{
UpdateData & curData = *i;
if (!curData.aUpdateInfo.is() || curData.aUpdateSource.is())
continue;
//We assume that m_aVecUpdateData contains only information about extensions which
//can be downloaded directly.
OSL_ASSERT(curData.sWebsiteURL.getLength() == 0);
//update the name of the extension which is to be downloaded
{
::vos::OGuard g(Application::GetSolarMutex());
if (m_stop) {
return;
}
m_dialog.m_ft_extension_name.SetText(curData.aInstalledPackage->getDisplayName());
sal_uInt16 prog = (sal::static_int_cast<sal_uInt16>(100) * ++count) /
sal::static_int_cast<sal_uInt16>(m_aVecUpdateData.size());
m_dialog.m_statusbar.SetValue(prog);
}
dp_misc::DescriptionInfoset info(m_xComponentContext, curData.aUpdateInfo);
//remember occurring exceptions in case we need to print out error information
::std::vector< ::std::pair<OUString, cssu::Exception> > vecExceptions;
cssu::Sequence<OUString> seqDownloadURLs = info.getUpdateDownloadUrls();
OSL_ENSURE(seqDownloadURLs.getLength() > 0, "No download URL provided!");
for (sal_Int32 j = 0; j < seqDownloadURLs.getLength(); j++)
{
try
{
OSL_ENSURE(seqDownloadURLs[j].getLength() > 0, "Download URL is empty!");
download(seqDownloadURLs[j], curData);
if (curData.sLocalURL.getLength() > 0)
break;
}
catch ( cssu::Exception & e )
{
vecExceptions.push_back( ::std::make_pair(seqDownloadURLs[j], e));
//There can be several different errors, for example, the URL is wrong, webserver cannot be reached,
//name cannot be resolved. The UCB helper API does not specify different special exceptions for these
//cases. Therefore ignore and continue.
continue;
}
}
//update the progress and display download error
{
::vos::OGuard g(Application::GetSolarMutex());
if (m_stop) {
return;
}
if (curData.sLocalURL.getLength() == 0)
{
//Construct a string of all messages contained in the exceptions plus the respective download URLs
::rtl::OUStringBuffer buf(256);
typedef ::std::vector< ::std::pair<OUString, cssu::Exception > >::const_iterator CIT;
for (CIT j = vecExceptions.begin(); j != vecExceptions.end(); j++)
{
if (j != vecExceptions.begin())
buf.appendAscii("\n");
buf.append(OUSTR("Could not download "));
buf.append(j->first);
buf.appendAscii(". ");
buf.append(j->second.Message);
}
m_dialog.setError(UpdateInstallDialog::ERROR_DOWNLOAD, curData.aInstalledPackage->getDisplayName(),
buf.makeStringAndClear());
}
}
}
}
catch (cssu::Exception & e)
{
::vos::OGuard g(Application::GetSolarMutex());
if (m_stop) {
return;
}
m_dialog.setError(e.Message);
}
}
void UpdateInstallDialog::Thread::installExtensions()
{
//Update the fix text in the dialog to "Installing extensions..."
{
vos::OGuard g(Application::GetSolarMutex());
if (m_stop) {
return;
}
m_dialog.m_ft_action.SetText(m_dialog.m_sInstalling);
m_dialog.m_statusbar.SetValue(0);
}
sal_uInt16 count = 0;
typedef std::vector<UpdateData>::iterator It;
for (It i = m_aVecUpdateData.begin(); i != m_aVecUpdateData.end(); i++, count++)
{
//update the name of the extension which is to be installed
{
::vos::OGuard g(Application::GetSolarMutex());
if (m_stop) {
return;
}
//we only show progress after an extension has been installed.
if (count > 0) {
m_dialog.m_statusbar.SetValue(
(sal::static_int_cast<sal_uInt16>(100) * count) /
sal::static_int_cast<sal_uInt16>(m_aVecUpdateData.size()));
}
m_dialog.m_ft_extension_name.SetText(i->aInstalledPackage->getDisplayName());
}
// TimeValue v = {1, 0};
// osl::Thread::wait(v);
bool bError = false;
bool bLicenseDeclined = false;
cssu::Reference<css::deployment::XPackage> xExtension;
UpdateData & curData = *i;
cssu::Exception exc;
try
{
cssu::Reference< css::task::XAbortChannel > xAbortChannel(
curData.aInstalledPackage->createAbortChannel() );
{
vos::OGuard g(Application::GetSolarMutex());
if (m_stop) {
return;
}
m_abort = xAbortChannel;
}
if (!curData.aUpdateSource.is() && curData.sLocalURL.getLength())
{
css::beans::NamedValue prop(OUSTR("EXTENSION_UPDATE"), css::uno::makeAny(OUSTR("1")));
if (!curData.bIsShared)
xExtension = m_dialog.getExtensionManager()->addExtension(
curData.sLocalURL, css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
OUSTR("user"), xAbortChannel, m_updateCmdEnv.get());
else
xExtension = m_dialog.getExtensionManager()->addExtension(
curData.sLocalURL, css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
OUSTR("shared"), xAbortChannel, m_updateCmdEnv.get());
}
else if (curData.aUpdateSource.is())
{
OSL_ASSERT(curData.aUpdateSource.is());
//I am not sure if we should obtain the install properties and pass them into
//add extension. Currently it contains only "SUPPRESS_LICENSE". So it it could happen
//that a license is displayed when updating from the shared repository, although the
//shared extension was installed using "SUPPRESS_LICENSE".
css::beans::NamedValue prop(OUSTR("EXTENSION_UPDATE"), css::uno::makeAny(OUSTR("1")));
if (!curData.bIsShared)
xExtension = m_dialog.getExtensionManager()->addExtension(
curData.aUpdateSource->getURL(), css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
OUSTR("user"), xAbortChannel, m_updateCmdEnv.get());
else
xExtension = m_dialog.getExtensionManager()->addExtension(
curData.aUpdateSource->getURL(), css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
OUSTR("shared"), xAbortChannel, m_updateCmdEnv.get());
}
}
catch (css::deployment::DeploymentException & de)
{
if (de.Cause.has<css::deployment::LicenseException>())
{
bLicenseDeclined = true;
}
else
{
exc = de.Cause.get<cssu::Exception>();
bError = true;
}
}
catch (cssu::Exception& e)
{
exc = e;
bError = true;
}
if (bLicenseDeclined)
{
::vos::OGuard g(Application::GetSolarMutex());
if (m_stop) {
return;
}
m_dialog.setError(UpdateInstallDialog::ERROR_LICENSE_DECLINED,
curData.aInstalledPackage->getDisplayName(), OUString());
}
else if (!xExtension.is() || bError)
{
::vos::OGuard g(Application::GetSolarMutex());
if (m_stop) {
return;
}
m_dialog.setError(UpdateInstallDialog::ERROR_INSTALLATION,
curData.aInstalledPackage->getDisplayName(), exc.Message);
}
}
{
vos::OGuard g(Application::GetSolarMutex());
if (m_stop) {
return;
}
m_dialog.m_statusbar.SetValue(100);
m_dialog.m_ft_extension_name.SetText(OUString());
m_dialog.m_ft_action.SetText(m_dialog.m_sFinished);
}
}
void UpdateInstallDialog::Thread::removeTempDownloads()
{
if (m_sDownloadFolder.getLength())
{
dp_misc::erase_path(m_sDownloadFolder,
cssu::Reference<css::ucb::XCommandEnvironment>(),false /* no throw: ignore errors */ );
//remove also the temp file which we have used to create the unique name
OUString tempFile = m_sDownloadFolder.copy(0, m_sDownloadFolder.getLength() - 1);
dp_misc::erase_path(tempFile, cssu::Reference<css::ucb::XCommandEnvironment>(),false);
m_sDownloadFolder = OUString();
}
}
void UpdateInstallDialog::Thread::download(OUString const & sDownloadURL, UpdateData & aUpdateData)
{
{
::vos::OGuard g(Application::GetSolarMutex());
if (m_stop) {
return;
}
}
OSL_ASSERT(m_sDownloadFolder.getLength());
OUString destFolder, tempEntry;
if (::osl::File::createTempFile(
&m_sDownloadFolder,
0, &tempEntry ) != ::osl::File::E_None)
{
//ToDo feedback in window that download of this component failed
throw cssu::Exception(OUSTR("Could not create temporary file in folder ") + destFolder + OUSTR("."), 0);
}
tempEntry = tempEntry.copy( tempEntry.lastIndexOf( '/' ) + 1 );
destFolder = dp_misc::makeURL( m_sDownloadFolder, tempEntry );
destFolder += OUSTR("_");
::ucbhelper::Content destFolderContent;
dp_misc::create_folder( &destFolderContent, destFolder, m_updateCmdEnv.get() );
::ucbhelper::Content sourceContent;
dp_misc::create_ucb_content( &sourceContent, sDownloadURL, m_updateCmdEnv.get() );
const OUString sTitle(sourceContent.getPropertyValue(
dp_misc::StrTitle::get() ).get<OUString>() );
if (destFolderContent.transferContent(
sourceContent, ::ucbhelper::InsertOperation_COPY,
sTitle, css::ucb::NameClash::OVERWRITE ))
{
//the user may have cancelled the dialog because downloading took to long
{
::vos::OGuard g(Application::GetSolarMutex());
if (m_stop) {
return;
}
//all errors should be handeld by the command environment.
aUpdateData.sLocalURL = destFolder + OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) ) + sTitle;
}
}
}
// -------------------------------------------------------------------------------------------------------
UpdateCommandEnv::UpdateCommandEnv( cssu::Reference< cssu::XComponentContext > const & xCtx,
UpdateInstallDialog & updateDialog,
::rtl::Reference<UpdateInstallDialog::Thread>const & thread)
: m_updateDialog( updateDialog ),
m_installThread(thread),
m_xContext(xCtx)
{
}
UpdateCommandEnv::~UpdateCommandEnv()
{
}
// XCommandEnvironment
//______________________________________________________________________________
cssu::Reference<css::task::XInteractionHandler> UpdateCommandEnv::getInteractionHandler()
throw (cssu::RuntimeException)
{
return this;
}
//______________________________________________________________________________
cssu::Reference<css::ucb::XProgressHandler> UpdateCommandEnv::getProgressHandler()
throw (cssu::RuntimeException)
{
return this;
}
// XInteractionHandler
void UpdateCommandEnv::handle(
cssu::Reference< css::task::XInteractionRequest> const & xRequest )
throw (cssu::RuntimeException)
{
cssu::Any request( xRequest->getRequest() );
OSL_ASSERT( request.getValueTypeClass() == cssu::TypeClass_EXCEPTION );
dp_misc::TRACE(OUSTR("[dp_gui_cmdenv.cxx] incoming request:\n")
+ ::comphelper::anyToString(request) + OUSTR("\n\n"));
css::deployment::VersionException verExc;
bool approve = false;
bool abort = false;
if (request >>= verExc)
{ //We must catch the version exception during the update,
//because otherwise the user would be confronted with the dialogs, asking
//them if they want to replace an already installed version of the same extension.
//During an update we assume that we always want to replace the old version with the
//new version.
approve = true;
}
if (approve == false && abort == false)
{
//forward to interaction handler for main dialog.
handleInteractionRequest( m_xContext, xRequest );
}
else
{
// select:
cssu::Sequence< cssu::Reference< css::task::XInteractionContinuation > > conts(
xRequest->getContinuations() );
cssu::Reference< css::task::XInteractionContinuation > const * pConts =
conts.getConstArray();
sal_Int32 len = conts.getLength();
for ( sal_Int32 pos = 0; pos < len; ++pos )
{
if (approve) {
cssu::Reference< css::task::XInteractionApprove > xInteractionApprove(
pConts[ pos ], cssu::UNO_QUERY );
if (xInteractionApprove.is()) {
xInteractionApprove->select();
// don't query again for ongoing continuations:
approve = false;
}
}
else if (abort) {
cssu::Reference< css::task::XInteractionAbort > xInteractionAbort(
pConts[ pos ], cssu::UNO_QUERY );
if (xInteractionAbort.is()) {
xInteractionAbort->select();
// don't query again for ongoing continuations:
abort = false;
}
}
}
}
}
// XProgressHandler
void UpdateCommandEnv::push( cssu::Any const & /*Status*/ )
throw (cssu::RuntimeException)
{
}
void UpdateCommandEnv::update( cssu::Any const & /*Status */)
throw (cssu::RuntimeException)
{
}
void UpdateCommandEnv::pop() throw (cssu::RuntimeException)
{
}
} //end namespace dp_gui