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

Generated by: LCOV version 1.11