1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <com/sun/star/lang/XUnoTunnel.hpp>
22 #include <sfx2/objsh.hxx>
23 #include <sfx2/docfac.hxx>
24 #include <comphelper/classids.hxx>
25 #include <comphelper/string.hxx>
26 #include <unotools/pathoptions.hxx>
27 #include <tools/rcid.h>
28 #include <tools/vcompat.hxx>
29 #include <tools/helpers.hxx>
30 #include <vcl/virdev.hxx>
31 #include <svl/itempool.hxx>
32 #include <svx/fmmodel.hxx>
33 #include <svx/fmview.hxx>
34 #include <svx/fmpage.hxx>
35 #include "gallery.hrc"
36 #include "svx/galmisc.hxx"
38 #include <vcl/svapp.hxx>
39 #include <vcl/settings.hxx>
40 #include <vcl/dibtools.hxx>
41 #include "gallerydrawmodel.hxx"
42 #include <boost/scoped_ptr.hpp>
44 using namespace ::com::sun::star
;
46 SgaObject::SgaObject()
52 BitmapEx
SgaObject::createPreviewBitmapEx(const Size
& rSizePixel
) const
56 if(rSizePixel
.Width() && rSizePixel
.Height())
58 if(SGA_OBJ_SOUND
== GetObjKind())
60 aRetval
= GAL_RES(RID_SVXBMP_GALLERY_MEDIA
);
62 else if(IsThumbBitmap())
64 aRetval
= GetThumbBmp();
68 const Graphic
aGraphic(GetThumbMtf());
70 aRetval
= aGraphic
.GetBitmapEx();
73 if(!aRetval
.IsEmpty())
75 const Size
aCurrentSizePixel(aRetval
.GetSizePixel());
76 const double fScaleX((double)rSizePixel
.Width() / (double)aCurrentSizePixel
.Width());
77 const double fScaleY((double)rSizePixel
.Height() / (double)aCurrentSizePixel
.Height());
78 const double fScale(std::min(fScaleX
, fScaleY
));
80 // only scale when need to decrease, no need to make bigger as original. Also
81 // prevent scaling close to 1.0 which is not needed for pixel graphics
82 if(fScale
< 1.0 && fabs(1.0 - fScale
) > 0.005)
84 aRetval
.Scale(fScale
, fScale
, BmpScaleFlag::BestQuality
);
92 bool SgaObject::CreateThumb( const Graphic
& rGraphic
)
96 if( rGraphic
.GetType() == GRAPHIC_BITMAP
)
98 BitmapEx
aBmpEx( rGraphic
.GetBitmapEx() );
99 Size
aBmpSize( aBmpEx
.GetSizePixel() );
101 if( aBmpSize
.Width() && aBmpSize
.Height() )
103 if( aBmpEx
.GetPrefMapMode().GetMapUnit() != MAP_PIXEL
&&
104 aBmpEx
.GetPrefSize().Width() > 0 &&
105 aBmpEx
.GetPrefSize().Height() > 0 )
107 Size
aLogSize( OutputDevice::LogicToLogic( aBmpEx
.GetPrefSize(), aBmpEx
.GetPrefMapMode(), MAP_100TH_MM
) );
109 if( aLogSize
.Width() > 0 && aLogSize
.Height() > 0 )
111 double fFactorLog
= static_cast< double >( aLogSize
.Width() ) / aLogSize
.Height();
112 double fFactorPix
= static_cast< double >( aBmpSize
.Width() ) / aBmpSize
.Height();
114 if( fFactorPix
> fFactorLog
)
115 aBmpSize
.Width() = FRound( aBmpSize
.Height() * fFactorLog
);
117 aBmpSize
.Height() = FRound( aBmpSize
.Width() / fFactorLog
);
119 aBmpEx
.SetSizePixel( aBmpSize
, BmpScaleFlag::BestQuality
);
123 // take over BitmapEx
126 if( ( aBmpSize
.Width() <= S_THUMB
) && ( aBmpSize
.Height() <= S_THUMB
) )
128 aThumbBmp
.Convert( BMP_CONVERSION_8BIT_COLORS
);
133 const float fFactor
= (float) aBmpSize
.Width() / aBmpSize
.Height();
134 const Size
aNewSize( std::max( (long) (fFactor
< 1. ? S_THUMB
* fFactor
: S_THUMB
), 8L ),
135 std::max( (long) (fFactor
< 1. ? S_THUMB
: S_THUMB
/ fFactor
), 8L ) );
137 (double) aNewSize
.Width() / aBmpSize
.Width(),
138 (double) aNewSize
.Height() / aBmpSize
.Height(),
139 BmpScaleFlag::BestQuality
) )
141 aThumbBmp
.Convert( BMP_CONVERSION_8BIT_COLORS
);
147 else if( rGraphic
.GetType() == GRAPHIC_GDIMETAFILE
)
149 const Size
aPrefSize( rGraphic
.GetPrefSize() );
150 const double fFactor
= (double)aPrefSize
.Width() / (double)aPrefSize
.Height();
151 Size
aSize( S_THUMB
, S_THUMB
);
153 aSize
.Width() = (sal_Int32
)( S_THUMB
* fFactor
);
155 aSize
.Height() = (sal_Int32
)( S_THUMB
/ fFactor
);
157 const GraphicConversionParameters
aParameters(aSize
, false, true, true /*TODO: extra ", true" post-#i121194#*/);
158 aThumbBmp
= rGraphic
.GetBitmapEx(aParameters
);
160 if( !aThumbBmp
.IsEmpty() )
162 aThumbBmp
.Convert( BMP_CONVERSION_8BIT_COLORS
);
170 void SgaObject::WriteData( SvStream
& rOut
, const OUString
& rDestDir
) const
172 static const sal_uInt32 nInventor
= COMPAT_FORMAT( 'S', 'G', 'A', '3' );
174 rOut
.WriteUInt32( nInventor
).WriteUInt16( 0x0004 ).WriteUInt16( GetVersion() ).WriteUInt16( GetObjKind() );
175 rOut
.WriteBool( bIsThumbBmp
);
179 const SvStreamCompressFlags nOldCompressMode
= rOut
.GetCompressMode();
180 const sal_uIntPtr nOldVersion
= rOut
.GetVersion();
182 rOut
.SetCompressMode( SvStreamCompressFlags::ZBITMAP
);
183 rOut
.SetVersion( SOFFICE_FILEFORMAT_50
);
185 WriteDIBBitmapEx(aThumbBmp
, rOut
);
187 rOut
.SetVersion( nOldVersion
);
188 rOut
.SetCompressMode( nOldCompressMode
);
191 WriteGDIMetaFile( rOut
, aThumbMtf
);
193 OUString aURLWithoutDestDir
= aURL
.GetMainURL( INetURLObject::NO_DECODE
);
194 aURLWithoutDestDir
= aURLWithoutDestDir
.replaceFirst(rDestDir
, "");
195 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut
, aURLWithoutDestDir
, RTL_TEXTENCODING_UTF8
);
198 void SgaObject::ReadData(SvStream
& rIn
, sal_uInt16
& rReadVersion
)
203 rIn
.ReadUInt32( nTmp32
).ReadUInt16( nTmp16
).ReadUInt16( rReadVersion
).ReadUInt16( nTmp16
).ReadCharAsBool( bIsThumbBmp
);
207 ReadDIBBitmapEx(aThumbBmp
, rIn
);
211 ReadGDIMetaFile( rIn
, aThumbMtf
);
214 OUString aTmpStr
= read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn
, RTL_TEXTENCODING_UTF8
);
215 aURL
= INetURLObject(aTmpStr
);
218 const OUString
SgaObject::GetTitle() const
220 OUString
aReturnValue( aTitle
);
221 if ( !getenv( "GALLERY_SHOW_PRIVATE_TITLE" ) )
223 if ( comphelper::string::getTokenCount(aReturnValue
, ':') == 3 )
225 OUString
aPrivateInd ( aReturnValue
.getToken( 0, ':' ) );
226 OUString
aResourceName( aReturnValue
.getToken( 1, ':' ) );
227 sal_Int32
nResId ( aReturnValue
.getToken( 2, ':' ).toInt32() );
228 if ( aPrivateInd
== "private" &&
229 !aResourceName
.isEmpty() && ( nResId
> 0 ) && ( nResId
< 0x10000 ) )
231 OString
aMgrName(OUStringToOString(aResourceName
, RTL_TEXTENCODING_UTF8
));
232 boost::scoped_ptr
<ResMgr
> pResMgr(ResMgr::CreateResMgr( aMgrName
.getStr(),
233 Application::GetSettings().GetUILanguageTag() ));
236 ResId
aResId( (sal_uInt16
)nResId
, *pResMgr
);
237 aResId
.SetRT( RSC_STRING
);
238 if ( pResMgr
->IsAvailable( aResId
) )
240 aReturnValue
= aResId
.toString();
249 void SgaObject::SetTitle( const OUString
& rTitle
)
254 SvStream
& WriteSgaObject( SvStream
& rOut
, const SgaObject
& rObj
)
256 rObj
.WriteData( rOut
, "" );
260 SvStream
& ReadSgaObject( SvStream
& rIn
, SgaObject
& rObj
)
262 sal_uInt16 nReadVersion
;
264 rObj
.ReadData( rIn
, nReadVersion
);
265 rObj
.bIsValid
= ( rIn
.GetError() == ERRCODE_NONE
);
270 SgaObjectBmp::SgaObjectBmp()
274 SgaObjectBmp::SgaObjectBmp( const INetURLObject
& rURL
)
279 if ( GalleryGraphicImportRet::IMPORT_NONE
!= GalleryGraphicImport( rURL
, aGraphic
, aFilter
) )
280 Init( aGraphic
, rURL
);
283 SgaObjectBmp::SgaObjectBmp( const Graphic
& rGraphic
, const INetURLObject
& rURL
, const OUString
& )
285 if( FileExists( rURL
) )
286 Init( rGraphic
, rURL
);
289 void SgaObjectBmp::Init( const Graphic
& rGraphic
, const INetURLObject
& rURL
)
292 bIsValid
= CreateThumb( rGraphic
);
295 void SgaObjectBmp::WriteData( SvStream
& rOut
, const OUString
& rDestDir
) const
298 SgaObject::WriteData( rOut
, rDestDir
);
300 rOut
.Write( aDummy
, 10 );
301 write_uInt16_lenPrefixed_uInt8s_FromOString(rOut
, OString()); //dummy
302 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut
, aTitle
, RTL_TEXTENCODING_UTF8
);
305 void SgaObjectBmp::ReadData( SvStream
& rIn
, sal_uInt16
& rReadVersion
)
308 SgaObject::ReadData( rIn
, rReadVersion
);
309 rIn
.SeekRel( 10 ); // 16, 16, 32, 16
310 read_uInt16_lenPrefixed_uInt8s_ToOString(rIn
); //dummy
312 if( rReadVersion
>= 5 )
313 aTitle
= read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn
, RTL_TEXTENCODING_UTF8
);
317 SgaObjectSound::SgaObjectSound() :
318 eSoundType( SOUND_STANDARD
)
322 SgaObjectSound::SgaObjectSound( const INetURLObject
& rURL
) :
323 eSoundType( SOUND_STANDARD
)
326 if( FileExists( rURL
) )
329 aThumbBmp
= Bitmap( Size( 1, 1 ), 1 );
336 SgaObjectSound::~SgaObjectSound()
340 BitmapEx
SgaObjectSound::GetThumbBmp() const
346 case( SOUND_COMPUTER
): nId
= RID_SVXBMP_GALLERY_SOUND_1
; break;
347 case( SOUND_MISC
): nId
= RID_SVXBMP_GALLERY_SOUND_2
; break;
348 case( SOUND_MUSIC
): nId
= RID_SVXBMP_GALLERY_SOUND_3
; break;
349 case( SOUND_NATURE
): nId
= RID_SVXBMP_GALLERY_SOUND_4
; break;
350 case( SOUND_SPEECH
): nId
= RID_SVXBMP_GALLERY_SOUND_5
; break;
351 case( SOUND_TECHNIC
): nId
= RID_SVXBMP_GALLERY_SOUND_6
; break;
352 case( SOUND_ANIMAL
): nId
= RID_SVXBMP_GALLERY_SOUND_7
; break;
356 nId
= RID_SVXBMP_GALLERY_MEDIA
;
360 const BitmapEx
aBmpEx( GAL_RES( nId
) );
365 void SgaObjectSound::WriteData( SvStream
& rOut
, const OUString
& rDestDir
) const
367 SgaObject::WriteData( rOut
, rDestDir
);
368 rOut
.WriteUInt16( eSoundType
);
369 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut
, aTitle
, RTL_TEXTENCODING_UTF8
);
372 void SgaObjectSound::ReadData( SvStream
& rIn
, sal_uInt16
& rReadVersion
)
374 SgaObject::ReadData( rIn
, rReadVersion
);
376 if( rReadVersion
>= 5 )
380 rIn
.ReadUInt16( nTmp16
); eSoundType
= (GalSoundType
) nTmp16
;
382 if( rReadVersion
>= 6 )
383 aTitle
= read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn
, RTL_TEXTENCODING_UTF8
);
387 SgaObjectAnim::SgaObjectAnim()
391 SgaObjectAnim::SgaObjectAnim( const Graphic
& rGraphic
,
392 const INetURLObject
& rURL
,
396 bIsValid
= CreateThumb( rGraphic
);
399 SgaObjectINet::SgaObjectINet()
403 SgaObjectINet::SgaObjectINet( const Graphic
& rGraphic
, const INetURLObject
& rURL
, const OUString
& rFormatName
) :
404 SgaObjectAnim ( rGraphic
, rURL
, rFormatName
)
408 SgaObjectSvDraw::SgaObjectSvDraw()
412 SgaObjectSvDraw::SgaObjectSvDraw( const FmFormModel
& rModel
, const INetURLObject
& rURL
)
415 bIsValid
= CreateThumb( rModel
);
419 SvxGalleryDrawModel::SvxGalleryDrawModel()
423 const OUString
sFactoryURL("sdraw");
425 mxDoc
= SfxObjectShell::CreateObjectByFactoryName( sFactoryURL
);
431 uno::Reference
< lang::XUnoTunnel
> xTunnel( mxDoc
->GetModel(), uno::UNO_QUERY
);
434 mpFormModel
= dynamic_cast< FmFormModel
* >(
435 reinterpret_cast<SdrModel
*>(xTunnel
->getSomething(SdrModel::getUnoTunnelImplementationId())));
438 mpFormModel
->InsertPage( mpFormModel
->AllocPage( false ) );
444 SvxGalleryDrawModel::~SvxGalleryDrawModel()
451 SgaObjectSvDraw::SgaObjectSvDraw( SvStream
& rIStm
, const INetURLObject
& rURL
)
453 SvxGalleryDrawModel aModel
;
455 if( aModel
.GetModel() )
457 if( GallerySvDrawImport( rIStm
, *aModel
.GetModel() ) )
460 bIsValid
= CreateThumb( *aModel
.GetModel() );
465 bool SgaObjectSvDraw::CreateThumb( const FmFormModel
& rModel
)
471 if ( CreateIMapGraphic( rModel
, aGraphic
, aImageMap
) )
473 bRet
= SgaObject::CreateThumb( aGraphic
);
477 const FmFormPage
* pPage
= static_cast< const FmFormPage
* >(rModel
.GetPage(0));
481 const Rectangle
aObjRect(pPage
->GetAllObjBoundRect());
483 if(aObjRect
.GetWidth() && aObjRect
.GetHeight())
485 ScopedVclPtrInstance
< VirtualDevice
> pVDev
;
486 FmFormView
aView(const_cast< FmFormModel
* >(&rModel
), pVDev
);
488 aView
.ShowSdrPage(const_cast< FmFormPage
* >(pPage
));
490 aThumbBmp
= aView
.GetMarkedObjBitmapEx();
492 const Size
aDiscreteSize(aThumbBmp
.GetSizePixel());
494 if(aDiscreteSize
.Width() && aDiscreteSize
.Height())
496 sal_uInt32
nTargetSizeX(S_THUMB
);
497 sal_uInt32
nTargetSizeY(S_THUMB
);
499 if(aDiscreteSize
.Width() > aDiscreteSize
.Height())
501 nTargetSizeY
= (aDiscreteSize
.Height() * nTargetSizeX
) / aDiscreteSize
.Width();
505 nTargetSizeX
= (aDiscreteSize
.Width() * nTargetSizeY
) / aDiscreteSize
.Height();
510 aThumbBmp
.Scale(Size(nTargetSizeX
, nTargetSizeY
), BmpScaleFlag::BestQuality
);
511 aThumbBmp
.Convert(BMP_CONVERSION_8BIT_COLORS
);
522 void SgaObjectSvDraw::WriteData( SvStream
& rOut
, const OUString
& rDestDir
) const
524 SgaObject::WriteData( rOut
, rDestDir
);
525 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut
, aTitle
, RTL_TEXTENCODING_UTF8
);
528 void SgaObjectSvDraw::ReadData( SvStream
& rIn
, sal_uInt16
& rReadVersion
)
530 SgaObject::ReadData( rIn
, rReadVersion
);
532 if( rReadVersion
>= 5 )
533 aTitle
= read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn
, RTL_TEXTENCODING_UTF8
);
536 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */