Coverage Report

Created: 2026-07-10 11:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sd/source/ui/unoidl/unomodel.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
22
#include <com/sun/star/presentation/XPresentation2.hpp>
23
24
#include <com/sun/star/drawing/FillStyle.hpp>
25
#include <com/sun/star/drawing/LineStyle.hpp>
26
#include <com/sun/star/lang/DisposedException.hpp>
27
#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
28
#include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
29
#include <com/sun/star/lang/Locale.hpp>
30
#include <com/sun/star/awt/XDevice.hpp>
31
#include <com/sun/star/document/IndexedPropertyValues.hpp>
32
#include <com/sun/star/beans/PropertyAttribute.hpp>
33
#include <com/sun/star/util/XTheme.hpp>
34
#include <com/sun/star/animations/AnimationFill.hpp>
35
#include <com/sun/star/animations/AnimationRestart.hpp>
36
#include <com/sun/star/animations/AnimationEndSync.hpp>
37
#include <com/sun/star/animations/AnimationCalcMode.hpp>
38
#include <com/sun/star/animations/AnimationAdditiveMode.hpp>
39
#include <com/sun/star/animations/AnimationNodeType.hpp>
40
#include <com/sun/star/animations/AnimationTransformType.hpp>
41
#include <com/sun/star/animations/AnimationColorSpace.hpp>
42
#include <com/sun/star/animations/Event.hpp>
43
#include <com/sun/star/animations/EventTrigger.hpp>
44
#include <com/sun/star/animations/Timing.hpp>
45
#include <com/sun/star/animations/TransitionType.hpp>
46
#include <com/sun/star/animations/TransitionSubType.hpp>
47
#include <com/sun/star/animations/ValuePair.hpp>
48
#include <com/sun/star/animations/XAnimate.hpp>
49
#include <com/sun/star/animations/XAnimateMotion.hpp>
50
#include <com/sun/star/animations/XAnimateColor.hpp>
51
#include <com/sun/star/animations/XAnimateTransform.hpp>
52
#include <com/sun/star/animations/XIterateContainer.hpp>
53
#include <com/sun/star/animations/XTimeContainer.hpp>
54
#include <com/sun/star/animations/XTransitionFilter.hpp>
55
#include <com/sun/star/presentation/EffectNodeType.hpp>
56
#include <com/sun/star/presentation/EffectPresetClass.hpp>
57
#include <com/sun/star/presentation/ParagraphTarget.hpp>
58
#include <com/sun/star/presentation/ShapeAnimationSubType.hpp>
59
#include <com/sun/star/presentation/TextAnimationType.hpp>
60
61
62
#include <com/sun/star/embed/Aspects.hpp>
63
64
#include <animations/animationnodehelper.hxx>
65
66
#include <officecfg/Office/Common.hxx>
67
#include <officecfg/Office/Impress.hxx>
68
#include <comphelper/dispatchcommand.hxx>
69
#include <comphelper/indexedpropertyvalues.hxx>
70
#include <comphelper/lok.hxx>
71
#include <comphelper/propertysequence.hxx>
72
#include <comphelper/propertyvalue.hxx>
73
#include <comphelper/sequence.hxx>
74
#include <comphelper/servicehelper.hxx>
75
#include <cppuhelper/supportsservice.hxx>
76
#include <comphelper/processfactory.hxx>
77
#include <comphelper/profilezone.hxx>
78
79
#include <sal/log.hxx>
80
#include <editeng/unofield.hxx>
81
#include <notifydocumentevent.hxx>
82
#include <tpaction.hxx>
83
#include <unomodel.hxx>
84
#include <sdhtmlfilter.hxx>
85
#include "unopool.hxx"
86
#include <sfx2/lokhelper.hxx>
87
#include <sfx2/dispatch.hxx>
88
#include <vcl/ptrstyle.hxx>
89
#include <vcl/themecolors.hxx>
90
#include <vcl/svapp.hxx>
91
#include <Outliner.hxx>
92
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
93
94
#include <editeng/UnoForbiddenCharsTable.hxx>
95
#include <svx/svdoutl.hxx>
96
#include <o3tl/any.hxx>
97
#include <o3tl/safeint.hxx>
98
#include <o3tl/string_view.hxx>
99
#include <o3tl/test_info.hxx>
100
#include <o3tl/unit_conversion.hxx>
101
#include <svx/UnoNamespaceMap.hxx>
102
#include <svx/svdlayer.hxx>
103
#include <svx/svdsob.hxx>
104
#include <svx/svdundo.hxx>
105
#include <svx/svdomedia.hxx>
106
#include <svx/unoapi.hxx>
107
#include <svx/unofill.hxx>
108
#include <svx/sdrpagewindow.hxx>
109
#include <svx/sdrpaintwindow.hxx>
110
#include <editeng/fontitem.hxx>
111
#include <toolkit/awt/vclxdevice.hxx>
112
#include <svx/svdpool.hxx>
113
#include <svx/svdpagv.hxx>
114
#include <svtools/unoimap.hxx>
115
#include <svx/unoshape.hxx>
116
#include <editeng/unonrule.hxx>
117
#include <editeng/eeitem.hxx>
118
#include <unotools/datetime.hxx>
119
#include <sax/tools/converter.hxx>
120
#include <xmloff/autolayout.hxx>
121
#include <xmloff/xmltoken.hxx>
122
#include <rtl/math.hxx>
123
#include <tools/helpers.hxx>
124
#include <tools/json_writer.hxx>
125
#include <TransitionPreset.hxx>
126
127
// Support creation of GraphicStorageHandler and EmbeddedObjectResolver
128
#include <svx/xmleohlp.hxx>
129
#include <xmloff/xmlgrhlp.hxx>
130
#include <DrawDocShell.hxx>
131
#include <ViewShellBase.hxx>
132
#include "UnoDocumentSettings.hxx"
133
134
#include <Annotation.hxx>
135
#include <drawdoc.hxx>
136
#include <SlideSectionManager.hxx>
137
#include <sdmod.hxx>
138
#include <sdresid.hxx>
139
#include <sdpage.hxx>
140
141
#include <strings.hrc>
142
#include <strings.hxx>
143
#include <unolayer.hxx>
144
#include <unopage.hxx>
145
#include "unocpres.hxx"
146
#include "unoobj.hxx"
147
#include <stlpool.hxx>
148
#include "unopback.hxx"
149
#include <unokywds.hxx>
150
151
#include <FrameView.hxx>
152
#include <ClientView.hxx>
153
#include <DrawViewShell.hxx>
154
#include <ViewShell.hxx>
155
#include <Window.hxx>
156
#include <optsitem.hxx>
157
#include <SlideshowLayerRenderer.hxx>
158
159
#include <vcl/pdfextoutdevdata.hxx>
160
#include <vcl/pdf/PDFNote.hxx>
161
162
#include <com/sun/star/presentation/AnimationSpeed.hpp>
163
#include <com/sun/star/presentation/ClickAction.hpp>
164
#include <svx/sdr/contact/viewobjectcontact.hxx>
165
#include <svx/sdr/contact/viewcontact.hxx>
166
#include <svx/sdr/contact/displayinfo.hxx>
167
168
#include <com/sun/star/office/XAnnotation.hpp>
169
#include <com/sun/star/office/XAnnotationAccess.hpp>
170
#include <com/sun/star/office/XAnnotationEnumeration.hpp>
171
#include <com/sun/star/geometry/RealPoint2D.hpp>
172
#include <com/sun/star/util/DateTime.hpp>
173
174
#include <drawinglayer/primitive2d/structuretagprimitive2d.hxx>
175
176
#include <sfx2/lokcomponenthelpers.hxx>
177
#include <sfx2/LokControlHandler.hxx>
178
#include <tools/gen.hxx>
179
#include <tools/debug.hxx>
180
#include <tools/urlobj.hxx>
181
#include <comphelper/diagnose_ex.hxx>
182
#include <tools/UnitConversion.hxx>
183
#include <svx/ColorSets.hxx>
184
#include <docmodel/theme/Theme.hxx>
185
186
#include <frozen/bits/defines.h>
187
#include <frozen/bits/elsa_std.h>
188
#include <frozen/unordered_map.h>
189
#include <SlideSorter.hxx>
190
#include <SlideSorterViewShell.hxx>
191
#include <controller/SlideSorterController.hxx>
192
#include <controller/SlsPageSelector.hxx>
193
194
#include <app.hrc>
195
196
using namespace ::cppu;
197
using namespace ::com::sun::star;
198
using namespace ::sd;
199
200
const TranslateId aTypeResIds[SdLinkTargetType::Count] =
201
{
202
    STR_SD_PAGE,            // SdLinkTargetType::Page
203
    STR_NOTES_MODE,         // SdLinkTargetType::Notes
204
    STR_HANDOUT,            // SdLinkTargetType::Handout
205
    STR_MASTERPAGE_NAME,    // SdLinkTargetType::MasterPage
206
};
207
208
TranslateId SdTPAction::GetClickActionSdResId( presentation::ClickAction eCA )
209
0
{
210
0
    switch( eCA )
211
0
    {
212
0
        case presentation::ClickAction_NONE:             return STR_CLICK_ACTION_NONE;
213
0
        case presentation::ClickAction_PREVPAGE:         return STR_CLICK_ACTION_PREVPAGE;
214
0
        case presentation::ClickAction_NEXTPAGE:         return STR_CLICK_ACTION_NEXTPAGE;
215
0
        case presentation::ClickAction_FIRSTPAGE:        return STR_CLICK_ACTION_FIRSTPAGE;
216
0
        case presentation::ClickAction_LASTPAGE:         return STR_CLICK_ACTION_LASTPAGE;
217
0
        case presentation::ClickAction_BOOKMARK:         return STR_CLICK_ACTION_BOOKMARK;
218
0
        case presentation::ClickAction_DOCUMENT:         return STR_CLICK_ACTION_DOCUMENT;
219
0
        case presentation::ClickAction_PROGRAM:          return STR_CLICK_ACTION_PROGRAM;
220
0
        case presentation::ClickAction_MACRO:            return STR_CLICK_ACTION_MACRO;
221
0
        case presentation::ClickAction_SOUND:            return STR_CLICK_ACTION_SOUND;
222
0
        case presentation::ClickAction_VERB:             return STR_CLICK_ACTION_VERB;
223
0
        case presentation::ClickAction_STOPPRESENTATION: return STR_CLICK_ACTION_STOPPRESENTATION;
224
0
        default: OSL_FAIL( "No StringResource for ClickAction available!" );
225
0
    }
226
0
    return {};
227
0
}
228
229
class SdUnoForbiddenCharsTable : public SvxUnoForbiddenCharsTable,
230
                                 public SfxListener
231
{
232
public:
233
    explicit SdUnoForbiddenCharsTable(SdrModel* pModel);
234
    virtual ~SdUnoForbiddenCharsTable() override;
235
236
    // SfxListener
237
    virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) noexcept override;
238
protected:
239
    virtual void onChange() override;
240
241
private:
242
    SdrModel*   mpModel;
243
};
244
245
namespace {
246
247
class SlideBackgroundInfo
248
{
249
public:
250
    SlideBackgroundInfo(const uno::Reference<drawing::XDrawPage>& xDrawPage,
251
                        const uno::Reference<drawing::XDrawPage>& xMasterPage);
252
0
    bool slideHasOwnBackground() const { return mbIsCustom; }
253
0
    bool hasBackground() const { return bHasBackground; }
254
0
    bool isSolidColor() const { return mbIsSolidColor; }
255
    ::Color getFillColor() const;
256
    sal_Int32 getFillTransparency() const;
257
    OString getFillColorAsRGBA() const;
258
private:
259
    bool getFillStyleImpl(const uno::Reference<drawing::XDrawPage>& xDrawPage);
260
private:
261
    uno::Reference<beans::XPropertySet> mxBackground;
262
    bool mbIsCustom;
263
    bool bHasBackground;
264
    bool mbIsSolidColor;
265
    drawing::FillStyle maFillStyle;
266
};
267
268
SlideBackgroundInfo::SlideBackgroundInfo(
269
        const uno::Reference<drawing::XDrawPage>& xDrawPage,
270
        const uno::Reference<drawing::XDrawPage>& xMasterPage)
271
0
    : mbIsCustom(false)
272
0
    , bHasBackground(false)
273
0
    , mbIsSolidColor(false)
274
0
    , maFillStyle(drawing::FillStyle_NONE)
275
0
{
276
0
    mbIsCustom = getFillStyleImpl(xDrawPage);
277
0
    bHasBackground = mbIsCustom;
278
0
    if (!bHasBackground)
279
0
    {
280
0
        bHasBackground = getFillStyleImpl(xMasterPage);
281
0
    }
282
0
    if (bHasBackground)
283
0
    {
284
0
        if (maFillStyle == drawing::FillStyle_SOLID)
285
0
        {
286
0
            OUString sGradientName;
287
0
            mxBackground->getPropertyValue("FillTransparenceGradientName") >>= sGradientName;
288
0
            if (sGradientName.isEmpty())
289
0
            {
290
0
                mbIsSolidColor = true;
291
0
            }
292
0
        }
293
0
    }
294
0
}
295
296
sal_Int32 SlideBackgroundInfo::getFillTransparency() const
297
0
{
298
0
    if (!mxBackground.is())
299
0
        return 0;
300
0
    sal_Int32 nFillTransparency = 0;
301
0
    mxBackground->getPropertyValue("FillTransparence") >>= nFillTransparency;
302
0
    return nFillTransparency;
303
0
}
304
305
::Color SlideBackgroundInfo::getFillColor() const
306
0
{
307
0
    if (!mxBackground.is())
308
0
        return {};
309
0
    if (sal_Int32 nFillColor; mxBackground->getPropertyValue("FillColor") >>= nFillColor)
310
0
    {
311
0
        return ::Color(ColorTransparency, nFillColor & 0xffffff);
312
0
    }
313
0
    return {};
314
0
}
315
316
OString SlideBackgroundInfo::getFillColorAsRGBA() const
317
0
{
318
0
    ::Color aColor = getFillColor();
319
0
    OString sColor = aColor.AsRGBHEXString().toUtf8();
320
0
    sal_uInt32 nAlpha = std::round((100 - getFillTransparency()) * 255 / 100.0);
321
0
    std::stringstream ss;
322
0
    ss << std::hex << std::uppercase << std::setfill ('0') << std::setw(2) << nAlpha;
323
0
    sColor += ss.str().c_str();
324
0
    return sColor;
325
0
}
326
327
bool SlideBackgroundInfo::getFillStyleImpl(const uno::Reference<drawing::XDrawPage>& xDrawPage)
328
0
{
329
0
    if( xDrawPage.is() )
330
0
    {
331
0
        uno::Reference< beans::XPropertySet > xPropSet( xDrawPage, uno::UNO_QUERY );
332
0
        if( xPropSet.is() )
333
0
        {
334
0
            uno::Reference< beans::XPropertySet > xBackground;
335
0
            if (xPropSet->getPropertySetInfo()->hasPropertyByName("Background"))
336
0
                xPropSet->getPropertyValue( "Background" ) >>= xBackground;
337
0
            if( xBackground.is() )
338
0
            {
339
0
                drawing::FillStyle aFillStyle;
340
0
                if( xBackground->getPropertyValue( "FillStyle" ) >>= aFillStyle )
341
0
                {
342
0
                    maFillStyle = aFillStyle;
343
0
                    if (aFillStyle != drawing::FillStyle_NONE)
344
0
                    {
345
0
                        mxBackground = std::move(xBackground);
346
0
                        return true;
347
0
                    }
348
0
                }
349
0
            }
350
0
        }
351
0
    }
352
0
    return false;
353
0
}
354
355
using namespace ::css::animations;
356
using namespace ::css::beans;
357
using namespace ::css::container;
358
using namespace ::css::uno;
359
using namespace ::xmloff::token;
360
using namespace ::css::presentation;
361
362
template <typename T, std::size_t N>
363
constexpr auto mapEnumToString(std::pair<T, std::string_view> const (&items)[N])
364
0
{
365
0
    return frozen::make_unordered_map<T, std::string_view, N>(items);
366
0
}
Unexecuted instantiation: unomodel.cxx:auto (anonymous namespace)::mapEnumToString<short, 17ul>(std::__1::pair<short, std::__1::basic_string_view<char, std::__1::char_traits<char> > > const (&) [17ul])
Unexecuted instantiation: unomodel.cxx:auto (anonymous namespace)::mapEnumToString<short, 40ul>(std::__1::pair<short, std::__1::basic_string_view<char, std::__1::char_traits<char> > > const (&) [40ul])
Unexecuted instantiation: unomodel.cxx:auto (anonymous namespace)::mapEnumToString<short, 13ul>(std::__1::pair<short, std::__1::basic_string_view<char, std::__1::char_traits<char> > > const (&) [13ul])
Unexecuted instantiation: unomodel.cxx:auto (anonymous namespace)::mapEnumToString<short, 6ul>(std::__1::pair<short, std::__1::basic_string_view<char, std::__1::char_traits<char> > > const (&) [6ul])
Unexecuted instantiation: unomodel.cxx:auto (anonymous namespace)::mapEnumToString<short, 4ul>(std::__1::pair<short, std::__1::basic_string_view<char, std::__1::char_traits<char> > > const (&) [4ul])
Unexecuted instantiation: unomodel.cxx:auto (anonymous namespace)::mapEnumToString<short, 5ul>(std::__1::pair<short, std::__1::basic_string_view<char, std::__1::char_traits<char> > > const (&) [5ul])
Unexecuted instantiation: unomodel.cxx:auto (anonymous namespace)::mapEnumToString<short, 7ul>(std::__1::pair<short, std::__1::basic_string_view<char, std::__1::char_traits<char> > > const (&) [7ul])
Unexecuted instantiation: unomodel.cxx:auto (anonymous namespace)::mapEnumToString<com::sun::star::animations::Timing, 2ul>(std::__1::pair<com::sun::star::animations::Timing, std::__1::basic_string_view<char, std::__1::char_traits<char> > > const (&) [2ul])
Unexecuted instantiation: unomodel.cxx:auto (anonymous namespace)::mapEnumToString<short, 3ul>(std::__1::pair<short, std::__1::basic_string_view<char, std::__1::char_traits<char> > > const (&) [3ul])
Unexecuted instantiation: unomodel.cxx:auto (anonymous namespace)::mapEnumToString<com::sun::star::drawing::FillStyle, 5ul>(std::__1::pair<com::sun::star::drawing::FillStyle, std::__1::basic_string_view<char, std::__1::char_traits<char> > > const (&) [5ul])
Unexecuted instantiation: unomodel.cxx:auto (anonymous namespace)::mapEnumToString<com::sun::star::drawing::LineStyle, 3ul>(std::__1::pair<com::sun::star::drawing::LineStyle, std::__1::basic_string_view<char, std::__1::char_traits<char> > > const (&) [3ul])
367
368
constexpr auto constTransitionTypeToString = mapEnumToString<sal_Int16>({
369
    { animations::TransitionType::BARWIPE, "BarWipe" }, // Wipe
370
    { animations::TransitionType::PINWHEELWIPE, "PineWheelWipe" }, // Wheel
371
    { animations::TransitionType::SLIDEWIPE, "SlideWipe" }, // Cover, Uncover
372
    { animations::TransitionType::RANDOMBARWIPE, "RandomBarWipe" }, // Bars
373
    { animations::TransitionType::CHECKERBOARDWIPE, "CheckerBoardWipe" }, // Checkers
374
    { animations::TransitionType::FOURBOXWIPE, "FourBoxWipe" }, // Shape
375
    { animations::TransitionType::IRISWIPE, "IrisWipe" }, // Box
376
    { animations::TransitionType::FANWIPE, "FanWipe" }, // Wedge
377
    { animations::TransitionType::BLINDSWIPE, "BlindWipe"}, // Venetian
378
    { animations::TransitionType::FADE, "Fade"},
379
    { animations::TransitionType::DISSOLVE, "Dissolve"},
380
    { animations::TransitionType::PUSHWIPE, "PushWipe"}, // Comb
381
    { animations::TransitionType::ELLIPSEWIPE, "EllipseWipe"}, // Shape
382
    { animations::TransitionType::BARNDOORWIPE, "BarnDoorWipe"}, // Split
383
    { animations::TransitionType::WATERFALLWIPE, "WaterfallWipe"}, // Diagonal
384
    { animations::TransitionType::MISCSHAPEWIPE, "MiscShapeWipe"},
385
    { animations::TransitionType::ZOOM, "Zoom"}
386
});
387
388
constexpr auto constTransitionSubTypeToString = mapEnumToString<sal_Int16>({
389
    { animations::TransitionSubType::LEFTTORIGHT, "LeftToRight" },
390
    { animations::TransitionSubType::TOPTOBOTTOM, "TopToBottom" },
391
    { animations::TransitionSubType::EIGHTBLADE, "8Blade" },
392
    { animations::TransitionSubType::FOURBLADE, "4Blade" },
393
    { animations::TransitionSubType::THREEBLADE, "3Blade" },
394
    { animations::TransitionSubType::TWOBLADEVERTICAL, "2BladeVertical" },
395
    { animations::TransitionSubType::ONEBLADE, "1Blade" },
396
    { animations::TransitionSubType::FROMTOPLEFT, "FromTopLeft" },
397
    { animations::TransitionSubType::FROMTOPRIGHT, "FromTopRight"},
398
    { animations::TransitionSubType::FROMBOTTOMLEFT, "FromBottomLeft"},
399
    { animations::TransitionSubType::FROMBOTTOMRIGHT, "FromBottomRight"},
400
    { animations::TransitionSubType::VERTICAL, "Vertical"},
401
    { animations::TransitionSubType::HORIZONTAL, "Horizontal"},
402
    { animations::TransitionSubType::DOWN, "Down"},
403
    { animations::TransitionSubType::ACROSS, "Across"},
404
    { animations::TransitionSubType::CORNERSOUT, "CornersOut"},
405
    { animations::TransitionSubType::DIAMOND, "Diamond"},
406
    { animations::TransitionSubType::CIRCLE, "Circle"},
407
    { animations::TransitionSubType::RECTANGLE, "Rectangle"},
408
    { animations::TransitionSubType::CENTERTOP, "CenterTop"},
409
    { animations::TransitionSubType::CROSSFADE, "CrossFade"},
410
    { animations::TransitionSubType::FADEOVERCOLOR, "FadeOverColor"},
411
    { animations::TransitionSubType::FROMLEFT, "FromLeft"},
412
    { animations::TransitionSubType::FROMRIGHT, "FromRight"},
413
    { animations::TransitionSubType::FROMTOP, "FromTop"},
414
    { animations::TransitionSubType::HORIZONTALLEFT, "HorizontalLeft"},
415
    { animations::TransitionSubType::HORIZONTALRIGHT, "HorizontalRight"},
416
    { animations::TransitionSubType::COMBVERTICAL, "CombVertical"},
417
    { animations::TransitionSubType::COMBHORIZONTAL, "CombHorizontal"},
418
    { animations::TransitionSubType::TOPLEFT, "TopLeft"},
419
    { animations::TransitionSubType::TOPRIGHT, "TopRight"},
420
    { animations::TransitionSubType::BOTTOMRIGHT, "BottomRight"},
421
    { animations::TransitionSubType::BOTTOMLEFT, "BottomLeft"},
422
    { animations::TransitionSubType::TOPCENTER, "TopCenter"},
423
    { animations::TransitionSubType::RIGHTCENTER, "RightCenter"},
424
    { animations::TransitionSubType::BOTTOMCENTER, "BottomCenter"},
425
    { animations::TransitionSubType::FANOUTHORIZONTAL, "FanOutHorizontal"},
426
    { animations::TransitionSubType::CORNERSIN, "CornersIn"},
427
    { animations::TransitionSubType::HEART, "Heart"},
428
    { animations::TransitionSubType::ROTATEIN, "RotateIn"}
429
});
430
431
constexpr auto constAnimationNodeTypeToString = mapEnumToString<sal_Int16>({
432
    { AnimationNodeType::ANIMATE, "Animate" },
433
    { AnimationNodeType::ANIMATECOLOR, "AnimateColor" },
434
    { AnimationNodeType::ANIMATEMOTION, "AnimateMotion" },
435
    { AnimationNodeType::ANIMATEPHYSICS, "Animate" },
436
    { AnimationNodeType::ANIMATETRANSFORM, "AnimateTransform" },
437
    { AnimationNodeType::AUDIO, "Audio" },
438
    { AnimationNodeType::COMMAND, "Command" },
439
    { AnimationNodeType::CUSTOM, "Custom" },
440
    { AnimationNodeType::ITERATE, "Iterate" },
441
    { AnimationNodeType::PAR, "Par" },
442
    { AnimationNodeType::SEQ, "Seq" },
443
    { AnimationNodeType::SET, "Set" },
444
    { AnimationNodeType::TRANSITIONFILTER, "TransitionFilter" },
445
});
446
447
constexpr auto constFillToString = mapEnumToString<sal_Int16>({
448
    { AnimationFill::DEFAULT, "Default" },
449
    { AnimationFill::REMOVE, "Remove" },
450
    { AnimationFill::FREEZE, "Freeze" },
451
    { AnimationFill::HOLD, "Hold" },
452
    { AnimationFill::TRANSITION, "Transition" },
453
    { AnimationFill::AUTO, "Auto" },
454
});
455
456
constexpr auto constRestartToString = mapEnumToString<sal_Int16>({
457
    { AnimationRestart::DEFAULT, "Default" },
458
    { AnimationRestart::ALWAYS, "Always" },
459
    { AnimationRestart::WHEN_NOT_ACTIVE, "WhenNotActive" },
460
    { AnimationRestart::NEVER, "Never" },
461
});
462
463
constexpr auto constEndSyncToString = mapEnumToString<sal_Int16>({
464
    { AnimationEndSync::FIRST, "First" },
465
    { AnimationEndSync::LAST, "Last" },
466
    { AnimationEndSync::ALL, "All" },
467
    { AnimationEndSync::MEDIA, "Media" },
468
});
469
470
constexpr auto constCalcModeToString = mapEnumToString<sal_Int16>({
471
    { AnimationCalcMode::DISCRETE, "Discrete" },
472
    { AnimationCalcMode::LINEAR, "Linear" },
473
    { AnimationCalcMode::PACED, "Paced" },
474
    { AnimationCalcMode::SPLINE, "Spline" },
475
});
476
477
constexpr auto constAdditiveModeToString = mapEnumToString<sal_Int16>({
478
    { AnimationAdditiveMode::BASE, "Base" },
479
    { AnimationAdditiveMode::SUM, "Sum" },
480
    { AnimationAdditiveMode::REPLACE, "Replace" },
481
    { AnimationAdditiveMode::MULTIPLY, "Multiply" },
482
    { AnimationAdditiveMode::NONE, "None" },
483
});
484
485
constexpr auto constEffectPresetClassToString = mapEnumToString<sal_Int16>({
486
    { EffectPresetClass::CUSTOM, "Custom" },
487
    { EffectPresetClass::ENTRANCE, "Entrance" },
488
    { EffectPresetClass::EXIT, "Exit" },
489
    { EffectPresetClass::EMPHASIS, "Emphasis" },
490
    { EffectPresetClass::MOTIONPATH, "MotionPath" },
491
    { EffectPresetClass::OLEACTION, "OleAction" },
492
    { EffectPresetClass::MEDIACALL, "MediaCall" },
493
});
494
495
constexpr auto constEffectNodeTypeToString = mapEnumToString<sal_Int16>({
496
    { EffectNodeType::DEFAULT, "Default" },
497
    { EffectNodeType::ON_CLICK, "OnClick" },
498
    { EffectNodeType::WITH_PREVIOUS, "WithPrevious" },
499
    { EffectNodeType::AFTER_PREVIOUS, "AfterPrevious" },
500
    { EffectNodeType::MAIN_SEQUENCE, "MainSequence" },
501
    { EffectNodeType::TIMING_ROOT, "TimingRoot" },
502
    { EffectNodeType::INTERACTIVE_SEQUENCE, "InteractiveSequence" },
503
});
504
505
constexpr auto constEventTriggerToString = mapEnumToString<sal_Int16>({
506
    { EventTrigger::BEGIN_EVENT, "BeginEvent" },
507
    { EventTrigger::END_EVENT, "EndEvent" },
508
    { EventTrigger::NONE, "None" },
509
    { EventTrigger::ON_BEGIN, "OnBegin" },
510
    { EventTrigger::ON_CLICK, "OnClick" },
511
    { EventTrigger::ON_DBL_CLICK, "OnDblClick" },
512
    { EventTrigger::ON_END, "OnEnd" },
513
    { EventTrigger::ON_MOUSE_ENTER, "OnMouseEnter" },
514
    { EventTrigger::ON_MOUSE_LEAVE, "OnMouseLeave" },
515
    { EventTrigger::ON_NEXT, "OnNext" },
516
    { EventTrigger::ON_PREV, "OnPrev" },
517
    { EventTrigger::ON_STOP_AUDIO, "OnStopAudio" },
518
    { EventTrigger::REPEAT, "Repeat" },
519
});
520
521
constexpr auto constTimingToString = mapEnumToString<Timing>({
522
    { Timing_INDEFINITE, "indefinite" },
523
    { Timing_MEDIA, "media" },
524
});
525
526
constexpr auto constTransformTypeToString = mapEnumToString<sal_Int16>({
527
    { AnimationTransformType::TRANSLATE, "Translate" },
528
    { AnimationTransformType::SCALE, "Scale" },
529
    { AnimationTransformType::ROTATE, "Rotate" },
530
    { AnimationTransformType::SKEWX, "SkewX" },
531
    { AnimationTransformType::SKEWY, "SkewY" },
532
});
533
534
constexpr auto constSubItemToString = mapEnumToString<sal_Int16>({
535
    { ShapeAnimationSubType::AS_WHOLE, "AsWhole" },
536
    { ShapeAnimationSubType::ONLY_BACKGROUND, "OnlyBackground" },
537
    { ShapeAnimationSubType::ONLY_TEXT, "OnlyText" },
538
});
539
540
constexpr auto constIterateTypeToString = mapEnumToString<sal_Int16>({
541
    { TextAnimationType::BY_PARAGRAPH, "ByParagraph" },
542
    { TextAnimationType::BY_WORD, "ByWord" },
543
    { TextAnimationType::BY_LETTER, "ByLetter" },
544
});
545
546
constexpr auto constFillStyleToString = mapEnumToString<drawing::FillStyle>({
547
    { drawing::FillStyle_NONE, "None" },
548
    { drawing::FillStyle_SOLID, "Solid" },
549
    { drawing::FillStyle_BITMAP, "Bitmap" },
550
    { drawing::FillStyle_GRADIENT, "Gradient" },
551
    { drawing::FillStyle_HATCH, "Hatch" },
552
});
553
554
constexpr auto constLineStyleToString = mapEnumToString<drawing::LineStyle>({
555
    { drawing::LineStyle_NONE, "None" },
556
    { drawing::LineStyle_SOLID, "Solid" },
557
    { drawing::LineStyle_DASH, "Dash" },
558
});
559
560
561
constexpr auto constAttributeNameToXMLEnum
562
    = frozen::make_unordered_map<std::string_view, XMLTokenEnum>({
563
        { "X", XML_X },
564
        { "Y", XML_Y },
565
        { "Width", XML_WIDTH },
566
        { "Height", XML_HEIGHT },
567
        { "Rotate", XML_ROTATE },
568
        { "SkewX", XML_SKEWX },
569
        { "FillColor", XML_FILL_COLOR },
570
        { "FillStyle", XML_FILL },
571
        { "LineColor", XML_STROKE_COLOR },
572
        { "LineStyle",XML_STROKE  },
573
        { "CharColor", XML_COLOR },
574
        { "CharRotation", XML_TEXT_ROTATION_ANGLE },
575
        { "CharWeight", XML_FONT_WEIGHT },
576
        { "CharUnderline", XML_TEXT_UNDERLINE },
577
        { "CharFontName", XML_FONT_FAMILY },
578
        { "CharHeight", XML_FONT_SIZE },
579
        { "CharPosture", XML_FONT_STYLE },
580
        { "Visibility", XML_VISIBILITY },
581
        { "Opacity", XML_OPACITY },
582
        { "DimColor", XML_DIM },
583
});
584
585
class AnimationsExporter
586
{
587
public:
588
    AnimationsExporter(::tools::JsonWriter& rWriter,
589
                       const Reference<drawing::XDrawPage>& xDrawPage);
590
    void exportAnimations();
591
    void exportTriggers() const;
592
0
    [[nodiscard]] bool hasEffects() const { return mbHasEffects; }
593
594
private:
595
    void exportNode(const Reference<XAnimationNode>& xNode);
596
    void exportNodeImpl(const Reference<XAnimationNode>& xNode);
597
    void exportContainer(const Reference<XTimeContainer>& xContainer);
598
599
    void exportAnimate(const Reference<XAnimate>& xAnimate);
600
601
    void convertValue(XMLTokenEnum eAttributeName, OStringBuffer& sTmp, const Any& rValue) const;
602
    void convertTiming(OStringBuffer& sTmp, const Any& rValue);
603
604
    void appendTrigger(const css::uno::Any& rTarget, const OString& rTriggerHash);
605
    void exportTriggersImpl(const uno::Reference<drawing::XShapes>& xShapes) const;
606
607
private:
608
    ::tools::JsonWriter& mrWriter;
609
    Reference<drawing::XDrawPage> mxDrawPage;
610
    Reference<XPropertySet> mxPageProps;
611
    Reference<XAnimationNode> mxRootNode;
612
    bool mbHasEffects;
613
    std::unordered_map<SdrObject*, OString> maEventTriggerSet;
614
};
615
616
AnimationsExporter::AnimationsExporter(::tools::JsonWriter& rWriter,
617
                                       const Reference<drawing::XDrawPage>& xDrawPage)
618
0
    : mrWriter(rWriter)
619
0
    , mxDrawPage(xDrawPage)
620
0
    , mbHasEffects(false)
621
0
{
622
0
    if (!mxDrawPage.is())
623
0
        return;
624
625
0
    try
626
0
    {
627
0
        mxPageProps = Reference<XPropertySet>(xDrawPage, UNO_QUERY);
628
0
        if (!mxPageProps.is())
629
0
            return;
630
631
0
        Reference<XAnimationNodeSupplier> xAnimNodeSupplier(mxDrawPage, UNO_QUERY);
632
0
        if (!xAnimNodeSupplier.is())
633
0
            return;
634
635
0
        Reference<XAnimationNode> xRootNode = xAnimNodeSupplier->getAnimationNode();
636
0
        if (xRootNode.is())
637
0
        {
638
            // first check if there are no animations
639
0
            Reference<XEnumerationAccess> xEnumerationAccess(xRootNode, UNO_QUERY_THROW);
640
0
            Reference<XEnumeration> xEnumeration(xEnumerationAccess->createEnumeration(),
641
0
                                                 css::uno::UNO_SET_THROW);
642
0
            if (xEnumeration->hasMoreElements())
643
0
            {
644
                // first child node may be an empty main sequence, check this
645
0
                Reference<XAnimationNode> xMainNode(xEnumeration->nextElement(), UNO_QUERY_THROW);
646
0
                Reference<XEnumerationAccess> xMainEnumerationAccess(xMainNode, UNO_QUERY_THROW);
647
0
                Reference<XEnumeration> xMainEnumeration(
648
0
                    xMainEnumerationAccess->createEnumeration(), css::uno::UNO_SET_THROW);
649
650
                // only export if the main sequence is not empty or if there are additional
651
                // trigger sequences
652
0
                mbHasEffects
653
0
                    = xMainEnumeration->hasMoreElements() || xEnumeration->hasMoreElements();
654
0
            }
655
0
        }
656
0
        if (mbHasEffects)
657
0
            mxRootNode = std::move(xRootNode);
658
0
    }
659
0
    catch (const RuntimeException&)
660
0
    {
661
0
        TOOLS_WARN_EXCEPTION("sd", "unomodel: AnimationsExporter");
662
0
    }
663
0
}
664
665
template <typename EnumT, size_t N>
666
constexpr bool convertEnum(OStringBuffer& rBuffer, EnumT nValue,
667
                           const frozen::unordered_map<EnumT, std::string_view, N>& rMap)
668
0
{
669
0
    auto iterator = rMap.find(nValue);
670
0
    if (iterator == rMap.end())
671
0
        return false;
672
0
    rBuffer.append(iterator->second);
673
0
    return true;
674
0
}
Unexecuted instantiation: unomodel.cxx:bool (anonymous namespace)::convertEnum<short, 13ul>(rtl::OStringBuffer&, short, frozen::unordered_map<short, std::__1::basic_string_view<char, std::__1::char_traits<char> >, 13ul, frozen::elsa<short>, std::__1::equal_to<short> > const&)
Unexecuted instantiation: unomodel.cxx:bool (anonymous namespace)::convertEnum<short, 6ul>(rtl::OStringBuffer&, short, frozen::unordered_map<short, std::__1::basic_string_view<char, std::__1::char_traits<char> >, 6ul, frozen::elsa<short>, std::__1::equal_to<short> > const&)
Unexecuted instantiation: unomodel.cxx:bool (anonymous namespace)::convertEnum<short, 4ul>(rtl::OStringBuffer&, short, frozen::unordered_map<short, std::__1::basic_string_view<char, std::__1::char_traits<char> >, 4ul, frozen::elsa<short>, std::__1::equal_to<short> > const&)
Unexecuted instantiation: unomodel.cxx:bool (anonymous namespace)::convertEnum<short, 7ul>(rtl::OStringBuffer&, short, frozen::unordered_map<short, std::__1::basic_string_view<char, std::__1::char_traits<char> >, 7ul, frozen::elsa<short>, std::__1::equal_to<short> > const&)
Unexecuted instantiation: unomodel.cxx:bool (anonymous namespace)::convertEnum<short, 3ul>(rtl::OStringBuffer&, short, frozen::unordered_map<short, std::__1::basic_string_view<char, std::__1::char_traits<char> >, 3ul, frozen::elsa<short>, std::__1::equal_to<short> > const&)
Unexecuted instantiation: unomodel.cxx:bool (anonymous namespace)::convertEnum<com::sun::star::drawing::FillStyle, 5ul>(rtl::OStringBuffer&, com::sun::star::drawing::FillStyle, frozen::unordered_map<com::sun::star::drawing::FillStyle, std::__1::basic_string_view<char, std::__1::char_traits<char> >, 5ul, frozen::elsa<com::sun::star::drawing::FillStyle>, std::__1::equal_to<com::sun::star::drawing::FillStyle> > const&)
Unexecuted instantiation: unomodel.cxx:bool (anonymous namespace)::convertEnum<com::sun::star::drawing::LineStyle, 3ul>(rtl::OStringBuffer&, com::sun::star::drawing::LineStyle, frozen::unordered_map<com::sun::star::drawing::LineStyle, std::__1::basic_string_view<char, std::__1::char_traits<char> >, 3ul, frozen::elsa<com::sun::star::drawing::LineStyle>, std::__1::equal_to<com::sun::star::drawing::LineStyle> > const&)
Unexecuted instantiation: unomodel.cxx:bool (anonymous namespace)::convertEnum<short, 5ul>(rtl::OStringBuffer&, short, frozen::unordered_map<short, std::__1::basic_string_view<char, std::__1::char_traits<char> >, 5ul, frozen::elsa<short>, std::__1::equal_to<short> > const&)
Unexecuted instantiation: unomodel.cxx:bool (anonymous namespace)::convertEnum<short, 17ul>(rtl::OStringBuffer&, short, frozen::unordered_map<short, std::__1::basic_string_view<char, std::__1::char_traits<char> >, 17ul, frozen::elsa<short>, std::__1::equal_to<short> > const&)
Unexecuted instantiation: unomodel.cxx:bool (anonymous namespace)::convertEnum<short, 40ul>(rtl::OStringBuffer&, short, frozen::unordered_map<short, std::__1::basic_string_view<char, std::__1::char_traits<char> >, 40ul, frozen::elsa<short>, std::__1::equal_to<short> > const&)
675
676
void convertDouble(OStringBuffer& rBuffer, double fValue)
677
0
{
678
0
        ::rtl::math::doubleToStringBuffer(rBuffer, fValue, rtl_math_StringFormat_Automatic,
679
0
                                          rtl_math_DecimalPlaces_Max, '.', true);
680
0
}
681
682
void convertBool(OStringBuffer& rBuffer, bool bValue)
683
0
{
684
0
    rBuffer.append( bValue );
685
0
}
686
687
void convertPath(OStringBuffer& sTmp, const Any& rPath)
688
0
{
689
0
    OUString aStr;
690
0
    rPath >>= aStr;
691
0
    sTmp = aStr.toUtf8();
692
0
}
693
694
void convertColor(OStringBuffer& rBuffer, sal_Int32 nColor)
695
0
{
696
0
    OUStringBuffer aUBuffer;
697
0
    ::sax::Converter::convertColor(aUBuffer, nColor);
698
0
    rBuffer.append(aUBuffer.makeStringAndClear().toUtf8());
699
0
}
700
701
void convertColor(OStringBuffer& rBuffer, const Any& rValue)
702
0
{
703
0
    sal_Int32 nColor = 0;
704
0
    if (rValue >>= nColor)
705
0
    {
706
0
        convertColor(rBuffer, nColor);
707
0
    }
708
0
    else
709
0
    {
710
0
        Sequence<double> aHSL;
711
0
        if ((rValue >>= aHSL) && (aHSL.getLength() == 3))
712
0
        {
713
0
            rBuffer.append("hsl(" + OString::number(aHSL[0]) + ","
714
0
                           + OString::number(aHSL[1] * 100.0) + "%,"
715
0
                           + OString::number(aHSL[2] * 100.0) + "%)");
716
0
        }
717
0
    }
718
0
}
719
720
bool isValidNode(const Reference<XAnimationNode>& xNode)
721
0
{
722
0
    if (xNode.is())
723
0
    {
724
0
        sal_Int16 nNodeType = xNode->getType();
725
0
        auto iterator = constAnimationNodeTypeToString.find(nNodeType);
726
0
        return iterator != constAnimationNodeTypeToString.end();
727
0
    }
728
0
    return false;
729
0
}
730
731
SdrObject* getObjectForShape(uno::Reference<drawing::XShape> const& xShape)
732
0
{
733
0
    if (!xShape.is())
734
0
        return nullptr;
735
0
    SvxShape* pShape = comphelper::getFromUnoTunnel<SvxShape>(xShape);
736
0
    if (pShape)
737
0
        return pShape->GetSdrObject();
738
0
    return nullptr;
739
0
}
740
741
SdrObject* getTargetObject(const uno::Any& aTargetAny)
742
0
{
743
0
    SdrObject* pObject = nullptr;
744
0
    uno::Reference<drawing::XShape> xShape;
745
746
0
    if ((aTargetAny >>= xShape) && xShape.is())
747
0
    {
748
0
        pObject = getObjectForShape(xShape);
749
0
    }
750
0
    else // if target is not a shape - could be paragraph target containing a shape
751
0
    {
752
0
        presentation::ParagraphTarget aParagraphTarget;
753
0
        if ((aTargetAny >>= aParagraphTarget) && aParagraphTarget.Shape.is())
754
0
        {
755
0
            pObject = getObjectForShape(aParagraphTarget.Shape);
756
0
        }
757
0
    }
758
759
0
    return pObject;
760
0
}
761
762
bool isNodeTargetInShapeGroup(const Reference<XAnimationNode>& xNode)
763
0
{
764
0
    Reference<XAnimate> xAnimate(xNode, UNO_QUERY);
765
0
    if (xAnimate.is())
766
0
    {
767
0
        SdrObject* pObject = getTargetObject(xAnimate->getTarget());
768
0
        if (pObject)
769
0
            return pObject->getParentSdrObjectFromSdrObject() != nullptr;
770
0
    }
771
0
    return false;
772
0
}
773
774
bool isNodeTargetAGroup(const Reference<XAnimationNode>& xNode)
775
0
{
776
0
    Reference<XAnimate> xAnimate(xNode, UNO_QUERY);
777
0
    if (xAnimate.is())
778
0
    {
779
0
        SdrObject* pObject = getTargetObject(xAnimate->getTarget());
780
0
        if (pObject)
781
0
            return pObject->getChildrenOfSdrObject() != nullptr;
782
0
    }
783
0
    return false;
784
0
}
785
786
bool isEffectValidForTarget(const Reference<XAnimationNode>& xNode)
787
0
{
788
0
    const Sequence<NamedValue> aUserData(xNode->getUserData());
789
0
    for (const auto& rValue : aUserData)
790
0
    {
791
0
        if (!IsXMLToken(rValue.Name, XML_PRESET_ID))
792
0
            continue;
793
794
0
        OUString aPresetId;
795
0
        if (rValue.Value >>= aPresetId)
796
0
        {
797
0
            if (constNonValidEffectsForGroupSet.find(aPresetId.toUtf8())
798
0
                != constNonValidEffectsForGroupSet.end())
799
0
            {
800
                // it's in the list, so we need to check if the effect target is a group or not
801
0
                Reference<XTimeContainer> xContainer(xNode, UNO_QUERY);
802
0
                if (xContainer.is())
803
0
                {
804
0
                    Reference<XEnumerationAccess> xEnumerationAccess(xContainer, UNO_QUERY);
805
0
                    Reference<XEnumeration> xEnumeration = xEnumerationAccess->createEnumeration();
806
807
                    // target is the same for all children, check the first one
808
0
                    if (xEnumeration.is() && xEnumeration->hasMoreElements())
809
0
                    {
810
0
                        Reference<XAnimationNode> xChildNode(xEnumeration->nextElement(),
811
0
                                                             UNO_QUERY);
812
0
                        if (isNodeTargetAGroup(xChildNode))
813
0
                            return false;
814
0
                    }
815
0
                }
816
0
            }
817
0
        }
818
        // preset id found and checked, we can exit
819
0
        break;
820
0
    }
821
0
    return true;
822
0
}
823
824
void AnimationsExporter::exportAnimations()
825
0
{
826
0
    if (!mxDrawPage.is() || !mxPageProps.is() || !mxRootNode.is() || !hasEffects())
827
0
        return;
828
829
0
    if (isValidNode(mxRootNode))
830
0
    {
831
0
        auto aNode = mrWriter.startNode("root");
832
0
        exportNodeImpl(mxRootNode);
833
0
    }
834
0
}
835
836
void AnimationsExporter::exportNode(const Reference<XAnimationNode>& xNode)
837
0
{
838
    // afaics, when a shape is part of a group any applied effect is ignored
839
    // moreover, some kind of effect, like the ones based on color animations,
840
    // is ignored when applied to a group
841
0
    if (!isValidNode(xNode) || isNodeTargetInShapeGroup(xNode) || !isEffectValidForTarget(xNode))
842
0
        return;
843
0
    auto aStruct = mrWriter.startStruct();
844
0
    exportNodeImpl(xNode);
845
0
}
846
847
void AnimationsExporter::exportNodeImpl(const Reference<XAnimationNode>& xNode)
848
0
{
849
0
    try
850
0
    {
851
0
        std::string sId = GetInterfaceHash(xNode);
852
0
        mrWriter.put("id", sId);
853
0
        sal_Int16 nNodeType = xNode->getType();
854
0
        auto iterator = constAnimationNodeTypeToString.find(nNodeType);
855
0
        assert(iterator != constAnimationNodeTypeToString.end() && "must be previously checked with isValidNode");
856
0
        mrWriter.put("nodeName", iterator->second);
857
858
        // common properties
859
0
        OStringBuffer sTmp;
860
0
        Any aTemp;
861
0
        double fTemp = 0;
862
0
        sal_Int16 nTemp;
863
864
0
        aTemp = xNode->getBegin();
865
0
        if (aTemp.hasValue())
866
0
        {
867
0
            convertTiming(sTmp, aTemp);
868
0
            mrWriter.put("begin", sTmp.makeStringAndClear());
869
0
        }
870
0
        aTemp = xNode->getDuration();
871
0
        if (aTemp.hasValue())
872
0
        {
873
0
            if (aTemp >>= fTemp)
874
0
            {
875
0
                convertDouble(sTmp, fTemp);
876
0
                sTmp.append('s');
877
0
                mrWriter.put("dur", sTmp.makeStringAndClear());
878
0
            }
879
0
            else
880
0
            {
881
0
                Timing eTiming;
882
0
                if (aTemp >>= eTiming)
883
0
                {
884
0
                    mrWriter.put("dur", eTiming == Timing_INDEFINITE ? "indefinite" : "media");
885
0
                }
886
0
            }
887
0
        }
888
0
        aTemp = xNode->getEnd();
889
0
        if (aTemp.hasValue())
890
0
        {
891
0
            convertTiming(sTmp, aTemp);
892
0
            mrWriter.put("end", sTmp.makeStringAndClear());
893
0
        }
894
0
        nTemp = xNode->getFill();
895
0
        if (nTemp != AnimationFill::DEFAULT)
896
0
        {
897
0
            convertEnum(sTmp, nTemp, constFillToString);
898
0
            mrWriter.put("fill", sTmp.makeStringAndClear());
899
0
        }
900
0
        nTemp = xNode->getFillDefault();
901
0
        if (nTemp != AnimationFill::INHERIT)
902
0
        {
903
0
            convertEnum(sTmp, nTemp, constFillToString);
904
0
            mrWriter.put("fillDefault", sTmp.makeStringAndClear());
905
0
        }
906
0
        nTemp = xNode->getRestart();
907
0
        if (nTemp != AnimationRestart::DEFAULT)
908
0
        {
909
0
            convertEnum(sTmp, nTemp, constRestartToString);
910
0
            mrWriter.put("restart", sTmp.makeStringAndClear());
911
0
        }
912
0
        nTemp = xNode->getRestartDefault();
913
0
        if (nTemp != AnimationRestart::INHERIT)
914
0
        {
915
0
            convertEnum(sTmp, nTemp, constRestartToString);
916
0
            mrWriter.put("restartDefault", sTmp.makeStringAndClear());
917
0
        }
918
0
        fTemp = xNode->getAcceleration();
919
0
        if (fTemp != 0.0)
920
0
        {
921
0
            convertDouble(sTmp, fTemp);
922
0
            mrWriter.put("accelerate", sTmp.makeStringAndClear());
923
0
        }
924
0
        fTemp = xNode->getDecelerate();
925
0
        if (fTemp != 0.0)
926
0
        {
927
0
            convertDouble(sTmp, fTemp);
928
0
            mrWriter.put("decelerate", sTmp.makeStringAndClear());
929
0
        }
930
0
        bool bTemp = xNode->getAutoReverse();
931
0
        if (bTemp)
932
0
        {
933
0
            convertBool(sTmp, bTemp);
934
0
            mrWriter.put("autoreverse", sTmp.makeStringAndClear());
935
0
        }
936
0
        aTemp = xNode->getRepeatCount();
937
0
        if (aTemp.hasValue())
938
0
        {
939
0
            Timing eTiming;
940
0
            if ((aTemp >>= eTiming) && (eTiming == Timing_INDEFINITE))
941
0
            {
942
0
                mrWriter.put("repeatCount", "indefinite");
943
0
            }
944
0
            else if (aTemp >>= fTemp)
945
0
            {
946
0
                convertDouble(sTmp, fTemp);
947
0
                mrWriter.put("repeatCount", sTmp.makeStringAndClear());
948
0
            }
949
0
        }
950
0
        aTemp = xNode->getRepeatDuration();
951
0
        if (aTemp.hasValue())
952
0
        {
953
0
            Timing eTiming;
954
0
            if ((aTemp >>= eTiming) && (eTiming == Timing_INDEFINITE))
955
0
            {
956
0
                mrWriter.put("repeatDur", "indefinite");
957
0
            }
958
0
            else if (aTemp >>= fTemp)
959
0
            {
960
0
                convertDouble(sTmp, fTemp);
961
0
                mrWriter.put("repeatDur", sTmp.makeStringAndClear());
962
0
            }
963
0
        }
964
0
        aTemp = xNode->getEndSync();
965
0
        if (aTemp.hasValue() && (aTemp >>= nTemp))
966
0
        {
967
0
            convertEnum(sTmp, nTemp, constEndSyncToString);
968
0
            mrWriter.put("endSync", sTmp.makeStringAndClear());
969
0
        }
970
971
0
        sal_Int16 nContainerNodeType = EffectNodeType::DEFAULT;
972
0
        const Sequence<NamedValue> aUserData(xNode->getUserData());
973
0
        for (const auto& rValue : aUserData)
974
0
        {
975
0
            if (IsXMLToken(rValue.Name, XML_NODE_TYPE))
976
0
            {
977
0
                if ((rValue.Value >>= nContainerNodeType)
978
0
                    && (nContainerNodeType != EffectNodeType::DEFAULT))
979
0
                {
980
0
                    convertEnum(sTmp, nContainerNodeType, constEffectNodeTypeToString);
981
0
                    mrWriter.put("nodeType", sTmp.makeStringAndClear());
982
0
                }
983
0
            }
984
0
            else if (IsXMLToken(rValue.Name, XML_PRESET_ID))
985
0
            {
986
0
                OUString aPresetId;
987
0
                if (rValue.Value >>= aPresetId)
988
0
                {
989
0
                    mrWriter.put("presetId", aPresetId);
990
0
                }
991
0
            }
992
0
            else if (IsXMLToken(rValue.Name, XML_PRESET_SUB_TYPE))
993
0
            {
994
0
                OUString aPresetSubType;
995
0
                if (rValue.Value >>= aPresetSubType)
996
0
                {
997
0
                    mrWriter.put("presetSubType", aPresetSubType);
998
0
                }
999
0
            }
1000
0
            else if (IsXMLToken(rValue.Name, XML_PRESET_CLASS))
1001
0
            {
1002
0
                sal_Int16 nEffectPresetClass = sal_uInt16(0);
1003
0
                if (rValue.Value >>= nEffectPresetClass)
1004
0
                {
1005
0
                    convertEnum(sTmp, nEffectPresetClass, constEffectPresetClassToString);
1006
0
                    mrWriter.put("presetClass", sTmp.makeStringAndClear());
1007
0
                }
1008
0
            }
1009
0
            else if (IsXMLToken(rValue.Name, XML_MASTER_ELEMENT))
1010
0
            {
1011
0
                Reference<XInterface> xMaster;
1012
0
                rValue.Value >>= xMaster;
1013
0
                if (xMaster.is())
1014
0
                {
1015
0
                    const std::string aIdentifier(GetInterfaceHash(xMaster));
1016
0
                    if (!aIdentifier.empty())
1017
0
                        mrWriter.put("masterElement", aIdentifier);
1018
0
                }
1019
0
            }
1020
0
            else if (IsXMLToken(rValue.Name, XML_GROUP_ID))
1021
0
            {
1022
0
                sal_Int32 nGroupId = 0;
1023
0
                if (rValue.Value >>= nGroupId)
1024
0
                    mrWriter.put("groupId", nGroupId);
1025
0
            }
1026
0
            else
1027
0
            {
1028
0
                OUString aTmp;
1029
0
                if (rValue.Value >>= aTmp)
1030
0
                    mrWriter.put(rValue.Name, aTmp);
1031
0
            }
1032
0
        }
1033
1034
0
        switch (nNodeType)
1035
0
        {
1036
0
            case AnimationNodeType::PAR:
1037
0
            case AnimationNodeType::SEQ:
1038
0
            case AnimationNodeType::ITERATE:
1039
0
            {
1040
0
                Reference<XTimeContainer> xContainer(xNode, UNO_QUERY_THROW);
1041
0
                exportContainer(xContainer);
1042
0
            }
1043
0
            break;
1044
1045
0
            case AnimationNodeType::ANIMATE:
1046
0
            case AnimationNodeType::SET:
1047
0
            case AnimationNodeType::ANIMATEMOTION:
1048
0
            case AnimationNodeType::ANIMATEPHYSICS:
1049
0
            case AnimationNodeType::ANIMATECOLOR:
1050
0
            case AnimationNodeType::ANIMATETRANSFORM:
1051
0
            case AnimationNodeType::TRANSITIONFILTER:
1052
0
            {
1053
0
                Reference<XAnimate> xAnimate(xNode, UNO_QUERY_THROW);
1054
0
                exportAnimate(xAnimate);
1055
0
            }
1056
0
            break;
1057
0
            case AnimationNodeType::AUDIO:
1058
0
            {
1059
0
                SAL_WARN("sd", "AnimationsExporter::exportNode(): Audio Node not supported.");
1060
0
            }
1061
0
            break;
1062
0
            case AnimationNodeType::COMMAND:
1063
0
            {
1064
0
                SAL_WARN("sd", "AnimationsExporter::exportNode(): Command Node not supported.");
1065
0
            }
1066
0
            break;
1067
0
            default:
1068
0
            {
1069
0
                OSL_FAIL(
1070
0
                    "sd unomodel: AnimationsExporter::exportNode(), invalid AnimationNodeType!");
1071
0
            }
1072
0
        }
1073
0
    }
1074
0
    catch (const RuntimeException&)
1075
0
    {
1076
0
        TOOLS_WARN_EXCEPTION("sd", "unomodel: AnimationsExporter");
1077
0
    }
1078
0
}
1079
1080
void AnimationsExporter::convertTiming(OStringBuffer& sTmp, const Any& rValue)
1081
0
{
1082
0
    if (!rValue.hasValue())
1083
0
        return;
1084
1085
0
    if (auto pSequence = o3tl::tryAccess<Sequence<Any>>(rValue))
1086
0
    {
1087
0
        const sal_Int32 nLength = pSequence->getLength();
1088
0
        sal_Int32 nElement;
1089
0
        const Any* pAny = pSequence->getConstArray();
1090
1091
0
        OStringBuffer sTmp2;
1092
1093
0
        for (nElement = 0; nElement < nLength; nElement++, pAny++)
1094
0
        {
1095
0
            if (!sTmp.isEmpty())
1096
0
                sTmp.append(';');
1097
0
            convertTiming(sTmp2, *pAny);
1098
0
            sTmp.append(sTmp2);
1099
0
            sTmp2.setLength(0);
1100
0
        }
1101
0
    }
1102
0
    else if (auto x = o3tl::tryAccess<double>(rValue))
1103
0
    {
1104
0
        sTmp.append(*x);
1105
0
        sTmp.append('s');
1106
0
    }
1107
0
    else if (auto pTiming = o3tl::tryAccess<Timing>(rValue))
1108
0
    {
1109
0
        const auto svTiming = (*pTiming == Timing_MEDIA)
1110
0
                                  ? constTimingToString.at(Timing_MEDIA)
1111
0
                                  : constTimingToString.at(Timing_INDEFINITE);
1112
0
        sTmp.append(svTiming);
1113
0
    }
1114
0
    else if (auto pEvent = o3tl::tryAccess<Event>(rValue))
1115
0
    {
1116
0
        OStringBuffer sTmp2;
1117
1118
0
        if (pEvent->Trigger != EventTrigger::NONE)
1119
0
        {
1120
0
            if (pEvent->Source.hasValue())
1121
0
            {
1122
0
                OStringBuffer aTriggerBuffer;
1123
                // hash must not start with a digit or on client it is parsed as a time in seconds
1124
0
                aTriggerBuffer.append("id");
1125
0
                anim::convertTarget(aTriggerBuffer, pEvent->Source);
1126
0
                OString sTriggerHash(aTriggerBuffer.makeStringAndClear());
1127
0
                sTmp.append(sTriggerHash);
1128
0
                sTmp.append('.');
1129
0
                appendTrigger(pEvent->Source, sTriggerHash);
1130
0
            }
1131
1132
0
            convertEnum(sTmp2, pEvent->Trigger, constEventTriggerToString);
1133
1134
0
            sTmp.append(sTmp2);
1135
0
            sTmp2.setLength(0);
1136
0
        }
1137
1138
0
        if (pEvent->Offset.hasValue())
1139
0
        {
1140
0
            convertTiming(sTmp2, pEvent->Offset);
1141
1142
0
            if (!sTmp.isEmpty())
1143
0
                sTmp.append('+');
1144
1145
0
            sTmp.append(sTmp2);
1146
0
            sTmp2.setLength(0);
1147
0
        }
1148
0
    }
1149
0
    else
1150
0
    {
1151
0
        OSL_FAIL("sd.unomodel: AnimationsExporter::convertTiming, invalid value type!");
1152
0
    }
1153
0
}
1154
1155
void AnimationsExporter::appendTrigger(const css::uno::Any& rTarget, const OString& rTriggerHash)
1156
0
{
1157
0
    css::uno::Reference<css::uno::XInterface> xRef;
1158
0
    rTarget >>= xRef;
1159
1160
0
    uno::Reference<drawing::XShape> xShape(xRef, uno::UNO_QUERY);
1161
0
    if (!xShape.is())
1162
0
    {
1163
0
        if (auto xParagraphTarget = o3tl::tryAccess<css::presentation::ParagraphTarget>(rTarget))
1164
0
        {
1165
0
            xShape = xParagraphTarget->Shape;
1166
0
        }
1167
0
    }
1168
0
    if (xShape.is())
1169
0
    {
1170
0
        auto* pObject = SdrObject::getSdrObjectFromXShape(xShape);
1171
0
        maEventTriggerSet[pObject] = rTriggerHash;
1172
0
    }
1173
0
}
1174
1175
void AnimationsExporter::exportTriggersImpl(const uno::Reference<drawing::XShapes>& xShapes) const
1176
0
{
1177
0
    if (!xShapes.is())
1178
0
        return;
1179
1180
0
    sal_Int32 nCount = xShapes->getCount();
1181
0
    for (sal_Int32 i = 0; i < nCount; ++i)
1182
0
    {
1183
0
        auto xObject = xShapes->getByIndex(i);
1184
0
        uno::Reference<drawing::XShape> xShape(xObject, uno::UNO_QUERY);
1185
0
        if (!xShape.is())
1186
0
            continue;
1187
1188
0
        auto* pObject = SdrObject::getSdrObjectFromXShape(xShape);
1189
0
        if (maEventTriggerSet.find(pObject) == maEventTriggerSet.end())
1190
0
            continue;
1191
0
        {
1192
0
            auto aShape = mrWriter.startStruct();
1193
0
            mrWriter.put("hash", maEventTriggerSet.at(pObject));
1194
0
            {
1195
0
                auto const& rRectangle = pObject->GetLogicRect();
1196
0
                auto aRectangle
1197
0
                    = o3tl::convert(rRectangle, o3tl::Length::mm100, o3tl::Length::twip);
1198
0
                auto aRect = mrWriter.startNode("bounds");
1199
0
                mrWriter.put("x", aRectangle.Left());
1200
0
                mrWriter.put("y", aRectangle.Top());
1201
0
                mrWriter.put("width", aRectangle.GetWidth());
1202
0
                mrWriter.put("height", aRectangle.GetHeight());
1203
0
            }
1204
0
        }
1205
0
    }
1206
0
}
1207
1208
void AnimationsExporter::exportTriggers() const
1209
0
{
1210
0
    uno::Reference<drawing::XShapes> const xShapes(mxDrawPage, uno::UNO_QUERY_THROW);
1211
0
    if (!xShapes.is())
1212
0
        return;
1213
1214
0
    auto aTriggerList = mrWriter.startArray("triggers");
1215
0
    exportTriggersImpl(xShapes);
1216
0
}
1217
1218
void AnimationsExporter::convertValue(XMLTokenEnum eAttributeName, OStringBuffer& sTmp,
1219
                                      const Any& rValue) const
1220
0
{
1221
0
    if (!rValue.hasValue())
1222
0
        return;
1223
1224
0
    if (auto pValuePair = o3tl::tryAccess<ValuePair>(rValue))
1225
0
    {
1226
0
        OStringBuffer sTmp2;
1227
0
        convertValue(eAttributeName, sTmp, pValuePair->First);
1228
0
        sTmp.append(',');
1229
0
        convertValue(eAttributeName, sTmp2, pValuePair->Second);
1230
0
        sTmp.append(sTmp2);
1231
0
    }
1232
0
    else if (auto pSequence = o3tl::tryAccess<Sequence<Any>>(rValue))
1233
0
    {
1234
0
        const sal_Int32 nLength = pSequence->getLength();
1235
0
        sal_Int32 nElement;
1236
0
        const Any* pAny = pSequence->getConstArray();
1237
1238
0
        OStringBuffer sTmp2;
1239
1240
0
        for (nElement = 0; nElement < nLength; nElement++, pAny++)
1241
0
        {
1242
0
            if (!sTmp.isEmpty())
1243
0
                sTmp.append(';');
1244
0
            convertValue(eAttributeName, sTmp2, *pAny);
1245
0
            sTmp.append(sTmp2);
1246
0
            sTmp2.setLength(0);
1247
0
        }
1248
0
    }
1249
0
    else
1250
0
    {
1251
0
        switch (eAttributeName)
1252
0
        {
1253
0
            case XML_X:
1254
0
            case XML_Y:
1255
0
            case XML_WIDTH:
1256
0
            case XML_HEIGHT:
1257
0
            case XML_ANIMATETRANSFORM:
1258
0
            case XML_ANIMATEMOTION:
1259
0
            case XML_ANIMATEPHYSICS:
1260
0
            {
1261
0
                if (auto sValue = o3tl::tryAccess<OUString>(rValue))
1262
0
                {
1263
0
                    sTmp.append(sValue->toUtf8());
1264
0
                }
1265
0
                else if (auto aValue = o3tl::tryAccess<double>(rValue))
1266
0
                {
1267
0
                    sTmp.append(*aValue);
1268
0
                }
1269
0
                else
1270
0
                {
1271
0
                    OSL_FAIL("sd::AnimationsExporter::convertValue(), invalid value type!");
1272
0
                }
1273
0
                return;
1274
0
            }
1275
0
            case XML_SKEWX:
1276
0
            case XML_ROTATE:
1277
0
            case XML_OPACITY:
1278
0
            case XML_TRANSITIONFILTER:
1279
0
                if (auto aValue = o3tl::tryAccess<double>(rValue))
1280
0
                {
1281
0
                    sTmp.append(*aValue);
1282
0
                }
1283
0
                break;
1284
0
            case XML_TEXT_ROTATION_ANGLE:
1285
0
                if (auto aValue = o3tl::tryAccess<sal_Int16>(rValue))
1286
0
                {
1287
                    // on win and armv7 platforms compiler complains
1288
                    // that append(sal_Int16) is ambiguous
1289
0
                    sTmp.append(static_cast<sal_Int32>(*aValue));
1290
0
                }
1291
0
                break;
1292
0
            case XML_FILL_COLOR:
1293
0
            case XML_STROKE_COLOR:
1294
0
            case XML_DIM:
1295
0
            case XML_COLOR:
1296
0
            {
1297
0
                convertColor(sTmp, rValue);
1298
0
            }
1299
0
            break;
1300
0
            case XML_FILL:
1301
0
                if (auto aValue = o3tl::tryAccess<drawing::FillStyle>(rValue))
1302
0
                {
1303
0
                    convertEnum(sTmp, *aValue, constFillStyleToString);
1304
0
                }
1305
0
                break;
1306
0
            case XML_STROKE:
1307
0
                if (auto aValue = o3tl::tryAccess<drawing::LineStyle>(rValue))
1308
0
                {
1309
0
                    convertEnum(sTmp, *aValue, constLineStyleToString);
1310
0
                }
1311
0
                break;
1312
0
            case XML_FONTSIZE:
1313
0
                if (auto aValue = o3tl::tryAccess<double>(rValue))
1314
0
                {
1315
0
                    double fValue = *aValue * 100;
1316
0
                    fValue += fValue > 0 ? 0.5 : -0.5;
1317
0
                    auto nValue = static_cast<sal_Int32>(fValue);
1318
0
                    sTmp.append(nValue); // percent
1319
0
                }
1320
0
                break;
1321
0
            case XML_FONT_WEIGHT:
1322
0
            case XML_FONT_STYLE:
1323
0
            case XML_TEXT_UNDERLINE:
1324
0
                SAL_WARN("sd", "AnimationsExporter::convertValue(): value type "
1325
0
                                   << GetXMLToken(eAttributeName) << " not supported");
1326
0
                break;
1327
0
            case XML_VISIBILITY:
1328
0
                if (auto aValue = o3tl::tryAccess<bool>(rValue))
1329
0
                {
1330
0
                    OUString sValue = *aValue ? GetXMLToken(XML_VISIBLE) : GetXMLToken(XML_HIDDEN);
1331
0
                    sTmp.append(sValue.toUtf8());
1332
0
                }
1333
0
                break;
1334
0
            default:
1335
0
                OSL_FAIL("unomodel: AnimationsExporter::convertValue(), invalid AttributeName!");
1336
0
        }
1337
0
    }
1338
0
}
1339
1340
void AnimationsExporter::exportContainer(const Reference<XTimeContainer>& xContainer)
1341
0
{
1342
0
    try
1343
0
    {
1344
0
        const sal_Int32 nNodeType = xContainer->getType();
1345
1346
0
        if (nNodeType == AnimationNodeType::ITERATE)
1347
0
        {
1348
0
            OStringBuffer sTmp;
1349
0
            Reference<XIterateContainer> xIter(xContainer, UNO_QUERY_THROW);
1350
1351
0
            Any aTemp(xIter->getTarget());
1352
0
            if (aTemp.hasValue())
1353
0
            {
1354
0
                anim::convertTarget(sTmp, aTemp);
1355
0
                mrWriter.put("targetElement", sTmp.makeStringAndClear());
1356
0
            }
1357
0
            sal_Int16 nTemp = xIter->getSubItem();
1358
0
            if (nTemp)
1359
0
            {
1360
0
                convertEnum(sTmp, nTemp, constSubItemToString);
1361
0
                mrWriter.put("subItem", sTmp.makeStringAndClear());
1362
0
            }
1363
0
            nTemp = xIter->getIterateType();
1364
0
            if (nTemp)
1365
0
            {
1366
0
                convertEnum(sTmp, nTemp, constIterateTypeToString);
1367
0
                mrWriter.put("iterateType", sTmp.makeStringAndClear());
1368
0
            }
1369
0
            double fTemp = xIter->getIterateInterval();
1370
0
            if (fTemp != 0)
1371
0
            {
1372
0
                OUStringBuffer buf;
1373
0
                ::sax::Converter::convertDuration(buf, fTemp / (24 * 60 * 60));
1374
0
                mrWriter.put("iterateInterval", sTmp.makeStringAndClear());
1375
0
            }
1376
0
        }
1377
1378
0
        auto anArray = mrWriter.startArray("children");
1379
1380
0
        Reference<XEnumerationAccess> xEnumerationAccess(xContainer, UNO_QUERY_THROW);
1381
0
        Reference<XEnumeration> xEnumeration(xEnumerationAccess->createEnumeration(),
1382
0
                                             css::uno::UNO_SET_THROW);
1383
0
        while (xEnumeration->hasMoreElements())
1384
0
        {
1385
0
            Reference<XAnimationNode> xChildNode(xEnumeration->nextElement(), UNO_QUERY_THROW);
1386
0
            exportNode(xChildNode);
1387
0
        }
1388
0
    }
1389
0
    catch (const RuntimeException&)
1390
0
    {
1391
0
        TOOLS_WARN_EXCEPTION("sd", "unomodel: AnimationsExporter");
1392
0
    }
1393
0
}
1394
1395
void AnimationsExporter::exportAnimate(const Reference<XAnimate>& xAnimate)
1396
0
{
1397
0
    try
1398
0
    {
1399
0
        const sal_Int16 nNodeType = xAnimate->getType();
1400
1401
0
        OStringBuffer sTmp;
1402
0
        sal_Int16 nTemp;
1403
0
        bool bTemp;
1404
1405
0
        Any aTemp(xAnimate->getTarget());
1406
0
        if (aTemp.hasValue())
1407
0
        {
1408
0
            anim::convertTarget(sTmp, aTemp);
1409
0
            mrWriter.put("targetElement", sTmp.makeStringAndClear());
1410
0
            SdrObject* pObject = getTargetObject(aTemp);
1411
0
            if (pObject)
1412
0
            {
1413
0
                mrWriter.put("title", pObject->GetTitle());
1414
0
            }
1415
0
        }
1416
0
        nTemp = xAnimate->getSubItem();
1417
0
        if (nTemp)
1418
0
        {
1419
0
            convertEnum(sTmp, nTemp, constSubItemToString);
1420
0
            mrWriter.put("subItem", sTmp.makeStringAndClear());
1421
0
        }
1422
1423
0
        XMLTokenEnum eAttributeName = XML_TOKEN_INVALID;
1424
0
        if (nNodeType == AnimationNodeType::TRANSITIONFILTER)
1425
0
        {
1426
0
            eAttributeName = XML_TRANSITIONFILTER;
1427
0
        }
1428
0
        else if (nNodeType == AnimationNodeType::ANIMATETRANSFORM)
1429
0
        {
1430
0
            eAttributeName = XML_ANIMATETRANSFORM;
1431
0
        }
1432
0
        else if (nNodeType == AnimationNodeType::ANIMATEMOTION)
1433
0
        {
1434
0
            eAttributeName = XML_ANIMATEMOTION;
1435
0
        }
1436
0
        else if (nNodeType == AnimationNodeType::ANIMATEPHYSICS)
1437
0
        {
1438
0
            eAttributeName = XML_ANIMATEPHYSICS;
1439
0
        }
1440
0
        else
1441
0
        {
1442
0
            OString sTemp(xAnimate->getAttributeName().toUtf8());
1443
0
            if (!sTemp.isEmpty())
1444
0
            {
1445
0
                auto iterator = constAttributeNameToXMLEnum.find(sTemp);
1446
0
                if (iterator != constAttributeNameToXMLEnum.end())
1447
0
                {
1448
0
                    eAttributeName = iterator->second;
1449
0
                    mrWriter.put("attributeName", sTemp);
1450
0
                }
1451
0
                else
1452
0
                {
1453
0
                    mrWriter.put("attributeName", "invalid");
1454
0
                }
1455
0
            }
1456
0
        }
1457
1458
0
        Sequence<Any> aValues(xAnimate->getValues());
1459
0
        if (aValues.hasElements())
1460
0
        {
1461
0
            aTemp <<= aValues;
1462
0
            convertValue(eAttributeName, sTmp, aTemp);
1463
0
            mrWriter.put("values", sTmp.makeStringAndClear());
1464
0
        }
1465
0
        else
1466
0
        {
1467
0
            aTemp = xAnimate->getFrom();
1468
0
            if (aTemp.hasValue())
1469
0
            {
1470
0
                convertValue(eAttributeName, sTmp, aTemp);
1471
0
                mrWriter.put("from", sTmp.makeStringAndClear());
1472
0
            }
1473
1474
0
            aTemp = xAnimate->getBy();
1475
0
            if (aTemp.hasValue())
1476
0
            {
1477
0
                convertValue(eAttributeName, sTmp, aTemp);
1478
0
                mrWriter.put("by", sTmp.makeStringAndClear());
1479
0
            }
1480
1481
0
            aTemp = xAnimate->getTo();
1482
0
            if (aTemp.hasValue())
1483
0
            {
1484
0
                convertValue(eAttributeName, sTmp, aTemp);
1485
0
                mrWriter.put("to", sTmp.makeStringAndClear());
1486
0
            }
1487
0
        }
1488
1489
0
        if (nNodeType != AnimationNodeType::SET)
1490
0
        {
1491
0
            const Sequence<double> aKeyTimes(xAnimate->getKeyTimes());
1492
0
            if (aKeyTimes.hasElements())
1493
0
            {
1494
0
                for (const auto& rKeyTime : aKeyTimes)
1495
0
                {
1496
0
                    if (!sTmp.isEmpty())
1497
0
                        sTmp.append(';');
1498
1499
0
                    sTmp.append(rKeyTime);
1500
0
                }
1501
0
                mrWriter.put("keyTimes", sTmp.makeStringAndClear());
1502
0
            }
1503
1504
0
            OUString sTemp(xAnimate->getFormula());
1505
0
            if (!sTemp.isEmpty())
1506
0
            {
1507
0
                mrWriter.put("formula", sTemp);
1508
0
            }
1509
1510
0
            if ((nNodeType != AnimationNodeType::TRANSITIONFILTER)
1511
0
                && (nNodeType != AnimationNodeType::AUDIO))
1512
0
            {
1513
                // calcMode  = "discrete | linear | paced | spline"
1514
0
                nTemp = xAnimate->getCalcMode();
1515
0
                if (((nNodeType == AnimationNodeType::ANIMATEMOTION)
1516
0
                     && (nTemp != AnimationCalcMode::PACED))
1517
0
                    || ((nNodeType != AnimationNodeType::ANIMATEMOTION)
1518
0
                        && (nTemp != AnimationCalcMode::LINEAR)))
1519
0
                {
1520
0
                    convertEnum(sTmp, nTemp, constCalcModeToString);
1521
0
                    mrWriter.put("calcMode", sTmp.makeStringAndClear());
1522
0
                }
1523
1524
0
                bTemp = xAnimate->getAccumulate();
1525
0
                if (bTemp)
1526
0
                {
1527
0
                    mrWriter.put("accumulate", "sum");
1528
0
                }
1529
1530
0
                nTemp = xAnimate->getAdditive();
1531
0
                if (nTemp != AnimationAdditiveMode::REPLACE)
1532
0
                {
1533
0
                    convertEnum(sTmp, nTemp, constAdditiveModeToString);
1534
0
                    mrWriter.put("additive", sTmp.makeStringAndClear());
1535
0
                }
1536
0
            }
1537
1538
0
            const Sequence<TimeFilterPair> aTimeFilter(xAnimate->getTimeFilter());
1539
0
            if (aTimeFilter.hasElements())
1540
0
            {
1541
0
                for (const auto& rPair : aTimeFilter)
1542
0
                {
1543
0
                    if (!sTmp.isEmpty())
1544
0
                        sTmp.append(';');
1545
1546
0
                    sTmp.append(OString::number(rPair.Time) + ","
1547
0
                                + OString::number(rPair.Progress));
1548
0
                }
1549
0
                mrWriter.put("keySplines", sTmp.makeStringAndClear());
1550
0
            }
1551
0
        }
1552
1553
0
        switch (nNodeType)
1554
0
        {
1555
0
            case AnimationNodeType::ANIMATEMOTION:
1556
0
            {
1557
0
                Reference<XAnimateMotion> xAnimateMotion(xAnimate, UNO_QUERY_THROW);
1558
1559
0
                aTemp = xAnimateMotion->getPath();
1560
0
                if (aTemp.hasValue())
1561
0
                {
1562
0
                    convertPath(sTmp, aTemp);
1563
0
                    mrWriter.put("path", sTmp.makeStringAndClear());
1564
0
                }
1565
0
            }
1566
0
            break;
1567
0
            case AnimationNodeType::ANIMATEPHYSICS:
1568
0
            {
1569
0
                SAL_WARN(
1570
0
                    "sd",
1571
0
                    "unomodel: AnimationsExporter::exportAnimate(): AnimatePhysics not supported");
1572
0
            }
1573
0
            break;
1574
0
            case AnimationNodeType::ANIMATECOLOR:
1575
0
            {
1576
0
                Reference<XAnimateColor> xAnimateColor(xAnimate, UNO_QUERY_THROW);
1577
1578
0
                nTemp = xAnimateColor->getColorInterpolation();
1579
0
                mrWriter.put("colorInterpolation",
1580
0
                             (nTemp == AnimationColorSpace::RGB) ? "rgb" : "hsl");
1581
1582
0
                bTemp = xAnimateColor->getDirection();
1583
0
                mrWriter.put("colorInterpolationDirection",
1584
0
                             bTemp ? "clockwise" : "counterClockwise");
1585
0
            }
1586
0
            break;
1587
0
            case AnimationNodeType::ANIMATETRANSFORM:
1588
0
            {
1589
0
                mrWriter.put("attributeName", "transform");
1590
1591
0
                Reference<XAnimateTransform> xTransform(xAnimate, UNO_QUERY_THROW);
1592
0
                nTemp = xTransform->getTransformType();
1593
0
                convertEnum(sTmp, nTemp, constTransformTypeToString);
1594
0
                mrWriter.put("transformType", sTmp.makeStringAndClear());
1595
0
            }
1596
0
            break;
1597
0
            case AnimationNodeType::TRANSITIONFILTER:
1598
0
            {
1599
0
                Reference<XTransitionFilter> xTransitionFilter(xAnimate, UNO_QUERY);
1600
1601
0
                sal_Int16 nTransition = xTransitionFilter->getTransition();
1602
0
                convertEnum(sTmp, nTransition, constTransitionTypeToString);
1603
0
                mrWriter.put("transitionType", sTmp.makeStringAndClear());
1604
1605
0
                sal_Int16 nSubtype = xTransitionFilter->getSubtype();
1606
0
                if (nSubtype != TransitionSubType::DEFAULT)
1607
0
                {
1608
0
                    convertEnum(sTmp, nSubtype, constTransitionSubTypeToString);
1609
0
                    mrWriter.put("transitionSubType", sTmp.makeStringAndClear());
1610
0
                }
1611
1612
0
                bTemp = xTransitionFilter->getMode();
1613
0
                if (!bTemp)
1614
0
                    mrWriter.put("transitionMode", "out");
1615
1616
0
                bTemp = xTransitionFilter->getDirection();
1617
0
                if (!bTemp)
1618
0
                    mrWriter.put("transitionDirection", "reverse");
1619
1620
0
                if ((nTransition == TransitionType::FADE)
1621
0
                    && ((nSubtype == TransitionSubType::FADETOCOLOR)
1622
0
                        || (nSubtype == TransitionSubType::FADEFROMCOLOR)))
1623
0
                {
1624
0
                    sal_Int32 nColor = xTransitionFilter->getFadeColor();
1625
0
                    convertColor(sTmp, nColor);
1626
0
                    mrWriter.put("transitionFadeColor", sTmp.makeStringAndClear());
1627
0
                }
1628
0
            }
1629
0
            break;
1630
0
            default:
1631
0
            {
1632
0
                SAL_WARN("sd",
1633
0
                         "unomodel: AnimationsExporter::exportAnimate(): not supported node type: "
1634
0
                             << nNodeType);
1635
0
            }
1636
0
        }
1637
0
    }
1638
0
    catch (const Exception&)
1639
0
    {
1640
0
        TOOLS_WARN_EXCEPTION("sd", "unomodel: AnimationsExporter");
1641
0
    }
1642
0
}
1643
1644
void GetDocStructureSlides(::tools::JsonWriter& rJsonWriter, const SdXImpressDocument* pDoc,
1645
                           const std::map<OUString, OUString>& rArguments)
1646
0
{
1647
0
    auto it = rArguments.find(u"filter"_ustr);
1648
0
    if (it != rArguments.end())
1649
0
    {
1650
        // If filter is present but we are filtering not to slide information
1651
0
        if (!it->second.equals(u"slides"_ustr))
1652
0
            return;
1653
0
    }
1654
1655
0
    sal_uInt16 nPageCount = pDoc->GetDoc()->GetSdPageCount(PageKind::Standard);
1656
0
    sal_uInt16 nMasterPageCount = pDoc->GetDoc()->GetMasterSdPageCount(PageKind::Standard);
1657
1658
0
    rJsonWriter.put("SlideCount", nPageCount);
1659
0
    rJsonWriter.put("MasterSlideCount", nMasterPageCount);
1660
1661
    // write data of every master slide
1662
0
    if (nMasterPageCount > 0)
1663
0
    {
1664
0
        auto aMasterPagesNode = rJsonWriter.startNode("MasterSlides");
1665
0
        for (int nMPId = 0; nMPId < nMasterPageCount; nMPId++)
1666
0
        {
1667
0
            auto aMasterPageNode = rJsonWriter.startNode("MasterSlide " + std::to_string(nMPId));
1668
0
            const OUString& aMName
1669
0
                = pDoc->GetDoc()->GetMasterSdPage(nMPId, PageKind::Standard)->GetName();
1670
0
            rJsonWriter.put("Name", aMName);
1671
0
        }
1672
0
    }
1673
1674
    // write data of every slide
1675
0
    if (nPageCount > 0)
1676
0
    {
1677
0
        auto aPagesNode = rJsonWriter.startNode("Slides");
1678
0
        for (int nPId = 0; nPId < nPageCount; nPId++)
1679
0
        {
1680
0
            auto aPageNode = rJsonWriter.startNode("Slide " + std::to_string(nPId));
1681
0
            SdPage* pPageStandard = pDoc->GetDoc()->GetSdPage(nPId, PageKind::Standard);
1682
1683
            // Slide Name
1684
0
            rJsonWriter.put("SlideName", pPageStandard->GetName());
1685
1686
            // MasterSlide Name
1687
0
            const FmFormPage* pMasterPage
1688
0
                = dynamic_cast<const FmFormPage*>(&pPageStandard->TRG_GetMasterPage());
1689
1690
0
            if (pMasterPage)
1691
0
            {
1692
0
                rJsonWriter.put("MasterSlideName", pMasterPage->GetName());
1693
0
            }
1694
1695
            // Layout id, and name.
1696
0
            AutoLayout nLayout = pPageStandard->GetAutoLayout();
1697
0
            rJsonWriter.put("LayoutId", static_cast<int>(nLayout));
1698
0
            rJsonWriter.put("LayoutName", SdPage::autoLayoutToString(nLayout));
1699
1700
            // Every Objects in the page
1701
0
            int nObjCount = pPageStandard->GetObjCount();
1702
0
            rJsonWriter.put("ObjectCount", nObjCount);
1703
1704
0
            if (nObjCount > 0)
1705
0
            {
1706
0
                auto aObjectsNode = rJsonWriter.startNode("Objects");
1707
0
                for (int nOId = 0; nOId < nObjCount; nOId++)
1708
0
                {
1709
0
                    auto aObjectNode = rJsonWriter.startNode("Objects " + std::to_string(nOId));
1710
0
                    SdrObject* pSdrObj = pPageStandard->GetObj(nOId);
1711
0
                    SdrTextObj* pSdrTxtObj = DynCastSdrTextObj(pSdrObj);
1712
0
                    if (pSdrTxtObj && pSdrTxtObj->HasText())
1713
0
                    {
1714
0
                        sal_Int32 nTextCount = pSdrTxtObj->getTextCount();
1715
0
                        rJsonWriter.put("TextCount", nTextCount);
1716
0
                        if (nTextCount > 0)
1717
0
                        {
1718
0
                            auto aTextsNode = rJsonWriter.startNode("Texts");
1719
0
                            for (int nTId = 0; nTId < nTextCount; nTId++)
1720
0
                            {
1721
0
                                auto aTextNode
1722
0
                                    = rJsonWriter.startNode("Text " + std::to_string(nTId));
1723
0
                                SdrText* pSdrTxt = pSdrTxtObj->getText(nTId);
1724
0
                                OutlinerParaObject* pOutlinerParaObject
1725
0
                                    = pSdrTxt->GetOutlinerParaObject();
1726
1727
0
                                sal_Int32 nParaCount
1728
0
                                    = pOutlinerParaObject->GetTextObject().GetParagraphCount();
1729
1730
0
                                rJsonWriter.put("ParaCount", nParaCount);
1731
0
                                auto aParasNode = rJsonWriter.startArray("Paragraphs");
1732
0
                                for (int nParaId = 0; nParaId < nParaCount; nParaId++)
1733
0
                                {
1734
0
                                    OUString aParaStr(
1735
0
                                        pOutlinerParaObject->GetTextObject().GetText(nParaId));
1736
1737
0
                                    rJsonWriter.putSimpleValue(aParaStr);
1738
0
                                }
1739
0
                            }
1740
0
                        }
1741
0
                    }
1742
0
                }
1743
0
            }
1744
0
        }
1745
0
    }
1746
0
}
1747
1748
} // end anonymous namespace
1749
1750
SdUnoForbiddenCharsTable::SdUnoForbiddenCharsTable( SdrModel* pModel )
1751
166
: SvxUnoForbiddenCharsTable( pModel->GetForbiddenCharsTable() ), mpModel( pModel )
1752
166
{
1753
166
    StartListening( *pModel );
1754
166
}
1755
1756
void SdUnoForbiddenCharsTable::onChange()
1757
68
{
1758
68
    if( mpModel )
1759
68
    {
1760
68
        mpModel->ReformatAllTextObjects();
1761
68
    }
1762
68
}
1763
1764
SdUnoForbiddenCharsTable::~SdUnoForbiddenCharsTable()
1765
166
{
1766
166
    SolarMutexGuard g;
1767
1768
166
    if( mpModel )
1769
166
        EndListening( *mpModel );
1770
166
}
1771
1772
void SdUnoForbiddenCharsTable::Notify( SfxBroadcaster&, const SfxHint& rHint ) noexcept
1773
0
{
1774
0
    if (rHint.GetId() != SfxHintId::ThisIsAnSdrHint)
1775
0
        return;
1776
0
    const SdrHint* pSdrHint = static_cast<const SdrHint*>( &rHint );
1777
0
    if( SdrHintKind::ModelCleared == pSdrHint->GetKind() )
1778
0
    {
1779
0
        mpModel = nullptr;
1780
0
    }
1781
0
}
1782
1783
const sal_uInt16 WID_MODEL_LANGUAGE           =  1;
1784
const sal_uInt16 WID_MODEL_TABSTOP            =  2;
1785
const sal_uInt16 WID_MODEL_VISAREA            =  3;
1786
const sal_uInt16 WID_MODEL_MAPUNIT            =  4;
1787
const sal_uInt16 WID_MODEL_FORBCHARS          =  5;
1788
const sal_uInt16 WID_MODEL_CONTFOCUS          =  6;
1789
const sal_uInt16 WID_MODEL_DSGNMODE           =  7;
1790
const sal_uInt16 WID_MODEL_BASICLIBS          =  8;
1791
const sal_uInt16 WID_MODEL_RUNTIMEUID         =  9;
1792
const sal_uInt16 WID_MODEL_BUILDID            = 10;
1793
const sal_uInt16 WID_MODEL_HASVALIDSIGNATURES = 11;
1794
const sal_uInt16 WID_MODEL_DIALOGLIBS         = 12;
1795
const sal_uInt16 WID_MODEL_FONTS              = 13;
1796
const sal_uInt16 WID_MODEL_INTEROPGRABBAG     = 14;
1797
const sal_uInt16 WID_MODEL_THEME = 15;
1798
const sal_uInt16 WID_MODEL_ALLOWLINKUPDATE    = 16;
1799
const sal_uInt16 WID_MODEL_SLIDESECTIONS      = 17;
1800
1801
static const SvxItemPropertySet* ImplGetDrawModelPropertySet()
1802
14.5k
{
1803
    // Attention: the first parameter HAS TO BE sorted!!!
1804
14.5k
    const static SfxItemPropertyMapEntry aDrawModelPropertyMap_Impl[] =
1805
14.5k
    {
1806
14.5k
        { u"BuildId"_ustr,                WID_MODEL_BUILDID,            ::cppu::UnoType<OUString>::get(),                      0, 0},
1807
14.5k
        { sUNO_Prop_CharLocale,           WID_MODEL_LANGUAGE,           ::cppu::UnoType<lang::Locale>::get(),                                  0, 0},
1808
14.5k
        { sUNO_Prop_TabStop,              WID_MODEL_TABSTOP,            ::cppu::UnoType<sal_Int32>::get(),                                     0, 0},
1809
14.5k
        { sUNO_Prop_VisibleArea,          WID_MODEL_VISAREA,            ::cppu::UnoType<awt::Rectangle>::get(),                                0, 0},
1810
14.5k
        { sUNO_Prop_MapUnit,              WID_MODEL_MAPUNIT,            ::cppu::UnoType<sal_Int16>::get(),                                     beans::PropertyAttribute::READONLY, 0},
1811
14.5k
        { sUNO_Prop_ForbiddenCharacters,  WID_MODEL_FORBCHARS,          cppu::UnoType<i18n::XForbiddenCharacters>::get(), beans::PropertyAttribute::READONLY, 0},
1812
14.5k
        { sUNO_Prop_AutomContFocus,       WID_MODEL_CONTFOCUS,          cppu::UnoType<bool>::get(),                                                 0, 0},
1813
14.5k
        { sUNO_Prop_ApplyFrmDsgnMode,     WID_MODEL_DSGNMODE,           cppu::UnoType<bool>::get(),                                                 0, 0},
1814
14.5k
        { u"BasicLibraries"_ustr,         WID_MODEL_BASICLIBS,          cppu::UnoType<script::XLibraryContainer>::get(),  beans::PropertyAttribute::READONLY, 0},
1815
14.5k
        { u"DialogLibraries"_ustr,        WID_MODEL_DIALOGLIBS,         cppu::UnoType<script::XLibraryContainer>::get(),  beans::PropertyAttribute::READONLY, 0},
1816
14.5k
        { sUNO_Prop_RuntimeUID,           WID_MODEL_RUNTIMEUID,         ::cppu::UnoType<OUString>::get(),                      beans::PropertyAttribute::READONLY, 0},
1817
14.5k
        { sUNO_Prop_HasValidSignatures,   WID_MODEL_HASVALIDSIGNATURES, ::cppu::UnoType<sal_Bool>::get(),                      beans::PropertyAttribute::READONLY, 0},
1818
14.5k
        { sUNO_Prop_AllowLinkUpdate,      WID_MODEL_ALLOWLINKUPDATE,    ::cppu::UnoType<sal_Bool>::get(),                      beans::PropertyAttribute::READONLY, 0},
1819
14.5k
        { u"Fonts"_ustr,                  WID_MODEL_FONTS,              cppu::UnoType<uno::Sequence<uno::Any>>::get(),                     beans::PropertyAttribute::READONLY, 0},
1820
14.5k
        { sUNO_Prop_InteropGrabBag,       WID_MODEL_INTEROPGRABBAG,     cppu::UnoType<uno::Sequence< beans::PropertyValue >>::get(),       0, 0},
1821
14.5k
        { u"SlideSections"_ustr,          WID_MODEL_SLIDESECTIONS,      cppu::UnoType<uno::Sequence< beans::PropertyValue >>::get(),       0, 0},
1822
14.5k
        { sUNO_Prop_Theme,                WID_MODEL_THEME,              cppu::UnoType<util::XTheme>::get(),       0, 0},
1823
14.5k
    };
1824
14.5k
    static SvxItemPropertySet aDrawModelPropertySet_Impl( aDrawModelPropertyMap_Impl, SdrObject::GetGlobalDrawObjectItemPool() );
1825
14.5k
    return &aDrawModelPropertySet_Impl;
1826
14.5k
}
1827
1828
// this ctor is used from the DocShell
1829
SdXImpressDocument::SdXImpressDocument(::sd::DrawDocShell* pShell, bool bClipBoard)
1830
14.5k
:   SfxBaseModel( pShell ),
1831
14.5k
    mpDocShell( pShell ),
1832
14.5k
    mpDoc( pShell ? pShell->GetDoc() : nullptr ),
1833
14.5k
    mbDisposed(false),
1834
14.5k
    mbImpressDoc( pShell && pShell->GetDoc() && pShell->GetDoc()->GetDocumentType() == DocumentType::Impress ),
1835
14.5k
    mbClipBoard( bClipBoard ),
1836
14.5k
    mpPropSet( ImplGetDrawModelPropertySet() ),
1837
14.5k
    mbPaintTextEdit( true )
1838
14.5k
{
1839
14.5k
    if( mpDoc )
1840
14.5k
    {
1841
14.5k
        StartListening( *mpDoc );
1842
14.5k
    }
1843
0
    else
1844
0
    {
1845
0
        OSL_FAIL("DocShell is invalid");
1846
0
    }
1847
14.5k
}
1848
1849
SdXImpressDocument::SdXImpressDocument(SdDrawDocument* pDoc, bool bClipBoard)
1850
0
:   SfxBaseModel( nullptr ),
1851
0
    mpDocShell( nullptr ),
1852
0
    mpDoc( pDoc ),
1853
0
    mbDisposed(false),
1854
0
    mbImpressDoc( pDoc && pDoc->GetDocumentType() == DocumentType::Impress ),
1855
0
    mbClipBoard( bClipBoard ),
1856
0
    mpPropSet( ImplGetDrawModelPropertySet() ),
1857
0
    mbPaintTextEdit( true )
1858
0
{
1859
0
    if( mpDoc )
1860
0
    {
1861
0
        StartListening( *mpDoc );
1862
0
    }
1863
0
    else
1864
0
    {
1865
0
        OSL_FAIL("SdDrawDocument is invalid");
1866
0
    }
1867
0
}
1868
1869
/***********************************************************************
1870
*                                                                      *
1871
***********************************************************************/
1872
SdXImpressDocument::~SdXImpressDocument() noexcept
1873
14.5k
{
1874
14.5k
}
1875
1876
// XInterface
1877
uno::Any SAL_CALL SdXImpressDocument::queryInterface( const uno::Type & rType )
1878
357k
{
1879
357k
    uno::Any aAny;
1880
1881
357k
    if (rType == cppu::UnoType<lang::XServiceInfo>::get())
1882
458
        aAny <<= uno::Reference<lang::XServiceInfo>(this);
1883
356k
    else if (rType == cppu::UnoType<beans::XPropertySet>::get())
1884
13.2k
        aAny <<= uno::Reference<beans::XPropertySet>(this);
1885
343k
    else if (rType == cppu::UnoType<lang::XMultiServiceFactory>::get())
1886
163k
        aAny <<= uno::Reference<lang::XMultiServiceFactory>(this);
1887
179k
    else if (rType == cppu::UnoType<drawing::XDrawPageDuplicator>::get())
1888
0
        aAny <<= uno::Reference<drawing::XDrawPageDuplicator>(this);
1889
179k
    else if (rType == cppu::UnoType<drawing::XLayerSupplier>::get())
1890
121
        aAny <<= uno::Reference<drawing::XLayerSupplier>(this);
1891
179k
    else if (rType == cppu::UnoType<drawing::XMasterPagesSupplier>::get())
1892
2.65k
        aAny <<= uno::Reference<drawing::XMasterPagesSupplier>(this);
1893
176k
    else if (rType == cppu::UnoType<drawing::XDrawPagesSupplier>::get())
1894
5.46k
        aAny <<= uno::Reference<drawing::XDrawPagesSupplier>(this);
1895
171k
    else if (rType == cppu::UnoType<presentation::XHandoutMasterSupplier>::get())
1896
41
        aAny <<= uno::Reference<presentation::XHandoutMasterSupplier>(this);
1897
171k
    else if (rType == cppu::UnoType<document::XLinkTargetSupplier>::get())
1898
0
        aAny <<= uno::Reference<document::XLinkTargetSupplier>(this);
1899
171k
    else if (rType == cppu::UnoType<style::XStyleFamiliesSupplier>::get())
1900
66.0k
        aAny <<= uno::Reference<style::XStyleFamiliesSupplier>(this);
1901
105k
    else if (rType == cppu::UnoType<css::ucb::XAnyCompareFactory>::get())
1902
765
        aAny <<= uno::Reference<css::ucb::XAnyCompareFactory>(this);
1903
104k
    else if (rType == cppu::UnoType<view::XRenderable>::get())
1904
0
        aAny <<= uno::Reference<view::XRenderable>(this);
1905
104k
    else if (mbImpressDoc && rType == cppu::UnoType<presentation::XPresentationSupplier>::get())
1906
781
        aAny <<= uno::Reference< presentation::XPresentationSupplier >(this);
1907
103k
    else if (mbImpressDoc && rType == cppu::UnoType<presentation::XCustomPresentationSupplier>::get())
1908
4
        aAny <<= uno::Reference< presentation::XCustomPresentationSupplier >(this);
1909
103k
    else
1910
103k
        return SfxBaseModel::queryInterface(rType);
1911
1912
253k
    return aAny;
1913
357k
}
1914
1915
void SAL_CALL SdXImpressDocument::acquire() noexcept
1916
829k
{
1917
829k
    SfxBaseModel::acquire();
1918
829k
}
1919
1920
void SAL_CALL SdXImpressDocument::release() noexcept
1921
829k
{
1922
829k
    if (osl_atomic_decrement( &m_refCount ) != 0)
1923
815k
        return;
1924
1925
    // restore reference count:
1926
14.5k
    osl_atomic_increment( &m_refCount );
1927
14.5k
    if(!mbDisposed)
1928
0
    {
1929
0
        try
1930
0
        {
1931
0
            dispose();
1932
0
        }
1933
0
        catch (const uno::RuntimeException&)
1934
0
        {
1935
            // don't break throw ()
1936
0
            TOOLS_WARN_EXCEPTION( "sd", "" );
1937
0
        }
1938
0
    }
1939
14.5k
    SfxBaseModel::release();
1940
14.5k
}
1941
1942
// XUnoTunnel
1943
const css::uno::Sequence< sal_Int8 > & SdXImpressDocument::getUnoTunnelId() noexcept
1944
70.5k
{
1945
70.5k
    static const comphelper::UnoIdInit theSdXImpressDocumentUnoTunnelId;
1946
70.5k
    return theSdXImpressDocumentUnoTunnelId.getSeq();
1947
70.5k
}
1948
1949
sal_Int64 SAL_CALL SdXImpressDocument::getSomething( const css::uno::Sequence< sal_Int8 >& rIdentifier )
1950
35.2k
{
1951
35.2k
    if (comphelper::isUnoTunnelId<SdrModel>(rIdentifier))
1952
0
        return comphelper::getSomething_cast(mpDoc);
1953
1954
35.2k
    if (comphelper::isUnoTunnelId<SfxObjectShell>(rIdentifier))
1955
0
        return comphelper::getSomething_cast(mpDocShell);
1956
1957
35.2k
    return comphelper::getSomethingImpl(rIdentifier, this,
1958
35.2k
                                        comphelper::FallbackToGetSomethingOf<SfxBaseModel>{});
1959
35.2k
}
1960
1961
// XTypeProvider
1962
uno::Sequence< uno::Type > SAL_CALL SdXImpressDocument::getTypes(  )
1963
0
{
1964
0
    ::SolarMutexGuard aGuard;
1965
1966
0
    if( !maTypeSequence.hasElements() )
1967
0
    {
1968
0
        uno::Sequence< uno::Type > aTypes( SfxBaseModel::getTypes() );
1969
0
        aTypes = comphelper::concatSequences(aTypes,
1970
0
            uno::Sequence {
1971
0
                cppu::UnoType<beans::XPropertySet>::get(),
1972
0
                cppu::UnoType<lang::XServiceInfo>::get(),
1973
0
                cppu::UnoType<lang::XMultiServiceFactory>::get(),
1974
0
                cppu::UnoType<drawing::XDrawPageDuplicator>::get(),
1975
0
                cppu::UnoType<drawing::XLayerSupplier>::get(),
1976
0
                cppu::UnoType<drawing::XMasterPagesSupplier>::get(),
1977
0
                cppu::UnoType<drawing::XDrawPagesSupplier>::get(),
1978
0
                cppu::UnoType<document::XLinkTargetSupplier>::get(),
1979
0
                cppu::UnoType<style::XStyleFamiliesSupplier>::get(),
1980
0
                cppu::UnoType<css::ucb::XAnyCompareFactory>::get(),
1981
0
                cppu::UnoType<view::XRenderable>::get() });
1982
0
        if( mbImpressDoc )
1983
0
        {
1984
0
            aTypes = comphelper::concatSequences(aTypes,
1985
0
                uno::Sequence {
1986
0
                    cppu::UnoType<presentation::XPresentationSupplier>::get(),
1987
0
                    cppu::UnoType<presentation::XCustomPresentationSupplier>::get(),
1988
0
                    cppu::UnoType<presentation::XHandoutMasterSupplier>::get() });
1989
0
        }
1990
0
        maTypeSequence = std::move(aTypes);
1991
0
    }
1992
1993
0
    return maTypeSequence;
1994
0
}
1995
1996
uno::Sequence< sal_Int8 > SAL_CALL SdXImpressDocument::getImplementationId(  )
1997
0
{
1998
0
    return css::uno::Sequence<sal_Int8>();
1999
0
}
2000
2001
/***********************************************************************
2002
*                                                                      *
2003
***********************************************************************/
2004
void SdXImpressDocument::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
2005
6.13M
{
2006
6.13M
    if( mpDoc )
2007
6.13M
    {
2008
6.13M
        if (rHint.GetId() == SfxHintId::ThisIsAnSdrHint)
2009
309k
        {
2010
309k
            const SdrHint* pSdrHint = static_cast<const SdrHint*>( &rHint );
2011
309k
            if( hasEventListeners() )
2012
0
            {
2013
0
                document::EventObject aEvent;
2014
0
                if( SvxUnoDrawMSFactory::createEvent( mpDoc, pSdrHint, aEvent ) )
2015
0
                    notifyEvent( aEvent );
2016
0
            }
2017
2018
309k
            if( pSdrHint->GetKind() == SdrHintKind::ModelCleared )
2019
0
            {
2020
0
                if( mpDoc )
2021
0
                    EndListening( *mpDoc );
2022
0
                mpDoc = nullptr;
2023
0
                mpDocShell = nullptr;
2024
0
            }
2025
309k
        }
2026
5.82M
        else
2027
5.82M
        {
2028
            // did our SdDrawDocument just died?
2029
5.82M
            if(rHint.GetId() == SfxHintId::Dying)
2030
0
            {
2031
                // yes, so we ask for a new one
2032
0
                if( mpDocShell )
2033
0
                {
2034
0
                    SdDrawDocument *pNewDoc = mpDocShell->GetDoc();
2035
2036
                    // is there a new one?
2037
0
                    if( pNewDoc != mpDoc )
2038
0
                    {
2039
0
                        mpDoc = pNewDoc;
2040
0
                        if(mpDoc)
2041
0
                            StartListening( *mpDoc );
2042
0
                    }
2043
0
                }
2044
0
            }
2045
5.82M
        }
2046
6.13M
    }
2047
6.13M
    SfxBaseModel::Notify( rBC, rHint );
2048
6.13M
}
2049
2050
void SdXImpressDocument::getCommandValues(::tools::JsonWriter& rJsonWriter, std::string_view rCommand)
2051
0
{
2052
0
    static constexpr OStringLiteral aExtractDocStructure(".uno:ExtractDocumentStructure");
2053
2054
0
    std::map<OUString, OUString> aMap
2055
0
        = SfxLokHelper::parseCommandParameters(OUString::fromUtf8(rCommand));
2056
2057
0
    if (o3tl::starts_with(rCommand, aExtractDocStructure))
2058
0
    {
2059
0
        auto commentsNode = rJsonWriter.startNode("DocStructure");
2060
0
        GetDocStructureSlides(rJsonWriter, this, aMap);
2061
0
    }
2062
0
}
2063
2064
/******************************************************************************
2065
*                                                                             *
2066
******************************************************************************/
2067
SdPage* SdXImpressDocument::InsertSdPage( sal_uInt16 nPage, bool bDuplicate )
2068
2.50k
{
2069
2.50k
    sal_uInt16 nPageCount = mpDoc->GetSdPageCount( PageKind::Standard );
2070
2.50k
    SdrLayerAdmin& rLayerAdmin = mpDoc->GetLayerAdmin();
2071
2.50k
    SdrLayerID aBckgrnd = rLayerAdmin.GetLayerID(sUNO_LayerName_background);
2072
2.50k
    SdrLayerID aBckgrndObj = rLayerAdmin.GetLayerID(sUNO_LayerName_background_objects);
2073
2074
2.50k
    rtl::Reference<SdPage> pStandardPage;
2075
2076
2.50k
    if( 0 == nPageCount )
2077
0
    {
2078
        // this is only used for clipboard where we only have one page
2079
0
        pStandardPage = mpDoc->AllocSdPage(false);
2080
2081
0
        Size aDefSize(21000, 29700);   // A4 portrait orientation
2082
0
        pStandardPage->SetSize( aDefSize );
2083
0
        mpDoc->InsertPage(pStandardPage.get(), 0);
2084
0
    }
2085
2.50k
    else
2086
2.50k
    {
2087
        // here we determine the page after which we should insert
2088
2.50k
        SdPage* pPreviousStandardPage = mpDoc->GetSdPage( std::min( static_cast<sal_uInt16>(nPageCount - 1), nPage ), PageKind::Standard );
2089
2.50k
        SdrLayerIDSet aVisibleLayers = pPreviousStandardPage->TRG_GetMasterPageVisibleLayers();
2090
2.50k
        bool bIsPageBack = aVisibleLayers.IsSet( aBckgrnd );
2091
2.50k
        bool bIsPageObj = aVisibleLayers.IsSet( aBckgrndObj );
2092
2093
        // AutoLayouts must be ready
2094
2.50k
        mpDoc->StopWorkStartupDelay();
2095
2096
        /* First we create a standard page and then a notes page. It is
2097
           guaranteed, that after a standard page the corresponding notes page
2098
           follows. */
2099
2100
2.50k
        sal_uInt16 nStandardPageNum = pPreviousStandardPage->GetPageNum() + 2;
2101
2.50k
        SdPage* pPreviousNotesPage = static_cast<SdPage*>( mpDoc->GetPage( nStandardPageNum - 1 ) );
2102
2.50k
        sal_uInt16 nNotesPageNum = nStandardPageNum + 1;
2103
2104
        /**************************************************************
2105
        * standard page
2106
        **************************************************************/
2107
2.50k
        if( bDuplicate )
2108
0
            pStandardPage = static_cast<SdPage*>( pPreviousStandardPage->CloneSdrPage(*mpDoc).get() );
2109
2.50k
        else
2110
2.50k
            pStandardPage = mpDoc->AllocSdPage(false);
2111
2112
2.50k
        pStandardPage->SetSize( pPreviousStandardPage->GetSize() );
2113
2.50k
        pStandardPage->SetBorder( pPreviousStandardPage->GetLeftBorder(),
2114
2.50k
                                    pPreviousStandardPage->GetUpperBorder(),
2115
2.50k
                                    pPreviousStandardPage->GetRightBorder(),
2116
2.50k
                                    pPreviousStandardPage->GetLowerBorder() );
2117
2.50k
        pStandardPage->SetOrientation( pPreviousStandardPage->GetOrientation() );
2118
2.50k
        pStandardPage->SetName(OUString());
2119
2120
        // insert page after current page
2121
2.50k
        mpDoc->InsertPage(pStandardPage.get(), nStandardPageNum);
2122
2123
2.50k
        if( !bDuplicate )
2124
2.50k
        {
2125
            // use MasterPage of the current page
2126
2.50k
            pStandardPage->TRG_SetMasterPage(pPreviousStandardPage->TRG_GetMasterPage());
2127
2.50k
            pStandardPage->SetLayoutName( pPreviousStandardPage->GetLayoutName() );
2128
2.50k
            pStandardPage->SetAutoLayout(AUTOLAYOUT_NONE, true );
2129
2.50k
        }
2130
2131
2.50k
        aBckgrnd = rLayerAdmin.GetLayerID(sUNO_LayerName_background);
2132
2.50k
        aBckgrndObj = rLayerAdmin.GetLayerID(sUNO_LayerName_background_objects);
2133
2.50k
        aVisibleLayers.Set(aBckgrnd, bIsPageBack);
2134
2.50k
        aVisibleLayers.Set(aBckgrndObj, bIsPageObj);
2135
2.50k
        pStandardPage->TRG_SetMasterPageVisibleLayers(aVisibleLayers);
2136
2137
        /**************************************************************
2138
        * notes page
2139
        **************************************************************/
2140
2.50k
        rtl::Reference<SdPage> pNotesPage;
2141
2142
2.50k
        if( bDuplicate )
2143
0
            pNotesPage = static_cast<SdPage*>( pPreviousNotesPage->CloneSdrPage(*mpDoc).get() );
2144
2.50k
        else
2145
2.50k
            pNotesPage = mpDoc->AllocSdPage(false);
2146
2147
2.50k
        pNotesPage->SetSize( pPreviousNotesPage->GetSize() );
2148
2.50k
        pNotesPage->SetBorder( pPreviousNotesPage->GetLeftBorder(),
2149
2.50k
                                pPreviousNotesPage->GetUpperBorder(),
2150
2.50k
                                pPreviousNotesPage->GetRightBorder(),
2151
2.50k
                                pPreviousNotesPage->GetLowerBorder() );
2152
2.50k
        pNotesPage->SetOrientation( pPreviousNotesPage->GetOrientation() );
2153
2.50k
        pNotesPage->SetName(OUString());
2154
2.50k
        pNotesPage->SetPageKind(PageKind::Notes);
2155
2156
        // insert page after current page
2157
2.50k
        mpDoc->InsertPage(pNotesPage.get(), nNotesPageNum);
2158
2159
2.50k
        if( !bDuplicate )
2160
2.50k
        {
2161
            // use MasterPage of the current page
2162
2.50k
            pNotesPage->TRG_SetMasterPage(pPreviousNotesPage->TRG_GetMasterPage());
2163
2.50k
            pNotesPage->SetLayoutName( pPreviousNotesPage->GetLayoutName() );
2164
2.50k
            pNotesPage->SetAutoLayout(AUTOLAYOUT_NOTES, true );
2165
2.50k
        }
2166
2.50k
    }
2167
2168
2.50k
    SetModified();
2169
2170
2.50k
    return pStandardPage.get();
2171
2.50k
}
2172
2173
void SdXImpressDocument::SetModified() noexcept
2174
1.56M
{
2175
1.56M
    if( mpDoc )
2176
1.56M
        mpDoc->SetChanged();
2177
1.56M
}
2178
2179
// XModel
2180
void SAL_CALL SdXImpressDocument::lockControllers(  )
2181
5.72k
{
2182
5.72k
    ::SolarMutexGuard aGuard;
2183
2184
5.72k
    if( nullptr == mpDoc )
2185
0
        throw lang::DisposedException();
2186
2187
5.72k
    mpDoc->setLock(true);
2188
5.72k
}
2189
2190
void SAL_CALL SdXImpressDocument::unlockControllers(  )
2191
5.72k
{
2192
5.72k
    ::SolarMutexGuard aGuard;
2193
2194
5.72k
    if( nullptr == mpDoc )
2195
0
        throw lang::DisposedException();
2196
2197
5.72k
    if( mpDoc->isLocked() )
2198
5.67k
    {
2199
5.67k
        mpDoc->setLock(false);
2200
5.67k
    }
2201
5.72k
}
2202
2203
sal_Bool SAL_CALL SdXImpressDocument::hasControllersLocked(  )
2204
2.65k
{
2205
2.65k
    ::SolarMutexGuard aGuard;
2206
2207
2.65k
    if( nullptr == mpDoc )
2208
0
        throw lang::DisposedException();
2209
2210
2.65k
    return mpDoc->isLocked();
2211
2.65k
}
2212
2213
uno::Reference < container::XIndexAccess > SAL_CALL SdXImpressDocument::getViewData()
2214
116
{
2215
116
    ::SolarMutexGuard aGuard;
2216
2217
116
    if( nullptr == mpDoc )
2218
0
        throw lang::DisposedException();
2219
2220
116
    uno::Reference < container::XIndexAccess > xRet( SfxBaseModel::getViewData() );
2221
2222
116
    if( !xRet.is() )
2223
116
    {
2224
116
        const std::vector<std::unique_ptr<sd::FrameView>> &rList = mpDoc->GetFrameViewList();
2225
2226
116
        if( !rList.empty() )
2227
0
        {
2228
0
            xRet = new comphelper::IndexedPropertyValuesContainer();
2229
2230
0
            uno::Reference < container::XIndexContainer > xCont( xRet, uno::UNO_QUERY );
2231
0
            DBG_ASSERT( xCont.is(), "SdXImpressDocument::getViewData() failed for OLE object" );
2232
0
            if( xCont.is() )
2233
0
            {
2234
0
                for( sal_uInt32 i = 0, n = rList.size(); i < n; i++ )
2235
0
                {
2236
0
                    ::sd::FrameView* pFrameView = rList[ i ].get();
2237
2238
0
                    uno::Sequence< beans::PropertyValue > aSeq;
2239
0
                    pFrameView->WriteUserDataSequence( aSeq );
2240
0
                    xCont->insertByIndex( i, uno::Any( aSeq ) );
2241
0
                }
2242
0
            }
2243
0
        }
2244
116
    }
2245
2246
116
    return xRet;
2247
116
}
2248
2249
void SAL_CALL SdXImpressDocument::setViewData( const uno::Reference < container::XIndexAccess >& xData )
2250
170
{
2251
170
    ::SolarMutexGuard aGuard;
2252
2253
170
    if( nullptr == mpDoc )
2254
0
        throw lang::DisposedException();
2255
2256
170
    SfxBaseModel::setViewData( xData );
2257
170
    if( !(mpDocShell && (mpDocShell->GetCreateMode() == SfxObjectCreateMode::EMBEDDED) && xData.is()) )
2258
116
        return;
2259
2260
54
    const sal_Int32 nCount = xData->getCount();
2261
2262
54
    std::vector<std::unique_ptr<sd::FrameView>> &rViews = mpDoc->GetFrameViewList();
2263
2264
54
    rViews.clear();
2265
2266
54
    uno::Sequence< beans::PropertyValue > aSeq;
2267
108
    for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
2268
54
    {
2269
54
        if( xData->getByIndex( nIndex ) >>= aSeq )
2270
54
        {
2271
54
            std::unique_ptr<::sd::FrameView> pFrameView(new ::sd::FrameView( mpDoc ));
2272
54
            pFrameView->ReadUserDataSequence( aSeq );
2273
54
            rViews.push_back( std::move(pFrameView) );
2274
54
        }
2275
54
    }
2276
54
}
2277
2278
// XDrawPageDuplicator
2279
uno::Reference< drawing::XDrawPage > SAL_CALL SdXImpressDocument::duplicate( const uno::Reference< drawing::XDrawPage >& xPage )
2280
0
{
2281
0
    ::SolarMutexGuard aGuard;
2282
2283
0
    if( nullptr == mpDoc )
2284
0
        throw lang::DisposedException();
2285
2286
    // get pPage from xPage and determine the Id (nPos ) afterwards
2287
0
    SvxDrawPage* pSvxPage = comphelper::getFromUnoTunnel<SvxDrawPage>( xPage );
2288
0
    if( pSvxPage )
2289
0
    {
2290
0
        SdPage* pPage = static_cast<SdPage*>( pSvxPage->GetSdrPage() );
2291
0
        sal_uInt16 nPos = pPage->GetPageNum();
2292
0
        nPos = ( nPos - 1 ) / 2;
2293
0
        pPage = InsertSdPage( nPos, true );
2294
0
        if( pPage )
2295
0
        {
2296
0
            uno::Reference< drawing::XDrawPage > xDrawPage( pPage->getUnoPage(), uno::UNO_QUERY );
2297
0
            return xDrawPage;
2298
0
        }
2299
0
    }
2300
2301
0
    uno::Reference< drawing::XDrawPage > xDrawPage;
2302
0
    return xDrawPage;
2303
0
}
2304
2305
// XDrawPagesSupplier
2306
uno::Reference< drawing::XDrawPages > SAL_CALL SdXImpressDocument::getDrawPages()
2307
5.46k
{
2308
5.46k
    ::SolarMutexGuard aGuard;
2309
2310
5.46k
    return getSdDrawPages();
2311
5.46k
}
2312
2313
rtl::Reference< SdDrawPagesAccess > SdXImpressDocument::getSdDrawPages()
2314
5.46k
{
2315
5.46k
    if( nullptr == mpDoc )
2316
0
        throw lang::DisposedException();
2317
2318
5.46k
    rtl::Reference< SdDrawPagesAccess > xDrawPages( mxDrawPagesAccess );
2319
2320
5.46k
    if( !xDrawPages.is() )
2321
5.45k
    {
2322
5.45k
        initializeDocument();
2323
5.45k
        xDrawPages = new SdDrawPagesAccess(*this);
2324
5.45k
        mxDrawPagesAccess = xDrawPages.get();
2325
5.45k
    }
2326
2327
5.46k
    return xDrawPages;
2328
5.46k
}
2329
2330
// XMasterPagesSupplier
2331
uno::Reference< drawing::XDrawPages > SAL_CALL SdXImpressDocument::getMasterPages()
2332
2.65k
{
2333
2.65k
    ::SolarMutexGuard aGuard;
2334
2335
2.65k
    if( nullptr == mpDoc )
2336
0
        throw lang::DisposedException();
2337
2338
2.65k
    rtl::Reference< SdMasterPagesAccess > xMasterPages( mxMasterPagesAccess );
2339
2340
2.65k
    if( !xMasterPages.is() )
2341
2.65k
    {
2342
2.65k
        if ( !hasControllersLocked() )
2343
287
            initializeDocument();
2344
2.65k
        xMasterPages = new SdMasterPagesAccess(*this);
2345
2.65k
        mxMasterPagesAccess = xMasterPages.get();
2346
2.65k
    }
2347
2348
2.65k
    return xMasterPages;
2349
2.65k
}
2350
2351
// XLayerManagerSupplier
2352
uno::Reference< container::XNameAccess > SAL_CALL SdXImpressDocument::getLayerManager(  )
2353
121
{
2354
121
    ::SolarMutexGuard aGuard;
2355
2356
121
    if( nullptr == mpDoc )
2357
0
        throw lang::DisposedException();
2358
2359
121
    rtl::Reference< SdLayerManager >  xLayerManager( mxLayerManager );
2360
2361
121
    if( !xLayerManager.is() )
2362
121
    {
2363
121
        xLayerManager = new SdLayerManager(*this);
2364
121
        mxLayerManager = xLayerManager.get();
2365
121
    }
2366
2367
121
    return xLayerManager;
2368
121
}
2369
2370
// XCustomPresentationSupplier
2371
uno::Reference< container::XNameContainer > SAL_CALL SdXImpressDocument::getCustomPresentations()
2372
4
{
2373
4
    ::SolarMutexGuard aGuard;
2374
2375
4
    if( nullptr == mpDoc )
2376
0
        throw lang::DisposedException();
2377
2378
4
    rtl::Reference< SdXCustomPresentationAccess >  xCustomPres( mxCustomPresentationAccess );
2379
2380
4
    if( !xCustomPres.is() )
2381
4
    {
2382
4
        xCustomPres = new SdXCustomPresentationAccess(*this);
2383
4
        mxCustomPresentationAccess = xCustomPres.get();
2384
4
    }
2385
2386
4
    return xCustomPres;
2387
4
}
2388
2389
// XPresentationSupplier
2390
uno::Reference< presentation::XPresentation > SAL_CALL SdXImpressDocument::getPresentation()
2391
781
{
2392
781
    ::SolarMutexGuard aGuard;
2393
2394
781
    if( nullptr == mpDoc )
2395
0
        throw lang::DisposedException();
2396
2397
781
    return mpDoc->getPresentation();
2398
781
}
2399
2400
// XHandoutMasterSupplier
2401
uno::Reference< drawing::XDrawPage > SAL_CALL SdXImpressDocument::getHandoutMasterPage()
2402
41
{
2403
41
    ::SolarMutexGuard aGuard;
2404
2405
41
    if( nullptr == mpDoc )
2406
0
        throw lang::DisposedException();
2407
2408
41
    uno::Reference< drawing::XDrawPage > xPage;
2409
2410
41
    initializeDocument();
2411
41
    SdPage* pPage = mpDoc->GetMasterSdPage(0, PageKind::Handout);
2412
41
    if (pPage)
2413
41
        xPage.set(pPage->getUnoPage(), uno::UNO_QUERY);
2414
41
    return xPage;
2415
41
}
2416
2417
// XMultiServiceFactory ( SvxFmMSFactory )
2418
2419
css::uno::Reference<css::uno::XInterface> SdXImpressDocument::create(
2420
    OUString const & aServiceSpecifier, OUString const & referer)
2421
73.5k
{
2422
73.5k
    ::SolarMutexGuard aGuard;
2423
2424
73.5k
    if( nullptr == mpDoc )
2425
0
        throw lang::DisposedException();
2426
2427
73.5k
    if( aServiceSpecifier == "com.sun.star.drawing.DashTable" )
2428
79
    {
2429
79
        if( !mxDashTable.is() )
2430
79
            mxDashTable = SvxUnoDashTable_createInstance( mpDoc );
2431
2432
79
        return mxDashTable;
2433
79
    }
2434
73.5k
    if( aServiceSpecifier == "com.sun.star.drawing.GradientTable" )
2435
112
    {
2436
112
        if( !mxGradientTable.is() )
2437
112
            mxGradientTable = SvxUnoGradientTable_createInstance( mpDoc );
2438
2439
112
        return mxGradientTable;
2440
112
    }
2441
73.3k
    if( aServiceSpecifier == "com.sun.star.drawing.HatchTable" )
2442
79
    {
2443
79
        if( !mxHatchTable.is() )
2444
79
            mxHatchTable = SvxUnoHatchTable_createInstance( mpDoc );
2445
2446
79
        return mxHatchTable;
2447
79
    }
2448
73.3k
    if( aServiceSpecifier == "com.sun.star.drawing.BitmapTable" )
2449
93
    {
2450
93
        if( !mxBitmapTable.is() )
2451
93
            mxBitmapTable = SvxUnoBitmapTable_createInstance( mpDoc );
2452
2453
93
        return mxBitmapTable;
2454
93
    }
2455
73.2k
    if( aServiceSpecifier == "com.sun.star.drawing.TransparencyGradientTable" )
2456
86
    {
2457
86
        if( !mxTransGradientTable.is() )
2458
86
            mxTransGradientTable = SvxUnoTransGradientTable_createInstance( mpDoc );
2459
2460
86
        return mxTransGradientTable;
2461
86
    }
2462
73.1k
    if( aServiceSpecifier == "com.sun.star.drawing.MarkerTable" )
2463
199
    {
2464
199
        if( !mxMarkerTable.is() )
2465
199
            mxMarkerTable = SvxUnoMarkerTable_createInstance( mpDoc );
2466
2467
199
        return mxMarkerTable;
2468
199
    }
2469
72.9k
    if( aServiceSpecifier == "com.sun.star.text.NumberingRules" )
2470
189
    {
2471
189
        return uno::Reference< uno::XInterface >( SvxCreateNumRule( mpDoc ), uno::UNO_QUERY );
2472
189
    }
2473
72.7k
    if( aServiceSpecifier == "com.sun.star.drawing.Background" )
2474
67
    {
2475
67
        return uno::Reference<uno::XInterface>(cppu::getXWeak(new SdUnoPageBackground(mpDoc)));
2476
67
    }
2477
2478
72.6k
    if( aServiceSpecifier == "com.sun.star.drawing.Defaults" )
2479
124
    {
2480
124
        if( !mxDrawingPool.is() )
2481
124
            mxDrawingPool = SdUnoCreatePool( mpDoc );
2482
2483
124
        return mxDrawingPool;
2484
2485
124
    }
2486
2487
72.5k
    if ( aServiceSpecifier == sUNO_Service_ImageMapRectangleObject )
2488
0
    {
2489
0
        return SvUnoImageMapRectangleObject_createInstance( ImplGetSupportedMacroItems() );
2490
0
    }
2491
2492
72.5k
    if ( aServiceSpecifier == sUNO_Service_ImageMapCircleObject )
2493
0
    {
2494
0
        return SvUnoImageMapCircleObject_createInstance( ImplGetSupportedMacroItems() );
2495
0
    }
2496
2497
72.5k
    if ( aServiceSpecifier == sUNO_Service_ImageMapPolygonObject )
2498
0
    {
2499
0
        return SvUnoImageMapPolygonObject_createInstance( ImplGetSupportedMacroItems() );
2500
0
    }
2501
2502
72.5k
    if( aServiceSpecifier == "com.sun.star.document.Settings" ||
2503
72.2k
        ( !mbImpressDoc && ( aServiceSpecifier == "com.sun.star.drawing.DocumentSettings" ) ) ||
2504
72.2k
        (  mbImpressDoc && ( aServiceSpecifier == "com.sun.star.presentation.DocumentSettings" ) ) )
2505
336
    {
2506
336
        return sd::DocumentSettings_createInstance( this );
2507
336
    }
2508
2509
72.2k
    if( aServiceSpecifier == "com.sun.star.text.TextField.DateTime" ||
2510
72.0k
        aServiceSpecifier == "com.sun.star.text.textfield.DateTime" )
2511
149
    {
2512
149
        return cppu::getXWeak(new SvxUnoTextField(text::textfield::Type::DATE));
2513
149
    }
2514
2515
72.0k
    if( aServiceSpecifier == "com.sun.star.presentation.TextField.Header" ||
2516
72.0k
        aServiceSpecifier == "com.sun.star.presentation.textfield.Header" )
2517
58
    {
2518
58
        return cppu::getXWeak(new SvxUnoTextField(text::textfield::Type::PRESENTATION_HEADER));
2519
58
    }
2520
2521
72.0k
    if( aServiceSpecifier == "com.sun.star.presentation.TextField.Footer" ||
2522
67.5k
        aServiceSpecifier == "com.sun.star.presentation.textfield.Footer" )
2523
4.41k
    {
2524
4.41k
        return cppu::getXWeak(new SvxUnoTextField(text::textfield::Type::PRESENTATION_FOOTER));
2525
4.41k
    }
2526
2527
67.5k
    if( aServiceSpecifier == "com.sun.star.presentation.TextField.DateTime" ||
2528
63.1k
        aServiceSpecifier == "com.sun.star.presentation.textfield.DateTime" )
2529
4.41k
    {
2530
4.41k
        return cppu::getXWeak(new SvxUnoTextField(text::textfield::Type::PRESENTATION_DATE_TIME));
2531
4.41k
    }
2532
2533
63.1k
    if( aServiceSpecifier == "com.sun.star.text.TextField.PageName" ||
2534
63.1k
        aServiceSpecifier == "com.sun.star.text.textfield.PageName" )
2535
0
    {
2536
0
        return cppu::getXWeak(new SvxUnoTextField(text::textfield::Type::PAGE_NAME));
2537
0
    }
2538
2539
63.1k
    if (aServiceSpecifier == "com.sun.star.text.TextField.DocInfo.Custom" ||
2540
63.1k
        aServiceSpecifier == "com.sun.star.text.textfield.DocInfo.Custom")
2541
0
    {
2542
0
        return cppu::getXWeak(new SvxUnoTextField(text::textfield::Type::DOCINFO_CUSTOM));
2543
0
    }
2544
2545
63.1k
    if( aServiceSpecifier == "com.sun.star.xml.NamespaceMap" )
2546
116
    {
2547
116
        static const sal_uInt16 aWhichIds[] = { SDRATTR_XMLATTRIBUTES, EE_CHAR_XMLATTRIBS, EE_PARA_XMLATTRIBS, 0 };
2548
2549
116
        return svx::NamespaceMap_createInstance( aWhichIds, &mpDoc->GetItemPool() );
2550
116
    }
2551
2552
    // Support creation of GraphicStorageHandler and EmbeddedObjectResolver
2553
63.0k
    if (aServiceSpecifier == "com.sun.star.document.ExportGraphicStorageHandler")
2554
0
    {
2555
0
        return cppu::getXWeak(new SvXMLGraphicHelper(SvXMLGraphicHelperMode::Write));
2556
0
    }
2557
2558
63.0k
    if (aServiceSpecifier == "com.sun.star.document.ImportGraphicStorageHandler")
2559
0
    {
2560
0
        return cppu::getXWeak(new SvXMLGraphicHelper(SvXMLGraphicHelperMode::Read));
2561
0
    }
2562
2563
63.0k
    if( aServiceSpecifier == "com.sun.star.document.ExportEmbeddedObjectResolver" )
2564
116
    {
2565
116
        comphelper::IEmbeddedHelper* pPersist = mpDoc->GetPersist();
2566
116
        if( nullptr == pPersist )
2567
0
            throw lang::DisposedException();
2568
2569
116
        return cppu::getXWeak(new SvXMLEmbeddedObjectHelper( *pPersist, SvXMLEmbeddedObjectHelperMode::Write ));
2570
116
    }
2571
2572
62.9k
    if( aServiceSpecifier == "com.sun.star.document.ImportEmbeddedObjectResolver" )
2573
171
    {
2574
171
        comphelper::IEmbeddedHelper* pPersist = mpDoc->GetPersist();
2575
171
        if( nullptr == pPersist )
2576
0
            throw lang::DisposedException();
2577
2578
171
        return cppu::getXWeak(new SvXMLEmbeddedObjectHelper( *pPersist, SvXMLEmbeddedObjectHelperMode::Read ));
2579
171
    }
2580
2581
62.7k
    uno::Reference< uno::XInterface > xRet;
2582
2583
62.7k
    if (std::u16string_view aType; aServiceSpecifier.startsWith("com.sun.star.presentation.", &aType))
2584
39.7k
    {
2585
39.7k
        SdrObjKind nType;
2586
        // create a shape wrapper
2587
39.7k
        if( o3tl::starts_with(aType, u"TitleTextShape" ) )
2588
8.94k
        {
2589
8.94k
            nType = SdrObjKind::Text;
2590
8.94k
        }
2591
30.8k
        else if( o3tl::starts_with(aType, u"OutlinerShape" ) )
2592
15.2k
        {
2593
15.2k
            nType = SdrObjKind::Text;
2594
15.2k
        }
2595
15.6k
        else if( o3tl::starts_with(aType, u"SubtitleShape" ) )
2596
1.43k
        {
2597
1.43k
            nType = SdrObjKind::Text;
2598
1.43k
        }
2599
14.1k
        else if( o3tl::starts_with(aType, u"GraphicObjectShape" ) )
2600
371
        {
2601
371
            nType = SdrObjKind::Graphic;
2602
371
        }
2603
13.8k
        else if( o3tl::starts_with(aType, u"PageShape" ) )
2604
70
        {
2605
70
            nType = SdrObjKind::Page;
2606
70
        }
2607
13.7k
        else if( o3tl::starts_with(aType, u"OLE2Shape" ) )
2608
0
        {
2609
0
            nType = SdrObjKind::OLE2;
2610
0
        }
2611
13.7k
        else if( o3tl::starts_with(aType, u"ChartShape" ) )
2612
0
        {
2613
0
            nType = SdrObjKind::OLE2;
2614
0
        }
2615
13.7k
        else if( o3tl::starts_with(aType, u"CalcShape" ) )
2616
0
        {
2617
0
            nType = SdrObjKind::OLE2;
2618
0
        }
2619
13.7k
        else if( o3tl::starts_with(aType, u"TableShape" ) )
2620
0
        {
2621
0
            nType = SdrObjKind::Table;
2622
0
        }
2623
13.7k
        else if( o3tl::starts_with(aType, u"OrgChartShape" ) )
2624
0
        {
2625
0
            nType = SdrObjKind::OLE2;
2626
0
        }
2627
13.7k
        else if( o3tl::starts_with(aType, u"NotesShape" ) )
2628
138
        {
2629
138
            nType = SdrObjKind::Text;
2630
138
        }
2631
13.5k
        else if( o3tl::starts_with(aType, u"HandoutShape" ) )
2632
245
        {
2633
245
            nType = SdrObjKind::Page;
2634
245
        }
2635
13.3k
        else if( o3tl::starts_with(aType, u"FooterShape" ) )
2636
4.42k
        {
2637
4.42k
            nType = SdrObjKind::Text;
2638
4.42k
        }
2639
8.92k
        else if( o3tl::starts_with(aType, u"HeaderShape" ) )
2640
49
        {
2641
49
            nType = SdrObjKind::Text;
2642
49
        }
2643
8.87k
        else if( o3tl::starts_with(aType, u"SlideNumberShape" ) )
2644
4.44k
        {
2645
4.44k
            nType = SdrObjKind::Text;
2646
4.44k
        }
2647
4.42k
        else if( o3tl::starts_with(aType, u"DateTimeShape" ) )
2648
4.42k
        {
2649
4.42k
            nType = SdrObjKind::Text;
2650
4.42k
        }
2651
0
        else if( o3tl::starts_with(aType, u"MediaShape" ) )
2652
0
        {
2653
0
            nType = SdrObjKind::Media;
2654
0
        }
2655
0
        else
2656
0
        {
2657
0
            throw lang::ServiceNotRegisteredException();
2658
0
        }
2659
2660
        // create the API wrapper
2661
39.7k
        rtl::Reference<SvxShape> pShape = CreateSvxShapeByTypeAndInventor(nType, SdrInventor::Default, referer);
2662
2663
        // set shape type
2664
39.7k
        if( pShape && !mbClipBoard )
2665
39.7k
            pShape->SetShapeType(aServiceSpecifier);
2666
2667
39.7k
        xRet = cppu::getXWeak(pShape.get());
2668
39.7k
    }
2669
23.0k
    else if ( aServiceSpecifier == "com.sun.star.drawing.TableShape" )
2670
114
    {
2671
114
        rtl::Reference<SvxShape> pShape = CreateSvxShapeByTypeAndInventor( SdrObjKind::Table, SdrInventor::Default, referer );
2672
114
        if( pShape && !mbClipBoard )
2673
114
            pShape->SetShapeType(aServiceSpecifier);
2674
2675
114
        xRet = cppu::getXWeak(pShape.get());
2676
114
    }
2677
22.8k
    else
2678
22.8k
    {
2679
22.8k
        xRet = SvxFmMSFactory::createInstance( aServiceSpecifier );
2680
22.8k
    }
2681
2682
62.7k
    uno::Reference< drawing::XShape > xShape( xRet, uno::UNO_QUERY );
2683
62.7k
    SvxShape* pShape = xShape.is() ? comphelper::getFromUnoTunnel<SvxShape>(xShape) : nullptr;
2684
62.7k
    if (pShape)
2685
55.8k
    {
2686
55.8k
        xRet.clear();
2687
55.8k
        new SdXShape( pShape, this );
2688
55.8k
        xRet = xShape;
2689
55.8k
        xShape.clear();
2690
55.8k
    }
2691
2692
62.7k
    return xRet;
2693
62.7k
}
2694
2695
uno::Reference< uno::XInterface > SAL_CALL SdXImpressDocument::createInstance( const OUString& aServiceSpecifier )
2696
73.5k
{
2697
73.5k
    return create(aServiceSpecifier, u""_ustr);
2698
73.5k
}
2699
2700
css::uno::Reference<css::uno::XInterface>
2701
SdXImpressDocument::createInstanceWithArguments(
2702
    OUString const & ServiceSpecifier,
2703
    css::uno::Sequence<css::uno::Any> const & Arguments)
2704
2
{
2705
2
    OUString arg;
2706
2
    if ((ServiceSpecifier == "com.sun.star.drawing.GraphicObjectShape"
2707
2
         || ServiceSpecifier == "com.sun.star.drawing.AppletShape"
2708
2
         || ServiceSpecifier == "com.sun.star.drawing.FrameShape"
2709
2
         || ServiceSpecifier == "com.sun.star.drawing.OLE2Shape"
2710
0
         || ServiceSpecifier == "com.sun.star.drawing.MediaShape"
2711
0
         || ServiceSpecifier == "com.sun.star.drawing.PluginShape"
2712
0
         || ServiceSpecifier == "com.sun.star.presentation.MediaShape")
2713
2
        && Arguments.getLength() == 1 && (Arguments[0] >>= arg))
2714
2
    {
2715
2
        return create(ServiceSpecifier, arg);
2716
2
    }
2717
0
    return SvxFmMSFactory::createInstanceWithArguments(
2718
0
        ServiceSpecifier, Arguments);
2719
2
}
2720
2721
uno::Sequence< OUString > SAL_CALL SdXImpressDocument::getAvailableServiceNames()
2722
338
{
2723
338
    ::SolarMutexGuard aGuard;
2724
2725
338
    if( nullptr == mpDoc )
2726
0
        throw lang::DisposedException();
2727
2728
338
    const uno::Sequence< OUString > aSNS_ORG( SvxFmMSFactory::getAvailableServiceNames() );
2729
2730
338
    uno::Sequence< OUString > aSNS_Common{ u"com.sun.star.drawing.DashTable"_ustr,
2731
338
                                           u"com.sun.star.drawing.GradientTable"_ustr,
2732
338
                                           u"com.sun.star.drawing.HatchTable"_ustr,
2733
338
                                           u"com.sun.star.drawing.BitmapTable"_ustr,
2734
338
                                           u"com.sun.star.drawing.TransparencyGradientTable"_ustr,
2735
338
                                           u"com.sun.star.drawing.MarkerTable"_ustr,
2736
338
                                           u"com.sun.star.text.NumberingRules"_ustr,
2737
338
                                           u"com.sun.star.drawing.Background"_ustr,
2738
338
                                           u"com.sun.star.document.Settings"_ustr,
2739
338
                                           sUNO_Service_ImageMapRectangleObject,
2740
338
                                           sUNO_Service_ImageMapCircleObject,
2741
338
                                           sUNO_Service_ImageMapPolygonObject,
2742
338
                                           u"com.sun.star.xml.NamespaceMap"_ustr,
2743
2744
                                           // Support creation of GraphicStorageHandler and EmbeddedObjectResolver
2745
338
                                           u"com.sun.star.document.ExportGraphicStorageHandler"_ustr,
2746
338
                                           u"com.sun.star.document.ImportGraphicStorageHandler"_ustr,
2747
338
                                           u"com.sun.star.document.ExportEmbeddedObjectResolver"_ustr,
2748
338
                                           u"com.sun.star.document.ImportEmbeddedObjectResolver"_ustr,
2749
338
                                           u"com.sun.star.drawing.TableShape"_ustr };
2750
2751
338
    uno::Sequence< OUString > aSNS_Specific;
2752
2753
338
    if(mbImpressDoc)
2754
222
        aSNS_Specific = { u"com.sun.star.presentation.TitleTextShape"_ustr,
2755
222
                          u"com.sun.star.presentation.OutlinerShape"_ustr,
2756
222
                          u"com.sun.star.presentation.SubtitleShape"_ustr,
2757
222
                          u"com.sun.star.presentation.GraphicObjectShape"_ustr,
2758
222
                          u"com.sun.star.presentation.ChartShape"_ustr,
2759
222
                          u"com.sun.star.presentation.PageShape"_ustr,
2760
222
                          u"com.sun.star.presentation.OLE2Shape"_ustr,
2761
222
                          u"com.sun.star.presentation.TableShape"_ustr,
2762
222
                          u"com.sun.star.presentation.OrgChartShape"_ustr,
2763
222
                          u"com.sun.star.presentation.NotesShape"_ustr,
2764
222
                          u"com.sun.star.presentation.HandoutShape"_ustr,
2765
222
                          u"com.sun.star.presentation.DocumentSettings"_ustr,
2766
222
                          u"com.sun.star.presentation.FooterShape"_ustr,
2767
222
                          u"com.sun.star.presentation.HeaderShape"_ustr,
2768
222
                          u"com.sun.star.presentation.SlideNumberShape"_ustr,
2769
222
                          u"com.sun.star.presentation.DateTimeShape"_ustr,
2770
222
                          u"com.sun.star.presentation.CalcShape"_ustr,
2771
222
                          u"com.sun.star.presentation.MediaShape"_ustr };
2772
116
    else
2773
116
        aSNS_Specific = { u"com.sun.star.drawing.DocumentSettings"_ustr };
2774
2775
338
    return comphelper::concatSequences( aSNS_ORG, aSNS_Common, aSNS_Specific );
2776
338
}
2777
2778
// lang::XServiceInfo
2779
OUString SAL_CALL SdXImpressDocument::getImplementationName()
2780
0
{
2781
0
    return u"SdXImpressDocument"_ustr;
2782
    /* // Matching the .component information:
2783
       return mbImpressDoc
2784
           ? OUString("com.sun.star.comp.Draw.PresentationDocument")
2785
           : OUString("com.sun.star.comp.Draw.DrawingDocument");
2786
    */
2787
0
}
2788
2789
sal_Bool SAL_CALL SdXImpressDocument::supportsService( const OUString& ServiceName )
2790
342
{
2791
342
    return cppu::supportsService(this, ServiceName);
2792
342
}
2793
2794
uno::Sequence< OUString > SAL_CALL SdXImpressDocument::getSupportedServiceNames()
2795
458
{
2796
458
    ::SolarMutexGuard aGuard;
2797
2798
458
    return { u"com.sun.star.document.OfficeDocument"_ustr,
2799
458
             u"com.sun.star.drawing.GenericDrawingDocument"_ustr,
2800
458
             u"com.sun.star.drawing.DrawingDocumentFactory"_ustr,
2801
458
             mbImpressDoc?u"com.sun.star.presentation.PresentationDocument"_ustr:u"com.sun.star.drawing.DrawingDocument"_ustr };
2802
458
}
2803
2804
// XPropertySet
2805
uno::Reference< beans::XPropertySetInfo > SAL_CALL SdXImpressDocument::getPropertySetInfo(  )
2806
12.5k
{
2807
12.5k
    ::SolarMutexGuard aGuard;
2808
12.5k
    return mpPropSet->getPropertySetInfo();
2809
12.5k
}
2810
2811
void SAL_CALL SdXImpressDocument::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue )
2812
12.6k
{
2813
12.6k
    ::SolarMutexGuard aGuard;
2814
2815
12.6k
    if( nullptr == mpDoc )
2816
0
        throw lang::DisposedException();
2817
2818
12.6k
    const SfxItemPropertyMapEntry* pEntry = mpPropSet->getPropertyMapEntry(aPropertyName);
2819
2820
12.6k
    switch( pEntry ? pEntry->nWID : -1 )
2821
12.6k
    {
2822
0
        case WID_MODEL_LANGUAGE:
2823
0
        {
2824
0
            lang::Locale aLocale;
2825
0
            if(!(aValue >>= aLocale))
2826
0
                throw lang::IllegalArgumentException();
2827
2828
0
            mpDoc->SetLanguage( LanguageTag::convertToLanguageType(aLocale), EE_CHAR_LANGUAGE );
2829
0
            break;
2830
0
        }
2831
0
        case WID_MODEL_TABSTOP:
2832
0
        {
2833
0
            sal_Int32 nValue = 0;
2834
0
            if(!(aValue >>= nValue) || nValue < 0 )
2835
0
                throw lang::IllegalArgumentException();
2836
2837
0
            mpDoc->SetDefaultTabulator(static_cast<sal_uInt16>(nValue));
2838
0
            break;
2839
0
        }
2840
56
        case WID_MODEL_VISAREA:
2841
56
            {
2842
56
                SfxObjectShell* pEmbeddedObj = mpDoc->GetDocSh();
2843
56
                if( !pEmbeddedObj )
2844
0
                    break;
2845
2846
56
                awt::Rectangle aVisArea;
2847
56
                if( !(aValue >>= aVisArea) || (aVisArea.Width < 0) || (aVisArea.Height < 0) )
2848
1
                    throw lang::IllegalArgumentException();
2849
2850
55
                sal_Int32 nRight, nTop;
2851
55
                if (o3tl::checked_add(aVisArea.X, aVisArea.Width, nRight) || o3tl::checked_add(aVisArea.Y, aVisArea.Height, nTop))
2852
0
                    throw lang::IllegalArgumentException();
2853
2854
55
                pEmbeddedObj->SetVisArea(::tools::Rectangle(aVisArea.X, aVisArea.Y, nRight, nTop));
2855
55
            }
2856
0
            break;
2857
0
        case WID_MODEL_CONTFOCUS:
2858
0
            {
2859
0
                bool bFocus = false;
2860
0
                if( !(aValue >>= bFocus ) )
2861
0
                    throw lang::IllegalArgumentException();
2862
0
                mpDoc->SetAutoControlFocus( bFocus );
2863
0
            }
2864
0
            break;
2865
0
        case WID_MODEL_DSGNMODE:
2866
0
            {
2867
0
                bool bMode = false;
2868
0
                if( !(aValue >>= bMode ) )
2869
0
                    throw lang::IllegalArgumentException();
2870
0
                mpDoc->SetOpenInDesignMode( bMode );
2871
0
            }
2872
0
            break;
2873
0
        case WID_MODEL_BUILDID:
2874
0
            aValue >>= maBuildId;
2875
0
            return;
2876
0
        case WID_MODEL_MAPUNIT:
2877
0
        case WID_MODEL_BASICLIBS:
2878
0
        case WID_MODEL_RUNTIMEUID: // is read-only
2879
0
        case WID_MODEL_DIALOGLIBS:
2880
0
        case WID_MODEL_FONTS:
2881
0
            throw beans::PropertyVetoException();
2882
12.5k
        case WID_MODEL_INTEROPGRABBAG:
2883
12.5k
            setGrabBagItem(aValue);
2884
12.5k
            break;
2885
0
        case WID_MODEL_SLIDESECTIONS:
2886
0
        {
2887
0
            uno::Sequence<beans::PropertyValue> aSections;
2888
0
            if (aValue >>= aSections)
2889
0
                mpDoc->GetSectionManager().SetSectionsFromPropertyValues(aSections);
2890
0
            break;
2891
0
        }
2892
0
        case WID_MODEL_THEME:
2893
0
            getSdrModelFromUnoModel().setTheme(model::Theme::FromAny(aValue));
2894
0
            break;
2895
0
        default:
2896
0
            throw beans::UnknownPropertyException( aPropertyName, static_cast<cppu::OWeakObject*>(this));
2897
12.6k
    }
2898
2899
12.6k
    SetModified();
2900
12.6k
}
2901
2902
uno::Any SAL_CALL SdXImpressDocument::getPropertyValue( const OUString& PropertyName )
2903
13.2k
{
2904
13.2k
    ::SolarMutexGuard aGuard;
2905
2906
13.2k
    uno::Any aAny;
2907
13.2k
    if( nullptr == mpDoc )
2908
0
        throw lang::DisposedException();
2909
2910
13.2k
    const SfxItemPropertyMapEntry* pEntry = mpPropSet->getPropertyMapEntry(PropertyName);
2911
2912
13.2k
    switch( pEntry ? pEntry->nWID : -1 )
2913
13.2k
    {
2914
0
        case WID_MODEL_LANGUAGE:
2915
0
        {
2916
0
            LanguageType eLang = mpDoc->GetLanguage( EE_CHAR_LANGUAGE );
2917
0
            aAny <<= LanguageTag::convertToLocale( eLang);
2918
0
            break;
2919
0
        }
2920
0
        case WID_MODEL_TABSTOP:
2921
0
            aAny <<= static_cast<sal_Int32>(mpDoc->GetDefaultTabulator());
2922
0
            break;
2923
116
        case WID_MODEL_VISAREA:
2924
116
            {
2925
116
                SfxObjectShell* pEmbeddedObj = mpDoc->GetDocSh();
2926
116
                if( !pEmbeddedObj )
2927
0
                    break;
2928
2929
116
                const ::tools::Rectangle& aRect = pEmbeddedObj->GetVisArea();
2930
116
                awt::Rectangle aVisArea( aRect.Left(), aRect.Top(), aRect.getOpenWidth(), aRect.getOpenHeight() );
2931
116
                aAny <<= aVisArea;
2932
116
            }
2933
0
            break;
2934
0
        case WID_MODEL_MAPUNIT:
2935
0
            {
2936
0
                SfxObjectShell* pEmbeddedObj = mpDoc->GetDocSh();
2937
0
                if( !pEmbeddedObj )
2938
0
                    break;
2939
2940
0
                sal_Int16 nMeasureUnit = 0;
2941
0
                SvxMapUnitToMeasureUnit( pEmbeddedObj->GetMapUnit(), nMeasureUnit );
2942
0
                aAny <<= nMeasureUnit;
2943
0
        }
2944
0
        break;
2945
0
        case WID_MODEL_FORBCHARS:
2946
0
        {
2947
0
            aAny <<= getForbiddenCharsTable();
2948
0
        }
2949
0
        break;
2950
0
        case WID_MODEL_CONTFOCUS:
2951
0
            aAny <<= mpDoc->GetAutoControlFocus();
2952
0
            break;
2953
0
        case WID_MODEL_DSGNMODE:
2954
0
            aAny <<= mpDoc->GetOpenInDesignMode();
2955
0
            break;
2956
246
        case WID_MODEL_BASICLIBS:
2957
246
            aAny <<= mpDocShell->GetBasicContainer();
2958
246
            break;
2959
0
        case WID_MODEL_DIALOGLIBS:
2960
0
            aAny <<= mpDocShell->GetDialogContainer();
2961
0
            break;
2962
0
        case WID_MODEL_RUNTIMEUID:
2963
0
            aAny <<= getRuntimeUID();
2964
0
            break;
2965
0
        case WID_MODEL_BUILDID:
2966
0
            return uno::Any( maBuildId );
2967
0
        case WID_MODEL_HASVALIDSIGNATURES:
2968
0
            aAny <<= hasValidSignatures();
2969
0
            break;
2970
0
        case WID_MODEL_ALLOWLINKUPDATE:
2971
0
        {
2972
0
            comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = mpDocShell->getEmbeddedObjectContainer();
2973
0
            aAny <<= rEmbeddedObjectContainer.getUserAllowsLinkUpdate();
2974
0
            break;
2975
0
        }
2976
242
        case WID_MODEL_FONTS:
2977
242
            {
2978
242
                uno::Sequence<uno::Any> aSeq;
2979
242
                int nSeqIndex = 0;
2980
2981
242
                sal_uInt16 const aWhichIds[] { EE_CHAR_FONTINFO, EE_CHAR_FONTINFO_CJK,
2982
242
                                               EE_CHAR_FONTINFO_CTL };
2983
2984
242
                const SfxItemPool& rPool = mpDoc->GetPool();
2985
2986
242
                for(sal_uInt16 nWhichId : aWhichIds)
2987
726
                {
2988
726
                    ItemSurrogates aSurrogates = rPool.GetItemSurrogates(nWhichId);
2989
726
                    const sal_uInt32 nItems(aSurrogates.size());
2990
2991
726
                    aSeq.realloc( aSeq.getLength() + nItems*5 + 5 );
2992
726
                    auto pSeq = aSeq.getArray();
2993
2994
726
                    for (const SfxPoolItem* pItem : aSurrogates)
2995
1.48k
                    {
2996
1.48k
                        const SvxFontItem *pFont = static_cast<const SvxFontItem *>(pItem);
2997
2998
1.48k
                        pSeq[nSeqIndex++] <<= pFont->GetFamilyName();
2999
1.48k
                        pSeq[nSeqIndex++] <<= pFont->GetStyleName();
3000
1.48k
                        pSeq[nSeqIndex++] <<= sal_Int16(pFont->GetFamily());
3001
1.48k
                        pSeq[nSeqIndex++] <<= sal_Int16(pFont->GetPitch());
3002
1.48k
                        pSeq[nSeqIndex++] <<= sal_Int16(pFont->GetCharSet());
3003
1.48k
                    }
3004
3005
726
                    const SvxFontItem& rFont = static_cast<const SvxFontItem&>(rPool.GetUserOrPoolDefaultItem( nWhichId ));
3006
3007
726
                    pSeq[nSeqIndex++] <<= rFont.GetFamilyName();
3008
726
                    pSeq[nSeqIndex++] <<= rFont.GetStyleName();
3009
726
                    pSeq[nSeqIndex++] <<= sal_Int16(rFont.GetFamily());
3010
726
                    pSeq[nSeqIndex++] <<= sal_Int16(rFont.GetPitch());
3011
726
                    pSeq[nSeqIndex++] <<= sal_Int16(rFont.GetCharSet());
3012
3013
726
                }
3014
3015
242
                aAny <<= aSeq;
3016
242
                break;
3017
0
            }
3018
12.5k
        case WID_MODEL_INTEROPGRABBAG:
3019
12.5k
            getGrabBagItem(aAny);
3020
12.5k
            break;
3021
0
        case WID_MODEL_SLIDESECTIONS:
3022
0
            aAny <<= mpDoc->GetSectionManager().GetSectionsAsPropertyValues();
3023
0
            break;
3024
0
        case WID_MODEL_THEME:
3025
0
            if (auto const& pTheme = getSdrModelFromUnoModel().getTheme())
3026
0
                pTheme->ToAny(aAny);
3027
0
            break;
3028
79
        default:
3029
79
            throw beans::UnknownPropertyException( PropertyName, static_cast<cppu::OWeakObject*>(this));
3030
13.2k
    }
3031
3032
13.1k
    return aAny;
3033
13.2k
}
3034
3035
0
void SAL_CALL SdXImpressDocument::addPropertyChangeListener( const OUString& , const uno::Reference< beans::XPropertyChangeListener >&  ) {}
3036
0
void SAL_CALL SdXImpressDocument::removePropertyChangeListener( const OUString& , const uno::Reference< beans::XPropertyChangeListener >&  ) {}
3037
0
void SAL_CALL SdXImpressDocument::addVetoableChangeListener( const OUString& , const uno::Reference< beans::XVetoableChangeListener >&  ) {}
3038
0
void SAL_CALL SdXImpressDocument::removeVetoableChangeListener( const OUString& , const uno::Reference< beans::XVetoableChangeListener >&  ) {}
3039
3040
// XLinkTargetSupplier
3041
uno::Reference< container::XNameAccess > SAL_CALL SdXImpressDocument::getLinks()
3042
0
{
3043
0
    ::SolarMutexGuard aGuard;
3044
3045
0
    if( nullptr == mpDoc )
3046
0
        throw lang::DisposedException();
3047
3048
0
    rtl::Reference< SdDocLinkTargets > xLinks( mxLinks );
3049
0
    if( !xLinks.is() )
3050
0
    {
3051
0
        xLinks = new SdDocLinkTargets( *this );
3052
0
        mxLinks = xLinks.get();
3053
0
    }
3054
0
    return xLinks;
3055
0
}
3056
3057
// XStyleFamiliesSupplier
3058
uno::Reference< container::XNameAccess > SAL_CALL SdXImpressDocument::getStyleFamilies(  )
3059
71.5k
{
3060
71.5k
    ::SolarMutexGuard aGuard;
3061
3062
71.5k
    if( nullptr == mpDoc )
3063
0
        throw lang::DisposedException();
3064
3065
71.5k
    uno::Reference< container::XNameAccess > xStyles( static_cast< OWeakObject* >( mpDoc->GetStyleSheetPool() ), css::uno::UNO_QUERY );
3066
71.5k
    return xStyles;
3067
71.5k
}
3068
3069
// XAnyCompareFactory
3070
uno::Reference< css::ucb::XAnyCompare > SAL_CALL SdXImpressDocument::createAnyCompareByName( const OUString& )
3071
765
{
3072
765
    return SvxCreateNumRuleCompare();
3073
765
}
3074
3075
// XRenderable
3076
sal_Int32 SAL_CALL SdXImpressDocument::getRendererCount( const uno::Any& rSelection,
3077
                                                         const uno::Sequence< beans::PropertyValue >&  )
3078
0
{
3079
0
    ::SolarMutexGuard aGuard;
3080
0
    sal_Int32   nRet = 0;
3081
3082
0
    if( nullptr == mpDoc )
3083
0
        throw lang::DisposedException();
3084
3085
0
    if (mpDocShell)
3086
0
    {
3087
0
        uno::Reference< frame::XModel > xModel;
3088
3089
0
        rSelection >>= xModel;
3090
3091
0
        if( xModel == mpDocShell->GetModel() )
3092
0
            nRet = mpDoc->GetSdPageCount( PageKind::Standard );
3093
0
        else
3094
0
        {
3095
0
            uno::Reference< drawing::XShapes > xShapes;
3096
3097
0
            rSelection >>= xShapes;
3098
3099
0
            if( xShapes.is() && xShapes->getCount() )
3100
0
                nRet = 1;
3101
0
        }
3102
0
    }
3103
0
    return nRet;
3104
0
}
3105
3106
uno::Sequence< beans::PropertyValue > SAL_CALL SdXImpressDocument::getRenderer( sal_Int32 , const uno::Any& ,
3107
                                                                                const uno::Sequence< beans::PropertyValue >& rxOptions )
3108
0
{
3109
0
    ::SolarMutexGuard aGuard;
3110
3111
0
    if( nullptr == mpDoc )
3112
0
        throw lang::DisposedException();
3113
3114
0
    bool bExportNotesPages = false;
3115
0
    for( const auto& rOption : rxOptions )
3116
0
    {
3117
0
        if ( rOption.Name == "ExportNotesPages" )
3118
0
            rOption.Value >>= bExportNotesPages;
3119
0
    }
3120
0
    uno::Sequence< beans::PropertyValue > aRenderer;
3121
0
    if (mpDocShell)
3122
0
    {
3123
0
        awt::Size aPageSize;
3124
0
        if ( bExportNotesPages )
3125
0
        {
3126
0
            Size aNotesPageSize = mpDoc->GetSdPage( 0, PageKind::Notes )->GetSize();
3127
0
            aPageSize = awt::Size( aNotesPageSize.Width(), aNotesPageSize.Height() );
3128
0
        }
3129
0
        else
3130
0
        {
3131
0
            const ::tools::Rectangle aVisArea( mpDocShell->GetVisArea( embed::Aspects::MSOLE_DOCPRINT ) );
3132
0
            aPageSize = awt::Size( aVisArea.GetWidth(), aVisArea.GetHeight() );
3133
0
        }
3134
0
        aRenderer = { comphelper::makePropertyValue(u"PageSize"_ustr, aPageSize) };
3135
0
    }
3136
0
    return aRenderer;
3137
0
}
3138
3139
namespace {
3140
3141
class ImplRenderPaintProc : public sdr::contact::ViewObjectContactRedirector
3142
{
3143
    const SdrLayerAdmin&    rLayerAdmin;
3144
    SdrPageView*            pSdrPageView;
3145
3146
public:
3147
    bool IsVisible  ( const SdrObject* pObj ) const;
3148
    bool IsPrintable( const SdrObject* pObj ) const;
3149
3150
    ImplRenderPaintProc(const SdrLayerAdmin& rLA, SdrPageView* pView);
3151
3152
    // all default implementations just call the same methods at the original. To do something
3153
    // different, override the method and at least do what the method does.
3154
    virtual void createRedirectedPrimitive2DSequence(
3155
        const sdr::contact::ViewObjectContact& rOriginal,
3156
        const sdr::contact::DisplayInfo& rDisplayInfo,
3157
        drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor) override;
3158
};
3159
3160
}
3161
3162
ImplRenderPaintProc::ImplRenderPaintProc(const SdrLayerAdmin& rLA, SdrPageView *const pView)
3163
0
    : rLayerAdmin(rLA)
3164
0
    , pSdrPageView(pView)
3165
0
{
3166
0
}
3167
3168
static sal_Int32 ImplPDFGetBookmarkPage( const OUString& rBookmark, SdDrawDocument const & rDoc )
3169
0
{
3170
0
    sal_Int32 nPage = -1;
3171
3172
0
    OUString aBookmark( rBookmark );
3173
3174
0
    if( rBookmark.startsWith("#") )
3175
0
        aBookmark = rBookmark.copy( 1 );
3176
3177
    // is the bookmark a page ?
3178
0
    bool        bIsMasterPage;
3179
0
    sal_uInt16  nPgNum = rDoc.GetPageByName( aBookmark, bIsMasterPage );
3180
3181
0
    if ( nPgNum == SDRPAGE_NOTFOUND )
3182
0
    {
3183
        // is the bookmark an object ?
3184
0
        SdrObject* pObj = rDoc.GetObj( aBookmark );
3185
0
        if (pObj)
3186
0
            nPgNum = pObj->getSdrPageFromSdrObject()->GetPageNum();
3187
0
    }
3188
0
    if ( nPgNum != SDRPAGE_NOTFOUND )
3189
0
        nPage = ( nPgNum - 1 ) / 2;
3190
0
    return nPage;
3191
0
}
3192
3193
static void ImplPDFExportComments( const uno::Reference< drawing::XDrawPage >& xPage, vcl::PDFExtOutDevData& rPDFExtOutDevData )
3194
0
{
3195
0
    try
3196
0
    {
3197
0
        uno::Reference< office::XAnnotationAccess > xAnnotationAccess( xPage, uno::UNO_QUERY_THROW );
3198
0
        uno::Reference< office::XAnnotationEnumeration > xAnnotationEnumeration( xAnnotationAccess->createAnnotationEnumeration() );
3199
3200
0
        while( xAnnotationEnumeration->hasMoreElements() )
3201
0
        {
3202
0
            uno::Reference<office::XAnnotation> xAnnotation(xAnnotationEnumeration->nextElement());
3203
3204
0
            geometry::RealPoint2D aRealPoint2D(xAnnotation->getPosition());
3205
0
            geometry::RealSize2D aRealSize2D(xAnnotation->getSize());
3206
3207
0
            Point aPoint(aRealPoint2D.X * 100.0, aRealPoint2D.Y * 100.0);
3208
0
            Size aSize(aRealSize2D.Width * 100.0, aRealSize2D.Height * 100.0);
3209
3210
0
            Point aPopupPoint(aPoint.X(), aPoint.Y());
3211
0
            Size aPopupSize(aSize.Width() * 10.0, aSize.Height() * 10.0);
3212
3213
0
            uno::Reference<text::XText> xText(xAnnotation->getTextRange());
3214
3215
0
            vcl::pdf::PDFNote aNote;
3216
0
            aNote.maTitle = xAnnotation->getAuthor();
3217
0
            aNote.maContents = xText->getString();
3218
0
            aNote.maModificationDate = xAnnotation->getDateTime();
3219
0
            auto* pAnnotation = dynamic_cast<sd::Annotation*>(xAnnotation.get());
3220
3221
0
            if (pAnnotation && pAnnotation->getCreationInfo().meType != sdr::annotation::AnnotationType::None)
3222
0
            {
3223
0
                sdr::annotation::CreationInfo const& rCreation = pAnnotation->getCreationInfo();
3224
0
                aNote.maPolygons = rCreation.maPolygons;
3225
0
                aNote.maAnnotationColor = rCreation.maColor;
3226
0
                aNote.maInteriorColor = rCreation.maFillColor;
3227
0
                aNote.mfWidth = rCreation.mnWidth;
3228
0
                switch (rCreation.meType)
3229
0
                {
3230
0
                    case sdr::annotation::AnnotationType::Square:
3231
0
                        aNote.meType = vcl::pdf::PDFAnnotationSubType::Square; break;
3232
0
                    case sdr::annotation::AnnotationType::Circle:
3233
0
                        aNote.meType = vcl::pdf::PDFAnnotationSubType::Circle; break;
3234
0
                    case sdr::annotation::AnnotationType::Polygon:
3235
0
                        aNote.meType = vcl::pdf::PDFAnnotationSubType::Polygon; break;
3236
0
                    case sdr::annotation::AnnotationType::Ink:
3237
0
                        aNote.meType = vcl::pdf::PDFAnnotationSubType::Ink; break;
3238
0
                    case sdr::annotation::AnnotationType::Highlight:
3239
0
                        aNote.meType = vcl::pdf::PDFAnnotationSubType::Highlight; break;
3240
0
                    case sdr::annotation::AnnotationType::Line:
3241
0
                        aNote.meType = vcl::pdf::PDFAnnotationSubType::Line; break;
3242
0
                    case sdr::annotation::AnnotationType::FreeText:
3243
0
                        aNote.meType = vcl::pdf::PDFAnnotationSubType::FreeText; break;
3244
0
                    default:
3245
0
                        aNote.meType = vcl::pdf::PDFAnnotationSubType::Text;
3246
0
                        break;
3247
0
                }
3248
0
            }
3249
3250
0
            rPDFExtOutDevData.CreateNote(::tools::Rectangle(aPoint, aSize), aNote,
3251
0
                                         ::tools::Rectangle(aPopupPoint, aPopupSize));
3252
0
        }
3253
0
    }
3254
0
    catch (const uno::Exception&)
3255
0
    {
3256
0
    }
3257
0
}
3258
3259
static void ImplPDFExportShapeInteraction( const uno::Reference< drawing::XShape >& xShape, SdDrawDocument& rDoc, vcl::PDFExtOutDevData& rPDFExtOutDevData )
3260
0
{
3261
0
    if ( xShape->getShapeType() == "com.sun.star.drawing.GroupShape" )
3262
0
    {
3263
0
        uno::Reference< container::XIndexAccess > xIndexAccess( xShape, uno::UNO_QUERY );
3264
0
        if ( xIndexAccess.is() )
3265
0
        {
3266
0
            sal_Int32 i, nCount = xIndexAccess->getCount();
3267
0
            for ( i = 0; i < nCount; i++ )
3268
0
            {
3269
0
                uno::Reference< drawing::XShape > xSubShape( xIndexAccess->getByIndex( i ), uno::UNO_QUERY );
3270
0
                if ( xSubShape.is() )
3271
0
                    ImplPDFExportShapeInteraction( xSubShape, rDoc, rPDFExtOutDevData );
3272
0
            }
3273
0
        }
3274
0
    }
3275
0
    else
3276
0
    {
3277
0
        uno::Reference< beans::XPropertySet > xShapePropSet( xShape, uno::UNO_QUERY );
3278
0
        if( xShapePropSet.is() )
3279
0
        {
3280
0
            Size        aPageSize( rDoc.GetSdPage( 0, PageKind::Standard )->GetSize() );
3281
0
            Point aPoint( 0, 0 );
3282
0
            ::tools::Rectangle   aPageRect( aPoint, aPageSize );
3283
3284
0
            awt::Point  aShapePos( xShape->getPosition() );
3285
0
            awt::Size   aShapeSize( xShape->getSize() );
3286
0
            ::tools::Rectangle   aLinkRect( Point( aShapePos.X, aShapePos.Y ), Size( aShapeSize.Width, aShapeSize.Height ) );
3287
3288
            // Handle linked videos.
3289
0
            if (xShape->getShapeType() == "com.sun.star.drawing.MediaShape" || xShape->getShapeType() == "com.sun.star.presentation.MediaShape")
3290
0
            {
3291
0
                OUString title;
3292
0
                xShapePropSet->getPropertyValue(u"Title"_ustr) >>= title;
3293
0
                OUString description;
3294
0
                xShapePropSet->getPropertyValue(u"Description"_ustr) >>= description;
3295
0
                OUString const altText(title.isEmpty()
3296
0
                    ? description
3297
0
                    : description.isEmpty()
3298
0
                        ? title
3299
0
                        : OUString::Concat(title) + OUString::Concat("\n") + OUString::Concat(description));
3300
3301
0
                OUString aMediaURL;
3302
0
                xShapePropSet->getPropertyValue(u"MediaURL"_ustr) >>= aMediaURL;
3303
0
                if (!aMediaURL.isEmpty())
3304
0
                {
3305
0
                    SdrObject const*const pSdrObj(SdrObject::getSdrObjectFromXShape(xShape));
3306
0
                    OUString const mimeType(xShapePropSet->getPropertyValue(u"MediaMimeType"_ustr).get<OUString>());
3307
0
                    sal_Int32 nScreenId = rPDFExtOutDevData.CreateScreen(aLinkRect, altText, mimeType, rPDFExtOutDevData.GetCurrentPageNumber(), pSdrObj);
3308
0
                    if (aMediaURL.startsWith("vnd.sun.star.Package:"))
3309
0
                    {
3310
0
                        OUString aTempFileURL;
3311
0
                        xShapePropSet->getPropertyValue(u"PrivateTempFileURL"_ustr) >>= aTempFileURL;
3312
0
                        rPDFExtOutDevData.SetScreenStream(nScreenId, aTempFileURL);
3313
0
                    }
3314
0
                    else
3315
0
                        rPDFExtOutDevData.SetScreenURL(nScreenId, aMediaURL);
3316
0
                }
3317
0
            }
3318
3319
0
            presentation::ClickAction eCa;
3320
0
            uno::Any aAny( xShapePropSet->getPropertyValue( u"OnClick"_ustr ) );
3321
0
            if ( aAny >>= eCa )
3322
0
            {
3323
0
                OUString const actionName(SdResId(SdTPAction::GetClickActionSdResId(eCa)));
3324
0
                switch ( eCa )
3325
0
                {
3326
0
                    case presentation::ClickAction_LASTPAGE :
3327
0
                    {
3328
0
                        sal_Int32 nCount = rDoc.GetSdPageCount( PageKind::Standard );
3329
0
                        sal_Int32 nDestId = rPDFExtOutDevData.CreateDest( aPageRect, nCount - 1, vcl::pdf::PDFWriter::DestAreaType::FitRectangle );
3330
0
                        sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink(aLinkRect, actionName);
3331
0
                        rPDFExtOutDevData.SetLinkDest( nLinkId, nDestId );
3332
0
                    }
3333
0
                    break;
3334
0
                    case presentation::ClickAction_FIRSTPAGE :
3335
0
                    {
3336
0
                        sal_Int32 nDestId = rPDFExtOutDevData.CreateDest( aPageRect, 0, vcl::pdf::PDFWriter::DestAreaType::FitRectangle );
3337
0
                        sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink(aLinkRect, actionName);
3338
0
                        rPDFExtOutDevData.SetLinkDest( nLinkId, nDestId );
3339
0
                    }
3340
0
                    break;
3341
0
                    case presentation::ClickAction_PREVPAGE :
3342
0
                    {
3343
0
                        sal_Int32 nDestPage = rPDFExtOutDevData.GetCurrentPageNumber();
3344
0
                        if ( nDestPage )
3345
0
                            nDestPage--;
3346
0
                        sal_Int32 nDestId = rPDFExtOutDevData.CreateDest( aPageRect, nDestPage, vcl::pdf::PDFWriter::DestAreaType::FitRectangle );
3347
0
                        sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink(aLinkRect, actionName);
3348
0
                        rPDFExtOutDevData.SetLinkDest( nLinkId, nDestId );
3349
0
                    }
3350
0
                    break;
3351
0
                    case presentation::ClickAction_NEXTPAGE :
3352
0
                    {
3353
0
                        sal_Int32 nDestPage = rPDFExtOutDevData.GetCurrentPageNumber() + 1;
3354
0
                        sal_Int32 nLastPage = rDoc.GetSdPageCount( PageKind::Standard ) - 1;
3355
0
                        if ( nDestPage > nLastPage )
3356
0
                            nDestPage = nLastPage;
3357
0
                        sal_Int32 nDestId = rPDFExtOutDevData.CreateDest( aPageRect, nDestPage, vcl::pdf::PDFWriter::DestAreaType::FitRectangle );
3358
0
                        sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink(aLinkRect, actionName);
3359
0
                        rPDFExtOutDevData.SetLinkDest( nLinkId, nDestId );
3360
0
                    }
3361
0
                    break;
3362
3363
0
                    case presentation::ClickAction_PROGRAM :
3364
0
                    case presentation::ClickAction_BOOKMARK :
3365
0
                    case presentation::ClickAction_DOCUMENT :
3366
0
                    {
3367
0
                        OUString aBookmark;
3368
0
                        xShapePropSet->getPropertyValue( u"Bookmark"_ustr ) >>= aBookmark;
3369
0
                        if( !aBookmark.isEmpty() )
3370
0
                        {
3371
0
                            switch( eCa )
3372
0
                            {
3373
0
                                case presentation::ClickAction_DOCUMENT :
3374
0
                                case presentation::ClickAction_PROGRAM :
3375
0
                                {
3376
0
                                    sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink(aLinkRect, actionName);
3377
0
                                    rPDFExtOutDevData.SetLinkURL( nLinkId, aBookmark );
3378
0
                                }
3379
0
                                break;
3380
0
                                case presentation::ClickAction_BOOKMARK :
3381
0
                                {
3382
0
                                    sal_Int32 nPage = ImplPDFGetBookmarkPage( aBookmark, rDoc );
3383
0
                                    if ( nPage != -1 )
3384
0
                                    {
3385
0
                                        sal_Int32 nDestId = rPDFExtOutDevData.CreateDest( aPageRect, nPage, vcl::pdf::PDFWriter::DestAreaType::FitRectangle );
3386
0
                                        sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink(aLinkRect, actionName);
3387
0
                                        rPDFExtOutDevData.SetLinkDest( nLinkId, nDestId );
3388
0
                                    }
3389
0
                                }
3390
0
                                break;
3391
0
                                default:
3392
0
                                    break;
3393
0
                            }
3394
0
                        }
3395
0
                    }
3396
0
                    break;
3397
3398
0
                    case presentation::ClickAction_STOPPRESENTATION :
3399
0
                    case presentation::ClickAction_SOUND :
3400
0
                    case presentation::ClickAction_INVISIBLE :
3401
0
                    case presentation::ClickAction_VERB :
3402
0
                    case presentation::ClickAction_VANISH :
3403
0
                    case presentation::ClickAction_MACRO :
3404
0
                    default :
3405
0
                    break;
3406
0
                }
3407
0
            }
3408
0
        }
3409
0
    }
3410
0
}
3411
3412
void ImplRenderPaintProc::createRedirectedPrimitive2DSequence(
3413
    const sdr::contact::ViewObjectContact& rOriginal,
3414
    const sdr::contact::DisplayInfo& rDisplayInfo,
3415
    drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor)
3416
0
{
3417
0
    SdrObject* pObject = rOriginal.GetViewContact().TryToGetSdrObject();
3418
0
    if(!pObject)
3419
0
    {
3420
        // not an object, maybe a page
3421
0
        sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(rOriginal, rDisplayInfo, rVisitor);
3422
0
        return;
3423
0
    }
3424
0
    SdrPage* pSdrPage(pObject->getSdrPageFromSdrObject());
3425
0
    if(!pSdrPage)
3426
0
        return;
3427
0
    if(!pSdrPage->checkVisibility(rOriginal, rDisplayInfo, false))
3428
0
        return;
3429
0
    if(!IsVisible(pObject) || !IsPrintable(pObject))
3430
0
        return;
3431
3432
0
    sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(rOriginal, rDisplayInfo, rVisitor);
3433
0
}
3434
3435
bool ImplRenderPaintProc::IsVisible( const SdrObject* pObj ) const
3436
0
{
3437
0
    bool bVisible = true;
3438
0
    SdrLayerID nLayerId = pObj->GetLayer();
3439
0
    if( pSdrPageView )
3440
0
    {
3441
0
        const SdrLayer* pSdrLayer = rLayerAdmin.GetLayerPerID( nLayerId );
3442
0
        if ( pSdrLayer )
3443
0
        {
3444
0
            const OUString& aLayerName = pSdrLayer->GetName();
3445
0
            bVisible = pSdrPageView->IsLayerVisible( aLayerName );
3446
0
        }
3447
0
    }
3448
0
    return bVisible;
3449
0
}
3450
bool ImplRenderPaintProc::IsPrintable( const SdrObject* pObj ) const
3451
0
{
3452
0
    bool bPrintable = true;
3453
0
    SdrLayerID nLayerId = pObj->GetLayer();
3454
0
    if( pSdrPageView )
3455
0
    {
3456
0
        const SdrLayer* pSdrLayer = rLayerAdmin.GetLayerPerID( nLayerId );
3457
0
        if ( pSdrLayer )
3458
0
        {
3459
0
            const OUString& aLayerName = pSdrLayer->GetName();
3460
0
            bPrintable = pSdrPageView->IsLayerPrintable( aLayerName );
3461
0
        }
3462
0
    }
3463
0
    return bPrintable;
3464
3465
0
}
3466
3467
namespace
3468
{
3469
    sal_Int16 CalcOutputPageNum(vcl::PDFExtOutDevData const * pPDFExtOutDevData, SdDrawDocument const *pDoc, sal_Int16 nPageNumber)
3470
0
    {
3471
        //export all pages, simple one to one case
3472
0
        if (pPDFExtOutDevData && pPDFExtOutDevData->GetIsExportHiddenSlides())
3473
0
            return nPageNumber-1;
3474
        //check all preceding pages, and only count non-hidden ones
3475
0
        sal_Int16 nRet = 0;
3476
0
        for (sal_Int16 i = 0; i < nPageNumber-1; ++i)
3477
0
        {
3478
0
           if (!pDoc->GetSdPage(i, PageKind::Standard)->IsExcluded())
3479
0
                ++nRet;
3480
0
        }
3481
0
        return nRet;
3482
0
    }
3483
}
3484
3485
void SAL_CALL SdXImpressDocument::render( sal_Int32 nRenderer, const uno::Any& rSelection,
3486
                                          const uno::Sequence< beans::PropertyValue >& rxOptions )
3487
0
{
3488
0
    ::SolarMutexGuard aGuard;
3489
3490
0
    if( nullptr == mpDoc )
3491
0
        throw lang::DisposedException();
3492
3493
0
    if (!mpDocShell)
3494
0
        return;
3495
3496
0
    uno::Reference< awt::XDevice >  xRenderDevice;
3497
0
    const sal_Int32                 nPageNumber = nRenderer + 1;
3498
0
    PageKind                        ePageKind = PageKind::Standard;
3499
0
    bool                        bExportNotesPages = false;
3500
3501
0
    for( const auto& rOption : rxOptions )
3502
0
    {
3503
0
        if ( rOption.Name == "RenderDevice" )
3504
0
            rOption.Value >>= xRenderDevice;
3505
0
        else if ( rOption.Name == "ExportNotesPages" )
3506
0
        {
3507
0
            rOption.Value >>= bExportNotesPages;
3508
0
            if ( bExportNotesPages )
3509
0
                ePageKind = PageKind::Notes;
3510
0
        }
3511
0
    }
3512
3513
0
    if( !(xRenderDevice.is() && nPageNumber && ( nPageNumber <= mpDoc->GetSdPageCount( ePageKind ) )) )
3514
0
        return;
3515
3516
0
    VCLXDevice* pDevice = dynamic_cast<VCLXDevice*>( xRenderDevice.get() );
3517
0
    VclPtr< OutputDevice> pOut = pDevice ? pDevice->GetOutputDevice() : VclPtr< OutputDevice >();
3518
3519
0
    if( !pOut )
3520
0
        return;
3521
3522
0
    vcl::PDFExtOutDevData* pPDFExtOutDevData = dynamic_cast<vcl::PDFExtOutDevData* >( pOut->GetExtOutDevData() );
3523
3524
0
    if ( mpDoc->GetSdPage(static_cast<sal_Int16>(nPageNumber)-1, PageKind::Standard)->IsExcluded() &&
3525
0
        !(pPDFExtOutDevData && pPDFExtOutDevData->GetIsExportHiddenSlides()) )
3526
0
        return;
3527
3528
0
    if (pPDFExtOutDevData)
3529
0
    {
3530
0
        css::lang::Locale const docLocale(Application::GetSettings().GetLanguageTag().getLocale());
3531
0
        pPDFExtOutDevData->SetDocumentLocale(docLocale);
3532
0
    }
3533
3534
0
    ::sd::ClientView aView( mpDocShell, pOut );
3535
0
    ::tools::Rectangle aVisArea( Point(), mpDoc->GetSdPage( static_cast<sal_uInt16>(nPageNumber) - 1, ePageKind )->GetSize() );
3536
0
    vcl::Region                       aRegion( aVisArea );
3537
3538
0
    ::sd::ViewShell* pOldViewSh = mpDocShell->GetViewShell();
3539
0
    ::sd::View* pOldSdView = pOldViewSh ? pOldViewSh->GetView() : nullptr;
3540
3541
0
    if  ( pOldSdView )
3542
0
        pOldSdView->SdrEndTextEdit();
3543
3544
0
    aView.SetHlplVisible( false );
3545
0
    aView.SetGridVisible( false );
3546
0
    aView.SetBordVisible( false );
3547
0
    aView.SetPageVisible( false );
3548
0
    aView.SetGlueVisible( false );
3549
3550
0
    pOut->SetMapMode(MapMode(MapUnit::Map100thMM));
3551
0
    pOut->IntersectClipRegion( aVisArea );
3552
3553
0
    uno::Reference< frame::XModel > xModel;
3554
0
    rSelection >>= xModel;
3555
3556
0
    if( xModel == mpDocShell->GetModel() )
3557
0
    {
3558
0
        aView.ShowSdrPage( mpDoc->GetSdPage( static_cast<sal_uInt16>(nPageNumber) - 1, ePageKind ));
3559
0
        SdrPageView* pPV = aView.GetSdrPageView();
3560
3561
0
        if( pOldSdView )
3562
0
        {
3563
0
            SdrPageView* pOldPV = pOldSdView->GetSdrPageView();
3564
0
            if( pPV && pOldPV )
3565
0
            {
3566
0
                pPV->SetVisibleLayers( pOldPV->GetVisibleLayers() );
3567
0
                pPV->SetPrintableLayers( pOldPV->GetPrintableLayers() );
3568
0
            }
3569
0
        }
3570
3571
0
        ImplRenderPaintProc aImplRenderPaintProc( mpDoc->GetLayerAdmin(),
3572
0
            pPV);
3573
3574
        // background color for outliner :o
3575
0
        SdPage* pPage = pPV ? static_cast<SdPage*>(pPV->GetPage()) : nullptr;
3576
0
        if( pPage )
3577
0
        {
3578
0
            SdrOutliner& rOutl = mpDoc->GetDrawOutliner();
3579
0
            bool bScreenDisplay(true);
3580
3581
            // #i75566# printing; suppress AutoColor BackgroundColor generation
3582
            // for visibility reasons by giving GetPageBackgroundColor()
3583
            // the needed hint
3584
            // #i75566# PDF export; suppress AutoColor BackgroundColor generation (see printing)
3585
0
            if (pOut && ((OUTDEV_PRINTER == pOut->GetOutDevType())
3586
0
                    || (OUTDEV_PDF == pOut->GetOutDevType())))
3587
0
                bScreenDisplay = false;
3588
3589
            // #i75566# Name change GetBackgroundColor -> GetPageBackgroundColor and
3590
            // hint value if screen display. Only then the AutoColor mechanisms shall be applied
3591
0
            rOutl.SetBackgroundColor( pPage->GetPageBackgroundColor( pPV, bScreenDisplay ) );
3592
0
        }
3593
3594
        // produce link annots for media shapes before painting them
3595
0
        if ( pPDFExtOutDevData && pPage )
3596
0
        {
3597
0
            try
3598
0
            {
3599
0
                uno::Any aAny;
3600
0
                uno::Reference< drawing::XDrawPage > xPage( uno::Reference< drawing::XDrawPage >::query( pPage->getUnoPage() ) );
3601
0
                if ( xPage.is() )
3602
0
                {
3603
0
                    if ( pPDFExtOutDevData->GetIsExportNotes() )
3604
0
                        ImplPDFExportComments( xPage, *pPDFExtOutDevData );
3605
0
                    uno::Reference< beans::XPropertySet > xPagePropSet( xPage, uno::UNO_QUERY );
3606
0
                    if( xPagePropSet.is() )
3607
0
                    {
3608
                        // exporting object interactions to pdf
3609
3610
                        // if necessary, the master page interactions will be exported first
3611
0
                        bool bIsBackgroundObjectsVisible = false;   // #i39428# IsBackgroundObjectsVisible not available for Draw
3612
0
                        if ( mbImpressDoc && xPagePropSet->getPropertySetInfo()->hasPropertyByName( u"IsBackgroundObjectsVisible"_ustr ) )
3613
0
                            xPagePropSet->getPropertyValue( u"IsBackgroundObjectsVisible"_ustr ) >>= bIsBackgroundObjectsVisible;
3614
0
                        if ( bIsBackgroundObjectsVisible && !pPDFExtOutDevData->GetIsExportNotesPages() )
3615
0
                        {
3616
0
                            uno::Reference< drawing::XMasterPageTarget > xMasterPageTarget( xPage, uno::UNO_QUERY );
3617
0
                            if ( xMasterPageTarget.is() )
3618
0
                            {
3619
0
                                uno::Reference< drawing::XDrawPage > xMasterPage = xMasterPageTarget->getMasterPage();
3620
0
                                if ( xMasterPage.is() )
3621
0
                                {
3622
0
                                    sal_Int32 i, nCount = xMasterPage->getCount();
3623
0
                                    for ( i = 0; i < nCount; i++ )
3624
0
                                    {
3625
0
                                        aAny = xMasterPage->getByIndex( i );
3626
0
                                        uno::Reference< drawing::XShape > xShape;
3627
0
                                        if ( aAny >>= xShape )
3628
0
                                            ImplPDFExportShapeInteraction( xShape, *mpDoc, *pPDFExtOutDevData );
3629
0
                                    }
3630
0
                                }
3631
0
                            }
3632
0
                        }
3633
3634
                        // exporting slide page object interactions
3635
0
                        sal_Int32 i, nCount = xPage->getCount();
3636
0
                        for ( i = 0; i < nCount; i++ )
3637
0
                        {
3638
0
                            aAny = xPage->getByIndex( i );
3639
0
                            uno::Reference< drawing::XShape > xShape;
3640
0
                            if ( aAny >>= xShape )
3641
0
                                ImplPDFExportShapeInteraction( xShape, *mpDoc, *pPDFExtOutDevData );
3642
0
                        }
3643
3644
                        // exporting transition effects to pdf
3645
0
                        if ( mbImpressDoc && !pPDFExtOutDevData->GetIsExportNotesPages() && pPDFExtOutDevData->GetIsExportTransitionEffects() )
3646
0
                        {
3647
0
                            static constexpr OUString sEffect( u"Effect"_ustr );
3648
0
                            static constexpr OUString sSpeed ( u"Speed"_ustr );
3649
0
                            sal_Int32 nTime = 800;
3650
0
                            presentation::AnimationSpeed aAs;
3651
0
                            if ( xPagePropSet->getPropertySetInfo( )->hasPropertyByName( sSpeed ) )
3652
0
                            {
3653
0
                                aAny = xPagePropSet->getPropertyValue( sSpeed );
3654
0
                                if ( aAny >>= aAs )
3655
0
                                {
3656
0
                                    switch( aAs )
3657
0
                                    {
3658
0
                                        case presentation::AnimationSpeed_SLOW : nTime = 1500; break;
3659
0
                                        case presentation::AnimationSpeed_FAST : nTime = 300; break;
3660
0
                                        default:
3661
0
                                        case presentation::AnimationSpeed_MEDIUM : nTime = 800;
3662
0
                                    }
3663
0
                                }
3664
0
                            }
3665
0
                            presentation::FadeEffect eFe;
3666
0
                            vcl::pdf::PDFWriter::PageTransition eType = vcl::pdf::PDFWriter::PageTransition::Regular;
3667
0
                            if ( xPagePropSet->getPropertySetInfo( )->hasPropertyByName( sEffect ) )
3668
0
                            {
3669
0
                                aAny = xPagePropSet->getPropertyValue( sEffect );
3670
0
                                if ( aAny >>= eFe )
3671
0
                                {
3672
0
                                    switch( eFe )
3673
0
                                    {
3674
0
                                        case presentation::FadeEffect_HORIZONTAL_LINES :
3675
0
                                        case presentation::FadeEffect_HORIZONTAL_CHECKERBOARD :
3676
0
                                        case presentation::FadeEffect_HORIZONTAL_STRIPES : eType = vcl::pdf::PDFWriter::PageTransition::BlindsHorizontal; break;
3677
3678
0
                                        case presentation::FadeEffect_VERTICAL_LINES :
3679
0
                                        case presentation::FadeEffect_VERTICAL_CHECKERBOARD :
3680
0
                                        case presentation::FadeEffect_VERTICAL_STRIPES : eType = vcl::pdf::PDFWriter::PageTransition::BlindsVertical; break;
3681
3682
0
                                        case presentation::FadeEffect_UNCOVER_TO_RIGHT :
3683
0
                                        case presentation::FadeEffect_UNCOVER_TO_UPPERRIGHT :
3684
0
                                        case presentation::FadeEffect_ROLL_FROM_LEFT :
3685
0
                                        case presentation::FadeEffect_FADE_FROM_UPPERLEFT :
3686
0
                                        case presentation::FadeEffect_MOVE_FROM_UPPERLEFT :
3687
0
                                        case presentation::FadeEffect_FADE_FROM_LEFT :
3688
0
                                        case presentation::FadeEffect_MOVE_FROM_LEFT : eType = vcl::pdf::PDFWriter::PageTransition::WipeLeftToRight; break;
3689
3690
0
                                        case presentation::FadeEffect_UNCOVER_TO_BOTTOM :
3691
0
                                        case presentation::FadeEffect_UNCOVER_TO_LOWERRIGHT :
3692
0
                                        case presentation::FadeEffect_ROLL_FROM_TOP :
3693
0
                                        case presentation::FadeEffect_FADE_FROM_UPPERRIGHT :
3694
0
                                        case presentation::FadeEffect_MOVE_FROM_UPPERRIGHT :
3695
0
                                        case presentation::FadeEffect_FADE_FROM_TOP :
3696
0
                                        case presentation::FadeEffect_MOVE_FROM_TOP : eType = vcl::pdf::PDFWriter::PageTransition::WipeTopToBottom; break;
3697
3698
0
                                        case presentation::FadeEffect_UNCOVER_TO_LEFT :
3699
0
                                        case presentation::FadeEffect_UNCOVER_TO_LOWERLEFT :
3700
0
                                        case presentation::FadeEffect_ROLL_FROM_RIGHT :
3701
3702
0
                                        case presentation::FadeEffect_FADE_FROM_LOWERRIGHT :
3703
0
                                        case presentation::FadeEffect_MOVE_FROM_LOWERRIGHT :
3704
0
                                        case presentation::FadeEffect_FADE_FROM_RIGHT :
3705
0
                                        case presentation::FadeEffect_MOVE_FROM_RIGHT : eType = vcl::pdf::PDFWriter::PageTransition::WipeRightToLeft; break;
3706
3707
0
                                        case presentation::FadeEffect_UNCOVER_TO_TOP :
3708
0
                                        case presentation::FadeEffect_UNCOVER_TO_UPPERLEFT :
3709
0
                                        case presentation::FadeEffect_ROLL_FROM_BOTTOM :
3710
0
                                        case presentation::FadeEffect_FADE_FROM_LOWERLEFT :
3711
0
                                        case presentation::FadeEffect_MOVE_FROM_LOWERLEFT :
3712
0
                                        case presentation::FadeEffect_FADE_FROM_BOTTOM :
3713
0
                                        case presentation::FadeEffect_MOVE_FROM_BOTTOM : eType = vcl::pdf::PDFWriter::PageTransition::WipeBottomToTop; break;
3714
3715
0
                                        case presentation::FadeEffect_OPEN_VERTICAL : eType = vcl::pdf::PDFWriter::PageTransition::SplitHorizontalInward; break;
3716
0
                                        case presentation::FadeEffect_CLOSE_HORIZONTAL : eType = vcl::pdf::PDFWriter::PageTransition::SplitHorizontalOutward; break;
3717
3718
0
                                        case presentation::FadeEffect_OPEN_HORIZONTAL : eType = vcl::pdf::PDFWriter::PageTransition::SplitVerticalInward; break;
3719
0
                                        case presentation::FadeEffect_CLOSE_VERTICAL : eType = vcl::pdf::PDFWriter::PageTransition::SplitVerticalOutward; break;
3720
3721
0
                                        case presentation::FadeEffect_FADE_TO_CENTER : eType = vcl::pdf::PDFWriter::PageTransition::BoxInward; break;
3722
0
                                        case presentation::FadeEffect_FADE_FROM_CENTER : eType = vcl::pdf::PDFWriter::PageTransition::BoxOutward; break;
3723
3724
0
                                        case presentation::FadeEffect_NONE : eType = vcl::pdf::PDFWriter::PageTransition::Regular; break;
3725
3726
0
                                        case presentation::FadeEffect_RANDOM :
3727
0
                                        case presentation::FadeEffect_DISSOLVE :
3728
0
                                        default: eType = vcl::pdf::PDFWriter::PageTransition::Dissolve; break;
3729
0
                                    }
3730
0
                                }
3731
0
                            }
3732
3733
0
                            if ( xPagePropSet->getPropertySetInfo( )->hasPropertyByName( sEffect ) ||
3734
0
                                xPagePropSet->getPropertySetInfo( )->hasPropertyByName( sSpeed ) )
3735
0
                            {
3736
0
                                pPDFExtOutDevData->SetPageTransition( eType, nTime );
3737
0
                            }
3738
0
                        }
3739
0
                    }
3740
0
                }
3741
0
            }
3742
0
            catch (const uno::Exception&)
3743
0
            {
3744
0
            }
3745
0
        }
3746
3747
0
        aView.SdrPaintView::CompleteRedraw(pOut, aRegion, &aImplRenderPaintProc);
3748
3749
0
        if (pPDFExtOutDevData && pPage)
3750
0
        {
3751
0
            try
3752
0
            {
3753
0
                Size        aPageSize( mpDoc->GetSdPage( 0, PageKind::Standard )->GetSize() );
3754
0
                Point aPoint( 0, 0 );
3755
0
                ::tools::Rectangle   aPageRect( aPoint, aPageSize );
3756
3757
                // resolving links found in this page by the method ImpEditEngine::Paint
3758
0
                std::vector< vcl::PDFExtOutDevBookmarkEntry >& rBookmarks = pPDFExtOutDevData->GetBookmarks();
3759
0
                for ( const auto& rBookmark : rBookmarks )
3760
0
                {
3761
0
                    sal_Int32 nPage = ImplPDFGetBookmarkPage( rBookmark.aBookmark, *mpDoc );
3762
0
                    if ( nPage != -1 )
3763
0
                    {
3764
0
                        if ( rBookmark.nLinkId != -1 )
3765
0
                            pPDFExtOutDevData->SetLinkDest( rBookmark.nLinkId, pPDFExtOutDevData->CreateDest( aPageRect, nPage, vcl::pdf::PDFWriter::DestAreaType::FitRectangle ) );
3766
0
                        else
3767
0
                            pPDFExtOutDevData->DescribeRegisteredDest( rBookmark.nDestId, aPageRect, nPage, vcl::pdf::PDFWriter::DestAreaType::FitRectangle );
3768
0
                    }
3769
0
                    else
3770
0
                        pPDFExtOutDevData->SetLinkURL( rBookmark.nLinkId, rBookmark.aBookmark );
3771
0
                }
3772
0
                rBookmarks.clear();
3773
                //---> #i56629, #i40318
3774
                //get the page name, will be used as outline element in PDF bookmark pane
3775
0
                OUString aPageName = mpDoc->GetSdPage( static_cast<sal_uInt16>(nPageNumber) - 1 , PageKind::Standard )->GetName();
3776
0
                if( !aPageName.isEmpty() )
3777
0
                {
3778
                    // Destination PageNum
3779
0
                    const sal_Int32 nDestPageNum = CalcOutputPageNum(pPDFExtOutDevData, mpDoc, nPageNumber);
3780
3781
                    // insert the bookmark to this page into the NamedDestinations
3782
0
                    if( pPDFExtOutDevData->GetIsExportNamedDestinations() )
3783
0
                        pPDFExtOutDevData->CreateNamedDest(aPageName, aPageRect, nDestPageNum);
3784
3785
                    // add the name to the outline, (almost) same code as in sc/source/ui/unoobj/docuno.cxx
3786
                    // issue #i40318.
3787
3788
0
                    if( pPDFExtOutDevData->GetIsExportBookmarks() )
3789
0
                    {
3790
                        // Destination Export
3791
0
                        const sal_Int32 nDestId =
3792
0
                            pPDFExtOutDevData->CreateDest(aPageRect , nDestPageNum);
3793
3794
                        // Create a new outline item:
3795
0
                        pPDFExtOutDevData->CreateOutlineItem( -1 , aPageName, nDestId );
3796
0
                    }
3797
0
                }
3798
                //<--- #i56629, #i40318
3799
0
            }
3800
0
            catch (const uno::Exception&)
3801
0
            {
3802
0
            }
3803
3804
0
        }
3805
0
    }
3806
0
    else
3807
0
    {
3808
0
        uno::Reference< drawing::XShapes > xShapes;
3809
0
        rSelection >>= xShapes;
3810
3811
0
        if( xShapes.is() && xShapes->getCount() )
3812
0
        {
3813
0
            SdrPageView* pPV = nullptr;
3814
3815
0
            ImplRenderPaintProc  aImplRenderPaintProc( mpDoc->GetLayerAdmin(),
3816
0
                            pOldSdView ? pOldSdView->GetSdrPageView() : nullptr);
3817
3818
0
            for( sal_uInt32 i = 0, nCount = xShapes->getCount(); i < nCount; i++ )
3819
0
            {
3820
0
                uno::Reference< drawing::XShape > xShape;
3821
0
                xShapes->getByIndex( i ) >>= xShape;
3822
3823
0
                if( xShape.is() )
3824
0
                {
3825
0
                    SdrObject* pObj = SdrObject::getSdrObjectFromXShape( xShape );
3826
0
                    if( pObj && pObj->getSdrPageFromSdrObject()
3827
0
                        && aImplRenderPaintProc.IsVisible( pObj )
3828
0
                            && aImplRenderPaintProc.IsPrintable( pObj ) )
3829
0
                    {
3830
0
                        if( !pPV )
3831
0
                            pPV = aView.ShowSdrPage( pObj->getSdrPageFromSdrObject() );
3832
3833
0
                        if( pPV )
3834
0
                            aView.MarkObj( pObj, pPV );
3835
0
                    }
3836
0
                }
3837
0
            }
3838
0
            aView.DrawMarkedObj(*pOut);
3839
0
        }
3840
0
    }
3841
0
}
3842
3843
DrawViewShell* SdXImpressDocument::GetViewShell()
3844
0
{
3845
0
    if (!mpDocShell)
3846
0
    {
3847
0
        return nullptr;
3848
0
    }
3849
3850
0
    DrawViewShell* pViewSh = dynamic_cast<DrawViewShell*>(mpDocShell->GetViewShell());
3851
0
    if (!pViewSh)
3852
0
    {
3853
0
        SAL_WARN("sd", "DrawViewShell not available!");
3854
0
        return nullptr;
3855
0
    }
3856
0
    return pViewSh;
3857
0
}
3858
3859
void SdXImpressDocument::paintTile( VirtualDevice& rDevice,
3860
                            int nOutputWidth, int nOutputHeight,
3861
                            int nTilePosX, int nTilePosY,
3862
                            ::tools::Long nTileWidth, ::tools::Long nTileHeight )
3863
0
{
3864
0
    DrawViewShell* pViewSh = GetViewShell();
3865
0
    if (!pViewSh)
3866
0
        return;
3867
3868
    // we need to skip tile invalidation for controls on rendering
3869
0
    comphelper::LibreOfficeKit::setTiledPainting(true);
3870
3871
    // Setup drawing layer to work properly. Since we use a custom VirtualDevice
3872
    // for the drawing, SdrPaintView::BeginCompleteRedraw() will call FindPaintWindow()
3873
    // unsuccessfully and use a temporary window that doesn't keep state. So patch
3874
    // the existing SdrPageWindow to use a temporary, and this way the state will be kept.
3875
    // Well, at least that's how I understand it based on Writer's RenderContextGuard,
3876
    // as the drawing layer classes lack documentation.
3877
0
    SdrPageWindow* patchedPageWindow = nullptr;
3878
0
    SdrPaintWindow* previousPaintWindow = nullptr;
3879
0
    std::unique_ptr<SdrPaintWindow> temporaryPaintWindow;
3880
0
    if(SdrView* pDrawView = pViewSh->GetDrawView())
3881
0
    {
3882
0
        if(SdrPageView* pSdrPageView = pDrawView->GetSdrPageView())
3883
0
        {
3884
0
            pSdrPageView->SetApplicationDocumentColor(pViewSh->GetViewOptions().mnDocBackgroundColor);
3885
0
            patchedPageWindow = pSdrPageView->FindPageWindow(*getDocWindow()->GetOutDev());
3886
0
            temporaryPaintWindow.reset(new SdrPaintWindow(*pDrawView, rDevice));
3887
0
            if (patchedPageWindow)
3888
0
                previousPaintWindow = patchedPageWindow->patchPaintWindow(*temporaryPaintWindow);
3889
0
        }
3890
0
    }
3891
3892
    // Scaling. Must convert from pixels to twips. We know
3893
    // that VirtualDevices use a DPI of 96.
3894
    // We specifically calculate these scales first as we're still
3895
    // in TWIPs, and might as well minimize the number of conversions.
3896
0
    const double scale = conversionFract(o3tl::Length::px, o3tl::Length::twip);
3897
0
    double scaleX = double(nOutputWidth) / nTileWidth * scale;
3898
0
    double scaleY = double(nOutputHeight) / nTileHeight * scale;
3899
3900
    // svx seems to be the only component that works natively in
3901
    // 100th mm rather than TWIP. It makes most sense just to
3902
    // convert here and in getDocumentSize, and leave the tiled
3903
    // rendering API working in TWIPs.
3904
0
    ::tools::Long nTileWidthHMM = convertTwipToMm100( nTileWidth );
3905
0
    ::tools::Long nTileHeightHMM = convertTwipToMm100( nTileHeight );
3906
0
    int nTilePosXHMM = convertTwipToMm100( nTilePosX );
3907
0
    int nTilePosYHMM = convertTwipToMm100( nTilePosY );
3908
3909
0
    MapMode aMapMode = rDevice.GetMapMode();
3910
0
    aMapMode.SetMapUnit( MapUnit::Map100thMM );
3911
0
    aMapMode.SetOrigin( Point( -nTilePosXHMM,
3912
0
                               -nTilePosYHMM) );
3913
0
    aMapMode.SetScaleX( scaleX );
3914
0
    aMapMode.SetScaleY( scaleY );
3915
3916
0
    rDevice.SetMapMode( aMapMode );
3917
3918
0
    rDevice.SetOutputSizePixel( Size(nOutputWidth, nOutputHeight), /*bErase*/false );
3919
3920
0
    Point aPoint(nTilePosXHMM, nTilePosYHMM);
3921
0
    Size aSize(nTileWidthHMM, nTileHeightHMM);
3922
0
    ::tools::Rectangle aRect(aPoint, aSize);
3923
3924
0
    SdrView* pView = pViewSh->GetDrawView();
3925
0
    if (comphelper::LibreOfficeKit::isActive())
3926
0
        pView->SetPaintTextEdit(mbPaintTextEdit);
3927
3928
0
    pViewSh->GetView()->CompleteRedraw(&rDevice, vcl::Region(aRect));
3929
3930
0
    if (comphelper::LibreOfficeKit::isActive())
3931
0
        pView->SetPaintTextEdit(true);
3932
3933
0
    LokChartHelper::PaintAllChartsOnTile(rDevice, nOutputWidth, nOutputHeight,
3934
0
                                         nTilePosX, nTilePosY, nTileWidth, nTileHeight);
3935
0
    LokStarMathHelper::PaintAllInPlaceOnTile(rDevice, nOutputWidth, nOutputHeight, nTilePosX,
3936
0
                                             nTilePosY, nTileWidth, nTileHeight);
3937
3938
0
    if(patchedPageWindow != nullptr)
3939
0
        patchedPageWindow->unpatchPaintWindow(previousPaintWindow);
3940
3941
    // Draw Form controls
3942
0
    SdrView* pDrawView = pViewSh->GetDrawView();
3943
0
    SdrPageView* pPageView = pDrawView->GetSdrPageView();
3944
0
    if (pPageView != nullptr)
3945
0
    {
3946
0
        SdrPage* pPage = pPageView->GetPage();
3947
0
        ::sd::Window* pActiveWin = pViewSh->GetActiveWindow();
3948
0
        ::tools::Rectangle aTileRect(Point(nTilePosX, nTilePosY), Size(nTileWidth, nTileHeight));
3949
0
        Size aOutputSize(nOutputWidth, nOutputHeight);
3950
0
        LokControlHandler::paintControlTile(pPage, pDrawView, *pActiveWin, rDevice, aOutputSize, aTileRect);
3951
0
    }
3952
3953
0
    comphelper::LibreOfficeKit::setTiledPainting(false);
3954
0
}
3955
3956
OString SdXImpressDocument::getViewRenderState(SfxViewShell* pViewShell)
3957
0
{
3958
0
    OStringBuffer aState;
3959
0
    DrawViewShell* pView = nullptr;
3960
3961
0
    if (ViewShellBase* pShellBase = dynamic_cast<ViewShellBase*>(pViewShell))
3962
0
        pView = dynamic_cast<DrawViewShell*>(pShellBase->GetMainViewShell().get());
3963
0
    else
3964
0
        pView = GetViewShell();
3965
3966
0
    if (pView)
3967
0
    {
3968
0
        const SdViewOptions& pVOpt = pView->GetViewOptions();
3969
0
        if (mpDoc && mpDoc->GetOnlineSpell())
3970
0
            aState.append('S');
3971
0
        if (!ThemeColors::UseOnlyWhiteDocBackground())
3972
0
        {
3973
0
            if (pVOpt.mnDocBackgroundColor
3974
0
                == svtools::ColorConfig::GetDefaultColor(svtools::DOCCOLOR))
3975
0
                aState.append('D');
3976
0
        }
3977
0
        aState.append(';');
3978
3979
0
        OString aThemeName = OUStringToOString(pVOpt.msColorSchemeName, RTL_TEXTENCODING_UTF8);
3980
0
        aState.append(aThemeName);
3981
0
    }
3982
0
    return aState.makeStringAndClear();
3983
0
}
3984
3985
void SdXImpressDocument::selectPart(int nPart, int nSelect)
3986
0
{
3987
0
    DrawViewShell* pViewSh = GetViewShell();
3988
0
    if (!pViewSh)
3989
0
        return;
3990
3991
0
    pViewSh->SelectPage(nPart, nSelect);
3992
0
}
3993
3994
void SdXImpressDocument::moveSelectedParts(int nPosition, bool bDuplicate)
3995
0
{
3996
    // Duplicating is currently unsupported.
3997
0
    if (bDuplicate)
3998
0
        return;
3999
4000
0
    DrawViewShell* pViewSh = GetViewShell();
4001
0
    if (!pViewSh)
4002
0
        return;
4003
4004
0
    auto pSlideSorter
4005
0
        = sd::slidesorter::SlideSorterViewShell::GetSlideSorter(pViewSh->GetViewShellBase());
4006
0
    sd::slidesorter::SharedPageSelection pSelectedPage
4007
0
        = pSlideSorter ? pSlideSorter->GetPageSelection() : nullptr;
4008
0
    if (!pSelectedPage)
4009
0
        return;
4010
0
    mpDoc->MovePages(nPosition, *pSelectedPage);
4011
0
}
4012
4013
OUString SdXImpressDocument::getPartInfo(int nPart)
4014
0
{
4015
0
    DrawViewShell* pViewSh = GetViewShell();
4016
0
    if (!pViewSh)
4017
0
        return OUString();
4018
4019
0
    SdPage* pSdPage = mpDoc->GetSdPage(nPart, pViewSh->GetPageKind());
4020
0
    const sal_Int16 nMasterPageCount= pViewSh->GetDoc()->GetMasterSdPageCount(pViewSh->GetPageKind());
4021
4022
0
    ::tools::JsonWriter jsonWriter;
4023
4024
0
    jsonWriter.put("masterPageCount", nMasterPageCount);
4025
0
    jsonWriter.put("mode", getEditMode());
4026
0
    jsonWriter.put("gridSnapEnabled", pViewSh->GetDrawView()->IsGridSnap());
4027
0
    jsonWriter.put("gridVisible", pViewSh->GetDrawView()->IsGridVisible());
4028
4029
    // Below information is useful when grid snapping is enabled. It let's to calculate the points we can snap to.
4030
0
    const Size gridCoarse = pViewSh->GetDrawView()->GetGridCoarse();
4031
0
    const Size innerDots = pViewSh->GetDrawView()->GetGridFine();
4032
0
    jsonWriter.put("gridCoarseWidth", gridCoarse.getWidth());
4033
0
    jsonWriter.put("gridCoarseHeight", gridCoarse.getHeight());
4034
0
    jsonWriter.put("innerSpacesX", innerDots.getWidth() ? gridCoarse.getWidth() / innerDots.getWidth() : 0);
4035
0
    jsonWriter.put("innerSpacesY", innerDots.getHeight() ? gridCoarse.getHeight() / innerDots.getHeight() : 0);
4036
4037
0
    if (pSdPage)
4038
0
        pSdPage->GetPageInfo(jsonWriter);
4039
0
    else
4040
0
        SAL_WARN("sd", "getPartInfo request for SdPage " << nPart << " that does not exist!");
4041
4042
0
    return OStringToOUString(jsonWriter.finishAndGetAsOString(), RTL_TEXTENCODING_UTF8);
4043
0
}
4044
4045
void SdXImpressDocument::setPart( int nPart, bool bAllowChangeFocus )
4046
0
{
4047
0
    DrawViewShell* pViewSh = GetViewShell();
4048
0
    if (!pViewSh)
4049
0
        return;
4050
4051
0
    pViewSh->SwitchPage( nPart, bAllowChangeFocus );
4052
0
}
4053
4054
int SdXImpressDocument::getParts()
4055
0
{
4056
0
    if (!mpDoc)
4057
0
        return 0;
4058
4059
0
    if (isMasterViewMode())
4060
0
        return mpDoc->GetMasterSdPageCount(PageKind::Standard);
4061
4062
0
    return mpDoc->GetSdPageCount(PageKind::Standard);
4063
0
}
4064
4065
int SdXImpressDocument::getPart()
4066
0
{
4067
0
    DrawViewShell* pViewSh = GetViewShell();
4068
0
    if (!pViewSh)
4069
0
        return 0;
4070
4071
0
    return pViewSh->GetViewShellBase().getPart();
4072
0
}
4073
4074
OUString SdXImpressDocument::getPartName(int nPart)
4075
0
{
4076
0
    SdPage* pPage;
4077
0
    if (isMasterViewMode())
4078
0
        pPage = mpDoc->GetMasterSdPage(nPart, PageKind::Standard);
4079
0
    else
4080
0
        pPage = mpDoc->GetSdPage(nPart, PageKind::Standard);
4081
4082
0
    if (!pPage)
4083
0
    {
4084
0
        SAL_WARN("sd", "DrawViewShell not available!");
4085
0
        return OUString();
4086
0
    }
4087
4088
0
    return pPage->GetName();
4089
0
}
4090
4091
OUString SdXImpressDocument::getPartHash(int nPart)
4092
0
{
4093
0
    SdPage* pPage;
4094
0
    if (isMasterViewMode())
4095
0
        pPage = mpDoc->GetMasterSdPage(nPart, PageKind::Standard);
4096
0
    else
4097
0
        pPage = mpDoc->GetSdPage(nPart, PageKind::Standard);
4098
4099
0
    if (!pPage)
4100
0
    {
4101
0
        SAL_WARN("sd", "DrawViewShell not available!");
4102
0
        return OUString();
4103
0
    }
4104
4105
0
    uno::Reference<drawing::XDrawPage> xDrawPage(pPage->getUnoPage(), uno::UNO_QUERY);
4106
0
    return OUString::fromUtf8(GetInterfaceHash(xDrawPage));
4107
0
}
4108
4109
bool SdXImpressDocument::isMasterViewMode()
4110
0
{
4111
0
    DrawViewShell* pViewSh = GetViewShell();
4112
0
    if (!pViewSh)
4113
0
        return false;
4114
4115
0
    if (pViewSh->GetDispatcher())
4116
0
    {
4117
0
        SfxPoolItemHolder aResult;
4118
0
        pViewSh->GetDispatcher()->QueryState(SID_SLIDE_MASTER_MODE, aResult);
4119
0
        const SfxBoolItem* isMasterViewMode(static_cast<const SfxBoolItem*>(aResult.getItem()));
4120
0
        if (isMasterViewMode && isMasterViewMode->GetValue())
4121
0
            return true;
4122
0
    }
4123
0
    return false;
4124
0
}
4125
4126
VclPtr<vcl::Window> SdXImpressDocument::getDocWindow()
4127
0
{
4128
0
    SolarMutexGuard aGuard;
4129
0
    DrawViewShell* pViewShell = GetViewShell();
4130
0
    if (!pViewShell)
4131
0
        return {};
4132
4133
0
    if (VclPtr<vcl::Window> pWindow = SfxLokHelper::getInPlaceDocWindow(pViewShell->GetViewShell()))
4134
0
        return pWindow;
4135
4136
0
    return pViewShell->GetActiveWindow();
4137
0
}
4138
4139
void SdXImpressDocument::setPartMode( int nPartMode )
4140
0
{
4141
0
    DrawViewShell* pViewSh = GetViewShell();
4142
0
    if (!pViewSh)
4143
0
        return;
4144
4145
0
    PageKind aPageKind( PageKind::Standard );
4146
0
    switch ( nPartMode )
4147
0
    {
4148
0
    case LOK_PARTMODE_SLIDES:
4149
0
        break;
4150
0
    case LOK_PARTMODE_NOTES:
4151
0
        aPageKind = PageKind::Notes;
4152
0
        break;
4153
0
    }
4154
0
    pViewSh->SetPageKind( aPageKind );
4155
    //TODO do the same as setEditMode and then can probably remove the TODOs
4156
    //from doc_setPartMode
4157
0
}
4158
4159
int SdXImpressDocument::getEditMode()
4160
0
{
4161
0
    DrawViewShell* pViewSh = GetViewShell();
4162
0
    if (!pViewSh)
4163
0
        return 0;
4164
4165
0
    return pViewSh->GetViewShellBase().getEditMode();
4166
0
}
4167
4168
void SdXImpressDocument::setEditMode(int nMode)
4169
0
{
4170
0
    SolarMutexGuard aGuard;
4171
4172
0
    DrawViewShell* pViewSh = GetViewShell();
4173
0
    if (!pViewSh)
4174
0
        return;
4175
4176
0
    pViewSh->GetViewShellBase().setEditMode(nMode);
4177
0
}
4178
4179
Size SdXImpressDocument::getDocumentSize()
4180
0
{
4181
0
    DrawViewShell* pViewSh = GetViewShell();
4182
0
    if (!pViewSh)
4183
0
        return Size();
4184
4185
0
    SdrView *pSdrView = pViewSh->GetView();
4186
0
    if (!pSdrView)
4187
0
        return Size();
4188
4189
0
    SdrPageView* pCurPageView = pSdrView->GetSdrPageView();
4190
0
    if (!pCurPageView)
4191
0
        return Size();
4192
4193
0
    Size aSize = pCurPageView->GetPageRect().GetSize();
4194
    // Convert the size in 100th mm to TWIP
4195
    // See paintTile above for further info.
4196
0
    return o3tl::convert(aSize, o3tl::Length::mm100, o3tl::Length::twip);
4197
0
}
4198
4199
Size SdXImpressDocument::getPartSize(int part)
4200
0
{
4201
0
    if (part < 0 || part > 0xFFFF)
4202
0
        return Size(0,0);
4203
4204
0
    const sal_uInt16 nSlideIndex = static_cast<sal_uInt16>(part);
4205
0
    SdPage* pPage = nullptr;
4206
0
    if (mpDoc)
4207
0
    {
4208
0
        if (isMasterViewMode())
4209
0
            pPage = mpDoc->GetMasterSdPage(nSlideIndex, PageKind::Standard);
4210
0
        else
4211
0
        {
4212
0
            DrawViewShell* pViewSh = GetViewShell();
4213
0
            PageKind ePageKind = pViewSh ? pViewSh->GetPageKind() : PageKind::Standard;
4214
0
            pPage = mpDoc->GetSdPage(nSlideIndex, ePageKind);
4215
0
        }
4216
0
    }
4217
4218
0
    if (pPage == nullptr)
4219
0
        return Size(0,0);
4220
4221
0
    Size aRectSize(pPage->GetWidth() + 1, pPage->GetHeight() + 1);
4222
0
    return o3tl::convert(aRectSize, o3tl::Length::mm100, o3tl::Length::twip);
4223
0
}
4224
4225
void SdXImpressDocument::getAllPartSize(::tools::JsonWriter& rJsonWriter)
4226
0
{
4227
0
    auto aArray = rJsonWriter.startArray("parts");
4228
0
    const int nParts = getParts();
4229
0
    for (int i = 0; i < nParts; ++i)
4230
0
    {
4231
0
        const Size aSize = getPartSize(i);
4232
0
        auto aItem = rJsonWriter.startStruct();
4233
0
        rJsonWriter.put("width", aSize.getWidth());
4234
0
        rJsonWriter.put("height", aSize.getHeight());
4235
0
    }
4236
0
}
4237
4238
void SdXImpressDocument::getPostIts(::tools::JsonWriter& rJsonWriter)
4239
0
{
4240
0
    auto commentsNode = rJsonWriter.startNode("comments");
4241
0
    if (!mpDoc)
4242
0
        return;
4243
    // Return annotations on master pages too ?
4244
0
    const sal_uInt16 nMaxPages = mpDoc->GetPageCount();
4245
0
    for (sal_uInt16 nPage = 0; nPage < nMaxPages; ++nPage)
4246
0
    {
4247
0
        SdrPage* pPage = mpDoc->GetPage(nPage);
4248
4249
0
        for (auto const& xAnnotation : pPage->getAnnotations())
4250
0
        {
4251
0
            sal_uInt32 nID = xAnnotation->GetId();
4252
0
            OString nodeName = "comment" + OString::number(nID);
4253
0
            auto commentNode = rJsonWriter.startNode(nodeName);
4254
0
            rJsonWriter.put("id", nID);
4255
0
            rJsonWriter.put("author", xAnnotation->getAuthor());
4256
0
            rJsonWriter.put("dateTime", utl::toISO8601(xAnnotation->getDateTime()));
4257
0
            uno::Reference<text::XText> xText(xAnnotation->getTextRange());
4258
0
            rJsonWriter.put("text", xText->getString());
4259
0
            rJsonWriter.put("parthash", pPage->GetUniqueID());
4260
0
            geometry::RealPoint2D const aPoint = xAnnotation->getPosition();
4261
0
            geometry::RealSize2D const aSize = xAnnotation->getSize();
4262
0
            ::tools::Rectangle aRectangle(Point(aPoint.X * 100.0, aPoint.Y * 100.0), Size(aSize.Width * 100.0, aSize.Height * 100.0));
4263
0
            aRectangle = o3tl::toTwips(aRectangle, o3tl::Length::mm100);
4264
0
            OString sRectangle = aRectangle.toString();
4265
0
            rJsonWriter.put("rectangle", sRectangle.getStr());
4266
0
            if (xAnnotation->IsThreaded())
4267
0
            {
4268
0
                rJsonWriter.put("threaded", "true");
4269
0
                rJsonWriter.put("resolved", xAnnotation->IsResolved() ? "true" : "false");
4270
0
                rJsonWriter.put("parentId", xAnnotation->GetParentId());
4271
0
            }
4272
0
        }
4273
0
    }
4274
0
}
4275
4276
void SdXImpressDocument::initializeForTiledRendering(const css::uno::Sequence<css::beans::PropertyValue>& rArguments)
4277
0
{
4278
0
    SolarMutexGuard aGuard;
4279
4280
0
    OUString sThemeName;
4281
0
    OUString sBackgroundThemeName;
4282
4283
0
    if (DrawViewShell* pViewShell = GetViewShell())
4284
0
    {
4285
0
        DrawView* pDrawView = pViewShell->GetDrawView();
4286
0
        for (const beans::PropertyValue& rValue : rArguments)
4287
0
        {
4288
0
            if (rValue.Name == ".uno:ShowBorderShadow" && rValue.Value.has<bool>())
4289
0
                pDrawView->SetPageShadowVisible(rValue.Value.get<bool>());
4290
0
            else if (rValue.Name == ".uno:Author" && rValue.Value.has<OUString>())
4291
0
                pDrawView->SetAuthor(rValue.Value.get<OUString>());
4292
0
            else if (rValue.Name == ".uno:SpellOnline" && rValue.Value.has<bool>())
4293
0
                mpDoc->SetOnlineSpell(rValue.Value.get<bool>());
4294
0
            else if (rValue.Name == ".uno:ChangeTheme" && rValue.Value.has<OUString>())
4295
0
                sThemeName = rValue.Value.get<OUString>();
4296
0
            else if (rValue.Name == ".uno:InvertBackground" && rValue.Value.has<OUString>())
4297
0
                sBackgroundThemeName = rValue.Value.get<OUString>();
4298
0
        }
4299
4300
        // Disable comments if requested
4301
0
        SdOptions* pOptions = SdModule::get()->GetSdOptions(mpDoc->GetDocumentType());
4302
0
        pOptions->SetShowComments(comphelper::LibreOfficeKit::isTiledAnnotations());
4303
4304
0
        pViewShell->SetRuler(false);
4305
0
        pViewShell->SetScrollBarsVisible(false);
4306
4307
0
        if (sd::Window* pWindow = pViewShell->GetActiveWindow())
4308
0
        {
4309
            // get the full page size in pixels
4310
0
            pWindow->EnableMapMode();
4311
0
            Size aSize(pWindow->LogicToPixel(pDrawView->GetSdrPageView()->GetPage()->GetSize()));
4312
            // Disable map mode, so that it's possible to send mouse event
4313
            // coordinates in logic units
4314
0
            pWindow->EnableMapMode(false);
4315
4316
            // arrange UI elements again with new view size
4317
0
            pViewShell->GetParentWindow()->SetSizePixel(aSize);
4318
0
            pViewShell->Resize();
4319
0
        }
4320
4321
        // Forces all images to be swapped in synchronously, this
4322
        // ensures that images are available when paintTile is called
4323
        // (whereas with async loading images start being loaded after
4324
        //  we have painted the tile, resulting in an invalidate, followed
4325
        //  by the tile being rerendered - which is wasteful and ugly).
4326
0
        pDrawView->SetSwapAsynchron(false);
4327
0
    }
4328
4329
    // when the "This document may contain formatting or content that cannot
4330
    // be saved..." dialog appears, it is auto-cancelled with tiled rendering,
4331
    // causing 'Save' being disabled; so let's always save to the original
4332
    // format
4333
0
    auto xChanges = comphelper::ConfigurationChanges::create();
4334
0
    officecfg::Office::Common::Save::Document::WarnAlienFormat::set(false, xChanges);
4335
4336
0
    if (!o3tl::IsRunningUnitTest() || !comphelper::LibreOfficeKit::isActive())
4337
0
        officecfg::Office::Impress::MultiPaneGUI::SlideSorterBar::Visible::ImpressView::set(true,xChanges);
4338
0
    xChanges->commit();
4339
4340
    // if we know what theme the user wants, then we can dispatch that now early
4341
0
    if (!sThemeName.isEmpty())
4342
0
    {
4343
0
        css::uno::Sequence<css::beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence(
4344
0
        {
4345
0
            { "NewTheme", uno::Any(sThemeName) }
4346
0
        }));
4347
0
        comphelper::dispatchCommand(u".uno:ChangeTheme"_ustr, aPropertyValues);
4348
0
    }
4349
0
    if (!sBackgroundThemeName.isEmpty())
4350
0
    {
4351
0
        css::uno::Sequence<css::beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence(
4352
0
        {
4353
0
            { "NewTheme", uno::Any(sBackgroundThemeName) }
4354
0
        }));
4355
0
        comphelper::dispatchCommand(".uno:InvertBackground", aPropertyValues);
4356
0
    }
4357
0
}
4358
4359
void SdXImpressDocument::postKeyEvent(int nType, int nCharCode, int nKeyCode)
4360
0
{
4361
0
    SolarMutexGuard aGuard;
4362
0
    SfxLokHelper::postKeyEventAsync(getDocWindow(), nType, nCharCode, nKeyCode);
4363
0
}
4364
4365
void SdXImpressDocument::postMouseEvent(int nType, int nX, int nY, int nCount, int nButtons, int nModifier)
4366
0
{
4367
0
    SolarMutexGuard aGuard;
4368
4369
0
    DrawViewShell* pViewShell = GetViewShell();
4370
0
    if (!pViewShell)
4371
0
        return;
4372
4373
0
    constexpr double fScale = o3tl::convert(1.0, o3tl::Length::twip, o3tl::Length::px);
4374
4375
0
    if (SfxLokHelper::testInPlaceComponentMouseEventHit(
4376
0
            pViewShell->GetViewShell(), nType, nX, nY, nCount, nButtons, nModifier, fScale, fScale))
4377
0
        return;
4378
4379
    // try to forward mouse event to control
4380
0
    const Point aPointTwip(nX, nY);
4381
0
    const Point aPointHMM = o3tl::convert(aPointTwip, o3tl::Length::twip, o3tl::Length::mm100);
4382
0
    SdrView* pDrawView = pViewShell->GetDrawView();
4383
0
    SdrPageView* pPageView = pDrawView->GetSdrPageView();
4384
0
    if (!pPageView)
4385
0
    {
4386
0
        return;
4387
0
    }
4388
4389
0
    SdrPage* pPage = pPageView->GetPage();
4390
0
    ::sd::Window* pActiveWin = pViewShell->GetActiveWindow();
4391
0
    if (!pActiveWin)
4392
0
    {
4393
0
        return;
4394
0
    }
4395
4396
0
    if (LokControlHandler::postMouseEvent(pPage, pDrawView, *pActiveWin, nType, aPointHMM, nCount, nButtons, nModifier))
4397
0
            return;
4398
4399
0
    LokMouseEventData aMouseEventData(nType, aPointHMM, nCount, MouseEventModifiers::SIMPLECLICK,
4400
0
                                      nButtons, nModifier);
4401
0
    SfxLokHelper::postMouseEventAsync(pViewShell->GetActiveWindow(), aMouseEventData);
4402
0
}
4403
4404
void SdXImpressDocument::setTextSelection(int nType, int nX, int nY)
4405
0
{
4406
0
    SolarMutexGuard aGuard;
4407
4408
0
    DrawViewShell* pViewShell = GetViewShell();
4409
0
    if (!pViewShell)
4410
0
        return;
4411
4412
0
    LokChartHelper aChartHelper(pViewShell->GetViewShell());
4413
0
    if (aChartHelper.setTextSelection(nType, nX, nY))
4414
0
        return;
4415
4416
0
    Point aPoint(convertTwipToMm100(nX), convertTwipToMm100(nY));
4417
0
    switch (nType)
4418
0
    {
4419
0
    case LOK_SETTEXTSELECTION_START:
4420
0
        pViewShell->SetCursorMm100Position(aPoint, /*bPoint=*/false, /*bClearMark=*/false);
4421
0
        break;
4422
0
    case LOK_SETTEXTSELECTION_END:
4423
0
        pViewShell->SetCursorMm100Position(aPoint, /*bPoint=*/true, /*bClearMark=*/false);
4424
0
        break;
4425
0
    case LOK_SETTEXTSELECTION_RESET:
4426
0
        pViewShell->SetCursorMm100Position(aPoint, /*bPoint=*/true, /*bClearMark=*/true);
4427
0
        break;
4428
0
    default:
4429
0
        assert(false);
4430
0
        break;
4431
0
    }
4432
0
}
4433
4434
uno::Reference<datatransfer::XTransferable> SdXImpressDocument::getSelection()
4435
0
{
4436
0
    SolarMutexGuard aGuard;
4437
4438
0
    DrawViewShell* pViewShell = GetViewShell();
4439
0
    if (!pViewShell)
4440
0
        return uno::Reference<datatransfer::XTransferable>();
4441
4442
0
    return pViewShell->GetSelectionTransferable();
4443
0
}
4444
4445
void SdXImpressDocument::setGraphicSelection(int nType, int nX, int nY)
4446
0
{
4447
0
    SolarMutexGuard aGuard;
4448
4449
0
    DrawViewShell* pViewShell = GetViewShell();
4450
0
    if (!pViewShell)
4451
0
        return;
4452
4453
0
    constexpr double fScale = o3tl::convert(1.0, o3tl::Length::twip, o3tl::Length::px);
4454
4455
0
    LokChartHelper aChartHelper(pViewShell->GetViewShell());
4456
0
    if (aChartHelper.setGraphicSelection(nType, nX, nY, fScale, fScale))
4457
0
        return;
4458
4459
0
    Point aPoint(convertTwipToMm100(nX), convertTwipToMm100(nY));
4460
0
    switch (nType)
4461
0
    {
4462
0
    case LOK_SETGRAPHICSELECTION_START:
4463
0
        pViewShell->SetGraphicMm100Position(/*bStart=*/true, aPoint);
4464
0
        break;
4465
0
    case LOK_SETGRAPHICSELECTION_END:
4466
0
        pViewShell->SetGraphicMm100Position(/*bStart=*/false, aPoint);
4467
0
        break;
4468
0
    default:
4469
0
        assert(false);
4470
0
        break;
4471
0
    }
4472
0
}
4473
4474
void SdXImpressDocument::resetSelection()
4475
0
{
4476
0
    SolarMutexGuard aGuard;
4477
4478
0
    DrawViewShell* pViewShell = GetViewShell();
4479
0
    if (!pViewShell)
4480
0
        return;
4481
4482
0
    SdrView* pSdrView = pViewShell->GetView();
4483
0
    if (!pSdrView)
4484
0
        return;
4485
4486
0
    if (pSdrView->IsTextEdit())
4487
0
    {
4488
        // Reset the editeng selection.
4489
0
        pSdrView->UnmarkAll();
4490
        // Finish editing.
4491
0
        pSdrView->SdrEndTextEdit();
4492
0
    }
4493
    // Reset graphic selection.
4494
0
    pSdrView->UnmarkAll();
4495
0
}
4496
4497
void SdXImpressDocument::setPageZoom(int nPageZoom)
4498
0
{
4499
0
    SolarMutexGuard aGuard;
4500
0
    DrawViewShell* pViewShell = GetViewShell();
4501
0
    if (!pViewShell)
4502
0
        return;
4503
0
    pViewShell->RememberPageZoom(nPageZoom);
4504
0
}
4505
4506
void SdXImpressDocument::setClientVisibleArea(const ::tools::Rectangle& rRectangle)
4507
0
{
4508
0
    SolarMutexGuard aGuard;
4509
4510
0
    DrawViewShell* pViewShell = GetViewShell();
4511
0
    if (!pViewShell)
4512
0
        return;
4513
4514
0
    pViewShell->GetViewShellBase().setLOKVisibleArea(rRectangle);
4515
4516
0
    if (pViewShell->getCurrentPage()->IsCanvasPage())
4517
0
        pViewShell->RememberCanvasPageVisArea(rRectangle);
4518
0
}
4519
4520
void SdXImpressDocument::setClipboard(const uno::Reference<datatransfer::clipboard::XClipboard>& xClipboard)
4521
0
{
4522
0
    SolarMutexGuard aGuard;
4523
4524
0
    DrawViewShell* pViewShell = GetViewShell();
4525
0
    if (!pViewShell)
4526
0
        return;
4527
4528
0
    pViewShell->GetActiveWindow()->SetClipboard(xClipboard);
4529
0
}
4530
4531
bool SdXImpressDocument::isMimeTypeSupported()
4532
0
{
4533
0
    SolarMutexGuard aGuard;
4534
0
    DrawViewShell* pViewShell = GetViewShell();
4535
0
    if (!pViewShell)
4536
0
        return false;
4537
4538
0
    TransferableDataHelper aDataHelper(TransferableDataHelper::CreateFromSystemClipboard(pViewShell->GetActiveWindow()));
4539
0
    return EditEngine::HasValidData(aDataHelper.GetTransferable());
4540
0
}
4541
4542
PointerStyle SdXImpressDocument::getPointer()
4543
0
{
4544
0
    SolarMutexGuard aGuard;
4545
0
    DrawViewShell* pViewShell = GetViewShell();
4546
0
    if (!pViewShell)
4547
0
        return PointerStyle::Arrow;
4548
4549
0
    Window* pWindow = pViewShell->GetActiveWindow();
4550
0
    if (!pWindow)
4551
0
        return PointerStyle::Arrow;
4552
4553
0
    return pWindow->GetPointer();
4554
0
}
4555
4556
uno::Reference< i18n::XForbiddenCharacters > SdXImpressDocument::getForbiddenCharsTable()
4557
166
{
4558
166
    rtl::Reference<SdUnoForbiddenCharsTable> xRef = mxForbiddenCharacters.get();
4559
166
    if( !xRef )
4560
166
    {
4561
166
        xRef = new SdUnoForbiddenCharsTable( mpDoc );
4562
166
        mxForbiddenCharacters = xRef.get();
4563
166
    }
4564
166
    return xRef;
4565
166
}
4566
4567
void SdXImpressDocument::initializeDocument()
4568
5.78k
{
4569
5.78k
    if( mbClipBoard )
4570
0
        return;
4571
4572
5.78k
    switch( mpDoc->GetPageCount() )
4573
5.78k
    {
4574
0
    case 1:
4575
0
    {
4576
        // nasty hack to detect clipboard document
4577
0
        mbClipBoard = true;
4578
0
        break;
4579
0
    }
4580
2.57k
    case 0:
4581
2.57k
    {
4582
2.57k
        mpDoc->CreateFirstPages();
4583
2.57k
        mpDoc->StopWorkStartupDelay();
4584
2.57k
        break;
4585
0
    }
4586
5.78k
    }
4587
5.78k
}
4588
4589
static
4590
void getShapeClickAction(const uno::Reference<drawing::XShape> &xShape, ::tools::JsonWriter& rJsonWriter)
4591
0
{
4592
0
    bool bIsShapeVisible = true;
4593
0
    uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY);
4594
0
    if (!xShapeProps)
4595
0
        return;
4596
4597
0
    if (!xShapeProps->getPropertySetInfo()->hasPropertyByName( u"Visible"_ustr ))
4598
0
        return;
4599
0
    xShapeProps->getPropertyValue("Visible") >>= bIsShapeVisible;
4600
4601
0
    if (!bIsShapeVisible)
4602
0
        return;
4603
4604
0
    if (!xShapeProps->getPropertySetInfo()->hasPropertyByName( u"OnClick"_ustr ))
4605
0
        return;
4606
4607
0
    presentation::ClickAction eClickAction = presentation::ClickAction_NONE;
4608
0
    xShapeProps->getPropertyValue(u"OnClick"_ustr) >>= eClickAction;
4609
4610
0
    if (eClickAction != presentation::ClickAction_NONE)
4611
0
    {
4612
0
        auto aShape = rJsonWriter.startStruct();
4613
4614
0
        sal_Int32 nVerb = 0;
4615
0
        OUString sBookmark;
4616
4617
0
        if (xShapeProps->getPropertySetInfo()->hasPropertyByName( u"Bookmark"_ustr ))
4618
0
            xShapeProps->getPropertyValue(u"Bookmark"_ustr) >>= sBookmark;
4619
4620
0
        {
4621
0
            auto* pObject = SdrObject::getSdrObjectFromXShape(xShape);
4622
0
            auto const& rRectangle = pObject->GetLogicRect();
4623
0
            auto aRectangle = o3tl::convert(rRectangle, o3tl::Length::mm100, o3tl::Length::twip);
4624
0
            auto aRect = rJsonWriter.startNode("bounds");
4625
0
            rJsonWriter.put("x", aRectangle.Left());
4626
0
            rJsonWriter.put("y", aRectangle.Top());
4627
0
            rJsonWriter.put("width", aRectangle.GetWidth());
4628
0
            rJsonWriter.put("height", aRectangle.GetHeight());
4629
0
        }
4630
4631
0
        {
4632
0
            auto aInteraction = rJsonWriter.startNode("clickAction");
4633
0
            switch (eClickAction)
4634
0
            {
4635
0
            case presentation::ClickAction_BOOKMARK:
4636
0
                rJsonWriter.put("action", "bookmark");
4637
0
                rJsonWriter.put("bookmark", sBookmark);
4638
0
                break;
4639
0
            case presentation::ClickAction_DOCUMENT:
4640
0
                rJsonWriter.put("action", "document");
4641
0
                rJsonWriter.put("document", sBookmark);
4642
0
                break;
4643
4644
0
            case presentation::ClickAction_PREVPAGE:
4645
0
                rJsonWriter.put("action", "prevpage");
4646
0
                break;
4647
0
            case presentation::ClickAction_NEXTPAGE:
4648
0
                rJsonWriter.put("action", "nextpage");
4649
0
                break;
4650
4651
0
            case presentation::ClickAction_FIRSTPAGE:
4652
0
                rJsonWriter.put("action", "firstpage");
4653
0
                break;
4654
0
            case presentation::ClickAction_LASTPAGE:
4655
0
                rJsonWriter.put("action", "lastpage");
4656
0
                break;
4657
4658
0
            case presentation::ClickAction_SOUND:
4659
0
                rJsonWriter.put("action", "sound");
4660
0
                rJsonWriter.put("sound", sBookmark);
4661
0
                break;
4662
4663
0
            case presentation::ClickAction_VERB:
4664
0
                rJsonWriter.put("action", "verb");
4665
0
                xShapeProps->getPropertyValue(u"Verb"_ustr) >>= nVerb;
4666
0
                rJsonWriter.put("verb", nVerb);
4667
0
                break;
4668
4669
0
            case presentation::ClickAction_PROGRAM:
4670
0
                rJsonWriter.put("action", "program");
4671
0
                rJsonWriter.put("program", sBookmark);
4672
0
                break;
4673
4674
0
            case presentation::ClickAction_MACRO:
4675
0
                rJsonWriter.put("action", "macro");
4676
0
                rJsonWriter.put("macro", sBookmark);
4677
0
                break;
4678
4679
0
            case presentation::ClickAction_STOPPRESENTATION:
4680
0
                rJsonWriter.put("action", "stoppresentation");
4681
0
                break;
4682
4683
0
            default:
4684
0
                break;
4685
0
            }
4686
0
        }
4687
0
    }
4688
0
}
4689
4690
OString SdXImpressDocument::getPresentationInfo(bool bAllyState) const
4691
0
{
4692
0
    ::tools::JsonWriter aJsonWriter;
4693
4694
0
    try
4695
0
    {
4696
0
        rtl::Reference<SdDrawPagesAccess> xDrawPages = const_cast<SdXImpressDocument*>(this)->getSdDrawPages();
4697
        // size in twips
4698
0
        Size aDocSize = const_cast<SdXImpressDocument*>(this)->getDocumentSize();
4699
0
        aJsonWriter.put("docWidth", aDocSize.getWidth());
4700
0
        aJsonWriter.put("docHeight", aDocSize.getHeight());
4701
4702
0
        sd::PresentationSettings const& rSettings = mpDoc->getPresentationSettings();
4703
4704
0
        const bool bIsEndless = rSettings.mbEndless;
4705
0
        aJsonWriter.put("isEndless", bIsEndless);
4706
4707
0
        if (bIsEndless) {
4708
0
            const sal_Int32 nPauseTimeout = rSettings.mnPauseTimeout;
4709
0
            aJsonWriter.put("loopAndRepeatDuration", nPauseTimeout);
4710
0
        }
4711
4712
        // Section data for COOL slide panel
4713
0
        {
4714
0
            sd::SlideSectionManager& rSectionMgr = mpDoc->GetSectionManager();
4715
0
            sal_Int32 nSectionCount = rSectionMgr.GetSectionCount();
4716
0
            if (nSectionCount > 0)
4717
0
            {
4718
0
                sal_uInt16 nPageCount = mpDoc->GetSdPageCount(PageKind::Standard);
4719
0
                auto aSectionsArray = aJsonWriter.startArray("sections");
4720
0
                for (sal_Int32 i = 0; i < nSectionCount; ++i)
4721
0
                {
4722
0
                    const sd::SlideSection& rSection = rSectionMgr.GetSection(i);
4723
0
                    sal_Int32 nSectionSlideCount
4724
0
                        = (i + 1 < nSectionCount)
4725
0
                              ? rSectionMgr.GetSection(i + 1).mnStartIndex - rSection.mnStartIndex
4726
0
                              : nPageCount - rSection.mnStartIndex;
4727
4728
0
                    auto aSectionNode = aJsonWriter.startStruct();
4729
0
                    aJsonWriter.put("name", rSection.maName);
4730
0
                    if (!rSection.maId.isEmpty())
4731
0
                        aJsonWriter.put("id", rSection.maId);
4732
0
                    aJsonWriter.put("startIndex", rSection.mnStartIndex);
4733
0
                    aJsonWriter.put("slideCount", nSectionSlideCount);
4734
0
                }
4735
0
            }
4736
0
        }
4737
4738
0
        auto aSlideList = aJsonWriter.startArray("slides");
4739
0
        sal_Int32 nSlideCount = xDrawPages->getCount();
4740
0
        for (sal_Int32 i = 0; i < nSlideCount; ++i)
4741
0
        {
4742
0
            SdGenericDrawPage* pSlide(xDrawPages->getDrawPageByIndex(i));
4743
0
            SdPage* pPage = SdPage::getImplementation(pSlide);
4744
0
            if (!pPage)
4745
0
            {
4746
0
                SAL_WARN("sd", "slide: " << i << " is disposed, skipping");
4747
0
                continue;
4748
0
            }
4749
4750
0
            bool bIsVisible = true; // default visible
4751
0
            pSlide->getPropertyValue("Visible") >>= bIsVisible;
4752
4753
0
            if (!bIsVisible)
4754
0
            {
4755
0
                auto aSlideNode = aJsonWriter.startStruct();
4756
0
                std::string sSlideHash = GetInterfaceHash(cppu::getXWeak(pSlide));
4757
0
                aJsonWriter.put("hash", sSlideHash);
4758
0
                aJsonWriter.put("index", i);
4759
0
                aJsonWriter.put("hidden", true);
4760
0
                aJsonWriter.put("uniqueID", pPage->GetUniqueID());
4761
0
            }
4762
0
            else
4763
0
            {
4764
0
                auto aSlideNode = aJsonWriter.startStruct();
4765
0
                std::string sSlideHash = GetInterfaceHash(cppu::getXWeak(pSlide));
4766
0
                aJsonWriter.put("hash", sSlideHash);
4767
0
                aJsonWriter.put("index", i);
4768
0
                aJsonWriter.put("uniqueID", pPage->GetUniqueID());
4769
4770
0
                auto aName = SdDrawPage::getPageApiNameFromUiName(pPage->GetName());
4771
0
                aJsonWriter.put("name", aName);
4772
4773
0
                if (bAllyState)
4774
0
                {
4775
0
                    OUStringBuffer aHtml;
4776
0
                    SdrOutliner* pOutliner = mpDoc->GetInternalOutliner();
4777
0
                    if (pOutliner)
4778
0
                    {
4779
0
                        SdHTMLFilter::ExportPage(pOutliner, pPage, aHtml);
4780
0
                        aJsonWriter.put("a11y", aHtml.makeStringAndClear());
4781
0
                        pOutliner->Clear();
4782
0
                    }
4783
0
                }
4784
4785
0
                bool bIsDrawPageEmpty = pSlide->getCount() == 0;
4786
0
                aJsonWriter.put("empty", bIsDrawPageEmpty);
4787
4788
                // Notes
4789
0
                SdPage* pNotesPage = mpDoc->GetSdPage((pPage->GetPageNum() - 1) >> 1, PageKind::Notes);
4790
0
                if (pNotesPage)
4791
0
                {
4792
0
                    SdrObject* pItObj = nullptr;
4793
0
                    SdrObject* pNotes = pNotesPage->GetPresObj(PresObjKind::Notes);
4794
4795
0
                    if (!pNotes)
4796
0
                    {
4797
0
                        for (size_t nNote = 0; nNote < pNotesPage->GetObjCount(); nNote++)
4798
0
                        {
4799
0
                            pItObj = pNotesPage->GetObj(nNote);
4800
4801
0
                            if (pItObj && pItObj->HasText() &&
4802
0
                                (pItObj->GetObjIdentifier() == SdrObjKind::Text
4803
0
                                 || pItObj->GetObjIdentifier() == SdrObjKind::TitleText
4804
0
                                 || pItObj->GetObjIdentifier() == SdrObjKind::OutlineText))
4805
0
                            {
4806
0
                                pNotes = pItObj;
4807
0
                                break;
4808
0
                            }
4809
0
                        }
4810
0
                    }
4811
4812
0
                    if (pNotes)
4813
0
                    {
4814
0
                        OUStringBuffer strNotes;
4815
0
                        OutlinerParaObject* pPara = pNotes->GetOutlinerParaObject();
4816
0
                        if (pPara)
4817
0
                        {
4818
0
                            const EditTextObject& rText = pPara->GetTextObject();
4819
0
                            for (sal_Int32 nNote = 0; nNote < rText.GetParagraphCount(); nNote++)
4820
0
                            {
4821
0
                                strNotes.append(rText.GetText(nNote));
4822
0
                            }
4823
0
                            aJsonWriter.put("notes", strNotes.makeStringAndClear());
4824
0
                        }
4825
0
                    }
4826
0
                }
4827
4828
0
                SdMasterPage* pMasterPage = nullptr;
4829
0
                SdDrawPage* pMasterPageTarget(dynamic_cast<SdDrawPage*>(pSlide));
4830
0
                if (pMasterPageTarget)
4831
0
                {
4832
0
                    pMasterPage = pMasterPageTarget->getSdMasterPage();
4833
0
                    if (pMasterPage)
4834
0
                    {
4835
0
                        std::string sMPHash = GetInterfaceHash(cppu::getXWeak(pMasterPage));
4836
0
                        aJsonWriter.put("masterPage", sMPHash);
4837
4838
0
                        bool bBackgroundObjectsVisibility = true; // default visible
4839
0
                        pSlide->getPropertyValue("IsBackgroundObjectsVisible") >>= bBackgroundObjectsVisibility;
4840
0
                        aJsonWriter.put("masterPageObjectsVisibility", bBackgroundObjectsVisibility);
4841
0
                    }
4842
0
                }
4843
4844
0
                bool bBackgroundVisibility = true; // default visible
4845
0
                pSlide->getPropertyValue("IsBackgroundVisible")  >>= bBackgroundVisibility;
4846
0
                if (bBackgroundVisibility)
4847
0
                {
4848
0
                    SlideBackgroundInfo aSlideBackgroundInfo(pSlide, static_cast<SvxDrawPage*>(pMasterPage));
4849
0
                    if (aSlideBackgroundInfo.hasBackground())
4850
0
                    {
4851
0
                        auto aBackgroundNode = aJsonWriter.startNode("background");
4852
0
                        aJsonWriter.put("isCustom", aSlideBackgroundInfo.slideHasOwnBackground());
4853
0
                        if (aSlideBackgroundInfo.isSolidColor())
4854
0
                        {
4855
0
                            aJsonWriter.put("fillColor", aSlideBackgroundInfo.getFillColorAsRGBA());
4856
0
                        }
4857
0
                    }
4858
0
                }
4859
4860
0
                {
4861
0
                    auto aVideoList = aJsonWriter.startArray("videos");
4862
0
                    SdrObjListIter aIterator(pPage, SdrIterMode::DeepWithGroups);
4863
0
                    while (aIterator.IsMore())
4864
0
                    {
4865
0
                        auto* pObject = aIterator.Next();
4866
0
                        if (pObject->GetObjIdentifier() == SdrObjKind::Media)
4867
0
                        {
4868
0
                            auto aVideosNode = aJsonWriter.startStruct();
4869
0
                            auto* pMediaObject = static_cast<SdrMediaObj*>(pObject);
4870
0
                            auto const& rRectangle = pMediaObject->GetLogicRect();
4871
0
                            auto aRectangle = o3tl::convert(rRectangle, o3tl::Length::mm100, o3tl::Length::twip);
4872
0
                            aJsonWriter.put("id", reinterpret_cast<sal_uInt64>(pMediaObject));
4873
0
                            aJsonWriter.put("url", pMediaObject->getTempURL());
4874
0
                            aJsonWriter.put("x", aRectangle.Left());
4875
0
                            aJsonWriter.put("y", aRectangle.Top());
4876
0
                            aJsonWriter.put("width", aRectangle.GetWidth());
4877
0
                            aJsonWriter.put("height", aRectangle.GetHeight());
4878
0
                        }
4879
0
                    }
4880
0
                }
4881
4882
0
                uno::Reference<drawing::XShapes> const xShapes(cppu::getXWeak(pSlide), uno::UNO_QUERY_THROW);
4883
0
                if (xShapes.is())
4884
0
                {
4885
0
                    auto aInteractions = aJsonWriter.startArray("interactions");
4886
0
                    auto count = xShapes->getCount();
4887
0
                    for (auto j = 0; j < count; j++)
4888
0
                    {
4889
0
                        auto xObject = xShapes->getByIndex(j);
4890
0
                        uno::Reference<drawing::XShape> xShape(xObject, uno::UNO_QUERY);
4891
0
                        if (!xShape.is())
4892
0
                        {
4893
0
                            continue;
4894
0
                        }
4895
4896
0
                        getShapeClickAction(xShape, aJsonWriter);
4897
0
                    }
4898
0
                }
4899
4900
0
                sal_Int32 nTransitionType = 0;
4901
0
                pSlide->getPropertyValue("TransitionType") >>= nTransitionType;
4902
4903
0
                if (nTransitionType != 0)
4904
0
                {
4905
0
                    auto iterator = constTransitionTypeToString.find(nTransitionType);
4906
4907
0
                    if (iterator != constTransitionTypeToString.end())
4908
0
                    {
4909
0
                        aJsonWriter.put("transitionType", iterator->second);
4910
4911
0
                        sal_Int32 nTransitionSubtype = 0;
4912
0
                        pSlide->getPropertyValue("TransitionSubtype") >>= nTransitionSubtype;
4913
4914
0
                        auto iteratorSubType = constTransitionSubTypeToString.find(nTransitionSubtype);
4915
0
                        if (iteratorSubType != constTransitionSubTypeToString.end())
4916
0
                        {
4917
0
                            aJsonWriter.put("transitionSubtype", iteratorSubType->second);
4918
0
                        }
4919
0
                        else
4920
0
                        {
4921
0
                            SAL_WARN("sd", "Transition sub-type unknown: " << nTransitionSubtype);
4922
0
                        }
4923
4924
0
                        if (bAllyState)
4925
0
                        {
4926
0
                            const TransitionPresetList& rList = TransitionPreset::getTransitionPresetList();
4927
0
                            auto aTransition = std::find_if(rList.begin(), rList.end(),
4928
0
                                                            [nTransitionType,
4929
0
                                                             nTransitionSubtype](const TransitionPresetPtr& rxPreset) {
4930
0
                                                                return (rxPreset->getTransition() == nTransitionType)
4931
0
                                                                    && (rxPreset->getSubtype() == nTransitionSubtype);
4932
0
                                                            });
4933
4934
0
                            if (aTransition != rList.end())
4935
0
                            {
4936
0
                                aJsonWriter.put("transitionLabel", (*aTransition)->getSetLabel());
4937
0
                            }
4938
0
                        }
4939
4940
0
                        bool nTransitionDirection = false;
4941
0
                        pSlide->getPropertyValue("TransitionDirection") >>= nTransitionDirection;
4942
0
                        aJsonWriter.put("transitionDirection", nTransitionDirection);
4943
4944
                        // fade color
4945
0
                        if ((nTransitionType == TransitionType::FADE)
4946
0
                                && ((nTransitionSubtype == TransitionSubType::FADETOCOLOR)
4947
0
                                    || (nTransitionSubtype == TransitionSubType::FADEFROMCOLOR)
4948
0
                                    || (nTransitionSubtype == TransitionSubType::FADEOVERCOLOR)))
4949
0
                        {
4950
0
                            sal_Int32 nFadeColor = 0;
4951
0
                            pSlide->getPropertyValue("TransitionFadeColor") >>= nFadeColor;
4952
0
                            OUStringBuffer sTmpBuf;
4953
0
                            ::sax::Converter::convertColor(sTmpBuf, nFadeColor);
4954
0
                            aJsonWriter.put("transitionFadeColor", sTmpBuf.makeStringAndClear());
4955
0
                        }
4956
0
                    }
4957
4958
0
                    double nTransitionDuration(0.0);
4959
0
                    if( pSlide->getPropertySetInfo()->hasPropertyByName( "TransitionDuration" ) &&
4960
0
                        (pSlide->getPropertyValue( "TransitionDuration" ) >>= nTransitionDuration ) && nTransitionDuration != 0.0 )
4961
0
                    {
4962
                        // convert transitionDuration time to ms
4963
0
                        aJsonWriter.put("transitionDuration", nTransitionDuration * 1000);
4964
0
                    }
4965
0
                }
4966
4967
0
                sal_Int32 nChange(0);
4968
0
                if( pSlide->getPropertySetInfo()->hasPropertyByName( "Change" ) &&
4969
0
                        (pSlide->getPropertyValue( "Change" ) >>= nChange ) && nChange == 1 )
4970
0
                {
4971
0
                    double fSlideDuration(0);
4972
0
                    if( pSlide->getPropertySetInfo()->hasPropertyByName( "HighResDuration" ) &&
4973
0
                            (pSlide->getPropertyValue( "HighResDuration" ) >>= fSlideDuration) )
4974
0
                    {
4975
                        // convert slide duration time to ms
4976
0
                        aJsonWriter.put("nextSlideDuration", fSlideDuration * 1000);
4977
0
                    }
4978
0
                }
4979
4980
4981
0
                AnimationsExporter aAnimationExporter(aJsonWriter, pSlide);
4982
0
                if (aAnimationExporter.hasEffects())
4983
0
                {
4984
0
                    {
4985
0
                        auto aAnimationsNode = aJsonWriter.startNode("animations");
4986
0
                        aAnimationExporter.exportAnimations();
4987
0
                    }
4988
0
                    aAnimationExporter.exportTriggers();
4989
0
                }
4990
0
            }
4991
0
        }
4992
0
    }
4993
0
    catch (uno::Exception& )
4994
0
    {
4995
0
        TOOLS_WARN_EXCEPTION("sd", "SdXImpressDocument::getSlideShowInfo ... maybe some property can't be retrieved");
4996
0
    }
4997
0
    return aJsonWriter.finishAndGetAsOString();
4998
0
}
4999
5000
namespace
5001
{
5002
bool isRequestedSlideValid(SdDrawDocument* mpDoc, sal_Int32 nSlideNumber, const std::string& slideHash)
5003
0
{
5004
0
    try
5005
0
    {
5006
0
        SdXImpressDocument* pDoc = mpDoc->getUnoModel();
5007
0
        rtl::Reference<SdDrawPagesAccess> xDrawPages = pDoc->getSdDrawPages();
5008
0
        SdGenericDrawPage* pSlide(xDrawPages->getDrawPageByIndex(nSlideNumber));
5009
0
        if (pSlide)
5010
0
        {
5011
0
            return slideHash == GetInterfaceHash(cppu::getXWeak(pSlide));
5012
0
        }
5013
0
    }
5014
0
    catch (uno::Exception&)
5015
0
    {
5016
0
        TOOLS_WARN_EXCEPTION( "sd", "SdXImpressDocument::createLOKSlideRenderer: failed" );
5017
0
    }
5018
0
    return false;
5019
0
}
5020
}
5021
5022
bool SdXImpressDocument::createSlideRenderer(
5023
    const OString& rSlideHash,
5024
    sal_Int32 nSlideNumber, sal_Int32& nViewWidth, sal_Int32& nViewHeight,
5025
    bool bRenderBackground, bool bRenderMasterPage)
5026
0
{
5027
0
    std::string sSlideHash(rSlideHash);
5028
0
    if (!isRequestedSlideValid(mpDoc, nSlideNumber, sSlideHash))
5029
0
        return false;
5030
5031
0
    SdPage* pPage = mpDoc->GetSdPage(sal_uInt16(nSlideNumber), PageKind::Standard);
5032
0
    if (!pPage)
5033
0
        return false;
5034
5035
0
    mpSlideshowLayerRenderer.reset(new SlideshowLayerRenderer(*pPage, rSlideHash, bRenderBackground, bRenderMasterPage));
5036
0
    Size aDesiredSize(nViewWidth, nViewHeight);
5037
0
    Size aCalculatedSize = mpSlideshowLayerRenderer->calculateAndSetSizePixel(aDesiredSize);
5038
0
    nViewWidth = aCalculatedSize.Width();
5039
0
    nViewHeight = aCalculatedSize.Height();
5040
0
    return true;
5041
0
}
5042
5043
void SdXImpressDocument::postSlideshowCleanup()
5044
0
{
5045
0
    DrawViewShell* pViewSh = GetViewShell();
5046
0
    if (!pViewSh)
5047
0
        return;
5048
5049
0
    pViewSh->destroyXSlideShowInstance();
5050
0
}
5051
5052
bool SdXImpressDocument::renderNextSlideLayer(unsigned char* pBuffer, bool& bIsBitmapLayer, double& rScale, OUString& rJsonMsg)
5053
0
{
5054
0
    bool bDone = true;
5055
5056
0
    if (!mpSlideshowLayerRenderer)
5057
0
        return bDone;
5058
5059
0
    OString sMsg;
5060
0
    bool bOK = mpSlideshowLayerRenderer->render(pBuffer, bIsBitmapLayer, rScale, sMsg);
5061
5062
0
    if (bOK)
5063
0
    {
5064
0
        rJsonMsg = OUString::fromUtf8(sMsg);
5065
0
        bDone = false;
5066
0
    }
5067
5068
0
    return bDone;
5069
0
}
5070
5071
SdrModel& SdXImpressDocument::getSdrModelFromUnoModel() const
5072
0
{
5073
0
    OSL_ENSURE(GetDoc(), "No SdrModel in draw/Impress, should not happen");
5074
0
    return *GetDoc(); // TTTT should be reference
5075
0
}
5076
5077
void SAL_CALL SdXImpressDocument::dispose()
5078
14.5k
{
5079
14.5k
    if( mbDisposed )
5080
0
        return;
5081
5082
14.5k
    ::SolarMutexGuard aGuard;
5083
5084
14.5k
    if( mpDoc )
5085
14.5k
    {
5086
14.5k
        EndListening( *mpDoc );
5087
14.5k
        mpDoc = nullptr;
5088
14.5k
    }
5089
5090
    // Call the base class dispose() before setting the mbDisposed flag
5091
    // to true.  The reason for this is that if close() has not yet been
5092
    // called this is done in SfxBaseModel::dispose().  At the end of
5093
    // that dispose() is called again.  It is important to forward this
5094
    // second dispose() to the base class, too.
5095
    // As a consequence the following code has to be able to be run twice.
5096
14.5k
    SfxBaseModel::dispose();
5097
14.5k
    mbDisposed = true;
5098
5099
14.5k
    rtl::Reference< SdDocLinkTargets > xLinks( mxLinks );
5100
14.5k
    if( xLinks.is() )
5101
0
    {
5102
0
        xLinks->dispose();
5103
0
        xLinks = nullptr;
5104
0
    }
5105
5106
14.5k
    rtl::Reference< SdDrawPagesAccess > xDrawPagesAccess( mxDrawPagesAccess );
5107
14.5k
    if( xDrawPagesAccess.is() )
5108
0
    {
5109
0
        xDrawPagesAccess->dispose();
5110
0
        xDrawPagesAccess = nullptr;
5111
0
    }
5112
5113
14.5k
    rtl::Reference< SdMasterPagesAccess > xMasterPagesAccess( mxMasterPagesAccess );
5114
14.5k
    if( xDrawPagesAccess.is() )
5115
0
    {
5116
0
        xMasterPagesAccess->dispose();
5117
0
        xMasterPagesAccess = nullptr;
5118
0
    }
5119
5120
14.5k
    rtl::Reference< SdLayerManager > xLayerManager( mxLayerManager );
5121
14.5k
    if( xLayerManager.is() )
5122
0
    {
5123
0
        xLayerManager->dispose();
5124
0
        xLayerManager = nullptr;
5125
0
    }
5126
5127
14.5k
    mxDashTable = nullptr;
5128
14.5k
    mxGradientTable = nullptr;
5129
14.5k
    mxHatchTable = nullptr;
5130
14.5k
    mxBitmapTable = nullptr;
5131
14.5k
    mxTransGradientTable = nullptr;
5132
14.5k
    mxMarkerTable = nullptr;
5133
14.5k
    mxDrawingPool = nullptr;
5134
14.5k
    mpDocShell = nullptr;
5135
14.5k
}
5136
5137
SdDrawPagesAccess::SdDrawPagesAccess( SdXImpressDocument& rMyModel )  noexcept
5138
5.45k
:   mpModel( &rMyModel)
5139
5.45k
{
5140
5.45k
}
5141
5142
SdDrawPagesAccess::~SdDrawPagesAccess() noexcept
5143
5.45k
{
5144
5.45k
}
5145
5146
// XIndexAccess
5147
sal_Int32 SAL_CALL SdDrawPagesAccess::getCount()
5148
361
{
5149
361
    ::SolarMutexGuard aGuard;
5150
5151
361
    if( nullptr == mpModel )
5152
0
        throw lang::DisposedException();
5153
5154
361
    return mpModel->mpDoc->GetSdPageCount( PageKind::Standard );
5155
361
}
5156
5157
uno::Any SAL_CALL SdDrawPagesAccess::getByIndex( sal_Int32 Index )
5158
3.29k
{
5159
3.29k
    uno::Reference< drawing::XDrawPage > xDrawPage( getDrawPageByIndex(Index) );
5160
3.29k
    return uno::Any(xDrawPage);
5161
3.29k
}
5162
5163
SdGenericDrawPage* SdDrawPagesAccess::getDrawPageByIndex( sal_Int32 Index )
5164
3.29k
{
5165
3.29k
    ::SolarMutexGuard aGuard;
5166
5167
3.29k
    if( nullptr == mpModel )
5168
0
        throw lang::DisposedException();
5169
5170
3.29k
    if( (Index < 0) || (Index >= mpModel->mpDoc->GetSdPageCount( PageKind::Standard ) ) )
5171
0
        throw lang::IndexOutOfBoundsException();
5172
5173
3.29k
    SdPage* pPage = mpModel->mpDoc->GetSdPage( static_cast<sal_uInt16>(Index), PageKind::Standard );
5174
3.29k
    if( pPage )
5175
3.29k
        return dynamic_cast<SdGenericDrawPage*>( pPage->getUnoPage().get() );
5176
5177
0
    return nullptr;
5178
3.29k
}
5179
5180
// XNameAccess
5181
uno::Any SAL_CALL SdDrawPagesAccess::getByName( const OUString& aName )
5182
0
{
5183
0
    ::SolarMutexGuard aGuard;
5184
5185
0
    if( nullptr == mpModel )
5186
0
        throw lang::DisposedException();
5187
5188
0
    if( !aName.isEmpty() )
5189
0
    {
5190
0
        const sal_uInt16 nCount = mpModel->mpDoc->GetSdPageCount( PageKind::Standard );
5191
0
        sal_uInt16 nPage;
5192
0
        for( nPage = 0; nPage < nCount; nPage++ )
5193
0
        {
5194
0
            SdPage* pPage = mpModel->mpDoc->GetSdPage( nPage, PageKind::Standard );
5195
0
            if(nullptr == pPage)
5196
0
                continue;
5197
5198
0
            if( aName == SdDrawPage::getPageApiName( pPage ) )
5199
0
            {
5200
0
                uno::Any aAny;
5201
0
                uno::Reference< drawing::XDrawPage >  xDrawPage( pPage->getUnoPage(), uno::UNO_QUERY );
5202
0
                aAny <<= xDrawPage;
5203
0
                return aAny;
5204
0
            }
5205
0
        }
5206
0
    }
5207
5208
0
    throw container::NoSuchElementException();
5209
0
}
5210
5211
uno::Sequence< OUString > SAL_CALL SdDrawPagesAccess::getElementNames()
5212
0
{
5213
0
    ::SolarMutexGuard aGuard;
5214
5215
0
    if( nullptr == mpModel )
5216
0
        throw lang::DisposedException();
5217
5218
0
    const sal_uInt16 nCount = mpModel->mpDoc->GetSdPageCount( PageKind::Standard );
5219
0
    uno::Sequence< OUString > aNames( nCount );
5220
0
    OUString* pNames = aNames.getArray();
5221
5222
0
    sal_uInt16 nPage;
5223
0
    for( nPage = 0; nPage < nCount; nPage++ )
5224
0
    {
5225
0
        SdPage* pPage = mpModel->mpDoc->GetSdPage( nPage, PageKind::Standard );
5226
0
        *pNames++ = SdDrawPage::getPageApiName( pPage );
5227
0
    }
5228
5229
0
    return aNames;
5230
0
}
5231
5232
sal_Bool SAL_CALL SdDrawPagesAccess::hasByName( const OUString& aName )
5233
0
{
5234
0
    ::SolarMutexGuard aGuard;
5235
5236
0
    if( nullptr == mpModel )
5237
0
        throw lang::DisposedException();
5238
5239
0
    const sal_uInt16 nCount = mpModel->mpDoc->GetSdPageCount( PageKind::Standard );
5240
0
    sal_uInt16 nPage;
5241
0
    for( nPage = 0; nPage < nCount; nPage++ )
5242
0
    {
5243
0
        SdPage* pPage = mpModel->mpDoc->GetSdPage( nPage, PageKind::Standard );
5244
0
        if(nullptr == pPage)
5245
0
            continue;
5246
5247
0
        if( aName == SdDrawPage::getPageApiName( pPage ) )
5248
0
            return true;
5249
0
    }
5250
5251
0
    return false;
5252
0
}
5253
5254
// XElementAccess
5255
uno::Type SAL_CALL SdDrawPagesAccess::getElementType()
5256
0
{
5257
0
    return cppu::UnoType<drawing::XDrawPage>::get();
5258
0
}
5259
5260
sal_Bool SAL_CALL SdDrawPagesAccess::hasElements()
5261
0
{
5262
0
    return getCount() > 0;
5263
0
}
5264
5265
// XDrawPages
5266
5267
/**
5268
 * Creates a new page with model at the specified position.
5269
 * @returns corresponding SdDrawPage
5270
 */
5271
uno::Reference< drawing::XDrawPage > SAL_CALL SdDrawPagesAccess::insertNewByIndex( sal_Int32 nIndex )
5272
2.50k
{
5273
2.50k
    ::SolarMutexGuard aGuard;
5274
2.50k
    comphelper::ProfileZone aZone("insertNewByIndex");
5275
5276
2.50k
    if( nullptr == mpModel )
5277
0
        throw lang::DisposedException();
5278
5279
2.50k
    if( mpModel->mpDoc )
5280
2.50k
    {
5281
2.50k
        SdPage* pPage = mpModel->InsertSdPage( static_cast<sal_uInt16>(nIndex), false );
5282
2.50k
        if( pPage )
5283
2.50k
        {
5284
2.50k
            uno::Reference< drawing::XDrawPage > xDrawPage( pPage->getUnoPage(), uno::UNO_QUERY );
5285
2.50k
            return xDrawPage;
5286
2.50k
        }
5287
2.50k
    }
5288
0
    uno::Reference< drawing::XDrawPage > xDrawPage;
5289
0
    return xDrawPage;
5290
2.50k
}
5291
5292
/**
5293
 * Removes the specified SdDrawPage from the model and the internal list. It
5294
 * only works, if there is at least one *normal* page in the model after
5295
 * removing this page.
5296
 */
5297
void SAL_CALL SdDrawPagesAccess::remove( const uno::Reference< drawing::XDrawPage >& xPage )
5298
0
{
5299
0
    ::SolarMutexGuard aGuard;
5300
5301
0
    if( nullptr == mpModel || mpModel->mpDoc == nullptr )
5302
0
        throw lang::DisposedException();
5303
5304
0
    SdDrawDocument& rDoc = *mpModel->mpDoc;
5305
5306
0
    sal_uInt16 nPageCount = rDoc.GetSdPageCount( PageKind::Standard );
5307
0
    if( nPageCount > 1 )
5308
0
    {
5309
        // get pPage from xPage and determine the Id (nPos ) afterwards
5310
0
        SdDrawPage* pSvxPage = comphelper::getFromUnoTunnel<SdDrawPage>( xPage );
5311
0
        if( pSvxPage )
5312
0
        {
5313
0
            SdPage* pPage = static_cast<SdPage*>(pSvxPage->GetSdrPage());
5314
0
            if(pPage && ( pPage->GetPageKind() == PageKind::Standard ) )
5315
0
            {
5316
0
                sal_uInt16 nPage = pPage->GetPageNum();
5317
5318
0
                SdPage* pNotesPage = static_cast< SdPage* >( rDoc.GetPage( nPage+1 ) );
5319
5320
0
                bool bUndo = rDoc.IsUndoEnabled();
5321
0
                if( bUndo )
5322
0
                {
5323
                    // Add undo actions and delete the pages.  The order of adding
5324
                    // the undo actions is important.
5325
0
                    rDoc.BegUndo( SdResId( STR_UNDO_DELETEPAGES ) );
5326
0
                    if (pNotesPage)
5327
0
                    {
5328
0
                        rDoc.AddUndo(rDoc.GetSdrUndoFactory().CreateUndoDeletePage(*pNotesPage));
5329
0
                    }
5330
0
                    rDoc.AddUndo(rDoc.GetSdrUndoFactory().CreateUndoDeletePage(*pPage));
5331
0
                }
5332
5333
0
                rDoc.RemovePage( nPage ); // the page
5334
0
                if (pNotesPage)
5335
0
                {
5336
0
                    rDoc.RemovePage( nPage ); // the notes page
5337
0
                }
5338
5339
0
                if( bUndo )
5340
0
                {
5341
0
                    rDoc.EndUndo();
5342
0
                }
5343
0
            }
5344
0
        }
5345
0
    }
5346
5347
0
    mpModel->SetModified();
5348
0
}
5349
5350
// XServiceInfo
5351
5352
OUString SAL_CALL SdDrawPagesAccess::getImplementationName(  )
5353
0
{
5354
0
    return u"SdDrawPagesAccess"_ustr;
5355
0
}
5356
5357
sal_Bool SAL_CALL SdDrawPagesAccess::supportsService( const OUString& ServiceName )
5358
0
{
5359
0
    return cppu::supportsService(this, ServiceName);
5360
0
}
5361
5362
uno::Sequence< OUString > SAL_CALL SdDrawPagesAccess::getSupportedServiceNames(  )
5363
0
{
5364
0
    return { u"com.sun.star.drawing.DrawPages"_ustr };
5365
0
}
5366
5367
// XComponent
5368
void SAL_CALL SdDrawPagesAccess::dispose(  )
5369
0
{
5370
0
    mpModel = nullptr;
5371
0
}
5372
5373
void SAL_CALL SdDrawPagesAccess::addEventListener( const uno::Reference< lang::XEventListener >&  )
5374
0
{
5375
0
    OSL_FAIL( "not implemented!" );
5376
0
}
5377
5378
void SAL_CALL SdDrawPagesAccess::removeEventListener( const uno::Reference< lang::XEventListener >&  )
5379
0
{
5380
0
    OSL_FAIL( "not implemented!" );
5381
0
}
5382
5383
5384
SdMasterPagesAccess::SdMasterPagesAccess( SdXImpressDocument& rMyModel ) noexcept
5385
2.65k
:   mpModel(&rMyModel)
5386
2.65k
{
5387
2.65k
}
5388
5389
SdMasterPagesAccess::~SdMasterPagesAccess() noexcept
5390
2.65k
{
5391
2.65k
}
5392
5393
// XComponent
5394
void SAL_CALL SdMasterPagesAccess::dispose(  )
5395
0
{
5396
0
    mpModel = nullptr;
5397
0
}
5398
5399
void SAL_CALL SdMasterPagesAccess::addEventListener( const uno::Reference< lang::XEventListener >&  )
5400
0
{
5401
0
    OSL_FAIL( "not implemented!" );
5402
0
}
5403
5404
void SAL_CALL SdMasterPagesAccess::removeEventListener( const uno::Reference< lang::XEventListener >&  )
5405
0
{
5406
0
    OSL_FAIL( "not implemented!" );
5407
0
}
5408
5409
// XIndexAccess
5410
sal_Int32 SAL_CALL SdMasterPagesAccess::getCount()
5411
16.1k
{
5412
16.1k
    ::SolarMutexGuard aGuard;
5413
5414
16.1k
    if( nullptr == mpModel->mpDoc )
5415
0
        throw lang::DisposedException();
5416
5417
16.1k
    return mpModel->mpDoc->GetMasterSdPageCount(PageKind::Standard);
5418
16.1k
}
5419
5420
/**
5421
 * Provides a drawing::XDrawPage interface for accessing the Masterpage at the
5422
 * specified position in the model.
5423
 */
5424
uno::Any SAL_CALL SdMasterPagesAccess::getByIndex( sal_Int32 Index )
5425
2.74k
{
5426
2.74k
    ::SolarMutexGuard aGuard;
5427
2.74k
    comphelper::ProfileZone aZone("SdMasterPagesAccess::getByIndex");
5428
5429
2.74k
    if( nullptr == mpModel )
5430
0
        throw lang::DisposedException();
5431
5432
2.74k
    uno::Any aAny;
5433
5434
2.74k
    if( (Index < 0) || (Index >= mpModel->mpDoc->GetMasterSdPageCount( PageKind::Standard ) ) )
5435
0
        throw lang::IndexOutOfBoundsException();
5436
5437
2.74k
    SdPage* pPage = mpModel->mpDoc->GetMasterSdPage( static_cast<sal_uInt16>(Index), PageKind::Standard );
5438
2.74k
    if( pPage )
5439
2.74k
    {
5440
2.74k
        uno::Reference< drawing::XDrawPage >  xDrawPage( pPage->getUnoPage(), uno::UNO_QUERY );
5441
2.74k
        aAny <<= xDrawPage;
5442
2.74k
    }
5443
5444
2.74k
    return aAny;
5445
2.74k
}
5446
5447
// XElementAccess
5448
uno::Type SAL_CALL SdMasterPagesAccess::getElementType()
5449
0
{
5450
0
    return cppu::UnoType<drawing::XDrawPage>::get();
5451
0
}
5452
5453
sal_Bool SAL_CALL SdMasterPagesAccess::hasElements()
5454
0
{
5455
0
    return getCount() > 0;
5456
0
}
5457
5458
// XDrawPages
5459
uno::Reference< drawing::XDrawPage > SAL_CALL SdMasterPagesAccess::insertNewByIndex( sal_Int32 nInsertPos )
5460
14.4k
{
5461
14.4k
    return insertNewImpl(nInsertPos, std::nullopt);
5462
14.4k
}
5463
5464
// XDrawPages2
5465
uno::Reference< drawing::XDrawPage > SAL_CALL SdMasterPagesAccess::insertNamedNewByIndex( sal_Int32 nInsertPos, const OUString& sName )
5466
3
{
5467
3
    return insertNewImpl(nInsertPos, sName);
5468
3
}
5469
5470
uno::Reference< drawing::XDrawPage > SdMasterPagesAccess::insertNewImpl( sal_Int32 nInsertPos, std::optional<OUString> oPageName )
5471
14.4k
{
5472
14.4k
    ::SolarMutexGuard aGuard;
5473
5474
14.4k
    if( nullptr == mpModel )
5475
0
        throw lang::DisposedException();
5476
5477
14.4k
    uno::Reference< drawing::XDrawPage > xDrawPage;
5478
5479
14.4k
    SdDrawDocument* pDoc = mpModel->mpDoc;
5480
14.4k
    if( pDoc )
5481
14.4k
    {
5482
        // calculate internal index and check for range errors
5483
14.4k
        const sal_Int32 nMPageCount = pDoc->GetMasterPageCount();
5484
14.4k
        nInsertPos = nInsertPos * 2 + 1;
5485
14.4k
        if( nInsertPos < 0 || nInsertPos > nMPageCount )
5486
0
            nInsertPos = nMPageCount;
5487
5488
        // now generate a unique name for the new masterpage
5489
14.4k
        OUString aPrefix;
5490
14.4k
        if (oPageName)
5491
3
            aPrefix = *oPageName;
5492
14.4k
        else
5493
14.4k
        {
5494
14.4k
            const OUString aStdPrefix( SdResId(STR_LAYOUT_DEFAULT_NAME) );
5495
14.4k
            aPrefix = aStdPrefix;
5496
5497
14.4k
            bool bUnique = true;
5498
5499
14.4k
            std::vector<OUString> aPageNames;
5500
180k
            for (sal_Int32 nMaster = 1; nMaster < nMPageCount; ++nMaster)
5501
165k
            {
5502
165k
                const SdPage* pPage = static_cast<const SdPage*>(pDoc->GetMasterPage(static_cast<sal_uInt16>(nMaster)));
5503
165k
                if (!pPage)
5504
0
                    continue;
5505
165k
                aPageNames.push_back(pPage->GetName());
5506
165k
                if (aPageNames.back() == aPrefix)
5507
10.4k
                    bUnique = false;
5508
165k
            }
5509
5510
14.4k
            sal_Int32 i = 0;
5511
44.1k
            while (!bUnique)
5512
29.6k
            {
5513
29.6k
                aPrefix = aStdPrefix + " " + OUString::number(++i);
5514
29.6k
                bUnique = std::find(aPageNames.begin(), aPageNames.end(), aPrefix) == aPageNames.end();
5515
29.6k
            }
5516
14.4k
        }
5517
14.4k
        OUString aLayoutName = aPrefix + SD_LT_SEPARATOR + STR_LAYOUT_OUTLINE;
5518
5519
        // create styles
5520
14.4k
        static_cast<SdStyleSheetPool*>(pDoc->GetStyleSheetPool())->CreateLayoutStyleSheets( aPrefix );
5521
5522
        // get the first page for initial size and border settings
5523
14.4k
        SdPage* pPage = mpModel->mpDoc->GetSdPage( sal_uInt16(0), PageKind::Standard );
5524
14.4k
        SdPage* pRefNotesPage = mpModel->mpDoc->GetSdPage( sal_uInt16(0), PageKind::Notes);
5525
5526
        // create and insert new draw masterpage
5527
14.4k
        rtl::Reference<SdPage> pMPage = mpModel->mpDoc->AllocSdPage(true);
5528
14.4k
        pMPage->SetSize( pPage->GetSize() );
5529
14.4k
        pMPage->SetBorder( pPage->GetLeftBorder(),
5530
14.4k
                           pPage->GetUpperBorder(),
5531
14.4k
                           pPage->GetRightBorder(),
5532
14.4k
                           pPage->GetLowerBorder() );
5533
14.4k
        if (oPageName)
5534
            // no need to update the page URLs on a brand new page
5535
3
            pMPage->SetName(*oPageName, /*bUpdatePageRelativeURLs*/false);
5536
14.4k
        pMPage->SetLayoutName( aLayoutName );
5537
14.4k
        pDoc->InsertMasterPage(pMPage.get(),  static_cast<sal_uInt16>(nInsertPos));
5538
5539
14.4k
        {
5540
            // ensure default MasterPage fill
5541
14.4k
            pMPage->EnsureMasterPageDefaultBackground();
5542
14.4k
        }
5543
5544
14.4k
        xDrawPage.set( pMPage->getUnoPage(), uno::UNO_QUERY );
5545
5546
        // create and insert new notes masterpage
5547
14.4k
        rtl::Reference<SdPage> pMNotesPage = mpModel->mpDoc->AllocSdPage(true);
5548
14.4k
        pMNotesPage->SetSize( pRefNotesPage->GetSize() );
5549
14.4k
        pMNotesPage->SetPageKind(PageKind::Notes);
5550
14.4k
        pMNotesPage->SetBorder( pRefNotesPage->GetLeftBorder(),
5551
14.4k
                                pRefNotesPage->GetUpperBorder(),
5552
14.4k
                                pRefNotesPage->GetRightBorder(),
5553
14.4k
                                pRefNotesPage->GetLowerBorder() );
5554
14.4k
        pMNotesPage->SetLayoutName( aLayoutName );
5555
14.4k
        pDoc->InsertMasterPage(pMNotesPage.get(),  static_cast<sal_uInt16>(nInsertPos) + 1);
5556
14.4k
        pMNotesPage->SetAutoLayout(AUTOLAYOUT_NOTES, true, true);
5557
14.4k
        mpModel->SetModified();
5558
14.4k
    }
5559
5560
14.4k
    return xDrawPage;
5561
14.4k
}
5562
5563
/**
5564
 * Removes the specified SdMasterPage from the model and the internal list. It
5565
 * only works, if there is no *normal* page using this page as MasterPage in
5566
 * the model.
5567
 */
5568
void SAL_CALL SdMasterPagesAccess::remove( const uno::Reference< drawing::XDrawPage >& xPage )
5569
0
{
5570
0
    ::SolarMutexGuard aGuard;
5571
5572
0
    if( nullptr == mpModel || mpModel->mpDoc == nullptr )
5573
0
        throw lang::DisposedException();
5574
5575
0
    SdMasterPage* pSdPage = comphelper::getFromUnoTunnel<SdMasterPage>( xPage );
5576
0
    if(pSdPage == nullptr)
5577
0
        return;
5578
5579
0
    SdPage* pPage = dynamic_cast< SdPage* > (pSdPage->GetSdrPage());
5580
5581
0
    DBG_ASSERT( pPage && pPage->IsMasterPage(), "SdMasterPage is not masterpage?");
5582
5583
0
    if( !pPage || !pPage->IsMasterPage() || (mpModel->mpDoc->GetMasterPageUserCount(pPage) > 0))
5584
0
        return; //Todo: this should be excepted
5585
5586
    // only standard pages can be removed directly
5587
0
    if( pPage->GetPageKind() != PageKind::Standard )
5588
0
        return;
5589
5590
0
    sal_uInt16 nPage = pPage->GetPageNum();
5591
5592
0
    SdDrawDocument& rDoc = *mpModel->mpDoc;
5593
5594
0
    SdPage* pNotesPage = static_cast< SdPage* >( rDoc.GetMasterPage( nPage+1 ) );
5595
5596
0
    bool bUndo = rDoc.IsUndoEnabled();
5597
0
    if( bUndo )
5598
0
    {
5599
        // Add undo actions and delete the pages.  The order of adding
5600
        // the undo actions is important.
5601
0
        rDoc.BegUndo( SdResId( STR_UNDO_DELETEPAGES ) );
5602
0
        rDoc.AddUndo(rDoc.GetSdrUndoFactory().CreateUndoDeletePage(*pNotesPage));
5603
0
        rDoc.AddUndo(rDoc.GetSdrUndoFactory().CreateUndoDeletePage(*pPage));
5604
0
    }
5605
5606
    // remove both pages
5607
0
    rDoc.RemoveMasterPage( nPage );
5608
0
    rDoc.RemoveMasterPage( nPage );
5609
5610
0
    if( bUndo )
5611
0
    {
5612
0
        rDoc.EndUndo();
5613
0
    }
5614
0
}
5615
5616
// XServiceInfo
5617
5618
OUString SAL_CALL SdMasterPagesAccess::getImplementationName(  )
5619
0
{
5620
0
    return u"SdMasterPagesAccess"_ustr;
5621
0
}
5622
5623
sal_Bool SAL_CALL SdMasterPagesAccess::supportsService( const OUString& ServiceName )
5624
0
{
5625
0
    return cppu::supportsService(this, ServiceName);
5626
0
}
5627
5628
uno::Sequence< OUString > SAL_CALL SdMasterPagesAccess::getSupportedServiceNames(  )
5629
0
{
5630
0
    return { u"com.sun.star.drawing.MasterPages"_ustr };
5631
0
}
5632
5633
SdDocLinkTargets::SdDocLinkTargets(SdXImpressDocument& rMyModel)
5634
0
    : mpModel(&rMyModel)
5635
0
{
5636
0
    for (sal_uInt16 i=0; i < SdLinkTargetType::Count; i++)
5637
0
        aNames[i] = SdResId(aTypeResIds[i]);
5638
0
}
5639
5640
SdDocLinkTargets::~SdDocLinkTargets() noexcept
5641
0
{
5642
0
}
5643
5644
// XComponent
5645
void SAL_CALL SdDocLinkTargets::dispose(  )
5646
0
{
5647
0
    mpModel = nullptr;
5648
0
}
5649
5650
void SAL_CALL SdDocLinkTargets::addEventListener( const uno::Reference< lang::XEventListener >&  )
5651
0
{
5652
0
    OSL_FAIL( "not implemented!" );
5653
0
}
5654
5655
void SAL_CALL SdDocLinkTargets::removeEventListener( const uno::Reference< lang::XEventListener >&  )
5656
0
{
5657
0
    OSL_FAIL( "not implemented!" );
5658
0
}
5659
5660
// XNameAccess
5661
uno::Any SAL_CALL SdDocLinkTargets::getByName( const OUString& aName )
5662
0
{
5663
0
    if (mpModel)
5664
0
    {
5665
0
        for (sal_uInt16 i=0; i < SdLinkTargetType::Count; i++)
5666
0
            if ( aNames[i] == aName )
5667
0
                return uno::Any(uno::Reference< beans::XPropertySet >(new SdDocLinkTargetType( mpModel, i )));
5668
0
    }
5669
5670
0
    throw container::NoSuchElementException();
5671
0
}
5672
5673
uno::Sequence< OUString > SAL_CALL SdDocLinkTargets::getElementNames()
5674
0
{
5675
0
    uno::Sequence<OUString> aRet(SdLinkTargetType::Count);
5676
0
    OUString* pArray = aRet.getArray();
5677
0
    for (sal_uInt16 i=0; i < SdLinkTargetType::Count; i++)
5678
0
        pArray[i] = aNames[i];
5679
0
    return aRet;
5680
0
}
5681
5682
sal_Bool SAL_CALL SdDocLinkTargets::hasByName( const OUString& aName )
5683
0
{
5684
0
    for (const auto & i : aNames)
5685
0
        if ( i == aName )
5686
0
            return true;
5687
0
    return false;
5688
0
}
5689
5690
// container::XElementAccess
5691
uno::Type SAL_CALL SdDocLinkTargets::getElementType()
5692
0
{
5693
0
    return cppu::UnoType<beans::XPropertySet>::get();
5694
0
}
5695
5696
sal_Bool SAL_CALL SdDocLinkTargets::hasElements()
5697
0
{
5698
0
    return true;
5699
0
}
5700
5701
SdPage* SdDocLinkTarget::FindPage( std::u16string_view rName ) const
5702
0
{
5703
0
    SdDrawDocument* pDoc = mpModel->GetDoc();
5704
0
    if( pDoc == nullptr )
5705
0
        return nullptr;
5706
5707
0
    const sal_uInt16 nMaxPages = pDoc->GetPageCount();
5708
0
    const sal_uInt16 nMaxMasterPages = pDoc->GetMasterPageCount();
5709
5710
0
    sal_uInt16 nPage;
5711
0
    SdPage* pPage;
5712
5713
0
    const bool bDraw = pDoc->GetDocumentType() == DocumentType::Draw;
5714
5715
    // standard pages
5716
0
    for( nPage = 0; nPage < nMaxPages; nPage++ )
5717
0
    {
5718
0
        pPage = static_cast<SdPage*>(pDoc->GetPage( nPage ));
5719
0
        if( (pPage->GetName() == rName) && (!bDraw || (pPage->GetPageKind() == PageKind::Standard)) )
5720
0
            return pPage;
5721
0
    }
5722
5723
    // master pages
5724
0
    for( nPage = 0; nPage < nMaxMasterPages; nPage++ )
5725
0
    {
5726
0
        pPage = static_cast<SdPage*>(pDoc->GetMasterPage( nPage ));
5727
0
        if( (pPage->GetName() == rName) && (!bDraw || (pPage->GetPageKind() == PageKind::Standard)) )
5728
0
            return pPage;
5729
0
    }
5730
5731
0
    return nullptr;
5732
0
}
5733
5734
// XServiceInfo
5735
OUString SAL_CALL SdDocLinkTargets::getImplementationName()
5736
0
{
5737
0
    return u"SdDocLinkTargets"_ustr;
5738
0
}
5739
5740
sal_Bool SAL_CALL SdDocLinkTargets::supportsService( const OUString& ServiceName )
5741
0
{
5742
0
    return cppu::supportsService( this, ServiceName );
5743
0
}
5744
5745
uno::Sequence< OUString > SAL_CALL SdDocLinkTargets::getSupportedServiceNames()
5746
0
{
5747
0
    return { u"com.sun.star.document.LinkTargets"_ustr };
5748
0
}
5749
5750
SdDocLinkTargetType::SdDocLinkTargetType(SdXImpressDocument* pModel, sal_uInt16 nT)
5751
0
    : mpModel(pModel)
5752
0
    , mnType(nT)
5753
0
{
5754
0
    maName = SdResId(aTypeResIds[nT]);
5755
0
}
5756
5757
// beans::XPropertySet
5758
5759
uno::Reference< beans::XPropertySetInfo > SAL_CALL SdDocLinkTargetType::getPropertySetInfo()
5760
0
{
5761
0
    static uno::Reference< beans::XPropertySetInfo > aRef;//(new SfxItemPropertySetInfo( lcl_GetLinkTargetMap() ));
5762
0
    return aRef;
5763
0
}
5764
5765
void SAL_CALL SdDocLinkTargetType::setPropertyValue(const OUString& /* aPropertyName */,
5766
            const uno::Any& /* aValue */)
5767
0
{
5768
    //  everything is read-only
5769
0
}
5770
5771
uno::Any SAL_CALL SdDocLinkTargetType::getPropertyValue(const OUString& PropertyName)
5772
0
{
5773
0
    uno::Any aRet;
5774
0
    if ( PropertyName == "LinkDisplayName" )
5775
0
        aRet <<= maName;
5776
5777
0
    return aRet;
5778
0
}
5779
5780
void SAL_CALL SdDocLinkTargetType::addPropertyChangeListener( const OUString&,
5781
                            const uno::Reference<beans::XPropertyChangeListener>&)
5782
0
{ OSL_FAIL("not implemented"); }
5783
5784
void SAL_CALL SdDocLinkTargetType::removePropertyChangeListener( const OUString&,
5785
                        const uno::Reference<beans::XPropertyChangeListener>&)
5786
0
{ OSL_FAIL("not implemented"); }
5787
5788
void SAL_CALL SdDocLinkTargetType::addVetoableChangeListener( const OUString&,
5789
                        const uno::Reference<beans::XVetoableChangeListener>&)
5790
0
{ OSL_FAIL("not implemented"); }
5791
5792
void SAL_CALL SdDocLinkTargetType::removeVetoableChangeListener( const OUString&,
5793
                        const uno::Reference<beans::XVetoableChangeListener>&)
5794
0
{ OSL_FAIL("not implemented"); }
5795
5796
// document::XLinkTargetSupplier
5797
5798
uno::Reference< container::XNameAccess > SAL_CALL SdDocLinkTargetType::getLinks()
5799
0
{
5800
0
    return new SdDocLinkTarget( mpModel, mnType );
5801
0
}
5802
5803
// XServiceInfo
5804
OUString SAL_CALL SdDocLinkTargetType::getImplementationName()
5805
0
{
5806
0
    return u"SdDocLinkTargetType"_ustr;
5807
0
}
5808
5809
sal_Bool SAL_CALL SdDocLinkTargetType::supportsService( const OUString& ServiceName )
5810
0
{
5811
0
    return cppu::supportsService( this, ServiceName );
5812
0
}
5813
5814
uno::Sequence< OUString > SAL_CALL SdDocLinkTargetType::getSupportedServiceNames()
5815
0
{
5816
0
    return { u"com.sun.star.document.LinkTargetSupplier"_ustr };
5817
0
}
5818
5819
SdDocLinkTarget::SdDocLinkTarget( SdXImpressDocument* pModel, sal_uInt16 nT )
5820
0
    : mpModel(pModel)
5821
0
    , mnType(nT)
5822
0
{
5823
0
}
5824
5825
// container::XNameAccess
5826
5827
uno::Any SAL_CALL SdDocLinkTarget::getByName(const OUString& aName)
5828
0
{
5829
0
    ::SolarMutexGuard aGuard;
5830
5831
0
    if( nullptr == mpModel )
5832
0
        throw lang::DisposedException();
5833
5834
0
    SdPage* pPage = FindPage( aName );
5835
5836
0
    if( pPage == nullptr )
5837
0
        throw container::NoSuchElementException();
5838
5839
0
    uno::Any aAny;
5840
5841
0
    uno::Reference< beans::XPropertySet > xProps( pPage->getUnoPage(), uno::UNO_QUERY );
5842
0
    if( xProps.is() )
5843
0
        aAny <<= xProps;
5844
5845
0
    return aAny;
5846
0
}
5847
5848
uno::Sequence<OUString> SAL_CALL SdDocLinkTarget::getElementNames()
5849
0
{
5850
0
    ::SolarMutexGuard aGuard;
5851
5852
0
    if( nullptr == mpModel )
5853
0
        throw lang::DisposedException();
5854
5855
0
    SdDrawDocument* pDoc = mpModel->GetDoc();
5856
0
    if( pDoc == nullptr )
5857
0
    {
5858
0
        return { };
5859
0
    }
5860
5861
0
    if( pDoc->GetDocumentType() == DocumentType::Draw )
5862
0
    {
5863
0
        const sal_uInt16 nMaxPages = pDoc->GetSdPageCount( PageKind::Standard );
5864
0
        const sal_uInt16 nMaxMasterPages = pDoc->GetMasterSdPageCount( PageKind::Standard );
5865
5866
0
        uno::Sequence< OUString > aSeq( mnType == SdLinkTargetType::Page ? nMaxPages : nMaxMasterPages );
5867
0
        OUString* pStr = aSeq.getArray();
5868
5869
0
        sal_uInt16 nPage;
5870
0
        if (mnType == SdLinkTargetType::Page)
5871
0
        {
5872
            // standard pages
5873
0
            for( nPage = 0; nPage < nMaxPages; nPage++ )
5874
0
                *pStr++ = pDoc->GetSdPage( nPage, PageKind::Standard )->GetName();
5875
0
        }
5876
0
        else
5877
0
        {
5878
            // master pages
5879
0
            for( nPage = 0; nPage < nMaxMasterPages; nPage++ )
5880
0
                *pStr++ = pDoc->GetMasterSdPage( nPage, PageKind::Standard )->GetName();
5881
0
        }
5882
0
        return aSeq;
5883
0
    }
5884
0
    else
5885
0
    {
5886
0
        PageKind eKind;
5887
0
        switch (mnType)
5888
0
        {
5889
0
            case SdLinkTargetType::Notes:
5890
0
                eKind = PageKind::Notes;
5891
0
                break;
5892
0
            case SdLinkTargetType::Handout:
5893
0
                eKind = PageKind::Handout;
5894
0
                break;
5895
0
            default:
5896
0
                eKind = PageKind::Standard;
5897
0
                break;
5898
0
        }
5899
0
        const sal_uInt16 nMaxPages = pDoc->GetSdPageCount( eKind );
5900
0
        const sal_uInt16 nMaxMasterPages = pDoc->GetMasterPageCount();
5901
5902
0
        uno::Sequence< OUString > aSeq( mnType == SdLinkTargetType::MasterPage ? nMaxMasterPages : nMaxPages );
5903
0
        OUString* pStr = aSeq.getArray();
5904
5905
0
        sal_uInt16 nPage;
5906
0
        switch (mnType)
5907
0
        {
5908
0
            case SdLinkTargetType::Page:
5909
0
            {
5910
0
                for( nPage = 0; nPage < nMaxPages; nPage++ )
5911
0
                    *pStr++ = pDoc->GetSdPage( nPage, PageKind::Standard )->GetName();
5912
0
                break;
5913
0
            }
5914
0
            case SdLinkTargetType::Notes:
5915
0
            {
5916
0
                for( nPage = 0; nPage < nMaxPages; nPage++ )
5917
0
                    *pStr++ = pDoc->GetSdPage( nPage, PageKind::Notes )->GetName();
5918
0
                break;
5919
0
            }
5920
0
            case SdLinkTargetType::Handout:
5921
0
            {
5922
0
                for( nPage = 0; nPage < nMaxPages; nPage++ )
5923
0
                    *pStr++ = pDoc->GetSdPage( nPage, PageKind::Handout )->GetName();
5924
0
                break;
5925
0
            }
5926
0
            case SdLinkTargetType::MasterPage:
5927
0
            {
5928
0
                for( nPage = 0; nPage < nMaxMasterPages; nPage++ )
5929
0
                    *pStr++ = static_cast<SdPage*>(pDoc->GetMasterPage( nPage ))->GetName();
5930
0
                break;
5931
0
            }
5932
0
        }
5933
0
        return aSeq;
5934
0
    }
5935
0
}
5936
5937
sal_Bool SAL_CALL SdDocLinkTarget::hasByName(const OUString& aName)
5938
0
{
5939
0
    ::SolarMutexGuard aGuard;
5940
5941
0
    if( nullptr == mpModel )
5942
0
        throw lang::DisposedException();
5943
5944
0
    return FindPage( aName ) != nullptr;
5945
0
}
5946
5947
// container::XElementAccess
5948
5949
uno::Type SAL_CALL SdDocLinkTarget::getElementType()
5950
0
{
5951
0
    return cppu::UnoType<beans::XPropertySet>::get();
5952
0
}
5953
5954
sal_Bool SAL_CALL SdDocLinkTarget::hasElements()
5955
0
{
5956
0
    ::SolarMutexGuard aGuard;
5957
5958
0
    if( nullptr == mpModel )
5959
0
        throw lang::DisposedException();
5960
5961
0
    return mpModel->GetDoc() != nullptr;
5962
0
}
5963
5964
// XServiceInfo
5965
OUString SAL_CALL SdDocLinkTarget::getImplementationName()
5966
0
{
5967
0
    return u"SdDocLinkTarget"_ustr;
5968
0
}
5969
5970
sal_Bool SAL_CALL SdDocLinkTarget::supportsService( const OUString& ServiceName )
5971
0
{
5972
0
    return cppu::supportsService( this, ServiceName );
5973
0
}
5974
5975
uno::Sequence< OUString > SAL_CALL SdDocLinkTarget::getSupportedServiceNames()
5976
0
{
5977
0
    return { u"com.sun.star.document.LinkTargets"_ustr };
5978
0
}
5979
5980
rtl::Reference< SdXImpressDocument > SdXImpressDocument::GetModel( SdDrawDocument const & rDocument )
5981
280
{
5982
280
    rtl::Reference< SdXImpressDocument > xRet;
5983
280
    ::sd::DrawDocShell* pDocShell(rDocument.GetDocSh());
5984
280
    if( pDocShell )
5985
280
    {
5986
280
        uno::Reference<frame::XModel> xModel(pDocShell->GetModel());
5987
5988
280
        xRet.set( dynamic_cast< SdXImpressDocument* >( xModel.get() ) );
5989
280
    }
5990
5991
280
    return xRet;
5992
280
}
5993
5994
void NotifyDocumentEvent(SdDrawDocument const & rDocument, const OUString& rEventName)
5995
0
{
5996
0
    rtl::Reference<SdXImpressDocument> xModel(SdXImpressDocument::GetModel(rDocument));
5997
5998
0
    if (xModel.is())
5999
0
    {
6000
0
        uno::Reference<uno::XInterface> xSource(static_cast<uno::XWeak*>(xModel.get()));
6001
0
        NotifyDocumentEvent(rDocument, rEventName, xSource);
6002
0
    }
6003
0
}
6004
6005
void NotifyDocumentEvent(SdDrawDocument const & rDocument, const OUString& rEventName, const uno::Reference<uno::XInterface>& xSource)
6006
280
{
6007
280
    rtl::Reference<SdXImpressDocument> xModel(SdXImpressDocument::GetModel(rDocument));
6008
6009
280
    if (xModel.is())
6010
280
    {
6011
280
        css::document::EventObject aEvent(xSource, rEventName);
6012
280
        xModel->notifyEvent(aEvent);
6013
280
    }
6014
280
}
6015
6016
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */