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  // disallow scrolling
876  EVControlBits nStat = pOutlView->GetControlWord();
877  nStat &= ~EVControlBits::AUTOSCROLL;
878  // AutoViewSize only if not ContourFrame.
879  if (!bContourFrame)
880  nStat |= EVControlBits::AUTOSIZE;
881  if (bTextFrame)
882  {
883  sal_uInt16 nPixSiz = maHdlList.GetHdlSize() * 2 + 1;
884  nStat |= EVControlBits::INVONEMORE;
885  pOutlView->SetInvalidateMore(nPixSiz);
886  }
887  pOutlView->SetControlWord(nStat);
888  pOutlView->SetBackgroundColor(aBackground);
889 
890  // In case we're in the process of constructing a new view shell,
891  // SfxViewShell::Current() may still point to the old one. So if possible,
892  // depend on the application owning this draw view to provide the view
893  // shell.
894  SfxViewShell* pSfxViewShell = pViewShell ? pViewShell : GetSfxViewShell();
895  pOutlView->RegisterViewShell(pSfxViewShell ? pSfxViewShell : SfxViewShell::Current());
896 
897  if (pText != nullptr)
898  {
899  pOutlView->SetAnchorMode(pText->GetOutlinerViewAnchorMode());
900  mpTextEditOutliner->SetFixedCellHeight(
902  }
903  // do update before setting output area so that aTextEditArea can be recalculated
904  mpTextEditOutliner->SetUpdateLayout(true);
905  pOutlView->SetOutputArea(aTextEditArea);
906  ImpInvalidateOutlinerView(*pOutlView);
907  return pOutlView;
908 }
909 
910 IMPL_LINK(SdrObjEditView, ImpOutlinerStatusEventHdl, EditStatus&, rEditStat, void)
911 {
912  if (mpTextEditOutliner)
913  {
914  SdrTextObj* pTextObj = mxWeakTextEditObj.get();
915  if (pTextObj)
916  {
917  pTextObj->onEditOutlinerStatusEvent(&rEditStat);
918  }
919  }
920 }
921 
923 {
924  if (!mpTextEditOutliner)
925  return;
926 
927  SdrTextObj* pTextObj = mxWeakTextEditObj.get();
929  if (pTextObj && pOLV)
930  {
931  TextChain* pTextChain = pTextObj->GetTextChain();
932 
933  // XXX: IsChainable and GetNilChainingEvent are a bit mixed up atm
934  if (!pTextObj->IsChainable())
935  {
936  return;
937  }
938  // This is true during an underflow-caused overflow (with pEdtOutl->SetText())
939  if (pTextChain->GetNilChainingEvent(pTextObj))
940  {
941  return;
942  }
943 
944  // We prevent to trigger further handling of overflow/underflow for pTextObj
945  pTextChain->SetNilChainingEvent(pTextObj, true); // XXX
946 
947  // Save previous selection pos // NOTE: It must be done to have the right CursorEvent in KeyInput
948  pTextChain->SetPreChainingSel(pTextObj, pOLV->GetSelection());
949  //maPreChainingSel = new ESelection(pOLV->GetSelection());
950 
951  // Handling Undo
952  const int nText = 0; // XXX: hardcoded index (SdrTextObj::getText handles only 0)
953 
954  const bool bUndoEnabled = GetModel() && IsUndoEnabled();
955  std::unique_ptr<SdrUndoObjSetText> pTxtUndo;
956  if (bUndoEnabled)
957  pTxtUndo.reset(
958  dynamic_cast<SdrUndoObjSetText*>(GetModel()
959  ->GetSdrUndoFactory()
960  .CreateUndoObjectSetText(*pTextObj, nText)
961  .release()));
962 
963  // trigger actual chaining
964  pTextObj->onChainingEvent();
965 
966  if (pTxtUndo)
967  {
968  pTxtUndo->AfterSetText();
969  if (!pTxtUndo->IsDifferent())
970  {
971  pTxtUndo.reset();
972  }
973  }
974 
975  if (pTxtUndo)
976  AddUndo(std::move(pTxtUndo));
977 
978  //maCursorEvent = new CursorChainingEvent(pTextChain->GetCursorEvent(pTextObj));
979  //SdrTextObj *pNextLink = pTextObj->GetNextLinkInChain();
980 
981  // NOTE: Must be called. Don't let the function return if you set it to true and not reset it
982  pTextChain->SetNilChainingEvent(pTextObj, false);
983  }
984  else
985  {
986  // XXX
987  SAL_INFO("svx.chaining", "[OnChaining] No Edit Outliner View");
988  }
989 }
990 
991 IMPL_LINK_NOARG(SdrObjEditView, ImpAfterCutOrPasteChainingEventHdl, LinkParamNone*, void)
992 {
993  SdrTextObj* pTextObj = GetTextEditObject();
994  if (!pTextObj)
995  return;
996  ImpChainingEventHdl();
997  TextChainCursorManager aCursorManager(this, pTextObj);
998  ImpMoveCursorAfterChainingEvent(&aCursorManager);
999 }
1000 
1002 {
1003  if (!mxWeakTextEditObj.is() || !pCursorManager)
1004  return;
1005 
1006  SdrTextObj* pTextObj = mxWeakTextEditObj.get();
1007 
1008  // Check if it has links to move it to
1009  if (!pTextObj || !pTextObj->IsChainable())
1010  return;
1011 
1012  TextChain* pTextChain = pTextObj->GetTextChain();
1013  ESelection aNewSel = pTextChain->GetPostChainingSel(pTextObj);
1014 
1015  pCursorManager->HandleCursorEventAfterChaining(pTextChain->GetCursorEvent(pTextObj), aNewSel);
1016 
1017  // Reset event
1018  pTextChain->SetCursorEvent(pTextObj, CursorChainingEvent::NULL_EVENT);
1019 }
1020 
1021 IMPL_LINK(SdrObjEditView, ImpOutlinerCalcFieldValueHdl, EditFieldInfo*, pFI, void)
1022 {
1023  bool bOk = false;
1024  OUString& rStr = pFI->GetRepresentation();
1025  rStr.clear();
1026  SdrTextObj* pTextObj = mxWeakTextEditObj.get();
1027  if (pTextObj != nullptr)
1028  {
1029  std::optional<Color> pTxtCol;
1030  std::optional<Color> pFldCol;
1031  bOk = pTextObj->CalcFieldValue(pFI->GetField(), pFI->GetPara(), pFI->GetPos(), true,
1032  pTxtCol, pFldCol, rStr);
1033  if (bOk)
1034  {
1035  if (pTxtCol)
1036  {
1037  pFI->SetTextColor(*pTxtCol);
1038  }
1039  if (pFldCol)
1040  {
1041  pFI->SetFieldColor(*pFldCol);
1042  }
1043  else
1044  {
1045  pFI->SetFieldColor(COL_LIGHTGRAY); // TODO: remove this later on (357)
1046  }
1047  }
1048  }
1049  Outliner& rDrawOutl = mpModel->GetDrawOutliner(pTextObj);
1050  Link<EditFieldInfo*, void> aDrawOutlLink = rDrawOutl.GetCalcFieldValueHdl();
1051  if (!bOk && aDrawOutlLink.IsSet())
1052  {
1053  aDrawOutlLink.Call(pFI);
1054  bOk = !rStr.isEmpty();
1055  }
1056  if (!bOk)
1057  {
1058  aOldCalcFieldValueLink.Call(pFI);
1059  }
1060 }
1061 
1062 IMPL_LINK_NOARG(SdrObjEditView, EndTextEditHdl, SdrUndoManager*, void) { SdrEndTextEdit(); }
1063 
1064 // Default implementation - null UndoManager
1065 std::unique_ptr<SdrUndoManager> SdrObjEditView::createLocalTextUndoManager()
1066 {
1067  SAL_WARN("svx", "SdrObjEditView::createLocalTextUndoManager needs to be overridden");
1068  return std::unique_ptr<SdrUndoManager>();
1069 }
1070 
1072  bool bIsNewObj, SdrOutliner* pGivenOutliner,
1073  OutlinerView* pGivenOutlinerView, bool bDontDeleteOutliner,
1074  bool bOnlyOneView, bool bGrabFocus)
1075 {
1076  // FIXME cannot be an assert() yet, the code is not ready for that;
1077  // eg. press F7 in Impress when you are inside a text object with spelling
1078  // mistakes => boom; and it is unclear how to avoid that
1079  SAL_WARN_IF(IsTextEdit(), "svx", "SdrBeginTextEdit called when IsTextEdit() is already true.");
1080  // FIXME this encourages all sorts of bad habits and should be removed
1081  SdrEndTextEdit();
1082 
1083  SdrTextObj* pObj = dynamic_cast<SdrTextObj*>(pObj_);
1084  if (!pObj)
1085  return false; // currently only possible with text objects
1086 
1087  if (bGrabFocus && pWin)
1088  {
1089  // attention, this call may cause an EndTextEdit() call to this view
1090  pWin->GrabFocus(); // to force the cursor into the edit view
1091  }
1092 
1093  mbTextEditDontDelete = bDontDeleteOutliner && pGivenOutliner != nullptr;
1094  mbTextEditOnlyOneView = bOnlyOneView;
1095  mbTextEditNewObj = bIsNewObj;
1096  const sal_uInt32 nWinCount(PaintWindowCount());
1097 
1098  bool bBrk(false);
1099 
1100  if (!pWin)
1101  {
1102  for (sal_uInt32 i = 0; i < nWinCount && !pWin; i++)
1103  {
1104  SdrPaintWindow* pPaintWindow = GetPaintWindow(i);
1105 
1106  if (OUTDEV_WINDOW == pPaintWindow->GetOutputDevice().GetOutDevType())
1107  {
1108  pWin = pPaintWindow->GetOutputDevice().GetOwnerWindow();
1109  }
1110  }
1111 
1112  // break, when no window exists
1113  if (!pWin)
1114  {
1115  bBrk = true;
1116  }
1117  }
1118 
1119  if (!bBrk && !pPV)
1120  {
1121  pPV = GetSdrPageView();
1122 
1123  // break, when no PageView for the object exists
1124  if (!pPV)
1125  {
1126  bBrk = true;
1127  }
1128  }
1129 
1130  // no TextEdit on objects in locked Layer
1131  if (pPV && pPV->GetLockedLayers().IsSet(pObj->GetLayer()))
1132  {
1133  bBrk = true;
1134  }
1135 
1136  if (mpTextEditOutliner)
1137  {
1138  OSL_FAIL("SdrObjEditView::SdrBeginTextEdit(): Old Outliner still exists.");
1139  mpTextEditOutliner.reset();
1140  }
1141 
1142  if (!bBrk)
1143  {
1144  mpTextEditWin = pWin;
1145  mpTextEditPV = pPV;
1146  mxWeakTextEditObj.reset(pObj);
1147  if (pGivenOutliner)
1148  {
1149  mpTextEditOutliner.reset(pGivenOutliner);
1150  pGivenOutliner = nullptr; // so we don't delete it on the error path
1151  }
1152  else
1153  mpTextEditOutliner = SdrMakeOutliner(OutlinerMode::TextObject,
1155 
1156  {
1157  SvtAccessibilityOptions aOptions;
1158  mpTextEditOutliner->ForceAutoColor(aOptions.GetIsAutomaticFontColor());
1159  }
1160 
1161  aOldCalcFieldValueLink = mpTextEditOutliner->GetCalcFieldValueHdl();
1162  // FieldHdl has to be set by SdrBeginTextEdit, because this call an UpdateFields
1163  mpTextEditOutliner->SetCalcFieldValueHdl(
1164  LINK(this, SdrObjEditView, ImpOutlinerCalcFieldValueHdl));
1165  mpTextEditOutliner->SetBeginPasteOrDropHdl(LINK(this, SdrObjEditView, BeginPasteOrDropHdl));
1166  mpTextEditOutliner->SetEndPasteOrDropHdl(LINK(this, SdrObjEditView, EndPasteOrDropHdl));
1167 
1168  // It is just necessary to make the visualized page known. Set it.
1169  mpTextEditOutliner->setVisualizedPage(pPV->GetPage());
1170 
1171  mpTextEditOutliner->SetTextObjNoInit(mxWeakTextEditObj.get());
1172 
1174  {
1175  SdrTextObj* pTextObj = mxWeakTextEditObj.get();
1176  DBG_ASSERT(pTextObj, "svx::SdrObjEditView::BegTextEdit(), no text object?");
1177  if (!pTextObj)
1178  return false;
1179 
1180  // switch off any running TextAnimations
1181  pTextObj->SetTextAnimationAllowed(false);
1182 
1183  // remember old cursor
1184  if (mpTextEditOutliner->GetViewCount() != 0)
1185  {
1186  mpTextEditOutliner->RemoveView(static_cast<size_t>(0));
1187  }
1188 
1189  // Determine EditArea via TakeTextEditArea.
1190  // TODO: This could theoretically be left out, because TakeTextRect() calculates the aTextEditArea,
1191  // but aMinTextEditArea has to happen, too (therefore leaving this in right now)
1192  pTextObj->TakeTextEditArea(nullptr, nullptr, &aTextEditArea, &aMinTextEditArea);
1193 
1194  tools::Rectangle aTextRect;
1195  tools::Rectangle aAnchorRect;
1196  pTextObj->TakeTextRect(*mpTextEditOutliner, aTextRect, true,
1197  &aAnchorRect /* Give true here, not false */);
1198 
1199  if (!pTextObj->IsContourTextFrame())
1200  {
1201  // FitToSize not together with ContourFrame, for now
1202  if (pTextObj->IsFitToSize())
1203  aTextRect = aAnchorRect;
1204  }
1205 
1206  aTextEditArea = aTextRect;
1207 
1208  // add possible GridOffset to up-to-now view-independent EditAreas
1209  basegfx::B2DVector aGridOffset(0.0, 0.0);
1210  if (getPossibleGridOffsetForSdrObject(aGridOffset, pTextObj, pPV))
1211  {
1212  const Point aOffset(basegfx::fround(aGridOffset.getX()),
1213  basegfx::fround(aGridOffset.getY()));
1214 
1215  aTextEditArea += aOffset;
1216  aMinTextEditArea += aOffset;
1217  }
1218 
1219  Point aPvOfs(pTextObj->GetTextEditOffset());
1220  aTextEditArea.Move(aPvOfs.X(), aPvOfs.Y());
1221  aMinTextEditArea.Move(aPvOfs.X(), aPvOfs.Y());
1222  pTextEditCursorBuffer = pWin->GetCursor();
1223 
1224  maHdlList.SetMoveOutside(true);
1225 
1226  // Since IsMarkHdlWhenTextEdit() is ignored, it is necessary
1227  // to call AdjustMarkHdl() always.
1228  AdjustMarkHdl();
1229 
1230  mpTextEditOutlinerView = ImpMakeOutlinerView(pWin, pGivenOutlinerView);
1231 
1233  {
1234  // activate visualization of EditView on Overlay, suppress when
1235  // LibreOfficeKit is active
1237 
1238  const Color aHilightColor(SvtOptionsDrawinglayer::getHilightColor());
1239  const SdrTextObj* pText = GetTextEditObject();
1240  const bool bTextFrame(pText && pText->IsTextFrame());
1241  const bool bFitToSize(mpTextEditOutliner->GetControlWord()
1242  & EEControlBits::STRETCHING);
1243  const bool bVisualizeSurroundingFrame(bTextFrame && !bFitToSize);
1244  SdrPageView* pPageView = GetSdrPageView();
1245 
1246  if (pPageView)
1247  {
1248  for (sal_uInt32 b(0); b < pPageView->PageWindowCount(); b++)
1249  {
1250  const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
1251 
1252  if (rPageWindow.GetPaintWindow().OutputToWindow())
1253  {
1255  = rPageWindow.GetOverlayManager();
1256  if (xManager.is())
1257  {
1258  std::unique_ptr<TextEditOverlayObject> pNewTextEditOverlayObject(
1259  new TextEditOverlayObject(aHilightColor,
1261  bVisualizeSurroundingFrame));
1262 
1263  xManager->add(*pNewTextEditOverlayObject);
1264  xManager->add(const_cast<sdr::overlay::OverlaySelection&>(
1265  *pNewTextEditOverlayObject->getOverlaySelection()));
1266 
1267  maTEOverlayGroup.append(std::move(pNewTextEditOverlayObject));
1268  }
1269  }
1270  }
1271  }
1272  }
1273 
1274  // check if this view is already inserted
1275  size_t i2, nCount = mpTextEditOutliner->GetViewCount();
1276  for (i2 = 0; i2 < nCount; i2++)
1277  {
1278  if (mpTextEditOutliner->GetView(i2) == mpTextEditOutlinerView)
1279  break;
1280  }
1281 
1282  if (i2 == nCount)
1284 
1285  maHdlList.SetMoveOutside(false);
1286  maHdlList.SetMoveOutside(true);
1287 
1288  // register all windows as OutlinerViews with the Outliner
1289  if (!bOnlyOneView)
1290  {
1291  for (sal_uInt32 i = 0; i < nWinCount; i++)
1292  {
1293  SdrPaintWindow* pPaintWindow = GetPaintWindow(i);
1294  OutputDevice& rOutDev = pPaintWindow->GetOutputDevice();
1295 
1296  if (&rOutDev != pWin->GetOutDev() && OUTDEV_WINDOW == rOutDev.GetOutDevType())
1297  {
1298  OutlinerView* pOutlView
1299  = ImpMakeOutlinerView(rOutDev.GetOwnerWindow(), nullptr);
1300  mpTextEditOutliner->InsertView(pOutlView, static_cast<sal_uInt16>(i));
1301  }
1302  }
1303 
1305  {
1306  // Register an outliner view for all other sdr views that
1307  // show the same page, so that when the text edit changes,
1308  // all interested windows get an invalidation.
1309  SdrViewIter aIter(pObj->getSdrPageFromSdrObject());
1310  for (SdrView* pView = aIter.FirstView(); pView; pView = aIter.NextView())
1311  {
1312  if (pView == this)
1313  continue;
1314 
1315  for (sal_uInt32 nViewPaintWindow = 0;
1316  nViewPaintWindow < pView->PaintWindowCount(); ++nViewPaintWindow)
1317  {
1318  SdrPaintWindow* pPaintWindow = pView->GetPaintWindow(nViewPaintWindow);
1319  OutputDevice& rOutDev = pPaintWindow->GetOutputDevice();
1320 
1321  if (&rOutDev != pWin->GetOutDev()
1322  && OUTDEV_WINDOW == rOutDev.GetOutDevType())
1323  {
1324  OutlinerView* pOutlView
1325  = ImpMakeOutlinerView(rOutDev.GetOwnerWindow(), nullptr);
1326  pOutlView->HideCursor();
1327  rOutDev.GetOwnerWindow()->SetCursor(nullptr);
1328  mpTextEditOutliner->InsertView(pOutlView);
1329  }
1330  }
1331  }
1332  }
1333  }
1334 
1336  mpTextEditOutliner->SetStatusEventHdl(
1337  LINK(this, SdrObjEditView, ImpOutlinerStatusEventHdl));
1338  if (pTextObj->IsChainable())
1339  {
1341  LINK(this, SdrObjEditView, ImpAfterCutOrPasteChainingEventHdl));
1342  }
1343 
1344  mpTextEditOutliner->ClearModifyFlag();
1345 
1346  if (pTextObj->IsFitToSize())
1347  {
1348  pWin->Invalidate(aTextEditArea);
1349  }
1350 
1351  if (GetModel())
1352  {
1353  SdrHint aHint(SdrHintKind::BeginEdit, *pTextObj);
1354  GetModel()->Broadcast(aHint);
1355  }
1356 
1357  mpTextEditOutliner->setVisualizedPage(nullptr);
1358 
1359  if (mxSelectionController.is())
1360  mxSelectionController->onSelectionHasChanged();
1361 
1362  if (GetModel() && IsUndoEnabled()
1363  && !GetModel()->GetDisableTextEditUsesCommonUndoManager())
1364  {
1365  SdrUndoManager* pSdrUndoManager = nullptr;
1367 
1369  pSdrUndoManager = mpLocalTextEditUndoManager.get();
1370 
1371  if (pSdrUndoManager)
1372  {
1373  // we have an outliner, undo manager and it's an EditUndoManager, exchange
1374  // the document undo manager and the default one from the outliner and tell
1375  // it that text edit starts by setting a callback if it needs to end text edit mode.
1376  assert(nullptr == mpOldTextEditUndoManager);
1377 
1378  mpOldTextEditUndoManager = mpTextEditOutliner->SetUndoManager(pSdrUndoManager);
1379  pSdrUndoManager->SetEndTextEditHdl(LINK(this, SdrObjEditView, EndTextEditHdl));
1380  }
1381  else
1382  {
1383  OSL_ENSURE(false,
1384  "The document undo manager is not derived from SdrUndoManager (!)");
1385  }
1386  }
1387 
1388  return true; // ran fine, let TextEdit run now
1389  }
1390  else
1391  {
1392  mpTextEditOutliner->SetCalcFieldValueHdl(aOldCalcFieldValueLink);
1393  mpTextEditOutliner->SetBeginPasteOrDropHdl(Link<PasteOrDropInfos*, void>());
1394  mpTextEditOutliner->SetEndPasteOrDropHdl(Link<PasteOrDropInfos*, void>());
1395  }
1396  }
1397  if (mpTextEditOutliner != nullptr)
1398  {
1399  mpTextEditOutliner->setVisualizedPage(nullptr);
1400  }
1401 
1402  // something went wrong...
1403  if (!bDontDeleteOutliner)
1404  {
1405  delete pGivenOutliner;
1406  if (pGivenOutlinerView != nullptr)
1407  {
1408  delete pGivenOutlinerView;
1409  pGivenOutlinerView = nullptr;
1410  }
1411  }
1412  mpTextEditOutliner.reset();
1413 
1414  mpTextEditOutlinerView = nullptr;
1415  mxWeakTextEditObj.reset(nullptr);
1416  mpTextEditPV = nullptr;
1417  mpTextEditWin = nullptr;
1418  maHdlList.SetMoveOutside(false);
1419 
1420  return false;
1421 }
1422 
1424 {
1426  SdrTextObj* pTEObj = mxWeakTextEditObj.get();
1427  vcl::Window* pTEWin = mpTextEditWin;
1428  OutlinerView* pTEOutlinerView = mpTextEditOutlinerView;
1429  vcl::Cursor* pTECursorBuffer = pTextEditCursorBuffer;
1430  SdrUndoManager* pUndoEditUndoManager = nullptr;
1431  bool bNeedToUndoSavedRedoTextEdit(false);
1432 
1433  if (GetModel() && IsUndoEnabled() && pTEObj && mpTextEditOutliner
1434  && !GetModel()->GetDisableTextEditUsesCommonUndoManager())
1435  {
1436  // change back the UndoManager to the remembered original one
1437  SfxUndoManager* pOriginal = mpTextEditOutliner->SetUndoManager(mpOldTextEditUndoManager);
1438  mpOldTextEditUndoManager = nullptr;
1439 
1440  if (pOriginal)
1441  {
1442  // check if we got back our document undo manager
1443  SdrUndoManager* pSdrUndoManager = mpLocalTextEditUndoManager.get();
1444 
1445  if (pSdrUndoManager && dynamic_cast<SdrUndoManager*>(pOriginal) == pSdrUndoManager)
1446  {
1447  if (pSdrUndoManager->isEndTextEditTriggeredFromUndo())
1448  {
1449  // remember the UndoManager where missing Undos have to be triggered after end
1450  // text edit. When the undo had triggered the end text edit, the original action
1451  // which had to be undone originally is not yet undone.
1452  pUndoEditUndoManager = pSdrUndoManager;
1453 
1454  // We are ending text edit; if text edit was triggered from undo, execute all redos
1455  // to create a complete text change undo action for the redo buffer. Also mark this
1456  // state when at least one redo was executed; the created extra TextChange needs to
1457  // be undone in addition to the first real undo outside the text edit changes
1458  while (pSdrUndoManager->GetRedoActionCount()
1459  > pSdrUndoManager->GetRedoActionCountBeforeTextEdit())
1460  {
1461  bNeedToUndoSavedRedoTextEdit = true;
1462  pSdrUndoManager->Redo();
1463  }
1464  }
1465 
1466  // reset the callback link and let the undo manager cleanup all text edit
1467  // undo actions to get the stack back to the form before the text edit
1468  pSdrUndoManager->SetEndTextEditHdl(Link<SdrUndoManager*, void>());
1469  }
1470  else
1471  {
1472  OSL_ENSURE(false, "Got UndoManager back in SdrEndTextEdit which is NOT the "
1473  "expected document UndoManager (!)");
1474  delete pOriginal;
1475  }
1476 
1477  // cid#1493241 - Wrapper object use after free
1478  if (pUndoEditUndoManager == mpLocalTextEditUndoManager.get())
1479  pUndoEditUndoManager = nullptr;
1481  }
1482  }
1483  else
1484  {
1485  assert(nullptr == mpOldTextEditUndoManager); // cannot be restored!
1486  }
1487 
1488  if (GetModel() && mxWeakTextEditObj.is())
1489  {
1491  GetModel()->Broadcast(aHint);
1492  }
1493 
1494  // if new mechanism was used, clean it up. At cleanup no need to check
1495  // for LibreOfficeKit
1497  {
1500  }
1501 
1502  mxWeakTextEditObj.reset(nullptr);
1503  mpTextEditPV = nullptr;
1504  mpTextEditWin = nullptr;
1505  SdrOutliner* pTEOutliner = mpTextEditOutliner.release();
1506  mpTextEditOutlinerView = nullptr;
1507  pTextEditCursorBuffer = nullptr;
1509 
1510  if (pTEOutliner != nullptr)
1511  {
1512  bool bModified = pTEOutliner->IsModified();
1513  if (pTEOutlinerView != nullptr)
1514  {
1515  pTEOutlinerView->HideCursor();
1516  }
1517  if (pTEObj != nullptr)
1518  {
1519  pTEOutliner->CompleteOnlineSpelling();
1520 
1521  std::unique_ptr<SdrUndoObjSetText> pTxtUndo;
1522 
1523  if (bModified)
1524  {
1525  sal_Int32 nText;
1526  for (nText = 0; nText < pTEObj->getTextCount(); ++nText)
1527  if (pTEObj->getText(nText) == pTEObj->getActiveText())
1528  break;
1529 
1530  pTxtUndo.reset(
1531  dynamic_cast<SdrUndoObjSetText*>(GetModel()
1532  ->GetSdrUndoFactory()
1533  .CreateUndoObjectSetText(*pTEObj, nText)
1534  .release()));
1535  }
1536  DBG_ASSERT(!bModified || pTxtUndo,
1537  "svx::SdrObjEditView::EndTextEdit(), could not create undo action!");
1538  // Set old CalcFieldValue-Handler again, this
1539  // has to happen before Obj::EndTextEdit(), as this does UpdateFields().
1543 
1544  const bool bUndo = IsUndoEnabled();
1545  if (bUndo)
1546  {
1547  OUString aObjName(pTEObj->TakeObjNameSingul());
1548  BegUndo(SvxResId(STR_UndoObjSetText), aObjName);
1549  }
1550 
1551  pTEObj->EndTextEdit(*pTEOutliner);
1552 
1553  if ((pTEObj->GetRotateAngle() != 0_deg100) || (pTEObj && pTEObj->IsFontwork()))
1554  {
1555  pTEObj->ActionChanged();
1556  }
1557 
1558  if (pTxtUndo != nullptr)
1559  {
1560  pTxtUndo->AfterSetText();
1561  if (!pTxtUndo->IsDifferent())
1562  {
1563  pTxtUndo.reset();
1564  }
1565  }
1566  // check deletion of entire TextObj
1567  std::unique_ptr<SdrUndoAction> pDelUndo;
1568  bool bDelObj = false;
1569  if (mbTextEditNewObj)
1570  {
1571  bDelObj = pTEObj->IsTextFrame() && !pTEObj->HasText() && !pTEObj->IsEmptyPresObj()
1572  && !pTEObj->HasFill() && !pTEObj->HasLine();
1573 
1574  if (pTEObj->IsInserted() && bDelObj
1575  && pTEObj->GetObjInventor() == SdrInventor::Default && !bDontDeleteReally)
1576  {
1577  SdrObjKind eIdent = pTEObj->GetObjIdentifier();
1578  if (eIdent == SdrObjKind::Text)
1579  {
1580  pDelUndo = GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pTEObj);
1581  }
1582  }
1583  }
1584  if (pTxtUndo)
1585  {
1586  if (bUndo)
1587  AddUndo(std::move(pTxtUndo));
1589  }
1590  if (pDelUndo != nullptr)
1591  {
1592  if (bUndo)
1593  {
1594  AddUndo(std::move(pDelUndo));
1595  }
1597  DBG_ASSERT(pTEObj->getParentSdrObjListFromSdrObject() != nullptr,
1598  "SdrObjEditView::SdrEndTextEdit(): Fatal: Object edited doesn't have an "
1599  "ObjList!");
1600  if (pTEObj->getParentSdrObjListFromSdrObject() != nullptr)
1601  {
1603  CheckMarked(); // remove selection immediately...
1604  }
1605  }
1606  else if (bDelObj)
1607  { // for Writer: the app has to do the deletion itself.
1609  }
1610 
1611  if (bUndo)
1612  EndUndo(); // EndUndo after Remove, in case UndoStack is deleted immediately
1613 
1614  // Switch on any TextAnimation again after TextEdit
1615  if (pTEObj)
1616  {
1617  pTEObj->SetTextAnimationAllowed(true);
1618  }
1619 
1620  // Since IsMarkHdlWhenTextEdit() is ignored, it is necessary
1621  // to call AdjustMarkHdl() always.
1622  AdjustMarkHdl();
1623  }
1624  // delete all OutlinerViews
1625  for (size_t i = pTEOutliner->GetViewCount(); i > 0;)
1626  {
1627  i--;
1628  OutlinerView* pOLV = pTEOutliner->GetView(i);
1629  sal_uInt16 nMorePix = pOLV->GetInvalidateMore() + 10;
1630  vcl::Window* pWin = pOLV->GetWindow();
1631  tools::Rectangle aRect(pOLV->GetOutputArea());
1632  pTEOutliner->RemoveView(i);
1633  if (!mbTextEditDontDelete || i != 0)
1634  {
1635  // may not own the zeroth one
1636  delete pOLV;
1637  }
1638  aRect.Union(aTextEditArea);
1639  aRect.Union(aMinTextEditArea);
1640  aRect = pWin->LogicToPixel(aRect);
1641  aRect.AdjustLeft(-nMorePix);
1642  aRect.AdjustTop(-nMorePix);
1643  aRect.AdjustRight(nMorePix);
1644  aRect.AdjustBottom(nMorePix);
1645  aRect = pWin->PixelToLogic(aRect);
1646  InvalidateOneWin(*pWin->GetOutDev(), aRect);
1647  pWin->GetOutDev()->SetFillColor();
1648  pWin->GetOutDev()->SetLineColor(COL_BLACK);
1649  }
1650  // and now the Outliner itself
1651  if (!mbTextEditDontDelete)
1652  delete pTEOutliner;
1653  else
1654  pTEOutliner->Clear();
1655  if (pTEWin != nullptr)
1656  {
1657  pTEWin->SetCursor(pTECursorBuffer);
1658  }
1659  maHdlList.SetMoveOutside(false);
1660  if (eRet != SdrEndTextEditKind::Unchanged)
1661  {
1663  }
1664  }
1665 
1666  if (pTEObj && !pTEObj->getSdrModelFromSdrObject().isLocked() && pTEObj->GetBroadcaster())
1667  {
1668  SdrHint aHint(SdrHintKind::EndEdit, *pTEObj);
1669  const_cast<SfxBroadcaster*>(pTEObj->GetBroadcaster())->Broadcast(aHint);
1670  }
1671 
1672  if (pUndoEditUndoManager)
1673  {
1674  if (bNeedToUndoSavedRedoTextEdit)
1675  {
1676  // undo the text edit action since it was created as part of an EndTextEdit
1677  // callback from undo itself. This needs to be done after the call to
1678  // FmFormView::SdrEndTextEdit since it gets created there
1679  pUndoEditUndoManager->Undo();
1680  }
1681 
1682  // trigger the Undo which was not executed, but lead to this
1683  // end text edit
1684  pUndoEditUndoManager->Undo();
1685  }
1686 
1687  return eRet;
1688 }
1689 
1690 // info about TextEdit. Default is false.
1692 
1693 // info about TextEditPageView. Default is 0L.
1695 
1697 {
1698  if (pWin == nullptr)
1699  return nullptr;
1700  if (mpTextEditOutliner == nullptr)
1701  return nullptr;
1702  OutlinerView* pNewView = nullptr;
1703  size_t nWinCount = mpTextEditOutliner->GetViewCount();
1704  for (size_t i = 0; i < nWinCount && pNewView == nullptr; i++)
1705  {
1706  OutlinerView* pView = mpTextEditOutliner->GetView(i);
1707  if (pView->GetWindow() == pWin)
1708  pNewView = pView;
1709  }
1710  return pNewView;
1711 }
1712 
1714 {
1715  if (!(mxWeakTextEditObj.is() && pWin != nullptr && pWin != mpTextEditWin))
1716  return;
1717 
1718  OutlinerView* pNewView = ImpFindOutlinerView(pWin);
1719  if (pNewView != nullptr && pNewView != mpTextEditOutlinerView)
1720  {
1721  if (mpTextEditOutlinerView != nullptr)
1722  {
1724  }
1725  mpTextEditOutlinerView = pNewView;
1726  mpTextEditWin = pWin;
1727  pWin->GrabFocus(); // Make the cursor blink here as well
1728  pNewView->ShowCursor();
1730  }
1731 }
1732 
1733 bool SdrObjEditView::IsTextEditHit(const Point& rHit) const
1734 {
1735  bool bOk = false;
1736  if (mxWeakTextEditObj.is())
1737  {
1738  tools::Rectangle aEditArea;
1739  if (OutlinerView* pOLV = mpTextEditOutliner->GetView(0))
1740  aEditArea.Union(pOLV->GetOutputArea());
1741 
1742  if (aEditArea.Contains(rHit))
1743  { // check if any characters were actually hit
1744  const Point aPnt(rHit - aEditArea.TopLeft());
1745  tools::Long nHitTol = 2000;
1746  if (OutputDevice* pRef = mpTextEditOutliner->GetRefDevice())
1747  nHitTol = OutputDevice::LogicToLogic(nHitTol, MapUnit::Map100thMM,
1748  pRef->GetMapMode().GetMapUnit());
1749 
1750  bOk = mpTextEditOutliner->IsTextPos(aPnt, static_cast<sal_uInt16>(nHitTol));
1751  }
1752  }
1753  return bOk;
1754 }
1755 
1756 bool SdrObjEditView::IsTextEditFrameHit(const Point& rHit) const
1757 {
1758  bool bOk = false;
1759  if (mxWeakTextEditObj.is())
1760  {
1761  SdrTextObj* pText = mxWeakTextEditObj.get();
1762  OutlinerView* pOLV = mpTextEditOutliner->GetView(0);
1763  if (pOLV)
1764  {
1765  vcl::Window* pWin = pOLV->GetWindow();
1766  if (pText != nullptr && pText->IsTextFrame() && pWin != nullptr)
1767  {
1768  sal_uInt16 nPixSiz = pOLV->GetInvalidateMore();
1770  aEditArea.Union(pOLV->GetOutputArea());
1771  if (!aEditArea.Contains(rHit))
1772  {
1773  Size aSiz(pWin->PixelToLogic(Size(nPixSiz, nPixSiz)));
1774  aEditArea.AdjustLeft(-(aSiz.Width()));
1775  aEditArea.AdjustTop(-(aSiz.Height()));
1776  aEditArea.AdjustRight(aSiz.Width());
1777  aEditArea.AdjustBottom(aSiz.Height());
1778  bOk = aEditArea.Contains(rHit);
1779  }
1780  }
1781  }
1782  }
1783  return bOk;
1784 }
1785 
1786 std::unique_ptr<TextChainCursorManager>
1788 {
1789  *bOutHandled = false;
1790 
1791  SdrTextObj* pTextObj = mxWeakTextEditObj.get();
1792  if (!pTextObj)
1793  return nullptr;
1794 
1795  if (!pTextObj->GetNextLinkInChain() && !pTextObj->GetPrevLinkInChain())
1796  return nullptr;
1797 
1798  std::unique_ptr<TextChainCursorManager> pCursorManager(
1799  new TextChainCursorManager(this, pTextObj));
1800  if (pCursorManager->HandleKeyEvent(rKEvt))
1801  {
1802  // Possibly do other stuff here if necessary...
1803  // XXX: Careful with the checks below (in KeyInput) for pWin and co. You should do them here I guess.
1804  *bOutHandled = true;
1805  }
1806 
1807  return pCursorManager;
1808 }
1809 
1811 {
1813  {
1814  /* Start special handling of keys within a chain */
1815  // We possibly move to another box before any handling
1816  bool bHandled = false;
1817  std::unique_ptr<TextChainCursorManager> xCursorManager(
1818  ImpHandleMotionThroughBoxesKeyInput(rKEvt, &bHandled));
1819  if (bHandled)
1820  return true;
1821  /* End special handling of keys within a chain */
1822 
1823  if (mpTextEditOutlinerView->PostKeyEvent(rKEvt, pWin))
1824  {
1825  if (mpModel)
1826  {
1827  if (mpTextEditOutliner && mpTextEditOutliner->IsModified())
1828  mpModel->SetChanged();
1829  }
1830 
1831  /* Start chaining processing */
1833  ImpMoveCursorAfterChainingEvent(xCursorManager.get());
1834  /* End chaining processing */
1835 
1836  if (pWin != nullptr && pWin != mpTextEditWin)
1837  SetTextEditWin(pWin);
1839  return true;
1840  }
1841  }
1842  return SdrGlueEditView::KeyInput(rKEvt, pWin);
1843 }
1844 
1846 {
1847  if (mpTextEditOutlinerView != nullptr)
1848  {
1849  bool bPostIt = mpTextEditOutliner->IsInSelectionMode();
1850  if (!bPostIt)
1851  {
1852  Point aPt(rMEvt.GetPosPixel());
1853  if (pWin != nullptr)
1854  aPt = pWin->PixelToLogic(aPt);
1855  else if (mpTextEditWin != nullptr)
1856  aPt = mpTextEditWin->PixelToLogic(aPt);
1857  bPostIt = IsTextEditHit(aPt);
1858  }
1859  if (bPostIt)
1860  {
1861  Point aPixPos(rMEvt.GetPosPixel());
1862  if (pWin)
1863  {
1865  if (aPixPos.X() < aR.Left())
1866  aPixPos.setX(aR.Left());
1867  if (aPixPos.X() > aR.Right())
1868  aPixPos.setX(aR.Right());
1869  if (aPixPos.Y() < aR.Top())
1870  aPixPos.setY(aR.Top());
1871  if (aPixPos.Y() > aR.Bottom())
1872  aPixPos.setY(aR.Bottom());
1873  }
1874  MouseEvent aMEvt(aPixPos, rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(),
1875  rMEvt.GetModifier());
1877  {
1878  if (pWin != nullptr && pWin != mpTextEditWin->GetOutDev()
1879  && pWin->GetOutDevType() == OUTDEV_WINDOW)
1880  SetTextEditWin(pWin->GetOwnerWindow());
1882  return true;
1883  }
1884  }
1885  }
1886  return SdrGlueEditView::MouseButtonDown(rMEvt, pWin);
1887 }
1888 
1890 {
1891  if (mpTextEditOutlinerView != nullptr)
1892  {
1893  bool bPostIt = mpTextEditOutliner->IsInSelectionMode();
1894  if (!bPostIt)
1895  {
1896  Point aPt(rMEvt.GetPosPixel());
1897  if (pWin != nullptr)
1898  aPt = pWin->PixelToLogic(aPt);
1899  else if (mpTextEditWin != nullptr)
1900  aPt = mpTextEditWin->PixelToLogic(aPt);
1901  bPostIt = IsTextEditHit(aPt);
1902  }
1903  if (bPostIt && pWin)
1904  {
1905  Point aPixPos(rMEvt.GetPosPixel());
1907  if (aPixPos.X() < aR.Left())
1908  aPixPos.setX(aR.Left());
1909  if (aPixPos.X() > aR.Right())
1910  aPixPos.setX(aR.Right());
1911  if (aPixPos.Y() < aR.Top())
1912  aPixPos.setY(aR.Top());
1913  if (aPixPos.Y() > aR.Bottom())
1914  aPixPos.setY(aR.Bottom());
1915  MouseEvent aMEvt(aPixPos, rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(),
1916  rMEvt.GetModifier());
1918  {
1920  return true;
1921  }
1922  }
1923  }
1924  return SdrGlueEditView::MouseButtonUp(rMEvt, pWin);
1925 }
1926 
1928 {
1929  if (mpTextEditOutlinerView != nullptr)
1930  {
1931  bool bSelMode = mpTextEditOutliner->IsInSelectionMode();
1932  bool bPostIt = bSelMode;
1933  if (!bPostIt)
1934  {
1935  Point aPt(rMEvt.GetPosPixel());
1936  if (pWin)
1937  aPt = pWin->PixelToLogic(aPt);
1938  else if (mpTextEditWin)
1939  aPt = mpTextEditWin->PixelToLogic(aPt);
1940  bPostIt = IsTextEditHit(aPt);
1941  }
1942  if (bPostIt)
1943  {
1944  Point aPixPos(rMEvt.GetPosPixel());
1946  if (pWin)
1947  aR = pWin->LogicToPixel(aR);
1948  else if (mpTextEditWin)
1949  aR = mpTextEditWin->LogicToPixel(aR);
1950  if (aPixPos.X() < aR.Left())
1951  aPixPos.setX(aR.Left());
1952  if (aPixPos.X() > aR.Right())
1953  aPixPos.setX(aR.Right());
1954  if (aPixPos.Y() < aR.Top())
1955  aPixPos.setY(aR.Top());
1956  if (aPixPos.Y() > aR.Bottom())
1957  aPixPos.setY(aR.Bottom());
1958  MouseEvent aMEvt(aPixPos, rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(),
1959  rMEvt.GetModifier());
1960  if (mpTextEditOutlinerView->MouseMove(aMEvt) && bSelMode)
1961  {
1963  return true;
1964  }
1965  }
1966  }
1967  return SdrGlueEditView::MouseMove(rMEvt, pWin);
1968 }
1969 
1971 {
1972  // as long as OutlinerView returns a sal_Bool, it only gets CommandEventId::StartDrag
1973  if (mpTextEditOutlinerView != nullptr)
1974  {
1975  if (rCEvt.GetCommand() == CommandEventId::StartDrag)
1976  {
1977  bool bPostIt = mpTextEditOutliner->IsInSelectionMode() || !rCEvt.IsMouseEvent();
1978  if (!bPostIt && rCEvt.IsMouseEvent())
1979  {
1980  Point aPt(rCEvt.GetMousePosPixel());
1981  if (pWin != nullptr)
1982  aPt = pWin->PixelToLogic(aPt);
1983  else if (mpTextEditWin != nullptr)
1984  aPt = mpTextEditWin->PixelToLogic(aPt);
1985  bPostIt = IsTextEditHit(aPt);
1986  }
1987  if (bPostIt)
1988  {
1989  Point aPixPos(rCEvt.GetMousePosPixel());
1990  if (rCEvt.IsMouseEvent() && pWin)
1991  {
1992  tools::Rectangle aR(
1994  if (aPixPos.X() < aR.Left())
1995  aPixPos.setX(aR.Left());
1996  if (aPixPos.X() > aR.Right())
1997  aPixPos.setX(aR.Right());
1998  if (aPixPos.Y() < aR.Top())
1999  aPixPos.setY(aR.Top());
2000  if (aPixPos.Y() > aR.Bottom())
2001  aPixPos.setY(aR.Bottom());
2002  }
2003  CommandEvent aCEvt(aPixPos, rCEvt.GetCommand(), rCEvt.IsMouseEvent());
2004  // Command is void at the OutlinerView, sadly
2006  if (pWin != nullptr && pWin != mpTextEditWin)
2007  SetTextEditWin(pWin);
2009  return true;
2010  }
2011  }
2012  else
2013  {
2016  {
2017  // It could execute CommandEventId::ExtTextInput, while SdrObjEditView::KeyInput
2018  // isn't called
2019  if (mpTextEditOutliner && mpTextEditOutliner->IsModified())
2020  mpModel->SetChanged();
2021  }
2022  return true;
2023  }
2024  }
2025  return SdrGlueEditView::Command(rCEvt, pWin);
2026 }
2027 
2029 {
2030  bool bRet = false;
2031  if (mpTextEditOutliner != nullptr && mpTextEditOutlinerView != nullptr)
2032  {
2034  {
2035  const sal_Int32 nParaCnt = mpTextEditOutliner->GetParagraphCount();
2036  Paragraph* pLastPara
2037  = mpTextEditOutliner->GetParagraph(nParaCnt > 1 ? nParaCnt - 1 : 0);
2038 
2040  if (aESel.nStartPara == 0 && aESel.nStartPos == 0 && aESel.nEndPara == (nParaCnt - 1))
2041  {
2042  if (mpTextEditOutliner->GetText(pLastPara).getLength() == aESel.nEndPos)
2043  bRet = true;
2044  }
2045  // in case the selection was done backwards
2046  if (!bRet && aESel.nEndPara == 0 && aESel.nEndPos == 0
2047  && aESel.nStartPara == (nParaCnt - 1))
2048  {
2049  if (mpTextEditOutliner->GetText(pLastPara).getLength() == aESel.nStartPos)
2050  bRet = true;
2051  }
2052  }
2053  else
2054  {
2055  bRet = true;
2056  }
2057  }
2058  return bRet;
2059 }
2060 
2062 {
2063  if (mpTextEditOutlinerView != nullptr && mpTextEditWin != nullptr)
2064  {
2065  vcl::Cursor* pCsr = mpTextEditWin->GetCursor();
2066  if (pCsr != nullptr)
2067  {
2068  Size aSiz(pCsr->GetSize());
2069  if (!aSiz.IsEmpty())
2070  {
2072  }
2073  }
2074  }
2075 }
2076 
2078 {
2079  SvtScriptType nScriptType = SvtScriptType::NONE;
2080 
2081  if (IsTextEdit())
2082  {
2084  nScriptType
2086 
2089  }
2090  else
2091  {
2092  const size_t nMarkCount(GetMarkedObjectCount());
2093 
2094  for (size_t i = 0; i < nMarkCount; ++i)
2095  {
2097 
2098  if (pParaObj)
2099  {
2100  nScriptType |= pParaObj->GetTextObject().GetScriptType();
2101  }
2102  }
2103  }
2104 
2105  if (nScriptType == SvtScriptType::NONE)
2106  nScriptType = SvtScriptType::LATIN;
2107 
2108  return nScriptType;
2109 }
2110 
2111 void SdrObjEditView::GetAttributes(SfxItemSet& rTargetSet, bool bOnlyHardAttr) const
2112 {
2113  if (mxSelectionController.is())
2114  if (mxSelectionController->GetAttributes(rTargetSet, bOnlyHardAttr))
2115  return;
2116 
2117  if (IsTextEdit())
2118  {
2120  "SdrObjEditView::GetAttributes(): mpTextEditOutlinerView=NULL");
2121  DBG_ASSERT(mpTextEditOutliner != nullptr,
2122  "SdrObjEditView::GetAttributes(): mpTextEditOutliner=NULL");
2123 
2124  // take care of bOnlyHardAttr(!)
2125  if (!bOnlyHardAttr && mxWeakTextEditObj->GetStyleSheet())
2126  rTargetSet.Put(mxWeakTextEditObj->GetStyleSheet()->GetItemSet());
2127 
2128  // add object attributes
2129  rTargetSet.Put(mxWeakTextEditObj->GetMergedItemSet());
2130 
2132  {
2133  // FALSE= regard InvalidItems as "holes," not as Default
2134  rTargetSet.Put(mpTextEditOutlinerView->GetAttribs(), false);
2135  }
2136 
2138  {
2139  MergeNotPersistAttrFromMarked(rTargetSet);
2140  }
2141  }
2142  else
2143  {
2144  SdrGlueEditView::GetAttributes(rTargetSet, bOnlyHardAttr);
2145  }
2146 }
2147 
2148 bool SdrObjEditView::SetAttributes(const SfxItemSet& rSet, bool bReplaceAll)
2149 {
2150  bool bRet = false;
2151  bool bTextEdit = mpTextEditOutlinerView != nullptr && mxWeakTextEditObj.is();
2152  bool bAllTextSelected = ImpIsTextEditAllSelected();
2153  const SfxItemSet* pSet = &rSet;
2154 
2155  if (!bTextEdit)
2156  {
2157  // no TextEdit active -> all Items to drawing object
2158  if (mxSelectionController.is())
2159  bRet = mxSelectionController->SetAttributes(*pSet, bReplaceAll);
2160 
2161  if (!bRet)
2162  {
2163  SdrGlueEditView::SetAttributes(*pSet, bReplaceAll);
2164  bRet = true;
2165  }
2166  }
2167  else
2168  {
2169 #ifdef DBG_UTIL
2170  {
2171  bool bHasEEFeatureItems = false;
2172  SfxItemIter aIter(rSet);
2173  for (const SfxPoolItem* pItem = aIter.GetCurItem(); !bHasEEFeatureItems && pItem;
2174  pItem = aIter.NextItem())
2175  {
2176  if (!IsInvalidItem(pItem))
2177  {
2178  sal_uInt16 nW = pItem->Which();
2179  if (nW >= EE_FEATURE_START && nW <= EE_FEATURE_END)
2180  bHasEEFeatureItems = true;
2181  }
2182  }
2183 
2184  if (bHasEEFeatureItems)
2185  {
2186  std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(
2187  nullptr, VclMessageType::Info, VclButtonsType::Ok,
2188  "SdrObjEditView::SetAttributes(): Setting EE_FEATURE items "
2189  "at the SdrView does not make sense! It only leads to "
2190  "overhead and unreadable documents."));
2191  xInfoBox->run();
2192  }
2193  }
2194 #endif
2195 
2196  bool bOnlyEEItems;
2197  bool bNoEEItems = !SearchOutlinerItems(*pSet, bReplaceAll, &bOnlyEEItems);
2198  // everything selected? -> attributes to the border, too
2199  // if no EEItems, attributes to the border only
2200  if (bAllTextSelected || bNoEEItems)
2201  {
2202  if (mxSelectionController.is())
2203  bRet = mxSelectionController->SetAttributes(*pSet, bReplaceAll);
2204 
2205  if (!bRet)
2206  {
2207  const bool bUndo = IsUndoEnabled();
2208 
2209  if (bUndo)
2210  {
2211  BegUndo(ImpGetDescriptionString(STR_EditSetAttributes));
2212  AddUndo(
2213  GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*mxWeakTextEditObj));
2214 
2215  // If this is a text object also rescue the OutlinerParaObject since
2216  // applying attributes to the object may change text layout when
2217  // multiple portions exist with multiple formats. If an OutlinerParaObject
2218  // really exists and needs to be rescued is evaluated in the undo
2219  // implementation itself.
2220  bool bRescueText = mxWeakTextEditObj;
2221 
2222  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(
2223  *mxWeakTextEditObj, false, !bNoEEItems || bRescueText));
2224  EndUndo();
2225  }
2226 
2227  mxWeakTextEditObj->SetMergedItemSetAndBroadcast(*pSet, bReplaceAll);
2228 
2229  FlushComeBackTimer(); // to set ModeHasChanged immediately
2230  }
2231  }
2232  else if (!bOnlyEEItems)
2233  {
2234  // Otherwise split Set, if necessary.
2235  // Now we build an ItemSet aSet that doesn't contain EE_Items from
2236  // *pSet (otherwise it would be a copy).
2237  WhichRangesContainer pNewWhichTable
2239  SfxItemSet aSet(mpModel->GetItemPool(), std::move(pNewWhichTable));
2240  SfxWhichIter aIter(aSet);
2241  sal_uInt16 nWhich = aIter.FirstWhich();
2242  while (nWhich != 0)
2243  {
2244  const SfxPoolItem* pItem;
2245  SfxItemState eState = pSet->GetItemState(nWhich, false, &pItem);
2246  if (eState == SfxItemState::SET)
2247  aSet.Put(*pItem);
2248  nWhich = aIter.NextWhich();
2249  }
2250 
2251  if (mxSelectionController.is())
2252  bRet = mxSelectionController->SetAttributes(aSet, bReplaceAll);
2253 
2254  if (!bRet)
2255  {
2256  if (IsUndoEnabled())
2257  {
2258  BegUndo(ImpGetDescriptionString(STR_EditSetAttributes));
2259  AddUndo(
2260  GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*mxWeakTextEditObj));
2261  AddUndo(
2262  GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*mxWeakTextEditObj));
2263  EndUndo();
2264  }
2265 
2266  mxWeakTextEditObj->SetMergedItemSetAndBroadcast(aSet, bReplaceAll);
2267 
2268  if (GetMarkedObjectCount() == 1
2270  {
2272  }
2273  }
2275  }
2276  if (!bNoEEItems)
2277  {
2278  // and now the attributes to the EditEngine
2279  if (bReplaceAll)
2280  {
2282  }
2284 
2285  Outliner* pTEOutliner = mpTextEditOutlinerView->GetOutliner();
2286  if (mpModel && pTEOutliner && pTEOutliner->IsModified())
2287  mpModel->SetChanged();
2288 
2290  }
2291  bRet = true;
2292  }
2293  return bRet;
2294 }
2295 
2297 {
2298  SfxStyleSheet* pSheet = nullptr;
2299 
2300  if (mxSelectionController.is())
2301  {
2302  if (mxSelectionController->GetStyleSheet(pSheet))
2303  return pSheet;
2304  }
2305 
2307  {
2309  }
2310  else
2311  {
2312  pSheet = SdrGlueEditView::GetStyleSheet();
2313  }
2314  return pSheet;
2315 }
2316 
2317 void SdrObjEditView::SetStyleSheet(SfxStyleSheet* pStyleSheet, bool bDontRemoveHardAttr)
2318 {
2319  if (mxSelectionController.is())
2320  {
2321  if (mxSelectionController->SetStyleSheet(pStyleSheet, bDontRemoveHardAttr))
2322  return;
2323  }
2324 
2325  // if we are currently in edit mode we must also set the stylesheet
2326  // on all paragraphs in the Outliner for the edit view
2327  if (nullptr != mpTextEditOutlinerView)
2328  {
2330 
2331  const sal_Int32 nParaCount = pOutliner->GetParagraphCount();
2332  for (sal_Int32 nPara = 0; nPara < nParaCount; nPara++)
2333  {
2334  pOutliner->SetStyleSheet(nPara, pStyleSheet);
2335  }
2336  }
2337 
2338  SdrGlueEditView::SetStyleSheet(pStyleSheet, bDontRemoveHardAttr);
2339 }
2340 
2342 {
2343  SdrGlueEditView::AddWindowToPaintView(pNewWin, pWindow);
2344 
2346  && pNewWin->GetOutDevType() == OUTDEV_WINDOW)
2347  {
2348  OutlinerView* pOutlView = ImpMakeOutlinerView(pNewWin->GetOwnerWindow(), nullptr);
2349  mpTextEditOutliner->InsertView(pOutlView);
2350  }
2351 }
2352 
2354 {
2356 
2358  && pOldWin->GetOutDevType() == OUTDEV_WINDOW)
2359  {
2360  for (size_t i = mpTextEditOutliner->GetViewCount(); i > 0;)
2361  {
2362  i--;
2363  OutlinerView* pOLV = mpTextEditOutliner->GetView(i);
2364  if (pOLV && pOLV->GetWindow() == pOldWin->GetOwnerWindow())
2365  {
2366  mpTextEditOutliner->RemoveView(i);
2367  }
2368  }
2369  }
2370 
2371  lcl_RemoveTextEditOutlinerViews(this, GetSdrPageView(), pOldWin);
2372 }
2373 
2375 {
2376  return mpTextEditOutliner != nullptr && mpTextEditOutliner->IsInSelectionMode();
2377 }
2378 
2379 // MacroMode
2380 
2381 void SdrObjEditView::BegMacroObj(const Point& rPnt, short nTol, SdrObject* pObj, SdrPageView* pPV,
2382  vcl::Window* pWin)
2383 {
2384  BrkMacroObj();
2385  if (pObj != nullptr && pPV != nullptr && pWin != nullptr && pObj->HasMacro())
2386  {
2387  nTol = ImpGetHitTolLogic(nTol, nullptr);
2388  pMacroObj = pObj;
2389  pMacroPV = pPV;
2390  pMacroWin = pWin;
2391  mbMacroDown = false;
2392  nMacroTol = sal_uInt16(nTol);
2393  aMacroDownPos = rPnt;
2394  MovMacroObj(rPnt);
2395  }
2396 }
2397 
2398 void SdrObjEditView::ImpMacroUp(const Point& rUpPos)
2399 {
2400  if (pMacroObj != nullptr && mbMacroDown)
2401  {
2402  SdrObjMacroHitRec aHitRec;
2403  aHitRec.aPos = rUpPos;
2404  aHitRec.nTol = nMacroTol;
2405  aHitRec.pVisiLayer = &pMacroPV->GetVisibleLayers();
2406  aHitRec.pPageView = pMacroPV;
2408  mbMacroDown = false;
2409  }
2410 }
2411 
2412 void SdrObjEditView::ImpMacroDown(const Point& rDownPos)
2413 {
2414  if (pMacroObj != nullptr && !mbMacroDown)
2415  {
2416  SdrObjMacroHitRec aHitRec;
2417  aHitRec.aPos = rDownPos;
2418  aHitRec.nTol = nMacroTol;
2419  aHitRec.pVisiLayer = &pMacroPV->GetVisibleLayers();
2420  aHitRec.pPageView = pMacroPV;
2422  mbMacroDown = true;
2423  }
2424 }
2425 
2426 void SdrObjEditView::MovMacroObj(const Point& rPnt)
2427 {
2428  if (pMacroObj == nullptr)
2429  return;
2430 
2431  SdrObjMacroHitRec aHitRec;
2432  aHitRec.aPos = rPnt;
2433  aHitRec.nTol = nMacroTol;
2434  aHitRec.pVisiLayer = &pMacroPV->GetVisibleLayers();
2435  aHitRec.pPageView = pMacroPV;
2436  bool bDown = pMacroObj->IsMacroHit(aHitRec);
2437  if (bDown)
2438  ImpMacroDown(rPnt);
2439  else
2440  ImpMacroUp(rPnt);
2441 }
2442 
2444 {
2445  if (pMacroObj != nullptr)
2446  {
2448  pMacroObj = nullptr;
2449  pMacroPV = nullptr;
2450  pMacroWin = nullptr;
2451  }
2452 }
2453 
2455 {
2456  if (pMacroObj != nullptr && mbMacroDown)
2457  {
2459  SdrObjMacroHitRec aHitRec;
2460  aHitRec.aPos = aMacroDownPos;
2461  aHitRec.nTol = nMacroTol;
2462  aHitRec.pVisiLayer = &pMacroPV->GetVisibleLayers();
2463  aHitRec.pPageView = pMacroPV;
2464  bool bRet = pMacroObj->DoMacro(aHitRec);
2465  pMacroObj = nullptr;
2466  pMacroPV = nullptr;
2467  pMacroWin = nullptr;
2468  return bRet;
2469  }
2470  else
2471  {
2472  BrkMacroObj();
2473  return false;
2474  }
2475 }
2476 
2479 void SdrObjEditView::getTextSelection(css::uno::Any& rSelection)
2480 {
2481  if (!IsTextEdit())
2482  return;
2483 
2484  OutlinerView* pOutlinerView = GetTextEditOutlinerView();
2485  if (!(pOutlinerView && pOutlinerView->HasSelection()))
2486  return;
2487 
2488  SdrObject* pObj = GetTextEditObject();
2489 
2490  if (!pObj)
2491  return;
2492 
2493  css::uno::Reference<css::text::XText> xText(pObj->getUnoShape(), css::uno::UNO_QUERY);
2494  if (xText.is())
2495  {
2496  SvxUnoTextBase* pRange = comphelper::getFromUnoTunnel<SvxUnoTextBase>(xText);
2497  if (pRange)
2498  {
2499  rSelection <<= pRange->createTextCursorBySelection(pOutlinerView->GetSelection());
2500  }
2501  }
2502 }
2503 
2504 /* check if we have a single selection and that single object likes
2505  to handle the mouse and keyboard events itself
2506 
2507  TODO: the selection controller should be queried from the
2508  object specific view contact. Currently this method only
2509  works for tables.
2510 */
2512 {
2514 
2515  if (mxSelectionController.is())
2516  {
2518  mxSelectionController->onSelectionHasChanged();
2519  }
2520 
2521  mxSelectionController.clear();
2522 
2523  const SdrMarkList& rMarkList = GetMarkedObjectList();
2524  if (rMarkList.GetMarkCount() != 1)
2525  return;
2526 
2527  const SdrObject* pObj(rMarkList.GetMark(0)->GetMarkedSdrObj());
2528  SdrView* pView(dynamic_cast<SdrView*>(this));
2529 
2530  // check for table
2531  if (pObj && pView && (pObj->GetObjInventor() == SdrInventor::Default)
2532  && (pObj->GetObjIdentifier() == SdrObjKind::Table))
2533  {
2535  *pView, static_cast<const sdr::table::SdrTableObj&>(*pObj), mxLastSelectionController);
2536 
2537  if (mxSelectionController.is())
2538  {
2539  mxLastSelectionController.clear();
2540  mxSelectionController->onSelectionHasChanged();
2541  }
2542  }
2543 }
2544 
2545 IMPL_LINK(SdrObjEditView, EndPasteOrDropHdl, PasteOrDropInfos*, pInfo, void)
2546 {
2547  OnEndPasteOrDrop(pInfo);
2548 }
2549 
2550 IMPL_LINK(SdrObjEditView, BeginPasteOrDropHdl, PasteOrDropInfos*, pInfo, void)
2551 {
2552  OnBeginPasteOrDrop(pInfo);
2553 }
2554 
2556 {
2557  // applications can derive from these virtual methods to do something before a drop or paste operation
2558 }
2559 
2561 {
2562  // applications can derive from these virtual methods to do something before a drop or paste operation
2563 }
2564 
2566 {
2567  sal_uInt16 nLevel = 0xFFFF;
2568  if (IsTextEdit())
2569  {
2571  "SdrObjEditView::GetAttributes(): mpTextEditOutlinerView=NULL");
2572  DBG_ASSERT(mpTextEditOutliner != nullptr,
2573  "SdrObjEditView::GetAttributes(): mpTextEditOutliner=NULL");
2575  {
2576  //start and end position
2578  sal_uInt16 nStartPara = ::std::min(aSelect.nStartPara, aSelect.nEndPara);
2579  sal_uInt16 nEndPara = ::std::max(aSelect.nStartPara, aSelect.nEndPara);
2580  //get level from each paragraph
2581  nLevel = 0;
2582  for (sal_uInt16 nPara = nStartPara; nPara <= nEndPara; nPara++)
2583  {
2584  sal_uInt16 nParaDepth
2585  = 1 << static_cast<sal_uInt16>(mpTextEditOutliner->GetDepth(nPara));
2586  if (!(nLevel & nParaDepth))
2587  nLevel += nParaDepth;
2588  }
2589  //reduce one level for Outliner Object
2590  //if( nLevel > 0 && GetTextEditObject()->GetObjIdentifier() == OBJ_OUTLINETEXT )
2591  // nLevel = nLevel >> 1;
2592  //no bullet paragraph selected
2593  if (nLevel == 0)
2594  nLevel = 0xFFFF;
2595  }
2596  }
2597  return nLevel;
2598 }
2599 
2601  SdrObjKind nObjectIdentifier)
2602 {
2603  if (nObjectInventor != SdrInventor::Default && nObjectInventor != SdrInventor::E3d)
2604  return false;
2605  switch (nObjectIdentifier)
2606  {
2607  case SdrObjKind::NONE:
2608  case SdrObjKind::Group:
2609  return false;
2610  case SdrObjKind::Line:
2611  case SdrObjKind::Rectangle:
2614  case SdrObjKind::CircleArc:
2615  case SdrObjKind::CircleCut:
2616  case SdrObjKind::Polygon:
2617  case SdrObjKind::PolyLine:
2618  case SdrObjKind::PathLine:
2619  case SdrObjKind::PathFill:
2624  case SdrObjKind::Text:
2625  case SdrObjKind::TitleText:
2627  case SdrObjKind::Graphic:
2628  case SdrObjKind::OLE2:
2629  case SdrObjKind::Table:
2630  return true;
2631  case SdrObjKind::Edge:
2632  case SdrObjKind::Caption:
2633  return false;
2634  case SdrObjKind::PathPoly:
2636  return true;
2637  case SdrObjKind::Page:
2638  case SdrObjKind::Measure:
2640  case SdrObjKind::UNO:
2641  return false;
2643  return true;
2644  default:
2645  return false;
2646  }
2647 }
2648 
2649 static const WhichRangesContainer& GetFormatRangeImpl(bool bTextOnly)
2650 {
2651  static const WhichRangesContainer gFull(
2654  SDRATTR_MISC_LAST, // table cell formats
2657 
2658  static const WhichRangesContainer gTextOnly(
2660  EE_CHAR_END>);
2661 
2662  return bTextOnly ? gTextOnly : gFull;
2663 }
2664 
2665 void SdrObjEditView::TakeFormatPaintBrush(std::shared_ptr<SfxItemSet>& rFormatSet)
2666 {
2667  const SdrMarkList& rMarkList = GetMarkedObjectList();
2668  if (rMarkList.GetMarkCount() <= 0)
2669  return;
2670 
2672 
2673  rFormatSet = std::make_shared<SfxItemSet>(GetModel()->GetItemPool(),
2674  GetFormatRangeImpl(pOLV != nullptr));
2675  if (pOLV)
2676  {
2677  rFormatSet->Put(pOLV->GetAttribs());
2678  }
2679  else
2680  {
2681  const bool bOnlyHardAttr = false;
2682  rFormatSet->Put(GetAttrFromMarked(bOnlyHardAttr));
2683  }
2684 
2685  // check for cloning from table cell, in which case we need to copy cell-specific formatting attributes
2686  const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
2687  if (pObj && (pObj->GetObjInventor() == SdrInventor::Default)
2688  && (pObj->GetObjIdentifier() == SdrObjKind::Table))
2689  {
2690  auto pTable = static_cast<const sdr::table::SdrTableObj*>(pObj);
2691  if (mxSelectionController.is() && pTable->getActiveCell().is())
2692  {
2693  mxSelectionController->GetAttributes(*rFormatSet, false);
2694  }
2695  }
2696 }
2697 
2699  const SfxItemSet& rSourceSet, const SfxItemSet& rTargetSet,
2700  bool bNoCharacterFormats, bool bNoParagraphFormats)
2701 {
2702  SfxItemSet aPaintSet(rPool, pRanges);
2703 
2704  for (const auto& pRange : pRanges)
2705  {
2706  sal_uInt16 nWhich = pRange.first;
2707  const sal_uInt16 nLastWhich = pRange.second;
2708 
2709  if (bNoCharacterFormats && (nWhich == EE_CHAR_START))
2710  continue;
2711 
2712  if (bNoParagraphFormats && (nWhich == EE_PARA_START))
2713  continue;
2714 
2715  for (; nWhich < nLastWhich; nWhich++)
2716  {
2717  const SfxPoolItem* pSourceItem = rSourceSet.GetItem(nWhich);
2718  const SfxPoolItem* pTargetItem = rTargetSet.GetItem(nWhich);
2719 
2720  if ((pSourceItem && !pTargetItem)
2721  || (pSourceItem && pTargetItem && *pSourceItem != *pTargetItem))
2722  {
2723  aPaintSet.Put(*pSourceItem);
2724  }
2725  }
2726  }
2727  return aPaintSet;
2728 }
2729 
2731  SdrText* pText, bool bNoCharacterFormats,
2732  bool bNoParagraphFormats)
2733 {
2734  OutlinerParaObject* pParaObj = pText ? pText->GetOutlinerParaObject() : nullptr;
2735  if (!pParaObj)
2736  return;
2737 
2738  SdrOutliner& rOutliner = rTextObj.ImpGetDrawOutliner();
2739  rOutliner.SetText(*pParaObj);
2740 
2741  sal_Int32 nParaCount(rOutliner.GetParagraphCount());
2742 
2743  if (!nParaCount)
2744  return;
2745 
2746  for (sal_Int32 nPara = 0; nPara < nParaCount; nPara++)
2747  {
2748  if (!bNoCharacterFormats)
2749  rOutliner.RemoveCharAttribs(nPara);
2750 
2751  SfxItemSet aSet(rOutliner.GetParaAttribs(nPara));
2752  aSet.Put(CreatePaintSet(GetFormatRangeImpl(true), *aSet.GetPool(), rFormatSet, aSet,
2753  bNoCharacterFormats, bNoParagraphFormats));
2754  rOutliner.SetParaAttribs(nPara, aSet);
2755  }
2756 
2757  std::optional<OutlinerParaObject> pTemp = rOutliner.CreateParaObject(0, nParaCount);
2758  rOutliner.Clear();
2759 
2760  rTextObj.NbcSetOutlinerParaObjectForText(std::move(pTemp), pText);
2761 }
2762 
2764 {
2765  if (mpTextEditOutliner)
2766  {
2767  if (typeid(mpTextEditOutliner->GetUndoManager()) != typeid(EditUndoManager))
2768  {
2769  // Non-owning pointer, clear it.
2770  mpTextEditOutliner->SetUndoManager(nullptr);
2771  }
2772  }
2773 
2774  mpOldTextEditUndoManager = nullptr;
2775 }
2776 
2777 void SdrObjEditView::ApplyFormatPaintBrush(SfxItemSet& rFormatSet, bool bNoCharacterFormats,
2778  bool bNoParagraphFormats)
2779 {
2780  if (mxSelectionController.is()
2781  && mxSelectionController->ApplyFormatPaintBrush(rFormatSet, bNoCharacterFormats,
2782  bNoParagraphFormats))
2783  {
2784  return;
2785  }
2786 
2788  const SdrMarkList& rMarkList = GetMarkedObjectList();
2789  if (!pOLV)
2790  {
2791  SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
2792  const SfxItemSet& rShapeSet = pObj->GetMergedItemSet();
2793 
2794  // if not in text edit mode (aka the user selected text or clicked on a word)
2795  // apply formatting attributes to selected shape
2796  // All formatting items (see ranges above) that are unequal in selected shape and
2797  // the format paintbrush are hard set on the selected shape.
2798 
2799  const WhichRangesContainer& pRanges = rFormatSet.GetRanges();
2800  bool bTextOnly = true;
2801 
2802  for (const auto& pRange : pRanges)
2803  {
2804  if ((pRange.first != EE_PARA_START) && (pRange.first != EE_CHAR_START))
2805  {
2806  bTextOnly = false;
2807  break;
2808  }
2809  }
2810 
2811  if (!bTextOnly)
2812  {
2813  SfxItemSet aPaintSet(CreatePaintSet(GetFormatRangeImpl(false), *rShapeSet.GetPool(),
2814  rFormatSet, rShapeSet, bNoCharacterFormats,
2815  bNoParagraphFormats));
2816  SetAttrToMarked(aPaintSet, false /*bReplaceAll*/);
2817  }
2818 
2819  // now apply character and paragraph formatting to text, if the shape has any
2820  SdrTextObj* pTextObj = dynamic_cast<SdrTextObj*>(pObj);
2821  if (pTextObj)
2822  {
2823  sal_Int32 nText = pTextObj->getTextCount();
2824 
2825  while (--nText >= 0)
2826  {
2827  SdrText* pText = pTextObj->getText(nText);
2828  ApplyFormatPaintBrushToText(rFormatSet, *pTextObj, pText, bNoCharacterFormats,
2829  bNoParagraphFormats);
2830  }
2831  }
2832  }
2833  else
2834  {
2835  ::Outliner* pOutliner = pOLV->GetOutliner();
2836  if (pOutliner)
2837  {
2838  const EditEngine& rEditEngine = pOutliner->GetEditEngine();
2839 
2840  ESelection aSel(pOLV->GetSelection());
2841  if (!aSel.HasRange())
2842  pOLV->SetSelection(rEditEngine.GetWord(aSel, css::i18n::WordType::DICTIONARY_WORD));
2843 
2844  const bool bRemoveParaAttribs = !bNoParagraphFormats;
2845  pOLV->RemoveAttribsKeepLanguages(bRemoveParaAttribs);
2846  SfxItemSet aSet(pOLV->GetAttribs());
2847  SfxItemSet aPaintSet(CreatePaintSet(GetFormatRangeImpl(true), *aSet.GetPool(),
2848  rFormatSet, aSet, bNoCharacterFormats,
2849  bNoParagraphFormats));
2850  pOLV->SetAttribs(aPaintSet);
2851  }
2852  }
2853 
2854  // check for cloning to table cell, in which case we need to copy cell-specific formatting attributes
2855  SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
2856  if (pObj && (pObj->GetObjInventor() == SdrInventor::Default)
2857  && (pObj->GetObjIdentifier() == SdrObjKind::Table))
2858  {
2859  auto pTable = static_cast<sdr::table::SdrTableObj*>(pObj);
2860  if (pTable->getActiveCell().is() && mxSelectionController.is())
2861  {
2862  mxSelectionController->SetAttributes(rFormatSet, false);
2863  }
2864  }
2865 }
2866 
2867 /* 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:2374
bool IsMacroHit(const SdrObjMacroHitRec &rRec) const
Definition: svdobj.cxx:1896
void ImpPaintOutlinerView(OutlinerView &rOutlView, const tools::Rectangle &rRect, OutputDevice &rTargetDevice) const
Definition: svdedxv.cxx:746
virtual void OnEndPasteOrDrop(PasteOrDropInfos *pInfo)
Definition: svdedxv.cxx:2560
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:353
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:2353
virtual const tools::Rectangle & GetCurrentBoundRect() const
Definition: svdobj.cxx:958
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:1423
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:1306
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:376
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:396
SfxStyleSheet * GetStyleSheet() const
Definition: svdedxv.cxx:2296
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:1064
void ShowCursor(bool bGotoCursor=true, bool bActivate=false)
tools::Rectangle GetVisArea() const
ESelection const & GetPostChainingSel(const SdrTextObj *)
Definition: textchain.cxx:60
MouseEventModifiers GetMode() const
long Long
void DisposeUndoManager()
Definition: svdedxv.cxx:2763
void ImpMakeTextCursorAreaVisible()
Definition: svdedxv.cxx:2061
void ImpChainingEventHdl()
Definition: svdedxv.cxx:922
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:743
virtual void BckAction() override
Definition: svdmrkv.cxx:323
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:729
SdrMark * GetMark(size_t nNum) const
Definition: svdmark.cxx:230
constexpr sal_uInt16 EE_PARA_END(EE_PARA_START+18)
sal_Int32 GetParagraphCount() const
void append(std::unique_ptr< OverlayObject > pOverlayObject)
virtual OUString TakeObjNameSingul() const override
Definition: svdotext.cxx:994
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:1927
void EnableMapMode(bool bEnable=true)
open free-hand line
open Bezier-curve
virtual void BrkAction() override
Definition: svdmrkv.cxx:331
virtual SdrObjKind GetObjIdentifier() const
Definition: svdobj.cxx:660
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:1696
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:2511
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:2600
closed free-hand line
virtual bool HasText() const override
Definition: svdotxat.cxx:417
std::unique_ptr< BaseProcessor2D > createProcessor2DFromOutputDevice(OutputDevice &rTargetOutDev, const drawinglayer::geometry::ViewInformation2D &rViewInformation2D)
OutputDevice * GetRefDevice() const
Definition: svdmodel.hxx:333
static SfxItemSet CreatePaintSet(const WhichRangesContainer &pRanges, SfxItemPool &rPool, const SfxItemSet &rSourceSet, const SfxItemSet &rTargetSet, bool bNoCharacterFormats, bool bNoParagraphFormats)
Definition: svdedxv.cxx:2698
SdrObjKind
Definition: svdobjkind.hxx:24
virtual bool MouseMove(const MouseEvent &rMEvt, OutputDevice *pWin) override
handle mouse over effects for handles
Definition: svdmrkv.cxx:1613
virtual std::unique_ptr< SdrUndoAction > CreateUndoDeleteObject(SdrObject &rObject, bool bOrdNumDirect=false)
Definition: svdundo.cxx:1694
virtual bool MouseButtonUp(const MouseEvent &rMEvt, OutputDevice *pWin) override
Definition: svdedxv.cxx:1889
TextChain * GetTextChain() const
Definition: svdotext.cxx:1462
SdrModel * mpModel
Definition: svdpntv.hxx:125
OutlinerParaObject * GetOutlinerParaObject()
Definition: svdtext.cxx:89
EVControlBits GetControlWord() const
sal_uInt16 GetClicks() const
Color const & GetBackgroundColor() const
void SetAttrToMarked(const SfxItemSet &rAttr, bool bReplaceAll)
Definition: svdedtv1.cxx:1039
const Size & GetSize() const
const SfxPoolItem * NextItem()
bool IsTextEditFrameHit(const Point &rHit) const
Definition: svdedxv.cxx:1756
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:270
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:2730
virtual css::uno::Reference< css::drawing::XShape > getUnoShape()
Definition: svdobj.cxx:2865
static SfxViewShell * Current()
SfxStyleSheet * GetStyleSheet() const
Definition: svdobj.cxx:2228
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:2381
virtual SvtScriptType GetScriptType() const
Definition: svdedxv.cxx:2077
tools::Long AdjustBottom(tools::Long nVertMoveDelta)
virtual void SetChanged(bool bFlg=true)
Definition: svdmodel.cxx:1155
SfxStyleSheet * GetStyleSheet() const
Definition: svdedtv1.cxx:1327
void SetAttributes(const SfxItemSet &rSet, bool bReplaceAll)
Definition: svdedtv1.cxx:1318
B2IRange fround(const B2DRange &rRange)
virtual Point EditViewPointerPosPixel() const override
Definition: svdedxv.cxx:663
void SetParaAttribs(sal_Int32 nPara, const SfxItemSet &)
void EndUndo()
Definition: svdedtv.cxx:303
natural cubic Spline (ni)
bool equal(const B2DRange &rRange) const
EditView & GetEditView() const
constexpr bool IsEmpty() const
sal_uInt32 PaintWindowCount() const
Definition: svdpntv.hxx:218
virtual void BckAction() override
Definition: svdedxv.cxx:116
const Point & GetPos() const
IMPL_LINK_NOARG(SdrObjEditView, ImpAfterCutOrPasteChainingEventHdl, LinkParamNone *, void)
Definition: svdedxv.cxx:991
void TextEditDrawing(SdrPaintWindow &rPaintWindow)
Definition: svdedxv.cxx:696
virtual bool KeyInput(const KeyEvent &rKEvt, vcl::Window *pWin)
Definition: svdpntv.cxx:779
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
SvtScriptType
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:2479
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:287
virtual void TakeActionRect(tools::Rectangle &rRect) const override
Definition: svdedxv.cxx:209
size_t GetMarkedObjectCount() const
Definition: svdmrkv.hxx:258
void MergeNotPersistAttrFromMarked(SfxItemSet &rAttr) const
Definition: svdedtv1.cxx:772
virtual void EndAction() override
Definition: svdmrkv.cxx:305
void HandleCursorEventAfterChaining(const CursorChainingEvent aCurEvt, const ESelection &aNewSel)
virtual void MakeVisible(const tools::Rectangle &rRect, vcl::Window &rWin)
Definition: svdpntv.cxx:1006
virtual std::unique_ptr< SdrUndoManager > createLocalTextUndoManager()
Definition: svdedxv.cxx:1065
virtual bool IsAction() const override
Definition: svdmrkv.cxx:282
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
css::uno::Reference< css::datatransfer::dnd::XDropTarget > GetDropTarget()
const SdrMarkList & GetMarkedObjectList() const
Definition: svdmrkv.hxx:252
virtual bool KeyInput(const KeyEvent &rKEvt, vcl::Window *pWin) override
Definition: svdedxv.cxx:1810
void CompleteOnlineSpelling()
bool IsTextEditHit(const Point &rHit) const
Definition: svdedxv.cxx:1733
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:1071
void ActionChanged() const
Definition: svdobj.cxx:264
constexpr tools::Long Right() const
constexpr sal_uInt16 XATTR_FILL_FIRST(XATTRSET_LINE+1)
void SetFillColor()
constexpr sal_uInt16 EE_ITEMS_START(OWN_ATTR_VALUE_END+1)
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:2021
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:280
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:901
virtual void TakeTextAnchorRect(::tools::Rectangle &rAnchorRect) const
Definition: svdotext.cxx:667
virtual bool HasMacro() const
Definition: svdobj.cxx:1854
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
void reset(reference_type *pReference)
bool ImpIsTextEditAllSelected() const
Definition: svdedxv.cxx:2028
static const WhichRangesContainer & GetFormatRangeImpl(bool bTextOnly)
Definition: svdedxv.cxx:2649
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:384
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:2016
virtual void PaintMacro(OutputDevice &rOut, const tools::Rectangle &rDirtyRect, const SdrObjMacroHitRec &rRec) const
Definition: svdobj.cxx:1874
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:1781
void GrabFocus()
bool getPossibleGridOffsetForSdrObject(basegfx::B2DVector &rOffset, const SdrObject *pObj, const SdrPageView *pPV) const
Definition: svdmrkv.cxx:2174
SfxItemPool * GetPool() const
virtual SdrObject * RemoveObject(size_t nObjNum)
Definition: svdpage.cxx:409
const EditEngine & GetEditEngine() const
SdrUndoFactory & GetSdrUndoFactory() const
returns the models undo factory.
Definition: svdmodel.cxx:1857
Polyline represented by SdrPathObj.
bool EndMacroObj()
Definition: svdedxv.cxx:2454
void SetCursorRect(const tools::Rectangle *pRect=nullptr, tools::Long nExtTextInputWidth=0)
void ImpMacroDown(const Point &rDownPos)
Definition: svdedxv.cxx:2412
virtual bool MouseButtonDown(const MouseEvent &rMEvt, OutputDevice *pWin) override
Definition: svdedxv.cxx:1845
virtual SdrInventor GetObjInventor() const
Definition: svdobj.cxx:655
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:679
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:2565
void MovMacroObj(const Point &rPnt)
Definition: svdedxv.cxx:2426
bool IsSet(SdrLayerID a) const
Definition: svdsob.hxx:64
rectangle (round corners optional)
bool IsMapModeEnabled() const
std::unique_ptr< TextChainCursorManager > ImpHandleMotionThroughBoxesKeyInput(const KeyEvent &rKEvt, bool *bOutHandled)
Definition: svdedxv.cxx:1787
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:1336
OverlayObject & getOverlayObject(sal_uInt32 nIndex) const
void ImpMoveCursorAfterChainingEvent(TextChainCursorManager *pCursorManager)
Definition: svdedxv.cxx:1001
bool HasFill() const
Definition: svdoattr.cxx:90
SfxItemState
virtual bool IsTextEdit() const final override
Definition: svdedxv.cxx:1691
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:1694
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:339
vcl::Cursor * pTextEditCursorBuffer
Definition: svdedxv.hxx:89
Color GetTextEditBackgroundColor(const SdrObjEditView &rView)
Definition: svdetc.cxx:674
#define SAL_INFO(area, stream)
virtual ~SdrObjEditView() override
Definition: svdedxv.cxx:90
const SfxItemSet & GetMergedItemSet() const
Definition: svdobj.cxx:1981
virtual bool Command(const CommandEvent &rCEvt, vcl::Window *pWin) override
Definition: svdedxv.cxx:1970
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:333
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:2565
SdrPaintWindow & GetPaintWindow() const
void SetTextEditWin(vcl::Window *pWin)
Definition: svdedxv.cxx:1713
SfxItemSet GetAttrFromMarked(bool bOnlyHardAttr) const
Definition: svdedtv1.cxx:879
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:2341
SfxUndoManager * mpOldTextEditUndoManager
Definition: svdedxv.hxx:111
const Point & GetPosPixel() const
SdrObject * GetMarkedObjectByIndex(size_t nNum) const
Definition: svdmrkv.hxx:257
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:2148
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:1891
SdrObjList * getParentSdrObjListFromSdrObject() const
Definition: svdobj.cxx:306
void Clear()
OUString ImpGetDescriptionString(TranslateId pStrCacheID, ImpGetDescriptionOptions nOpt=ImpGetDescriptionOptions::NONE) const
Definition: svdmrkv.cxx:2607
void SetStyleSheet(SfxStyleSheet *pStyleSheet, bool bDontRemoveHardAttr)
Definition: svdedxv.cxx:2317
virtual void OnBeginPasteOrDrop(PasteOrDropInfos *pInfo)
Definition: svdedxv.cxx:2555
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:858
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:2777
closed Bezier-curve
constexpr sal_uInt16 SDRATTR_MISC_FIRST(SDRATTR_CAPTION_LAST+1)
void ImpMacroUp(const Point &rUpPos)
Definition: svdedxv.cxx:2398
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
void GetAttributes(SfxItemSet &rTargetSet, bool bOnlyHardAttr) const
Definition: svdedxv.cxx:2111
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:910
void BrkMacroObj()
Definition: svdedxv.cxx:2443
virtual void HideSdrPage() override
Definition: svdmrkv.cxx:358
SdrMarkList & GetMarkedObjectListWriteAccess()
Definition: svdmrkv.hxx:248
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:1840
SdrOutliner & ImpGetDrawOutliner() const
Definition: svdotext.cxx:1164
void CheckMarked()
Definition: svdmrkv.cxx:1786
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
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:2665
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:831
void Paint(const tools::Rectangle &rRect, OutputDevice *pTargetDevice=nullptr)