1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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
;
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
),
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
);
95 beans::PropertyValue
aValue( OUSTR("nodepath"), 0, uno::Any( OUSTR("/org.openoffice.Office.OptionsDialog/Nodes") ),
96 beans::PropertyState_DIRECT_VALUE
);
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
);
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
);
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() );
135 if ( !m_pUpdReqDialog
)
137 m_pUpdReqDialog
= new UpdateRequiredDialog( NULL
, this );
138 m_pExecuteCmdQueue
.reset( new ExtensionCmdQueue( (DialogHelper
*) m_pUpdReqDialog
, this, m_xContext
) );
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
);
151 //------------------------------------------------------------------------------
152 void TheExtensionManager::Show()
154 const ::vos::OGuard
guard( Application::GetSolarMutex() );
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();
186 //------------------------------------------------------------------------------
187 sal_Int16
TheExtensionManager::execute()
191 if ( m_pUpdReqDialog
)
193 nRet
= m_pUpdReqDialog
->Execute();
194 delete m_pUpdReqDialog
;
195 m_pUpdReqDialog
= NULL
;
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
;
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
& ) {
225 } catch ( ucb::CommandFailedException
& ) {
227 } catch ( ucb::CommandAbortedException
& ) {
229 } catch ( lang::IllegalArgumentException
& e
) {
230 throw uno::RuntimeException( e
.Message
, e
.Context
);
234 m_pExecuteCmdQueue
->checkForUpdates( vEntries
);
238 //------------------------------------------------------------------------------
239 bool TheExtensionManager::enablePackage( const uno::Reference
< deployment::XPackage
> &xPackage
,
242 m_pExecuteCmdQueue
->enableExtension( xPackage
, bEnable
);
247 //------------------------------------------------------------------------------
248 bool TheExtensionManager::removePackage( const uno::Reference
< deployment::XPackageManager
> &xPackageManager
,
249 const uno::Reference
< deployment::XPackage
> &xPackage
)
251 m_pExecuteCmdQueue
->removeExtension( xPackageManager
, xPackage
);
256 //------------------------------------------------------------------------------
257 bool TheExtensionManager::updatePackages( const std::vector
< TUpdateListEntry
> &vList
)
259 m_pExecuteCmdQueue
->checkForUpdates( vList
);
264 //------------------------------------------------------------------------------
265 bool TheExtensionManager::installPackage( const OUString
&rPackageURL
, bool bWarnUser
)
267 if ( rPackageURL
.getLength() == 0 )
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
);
284 if ( bInstallForAll
)
285 m_pExecuteCmdQueue
->addExtension( xSharedPkgMgr
, rPackageURL
, false );
287 m_pExecuteCmdQueue
->addExtension( xUserPkgMgr
, rPackageURL
, bWarnUser
);
292 //------------------------------------------------------------------------------
293 bool TheExtensionManager::queryTermination()
295 if ( dp_misc::office_is_running() )
297 // the standalone application unopkg must not close ( and quit ) the dialog
298 // when there are still actions in the queue
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
;
316 //------------------------------------------------------------------------------
317 bool TheExtensionManager::createPackageList( const uno::Reference
< deployment::XPackageManager
> &xPackageManager
)
319 uno::Sequence
< uno::Reference
< deployment::XPackage
> > packages
;
322 packages
= xPackageManager
->getDeployedPackages( uno::Reference
< task::XAbortChannel
>(),
323 uno::Reference
< ucb::XCommandEnvironment
>() );
324 } catch ( deployment::DeploymentException
& ) {
325 //handleGeneralError(e.Cause);
327 } catch ( ucb::CommandFailedException
& ) {
328 //handleGeneralError(e.Reason);
330 } catch ( ucb::CommandAbortedException
& ) {
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
);
344 //------------------------------------------------------------------------------
345 void TheExtensionManager::createPackageList()
347 for ( sal_Int32 i
= 0; i
< m_sPackageManagers
.getLength(); ++i
)
349 if ( ! createPackageList( m_sPackageManagers
[i
] ) )
354 //------------------------------------------------------------------------------
355 PackageState
TheExtensionManager::getPackageState( const uno::Reference
< deployment::XPackage
> &xPackage
) const
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
)
367 return reg
.Value
? REGISTERED
: NOT_REGISTERED
;
370 return NOT_AVAILABLE
;
372 catch ( uno::RuntimeException
& ) {
375 catch ( uno::Exception
& 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() )
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
)
434 //------------------------------------------------------------------------------
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 );
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
;
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
));
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
)
491 //------------------------------------------------------------------------------
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
)
512 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
513 if ( extensionURL
.getLength() )
514 s_ExtMgr
->installPackage( extensionURL
, true );
518 Window
* pParent
= DIALOG_NO_PARENT
;
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();
531 if ( extensionURL
.getLength() )
532 s_ExtMgr
->installPackage( extensionURL
, true );