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