xref: /trunk/main/svx/source/gallery2/galobj.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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