LibreOffice Module svx (master)  1
svdedxv.cxx
Go to the documentation of this file.
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 <com/sun/star/i18n/WordType.hpp>
21 #include <editeng/editdata.hxx>
22 #include <editeng/editeng.hxx>
23 #include <editeng/editobj.hxx>
24 #include <editeng/editstat.hxx>
25 #include <editeng/outlobj.hxx>
26 #include <editeng/unotext.hxx>
27 #include <svl/itemiter.hxx>
28 #include <svl/solar.hrc>
29 #include <svl/style.hxx>
30 #include <svl/whiter.hxx>
32 #include <svx/sdtfchim.hxx>
34 #include <svx/svdedxv.hxx>
35 #include <svx/svdetc.hxx>
36 #include <svx/svditer.hxx>
37 #include <svx/svdotable.hxx>
38 #include <svx/svdotext.hxx>
39 #include <svx/svdoutl.hxx>
40 #include <svx/svdpage.hxx>
41 #include <svx/svdpagv.hxx>
42 #include <svx/svdundo.hxx>
43 #include <vcl/canvastools.hxx>
44 #include <vcl/commandevent.hxx>
45 #include <vcl/cursor.hxx>
46 #include <vcl/hatch.hxx>
47 #include <vcl/weld.hxx>
48 #include <comphelper/lok.hxx>
51 #include <editeng/adjustitem.hxx>
52 #include <editeng/outliner.hxx>
53 #include <sal/log.hxx>
55 #include <sfx2/viewsh.hxx>
56 #include <svtools/colorcfg.hxx>
57 #include <svx/dialmgr.hxx>
58 #include <svx/globl3d.hxx>
62 #include <svx/sdrpagewindow.hxx>
63 #include <svx/sdrpaintwindow.hxx>
64 #include <svx/sdrundomanager.hxx>
65 #include <svx/strings.hrc>
66 #include <svx/svddrgv.hxx>
67 #include <svx/svdviter.hxx>
68 #include <svx/textchain.hxx>
69 #include <svx/textchaincursor.hxx>
70 #include <tools/debug.hxx>
71 #include <vcl/svapp.hxx>
72 
73 #include <memory>
74 
76 {
77  bQuickTextEditMode = true;
78  pTextEditOutliner.reset();
79  pTextEditOutlinerView = nullptr;
80  pTextEditPV = nullptr;
81  pTextEditWin = nullptr;
82  pTextEditCursorBuffer = nullptr;
83  bTextEditNewObj = false;
84  bMacroDown = false;
85  pMacroObj = nullptr;
86  pMacroPV = nullptr;
87  pMacroWin = nullptr;
88  nMacroTol = 0;
89  bTextEditDontDelete = false;
90  bTextEditOnlyOneView = false;
91 }
92 
94  : SdrGlueEditView(rSdrModel, pOut)
95  , mpOldTextEditUndoManager(nullptr)
96 {
97  ImpClearVars();
98 }
99 
101 {
102  pTextEditWin = nullptr; // so there's no ShowCursor in SdrEndTextEdit
103  assert(!IsTextEdit());
104  if (IsTextEdit())
105  SdrEndTextEdit();
106  pTextEditOutliner.reset();
107  assert(nullptr == mpOldTextEditUndoManager); // should have been reset
108 }
109 
111 
113 {
114  if (IsMacroObj())
115  MovMacroObj(rPnt);
117 }
118 
120 {
121  if (IsMacroObj())
122  EndMacroObj();
124 }
125 
127 {
128  BrkMacroObj();
130 }
131 
133 {
134  BrkMacroObj();
136 }
137 
139 {
140  SdrPageView* pPageView = SdrGlueEditView::ShowSdrPage(pPage);
141 
142  if (comphelper::LibreOfficeKit::isActive() && pPageView)
143  {
144  // Check if other views have an active text edit on the same page as
145  // this one.
146  SdrViewIter aIter(pPageView->GetPage());
147  for (SdrView* pView = aIter.FirstView(); pView; pView = aIter.NextView())
148  {
149  if (pView == this || !pView->IsTextEdit())
150  continue;
151 
152  OutputDevice* pOutDev = GetFirstOutputDevice();
153  if (!pOutDev || pOutDev->GetOutDevType() != OUTDEV_WINDOW)
154  continue;
155 
156  // Found one, so create an outliner view, to get invalidations when
157  // the text edit changes.
158  // Call GetSfxViewShell() to make sure ImpMakeOutlinerView()
159  // registers the view shell of this draw view, and not the view
160  // shell of pView.
161  OutlinerView* pOutlinerView = pView->ImpMakeOutlinerView(
162  static_cast<vcl::Window*>(pOutDev), nullptr, GetSfxViewShell());
163  pOutlinerView->HideCursor();
164  pView->GetTextEditOutliner()->InsertView(pOutlinerView);
165  }
166  }
167 
168  return pPageView;
169 }
170 
171 namespace
172 {
174 void lcl_RemoveTextEditOutlinerViews(SdrObjEditView const* pThis, SdrPageView const* pPageView,
175  OutputDevice const* pOutputDevice)
176 {
178  return;
179 
180  if (!pPageView)
181  return;
182 
183  if (!pOutputDevice || pOutputDevice->GetOutDevType() != OUTDEV_WINDOW)
184  return;
185 
186  SdrViewIter aIter(pPageView->GetPage());
187  for (SdrView* pView = aIter.FirstView(); pView; pView = aIter.NextView())
188  {
189  if (pView == pThis || !pView->IsTextEdit())
190  continue;
191 
192  SdrOutliner* pOutliner = pView->GetTextEditOutliner();
193  for (size_t nView = 0; nView < pOutliner->GetViewCount(); ++nView)
194  {
195  OutlinerView* pOutlinerView = pOutliner->GetView(nView);
196  if (pOutlinerView->GetWindow() != pOutputDevice)
197  continue;
198 
199  pOutliner->RemoveView(pOutlinerView);
200  delete pOutlinerView;
201  }
202  }
203 }
204 }
205 
207 {
208  lcl_RemoveTextEditOutlinerViews(this, GetSdrPageView(), GetFirstOutputDevice());
209 
211 }
212 
214 {
215  if (IsMacroObj())
216  {
217  rRect = pMacroObj->GetCurrentBoundRect();
218  }
219  else
220  {
222  }
223 }
224 
226 {
227  SdrGlueEditView::Notify(rBC, rHint);
228  if (pTextEditOutliner != nullptr)
229  {
230  // change of printer while editing
231  if (rHint.GetId() == SfxHintId::ThisIsAnSdrHint)
232  {
233  const SdrHint* pSdrHint = static_cast<const SdrHint*>(&rHint);
234  SdrHintKind eKind = pSdrHint->GetKind();
235  if (eKind == SdrHintKind::RefDeviceChange)
236  {
237  pTextEditOutliner->SetRefDevice(mpModel->GetRefDevice());
238  }
239  if (eKind == SdrHintKind::DefaultTabChange)
240  {
242  }
243  }
244  }
245 }
246 
248 {
251  SdrEndTextEdit(); // object deleted
252  // TextEditObj changed?
253  if (IsTextEdit())
254  {
255  SdrTextObj* pTextObj = mxTextEditObj.get();
256  if (pTextObj != nullptr)
257  {
258  size_t nOutlViewCnt = pTextEditOutliner->GetViewCount();
259  bool bAreaChg = false;
260  bool bAnchorChg = false;
261  bool bColorChg = false;
262  bool bContourFrame = pTextObj->IsContourTextFrame();
263  EEAnchorMode eNewAnchor(EEAnchorMode::VCenterHCenter);
265  aOldArea.Union(aTextEditArea);
266  Color aNewColor;
267  { // check area
268  Size aPaperMin1;
269  Size aPaperMax1;
270  tools::Rectangle aEditArea1;
271  tools::Rectangle aMinArea1;
272  pTextObj->TakeTextEditArea(&aPaperMin1, &aPaperMax1, &aEditArea1, &aMinArea1);
273  Point aPvOfs(pTextObj->GetTextEditOffset());
274 
275  // add possible GridOffset to up-to-now view-independent EditAreas
276  basegfx::B2DVector aGridOffset(0.0, 0.0);
277  if (getPossibleGridOffsetForSdrObject(aGridOffset, pTextObj, GetSdrPageView()))
278  {
279  const Point aOffset(basegfx::fround(aGridOffset.getX()),
280  basegfx::fround(aGridOffset.getY()));
281 
282  aEditArea1 += aOffset;
283  aMinArea1 += aOffset;
284  }
285 
286  aEditArea1.Move(aPvOfs.X(), aPvOfs.Y());
287  aMinArea1.Move(aPvOfs.X(), aPvOfs.Y());
288  tools::Rectangle aNewArea(aMinArea1);
289  aNewArea.Union(aEditArea1);
290 
291  if (aNewArea != aOldArea || aEditArea1 != aTextEditArea
292  || aMinArea1 != aMinTextEditArea
293  || pTextEditOutliner->GetMinAutoPaperSize() != aPaperMin1
294  || pTextEditOutliner->GetMaxAutoPaperSize() != aPaperMax1)
295  {
296  aTextEditArea = aEditArea1;
297  aMinTextEditArea = aMinArea1;
298  pTextEditOutliner->SetUpdateMode(false);
299  pTextEditOutliner->SetMinAutoPaperSize(aPaperMin1);
300  pTextEditOutliner->SetMaxAutoPaperSize(aPaperMax1);
301  pTextEditOutliner->SetPaperSize(Size(0, 0)); // re-format Outliner
302  if (!bContourFrame)
303  {
304  pTextEditOutliner->ClearPolygon();
305  EEControlBits nStat = pTextEditOutliner->GetControlWord();
306  nStat |= EEControlBits::AUTOPAGESIZE;
307  pTextEditOutliner->SetControlWord(nStat);
308  }
309  else
310  {
311  EEControlBits nStat = pTextEditOutliner->GetControlWord();
312  nStat &= ~EEControlBits::AUTOPAGESIZE;
313  pTextEditOutliner->SetControlWord(nStat);
314  tools::Rectangle aAnchorRect;
315  pTextObj->TakeTextAnchorRect(aAnchorRect);
316  pTextObj->ImpSetContourPolygon(*pTextEditOutliner, aAnchorRect, true);
317  }
318  for (size_t nOV = 0; nOV < nOutlViewCnt; nOV++)
319  {
320  OutlinerView* pOLV = pTextEditOutliner->GetView(nOV);
321  EVControlBits nStat0 = pOLV->GetControlWord();
322  EVControlBits nStat = nStat0;
323  // AutoViewSize only if not ContourFrame.
324  if (!bContourFrame)
325  nStat |= EVControlBits::AUTOSIZE;
326  else
327  nStat &= ~EVControlBits::AUTOSIZE;
328  if (nStat != nStat0)
329  pOLV->SetControlWord(nStat);
330  }
331  pTextEditOutliner->SetUpdateMode(true);
332  bAreaChg = true;
333  }
334  }
335  if (pTextEditOutlinerView != nullptr)
336  { // check fill and anchor
338  eNewAnchor = pTextObj->GetOutlinerViewAnchorMode();
339  bAnchorChg = eOldAnchor != eNewAnchor;
341  aNewColor = GetTextEditBackgroundColor(*this);
342  bColorChg = aOldColor != aNewColor;
343  }
344  // refresh always when it's a contour frame. That
345  // refresh is necessary since it triggers the repaint
346  // which makes the Handles visible. Changes at TakeTextRect()
347  // seem to have resulted in a case where no refresh is executed.
348  // Before that, a refresh must have been always executed
349  // (else this error would have happened earlier), thus I
350  // even think here a refresh should be done always.
351  // Since follow-up problems cannot even be guessed I only
352  // add this one more case to the if below.
353  // BTW: It's VERY bad style that here, inside ModelHasChanged()
354  // the outliner is again massively changed for the text object
355  // in text edit mode. Normally, all necessary data should be
356  // set at SdrBeginTextEdit(). Some changes and value assigns in
357  // SdrBeginTextEdit() are completely useless since they are set here
358  // again on ModelHasChanged().
359  if (bContourFrame || bAreaChg || bAnchorChg || bColorChg)
360  {
361  for (size_t nOV = 0; nOV < nOutlViewCnt; nOV++)
362  {
363  OutlinerView* pOLV = pTextEditOutliner->GetView(nOV);
364  { // invalidate old OutlinerView area
365  vcl::Window* pWin = pOLV->GetWindow();
366  tools::Rectangle aTmpRect(aOldArea);
367  sal_uInt16 nPixSiz = pOLV->GetInvalidateMore() + 1;
368  Size aMore(pWin->PixelToLogic(Size(nPixSiz, nPixSiz)));
369  aTmpRect.AdjustLeft(-(aMore.Width()));
370  aTmpRect.AdjustRight(aMore.Width());
371  aTmpRect.AdjustTop(-(aMore.Height()));
372  aTmpRect.AdjustBottom(aMore.Height());
373  InvalidateOneWin(*pWin, aTmpRect);
374  }
375  if (bAnchorChg)
376  pOLV->SetAnchorMode(eNewAnchor);
377  if (bColorChg)
378  pOLV->SetBackgroundColor(aNewColor);
379 
380  pOLV->SetOutputArea(
381  aTextEditArea); // because otherwise, we're not re-anchoring correctly
383  }
385  }
386  }
388  }
389 }
390 
391 namespace
392 {
406 class TextEditOverlayObject : public sdr::overlay::OverlayObject
407 {
408 protected:
410  sdr::overlay::OverlaySelection* mpOverlaySelection;
411 
413  OutlinerView& mrOutlinerView;
414 
416  basegfx::B2DRange maLastRange;
418 
422 
424  bool const mbVisualizeSurroundingFrame : 1;
425 
426  // geometry creation for OverlayObject, can use local *Last* values
429 
430 public:
431  TextEditOverlayObject(const Color& rColor, OutlinerView& rOutlinerView,
432  bool bVisualizeSurroundingFrame);
433  virtual ~TextEditOverlayObject() override;
434 
435  // data read access
436  const sdr::overlay::OverlaySelection* getOverlaySelection() const { return mpOverlaySelection; }
437  const OutlinerView& getOutlinerView() const { return mrOutlinerView; }
438 
441  getOverlayObjectPrimitive2DSequence() const override;
442 
443  // data write access. In this OverlayObject we only have the
444  // callback that triggers detecting if something *has* changed
445  void checkDataChange(const basegfx::B2DRange& rMinTextEditArea);
446  void checkSelectionChange();
447 };
448 
450 TextEditOverlayObject::createOverlayObjectPrimitive2DSequence()
451 {
453 
455  if (mbVisualizeSurroundingFrame)
456  {
457  const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
458  const double fTransparence(aSvtOptionsDrawinglayer.GetTransparentSelectionPercent() * 0.01);
459  const sal_uInt16 nPixSiz(getOutlinerView().GetInvalidateMore() - 1);
460 
462  maRange, getBaseColor().getBColor(), fTransparence, std::max(6, nPixSiz - 2), // grow
463  0.0, // shrink
464  0.0));
465  }
466 
467  // add buffered TextPrimitives
468  aRetval.append(maTextPrimitives);
469 
470  return aRetval;
471 }
472 
473 TextEditOverlayObject::TextEditOverlayObject(const Color& rColor, OutlinerView& rOutlinerView,
474  bool bVisualizeSurroundingFrame)
475  : OverlayObject(rColor)
476  , mpOverlaySelection(nullptr)
477  , mrOutlinerView(rOutlinerView)
478  , maLastRange()
479  , maRange()
480  , maTextPrimitives()
481  , maLastTextPrimitives()
482  , mbVisualizeSurroundingFrame(bVisualizeSurroundingFrame)
483 {
484  // no AA for TextEdit overlay
485  allowAntiAliase(false);
486 
487  // create local OverlaySelection - this is an integral part of EditText
488  // visualization
489  const std::vector<basegfx::B2DRange> aEmptySelection{};
491  rColor, aEmptySelection, true);
492 }
493 
494 TextEditOverlayObject::~TextEditOverlayObject()
495 {
496  if (getOverlaySelection())
497  {
498  delete mpOverlaySelection;
499  mpOverlaySelection = nullptr;
500  }
501 
502  if (getOverlayManager())
503  {
504  getOverlayManager()->remove(*this);
505  }
506 }
507 
509 TextEditOverlayObject::getOverlayObjectPrimitive2DSequence() const
510 {
511  if (!getPrimitive2DSequence().empty())
512  {
513  if (!maRange.equal(maLastRange) || maLastTextPrimitives != maTextPrimitives)
514  {
515  // conditions of last local decomposition have changed, delete to force new evaluation
516  const_cast<TextEditOverlayObject*>(this)->resetPrimitive2DSequence();
517  }
518  }
519 
520  if (getPrimitive2DSequence().empty())
521  {
522  // remember new buffered values
523  const_cast<TextEditOverlayObject*>(this)->maLastRange = maRange;
524  const_cast<TextEditOverlayObject*>(this)->maLastTextPrimitives = maTextPrimitives;
525  }
526 
527  // call base implementation
528  return OverlayObject::getOverlayObjectPrimitive2DSequence();
529 }
530 
531 void TextEditOverlayObject::checkDataChange(const basegfx::B2DRange& rMinTextEditArea)
532 {
533  bool bObjectChange(false);
534 
535  // check current range
536  const tools::Rectangle aOutArea(mrOutlinerView.GetOutputArea());
538  aNewRange.expand(rMinTextEditArea);
539 
540  if (aNewRange != maRange)
541  {
542  maRange = aNewRange;
543  bObjectChange = true;
544  }
545 
546  // check if text primitives did change
547  SdrOutliner* pSdrOutliner = dynamic_cast<SdrOutliner*>(getOutlinerView().GetOutliner());
548 
549  if (pSdrOutliner)
550  {
551  // get TextPrimitives directly from active Outliner
552  basegfx::B2DHomMatrix aNewTransformA;
553  basegfx::B2DHomMatrix aNewTransformB;
554  basegfx::B2DRange aClipRange;
556 
557  // active Outliner is always in unified oriented coordinate system (currently)
558  // so just translate to TopLeft of visible Range. Keep in mind that top-left
559  // depends on vertical text and top-to-bottom text attributes
560  const tools::Rectangle aVisArea(mrOutlinerView.GetVisArea());
561  const bool bVerticalWriting(pSdrOutliner->IsVertical());
562  const bool bTopToBottom(pSdrOutliner->IsTopToBottom());
563  const double fStartInX(bVerticalWriting && bTopToBottom
564  ? aOutArea.Right() - aVisArea.Left()
565  : aOutArea.Left() - aVisArea.Left());
566  const double fStartInY(bVerticalWriting && !bTopToBottom
567  ? aOutArea.Bottom() - aVisArea.Top()
568  : aOutArea.Top() - aVisArea.Top());
569 
570  aNewTransformB.translate(fStartInX, fStartInY);
571 
572  // get the current TextPrimitives. This is the most expensive part
573  // of this mechanism, it *may* be possible to buffer layouted
574  // primitives per ParaPortion with/in/dependent on the EditEngine
575  // content if needed. For now, get and compare
577  aNewTextPrimitives, *pSdrOutliner, aNewTransformA, aNewTransformB, aClipRange);
578 
579  if (aNewTextPrimitives != maTextPrimitives)
580  {
581  maTextPrimitives = aNewTextPrimitives;
582  bObjectChange = true;
583  }
584  }
585 
586  if (bObjectChange)
587  {
588  // if there really *was* a change signal the OverlayManager to
589  // refresh this object's visualization
590  objectChange();
591 
592  // on data change, always do a SelectionChange, too
593  // since the selection is an integral part of text visualization
594  checkSelectionChange();
595  }
596 }
597 
598 void TextEditOverlayObject::checkSelectionChange()
599 {
600  if (getOverlaySelection() && getOverlayManager())
601  {
602  std::vector<tools::Rectangle> aLogicRects;
603  std::vector<basegfx::B2DRange> aLogicRanges;
604  const Size aLogicPixel(getOverlayManager()->getOutputDevice().PixelToLogic(Size(1, 1)));
605 
606  // get logic selection
607  getOutlinerView().GetSelectionRectangles(aLogicRects);
608 
609  aLogicRanges.reserve(aLogicRects.size());
610  for (const auto& aRect : aLogicRects)
611  {
612  // convert from logic Rectangles to logic Ranges, do not forget to add
613  // one Unit (in this case logical units for one pixel, pre-calculated)
614  aLogicRanges.emplace_back(
615  aRect.Left() - aLogicPixel.Width(), aRect.Top() - aLogicPixel.Height(),
616  aRect.Right() + aLogicPixel.Width(), aRect.Bottom() + aLogicPixel.Height());
617  }
618 
619  mpOverlaySelection->setRanges(aLogicRanges);
620  }
621 }
622 } // end of anonymous namespace
623 
624 // TextEdit
625 
626 // callback from the active EditView, forward to evtl. existing instances of the
627 // TextEditOverlayObject(s). This will additionally update the selection which
628 // is an integral part of the text visualization
630 {
631  if (IsTextEdit())
632  {
633  // MinTextRange may have changed. Forward it, too
634  const basegfx::B2DRange aMinTextRange
636 
637  for (sal_uInt32 a(0); a < maTEOverlayGroup.count(); a++)
638  {
639  TextEditOverlayObject* pCandidate
640  = dynamic_cast<TextEditOverlayObject*>(&maTEOverlayGroup.getOverlayObject(a));
641 
642  if (pCandidate)
643  {
644  pCandidate->checkDataChange(aMinTextRange);
645  }
646  }
647  }
648 }
649 
650 // callback from the active EditView, forward to evtl. existing instances of the
651 // TextEditOverlayObject(s). This cvall *only* updates the selection visualization
652 // which is e.g. used when only the selection is changed, but not the text
654 {
655  if (IsTextEdit())
656  {
657  for (sal_uInt32 a(0); a < maTEOverlayGroup.count(); a++)
658  {
659  TextEditOverlayObject* pCandidate
660  = dynamic_cast<TextEditOverlayObject*>(&maTEOverlayGroup.getOverlayObject(a));
661 
662  if (pCandidate)
663  {
664  pCandidate->checkSelectionChange();
665  }
666  }
667  }
668 }
669 
671 
673 {
675  {
676  // adapt all TextEditOverlayObject(s), so call EditViewInvalidate()
677  // to update accordingly (will update selection, too). Suppress new
678  // stuff when LibreOfficeKit is active
680  }
681  else
682  {
683  // draw old text edit stuff
684  if (IsTextEdit())
685  {
686  const SdrOutliner* pActiveOutliner = GetTextEditOutliner();
687 
688  if (pActiveOutliner)
689  {
690  const sal_uInt32 nViewCount(pActiveOutliner->GetViewCount());
691 
692  if (nViewCount)
693  {
694  const vcl::Region& rRedrawRegion = rPaintWindow.GetRedrawRegion();
695  const tools::Rectangle aCheckRect(rRedrawRegion.GetBoundRect());
696 
697  for (sal_uInt32 i(0); i < nViewCount; i++)
698  {
699  OutlinerView* pOLV = pActiveOutliner->GetView(i);
700 
701  // If rPaintWindow knows that the output device is a render
702  // context and is aware of the underlying vcl::Window,
703  // compare against that; that's how double-buffering can
704  // still find the matching OutlinerView.
705  OutputDevice* pOutputDevice = rPaintWindow.GetWindow()
706  ? rPaintWindow.GetWindow()
707  : &rPaintWindow.GetOutputDevice();
708  if (pOLV->GetWindow() == pOutputDevice
710  {
711  ImpPaintOutlinerView(*pOLV, aCheckRect,
712  rPaintWindow.GetTargetOutputDevice());
713  return;
714  }
715  }
716  }
717  }
718  }
719  }
720 }
721 
723  OutputDevice& rTargetDevice) const
724 {
725  const SdrTextObj* pText = GetTextEditObject();
726  bool bTextFrame(pText && pText->IsTextFrame());
727  bool bFitToSize(pTextEditOutliner->GetControlWord() & EEControlBits::STRETCHING);
728  bool bModified(pTextEditOutliner->IsModified());
729  tools::Rectangle aBlankRect(rOutlView.GetOutputArea());
730  aBlankRect.Union(aMinTextEditArea);
731  tools::Rectangle aPixRect(rTargetDevice.LogicToPixel(aBlankRect));
732 
733  // in the tiled rendering case, the setup is incomplete, and we very
734  // easily get an empty rRect on input - that will cause that everything is
735  // clipped; happens in case of editing text inside a shape in Calc.
736  // FIXME would be better to complete the setup so that we don't get an
737  // empty rRect here
739  aBlankRect.Intersection(rRect);
740 
741  rOutlView.GetOutliner()->SetUpdateMode(true); // Bugfix #22596#
742  rOutlView.Paint(aBlankRect, &rTargetDevice);
743 
744  if (!bModified)
745  {
746  pTextEditOutliner->ClearModifyFlag();
747  }
748 
749  if (bTextFrame && !bFitToSize)
750  {
751  // completely reworked to use primitives; this ensures same look and functionality
752  const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
753  std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> xProcessor(
755  aViewInformation2D));
756 
757  if (xProcessor)
758  {
759  const bool bMapModeEnabled(rTargetDevice.IsMapModeEnabled());
761  const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
762  const Color aHilightColor(aSvtOptionsDrawinglayer.getHilightColor());
763  const double fTransparence(aSvtOptionsDrawinglayer.GetTransparentSelectionPercent()
764  * 0.01);
765  const sal_uInt16 nPixSiz(rOutlView.GetInvalidateMore() - 1);
768  aRange, aHilightColor.getBColor(), fTransparence,
769  std::max(6, nPixSiz - 2), // grow
770  0.0, // shrink
771  0.0));
772  const drawinglayer::primitive2d::Primitive2DContainer aSequence{ xReference };
773 
774  rTargetDevice.EnableMapMode(false);
775  xProcessor->process(aSequence);
776  rTargetDevice.EnableMapMode(bMapModeEnabled);
777  }
778  }
779 
780  rOutlView.ShowCursor(/*bGotoCursor=*/true, /*bActivate=*/true);
781 }
782 
784 {
785  vcl::Window* pWin = rOutlView.GetWindow();
786 
787  if (pWin)
788  {
789  const SdrTextObj* pText = GetTextEditObject();
790  bool bTextFrame(pText && pText->IsTextFrame());
791  bool bFitToSize(pText && pText->IsFitToSize());
792 
793  if (bTextFrame && !bFitToSize)
794  {
795  tools::Rectangle aBlankRect(rOutlView.GetOutputArea());
796  aBlankRect.Union(aMinTextEditArea);
797  tools::Rectangle aPixRect(pWin->LogicToPixel(aBlankRect));
798  sal_uInt16 nPixSiz(rOutlView.GetInvalidateMore() - 1);
799 
800  aPixRect.AdjustLeft(-1);
801  aPixRect.AdjustTop(-1);
802  aPixRect.AdjustRight(1);
803  aPixRect.AdjustBottom(1);
804 
805  {
806  // limit xPixRect because of driver problems when pixel coordinates are too far out
807  Size aMaxXY(pWin->GetOutputSizePixel());
808  long a(2 * nPixSiz);
809  long nMaxX(aMaxXY.Width() + a);
810  long nMaxY(aMaxXY.Height() + a);
811 
812  if (aPixRect.Left() < -a)
813  aPixRect.SetLeft(-a);
814  if (aPixRect.Top() < -a)
815  aPixRect.SetTop(-a);
816  if (aPixRect.Right() > nMaxX)
817  aPixRect.SetRight(nMaxX);
818  if (aPixRect.Bottom() > nMaxY)
819  aPixRect.SetBottom(nMaxY);
820  }
821 
822  tools::Rectangle aOuterPix(aPixRect);
823  aOuterPix.AdjustLeft(-nPixSiz);
824  aOuterPix.AdjustTop(-nPixSiz);
825  aOuterPix.AdjustRight(nPixSiz);
826  aOuterPix.AdjustBottom(nPixSiz);
827 
828  bool bMapModeEnabled(pWin->IsMapModeEnabled());
829  pWin->EnableMapMode(false);
830  pWin->Invalidate(aOuterPix);
831  pWin->EnableMapMode(bMapModeEnabled);
832  }
833  }
834 }
835 
837  SfxViewShell* pViewShell) const
838 {
839  // background
840  Color aBackground(GetTextEditBackgroundColor(*this));
841  SdrTextObj* pText = mxTextEditObj.get();
842  bool bTextFrame = pText != nullptr && pText->IsTextFrame();
843  bool bContourFrame = pText != nullptr && pText->IsContourTextFrame();
844  // create OutlinerView
845  OutlinerView* pOutlView = pGivenView;
846  pTextEditOutliner->SetUpdateMode(false);
847 
848  if (pOutlView == nullptr)
849  {
850  pOutlView = new OutlinerView(pTextEditOutliner.get(), pWin);
851  }
852  else
853  {
854  pOutlView->SetWindow(pWin);
855  }
856 
857  // disallow scrolling
858  EVControlBits nStat = pOutlView->GetControlWord();
859  nStat &= ~EVControlBits::AUTOSCROLL;
860  // AutoViewSize only if not ContourFrame.
861  if (!bContourFrame)
862  nStat |= EVControlBits::AUTOSIZE;
863  if (bTextFrame)
864  {
865  sal_uInt16 nPixSiz = maHdlList.GetHdlSize() * 2 + 1;
866  nStat |= EVControlBits::INVONEMORE;
867  pOutlView->SetInvalidateMore(nPixSiz);
868  }
869  pOutlView->SetControlWord(nStat);
870  pOutlView->SetBackgroundColor(aBackground);
871 
872  // In case we're in the process of constructing a new view shell,
873  // SfxViewShell::Current() may still point to the old one. So if possible,
874  // depend on the application owning this draw view to provide the view
875  // shell.
876  SfxViewShell* pSfxViewShell = pViewShell ? pViewShell : GetSfxViewShell();
877  pOutlView->RegisterViewShell(pSfxViewShell ? pSfxViewShell : SfxViewShell::Current());
878 
879  if (pText != nullptr)
880  {
881  pOutlView->SetAnchorMode(pText->GetOutlinerViewAnchorMode());
882  pTextEditOutliner->SetFixedCellHeight(
884  }
885  // do update before setting output area so that aTextEditArea can be recalculated
886  pTextEditOutliner->SetUpdateMode(true);
887  pOutlView->SetOutputArea(aTextEditArea);
888  ImpInvalidateOutlinerView(*pOutlView);
889  return pOutlView;
890 }
891 
892 IMPL_LINK(SdrObjEditView, ImpOutlinerStatusEventHdl, EditStatus&, rEditStat, void)
893 {
894  if (pTextEditOutliner)
895  {
896  SdrTextObj* pTextObj = mxTextEditObj.get();
897  if (pTextObj)
898  {
899  pTextObj->onEditOutlinerStatusEvent(&rEditStat);
900  }
901  }
902 }
903 
905 {
906  if (pTextEditOutliner)
907  {
908  SdrTextObj* pTextObj = mxTextEditObj.get();
910  if (pTextObj && pOLV)
911  {
912  TextChain* pTextChain = pTextObj->GetTextChain();
913 
914  // XXX: IsChainable and GetNilChainingEvent are a bit mixed up atm
915  if (!pTextObj->IsChainable())
916  {
917  return;
918  }
919  // This is true during an underflow-caused overflow (with pEdtOutl->SetText())
920  if (pTextChain->GetNilChainingEvent(pTextObj))
921  {
922  return;
923  }
924 
925  // We prevent to trigger further handling of overflow/underflow for pTextObj
926  pTextChain->SetNilChainingEvent(pTextObj, true); // XXX
927 
928  // Save previous selection pos // NOTE: It must be done to have the right CursorEvent in KeyInput
929  pTextChain->SetPreChainingSel(pTextObj, pOLV->GetSelection());
930  //maPreChainingSel = new ESelection(pOLV->GetSelection());
931 
932  // Handling Undo
933  const int nText = 0; // XXX: hardcoded index (SdrTextObj::getText handles only 0)
934 
935  const bool bUndoEnabled = GetModel() && IsUndoEnabled();
936  std::unique_ptr<SdrUndoObjSetText> pTxtUndo;
937  if (bUndoEnabled)
938  pTxtUndo.reset(
939  dynamic_cast<SdrUndoObjSetText*>(GetModel()
940  ->GetSdrUndoFactory()
941  .CreateUndoObjectSetText(*pTextObj, nText)
942  .release()));
943 
944  // trigger actual chaining
945  pTextObj->onChainingEvent();
946 
947  if (pTxtUndo)
948  {
949  pTxtUndo->AfterSetText();
950  if (!pTxtUndo->IsDifferent())
951  {
952  pTxtUndo.reset();
953  }
954  }
955 
956  if (pTxtUndo)
957  AddUndo(std::move(pTxtUndo));
958 
959  //maCursorEvent = new CursorChainingEvent(pTextChain->GetCursorEvent(pTextObj));
960  //SdrTextObj *pNextLink = pTextObj->GetNextLinkInChain();
961 
962  // NOTE: Must be called. Don't let the function return if you set it to true and not reset it
963  pTextChain->SetNilChainingEvent(pTextObj, false);
964  }
965  else
966  {
967  // XXX
968  SAL_INFO("svx.chaining", "[OnChaining] No Edit Outliner View");
969  }
970  }
971 }
972 
973 IMPL_LINK_NOARG(SdrObjEditView, ImpAfterCutOrPasteChainingEventHdl, LinkParamNone*, void)
974 {
975  SdrTextObj* pTextObj = GetTextEditObject();
976  if (!pTextObj)
977  return;
978  ImpChainingEventHdl();
979  TextChainCursorManager aCursorManager(this, pTextObj);
980  ImpMoveCursorAfterChainingEvent(&aCursorManager);
981 }
982 
984 {
985  if (!mxTextEditObj.is() || !pCursorManager)
986  return;
987 
988  SdrTextObj* pTextObj = mxTextEditObj.get();
989 
990  // Check if it has links to move it to
991  if (!pTextObj || !pTextObj->IsChainable())
992  return;
993 
994  TextChain* pTextChain = pTextObj->GetTextChain();
995  ESelection aNewSel = pTextChain->GetPostChainingSel(pTextObj);
996 
997  pCursorManager->HandleCursorEventAfterChaining(pTextChain->GetCursorEvent(pTextObj), aNewSel);
998 
999  // Reset event
1000  pTextChain->SetCursorEvent(pTextObj, CursorChainingEvent::NULL_EVENT);
1001 }
1002 
1003 IMPL_LINK(SdrObjEditView, ImpOutlinerCalcFieldValueHdl, EditFieldInfo*, pFI, void)
1004 {
1005  bool bOk = false;
1006  OUString& rStr = pFI->GetRepresentation();
1007  rStr.clear();
1008  SdrTextObj* pTextObj = mxTextEditObj.get();
1009  if (pTextObj != nullptr)
1010  {
1011  o3tl::optional<Color> pTxtCol;
1012  o3tl::optional<Color> pFldCol;
1013  bOk = pTextObj->CalcFieldValue(pFI->GetField(), pFI->GetPara(), pFI->GetPos(), true,
1014  pTxtCol, pFldCol, rStr);
1015  if (bOk)
1016  {
1017  if (pTxtCol)
1018  {
1019  pFI->SetTextColor(*pTxtCol);
1020  }
1021  if (pFldCol)
1022  {
1023  pFI->SetFieldColor(*pFldCol);
1024  }
1025  else
1026  {
1027  pFI->SetFieldColor(COL_LIGHTGRAY); // TODO: remove this later on (357)
1028  }
1029  }
1030  }
1031  Outliner& rDrawOutl = mpModel->GetDrawOutliner(pTextObj);
1032  Link<EditFieldInfo*, void> aDrawOutlLink = rDrawOutl.GetCalcFieldValueHdl();
1033  if (!bOk && aDrawOutlLink.IsSet())
1034  {
1035  aDrawOutlLink.Call(pFI);
1036  bOk = !rStr.isEmpty();
1037  }
1038  if (!bOk)
1039  {
1040  aOldCalcFieldValueLink.Call(pFI);
1041  }
1042 }
1043 
1044 IMPL_LINK_NOARG(SdrObjEditView, EndTextEditHdl, SdrUndoManager*, void) { SdrEndTextEdit(); }
1045 
1047 {
1048  // default returns registered UndoManager
1049  return GetModel() ? dynamic_cast<SdrUndoManager*>(GetModel()->GetSdrUndoManager()) : nullptr;
1050 }
1051 
1053  bool bIsNewObj, SdrOutliner* pGivenOutliner,
1054  OutlinerView* pGivenOutlinerView, bool bDontDeleteOutliner,
1055  bool bOnlyOneView, bool bGrabFocus)
1056 {
1057  // FIXME cannot be an assert() yet, the code is not ready for that;
1058  // eg. press F7 in Impress when you are inside a text object with spelling
1059  // mistakes => boom; and it is unclear how to avoid that
1060  SAL_WARN_IF(IsTextEdit(), "svx", "SdrBeginTextEdit called when IsTextEdit() is already true.");
1061  // FIXME this encourages all sorts of bad habits and should be removed
1062  SdrEndTextEdit();
1063 
1064  SdrTextObj* pObj = dynamic_cast<SdrTextObj*>(pObj_);
1065  if (!pObj)
1066  return false; // currently only possible with text objects
1067 
1068  if (bGrabFocus && pWin)
1069  {
1070  // attention, this call may cause an EndTextEdit() call to this view
1071  pWin->GrabFocus(); // to force the cursor into the edit view
1072  }
1073 
1074  bTextEditDontDelete = bDontDeleteOutliner && pGivenOutliner != nullptr;
1075  bTextEditOnlyOneView = bOnlyOneView;
1076  bTextEditNewObj = bIsNewObj;
1077  const sal_uInt32 nWinCount(PaintWindowCount());
1078  sal_uInt32 i;
1079  bool bBrk(false);
1080 
1081  if (!pWin)
1082  {
1083  for (i = 0; i < nWinCount && !pWin; i++)
1084  {
1085  SdrPaintWindow* pPaintWindow = GetPaintWindow(i);
1086 
1087  if (OUTDEV_WINDOW == pPaintWindow->GetOutputDevice().GetOutDevType())
1088  {
1089  pWin = static_cast<vcl::Window*>(&pPaintWindow->GetOutputDevice());
1090  }
1091  }
1092 
1093  // break, when no window exists
1094  if (!pWin)
1095  {
1096  bBrk = true;
1097  }
1098  }
1099 
1100  if (!bBrk && !pPV)
1101  {
1102  pPV = GetSdrPageView();
1103 
1104  // break, when no PageView for the object exists
1105  if (!pPV)
1106  {
1107  bBrk = true;
1108  }
1109  }
1110 
1111  // no TextEdit on objects in locked Layer
1112  if (pPV && pPV->GetLockedLayers().IsSet(pObj->GetLayer()))
1113  {
1114  bBrk = true;
1115  }
1116 
1117  if (pTextEditOutliner)
1118  {
1119  OSL_FAIL("SdrObjEditView::SdrBeginTextEdit(): Old Outliner still exists.");
1120  pTextEditOutliner.reset();
1121  }
1122 
1123  if (!bBrk)
1124  {
1125  pTextEditWin = pWin;
1126  pTextEditPV = pPV;
1127  mxTextEditObj.reset(pObj);
1128  if (pGivenOutliner)
1129  {
1130  pTextEditOutliner.reset(pGivenOutliner);
1131  pGivenOutliner = nullptr; // so we don't delete it on the error path
1132  }
1133  else
1134  pTextEditOutliner = SdrMakeOutliner(OutlinerMode::TextObject,
1136 
1137  {
1138  SvtAccessibilityOptions aOptions;
1139  pTextEditOutliner->ForceAutoColor(aOptions.GetIsAutomaticFontColor());
1140  }
1141 
1142  aOldCalcFieldValueLink = pTextEditOutliner->GetCalcFieldValueHdl();
1143  // FieldHdl has to be set by SdrBeginTextEdit, because this call an UpdateFields
1144  pTextEditOutliner->SetCalcFieldValueHdl(
1145  LINK(this, SdrObjEditView, ImpOutlinerCalcFieldValueHdl));
1146  pTextEditOutliner->SetBeginPasteOrDropHdl(LINK(this, SdrObjEditView, BeginPasteOrDropHdl));
1147  pTextEditOutliner->SetEndPasteOrDropHdl(LINK(this, SdrObjEditView, EndPasteOrDropHdl));
1148 
1149  // It is just necessary to make the visualized page known. Set it.
1150  pTextEditOutliner->setVisualizedPage(pPV->GetPage());
1151 
1152  pTextEditOutliner->SetTextObjNoInit(mxTextEditObj.get());
1153 
1155  {
1156  SdrTextObj* pTextObj = mxTextEditObj.get();
1157  DBG_ASSERT(pTextObj, "svx::SdrObjEditView::BegTextEdit(), no text object?");
1158  if (!pTextObj)
1159  return false;
1160 
1161  // switch off any running TextAnimations
1162  pTextObj->SetTextAnimationAllowed(false);
1163 
1164  // remember old cursor
1165  if (pTextEditOutliner->GetViewCount() != 0)
1166  {
1167  pTextEditOutliner->RemoveView(static_cast<size_t>(0));
1168  }
1169 
1170  // Determine EditArea via TakeTextEditArea.
1171  // TODO: This could theoretically be left out, because TakeTextRect() calculates the aTextEditArea,
1172  // but aMinTextEditArea has to happen, too (therefore leaving this in right now)
1173  pTextObj->TakeTextEditArea(nullptr, nullptr, &aTextEditArea, &aMinTextEditArea);
1174 
1175  tools::Rectangle aTextRect;
1176  tools::Rectangle aAnchorRect;
1177  pTextObj->TakeTextRect(*pTextEditOutliner, aTextRect, true,
1178  &aAnchorRect /* Give true here, not false */);
1179 
1180  if (!pTextObj->IsContourTextFrame())
1181  {
1182  // FitToSize not together with ContourFrame, for now
1183  if (pTextObj->IsFitToSize())
1184  aTextRect = aAnchorRect;
1185  }
1186 
1187  aTextEditArea = aTextRect;
1188 
1189  // add possible GridOffset to up-to-now view-independent EditAreas
1190  basegfx::B2DVector aGridOffset(0.0, 0.0);
1191  if (getPossibleGridOffsetForSdrObject(aGridOffset, pTextObj, pPV))
1192  {
1193  const Point aOffset(basegfx::fround(aGridOffset.getX()),
1194  basegfx::fround(aGridOffset.getY()));
1195 
1196  aTextEditArea += aOffset;
1197  aMinTextEditArea += aOffset;
1198  }
1199 
1200  Point aPvOfs(pTextObj->GetTextEditOffset());
1201  aTextEditArea.Move(aPvOfs.X(), aPvOfs.Y());
1202  aMinTextEditArea.Move(aPvOfs.X(), aPvOfs.Y());
1203  pTextEditCursorBuffer = pWin->GetCursor();
1204 
1205  maHdlList.SetMoveOutside(true);
1206 
1207  // Since IsMarkHdlWhenTextEdit() is ignored, it is necessary
1208  // to call AdjustMarkHdl() always.
1209  AdjustMarkHdl();
1210 
1211  pTextEditOutlinerView = ImpMakeOutlinerView(pWin, pGivenOutlinerView);
1212 
1214  {
1215  // activate visualization of EditView on Overlay, suppress when
1216  // LibreOfficeKit is active
1218 
1219  const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
1220  const Color aHilightColor(aSvtOptionsDrawinglayer.getHilightColor());
1221  const SdrTextObj* pText = GetTextEditObject();
1222  const bool bTextFrame(pText && pText->IsTextFrame());
1223  const bool bFitToSize(pTextEditOutliner->GetControlWord()
1224  & EEControlBits::STRETCHING);
1225  const bool bVisualizeSurroundingFrame(bTextFrame && !bFitToSize);
1226  SdrPageView* pPageView = GetSdrPageView();
1227 
1228  if (pPageView)
1229  {
1230  for (sal_uInt32 b(0); b < pPageView->PageWindowCount(); b++)
1231  {
1232  const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1233 
1234  if (rPageWindow.GetPaintWindow().OutputToWindow())
1235  {
1237  = rPageWindow.GetOverlayManager();
1238  if (xManager.is())
1239  {
1240  std::unique_ptr<TextEditOverlayObject> pNewTextEditOverlayObject(
1241  new TextEditOverlayObject(aHilightColor, *pTextEditOutlinerView,
1242  bVisualizeSurroundingFrame));
1243 
1244  xManager->add(*pNewTextEditOverlayObject);
1245  xManager->add(const_cast<sdr::overlay::OverlaySelection&>(
1246  *pNewTextEditOverlayObject->getOverlaySelection()));
1247 
1248  maTEOverlayGroup.append(std::move(pNewTextEditOverlayObject));
1249  }
1250  }
1251  }
1252  }
1253  }
1254 
1255  // check if this view is already inserted
1256  size_t i2, nCount = pTextEditOutliner->GetViewCount();
1257  for (i2 = 0; i2 < nCount; i2++)
1258  {
1259  if (pTextEditOutliner->GetView(i2) == pTextEditOutlinerView)
1260  break;
1261  }
1262 
1263  if (i2 == nCount)
1264  pTextEditOutliner->InsertView(pTextEditOutlinerView, 0);
1265 
1266  maHdlList.SetMoveOutside(false);
1267  maHdlList.SetMoveOutside(true);
1268 
1269  // register all windows as OutlinerViews with the Outliner
1270  if (!bOnlyOneView)
1271  {
1272  for (i = 0; i < nWinCount; i++)
1273  {
1274  SdrPaintWindow* pPaintWindow = GetPaintWindow(i);
1275  OutputDevice& rOutDev = pPaintWindow->GetOutputDevice();
1276 
1277  if (&rOutDev != pWin && OUTDEV_WINDOW == rOutDev.GetOutDevType())
1278  {
1279  OutlinerView* pOutlView
1280  = ImpMakeOutlinerView(static_cast<vcl::Window*>(&rOutDev), nullptr);
1281  pTextEditOutliner->InsertView(pOutlView, static_cast<sal_uInt16>(i));
1282  }
1283  }
1284 
1286  {
1287  // Register an outliner view for all other sdr views that
1288  // show the same page, so that when the text edit changes,
1289  // all interested windows get an invalidation.
1290  SdrViewIter aIter(pObj->getSdrPageFromSdrObject());
1291  for (SdrView* pView = aIter.FirstView(); pView; pView = aIter.NextView())
1292  {
1293  if (pView == this)
1294  continue;
1295 
1296  for (sal_uInt32 nViewPaintWindow = 0;
1297  nViewPaintWindow < pView->PaintWindowCount(); ++nViewPaintWindow)
1298  {
1299  SdrPaintWindow* pPaintWindow = pView->GetPaintWindow(nViewPaintWindow);
1300  OutputDevice& rOutDev = pPaintWindow->GetOutputDevice();
1301 
1302  if (&rOutDev != pWin && OUTDEV_WINDOW == rOutDev.GetOutDevType())
1303  {
1304  OutlinerView* pOutlView = ImpMakeOutlinerView(
1305  static_cast<vcl::Window*>(&rOutDev), nullptr);
1306  pOutlView->HideCursor();
1307  static_cast<vcl::Window*>(&rOutDev)->SetCursor(nullptr);
1308  pTextEditOutliner->InsertView(pOutlView);
1309  }
1310  }
1311  }
1312  }
1313  }
1314 
1316  pTextEditOutliner->SetStatusEventHdl(
1317  LINK(this, SdrObjEditView, ImpOutlinerStatusEventHdl));
1318  if (pTextObj->IsChainable())
1319  {
1321  LINK(this, SdrObjEditView, ImpAfterCutOrPasteChainingEventHdl));
1322  }
1323 
1324  pTextEditOutliner->ClearModifyFlag();
1325 
1326  if (pTextObj->IsFitToSize())
1327  {
1328  pWin->Invalidate(aTextEditArea);
1329  }
1330 
1331  if (GetModel())
1332  {
1333  SdrHint aHint(SdrHintKind::BeginEdit, *pTextObj);
1334  GetModel()->Broadcast(aHint);
1335  }
1336 
1337  pTextEditOutliner->setVisualizedPage(nullptr);
1338 
1339  if (mxSelectionController.is())
1340  mxSelectionController->onSelectionHasChanged();
1341 
1342  if (GetModel() && IsUndoEnabled()
1343  && !GetModel()->GetDisableTextEditUsesCommonUndoManager())
1344  {
1346 
1347  if (pSdrUndoManager)
1348  {
1349  // we have an outliner, undo manager and it's an EditUndoManager, exchange
1350  // the document undo manager and the default one from the outliner and tell
1351  // it that text edit starts by setting a callback if it needs to end text edit mode.
1352  assert(nullptr == mpOldTextEditUndoManager);
1353 
1354  mpOldTextEditUndoManager = pTextEditOutliner->SetUndoManager(pSdrUndoManager);
1355  pSdrUndoManager->SetEndTextEditHdl(LINK(this, SdrObjEditView, EndTextEditHdl));
1356  }
1357  else
1358  {
1359  OSL_ENSURE(false,
1360  "The document undo manager is not derived from SdrUndoManager (!)");
1361  }
1362  }
1363 
1364  return true; // ran fine, let TextEdit run now
1365  }
1366  else
1367  {
1368  pTextEditOutliner->SetCalcFieldValueHdl(aOldCalcFieldValueLink);
1369  pTextEditOutliner->SetBeginPasteOrDropHdl(Link<PasteOrDropInfos*, void>());
1370  pTextEditOutliner->SetEndPasteOrDropHdl(Link<PasteOrDropInfos*, void>());
1371  }
1372  }
1373  if (pTextEditOutliner != nullptr)
1374  {
1375  pTextEditOutliner->setVisualizedPage(nullptr);
1376  }
1377 
1378  // something went wrong...
1379  if (!bDontDeleteOutliner)
1380  {
1381  delete pGivenOutliner;
1382  if (pGivenOutlinerView != nullptr)
1383  {
1384  delete pGivenOutlinerView;
1385  pGivenOutlinerView = nullptr;
1386  }
1387  }
1388  pTextEditOutliner.reset();
1389 
1390  pTextEditOutlinerView = nullptr;
1391  mxTextEditObj.reset(nullptr);
1392  pTextEditPV = nullptr;
1393  pTextEditWin = nullptr;
1394  maHdlList.SetMoveOutside(false);
1395 
1396  return false;
1397 }
1398 
1400 {
1402  SdrTextObj* pTEObj = mxTextEditObj.get();
1403  vcl::Window* pTEWin = pTextEditWin;
1404  OutlinerView* pTEOutlinerView = pTextEditOutlinerView;
1405  vcl::Cursor* pTECursorBuffer = pTextEditCursorBuffer;
1406  SdrUndoManager* pUndoEditUndoManager = nullptr;
1407  bool bNeedToUndoSavedRedoTextEdit(false);
1408 
1409  if (GetModel() && IsUndoEnabled() && pTEObj && pTextEditOutliner
1410  && !GetModel()->GetDisableTextEditUsesCommonUndoManager())
1411  {
1412  // change back the UndoManager to the remembered original one
1413  SfxUndoManager* pOriginal = pTextEditOutliner->SetUndoManager(mpOldTextEditUndoManager);
1414  mpOldTextEditUndoManager = nullptr;
1415 
1416  if (pOriginal)
1417  {
1418  // check if we got back our document undo manager
1420 
1421  if (pSdrUndoManager && dynamic_cast<SdrUndoManager*>(pOriginal) == pSdrUndoManager)
1422  {
1423  if (pSdrUndoManager->isEndTextEditTriggeredFromUndo())
1424  {
1425  // remember the UndoManager where missing Undos have to be triggered after end
1426  // text edit. When the undo had triggered the end text edit, the original action
1427  // which had to be undone originally is not yet undone.
1428  pUndoEditUndoManager = pSdrUndoManager;
1429 
1430  // We are ending text edit; if text edit was triggered from undo, execute all redos
1431  // to create a complete text change undo action for the redo buffer. Also mark this
1432  // state when at least one redo was executed; the created extra TextChange needs to
1433  // be undone in addition to the first real undo outside the text edit changes
1434  while (pSdrUndoManager->GetRedoActionCount())
1435  {
1436  bNeedToUndoSavedRedoTextEdit = true;
1437  pSdrUndoManager->Redo();
1438  }
1439  }
1440 
1441  // reset the callback link and let the undo manager cleanup all text edit
1442  // undo actions to get the stack back to the form before the text edit
1443  pSdrUndoManager->SetEndTextEditHdl(Link<SdrUndoManager*, void>());
1444  }
1445  else
1446  {
1447  OSL_ENSURE(false, "Got UndoManager back in SdrEndTextEdit which is NOT the "
1448  "expected document UndoManager (!)");
1449  delete pOriginal;
1450  }
1451  }
1452  }
1453  else
1454  {
1455  assert(nullptr == mpOldTextEditUndoManager); // cannot be restored!
1456  }
1457 
1458  if (GetModel() && mxTextEditObj.is())
1459  {
1461  GetModel()->Broadcast(aHint);
1462  }
1463 
1464  // if new mechanism was used, clean it up. At cleanup no need to check
1465  // for LibreOfficeKit
1467  {
1470  }
1471 
1472  mxTextEditObj.reset(nullptr);
1473  pTextEditPV = nullptr;
1474  pTextEditWin = nullptr;
1475  SdrOutliner* pTEOutliner = pTextEditOutliner.release();
1476  pTextEditOutlinerView = nullptr;
1477  pTextEditCursorBuffer = nullptr;
1479 
1480  if (pTEOutliner != nullptr)
1481  {
1482  bool bModified = pTEOutliner->IsModified();
1483  if (pTEOutlinerView != nullptr)
1484  {
1485  pTEOutlinerView->HideCursor();
1486  }
1487  if (pTEObj != nullptr)
1488  {
1489  pTEOutliner->CompleteOnlineSpelling();
1490 
1491  std::unique_ptr<SdrUndoObjSetText> pTxtUndo;
1492 
1493  if (bModified)
1494  {
1495  sal_Int32 nText;
1496  for (nText = 0; nText < pTEObj->getTextCount(); ++nText)
1497  if (pTEObj->getText(nText) == pTEObj->getActiveText())
1498  break;
1499 
1500  pTxtUndo.reset(
1501  dynamic_cast<SdrUndoObjSetText*>(GetModel()
1502  ->GetSdrUndoFactory()
1503  .CreateUndoObjectSetText(*pTEObj, nText)
1504  .release()));
1505  }
1506  DBG_ASSERT(!bModified || pTxtUndo,
1507  "svx::SdrObjEditView::EndTextEdit(), could not create undo action!");
1508  // Set old CalcFieldValue-Handler again, this
1509  // has to happen before Obj::EndTextEdit(), as this does UpdateFields().
1513 
1514  const bool bUndo = IsUndoEnabled();
1515  if (bUndo)
1516  {
1518  OUString aObjName(pTEObj->TakeObjNameSingul());
1519  BegUndo(SvxResId(STR_UndoObjSetText), aObjName);
1520  }
1521 
1522  pTEObj->EndTextEdit(*pTEOutliner);
1523 
1524  if ((pTEObj->GetRotateAngle() != 0)
1525  || (dynamic_cast<const SdrTextObj*>(pTEObj) != nullptr && pTEObj->IsFontwork()))
1526  {
1527  pTEObj->ActionChanged();
1528  }
1529 
1530  if (pTxtUndo != nullptr)
1531  {
1532  pTxtUndo->AfterSetText();
1533  if (!pTxtUndo->IsDifferent())
1534  {
1535  pTxtUndo.reset();
1536  }
1537  }
1538  // check deletion of entire TextObj
1539  std::unique_ptr<SdrUndoAction> pDelUndo;
1540  bool bDelObj = false;
1541  if (bTextEditNewObj)
1542  {
1543  bDelObj = pTEObj->IsTextFrame() && !pTEObj->HasText() && !pTEObj->IsEmptyPresObj()
1544  && !pTEObj->HasFill() && !pTEObj->HasLine();
1545 
1546  if (pTEObj->IsInserted() && bDelObj
1547  && pTEObj->GetObjInventor() == SdrInventor::Default && !bDontDeleteReally)
1548  {
1549  SdrObjKind eIdent = static_cast<SdrObjKind>(pTEObj->GetObjIdentifier());
1550  if (eIdent == OBJ_TEXT)
1551  {
1552  pDelUndo = GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pTEObj);
1553  }
1554  }
1555  }
1556  if (pTxtUndo)
1557  {
1558  if (bUndo)
1559  AddUndo(std::move(pTxtUndo));
1561  }
1562  if (pDelUndo != nullptr)
1563  {
1564  if (bUndo)
1565  {
1566  AddUndo(std::move(pDelUndo));
1567  }
1569  DBG_ASSERT(pTEObj->getParentSdrObjListFromSdrObject() != nullptr,
1570  "SdrObjEditView::SdrEndTextEdit(): Fatal: Object edited doesn't have an "
1571  "ObjList!");
1572  if (pTEObj->getParentSdrObjListFromSdrObject() != nullptr)
1573  {
1575  CheckMarked(); // remove selection immediately...
1576  }
1577  }
1578  else if (bDelObj)
1579  { // for Writer: the app has to do the deletion itself.
1581  }
1582 
1583  if (bUndo)
1584  EndUndo(); // EndUndo after Remove, in case UndoStack is deleted immediately
1585 
1586  // Switch on any TextAnimation again after TextEdit
1587  if (dynamic_cast<const SdrTextObj*>(pTEObj) != nullptr)
1588  {
1589  pTEObj->SetTextAnimationAllowed(true);
1590  }
1591 
1592  // Since IsMarkHdlWhenTextEdit() is ignored, it is necessary
1593  // to call AdjustMarkHdl() always.
1594  AdjustMarkHdl();
1595  }
1596  // delete all OutlinerViews
1597  for (size_t i = pTEOutliner->GetViewCount(); i > 0;)
1598  {
1599  i--;
1600  OutlinerView* pOLV = pTEOutliner->GetView(i);
1601  sal_uInt16 nMorePix = pOLV->GetInvalidateMore() + 10;
1602  vcl::Window* pWin = pOLV->GetWindow();
1603  tools::Rectangle aRect(pOLV->GetOutputArea());
1604  pTEOutliner->RemoveView(i);
1605  if (!bTextEditDontDelete || i != 0)
1606  {
1607  // may not own the zeroth one
1608  delete pOLV;
1609  }
1610  aRect.Union(aTextEditArea);
1611  aRect.Union(aMinTextEditArea);
1612  aRect = pWin->LogicToPixel(aRect);
1613  aRect.AdjustLeft(-nMorePix);
1614  aRect.AdjustTop(-nMorePix);
1615  aRect.AdjustRight(nMorePix);
1616  aRect.AdjustBottom(nMorePix);
1617  aRect = pWin->PixelToLogic(aRect);
1618  InvalidateOneWin(*pWin, aRect);
1619  pWin->SetFillColor();
1620  pWin->SetLineColor(COL_BLACK);
1621  }
1622  // and now the Outliner itself
1623  if (!bTextEditDontDelete)
1624  delete pTEOutliner;
1625  else
1626  pTEOutliner->Clear();
1627  if (pTEWin != nullptr)
1628  {
1629  pTEWin->SetCursor(pTECursorBuffer);
1630  }
1631  maHdlList.SetMoveOutside(false);
1632  if (eRet != SdrEndTextEditKind::Unchanged)
1633  {
1635  }
1636  }
1637 
1638  if (pTEObj && !pTEObj->getSdrModelFromSdrObject().isLocked() && pTEObj->GetBroadcaster())
1639  {
1640  SdrHint aHint(SdrHintKind::EndEdit, *pTEObj);
1641  const_cast<SfxBroadcaster*>(pTEObj->GetBroadcaster())->Broadcast(aHint);
1642  }
1643 
1644  if (pUndoEditUndoManager)
1645  {
1646  if (bNeedToUndoSavedRedoTextEdit)
1647  {
1648  // undo the text edit action since it was created as part of an EndTextEdit
1649  // callback from undo itself. This needs to be done after the call to
1650  // FmFormView::SdrEndTextEdit since it gets created there
1651  pUndoEditUndoManager->Undo();
1652  }
1653 
1654  // trigger the Undo which was not executed, but lead to this
1655  // end text edit
1656  pUndoEditUndoManager->Undo();
1657  }
1658 
1659  return eRet;
1660 }
1661 
1662 // info about TextEdit. Default is false.
1663 bool SdrObjEditView::IsTextEdit() const { return mxTextEditObj.is(); }
1664 
1665 // info about TextEditPageView. Default is 0L.
1667 
1669 {
1670  if (pWin == nullptr)
1671  return nullptr;
1672  if (pTextEditOutliner == nullptr)
1673  return nullptr;
1674  OutlinerView* pNewView = nullptr;
1675  size_t nWinCount = pTextEditOutliner->GetViewCount();
1676  for (size_t i = 0; i < nWinCount && pNewView == nullptr; i++)
1677  {
1678  OutlinerView* pView = pTextEditOutliner->GetView(i);
1679  if (pView->GetWindow() == pWin)
1680  pNewView = pView;
1681  }
1682  return pNewView;
1683 }
1684 
1686 {
1687  if (mxTextEditObj.is() && pWin != nullptr && pWin != pTextEditWin)
1688  {
1689  OutlinerView* pNewView = ImpFindOutlinerView(pWin);
1690  if (pNewView != nullptr && pNewView != pTextEditOutlinerView)
1691  {
1692  if (pTextEditOutlinerView != nullptr)
1693  {
1695  }
1696  pTextEditOutlinerView = pNewView;
1697  pTextEditWin = pWin;
1698  pWin->GrabFocus(); // Make the cursor blink here as well
1699  pNewView->ShowCursor();
1701  }
1702  }
1703 }
1704 
1705 bool SdrObjEditView::IsTextEditHit(const Point& rHit) const
1706 {
1707  bool bOk = false;
1708  if (mxTextEditObj.is())
1709  {
1710  tools::Rectangle aEditArea;
1711  OutlinerView* pOLV = pTextEditOutliner->GetView(0);
1712  if (pOLV != nullptr)
1713  {
1714  aEditArea.Union(pOLV->GetOutputArea());
1715  }
1716  bOk = aEditArea.IsInside(rHit);
1717  if (bOk)
1718  { // check if any characters were actually hit
1719  Point aPnt(rHit);
1720  aPnt -= aEditArea.TopLeft();
1721  long nHitTol = 2000;
1722  OutputDevice* pRef = pTextEditOutliner->GetRefDevice();
1723  if (pRef)
1724  nHitTol = OutputDevice::LogicToLogic(nHitTol, MapUnit::Map100thMM,
1725  pRef->GetMapMode().GetMapUnit());
1726 
1727  bOk = pTextEditOutliner->IsTextPos(aPnt, static_cast<sal_uInt16>(nHitTol));
1728  }
1729  }
1730  return bOk;
1731 }
1732 
1734 {
1735  bool bOk = false;
1736  if (mxTextEditObj.is())
1737  {
1738  SdrTextObj* pText = mxTextEditObj.get();
1739  OutlinerView* pOLV = pTextEditOutliner->GetView(0);
1740  if (pOLV)
1741  {
1742  vcl::Window* pWin = pOLV->GetWindow();
1743  if (pText != nullptr && pText->IsTextFrame() && pWin != nullptr)
1744  {
1745  sal_uInt16 nPixSiz = pOLV->GetInvalidateMore();
1747  aEditArea.Union(pOLV->GetOutputArea());
1748  if (!aEditArea.IsInside(rHit))
1749  {
1750  Size aSiz(pWin->PixelToLogic(Size(nPixSiz, nPixSiz)));
1751  aEditArea.AdjustLeft(-(aSiz.Width()));
1752  aEditArea.AdjustTop(-(aSiz.Height()));
1753  aEditArea.AdjustRight(aSiz.Width());
1754  aEditArea.AdjustBottom(aSiz.Height());
1755  bOk = aEditArea.IsInside(rHit);
1756  }
1757  }
1758  }
1759  }
1760  return bOk;
1761 }
1762 
1764  bool* bOutHandled)
1765 {
1766  *bOutHandled = false;
1767 
1768  SdrTextObj* pTextObj = mxTextEditObj.get();
1769  if (!pTextObj)
1770  return nullptr;
1771 
1772  if (!pTextObj->GetNextLinkInChain() && !pTextObj->GetPrevLinkInChain())
1773  return nullptr;
1774 
1775  TextChainCursorManager* pCursorManager = new TextChainCursorManager(this, pTextObj);
1776  if (pCursorManager->HandleKeyEvent(rKEvt))
1777  {
1778  // Possibly do other stuff here if necessary...
1779  // XXX: Careful with the checks below (in KeyInput) for pWin and co. You should do them here I guess.
1780  *bOutHandled = true;
1781  }
1782 
1783  return pCursorManager;
1784 }
1785 
1787 {
1789  {
1790  /* Start special handling of keys within a chain */
1791  // We possibly move to another box before any handling
1792  bool bHandled = false;
1793  std::unique_ptr<TextChainCursorManager> xCursorManager(
1794  ImpHandleMotionThroughBoxesKeyInput(rKEvt, &bHandled));
1795  if (bHandled)
1796  return true;
1797  /* End special handling of keys within a chain */
1798 
1799  if (pTextEditOutlinerView->PostKeyEvent(rKEvt, pWin))
1800  {
1801  if (mpModel)
1802  {
1803  if (pTextEditOutliner && pTextEditOutliner->IsModified())
1804  mpModel->SetChanged();
1805  }
1806 
1807  /* Start chaining processing */
1809  ImpMoveCursorAfterChainingEvent(xCursorManager.get());
1810  /* End chaining processing */
1811 
1812  if (pWin != nullptr && pWin != pTextEditWin)
1813  SetTextEditWin(pWin);
1815  return true;
1816  }
1817  }
1818  return SdrGlueEditView::KeyInput(rKEvt, pWin);
1819 }
1820 
1822 {
1823  if (pTextEditOutlinerView != nullptr)
1824  {
1825  bool bPostIt = pTextEditOutliner->IsInSelectionMode();
1826  if (!bPostIt)
1827  {
1828  Point aPt(rMEvt.GetPosPixel());
1829  if (pWin != nullptr)
1830  aPt = pWin->PixelToLogic(aPt);
1831  else if (pTextEditWin != nullptr)
1832  aPt = pTextEditWin->PixelToLogic(aPt);
1833  bPostIt = IsTextEditHit(aPt);
1834  }
1835  if (bPostIt)
1836  {
1837  Point aPixPos(rMEvt.GetPosPixel());
1838  if (pWin)
1839  {
1841  if (aPixPos.X() < aR.Left())
1842  aPixPos.setX(aR.Left());
1843  if (aPixPos.X() > aR.Right())
1844  aPixPos.setX(aR.Right());
1845  if (aPixPos.Y() < aR.Top())
1846  aPixPos.setY(aR.Top());
1847  if (aPixPos.Y() > aR.Bottom())
1848  aPixPos.setY(aR.Bottom());
1849  }
1850  MouseEvent aMEvt(aPixPos, rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(),
1851  rMEvt.GetModifier());
1853  {
1854  if (pWin != nullptr && pWin != pTextEditWin
1855  && pWin->GetOutDevType() == OUTDEV_WINDOW)
1856  SetTextEditWin(static_cast<vcl::Window*>(pWin));
1858  return true;
1859  }
1860  }
1861  }
1862  return SdrGlueEditView::MouseButtonDown(rMEvt, pWin);
1863 }
1864 
1866 {
1867  if (pTextEditOutlinerView != nullptr)
1868  {
1869  bool bPostIt = pTextEditOutliner->IsInSelectionMode();
1870  if (!bPostIt)
1871  {
1872  Point aPt(rMEvt.GetPosPixel());
1873  if (pWin != nullptr)
1874  aPt = pWin->PixelToLogic(aPt);
1875  else if (pTextEditWin != nullptr)
1876  aPt = pTextEditWin->PixelToLogic(aPt);
1877  bPostIt = IsTextEditHit(aPt);
1878  }
1879  if (bPostIt && pWin)
1880  {
1881  Point aPixPos(rMEvt.GetPosPixel());
1883  if (aPixPos.X() < aR.Left())
1884  aPixPos.setX(aR.Left());
1885  if (aPixPos.X() > aR.Right())
1886  aPixPos.setX(aR.Right());
1887  if (aPixPos.Y() < aR.Top())
1888  aPixPos.setY(aR.Top());
1889  if (aPixPos.Y() > aR.Bottom())
1890  aPixPos.setY(aR.Bottom());
1891  MouseEvent aMEvt(aPixPos, rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(),
1892  rMEvt.GetModifier());
1894  {
1896  return true;
1897  }
1898  }
1899  }
1900  return SdrGlueEditView::MouseButtonUp(rMEvt, pWin);
1901 }
1902 
1904 {
1905  if (pTextEditOutlinerView != nullptr)
1906  {
1907  bool bSelMode = pTextEditOutliner->IsInSelectionMode();
1908  bool bPostIt = bSelMode;
1909  if (!bPostIt)
1910  {
1911  Point aPt(rMEvt.GetPosPixel());
1912  if (pWin)
1913  aPt = pWin->PixelToLogic(aPt);
1914  else if (pTextEditWin)
1915  aPt = pTextEditWin->PixelToLogic(aPt);
1916  bPostIt = IsTextEditHit(aPt);
1917  }
1918  if (bPostIt)
1919  {
1920  Point aPixPos(rMEvt.GetPosPixel());
1922  if (pWin)
1923  aR = pWin->LogicToPixel(aR);
1924  else if (pTextEditWin)
1925  aR = pTextEditWin->LogicToPixel(aR);
1926  if (aPixPos.X() < aR.Left())
1927  aPixPos.setX(aR.Left());
1928  if (aPixPos.X() > aR.Right())
1929  aPixPos.setX(aR.Right());
1930  if (aPixPos.Y() < aR.Top())
1931  aPixPos.setY(aR.Top());
1932  if (aPixPos.Y() > aR.Bottom())
1933  aPixPos.setY(aR.Bottom());
1934  MouseEvent aMEvt(aPixPos, rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(),
1935  rMEvt.GetModifier());
1936  if (pTextEditOutlinerView->MouseMove(aMEvt) && bSelMode)
1937  {
1939  return true;
1940  }
1941  }
1942  }
1943  return SdrGlueEditView::MouseMove(rMEvt, pWin);
1944 }
1945 
1947 {
1948  // as long as OutlinerView returns a sal_Bool, it only gets CommandEventId::StartDrag
1949  if (pTextEditOutlinerView != nullptr)
1950  {
1951  if (rCEvt.GetCommand() == CommandEventId::StartDrag)
1952  {
1953  bool bPostIt = pTextEditOutliner->IsInSelectionMode() || !rCEvt.IsMouseEvent();
1954  if (!bPostIt && rCEvt.IsMouseEvent())
1955  {
1956  Point aPt(rCEvt.GetMousePosPixel());
1957  if (pWin != nullptr)
1958  aPt = pWin->PixelToLogic(aPt);
1959  else if (pTextEditWin != nullptr)
1960  aPt = pTextEditWin->PixelToLogic(aPt);
1961  bPostIt = IsTextEditHit(aPt);
1962  }
1963  if (bPostIt)
1964  {
1965  Point aPixPos(rCEvt.GetMousePosPixel());
1966  if (rCEvt.IsMouseEvent() && pWin)
1967  {
1969  if (aPixPos.X() < aR.Left())
1970  aPixPos.setX(aR.Left());
1971  if (aPixPos.X() > aR.Right())
1972  aPixPos.setX(aR.Right());
1973  if (aPixPos.Y() < aR.Top())
1974  aPixPos.setY(aR.Top());
1975  if (aPixPos.Y() > aR.Bottom())
1976  aPixPos.setY(aR.Bottom());
1977  }
1978  CommandEvent aCEvt(aPixPos, rCEvt.GetCommand(), rCEvt.IsMouseEvent());
1979  // Command is void at the OutlinerView, sadly
1981  if (pWin != nullptr && pWin != pTextEditWin)
1982  SetTextEditWin(pWin);
1984  return true;
1985  }
1986  }
1987  else
1988  {
1990  return true;
1991  }
1992  }
1993  return SdrGlueEditView::Command(rCEvt, pWin);
1994 }
1995 
1997 {
1998  bool bRet = false;
1999  if (pTextEditOutliner != nullptr && pTextEditOutlinerView != nullptr)
2000  {
2002  {
2003  const sal_Int32 nParaCnt = pTextEditOutliner->GetParagraphCount();
2004  Paragraph* pLastPara = pTextEditOutliner->GetParagraph(nParaCnt > 1 ? nParaCnt - 1 : 0);
2005 
2007  if (aESel.nStartPara == 0 && aESel.nStartPos == 0 && aESel.nEndPara == (nParaCnt - 1))
2008  {
2009  if (pTextEditOutliner->GetText(pLastPara).getLength() == aESel.nEndPos)
2010  bRet = true;
2011  }
2012  // in case the selection was done backwards
2013  if (!bRet && aESel.nEndPara == 0 && aESel.nEndPos == 0
2014  && aESel.nStartPara == (nParaCnt - 1))
2015  {
2016  if (pTextEditOutliner->GetText(pLastPara).getLength() == aESel.nStartPos)
2017  bRet = true;
2018  }
2019  }
2020  else
2021  {
2022  bRet = true;
2023  }
2024  }
2025  return bRet;
2026 }
2027 
2029 {
2030  if (pTextEditOutlinerView != nullptr && pTextEditWin != nullptr)
2031  {
2032  vcl::Cursor* pCsr = pTextEditWin->GetCursor();
2033  if (pCsr != nullptr)
2034  {
2035  Size aSiz(pCsr->GetSize());
2036  if (aSiz.Width() != 0 && aSiz.Height() != 0)
2037  {
2038  MakeVisible(tools::Rectangle(pCsr->GetPos(), aSiz), *pTextEditWin);
2039  }
2040  }
2041  }
2042 }
2043 
2045 {
2046  SvtScriptType nScriptType = SvtScriptType::NONE;
2047 
2048  if (IsTextEdit())
2049  {
2052 
2055  }
2056  else
2057  {
2058  const size_t nMarkCount(GetMarkedObjectCount());
2059 
2060  for (size_t i = 0; i < nMarkCount; ++i)
2061  {
2063 
2064  if (pParaObj)
2065  {
2066  nScriptType |= pParaObj->GetTextObject().GetScriptType();
2067  }
2068  }
2069  }
2070 
2071  if (nScriptType == SvtScriptType::NONE)
2072  nScriptType = SvtScriptType::LATIN;
2073 
2074  return nScriptType;
2075 }
2076 
2077 void SdrObjEditView::GetAttributes(SfxItemSet& rTargetSet, bool bOnlyHardAttr) const
2078 {
2079  if (mxSelectionController.is())
2080  if (mxSelectionController->GetAttributes(rTargetSet, bOnlyHardAttr))
2081  return;
2082 
2083  if (IsTextEdit())
2084  {
2085  DBG_ASSERT(pTextEditOutlinerView != nullptr,
2086  "SdrObjEditView::GetAttributes(): pTextEditOutlinerView=NULL");
2087  DBG_ASSERT(pTextEditOutliner != nullptr,
2088  "SdrObjEditView::GetAttributes(): pTextEditOutliner=NULL");
2089 
2090  // take care of bOnlyHardAttr(!)
2091  if (!bOnlyHardAttr && mxTextEditObj->GetStyleSheet())
2092  rTargetSet.Put(mxTextEditObj->GetStyleSheet()->GetItemSet());
2093 
2094  // add object attributes
2095  rTargetSet.Put(mxTextEditObj->GetMergedItemSet());
2096 
2098  {
2099  // FALSE= regard InvalidItems as "holes," not as Default
2100  rTargetSet.Put(pTextEditOutlinerView->GetAttribs(), false);
2101  }
2102 
2104  {
2105  MergeNotPersistAttrFromMarked(rTargetSet);
2106  }
2107  }
2108  else
2109  {
2110  SdrGlueEditView::GetAttributes(rTargetSet, bOnlyHardAttr);
2111  }
2112 }
2113 
2114 bool SdrObjEditView::SetAttributes(const SfxItemSet& rSet, bool bReplaceAll)
2115 {
2116  bool bRet = false;
2117  bool bTextEdit = pTextEditOutlinerView != nullptr && mxTextEditObj.is();
2118  bool bAllTextSelected = ImpIsTextEditAllSelected();
2119  const SfxItemSet* pSet = &rSet;
2120 
2121  if (!bTextEdit)
2122  {
2123  // no TextEdit active -> all Items to drawing object
2124  if (mxSelectionController.is())
2125  bRet = mxSelectionController->SetAttributes(*pSet, bReplaceAll);
2126 
2127  if (!bRet)
2128  {
2129  SdrGlueEditView::SetAttributes(*pSet, bReplaceAll);
2130  bRet = true;
2131  }
2132  }
2133  else
2134  {
2135 #ifdef DBG_UTIL
2136  {
2137  bool bHasEEFeatureItems = false;
2138  SfxItemIter aIter(rSet);
2139  for (const SfxPoolItem* pItem = aIter.GetCurItem(); !bHasEEFeatureItems && pItem;
2140  pItem = aIter.NextItem())
2141  {
2142  if (!IsInvalidItem(pItem))
2143  {
2144  sal_uInt16 nW = pItem->Which();
2145  if (nW >= EE_FEATURE_START && nW <= EE_FEATURE_END)
2146  bHasEEFeatureItems = true;
2147  }
2148  }
2149 
2150  if (bHasEEFeatureItems)
2151  {
2152  const OUString aMessage("SdrObjEditView::SetAttributes(): Setting EE_FEATURE items "
2153  "at the SdrView does not make sense! It only leads to "
2154  "overhead and unreadable documents.");
2155  std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(
2156  nullptr, VclMessageType::Info, VclButtonsType::Ok, aMessage));
2157  xInfoBox->run();
2158  }
2159  }
2160 #endif
2161 
2162  bool bOnlyEEItems;
2163  bool bNoEEItems = !SearchOutlinerItems(*pSet, bReplaceAll, &bOnlyEEItems);
2164  // everything selected? -> attributes to the border, too
2165  // if no EEItems, attributes to the border only
2166  if (bAllTextSelected || bNoEEItems)
2167  {
2168  if (mxSelectionController.is())
2169  bRet = mxSelectionController->SetAttributes(*pSet, bReplaceAll);
2170 
2171  if (!bRet)
2172  {
2173  const bool bUndo = IsUndoEnabled();
2174 
2175  if (bUndo)
2176  {
2177  BegUndo(ImpGetDescriptionString(STR_EditSetAttributes));
2178  AddUndo(
2179  GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*mxTextEditObj.get()));
2180 
2181  // If this is a text object also rescue the OutlinerParaObject since
2182  // applying attributes to the object may change text layout when
2183  // multiple portions exist with multiple formats. If an OutlinerParaObject
2184  // really exists and needs to be rescued is evaluated in the undo
2185  // implementation itself.
2186  bool bRescueText = mxTextEditObj.get();
2187 
2188  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(
2189  *mxTextEditObj.get(), false, !bNoEEItems || bRescueText));
2190  EndUndo();
2191  }
2192 
2193  mxTextEditObj->SetMergedItemSetAndBroadcast(*pSet, bReplaceAll);
2194 
2195  FlushComeBackTimer(); // to set ModeHasChanged immediately
2196  }
2197  }
2198  else if (!bOnlyEEItems)
2199  {
2200  // Otherwise split Set, if necessary.
2201  // Now we build an ItemSet aSet that doesn't contain EE_Items from
2202  // *pSet (otherwise it would be a copy).
2203  std::unique_ptr<sal_uInt16[]> pNewWhichTable
2205  SfxItemSet aSet(mpModel->GetItemPool(), pNewWhichTable.get());
2206  pNewWhichTable.reset();
2207  SfxWhichIter aIter(aSet);
2208  sal_uInt16 nWhich = aIter.FirstWhich();
2209  while (nWhich != 0)
2210  {
2211  const SfxPoolItem* pItem;
2212  SfxItemState eState = pSet->GetItemState(nWhich, false, &pItem);
2213  if (eState == SfxItemState::SET)
2214  aSet.Put(*pItem);
2215  nWhich = aIter.NextWhich();
2216  }
2217 
2218  if (mxSelectionController.is())
2219  bRet = mxSelectionController->SetAttributes(aSet, bReplaceAll);
2220 
2221  if (!bRet)
2222  {
2223  if (IsUndoEnabled())
2224  {
2225  BegUndo(ImpGetDescriptionString(STR_EditSetAttributes));
2226  AddUndo(
2227  GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*mxTextEditObj.get()));
2228  AddUndo(
2229  GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*mxTextEditObj.get()));
2230  EndUndo();
2231  }
2232 
2233  mxTextEditObj->SetMergedItemSetAndBroadcast(aSet, bReplaceAll);
2234 
2236  {
2238  }
2239  }
2241  }
2242  if (!bNoEEItems)
2243  {
2244  // and now the attributes to the EditEngine
2245  if (bReplaceAll)
2246  {
2248  }
2250 
2251  Outliner* pTEOutliner = pTextEditOutlinerView->GetOutliner();
2252  if (mpModel && pTEOutliner && pTEOutliner->IsModified())
2253  mpModel->SetChanged();
2254 
2256  }
2257  bRet = true;
2258  }
2259  return bRet;
2260 }
2261 
2263 {
2264  SfxStyleSheet* pSheet = nullptr;
2265 
2266  if (mxSelectionController.is())
2267  {
2268  if (mxSelectionController->GetStyleSheet(pSheet))
2269  return pSheet;
2270  }
2271 
2273  {
2275  }
2276  else
2277  {
2278  pSheet = SdrGlueEditView::GetStyleSheet();
2279  }
2280  return pSheet;
2281 }
2282 
2283 void SdrObjEditView::SetStyleSheet(SfxStyleSheet* pStyleSheet, bool bDontRemoveHardAttr)
2284 {
2285  if (mxSelectionController.is())
2286  {
2287  if (mxSelectionController->SetStyleSheet(pStyleSheet, bDontRemoveHardAttr))
2288  return;
2289  }
2290 
2291  // if we are currently in edit mode we must also set the stylesheet
2292  // on all paragraphs in the Outliner for the edit view
2293  if (nullptr != pTextEditOutlinerView)
2294  {
2295  Outliner* pOutliner = pTextEditOutlinerView->GetOutliner();
2296 
2297  const sal_Int32 nParaCount = pOutliner->GetParagraphCount();
2298  for (sal_Int32 nPara = 0; nPara < nParaCount; nPara++)
2299  {
2300  pOutliner->SetStyleSheet(nPara, pStyleSheet);
2301  }
2302  }
2303 
2304  SdrGlueEditView::SetStyleSheet(pStyleSheet, bDontRemoveHardAttr);
2305 }
2306 
2308 {
2309  SdrGlueEditView::AddWindowToPaintView(pNewWin, pWindow);
2310 
2312  {
2313  OutlinerView* pOutlView = ImpMakeOutlinerView(static_cast<vcl::Window*>(pNewWin), nullptr);
2314  pTextEditOutliner->InsertView(pOutlView);
2315  }
2316 }
2317 
2319 {
2321 
2323  {
2324  for (size_t i = pTextEditOutliner->GetViewCount(); i > 0;)
2325  {
2326  i--;
2327  OutlinerView* pOLV = pTextEditOutliner->GetView(i);
2328  if (pOLV && pOLV->GetWindow() == static_cast<vcl::Window*>(pOldWin))
2329  {
2330  pTextEditOutliner->RemoveView(i);
2331  }
2332  }
2333  }
2334 
2335  lcl_RemoveTextEditOutlinerViews(this, GetSdrPageView(), pOldWin);
2336 }
2337 
2339 {
2340  return pTextEditOutliner != nullptr && pTextEditOutliner->IsInSelectionMode();
2341 }
2342 
2343 // MacroMode
2344 
2345 void SdrObjEditView::BegMacroObj(const Point& rPnt, short nTol, SdrObject* pObj, SdrPageView* pPV,
2346  vcl::Window* pWin)
2347 {
2348  BrkMacroObj();
2349  if (pObj != nullptr && pPV != nullptr && pWin != nullptr && pObj->HasMacro())
2350  {
2351  nTol = ImpGetHitTolLogic(nTol, nullptr);
2352  pMacroObj = pObj;
2353  pMacroPV = pPV;
2354  pMacroWin = pWin;
2355  bMacroDown = false;
2356  nMacroTol = sal_uInt16(nTol);
2357  aMacroDownPos = rPnt;
2358  MovMacroObj(rPnt);
2359  }
2360 }
2361 
2363 {
2364  if (pMacroObj != nullptr && bMacroDown)
2365  {
2366  SdrObjMacroHitRec aHitRec;
2367  aHitRec.aPos = rUpPos;
2368  aHitRec.nTol = nMacroTol;
2369  aHitRec.pVisiLayer = &pMacroPV->GetVisibleLayers();
2370  aHitRec.pPageView = pMacroPV;
2372  bMacroDown = false;
2373  }
2374 }
2375 
2377 {
2378  if (pMacroObj != nullptr && !bMacroDown)
2379  {
2380  SdrObjMacroHitRec aHitRec;
2381  aHitRec.aPos = rDownPos;
2382  aHitRec.nTol = nMacroTol;
2383  aHitRec.pVisiLayer = &pMacroPV->GetVisibleLayers();
2384  aHitRec.pPageView = pMacroPV;
2386  bMacroDown = true;
2387  }
2388 }
2389 
2391 {
2392  if (pMacroObj != nullptr)
2393  {
2394  SdrObjMacroHitRec aHitRec;
2395  aHitRec.aPos = rPnt;
2396  aHitRec.nTol = nMacroTol;
2397  aHitRec.pVisiLayer = &pMacroPV->GetVisibleLayers();
2398  aHitRec.pPageView = pMacroPV;
2399  bool bDown = pMacroObj->IsMacroHit(aHitRec);
2400  if (bDown)
2401  ImpMacroDown(rPnt);
2402  else
2403  ImpMacroUp(rPnt);
2404  }
2405 }
2406 
2408 {
2409  if (pMacroObj != nullptr)
2410  {
2412  pMacroObj = nullptr;
2413  pMacroPV = nullptr;
2414  pMacroWin = nullptr;
2415  }
2416 }
2417 
2419 {
2420  if (pMacroObj != nullptr && bMacroDown)
2421  {
2423  SdrObjMacroHitRec aHitRec;
2424  aHitRec.aPos = aMacroDownPos;
2425  aHitRec.nTol = nMacroTol;
2426  aHitRec.pVisiLayer = &pMacroPV->GetVisibleLayers();
2427  aHitRec.pPageView = pMacroPV;
2428  bool bRet = pMacroObj->DoMacro(aHitRec);
2429  pMacroObj = nullptr;
2430  pMacroPV = nullptr;
2431  pMacroWin = nullptr;
2432  return bRet;
2433  }
2434  else
2435  {
2436  BrkMacroObj();
2437  return false;
2438  }
2439 }
2440 
2443 void SdrObjEditView::getTextSelection(css::uno::Any& rSelection)
2444 {
2445  if (IsTextEdit())
2446  {
2447  OutlinerView* pOutlinerView = GetTextEditOutlinerView();
2448  if (pOutlinerView && pOutlinerView->HasSelection())
2449  {
2450  SdrObject* pObj = GetTextEditObject();
2451 
2452  if (pObj)
2453  {
2454  css::uno::Reference<css::text::XText> xText(pObj->getUnoShape(),
2455  css::uno::UNO_QUERY);
2456  if (xText.is())
2457  {
2458  SvxUnoTextBase* pRange
2459  = comphelper::getUnoTunnelImplementation<SvxUnoTextBase>(xText);
2460  if (pRange)
2461  {
2462  rSelection
2463  <<= pRange->createTextCursorBySelection(pOutlinerView->GetSelection());
2464  }
2465  }
2466  }
2467  }
2468  }
2469 }
2470 
2471 /* check if we have a single selection and that single object likes
2472  to handle the mouse and keyboard events itself
2473 
2474  TODO: the selection controller should be queried from the
2475  object specific view contact. Currently this method only
2476  works for tables.
2477 */
2479 {
2481 
2482  if (mxSelectionController.is())
2483  {
2485  mxSelectionController->onSelectionHasChanged();
2486  }
2487 
2488  mxSelectionController.clear();
2489 
2490  const SdrMarkList& rMarkList = GetMarkedObjectList();
2491  if (rMarkList.GetMarkCount() == 1)
2492  {
2493  const SdrObject* pObj(rMarkList.GetMark(0)->GetMarkedSdrObj());
2494  SdrView* pView(dynamic_cast<SdrView*>(this));
2495 
2496  // check for table
2497  if (pObj && pView && (pObj->GetObjInventor() == SdrInventor::Default)
2498  && (pObj->GetObjIdentifier() == OBJ_TABLE))
2499  {
2501  *pView, static_cast<const sdr::table::SdrTableObj&>(*pObj),
2503 
2504  if (mxSelectionController.is())
2505  {
2506  mxLastSelectionController.clear();
2507  mxSelectionController->onSelectionHasChanged();
2508  }
2509  }
2510  }
2511 }
2512 
2513 IMPL_LINK(SdrObjEditView, EndPasteOrDropHdl, PasteOrDropInfos*, pInfo, void)
2514 {
2515  OnEndPasteOrDrop(pInfo);
2516 }
2517 
2518 IMPL_LINK(SdrObjEditView, BeginPasteOrDropHdl, PasteOrDropInfos*, pInfo, void)
2519 {
2520  OnBeginPasteOrDrop(pInfo);
2521 }
2522 
2524 {
2525  // applications can derive from these virtual methods to do something before a drop or paste operation
2526 }
2527 
2529 {
2530  // applications can derive from these virtual methods to do something before a drop or paste operation
2531 }
2532 
2534 {
2535  sal_uInt16 nLevel = 0xFFFF;
2536  if (IsTextEdit())
2537  {
2538  DBG_ASSERT(pTextEditOutlinerView != nullptr,
2539  "SdrObjEditView::GetAttributes(): pTextEditOutlinerView=NULL");
2540  DBG_ASSERT(pTextEditOutliner != nullptr,
2541  "SdrObjEditView::GetAttributes(): pTextEditOutliner=NULL");
2543  {
2544  //start and end position
2546  sal_uInt16 nStartPara = ::std::min(aSelect.nStartPara, aSelect.nEndPara);
2547  sal_uInt16 nEndPara = ::std::max(aSelect.nStartPara, aSelect.nEndPara);
2548  //get level from each paragraph
2549  nLevel = 0;
2550  for (sal_uInt16 nPara = nStartPara; nPara <= nEndPara; nPara++)
2551  {
2552  sal_uInt16 nParaDepth
2553  = 1 << static_cast<sal_uInt16>(pTextEditOutliner->GetDepth(nPara));
2554  if (!(nLevel & nParaDepth))
2555  nLevel += nParaDepth;
2556  }
2557  //reduce one level for Outliner Object
2558  //if( nLevel > 0 && GetTextEditObject()->GetObjIdentifier() == OBJ_OUTLINETEXT )
2559  // nLevel = nLevel >> 1;
2560  //no bullet paragraph selected
2561  if (nLevel == 0)
2562  nLevel = 0xFFFF;
2563  }
2564  }
2565  return nLevel;
2566 }
2567 
2569  sal_uInt16 nObjectIdentifier)
2570 {
2571  if (nObjectInventor != SdrInventor::Default && nObjectInventor != SdrInventor::E3d)
2572  return false;
2573  switch (nObjectIdentifier)
2574  {
2575  case OBJ_NONE:
2576  case OBJ_GRUP:
2577  return false;
2578  case OBJ_LINE:
2579  case OBJ_RECT:
2580  case OBJ_CIRC:
2581  case OBJ_SECT:
2582  case OBJ_CARC:
2583  case OBJ_CCUT:
2584  case OBJ_POLY:
2585  case OBJ_PLIN:
2586  case OBJ_PATHLINE:
2587  case OBJ_PATHFILL:
2588  case OBJ_FREELINE:
2589  case OBJ_FREEFILL:
2590  case OBJ_SPLNLINE:
2591  case OBJ_SPLNFILL:
2592  case OBJ_TEXT:
2593  case OBJ_TITLETEXT:
2594  case OBJ_OUTLINETEXT:
2595  case OBJ_GRAF:
2596  case OBJ_OLE2:
2597  case OBJ_TABLE:
2598  return true;
2599  case OBJ_EDGE:
2600  case OBJ_CAPTION:
2601  return false;
2602  case OBJ_PATHPOLY:
2603  case OBJ_PATHPLIN:
2604  return true;
2605  case OBJ_PAGE:
2606  case OBJ_MEASURE:
2607  case OBJ_FRAME:
2608  case OBJ_UNO:
2609  return false;
2610  case OBJ_CUSTOMSHAPE:
2611  return true;
2612  default:
2613  return false;
2614  }
2615 }
2616 
2617 static const sal_uInt16* GetFormatRangeImpl(bool bTextOnly)
2618 {
2619  static const sal_uInt16 gRanges[] = { SDRATTR_SHADOW_FIRST,
2628  XATTRSET_FILL,
2629  EE_PARA_START,
2630  EE_PARA_END, // text-only from here on
2631  EE_CHAR_START,
2632  EE_CHAR_END,
2634  SDRATTR_MISC_LAST, // table cell formats
2635  0,
2636  0 };
2637  return &gRanges[bTextOnly ? 10 : 0];
2638 }
2639 
2640 void SdrObjEditView::TakeFormatPaintBrush(std::shared_ptr<SfxItemSet>& rFormatSet)
2641 {
2642  const SdrMarkList& rMarkList = GetMarkedObjectList();
2643  if (rMarkList.GetMarkCount() > 0)
2644  {
2646 
2647  rFormatSet.reset(
2648  new SfxItemSet(GetModel()->GetItemPool(), GetFormatRangeImpl(pOLV != nullptr)));
2649  if (pOLV)
2650  {
2651  rFormatSet->Put(pOLV->GetAttribs());
2652  }
2653  else
2654  {
2655  const bool bOnlyHardAttr = false;
2656  rFormatSet->Put(GetAttrFromMarked(bOnlyHardAttr));
2657  }
2658 
2659  // check for cloning from table cell, in which case we need to copy cell-specific formatting attributes
2660  const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
2661  if (pObj && (pObj->GetObjInventor() == SdrInventor::Default)
2662  && (pObj->GetObjIdentifier() == OBJ_TABLE))
2663  {
2664  auto pTable = static_cast<const sdr::table::SdrTableObj*>(pObj);
2665  if (mxSelectionController.is() && pTable->getActiveCell().is())
2666  {
2667  mxSelectionController->GetAttributes(*rFormatSet, false);
2668  }
2669  }
2670  }
2671 }
2672 
2673 static SfxItemSet CreatePaintSet(const sal_uInt16* pRanges, SfxItemPool& rPool,
2674  const SfxItemSet& rSourceSet, const SfxItemSet& rTargetSet,
2675  bool bNoCharacterFormats, bool bNoParagraphFormats)
2676 {
2677  SfxItemSet aPaintSet(rPool, pRanges);
2678 
2679  while (*pRanges)
2680  {
2681  sal_uInt16 nWhich = *pRanges++;
2682  const sal_uInt16 nLastWhich = *pRanges++;
2683 
2684  if (bNoCharacterFormats && (nWhich == EE_CHAR_START))
2685  continue;
2686 
2687  if (bNoParagraphFormats && (nWhich == EE_PARA_START))
2688  continue;
2689 
2690  for (; nWhich < nLastWhich; nWhich++)
2691  {
2692  const SfxPoolItem* pSourceItem = rSourceSet.GetItem(nWhich);
2693  const SfxPoolItem* pTargetItem = rTargetSet.GetItem(nWhich);
2694 
2695  if ((pSourceItem && !pTargetItem)
2696  || (pSourceItem && pTargetItem && *pSourceItem != *pTargetItem))
2697  {
2698  aPaintSet.Put(*pSourceItem);
2699  }
2700  }
2701  }
2702  return aPaintSet;
2703 }
2704 
2706  SdrText* pText, bool bNoCharacterFormats,
2707  bool bNoParagraphFormats)
2708 {
2709  OutlinerParaObject* pParaObj = pText ? pText->GetOutlinerParaObject() : nullptr;
2710  if (pParaObj)
2711  {
2712  SdrOutliner& rOutliner = rTextObj.ImpGetDrawOutliner();
2713  rOutliner.SetText(*pParaObj);
2714 
2715  sal_Int32 nParaCount(rOutliner.GetParagraphCount());
2716 
2717  if (nParaCount)
2718  {
2719  for (sal_Int32 nPara = 0; nPara < nParaCount; nPara++)
2720  {
2721  if (!bNoCharacterFormats)
2722  rOutliner.RemoveCharAttribs(nPara);
2723 
2724  SfxItemSet aSet(rOutliner.GetParaAttribs(nPara));
2725  aSet.Put(CreatePaintSet(GetFormatRangeImpl(true), *aSet.GetPool(), rFormatSet, aSet,
2726  bNoCharacterFormats, bNoParagraphFormats));
2727  rOutliner.SetParaAttribs(nPara, aSet);
2728  }
2729 
2730  std::unique_ptr<OutlinerParaObject> pTemp = rOutliner.CreateParaObject(0, nParaCount);
2731  rOutliner.Clear();
2732 
2733  rTextObj.NbcSetOutlinerParaObjectForText(std::move(pTemp), pText);
2734  }
2735  }
2736 }
2737 
2738 void SdrObjEditView::ApplyFormatPaintBrush(SfxItemSet& rFormatSet, bool bNoCharacterFormats,
2739  bool bNoParagraphFormats)
2740 {
2741  if (mxSelectionController.is()
2742  && mxSelectionController->ApplyFormatPaintBrush(rFormatSet, bNoCharacterFormats,
2743  bNoParagraphFormats))
2744  {
2745  return;
2746  }
2747 
2749  const SdrMarkList& rMarkList = GetMarkedObjectList();
2750  if (!pOLV)
2751  {
2752  SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
2753  const SfxItemSet& rShapeSet = pObj->GetMergedItemSet();
2754 
2755  // if not in text edit mode (aka the user selected text or clicked on a word)
2756  // apply formatting attributes to selected shape
2757  // All formatting items (see ranges above) that are unequal in selected shape and
2758  // the format paintbrush are hard set on the selected shape.
2759 
2760  const sal_uInt16* pRanges = rFormatSet.GetRanges();
2761  bool bTextOnly = true;
2762 
2763  while (*pRanges)
2764  {
2765  if ((*pRanges != EE_PARA_START) && (*pRanges != EE_CHAR_START))
2766  {
2767  bTextOnly = false;
2768  break;
2769  }
2770  pRanges += 2;
2771  }
2772 
2773  if (!bTextOnly)
2774  {
2775  SfxItemSet aPaintSet(CreatePaintSet(GetFormatRangeImpl(false), *rShapeSet.GetPool(),
2776  rFormatSet, rShapeSet, bNoCharacterFormats,
2777  bNoParagraphFormats));
2778  SetAttrToMarked(aPaintSet, false /*bReplaceAll*/);
2779  }
2780 
2781  // now apply character and paragraph formatting to text, if the shape has any
2782  SdrTextObj* pTextObj = dynamic_cast<SdrTextObj*>(pObj);
2783  if (pTextObj)
2784  {
2785  sal_Int32 nText = pTextObj->getTextCount();
2786 
2787  while (--nText >= 0)
2788  {
2789  SdrText* pText = pTextObj->getText(nText);
2790  ApplyFormatPaintBrushToText(rFormatSet, *pTextObj, pText, bNoCharacterFormats,
2791  bNoParagraphFormats);
2792  }
2793  }
2794  }
2795  else
2796  {
2797  ::Outliner* pOutliner = pOLV->GetOutliner();
2798  if (pOutliner)
2799  {
2800  const EditEngine& rEditEngine = pOutliner->GetEditEngine();
2801 
2802  ESelection aSel(pOLV->GetSelection());
2803  if (!aSel.HasRange())
2804  pOLV->SetSelection(rEditEngine.GetWord(aSel, css::i18n::WordType::DICTIONARY_WORD));
2805 
2806  const bool bRemoveParaAttribs = !bNoParagraphFormats;
2807  pOLV->RemoveAttribsKeepLanguages(bRemoveParaAttribs);
2808  SfxItemSet aSet(pOLV->GetAttribs());
2809  SfxItemSet aPaintSet(CreatePaintSet(GetFormatRangeImpl(true), *aSet.GetPool(),
2810  rFormatSet, aSet, bNoCharacterFormats,
2811  bNoParagraphFormats));
2812  pOLV->SetAttribs(aPaintSet);
2813  }
2814  }
2815 
2816  // check for cloning to table cell, in which case we need to copy cell-specific formatting attributes
2817  SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
2818  if (pObj && (pObj->GetObjInventor() == SdrInventor::Default)
2819  && (pObj->GetObjIdentifier() == OBJ_TABLE))
2820  {
2821  auto pTable = static_cast<sdr::table::SdrTableObj*>(pObj);
2822  if (pTable->getActiveCell().is() && mxSelectionController.is())
2823  {
2824  mxSelectionController->SetAttributes(rFormatSet, false);
2825  }
2826  }
2827 }
2828 
2829 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Point TopLeft() const
bool MouseButtonDown(const MouseEvent &)
virtual void ModelHasChanged() override
Definition: svdedxv.cxx:247
OutDevType GetOutDevType() const
rtl::Reference< sdr::overlay::OverlayManager > const & GetOverlayManager() const
OutlineText, special text object for StarDraw.
Definition: svdobj.hxx:136
bool IsTextEditInSelectionMode() const
Definition: svdedxv.cxx:2338
bool IsMacroHit(const SdrObjMacroHitRec &rRec) const
Definition: svdobj.cxx:1826
void ImpPaintOutlinerView(OutlinerView &rOutlView, const tools::Rectangle &rRect, OutputDevice &rTargetDevice) const
Definition: svdedxv.cxx:722
virtual void OnEndPasteOrDrop(PasteOrDropInfos *pInfo)
Definition: svdedxv.cxx:2528
#define EE_FEATURE_END
TextChainCursorManager * ImpHandleMotionThroughBoxesKeyInput(const KeyEvent &rKEvt, bool *bOutHandled)
Definition: svdedxv.cxx:1763
#define EE_ITEMS_START
sal_Int32 nStartPara
bool SearchOutlinerItems(const SfxItemSet &rSet, bool bInklDefaults, bool *pbOnlyEE)
Search an ItemSet for Outliner/EditEngine Items.
Definition: svdetc.cxx:358
virtual bool MouseButtonUp(const MouseEvent &, OutputDevice *)
Definition: svdpntv.hxx:460
OUString GetWord(sal_Int32 nPara, sal_Int32 nIndex)
SdrHintKind GetKind() const
Definition: svdmodel.hxx:124
size_t GetMarkCount() const
Definition: svdmark.hxx:179
constexpr::Color COL_BLACK(0x00, 0x00, 0x00)
virtual void DeleteWindowFromPaintView(OutputDevice *pOldWin) override
Definition: svdedxv.cxx:2318
virtual const tools::Rectangle & GetCurrentBoundRect() const
Definition: svdobj.cxx:881
static void impDecomposeBlockTextPrimitiveDirect(drawinglayer::primitive2d::Primitive2DContainer &rTarget, SdrOutliner &rOutliner, const basegfx::B2DHomMatrix &rNewTransformA, const basegfx::B2DHomMatrix &rNewTransformB, const basegfx::B2DRange &rClipRange)
virtual SdrEndTextEditKind SdrEndTextEdit(bool bDontDeleteReally=false)
Definition: svdedxv.cxx:1399
SVX_DLLPRIVATE void ImpClearVars()
Definition: svdedxv.cxx:75
Universal Network Object packed into SvDraw object.
Definition: svdobj.hxx:146
foreign graphic (StarView Graphic)
Definition: svdobj.hxx:137
bool IsChainable() const
Definition: svdotext.cxx:1933
void GetAttributes(SfxItemSet &rTargetSet, bool bOnlyHardAttr) const
Definition: svdedtv1.cxx:1321
virtual void BrkAction() override
Definition: svdedxv.cxx:132
tools::Rectangle & Intersection(const tools::Rectangle &rRect)
std::unique_ptr< SdrOutliner > pTextEditOutliner
Definition: svdedxv.hxx:81
sal_uInt16 GetTransparentSelectionPercent() const
natural cubic Spline (ni)
Definition: svdobj.hxx:132
void RemoveAttribsKeepLanguages(bool bRemoveParaAttribs)
bool IsMacroObj() const
Definition: svdedxv.hxx:268
Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
media shape
Definition: svdobj.hxx:148
void SetNotPersistAttrToMarked(const SfxItemSet &rAttr)
Definition: svdedtv1.cxx:704
rtl::Reference< sdr::SelectionController > mxLastSelectionController
Definition: svdedxv.hxx:103
virtual void TakeTextEditArea(Size *pPaperMin, Size *pPaperMax, tools::Rectangle *pViewInit, tools::Rectangle *pViewMin) const
Definition: svdotxed.cxx:132
Polyline represented by SdrPathObj.
Definition: svdobj.hxx:142
virtual SdrText * getText(sal_Int32 nIndex) const override
returns the nth available text.
Definition: svdotext.cxx:2066
virtual void DeleteWindowFromPaintView(OutputDevice *pOldWin)
Definition: svdpntv.cxx:411
SfxStyleSheet * GetStyleSheet() const
Definition: svdedxv.cxx:2262
periodic cubic Spline (ni)
Definition: svdobj.hxx:133
tools::Rectangle const & GetOutputArea() const
tools::Rectangle aMinTextEditArea
Definition: svdedxv.hxx:90
long AdjustLeft(long nHorzMoveDelta)
bool bTextEditDontDelete
Definition: svdedxv.hxx:96
SdrTextObj * GetTextEditObject() const
Definition: svdedxv.hxx:223
bool IsUndoEnabled() const
Definition: svdedtv.cxx:1031
void ShowCursor(bool bGotoCursor=true, bool bActivate=false)
ESelection const & GetPostChainingSel(const SdrTextObj *)
Definition: textchain.cxx:61
MouseEventModifiers GetMode() const
void ImpMakeTextCursorAreaVisible()
Definition: svdedxv.cxx:2028
void ImpChainingEventHdl()
Definition: svdedxv.cxx:904
void FlushComeBackTimer() const
Definition: svdpntv.cxx:262
SdrEndTextEditKind
Definition: svdedxv.hxx:48
virtual bool Undo() override
react depending on edit mode and if no more undo is possible
bool IsTextFrame() const
Definition: svdotext.hxx:343
void HideSdrPage() override
Definition: svdedxv.cxx:206
bool IsMapModeEnabled() const
rtl::Reference< sdr::SelectionController > CreateTableController(SdrView &rView, const SdrTableObj &rObj, const rtl::Reference< sdr::SelectionController > &xRefController)
double getX() const
bool MouseButtonUp(const MouseEvent &)
SdrHintKind
Definition: svdmodel.hxx:93
caption object
Definition: svdobj.hxx:140
bool IsInserted() const
Definition: svdobj.hxx:792
virtual void BckAction() override
Definition: svdmrkv.cxx:296
bool bTextEditOnlyOneView
Definition: svdedxv.hxx:97
std::unique_ptr< sal_uInt16[]> RemoveWhichRange(const sal_uInt16 *pOldWhichTable, sal_uInt16 nRangeBeg, sal_uInt16 nRangeEnd)
Definition: svdetc.cxx:381
static SfxItemSet CreatePaintSet(const sal_uInt16 *pRanges, SfxItemPool &rPool, const SfxItemSet &rSourceSet, const SfxItemSet &rTargetSet, bool bNoCharacterFormats, bool bNoParagraphFormats)
Definition: svdedxv.cxx:2673
void BegUndo()
Definition: svdedtv.hxx:179
sal_uInt16 FirstWhich()
void SetPreChainingSel(const SdrTextObj *, ESelection const &)
Definition: textchain.cxx:55
const MapMode & GetMapMode() const
double getY() const
void ImpSetContourPolygon(SdrOutliner &rOutliner, tools::Rectangle const &rAnchorRect, bool bLineWidth) const
Definition: svdotext.cxx:541
SdrInventor
Definition: svdobj.hxx:152
static const sal_uInt16 * GetFormatRangeImpl(bool bTextOnly)
Definition: svdedxv.cxx:2617
measurement object
Definition: svdobj.hxx:144
const SfxBroadcaster * GetBroadcaster() const
Definition: svdobj.cxx:654
SdrMark * GetMark(size_t nNum) const
Definition: svdmark.cxx:234
OLE object.
Definition: svdobj.hxx:138
sal_Int32 GetParagraphCount() const
void append(std::unique_ptr< OverlayObject > pOverlayObject)
#define SDRATTR_MISC_LAST
Definition: svddef.hxx:220
virtual OUString TakeObjNameSingul() const override
Definition: svdotext.cxx:938
virtual SfxItemSet & GetItemSet()
void SetControlWord(EVControlBits nWord)
constexpr::Color COL_LIGHTGRAY(0xC0, 0xC0, 0xC0)
virtual bool MouseMove(const MouseEvent &rMEvt, OutputDevice *pWin) override
handle mouse over effects for handles
Definition: svdedxv.cxx:1903
void EnableMapMode(bool bEnable=true)
virtual void BrkAction() override
Definition: svdmrkv.cxx:304
void EndTextEditAllViews() const
Checks if this or other views have an active text edit, if true, end them.
Definition: svdedtv.cxx:1036
circle cut
Definition: svdobj.hxx:125
tools::Rectangle GetBoundRect() const
open free-hand line
Definition: svdobj.hxx:130
virtual bool Redo() override
EEControlBits
OutlinerView * ImpFindOutlinerView(vcl::Window const *pWin) const
Definition: svdedxv.cxx:1668
virtual bool MouseButtonDown(const MouseEvent &, OutputDevice *)
Definition: svdpntv.hxx:459
css::uno::Reference< css::text::XTextCursor > createTextCursorBySelection(const ESelection &rSel)
virtual void EndTextEdit(SdrOutliner &rOutl)
Definition: svdotxed.cxx:265
virtual void MarkListHasChanged() override
Definition: svdedxv.cxx:2478
polygon, PolyPolygon
Definition: svdobj.hxx:126
#define EE_FEATURE_START
SfxHintId GetId() const
object that represents a SdrPage
Definition: svdobj.hxx:143
line
Definition: svdobj.hxx:120
virtual bool HasText() const override
Definition: svdotxat.cxx:429
std::unique_ptr< BaseProcessor2D > createProcessor2DFromOutputDevice(OutputDevice &rTargetOutDev, const drawinglayer::geometry::ViewInformation2D &rViewInformation2D)
OutputDevice * GetRefDevice() const
Definition: svdmodel.hxx:330
sal_uInt16 NextWhich()
long AdjustBottom(long nVertMoveDelta)
void Move(long nHorzMoveDelta, long nVertMoveDelta)
virtual bool MouseMove(const MouseEvent &rMEvt, OutputDevice *pWin) override
handle mouse over effects for handles
Definition: svdmrkv.cxx:1398
virtual std::unique_ptr< SdrUndoAction > CreateUndoDeleteObject(SdrObject &rObject, bool bOrdNumDirect=false)
Definition: svdundo.cxx:1669
virtual bool MouseButtonUp(const MouseEvent &rMEvt, OutputDevice *pWin) override
Definition: svdedxv.cxx:1865
virtual long GetRotateAngle() const override
Definition: svdotxtr.cxx:88
bool IsEmpty() const
TextChain * GetTextChain() const
Definition: svdotext.cxx:1494
SdrModel * mpModel
Definition: svdpntv.hxx:132
EVControlBits GetControlWord() const
sal_uInt16 GetClicks() const
Color const & GetBackgroundColor() const
void SetAttrToMarked(const SfxItemSet &rAttr, bool bReplaceAll)
Definition: svdedtv1.cxx:1051
Polygon/PolyPolygon represented by SdrPathObj.
Definition: svdobj.hxx:141
const Size & GetSize() const
const SfxPoolItem * NextItem()
bool IsTextEditFrameHit(const Point &rHit) const
Definition: svdedxv.cxx:1733
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: svdedxv.cxx:225
SdrPageWindow * GetPageWindow(sal_uInt32 nIndex) const
Definition: svdpagv.cxx:93
long Right() const
void SetNameDirty()
Definition: svdmark.hxx:194
SvtScriptType GetScriptType() const
connector object
Definition: svdobj.hxx:139
virtual css::uno::Reference< css::uno::XInterface > getUnoShape()
Definition: svdobj.cxx:2793
sal_uInt16 GetButtons() const
sal_uInt16 ImpGetHitTolLogic(short nHitTol, const OutputDevice *pOut) const
Definition: svdpntv.cxx:333
tools::Rectangle aTextEditArea
Definition: svdedxv.hxx:89
SdrPage * getSdrPageFromSdrObject() const
Definition: svdobj.cxx:289
OUString SvxResId(const char *pId)
Definition: dialmgr.cxx:28
#define SDRATTR_SHADOW_LAST
Definition: svddef.hxx:178
void setX(long nX)
OUTDEV_WINDOW
OutlinerView * GetView(size_t nIndex) const
continuously activated OLE (PlugIn-Frame or similar)
Definition: svdobj.hxx:145
OutputDevice & GetTargetOutputDevice()
#define XATTR_FILL_FIRST
Definition: xdef.hxx:106
bool OutputToWindow() const
EEAnchorMode GetAnchorMode() const
bool IsMouseEvent() const
int nCount
static void ApplyFormatPaintBrushToText(SfxItemSet const &rFormatSet, SdrTextObj &rTextObj, SdrText *pText, bool bNoCharacterFormats, bool bNoParagraphFormats)
helper function for selections with multiple SdrText for one SdrTextObj (f.e.
Definition: svdedxv.cxx:2705
void TextEditDrawing(SdrPaintWindow &rPaintWindow) const
Definition: svdedxv.cxx:672
static SfxViewShell * Current()
SfxStyleSheet * GetStyleSheet() const
Definition: svdobj.cxx:2162
bool isLocked() const
Definition: svdmodel.hxx:552
void RemoveCharAttribs(sal_Int32 nPara, sal_uInt16 nWhich=0)
virtual void ModelHasChanged() override
Definition: svdedtv.cxx:360
virtual void onEditOutlinerStatusEvent(EditStatus *pEditStatus)
called from the SdrObjEditView during text edit when the status of the edit outliner changes ...
Definition: svdotext.cxx:1867
PolyLine.
Definition: svdobj.hxx:127
SdrPageView * ShowSdrPage(SdrPage *pPage) override
Definition: svdedxv.cxx:138
const Point & GetTextEditOffset() const
Definition: svdotext.hxx:216
long Top() const
SfxItemSet const & GetParaAttribs(sal_Int32 nPara)
OutputDevice * GetFirstOutputDevice() const
Definition: svdpntv.cxx:93
sal_uInt16 GetHdlSize() const
Definition: svdhdl.hxx:465
bool HasSelection() const
void SetNilChainingEvent(const SdrTextObj *, bool)
Definition: textchain.cxx:44
circle, ellipse
Definition: svdobj.hxx:122
bool bTextEditNewObj
Definition: svdedxv.hxx:98
void BegMacroObj(const Point &rPnt, short nTol, SdrObject *pObj, SdrPageView *pPV, vcl::Window *pWin)
Definition: svdedxv.cxx:2345
virtual SvtScriptType GetScriptType() const
Definition: svdedxv.cxx:2044
virtual void SetChanged(bool bFlg=true)
Definition: svdmodel.cxx:1274
SfxStyleSheet * GetStyleSheet() const
Definition: svdedtv1.cxx:1342
void SetAttributes(const SfxItemSet &rSet, bool bReplaceAll)
Definition: svdedtv1.cxx:1333
B2IRange fround(const B2DRange &rRange)
void SetParaAttribs(sal_Int32 nPara, const SfxItemSet &)
void EndUndo()
Definition: svdedtv.cxx:278
EditView & GetEditView() const
sal_uInt32 PaintWindowCount() const
Definition: svdpntv.hxx:228
virtual void BckAction() override
Definition: svdedxv.cxx:126
const Point & GetPos() const
IMPL_LINK_NOARG(SdrObjEditView, ImpAfterCutOrPasteChainingEventHdl, LinkParamNone *, void)
Definition: svdedxv.cxx:973
virtual bool KeyInput(const KeyEvent &rKEvt, vcl::Window *pWin)
Definition: svdpntv.cxx:794
sdr::overlay::OverlayObjectList maTEOverlayGroup
Definition: svdedxv.hxx:74
SdrObject * GetMarkedSdrObj() const
Definition: svdmark.hxx:67
const SdrLayerIDSet & GetVisibleLayers() const
Definition: svdpagv.hxx:215
void AddUndo(std::unique_ptr< SdrUndoAction > pUndo)
Definition: svdedtv.hxx:183
void SetBeginPasteOrDropHdl(const Link< PasteOrDropInfos *, void > &rLink)
void SetLineColor()
const EditTextObject & GetTextObject() const
sal_Int32 nEndPara
object group
Definition: svdobj.hxx:119
const SdrOutliner * GetTextEditOutliner() const
Definition: svdedxv.hxx:233
SvtScriptType
VclPtr< vcl::Window > pTextEditWin
Definition: svdedxv.hxx:83
#define XATTR_LINE_LAST
Definition: xdef.hxx:103
virtual void MarkListHasChanged() override
Definition: svdedtv.cxx:354
void SetText(const OutlinerParaObject &)
void SetAttribs(const SfxItemSet &)
tools::WeakReference< SdrTextObj > mxTextEditObj
Definition: svdedxv.hxx:79
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
#define DBG_ASSERT(sCon, aError)
SfxUndoManager * GetSdrUndoManager() const
Definition: svdmodel.cxx:1969
void RegisterViewShell(OutlinerViewShell *pViewShell)
uno_Any a
void getTextSelection(css::uno::Any &rSelection)
fills the given any with a XTextCursor for the current text selection.
Definition: svdedxv.cxx:2443
bool IsFitToSize() const
returns true if the old feature for fitting shape content should into shape is enabled. implies IsAutoFit()==false!
Definition: svdotext.cxx:1850
abstract object (SdrObject)
Definition: svdobj.hxx:118
virtual sal_uInt16 GetObjIdentifier() const
Definition: svdobj.cxx:585
virtual bool BegTextEdit(SdrOutliner &rOutl)
Definition: svdotxed.cxx:41
VclPtr< vcl::Window > pMacroWin
Definition: svdedxv.hxx:87
CursorChainingEvent const & GetCursorEvent(const SdrTextObj *)
Definition: textchain.cxx:28
#define EE_PARA_END
OutlinerView * ImpMakeOutlinerView(vcl::Window *pWin, OutlinerView *pGivenView, SfxViewShell *pViewShell=nullptr) const
Definition: svdedxv.cxx:836
virtual void MovAction(const Point &rPnt) override
Definition: svdmrkv.cxx:260
#define EE_PARA_START
virtual void TakeActionRect(tools::Rectangle &rRect) const override
Definition: svdedxv.cxx:213
size_t GetMarkedObjectCount() const
Definition: svdmrkv.hxx:249
void MergeNotPersistAttrFromMarked(SfxItemSet &rAttr) const
Definition: svdedtv1.cxx:790
virtual void EndAction() override
Definition: svdmrkv.cxx:278
#define SDRATTR_TABLE_FIRST
Definition: svddef.hxx:398
SdrPageView * pTextEditPV
Definition: svdedxv.hxx:80
void HandleCursorEventAfterChaining(const CursorChainingEvent aCurEvt, const ESelection &aNewSel)
virtual void MakeVisible(const tools::Rectangle &rRect, vcl::Window &rWin)
Definition: svdpntv.cxx:1019
static bool SupportsFormatPaintbrush(SdrInventor nObjectInventor, sal_uInt16 nObjectIdentifier)
returns true if the shape identified by its inventor and identifier supports format paint brush opera...
Definition: svdedxv.cxx:2568
int i
virtual bool IsAction() const override
Definition: svdmrkv.cxx:255
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
const SdrMarkList & GetMarkedObjectList() const
Definition: svdmrkv.hxx:243
#define SDRATTR_MISC_FIRST
Definition: svddef.hxx:193
virtual bool KeyInput(const KeyEvent &rKEvt, vcl::Window *pWin) override
Definition: svdedxv.cxx:1786
void CompleteOnlineSpelling()
bool IsTextEditHit(const Point &rHit) const
Definition: svdedxv.cxx:1705
virtual bool SdrBeginTextEdit(SdrObject *pObj, SdrPageView *pPV=nullptr, vcl::Window *pWin=nullptr, bool bIsNewObj=false, SdrOutliner *pGivenOutliner=nullptr, OutlinerView *pGivenOutlinerView=nullptr, bool bDontDeleteOutliner=false, bool bOnlyOneView=false, bool bGrabFocus=true)
Definition: svdedxv.cxx:1052
void ActionChanged() const
Definition: svdobj.cxx:283
#define SDRATTR_SHADOW_FIRST
Definition: svddef.hxx:170
void SetFillColor()
CommandEventId GetCommand() const
Link< EditFieldInfo *, void > aOldCalcFieldValueLink
Definition: svdedxv.hxx:91
void SetMergedItemSetAndBroadcast(const SfxItemSet &rSet, bool bClearAllItems=false)
Definition: svdobj.cxx:1951
void SetCalcFieldValueHdl(const Link< EditFieldInfo *, void > &rLink)
SvtScriptType GetSelectedScriptType() const
void SetEndTextEditHdl(const Link< SdrUndoManager *, void > &rLink)
long Bottom() const
SdrModel & getSdrModelFromSdrObject() const
Definition: svdobj.cxx:299
bool IsModified() const
sal_uInt32 GetOrdNum() const
The order number (aka ZOrder, aka z-index) determines whether a SdrObject is located above or below a...
Definition: svdobj.cxx:823
virtual void TakeTextAnchorRect(::tools::Rectangle &rAnchorRect) const
Definition: svdotext.cxx:603
virtual void append(const Primitive2DReference &) override
virtual bool HasMacro() const
Definition: svdobj.cxx:1784
void SetMoveOutside(bool bOn)
Definition: svdhdl.cxx:2213
virtual sal_uInt16 GetObjIdentifier() const override
Definition: svdotext.cxx:432
const OutlinerView * GetTextEditOutlinerView() const
Definition: svdedxv.hxx:235
const vcl::Region & GetRedrawRegion() const
vcl::Cursor * GetCursor() const
virtual SdrPageView * ShowSdrPage(SdrPage *pPage)
Definition: svdpntv.cxx:373
bool IsInside(const Point &rPOINT) const
Outliner * GetOutliner() const
void reset(reference_type *pReference)
virtual void EditViewSelectionChange() const override
Definition: svdedxv.cxx:653
bool ImpIsTextEditAllSelected() const
Definition: svdedxv.cxx:1996
Size GetOutputSizePixel() const
MapUnit GetMapUnit() const
virtual bool Command(const CommandEvent &, vcl::Window *)
Definition: svdpntv.hxx:463
bool IsTopToBottom() const
bool GetNilChainingEvent(const SdrTextObj *)
Definition: textchain.cxx:39
virtual void AddWindowToPaintView(OutputDevice *pNewWin, vcl::Window *pWindow)
Definition: svdpntv.cxx:399
virtual SdrText * getActiveText() const
returns the currently active text.
Definition: svdotext.cxx:2057
virtual drawinglayer::primitive2d::Primitive2DContainer getOverlayObjectPrimitive2DSequence() const
#define SDRATTR_GRAF_FIRST
Definition: svddef.hxx:307
void ImpInvalidateOutlinerView(OutlinerView const &rOutlView) const
Definition: svdedxv.cxx:783
const SfxPoolItem & GetMergedItem(const sal_uInt16 nWhich) const
Definition: svdobj.cxx:1946
virtual void PaintMacro(OutputDevice &rOut, const tools::Rectangle &rDirtyRect, const SdrObjMacroHitRec &rRec) const
Definition: svdobj.cxx:1804
bool MouseMove(const MouseEvent &)
bool IsContourTextFrame() const
Definition: svdotext.cxx:1753
sal_uInt16 GetModifier() const
const SdrLayerIDSet * pVisiLayer
Definition: svdobj.hxx:192
void HideCursor(bool bDeactivate=false)
size_t GetViewCount() const
Abstract DrawObject.
Definition: svdobj.hxx:312
virtual SfxViewShell * GetSfxViewShell() const
Get access to the view shell owning this draw view, if any.
Definition: svdmrkv.cxx:1566
void GrabFocus()
bool getPossibleGridOffsetForSdrObject(basegfx::B2DVector &rOffset, const SdrObject *pObj, const SdrPageView *pPV) const
Definition: svdmrkv.cxx:1954
SfxItemPool * GetPool() const
virtual SdrObject * RemoveObject(size_t nObjNum)
Definition: svdpage.cxx:436
const EditEngine & GetEditEngine() const
SdrUndoFactory & GetSdrUndoFactory() const
returns the models undo factory.
Definition: svdmodel.cxx:1974
bool EndMacroObj()
Definition: svdedxv.cxx:2418
#define SDRATTR_GRAF_LAST
Definition: svddef.hxx:318
void ImpMacroDown(const Point &rDownPos)
Definition: svdedxv.cxx:2376
virtual bool MouseButtonDown(const MouseEvent &rMEvt, OutputDevice *pWin) override
Definition: svdedxv.cxx:1821
virtual SdrInventor GetObjInventor() const
Definition: svdobj.cxx:580
sal_uInt16 nMacroTol
Definition: svdedxv.hxx:94
void RemoveAttribs(bool bRemoveParaAttribs, bool bKeepLanguages=false)
SdrTextObj * GetNextLinkInChain() const
Definition: svdotext.cxx:1986
virtual SdrLayerID GetLayer() const
Definition: svdobj.cxx:604
bool is() const
basegfx::B2DRange b2DRectangleFromRectangle(const ::tools::Rectangle &rRect)
const Point & GetMousePosPixel() const
sal_uInt16 GetInvalidateMore() const
Point PixelToLogic(const Point &rDevicePt) const
Point LogicToPixel(const Point &rLogicPt) const
ESelection GetSelection() const
const SdrLayerIDSet & GetLockedLayers() const
Definition: svdpagv.hxx:219
sal_uInt16 GetSelectionLevel() const
Definition: svdedxv.cxx:2533
void MovMacroObj(const Point &rPnt)
Definition: svdedxv.cxx:2390
bool IsSet(SdrLayerID a) const
Definition: svdsob.hxx:66
#define XATTR_LINE_FIRST
Definition: xdef.hxx:89
closed Bezier-curve
Definition: svdobj.hxx:129
void setEditViewCallbacks(const EditViewCallbacks *pEditViewCallbacks)
void SetCursorEvent(const SdrTextObj *, CursorChainingEvent const &)
Definition: textchain.cxx:33
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
circle section
Definition: svdobj.hxx:123
virtual SdrUndoManager * getSdrUndoManagerForEnhancedTextEdit() const
Definition: svdedxv.cxx:1046
TitleText, special text object for StarDraw.
Definition: svdobj.hxx:135
std::unique_ptr< OutlinerParaObject > CreateParaObject(sal_Int32 nStartPara=0, sal_Int32 nParaCount=EE_PARA_ALL) const
virtual drawinglayer::primitive2d::Primitive2DContainer createOverlayObjectPrimitive2DSequence()
void Broadcast(const SfxHint &rHint)
css::uno::Reference< css::graphic::XPrimitive2D > Primitive2DReference
void SetSelection(const ESelection &)
void SetStyleSheet(SfxStyleSheet *pStyleSheet, bool bDontRemoveHardAttr)
Definition: svdedtv1.cxx:1351
OverlayObject & getOverlayObject(sal_uInt32 nIndex) const
void ImpMoveCursorAfterChainingEvent(TextChainCursorManager *pCursorManager)
Definition: svdedxv.cxx:983
bool HasFill() const
Definition: svdoattr.cxx:132
#define EE_CHAR_START
SfxItemState
virtual bool IsTextEdit() const final override
Definition: svdedxv.cxx:1663
virtual void TakeTextRect(SdrOutliner &rOutliner, tools::Rectangle &rTextRect, bool bNoEditText, tools::Rectangle *pAnchorRect, bool bLineWidth=true) const
Definition: svdotext.cxx:638
bool HandleKeyEvent(const KeyEvent &rKEvt)
long AdjustRight(long nHorzMoveDelta)
bool HasLine() const
Definition: svdoattr.cxx:137
circle arc
Definition: svdobj.hxx:124
SdrObjKind
Definition: svdobj.hxx:116
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: svdmrkv.cxx:178
vcl::Window * GetWindow() const
tools::Rectangle & Union(const tools::Rectangle &rRect)
#define SAL_WARN_IF(condition, area, stream)
SdrPageView * GetTextEditPageView() const
Definition: svdedxv.cxx:1666
virtual OutlinerParaObject * GetOutlinerParaObject() const override
Definition: svdotext.cxx:1371
SdrPage * GetPage() const
Definition: svdpagv.hxx:171
void SetAnchorMode(EEAnchorMode eMode)
void SetCursor(vcl::Cursor *pCursor)
OUString ImpGetDescriptionString(const char *pStrCacheID, ImpGetDescriptionOptions nOpt=ImpGetDescriptionOptions::NONE) const
Definition: svdmrkv.cxx:2385
reference_type * get() const
void Command(const CommandEvent &rCEvt)
void SetEndCutPasteLinkHdl(const Link< LinkParamNone *, void > &rLink)
virtual void TakeActionRect(tools::Rectangle &rRect) const override
Definition: svdmrkv.cxx:312
vcl::Cursor * pTextEditCursorBuffer
Definition: svdedxv.hxx:84
void NbcSetOutlinerParaObjectForText(std::unique_ptr< OutlinerParaObject > pTextObject, SdrText *pText)
Definition: svdotext.cxx:1385
Color GetTextEditBackgroundColor(const SdrObjEditView &rView)
Definition: svdetc.cxx:713
#define SAL_INFO(area, stream)
OutlinerView * pTextEditOutlinerView
Definition: svdedxv.hxx:82
virtual ~SdrObjEditView() override
Definition: svdedxv.cxx:100
const SfxItemSet & GetMergedItemSet() const
Definition: svdobj.cxx:1911
virtual bool Command(const CommandEvent &rCEvt, vcl::Window *pWin) override
Definition: svdedxv.cxx:1946
std::unique_ptr< SdrOutliner > SdrMakeOutliner(OutlinerMode nOutlinerMode, SdrModel &rModel)
Create an Outliner with the engine-global default settings on the heap.
Definition: svdetc.cxx:338
SdrPageView * pMacroPV
Definition: svdedxv.hxx:86
bool PostKeyEvent(const KeyEvent &rKEvt, vcl::Window const *pFrameWin=nullptr)
void SetEndPasteOrDropHdl(const Link< PasteOrDropInfos *, void > &rLink)
void SetBackgroundColor(const Color &rColor)
virtual void EditViewInvalidate(const tools::Rectangle &rRect) const override
Definition: svdedxv.cxx:629
void AdjustMarkHdl(SfxViewShell *pOtherShell=nullptr)
Definition: svdmrkv.cxx:2343
SdrPaintWindow & GetPaintWindow() const
void SetTextEditWin(vcl::Window *pWin)
Definition: svdedxv.cxx:1685
SfxItemSet GetAttrFromMarked(bool bOnlyHardAttr) const
Definition: svdedtv1.cxx:897
vcl::Window * GetWindow() const
long AdjustTop(long nVertMoveDelta)
const SfxStyleSheet * GetStyleSheet() const
bool isEndTextEditTriggeredFromUndo() const
void onChainingEvent()
called from the SdrObjEditView during text edit when a chain of boxes is to be updated ...
Definition: svdotext.cxx:1956
void SetOutputArea(const tools::Rectangle &rRect)
virtual void AddWindowToPaintView(OutputDevice *pNewWin, vcl::Window *pWindow) override
Definition: svdedxv.cxx:2307
SfxUndoManager * mpOldTextEditUndoManager
Definition: svdedxv.hxx:106
const Point & GetPosPixel() const
SdrObject * GetMarkedObjectByIndex(size_t nNum) const
Definition: svdmrkv.hxx:248
EVControlBits
void SetUpdateMode(bool bUpdate)
long Left() const
void translate(double fX, double fY)
void SetStyleSheet(sal_Int32 nPara, SfxStyleSheet *pStyle)
#define SDRATTR_TABLE_LAST
Definition: svddef.hxx:405
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage)
SdrPageView * GetSdrPageView() const
Definition: svdpntv.hxx:310
bool IsVertical() const
virtual bool CalcFieldValue(const SvxFieldItem &rField, sal_Int32 nPara, sal_uInt16 nPos, bool bEdit, o3tl::optional< Color > &rpTxtColor, o3tl::optional< Color > &rpFldColor, OUString &rRet) const
Definition: svdotxfl.cxx:24
const Link< EditFieldInfo *, void > & GetCalcFieldValueHdl() const
bool SetAttributes(const SfxItemSet &rSet, bool bReplaceAll)
Definition: svdedxv.cxx:2114
SdrObjEditView(SdrModel &rSdrModel, OutputDevice *pOut)
Definition: svdedxv.cxx:93
Point aMacroDownPos
Definition: svdedxv.hxx:92
EEAnchorMode
const sal_uInt16 * GetRanges() const
virtual sal_Int32 getTextCount() const override
returns the number of texts available for this object.
Definition: svdotext.cxx:2081
SdrHdlList maHdlList
Definition: svdmrkv.hxx:103
#define SDRATTR_TEXT_USEFIXEDCELLHEIGHT
Definition: svddef.hxx:217
SfxItemSet GetAttribs()
const SfxItemPool & GetItemPool() const
Definition: svdmodel.hxx:314
bool GetIsAutomaticFontColor() const
sal_uInt16 nTol
Definition: svdobj.hxx:194
A SdrPage contains exactly one SdrObjList and a description of the physical page dimensions (size / m...
Definition: svdpage.hxx:366
virtual bool DoMacro(const SdrObjMacroHitRec &rRec)
Definition: svdobj.cxx:1821
SdrObjList * getParentSdrObjListFromSdrObject() const
Definition: svdobj.cxx:325
void Clear()
OutlinerParaObject * GetOutlinerParaObject() const
Definition: svdtext.cxx:90
void SetStyleSheet(SfxStyleSheet *pStyleSheet, bool bDontRemoveHardAttr)
Definition: svdedxv.cxx:2283
virtual void OnBeginPasteOrDrop(PasteOrDropInfos *pInfo)
Definition: svdedxv.cxx:2523
virtual void InvalidateOneWin(OutputDevice &rWin)
If the View should not call Invalidate() on the windows, override the following 2 methods and do some...
Definition: svdpntv.cxx:868
bool IsInvalidItem(const SfxPoolItem *pItem)
void ApplyFormatPaintBrush(SfxItemSet &rFormatSet, bool bNoCharacterFormats, bool bNoParagraphFormats)
applies a format paint brush set from the current selection.
Definition: svdedxv.cxx:2738
bool bQuickTextEditMode
Definition: svdedxv.hxx:99
void ImpMacroUp(const Point &rUpPos)
Definition: svdedxv.cxx:2362
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
void GetAttributes(SfxItemSet &rTargetSet, bool bOnlyHardAttr) const
Definition: svdedxv.cxx:2077
#define XATTRSET_FILL
Definition: xdef.hxx:128
rtl::Reference< sdr::SelectionController > mxSelectionController
Definition: svdedxv.hxx:102
IMPL_LINK(SdrObjEditView, ImpOutlinerStatusEventHdl, EditStatus &, rEditStat, void)
Definition: svdedxv.cxx:892
void BrkMacroObj()
Definition: svdedxv.cxx:2407
virtual void HideSdrPage() override
Definition: svdmrkv.cxx:331
SdrMarkList & GetMarkedObjectListWriteAccess()
Definition: svdmrkv.hxx:239
SdrTextObj * GetPrevLinkInChain() const
Definition: svdotext.cxx:2024
SdrModel * GetModel() const
Definition: svdpntv.hxx:271
SdrObject * pMacroObj
Definition: svdedxv.hxx:85
virtual OutlinerParaObject * GetOutlinerParaObject() const
Definition: svdobj.cxx:1770
SdrOutliner & ImpGetDrawOutliner() const
Definition: svdotext.cxx:1161
void CheckMarked()
Definition: svdmrkv.cxx:1571
OutputDevice & GetOutputDevice() const
text object
Definition: svdobj.hxx:134
static bool HasTextImpl(SdrOutliner const *pOutliner)
returns false if the given pointer is NULL or if the given SdrOutliner contains no text...
Definition: svdotext.cxx:437
SdrPaintWindow * GetPaintWindow(sal_uInt32 nIndex) const
Definition: svdpntv.cxx:77
open Bezier-curve
Definition: svdobj.hxx:128
const SdrPageView * pPageView
Definition: svdobj.hxx:193
virtual EEAnchorMode GetOutlinerViewAnchorMode() const
Definition: svdotxed.cxx:304
closed free-hand line
Definition: svdobj.hxx:131
void SetInvalidateMore(sal_uInt16 nPixel)
#define EE_CHAR_END
virtual void EndAction() override
Definition: svdedxv.cxx:119
B2DRange maRange
virtual bool IsFontwork() const
Definition: svdotext.cxx:1741
const SfxPoolItem * GetCurItem() const
sal_uInt16 GetDefaultTabulator() const
Definition: svdmodel.hxx:337
virtual void MovAction(const Point &rPnt) override
Definition: svdedxv.cxx:112
void SetTextAnimationAllowed(bool bNew)
Definition: svdotext.cxx:1857
void RemoveView(OutlinerView const *pView)
rectangle (round corners optional)
Definition: svdobj.hxx:121
virtual bool IsAction() const override
Definition: svdedxv.cxx:110
Color getHilightColor() const
void TakeFormatPaintBrush(std::shared_ptr< SfxItemSet > &rFormatSet)
returns a format paint brush set from the current selection
Definition: svdedxv.cxx:2640
sal_uInt32 PageWindowCount() const
Definition: svdpagv.hxx:94
virtual OutputDevice & EditViewOutputDevice() const override
Definition: svdedxv.cxx:670
void SetWindow(vcl::Window *pWindow)
::rtl::Reference< IEventProcessor > xProcessor
#define EE_ITEMS_END
bool IsEmptyPresObj() const
Definition: svdobj.hxx:880
void Paint(const tools::Rectangle &rRect, OutputDevice *pTargetDevice=nullptr)