diff options
Diffstat (limited to 'desktop/source/deployment/gui/dp_gui_theextmgr.cxx')
-rw-r--r-- | desktop/source/deployment/gui/dp_gui_theextmgr.cxx | 538 |
1 files changed, 538 insertions, 0 deletions
diff --git a/desktop/source/deployment/gui/dp_gui_theextmgr.cxx b/desktop/source/deployment/gui/dp_gui_theextmgr.cxx new file mode 100644 index 000000000000..3d994f31c395 --- /dev/null +++ b/desktop/source/deployment/gui/dp_gui_theextmgr.cxx @@ -0,0 +1,538 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: dp_gui_theextmgr.cxx,v $ + * + * $Revision: 1.3.14.2 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_desktop.hxx" + +#include "vcl/svapp.hxx" +#include "vcl/msgbox.hxx" + +#include "vos/mutex.hxx" + +#include "toolkit/helper/vclunohelper.hxx" + +#include "com/sun/star/beans/XPropertySet.hpp" +#include "com/sun/star/deployment/XPackageManagerFactory.hpp" +#include "com/sun/star/deployment/thePackageManagerFactory.hpp" + +#include "dp_gui_dialog2.hxx" +#include "dp_gui_extensioncmdqueue.hxx" +#include "dp_gui_theextmgr.hxx" +#include "dp_gui_theextmgr.hxx" +#include "dp_identifier.hxx" + +#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) + +using namespace ::com::sun::star; +using ::rtl::OUString; + +namespace dp_gui { + +//------------------------------------------------------------------------------ + +::rtl::Reference< TheExtensionManager > TheExtensionManager::s_ExtMgr; + +//------------------------------------------------------------------------------ +// TheExtensionManager +//------------------------------------------------------------------------------ + +TheExtensionManager::TheExtensionManager( Window *pParent, + const uno::Reference< uno::XComponentContext > &xContext ) : + m_xContext( xContext ), + m_pParent( pParent ), + m_pExtMgrDialog( NULL ), + m_pUpdReqDialog( NULL ) +{ + if ( dp_misc::office_is_running() ) + { + m_xDesktop.set( xContext->getServiceManager()->createInstanceWithContext( + OUSTR("com.sun.star.frame.Desktop"), xContext ), uno::UNO_QUERY ); + if ( m_xDesktop.is() ) + m_xDesktop->addTerminateListener( this ); + } + + m_sPackageManagers.realloc(2); + m_sPackageManagers[0] = deployment::thePackageManagerFactory::get( m_xContext )->getPackageManager( OUSTR("user") ); + m_sPackageManagers[1] = deployment::thePackageManagerFactory::get( m_xContext )->getPackageManager( OUSTR("shared") );; + + for ( sal_Int32 i = 0; i < m_sPackageManagers.getLength(); ++i ) + { + m_sPackageManagers[i]->addModifyListener( this ); + } + + uno::Reference< lang::XMultiServiceFactory > xConfig( + xContext->getServiceManager()->createInstanceWithContext( + OUSTR("com.sun.star.configuration.ConfigurationProvider"), xContext ), uno::UNO_QUERY_THROW); + uno::Any args[1]; + beans::PropertyValue aValue( OUSTR("nodepath"), 0, uno::Any( OUSTR("/org.openoffice.Office.OptionsDialog/Nodes") ), + beans::PropertyState_DIRECT_VALUE ); + args[0] <<= aValue; + m_xNameAccessNodes = uno::Reference< container::XNameAccess >( + xConfig->createInstanceWithArguments( OUSTR("com.sun.star.configuration.ConfigurationAccess"), + uno::Sequence< uno::Any >( args, 1 )), uno::UNO_QUERY_THROW); + + // get the 'get more extensions here' url + uno::Reference< container::XNameAccess > xNameAccessRepositories; + beans::PropertyValue aValue2( OUSTR("nodepath"), 0, uno::Any( OUSTR("/org.openoffice.Office.ExtensionManager/ExtensionRepositories") ), + beans::PropertyState_DIRECT_VALUE ); + args[0] <<= aValue2; + xNameAccessRepositories = uno::Reference< container::XNameAccess > ( + xConfig->createInstanceWithArguments( OUSTR("com.sun.star.configuration.ConfigurationAccess"), + uno::Sequence< uno::Any >( args, 1 )), uno::UNO_QUERY_THROW); + try + { //throws css::container::NoSuchElementException, css::lang::WrappedTargetException + uno::Any value = xNameAccessRepositories->getByName( OUSTR( "WebsiteLink" ) ); + m_sGetExtensionsURL = value.get< OUString > (); + } + catch ( uno::Exception& ) + {} +} + +//------------------------------------------------------------------------------ +TheExtensionManager::~TheExtensionManager() +{ + if ( m_pUpdReqDialog ) + delete m_pUpdReqDialog; + if ( m_pExtMgrDialog ) + delete m_pExtMgrDialog; +} + +//------------------------------------------------------------------------------ +void TheExtensionManager::createDialog( const bool bCreateUpdDlg ) +{ + const ::vos::OGuard guard( Application::GetSolarMutex() ); + + if ( bCreateUpdDlg ) + { + if ( !m_pUpdReqDialog ) + { + m_pUpdReqDialog = new UpdateRequiredDialog( NULL, this ); + m_pExecuteCmdQueue.reset( new ExtensionCmdQueue( (DialogHelper*) m_pUpdReqDialog, this, m_xContext ) ); + createPackageList(); + } + } + else if ( !m_pExtMgrDialog ) + { + m_pExtMgrDialog = new ExtMgrDialog( m_pParent, this ); + m_pExecuteCmdQueue.reset( new ExtensionCmdQueue( (DialogHelper*) m_pExtMgrDialog, this, m_xContext ) ); + m_pExtMgrDialog->setGetExtensionsURL( m_sGetExtensionsURL ); + createPackageList(); + } +} + +//------------------------------------------------------------------------------ +void TheExtensionManager::Show() +{ + const ::vos::OGuard guard( Application::GetSolarMutex() ); + + getDialog()->Show(); +} + +//------------------------------------------------------------------------------ +void TheExtensionManager::SetText( const ::rtl::OUString &rTitle ) +{ + const ::vos::OGuard guard( Application::GetSolarMutex() ); + + getDialog()->SetText( rTitle ); +} + +//------------------------------------------------------------------------------ +void TheExtensionManager::ToTop( USHORT nFlags ) +{ + const ::vos::OGuard guard( Application::GetSolarMutex() ); + + getDialog()->ToTop( nFlags ); +} + +//------------------------------------------------------------------------------ +bool TheExtensionManager::Close() +{ + if ( m_pExtMgrDialog ) + return m_pExtMgrDialog->Close(); + else if ( m_pUpdReqDialog ) + return m_pUpdReqDialog->Close(); + else + return true; +} + +//------------------------------------------------------------------------------ +sal_Int16 TheExtensionManager::execute() +{ + sal_Int16 nRet = 0; + + if ( m_pUpdReqDialog ) + { + nRet = m_pUpdReqDialog->Execute(); + delete m_pUpdReqDialog; + m_pUpdReqDialog = NULL; + } + + return nRet; +} + +//------------------------------------------------------------------------------ +bool TheExtensionManager::isVisible() +{ + return getDialog()->IsVisible(); +} + +//------------------------------------------------------------------------------ +bool TheExtensionManager::checkUpdates( bool /* bShowUpdateOnly */, bool /*bParentVisible*/ ) +{ + std::vector< TUpdateListEntry > vEntries; + + for ( sal_Int32 i = 0; i < m_sPackageManagers.getLength(); ++i ) + { + uno::Sequence< uno::Reference< deployment::XPackage > > xPackages; + try { + xPackages = m_sPackageManagers[i]->getDeployedPackages( uno::Reference< task::XAbortChannel >(), + uno::Reference< ucb::XCommandEnvironment >() ); + for ( sal_Int32 k = 0; k < xPackages.getLength(); ++k ) + { + TUpdateListEntry pEntry( new UpdateListEntry( xPackages[k], m_sPackageManagers[i] ) ); + vEntries.push_back( pEntry ); + } + } catch ( deployment::DeploymentException & ) { + continue; + } catch ( ucb::CommandFailedException & ) { + continue; + } catch ( ucb::CommandAbortedException & ) { + return true; + } catch ( lang::IllegalArgumentException & e ) { + throw uno::RuntimeException( e.Message, e.Context ); + } + } + + m_pExecuteCmdQueue->checkForUpdates( vEntries ); + return true; +} + +//------------------------------------------------------------------------------ +bool TheExtensionManager::enablePackage( const uno::Reference< deployment::XPackage > &xPackage, + bool bEnable ) +{ + m_pExecuteCmdQueue->enableExtension( xPackage, bEnable ); + + return true; +} + +//------------------------------------------------------------------------------ +bool TheExtensionManager::removePackage( const uno::Reference< deployment::XPackageManager > &xPackageManager, + const uno::Reference< deployment::XPackage > &xPackage ) +{ + m_pExecuteCmdQueue->removeExtension( xPackageManager, xPackage ); + + return true; +} + +//------------------------------------------------------------------------------ +bool TheExtensionManager::updatePackages( const std::vector< TUpdateListEntry > &vList ) +{ + m_pExecuteCmdQueue->checkForUpdates( vList ); + + return true; +} + +//------------------------------------------------------------------------------ +bool TheExtensionManager::installPackage( const OUString &rPackageURL, bool bWarnUser ) +{ + if ( rPackageURL.getLength() == 0 ) + return false; + + createDialog( false ); + + uno::Reference< deployment::XPackageManager > xUserPkgMgr = getUserPkgMgr(); + uno::Reference< deployment::XPackageManager > xSharedPkgMgr = getSharedPkgMgr(); + + bool bInstall = true; + bool bInstallForAll = false; + + if ( !bWarnUser && ! xSharedPkgMgr->isReadOnly() ) + bInstall = getDialogHelper()->installForAllUsers( bInstallForAll ); + + if ( !bInstall ) + return false; + + if ( bInstallForAll ) + m_pExecuteCmdQueue->addExtension( xSharedPkgMgr, rPackageURL, false ); + else + m_pExecuteCmdQueue->addExtension( xUserPkgMgr, rPackageURL, bWarnUser ); + + return true; +} + +//------------------------------------------------------------------------------ +bool TheExtensionManager::queryTermination() +{ + if ( dp_misc::office_is_running() ) + return true; + // the standalone application unopkg must not close ( and quit ) the dialog + // when there are still actions in the queue + return true; +} + +//------------------------------------------------------------------------------ +void TheExtensionManager::terminateDialog() +{ + if ( ! dp_misc::office_is_running() ) + { + const ::vos::OGuard guard( Application::GetSolarMutex() ); + delete m_pExtMgrDialog; + m_pExtMgrDialog = NULL; + delete m_pUpdReqDialog; + m_pUpdReqDialog = NULL; + Application::Quit(); + } +} + +//------------------------------------------------------------------------------ +bool TheExtensionManager::createPackageList( const uno::Reference< deployment::XPackageManager > &xPackageManager ) +{ + uno::Sequence< uno::Reference< deployment::XPackage > > packages; + + try { + packages = xPackageManager->getDeployedPackages( uno::Reference< task::XAbortChannel >(), + uno::Reference< ucb::XCommandEnvironment >() ); + } catch ( deployment::DeploymentException & ) { + //handleGeneralError(e.Cause); + return true; + } catch ( ucb::CommandFailedException & ) { + //handleGeneralError(e.Reason); + return true; + } catch ( ucb::CommandAbortedException & ) { + return false; + } catch ( lang::IllegalArgumentException & e ) { + throw uno::RuntimeException( e.Message, e.Context ); + } + + for ( sal_Int32 j = 0; j < packages.getLength(); ++j ) + { + getDialogHelper()->addPackageToList( packages[j], xPackageManager ); + } + + return true; +} + +//------------------------------------------------------------------------------ +void TheExtensionManager::createPackageList() +{ + for ( sal_Int32 i = 0; i < m_sPackageManagers.getLength(); ++i ) + { + if ( ! createPackageList( m_sPackageManagers[i] ) ) + break; + } +} + +//------------------------------------------------------------------------------ +PackageState TheExtensionManager::getPackageState( const uno::Reference< deployment::XPackage > &xPackage ) const +{ + try { + beans::Optional< beans::Ambiguous< sal_Bool > > option( + xPackage->isRegistered( uno::Reference< task::XAbortChannel >(), + uno::Reference< ucb::XCommandEnvironment >() ) ); + if ( option.IsPresent ) + { + ::beans::Ambiguous< sal_Bool > const & reg = option.Value; + if ( reg.IsAmbiguous ) + return AMBIGUOUS; + else + return reg.Value ? REGISTERED : NOT_REGISTERED; + } + else + return NOT_AVAILABLE; + } + catch ( uno::RuntimeException & ) { + throw; + } + catch ( uno::Exception & exc) { + (void) exc; + OSL_ENSURE( 0, ::rtl::OUStringToOString( exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() ); + return NOT_AVAILABLE; + } +} + +//------------------------------------------------------------------------------ +// The function investigates if the extension supports options. +bool TheExtensionManager::supportsOptions( const uno::Reference< deployment::XPackage > &xPackage ) const +{ + bool bOptions = false; + + if ( ! xPackage->isBundle() ) + return false; + + beans::Optional< OUString > aId = xPackage->getIdentifier(); + + //a bundle must always have an id + OSL_ASSERT( aId.IsPresent ); + + //iterate over all available nodes + uno::Sequence< OUString > seqNames = m_xNameAccessNodes->getElementNames(); + + for ( int i = 0; i < seqNames.getLength(); i++ ) + { + uno::Any anyNode = m_xNameAccessNodes->getByName( seqNames[i] ); + //If we have a node then then it must contain the set of leaves. This is part of OptionsDialog.xcs + uno::Reference< XInterface> xIntNode = anyNode.get< uno::Reference< XInterface > >(); + uno::Reference< container::XNameAccess > xNode( xIntNode, uno::UNO_QUERY_THROW ); + + uno::Any anyLeaves = xNode->getByName( OUSTR("Leaves") ); + uno::Reference< XInterface > xIntLeaves = anyLeaves.get< uno::Reference< XInterface > >(); + uno::Reference< container::XNameAccess > xLeaves( xIntLeaves, uno::UNO_QUERY_THROW ); + + //iterate over all available leaves + uno::Sequence< OUString > seqLeafNames = xLeaves->getElementNames(); + for ( int j = 0; j < seqLeafNames.getLength(); j++ ) + { + uno::Any anyLeaf = xLeaves->getByName( seqLeafNames[j] ); + uno::Reference< XInterface > xIntLeaf = anyLeaf.get< uno::Reference< XInterface > >(); + uno::Reference< beans::XPropertySet > xLeaf( xIntLeaf, uno::UNO_QUERY_THROW ); + //investigate the Id property if it matches the extension identifier which + //has been passed in. + uno::Any anyValue = xLeaf->getPropertyValue( OUSTR("Id") ); + + OUString sId = anyValue.get< OUString >(); + if ( sId == aId.Value ) + { + bOptions = true; + break; + } + } + if ( bOptions ) + break; + } + return bOptions; +} + +//------------------------------------------------------------------------------ +// XEventListener +void TheExtensionManager::disposing( lang::EventObject const & rEvt ) + throw ( uno::RuntimeException ) +{ + bool shutDown = (rEvt.Source == m_xDesktop); + + if ( shutDown && m_xDesktop.is() ) + { + m_xDesktop->removeTerminateListener( this ); + m_xDesktop.clear(); + } + + if ( shutDown ) + { + if ( dp_misc::office_is_running() ) + { + const ::vos::OGuard guard( Application::GetSolarMutex() ); + delete m_pExtMgrDialog; + m_pExtMgrDialog = NULL; + delete m_pUpdReqDialog; + m_pUpdReqDialog = NULL; + } + s_ExtMgr.clear(); + } +} + +//------------------------------------------------------------------------------ +// XTerminateListener +void TheExtensionManager::queryTermination( ::lang::EventObject const & ) + throw ( frame::TerminationVetoException, uno::RuntimeException ) +{ + DialogHelper *pDialogHelper = getDialogHelper(); + + if ( m_pExecuteCmdQueue->isBusy() || ( pDialogHelper && pDialogHelper->isBusy() ) ) + { + ToTop( TOTOP_RESTOREWHENMIN ); + throw frame::TerminationVetoException( + OUSTR("The office cannot be closed while the Extension Manager is running"), + uno::Reference<XInterface>(static_cast<frame::XTerminateListener*>(this), uno::UNO_QUERY)); + } + else + { + if ( m_pExtMgrDialog ) + m_pExtMgrDialog->Close(); + if ( m_pUpdReqDialog ) + m_pUpdReqDialog->Close(); + } +} + +//------------------------------------------------------------------------------ +void TheExtensionManager::notifyTermination( ::lang::EventObject const & rEvt ) + throw ( uno::RuntimeException ) +{ + disposing( rEvt ); +} + +//------------------------------------------------------------------------------ +// XModifyListener +void TheExtensionManager::modified( ::lang::EventObject const & rEvt ) + throw ( uno::RuntimeException ) +{ + uno::Reference< deployment::XPackageManager > xPackageManager( rEvt.Source, uno::UNO_QUERY ); + if ( xPackageManager.is() ) + { + getDialogHelper()->prepareChecking( xPackageManager ); + createPackageList( xPackageManager ); + getDialogHelper()->checkEntries(); + } +} + +//------------------------------------------------------------------------------ +::rtl::Reference< TheExtensionManager > TheExtensionManager::get( const uno::Reference< uno::XComponentContext > &xContext, + const uno::Reference< awt::XWindow > &xParent, + const OUString & extensionURL ) +{ + if ( s_ExtMgr.is() ) + { + OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); + if ( extensionURL.getLength() ) + s_ExtMgr->installPackage( extensionURL, true ); + return s_ExtMgr; + } + + Window * pParent = DIALOG_NO_PARENT; + if ( xParent.is() ) + pParent = VCLUnoHelper::GetWindow(xParent); + + ::rtl::Reference<TheExtensionManager> that( new TheExtensionManager( pParent, xContext ) ); + + const ::vos::OGuard guard( Application::GetSolarMutex() ); + if ( ! s_ExtMgr.is() ) + { + OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); + s_ExtMgr = that; + } + + if ( extensionURL.getLength() ) + s_ExtMgr->installPackage( extensionURL, true ); + + return s_ExtMgr; +} + +} //namespace dp_gui + |