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