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  sal_uIntPtr 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 (sal_uIntPtr 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 (sal_uIntPtr 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  bool getVisualizeSurroundingFrame() const { return mbVisualizeSurroundingFrame; }
439 
442  getOverlayObjectPrimitive2DSequence() const override;
443 
444  // data write access. In this OverlayObject we only have the
445  // callback that triggers detecting if something *has* changed
446  void checkDataChange(const basegfx::B2DRange& rMinTextEditArea);
447  void checkSelectionChange();
448 };
449 
451 TextEditOverlayObject::createOverlayObjectPrimitive2DSequence()
452 {
454 
456  if (getVisualizeSurroundingFrame())
457  {
458  const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
459  const double fTransparence(aSvtOptionsDrawinglayer.GetTransparentSelectionPercent() * 0.01);
460  const sal_uInt16 nPixSiz(getOutlinerView().GetInvalidateMore() - 1);
461 
463  maRange, getBaseColor().getBColor(), fTransparence, std::max(6, nPixSiz - 2), // grow
464  0.0, // shrink
465  0.0));
466  }
467 
468  // add buffered TextPrimitives
469  aRetval.append(maTextPrimitives);
470 
471  return aRetval;
472 }
473 
474 TextEditOverlayObject::TextEditOverlayObject(const Color& rColor, OutlinerView& rOutlinerView,
475  bool bVisualizeSurroundingFrame)
476  : OverlayObject(rColor)
477  , mpOverlaySelection(nullptr)
478  , mrOutlinerView(rOutlinerView)
479  , maLastRange()
480  , maRange()
481  , maTextPrimitives()
482  , maLastTextPrimitives()
483  , mbVisualizeSurroundingFrame(bVisualizeSurroundingFrame)
484 {
485  // no AA for TextEdit overlay
486  allowAntiAliase(false);
487 
488  // create local OverlaySelection - this is an integral part of EditText
489  // visualization
490  const std::vector<basegfx::B2DRange> aEmptySelection{};
492  rColor, aEmptySelection, true);
493 }
494 
495 TextEditOverlayObject::~TextEditOverlayObject()
496 {
497  if (getOverlaySelection())
498  {
499  delete mpOverlaySelection;
500  mpOverlaySelection = nullptr;
501  }
502 
503  if (getOverlayManager())
504  {
505  getOverlayManager()->remove(*this);
506  }
507 }
508 
510 TextEditOverlayObject::getOverlayObjectPrimitive2DSequence() const
511 {
512  if (!getPrimitive2DSequence().empty())
513  {
514  if (!maRange.equal(maLastRange) || maLastTextPrimitives != maTextPrimitives)
515  {
516  // conditions of last local decomposition have changed, delete to force new evaluation
517  const_cast<TextEditOverlayObject*>(this)->resetPrimitive2DSequence();
518  }
519  }
520 
521  if (getPrimitive2DSequence().empty())
522  {
523  // remember new buffered values
524  const_cast<TextEditOverlayObject*>(this)->maLastRange = maRange;
525  const_cast<TextEditOverlayObject*>(this)->maLastTextPrimitives = maTextPrimitives;
526  }
527 
528  // call base implementation
529  return OverlayObject::getOverlayObjectPrimitive2DSequence();
530 }
531 
532 void TextEditOverlayObject::checkDataChange(const basegfx::B2DRange& rMinTextEditArea)
533 {
534  bool bObjectChange(false);
535 
536  // check current range
537  const tools::Rectangle aOutArea(mrOutlinerView.GetOutputArea());
539  aNewRange.expand(rMinTextEditArea);
540 
541  if (aNewRange != maRange)
542  {
543  maRange = aNewRange;
544  bObjectChange = true;
545  }
546 
547  // check if text primitives did change
548  SdrOutliner* pSdrOutliner = dynamic_cast<SdrOutliner*>(getOutlinerView().GetOutliner());
549 
550  if (pSdrOutliner)
551  {
552  // get TextPrimitives directly from active Outliner
553  basegfx::B2DHomMatrix aNewTransformA;
554  basegfx::B2DHomMatrix aNewTransformB;
555  basegfx::B2DRange aClipRange;
557 
558  // active Outliner is always in unified oriented coordinate system (currently)
559  // so just translate to TopLeft of visible Range. Keep in mind that top-left
560  // depends on vertical text and top-to-bottom text attributes
561  const tools::Rectangle aVisArea(mrOutlinerView.GetVisArea());
562  const bool bVerticalWriting(pSdrOutliner->IsVertical());
563  const bool bTopToBottom(pSdrOutliner->IsTopToBottom());
564  const double fStartInX(bVerticalWriting && bTopToBottom
565  ? aOutArea.Right() - aVisArea.Left()
566  : aOutArea.Left() - aVisArea.Left());
567  const double fStartInY(bVerticalWriting && !bTopToBottom
568  ? aOutArea.Bottom() - aVisArea.Top()
569  : aOutArea.Top() - aVisArea.Top());
570 
571  aNewTransformB.translate(fStartInX, fStartInY);
572 
573  // get the current TextPrimitives. This is the most expensive part
574  // of this mechanism, it *may* be possible to buffer layouted
575  // primitives per ParaPortion with/in/dependent on the EditEngine
576  // content if needed. For now, get and compare
578  aNewTextPrimitives, *pSdrOutliner, aNewTransformA, aNewTransformB, aClipRange);
579 
580  if (aNewTextPrimitives != maTextPrimitives)
581  {
582  maTextPrimitives = aNewTextPrimitives;
583  bObjectChange = true;
584  }
585  }
586 
587  if (bObjectChange)
588  {
589  // if there really *was* a change signal the OverlayManager to
590  // refresh this object's visualization
591  objectChange();
592 
593  // on data change, always do a SelectionChange, too
594  // since the selection is an integral part of text visualization
595  checkSelectionChange();
596  }
597 }
598 
599 void TextEditOverlayObject::checkSelectionChange()
600 {
601  if (getOverlaySelection() && getOverlayManager())
602  {
603  std::vector<tools::Rectangle> aLogicRects;
604  std::vector<basegfx::B2DRange> aLogicRanges;
605  const Size aLogicPixel(getOverlayManager()->getOutputDevice().PixelToLogic(Size(1, 1)));
606 
607  // get logic selection
608  getOutlinerView().GetSelectionRectangles(aLogicRects);
609 
610  aLogicRanges.reserve(aLogicRects.size());
611  for (const auto& aRect : aLogicRects)
612  {
613  // convert from logic Rectangles to logic Ranges, do not forget to add
614  // one Unit (in this case logical units for one pixel, pre-calculated)
615  aLogicRanges.emplace_back(
616  aRect.Left() - aLogicPixel.Width(), aRect.Top() - aLogicPixel.Height(),
617  aRect.Right() + aLogicPixel.Width(), aRect.Bottom() + aLogicPixel.Height());
618  }
619 
620  mpOverlaySelection->setRanges(aLogicRanges);
621  }
622 }
623 } // end of anonymous namespace
624 
625 // TextEdit
626 
627 // callback from the active EditView, forward to evtl. existing instances of the
628 // TextEditOverlayObject(s). This will additionally update the selection which
629 // is an integral part of the text visualization
631 {
632  if (IsTextEdit())
633  {
634  // MinTextRange may have changed. Forward it, too
635  const basegfx::B2DRange aMinTextRange
637 
638  for (sal_uInt32 a(0); a < maTEOverlayGroup.count(); a++)
639  {
640  TextEditOverlayObject* pCandidate
641  = dynamic_cast<TextEditOverlayObject*>(&maTEOverlayGroup.getOverlayObject(a));
642 
643  if (pCandidate)
644  {
645  pCandidate->checkDataChange(aMinTextRange);
646  }
647  }
648  }
649 }
650 
651 // callback from the active EditView, forward to evtl. existing instances of the
652 // TextEditOverlayObject(s). This cvall *only* updates the selection visualization
653 // which is e.g. used when only the selection is changed, but not the text
655 {
656  if (IsTextEdit())
657  {
658  for (sal_uInt32 a(0); a < maTEOverlayGroup.count(); a++)
659  {
660  TextEditOverlayObject* pCandidate
661  = dynamic_cast<TextEditOverlayObject*>(&maTEOverlayGroup.getOverlayObject(a));
662 
663  if (pCandidate)
664  {
665  pCandidate->checkSelectionChange();
666  }
667  }
668  }
669 }
670 
672 
674 {
676  {
677  // adapt all TextEditOverlayObject(s), so call EditViewInvalidate()
678  // to update accordingly (will update selection, too). Suppress new
679  // stuff when LibreOfficeKit is active
681  }
682  else
683  {
684  // draw old text edit stuff
685  if (IsTextEdit())
686  {
687  const SdrOutliner* pActiveOutliner = GetTextEditOutliner();
688 
689  if (pActiveOutliner)
690  {
691  const sal_uInt32 nViewCount(pActiveOutliner->GetViewCount());
692 
693  if (nViewCount)
694  {
695  const vcl::Region& rRedrawRegion = rPaintWindow.GetRedrawRegion();
696  const tools::Rectangle aCheckRect(rRedrawRegion.GetBoundRect());
697 
698  for (sal_uInt32 i(0); i < nViewCount; i++)
699  {
700  OutlinerView* pOLV = pActiveOutliner->GetView(i);
701 
702  // If rPaintWindow knows that the output device is a render
703  // context and is aware of the underlying vcl::Window,
704  // compare against that; that's how double-buffering can
705  // still find the matching OutlinerView.
706  OutputDevice* pOutputDevice = rPaintWindow.GetWindow()
707  ? rPaintWindow.GetWindow()
708  : &rPaintWindow.GetOutputDevice();
709  if (pOLV->GetWindow() == pOutputDevice
711  {
712  ImpPaintOutlinerView(*pOLV, aCheckRect,
713  rPaintWindow.GetTargetOutputDevice());
714  return;
715  }
716  }
717  }
718  }
719  }
720  }
721 }
722 
724  OutputDevice& rTargetDevice) const
725 {
726  const SdrTextObj* pText = GetTextEditObject();
727  bool bTextFrame(pText && pText->IsTextFrame());
728  bool bFitToSize(pTextEditOutliner->GetControlWord() & EEControlBits::STRETCHING);
729  bool bModified(pTextEditOutliner->IsModified());
730  tools::Rectangle aBlankRect(rOutlView.GetOutputArea());
731  aBlankRect.Union(aMinTextEditArea);
732  tools::Rectangle aPixRect(rTargetDevice.LogicToPixel(aBlankRect));
733 
734  // in the tiled rendering case, the setup is incomplete, and we very
735  // easily get an empty rRect on input - that will cause that everything is
736  // clipped; happens in case of editing text inside a shape in Calc.
737  // FIXME would be better to complete the setup so that we don't get an
738  // empty rRect here
740  aBlankRect.Intersection(rRect);
741 
742  rOutlView.GetOutliner()->SetUpdateMode(true); // Bugfix #22596#
743  rOutlView.Paint(aBlankRect, &rTargetDevice);
744 
745  if (!bModified)
746  {
747  pTextEditOutliner->ClearModifyFlag();
748  }
749 
750  if (bTextFrame && !bFitToSize)
751  {
752  // completely reworked to use primitives; this ensures same look and functionality
753  const drawinglayer::geometry::ViewInformation2D aViewInformation2D;
754  std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> xProcessor(
756  aViewInformation2D));
757 
758  if (xProcessor)
759  {
760  const bool bMapModeEnabled(rTargetDevice.IsMapModeEnabled());
762  const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
763  const Color aHilightColor(aSvtOptionsDrawinglayer.getHilightColor());
764  const double fTransparence(aSvtOptionsDrawinglayer.GetTransparentSelectionPercent()
765  * 0.01);
766  const sal_uInt16 nPixSiz(rOutlView.GetInvalidateMore() - 1);
769  aRange, aHilightColor.getBColor(), fTransparence,
770  std::max(6, nPixSiz - 2), // grow
771  0.0, // shrink
772  0.0));
773  const drawinglayer::primitive2d::Primitive2DContainer aSequence{ xReference };
774 
775  rTargetDevice.EnableMapMode(false);
776  xProcessor->process(aSequence);
777  rTargetDevice.EnableMapMode(bMapModeEnabled);
778  }
779  }
780 
781  rOutlView.ShowCursor(/*bGotoCursor=*/true, /*bActivate=*/true);
782 }
783 
785 {
786  vcl::Window* pWin = rOutlView.GetWindow();
787 
788  if (pWin)
789  {
790  const SdrTextObj* pText = GetTextEditObject();
791  bool bTextFrame(pText && pText->IsTextFrame());
792  bool bFitToSize(pText && pText->IsFitToSize());
793 
794  if (bTextFrame && !bFitToSize)
795  {
796  tools::Rectangle aBlankRect(rOutlView.GetOutputArea());
797  aBlankRect.Union(aMinTextEditArea);
798  tools::Rectangle aPixRect(pWin->LogicToPixel(aBlankRect));
799  sal_uInt16 nPixSiz(rOutlView.GetInvalidateMore() - 1);
800 
801  aPixRect.AdjustLeft(-1);
802  aPixRect.AdjustTop(-1);
803  aPixRect.AdjustRight(1);
804  aPixRect.AdjustBottom(1);
805 
806  {
807  // limit xPixRect because of driver problems when pixel coordinates are too far out
808  Size aMaxXY(pWin->GetOutputSizePixel());
809  long a(2 * nPixSiz);
810  long nMaxX(aMaxXY.Width() + a);
811  long nMaxY(aMaxXY.Height() + a);
812 
813  if (aPixRect.Left() < -a)
814  aPixRect.SetLeft(-a);
815  if (aPixRect.Top() < -a)
816  aPixRect.SetTop(-a);
817  if (aPixRect.Right() > nMaxX)
818  aPixRect.SetRight(nMaxX);
819  if (aPixRect.Bottom() > nMaxY)
820  aPixRect.SetBottom(nMaxY);
821  }
822 
823  tools::Rectangle aOuterPix(aPixRect);
824  aOuterPix.AdjustLeft(-nPixSiz);
825  aOuterPix.AdjustTop(-nPixSiz);
826  aOuterPix.AdjustRight(nPixSiz);
827  aOuterPix.AdjustBottom(nPixSiz);
828 
829  bool bMapModeEnabled(pWin->IsMapModeEnabled());
830  pWin->EnableMapMode(false);
831  pWin->Invalidate(aOuterPix);
832  pWin->EnableMapMode(bMapModeEnabled);
833  }
834  }
835 }
836 
838  SfxViewShell* pViewShell) const
839 {
840  // background
841  Color aBackground(GetTextEditBackgroundColor(*this));
842  SdrTextObj* pText = mxTextEditObj.get();
843  bool bTextFrame = pText != nullptr && pText->IsTextFrame();
844  bool bContourFrame = pText != nullptr && pText->IsContourTextFrame();
845  // create OutlinerView
846  OutlinerView* pOutlView = pGivenView;
847  pTextEditOutliner->SetUpdateMode(false);
848 
849  if (pOutlView == nullptr)
850  {
851  pOutlView = new OutlinerView(pTextEditOutliner.get(), pWin);
852  }
853  else
854  {
855  pOutlView->SetWindow(pWin);
856  }
857 
858  // disallow scrolling
859  EVControlBits nStat = pOutlView->GetControlWord();
860  nStat &= ~EVControlBits::AUTOSCROLL;
861  // AutoViewSize only if not ContourFrame.
862  if (!bContourFrame)
863  nStat |= EVControlBits::AUTOSIZE;
864  if (bTextFrame)
865  {
866  sal_uInt16 nPixSiz = maHdlList.GetHdlSize() * 2 + 1;
867  nStat |= EVControlBits::INVONEMORE;
868  pOutlView->SetInvalidateMore(nPixSiz);
869  }
870  pOutlView->SetControlWord(nStat);
871  pOutlView->SetBackgroundColor(aBackground);
872 
873  // In case we're in the process of constructing a new view shell,
874  // SfxViewShell::Current() may still point to the old one. So if possible,
875  // depend on the application owning this draw view to provide the view
876  // shell.
877  SfxViewShell* pSfxViewShell = pViewShell ? pViewShell : GetSfxViewShell();
878  pOutlView->RegisterViewShell(pSfxViewShell ? pSfxViewShell : SfxViewShell::Current());
879 
880  if (pText != nullptr)
881  {
882  pOutlView->SetAnchorMode(pText->GetOutlinerViewAnchorMode());
883  pTextEditOutliner->SetFixedCellHeight(
885  }
886  // do update before setting output area so that aTextEditArea can be recalculated
887  pTextEditOutliner->SetUpdateMode(true);
888  pOutlView->SetOutputArea(aTextEditArea);
889  ImpInvalidateOutlinerView(*pOutlView);
890  return pOutlView;
891 }
892 
893 IMPL_LINK(SdrObjEditView, ImpOutlinerStatusEventHdl, EditStatus&, rEditStat, void)
894 {
895  if (pTextEditOutliner)
896  {
897  SdrTextObj* pTextObj = mxTextEditObj.get();
898  if (pTextObj)
899  {
900  pTextObj->onEditOutlinerStatusEvent(&rEditStat);
901  }
902  }
903 }
904 
906 {
907  if (pTextEditOutliner)
908  {
909  SdrTextObj* pTextObj = mxTextEditObj.get();
911  if (pTextObj && pOLV)
912  {
913  TextChain* pTextChain = pTextObj->GetTextChain();
914 
915  // XXX: IsChainable and GetNilChainingEvent are a bit mixed up atm
916  if (!pTextObj->IsChainable())
917  {
918  return;
919  }
920  // This is true during an underflow-caused overflow (with pEdtOutl->SetText())
921  if (pTextChain->GetNilChainingEvent(pTextObj))
922  {
923  return;
924  }
925 
926  // We prevent to trigger further handling of overflow/underflow for pTextObj
927  pTextChain->SetNilChainingEvent(pTextObj, true); // XXX
928 
929  // Save previous selection pos // NOTE: It must be done to have the right CursorEvent in KeyInput
930  pTextChain->SetPreChainingSel(pTextObj, pOLV->GetSelection());
931  //maPreChainingSel = new ESelection(pOLV->GetSelection());
932 
933  // Handling Undo
934  const int nText = 0; // XXX: hardcoded index (SdrTextObj::getText handles only 0)
935 
936  const bool bUndoEnabled = GetModel() && IsUndoEnabled();
937  std::unique_ptr<SdrUndoObjSetText> pTxtUndo;
938  if (bUndoEnabled)
939  pTxtUndo.reset(
940  dynamic_cast<SdrUndoObjSetText*>(GetModel()
941  ->GetSdrUndoFactory()
942  .CreateUndoObjectSetText(*pTextObj, nText)
943  .release()));
944 
945  // trigger actual chaining
946  pTextObj->onChainingEvent();
947 
948  if (pTxtUndo)
949  {
950  pTxtUndo->AfterSetText();
951  if (!pTxtUndo->IsDifferent())
952  {
953  pTxtUndo.reset();
954  }
955  }
956 
957  if (pTxtUndo)
958  AddUndo(std::move(pTxtUndo));
959 
960  //maCursorEvent = new CursorChainingEvent(pTextChain->GetCursorEvent(pTextObj));
961  //SdrTextObj *pNextLink = pTextObj->GetNextLinkInChain();
962 
963  // NOTE: Must be called. Don't let the function return if you set it to true and not reset it
964  pTextChain->SetNilChainingEvent(pTextObj, false);
965  }
966  else
967  {
968  // XXX
969  SAL_INFO("svx.chaining", "[OnChaining] No Edit Outliner View");
970  }
971  }
972 }
973 
974 IMPL_LINK_NOARG(SdrObjEditView, ImpAfterCutOrPasteChainingEventHdl, LinkParamNone*, void)
975 {
976  SdrTextObj* pTextObj = GetTextEditObject();
977  if (!pTextObj)
978  return;
979  ImpChainingEventHdl();
980  TextChainCursorManager aCursorManager(this, pTextObj);
981  ImpMoveCursorAfterChainingEvent(&aCursorManager);
982 }
983 
985 {
986  if (!mxTextEditObj.is() || !pCursorManager)
987  return;
988 
989  SdrTextObj* pTextObj = mxTextEditObj.get();
990 
991  // Check if it has links to move it to
992  if (!pTextObj || !pTextObj->IsChainable())
993  return;
994 
995  TextChain* pTextChain = pTextObj->GetTextChain();
996  ESelection aNewSel = pTextChain->GetPostChainingSel(pTextObj);
997 
998  pCursorManager->HandleCursorEventAfterChaining(pTextChain->GetCursorEvent(pTextObj), aNewSel);
999 
1000  // Reset event
1001  pTextChain->SetCursorEvent(pTextObj, CursorChainingEvent::NULL_EVENT);
1002 }
1003 
1004 IMPL_LINK(SdrObjEditView, ImpOutlinerCalcFieldValueHdl, EditFieldInfo*, pFI, void)
1005 {
1006  bool bOk = false;
1007  OUString& rStr = pFI->GetRepresentation();
1008  rStr.clear();
1009  SdrTextObj* pTextObj = mxTextEditObj.get();
1010  if (pTextObj != nullptr)
1011  {
1012  o3tl::optional<Color> pTxtCol;
1013  o3tl::optional<Color> pFldCol;
1014  bOk = pTextObj->CalcFieldValue(pFI->GetField(), pFI->GetPara(), pFI->GetPos(), true,
1015  pTxtCol, pFldCol, rStr);
1016  if (bOk)
1017  {
1018  if (pTxtCol)
1019  {
1020  pFI->SetTextColor(*pTxtCol);
1021  }
1022  if (pFldCol)
1023  {
1024  pFI->SetFieldColor(*pFldCol);
1025  }
1026  else
1027  {
1028  pFI->SetFieldColor(COL_LIGHTGRAY); // TODO: remove this later on (357)
1029  }
1030  }
1031  }
1032  Outliner& rDrawOutl = mpModel->GetDrawOutliner(pTextObj);
1033  Link<EditFieldInfo*, void> aDrawOutlLink = rDrawOutl.GetCalcFieldValueHdl();
1034  if (!bOk && aDrawOutlLink.IsSet())
1035  {
1036  aDrawOutlLink.Call(pFI);
1037  bOk = !rStr.isEmpty();
1038  }
1039  if (!bOk)
1040  {
1041  aOldCalcFieldValueLink.Call(pFI);
1042  }
1043 }
1044 
1045 IMPL_LINK_NOARG(SdrObjEditView, EndTextEditHdl, SdrUndoManager*, void) { SdrEndTextEdit(); }
1046 
1048 {
1049  // default returns registered UndoManager
1050  return GetModel() ? dynamic_cast<SdrUndoManager*>(GetModel()->GetSdrUndoManager()) : nullptr;
1051 }
1052 
1054  bool bIsNewObj, SdrOutliner* pGivenOutliner,
1055  OutlinerView* pGivenOutlinerView, bool bDontDeleteOutliner,
1056  bool bOnlyOneView, bool bGrabFocus)
1057 {
1058  // FIXME cannot be an assert() yet, the code is not ready for that;
1059  // eg. press F7 in Impress when you are inside a text object with spelling
1060  // mistakes => boom; and it is unclear how to avoid that
1061  SAL_WARN_IF(IsTextEdit(), "svx", "SdrBeginTextEdit called when IsTextEdit() is already true.");
1062  // FIXME this encourages all sorts of bad habits and should be removed
1063  SdrEndTextEdit();
1064 
1065  SdrTextObj* pObj = dynamic_cast<SdrTextObj*>(pObj_);
1066  if (!pObj)
1067  return false; // currently only possible with text objects
1068 
1069  if (bGrabFocus && pWin)
1070  {
1071  // attention, this call may cause an EndTextEdit() call to this view
1072  pWin->GrabFocus(); // to force the cursor into the edit view
1073  }
1074 
1075  bTextEditDontDelete = bDontDeleteOutliner && pGivenOutliner != nullptr;
1076  bTextEditOnlyOneView = bOnlyOneView;
1077  bTextEditNewObj = bIsNewObj;
1078  const sal_uInt32 nWinCount(PaintWindowCount());
1079  sal_uInt32 i;
1080  bool bBrk(false);
1081 
1082  if (!pWin)
1083  {
1084  for (i = 0; i < nWinCount && !pWin; i++)
1085  {
1086  SdrPaintWindow* pPaintWindow = GetPaintWindow(i);
1087 
1088  if (OUTDEV_WINDOW == pPaintWindow->GetOutputDevice().GetOutDevType())
1089  {
1090  pWin = static_cast<vcl::Window*>(&pPaintWindow->GetOutputDevice());
1091  }
1092  }
1093 
1094  // break, when no window exists
1095  if (!pWin)
1096  {
1097  bBrk = true;
1098  }
1099  }
1100 
1101  if (!bBrk && !pPV)
1102  {
1103  pPV = GetSdrPageView();
1104 
1105  // break, when no PageView for the object exists
1106  if (!pPV)
1107  {
1108  bBrk = true;
1109  }
1110  }
1111 
1112  // no TextEdit on objects in locked Layer
1113  if (pPV && pPV->GetLockedLayers().IsSet(pObj->GetLayer()))
1114  {
1115  bBrk = true;
1116  }
1117 
1118  if (pTextEditOutliner)
1119  {
1120  OSL_FAIL("SdrObjEditView::SdrBeginTextEdit(): Old Outliner still exists.");
1121  pTextEditOutliner.reset();
1122  }
1123 
1124  if (!bBrk)
1125  {
1126  pTextEditWin = pWin;
1127  pTextEditPV = pPV;
1128  mxTextEditObj.reset(pObj);
1129  if (pGivenOutliner)
1130  {
1131  pTextEditOutliner.reset(pGivenOutliner);
1132  pGivenOutliner = nullptr; // so we don't delete it on the error path
1133  }
1134  else
1135  pTextEditOutliner = SdrMakeOutliner(OutlinerMode::TextObject,
1137 
1138  {
1139  SvtAccessibilityOptions aOptions;
1140  pTextEditOutliner->ForceAutoColor(aOptions.GetIsAutomaticFontColor());
1141  }
1142 
1143  aOldCalcFieldValueLink = pTextEditOutliner->GetCalcFieldValueHdl();
1144  // FieldHdl has to be set by SdrBeginTextEdit, because this call an UpdateFields
1145  pTextEditOutliner->SetCalcFieldValueHdl(
1146  LINK(this, SdrObjEditView, ImpOutlinerCalcFieldValueHdl));
1147  pTextEditOutliner->SetBeginPasteOrDropHdl(LINK(this, SdrObjEditView, BeginPasteOrDropHdl));
1148  pTextEditOutliner->SetEndPasteOrDropHdl(LINK(this, SdrObjEditView, EndPasteOrDropHdl));
1149 
1150  // It is just necessary to make the visualized page known. Set it.
1151  pTextEditOutliner->setVisualizedPage(pPV->GetPage());
1152 
1153  pTextEditOutliner->SetTextObjNoInit(mxTextEditObj.get());
1154 
1156  {
1157  SdrTextObj* pTextObj = mxTextEditObj.get();
1158  DBG_ASSERT(pTextObj, "svx::SdrObjEditView::BegTextEdit(), no text object?");
1159  if (!pTextObj)
1160  return false;
1161 
1162  // switch off any running TextAnimations
1163  pTextObj->SetTextAnimationAllowed(false);
1164 
1165  // remember old cursor
1166  if (pTextEditOutliner->GetViewCount() != 0)
1167  {
1168  pTextEditOutliner->RemoveView(static_cast<size_t>(0));
1169  }
1170 
1171  // Determine EditArea via TakeTextEditArea.
1172  // TODO: This could theoretically be left out, because TakeTextRect() calculates the aTextEditArea,
1173  // but aMinTextEditArea has to happen, too (therefore leaving this in right now)
1174  pTextObj->TakeTextEditArea(nullptr, nullptr, &aTextEditArea, &aMinTextEditArea);
1175 
1176  tools::Rectangle aTextRect;
1177  tools::Rectangle aAnchorRect;
1178  pTextObj->TakeTextRect(*pTextEditOutliner, aTextRect, true,
1179  &aAnchorRect /* Give true here, not false */);
1180 
1181  if (!pTextObj->IsContourTextFrame())
1182  {
1183  // FitToSize not together with ContourFrame, for now
1184  if (pTextObj->IsFitToSize())
1185  aTextRect = aAnchorRect;
1186  }
1187 
1188  aTextEditArea = aTextRect;
1189 
1190  // add possible GridOffset to up-to-now view-independent EditAreas
1191  basegfx::B2DVector aGridOffset(0.0, 0.0);
1192  if (getPossibleGridOffsetForSdrObject(aGridOffset, pTextObj, pPV))
1193  {
1194  const Point aOffset(basegfx::fround(aGridOffset.getX()),
1195  basegfx::fround(aGridOffset.getY()));
1196 
1197  aTextEditArea += aOffset;
1198  aMinTextEditArea += aOffset;
1199  }
1200 
1201  Point aPvOfs(pTextObj->GetTextEditOffset());
1202  aTextEditArea.Move(aPvOfs.X(), aPvOfs.Y());
1203  aMinTextEditArea.Move(aPvOfs.X(), aPvOfs.Y());
1204  pTextEditCursorBuffer = pWin->GetCursor();
1205 
1206  maHdlList.SetMoveOutside(true);
1207 
1208  // Since IsMarkHdlWhenTextEdit() is ignored, it is necessary
1209  // to call AdjustMarkHdl() always.
1210  AdjustMarkHdl();
1211 
1212  pTextEditOutlinerView = ImpMakeOutlinerView(pWin, pGivenOutlinerView);
1213 
1215  {
1216  // activate visualization of EditView on Overlay, suppress when
1217  // LibreOfficeKit is active
1219 
1220  const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
1221  const Color aHilightColor(aSvtOptionsDrawinglayer.getHilightColor());
1222  const SdrTextObj* pText = GetTextEditObject();
1223  const bool bTextFrame(pText && pText->IsTextFrame());
1224  const bool bFitToSize(pTextEditOutliner->GetControlWord()
1225  & EEControlBits::STRETCHING);
1226  const bool bVisualizeSurroundingFrame(bTextFrame && !bFitToSize);
1227  SdrPageView* pPageView = GetSdrPageView();
1228 
1229  if (pPageView)
1230  {
1231  for (sal_uInt32 b(0); b < pPageView->PageWindowCount(); b++)
1232  {
1233  const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1234 
1235  if (rPageWindow.GetPaintWindow().OutputToWindow())
1236  {
1238  = rPageWindow.GetOverlayManager();
1239  if (xManager.is())
1240  {
1241  std::unique_ptr<TextEditOverlayObject> pNewTextEditOverlayObject(
1242  new TextEditOverlayObject(aHilightColor, *pTextEditOutlinerView,
1243  bVisualizeSurroundingFrame));
1244 
1245  xManager->add(*pNewTextEditOverlayObject);
1246  xManager->add(const_cast<sdr::overlay::OverlaySelection&>(
1247  *pNewTextEditOverlayObject->getOverlaySelection()));
1248 
1249  maTEOverlayGroup.append(std::move(pNewTextEditOverlayObject));
1250  }
1251  }
1252  }
1253  }
1254  }
1255 
1256  // check if this view is already inserted
1257  sal_uIntPtr i2, nCount = pTextEditOutliner->GetViewCount();
1258  for (i2 = 0; i2 < nCount; i2++)
1259  {
1260  if (pTextEditOutliner->GetView(i2) == pTextEditOutlinerView)
1261  break;
1262  }
1263 
1264  if (i2 == nCount)
1265  pTextEditOutliner->InsertView(pTextEditOutlinerView, 0);
1266 
1267  maHdlList.SetMoveOutside(false);
1268  maHdlList.SetMoveOutside(true);
1269 
1270  // register all windows as OutlinerViews with the Outliner
1271  if (!bOnlyOneView)
1272  {
1273  for (i = 0; i < nWinCount; i++)
1274  {
1275  SdrPaintWindow* pPaintWindow = GetPaintWindow(i);
1276  OutputDevice& rOutDev = pPaintWindow->GetOutputDevice();
1277 
1278  if (&rOutDev != pWin && OUTDEV_WINDOW == rOutDev.GetOutDevType())
1279  {
1280  OutlinerView* pOutlView
1281  = ImpMakeOutlinerView(static_cast<vcl::Window*>(&rOutDev), nullptr);
1282  pTextEditOutliner->InsertView(pOutlView, static_cast<sal_uInt16>(i));
1283  }
1284  }
1285 
1287  {
1288  // Register an outliner view for all other sdr views that
1289  // show the same page, so that when the text edit changes,
1290  // all interested windows get an invalidation.
1291  SdrViewIter aIter(pObj->getSdrPageFromSdrObject());
1292  for (SdrView* pView = aIter.FirstView(); pView; pView = aIter.NextView())
1293  {
1294  if (pView == this)
1295  continue;
1296 
1297  for (sal_uInt32 nViewPaintWindow = 0;
1298  nViewPaintWindow < pView->PaintWindowCount(); ++nViewPaintWindow)
1299  {
1300  SdrPaintWindow* pPaintWindow = pView->GetPaintWindow(nViewPaintWindow);
1301  OutputDevice& rOutDev = pPaintWindow->GetOutputDevice();
1302 
1303  if (&rOutDev != pWin && OUTDEV_WINDOW == rOutDev.GetOutDevType())
1304  {
1305  OutlinerView* pOutlView = ImpMakeOutlinerView(
1306  static_cast<vcl::Window*>(&rOutDev), nullptr);
1307  pOutlView->HideCursor();
1308  static_cast<vcl::Window*>(&rOutDev)->SetCursor(nullptr);
1309  pTextEditOutliner->InsertView(pOutlView);
1310  }
1311  }
1312  }
1313  }
1314  }
1315 
1317  pTextEditOutliner->SetStatusEventHdl(
1318  LINK(this, SdrObjEditView, ImpOutlinerStatusEventHdl));
1319  if (pTextObj->IsChainable())
1320  {
1322  LINK(this, SdrObjEditView, ImpAfterCutOrPasteChainingEventHdl));
1323  }
1324 
1325  pTextEditOutliner->ClearModifyFlag();
1326 
1327  if (pTextObj->IsFitToSize())
1328  {
1329  pWin->Invalidate(aTextEditArea);
1330  }
1331 
1332  if (GetModel())
1333  {
1334  SdrHint aHint(SdrHintKind::BeginEdit, *pTextObj);
1335  GetModel()->Broadcast(aHint);
1336  }
1337 
1338  pTextEditOutliner->setVisualizedPage(nullptr);
1339 
1340  if (mxSelectionController.is())
1341  mxSelectionController->onSelectionHasChanged();
1342 
1343  if (GetModel() && IsUndoEnabled()
1344  && !GetModel()->GetDisableTextEditUsesCommonUndoManager())
1345  {
1347 
1348  if (pSdrUndoManager)
1349  {
1350  // we have an outliner, undo manager and it's an EditUndoManager, exchange
1351  // the document undo manager and the default one from the outliner and tell
1352  // it that text edit starts by setting a callback if it needs to end text edit mode.
1353  assert(nullptr == mpOldTextEditUndoManager);
1354 
1355  mpOldTextEditUndoManager = pTextEditOutliner->SetUndoManager(pSdrUndoManager);
1356  pSdrUndoManager->SetEndTextEditHdl(LINK(this, SdrObjEditView, EndTextEditHdl));
1357  }
1358  else
1359  {
1360  OSL_ENSURE(false,
1361  "The document undo manager is not derived from SdrUndoManager (!)");
1362  }
1363  }
1364 
1365  return true; // ran fine, let TextEdit run now
1366  }
1367  else
1368  {
1369  pTextEditOutliner->SetCalcFieldValueHdl(aOldCalcFieldValueLink);
1370  pTextEditOutliner->SetBeginPasteOrDropHdl(Link<PasteOrDropInfos*, void>());
1371  pTextEditOutliner->SetEndPasteOrDropHdl(Link<PasteOrDropInfos*, void>());
1372  }
1373  }
1374  if (pTextEditOutliner != nullptr)
1375  {
1376  pTextEditOutliner->setVisualizedPage(nullptr);
1377  }
1378 
1379  // something went wrong...
1380  if (!bDontDeleteOutliner)
1381  {
1382  delete pGivenOutliner;
1383  if (pGivenOutlinerView != nullptr)
1384  {
1385  delete pGivenOutlinerView;
1386  pGivenOutlinerView = nullptr;
1387  }
1388  }
1389  pTextEditOutliner.reset();
1390 
1391  pTextEditOutlinerView = nullptr;
1392  mxTextEditObj.reset(nullptr);
1393  pTextEditPV = nullptr;
1394  pTextEditWin = nullptr;
1395  maHdlList.SetMoveOutside(false);
1396 
1397  return false;
1398 }
1399 
1401 {
1403  SdrTextObj* pTEObj = mxTextEditObj.get();
1404  vcl::Window* pTEWin = pTextEditWin;
1405  OutlinerView* pTEOutlinerView = pTextEditOutlinerView;
1406  vcl::Cursor* pTECursorBuffer = pTextEditCursorBuffer;
1407  SdrUndoManager* pUndoEditUndoManager = nullptr;
1408  bool bNeedToUndoSavedRedoTextEdit(false);
1409 
1410  if (GetModel() && IsUndoEnabled() && pTEObj && pTextEditOutliner
1411  && !GetModel()->GetDisableTextEditUsesCommonUndoManager())
1412  {
1413  // change back the UndoManager to the remembered original one
1414  SfxUndoManager* pOriginal = pTextEditOutliner->SetUndoManager(mpOldTextEditUndoManager);
1415  mpOldTextEditUndoManager = nullptr;
1416 
1417  if (pOriginal)
1418  {
1419  // check if we got back our document undo manager
1421 
1422  if (pSdrUndoManager && dynamic_cast<SdrUndoManager*>(pOriginal) == pSdrUndoManager)
1423  {
1424  if (pSdrUndoManager->isEndTextEditTriggeredFromUndo())
1425  {
1426  // remember the UndoManager where missing Undos have to be triggered after end
1427  // text edit. When the undo had triggered the end text edit, the original action
1428  // which had to be undone originally is not yet undone.
1429  pUndoEditUndoManager = pSdrUndoManager;
1430 
1431  // We are ending text edit; if text edit was triggered from undo, execute all redos
1432  // to create a complete text change undo action for the redo buffer. Also mark this
1433  // state when at least one redo was executed; the created extra TextChange needs to
1434  // be undone in addition to the first real undo outside the text edit changes
1435  while (pSdrUndoManager->GetRedoActionCount())
1436  {
1437  bNeedToUndoSavedRedoTextEdit = true;
1438  pSdrUndoManager->Redo();
1439  }
1440  }
1441 
1442  // reset the callback link and let the undo manager cleanup all text edit
1443  // undo actions to get the stack back to the form before the text edit
1444  pSdrUndoManager->SetEndTextEditHdl(Link<SdrUndoManager*, void>());
1445  }
1446  else
1447  {
1448  OSL_ENSURE(false, "Got UndoManager back in SdrEndTextEdit which is NOT the "
1449  "expected document UndoManager (!)");
1450  delete pOriginal;
1451  }
1452  }
1453  }
1454  else
1455  {
1456  assert(nullptr == mpOldTextEditUndoManager); // cannot be restored!
1457  }
1458 
1459  if (GetModel() && mxTextEditObj.is())
1460  {
1462  GetModel()->Broadcast(aHint);
1463  }
1464 
1465  // if new mechanism was used, clean it up. At cleanup no need to check
1466  // for LibreOfficeKit
1468  {
1471  }
1472 
1473  mxTextEditObj.reset(nullptr);
1474  pTextEditPV = nullptr;
1475  pTextEditWin = nullptr;
1476  SdrOutliner* pTEOutliner = pTextEditOutliner.release();
1477  pTextEditOutlinerView = nullptr;
1478  pTextEditCursorBuffer = nullptr;
1480 
1481  if (pTEOutliner != nullptr)
1482  {
1483  bool bModified = pTEOutliner->IsModified();
1484  if (pTEOutlinerView != nullptr)
1485  {
1486  pTEOutlinerView->HideCursor();
1487  }
1488  if (pTEObj != nullptr)
1489  {
1490  pTEOutliner->CompleteOnlineSpelling();
1491 
1492  std::unique_ptr<SdrUndoObjSetText> pTxtUndo;
1493 
1494  if (bModified)
1495  {
1496  sal_Int32 nText;
1497  for (nText = 0; nText < pTEObj->getTextCount(); ++nText)
1498  if (pTEObj->getText(nText) == pTEObj->getActiveText())
1499  break;
1500 
1501  pTxtUndo.reset(
1502  dynamic_cast<SdrUndoObjSetText*>(GetModel()
1503  ->GetSdrUndoFactory()
1504  .CreateUndoObjectSetText(*pTEObj, nText)
1505  .release()));
1506  }
1507  DBG_ASSERT(!bModified || pTxtUndo,
1508  "svx::SdrObjEditView::EndTextEdit(), could not create undo action!");
1509  // Set old CalcFieldValue-Handler again, this
1510  // has to happen before Obj::EndTextEdit(), as this does UpdateFields().
1514 
1515  const bool bUndo = IsUndoEnabled();
1516  if (bUndo)
1517  {
1519  OUString aObjName(pTEObj->TakeObjNameSingul());
1520  BegUndo(SvxResId(STR_UndoObjSetText), aObjName);
1521  }
1522 
1523  pTEObj->EndTextEdit(*pTEOutliner);
1524 
1525  if ((pTEObj->GetRotateAngle() != 0)
1526  || (dynamic_cast<const SdrTextObj*>(pTEObj) != nullptr && pTEObj->IsFontwork()))
1527  {
1528  pTEObj->ActionChanged();
1529  }
1530 
1531  if (pTxtUndo != nullptr)
1532  {
1533  pTxtUndo->AfterSetText();
1534  if (!pTxtUndo->IsDifferent())
1535  {
1536  pTxtUndo.reset();
1537  }
1538  }
1539  // check deletion of entire TextObj
1540  std::unique_ptr<SdrUndoAction> pDelUndo;
1541  bool bDelObj = false;
1542  if (bTextEditNewObj)
1543  {
1544  bDelObj = pTEObj->IsTextFrame() && !pTEObj->HasText() && !pTEObj->IsEmptyPresObj()
1545  && !pTEObj->HasFill() && !pTEObj->HasLine();
1546 
1547  if (pTEObj->IsInserted() && bDelObj
1548  && pTEObj->GetObjInventor() == SdrInventor::Default && !bDontDeleteReally)
1549  {
1550  SdrObjKind eIdent = static_cast<SdrObjKind>(pTEObj->GetObjIdentifier());
1551  if (eIdent == OBJ_TEXT)
1552  {
1553  pDelUndo = GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pTEObj);
1554  }
1555  }
1556  }
1557  if (pTxtUndo)
1558  {
1559  if (bUndo)
1560  AddUndo(std::move(pTxtUndo));
1562  }
1563  if (pDelUndo != nullptr)
1564  {
1565  if (bUndo)
1566  {
1567  AddUndo(std::move(pDelUndo));
1568  }
1570  DBG_ASSERT(pTEObj->getParentSdrObjListFromSdrObject() != nullptr,
1571  "SdrObjEditView::SdrEndTextEdit(): Fatal: Object edited doesn't have an "
1572  "ObjList!");
1573  if (pTEObj->getParentSdrObjListFromSdrObject() != nullptr)
1574  {
1576  CheckMarked(); // remove selection immediately...
1577  }
1578  }
1579  else if (bDelObj)
1580  { // for Writer: the app has to do the deletion itself.
1582  }
1583 
1584  if (bUndo)
1585  EndUndo(); // EndUndo after Remove, in case UndoStack is deleted immediately
1586 
1587  // Switch on any TextAnimation again after TextEdit
1588  if (dynamic_cast<const SdrTextObj*>(pTEObj) != nullptr)
1589  {
1590  pTEObj->SetTextAnimationAllowed(true);
1591  }
1592 
1593  // Since IsMarkHdlWhenTextEdit() is ignored, it is necessary
1594  // to call AdjustMarkHdl() always.
1595  AdjustMarkHdl();
1596  }
1597  // delete all OutlinerViews
1598  for (sal_uIntPtr i = pTEOutliner->GetViewCount(); i > 0;)
1599  {
1600  i--;
1601  OutlinerView* pOLV = pTEOutliner->GetView(i);
1602  sal_uInt16 nMorePix = pOLV->GetInvalidateMore() + 10;
1603  vcl::Window* pWin = pOLV->GetWindow();
1604  tools::Rectangle aRect(pOLV->GetOutputArea());
1605  pTEOutliner->RemoveView(i);
1606  if (!bTextEditDontDelete || i != 0)
1607  {
1608  // may not own the zeroth one
1609  delete pOLV;
1610  }
1611  aRect.Union(aTextEditArea);
1612  aRect.Union(aMinTextEditArea);
1613  aRect = pWin->LogicToPixel(aRect);
1614  aRect.AdjustLeft(-nMorePix);
1615  aRect.AdjustTop(-nMorePix);
1616  aRect.AdjustRight(nMorePix);
1617  aRect.AdjustBottom(nMorePix);
1618  aRect = pWin->PixelToLogic(aRect);
1619  InvalidateOneWin(*pWin, aRect);
1620  pWin->SetFillColor();
1621  pWin->SetLineColor(COL_BLACK);
1622  }
1623  // and now the Outliner itself
1624  if (!bTextEditDontDelete)
1625  delete pTEOutliner;
1626  else
1627  pTEOutliner->Clear();
1628  if (pTEWin != nullptr)
1629  {
1630  pTEWin->SetCursor(pTECursorBuffer);
1631  }
1632  maHdlList.SetMoveOutside(false);
1633  if (eRet != SdrEndTextEditKind::Unchanged)
1634  {
1636  }
1637  }
1638 
1639  if (pTEObj && !pTEObj->getSdrModelFromSdrObject().isLocked() && pTEObj->GetBroadcaster())
1640  {
1641  SdrHint aHint(SdrHintKind::EndEdit, *pTEObj);
1642  const_cast<SfxBroadcaster*>(pTEObj->GetBroadcaster())->Broadcast(aHint);
1643  }
1644 
1645  if (pUndoEditUndoManager)
1646  {
1647  if (bNeedToUndoSavedRedoTextEdit)
1648  {
1649  // undo the text edit action since it was created as part of an EndTextEdit
1650  // callback from undo itself. This needs to be done after the call to
1651  // FmFormView::SdrEndTextEdit since it gets created there
1652  pUndoEditUndoManager->Undo();
1653  }
1654 
1655  // trigger the Undo which was not executed, but lead to this
1656  // end text edit
1657  pUndoEditUndoManager->Undo();
1658  }
1659 
1660  return eRet;
1661 }
1662 
1663 // info about TextEdit. Default is false.
1664 bool SdrObjEditView::IsTextEdit() const { return mxTextEditObj.is(); }
1665 
1666 // info about TextEditPageView. Default is 0L.
1668 
1670 {
1671  if (pWin == nullptr)
1672  return nullptr;
1673  if (pTextEditOutliner == nullptr)
1674  return nullptr;
1675  OutlinerView* pNewView = nullptr;
1676  sal_uIntPtr nWinCount = pTextEditOutliner->GetViewCount();
1677  for (sal_uIntPtr i = 0; i < nWinCount && pNewView == nullptr; i++)
1678  {
1679  OutlinerView* pView = pTextEditOutliner->GetView(i);
1680  if (pView->GetWindow() == pWin)
1681  pNewView = pView;
1682  }
1683  return pNewView;
1684 }
1685 
1687 {
1688  if (mxTextEditObj.is() && pWin != nullptr && pWin != pTextEditWin)
1689  {
1690  OutlinerView* pNewView = ImpFindOutlinerView(pWin);
1691  if (pNewView != nullptr && pNewView != pTextEditOutlinerView)
1692  {
1693  if (pTextEditOutlinerView != nullptr)
1694  {
1696  }
1697  pTextEditOutlinerView = pNewView;
1698  pTextEditWin = pWin;
1699  pWin->GrabFocus(); // Make the cursor blink here as well
1700  pNewView->ShowCursor();
1702  }
1703  }
1704 }
1705 
1706 bool SdrObjEditView::IsTextEditHit(const Point& rHit) const
1707 {
1708  bool bOk = false;
1709  if (mxTextEditObj.is())
1710  {
1711  tools::Rectangle aEditArea;
1712  OutlinerView* pOLV = pTextEditOutliner->GetView(0);
1713  if (pOLV != nullptr)
1714  {
1715  aEditArea.Union(pOLV->GetOutputArea());
1716  }
1717  bOk = aEditArea.IsInside(rHit);
1718  if (bOk)
1719  { // check if any characters were actually hit
1720  Point aPnt(rHit);
1721  aPnt -= aEditArea.TopLeft();
1722  long nHitTol = 2000;
1723  OutputDevice* pRef = pTextEditOutliner->GetRefDevice();
1724  if (pRef)
1725  nHitTol = OutputDevice::LogicToLogic(nHitTol, MapUnit::Map100thMM,
1726  pRef->GetMapMode().GetMapUnit());
1727 
1728  bOk = pTextEditOutliner->IsTextPos(aPnt, static_cast<sal_uInt16>(nHitTol));
1729  }
1730  }
1731  return bOk;
1732 }
1733 
1735 {
1736  bool bOk = false;
1737  if (mxTextEditObj.is())
1738  {
1739  SdrTextObj* pText = mxTextEditObj.get();
1740  OutlinerView* pOLV = pTextEditOutliner->GetView(0);
1741  if (pOLV)
1742  {
1743  vcl::Window* pWin = pOLV->GetWindow();
1744  if (pText != nullptr && pText->IsTextFrame() && pWin != nullptr)
1745  {
1746  sal_uInt16 nPixSiz = pOLV->GetInvalidateMore();
1748  aEditArea.Union(pOLV->GetOutputArea());
1749  if (!aEditArea.IsInside(rHit))
1750  {
1751  Size aSiz(pWin->PixelToLogic(Size(nPixSiz, nPixSiz)));
1752  aEditArea.AdjustLeft(-(aSiz.Width()));
1753  aEditArea.AdjustTop(-(aSiz.Height()));
1754  aEditArea.AdjustRight(aSiz.Width());
1755  aEditArea.AdjustBottom(aSiz.Height());
1756  bOk = aEditArea.IsInside(rHit);
1757  }
1758  }
1759  }
1760  }
1761  return bOk;
1762 }
1763 
1765  bool* bOutHandled)
1766 {
1767  *bOutHandled = false;
1768 
1769  SdrTextObj* pTextObj = mxTextEditObj.get();
1770  if (!pTextObj)
1771  return nullptr;
1772 
1773  if (!pTextObj->GetNextLinkInChain() && !pTextObj->GetPrevLinkInChain())
1774  return nullptr;
1775 
1776  TextChainCursorManager* pCursorManager = new TextChainCursorManager(this, pTextObj);
1777  if (pCursorManager->HandleKeyEvent(rKEvt))
1778  {
1779  // Possibly do other stuff here if necessary...
1780  // XXX: Careful with the checks below (in KeyInput) for pWin and co. You should do them here I guess.
1781  *bOutHandled = true;
1782  }
1783 
1784  return pCursorManager;
1785 }
1786 
1788 {
1790  {
1791  /* Start special handling of keys within a chain */
1792  // We possibly move to another box before any handling
1793  bool bHandled = false;
1794  std::unique_ptr<TextChainCursorManager> xCursorManager(
1795  ImpHandleMotionThroughBoxesKeyInput(rKEvt, &bHandled));
1796  if (bHandled)
1797  return true;
1798  /* End special handling of keys within a chain */
1799 
1800  if (pTextEditOutlinerView->PostKeyEvent(rKEvt, pWin))
1801  {
1802  if (mpModel)
1803  {
1804  if (pTextEditOutliner && pTextEditOutliner->IsModified())
1805  mpModel->SetChanged();
1806  }
1807 
1808  /* Start chaining processing */
1810  ImpMoveCursorAfterChainingEvent(xCursorManager.get());
1811  /* End chaining processing */
1812 
1813  if (pWin != nullptr && pWin != pTextEditWin)
1814  SetTextEditWin(pWin);
1816  return true;
1817  }
1818  }
1819  return SdrGlueEditView::KeyInput(rKEvt, pWin);
1820 }
1821 
1823 {
1824  if (pTextEditOutlinerView != nullptr)
1825  {
1826  bool bPostIt = pTextEditOutliner->IsInSelectionMode();
1827  if (!bPostIt)
1828  {
1829  Point aPt(rMEvt.GetPosPixel());
1830  if (pWin != nullptr)
1831  aPt = pWin->PixelToLogic(aPt);
1832  else if (pTextEditWin != nullptr)
1833  aPt = pTextEditWin->PixelToLogic(aPt);
1834  bPostIt = IsTextEditHit(aPt);
1835  }
1836  if (bPostIt)
1837  {
1838  Point aPixPos(rMEvt.GetPosPixel());
1839  if (pWin)
1840  {
1842  if (aPixPos.X() < aR.Left())
1843  aPixPos.setX(aR.Left());
1844  if (aPixPos.X() > aR.Right())
1845  aPixPos.setX(aR.Right());
1846  if (aPixPos.Y() < aR.Top())
1847  aPixPos.setY(aR.Top());
1848  if (aPixPos.Y() > aR.Bottom())
1849  aPixPos.setY(aR.Bottom());
1850  }
1851  MouseEvent aMEvt(aPixPos, rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(),
1852  rMEvt.GetModifier());
1854  {
1855  if (pWin != nullptr && pWin != pTextEditWin
1856  && pWin->GetOutDevType() == OUTDEV_WINDOW)
1857  SetTextEditWin(static_cast<vcl::Window*>(pWin));
1859  return true;
1860  }
1861  }
1862  }
1863  return SdrGlueEditView::MouseButtonDown(rMEvt, pWin);
1864 }
1865 
1867 {
1868  if (pTextEditOutlinerView != nullptr)
1869  {
1870  bool bPostIt = pTextEditOutliner->IsInSelectionMode();
1871  if (!bPostIt)
1872  {
1873  Point aPt(rMEvt.GetPosPixel());
1874  if (pWin != nullptr)
1875  aPt = pWin->PixelToLogic(aPt);
1876  else if (pTextEditWin != nullptr)
1877  aPt = pTextEditWin->PixelToLogic(aPt);
1878  bPostIt = IsTextEditHit(aPt);
1879  }
1880  if (bPostIt && pWin)
1881  {
1882  Point aPixPos(rMEvt.GetPosPixel());
1884  if (aPixPos.X() < aR.Left())
1885  aPixPos.setX(aR.Left());
1886  if (aPixPos.X() > aR.Right())
1887  aPixPos.setX(aR.Right());
1888  if (aPixPos.Y() < aR.Top())
1889  aPixPos.setY(aR.Top());
1890  if (aPixPos.Y() > aR.Bottom())
1891  aPixPos.setY(aR.Bottom());
1892  MouseEvent aMEvt(aPixPos, rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(),
1893  rMEvt.GetModifier());
1895  {
1897  return true;
1898  }
1899  }
1900  }
1901  return SdrGlueEditView::MouseButtonUp(rMEvt, pWin);
1902 }
1903 
1905 {
1906  if (pTextEditOutlinerView != nullptr)
1907  {
1908  bool bSelMode = pTextEditOutliner->IsInSelectionMode();
1909  bool bPostIt = bSelMode;
1910  if (!bPostIt)
1911  {
1912  Point aPt(rMEvt.GetPosPixel());
1913  if (pWin)
1914  aPt = pWin->PixelToLogic(aPt);
1915  else if (pTextEditWin)
1916  aPt = pTextEditWin->PixelToLogic(aPt);
1917  bPostIt = IsTextEditHit(aPt);
1918  }
1919  if (bPostIt)
1920  {
1921  Point aPixPos(rMEvt.GetPosPixel());
1923  if (pWin)
1924  aR = pWin->LogicToPixel(aR);
1925  else if (pTextEditWin)
1926  aR = pTextEditWin->LogicToPixel(aR);
1927  if (aPixPos.X() < aR.Left())
1928  aPixPos.setX(aR.Left());
1929  if (aPixPos.X() > aR.Right())
1930  aPixPos.setX(aR.Right());
1931  if (aPixPos.Y() < aR.Top())
1932  aPixPos.setY(aR.Top());
1933  if (aPixPos.Y() > aR.Bottom())
1934  aPixPos.setY(aR.Bottom());
1935  MouseEvent aMEvt(aPixPos, rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(),
1936  rMEvt.GetModifier());
1937  if (pTextEditOutlinerView->MouseMove(aMEvt) && bSelMode)
1938  {
1940  return true;
1941  }
1942  }
1943  }
1944  return SdrGlueEditView::MouseMove(rMEvt, pWin);
1945 }
1946 
1948 {
1949  // as long as OutlinerView returns a sal_Bool, it only gets CommandEventId::StartDrag
1950  if (pTextEditOutlinerView != nullptr)
1951  {
1952  if (rCEvt.GetCommand() == CommandEventId::StartDrag)
1953  {
1954  bool bPostIt = pTextEditOutliner->IsInSelectionMode() || !rCEvt.IsMouseEvent();
1955  if (!bPostIt && rCEvt.IsMouseEvent())
1956  {
1957  Point aPt(rCEvt.GetMousePosPixel());
1958  if (pWin != nullptr)
1959  aPt = pWin->PixelToLogic(aPt);
1960  else if (pTextEditWin != nullptr)
1961  aPt = pTextEditWin->PixelToLogic(aPt);
1962  bPostIt = IsTextEditHit(aPt);
1963  }
1964  if (bPostIt)
1965  {
1966  Point aPixPos(rCEvt.GetMousePosPixel());
1967  if (rCEvt.IsMouseEvent() && pWin)
1968  {
1970  if (aPixPos.X() < aR.Left())
1971  aPixPos.setX(aR.Left());
1972  if (aPixPos.X() > aR.Right())
1973  aPixPos.setX(aR.Right());
1974  if (aPixPos.Y() < aR.Top())
1975  aPixPos.setY(aR.Top());
1976  if (aPixPos.Y() > aR.Bottom())
1977  aPixPos.setY(aR.Bottom());
1978  }
1979  CommandEvent aCEvt(aPixPos, rCEvt.GetCommand(), rCEvt.IsMouseEvent());
1980  // Command is void at the OutlinerView, sadly
1982  if (pWin != nullptr && pWin != pTextEditWin)
1983  SetTextEditWin(pWin);
1985  return true;
1986  }
1987  }
1988  else
1989  {
1991  return true;
1992  }
1993  }
1994  return SdrGlueEditView::Command(rCEvt, pWin);
1995 }
1996 
1998 {
1999  bool bRet = false;
2000  if (pTextEditOutliner != nullptr && pTextEditOutlinerView != nullptr)
2001  {
2003  {
2004  const sal_Int32 nParaCnt = pTextEditOutliner->GetParagraphCount();
2005  Paragraph* pLastPara = pTextEditOutliner->GetParagraph(nParaCnt > 1 ? nParaCnt - 1 : 0);
2006 
2008  if (aESel.nStartPara == 0 && aESel.nStartPos == 0 && aESel.nEndPara == (nParaCnt - 1))
2009  {
2010  if (pTextEditOutliner->GetText(pLastPara).getLength() == aESel.nEndPos)
2011  bRet = true;
2012  }
2013  // in case the selection was done backwards
2014  if (!bRet && aESel.nEndPara == 0 && aESel.nEndPos == 0
2015  && aESel.nStartPara == (nParaCnt - 1))
2016  {
2017  if (pTextEditOutliner->GetText(pLastPara).getLength() == aESel.nStartPos)
2018  bRet = true;
2019  }
2020  }
2021  else
2022  {
2023  bRet = true;
2024  }
2025  }
2026  return bRet;
2027 }
2028 
2030 {
2031  if (pTextEditOutlinerView != nullptr && pTextEditWin != nullptr)
2032  {
2033  vcl::Cursor* pCsr = pTextEditWin->GetCursor();
2034  if (pCsr != nullptr)
2035  {
2036  Size aSiz(pCsr->GetSize());
2037  if (aSiz.Width() != 0 && aSiz.Height() != 0)
2038  {
2039  MakeVisible(tools::Rectangle(pCsr->GetPos(), aSiz), *pTextEditWin);
2040  }
2041  }
2042  }
2043 }
2044 
2046 {
2047  SvtScriptType nScriptType = SvtScriptType::NONE;
2048 
2049  if (IsTextEdit())
2050  {
2053 
2056  }
2057  else
2058  {
2059  const size_t nMarkCount(GetMarkedObjectCount());
2060 
2061  for (size_t i = 0; i < nMarkCount; ++i)
2062  {
2064 
2065  if (pParaObj)
2066  {
2067  nScriptType |= pParaObj->GetTextObject().GetScriptType();
2068  }
2069  }
2070  }
2071 
2072  if (nScriptType == SvtScriptType::NONE)
2073  nScriptType = SvtScriptType::LATIN;
2074 
2075  return nScriptType;
2076 }
2077 
2078 void SdrObjEditView::GetAttributes(SfxItemSet& rTargetSet, bool bOnlyHardAttr) const
2079 {
2080  if (mxSelectionController.is())
2081  if (mxSelectionController->GetAttributes(rTargetSet, bOnlyHardAttr))
2082  return;
2083 
2084  if (IsTextEdit())
2085  {
2086  DBG_ASSERT(pTextEditOutlinerView != nullptr,
2087  "SdrObjEditView::GetAttributes(): pTextEditOutlinerView=NULL");
2088  DBG_ASSERT(pTextEditOutliner != nullptr,
2089  "SdrObjEditView::GetAttributes(): pTextEditOutliner=NULL");
2090 
2091  // take care of bOnlyHardAttr(!)
2092  if (!bOnlyHardAttr && mxTextEditObj->GetStyleSheet())
2093  rTargetSet.Put(mxTextEditObj->GetStyleSheet()->GetItemSet());
2094 
2095  // add object attributes
2096  rTargetSet.Put(mxTextEditObj->GetMergedItemSet());
2097 
2099  {
2100  // FALSE= regard InvalidItems as "holes," not as Default
2101  rTargetSet.Put(pTextEditOutlinerView->GetAttribs(), false);
2102  }
2103 
2105  {
2106  MergeNotPersistAttrFromMarked(rTargetSet);
2107  }
2108  }
2109  else
2110  {
2111  SdrGlueEditView::GetAttributes(rTargetSet, bOnlyHardAttr);
2112  }
2113 }
2114 
2115 bool SdrObjEditView::SetAttributes(const SfxItemSet& rSet, bool bReplaceAll)
2116 {
2117  bool bRet = false;
2118  bool bTextEdit = pTextEditOutlinerView != nullptr && mxTextEditObj.is();
2119  bool bAllTextSelected = ImpIsTextEditAllSelected();
2120  const SfxItemSet* pSet = &rSet;
2121 
2122  if (!bTextEdit)
2123  {
2124  // no TextEdit active -> all Items to drawing object
2125  if (mxSelectionController.is())
2126  bRet = mxSelectionController->SetAttributes(*pSet, bReplaceAll);
2127 
2128  if (!bRet)
2129  {
2130  SdrGlueEditView::SetAttributes(*pSet, bReplaceAll);
2131  bRet = true;
2132  }
2133  }
2134  else
2135  {
2136 #ifdef DBG_UTIL
2137  {
2138  bool bHasEEFeatureItems = false;
2139  SfxItemIter aIter(rSet);
2140  for (const SfxPoolItem* pItem = aIter.GetCurItem(); !bHasEEFeatureItems && pItem;
2141  pItem = aIter.NextItem())
2142  {
2143  if (!IsInvalidItem(pItem))
2144  {
2145  sal_uInt16 nW = pItem->Which();
2146  if (nW >= EE_FEATURE_START && nW <= EE_FEATURE_END)
2147  bHasEEFeatureItems = true;
2148  }
2149  }
2150 
2151  if (bHasEEFeatureItems)
2152  {
2153  const OUString aMessage("SdrObjEditView::SetAttributes(): Setting EE_FEATURE items "
2154  "at the SdrView does not make sense! It only leads to "
2155  "overhead and unreadable documents.");
2156  std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(
2157  nullptr, VclMessageType::Info, VclButtonsType::Ok, aMessage));
2158  xInfoBox->run();
2159  }
2160  }
2161 #endif
2162 
2163  bool bOnlyEEItems;
2164  bool bNoEEItems = !SearchOutlinerItems(*pSet, bReplaceAll, &bOnlyEEItems);
2165  // everything selected? -> attributes to the border, too
2166  // if no EEItems, attributes to the border only
2167  if (bAllTextSelected || bNoEEItems)
2168  {
2169  if (mxSelectionController.is())
2170  bRet = mxSelectionController->SetAttributes(*pSet, bReplaceAll);
2171 
2172  if (!bRet)
2173  {
2174  const bool bUndo = IsUndoEnabled();
2175 
2176  if (bUndo)
2177  {
2178  BegUndo(ImpGetDescriptionString(STR_EditSetAttributes));
2179  AddUndo(
2180  GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*mxTextEditObj.get()));
2181 
2182  // If this is a text object also rescue the OutlinerParaObject since
2183  // applying attributes to the object may change text layout when
2184  // multiple portions exist with multiple formats. If an OutlinerParaObject
2185  // really exists and needs to be rescued is evaluated in the undo
2186  // implementation itself.
2187  bool bRescueText = mxTextEditObj.get();
2188 
2189  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(
2190  *mxTextEditObj.get(), false, !bNoEEItems || bRescueText));
2191  EndUndo();
2192  }
2193 
2194  mxTextEditObj->SetMergedItemSetAndBroadcast(*pSet, bReplaceAll);
2195 
2196  FlushComeBackTimer(); // to set ModeHasChanged immediately
2197  }
2198  }
2199  else if (!bOnlyEEItems)
2200  {
2201  // Otherwise split Set, if necessary.
2202  // Now we build an ItemSet aSet that doesn't contain EE_Items from
2203  // *pSet (otherwise it would be a copy).
2204  std::unique_ptr<sal_uInt16[]> pNewWhichTable
2206  SfxItemSet aSet(mpModel->GetItemPool(), pNewWhichTable.get());
2207  pNewWhichTable.reset();
2208  SfxWhichIter aIter(aSet);
2209  sal_uInt16 nWhich = aIter.FirstWhich();
2210  while (nWhich != 0)
2211  {
2212  const SfxPoolItem* pItem;
2213  SfxItemState eState = pSet->GetItemState(nWhich, false, &pItem);
2214  if (eState == SfxItemState::SET)
2215  aSet.Put(*pItem);
2216  nWhich = aIter.NextWhich();
2217  }
2218 
2219  if (mxSelectionController.is())
2220  bRet = mxSelectionController->SetAttributes(aSet, bReplaceAll);
2221 
2222  if (!bRet)
2223  {
2224  if (IsUndoEnabled())
2225  {
2226  BegUndo(ImpGetDescriptionString(STR_EditSetAttributes));
2227  AddUndo(
2228  GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*mxTextEditObj.get()));
2229  AddUndo(
2230  GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*mxTextEditObj.get()));
2231  EndUndo();
2232  }
2233 
2234  mxTextEditObj->SetMergedItemSetAndBroadcast(aSet, bReplaceAll);
2235 
2237  {
2239  }
2240  }
2242  }
2243  if (!bNoEEItems)
2244  {
2245  // and now the attributes to the EditEngine
2246  if (bReplaceAll)
2247  {
2249  }
2251 
2252  Outliner* pTEOutliner = pTextEditOutlinerView->GetOutliner();
2253  if (mpModel && pTEOutliner && pTEOutliner->IsModified())
2254  mpModel->SetChanged();
2255 
2257  }
2258  bRet = true;
2259  }
2260  return bRet;
2261 }
2262 
2264 {
2265  SfxStyleSheet* pSheet = nullptr;
2266 
2267  if (mxSelectionController.is())
2268  {
2269  if (mxSelectionController->GetStyleSheet(pSheet))
2270  return pSheet;
2271  }
2272 
2274  {
2276  }
2277  else
2278  {
2279  pSheet = SdrGlueEditView::GetStyleSheet();
2280  }
2281  return pSheet;
2282 }
2283 
2284 void SdrObjEditView::SetStyleSheet(SfxStyleSheet* pStyleSheet, bool bDontRemoveHardAttr)
2285 {
2286  if (mxSelectionController.is())
2287  {
2288  if (mxSelectionController->SetStyleSheet(pStyleSheet, bDontRemoveHardAttr))
2289  return;
2290  }
2291 
2292  // if we are currently in edit mode we must also set the stylesheet
2293  // on all paragraphs in the Outliner for the edit view
2294  if (nullptr != pTextEditOutlinerView)
2295  {
2296  Outliner* pOutliner = pTextEditOutlinerView->GetOutliner();
2297 
2298  const sal_Int32 nParaCount = pOutliner->GetParagraphCount();
2299  for (sal_Int32 nPara = 0; nPara < nParaCount; nPara++)
2300  {
2301  pOutliner->SetStyleSheet(nPara, pStyleSheet);
2302  }
2303  }
2304 
2305  SdrGlueEditView::SetStyleSheet(pStyleSheet, bDontRemoveHardAttr);
2306 }
2307 
2309 {
2310  SdrGlueEditView::AddWindowToPaintView(pNewWin, pWindow);
2311 
2313  {
2314  OutlinerView* pOutlView = ImpMakeOutlinerView(static_cast<vcl::Window*>(pNewWin), nullptr);
2315  pTextEditOutliner->InsertView(pOutlView);
2316  }
2317 }
2318 
2320 {
2322 
2324  {
2325  for (sal_uIntPtr i = pTextEditOutliner->GetViewCount(); i > 0;)
2326  {
2327  i--;
2328  OutlinerView* pOLV = pTextEditOutliner->GetView(i);
2329  if (pOLV && pOLV->GetWindow() == static_cast<vcl::Window*>(pOldWin))
2330  {
2331  pTextEditOutliner->RemoveView(i);
2332  }
2333  }
2334  }
2335 
2336  lcl_RemoveTextEditOutlinerViews(this, GetSdrPageView(), pOldWin);
2337 }
2338 
2340 {
2341  return pTextEditOutliner != nullptr && pTextEditOutliner->IsInSelectionMode();
2342 }
2343 
2344 // MacroMode
2345 
2346 void SdrObjEditView::BegMacroObj(const Point& rPnt, short nTol, SdrObject* pObj, SdrPageView* pPV,
2347  vcl::Window* pWin)
2348 {
2349  BrkMacroObj();
2350  if (pObj != nullptr && pPV != nullptr && pWin != nullptr && pObj->HasMacro())
2351  {
2352  nTol = ImpGetHitTolLogic(nTol, nullptr);
2353  pMacroObj = pObj;
2354  pMacroPV = pPV;
2355  pMacroWin = pWin;
2356  bMacroDown = false;
2357  nMacroTol = sal_uInt16(nTol);
2358  aMacroDownPos = rPnt;
2359  MovMacroObj(rPnt);
2360  }
2361 }
2362 
2364 {
2365  if (pMacroObj != nullptr && bMacroDown)
2366  {
2367  SdrObjMacroHitRec aHitRec;
2368  aHitRec.aPos = rUpPos;
2369  aHitRec.nTol = nMacroTol;
2370  aHitRec.pVisiLayer = &pMacroPV->GetVisibleLayers();
2371  aHitRec.pPageView = pMacroPV;
2373  bMacroDown = false;
2374  }
2375 }
2376 
2378 {
2379  if (pMacroObj != nullptr && !bMacroDown)
2380  {
2381  SdrObjMacroHitRec aHitRec;
2382  aHitRec.aPos = rDownPos;
2383  aHitRec.nTol = nMacroTol;
2384  aHitRec.pVisiLayer = &pMacroPV->GetVisibleLayers();
2385  aHitRec.pPageView = pMacroPV;
2387  bMacroDown = true;
2388  }
2389 }
2390 
2392 {
2393  if (pMacroObj != nullptr)
2394  {
2395  SdrObjMacroHitRec aHitRec;
2396  aHitRec.aPos = rPnt;
2397  aHitRec.nTol = nMacroTol;
2398  aHitRec.pVisiLayer = &pMacroPV->GetVisibleLayers();
2399  aHitRec.pPageView = pMacroPV;
2400  bool bDown = pMacroObj->IsMacroHit(aHitRec);
2401  if (bDown)
2402  ImpMacroDown(rPnt);
2403  else
2404  ImpMacroUp(rPnt);
2405  }
2406 }
2407 
2409 {
2410  if (pMacroObj != nullptr)
2411  {
2413  pMacroObj = nullptr;
2414  pMacroPV = nullptr;
2415  pMacroWin = nullptr;
2416  }
2417 }
2418 
2420 {
2421  if (pMacroObj != nullptr && bMacroDown)
2422  {
2424  SdrObjMacroHitRec aHitRec;
2425  aHitRec.aPos = aMacroDownPos;
2426  aHitRec.nTol = nMacroTol;
2427  aHitRec.pVisiLayer = &pMacroPV->GetVisibleLayers();
2428  aHitRec.pPageView = pMacroPV;
2429  bool bRet = pMacroObj->DoMacro(aHitRec);
2430  pMacroObj = nullptr;
2431  pMacroPV = nullptr;
2432  pMacroWin = nullptr;
2433  return bRet;
2434  }
2435  else
2436  {
2437  BrkMacroObj();
2438  return false;
2439  }
2440 }
2441 
2444 void SdrObjEditView::getTextSelection(css::uno::Any& rSelection)
2445 {
2446  if (IsTextEdit())
2447  {
2448  OutlinerView* pOutlinerView = GetTextEditOutlinerView();
2449  if (pOutlinerView && pOutlinerView->HasSelection())
2450  {
2451  SdrObject* pObj = GetTextEditObject();
2452 
2453  if (pObj)
2454  {
2455  css::uno::Reference<css::text::XText> xText(pObj->getUnoShape(),
2456  css::uno::UNO_QUERY);
2457  if (xText.is())
2458  {
2459  SvxUnoTextBase* pRange
2460  = comphelper::getUnoTunnelImplementation<SvxUnoTextBase>(xText);
2461  if (pRange)
2462  {
2463  rSelection
2464  <<= pRange->createTextCursorBySelection(pOutlinerView->GetSelection());
2465  }
2466  }
2467  }
2468  }
2469  }
2470 }
2471 
2472 /* check if we have a single selection and that single object likes
2473  to handle the mouse and keyboard events itself
2474 
2475  TODO: the selection controller should be queried from the
2476  object specific view contact. Currently this method only
2477  works for tables.
2478 */
2480 {
2482 
2483  if (mxSelectionController.is())
2484  {
2486  mxSelectionController->onSelectionHasChanged();
2487  }
2488 
2489  mxSelectionController.clear();
2490 
2491  const SdrMarkList& rMarkList = GetMarkedObjectList();
2492  if (rMarkList.GetMarkCount() == 1)
2493  {
2494  const SdrObject* pObj(rMarkList.GetMark(0)->GetMarkedSdrObj());
2495  SdrView* pView(dynamic_cast<SdrView*>(this));
2496 
2497  // check for table
2498  if (pObj && pView && (pObj->GetObjInventor() == SdrInventor::Default)
2499  && (pObj->GetObjIdentifier() == OBJ_TABLE))
2500  {
2502  *pView, static_cast<const sdr::table::SdrTableObj&>(*pObj),
2504 
2505  if (mxSelectionController.is())
2506  {
2507  mxLastSelectionController.clear();
2508  mxSelectionController->onSelectionHasChanged();
2509  }
2510  }
2511  }
2512 }
2513 
2514 IMPL_LINK(SdrObjEditView, EndPasteOrDropHdl, PasteOrDropInfos*, pInfo, void)
2515 {
2516  OnEndPasteOrDrop(pInfo);
2517 }
2518 
2519 IMPL_LINK(SdrObjEditView, BeginPasteOrDropHdl, PasteOrDropInfos*, pInfo, void)
2520 {
2521  OnBeginPasteOrDrop(pInfo);
2522 }
2523 
2525 {
2526  // applications can derive from these virtual methods to do something before a drop or paste operation
2527 }
2528 
2530 {
2531  // applications can derive from these virtual methods to do something before a drop or paste operation
2532 }
2533 
2535 {
2536  sal_uInt16 nLevel = 0xFFFF;
2537  if (IsTextEdit())
2538  {
2539  DBG_ASSERT(pTextEditOutlinerView != nullptr,
2540  "SdrObjEditView::GetAttributes(): pTextEditOutlinerView=NULL");
2541  DBG_ASSERT(pTextEditOutliner != nullptr,
2542  "SdrObjEditView::GetAttributes(): pTextEditOutliner=NULL");
2544  {
2545  //start and end position
2547  sal_uInt16 nStartPara = ::std::min(aSelect.nStartPara, aSelect.nEndPara);
2548  sal_uInt16 nEndPara = ::std::max(aSelect.nStartPara, aSelect.nEndPara);
2549  //get level from each paragraph
2550  nLevel = 0;
2551  for (sal_uInt16 nPara = nStartPara; nPara <= nEndPara; nPara++)
2552  {
2553  sal_uInt16 nParaDepth
2554  = 1 << static_cast<sal_uInt16>(pTextEditOutliner->GetDepth(nPara));
2555  if (!(nLevel & nParaDepth))
2556  nLevel += nParaDepth;
2557  }
2558  //reduce one level for Outliner Object
2559  //if( nLevel > 0 && GetTextEditObject()->GetObjIdentifier() == OBJ_OUTLINETEXT )
2560  // nLevel = nLevel >> 1;
2561  //no bullet paragraph selected
2562  if (nLevel == 0)
2563  nLevel = 0xFFFF;
2564  }
2565  }
2566  return nLevel;
2567 }
2568 
2570  sal_uInt16 nObjectIdentifier)
2571 {
2572  if (nObjectInventor != SdrInventor::Default && nObjectInventor != SdrInventor::E3d)
2573  return false;
2574  switch (nObjectIdentifier)
2575  {
2576  case OBJ_NONE:
2577  case OBJ_GRUP:
2578  return false;
2579  case OBJ_LINE:
2580  case OBJ_RECT:
2581  case OBJ_CIRC:
2582  case OBJ_SECT:
2583  case OBJ_CARC:
2584  case OBJ_CCUT:
2585  case OBJ_POLY:
2586  case OBJ_PLIN:
2587  case OBJ_PATHLINE:
2588  case OBJ_PATHFILL:
2589  case OBJ_FREELINE:
2590  case OBJ_FREEFILL:
2591  case OBJ_SPLNLINE:
2592  case OBJ_SPLNFILL:
2593  case OBJ_TEXT:
2594  case OBJ_TITLETEXT:
2595  case OBJ_OUTLINETEXT:
2596  case OBJ_GRAF:
2597  case OBJ_OLE2:
2598  case OBJ_TABLE:
2599  return true;
2600  case OBJ_EDGE:
2601  case OBJ_CAPTION:
2602  return false;
2603  case OBJ_PATHPOLY:
2604  case OBJ_PATHPLIN:
2605  return true;
2606  case OBJ_PAGE:
2607  case OBJ_MEASURE:
2608  case OBJ_FRAME:
2609  case OBJ_UNO:
2610  return false;
2611  case OBJ_CUSTOMSHAPE:
2612  return true;
2613  default:
2614  return false;
2615  }
2616 }
2617 
2618 static const sal_uInt16* GetFormatRangeImpl(bool bTextOnly)
2619 {
2620  static const sal_uInt16 gRanges[] = { SDRATTR_SHADOW_FIRST,
2629  XATTRSET_FILL,
2630  EE_PARA_START,
2631  EE_PARA_END, // text-only from here on
2632  EE_CHAR_START,
2633  EE_CHAR_END,
2635  SDRATTR_MISC_LAST, // table cell formats
2636  0,
2637  0 };
2638  return &gRanges[bTextOnly ? 10 : 0];
2639 }
2640 
2641 void SdrObjEditView::TakeFormatPaintBrush(std::shared_ptr<SfxItemSet>& rFormatSet)
2642 {
2643  const SdrMarkList& rMarkList = GetMarkedObjectList();
2644  if (rMarkList.GetMarkCount() > 0)
2645  {
2647 
2648  rFormatSet.reset(
2649  new SfxItemSet(GetModel()->GetItemPool(), GetFormatRangeImpl(pOLV != nullptr)));
2650  if (pOLV)
2651  {
2652  rFormatSet->Put(pOLV->GetAttribs());
2653  }
2654  else
2655  {
2656  const bool bOnlyHardAttr = false;
2657  rFormatSet->Put(GetAttrFromMarked(bOnlyHardAttr));
2658  }
2659 
2660  // check for cloning from table cell, in which case we need to copy cell-specific formatting attributes
2661  const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
2662  if (pObj && (pObj->GetObjInventor() == SdrInventor::Default)
2663  && (pObj->GetObjIdentifier() == OBJ_TABLE))
2664  {
2665  auto pTable = static_cast<const sdr::table::SdrTableObj*>(pObj);
2666  if (mxSelectionController.is() && pTable->getActiveCell().is())
2667  {
2668  mxSelectionController->GetAttributes(*rFormatSet, false);
2669  }
2670  }
2671  }
2672 }
2673 
2674 static SfxItemSet CreatePaintSet(const sal_uInt16* pRanges, SfxItemPool& rPool,
2675  const SfxItemSet& rSourceSet, const SfxItemSet& rTargetSet,
2676  bool bNoCharacterFormats, bool bNoParagraphFormats)
2677 {
2678  SfxItemSet aPaintSet(rPool, pRanges);
2679 
2680  while (*pRanges)
2681  {
2682  sal_uInt16 nWhich = *pRanges++;
2683  const sal_uInt16 nLastWhich = *pRanges++;
2684 
2685  if (bNoCharacterFormats && (nWhich == EE_CHAR_START))
2686  continue;
2687 
2688  if (bNoParagraphFormats && (nWhich == EE_PARA_START))
2689  continue;
2690 
2691  for (; nWhich < nLastWhich; nWhich++)
2692  {
2693  const SfxPoolItem* pSourceItem = rSourceSet.GetItem(nWhich);
2694  const SfxPoolItem* pTargetItem = rTargetSet.GetItem(nWhich);
2695 
2696  if ((pSourceItem && !pTargetItem)
2697  || (pSourceItem && pTargetItem && *pSourceItem != *pTargetItem))
2698  {
2699  aPaintSet.Put(*pSourceItem);
2700  }
2701  }
2702  }
2703  return aPaintSet;
2704 }
2705 
2707  SdrText* pText, bool bNoCharacterFormats,
2708  bool bNoParagraphFormats)
2709 {
2710  OutlinerParaObject* pParaObj = pText ? pText->GetOutlinerParaObject() : nullptr;
2711  if (pParaObj)
2712  {
2713  SdrOutliner& rOutliner = rTextObj.ImpGetDrawOutliner();
2714  rOutliner.SetText(*pParaObj);
2715 
2716  sal_Int32 nParaCount(rOutliner.GetParagraphCount());
2717 
2718  if (nParaCount)
2719  {
2720  for (sal_Int32 nPara = 0; nPara < nParaCount; nPara++)
2721  {
2722  if (!bNoCharacterFormats)
2723  rOutliner.RemoveCharAttribs(nPara);
2724 
2725  SfxItemSet aSet(rOutliner.GetParaAttribs(nPara));
2726  aSet.Put(CreatePaintSet(GetFormatRangeImpl(true), *aSet.GetPool(), rFormatSet, aSet,
2727  bNoCharacterFormats, bNoParagraphFormats));
2728  rOutliner.SetParaAttribs(nPara, aSet);
2729  }
2730 
2731  std::unique_ptr<OutlinerParaObject> pTemp = rOutliner.CreateParaObject(0, nParaCount);
2732  rOutliner.Clear();
2733 
2734  rTextObj.NbcSetOutlinerParaObjectForText(std::move(pTemp), pText);
2735  }
2736  }
2737 }
2738 
2739 void SdrObjEditView::ApplyFormatPaintBrush(SfxItemSet& rFormatSet, bool bNoCharacterFormats,
2740  bool bNoParagraphFormats)
2741 {
2742  if (mxSelectionController.is()
2743  && mxSelectionController->ApplyFormatPaintBrush(rFormatSet, bNoCharacterFormats,
2744  bNoParagraphFormats))
2745  {
2746  return;
2747  }
2748 
2750  const SdrMarkList& rMarkList = GetMarkedObjectList();
2751  if (!pOLV)
2752  {
2753  SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
2754  const SfxItemSet& rShapeSet = pObj->GetMergedItemSet();
2755 
2756  // if not in text edit mode (aka the user selected text or clicked on a word)
2757  // apply formatting attributes to selected shape
2758  // All formatting items (see ranges above) that are unequal in selected shape and
2759  // the format paintbrush are hard set on the selected shape.
2760 
2761  const sal_uInt16* pRanges = rFormatSet.GetRanges();
2762  bool bTextOnly = true;
2763 
2764  while (*pRanges)
2765  {
2766  if ((*pRanges != EE_PARA_START) && (*pRanges != EE_CHAR_START))
2767  {
2768  bTextOnly = false;
2769  break;
2770  }
2771  pRanges += 2;
2772  }
2773 
2774  if (!bTextOnly)
2775  {
2776  SfxItemSet aPaintSet(CreatePaintSet(GetFormatRangeImpl(false), *rShapeSet.GetPool(),
2777  rFormatSet, rShapeSet, bNoCharacterFormats,
2778  bNoParagraphFormats));
2779  SetAttrToMarked(aPaintSet, false /*bReplaceAll*/);
2780  }
2781 
2782  // now apply character and paragraph formatting to text, if the shape has any
2783  SdrTextObj* pTextObj = dynamic_cast<SdrTextObj*>(pObj);
2784  if (pTextObj)
2785  {
2786  sal_Int32 nText = pTextObj->getTextCount();
2787 
2788  while (--nText >= 0)
2789  {
2790  SdrText* pText = pTextObj->getText(nText);
2791  ApplyFormatPaintBrushToText(rFormatSet, *pTextObj, pText, bNoCharacterFormats,
2792  bNoParagraphFormats);
2793  }
2794  }
2795  }
2796  else
2797  {
2798  ::Outliner* pOutliner = pOLV->GetOutliner();
2799  if (pOutliner)
2800  {
2801  const EditEngine& rEditEngine = pOutliner->GetEditEngine();
2802 
2803  ESelection aSel(pOLV->GetSelection());
2804  if (!aSel.HasRange())
2805  pOLV->SetSelection(rEditEngine.GetWord(aSel, css::i18n::WordType::DICTIONARY_WORD));
2806 
2807  const bool bRemoveParaAttribs = !bNoParagraphFormats;
2808  pOLV->RemoveAttribsKeepLanguages(bRemoveParaAttribs);
2809  SfxItemSet aSet(pOLV->GetAttribs());
2810  SfxItemSet aPaintSet(CreatePaintSet(GetFormatRangeImpl(true), *aSet.GetPool(),
2811  rFormatSet, aSet, bNoCharacterFormats,
2812  bNoParagraphFormats));
2813  pOLV->SetAttribs(aPaintSet);
2814  }
2815  }
2816 
2817  // check for cloning to table cell, in which case we need to copy cell-specific formatting attributes
2818  SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
2819  if (pObj && (pObj->GetObjInventor() == SdrInventor::Default)
2820  && (pObj->GetObjIdentifier() == OBJ_TABLE))
2821  {
2822  auto pTable = static_cast<sdr::table::SdrTableObj*>(pObj);
2823  if (pTable->getActiveCell().is() && mxSelectionController.is())
2824  {
2825  mxSelectionController->SetAttributes(rFormatSet, false);
2826  }
2827  }
2828 }
2829 
2830 /* 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:2339
bool IsMacroHit(const SdrObjMacroHitRec &rRec) const
Definition: svdobj.cxx:1826
void ImpPaintOutlinerView(OutlinerView &rOutlView, const tools::Rectangle &rRect, OutputDevice &rTargetDevice) const
Definition: svdedxv.cxx:723
virtual void OnEndPasteOrDrop(PasteOrDropInfos *pInfo)
Definition: svdedxv.cxx:2529
#define EE_FEATURE_END
TextChainCursorManager * ImpHandleMotionThroughBoxesKeyInput(const KeyEvent &rKEvt, bool *bOutHandled)
Definition: svdedxv.cxx:1764
#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:2319
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:1400
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:1924
void GetAttributes(SfxItemSet &rTargetSet, bool bOnlyHardAttr) const
Definition: svdedtv1.cxx:1325
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:2057
virtual void DeleteWindowFromPaintView(OutputDevice *pOldWin)
Definition: svdpntv.cxx:411
SfxStyleSheet * GetStyleSheet() const
Definition: svdedxv.cxx:2263
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:2029
void ImpChainingEventHdl()
Definition: svdedxv.cxx:905
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:2674
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:2618
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:929
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:1904
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:1669
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:2479
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:1866
virtual long GetRotateAngle() const override
Definition: svdotxtr.cxx:88
bool IsEmpty() const
TextChain * GetTextChain() const
Definition: svdotext.cxx:1485
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:1055
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:1734
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:2706
void TextEditDrawing(SdrPaintWindow &rPaintWindow) const
Definition: svdedxv.cxx:673
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:1858
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:2346
virtual SvtScriptType GetScriptType() const
Definition: svdedxv.cxx:2045
virtual void SetChanged(bool bFlg=true)
Definition: svdmodel.cxx:1274
SfxStyleSheet * GetStyleSheet() const
Definition: svdedtv1.cxx:1346
void SetAttributes(const SfxItemSet &rSet, bool bReplaceAll)
Definition: svdedtv1.cxx:1337
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:974
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:217
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:2444
bool IsFitToSize() const
returns true if the old feature for fitting shape content should into shape is enabled. implies IsAutoFit()==false!
Definition: svdotext.cxx:1841
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:837
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:2569
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:1787
void CompleteOnlineSpelling()
bool IsTextEditHit(const Point &rHit) const
Definition: svdedxv.cxx:1706
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:1053
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:654
bool ImpIsTextEditAllSelected() const
Definition: svdedxv.cxx:1997
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:2048
virtual drawinglayer::primitive2d::Primitive2DContainer getOverlayObjectPrimitive2DSequence() const
#define SDRATTR_GRAF_FIRST
Definition: svddef.hxx:307
void ImpInvalidateOutlinerView(OutlinerView const &rOutlView) const
Definition: svdedxv.cxx:784
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:1744
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:2419
#define SDRATTR_GRAF_LAST
Definition: svddef.hxx:318
void ImpMacroDown(const Point &rDownPos)
Definition: svdedxv.cxx:2377
virtual bool MouseButtonDown(const MouseEvent &rMEvt, OutputDevice *pWin) override
Definition: svdedxv.cxx:1822
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:1977
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:221
sal_uInt16 GetSelectionLevel() const
Definition: svdedxv.cxx:2534
void MovMacroObj(const Point &rPnt)
Definition: svdedxv.cxx:2391
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:1047
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)
void SetSelection(const ESelection &)
void SetStyleSheet(SfxStyleSheet *pStyleSheet, bool bDontRemoveHardAttr)
Definition: svdedtv1.cxx:1355
OverlayObject & getOverlayObject(sal_uInt32 nIndex) const
void ImpMoveCursorAfterChainingEvent(TextChainCursorManager *pCursorManager)
Definition: svdedxv.cxx:984
bool HasFill() const
Definition: svdoattr.cxx:132
#define EE_CHAR_START
SfxItemState
virtual bool IsTextEdit() const final override
Definition: svdedxv.cxx:1664
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:1667
virtual OutlinerParaObject * GetOutlinerParaObject() const override
Definition: svdotext.cxx:1362
SdrPage * GetPage() const
Definition: svdpagv.hxx:173
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:1376
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:1947
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:630
void AdjustMarkHdl(SfxViewShell *pOtherShell=nullptr)
Definition: svdmrkv.cxx:2343
SdrPaintWindow & GetPaintWindow() const
void SetTextEditWin(vcl::Window *pWin)
Definition: svdedxv.cxx:1686
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:1947
void SetOutputArea(const tools::Rectangle &rRect)
css::uno::Reference< css::graphic::XPrimitive2D > Primitive2DReference
virtual void AddWindowToPaintView(OutputDevice *pNewWin, vcl::Window *pWindow) override
Definition: svdedxv.cxx:2308
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:2115
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:2072
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:2284
virtual void OnBeginPasteOrDrop(PasteOrDropInfos *pInfo)
Definition: svdedxv.cxx:2524
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:2739
bool bQuickTextEditMode
Definition: svdedxv.hxx:99
void ImpMacroUp(const Point &rUpPos)
Definition: svdedxv.cxx:2363
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
void GetAttributes(SfxItemSet &rTargetSet, bool bOnlyHardAttr) const
Definition: svdedxv.cxx:2078
#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:893
void BrkMacroObj()
Definition: svdedxv.cxx:2408
virtual void HideSdrPage() override
Definition: svdmrkv.cxx:331
SdrMarkList & GetMarkedObjectListWriteAccess()
Definition: svdmrkv.hxx:239
SdrTextObj * GetPrevLinkInChain() const
Definition: svdotext.cxx:2015
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:1152
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:1732
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:1848
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:2641
sal_uInt32 PageWindowCount() const
Definition: svdpagv.hxx:96
virtual OutputDevice & EditViewOutputDevice() const override
Definition: svdedxv.cxx:671
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)