28 #include <com/sun/star/beans/NamedValue.hpp>
29 #include <com/sun/star/beans/PropertyValue.hpp>
30 #include <com/sun/star/beans/XPropertySet.hpp>
31 #include <com/sun/star/configuration/theDefaultProvider.hpp>
32 #include <com/sun/star/container/XNameAccess.hpp>
33 #include <com/sun/star/deployment/UpdateInformationProvider.hpp>
34 #include <com/sun/star/deployment/ExtensionManager.hpp>
35 #include <com/sun/star/deployment/XUpdateInformationProvider.hpp>
36 #include <com/sun/star/frame/Desktop.hpp>
37 #include <com/sun/star/frame/XDispatch.hpp>
38 #include <com/sun/star/frame/XDispatchProvider.hpp>
39 #include <com/sun/star/lang/IllegalArgumentException.hpp>
40 #include <com/sun/star/task/InteractionHandler.hpp>
41 #include <com/sun/star/ucb/CommandFailedException.hpp>
42 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
43 #include <com/sun/star/uno/Any.hxx>
44 #include <com/sun/star/uno/Exception.hpp>
45 #include <com/sun/star/uno/Reference.hxx>
46 #include <com/sun/star/uno/Sequence.hxx>
47 #include <com/sun/star/util/URL.hpp>
48 #include <com/sun/star/util/URLTransformer.hpp>
49 #include <com/sun/star/util/XURLTransformer.hpp>
50 #include <com/sun/star/xml/dom/XElement.hpp>
51 #include <osl/diagnose.h>
52 #include <rtl/ref.hxx>
53 #include <rtl/ustrbuf.hxx>
54 #include <rtl/ustring.hxx>
70 #include <strings.hrc>
78 class XComponentContext;
89 #define IGNORED_UPDATES OUString("/org.openoffice.Office.ExtensionManager/ExtensionUpdateData/IgnoredUpdates")
90 #define PROPERTY_VERSION "Version"
92 enum Kind { ENABLED_UPDATE, DISABLED_UPDATE, SPECIFIC_ERROR };
94 OUString confineToParagraph(OUString
const & text) {
99 return text.replace(LF,
' ').replace(CR,
' ');
120 IgnoredUpdate(
const OUString &rExtensionID,
const OUString &rVersion );
125 sExtensionID( rExtensionID ),
137 Index(
Kind theKind, sal_uInt16 nIndex,
const OUString &rName ) :
148 uno::Reference< uno::XComponentContext >
const & context,
150 const std::vector< uno::Reference< deployment::XPackage > > & vExtensionList);
157 virtual void execute()
override;
160 uno::Reference< deployment::XPackage >
const &
package,
167 css::uno::Reference< css::xml::dom::XNode >
const & updateInfo,
186 uno::Reference< uno::XComponentContext >
const & context,
188 const std::vector< uno::Reference< deployment::XPackage > > &vExtensionList):
210 m_updateInformation->cancel();
215 if ( m_xInteractionHdl.is() )
216 m_updateInformation->setInteractionHandler( uno::Reference< task::XInteractionHandler > () );
227 uno::Reference<deployment::XExtensionManager> extMgr =
228 deployment::ExtensionManager::get(m_context);
230 std::vector<std::pair<uno::Reference<deployment::XPackage>,
uno::Any > > errors;
235 for (
auto const& elem : errors)
236 handleSpecificError(elem.first, elem.second);
238 for (
auto const& updateInfo : updateInfoMap)
244 prepareUpdateData(info.
info, disableUpdate, updateData);
247 OUString sOnlineVersion;
250 OUString sVersionUser;
251 OUString sVersionShared;
252 OUString sVersionBundled;
253 uno::Sequence< uno::Reference< deployment::XPackage> >
extensions;
255 extensions = extMgr->getExtensionsWithSameIdentifier(
257 uno::Reference<ucb::XCommandEnvironment>());
258 }
catch (
const lang::IllegalArgumentException& ) {
261 }
catch (
const css::ucb::CommandFailedException& ) {
271 sVersionBundled =
extensions[2]->getVersion();
273 bool bSharedReadOnly = extMgr->isReadOnlyRepository(
"shared");
276 bSharedReadOnly, sVersionUser, sVersionShared, sVersionBundled, sOnlineVersion);
278 bSharedReadOnly, sVersionShared, sVersionBundled, sOnlineVersion);
285 updateData.updateVersion =
extensions[1]->getVersion();
290 updateData.updateVersion =
extensions[2]->getVersion();
292 if (!
update(disableUpdate, updateData))
301 updateData.updateVersion =
extensions[2]->getVersion();
303 updateData.bIsShared =
true;
304 if (!
update(disableUpdate, updateData))
312 m_dialog.checkingDone();
318 uno::Reference< deployment::XPackage >
const &
package,
323 data.
name = package->getDisplayName();
325 if (exception >>= e) {
330 m_dialog.addSpecificError(data);
343 b.append(m_dialog.m_version);
346 if (!version.empty())
357 b.append(m_dialog.m_browserbased);
360 return b.makeStringAndClear();
366 uno::Reference< xml::dom::XNode >
const & updateInfo,
370 if (!updateInfo.is())
374 uno::Sequence< uno::Reference< xml::dom::XElement > > ds(
379 for (sal_Int32
i = 0;
i < ds.getLength(); ++
i) {
385 out_du.
name = getUpdateDisplayString(out_data, infoset.
getVersion());
391 if (updateWebsiteURL)
405 m_dialog.addEnabledUpdate(getUpdateDisplayString(data), data);
411 m_dialog.addDisabledUpdate(du);
419 UpdateDialog::UpdateDialog(
420 uno::Reference< uno::XComponentContext >
const & context,
421 weld::Window * parent,
const std::vector<uno::Reference< deployment::XPackage > > &vExtensionList,
422 std::vector< dp_gui::UpdateData > * updateData)
423 : GenericDialogController(parent,
"desktop/ui/updatedialog.ui",
"UpdateDialog")
425 , m_none(
DpResId(RID_DLG_UPDATE_NONE))
426 , m_noInstallable(
DpResId(RID_DLG_UPDATE_NOINSTALLABLE))
427 , m_failure(
DpResId(RID_DLG_UPDATE_FAILURE))
428 , m_unknownError(
DpResId(RID_DLG_UPDATE_UNKNOWNERROR))
429 , m_noDescription(
DpResId(RID_DLG_UPDATE_NODESCRIPTION))
430 , m_noInstall(
DpResId(RID_DLG_UPDATE_NOINSTALL))
431 , m_noDependency(
DpResId(RID_DLG_UPDATE_NODEPENDENCY))
432 , m_noDependencyCurVer(
DpResId(RID_DLG_UPDATE_NODEPENDENCY_CUR_VER))
433 , m_browserbased(
DpResId(RID_DLG_UPDATE_BROWSERBASED))
434 , m_version(
DpResId(RID_DLG_UPDATE_VERSION))
435 , m_ignoredUpdate(
DpResId(RID_DLG_UPDATE_IGNORED_UPDATE))
436 , m_updateData(*updateData)
438 , m_xChecking(m_xBuilder->weld_label(
"UPDATE_CHECKING"))
439 , m_xThrobber(m_xBuilder->weld_spinner(
"THROBBER"))
440 , m_xUpdate(m_xBuilder->weld_label(
"UPDATE_LABEL"))
441 , m_xUpdates(m_xBuilder->weld_tree_view(
"checklist"))
442 , m_xAll(m_xBuilder->weld_check_button(
"UPDATE_ALL"))
443 , m_xDescription(m_xBuilder->weld_label(
"DESCRIPTION_LABEL"))
444 , m_xPublisherLabel(m_xBuilder->weld_label(
"PUBLISHER_LABEL"))
445 , m_xPublisherLink(m_xBuilder->weld_link_button(
"PUBLISHER_LINK"))
446 , m_xReleaseNotesLabel(m_xBuilder->weld_label(
"RELEASE_NOTES_LABEL"))
447 , m_xReleaseNotesLink(m_xBuilder->weld_link_button(
"RELEASE_NOTES_LINK"))
448 , m_xDescriptions(m_xBuilder->weld_text_view(
"DESCRIPTIONS"))
449 , m_xOk(m_xBuilder->weld_button(
"ok"))
450 , m_xClose(m_xBuilder->weld_button(
"close"))
451 , m_xHelp(m_xBuilder->weld_button(
"help"))
453 auto nWidth = m_xDescriptions->get_approximate_digit_width() * 62;
454 auto nHeight = m_xDescriptions->get_height_rows(8);
455 m_xDescriptions->set_size_request(nWidth, nHeight);
456 m_xUpdates->set_size_request(nWidth, nHeight);
460 OSL_ASSERT(updateData !=
nullptr);
462 m_xExtensionManager = deployment::ExtensionManager::get( context );
470 m_xHelp->set_sensitive(
false);
476 UpdateDialog::~UpdateDialog()
480 short UpdateDialog::run() {
481 m_xThrobber->start();
483 short nRet = GenericDialogController::run();
492 if (p->
m_eKind == SPECIFIC_ERROR)
500 int nEntry = m_xUpdates->n_children();
501 m_xUpdates->append();
503 m_xUpdates->set_text(nEntry, pEntry->
m_aName, 0);
504 m_xUpdates->set_id(nEntry, OUString::number(reinterpret_cast<sal_Int64>(pEntry)));
509 m_xAll->set_sensitive(
true);
510 if (m_xAll->get_active())
512 insertItem(index, bEnabledCheckBox);
513 m_xUpdate->set_sensitive(
true);
514 m_xUpdates->set_sensitive(
true);
515 m_xDescription->set_sensitive(
true);
516 m_xDescriptions->set_sensitive(
true);
520 void UpdateDialog::addEnabledUpdate( OUString
const & name,
523 sal_uInt16
nIndex = sal::static_int_cast< sal_uInt16 >( m_enabledUpdates.size() );
526 m_enabledUpdates.push_back( data );
527 m_ListboxEntries.emplace_back( pEntry );
529 if (!isIgnoredUpdate(pEntry))
531 insertItem(pEntry,
true);
534 addAdditional(pEntry,
false);
536 m_xUpdate->set_sensitive(
true);
537 m_xUpdates->set_sensitive(
true);
538 m_xDescription->set_sensitive(
true);
539 m_xDescriptions->set_sensitive(
true);
544 sal_uInt16
nIndex = sal::static_int_cast< sal_uInt16 >( m_disabledUpdates.size() );
547 m_disabledUpdates.push_back( data );
548 m_ListboxEntries.emplace_back( pEntry );
550 isIgnoredUpdate( pEntry );
551 addAdditional(pEntry,
false);
556 sal_uInt16
nIndex = sal::static_int_cast< sal_uInt16 >( m_specificErrors.size() );
559 m_specificErrors.push_back( data );
560 m_ListboxEntries.emplace_back( pEntry );
562 addAdditional(pEntry,
false);
565 void UpdateDialog::checkingDone() {
569 if (m_xUpdates->n_children() == 0)
572 m_xDescription->set_sensitive(
true);
573 m_xDescriptions->set_sensitive(
true);
575 if ( m_disabledUpdates.empty() && m_specificErrors.empty() && m_ignoredUpdates.empty() )
576 showDescription( m_none );
578 showDescription( m_noInstallable );
584 void UpdateDialog::enableOk() {
585 if (!m_xChecking->get_visible()) {
591 m_xOk->set_sensitive(nChecked != 0);
596 void UpdateDialog::createNotifyJob(
bool bPrepareOnly,
597 uno::Sequence< uno::Sequence< OUString > >
const &rItemList )
605 uno::Reference< lang::XMultiServiceFactory > xConfigProvider(
606 configuration::theDefaultProvider::get(
609 beans::PropertyValue aProperty;
610 aProperty.Name =
"nodepath";
611 aProperty.Value <<= OUString(
"org.openoffice.Office.Addons/AddonUI/OfficeHelp/UpdateCheckJob");
613 uno::Sequence< uno::Any > aArgumentList( 1 );
614 aArgumentList[0] <<= aProperty;
616 uno::Reference< container::XNameAccess > xNameAccess(
617 xConfigProvider->createInstanceWithArguments(
618 "com.sun.star.configuration.ConfigurationAccess", aArgumentList ),
619 uno::UNO_QUERY_THROW );
622 xNameAccess->getByName(
"URL") >>= aURL.Complete;
627 xTransformer->parseStrict(aURL);
630 uno::Reference< frame::XDispatchProvider > xDispatchProvider( xDesktop->getCurrentFrame(),
631 uno::UNO_QUERY_THROW );
632 uno::Reference< frame::XDispatch >
xDispatch = xDispatchProvider->queryDispatch(aURL, OUString(), 0);
636 uno::Sequence< beans::PropertyValue > aPropList(2);
637 aProperty.Name =
"updateList";
638 aProperty.Value <<= rItemList;
639 aPropList[0] = aProperty;
640 aProperty.Name =
"prepareOnly";
641 aProperty.Value <<= bPrepareOnly;
642 aPropList[1] = aProperty;
644 xDispatch->dispatch(aURL, aPropList );
647 catch(
const uno::Exception& e )
650 + e.Message +
"\n thread terminated.\n\n");
655 void UpdateDialog::notifyMenubar(
bool bPrepareOnly,
bool bRecheckOnly )
660 uno::Sequence< uno::Sequence< OUString > > aItemList;
662 if ( ! bRecheckOnly )
665 for (sal_uInt16
i = 0, nItemCount = m_xUpdates->n_children();
i < nItemCount; ++
i)
667 uno::Sequence< OUString > aItem(2);
671 if ( p->
m_eKind == ENABLED_UPDATE )
682 aItemList.realloc( nCount + 1 );
683 aItemList[ nCount ] = aItem;
688 createNotifyJob( bPrepareOnly, aItemList );
693 void UpdateDialog::initDescription()
695 m_xPublisherLabel->hide();
696 m_xPublisherLink->hide();
697 m_xReleaseNotesLabel->hide();
698 m_xReleaseNotesLink->hide();
701 void UpdateDialog::clearDescription()
703 m_xPublisherLabel->hide();
704 m_xPublisherLink->hide();
705 m_xPublisherLink->set_label(
"");
706 m_xPublisherLink->set_uri(
"");
707 m_xReleaseNotesLabel->hide();
708 m_xReleaseNotesLink->hide();
709 m_xReleaseNotesLink->set_uri(
"" );
710 m_xDescriptions->set_text(
"");
713 bool UpdateDialog::showDescription(uno::Reference< xml::dom::XNode >
const & aUpdateInfo)
716 return showDescription(infoset.getLocalizedPublisherNameAndURL(),
717 infoset.getLocalizedReleaseNotesURL());
720 bool UpdateDialog::showDescription(uno::Reference< deployment::XPackage >
const & aExtension)
722 OSL_ASSERT(aExtension.is());
723 beans::StringPair pubInfo = aExtension->getPublisherInfo();
724 return showDescription(std::make_pair(pubInfo.First, pubInfo.Second),
728 bool UpdateDialog::showDescription(std::pair< OUString, OUString >
const & pairPublisher,
729 OUString
const & sReleaseNotes)
731 OUString sPub = pairPublisher.first;
732 OUString sURL = pairPublisher.second;
734 if ( sPub.isEmpty() && sURL.isEmpty() && sReleaseNotes.isEmpty() )
738 if ( !sPub.isEmpty() )
740 m_xPublisherLabel->show();
741 m_xPublisherLink->show();
742 m_xPublisherLink->set_label(sPub);
743 m_xPublisherLink->set_uri(sURL);
746 if ( !sReleaseNotes.isEmpty() )
748 m_xReleaseNotesLabel->show();
749 m_xReleaseNotesLink->show();
750 m_xReleaseNotesLink->set_uri( sReleaseNotes );
755 bool UpdateDialog::showDescription(
const OUString& rDescription)
757 if ( rDescription.isEmpty() )
761 m_xDescriptions->set_text(rDescription);
765 void UpdateDialog::getIgnoredUpdates()
767 uno::Reference< lang::XMultiServiceFactory > xConfig(
768 configuration::theDefaultProvider::get(m_context));
770 uno::Sequence< uno::Any >
args(1);
773 uno::Reference< container::XNameAccess > xNameAccess( xConfig->createInstanceWithArguments(
"com.sun.star.configuration.ConfigurationAccess", args), uno::UNO_QUERY_THROW );
774 const uno::Sequence< OUString > aElementNames = xNameAccess->getElementNames();
776 for ( OUString
const & aIdentifier : aElementNames )
781 aPropValue >>= aVersion;
783 m_ignoredUpdates.emplace_back( pData );
790 bool bIsIgnored =
false;
792 if (! m_ignoredUpdates.empty() )
794 OUString aExtensionID;
797 if ( index->
m_eKind == ENABLED_UPDATE )
803 else if ( index->
m_eKind == DISABLED_UPDATE )
813 for (
auto const& ignoredUpdate : m_ignoredUpdates)
815 if ( ignoredUpdate->sExtensionID == aExtensionID )
817 if ( ( !ignoredUpdate->sVersion.isEmpty() ) || ( ignoredUpdate->sVersion == aVersion ) )
834 int nSelectedPos = m_xUpdates->get_selected_index();
838 if (nSelectedPos != -1)
839 p =
reinterpret_cast<UpdateDialog::Index const *
>(m_xUpdates->get_id(nSelectedPos).toInt64());
848 if ( m_enabledUpdates[ pos ].aUpdateSource.is() )
849 showDescription( m_enabledUpdates[ pos ].aUpdateSource );
851 showDescription( m_enabledUpdates[ pos ].aUpdateInfo );
854 b.append( m_ignoredUpdate );
858 case DISABLED_UPDATE:
860 if ( !m_disabledUpdates.empty() )
861 showDescription( m_disabledUpdates[pos].aUpdateInfo );
864 b.append( m_ignoredUpdate );
866 if ( m_disabledUpdates.empty() )
873 OUString sVersion(
"%VERSION" );
874 OUString sProductName(
"%PRODUCTNAME" );
875 sal_Int32
nPos = m_noDependencyCurVer.indexOf( sVersion );
880 nPos = m_noDependencyCurVer.indexOf( sProductName );
885 nPos = m_noDependency.indexOf( sProductName );
891 b.append(m_noInstall);
893 b.append(m_noDependency);
894 for (sal_Int32
i = 0;
907 b.append(m_noDependencyCurVer);
916 b.append( data.
message.isEmpty() ? m_unknownError : data.
message );
926 b.append( m_noDescription );
928 showDescription( b.makeStringAndClear() );
933 if (m_xAll->get_active())
935 m_xUpdate->set_sensitive(
true);
936 m_xUpdates->set_sensitive(
true);
937 m_xDescription->set_sensitive(
true);
938 m_xDescriptions->set_sensitive(
true);
940 for (
auto const& listboxEntry : m_ListboxEntries)
942 if ( listboxEntry->m_bIgnored || ( listboxEntry->m_eKind != ENABLED_UPDATE ) )
943 insertItem(listboxEntry.get(),
false);
948 for (sal_uInt16
i = m_xUpdates->n_children();
i != 0 ;)
954 m_xUpdates->remove(
i);
958 if (m_xUpdates->n_children() == 0)
961 m_xUpdate->set_sensitive(
false);
962 m_xUpdates->set_sensitive(
false);
963 if (m_xChecking->get_visible())
964 m_xDescription->set_sensitive(
false);
966 showDescription(m_noInstallable);
975 for (
auto const& enableUpdate : m_enabledUpdates)
977 OSL_ASSERT(enableUpdate.aInstalledPackage.is());
983 for (sal_uInt16
i = 0,
nCount = m_xUpdates->n_children();
i <
nCount; ++
i)
987 m_xUpdates->get_id(
i).toInt64());
989 m_updateData.push_back( m_enabledUpdates[ p->
m_nIndex ] );
uno::Reference< task::XInteractionHandler > m_xInteractionHdl
#define LINK(Instance, Class, Member)
css::uno::Reference< css::deployment::XPackage > aInstalledPackage
css::uno::Reference< css::xml::dom::XNode > aUpdateInfo
std::map< OUString, UpdateInfo > UpdateInfoMap
virtual css::uno::Reference< css::awt::XWindow > GetXWindow()=0
void prepareUpdateData(css::uno::Reference< css::xml::dom::XNode > const &updateInfo, UpdateDialog::DisabledUpdate &out_du, dp_gui::UpdateData &out_data) const
out_data will only be filled if all dependencies are ok.
uno::Reference< deployment::XUpdateInformationProvider > m_updateInformation
css::uno::Reference< css::xml::dom::XNode > aUpdateInfo
std::unique_ptr< ContentProperties > pData
uno::Reference< uno::XComponentContext > m_context
virtual ~Thread() override
const ContentProperties & rData
virtual Dialog * getDialog() override
css::uno::Reference< css::deployment::XPackageRegistry > create(css::uno::Reference< css::deployment::XPackageRegistry > const &xRootRegistry, OUString const &context, OUString const &cachePath, css::uno::Reference< css::uno::XComponentContext > const &xComponentContext)
Thread(uno::Reference< uno::XComponentContext > const &context, UpdateDialog &dialog, const std::vector< uno::Reference< deployment::XPackage > > &vExtensionList)
OUString getVersion() const
Return the textual version representation.
IMPL_LINK_NOARG(UpdateDialog, selectionHandler, weld::TreeView &, void)
OUString getUpdateDisplayString(dp_gui::UpdateData const &data, std::u16string_view version=std::u16string_view()) const
std::vector< uno::Reference< deployment::XPackage > > m_vExtensionList
std::pair< const TreeIter &, int > iter_col
bool getPropertyValue(ValueType &rValue, css::uno::Reference< css::beans::XPropertySet > const &xPropSet, OUString const &propName)
std::vector< uno::Reference< deployment::XPackage > > m_vExtensionList
void handleSpecificError(uno::Reference< deployment::XPackage > const &package, uno::Any const &exception) const
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC UPDATE_SOURCE isUpdateSharedExtension(bool bReadOnlyShared, OUString const &sharedVersion, OUString const &bundledVersion, OUString const &onlineVersion)
static OUString getProductName()
::std::optional< OUString > getIdentifier() const
Return the identifier.
css::uno::Reference< css::xml::dom::XNode > info
The modal “Check for Updates” dialog.
static OUString getAboutBoxProductVersion()
exports com.sun.star.chart2. data
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC UPDATE_SOURCE isUpdateUserExtension(bool bReadOnlyShared, OUString const &userVersion, OUString const &sharedVersion, OUString const &bundledVersion, OUString const &onlineVersion)
static uno::Reference< css::uno::XComponentContext > xContext
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC UpdateInfoMap getOnlineUpdateInfos(css::uno::Reference< css::uno::XComponentContext > const &xContext, css::uno::Reference< css::deployment::XExtensionManager > const &xExtMgr, css::uno::Reference< css::deployment::XUpdateInformationProvider > const &updateInformation, std::vector< css::uno::Reference< css::deployment::XPackage > > const *extensionList, std::vector< std::pair< css::uno::Reference< css::deployment::XPackage >, css::uno::Any > > &out_errors)
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC css::uno::Sequence< css::uno::Reference< css::xml::dom::XElement > > check(dp_misc::DescriptionInfoset const &infoset)
Check for unsatisfied dependencies.
void TRACE(OUString const &sText)
print the text to the console in a debug build.
Reference< XDispatch > xDispatch
IgnoredUpdate(const OUString &rExtensionID, const OUString &rVersion)
css::uno::Reference< css::deployment::XPackage > extension
IMPL_LINK(UpdateDialog, entryToggled, const weld::TreeView::iter_col &, rRowCol, void)
Reference< XExecutableDialog > m_xDialog
Reference< XComponentContext > getProcessComponentContext()
virtual void execute() override
bool update(UpdateDialog::DisabledUpdate const &du, dp_gui::UpdateData const &data) const
OUString DpResId(const char *pId)
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC OUString getErrorText(css::uno::Reference< css::xml::dom::XElement > const &dependency)
Obtain the (human-readable) error message of a failed dependency.
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC OUString getIdentifier(css::uno::Reference< css::deployment::XPackage > const &package)
Gets the identifier of a package.
Index(Kind theKind, sal_uInt16 nIndex, const OUString &rName)
uno::Sequence< OUString > unsatisfiedDependencies
::std::optional< OUString > getLocalizedUpdateWebsiteURL() const
returns the download website URL from the update information.
Access to the content of an XML description element.