xref: /trunk/main/svx/source/gallery2/galobj.cxx (revision cdf0e10c)
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 #define ENABLE_BYTESTRING_STREAM_OPERATORS
32 
33 #include <com/sun/star/lang/XUnoTunnel.hpp>
34 #include <sfx2/objsh.hxx>
35 #include <sfx2/docfac.hxx>
36 
37 #include <comphelper/classids.hxx>
38 #include <unotools/pathoptions.hxx>
39 
40 #include <tools/rcid.h>
41 #include <tools/vcompat.hxx>
42 #include <vcl/virdev.hxx>
43 #include <svl/itempool.hxx>
44 #include <svx/fmmodel.hxx>
45 #include <svx/fmview.hxx>
46 #include <svx/fmpage.hxx>
47 #include "gallery.hrc"
48 #include "svx/galmisc.hxx"
49 #include "galobj.hxx"
50 #include <vcl/salbtype.hxx>		// FRound
51 #include <vcl/svapp.hxx>
52 
53 #include "gallerydrawmodel.hxx"
54 
55 using namespace ::com::sun::star;
56 
57 // -------------
58 // - SgaObject -
59 // -------------
60 
61 SgaObject::SgaObject() :
62 		bIsValid    ( sal_False ),
63 		bIsThumbBmp	( sal_True )
64 {
65 }
66 
67 // ------------------------------------------------------------------------
68 
69 sal_Bool SgaObject::CreateThumb( const Graphic& rGraphic )
70 {
71 	sal_Bool bRet = sal_False;
72 
73 	if( rGraphic.GetType() == GRAPHIC_BITMAP )
74 	{
75 		BitmapEx    aBmpEx( rGraphic.GetBitmapEx() );
76 		Size        aBmpSize( aBmpEx.GetSizePixel() );
77 
78 		if( aBmpSize.Width() && aBmpSize.Height() )
79 		{
80 			const Color	aWhite( COL_WHITE );
81 
82 		    if( aBmpEx.GetPrefMapMode().GetMapUnit() != MAP_PIXEL &&
83 		        aBmpEx.GetPrefSize().Width() > 0 &&
84 		        aBmpEx.GetPrefSize().Height() > 0 )
85 		    {
86 		        Size aLogSize( OutputDevice::LogicToLogic( aBmpEx.GetPrefSize(), aBmpEx.GetPrefMapMode(), MAP_100TH_MM ) );
87 
88 		        if( aLogSize.Width() > 0 && aLogSize.Height() > 0 )
89 		        {
90 		            double  fFactorLog = static_cast< double >( aLogSize.Width() ) / aLogSize.Height();
91 		            double  fFactorPix = static_cast< double >( aBmpSize.Width() ) / aBmpSize.Height();
92 
93 		            if( fFactorPix > fFactorLog )
94 		                aBmpSize.Width() = FRound( aBmpSize.Height() * fFactorLog );
95 		            else
96 		                aBmpSize.Height() = FRound( aBmpSize.Width() / fFactorLog );
97 
98 		            aBmpEx.SetSizePixel( aBmpSize );
99 		        }
100 		    }
101 
102 			aThumbBmp = aBmpEx.GetBitmap( &aWhite );
103 
104 			if( ( aBmpSize.Width() <= S_THUMB ) && ( aBmpSize.Height() <= S_THUMB ) )
105 			{
106 				aThumbBmp.Convert( BMP_CONVERSION_8BIT_COLORS );
107 				bRet = sal_True;
108 			}
109 			else
110 			{
111 				const float	fFactor  = (float) aBmpSize.Width() / aBmpSize.Height();
112 				const Size	aNewSize( Max( (long) (fFactor < 1. ? S_THUMB * fFactor : S_THUMB), 8L ),
113 									  Max( (long) (fFactor < 1. ? S_THUMB : S_THUMB / fFactor), 8L ) );
114 
115 				if( aThumbBmp.Scale( (double) aNewSize.Width() / aBmpSize.Width(),
116 									 (double) aNewSize.Height() / aBmpSize.Height(), BMP_SCALE_INTERPOLATE ) )
117 				{
118 					aThumbBmp.Convert( BMP_CONVERSION_8BIT_COLORS );
119 					bRet = sal_True;
120 				}
121 			}
122 		}
123 	}
124 	else if( rGraphic.GetType() == GRAPHIC_GDIMETAFILE )
125 	{
126 		const Size aPrefSize( rGraphic.GetPrefSize() );
127 		const double fFactor  = (double)aPrefSize.Width() / (double)aPrefSize.Height();
128         Size aSize( S_THUMB, S_THUMB );
129 		if ( fFactor < 1.0 )
130 			aSize.Width() = (sal_Int32)( S_THUMB * fFactor );
131 		else
132 			aSize.Height() = (sal_Int32)( S_THUMB / fFactor );
133 
134         const GraphicConversionParameters aParameters(aSize);
135         aThumbBmp = rGraphic.GetBitmap(aParameters);
136 
137 		if( !aThumbBmp.IsEmpty() )
138 		{
139 			aThumbBmp.Convert( BMP_CONVERSION_8BIT_COLORS );
140 			bRet = sal_True;
141 		}
142 	}
143 
144 	return bRet;
145 }
146 
147 // ------------------------------------------------------------------------
148 
149 void SgaObject::WriteData( SvStream& rOut, const String& rDestDir ) const
150 {
151 	static const sal_uInt32 nInventor = COMPAT_FORMAT( 'S', 'G', 'A', '3' );
152 
153 	rOut << nInventor << (sal_uInt16) 0x0004 << GetVersion() << (sal_uInt16) GetObjKind();
154 	rOut << bIsThumbBmp;
155 
156 	if( bIsThumbBmp )
157 	{
158 		const sal_uInt16	nOldCompressMode = rOut.GetCompressMode();
159 		const sal_uIntPtr		nOldVersion = rOut.GetVersion();
160 
161 		rOut.SetCompressMode( COMPRESSMODE_ZBITMAP );
162 		rOut.SetVersion( SOFFICE_FILEFORMAT_50 );
163 
164 		rOut << aThumbBmp;
165 
166 		rOut.SetVersion( nOldVersion );
167 		rOut.SetCompressMode( nOldCompressMode );
168 	}
169 	else
170 		rOut << aThumbMtf;
171 
172 	String aURLWithoutDestDir = String(aURL.GetMainURL( INetURLObject::NO_DECODE ));
173 	aURLWithoutDestDir.SearchAndReplace(rDestDir, String());
174 	rOut << ByteString( aURLWithoutDestDir, RTL_TEXTENCODING_UTF8 );
175 }
176 
177 // ------------------------------------------------------------------------
178 
179 void SgaObject::ReadData(SvStream& rIn, sal_uInt16& rReadVersion )
180 {
181 	ByteString	aTmpStr;
182 	sal_uInt32		nTmp32;
183 	sal_uInt16		nTmp16;
184 
185 	rIn >> nTmp32 >> nTmp16 >> rReadVersion >> nTmp16 >> bIsThumbBmp;
186 
187 	if( bIsThumbBmp )
188 		rIn >> aThumbBmp;
189 	else
190 		rIn >> aThumbMtf;
191 
192 	rIn >> aTmpStr; aURL = INetURLObject( String( aTmpStr.GetBuffer(), RTL_TEXTENCODING_UTF8 ) );
193 }
194 
195 // ------------------------------------------------------------------------
196 
197 const String SgaObject::GetTitle() const
198 {
199 	String aReturnValue( aTitle );
200 	if ( !getenv( "GALLERY_SHOW_PRIVATE_TITLE" ) )
201 	{
202 		if ( aReturnValue.GetTokenCount( ':' ) == 3 )
203 		{
204 			String		aPrivateInd  ( aReturnValue.GetToken( 0, ':' ) );
205 			String		aResourceName( aReturnValue.GetToken( 1, ':' ) );
206 			sal_Int32	nResId		 ( aReturnValue.GetToken( 2, ':' ).ToInt32() );
207 			if ( aReturnValue.GetToken( 0, ':' ).EqualsAscii( "private" ) &&
208 				aResourceName.Len() && ( nResId > 0 ) && ( nResId < 0x10000 ) )
209 			{
210 				ByteString aMgrName( aResourceName, RTL_TEXTENCODING_UTF8 );
211 				ResMgr* pResMgr = ResMgr::CreateResMgr( aMgrName.GetBuffer(),
212 							Application::GetSettings().GetUILocale() );
213 				if ( pResMgr )
214 				{
215 					ResId aResId( (sal_uInt16)nResId, *pResMgr );
216 					aResId.SetRT( RSC_STRING );
217 					if ( pResMgr->IsAvailable( aResId ) )
218 					{
219 						aReturnValue = String( aResId );
220 					}
221 					delete pResMgr;
222 				}
223 			}
224 		}
225 	}
226 	return aReturnValue;
227 }
228 
229 // ------------------------------------------------------------------------
230 
231 void SgaObject::SetTitle( const String& rTitle )
232 {
233 	aTitle = rTitle;
234 }
235 
236 // ------------------------------------------------------------------------
237 
238 SvStream& operator<<( SvStream& rOut, const SgaObject& rObj )
239 {
240 	rObj.WriteData( rOut, String() );
241 	return rOut;
242 }
243 
244 // ------------------------------------------------------------------------
245 
246 SvStream& operator>>( SvStream& rIn, SgaObject& rObj )
247 {
248 	sal_uInt16 nReadVersion;
249 
250 	rObj.ReadData( rIn, nReadVersion );
251 	rObj.bIsValid = ( rIn.GetError() == ERRCODE_NONE );
252 
253 	return rIn;
254 }
255 
256 // ----------------
257 // - SgaObjectBmp -
258 // ----------------
259 
260 SgaObjectBmp::SgaObjectBmp()
261 {
262 }
263 
264 // ------------------------------------------------------------------------
265 
266 SgaObjectBmp::SgaObjectBmp( const INetURLObject& rURL )
267 {
268 	Graphic aGraphic;
269 	String	aFilter;
270 
271 	if ( SGA_IMPORT_NONE != GalleryGraphicImport( rURL, aGraphic, aFilter ) )
272 		Init( aGraphic, rURL );
273 }
274 
275 // ------------------------------------------------------------------------
276 
277 SgaObjectBmp::SgaObjectBmp( const Graphic& rGraphic, const INetURLObject& rURL, const String& )
278 {
279 	if( FileExists( rURL ) )
280 		Init( rGraphic, rURL );
281 }
282 
283 // ------------------------------------------------------------------------
284 
285 void SgaObjectBmp::Init( const Graphic& rGraphic, const INetURLObject& rURL )
286 {
287 	aURL = rURL;
288 	bIsValid = CreateThumb( rGraphic );
289 }
290 
291 // ------------------------------------------------------------------------
292 
293 void SgaObjectBmp::WriteData( SvStream& rOut, const String& rDestDir ) const
294 {
295 	String	aDummyStr;
296 	char	aDummy[ 10 ];
297 
298 	// Version setzen
299 	SgaObject::WriteData( rOut, rDestDir );
300 	rOut.Write( aDummy, 10 );
301 	rOut << ByteString( aDummyStr, RTL_TEXTENCODING_UTF8 ) << ByteString( aTitle, RTL_TEXTENCODING_UTF8 );
302 }
303 
304 // ------------------------------------------------------------------------
305 
306 void SgaObjectBmp::ReadData( SvStream& rIn, sal_uInt16& rReadVersion )
307 {
308 	ByteString aTmpStr;
309 
310 	SgaObject::ReadData( rIn, rReadVersion );
311 	rIn.SeekRel( 10 ); // 16, 16, 32, 16
312 	rIn >> aTmpStr; // dummy
313 
314 	if( rReadVersion >= 5 )
315 	{
316 		rIn >> aTmpStr; aTitle = String( aTmpStr.GetBuffer(), RTL_TEXTENCODING_UTF8 );
317 	}
318 }
319 
320 // ------------------
321 // - SgaObjectSound -
322 // ------------------
323 DBG_NAME(SgaObjectSound)
324 
325 SgaObjectSound::SgaObjectSound() :
326 	eSoundType( SOUND_STANDARD )
327 {
328     DBG_CTOR(SgaObjectSound,NULL);
329 
330 }
331 
332 // ------------------------------------------------------------------------
333 
334 SgaObjectSound::SgaObjectSound( const INetURLObject& rURL ) :
335 	eSoundType( SOUND_STANDARD )
336 {
337     DBG_CTOR(SgaObjectSound,NULL);
338 
339 	if( FileExists( rURL ) )
340 	{
341 		aURL = rURL;
342 		aThumbBmp = Bitmap( Size( 1, 1 ), 1 );
343 		bIsValid = sal_True;
344 	}
345 	else
346 		bIsValid = sal_False;
347 }
348 
349 // ------------------------------------------------------------------------
350 
351 SgaObjectSound::~SgaObjectSound()
352 {
353 
354     DBG_DTOR(SgaObjectSound,NULL);
355 }
356 
357 // ------------------------------------------------------------------------
358 
359 Bitmap SgaObjectSound::GetThumbBmp() const
360 {
361 	sal_uInt16 nId;
362 
363 	switch( eSoundType )
364 	{
365 		case( SOUND_COMPUTER ): nId = RID_SVXBMP_GALLERY_SOUND_1; break;
366 		case( SOUND_MISC ): nId = RID_SVXBMP_GALLERY_SOUND_2; break;
367 		case( SOUND_MUSIC ): nId = RID_SVXBMP_GALLERY_SOUND_3; break;
368 		case( SOUND_NATURE ): nId = RID_SVXBMP_GALLERY_SOUND_4; break;
369 		case( SOUND_SPEECH ): nId = RID_SVXBMP_GALLERY_SOUND_5; break;
370 		case( SOUND_TECHNIC ): nId = RID_SVXBMP_GALLERY_SOUND_6; break;
371 		case( SOUND_ANIMAL ): nId = RID_SVXBMP_GALLERY_SOUND_7; break;
372 
373 		// standard
374 		default:
375 			 nId = RID_SVXBMP_GALLERY_MEDIA;
376 		break;
377 	}
378 
379 	const BitmapEx  aBmpEx( GAL_RESID( nId ) );
380 	const Color     aTransColor( COL_WHITE );
381 
382 	return aBmpEx.GetBitmap( &aTransColor );
383 }
384 
385 // ------------------------------------------------------------------------
386 
387 void SgaObjectSound::WriteData( SvStream& rOut, const String& rDestDir ) const
388 {
389 	SgaObject::WriteData( rOut, rDestDir );
390 	rOut << (sal_uInt16) eSoundType << ByteString( aTitle, RTL_TEXTENCODING_UTF8 );
391 }
392 
393 // ------------------------------------------------------------------------
394 
395 void SgaObjectSound::ReadData( SvStream& rIn, sal_uInt16& rReadVersion )
396 {
397 	SgaObject::ReadData( rIn, rReadVersion );
398 
399 	if( rReadVersion >= 5 )
400 	{
401 		ByteString	aTmpStr;
402 		sal_uInt16		nTmp16;
403 
404 		rIn >> nTmp16; eSoundType = (GalSoundType) nTmp16;
405 
406 		if( rReadVersion >= 6 )
407 		{
408 			rIn >> aTmpStr; aTitle = String( aTmpStr.GetBuffer(), RTL_TEXTENCODING_UTF8 );
409 		}
410 	}
411 }
412 
413 // -----------------
414 // - SgaObjectAnim -
415 // -----------------
416 
417 SgaObjectAnim::SgaObjectAnim()
418 {
419 }
420 
421 // ------------------------------------------------------------------------
422 
423 SgaObjectAnim::SgaObjectAnim( const Graphic& rGraphic,
424 							  const INetURLObject& rURL,
425 							  const String& )
426 {
427 	aURL = rURL;
428 	bIsValid = CreateThumb( rGraphic );
429 }
430 
431 // -----------------
432 // - SgaObjectINet -
433 // -----------------
434 
435 SgaObjectINet::SgaObjectINet()
436 {
437 }
438 
439 // ------------------------------------------------------------------------
440 
441 SgaObjectINet::SgaObjectINet( const Graphic& rGraphic, const INetURLObject& rURL, const String& rFormatName ) :
442 			SgaObjectAnim	( rGraphic, rURL, rFormatName )
443 {
444 }
445 
446 // -------------------
447 // - SgaObjectSvDraw -
448 // -------------------
449 
450 SgaObjectSvDraw::SgaObjectSvDraw()
451 {
452 }
453 
454 // ------------------------------------------------------------------------
455 
456 SgaObjectSvDraw::SgaObjectSvDraw( const FmFormModel& rModel, const INetURLObject& rURL )
457 {
458 	aURL = rURL;
459 	bIsValid = CreateThumb( rModel );
460 }
461 
462 // ------------------------------------------------------------------------
463 DBG_NAME(SvxGalleryDrawModel)
464 
465 SvxGalleryDrawModel::SvxGalleryDrawModel()
466 : mpFormModel( 0 )
467 {
468     DBG_CTOR(SvxGalleryDrawModel,NULL);
469 
470     const String sFactoryURL(RTL_CONSTASCII_USTRINGPARAM("sdraw"));
471 
472     mxDoc = SfxObjectShell::CreateObjectByFactoryName( sFactoryURL );
473 
474     if( mxDoc.Is() )
475     {
476         mxDoc->DoInitNew(0);
477 
478         uno::Reference< lang::XUnoTunnel > xTunnel( mxDoc->GetModel(), uno::UNO_QUERY );
479         if( xTunnel.is() )
480         {
481             mpFormModel = dynamic_cast< FmFormModel* >(
482                 reinterpret_cast<SdrModel*>(xTunnel->getSomething(SdrModel::getUnoTunnelImplementationId())));
483             if( mpFormModel )
484             {
485                 mpFormModel->InsertPage( mpFormModel->AllocPage( false ) );
486             }
487         }
488     }
489 }
490 
491 // ------------------------------------------------------------------------
492 
493 SvxGalleryDrawModel::~SvxGalleryDrawModel()
494 {
495     if( mxDoc.Is() )
496         mxDoc->DoClose();
497 
498     DBG_DTOR(SvxGalleryDrawModel,NULL);
499 }
500 
501 // ------------------------------------------------------------------------
502 
503 SgaObjectSvDraw::SgaObjectSvDraw( SvStream& rIStm, const INetURLObject& rURL )
504 {
505     SvxGalleryDrawModel aModel;
506 
507     if( aModel.GetModel() )
508     {
509         if( GallerySvDrawImport( rIStm, *aModel.GetModel()  ) )
510         {
511             aURL = rURL;
512             bIsValid = CreateThumb( *aModel.GetModel()  );
513         }
514     }
515 }
516 
517 // ------------------------------------------------------------------------
518 
519 sal_Bool SgaObjectSvDraw::CreateThumb( const FmFormModel& rModel )
520 {
521 	Graphic		aGraphic;
522 	ImageMap	aImageMap;
523 	sal_Bool		bRet = sal_False;
524 
525 	if ( CreateIMapGraphic( rModel, aGraphic, aImageMap ) )
526 		bRet = SgaObject::CreateThumb( aGraphic );
527 	else
528 	{
529         VirtualDevice aVDev;
530 
531         aVDev.SetOutputSizePixel( Size( S_THUMB*2, S_THUMB*2 ) );
532 
533         bRet = DrawCentered( &aVDev, rModel );
534         if( bRet )
535         {
536             aThumbBmp = aVDev.GetBitmap( Point(), aVDev.GetOutputSizePixel() );
537 
538 			Size aMS( 2, 2 );
539 			BmpFilterParam aParam( aMS );
540 			aThumbBmp.Filter( BMP_FILTER_MOSAIC, &aParam );
541 			aThumbBmp.Scale( Size( S_THUMB, S_THUMB ) );
542 
543 	        aThumbBmp.Convert( BMP_CONVERSION_8BIT_COLORS );
544         }
545 	}
546 
547 	return bRet;
548 }
549 
550 // ------------------------------------------------------------------------
551 
552 sal_Bool SgaObjectSvDraw::DrawCentered( OutputDevice* pOut, const FmFormModel& rModel )
553 {
554     const FmFormPage*   pPage = static_cast< const FmFormPage* >( rModel.GetPage( 0 ) );
555     sal_Bool                bRet = sal_False;
556 
557     if( pOut && pPage )
558     {
559         const Rectangle aObjRect( pPage->GetAllObjBoundRect() );
560         const Size      aOutSizePix( pOut->GetOutputSizePixel() );
561 
562         if( aObjRect.GetWidth() && aObjRect.GetHeight() && aOutSizePix.Width() > 2 && aOutSizePix.Height() > 2 )
563         {
564             FmFormView      aView( const_cast< FmFormModel* >( &rModel ), pOut );
565             MapMode	        aMap( rModel.GetScaleUnit() );
566             Rectangle       aDrawRectPix( Point( 1, 1 ), Size( aOutSizePix.Width() - 2, aOutSizePix.Height() - 2 ) );
567             const double    fFactor  = (double) aObjRect.GetWidth() / aObjRect.GetHeight();
568             Fraction        aFrac( FRound( fFactor < 1. ? aDrawRectPix.GetWidth() * fFactor : aDrawRectPix.GetWidth() ),
569                                    pOut->LogicToPixel( aObjRect.GetSize(), aMap ).Width() );
570 
571             aMap.SetScaleX( aFrac );
572             aMap.SetScaleY( aFrac );
573 
574             const Size aDrawSize( pOut->PixelToLogic( aDrawRectPix.GetSize(), aMap ) );
575             Point aOrigin( pOut->PixelToLogic( aDrawRectPix.TopLeft(), aMap ) );
576 
577             aOrigin.X() += ( ( aDrawSize.Width() - aObjRect.GetWidth() ) >> 1 ) - aObjRect.Left();
578             aOrigin.Y() += ( ( aDrawSize.Height() - aObjRect.GetHeight() ) >> 1 ) - aObjRect.Top();
579             aMap.SetOrigin( aOrigin );
580 
581             aView.SetPageVisible( sal_False );
582             aView.SetBordVisible( sal_False );
583             aView.SetGridVisible( sal_False );
584             aView.SetHlplVisible( sal_False );
585             aView.SetGlueVisible( sal_False );
586 
587             pOut->Push();
588             pOut->SetMapMode( aMap );
589             aView.ShowSdrPage( const_cast< FmFormPage* >( pPage ));
590             aView.CompleteRedraw( pOut, Rectangle( pOut->PixelToLogic( Point() ), pOut->GetOutputSize() ) );
591             pOut->Pop();
592 
593             bRet = sal_True;
594         }
595     }
596 
597     return bRet;
598 }
599 
600 // ------------------------------------------------------------------------
601 
602 void SgaObjectSvDraw::WriteData( SvStream& rOut, const String& rDestDir ) const
603 {
604 	SgaObject::WriteData( rOut, rDestDir );
605 	rOut << ByteString( aTitle, RTL_TEXTENCODING_UTF8 );
606 }
607 
608 // ------------------------------------------------------------------------
609 
610 void SgaObjectSvDraw::ReadData( SvStream& rIn, sal_uInt16& rReadVersion )
611 {
612 	SgaObject::ReadData( rIn, rReadVersion );
613 
614 	if( rReadVersion >= 5 )
615 	{
616 		ByteString aTmpStr;
617 		rIn >> aTmpStr; aTitle = String( aTmpStr.GetBuffer(), RTL_TEXTENCODING_UTF8 );
618 	}
619 }
620