Bump version to 6.4-15
[LibreOffice.git] / svx / source / gallery2 / galtheme.cxx
blobfa3ab3ea9167d3fea7e2795ded628fd70d362d9c
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 .
20 #include <config_features.h>
22 #include <sal/config.h>
23 #include <sal/log.hxx>
25 #include <algorithm>
27 #include <comphelper/fileformat.h>
28 #include <comphelper/processfactory.hxx>
29 #include <osl/file.hxx>
30 #include <osl/thread.hxx>
31 #include <tools/diagnose_ex.h>
32 #include <tools/urlobj.hxx>
33 #include <tools/vcompat.hxx>
34 #include <unotools/streamwrap.hxx>
35 #include <unotools/ucbstreamhelper.hxx>
36 #include <unotools/tempfile.hxx>
37 #include <ucbhelper/content.hxx>
38 #include <com/sun/star/ucb/ContentCreationException.hpp>
39 #include <sot/storage.hxx>
40 #include <sot/formats.hxx>
41 #include <sot/filelist.hxx>
42 #include <vcl/virdev.hxx>
43 #include <vcl/cvtgrf.hxx>
44 #include <svl/itempool.hxx>
45 #include <sfx2/docfile.hxx>
46 #include <avmedia/mediawindow.hxx>
47 #include <svx/svxids.hrc>
48 #include <svx/svdograf.hxx>
49 #include <svx/fmpage.hxx>
50 #include "codec.hxx"
51 #include <svx/unomodel.hxx>
52 #include <svx/fmmodel.hxx>
53 #include <svx/fmview.hxx>
54 #include <svx/galmisc.hxx>
55 #include <svx/galtheme.hxx>
56 #include <com/sun/star/sdbc/XResultSet.hpp>
57 #include <com/sun/star/ucb/XContentAccess.hpp>
58 #include <com/sun/star/io/XInputStream.hpp>
59 #include <galobj.hxx>
60 #include <svx/gallery1.hxx>
61 #include "gallerydrawmodel.hxx"
62 #include <memory>
64 using namespace ::com::sun::star;
67 GalleryTheme::GalleryTheme( Gallery* pGallery, GalleryThemeEntry* pThemeEntry )
68 : m_bDestDirRelative(false)
69 , pParent(pGallery)
70 , pThm(pThemeEntry)
71 , mnThemeLockCount(0)
72 , mnBroadcasterLockCount(0)
73 , nDragPos(0)
74 , bDragging(false)
75 , bAbortActualize(false)
77 ImplCreateSvDrawStorage();
80 GalleryTheme::~GalleryTheme()
82 ImplWrite();
84 for (auto & pEntry : aObjectList)
86 Broadcast( GalleryHint( GalleryHintType::CLOSE_OBJECT, GetName(), pEntry.get() ) );
87 pEntry.reset();
89 aObjectList.clear();
93 void GalleryTheme::ImplCreateSvDrawStorage()
95 try
97 aSvDrawStorageRef = new SotStorage( false, GetSdvURL().GetMainURL( INetURLObject::DecodeMechanism::NONE ), pThm->IsReadOnly() ? StreamMode::READ : StreamMode::STD_READWRITE );
98 // #i50423# ReadOnly may not been set though the file can't be written (because of security reasons)
99 if ( ( aSvDrawStorageRef->GetError() != ERRCODE_NONE ) && !pThm->IsReadOnly() )
100 aSvDrawStorageRef = new SotStorage( false, GetSdvURL().GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ );
102 catch (const css::ucb::ContentCreationException&)
104 TOOLS_WARN_EXCEPTION("svx", "failed to open: "
105 << GetSdvURL().GetMainURL(INetURLObject::DecodeMechanism::NONE)
106 << "due to");
110 bool GalleryTheme::ImplWriteSgaObject(const SgaObject& rObj, sal_uInt32 nPos, GalleryObject* pExistentEntry)
112 std::unique_ptr<SvStream> pOStm(::utl::UcbStreamHelper::CreateStream( GetSdgURL().GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::WRITE ));
113 bool bRet = false;
115 if( pOStm )
117 const sal_uInt32 nOffset = pOStm->Seek( STREAM_SEEK_TO_END );
119 rObj.WriteData( *pOStm, m_aDestDir );
121 if( !pOStm->GetError() )
123 GalleryObject* pEntry;
125 if( !pExistentEntry )
127 pEntry = new GalleryObject;
128 if ( nPos < aObjectList.size() )
130 aObjectList.emplace( aObjectList.begin() + nPos, pEntry );
132 else
133 aObjectList.emplace_back( pEntry );
135 else
136 pEntry = pExistentEntry;
138 pEntry->aURL = rObj.GetURL();
139 pEntry->nOffset = nOffset;
140 pEntry->eObjKind = rObj.GetObjKind();
141 bRet = true;
145 return bRet;
148 std::unique_ptr<SgaObject> GalleryTheme::ImplReadSgaObject( GalleryObject const * pEntry )
150 std::unique_ptr<SgaObject> pSgaObj;
152 if( pEntry )
154 std::unique_ptr<SvStream> pIStm(::utl::UcbStreamHelper::CreateStream( GetSdgURL().GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ ));
156 if( pIStm )
158 sal_uInt32 nInventor;
160 // Check to ensure that the file is a valid SGA file
161 pIStm->Seek( pEntry->nOffset );
162 pIStm->ReadUInt32( nInventor );
164 if( nInventor == COMPAT_FORMAT( 'S', 'G', 'A', '3' ) )
166 pIStm->Seek( pEntry->nOffset );
168 switch( pEntry->eObjKind )
170 case SgaObjKind::Bitmap: pSgaObj.reset(new SgaObjectBmp()); break;
171 case SgaObjKind::Animation: pSgaObj.reset(new SgaObjectAnim()); break;
172 case SgaObjKind::Inet: pSgaObj.reset(new SgaObjectINet()); break;
173 case SgaObjKind::SvDraw: pSgaObj.reset(new SgaObjectSvDraw()); break;
174 case SgaObjKind::Sound: pSgaObj.reset(new SgaObjectSound()); break;
176 default:
177 break;
180 if( pSgaObj )
182 ReadSgaObject( *pIStm, *pSgaObj );
183 pSgaObj->ImplUpdateURL( pEntry->aURL );
189 return pSgaObj;
192 void GalleryTheme::ImplWrite()
194 if( pThm->IsModified() )
196 INetURLObject aPathURL( GetThmURL() );
198 aPathURL.removeSegment();
199 aPathURL.removeFinalSlash();
201 DBG_ASSERT( aPathURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
203 if( FileExists( aPathURL ) || CreateDir( aPathURL ) )
205 #ifdef UNX
206 std::unique_ptr<SvStream> pOStm(::utl::UcbStreamHelper::CreateStream( GetThmURL().GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::WRITE | StreamMode::COPY_ON_SYMLINK | StreamMode::TRUNC ));
207 #else
208 std::unique_ptr<SvStream> pOStm(::utl::UcbStreamHelper::CreateStream( GetThmURL().GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::WRITE | StreamMode::TRUNC ));
209 #endif
211 if( pOStm )
213 WriteGalleryTheme( *pOStm, *this );
214 pOStm.reset();
217 ImplSetModified( false );
222 const GalleryObject* GalleryTheme::ImplGetGalleryObject( const INetURLObject& rURL )
224 for (auto const & i : aObjectList)
225 if ( i->aURL == rURL )
226 return i.get();
227 return nullptr;
230 INetURLObject GalleryTheme::ImplGetURL( const GalleryObject* pObject )
232 INetURLObject aURL;
234 if( pObject )
235 aURL = pObject->aURL;
237 return aURL;
240 INetURLObject GalleryTheme::ImplCreateUniqueURL( SgaObjKind eObjKind, ConvertDataFormat nFormat )
242 INetURLObject aDir( GetParent()->GetUserURL() );
243 INetURLObject aInfoFileURL( GetParent()->GetUserURL() );
244 INetURLObject aNewURL;
245 sal_uInt32 nNextNumber = 1999;
246 sal_Char const* pExt = nullptr;
247 bool bExists;
249 aDir.Append( "dragdrop" );
250 CreateDir( aDir );
252 aInfoFileURL.Append( "sdddndx1" );
254 // read next possible number
255 if( FileExists( aInfoFileURL ) )
257 std::unique_ptr<SvStream> pIStm(::utl::UcbStreamHelper::CreateStream( aInfoFileURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ ));
259 if( pIStm )
261 pIStm->ReadUInt32( nNextNumber );
265 // create extension
266 if( nFormat != ConvertDataFormat::Unknown )
268 switch( nFormat )
270 case ConvertDataFormat::BMP: pExt = ".bmp"; break;
271 case ConvertDataFormat::GIF: pExt = ".gif"; break;
272 case ConvertDataFormat::JPG: pExt = ".jpg"; break;
273 case ConvertDataFormat::MET: pExt = ".met"; break;
274 case ConvertDataFormat::PCT: pExt = ".pct"; break;
275 case ConvertDataFormat::PNG: pExt = ".png"; break;
276 case ConvertDataFormat::SVM: pExt = ".svm"; break;
277 case ConvertDataFormat::TIF: pExt = ".tif"; break;
278 case ConvertDataFormat::WMF: pExt = ".wmf"; break;
279 case ConvertDataFormat::EMF: pExt = ".emf"; break;
281 default:
282 pExt = ".grf";
283 break;
289 // get URL
290 if( SgaObjKind::SvDraw == eObjKind )
292 OUString aFileName( "gallery/svdraw/dd" );
293 aNewURL = INetURLObject( aFileName += OUString::number( ++nNextNumber % 99999999 ), INetProtocol::PrivSoffice );
295 bExists = false;
297 for (auto const & p : aObjectList)
298 if ( p->aURL == aNewURL )
300 bExists = true;
301 break;
304 else
306 OUString aFileName = "dd" + OUString::number( ++nNextNumber % 999999 );
308 if (pExt)
309 aFileName += OUString( pExt, strlen(pExt), RTL_TEXTENCODING_ASCII_US );
311 aNewURL = aDir;
312 aNewURL.Append( aFileName );
314 bExists = FileExists( aNewURL );
317 while( bExists );
319 // write updated number
320 std::unique_ptr<SvStream> pOStm(::utl::UcbStreamHelper::CreateStream( aInfoFileURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::WRITE ));
322 if( pOStm )
324 pOStm->WriteUInt32( nNextNumber );
327 return aNewURL;
330 void GalleryTheme::ImplBroadcast(sal_uInt32 nUpdatePos)
332 if( !IsBroadcasterLocked() )
334 if( GetObjectCount() && ( nUpdatePos >= GetObjectCount() ) )
335 nUpdatePos = GetObjectCount() - 1;
337 Broadcast( GalleryHint( GalleryHintType::THEME_UPDATEVIEW, GetName(), reinterpret_cast<void*>(nUpdatePos) ) );
341 bool GalleryTheme::UnlockTheme()
343 DBG_ASSERT( mnThemeLockCount, "Theme is not locked" );
345 bool bRet = false;
347 if( mnThemeLockCount )
349 --mnThemeLockCount;
350 bRet = true;
353 return bRet;
356 void GalleryTheme::UnlockBroadcaster()
358 DBG_ASSERT( mnBroadcasterLockCount, "Broadcaster is not locked" );
360 if( mnBroadcasterLockCount && !--mnBroadcasterLockCount )
361 ImplBroadcast( 0 );
364 bool GalleryTheme::InsertObject(const SgaObject& rObj, sal_uInt32 nInsertPos)
366 if (!rObj.IsValid())
367 return false;
369 GalleryObject* pFoundEntry = nullptr;
370 sal_uInt32 iFoundPos = 0;
371 for (sal_uInt32 n = aObjectList.size(); iFoundPos < n; ++iFoundPos)
373 if (aObjectList[ iFoundPos ]->aURL == rObj.GetURL())
375 pFoundEntry = aObjectList[ iFoundPos ].get();
376 break;
380 if (pFoundEntry)
382 GalleryObject aNewEntry;
384 // update title of new object if necessary
385 if (rObj.GetTitle().isEmpty())
387 std::unique_ptr<SgaObject> pOldObj(ImplReadSgaObject(pFoundEntry));
389 if (pOldObj)
391 const_cast<SgaObject&>(rObj).SetTitle( pOldObj->GetTitle() );
394 else if (rObj.GetTitle() == "__<empty>__")
395 const_cast<SgaObject&>(rObj).SetTitle("");
397 ImplWriteSgaObject(rObj, nInsertPos, &aNewEntry);
398 pFoundEntry->nOffset = aNewEntry.nOffset;
400 else
401 ImplWriteSgaObject(rObj, nInsertPos, nullptr);
403 ImplSetModified(true);
404 ImplBroadcast(pFoundEntry? iFoundPos: nInsertPos);
406 return true;
409 std::unique_ptr<SgaObject> GalleryTheme::AcquireObject(sal_uInt32 nPos)
411 return ImplReadSgaObject(ImplGetGalleryObject(nPos));
414 void GalleryTheme::GetPreviewBitmapExAndStrings(sal_uInt32 nPos, BitmapEx& rBitmapEx, Size& rSize, OUString& rTitle, OUString& rPath) const
416 const GalleryObject* pGalleryObject = aObjectList[ nPos ].get();
418 rBitmapEx = pGalleryObject->maPreviewBitmapEx;
419 rSize = pGalleryObject->maPreparedSize;
420 rTitle = pGalleryObject->maTitle;
421 rPath = pGalleryObject->maPath;
424 void GalleryTheme::SetPreviewBitmapExAndStrings(sal_uInt32 nPos, const BitmapEx& rBitmapEx, const Size& rSize, const OUString& rTitle, const OUString& rPath)
426 GalleryObject* pGalleryObject = aObjectList[ nPos ].get();
428 pGalleryObject->maPreviewBitmapEx = rBitmapEx;
429 pGalleryObject->maPreparedSize = rSize;
430 pGalleryObject->maTitle = rTitle;
431 pGalleryObject->maPath = rPath;
434 void GalleryTheme::RemoveObject(sal_uInt32 nPos)
436 auto it = aObjectList.begin() + nPos;
437 std::unique_ptr<GalleryObject> pEntry = std::move(*it);
438 aObjectList.erase( it );
440 if( aObjectList.empty() )
441 KillFile( GetSdgURL() );
443 if( SgaObjKind::SvDraw == pEntry->eObjKind )
444 aSvDrawStorageRef->Remove( pEntry->aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
446 Broadcast( GalleryHint( GalleryHintType::CLOSE_OBJECT, GetName(), pEntry.get() ) );
447 pEntry.reset();
449 ImplSetModified( true );
450 ImplBroadcast( nPos );
453 bool GalleryTheme::ChangeObjectPos(sal_uInt32 nOldPos, sal_uInt32 nNewPos)
455 if (nOldPos == nNewPos || nOldPos >= aObjectList.size())
456 return false;
458 std::unique_ptr<GalleryObject> pEntry = std::move(aObjectList[nOldPos]);
460 aObjectList.insert(aObjectList.begin() + nNewPos, std::move(pEntry));
462 if (nNewPos < nOldPos)
463 nOldPos++;
465 auto it = aObjectList.begin() + nOldPos;
466 aObjectList.erase(it);
468 ImplSetModified(true);
469 ImplBroadcast((nNewPos < nOldPos)? nNewPos: (nNewPos - 1));
471 return true;
474 void GalleryTheme::Actualize( const Link<const INetURLObject&, void>& rActualizeLink, GalleryProgress* pProgress )
476 if( IsReadOnly() )
477 return;
479 Graphic aGraphic;
480 OUString aFormat;
481 const sal_uInt32 nCount = aObjectList.size();
483 LockBroadcaster();
484 bAbortActualize = false;
486 // reset delete flag
487 for (sal_uInt32 i = 0; i < nCount; i++)
488 aObjectList[ i ]->mbDelete = false;
490 for (sal_uInt32 i = 0; ( i < nCount ) && !bAbortActualize; i++)
492 if( pProgress )
493 pProgress->Update( i, nCount - 1 );
495 GalleryObject* pEntry = aObjectList[ i ].get();
497 const INetURLObject aURL( pEntry->aURL );
499 rActualizeLink.Call( aURL );
501 // SvDraw objects will be updated later
502 if( pEntry->eObjKind != SgaObjKind::SvDraw )
504 // Still a function should be implemented,
505 // which assigns files to the relevant entry.
506 // insert graphics as graphic objects into the gallery
507 if( pEntry->eObjKind == SgaObjKind::Sound )
509 SgaObjectSound aObjSound( aURL );
510 if( !InsertObject( aObjSound ) )
511 pEntry->mbDelete = true;
513 else
515 aGraphic.Clear();
517 if ( GalleryGraphicImport( aURL, aGraphic, aFormat ) != GalleryGraphicImportRet::IMPORT_NONE )
519 std::unique_ptr<SgaObject> pNewObj;
521 if ( SgaObjKind::Inet == pEntry->eObjKind )
522 pNewObj.reset(new SgaObjectINet( aGraphic, aURL ));
523 else if ( aGraphic.IsAnimated() )
524 pNewObj.reset(new SgaObjectAnim( aGraphic, aURL ));
525 else
526 pNewObj.reset(new SgaObjectBmp( aGraphic, aURL ));
528 if( !InsertObject( *pNewObj ) )
529 pEntry->mbDelete = true;
531 else
532 pEntry->mbDelete = true; // set delete flag
535 else
537 if ( aSvDrawStorageRef.is() )
539 const OUString aStmName( GetSvDrawStreamNameFromURL( pEntry->aURL ) );
540 tools::SvRef<SotStorageStream> pIStm = aSvDrawStorageRef->OpenSotStream( aStmName, StreamMode::READ );
542 if( pIStm.is() && !pIStm->GetError() )
544 pIStm->SetBufferSize( 16384 );
546 SgaObjectSvDraw aNewObj( *pIStm, pEntry->aURL );
548 if( !InsertObject( aNewObj ) )
549 pEntry->mbDelete = true;
551 pIStm->SetBufferSize( 0 );
557 // remove all entries with set flag
558 for ( auto it = aObjectList.begin(); it != aObjectList.end(); /* increment is in the body of loop */)
560 if( (*it)->mbDelete )
562 Broadcast( GalleryHint( GalleryHintType::CLOSE_OBJECT, GetName(), it->get() ) );
563 it = aObjectList.erase( it );
565 else
566 ++it;
569 // update theme
570 ::utl::TempFile aTmp;
571 INetURLObject aInURL( GetSdgURL() );
572 INetURLObject aTmpURL( aTmp.GetURL() );
574 DBG_ASSERT( aInURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
575 DBG_ASSERT( aTmpURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
577 std::unique_ptr<SvStream> pIStm(::utl::UcbStreamHelper::CreateStream( aInURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ ));
578 std::unique_ptr<SvStream> pTmpStm(::utl::UcbStreamHelper::CreateStream( aTmpURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::WRITE | StreamMode::TRUNC ));
580 if( pIStm && pTmpStm )
582 for (const auto & i : aObjectList)
584 GalleryObject* pEntry = i.get();
585 std::unique_ptr<SgaObject> pObj;
587 switch( pEntry->eObjKind )
589 case SgaObjKind::Bitmap: pObj.reset(new SgaObjectBmp()); break;
590 case SgaObjKind::Animation: pObj.reset(new SgaObjectAnim()); break;
591 case SgaObjKind::Inet: pObj.reset(new SgaObjectINet()); break;
592 case SgaObjKind::SvDraw: pObj.reset(new SgaObjectSvDraw()); break;
593 case SgaObjKind::Sound: pObj.reset(new SgaObjectSound()); break;
595 default:
596 break;
599 if( pObj )
601 pIStm->Seek( pEntry->nOffset );
602 ReadSgaObject( *pIStm, *pObj);
603 pEntry->nOffset = pTmpStm->Tell();
604 WriteSgaObject( *pTmpStm, *pObj );
608 else
610 OSL_FAIL( "File(s) could not be opened" );
613 pIStm.reset();
614 pTmpStm.reset();
616 CopyFile( aTmpURL, aInURL );
617 KillFile( aTmpURL );
619 ErrCode nStorErr = ERRCODE_NONE;
623 tools::SvRef<SotStorage> aTempStorageRef( new SotStorage( false, aTmpURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::STD_READWRITE ) );
624 aSvDrawStorageRef->CopyTo( aTempStorageRef.get() );
625 nStorErr = aSvDrawStorageRef->GetError();
627 catch (const css::ucb::ContentCreationException&)
629 TOOLS_WARN_EXCEPTION("svx", "failed to open: "
630 << aTmpURL.GetMainURL(INetURLObject::DecodeMechanism::NONE)
631 << "due to");
632 nStorErr = ERRCODE_IO_GENERAL;
635 if( nStorErr == ERRCODE_NONE )
637 aSvDrawStorageRef.clear();
638 CopyFile( aTmpURL, GetSdvURL() );
639 ImplCreateSvDrawStorage();
642 KillFile( aTmpURL );
643 ImplSetModified( true );
644 ImplWrite();
645 UnlockBroadcaster();
648 GalleryThemeEntry* GalleryTheme::CreateThemeEntry( const INetURLObject& rURL, bool bReadOnly )
650 DBG_ASSERT( rURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
652 GalleryThemeEntry* pRet = nullptr;
654 if( FileExists( rURL ) )
656 std::unique_ptr<SvStream> pIStm(::utl::UcbStreamHelper::CreateStream( rURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ ));
658 if( pIStm )
660 OUString aThemeName;
661 sal_uInt16 nVersion;
663 pIStm->ReadUInt16( nVersion );
665 if( nVersion <= 0x00ff )
667 bool bThemeNameFromResource = false;
668 sal_uInt32 nThemeId = 0;
670 OString aTmpStr = read_uInt16_lenPrefixed_uInt8s_ToOString(*pIStm);
671 aThemeName = OStringToOUString(aTmpStr, RTL_TEXTENCODING_UTF8);
673 // execute a character conversion
674 if( nVersion >= 0x0004 )
676 sal_uInt32 nCount;
677 sal_uInt16 nTemp16;
679 pIStm->ReadUInt32( nCount ).ReadUInt16( nTemp16 );
680 pIStm->Seek( STREAM_SEEK_TO_END );
682 // check whether there is a newer version;
683 // therefore jump back by 520Bytes (8 bytes ID + 512Bytes reserve buffer)
684 // if this is at all possible.
685 if( pIStm->Tell() >= 520 )
687 sal_uInt32 nId1, nId2;
689 pIStm->SeekRel( -520 );
690 pIStm->ReadUInt32( nId1 ).ReadUInt32( nId2 );
692 if( nId1 == COMPAT_FORMAT( 'G', 'A', 'L', 'R' ) &&
693 nId2 == COMPAT_FORMAT( 'E', 'S', 'R', 'V' ) )
695 std::unique_ptr<VersionCompat> pCompat(new VersionCompat( *pIStm, StreamMode::READ ));
697 pIStm->ReadUInt32( nThemeId );
699 if( pCompat->GetVersion() >= 2 )
701 pIStm->ReadCharAsBool( bThemeNameFromResource );
707 pRet = new GalleryThemeEntry( false, rURL, aThemeName,
708 bReadOnly, false, nThemeId,
709 bThemeNameFromResource );
714 return pRet;
717 bool GalleryTheme::GetThumb(sal_uInt32 nPos, BitmapEx& rBmp)
719 std::unique_ptr<SgaObject> pObj = AcquireObject( nPos );
720 bool bRet = false;
722 if( pObj )
724 rBmp = pObj->GetThumbBmp();
725 bRet = true;
728 return bRet;
731 bool GalleryTheme::GetGraphic(sal_uInt32 nPos, Graphic& rGraphic)
733 const GalleryObject* pObject = ImplGetGalleryObject( nPos );
734 bool bRet = false;
736 if( pObject )
738 const INetURLObject aURL( ImplGetURL( pObject ) );
740 switch( pObject->eObjKind )
742 case SgaObjKind::Bitmap:
743 case SgaObjKind::Animation:
744 case SgaObjKind::Inet:
746 OUString aFilterDummy;
747 bRet = ( GalleryGraphicImport( aURL, rGraphic, aFilterDummy ) != GalleryGraphicImportRet::IMPORT_NONE );
749 break;
751 case SgaObjKind::SvDraw:
753 SvxGalleryDrawModel aModel;
755 if( aModel.GetModel() )
757 if( GetModel( nPos, *aModel.GetModel() ) )
759 ImageMap aIMap;
761 if( CreateIMapGraphic( *aModel.GetModel(), rGraphic, aIMap ) )
762 bRet = true;
763 else
765 ScopedVclPtrInstance< VirtualDevice > pVDev;
766 pVDev->SetMapMode( MapMode( MapUnit::Map100thMM ) );
767 FmFormView aView(*aModel.GetModel(), pVDev);
769 aView.hideMarkHandles();
770 aView.ShowSdrPage(aView.GetModel()->GetPage(0));
771 aView.MarkAll();
772 rGraphic = aView.GetAllMarkedGraphic();
773 bRet = true;
778 break;
780 case SgaObjKind::Sound:
782 std::unique_ptr<SgaObject> pObj = AcquireObject( nPos );
784 if( pObj )
786 rGraphic = pObj->GetThumbBmp();
787 //Bitmap aBmp( pObj->GetThumbBmp() );
788 //aBmp.Replace( COL_LIGHTMAGENTA, COL_WHITE );
789 //rGraphic = aBmp;
790 bRet = true;
793 break;
795 default:
796 break;
800 return bRet;
803 bool GalleryTheme::InsertGraphic(const Graphic& rGraphic, sal_uInt32 nInsertPos)
805 bool bRet = false;
807 if( rGraphic.GetType() != GraphicType::NONE )
809 ConvertDataFormat nExportFormat = ConvertDataFormat::Unknown;
810 const GfxLink aGfxLink( rGraphic.GetGfxLink() );
812 if( aGfxLink.GetDataSize() )
814 switch( aGfxLink.GetType() )
816 case GfxLinkType::EpsBuffer: nExportFormat = ConvertDataFormat::SVM; break;
817 case GfxLinkType::NativeGif: nExportFormat = ConvertDataFormat::GIF; break;
819 // #i15508# added BMP type
820 // could not find/trigger a call to this, but should do no harm
821 case GfxLinkType::NativeBmp: nExportFormat = ConvertDataFormat::BMP; break;
823 case GfxLinkType::NativeJpg: nExportFormat = ConvertDataFormat::JPG; break;
824 case GfxLinkType::NativePng: nExportFormat = ConvertDataFormat::PNG; break;
825 case GfxLinkType::NativeTif: nExportFormat = ConvertDataFormat::TIF; break;
826 case GfxLinkType::NativeWmf: nExportFormat = ConvertDataFormat::WMF; break;
827 case GfxLinkType::NativeMet: nExportFormat = ConvertDataFormat::MET; break;
828 case GfxLinkType::NativePct: nExportFormat = ConvertDataFormat::PCT; break;
829 case GfxLinkType::NativeSvg: nExportFormat = ConvertDataFormat::SVG; break;
830 default:
831 break;
834 else
836 if( rGraphic.GetType() == GraphicType::Bitmap )
838 if( rGraphic.IsAnimated() )
839 nExportFormat = ConvertDataFormat::GIF;
840 else
841 nExportFormat = ConvertDataFormat::PNG;
843 else
844 nExportFormat = ConvertDataFormat::SVM;
847 const INetURLObject aURL( ImplCreateUniqueURL( SgaObjKind::Bitmap, nExportFormat ) );
848 std::unique_ptr<SvStream> pOStm(::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::WRITE | StreamMode::TRUNC ));
850 if( pOStm )
852 pOStm->SetVersion( SOFFICE_FILEFORMAT_50 );
854 if( ConvertDataFormat::SVM == nExportFormat )
856 GDIMetaFile aMtf( rGraphic.GetGDIMetaFile() );
858 aMtf.Write( *pOStm );
859 bRet = ( pOStm->GetError() == ERRCODE_NONE );
861 else
863 if( aGfxLink.GetDataSize() && aGfxLink.GetData() )
865 pOStm->WriteBytes(aGfxLink.GetData(), aGfxLink.GetDataSize());
866 bRet = ( pOStm->GetError() == ERRCODE_NONE );
868 else
869 bRet = ( GraphicConverter::Export( *pOStm, rGraphic, nExportFormat ) == ERRCODE_NONE );
872 pOStm.reset();
875 if( bRet )
877 const SgaObjectBmp aObjBmp( aURL );
878 InsertObject( aObjBmp, nInsertPos );
882 return bRet;
885 bool GalleryTheme::GetModel(sal_uInt32 nPos, SdrModel& rModel)
887 const GalleryObject* pObject = ImplGetGalleryObject( nPos );
888 bool bRet = false;
890 if( pObject && ( SgaObjKind::SvDraw == pObject->eObjKind ) )
892 const INetURLObject aURL( ImplGetURL( pObject ) );
893 tools::SvRef<SotStorage> xStor( GetSvDrawStorage() );
895 if( xStor.is() )
897 const OUString aStmName( GetSvDrawStreamNameFromURL( aURL ) );
898 tools::SvRef<SotStorageStream> xIStm( xStor->OpenSotStream( aStmName, StreamMode::READ ) );
900 if( xIStm.is() && !xIStm->GetError() )
902 xIStm->SetBufferSize( STREAMBUF_SIZE );
903 bRet = GallerySvDrawImport( *xIStm, rModel );
904 xIStm->SetBufferSize( 0 );
909 return bRet;
912 bool GalleryTheme::InsertModel(const FmFormModel& rModel, sal_uInt32 nInsertPos)
914 INetURLObject aURL( ImplCreateUniqueURL( SgaObjKind::SvDraw ) );
915 tools::SvRef<SotStorage> xStor( GetSvDrawStorage() );
916 bool bRet = false;
918 if( xStor.is() )
920 const OUString aStmName( GetSvDrawStreamNameFromURL( aURL ) );
921 tools::SvRef<SotStorageStream> xOStm( xStor->OpenSotStream( aStmName, StreamMode::WRITE | StreamMode::TRUNC ) );
923 if( xOStm.is() && !xOStm->GetError() )
925 SvMemoryStream aMemStm( 65535, 65535 );
926 FmFormModel* pFormModel = const_cast<FmFormModel*>(&rModel);
928 pFormModel->BurnInStyleSheetAttributes();
931 uno::Reference< io::XOutputStream > xDocOut( new utl::OOutputStreamWrapper( aMemStm ) );
933 if (xDocOut.is())
934 (void)SvxDrawingLayerExport( pFormModel, xDocOut );
937 aMemStm.Seek( 0 );
939 xOStm->SetBufferSize( 16348 );
940 GalleryCodec aCodec( *xOStm );
941 aCodec.Write( aMemStm );
943 if( !xOStm->GetError() )
945 SgaObjectSvDraw aObjSvDraw( rModel, aURL );
946 bRet = InsertObject( aObjSvDraw, nInsertPos );
949 xOStm->SetBufferSize( 0 );
950 xOStm->Commit();
954 return bRet;
957 bool GalleryTheme::GetModelStream(sal_uInt32 nPos, tools::SvRef<SotStorageStream> const & rxModelStream)
959 const GalleryObject* pObject = ImplGetGalleryObject( nPos );
960 bool bRet = false;
962 if( pObject && ( SgaObjKind::SvDraw == pObject->eObjKind ) )
964 const INetURLObject aURL( ImplGetURL( pObject ) );
965 tools::SvRef<SotStorage> xStor( GetSvDrawStorage() );
967 if( xStor.is() )
969 const OUString aStmName( GetSvDrawStreamNameFromURL( aURL ) );
970 tools::SvRef<SotStorageStream> xIStm( xStor->OpenSotStream( aStmName, StreamMode::READ ) );
972 if( xIStm.is() && !xIStm->GetError() )
974 sal_uInt32 nVersion = 0;
976 xIStm->SetBufferSize( 16348 );
978 if( GalleryCodec::IsCoded( *xIStm, nVersion ) )
980 SvxGalleryDrawModel aModel;
982 if( aModel.GetModel() )
984 if( GallerySvDrawImport( *xIStm, *aModel.GetModel() ) )
986 aModel.GetModel()->BurnInStyleSheetAttributes();
989 uno::Reference< io::XOutputStream > xDocOut( new utl::OOutputStreamWrapper( *rxModelStream ) );
991 if( SvxDrawingLayerExport( aModel.GetModel(), xDocOut ) )
992 rxModelStream->Commit();
996 bRet = ( rxModelStream->GetError() == ERRCODE_NONE );
1000 xIStm->SetBufferSize( 0 );
1005 return bRet;
1008 bool GalleryTheme::InsertModelStream(const tools::SvRef<SotStorageStream>& rxModelStream, sal_uInt32 nInsertPos)
1010 INetURLObject aURL( ImplCreateUniqueURL( SgaObjKind::SvDraw ) );
1011 tools::SvRef<SotStorage> xStor( GetSvDrawStorage() );
1012 bool bRet = false;
1014 if( xStor.is() )
1016 const OUString aStmName( GetSvDrawStreamNameFromURL( aURL ) );
1017 tools::SvRef<SotStorageStream> xOStm( xStor->OpenSotStream( aStmName, StreamMode::WRITE | StreamMode::TRUNC ) );
1019 if( xOStm.is() && !xOStm->GetError() )
1021 GalleryCodec aCodec( *xOStm );
1022 SvMemoryStream aMemStm( 65535, 65535 );
1024 xOStm->SetBufferSize( 16348 );
1025 aCodec.Write( *rxModelStream );
1027 if( !xOStm->GetError() )
1029 xOStm->Seek( 0 );
1030 SgaObjectSvDraw aObjSvDraw( *xOStm, aURL );
1031 bRet = InsertObject( aObjSvDraw, nInsertPos );
1034 xOStm->SetBufferSize( 0 );
1035 xOStm->Commit();
1039 return bRet;
1042 bool GalleryTheme::GetURL(sal_uInt32 nPos, INetURLObject& rURL)
1044 const GalleryObject* pObject = ImplGetGalleryObject( nPos );
1045 bool bRet = false;
1047 if( pObject )
1049 rURL = ImplGetURL( pObject );
1050 bRet = true;
1053 return bRet;
1056 bool GalleryTheme::InsertURL(const INetURLObject& rURL, sal_uInt32 nInsertPos)
1058 Graphic aGraphic;
1059 OUString aFormat;
1060 std::unique_ptr<SgaObject> pNewObj;
1061 const GalleryGraphicImportRet nImportRet = GalleryGraphicImport( rURL, aGraphic, aFormat );
1062 bool bRet = false;
1064 if( nImportRet != GalleryGraphicImportRet::IMPORT_NONE )
1066 if ( aGraphic.IsAnimated() )
1067 pNewObj.reset(new SgaObjectAnim( aGraphic, rURL ));
1068 else
1069 pNewObj.reset(new SgaObjectBmp( aGraphic, rURL ));
1071 #if HAVE_FEATURE_AVMEDIA
1072 else if( ::avmedia::MediaWindow::isMediaURL( rURL.GetMainURL( INetURLObject::DecodeMechanism::Unambiguous ), ""/*TODO?*/ ) )
1073 pNewObj.reset(new SgaObjectSound( rURL ));
1074 #endif
1075 if( pNewObj && InsertObject( *pNewObj, nInsertPos ) )
1076 bRet = true;
1078 return bRet;
1081 bool GalleryTheme::InsertFileOrDirURL(const INetURLObject& rFileOrDirURL, sal_uInt32 nInsertPos)
1083 INetURLObject aURL;
1084 ::std::vector< INetURLObject > aURLVector;
1085 bool bRet = false;
1089 ::ucbhelper::Content aCnt( rFileOrDirURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), uno::Reference< ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
1090 bool bFolder = false;
1092 aCnt.getPropertyValue("IsFolder") >>= bFolder;
1094 if( bFolder )
1096 uno::Sequence<OUString> aProps { "Url" };
1097 uno::Reference< sdbc::XResultSet > xResultSet( aCnt.createCursor( aProps, ::ucbhelper::INCLUDE_DOCUMENTS_ONLY ) );
1098 uno::Reference< ucb::XContentAccess > xContentAccess( xResultSet, uno::UNO_QUERY );
1099 if( xContentAccess.is() )
1101 while( xResultSet->next() )
1103 aURL.SetSmartURL( xContentAccess->queryContentIdentifierString() );
1104 aURLVector.push_back( aURL );
1108 else
1109 aURLVector.push_back( rFileOrDirURL );
1111 catch( const ucb::ContentCreationException& )
1114 catch( const uno::RuntimeException& )
1117 catch( const uno::Exception& )
1121 for( const auto& rURL : aURLVector )
1122 bRet = bRet || InsertURL( rURL, nInsertPos );
1124 return bRet;
1127 bool GalleryTheme::InsertTransferable(const uno::Reference< datatransfer::XTransferable >& rxTransferable, sal_uInt32 nInsertPos)
1129 bool bRet = false;
1131 if( rxTransferable.is() )
1133 TransferableDataHelper aDataHelper( rxTransferable );
1134 std::unique_ptr<Graphic> pGraphic;
1136 if( aDataHelper.HasFormat( SotClipboardFormatId::DRAWING ) )
1138 tools::SvRef<SotStorageStream> xModelStm;
1140 if( aDataHelper.GetSotStorageStream( SotClipboardFormatId::DRAWING, xModelStm ) )
1141 bRet = InsertModelStream( xModelStm, nInsertPos );
1143 else if( aDataHelper.HasFormat( SotClipboardFormatId::FILE_LIST ) ||
1144 aDataHelper.HasFormat( SotClipboardFormatId::SIMPLE_FILE ) )
1146 FileList aFileList;
1148 if( aDataHelper.HasFormat( SotClipboardFormatId::FILE_LIST ) )
1149 aDataHelper.GetFileList( SotClipboardFormatId::FILE_LIST, aFileList );
1150 else
1152 OUString aFile;
1153 if (aDataHelper.GetString(SotClipboardFormatId::SIMPLE_FILE, aFile) && !aFile.isEmpty())
1154 aFileList.AppendFile( aFile );
1157 for( sal_uInt32 i = 0, nCount = aFileList.Count(); i < nCount; ++i )
1159 const OUString aFile( aFileList.GetFile( i ) );
1160 INetURLObject aURL( aFile );
1162 if( aURL.GetProtocol() == INetProtocol::NotValid )
1164 OUString aLocalURL;
1166 if( osl::FileBase::getFileURLFromSystemPath( aFile, aLocalURL ) == osl::FileBase::E_None )
1167 aURL = INetURLObject( aLocalURL );
1170 if( aURL.GetProtocol() != INetProtocol::NotValid )
1171 bRet = InsertFileOrDirURL( aURL, nInsertPos );
1174 else
1176 Graphic aGraphic;
1177 SotClipboardFormatId nFormat = SotClipboardFormatId::NONE;
1179 if( aDataHelper.HasFormat( SotClipboardFormatId::SVXB ) )
1180 nFormat = SotClipboardFormatId::SVXB;
1181 else if( aDataHelper.HasFormat( SotClipboardFormatId::GDIMETAFILE ) )
1182 nFormat = SotClipboardFormatId::GDIMETAFILE;
1183 else if( aDataHelper.HasFormat( SotClipboardFormatId::BITMAP ) )
1184 nFormat = SotClipboardFormatId::BITMAP;
1186 if( nFormat != SotClipboardFormatId::NONE && aDataHelper.GetGraphic( nFormat, aGraphic ) )
1187 pGraphic.reset(new Graphic( aGraphic ));
1190 if( pGraphic )
1192 bRet = false;
1194 if( aDataHelper.HasFormat( SotClipboardFormatId::SVIM ) )
1197 ImageMap aImageMap;
1199 // according to KA we don't need a BaseURL here
1200 if( aDataHelper.GetImageMap( SotClipboardFormatId::SVIM, aImageMap ) )
1202 SvxGalleryDrawModel aModel;
1204 if( aModel.GetModel() )
1206 SdrPage* pPage = aModel.GetModel()->GetPage(0);
1207 SdrGrafObj* pGrafObj = new SdrGrafObj(*aModel.GetModel(), *pGraphic );
1209 pGrafObj->AppendUserData( std::unique_ptr<SdrObjUserData>(new SgaIMapInfo( aImageMap )) );
1210 pPage->InsertObject( pGrafObj );
1211 bRet = InsertModel( *aModel.GetModel(), nInsertPos );
1216 if( !bRet )
1217 bRet = InsertGraphic( *pGraphic, nInsertPos );
1221 return bRet;
1224 void GalleryTheme::CopyToClipboard(vcl::Window* pWindow, sal_uInt32 nPos)
1226 GalleryTransferable* pTransferable = new GalleryTransferable( this, nPos, false );
1227 pTransferable->CopyToClipboard( pWindow );
1230 void GalleryTheme::StartDrag(vcl::Window* pWindow, sal_uInt32 nPos)
1232 GalleryTransferable* pTransferable = new GalleryTransferable( this, nPos, true );
1233 pTransferable->StartDrag( pWindow, DND_ACTION_COPY | DND_ACTION_LINK );
1236 SvStream& GalleryTheme::WriteData( SvStream& rOStm ) const
1238 const INetURLObject aRelURL1( GetParent()->GetRelativeURL() );
1239 const INetURLObject aRelURL2( GetParent()->GetUserURL() );
1240 sal_uInt32 nCount = GetObjectCount();
1241 bool bRel;
1243 rOStm.WriteUInt16( 0x0004 );
1244 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStm, pThm->GetThemeName(), RTL_TEXTENCODING_UTF8);
1245 rOStm.WriteUInt32( nCount ).WriteUInt16( osl_getThreadTextEncoding() );
1247 for( sal_uInt32 i = 0; i < nCount; i++ )
1249 const GalleryObject* pObj = ImplGetGalleryObject( i );
1250 OUString aPath;
1252 if( SgaObjKind::SvDraw == pObj->eObjKind )
1254 aPath = GetSvDrawStreamNameFromURL( pObj->aURL );
1255 bRel = false;
1257 else
1259 aPath = pObj->aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1260 aPath = aPath.copy( 0, std::min(aRelURL1.GetMainURL( INetURLObject::DecodeMechanism::NONE ).getLength(), aPath.getLength()) );
1261 bRel = aPath == aRelURL1.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1263 if( bRel && ( pObj->aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ).getLength() > ( aRelURL1.GetMainURL( INetURLObject::DecodeMechanism::NONE ).getLength() + 1 ) ) )
1265 aPath = pObj->aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1266 aPath = aPath.copy( std::min(aRelURL1.GetMainURL( INetURLObject::DecodeMechanism::NONE ).getLength(), aPath.getLength()) );
1268 else
1270 aPath = pObj->aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1271 aPath = aPath.copy( 0, std::min(aRelURL2.GetMainURL( INetURLObject::DecodeMechanism::NONE ).getLength(), aPath.getLength()) );
1272 bRel = aPath == aRelURL2.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1274 if( bRel && ( pObj->aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ).getLength() > ( aRelURL2.GetMainURL( INetURLObject::DecodeMechanism::NONE ).getLength() + 1 ) ) )
1276 aPath = pObj->aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1277 aPath = aPath.copy( std::min(aRelURL2.GetMainURL( INetURLObject::DecodeMechanism::NONE ).getLength(), aPath.getLength()) );
1279 else
1280 aPath = pObj->aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1284 if ( !m_aDestDir.isEmpty() )
1286 bool aFound = aPath.indexOf(m_aDestDir) != -1;
1287 aPath = aPath.replaceFirst(m_aDestDir, "");
1288 if ( aFound )
1289 bRel = m_bDestDirRelative;
1290 else
1291 SAL_WARN( "svx", "failed to replace destdir of '"
1292 << m_aDestDir << "' in '" << aPath << "'");
1295 rOStm.WriteBool( bRel );
1296 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStm, aPath, RTL_TEXTENCODING_UTF8);
1297 rOStm.WriteUInt32( pObj->nOffset ).WriteUInt16( static_cast<sal_uInt16>(pObj->eObjKind) );
1300 // more recently, a 512-byte reserve buffer is written,
1301 // to recognize them two sal_uInt32-Ids will be written.
1302 rOStm.WriteUInt32( COMPAT_FORMAT( 'G', 'A', 'L', 'R' ) ).WriteUInt32( COMPAT_FORMAT( 'E', 'S', 'R', 'V' ) );
1304 const long nReservePos = rOStm.Tell();
1305 std::unique_ptr<VersionCompat> pCompat(new VersionCompat( rOStm, StreamMode::WRITE, 2 ));
1307 rOStm.WriteUInt32( GetId() ).WriteBool( IsThemeNameFromResource() ); // From version 2 and up
1309 pCompat.reset();
1311 // Fill the rest of the buffer.
1312 const long nRest = std::max( 512L - ( static_cast<long>(rOStm.Tell()) - nReservePos ), 0L );
1314 if( nRest )
1316 std::unique_ptr<char[]> pReserve(new char[ nRest ]);
1317 memset( pReserve.get(), 0, nRest );
1318 rOStm.WriteBytes(pReserve.get(), nRest);
1321 return rOStm;
1324 SvStream& GalleryTheme::ReadData( SvStream& rIStm )
1326 sal_uInt32 nCount;
1327 sal_uInt16 nVersion;
1329 rIStm.ReadUInt16( nVersion );
1330 read_uInt16_lenPrefixed_uInt8s_ToOString(rIStm);
1331 rIStm.ReadUInt32( nCount );
1333 if( nVersion >= 0x0004 )
1335 sal_uInt16 nTmp16;
1336 rIStm.ReadUInt16( nTmp16 );
1339 if( nCount <= ( 1 << 14 ) )
1341 INetURLObject aRelURL1( GetParent()->GetRelativeURL() );
1342 INetURLObject aRelURL2( GetParent()->GetUserURL() );
1343 sal_uInt32 nId1, nId2;
1344 bool bRel;
1346 for(auto & i : aObjectList)
1348 GalleryObject* pObj = i.get();
1349 Broadcast( GalleryHint( GalleryHintType::CLOSE_OBJECT, GetName(), pObj ) );
1350 i.reset();
1352 aObjectList.clear();
1354 for( sal_uInt32 i = 0; i < nCount; i++ )
1356 std::unique_ptr<GalleryObject> pObj(new GalleryObject);
1358 OUString aFileName;
1359 OUString aPath;
1360 sal_uInt16 nTemp;
1362 rIStm.ReadCharAsBool( bRel );
1363 OString aTempFileName = read_uInt16_lenPrefixed_uInt8s_ToOString(rIStm);
1364 rIStm.ReadUInt32( pObj->nOffset );
1365 rIStm.ReadUInt16( nTemp ); pObj->eObjKind = static_cast<SgaObjKind>(nTemp);
1367 aFileName = OStringToOUString(aTempFileName, osl_getThreadTextEncoding());
1369 if( bRel )
1371 aFileName = aFileName.replaceAll( "\\", "/" );
1372 aPath = aRelURL1.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1374 if( aFileName[ 0 ] != '/' )
1375 aPath += "/";
1377 aPath += aFileName;
1379 pObj->aURL = INetURLObject( aPath );
1381 if( !FileExists( pObj->aURL ) )
1383 aPath = aRelURL2.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1385 if( aFileName[0] != '/' )
1386 aPath += "/";
1388 aPath += aFileName;
1390 // assign this URL, even in the case it is not valid (#94482)
1391 pObj->aURL = INetURLObject( aPath );
1394 else
1396 if( SgaObjKind::SvDraw == pObj->eObjKind )
1398 OUString aDummyURL( "gallery/svdraw/" );
1399 pObj->aURL = INetURLObject( aDummyURL += aFileName, INetProtocol::PrivSoffice );
1401 else
1403 OUString aLocalURL;
1405 pObj->aURL = INetURLObject( aFileName );
1407 if( ( pObj->aURL.GetProtocol() == INetProtocol::NotValid ) &&
1408 osl::FileBase::getFileURLFromSystemPath( aFileName, aLocalURL ) == osl::FileBase::E_None )
1410 pObj->aURL = INetURLObject( aLocalURL );
1414 aObjectList.push_back( std::move(pObj) );
1417 rIStm.ReadUInt32( nId1 ).ReadUInt32( nId2 );
1419 // In newer versions a 512 byte reserve buffer is located at the end,
1420 // the data is located at the beginning of this buffer and are clamped
1421 // by a VersionCompat.
1422 if( !rIStm.eof() &&
1423 nId1 == COMPAT_FORMAT( 'G', 'A', 'L', 'R' ) &&
1424 nId2 == COMPAT_FORMAT( 'E', 'S', 'R', 'V' ) )
1426 std::unique_ptr<VersionCompat> pCompat(new VersionCompat( rIStm, StreamMode::READ ));
1427 sal_uInt32 nTemp32;
1428 bool bThemeNameFromResource = false;
1430 rIStm.ReadUInt32( nTemp32 );
1432 if( pCompat->GetVersion() >= 2 )
1434 rIStm.ReadCharAsBool( bThemeNameFromResource );
1437 SetId( nTemp32, bThemeNameFromResource );
1440 else
1441 rIStm.SetError( SVSTREAM_READ_ERROR );
1443 ImplSetModified( false );
1445 return rIStm;
1448 SvStream& WriteGalleryTheme( SvStream& rOut, const GalleryTheme& rTheme )
1450 return rTheme.WriteData( rOut );
1453 SvStream& ReadGalleryTheme( SvStream& rIn, GalleryTheme& rTheme )
1455 return rTheme.ReadData( rIn );
1458 void GalleryTheme::ImplSetModified( bool bModified )
1460 pThm->SetModified(bModified);
1463 const INetURLObject& GalleryTheme::GetThmURL() const { return pThm->GetThmURL(); }
1464 const INetURLObject& GalleryTheme::GetSdgURL() const { return pThm->GetSdgURL(); }
1465 const INetURLObject& GalleryTheme::GetSdvURL() const { return pThm->GetSdvURL(); }
1466 const INetURLObject& GalleryTheme::GetStrURL() const { return pThm->GetStrURL(); }
1467 sal_uInt32 GalleryTheme::GetId() const { return pThm->GetId(); }
1468 void GalleryTheme::SetId( sal_uInt32 nNewId, bool bResetThemeName ) { pThm->SetId( nNewId, bResetThemeName ); }
1469 bool GalleryTheme::IsThemeNameFromResource() const { return pThm->IsNameFromResource(); }
1470 bool GalleryTheme::IsReadOnly() const { return pThm->IsReadOnly(); }
1471 bool GalleryTheme::IsDefault() const { return pThm->IsDefault(); }
1473 const tools::SvRef<SotStorage>& GalleryTheme::GetSvDrawStorage() const
1475 return aSvDrawStorageRef;
1478 const OUString& GalleryTheme::GetName() const { return pThm->GetThemeName(); }
1480 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */