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_svx.hxx"
30 
31 #include <algorithm>
32 
33 #include "unogaltheme.hxx"
34 #include "unogalitem.hxx"
35 #include "svx/galtheme.hxx"
36 #include "svx/gallery1.hxx"
37 #include "svx/galmisc.hxx"
38 #include <svx/fmmodel.hxx>
39 #include <rtl/uuid.h>
40 #include <vos/mutex.hxx>
41 #ifndef _SV_SVAPP_HXX_
42 #include <vcl/svapp.hxx>
43 #endif
44 #include <unotools/pathoptions.hxx>
45 
46 using namespace ::com::sun::star;
47 
48 namespace unogallery {
49 
50 // -----------------
51 // - GalleryTheme -
52 // -----------------
53 
54 GalleryTheme::GalleryTheme( const ::rtl::OUString& rThemeName )
55 {
56 	mpGallery = ::Gallery::GetGalleryInstance();
57 	mpTheme = ( mpGallery ? mpGallery->AcquireTheme( rThemeName, *this ) : NULL );
58 
59 	if( mpGallery )
60 		StartListening( *mpGallery );
61 }
62 
63 // ------------------------------------------------------------------------------
64 
65 GalleryTheme::~GalleryTheme()
66 {
67 	const ::vos::OGuard aGuard( Application::GetSolarMutex() );
68 
69 	DBG_ASSERT( !mpTheme || mpGallery, "Theme is living without Gallery" );
70 
71 	implReleaseItems( NULL );
72 
73 	if( mpGallery )
74 	{
75 		EndListening( *mpGallery );
76 
77 		if( mpTheme )
78 			mpGallery->ReleaseTheme( mpTheme, *this );
79 	}
80 }
81 
82 // ------------------------------------------------------------------------------
83 
84 ::rtl::OUString GalleryTheme::getImplementationName_Static()
85 	throw()
86 {
87 	return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.gallery.GalleryTheme" ) );
88 }
89 
90 // ------------------------------------------------------------------------------
91 
92 uno::Sequence< ::rtl::OUString > GalleryTheme::getSupportedServiceNames_Static()
93 	throw()
94 {
95 	uno::Sequence< ::rtl::OUString > aSeq( 1 );
96 
97 	aSeq.getArray()[ 0 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.gallery.GalleryTheme" ) );
98 
99 	return aSeq;
100 }
101 
102 // ------------------------------------------------------------------------------
103 
104 ::rtl::OUString SAL_CALL GalleryTheme::getImplementationName()
105 	throw( uno::RuntimeException )
106 {
107 	return getImplementationName_Static();
108 }
109 
110 // ------------------------------------------------------------------------------
111 
112 sal_Bool SAL_CALL GalleryTheme::supportsService( const ::rtl::OUString& ServiceName )
113 	throw( uno::RuntimeException )
114 {
115     uno::Sequence< ::rtl::OUString >	aSNL( getSupportedServiceNames() );
116     const ::rtl::OUString*				pArray = aSNL.getConstArray();
117 
118     for( int i = 0; i < aSNL.getLength(); i++ )
119         if( pArray[i] == ServiceName )
120             return true;
121 
122     return false;
123 }
124 
125 // ------------------------------------------------------------------------------
126 
127 uno::Sequence< ::rtl::OUString > SAL_CALL GalleryTheme::getSupportedServiceNames()
128 	throw( uno::RuntimeException )
129 {
130 	return getSupportedServiceNames_Static();
131 }
132 
133 // ------------------------------------------------------------------------------
134 
135 uno::Sequence< uno::Type > SAL_CALL GalleryTheme::getTypes()
136 	throw(uno::RuntimeException)
137 {
138 	uno::Sequence< uno::Type >	aTypes( 5 );
139 	uno::Type* 					pTypes = aTypes.getArray();
140 
141 	*pTypes++ = ::getCppuType((const uno::Reference< lang::XServiceInfo>*)0);
142 	*pTypes++ = ::getCppuType((const uno::Reference< lang::XTypeProvider>*)0);
143 	*pTypes++ = ::getCppuType((const uno::Reference< container::XElementAccess>*)0);
144 	*pTypes++ = ::getCppuType((const uno::Reference< container::XIndexAccess>*)0);
145 	*pTypes++ = ::getCppuType((const uno::Reference< gallery::XGalleryTheme>*)0);
146 
147 	return aTypes;
148 }
149 
150 // ------------------------------------------------------------------------------
151 
152 uno::Sequence< sal_Int8 > SAL_CALL GalleryTheme::getImplementationId()
153 	throw(uno::RuntimeException)
154 {
155 	const vos::OGuard 					aGuard( Application::GetSolarMutex() );
156 	static uno::Sequence< sal_Int8 >	aId;
157 
158 	if( aId.getLength() == 0 )
159 	{
160 		aId.realloc( 16 );
161 		rtl_createUuid( reinterpret_cast< sal_uInt8* >( aId.getArray() ), 0, sal_True );
162 	}
163 
164 	return aId;
165 }
166 
167 // ------------------------------------------------------------------------------
168 
169 uno::Type SAL_CALL GalleryTheme::getElementType()
170 	throw (uno::RuntimeException)
171 {
172 	return ::getCppuType( (const uno::Reference< gallery::XGalleryItem >*) 0);
173 }
174 
175 // ------------------------------------------------------------------------------
176 
177 sal_Bool SAL_CALL GalleryTheme::hasElements()
178 	throw (uno::RuntimeException)
179 {
180 	const ::vos::OGuard aGuard( Application::GetSolarMutex() );
181 
182 	return( ( mpTheme != NULL ) && ( mpTheme->GetObjectCount() > 0 ) );
183 }
184 
185 // ------------------------------------------------------------------------------
186 
187 sal_Int32 SAL_CALL GalleryTheme::getCount()
188 	throw (uno::RuntimeException)
189 {
190 	const ::vos::OGuard aGuard( Application::GetSolarMutex() );
191 
192 	return( mpTheme ? mpTheme->GetObjectCount() : 0 );
193 }
194 
195 // ------------------------------------------------------------------------------
196 
197 uno::Any SAL_CALL GalleryTheme::getByIndex( ::sal_Int32 nIndex )
198 	throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException)
199 {
200 	const ::vos::OGuard aGuard( Application::GetSolarMutex() );
201 	uno::Any 			aRet;
202 
203 	if( mpTheme )
204 	{
205 		if( ( nIndex < 0 ) || ( nIndex >= getCount() ) )
206 		{
207 			throw lang::IndexOutOfBoundsException();
208 		}
209 		else
210 		{
211 			const GalleryObject* pObj = mpTheme->ImplGetGalleryObject( nIndex );
212 
213 			if( pObj )
214 				aRet = uno::makeAny( uno::Reference< gallery::XGalleryItem >( new GalleryItem( *this, *pObj ) ) );
215 		}
216 	}
217 
218 	return aRet;
219 }
220 
221 // ------------------------------------------------------------------------------
222 
223 ::rtl::OUString SAL_CALL GalleryTheme::getName(  )
224 	throw (uno::RuntimeException)
225 {
226 	const ::vos::OGuard aGuard( Application::GetSolarMutex() );
227 	::rtl::OUString 	aRet;
228 
229 	if( mpTheme )
230 		aRet = mpTheme->GetName();
231 
232 	return aRet;
233 }
234 
235 // ------------------------------------------------------------------------------
236 
237 void SAL_CALL GalleryTheme::update(  )
238 	throw (uno::RuntimeException)
239 {
240 	const ::vos::OGuard aGuard( Application::GetSolarMutex() );
241 
242 	if( mpTheme )
243 	{
244 		const Link aDummyLink;
245 		mpTheme->Actualize( aDummyLink );
246 	}
247 }
248 
249 // ------------------------------------------------------------------------------
250 
251 ::sal_Int32 SAL_CALL GalleryTheme::insertURLByIndex(
252 	const ::rtl::OUString& rURL, ::sal_Int32 nIndex )
253 	throw (lang::WrappedTargetException, uno::RuntimeException)
254 {
255 	const ::vos::OGuard aGuard( Application::GetSolarMutex() );
256 	sal_Int32			nRet = -1;
257 
258 	if( mpTheme )
259 	{
260 		try
261 		{
262 			const INetURLObject aURL( rURL );
263 
264 			nIndex = ::std::max( ::std::min( nIndex, getCount() ), sal_Int32( 0 ) );
265 
266 			if( ( aURL.GetProtocol() != INET_PROT_NOT_VALID ) && mpTheme->InsertURL( aURL, nIndex ) )
267 			{
268 				const GalleryObject* pObj = mpTheme->ImplGetGalleryObject( aURL );
269 
270 				if( pObj )
271 					nRet = mpTheme->ImplGetGalleryObjectPos( pObj );
272 			}
273 		}
274 		catch( ... )
275 		{
276 		}
277 	}
278 
279 	return nRet;
280 }
281 
282 // ------------------------------------------------------------------------------
283 
284 ::sal_Int32 SAL_CALL GalleryTheme::insertGraphicByIndex(
285 	const uno::Reference< graphic::XGraphic >& rxGraphic, sal_Int32 nIndex )
286 	throw (lang::WrappedTargetException, uno::RuntimeException)
287 {
288 	const ::vos::OGuard aGuard( Application::GetSolarMutex() );
289 	sal_Int32 			nRet = -1;
290 
291 	if( mpTheme )
292 	{
293 		try
294 		{
295 			const Graphic aGraphic( rxGraphic );
296 
297 			nIndex = ::std::max( ::std::min( nIndex, getCount() ), sal_Int32( 0 ) );
298 
299 			if( mpTheme->InsertGraphic( aGraphic, nIndex ) )
300 				nRet = nIndex;
301 		}
302 		catch( ... )
303 		{
304 		}
305 	}
306 
307 	return nRet;
308 }
309 
310 // ------------------------------------------------------------------------------
311 
312 ::sal_Int32 SAL_CALL GalleryTheme::insertDrawingByIndex(
313 	const uno::Reference< lang::XComponent >& Drawing, sal_Int32 nIndex )
314 	throw (lang::WrappedTargetException, uno::RuntimeException)
315 {
316 	const ::vos::OGuard aGuard( Application::GetSolarMutex() );
317 	sal_Int32 			nRet = -1;
318 
319 	if( mpTheme )
320 	{
321 		GalleryDrawingModel* pModel = GalleryDrawingModel::getImplementation( Drawing );
322 
323 		if( pModel && pModel->GetDoc() && pModel->GetDoc()->ISA( FmFormModel ) )
324 		{
325 			nIndex = ::std::max( ::std::min( nIndex, getCount() ), sal_Int32( 0 ) );
326 
327 			if( mpTheme->InsertModel( *static_cast< FmFormModel* >( pModel->GetDoc() ), nIndex ) )
328 				nRet = nIndex;
329 		}
330 	}
331 
332 	return nRet;
333 }
334 
335 // ------------------------------------------------------------------------------
336 
337 void SAL_CALL GalleryTheme::removeByIndex( sal_Int32 nIndex )
338 	throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
339 {
340 	const ::vos::OGuard aGuard( Application::GetSolarMutex() );
341 
342 	if( mpTheme )
343 	{
344 		if( ( nIndex < 0 ) || ( nIndex >= getCount() ) )
345 			throw lang::IndexOutOfBoundsException();
346 		else
347 			mpTheme->RemoveObject( nIndex );
348 	}
349 }
350 
351 // ------------------------------------------------------------------------------
352 
353 void GalleryTheme::Notify( SfxBroadcaster&, const SfxHint& rHint )
354 {
355 	const ::vos::OGuard aGuard( Application::GetSolarMutex() );
356 	const GalleryHint& 	rGalleryHint = static_cast< const GalleryHint& >( rHint );
357 
358 	switch( rGalleryHint.GetType() )
359 	{
360 		case( GALLERY_HINT_CLOSE_THEME ):
361 		{
362 			DBG_ASSERT( !mpTheme || mpGallery, "Theme is living without Gallery" );
363 
364 			implReleaseItems( NULL );
365 
366 			if( mpGallery && mpTheme )
367 			{
368 				mpGallery->ReleaseTheme( mpTheme, *this );
369 				mpTheme = NULL;
370 			}
371 		}
372 		break;
373 
374 		case( GALLERY_HINT_CLOSE_OBJECT ):
375 		{
376 			GalleryObject* pObj = reinterpret_cast< GalleryObject* >( rGalleryHint.GetData1() );
377 
378 			if( pObj )
379 				implReleaseItems( pObj );
380 		}
381 		break;
382 
383 		default:
384 		break;
385 	}
386 }
387 
388 // ------------------------------------------------------------------------------
389 
390 void GalleryTheme::implReleaseItems( GalleryObject* pObj )
391 {
392 	const ::vos::OGuard aGuard( Application::GetSolarMutex() );
393 
394 	for( GalleryItemList::iterator aIter = maItemList.begin(); aIter != maItemList.end();  )
395 	{
396 		if( !pObj || ( (*aIter)->implGetObject() == pObj ) )
397 		{
398 			(*aIter)->implSetInvalid();
399 			aIter = maItemList.erase( aIter );
400 		}
401 		else
402 			++aIter;
403 	}
404 }
405 
406 // ------------------------------------------------------------------------------
407 
408 ::GalleryTheme*	GalleryTheme::implGetTheme() const
409 {
410 	return mpTheme;
411 }
412 
413 // ------------------------------------------------------------------------------
414 
415 void GalleryTheme::implRegisterGalleryItem( ::unogallery::GalleryItem& rItem )
416 {
417 	const ::vos::OGuard aGuard( Application::GetSolarMutex() );
418 
419 //	DBG_ASSERT( maItemList.find( &rItem ) == maItemList.end(), "Item already registered" );
420 	maItemList.push_back( &rItem );
421 }
422 
423 // ------------------------------------------------------------------------------
424 
425 void GalleryTheme::implDeregisterGalleryItem( ::unogallery::GalleryItem& rItem )
426 {
427 	const ::vos::OGuard aGuard( Application::GetSolarMutex() );
428 
429 //	DBG_ASSERT( maItemList.find( &rItem ) != maItemList.end(), "Item is not registered" );
430 	maItemList.remove( &rItem );
431 }
432 
433 }
434