2006-12-20 13:24:40 +00:00
|
|
|
/*************************************************************************
|
|
|
|
*
|
|
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
|
|
*
|
|
|
|
* $RCSfile: dp_gui_updatedialog.cxx,v $
|
|
|
|
*
|
2007-07-26 07:54:10 +00:00
|
|
|
* $Revision: 1.8 $
|
2006-12-20 13:24:40 +00:00
|
|
|
*
|
2007-07-26 07:54:10 +00:00
|
|
|
* last change: $Author: rt $ $Date: 2007-07-26 08:54:10 $
|
2006-12-20 13:24:40 +00:00
|
|
|
*
|
|
|
|
* The Contents of this file are made available subject to
|
|
|
|
* the terms of GNU Lesser General Public License Version 2.1.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* GNU Lesser General Public License Version 2.1
|
|
|
|
* =============================================
|
|
|
|
* Copyright 2006 by Sun Microsystems, Inc.
|
|
|
|
* 901 San Antonio Road, Palo Alto, CA 94303, USA
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License version 2.1, as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
|
|
* MA 02111-1307 USA
|
|
|
|
*
|
|
|
|
************************************************************************/
|
|
|
|
|
|
|
|
// MARKER(update_precomp.py): autogen include statement, do not remove
|
|
|
|
#include "precompiled_desktop.hxx"
|
|
|
|
|
|
|
|
#include "sal/config.h"
|
|
|
|
|
|
|
|
#include <cstddef>
|
|
|
|
#include <limits>
|
|
|
|
#include <map>
|
|
|
|
#include <memory>
|
|
|
|
#include <utility>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include "boost/optional.hpp"
|
|
|
|
#include "com/sun/star/awt/Rectangle.hpp"
|
|
|
|
#include "com/sun/star/awt/WindowAttribute.hpp"
|
|
|
|
#include "com/sun/star/awt/WindowClass.hpp"
|
|
|
|
#include "com/sun/star/awt/WindowDescriptor.hpp"
|
|
|
|
#include "com/sun/star/awt/XThrobber.hpp"
|
|
|
|
#include "com/sun/star/awt/XToolkit.hpp"
|
|
|
|
#include "com/sun/star/awt/XWindow.hpp"
|
|
|
|
#include "com/sun/star/awt/XWindowPeer.hpp"
|
|
|
|
#include "com/sun/star/beans/Optional.hpp"
|
|
|
|
#include "com/sun/star/deployment/DeploymentException.hpp"
|
|
|
|
#include "com/sun/star/deployment/UpdateInformationProvider.hpp"
|
|
|
|
#include "com/sun/star/deployment/XPackage.hpp"
|
|
|
|
#include "com/sun/star/deployment/XPackageManager.hpp"
|
|
|
|
#include "com/sun/star/deployment/XUpdateInformationProvider.hpp"
|
|
|
|
#include "com/sun/star/lang/IllegalArgumentException.hpp"
|
|
|
|
#include "com/sun/star/lang/XMultiComponentFactory.hpp"
|
|
|
|
#include "com/sun/star/task/XAbortChannel.hpp"
|
|
|
|
#include "com/sun/star/ucb/CommandAbortedException.hpp"
|
|
|
|
#include "com/sun/star/ucb/CommandFailedException.hpp"
|
|
|
|
#include "com/sun/star/ucb/XCommandEnvironment.hpp"
|
|
|
|
#include "com/sun/star/uno/Any.hxx"
|
|
|
|
#include "com/sun/star/uno/Exception.hpp"
|
|
|
|
#include "com/sun/star/uno/Reference.hxx"
|
|
|
|
#include "com/sun/star/uno/RuntimeException.hpp"
|
|
|
|
#include "com/sun/star/uno/Sequence.hxx"
|
|
|
|
#include "com/sun/star/uno/XInterface.hpp"
|
|
|
|
#include "com/sun/star/xml/dom/XElement.hpp"
|
|
|
|
#include "com/sun/star/xml/dom/XNode.hpp"
|
|
|
|
#include "com/sun/star/xml/xpath/XXPathAPI.hpp"
|
|
|
|
#include "osl/diagnose.h"
|
|
|
|
#include "rtl/ref.hxx"
|
|
|
|
#include "rtl/string.h"
|
|
|
|
#include "rtl/ustrbuf.hxx"
|
|
|
|
#include "rtl/ustring.h"
|
|
|
|
#include "rtl/ustring.hxx"
|
|
|
|
#include "sal/types.h"
|
|
|
|
#include "svtools/svlbitm.hxx"
|
|
|
|
#include "svtools/svlbox.hxx"
|
|
|
|
#include "svtools/svmedit.hxx"
|
|
|
|
#include "svx/checklbx.hxx"
|
|
|
|
#include "tools/gen.hxx"
|
|
|
|
#include "tools/link.hxx"
|
|
|
|
#include "tools/resid.hxx"
|
|
|
|
#include "tools/resmgr.hxx"
|
|
|
|
#include "tools/solar.h"
|
|
|
|
#include "tools/string.hxx"
|
|
|
|
#include "vcl/button.hxx"
|
|
|
|
#include "vcl/dialog.hxx"
|
|
|
|
#include "vcl/fixed.hxx"
|
|
|
|
#include "vcl/image.hxx"
|
|
|
|
#include "vcl/msgbox.hxx"
|
|
|
|
#include "vcl/svapp.hxx"
|
|
|
|
#include "vos/mutex.hxx"
|
|
|
|
|
|
|
|
#include "dp_dependencies.hxx"
|
|
|
|
#include "dp_descriptioninfoset.hxx"
|
2007-01-18 13:53:29 +00:00
|
|
|
#include "dp_identifier.hxx"
|
2006-12-20 13:24:40 +00:00
|
|
|
#include "dp_version.hxx"
|
|
|
|
#include "dp_misc.h"
|
|
|
|
|
|
|
|
#include "dp_gui.h"
|
|
|
|
#include "dp_gui.hrc"
|
|
|
|
#include "dp_gui_thread.hxx"
|
|
|
|
#include "dp_gui_updatedata.hxx"
|
|
|
|
#include "dp_gui_updatedialog.hxx"
|
2007-04-26 07:23:53 +00:00
|
|
|
#include "dp_gui_shared.hxx"
|
2007-07-06 11:35:27 +00:00
|
|
|
#include "dp_gui_system.hxx"
|
2006-12-20 13:24:40 +00:00
|
|
|
|
|
|
|
class KeyEvent;
|
|
|
|
class MouseEvent;
|
|
|
|
class Window;
|
|
|
|
namespace com { namespace sun { namespace star { namespace uno {
|
|
|
|
class XComponentContext;
|
|
|
|
} } } }
|
|
|
|
|
|
|
|
using dp_gui::UpdateDialog;
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
static sal_Unicode const LF = 0x000A;
|
|
|
|
static sal_Unicode const CR = 0x000D;
|
|
|
|
|
|
|
|
enum Kind { ENABLED_UPDATE, DISABLED_UPDATE, GENERAL_ERROR, SPECIFIC_ERROR };
|
|
|
|
|
|
|
|
rtl::OUString confineToParagraph(rtl::OUString const & text) {
|
|
|
|
// Confine arbitrary text to a single paragraph in a dp_gui::AutoScrollEdit.
|
|
|
|
// This assumes that U+000A and U+000D are the only paragraph separators in
|
|
|
|
// a dp_gui::AutoScrollEdit, and that replacing them with a single space
|
|
|
|
// each is acceptable:
|
|
|
|
return text.replace(LF, ' ').replace(CR, ' ');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct UpdateDialog::DisabledUpdate {
|
|
|
|
rtl::OUString name;
|
|
|
|
css::uno::Sequence< rtl::OUString > unsatisfiedDependencies;
|
|
|
|
bool permission;
|
|
|
|
boost::optional< rtl::OUString > updateWebsiteUrl;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct UpdateDialog::SpecificError {
|
|
|
|
rtl::OUString name;
|
|
|
|
rtl::OUString message;
|
|
|
|
};
|
|
|
|
|
|
|
|
union UpdateDialog::IndexUnion{
|
|
|
|
std::vector< dp_gui::UpdateData >::size_type enabledUpdate;
|
|
|
|
std::vector< UpdateDialog::DisabledUpdate >::size_type disabledUpdate;
|
|
|
|
std::vector< rtl::OUString >::size_type generalError;
|
|
|
|
std::vector< UpdateDialog::SpecificError >::size_type specificError;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct UpdateDialog::Index {
|
|
|
|
static std::auto_ptr< UpdateDialog::Index const > newEnabledUpdate(
|
|
|
|
std::vector< dp_gui::UpdateData >::size_type n);
|
|
|
|
|
|
|
|
static std::auto_ptr< UpdateDialog::Index const > newDisabledUpdate(
|
|
|
|
std::vector< UpdateDialog::DisabledUpdate >::size_type n);
|
|
|
|
|
|
|
|
static std::auto_ptr< UpdateDialog::Index const > newGeneralError(
|
|
|
|
std::vector< rtl::OUString >::size_type n);
|
|
|
|
|
|
|
|
static std::auto_ptr< UpdateDialog::Index const > newSpecificError(
|
|
|
|
std::vector< UpdateDialog::SpecificError >::size_type n);
|
|
|
|
|
|
|
|
Kind kind;
|
|
|
|
IndexUnion index;
|
|
|
|
|
|
|
|
private:
|
|
|
|
explicit Index(Kind theKind);
|
|
|
|
};
|
|
|
|
|
|
|
|
std::auto_ptr< UpdateDialog::Index const >
|
|
|
|
UpdateDialog::Index::newEnabledUpdate(
|
|
|
|
std::vector< dp_gui::UpdateData >::size_type n)
|
|
|
|
{
|
|
|
|
UpdateDialog::Index * p = new UpdateDialog::Index(ENABLED_UPDATE);
|
|
|
|
p->index.enabledUpdate = n;
|
|
|
|
return std::auto_ptr< UpdateDialog::Index const >(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::auto_ptr< UpdateDialog::Index const >
|
|
|
|
UpdateDialog::Index::newDisabledUpdate(
|
|
|
|
std::vector< UpdateDialog::DisabledUpdate >::size_type n)
|
|
|
|
{
|
|
|
|
UpdateDialog::Index * p = new UpdateDialog::Index(DISABLED_UPDATE);
|
|
|
|
p->index.disabledUpdate = n;
|
|
|
|
return std::auto_ptr< UpdateDialog::Index const >(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::auto_ptr< UpdateDialog::Index const > UpdateDialog::Index::newGeneralError(
|
|
|
|
std::vector< rtl::OUString >::size_type n)
|
|
|
|
{
|
|
|
|
UpdateDialog::Index * p = new UpdateDialog::Index(GENERAL_ERROR);
|
|
|
|
p->index.generalError = n;
|
|
|
|
return std::auto_ptr< UpdateDialog::Index const >(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::auto_ptr< UpdateDialog::Index const >
|
|
|
|
UpdateDialog::Index::newSpecificError(
|
|
|
|
std::vector< UpdateDialog::SpecificError >::size_type n)
|
|
|
|
{
|
|
|
|
UpdateDialog::Index * p = new UpdateDialog::Index(SPECIFIC_ERROR);
|
|
|
|
p->index.specificError = n;
|
|
|
|
return std::auto_ptr< UpdateDialog::Index const >(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
UpdateDialog::Index::Index(Kind theKind): kind(theKind) {}
|
|
|
|
|
|
|
|
class UpdateDialog::Thread: public dp_gui::Thread {
|
|
|
|
public:
|
|
|
|
Thread(
|
|
|
|
css::uno::Reference< css::uno::XComponentContext > const & context,
|
|
|
|
UpdateDialog & dialog,
|
|
|
|
rtl::Reference< dp_gui::SelectedPackageIterator > const &
|
|
|
|
selectedPackages,
|
|
|
|
css::uno::Sequence< css::uno::Reference<
|
|
|
|
css::deployment::XPackageManager > > const & packageManagers);
|
|
|
|
|
|
|
|
void stop();
|
|
|
|
|
|
|
|
private:
|
|
|
|
Thread(UpdateDialog::Thread &); // not defined
|
|
|
|
void operator =(UpdateDialog::Thread &); // not defined
|
|
|
|
|
|
|
|
struct Entry {
|
|
|
|
explicit Entry(
|
|
|
|
css::uno::Reference< css::deployment::XPackage > const & thePackage,
|
|
|
|
css::uno::Reference< css::deployment::XPackageManager > const &
|
|
|
|
thePackageManager,
|
|
|
|
rtl::OUString const & theVersion);
|
|
|
|
|
|
|
|
css::uno::Reference< css::deployment::XPackage > package;
|
|
|
|
css::uno::Reference< css::deployment::XPackageManager > packageManager;
|
|
|
|
rtl::OUString version;
|
|
|
|
css::uno::Reference< css::xml::dom::XNode > info;
|
|
|
|
};
|
|
|
|
|
|
|
|
// A multimap in case an extension is installed in both "user" and "shared":
|
|
|
|
typedef std::multimap< rtl::OUString, Entry > Map;
|
|
|
|
|
|
|
|
virtual ~Thread();
|
|
|
|
|
|
|
|
virtual void execute();
|
|
|
|
|
|
|
|
void handleGeneralError(css::uno::Any const & exception) const;
|
|
|
|
|
|
|
|
void handleSpecificError(
|
|
|
|
css::uno::Reference< css::deployment::XPackage > const & package,
|
|
|
|
css::uno::Any const & exception) const;
|
|
|
|
|
|
|
|
css::uno::Sequence< css::uno::Reference< css::xml::dom::XElement > >
|
|
|
|
getUpdateInformation(
|
|
|
|
css::uno::Reference< css::deployment::XPackage > const & package,
|
|
|
|
css::uno::Sequence< rtl::OUString > const & urls,
|
|
|
|
rtl::OUString const & identifier) const;
|
|
|
|
|
|
|
|
void handle(
|
|
|
|
css::uno::Reference< css::deployment::XPackage > const & package,
|
|
|
|
css::uno::Reference< css::deployment::XPackageManager > const &
|
|
|
|
packageManager,
|
2007-07-06 11:35:27 +00:00
|
|
|
Map * map);
|
2006-12-20 13:24:40 +00:00
|
|
|
|
|
|
|
bool update(
|
|
|
|
css::uno::Reference< css::deployment::XPackage > const & package,
|
|
|
|
css::uno::Reference< css::deployment::XPackageManager > const &
|
|
|
|
packageManager,
|
|
|
|
css::uno::Reference< css::xml::dom::XNode > const & updateInfo) const;
|
|
|
|
|
|
|
|
css::uno::Reference< css::uno::XComponentContext > const & m_context;
|
|
|
|
UpdateDialog & m_dialog;
|
|
|
|
rtl::Reference< dp_gui::SelectedPackageIterator > m_selectedPackages;
|
|
|
|
css::uno::Sequence< css::uno::Reference<
|
|
|
|
css::deployment::XPackageManager > > m_packageManagers;
|
|
|
|
css::uno::Reference< css::deployment::XUpdateInformationProvider >
|
|
|
|
m_updateInformation;
|
|
|
|
|
|
|
|
// guarded by Application::GetSolarMutex():
|
|
|
|
css::uno::Reference< css::task::XAbortChannel > m_abort;
|
|
|
|
bool m_stop;
|
2007-07-06 11:35:27 +00:00
|
|
|
bool m_infoSharedDone;
|
2006-12-20 13:24:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
UpdateDialog::Thread::Thread(
|
|
|
|
css::uno::Reference< css::uno::XComponentContext > const & context,
|
|
|
|
UpdateDialog & dialog,
|
|
|
|
rtl::Reference< dp_gui::SelectedPackageIterator > const & selectedPackages,
|
|
|
|
css::uno::Sequence< css::uno::Reference<
|
|
|
|
css::deployment::XPackageManager > > const & packageManagers):
|
|
|
|
m_context(context),
|
|
|
|
m_dialog(dialog),
|
|
|
|
m_selectedPackages(selectedPackages),
|
|
|
|
m_packageManagers(packageManagers),
|
|
|
|
m_updateInformation(
|
|
|
|
css::deployment::UpdateInformationProvider::create(context)),
|
2007-07-06 11:35:27 +00:00
|
|
|
m_stop(false),
|
|
|
|
m_infoSharedDone(false)
|
2006-12-20 13:24:40 +00:00
|
|
|
{}
|
|
|
|
|
|
|
|
void UpdateDialog::Thread::stop() {
|
|
|
|
css::uno::Reference< css::task::XAbortChannel > abort;
|
|
|
|
{
|
|
|
|
vos::OGuard g(Application::GetSolarMutex());
|
|
|
|
abort = m_abort;
|
|
|
|
m_stop = true;
|
|
|
|
}
|
|
|
|
if (abort.is()) {
|
|
|
|
abort->sendAbort();
|
|
|
|
}
|
|
|
|
m_updateInformation->cancel();
|
|
|
|
}
|
|
|
|
|
|
|
|
UpdateDialog::Thread::Entry::Entry(
|
|
|
|
css::uno::Reference< css::deployment::XPackage > const & thePackage,
|
|
|
|
css::uno::Reference< css::deployment::XPackageManager > const &
|
|
|
|
thePackageManager,
|
|
|
|
rtl::OUString const & theVersion):
|
|
|
|
package(thePackage),
|
|
|
|
packageManager(thePackageManager),
|
|
|
|
version(theVersion)
|
|
|
|
{}
|
|
|
|
|
|
|
|
UpdateDialog::Thread::~Thread() {}
|
|
|
|
|
|
|
|
void UpdateDialog::Thread::execute() {
|
|
|
|
OSL_ASSERT(m_selectedPackages.is() != (m_packageManagers.getLength() != 0));
|
|
|
|
Map map;
|
|
|
|
if (m_selectedPackages.is()) {
|
|
|
|
for (;;) {
|
|
|
|
css::uno::Reference< css::deployment::XPackage > p;
|
|
|
|
css::uno::Reference< css::deployment::XPackageManager > m;
|
|
|
|
{
|
|
|
|
vos::OGuard g(Application::GetSolarMutex());
|
|
|
|
if (m_stop) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
m_selectedPackages->next(&p, &m);
|
|
|
|
}
|
|
|
|
if (!p.is()) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
handle(p, m, &map);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (sal_Int32 i = 0; i < m_packageManagers.getLength(); ++i) {
|
|
|
|
css::uno::Reference< css::task::XAbortChannel > abort(
|
|
|
|
m_packageManagers[i]->createAbortChannel());
|
|
|
|
{
|
|
|
|
vos::OGuard g(Application::GetSolarMutex());
|
|
|
|
if (m_stop) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
m_abort = abort;
|
|
|
|
}
|
|
|
|
css::uno::Sequence<
|
|
|
|
css::uno::Reference< css::deployment::XPackage > > ps;
|
|
|
|
try {
|
|
|
|
ps = m_packageManagers[i]->getDeployedPackages(
|
|
|
|
abort,
|
|
|
|
css::uno::Reference< css::ucb::XCommandEnvironment >());
|
|
|
|
} catch (css::deployment::DeploymentException & e) {
|
|
|
|
handleGeneralError(e.Cause);
|
|
|
|
continue;
|
|
|
|
} catch (css::ucb::CommandFailedException & e) {
|
|
|
|
handleGeneralError(e.Reason);
|
|
|
|
continue;
|
|
|
|
} catch (css::ucb::CommandAbortedException &) {
|
|
|
|
return;
|
|
|
|
} catch (css::lang::IllegalArgumentException & e) {
|
|
|
|
throw css::uno::RuntimeException(e.Message, e.Context);
|
|
|
|
}
|
|
|
|
for (sal_Int32 j = 0; j < ps.getLength(); ++j) {
|
|
|
|
{
|
|
|
|
vos::OGuard g(Application::GetSolarMutex());
|
|
|
|
if (m_stop) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
handle(ps[j], m_packageManagers[i], &map);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!map.empty()) {
|
2007-07-26 07:54:10 +00:00
|
|
|
const rtl::OUString sDefaultURL(dp_misc::getExtensionDefaultUpdateURL());
|
|
|
|
if (sDefaultURL.getLength())
|
|
|
|
{
|
|
|
|
css::uno::Sequence< css::uno::Reference< css::xml::dom::XElement > >
|
|
|
|
infos(
|
|
|
|
getUpdateInformation(
|
|
|
|
css::uno::Reference< css::deployment::XPackage >(),
|
|
|
|
css::uno::Sequence< rtl::OUString >(&sDefaultURL, 1), rtl::OUString()));
|
|
|
|
for (sal_Int32 i = 0; i < infos.getLength(); ++i) {
|
|
|
|
css::uno::Reference< css::xml::dom::XNode > node(
|
|
|
|
infos[i], css::uno::UNO_QUERY_THROW);
|
|
|
|
dp_misc::DescriptionInfoset infoset(m_context, node);
|
|
|
|
boost::optional< rtl::OUString > id(infoset.getIdentifier());
|
|
|
|
if (!id) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
Map::iterator end(map.upper_bound(*id));
|
|
|
|
for (Map::iterator j(map.lower_bound(*id)); j != end; ++j) {
|
|
|
|
rtl::OUString v(infoset.getVersion());
|
|
|
|
if (dp_misc::compareVersions(v, j->second.version) ==
|
|
|
|
dp_misc::GREATER)
|
|
|
|
{
|
|
|
|
j->second.version = v;
|
|
|
|
j->second.info = node;
|
|
|
|
}
|
|
|
|
}
|
2006-12-20 13:24:40 +00:00
|
|
|
}
|
2007-07-26 07:54:10 +00:00
|
|
|
for (Map::const_iterator i(map.begin()); i != map.end(); ++i) {
|
|
|
|
if (i->second.info.is() &&
|
|
|
|
!update(
|
|
|
|
i->second.package, i->second.packageManager,
|
|
|
|
i->second.info))
|
2006-12-20 13:24:40 +00:00
|
|
|
{
|
2007-07-26 07:54:10 +00:00
|
|
|
break;
|
2006-12-20 13:24:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
vos::OGuard g(Application::GetSolarMutex());
|
|
|
|
if (!m_stop) {
|
|
|
|
m_dialog.checkingDone();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void UpdateDialog::Thread::handleGeneralError(css::uno::Any const & exception)
|
|
|
|
const
|
|
|
|
{
|
|
|
|
rtl::OUString message;
|
|
|
|
css::uno::Exception e;
|
|
|
|
if (exception >>= e) {
|
|
|
|
message = e.Message;
|
|
|
|
}
|
|
|
|
vos::OGuard g(Application::GetSolarMutex());
|
|
|
|
if (!m_stop) {
|
|
|
|
m_dialog.addGeneralError(message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-01-29 14:24:20 +00:00
|
|
|
//Parameter package can be null
|
2006-12-20 13:24:40 +00:00
|
|
|
void UpdateDialog::Thread::handleSpecificError(
|
|
|
|
css::uno::Reference< css::deployment::XPackage > const & package,
|
|
|
|
css::uno::Any const & exception) const
|
|
|
|
{
|
|
|
|
UpdateDialog::SpecificError data;
|
2007-01-29 14:24:20 +00:00
|
|
|
if (package.is())
|
|
|
|
data.name = package->getDisplayName();
|
2006-12-20 13:24:40 +00:00
|
|
|
css::uno::Exception e;
|
|
|
|
if (exception >>= e) {
|
|
|
|
data.message = e.Message;
|
|
|
|
}
|
|
|
|
vos::OGuard g(Application::GetSolarMutex());
|
|
|
|
if (!m_stop) {
|
|
|
|
m_dialog.addSpecificError(data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
css::uno::Sequence< css::uno::Reference< css::xml::dom::XElement > >
|
|
|
|
UpdateDialog::Thread::getUpdateInformation(
|
|
|
|
css::uno::Reference< css::deployment::XPackage > const & package,
|
|
|
|
css::uno::Sequence< rtl::OUString > const & urls,
|
|
|
|
rtl::OUString const & identifier) const
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
return m_updateInformation->getUpdateInformation(urls, identifier);
|
|
|
|
} catch (css::uno::RuntimeException &) {
|
|
|
|
throw;
|
|
|
|
} catch (css::ucb::CommandFailedException & e) {
|
|
|
|
handleSpecificError(package, e.Reason);
|
|
|
|
} catch (css::ucb::CommandAbortedException &) {
|
|
|
|
} catch (css::uno::Exception & e) {
|
|
|
|
handleSpecificError(package, css::uno::makeAny(e));
|
|
|
|
}
|
|
|
|
return
|
|
|
|
css::uno::Sequence< css::uno::Reference< css::xml::dom::XElement > >();
|
|
|
|
}
|
|
|
|
|
|
|
|
void UpdateDialog::Thread::handle(
|
|
|
|
css::uno::Reference< css::deployment::XPackage > const & package,
|
|
|
|
css::uno::Reference< css::deployment::XPackageManager > const &
|
|
|
|
packageManager,
|
2007-07-06 11:35:27 +00:00
|
|
|
Map * map)
|
2006-12-20 13:24:40 +00:00
|
|
|
{
|
2007-01-18 13:53:29 +00:00
|
|
|
rtl::OUString id(dp_misc::getIdentifier(package));
|
2006-12-20 13:24:40 +00:00
|
|
|
css::uno::Sequence< rtl::OUString > urls(
|
|
|
|
package->getUpdateInformationURLs());
|
|
|
|
if (urls.getLength() == 0) {
|
|
|
|
map->insert(
|
2007-03-14 07:32:22 +00:00
|
|
|
Map::value_type(
|
2006-12-20 13:24:40 +00:00
|
|
|
id, Entry(package, packageManager, package->getVersion())));
|
|
|
|
} else {
|
|
|
|
css::uno::Sequence< css::uno::Reference< css::xml::dom::XElement > >
|
|
|
|
infos(getUpdateInformation(package, urls, id));
|
2007-07-06 11:35:27 +00:00
|
|
|
//If there is an update for a shared extension and this user has writer
|
|
|
|
//access tho office/shared then we need to warn the user.
|
|
|
|
if ( ! m_infoSharedDone && infos.getLength() > 0
|
|
|
|
&& packageManager->getContext().equals(OUSTR("shared"))
|
|
|
|
&& ! packageManager->isReadOnly())
|
|
|
|
{
|
|
|
|
vos::OGuard guard(Application::GetSolarMutex());
|
|
|
|
InfoBox box(&m_dialog, ResId(RID_INFOBOX_UPDATE_SHARED_EXTENSION,
|
|
|
|
*DeploymentGuiResMgr::get()));
|
|
|
|
String msgText = box.GetMessText();
|
|
|
|
msgText.SearchAndReplaceAllAscii( "%PRODUCTNAME", BrandName::get() );
|
|
|
|
box.Execute();
|
|
|
|
m_infoSharedDone = true;
|
|
|
|
}
|
2006-12-20 13:24:40 +00:00
|
|
|
rtl::OUString latestVersion(package->getVersion());
|
|
|
|
sal_Int32 latestIndex = -1;
|
|
|
|
for (sal_Int32 i = 0; i < infos.getLength(); ++i) {
|
|
|
|
dp_misc::DescriptionInfoset infoset(
|
|
|
|
m_context,
|
|
|
|
css::uno::Reference< css::xml::dom::XNode >(
|
|
|
|
infos[i], css::uno::UNO_QUERY_THROW));
|
|
|
|
boost::optional< rtl::OUString > id2(infoset.getIdentifier());
|
|
|
|
if (!id2) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (*id2 == id) {
|
|
|
|
rtl::OUString v(infoset.getVersion());
|
|
|
|
if (dp_misc::compareVersions(v, latestVersion) ==
|
|
|
|
dp_misc::GREATER)
|
|
|
|
{
|
|
|
|
latestVersion = v;
|
|
|
|
latestIndex = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (latestIndex != -1) {
|
|
|
|
update(
|
|
|
|
package, packageManager,
|
|
|
|
css::uno::Reference< css::xml::dom::XNode >(
|
|
|
|
infos[latestIndex], css::uno::UNO_QUERY_THROW));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UpdateDialog::Thread::update(
|
|
|
|
css::uno::Reference< css::deployment::XPackage > const & package,
|
|
|
|
css::uno::Reference< css::deployment::XPackageManager > const &
|
|
|
|
packageManager,
|
|
|
|
css::uno::Reference< css::xml::dom::XNode > const & updateInfo) const
|
|
|
|
{
|
|
|
|
dp_misc::DescriptionInfoset infoset(m_context, updateInfo);
|
|
|
|
OSL_ASSERT(infoset.getVersion().getLength() != 0);
|
|
|
|
rtl::OUStringBuffer b(package->getDisplayName());
|
|
|
|
b.append(static_cast< sal_Unicode >(' '));
|
|
|
|
b.append(infoset.getVersion());
|
|
|
|
UpdateDialog::DisabledUpdate du;
|
|
|
|
du.name = b.makeStringAndClear();
|
|
|
|
css::uno::Sequence< css::uno::Reference< css::xml::dom::XElement > > ds(
|
|
|
|
dp_misc::Dependencies::check(infoset));
|
|
|
|
du.unsatisfiedDependencies.realloc(ds.getLength());
|
|
|
|
for (sal_Int32 i = 0; i < ds.getLength(); ++i) {
|
|
|
|
du.unsatisfiedDependencies[i] = dp_misc::Dependencies::name(ds[i]);
|
|
|
|
}
|
2007-07-06 11:35:27 +00:00
|
|
|
du.permission = ! packageManager->isReadOnly();
|
2006-12-20 13:24:40 +00:00
|
|
|
du.updateWebsiteUrl = infoset.getUpdateWebsiteUrl();
|
|
|
|
if (du.unsatisfiedDependencies.getLength() == 0 && du.permission &&
|
|
|
|
!du.updateWebsiteUrl)
|
|
|
|
{
|
|
|
|
dp_gui::UpdateData data;
|
|
|
|
data.aInstalledPackage = package;
|
|
|
|
data.aPackageManager = packageManager;
|
|
|
|
data.aUpdateInfo = updateInfo;
|
|
|
|
vos::OGuard g(Application::GetSolarMutex());
|
|
|
|
if (!m_stop) {
|
|
|
|
m_dialog.addEnabledUpdate(du.name, data);
|
|
|
|
}
|
|
|
|
return !m_stop;
|
|
|
|
} else {
|
|
|
|
vos::OGuard g(Application::GetSolarMutex());
|
|
|
|
if (!m_stop) {
|
|
|
|
m_dialog.addDisabledUpdate(du);
|
|
|
|
}
|
|
|
|
return !m_stop;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
UpdateDialog::UpdateDialog(
|
|
|
|
css::uno::Reference< css::uno::XComponentContext > const & context,
|
|
|
|
Window * parent,
|
|
|
|
rtl::Reference< dp_gui::SelectedPackageIterator > const & selectedPackages,
|
|
|
|
css::uno::Sequence< css::uno::Reference<
|
|
|
|
css::deployment::XPackageManager > > const & packageManagers,
|
|
|
|
std::vector< dp_gui::UpdateData > * updateData):
|
2007-04-26 07:23:53 +00:00
|
|
|
ModalDialog(parent,DpGuiResId(RID_DLG_UPDATE)),
|
2006-12-20 13:24:40 +00:00
|
|
|
m_context(context),
|
2007-04-26 07:23:53 +00:00
|
|
|
m_checking(this, DpGuiResId(RID_DLG_UPDATE_CHECKING)),
|
|
|
|
m_update(this, DpGuiResId(RID_DLG_UPDATE_UPDATE)),
|
2006-12-20 13:24:40 +00:00
|
|
|
m_updates(
|
2007-04-26 07:23:53 +00:00
|
|
|
*this, DpGuiResId(RID_DLG_UPDATE_UPDATES),
|
|
|
|
Image(DpGuiResId(RID_DLG_UPDATE_NORMALALERT)),
|
|
|
|
Image(DpGuiResId(RID_DLG_UPDATE_HIGHCONTRASTALERT))),
|
|
|
|
m_all(this, DpGuiResId(RID_DLG_UPDATE_ALL)),
|
|
|
|
m_description(this, DpGuiResId(RID_DLG_UPDATE_DESCRIPTION)),
|
|
|
|
m_descriptions(this, DpGuiResId(RID_DLG_UPDATE_DESCRIPTIONS)),
|
|
|
|
m_line(this, DpGuiResId(RID_DLG_UPDATE_LINE)),
|
|
|
|
m_help(this, DpGuiResId(RID_DLG_UPDATE_HELP)),
|
|
|
|
m_ok(this, DpGuiResId(RID_DLG_UPDATE_OK)),
|
|
|
|
m_cancel(this, DpGuiResId(RID_DLG_UPDATE_CANCEL)),
|
|
|
|
m_error(String(DpGuiResId(RID_DLG_UPDATE_ERROR))),
|
|
|
|
m_none(String(DpGuiResId(RID_DLG_UPDATE_NONE))),
|
|
|
|
m_noInstallable(String(DpGuiResId(RID_DLG_UPDATE_NOINSTALLABLE))),
|
|
|
|
m_failure(String(DpGuiResId(RID_DLG_UPDATE_FAILURE))),
|
|
|
|
m_unknownError(String(DpGuiResId(RID_DLG_UPDATE_UNKNOWNERROR))),
|
|
|
|
m_noDescription(String(DpGuiResId(RID_DLG_UPDATE_NODESCRIPTION))),
|
|
|
|
m_noInstall(String(DpGuiResId(RID_DLG_UPDATE_NOINSTALL))),
|
|
|
|
m_noDependency(String(DpGuiResId(RID_DLG_UPDATE_NODEPENDENCY))),
|
|
|
|
m_noPermission(String(DpGuiResId(RID_DLG_UPDATE_NOPERMISSION))),
|
2007-07-06 11:35:27 +00:00
|
|
|
m_noPermissionVista(String(DpGuiResId(RID_DLG_UPDATE_NOPERMISSION_VISTA))),
|
2007-04-26 07:23:53 +00:00
|
|
|
m_noUpdate(String(DpGuiResId(RID_DLG_UPDATE_NOUPDATE))),
|
2006-12-20 13:24:40 +00:00
|
|
|
m_updateData(*updateData),
|
|
|
|
m_thread(
|
|
|
|
new UpdateDialog::Thread(
|
2007-07-06 11:35:27 +00:00
|
|
|
context, *this, selectedPackages,
|
2006-12-20 13:24:40 +00:00
|
|
|
packageManagers))
|
|
|
|
{
|
|
|
|
OSL_ASSERT(updateData != NULL);
|
|
|
|
css::uno::Reference< css::awt::XToolkit > toolkit;
|
|
|
|
try {
|
|
|
|
toolkit = css::uno::Reference< css::awt::XToolkit >(
|
|
|
|
(css::uno::Reference< css::lang::XMultiComponentFactory >(
|
|
|
|
m_context->getServiceManager(),
|
|
|
|
css::uno::UNO_QUERY_THROW)->
|
|
|
|
createInstanceWithContext(
|
|
|
|
rtl::OUString(
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.Toolkit")),
|
|
|
|
m_context)),
|
|
|
|
css::uno::UNO_QUERY_THROW);
|
|
|
|
} catch (css::uno::RuntimeException &) {
|
|
|
|
throw;
|
|
|
|
} catch (css::uno::Exception & e) {
|
|
|
|
throw css::uno::RuntimeException(e.Message, e.Context);
|
|
|
|
}
|
2007-04-26 07:23:53 +00:00
|
|
|
Control c(this, DpGuiResId(RID_DLG_UPDATE_THROBBER));
|
2006-12-20 13:24:40 +00:00
|
|
|
Point pos(c.GetPosPixel());
|
|
|
|
Size size(c.GetSizePixel());
|
|
|
|
try {
|
|
|
|
m_throbber = css::uno::Reference< css::awt::XThrobber >(
|
|
|
|
toolkit->createWindow(
|
|
|
|
css::awt::WindowDescriptor(
|
|
|
|
css::awt::WindowClass_SIMPLE,
|
|
|
|
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Throbber")),
|
|
|
|
GetComponentInterface(), 0,
|
|
|
|
css::awt::Rectangle(
|
|
|
|
pos.X(), pos.Y(), size.Width(), size.Height()),
|
|
|
|
css::awt::WindowAttribute::SHOW)),
|
|
|
|
css::uno::UNO_QUERY_THROW);
|
|
|
|
} catch (css::lang::IllegalArgumentException & e) {
|
|
|
|
throw css::uno::RuntimeException(e.Message, e.Context);
|
|
|
|
}
|
|
|
|
m_updates.SetSelectHdl(LINK(this, UpdateDialog, selectionHandler));
|
|
|
|
m_all.SetToggleHdl(LINK(this, UpdateDialog, allHandler));
|
|
|
|
m_ok.SetClickHdl(LINK(this, UpdateDialog, okHandler));
|
|
|
|
m_cancel.SetClickHdl(LINK(this, UpdateDialog, cancelHandler));
|
|
|
|
if ( ! dp_misc::office_is_running())
|
|
|
|
m_help.Disable();
|
|
|
|
FreeResource();
|
2007-07-06 11:35:27 +00:00
|
|
|
|
|
|
|
String sTemp(m_noPermissionVista);
|
|
|
|
sTemp.SearchAndReplaceAllAscii( "%PRODUCTNAME", BrandName::get() );
|
|
|
|
m_noPermissionVista = sTemp;
|
2006-12-20 13:24:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
UpdateDialog::~UpdateDialog() {
|
|
|
|
for (USHORT i = 0; i < m_updates.getItemCount(); ++i) {
|
|
|
|
delete static_cast< UpdateDialog::Index const * >(
|
|
|
|
m_updates.GetEntryData(i));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL UpdateDialog::Close() {
|
|
|
|
m_thread->stop();
|
|
|
|
return ModalDialog::Close();
|
|
|
|
}
|
|
|
|
|
|
|
|
short UpdateDialog::Execute() {
|
|
|
|
m_throbber->start();
|
|
|
|
m_thread->launch();
|
|
|
|
return ModalDialog::Execute();
|
|
|
|
}
|
|
|
|
|
|
|
|
UpdateDialog::CheckListBox::CheckListBox(
|
|
|
|
UpdateDialog & dialog, ResId const & resource,
|
|
|
|
Image const & normalStaticImage, Image const & highContrastStaticImage):
|
|
|
|
SvxCheckListBox(
|
|
|
|
&dialog, resource, normalStaticImage, highContrastStaticImage),
|
|
|
|
m_dialog(dialog)
|
|
|
|
{}
|
|
|
|
|
|
|
|
UpdateDialog::CheckListBox::~CheckListBox() {}
|
|
|
|
|
|
|
|
USHORT UpdateDialog::CheckListBox::getItemCount() const {
|
|
|
|
ULONG i = GetEntryCount();
|
|
|
|
OSL_ASSERT(i <= std::numeric_limits< USHORT >::max());
|
|
|
|
return sal::static_int_cast< USHORT >(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
void UpdateDialog::CheckListBox::MouseButtonDown(MouseEvent const & event) {
|
|
|
|
// When clicking on a selected entry in an SvxCheckListBox, the entry's
|
|
|
|
// checkbox is toggled on mouse button down:
|
|
|
|
SvxCheckListBox::MouseButtonDown(event);
|
|
|
|
m_dialog.enableOk();
|
|
|
|
}
|
|
|
|
|
|
|
|
void UpdateDialog::CheckListBox::MouseButtonUp(MouseEvent const & event) {
|
|
|
|
// When clicking on an entry's checkbox in an SvxCheckListBox, the entry's
|
|
|
|
// checkbox is toggled on mouse button up:
|
|
|
|
SvxCheckListBox::MouseButtonUp(event);
|
|
|
|
m_dialog.enableOk();
|
|
|
|
}
|
|
|
|
|
|
|
|
void UpdateDialog::CheckListBox::KeyInput(KeyEvent const & event) {
|
|
|
|
SvxCheckListBox::KeyInput(event);
|
|
|
|
m_dialog.enableOk();
|
|
|
|
}
|
|
|
|
|
|
|
|
void UpdateDialog::insertItem(
|
|
|
|
rtl::OUString const & name, USHORT position,
|
|
|
|
std::auto_ptr< UpdateDialog::Index const > index, SvLBoxButtonKind kind)
|
|
|
|
{
|
|
|
|
m_updates.InsertEntry(
|
|
|
|
name, position,
|
|
|
|
const_cast< void * >(static_cast< void const * >(index.release())),
|
|
|
|
kind);
|
|
|
|
//TODO #i72487#: UpdateDialog::Index potentially leaks as the exception
|
|
|
|
// behavior of SvxCheckListBox::InsertEntry is unspecified
|
|
|
|
}
|
|
|
|
|
|
|
|
void UpdateDialog::addAdditional(
|
|
|
|
rtl::OUString const & name, USHORT position,
|
|
|
|
std::auto_ptr< UpdateDialog::Index const > index, SvLBoxButtonKind kind)
|
|
|
|
{
|
|
|
|
m_all.Enable();
|
|
|
|
if (m_all.IsChecked()) {
|
|
|
|
insertItem(name, position, index, kind);
|
|
|
|
m_update.Enable();
|
|
|
|
m_updates.Enable();
|
|
|
|
m_description.Enable();
|
|
|
|
m_descriptions.Enable();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void UpdateDialog::addEnabledUpdate(
|
|
|
|
rtl::OUString const & name, dp_gui::UpdateData const & data)
|
|
|
|
{
|
|
|
|
std::vector< dp_gui::UpdateData >::size_type n = m_enabledUpdates.size();
|
|
|
|
m_enabledUpdates.push_back(data);
|
|
|
|
insertItem(
|
|
|
|
name, sal::static_int_cast< USHORT >(n),
|
|
|
|
UpdateDialog::Index::newEnabledUpdate(n),
|
|
|
|
SvLBoxButtonKind_enabledCheckbox);
|
|
|
|
// position overflow is rather harmless
|
|
|
|
m_updates.CheckEntryPos(sal::static_int_cast< USHORT >(n));
|
|
|
|
//TODO #i72487#: fragile computation; insertItem should instead return
|
|
|
|
// pos
|
|
|
|
m_update.Enable();
|
|
|
|
m_updates.Enable();
|
|
|
|
m_description.Enable();
|
|
|
|
m_descriptions.Enable();
|
|
|
|
}
|
|
|
|
|
|
|
|
void UpdateDialog::addDisabledUpdate(UpdateDialog::DisabledUpdate const & data)
|
|
|
|
{
|
|
|
|
std::vector< UpdateDialog::DisabledUpdate >::size_type n =
|
|
|
|
m_disabledUpdates.size();
|
|
|
|
m_disabledUpdates.push_back(data);
|
|
|
|
addAdditional(
|
|
|
|
data.name, sal::static_int_cast< USHORT >(m_enabledUpdates.size() + n),
|
|
|
|
UpdateDialog::Index::newDisabledUpdate(n),
|
|
|
|
SvLBoxButtonKind_disabledCheckbox);
|
|
|
|
// position overflow is rather harmless
|
|
|
|
}
|
|
|
|
|
|
|
|
void UpdateDialog::addGeneralError(rtl::OUString const & message) {
|
|
|
|
std::vector< rtl::OUString >::size_type n = m_generalErrors.size();
|
|
|
|
m_generalErrors.push_back(message);
|
|
|
|
addAdditional(
|
|
|
|
m_error,
|
|
|
|
sal::static_int_cast< USHORT >(
|
|
|
|
m_enabledUpdates.size() + m_disabledUpdates.size() + n),
|
|
|
|
UpdateDialog::Index::newGeneralError(n), SvLBoxButtonKind_staticImage);
|
|
|
|
// position overflow is rather harmless
|
|
|
|
}
|
|
|
|
|
|
|
|
void UpdateDialog::addSpecificError(UpdateDialog::SpecificError const & data) {
|
|
|
|
std::vector< UpdateDialog::SpecificError >::size_type n =
|
|
|
|
m_specificErrors.size();
|
|
|
|
m_specificErrors.push_back(data);
|
|
|
|
addAdditional(
|
|
|
|
data.name, LISTBOX_APPEND, UpdateDialog::Index::newSpecificError(n),
|
|
|
|
SvLBoxButtonKind_staticImage);
|
|
|
|
}
|
|
|
|
|
|
|
|
void UpdateDialog::checkingDone() {
|
|
|
|
m_checking.Hide();
|
|
|
|
m_throbber->stop();
|
|
|
|
css::uno::Reference< css::awt::XWindow >(
|
|
|
|
m_throbber, css::uno::UNO_QUERY_THROW)->setVisible(false);
|
|
|
|
if (m_updates.getItemCount() == 0) {
|
|
|
|
m_description.Enable();
|
|
|
|
m_descriptions.Enable();
|
|
|
|
m_descriptions.SetText(
|
|
|
|
(m_disabledUpdates.empty() && m_generalErrors.empty() &&
|
|
|
|
m_specificErrors.empty())
|
|
|
|
? m_none : m_noInstallable);
|
|
|
|
}
|
|
|
|
enableOk();
|
|
|
|
}
|
|
|
|
|
|
|
|
void UpdateDialog::enableOk() {
|
|
|
|
if (!m_checking.IsVisible()) {
|
|
|
|
m_ok.Enable(m_updates.GetCheckedEntryCount() != 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
IMPL_LINK(UpdateDialog, selectionHandler, void *, EMPTYARG) {
|
|
|
|
rtl::OUStringBuffer b;
|
|
|
|
UpdateDialog::Index const * p = static_cast< UpdateDialog::Index const * >(
|
|
|
|
m_updates.GetEntryData(m_updates.GetSelectEntryPos()));
|
|
|
|
if (p != NULL) {
|
|
|
|
switch (p->kind) {
|
|
|
|
case ENABLED_UPDATE:
|
|
|
|
b.append(m_noDescription);
|
|
|
|
break;
|
|
|
|
case DISABLED_UPDATE:
|
|
|
|
{
|
|
|
|
UpdateDialog::DisabledUpdate & data = m_disabledUpdates[
|
|
|
|
p->index.disabledUpdate];
|
|
|
|
if (data.unsatisfiedDependencies.getLength() != 0) {
|
|
|
|
b.append(m_noInstall);
|
|
|
|
b.append(LF);
|
|
|
|
b.append(m_noDependency);
|
|
|
|
for (sal_Int32 i = 0;
|
|
|
|
i < data.unsatisfiedDependencies.getLength(); ++i)
|
|
|
|
{
|
|
|
|
b.append(LF);
|
|
|
|
b.appendAscii(RTL_CONSTASCII_STRINGPARAM(" "));
|
|
|
|
// U+2003 EM SPACE would be better than two spaces,
|
|
|
|
// but some fonts do not contain it
|
|
|
|
b.append(
|
|
|
|
confineToParagraph(
|
|
|
|
data.unsatisfiedDependencies[i]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!data.permission) {
|
|
|
|
if (b.getLength() == 0) {
|
|
|
|
b.append(m_noInstall);
|
|
|
|
}
|
|
|
|
b.append(LF);
|
2007-07-06 11:35:27 +00:00
|
|
|
if (isVista())
|
|
|
|
b.append(m_noPermissionVista);
|
|
|
|
else
|
|
|
|
b.append(m_noPermission);
|
2006-12-20 13:24:40 +00:00
|
|
|
}
|
|
|
|
if (data.updateWebsiteUrl) {
|
|
|
|
if (b.getLength() == 0) {
|
|
|
|
b.append(m_noInstall);
|
|
|
|
}
|
|
|
|
b.append(LF);
|
|
|
|
static char const url[] = "%URL";
|
|
|
|
sal_Int32 i = m_noUpdate.indexOf(
|
|
|
|
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(url)));
|
|
|
|
b.append(
|
|
|
|
i < 0
|
|
|
|
? m_noUpdate
|
|
|
|
: m_noUpdate.replaceAt(
|
|
|
|
i, RTL_CONSTASCII_LENGTH(url),
|
|
|
|
confineToParagraph(*data.updateWebsiteUrl)));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case GENERAL_ERROR:
|
|
|
|
{
|
|
|
|
rtl::OUString & msg = m_generalErrors[p->index.generalError];
|
|
|
|
b.append(m_failure);
|
|
|
|
b.append(LF);
|
|
|
|
b.append(msg.getLength() == 0 ? m_unknownError : msg);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case SPECIFIC_ERROR:
|
|
|
|
{
|
|
|
|
UpdateDialog::SpecificError & data = m_specificErrors[
|
|
|
|
p->index.specificError];
|
|
|
|
b.append(m_failure);
|
|
|
|
b.append(LF);
|
|
|
|
b.append(
|
|
|
|
data.message.getLength() == 0
|
|
|
|
? m_unknownError : data.message);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
OSL_ASSERT(false);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m_descriptions.SetText(b.makeStringAndClear());
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
IMPL_LINK(UpdateDialog, allHandler, void *, EMPTYARG) {
|
|
|
|
if (m_all.IsChecked()) {
|
|
|
|
m_update.Enable();
|
|
|
|
m_updates.Enable();
|
|
|
|
m_description.Enable();
|
|
|
|
m_descriptions.Enable();
|
|
|
|
std::vector< UpdateDialog::DisabledUpdate >::size_type n1 = 0;
|
|
|
|
for (std::vector< UpdateDialog::DisabledUpdate >::iterator i(
|
|
|
|
m_disabledUpdates.begin());
|
|
|
|
i != m_disabledUpdates.end(); ++i)
|
|
|
|
{
|
|
|
|
insertItem(
|
|
|
|
i->name, LISTBOX_APPEND,
|
|
|
|
UpdateDialog::Index::newDisabledUpdate(n1++),
|
|
|
|
SvLBoxButtonKind_disabledCheckbox);
|
|
|
|
}
|
|
|
|
std::vector< rtl::OUString >::size_type n2 = 0;
|
|
|
|
for (std::vector< rtl::OUString >::iterator i(m_generalErrors.begin());
|
|
|
|
i != m_generalErrors.end(); ++i)
|
|
|
|
{
|
|
|
|
insertItem(
|
|
|
|
m_error, LISTBOX_APPEND,
|
|
|
|
UpdateDialog::Index::newGeneralError(n2++),
|
|
|
|
SvLBoxButtonKind_staticImage);
|
|
|
|
}
|
|
|
|
std::vector< UpdateDialog::SpecificError >::size_type n3 = 0;
|
|
|
|
for (std::vector< UpdateDialog::SpecificError >::iterator i(
|
|
|
|
m_specificErrors.begin());
|
|
|
|
i != m_specificErrors.end(); ++i)
|
|
|
|
{
|
|
|
|
insertItem(
|
|
|
|
i->name, LISTBOX_APPEND,
|
|
|
|
UpdateDialog::Index::newSpecificError(n3++),
|
|
|
|
SvLBoxButtonKind_staticImage);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (USHORT i = 0; i < m_updates.getItemCount();) {
|
|
|
|
UpdateDialog::Index const * p =
|
|
|
|
static_cast< UpdateDialog::Index const * >(
|
|
|
|
m_updates.GetEntryData(i));
|
|
|
|
if (p->kind != ENABLED_UPDATE) {
|
|
|
|
m_updates.RemoveEntry(i);
|
|
|
|
//TODO #i72487#: UpdateDialog::Index potentially leaks as
|
|
|
|
// SvxCheckListBox::RemoveEntry's exception behavior is
|
|
|
|
// unspecified
|
|
|
|
delete p;
|
|
|
|
} else {
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (m_updates.getItemCount() == 0) {
|
|
|
|
m_update.Disable();
|
|
|
|
m_updates.Disable();
|
|
|
|
if (m_checking.IsVisible()) {
|
|
|
|
m_description.Disable();
|
|
|
|
m_descriptions.Disable();
|
|
|
|
m_descriptions.SetText(String());
|
|
|
|
} else {
|
|
|
|
m_descriptions.SetText(m_noInstallable);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
IMPL_LINK(UpdateDialog, okHandler, void *, EMPTYARG) {
|
|
|
|
for (USHORT i = 0; i < m_updates.getItemCount(); ++i) {
|
|
|
|
UpdateDialog::Index const * p =
|
|
|
|
static_cast< UpdateDialog::Index const * >(
|
|
|
|
m_updates.GetEntryData(i));
|
|
|
|
if (p->kind == ENABLED_UPDATE && m_updates.IsChecked(i)) {
|
|
|
|
m_updateData.push_back(m_enabledUpdates[p->index.enabledUpdate]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
EndDialog(RET_OK);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
IMPL_LINK(UpdateDialog, cancelHandler, void *, EMPTYARG) {
|
|
|
|
m_thread->stop();
|
|
|
|
EndDialog(RET_CANCEL);
|
|
|
|
return 0;
|
|
|
|
}
|