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