Coverage Report

Created: 2026-04-09 11:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sd/source/ui/view/sdview.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 <config_features.h>
21
22
#include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
23
#include <com/sun/star/embed/XEmbeddedObject.hpp>
24
#include <com/sun/star/linguistic2/XSpellChecker1.hpp>
25
26
#include <View.hxx>
27
#include <slideshow.hxx>
28
#include <avmedia/mediawindow.hxx>
29
#include <editeng/outlobj.hxx>
30
#include <editeng/unolingu.hxx>
31
#include <o3tl/deleter.hxx>
32
#include <svx/obj3d.hxx>
33
#include <svx/fmview.hxx>
34
#include <editeng/outliner.hxx>
35
#include <svx/svdograf.hxx>
36
#include <svx/svdoole2.hxx>
37
#include <svx/svdundo.hxx>
38
39
#include <vcl/settings.hxx>
40
41
#include <officecfg/Office/Common.hxx>
42
#include <officecfg/Office/Impress.hxx>
43
#include <sfx2/dispatch.hxx>
44
#include <svx/svdpagv.hxx>
45
#include <svx/svdoutl.hxx>
46
#include <svx/sdr/contact/displayinfo.hxx>
47
#include <unotools/configmgr.hxx>
48
49
#include <svx/svdetc.hxx>
50
#include <editeng/editstat.hxx>
51
52
#include <sfx2/viewfrm.hxx>
53
#include <toolkit/helper/vclunohelper.hxx>
54
#include <svx/xfillit0.hxx>
55
56
#include <app.hrc>
57
#include <strings.hrc>
58
#include <Window.hxx>
59
#include <Client.hxx>
60
#include <drawdoc.hxx>
61
#include <DrawDocShell.hxx>
62
#include <sdmod.hxx>
63
#include <sdpage.hxx>
64
#include <sdresid.hxx>
65
#include <unokywds.hxx>
66
#include <ViewClipboard.hxx>
67
#include <undo/undomanager.hxx>
68
#include <svx/sdr/contact/viewobjectcontact.hxx>
69
#include <svx/sdr/contact/viewcontact.hxx>
70
#include <svx/svdotable.hxx>
71
#include <EventMultiplexer.hxx>
72
#include <ViewShellBase.hxx>
73
#include <ViewShell.hxx>
74
75
#include <basegfx/polygon/b2dpolygontools.hxx>
76
#include <basegfx/color/bcolor.hxx>
77
#include <drawinglayer/attribute/lineattribute.hxx>
78
#include <drawinglayer/attribute/strokeattribute.hxx>
79
#include <drawinglayer/primitive2d/textlayoutdevice.hxx>
80
#include <drawinglayer/primitive2d/PolygonStrokePrimitive2D.hxx>
81
#include <svx/sdr/contact/objectcontact.hxx>
82
#include <svx/sdr/table/tablecontroller.hxx>
83
#include <basegfx/matrix/b2dhommatrix.hxx>
84
#include <drawinglayer/primitive2d/textprimitive2d.hxx>
85
#include <svx/unoapi.hxx>
86
#include <basegfx/matrix/b2dhommatrixtools.hxx>
87
#include <comphelper/lok.hxx>
88
#include <sfx2/lokhelper.hxx>
89
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
90
#include <DrawController.hxx>
91
92
#include <memory>
93
#include <numeric>
94
95
using namespace com::sun::star;
96
using namespace com::sun::star::uno;
97
using namespace sdr::table;
98
namespace sd {
99
100
View::View(
101
    SdDrawDocument& rDrawDoc,
102
    OutputDevice* pOutDev,
103
    ViewShell* pViewShell)
104
0
:   FmFormView(rDrawDoc, pOutDev),
105
0
    mrDoc(rDrawDoc),
106
0
    mpDocSh(rDrawDoc.GetDocSh()),
107
0
    mpViewSh(pViewShell),
108
0
    mpDropMarkerObj(nullptr),
109
0
    mnDragSrcPgNum(SDRPAGE_NOTFOUND),
110
0
    mnAction(DND_ACTION_NONE),
111
0
    maDropErrorIdle("sd View DropError"),
112
0
    maDropInsertFileIdle("sd View DropInsertFile"),
113
0
    mnLockRedrawSmph(0),
114
0
    mbIsDropAllowed(true),
115
0
    maSmartTags(*this),
116
0
    mpClipboard (new ViewClipboard (*this))
117
0
{
118
    // #i73602# Use default from the configuration
119
0
    SetBufferedOverlayAllowed(!comphelper::IsFuzzing() && officecfg::Office::Common::Drawinglayer::OverlayBuffer_DrawImpress::get());
120
121
    // #i74769#, #i75172# Use default from the configuration
122
0
    SetBufferedOutputAllowed(!comphelper::IsFuzzing() && officecfg::Office::Common::Drawinglayer::PaintBuffer_DrawImpress::get());
123
124
0
    EnableExtendedKeyInputDispatcher(false);
125
0
    EnableExtendedMouseEventDispatcher(false);
126
127
0
    SetUseIncompatiblePathCreateInterface(false);
128
129
0
    SetMinMoveDistancePixel(2);
130
0
    SetHitTolerancePixel(2);
131
0
    SetMeasureLayer(sUNO_LayerName_measurelines);
132
133
    // Timer for delayed drop (has to be for MAC)
134
0
    maDropErrorIdle.SetInvokeHandler( LINK(this, View, DropErrorHdl) );
135
0
    maDropInsertFileIdle.SetInvokeHandler( LINK(this, View, DropInsertFileHdl) );
136
0
}
137
138
void View::ImplClearDrawDropMarker()
139
0
{
140
0
    mpDropMarker.reset();
141
0
}
142
143
View::~View()
144
0
{
145
0
    maSmartTags.Dispose();
146
147
    // release content of selection clipboard, if we own the content
148
0
    ClearSelectionClipboard();
149
150
0
#if HAVE_FEATURE_AVMEDIA
151
0
    if (mxDropMediaSizeListener)
152
0
    {
153
0
        suppress_fun_call_w_exception(mxDropMediaSizeListener->dispose());
154
0
        mxDropMediaSizeListener.clear();
155
0
    }
156
0
#endif
157
158
0
    maDropErrorIdle.Stop();
159
0
    maDropInsertFileIdle.Stop();
160
161
0
    ImplClearDrawDropMarker();
162
163
0
    while(PaintWindowCount())
164
0
    {
165
        // remove all registered OutDevs
166
0
        suppress_fun_call_w_exception(DeleteDeviceFromPaintView(*GetFirstOutputDevice()));
167
0
    }
168
0
}
169
170
namespace {
171
172
class ViewRedirector : public sdr::contact::ViewObjectContactRedirector
173
{
174
public:
175
    ViewRedirector();
176
177
    // all default implementations just call the same methods at the original. To do something
178
    // different, override the method and at least do what the method does.
179
    virtual void createRedirectedPrimitive2DSequence(
180
        const sdr::contact::ViewObjectContact& rOriginal,
181
        const sdr::contact::DisplayInfo& rDisplayInfo,
182
        drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor) override;
183
};
184
185
}
186
187
ViewRedirector::ViewRedirector()
188
0
{
189
0
}
190
191
void ViewRedirector::createRedirectedPrimitive2DSequence(
192
    const sdr::contact::ViewObjectContact& rOriginal,
193
    const sdr::contact::DisplayInfo& rDisplayInfo,
194
    drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor)
195
0
{
196
0
    SdrObject* pObject = rOriginal.GetViewContact().TryToGetSdrObject();
197
0
    SdrPage* pSdrPage = pObject ? pObject->getSdrPageFromSdrObject() : nullptr;
198
0
    if(!pObject || !pSdrPage)
199
0
    {
200
        // not a SdrObject visualisation (maybe e.g. page) or no page
201
0
        sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(rOriginal, rDisplayInfo, rVisitor);
202
0
        return;
203
0
    }
204
205
0
    const bool bDoCreateGeometry(pSdrPage->checkVisibility( rOriginal, rDisplayInfo, true ));
206
207
0
    if(!bDoCreateGeometry &&
208
0
        (( pObject->GetObjInventor() != SdrInventor::Default ) || ( pObject->GetObjIdentifier() != SdrObjKind::Page )) )
209
0
        return;
210
211
0
    PresObjKind eKind(PresObjKind::NONE);
212
0
    const bool bSubContentProcessing(rDisplayInfo.GetSubContentActive());
213
0
    const bool bIsMasterPageObject(pSdrPage->IsMasterPage());
214
0
    const bool bIsPrinting(rOriginal.GetObjectContact().isOutputToPrinter());
215
0
    const SdrPageView* pPageView = rOriginal.GetObjectContact().TryToGetSdrPageView();
216
0
    const SdrPage* pVisualizedPage = GetSdrPageFromXDrawPage(rOriginal.GetObjectContact().getViewInformation2D().getVisualizedPage());
217
0
    const SdPage* pObjectsSdPage = dynamic_cast< SdPage* >(pSdrPage);
218
0
    const bool bIsInsidePageObj(pPageView && pPageView->GetPage() != pVisualizedPage);
219
220
    // check if we need to draw a placeholder border. Never do it for
221
    // objects inside a SdrPageObj and never when printing
222
0
    if(!bIsInsidePageObj && !bIsPrinting)
223
0
    {
224
0
        bool bCreateOutline(false);
225
226
0
        if( pObject->IsEmptyPresObj() && DynCastSdrTextObj( pObject ) !=  nullptr )
227
0
        {
228
0
            if( !bSubContentProcessing || !pObject->IsNotVisibleAsMaster() )
229
0
            {
230
0
                eKind = pObjectsSdPage ? pObjectsSdPage->GetPresObjKind(pObject) : PresObjKind::NONE;
231
0
                bCreateOutline = true;
232
0
            }
233
0
        }
234
0
        else if( ( pObject->GetObjInventor() == SdrInventor::Default ) && ( pObject->GetObjIdentifier() == SdrObjKind::Text ) )
235
0
        {
236
0
            if( pObjectsSdPage )
237
0
            {
238
0
                eKind = pObjectsSdPage->GetPresObjKind(pObject);
239
240
0
                if((eKind == PresObjKind::Footer) || (eKind == PresObjKind::Header) || (eKind == PresObjKind::DateTime) || (eKind == PresObjKind::SlideNumber) )
241
0
                {
242
0
                    if( !bSubContentProcessing )
243
0
                    {
244
                        // only draw a boundary for header&footer objects on the masterpage itself
245
0
                        bCreateOutline = true;
246
0
                    }
247
0
                }
248
0
            }
249
0
        }
250
0
        else if( ( pObject->GetObjInventor() == SdrInventor::Default ) && ( pObject->GetObjIdentifier() == SdrObjKind::Page ) )
251
0
        {
252
            // only for handout page, else this frame will be created for each
253
            // page preview object in SlideSorter and PagePane
254
0
            if(pObjectsSdPage && PageKind::Handout == pObjectsSdPage->GetPageKind())
255
0
            {
256
0
                bCreateOutline = true;
257
0
            }
258
0
        }
259
0
        if (bCreateOutline)
260
0
            bCreateOutline = officecfg::Office::Impress::Misc::TextObject::ShowBoundary::get();
261
262
0
        if(bCreateOutline)
263
0
        {
264
            // empty presentation objects get a gray frame
265
0
            const svtools::ColorConfig aColorConfig;
266
0
            const svtools::ColorConfigValue aColor( aColorConfig.GetColorValue( svtools::DOCBOUNDARIES ) );
267
268
            // get basic object transformation
269
0
            const basegfx::BColor aRGBColor(aColor.nColor.getBColor());
270
0
            basegfx::B2DHomMatrix aObjectMatrix;
271
0
            basegfx::B2DPolyPolygon aObjectPolyPolygon;
272
0
            pObject->TRGetBaseGeometry(aObjectMatrix, aObjectPolyPolygon);
273
274
            // create dashed border
275
0
            {
276
                // create object polygon
277
0
                basegfx::B2DPolygon aPolygon(basegfx::utils::createUnitPolygon());
278
0
                aPolygon.transform(aObjectMatrix);
279
280
                // create line and stroke attribute
281
0
                ::std::vector< double > aDotDashArray { 160.0, 80.0 };
282
283
0
                const double fFullDotDashLen(::std::accumulate(aDotDashArray.begin(), aDotDashArray.end(), 0.0));
284
0
                const drawinglayer::attribute::LineAttribute aLine(aRGBColor);
285
0
                drawinglayer::attribute::StrokeAttribute aStroke(std::move(aDotDashArray), fFullDotDashLen);
286
287
                // create primitive and add
288
0
                const drawinglayer::primitive2d::Primitive2DReference xRef(new drawinglayer::primitive2d::PolygonStrokePrimitive2D(
289
0
                    std::move(aPolygon),
290
0
                    aLine,
291
0
                    std::move(aStroke)));
292
0
                rVisitor.visit(xRef);
293
0
            }
294
295
            // now paint the placeholder description, but only when masterpage
296
            // is displayed as page directly (MasterPage view)
297
0
            if(!bSubContentProcessing && bIsMasterPageObject)
298
0
            {
299
0
                OUString aObjectString;
300
301
0
                switch( eKind )
302
0
                {
303
0
                    case PresObjKind::Title:
304
0
                    {
305
0
                        if(pObjectsSdPage && pObjectsSdPage->GetPageKind() == PageKind::Standard)
306
0
                        {
307
0
                            static OUString aTitleAreaStr(SdResId(STR_PLACEHOLDER_DESCRIPTION_TITLE));
308
0
                            aObjectString = aTitleAreaStr;
309
0
                        }
310
311
0
                        break;
312
0
                    }
313
0
                    case PresObjKind::Outline:
314
0
                    {
315
0
                        static OUString aOutlineAreaStr(SdResId(STR_PLACEHOLDER_DESCRIPTION_OUTLINE));
316
0
                        aObjectString = aOutlineAreaStr;
317
0
                        break;
318
0
                    }
319
0
                    case PresObjKind::Footer:
320
0
                    {
321
0
                        static OUString aFooterAreaStr(SdResId(STR_PLACEHOLDER_DESCRIPTION_FOOTER));
322
0
                        aObjectString = aFooterAreaStr;
323
0
                        break;
324
0
                    }
325
0
                    case PresObjKind::Header:
326
0
                    {
327
0
                        static OUString aHeaderAreaStr(SdResId(STR_PLACEHOLDER_DESCRIPTION_HEADER));
328
0
                        aObjectString = aHeaderAreaStr;
329
0
                        break;
330
0
                    }
331
0
                    case PresObjKind::DateTime:
332
0
                    {
333
0
                        static OUString aDateTimeStr(SdResId(STR_PLACEHOLDER_DESCRIPTION_DATETIME));
334
0
                        aObjectString = aDateTimeStr;
335
0
                        break;
336
0
                    }
337
0
                    case PresObjKind::Notes:
338
0
                    {
339
0
                        static OUString aDateTimeStr(SdResId(STR_PLACEHOLDER_DESCRIPTION_NOTES));
340
0
                        aObjectString = aDateTimeStr;
341
0
                        break;
342
0
                    }
343
0
                    case PresObjKind::SlideNumber:
344
0
                    {
345
0
                        if(pObjectsSdPage && pObjectsSdPage->GetPageKind() == PageKind::Standard)
346
0
                        {
347
0
                            static OUString aSlideAreaStr(SdResId(STR_PLACEHOLDER_DESCRIPTION_SLIDE));
348
0
                            aObjectString = aSlideAreaStr;
349
0
                        }
350
0
                        else
351
0
                        {
352
0
                            static OUString aNumberAreaStr(SdResId(STR_PLACEHOLDER_DESCRIPTION_NUMBER));
353
0
                            aObjectString = aNumberAreaStr;
354
0
                        }
355
0
                        break;
356
0
                    }
357
0
                    default:
358
0
                    {
359
0
                        break;
360
0
                    }
361
0
                }
362
363
0
                if( !aObjectString.isEmpty() )
364
0
                {
365
                    // decompose object matrix to be able to place text correctly
366
0
                    basegfx::B2DTuple aScale;
367
0
                    basegfx::B2DTuple aTranslate;
368
0
                    double fRotate, fShearX;
369
0
                    aObjectMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
370
371
                    // create font
372
0
                    SdrTextObj* pTextObj = DynCastSdrTextObj( pObject );
373
0
                    const SdrTextVertAdjust eTVA(pTextObj ? pTextObj->GetTextVerticalAdjust() : SDRTEXTVERTADJUST_CENTER);
374
0
                    vcl::Font aScaledVclFont;
375
376
                    // use a text size factor to get more reliable text sizes from the text layouter
377
                    // (and from vcl), tipp from HDU
378
0
                    static const sal_uInt32 nTextSizeFactor(100);
379
380
                    // use a factor to get more linear text size calculations
381
0
                    aScaledVclFont.SetFontHeight( 500 * nTextSizeFactor );
382
383
                    // get basic geometry and get text size
384
0
                    drawinglayer::primitive2d::TextLayouterDevice aTextLayouter;
385
0
                    aTextLayouter.setFont(aScaledVclFont);
386
0
                    const sal_Int32 nTextLength(aObjectString.getLength());
387
388
                    // do not forget to use the factor again to get the width for the 500
389
0
                    const double fTextWidth(aTextLayouter.getTextWidth(aObjectString, 0, nTextLength) * (1.0 / nTextSizeFactor));
390
0
                    const double fTextHeight(aTextLayouter.getTextHeight() * (1.0 / nTextSizeFactor));
391
392
                    // calculate text primitive position. If text is at bottom, use top for
393
                    // the extra text and vice versa
394
0
                    const double fHorDist(125);
395
0
                    const double fVerDist(125);
396
0
                    const double fPosX((aTranslate.getX() + aScale.getX()) - fTextWidth - fHorDist);
397
0
                    const double fPosY((SDRTEXTVERTADJUST_BOTTOM == eTVA)
398
0
                        ? aTranslate.getY() - fVerDist + fTextHeight
399
0
                        : (aTranslate.getY() + aScale.getY()) - fVerDist);
400
401
                    // get font attributes; use normally scaled font
402
0
                    vcl::Font aVclFont;
403
0
                    basegfx::B2DVector aTextSizeAttribute;
404
405
0
                    aVclFont.SetFontHeight( 500 );
406
407
0
                    drawinglayer::attribute::FontAttribute aFontAttribute(
408
0
                        drawinglayer::primitive2d::getFontAttributeFromVclFont(
409
0
                            aTextSizeAttribute,
410
0
                            aVclFont,
411
0
                            false,
412
0
                            false));
413
414
                    // fill text matrix
415
0
                    const basegfx::B2DHomMatrix aTextMatrix(basegfx::utils::createScaleShearXRotateTranslateB2DHomMatrix(
416
0
                        aTextSizeAttribute.getX(), aTextSizeAttribute.getY(),
417
0
                        fShearX,
418
0
                        fRotate,
419
0
                        fPosX, fPosY));
420
421
                    // create DXTextArray (can be empty one)
422
0
                    ::std::vector< double > aDXArray{};
423
424
                    // create locale; this may need some more information in the future
425
0
                    css::lang::Locale aLocale;
426
427
                    // create primitive and add
428
0
                    const drawinglayer::primitive2d::Primitive2DReference xRef(
429
0
                        new drawinglayer::primitive2d::TextSimplePortionPrimitive2D(
430
0
                            aTextMatrix,
431
0
                            aObjectString,
432
0
                            0,
433
0
                            nTextLength,
434
0
                            std::move(aDXArray),
435
0
                            {},
436
0
                            std::move(aFontAttribute),
437
0
                            std::move(aLocale),
438
0
                            aRGBColor));
439
0
                    rVisitor.visit(xRef);
440
0
                }
441
0
            }
442
0
        }
443
0
    }
444
445
0
    if(bDoCreateGeometry)
446
0
    {
447
0
        sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(
448
0
            rOriginal,
449
0
            rDisplayInfo, rVisitor);
450
0
    }
451
0
}
452
453
namespace
454
{
455
    void setOutlinerBgFromPage(::Outliner& rOutl, const SdrPageView& rPgView, bool bScreenDisplay)
456
0
    {
457
0
        SdrPage* pPage = rPgView.GetPage();
458
0
        if (pPage)
459
0
        {
460
            // #i75566# Name change GetBackgroundColor -> GetPageBackgroundColor and
461
            // hint value if screen display. Only then the AutoColor mechanisms shall be applied
462
0
            rOutl.SetBackgroundColor(pPage->GetPageBackgroundColor(&rPgView, bScreenDisplay));
463
0
        }
464
0
    }
465
}
466
467
/**
468
 * The event will be forwarded to the View
469
 */
470
void View::CompleteRedraw(OutputDevice* pOutDev, const vcl::Region& rReg, sdr::contact::ViewObjectContactRedirector* pRedirector /*=0*/)
471
0
{
472
    // execute ??
473
0
    if (mnLockRedrawSmph != 0)
474
0
        return;
475
476
0
    SdrPageView* pPgView = GetSdrPageView();
477
478
0
    if (pPgView)
479
0
    {
480
0
        SdPage* pPage = static_cast<SdPage*>( pPgView->GetPage() );
481
0
        if( pPage )
482
0
        {
483
0
            SdrOutliner& rOutl = mrDoc.GetDrawOutliner();
484
0
            bool bScreenDisplay(true);
485
486
            // #i75566# printing; suppress AutoColor BackgroundColor generation
487
            // for visibility reasons by giving GetPageBackgroundColor()
488
            // the needed hint
489
            // #i75566# PDF export; suppress AutoColor BackgroundColor generation (see printing)
490
0
            if (pOutDev && ((OUTDEV_PRINTER == pOutDev->GetOutDevType())
491
0
                    || (OUTDEV_PDF == pOutDev->GetOutDevType())))
492
0
                bScreenDisplay = false;
493
494
0
            setOutlinerBgFromPage(rOutl, *pPgView, bScreenDisplay);
495
0
        }
496
0
    }
497
498
0
    ViewRedirector aViewRedirector;
499
0
    FmFormView::CompleteRedraw(pOutDev, rReg, pRedirector ? pRedirector : &aViewRedirector);
500
0
}
501
502
void View::MarkListHasChanged()
503
0
{
504
0
    FmFormView::MarkListHasChanged();
505
506
0
    const SdrMarkList& rMarkList = GetMarkedObjectList();
507
0
    if( rMarkList.GetMarkCount() > 0 )
508
0
        maSmartTags.deselect();
509
0
}
510
511
bool View::SetAttributes(const SfxItemSet& rSet, bool bReplaceAll, bool /*bSlide*/, bool /*bMaster*/)
512
0
{
513
0
    bool bOk = FmFormView::SetAttributes(rSet, bReplaceAll);
514
0
    return bOk;
515
0
}
516
517
void View::GetAttributes( SfxItemSet& rTargetSet, bool bOnlyHardAttr ) const
518
0
{
519
0
    FmFormView::GetAttributes( rTargetSet, bOnlyHardAttr );
520
0
}
521
522
/**
523
 * Is a presentation object selected?
524
 */
525
bool View::IsPresObjSelected(bool bOnPage, bool bOnMasterPage, bool bCheckPresObjListOnly, bool bCheckLayoutOnly) const
526
0
{
527
0
    SdrMarkList* pMarkList;
528
529
0
    if (mnDragSrcPgNum != SDRPAGE_NOTFOUND &&
530
0
        mnDragSrcPgNum != GetSdrPageView()->GetPage()->GetPageNum())
531
0
    {
532
        /* Drag&Drop is in progress
533
           Source and destination page are different:
534
           we use the saved mark list */
535
0
        pMarkList = mpDragSrcMarkList.get();
536
0
    }
537
0
    else
538
0
    {
539
        // We use the current mark list
540
0
        pMarkList = new SdrMarkList(GetMarkedObjectList());
541
0
    }
542
543
0
    SdrMark* pMark;
544
0
    SdPage* pPage;
545
546
0
    bool bSelected = false;
547
0
    bool bMasterPage = false;
548
549
0
    for (size_t nMark = pMarkList->GetMarkCount(); nMark && !bSelected; )
550
0
    {
551
0
        --nMark;
552
        // Backwards through mark list
553
0
        pMark = pMarkList->GetMark(nMark);
554
0
        SdrObject* pObj = pMark->GetMarkedSdrObj();
555
556
0
        if ( pObj && ( bCheckPresObjListOnly || pObj->IsEmptyPresObj() || pObj->GetUserCall() ) )
557
0
        {
558
0
            pPage = static_cast<SdPage*>( pObj->getSdrPageFromSdrObject() );
559
0
            bMasterPage = pPage && pPage->IsMasterPage();
560
561
0
            if ( (bMasterPage && bOnMasterPage) || (!bMasterPage && bOnPage) )
562
0
            {
563
0
                if ( pPage && pPage->IsPresObj(pObj) )
564
0
                {
565
0
                    if( bCheckLayoutOnly )
566
0
                    {
567
0
                        PresObjKind eKind = pPage->GetPresObjKind(pObj);
568
569
0
                        if((eKind != PresObjKind::Footer) && (eKind != PresObjKind::Header) && (eKind != PresObjKind::DateTime) && (eKind != PresObjKind::SlideNumber) )
570
0
                            bSelected = true;
571
0
                    }
572
0
                    else
573
0
                    {
574
0
                        bSelected = true;
575
0
                    }
576
0
                }
577
0
            }
578
0
        }
579
0
    }
580
581
0
    if (pMarkList != mpDragSrcMarkList.get())
582
0
    {
583
0
       delete pMarkList;
584
0
    }
585
586
0
    return bSelected;
587
0
}
588
589
void View::SelectAll()
590
0
{
591
0
    if ( IsTextEdit() )
592
0
    {
593
0
        OutlinerView* pOLV = GetTextEditOutlinerView();
594
0
        const ::Outliner* pOutliner = GetTextEditOutliner();
595
0
        pOLV->SelectRange( 0, pOutliner->GetParagraphCount() );
596
0
    }
597
0
    else
598
0
    {
599
0
        MarkAll();
600
0
    }
601
0
}
602
603
bool View::SetStyleSheet(SfxStyleSheet* pStyleSheet, bool bDontRemoveHardAttr)
604
0
{
605
    // forward to SdrView
606
0
    FmFormView::SetStyleSheet(pStyleSheet, bDontRemoveHardAttr);
607
0
    return true;
608
0
}
609
610
/**
611
 * Start text input
612
 */
613
static void SetSpellOptions( const SdDrawDocument& rDoc, EEControlBits& rCntrl )
614
0
{
615
0
    bool bOnlineSpell = rDoc.GetOnlineSpell();
616
617
0
    if( bOnlineSpell )
618
0
        rCntrl |= EEControlBits::ONLINESPELLING;
619
0
    else
620
0
        rCntrl &= ~EEControlBits::ONLINESPELLING;
621
0
}
622
623
void OutlinerMasterViewFilter::Start(SdrOutliner *pOutl)
624
0
{
625
0
    m_pOutl = pOutl;
626
0
    OutlinerView* pOutlView = m_pOutl->GetView(0);
627
0
    m_bReadOnly = pOutlView->IsReadOnly();
628
0
    pOutlView->SetReadOnly(true);
629
0
}
630
631
void OutlinerMasterViewFilter::End()
632
0
{
633
0
    if (m_pOutl)
634
0
    {
635
0
        OutlinerView* pOutlView = m_pOutl->GetView(0);
636
0
        pOutlView->SetReadOnly(m_bReadOnly);
637
0
        m_pOutl = nullptr;
638
0
    }
639
0
}
640
641
SfxViewShell* View::GetSfxViewShell() const
642
0
{
643
0
    SfxViewShell* pRet = nullptr;
644
645
0
    if (mpViewSh)
646
0
        pRet = &mpViewSh->GetViewShellBase();
647
648
0
    return pRet;
649
0
}
650
651
// Create a new view-local UndoManager manager for Impress/Draw
652
std::unique_ptr<SdrUndoManager> View::createLocalTextUndoManager()
653
0
{
654
0
    std::unique_ptr<SdrUndoManager> pUndoManager(new sd::UndoManager);
655
0
    pUndoManager->SetDocShell(mpDocSh);
656
0
    return pUndoManager;
657
0
}
658
659
bool View::SdrBeginTextEdit(
660
    SdrObject* pObj, SdrPageView* pPV, vcl::Window* pWin,
661
    bool bIsNewObj,
662
    SdrOutliner* pOutl, OutlinerView* pGivenOutlinerView,
663
    bool bDontDeleteOutliner, bool bOnlyOneView, bool bGrabFocus )
664
0
{
665
0
    SdrPage* pPage = pObj ? pObj->getSdrPageFromSdrObject() : nullptr;
666
0
    bool bMasterPage = pPage && pPage->IsMasterPage();
667
668
0
    GetViewShell()->GetViewShellBase().GetEventMultiplexer()->MultiplexEvent(
669
0
        EventMultiplexerEventId::BeginTextEdit, static_cast<void*>(pObj) );
670
671
0
    if( pOutl==nullptr && pObj )
672
0
        pOutl = SdrMakeOutliner(OutlinerMode::TextObject, pObj->getSdrModelFromSdrObject()).release();
673
674
    // make draw&impress specific initialisations
675
0
    if( pOutl )
676
0
    {
677
0
        pOutl->SetStyleSheetPool(static_cast<SfxStyleSheetPool*>( mrDoc.GetStyleSheetPool() ));
678
0
        pOutl->SetCalcFieldValueHdl(LINK(SdModule::get(), SdModule, CalcFieldValueHdl));
679
0
        EEControlBits nCntrl = pOutl->GetControlWord();
680
0
        nCntrl |= EEControlBits::ALLOWBIGOBJS;
681
0
        nCntrl |= EEControlBits::MARKFIELDS;
682
0
        nCntrl |= EEControlBits::AUTOCORRECT;
683
684
0
        nCntrl &= ~EEControlBits::ULSPACESUMMATION;
685
0
        if ( mrDoc.IsSummationOfParagraphs() )
686
0
            nCntrl |= EEControlBits::ULSPACESUMMATION;
687
688
0
        SetSpellOptions( mrDoc, nCntrl );
689
690
0
        pOutl->SetControlWord(nCntrl);
691
692
0
        Reference< linguistic2::XSpellChecker1 > xSpellChecker( LinguMgr::GetSpellChecker() );
693
0
        if ( xSpellChecker.is() )
694
0
            pOutl->SetSpeller( xSpellChecker );
695
696
0
        Reference< linguistic2::XHyphenator > xHyphenator( LinguMgr::GetHyphenator() );
697
0
        if( xHyphenator.is() )
698
0
            pOutl->SetHyphenator( xHyphenator );
699
700
0
        pOutl->SetDefaultLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() );
701
0
    }
702
703
0
    if (mpViewSh)
704
0
    {
705
        // check if we have IASS active and propagate that info to the view with the active TextEdit
706
0
        rtl::Reference< SlideShow > xSlideshow(SlideShow::GetSlideShow(mpViewSh->GetViewShellBase()));
707
0
        const bool bIASS(xSlideshow.is() && xSlideshow->isRunning() && xSlideshow->IsInteractiveSlideshow());
708
0
        setInteractiveSlideShow(bIASS);
709
0
    }
710
711
0
    bool bReturn = FmFormView::SdrBeginTextEdit(
712
0
        pObj, pPV, pWin, bIsNewObj, pOutl,
713
0
        pGivenOutlinerView, bDontDeleteOutliner,
714
0
        bOnlyOneView, bGrabFocus);
715
716
0
    if ( mpViewSh )
717
0
    {
718
0
        mpViewSh->GetViewShellBase().GetDrawController()->FireSelectionChangeListener();
719
720
0
        if (pObj && pObj->GetObjIdentifier() == SdrObjKind::Table)
721
0
            mpViewSh->UpdateScrollBars();
722
723
0
        if (comphelper::LibreOfficeKit::isActive())
724
0
        {
725
0
            if (OutlinerView* pView = GetTextEditOutlinerView())
726
0
            {
727
0
                ::tools::Rectangle aRectangle = pView->GetOutputArea();
728
0
                if (pWin && pWin->GetMapMode().GetMapUnit() == MapUnit::Map100thMM)
729
0
                {
730
0
                    aRectangle = o3tl::convert(aRectangle, o3tl::Length::mm100, o3tl::Length::twip);
731
0
                }
732
0
                OString sRectangle = aRectangle.toString();
733
0
                SfxLokHelper::notifyOtherViews(&mpViewSh->GetViewShellBase(), LOK_CALLBACK_VIEW_LOCK, "rectangle", sRectangle);
734
0
            }
735
0
        }
736
0
    }
737
738
0
    if (::Outliner* pOL = bReturn ? GetTextEditOutliner() : nullptr)
739
0
    {
740
0
        if (pObj)
741
0
        {
742
0
            if( pObj->GetObjInventor() == SdrInventor::Default && pObj->GetObjIdentifier() == SdrObjKind::Table )
743
0
            {
744
0
                Color aBackground = GetTextEditBackgroundColor(*this);
745
0
                pOL->SetBackgroundColor( aBackground  );
746
0
            }
747
0
            else
748
0
            {
749
                // tdf#148140 Set the background to determine autocolor.
750
                // Use any explicit bg with fallback to underlying page if
751
                // none found
752
0
                if (!pObj->setSuitableOutlinerBg(*pOL) && pPV)
753
0
                    setOutlinerBgFromPage(*pOL, *pPV, true);
754
0
            }
755
0
        }
756
757
0
        pOL->SetParaInsertedHdl(LINK(this, View, OnParagraphInsertedHdl));
758
0
        pOL->SetParaRemovingHdl(LINK(this, View, OnParagraphRemovingHdl));
759
0
    }
760
761
0
    if (bMasterPage && bReturn && pOutl)
762
0
    {
763
0
        const SdrTextObj* pTextObj = pOutl->GetTextObj();
764
0
        const SdPage* pSdPage = pTextObj ? static_cast<const SdPage*>(pTextObj->getSdrPageFromSdrObject()) : nullptr;
765
0
        const PresObjKind eKind = pSdPage ? pSdPage->GetPresObjKind(const_cast<SdrTextObj*>(pTextObj)) : PresObjKind::NONE;
766
0
        switch (eKind)
767
0
        {
768
0
            case PresObjKind::Title:
769
0
            case PresObjKind::Outline:
770
0
            case PresObjKind::Text:
771
0
                maMasterViewFilter.Start(pOutl);
772
0
                break;
773
0
            default:
774
0
                break;
775
0
        }
776
0
    }
777
778
0
    return bReturn;
779
0
}
780
781
/** ends current text editing */
782
SdrEndTextEditKind View::SdrEndTextEdit(bool bDontDeleteReally)
783
0
{
784
0
    maMasterViewFilter.End();
785
786
0
    SdrTextObj* pObj = GetTextEditObject();
787
788
0
    bool bDefaultTextRestored = RestoreDefaultText( pObj );
789
0
    const bool bSaveSetModifiedEnabled = mpDocSh && mpDocSh->IsEnableSetModified();
790
0
    if (bDefaultTextRestored)
791
0
    {
792
0
        if (bSaveSetModifiedEnabled)
793
0
            mpDocSh->EnableSetModified(false);
794
0
    }
795
796
0
    SdrEndTextEditKind eKind = FmFormView::SdrEndTextEdit(bDontDeleteReally);
797
798
0
    if( bDefaultTextRestored )
799
0
    {
800
0
        if (bSaveSetModifiedEnabled)
801
0
            mpDocSh->EnableSetModified();
802
803
0
        if( pObj && !pObj->IsEmptyPresObj() )
804
0
        {
805
0
            pObj->SetEmptyPresObj( true );
806
0
        }
807
0
        else
808
0
        {
809
0
            eKind = SdrEndTextEditKind::Unchanged;
810
0
        }
811
0
    }
812
0
    else if( pObj && pObj->IsEmptyPresObj() && pObj->HasText() )
813
0
    {
814
0
        SdrPage* pPage = pObj->getSdrPageFromSdrObject();
815
0
        if( !pPage || !pPage->IsMasterPage() )
816
0
            pObj->SetEmptyPresObj( false );
817
0
    }
818
819
0
    GetViewShell()->GetViewShellBase().GetEventMultiplexer()->MultiplexEvent(
820
0
        EventMultiplexerEventId::EndTextEdit,
821
0
        static_cast<void*>(pObj) );
822
823
0
    if( pObj )
824
0
    {
825
0
        if ( mpViewSh )
826
0
        {
827
0
            mpViewSh->GetViewShellBase().GetDrawController()->FireSelectionChangeListener();
828
829
0
            if (comphelper::LibreOfficeKit::isActive())
830
0
                SfxLokHelper::notifyOtherViews(&mpViewSh->GetViewShellBase(), LOK_CALLBACK_VIEW_LOCK, "rectangle", "EMPTY"_ostr);
831
832
0
        }
833
834
0
        SdPage* pPage = dynamic_cast< SdPage* >( pObj->getSdrPageFromSdrObject() );
835
0
        if( pPage )
836
0
            pPage->onEndTextEdit( pObj );
837
0
    }
838
839
0
    return eKind;
840
0
}
841
842
/** restores the default text if the given text object is currently in edit mode and
843
    no text has been entered already. Is only useful just before text edit ends. */
844
bool View::RestoreDefaultText( SdrTextObj* pTextObj )
845
0
{
846
0
    bool bRestored = false;
847
848
0
    if( pTextObj && (pTextObj == GetTextEditObject()) )
849
0
    {
850
0
        if( !pTextObj->HasText() )
851
0
        {
852
0
            SdPage* pPage = dynamic_cast< SdPage* >( pTextObj->getSdrPageFromSdrObject() );
853
854
0
            if(pPage)
855
0
            {
856
0
                bRestored = pPage->RestoreDefaultText( pTextObj, pTextObj->GetCustomPromptText() );
857
0
                if( bRestored )
858
0
                {
859
0
                    SdrOutliner* pOutliner = GetTextEditOutliner();
860
0
                    pTextObj->SetTextEditOutliner( pOutliner );
861
0
                    OutlinerParaObject* pParaObj = pTextObj->GetOutlinerParaObject();
862
0
                    if (pOutliner)
863
0
                        pOutliner->SetText(*pParaObj);
864
0
                }
865
0
            }
866
0
        }
867
0
    }
868
869
0
    return bRestored;
870
0
}
871
872
/**
873
 * Sets the original size of the marked objects.
874
 */
875
void View::SetMarkedOriginalSize()
876
0
{
877
0
    std::unique_ptr<SdrUndoGroup> pUndoGroup(new SdrUndoGroup(mrDoc));
878
0
    const SdrMarkList& rMarkList = GetMarkedObjectList();
879
0
    const size_t nCount = rMarkList.GetMarkCount();
880
0
    bool            bOK = false;
881
882
0
    for( size_t i = 0; i < nCount; ++i )
883
0
    {
884
0
        SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
885
886
0
        if( pObj->GetObjInventor() == SdrInventor::Default )
887
0
        {
888
0
            if( pObj->GetObjIdentifier() == SdrObjKind::OLE2 )
889
0
            {
890
0
                uno::Reference < embed::XEmbeddedObject > xObj = static_cast<SdrOle2Obj*>(pObj)->GetObjRef();
891
0
                if( xObj.is() )
892
0
                {
893
                    // TODO/LEAN: working with VisualArea can switch object to running state
894
895
0
                    sal_Int64 nAspect = static_cast<SdrOle2Obj*>(pObj)->GetAspect();
896
0
                    Size aOleSize;
897
898
0
                    if ( nAspect == embed::Aspects::MSOLE_ICON )
899
0
                    {
900
0
                        MapMode aMap100( MapUnit::Map100thMM );
901
0
                        aOleSize = static_cast<SdrOle2Obj*>(pObj)->GetOrigObjSize( &aMap100 );
902
0
                        bOK = true;
903
0
                    }
904
0
                    else
905
0
                    {
906
0
                        MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) );
907
0
                        try
908
0
                        {
909
0
                            awt::Size aSz = xObj->getVisualAreaSize( nAspect );
910
0
                            aOleSize = OutputDevice::LogicToLogic(Size(aSz.Width, aSz.Height), MapMode(aUnit), MapMode(MapUnit::Map100thMM));
911
0
                            bOK = true;
912
0
                        }
913
0
                        catch( embed::NoVisualAreaSizeException& )
914
0
                        {}
915
0
                    }
916
917
0
                    if ( bOK )
918
0
                    {
919
0
                        ::tools::Rectangle   aDrawRect( pObj->GetLogicRect() );
920
921
0
                        if (aDrawRect.GetWidth() && aDrawRect.GetHeight())
922
0
                        {
923
0
                            pUndoGroup->AddAction( mrDoc.GetSdrUndoFactory().CreateUndoGeoObject( *pObj ) );
924
0
                            pObj->Resize( aDrawRect.TopLeft(), double( aOleSize.Width() ) / aDrawRect.GetWidth(),
925
0
                                                               double( aOleSize.Height() ) / aDrawRect.GetHeight() );
926
0
                        }
927
0
                    }
928
0
                }
929
0
            }
930
0
            else if( pObj->GetObjIdentifier() == SdrObjKind::Graphic )
931
0
            {
932
0
                const SdrGrafObj* pSdrGrafObj = static_cast< const SdrGrafObj* >(pObj);
933
0
                const Size aSize = pSdrGrafObj->getOriginalSize( );
934
0
                pUndoGroup->AddAction(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
935
0
                ::tools::Rectangle aRect( pObj->GetLogicRect() );
936
0
                aRect.SetSize( aSize );
937
0
                pObj->SetLogicRect( aRect );
938
0
                bOK = true;
939
0
            }
940
0
        }
941
0
    }
942
943
0
    if( bOK )
944
0
    {
945
0
        pUndoGroup->SetComment(SdResId(STR_UNDO_ORIGINALSIZE));
946
0
        mpDocSh->GetUndoManager()->AddUndoAction(std::move(pUndoGroup));
947
0
    }
948
0
}
949
950
/**
951
 * Connect OLE object to client.
952
 */
953
void View::DoConnect(SdrOle2Obj* pObj)
954
0
{
955
0
    if (!mpViewSh)
956
0
        return;
957
958
0
    uno::Reference < embed::XEmbeddedObject > xObj( pObj->GetObjRef() );
959
0
    if( !xObj.is() )
960
0
        return;
961
962
0
    ::sd::Window* pWindow = mpViewSh->GetActiveWindow();
963
0
    SfxInPlaceClient* pSdClient = mpViewSh-> GetViewShellBase().FindIPClient( xObj, pWindow );
964
0
    if ( pSdClient )
965
0
        return;
966
967
0
    pSdClient = new Client(pObj, *mpViewSh, pWindow);
968
0
    ::tools::Rectangle aRect = pObj->GetLogicRect();
969
0
    {
970
        // TODO/LEAN: working with visual area can switch object to running state
971
0
        Size aDrawSize = aRect.GetSize();
972
973
0
        MapMode aMapMode( mrDoc.GetScaleUnit() );
974
0
        Size aObjAreaSize = pObj->GetOrigObjSize( &aMapMode );
975
976
0
        double fScaleWidth  = static_cast<double>(aDrawSize.Width()) / aObjAreaSize.Width();
977
0
        double fScaleHeight = static_cast<double>(aDrawSize.Height()) / aObjAreaSize.Height();
978
0
        pSdClient->SetSizeScale(fScaleWidth, fScaleHeight);
979
980
        // visible area is only changed in-place!
981
        // the object area must be set after the scaling, since it triggers resize
982
0
        aRect.SetSize(aObjAreaSize);
983
0
        pSdClient->SetObjArea(aRect);
984
0
    }
985
0
}
986
987
bool View::IsMorphingAllowed() const
988
0
{
989
0
    const SdrMarkList&  rMarkList = GetMarkedObjectList();
990
0
    bool                bRet = false;
991
992
0
    if ( rMarkList.GetMarkCount() == 2 )
993
0
    {
994
0
        const SdrObject*    pObj1 = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
995
0
        const SdrObject*    pObj2 = rMarkList.GetMark( 1 )->GetMarkedSdrObj();
996
0
        const SdrObjKind    nKind1 = pObj1->GetObjIdentifier();
997
0
        const SdrObjKind    nKind2 = pObj2->GetObjIdentifier();
998
999
0
        if ( ( nKind1 != SdrObjKind::Text && nKind2 != SdrObjKind::Text ) &&
1000
0
             ( nKind1 != SdrObjKind::TitleText && nKind2 != SdrObjKind::TitleText ) &&
1001
0
             ( nKind1 != SdrObjKind::OutlineText && nKind2 != SdrObjKind::OutlineText ) &&
1002
0
             ( nKind1 != SdrObjKind::Group && nKind2 != SdrObjKind::Group ) &&
1003
0
             ( nKind1 != SdrObjKind::Line && nKind2 != SdrObjKind::Line ) &&
1004
0
             ( nKind1 != SdrObjKind::PolyLine && nKind2 != SdrObjKind::PolyLine ) &&
1005
0
             ( nKind1 != SdrObjKind::PathLine && nKind2 != SdrObjKind::PathLine ) &&
1006
0
             ( nKind1 != SdrObjKind::FreehandLine && nKind2 != SdrObjKind::FreehandLine ) &&
1007
0
             ( nKind1 != SdrObjKind::PathPolyLine && nKind2 != SdrObjKind::PathPolyLine ) &&
1008
0
             ( nKind1 != SdrObjKind::Measure && nKind2 != SdrObjKind::Measure ) &&
1009
0
             ( nKind1 != SdrObjKind::Edge && nKind2 != SdrObjKind::Edge ) &&
1010
0
             ( nKind1 != SdrObjKind::Graphic && nKind2 != SdrObjKind::Graphic ) &&
1011
0
             ( nKind1 != SdrObjKind::OLE2 && nKind2 != SdrObjKind::OLE2 ) &&
1012
0
             ( nKind1 != SdrObjKind::Caption && nKind2 !=  SdrObjKind::Caption ) &&
1013
0
             DynCastE3dObject( pObj1 ) == nullptr && DynCastE3dObject( pObj2 ) ==  nullptr )
1014
0
        {
1015
0
            SfxItemSetFixed<XATTR_FILLSTYLE, XATTR_FILLSTYLE> aSet1( mrDoc.GetPool() );
1016
0
            SfxItemSetFixed<XATTR_FILLSTYLE, XATTR_FILLSTYLE> aSet2( mrDoc.GetPool() );
1017
1018
0
            aSet1.Put(pObj1->GetMergedItemSet());
1019
0
            aSet2.Put(pObj2->GetMergedItemSet());
1020
1021
0
            const drawing::FillStyle eFillStyle1 = aSet1.Get( XATTR_FILLSTYLE ).GetValue();
1022
0
            const drawing::FillStyle eFillStyle2 = aSet2.Get( XATTR_FILLSTYLE ).GetValue();
1023
1024
0
            if( ( eFillStyle1 == drawing::FillStyle_NONE || eFillStyle1 == drawing::FillStyle_SOLID ) &&
1025
0
                ( eFillStyle2 == drawing::FillStyle_NONE || eFillStyle2 == drawing::FillStyle_SOLID ) )
1026
0
                bRet = true;
1027
0
        }
1028
0
    }
1029
1030
0
    return bRet;
1031
0
}
1032
1033
bool View::IsVectorizeAllowed() const
1034
0
{
1035
0
    const SdrMarkList&  rMarkList = GetMarkedObjectList();
1036
0
    bool                bRet = false;
1037
1038
0
    if( rMarkList.GetMarkCount() == 1 )
1039
0
    {
1040
0
        const SdrGrafObj* pObj = dynamic_cast< const SdrGrafObj* >(rMarkList.GetMark( 0 )->GetMarkedSdrObj());
1041
1042
0
        if(pObj)
1043
0
        {
1044
0
            if(GraphicType::Bitmap == pObj->GetGraphicType() && !pObj->isEmbeddedVectorGraphicData())
1045
0
            {
1046
0
                bRet = true;
1047
0
            }
1048
0
        }
1049
0
    }
1050
1051
0
    return bRet;
1052
0
}
1053
1054
IMPL_LINK( View, OnParagraphInsertedHdl, ::Outliner::ParagraphHdlParam, aParam, void )
1055
0
{
1056
0
    SdrObject* pObj = GetTextEditObject();
1057
1058
0
    if( aParam.pPara && pObj )
1059
0
    {
1060
0
        SdPage* pPage = dynamic_cast< SdPage* >( pObj->getSdrPageFromSdrObject() );
1061
0
        if( pPage )
1062
0
            pPage->onParagraphInserted( aParam.pOutliner, aParam.pPara, pObj );
1063
0
    }
1064
0
}
1065
1066
/**
1067
 * Handler for the deletion of the pages (paragraphs).
1068
 */
1069
IMPL_LINK( View, OnParagraphRemovingHdl, ::Outliner::ParagraphHdlParam, aParam, void )
1070
0
{
1071
0
    SdrObject* pObj = GetTextEditObject();
1072
1073
0
    if( aParam.pPara && pObj )
1074
0
    {
1075
0
        SdPage* pPage = dynamic_cast< SdPage* >( pObj->getSdrPageFromSdrObject() );
1076
0
        if( pPage )
1077
0
            pPage->onParagraphRemoving( aParam.pOutliner, aParam.pPara, pObj );
1078
0
    }
1079
0
}
1080
1081
bool View::isRecordingUndo() const
1082
0
{
1083
0
    if( mrDoc.IsUndoEnabled() )
1084
0
    {
1085
0
        sd::UndoManager* pUndoManager = mrDoc.GetUndoManager();
1086
0
        return pUndoManager && pUndoManager->IsInListAction();
1087
0
    }
1088
0
    else
1089
0
    {
1090
0
        return false;
1091
0
    }
1092
0
}
1093
1094
void View::AddCustomHdl()
1095
0
{
1096
0
    maSmartTags.addCustomHandles( maHdlList );
1097
0
}
1098
1099
void View::updateHandles()
1100
0
{
1101
0
    AdjustMarkHdl();
1102
0
}
1103
1104
SdrViewContext View::GetContext() const
1105
0
{
1106
0
    SdrViewContext eContext = SdrViewContext::Standard;
1107
0
    if( maSmartTags.getContext( eContext ) )
1108
0
        return eContext;
1109
0
    else
1110
0
        return FmFormView::GetContext();
1111
0
}
1112
1113
bool View::HasMarkablePoints() const
1114
0
{
1115
0
    if( maSmartTags.HasMarkablePoints() )
1116
0
        return true;
1117
0
    else
1118
0
        return FmFormView::HasMarkablePoints();
1119
0
}
1120
1121
sal_Int32 View::GetMarkablePointCount() const
1122
0
{
1123
0
    sal_Int32 nCount = FmFormView::GetMarkablePointCount();
1124
0
    nCount += maSmartTags.GetMarkablePointCount();
1125
0
    return nCount;
1126
0
}
1127
1128
bool View::HasMarkedPoints() const
1129
0
{
1130
0
    if( maSmartTags.HasMarkedPoints() )
1131
0
        return true;
1132
0
    else
1133
0
        return FmFormView::HasMarkedPoints();
1134
0
}
1135
1136
bool View::MarkPoint(SdrHdl& rHdl, bool bUnmark )
1137
0
{
1138
0
    if( maSmartTags.MarkPoint( rHdl, bUnmark ) )
1139
0
        return true;
1140
0
    else
1141
0
        return FmFormView::MarkPoint( rHdl, bUnmark );
1142
0
}
1143
1144
bool View::MarkPoints(const ::tools::Rectangle* pRect, bool bUnmark)
1145
0
{
1146
0
    if( maSmartTags.MarkPoints( pRect, bUnmark ) )
1147
0
        return true;
1148
0
    else
1149
0
        return FmFormView::MarkPoints( pRect, bUnmark );
1150
0
}
1151
1152
void View::CheckPossibilities()
1153
0
{
1154
0
    FmFormView::CheckPossibilities();
1155
0
    maSmartTags.CheckPossibilities();
1156
0
}
1157
1158
void View::OnBeginPasteOrDrop( PasteOrDropInfos* pInfo )
1159
0
{
1160
0
    SdrOutliner* pOutliner = GetTextEditOutliner();
1161
0
    if (!pOutliner)
1162
0
        return;
1163
1164
    // Turn character attributes of the table paragraph of the insert position into
1165
    // character-level attributes, so they are not lost when OnEndPasteOrDrop()
1166
    // sets the paragraph stylesheet. (tdf#115783)
1167
0
    const SdrTableObj* pTableObj = dynamic_cast<const SdrTableObj*>(pOutliner->GetTextObj());
1168
0
    if (pTableObj)
1169
0
    {
1170
0
        SfxItemSet aSet(pOutliner->GetParaAttribs(pInfo->nStartPara));
1171
0
        pOutliner->SetCharAttribs(pInfo->nStartPara, aSet);
1172
0
    }
1173
0
}
1174
1175
/** this is called after a paste or drop operation, make sure that the newly inserted paragraphs
1176
    get the correct style sheet. */
1177
void View::OnEndPasteOrDrop( PasteOrDropInfos* pInfo )
1178
0
{
1179
    /* Style Sheet handling */
1180
0
    SdrTextObj* pTextObj = GetTextEditObject();
1181
0
    SdrOutliner* pOutliner = GetTextEditOutliner();
1182
0
    if( !pOutliner || !pTextObj || !pTextObj->getSdrPageFromSdrObject() )
1183
0
        return;
1184
1185
0
    SdPage* pPage = static_cast< SdPage* >( pTextObj->getSdrPageFromSdrObject() );
1186
0
    const PresObjKind eKind = pPage->GetPresObjKind(pTextObj);
1187
1188
    // outline kinds are taken care of in Outliner::ImplSetLevelDependentStyleSheet
1189
0
    if( eKind == PresObjKind::Outline )
1190
0
        return;
1191
1192
0
    SfxStyleSheet* pStyleSheet = nullptr;
1193
0
    if( eKind != PresObjKind::NONE )
1194
0
        pStyleSheet = pPage->GetStyleSheetForPresObj(eKind);
1195
0
    else
1196
0
         pStyleSheet = pTextObj->GetStyleSheet();
1197
    // just put the object style on each new paragraph
1198
0
    for ( sal_Int32 nPara = pInfo->nStartPara; nPara <= pInfo->nEndPara; nPara++ )
1199
0
    {
1200
0
        pOutliner->SetStyleSheet( nPara, pStyleSheet );
1201
0
    }
1202
0
}
1203
1204
bool View::ShouldToggleOn(
1205
    const bool bBulletOnOffMode,
1206
    const bool bNormalBullet)
1207
0
{
1208
    // If setting bullets/numbering by the dialog, always should toggle on.
1209
0
    if (!bBulletOnOffMode)
1210
0
        return true;
1211
0
    SdrModel& rSdrModel = GetModel();
1212
1213
0
    bool bToggleOn = false;
1214
0
    std::unique_ptr<SdrOutliner> pOutliner(SdrMakeOutliner(OutlinerMode::TextObject, rSdrModel));
1215
0
    const SdrMarkList& rMarkList = GetMarkedObjectList();
1216
0
    const size_t nMarkCount = rMarkList.GetMarkCount();
1217
0
    for (size_t nIndex = 0; nIndex < nMarkCount && !bToggleOn; ++nIndex)
1218
0
    {
1219
0
        SdrTextObj* pTextObj = DynCastSdrTextObj(rMarkList.GetMark(nIndex)->GetMarkedSdrObj());
1220
0
        if (!pTextObj || pTextObj->IsTextEditActive())
1221
0
            continue;
1222
0
        if( dynamic_cast< const SdrTableObj *>( pTextObj ) !=  nullptr)
1223
0
        {
1224
0
            SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >(pTextObj);
1225
0
            if (!pTableObj)
1226
0
                continue;
1227
0
            CellPos aStart, aEnd;
1228
0
            SvxTableController* pTableController = dynamic_cast< SvxTableController* >(getSelectionController().get());
1229
0
            if (pTableController)
1230
0
            {
1231
0
                pTableController->getSelectedCells(aStart, aEnd);
1232
0
            }
1233
0
            else
1234
0
            {
1235
0
                aStart = SdrTableObj::getFirstCell();
1236
0
                aEnd = pTableObj->getLastCell();
1237
0
            }
1238
0
            sal_Int32 nColCount = pTableObj->getColumnCount();
1239
0
            for (sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow && !bToggleOn; nRow++)
1240
0
            {
1241
0
                for (sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol && !bToggleOn; nCol++)
1242
0
                {
1243
0
                    sal_Int32 nCellIndex = nRow * nColCount + nCol;
1244
0
                    SdrText* pText = pTableObj->getText(nCellIndex);
1245
0
                    if (!pText || !pText->GetOutlinerParaObject())
1246
0
                        continue;
1247
0
                    pOutliner->SetText(*(pText->GetOutlinerParaObject()));
1248
0
                    sal_Int16 nStatus = pOutliner->GetBulletsNumberingStatus();
1249
0
                    bToggleOn = (bNormalBullet && nStatus != 0) || (!bNormalBullet && nStatus != 1);
1250
0
                    pOutliner->Clear();
1251
0
                }
1252
0
            }
1253
0
        }
1254
0
        else
1255
0
        {
1256
0
            OutlinerParaObject* pParaObj = pTextObj->GetOutlinerParaObject();
1257
0
            if (!pParaObj)
1258
0
                continue;
1259
0
            pOutliner->SetText(*pParaObj);
1260
0
            sal_Int16 nStatus = pOutliner->GetBulletsNumberingStatus();
1261
0
            bToggleOn = (bNormalBullet && nStatus != 0) || (!bNormalBullet && nStatus != 1);
1262
0
            pOutliner->Clear();
1263
0
        }
1264
0
    }
1265
0
    return bToggleOn;
1266
0
}
1267
1268
void View::ChangeMarkedObjectsBulletsNumbering(
1269
    const bool bToggle,
1270
    const bool bHandleBullets,
1271
    const SvxNumRule* pNumRule )
1272
0
{
1273
0
    SdrModel& rSdrModel = GetModel();
1274
0
    OutputDevice* pOut = GetFirstOutputDevice();
1275
0
    vcl::Window* pWindow = pOut ? pOut->GetOwnerWindow() : nullptr;
1276
0
    if (!pWindow)
1277
0
        return;
1278
1279
0
    const bool bUndoEnabled = rSdrModel.IsUndoEnabled();
1280
0
    std::unique_ptr<SdrUndoGroup> pUndoGroup(bUndoEnabled ? new SdrUndoGroup(rSdrModel) : nullptr);
1281
1282
0
    const bool bToggleOn = ShouldToggleOn( bToggle, bHandleBullets );
1283
1284
0
    std::unique_ptr<SdrOutliner> pOutliner(SdrMakeOutliner(OutlinerMode::TextObject, rSdrModel));
1285
0
    OutlinerView aOutlinerView(*pOutliner, pWindow);
1286
1287
0
    const SdrMarkList& rMarkList = GetMarkedObjectList();
1288
0
    const size_t nMarkCount = rMarkList.GetMarkCount();
1289
0
    for (size_t nIndex = 0; nIndex < nMarkCount; ++nIndex)
1290
0
    {
1291
0
        SdrTextObj* pTextObj = DynCastSdrTextObj(rMarkList.GetMark(nIndex)->GetMarkedSdrObj());
1292
0
        if (!pTextObj || pTextObj->IsTextEditActive())
1293
0
            continue;
1294
0
        if( dynamic_cast< SdrTableObj *>( pTextObj ) !=  nullptr)
1295
0
        {
1296
0
            SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >(pTextObj);
1297
0
            if (!pTableObj)
1298
0
                continue;
1299
0
            CellPos aStart, aEnd;
1300
0
            SvxTableController* pTableController = dynamic_cast< SvxTableController* >(getSelectionController().get());
1301
0
            if (pTableController)
1302
0
            {
1303
0
                pTableController->getSelectedCells(aStart, aEnd);
1304
0
            }
1305
0
            else
1306
0
            {
1307
0
                aStart = SdrTableObj::getFirstCell();
1308
0
                aEnd = pTableObj->getLastCell();
1309
0
            }
1310
0
            sal_Int32 nColCount = pTableObj->getColumnCount();
1311
0
            for (sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++)
1312
0
            {
1313
0
                for (sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++)
1314
0
                {
1315
0
                    sal_Int32 nCellIndex = nRow * nColCount + nCol;
1316
0
                    SdrText* pText = pTableObj->getText(nCellIndex);
1317
0
                    if (!pText || !pText->GetOutlinerParaObject())
1318
0
                        continue;
1319
1320
0
                    pOutliner->SetText(*(pText->GetOutlinerParaObject()));
1321
0
                    if (bUndoEnabled)
1322
0
                    {
1323
0
                        pUndoGroup->AddAction(rSdrModel.GetSdrUndoFactory().CreateUndoObjectSetText(*pTextObj, nCellIndex));
1324
0
                    }
1325
0
                    if ( !bToggleOn )
1326
0
                    {
1327
0
                        aOutlinerView.SwitchOffBulletsNumbering();
1328
0
                    }
1329
0
                    else
1330
0
                    {
1331
0
                        aOutlinerView.ApplyBulletsNumbering( bHandleBullets, pNumRule, bToggle );
1332
0
                    }
1333
0
                    sal_uInt32 nParaCount = pOutliner->GetParagraphCount();
1334
0
                    pText->SetOutlinerParaObject(pOutliner->CreateParaObject(0, static_cast<sal_uInt16>(nParaCount)));
1335
0
                    pOutliner->Clear();
1336
0
                }
1337
0
            }
1338
            // Broadcast the object change event.
1339
0
            if (!pTextObj->AdjustTextFrameWidthAndHeight())
1340
0
            {
1341
0
                pTextObj->SetChanged();
1342
0
                pTextObj->BroadcastObjectChange();
1343
0
            }
1344
0
        }
1345
0
        else
1346
0
        {
1347
0
            OutlinerParaObject* pParaObj = pTextObj->GetOutlinerParaObject();
1348
0
            if (!pParaObj)
1349
0
                continue;
1350
0
            pOutliner->SetText(*pParaObj);
1351
0
            if (bUndoEnabled)
1352
0
            {
1353
0
                pUndoGroup->AddAction(
1354
0
                    rSdrModel.GetSdrUndoFactory().CreateUndoObjectSetText(*pTextObj, 0));
1355
0
            }
1356
0
            if ( !bToggleOn )
1357
0
            {
1358
0
                aOutlinerView.SwitchOffBulletsNumbering();
1359
0
            }
1360
0
            else
1361
0
            {
1362
0
                aOutlinerView.ApplyBulletsNumbering( bHandleBullets, pNumRule, bToggle );
1363
0
            }
1364
0
            sal_uInt32 nParaCount = pOutliner->GetParagraphCount();
1365
0
            pTextObj->SetOutlinerParaObject(pOutliner->CreateParaObject(0, static_cast<sal_uInt16>(nParaCount)));
1366
0
            pOutliner->Clear();
1367
0
        }
1368
0
    }
1369
1370
0
    if ( bUndoEnabled && pUndoGroup->GetActionCount() > 0 )
1371
0
    {
1372
0
        rSdrModel.BegUndo();
1373
0
        rSdrModel.AddUndo(std::move(pUndoGroup));
1374
0
        rSdrModel.EndUndo();
1375
0
    }
1376
0
}
1377
1378
} // end of namespace sd
1379
1380
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */