Update ooo320-m1
[ooovba.git] / desktop / source / deployment / gui / dp_gui_theextmgr.cxx
blob82577c614a783726b965fab82a573a72a8fba11b
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dp_gui_theextmgr.cxx,v $
11 * $Revision: 1.3.14.2 $
13 * This file is part of OpenOffice.org.
15 * OpenOffice.org is free software: you can redistribute it and/or modify
16 * it under the terms of the GNU Lesser General Public License version 3
17 * only, as published by the Free Software Foundation.
19 * OpenOffice.org is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Lesser General Public License version 3 for more details
23 * (a copy is included in the LICENSE file that accompanied this code).
25 * You should have received a copy of the GNU Lesser General Public License
26 * version 3 along with OpenOffice.org. If not, see
27 * <http://www.openoffice.org/license.html>
28 * for a copy of the LGPLv3 License.
30 ************************************************************************/
32 // MARKER(update_precomp.py): autogen include statement, do not remove
33 #include "precompiled_desktop.hxx"
35 #include "vcl/svapp.hxx"
36 #include "vcl/msgbox.hxx"
38 #include "vos/mutex.hxx"
40 #include "toolkit/helper/vclunohelper.hxx"
42 #include "com/sun/star/beans/XPropertySet.hpp"
43 #include "com/sun/star/deployment/XPackageManagerFactory.hpp"
44 #include "com/sun/star/deployment/thePackageManagerFactory.hpp"
46 #include "dp_gui_dialog2.hxx"
47 #include "dp_gui_extensioncmdqueue.hxx"
48 #include "dp_gui_theextmgr.hxx"
49 #include "dp_gui_theextmgr.hxx"
50 #include "dp_identifier.hxx"
52 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
54 using namespace ::com::sun::star;
55 using ::rtl::OUString;
57 namespace dp_gui {
59 //------------------------------------------------------------------------------
61 ::rtl::Reference< TheExtensionManager > TheExtensionManager::s_ExtMgr;
63 //------------------------------------------------------------------------------
64 // TheExtensionManager
65 //------------------------------------------------------------------------------
67 TheExtensionManager::TheExtensionManager( Window *pParent,
68 const uno::Reference< uno::XComponentContext > &xContext ) :
69 m_xContext( xContext ),
70 m_pParent( pParent ),
71 m_pExtMgrDialog( NULL ),
72 m_pUpdReqDialog( NULL )
74 if ( dp_misc::office_is_running() )
76 m_xDesktop.set( xContext->getServiceManager()->createInstanceWithContext(
77 OUSTR("com.sun.star.frame.Desktop"), xContext ), uno::UNO_QUERY );
78 if ( m_xDesktop.is() )
79 m_xDesktop->addTerminateListener( this );
82 m_sPackageManagers.realloc(2);
83 m_sPackageManagers[0] = deployment::thePackageManagerFactory::get( m_xContext )->getPackageManager( OUSTR("user") );
84 m_sPackageManagers[1] = deployment::thePackageManagerFactory::get( m_xContext )->getPackageManager( OUSTR("shared") );;
86 for ( sal_Int32 i = 0; i < m_sPackageManagers.getLength(); ++i )
88 m_sPackageManagers[i]->addModifyListener( this );
91 uno::Reference< lang::XMultiServiceFactory > xConfig(
92 xContext->getServiceManager()->createInstanceWithContext(
93 OUSTR("com.sun.star.configuration.ConfigurationProvider"), xContext ), uno::UNO_QUERY_THROW);
94 uno::Any args[1];
95 beans::PropertyValue aValue( OUSTR("nodepath"), 0, uno::Any( OUSTR("/org.openoffice.Office.OptionsDialog/Nodes") ),
96 beans::PropertyState_DIRECT_VALUE );
97 args[0] <<= aValue;
98 m_xNameAccessNodes = uno::Reference< container::XNameAccess >(
99 xConfig->createInstanceWithArguments( OUSTR("com.sun.star.configuration.ConfigurationAccess"),
100 uno::Sequence< uno::Any >( args, 1 )), uno::UNO_QUERY_THROW);
102 // get the 'get more extensions here' url
103 uno::Reference< container::XNameAccess > xNameAccessRepositories;
104 beans::PropertyValue aValue2( OUSTR("nodepath"), 0, uno::Any( OUSTR("/org.openoffice.Office.ExtensionManager/ExtensionRepositories") ),
105 beans::PropertyState_DIRECT_VALUE );
106 args[0] <<= aValue2;
107 xNameAccessRepositories = uno::Reference< container::XNameAccess > (
108 xConfig->createInstanceWithArguments( OUSTR("com.sun.star.configuration.ConfigurationAccess"),
109 uno::Sequence< uno::Any >( args, 1 )), uno::UNO_QUERY_THROW);
110 try
111 { //throws css::container::NoSuchElementException, css::lang::WrappedTargetException
112 uno::Any value = xNameAccessRepositories->getByName( OUSTR( "WebsiteLink" ) );
113 m_sGetExtensionsURL = value.get< OUString > ();
115 catch ( uno::Exception& )
119 //------------------------------------------------------------------------------
120 TheExtensionManager::~TheExtensionManager()
122 if ( m_pUpdReqDialog )
123 delete m_pUpdReqDialog;
124 if ( m_pExtMgrDialog )
125 delete m_pExtMgrDialog;
128 //------------------------------------------------------------------------------
129 void TheExtensionManager::createDialog( const bool bCreateUpdDlg )
131 const ::vos::OGuard guard( Application::GetSolarMutex() );
133 if ( bCreateUpdDlg )
135 if ( !m_pUpdReqDialog )
137 m_pUpdReqDialog = new UpdateRequiredDialog( NULL, this );
138 m_pExecuteCmdQueue.reset( new ExtensionCmdQueue( (DialogHelper*) m_pUpdReqDialog, this, m_xContext ) );
139 createPackageList();
142 else if ( !m_pExtMgrDialog )
144 m_pExtMgrDialog = new ExtMgrDialog( m_pParent, this );
145 m_pExecuteCmdQueue.reset( new ExtensionCmdQueue( (DialogHelper*) m_pExtMgrDialog, this, m_xContext ) );
146 m_pExtMgrDialog->setGetExtensionsURL( m_sGetExtensionsURL );
147 createPackageList();
151 //------------------------------------------------------------------------------
152 void TheExtensionManager::Show()
154 const ::vos::OGuard guard( Application::GetSolarMutex() );
156 getDialog()->Show();
159 //------------------------------------------------------------------------------
160 void TheExtensionManager::SetText( const ::rtl::OUString &rTitle )
162 const ::vos::OGuard guard( Application::GetSolarMutex() );
164 getDialog()->SetText( rTitle );
167 //------------------------------------------------------------------------------
168 void TheExtensionManager::ToTop( USHORT nFlags )
170 const ::vos::OGuard guard( Application::GetSolarMutex() );
172 getDialog()->ToTop( nFlags );
175 //------------------------------------------------------------------------------
176 bool TheExtensionManager::Close()
178 if ( m_pExtMgrDialog )
179 return m_pExtMgrDialog->Close();
180 else if ( m_pUpdReqDialog )
181 return m_pUpdReqDialog->Close();
182 else
183 return true;
186 //------------------------------------------------------------------------------
187 sal_Int16 TheExtensionManager::execute()
189 sal_Int16 nRet = 0;
191 if ( m_pUpdReqDialog )
193 nRet = m_pUpdReqDialog->Execute();
194 delete m_pUpdReqDialog;
195 m_pUpdReqDialog = NULL;
198 return nRet;
201 //------------------------------------------------------------------------------
202 bool TheExtensionManager::isVisible()
204 return getDialog()->IsVisible();
207 //------------------------------------------------------------------------------
208 bool TheExtensionManager::checkUpdates( bool /* bShowUpdateOnly */, bool /*bParentVisible*/ )
210 std::vector< TUpdateListEntry > vEntries;
212 for ( sal_Int32 i = 0; i < m_sPackageManagers.getLength(); ++i )
214 uno::Sequence< uno::Reference< deployment::XPackage > > xPackages;
215 try {
216 xPackages = m_sPackageManagers[i]->getDeployedPackages( uno::Reference< task::XAbortChannel >(),
217 uno::Reference< ucb::XCommandEnvironment >() );
218 for ( sal_Int32 k = 0; k < xPackages.getLength(); ++k )
220 TUpdateListEntry pEntry( new UpdateListEntry( xPackages[k], m_sPackageManagers[i] ) );
221 vEntries.push_back( pEntry );
223 } catch ( deployment::DeploymentException & ) {
224 continue;
225 } catch ( ucb::CommandFailedException & ) {
226 continue;
227 } catch ( ucb::CommandAbortedException & ) {
228 return true;
229 } catch ( lang::IllegalArgumentException & e ) {
230 throw uno::RuntimeException( e.Message, e.Context );
234 m_pExecuteCmdQueue->checkForUpdates( vEntries );
235 return true;
238 //------------------------------------------------------------------------------
239 bool TheExtensionManager::enablePackage( const uno::Reference< deployment::XPackage > &xPackage,
240 bool bEnable )
242 m_pExecuteCmdQueue->enableExtension( xPackage, bEnable );
244 return true;
247 //------------------------------------------------------------------------------
248 bool TheExtensionManager::removePackage( const uno::Reference< deployment::XPackageManager > &xPackageManager,
249 const uno::Reference< deployment::XPackage > &xPackage )
251 m_pExecuteCmdQueue->removeExtension( xPackageManager, xPackage );
253 return true;
256 //------------------------------------------------------------------------------
257 bool TheExtensionManager::updatePackages( const std::vector< TUpdateListEntry > &vList )
259 m_pExecuteCmdQueue->checkForUpdates( vList );
261 return true;
264 //------------------------------------------------------------------------------
265 bool TheExtensionManager::installPackage( const OUString &rPackageURL, bool bWarnUser )
267 if ( rPackageURL.getLength() == 0 )
268 return false;
270 createDialog( false );
272 uno::Reference< deployment::XPackageManager > xUserPkgMgr = getUserPkgMgr();
273 uno::Reference< deployment::XPackageManager > xSharedPkgMgr = getSharedPkgMgr();
275 bool bInstall = true;
276 bool bInstallForAll = false;
278 if ( !bWarnUser && ! xSharedPkgMgr->isReadOnly() )
279 bInstall = getDialogHelper()->installForAllUsers( bInstallForAll );
281 if ( !bInstall )
282 return false;
284 if ( bInstallForAll )
285 m_pExecuteCmdQueue->addExtension( xSharedPkgMgr, rPackageURL, false );
286 else
287 m_pExecuteCmdQueue->addExtension( xUserPkgMgr, rPackageURL, bWarnUser );
289 return true;
292 //------------------------------------------------------------------------------
293 bool TheExtensionManager::queryTermination()
295 if ( dp_misc::office_is_running() )
296 return true;
297 // the standalone application unopkg must not close ( and quit ) the dialog
298 // when there are still actions in the queue
299 return true;
302 //------------------------------------------------------------------------------
303 void TheExtensionManager::terminateDialog()
305 if ( ! dp_misc::office_is_running() )
307 const ::vos::OGuard guard( Application::GetSolarMutex() );
308 delete m_pExtMgrDialog;
309 m_pExtMgrDialog = NULL;
310 delete m_pUpdReqDialog;
311 m_pUpdReqDialog = NULL;
312 Application::Quit();
316 //------------------------------------------------------------------------------
317 bool TheExtensionManager::createPackageList( const uno::Reference< deployment::XPackageManager > &xPackageManager )
319 uno::Sequence< uno::Reference< deployment::XPackage > > packages;
321 try {
322 packages = xPackageManager->getDeployedPackages( uno::Reference< task::XAbortChannel >(),
323 uno::Reference< ucb::XCommandEnvironment >() );
324 } catch ( deployment::DeploymentException & ) {
325 //handleGeneralError(e.Cause);
326 return true;
327 } catch ( ucb::CommandFailedException & ) {
328 //handleGeneralError(e.Reason);
329 return true;
330 } catch ( ucb::CommandAbortedException & ) {
331 return false;
332 } catch ( lang::IllegalArgumentException & e ) {
333 throw uno::RuntimeException( e.Message, e.Context );
336 for ( sal_Int32 j = 0; j < packages.getLength(); ++j )
338 getDialogHelper()->addPackageToList( packages[j], xPackageManager );
341 return true;
344 //------------------------------------------------------------------------------
345 void TheExtensionManager::createPackageList()
347 for ( sal_Int32 i = 0; i < m_sPackageManagers.getLength(); ++i )
349 if ( ! createPackageList( m_sPackageManagers[i] ) )
350 break;
354 //------------------------------------------------------------------------------
355 PackageState TheExtensionManager::getPackageState( const uno::Reference< deployment::XPackage > &xPackage ) const
357 try {
358 beans::Optional< beans::Ambiguous< sal_Bool > > option(
359 xPackage->isRegistered( uno::Reference< task::XAbortChannel >(),
360 uno::Reference< ucb::XCommandEnvironment >() ) );
361 if ( option.IsPresent )
363 ::beans::Ambiguous< sal_Bool > const & reg = option.Value;
364 if ( reg.IsAmbiguous )
365 return AMBIGUOUS;
366 else
367 return reg.Value ? REGISTERED : NOT_REGISTERED;
369 else
370 return NOT_AVAILABLE;
372 catch ( uno::RuntimeException & ) {
373 throw;
375 catch ( uno::Exception & exc) {
376 (void) exc;
377 OSL_ENSURE( 0, ::rtl::OUStringToOString( exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
378 return NOT_AVAILABLE;
382 //------------------------------------------------------------------------------
383 // The function investigates if the extension supports options.
384 bool TheExtensionManager::supportsOptions( const uno::Reference< deployment::XPackage > &xPackage ) const
386 bool bOptions = false;
388 if ( ! xPackage->isBundle() )
389 return false;
391 beans::Optional< OUString > aId = xPackage->getIdentifier();
393 //a bundle must always have an id
394 OSL_ASSERT( aId.IsPresent );
396 //iterate over all available nodes
397 uno::Sequence< OUString > seqNames = m_xNameAccessNodes->getElementNames();
399 for ( int i = 0; i < seqNames.getLength(); i++ )
401 uno::Any anyNode = m_xNameAccessNodes->getByName( seqNames[i] );
402 //If we have a node then then it must contain the set of leaves. This is part of OptionsDialog.xcs
403 uno::Reference< XInterface> xIntNode = anyNode.get< uno::Reference< XInterface > >();
404 uno::Reference< container::XNameAccess > xNode( xIntNode, uno::UNO_QUERY_THROW );
406 uno::Any anyLeaves = xNode->getByName( OUSTR("Leaves") );
407 uno::Reference< XInterface > xIntLeaves = anyLeaves.get< uno::Reference< XInterface > >();
408 uno::Reference< container::XNameAccess > xLeaves( xIntLeaves, uno::UNO_QUERY_THROW );
410 //iterate over all available leaves
411 uno::Sequence< OUString > seqLeafNames = xLeaves->getElementNames();
412 for ( int j = 0; j < seqLeafNames.getLength(); j++ )
414 uno::Any anyLeaf = xLeaves->getByName( seqLeafNames[j] );
415 uno::Reference< XInterface > xIntLeaf = anyLeaf.get< uno::Reference< XInterface > >();
416 uno::Reference< beans::XPropertySet > xLeaf( xIntLeaf, uno::UNO_QUERY_THROW );
417 //investigate the Id property if it matches the extension identifier which
418 //has been passed in.
419 uno::Any anyValue = xLeaf->getPropertyValue( OUSTR("Id") );
421 OUString sId = anyValue.get< OUString >();
422 if ( sId == aId.Value )
424 bOptions = true;
425 break;
428 if ( bOptions )
429 break;
431 return bOptions;
434 //------------------------------------------------------------------------------
435 // XEventListener
436 void TheExtensionManager::disposing( lang::EventObject const & rEvt )
437 throw ( uno::RuntimeException )
439 bool shutDown = (rEvt.Source == m_xDesktop);
441 if ( shutDown && m_xDesktop.is() )
443 m_xDesktop->removeTerminateListener( this );
444 m_xDesktop.clear();
447 if ( shutDown )
449 if ( dp_misc::office_is_running() )
451 const ::vos::OGuard guard( Application::GetSolarMutex() );
452 delete m_pExtMgrDialog;
453 m_pExtMgrDialog = NULL;
454 delete m_pUpdReqDialog;
455 m_pUpdReqDialog = NULL;
457 s_ExtMgr.clear();
461 //------------------------------------------------------------------------------
462 // XTerminateListener
463 void TheExtensionManager::queryTermination( ::lang::EventObject const & )
464 throw ( frame::TerminationVetoException, uno::RuntimeException )
466 DialogHelper *pDialogHelper = getDialogHelper();
468 if ( m_pExecuteCmdQueue->isBusy() || ( pDialogHelper && pDialogHelper->isBusy() ) )
470 ToTop( TOTOP_RESTOREWHENMIN );
471 throw frame::TerminationVetoException(
472 OUSTR("The office cannot be closed while the Extension Manager is running"),
473 uno::Reference<XInterface>(static_cast<frame::XTerminateListener*>(this), uno::UNO_QUERY));
475 else
477 if ( m_pExtMgrDialog )
478 m_pExtMgrDialog->Close();
479 if ( m_pUpdReqDialog )
480 m_pUpdReqDialog->Close();
484 //------------------------------------------------------------------------------
485 void TheExtensionManager::notifyTermination( ::lang::EventObject const & rEvt )
486 throw ( uno::RuntimeException )
488 disposing( rEvt );
491 //------------------------------------------------------------------------------
492 // XModifyListener
493 void TheExtensionManager::modified( ::lang::EventObject const & rEvt )
494 throw ( uno::RuntimeException )
496 uno::Reference< deployment::XPackageManager > xPackageManager( rEvt.Source, uno::UNO_QUERY );
497 if ( xPackageManager.is() )
499 getDialogHelper()->prepareChecking( xPackageManager );
500 createPackageList( xPackageManager );
501 getDialogHelper()->checkEntries();
505 //------------------------------------------------------------------------------
506 ::rtl::Reference< TheExtensionManager > TheExtensionManager::get( const uno::Reference< uno::XComponentContext > &xContext,
507 const uno::Reference< awt::XWindow > &xParent,
508 const OUString & extensionURL )
510 if ( s_ExtMgr.is() )
512 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
513 if ( extensionURL.getLength() )
514 s_ExtMgr->installPackage( extensionURL, true );
515 return s_ExtMgr;
518 Window * pParent = DIALOG_NO_PARENT;
519 if ( xParent.is() )
520 pParent = VCLUnoHelper::GetWindow(xParent);
522 ::rtl::Reference<TheExtensionManager> that( new TheExtensionManager( pParent, xContext ) );
524 const ::vos::OGuard guard( Application::GetSolarMutex() );
525 if ( ! s_ExtMgr.is() )
527 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
528 s_ExtMgr = that;
531 if ( extensionURL.getLength() )
532 s_ExtMgr->installPackage( extensionURL, true );
534 return s_ExtMgr;
537 } //namespace dp_gui