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