1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20 #include <svx/unomodel.hxx>
21 #include <svx/fmmodel.hxx>
22 #include <galobj.hxx>
23 #include <svx/gallerybinaryengine.hxx>
24 #include <svx/galleryobjectcollection.hxx>
25 #include <svx/gallery1.hxx>
26 #include <galleryobjectbinarystorage.hxx>
27 #include <osl/thread.hxx>
28 #include "codec.hxx"
29 #include "gallerydrawmodel.hxx"
30 #include <vcl/cvtgrf.hxx>
31
32 #include <sal/log.hxx>
33
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 <tools/diagnose_ex.h>
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>
49
50 using namespace ::com::sun::star;
51
GalleryBinaryEngine(const GalleryBinaryStorageLocations & rGalleryBinaryStorageLocations,GalleryObjectCollection & rGalleryObjectCollection,bool bReadOnly)52 GalleryBinaryEngine::GalleryBinaryEngine(
53 const GalleryBinaryStorageLocations& rGalleryBinaryStorageLocations,
54 GalleryObjectCollection& rGalleryObjectCollection, bool bReadOnly)
55 : maGalleryStorageLocations(rGalleryBinaryStorageLocations)
56 , mrGalleryObjectCollection(rGalleryObjectCollection)
57 , mbReadOnly(bReadOnly)
58 , m_bDestDirRelative(false)
59 {
60 ImplCreateSvDrawStorage();
61 }
62
~GalleryBinaryEngine()63 GalleryBinaryEngine::~GalleryBinaryEngine() { clearSotStorage(); }
64
setDestDir(const OUString & rDestDir,bool bRelative)65 void GalleryBinaryEngine::setDestDir(const OUString& rDestDir, bool bRelative)
66 {
67 m_aDestDir = rDestDir;
68 m_bDestDirRelative = bRelative;
69 }
70
clearSotStorage()71 void GalleryBinaryEngine::clearSotStorage() { m_aSvDrawStorageRef.clear(); }
72
ImplCreateSvDrawStorage()73 void GalleryBinaryEngine::ImplCreateSvDrawStorage()
74 {
75 try
76 {
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);
85 }
86 catch (const css::ucb::ContentCreationException&)
87 {
88 TOOLS_WARN_EXCEPTION("svx", "failed to open: " << GetSdvURL().GetMainURL(
89 INetURLObject::DecodeMechanism::NONE)
90 << "due to");
91 }
92 }
93
GetSvDrawStorage() const94 const tools::SvRef<SotStorage>& GalleryBinaryEngine::GetSvDrawStorage() const
95 {
96 return m_aSvDrawStorageRef;
97 }
98
implWrite(const GalleryTheme & rTheme,const GalleryThemeEntry * pThm)99 bool GalleryBinaryEngine::implWrite(const GalleryTheme& rTheme, const GalleryThemeEntry* pThm)
100 {
101 INetURLObject aPathURL(GetThmURL());
102
103 aPathURL.removeSegment();
104 aPathURL.removeFinalSlash();
105
106 DBG_ASSERT(aPathURL.GetProtocol() != INetProtocol::NotValid, "invalid URL");
107
108 if (FileExists(aPathURL) || CreateDir(aPathURL))
109 {
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
119
120 if (pOStm)
121 {
122 writeGalleryTheme(*pOStm, rTheme, pThm);
123 pOStm.reset();
124 return true;
125 }
126
127 return false;
128 }
129 return true;
130 }
131
insertObject(const SgaObject & rObj,GalleryObject * pFoundEntry,sal_uInt32 nInsertPos)132 void GalleryBinaryEngine::insertObject(const SgaObject& rObj, GalleryObject* pFoundEntry,
133 sal_uInt32 nInsertPos)
134 {
135 if (pFoundEntry)
136 {
137 GalleryObject aNewEntry;
138
139 // update title of new object if necessary
140 if (rObj.GetTitle().isEmpty())
141 {
142 std::unique_ptr<SgaObject> pOldObj(implReadSgaObject(pFoundEntry));
143
144 if (pOldObj)
145 {
146 const_cast<SgaObject&>(rObj).SetTitle(pOldObj->GetTitle());
147 }
148 }
149 else if (rObj.GetTitle() == "__<empty>__")
150 const_cast<SgaObject&>(rObj).SetTitle("");
151
152 implWriteSgaObject(rObj, nInsertPos, &aNewEntry);
153 pFoundEntry->nOffset = aNewEntry.nOffset;
154 }
155 else
156 implWriteSgaObject(rObj, nInsertPos, nullptr);
157 }
158
removeObject(const std::unique_ptr<GalleryObject> & pEntry)159 void GalleryBinaryEngine::removeObject(const std::unique_ptr<GalleryObject>& pEntry)
160 {
161 if (mrGalleryObjectCollection.getObjectList().empty())
162 KillFile(GetSdgURL());
163
164 if (SgaObjKind::SvDraw == pEntry->eObjKind)
165 GetSvDrawStorage()->Remove(
166 pEntry->getURL().GetMainURL(INetURLObject::DecodeMechanism::NONE));
167 }
168
implReadSgaObject(GalleryObject const * pEntry)169 std::unique_ptr<SgaObject> GalleryBinaryEngine::implReadSgaObject(GalleryObject const* pEntry)
170 {
171 std::unique_ptr<SgaObject> pSgaObj;
172
173 if (pEntry)
174 {
175 std::unique_ptr<SvStream> pIStm(::utl::UcbStreamHelper::CreateStream(
176 GetSdgURL().GetMainURL(INetURLObject::DecodeMechanism::NONE), StreamMode::READ));
177
178 if (pIStm)
179 {
180 sal_uInt32 nInventor;
181
182 // Check to ensure that the file is a valid SGA file
183 pIStm->Seek(pEntry->nOffset);
184 pIStm->ReadUInt32(nInventor);
185
186 if (nInventor == COMPAT_FORMAT('S', 'G', 'A', '3'))
187 {
188 pIStm->Seek(pEntry->nOffset);
189
190 switch (pEntry->eObjKind)
191 {
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;
207
208 default:
209 break;
210 }
211
212 if (pSgaObj)
213 {
214 ReadSgaObject(*pIStm, *pSgaObj);
215 pSgaObj->ImplUpdateURL(pEntry->getURL());
216 }
217 }
218 }
219 }
220
221 return pSgaObj;
222 }
223
implWriteSgaObject(const SgaObject & rObj,sal_uInt32 nPos,GalleryObject * pExistentEntry)224 bool GalleryBinaryEngine::implWriteSgaObject(const SgaObject& rObj, sal_uInt32 nPos,
225 GalleryObject* pExistentEntry)
226 {
227 std::unique_ptr<SvStream> pOStm(::utl::UcbStreamHelper::CreateStream(
228 GetSdgURL().GetMainURL(INetURLObject::DecodeMechanism::NONE), StreamMode::WRITE));
229 bool bRet = false;
230
231 if (pOStm)
232 {
233 const sal_uInt32 nOffset = pOStm->Seek(STREAM_SEEK_TO_END);
234
235 rObj.WriteData(*pOStm, m_aDestDir);
236
237 if (!pOStm->GetError())
238 {
239 GalleryObject* pEntry;
240
241 if (!pExistentEntry)
242 {
243 pEntry = new GalleryObject;
244 if (nPos < mrGalleryObjectCollection.size())
245 {
246 mrGalleryObjectCollection.getObjectList().emplace(
247 mrGalleryObjectCollection.getObjectList().begin() + nPos, pEntry);
248 }
249 else
250 mrGalleryObjectCollection.getObjectList().emplace_back(pEntry);
251 }
252 else
253 pEntry = pExistentEntry;
254
255 pEntry->m_pGalleryObjectStorage = std::make_unique<GalleryObjectBinaryStorage>();
256 pEntry->m_pGalleryObjectStorage->setURL(rObj.GetURL());
257
258 pEntry->nOffset = nOffset;
259 pEntry->eObjKind = rObj.GetObjKind();
260 bRet = true;
261 }
262 }
263
264 return bRet;
265 }
266
readModel(const GalleryObject * pObject,SdrModel & rModel)267 bool GalleryBinaryEngine::readModel(const GalleryObject* pObject, SdrModel& rModel)
268 {
269 tools::SvRef<SotStorage> xSotStorage(GetSvDrawStorage());
270 bool bRet = false;
271 const INetURLObject aURL(ImplGetURL(pObject));
272
273 if (xSotStorage.is())
274 {
275 const OUString aStreamName(GetSvDrawStreamNameFromURL(aURL));
276 tools::SvRef<SotStorageStream> xInputStream(
277 xSotStorage->OpenSotStream(aStreamName, StreamMode::READ));
278
279 if (xInputStream.is() && !xInputStream->GetError())
280 {
281 xInputStream->SetBufferSize(STREAMBUF_SIZE);
282 bRet = GallerySvDrawImport(*xInputStream, rModel);
283 xInputStream->SetBufferSize(0);
284 }
285 }
286 return bRet;
287 }
288
insertModel(const FmFormModel & rModel,const INetURLObject & rUserURL)289 SgaObjectSvDraw GalleryBinaryEngine::insertModel(const FmFormModel& rModel,
290 const INetURLObject& rUserURL)
291 {
292 INetURLObject aURL(implCreateUniqueURL(SgaObjKind::SvDraw, rUserURL));
293 tools::SvRef<SotStorage> xSotStorage(GetSvDrawStorage());
294 bool bRet = false;
295
296 if (xSotStorage.is())
297 {
298 const OUString aStreamName(GetSvDrawStreamNameFromURL(aURL));
299 tools::SvRef<SotStorageStream> xOutputStream(
300 xSotStorage->OpenSotStream(aStreamName, StreamMode::WRITE | StreamMode::TRUNC));
301
302 if (xOutputStream.is() && !xOutputStream->GetError())
303 {
304 SvMemoryStream aMemoryStream(65535, 65535);
305 FmFormModel* pFormModel = const_cast<FmFormModel*>(&rModel);
306
307 pFormModel->BurnInStyleSheetAttributes();
308
309 {
310 uno::Reference<io::XOutputStream> xDocOut(
311 new utl::OOutputStreamWrapper(aMemoryStream));
312
313 if (xDocOut.is())
314 (void)SvxDrawingLayerExport(pFormModel, xDocOut);
315 }
316
317 aMemoryStream.Seek(0);
318
319 xOutputStream->SetBufferSize(16348);
320 GalleryCodec aCodec(*xOutputStream);
321 aCodec.Write(aMemoryStream);
322
323 xOutputStream->SetBufferSize(0);
324 xOutputStream->Commit();
325 bRet = !xOutputStream->GetError();
326 }
327 }
328 if (bRet)
329 {
330 SgaObjectSvDraw aObjSvDraw(rModel, aURL);
331 return aObjSvDraw;
332 }
333 return SgaObjectSvDraw();
334 }
335
readModelStream(const GalleryObject * pObject,tools::SvRef<SotTempStream> const & rxModelStream)336 bool GalleryBinaryEngine::readModelStream(const GalleryObject* pObject,
337 tools::SvRef<SotTempStream> const& rxModelStream)
338 {
339 const INetURLObject aURL(ImplGetURL(pObject));
340 tools::SvRef<SotStorage> xSotStorage(GetSvDrawStorage());
341 bool bRet = false;
342
343 if (xSotStorage.is())
344 {
345 const OUString aStreamName(GetSvDrawStreamNameFromURL(aURL));
346 tools::SvRef<SotStorageStream> xInputStream(
347 xSotStorage->OpenSotStream(aStreamName, StreamMode::READ));
348
349 if (xInputStream.is() && !xInputStream->GetError())
350 {
351 sal_uInt32 nVersion = 0;
352
353 xInputStream->SetBufferSize(16348);
354
355 if (GalleryCodec::IsCoded(*xInputStream, nVersion))
356 {
357 SvxGalleryDrawModel aModel;
358
359 if (aModel.GetModel())
360 {
361 if (GallerySvDrawImport(*xInputStream, *aModel.GetModel()))
362 {
363 aModel.GetModel()->BurnInStyleSheetAttributes();
364
365 {
366 uno::Reference<io::XOutputStream> xDocOut(
367 new utl::OOutputStreamWrapper(*rxModelStream));
368
369 SvxDrawingLayerExport(aModel.GetModel(), xDocOut);
370 }
371 }
372
373 bRet = (rxModelStream->GetError() == ERRCODE_NONE);
374 }
375 }
376
377 xInputStream->SetBufferSize(0);
378 }
379 }
380 return bRet;
381 }
382
383 SgaObjectSvDraw
insertModelStream(const tools::SvRef<SotTempStream> & rxModelStream,const INetURLObject & rUserURL)384 GalleryBinaryEngine::insertModelStream(const tools::SvRef<SotTempStream>& rxModelStream,
385 const INetURLObject& rUserURL)
386 {
387 INetURLObject aURL(implCreateUniqueURL(SgaObjKind::SvDraw, rUserURL));
388 tools::SvRef<SotStorage> xSotStorage(GetSvDrawStorage());
389
390 if (xSotStorage.is())
391 {
392 const OUString aStreamName(GetSvDrawStreamNameFromURL(aURL));
393 tools::SvRef<SotStorageStream> xOutputStream(
394 xSotStorage->OpenSotStream(aStreamName, StreamMode::WRITE | StreamMode::TRUNC));
395
396 if (xOutputStream.is() && !xOutputStream->GetError())
397 {
398 GalleryCodec aCodec(*xOutputStream);
399
400 xOutputStream->SetBufferSize(16348);
401 aCodec.Write(*rxModelStream);
402
403 if (!xOutputStream->GetError())
404 {
405 xOutputStream->Seek(0);
406 SgaObjectSvDraw aObjSvDraw(*xOutputStream, aURL);
407 return aObjSvDraw;
408 }
409 }
410 }
411 return SgaObjectSvDraw();
412 }
413
implCreateUniqueURL(SgaObjKind eObjKind,const INetURLObject & rUserURL,ConvertDataFormat nFormat)414 INetURLObject GalleryBinaryEngine::implCreateUniqueURL(SgaObjKind eObjKind,
415 const INetURLObject& rUserURL,
416 ConvertDataFormat nFormat)
417 {
418 INetURLObject aDir(rUserURL);
419 INetURLObject aInfoFileURL(rUserURL);
420 INetURLObject aNewURL;
421 sal_uInt32 nNextNumber = 1999;
422 char const* pExt = nullptr;
423 bool bExists;
424
425 aDir.Append(u"dragdrop");
426 CreateDir(aDir);
427
428 aInfoFileURL.Append(u"sdddndx1");
429
430 // read next possible number
431 if (FileExists(aInfoFileURL))
432 {
433 std::unique_ptr<SvStream> pIStm(::utl::UcbStreamHelper::CreateStream(
434 aInfoFileURL.GetMainURL(INetURLObject::DecodeMechanism::NONE), StreamMode::READ));
435
436 if (pIStm)
437 {
438 pIStm->ReadUInt32(nNextNumber);
439 }
440 }
441
442 pExt = comphelper::GraphicMimeTypeHelper::GetExtensionForConvertDataFormat(nFormat);
443
444 do
445 {
446 // get URL
447 if (SgaObjKind::SvDraw == eObjKind)
448 {
449 OUString aFileName = "gallery/svdraw/dd" + OUString::number(++nNextNumber % 99999999);
450 aNewURL = INetURLObject(aFileName, INetProtocol::PrivSoffice);
451
452 bExists = false;
453
454 for (auto const& pObject : mrGalleryObjectCollection.getObjectList())
455 {
456 if (pObject->getURL() == aNewURL)
457 {
458 bExists = true;
459 break;
460 }
461 }
462 }
463 else
464 {
465 OUString aFileName = "dd" + OUString::number(++nNextNumber % 999999);
466
467 if (pExt)
468 aFileName += OUString(pExt, strlen(pExt), RTL_TEXTENCODING_ASCII_US);
469
470 aNewURL = aDir;
471 aNewURL.Append(aFileName);
472
473 bExists = FileExists(aNewURL);
474 }
475 } while (bExists);
476
477 // write updated number
478 std::unique_ptr<SvStream> pOStm(::utl::UcbStreamHelper::CreateStream(
479 aInfoFileURL.GetMainURL(INetURLObject::DecodeMechanism::NONE), StreamMode::WRITE));
480
481 if (pOStm)
482 {
483 pOStm->WriteUInt32(nNextNumber);
484 }
485
486 return aNewURL;
487 }
488
insertGraphic(const Graphic & rGraphic,const GfxLink & aGfxLink,const ConvertDataFormat & nExportFormat,const INetURLObject & rUserURL)489 SgaObjectBmp GalleryBinaryEngine::insertGraphic(const Graphic& rGraphic, const GfxLink& aGfxLink,
490 const ConvertDataFormat& nExportFormat,
491 const INetURLObject& rUserURL)
492 {
493 const INetURLObject aURL(implCreateUniqueURL(SgaObjKind::Bitmap, rUserURL, nExportFormat));
494 std::unique_ptr<SvStream> pOStm(
495 ::utl::UcbStreamHelper::CreateStream(aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE),
496 StreamMode::WRITE | StreamMode::TRUNC));
497 bool bRet = false;
498
499 if (pOStm)
500 {
501 pOStm->SetVersion(SOFFICE_FILEFORMAT_50);
502
503 if (ConvertDataFormat::SVM == nExportFormat)
504 {
505 GDIMetaFile aMtf(rGraphic.GetGDIMetaFile());
506
507 aMtf.Write(*pOStm);
508 bRet = (pOStm->GetError() == ERRCODE_NONE);
509 }
510 else
511 {
512 if (aGfxLink.GetDataSize() && aGfxLink.GetData())
513 {
514 pOStm->WriteBytes(aGfxLink.GetData(), aGfxLink.GetDataSize());
515 bRet = (pOStm->GetError() == ERRCODE_NONE);
516 }
517 else
518 bRet = (GraphicConverter::Export(*pOStm, rGraphic, nExportFormat) == ERRCODE_NONE);
519 }
520
521 pOStm.reset();
522 }
523 if (bRet)
524 {
525 const SgaObjectBmp aObjBmp(aURL);
526 return aObjBmp;
527 }
528 return SgaObjectBmp();
529 }
530
updateSvDrawObject(const GalleryObject * pEntry)531 SgaObjectSvDraw GalleryBinaryEngine::updateSvDrawObject(const GalleryObject* pEntry)
532 {
533 if (GetSvDrawStorage().is())
534 {
535 const OUString aStmName(GetSvDrawStreamNameFromURL(pEntry->getURL()));
536 tools::SvRef<SotStorageStream> pIStm
537 = GetSvDrawStorage()->OpenSotStream(aStmName, StreamMode::READ);
538
539 if (pIStm.is() && !pIStm->GetError())
540 {
541 pIStm->SetBufferSize(16384);
542
543 SgaObjectSvDraw aNewObj(*pIStm, pEntry->getURL());
544
545 pIStm->SetBufferSize(0);
546
547 return aNewObj;
548 }
549 }
550 return SgaObjectSvDraw();
551 }
552
updateTheme()553 void GalleryBinaryEngine::updateTheme()
554 {
555 ::utl::TempFile aTmp;
556 INetURLObject aInURL(GetSdgURL());
557 INetURLObject aTmpURL(aTmp.GetURL());
558
559 DBG_ASSERT(aInURL.GetProtocol() != INetProtocol::NotValid, "invalid URL");
560 DBG_ASSERT(aTmpURL.GetProtocol() != INetProtocol::NotValid, "invalid URL");
561
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));
567
568 if (pIStm && pTmpStm)
569 {
570 for (const auto& i : mrGalleryObjectCollection.getObjectList())
571 {
572 GalleryObject* pEntry = i.get();
573 std::unique_ptr<SgaObject> pObj;
574
575 switch (pEntry->eObjKind)
576 {
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;
592
593 default:
594 break;
595 }
596
597 if (pObj)
598 {
599 pIStm->Seek(pEntry->nOffset);
600 ReadSgaObject(*pIStm, *pObj);
601 pEntry->nOffset = pTmpStm->Tell();
602 WriteSgaObject(*pTmpStm, *pObj);
603 }
604 }
605 }
606 else
607 {
608 OSL_FAIL("File(s) could not be opened");
609 }
610
611 pIStm.reset();
612 pTmpStm.reset();
613
614 CopyFile(aTmpURL, aInURL);
615 KillFile(aTmpURL);
616
617 ErrCode nStorErr = ERRCODE_NONE;
618
619 try
620 {
621 tools::SvRef<SotStorage> aTempStorageRef(
622 new SotStorage(false, aTmpURL.GetMainURL(INetURLObject::DecodeMechanism::NONE),
623 StreamMode::STD_READWRITE));
624 GetSvDrawStorage()->CopyTo(aTempStorageRef.get());
625 nStorErr = GetSvDrawStorage()->GetError();
626 }
627 catch (const css::ucb::ContentCreationException&)
628 {
629 TOOLS_WARN_EXCEPTION("svx", "failed to open: "
630 << aTmpURL.GetMainURL(INetURLObject::DecodeMechanism::NONE)
631 << "due to");
632 nStorErr = ERRCODE_IO_GENERAL;
633 }
634
635 if (nStorErr == ERRCODE_NONE)
636 {
637 clearSotStorage();
638 CopyFile(aTmpURL, GetSdvURL());
639 ImplCreateSvDrawStorage();
640 }
641
642 KillFile(aTmpURL);
643 }
644
insertFileOrDirURL(const INetURLObject & rFileOrDirURL,std::vector<INetURLObject> & rURLVector)645 void GalleryBinaryEngine::insertFileOrDirURL(const INetURLObject& rFileOrDirURL,
646 std::vector<INetURLObject>& rURLVector)
647 {
648 INetURLObject aURL;
649 try
650 {
651 ::ucbhelper::Content aCnt(rFileOrDirURL.GetMainURL(INetURLObject::DecodeMechanism::NONE),
652 uno::Reference<ucb::XCommandEnvironment>(),
653 comphelper::getProcessComponentContext());
654 bool bFolder = false;
655
656 aCnt.getPropertyValue("IsFolder") >>= bFolder;
657
658 if (bFolder)
659 {
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())
665 {
666 while (xResultSet->next())
667 {
668 aURL.SetSmartURL(xContentAccess->queryContentIdentifierString());
669 rURLVector.push_back(aURL);
670 }
671 }
672 }
673 else
674 rURLVector.push_back(rFileOrDirURL);
675 }
676 catch (const ucb::ContentCreationException&)
677 {
678 }
679 catch (const uno::RuntimeException&)
680 {
681 }
682 catch (const uno::Exception&)
683 {
684 }
685 }
686
writeGalleryTheme(SvStream & rOStm,const GalleryTheme & rTheme,const GalleryThemeEntry * pThm)687 SvStream& GalleryBinaryEngine::writeGalleryTheme(SvStream& rOStm, const GalleryTheme& rTheme,
688 const GalleryThemeEntry* pThm)
689 {
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;
695
696 rOStm.WriteUInt16(0x0004);
697 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStm, pThm->GetThemeName(),
698 RTL_TEXTENCODING_UTF8);
699 rOStm.WriteUInt32(nCount).WriteUInt16(osl_getThreadTextEncoding());
700
701 for (sal_uInt32 i = 0; i < nCount; i++)
702 {
703 const GalleryObject* pObj = mrGalleryObjectCollection.getForPosition(i);
704 OUString aPath;
705
706 if (SgaObjKind::SvDraw == pObj->eObjKind)
707 {
708 aPath = GetSvDrawStreamNameFromURL(pObj->getURL());
709 bRel = false;
710 }
711 else
712 {
713 aPath = pObj->getURL().GetMainURL(INetURLObject::DecodeMechanism::NONE);
714 aPath = aPath.copy(
715 0, std::min(rRelURL1.GetMainURL(INetURLObject::DecodeMechanism::NONE).getLength(),
716 aPath.getLength()));
717 bRel = aPath == rRelURL1.GetMainURL(INetURLObject::DecodeMechanism::NONE);
718
719 if (bRel
720 && (pObj->getURL().GetMainURL(INetURLObject::DecodeMechanism::NONE).getLength()
721 > (rRelURL1.GetMainURL(INetURLObject::DecodeMechanism::NONE).getLength() + 1)))
722 {
723 aPath = pObj->getURL().GetMainURL(INetURLObject::DecodeMechanism::NONE);
724 aPath = aPath.copy(
725 std::min(rRelURL1.GetMainURL(INetURLObject::DecodeMechanism::NONE).getLength(),
726 aPath.getLength()));
727 }
728 else
729 {
730 aPath = pObj->getURL().GetMainURL(INetURLObject::DecodeMechanism::NONE);
731 aPath = aPath.copy(
732 0,
733 std::min(rRelURL2.GetMainURL(INetURLObject::DecodeMechanism::NONE).getLength(),
734 aPath.getLength()));
735 bRel = aPath == rRelURL2.GetMainURL(INetURLObject::DecodeMechanism::NONE);
736
737 if (bRel
738 && (pObj->getURL().GetMainURL(INetURLObject::DecodeMechanism::NONE).getLength()
739 > (rRelURL2.GetMainURL(INetURLObject::DecodeMechanism::NONE).getLength()
740 + 1)))
741 {
742 aPath = pObj->getURL().GetMainURL(INetURLObject::DecodeMechanism::NONE);
743 aPath = aPath.copy(std::min(
744 rRelURL2.GetMainURL(INetURLObject::DecodeMechanism::NONE).getLength(),
745 aPath.getLength()));
746 }
747 else
748 aPath = pObj->getURL().GetMainURL(INetURLObject::DecodeMechanism::NONE);
749 }
750 }
751
752 if (!m_aDestDir.isEmpty())
753 {
754 bool aFound = aPath.indexOf(m_aDestDir) != -1;
755 aPath = aPath.replaceFirst(m_aDestDir, "");
756 if (aFound)
757 bRel = m_bDestDirRelative;
758 else
759 SAL_WARN("svx", "failed to replace destdir of '" << m_aDestDir << "' in '" << aPath
760 << "'");
761 }
762
763 rOStm.WriteBool(bRel);
764 write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStm, aPath, RTL_TEXTENCODING_UTF8);
765 rOStm.WriteUInt32(pObj->nOffset).WriteUInt16(static_cast<sal_uInt16>(pObj->eObjKind));
766 }
767
768 // more recently, a 512-byte reserve buffer is written,
769 // to recognize them two sal_uInt32-Ids will be written.
770 rOStm.WriteUInt32(COMPAT_FORMAT('G', 'A', 'L', 'R'))
771 .WriteUInt32(COMPAT_FORMAT('E', 'S', 'R', 'V'));
772
773 const tools::Long nReservePos = rOStm.Tell();
774 std::unique_ptr<VersionCompatWrite> pCompat(new VersionCompatWrite(rOStm, 2));
775
776 rOStm.WriteUInt32(rId).WriteBool(pThm->IsNameFromResource()); // From version 2 and up
777
778 pCompat.reset();
779
780 // Fill the rest of the buffer.
781 const tools::Long nRest
782 = std::max(tools::Long(512 - (rOStm.Tell() - nReservePos)), tools::Long(0));
783
784 if (nRest)
785 {
786 std::unique_ptr<char[]> pReserve(new char[nRest]);
787 memset(pReserve.get(), 0, nRest);
788 rOStm.WriteBytes(pReserve.get(), nRest);
789 }
790
791 return rOStm;
792 }
793
getModificationDate() const794 DateTime GalleryBinaryEngine::getModificationDate() const
795 {
796 ::ucbhelper::Content aCnt(GetThmURL().GetMainURL(INetURLObject::DecodeMechanism::NONE),
797 uno::Reference<ucb::XCommandEnvironment>(),
798 comphelper::getProcessComponentContext());
799 util::DateTime aDateTimeModified;
800 DateTime aDateTime(DateTime::EMPTY);
801
802 aCnt.getPropertyValue("DateModified") >>= aDateTimeModified;
803 ::utl::typeConvert(aDateTimeModified, aDateTime);
804
805 return aDateTime;
806 }
807
808 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
809