android: Update app-specific/MIME type icons
[LibreOffice.git] / sd / source / ui / view / sdview.cxx
blob02a1243e0264767014c69f6a950f23f9e12fcedd
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <config_features.h>
22 #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
23 #include <com/sun/star/embed/XEmbeddedObject.hpp>
24 #include <com/sun/star/linguistic2/XSpellChecker1.hpp>
26 #include <View.hxx>
27 #include <avmedia/mediawindow.hxx>
28 #include <editeng/outlobj.hxx>
29 #include <editeng/unolingu.hxx>
30 #include <o3tl/deleter.hxx>
31 #include <svx/obj3d.hxx>
32 #include <svx/fmview.hxx>
33 #include <editeng/outliner.hxx>
34 #include <svx/svdograf.hxx>
35 #include <svx/svdoole2.hxx>
36 #include <svx/svdundo.hxx>
38 #include <vcl/settings.hxx>
40 #include <officecfg/Office/Common.hxx>
41 #include <sfx2/dispatch.hxx>
42 #include <svx/svdpagv.hxx>
43 #include <svx/svdoutl.hxx>
44 #include <svx/sdr/contact/displayinfo.hxx>
46 #include <svx/svdetc.hxx>
47 #include <editeng/editstat.hxx>
49 #include <sfx2/viewfrm.hxx>
50 #include <toolkit/helper/vclunohelper.hxx>
51 #include <svx/xfillit0.hxx>
53 #include <app.hrc>
54 #include <strings.hrc>
55 #include <Window.hxx>
56 #include <Client.hxx>
57 #include <drawdoc.hxx>
58 #include <DrawDocShell.hxx>
59 #include <sdmod.hxx>
60 #include <sdpage.hxx>
61 #include <sdresid.hxx>
62 #include <unokywds.hxx>
63 #include <ViewClipboard.hxx>
64 #include <undo/undomanager.hxx>
65 #include <svx/sdr/contact/viewobjectcontact.hxx>
66 #include <svx/sdr/contact/viewcontact.hxx>
67 #include <svx/svdotable.hxx>
68 #include <EventMultiplexer.hxx>
69 #include <ViewShellBase.hxx>
70 #include <ViewShell.hxx>
72 #include <basegfx/polygon/b2dpolygontools.hxx>
73 #include <basegfx/color/bcolor.hxx>
74 #include <drawinglayer/attribute/lineattribute.hxx>
75 #include <drawinglayer/attribute/strokeattribute.hxx>
76 #include <drawinglayer/primitive2d/textlayoutdevice.hxx>
77 #include <drawinglayer/primitive2d/PolygonStrokePrimitive2D.hxx>
78 #include <svx/sdr/contact/objectcontact.hxx>
79 #include <svx/sdr/table/tablecontroller.hxx>
80 #include <basegfx/matrix/b2dhommatrix.hxx>
81 #include <drawinglayer/primitive2d/textprimitive2d.hxx>
82 #include <svx/unoapi.hxx>
83 #include <basegfx/matrix/b2dhommatrixtools.hxx>
84 #include <comphelper/lok.hxx>
85 #include <sfx2/lokhelper.hxx>
86 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
87 #include <DrawController.hxx>
88 #include <svtools/optionsdrawinglayer.hxx>
90 #include <memory>
91 #include <numeric>
93 using namespace com::sun::star;
94 using namespace com::sun::star::uno;
95 using namespace sdr::table;
96 namespace sd {
98 View::View(
99 SdDrawDocument& rDrawDoc,
100 OutputDevice* pOutDev,
101 ViewShell* pViewShell)
102 : FmFormView(rDrawDoc, pOutDev),
103 mrDoc(rDrawDoc),
104 mpDocSh(rDrawDoc.GetDocSh()),
105 mpViewSh(pViewShell),
106 mpDropMarkerObj(nullptr),
107 mnDragSrcPgNum(SDRPAGE_NOTFOUND),
108 mnAction(DND_ACTION_NONE),
109 maDropErrorIdle("sd View DropError"),
110 maDropInsertFileIdle("sd View DropInsertFile"),
111 mnLockRedrawSmph(0),
112 mbIsDropAllowed(true),
113 maSmartTags(*this),
114 mpClipboard (new ViewClipboard (*this))
116 // #i73602# Use default from the configuration
117 SetBufferedOverlayAllowed(SvtOptionsDrawinglayer::IsOverlayBuffer_DrawImpress());
119 // #i74769#, #i75172# Use default from the configuration
120 SetBufferedOutputAllowed(SvtOptionsDrawinglayer::IsPaintBuffer_DrawImpress());
122 EnableExtendedKeyInputDispatcher(false);
123 EnableExtendedMouseEventDispatcher(false);
125 SetUseIncompatiblePathCreateInterface(false);
127 SetMinMoveDistancePixel(2);
128 SetHitTolerancePixel(2);
129 SetMeasureLayer(sUNO_LayerName_measurelines);
131 // Timer for delayed drop (has to be for MAC)
132 maDropErrorIdle.SetInvokeHandler( LINK(this, View, DropErrorHdl) );
133 maDropInsertFileIdle.SetInvokeHandler( LINK(this, View, DropInsertFileHdl) );
136 void View::ImplClearDrawDropMarker()
138 mpDropMarker.reset();
141 View::~View()
143 maSmartTags.Dispose();
145 // release content of selection clipboard, if we own the content
146 ClearSelectionClipboard();
148 #if HAVE_FEATURE_AVMEDIA
149 if (mxDropMediaSizeListener)
151 suppress_fun_call_w_exception(mxDropMediaSizeListener->dispose());
152 mxDropMediaSizeListener.clear();
154 #endif
156 maDropErrorIdle.Stop();
157 maDropInsertFileIdle.Stop();
159 ImplClearDrawDropMarker();
161 while(PaintWindowCount())
163 // remove all registered OutDevs
164 suppress_fun_call_w_exception(DeleteDeviceFromPaintView(*GetFirstOutputDevice()));
168 namespace {
170 class ViewRedirector : public sdr::contact::ViewObjectContactRedirector
172 public:
173 ViewRedirector();
175 // all default implementations just call the same methods at the original. To do something
176 // different, override the method and at least do what the method does.
177 virtual void createRedirectedPrimitive2DSequence(
178 const sdr::contact::ViewObjectContact& rOriginal,
179 const sdr::contact::DisplayInfo& rDisplayInfo,
180 drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor) override;
185 ViewRedirector::ViewRedirector()
189 void ViewRedirector::createRedirectedPrimitive2DSequence(
190 const sdr::contact::ViewObjectContact& rOriginal,
191 const sdr::contact::DisplayInfo& rDisplayInfo,
192 drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor)
194 SdrObject* pObject = rOriginal.GetViewContact().TryToGetSdrObject();
195 SdrPage* pSdrPage = pObject ? pObject->getSdrPageFromSdrObject() : nullptr;
196 if(!pObject || !pSdrPage)
198 // not a SdrObject visualisation (maybe e.g. page) or no page
199 sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(rOriginal, rDisplayInfo, rVisitor);
200 return;
203 const bool bDoCreateGeometry(pSdrPage->checkVisibility( rOriginal, rDisplayInfo, true ));
205 if(!bDoCreateGeometry &&
206 (( pObject->GetObjInventor() != SdrInventor::Default ) || ( pObject->GetObjIdentifier() != SdrObjKind::Page )) )
207 return;
209 PresObjKind eKind(PresObjKind::NONE);
210 const bool bSubContentProcessing(rDisplayInfo.GetSubContentActive());
211 const bool bIsMasterPageObject(pSdrPage->IsMasterPage());
212 const bool bIsPrinting(rOriginal.GetObjectContact().isOutputToPrinter());
213 const SdrPageView* pPageView = rOriginal.GetObjectContact().TryToGetSdrPageView();
214 const SdrPage* pVisualizedPage = GetSdrPageFromXDrawPage(rOriginal.GetObjectContact().getViewInformation2D().getVisualizedPage());
215 const SdPage* pObjectsSdPage = dynamic_cast< SdPage* >(pSdrPage);
216 const bool bIsInsidePageObj(pPageView && pPageView->GetPage() != pVisualizedPage);
218 // check if we need to draw a placeholder border. Never do it for
219 // objects inside a SdrPageObj and never when printing
220 if(!bIsInsidePageObj && !bIsPrinting)
222 bool bCreateOutline(false);
224 if( pObject->IsEmptyPresObj() && DynCastSdrTextObj( pObject ) != nullptr )
226 if( !bSubContentProcessing || !pObject->IsNotVisibleAsMaster() )
228 eKind = pObjectsSdPage ? pObjectsSdPage->GetPresObjKind(pObject) : PresObjKind::NONE;
229 bCreateOutline = true;
232 else if( ( pObject->GetObjInventor() == SdrInventor::Default ) && ( pObject->GetObjIdentifier() == SdrObjKind::Text ) )
234 if( pObjectsSdPage )
236 eKind = pObjectsSdPage->GetPresObjKind(pObject);
238 if((eKind == PresObjKind::Footer) || (eKind == PresObjKind::Header) || (eKind == PresObjKind::DateTime) || (eKind == PresObjKind::SlideNumber) )
240 if( !bSubContentProcessing )
242 // only draw a boundary for header&footer objects on the masterpage itself
243 bCreateOutline = true;
248 else if( ( pObject->GetObjInventor() == SdrInventor::Default ) && ( pObject->GetObjIdentifier() == SdrObjKind::Page ) )
250 // only for handout page, else this frame will be created for each
251 // page preview object in SlideSorter and PagePane
252 if(pObjectsSdPage && PageKind::Handout == pObjectsSdPage->GetPageKind())
254 bCreateOutline = true;
258 if(bCreateOutline)
260 // empty presentation objects get a gray frame
261 const svtools::ColorConfig aColorConfig;
262 const svtools::ColorConfigValue aColor( aColorConfig.GetColorValue( svtools::OBJECTBOUNDARIES ) );
264 if( aColor.bIsVisible )
266 // get basic object transformation
267 const basegfx::BColor aRGBColor(aColor.nColor.getBColor());
268 basegfx::B2DHomMatrix aObjectMatrix;
269 basegfx::B2DPolyPolygon aObjectPolyPolygon;
270 pObject->TRGetBaseGeometry(aObjectMatrix, aObjectPolyPolygon);
272 // create dashed border
274 // create object polygon
275 basegfx::B2DPolygon aPolygon(basegfx::utils::createUnitPolygon());
276 aPolygon.transform(aObjectMatrix);
278 // create line and stroke attribute
279 ::std::vector< double > aDotDashArray { 160.0, 80.0 };
281 const double fFullDotDashLen(::std::accumulate(aDotDashArray.begin(), aDotDashArray.end(), 0.0));
282 const drawinglayer::attribute::LineAttribute aLine(aRGBColor);
283 drawinglayer::attribute::StrokeAttribute aStroke(std::move(aDotDashArray), fFullDotDashLen);
285 // create primitive and add
286 const drawinglayer::primitive2d::Primitive2DReference xRef(new drawinglayer::primitive2d::PolygonStrokePrimitive2D(
287 std::move(aPolygon),
288 aLine,
289 std::move(aStroke)));
290 rVisitor.visit(xRef);
293 // now paint the placeholder description, but only when masterpage
294 // is displayed as page directly (MasterPage view)
295 if(!bSubContentProcessing && bIsMasterPageObject)
297 OUString aObjectString;
299 switch( eKind )
301 case PresObjKind::Title:
303 if(pObjectsSdPage && pObjectsSdPage->GetPageKind() == PageKind::Standard)
305 static OUString aTitleAreaStr(SdResId(STR_PLACEHOLDER_DESCRIPTION_TITLE));
306 aObjectString = aTitleAreaStr;
309 break;
311 case PresObjKind::Outline:
313 static OUString aOutlineAreaStr(SdResId(STR_PLACEHOLDER_DESCRIPTION_OUTLINE));
314 aObjectString = aOutlineAreaStr;
315 break;
317 case PresObjKind::Footer:
319 static OUString aFooterAreaStr(SdResId(STR_PLACEHOLDER_DESCRIPTION_FOOTER));
320 aObjectString = aFooterAreaStr;
321 break;
323 case PresObjKind::Header:
325 static OUString aHeaderAreaStr(SdResId(STR_PLACEHOLDER_DESCRIPTION_HEADER));
326 aObjectString = aHeaderAreaStr;
327 break;
329 case PresObjKind::DateTime:
331 static OUString aDateTimeStr(SdResId(STR_PLACEHOLDER_DESCRIPTION_DATETIME));
332 aObjectString = aDateTimeStr;
333 break;
335 case PresObjKind::Notes:
337 static OUString aDateTimeStr(SdResId(STR_PLACEHOLDER_DESCRIPTION_NOTES));
338 aObjectString = aDateTimeStr;
339 break;
341 case PresObjKind::SlideNumber:
343 if(pObjectsSdPage && pObjectsSdPage->GetPageKind() == PageKind::Standard)
345 static OUString aSlideAreaStr(SdResId(STR_PLACEHOLDER_DESCRIPTION_SLIDE));
346 aObjectString = aSlideAreaStr;
348 else
350 static OUString aNumberAreaStr(SdResId(STR_PLACEHOLDER_DESCRIPTION_NUMBER));
351 aObjectString = aNumberAreaStr;
353 break;
355 default:
357 break;
361 if( !aObjectString.isEmpty() )
363 // decompose object matrix to be able to place text correctly
364 basegfx::B2DTuple aScale;
365 basegfx::B2DTuple aTranslate;
366 double fRotate, fShearX;
367 aObjectMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
369 // create font
370 SdrTextObj* pTextObj = DynCastSdrTextObj( pObject );
371 const SdrTextVertAdjust eTVA(pTextObj ? pTextObj->GetTextVerticalAdjust() : SDRTEXTVERTADJUST_CENTER);
372 vcl::Font aScaledVclFont;
374 // use a text size factor to get more reliable text sizes from the text layouter
375 // (and from vcl), tipp from HDU
376 static const sal_uInt32 nTextSizeFactor(100);
378 // use a factor to get more linear text size calculations
379 aScaledVclFont.SetFontHeight( 500 * nTextSizeFactor );
381 // get basic geometry and get text size
382 drawinglayer::primitive2d::TextLayouterDevice aTextLayouter;
383 aTextLayouter.setFont(aScaledVclFont);
384 const sal_Int32 nTextLength(aObjectString.getLength());
386 // do not forget to use the factor again to get the width for the 500
387 const double fTextWidth(aTextLayouter.getTextWidth(aObjectString, 0, nTextLength) * (1.0 / nTextSizeFactor));
388 const double fTextHeight(aTextLayouter.getTextHeight() * (1.0 / nTextSizeFactor));
390 // calculate text primitive position. If text is at bottom, use top for
391 // the extra text and vice versa
392 const double fHorDist(125);
393 const double fVerDist(125);
394 const double fPosX((aTranslate.getX() + aScale.getX()) - fTextWidth - fHorDist);
395 const double fPosY((SDRTEXTVERTADJUST_BOTTOM == eTVA)
396 ? aTranslate.getY() - fVerDist + fTextHeight
397 : (aTranslate.getY() + aScale.getY()) - fVerDist);
399 // get font attributes; use normally scaled font
400 vcl::Font aVclFont;
401 basegfx::B2DVector aTextSizeAttribute;
403 aVclFont.SetFontHeight( 500 );
405 drawinglayer::attribute::FontAttribute aFontAttribute(
406 drawinglayer::primitive2d::getFontAttributeFromVclFont(
407 aTextSizeAttribute,
408 aVclFont,
409 false,
410 false));
412 // fill text matrix
413 const basegfx::B2DHomMatrix aTextMatrix(basegfx::utils::createScaleShearXRotateTranslateB2DHomMatrix(
414 aTextSizeAttribute.getX(), aTextSizeAttribute.getY(),
415 fShearX,
416 fRotate,
417 fPosX, fPosY));
419 // create DXTextArray (can be empty one)
420 ::std::vector< double > aDXArray{};
422 // create locale; this may need some more information in the future
423 css::lang::Locale aLocale;
425 // create primitive and add
426 const drawinglayer::primitive2d::Primitive2DReference xRef(
427 new drawinglayer::primitive2d::TextSimplePortionPrimitive2D(
428 aTextMatrix,
429 aObjectString,
431 nTextLength,
432 std::move(aDXArray),
434 std::move(aFontAttribute),
435 std::move(aLocale),
436 aRGBColor));
437 rVisitor.visit(xRef);
444 if(bDoCreateGeometry)
446 sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(
447 rOriginal,
448 rDisplayInfo, rVisitor);
452 namespace
454 void setOutlinerBgFromPage(::Outliner& rOutl, SdrPageView& rPgView, bool bScreenDisplay)
456 SdPage* pPage = static_cast<SdPage*>(rPgView.GetPage());
457 if (pPage)
459 // #i75566# Name change GetBackgroundColor -> GetPageBackgroundColor and
460 // hint value if screen display. Only then the AutoColor mechanisms shall be applied
461 rOutl.SetBackgroundColor(pPage->GetPageBackgroundColor(&rPgView, bScreenDisplay));
467 * The event will be forwarded to the View
469 void View::CompleteRedraw(OutputDevice* pOutDev, const vcl::Region& rReg, sdr::contact::ViewObjectContactRedirector* pRedirector /*=0*/)
471 // execute ??
472 if (mnLockRedrawSmph != 0)
473 return;
475 SdrPageView* pPgView = GetSdrPageView();
477 if (pPgView)
479 SdPage* pPage = static_cast<SdPage*>( pPgView->GetPage() );
480 if( pPage )
482 SdrOutliner& rOutl = mrDoc.GetDrawOutliner();
483 bool bScreenDisplay(true);
485 // #i75566# printing; suppress AutoColor BackgroundColor generation
486 // for visibility reasons by giving GetPageBackgroundColor()
487 // the needed hint
488 // #i75566# PDF export; suppress AutoColor BackgroundColor generation (see printing)
489 if (pOutDev && ((OUTDEV_PRINTER == pOutDev->GetOutDevType())
490 || (OUTDEV_PDF == pOutDev->GetOutDevType())))
491 bScreenDisplay = false;
493 setOutlinerBgFromPage(rOutl, *pPgView, bScreenDisplay);
497 ViewRedirector aViewRedirector;
498 FmFormView::CompleteRedraw(pOutDev, rReg, pRedirector ? pRedirector : &aViewRedirector);
501 void View::MarkListHasChanged()
503 FmFormView::MarkListHasChanged();
505 if( GetMarkedObjectCount() > 0 )
506 maSmartTags.deselect();
509 bool View::SetAttributes(const SfxItemSet& rSet, bool bReplaceAll, bool /*bSlide*/, bool /*bMaster*/)
511 bool bOk = FmFormView::SetAttributes(rSet, bReplaceAll);
512 return bOk;
515 void View::GetAttributes( SfxItemSet& rTargetSet, bool bOnlyHardAttr ) const
517 FmFormView::GetAttributes( rTargetSet, bOnlyHardAttr );
521 * Is a presentation object selected?
523 bool View::IsPresObjSelected(bool bOnPage, bool bOnMasterPage, bool bCheckPresObjListOnly, bool bCheckLayoutOnly) const
525 SdrMarkList* pMarkList;
527 if (mnDragSrcPgNum != SDRPAGE_NOTFOUND &&
528 mnDragSrcPgNum != GetSdrPageView()->GetPage()->GetPageNum())
530 /* Drag&Drop is in progress
531 Source and destination page are different:
532 we use the saved mark list */
533 pMarkList = mpDragSrcMarkList.get();
535 else
537 // We use the current mark list
538 pMarkList = new SdrMarkList(GetMarkedObjectList());
541 SdrMark* pMark;
542 SdPage* pPage;
544 bool bSelected = false;
545 bool bMasterPage = false;
547 for (size_t nMark = pMarkList->GetMarkCount(); nMark && !bSelected; )
549 --nMark;
550 // Backwards through mark list
551 pMark = pMarkList->GetMark(nMark);
552 SdrObject* pObj = pMark->GetMarkedSdrObj();
554 if ( pObj && ( bCheckPresObjListOnly || pObj->IsEmptyPresObj() || pObj->GetUserCall() ) )
556 pPage = static_cast<SdPage*>( pObj->getSdrPageFromSdrObject() );
557 bMasterPage = pPage && pPage->IsMasterPage();
559 if ( (bMasterPage && bOnMasterPage) || (!bMasterPage && bOnPage) )
561 if ( pPage && pPage->IsPresObj(pObj) )
563 if( bCheckLayoutOnly )
565 PresObjKind eKind = pPage->GetPresObjKind(pObj);
567 if((eKind != PresObjKind::Footer) && (eKind != PresObjKind::Header) && (eKind != PresObjKind::DateTime) && (eKind != PresObjKind::SlideNumber) )
568 bSelected = true;
570 else
572 bSelected = true;
579 if (pMarkList != mpDragSrcMarkList.get())
581 delete pMarkList;
584 return bSelected;
587 void View::SelectAll()
589 if ( IsTextEdit() )
591 OutlinerView* pOLV = GetTextEditOutlinerView();
592 const ::Outliner* pOutliner = GetTextEditOutliner();
593 pOLV->SelectRange( 0, pOutliner->GetParagraphCount() );
595 else
597 MarkAll();
601 bool View::SetStyleSheet(SfxStyleSheet* pStyleSheet, bool bDontRemoveHardAttr)
603 // forward to SdrView
604 FmFormView::SetStyleSheet(pStyleSheet, bDontRemoveHardAttr);
605 return true;
609 * Start text input
611 static void SetSpellOptions( const SdDrawDocument& rDoc, EEControlBits& rCntrl )
613 bool bOnlineSpell = rDoc.GetOnlineSpell();
615 if( bOnlineSpell )
616 rCntrl |= EEControlBits::ONLINESPELLING;
617 else
618 rCntrl &= ~EEControlBits::ONLINESPELLING;
621 void OutlinerMasterViewFilter::Start(SdrOutliner *pOutl)
623 m_pOutl = pOutl;
624 OutlinerView* pOutlView = m_pOutl->GetView(0);
625 m_bReadOnly = pOutlView->IsReadOnly();
626 pOutlView->SetReadOnly(true);
629 void OutlinerMasterViewFilter::End()
631 if (m_pOutl)
633 OutlinerView* pOutlView = m_pOutl->GetView(0);
634 pOutlView->SetReadOnly(m_bReadOnly);
635 m_pOutl = nullptr;
639 SfxViewShell* View::GetSfxViewShell() const
641 SfxViewShell* pRet = nullptr;
643 if (mpViewSh)
644 pRet = &mpViewSh->GetViewShellBase();
646 return pRet;
649 // Create a new view-local UndoManager manager for Impress/Draw
650 std::unique_ptr<SdrUndoManager> View::createLocalTextUndoManager()
652 std::unique_ptr<SdrUndoManager> pUndoManager(new sd::UndoManager);
653 pUndoManager->SetDocShell(mpDocSh);
654 return pUndoManager;
657 bool View::SdrBeginTextEdit(
658 SdrObject* pObj, SdrPageView* pPV, vcl::Window* pWin,
659 bool bIsNewObj,
660 SdrOutliner* pOutl, OutlinerView* pGivenOutlinerView,
661 bool bDontDeleteOutliner, bool bOnlyOneView, bool bGrabFocus )
663 SdrPage* pPage = pObj ? pObj->getSdrPageFromSdrObject() : nullptr;
664 bool bMasterPage = pPage && pPage->IsMasterPage();
666 GetViewShell()->GetViewShellBase().GetEventMultiplexer()->MultiplexEvent(
667 EventMultiplexerEventId::BeginTextEdit, static_cast<void*>(pObj) );
669 if( pOutl==nullptr && pObj )
670 pOutl = SdrMakeOutliner(OutlinerMode::TextObject, pObj->getSdrModelFromSdrObject()).release();
672 // make draw&impress specific initialisations
673 if( pOutl )
675 pOutl->SetStyleSheetPool(static_cast<SfxStyleSheetPool*>( mrDoc.GetStyleSheetPool() ));
676 pOutl->SetCalcFieldValueHdl(LINK(SD_MOD(), SdModule, CalcFieldValueHdl));
677 EEControlBits nCntrl = pOutl->GetControlWord();
678 nCntrl |= EEControlBits::ALLOWBIGOBJS;
679 nCntrl |= EEControlBits::MARKFIELDS;
680 nCntrl |= EEControlBits::AUTOCORRECT;
682 nCntrl &= ~EEControlBits::ULSPACESUMMATION;
683 if ( mrDoc.IsSummationOfParagraphs() )
684 nCntrl |= EEControlBits::ULSPACESUMMATION;
686 SetSpellOptions( mrDoc, nCntrl );
688 pOutl->SetControlWord(nCntrl);
690 Reference< linguistic2::XSpellChecker1 > xSpellChecker( LinguMgr::GetSpellChecker() );
691 if ( xSpellChecker.is() )
692 pOutl->SetSpeller( xSpellChecker );
694 Reference< linguistic2::XHyphenator > xHyphenator( LinguMgr::GetHyphenator() );
695 if( xHyphenator.is() )
696 pOutl->SetHyphenator( xHyphenator );
698 pOutl->SetDefaultLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() );
701 bool bReturn = FmFormView::SdrBeginTextEdit(
702 pObj, pPV, pWin, bIsNewObj, pOutl,
703 pGivenOutlinerView, bDontDeleteOutliner,
704 bOnlyOneView, bGrabFocus);
706 if ( mpViewSh )
708 mpViewSh->GetViewShellBase().GetDrawController()->FireSelectionChangeListener();
710 if (pObj && pObj->GetObjIdentifier() == SdrObjKind::Table)
711 mpViewSh->UpdateScrollBars();
713 if (comphelper::LibreOfficeKit::isActive())
715 if (OutlinerView* pView = GetTextEditOutlinerView())
717 ::tools::Rectangle aRectangle = pView->GetOutputArea();
718 if (pWin && pWin->GetMapMode().GetMapUnit() == MapUnit::Map100thMM)
720 aRectangle = o3tl::convert(aRectangle, o3tl::Length::mm100, o3tl::Length::twip);
722 OString sRectangle = aRectangle.toString();
723 SfxLokHelper::notifyOtherViews(&mpViewSh->GetViewShellBase(), LOK_CALLBACK_VIEW_LOCK, "rectangle", sRectangle);
728 if (::Outliner* pOL = bReturn ? GetTextEditOutliner() : nullptr)
730 if (pObj)
732 if( pObj->GetObjInventor() == SdrInventor::Default && pObj->GetObjIdentifier() == SdrObjKind::Table )
734 Color aBackground = GetTextEditBackgroundColor(*this);
735 pOL->SetBackgroundColor( aBackground );
737 else
739 // tdf#148140 Set the background to determine autocolor.
740 // Use any explicit bg with fallback to underlying page if
741 // none found
742 if (!pObj->setSuitableOutlinerBg(*pOL) && pPV)
743 setOutlinerBgFromPage(*pOL, *pPV, true);
747 pOL->SetParaInsertedHdl(LINK(this, View, OnParagraphInsertedHdl));
748 pOL->SetParaRemovingHdl(LINK(this, View, OnParagraphRemovingHdl));
751 if (bMasterPage && bReturn && pOutl)
753 const SdrTextObj* pTextObj = pOutl->GetTextObj();
754 const SdPage* pSdPage = pTextObj ? static_cast<const SdPage*>(pTextObj->getSdrPageFromSdrObject()) : nullptr;
755 const PresObjKind eKind = pSdPage ? pSdPage->GetPresObjKind(const_cast<SdrTextObj*>(pTextObj)) : PresObjKind::NONE;
756 switch (eKind)
758 case PresObjKind::Title:
759 case PresObjKind::Outline:
760 case PresObjKind::Text:
761 maMasterViewFilter.Start(pOutl);
762 break;
763 default:
764 break;
768 return bReturn;
771 /** ends current text editing */
772 SdrEndTextEditKind View::SdrEndTextEdit(bool bDontDeleteReally)
774 maMasterViewFilter.End();
776 SdrTextObj* xObj = GetTextEditObject();
778 bool bDefaultTextRestored = RestoreDefaultText( xObj );
780 SdrEndTextEditKind eKind = FmFormView::SdrEndTextEdit(bDontDeleteReally);
782 if( bDefaultTextRestored )
784 if( xObj && !xObj->IsEmptyPresObj() )
786 xObj->SetEmptyPresObj( true );
788 else
790 eKind = SdrEndTextEditKind::Unchanged;
793 else if( xObj && xObj->IsEmptyPresObj() )
795 if( xObj && xObj->HasText() )
797 SdrPage* pPage = xObj->getSdrPageFromSdrObject();
798 if( !pPage || !pPage->IsMasterPage() )
799 xObj->SetEmptyPresObj( false );
803 GetViewShell()->GetViewShellBase().GetEventMultiplexer()->MultiplexEvent(
804 EventMultiplexerEventId::EndTextEdit,
805 static_cast<void*>(xObj) );
807 if( xObj )
809 if ( mpViewSh )
811 mpViewSh->GetViewShellBase().GetDrawController()->FireSelectionChangeListener();
813 if (comphelper::LibreOfficeKit::isActive())
814 SfxLokHelper::notifyOtherViews(&mpViewSh->GetViewShellBase(), LOK_CALLBACK_VIEW_LOCK, "rectangle", "EMPTY");
818 SdPage* pPage = dynamic_cast< SdPage* >( xObj->getSdrPageFromSdrObject() );
819 if( pPage )
820 pPage->onEndTextEdit( xObj );
823 return eKind;
826 /** restores the default text if the given text object is currently in edit mode and
827 no text has been entered already. Is only useful just before text edit ends. */
828 bool View::RestoreDefaultText( SdrTextObj* pTextObj )
830 bool bRestored = false;
832 if( pTextObj && (pTextObj == GetTextEditObject()) )
834 if( !pTextObj->HasText() )
836 SdPage* pPage = dynamic_cast< SdPage* >( pTextObj->getSdrPageFromSdrObject() );
838 if(pPage)
840 bRestored = pPage->RestoreDefaultText( pTextObj );
841 if( bRestored )
843 SdrOutliner* pOutliner = GetTextEditOutliner();
844 pTextObj->SetTextEditOutliner( pOutliner );
845 OutlinerParaObject* pParaObj = pTextObj->GetOutlinerParaObject();
846 if (pOutliner)
847 pOutliner->SetText(*pParaObj);
853 return bRestored;
857 * Sets the original size of the marked objects.
859 void View::SetMarkedOriginalSize()
861 std::unique_ptr<SdrUndoGroup> pUndoGroup(new SdrUndoGroup(mrDoc));
862 const size_t nCount = GetMarkedObjectCount();
863 bool bOK = false;
865 for( size_t i = 0; i < nCount; ++i )
867 SdrObject* pObj = GetMarkedObjectByIndex(i);
869 if( pObj->GetObjInventor() == SdrInventor::Default )
871 if( pObj->GetObjIdentifier() == SdrObjKind::OLE2 )
873 uno::Reference < embed::XEmbeddedObject > xObj = static_cast<SdrOle2Obj*>(pObj)->GetObjRef();
874 if( xObj.is() )
876 // TODO/LEAN: working with VisualArea can switch object to running state
878 sal_Int64 nAspect = static_cast<SdrOle2Obj*>(pObj)->GetAspect();
879 Size aOleSize;
881 if ( nAspect == embed::Aspects::MSOLE_ICON )
883 MapMode aMap100( MapUnit::Map100thMM );
884 aOleSize = static_cast<SdrOle2Obj*>(pObj)->GetOrigObjSize( &aMap100 );
885 bOK = true;
887 else
889 MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) );
892 awt::Size aSz = xObj->getVisualAreaSize( nAspect );
893 aOleSize = OutputDevice::LogicToLogic(Size(aSz.Width, aSz.Height), MapMode(aUnit), MapMode(MapUnit::Map100thMM));
894 bOK = true;
896 catch( embed::NoVisualAreaSizeException& )
900 if ( bOK )
902 ::tools::Rectangle aDrawRect( pObj->GetLogicRect() );
904 pUndoGroup->AddAction( mrDoc.GetSdrUndoFactory().CreateUndoGeoObject( *pObj ) );
905 pObj->Resize( aDrawRect.TopLeft(), Fraction( aOleSize.Width(), aDrawRect.GetWidth() ),
906 Fraction( aOleSize.Height(), aDrawRect.GetHeight() ) );
910 else if( pObj->GetObjIdentifier() == SdrObjKind::Graphic )
912 const SdrGrafObj* pSdrGrafObj = static_cast< const SdrGrafObj* >(pObj);
913 const Size aSize = pSdrGrafObj->getOriginalSize( );
914 pUndoGroup->AddAction(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
915 ::tools::Rectangle aRect( pObj->GetLogicRect() );
916 aRect.SetSize( aSize );
917 pObj->SetLogicRect( aRect );
918 bOK = true;
923 if( bOK )
925 pUndoGroup->SetComment(SdResId(STR_UNDO_ORIGINALSIZE));
926 mpDocSh->GetUndoManager()->AddUndoAction(std::move(pUndoGroup));
931 * Connect OLE object to client.
933 void View::DoConnect(SdrOle2Obj* pObj)
935 if (!mpViewSh)
936 return;
938 uno::Reference < embed::XEmbeddedObject > xObj( pObj->GetObjRef() );
939 if( !xObj.is() )
940 return;
942 ::sd::Window* pWindow = mpViewSh->GetActiveWindow();
943 SfxInPlaceClient* pSdClient = mpViewSh-> GetViewShellBase().FindIPClient( xObj, pWindow );
944 if ( pSdClient )
945 return;
947 pSdClient = new Client(pObj, mpViewSh, pWindow);
948 ::tools::Rectangle aRect = pObj->GetLogicRect();
950 // TODO/LEAN: working with visual area can switch object to running state
951 Size aDrawSize = aRect.GetSize();
953 MapMode aMapMode( mrDoc.GetScaleUnit() );
954 Size aObjAreaSize = pObj->GetOrigObjSize( &aMapMode );
956 Fraction aScaleWidth (aDrawSize.Width(), aObjAreaSize.Width() );
957 Fraction aScaleHeight(aDrawSize.Height(), aObjAreaSize.Height() );
958 aScaleWidth.ReduceInaccurate(10); // compatible to SdrOle2Obj
959 aScaleHeight.ReduceInaccurate(10);
960 pSdClient->SetSizeScale(aScaleWidth, aScaleHeight);
962 // visible area is only changed in-place!
963 // the object area must be set after the scaling, since it triggers resize
964 aRect.SetSize(aObjAreaSize);
965 pSdClient->SetObjArea(aRect);
969 bool View::IsMorphingAllowed() const
971 const SdrMarkList& rMarkList = GetMarkedObjectList();
972 bool bRet = false;
974 if ( rMarkList.GetMarkCount() == 2 )
976 const SdrObject* pObj1 = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
977 const SdrObject* pObj2 = rMarkList.GetMark( 1 )->GetMarkedSdrObj();
978 const SdrObjKind nKind1 = pObj1->GetObjIdentifier();
979 const SdrObjKind nKind2 = pObj2->GetObjIdentifier();
981 if ( ( nKind1 != SdrObjKind::Text && nKind2 != SdrObjKind::Text ) &&
982 ( nKind1 != SdrObjKind::TitleText && nKind2 != SdrObjKind::TitleText ) &&
983 ( nKind1 != SdrObjKind::OutlineText && nKind2 != SdrObjKind::OutlineText ) &&
984 ( nKind1 != SdrObjKind::Group && nKind2 != SdrObjKind::Group ) &&
985 ( nKind1 != SdrObjKind::Line && nKind2 != SdrObjKind::Line ) &&
986 ( nKind1 != SdrObjKind::PolyLine && nKind2 != SdrObjKind::PolyLine ) &&
987 ( nKind1 != SdrObjKind::PathLine && nKind2 != SdrObjKind::PathLine ) &&
988 ( nKind1 != SdrObjKind::FreehandLine && nKind2 != SdrObjKind::FreehandLine ) &&
989 ( nKind1 != SdrObjKind::PathPolyLine && nKind2 != SdrObjKind::PathPolyLine ) &&
990 ( nKind1 != SdrObjKind::Measure && nKind2 != SdrObjKind::Measure ) &&
991 ( nKind1 != SdrObjKind::Edge && nKind2 != SdrObjKind::Edge ) &&
992 ( nKind1 != SdrObjKind::Graphic && nKind2 != SdrObjKind::Graphic ) &&
993 ( nKind1 != SdrObjKind::OLE2 && nKind2 != SdrObjKind::OLE2 ) &&
994 ( nKind1 != SdrObjKind::Caption && nKind2 != SdrObjKind::Caption ) &&
995 DynCastE3dObject( pObj1 ) == nullptr && DynCastE3dObject( pObj2 ) == nullptr )
997 SfxItemSetFixed<XATTR_FILLSTYLE, XATTR_FILLSTYLE> aSet1( mrDoc.GetPool() );
998 SfxItemSetFixed<XATTR_FILLSTYLE, XATTR_FILLSTYLE> aSet2( mrDoc.GetPool() );
1000 aSet1.Put(pObj1->GetMergedItemSet());
1001 aSet2.Put(pObj2->GetMergedItemSet());
1003 const drawing::FillStyle eFillStyle1 = aSet1.Get( XATTR_FILLSTYLE ).GetValue();
1004 const drawing::FillStyle eFillStyle2 = aSet2.Get( XATTR_FILLSTYLE ).GetValue();
1006 if( ( eFillStyle1 == drawing::FillStyle_NONE || eFillStyle1 == drawing::FillStyle_SOLID ) &&
1007 ( eFillStyle2 == drawing::FillStyle_NONE || eFillStyle2 == drawing::FillStyle_SOLID ) )
1008 bRet = true;
1012 return bRet;
1015 bool View::IsVectorizeAllowed() const
1017 const SdrMarkList& rMarkList = GetMarkedObjectList();
1018 bool bRet = false;
1020 if( rMarkList.GetMarkCount() == 1 )
1022 const SdrGrafObj* pObj = dynamic_cast< const SdrGrafObj* >(rMarkList.GetMark( 0 )->GetMarkedSdrObj());
1024 if(pObj)
1026 if(GraphicType::Bitmap == pObj->GetGraphicType() && !pObj->isEmbeddedVectorGraphicData())
1028 bRet = true;
1033 return bRet;
1036 void View::onAccessibilityOptionsChanged()
1038 if( !mpViewSh )
1039 return;
1041 ::sd::Window* pWindow = mpViewSh->GetActiveWindow();
1042 if( !pWindow )
1043 return;
1045 const StyleSettings& rStyleSettings = pWindow->GetSettings().GetStyleSettings();
1047 if( mpViewSh->GetViewFrame() && mpViewSh->GetViewFrame()->GetDispatcher() )
1049 sal_uInt16 nOutputSlot, nPreviewSlot;
1051 if( rStyleSettings.GetHighContrastMode() )
1053 nOutputSlot = SID_OUTPUT_QUALITY_CONTRAST;
1055 else
1057 nOutputSlot = SID_OUTPUT_QUALITY_COLOR;
1060 if( rStyleSettings.GetHighContrastMode()
1061 && officecfg::Office::Common::Accessibility::IsForPagePreviews::get() )
1063 nPreviewSlot = SID_PREVIEW_QUALITY_CONTRAST;
1065 else
1067 nPreviewSlot = SID_PREVIEW_QUALITY_COLOR;
1070 mpViewSh->GetViewFrame()->GetDispatcher()->Execute( nOutputSlot, SfxCallMode::ASYNCHRON );
1071 mpViewSh->GetViewFrame()->GetDispatcher()->Execute( nPreviewSlot, SfxCallMode::ASYNCHRON );
1074 mpViewSh->Invalidate();
1077 IMPL_LINK( View, OnParagraphInsertedHdl, ::Outliner::ParagraphHdlParam, aParam, void )
1079 SdrObject* pObj = GetTextEditObject();
1081 if( aParam.pPara && pObj )
1083 SdPage* pPage = dynamic_cast< SdPage* >( pObj->getSdrPageFromSdrObject() );
1084 if( pPage )
1085 pPage->onParagraphInserted( aParam.pOutliner, aParam.pPara, pObj );
1090 * Handler for the deletion of the pages (paragraphs).
1092 IMPL_LINK( View, OnParagraphRemovingHdl, ::Outliner::ParagraphHdlParam, aParam, void )
1094 SdrObject* pObj = GetTextEditObject();
1096 if( aParam.pPara && pObj )
1098 SdPage* pPage = dynamic_cast< SdPage* >( pObj->getSdrPageFromSdrObject() );
1099 if( pPage )
1100 pPage->onParagraphRemoving( aParam.pOutliner, aParam.pPara, pObj );
1104 bool View::isRecordingUndo() const
1106 if( mrDoc.IsUndoEnabled() )
1108 sd::UndoManager* pUndoManager = mrDoc.GetUndoManager();
1109 return pUndoManager && pUndoManager->IsInListAction();
1111 else
1113 return false;
1117 void View::AddCustomHdl()
1119 maSmartTags.addCustomHandles( maHdlList );
1122 void View::updateHandles()
1124 AdjustMarkHdl();
1127 SdrViewContext View::GetContext() const
1129 SdrViewContext eContext = SdrViewContext::Standard;
1130 if( maSmartTags.getContext( eContext ) )
1131 return eContext;
1132 else
1133 return FmFormView::GetContext();
1136 bool View::HasMarkablePoints() const
1138 if( maSmartTags.HasMarkablePoints() )
1139 return true;
1140 else
1141 return FmFormView::HasMarkablePoints();
1144 sal_Int32 View::GetMarkablePointCount() const
1146 sal_Int32 nCount = FmFormView::GetMarkablePointCount();
1147 nCount += maSmartTags.GetMarkablePointCount();
1148 return nCount;
1151 bool View::HasMarkedPoints() const
1153 if( maSmartTags.HasMarkedPoints() )
1154 return true;
1155 else
1156 return FmFormView::HasMarkedPoints();
1159 bool View::MarkPoint(SdrHdl& rHdl, bool bUnmark )
1161 if( maSmartTags.MarkPoint( rHdl, bUnmark ) )
1162 return true;
1163 else
1164 return FmFormView::MarkPoint( rHdl, bUnmark );
1167 bool View::MarkPoints(const ::tools::Rectangle* pRect, bool bUnmark)
1169 if( maSmartTags.MarkPoints( pRect, bUnmark ) )
1170 return true;
1171 else
1172 return FmFormView::MarkPoints( pRect, bUnmark );
1175 void View::CheckPossibilities()
1177 FmFormView::CheckPossibilities();
1178 maSmartTags.CheckPossibilities();
1181 void View::OnBeginPasteOrDrop( PasteOrDropInfos* pInfo )
1183 SdrOutliner* pOutliner = GetTextEditOutliner();
1184 if (!pOutliner)
1185 return;
1187 // Turn character attributes of the paragraph of the insert position into
1188 // character-level attributes, so they are not lost when OnEndPasteOrDrop()
1189 // sets the paragraph stylesheet.
1190 SfxItemSet aSet(pOutliner->GetParaAttribs(pInfo->nStartPara));
1191 pOutliner->SetCharAttribs(pInfo->nStartPara, aSet);
1194 /** this is called after a paste or drop operation, make sure that the newly inserted paragraphs
1195 get the correct style sheet. */
1196 void View::OnEndPasteOrDrop( PasteOrDropInfos* pInfo )
1198 /* Style Sheet handling */
1199 SdrTextObj* pTextObj = GetTextEditObject();
1200 SdrOutliner* pOutliner = GetTextEditOutliner();
1201 if( !pOutliner || !pTextObj || !pTextObj->getSdrPageFromSdrObject() )
1202 return;
1204 SdPage* pPage = static_cast< SdPage* >( pTextObj->getSdrPageFromSdrObject() );
1205 const PresObjKind eKind = pPage->GetPresObjKind(pTextObj);
1207 // outline kinds are taken care of in Outliner::ImplSetLevelDependentStyleSheet
1208 if( eKind == PresObjKind::Outline )
1209 return;
1211 SfxStyleSheet* pStyleSheet = nullptr;
1212 if( eKind != PresObjKind::NONE )
1213 pStyleSheet = pPage->GetStyleSheetForPresObj(eKind);
1214 else
1215 pStyleSheet = pTextObj->GetStyleSheet();
1216 // just put the object style on each new paragraph
1217 for ( sal_Int32 nPara = pInfo->nStartPara; nPara <= pInfo->nEndPara; nPara++ )
1219 pOutliner->SetStyleSheet( nPara, pStyleSheet );
1223 bool View::ShouldToggleOn(
1224 const bool bBulletOnOffMode,
1225 const bool bNormalBullet)
1227 // If setting bullets/numbering by the dialog, always should toggle on.
1228 if (!bBulletOnOffMode)
1229 return true;
1230 SdrModel& rSdrModel = GetModel();
1232 bool bToggleOn = false;
1233 std::unique_ptr<SdrOutliner> pOutliner(SdrMakeOutliner(OutlinerMode::TextObject, rSdrModel));
1234 const size_t nMarkCount = GetMarkedObjectCount();
1235 for (size_t nIndex = 0; nIndex < nMarkCount && !bToggleOn; ++nIndex)
1237 SdrTextObj* pTextObj = DynCastSdrTextObj(GetMarkedObjectByIndex(nIndex));
1238 if (!pTextObj || pTextObj->IsTextEditActive())
1239 continue;
1240 if( dynamic_cast< const SdrTableObj *>( pTextObj ) != nullptr)
1242 SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >(pTextObj);
1243 if (!pTableObj)
1244 continue;
1245 CellPos aStart, aEnd;
1246 SvxTableController* pTableController = dynamic_cast< SvxTableController* >(getSelectionController().get());
1247 if (pTableController)
1249 pTableController->getSelectedCells(aStart, aEnd);
1251 else
1253 aStart = SdrTableObj::getFirstCell();
1254 aEnd = pTableObj->getLastCell();
1256 sal_Int32 nColCount = pTableObj->getColumnCount();
1257 for (sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow && !bToggleOn; nRow++)
1259 for (sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol && !bToggleOn; nCol++)
1261 sal_Int32 nCellIndex = nRow * nColCount + nCol;
1262 SdrText* pText = pTableObj->getText(nCellIndex);
1263 if (!pText || !pText->GetOutlinerParaObject())
1264 continue;
1265 pOutliner->SetText(*(pText->GetOutlinerParaObject()));
1266 sal_Int16 nStatus = pOutliner->GetBulletsNumberingStatus();
1267 bToggleOn = (bNormalBullet && nStatus != 0) || (!bNormalBullet && nStatus != 1);
1268 pOutliner->Clear();
1272 else
1274 OutlinerParaObject* pParaObj = pTextObj->GetOutlinerParaObject();
1275 if (!pParaObj)
1276 continue;
1277 pOutliner->SetText(*pParaObj);
1278 sal_Int16 nStatus = pOutliner->GetBulletsNumberingStatus();
1279 bToggleOn = (bNormalBullet && nStatus != 0) || (!bNormalBullet && nStatus != 1);
1280 pOutliner->Clear();
1283 return bToggleOn;
1286 void View::ChangeMarkedObjectsBulletsNumbering(
1287 const bool bToggle,
1288 const bool bHandleBullets,
1289 const SvxNumRule* pNumRule )
1291 SdrModel& rSdrModel = GetModel();
1292 OutputDevice* pOut = GetFirstOutputDevice();
1293 vcl::Window* pWindow = pOut ? pOut->GetOwnerWindow() : nullptr;
1294 if (!pWindow)
1295 return;
1297 const bool bUndoEnabled = rSdrModel.IsUndoEnabled();
1298 std::unique_ptr<SdrUndoGroup> pUndoGroup(bUndoEnabled ? new SdrUndoGroup(rSdrModel) : nullptr);
1300 const bool bToggleOn = ShouldToggleOn( bToggle, bHandleBullets );
1302 std::unique_ptr<SdrOutliner> pOutliner(SdrMakeOutliner(OutlinerMode::TextObject, rSdrModel));
1303 OutlinerView aOutlinerView(pOutliner.get(), pWindow);
1305 const size_t nMarkCount = GetMarkedObjectCount();
1306 for (size_t nIndex = 0; nIndex < nMarkCount; ++nIndex)
1308 SdrTextObj* pTextObj = DynCastSdrTextObj(GetMarkedObjectByIndex(nIndex));
1309 if (!pTextObj || pTextObj->IsTextEditActive())
1310 continue;
1311 if( dynamic_cast< SdrTableObj *>( pTextObj ) != nullptr)
1313 SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >(pTextObj);
1314 if (!pTableObj)
1315 continue;
1316 CellPos aStart, aEnd;
1317 SvxTableController* pTableController = dynamic_cast< SvxTableController* >(getSelectionController().get());
1318 if (pTableController)
1320 pTableController->getSelectedCells(aStart, aEnd);
1322 else
1324 aStart = SdrTableObj::getFirstCell();
1325 aEnd = pTableObj->getLastCell();
1327 sal_Int32 nColCount = pTableObj->getColumnCount();
1328 for (sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++)
1330 for (sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++)
1332 sal_Int32 nCellIndex = nRow * nColCount + nCol;
1333 SdrText* pText = pTableObj->getText(nCellIndex);
1334 if (!pText || !pText->GetOutlinerParaObject())
1335 continue;
1337 pOutliner->SetText(*(pText->GetOutlinerParaObject()));
1338 if (bUndoEnabled)
1340 pUndoGroup->AddAction(rSdrModel.GetSdrUndoFactory().CreateUndoObjectSetText(*pTextObj, nCellIndex));
1342 if ( !bToggleOn )
1344 aOutlinerView.SwitchOffBulletsNumbering();
1346 else
1348 aOutlinerView.ApplyBulletsNumbering( bHandleBullets, pNumRule, bToggle );
1350 sal_uInt32 nParaCount = pOutliner->GetParagraphCount();
1351 pText->SetOutlinerParaObject(pOutliner->CreateParaObject(0, static_cast<sal_uInt16>(nParaCount)));
1352 pOutliner->Clear();
1355 // Broadcast the object change event.
1356 if (!pTextObj->AdjustTextFrameWidthAndHeight())
1358 pTextObj->SetChanged();
1359 pTextObj->BroadcastObjectChange();
1362 else
1364 OutlinerParaObject* pParaObj = pTextObj->GetOutlinerParaObject();
1365 if (!pParaObj)
1366 continue;
1367 pOutliner->SetText(*pParaObj);
1368 if (bUndoEnabled)
1370 pUndoGroup->AddAction(
1371 rSdrModel.GetSdrUndoFactory().CreateUndoObjectSetText(*pTextObj, 0));
1373 if ( !bToggleOn )
1375 aOutlinerView.SwitchOffBulletsNumbering();
1377 else
1379 aOutlinerView.ApplyBulletsNumbering( bHandleBullets, pNumRule, bToggle );
1381 sal_uInt32 nParaCount = pOutliner->GetParagraphCount();
1382 pTextObj->SetOutlinerParaObject(pOutliner->CreateParaObject(0, static_cast<sal_uInt16>(nParaCount)));
1383 pOutliner->Clear();
1387 if ( bUndoEnabled && pUndoGroup->GetActionCount() > 0 )
1389 rSdrModel.BegUndo();
1390 rSdrModel.AddUndo(std::move(pUndoGroup));
1391 rSdrModel.EndUndo();
1395 } // end of namespace sd
1397 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */