1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_framework.hxx"
30 
31 //_________________________________________________________________________________________________________________
32 //	my own includes
33 //_________________________________________________________________________________________________________________
34 #include <helper/ocomponentaccess.hxx>
35 #include <helper/ocomponentenumeration.hxx>
36 
37 #ifndef _FRAMEWORK_THREADHELP_RESETABLEGUARD_HXX_
38 #include <threadhelp/resetableguard.hxx>
39 #endif
40 
41 //_________________________________________________________________________________________________________________
42 //	interface includes
43 //_________________________________________________________________________________________________________________
44 #include <com/sun/star/frame/FrameSearchFlag.hpp>
45 
46 //_________________________________________________________________________________________________________________
47 //	includes of other projects
48 //_________________________________________________________________________________________________________________
49 #include <vcl/svapp.hxx>
50 
51 //_________________________________________________________________________________________________________________
52 //	namespace
53 //_________________________________________________________________________________________________________________
54 
55 namespace framework{
56 
57 using namespace ::com::sun::star::container		;
58 using namespace ::com::sun::star::frame			;
59 using namespace ::com::sun::star::lang			;
60 using namespace ::com::sun::star::uno			;
61 using namespace ::cppu							;
62 using namespace ::osl							;
63 using namespace ::rtl							;
64 
65 //_________________________________________________________________________________________________________________
66 //	non exported const
67 //_________________________________________________________________________________________________________________
68 
69 //_________________________________________________________________________________________________________________
70 //	non exported definitions
71 //_________________________________________________________________________________________________________________
72 
73 //_________________________________________________________________________________________________________________
74 //	declarations
75 //_________________________________________________________________________________________________________________
76 
77 //*****************************************************************************************************************
78 //	constructor
79 //*****************************************************************************************************************
80 OComponentAccess::OComponentAccess( const css::uno::Reference< XDesktop >& xOwner )
81 		//	Init baseclasses first
82         :   ThreadHelpBase  ( &Application::GetSolarMutex() )
83 		// Init member
84         ,   m_xOwner        ( xOwner                        )
85 {
86 	// Safe impossible cases
87     LOG_ASSERT( impldbg_checkParameter_OComponentAccessCtor( xOwner ), "OComponentAccess::OComponentAccess()\nInvalid parameter detected!\n" )
88 }
89 
90 //*****************************************************************************************************************
91 //	destructor
92 //*****************************************************************************************************************
93 OComponentAccess::~OComponentAccess()
94 {
95 }
96 
97 //*****************************************************************************************************************
98 //	XEnumerationAccess
99 //*****************************************************************************************************************
100 css::uno::Reference< XEnumeration > SAL_CALL OComponentAccess::createEnumeration() throw( RuntimeException )
101 {
102 	// Ready for multithreading
103 	ResetableGuard aGuard( m_aLock );
104 
105 	// Set default return value, if method failed.
106 	// If no desktop exist and there is no task container - return an empty enumeration!
107 	css::uno::Reference< XEnumeration > xReturn = css::uno::Reference< XEnumeration >();
108 
109 	// Try to "lock" the desktop for access to task container.
110 	css::uno::Reference< XInterface > xLock = m_xOwner.get();
111 	if ( xLock.is() == sal_True )
112 	{
113 		// Desktop exist => pointer to task container must be valid.
114 		// Initialize a new enumeration ... if some tasks and his components exist!
115 		// (OTasksEnumeration will make an assert, if we initialize the new instance without valid values!)
116 
117 		Sequence< css::uno::Reference< XComponent > > seqComponents;
118 		impl_collectAllChildComponents( css::uno::Reference< XFramesSupplier >( xLock, UNO_QUERY ), seqComponents );
119 		OComponentEnumeration* pEnumeration = new OComponentEnumeration( seqComponents );
120 		xReturn = css::uno::Reference< XEnumeration >( (OWeakObject*)pEnumeration, UNO_QUERY );
121 	}
122 
123 	// Return result of this operation.
124 	return xReturn;
125 }
126 
127 //*****************************************************************************************************************
128 //	XElementAccess
129 //*****************************************************************************************************************
130 Type SAL_CALL OComponentAccess::getElementType() throw( RuntimeException )
131 {
132 	// Elements in list an enumeration are components!
133 	// Return the uno-type of XComponent.
134 	return ::getCppuType((const css::uno::Reference< XComponent >*)NULL);
135 }
136 
137 //*****************************************************************************************************************
138 //	XElementAccess
139 //*****************************************************************************************************************
140 sal_Bool SAL_CALL OComponentAccess::hasElements() throw( RuntimeException )
141 {
142 	// Ready for multithreading
143 	ResetableGuard aGuard( m_aLock );
144 
145 	// Set default return value, if method failed.
146 	sal_Bool bReturn = sal_False;
147 
148 	// Try to "lock" the desktop for access to task container.
149 	css::uno::Reference< XFramesSupplier > xLock( m_xOwner.get(), UNO_QUERY );
150 	if ( xLock.is() == sal_True )
151 	{
152 		// Ask container of owner for existing elements.
153 		bReturn = xLock->getFrames()->hasElements();
154 	}
155 
156 	// Return result of this operation.
157 	return bReturn;
158 }
159 
160 //*****************************************************************************************************************
161 //	private method
162 //*****************************************************************************************************************
163 void OComponentAccess::impl_collectAllChildComponents(	const	css::uno::Reference< XFramesSupplier >&			xNode			,
164 	 															Sequence< css::uno::Reference< XComponent > >&	seqComponents	)
165 {
166 	// If valid node was given ...
167 	if( xNode.is() == sal_True )
168 	{
169 		// ... continue collection at these.
170 
171 		// Get the container of current node, collect the components of existing child frames
172 		// and go down to next level in tree (recursive!).
173 
174 		sal_Int32 nComponentCount = seqComponents.getLength();
175 
176 		const css::uno::Reference< XFrames >				xContainer	= xNode->getFrames();
177 		const Sequence< css::uno::Reference< XFrame > >	seqFrames	= xContainer->queryFrames( FrameSearchFlag::CHILDREN );
178 
179 		const sal_Int32 nFrameCount = seqFrames.getLength();
180 		for( sal_Int32 nFrame=0; nFrame<nFrameCount; ++nFrame )
181 		{
182 			css::uno::Reference< XComponent > xComponent = impl_getFrameComponent( seqFrames[nFrame] );
183 			if( xComponent.is() == sal_True )
184 			{
185 				nComponentCount++;
186 				seqComponents.realloc( nComponentCount );
187 				seqComponents[nComponentCount-1] = xComponent;
188 			}
189 		}
190 	}
191 	// ... otherwise break a recursive path and go back at current stack!
192 }
193 
194 //*****************************************************************************************************************
195 //	private method
196 //*****************************************************************************************************************
197 css::uno::Reference< XComponent > OComponentAccess::impl_getFrameComponent( const css::uno::Reference< XFrame >& xFrame ) const
198 {
199 	// Set default return value, if method failed.
200 	css::uno::Reference< XComponent > xComponent = css::uno::Reference< XComponent >();
201 	// Does no controller exists?
202 	css::uno::Reference< XController > xController = xFrame->getController();
203 	if ( xController.is() == sal_False )
204 	{
205 		// Controller not exist - use the VCL-component.
206 		xComponent = css::uno::Reference< XComponent >( xFrame->getComponentWindow(), UNO_QUERY );
207 	}
208 	else
209 	{
210 		// Does no model exists?
211 		css::uno::Reference< XModel > xModel( xController->getModel(), UNO_QUERY );
212 		if ( xModel.is() == sal_True )
213 		{
214 			// Model exist - use the model as component.
215 			xComponent = css::uno::Reference< XComponent >( xModel, UNO_QUERY );
216 		}
217 		else
218 		{
219 			// Model not exist - use the controller as component.
220 			xComponent = css::uno::Reference< XComponent >( xController, UNO_QUERY );
221 		}
222 	}
223 
224 	return xComponent;
225 }
226 
227 //_________________________________________________________________________________________________________________
228 //	debug methods
229 //_________________________________________________________________________________________________________________
230 
231 /*-----------------------------------------------------------------------------------------------------------------
232 	The follow methods checks the parameter for other functions. If a parameter or his value is non valid,
233 	we return "sal_False". (else sal_True) This mechanism is used to throw an ASSERT!
234 
235 	ATTENTION
236 
237 		If you miss a test for one of this parameters, contact the autor or add it himself !(?)
238 		But ... look for right testing! See using of this methods!
239 -----------------------------------------------------------------------------------------------------------------*/
240 
241 #ifdef ENABLE_ASSERTIONS
242 
243 //*****************************************************************************************************************
244 sal_Bool OComponentAccess::impldbg_checkParameter_OComponentAccessCtor( const   css::uno::Reference< XDesktop >&      xOwner  )
245 {
246 	// Set default return value.
247 	sal_Bool bOK = sal_True;
248 	// Check parameter.
249 	if	(
250 			( &xOwner		==	NULL		)	||
251 			( xOwner.is()	==	sal_False	)
252 		)
253 	{
254 		bOK = sal_False ;
255 	}
256 	// Return result of check.
257 	return bOK ;
258 }
259 
260 #endif	//	#ifdef ENABLE_ASSERTIONS
261 
262 }		//	namespace framework
263