Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / svx / source / gallery2 / galobj.cxx
blob2f23545905ce8f606f1ca4dda0f7895fd84d1bc3
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/resmgr.hxx>
29 #include <tools/vcompat.hxx>
30 #include <tools/helpers.hxx>
31 #include <vcl/virdev.hxx>
32 #include <svl/itempool.hxx>
33 #include <svx/fmmodel.hxx>
34 #include <svx/fmview.hxx>
35 #include <svx/fmpage.hxx>
36 #include "gallery.hrc"
37 #include "svx/galmisc.hxx"
38 #include "galobj.hxx"
39 #include <vcl/svapp.hxx>
40 #include <vcl/settings.hxx>
41 #include <vcl/dibtools.hxx>
42 #include "gallerydrawmodel.hxx"
43 #include <memory>
44 #include "bitmaps.hlst"
46 using namespace ::com::sun::star;
48 SgaObject::SgaObject()
49 : bIsValid ( false ),
50 bIsThumbBmp ( true )
54 BitmapEx SgaObject::createPreviewBitmapEx(const Size& rSizePixel) const
56 BitmapEx aRetval;
58 if(rSizePixel.Width() && rSizePixel.Height())
60 if(SgaObjKind::Sound == GetObjKind())
62 aRetval = BitmapEx(RID_SVXBMP_GALLERY_MEDIA);
64 else if(IsThumbBitmap())
66 aRetval = GetThumbBmp();
68 else
70 const Graphic aGraphic(GetThumbMtf());
72 aRetval = aGraphic.GetBitmapEx();
75 if(!aRetval.IsEmpty())
77 const Size aCurrentSizePixel(aRetval.GetSizePixel());
78 const double fScaleX((double)rSizePixel.Width() / (double)aCurrentSizePixel.Width());
79 const double fScaleY((double)rSizePixel.Height() / (double)aCurrentSizePixel.Height());
80 const double fScale(std::min(fScaleX, fScaleY));
82 // only scale when need to decrease, no need to make bigger as original. Also
83 // prevent scaling close to 1.0 which is not needed for pixel graphics
84 if(fScale < 1.0 && fabs(1.0 - fScale) > 0.005)
86 aRetval.Scale(fScale, fScale, BmpScaleFlag::BestQuality);
91 return aRetval;
94 bool SgaObject::CreateThumb( const Graphic& rGraphic )
96 bool bRet = false;
98 if( rGraphic.GetType() == GraphicType::Bitmap )
100 BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
101 Size aBmpSize( aBmpEx.GetSizePixel() );
103 if( aBmpSize.Width() && aBmpSize.Height() )
105 if( aBmpEx.GetPrefMapMode().GetMapUnit() != MapUnit::MapPixel &&
106 aBmpEx.GetPrefSize().Width() > 0 &&
107 aBmpEx.GetPrefSize().Height() > 0 )
109 Size aLogSize( OutputDevice::LogicToLogic( aBmpEx.GetPrefSize(), aBmpEx.GetPrefMapMode(), MapUnit::Map100thMM ) );
111 if( aLogSize.Width() > 0 && aLogSize.Height() > 0 )
113 double fFactorLog = static_cast< double >( aLogSize.Width() ) / aLogSize.Height();
114 double fFactorPix = static_cast< double >( aBmpSize.Width() ) / aBmpSize.Height();
116 if( fFactorPix > fFactorLog )
117 aBmpSize.Width() = FRound( aBmpSize.Height() * fFactorLog );
118 else
119 aBmpSize.Height() = FRound( aBmpSize.Width() / fFactorLog );
121 aBmpEx.SetSizePixel( aBmpSize, BmpScaleFlag::BestQuality );
125 // take over BitmapEx
126 aThumbBmp = aBmpEx;
128 if( ( aBmpSize.Width() <= S_THUMB ) && ( aBmpSize.Height() <= S_THUMB ) )
130 aThumbBmp.Convert( BmpConversion::N8BitColors );
131 bRet = true;
133 else
135 const float fFactor = (float) aBmpSize.Width() / aBmpSize.Height();
136 const Size aNewSize( std::max( (long) (fFactor < 1. ? S_THUMB * fFactor : S_THUMB), 8L ),
137 std::max( (long) (fFactor < 1. ? S_THUMB : S_THUMB / fFactor), 8L ) );
138 if(aThumbBmp.Scale(
139 (double) aNewSize.Width() / aBmpSize.Width(),
140 (double) aNewSize.Height() / aBmpSize.Height(),
141 BmpScaleFlag::BestQuality ) )
143 aThumbBmp.Convert( BmpConversion::N8BitColors );
144 bRet = true;
149 else if( rGraphic.GetType() == GraphicType::GdiMetafile )
151 const Size aPrefSize( rGraphic.GetPrefSize() );
152 const double fFactor = (double)aPrefSize.Width() / (double)aPrefSize.Height();
153 Size aSize( S_THUMB, S_THUMB );
154 if ( fFactor < 1.0 )
155 aSize.Width() = (sal_Int32)( S_THUMB * fFactor );
156 else
157 aSize.Height() = (sal_Int32)( S_THUMB / fFactor );
159 const GraphicConversionParameters aParameters(aSize, false, true, true /*TODO: extra ", true" post-#i121194#*/);
160 aThumbBmp = rGraphic.GetBitmapEx(aParameters);
162 if( !aThumbBmp.IsEmpty() )
164 aThumbBmp.Convert( BmpConversion::N8BitColors );
165 bRet = true;
169 return bRet;
172 void SgaObject::WriteData( SvStream& rOut, const OUString& rDestDir ) const
174 static const sal_uInt32 nInventor = COMPAT_FORMAT( 'S', 'G', 'A', '3' );
176 rOut.WriteUInt32( nInventor ).WriteUInt16( 0x0004 ).WriteUInt16( GetVersion() ).WriteUInt16( (sal_uInt16)GetObjKind() );
177 rOut.WriteBool( bIsThumbBmp );
179 if( bIsThumbBmp )
181 const SvStreamCompressFlags nOldCompressMode = rOut.GetCompressMode();
182 const sal_uIntPtr nOldVersion = rOut.GetVersion();
184 rOut.SetCompressMode( SvStreamCompressFlags::ZBITMAP );
185 rOut.SetVersion( SOFFICE_FILEFORMAT_50 );
187 WriteDIBBitmapEx(aThumbBmp, rOut);
189 rOut.SetVersion( nOldVersion );
190 rOut.SetCompressMode( nOldCompressMode );
192 else
193 WriteGDIMetaFile( rOut, aThumbMtf );
195 OUString aURLWithoutDestDir = aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
196 aURLWithoutDestDir = aURLWithoutDestDir.replaceFirst(rDestDir, "");
197 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut, aURLWithoutDestDir, RTL_TEXTENCODING_UTF8);
200 void SgaObject::ReadData(SvStream& rIn, sal_uInt16& rReadVersion )
202 sal_uInt32 nTmp32;
203 sal_uInt16 nTmp16;
205 rIn.ReadUInt32( nTmp32 ).ReadUInt16( nTmp16 ).ReadUInt16( rReadVersion ).ReadUInt16( nTmp16 ).ReadCharAsBool( bIsThumbBmp );
207 if( bIsThumbBmp )
209 ReadDIBBitmapEx(aThumbBmp, rIn);
211 else
213 ReadGDIMetaFile( rIn, aThumbMtf );
216 OUString aTmpStr = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn, RTL_TEXTENCODING_UTF8);
217 aURL = INetURLObject(aTmpStr);
220 const OUString SgaObject::GetTitle() const
222 OUString aReturnValue( aTitle );
223 if ( !getenv( "GALLERY_SHOW_PRIVATE_TITLE" ) )
225 if ( comphelper::string::getTokenCount(aReturnValue, ':') == 3 )
227 OUString aPrivateInd ( aReturnValue.getToken( 0, ':' ) );
228 OUString aResourceName( aReturnValue.getToken( 1, ':' ) );
229 sal_Int32 nResId ( aReturnValue.getToken( 2, ':' ).toInt32() );
230 if ( aPrivateInd == "private" &&
231 !aResourceName.isEmpty() && ( nResId > 0 ) && ( nResId < 0x10000 ) )
233 OString aMgrName(OUStringToOString(aResourceName, RTL_TEXTENCODING_UTF8));
234 std::unique_ptr<ResMgr> pResMgr(ResMgr::CreateResMgr( aMgrName.getStr(),
235 Application::GetSettings().GetUILanguageTag() ));
236 if ( pResMgr )
238 ResId aResId( (sal_uInt16)nResId, *pResMgr );
239 aResId.SetRT( RSC_STRING );
240 if ( pResMgr->IsAvailable( aResId ) )
242 aReturnValue = aResId;
248 return aReturnValue;
251 void SgaObject::SetTitle( const OUString& rTitle )
253 aTitle = rTitle;
256 SvStream& WriteSgaObject( SvStream& rOut, const SgaObject& rObj )
258 rObj.WriteData( rOut, "" );
259 return rOut;
262 SvStream& ReadSgaObject( SvStream& rIn, SgaObject& rObj )
264 sal_uInt16 nReadVersion;
266 rObj.ReadData( rIn, nReadVersion );
267 rObj.bIsValid = ( rIn.GetError() == ERRCODE_NONE );
269 return rIn;
272 SgaObjectBmp::SgaObjectBmp()
276 SgaObjectBmp::SgaObjectBmp( const INetURLObject& rURL )
278 Graphic aGraphic;
279 OUString aFilter;
281 if ( GalleryGraphicImportRet::IMPORT_NONE != GalleryGraphicImport( rURL, aGraphic, aFilter ) )
282 Init( aGraphic, rURL );
285 SgaObjectBmp::SgaObjectBmp( const Graphic& rGraphic, const INetURLObject& rURL )
287 if( FileExists( rURL ) )
288 Init( rGraphic, rURL );
291 void SgaObjectBmp::Init( const Graphic& rGraphic, const INetURLObject& rURL )
293 aURL = rURL;
294 bIsValid = CreateThumb( rGraphic );
297 void SgaObjectBmp::WriteData( SvStream& rOut, const OUString& rDestDir ) const
299 // Set version
300 SgaObject::WriteData( rOut, rDestDir );
301 char aDummy[ 10 ] = { 0 };
302 rOut.WriteBytes(aDummy, 10);
303 write_uInt16_lenPrefixed_uInt8s_FromOString(rOut, OString()); //dummy
304 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut, aTitle, RTL_TEXTENCODING_UTF8);
307 void SgaObjectBmp::ReadData( SvStream& rIn, sal_uInt16& rReadVersion )
310 SgaObject::ReadData( rIn, rReadVersion );
311 rIn.SeekRel( 10 ); // 16, 16, 32, 16
312 read_uInt16_lenPrefixed_uInt8s_ToOString(rIn); //dummy
314 if( rReadVersion >= 5 )
315 aTitle = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn, RTL_TEXTENCODING_UTF8);
319 SgaObjectSound::SgaObjectSound() :
320 eSoundType( SOUND_STANDARD )
324 SgaObjectSound::SgaObjectSound( const INetURLObject& rURL ) :
325 eSoundType( SOUND_STANDARD )
328 if( FileExists( rURL ) )
330 aURL = rURL;
331 aThumbBmp = Bitmap( Size( 1, 1 ), 1 );
332 bIsValid = true;
334 else
335 bIsValid = false;
338 SgaObjectSound::~SgaObjectSound()
342 BitmapEx SgaObjectSound::GetThumbBmp() const
344 OUString sId;
346 switch( eSoundType )
348 case SOUND_COMPUTER: sId = RID_SVXBMP_GALLERY_SOUND_1; break;
349 case SOUND_MISC: sId = RID_SVXBMP_GALLERY_SOUND_2; break;
350 case SOUND_MUSIC: sId = RID_SVXBMP_GALLERY_SOUND_3; break;
351 case SOUND_NATURE: sId = RID_SVXBMP_GALLERY_SOUND_4; break;
352 case SOUND_SPEECH: sId = RID_SVXBMP_GALLERY_SOUND_5; break;
353 case SOUND_TECHNIC: sId = RID_SVXBMP_GALLERY_SOUND_6; break;
354 case SOUND_ANIMAL: sId = RID_SVXBMP_GALLERY_SOUND_7; break;
356 // standard
357 default:
358 sId = RID_SVXBMP_GALLERY_MEDIA;
359 break;
362 const BitmapEx aBmpEx(sId);
364 return aBmpEx;
367 void SgaObjectSound::WriteData( SvStream& rOut, const OUString& rDestDir ) const
369 SgaObject::WriteData( rOut, rDestDir );
370 rOut.WriteUInt16( eSoundType );
371 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut, aTitle, RTL_TEXTENCODING_UTF8);
374 void SgaObjectSound::ReadData( SvStream& rIn, sal_uInt16& rReadVersion )
376 SgaObject::ReadData( rIn, rReadVersion );
378 if( rReadVersion >= 5 )
380 sal_uInt16 nTmp16;
382 rIn.ReadUInt16( nTmp16 ); eSoundType = (GalSoundType) nTmp16;
384 if( rReadVersion >= 6 )
385 aTitle = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn, RTL_TEXTENCODING_UTF8);
389 SgaObjectAnim::SgaObjectAnim()
393 SgaObjectAnim::SgaObjectAnim( const Graphic& rGraphic,
394 const INetURLObject& rURL )
396 aURL = rURL;
397 bIsValid = CreateThumb( rGraphic );
400 SgaObjectINet::SgaObjectINet()
404 SgaObjectINet::SgaObjectINet( const Graphic& rGraphic, const INetURLObject& rURL ) :
405 SgaObjectAnim ( rGraphic, rURL )
409 SgaObjectSvDraw::SgaObjectSvDraw()
413 SgaObjectSvDraw::SgaObjectSvDraw( const FmFormModel& rModel, const INetURLObject& rURL )
415 aURL = rURL;
416 bIsValid = CreateThumb( rModel );
420 SvxGalleryDrawModel::SvxGalleryDrawModel()
421 : mpFormModel( nullptr )
424 const OUString sFactoryURL("sdraw");
426 mxDoc = SfxObjectShell::CreateObjectByFactoryName( sFactoryURL );
428 if( mxDoc.Is() )
430 mxDoc->DoInitNew();
432 uno::Reference< lang::XUnoTunnel > xTunnel( mxDoc->GetModel(), uno::UNO_QUERY );
433 if( xTunnel.is() )
435 mpFormModel = dynamic_cast< FmFormModel* >(
436 reinterpret_cast<SdrModel*>(xTunnel->getSomething(SdrModel::getUnoTunnelImplementationId())));
437 if( mpFormModel )
439 mpFormModel->InsertPage( mpFormModel->AllocPage( false ) );
445 SvxGalleryDrawModel::~SvxGalleryDrawModel()
447 if( mxDoc.Is() )
448 mxDoc->DoClose();
452 SgaObjectSvDraw::SgaObjectSvDraw( SvStream& rIStm, const INetURLObject& rURL )
454 SvxGalleryDrawModel aModel;
456 if( aModel.GetModel() )
458 if( GallerySvDrawImport( rIStm, *aModel.GetModel() ) )
460 aURL = rURL;
461 bIsValid = CreateThumb( *aModel.GetModel() );
466 bool SgaObjectSvDraw::CreateThumb( const FmFormModel& rModel )
468 Graphic aGraphic;
469 ImageMap aImageMap;
470 bool bRet = false;
472 if ( CreateIMapGraphic( rModel, aGraphic, aImageMap ) )
474 bRet = SgaObject::CreateThumb( aGraphic );
476 else
478 const FmFormPage* pPage = static_cast< const FmFormPage* >(rModel.GetPage(0));
480 if(pPage)
482 const tools::Rectangle aObjRect(pPage->GetAllObjBoundRect());
484 if(aObjRect.GetWidth() && aObjRect.GetHeight())
486 ScopedVclPtrInstance< VirtualDevice > pVDev;
487 FmFormView aView(const_cast< FmFormModel* >(&rModel), pVDev);
489 aView.ShowSdrPage(const_cast< FmFormPage* >(pPage));
490 aView.MarkAllObj();
491 aThumbBmp = aView.GetMarkedObjBitmapEx();
493 const Size aDiscreteSize(aThumbBmp.GetSizePixel());
495 if(aDiscreteSize.Width() && aDiscreteSize.Height())
497 sal_uInt32 nTargetSizeX(S_THUMB);
498 sal_uInt32 nTargetSizeY(S_THUMB);
500 if(aDiscreteSize.Width() > aDiscreteSize.Height())
502 nTargetSizeY = (aDiscreteSize.Height() * nTargetSizeX) / aDiscreteSize.Width();
504 else
506 nTargetSizeX = (aDiscreteSize.Width() * nTargetSizeY) / aDiscreteSize.Height();
509 if(!!aThumbBmp)
511 aThumbBmp.Scale(Size(nTargetSizeX, nTargetSizeY), BmpScaleFlag::BestQuality);
512 aThumbBmp.Convert(BmpConversion::N8BitColors);
513 bRet = true;
520 return bRet;
523 void SgaObjectSvDraw::WriteData( SvStream& rOut, const OUString& rDestDir ) const
525 SgaObject::WriteData( rOut, rDestDir );
526 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut, aTitle, RTL_TEXTENCODING_UTF8);
529 void SgaObjectSvDraw::ReadData( SvStream& rIn, sal_uInt16& rReadVersion )
531 SgaObject::ReadData( rIn, rReadVersion );
533 if( rReadVersion >= 5 )
534 aTitle = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn, RTL_TEXTENCODING_UTF8);
537 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */