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

Generated by: LCOV version 1.10