1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26
27 #define ENABLE_BYTESTRING_STREAM_OPERATORS
28
29 #include <com/sun/star/lang/XUnoTunnel.hpp>
30 #include <sfx2/objsh.hxx>
31 #include <sfx2/docfac.hxx>
32 #include <comphelper/classids.hxx>
33 #include <unotools/pathoptions.hxx>
34 #include <tools/rcid.h>
35 #include <tools/vcompat.hxx>
36 #include <vcl/virdev.hxx>
37 #include <svl/itempool.hxx>
38 #include <svx/fmmodel.hxx>
39 #include <svx/fmview.hxx>
40 #include <svx/fmpage.hxx>
41 #include "gallery.hrc"
42 #include "svx/galmisc.hxx"
43 #include "galobj.hxx"
44 #include <vcl/salbtype.hxx> // FRound
45 #include <vcl/svapp.hxx>
46 #include <vcl/dibtools.hxx>
47 #include "gallerydrawmodel.hxx"
48
49 using namespace ::com::sun::star;
50
51 // -------------
52 // - SgaObject -
53 // -------------
54
SgaObject()55 SgaObject::SgaObject()
56 : bIsValid ( sal_False ),
57 bIsThumbBmp ( sal_True )
58 {
59 }
60
createPreviewBitmapEx(const Size & rSizePixel) const61 BitmapEx SgaObject::createPreviewBitmapEx(const Size& rSizePixel) const
62 {
63 BitmapEx aRetval;
64
65 if(rSizePixel.Width() && rSizePixel.Height())
66 {
67 if(SGA_OBJ_SOUND == GetObjKind())
68 {
69 aRetval = GAL_RESID(RID_SVXBMP_GALLERY_MEDIA);
70 }
71 else if(IsThumbBitmap())
72 {
73 aRetval = GetThumbBmp();
74 }
75 else
76 {
77 const Graphic aGraphic(GetThumbMtf());
78
79 aRetval = aGraphic.GetBitmapEx();
80 }
81
82 if(!aRetval.IsEmpty())
83 {
84 const Size aCurrentSizePixel(aRetval.GetSizePixel());
85 const double fScaleX((double)rSizePixel.Width() / (double)aCurrentSizePixel.Width());
86 const double fScaleY((double)rSizePixel.Height() / (double)aCurrentSizePixel.Height());
87 const double fScale(std::min(fScaleX, fScaleY));
88
89 // only scale when need to decrease, no need to make bigger as original. Also
90 // prevent scaling close to 1.0 which is not needed for pixel graphics
91 if(fScale < 1.0 && fabs(1.0 - fScale) > 0.005)
92 {
93 static sal_uInt32 nScaleFlag = BMP_SCALE_FASTESTINTERPOLATE;
94
95 aRetval.Scale(fScale, fScale, nScaleFlag);
96 }
97 }
98 }
99
100 return aRetval;
101 }
102
103 // ------------------------------------------------------------------------
104
CreateThumb(const Graphic & rGraphic)105 sal_Bool SgaObject::CreateThumb( const Graphic& rGraphic )
106 {
107 sal_Bool bRet = sal_False;
108
109 if( rGraphic.GetType() == GRAPHIC_BITMAP )
110 {
111 BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
112 Size aBmpSize( aBmpEx.GetSizePixel() );
113
114 if( aBmpSize.Width() && aBmpSize.Height() )
115 {
116 const Color aWhite( COL_WHITE );
117
118 if( aBmpEx.GetPrefMapMode().GetMapUnit() != MAP_PIXEL &&
119 aBmpEx.GetPrefSize().Width() > 0 &&
120 aBmpEx.GetPrefSize().Height() > 0 )
121 {
122 Size aLogSize( OutputDevice::LogicToLogic( aBmpEx.GetPrefSize(), aBmpEx.GetPrefMapMode(), MAP_100TH_MM ) );
123
124 if( aLogSize.Width() > 0 && aLogSize.Height() > 0 )
125 {
126 double fFactorLog = static_cast< double >( aLogSize.Width() ) / aLogSize.Height();
127 double fFactorPix = static_cast< double >( aBmpSize.Width() ) / aBmpSize.Height();
128
129 if( fFactorPix > fFactorLog )
130 aBmpSize.Width() = FRound( aBmpSize.Height() * fFactorLog );
131 else
132 aBmpSize.Height() = FRound( aBmpSize.Width() / fFactorLog );
133
134 aBmpEx.SetSizePixel( aBmpSize, BMP_SCALE_BESTQUALITY );
135 }
136 }
137
138 // take over BitmapEx
139 aThumbBmp = aBmpEx;
140
141 if( ( aBmpSize.Width() <= S_THUMB ) && ( aBmpSize.Height() <= S_THUMB ) )
142 {
143 aThumbBmp.Convert( BMP_CONVERSION_8BIT_COLORS );
144 bRet = sal_True;
145 }
146 else
147 {
148 const float fFactor = (float) aBmpSize.Width() / aBmpSize.Height();
149 const Size aNewSize( Max( (long) (fFactor < 1. ? S_THUMB * fFactor : S_THUMB), 8L ),
150 Max( (long) (fFactor < 1. ? S_THUMB : S_THUMB / fFactor), 8L ) );
151
152 if(aThumbBmp.Scale(
153 (double) aNewSize.Width() / aBmpSize.Width(),
154 (double) aNewSize.Height() / aBmpSize.Height(),
155 BMP_SCALE_BESTQUALITY ) )
156 {
157 aThumbBmp.Convert( BMP_CONVERSION_8BIT_COLORS );
158 bRet = sal_True;
159 }
160 }
161 }
162 }
163 else if( rGraphic.GetType() == GRAPHIC_GDIMETAFILE )
164 {
165 const Size aPrefSize( rGraphic.GetPrefSize() );
166 const double fFactor = (double)aPrefSize.Width() / (double)aPrefSize.Height();
167 Size aSize( S_THUMB, S_THUMB );
168 if ( fFactor < 1.0 )
169 aSize.Width() = (sal_Int32)( S_THUMB * fFactor );
170 else
171 aSize.Height() = (sal_Int32)( S_THUMB / fFactor );
172
173 const GraphicConversionParameters aParameters(aSize, false, true, true, true);
174 aThumbBmp = rGraphic.GetBitmapEx(aParameters);
175
176 if( !aThumbBmp.IsEmpty() )
177 {
178 aThumbBmp.Convert( BMP_CONVERSION_8BIT_COLORS );
179 bRet = sal_True;
180 }
181 }
182
183 return bRet;
184 }
185
186 // ------------------------------------------------------------------------
187
WriteData(SvStream & rOut,const String & rDestDir) const188 void SgaObject::WriteData( SvStream& rOut, const String& rDestDir ) const
189 {
190 static const sal_uInt32 nInventor = COMPAT_FORMAT( 'S', 'G', 'A', '3' );
191
192 rOut << nInventor << (sal_uInt16) 0x0004 << GetVersion() << (sal_uInt16) GetObjKind();
193 rOut << bIsThumbBmp;
194
195 if( bIsThumbBmp )
196 {
197 const sal_uInt16 nOldCompressMode = rOut.GetCompressMode();
198 const sal_uIntPtr nOldVersion = rOut.GetVersion();
199
200 rOut.SetCompressMode( COMPRESSMODE_ZBITMAP );
201 rOut.SetVersion( SOFFICE_FILEFORMAT_50 );
202
203 WriteDIBBitmapEx(aThumbBmp, rOut);
204
205 rOut.SetVersion( nOldVersion );
206 rOut.SetCompressMode( nOldCompressMode );
207 }
208 else
209 rOut << aThumbMtf;
210
211 String aURLWithoutDestDir = String(aURL.GetMainURL( INetURLObject::NO_DECODE ));
212 aURLWithoutDestDir.SearchAndReplace(rDestDir, String());
213 rOut << ByteString( aURLWithoutDestDir, RTL_TEXTENCODING_UTF8 );
214 }
215
216 // ------------------------------------------------------------------------
217
ReadData(SvStream & rIn,sal_uInt16 & rReadVersion)218 void SgaObject::ReadData(SvStream& rIn, sal_uInt16& rReadVersion )
219 {
220 ByteString aTmpStr;
221 sal_uInt32 nTmp32;
222 sal_uInt16 nTmp16;
223
224 rIn >> nTmp32 >> nTmp16 >> rReadVersion >> nTmp16 >> bIsThumbBmp;
225
226 if( bIsThumbBmp )
227 {
228 ReadDIBBitmapEx(aThumbBmp, rIn);
229 }
230 else
231 {
232 rIn >> aThumbMtf;
233 }
234
235 rIn >> aTmpStr; aURL = INetURLObject( String( aTmpStr.GetBuffer(), RTL_TEXTENCODING_UTF8 ) );
236 }
237
238 // ------------------------------------------------------------------------
239
GetTitle() const240 const String SgaObject::GetTitle() const
241 {
242 String aReturnValue( aTitle );
243 if ( !getenv( "GALLERY_SHOW_PRIVATE_TITLE" ) )
244 {
245 if ( aReturnValue.GetTokenCount( ':' ) == 3 )
246 {
247 String aPrivateInd ( aReturnValue.GetToken( 0, ':' ) );
248 String aResourceName( aReturnValue.GetToken( 1, ':' ) );
249 sal_Int32 nResId ( aReturnValue.GetToken( 2, ':' ).ToInt32() );
250 if ( aReturnValue.GetToken( 0, ':' ).EqualsAscii( "private" ) &&
251 aResourceName.Len() && ( nResId > 0 ) && ( nResId < 0x10000 ) )
252 {
253 ByteString aMgrName( aResourceName, RTL_TEXTENCODING_UTF8 );
254 ResMgr* pResMgr = ResMgr::CreateResMgr( aMgrName.GetBuffer(),
255 Application::GetSettings().GetUILocale() );
256 if ( pResMgr )
257 {
258 ResId aResId( (sal_uInt16)nResId, *pResMgr );
259 aResId.SetRT( RSC_STRING );
260 if ( pResMgr->IsAvailable( aResId ) )
261 {
262 aReturnValue = String( aResId );
263 }
264 delete pResMgr;
265 }
266 }
267 }
268 }
269 return aReturnValue;
270 }
271
272 // ------------------------------------------------------------------------
273
SetTitle(const String & rTitle)274 void SgaObject::SetTitle( const String& rTitle )
275 {
276 aTitle = rTitle;
277 }
278
279 // ------------------------------------------------------------------------
280
operator <<(SvStream & rOut,const SgaObject & rObj)281 SvStream& operator<<( SvStream& rOut, const SgaObject& rObj )
282 {
283 rObj.WriteData( rOut, String() );
284 return rOut;
285 }
286
287 // ------------------------------------------------------------------------
288
operator >>(SvStream & rIn,SgaObject & rObj)289 SvStream& operator>>( SvStream& rIn, SgaObject& rObj )
290 {
291 sal_uInt16 nReadVersion;
292
293 rObj.ReadData( rIn, nReadVersion );
294 rObj.bIsValid = ( rIn.GetError() == ERRCODE_NONE );
295
296 return rIn;
297 }
298
299 // ----------------
300 // - SgaObjectBmp -
301 // ----------------
302
SgaObjectBmp()303 SgaObjectBmp::SgaObjectBmp()
304 {
305 }
306
307 // ------------------------------------------------------------------------
308
SgaObjectBmp(const INetURLObject & rURL)309 SgaObjectBmp::SgaObjectBmp( const INetURLObject& rURL )
310 {
311 Graphic aGraphic;
312 String aFilter;
313
314 if ( SGA_IMPORT_NONE != GalleryGraphicImport( rURL, aGraphic, aFilter ) )
315 Init( aGraphic, rURL );
316 }
317
318 // ------------------------------------------------------------------------
319
SgaObjectBmp(const Graphic & rGraphic,const INetURLObject & rURL,const String &)320 SgaObjectBmp::SgaObjectBmp( const Graphic& rGraphic, const INetURLObject& rURL, const String& )
321 {
322 if( FileExists( rURL ) )
323 Init( rGraphic, rURL );
324 }
325
326 // ------------------------------------------------------------------------
327
Init(const Graphic & rGraphic,const INetURLObject & rURL)328 void SgaObjectBmp::Init( const Graphic& rGraphic, const INetURLObject& rURL )
329 {
330 aURL = rURL;
331 bIsValid = CreateThumb( rGraphic );
332 }
333
334 // ------------------------------------------------------------------------
335
WriteData(SvStream & rOut,const String & rDestDir) const336 void SgaObjectBmp::WriteData( SvStream& rOut, const String& rDestDir ) const
337 {
338 String aDummyStr;
339 char aDummy[ 10 ];
340
341 // Version setzen
342 SgaObject::WriteData( rOut, rDestDir );
343 rOut.Write( aDummy, 10 );
344 rOut << ByteString( aDummyStr, RTL_TEXTENCODING_UTF8 ) << ByteString( aTitle, RTL_TEXTENCODING_UTF8 );
345 }
346
347 // ------------------------------------------------------------------------
348
ReadData(SvStream & rIn,sal_uInt16 & rReadVersion)349 void SgaObjectBmp::ReadData( SvStream& rIn, sal_uInt16& rReadVersion )
350 {
351 ByteString aTmpStr;
352
353 SgaObject::ReadData( rIn, rReadVersion );
354 rIn.SeekRel( 10 ); // 16, 16, 32, 16
355 rIn >> aTmpStr; // dummy
356
357 if( rReadVersion >= 5 )
358 {
359 rIn >> aTmpStr; aTitle = String( aTmpStr.GetBuffer(), RTL_TEXTENCODING_UTF8 );
360 }
361 }
362
363 // ------------------
364 // - SgaObjectSound -
365 // ------------------
DBG_NAME(SgaObjectSound)366 DBG_NAME(SgaObjectSound)
367
368 SgaObjectSound::SgaObjectSound() :
369 eSoundType( SOUND_STANDARD )
370 {
371 DBG_CTOR(SgaObjectSound,NULL);
372
373 }
374
375 // ------------------------------------------------------------------------
376
SgaObjectSound(const INetURLObject & rURL)377 SgaObjectSound::SgaObjectSound( const INetURLObject& rURL ) :
378 eSoundType( SOUND_STANDARD )
379 {
380 DBG_CTOR(SgaObjectSound,NULL);
381
382 if( FileExists( rURL ) )
383 {
384 aURL = rURL;
385 aThumbBmp = Bitmap( Size( 1, 1 ), 1 );
386 bIsValid = sal_True;
387 }
388 else
389 bIsValid = sal_False;
390 }
391
392 // ------------------------------------------------------------------------
393
~SgaObjectSound()394 SgaObjectSound::~SgaObjectSound()
395 {
396
397 DBG_DTOR(SgaObjectSound,NULL);
398 }
399
400 // ------------------------------------------------------------------------
401
GetThumbBmp() const402 BitmapEx SgaObjectSound::GetThumbBmp() const
403 {
404 sal_uInt16 nId;
405
406 switch( eSoundType )
407 {
408 case( SOUND_COMPUTER ): nId = RID_SVXBMP_GALLERY_SOUND_1; break;
409 case( SOUND_MISC ): nId = RID_SVXBMP_GALLERY_SOUND_2; break;
410 case( SOUND_MUSIC ): nId = RID_SVXBMP_GALLERY_SOUND_3; break;
411 case( SOUND_NATURE ): nId = RID_SVXBMP_GALLERY_SOUND_4; break;
412 case( SOUND_SPEECH ): nId = RID_SVXBMP_GALLERY_SOUND_5; break;
413 case( SOUND_TECHNIC ): nId = RID_SVXBMP_GALLERY_SOUND_6; break;
414 case( SOUND_ANIMAL ): nId = RID_SVXBMP_GALLERY_SOUND_7; break;
415
416 // standard
417 default:
418 nId = RID_SVXBMP_GALLERY_MEDIA;
419 break;
420 }
421
422 const BitmapEx aBmpEx( GAL_RESID( nId ) );
423
424 return aBmpEx;
425 }
426
427 // ------------------------------------------------------------------------
428
WriteData(SvStream & rOut,const String & rDestDir) const429 void SgaObjectSound::WriteData( SvStream& rOut, const String& rDestDir ) const
430 {
431 SgaObject::WriteData( rOut, rDestDir );
432 rOut << (sal_uInt16) eSoundType << ByteString( aTitle, RTL_TEXTENCODING_UTF8 );
433 }
434
435 // ------------------------------------------------------------------------
436
ReadData(SvStream & rIn,sal_uInt16 & rReadVersion)437 void SgaObjectSound::ReadData( SvStream& rIn, sal_uInt16& rReadVersion )
438 {
439 SgaObject::ReadData( rIn, rReadVersion );
440
441 if( rReadVersion >= 5 )
442 {
443 ByteString aTmpStr;
444 sal_uInt16 nTmp16;
445
446 rIn >> nTmp16; eSoundType = (GalSoundType) nTmp16;
447
448 if( rReadVersion >= 6 )
449 {
450 rIn >> aTmpStr; aTitle = String( aTmpStr.GetBuffer(), RTL_TEXTENCODING_UTF8 );
451 }
452 }
453 }
454
455 // -----------------
456 // - SgaObjectAnim -
457 // -----------------
458
SgaObjectAnim()459 SgaObjectAnim::SgaObjectAnim()
460 {
461 }
462
463 // ------------------------------------------------------------------------
464
SgaObjectAnim(const Graphic & rGraphic,const INetURLObject & rURL,const String &)465 SgaObjectAnim::SgaObjectAnim( const Graphic& rGraphic,
466 const INetURLObject& rURL,
467 const String& )
468 {
469 aURL = rURL;
470 bIsValid = CreateThumb( rGraphic );
471 }
472
473 // -----------------
474 // - SgaObjectINet -
475 // -----------------
476
SgaObjectINet()477 SgaObjectINet::SgaObjectINet()
478 {
479 }
480
481 // ------------------------------------------------------------------------
482
SgaObjectINet(const Graphic & rGraphic,const INetURLObject & rURL,const String & rFormatName)483 SgaObjectINet::SgaObjectINet( const Graphic& rGraphic, const INetURLObject& rURL, const String& rFormatName ) :
484 SgaObjectAnim ( rGraphic, rURL, rFormatName )
485 {
486 }
487
488 // -------------------
489 // - SgaObjectSvDraw -
490 // -------------------
491
SgaObjectSvDraw()492 SgaObjectSvDraw::SgaObjectSvDraw()
493 {
494 }
495
496 // ------------------------------------------------------------------------
497
SgaObjectSvDraw(const FmFormModel & rModel,const INetURLObject & rURL)498 SgaObjectSvDraw::SgaObjectSvDraw( const FmFormModel& rModel, const INetURLObject& rURL )
499 {
500 aURL = rURL;
501 bIsValid = CreateThumb( rModel );
502 }
503
504 // ------------------------------------------------------------------------
DBG_NAME(SvxGalleryDrawModel)505 DBG_NAME(SvxGalleryDrawModel)
506
507 SvxGalleryDrawModel::SvxGalleryDrawModel()
508 : mpFormModel( 0 )
509 {
510 DBG_CTOR(SvxGalleryDrawModel,NULL);
511
512 const String sFactoryURL(RTL_CONSTASCII_USTRINGPARAM("sdraw"));
513
514 mxDoc = SfxObjectShell::CreateObjectByFactoryName( sFactoryURL );
515
516 if( mxDoc.Is() )
517 {
518 mxDoc->DoInitNew(0);
519
520 uno::Reference< lang::XUnoTunnel > xTunnel( mxDoc->GetModel(), uno::UNO_QUERY );
521 if( xTunnel.is() )
522 {
523 mpFormModel = dynamic_cast< FmFormModel* >(
524 reinterpret_cast<SdrModel*>(xTunnel->getSomething(SdrModel::getUnoTunnelImplementationId())));
525 if( mpFormModel )
526 {
527 mpFormModel->InsertPage( mpFormModel->AllocPage( false ) );
528 }
529 }
530 }
531 }
532
533 // ------------------------------------------------------------------------
534
~SvxGalleryDrawModel()535 SvxGalleryDrawModel::~SvxGalleryDrawModel()
536 {
537 if( mxDoc.Is() )
538 mxDoc->DoClose();
539
540 DBG_DTOR(SvxGalleryDrawModel,NULL);
541 }
542
543 // ------------------------------------------------------------------------
544
SgaObjectSvDraw(SvStream & rIStm,const INetURLObject & rURL)545 SgaObjectSvDraw::SgaObjectSvDraw( SvStream& rIStm, const INetURLObject& rURL )
546 {
547 SvxGalleryDrawModel aModel;
548
549 if( aModel.GetModel() )
550 {
551 if( GallerySvDrawImport( rIStm, *aModel.GetModel() ) )
552 {
553 aURL = rURL;
554 bIsValid = CreateThumb( *aModel.GetModel() );
555 }
556 }
557 }
558
559 // ------------------------------------------------------------------------
560
CreateThumb(const FmFormModel & rModel)561 sal_Bool SgaObjectSvDraw::CreateThumb( const FmFormModel& rModel )
562 {
563 Graphic aGraphic;
564 ImageMap aImageMap;
565 sal_Bool bRet = sal_False;
566
567 if ( CreateIMapGraphic( rModel, aGraphic, aImageMap ) )
568 {
569 bRet = SgaObject::CreateThumb( aGraphic );
570 }
571 else
572 {
573 const FmFormPage* pPage = static_cast< const FmFormPage* >(rModel.GetPage(0));
574
575 if(pPage)
576 {
577 const Rectangle aObjRect(pPage->GetAllObjBoundRect());
578
579 if(aObjRect.GetWidth() && aObjRect.GetHeight())
580 {
581 VirtualDevice aVDev;
582 FmFormView aView(const_cast< FmFormModel* >(&rModel), &aVDev);
583
584 aView.ShowSdrPage(const_cast< FmFormPage* >(pPage));
585 aView.MarkAllObj();
586 aThumbBmp = aView.GetMarkedObjBitmapEx();
587
588 const Size aDiscreteSize(aThumbBmp.GetSizePixel());
589
590 if(aDiscreteSize.Width() && aDiscreteSize.Height())
591 {
592 sal_uInt32 nTargetSizeX(S_THUMB);
593 sal_uInt32 nTargetSizeY(S_THUMB);
594
595 if(aDiscreteSize.Width() > aDiscreteSize.Height())
596 {
597 nTargetSizeY = (aDiscreteSize.Height() * nTargetSizeX) / aDiscreteSize.Width();
598 }
599 else
600 {
601 nTargetSizeX = (aDiscreteSize.Width() * nTargetSizeY) / aDiscreteSize.Height();
602 }
603
604 if(!!aThumbBmp)
605 {
606 aThumbBmp.Scale(Size(nTargetSizeX, nTargetSizeY), BMP_SCALE_BESTQUALITY);
607 aThumbBmp.Convert(BMP_CONVERSION_8BIT_COLORS);
608 bRet = true;
609 }
610 }
611 }
612 }
613 }
614
615 return bRet;
616 }
617
618 // ------------------------------------------------------------------------
619
WriteData(SvStream & rOut,const String & rDestDir) const620 void SgaObjectSvDraw::WriteData( SvStream& rOut, const String& rDestDir ) const
621 {
622 SgaObject::WriteData( rOut, rDestDir );
623 rOut << ByteString( aTitle, RTL_TEXTENCODING_UTF8 );
624 }
625
626 // ------------------------------------------------------------------------
627
ReadData(SvStream & rIn,sal_uInt16 & rReadVersion)628 void SgaObjectSvDraw::ReadData( SvStream& rIn, sal_uInt16& rReadVersion )
629 {
630 SgaObject::ReadData( rIn, rReadVersion );
631
632 if( rReadVersion >= 5 )
633 {
634 ByteString aTmpStr;
635 rIn >> aTmpStr; aTitle = String( aTmpStr.GetBuffer(), RTL_TEXTENCODING_UTF8 );
636 }
637 }
638
639 // eof
640