LCOV - code coverage report
Current view: top level - libreoffice/desktop/source/deployment/gui - dp_gui_updateinstalldialog.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 266 0.0 %
Date: 2012-12-27 Functions: 0 28 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include "dp_gui_updatedata.hxx"
      22             : 
      23             : #include "sal/config.h"
      24             : #include "osl/file.hxx"
      25             : #include "osl/conditn.hxx"
      26             : #include "cppuhelper/exc_hlp.hxx"
      27             : #include "tools/resid.hxx"
      28             : #include "tools/solar.h"
      29             : #include "tools/string.hxx"
      30             : #include "vcl/dialog.hxx"
      31             : #include "vcl/msgbox.hxx"
      32             : #include "vcl/svapp.hxx"
      33             : #include "osl/mutex.hxx"
      34             : #include "cppuhelper/implbase3.hxx"
      35             : 
      36             : #include "com/sun/star/beans/PropertyValue.hpp"
      37             : #include "com/sun/star/beans/NamedValue.hpp"
      38             : #include "com/sun/star/xml/dom/XElement.hpp"
      39             : #include "com/sun/star/xml/dom/XNode.hpp"
      40             : #include "com/sun/star/xml/dom/XNodeList.hpp"
      41             : #include "com/sun/star/ucb/NameClash.hpp"
      42             : #include "com/sun/star/ucb/InteractiveAugmentedIOException.hpp"
      43             : #include "com/sun/star/ucb/XCommandEnvironment.hpp"
      44             : #include "com/sun/star/ucb/XProgressHandler.hpp"
      45             : #include "com/sun/star/deployment/XExtensionManager.hpp"
      46             : #include "com/sun/star/deployment/ExtensionManager.hpp"
      47             : #include "com/sun/star/deployment/XUpdateInformationProvider.hpp"
      48             : #include "com/sun/star/deployment/DependencyException.hpp"
      49             : #include "com/sun/star/deployment/LicenseException.hpp"
      50             : #include "com/sun/star/deployment/VersionException.hpp"
      51             : #include "com/sun/star/deployment/ui/LicenseDialog.hpp"
      52             : #include "com/sun/star/task/XInteractionHandler.hpp"
      53             : #include "com/sun/star/ui/dialogs/XExecutableDialog.hpp"
      54             : #include "com/sun/star/ui/dialogs/ExecutableDialogResults.hpp"
      55             : #include "com/sun/star/task/XInteractionAbort.hpp"
      56             : #include "com/sun/star/task/XInteractionApprove.hpp"
      57             : 
      58             : #include "dp_descriptioninfoset.hxx"
      59             : #include "dp_gui.hrc"
      60             : #include "dp_gui_updateinstalldialog.hxx"
      61             : #include "dp_gui_shared.hxx"
      62             : #include "dp_ucb.h"
      63             : #include "dp_misc.h"
      64             : #include "dp_version.hxx"
      65             : #include "dp_gui_extensioncmdqueue.hxx"
      66             : #include "ucbhelper/content.hxx"
      67             : #include "osl/mutex.hxx"
      68             : #include "rtl/ref.hxx"
      69             : #include "salhelper/thread.hxx"
      70             : #include "com/sun/star/uno/Sequence.h"
      71             : #include "comphelper/anytostring.hxx"
      72             : #include "toolkit/helper/vclunohelper.hxx"
      73             : 
      74             : #include <vector>
      75             : 
      76             : class Window;
      77             : 
      78             : namespace cssu = ::com::sun::star::uno;
      79             : 
      80             : using dp_misc::StrTitle;
      81             : using ::rtl::OUString;
      82             : 
      83             : namespace dp_gui {
      84             : 
      85             : class UpdateInstallDialog::Thread: public salhelper::Thread {
      86             :     friend class UpdateCommandEnv;
      87             : public:
      88             :     Thread(cssu::Reference< cssu::XComponentContext > ctx,
      89             :         UpdateInstallDialog & dialog, std::vector< dp_gui::UpdateData > & aVecUpdateData);
      90             : 
      91             :     void stop();
      92             : 
      93             : 
      94             : 
      95             : private:
      96             :     virtual ~Thread();
      97             : 
      98             :     virtual void execute();
      99             :     void downloadExtensions();
     100             :     void download(::rtl::OUString const & aUrls, UpdateData & aUpdatData);
     101             :     void installExtensions();
     102             :     void removeTempDownloads();
     103             : 
     104             :     UpdateInstallDialog & m_dialog;
     105             :     cssu::Reference< css::deployment::XUpdateInformationProvider >
     106             :         m_updateInformation;
     107             : 
     108             :     // guarded by Application::GetSolarMutex():
     109             :     cssu::Reference< css::task::XAbortChannel > m_abort;
     110             :     cssu::Reference< cssu::XComponentContext > m_xComponentContext;
     111             :     std::vector< dp_gui::UpdateData > & m_aVecUpdateData;
     112             :     ::rtl::Reference<UpdateCommandEnv> m_updateCmdEnv;
     113             : 
     114             :     //A folder which is created in the temp directory in which then the updates are downloaded
     115             :     ::rtl::OUString m_sDownloadFolder;
     116             : 
     117             :     bool m_stop;
     118             : 
     119             : };
     120             : 
     121             : class UpdateCommandEnv
     122             :     : public ::cppu::WeakImplHelper3< css::ucb::XCommandEnvironment,
     123             :                                       css::task::XInteractionHandler,
     124             :                                       css::ucb::XProgressHandler >
     125             : {
     126             :     friend class UpdateInstallDialog::Thread;
     127             : 
     128             :     ::rtl::Reference<UpdateInstallDialog::Thread> m_installThread;
     129             :     cssu::Reference< cssu::XComponentContext > m_xContext;
     130             : 
     131             : public:
     132             :     virtual ~UpdateCommandEnv();
     133             :     UpdateCommandEnv( cssu::Reference< cssu::XComponentContext > const & xCtx,
     134             :         ::rtl::Reference<UpdateInstallDialog::Thread>const & thread);
     135             : 
     136             :     // XCommandEnvironment
     137             :     virtual cssu::Reference<css::task::XInteractionHandler > SAL_CALL
     138             :     getInteractionHandler() throw (cssu::RuntimeException);
     139             :     virtual cssu::Reference<css::ucb::XProgressHandler >
     140             :     SAL_CALL getProgressHandler() throw (cssu::RuntimeException);
     141             : 
     142             :     // XInteractionHandler
     143             :     virtual void SAL_CALL handle(
     144             :         cssu::Reference<css::task::XInteractionRequest > const & xRequest )
     145             :         throw (cssu::RuntimeException);
     146             : 
     147             :     // XProgressHandler
     148             :     virtual void SAL_CALL push( cssu::Any const & Status )
     149             :         throw (cssu::RuntimeException);
     150             :     virtual void SAL_CALL update( cssu::Any const & Status )
     151             :         throw (cssu::RuntimeException);
     152             :     virtual void SAL_CALL pop() throw (cssu::RuntimeException);
     153             : };
     154             : 
     155             : 
     156           0 : UpdateInstallDialog::Thread::Thread(
     157             :     cssu::Reference< cssu::XComponentContext> xCtx,
     158             :     UpdateInstallDialog & dialog,
     159             :     std::vector< dp_gui::UpdateData > & aVecUpdateData):
     160             :     salhelper::Thread("dp_gui_updateinstalldialog"),
     161             :     m_dialog(dialog),
     162             :     m_xComponentContext(xCtx),
     163             :     m_aVecUpdateData(aVecUpdateData),
     164           0 :     m_updateCmdEnv(new UpdateCommandEnv(xCtx, this)),
     165           0 :     m_stop(false)
     166           0 : {}
     167             : 
     168           0 : void UpdateInstallDialog::Thread::stop() {
     169           0 :     cssu::Reference< css::task::XAbortChannel > abort;
     170             :     {
     171           0 :         SolarMutexGuard g;
     172           0 :         abort = m_abort;
     173           0 :         m_stop = true;
     174             :     }
     175           0 :     if (abort.is()) {
     176           0 :         abort->sendAbort();
     177           0 :     }
     178           0 : }
     179             : 
     180           0 : UpdateInstallDialog::Thread::~Thread() {}
     181             : 
     182           0 : void UpdateInstallDialog::Thread::execute()
     183             : {
     184             :     try {
     185           0 :         downloadExtensions();
     186           0 :         installExtensions();
     187             :     }
     188           0 :     catch (...)
     189             :     {
     190             :     }
     191             : 
     192             :     //clean up the temp directories
     193             :     try {
     194           0 :         removeTempDownloads();
     195           0 :     } catch( ... ) {
     196             :     }
     197             : 
     198             :     {
     199             :         //make sure m_dialog is still alive
     200           0 :         SolarMutexGuard g;
     201           0 :         if (! m_stop)
     202           0 :              m_dialog.updateDone();
     203             :     }
     204             :     //UpdateCommandEnv keeps a reference to Thread and prevents destruction. Therefore remove it.
     205           0 :     m_updateCmdEnv->m_installThread.clear();
     206           0 : }
     207             : 
     208             : 
     209           0 : UpdateInstallDialog::UpdateInstallDialog(
     210             :     Window * parent,
     211             :     std::vector<dp_gui::UpdateData> & aVecUpdateData,
     212             :     cssu::Reference< cssu::XComponentContext > const & xCtx):
     213             :     ModalDialog(
     214             :         parent,
     215             :         DpGuiResId(RID_DLG_UPDATEINSTALL)),
     216             : 
     217           0 :         m_thread(new Thread(xCtx, *this, aVecUpdateData)),
     218             :         m_xComponentContext(xCtx),
     219             :         m_bError(false),
     220             :         m_bNoEntry(true),
     221             :         m_bActivated(false),
     222             :         m_sInstalling(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_INSTALLING))),
     223             :         m_sFinished(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_FINISHED))),
     224             :         m_sNoErrors(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_NO_ERRORS))),
     225             :         m_sErrorDownload(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_ERROR_DOWNLOAD))),
     226             :         m_sErrorInstallation(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_ERROR_INSTALLATION))),
     227             :         m_sErrorLicenseDeclined(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_ERROR_LIC_DECLINED))),
     228             :         m_sNoInstall(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_EXTENSION_NOINSTALL))),
     229             :         m_sThisErrorOccurred(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_THIS_ERROR_OCCURRED))),
     230             :         m_ft_action(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_DOWNLOADING)),
     231             :         m_statusbar(this,DpGuiResId(RID_DLG_UPDATE_INSTALL_STATUSBAR)),
     232             :         m_ft_extension_name(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_EXTENSION_NAME)),
     233             :         m_ft_results(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_RESULTS)),
     234             :         m_mle_info(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_INFO)),
     235             :         m_line(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_LINE)),
     236             :         m_help(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_HELP)),
     237             :         m_ok(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_OK)),
     238           0 :         m_cancel(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_ABORT))
     239             : {
     240           0 :     FreeResource();
     241             : 
     242           0 :     m_xExtensionManager = css::deployment::ExtensionManager::get( xCtx );
     243             : 
     244           0 :     m_cancel.SetClickHdl(LINK(this, UpdateInstallDialog, cancelHandler));
     245           0 :     m_mle_info.EnableCursor(sal_False);
     246           0 :     if ( ! dp_misc::office_is_running())
     247           0 :         m_help.Disable();
     248           0 : }
     249             : 
     250           0 : UpdateInstallDialog::~UpdateInstallDialog() {}
     251             : 
     252           0 : sal_Bool UpdateInstallDialog::Close()
     253             : {
     254           0 :     m_thread->stop();
     255           0 :     return ModalDialog::Close();
     256             : }
     257             : 
     258           0 : short UpdateInstallDialog::Execute()
     259             : {
     260           0 :     m_thread->launch();
     261           0 :     return ModalDialog::Execute();
     262             : }
     263             : 
     264             : 
     265             : // make sure the solar mutex is locked before calling
     266           0 : void UpdateInstallDialog::updateDone()
     267             : {
     268           0 :     if (!m_bError)
     269           0 :         m_mle_info.InsertText(m_sNoErrors);
     270           0 :     m_ok.Enable();
     271           0 :     m_ok.GrabFocus();
     272           0 :     m_cancel.Disable();
     273           0 : }
     274             : // make sure the solar mutex is locked before calling
     275             : //sets an error message in the text area
     276           0 : void UpdateInstallDialog::setError(INSTALL_ERROR err, ::rtl::OUString const & sExtension,
     277             :     OUString const & exceptionMessage)
     278             : {
     279           0 :     String sError;
     280           0 :     m_bError = true;
     281             : 
     282           0 :     switch (err)
     283             :     {
     284             :     case ERROR_DOWNLOAD:
     285           0 :         sError = m_sErrorDownload;
     286           0 :         break;
     287             :     case ERROR_INSTALLATION:
     288           0 :         sError = m_sErrorInstallation;
     289           0 :         break;
     290             :     case ERROR_LICENSE_DECLINED:
     291           0 :         sError = m_sErrorLicenseDeclined;
     292           0 :         break;
     293             : 
     294             :     default:
     295             :         OSL_ASSERT(0);
     296             :     }
     297             : 
     298           0 :     sError.SearchAndReplace(String(OUSTR("%NAME")), String(sExtension), 0);
     299             :     //We want to have an empty line between the error messages. However,
     300             :     //there shall be no empty line after the last entry.
     301           0 :     if (m_bNoEntry)
     302           0 :         m_bNoEntry = false;
     303             :     else
     304           0 :         m_mle_info.InsertText(OUSTR("\n"));
     305           0 :     m_mle_info.InsertText(sError);
     306             :     //Insert more information about the error
     307           0 :     if (!exceptionMessage.isEmpty())
     308           0 :         m_mle_info.InsertText(m_sThisErrorOccurred + exceptionMessage + OUSTR("\n"));
     309             : 
     310           0 :     m_mle_info.InsertText(m_sNoInstall);
     311           0 :     m_mle_info.InsertText(OUSTR("\n"));
     312           0 : }
     313             : 
     314           0 : void UpdateInstallDialog::setError(OUString const & exceptionMessage)
     315             : {
     316           0 :     m_bError = true;
     317           0 :     m_mle_info.InsertText(exceptionMessage + OUSTR("\n"));
     318           0 : }
     319             : 
     320           0 : IMPL_LINK_NOARG(UpdateInstallDialog, cancelHandler)
     321             : {
     322           0 :     m_thread->stop();
     323           0 :     EndDialog(RET_CANCEL);
     324           0 :     return 0;
     325             : }
     326             : 
     327             : //------------------------------------------------------------------------------------------------
     328             : 
     329           0 : void UpdateInstallDialog::Thread::downloadExtensions()
     330             : {
     331             :     try
     332             :     {
     333             :         //create the download directory in the temp folder
     334           0 :         OUString sTempDir;
     335           0 :         if (::osl::FileBase::getTempDirURL(sTempDir) != ::osl::FileBase::E_None)
     336           0 :             throw cssu::Exception(OUSTR("Could not get URL for the temp directory. No extensions will be installed."), 0);
     337             : 
     338             :         //create a unique name for the directory
     339           0 :         OUString tempEntry, destFolder;
     340           0 :         if (::osl::File::createTempFile(&sTempDir, 0, &tempEntry ) != ::osl::File::E_None)
     341           0 :             throw cssu::Exception(OUSTR("Could not create a temporary file in ") + sTempDir +
     342           0 :              OUSTR(". No extensions will be installed"), 0 );
     343             : 
     344           0 :         tempEntry = tempEntry.copy( tempEntry.lastIndexOf( '/' ) + 1 );
     345             : 
     346           0 :         destFolder = dp_misc::makeURL( sTempDir, tempEntry );
     347           0 :         destFolder += OUSTR("_");
     348           0 :         m_sDownloadFolder = destFolder;
     349             :         try
     350             :         {
     351           0 :             dp_misc::create_folder(0, destFolder, m_updateCmdEnv.get(), true );
     352           0 :         } catch (const cssu::Exception & e)
     353             :         {
     354           0 :             throw cssu::Exception(e.Message + OUSTR(" No extensions will be installed."), 0);
     355             :         }
     356             : 
     357             : 
     358           0 :         sal_uInt16 count = 0;
     359             :         typedef std::vector<UpdateData>::iterator It;
     360           0 :         for (It i = m_aVecUpdateData.begin(); i != m_aVecUpdateData.end(); ++i)
     361             :         {
     362           0 :             UpdateData & curData = *i;
     363             : 
     364           0 :             if (!curData.aUpdateInfo.is() || curData.aUpdateSource.is())
     365           0 :                 continue;
     366             :             //We assume that m_aVecUpdateData contains only information about extensions which
     367             :             //can be downloaded directly.
     368             :             OSL_ASSERT(curData.sWebsiteURL.isEmpty());
     369             : 
     370             :             //update the name of the extension which is to be downloaded
     371             :             {
     372           0 :                 SolarMutexGuard g;
     373           0 :                 if (m_stop) {
     374             :                     return;
     375             :                 }
     376           0 :                 m_dialog.m_ft_extension_name.SetText(curData.aInstalledPackage->getDisplayName());
     377           0 :                 sal_uInt16 prog = (sal::static_int_cast<sal_uInt16>(100) * ++count) /
     378           0 :                     sal::static_int_cast<sal_uInt16>(m_aVecUpdateData.size());
     379           0 :                 m_dialog.m_statusbar.SetValue(prog);
     380             :             }
     381           0 :             dp_misc::DescriptionInfoset info(m_xComponentContext, curData.aUpdateInfo);
     382             :             //remember occurring exceptions in case we need to print out error information
     383           0 :             ::std::vector< ::std::pair<OUString, cssu::Exception> > vecExceptions;
     384           0 :             cssu::Sequence<OUString> seqDownloadURLs = info.getUpdateDownloadUrls();
     385             :             OSL_ENSURE(seqDownloadURLs.getLength() > 0, "No download URL provided!");
     386           0 :             for (sal_Int32 j = 0; j < seqDownloadURLs.getLength(); j++)
     387             :             {
     388             :                 try
     389             :                 {
     390             :                     OSL_ENSURE(!seqDownloadURLs[j].isEmpty(), "Download URL is empty!");
     391           0 :                     download(seqDownloadURLs[j], curData);
     392           0 :                     if (!curData.sLocalURL.isEmpty())
     393           0 :                         break;
     394             :                 }
     395           0 :                 catch ( cssu::Exception & e )
     396             :                 {
     397           0 :                     vecExceptions.push_back( ::std::make_pair(seqDownloadURLs[j], e));
     398             :                     //There can be several different errors, for example, the URL is wrong, webserver cannot be reached,
     399             :                     //name cannot be resolved. The UCB helper API does not specify different special exceptions for these
     400             :                     //cases. Therefore ignore and continue.
     401           0 :                     continue;
     402             :                 }
     403             :             }
     404             :             //update the progress and display download error
     405             :             {
     406           0 :                 SolarMutexGuard g;
     407           0 :                 if (m_stop) {
     408             :                     return;
     409             :                 }
     410           0 :                 if (curData.sLocalURL.isEmpty())
     411             :                 {
     412             :                     //Construct a string of all messages contained in the exceptions plus the respective download URLs
     413           0 :                     ::rtl::OUStringBuffer buf(256);
     414             :                     typedef ::std::vector< ::std::pair<OUString, cssu::Exception > >::const_iterator CIT;
     415           0 :                     for (CIT j = vecExceptions.begin(); j != vecExceptions.end(); ++j)
     416             :                     {
     417           0 :                         if (j != vecExceptions.begin())
     418           0 :                             buf.appendAscii("\n");
     419           0 :                         buf.append(OUSTR("Could not download "));
     420           0 :                         buf.append(j->first);
     421           0 :                         buf.appendAscii(". ");
     422           0 :                         buf.append(j->second.Message);
     423             :                     }
     424           0 :                     m_dialog.setError(UpdateInstallDialog::ERROR_DOWNLOAD, curData.aInstalledPackage->getDisplayName(),
     425           0 :                         buf.makeStringAndClear());
     426           0 :                 }
     427             :             }
     428             : 
     429           0 :         }
     430             :     }
     431           0 :     catch (const cssu::Exception & e)
     432             :     {
     433           0 :         SolarMutexGuard g;
     434           0 :         if (m_stop) {
     435             :             return;
     436             :         }
     437           0 :         m_dialog.setError(e.Message);
     438             :     }
     439             : }
     440           0 : void UpdateInstallDialog::Thread::installExtensions()
     441             : {
     442             :     //Update the fix text in the dialog to "Installing extensions..."
     443             :     {
     444           0 :         SolarMutexGuard g;
     445           0 :         if (m_stop) {
     446             :             return;
     447             :         }
     448           0 :         m_dialog.m_ft_action.SetText(m_dialog.m_sInstalling);
     449           0 :         m_dialog.m_statusbar.SetValue(0);
     450             :     }
     451             : 
     452           0 :     sal_uInt16 count = 0;
     453             :     typedef std::vector<UpdateData>::iterator It;
     454           0 :     for (It i = m_aVecUpdateData.begin(); i != m_aVecUpdateData.end(); ++i, ++count)
     455             :     {
     456             :         //update the name of the extension which is to be installed
     457             :         {
     458           0 :             SolarMutexGuard g;
     459           0 :             if (m_stop) {
     460             :                 return;
     461             :             }
     462             :             //we only show progress after an extension has been installed.
     463           0 :             if (count > 0) {
     464             :                 m_dialog.m_statusbar.SetValue(
     465           0 :                 (sal::static_int_cast<sal_uInt16>(100) * count) /
     466           0 :                 sal::static_int_cast<sal_uInt16>(m_aVecUpdateData.size()));
     467             :              }
     468           0 :             m_dialog.m_ft_extension_name.SetText(i->aInstalledPackage->getDisplayName());
     469             :         }
     470           0 :         bool bError = false;
     471           0 :         bool bLicenseDeclined = false;
     472           0 :         cssu::Reference<css::deployment::XPackage> xExtension;
     473           0 :         UpdateData & curData = *i;
     474           0 :         cssu::Exception exc;
     475             :         try
     476             :         {
     477             :             cssu::Reference< css::task::XAbortChannel > xAbortChannel(
     478           0 :                 curData.aInstalledPackage->createAbortChannel() );
     479             :             {
     480           0 :                 SolarMutexGuard g;
     481           0 :                 if (m_stop) {
     482             :                     return;
     483             :                 }
     484           0 :                 m_abort = xAbortChannel;
     485             :             }
     486           0 :             if (!curData.aUpdateSource.is() && !curData.sLocalURL.isEmpty())
     487             :             {
     488           0 :                 css::beans::NamedValue prop(OUSTR("EXTENSION_UPDATE"), css::uno::makeAny(OUSTR("1")));
     489           0 :                 if (!curData.bIsShared)
     490           0 :                     xExtension = m_dialog.getExtensionManager()->addExtension(
     491             :                         curData.sLocalURL, css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
     492           0 :                         OUSTR("user"), xAbortChannel, m_updateCmdEnv.get());
     493             :                 else
     494           0 :                     xExtension = m_dialog.getExtensionManager()->addExtension(
     495             :                         curData.sLocalURL, css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
     496           0 :                         OUSTR("shared"), xAbortChannel, m_updateCmdEnv.get());
     497             :             }
     498           0 :             else if (curData.aUpdateSource.is())
     499             :             {
     500             :                 OSL_ASSERT(curData.aUpdateSource.is());
     501             :                 //I am not sure if we should obtain the install properties and pass them into
     502             :                 //add extension. Currently it contains only "SUPPRESS_LICENSE". So it it could happen
     503             :                 //that a license is displayed when updating from the shared repository, although the
     504             :                 //shared extension was installed using "SUPPRESS_LICENSE".
     505           0 :                 css::beans::NamedValue prop(OUSTR("EXTENSION_UPDATE"), css::uno::makeAny(OUSTR("1")));
     506           0 :                 if (!curData.bIsShared)
     507           0 :                     xExtension = m_dialog.getExtensionManager()->addExtension(
     508           0 :                         curData.aUpdateSource->getURL(), css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
     509           0 :                         OUSTR("user"), xAbortChannel, m_updateCmdEnv.get());
     510             :                 else
     511           0 :                     xExtension = m_dialog.getExtensionManager()->addExtension(
     512           0 :                         curData.aUpdateSource->getURL(), css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
     513           0 :                         OUSTR("shared"), xAbortChannel, m_updateCmdEnv.get());
     514           0 :             }
     515             :         }
     516           0 :         catch (css::deployment::DeploymentException & de)
     517             :         {
     518           0 :             if (de.Cause.has<css::deployment::LicenseException>())
     519             :             {
     520           0 :                 bLicenseDeclined = true;
     521             :             }
     522             :             else
     523             :             {
     524           0 :                 exc = de.Cause.get<cssu::Exception>();
     525           0 :                 bError = true;
     526             :             }
     527             :         }
     528           0 :         catch (cssu::Exception& e)
     529             :         {
     530           0 :             exc = e;
     531           0 :             bError = true;
     532             :         }
     533             : 
     534           0 :         if (bLicenseDeclined)
     535             :         {
     536           0 :             SolarMutexGuard g;
     537           0 :             if (m_stop) {
     538             :                 return;
     539             :             }
     540             :             m_dialog.setError(UpdateInstallDialog::ERROR_LICENSE_DECLINED,
     541           0 :                 curData.aInstalledPackage->getDisplayName(), OUString());
     542             :         }
     543           0 :         else if (!xExtension.is() || bError)
     544             :         {
     545           0 :             SolarMutexGuard g;
     546           0 :             if (m_stop) {
     547             :                 return;
     548             :             }
     549             :             m_dialog.setError(UpdateInstallDialog::ERROR_INSTALLATION,
     550           0 :                 curData.aInstalledPackage->getDisplayName(), exc.Message);
     551             :         }
     552           0 :     }
     553             :     {
     554           0 :         SolarMutexGuard g;
     555           0 :         if (m_stop) {
     556             :             return;
     557             :         }
     558           0 :         m_dialog.m_statusbar.SetValue(100);
     559           0 :         m_dialog.m_ft_extension_name.SetText(OUString());
     560           0 :         m_dialog.m_ft_action.SetText(m_dialog.m_sFinished);
     561             :     }
     562             : }
     563             : 
     564           0 : void UpdateInstallDialog::Thread::removeTempDownloads()
     565             : {
     566           0 :     if (!m_sDownloadFolder.isEmpty())
     567             :     {
     568             :         dp_misc::erase_path(m_sDownloadFolder,
     569           0 :             cssu::Reference<css::ucb::XCommandEnvironment>(),false /* no throw: ignore errors */ );
     570             :         //remove also the temp file which we have used to create the unique name
     571           0 :         OUString tempFile = m_sDownloadFolder.copy(0, m_sDownloadFolder.getLength() - 1);
     572           0 :         dp_misc::erase_path(tempFile, cssu::Reference<css::ucb::XCommandEnvironment>(),false);
     573           0 :         m_sDownloadFolder = OUString();
     574             :     }
     575           0 : }
     576             : 
     577             : 
     578           0 : void UpdateInstallDialog::Thread::download(OUString const & sDownloadURL, UpdateData & aUpdateData)
     579             : {
     580             :     {
     581           0 :         SolarMutexGuard g;
     582           0 :         if (m_stop) {
     583             :             return;
     584           0 :         }
     585             :     }
     586             : 
     587             :     OSL_ASSERT(m_sDownloadFolder.getLength());
     588           0 :     OUString destFolder, tempEntry;
     589           0 :     if (::osl::File::createTempFile(
     590             :         &m_sDownloadFolder,
     591           0 :         0, &tempEntry ) != ::osl::File::E_None)
     592             :     {
     593             :         //ToDo feedback in window that download of this component failed
     594           0 :         throw cssu::Exception(OUSTR("Could not create temporary file in folder ") + destFolder + OUSTR("."), 0);
     595             :     }
     596           0 :     tempEntry = tempEntry.copy( tempEntry.lastIndexOf( '/' ) + 1 );
     597             : 
     598           0 :     destFolder = dp_misc::makeURL( m_sDownloadFolder, tempEntry );
     599           0 :     destFolder += OUSTR("_");
     600             : 
     601           0 :     ::ucbhelper::Content destFolderContent;
     602           0 :     dp_misc::create_folder( &destFolderContent, destFolder, m_updateCmdEnv.get() );
     603             : 
     604           0 :     ::ucbhelper::Content sourceContent;
     605           0 :     dp_misc::create_ucb_content( &sourceContent, sDownloadURL, m_updateCmdEnv.get() );
     606             : 
     607           0 :     const OUString sTitle( StrTitle::getTitle( sourceContent ) );
     608             : 
     609           0 :     if (destFolderContent.transferContent(
     610             :             sourceContent, ::ucbhelper::InsertOperation_COPY,
     611           0 :             sTitle, css::ucb::NameClash::OVERWRITE ))
     612             :     {
     613             :         //the user may have cancelled the dialog because downloading took to long
     614             :         {
     615           0 :             SolarMutexGuard g;
     616           0 :             if (m_stop) {
     617             :                 return;
     618             :             }
     619             :             //all errors should be handeld by the command environment.
     620           0 :             aUpdateData.sLocalURL = destFolder + OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) ) + sTitle;
     621             :         }
     622           0 :     }
     623             : }
     624             : 
     625             : 
     626             : // -------------------------------------------------------------------------------------------------------
     627             : 
     628           0 : UpdateCommandEnv::UpdateCommandEnv( cssu::Reference< cssu::XComponentContext > const & xCtx,
     629             :     ::rtl::Reference<UpdateInstallDialog::Thread>const & thread)
     630             :     : m_installThread(thread),
     631           0 :     m_xContext(xCtx)
     632             : {
     633           0 : }
     634             : 
     635           0 : UpdateCommandEnv::~UpdateCommandEnv()
     636             : {
     637           0 : }
     638             : 
     639             : 
     640             : // XCommandEnvironment
     641             : //______________________________________________________________________________
     642           0 : cssu::Reference<css::task::XInteractionHandler> UpdateCommandEnv::getInteractionHandler()
     643             : throw (cssu::RuntimeException)
     644             : {
     645           0 :     return this;
     646             : }
     647             : 
     648             : //______________________________________________________________________________
     649           0 : cssu::Reference<css::ucb::XProgressHandler> UpdateCommandEnv::getProgressHandler()
     650             : throw (cssu::RuntimeException)
     651             : {
     652           0 :     return this;
     653             : }
     654             : 
     655             : // XInteractionHandler
     656           0 : void UpdateCommandEnv::handle(
     657             :     cssu::Reference< css::task::XInteractionRequest> const & xRequest )
     658             :     throw (cssu::RuntimeException)
     659             : {
     660           0 :     cssu::Any request( xRequest->getRequest() );
     661             :     OSL_ASSERT( request.getValueTypeClass() == cssu::TypeClass_EXCEPTION );
     662             :     dp_misc::TRACE(OUSTR("[dp_gui_cmdenv.cxx] incoming request:\n")
     663           0 :         + ::comphelper::anyToString(request) + OUSTR("\n\n"));
     664             : 
     665           0 :     css::deployment::VersionException verExc;
     666           0 :     bool approve = false;
     667           0 :     bool abort = false;
     668             : 
     669           0 :     if (request >>= verExc)
     670             :     {   //We must catch the version exception during the update,
     671             :         //because otherwise the user would be confronted with the dialogs, asking
     672             :         //them if they want to replace an already installed version of the same extension.
     673             :         //During an update we assume that we always want to replace the old version with the
     674             :         //new version.
     675           0 :         approve = true;
     676             :     }
     677             : 
     678           0 :     if (approve == false && abort == false)
     679             :     {
     680             :         //forward to interaction handler for main dialog.
     681           0 :         handleInteractionRequest( m_xContext, xRequest );
     682             :     }
     683             :     else
     684             :     {
     685             :         // select:
     686             :         cssu::Sequence< cssu::Reference< css::task::XInteractionContinuation > > conts(
     687           0 :             xRequest->getContinuations() );
     688             :         cssu::Reference< css::task::XInteractionContinuation > const * pConts =
     689           0 :             conts.getConstArray();
     690           0 :         sal_Int32 len = conts.getLength();
     691           0 :         for ( sal_Int32 pos = 0; pos < len; ++pos )
     692             :         {
     693           0 :             if (approve) {
     694             :                 cssu::Reference< css::task::XInteractionApprove > xInteractionApprove(
     695           0 :                     pConts[ pos ], cssu::UNO_QUERY );
     696           0 :                 if (xInteractionApprove.is()) {
     697           0 :                     xInteractionApprove->select();
     698             :                     // don't query again for ongoing continuations:
     699           0 :                     approve = false;
     700           0 :                 }
     701             :             }
     702           0 :             else if (abort) {
     703             :                 cssu::Reference< css::task::XInteractionAbort > xInteractionAbort(
     704           0 :                     pConts[ pos ], cssu::UNO_QUERY );
     705           0 :                 if (xInteractionAbort.is()) {
     706           0 :                     xInteractionAbort->select();
     707             :                     // don't query again for ongoing continuations:
     708           0 :                     abort = false;
     709           0 :                 }
     710             :             }
     711           0 :         }
     712           0 :     }
     713           0 : }
     714             : 
     715             : // XProgressHandler
     716           0 : void UpdateCommandEnv::push( cssu::Any const & /*Status*/ )
     717             : throw (cssu::RuntimeException)
     718             : {
     719           0 : }
     720             : 
     721             : 
     722           0 : void UpdateCommandEnv::update( cssu::Any const & /*Status */)
     723             : throw (cssu::RuntimeException)
     724             : {
     725           0 : }
     726             : 
     727           0 : void UpdateCommandEnv::pop() throw (cssu::RuntimeException)
     728             : {
     729           0 : }
     730             : 
     731             : 
     732             : } //end namespace dp_gui
     733             : 
     734             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10