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