Coverage Report

Created: 2025-11-16 09:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/svx/source/svdraw/sdrpagewindow.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
#include <svx/sdrpagewindow.hxx>
21
#include <com/sun/star/awt/XWindow.hpp>
22
#include <com/sun/star/awt/PosSize.hpp>
23
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
24
#include <comphelper/lok.hxx>
25
#include <comphelper/processfactory.hxx>
26
#include <toolkit/helper/vclunohelper.hxx>
27
#include <toolkit/controls/unocontrolcontainer.hxx>
28
#include <toolkit/controls/unocontrolcontainermodel.hxx>
29
#include <svx/svdview.hxx>
30
#include <svx/svdpagv.hxx>
31
#include <svx/sdrpaintwindow.hxx>
32
#include <svx/sdr/contact/objectcontactofpageview.hxx>
33
#include <svx/sdr/contact/displayinfo.hxx>
34
#include <svx/fmview.hxx>
35
#include <sfx2/lokhelper.hxx>
36
#include <svtools/optionsdrawinglayer.hxx>
37
#include <tools/debug.hxx>
38
#include <vcl/window.hxx>
39
40
using namespace ::com::sun::star;
41
42
struct SdrPageWindow::Impl
43
{
44
    // #110094# ObjectContact section
45
    mutable sdr::contact::ObjectContact* mpObjectContact;
46
47
    // the SdrPageView this window belongs to
48
    SdrPageView& mrPageView;
49
50
    // the PaintWindow to paint on. Here is access to OutDev etc.
51
    // #i72752# change to pointer to allow patcing it in DrawLayer() if necessary
52
    SdrPaintWindow* mpPaintWindow;
53
    SdrPaintWindow* mpOriginalPaintWindow;
54
55
    // UNO stuff for xControls
56
    rtl::Reference<UnoControlContainer> mxControlContainer;
57
58
    Impl( SdrPageView& rPageView, SdrPaintWindow& rPaintWindow ) :
59
64.2k
        mpObjectContact(nullptr),
60
64.2k
        mrPageView(rPageView),
61
64.2k
        mpPaintWindow(&rPaintWindow),
62
64.2k
        mpOriginalPaintWindow(nullptr)
63
64.2k
    {
64
64.2k
    }
65
};
66
67
68
rtl::Reference<UnoControlContainer> const & SdrPageWindow::GetControlContainer( bool _bCreateIfNecessary ) const
69
85
{
70
85
    if (!mpImpl->mxControlContainer.is() && _bCreateIfNecessary)
71
17
    {
72
17
        SdrView& rView = GetPageView().GetView();
73
74
17
        const SdrPaintWindow& rPaintWindow( GetOriginalPaintWindow() ? *GetOriginalPaintWindow() : GetPaintWindow() );
75
17
        if ( rPaintWindow.OutputToWindow() && !rView.IsPrintPreview() )
76
8
        {
77
8
            vcl::Window* pWindow = rPaintWindow.GetOutputDevice().GetOwnerWindow();
78
8
            const_cast< SdrPageWindow* >( this )->mpImpl->mxControlContainer = VCLUnoHelper::CreateControlContainer( pWindow );
79
80
            // #100394# xC->setVisible triggers window->Show() and this has
81
            // problems when the view is not completely constructed which may
82
            // happen when loading. This leads to accessibility broadcasts which
83
            // throw asserts due to the not finished view. All this chain can be avoided
84
            // since xC->setVisible is here called only for the side effect in
85
            // UnoControlContainer::setVisible(...) which calls createPeer(...).
86
            // This will now be called directly from here.
87
88
8
            if(mpImpl->mxControlContainer.is())
89
8
            {
90
8
                uno::Reference< uno::XInterface > xContext = mpImpl->mxControlContainer->getContext();
91
8
                if(!xContext.is())
92
8
                {
93
8
                    mpImpl->mxControlContainer->createPeer( uno::Reference<awt::XToolkit>(), uno::Reference<awt::XWindowPeer>() );
94
8
                }
95
8
            }
96
8
        }
97
9
        else
98
9
        {
99
            // Printer and VirtualDevice, or rather: no OutDev
100
9
            const_cast< SdrPageWindow* >( this )->mpImpl->mxControlContainer = new UnoControlContainer();
101
9
            rtl::Reference< UnoControlContainerModel > xModel(new UnoControlContainerModel(comphelper::getProcessComponentContext()));
102
9
            mpImpl->mxControlContainer->setModel(xModel);
103
104
9
            OutputDevice& rOutDev = rPaintWindow.GetOutputDevice();
105
9
            Point aPosPix = rOutDev.GetMapMode().GetOrigin();
106
9
            Size aSizePix = rOutDev.GetOutputSizePixel();
107
108
9
            mpImpl->mxControlContainer->setPosSize(aPosPix.X(), aPosPix.Y(), aSizePix.Width(), aSizePix.Height(), awt::PosSize::POSSIZE);
109
9
        }
110
111
17
        FmFormView* pViewAsFormView = dynamic_cast< FmFormView* >( &rView );
112
17
        if ( pViewAsFormView )
113
17
            pViewAsFormView->InsertControlContainer(mpImpl->mxControlContainer);
114
17
    }
115
85
    return mpImpl->mxControlContainer;
116
85
}
117
118
SdrPageWindow::SdrPageWindow(SdrPageView& rPageView, SdrPaintWindow& rPaintWindow) :
119
64.2k
    mpImpl(new Impl(rPageView, rPaintWindow))
120
64.2k
{
121
64.2k
}
122
123
SdrPageWindow::~SdrPageWindow()
124
64.2k
{
125
    // #i26631#
126
64.2k
    ResetObjectContact();
127
128
64.2k
    if (!mpImpl->mxControlContainer.is())
129
64.2k
        return;
130
131
17
    auto & rView = static_cast<SdrPaintView &>(GetPageView().GetView());
132
133
    // notify derived views
134
17
    FmFormView* pViewAsFormView = dynamic_cast< FmFormView* >( &rView );
135
17
    if ( pViewAsFormView )
136
17
        pViewAsFormView->RemoveControlContainer(mpImpl->mxControlContainer);
137
138
    // dispose the control container
139
17
    mpImpl->mxControlContainer->dispose();
140
17
}
141
142
SdrPageView& SdrPageWindow::GetPageView() const
143
2.16M
{
144
2.16M
    return mpImpl->mrPageView;
145
2.16M
}
146
147
SdrPaintWindow& SdrPageWindow::GetPaintWindow() const
148
2.12M
{
149
2.12M
    return *mpImpl->mpPaintWindow;
150
2.12M
}
151
152
const SdrPaintWindow* SdrPageWindow::GetOriginalPaintWindow() const
153
17
{
154
17
    return mpImpl->mpOriginalPaintWindow;
155
17
}
156
157
// OVERLAY MANAGER
158
rtl::Reference< sdr::overlay::OverlayManager > const & SdrPageWindow::GetOverlayManager() const
159
0
{
160
0
    return GetPaintWindow().GetOverlayManager();
161
0
}
162
163
SdrPaintWindow* SdrPageWindow::patchPaintWindow(SdrPaintWindow& rPaintWindow)
164
0
{
165
0
    if (!mpImpl)
166
0
        return nullptr;
167
168
0
    if (!mpImpl->mpOriginalPaintWindow)
169
0
    {
170
        // first patch
171
0
        mpImpl->mpOriginalPaintWindow = mpImpl->mpPaintWindow;
172
0
        mpImpl->mpPaintWindow = &rPaintWindow;
173
0
        mpImpl->mpOriginalPaintWindow->setPatched(&rPaintWindow);
174
0
        return mpImpl->mpOriginalPaintWindow;
175
0
    }
176
0
    else
177
0
    {
178
        // second or more patch
179
0
        auto pPreviousPaintWindow = mpImpl->mpPaintWindow;
180
0
        mpImpl->mpPaintWindow = &rPaintWindow;
181
0
        mpImpl->mpOriginalPaintWindow->setPatched(&rPaintWindow);
182
0
        return pPreviousPaintWindow;
183
0
    }
184
0
}
185
186
void SdrPageWindow::unpatchPaintWindow(SdrPaintWindow* pPreviousPaintWindow)
187
0
{
188
0
    if (pPreviousPaintWindow == mpImpl->mpOriginalPaintWindow)
189
0
    {
190
        // first patch
191
0
        mpImpl->mpPaintWindow = mpImpl->mpOriginalPaintWindow;
192
0
        mpImpl->mpOriginalPaintWindow->setPatched(nullptr);
193
0
        mpImpl->mpOriginalPaintWindow = nullptr;
194
0
    }
195
0
    else
196
0
    {
197
        // second or more patch
198
0
        mpImpl->mpPaintWindow = pPreviousPaintWindow;
199
0
        mpImpl->mpOriginalPaintWindow->setPatched(pPreviousPaintWindow);
200
0
    }
201
0
}
202
203
void SdrPageWindow::PrePaint()
204
0
{
205
    // give OC the chance to do ProcessDisplay preparations
206
0
    if(HasObjectContact())
207
0
    {
208
0
        GetObjectContact().PrepareProcessDisplay();
209
0
    }
210
0
}
211
212
void SdrPageWindow::PrepareRedraw(const vcl::Region& rReg)
213
60.5k
{
214
    // give OC the chance to do ProcessDisplay preparations
215
60.5k
    if(HasObjectContact())
216
0
    {
217
0
        GetObjectContact().PrepareProcessDisplay();
218
0
    }
219
220
    // if necessary, remember changed RedrawArea at PaintWindow for usage with
221
    // overlay and PreRenderDevice stuff
222
60.5k
    GetPaintWindow().SetRedrawRegion(rReg);
223
60.5k
}
224
225
226
// clip test
227
#ifdef CLIPPER_TEST
228
#include <svx/svdopath.hxx>
229
#include <basegfx/numeric/ftools.hxx>
230
#include <basegfx/polygon/b2dpolygon.hxx>
231
#include <tools/helpers.hxx>
232
#include <basegfx/polygon/b2dpolygoncutandtouch.hxx>
233
#include <basegfx/polygon/b2dpolypolygontools.hxx>
234
#include <basegfx/polygon/b2dpolygontools.hxx>
235
#include <basegfx/polygon/b2dpolygonclipper.hxx>
236
237
// for ::std::sort
238
#include <algorithm>
239
240
namespace
241
{
242
    void impPaintStrokePolygon(const basegfx::B2DPolygon& rCandidate, OutputDevice& rOutDev, Color aColor)
243
    {
244
        basegfx::B2DPolygon aCandidate(rCandidate);
245
246
        if(aCandidate.areControlPointsUsed())
247
        {
248
            aCandidate = basegfx::utils::adaptiveSubdivideByAngle(rCandidate);
249
        }
250
251
        if(aCandidate.count())
252
        {
253
            const sal_uInt32 nLoopCount(aCandidate.isClosed() ? aCandidate.count() : aCandidate.count() - 1);
254
            rOutDev.SetFillColor();
255
            rOutDev.SetLineColor(aColor);
256
257
            for(sal_uInt32 a(0); a < nLoopCount; a++)
258
            {
259
                const basegfx::B2DPoint aBStart(aCandidate.getB2DPoint(a));
260
                const basegfx::B2DPoint aBEnd(aCandidate.getB2DPoint((a + 1) % aCandidate.count()));
261
                const Point aStart(basegfx::fround<tools::Long>(aBStart.getX()),
262
                                   basegfx::fround<tools::Long>(aBStart.getY()));
263
                const Point aEnd(basegfx::fround<tools::Long>(aBEnd.getX()),
264
                                 basegfx::fround<tools::Long>(aBEnd.getY()));
265
                rOutDev.DrawLine(aStart, aEnd);
266
            }
267
        }
268
    }
269
270
    void impTryTest(const SdrPageView& rPageView, OutputDevice& rOutDev)
271
    {
272
        if(rPageView.GetPage() && rPageView.GetPage()->GetObjCount() >= 2)
273
        {
274
            SdrPage* pPage = rPageView.GetPage();
275
            SdrObject* pObjA = pPage->GetObj(0);
276
277
            if(dynamic_cast<const SdrPathObj*>( pObjA))
278
            {
279
                basegfx::B2DPolyPolygon aPolyA(pObjA->GetPathPoly());
280
                aPolyA = basegfx::utils::correctOrientations(aPolyA);
281
282
                basegfx::B2DPolyPolygon aPolyB;
283
284
                for (const rtl::Reference<SdrObject>& pObjB : *rPageView.GetPage())
285
                {
286
                    if(dynamic_cast<const SdrPathObj*>( pObjB.get()))
287
                    {
288
                        basegfx::B2DPolyPolygon aCandidate(pObjB->GetPathPoly());
289
                        aCandidate = basegfx::utils::correctOrientations(aCandidate);
290
                        aPolyB.append(aCandidate);
291
                    }
292
                }
293
294
                if(aPolyA.count() && aPolyA.isClosed() && aPolyB.count())
295
                {
296
                    // poly A is the clipregion, clip poly b against it. Algo depends on
297
                    // poly b being closed.
298
                    basegfx::B2DPolyPolygon aResult(basegfx::utils::clipPolyPolygonOnPolyPolygon(aPolyB, aPolyA));
299
300
                    for(auto const& rPolygon : aResult)
301
                    {
302
                        int nR = comphelper::rng::uniform_int_distribution(0, 254);
303
                        int nG = comphelper::rng::uniform_int_distribution(0, 254);
304
                        int nB = comphelper::rng::uniform_int_distribution(0, 254);
305
                        Color aColor(nR, nG, nB);
306
                        impPaintStrokePolygon(rPolygon, rOutDev, aColor);
307
                    }
308
                }
309
            }
310
        }
311
    }
312
} // end of anonymous namespace
313
#endif // CLIPPER_TEST
314
315
316
void SdrPageWindow::RedrawAll( sdr::contact::ViewObjectContactRedirector* pRedirector )
317
0
{
318
    // set Redirector
319
0
    GetObjectContact().SetViewObjectContactRedirector(pRedirector);
320
321
    // set PaintingPageView
322
0
    const SdrView& rView = mpImpl->mrPageView.GetView();
323
0
    SdrModel& rModel = rView.GetModel();
324
325
    // get to be processed layers
326
0
    const bool bPrinter(GetPaintWindow().OutputToPrinter());
327
0
    SdrLayerIDSet aProcessLayers = bPrinter ? mpImpl->mrPageView.GetPrintableLayers() : mpImpl->mrPageView.GetVisibleLayers();
328
329
    // create PaintInfoRec; use Rectangle only temporarily
330
0
    const vcl::Region& rRegion = GetPaintWindow().GetRedrawRegion();
331
332
    // create processing data
333
0
    sdr::contact::DisplayInfo aDisplayInfo;
334
335
    // Draw all layers. do NOT draw form layer from CompleteRedraw, this is done separately
336
    // as a single layer paint
337
0
    const SdrLayerAdmin& rLayerAdmin = rModel.GetLayerAdmin();
338
0
    const SdrLayerID nControlLayerId = rLayerAdmin.GetLayerID(rLayerAdmin.GetControlLayerName());
339
0
    aProcessLayers.Clear(nControlLayerId);
340
341
    // still something to paint?
342
0
    if(!aProcessLayers.IsEmpty())
343
0
    {
344
0
        aDisplayInfo.SetProcessLayers(aProcessLayers);
345
346
        // Set region as redraw area
347
0
        aDisplayInfo.SetRedrawArea(rRegion);
348
349
        // paint page
350
0
        GetObjectContact().ProcessDisplay(aDisplayInfo);
351
0
    }
352
353
    // reset redirector
354
0
    GetObjectContact().SetViewObjectContactRedirector(nullptr);
355
356
    // LineClip test
357
#ifdef CLIPPER_TEST
358
    if(true)
359
    {
360
        impTryTest(GetPageView(), GetPaintWindow().GetOutputDevice());
361
    }
362
#endif // CLIPPER_TEST
363
0
}
364
365
void SdrPageWindow::RedrawLayer(const SdrLayerID* pId,
366
        sdr::contact::ViewObjectContactRedirector* pRedirector,
367
        basegfx::B2IRectangle const*const pPageFrame)
368
182k
{
369
    // set redirector
370
182k
    GetObjectContact().SetViewObjectContactRedirector(pRedirector);
371
372
    // set PaintingPageView
373
182k
    const SdrView& rView = mpImpl->mrPageView.GetView();
374
182k
    SdrModel& rModel = rView.GetModel();
375
376
    // get the layers to process
377
182k
    const bool bPrinter(GetPaintWindow().OutputToPrinter());
378
182k
    SdrLayerIDSet aProcessLayers = bPrinter ? mpImpl->mrPageView.GetPrintableLayers() : mpImpl->mrPageView.GetVisibleLayers();
379
380
    // is the given layer visible at all?
381
182k
    if(aProcessLayers.IsSet(*pId))
382
182k
    {
383
        // find out if we are painting the ControlLayer
384
182k
        const SdrLayerAdmin& rLayerAdmin = rModel.GetLayerAdmin();
385
182k
        const SdrLayerID nControlLayerId = rLayerAdmin.GetLayerID(rLayerAdmin.GetControlLayerName());
386
182k
        const bool bControlLayerProcessingActive(nControlLayerId == *pId);
387
388
        // create PaintInfoRec, use Rectangle only temporarily
389
182k
        const vcl::Region& rRegion = GetPaintWindow().GetRedrawRegion();
390
391
        // create processing data
392
182k
        sdr::contact::DisplayInfo aDisplayInfo;
393
394
        // is it the control layer? If Yes, set flag
395
182k
        aDisplayInfo.SetControlLayerProcessingActive(bControlLayerProcessingActive);
396
397
        // Draw just the one given layer
398
182k
        aProcessLayers.ClearAll();
399
182k
        aProcessLayers.Set(*pId);
400
401
182k
        aDisplayInfo.SetProcessLayers(aProcessLayers);
402
403
        // Set region as redraw area
404
182k
        aDisplayInfo.SetRedrawArea(rRegion);
405
406
        // Writer or calc, coming from original RedrawOneLayer.
407
        // #i72889# no page painting or MasterPage painting for layer painting
408
182k
        const bool bOldPageDecorationAllowed(GetPageView().GetView().IsPageDecorationAllowed());
409
182k
        const bool bOldMasterPageVisualizationAllowed(GetPageView().GetView().IsMasterPageVisualizationAllowed());
410
182k
        GetPageView().GetView().SetPageDecorationAllowed(false);
411
182k
        GetPageView().GetView().SetMasterPageVisualizationAllowed(false);
412
413
182k
        if (pPageFrame) // Writer page frame for anchor based clipping
414
122k
        {
415
122k
            aDisplayInfo.SetWriterPageFrame(*pPageFrame);
416
122k
        }
417
418
        // paint page
419
182k
        GetObjectContact().ProcessDisplay(aDisplayInfo);
420
421
        // reset temporarily changed flags
422
182k
        GetPageView().GetView().SetPageDecorationAllowed(bOldPageDecorationAllowed);
423
182k
        GetPageView().GetView().SetMasterPageVisualizationAllowed(bOldMasterPageVisualizationAllowed);
424
182k
    }
425
426
    // reset redirector
427
182k
    GetObjectContact().SetViewObjectContactRedirector(nullptr);
428
182k
}
429
430
// Invalidate call, used from ObjectContact(OfPageView) in InvalidatePartOfView(...)
431
void SdrPageWindow::InvalidatePageWindow(const basegfx::B2DRange& rRange)
432
0
{
433
0
    if (GetPageView().IsVisible() && GetPaintWindow().OutputToWindow())
434
0
    {
435
0
        OutputDevice& rWindow(GetPaintWindow().GetOutputDevice());
436
0
        basegfx::B2DRange aDiscreteRange(rRange);
437
0
        aDiscreteRange.transform(rWindow.GetViewTransformation());
438
439
0
        if (SvtOptionsDrawinglayer::IsAntiAliasing())
440
0
        {
441
            // invalidate one discrete unit more under the assumption that AA
442
            // needs one pixel more
443
0
            aDiscreteRange.grow(1.0);
444
0
        }
445
446
        // If the shapes use negative X coordinates, make them positive before sending
447
        // the invalidation rectangle.
448
0
        bool bNegativeX = mpImpl->mrPageView.GetView().IsNegativeX();
449
450
0
        const tools::Rectangle aVCLDiscreteRectangle(
451
0
            static_cast<tools::Long>(bNegativeX ? std::max(0.0, ceil(-aDiscreteRange.getMaxX())) : floor(aDiscreteRange.getMinX())),
452
0
            static_cast<tools::Long>(floor(aDiscreteRange.getMinY())),
453
0
            static_cast<tools::Long>(bNegativeX ? std::max(0.0, floor(-aDiscreteRange.getMinX())) : ceil(aDiscreteRange.getMaxX())),
454
0
            static_cast<tools::Long>(ceil(aDiscreteRange.getMaxY())));
455
456
0
        const bool bWasMapModeEnabled(rWindow.IsMapModeEnabled());
457
0
        rWindow.EnableMapMode(false);
458
0
        GetPageView().GetView().InvalidateOneWin(rWindow, aVCLDiscreteRectangle);
459
0
        rWindow.EnableMapMode(bWasMapModeEnabled);
460
0
    }
461
0
    else if (comphelper::LibreOfficeKit::isActive())
462
0
    {
463
        // we don't really have to have a paint window with LOK; OTOH we know
464
        // that the drawinglayer units are 100ths of mm, so they are easy to
465
        // convert to twips
466
467
        // If the shapes use negative X coordinates, make them positive before sending
468
        // the invalidation rectangle.
469
0
        bool bNegativeX = mpImpl->mrPageView.GetView().IsNegativeX();
470
0
        const tools::Rectangle aRect100thMM(
471
0
            static_cast<tools::Long>(bNegativeX ? std::max(0.0, ceil(-rRange.getMaxX())) : floor(rRange.getMinX())),
472
0
            static_cast<tools::Long>(floor(rRange.getMinY())),
473
0
            static_cast<tools::Long>(bNegativeX ? std::max(0.0, floor(-rRange.getMinX())) : ceil(rRange.getMaxX())),
474
0
            static_cast<tools::Long>(ceil(rRange.getMaxY())));
475
476
0
        const tools::Rectangle aRectTwips = o3tl::convert(aRect100thMM, o3tl::Length::mm100, o3tl::Length::twip);
477
478
0
        if (SfxViewShell* pViewShell = SfxViewShell::Current())
479
0
            SfxLokHelper::notifyInvalidation(pViewShell, &aRectTwips);
480
0
    }
481
0
}
482
483
// ObjectContact section
484
const sdr::contact::ObjectContact& SdrPageWindow::GetObjectContact() const
485
0
{
486
0
    if (!mpImpl->mpObjectContact)
487
0
    {
488
0
        mpImpl->mpObjectContact = GetPageView().GetView().createViewSpecificObjectContact(
489
0
            const_cast<SdrPageWindow&>(*this),
490
0
            "svx::svdraw::SdrPageWindow mpObjectContact");
491
0
    }
492
493
0
    return *mpImpl->mpObjectContact;
494
0
}
495
496
sdr::contact::ObjectContact& SdrPageWindow::GetObjectContact()
497
548k
{
498
548k
    if (!mpImpl->mpObjectContact)
499
60.5k
    {
500
60.5k
        mpImpl->mpObjectContact = GetPageView().GetView().createViewSpecificObjectContact(
501
60.5k
             *this,
502
60.5k
             "svx::svdraw::SdrPageWindow mpObjectContact" );
503
60.5k
    }
504
505
548k
    return *mpImpl->mpObjectContact;
506
548k
}
507
508
bool SdrPageWindow::HasObjectContact() const
509
60.5k
{
510
60.5k
    return mpImpl->mpObjectContact != nullptr;
511
60.5k
}
512
513
// #i26631#
514
void SdrPageWindow::ResetObjectContact()
515
64.2k
{
516
64.2k
    if (mpImpl->mpObjectContact)
517
60.5k
    {
518
60.5k
        delete mpImpl->mpObjectContact;
519
60.5k
        mpImpl->mpObjectContact = nullptr;
520
60.5k
    }
521
64.2k
}
522
523
void SdrPageWindow::SetDesignMode( bool _bDesignMode ) const
524
0
{
525
0
    const sdr::contact::ObjectContactOfPageView* pOC = dynamic_cast< const sdr::contact::ObjectContactOfPageView* >( &GetObjectContact() );
526
0
    DBG_ASSERT( pOC, "SdrPageWindow::SetDesignMode: invalid object contact!" );
527
0
    if ( pOC )
528
0
        pOC->SetUNOControlsDesignMode( _bDesignMode );
529
0
}
530
531
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */