Bump version to 6.4-15
[LibreOffice.git] / svx / source / gallery2 / galobj.cxx
blob23b1e3cda851f20922f4d2d295e70cf270070ff0
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/fileformat.h>
25 #include <comphelper/classids.hxx>
26 #include <unotools/pathoptions.hxx>
27 #include <unotools/resmgr.hxx>
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 <svx/galmisc.hxx>
36 #include <galobj.hxx>
37 #include <vcl/svapp.hxx>
38 #include <vcl/settings.hxx>
39 #include <vcl/dibtools.hxx>
40 #include "gallerydrawmodel.hxx"
41 #include <memory>
42 #include <bitmaps.hlst>
44 using namespace ::com::sun::star;
46 SgaObject::SgaObject()
47 : bIsValid ( false ),
48 bIsThumbBmp ( true )
52 BitmapEx SgaObject::createPreviewBitmapEx(const Size& rSizePixel) const
54 BitmapEx aRetval;
56 if(rSizePixel.Width() && rSizePixel.Height())
58 if(SgaObjKind::Sound == GetObjKind())
60 aRetval = BitmapEx(RID_SVXBMP_GALLERY_MEDIA);
62 else if(IsThumbBitmap())
64 aRetval = GetThumbBmp();
66 else
68 const Graphic aGraphic(GetThumbMtf());
70 aRetval = aGraphic.GetBitmapEx();
73 if(!aRetval.IsEmpty())
75 const Size aCurrentSizePixel(aRetval.GetSizePixel());
76 const double fScaleX(static_cast<double>(rSizePixel.Width()) / static_cast<double>(aCurrentSizePixel.Width()));
77 const double fScaleY(static_cast<double>(rSizePixel.Height()) / static_cast<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);
89 return aRetval;
92 bool SgaObject::CreateThumb( const Graphic& rGraphic )
94 bool bRet = false;
96 if( rGraphic.GetType() == GraphicType::Bitmap )
98 BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
99 Size aBmpSize( aBmpEx.GetSizePixel() );
101 if( aBmpSize.Width() && aBmpSize.Height() )
103 if( aBmpEx.GetPrefMapMode().GetMapUnit() != MapUnit::MapPixel &&
104 aBmpEx.GetPrefSize().Width() > 0 &&
105 aBmpEx.GetPrefSize().Height() > 0 )
107 Size aLogSize( OutputDevice::LogicToLogic(aBmpEx.GetPrefSize(), aBmpEx.GetPrefMapMode(), MapMode(MapUnit::Map100thMM)) );
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.setWidth( FRound( aBmpSize.Height() * fFactorLog ) );
116 else
117 aBmpSize.setHeight( FRound( aBmpSize.Width() / fFactorLog ) );
119 aBmpEx.Scale(aBmpSize, BmpScaleFlag::BestQuality);
123 // take over BitmapEx
124 aThumbBmp = aBmpEx;
126 if( ( aBmpSize.Width() <= S_THUMB ) && ( aBmpSize.Height() <= S_THUMB ) )
128 aThumbBmp.Convert( BmpConversion::N8BitColors );
129 bRet = true;
131 else
133 const float fFactor = static_cast<float>(aBmpSize.Width()) / aBmpSize.Height();
134 const Size aNewSize( std::max( static_cast<long>(fFactor < 1. ? S_THUMB * fFactor : S_THUMB), 8L ),
135 std::max( static_cast<long>(fFactor < 1. ? S_THUMB : S_THUMB / fFactor), 8L ) );
136 if(aThumbBmp.Scale(
137 static_cast<double>(aNewSize.Width()) / aBmpSize.Width(),
138 static_cast<double>(aNewSize.Height()) / aBmpSize.Height(),
139 BmpScaleFlag::BestQuality ) )
141 aThumbBmp.Convert( BmpConversion::N8BitColors );
142 bRet = true;
147 else if( rGraphic.GetType() == GraphicType::GdiMetafile )
149 const Size aPrefSize( rGraphic.GetPrefSize() );
150 const double fFactor = static_cast<double>(aPrefSize.Width()) / static_cast<double>(aPrefSize.Height());
151 Size aSize( S_THUMB, S_THUMB );
152 if ( fFactor < 1.0 )
153 aSize.setWidth( static_cast<sal_Int32>( S_THUMB * fFactor ) );
154 else
155 aSize.setHeight( static_cast<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( BmpConversion::N8BitColors );
163 bRet = true;
167 return bRet;
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( static_cast<sal_uInt16>(GetObjKind()) );
175 rOut.WriteBool( bIsThumbBmp );
177 if( 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 );
190 else
191 WriteGDIMetaFile( rOut, aThumbMtf );
193 OUString aURLWithoutDestDir = aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
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 )
200 sal_uInt32 nTmp32;
201 sal_uInt16 nTmp16;
203 rIn.ReadUInt32( nTmp32 ).ReadUInt16( nTmp16 ).ReadUInt16( rReadVersion ).ReadUInt16( nTmp16 ).ReadCharAsBool( bIsThumbBmp );
205 if( bIsThumbBmp )
207 ReadDIBBitmapEx(aThumbBmp, rIn);
209 else
211 ReadGDIMetaFile( rIn, aThumbMtf );
214 OUString aTmpStr = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn, RTL_TEXTENCODING_UTF8);
215 aURL = INetURLObject(aTmpStr);
218 OUString const & SgaObject::GetTitle() const
220 return aTitle;
223 void SgaObject::SetTitle( const OUString& rTitle )
225 aTitle = rTitle;
228 SvStream& WriteSgaObject( SvStream& rOut, const SgaObject& rObj )
230 rObj.WriteData( rOut, "" );
231 return rOut;
234 SvStream& ReadSgaObject( SvStream& rIn, SgaObject& rObj )
236 sal_uInt16 nReadVersion;
238 rObj.ReadData( rIn, nReadVersion );
239 rObj.bIsValid = ( rIn.GetError() == ERRCODE_NONE );
241 return rIn;
244 SgaObjectBmp::SgaObjectBmp()
248 SgaObjectBmp::SgaObjectBmp( const INetURLObject& rURL )
250 Graphic aGraphic;
251 OUString aFilter;
253 if ( GalleryGraphicImportRet::IMPORT_NONE != GalleryGraphicImport( rURL, aGraphic, aFilter ) )
254 Init( aGraphic, rURL );
257 SgaObjectBmp::SgaObjectBmp( const Graphic& rGraphic, const INetURLObject& rURL )
259 if( FileExists( rURL ) )
260 Init( rGraphic, rURL );
263 void SgaObjectBmp::Init( const Graphic& rGraphic, const INetURLObject& rURL )
265 aURL = rURL;
266 bIsValid = CreateThumb( rGraphic );
269 void SgaObjectBmp::WriteData( SvStream& rOut, const OUString& rDestDir ) const
271 // Set version
272 SgaObject::WriteData( rOut, rDestDir );
273 char const aDummy[ 10 ] = { 0 };
274 rOut.WriteBytes(aDummy, 10);
275 write_uInt16_lenPrefixed_uInt8s_FromOString(rOut, OString()); //dummy
276 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut, aTitle, RTL_TEXTENCODING_UTF8);
279 void SgaObjectBmp::ReadData( SvStream& rIn, sal_uInt16& rReadVersion )
282 SgaObject::ReadData( rIn, rReadVersion );
283 rIn.SeekRel( 10 ); // 16, 16, 32, 16
284 read_uInt16_lenPrefixed_uInt8s_ToOString(rIn); //dummy
286 if( rReadVersion >= 5 )
287 aTitle = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn, RTL_TEXTENCODING_UTF8);
291 SgaObjectSound::SgaObjectSound() :
292 eSoundType( SOUND_STANDARD )
296 SgaObjectSound::SgaObjectSound( const INetURLObject& rURL ) :
297 eSoundType( SOUND_STANDARD )
300 if( FileExists( rURL ) )
302 aURL = rURL;
303 aThumbBmp = Bitmap( Size( 1, 1 ), 1 );
304 bIsValid = true;
306 else
307 bIsValid = false;
310 SgaObjectSound::~SgaObjectSound()
314 BitmapEx SgaObjectSound::GetThumbBmp() const
316 OUString sId;
318 switch( eSoundType )
320 case SOUND_COMPUTER: sId = RID_SVXBMP_GALLERY_SOUND_1; break;
321 case SOUND_MISC: sId = RID_SVXBMP_GALLERY_SOUND_2; break;
322 case SOUND_MUSIC: sId = RID_SVXBMP_GALLERY_SOUND_3; break;
323 case SOUND_NATURE: sId = RID_SVXBMP_GALLERY_SOUND_4; break;
324 case SOUND_SPEECH: sId = RID_SVXBMP_GALLERY_SOUND_5; break;
325 case SOUND_TECHNIC: sId = RID_SVXBMP_GALLERY_SOUND_6; break;
326 case SOUND_ANIMAL: sId = RID_SVXBMP_GALLERY_SOUND_7; break;
328 // standard
329 default:
330 sId = RID_SVXBMP_GALLERY_MEDIA;
331 break;
334 const BitmapEx aBmpEx(sId);
336 return aBmpEx;
339 void SgaObjectSound::WriteData( SvStream& rOut, const OUString& rDestDir ) const
341 SgaObject::WriteData( rOut, rDestDir );
342 rOut.WriteUInt16( eSoundType );
343 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut, aTitle, RTL_TEXTENCODING_UTF8);
346 void SgaObjectSound::ReadData( SvStream& rIn, sal_uInt16& rReadVersion )
348 SgaObject::ReadData( rIn, rReadVersion );
350 if( rReadVersion >= 5 )
352 sal_uInt16 nTmp16;
354 rIn.ReadUInt16( nTmp16 ); eSoundType = static_cast<GalSoundType>(nTmp16);
356 if( rReadVersion >= 6 )
357 aTitle = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn, RTL_TEXTENCODING_UTF8);
361 SgaObjectAnim::SgaObjectAnim()
365 SgaObjectAnim::SgaObjectAnim( const Graphic& rGraphic,
366 const INetURLObject& rURL )
368 aURL = rURL;
369 bIsValid = CreateThumb( rGraphic );
372 SgaObjectINet::SgaObjectINet()
376 SgaObjectINet::SgaObjectINet( const Graphic& rGraphic, const INetURLObject& rURL ) :
377 SgaObjectAnim ( rGraphic, rURL )
381 SgaObjectSvDraw::SgaObjectSvDraw()
385 SgaObjectSvDraw::SgaObjectSvDraw( const FmFormModel& rModel, const INetURLObject& rURL )
387 aURL = rURL;
388 bIsValid = CreateThumb( rModel );
392 SvxGalleryDrawModel::SvxGalleryDrawModel()
393 : mpFormModel( nullptr )
396 const OUString sFactoryURL("sdraw");
398 mxDoc = SfxObjectShell::CreateObjectByFactoryName( sFactoryURL );
400 if( mxDoc.Is() )
402 mxDoc->DoInitNew();
404 uno::Reference< lang::XUnoTunnel > xTunnel( mxDoc->GetModel(), uno::UNO_QUERY );
405 if( xTunnel.is() )
407 mpFormModel = dynamic_cast< FmFormModel* >(
408 reinterpret_cast<SdrModel*>(xTunnel->getSomething(SdrModel::getUnoTunnelId())));
409 if( mpFormModel )
411 mpFormModel->InsertPage( mpFormModel->AllocPage( false ) );
417 SvxGalleryDrawModel::~SvxGalleryDrawModel()
419 if( mxDoc.Is() )
420 mxDoc->DoClose();
424 SgaObjectSvDraw::SgaObjectSvDraw( SvStream& rIStm, const INetURLObject& rURL )
426 SvxGalleryDrawModel aModel;
428 if( aModel.GetModel() )
430 if( GallerySvDrawImport( rIStm, *aModel.GetModel() ) )
432 aURL = rURL;
433 bIsValid = CreateThumb( *aModel.GetModel() );
438 bool SgaObjectSvDraw::CreateThumb( const FmFormModel& rModel )
440 Graphic aGraphic;
441 ImageMap aImageMap;
442 bool bRet = false;
444 if ( CreateIMapGraphic( rModel, aGraphic, aImageMap ) )
446 bRet = SgaObject::CreateThumb( aGraphic );
448 else
450 const FmFormPage* pPage = static_cast< const FmFormPage* >(rModel.GetPage(0));
452 if(pPage)
454 const tools::Rectangle aObjRect(pPage->GetAllObjBoundRect());
456 if(aObjRect.GetWidth() && aObjRect.GetHeight())
458 ScopedVclPtrInstance< VirtualDevice > pVDev;
459 FmFormView aView(const_cast< FmFormModel& >(rModel), pVDev);
461 aView.ShowSdrPage(const_cast< FmFormPage* >(pPage));
462 aView.MarkAllObj();
463 aThumbBmp = aView.GetMarkedObjBitmapEx();
465 const Size aDiscreteSize(aThumbBmp.GetSizePixel());
467 if(aDiscreteSize.Width() && aDiscreteSize.Height())
469 sal_uInt32 nTargetSizeX(S_THUMB);
470 sal_uInt32 nTargetSizeY(S_THUMB);
472 if(aDiscreteSize.Width() > aDiscreteSize.Height())
474 nTargetSizeY = (aDiscreteSize.Height() * nTargetSizeX) / aDiscreteSize.Width();
476 else
478 nTargetSizeX = (aDiscreteSize.Width() * nTargetSizeY) / aDiscreteSize.Height();
481 if(!!aThumbBmp)
483 aThumbBmp.Scale(Size(nTargetSizeX, nTargetSizeY), BmpScaleFlag::BestQuality);
484 aThumbBmp.Convert(BmpConversion::N8BitColors);
485 bRet = true;
492 return bRet;
495 void SgaObjectSvDraw::WriteData( SvStream& rOut, const OUString& rDestDir ) const
497 SgaObject::WriteData( rOut, rDestDir );
498 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut, aTitle, RTL_TEXTENCODING_UTF8);
501 void SgaObjectSvDraw::ReadData( SvStream& rIn, sal_uInt16& rReadVersion )
503 SgaObject::ReadData( rIn, rReadVersion );
505 if( rReadVersion >= 5 )
506 aTitle = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn, RTL_TEXTENCODING_UTF8);
509 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */