Coverage Report

Created: 2026-09-28 10:59

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