summaryrefslogtreecommitdiffstats
path: root/svx/source/gallery2/galtheme.cxx
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
commit940b4d1848e8c70ab7642901a68594e8016caffc (patch)
treeeb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /svx/source/gallery2/galtheme.cxx
parentInitial commit. (diff)
downloadlibreoffice-upstream.tar.xz
libreoffice-upstream.zip
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--svx/source/gallery2/galtheme.cxx1468
1 files changed, 1468 insertions, 0 deletions
diff --git a/svx/source/gallery2/galtheme.cxx b/svx/source/gallery2/galtheme.cxx
new file mode 100644
index 000000000..a5b60f572
--- /dev/null
+++ b/svx/source/gallery2/galtheme.cxx
@@ -0,0 +1,1468 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <config_features.h>
+
+#include <sal/config.h>
+#include <sal/log.hxx>
+
+#include <algorithm>
+
+#include <comphelper/fileformat.h>
+#include <comphelper/processfactory.hxx>
+#include <osl/file.hxx>
+#include <osl/thread.hxx>
+#include <tools/diagnose_ex.h>
+#include <tools/urlobj.hxx>
+#include <tools/vcompat.hxx>
+#include <unotools/streamwrap.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <unotools/tempfile.hxx>
+#include <ucbhelper/content.hxx>
+#include <com/sun/star/ucb/ContentCreationException.hpp>
+#include <sot/storage.hxx>
+#include <sot/formats.hxx>
+#include <sot/filelist.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/cvtgrf.hxx>
+#include <avmedia/mediawindow.hxx>
+#include <svx/svdograf.hxx>
+#include "codec.hxx"
+#include <svx/unomodel.hxx>
+#include <svx/fmmodel.hxx>
+#include <svx/fmview.hxx>
+#include <svx/galmisc.hxx>
+#include <svx/galtheme.hxx>
+#include <svx/svdpage.hxx>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/ucb/XContentAccess.hpp>
+#include <galobj.hxx>
+#include <svx/gallery1.hxx>
+#include "gallerydrawmodel.hxx"
+#include <memory>
+
+using namespace ::com::sun::star;
+
+
+GalleryTheme::GalleryTheme( Gallery* pGallery, GalleryThemeEntry* pThemeEntry )
+ : m_bDestDirRelative(false)
+ , pParent(pGallery)
+ , pThm(pThemeEntry)
+ , mnThemeLockCount(0)
+ , mnBroadcasterLockCount(0)
+ , nDragPos(0)
+ , bDragging(false)
+ , bAbortActualize(false)
+{
+ ImplCreateSvDrawStorage();
+}
+
+GalleryTheme::~GalleryTheme()
+{
+ ImplWrite();
+
+ for (auto & pEntry : aObjectList)
+ {
+ Broadcast( GalleryHint( GalleryHintType::CLOSE_OBJECT, GetName(), pEntry.get() ) );
+ pEntry.reset();
+ }
+ aObjectList.clear();
+
+}
+
+void GalleryTheme::ImplCreateSvDrawStorage()
+{
+ try
+ {
+ aSvDrawStorageRef = new SotStorage( false, GetSdvURL().GetMainURL( INetURLObject::DecodeMechanism::NONE ), pThm->IsReadOnly() ? StreamMode::READ : StreamMode::STD_READWRITE );
+ // #i50423# ReadOnly may not been set though the file can't be written (because of security reasons)
+ if ( ( aSvDrawStorageRef->GetError() != ERRCODE_NONE ) && !pThm->IsReadOnly() )
+ aSvDrawStorageRef = new SotStorage( false, GetSdvURL().GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ );
+ }
+ catch (const css::ucb::ContentCreationException&)
+ {
+ TOOLS_WARN_EXCEPTION("svx", "failed to open: "
+ << GetSdvURL().GetMainURL(INetURLObject::DecodeMechanism::NONE)
+ << "due to");
+ }
+}
+
+bool GalleryTheme::ImplWriteSgaObject(const SgaObject& rObj, sal_uInt32 nPos, GalleryObject* pExistentEntry)
+{
+ std::unique_ptr<SvStream> pOStm(::utl::UcbStreamHelper::CreateStream( GetSdgURL().GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::WRITE ));
+ bool bRet = false;
+
+ if( pOStm )
+ {
+ const sal_uInt32 nOffset = pOStm->Seek( STREAM_SEEK_TO_END );
+
+ rObj.WriteData( *pOStm, m_aDestDir );
+
+ if( !pOStm->GetError() )
+ {
+ GalleryObject* pEntry;
+
+ if( !pExistentEntry )
+ {
+ pEntry = new GalleryObject;
+ if ( nPos < aObjectList.size() )
+ {
+ aObjectList.emplace( aObjectList.begin() + nPos, pEntry );
+ }
+ else
+ aObjectList.emplace_back( pEntry );
+ }
+ else
+ pEntry = pExistentEntry;
+
+ pEntry->aURL = rObj.GetURL();
+ pEntry->nOffset = nOffset;
+ pEntry->eObjKind = rObj.GetObjKind();
+ bRet = true;
+ }
+ }
+
+ return bRet;
+}
+
+std::unique_ptr<SgaObject> GalleryTheme::ImplReadSgaObject( GalleryObject const * pEntry )
+{
+ std::unique_ptr<SgaObject> pSgaObj;
+
+ if( pEntry )
+ {
+ std::unique_ptr<SvStream> pIStm(::utl::UcbStreamHelper::CreateStream( GetSdgURL().GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ ));
+
+ if( pIStm )
+ {
+ sal_uInt32 nInventor;
+
+ // Check to ensure that the file is a valid SGA file
+ pIStm->Seek( pEntry->nOffset );
+ pIStm->ReadUInt32( nInventor );
+
+ if( nInventor == COMPAT_FORMAT( 'S', 'G', 'A', '3' ) )
+ {
+ pIStm->Seek( pEntry->nOffset );
+
+ switch( pEntry->eObjKind )
+ {
+ case SgaObjKind::Bitmap: pSgaObj.reset(new SgaObjectBmp()); break;
+ case SgaObjKind::Animation: pSgaObj.reset(new SgaObjectAnim()); break;
+ case SgaObjKind::Inet: pSgaObj.reset(new SgaObjectINet()); break;
+ case SgaObjKind::SvDraw: pSgaObj.reset(new SgaObjectSvDraw()); break;
+ case SgaObjKind::Sound: pSgaObj.reset(new SgaObjectSound()); break;
+
+ default:
+ break;
+ }
+
+ if( pSgaObj )
+ {
+ ReadSgaObject( *pIStm, *pSgaObj );
+ pSgaObj->ImplUpdateURL( pEntry->aURL );
+ }
+ }
+ }
+ }
+
+ return pSgaObj;
+}
+
+void GalleryTheme::ImplWrite()
+{
+ if( pThm->IsModified() )
+ {
+ INetURLObject aPathURL( GetThmURL() );
+
+ aPathURL.removeSegment();
+ aPathURL.removeFinalSlash();
+
+ DBG_ASSERT( aPathURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
+
+ if( FileExists( aPathURL ) || CreateDir( aPathURL ) )
+ {
+#ifdef UNX
+ std::unique_ptr<SvStream> pOStm(::utl::UcbStreamHelper::CreateStream( GetThmURL().GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::WRITE | StreamMode::COPY_ON_SYMLINK | StreamMode::TRUNC ));
+#else
+ std::unique_ptr<SvStream> pOStm(::utl::UcbStreamHelper::CreateStream( GetThmURL().GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::WRITE | StreamMode::TRUNC ));
+#endif
+
+ if( pOStm )
+ {
+ WriteGalleryTheme( *pOStm, *this );
+ pOStm.reset();
+ }
+
+ ImplSetModified( false );
+ }
+ }
+}
+
+const GalleryObject* GalleryTheme::ImplGetGalleryObject( const INetURLObject& rURL )
+{
+ for (auto const & i : aObjectList)
+ if ( i->aURL == rURL )
+ return i.get();
+ return nullptr;
+}
+
+INetURLObject GalleryTheme::ImplGetURL( const GalleryObject* pObject )
+{
+ INetURLObject aURL;
+
+ if( pObject )
+ aURL = pObject->aURL;
+
+ return aURL;
+}
+
+INetURLObject GalleryTheme::ImplCreateUniqueURL( SgaObjKind eObjKind, ConvertDataFormat nFormat )
+{
+ INetURLObject aDir( GetParent()->GetUserURL() );
+ INetURLObject aInfoFileURL( GetParent()->GetUserURL() );
+ INetURLObject aNewURL;
+ sal_uInt32 nNextNumber = 1999;
+ char const* pExt = nullptr;
+ bool bExists;
+
+ aDir.Append( "dragdrop" );
+ CreateDir( aDir );
+
+ aInfoFileURL.Append( "sdddndx1" );
+
+ // read next possible number
+ if( FileExists( aInfoFileURL ) )
+ {
+ std::unique_ptr<SvStream> pIStm(::utl::UcbStreamHelper::CreateStream( aInfoFileURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ ));
+
+ if( pIStm )
+ {
+ pIStm->ReadUInt32( nNextNumber );
+ }
+ }
+
+ // create extension
+ if( nFormat != ConvertDataFormat::Unknown )
+ {
+ switch( nFormat )
+ {
+ case ConvertDataFormat::BMP: pExt = ".bmp"; break;
+ case ConvertDataFormat::GIF: pExt = ".gif"; break;
+ case ConvertDataFormat::JPG: pExt = ".jpg"; break;
+ case ConvertDataFormat::MET: pExt = ".met"; break;
+ case ConvertDataFormat::PCT: pExt = ".pct"; break;
+ case ConvertDataFormat::PNG: pExt = ".png"; break;
+ case ConvertDataFormat::SVM: pExt = ".svm"; break;
+ case ConvertDataFormat::TIF: pExt = ".tif"; break;
+ case ConvertDataFormat::WMF: pExt = ".wmf"; break;
+ case ConvertDataFormat::EMF: pExt = ".emf"; break;
+
+ default:
+ pExt = ".grf";
+ break;
+ }
+ }
+
+ do
+ {
+ // get URL
+ if( SgaObjKind::SvDraw == eObjKind )
+ {
+ OUString aFileName = "gallery/svdraw/dd" + OUString::number( ++nNextNumber % 99999999 );
+ aNewURL = INetURLObject( aFileName, INetProtocol::PrivSoffice );
+
+ bExists = false;
+
+ for (auto const & p : aObjectList)
+ if ( p->aURL == aNewURL )
+ {
+ bExists = true;
+ break;
+ }
+ }
+ else
+ {
+ OUString aFileName = "dd" + OUString::number( ++nNextNumber % 999999 );
+
+ if (pExt)
+ aFileName += OUString( pExt, strlen(pExt), RTL_TEXTENCODING_ASCII_US );
+
+ aNewURL = aDir;
+ aNewURL.Append( aFileName );
+
+ bExists = FileExists( aNewURL );
+ }
+ }
+ while( bExists );
+
+ // write updated number
+ std::unique_ptr<SvStream> pOStm(::utl::UcbStreamHelper::CreateStream( aInfoFileURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::WRITE ));
+
+ if( pOStm )
+ {
+ pOStm->WriteUInt32( nNextNumber );
+ }
+
+ return aNewURL;
+}
+
+void GalleryTheme::ImplBroadcast(sal_uInt32 nUpdatePos)
+{
+ if( !IsBroadcasterLocked() )
+ {
+ if( GetObjectCount() && ( nUpdatePos >= GetObjectCount() ) )
+ nUpdatePos = GetObjectCount() - 1;
+
+ Broadcast( GalleryHint( GalleryHintType::THEME_UPDATEVIEW, GetName(), reinterpret_cast<void*>(nUpdatePos) ) );
+ }
+}
+
+bool GalleryTheme::UnlockTheme()
+{
+ DBG_ASSERT( mnThemeLockCount, "Theme is not locked" );
+
+ bool bRet = false;
+
+ if( mnThemeLockCount )
+ {
+ --mnThemeLockCount;
+ bRet = true;
+ }
+
+ return bRet;
+}
+
+void GalleryTheme::UnlockBroadcaster()
+{
+ DBG_ASSERT( mnBroadcasterLockCount, "Broadcaster is not locked" );
+
+ if( mnBroadcasterLockCount && !--mnBroadcasterLockCount )
+ ImplBroadcast( 0 );
+}
+
+bool GalleryTheme::InsertObject(const SgaObject& rObj, sal_uInt32 nInsertPos)
+{
+ if (!rObj.IsValid())
+ return false;
+
+ GalleryObject* pFoundEntry = nullptr;
+ sal_uInt32 iFoundPos = 0;
+ for (sal_uInt32 n = aObjectList.size(); iFoundPos < n; ++iFoundPos)
+ {
+ if (aObjectList[ iFoundPos ]->aURL == rObj.GetURL())
+ {
+ pFoundEntry = aObjectList[ iFoundPos ].get();
+ break;
+ }
+ }
+
+ if (pFoundEntry)
+ {
+ GalleryObject aNewEntry;
+
+ // update title of new object if necessary
+ if (rObj.GetTitle().isEmpty())
+ {
+ std::unique_ptr<SgaObject> pOldObj(ImplReadSgaObject(pFoundEntry));
+
+ if (pOldObj)
+ {
+ const_cast<SgaObject&>(rObj).SetTitle( pOldObj->GetTitle() );
+ }
+ }
+ else if (rObj.GetTitle() == "__<empty>__")
+ const_cast<SgaObject&>(rObj).SetTitle("");
+
+ ImplWriteSgaObject(rObj, nInsertPos, &aNewEntry);
+ pFoundEntry->nOffset = aNewEntry.nOffset;
+ }
+ else
+ ImplWriteSgaObject(rObj, nInsertPos, nullptr);
+
+ ImplSetModified(true);
+ ImplBroadcast(pFoundEntry? iFoundPos: nInsertPos);
+
+ return true;
+}
+
+std::unique_ptr<SgaObject> GalleryTheme::AcquireObject(sal_uInt32 nPos)
+{
+ return ImplReadSgaObject(ImplGetGalleryObject(nPos));
+}
+
+void GalleryTheme::GetPreviewBitmapExAndStrings(sal_uInt32 nPos, BitmapEx& rBitmapEx, Size& rSize, OUString& rTitle, OUString& rPath) const
+{
+ const GalleryObject* pGalleryObject = aObjectList[ nPos ].get();
+
+ rBitmapEx = pGalleryObject->maPreviewBitmapEx;
+ rSize = pGalleryObject->maPreparedSize;
+ rTitle = pGalleryObject->maTitle;
+ rPath = pGalleryObject->maPath;
+}
+
+void GalleryTheme::SetPreviewBitmapExAndStrings(sal_uInt32 nPos, const BitmapEx& rBitmapEx, const Size& rSize, const OUString& rTitle, const OUString& rPath)
+{
+ GalleryObject* pGalleryObject = aObjectList[ nPos ].get();
+
+ pGalleryObject->maPreviewBitmapEx = rBitmapEx;
+ pGalleryObject->maPreparedSize = rSize;
+ pGalleryObject->maTitle = rTitle;
+ pGalleryObject->maPath = rPath;
+}
+
+void GalleryTheme::RemoveObject(sal_uInt32 nPos)
+{
+ auto it = aObjectList.begin() + nPos;
+ std::unique_ptr<GalleryObject> pEntry = std::move(*it);
+ aObjectList.erase( it );
+
+ if( aObjectList.empty() )
+ KillFile( GetSdgURL() );
+
+ if( SgaObjKind::SvDraw == pEntry->eObjKind )
+ aSvDrawStorageRef->Remove( pEntry->aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+
+ Broadcast( GalleryHint( GalleryHintType::CLOSE_OBJECT, GetName(), pEntry.get() ) );
+ pEntry.reset();
+
+ ImplSetModified( true );
+ ImplBroadcast( nPos );
+}
+
+bool GalleryTheme::ChangeObjectPos(sal_uInt32 nOldPos, sal_uInt32 nNewPos)
+{
+ if (nOldPos == nNewPos || nOldPos >= aObjectList.size())
+ return false;
+
+ std::unique_ptr<GalleryObject> pEntry = std::move(aObjectList[nOldPos]);
+
+ aObjectList.insert(aObjectList.begin() + nNewPos, std::move(pEntry));
+
+ if (nNewPos < nOldPos)
+ nOldPos++;
+
+ auto it = aObjectList.begin() + nOldPos;
+ aObjectList.erase(it);
+
+ ImplSetModified(true);
+ ImplBroadcast((nNewPos < nOldPos)? nNewPos: (nNewPos - 1));
+
+ return true;
+}
+
+void GalleryTheme::Actualize( const Link<const INetURLObject&, void>& rActualizeLink, GalleryProgress* pProgress )
+{
+ if( IsReadOnly() )
+ return;
+
+ Graphic aGraphic;
+ OUString aFormat;
+ const sal_uInt32 nCount = aObjectList.size();
+
+ LockBroadcaster();
+ bAbortActualize = false;
+
+ // reset delete flag
+ for (sal_uInt32 i = 0; i < nCount; i++)
+ aObjectList[ i ]->mbDelete = false;
+
+ for (sal_uInt32 i = 0; ( i < nCount ) && !bAbortActualize; i++)
+ {
+ if( pProgress )
+ pProgress->Update( i, nCount - 1 );
+
+ GalleryObject* pEntry = aObjectList[ i ].get();
+
+ const INetURLObject aURL( pEntry->aURL );
+
+ rActualizeLink.Call( aURL );
+
+ // SvDraw objects will be updated later
+ if( pEntry->eObjKind != SgaObjKind::SvDraw )
+ {
+ // Still a function should be implemented,
+ // which assigns files to the relevant entry.
+ // insert graphics as graphic objects into the gallery
+ if( pEntry->eObjKind == SgaObjKind::Sound )
+ {
+ SgaObjectSound aObjSound( aURL );
+ if( !InsertObject( aObjSound ) )
+ pEntry->mbDelete = true;
+ }
+ else
+ {
+ aGraphic.Clear();
+
+ if ( GalleryGraphicImport( aURL, aGraphic, aFormat ) != GalleryGraphicImportRet::IMPORT_NONE )
+ {
+ std::unique_ptr<SgaObject> pNewObj;
+
+ if ( SgaObjKind::Inet == pEntry->eObjKind )
+ pNewObj.reset(new SgaObjectINet( aGraphic, aURL ));
+ else if ( aGraphic.IsAnimated() )
+ pNewObj.reset(new SgaObjectAnim( aGraphic, aURL ));
+ else
+ pNewObj.reset(new SgaObjectBmp( aGraphic, aURL ));
+
+ if( !InsertObject( *pNewObj ) )
+ pEntry->mbDelete = true;
+ }
+ else
+ pEntry->mbDelete = true; // set delete flag
+ }
+ }
+ else
+ {
+ if ( aSvDrawStorageRef.is() )
+ {
+ const OUString aStmName( GetSvDrawStreamNameFromURL( pEntry->aURL ) );
+ tools::SvRef<SotStorageStream> pIStm = aSvDrawStorageRef->OpenSotStream( aStmName, StreamMode::READ );
+
+ if( pIStm.is() && !pIStm->GetError() )
+ {
+ pIStm->SetBufferSize( 16384 );
+
+ SgaObjectSvDraw aNewObj( *pIStm, pEntry->aURL );
+
+ if( !InsertObject( aNewObj ) )
+ pEntry->mbDelete = true;
+
+ pIStm->SetBufferSize( 0 );
+ }
+ }
+ }
+ }
+
+ // remove all entries with set flag
+ for ( auto it = aObjectList.begin(); it != aObjectList.end(); /* increment is in the body of loop */)
+ {
+ if( (*it)->mbDelete )
+ {
+ Broadcast( GalleryHint( GalleryHintType::CLOSE_OBJECT, GetName(), it->get() ) );
+ it = aObjectList.erase( it );
+ }
+ else
+ ++it;
+ }
+
+ // update theme
+ ::utl::TempFile aTmp;
+ INetURLObject aInURL( GetSdgURL() );
+ INetURLObject aTmpURL( aTmp.GetURL() );
+
+ DBG_ASSERT( aInURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
+ DBG_ASSERT( aTmpURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
+
+ std::unique_ptr<SvStream> pIStm(::utl::UcbStreamHelper::CreateStream( aInURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ ));
+ std::unique_ptr<SvStream> pTmpStm(::utl::UcbStreamHelper::CreateStream( aTmpURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::WRITE | StreamMode::TRUNC ));
+
+ if( pIStm && pTmpStm )
+ {
+ for (const auto & i : aObjectList)
+ {
+ GalleryObject* pEntry = i.get();
+ std::unique_ptr<SgaObject> pObj;
+
+ switch( pEntry->eObjKind )
+ {
+ case SgaObjKind::Bitmap: pObj.reset(new SgaObjectBmp()); break;
+ case SgaObjKind::Animation: pObj.reset(new SgaObjectAnim()); break;
+ case SgaObjKind::Inet: pObj.reset(new SgaObjectINet()); break;
+ case SgaObjKind::SvDraw: pObj.reset(new SgaObjectSvDraw()); break;
+ case SgaObjKind::Sound: pObj.reset(new SgaObjectSound()); break;
+
+ default:
+ break;
+ }
+
+ if( pObj )
+ {
+ pIStm->Seek( pEntry->nOffset );
+ ReadSgaObject( *pIStm, *pObj);
+ pEntry->nOffset = pTmpStm->Tell();
+ WriteSgaObject( *pTmpStm, *pObj );
+ }
+ }
+ }
+ else
+ {
+ OSL_FAIL( "File(s) could not be opened" );
+ }
+
+ pIStm.reset();
+ pTmpStm.reset();
+
+ CopyFile( aTmpURL, aInURL );
+ KillFile( aTmpURL );
+
+ ErrCode nStorErr = ERRCODE_NONE;
+
+ try
+ {
+ tools::SvRef<SotStorage> aTempStorageRef( new SotStorage( false, aTmpURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::STD_READWRITE ) );
+ aSvDrawStorageRef->CopyTo( aTempStorageRef.get() );
+ nStorErr = aSvDrawStorageRef->GetError();
+ }
+ catch (const css::ucb::ContentCreationException&)
+ {
+ TOOLS_WARN_EXCEPTION("svx", "failed to open: "
+ << aTmpURL.GetMainURL(INetURLObject::DecodeMechanism::NONE)
+ << "due to");
+ nStorErr = ERRCODE_IO_GENERAL;
+ }
+
+ if( nStorErr == ERRCODE_NONE )
+ {
+ aSvDrawStorageRef.clear();
+ CopyFile( aTmpURL, GetSdvURL() );
+ ImplCreateSvDrawStorage();
+ }
+
+ KillFile( aTmpURL );
+ ImplSetModified( true );
+ ImplWrite();
+ UnlockBroadcaster();
+}
+
+GalleryThemeEntry* GalleryTheme::CreateThemeEntry( const INetURLObject& rURL, bool bReadOnly )
+{
+ DBG_ASSERT( rURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
+
+ GalleryThemeEntry* pRet = nullptr;
+
+ if( FileExists( rURL ) )
+ {
+ std::unique_ptr<SvStream> pIStm(::utl::UcbStreamHelper::CreateStream( rURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ ));
+
+ if( pIStm )
+ {
+ OUString aThemeName;
+ sal_uInt16 nVersion;
+
+ pIStm->ReadUInt16( nVersion );
+
+ if( nVersion <= 0x00ff )
+ {
+ bool bThemeNameFromResource = false;
+ sal_uInt32 nThemeId = 0;
+
+ OString aTmpStr = read_uInt16_lenPrefixed_uInt8s_ToOString(*pIStm);
+ aThemeName = OStringToOUString(aTmpStr, RTL_TEXTENCODING_UTF8);
+
+ // execute a character conversion
+ if( nVersion >= 0x0004 )
+ {
+ sal_uInt32 nCount;
+ sal_uInt16 nTemp16;
+
+ pIStm->ReadUInt32( nCount ).ReadUInt16( nTemp16 );
+ pIStm->Seek( STREAM_SEEK_TO_END );
+
+ // check whether there is a newer version;
+ // therefore jump back by 520Bytes (8 bytes ID + 512Bytes reserve buffer)
+ // if this is at all possible.
+ if( pIStm->Tell() >= 520 )
+ {
+ sal_uInt32 nId1, nId2;
+
+ pIStm->SeekRel( -520 );
+ pIStm->ReadUInt32( nId1 ).ReadUInt32( nId2 );
+
+ if( nId1 == COMPAT_FORMAT( 'G', 'A', 'L', 'R' ) &&
+ nId2 == COMPAT_FORMAT( 'E', 'S', 'R', 'V' ) )
+ {
+ VersionCompat aCompat( *pIStm, StreamMode::READ );
+
+ pIStm->ReadUInt32( nThemeId );
+
+ if( aCompat.GetVersion() >= 2 )
+ {
+ pIStm->ReadCharAsBool( bThemeNameFromResource );
+ }
+ }
+ }
+ }
+
+ pRet = new GalleryThemeEntry( false, rURL, aThemeName,
+ bReadOnly, false, nThemeId,
+ bThemeNameFromResource );
+ }
+ }
+ }
+
+ return pRet;
+}
+
+bool GalleryTheme::GetThumb(sal_uInt32 nPos, BitmapEx& rBmp)
+{
+ std::unique_ptr<SgaObject> pObj = AcquireObject( nPos );
+ bool bRet = false;
+
+ if( pObj )
+ {
+ rBmp = pObj->GetThumbBmp();
+ bRet = true;
+ }
+
+ return bRet;
+}
+
+bool GalleryTheme::GetGraphic(sal_uInt32 nPos, Graphic& rGraphic)
+{
+ const GalleryObject* pObject = ImplGetGalleryObject( nPos );
+ bool bRet = false;
+
+ if( pObject )
+ {
+ const INetURLObject aURL( ImplGetURL( pObject ) );
+
+ switch( pObject->eObjKind )
+ {
+ case SgaObjKind::Bitmap:
+ case SgaObjKind::Animation:
+ case SgaObjKind::Inet:
+ {
+ OUString aFilterDummy;
+ bRet = ( GalleryGraphicImport( aURL, rGraphic, aFilterDummy ) != GalleryGraphicImportRet::IMPORT_NONE );
+ }
+ break;
+
+ case SgaObjKind::SvDraw:
+ {
+ SvxGalleryDrawModel aModel;
+
+ if( aModel.GetModel() )
+ {
+ if( GetModel( nPos, *aModel.GetModel() ) )
+ {
+ ImageMap aIMap;
+
+ if( CreateIMapGraphic( *aModel.GetModel(), rGraphic, aIMap ) )
+ bRet = true;
+ else
+ {
+ ScopedVclPtrInstance< VirtualDevice > pVDev;
+ pVDev->SetMapMode( MapMode( MapUnit::Map100thMM ) );
+ FmFormView aView(*aModel.GetModel(), pVDev);
+
+ aView.hideMarkHandles();
+ aView.ShowSdrPage(aView.GetModel()->GetPage(0));
+ aView.MarkAll();
+ rGraphic = aView.GetAllMarkedGraphic();
+ bRet = true;
+ }
+ }
+ }
+ }
+ break;
+
+ case SgaObjKind::Sound:
+ {
+ std::unique_ptr<SgaObject> pObj = AcquireObject( nPos );
+
+ if( pObj )
+ {
+ rGraphic = pObj->GetThumbBmp();
+ //Bitmap aBmp( pObj->GetThumbBmp() );
+ //aBmp.Replace( COL_LIGHTMAGENTA, COL_WHITE );
+ //rGraphic = aBmp;
+ bRet = true;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return bRet;
+}
+
+bool GalleryTheme::InsertGraphic(const Graphic& rGraphic, sal_uInt32 nInsertPos)
+{
+ bool bRet = false;
+
+ if( rGraphic.GetType() != GraphicType::NONE )
+ {
+ ConvertDataFormat nExportFormat = ConvertDataFormat::Unknown;
+ const GfxLink aGfxLink( rGraphic.GetGfxLink() );
+
+ if( aGfxLink.GetDataSize() )
+ {
+ switch( aGfxLink.GetType() )
+ {
+ case GfxLinkType::EpsBuffer: nExportFormat = ConvertDataFormat::SVM; break;
+ case GfxLinkType::NativeGif: nExportFormat = ConvertDataFormat::GIF; break;
+
+ // #i15508# added BMP type
+ // could not find/trigger a call to this, but should do no harm
+ case GfxLinkType::NativeBmp: nExportFormat = ConvertDataFormat::BMP; break;
+
+ case GfxLinkType::NativeJpg: nExportFormat = ConvertDataFormat::JPG; break;
+ case GfxLinkType::NativePng: nExportFormat = ConvertDataFormat::PNG; break;
+ case GfxLinkType::NativeTif: nExportFormat = ConvertDataFormat::TIF; break;
+ case GfxLinkType::NativeWmf: nExportFormat = ConvertDataFormat::WMF; break;
+ case GfxLinkType::NativeMet: nExportFormat = ConvertDataFormat::MET; break;
+ case GfxLinkType::NativePct: nExportFormat = ConvertDataFormat::PCT; break;
+ case GfxLinkType::NativeSvg: nExportFormat = ConvertDataFormat::SVG; break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ if( rGraphic.GetType() == GraphicType::Bitmap )
+ {
+ if( rGraphic.IsAnimated() )
+ nExportFormat = ConvertDataFormat::GIF;
+ else
+ nExportFormat = ConvertDataFormat::PNG;
+ }
+ else
+ nExportFormat = ConvertDataFormat::SVM;
+ }
+
+ const INetURLObject aURL( ImplCreateUniqueURL( SgaObjKind::Bitmap, nExportFormat ) );
+ std::unique_ptr<SvStream> pOStm(::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::WRITE | StreamMode::TRUNC ));
+
+ if( pOStm )
+ {
+ pOStm->SetVersion( SOFFICE_FILEFORMAT_50 );
+
+ if( ConvertDataFormat::SVM == nExportFormat )
+ {
+ GDIMetaFile aMtf( rGraphic.GetGDIMetaFile() );
+
+ aMtf.Write( *pOStm );
+ bRet = ( pOStm->GetError() == ERRCODE_NONE );
+ }
+ else
+ {
+ if( aGfxLink.GetDataSize() && aGfxLink.GetData() )
+ {
+ pOStm->WriteBytes(aGfxLink.GetData(), aGfxLink.GetDataSize());
+ bRet = ( pOStm->GetError() == ERRCODE_NONE );
+ }
+ else
+ bRet = ( GraphicConverter::Export( *pOStm, rGraphic, nExportFormat ) == ERRCODE_NONE );
+ }
+
+ pOStm.reset();
+ }
+
+ if( bRet )
+ {
+ const SgaObjectBmp aObjBmp( aURL );
+ InsertObject( aObjBmp, nInsertPos );
+ }
+ }
+
+ return bRet;
+}
+
+bool GalleryTheme::GetModel(sal_uInt32 nPos, SdrModel& rModel)
+{
+ const GalleryObject* pObject = ImplGetGalleryObject( nPos );
+ bool bRet = false;
+
+ if( pObject && ( SgaObjKind::SvDraw == pObject->eObjKind ) )
+ {
+ const INetURLObject aURL( ImplGetURL( pObject ) );
+ tools::SvRef<SotStorage> xStor( GetSvDrawStorage() );
+
+ if( xStor.is() )
+ {
+ const OUString aStmName( GetSvDrawStreamNameFromURL( aURL ) );
+ tools::SvRef<SotStorageStream> xIStm( xStor->OpenSotStream( aStmName, StreamMode::READ ) );
+
+ if( xIStm.is() && !xIStm->GetError() )
+ {
+ xIStm->SetBufferSize( STREAMBUF_SIZE );
+ bRet = GallerySvDrawImport( *xIStm, rModel );
+ xIStm->SetBufferSize( 0 );
+ }
+ }
+ }
+
+ return bRet;
+}
+
+bool GalleryTheme::InsertModel(const FmFormModel& rModel, sal_uInt32 nInsertPos)
+{
+ INetURLObject aURL( ImplCreateUniqueURL( SgaObjKind::SvDraw ) );
+ tools::SvRef<SotStorage> xStor( GetSvDrawStorage() );
+ bool bRet = false;
+
+ if( xStor.is() )
+ {
+ const OUString aStmName( GetSvDrawStreamNameFromURL( aURL ) );
+ tools::SvRef<SotStorageStream> xOStm( xStor->OpenSotStream( aStmName, StreamMode::WRITE | StreamMode::TRUNC ) );
+
+ if( xOStm.is() && !xOStm->GetError() )
+ {
+ SvMemoryStream aMemStm( 65535, 65535 );
+ FmFormModel* pFormModel = const_cast<FmFormModel*>(&rModel);
+
+ pFormModel->BurnInStyleSheetAttributes();
+
+ {
+ uno::Reference< io::XOutputStream > xDocOut( new utl::OOutputStreamWrapper( aMemStm ) );
+
+ if (xDocOut.is())
+ (void)SvxDrawingLayerExport( pFormModel, xDocOut );
+ }
+
+ aMemStm.Seek( 0 );
+
+ xOStm->SetBufferSize( 16348 );
+ GalleryCodec aCodec( *xOStm );
+ aCodec.Write( aMemStm );
+
+ if( !xOStm->GetError() )
+ {
+ SgaObjectSvDraw aObjSvDraw( rModel, aURL );
+ bRet = InsertObject( aObjSvDraw, nInsertPos );
+ }
+
+ xOStm->SetBufferSize( 0 );
+ xOStm->Commit();
+ }
+ }
+
+ return bRet;
+}
+
+bool GalleryTheme::GetModelStream(sal_uInt32 nPos, tools::SvRef<SotStorageStream> const & rxModelStream)
+{
+ const GalleryObject* pObject = ImplGetGalleryObject( nPos );
+ bool bRet = false;
+
+ if( pObject && ( SgaObjKind::SvDraw == pObject->eObjKind ) )
+ {
+ const INetURLObject aURL( ImplGetURL( pObject ) );
+ tools::SvRef<SotStorage> xStor( GetSvDrawStorage() );
+
+ if( xStor.is() )
+ {
+ const OUString aStmName( GetSvDrawStreamNameFromURL( aURL ) );
+ tools::SvRef<SotStorageStream> xIStm( xStor->OpenSotStream( aStmName, StreamMode::READ ) );
+
+ if( xIStm.is() && !xIStm->GetError() )
+ {
+ sal_uInt32 nVersion = 0;
+
+ xIStm->SetBufferSize( 16348 );
+
+ if( GalleryCodec::IsCoded( *xIStm, nVersion ) )
+ {
+ SvxGalleryDrawModel aModel;
+
+ if( aModel.GetModel() )
+ {
+ if( GallerySvDrawImport( *xIStm, *aModel.GetModel() ) )
+ {
+ aModel.GetModel()->BurnInStyleSheetAttributes();
+
+ {
+ uno::Reference< io::XOutputStream > xDocOut( new utl::OOutputStreamWrapper( *rxModelStream ) );
+
+ if( SvxDrawingLayerExport( aModel.GetModel(), xDocOut ) )
+ rxModelStream->Commit();
+ }
+ }
+
+ bRet = ( rxModelStream->GetError() == ERRCODE_NONE );
+ }
+ }
+
+ xIStm->SetBufferSize( 0 );
+ }
+ }
+ }
+
+ return bRet;
+}
+
+bool GalleryTheme::InsertModelStream(const tools::SvRef<SotStorageStream>& rxModelStream, sal_uInt32 nInsertPos)
+{
+ INetURLObject aURL( ImplCreateUniqueURL( SgaObjKind::SvDraw ) );
+ tools::SvRef<SotStorage> xStor( GetSvDrawStorage() );
+ bool bRet = false;
+
+ if( xStor.is() )
+ {
+ const OUString aStmName( GetSvDrawStreamNameFromURL( aURL ) );
+ tools::SvRef<SotStorageStream> xOStm( xStor->OpenSotStream( aStmName, StreamMode::WRITE | StreamMode::TRUNC ) );
+
+ if( xOStm.is() && !xOStm->GetError() )
+ {
+ GalleryCodec aCodec( *xOStm );
+
+ xOStm->SetBufferSize( 16348 );
+ aCodec.Write( *rxModelStream );
+
+ if( !xOStm->GetError() )
+ {
+ xOStm->Seek( 0 );
+ SgaObjectSvDraw aObjSvDraw( *xOStm, aURL );
+ bRet = InsertObject( aObjSvDraw, nInsertPos );
+ }
+
+ xOStm->SetBufferSize( 0 );
+ xOStm->Commit();
+ }
+ }
+
+ return bRet;
+}
+
+bool GalleryTheme::GetURL(sal_uInt32 nPos, INetURLObject& rURL)
+{
+ const GalleryObject* pObject = ImplGetGalleryObject( nPos );
+ bool bRet = false;
+
+ if( pObject )
+ {
+ rURL = ImplGetURL( pObject );
+ bRet = true;
+ }
+
+ return bRet;
+}
+
+bool GalleryTheme::InsertURL(const INetURLObject& rURL, sal_uInt32 nInsertPos)
+{
+ Graphic aGraphic;
+ OUString aFormat;
+ std::unique_ptr<SgaObject> pNewObj;
+ const GalleryGraphicImportRet nImportRet = GalleryGraphicImport( rURL, aGraphic, aFormat );
+ bool bRet = false;
+
+ if( nImportRet != GalleryGraphicImportRet::IMPORT_NONE )
+ {
+ if ( aGraphic.IsAnimated() )
+ pNewObj.reset(new SgaObjectAnim( aGraphic, rURL ));
+ else
+ pNewObj.reset(new SgaObjectBmp( aGraphic, rURL ));
+ }
+#if HAVE_FEATURE_AVMEDIA
+ else if( ::avmedia::MediaWindow::isMediaURL( rURL.GetMainURL( INetURLObject::DecodeMechanism::Unambiguous ), ""/*TODO?*/ ) )
+ pNewObj.reset(new SgaObjectSound( rURL ));
+#endif
+ if( pNewObj && InsertObject( *pNewObj, nInsertPos ) )
+ bRet = true;
+
+ return bRet;
+}
+
+bool GalleryTheme::InsertFileOrDirURL(const INetURLObject& rFileOrDirURL, sal_uInt32 nInsertPos)
+{
+ INetURLObject aURL;
+ ::std::vector< INetURLObject > aURLVector;
+ bool bRet = false;
+
+ try
+ {
+ ::ucbhelper::Content aCnt( rFileOrDirURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), uno::Reference< ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
+ bool bFolder = false;
+
+ aCnt.getPropertyValue("IsFolder") >>= bFolder;
+
+ if( bFolder )
+ {
+ uno::Sequence<OUString> aProps { "Url" };
+ uno::Reference< sdbc::XResultSet > xResultSet( aCnt.createCursor( aProps, ::ucbhelper::INCLUDE_DOCUMENTS_ONLY ) );
+ uno::Reference< ucb::XContentAccess > xContentAccess( xResultSet, uno::UNO_QUERY );
+ if( xContentAccess.is() )
+ {
+ while( xResultSet->next() )
+ {
+ aURL.SetSmartURL( xContentAccess->queryContentIdentifierString() );
+ aURLVector.push_back( aURL );
+ }
+ }
+ }
+ else
+ aURLVector.push_back( rFileOrDirURL );
+ }
+ catch( const ucb::ContentCreationException& )
+ {
+ }
+ catch( const uno::RuntimeException& )
+ {
+ }
+ catch( const uno::Exception& )
+ {
+ }
+
+ for( const auto& rURL : aURLVector )
+ bRet = bRet || InsertURL( rURL, nInsertPos );
+
+ return bRet;
+}
+
+bool GalleryTheme::InsertTransferable(const uno::Reference< datatransfer::XTransferable >& rxTransferable, sal_uInt32 nInsertPos)
+{
+ bool bRet = false;
+
+ if( rxTransferable.is() )
+ {
+ TransferableDataHelper aDataHelper( rxTransferable );
+ std::unique_ptr<Graphic> pGraphic;
+
+ if( aDataHelper.HasFormat( SotClipboardFormatId::DRAWING ) )
+ {
+ tools::SvRef<SotStorageStream> xModelStm;
+
+ if( aDataHelper.GetSotStorageStream( SotClipboardFormatId::DRAWING, xModelStm ) )
+ bRet = InsertModelStream( xModelStm, nInsertPos );
+ }
+ else if( aDataHelper.HasFormat( SotClipboardFormatId::FILE_LIST ) ||
+ aDataHelper.HasFormat( SotClipboardFormatId::SIMPLE_FILE ) )
+ {
+ FileList aFileList;
+
+ if( aDataHelper.HasFormat( SotClipboardFormatId::FILE_LIST ) )
+ aDataHelper.GetFileList( SotClipboardFormatId::FILE_LIST, aFileList );
+ else
+ {
+ OUString aFile;
+ if (aDataHelper.GetString(SotClipboardFormatId::SIMPLE_FILE, aFile) && !aFile.isEmpty())
+ aFileList.AppendFile( aFile );
+ }
+
+ for( sal_uInt32 i = 0, nCount = aFileList.Count(); i < nCount; ++i )
+ {
+ const OUString aFile( aFileList.GetFile( i ) );
+ INetURLObject aURL( aFile );
+
+ if( aURL.GetProtocol() == INetProtocol::NotValid )
+ {
+ OUString aLocalURL;
+
+ if( osl::FileBase::getFileURLFromSystemPath( aFile, aLocalURL ) == osl::FileBase::E_None )
+ aURL = INetURLObject( aLocalURL );
+ }
+
+ if( aURL.GetProtocol() != INetProtocol::NotValid )
+ bRet = InsertFileOrDirURL( aURL, nInsertPos );
+ }
+ }
+ else
+ {
+ Graphic aGraphic;
+ SotClipboardFormatId nFormat = SotClipboardFormatId::NONE;
+
+ if( aDataHelper.HasFormat( SotClipboardFormatId::SVXB ) )
+ nFormat = SotClipboardFormatId::SVXB;
+ else if( aDataHelper.HasFormat( SotClipboardFormatId::GDIMETAFILE ) )
+ nFormat = SotClipboardFormatId::GDIMETAFILE;
+ else if( aDataHelper.HasFormat( SotClipboardFormatId::BITMAP ) )
+ nFormat = SotClipboardFormatId::BITMAP;
+
+ if( nFormat != SotClipboardFormatId::NONE && aDataHelper.GetGraphic( nFormat, aGraphic ) )
+ pGraphic.reset(new Graphic( aGraphic ));
+ }
+
+ if( pGraphic )
+ {
+ bRet = false;
+
+ if( aDataHelper.HasFormat( SotClipboardFormatId::SVIM ) )
+ {
+
+ ImageMap aImageMap;
+
+ // according to KA we don't need a BaseURL here
+ if( aDataHelper.GetImageMap( SotClipboardFormatId::SVIM, aImageMap ) )
+ {
+ SvxGalleryDrawModel aModel;
+
+ if( aModel.GetModel() )
+ {
+ SdrPage* pPage = aModel.GetModel()->GetPage(0);
+ SdrGrafObj* pGrafObj = new SdrGrafObj(*aModel.GetModel(), *pGraphic );
+
+ pGrafObj->AppendUserData( std::unique_ptr<SdrObjUserData>(new SgaIMapInfo( aImageMap )) );
+ pPage->InsertObject( pGrafObj );
+ bRet = InsertModel( *aModel.GetModel(), nInsertPos );
+ }
+ }
+ }
+
+ if( !bRet )
+ bRet = InsertGraphic( *pGraphic, nInsertPos );
+ }
+ }
+
+ return bRet;
+}
+
+void GalleryTheme::CopyToClipboard(sal_uInt32 nPos)
+{
+ GalleryTransferable* pTransferable = new GalleryTransferable( this, nPos, false );
+ pTransferable->CopyToClipboard(GetSystemClipboard());
+}
+
+SvStream& GalleryTheme::WriteData( SvStream& rOStm ) const
+{
+ const INetURLObject aRelURL1( GetParent()->GetRelativeURL() );
+ const INetURLObject aRelURL2( GetParent()->GetUserURL() );
+ sal_uInt32 nCount = GetObjectCount();
+ bool bRel;
+
+ rOStm.WriteUInt16( 0x0004 );
+ write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStm, pThm->GetThemeName(), RTL_TEXTENCODING_UTF8);
+ rOStm.WriteUInt32( nCount ).WriteUInt16( osl_getThreadTextEncoding() );
+
+ for( sal_uInt32 i = 0; i < nCount; i++ )
+ {
+ const GalleryObject* pObj = ImplGetGalleryObject( i );
+ OUString aPath;
+
+ if( SgaObjKind::SvDraw == pObj->eObjKind )
+ {
+ aPath = GetSvDrawStreamNameFromURL( pObj->aURL );
+ bRel = false;
+ }
+ else
+ {
+ aPath = pObj->aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
+ aPath = aPath.copy( 0, std::min(aRelURL1.GetMainURL( INetURLObject::DecodeMechanism::NONE ).getLength(), aPath.getLength()) );
+ bRel = aPath == aRelURL1.GetMainURL( INetURLObject::DecodeMechanism::NONE );
+
+ if( bRel && ( pObj->aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ).getLength() > ( aRelURL1.GetMainURL( INetURLObject::DecodeMechanism::NONE ).getLength() + 1 ) ) )
+ {
+ aPath = pObj->aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
+ aPath = aPath.copy( std::min(aRelURL1.GetMainURL( INetURLObject::DecodeMechanism::NONE ).getLength(), aPath.getLength()) );
+ }
+ else
+ {
+ aPath = pObj->aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
+ aPath = aPath.copy( 0, std::min(aRelURL2.GetMainURL( INetURLObject::DecodeMechanism::NONE ).getLength(), aPath.getLength()) );
+ bRel = aPath == aRelURL2.GetMainURL( INetURLObject::DecodeMechanism::NONE );
+
+ if( bRel && ( pObj->aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ).getLength() > ( aRelURL2.GetMainURL( INetURLObject::DecodeMechanism::NONE ).getLength() + 1 ) ) )
+ {
+ aPath = pObj->aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
+ aPath = aPath.copy( std::min(aRelURL2.GetMainURL( INetURLObject::DecodeMechanism::NONE ).getLength(), aPath.getLength()) );
+ }
+ else
+ aPath = pObj->aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
+ }
+ }
+
+ if ( !m_aDestDir.isEmpty() )
+ {
+ bool aFound = aPath.indexOf(m_aDestDir) != -1;
+ aPath = aPath.replaceFirst(m_aDestDir, "");
+ if ( aFound )
+ bRel = m_bDestDirRelative;
+ else
+ SAL_WARN( "svx", "failed to replace destdir of '"
+ << m_aDestDir << "' in '" << aPath << "'");
+ }
+
+ rOStm.WriteBool( bRel );
+ write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStm, aPath, RTL_TEXTENCODING_UTF8);
+ rOStm.WriteUInt32( pObj->nOffset ).WriteUInt16( static_cast<sal_uInt16>(pObj->eObjKind) );
+ }
+
+ // more recently, a 512-byte reserve buffer is written,
+ // to recognize them two sal_uInt32-Ids will be written.
+ rOStm.WriteUInt32( COMPAT_FORMAT( 'G', 'A', 'L', 'R' ) ).WriteUInt32( COMPAT_FORMAT( 'E', 'S', 'R', 'V' ) );
+
+ const long nReservePos = rOStm.Tell();
+ std::unique_ptr<VersionCompat> pCompat(new VersionCompat( rOStm, StreamMode::WRITE, 2 ));
+
+ rOStm.WriteUInt32( GetId() ).WriteBool( pThm->IsNameFromResource() ); // From version 2 and up
+
+ pCompat.reset();
+
+ // Fill the rest of the buffer.
+ const long nRest = std::max( 512L - ( static_cast<long>(rOStm.Tell()) - nReservePos ), 0L );
+
+ if( nRest )
+ {
+ std::unique_ptr<char[]> pReserve(new char[ nRest ]);
+ memset( pReserve.get(), 0, nRest );
+ rOStm.WriteBytes(pReserve.get(), nRest);
+ }
+
+ return rOStm;
+}
+
+SvStream& GalleryTheme::ReadData( SvStream& rIStm )
+{
+ sal_uInt32 nCount;
+ sal_uInt16 nVersion;
+
+ rIStm.ReadUInt16( nVersion );
+ read_uInt16_lenPrefixed_uInt8s_ToOString(rIStm);
+ rIStm.ReadUInt32( nCount );
+
+ if( nVersion >= 0x0004 )
+ {
+ sal_uInt16 nTmp16;
+ rIStm.ReadUInt16( nTmp16 );
+ }
+
+ if( nCount <= ( 1 << 14 ) )
+ {
+ INetURLObject aRelURL1( GetParent()->GetRelativeURL() );
+ INetURLObject aRelURL2( GetParent()->GetUserURL() );
+ sal_uInt32 nId1, nId2;
+ bool bRel;
+
+ for(auto & i : aObjectList)
+ {
+ GalleryObject* pObj = i.get();
+ Broadcast( GalleryHint( GalleryHintType::CLOSE_OBJECT, GetName(), pObj ) );
+ i.reset();
+ }
+ aObjectList.clear();
+
+ for( sal_uInt32 i = 0; i < nCount; i++ )
+ {
+ std::unique_ptr<GalleryObject> pObj(new GalleryObject);
+
+ OUString aFileName;
+ OUString aPath;
+ sal_uInt16 nTemp;
+
+ rIStm.ReadCharAsBool( bRel );
+ OString aTempFileName = read_uInt16_lenPrefixed_uInt8s_ToOString(rIStm);
+ rIStm.ReadUInt32( pObj->nOffset );
+ rIStm.ReadUInt16( nTemp ); pObj->eObjKind = static_cast<SgaObjKind>(nTemp);
+
+ aFileName = OStringToOUString(aTempFileName, osl_getThreadTextEncoding());
+
+ if( bRel )
+ {
+ aFileName = aFileName.replaceAll( "\\", "/" );
+ aPath = aRelURL1.GetMainURL( INetURLObject::DecodeMechanism::NONE );
+
+ if( aFileName[ 0 ] != '/' )
+ aPath += "/";
+
+ aPath += aFileName;
+
+ pObj->aURL = INetURLObject( aPath );
+
+ if( !FileExists( pObj->aURL ) )
+ {
+ aPath = aRelURL2.GetMainURL( INetURLObject::DecodeMechanism::NONE );
+
+ if( aFileName[0] != '/' )
+ aPath += "/";
+
+ aPath += aFileName;
+
+ // assign this URL, even in the case it is not valid (#94482)
+ pObj->aURL = INetURLObject( aPath );
+ }
+ }
+ else
+ {
+ if( SgaObjKind::SvDraw == pObj->eObjKind )
+ {
+ OUString aDummyURL = "gallery/svdraw/" + aFileName;
+ pObj->aURL = INetURLObject( aDummyURL, INetProtocol::PrivSoffice );
+ }
+ else
+ {
+ OUString aLocalURL;
+
+ pObj->aURL = INetURLObject( aFileName );
+
+ if( ( pObj->aURL.GetProtocol() == INetProtocol::NotValid ) &&
+ osl::FileBase::getFileURLFromSystemPath( aFileName, aLocalURL ) == osl::FileBase::E_None )
+ {
+ pObj->aURL = INetURLObject( aLocalURL );
+ }
+ }
+ }
+ aObjectList.push_back( std::move(pObj) );
+ }
+
+ rIStm.ReadUInt32( nId1 ).ReadUInt32( nId2 );
+
+ // In newer versions a 512 byte reserve buffer is located at the end,
+ // the data is located at the beginning of this buffer and are clamped
+ // by a VersionCompat.
+ if( !rIStm.eof() &&
+ nId1 == COMPAT_FORMAT( 'G', 'A', 'L', 'R' ) &&
+ nId2 == COMPAT_FORMAT( 'E', 'S', 'R', 'V' ) )
+ {
+ VersionCompat aCompat( rIStm, StreamMode::READ );
+ sal_uInt32 nTemp32;
+ bool bThemeNameFromResource = false;
+
+ rIStm.ReadUInt32( nTemp32 );
+
+ if( aCompat.GetVersion() >= 2 )
+ {
+ rIStm.ReadCharAsBool( bThemeNameFromResource );
+ }
+
+ SetId( nTemp32, bThemeNameFromResource );
+ }
+ }
+ else
+ rIStm.SetError( SVSTREAM_READ_ERROR );
+
+ ImplSetModified( false );
+
+ return rIStm;
+}
+
+SvStream& WriteGalleryTheme( SvStream& rOut, const GalleryTheme& rTheme )
+{
+ return rTheme.WriteData( rOut );
+}
+
+SvStream& ReadGalleryTheme( SvStream& rIn, GalleryTheme& rTheme )
+{
+ return rTheme.ReadData( rIn );
+}
+
+void GalleryTheme::ImplSetModified( bool bModified )
+{
+ pThm->SetModified(bModified);
+}
+
+const INetURLObject& GalleryTheme::GetThmURL() const { return pThm->GetThmURL(); }
+const INetURLObject& GalleryTheme::GetSdgURL() const { return pThm->GetSdgURL(); }
+const INetURLObject& GalleryTheme::GetSdvURL() const { return pThm->GetSdvURL(); }
+const INetURLObject& GalleryTheme::GetStrURL() const { return pThm->GetStrURL(); }
+sal_uInt32 GalleryTheme::GetId() const { return pThm->GetId(); }
+void GalleryTheme::SetId( sal_uInt32 nNewId, bool bResetThemeName ) { pThm->SetId( nNewId, bResetThemeName ); }
+bool GalleryTheme::IsReadOnly() const { return pThm->IsReadOnly(); }
+bool GalleryTheme::IsDefault() const { return pThm->IsDefault(); }
+
+const tools::SvRef<SotStorage>& GalleryTheme::GetSvDrawStorage() const
+{
+ return aSvDrawStorageRef;
+}
+
+const OUString& GalleryTheme::GetName() const { return pThm->GetThemeName(); }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */