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