1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_desktop.hxx"
31 #include "sal/config.h"
41 #include "boost/optional.hpp"
42 #include "com/sun/star/awt/Rectangle.hpp"
43 #include "com/sun/star/awt/WindowAttribute.hpp"
44 #include "com/sun/star/awt/WindowClass.hpp"
45 #include "com/sun/star/awt/WindowDescriptor.hpp"
46 #include "com/sun/star/awt/XThrobber.hpp"
47 #include "com/sun/star/awt/XToolkit.hpp"
48 #include "com/sun/star/awt/XWindow.hpp"
49 #include "com/sun/star/awt/XWindowPeer.hpp"
50 #include "com/sun/star/beans/NamedValue.hpp"
51 #include "com/sun/star/beans/Optional.hpp"
52 #include "com/sun/star/beans/PropertyValue.hpp"
53 #include "com/sun/star/container/XNameAccess.hpp"
54 #include "com/sun/star/deployment/DeploymentException.hpp"
55 #include "com/sun/star/deployment/UpdateInformationProvider.hpp"
56 #include "com/sun/star/deployment/XPackage.hpp"
57 #include "com/sun/star/deployment/XPackageManager.hpp"
58 #include "com/sun/star/deployment/XUpdateInformationProvider.hpp"
59 #include "com/sun/star/frame/XDesktop.hpp"
60 #include "com/sun/star/frame/XDispatch.hpp"
61 #include "com/sun/star/frame/XDispatchProvider.hpp"
62 #include "com/sun/star/lang/IllegalArgumentException.hpp"
63 #include "com/sun/star/lang/XMultiComponentFactory.hpp"
64 #include "com/sun/star/system/SystemShellExecuteFlags.hpp"
65 #include "com/sun/star/system/XSystemShellExecute.hpp"
66 #include "com/sun/star/task/XAbortChannel.hpp"
67 #include "com/sun/star/task/XJob.hpp"
68 #include "com/sun/star/ucb/CommandAbortedException.hpp"
69 #include "com/sun/star/ucb/CommandFailedException.hpp"
70 #include "com/sun/star/ucb/XCommandEnvironment.hpp"
71 #include "com/sun/star/uno/Any.hxx"
72 #include "com/sun/star/uno/Exception.hpp"
73 #include "com/sun/star/uno/Reference.hxx"
74 #include "com/sun/star/uno/RuntimeException.hpp"
75 #include "com/sun/star/uno/Sequence.hxx"
76 #include "com/sun/star/uno/XInterface.hpp"
77 #include "com/sun/star/util/URL.hpp"
78 #include "com/sun/star/util/XURLTransformer.hpp"
79 #include "com/sun/star/xml/dom/XElement.hpp"
80 #include "com/sun/star/xml/dom/XNode.hpp"
81 #include "osl/diagnose.h"
82 #include "rtl/bootstrap.hxx"
83 #include "rtl/ref.hxx"
84 #include "rtl/string.h"
85 #include "rtl/ustrbuf.hxx"
86 #include "rtl/ustring.h"
87 #include "rtl/ustring.hxx"
88 #include "sal/types.h"
89 #include "svtools/svlbitm.hxx"
90 #include "svtools/svlbox.hxx"
91 #include <svtools/controldims.hrc>
92 #include "svx/checklbx.hxx"
93 #include "tools/gen.hxx"
94 #include "tools/link.hxx"
95 #include "tools/resid.hxx"
96 #include "tools/resmgr.hxx"
97 #include "tools/solar.h"
98 #include "tools/string.hxx"
99 #include "vcl/button.hxx"
100 #include "vcl/dialog.hxx"
101 #include "vcl/fixed.hxx"
102 #include "vcl/image.hxx"
103 #include "vcl/msgbox.hxx"
104 #include "vcl/svapp.hxx"
105 #include "vos/mutex.hxx"
107 #include "comphelper/processfactory.hxx"
109 #include "dp_dependencies.hxx"
110 #include "dp_descriptioninfoset.hxx"
111 #include "dp_identifier.hxx"
112 #include "dp_version.hxx"
116 #include "dp_gui.hrc"
117 #include "dp_gui_thread.hxx"
118 #include "dp_gui_updatedata.hxx"
119 #include "dp_gui_updatedialog.hxx"
120 #include "dp_gui_shared.hxx"
121 #include "dp_gui_system.hxx"
126 namespace com
{ namespace sun
{ namespace star
{ namespace uno
{
127 class XComponentContext
;
130 namespace css
= ::com::sun::star
;
132 using dp_gui::UpdateDialog
;
136 static sal_Unicode
const LF
= 0x000A;
137 static sal_Unicode
const CR
= 0x000D;
139 enum Kind
{ ENABLED_UPDATE
, DISABLED_UPDATE
, GENERAL_ERROR
, SPECIFIC_ERROR
};
141 rtl::OUString
confineToParagraph(rtl::OUString
const & text
) {
142 // Confine arbitrary text to a single paragraph in a dp_gui::AutoScrollEdit.
143 // This assumes that U+000A and U+000D are the only paragraph separators in
144 // a dp_gui::AutoScrollEdit, and that replacing them with a single space
145 // each is acceptable:
146 return text
.replace(LF
, ' ').replace(CR
, ' ');
150 struct UpdateDialog::DisabledUpdate
{
152 css::uno::Sequence
< rtl::OUString
> unsatisfiedDependencies
;
154 // We also want to show release notes and publisher for disabled updates
155 ::com::sun::star::uno::Reference
< ::com::sun::star::xml::dom::XNode
> aUpdateInfo
;
158 struct UpdateDialog::SpecificError
{
160 rtl::OUString message
;
163 union UpdateDialog::IndexUnion
{
164 std::vector
< dp_gui::UpdateData
>::size_type enabledUpdate
;
165 std::vector
< UpdateDialog::DisabledUpdate
>::size_type disabledUpdate
;
166 std::vector
< rtl::OUString
>::size_type generalError
;
167 std::vector
< UpdateDialog::SpecificError
>::size_type specificError
;
170 struct UpdateDialog::Index
{
171 static std::auto_ptr
< UpdateDialog::Index
const > newEnabledUpdate(
172 std::vector
< dp_gui::UpdateData
>::size_type n
);
174 static std::auto_ptr
< UpdateDialog::Index
const > newDisabledUpdate(
175 std::vector
< UpdateDialog::DisabledUpdate
>::size_type n
);
177 static std::auto_ptr
< UpdateDialog::Index
const > newGeneralError(
178 std::vector
< rtl::OUString
>::size_type n
);
180 static std::auto_ptr
< UpdateDialog::Index
const > newSpecificError(
181 std::vector
< UpdateDialog::SpecificError
>::size_type n
);
187 explicit Index(Kind theKind
);
190 std::auto_ptr
< UpdateDialog::Index
const >
191 UpdateDialog::Index::newEnabledUpdate(
192 std::vector
< dp_gui::UpdateData
>::size_type n
)
194 UpdateDialog::Index
* p
= new UpdateDialog::Index(ENABLED_UPDATE
);
195 p
->index
.enabledUpdate
= n
;
196 return std::auto_ptr
< UpdateDialog::Index
const >(p
);
199 std::auto_ptr
< UpdateDialog::Index
const >
200 UpdateDialog::Index::newDisabledUpdate(
201 std::vector
< UpdateDialog::DisabledUpdate
>::size_type n
)
203 UpdateDialog::Index
* p
= new UpdateDialog::Index(DISABLED_UPDATE
);
204 p
->index
.disabledUpdate
= n
;
205 return std::auto_ptr
< UpdateDialog::Index
const >(p
);
208 std::auto_ptr
< UpdateDialog::Index
const > UpdateDialog::Index::newGeneralError(
209 std::vector
< rtl::OUString
>::size_type n
)
211 UpdateDialog::Index
* p
= new UpdateDialog::Index(GENERAL_ERROR
);
212 p
->index
.generalError
= n
;
213 return std::auto_ptr
< UpdateDialog::Index
const >(p
);
216 std::auto_ptr
< UpdateDialog::Index
const >
217 UpdateDialog::Index::newSpecificError(
218 std::vector
< UpdateDialog::SpecificError
>::size_type n
)
220 UpdateDialog::Index
* p
= new UpdateDialog::Index(SPECIFIC_ERROR
);
221 p
->index
.specificError
= n
;
222 return std::auto_ptr
< UpdateDialog::Index
const >(p
);
225 UpdateDialog::Index::Index(Kind theKind
): kind(theKind
) {}
227 class UpdateDialog::Thread
: public dp_gui::Thread
{
230 css::uno::Reference
< css::uno::XComponentContext
> const & context
,
231 UpdateDialog
& dialog
,
232 const std::vector
< TUpdateListEntry
> &vExtensionList
);
237 Thread(UpdateDialog::Thread
&); // not defined
238 void operator =(UpdateDialog::Thread
&); // not defined
242 css::uno::Reference
< css::deployment::XPackage
> const & thePackage
,
243 css::uno::Reference
< css::deployment::XPackageManager
> const &
245 rtl::OUString
const & theVersion
);
247 css::uno::Reference
< css::deployment::XPackage
> package
;
248 css::uno::Reference
< css::deployment::XPackageManager
> packageManager
;
249 rtl::OUString version
;
250 css::uno::Reference
< css::xml::dom::XNode
> info
;
253 // A multimap in case an extension is installed in both "user" and "shared":
254 typedef std::multimap
< rtl::OUString
, Entry
> Map
;
258 virtual void execute();
260 void handleGeneralError(css::uno::Any
const & exception
) const;
262 void handleSpecificError(
263 css::uno::Reference
< css::deployment::XPackage
> const & package
,
264 css::uno::Any
const & exception
) const;
266 css::uno::Sequence
< css::uno::Reference
< css::xml::dom::XElement
> >
267 getUpdateInformation(
268 css::uno::Reference
< css::deployment::XPackage
> const & package
,
269 css::uno::Sequence
< rtl::OUString
> const & urls
,
270 rtl::OUString
const & identifier
) const;
273 css::uno::Reference
< css::deployment::XPackage
> const & package
,
274 css::uno::Reference
< css::deployment::XPackageManager
> const &
279 css::uno::Reference
< css::deployment::XPackage
> const & package
,
280 css::uno::Reference
< css::deployment::XPackageManager
> const &
282 css::uno::Reference
< css::xml::dom::XNode
> const & updateInfo
) const;
284 css::uno::Reference
< css::uno::XComponentContext
> m_context
;
285 UpdateDialog
& m_dialog
;
286 std::vector
< dp_gui::TUpdateListEntry
> m_vExtensionList
;
287 css::uno::Reference
< css::deployment::XUpdateInformationProvider
>
290 // guarded by Application::GetSolarMutex():
291 css::uno::Reference
< css::task::XAbortChannel
> m_abort
;
295 UpdateDialog::Thread::Thread(
296 css::uno::Reference
< css::uno::XComponentContext
> const & context
,
297 UpdateDialog
& dialog
,
298 const std::vector
< dp_gui::TUpdateListEntry
> &vExtensionList
):
301 m_vExtensionList(vExtensionList
),
303 css::deployment::UpdateInformationProvider::create(context
)),
307 void UpdateDialog::Thread::stop() {
308 css::uno::Reference
< css::task::XAbortChannel
> abort
;
310 vos::OGuard
g(Application::GetSolarMutex());
317 m_updateInformation
->cancel();
320 UpdateDialog::Thread::Entry::Entry(
321 css::uno::Reference
< css::deployment::XPackage
> const & thePackage
,
322 css::uno::Reference
< css::deployment::XPackageManager
> const &
324 rtl::OUString
const & theVersion
):
326 packageManager(thePackageManager
),
330 UpdateDialog::Thread::~Thread() {}
332 void UpdateDialog::Thread::execute()
334 OSL_ASSERT( ! m_vExtensionList
.empty() );
337 typedef std::vector
< TUpdateListEntry
>::const_iterator ITER
;
338 for ( ITER iIndex
= m_vExtensionList
.begin(); iIndex
< m_vExtensionList
.end(); ++iIndex
)
340 css::uno::Reference
< css::deployment::XPackage
> p
= (*iIndex
)->m_xPackage
;
341 css::uno::Reference
< css::deployment::XPackageManager
> m
= (*iIndex
)->m_xPackageManager
;
345 vos::OGuard
g( Application::GetSolarMutex() );
350 handle( p
, m
, &map
);
355 const rtl::OUString
sDefaultURL(dp_misc::getExtensionDefaultUpdateURL());
356 if (sDefaultURL
.getLength())
358 css::uno::Sequence
< css::uno::Reference
< css::xml::dom::XElement
> >
360 getUpdateInformation(
361 css::uno::Reference
< css::deployment::XPackage
>(),
362 css::uno::Sequence
< rtl::OUString
>(&sDefaultURL
, 1), rtl::OUString()));
363 for (sal_Int32 i
= 0; i
< infos
.getLength(); ++i
) {
364 css::uno::Reference
< css::xml::dom::XNode
> node(
365 infos
[i
], css::uno::UNO_QUERY_THROW
);
366 dp_misc::DescriptionInfoset
infoset(m_context
, node
);
367 boost::optional
< rtl::OUString
> id(infoset
.getIdentifier());
371 Map::iterator
end(map
.upper_bound(*id
));
372 for (Map::iterator
j(map
.lower_bound(*id
)); j
!= end
; ++j
) {
373 rtl::OUString
v(infoset
.getVersion());
374 if (dp_misc::compareVersions(v
, j
->second
.version
) ==
377 j
->second
.version
= v
;
378 j
->second
.info
= node
;
382 for (Map::const_iterator
i(map
.begin()); i
!= map
.end(); ++i
) {
383 if (i
->second
.info
.is() &&
385 i
->second
.package
, i
->second
.packageManager
,
393 vos::OGuard
g(Application::GetSolarMutex());
395 m_dialog
.checkingDone();
399 void UpdateDialog::Thread::handleGeneralError(css::uno::Any
const & exception
)
402 rtl::OUString message
;
403 css::uno::Exception e
;
404 if (exception
>>= e
) {
407 vos::OGuard
g(Application::GetSolarMutex());
409 m_dialog
.addGeneralError(message
);
413 //Parameter package can be null
414 void UpdateDialog::Thread::handleSpecificError(
415 css::uno::Reference
< css::deployment::XPackage
> const & package
,
416 css::uno::Any
const & exception
) const
418 UpdateDialog::SpecificError data
;
420 data
.name
= package
->getDisplayName();
421 css::uno::Exception e
;
422 if (exception
>>= e
) {
423 data
.message
= e
.Message
;
425 vos::OGuard
g(Application::GetSolarMutex());
427 m_dialog
.addSpecificError(data
);
431 css::uno::Sequence
< css::uno::Reference
< css::xml::dom::XElement
> >
432 UpdateDialog::Thread::getUpdateInformation(
433 css::uno::Reference
< css::deployment::XPackage
> const & package
,
434 css::uno::Sequence
< rtl::OUString
> const & urls
,
435 rtl::OUString
const & identifier
) const
438 return m_updateInformation
->getUpdateInformation(urls
, identifier
);
439 } catch (css::uno::RuntimeException
&) {
441 } catch (css::ucb::CommandFailedException
& e
) {
442 handleSpecificError(package
, e
.Reason
);
443 } catch (css::ucb::CommandAbortedException
&) {
444 } catch (css::uno::Exception
& e
) {
445 handleSpecificError(package
, css::uno::makeAny(e
));
448 css::uno::Sequence
< css::uno::Reference
< css::xml::dom::XElement
> >();
451 void UpdateDialog::Thread::handle(
452 css::uno::Reference
< css::deployment::XPackage
> const & package
,
453 css::uno::Reference
< css::deployment::XPackageManager
> const &
457 rtl::OUString
id(dp_misc::getIdentifier(package
));
458 css::uno::Sequence
< rtl::OUString
> urls(
459 package
->getUpdateInformationURLs());
460 if (urls
.getLength() == 0) {
463 id
, Entry(package
, packageManager
, package
->getVersion())));
465 css::uno::Sequence
< css::uno::Reference
< css::xml::dom::XElement
> >
466 infos(getUpdateInformation(package
, urls
, id
));
467 rtl::OUString
latestVersion(package
->getVersion());
468 sal_Int32 latestIndex
= -1;
469 for (sal_Int32 i
= 0; i
< infos
.getLength(); ++i
) {
470 dp_misc::DescriptionInfoset
infoset(
472 css::uno::Reference
< css::xml::dom::XNode
>(
473 infos
[i
], css::uno::UNO_QUERY_THROW
));
474 boost::optional
< rtl::OUString
> id2(infoset
.getIdentifier());
479 rtl::OUString
v(infoset
.getVersion());
480 if (dp_misc::compareVersions(v
, latestVersion
) ==
488 if (latestIndex
!= -1) {
490 package
, packageManager
,
491 css::uno::Reference
< css::xml::dom::XNode
>(
492 infos
[latestIndex
], css::uno::UNO_QUERY_THROW
));
497 bool UpdateDialog::Thread::update(
498 css::uno::Reference
< css::deployment::XPackage
> const & package
,
499 css::uno::Reference
< css::deployment::XPackageManager
> const &
501 css::uno::Reference
< css::xml::dom::XNode
> const & updateInfo
) const
503 dp_misc::DescriptionInfoset
infoset(m_context
, updateInfo
);
504 OSL_ASSERT(infoset
.getVersion().getLength() != 0);
505 css::uno::Sequence
< css::uno::Reference
< css::xml::dom::XElement
> > ds(
506 dp_misc::Dependencies::check(infoset
));
508 UpdateDialog::DisabledUpdate du
;
509 du
.aUpdateInfo
= updateInfo
;
510 du
.unsatisfiedDependencies
.realloc(ds
.getLength());
511 for (sal_Int32 i
= 0; i
< ds
.getLength(); ++i
) {
512 du
.unsatisfiedDependencies
[i
] = dp_misc::Dependencies::getErrorText(ds
[i
]);
514 du
.permission
= ! packageManager
->isReadOnly();
515 const ::boost::optional
< ::rtl::OUString
> updateWebsiteURL(infoset
.getLocalizedUpdateWebsiteURL());
516 rtl::OUStringBuffer
b(package
->getDisplayName());
517 b
.append(static_cast< sal_Unicode
>(' '));
519 vos::OGuard
g( Application::GetSolarMutex() );
523 b
.append(m_dialog
.m_version
);
525 b
.append(static_cast< sal_Unicode
>(' '));
526 b
.append(infoset
.getVersion());
527 if (updateWebsiteURL
)
529 b
.append(static_cast< sal_Unicode
>(' '));
531 vos::OGuard
g( Application::GetSolarMutex() );
535 b
.append(m_dialog
.m_browserbased
);
538 du
.name
= b
.makeStringAndClear();
540 if (du
.unsatisfiedDependencies
.getLength() == 0 && du
.permission
)
542 dp_gui::UpdateData data
;
543 data
.aInstalledPackage
= package
;
544 data
.aPackageManager
= packageManager
;
545 data
.aUpdateInfo
= updateInfo
;
546 if (updateWebsiteURL
)
547 data
.sWebsiteURL
= *updateWebsiteURL
;
548 vos::OGuard
g(Application::GetSolarMutex());
550 m_dialog
.addEnabledUpdate(du
.name
, data
);
554 vos::OGuard
g(Application::GetSolarMutex());
556 m_dialog
.addDisabledUpdate(du
);
562 // UpdateDialog ----------------------------------------------------------
563 UpdateDialog::UpdateDialog(
564 css::uno::Reference
< css::uno::XComponentContext
> const & context
,
566 const std::vector
< dp_gui::TUpdateListEntry
> &vExtensionList
,
567 std::vector
< dp_gui::UpdateData
> * updateData
):
568 ModalDialog(parent
,DpGuiResId(RID_DLG_UPDATE
)),
570 m_checking(this, DpGuiResId(RID_DLG_UPDATE_CHECKING
)),
571 m_update(this, DpGuiResId(RID_DLG_UPDATE_UPDATE
)),
573 *this, DpGuiResId(RID_DLG_UPDATE_UPDATES
),
574 Image(DpGuiResId(RID_DLG_UPDATE_NORMALALERT
)),
575 Image(DpGuiResId(RID_DLG_UPDATE_HIGHCONTRASTALERT
))),
576 m_all(this, DpGuiResId(RID_DLG_UPDATE_ALL
)),
577 m_description(this, DpGuiResId(RID_DLG_UPDATE_DESCRIPTION
)),
578 m_PublisherLabel(this, DpGuiResId(RID_DLG_UPDATE_PUBLISHER_LABEL
)),
579 m_PublisherLink(this, DpGuiResId(RID_DLG_UPDATE_PUBLISHER_LINK
)),
580 m_ReleaseNotesLabel(this, DpGuiResId(RID_DLG_UPDATE_RELEASENOTES_LABEL
)),
581 m_ReleaseNotesLink(this, DpGuiResId(RID_DLG_UPDATE_RELEASENOTES_LINK
)),
582 m_descriptions(this, DpGuiResId(RID_DLG_UPDATE_DESCRIPTIONS
)),
583 m_line(this, DpGuiResId(RID_DLG_UPDATE_LINE
)),
584 m_help(this, DpGuiResId(RID_DLG_UPDATE_HELP
)),
585 m_ok(this, DpGuiResId(RID_DLG_UPDATE_OK
)),
586 m_cancel(this, DpGuiResId(RID_DLG_UPDATE_CANCEL
)),
587 m_error(String(DpGuiResId(RID_DLG_UPDATE_ERROR
))),
588 m_none(String(DpGuiResId(RID_DLG_UPDATE_NONE
))),
589 m_noInstallable(String(DpGuiResId(RID_DLG_UPDATE_NOINSTALLABLE
))),
590 m_failure(String(DpGuiResId(RID_DLG_UPDATE_FAILURE
))),
591 m_unknownError(String(DpGuiResId(RID_DLG_UPDATE_UNKNOWNERROR
))),
592 m_noDescription(String(DpGuiResId(RID_DLG_UPDATE_NODESCRIPTION
))),
593 m_noInstall(String(DpGuiResId(RID_DLG_UPDATE_NOINSTALL
))),
594 m_noDependency(String(DpGuiResId(RID_DLG_UPDATE_NODEPENDENCY
))),
595 m_noDependencyCurVer(String(DpGuiResId(RID_DLG_UPDATE_NODEPENDENCY_CUR_VER
))),
596 m_noPermission(String(DpGuiResId(RID_DLG_UPDATE_NOPERMISSION
))),
597 m_noPermissionVista(String(DpGuiResId(RID_DLG_UPDATE_NOPERMISSION_VISTA
))),
598 m_browserbased(String(DpGuiResId(RID_DLG_UPDATE_BROWSERBASED
))),
599 m_version(String(DpGuiResId(RID_DLG_UPDATE_VERSION
))),
600 m_updateData(*updateData
),
602 new UpdateDialog::Thread(
603 context
, *this, vExtensionList
)),
604 m_nFirstLineDelta(0),
608 // m_extensionManagerDialog(extensionManagerDialog)
610 OSL_ASSERT(updateData
!= NULL
);
611 css::uno::Reference
< css::awt::XToolkit
> toolkit
;
613 toolkit
= css::uno::Reference
< css::awt::XToolkit
>(
614 (css::uno::Reference
< css::lang::XMultiComponentFactory
>(
615 m_context
->getServiceManager(),
616 css::uno::UNO_QUERY_THROW
)->
617 createInstanceWithContext(
619 RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.Toolkit")),
621 css::uno::UNO_QUERY_THROW
);
622 } catch (css::uno::RuntimeException
&) {
624 } catch (css::uno::Exception
& e
) {
625 throw css::uno::RuntimeException(e
.Message
, e
.Context
);
627 Control
c(this, DpGuiResId(RID_DLG_UPDATE_THROBBER
));
628 Point
pos(c
.GetPosPixel());
629 Size
size(c
.GetSizePixel());
631 m_throbber
= css::uno::Reference
< css::awt::XThrobber
>(
632 toolkit
->createWindow(
633 css::awt::WindowDescriptor(
634 css::awt::WindowClass_SIMPLE
,
635 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Throbber")),
636 GetComponentInterface(), 0,
638 pos
.X(), pos
.Y(), size
.Width(), size
.Height()),
639 css::awt::WindowAttribute::SHOW
)),
640 css::uno::UNO_QUERY_THROW
);
641 } catch (css::lang::IllegalArgumentException
& e
) {
642 throw css::uno::RuntimeException(e
.Message
, e
.Context
);
644 m_updates
.SetSelectHdl(LINK(this, UpdateDialog
, selectionHandler
));
645 m_all
.SetToggleHdl(LINK(this, UpdateDialog
, allHandler
));
646 m_ok
.SetClickHdl(LINK(this, UpdateDialog
, okHandler
));
647 m_cancel
.SetClickHdl(LINK(this, UpdateDialog
, cancelHandler
));
648 if ( ! dp_misc::office_is_running())
651 String
sTemp(m_noPermissionVista
);
652 sTemp
.SearchAndReplaceAllAscii( "%PRODUCTNAME", BrandName::get() );
653 m_noPermissionVista
= sTemp
;
658 UpdateDialog::~UpdateDialog() {
659 for (USHORT i
= 0; i
< m_updates
.getItemCount(); ++i
) {
660 delete static_cast< UpdateDialog::Index
const * >(
661 m_updates
.GetEntryData(i
));
665 BOOL
UpdateDialog::Close() {
667 return ModalDialog::Close();
670 short UpdateDialog::Execute() {
673 return ModalDialog::Execute();
676 UpdateDialog::CheckListBox::CheckListBox(
677 UpdateDialog
& dialog
, ResId
const & resource
,
678 Image
const & normalStaticImage
, Image
const & highContrastStaticImage
):
680 &dialog
, resource
, normalStaticImage
, highContrastStaticImage
),
684 UpdateDialog::CheckListBox::~CheckListBox() {}
686 USHORT
UpdateDialog::CheckListBox::getItemCount() const {
687 ULONG i
= GetEntryCount();
688 OSL_ASSERT(i
<= std::numeric_limits
< USHORT
>::max());
689 return sal::static_int_cast
< USHORT
>(i
);
692 void UpdateDialog::CheckListBox::MouseButtonDown(MouseEvent
const & event
) {
693 // When clicking on a selected entry in an SvxCheckListBox, the entry's
694 // checkbox is toggled on mouse button down:
695 SvxCheckListBox::MouseButtonDown(event
);
699 void UpdateDialog::CheckListBox::MouseButtonUp(MouseEvent
const & event
) {
700 // When clicking on an entry's checkbox in an SvxCheckListBox, the entry's
701 // checkbox is toggled on mouse button up:
702 SvxCheckListBox::MouseButtonUp(event
);
706 void UpdateDialog::CheckListBox::KeyInput(KeyEvent
const & event
) {
707 SvxCheckListBox::KeyInput(event
);
711 void UpdateDialog::insertItem(
712 rtl::OUString
const & name
, USHORT position
,
713 std::auto_ptr
< UpdateDialog::Index
const > index
, SvLBoxButtonKind kind
)
715 m_updates
.InsertEntry(
717 const_cast< void * >(static_cast< void const * >(index
.release())),
719 //TODO #i72487#: UpdateDialog::Index potentially leaks as the exception
720 // behavior of SvxCheckListBox::InsertEntry is unspecified
723 void UpdateDialog::addAdditional(
724 rtl::OUString
const & name
, USHORT position
,
725 std::auto_ptr
< UpdateDialog::Index
const > index
, SvLBoxButtonKind kind
)
728 if (m_all
.IsChecked()) {
729 insertItem(name
, position
, index
, kind
);
732 m_description
.Enable();
733 m_descriptions
.Enable();
737 void UpdateDialog::addEnabledUpdate(
738 rtl::OUString
const & name
, dp_gui::UpdateData
const & data
)
740 std::vector
< dp_gui::UpdateData
>::size_type n
= m_enabledUpdates
.size();
741 m_enabledUpdates
.push_back(data
);
743 name
, sal::static_int_cast
< USHORT
>(n
),
744 UpdateDialog::Index::newEnabledUpdate(n
),
745 SvLBoxButtonKind_enabledCheckbox
);
746 // position overflow is rather harmless
747 m_updates
.CheckEntryPos(sal::static_int_cast
< USHORT
>(n
));
748 //TODO #i72487#: fragile computation; insertItem should instead return
752 m_description
.Enable();
753 m_descriptions
.Enable();
756 void UpdateDialog::addDisabledUpdate(UpdateDialog::DisabledUpdate
const & data
)
758 std::vector
< UpdateDialog::DisabledUpdate
>::size_type n
=
759 m_disabledUpdates
.size();
760 m_disabledUpdates
.push_back(data
);
762 data
.name
, sal::static_int_cast
< USHORT
>(m_enabledUpdates
.size() + n
),
763 UpdateDialog::Index::newDisabledUpdate(n
),
764 SvLBoxButtonKind_disabledCheckbox
);
765 // position overflow is rather harmless
768 void UpdateDialog::addGeneralError(rtl::OUString
const & message
) {
769 std::vector
< rtl::OUString
>::size_type n
= m_generalErrors
.size();
770 m_generalErrors
.push_back(message
);
773 sal::static_int_cast
< USHORT
>(
774 m_enabledUpdates
.size() + m_disabledUpdates
.size() + n
),
775 UpdateDialog::Index::newGeneralError(n
), SvLBoxButtonKind_staticImage
);
776 // position overflow is rather harmless
779 void UpdateDialog::addSpecificError(UpdateDialog::SpecificError
const & data
) {
780 std::vector
< UpdateDialog::SpecificError
>::size_type n
=
781 m_specificErrors
.size();
782 m_specificErrors
.push_back(data
);
784 data
.name
, LISTBOX_APPEND
, UpdateDialog::Index::newSpecificError(n
),
785 SvLBoxButtonKind_staticImage
);
788 void UpdateDialog::checkingDone() {
791 css::uno::Reference
< css::awt::XWindow
>(
792 m_throbber
, css::uno::UNO_QUERY_THROW
)->setVisible(false);
793 if (m_updates
.getItemCount() == 0)
796 m_description
.Enable();
797 m_descriptions
.Enable();
799 ( m_disabledUpdates
.empty() && m_generalErrors
.empty() && m_specificErrors
.empty() )
800 ? m_none
: m_noInstallable
, false );
805 void UpdateDialog::enableOk() {
806 if (!m_checking
.IsVisible()) {
807 m_ok
.Enable(m_updates
.GetCheckedEntryCount() != 0);
811 // *********************************************************************************
812 void UpdateDialog::createNotifyJob( bool bPrepareOnly
,
813 css::uno::Sequence
< css::uno::Sequence
< rtl::OUString
> > &rItemList
)
815 if ( !dp_misc::office_is_running() )
818 // notify update check job
821 css::uno::Reference
< css::lang::XMultiServiceFactory
> xFactory( ::comphelper::getProcessServiceFactory() );
822 css::uno::Reference
< css::lang::XMultiServiceFactory
> xConfigProvider(
823 xFactory
->createInstance( OUSTR( "com.sun.star.configuration.ConfigurationProvider" )),
824 css::uno::UNO_QUERY_THROW
);
826 css::beans::PropertyValue aProperty
;
827 aProperty
.Name
= OUSTR( "nodepath" );
828 aProperty
.Value
= css::uno::makeAny( OUSTR("org.openoffice.Office.Addons/AddonUI/OfficeHelp/UpdateCheckJob") );
830 css::uno::Sequence
< css::uno::Any
> aArgumentList( 1 );
831 aArgumentList
[0] = css::uno::makeAny( aProperty
);
833 css::uno::Reference
< css::container::XNameAccess
> xNameAccess(
834 xConfigProvider
->createInstanceWithArguments(
835 OUSTR("com.sun.star.configuration.ConfigurationAccess"), aArgumentList
),
836 css::uno::UNO_QUERY_THROW
);
839 xNameAccess
->getByName(OUSTR("URL")) >>= aURL
.Complete
;
841 css::uno::Reference
< css::util::XURLTransformer
> xTransformer( xFactory
->createInstance( OUSTR( "com.sun.star.util.URLTransformer" ) ),
842 css::uno::UNO_QUERY_THROW
);
844 xTransformer
->parseStrict(aURL
);
846 css::uno::Reference
< css::frame::XDesktop
> xDesktop( xFactory
->createInstance( OUSTR( "com.sun.star.frame.Desktop" ) ),
847 css::uno::UNO_QUERY_THROW
);
848 css::uno::Reference
< css::frame::XDispatchProvider
> xDispatchProvider( xDesktop
->getCurrentFrame(),
849 css::uno::UNO_QUERY_THROW
);
850 css::uno::Reference
< css::frame::XDispatch
> xDispatch
= xDispatchProvider
->queryDispatch(aURL
, rtl::OUString(), 0);
854 css::uno::Sequence
< css::beans::PropertyValue
> aPropList(2);
855 aProperty
.Name
= OUSTR( "updateList" );
856 aProperty
.Value
= css::uno::makeAny( rItemList
);
857 aPropList
[0] = aProperty
;
858 aProperty
.Name
= OUSTR( "prepareOnly" );
859 aProperty
.Value
= css::uno::makeAny( bPrepareOnly
);
860 aPropList
[1] = aProperty
;
862 xDispatch
->dispatch(aURL
, aPropList
);
865 catch( const css::uno::Exception
& e
)
867 dp_misc::TRACE( OUSTR("Caught exception: ")
868 + e
.Message
+ OUSTR("\n thread terminated.\n\n"));
872 // *********************************************************************************
873 void UpdateDialog::notifyMenubar( bool bPrepareOnly
, bool bRecheckOnly
)
875 if ( !dp_misc::office_is_running() )
878 css::uno::Sequence
< css::uno::Sequence
< rtl::OUString
> > aItemList
;
879 sal_Int32 nCount
= 0;
881 if ( ! bRecheckOnly
)
883 for ( sal_Int16 i
= 0; i
< m_updates
.getItemCount(); ++i
)
885 css::uno::Sequence
< rtl::OUString
> aItem(2);
887 UpdateDialog::Index
const * p
= static_cast< UpdateDialog::Index
const * >(m_updates
.GetEntryData(i
));
889 if ( p
->kind
== ENABLED_UPDATE
)
891 dp_gui::UpdateData aUpdData
= m_enabledUpdates
[ p
->index
.enabledUpdate
];
892 aItem
[0] = dp_misc::getIdentifier( aUpdData
.aInstalledPackage
);
894 dp_misc::DescriptionInfoset
aInfoset( m_context
, aUpdData
.aUpdateInfo
);
895 aItem
[1] = aInfoset
.getVersion();
897 else if ( p
->kind
== DISABLED_UPDATE
)
902 aItemList
.realloc( nCount
+ 1 );
903 aItemList
[ nCount
] = aItem
;
907 createNotifyJob( bPrepareOnly
, aItemList
);
910 // *********************************************************************************
912 void UpdateDialog::initDescription()
914 m_PublisherLabel
.Hide();
915 m_PublisherLink
.Hide();
916 m_ReleaseNotesLabel
.Hide();
917 m_ReleaseNotesLink
.Hide();
918 m_descriptions
.Hide();
920 Link aLink
= LINK( this, UpdateDialog
, hyperlink_clicked
);
921 m_PublisherLink
.SetClickHdl( aLink
);
922 m_ReleaseNotesLink
.SetClickHdl( aLink
);
924 long nTextWidth
= m_PublisherLabel
.GetCtrlTextWidth( m_PublisherLabel
.GetText() );
925 long nTemp
= m_ReleaseNotesLabel
.GetTextWidth( m_ReleaseNotesLabel
.GetText() );
926 if ( nTemp
> nTextWidth
)
928 nTextWidth
= nTextWidth
* 110 / 100;
930 Size aNewSize
= m_PublisherLabel
.GetSizePixel();
931 if ( nTextWidth
> aNewSize
.Width() )
933 long nDelta
= nTextWidth
- aNewSize
.Width();
934 aNewSize
.Width() = nTextWidth
;
935 m_PublisherLabel
.SetSizePixel( aNewSize
);
936 m_ReleaseNotesLabel
.SetSizePixel( aNewSize
);
938 aNewSize
= m_PublisherLink
.GetSizePixel();
939 aNewSize
.Width() = aNewSize
.Width() - nDelta
;
940 Point aNewPos
= m_PublisherLink
.GetPosPixel();
941 aNewPos
.X() = aNewPos
.X() + nDelta
;
942 m_PublisherLink
.SetPosSizePixel( aNewPos
, aNewSize
);
943 aNewPos
.Y() = m_ReleaseNotesLink
.GetPosPixel().Y();
944 m_ReleaseNotesLink
.SetPosSizePixel( aNewPos
, aNewSize
);
947 m_aFirstLinePos
= m_descriptions
.GetPosPixel();
948 m_aFirstLineSize
= m_descriptions
.GetSizePixel();
949 Size aMarginSize
= LogicToPixel( Size( RSC_SP_CTRL_GROUP_X
, RSC_SP_CTRL_GROUP_Y
), MAP_APPFONT
);
950 Point aThirdLinePos
= m_ReleaseNotesLabel
.GetPosPixel();
951 aThirdLinePos
.Y() = aThirdLinePos
.Y() + m_ReleaseNotesLabel
.GetSizePixel().Height() + aMarginSize
.Height();
952 m_nFirstLineDelta
= aThirdLinePos
.Y() - m_aFirstLinePos
.Y();
953 m_nOneLineMissing
= m_ReleaseNotesLabel
.GetPosPixel().Y() - m_PublisherLabel
.GetPosPixel().Y();
956 void UpdateDialog::clearDescription()
959 m_PublisherLabel
.Hide();
960 m_PublisherLink
.Hide();
961 m_PublisherLink
.SetDescription( sEmpty
);
962 m_PublisherLink
.SetURL( sEmpty
);
963 m_ReleaseNotesLabel
.Hide();
964 m_ReleaseNotesLink
.Hide();
965 m_ReleaseNotesLink
.SetURL( sEmpty
);
966 if ( m_PublisherLabel
.GetPosPixel().Y() == m_ReleaseNotesLabel
.GetPosPixel().Y() )
968 Point aNewPos
= m_ReleaseNotesLabel
.GetPosPixel();
969 aNewPos
.Y() += m_nOneLineMissing
;
970 m_ReleaseNotesLabel
.SetPosPixel( aNewPos
);
971 aNewPos
= m_ReleaseNotesLink
.GetPosPixel();
972 aNewPos
.Y() += m_nOneLineMissing
;
973 m_ReleaseNotesLink
.SetPosPixel( aNewPos
);
975 m_descriptions
.Hide();
976 m_descriptions
.Clear();
977 m_descriptions
.SetPosSizePixel( m_aFirstLinePos
, m_aFirstLineSize
);
980 bool UpdateDialog::showDescription(css::uno::Reference
< css::xml::dom::XNode
> const & aUpdateInfo
)
982 dp_misc::DescriptionInfoset
infoset(m_context
, aUpdateInfo
);
983 std::pair
< rtl::OUString
, rtl::OUString
> pairPub
= infoset
.getLocalizedPublisherNameAndURL();
984 rtl::OUString sPub
= pairPub
.first
;
985 rtl::OUString sURL
= pairPub
.second
;
986 rtl::OUString sRel
= infoset
.getLocalizedReleaseNotesURL();
988 if ( sPub
.getLength() == 0 && sURL
.getLength() == 0 && sRel
.getLength() == 0 )
992 bool bPublisher
= false;
993 if ( sPub
.getLength() > 0 )
995 m_PublisherLabel
.Show();
996 m_PublisherLink
.Show();
997 m_PublisherLink
.SetDescription( sPub
);
998 m_PublisherLink
.SetURL( sURL
);
1002 if ( sRel
.getLength() > 0 )
1006 m_ReleaseNotesLabel
.SetPosPixel( m_PublisherLabel
.GetPosPixel() );
1007 m_ReleaseNotesLink
.SetPosPixel( m_PublisherLink
.GetPosPixel() );
1009 m_ReleaseNotesLabel
.Show();
1010 m_ReleaseNotesLink
.Show();
1011 m_ReleaseNotesLink
.SetURL( sRel
);
1016 bool UpdateDialog::showDescription( const String
& rDescription
, bool bWithPublisher
)
1018 if ( rDescription
.Len() == 0 )
1022 if ( bWithPublisher
)
1024 bool bOneLineMissing
= !m_ReleaseNotesLabel
.IsVisible() || !m_PublisherLabel
.IsVisible();
1025 Point aNewPos
= m_aFirstLinePos
;
1026 aNewPos
.Y() += m_nFirstLineDelta
;
1027 if ( bOneLineMissing
)
1028 aNewPos
.Y() -= m_nOneLineMissing
;
1029 Size aNewSize
= m_aFirstLineSize
;
1030 aNewSize
.Height() -= m_nFirstLineDelta
;
1031 if ( bOneLineMissing
)
1032 aNewSize
.Height() += m_nOneLineMissing
;
1033 m_descriptions
.SetPosSizePixel( aNewPos
, aNewSize
);
1035 m_descriptions
.Show();
1036 m_descriptions
.SetDescription( rDescription
);
1040 IMPL_LINK(UpdateDialog
, selectionHandler
, void *, EMPTYARG
)
1042 rtl::OUStringBuffer b
;
1043 bool bInserted
= false;
1044 UpdateDialog::Index
const * p
= static_cast< UpdateDialog::Index
const * >(
1045 m_updates
.GetEntryData(m_updates
.GetSelectEntryPos()));
1050 //When the index is greater or equal than the amount of enabled updates then the "Show all"
1051 //button is probably checked. Then we show first all enabled and then the disabled
1053 USHORT pos
= m_updates
.GetSelectEntryPos();
1054 const std::vector
< dp_gui::UpdateData
>::size_type sizeEnabled
=
1055 m_enabledUpdates
.size();
1056 const std::vector
< UpdateDialog::DisabledUpdate
>::size_type sizeDisabled
=
1057 m_disabledUpdates
.size();
1058 if (pos
< sizeEnabled
)
1059 bInserted
= showDescription(m_enabledUpdates
[pos
].aUpdateInfo
);
1060 else if (pos
>= sizeEnabled
1061 && pos
< (sizeEnabled
+ sizeDisabled
))
1062 bInserted
= showDescription(m_disabledUpdates
[pos
- sizeEnabled
].aUpdateInfo
);
1066 case ENABLED_UPDATE
:
1068 b
.append(m_noDescription
);
1071 case DISABLED_UPDATE
:
1073 UpdateDialog::DisabledUpdate
& data
= m_disabledUpdates
[
1074 p
->index
.disabledUpdate
];
1075 if (data
.unsatisfiedDependencies
.getLength() != 0)
1077 // create error string for version mismatch
1078 ::rtl::OUString
sVersion( RTL_CONSTASCII_USTRINGPARAM("%VERSION") );
1079 sal_Int32 nPos
= m_noDependencyCurVer
.indexOf( sVersion
);
1082 ::rtl::OUString
sCurVersion( RTL_CONSTASCII_USTRINGPARAM( "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("version") ":Version:OOOPackageVersion}"));
1083 ::rtl::Bootstrap::expandMacros(sCurVersion
);
1084 m_noDependencyCurVer
= m_noDependencyCurVer
.replaceAt( nPos
, sVersion
.getLength(), sCurVersion
);
1087 b
.append(m_noInstall
);
1089 b
.append(m_noDependency
);
1090 for (sal_Int32 i
= 0;
1091 i
< data
.unsatisfiedDependencies
.getLength(); ++i
)
1094 b
.appendAscii(RTL_CONSTASCII_STRINGPARAM(" "));
1095 // U+2003 EM SPACE would be better than two spaces,
1096 // but some fonts do not contain it
1099 data
.unsatisfiedDependencies
[i
]));
1102 b
.appendAscii(RTL_CONSTASCII_STRINGPARAM(" "));
1103 b
.append(m_noDependencyCurVer
);
1105 if (!data
.permission
) {
1106 if (b
.getLength() == 0) {
1107 b
.append(m_noInstall
);
1111 b
.append(m_noPermissionVista
);
1113 b
.append(m_noPermission
);
1119 rtl::OUString
& msg
= m_generalErrors
[p
->index
.generalError
];
1120 b
.append(m_failure
);
1122 b
.append(msg
.getLength() == 0 ? m_unknownError
: msg
);
1125 case SPECIFIC_ERROR
:
1127 UpdateDialog::SpecificError
& data
= m_specificErrors
[
1128 p
->index
.specificError
];
1129 b
.append(m_failure
);
1132 data
.message
.getLength() == 0
1133 ? m_unknownError
: data
.message
);
1142 showDescription( b
.makeStringAndClear(), bInserted
);
1146 IMPL_LINK(UpdateDialog
, allHandler
, void *, EMPTYARG
) {
1147 if (m_all
.IsChecked()) {
1150 m_description
.Enable();
1151 m_descriptions
.Enable();
1152 std::vector
< UpdateDialog::DisabledUpdate
>::size_type n1
= 0;
1153 for (std::vector
< UpdateDialog::DisabledUpdate
>::iterator
i(
1154 m_disabledUpdates
.begin());
1155 i
!= m_disabledUpdates
.end(); ++i
)
1158 i
->name
, LISTBOX_APPEND
,
1159 UpdateDialog::Index::newDisabledUpdate(n1
++),
1160 SvLBoxButtonKind_disabledCheckbox
);
1162 std::vector
< rtl::OUString
>::size_type n2
= 0;
1163 for (std::vector
< rtl::OUString
>::iterator
i(m_generalErrors
.begin());
1164 i
!= m_generalErrors
.end(); ++i
)
1167 m_error
, LISTBOX_APPEND
,
1168 UpdateDialog::Index::newGeneralError(n2
++),
1169 SvLBoxButtonKind_staticImage
);
1171 std::vector
< UpdateDialog::SpecificError
>::size_type n3
= 0;
1172 for (std::vector
< UpdateDialog::SpecificError
>::iterator
i(
1173 m_specificErrors
.begin());
1174 i
!= m_specificErrors
.end(); ++i
)
1177 i
->name
, LISTBOX_APPEND
,
1178 UpdateDialog::Index::newSpecificError(n3
++),
1179 SvLBoxButtonKind_staticImage
);
1182 for (USHORT i
= 0; i
< m_updates
.getItemCount();) {
1183 UpdateDialog::Index
const * p
=
1184 static_cast< UpdateDialog::Index
const * >(
1185 m_updates
.GetEntryData(i
));
1186 if (p
->kind
!= ENABLED_UPDATE
) {
1187 m_updates
.RemoveEntry(i
);
1188 //TODO #i72487#: UpdateDialog::Index potentially leaks as
1189 // SvxCheckListBox::RemoveEntry's exception behavior is
1197 if (m_updates
.getItemCount() == 0)
1201 m_updates
.Disable();
1202 if (m_checking
.IsVisible())
1203 m_description
.Disable();
1205 showDescription(m_noInstallable
,false);
1211 IMPL_LINK(UpdateDialog
, okHandler
, void *, EMPTYARG
)
1213 //If users are going to update a shared extension then we need
1215 typedef ::std::vector
<UpdateData
>::const_iterator CIT
;
1216 for (CIT i
= m_enabledUpdates
.begin(); i
< m_enabledUpdates
.end(); i
++)
1218 OSL_ASSERT(i
->aPackageManager
.is());
1219 //If the user has no write access to the shared folder then the update
1220 //for a shared extension is disable, that is it cannot be in m_enabledUpdates
1221 OSL_ASSERT(i
->aPackageManager
->isReadOnly() == sal_False
);
1224 OSL_ASSERT(m_extensionManagerDialog
.get());
1225 if (RET_CANCEL
== m_extensionManagerDialog
->continueUpdateForSharedExtension(
1226 this, i
->aPackageManager
))
1228 EndDialog(RET_CANCEL
);
1233 for (USHORT i
= 0; i
< m_updates
.getItemCount(); ++i
) {
1234 UpdateDialog::Index
const * p
=
1235 static_cast< UpdateDialog::Index
const * >(
1236 m_updates
.GetEntryData(i
));
1237 if (p
->kind
== ENABLED_UPDATE
&& m_updates
.IsChecked(i
)) {
1238 m_updateData
.push_back(m_enabledUpdates
[p
->index
.enabledUpdate
]);
1245 IMPL_LINK(UpdateDialog
, cancelHandler
, void *, EMPTYARG
) {
1247 EndDialog(RET_CANCEL
);
1251 IMPL_LINK( UpdateDialog
, hyperlink_clicked
, svt::FixedHyperlink
*, pHyperlink
)
1253 ::rtl::OUString sURL
;
1255 sURL
= ::rtl::OUString( pHyperlink
->GetURL() );
1256 if ( sURL
.getLength() == 0 )
1261 css::uno::Reference
< css::system::XSystemShellExecute
> xSystemShellExecute(
1262 m_context
->getServiceManager()->createInstanceWithContext(
1263 ::rtl::OUString::createFromAscii( "com.sun.star.system.SystemShellExecute" ),
1264 m_context
), css::uno::UNO_QUERY_THROW
);
1265 //throws css::lang::IllegalArgumentException, css::system::SystemShellExecuteException
1266 xSystemShellExecute
->execute(
1267 sURL
, ::rtl::OUString(), css::system::SystemShellExecuteFlags::DEFAULTS
);
1269 catch (css::uno::Exception
& )