LibreOffice Module desktop (master) 1
dp_gui_updateinstalldialog.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20
21#include "dp_gui_updatedata.hxx"
22
23#include <sal/config.h>
24#include <osl/file.hxx>
26#include <utility>
27#include <vcl/svapp.hxx>
29
30#include <com/sun/star/beans/NamedValue.hpp>
31#include <com/sun/star/lang/WrappedTargetException.hpp>
32#include <com/sun/star/ucb/NameClash.hpp>
33#include <com/sun/star/ucb/XCommandEnvironment.hpp>
34#include <com/sun/star/ucb/XProgressHandler.hpp>
35#include <com/sun/star/deployment/DeploymentException.hpp>
36#include <com/sun/star/deployment/ExtensionManager.hpp>
37#include <com/sun/star/deployment/LicenseException.hpp>
38#include <com/sun/star/deployment/VersionException.hpp>
39#include <com/sun/star/task/XInteractionHandler.hpp>
40#include <com/sun/star/task/XInteractionApprove.hpp>
41
43#include <strings.hrc>
45#include <dp_shared.hxx>
46#include <dp_ucb.h>
47#include <dp_misc.h>
49#include <ucbhelper/content.hxx>
50#include <rtl/ustrbuf.hxx>
51#include <rtl/ref.hxx>
52#include <salhelper/thread.hxx>
53#include <com/sun/star/uno/Sequence.h>
55
56#include <string_view>
57#include <vector>
58
60
61namespace dp_gui {
62
64 friend class UpdateCommandEnv;
65public:
66 Thread(css::uno::Reference< css::uno::XComponentContext > const & ctx,
67 UpdateInstallDialog & dialog, std::vector< dp_gui::UpdateData > & aVecUpdateData);
68
69 void stop();
70
71private:
72 virtual ~Thread() override;
73
74 virtual void execute() override;
75 void downloadExtensions();
76 bool download(OUString const & aUrls, UpdateData & aUpdatData);
77 void installExtensions();
79
81
82 // guarded by Application::GetSolarMutex():
83 css::uno::Reference< css::task::XAbortChannel > m_abort;
84 css::uno::Reference< css::uno::XComponentContext > m_xComponentContext;
85 std::vector< dp_gui::UpdateData > & m_aVecUpdateData;
87
88 //A folder which is created in the temp directory in which then the updates are downloaded
90
91 bool m_stop;
92
93};
94
96 : public ::cppu::WeakImplHelper< css::ucb::XCommandEnvironment,
97 css::task::XInteractionHandler,
98 css::ucb::XProgressHandler >
99{
101
103 css::uno::Reference< css::uno::XComponentContext > m_xContext;
104
105public:
106 UpdateCommandEnv( css::uno::Reference< css::uno::XComponentContext > xCtx,
108
109 // XCommandEnvironment
110 virtual css::uno::Reference<css::task::XInteractionHandler > SAL_CALL
111 getInteractionHandler() override;
112 virtual css::uno::Reference<css::ucb::XProgressHandler >
113 SAL_CALL getProgressHandler() override;
114
115 // XInteractionHandler
116 virtual void SAL_CALL handle(
117 css::uno::Reference<css::task::XInteractionRequest > const & xRequest ) override;
118
119 // XProgressHandler
120 virtual void SAL_CALL push( css::uno::Any const & Status ) override;
121 virtual void SAL_CALL update( css::uno::Any const & Status ) override;
122 virtual void SAL_CALL pop() override;
123};
124
125
127 css::uno::Reference< css::uno::XComponentContext> const & xCtx,
128 UpdateInstallDialog & dialog,
129 std::vector< dp_gui::UpdateData > & aVecUpdateData):
130 salhelper::Thread("dp_gui_updateinstalldialog"),
131 m_dialog(dialog),
133 m_aVecUpdateData(aVecUpdateData),
134 m_updateCmdEnv(new UpdateCommandEnv(xCtx, this)),
135 m_stop(false)
136{}
137
139 css::uno::Reference< css::task::XAbortChannel > abort;
140 {
142 abort = m_abort;
143 m_stop = true;
144 }
145 if (abort.is()) {
146 abort->sendAbort();
147 }
148}
149
151
153{
154 try {
155 downloadExtensions();
156 installExtensions();
157 }
158 catch (...)
159 {
160 }
161
162 //clean up the temp directories
163 try {
164 removeTempDownloads();
165 } catch( ... ) {
166 }
167
168 {
169 //make sure m_dialog is still alive
171 if (! m_stop)
172 m_dialog.updateDone();
173 }
174 //UpdateCommandEnv keeps a reference to Thread and prevents destruction. Therefore remove it.
175 m_updateCmdEnv->m_installThread.clear();
176}
177
179 weld::Window* pParent,
180 std::vector<dp_gui::UpdateData> & aVecUpdateData,
181 css::uno::Reference< css::uno::XComponentContext > const & xCtx)
182 : GenericDialogController(pParent, "desktop/ui/updateinstalldialog.ui",
183 "UpdateInstallDialog")
184 , m_thread(new Thread(xCtx, *this, aVecUpdateData))
185 , m_bError(false)
186 , m_bNoEntry(true)
187 , m_sInstalling(DpResId(RID_DLG_UPDATE_INSTALL_INSTALLING))
188 , m_sFinished(DpResId(RID_DLG_UPDATE_INSTALL_FINISHED))
189 , m_sNoErrors(DpResId(RID_DLG_UPDATE_INSTALL_NO_ERRORS))
190 , m_sErrorDownload(DpResId(RID_DLG_UPDATE_INSTALL_ERROR_DOWNLOAD))
191 , m_sErrorInstallation(DpResId(RID_DLG_UPDATE_INSTALL_ERROR_INSTALLATION))
192 , m_sErrorLicenseDeclined(DpResId(RID_DLG_UPDATE_INSTALL_ERROR_LIC_DECLINED))
193 , m_sNoInstall(DpResId(RID_DLG_UPDATE_INSTALL_EXTENSION_NOINSTALL))
194 , m_sThisErrorOccurred(DpResId(RID_DLG_UPDATE_INSTALL_THIS_ERROR_OCCURRED))
195 , m_xFt_action(m_xBuilder->weld_label("DOWNLOADING"))
196 , m_xStatusbar(m_xBuilder->weld_progress_bar("STATUSBAR"))
197 , m_xFt_extension_name(m_xBuilder->weld_label("EXTENSION_NAME"))
198 , m_xMle_info(m_xBuilder->weld_text_view("INFO"))
199 , m_xHelp(m_xBuilder->weld_button("help"))
200 , m_xOk(m_xBuilder->weld_button("ok"))
201 , m_xCancel(m_xBuilder->weld_button("cancel"))
202{
203 m_xMle_info->set_size_request(m_xMle_info->get_approximate_digit_width() * 52,
204 m_xMle_info->get_height_rows(5));
205
206 m_xExtensionManager = css::deployment::ExtensionManager::get( xCtx );
207
208 m_xCancel->connect_clicked(LINK(this, UpdateInstallDialog, cancelHandler));
210 m_xHelp->set_sensitive(false);
211}
212
214{
215}
216
218{
219 m_thread->launch();
220 short nRet = GenericDialogController::run();
221 m_thread->stop();
222 return nRet;
223}
224
225// make sure the solar mutex is locked before calling
227{
228 if (!m_bError)
229 m_xMle_info->set_text(m_xMle_info->get_text() + m_sNoErrors);
230 m_xOk->set_sensitive(true);
231 m_xOk->grab_focus();
232 m_xCancel->set_sensitive(false);
233}
234
235// make sure the solar mutex is locked before calling
236//sets an error message in the text area
237void UpdateInstallDialog::setError(INSTALL_ERROR err, std::u16string_view sExtension,
238 std::u16string_view exceptionMessage)
239{
240 OUString sError;
241 m_bError = true;
242
243 switch (err)
244 {
245 case ERROR_DOWNLOAD:
246 sError = m_sErrorDownload;
247 break;
249 sError = m_sErrorInstallation;
250 break;
253 break;
254
255 default:
256 OSL_ASSERT(false);
257 }
258
259 OUString sMsg(m_xMle_info->get_text());
260 sError = sError.replaceFirst("%NAME", sExtension);
261 //We want to have an empty line between the error messages. However,
262 //there shall be no empty line after the last entry.
263 if (m_bNoEntry)
264 m_bNoEntry = false;
265 else
266 sMsg += "\n";
267 sMsg += sError;
268 //Insert more information about the error
269 if (!exceptionMessage.empty())
270 sMsg += m_sThisErrorOccurred + exceptionMessage + "\n";
271
272 sMsg += m_sNoInstall + "\n";
273
274 m_xMle_info->set_text(sMsg);
275}
276
277void UpdateInstallDialog::setError(std::u16string_view exceptionMessage)
278{
279 m_bError = true;
280 m_xMle_info->set_text(m_xMle_info->get_text() + exceptionMessage + "\n");
281}
282
284{
285 m_xDialog->response(RET_CANCEL);
286}
287
289{
290 try
291 {
292 //create the download directory in the temp folder
293 OUString sTempDir;
294 if (::osl::FileBase::getTempDirURL(sTempDir) != ::osl::FileBase::E_None)
295 throw css::uno::Exception("Could not get URL for the temp directory. No extensions will be installed.", nullptr);
296
297 //create a unique name for the directory
298 OUString tempEntry, destFolder;
299 if (::osl::File::createTempFile(&sTempDir, nullptr, &tempEntry ) != ::osl::File::E_None)
300 throw css::uno::Exception("Could not create a temporary file in " + sTempDir +
301 ". No extensions will be installed", nullptr );
302
303 tempEntry = tempEntry.copy( tempEntry.lastIndexOf( '/' ) + 1 );
304
305 destFolder = dp_misc::makeURL( sTempDir, tempEntry ) + "_";
306 m_sDownloadFolder = destFolder;
307 try
308 {
309 dp_misc::create_folder(nullptr, destFolder, m_updateCmdEnv );
310 } catch (const css::uno::Exception & e)
311 {
312 css::uno::Any anyEx = cppu::getCaughtException();
313 throw css::lang::WrappedTargetException( e.Message + " No extensions will be installed",
314 nullptr, anyEx );
315 }
316
317
318 sal_uInt16 count = 0;
319 for (auto & updateData : m_aVecUpdateData)
320 {
321 if (!updateData.aUpdateInfo.is() || updateData.aUpdateSource.is())
322 continue;
323 //We assume that m_aVecUpdateData contains only information about extensions which
324 //can be downloaded directly.
325 OSL_ASSERT(updateData.sWebsiteURL.isEmpty());
326
327 //update the name of the extension which is to be downloaded
328 {
330 if (m_stop) {
331 return;
332 }
333 m_dialog.m_xFt_extension_name->set_label(updateData.aInstalledPackage->getDisplayName());
334 sal_uInt16 prog = (sal::static_int_cast<sal_uInt16>(100) * ++count) /
335 sal::static_int_cast<sal_uInt16>(m_aVecUpdateData.size());
336 m_dialog.m_xStatusbar->set_percentage(prog);
337 }
338 dp_misc::DescriptionInfoset info(m_xComponentContext, updateData.aUpdateInfo);
339 //remember occurring exceptions in case we need to print out error information
340 std::vector< std::pair<OUString, css::uno::Exception> > vecExceptions;
341 css::uno::Sequence<OUString> seqDownloadURLs = info.getUpdateDownloadUrls();
342 OSL_ENSURE(seqDownloadURLs.hasElements(), "No download URL provided!");
343 for (sal_Int32 j = 0; j < seqDownloadURLs.getLength(); j++)
344 {
345 try
346 {
347 OSL_ENSURE(!seqDownloadURLs[j].isEmpty(), "Download URL is empty!");
348 bool bCancelled = download(seqDownloadURLs[j], updateData);
349 if (bCancelled || !updateData.sLocalURL.isEmpty())
350 break;
351 }
352 catch ( css::uno::Exception & e )
353 {
354 vecExceptions.emplace_back(seqDownloadURLs[j], e);
355 //There can be several different errors, for example, the URL is wrong, webserver cannot be reached,
356 //name cannot be resolved. The UCB helper API does not specify different special exceptions for these
357 //cases. Therefore ignore and continue.
358 continue;
359 }
360 }
361 //update the progress and display download error
362 {
364 if (m_stop) {
365 return;
366 }
367 if (updateData.sLocalURL.isEmpty())
368 {
369 //Construct a string of all messages contained in the exceptions plus the respective download URLs
370 OUStringBuffer buf(256);
371 size_t nPos = 0;
372 for (auto const& elem : vecExceptions)
373 {
374 if (nPos)
375 buf.append("\n");
376 buf.append("Could not download " + elem.first + ". " + elem.second.Message);
377 ++nPos;
378 }
379 m_dialog.setError(UpdateInstallDialog::ERROR_DOWNLOAD, updateData.aInstalledPackage->getDisplayName(),
380 buf);
381 }
382 }
383
384 }
385 }
386 catch (const css::uno::Exception & e)
387 {
389 if (m_stop) {
390 return;
391 }
392 m_dialog.setError(e.Message);
393 }
394}
395
397{
398 //Update the fix text in the dialog to "Installing extensions..."
399 {
401 if (m_stop) {
402 return;
403 }
404 m_dialog.m_xFt_action->set_label(m_dialog.m_sInstalling);
405 m_dialog.m_xStatusbar->set_percentage(0);
406 }
407
408 sal_uInt16 count = 0;
409 for (auto const& updateData : m_aVecUpdateData)
410 {
411 //update the name of the extension which is to be installed
412 {
414 if (m_stop) {
415 return;
416 }
417 //we only show progress after an extension has been installed.
418 if (count > 0) {
419 m_dialog.m_xStatusbar->set_percentage(
420 (sal::static_int_cast<sal_uInt16>(100) * count) /
421 sal::static_int_cast<sal_uInt16>(m_aVecUpdateData.size()));
422 }
423 m_dialog.m_xFt_extension_name->set_label(updateData.aInstalledPackage->getDisplayName());
424 }
425 bool bError = false;
426 bool bLicenseDeclined = false;
427 css::uno::Reference<css::deployment::XPackage> xExtension;
428 css::uno::Exception exc;
429 try
430 {
431 css::uno::Reference< css::task::XAbortChannel > xAbortChannel(
432 updateData.aInstalledPackage->createAbortChannel() );
433 {
435 if (m_stop) {
436 return;
437 }
438 m_abort = xAbortChannel;
439 }
440 if (!updateData.aUpdateSource.is() && !updateData.sLocalURL.isEmpty())
441 {
442 css::beans::NamedValue prop("EXTENSION_UPDATE", css::uno::Any(OUString("1")));
443 if (!updateData.bIsShared)
444 xExtension = m_dialog.getExtensionManager()->addExtension(
445 updateData.sLocalURL, css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
446 "user", xAbortChannel, m_updateCmdEnv);
447 else
448 xExtension = m_dialog.getExtensionManager()->addExtension(
449 updateData.sLocalURL, css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
450 "shared", xAbortChannel, m_updateCmdEnv);
451 }
452 else if (updateData.aUpdateSource.is())
453 {
454 OSL_ASSERT(updateData.aUpdateSource.is());
455 //I am not sure if we should obtain the install properties and pass them into
456 //add extension. Currently it contains only "SUPPRESS_LICENSE". So it could happen
457 //that a license is displayed when updating from the shared repository, although the
458 //shared extension was installed using "SUPPRESS_LICENSE".
459 css::beans::NamedValue prop("EXTENSION_UPDATE", css::uno::Any(OUString("1")));
460 if (!updateData.bIsShared)
461 xExtension = m_dialog.getExtensionManager()->addExtension(
462 updateData.aUpdateSource->getURL(), css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
463 "user", xAbortChannel, m_updateCmdEnv);
464 else
465 xExtension = m_dialog.getExtensionManager()->addExtension(
466 updateData.aUpdateSource->getURL(), css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
467 "shared", xAbortChannel, m_updateCmdEnv);
468 }
469 }
470 catch (css::deployment::DeploymentException & de)
471 {
472 if (de.Cause.has<css::deployment::LicenseException>())
473 {
474 bLicenseDeclined = true;
475 }
476 else
477 {
478 exc = de.Cause.get<css::uno::Exception>();
479 bError = true;
480 }
481 }
482 catch (css::uno::Exception& e)
483 {
484 exc = e;
485 bError = true;
486 }
487
488 if (bLicenseDeclined)
489 {
491 if (m_stop) {
492 return;
493 }
495 updateData.aInstalledPackage->getDisplayName(), std::u16string_view());
496 }
497 else if (!xExtension.is() || bError)
498 {
500 if (m_stop) {
501 return;
502 }
504 updateData.aInstalledPackage->getDisplayName(), exc.Message);
505 }
506 ++count;
507 }
508 {
510 if (m_stop) {
511 return;
512 }
513 m_dialog.m_xStatusbar->set_percentage(100);
514 m_dialog.m_xFt_extension_name->set_label(OUString());
515 m_dialog.m_xFt_action->set_label(m_dialog.m_sFinished);
516 }
517}
518
520{
521 if (!m_sDownloadFolder.isEmpty())
522 {
523 dp_misc::erase_path(m_sDownloadFolder,
524 css::uno::Reference<css::ucb::XCommandEnvironment>(),false /* no throw: ignore errors */ );
525 //remove also the temp file which we have used to create the unique name
526 OUString tempFile = m_sDownloadFolder.copy(0, m_sDownloadFolder.getLength() - 1);
527 dp_misc::erase_path(tempFile, css::uno::Reference<css::ucb::XCommandEnvironment>(),false);
528 m_sDownloadFolder.clear();
529 }
530}
531
532bool UpdateInstallDialog::Thread::download(OUString const & sDownloadURL, UpdateData & aUpdateData)
533{
534 {
536 if (m_stop) {
537 return m_stop;
538 }
539 }
540
541 OSL_ASSERT(m_sDownloadFolder.getLength());
542 OUString destFolder, tempEntry;
543 if (::osl::File::createTempFile(
544 &m_sDownloadFolder,
545 nullptr, &tempEntry ) != ::osl::File::E_None)
546 {
547 //ToDo feedback in window that download of this component failed
548 throw css::uno::Exception("Could not create temporary file in folder " + destFolder + ".", nullptr);
549 }
550 tempEntry = tempEntry.copy( tempEntry.lastIndexOf( '/' ) + 1 );
551
552 destFolder = dp_misc::makeURL( m_sDownloadFolder, tempEntry ) + "_";
553
554 ::ucbhelper::Content destFolderContent;
555 dp_misc::create_folder( &destFolderContent, destFolder, m_updateCmdEnv );
556
557 ::ucbhelper::Content sourceContent;
558 (void)dp_misc::create_ucb_content(&sourceContent, sDownloadURL, m_updateCmdEnv);
559
560 const OUString sTitle( StrTitle::getTitle( sourceContent ) );
561
562 destFolderContent.transferContent(
564 sTitle, css::ucb::NameClash::OVERWRITE );
565
566 {
567 //the user may have cancelled the dialog because downloading took too long
569 if (m_stop) {
570 return m_stop;
571 }
572 //all errors should be handled by the command environment.
573 aUpdateData.sLocalURL = destFolder + "/" + sTitle;
574 }
575
576 return m_stop;
577}
578
579UpdateCommandEnv::UpdateCommandEnv( css::uno::Reference< css::uno::XComponentContext > xCtx,
581 : m_installThread(std::move(thread)),
582 m_xContext(std::move(xCtx))
583{
584}
585
586// XCommandEnvironment
587css::uno::Reference<css::task::XInteractionHandler> UpdateCommandEnv::getInteractionHandler()
588{
589 return this;
590}
591
592css::uno::Reference<css::ucb::XProgressHandler> UpdateCommandEnv::getProgressHandler()
593{
594 return this;
595}
596
597// XInteractionHandler
599 css::uno::Reference< css::task::XInteractionRequest> const & xRequest )
600{
601 css::uno::Any request( xRequest->getRequest() );
602 OSL_ASSERT( request.getValueTypeClass() == css::uno::TypeClass_EXCEPTION );
603 dp_misc::TRACE("[dp_gui_cmdenv.cxx] incoming request:\n"
604 + ::comphelper::anyToString(request) + "\n\n");
605
606 css::deployment::VersionException verExc;
607 bool approve = false;
608
609 if (request >>= verExc)
610 { //We must catch the version exception during the update,
611 //because otherwise the user would be confronted with the dialogs, asking
612 //them if they want to replace an already installed version of the same extension.
613 //During an update we assume that we always want to replace the old version with the
614 //new version.
615 approve = true;
616 }
617
618 if (!approve)
619 {
620 //forward to interaction handler for main dialog.
622 }
623 else
624 {
625 // select:
626 css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > conts(
627 xRequest->getContinuations() );
628 css::uno::Reference< css::task::XInteractionContinuation > const * pConts =
629 conts.getConstArray();
630 sal_Int32 len = conts.getLength();
631 for ( sal_Int32 pos = 0; pos < len; ++pos )
632 {
633 if (approve) {
634 css::uno::Reference< css::task::XInteractionApprove > xInteractionApprove(
635 pConts[ pos ], css::uno::UNO_QUERY );
636 if (xInteractionApprove.is()) {
637 xInteractionApprove->select();
638 // don't query again for ongoing continuations:
639 approve = false;
640 }
641 }
642 }
643 }
644}
645
646// XProgressHandler
647void UpdateCommandEnv::push( css::uno::Any const & /*Status*/ )
648{
649}
650
651void UpdateCommandEnv::update( css::uno::Any const & /*Status */)
652{
653}
654
656{
657}
658
659
660} //end namespace dp_gui
661
662/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual void SAL_CALL handle(css::uno::Reference< css::task::XInteractionRequest > const &xRequest) override
virtual css::uno::Reference< css::ucb::XProgressHandler > SAL_CALL getProgressHandler() override
UpdateCommandEnv(css::uno::Reference< css::uno::XComponentContext > xCtx, ::rtl::Reference< UpdateInstallDialog::Thread > thread)
virtual void SAL_CALL update(css::uno::Any const &Status) override
virtual void SAL_CALL push(css::uno::Any const &Status) override
virtual void SAL_CALL pop() override
virtual css::uno::Reference< css::task::XInteractionHandler > SAL_CALL getInteractionHandler() override
css::uno::Reference< css::uno::XComponentContext > m_xContext
::rtl::Reference< UpdateInstallDialog::Thread > m_installThread
css::uno::Reference< css::uno::XComponentContext > m_xComponentContext
::rtl::Reference< UpdateCommandEnv > m_updateCmdEnv
bool download(OUString const &aUrls, UpdateData &aUpdatData)
Thread(css::uno::Reference< css::uno::XComponentContext > const &ctx, UpdateInstallDialog &dialog, std::vector< dp_gui::UpdateData > &aVecUpdateData)
css::uno::Reference< css::task::XAbortChannel > m_abort
std::vector< dp_gui::UpdateData > & m_aVecUpdateData
The modal “Download and Installation” dialog.
std::unique_ptr< weld::ProgressBar > m_xStatusbar
std::unique_ptr< weld::Label > m_xFt_extension_name
void setError(INSTALL_ERROR err, std::u16string_view sExtension, std::u16string_view exceptionMessage)
std::unique_ptr< weld::Button > m_xCancel
std::unique_ptr< weld::Label > m_xFt_action
std::unique_ptr< weld::Button > m_xHelp
std::unique_ptr< weld::TextView > m_xMle_info
std::unique_ptr< weld::Button > m_xOk
css::uno::Reference< css::deployment::XExtensionManager > m_xExtensionManager
UpdateInstallDialog(weld::Window *parent, std::vector< UpdateData > &aVecUpdateData, css::uno::Reference< css::uno::XComponentContext > const &xCtx)
Create an instance.
Access to the content of an XML description element.
css::uno::Sequence< OUString > getUpdateDownloadUrls() const
Return the download URLs from the update information.
void transferContent(const Content &rSourceContent, InsertOperation eOperation, const OUString &rTitle, const sal_Int32 nNameClashAction, const OUString &rMimeType=OUString(), bool bMajorVersion=false, const OUString &rCommentVersion=OUString(), OUString *pResultURL=nullptr, const OUString &rDocumentId=OUString()) const
std::shared_ptr< weld::Dialog > m_xDialog
GenericDialogController(weld::Widget *pParent, const OUString &rUIFile, const OUString &rDialogId, bool bMobile=false)
std::unique_ptr< weld::Builder > m_xBuilder
uno::Reference< uno::XComponentContext > m_xContext
Reference< XComponentContext > const m_xComponentContext
OUString DpResId(TranslateId aId)
Definition: dp_misc.cxx:555
sal_uInt16 nPos
err
Any SAL_CALL getCaughtException()
Definition: dp_gui.h:22
void handleInteractionRequest(const uno::Reference< uno::XComponentContext > &xContext, const uno::Reference< task::XInteractionRequest > &xRequest)
IMPL_LINK_NOARG(ExtMgrDialog, HandleCancelBtn, weld::Button &, void)
OUString makeURL(std::u16string_view baseURL, OUString const &relPath_)
appends a relative path to a url.
Definition: dp_misc.cxx:253
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC bool create_folder(::ucbhelper::Content *ucb_content, OUString const &url, css::uno::Reference< css::ucb::XCommandEnvironment > const &xCmdEnv, bool throw_exc=true)
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC bool erase_path(OUString const &url, css::uno::Reference< css::ucb::XCommandEnvironment > const &xCmdEnv, bool throw_exc=true)
bool office_is_running()
Definition: dp_misc.cxx:331
void TRACE(OUString const &sText)
print the text to the console in a debug build.
Definition: dp_misc.cxx:486
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC bool create_ucb_content(::ucbhelper::Content *ucb_content, OUString const &url, css::uno::Reference< css::ucb::XCommandEnvironment > const &xCmdEnv, bool throw_exc=true)
RET_CANCEL
size_t pos