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