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