LCOV - code coverage report
Current view: top level - libreoffice/desktop/source/deployment/gui - dp_gui_updatedialog.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 643 0.0 %
Date: 2012-12-17 Functions: 0 62 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 "sal/config.h"
      22             : 
      23             : #include <cstddef>
      24             : #include <limits>
      25             : #include <map>
      26             : #include <memory>
      27             : #include <utility>
      28             : #include <vector>
      29             : 
      30             : 
      31             : #include "boost/optional.hpp"
      32             : #include "com/sun/star/awt/Rectangle.hpp"
      33             : #include "com/sun/star/awt/WindowAttribute.hpp"
      34             : #include "com/sun/star/awt/WindowClass.hpp"
      35             : #include "com/sun/star/awt/WindowDescriptor.hpp"
      36             : #include "com/sun/star/awt/Toolkit.hpp"
      37             : #include "com/sun/star/awt/XWindow.hpp"
      38             : #include "com/sun/star/awt/XWindowPeer.hpp"
      39             : #include "com/sun/star/beans/NamedValue.hpp"
      40             : #include "com/sun/star/beans/Optional.hpp"
      41             : #include "com/sun/star/beans/PropertyValue.hpp"
      42             : #include "com/sun/star/beans/XPropertySet.hpp"
      43             : #include "com/sun/star/configuration/theDefaultProvider.hpp"
      44             : #include "com/sun/star/container/XNameAccess.hpp"
      45             : #include "com/sun/star/container/XNameContainer.hpp"
      46             : #include "com/sun/star/deployment/DeploymentException.hpp"
      47             : #include "com/sun/star/deployment/UpdateInformationProvider.hpp"
      48             : #include "com/sun/star/deployment/XPackage.hpp"
      49             : #include "com/sun/star/deployment/XExtensionManager.hpp"
      50             : #include "com/sun/star/deployment/ExtensionManager.hpp"
      51             : #include "com/sun/star/deployment/XUpdateInformationProvider.hpp"
      52             : #include "com/sun/star/frame/XDesktop.hpp"
      53             : #include "com/sun/star/frame/XDispatch.hpp"
      54             : #include "com/sun/star/frame/XDispatchProvider.hpp"
      55             : #include "com/sun/star/lang/IllegalArgumentException.hpp"
      56             : #include "com/sun/star/lang/XMultiComponentFactory.hpp"
      57             : #include "com/sun/star/lang/XSingleServiceFactory.hpp"
      58             : #include "com/sun/star/system/SystemShellExecuteFlags.hpp"
      59             : #include "com/sun/star/system/SystemShellExecute.hpp"
      60             : #include "com/sun/star/task/InteractionHandler.hpp"
      61             : #include "com/sun/star/task/XAbortChannel.hpp"
      62             : #include "com/sun/star/task/XJob.hpp"
      63             : #include "com/sun/star/ucb/CommandAbortedException.hpp"
      64             : #include "com/sun/star/ucb/CommandFailedException.hpp"
      65             : #include "com/sun/star/ucb/XCommandEnvironment.hpp"
      66             : #include "com/sun/star/uno/Any.hxx"
      67             : #include "com/sun/star/uno/Exception.hpp"
      68             : #include "com/sun/star/uno/Reference.hxx"
      69             : #include "com/sun/star/uno/RuntimeException.hpp"
      70             : #include "com/sun/star/uno/Sequence.hxx"
      71             : #include "com/sun/star/uno/XInterface.hpp"
      72             : #include "com/sun/star/util/URL.hpp"
      73             : #include "com/sun/star/util/XChangesBatch.hpp"
      74             : #include "com/sun/star/util/URLTransformer.hpp"
      75             : #include "com/sun/star/util/XURLTransformer.hpp"
      76             : #include "com/sun/star/xml/dom/XElement.hpp"
      77             : #include "com/sun/star/xml/dom/XNode.hpp"
      78             : #include "osl/diagnose.h"
      79             : #include "rtl/ref.hxx"
      80             : #include "rtl/string.h"
      81             : #include "rtl/ustrbuf.hxx"
      82             : #include "rtl/ustring.h"
      83             : #include "rtl/ustring.hxx"
      84             : #include "sal/types.h"
      85             : #include "salhelper/thread.hxx"
      86             : #include "svtools/svlbitm.hxx"
      87             : #include "svtools/treelistbox.hxx"
      88             : #include <svtools/controldims.hrc>
      89             : #include "svx/checklbx.hxx"
      90             : #include "tools/gen.hxx"
      91             : #include "tools/link.hxx"
      92             : #include "tools/resid.hxx"
      93             : #include "tools/solar.h"
      94             : #include "unotools/configmgr.hxx"
      95             : #include "vcl/button.hxx"
      96             : #include "vcl/dialog.hxx"
      97             : #include "vcl/fixed.hxx"
      98             : #include "vcl/image.hxx"
      99             : #include "vcl/msgbox.hxx"
     100             : #include "vcl/svapp.hxx"
     101             : #include "osl/mutex.hxx"
     102             : 
     103             : #include "comphelper/processfactory.hxx"
     104             : 
     105             : #include "dp_dependencies.hxx"
     106             : #include "dp_descriptioninfoset.hxx"
     107             : #include "dp_identifier.hxx"
     108             : #include "dp_version.hxx"
     109             : #include "dp_misc.h"
     110             : #include "dp_update.hxx"
     111             : 
     112             : #include "dp_gui.h"
     113             : #include "dp_gui.hrc"
     114             : #include "dp_gui_updatedata.hxx"
     115             : #include "dp_gui_updatedialog.hxx"
     116             : #include "dp_gui_shared.hxx"
     117             : 
     118             : class KeyEvent;
     119             : class MouseEvent;
     120             : class Window;
     121             : namespace com { namespace sun { namespace star { namespace uno {
     122             :     class XComponentContext;
     123             : } } } }
     124             : 
     125             : using namespace ::com::sun::star;
     126             : using dp_gui::UpdateDialog;
     127             : 
     128             : namespace {
     129             : 
     130             : static sal_Unicode const LF = 0x000A;
     131             : static sal_Unicode const CR = 0x000D;
     132             : static const sal_uInt16 CMD_ENABLE_UPDATE = 1;
     133             : static const sal_uInt16 CMD_IGNORE_UPDATE = 2;
     134             : static const sal_uInt16 CMD_IGNORE_ALL_UPDATES = 3;
     135             : 
     136             : #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
     137             : 
     138             : #define IGNORED_UPDATES     OUSTR("/org.openoffice.Office.ExtensionManager/ExtensionUpdateData/IgnoredUpdates")
     139             : #define PROPERTY_VERSION    OUSTR("Version")
     140             : 
     141             : enum Kind { ENABLED_UPDATE, DISABLED_UPDATE, SPECIFIC_ERROR };
     142             : 
     143           0 : rtl::OUString confineToParagraph(rtl::OUString const & text) {
     144             :     // Confine arbitrary text to a single paragraph in a dp_gui::AutoScrollEdit.
     145             :     // This assumes that U+000A and U+000D are the only paragraph separators in
     146             :     // a dp_gui::AutoScrollEdit, and that replacing them with a single space
     147             :     // each is acceptable:
     148           0 :     return text.replace(LF, ' ').replace(CR, ' ');
     149             : }
     150             : }
     151             : 
     152           0 : struct UpdateDialog::DisabledUpdate {
     153             :     rtl::OUString name;
     154             :     uno::Sequence< rtl::OUString > unsatisfiedDependencies;
     155             :     // We also want to show release notes and publisher for disabled updates
     156             :     ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode > aUpdateInfo;
     157             :     sal_uInt16 m_nID;
     158             : };
     159             : 
     160           0 : struct UpdateDialog::SpecificError {
     161             :     rtl::OUString name;
     162             :     rtl::OUString message;
     163             :     sal_uInt16 m_nID;
     164             : };
     165             : 
     166             : //------------------------------------------------------------------------------
     167           0 : struct UpdateDialog::IgnoredUpdate {
     168             :     rtl::OUString sExtensionID;
     169             :     rtl::OUString sVersion;
     170             :     bool          bRemoved;
     171             : 
     172             :     IgnoredUpdate( const rtl::OUString &rExtensionID, const rtl::OUString &rVersion );
     173             : };
     174             : 
     175             : //------------------------------------------------------------------------------
     176           0 : UpdateDialog::IgnoredUpdate::IgnoredUpdate( const rtl::OUString &rExtensionID, const rtl::OUString &rVersion ):
     177             :     sExtensionID( rExtensionID ),
     178             :     sVersion( rVersion ),
     179           0 :     bRemoved( false )
     180           0 : {}
     181             : 
     182             : //------------------------------------------------------------------------------
     183           0 : struct UpdateDialog::Index
     184             : {
     185             :     Kind          m_eKind;
     186             :     bool          m_bIgnored;
     187             :     sal_uInt16        m_nID;
     188             :     sal_uInt16        m_nIndex;
     189             :     rtl::OUString m_aName;
     190             : 
     191             :     Index( Kind theKind, sal_uInt16 nID, sal_uInt16 nIndex, const rtl::OUString &rName );
     192             : };
     193             : 
     194             : //------------------------------------------------------------------------------
     195           0 : UpdateDialog::Index::Index( Kind theKind, sal_uInt16 nID, sal_uInt16 nIndex, const rtl::OUString &rName ):
     196             :     m_eKind( theKind ),
     197             :     m_bIgnored( false ),
     198             :     m_nID( nID ),
     199             :     m_nIndex( nIndex ),
     200           0 :     m_aName( rName )
     201           0 : {}
     202             : 
     203             : //------------------------------------------------------------------------------
     204             : //------------------------------------------------------------------------------
     205             : //------------------------------------------------------------------------------
     206             : class UpdateDialog::Thread: public salhelper::Thread {
     207             : public:
     208             :     Thread(
     209             :         uno::Reference< uno::XComponentContext > const & context,
     210             :         UpdateDialog & dialog,
     211             :         const std::vector< uno::Reference< deployment::XPackage >  > & vExtensionList);
     212             : 
     213             :     void stop();
     214             : 
     215             : private:
     216             :     virtual ~Thread();
     217             : 
     218             :     virtual void execute();
     219             : 
     220             :     void handleSpecificError(
     221             :         uno::Reference< deployment::XPackage > const & package,
     222             :         uno::Any const & exception) const;
     223             : 
     224             :     uno::Sequence< uno::Reference< xml::dom::XElement > >
     225             :     getUpdateInformation(
     226             :         uno::Reference< deployment::XPackage > const & package,
     227             :         uno::Sequence< rtl::OUString > const & urls,
     228             :         rtl::OUString const & identifier) const;
     229             : 
     230             :     ::rtl::OUString getUpdateDisplayString(
     231             :         dp_gui::UpdateData const & data, ::rtl::OUString const & version = ::rtl::OUString()) const;
     232             : 
     233             :     void prepareUpdateData(
     234             :         ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode > const & updateInfo,
     235             :         UpdateDialog::DisabledUpdate & out_du,
     236             :         dp_gui::UpdateData & out_data) const;
     237             : 
     238             :     bool update(
     239             :         UpdateDialog::DisabledUpdate & du,
     240             :         dp_gui::UpdateData & data) const;
     241             : 
     242             :     uno::Reference< uno::XComponentContext > m_context;
     243             :     UpdateDialog & m_dialog;
     244             :     std::vector< uno::Reference< deployment::XPackage > > m_vExtensionList;
     245             :     uno::Reference< deployment::XUpdateInformationProvider > m_updateInformation;
     246             :     uno::Reference< task::XInteractionHandler > m_xInteractionHdl;
     247             : 
     248             :     // guarded by Application::GetSolarMutex():
     249             :     uno::Reference< task::XAbortChannel > m_abort;
     250             :     bool m_stop;
     251             : };
     252             : 
     253           0 : UpdateDialog::Thread::Thread(
     254             :     uno::Reference< uno::XComponentContext > const & context,
     255             :     UpdateDialog & dialog,
     256             :     const std::vector< uno::Reference< deployment::XPackage > > &vExtensionList):
     257             :     salhelper::Thread("dp_gui_updatedialog"),
     258             :     m_context(context),
     259             :     m_dialog(dialog),
     260             :     m_vExtensionList(vExtensionList),
     261             :     m_updateInformation(
     262             :         deployment::UpdateInformationProvider::create(context)),
     263           0 :     m_stop(false)
     264             : {
     265           0 :     if( m_context.is() )
     266             :     {
     267             :         m_xInteractionHdl.set(
     268             :             task::InteractionHandler::createWithParent(m_context, 0),
     269           0 :             uno::UNO_QUERY );
     270           0 :         m_updateInformation->setInteractionHandler( m_xInteractionHdl );
     271             :     }
     272           0 : }
     273             : 
     274           0 : void UpdateDialog::Thread::stop() {
     275           0 :     uno::Reference< task::XAbortChannel > abort;
     276             :     {
     277           0 :         SolarMutexGuard g;
     278           0 :         abort = m_abort;
     279           0 :         m_stop = true;
     280             :     }
     281           0 :     if (abort.is()) {
     282           0 :         abort->sendAbort();
     283             :     }
     284           0 :     m_updateInformation->cancel();
     285           0 : }
     286             : 
     287           0 : UpdateDialog::Thread::~Thread()
     288             : {
     289           0 :     if ( m_xInteractionHdl.is() )
     290           0 :         m_updateInformation->setInteractionHandler( uno::Reference< task::XInteractionHandler > () );
     291           0 : }
     292             : 
     293           0 : void UpdateDialog::Thread::execute()
     294             : {
     295             :     {
     296           0 :         SolarMutexGuard g;
     297           0 :         if ( m_stop ) {
     298             :             return;
     299           0 :         }
     300             :     }
     301             :     uno::Reference<deployment::XExtensionManager> extMgr =
     302           0 :         deployment::ExtensionManager::get(m_context);
     303             : 
     304           0 :     std::vector<std::pair<uno::Reference<deployment::XPackage>, uno::Any > > errors;
     305             : 
     306             :     dp_misc::UpdateInfoMap updateInfoMap = dp_misc::getOnlineUpdateInfos(
     307           0 :         m_context, extMgr, m_updateInformation, &m_vExtensionList, errors);
     308             : 
     309             :     typedef std::vector<std::pair<uno::Reference<deployment::XPackage>,
     310             :         uno::Any> >::const_iterator ITERROR;
     311           0 :     for (ITERROR ite = errors.begin(); ite != errors.end(); ++ite )
     312           0 :         handleSpecificError(ite->first, ite->second);
     313             : 
     314           0 :     for (dp_misc::UpdateInfoMap::iterator i(updateInfoMap.begin()); i != updateInfoMap.end(); ++i)
     315             :     {
     316           0 :         dp_misc::UpdateInfo const & info = i->second;
     317           0 :         UpdateData updateData(info.extension);
     318           0 :         DisabledUpdate disableUpdate;
     319             :         //determine if online updates meet the requirements
     320           0 :         prepareUpdateData(info.info, disableUpdate, updateData);
     321             : 
     322             :         //determine if the update is installed in the user or shared repository
     323           0 :         rtl::OUString sOnlineVersion;
     324           0 :         if (info.info.is())
     325           0 :             sOnlineVersion = info.version;
     326           0 :         rtl::OUString sVersionUser;
     327           0 :         rtl::OUString sVersionShared;
     328           0 :         rtl::OUString sVersionBundled;
     329           0 :         uno::Sequence< uno::Reference< deployment::XPackage> > extensions;
     330             :         try {
     331           0 :             extensions = extMgr->getExtensionsWithSameIdentifier(
     332           0 :                 dp_misc::getIdentifier(info.extension), info.extension->getName(),
     333           0 :                 uno::Reference<ucb::XCommandEnvironment>());
     334           0 :         } catch ( const lang::IllegalArgumentException& ) {
     335             :             OSL_ASSERT(0);
     336           0 :             continue;
     337           0 :         } catch ( const css::ucb::CommandFailedException& ) {
     338             :             OSL_ASSERT(0);
     339           0 :             continue;
     340             :         }
     341             :         OSL_ASSERT(extensions.getLength() == 3);
     342           0 :         if (extensions[0].is() )
     343           0 :             sVersionUser = extensions[0]->getVersion();
     344           0 :         if (extensions[1].is() )
     345           0 :             sVersionShared = extensions[1]->getVersion();
     346           0 :         if (extensions[2].is() )
     347           0 :             sVersionBundled = extensions[2]->getVersion();
     348             : 
     349           0 :         bool bSharedReadOnly = extMgr->isReadOnlyRepository(OUSTR("shared"));
     350             : 
     351             :         dp_misc::UPDATE_SOURCE sourceUser = dp_misc::isUpdateUserExtension(
     352           0 :             bSharedReadOnly, sVersionUser, sVersionShared, sVersionBundled, sOnlineVersion);
     353             :         dp_misc::UPDATE_SOURCE sourceShared = dp_misc::isUpdateSharedExtension(
     354           0 :             bSharedReadOnly, sVersionShared, sVersionBundled, sOnlineVersion);
     355             : 
     356           0 :         uno::Reference<deployment::XPackage> updateSource;
     357           0 :         if (sourceUser != dp_misc::UPDATE_SOURCE_NONE)
     358             :         {
     359           0 :             if (sourceUser == dp_misc::UPDATE_SOURCE_SHARED)
     360             :             {
     361           0 :                 updateData.aUpdateSource = extensions[1];
     362           0 :                 updateData.updateVersion = extensions[1]->getVersion();
     363             :             }
     364           0 :             else if (sourceUser == dp_misc::UPDATE_SOURCE_BUNDLED)
     365             :             {
     366           0 :                 updateData.aUpdateSource = extensions[2];
     367           0 :                 updateData.updateVersion = extensions[2]->getVersion();
     368             :             }
     369           0 :             if (!update(disableUpdate, updateData))
     370             :                 return;
     371             :         }
     372             : 
     373           0 :         if (sourceShared != dp_misc::UPDATE_SOURCE_NONE)
     374             :         {
     375           0 :             if (sourceShared == dp_misc::UPDATE_SOURCE_BUNDLED)
     376             :             {
     377           0 :                 updateData.aUpdateSource = extensions[2];
     378           0 :                 updateData.updateVersion = extensions[2]->getVersion();
     379             :             }
     380           0 :             updateData.bIsShared = true;
     381           0 :             if (!update(disableUpdate, updateData))
     382             :                 return;
     383             :         }
     384           0 :     }
     385             : 
     386             : 
     387           0 :     SolarMutexGuard g;
     388           0 :     if (!m_stop) {
     389           0 :         m_dialog.checkingDone();
     390           0 :     }
     391             : }
     392             : 
     393             : //Parameter package can be null
     394           0 : void UpdateDialog::Thread::handleSpecificError(
     395             :     uno::Reference< deployment::XPackage > const & package,
     396             :     uno::Any const & exception) const
     397             : {
     398           0 :     UpdateDialog::SpecificError data;
     399           0 :     if (package.is())
     400           0 :         data.name = package->getDisplayName();
     401           0 :     uno::Exception e;
     402           0 :     if (exception >>= e) {
     403           0 :         data.message = e.Message;
     404             :     }
     405           0 :     SolarMutexGuard g;
     406           0 :     if (!m_stop) {
     407           0 :         m_dialog.addSpecificError(data);
     408           0 :     }
     409           0 : }
     410             : 
     411           0 : ::rtl::OUString UpdateDialog::Thread::getUpdateDisplayString(
     412             :     dp_gui::UpdateData const & data, ::rtl::OUString const & version) const
     413             : {
     414             :     OSL_ASSERT(data.aInstalledPackage.is());
     415           0 :     rtl::OUStringBuffer b(data.aInstalledPackage->getDisplayName());
     416           0 :     b.append(static_cast< sal_Unicode >(' '));
     417             :     {
     418           0 :         SolarMutexGuard g;
     419           0 :         if(!m_stop)
     420           0 :             b.append(m_dialog.m_version);
     421             :     }
     422           0 :     b.append(static_cast< sal_Unicode >(' '));
     423           0 :     if (!version.isEmpty())
     424           0 :         b.append(version);
     425             :     else
     426           0 :         b.append(data.updateVersion);
     427             : 
     428           0 :     if (!data.sWebsiteURL.isEmpty())
     429             :     {
     430           0 :         b.append(static_cast< sal_Unicode >(' '));
     431             :         {
     432           0 :             SolarMutexGuard g;
     433           0 :             if(!m_stop)
     434           0 :                 b.append(m_dialog.m_browserbased);
     435             :         }
     436             :     }
     437           0 :     return  b.makeStringAndClear();
     438             : }
     439             : 
     440             : /** out_data will only be filled if all dependencies are ok.
     441             :  */
     442           0 : void UpdateDialog::Thread::prepareUpdateData(
     443             :     uno::Reference< xml::dom::XNode > const & updateInfo,
     444             :     UpdateDialog::DisabledUpdate & out_du,
     445             :     dp_gui::UpdateData & out_data) const
     446             : {
     447           0 :     if (!updateInfo.is())
     448           0 :         return;
     449           0 :     dp_misc::DescriptionInfoset infoset(m_context, updateInfo);
     450             :     OSL_ASSERT(!infoset.getVersion().isEmpty());
     451             :     uno::Sequence< uno::Reference< xml::dom::XElement > > ds(
     452           0 :         dp_misc::Dependencies::check(infoset));
     453             : 
     454           0 :     out_du.aUpdateInfo = updateInfo;
     455           0 :     out_du.unsatisfiedDependencies.realloc(ds.getLength());
     456           0 :     for (sal_Int32 i = 0; i < ds.getLength(); ++i) {
     457           0 :         out_du.unsatisfiedDependencies[i] = dp_misc::Dependencies::getErrorText(ds[i]);
     458             :     }
     459             : 
     460           0 :     const ::boost::optional< ::rtl::OUString> updateWebsiteURL(infoset.getLocalizedUpdateWebsiteURL());
     461             : 
     462           0 :     out_du.name = getUpdateDisplayString(out_data, infoset.getVersion());
     463             : 
     464           0 :     if (out_du.unsatisfiedDependencies.getLength() == 0)
     465             :     {
     466           0 :         out_data.aUpdateInfo = updateInfo;
     467           0 :         out_data.updateVersion = infoset.getVersion();
     468           0 :         if (updateWebsiteURL)
     469           0 :             out_data.sWebsiteURL = *updateWebsiteURL;
     470           0 :     }
     471             : }
     472             : 
     473           0 : bool UpdateDialog::Thread::update(
     474             :     UpdateDialog::DisabledUpdate & du,
     475             :     dp_gui::UpdateData & data) const
     476             : {
     477           0 :     bool ret = false;
     478           0 :     if (du.unsatisfiedDependencies.getLength() == 0)
     479             :     {
     480           0 :         SolarMutexGuard g;
     481           0 :         if (!m_stop) {
     482           0 :             m_dialog.addEnabledUpdate(getUpdateDisplayString(data), data);
     483             :         }
     484           0 :         ret = !m_stop;
     485             :     } else {
     486           0 :         SolarMutexGuard g;
     487           0 :         if (!m_stop) {
     488           0 :                 m_dialog.addDisabledUpdate(du);
     489             :         }
     490           0 :         ret = !m_stop;
     491             :     }
     492           0 :     return ret;
     493             : }
     494             : 
     495             : // UpdateDialog ----------------------------------------------------------
     496           0 : UpdateDialog::UpdateDialog(
     497             :     uno::Reference< uno::XComponentContext > const & context,
     498             :     Window * parent,
     499             :     const std::vector<uno::Reference< deployment::XPackage > > &vExtensionList,
     500             :     std::vector< dp_gui::UpdateData > * updateData):
     501             :     ModalDialog(parent,DpGuiResId(RID_DLG_UPDATE)),
     502             :     m_context(context),
     503             :     m_checking(this, DpGuiResId(RID_DLG_UPDATE_CHECKING)),
     504             :     m_throbber(this, DpGuiResId(RID_DLG_UPDATE_THROBBER)),
     505             :     m_update(this, DpGuiResId(RID_DLG_UPDATE_UPDATE)),
     506             :     m_updates(
     507             :         *this, DpGuiResId(RID_DLG_UPDATE_UPDATES),
     508             :         Image(DpGuiResId(RID_DLG_UPDATE_NORMALALERT))),
     509             :     m_all(this, DpGuiResId(RID_DLG_UPDATE_ALL)),
     510             :     m_description(this, DpGuiResId(RID_DLG_UPDATE_DESCRIPTION)),
     511             :     m_PublisherLabel(this, DpGuiResId(RID_DLG_UPDATE_PUBLISHER_LABEL)),
     512             :     m_PublisherLink(this, DpGuiResId(RID_DLG_UPDATE_PUBLISHER_LINK)),
     513             :     m_ReleaseNotesLabel(this, DpGuiResId(RID_DLG_UPDATE_RELEASENOTES_LABEL)),
     514             :     m_ReleaseNotesLink(this, DpGuiResId(RID_DLG_UPDATE_RELEASENOTES_LINK)),
     515             :     m_descriptions(this, DpGuiResId(RID_DLG_UPDATE_DESCRIPTIONS)),
     516             :     m_line(this, DpGuiResId(RID_DLG_UPDATE_LINE)),
     517             :     m_help(this, DpGuiResId(RID_DLG_UPDATE_HELP)),
     518             :     m_ok(this, DpGuiResId(RID_DLG_UPDATE_OK)),
     519             :     m_close(this, DpGuiResId(RID_DLG_UPDATE_CLOSE)),
     520             :     m_error(DPGUI_RESSTR(RID_DLG_UPDATE_ERROR)),
     521             :     m_none(DPGUI_RESSTR(RID_DLG_UPDATE_NONE)),
     522             :     m_noInstallable(DPGUI_RESSTR(RID_DLG_UPDATE_NOINSTALLABLE)),
     523             :     m_failure(DPGUI_RESSTR(RID_DLG_UPDATE_FAILURE)),
     524             :     m_unknownError(DPGUI_RESSTR(RID_DLG_UPDATE_UNKNOWNERROR)),
     525             :     m_noDescription(DPGUI_RESSTR(RID_DLG_UPDATE_NODESCRIPTION)),
     526             :     m_noInstall(DPGUI_RESSTR(RID_DLG_UPDATE_NOINSTALL)),
     527             :     m_noDependency(DPGUI_RESSTR(RID_DLG_UPDATE_NODEPENDENCY)),
     528             :     m_noDependencyCurVer(DPGUI_RESSTR(RID_DLG_UPDATE_NODEPENDENCY_CUR_VER)),
     529             :     m_browserbased(DPGUI_RESSTR(RID_DLG_UPDATE_BROWSERBASED)),
     530             :     m_version(DPGUI_RESSTR(RID_DLG_UPDATE_VERSION)),
     531             :     m_ignoredUpdate(DPGUI_RESSTR(RID_DLG_UPDATE_IGNORED_UPDATE)),
     532             :     m_updateData(*updateData),
     533             :     m_thread(
     534             :         new UpdateDialog::Thread(
     535           0 :             context, *this, vExtensionList)),
     536             :     m_nFirstLineDelta(0),
     537             :     m_nOneLineMissing(0),
     538             :     m_nLastID(1),
     539           0 :     m_bModified( false )
     540             :     // TODO: check!
     541             : //    ,
     542             : //    m_extensionManagerDialog(extensionManagerDialog)
     543             : {
     544             :     OSL_ASSERT(updateData != NULL);
     545             : 
     546           0 :     m_xExtensionManager = deployment::ExtensionManager::get( context );
     547             : 
     548           0 :     uno::Reference< awt::XToolkit2 > toolkit;
     549             :     try {
     550           0 :         toolkit = awt::Toolkit::create(m_context);
     551           0 :     } catch (const uno::RuntimeException &) {
     552           0 :         throw;
     553           0 :     } catch (const uno::Exception & e) {
     554           0 :         throw uno::RuntimeException(e.Message, e.Context);
     555             :     }
     556           0 :     m_updates.SetSelectHdl(LINK(this, UpdateDialog, selectionHandler));
     557           0 :     m_all.SetToggleHdl(LINK(this, UpdateDialog, allHandler));
     558           0 :     m_ok.SetClickHdl(LINK(this, UpdateDialog, okHandler));
     559           0 :     m_close.SetClickHdl(LINK(this, UpdateDialog, closeHandler));
     560           0 :     if ( ! dp_misc::office_is_running())
     561           0 :         m_help.Disable();
     562           0 :     FreeResource();
     563             : 
     564           0 :     initDescription();
     565           0 :     getIgnoredUpdates();
     566           0 : }
     567             : 
     568             : //------------------------------------------------------------------------------
     569           0 : UpdateDialog::~UpdateDialog()
     570             : {
     571           0 :     storeIgnoredUpdates();
     572             : 
     573           0 :     for ( std::vector< UpdateDialog::Index* >::iterator i( m_ListboxEntries.begin() ); i != m_ListboxEntries.end(); ++i )
     574             :     {
     575           0 :         delete (*i);
     576             :     }
     577           0 :     for ( std::vector< UpdateDialog::IgnoredUpdate* >::iterator i( m_ignoredUpdates.begin() ); i != m_ignoredUpdates.end(); ++i )
     578             :     {
     579           0 :         delete (*i);
     580             :     }
     581           0 : }
     582             : 
     583             : //------------------------------------------------------------------------------
     584           0 : sal_Bool UpdateDialog::Close() {
     585           0 :     m_thread->stop();
     586           0 :     return ModalDialog::Close();
     587             : }
     588             : 
     589           0 : short UpdateDialog::Execute() {
     590           0 :     m_throbber.start();
     591           0 :     m_thread->launch();
     592           0 :     return ModalDialog::Execute();
     593             : }
     594             : 
     595             : //------------------------------------------------------------------------------
     596             : //------------------------------------------------------------------------------
     597             : //------------------------------------------------------------------------------
     598           0 : UpdateDialog::CheckListBox::CheckListBox( UpdateDialog & dialog, ResId const & resource,
     599             :                                           Image const & normalStaticImage ):
     600             :     SvxCheckListBox( &dialog, resource, normalStaticImage ),
     601             :     m_ignoreUpdate( DPGUI_RESSTR( RID_DLG_UPDATE_IGNORE ) ),
     602             :     m_ignoreAllUpdates( DPGUI_RESSTR( RID_DLG_UPDATE_IGNORE_ALL ) ),
     603             :     m_enableUpdate( DPGUI_RESSTR( RID_DLG_UPDATE_ENABLE ) ),
     604           0 :     m_dialog(dialog)
     605           0 : {}
     606             : 
     607             : //------------------------------------------------------------------------------
     608           0 : UpdateDialog::CheckListBox::~CheckListBox() {}
     609             : 
     610             : //------------------------------------------------------------------------------
     611           0 : sal_uInt16 UpdateDialog::CheckListBox::getItemCount() const {
     612           0 :     sal_uLong i = GetEntryCount();
     613             :     OSL_ASSERT(i <= std::numeric_limits< sal_uInt16 >::max());
     614           0 :     return sal::static_int_cast< sal_uInt16 >(i);
     615             : }
     616             : 
     617             : //------------------------------------------------------------------------------
     618           0 : void UpdateDialog::CheckListBox::MouseButtonDown( MouseEvent const & event )
     619             : {
     620             :     // When clicking on a selected entry in an SvxCheckListBox, the entry's
     621             :     // checkbox is toggled on mouse button down:
     622           0 :     SvxCheckListBox::MouseButtonDown( event );
     623             : 
     624           0 :     if ( event.IsRight() )
     625             :     {
     626           0 :         handlePopupMenu( event.GetPosPixel() );
     627             :     }
     628             : 
     629           0 :     m_dialog.enableOk();
     630           0 : }
     631             : 
     632             : //------------------------------------------------------------------------------
     633           0 : void UpdateDialog::CheckListBox::MouseButtonUp(MouseEvent const & event) {
     634             :     // When clicking on an entry's checkbox in an SvxCheckListBox, the entry's
     635             :     // checkbox is toggled on mouse button up:
     636           0 :     SvxCheckListBox::MouseButtonUp(event);
     637           0 :     m_dialog.enableOk();
     638           0 : }
     639             : 
     640           0 : void UpdateDialog::CheckListBox::KeyInput(KeyEvent const & event) {
     641           0 :     SvxCheckListBox::KeyInput(event);
     642           0 :     m_dialog.enableOk();
     643           0 : }
     644             : 
     645             : //------------------------------------------------------------------------------
     646           0 : void UpdateDialog::CheckListBox::handlePopupMenu( const Point &rPos )
     647             : {
     648           0 :     SvTreeListEntry *pData = GetEntry( rPos );
     649             : 
     650           0 :     if ( pData )
     651             :     {
     652           0 :         sal_uInt16 nEntryPos = GetSelectEntryPos();
     653           0 :         UpdateDialog::Index * p = static_cast< UpdateDialog::Index * >( GetEntryData( nEntryPos ) );
     654             : 
     655           0 :         if ( ( p->m_eKind == ENABLED_UPDATE ) || ( p->m_eKind == DISABLED_UPDATE ) )
     656             :         {
     657           0 :             PopupMenu aPopup;
     658             : 
     659           0 :             if ( p->m_bIgnored )
     660           0 :                 aPopup.InsertItem( CMD_ENABLE_UPDATE, m_enableUpdate );
     661             :             else
     662             :             {
     663           0 :                 aPopup.InsertItem( CMD_IGNORE_UPDATE, m_ignoreUpdate );
     664           0 :                 aPopup.InsertItem( CMD_IGNORE_ALL_UPDATES, m_ignoreAllUpdates );
     665             :             }
     666             : 
     667           0 :             sal_uInt16 aCmd = aPopup.Execute( this, rPos );
     668           0 :             if ( ( aCmd == CMD_IGNORE_UPDATE ) || ( aCmd == CMD_IGNORE_ALL_UPDATES ) )
     669             :             {
     670           0 :                 p->m_bIgnored = true;
     671           0 :                 if ( p->m_eKind == ENABLED_UPDATE )
     672             :                 {
     673           0 :                     RemoveEntry( nEntryPos );
     674           0 :                     m_dialog.addAdditional( p, SvLBoxButtonKind_disabledCheckbox );
     675             :                 }
     676           0 :                 if ( aCmd == CMD_IGNORE_UPDATE )
     677           0 :                     m_dialog.setIgnoredUpdate( p, true, false );
     678             :                 else
     679           0 :                     m_dialog.setIgnoredUpdate( p, true, true );
     680             :                 // TODO: reselect entry to display new description!
     681             :             }
     682           0 :             else if ( aCmd == CMD_ENABLE_UPDATE )
     683             :             {
     684           0 :                 p->m_bIgnored = false;
     685           0 :                 if ( p->m_eKind == ENABLED_UPDATE )
     686             :                 {
     687           0 :                     RemoveEntry( nEntryPos );
     688           0 :                     m_dialog.insertItem( p, SvLBoxButtonKind_enabledCheckbox );
     689             :                 }
     690           0 :                 m_dialog.setIgnoredUpdate( p, false, false );
     691           0 :             }
     692             :         }
     693             :     }
     694           0 : }
     695             : 
     696             : //------------------------------------------------------------------------------
     697             : //------------------------------------------------------------------------------
     698             : //------------------------------------------------------------------------------
     699           0 : sal_uInt16 UpdateDialog::insertItem( UpdateDialog::Index *pEntry, SvLBoxButtonKind kind )
     700             : {
     701           0 :     m_updates.InsertEntry( pEntry->m_aName, LISTBOX_APPEND, static_cast< void * >( pEntry ), kind );
     702             : 
     703           0 :     for ( sal_uInt16 i = m_updates.getItemCount(); i != 0 ; )
     704             :     {
     705           0 :         i -= 1;
     706           0 :         UpdateDialog::Index const * p = static_cast< UpdateDialog::Index const * >( m_updates.GetEntryData( i ) );
     707           0 :         if ( p == pEntry )
     708           0 :             return i;
     709             :     }
     710             :     OSL_ASSERT(0);
     711           0 :     return 0;
     712             : }
     713             : 
     714             : //------------------------------------------------------------------------------
     715           0 : void UpdateDialog::addAdditional( UpdateDialog::Index * index, SvLBoxButtonKind kind )
     716             : {
     717           0 :     m_all.Enable();
     718           0 :     if (m_all.IsChecked())
     719             :     {
     720           0 :         insertItem( index, kind );
     721           0 :         m_update.Enable();
     722           0 :         m_updates.Enable();
     723           0 :         m_description.Enable();
     724           0 :         m_descriptions.Enable();
     725             :     }
     726           0 : }
     727             : 
     728             : //------------------------------------------------------------------------------
     729           0 : void UpdateDialog::addEnabledUpdate( rtl::OUString const & name,
     730             :                                      dp_gui::UpdateData & data )
     731             : {
     732           0 :     sal_uInt16 nIndex = sal::static_int_cast< sal_uInt16 >( m_enabledUpdates.size() );
     733           0 :     UpdateDialog::Index *pEntry = new UpdateDialog::Index( ENABLED_UPDATE, m_nLastID, nIndex, name );
     734             : 
     735           0 :     data.m_nID = m_nLastID;
     736           0 :     m_nLastID += 1;
     737             : 
     738           0 :     m_enabledUpdates.push_back( data );
     739           0 :     m_ListboxEntries.push_back( pEntry );
     740             : 
     741           0 :     if ( ! isIgnoredUpdate( pEntry ) )
     742             :     {
     743           0 :         sal_uInt16 nPos = insertItem( pEntry, SvLBoxButtonKind_enabledCheckbox );
     744           0 :         m_updates.CheckEntryPos( nPos );
     745             :     }
     746             :     else
     747           0 :         addAdditional( pEntry, SvLBoxButtonKind_disabledCheckbox );
     748             : 
     749           0 :     m_update.Enable();
     750           0 :     m_updates.Enable();
     751           0 :     m_description.Enable();
     752           0 :     m_descriptions.Enable();
     753           0 : }
     754             : 
     755             : //------------------------------------------------------------------------------
     756           0 : void UpdateDialog::addDisabledUpdate( UpdateDialog::DisabledUpdate & data )
     757             : {
     758           0 :     sal_uInt16 nIndex = sal::static_int_cast< sal_uInt16 >( m_disabledUpdates.size() );
     759           0 :     UpdateDialog::Index *pEntry = new UpdateDialog::Index( DISABLED_UPDATE, m_nLastID, nIndex, data.name );
     760             : 
     761           0 :     data.m_nID = m_nLastID;
     762           0 :     m_nLastID += 1;
     763             : 
     764           0 :     m_disabledUpdates.push_back( data );
     765           0 :     m_ListboxEntries.push_back( pEntry );
     766             : 
     767           0 :     isIgnoredUpdate( pEntry );
     768           0 :     addAdditional( pEntry, SvLBoxButtonKind_disabledCheckbox );
     769           0 : }
     770             : 
     771             : //------------------------------------------------------------------------------
     772           0 : void UpdateDialog::addSpecificError( UpdateDialog::SpecificError & data )
     773             : {
     774           0 :     sal_uInt16 nIndex = sal::static_int_cast< sal_uInt16 >( m_specificErrors.size() );
     775           0 :     UpdateDialog::Index *pEntry = new UpdateDialog::Index( SPECIFIC_ERROR, m_nLastID, nIndex, data.name );
     776             : 
     777           0 :     data.m_nID = m_nLastID;
     778           0 :     m_nLastID += 1;
     779             : 
     780           0 :     m_specificErrors.push_back( data );
     781           0 :     m_ListboxEntries.push_back( pEntry );
     782             : 
     783           0 :     addAdditional( pEntry, SvLBoxButtonKind_staticImage);
     784           0 : }
     785             : 
     786           0 : void UpdateDialog::checkingDone() {
     787           0 :     m_checking.Hide();
     788           0 :     m_throbber.stop();
     789           0 :     m_throbber.Hide();
     790           0 :     if (m_updates.getItemCount() == 0)
     791             :     {
     792           0 :         clearDescription();
     793           0 :         m_description.Enable();
     794           0 :         m_descriptions.Enable();
     795             : 
     796           0 :         if ( m_disabledUpdates.empty() && m_specificErrors.empty() && m_ignoredUpdates.empty() )
     797           0 :             showDescription( m_none, false );
     798             :         else
     799           0 :             showDescription( m_noInstallable, false );
     800             :     }
     801             : 
     802           0 :     enableOk();
     803           0 : }
     804             : 
     805           0 : void UpdateDialog::enableOk() {
     806           0 :     if (!m_checking.IsVisible()) {
     807           0 :         m_ok.Enable(m_updates.GetCheckedEntryCount() != 0);
     808             :     }
     809           0 : }
     810             : 
     811             : // *********************************************************************************
     812           0 : void UpdateDialog::createNotifyJob( bool bPrepareOnly,
     813             :     uno::Sequence< uno::Sequence< rtl::OUString > > &rItemList )
     814             : {
     815           0 :     if ( !dp_misc::office_is_running() )
     816           0 :         return;
     817             : 
     818             :     // notify update check job
     819             :     try
     820             :     {
     821             :         uno::Reference< lang::XMultiServiceFactory > xConfigProvider(
     822             :             configuration::theDefaultProvider::get(
     823           0 :                 comphelper::getProcessComponentContext()));
     824             : 
     825           0 :         beans::PropertyValue aProperty;
     826           0 :         aProperty.Name  = OUSTR( "nodepath" );
     827           0 :         aProperty.Value = uno::makeAny( OUSTR("org.openoffice.Office.Addons/AddonUI/OfficeHelp/UpdateCheckJob") );
     828             : 
     829           0 :         uno::Sequence< uno::Any > aArgumentList( 1 );
     830           0 :         aArgumentList[0] = uno::makeAny( aProperty );
     831             : 
     832             :         uno::Reference< container::XNameAccess > xNameAccess(
     833           0 :             xConfigProvider->createInstanceWithArguments(
     834           0 :                 OUSTR("com.sun.star.configuration.ConfigurationAccess"), aArgumentList ),
     835           0 :             uno::UNO_QUERY_THROW );
     836             : 
     837           0 :         util::URL aURL;
     838           0 :         xNameAccess->getByName(OUSTR("URL")) >>= aURL.Complete;
     839             : 
     840           0 :         uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
     841           0 :         uno::Reference < util::XURLTransformer > xTransformer( util::URLTransformer::create(::comphelper::getProcessComponentContext()) );
     842             : 
     843           0 :         xTransformer->parseStrict(aURL);
     844             : 
     845           0 :         uno::Reference < frame::XDesktop > xDesktop( xFactory->createInstance( OUSTR( "com.sun.star.frame.Desktop" ) ),
     846           0 :             uno::UNO_QUERY_THROW );
     847           0 :         uno::Reference< frame::XDispatchProvider > xDispatchProvider( xDesktop->getCurrentFrame(),
     848           0 :             uno::UNO_QUERY_THROW );
     849           0 :         uno::Reference< frame::XDispatch > xDispatch = xDispatchProvider->queryDispatch(aURL, rtl::OUString(), 0);
     850             : 
     851           0 :         if( xDispatch.is() )
     852             :         {
     853           0 :             uno::Sequence< beans::PropertyValue > aPropList(2);
     854           0 :             aProperty.Name  = OUSTR( "updateList" );
     855           0 :             aProperty.Value = uno::makeAny( rItemList );
     856           0 :             aPropList[0] = aProperty;
     857           0 :             aProperty.Name  = OUSTR( "prepareOnly" );
     858           0 :             aProperty.Value = uno::makeAny( bPrepareOnly );
     859           0 :             aPropList[1] = aProperty;
     860             : 
     861           0 :             xDispatch->dispatch(aURL, aPropList );
     862           0 :         }
     863             :     }
     864           0 :     catch( const uno::Exception& e )
     865             :     {
     866             :         dp_misc::TRACE( OUSTR("Caught exception: ")
     867           0 :             + e.Message + OUSTR("\n thread terminated.\n\n"));
     868             :     }
     869             : }
     870             : 
     871             : // *********************************************************************************
     872           0 : void UpdateDialog::notifyMenubar( bool bPrepareOnly, bool bRecheckOnly )
     873             : {
     874           0 :     if ( !dp_misc::office_is_running() )
     875           0 :         return;
     876             : 
     877           0 :     uno::Sequence< uno::Sequence< rtl::OUString > > aItemList;
     878             : 
     879           0 :     if ( ! bRecheckOnly )
     880             :     {
     881           0 :         sal_Int32 nCount = 0;
     882           0 :         for ( sal_Int16 i = 0; i < m_updates.getItemCount(); ++i )
     883             :         {
     884           0 :             uno::Sequence< rtl::OUString > aItem(2);
     885             : 
     886           0 :             UpdateDialog::Index const * p = static_cast< UpdateDialog::Index const * >(m_updates.GetEntryData(i));
     887             : 
     888           0 :             if ( p->m_eKind == ENABLED_UPDATE )
     889             :             {
     890           0 :                 dp_gui::UpdateData aUpdData = m_enabledUpdates[ p->m_nIndex ];
     891           0 :                 aItem[0] = dp_misc::getIdentifier( aUpdData.aInstalledPackage );
     892             : 
     893           0 :                 dp_misc::DescriptionInfoset aInfoset( m_context, aUpdData.aUpdateInfo );
     894           0 :                 aItem[1] = aInfoset.getVersion();
     895             :             }
     896             :             else
     897           0 :                 continue;
     898             : 
     899           0 :             aItemList.realloc( nCount + 1 );
     900           0 :             aItemList[ nCount ] = aItem;
     901           0 :             nCount += 1;
     902           0 :         }
     903             :     }
     904             : 
     905           0 :     storeIgnoredUpdates();
     906           0 :     createNotifyJob( bPrepareOnly, aItemList );
     907             : }
     908             : 
     909             : // *********************************************************************************
     910             : 
     911           0 : void UpdateDialog::initDescription()
     912             : {
     913           0 :     m_PublisherLabel.Hide();
     914           0 :     m_PublisherLink.Hide();
     915           0 :     m_ReleaseNotesLabel.Hide();
     916           0 :     m_ReleaseNotesLink.Hide();
     917           0 :     m_descriptions.Hide();
     918             : 
     919           0 :     Link aLink = LINK( this, UpdateDialog, hyperlink_clicked );
     920           0 :     m_PublisherLink.SetClickHdl( aLink );
     921           0 :     m_ReleaseNotesLink.SetClickHdl( aLink );
     922             : 
     923           0 :     long nTextWidth = m_PublisherLabel.GetCtrlTextWidth( m_PublisherLabel.GetText() );
     924           0 :     long nTemp = m_ReleaseNotesLabel.GetTextWidth( m_ReleaseNotesLabel.GetText() );
     925           0 :     if ( nTemp > nTextWidth )
     926           0 :         nTextWidth = nTemp;
     927           0 :     nTextWidth = nTextWidth * 110 / 100;
     928             : 
     929           0 :     Size aNewSize = m_PublisherLabel.GetSizePixel();
     930           0 :     if ( nTextWidth > aNewSize.Width() )
     931             :     {
     932           0 :         long nDelta = nTextWidth - aNewSize.Width();
     933           0 :         aNewSize.Width() = nTextWidth;
     934           0 :         m_PublisherLabel.SetSizePixel( aNewSize );
     935           0 :         m_ReleaseNotesLabel.SetSizePixel( aNewSize );
     936             : 
     937           0 :         aNewSize = m_PublisherLink.GetSizePixel();
     938           0 :         aNewSize.Width() = aNewSize.Width() - nDelta;
     939           0 :         Point aNewPos = m_PublisherLink.GetPosPixel();
     940           0 :         aNewPos.X() = aNewPos.X() + nDelta;
     941           0 :         m_PublisherLink.SetPosSizePixel( aNewPos, aNewSize );
     942           0 :         aNewPos.Y() = m_ReleaseNotesLink.GetPosPixel().Y();
     943           0 :         m_ReleaseNotesLink.SetPosSizePixel( aNewPos, aNewSize );
     944             :     }
     945             : 
     946           0 :     m_aFirstLinePos = m_descriptions.GetPosPixel();
     947           0 :     m_aFirstLineSize = m_descriptions.GetSizePixel();
     948           0 :     Size aMarginSize = LogicToPixel( Size( RSC_SP_CTRL_GROUP_X, RSC_SP_CTRL_GROUP_Y ), MAP_APPFONT );
     949           0 :     Point aThirdLinePos = m_ReleaseNotesLabel.GetPosPixel();
     950           0 :     aThirdLinePos.Y() = aThirdLinePos.Y() + m_ReleaseNotesLabel.GetSizePixel().Height() + aMarginSize.Height();
     951           0 :     m_nFirstLineDelta = aThirdLinePos.Y() - m_aFirstLinePos.Y();
     952           0 :     m_nOneLineMissing = m_ReleaseNotesLabel.GetPosPixel().Y() - m_PublisherLabel.GetPosPixel().Y();
     953           0 : }
     954             : 
     955           0 : void UpdateDialog::clearDescription()
     956             : {
     957           0 :     String sEmpty;
     958           0 :     m_PublisherLabel.Hide();
     959           0 :     m_PublisherLink.Hide();
     960           0 :     m_PublisherLink.SetText( sEmpty );
     961           0 :     m_PublisherLink.SetURL( sEmpty );
     962           0 :     m_ReleaseNotesLabel.Hide();
     963           0 :     m_ReleaseNotesLink.Hide();
     964           0 :     m_ReleaseNotesLink.SetURL( sEmpty );
     965           0 :     if ( m_PublisherLabel.GetPosPixel().Y() == m_ReleaseNotesLabel.GetPosPixel().Y() )
     966             :     {
     967           0 :         Point aNewPos = m_ReleaseNotesLabel.GetPosPixel();
     968           0 :         aNewPos.Y() += m_nOneLineMissing;
     969           0 :         m_ReleaseNotesLabel.SetPosPixel( aNewPos );
     970           0 :         aNewPos = m_ReleaseNotesLink.GetPosPixel();
     971           0 :         aNewPos.Y() += m_nOneLineMissing;
     972           0 :         m_ReleaseNotesLink.SetPosPixel( aNewPos );
     973             :     }
     974           0 :     m_descriptions.Hide();
     975           0 :     m_descriptions.Clear();
     976           0 :     m_descriptions.SetPosSizePixel( m_aFirstLinePos, m_aFirstLineSize );
     977           0 : }
     978             : 
     979           0 : bool UpdateDialog::showDescription(uno::Reference< xml::dom::XNode > const & aUpdateInfo)
     980             : {
     981           0 :     dp_misc::DescriptionInfoset infoset(m_context, aUpdateInfo);
     982             :     return showDescription(infoset.getLocalizedPublisherNameAndURL(),
     983           0 :                            infoset.getLocalizedReleaseNotesURL());
     984             : }
     985             : 
     986           0 : bool UpdateDialog::showDescription(uno::Reference< deployment::XPackage > const & aExtension)
     987             : {
     988             :     OSL_ASSERT(aExtension.is());
     989           0 :     beans::StringPair pubInfo = aExtension->getPublisherInfo();
     990             :     return showDescription(std::make_pair(pubInfo.First, pubInfo.Second),
     991           0 :                            OUSTR(""));
     992             : }
     993             : 
     994           0 : bool UpdateDialog::showDescription(std::pair< rtl::OUString, rtl::OUString > const & pairPublisher,
     995             :                                    rtl::OUString const & sReleaseNotes)
     996             : {
     997           0 :     rtl::OUString sPub = pairPublisher.first;
     998           0 :     rtl::OUString sURL = pairPublisher.second;
     999             : 
    1000           0 :     if ( sPub.isEmpty() && sURL.isEmpty() && sReleaseNotes.isEmpty() )
    1001             :         // nothing to show
    1002           0 :         return false;
    1003             : 
    1004           0 :     bool bPublisher = false;
    1005           0 :     if ( !sPub.isEmpty() )
    1006             :     {
    1007           0 :         m_PublisherLabel.Show();
    1008           0 :         m_PublisherLink.Show();
    1009           0 :         m_PublisherLink.SetText( sPub );
    1010           0 :         m_PublisherLink.SetURL( sURL );
    1011           0 :         bPublisher = true;
    1012             :     }
    1013             : 
    1014           0 :     if ( !sReleaseNotes.isEmpty() )
    1015             :     {
    1016           0 :         if ( !bPublisher )
    1017             :         {
    1018           0 :             m_ReleaseNotesLabel.SetPosPixel( m_PublisherLabel.GetPosPixel() );
    1019           0 :             m_ReleaseNotesLink.SetPosPixel( m_PublisherLink.GetPosPixel() );
    1020             :         }
    1021           0 :         m_ReleaseNotesLabel.Show();
    1022           0 :         m_ReleaseNotesLink.Show();
    1023           0 :         m_ReleaseNotesLink.SetURL( sReleaseNotes );
    1024             :     }
    1025           0 :     return true;
    1026             : }
    1027             : 
    1028           0 : bool UpdateDialog::showDescription( const String& rDescription, bool bWithPublisher )
    1029             : {
    1030           0 :     if ( rDescription.Len() == 0 )
    1031             :         // nothing to show
    1032           0 :         return false;
    1033             : 
    1034           0 :     if ( bWithPublisher )
    1035             :     {
    1036           0 :         bool bOneLineMissing = !m_ReleaseNotesLabel.IsVisible() || !m_PublisherLabel.IsVisible();
    1037           0 :         Point aNewPos = m_aFirstLinePos;
    1038           0 :         aNewPos.Y() += m_nFirstLineDelta;
    1039           0 :         if ( bOneLineMissing )
    1040           0 :             aNewPos.Y() -= m_nOneLineMissing;
    1041           0 :         Size aNewSize = m_aFirstLineSize;
    1042           0 :         aNewSize.Height() -= m_nFirstLineDelta;
    1043           0 :         if ( bOneLineMissing )
    1044           0 :             aNewSize.Height() += m_nOneLineMissing;
    1045           0 :         m_descriptions.SetPosSizePixel( aNewPos, aNewSize );
    1046             :     }
    1047           0 :     m_descriptions.Show();
    1048           0 :     m_descriptions.SetText( rDescription );
    1049           0 :     return true;
    1050             : }
    1051             : 
    1052             : //------------------------------------------------------------------------------
    1053           0 : void UpdateDialog::getIgnoredUpdates()
    1054             : {
    1055             :     uno::Reference< lang::XMultiServiceFactory > xConfig(
    1056           0 :         configuration::theDefaultProvider::get(m_context));
    1057           0 :     beans::NamedValue aValue( OUSTR("nodepath"), uno::Any( IGNORED_UPDATES ) );
    1058           0 :     uno::Sequence< uno::Any > args(1);
    1059           0 :     args[0] <<= aValue;
    1060             : 
    1061           0 :     uno::Reference< container::XNameAccess > xNameAccess( xConfig->createInstanceWithArguments( OUSTR("com.sun.star.configuration.ConfigurationAccess"), args), uno::UNO_QUERY_THROW );
    1062           0 :     uno::Sequence< rtl::OUString > aElementNames = xNameAccess->getElementNames();
    1063             : 
    1064           0 :     for ( sal_Int32 i = 0; i < aElementNames.getLength(); i++ )
    1065             :     {
    1066           0 :         ::rtl::OUString aIdentifier = aElementNames[i];
    1067           0 :         ::rtl::OUString aVersion;
    1068             : 
    1069           0 :         uno::Any aPropValue( uno::Reference< beans::XPropertySet >( xNameAccess->getByName( aIdentifier ), uno::UNO_QUERY_THROW )->getPropertyValue( PROPERTY_VERSION ) );
    1070           0 :         aPropValue >>= aVersion;
    1071           0 :         IgnoredUpdate *pData = new IgnoredUpdate( aIdentifier, aVersion );
    1072           0 :         m_ignoredUpdates.push_back( pData );
    1073           0 :     }
    1074           0 : }
    1075             : 
    1076             : //------------------------------------------------------------------------------
    1077           0 : void UpdateDialog::storeIgnoredUpdates()
    1078             : {
    1079           0 :     if ( m_bModified && ( !m_ignoredUpdates.empty() ) )
    1080             :     {
    1081             :         uno::Reference< lang::XMultiServiceFactory > xConfig(
    1082           0 :             configuration::theDefaultProvider::get(m_context));
    1083           0 :         beans::NamedValue aValue( OUSTR("nodepath"), uno::Any( IGNORED_UPDATES ) );
    1084           0 :         uno::Sequence< uno::Any > args(1);
    1085           0 :         args[0] <<= aValue;
    1086             : 
    1087           0 :         uno::Reference< container::XNameContainer > xNameContainer( xConfig->createInstanceWithArguments(
    1088           0 :             OUSTR("com.sun.star.configuration.ConfigurationUpdateAccess"), args ), uno::UNO_QUERY_THROW );
    1089             : 
    1090           0 :         for ( std::vector< UpdateDialog::IgnoredUpdate* >::iterator i( m_ignoredUpdates.begin() ); i != m_ignoredUpdates.end(); ++i )
    1091             :         {
    1092           0 :             if ( xNameContainer->hasByName( (*i)->sExtensionID ) )
    1093             :             {
    1094           0 :                 if ( (*i)->bRemoved )
    1095           0 :                     xNameContainer->removeByName( (*i)->sExtensionID );
    1096             :                 else
    1097           0 :                     uno::Reference< beans::XPropertySet >( xNameContainer->getByName( (*i)->sExtensionID ), uno::UNO_QUERY_THROW )->setPropertyValue( PROPERTY_VERSION, uno::Any( (*i)->sVersion ) );
    1098             :             }
    1099           0 :             else if ( ! (*i)->bRemoved )
    1100             :             {
    1101           0 :                 uno::Reference< beans::XPropertySet > elem( uno::Reference< lang::XSingleServiceFactory >( xNameContainer, uno::UNO_QUERY_THROW )->createInstance(), uno::UNO_QUERY_THROW );
    1102           0 :                 elem->setPropertyValue( PROPERTY_VERSION, uno::Any( (*i)->sVersion ) );
    1103           0 :                 xNameContainer->insertByName( (*i)->sExtensionID, uno::Any( elem ) );
    1104             :             }
    1105             :         }
    1106             : 
    1107           0 :         uno::Reference< util::XChangesBatch > xChangesBatch( xNameContainer, uno::UNO_QUERY );
    1108           0 :         if ( xChangesBatch.is() && xChangesBatch->hasPendingChanges() )
    1109           0 :             xChangesBatch->commitChanges();
    1110             :     }
    1111             : 
    1112           0 :     m_bModified = false;
    1113           0 : }
    1114             : 
    1115             : //------------------------------------------------------------------------------
    1116           0 : bool UpdateDialog::isIgnoredUpdate( UpdateDialog::Index * index )
    1117             : {
    1118           0 :     bool bIsIgnored = false;
    1119             : 
    1120           0 :     if (! m_ignoredUpdates.empty() )
    1121             :     {
    1122           0 :         rtl::OUString aExtensionID;
    1123           0 :         rtl::OUString aVersion;
    1124             : 
    1125           0 :         if ( index->m_eKind == ENABLED_UPDATE )
    1126             :         {
    1127           0 :             dp_gui::UpdateData aUpdData = m_enabledUpdates[ index->m_nIndex ];
    1128           0 :             aExtensionID = dp_misc::getIdentifier( aUpdData.aInstalledPackage );
    1129           0 :             aVersion = aUpdData.updateVersion;
    1130             :         }
    1131           0 :         else if ( index->m_eKind == DISABLED_UPDATE )
    1132             :         {
    1133           0 :             DisabledUpdate &rData = m_disabledUpdates[ index->m_nIndex ];
    1134           0 :             dp_misc::DescriptionInfoset aInfoset( m_context, rData.aUpdateInfo );
    1135           0 :             ::boost::optional< ::rtl::OUString > aID( aInfoset.getIdentifier() );
    1136           0 :             if ( aID )
    1137           0 :                 aExtensionID = *aID;
    1138           0 :             aVersion = aInfoset.getVersion();
    1139             :         }
    1140             : 
    1141           0 :         for ( std::vector< UpdateDialog::IgnoredUpdate* >::iterator i( m_ignoredUpdates.begin() ); i != m_ignoredUpdates.end(); ++i )
    1142             :         {
    1143           0 :             if ( (*i)->sExtensionID == aExtensionID )
    1144             :             {
    1145           0 :                 if ( ( !(*i)->sVersion.isEmpty() ) || ( (*i)->sVersion == aVersion ) )
    1146             :                 {
    1147           0 :                     bIsIgnored = true;
    1148           0 :                     index->m_bIgnored = true;
    1149             :                 }
    1150             :                 else // when we find another update of an ignored version, we will remove the old one to keep the ignored list small
    1151           0 :                     (*i)->bRemoved = true;
    1152           0 :                 break;
    1153             :             }
    1154           0 :         }
    1155             :     }
    1156             : 
    1157           0 :     return bIsIgnored;
    1158             : }
    1159             : 
    1160             : //------------------------------------------------------------------------------
    1161           0 : void UpdateDialog::setIgnoredUpdate( UpdateDialog::Index *pIndex, bool bIgnore, bool bIgnoreAll )
    1162             : {
    1163           0 :     rtl::OUString aExtensionID;
    1164           0 :     rtl::OUString aVersion;
    1165             : 
    1166           0 :     m_bModified = true;
    1167             : 
    1168           0 :     if ( pIndex->m_eKind == ENABLED_UPDATE )
    1169             :     {
    1170           0 :         dp_gui::UpdateData aUpdData = m_enabledUpdates[ pIndex->m_nIndex ];
    1171           0 :         aExtensionID = dp_misc::getIdentifier( aUpdData.aInstalledPackage );
    1172           0 :         if ( !bIgnoreAll )
    1173           0 :             aVersion = aUpdData.updateVersion;
    1174             :     }
    1175           0 :     else if ( pIndex->m_eKind == DISABLED_UPDATE )
    1176             :     {
    1177           0 :         DisabledUpdate &rData = m_disabledUpdates[ pIndex->m_nIndex ];
    1178           0 :         dp_misc::DescriptionInfoset aInfoset( m_context, rData.aUpdateInfo );
    1179           0 :         ::boost::optional< ::rtl::OUString > aID( aInfoset.getIdentifier() );
    1180           0 :         if ( aID )
    1181           0 :             aExtensionID = *aID;
    1182           0 :         if ( !bIgnoreAll )
    1183           0 :             aVersion = aInfoset.getVersion();
    1184             :     }
    1185             : 
    1186           0 :     if ( !aExtensionID.isEmpty() )
    1187             :     {
    1188           0 :         bool bFound = false;
    1189           0 :         for ( std::vector< UpdateDialog::IgnoredUpdate* >::iterator i( m_ignoredUpdates.begin() ); i != m_ignoredUpdates.end(); ++i )
    1190             :         {
    1191           0 :             if ( (*i)->sExtensionID == aExtensionID )
    1192             :             {
    1193           0 :                 (*i)->sVersion = aVersion;
    1194           0 :                 (*i)->bRemoved = !bIgnore;
    1195           0 :                 bFound = true;
    1196           0 :                 break;
    1197             :             }
    1198             :         }
    1199           0 :         if ( bIgnore && !bFound )
    1200             :         {
    1201           0 :             IgnoredUpdate *pData = new IgnoredUpdate( aExtensionID, aVersion );
    1202           0 :             m_ignoredUpdates.push_back( pData );
    1203             :         }
    1204           0 :     }
    1205           0 : }
    1206             : 
    1207             : //------------------------------------------------------------------------------
    1208             : 
    1209           0 : IMPL_LINK_NOARG(UpdateDialog, selectionHandler)
    1210             : {
    1211           0 :     rtl::OUStringBuffer b;
    1212           0 :     bool bInserted = false;
    1213             :     UpdateDialog::Index const * p = static_cast< UpdateDialog::Index const * >(
    1214           0 :         m_updates.GetEntryData(m_updates.GetSelectEntryPos()));
    1215           0 :     clearDescription();
    1216             : 
    1217           0 :     if ( p != NULL )
    1218             :     {
    1219           0 :         sal_uInt16 pos = p->m_nIndex;
    1220             : 
    1221           0 :         switch (p->m_eKind)
    1222             :         {
    1223             :             case ENABLED_UPDATE:
    1224             :             {
    1225           0 :                 if ( m_enabledUpdates[ pos ].aUpdateSource.is() )
    1226           0 :                     bInserted = showDescription( m_enabledUpdates[ pos ].aUpdateSource );
    1227             :                 else
    1228           0 :                     bInserted = showDescription( m_enabledUpdates[ pos ].aUpdateInfo );
    1229             : 
    1230           0 :                 if ( p->m_bIgnored )
    1231           0 :                     b.append( m_ignoredUpdate );
    1232             : 
    1233           0 :                 break;
    1234             :             }
    1235             :             case DISABLED_UPDATE:
    1236             :             {
    1237           0 :                 if ( !m_disabledUpdates.empty() )
    1238           0 :                     bInserted = showDescription( m_disabledUpdates[pos].aUpdateInfo );
    1239             : 
    1240           0 :                 if ( p->m_bIgnored )
    1241           0 :                     b.append( m_ignoredUpdate );
    1242             : 
    1243           0 :                 if ( m_disabledUpdates.empty() )
    1244           0 :                     break;
    1245             : 
    1246           0 :                 UpdateDialog::DisabledUpdate & data = m_disabledUpdates[ pos ];
    1247           0 :                 if (data.unsatisfiedDependencies.getLength() != 0)
    1248             :                 {
    1249             :                     // create error string for version mismatch
    1250           0 :                     ::rtl::OUString sVersion( RTL_CONSTASCII_USTRINGPARAM("%VERSION") );
    1251           0 :                     ::rtl::OUString sProductName( RTL_CONSTASCII_USTRINGPARAM("%PRODUCTNAME") );
    1252           0 :                     sal_Int32 nPos = m_noDependencyCurVer.indexOf( sVersion );
    1253           0 :                     if ( nPos >= 0 )
    1254             :                     {
    1255           0 :                         m_noDependencyCurVer = m_noDependencyCurVer.replaceAt( nPos, sVersion.getLength(), utl::ConfigManager::getAboutBoxProductVersion() );
    1256             :                     }
    1257           0 :                     nPos = m_noDependencyCurVer.indexOf( sProductName );
    1258           0 :                     if ( nPos >= 0 )
    1259             :                     {
    1260           0 :                         m_noDependencyCurVer = m_noDependencyCurVer.replaceAt( nPos, sProductName.getLength(), utl::ConfigManager::getProductName() );
    1261             :                     }
    1262           0 :                     nPos = m_noDependency.indexOf( sProductName );
    1263           0 :                     if ( nPos >= 0 )
    1264             :                     {
    1265           0 :                         m_noDependency = m_noDependency.replaceAt( nPos, sProductName.getLength(), utl::ConfigManager::getProductName() );
    1266             :                     }
    1267             : 
    1268           0 :                     b.append(m_noInstall);
    1269           0 :                     b.append(LF);
    1270           0 :                     b.append(m_noDependency);
    1271           0 :                     for (sal_Int32 i = 0;
    1272           0 :                          i < data.unsatisfiedDependencies.getLength(); ++i)
    1273             :                     {
    1274           0 :                         b.append(LF);
    1275           0 :                         b.appendAscii(RTL_CONSTASCII_STRINGPARAM("  "));
    1276             :                             // U+2003 EM SPACE would be better than two spaces,
    1277             :                             // but some fonts do not contain it
    1278             :                         b.append(
    1279             :                             confineToParagraph(
    1280           0 :                                 data.unsatisfiedDependencies[i]));
    1281             :                     }
    1282           0 :                     b.append(LF);
    1283           0 :                     b.appendAscii(RTL_CONSTASCII_STRINGPARAM("  "));
    1284           0 :                     b.append(m_noDependencyCurVer);
    1285             :                 }
    1286           0 :                 break;
    1287             :             }
    1288             :             case SPECIFIC_ERROR:
    1289             :             {
    1290           0 :                 UpdateDialog::SpecificError & data = m_specificErrors[ pos ];
    1291           0 :                 b.append(m_failure);
    1292           0 :                 b.append(LF);
    1293           0 :                 b.append( data.message.isEmpty() ? m_unknownError : data.message );
    1294           0 :                 break;
    1295             :             }
    1296             :             default:
    1297             :                 OSL_ASSERT(false);
    1298           0 :                 break;
    1299             :         }
    1300             :     }
    1301             : 
    1302           0 :     if ( b.getLength() == 0 )
    1303           0 :         b.append( m_noDescription );
    1304             : 
    1305           0 :     showDescription( b.makeStringAndClear(), bInserted );
    1306           0 :     return 0;
    1307             : }
    1308             : 
    1309           0 : IMPL_LINK_NOARG(UpdateDialog, allHandler)
    1310             : {
    1311           0 :     if (m_all.IsChecked())
    1312             :     {
    1313           0 :         m_update.Enable();
    1314           0 :         m_updates.Enable();
    1315           0 :         m_description.Enable();
    1316           0 :         m_descriptions.Enable();
    1317             : 
    1318           0 :         for (std::vector< UpdateDialog::Index* >::iterator i( m_ListboxEntries.begin() );
    1319           0 :              i != m_ListboxEntries.end(); ++i )
    1320             :         {
    1321           0 :             if ( (*i)->m_bIgnored || ( (*i)->m_eKind != ENABLED_UPDATE ) )
    1322           0 :                 insertItem( (*i), SvLBoxButtonKind_disabledCheckbox );
    1323             :         }
    1324             :     }
    1325             :     else
    1326             :     {
    1327           0 :         for ( sal_uInt16 i = 0; i < m_updates.getItemCount(); )
    1328             :         {
    1329           0 :             UpdateDialog::Index const * p = static_cast< UpdateDialog::Index const * >( m_updates.GetEntryData(i) );
    1330           0 :             if ( p->m_bIgnored || ( p->m_eKind != ENABLED_UPDATE ) )
    1331             :             {
    1332           0 :                 m_updates.RemoveEntry(i);
    1333             :             } else {
    1334           0 :                 ++i;
    1335             :             }
    1336             :         }
    1337             : 
    1338           0 :         if (m_updates.getItemCount() == 0)
    1339             :         {
    1340           0 :             clearDescription();
    1341           0 :             m_update.Disable();
    1342           0 :             m_updates.Disable();
    1343           0 :             if (m_checking.IsVisible())
    1344           0 :                 m_description.Disable();
    1345             :             else
    1346           0 :                 showDescription(m_noInstallable,false);
    1347             :         }
    1348             :     }
    1349           0 :     return 0;
    1350             : }
    1351             : 
    1352           0 : IMPL_LINK_NOARG(UpdateDialog, okHandler)
    1353             : {
    1354             :     //If users are going to update a shared extension then we need
    1355             :     //to warn them
    1356             :     typedef ::std::vector<UpdateData>::const_iterator CIT;
    1357           0 :     for (CIT i = m_enabledUpdates.begin(); i < m_enabledUpdates.end(); ++i)
    1358             :     {
    1359             :         OSL_ASSERT(i->aInstalledPackage.is());
    1360             :         //If the user has no write access to the shared folder then the update
    1361             :         //for a shared extension is disable, that is it cannot be in m_enabledUpdates
    1362             :     }
    1363             : 
    1364             : 
    1365           0 :     for (sal_uInt16 i = 0; i < m_updates.getItemCount(); ++i) {
    1366             :         UpdateDialog::Index const * p =
    1367             :             static_cast< UpdateDialog::Index const * >(
    1368           0 :                 m_updates.GetEntryData(i));
    1369           0 :         if (p->m_eKind == ENABLED_UPDATE && m_updates.IsChecked(i)) {
    1370           0 :             m_updateData.push_back( m_enabledUpdates[ p->m_nIndex ] );
    1371             :         }
    1372             :     }
    1373             : 
    1374           0 :     EndDialog(RET_OK);
    1375           0 :     return 0;
    1376             : }
    1377             : 
    1378           0 : IMPL_LINK_NOARG(UpdateDialog, closeHandler) {
    1379           0 :     m_thread->stop();
    1380           0 :     EndDialog(RET_CANCEL);
    1381           0 :     return 0;
    1382             : }
    1383             : 
    1384           0 : IMPL_LINK( UpdateDialog, hyperlink_clicked, FixedHyperlink*, pHyperlink )
    1385             : {
    1386           0 :     ::rtl::OUString sURL;
    1387           0 :     if ( pHyperlink )
    1388           0 :         sURL = ::rtl::OUString( pHyperlink->GetURL() );
    1389           0 :     if ( sURL.isEmpty() )
    1390           0 :         return 0;
    1391             : 
    1392             :     try
    1393             :     {
    1394             :         uno::Reference< com::sun::star::system::XSystemShellExecute > xSystemShellExecute(
    1395           0 :             com::sun::star::system::SystemShellExecute::create(m_context) );
    1396             :         //throws lang::IllegalArgumentException, system::SystemShellExecuteException
    1397           0 :         xSystemShellExecute->execute( sURL, ::rtl::OUString(), com::sun::star::system::SystemShellExecuteFlags::URIS_ONLY);
    1398             :     }
    1399           0 :     catch ( const uno::Exception& )
    1400             :     {
    1401             :     }
    1402             : 
    1403           0 :     return 1;
    1404             : }
    1405             : 
    1406             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10