diff options
Diffstat (limited to 'desktop/source/deployment/gui/dp_gui_updateinstalldialog.cxx')
-rw-r--r-- | desktop/source/deployment/gui/dp_gui_updateinstalldialog.cxx | 757 |
1 files changed, 757 insertions, 0 deletions
diff --git a/desktop/source/deployment/gui/dp_gui_updateinstalldialog.cxx b/desktop/source/deployment/gui/dp_gui_updateinstalldialog.cxx new file mode 100644 index 000000000000..696c2fe3ef0c --- /dev/null +++ b/desktop/source/deployment/gui/dp_gui_updateinstalldialog.cxx @@ -0,0 +1,757 @@ +/* -*- 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. + * + ************************************************************************/ + +// 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 "osl/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 "osl/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; + { + SolarMutexGuard g; + 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 + SolarMutexGuard g; + 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 + { + SolarMutexGuard g; + 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 + { + SolarMutexGuard g; + 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) + { + SolarMutexGuard g; + if (m_stop) { + return; + } + m_dialog.setError(e.Message); + } +} +void UpdateInstallDialog::Thread::installExtensions() +{ + //Update the fix text in the dialog to "Installing extensions..." + { + SolarMutexGuard g; + 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 + { + SolarMutexGuard g; + 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()); + } + 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() ); + { + SolarMutexGuard g; + 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) + { + SolarMutexGuard g; + if (m_stop) { + return; + } + m_dialog.setError(UpdateInstallDialog::ERROR_LICENSE_DECLINED, + curData.aInstalledPackage->getDisplayName(), OUString()); + } + else if (!xExtension.is() || bError) + { + SolarMutexGuard g; + if (m_stop) { + return; + } + m_dialog.setError(UpdateInstallDialog::ERROR_INSTALLATION, + curData.aInstalledPackage->getDisplayName(), exc.Message); + } + } + { + SolarMutexGuard g; + 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) +{ + { + SolarMutexGuard g; + 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 + { + SolarMutexGuard g; + 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 + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |