Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 :
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"
37 : #include "galobj.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>
43 :
44 : using namespace ::com::sun::star;
45 :
46 503 : SgaObject::SgaObject()
47 : : bIsValid ( false ),
48 503 : bIsThumbBmp ( true )
49 : {
50 503 : }
51 :
52 0 : BitmapEx SgaObject::createPreviewBitmapEx(const Size& rSizePixel) const
53 : {
54 0 : BitmapEx aRetval;
55 :
56 0 : if(rSizePixel.Width() && rSizePixel.Height())
57 : {
58 0 : if(SGA_OBJ_SOUND == GetObjKind())
59 : {
60 0 : aRetval = GAL_RES(RID_SVXBMP_GALLERY_MEDIA);
61 : }
62 0 : else if(IsThumbBitmap())
63 : {
64 0 : aRetval = GetThumbBmp();
65 : }
66 : else
67 : {
68 0 : const Graphic aGraphic(GetThumbMtf());
69 :
70 0 : aRetval = aGraphic.GetBitmapEx();
71 : }
72 :
73 0 : if(!aRetval.IsEmpty())
74 : {
75 0 : const Size aCurrentSizePixel(aRetval.GetSizePixel());
76 0 : const double fScaleX((double)rSizePixel.Width() / (double)aCurrentSizePixel.Width());
77 0 : const double fScaleY((double)rSizePixel.Height() / (double)aCurrentSizePixel.Height());
78 0 : const double fScale(std::min(fScaleX, fScaleY));
79 :
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 0 : if(fScale < 1.0 && fabs(1.0 - fScale) > 0.005)
83 : {
84 0 : aRetval.Scale(fScale, fScale, BmpScaleFlag::BestQuality);
85 : }
86 : }
87 : }
88 :
89 0 : return aRetval;
90 : }
91 :
92 468 : bool SgaObject::CreateThumb( const Graphic& rGraphic )
93 : {
94 468 : bool bRet = false;
95 :
96 468 : if( rGraphic.GetType() == GRAPHIC_BITMAP )
97 : {
98 467 : BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
99 467 : Size aBmpSize( aBmpEx.GetSizePixel() );
100 :
101 467 : if( aBmpSize.Width() && aBmpSize.Height() )
102 : {
103 1226 : if( aBmpEx.GetPrefMapMode().GetMapUnit() != MAP_PIXEL &&
104 759 : aBmpEx.GetPrefSize().Width() > 0 &&
105 292 : aBmpEx.GetPrefSize().Height() > 0 )
106 : {
107 292 : Size aLogSize( OutputDevice::LogicToLogic( aBmpEx.GetPrefSize(), aBmpEx.GetPrefMapMode(), MAP_100TH_MM ) );
108 :
109 292 : if( aLogSize.Width() > 0 && aLogSize.Height() > 0 )
110 : {
111 292 : double fFactorLog = static_cast< double >( aLogSize.Width() ) / aLogSize.Height();
112 292 : double fFactorPix = static_cast< double >( aBmpSize.Width() ) / aBmpSize.Height();
113 :
114 292 : if( fFactorPix > fFactorLog )
115 111 : aBmpSize.Width() = FRound( aBmpSize.Height() * fFactorLog );
116 : else
117 181 : aBmpSize.Height() = FRound( aBmpSize.Width() / fFactorLog );
118 :
119 292 : aBmpEx.SetSizePixel( aBmpSize, BmpScaleFlag::BestQuality );
120 : }
121 : }
122 :
123 : // take over BitmapEx
124 467 : aThumbBmp = aBmpEx;
125 :
126 467 : if( ( aBmpSize.Width() <= S_THUMB ) && ( aBmpSize.Height() <= S_THUMB ) )
127 : {
128 13 : aThumbBmp.Convert( BMP_CONVERSION_8BIT_COLORS );
129 13 : bRet = true;
130 : }
131 : else
132 : {
133 454 : const float fFactor = (float) aBmpSize.Width() / aBmpSize.Height();
134 908 : const Size aNewSize( std::max( (long) (fFactor < 1. ? S_THUMB * fFactor : S_THUMB), 8L ),
135 1362 : std::max( (long) (fFactor < 1. ? S_THUMB : S_THUMB / fFactor), 8L ) );
136 908 : if(aThumbBmp.Scale(
137 454 : (double) aNewSize.Width() / aBmpSize.Width(),
138 454 : (double) aNewSize.Height() / aBmpSize.Height(),
139 1362 : BmpScaleFlag::BestQuality ) )
140 : {
141 454 : aThumbBmp.Convert( BMP_CONVERSION_8BIT_COLORS );
142 454 : bRet = true;
143 : }
144 : }
145 467 : }
146 : }
147 1 : else if( rGraphic.GetType() == GRAPHIC_GDIMETAFILE )
148 : {
149 1 : const Size aPrefSize( rGraphic.GetPrefSize() );
150 1 : const double fFactor = (double)aPrefSize.Width() / (double)aPrefSize.Height();
151 1 : Size aSize( S_THUMB, S_THUMB );
152 1 : if ( fFactor < 1.0 )
153 0 : aSize.Width() = (sal_Int32)( S_THUMB * fFactor );
154 : else
155 1 : aSize.Height() = (sal_Int32)( S_THUMB / fFactor );
156 :
157 1 : const GraphicConversionParameters aParameters(aSize, false, true, true /*TODO: extra ", true" post-#i121194#*/);
158 1 : aThumbBmp = rGraphic.GetBitmapEx(aParameters);
159 :
160 1 : if( !aThumbBmp.IsEmpty() )
161 : {
162 1 : aThumbBmp.Convert( BMP_CONVERSION_8BIT_COLORS );
163 1 : bRet = true;
164 : }
165 : }
166 :
167 468 : return bRet;
168 : }
169 :
170 503 : void SgaObject::WriteData( SvStream& rOut, const OUString& rDestDir ) const
171 : {
172 : static const sal_uInt32 nInventor = COMPAT_FORMAT( 'S', 'G', 'A', '3' );
173 :
174 503 : rOut.WriteUInt32( nInventor ).WriteUInt16( 0x0004 ).WriteUInt16( GetVersion() ).WriteUInt16( GetObjKind() );
175 503 : rOut.WriteBool( bIsThumbBmp );
176 :
177 503 : if( bIsThumbBmp )
178 : {
179 503 : const SvStreamCompressFlags nOldCompressMode = rOut.GetCompressMode();
180 503 : const sal_uIntPtr nOldVersion = rOut.GetVersion();
181 :
182 503 : rOut.SetCompressMode( SvStreamCompressFlags::ZBITMAP );
183 503 : rOut.SetVersion( SOFFICE_FILEFORMAT_50 );
184 :
185 503 : WriteDIBBitmapEx(aThumbBmp, rOut);
186 :
187 503 : rOut.SetVersion( nOldVersion );
188 503 : rOut.SetCompressMode( nOldCompressMode );
189 : }
190 : else
191 0 : WriteGDIMetaFile( rOut, aThumbMtf );
192 :
193 503 : OUString aURLWithoutDestDir = aURL.GetMainURL( INetURLObject::NO_DECODE );
194 503 : aURLWithoutDestDir = aURLWithoutDestDir.replaceFirst(rDestDir, "");
195 503 : write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut, aURLWithoutDestDir, RTL_TEXTENCODING_UTF8);
196 503 : }
197 :
198 0 : void SgaObject::ReadData(SvStream& rIn, sal_uInt16& rReadVersion )
199 : {
200 : sal_uInt32 nTmp32;
201 : sal_uInt16 nTmp16;
202 :
203 0 : rIn.ReadUInt32( nTmp32 ).ReadUInt16( nTmp16 ).ReadUInt16( rReadVersion ).ReadUInt16( nTmp16 ).ReadCharAsBool( bIsThumbBmp );
204 :
205 0 : if( bIsThumbBmp )
206 : {
207 0 : ReadDIBBitmapEx(aThumbBmp, rIn);
208 : }
209 : else
210 : {
211 0 : ReadGDIMetaFile( rIn, aThumbMtf );
212 : }
213 :
214 0 : OUString aTmpStr = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn, RTL_TEXTENCODING_UTF8);
215 0 : aURL = INetURLObject(aTmpStr);
216 0 : }
217 :
218 0 : const OUString SgaObject::GetTitle() const
219 : {
220 0 : OUString aReturnValue( aTitle );
221 0 : if ( !getenv( "GALLERY_SHOW_PRIVATE_TITLE" ) )
222 : {
223 0 : if ( comphelper::string::getTokenCount(aReturnValue, ':') == 3 )
224 : {
225 0 : OUString aPrivateInd ( aReturnValue.getToken( 0, ':' ) );
226 0 : OUString aResourceName( aReturnValue.getToken( 1, ':' ) );
227 0 : sal_Int32 nResId ( aReturnValue.getToken( 2, ':' ).toInt32() );
228 0 : if ( aPrivateInd == "private" &&
229 0 : !aResourceName.isEmpty() && ( nResId > 0 ) && ( nResId < 0x10000 ) )
230 : {
231 0 : OString aMgrName(OUStringToOString(aResourceName, RTL_TEXTENCODING_UTF8));
232 : boost::scoped_ptr<ResMgr> pResMgr(ResMgr::CreateResMgr( aMgrName.getStr(),
233 0 : Application::GetSettings().GetUILanguageTag() ));
234 0 : if ( pResMgr )
235 : {
236 0 : ResId aResId( (sal_uInt16)nResId, *pResMgr );
237 0 : aResId.SetRT( RSC_STRING );
238 0 : if ( pResMgr->IsAvailable( aResId ) )
239 : {
240 0 : aReturnValue = aResId.toString();
241 : }
242 0 : }
243 0 : }
244 : }
245 : }
246 0 : return aReturnValue;
247 : }
248 :
249 0 : void SgaObject::SetTitle( const OUString& rTitle )
250 : {
251 0 : aTitle = rTitle;
252 0 : }
253 :
254 0 : SvStream& WriteSgaObject( SvStream& rOut, const SgaObject& rObj )
255 : {
256 0 : rObj.WriteData( rOut, "" );
257 0 : return rOut;
258 : }
259 :
260 0 : SvStream& ReadSgaObject( SvStream& rIn, SgaObject& rObj )
261 : {
262 : sal_uInt16 nReadVersion;
263 :
264 0 : rObj.ReadData( rIn, nReadVersion );
265 0 : rObj.bIsValid = ( rIn.GetError() == ERRCODE_NONE );
266 :
267 0 : return rIn;
268 : }
269 :
270 0 : SgaObjectBmp::SgaObjectBmp()
271 : {
272 0 : }
273 :
274 0 : SgaObjectBmp::SgaObjectBmp( const INetURLObject& rURL )
275 : {
276 0 : Graphic aGraphic;
277 0 : OUString aFilter;
278 :
279 0 : if ( GalleryGraphicImportRet::IMPORT_NONE != GalleryGraphicImport( rURL, aGraphic, aFilter ) )
280 0 : Init( aGraphic, rURL );
281 0 : }
282 :
283 468 : SgaObjectBmp::SgaObjectBmp( const Graphic& rGraphic, const INetURLObject& rURL, const OUString& )
284 : {
285 468 : if( FileExists( rURL ) )
286 468 : Init( rGraphic, rURL );
287 468 : }
288 :
289 468 : void SgaObjectBmp::Init( const Graphic& rGraphic, const INetURLObject& rURL )
290 : {
291 468 : aURL = rURL;
292 468 : bIsValid = CreateThumb( rGraphic );
293 468 : }
294 :
295 468 : void SgaObjectBmp::WriteData( SvStream& rOut, const OUString& rDestDir ) const
296 : {
297 : // Set version
298 468 : SgaObject::WriteData( rOut, rDestDir );
299 : char aDummy[ 10 ];
300 468 : rOut.Write( aDummy, 10 );
301 468 : write_uInt16_lenPrefixed_uInt8s_FromOString(rOut, OString()); //dummy
302 468 : write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut, aTitle, RTL_TEXTENCODING_UTF8);
303 468 : }
304 :
305 0 : void SgaObjectBmp::ReadData( SvStream& rIn, sal_uInt16& rReadVersion )
306 : {
307 :
308 0 : SgaObject::ReadData( rIn, rReadVersion );
309 0 : rIn.SeekRel( 10 ); // 16, 16, 32, 16
310 0 : read_uInt16_lenPrefixed_uInt8s_ToOString(rIn); //dummy
311 :
312 0 : if( rReadVersion >= 5 )
313 0 : aTitle = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn, RTL_TEXTENCODING_UTF8);
314 0 : }
315 :
316 :
317 0 : SgaObjectSound::SgaObjectSound() :
318 0 : eSoundType( SOUND_STANDARD )
319 : {
320 0 : }
321 :
322 35 : SgaObjectSound::SgaObjectSound( const INetURLObject& rURL ) :
323 35 : eSoundType( SOUND_STANDARD )
324 : {
325 :
326 35 : if( FileExists( rURL ) )
327 : {
328 35 : aURL = rURL;
329 35 : aThumbBmp = Bitmap( Size( 1, 1 ), 1 );
330 35 : bIsValid = true;
331 : }
332 : else
333 0 : bIsValid = false;
334 35 : }
335 :
336 70 : SgaObjectSound::~SgaObjectSound()
337 : {
338 70 : }
339 :
340 0 : BitmapEx SgaObjectSound::GetThumbBmp() const
341 : {
342 : sal_uInt16 nId;
343 :
344 0 : switch( eSoundType )
345 : {
346 0 : case( SOUND_COMPUTER ): nId = RID_SVXBMP_GALLERY_SOUND_1; break;
347 0 : case( SOUND_MISC ): nId = RID_SVXBMP_GALLERY_SOUND_2; break;
348 0 : case( SOUND_MUSIC ): nId = RID_SVXBMP_GALLERY_SOUND_3; break;
349 0 : case( SOUND_NATURE ): nId = RID_SVXBMP_GALLERY_SOUND_4; break;
350 0 : case( SOUND_SPEECH ): nId = RID_SVXBMP_GALLERY_SOUND_5; break;
351 0 : case( SOUND_TECHNIC ): nId = RID_SVXBMP_GALLERY_SOUND_6; break;
352 0 : case( SOUND_ANIMAL ): nId = RID_SVXBMP_GALLERY_SOUND_7; break;
353 :
354 : // standard
355 : default:
356 0 : nId = RID_SVXBMP_GALLERY_MEDIA;
357 0 : break;
358 : }
359 :
360 0 : const BitmapEx aBmpEx( GAL_RES( nId ) );
361 :
362 0 : return aBmpEx;
363 : }
364 :
365 35 : void SgaObjectSound::WriteData( SvStream& rOut, const OUString& rDestDir ) const
366 : {
367 35 : SgaObject::WriteData( rOut, rDestDir );
368 35 : rOut.WriteUInt16( eSoundType );
369 35 : write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut, aTitle, RTL_TEXTENCODING_UTF8);
370 35 : }
371 :
372 0 : void SgaObjectSound::ReadData( SvStream& rIn, sal_uInt16& rReadVersion )
373 : {
374 0 : SgaObject::ReadData( rIn, rReadVersion );
375 :
376 0 : if( rReadVersion >= 5 )
377 : {
378 : sal_uInt16 nTmp16;
379 :
380 0 : rIn.ReadUInt16( nTmp16 ); eSoundType = (GalSoundType) nTmp16;
381 :
382 0 : if( rReadVersion >= 6 )
383 0 : aTitle = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn, RTL_TEXTENCODING_UTF8);
384 : }
385 0 : }
386 :
387 0 : SgaObjectAnim::SgaObjectAnim()
388 : {
389 0 : }
390 :
391 0 : SgaObjectAnim::SgaObjectAnim( const Graphic& rGraphic,
392 : const INetURLObject& rURL,
393 0 : const OUString& )
394 : {
395 0 : aURL = rURL;
396 0 : bIsValid = CreateThumb( rGraphic );
397 0 : }
398 :
399 0 : SgaObjectINet::SgaObjectINet()
400 : {
401 0 : }
402 :
403 0 : SgaObjectINet::SgaObjectINet( const Graphic& rGraphic, const INetURLObject& rURL, const OUString& rFormatName ) :
404 0 : SgaObjectAnim ( rGraphic, rURL, rFormatName )
405 : {
406 0 : }
407 :
408 0 : SgaObjectSvDraw::SgaObjectSvDraw()
409 : {
410 0 : }
411 :
412 0 : SgaObjectSvDraw::SgaObjectSvDraw( const FmFormModel& rModel, const INetURLObject& rURL )
413 : {
414 0 : aURL = rURL;
415 0 : bIsValid = CreateThumb( rModel );
416 0 : }
417 :
418 :
419 0 : SvxGalleryDrawModel::SvxGalleryDrawModel()
420 0 : : mpFormModel( 0 )
421 : {
422 :
423 0 : const OUString sFactoryURL("sdraw");
424 :
425 0 : mxDoc = SfxObjectShell::CreateObjectByFactoryName( sFactoryURL );
426 :
427 0 : if( mxDoc.Is() )
428 : {
429 0 : mxDoc->DoInitNew(0);
430 :
431 0 : uno::Reference< lang::XUnoTunnel > xTunnel( mxDoc->GetModel(), uno::UNO_QUERY );
432 0 : if( xTunnel.is() )
433 : {
434 : mpFormModel = dynamic_cast< FmFormModel* >(
435 0 : reinterpret_cast<SdrModel*>(xTunnel->getSomething(SdrModel::getUnoTunnelImplementationId())));
436 0 : if( mpFormModel )
437 : {
438 0 : mpFormModel->InsertPage( mpFormModel->AllocPage( false ) );
439 : }
440 0 : }
441 0 : }
442 0 : }
443 :
444 0 : SvxGalleryDrawModel::~SvxGalleryDrawModel()
445 : {
446 0 : if( mxDoc.Is() )
447 0 : mxDoc->DoClose();
448 :
449 0 : }
450 :
451 0 : SgaObjectSvDraw::SgaObjectSvDraw( SvStream& rIStm, const INetURLObject& rURL )
452 : {
453 0 : SvxGalleryDrawModel aModel;
454 :
455 0 : if( aModel.GetModel() )
456 : {
457 0 : if( GallerySvDrawImport( rIStm, *aModel.GetModel() ) )
458 : {
459 0 : aURL = rURL;
460 0 : bIsValid = CreateThumb( *aModel.GetModel() );
461 : }
462 0 : }
463 0 : }
464 :
465 0 : bool SgaObjectSvDraw::CreateThumb( const FmFormModel& rModel )
466 : {
467 0 : Graphic aGraphic;
468 0 : ImageMap aImageMap;
469 0 : bool bRet = false;
470 :
471 0 : if ( CreateIMapGraphic( rModel, aGraphic, aImageMap ) )
472 : {
473 0 : bRet = SgaObject::CreateThumb( aGraphic );
474 : }
475 : else
476 : {
477 0 : const FmFormPage* pPage = static_cast< const FmFormPage* >(rModel.GetPage(0));
478 :
479 0 : if(pPage)
480 : {
481 0 : const Rectangle aObjRect(pPage->GetAllObjBoundRect());
482 :
483 0 : if(aObjRect.GetWidth() && aObjRect.GetHeight())
484 : {
485 0 : ScopedVclPtrInstance< VirtualDevice > pVDev;
486 0 : FmFormView aView(const_cast< FmFormModel* >(&rModel), pVDev);
487 :
488 0 : aView.ShowSdrPage(const_cast< FmFormPage* >(pPage));
489 0 : aView.MarkAllObj();
490 0 : aThumbBmp = aView.GetMarkedObjBitmapEx();
491 :
492 0 : const Size aDiscreteSize(aThumbBmp.GetSizePixel());
493 :
494 0 : if(aDiscreteSize.Width() && aDiscreteSize.Height())
495 : {
496 0 : sal_uInt32 nTargetSizeX(S_THUMB);
497 0 : sal_uInt32 nTargetSizeY(S_THUMB);
498 :
499 0 : if(aDiscreteSize.Width() > aDiscreteSize.Height())
500 : {
501 0 : nTargetSizeY = (aDiscreteSize.Height() * nTargetSizeX) / aDiscreteSize.Width();
502 : }
503 : else
504 : {
505 0 : nTargetSizeX = (aDiscreteSize.Width() * nTargetSizeY) / aDiscreteSize.Height();
506 : }
507 :
508 0 : if(!!aThumbBmp)
509 : {
510 0 : aThumbBmp.Scale(Size(nTargetSizeX, nTargetSizeY), BmpScaleFlag::BestQuality);
511 0 : aThumbBmp.Convert(BMP_CONVERSION_8BIT_COLORS);
512 0 : bRet = true;
513 : }
514 0 : }
515 : }
516 : }
517 : }
518 :
519 0 : return bRet;
520 : }
521 :
522 0 : void SgaObjectSvDraw::WriteData( SvStream& rOut, const OUString& rDestDir ) const
523 : {
524 0 : SgaObject::WriteData( rOut, rDestDir );
525 0 : write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut, aTitle, RTL_TEXTENCODING_UTF8);
526 0 : }
527 :
528 0 : void SgaObjectSvDraw::ReadData( SvStream& rIn, sal_uInt16& rReadVersion )
529 : {
530 0 : SgaObject::ReadData( rIn, rReadVersion );
531 :
532 0 : if( rReadVersion >= 5 )
533 0 : aTitle = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn, RTL_TEXTENCODING_UTF8);
534 435 : }
535 :
536 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|