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