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 ");
377 buf.append(elem.first);
378 buf.append(". ");
379 buf.append(elem.second.Message);
380 ++nPos;
381 }
382 m_dialog.setError(UpdateInstallDialog::ERROR_DOWNLOAD, updateData.aInstalledPackage->getDisplayName(),
383 buf);
384 }
385 }
386
387 }
388 }
389 catch (const css::uno::Exception & e)
390 {
392 if (m_stop) {
393 return;
394 }
395 m_dialog.setError(e.Message);
396 }
397}
398
400{
401 //Update the fix text in the dialog to "Installing extensions..."
402 {
404 if (m_stop) {
405 return;
406 }
407 m_dialog.m_xFt_action->set_label(m_dialog.m_sInstalling);
408 m_dialog.m_xStatusbar->set_percentage(0);
409 }
410
411 sal_uInt16 count = 0;
412 for (auto const& updateData : m_aVecUpdateData)
413 {
414 //update the name of the extension which is to be installed
415 {
417 if (m_stop) {
418 return;
419 }
420 //we only show progress after an extension has been installed.
421 if (count > 0) {
422 m_dialog.m_xStatusbar->set_percentage(
423 (sal::static_int_cast<sal_uInt16>(100) * count) /
424 sal::static_int_cast<sal_uInt16>(m_aVecUpdateData.size()));
425 }
426 m_dialog.m_xFt_extension_name->set_label(updateData.aInstalledPackage->getDisplayName());
427 }
428 bool bError = false;
429 bool bLicenseDeclined = false;
430 css::uno::Reference<css::deployment::XPackage> xExtension;
431 css::uno::Exception exc;
432 try
433 {
434 css::uno::Reference< css::task::XAbortChannel > xAbortChannel(
435 updateData.aInstalledPackage->createAbortChannel() );
436 {
438 if (m_stop) {
439 return;
440 }
441 m_abort = xAbortChannel;
442 }
443 if (!updateData.aUpdateSource.is() && !updateData.sLocalURL.isEmpty())
444 {
445 css::beans::NamedValue prop("EXTENSION_UPDATE", css::uno::Any(OUString("1")));
446 if (!updateData.bIsShared)
447 xExtension = m_dialog.getExtensionManager()->addExtension(
448 updateData.sLocalURL, css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
449 "user", xAbortChannel, m_updateCmdEnv);
450 else
451 xExtension = m_dialog.getExtensionManager()->addExtension(
452 updateData.sLocalURL, css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
453 "shared", xAbortChannel, m_updateCmdEnv);
454 }
455 else if (updateData.aUpdateSource.is())
456 {
457 OSL_ASSERT(updateData.aUpdateSource.is());
458 //I am not sure if we should obtain the install properties and pass them into
459 //add extension. Currently it contains only "SUPPRESS_LICENSE". So it could happen
460 //that a license is displayed when updating from the shared repository, although the
461 //shared extension was installed using "SUPPRESS_LICENSE".
462 css::beans::NamedValue prop("EXTENSION_UPDATE", css::uno::Any(OUString("1")));
463 if (!updateData.bIsShared)
464 xExtension = m_dialog.getExtensionManager()->addExtension(
465 updateData.aUpdateSource->getURL(), css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
466 "user", xAbortChannel, m_updateCmdEnv);
467 else
468 xExtension = m_dialog.getExtensionManager()->addExtension(
469 updateData.aUpdateSource->getURL(), css::uno::Sequence<css::beans::NamedValue>(&prop, 1),
470 "shared", xAbortChannel, m_updateCmdEnv);
471 }
472 }
473 catch (css::deployment::DeploymentException & de)
474 {
475 if (de.Cause.has<css::deployment::LicenseException>())
476 {
477 bLicenseDeclined = true;
478 }
479 else
480 {
481 exc = de.Cause.get<css::uno::Exception>();
482 bError = true;
483 }
484 }
485 catch (css::uno::Exception& e)
486 {
487 exc = e;
488 bError = true;
489 }
490
491 if (bLicenseDeclined)
492 {
494 if (m_stop) {
495 return;
496 }
498 updateData.aInstalledPackage->getDisplayName(), std::u16string_view());
499 }
500 else if (!xExtension.is() || bError)
501 {
503 if (m_stop) {
504 return;
505 }
507 updateData.aInstalledPackage->getDisplayName(), exc.Message);
508 }
509 ++count;
510 }
511 {
513 if (m_stop) {
514 return;
515 }
516 m_dialog.m_xStatusbar->set_percentage(100);
517 m_dialog.m_xFt_extension_name->set_label(OUString());
518 m_dialog.m_xFt_action->set_label(m_dialog.m_sFinished);
519 }
520}
521
523{
524 if (!m_sDownloadFolder.isEmpty())
525 {
526 dp_misc::erase_path(m_sDownloadFolder,
527 css::uno::Reference<css::ucb::XCommandEnvironment>(),false /* no throw: ignore errors */ );
528 //remove also the temp file which we have used to create the unique name
529 OUString tempFile = m_sDownloadFolder.copy(0, m_sDownloadFolder.getLength() - 1);
530 dp_misc::erase_path(tempFile, css::uno::Reference<css::ucb::XCommandEnvironment>(),false);
531 m_sDownloadFolder.clear();
532 }
533}
534
535bool UpdateInstallDialog::Thread::download(OUString const & sDownloadURL, UpdateData & aUpdateData)
536{
537 {
539 if (m_stop) {
540 return m_stop;
541 }
542 }
543
544 OSL_ASSERT(m_sDownloadFolder.getLength());
545 OUString destFolder, tempEntry;
546 if (::osl::File::createTempFile(
547 &m_sDownloadFolder,
548 nullptr, &tempEntry ) != ::osl::File::E_None)
549 {
550 //ToDo feedback in window that download of this component failed
551 throw css::uno::Exception("Could not create temporary file in folder " + destFolder + ".", nullptr);
552 }
553 tempEntry = tempEntry.copy( tempEntry.lastIndexOf( '/' ) + 1 );
554
555 destFolder = dp_misc::makeURL( m_sDownloadFolder, tempEntry ) + "_";
556
557 ::ucbhelper::Content destFolderContent;
558 dp_misc::create_folder( &destFolderContent, destFolder, m_updateCmdEnv );
559
560 ::ucbhelper::Content sourceContent;
561 (void)dp_misc::create_ucb_content(&sourceContent, sDownloadURL, m_updateCmdEnv);
562
563 const OUString sTitle( StrTitle::getTitle( sourceContent ) );
564
565 destFolderContent.transferContent(
567 sTitle, css::ucb::NameClash::OVERWRITE );
568
569 {
570 //the user may have cancelled the dialog because downloading took too long
572 if (m_stop) {
573 return m_stop;
574 }
575 //all errors should be handled by the command environment.
576 aUpdateData.sLocalURL = destFolder + "/" + sTitle;
577 }
578
579 return m_stop;
580}
581
582UpdateCommandEnv::UpdateCommandEnv( css::uno::Reference< css::uno::XComponentContext > xCtx,
584 : m_installThread(std::move(thread)),
585 m_xContext(std::move(xCtx))
586{
587}
588
589// XCommandEnvironment
590css::uno::Reference<css::task::XInteractionHandler> UpdateCommandEnv::getInteractionHandler()
591{
592 return this;
593}
594
595css::uno::Reference<css::ucb::XProgressHandler> UpdateCommandEnv::getProgressHandler()
596{
597 return this;
598}
599
600// XInteractionHandler
602 css::uno::Reference< css::task::XInteractionRequest> const & xRequest )
603{
604 css::uno::Any request( xRequest->getRequest() );
605 OSL_ASSERT( request.getValueTypeClass() == css::uno::TypeClass_EXCEPTION );
606 dp_misc::TRACE("[dp_gui_cmdenv.cxx] incoming request:\n"
607 + ::comphelper::anyToString(request) + "\n\n");
608
609 css::deployment::VersionException verExc;
610 bool approve = false;
611
612 if (request >>= verExc)
613 { //We must catch the version exception during the update,
614 //because otherwise the user would be confronted with the dialogs, asking
615 //them if they want to replace an already installed version of the same extension.
616 //During an update we assume that we always want to replace the old version with the
617 //new version.
618 approve = true;
619 }
620
621 if (!approve)
622 {
623 //forward to interaction handler for main dialog.
625 }
626 else
627 {
628 // select:
629 css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > conts(
630 xRequest->getContinuations() );
631 css::uno::Reference< css::task::XInteractionContinuation > const * pConts =
632 conts.getConstArray();
633 sal_Int32 len = conts.getLength();
634 for ( sal_Int32 pos = 0; pos < len; ++pos )
635 {
636 if (approve) {
637 css::uno::Reference< css::task::XInteractionApprove > xInteractionApprove(
638 pConts[ pos ], css::uno::UNO_QUERY );
639 if (xInteractionApprove.is()) {
640 xInteractionApprove->select();
641 // don't query again for ongoing continuations:
642 approve = false;
643 }
644 }
645 }
646 }
647}
648
649// XProgressHandler
650void UpdateCommandEnv::push( css::uno::Any const & /*Status*/ )
651{
652}
653
654void UpdateCommandEnv::update( css::uno::Any const & /*Status */)
655{
656}
657
659{
660}
661
662
663} //end namespace dp_gui
664
665/* 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 OString &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:558
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:252
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:334
void TRACE(OUString const &sText)
print the text to the console in a debug build.
Definition: dp_misc.cxx:489
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