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