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