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  {
1984  {
1985  // It could execute CommandEventId::ExtTextInput, while SdrObjEditView::KeyInput
1986  // isn't called
1987  if (pTextEditOutliner && pTextEditOutliner->IsModified())
1988  mpModel->SetChanged();
1989  }
1990  return true;
1991  }
1992  }
1993  return SdrGlueEditView::Command(rCEvt, pWin);
1994 }
1995 
1997 {
1998  bool bRet = false;
1999  if (pTextEditOutliner != nullptr && pTextEditOutlinerView != nullptr)
2000  {
2002  {
2003  const sal_Int32 nParaCnt = pTextEditOutliner->GetParagraphCount();
2004  Paragraph* pLastPara = pTextEditOutliner->GetParagraph(nParaCnt > 1 ? nParaCnt - 1 : 0);
2005 
2007  if (aESel.nStartPara == 0 && aESel.nStartPos == 0 && aESel.nEndPara == (nParaCnt - 1))
2008  {
2009  if (pTextEditOutliner->GetText(pLastPara).getLength() == aESel.nEndPos)
2010  bRet = true;
2011  }
2012  // in case the selection was done backwards
2013  if (!bRet && aESel.nEndPara == 0 && aESel.nEndPos == 0
2014  && aESel.nStartPara == (nParaCnt - 1))
2015  {
2016  if (pTextEditOutliner->GetText(pLastPara).getLength() == aESel.nStartPos)
2017  bRet = true;
2018  }
2019  }
2020  else
2021  {
2022  bRet = true;
2023  }
2024  }
2025  return bRet;
2026 }
2027 
2029 {
2030  if (pTextEditOutlinerView != nullptr && pTextEditWin != nullptr)
2031  {
2032  vcl::Cursor* pCsr = pTextEditWin->GetCursor();
2033  if (pCsr != nullptr)
2034  {
2035  Size aSiz(pCsr->GetSize());
2036  if (!aSiz.IsEmpty())
2037  {
2038  MakeVisible(tools::Rectangle(pCsr->GetPos(), aSiz), *pTextEditWin);
2039  }
2040  }
2041  }
2042 }
2043 
2045 {
2046  SvtScriptType nScriptType = SvtScriptType::NONE;
2047 
2048  if (IsTextEdit())
2049  {
2052 
2055  }
2056  else
2057  {
2058  const size_t nMarkCount(GetMarkedObjectCount());
2059 
2060  for (size_t i = 0; i < nMarkCount; ++i)
2061  {
2063 
2064  if (pParaObj)
2065  {
2066  nScriptType |= pParaObj->GetTextObject().GetScriptType();
2067  }
2068  }
2069  }
2070 
2071  if (nScriptType == SvtScriptType::NONE)
2072  nScriptType = SvtScriptType::LATIN;
2073 
2074  return nScriptType;
2075 }
2076 
2077 void SdrObjEditView::GetAttributes(SfxItemSet& rTargetSet, bool bOnlyHardAttr) const
2078 {
2079  if (mxSelectionController.is())
2080  if (mxSelectionController->GetAttributes(rTargetSet, bOnlyHardAttr))
2081  return;
2082 
2083  if (IsTextEdit())
2084  {
2085  DBG_ASSERT(pTextEditOutlinerView != nullptr,
2086  "SdrObjEditView::GetAttributes(): pTextEditOutlinerView=NULL");
2087  DBG_ASSERT(pTextEditOutliner != nullptr,
2088  "SdrObjEditView::GetAttributes(): pTextEditOutliner=NULL");
2089 
2090  // take care of bOnlyHardAttr(!)
2091  if (!bOnlyHardAttr && mxTextEditObj->GetStyleSheet())
2092  rTargetSet.Put(mxTextEditObj->GetStyleSheet()->GetItemSet());
2093 
2094  // add object attributes
2095  rTargetSet.Put(mxTextEditObj->GetMergedItemSet());
2096 
2098  {
2099  // FALSE= regard InvalidItems as "holes," not as Default
2100  rTargetSet.Put(pTextEditOutlinerView->GetAttribs(), false);
2101  }
2102 
2104  {
2105  MergeNotPersistAttrFromMarked(rTargetSet);
2106  }
2107  }
2108  else
2109  {
2110  SdrGlueEditView::GetAttributes(rTargetSet, bOnlyHardAttr);
2111  }
2112 }
2113 
2114 bool SdrObjEditView::SetAttributes(const SfxItemSet& rSet, bool bReplaceAll)
2115 {
2116  bool bRet = false;
2117  bool bTextEdit = pTextEditOutlinerView != nullptr && mxTextEditObj.is();
2118  bool bAllTextSelected = ImpIsTextEditAllSelected();
2119  const SfxItemSet* pSet = &rSet;
2120 
2121  if (!bTextEdit)
2122  {
2123  // no TextEdit active -> all Items to drawing object
2124  if (mxSelectionController.is())
2125  bRet = mxSelectionController->SetAttributes(*pSet, bReplaceAll);
2126 
2127  if (!bRet)
2128  {
2129  SdrGlueEditView::SetAttributes(*pSet, bReplaceAll);
2130  bRet = true;
2131  }
2132  }
2133  else
2134  {
2135 #ifdef DBG_UTIL
2136  {
2137  bool bHasEEFeatureItems = false;
2138  SfxItemIter aIter(rSet);
2139  for (const SfxPoolItem* pItem = aIter.GetCurItem(); !bHasEEFeatureItems && pItem;
2140  pItem = aIter.NextItem())
2141  {
2142  if (!IsInvalidItem(pItem))
2143  {
2144  sal_uInt16 nW = pItem->Which();
2145  if (nW >= EE_FEATURE_START && nW <= EE_FEATURE_END)
2146  bHasEEFeatureItems = true;
2147  }
2148  }
2149 
2150  if (bHasEEFeatureItems)
2151  {
2152  std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(
2153  nullptr, VclMessageType::Info, VclButtonsType::Ok,
2154  "SdrObjEditView::SetAttributes(): Setting EE_FEATURE items "
2155  "at the SdrView does not make sense! It only leads to "
2156  "overhead and unreadable documents."));
2157  xInfoBox->run();
2158  }
2159  }
2160 #endif
2161 
2162  bool bOnlyEEItems;
2163  bool bNoEEItems = !SearchOutlinerItems(*pSet, bReplaceAll, &bOnlyEEItems);
2164  // everything selected? -> attributes to the border, too
2165  // if no EEItems, attributes to the border only
2166  if (bAllTextSelected || bNoEEItems)
2167  {
2168  if (mxSelectionController.is())
2169  bRet = mxSelectionController->SetAttributes(*pSet, bReplaceAll);
2170 
2171  if (!bRet)
2172  {
2173  const bool bUndo = IsUndoEnabled();
2174 
2175  if (bUndo)
2176  {
2177  BegUndo(ImpGetDescriptionString(STR_EditSetAttributes));
2178  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*mxTextEditObj));
2179 
2180  // If this is a text object also rescue the OutlinerParaObject since
2181  // applying attributes to the object may change text layout when
2182  // multiple portions exist with multiple formats. If an OutlinerParaObject
2183  // really exists and needs to be rescued is evaluated in the undo
2184  // implementation itself.
2185  bool bRescueText = mxTextEditObj;
2186 
2187  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(
2188  *mxTextEditObj, false, !bNoEEItems || bRescueText));
2189  EndUndo();
2190  }
2191 
2192  mxTextEditObj->SetMergedItemSetAndBroadcast(*pSet, bReplaceAll);
2193 
2194  FlushComeBackTimer(); // to set ModeHasChanged immediately
2195  }
2196  }
2197  else if (!bOnlyEEItems)
2198  {
2199  // Otherwise split Set, if necessary.
2200  // Now we build an ItemSet aSet that doesn't contain EE_Items from
2201  // *pSet (otherwise it would be a copy).
2202  std::unique_ptr<sal_uInt16[]> pNewWhichTable
2204  SfxItemSet aSet(mpModel->GetItemPool(), pNewWhichTable.get());
2205  pNewWhichTable.reset();
2206  SfxWhichIter aIter(aSet);
2207  sal_uInt16 nWhich = aIter.FirstWhich();
2208  while (nWhich != 0)
2209  {
2210  const SfxPoolItem* pItem;
2211  SfxItemState eState = pSet->GetItemState(nWhich, false, &pItem);
2212  if (eState == SfxItemState::SET)
2213  aSet.Put(*pItem);
2214  nWhich = aIter.NextWhich();
2215  }
2216 
2217  if (mxSelectionController.is())
2218  bRet = mxSelectionController->SetAttributes(aSet, bReplaceAll);
2219 
2220  if (!bRet)
2221  {
2222  if (IsUndoEnabled())
2223  {
2224  BegUndo(ImpGetDescriptionString(STR_EditSetAttributes));
2225  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*mxTextEditObj));
2226  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*mxTextEditObj));
2227  EndUndo();
2228  }
2229 
2230  mxTextEditObj->SetMergedItemSetAndBroadcast(aSet, bReplaceAll);
2231 
2233  {
2235  }
2236  }
2238  }
2239  if (!bNoEEItems)
2240  {
2241  // and now the attributes to the EditEngine
2242  if (bReplaceAll)
2243  {
2245  }
2247 
2248  Outliner* pTEOutliner = pTextEditOutlinerView->GetOutliner();
2249  if (mpModel && pTEOutliner && pTEOutliner->IsModified())
2250  mpModel->SetChanged();
2251 
2253  }
2254  bRet = true;
2255  }
2256  return bRet;
2257 }
2258 
2260 {
2261  SfxStyleSheet* pSheet = nullptr;
2262 
2263  if (mxSelectionController.is())
2264  {
2265  if (mxSelectionController->GetStyleSheet(pSheet))
2266  return pSheet;
2267  }
2268 
2270  {
2272  }
2273  else
2274  {
2275  pSheet = SdrGlueEditView::GetStyleSheet();
2276  }
2277  return pSheet;
2278 }
2279 
2280 void SdrObjEditView::SetStyleSheet(SfxStyleSheet* pStyleSheet, bool bDontRemoveHardAttr)
2281 {
2282  if (mxSelectionController.is())
2283  {
2284  if (mxSelectionController->SetStyleSheet(pStyleSheet, bDontRemoveHardAttr))
2285  return;
2286  }
2287 
2288  // if we are currently in edit mode we must also set the stylesheet
2289  // on all paragraphs in the Outliner for the edit view
2290  if (nullptr != pTextEditOutlinerView)
2291  {
2292  Outliner* pOutliner = pTextEditOutlinerView->GetOutliner();
2293 
2294  const sal_Int32 nParaCount = pOutliner->GetParagraphCount();
2295  for (sal_Int32 nPara = 0; nPara < nParaCount; nPara++)
2296  {
2297  pOutliner->SetStyleSheet(nPara, pStyleSheet);
2298  }
2299  }
2300 
2301  SdrGlueEditView::SetStyleSheet(pStyleSheet, bDontRemoveHardAttr);
2302 }
2303 
2305 {
2306  SdrGlueEditView::AddWindowToPaintView(pNewWin, pWindow);
2307 
2309  {
2310  OutlinerView* pOutlView = ImpMakeOutlinerView(static_cast<vcl::Window*>(pNewWin), nullptr);
2311  pTextEditOutliner->InsertView(pOutlView);
2312  }
2313 }
2314 
2316 {
2318 
2320  {
2321  for (size_t i = pTextEditOutliner->GetViewCount(); i > 0;)
2322  {
2323  i--;
2324  OutlinerView* pOLV = pTextEditOutliner->GetView(i);
2325  if (pOLV && pOLV->GetWindow() == static_cast<vcl::Window*>(pOldWin))
2326  {
2327  pTextEditOutliner->RemoveView(i);
2328  }
2329  }
2330  }
2331 
2332  lcl_RemoveTextEditOutlinerViews(this, GetSdrPageView(), pOldWin);
2333 }
2334 
2336 {
2337  return pTextEditOutliner != nullptr && pTextEditOutliner->IsInSelectionMode();
2338 }
2339 
2340 // MacroMode
2341 
2342 void SdrObjEditView::BegMacroObj(const Point& rPnt, short nTol, SdrObject* pObj, SdrPageView* pPV,
2343  vcl::Window* pWin)
2344 {
2345  BrkMacroObj();
2346  if (pObj != nullptr && pPV != nullptr && pWin != nullptr && pObj->HasMacro())
2347  {
2348  nTol = ImpGetHitTolLogic(nTol, nullptr);
2349  pMacroObj = pObj;
2350  pMacroPV = pPV;
2351  pMacroWin = pWin;
2352  bMacroDown = false;
2353  nMacroTol = sal_uInt16(nTol);
2354  aMacroDownPos = rPnt;
2355  MovMacroObj(rPnt);
2356  }
2357 }
2358 
2359 void SdrObjEditView::ImpMacroUp(const Point& rUpPos)
2360 {
2361  if (pMacroObj != nullptr && bMacroDown)
2362  {
2363  SdrObjMacroHitRec aHitRec;
2364  aHitRec.aPos = rUpPos;
2365  aHitRec.nTol = nMacroTol;
2366  aHitRec.pVisiLayer = &pMacroPV->GetVisibleLayers();
2367  aHitRec.pPageView = pMacroPV;
2369  bMacroDown = false;
2370  }
2371 }
2372 
2373 void SdrObjEditView::ImpMacroDown(const Point& rDownPos)
2374 {
2375  if (pMacroObj != nullptr && !bMacroDown)
2376  {
2377  SdrObjMacroHitRec aHitRec;
2378  aHitRec.aPos = rDownPos;
2379  aHitRec.nTol = nMacroTol;
2380  aHitRec.pVisiLayer = &pMacroPV->GetVisibleLayers();
2381  aHitRec.pPageView = pMacroPV;
2383  bMacroDown = true;
2384  }
2385 }
2386 
2387 void SdrObjEditView::MovMacroObj(const Point& rPnt)
2388 {
2389  if (pMacroObj != nullptr)
2390  {
2391  SdrObjMacroHitRec aHitRec;
2392  aHitRec.aPos = rPnt;
2393  aHitRec.nTol = nMacroTol;
2394  aHitRec.pVisiLayer = &pMacroPV->GetVisibleLayers();
2395  aHitRec.pPageView = pMacroPV;
2396  bool bDown = pMacroObj->IsMacroHit(aHitRec);
2397  if (bDown)
2398  ImpMacroDown(rPnt);
2399  else
2400  ImpMacroUp(rPnt);
2401  }
2402 }
2403 
2405 {
2406  if (pMacroObj != nullptr)
2407  {
2409  pMacroObj = nullptr;
2410  pMacroPV = nullptr;
2411  pMacroWin = nullptr;
2412  }
2413 }
2414 
2416 {
2417  if (pMacroObj != nullptr && bMacroDown)
2418  {
2420  SdrObjMacroHitRec aHitRec;
2421  aHitRec.aPos = aMacroDownPos;
2422  aHitRec.nTol = nMacroTol;
2423  aHitRec.pVisiLayer = &pMacroPV->GetVisibleLayers();
2424  aHitRec.pPageView = pMacroPV;
2425  bool bRet = pMacroObj->DoMacro(aHitRec);
2426  pMacroObj = nullptr;
2427  pMacroPV = nullptr;
2428  pMacroWin = nullptr;
2429  return bRet;
2430  }
2431  else
2432  {
2433  BrkMacroObj();
2434  return false;
2435  }
2436 }
2437 
2440 void SdrObjEditView::getTextSelection(css::uno::Any& rSelection)
2441 {
2442  if (IsTextEdit())
2443  {
2444  OutlinerView* pOutlinerView = GetTextEditOutlinerView();
2445  if (pOutlinerView && pOutlinerView->HasSelection())
2446  {
2447  SdrObject* pObj = GetTextEditObject();
2448 
2449  if (pObj)
2450  {
2451  css::uno::Reference<css::text::XText> xText(pObj->getUnoShape(),
2452  css::uno::UNO_QUERY);
2453  if (xText.is())
2454  {
2455  SvxUnoTextBase* pRange
2456  = comphelper::getUnoTunnelImplementation<SvxUnoTextBase>(xText);
2457  if (pRange)
2458  {
2459  rSelection
2460  <<= pRange->createTextCursorBySelection(pOutlinerView->GetSelection());
2461  }
2462  }
2463  }
2464  }
2465  }
2466 }
2467 
2468 /* check if we have a single selection and that single object likes
2469  to handle the mouse and keyboard events itself
2470 
2471  TODO: the selection controller should be queried from the
2472  object specific view contact. Currently this method only
2473  works for tables.
2474 */
2476 {
2478 
2479  if (mxSelectionController.is())
2480  {
2482  mxSelectionController->onSelectionHasChanged();
2483  }
2484 
2485  mxSelectionController.clear();
2486 
2487  const SdrMarkList& rMarkList = GetMarkedObjectList();
2488  if (rMarkList.GetMarkCount() == 1)
2489  {
2490  const SdrObject* pObj(rMarkList.GetMark(0)->GetMarkedSdrObj());
2491  SdrView* pView(dynamic_cast<SdrView*>(this));
2492 
2493  // check for table
2494  if (pObj && pView && (pObj->GetObjInventor() == SdrInventor::Default)
2495  && (pObj->GetObjIdentifier() == OBJ_TABLE))
2496  {
2498  *pView, static_cast<const sdr::table::SdrTableObj&>(*pObj),
2500 
2501  if (mxSelectionController.is())
2502  {
2503  mxLastSelectionController.clear();
2504  mxSelectionController->onSelectionHasChanged();
2505  }
2506  }
2507  }
2508 }
2509 
2510 IMPL_LINK(SdrObjEditView, EndPasteOrDropHdl, PasteOrDropInfos*, pInfo, void)
2511 {
2512  OnEndPasteOrDrop(pInfo);
2513 }
2514 
2515 IMPL_LINK(SdrObjEditView, BeginPasteOrDropHdl, PasteOrDropInfos*, pInfo, void)
2516 {
2517  OnBeginPasteOrDrop(pInfo);
2518 }
2519 
2521 {
2522  // applications can derive from these virtual methods to do something before a drop or paste operation
2523 }
2524 
2526 {
2527  // applications can derive from these virtual methods to do something before a drop or paste operation
2528 }
2529 
2531 {
2532  sal_uInt16 nLevel = 0xFFFF;
2533  if (IsTextEdit())
2534  {
2535  DBG_ASSERT(pTextEditOutlinerView != nullptr,
2536  "SdrObjEditView::GetAttributes(): pTextEditOutlinerView=NULL");
2537  DBG_ASSERT(pTextEditOutliner != nullptr,
2538  "SdrObjEditView::GetAttributes(): pTextEditOutliner=NULL");
2540  {
2541  //start and end position
2543  sal_uInt16 nStartPara = ::std::min(aSelect.nStartPara, aSelect.nEndPara);
2544  sal_uInt16 nEndPara = ::std::max(aSelect.nStartPara, aSelect.nEndPara);
2545  //get level from each paragraph
2546  nLevel = 0;
2547  for (sal_uInt16 nPara = nStartPara; nPara <= nEndPara; nPara++)
2548  {
2549  sal_uInt16 nParaDepth
2550  = 1 << static_cast<sal_uInt16>(pTextEditOutliner->GetDepth(nPara));
2551  if (!(nLevel & nParaDepth))
2552  nLevel += nParaDepth;
2553  }
2554  //reduce one level for Outliner Object
2555  //if( nLevel > 0 && GetTextEditObject()->GetObjIdentifier() == OBJ_OUTLINETEXT )
2556  // nLevel = nLevel >> 1;
2557  //no bullet paragraph selected
2558  if (nLevel == 0)
2559  nLevel = 0xFFFF;
2560  }
2561  }
2562  return nLevel;
2563 }
2564 
2566  sal_uInt16 nObjectIdentifier)
2567 {
2568  if (nObjectInventor != SdrInventor::Default && nObjectInventor != SdrInventor::E3d)
2569  return false;
2570  switch (nObjectIdentifier)
2571  {
2572  case OBJ_NONE:
2573  case OBJ_GRUP:
2574  return false;
2575  case OBJ_LINE:
2576  case OBJ_RECT:
2577  case OBJ_CIRC:
2578  case OBJ_SECT:
2579  case OBJ_CARC:
2580  case OBJ_CCUT:
2581  case OBJ_POLY:
2582  case OBJ_PLIN:
2583  case OBJ_PATHLINE:
2584  case OBJ_PATHFILL:
2585  case OBJ_FREELINE:
2586  case OBJ_FREEFILL:
2587  case OBJ_SPLNLINE:
2588  case OBJ_SPLNFILL:
2589  case OBJ_TEXT:
2590  case OBJ_TITLETEXT:
2591  case OBJ_OUTLINETEXT:
2592  case OBJ_GRAF:
2593  case OBJ_OLE2:
2594  case OBJ_TABLE:
2595  return true;
2596  case OBJ_EDGE:
2597  case OBJ_CAPTION:
2598  return false;
2599  case OBJ_PATHPOLY:
2600  case OBJ_PATHPLIN:
2601  return true;
2602  case OBJ_PAGE:
2603  case OBJ_MEASURE:
2604  case OBJ_FRAME:
2605  case OBJ_UNO:
2606  return false;
2607  case OBJ_CUSTOMSHAPE:
2608  return true;
2609  default:
2610  return false;
2611  }
2612 }
2613 
2614 static const sal_uInt16* GetFormatRangeImpl(bool bTextOnly)
2615 {
2616  static const sal_uInt16 gRanges[] = { SDRATTR_SHADOW_FIRST,
2625  XATTRSET_FILL,
2626  EE_PARA_START,
2627  EE_PARA_END, // text-only from here on
2628  EE_CHAR_START,
2629  EE_CHAR_END,
2631  SDRATTR_MISC_LAST, // table cell formats
2632  0,
2633  0 };
2634  return &gRanges[bTextOnly ? 10 : 0];
2635 }
2636 
2637 void SdrObjEditView::TakeFormatPaintBrush(std::shared_ptr<SfxItemSet>& rFormatSet)
2638 {
2639  const SdrMarkList& rMarkList = GetMarkedObjectList();
2640  if (rMarkList.GetMarkCount() > 0)
2641  {
2643 
2644  rFormatSet = std::make_shared<SfxItemSet>(GetModel()->GetItemPool(),
2645  GetFormatRangeImpl(pOLV != nullptr));
2646  if (pOLV)
2647  {
2648  rFormatSet->Put(pOLV->GetAttribs());
2649  }
2650  else
2651  {
2652  const bool bOnlyHardAttr = false;
2653  rFormatSet->Put(GetAttrFromMarked(bOnlyHardAttr));
2654  }
2655 
2656  // check for cloning from table cell, in which case we need to copy cell-specific formatting attributes
2657  const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
2658  if (pObj && (pObj->GetObjInventor() == SdrInventor::Default)
2659  && (pObj->GetObjIdentifier() == OBJ_TABLE))
2660  {
2661  auto pTable = static_cast<const sdr::table::SdrTableObj*>(pObj);
2662  if (mxSelectionController.is() && pTable->getActiveCell().is())
2663  {
2664  mxSelectionController->GetAttributes(*rFormatSet, false);
2665  }
2666  }
2667  }
2668 }
2669 
2670 static SfxItemSet CreatePaintSet(const sal_uInt16* pRanges, SfxItemPool& rPool,
2671  const SfxItemSet& rSourceSet, const SfxItemSet& rTargetSet,
2672  bool bNoCharacterFormats, bool bNoParagraphFormats)
2673 {
2674  SfxItemSet aPaintSet(rPool, pRanges);
2675 
2676  while (*pRanges)
2677  {
2678  sal_uInt16 nWhich = *pRanges++;
2679  const sal_uInt16 nLastWhich = *pRanges++;
2680 
2681  if (bNoCharacterFormats && (nWhich == EE_CHAR_START))
2682  continue;
2683 
2684  if (bNoParagraphFormats && (nWhich == EE_PARA_START))
2685  continue;
2686 
2687  for (; nWhich < nLastWhich; nWhich++)
2688  {
2689  const SfxPoolItem* pSourceItem = rSourceSet.GetItem(nWhich);
2690  const SfxPoolItem* pTargetItem = rTargetSet.GetItem(nWhich);
2691 
2692  if ((pSourceItem && !pTargetItem)
2693  || (pSourceItem && pTargetItem && *pSourceItem != *pTargetItem))
2694  {
2695  aPaintSet.Put(*pSourceItem);
2696  }
2697  }
2698  }
2699  return aPaintSet;
2700 }
2701 
2703  SdrText* pText, bool bNoCharacterFormats,
2704  bool bNoParagraphFormats)
2705 {
2706  OutlinerParaObject* pParaObj = pText ? pText->GetOutlinerParaObject() : nullptr;
2707  if (pParaObj)
2708  {
2709  SdrOutliner& rOutliner = rTextObj.ImpGetDrawOutliner();
2710  rOutliner.SetText(*pParaObj);
2711 
2712  sal_Int32 nParaCount(rOutliner.GetParagraphCount());
2713 
2714  if (nParaCount)
2715  {
2716  for (sal_Int32 nPara = 0; nPara < nParaCount; nPara++)
2717  {
2718  if (!bNoCharacterFormats)
2719  rOutliner.RemoveCharAttribs(nPara);
2720 
2721  SfxItemSet aSet(rOutliner.GetParaAttribs(nPara));
2722  aSet.Put(CreatePaintSet(GetFormatRangeImpl(true), *aSet.GetPool(), rFormatSet, aSet,
2723  bNoCharacterFormats, bNoParagraphFormats));
2724  rOutliner.SetParaAttribs(nPara, aSet);
2725  }
2726 
2727  std::unique_ptr<OutlinerParaObject> pTemp = rOutliner.CreateParaObject(0, nParaCount);
2728  rOutliner.Clear();
2729 
2730  rTextObj.NbcSetOutlinerParaObjectForText(std::move(pTemp), pText);
2731  }
2732  }
2733 }
2734 
2735 void SdrObjEditView::ApplyFormatPaintBrush(SfxItemSet& rFormatSet, bool bNoCharacterFormats,
2736  bool bNoParagraphFormats)
2737 {
2738  if (mxSelectionController.is()
2739  && mxSelectionController->ApplyFormatPaintBrush(rFormatSet, bNoCharacterFormats,
2740  bNoParagraphFormats))
2741  {
2742  return;
2743  }
2744 
2746  const SdrMarkList& rMarkList = GetMarkedObjectList();
2747  if (!pOLV)
2748  {
2749  SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
2750  const SfxItemSet& rShapeSet = pObj->GetMergedItemSet();
2751 
2752  // if not in text edit mode (aka the user selected text or clicked on a word)
2753  // apply formatting attributes to selected shape
2754  // All formatting items (see ranges above) that are unequal in selected shape and
2755  // the format paintbrush are hard set on the selected shape.
2756 
2757  const sal_uInt16* pRanges = rFormatSet.GetRanges();
2758  bool bTextOnly = true;
2759 
2760  while (*pRanges)
2761  {
2762  if ((*pRanges != EE_PARA_START) && (*pRanges != EE_CHAR_START))
2763  {
2764  bTextOnly = false;
2765  break;
2766  }
2767  pRanges += 2;
2768  }
2769 
2770  if (!bTextOnly)
2771  {
2772  SfxItemSet aPaintSet(CreatePaintSet(GetFormatRangeImpl(false), *rShapeSet.GetPool(),
2773  rFormatSet, rShapeSet, bNoCharacterFormats,
2774  bNoParagraphFormats));
2775  SetAttrToMarked(aPaintSet, false /*bReplaceAll*/);
2776  }
2777 
2778  // now apply character and paragraph formatting to text, if the shape has any
2779  SdrTextObj* pTextObj = dynamic_cast<SdrTextObj*>(pObj);
2780  if (pTextObj)
2781  {
2782  sal_Int32 nText = pTextObj->getTextCount();
2783 
2784  while (--nText >= 0)
2785  {
2786  SdrText* pText = pTextObj->getText(nText);
2787  ApplyFormatPaintBrushToText(rFormatSet, *pTextObj, pText, bNoCharacterFormats,
2788  bNoParagraphFormats);
2789  }
2790  }
2791  }
2792  else
2793  {
2794  ::Outliner* pOutliner = pOLV->GetOutliner();
2795  if (pOutliner)
2796  {
2797  const EditEngine& rEditEngine = pOutliner->GetEditEngine();
2798 
2799  ESelection aSel(pOLV->GetSelection());
2800  if (!aSel.HasRange())
2801  pOLV->SetSelection(rEditEngine.GetWord(aSel, css::i18n::WordType::DICTIONARY_WORD));
2802 
2803  const bool bRemoveParaAttribs = !bNoParagraphFormats;
2804  pOLV->RemoveAttribsKeepLanguages(bRemoveParaAttribs);
2805  SfxItemSet aSet(pOLV->GetAttribs());
2806  SfxItemSet aPaintSet(CreatePaintSet(GetFormatRangeImpl(true), *aSet.GetPool(),
2807  rFormatSet, aSet, bNoCharacterFormats,
2808  bNoParagraphFormats));
2809  pOLV->SetAttribs(aPaintSet);
2810  }
2811  }
2812 
2813  // check for cloning to table cell, in which case we need to copy cell-specific formatting attributes
2814  SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
2815  if (pObj && (pObj->GetObjInventor() == SdrInventor::Default)
2816  && (pObj->GetObjIdentifier() == OBJ_TABLE))
2817  {
2818  auto pTable = static_cast<sdr::table::SdrTableObj*>(pObj);
2819  if (pTable->getActiveCell().is() && mxSelectionController.is())
2820  {
2821  mxSelectionController->SetAttributes(rFormatSet, false);
2822  }
2823  }
2824 }
2825 
2826 /* 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:2335
bool IsMacroHit(const SdrObjMacroHitRec &rRec) const
Definition: svdobj.cxx:1804
void ImpPaintOutlinerView(OutlinerView &rOutlView, const tools::Rectangle &rRect, OutputDevice &rTargetDevice) const
Definition: svdedxv.cxx:715
virtual void OnEndPasteOrDrop(PasteOrDropInfos *pInfo)
Definition: svdedxv.cxx:2525
TextChainCursorManager * ImpHandleMotionThroughBoxesKeyInput(const KeyEvent &rKEvt, bool *bOutHandled)
Definition: svdedxv.cxx:1756
constexpr sal_uInt16 XATTR_LINE_LAST(XATTR_LINECAP)
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:454
constexpr sal_uInt16 SDRATTR_SHADOW_FIRST(XATTR_END+1)
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:2315
virtual const tools::Rectangle & GetCurrentBoundRect() const
Definition: svdobj.cxx:854
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
constexpr sal_uInt16 SDRATTR_TABLE_FIRST(SDRATTR_CUSTOMSHAPE_LAST+1)
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:1315
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:2259
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:2028
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:793
virtual void BckAction() override
Definition: svdmrkv.cxx:324
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:2670
void BegUndo()
Definition: svdedtv.hxx:179
sal_uInt16 FirstWhich()
void SetPreChainingSel(const SdrTextObj *, ESelection const &)
Definition: textchain.cxx:54
constexpr sal_uInt16 XATTR_LINE_FIRST(XATTR_START)
const MapMode & GetMapMode() const
constexpr sal_uInt16 EE_ITEMS_END(EE_FEATURE_END)
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:2614
measurement object
Definition: svdobj.hxx:144
const SfxBroadcaster * GetBroadcaster() const
Definition: svdobj.cxx:627
SdrMark * GetMark(size_t nNum) const
Definition: svdmark.cxx:229
constexpr sal_uInt16 EE_PARA_END(EE_PARA_START+18)
OLE object.
Definition: svdobj.hxx:138
sal_Int32 GetParagraphCount() const
void append(std::unique_ptr< OverlayObject > pOverlayObject)
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:332
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
constexpr sal_uInt16 SDRATTR_MISC_LAST(SDRATTR_TEXT_CHAINNEXTNAME)
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:453
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:2475
polygon, PolyPolygon
Definition: svdobj.hxx:126
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:1439
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:126
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:2771
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:263
OUString SvxResId(const char *pId)
Definition: dialmgr.cxx:28
OUTDEV_WINDOW
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
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:2702
void TextEditDrawing(SdrPaintWindow &rPaintWindow) const
Definition: svdedxv.cxx:665
static SfxViewShell * Current()
SfxStyleSheet * GetStyleSheet() const
Definition: svdobj.cxx:2140
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:2342
virtual SvtScriptType GetScriptType() const
Definition: svdedxv.cxx:2044
virtual void SetChanged(bool bFlg=true)
Definition: svdmodel.cxx:1261
SfxStyleSheet * GetStyleSheet() const
Definition: svdedtv1.cxx:1336
void SetAttributes(const SfxItemSet &rSet, bool bReplaceAll)
Definition: svdedtv1.cxx:1327
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:222
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
virtual void MarkListHasChanged() override
Definition: svdedtv.cxx:351
constexpr sal_uInt16 SDRATTR_GRAF_LAST(SDRATTR_GRAFCROP)
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:1956
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:2440
constexpr sal_uInt16 EE_PARA_START(EE_ITEMS_START+0)
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:558
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
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:288
virtual void TakeActionRect(tools::Rectangle &rRect) const override
Definition: svdedxv.cxx:206
size_t GetMarkedObjectCount() const
Definition: svdmrkv.hxx:258
void MergeNotPersistAttrFromMarked(SfxItemSet &rAttr) const
Definition: svdedtv1.cxx:785
virtual void EndAction() override
Definition: svdmrkv.cxx:306
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:1012
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:2565
virtual bool IsAction() const override
Definition: svdmrkv.cxx:283
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
const SdrMarkList & GetMarkedObjectList() const
Definition: svdmrkv.hxx:252
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:257
constexpr sal_uInt16 XATTR_FILL_FIRST(XATTRSET_LINE+1)
void SetFillColor()
constexpr sal_uInt16 EE_ITEMS_START(OWN_ATTR_VALUE_END+1)
CommandEventId GetCommand() const
Link< EditFieldInfo *, void > aOldCalcFieldValueLink
Definition: svdedxv.hxx:91
void SetMergedItemSetAndBroadcast(const SfxItemSet &rSet, bool bClearAllItems=false)
Definition: svdobj.cxx:1929
void SetCalcFieldValueHdl(const Link< EditFieldInfo *, void > &rLink)
SvtScriptType GetSelectedScriptType() const
constexpr sal_uInt16 EE_CHAR_START(EE_PARA_END+1)
void SetEndTextEditHdl(const Link< SdrUndoManager *, void > &rLink)
long Bottom() const
SdrModel & getSdrModelFromSdrObject() const
Definition: svdobj.cxx:273
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:796
virtual void TakeTextAnchorRect(::tools::Rectangle &rAnchorRect) const
Definition: svdotext.cxx:586
virtual void append(const Primitive2DReference &) override
virtual bool HasMacro() const
Definition: svdobj.cxx:1762
void SetMoveOutside(bool bOn)
Definition: svdhdl.cxx:2208
virtual sal_uInt16 GetObjIdentifier() const override
Definition: svdotext.cxx:415
constexpr sal_uInt16 SDRATTR_GRAF_FIRST(SDRATTR_NOTPERSIST_LAST+1)
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:1996
Size GetOutputSizePixel() const
MapUnit GetMapUnit() const
virtual bool Command(const CommandEvent &, vcl::Window *)
Definition: svdpntv.hxx:457
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
constexpr sal_uInt16 EE_CHAR_END(EE_CHAR_START+32)
void ImpInvalidateOutlinerView(OutlinerView const &rOutlView) const
Definition: svdedxv.cxx:776
const SfxPoolItem & GetMergedItem(const sal_uInt16 nWhich) const
Definition: svdobj.cxx:1924
virtual void PaintMacro(OutputDevice &rOut, const tools::Rectangle &rDirtyRect, const SdrObjMacroHitRec &rRec) const
Definition: svdobj.cxx:1782
constexpr sal_uInt16 EE_FEATURE_START(EE_CHAR_END+1)
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:1607
void GrabFocus()
bool getPossibleGridOffsetForSdrObject(basegfx::B2DVector &rOffset, const SdrObject *pObj, const SdrPageView *pPV) const
Definition: svdmrkv.cxx:1999
SfxItemPool * GetPool() const
virtual SdrObject * RemoveObject(size_t nObjNum)
Definition: svdpage.cxx:421
const EditEngine & GetEditEngine() const
SdrUndoFactory & GetSdrUndoFactory() const
returns the models undo factory.
Definition: svdmodel.cxx:1961
bool EndMacroObj()
Definition: svdedxv.cxx:2415
void ImpMacroDown(const Point &rDownPos)
Definition: svdedxv.cxx:2373
virtual bool MouseButtonDown(const MouseEvent &rMEvt, OutputDevice *pWin) override
Definition: svdedxv.cxx:1814
virtual SdrInventor GetObjInventor() const
Definition: svdobj.cxx:553
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:577
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:2530
void MovMacroObj(const Point &rPnt)
Definition: svdedxv.cxx:2387
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
constexpr sal_uInt16 SDRATTR_SHADOW_LAST(SDRATTR_SHADOWBLUR)
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
constexpr sal_uInt16 SDRATTR_TABLE_LAST(SDRATTR_TABLE_TEXT_ROTATION)
void SetSelection(const ESelection &)
constexpr TypedWhichId< XFillAttrSetItem > XATTRSET_FILL(XATTR_FILL_LAST+1)
void SetStyleSheet(SfxStyleSheet *pStyleSheet, bool bDontRemoveHardAttr)
Definition: svdedtv1.cxx:1345
OverlayObject & getOverlayObject(sal_uInt32 nIndex) const
void ImpMoveCursorAfterChainingEvent(TextChainCursorManager *pCursorManager)
Definition: svdedxv.cxx:976
bool HasFill() const
Definition: svdoattr.cxx:89
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:206
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:2430
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:340
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:1889
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:2388
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:2304
SfxUndoManager * mpOldTextEditUndoManager
Definition: svdedxv.hxx:106
const Point & GetPosPixel() const
SdrObject * GetMarkedObjectByIndex(size_t nNum) const
Definition: svdmrkv.hxx:257
EVControlBits
void SetUpdateMode(bool bUpdate)
long Left() const
void translate(double fX, double fY)
constexpr TypedWhichId< SdrTextFixedCellHeightItem > SDRATTR_TEXT_USEFIXEDCELLHEIGHT(SDRATTR_MISC_FIRST+23)
void SetStyleSheet(sal_Int32 nPara, SfxStyleSheet *pStyle)
SdrPageView * GetSdrPageView() const
Definition: svdpntv.hxx:304
bool IsVertical() const
const Link< EditFieldInfo *, void > & GetCalcFieldValueHdl() const
bool SetAttributes(const SfxItemSet &rSet, bool bReplaceAll)
Definition: svdedxv.cxx:2114
SdrObjEditView(SdrModel &rSdrModel, OutputDevice *pOut)
Definition: svdedxv.cxx:86
Point aMacroDownPos
Definition: svdedxv.hxx:92
EEAnchorMode
constexpr sal_uInt16 EE_FEATURE_END(EE_FEATURE_FIELD+0)
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:108
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:365
virtual bool DoMacro(const SdrObjMacroHitRec &rRec)
Definition: svdobj.cxx:1799
SdrObjList * getParentSdrObjListFromSdrObject() const
Definition: svdobj.cxx:299
void Clear()
OutlinerParaObject * GetOutlinerParaObject() const
Definition: svdtext.cxx:88
void SetStyleSheet(SfxStyleSheet *pStyleSheet, bool bDontRemoveHardAttr)
Definition: svdedxv.cxx:2280
virtual void OnBeginPasteOrDrop(PasteOrDropInfos *pInfo)
Definition: svdedxv.cxx:2520
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:2735
bool bQuickTextEditMode
Definition: svdedxv.hxx:99
constexpr sal_uInt16 SDRATTR_MISC_FIRST(SDRATTR_CAPTION_LAST+1)
void ImpMacroUp(const Point &rUpPos)
Definition: svdedxv.cxx:2359
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
void GetAttributes(SfxItemSet &rTargetSet, bool bOnlyHardAttr) const
Definition: svdedxv.cxx:2077
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:2404
virtual void HideSdrPage() override
Definition: svdmrkv.cxx:359
SdrMarkList & GetMarkedObjectListWriteAccess()
Definition: svdmrkv.hxx:248
SdrTextObj * GetPrevLinkInChain() const
Definition: svdotext.cxx:2007
SdrModel * GetModel() const
Definition: svdpntv.hxx:265
SdrObject * pMacroObj
Definition: svdedxv.hxx:85
virtual OutlinerParaObject * GetOutlinerParaObject() const
Definition: svdobj.cxx:1748
SdrOutliner & ImpGetDrawOutliner() const
Definition: svdotext.cxx:1144
void CheckMarked()
Definition: svdmrkv.cxx:1612
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
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, bool bMobile=false)
void SetInvalidateMore(sal_uInt16 nPixel)
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:2637
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
bool IsEmptyPresObj() const
Definition: svdobj.hxx:881
void Paint(const tools::Rectangle &rRect, OutputDevice *pTargetDevice=nullptr)