Update ooo320-m1
[ooovba.git] / desktop / source / deployment / gui / dp_gui_updatedialog.cxx
blobea05a7394b91c3ab95eb343882517bbe3717f4e6
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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"
33 #include <cstddef>
34 #include <limits>
35 #include <map>
36 #include <memory>
37 #include <utility>
38 #include <vector>
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"
113 #include "dp_misc.h"
115 #include "dp_gui.h"
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"
123 class KeyEvent;
124 class MouseEvent;
125 class Window;
126 namespace com { namespace sun { namespace star { namespace uno {
127 class XComponentContext;
128 } } } }
130 namespace css = ::com::sun::star;
132 using dp_gui::UpdateDialog;
134 namespace {
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 {
151 rtl::OUString name;
152 css::uno::Sequence< rtl::OUString > unsatisfiedDependencies;
153 bool permission;
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 {
159 rtl::OUString name;
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);
183 Kind kind;
184 IndexUnion index;
186 private:
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 {
228 public:
229 Thread(
230 css::uno::Reference< css::uno::XComponentContext > const & context,
231 UpdateDialog & dialog,
232 const std::vector< TUpdateListEntry > &vExtensionList);
234 void stop();
236 private:
237 Thread(UpdateDialog::Thread &); // not defined
238 void operator =(UpdateDialog::Thread &); // not defined
240 struct Entry {
241 explicit Entry(
242 css::uno::Reference< css::deployment::XPackage > const & thePackage,
243 css::uno::Reference< css::deployment::XPackageManager > const &
244 thePackageManager,
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;
256 virtual ~Thread();
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;
272 void handle(
273 css::uno::Reference< css::deployment::XPackage > const & package,
274 css::uno::Reference< css::deployment::XPackageManager > const &
275 packageManager,
276 Map * map);
278 bool update(
279 css::uno::Reference< css::deployment::XPackage > const & package,
280 css::uno::Reference< css::deployment::XPackageManager > const &
281 packageManager,
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 >
288 m_updateInformation;
290 // guarded by Application::GetSolarMutex():
291 css::uno::Reference< css::task::XAbortChannel > m_abort;
292 bool m_stop;
295 UpdateDialog::Thread::Thread(
296 css::uno::Reference< css::uno::XComponentContext > const & context,
297 UpdateDialog & dialog,
298 const std::vector< dp_gui::TUpdateListEntry > &vExtensionList):
299 m_context(context),
300 m_dialog(dialog),
301 m_vExtensionList(vExtensionList),
302 m_updateInformation(
303 css::deployment::UpdateInformationProvider::create(context)),
304 m_stop(false)
307 void UpdateDialog::Thread::stop() {
308 css::uno::Reference< css::task::XAbortChannel > abort;
310 vos::OGuard g(Application::GetSolarMutex());
311 abort = m_abort;
312 m_stop = true;
314 if (abort.is()) {
315 abort->sendAbort();
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 &
323 thePackageManager,
324 rtl::OUString const & theVersion):
325 package(thePackage),
326 packageManager(thePackageManager),
327 version(theVersion)
330 UpdateDialog::Thread::~Thread() {}
332 void UpdateDialog::Thread::execute()
334 OSL_ASSERT( ! m_vExtensionList.empty() );
335 Map map;
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;
342 if ( p.is() )
345 vos::OGuard g( Application::GetSolarMutex() );
346 if ( m_stop ) {
347 return;
350 handle( p, m, &map );
354 if (!map.empty()) {
355 const rtl::OUString sDefaultURL(dp_misc::getExtensionDefaultUpdateURL());
356 if (sDefaultURL.getLength())
358 css::uno::Sequence< css::uno::Reference< css::xml::dom::XElement > >
359 infos(
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());
368 if (!id) {
369 continue;
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) ==
375 dp_misc::GREATER)
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() &&
384 !update(
385 i->second.package, i->second.packageManager,
386 i->second.info))
388 break;
393 vos::OGuard g(Application::GetSolarMutex());
394 if (!m_stop) {
395 m_dialog.checkingDone();
399 void UpdateDialog::Thread::handleGeneralError(css::uno::Any const & exception)
400 const
402 rtl::OUString message;
403 css::uno::Exception e;
404 if (exception >>= e) {
405 message = e.Message;
407 vos::OGuard g(Application::GetSolarMutex());
408 if (!m_stop) {
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;
419 if (package.is())
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());
426 if (!m_stop) {
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
437 try {
438 return m_updateInformation->getUpdateInformation(urls, identifier);
439 } catch (css::uno::RuntimeException &) {
440 throw;
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));
447 return
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 &
454 packageManager,
455 Map * map)
457 rtl::OUString id(dp_misc::getIdentifier(package));
458 css::uno::Sequence< rtl::OUString > urls(
459 package->getUpdateInformationURLs());
460 if (urls.getLength() == 0) {
461 map->insert(
462 Map::value_type(
463 id, Entry(package, packageManager, package->getVersion())));
464 } else {
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(
471 m_context,
472 css::uno::Reference< css::xml::dom::XNode >(
473 infos[i], css::uno::UNO_QUERY_THROW));
474 boost::optional< rtl::OUString > id2(infoset.getIdentifier());
475 if (!id2) {
476 continue;
478 if (*id2 == id) {
479 rtl::OUString v(infoset.getVersion());
480 if (dp_misc::compareVersions(v, latestVersion) ==
481 dp_misc::GREATER)
483 latestVersion = v;
484 latestIndex = i;
488 if (latestIndex != -1) {
489 update(
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 &
500 packageManager,
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() );
520 if ( m_stop )
521 return !m_stop;
522 else
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() );
532 if ( m_stop )
533 return !m_stop;
534 else
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());
549 if (!m_stop) {
550 m_dialog.addEnabledUpdate(du.name, data);
552 return !m_stop;
553 } else {
554 vos::OGuard g(Application::GetSolarMutex());
555 if (!m_stop) {
556 m_dialog.addDisabledUpdate(du);
558 return !m_stop;
562 // UpdateDialog ----------------------------------------------------------
563 UpdateDialog::UpdateDialog(
564 css::uno::Reference< css::uno::XComponentContext > const & context,
565 Window * parent,
566 const std::vector< dp_gui::TUpdateListEntry > &vExtensionList,
567 std::vector< dp_gui::UpdateData > * updateData):
568 ModalDialog(parent,DpGuiResId(RID_DLG_UPDATE)),
569 m_context(context),
570 m_checking(this, DpGuiResId(RID_DLG_UPDATE_CHECKING)),
571 m_update(this, DpGuiResId(RID_DLG_UPDATE_UPDATE)),
572 m_updates(
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),
601 m_thread(
602 new UpdateDialog::Thread(
603 context, *this, vExtensionList)),
604 m_nFirstLineDelta(0),
605 m_nOneLineMissing(0)
606 // TODO: check!
607 // ,
608 // m_extensionManagerDialog(extensionManagerDialog)
610 OSL_ASSERT(updateData != NULL);
611 css::uno::Reference< css::awt::XToolkit > toolkit;
612 try {
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(
618 rtl::OUString(
619 RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.Toolkit")),
620 m_context)),
621 css::uno::UNO_QUERY_THROW);
622 } catch (css::uno::RuntimeException &) {
623 throw;
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());
630 try {
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,
637 css::awt::Rectangle(
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())
649 m_help.Disable();
650 FreeResource();
651 String sTemp(m_noPermissionVista);
652 sTemp.SearchAndReplaceAllAscii( "%PRODUCTNAME", BrandName::get() );
653 m_noPermissionVista = sTemp;
655 initDescription();
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() {
666 m_thread->stop();
667 return ModalDialog::Close();
670 short UpdateDialog::Execute() {
671 m_throbber->start();
672 m_thread->launch();
673 return ModalDialog::Execute();
676 UpdateDialog::CheckListBox::CheckListBox(
677 UpdateDialog & dialog, ResId const & resource,
678 Image const & normalStaticImage, Image const & highContrastStaticImage):
679 SvxCheckListBox(
680 &dialog, resource, normalStaticImage, highContrastStaticImage),
681 m_dialog(dialog)
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);
696 m_dialog.enableOk();
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);
703 m_dialog.enableOk();
706 void UpdateDialog::CheckListBox::KeyInput(KeyEvent const & event) {
707 SvxCheckListBox::KeyInput(event);
708 m_dialog.enableOk();
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(
716 name, position,
717 const_cast< void * >(static_cast< void const * >(index.release())),
718 kind);
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)
727 m_all.Enable();
728 if (m_all.IsChecked()) {
729 insertItem(name, position, index, kind);
730 m_update.Enable();
731 m_updates.Enable();
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);
742 insertItem(
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
749 // pos
750 m_update.Enable();
751 m_updates.Enable();
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);
761 addAdditional(
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);
771 addAdditional(
772 m_error,
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);
783 addAdditional(
784 data.name, LISTBOX_APPEND, UpdateDialog::Index::newSpecificError(n),
785 SvLBoxButtonKind_staticImage);
788 void UpdateDialog::checkingDone() {
789 m_checking.Hide();
790 m_throbber->stop();
791 css::uno::Reference< css::awt::XWindow >(
792 m_throbber, css::uno::UNO_QUERY_THROW)->setVisible(false);
793 if (m_updates.getItemCount() == 0)
795 clearDescription();
796 m_description.Enable();
797 m_descriptions.Enable();
798 showDescription(
799 ( m_disabledUpdates.empty() && m_generalErrors.empty() && m_specificErrors.empty() )
800 ? m_none : m_noInstallable, false );
802 enableOk();
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() )
816 return;
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 );
838 css::util::URL aURL;
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);
852 if( xDispatch.is() )
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() )
876 return;
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 )
898 continue;
899 else
900 continue;
902 aItemList.realloc( nCount + 1 );
903 aItemList[ nCount ] = aItem;
904 nCount += 1;
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 )
927 nTextWidth = nTemp;
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()
958 String sEmpty;
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 )
989 // nothing to show
990 return false;
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 );
999 bPublisher = true;
1002 if ( sRel.getLength() > 0 )
1004 if ( !bPublisher )
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 );
1013 return true;
1016 bool UpdateDialog::showDescription( const String& rDescription, bool bWithPublisher )
1018 if ( rDescription.Len() == 0 )
1019 // nothing to show
1020 return false;
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 );
1037 return true;
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()));
1046 clearDescription();
1048 if (p != NULL)
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
1052 //updates.
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);
1064 switch (p->kind)
1066 case ENABLED_UPDATE:
1068 b.append(m_noDescription);
1069 break;
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 );
1080 if ( nPos >= 0 )
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);
1088 b.append(LF);
1089 b.append(m_noDependency);
1090 for (sal_Int32 i = 0;
1091 i < data.unsatisfiedDependencies.getLength(); ++i)
1093 b.append(LF);
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
1097 b.append(
1098 confineToParagraph(
1099 data.unsatisfiedDependencies[i]));
1101 b.append(LF);
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);
1109 b.append(LF);
1110 if (isVista())
1111 b.append(m_noPermissionVista);
1112 else
1113 b.append(m_noPermission);
1115 break;
1117 case GENERAL_ERROR:
1119 rtl::OUString & msg = m_generalErrors[p->index.generalError];
1120 b.append(m_failure);
1121 b.append(LF);
1122 b.append(msg.getLength() == 0 ? m_unknownError : msg);
1123 break;
1125 case SPECIFIC_ERROR:
1127 UpdateDialog::SpecificError & data = m_specificErrors[
1128 p->index.specificError];
1129 b.append(m_failure);
1130 b.append(LF);
1131 b.append(
1132 data.message.getLength() == 0
1133 ? m_unknownError : data.message);
1134 break;
1136 default:
1137 OSL_ASSERT(false);
1138 break;
1142 showDescription( b.makeStringAndClear(), bInserted );
1143 return 0;
1146 IMPL_LINK(UpdateDialog, allHandler, void *, EMPTYARG) {
1147 if (m_all.IsChecked()) {
1148 m_update.Enable();
1149 m_updates.Enable();
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)
1157 insertItem(
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)
1166 insertItem(
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)
1176 insertItem(
1177 i->name, LISTBOX_APPEND,
1178 UpdateDialog::Index::newSpecificError(n3++),
1179 SvLBoxButtonKind_staticImage);
1181 } else {
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
1190 // unspecified
1191 delete p;
1192 } else {
1193 ++i;
1197 if (m_updates.getItemCount() == 0)
1199 clearDescription();
1200 m_update.Disable();
1201 m_updates.Disable();
1202 if (m_checking.IsVisible())
1203 m_description.Disable();
1204 else
1205 showDescription(m_noInstallable,false);
1208 return 0;
1211 IMPL_LINK(UpdateDialog, okHandler, void *, EMPTYARG)
1213 //If users are going to update a shared extension then we need
1214 //to warn them
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);
1222 #if 0
1223 // TODO: check!
1224 OSL_ASSERT(m_extensionManagerDialog.get());
1225 if (RET_CANCEL == m_extensionManagerDialog->continueUpdateForSharedExtension(
1226 this, i->aPackageManager))
1228 EndDialog(RET_CANCEL);
1230 #endif
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]);
1241 EndDialog(RET_OK);
1242 return 0;
1245 IMPL_LINK(UpdateDialog, cancelHandler, void *, EMPTYARG) {
1246 m_thread->stop();
1247 EndDialog(RET_CANCEL);
1248 return 0;
1251 IMPL_LINK( UpdateDialog, hyperlink_clicked, svt::FixedHyperlink*, pHyperlink )
1253 ::rtl::OUString sURL;
1254 if ( pHyperlink )
1255 sURL = ::rtl::OUString( pHyperlink->GetURL() );
1256 if ( sURL.getLength() == 0 )
1257 return 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& )
1273 return 1;