1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <strings.hrc>
22 #include <svtools/controldims.hxx>
25 #include "dp_gui_dialog2.hxx"
26 #include "dp_gui_extlistbox.hxx"
27 #include <dp_shared.hxx>
28 #include "dp_gui_theextmgr.hxx"
29 #include "dp_gui_extensioncmdqueue.hxx"
32 #include <dp_update.hxx>
33 #include <dp_identifier.hxx>
34 #include <dp_descriptioninfoset.hxx>
36 #include <fpicker/strings.hrc>
38 #include <vcl/commandevent.hxx>
39 #include <vcl/svapp.hxx>
41 #include <osl/mutex.hxx>
42 #include <sal/log.hxx>
44 #include <svtools/restartdialog.hxx>
46 #include <sfx2/filedlghelper.hxx>
47 #include <sfx2/sfxdlg.hxx>
49 #include <comphelper/anytostring.hxx>
50 #include <cppuhelper/exc_hlp.hxx>
51 #include <cppuhelper/bootstrap.hxx>
53 #include <comphelper/processfactory.hxx>
54 #include <tools/diagnose_ex.h>
55 #include <ucbhelper/content.hxx>
56 #include <unotools/collatorwrapper.hxx>
57 #include <unotools/configmgr.hxx>
59 #include <com/sun/star/beans/StringPair.hpp>
60 #include <com/sun/star/deployment/DeploymentException.hpp>
61 #include <com/sun/star/i18n/CollatorOptions.hpp>
62 #include <com/sun/star/lang/IllegalArgumentException.hpp>
63 #include <com/sun/star/system/SystemShellExecuteFlags.hpp>
64 #include <com/sun/star/system/SystemShellExecute.hpp>
66 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
67 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
68 #include <com/sun/star/ui/dialogs/FilePicker.hpp>
69 #include <com/sun/star/ui/dialogs/XFilterManager.hpp>
71 #include <com/sun/star/uno/Any.hxx>
72 #include <com/sun/star/uno/XComponentContext.hpp>
74 #include <officecfg/Office/ExtensionManager.hxx>
80 using namespace ::com::sun::star
;
81 using namespace ::com::sun::star::system
;
86 #define USER_PACKAGE_MANAGER "user"
87 #define SHARED_PACKAGE_MANAGER "shared"
88 #define BUNDLED_PACKAGE_MANAGER "bundled"
91 struct StrAllFiles
: public rtl::StaticWithInit
< OUString
, StrAllFiles
>
93 OUString
operator () () {
94 const SolarMutexGuard guard
;
95 std::locale loc
= Translate::Create("fps");
96 return Translate::get(STR_FILTERNAME_ALL
, loc
);
100 // ExtBoxWithBtns_Impl
101 class ExtBoxWithBtns_Impl
: public ExtensionBox_Impl
103 bool m_bInterfaceLocked
;
105 ExtMgrDialog
* m_pParent
;
107 void SetButtonStatus( const TEntry_Impl
& rEntry
);
108 OString
ShowPopupMenu( const Point
&rPos
, const long nPos
);
111 explicit ExtBoxWithBtns_Impl(std::unique_ptr
<weld::ScrolledWindow
> xScroll
);
113 void InitFromDialog(ExtMgrDialog
*pParentDialog
);
115 virtual bool MouseButtonDown( const MouseEvent
& rMEvt
) override
;
116 virtual bool Command( const CommandEvent
& rCEvt
) override
;
118 virtual void RecalcAll() override
;
119 virtual void selectEntry( const long nPos
) override
;
121 void enableButtons( bool bEnable
);
124 ExtBoxWithBtns_Impl::ExtBoxWithBtns_Impl(std::unique_ptr
<weld::ScrolledWindow
> xScroll
)
125 : ExtensionBox_Impl(std::move(xScroll
))
126 , m_bInterfaceLocked(false)
131 void ExtBoxWithBtns_Impl::InitFromDialog(ExtMgrDialog
*pParentDialog
)
133 setExtensionManager(pParentDialog
->getExtensionManager());
135 m_pParent
= pParentDialog
;
138 void ExtBoxWithBtns_Impl::RecalcAll()
140 const sal_Int32 nActive
= getSelIndex();
142 if ( nActive
!= ExtensionBox_Impl::ENTRY_NOTFOUND
)
144 SetButtonStatus( GetEntryData( nActive
) );
148 m_pParent
->enableOptionsButton( false );
149 m_pParent
->enableRemoveButton( false );
150 m_pParent
->enableEnableButton( false );
153 ExtensionBox_Impl::RecalcAll();
157 //This function may be called with nPos < 0
158 void ExtBoxWithBtns_Impl::selectEntry( const long nPos
)
160 if ( HasActive() && ( nPos
== getSelIndex() ) )
163 ExtensionBox_Impl::selectEntry( nPos
);
166 void ExtBoxWithBtns_Impl::SetButtonStatus(const TEntry_Impl
& rEntry
)
168 bool bShowOptionBtn
= true;
170 rEntry
->m_bHasButtons
= false;
171 if ( ( rEntry
->m_eState
== REGISTERED
) || ( rEntry
->m_eState
== NOT_AVAILABLE
) )
173 m_pParent
->enableButtontoEnable( false );
177 m_pParent
->enableButtontoEnable( true );
178 bShowOptionBtn
= false;
181 if ( ( !rEntry
->m_bUser
|| ( rEntry
->m_eState
== NOT_AVAILABLE
) || rEntry
->m_bMissingDeps
)
182 && !rEntry
->m_bMissingLic
)
184 m_pParent
->enableEnableButton( false );
188 m_pParent
->enableEnableButton( !rEntry
->m_bLocked
);
189 rEntry
->m_bHasButtons
= true;
192 if ( rEntry
->m_bHasOptions
&& bShowOptionBtn
)
194 m_pParent
->enableOptionsButton( true );
195 rEntry
->m_bHasButtons
= true;
199 m_pParent
->enableOptionsButton( false );
202 if ( rEntry
->m_bUser
|| rEntry
->m_bShared
)
204 m_pParent
->enableRemoveButton( !rEntry
->m_bLocked
);
205 rEntry
->m_bHasButtons
= true;
209 m_pParent
->enableRemoveButton( false );
213 bool ExtBoxWithBtns_Impl::Command(const CommandEvent
& rCEvt
)
215 if (rCEvt
.GetCommand() != CommandEventId::ContextMenu
)
216 return ExtensionBox_Impl::Command(rCEvt
);
218 const Point
aMousePos(rCEvt
.GetMousePosPixel());
219 const auto nPos
= PointToPos(aMousePos
);
220 OString sCommand
= ShowPopupMenu(aMousePos
, nPos
);
222 if (sCommand
== "CMD_ENABLE")
223 m_pParent
->enablePackage( GetEntryData( nPos
)->m_xPackage
, true );
224 else if (sCommand
== "CMD_DISABLE")
225 m_pParent
->enablePackage( GetEntryData( nPos
)->m_xPackage
, false );
226 else if (sCommand
== "CMD_UPDATE")
227 m_pParent
->updatePackage( GetEntryData( nPos
)->m_xPackage
);
228 else if (sCommand
== "CMD_REMOVE")
229 m_pParent
->removePackage( GetEntryData( nPos
)->m_xPackage
);
230 else if (sCommand
== "CMD_SHOW_LICENSE")
232 m_pParent
->incBusy();
233 ShowLicenseDialog
aLicenseDlg(m_pParent
->getDialog(), GetEntryData(nPos
)->m_xPackage
);
235 m_pParent
->decBusy();
241 OString
ExtBoxWithBtns_Impl::ShowPopupMenu( const Point
& rPos
, const long nPos
)
243 if ( nPos
>= static_cast<long>(getItemCount()) )
246 std::unique_ptr
<weld::Builder
> xBuilder(Application::CreateBuilder(nullptr, "desktop/ui/extensionmenu.ui"));
247 std::unique_ptr
<weld::Menu
> xPopup(xBuilder
->weld_menu("menu"));
249 #if ENABLE_EXTENSION_UPDATE
250 xPopup
->append("CMD_UPDATE", DpResId( RID_CTX_ITEM_CHECK_UPDATE
) );
253 if ( ! GetEntryData( nPos
)->m_bLocked
)
255 if ( GetEntryData( nPos
)->m_bUser
)
257 if ( GetEntryData( nPos
)->m_eState
== REGISTERED
)
258 xPopup
->append("CMD_DISABLE", DpResId(RID_CTX_ITEM_DISABLE
));
259 else if ( GetEntryData( nPos
)->m_eState
!= NOT_AVAILABLE
)
260 xPopup
->append("CMD_ENABLE", DpResId(RID_CTX_ITEM_ENABLE
));
262 if (!officecfg::Office::ExtensionManager::ExtensionSecurity::DisableExtensionRemoval::get())
264 xPopup
->append("CMD_REMOVE", DpResId(RID_CTX_ITEM_REMOVE
));
268 if ( !GetEntryData( nPos
)->m_sLicenseText
.isEmpty() )
269 xPopup
->append("CMD_SHOW_LICENSE", DpResId(RID_STR_SHOW_LICENSE_CMD
));
271 return xPopup
->popup_at_rect(GetDrawingArea(), tools::Rectangle(rPos
, Size(1, 1)));
274 bool ExtBoxWithBtns_Impl::MouseButtonDown( const MouseEvent
& rMEvt
)
276 if (m_bInterfaceLocked
)
278 return ExtensionBox_Impl::MouseButtonDown(rMEvt
);
281 void ExtBoxWithBtns_Impl::enableButtons( bool bEnable
)
283 m_bInterfaceLocked
= ! bEnable
;
287 sal_Int32 nIndex
= getSelIndex();
288 if ( nIndex
!= ExtensionBox_Impl::ENTRY_NOTFOUND
)
289 SetButtonStatus( GetEntryData( nIndex
) );
293 m_pParent
->enableEnableButton( false );
294 m_pParent
->enableOptionsButton( false );
295 m_pParent
->enableRemoveButton( false );
301 DialogHelper::DialogHelper(const uno::Reference
< uno::XComponentContext
> &xContext
,
302 weld::Window
* pWindow
)
304 , m_nEventID(nullptr)
306 m_xContext
= xContext
;
309 DialogHelper::~DialogHelper()
312 Application::RemoveUserEvent( m_nEventID
);
316 bool DialogHelper::IsSharedPkgMgr( const uno::Reference
< deployment::XPackage
> &xPackage
)
318 return xPackage
->getRepositoryName() == SHARED_PACKAGE_MANAGER
;
321 bool DialogHelper::continueOnSharedExtension( const uno::Reference
< deployment::XPackage
> &xPackage
,
322 weld::Widget
* pParent
,
326 if ( !bHadWarning
&& IsSharedPkgMgr( xPackage
) )
328 const SolarMutexGuard guard
;
330 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(pParent
,
331 VclMessageType::Warning
, VclButtonsType::OkCancel
, DpResId(pResID
)));
334 bool bRet
= RET_OK
== xBox
->run();
343 void DialogHelper::openWebBrowser(const OUString
& sURL
, const OUString
& sTitle
)
345 if ( sURL
.isEmpty() ) // Nothing to do, when the URL is empty
350 uno::Reference
< XSystemShellExecute
> xSystemShellExecute(
351 SystemShellExecute::create(m_xContext
));
352 //throws css::lang::IllegalArgumentException, css::system::SystemShellExecuteException
353 xSystemShellExecute
->execute( sURL
, OUString(), SystemShellExecuteFlags::URIS_ONLY
);
355 catch ( const uno::Exception
& )
357 uno::Any
exc( ::cppu::getCaughtException() );
358 OUString
msg( ::comphelper::anyToString( exc
) );
359 const SolarMutexGuard guard
;
361 std::unique_ptr
<weld::MessageDialog
> xErrorBox(Application::CreateMessageDialog(getFrameWeld(),
362 VclMessageType::Warning
, VclButtonsType::Ok
, msg
));
363 xErrorBox
->set_title(sTitle
);
370 bool DialogHelper::installExtensionWarn(const OUString
&rExtensionName
)
372 const SolarMutexGuard guard
;
374 // Check if extension installation is disabled in the expert configurations
375 if (officecfg::Office::ExtensionManager::ExtensionSecurity::DisableExtensionInstallation::get())
378 std::unique_ptr
<weld::MessageDialog
> xWarnBox(Application::CreateMessageDialog(getFrameWeld(),
379 VclMessageType::Warning
, VclButtonsType::Ok
,
380 DpResId(RID_STR_WARNING_INSTALL_EXTENSION_DISABLED
)));
389 std::unique_ptr
<weld::MessageDialog
> xInfoBox(Application::CreateMessageDialog(getFrameWeld(),
390 VclMessageType::Warning
, VclButtonsType::OkCancel
,
391 DpResId(RID_STR_WARNING_INSTALL_EXTENSION
)));
392 OUString
sText(xInfoBox
->get_primary_text());
393 sText
= sText
.replaceAll("%NAME", rExtensionName
);
394 xInfoBox
->set_primary_text(sText
);
396 bool bRet
= RET_OK
== xInfoBox
->run();
402 bool DialogHelper::installForAllUsers(bool &bInstallForAll
)
404 const SolarMutexGuard guard
;
406 std::unique_ptr
<weld::Builder
> xBuilder(Application::CreateBuilder(getFrameWeld(), "desktop/ui/installforalldialog.ui"));
407 std::unique_ptr
<weld::MessageDialog
> xQuery(xBuilder
->weld_message_dialog("InstallForAllDialog"));
408 short nRet
= xQuery
->run();
411 if (nRet
== RET_CANCEL
)
414 bInstallForAll
= ( nRet
== RET_NO
);
418 void DialogHelper::PostUserEvent( const Link
<void*,void>& rLink
, void* pCaller
)
421 Application::RemoveUserEvent( m_nEventID
);
423 m_nEventID
= Application::PostUserEvent(rLink
, pCaller
);
427 ExtMgrDialog::ExtMgrDialog(weld::Window
*pParent
, TheExtensionManager
*pManager
)
428 : GenericDialogController(pParent
, "desktop/ui/extensionmanager.ui", "ExtensionManagerDialog")
429 , DialogHelper(pManager
->getContext(), m_xDialog
.get())
430 , m_sAddPackages(DpResId(RID_STR_ADD_PACKAGES
))
431 , m_bHasProgress(false)
432 , m_bProgressChanged(false)
433 , m_bStartProgress(false)
434 , m_bStopProgress(false)
435 , m_bEnableWarning(false)
436 , m_bDisableWarning(false)
437 , m_bDeleteWarning(false)
440 , m_pManager(pManager
)
441 , m_xExtensionBox(new ExtBoxWithBtns_Impl(m_xBuilder
->weld_scrolled_window("scroll")))
442 , m_xExtensionBoxWnd(new weld::CustomWeld(*m_xBuilder
, "extensions", *m_xExtensionBox
))
443 , m_xOptionsBtn(m_xBuilder
->weld_button("optionsbtn"))
444 , m_xAddBtn(m_xBuilder
->weld_button("addbtn"))
445 , m_xRemoveBtn(m_xBuilder
->weld_button("removebtn"))
446 , m_xEnableBtn(m_xBuilder
->weld_button("enablebtn"))
447 , m_xUpdateBtn(m_xBuilder
->weld_button("updatebtn"))
448 , m_xCloseBtn(m_xBuilder
->weld_button("close"))
449 , m_xBundledCbx(m_xBuilder
->weld_check_button("bundled"))
450 , m_xSharedCbx(m_xBuilder
->weld_check_button("shared"))
451 , m_xUserCbx(m_xBuilder
->weld_check_button("user"))
452 , m_xGetExtensions(m_xBuilder
->weld_link_button("getextensions"))
453 , m_xProgressText(m_xBuilder
->weld_label("progressft"))
454 , m_xProgressBar(m_xBuilder
->weld_progress_bar("progressbar"))
455 , m_xCancelBtn(m_xBuilder
->weld_button("cancel"))
457 m_xExtensionBox
->InitFromDialog(this);
459 m_xEnableBtn
->set_help_id(HID_EXTENSION_MANAGER_LISTBOX_ENABLE
);
461 m_xOptionsBtn
->connect_clicked( LINK( this, ExtMgrDialog
, HandleOptionsBtn
) );
462 m_xAddBtn
->connect_clicked( LINK( this, ExtMgrDialog
, HandleAddBtn
) );
463 m_xRemoveBtn
->connect_clicked( LINK( this, ExtMgrDialog
, HandleRemoveBtn
) );
464 m_xEnableBtn
->connect_clicked( LINK( this, ExtMgrDialog
, HandleEnableBtn
) );
465 m_xCloseBtn
->connect_clicked( LINK( this, ExtMgrDialog
, HandleCloseBtn
) );
467 m_xCancelBtn
->connect_clicked( LINK( this, ExtMgrDialog
, HandleCancelBtn
) );
469 m_xBundledCbx
->connect_clicked( LINK( this, ExtMgrDialog
, HandleExtTypeCbx
) );
470 m_xSharedCbx
->connect_clicked( LINK( this, ExtMgrDialog
, HandleExtTypeCbx
) );
471 m_xUserCbx
->connect_clicked( LINK( this, ExtMgrDialog
, HandleExtTypeCbx
) );
473 m_xBundledCbx
->set_active(true);
474 m_xSharedCbx
->set_active(true);
475 m_xUserCbx
->set_active(true);
477 m_xProgressBar
->hide();
479 #if ENABLE_EXTENSION_UPDATE
480 m_xUpdateBtn
->connect_clicked( LINK( this, ExtMgrDialog
, HandleUpdateBtn
) );
481 m_xUpdateBtn
->set_sensitive(false);
483 m_xUpdateBtn
->hide();
486 if (officecfg::Office::ExtensionManager::ExtensionSecurity::DisableExtensionInstallation::get())
488 m_xAddBtn
->set_sensitive(false);
489 m_xAddBtn
->set_tooltip_text(DpResId(RID_STR_WARNING_INSTALL_EXTENSION_DISABLED
));
491 if (officecfg::Office::ExtensionManager::ExtensionSecurity::DisableExtensionRemoval::get())
493 m_xRemoveBtn
->set_sensitive(false);
494 m_xRemoveBtn
->set_tooltip_text(DpResId(RID_STR_WARNING_REMOVE_EXTENSION_DISABLED
));
497 m_aIdle
.SetPriority(TaskPriority::LOWEST
);
498 m_aIdle
.SetDebugName( "ExtMgrDialog m_aIdle TimeOutHdl" );
499 m_aIdle
.SetInvokeHandler( LINK( this, ExtMgrDialog
, TimeOutHdl
) );
502 ExtMgrDialog::~ExtMgrDialog()
507 void ExtMgrDialog::setGetExtensionsURL( const OUString
&rURL
)
509 m_xGetExtensions
->set_uri( rURL
);
512 void ExtMgrDialog::addPackageToList( const uno::Reference
< deployment::XPackage
> &xPackage
,
513 bool bLicenseMissing
)
515 const SolarMutexGuard aGuard
;
516 m_xUpdateBtn
->set_sensitive(true);
518 if (m_xBundledCbx
->get_active() && (xPackage
->getRepositoryName() == BUNDLED_PACKAGE_MANAGER
) )
520 m_xExtensionBox
->addEntry( xPackage
, bLicenseMissing
);
522 else if (m_xSharedCbx
->get_active() && (xPackage
->getRepositoryName() == SHARED_PACKAGE_MANAGER
) )
524 m_xExtensionBox
->addEntry( xPackage
, bLicenseMissing
);
526 else if (m_xUserCbx
->get_active() && (xPackage
->getRepositoryName() == USER_PACKAGE_MANAGER
))
528 m_xExtensionBox
->addEntry( xPackage
, bLicenseMissing
);
532 void ExtMgrDialog::prepareChecking()
534 m_xExtensionBox
->prepareChecking();
537 void ExtMgrDialog::checkEntries()
539 const SolarMutexGuard guard
;
540 m_xExtensionBox
->checkEntries();
543 bool ExtMgrDialog::removeExtensionWarn(const OUString
&rExtensionName
)
545 const SolarMutexGuard guard
;
547 std::unique_ptr
<weld::MessageDialog
> xInfoBox(Application::CreateMessageDialog(m_xDialog
.get(),
548 VclMessageType::Warning
, VclButtonsType::OkCancel
,
549 DpResId(RID_STR_WARNING_REMOVE_EXTENSION
)));
551 OUString
sText(xInfoBox
->get_primary_text());
552 sText
= sText
.replaceAll("%NAME", rExtensionName
);
553 xInfoBox
->set_primary_text(sText
);
555 bool bRet
= RET_OK
== xInfoBox
->run();
562 void ExtMgrDialog::enablePackage( const uno::Reference
< deployment::XPackage
> &xPackage
,
565 if ( !xPackage
.is() )
570 if (!continueOnSharedExtension(xPackage
, m_xDialog
.get(), RID_STR_WARNING_ENABLE_SHARED_EXTENSION
, m_bEnableWarning
))
575 if (!continueOnSharedExtension(xPackage
, m_xDialog
.get(), RID_STR_WARNING_DISABLE_SHARED_EXTENSION
, m_bDisableWarning
))
579 m_pManager
->getCmdQueue()->enableExtension( xPackage
, bEnable
);
583 void ExtMgrDialog::removePackage( const uno::Reference
< deployment::XPackage
> &xPackage
)
585 if ( !xPackage
.is() )
588 if ( !IsSharedPkgMgr( xPackage
) || m_bDeleteWarning
)
590 if ( ! removeExtensionWarn( xPackage
->getDisplayName() ) )
594 if (!continueOnSharedExtension(xPackage
, m_xDialog
.get(), RID_STR_WARNING_REMOVE_SHARED_EXTENSION
, m_bDeleteWarning
))
597 m_pManager
->getCmdQueue()->removeExtension( xPackage
);
601 void ExtMgrDialog::updatePackage( const uno::Reference
< deployment::XPackage
> &xPackage
)
603 if ( !xPackage
.is() )
606 // get the extension with highest version
607 uno::Sequence
<uno::Reference
<deployment::XPackage
> > seqExtensions
=
608 m_pManager
->getExtensionManager()->getExtensionsWithSameIdentifier(
609 dp_misc::getIdentifier(xPackage
), xPackage
->getName(), uno::Reference
<ucb::XCommandEnvironment
>());
610 uno::Reference
<deployment::XPackage
> extension
=
611 dp_misc::getExtensionWithHighestVersion(seqExtensions
);
612 OSL_ASSERT(extension
.is());
613 std::vector
< css::uno::Reference
< css::deployment::XPackage
> > vEntries
;
614 vEntries
.push_back(extension
);
616 m_pManager
->getCmdQueue()->checkForUpdates( vEntries
);
620 bool ExtMgrDialog::acceptLicense( const uno::Reference
< deployment::XPackage
> &xPackage
)
622 if ( !xPackage
.is() )
625 m_pManager
->getCmdQueue()->acceptLicense( xPackage
);
631 uno::Sequence
< OUString
> ExtMgrDialog::raiseAddPicker()
633 sfx2::FileDialogHelper
aDlgHelper(ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE
, FileDialogFlags::NONE
, m_xDialog
.get());
634 const uno::Reference
<ui::dialogs::XFilePicker3
>& xFilePicker
= aDlgHelper
.GetFilePicker();
635 xFilePicker
->setTitle( m_sAddPackages
);
637 if ( !m_sLastFolderURL
.isEmpty() )
638 xFilePicker
->setDisplayDirectory( m_sLastFolderURL
);
640 // collect and set filter list:
641 typedef std::map
< OUString
, OUString
> t_string2string
;
642 t_string2string title2filter
;
643 OUString
sDefaultFilter( StrAllFiles::get() );
645 const uno::Sequence
< uno::Reference
< deployment::XPackageTypeInfo
> > packageTypes(
646 m_pManager
->getExtensionManager()->getSupportedPackageTypes() );
648 for ( sal_Int32 pos
= 0; pos
< packageTypes
.getLength(); ++pos
)
650 uno::Reference
< deployment::XPackageTypeInfo
> const & xPackageType
= packageTypes
[ pos
];
651 const OUString
filter( xPackageType
->getFileFilter() );
652 if (!filter
.isEmpty())
654 const OUString
title( xPackageType
->getShortDescription() );
655 const std::pair
< t_string2string::iterator
, bool > insertion(
656 title2filter
.emplace( title
, filter
) );
657 if ( ! insertion
.second
)
658 { // already existing, append extensions:
660 buf
.append( insertion
.first
->second
);
662 buf
.append( filter
);
663 insertion
.first
->second
= buf
.makeStringAndClear();
665 if ( xPackageType
->getMediaType() == "application/vnd.sun.star.package-bundle" )
666 sDefaultFilter
= title
;
671 xFilePicker
->appendFilter( StrAllFiles::get(), "*.*" );
672 // then supported ones:
673 for (auto const& elem
: title2filter
)
677 xFilePicker
->appendFilter( elem
.first
, elem
.second
);
679 catch (const lang::IllegalArgumentException
&)
681 TOOLS_WARN_EXCEPTION( "desktop", "" );
684 xFilePicker
->setCurrentFilter( sDefaultFilter
);
686 if ( xFilePicker
->execute() != ui::dialogs::ExecutableDialogResults::OK
)
687 return uno::Sequence
<OUString
>(); // cancelled
689 m_sLastFolderURL
= xFilePicker
->getDisplayDirectory();
690 uno::Sequence
< OUString
> files( xFilePicker
->getSelectedFiles() );
691 OSL_ASSERT( files
.hasElements() );
695 void ExtMgrDialog::enableOptionsButton( bool bEnable
)
697 m_xOptionsBtn
->set_sensitive( bEnable
);
700 void ExtMgrDialog::enableRemoveButton( bool bEnable
)
702 m_xRemoveBtn
->set_sensitive( bEnable
&& !officecfg::Office::ExtensionManager::ExtensionSecurity::DisableExtensionRemoval::get());
704 if (officecfg::Office::ExtensionManager::ExtensionSecurity::DisableExtensionRemoval::get())
706 m_xRemoveBtn
->set_tooltip_text(DpResId(RID_STR_WARNING_REMOVE_EXTENSION_DISABLED
));
710 m_xRemoveBtn
->set_tooltip_text("");
714 void ExtMgrDialog::enableEnableButton( bool bEnable
)
716 m_xEnableBtn
->set_sensitive( bEnable
);
719 void ExtMgrDialog::enableButtontoEnable( bool bEnable
)
723 m_xEnableBtn
->set_label( DpResId( RID_CTX_ITEM_ENABLE
) );
724 m_xEnableBtn
->set_help_id( HID_EXTENSION_MANAGER_LISTBOX_ENABLE
);
728 m_xEnableBtn
->set_label( DpResId( RID_CTX_ITEM_DISABLE
) );
729 m_xEnableBtn
->set_help_id( HID_EXTENSION_MANAGER_LISTBOX_DISABLE
);
733 IMPL_LINK_NOARG(ExtMgrDialog
, HandleCancelBtn
, weld::Button
&, void)
735 if ( m_xAbortChannel
.is() )
739 m_xAbortChannel
->sendAbort();
741 catch ( const uno::RuntimeException
& )
743 OSL_FAIL( "### unexpected RuntimeException!" );
748 IMPL_LINK_NOARG(ExtMgrDialog
, HandleCloseBtn
, weld::Button
&, void)
750 bool bCallClose
= true;
752 //only suggest restart if modified and this is the first close attempt
753 if (!m_bClosed
&& m_pManager
->isModified())
755 m_pManager
->clearModified();
757 //only suggest restart if we're actually running, e.g. not from standalone unopkg gui
758 if (dp_misc::office_is_running())
760 SolarMutexGuard aGuard
;
761 bCallClose
= !::svtools::executeRestartDialog(comphelper::getProcessComponentContext(),
763 svtools::RESTART_REASON_EXTENSION_INSTALL
);
768 m_xDialog
->response(RET_CANCEL
);
771 IMPL_LINK( ExtMgrDialog
, startProgress
, void*, _bLockInterface
, void )
773 ::osl::MutexGuard
aGuard( m_aMutex
);
774 bool bLockInterface
= static_cast<bool>(_bLockInterface
);
776 if ( m_bStartProgress
&& !m_bHasProgress
)
779 if ( m_bStopProgress
)
781 if ( m_xProgressBar
->get_visible() )
782 m_xProgressBar
->set_percentage( 100 );
783 m_xAbortChannel
.clear();
785 SAL_INFO( "desktop.deployment", " startProgress handler: stop" );
789 SAL_INFO( "desktop.deployment", " startProgress handler: start" );
792 m_xCancelBtn
->set_sensitive( bLockInterface
);
793 m_xAddBtn
->set_sensitive( !bLockInterface
&& !officecfg::Office::ExtensionManager::ExtensionSecurity::DisableExtensionInstallation::get());
794 if (officecfg::Office::ExtensionManager::ExtensionSecurity::DisableExtensionInstallation::get())
796 m_xAddBtn
->set_tooltip_text(DpResId(RID_STR_WARNING_INSTALL_EXTENSION_DISABLED
));
800 m_xAddBtn
->set_tooltip_text("");
803 m_xUpdateBtn
->set_sensitive( !bLockInterface
&& m_xExtensionBox
->getItemCount() );
804 m_xExtensionBox
->enableButtons( !bLockInterface
);
810 void ExtMgrDialog::showProgress( bool _bStart
)
812 ::osl::MutexGuard
aGuard( m_aMutex
);
814 bool bStart
= _bStart
;
819 m_bStartProgress
= true;
820 SAL_INFO( "desktop.deployment", "showProgress start" );
825 m_bStopProgress
= true;
826 SAL_INFO( "desktop.deployment", "showProgress stop!" );
829 DialogHelper::PostUserEvent( LINK( this, ExtMgrDialog
, startProgress
), reinterpret_cast<void*>(bStart
) );
834 void ExtMgrDialog::updateProgress( const long nProgress
)
836 if ( m_nProgress
!= nProgress
)
838 ::osl::MutexGuard
aGuard( m_aMutex
);
839 m_nProgress
= nProgress
;
845 void ExtMgrDialog::updateProgress( const OUString
&rText
,
846 const uno::Reference
< task::XAbortChannel
> &xAbortChannel
)
848 ::osl::MutexGuard
aGuard( m_aMutex
);
850 m_xAbortChannel
= xAbortChannel
;
851 m_sProgressText
= rText
;
852 m_bProgressChanged
= true;
857 void ExtMgrDialog::updatePackageInfo( const uno::Reference
< deployment::XPackage
> &xPackage
)
859 const SolarMutexGuard aGuard
;
860 m_xExtensionBox
->updateEntry( xPackage
);
863 IMPL_LINK_NOARG(ExtMgrDialog
, HandleOptionsBtn
, weld::Button
&, void)
865 const sal_Int32 nActive
= m_xExtensionBox
->getSelIndex();
867 if ( nActive
!= ExtensionBox_Impl::ENTRY_NOTFOUND
)
869 SfxAbstractDialogFactory
* pFact
= SfxAbstractDialogFactory::Create();
871 OUString sExtensionId
= m_xExtensionBox
->GetEntryData( nActive
)->m_xPackage
->getIdentifier().Value
;
872 ScopedVclPtr
<VclAbstractDialog
> pDlg(pFact
->CreateOptionsDialog(m_xDialog
.get(), sExtensionId
));
878 IMPL_LINK_NOARG(ExtMgrDialog
, HandleAddBtn
, weld::Button
&, void)
882 uno::Sequence
< OUString
> aFileList
= raiseAddPicker();
884 if ( aFileList
.hasElements() )
886 m_pManager
->installPackage( aFileList
[0] );
892 IMPL_LINK_NOARG(ExtMgrDialog
, HandleRemoveBtn
, weld::Button
&, void)
894 const sal_Int32 nActive
= m_xExtensionBox
->getSelIndex();
896 if ( nActive
!= ExtensionBox_Impl::ENTRY_NOTFOUND
)
898 TEntry_Impl pEntry
= m_xExtensionBox
->GetEntryData( nActive
);
899 removePackage( pEntry
->m_xPackage
);
903 IMPL_LINK_NOARG(ExtMgrDialog
, HandleEnableBtn
, weld::Button
&, void)
905 const sal_Int32 nActive
= m_xExtensionBox
->getSelIndex();
907 if ( nActive
!= ExtensionBox_Impl::ENTRY_NOTFOUND
)
909 TEntry_Impl pEntry
= m_xExtensionBox
->GetEntryData( nActive
);
911 if ( pEntry
->m_bMissingLic
)
912 acceptLicense( pEntry
->m_xPackage
);
915 const bool bEnable( pEntry
->m_eState
!= REGISTERED
);
916 enablePackage( pEntry
->m_xPackage
, bEnable
);
921 IMPL_LINK_NOARG(ExtMgrDialog
, HandleExtTypeCbx
, weld::Button
&, void)
923 // re-creates the list of packages with addEntry selecting the packages
925 m_pManager
->createPackageList();
929 IMPL_LINK_NOARG(ExtMgrDialog
, HandleUpdateBtn
, weld::Button
&, void)
931 #if ENABLE_EXTENSION_UPDATE
932 m_pManager
->checkUpdates();
938 IMPL_LINK_NOARG(ExtMgrDialog
, TimeOutHdl
, Timer
*, void)
940 if ( m_bStopProgress
)
942 m_bHasProgress
= false;
943 m_bStopProgress
= false;
944 m_xProgressText
->hide();
945 m_xProgressBar
->hide();
946 m_xCancelBtn
->hide();
950 if ( m_bProgressChanged
)
952 m_bProgressChanged
= false;
953 m_xProgressText
->set_label(m_sProgressText
);
956 if ( m_bStartProgress
)
958 m_bStartProgress
= false;
959 m_bHasProgress
= true;
960 m_xProgressBar
->show();
961 m_xProgressText
->show();
962 m_xCancelBtn
->set_sensitive(true);
963 m_xCancelBtn
->show();
966 if ( m_xProgressBar
->get_visible() )
967 m_xProgressBar
->set_percentage( static_cast<sal_uInt16
>(m_nProgress
) );
971 void ExtMgrDialog::Close()
973 m_pManager
->terminateDialog();
977 //UpdateRequiredDialog
978 UpdateRequiredDialog::UpdateRequiredDialog(weld::Window
*pParent
, TheExtensionManager
*pManager
)
979 : GenericDialogController(pParent
, "desktop/ui/updaterequireddialog.ui", "UpdateRequiredDialog")
980 , DialogHelper(pManager
->getContext(), m_xDialog
.get())
981 , m_sCloseText(DpResId(RID_STR_CLOSE_BTN
))
982 , m_bHasProgress(false)
983 , m_bProgressChanged(false)
984 , m_bStartProgress(false)
985 , m_bStopProgress(false)
986 , m_bHasLockedEntries(false)
988 , m_pManager(pManager
)
989 , m_xExtensionBox(new ExtensionBox_Impl(m_xBuilder
->weld_scrolled_window("scroll")))
990 , m_xExtensionBoxWnd(new weld::CustomWeld(*m_xBuilder
, "extensions", *m_xExtensionBox
))
991 , m_xUpdateNeeded(m_xBuilder
->weld_label("updatelabel"))
992 , m_xUpdateBtn(m_xBuilder
->weld_button("ok"))
993 , m_xCloseBtn(m_xBuilder
->weld_button("disable"))
994 , m_xCancelBtn(m_xBuilder
->weld_button("cancel"))
995 , m_xProgressText(m_xBuilder
->weld_label("progresslabel"))
996 , m_xProgressBar(m_xBuilder
->weld_progress_bar("progress"))
998 m_xExtensionBox
->setExtensionManager(pManager
);
1000 m_xUpdateBtn
->connect_clicked( LINK( this, UpdateRequiredDialog
, HandleUpdateBtn
) );
1001 m_xCloseBtn
->connect_clicked( LINK( this, UpdateRequiredDialog
, HandleCloseBtn
) );
1002 m_xCancelBtn
->connect_clicked( LINK( this, UpdateRequiredDialog
, HandleCancelBtn
) );
1004 OUString aText
= m_xUpdateNeeded
->get_label();
1005 aText
= aText
.replaceAll(
1006 "%PRODUCTNAME", utl::ConfigManager::getProductName());
1007 m_xUpdateNeeded
->set_label(aText
);
1009 m_xProgressBar
->hide();
1010 m_xUpdateBtn
->set_sensitive( false );
1011 m_xCloseBtn
->grab_focus();
1013 m_aIdle
.SetPriority( TaskPriority::LOWEST
);
1014 m_aIdle
.SetDebugName( "UpdateRequiredDialog m_aIdle TimeOutHdl" );
1015 m_aIdle
.SetInvokeHandler( LINK( this, UpdateRequiredDialog
, TimeOutHdl
) );
1018 UpdateRequiredDialog::~UpdateRequiredDialog()
1023 void UpdateRequiredDialog::addPackageToList( const uno::Reference
< deployment::XPackage
> &xPackage
,
1024 bool bLicenseMissing
)
1026 // We will only add entries to the list with unsatisfied dependencies
1027 if ( !bLicenseMissing
&& !checkDependencies( xPackage
) )
1029 m_bHasLockedEntries
|= m_pManager
->isReadOnly( xPackage
);
1030 const SolarMutexGuard aGuard
;
1031 m_xUpdateBtn
->set_sensitive(true);
1032 m_xExtensionBox
->addEntry( xPackage
);
1037 void UpdateRequiredDialog::prepareChecking()
1039 m_xExtensionBox
->prepareChecking();
1043 void UpdateRequiredDialog::checkEntries()
1045 const SolarMutexGuard guard
;
1046 m_xExtensionBox
->checkEntries();
1048 if ( ! hasActiveEntries() )
1050 m_xCloseBtn
->set_label( m_sCloseText
);
1051 m_xCloseBtn
->grab_focus();
1056 IMPL_LINK_NOARG(UpdateRequiredDialog
, HandleCancelBtn
, weld::Button
&, void)
1058 if ( m_xAbortChannel
.is() )
1062 m_xAbortChannel
->sendAbort();
1064 catch ( const uno::RuntimeException
& )
1066 OSL_FAIL( "### unexpected RuntimeException!" );
1072 IMPL_LINK( UpdateRequiredDialog
, startProgress
, void*, _bLockInterface
, void )
1074 ::osl::MutexGuard
aGuard( m_aMutex
);
1075 bool bLockInterface
= static_cast<bool>(_bLockInterface
);
1077 if ( m_bStartProgress
&& !m_bHasProgress
)
1080 if ( m_bStopProgress
)
1082 if ( m_xProgressBar
->get_visible() )
1083 m_xProgressBar
->set_percentage( 100 );
1084 m_xAbortChannel
.clear();
1085 SAL_INFO( "desktop.deployment", " startProgress handler: stop" );
1089 SAL_INFO( "desktop.deployment", " startProgress handler: start" );
1092 m_xCancelBtn
->set_sensitive( bLockInterface
);
1093 m_xUpdateBtn
->set_sensitive( false );
1098 void UpdateRequiredDialog::showProgress( bool _bStart
)
1100 ::osl::MutexGuard
aGuard( m_aMutex
);
1102 bool bStart
= _bStart
;
1107 m_bStartProgress
= true;
1108 SAL_INFO( "desktop.deployment", "showProgress start" );
1113 m_bStopProgress
= true;
1114 SAL_INFO( "desktop.deployment", "showProgress stop!" );
1117 DialogHelper::PostUserEvent( LINK( this, UpdateRequiredDialog
, startProgress
), reinterpret_cast<void*>(bStart
) );
1122 void UpdateRequiredDialog::updateProgress( const long nProgress
)
1124 if ( m_nProgress
!= nProgress
)
1126 ::osl::MutexGuard
aGuard( m_aMutex
);
1127 m_nProgress
= nProgress
;
1133 void UpdateRequiredDialog::updateProgress( const OUString
&rText
,
1134 const uno::Reference
< task::XAbortChannel
> &xAbortChannel
)
1136 ::osl::MutexGuard
aGuard( m_aMutex
);
1138 m_xAbortChannel
= xAbortChannel
;
1139 m_sProgressText
= rText
;
1140 m_bProgressChanged
= true;
1145 void UpdateRequiredDialog::updatePackageInfo( const uno::Reference
< deployment::XPackage
> &xPackage
)
1147 // We will remove all updated packages with satisfied dependencies, but
1148 // we will show all disabled entries so the user sees the result
1149 // of the 'disable all' button
1150 const SolarMutexGuard aGuard
;
1151 if ( isEnabled( xPackage
) && checkDependencies( xPackage
) )
1152 m_xExtensionBox
->removeEntry( xPackage
);
1154 m_xExtensionBox
->updateEntry( xPackage
);
1156 if ( ! hasActiveEntries() )
1158 m_xCloseBtn
->set_label( m_sCloseText
);
1159 m_xCloseBtn
->grab_focus();
1164 IMPL_LINK_NOARG(UpdateRequiredDialog
, HandleUpdateBtn
, weld::Button
&, void)
1166 ::osl::ClearableMutexGuard
aGuard( m_aMutex
);
1168 std::vector
< uno::Reference
< deployment::XPackage
> > vUpdateEntries
;
1169 sal_Int32 nCount
= m_xExtensionBox
->GetEntryCount();
1171 for ( sal_Int32 i
= 0; i
< nCount
; ++i
)
1173 TEntry_Impl pEntry
= m_xExtensionBox
->GetEntryData( i
);
1174 vUpdateEntries
.push_back( pEntry
->m_xPackage
);
1179 m_pManager
->getCmdQueue()->checkForUpdates( vUpdateEntries
);
1183 IMPL_LINK_NOARG(UpdateRequiredDialog
, HandleCloseBtn
, weld::Button
&, void)
1185 ::osl::MutexGuard
aGuard( m_aMutex
);
1189 if ( m_bHasLockedEntries
)
1190 m_xDialog
->response(-1);
1191 else if ( hasActiveEntries() )
1192 disableAllEntries();
1194 m_xDialog
->response(RET_CANCEL
);
1199 IMPL_LINK_NOARG(UpdateRequiredDialog
, TimeOutHdl
, Timer
*, void)
1201 if ( m_bStopProgress
)
1203 m_bHasProgress
= false;
1204 m_bStopProgress
= false;
1205 m_xProgressText
->hide();
1206 m_xProgressBar
->hide();
1207 m_xCancelBtn
->hide();
1211 if ( m_bProgressChanged
)
1213 m_bProgressChanged
= false;
1214 m_xProgressText
->set_label( m_sProgressText
);
1217 if ( m_bStartProgress
)
1219 m_bStartProgress
= false;
1220 m_bHasProgress
= true;
1221 m_xProgressBar
->show();
1222 m_xProgressText
->show();
1223 m_xCancelBtn
->set_sensitive(true);
1224 m_xCancelBtn
->show();
1227 if (m_xProgressBar
->get_visible())
1228 m_xProgressBar
->set_percentage(m_nProgress
);
1233 short UpdateRequiredDialog::run()
1236 //I believe m_bHasLockedEntries was used to prevent showing extensions which cannot
1237 //be disabled because they are in a read only repository. However, disabling extensions
1238 //is now always possible because the registration data of all repositories
1239 //are in the user installation.
1240 //Therefore all extensions could be displayed and all the handling around m_bHasLockedEntries
1242 if ( m_bHasLockedEntries
)
1244 // Set other text, disable update btn, remove not shared entries from list;
1245 m_xUpdateNeeded
->set_label( DpResId( RID_STR_NO_ADMIN_PRIVILEGE
) );
1246 m_xCloseBtn
->set_label( DpResId( RID_STR_EXIT_BTN
) );
1247 m_xUpdateBtn
->set_sensitive( false );
1248 m_xExtensionBox
->RemoveUnlocked();
1251 return GenericDialogController::run();
1254 // Check dependencies of all packages
1256 bool UpdateRequiredDialog::isEnabled( const uno::Reference
< deployment::XPackage
> &xPackage
)
1258 bool bRegistered
= false;
1260 beans::Optional
< beans::Ambiguous
< sal_Bool
> > option( xPackage
->isRegistered( uno::Reference
< task::XAbortChannel
>(),
1261 uno::Reference
< ucb::XCommandEnvironment
>() ) );
1262 if ( option
.IsPresent
)
1264 ::beans::Ambiguous
< sal_Bool
> const & reg
= option
.Value
;
1265 if ( reg
.IsAmbiguous
)
1266 bRegistered
= false;
1268 bRegistered
= reg
.Value
;
1271 bRegistered
= false;
1273 catch ( const uno::RuntimeException
& ) { throw; }
1274 catch (const uno::Exception
& ) {
1275 TOOLS_WARN_EXCEPTION( "desktop", "" );
1276 bRegistered
= false;
1282 // Checks the dependencies no matter if the extension is enabled or disabled!
1283 bool UpdateRequiredDialog::checkDependencies( const uno::Reference
< deployment::XPackage
> &xPackage
)
1285 bool bDependenciesValid
= false;
1287 bDependenciesValid
= xPackage
->checkDependencies( uno::Reference
< ucb::XCommandEnvironment
>() );
1289 catch ( const deployment::DeploymentException
& ) {}
1290 return bDependenciesValid
;
1294 bool UpdateRequiredDialog::hasActiveEntries()
1296 ::osl::MutexGuard
aGuard( m_aMutex
);
1299 long nCount
= m_xExtensionBox
->GetEntryCount();
1300 for ( long nIndex
= 0; nIndex
< nCount
; nIndex
++ )
1302 TEntry_Impl pEntry
= m_xExtensionBox
->GetEntryData( nIndex
);
1304 if ( isEnabled(pEntry
->m_xPackage
) && !checkDependencies( pEntry
->m_xPackage
) )
1315 void UpdateRequiredDialog::disableAllEntries()
1317 ::osl::MutexGuard
aGuard( m_aMutex
);
1321 long nCount
= m_xExtensionBox
->GetEntryCount();
1322 for ( long nIndex
= 0; nIndex
< nCount
; nIndex
++ )
1324 TEntry_Impl pEntry
= m_xExtensionBox
->GetEntryData( nIndex
);
1325 m_pManager
->getCmdQueue()->enableExtension( pEntry
->m_xPackage
, false );
1330 if ( ! hasActiveEntries() )
1331 m_xCloseBtn
->set_label( m_sCloseText
);
1334 // ShowLicenseDialog
1335 ShowLicenseDialog::ShowLicenseDialog(weld::Window
* pParent
,
1336 const uno::Reference
< deployment::XPackage
> &xPackage
)
1337 : GenericDialogController(pParent
, "desktop/ui/showlicensedialog.ui", "ShowLicenseDialog")
1338 , m_xLicenseText(m_xBuilder
->weld_text_view("textview"))
1340 m_xLicenseText
->set_size_request(m_xLicenseText
->get_approximate_digit_width() * 72,
1341 m_xLicenseText
->get_height_rows(21));
1342 m_xLicenseText
->set_text(xPackage
->getLicenseText());
1345 ShowLicenseDialog::~ShowLicenseDialog()
1349 // UpdateRequiredDialogService
1351 UpdateRequiredDialogService::UpdateRequiredDialogService( SAL_UNUSED_PARAMETER
uno::Sequence
< uno::Any
> const&,
1352 uno::Reference
< uno::XComponentContext
> const& xComponentContext
)
1353 : m_xComponentContext( xComponentContext
)
1358 // XExecutableDialog
1360 void UpdateRequiredDialogService::setTitle( OUString
const & )
1365 sal_Int16
UpdateRequiredDialogService::execute()
1367 ::rtl::Reference
< ::dp_gui::TheExtensionManager
> xManager( TheExtensionManager::get(
1368 m_xComponentContext
) );
1369 xManager
->createDialog( true );
1370 sal_Int16 nRet
= xManager
->execute();
1376 } //namespace dp_gui
1378 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */