Best effort to create directories of SAL_LOG_FILE
[LibreOffice.git] / svx / source / gallery2 / galleryfilestorage.cxx
blobbef365a0060cc74c3700fc6b1c50ce5f5b02d1d3
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 <svx/unomodel.hxx>
21 #include <svx/fmmodel.hxx>
22 #include <svx/galtheme.hxx>
23 #include <galobj.hxx>
24 #include <galleryfilestorage.hxx>
25 #include <svx/galleryobjectcollection.hxx>
26 #include <svx/gallery1.hxx>
27 #include "codec.hxx"
28 #include "gallerydrawmodel.hxx"
29 #include <vcl/cvtgrf.hxx>
30 #include <vcl/filter/SvmWriter.hxx>
32 #include <sal/log.hxx>
34 #include <com/sun/star/ucb/ContentCreationException.hpp>
35 #include <com/sun/star/sdbc/XResultSet.hpp>
36 #include <com/sun/star/ucb/XContentAccess.hpp>
37 #include <comphelper/fileformat.h>
38 #include <comphelper/graphicmimetype.hxx>
39 #include <comphelper/processfactory.hxx>
40 #include <tools/urlobj.hxx>
41 #include <comphelper/diagnose_ex.hxx>
42 #include <tools/datetime.hxx>
43 #include <unotools/datetime.hxx>
44 #include <unotools/ucbstreamhelper.hxx>
45 #include <unotools/streamwrap.hxx>
46 #include <unotools/tempfile.hxx>
47 #include <ucbhelper/content.hxx>
48 #include <tools/vcompat.hxx>
50 using namespace ::com::sun::star;
52 GalleryFileStorage::GalleryFileStorage(
53 const GalleryStorageLocations& rGalleryBinaryStorageLocations,
54 GalleryObjectCollection& rGalleryObjectCollection, bool bReadOnly)
55 : maGalleryStorageLocations(rGalleryBinaryStorageLocations)
56 , mrGalleryObjectCollection(rGalleryObjectCollection)
57 , mbReadOnly(bReadOnly)
58 , m_bDestDirRelative(false)
60 ImplCreateSvDrawStorage();
63 GalleryFileStorage::~GalleryFileStorage() { clearSotStorage(); }
65 void GalleryFileStorage::setDestDir(const OUString& rDestDir, bool bRelative)
67 m_aDestDir = rDestDir;
68 m_bDestDirRelative = bRelative;
71 void GalleryFileStorage::clearSotStorage() { m_aSvDrawStorageRef.clear(); }
73 void GalleryFileStorage::ImplCreateSvDrawStorage()
75 try
77 m_aSvDrawStorageRef
78 = new SotStorage(false, GetSdvURL().GetMainURL(INetURLObject::DecodeMechanism::NONE),
79 mbReadOnly ? StreamMode::READ : StreamMode::STD_READWRITE);
80 // #i50423# ReadOnly may not been set though the file can't be written (because of security reasons)
81 if ((m_aSvDrawStorageRef->GetError() != ERRCODE_NONE) && !mbReadOnly)
82 m_aSvDrawStorageRef = new SotStorage(
83 false, GetSdvURL().GetMainURL(INetURLObject::DecodeMechanism::NONE),
84 StreamMode::READ);
86 catch (const css::ucb::ContentCreationException&)
88 TOOLS_WARN_EXCEPTION("svx", "failed to open: " << GetSdvURL().GetMainURL(
89 INetURLObject::DecodeMechanism::NONE)
90 << "due to");
94 const rtl::Reference<SotStorage>& GalleryFileStorage::GetSvDrawStorage() const
96 return m_aSvDrawStorageRef;
99 bool GalleryFileStorage::implWrite(const GalleryTheme& rTheme, const GalleryThemeEntry* pThm)
101 INetURLObject aPathURL(GetThmURL());
103 aPathURL.removeSegment();
104 aPathURL.removeFinalSlash();
106 DBG_ASSERT(aPathURL.GetProtocol() != INetProtocol::NotValid, "invalid URL");
108 if (FileExists(aPathURL) || CreateDir(aPathURL))
110 #ifdef UNX
111 std::unique_ptr<SvStream> pOStm(::utl::UcbStreamHelper::CreateStream(
112 GetThmURL().GetMainURL(INetURLObject::DecodeMechanism::NONE),
113 StreamMode::WRITE | StreamMode::COPY_ON_SYMLINK | StreamMode::TRUNC));
114 #else
115 std::unique_ptr<SvStream> pOStm(::utl::UcbStreamHelper::CreateStream(
116 GetThmURL().GetMainURL(INetURLObject::DecodeMechanism::NONE),
117 StreamMode::WRITE | StreamMode::TRUNC));
118 #endif
120 if (pOStm)
122 writeGalleryTheme(*pOStm, rTheme, pThm);
123 pOStm.reset();
124 return true;
127 return false;
129 return true;
132 void GalleryFileStorage::insertObject(const SgaObject& rObj, GalleryObject* pFoundEntry,
133 sal_uInt32 nInsertPos)
135 if (pFoundEntry)
137 GalleryObject aNewEntry;
139 // update title of new object if necessary
140 if (rObj.GetTitle().isEmpty())
142 std::unique_ptr<SgaObject> pOldObj(implReadSgaObject(pFoundEntry));
144 if (pOldObj)
146 const_cast<SgaObject&>(rObj).SetTitle(pOldObj->GetTitle());
149 else if (rObj.GetTitle() == "__<empty>__")
150 const_cast<SgaObject&>(rObj).SetTitle("");
152 implWriteSgaObject(rObj, nInsertPos, &aNewEntry);
153 pFoundEntry->nOffset = aNewEntry.nOffset;
155 else
156 implWriteSgaObject(rObj, nInsertPos, nullptr);
159 void GalleryFileStorage::removeObject(const std::unique_ptr<GalleryObject>& pEntry)
161 if (mrGalleryObjectCollection.getObjectList().empty())
162 KillFile(GetSdgURL());
164 if (SgaObjKind::SvDraw == pEntry->eObjKind)
165 GetSvDrawStorage()->Remove(
166 pEntry->m_oStorageUrl->GetMainURL(INetURLObject::DecodeMechanism::NONE));
169 std::unique_ptr<SgaObject> GalleryFileStorage::implReadSgaObject(GalleryObject const* pEntry)
171 std::unique_ptr<SgaObject> pSgaObj;
173 if (pEntry)
175 std::unique_ptr<SvStream> pIStm(::utl::UcbStreamHelper::CreateStream(
176 GetSdgURL().GetMainURL(INetURLObject::DecodeMechanism::NONE), StreamMode::READ));
178 if (pIStm)
180 sal_uInt32 nInventor;
182 // Check to ensure that the file is a valid SGA file
183 pIStm->Seek(pEntry->nOffset);
184 pIStm->ReadUInt32(nInventor);
186 if (nInventor == COMPAT_FORMAT('S', 'G', 'A', '3'))
188 pIStm->Seek(pEntry->nOffset);
190 switch (pEntry->eObjKind)
192 case SgaObjKind::Bitmap:
193 pSgaObj.reset(new SgaObjectBmp());
194 break;
195 case SgaObjKind::Animation:
196 pSgaObj.reset(new SgaObjectAnim());
197 break;
198 case SgaObjKind::Inet:
199 pSgaObj.reset(new SgaObjectINet());
200 break;
201 case SgaObjKind::SvDraw:
202 pSgaObj.reset(new SgaObjectSvDraw());
203 break;
204 case SgaObjKind::Sound:
205 pSgaObj.reset(new SgaObjectSound());
206 break;
208 default:
209 break;
212 if (pSgaObj)
214 ReadSgaObject(*pIStm, *pSgaObj);
215 pSgaObj->ImplUpdateURL(*pEntry->m_oStorageUrl);
221 return pSgaObj;
224 bool GalleryFileStorage::implWriteSgaObject(const SgaObject& rObj, sal_uInt32 nPos,
225 GalleryObject* pExistentEntry)
227 std::unique_ptr<SvStream> pOStm(::utl::UcbStreamHelper::CreateStream(
228 GetSdgURL().GetMainURL(INetURLObject::DecodeMechanism::NONE), StreamMode::WRITE));
229 bool bRet = false;
231 if (pOStm)
233 const sal_uInt32 nOffset = pOStm->Seek(STREAM_SEEK_TO_END);
235 rObj.WriteData(*pOStm, m_aDestDir);
237 if (!pOStm->GetError())
239 GalleryObject* pEntry;
241 if (!pExistentEntry)
243 pEntry = new GalleryObject;
244 if (nPos < mrGalleryObjectCollection.size())
246 mrGalleryObjectCollection.getObjectList().emplace(
247 mrGalleryObjectCollection.getObjectList().begin() + nPos, pEntry);
249 else
250 mrGalleryObjectCollection.getObjectList().emplace_back(pEntry);
252 else
253 pEntry = pExistentEntry;
255 pEntry->m_oStorageUrl = rObj.GetURL();
257 pEntry->nOffset = nOffset;
258 pEntry->eObjKind = rObj.GetObjKind();
259 bRet = true;
263 return bRet;
266 bool GalleryFileStorage::readModel(const GalleryObject* pObject, SdrModel& rModel)
268 rtl::Reference<SotStorage> xSotStorage(GetSvDrawStorage());
269 bool bRet = false;
270 const INetURLObject aURL(ImplGetURL(pObject));
272 if (xSotStorage.is())
274 const OUString aStreamName(GetSvDrawStreamNameFromURL(aURL));
275 rtl::Reference<SotStorageStream> xInputStream(
276 xSotStorage->OpenSotStream(aStreamName, StreamMode::READ));
278 if (xInputStream.is() && !xInputStream->GetError())
280 xInputStream->SetBufferSize(STREAMBUF_SIZE);
281 bRet = GallerySvDrawImport(*xInputStream, rModel);
282 xInputStream->SetBufferSize(0);
285 return bRet;
288 SgaObjectSvDraw GalleryFileStorage::insertModel(const FmFormModel& rModel,
289 const INetURLObject& rUserURL)
291 INetURLObject aURL(implCreateUniqueURL(SgaObjKind::SvDraw, rUserURL));
292 rtl::Reference<SotStorage> xSotStorage(GetSvDrawStorage());
293 bool bRet = false;
295 if (xSotStorage.is())
297 const OUString aStreamName(GetSvDrawStreamNameFromURL(aURL));
298 rtl::Reference<SotStorageStream> xOutputStream(
299 xSotStorage->OpenSotStream(aStreamName, StreamMode::WRITE | StreamMode::TRUNC));
301 if (xOutputStream.is() && !xOutputStream->GetError())
303 SvMemoryStream aMemoryStream(65535, 65535);
304 FmFormModel* pFormModel = const_cast<FmFormModel*>(&rModel);
306 pFormModel->BurnInStyleSheetAttributes();
309 uno::Reference<io::XOutputStream> xDocOut(
310 new utl::OOutputStreamWrapper(aMemoryStream));
312 if (xDocOut.is())
313 (void)SvxDrawingLayerExport(pFormModel, xDocOut);
316 aMemoryStream.Seek(0);
318 xOutputStream->SetBufferSize(16348);
319 GalleryCodec aCodec(*xOutputStream);
320 aCodec.Write(aMemoryStream);
322 xOutputStream->SetBufferSize(0);
323 xOutputStream->Commit();
324 bRet = !xOutputStream->GetError();
327 if (bRet)
329 SgaObjectSvDraw aObjSvDraw(rModel, aURL);
330 return aObjSvDraw;
332 return SgaObjectSvDraw();
335 bool GalleryFileStorage::readModelStream(const GalleryObject* pObject,
336 tools::SvRef<SotTempStream> const& rxModelStream)
338 const INetURLObject aURL(ImplGetURL(pObject));
339 rtl::Reference<SotStorage> xSotStorage(GetSvDrawStorage());
340 bool bRet = false;
342 if (xSotStorage.is())
344 const OUString aStreamName(GetSvDrawStreamNameFromURL(aURL));
345 rtl::Reference<SotStorageStream> xInputStream(
346 xSotStorage->OpenSotStream(aStreamName, StreamMode::READ));
348 if (xInputStream.is() && !xInputStream->GetError())
350 sal_uInt32 nVersion = 0;
352 xInputStream->SetBufferSize(16348);
354 if (GalleryCodec::IsCoded(*xInputStream, nVersion))
356 SvxGalleryDrawModel aModel;
358 if (aModel.GetModel())
360 if (GallerySvDrawImport(*xInputStream, *aModel.GetModel()))
362 aModel.GetModel()->BurnInStyleSheetAttributes();
365 uno::Reference<io::XOutputStream> xDocOut(
366 new utl::OOutputStreamWrapper(*rxModelStream));
368 SvxDrawingLayerExport(aModel.GetModel(), xDocOut);
372 bRet = (rxModelStream->GetError() == ERRCODE_NONE);
376 xInputStream->SetBufferSize(0);
379 return bRet;
382 SgaObjectSvDraw
383 GalleryFileStorage::insertModelStream(const tools::SvRef<SotTempStream>& rxModelStream,
384 const INetURLObject& rUserURL)
386 INetURLObject aURL(implCreateUniqueURL(SgaObjKind::SvDraw, rUserURL));
387 rtl::Reference<SotStorage> xSotStorage(GetSvDrawStorage());
389 if (xSotStorage.is())
391 const OUString aStreamName(GetSvDrawStreamNameFromURL(aURL));
392 rtl::Reference<SotStorageStream> xOutputStream(
393 xSotStorage->OpenSotStream(aStreamName, StreamMode::WRITE | StreamMode::TRUNC));
395 if (xOutputStream.is() && !xOutputStream->GetError())
397 GalleryCodec aCodec(*xOutputStream);
399 xOutputStream->SetBufferSize(16348);
400 aCodec.Write(*rxModelStream);
402 if (!xOutputStream->GetError())
404 xOutputStream->Seek(0);
405 SgaObjectSvDraw aObjSvDraw(*xOutputStream, aURL);
406 return aObjSvDraw;
410 return SgaObjectSvDraw();
413 INetURLObject GalleryFileStorage::implCreateUniqueURL(SgaObjKind eObjKind,
414 const INetURLObject& rUserURL,
415 ConvertDataFormat nFormat)
417 INetURLObject aDir(rUserURL);
418 INetURLObject aInfoFileURL(rUserURL);
419 INetURLObject aNewURL;
420 sal_uInt32 nNextNumber = 1999;
421 char const* pExt = nullptr;
422 bool bExists;
424 aDir.Append(u"dragdrop");
425 CreateDir(aDir);
427 aInfoFileURL.Append(u"sdddndx1");
429 // read next possible number
430 if (FileExists(aInfoFileURL))
432 std::unique_ptr<SvStream> pIStm(::utl::UcbStreamHelper::CreateStream(
433 aInfoFileURL.GetMainURL(INetURLObject::DecodeMechanism::NONE), StreamMode::READ));
435 if (pIStm)
437 pIStm->ReadUInt32(nNextNumber);
441 pExt = comphelper::GraphicMimeTypeHelper::GetExtensionForConvertDataFormat(nFormat);
445 // get URL
446 if (SgaObjKind::SvDraw == eObjKind)
448 OUString aFileName = "gallery/svdraw/dd" + OUString::number(++nNextNumber % 99999999);
449 aNewURL = INetURLObject(aFileName, INetProtocol::PrivSoffice);
451 bExists = false;
453 for (auto const& pObject : mrGalleryObjectCollection.getObjectList())
455 if (*pObject->m_oStorageUrl == aNewURL)
457 bExists = true;
458 break;
462 else
464 OUString aFileName = "dd" + OUString::number(++nNextNumber % 999999);
466 if (pExt)
467 aFileName += OUString(pExt, strlen(pExt), RTL_TEXTENCODING_ASCII_US);
469 aNewURL = aDir;
470 aNewURL.Append(aFileName);
472 bExists = FileExists(aNewURL);
474 } while (bExists);
476 // write updated number
477 std::unique_ptr<SvStream> pOStm(::utl::UcbStreamHelper::CreateStream(
478 aInfoFileURL.GetMainURL(INetURLObject::DecodeMechanism::NONE), StreamMode::WRITE));
480 if (pOStm)
482 pOStm->WriteUInt32(nNextNumber);
485 return aNewURL;
488 SgaObjectBmp GalleryFileStorage::insertGraphic(const Graphic& rGraphic, const GfxLink& aGfxLink,
489 const ConvertDataFormat& nExportFormat,
490 const INetURLObject& rUserURL)
492 const INetURLObject aURL(implCreateUniqueURL(SgaObjKind::Bitmap, rUserURL, nExportFormat));
493 std::unique_ptr<SvStream> pOStm(
494 ::utl::UcbStreamHelper::CreateStream(aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE),
495 StreamMode::WRITE | StreamMode::TRUNC));
496 bool bRet = false;
498 if (pOStm)
500 pOStm->SetVersion(SOFFICE_FILEFORMAT_50);
502 if (ConvertDataFormat::SVM == nExportFormat)
504 GDIMetaFile aMtf(rGraphic.GetGDIMetaFile());
506 SvmWriter aWriter(*pOStm);
507 aWriter.Write(aMtf);
508 bRet = (pOStm->GetError() == ERRCODE_NONE);
510 else
512 if (aGfxLink.GetDataSize() && aGfxLink.GetData())
514 pOStm->WriteBytes(aGfxLink.GetData(), aGfxLink.GetDataSize());
515 bRet = (pOStm->GetError() == ERRCODE_NONE);
517 else
518 bRet = (GraphicConverter::Export(*pOStm, rGraphic, nExportFormat) == ERRCODE_NONE);
521 pOStm.reset();
523 if (bRet)
525 const SgaObjectBmp aObjBmp(aURL);
526 return aObjBmp;
528 return SgaObjectBmp();
531 SgaObjectSvDraw GalleryFileStorage::updateSvDrawObject(const GalleryObject* pEntry)
533 if (GetSvDrawStorage().is())
535 const OUString aStmName(GetSvDrawStreamNameFromURL(*pEntry->m_oStorageUrl));
536 rtl::Reference<SotStorageStream> pIStm
537 = GetSvDrawStorage()->OpenSotStream(aStmName, StreamMode::READ);
539 if (pIStm.is() && !pIStm->GetError())
541 pIStm->SetBufferSize(16384);
543 SgaObjectSvDraw aNewObj(*pIStm, *pEntry->m_oStorageUrl);
545 pIStm->SetBufferSize(0);
547 return aNewObj;
550 return SgaObjectSvDraw();
553 void GalleryFileStorage::updateTheme()
555 ::utl::TempFileNamed aTmp;
556 INetURLObject aInURL(GetSdgURL());
557 INetURLObject aTmpURL(aTmp.GetURL());
559 DBG_ASSERT(aInURL.GetProtocol() != INetProtocol::NotValid, "invalid URL");
560 DBG_ASSERT(aTmpURL.GetProtocol() != INetProtocol::NotValid, "invalid URL");
562 std::unique_ptr<SvStream> pIStm(::utl::UcbStreamHelper::CreateStream(
563 aInURL.GetMainURL(INetURLObject::DecodeMechanism::NONE), StreamMode::READ));
564 std::unique_ptr<SvStream> pTmpStm(::utl::UcbStreamHelper::CreateStream(
565 aTmpURL.GetMainURL(INetURLObject::DecodeMechanism::NONE),
566 StreamMode::WRITE | StreamMode::TRUNC));
568 if (pIStm && pTmpStm)
570 for (const auto& i : mrGalleryObjectCollection.getObjectList())
572 GalleryObject* pEntry = i.get();
573 std::unique_ptr<SgaObject> pObj;
575 switch (pEntry->eObjKind)
577 case SgaObjKind::Bitmap:
578 pObj.reset(new SgaObjectBmp());
579 break;
580 case SgaObjKind::Animation:
581 pObj.reset(new SgaObjectAnim());
582 break;
583 case SgaObjKind::Inet:
584 pObj.reset(new SgaObjectINet());
585 break;
586 case SgaObjKind::SvDraw:
587 pObj.reset(new SgaObjectSvDraw());
588 break;
589 case SgaObjKind::Sound:
590 pObj.reset(new SgaObjectSound());
591 break;
593 default:
594 break;
597 if (pObj)
599 pIStm->Seek(pEntry->nOffset);
600 ReadSgaObject(*pIStm, *pObj);
601 pEntry->nOffset = pTmpStm->Tell();
602 WriteSgaObject(*pTmpStm, *pObj);
606 else
608 OSL_FAIL("File(s) could not be opened");
611 pIStm.reset();
612 pTmpStm.reset();
614 CopyFile(aTmpURL, aInURL);
615 KillFile(aTmpURL);
617 ErrCode nStorErr = ERRCODE_NONE;
621 rtl::Reference<SotStorage> aTempStorageRef(
622 new SotStorage(false, aTmpURL.GetMainURL(INetURLObject::DecodeMechanism::NONE),
623 StreamMode::STD_READWRITE));
624 GetSvDrawStorage()->CopyTo(aTempStorageRef.get());
625 nStorErr = GetSvDrawStorage()->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 clearSotStorage();
638 CopyFile(aTmpURL, GetSdvURL());
639 ImplCreateSvDrawStorage();
642 KillFile(aTmpURL);
645 void GalleryFileStorage::insertFileOrDirURL(const INetURLObject& rFileOrDirURL,
646 std::vector<INetURLObject>& rURLVector)
648 INetURLObject aURL;
651 ::ucbhelper::Content aCnt(rFileOrDirURL.GetMainURL(INetURLObject::DecodeMechanism::NONE),
652 uno::Reference<ucb::XCommandEnvironment>(),
653 comphelper::getProcessComponentContext());
654 bool bFolder = false;
656 aCnt.getPropertyValue("IsFolder") >>= bFolder;
658 if (bFolder)
660 uno::Sequence<OUString> aProps{ "Url" };
661 uno::Reference<sdbc::XResultSet> xResultSet(
662 aCnt.createCursor(aProps, ::ucbhelper::INCLUDE_DOCUMENTS_ONLY));
663 uno::Reference<ucb::XContentAccess> xContentAccess(xResultSet, uno::UNO_QUERY);
664 if (xContentAccess.is())
666 while (xResultSet->next())
668 aURL.SetSmartURL(xContentAccess->queryContentIdentifierString());
669 rURLVector.push_back(aURL);
673 else
674 rURLVector.push_back(rFileOrDirURL);
676 catch (const ucb::ContentCreationException&)
679 catch (const uno::RuntimeException&)
682 catch (const uno::Exception&)
687 SvStream& GalleryFileStorage::writeGalleryTheme(SvStream& rOStm, const GalleryTheme& rTheme,
688 const GalleryThemeEntry* pThm)
690 const INetURLObject rRelURL1 = rTheme.GetParent()->GetRelativeURL();
691 const INetURLObject rRelURL2 = rTheme.GetParent()->GetUserURL();
692 const sal_uInt32 rId = rTheme.GetId();
693 sal_uInt32 nCount = mrGalleryObjectCollection.size();
694 bool bRel;
696 rOStm.WriteUInt16(0x0004);
697 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStm, pThm->GetThemeName(),
698 RTL_TEXTENCODING_UTF8);
699 rOStm.WriteUInt32(nCount);
700 rOStm.WriteUInt16(RTL_TEXTENCODING_UTF8); // unused on reading
702 for (sal_uInt32 i = 0; i < nCount; i++)
704 const GalleryObject* pObj = mrGalleryObjectCollection.getForPosition(i);
705 OUString aPath;
707 if (SgaObjKind::SvDraw == pObj->eObjKind)
709 aPath = GetSvDrawStreamNameFromURL(*pObj->m_oStorageUrl);
710 bRel = false;
712 else
714 aPath = pObj->m_oStorageUrl->GetMainURL(INetURLObject::DecodeMechanism::NONE);
715 aPath = aPath.copy(
716 0, std::min(rRelURL1.GetMainURL(INetURLObject::DecodeMechanism::NONE).getLength(),
717 aPath.getLength()));
718 bRel = aPath == rRelURL1.GetMainURL(INetURLObject::DecodeMechanism::NONE);
720 if (bRel
721 && (pObj->m_oStorageUrl->GetMainURL(INetURLObject::DecodeMechanism::NONE)
722 .getLength()
723 > (rRelURL1.GetMainURL(INetURLObject::DecodeMechanism::NONE).getLength() + 1)))
725 aPath = pObj->m_oStorageUrl->GetMainURL(INetURLObject::DecodeMechanism::NONE);
726 aPath = aPath.copy(
727 std::min(rRelURL1.GetMainURL(INetURLObject::DecodeMechanism::NONE).getLength(),
728 aPath.getLength()));
730 else
732 aPath = pObj->m_oStorageUrl->GetMainURL(INetURLObject::DecodeMechanism::NONE);
733 aPath = aPath.copy(
735 std::min(rRelURL2.GetMainURL(INetURLObject::DecodeMechanism::NONE).getLength(),
736 aPath.getLength()));
737 bRel = aPath == rRelURL2.GetMainURL(INetURLObject::DecodeMechanism::NONE);
739 if (bRel
740 && (pObj->m_oStorageUrl->GetMainURL(INetURLObject::DecodeMechanism::NONE)
741 .getLength()
742 > (rRelURL2.GetMainURL(INetURLObject::DecodeMechanism::NONE).getLength()
743 + 1)))
745 aPath = pObj->m_oStorageUrl->GetMainURL(INetURLObject::DecodeMechanism::NONE);
746 aPath = aPath.copy(std::min(
747 rRelURL2.GetMainURL(INetURLObject::DecodeMechanism::NONE).getLength(),
748 aPath.getLength()));
750 else
751 aPath = pObj->m_oStorageUrl->GetMainURL(INetURLObject::DecodeMechanism::NONE);
755 if (!m_aDestDir.isEmpty())
757 bool aFound = aPath.indexOf(m_aDestDir) != -1;
758 aPath = aPath.replaceFirst(m_aDestDir, "");
759 if (aFound)
760 bRel = m_bDestDirRelative;
761 else
762 SAL_WARN("svx", "failed to replace destdir of '" << m_aDestDir << "' in '" << aPath
763 << "'");
766 rOStm.WriteBool(bRel);
767 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStm, aPath, RTL_TEXTENCODING_UTF8);
768 rOStm.WriteUInt32(pObj->nOffset).WriteUInt16(static_cast<sal_uInt16>(pObj->eObjKind));
771 // more recently, a 512-byte reserve buffer is written,
772 // to recognize them two sal_uInt32-Ids will be written.
773 rOStm.WriteUInt32(COMPAT_FORMAT('G', 'A', 'L', 'R'))
774 .WriteUInt32(COMPAT_FORMAT('E', 'S', 'R', 'V'));
776 const sal_uInt64 nReservePos = rOStm.Tell();
777 std::unique_ptr<VersionCompatWrite> pCompat(new VersionCompatWrite(rOStm, 2));
779 rOStm.WriteUInt32(rId).WriteBool(pThm->IsNameFromResource()); // From version 2 and up
781 pCompat.reset();
783 // Fill the rest of the buffer.
784 const tools::Long nRest
785 = std::max(tools::Long(512 - (rOStm.Tell() - nReservePos)), tools::Long(0));
787 if (nRest)
789 std::unique_ptr<char[]> pReserve(new char[nRest]);
790 memset(pReserve.get(), 0, nRest);
791 rOStm.WriteBytes(pReserve.get(), nRest);
794 return rOStm;
797 DateTime GalleryFileStorage::getModificationDate() const
799 ::ucbhelper::Content aCnt(GetThmURL().GetMainURL(INetURLObject::DecodeMechanism::NONE),
800 uno::Reference<ucb::XCommandEnvironment>(),
801 comphelper::getProcessComponentContext());
802 util::DateTime aDateTimeModified;
803 DateTime aDateTime(DateTime::EMPTY);
805 aCnt.getPropertyValue("DateModified") >>= aDateTimeModified;
806 ::utl::typeConvert(aDateTimeModified, aDateTime);
808 return aDateTime;
811 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */