Coverage Report

Created: 2026-02-14 09:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sd/source/ui/sidebar/MasterPageDescriptor.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 <memory>
21
#include "MasterPageDescriptor.hxx"
22
#include "MasterPageContainerProviders.hxx"
23
24
#include "DocumentHelper.hxx"
25
#include <PreviewRenderer.hxx>
26
#include <sdpage.hxx>
27
#include <tools/urlobj.hxx>
28
#include <sal/log.hxx>
29
#include <utility>
30
31
namespace sd::sidebar {
32
33
//===== MasterPageDescriptor ==================================================
34
35
MasterPageDescriptor::MasterPageDescriptor (
36
    MasterPageContainer::Origin eOrigin,
37
    const sal_Int32 nTemplateIndex,
38
    std::u16string_view rsURL,
39
    OUString sPageName,
40
    OUString sStyleName,
41
    const bool bIsPrecious,
42
    std::shared_ptr<PageObjectProvider> pPageObjectProvider,
43
    std::shared_ptr<PreviewProvider> pPreviewProvider)
44
0
    : maToken(MasterPageContainer::NIL_TOKEN),
45
0
      meOrigin(eOrigin),
46
0
      msURL(INetURLObject(rsURL).GetMainURL(INetURLObject::DecodeMechanism::Unambiguous)),
47
0
      msPageName(std::move(sPageName)),
48
0
      msStyleName(std::move(sStyleName)),
49
0
      mbIsPrecious(bIsPrecious),
50
0
      mpMasterPage(nullptr),
51
0
      mpSlide(nullptr),
52
0
      mpPreviewProvider(std::move(pPreviewProvider)),
53
0
      mpPageObjectProvider(std::move(pPageObjectProvider)),
54
0
      mnTemplateIndex(nTemplateIndex),
55
0
      meURLClassification(URLCLASS_UNDETERMINED),
56
0
      mnUseCount(0)
57
0
{
58
0
}
59
60
void MasterPageDescriptor::SetToken (MasterPageContainer::Token aToken)
61
0
{
62
0
    maToken = aToken;
63
0
}
64
65
const Image& MasterPageDescriptor::GetPreview (MasterPageContainer::PreviewSize eSize) const
66
0
{
67
0
    if (eSize == MasterPageContainer::SMALL)
68
0
        return maSmallPreview;
69
0
    else
70
0
        return maLargePreview;
71
0
}
72
73
::std::unique_ptr<std::vector<MasterPageContainerChangeEvent::EventType> >
74
    MasterPageDescriptor::Update (
75
        const MasterPageDescriptor& rDescriptor)
76
0
{
77
0
    bool bDataChanged (false);
78
0
    bool bIndexChanged (false);
79
0
    bool bPreviewChanged (false);
80
81
0
    if (meOrigin==MasterPageContainer::UNKNOWN
82
0
        && rDescriptor.meOrigin!=MasterPageContainer::UNKNOWN)
83
0
    {
84
0
        meOrigin = rDescriptor.meOrigin;
85
0
        bIndexChanged = true;
86
0
    }
87
88
0
    if (msURL.isEmpty() && !rDescriptor.msURL.isEmpty())
89
0
    {
90
0
        msURL = rDescriptor.msURL;
91
0
        bDataChanged = true;
92
0
    }
93
94
0
    if (msPageName.isEmpty() && !rDescriptor.msPageName.isEmpty())
95
0
    {
96
0
        msPageName = rDescriptor.msPageName;
97
0
        bDataChanged = true;
98
0
    }
99
100
0
    if (msStyleName.isEmpty() && !rDescriptor.msStyleName.isEmpty())
101
0
    {
102
0
        msStyleName = rDescriptor.msStyleName;
103
0
        bDataChanged = true;
104
0
    }
105
106
0
    if (mpPageObjectProvider == nullptr && rDescriptor.mpPageObjectProvider != nullptr)
107
0
    {
108
0
        mpPageObjectProvider = rDescriptor.mpPageObjectProvider;
109
0
        bDataChanged = true;
110
0
    }
111
112
0
    if (mpPreviewProvider == nullptr && rDescriptor.mpPreviewProvider != nullptr)
113
0
    {
114
0
        mpPreviewProvider = rDescriptor.mpPreviewProvider;
115
0
        bPreviewChanged = true;
116
0
    }
117
118
0
    if (mnTemplateIndex<0 && rDescriptor.mnTemplateIndex>=0)
119
0
    {
120
0
         mnTemplateIndex = rDescriptor.mnTemplateIndex;
121
0
         bIndexChanged = true;
122
0
    }
123
124
     // Prepare the list of event types that will be returned.
125
0
    ::std::unique_ptr<std::vector<MasterPageContainerChangeEvent::EventType> > pResult;
126
0
    if (bDataChanged || bIndexChanged || bPreviewChanged)
127
0
    {
128
0
         pResult.reset(new std::vector<MasterPageContainerChangeEvent::EventType>);
129
0
         if (bDataChanged)
130
0
             pResult->push_back(MasterPageContainerChangeEvent::EventType::DATA_CHANGED);
131
0
         if (bIndexChanged)
132
0
             pResult->push_back(MasterPageContainerChangeEvent::EventType::INDEX_CHANGED);
133
0
         if (bPreviewChanged)
134
0
             pResult->push_back(MasterPageContainerChangeEvent::EventType::PREVIEW_CHANGED);
135
0
    }
136
137
0
    return pResult;
138
0
}
139
140
int MasterPageDescriptor::UpdatePageObject (
141
    sal_Int32 nCostThreshold,
142
    SdDrawDocument* pDocument)
143
0
{
144
0
    int nModified = 0;
145
146
    // Update the page object when that is not yet known.
147
0
    if (mpMasterPage == nullptr && mpPageObjectProvider != nullptr
148
0
        && (nCostThreshold < 0 || mpPageObjectProvider->GetCostIndex() <= nCostThreshold))
149
0
    {
150
        // Note that pDocument may be NULL.
151
152
0
        SdPage* pPage = (*mpPageObjectProvider)(pDocument);
153
0
        if (meOrigin == MasterPageContainer::MASTERPAGE)
154
0
        {
155
0
            mpMasterPage = pPage;
156
0
            if (mpMasterPage != nullptr)
157
0
                mpMasterPage->SetPrecious(mbIsPrecious);
158
0
        }
159
0
        else
160
0
        {
161
            // Master pages from templates are copied into the local document.
162
0
            if (pDocument != nullptr)
163
0
                mpMasterPage = DocumentHelper::CopyMasterPageToLocalDocument(*pDocument,pPage);
164
0
            mpSlide = DocumentHelper::GetSlideForMasterPage(mpMasterPage);
165
0
        }
166
167
0
        if (mpMasterPage != nullptr)
168
0
        {
169
            // Update page name and style name.
170
0
            if (msPageName.isEmpty())
171
0
                msPageName = mpMasterPage->GetName();
172
0
            msStyleName = mpMasterPage->GetName();
173
174
            // Delete an existing substitution. The next request for a preview
175
            // will create the real one.
176
0
            maSmallPreview = Image();
177
0
            maLargePreview = Image();
178
0
            mpPreviewProvider = std::make_shared<PagePreviewProvider>();
179
0
        }
180
0
        else
181
0
        {
182
0
            SAL_WARN( "sd", "UpdatePageObject: master page is NULL");
183
0
            return -1;
184
0
        }
185
186
0
        nModified = 1;
187
0
    }
188
189
0
    return nModified;
190
0
}
191
192
bool MasterPageDescriptor::UpdatePreview (
193
    sal_Int32 nCostThreshold,
194
    const Size& rSmallSize,
195
    const Size& rLargeSize,
196
    ::sd::PreviewRenderer& rRenderer)
197
0
{
198
0
    bool bModified (false);
199
200
    // Update the preview when that is not yet known.
201
0
    if (maLargePreview.GetSizePixel().Width() == 0 && mpPreviewProvider != nullptr
202
0
        && (nCostThreshold < 0 || mpPreviewProvider->GetCostIndex() <= nCostThreshold))
203
0
    {
204
0
        SdPage* pPage = mpSlide;
205
0
        if (pPage == nullptr)
206
0
        {
207
0
            pPage = mpMasterPage;
208
0
        }
209
        //TODO: Notify LOOL of preview updates.
210
0
        maLargePreview = (*mpPreviewProvider)(
211
0
            rLargeSize.Width(),
212
0
            pPage,
213
0
            rRenderer);
214
0
        if (maLargePreview.GetSizePixel().Width() > 0)
215
0
        {
216
            // Create the small preview by scaling the large one down.
217
0
            maSmallPreview = rRenderer.ScaleBitmap(
218
0
                maLargePreview.GetBitmap(),
219
0
                rSmallSize.Width());
220
            // The large preview may not have the desired width.  Scale it
221
            // accordingly.
222
0
            if (maLargePreview.GetSizePixel().Width() != rLargeSize.Width())
223
0
                maLargePreview = rRenderer.ScaleBitmap(
224
0
                    maLargePreview.GetBitmap(),
225
0
                    rLargeSize.Width());
226
0
            bModified = true;
227
0
        }
228
0
    }
229
230
0
    return bModified;
231
0
}
232
233
MasterPageDescriptor::URLClassification MasterPageDescriptor::GetURLClassification()
234
0
{
235
0
    if (meURLClassification == URLCLASS_UNDETERMINED)
236
0
    {
237
0
        if (msURL.isEmpty())
238
0
            meURLClassification = URLCLASS_UNKNOWN;
239
0
        else if (msURL.indexOf("presnt")>=0)
240
0
        {
241
0
            meURLClassification = URLCLASS_PRESENTATION;
242
0
        }
243
0
        else if (msURL.indexOf("layout")>=0)
244
0
        {
245
0
            meURLClassification = URLCLASS_LAYOUT;
246
0
        }
247
0
        else if (msURL.indexOf("educate")>=0)
248
0
        {
249
0
            meURLClassification = URLCLASS_OTHER;
250
0
        }
251
0
        else
252
0
        {
253
0
            meURLClassification = URLCLASS_USER;
254
0
        }
255
0
    }
256
257
0
    return meURLClassification;
258
0
}
259
260
//===== URLComparator =========================================================
261
262
MasterPageDescriptor::URLComparator::URLComparator (OUString sURL)
263
0
    : msURL(std::move(sURL))
264
0
{
265
0
}
266
267
bool MasterPageDescriptor::URLComparator::operator() (
268
    const SharedMasterPageDescriptor& rDescriptor)
269
0
{
270
0
    if (!rDescriptor)
271
0
        return false;
272
0
    else
273
0
        return rDescriptor->msURL == msURL;
274
0
}
275
276
// ===== StyleNameComparator ==================================================
277
278
MasterPageDescriptor::StyleNameComparator::StyleNameComparator (OUString sStyleName)
279
0
    : msStyleName(std::move(sStyleName))
280
0
{
281
0
}
282
283
bool MasterPageDescriptor::StyleNameComparator::operator() (
284
    const SharedMasterPageDescriptor& rDescriptor)
285
0
{
286
0
    if (!rDescriptor)
287
0
        return false;
288
0
    else
289
0
        return rDescriptor->msStyleName == msStyleName;
290
0
}
291
292
//===== PageObjectComparator ==================================================
293
294
MasterPageDescriptor::PageObjectComparator::PageObjectComparator (const SdPage* pPageObject)
295
0
    : mpMasterPage(pPageObject)
296
0
{
297
0
}
298
299
bool MasterPageDescriptor::PageObjectComparator::operator() (
300
    const SharedMasterPageDescriptor& rDescriptor)
301
0
{
302
0
    if (!rDescriptor)
303
0
        return false;
304
0
    else
305
0
        return rDescriptor->mpMasterPage==mpMasterPage;
306
0
}
307
308
//===== AllComparator =========================================================
309
310
MasterPageDescriptor::AllComparator::AllComparator(SharedMasterPageDescriptor aDescriptor)
311
0
    : mpDescriptor(std::move(aDescriptor))
312
0
{
313
0
}
314
315
bool MasterPageDescriptor::AllComparator::operator() (const SharedMasterPageDescriptor&rDescriptor)
316
0
{
317
0
    if (!rDescriptor)
318
0
        return false;
319
0
    else
320
0
    {
321
        // Take URL, page name, style name, and page object into account
322
        // when comparing two descriptors.  When two descriptors are
323
        // identical in any of these values then there are thought of as
324
        // equivalent.  Only the Origin has to be the same in both
325
        // descriptors.
326
0
        return mpDescriptor->meOrigin == rDescriptor->meOrigin
327
0
               && ((!mpDescriptor->msURL.isEmpty() && mpDescriptor->msURL == rDescriptor->msURL)
328
0
                   || (!mpDescriptor->msPageName.isEmpty()
329
0
                       && mpDescriptor->msPageName == rDescriptor->msPageName)
330
0
                   || (!mpDescriptor->msStyleName.isEmpty()
331
0
                       && mpDescriptor->msStyleName == rDescriptor->msStyleName)
332
0
                   || (mpDescriptor->mpMasterPage != nullptr
333
0
                       && mpDescriptor->mpMasterPage == rDescriptor->mpMasterPage)
334
0
                   || (mpDescriptor->mpPageObjectProvider != nullptr
335
0
                       && rDescriptor->mpPageObjectProvider != nullptr
336
0
                       && mpDescriptor->mpPageObjectProvider == rDescriptor->mpPageObjectProvider));
337
0
    }
338
0
}
339
340
} // end of namespace sd::sidebar
341
342
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */