LibreOffice Module svx (master)  1
svdedtv2.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 <svx/svdedtv.hxx>
21 #include <editeng/outliner.hxx>
22 #include <svx/svdundo.hxx>
23 #include <svx/svdogrp.hxx>
24 #include <svx/svdoutl.hxx>
25 #include <svx/svdovirt.hxx>
26 #include <svx/svdopath.hxx>
27 #include <svx/svdpage.hxx>
28 #include <svx/svdpagv.hxx>
29 #include <svx/svditer.hxx>
30 #include <svx/svdograf.hxx>
31 #include <svx/svdoole2.hxx>
32 #include <svx/dialmgr.hxx>
33 #include <svx/sdooitm.hxx>
34 #include <svx/sdshitm.hxx>
35 #include <svx/xfillit0.hxx>
36 #include <svx/xlineit0.hxx>
37 #include <svx/xtextit0.hxx>
38 #include "svdfmtf.hxx"
39 #include "svdpdf.hxx"
40 #include <svx/svdetc.hxx>
41 #include <sfx2/basedlgs.hxx>
42 #include <editeng/outlobj.hxx>
43 #include <editeng/eeitem.hxx>
46 #include <svx/svxdlg.hxx>
47 #include <svx/strings.hrc>
48 #include <svx/svdoashp.hxx>
50 #include <i18nutil/unicode.hxx>
51 #include <sal/log.hxx>
52 #include <tools/debug.hxx>
53 #include <memory>
54 #include <vector>
55 
56 using ::std::vector;
57 using namespace com::sun::star;
58 
60 {
61  return nullptr;
62 }
63 
65 {
66  return nullptr;
67 }
68 
69 void SdrEditView::ObjOrderChanged(SdrObject* /*pObj*/, size_t /*nOldPos*/, size_t /*nNewPos*/)
70 {
71 }
72 
74 {
75  const size_t nCount=GetMarkedObjectCount();
76  if (nCount!=0)
77  {
78  const bool bUndo = IsUndoEnabled();
79 
80  if( bUndo )
81  BegUndo(SvxResId(STR_EditMovToTop),GetDescriptionOfMarkedObjects(),SdrRepeatFunc::MoveToTop);
82 
83  SortMarkedObjects();
84  for (size_t nm=0; nm<nCount; ++nm)
85  { // All Ordnums have to be correct!
86  GetMarkedObjectByIndex(nm)->GetOrdNum();
87  }
88  bool bChg=false;
89  SdrObjList* pOL0=nullptr;
90  size_t nNewPos=0;
91  for (size_t nm=nCount; nm>0;)
92  {
93  --nm;
94  SdrMark* pM=GetSdrMarkByIndex(nm);
95  SdrObject* pObj=pM->GetMarkedSdrObj();
97  if (pOL!=pOL0)
98  {
99  nNewPos = pOL->GetObjCount()-1;
100  pOL0=pOL;
101  }
102  const size_t nNowPos = pObj->GetOrdNumDirect();
103  const tools::Rectangle& rBR=pObj->GetCurrentBoundRect();
104  size_t nCmpPos = nNowPos+1;
105  SdrObject* pMaxObj=GetMaxToTopObj(pObj);
106  if (pMaxObj!=nullptr)
107  {
108  size_t nMaxPos=pMaxObj->GetOrdNum();
109  if (nMaxPos!=0)
110  nMaxPos--;
111  if (nNewPos>nMaxPos)
112  nNewPos=nMaxPos; // neither go faster...
113  if (nNewPos<nNowPos)
114  nNewPos=nNowPos; // nor go in the other direction
115  }
116  bool bEnd=false;
117  while (nCmpPos<nNewPos && !bEnd)
118  {
119  SdrObject* pCmpObj=pOL->GetObj(nCmpPos);
120  if (pCmpObj==nullptr)
121  {
122  OSL_FAIL("MovMarkedToTop(): Reference object not found.");
123  bEnd=true;
124  }
125  else if (pCmpObj==pMaxObj)
126  {
127  nNewPos=nCmpPos;
128  nNewPos--;
129  bEnd=true;
130  }
131  else if (rBR.IsOver(pCmpObj->GetCurrentBoundRect()))
132  {
133  nNewPos=nCmpPos;
134  bEnd=true;
135  }
136  else
137  {
138  nCmpPos++;
139  }
140  }
141  if (nNowPos!=nNewPos)
142  {
143  bChg=true;
144  pOL->SetObjectOrdNum(nNowPos,nNewPos);
145  if( bUndo )
146  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj,nNowPos,nNewPos));
147  ObjOrderChanged(pObj,nNowPos,nNewPos);
148  }
149  nNewPos--;
150  }
151 
152  if( bUndo )
153  EndUndo();
154 
155  if (bChg)
156  MarkListHasChanged();
157  }
158 }
159 
161 {
162  const size_t nCount=GetMarkedObjectCount();
163  if (nCount!=0)
164  {
165  const bool bUndo = IsUndoEnabled();
166 
167  if( bUndo )
168  BegUndo(SvxResId(STR_EditMovToBtm),GetDescriptionOfMarkedObjects(),SdrRepeatFunc::MoveToBottom);
169 
170  SortMarkedObjects();
171  for (size_t nm=0; nm<nCount; ++nm)
172  { // All Ordnums have to be correct!
173  GetMarkedObjectByIndex(nm)->GetOrdNum();
174  }
175 
176  bool bChg=false;
177  SdrObjList* pOL0=nullptr;
178  size_t nNewPos=0;
179  for (size_t nm=0; nm<nCount; ++nm)
180  {
181  SdrMark* pM=GetSdrMarkByIndex(nm);
182  SdrObject* pObj=pM->GetMarkedSdrObj();
184  if (pOL!=pOL0)
185  {
186  nNewPos=0;
187  pOL0=pOL;
188  }
189  const size_t nNowPos = pObj->GetOrdNumDirect();
190  const tools::Rectangle& rBR=pObj->GetCurrentBoundRect();
191  size_t nCmpPos = nNowPos;
192  if (nCmpPos>0)
193  --nCmpPos;
194  SdrObject* pMaxObj=GetMaxToBtmObj(pObj);
195  if (pMaxObj!=nullptr)
196  {
197  const size_t nMinPos=pMaxObj->GetOrdNum()+1;
198  if (nNewPos<nMinPos)
199  nNewPos=nMinPos; // neither go faster...
200  if (nNewPos>nNowPos)
201  nNewPos=nNowPos; // nor go in the other direction
202  }
203  bool bEnd=false;
204  // nNewPos in this case is the "maximum" position
205  // the object may reach without going faster than the object before
206  // it (multiple selection).
207  while (nCmpPos>nNewPos && !bEnd)
208  {
209  SdrObject* pCmpObj=pOL->GetObj(nCmpPos);
210  if (pCmpObj==nullptr)
211  {
212  OSL_FAIL("MovMarkedToBtm(): Reference object not found.");
213  bEnd=true;
214  }
215  else if (pCmpObj==pMaxObj)
216  {
217  nNewPos=nCmpPos;
218  nNewPos++;
219  bEnd=true;
220  }
221  else if (rBR.IsOver(pCmpObj->GetCurrentBoundRect()))
222  {
223  nNewPos=nCmpPos;
224  bEnd=true;
225  }
226  else
227  {
228  nCmpPos--;
229  }
230  }
231  if (nNowPos!=nNewPos)
232  {
233  bChg=true;
234  pOL->SetObjectOrdNum(nNowPos,nNewPos);
235  if( bUndo )
236  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj,nNowPos,nNewPos));
237  ObjOrderChanged(pObj,nNowPos,nNewPos);
238  }
239  nNewPos++;
240  }
241 
242  if(bUndo)
243  EndUndo();
244 
245  if(bChg)
246  MarkListHasChanged();
247  }
248 }
249 
251 {
252  PutMarkedInFrontOfObj(nullptr);
253 }
254 
256 {
257  const size_t nCount=GetMarkedObjectCount();
258  if (nCount==0)
259  return;
260 
261  const bool bUndo = IsUndoEnabled();
262  if( bUndo )
263  BegUndo(SvxResId(STR_EditPutToTop),GetDescriptionOfMarkedObjects(),SdrRepeatFunc::PutToTop);
264 
265  SortMarkedObjects();
266 
267  if (pRefObj!=nullptr)
268  {
269  // Make "in front of the object" work, even if the
270  // selected objects are already in front of the other object
271  const size_t nRefMark=TryToFindMarkedObject(pRefObj);
272  SdrMark aRefMark;
273  if (nRefMark!=SAL_MAX_SIZE)
274  {
275  aRefMark=*GetSdrMarkByIndex(nRefMark);
276  GetMarkedObjectListWriteAccess().DeleteMark(nRefMark);
277  }
278  PutMarkedToBtm();
279  if (nRefMark!=SAL_MAX_SIZE)
280  {
281  GetMarkedObjectListWriteAccess().InsertEntry(aRefMark);
282  SortMarkedObjects();
283  }
284  }
285  for (size_t nm=0; nm<nCount; ++nm)
286  { // All Ordnums have to be correct!
287  GetMarkedObjectByIndex(nm)->GetOrdNum();
288  }
289  bool bChg=false;
290  SdrObjList* pOL0=nullptr;
291  size_t nNewPos=0;
292  for (size_t nm=nCount; nm>0;)
293  {
294  --nm;
295  SdrMark* pM=GetSdrMarkByIndex(nm);
296  SdrObject* pObj=pM->GetMarkedSdrObj();
297  if (pObj!=pRefObj)
298  {
300  if (pOL!=pOL0)
301  {
302  nNewPos=pOL->GetObjCount()-1;
303  pOL0=pOL;
304  }
305  const size_t nNowPos=pObj->GetOrdNumDirect();
306  SdrObject* pMaxObj=GetMaxToTopObj(pObj);
307  if (pMaxObj!=nullptr)
308  {
309  size_t nMaxOrd=pMaxObj->GetOrdNum(); // sadly doesn't work any other way
310  if (nMaxOrd>0)
311  nMaxOrd--;
312  if (nNewPos>nMaxOrd)
313  nNewPos=nMaxOrd; // neither go faster...
314  if (nNewPos<nNowPos)
315  nNewPos=nNowPos; // nor go into the other direction
316  }
317  if (pRefObj!=nullptr)
318  {
320  {
321  const size_t nMaxOrd=pRefObj->GetOrdNum(); // sadly doesn't work any other way
322  if (nNewPos>nMaxOrd)
323  nNewPos=nMaxOrd; // neither go faster...
324  if (nNewPos<nNowPos)
325  nNewPos=nNowPos; // nor go into the other direction
326  }
327  else
328  {
329  nNewPos=nNowPos; // different PageView, so don't change
330  }
331  }
332  if (nNowPos!=nNewPos)
333  {
334  bChg=true;
335  pOL->SetObjectOrdNum(nNowPos,nNewPos);
336  if( bUndo )
337  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj,nNowPos,nNewPos));
338  ObjOrderChanged(pObj,nNowPos,nNewPos);
339  }
340  nNewPos--;
341  } // if (pObj!=pRefObj)
342  } // for loop over all selected objects
343 
344  if( bUndo )
345  EndUndo();
346 
347  if(bChg)
348  MarkListHasChanged();
349 }
350 
352 {
353  PutMarkedBehindObj(nullptr);
354 }
355 
357 {
358  const size_t nCount=GetMarkedObjectCount();
359  if (nCount==0)
360  return;
361 
362  const bool bUndo = IsUndoEnabled();
363 
364  if( bUndo )
365  BegUndo(SvxResId(STR_EditPutToBtm),GetDescriptionOfMarkedObjects(),SdrRepeatFunc::PutToBottom);
366 
367  SortMarkedObjects();
368  if (pRefObj!=nullptr)
369  {
370  // Make "behind the object" work, even if the
371  // selected objects are already behind the other object
372  const size_t nRefMark=TryToFindMarkedObject(pRefObj);
373  SdrMark aRefMark;
374  if (nRefMark!=SAL_MAX_SIZE)
375  {
376  aRefMark=*GetSdrMarkByIndex(nRefMark);
377  GetMarkedObjectListWriteAccess().DeleteMark(nRefMark);
378  }
379  PutMarkedToTop();
380  if (nRefMark!=SAL_MAX_SIZE)
381  {
382  GetMarkedObjectListWriteAccess().InsertEntry(aRefMark);
383  SortMarkedObjects();
384  }
385  }
386  for (size_t nm=0; nm<nCount; ++nm) { // All Ordnums have to be correct!
387  GetMarkedObjectByIndex(nm)->GetOrdNum();
388  }
389  bool bChg=false;
390  SdrObjList* pOL0=nullptr;
391  size_t nNewPos=0;
392  for (size_t nm=0; nm<nCount; ++nm) {
393  SdrMark* pM=GetSdrMarkByIndex(nm);
394  SdrObject* pObj=pM->GetMarkedSdrObj();
395  if (pObj!=pRefObj) {
397  if (pOL!=pOL0) {
398  nNewPos=0;
399  pOL0=pOL;
400  }
401  const size_t nNowPos=pObj->GetOrdNumDirect();
402  SdrObject* pMinObj=GetMaxToBtmObj(pObj);
403  if (pMinObj!=nullptr) {
404  const size_t nMinOrd=pMinObj->GetOrdNum()+1; // sadly doesn't work any differently
405  if (nNewPos<nMinOrd) nNewPos=nMinOrd; // neither go faster...
406  if (nNewPos>nNowPos) nNewPos=nNowPos; // nor go into the other direction
407  }
408  if (pRefObj!=nullptr) {
410  const size_t nMinOrd=pRefObj->GetOrdNum(); // sadly doesn't work any differently
411  if (nNewPos<nMinOrd) nNewPos=nMinOrd; // neither go faster...
412  if (nNewPos>nNowPos) nNewPos=nNowPos; // nor go into the other direction
413  } else {
414  nNewPos=nNowPos; // different PageView, so don't change
415  }
416  }
417  if (nNowPos!=nNewPos) {
418  bChg=true;
419  pOL->SetObjectOrdNum(nNowPos,nNewPos);
420  if( bUndo )
421  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj,nNowPos,nNewPos));
422  ObjOrderChanged(pObj,nNowPos,nNewPos);
423  }
424  nNewPos++;
425  } // if (pObj!=pRefObj)
426  } // for loop over all selected objects
427 
428  if(bUndo)
429  EndUndo();
430 
431  if(bChg)
432  MarkListHasChanged();
433 
434 }
435 
437 {
438  SortMarkedObjects();
439  const size_t nMarkCount=GetMarkedObjectCount();
440  if (nMarkCount>0)
441  {
442  bool bChg=false;
443 
444  bool bUndo = IsUndoEnabled();
445  if( bUndo )
446  BegUndo(SvxResId(STR_EditRevOrder),GetDescriptionOfMarkedObjects(),SdrRepeatFunc::ReverseOrder);
447 
448  size_t a=0;
449  do {
450  // take into account selection across multiple PageViews
451  size_t b=a+1;
452  while (b<nMarkCount && GetSdrPageViewOfMarkedByIndex(b) == GetSdrPageViewOfMarkedByIndex(a)) ++b;
453  --b;
454  SdrObjList* pOL=GetSdrPageViewOfMarkedByIndex(a)->GetObjList();
455  size_t c=b;
456  if (a<c) { // make sure OrdNums aren't dirty
457  GetMarkedObjectByIndex(a)->GetOrdNum();
458  }
459  while (a<c) {
460  SdrObject* pObj1=GetMarkedObjectByIndex(a);
461  SdrObject* pObj2=GetMarkedObjectByIndex(c);
462  const size_t nOrd1=pObj1->GetOrdNumDirect();
463  const size_t nOrd2=pObj2->GetOrdNumDirect();
464  if( bUndo )
465  {
466  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj1,nOrd1,nOrd2));
467  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj2,nOrd2-1,nOrd1));
468  }
469  pOL->SetObjectOrdNum(nOrd1,nOrd2);
470  // Obj 2 has moved forward by one position, so now nOrd2-1
471  pOL->SetObjectOrdNum(nOrd2-1,nOrd1);
472  // use Replace instead of SetOrdNum for performance reasons (recalculation of Ordnums)
473  ++a;
474  --c;
475  bChg=true;
476  }
477  a=b+1;
478  } while (a<nMarkCount);
479 
480  if(bUndo)
481  EndUndo();
482 
483  if(bChg)
484  MarkListHasChanged();
485  }
486 }
487 
489 {
490  const size_t nCount=GetMarkedObjectCount();
491  if (nCount==0)
492  return;
493  if (nCount==1)
494  { // special-casing for single selection
495  SdrObject* pObj=GetMarkedObjectByIndex(0);
497  SAL_WARN_IF(!pOL, "svx", "Object somehow has no ObjList");
498  size_t nMax = pOL ? pOL->GetObjCount() : 0;
499  size_t nMin = 0;
500  const size_t nObjNum=pObj->GetOrdNum();
501  SdrObject* pRestrict=GetMaxToTopObj(pObj);
502  if (pRestrict!=nullptr) {
503  const size_t nRestrict=pRestrict->GetOrdNum();
504  if (nRestrict<nMax) nMax=nRestrict;
505  }
506  pRestrict=GetMaxToBtmObj(pObj);
507  if (pRestrict!=nullptr) {
508  const size_t nRestrict=pRestrict->GetOrdNum();
509  if (nRestrict>nMin) nMin=nRestrict;
510  }
511  m_bToTopPossible=nObjNum<nMax-1;
512  m_bToBtmPossible=nObjNum>nMin;
513  } else { // multiple selection
514  SdrObjList* pOL0=nullptr;
515  size_t nPos0 = 0;
516  for (size_t nm = 0; !m_bToBtmPossible && nm<nCount; ++nm) { // check 'send to background'
517  SdrObject* pObj=GetMarkedObjectByIndex(nm);
519  if (pOL!=pOL0) {
520  nPos0 = 0;
521  pOL0=pOL;
522  }
523  const size_t nPos = pObj->GetOrdNum();
524  m_bToBtmPossible = nPos && (nPos-1 > nPos0);
525  nPos0 = nPos;
526  }
527 
528  pOL0=nullptr;
529  nPos0 = SAL_MAX_SIZE;
530  for (size_t nm=nCount; !m_bToTopPossible && nm>0; ) { // check 'bring to front'
531  --nm;
532  SdrObject* pObj=GetMarkedObjectByIndex(nm);
534  if (pOL!=pOL0) {
535  nPos0=pOL->GetObjCount();
536  pOL0=pOL;
537  }
538  const size_t nPos = pObj->GetOrdNum();
539  m_bToTopPossible = nPos+1 < nPos0;
540  nPos0=nPos;
541  }
542  }
543 }
544 
545 
546 // Combine
547 
548 
549 void SdrEditView::ImpCopyAttributes(const SdrObject* pSource, SdrObject* pDest) const
550 {
551  if (pSource!=nullptr) {
552  SdrObjList* pOL=pSource->GetSubList();
553  if (pOL!=nullptr && !pSource->Is3DObj()) { // get first non-group object from group
555  pSource=aIter.Next();
556  }
557  }
558 
559  if(pSource && pDest)
560  {
561  SfxItemSet aSet(mpModel->GetItemPool(),
565 
566  aSet.Put(pSource->GetMergedItemSet());
567 
568  pDest->ClearMergedItem();
569  pDest->SetMergedItemSet(aSet);
570 
571  pDest->NbcSetLayer(pSource->GetLayer());
572  pDest->NbcSetStyleSheet(pSource->GetStyleSheet(), true);
573  }
574 }
575 
577 {
578  // new condition IsLine() to be able to combine simple Lines
579  bool bIsLine(false);
580 
581  const SdrPathObj* pPath = dynamic_cast< const SdrPathObj*>( pObj );
582 
583  if(pPath)
584  {
585  bIsLine = pPath->IsLine();
586  }
587 
589  pObj->TakeObjInfo(aInfo);
590 
591  return (aInfo.bCanConvToPath || aInfo.bCanConvToPoly || bIsLine);
592 }
593 
595 {
596  SdrObjList* pOL = pObj->GetSubList();
597 
598  if(pOL && !pObj->Is3DObj())
599  {
601 
602  while(aIter.IsMore())
603  {
604  SdrObject* pObj1 = aIter.Next();
605 
606  // all members of a group have to be convertible
607  if(!ImpCanConvertForCombine1(pObj1))
608  {
609  return false;
610  }
611  }
612  }
613  else
614  {
615  if(!ImpCanConvertForCombine1(pObj))
616  {
617  return false;
618  }
619  }
620 
621  return true;
622 }
623 
625 {
626  basegfx::B2DPolyPolygon aRetval;
627  const SdrPathObj* pPath = dynamic_cast<const SdrPathObj*>( pObj );
628 
629  if(pPath && !pObj->GetOutlinerParaObject())
630  {
631  aRetval = pPath->GetPathPoly();
632  }
633  else
634  {
635  SdrObjectUniquePtr pConvObj = pObj->ConvertToPolyObj(true/*bCombine*/, false);
636 
637  if(pConvObj)
638  {
639  SdrObjList* pOL = pConvObj->GetSubList();
640 
641  if(pOL)
642  {
644 
645  while(aIter.IsMore())
646  {
647  SdrObject* pObj1 = aIter.Next();
648  pPath = dynamic_cast<SdrPathObj*>( pObj1 );
649 
650  if(pPath)
651  {
652  aRetval.append(pPath->GetPathPoly());
653  }
654  }
655  }
656  else
657  {
658  pPath = dynamic_cast<SdrPathObj*>( pConvObj.get() );
659 
660  if(pPath)
661  {
662  aRetval = pPath->GetPathPoly();
663  }
664  }
665  }
666  }
667 
668  return aRetval;
669 }
670 
672 {
673  SdrObjList* pOL = pObj->GetSubList();
674 
675  if(pOL && !pObj->Is3DObj())
676  {
677  basegfx::B2DPolyPolygon aRetval;
679 
680  while(aIter.IsMore())
681  {
682  SdrObject* pObj1 = aIter.Next();
683  aRetval.append(ImpGetPolyPolygon1(pObj1));
684  }
685 
686  return aRetval;
687  }
688  else
689  {
690  return ImpGetPolyPolygon1(pObj);
691  }
692 }
693 
695 {
696  const sal_uInt32 nPolyCount(rPolyPolygon.count());
697 
698  if(0 == nPolyCount)
699  {
700  return basegfx::B2DPolygon();
701  }
702  else if(1 == nPolyCount)
703  {
704  return rPolyPolygon.getB2DPolygon(0);
705  }
706  else
707  {
708  basegfx::B2DPolygon aRetval(rPolyPolygon.getB2DPolygon(0));
709 
710  for(sal_uInt32 a(1); a < nPolyCount; a++)
711  {
712  basegfx::B2DPolygon aCandidate(rPolyPolygon.getB2DPolygon(a));
713 
714  if(aRetval.count())
715  {
716  if(aCandidate.count())
717  {
718  const basegfx::B2DPoint aCA(aCandidate.getB2DPoint(0));
719  const basegfx::B2DPoint aCB(aCandidate.getB2DPoint(aCandidate.count() - 1));
720  const basegfx::B2DPoint aRA(aRetval.getB2DPoint(0));
721  const basegfx::B2DPoint aRB(aRetval.getB2DPoint(aRetval.count() - 1));
722 
723  const double fRACA(basegfx::B2DVector(aCA - aRA).getLength());
724  const double fRACB(basegfx::B2DVector(aCB - aRA).getLength());
725  const double fRBCA(basegfx::B2DVector(aCA - aRB).getLength());
726  const double fRBCB(basegfx::B2DVector(aCB - aRB).getLength());
727 
728  const double fSmallestRA(std::min(fRACA, fRACB));
729  const double fSmallestRB(std::min(fRBCA, fRBCB));
730 
731  if(fSmallestRA < fSmallestRB)
732  {
733  // flip result
734  aRetval.flip();
735  }
736 
737  const double fSmallestCA(std::min(fRACA, fRBCA));
738  const double fSmallestCB(std::min(fRACB, fRBCB));
739 
740  if(fSmallestCB < fSmallestCA)
741  {
742  // flip candidate
743  aCandidate.flip();
744  }
745 
746  // append candidate to retval
747  aRetval.append(aCandidate);
748  }
749  }
750  else
751  {
752  aRetval = aCandidate;
753  }
754  }
755 
756  return aRetval;
757  }
758 }
759 
760 namespace {
761 
762 // for distribution dialog function
763 struct ImpDistributeEntry
764 {
765  SdrObject* mpObj;
766  sal_Int32 mnPos;
767  sal_Int32 mnLength;
768 };
769 
770 }
771 
772 typedef vector<ImpDistributeEntry> ImpDistributeEntryList;
773 
775 {
776  const size_t nMark(GetMarkedObjectCount());
777 
778  if(nMark > 2)
779  {
780  SfxItemSet aNewAttr(mpModel->GetItemPool());
781 
783  ScopedVclPtr<AbstractSvxDistributeDialog> pDlg(pFact->CreateSvxDistributeDialog(pParent, aNewAttr));
784 
785  sal_uInt16 nResult = pDlg->Execute();
786 
787  if(nResult == RET_OK)
788  {
789  SvxDistributeHorizontal eHor = pDlg->GetDistributeHor();
790  SvxDistributeVertical eVer = pDlg->GetDistributeVer();
791  ImpDistributeEntryList aEntryList;
792  ImpDistributeEntryList::iterator itEntryList;
793  sal_uInt32 nFullLength;
794 
795  const bool bUndo = IsUndoEnabled();
796  if( bUndo )
797  BegUndo();
798 
800  {
801  // build sorted entry list
802  nFullLength = 0;
803 
804  for( size_t a = 0; a < nMark; ++a )
805  {
806  SdrMark* pMark = GetSdrMarkByIndex(a);
807  ImpDistributeEntry aNew;
808 
809  aNew.mpObj = pMark->GetMarkedSdrObj();
810 
811  switch(eHor)
812  {
814  {
815  aNew.mnPos = aNew.mpObj->GetSnapRect().Left();
816  break;
817  }
819  {
820  aNew.mnPos = (aNew.mpObj->GetSnapRect().Right() + aNew.mpObj->GetSnapRect().Left()) / 2;
821  break;
822  }
824  {
825  aNew.mnLength = aNew.mpObj->GetSnapRect().GetWidth() + 1;
826  nFullLength += aNew.mnLength;
827  aNew.mnPos = (aNew.mpObj->GetSnapRect().Right() + aNew.mpObj->GetSnapRect().Left()) / 2;
828  break;
829  }
831  {
832  aNew.mnPos = aNew.mpObj->GetSnapRect().Right();
833  break;
834  }
835  default: break;
836  }
837 
838  itEntryList = std::find_if(aEntryList.begin(), aEntryList.end(),
839  [&aNew](const ImpDistributeEntry& rEntry) { return rEntry.mnPos >= aNew.mnPos; });
840  if ( itEntryList < aEntryList.end() )
841  aEntryList.insert( itEntryList, aNew );
842  else
843  aEntryList.push_back( aNew );
844  }
845 
847  {
848  // calculate room in-between
849  sal_Int32 nWidth = GetAllMarkedBoundRect().GetWidth() + 1;
850  double fStepWidth = (static_cast<double>(nWidth) - static_cast<double>(nFullLength)) / static_cast<double>(aEntryList.size() - 1);
851  double fStepStart = static_cast<double>(aEntryList[ 0 ].mnPos);
852  fStepStart += fStepWidth + static_cast<double>((aEntryList[ 0 ].mnLength + aEntryList[ 1 ].mnLength) / 2);
853 
854  // move entries 1..n-1
855  for( size_t i = 1, n = aEntryList.size()-1; i < n; ++i )
856  {
857  ImpDistributeEntry& rCurr = aEntryList[ i ];
858  ImpDistributeEntry& rNext = aEntryList[ i + 1];
859  sal_Int32 nDelta = static_cast<sal_Int32>(fStepStart + 0.5) - rCurr.mnPos;
860  if( bUndo )
861  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*rCurr.mpObj));
862  rCurr.mpObj->Move(Size(nDelta, 0));
863  fStepStart += fStepWidth + static_cast<double>((rCurr.mnLength + rNext.mnLength) / 2);
864  }
865  }
866  else
867  {
868  // calculate distances
869  sal_Int32 nWidth = aEntryList[ aEntryList.size() - 1 ].mnPos - aEntryList[ 0 ].mnPos;
870  double fStepWidth = static_cast<double>(nWidth) / static_cast<double>(aEntryList.size() - 1);
871  double fStepStart = static_cast<double>(aEntryList[ 0 ].mnPos);
872  fStepStart += fStepWidth;
873 
874  // move entries 1..n-1
875  for( size_t i = 1 ; i < aEntryList.size()-1 ; ++i )
876  {
877  ImpDistributeEntry& rCurr = aEntryList[ i ];
878  sal_Int32 nDelta = static_cast<sal_Int32>(fStepStart + 0.5) - rCurr.mnPos;
879  if( bUndo )
880  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*rCurr.mpObj));
881  rCurr.mpObj->Move(Size(nDelta, 0));
882  fStepStart += fStepWidth;
883  }
884  }
885 
886  // clear list
887  aEntryList.clear();
888  }
889 
890  if(eVer != SvxDistributeVertical::NONE)
891  {
892  // build sorted entry list
893  nFullLength = 0;
894 
895  for( size_t a = 0; a < nMark; ++a )
896  {
897  SdrMark* pMark = GetSdrMarkByIndex(a);
898  ImpDistributeEntry aNew;
899 
900  aNew.mpObj = pMark->GetMarkedSdrObj();
901 
902  switch(eVer)
903  {
905  {
906  aNew.mnPos = aNew.mpObj->GetSnapRect().Top();
907  break;
908  }
910  {
911  aNew.mnPos = (aNew.mpObj->GetSnapRect().Bottom() + aNew.mpObj->GetSnapRect().Top()) / 2;
912  break;
913  }
915  {
916  aNew.mnLength = aNew.mpObj->GetSnapRect().GetHeight() + 1;
917  nFullLength += aNew.mnLength;
918  aNew.mnPos = (aNew.mpObj->GetSnapRect().Bottom() + aNew.mpObj->GetSnapRect().Top()) / 2;
919  break;
920  }
922  {
923  aNew.mnPos = aNew.mpObj->GetSnapRect().Bottom();
924  break;
925  }
926  default: break;
927  }
928 
929  itEntryList = std::find_if(aEntryList.begin(), aEntryList.end(),
930  [&aNew](const ImpDistributeEntry& rEntry) { return rEntry.mnPos >= aNew.mnPos; });
931  if ( itEntryList < aEntryList.end() )
932  aEntryList.insert( itEntryList, aNew );
933  else
934  aEntryList.push_back( aNew );
935  }
936 
938  {
939  // calculate room in-between
940  sal_Int32 nHeight = GetAllMarkedBoundRect().GetHeight() + 1;
941  double fStepWidth = (static_cast<double>(nHeight) - static_cast<double>(nFullLength)) / static_cast<double>(aEntryList.size() - 1);
942  double fStepStart = static_cast<double>(aEntryList[ 0 ].mnPos);
943  fStepStart += fStepWidth + static_cast<double>((aEntryList[ 0 ].mnLength + aEntryList[ 1 ].mnLength) / 2);
944 
945  // move entries 1..n-1
946  for( size_t i = 1, n = aEntryList.size()-1; i < n; ++i)
947  {
948  ImpDistributeEntry& rCurr = aEntryList[ i ];
949  ImpDistributeEntry& rNext = aEntryList[ i + 1 ];
950  sal_Int32 nDelta = static_cast<sal_Int32>(fStepStart + 0.5) - rCurr.mnPos;
951  if( bUndo )
952  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*rCurr.mpObj));
953  rCurr.mpObj->Move(Size(0, nDelta));
954  fStepStart += fStepWidth + static_cast<double>((rCurr.mnLength + rNext.mnLength) / 2);
955  }
956  }
957  else
958  {
959  // calculate distances
960  sal_Int32 nHeight = aEntryList[ aEntryList.size() - 1 ].mnPos - aEntryList[ 0 ].mnPos;
961  double fStepWidth = static_cast<double>(nHeight) / static_cast<double>(aEntryList.size() - 1);
962  double fStepStart = static_cast<double>(aEntryList[ 0 ].mnPos);
963  fStepStart += fStepWidth;
964 
965  // move entries 1..n-1
966  for(size_t i = 1, n = aEntryList.size()-1; i < n; ++i)
967  {
968  ImpDistributeEntry& rCurr = aEntryList[ i ];
969  sal_Int32 nDelta = static_cast<sal_Int32>(fStepStart + 0.5) - rCurr.mnPos;
970  if( bUndo )
971  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*rCurr.mpObj));
972  rCurr.mpObj->Move(Size(0, nDelta));
973  fStepStart += fStepWidth;
974  }
975  }
976 
977  // clear list
978  aEntryList.clear();
979  }
980 
981  // UNDO-Comment and end of UNDO
982  mpModel->SetUndoComment(SvxResId(STR_DistributeMarkedObjects));
983 
984  if( bUndo )
985  EndUndo();
986  }
987  }
988 }
989 
991 {
992  // #i73441# check content
993  if(!AreObjectsMarked())
994  return;
995 
996  SdrMarkList aRemove;
997  SortMarkedObjects();
998 
999  const bool bUndo = IsUndoEnabled();
1000 
1001  if( bUndo )
1002  BegUndo();
1003 
1004  size_t nInsPos = SAL_MAX_SIZE;
1005  const SdrObject* pAttrObj = nullptr;
1006  basegfx::B2DPolyPolygon aMergePolyPolygonA;
1007  basegfx::B2DPolyPolygon aMergePolyPolygonB;
1008 
1009  SdrObjList* pInsOL = nullptr;
1010  SdrPageView* pInsPV = nullptr;
1011  bool bFirstObjectComplete(false);
1012 
1013  // make sure selected objects are contour objects
1014  // since now basegfx::utils::adaptiveSubdivide() is used, it is no longer
1015  // necessary to use ConvertMarkedToPolyObj which will subdivide curves using the old
1016  // mechanisms. In a next step the polygon clipper will even be able to clip curves...
1017  // ConvertMarkedToPolyObj(true);
1018  ConvertMarkedToPathObj(true);
1019  OSL_ENSURE(AreObjectsMarked(), "no more objects selected after preparations (!)");
1020 
1021  for(size_t a=0; a<GetMarkedObjectCount(); ++a)
1022  {
1023  SdrMark* pM = GetSdrMarkByIndex(a);
1024  SdrObject* pObj = pM->GetMarkedSdrObj();
1025 
1026  if(ImpCanConvertForCombine(pObj))
1027  {
1028  if(!pAttrObj)
1029  pAttrObj = pObj;
1030 
1031  nInsPos = pObj->GetOrdNum() + 1;
1032  pInsPV = pM->GetPageView();
1033  pInsOL = pObj->getParentSdrObjListFromSdrObject();
1034 
1035  // #i76891# use single iteration from SJ here which works on SdrObjects and takes
1036  // groups into account by itself
1038 
1039  while(aIter.IsMore())
1040  {
1041  SdrObject* pCandidate = aIter.Next();
1042  SdrPathObj* pPathObj = dynamic_cast<SdrPathObj*>( pCandidate );
1043  if(pPathObj)
1044  {
1045  basegfx::B2DPolyPolygon aTmpPoly(pPathObj->GetPathPoly());
1046 
1047  // #i76891# unfortunately ConvertMarkedToPathObj has converted all
1048  // involved polygon data to curve segments, even if not necessary.
1049  // It is better to try to reduce to more simple polygons.
1050  aTmpPoly = basegfx::utils::simplifyCurveSegments(aTmpPoly);
1051 
1052  // for each part polygon as preparation, remove self-intersections
1053  // correct orientations and get rid of possible neutral polygons.
1054  aTmpPoly = basegfx::utils::prepareForPolygonOperation(aTmpPoly);
1055 
1056  if(!bFirstObjectComplete)
1057  {
1058  // #i111987# Also need to collect ORed source shape when more than
1059  // a single polygon is involved
1060  if(aMergePolyPolygonA.count())
1061  {
1062  aMergePolyPolygonA = basegfx::utils::solvePolygonOperationOr(aMergePolyPolygonA, aTmpPoly);
1063  }
1064  else
1065  {
1066  aMergePolyPolygonA = aTmpPoly;
1067  }
1068  }
1069  else
1070  {
1071  if(aMergePolyPolygonB.count())
1072  {
1073  // to topologically correctly collect the 2nd polygon
1074  // group it is necessary to OR the parts (each is seen as
1075  // XOR-FillRule polygon and they are drawn over each-other)
1076  aMergePolyPolygonB = basegfx::utils::solvePolygonOperationOr(aMergePolyPolygonB, aTmpPoly);
1077  }
1078  else
1079  {
1080  aMergePolyPolygonB = aTmpPoly;
1081  }
1082  }
1083  }
1084  }
1085 
1086  // was there something added to the first polygon?
1087  if(!bFirstObjectComplete && aMergePolyPolygonA.count())
1088  {
1089  bFirstObjectComplete = true;
1090  }
1091 
1092  // move object to temporary delete list
1093  aRemove.InsertEntry(SdrMark(pObj, pM->GetPageView()));
1094  }
1095  }
1096 
1097  switch(eMode)
1098  {
1099  case SdrMergeMode::Merge:
1100  {
1101  // merge all contained parts (OR)
1102  aMergePolyPolygonA = basegfx::utils::solvePolygonOperationOr(aMergePolyPolygonA, aMergePolyPolygonB);
1103  break;
1104  }
1106  {
1107  // Subtract B from A
1108  aMergePolyPolygonA = basegfx::utils::solvePolygonOperationDiff(aMergePolyPolygonA, aMergePolyPolygonB);
1109  break;
1110  }
1112  {
1113  // AND B and A
1114  aMergePolyPolygonA = basegfx::utils::solvePolygonOperationAnd(aMergePolyPolygonA, aMergePolyPolygonB);
1115  break;
1116  }
1117  }
1118 
1119  // #i73441# check insert list before taking actions
1120  if(pInsOL)
1121  {
1122  SdrPathObj* pPath = new SdrPathObj(pAttrObj->getSdrModelFromSdrObject(), OBJ_PATHFILL, aMergePolyPolygonA);
1123  ImpCopyAttributes(pAttrObj, pPath);
1124  pInsOL->InsertObject(pPath, nInsPos);
1125  if( bUndo )
1126  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pPath));
1127 
1128  // #i124760# To have a correct selection with only the new object it is necessary to
1129  // unmark all objects first. If not doing so, there may remain invalid pointers to objects
1130  // TTTT:Not needed for aw080 (!)
1131  UnmarkAllObj(pInsPV);
1132 
1133  MarkObj(pPath, pInsPV, false, true);
1134  }
1135 
1136  aRemove.ForceSort();
1137  switch(eMode)
1138  {
1139  case SdrMergeMode::Merge:
1140  {
1141  SetUndoComment(
1142  SvxResId(STR_EditMergeMergePoly),
1143  aRemove.GetMarkDescription());
1144  break;
1145  }
1147  {
1148  SetUndoComment(
1149  SvxResId(STR_EditMergeSubstractPoly),
1150  aRemove.GetMarkDescription());
1151  break;
1152  }
1154  {
1155  SetUndoComment(
1156  SvxResId(STR_EditMergeIntersectPoly),
1157  aRemove.GetMarkDescription());
1158  break;
1159  }
1160  }
1161  DeleteMarkedList(aRemove);
1162 
1163  if( bUndo )
1164  EndUndo();
1165 }
1166 
1168 {
1169  const SdrMarkList& rMarkList = GetMarkedObjectList();
1170  size_t nMarked = rMarkList.GetMarkCount();
1171 
1172  if (nMarked < 2)
1173  return;
1174 
1175  size_t nLastSelected = 0;
1176  sal_Int64 nLastSelectedTime = rMarkList.GetMark(0)->getTimeStamp();
1177  for (size_t a = 1; a < nMarked; ++a)
1178  {
1179  sal_Int64 nCandidateTime = rMarkList.GetMark(a)->getTimeStamp();
1180  if (nCandidateTime > nLastSelectedTime)
1181  {
1182  nLastSelectedTime = nCandidateTime;
1183  nLastSelected = a;
1184  }
1185  }
1186 
1187  SdrObject* pLastSelectedObj = rMarkList.GetMark(nLastSelected)->GetMarkedSdrObj();
1188  Size aLastRectSize(pLastSelectedObj->GetLogicRect().GetSize());
1189 
1190  const bool bUndo = IsUndoEnabled();
1191 
1192  if (bUndo)
1193  BegUndo();
1194 
1195  for (size_t a = 0; a < nMarked; ++a)
1196  {
1197  if (a == nLastSelected)
1198  continue;
1199  SdrMark* pM = rMarkList.GetMark(a);
1200  SdrObject* pObj = pM->GetMarkedSdrObj();
1201  tools::Rectangle aLogicRect(pObj->GetLogicRect());
1202  Size aLogicRectSize(aLogicRect.GetSize());
1203  if (bWidth)
1204  aLogicRectSize.setWidth( aLastRectSize.Width() );
1205  else
1206  aLogicRectSize.setHeight( aLastRectSize.Height() );
1207  aLogicRect.SetSize(aLogicRectSize);
1208  if (bUndo)
1209  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
1210  pObj->SetLogicRect(aLogicRect);
1211  }
1212 
1213  SetUndoComment(
1214  SvxResId(bWidth ? STR_EqualizeWidthMarkedObjects : STR_EqualizeHeightMarkedObjects),
1215  rMarkList.GetMarkDescription());
1216 
1217  if (bUndo)
1218  EndUndo();
1219 }
1220 
1222 {
1223  SdrPageView* pPageView = GetSdrPageView();
1224  if ( !pPageView || pPageView->IsLayerLocked( GetActiveLayer() ) )
1225  return;
1226 
1227  bool bUndo = IsUndoEnabled();
1228 
1229  // Undo-String will be set later
1230  if ( bUndo )
1231  BegUndo();
1232 
1233  SdrOutliner& rDrawOutliner = getSdrModelFromSdrView().GetDrawOutliner();
1234 
1235  SdrObjListIter aIter( GetMarkedObjectList(), SdrIterMode::Flat);
1236  while ( aIter.IsMore() )
1237  {
1238  SdrObject* pObj = aIter.Next();
1239  SdrTextObj* pTextObj = dynamic_cast<SdrTextObj*>( pObj );
1240  const OutlinerParaObject* pOPO = pTextObj ? pTextObj->GetOutlinerParaObject() : nullptr;
1241  if ( pOPO && pTextObj->IsTextFrame()
1242  && pTextObj->GetObjIdentifier() == OBJ_TEXT // not callouts (OBJ_CAPTION)
1243  && !pTextObj->IsOutlText() // not impress presentation objects
1244  && pTextObj->GetMergedItem(XATTR_FORMTXTSTYLE).GetValue() == XFormTextStyle::NONE // not Fontwork
1245  )
1246  {
1247  // if the last paragraph does not end in paragraph-end punctuation (ignoring whitespace),
1248  // assume this text should be added to the end of the last paragraph, instead of starting a new paragraph.
1249  const sal_Int32 nPara = rDrawOutliner.GetParagraphCount();
1250  const OUString sLastPara = nPara ? rDrawOutliner.GetText( rDrawOutliner.GetParagraph( nPara - 1 ) ) : "";
1251  sal_Int32 n = sLastPara.getLength();
1252  while ( n && unicode::isWhiteSpace( sLastPara[--n] ) )
1253  ;
1254  //TODO: find way to use Locale to identify sentence final punctuation. Copied IsSentenceAtEnd() from autofmt.cxx
1255  const bool bAppend = !n || ( sLastPara[n] != '.' && sLastPara[n] != '?' && sLastPara[n] != '!' );
1256  rDrawOutliner.AddText( *pOPO, bAppend );
1257  }
1258  else
1259  {
1260  // Unmark non-textboxes, because all marked objects are deleted at the end. AdjustMarkHdl later.
1261  MarkObj(pObj, pPageView, /*bUnmark=*/true, /*bImpNoSetMarkHdl=*/true);
1262  }
1263  }
1264 
1265  MarkListHasChanged();
1266  AdjustMarkHdl();
1267 
1268  if ( GetMarkedObjectCount() > 1 )
1269  {
1270  SdrRectObj* pReplacement = new SdrRectObj( getSdrModelFromSdrView(), OBJ_TEXT );
1271  pReplacement->SetOutlinerParaObject( rDrawOutliner.CreateParaObject() );
1272  pReplacement->SetSnapRect( GetMarkedObjRect() );
1273 
1275  if ( InsertObjectAtView( pReplacement, *pPageView, nFlags ) )
1276  DeleteMarkedObj();
1277  }
1278 
1279  if ( bUndo )
1280  EndUndo();
1281 
1282  return;
1283 }
1284 
1286 {
1287  // #105899# Start of Combine-Undo put to front, else ConvertMarkedToPolyObj would
1288  // create a 2nd Undo-action and Undo-Comment.
1289 
1290  bool bUndo = IsUndoEnabled();
1291 
1292  // Undo-String will be set later
1293  if( bUndo )
1294  BegUndo("", "", bNoPolyPoly ? SdrRepeatFunc::CombineOnePoly : SdrRepeatFunc::CombinePolyPoly);
1295 
1296  // #105899# First, guarantee that all objects are converted to polyobjects,
1297  // especially for SdrGrafObj with bitmap filling this is necessary to not
1298  // lose the bitmap filling.
1299 
1300  // #i12392#
1301  // ConvertMarkedToPolyObj was too strong here, it will lose quality and
1302  // information when curve objects are combined. This can be replaced by
1303  // using ConvertMarkedToPathObj without changing the previous fix.
1304 
1305  // #i21250#
1306  // Instead of simply passing true as LineToArea, use bNoPolyPoly as info
1307  // if this command is a 'Combine' or a 'Connect' command. On Connect it's true.
1308  // To not concert line segments with a set line width to polygons in that case,
1309  // use this info. Do not convert LineToArea on Connect commands.
1310  // ConvertMarkedToPathObj(!bNoPolyPoly);
1311 
1312  // This is used for Combine and Connect. In no case it is necessary to force
1313  // the content to curve, but it is also not good to force to polygons. Thus,
1314  // curve is the less information losing one. Remember: This place is not
1315  // used for merge.
1316  // LineToArea is never necessary, both commands are able to take over the
1317  // set line style and to display it correctly. Thus, i will use a
1318  // ConvertMarkedToPathObj with a false in any case. Only drawback is that
1319  // simple polygons will be changed to curves, but with no information loss.
1320  ConvertMarkedToPathObj(false /* bLineToArea */);
1321 
1322  // continue as before
1323  basegfx::B2DPolyPolygon aPolyPolygon;
1324  SdrObjList* pCurrentOL = nullptr;
1325  SdrMarkList aRemoveBuffer;
1326 
1327  SortMarkedObjects();
1328  size_t nInsPos = SAL_MAX_SIZE;
1329  SdrObjList* pInsOL = nullptr;
1330  SdrPageView* pInsPV = nullptr;
1331  const SdrObject* pAttrObj = nullptr;
1332 
1333  for(size_t a = GetMarkedObjectCount(); a; )
1334  {
1335  --a;
1336  SdrMark* pM = GetSdrMarkByIndex(a);
1337  SdrObject* pObj = pM->GetMarkedSdrObj();
1338  SdrObjList* pThisOL = pObj->getParentSdrObjListFromSdrObject();
1339 
1340  if(pCurrentOL != pThisOL)
1341  {
1342  pCurrentOL = pThisOL;
1343  }
1344 
1345  if(ImpCanConvertForCombine(pObj))
1346  {
1347  // remember objects to be able to copy attributes
1348  pAttrObj = pObj;
1349 
1350  // unfortunately ConvertMarkedToPathObj has converted all
1351  // involved polygon data to curve segments, even if not necessary.
1352  // It is better to try to reduce to more simple polygons.
1353  basegfx::B2DPolyPolygon aTmpPoly(basegfx::utils::simplifyCurveSegments(ImpGetPolyPolygon(pObj)));
1354  aPolyPolygon.insert(0L, aTmpPoly);
1355 
1356  if(!pInsOL)
1357  {
1358  nInsPos = pObj->GetOrdNum() + 1;
1359  pInsPV = pM->GetPageView();
1360  pInsOL = pObj->getParentSdrObjListFromSdrObject();
1361  }
1362 
1363  aRemoveBuffer.InsertEntry(SdrMark(pObj, pM->GetPageView()));
1364  }
1365  }
1366 
1367  if(bNoPolyPoly)
1368  {
1369  basegfx::B2DPolygon aCombinedPolygon(ImpCombineToSinglePolygon(aPolyPolygon));
1370  aPolyPolygon.clear();
1371  aPolyPolygon.append(aCombinedPolygon);
1372  }
1373 
1374  const sal_uInt32 nPolyCount(aPolyPolygon.count());
1375 
1376  if (nPolyCount && pAttrObj)
1377  {
1378  SdrObjKind eKind = OBJ_PATHFILL;
1379 
1380  if(nPolyCount > 1)
1381  {
1382  aPolyPolygon.setClosed(true);
1383  }
1384  else
1385  {
1386  // check for Polyline
1387  const basegfx::B2DPolygon aPolygon(aPolyPolygon.getB2DPolygon(0));
1388  const sal_uInt32 nPointCount(aPolygon.count());
1389 
1390  if(nPointCount <= 2)
1391  {
1392  eKind = OBJ_PATHLINE;
1393  }
1394  else
1395  {
1396  if(!aPolygon.isClosed())
1397  {
1398  const basegfx::B2DPoint aPointA(aPolygon.getB2DPoint(0));
1399  const basegfx::B2DPoint aPointB(aPolygon.getB2DPoint(nPointCount - 1));
1400  const double fDistance(basegfx::B2DVector(aPointB - aPointA).getLength());
1401  const double fJoinTolerance(10.0);
1402 
1403  if(fDistance < fJoinTolerance)
1404  {
1405  aPolyPolygon.setClosed(true);
1406  }
1407  else
1408  {
1409  eKind = OBJ_PATHLINE;
1410  }
1411  }
1412  }
1413  }
1414 
1415  SdrPathObj* pPath = new SdrPathObj(pAttrObj->getSdrModelFromSdrObject(), eKind, aPolyPolygon);
1416 
1417  // attributes of the lowest object
1418  ImpCopyAttributes(pAttrObj, pPath);
1419 
1420  // If LineStyle of pAttrObj is drawing::LineStyle_NONE force to drawing::LineStyle_SOLID to make visible.
1421  const drawing::LineStyle eLineStyle = pAttrObj->GetMergedItem(XATTR_LINESTYLE).GetValue();
1422  const drawing::FillStyle eFillStyle = pAttrObj->GetMergedItem(XATTR_FILLSTYLE).GetValue();
1423 
1424  // Take fill style/closed state of pAttrObj in account when deciding to change the line style
1425  bool bIsClosedPathObj(dynamic_cast<const SdrPathObj*>( pAttrObj) != nullptr && static_cast<const SdrPathObj*>(pAttrObj)->IsClosed());
1426 
1427  if(drawing::LineStyle_NONE == eLineStyle && (drawing::FillStyle_NONE == eFillStyle || !bIsClosedPathObj))
1428  {
1429  pPath->SetMergedItem(XLineStyleItem(drawing::LineStyle_SOLID));
1430  }
1431 
1432  pInsOL->InsertObject(pPath,nInsPos);
1433  if( bUndo )
1434  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pPath));
1435 
1436  // Here was a severe error: Without UnmarkAllObj, the new object was marked
1437  // additionally to the two ones which are deleted below. As long as those are
1438  // in the UNDO there is no problem, but as soon as they get deleted, the
1439  // MarkList will contain deleted objects -> GPF.
1440  UnmarkAllObj(pInsPV);
1441  MarkObj(pPath, pInsPV, false, true);
1442  }
1443 
1444  // build an UndoComment from the objects actually used
1445  aRemoveBuffer.ForceSort(); // important for remove (see below)
1446  if( bUndo )
1447  SetUndoComment(SvxResId(bNoPolyPoly?STR_EditCombine_OnePoly:STR_EditCombine_PolyPoly),aRemoveBuffer.GetMarkDescription());
1448 
1449  // remove objects actually used from the list
1450  DeleteMarkedList(aRemoveBuffer);
1451  if( bUndo )
1452  EndUndo();
1453 }
1454 
1455 
1456 // Dismantle
1457 
1458 
1459 bool SdrEditView::ImpCanDismantle(const basegfx::B2DPolyPolygon& rPpolyPolygon, bool bMakeLines)
1460 {
1461  bool bCan(false);
1462  const sal_uInt32 nPolygonCount(rPpolyPolygon.count());
1463 
1464  if(nPolygonCount >= 2)
1465  {
1466  // #i69172# dismantle makes sense with 2 or more polygons in a polyPolygon
1467  bCan = true;
1468  }
1469  else if(bMakeLines && 1 == nPolygonCount)
1470  {
1471  // #i69172# ..or with at least 2 edges (curves or lines)
1472  const basegfx::B2DPolygon& aPolygon(rPpolyPolygon.getB2DPolygon(0));
1473  const sal_uInt32 nPointCount(aPolygon.count());
1474 
1475  if(nPointCount > 2)
1476  {
1477  bCan = true;
1478  }
1479  }
1480 
1481  return bCan;
1482 }
1483 
1484 bool SdrEditView::ImpCanDismantle(const SdrObject* pObj, bool bMakeLines)
1485 {
1486  bool bOtherObjs(false); // true=objects other than PathObj's existent
1487  bool bMin1PolyPoly(false); // true=at least 1 tools::PolyPolygon with more than one Polygon existent
1488  SdrObjList* pOL = pObj->GetSubList();
1489 
1490  if(pOL)
1491  {
1492  // group object -- check all members if they're PathObjs
1494 
1495  while(aIter.IsMore() && !bOtherObjs)
1496  {
1497  const SdrObject* pObj1 = aIter.Next();
1498  const SdrPathObj* pPath = dynamic_cast<const SdrPathObj*>( pObj1 );
1499 
1500  if(pPath)
1501  {
1502  if(ImpCanDismantle(pPath->GetPathPoly(), bMakeLines))
1503  {
1504  bMin1PolyPoly = true;
1505  }
1506 
1507  SdrObjTransformInfoRec aInfo;
1508  pObj1->TakeObjInfo(aInfo);
1509 
1510  if(!aInfo.bCanConvToPath)
1511  {
1512  // happens e. g. in the case of FontWork
1513  bOtherObjs = true;
1514  }
1515  }
1516  else
1517  {
1518  bOtherObjs = true;
1519  }
1520  }
1521  }
1522  else
1523  {
1524  const SdrPathObj* pPath = dynamic_cast<const SdrPathObj*>(pObj);
1525  const SdrObjCustomShape* pCustomShape = dynamic_cast<const SdrObjCustomShape*>(pObj);
1526 
1527  // #i37011#
1528  if(pPath)
1529  {
1530  if(ImpCanDismantle(pPath->GetPathPoly(),bMakeLines))
1531  {
1532  bMin1PolyPoly = true;
1533  }
1534 
1535  SdrObjTransformInfoRec aInfo;
1536  pObj->TakeObjInfo(aInfo);
1537 
1538  // new condition IsLine() to be able to break simple Lines
1539  if(!(aInfo.bCanConvToPath || aInfo.bCanConvToPoly) && !pPath->IsLine())
1540  {
1541  // happens e. g. in the case of FontWork
1542  bOtherObjs = true;
1543  }
1544  }
1545  else if(pCustomShape)
1546  {
1547  if(bMakeLines)
1548  {
1549  // allow break command
1550  bMin1PolyPoly = true;
1551  }
1552  }
1553  else
1554  {
1555  bOtherObjs = true;
1556  }
1557  }
1558  return bMin1PolyPoly && !bOtherObjs;
1559 }
1560 
1561 void SdrEditView::ImpDismantleOneObject(const SdrObject* pObj, SdrObjList& rOL, size_t& rPos, SdrPageView* pPV, bool bMakeLines)
1562 {
1563  const SdrPathObj* pSrcPath = dynamic_cast<const SdrPathObj*>( pObj );
1564  const SdrObjCustomShape* pCustomShape = dynamic_cast<const SdrObjCustomShape*>( pObj );
1565 
1566  const bool bUndo = IsUndoEnabled();
1567 
1568  if(pSrcPath)
1569  {
1570  // #i74631# redesigned due to XpolyPolygon removal and explicit constructors
1571  SdrObject* pLast = nullptr; // to be able to apply OutlinerParaObject
1572  const basegfx::B2DPolyPolygon& rPolyPolygon(pSrcPath->GetPathPoly());
1573  const sal_uInt32 nPolyCount(rPolyPolygon.count());
1574 
1575  for(sal_uInt32 a(0); a < nPolyCount; a++)
1576  {
1577  const basegfx::B2DPolygon& rCandidate(rPolyPolygon.getB2DPolygon(a));
1578  const sal_uInt32 nPointCount(rCandidate.count());
1579 
1580  if(!bMakeLines || nPointCount < 2)
1581  {
1582  SdrPathObj* pPath = new SdrPathObj(
1583  pSrcPath->getSdrModelFromSdrObject(),
1584  static_cast<SdrObjKind>(pSrcPath->GetObjIdentifier()),
1585  basegfx::B2DPolyPolygon(rCandidate));
1586  ImpCopyAttributes(pSrcPath, pPath);
1587  pLast = pPath;
1588  rOL.InsertObject(pPath, rPos);
1589  if( bUndo )
1590  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pPath, true));
1591  MarkObj(pPath, pPV, false, true);
1592  rPos++;
1593  }
1594  else
1595  {
1596  const sal_uInt32 nLoopCount(rCandidate.isClosed() ? nPointCount : nPointCount - 1);
1597 
1598  for(sal_uInt32 b(0); b < nLoopCount; b++)
1599  {
1600  SdrObjKind eKind(OBJ_PLIN);
1601  basegfx::B2DPolygon aNewPolygon;
1602  const sal_uInt32 nNextIndex((b + 1) % nPointCount);
1603 
1604  aNewPolygon.append(rCandidate.getB2DPoint(b));
1605 
1606  if(rCandidate.areControlPointsUsed())
1607  {
1608  aNewPolygon.appendBezierSegment(
1609  rCandidate.getNextControlPoint(b),
1610  rCandidate.getPrevControlPoint(nNextIndex),
1611  rCandidate.getB2DPoint(nNextIndex));
1612  eKind = OBJ_PATHLINE;
1613  }
1614  else
1615  {
1616  aNewPolygon.append(rCandidate.getB2DPoint(nNextIndex));
1617  }
1618 
1619  SdrPathObj* pPath = new SdrPathObj(
1620  pSrcPath->getSdrModelFromSdrObject(),
1621  eKind,
1622  basegfx::B2DPolyPolygon(aNewPolygon));
1623  ImpCopyAttributes(pSrcPath, pPath);
1624  pLast = pPath;
1625  rOL.InsertObject(pPath, rPos);
1626  if( bUndo )
1627  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pPath, true));
1628  MarkObj(pPath, pPV, false, true);
1629  rPos++;
1630  }
1631  }
1632  }
1633 
1634  if(pLast && pSrcPath->GetOutlinerParaObject())
1635  {
1636  pLast->SetOutlinerParaObject(std::make_unique<OutlinerParaObject>(*pSrcPath->GetOutlinerParaObject()));
1637  }
1638  }
1639  else if(pCustomShape)
1640  {
1641  if(bMakeLines)
1642  {
1643  // break up custom shape
1644  const SdrObject* pReplacement = pCustomShape->GetSdrObjectFromCustomShape();
1645 
1646  if(pReplacement)
1647  {
1648  SdrObject* pCandidate(pReplacement->CloneSdrObject(pReplacement->getSdrModelFromSdrObject()));
1649  DBG_ASSERT(pCandidate, "SdrEditView::ImpDismantleOneObject: Could not clone SdrObject (!)");
1650 
1651  if(pCustomShape->GetMergedItem(SDRATTR_SHADOW).GetValue())
1652  {
1653  if(dynamic_cast<const SdrObjGroup*>( pReplacement) != nullptr)
1654  {
1655  pCandidate->SetMergedItem(makeSdrShadowItem(true));
1656  }
1657  }
1658 
1659  rOL.InsertObject(pCandidate, rPos);
1660  if( bUndo )
1661  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pCandidate, true));
1662  MarkObj(pCandidate, pPV, false, true);
1663 
1664  if(pCustomShape->HasText() && !pCustomShape->IsTextPath())
1665  {
1666  // #i37011# also create a text object and add at rPos + 1
1668  pCustomShape->getSdrModelFromSdrObject(),
1669  pCustomShape->GetObjInventor(),
1670  OBJ_TEXT);
1671 
1672  // Copy text content
1673  OutlinerParaObject* pParaObj = pCustomShape->GetOutlinerParaObject();
1674  if(pParaObj)
1675  {
1676  pTextObj->NbcSetOutlinerParaObject(std::make_unique<OutlinerParaObject>(*pParaObj));
1677  }
1678 
1679  // copy all attributes
1680  SfxItemSet aTargetItemSet(pCustomShape->GetMergedItemSet());
1681 
1682  // clear fill and line style
1683  aTargetItemSet.Put(XLineStyleItem(drawing::LineStyle_NONE));
1684  aTargetItemSet.Put(XFillStyleItem(drawing::FillStyle_NONE));
1685 
1686  // get the text bounds and set at text object
1687  tools::Rectangle aTextBounds = pCustomShape->GetSnapRect();
1688  if(pCustomShape->GetTextBounds(aTextBounds))
1689  {
1690  pTextObj->SetSnapRect(aTextBounds);
1691  }
1692 
1693  // if rotated, copy GeoStat, too.
1694  const GeoStat& rSourceGeo = pCustomShape->GetGeoStat();
1695  if(rSourceGeo.nRotationAngle)
1696  {
1697  pTextObj->NbcRotate(
1698  pCustomShape->GetSnapRect().Center(), rSourceGeo.nRotationAngle,
1699  rSourceGeo.nSin, rSourceGeo.nCos);
1700  }
1701 
1702  // set modified ItemSet at text object
1703  pTextObj->SetMergedItemSet(aTargetItemSet);
1704 
1705  // insert object
1706  rOL.InsertObject(pTextObj, rPos + 1);
1707  if( bUndo )
1708  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pTextObj, true));
1709  MarkObj(pTextObj, pPV, false, true);
1710  }
1711  }
1712  }
1713  }
1714 }
1715 
1717 {
1718  // temporary MarkList
1719  SdrMarkList aRemoveBuffer;
1720 
1721  SortMarkedObjects();
1722 
1723  const bool bUndo = IsUndoEnabled();
1724 
1725  if( bUndo )
1726  {
1727  // comment is constructed later
1728  BegUndo("", "", bMakeLines ? SdrRepeatFunc::DismantleLines : SdrRepeatFunc::DismantlePolys);
1729  }
1730 
1731  SdrObjList* pOL0=nullptr;
1732  for (size_t nm=GetMarkedObjectCount(); nm>0;) {
1733  --nm;
1734  SdrMark* pM=GetSdrMarkByIndex(nm);
1735  SdrObject* pObj=pM->GetMarkedSdrObj();
1736  SdrPageView* pPV=pM->GetPageView();
1738  if (pOL!=pOL0) { pOL0=pOL; pObj->GetOrdNum(); } // make sure OrdNums are correct!
1739  if (ImpCanDismantle(pObj,bMakeLines)) {
1740  aRemoveBuffer.InsertEntry(SdrMark(pObj,pM->GetPageView()));
1741  const size_t nPos0=pObj->GetOrdNumDirect();
1742  size_t nPos=nPos0+1;
1743  SdrObjList* pSubList=pObj->GetSubList();
1744  if (pSubList!=nullptr && !pObj->Is3DObj()) {
1745  SdrObjListIter aIter(pSubList,SdrIterMode::DeepNoGroups);
1746  while (aIter.IsMore()) {
1747  const SdrObject* pObj1=aIter.Next();
1748  ImpDismantleOneObject(pObj1,*pOL,nPos,pPV,bMakeLines);
1749  }
1750  } else {
1751  ImpDismantleOneObject(pObj,*pOL,nPos,pPV,bMakeLines);
1752  }
1753  if( bUndo )
1754  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj,true));
1755  pOL->RemoveObject(nPos0);
1756 
1757  if( !bUndo )
1758  SdrObject::Free(pObj);
1759  }
1760  }
1761 
1762  if( bUndo )
1763  {
1764  // construct UndoComment from objects actually used
1765  SetUndoComment(SvxResId(bMakeLines?STR_EditDismantle_Lines:STR_EditDismantle_Polys),aRemoveBuffer.GetMarkDescription());
1766  // remove objects actually used from the list
1767  EndUndo();
1768  }
1769 }
1770 
1771 
1772 // Group
1773 
1774 
1776 {
1777  if (AreObjectsMarked())
1778  {
1779  SortMarkedObjects();
1780 
1781  const bool bUndo = IsUndoEnabled();
1782  if( bUndo )
1783  {
1784  BegUndo(SvxResId(STR_EditGroup),GetDescriptionOfMarkedObjects(),SdrRepeatFunc::Group);
1785 
1786  for(size_t nm = GetMarkedObjectCount(); nm>0; )
1787  {
1788  // add UndoActions for all affected objects
1789  --nm;
1790  SdrMark* pM=GetSdrMarkByIndex(nm);
1791  SdrObject* pObj = pM->GetMarkedSdrObj();
1792  AddUndoActions( CreateConnectorUndo( *pObj ) );
1793  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoRemoveObject( *pObj ));
1794  }
1795  }
1796 
1797  SdrMarkList aNewMark;
1798  SdrPageView* pPV = GetSdrPageView();
1799 
1800  if(pPV)
1801  {
1802  SdrObjList* pCurrentLst=pPV->GetObjList();
1803  SdrObjList* pSrcLst=pCurrentLst;
1804  SdrObjList* pSrcLst0=pSrcLst;
1805  // make sure OrdNums are correct
1806  if (pSrcLst->IsObjOrdNumsDirty())
1807  pSrcLst->RecalcObjOrdNums();
1808  SdrObject* pGrp=nullptr;
1809  SdrObjList* pDstLst=nullptr;
1810  // if all selected objects come from foreign object lists.
1811  // the group object is the last one in the list.
1812  size_t nInsPos=pSrcLst->GetObjCount();
1813  bool bNeedInsPos=true;
1814  for (size_t nm=GetMarkedObjectCount(); nm>0;)
1815  {
1816  --nm;
1817  SdrMark* pM=GetSdrMarkByIndex(nm);
1818  if (pM->GetPageView()==pPV)
1819  {
1820  SdrObject* pObj=pM->GetMarkedSdrObj();
1821  if (nullptr==pGrp)
1822  {
1823  pGrp = new SdrObjGroup(pObj->getSdrModelFromSdrObject());
1824  pDstLst=pGrp->GetSubList();
1825  DBG_ASSERT(pDstLst!=nullptr,"Alleged group object doesn't return object list.");
1826  }
1827  pSrcLst=pObj->getParentSdrObjListFromSdrObject();
1828  if (pSrcLst!=pSrcLst0)
1829  {
1830  if (pSrcLst->IsObjOrdNumsDirty())
1831  pSrcLst->RecalcObjOrdNums();
1832  }
1833  bool bForeignList=pSrcLst!=pCurrentLst;
1834  if (!bForeignList && bNeedInsPos)
1835  {
1836  nInsPos=pObj->GetOrdNum(); // this way, all ObjOrdNum of the page are set
1837  nInsPos++;
1838  bNeedInsPos=false;
1839  }
1840  pSrcLst->RemoveObject(pObj->GetOrdNumDirect());
1841  if (!bForeignList)
1842  nInsPos--; // correct InsertPos
1843  pDstLst->InsertObject(pObj,0);
1844  GetMarkedObjectListWriteAccess().DeleteMark(nm);
1845  pSrcLst0=pSrcLst;
1846  }
1847  }
1848  if (pGrp!=nullptr)
1849  {
1850  aNewMark.InsertEntry(SdrMark(pGrp,pPV));
1851  const size_t nCount=pDstLst->GetObjCount();
1852  pCurrentLst->InsertObject(pGrp,nInsPos);
1853  if( bUndo )
1854  {
1855  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pGrp,true)); // no recalculation!
1856  for (size_t no=0; no<nCount; ++no)
1857  {
1858  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoInsertObject(*pDstLst->GetObj(no)));
1859  }
1860  }
1861  }
1862  }
1863  GetMarkedObjectListWriteAccess().Merge(aNewMark);
1864  MarkListHasChanged();
1865 
1866  if( bUndo )
1867  EndUndo();
1868  }
1869 }
1870 
1871 
1872 // Ungroup
1873 
1874 
1876 {
1877  SdrMarkList aNewMark;
1878 
1879  const bool bUndo = IsUndoEnabled();
1880  if( bUndo )
1881  BegUndo("", "", SdrRepeatFunc::Ungroup);
1882 
1883  size_t nCount=0;
1884  OUString aName1;
1885  OUString aName;
1886  bool bNameOk=false;
1887  for (size_t nm=GetMarkedObjectCount(); nm>0;) {
1888  --nm;
1889  SdrMark* pM=GetSdrMarkByIndex(nm);
1890  SdrObject* pGrp=pM->GetMarkedSdrObj();
1891  SdrObjList* pSrcLst=pGrp->GetSubList();
1892  if (pSrcLst!=nullptr) {
1893  nCount++;
1894  if (nCount==1) {
1895  aName = pGrp->TakeObjNameSingul(); // retrieve name of group
1896  aName1 = pGrp->TakeObjNamePlural(); // retrieve name of group
1897  bNameOk=true;
1898  } else {
1899  if (nCount==2) aName=aName1; // set plural name
1900  if (bNameOk) {
1901  OUString aStr(pGrp->TakeObjNamePlural()); // retrieve name of group
1902 
1903  if (aStr != aName)
1904  bNameOk = false;
1905  }
1906  }
1907  size_t nDstCnt=pGrp->GetOrdNum();
1908  SdrObjList* pDstLst=pM->GetPageView()->GetObjList();
1909 
1910  // FIRST move contained objects to parent of group, so that
1911  // the contained objects are NOT migrated to the UNDO-ItemPool
1912  // when AddUndo(new SdrUndoDelObj(*pGrp)) is called.
1913  const size_t nObjCount=pSrcLst->GetObjCount();
1914 
1915  if( bUndo )
1916  {
1917  for (size_t no=nObjCount; no>0;)
1918  {
1919  no--;
1920  SdrObject* pObj=pSrcLst->GetObj(no);
1921  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoRemoveObject(*pObj));
1922  }
1923  }
1924  for (size_t no=0; no<nObjCount; ++no)
1925  {
1926  SdrObject* pObj=pSrcLst->RemoveObject(0);
1927  pDstLst->InsertObject(pObj,nDstCnt);
1928  if( bUndo )
1929  AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoInsertObject(*pObj,true));
1930  nDstCnt++;
1931  // No SortCheck when inserting into MarkList, because that would
1932  // provoke a RecalcOrdNums() each time because of pObj->GetOrdNum():
1933  aNewMark.InsertEntry(SdrMark(pObj,pM->GetPageView()),false);
1934  }
1935 
1936  if( bUndo )
1937  {
1938  // Now it is safe to add the delete-UNDO which triggers the
1939  // MigrateItemPool now only for itself, not for the sub-objects.
1940  // nDstCnt is right, because previous inserts move group
1941  // object deeper and increase nDstCnt.
1942  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pGrp));
1943  }
1944  pDstLst->RemoveObject(nDstCnt);
1945 
1946  if( !bUndo )
1947  SdrObject::Free(pGrp);
1948 
1949  GetMarkedObjectListWriteAccess().DeleteMark(nm);
1950  }
1951  }
1952  if (nCount!=0)
1953  {
1954  if (!bNameOk)
1955  aName=SvxResId(STR_ObjNamePluralGRUP); // Use the term "Group Objects," if different objects are grouped.
1956  SetUndoComment(SvxResId(STR_EditUngroup),aName);
1957  }
1958 
1959  if( bUndo )
1960  EndUndo();
1961 
1962  if (nCount!=0)
1963  {
1964  GetMarkedObjectListWriteAccess().Merge(aNewMark,true); // Because of the sorting above, aNewMark is reversed
1965  MarkListHasChanged();
1966  }
1967 }
1968 
1969 
1970 // ConvertToPoly
1971 
1972 
1973 SdrObject* SdrEditView::ImpConvertOneObj(SdrObject* pObj, bool bPath, bool bLineToArea)
1974 {
1975  SdrObjectUniquePtr pNewObj = pObj->ConvertToPolyObj(bPath, bLineToArea);
1976  if (pNewObj)
1977  {
1979  const bool bUndo = IsUndoEnabled();
1980  if( bUndo )
1981  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoReplaceObject(*pObj,*pNewObj));
1982 
1983  pOL->ReplaceObject(pNewObj.get(), pObj->GetOrdNum());
1984 
1985  if( !bUndo )
1986  SdrObject::Free(pObj);
1987  }
1988  return pNewObj.release();
1989 }
1990 
1991 void SdrEditView::ImpConvertTo(bool bPath, bool bLineToArea)
1992 {
1993  if (AreObjectsMarked()) {
1994  bool bMrkChg = false;
1995  const size_t nMarkCount=GetMarkedObjectCount();
1996  const char* pDscrID = nullptr;
1997  if(bLineToArea)
1998  {
1999  if(nMarkCount == 1)
2000  pDscrID = STR_EditConvToContour;
2001  else
2002  pDscrID = STR_EditConvToContours;
2003 
2004  BegUndo(SvxResId(pDscrID), GetDescriptionOfMarkedObjects());
2005  }
2006  else
2007  {
2008  if (bPath) {
2009  if (nMarkCount==1) pDscrID=STR_EditConvToCurve;
2010  else pDscrID=STR_EditConvToCurves;
2011  BegUndo(SvxResId(pDscrID),GetDescriptionOfMarkedObjects(),SdrRepeatFunc::ConvertToPath);
2012  } else {
2013  if (nMarkCount==1) pDscrID=STR_EditConvToPoly;
2014  else pDscrID=STR_EditConvToPolys;
2015  BegUndo(SvxResId(pDscrID),GetDescriptionOfMarkedObjects(),SdrRepeatFunc::ConvertToPoly);
2016  }
2017  }
2018  for (size_t nm=nMarkCount; nm>0;) {
2019  --nm;
2020  SdrMark* pM=GetSdrMarkByIndex(nm);
2021  SdrObject* pObj=pM->GetMarkedSdrObj();
2022  SdrPageView* pPV=pM->GetPageView();
2023  if (pObj->IsGroupObject() && !pObj->Is3DObj()) {
2024  SdrObject* pGrp=pObj;
2026  while (aIter.IsMore()) {
2027  pObj=aIter.Next();
2028  ImpConvertOneObj(pObj,bPath,bLineToArea);
2029  }
2030  } else {
2031  SdrObject* pNewObj=ImpConvertOneObj(pObj,bPath,bLineToArea);
2032  if (pNewObj!=nullptr) {
2033  bMrkChg=true;
2034  GetMarkedObjectListWriteAccess().ReplaceMark(SdrMark(pNewObj,pPV),nm);
2035  }
2036  }
2037  }
2038  EndUndo();
2039  if (bMrkChg)
2040  {
2041  AdjustMarkHdl();
2042  MarkListHasChanged();
2043  }
2044  }
2045 }
2046 
2048 {
2049  ImpConvertTo(true, bLineToArea);
2050 }
2051 
2053 {
2054  ImpConvertTo(false, false/*bLineToArea*/);
2055 }
2056 
2057 namespace
2058 {
2059  GDIMetaFile GetMetaFile(SdrGrafObj const * pGraf)
2060  {
2061  if (pGraf->HasGDIMetaFile())
2063  assert(pGraf->isEmbeddedVectorGraphicData());
2065  }
2066 }
2067 
2068 // Metafile Import
2070 {
2071  const bool bUndo = IsUndoEnabled();
2072 
2073  if( bUndo )
2074  BegUndo("", "", SdrRepeatFunc::ImportMtf);
2075 
2076  SortMarkedObjects();
2077  SdrMarkList aForTheDescription;
2078  SdrMarkList aNewMarked;
2079  for (size_t nm =GetMarkedObjectCount(); nm > 0; )
2080  {
2081  // create Undo objects for all new objects
2082  // check for cancellation between the metafiles
2083  if (pProgrInfo != nullptr)
2084  {
2085  pProgrInfo->SetNextObject();
2086  if (!pProgrInfo->ReportActions(0))
2087  break;
2088  }
2089 
2090  --nm;
2091  SdrMark* pM=GetSdrMarkByIndex(nm);
2092  SdrObject* pObj=pM->GetMarkedSdrObj();
2093  SdrPageView* pPV=pM->GetPageView();
2095  const size_t nInsPos=pObj->GetOrdNum()+1;
2096  sal_uIntPtr nInsCnt=0;
2097  tools::Rectangle aLogicRect;
2098 
2099  SdrGrafObj* pGraf = dynamic_cast<SdrGrafObj*>( pObj );
2100  if (pGraf != nullptr)
2101  {
2102  if (pGraf->HasGDIMetaFile() || pGraf->isEmbeddedVectorGraphicData())
2103  {
2104  GDIMetaFile aMetaFile(GetMetaFile(pGraf));
2105  if (aMetaFile.GetActionSize())
2106  {
2107  aLogicRect = pGraf->GetLogicRect();
2108  ImpSdrGDIMetaFileImport aFilter(*mpModel, pObj->GetLayer(), aLogicRect);
2109  nInsCnt = aFilter.DoImport(aMetaFile, *pOL, nInsPos, pProgrInfo);
2110  }
2111  }
2112  else if (pGraf->isEmbeddedPdfData())
2113  {
2114 #if HAVE_FEATURE_PDFIUM
2115  aLogicRect = pGraf->GetLogicRect();
2116  ImpSdrPdfImport aFilter(*mpModel, pObj->GetLayer(), aLogicRect, pGraf->getEmbeddedPdfData());
2117  if (pGraf->getEmbeddedPageNumber() < aFilter.GetPageCount())
2118  {
2119  nInsCnt = aFilter.DoImport(*pOL, nInsPos, pGraf->getEmbeddedPageNumber(), pProgrInfo);
2120  }
2121 #endif // HAVE_FEATURE_PDFIUM
2122  }
2123  }
2124 
2125  SdrOle2Obj* pOle2 = dynamic_cast<SdrOle2Obj*>(pObj);
2126  if (pOle2 != nullptr && pOle2->GetGraphic())
2127  {
2128  aLogicRect = pOle2->GetLogicRect();
2129  ImpSdrGDIMetaFileImport aFilter(*mpModel, pObj->GetLayer(), aLogicRect);
2130  nInsCnt = aFilter.DoImport(pOle2->GetGraphic()->GetGDIMetaFile(), *pOL, nInsPos, pProgrInfo);
2131  }
2132 
2133  if (nInsCnt != 0)
2134  {
2135  // transformation
2136  GeoStat aGeoStat(pGraf ? pGraf->GetGeoStat() : pOle2->GetGeoStat());
2137  size_t nObj = nInsPos;
2138 
2139  if (aGeoStat.nShearAngle)
2140  aGeoStat.RecalcTan();
2141 
2142  if (aGeoStat.nRotationAngle)
2143  aGeoStat.RecalcSinCos();
2144 
2145  for (sal_uIntPtr i = 0; i < nInsCnt; i++)
2146  {
2147  if (bUndo)
2148  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pOL->GetObj(nObj)));
2149 
2150  // update new MarkList
2151  SdrObject* pCandidate = pOL->GetObj(nObj);
2152 
2153  // apply original transformation
2154  if (aGeoStat.nShearAngle)
2155  pCandidate->NbcShear(aLogicRect.TopLeft(), aGeoStat.nShearAngle, aGeoStat.nTan, false);
2156 
2157  if (aGeoStat.nRotationAngle)
2158  pCandidate->NbcRotate(aLogicRect.TopLeft(), aGeoStat.nRotationAngle, aGeoStat.nSin, aGeoStat.nCos);
2159 
2160  SdrMark aNewMark(pCandidate, pPV);
2161  aNewMarked.InsertEntry(aNewMark);
2162 
2163  nObj++;
2164  }
2165 
2166  aForTheDescription.InsertEntry(*pM);
2167 
2168  if (bUndo)
2169  AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj));
2170 
2171  // remove object from selection and delete
2172  GetMarkedObjectListWriteAccess().DeleteMark(TryToFindMarkedObject(pObj));
2173  pOL->RemoveObject(nInsPos-1);
2174 
2175  if (!bUndo)
2176  SdrObject::Free(pObj);
2177  }
2178  }
2179 
2180  if (aNewMarked.GetMarkCount())
2181  {
2182  // create new selection
2183  for (size_t a = 0; a < aNewMarked.GetMarkCount(); ++a)
2184  {
2185  GetMarkedObjectListWriteAccess().InsertEntry(*aNewMarked.GetMark(a));
2186  }
2187 
2188  SortMarkedObjects();
2189  }
2190 
2191  if (bUndo)
2192  {
2193  SetUndoComment(SvxResId(STR_EditImportMtf),aForTheDescription.GetMarkDescription());
2194  EndUndo();
2195  }
2196 }
2197 
2198 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void ImpCheckToTopBtmPossible()
Definition: svdedtv2.cxx:488
Point TopLeft() const
void MovMarkedToBtm()
Definition: svdedtv2.cxx:160
GDIMetaFile getMetafileFromEmbeddedVectorGraphicData() const
Definition: svdograf.cxx:858
#define EE_ITEMS_START
virtual void TakeObjInfo(SdrObjTransformInfoRec &rInfo) const
Definition: svdobj.cxx:590
void append(const basegfx::B2DPoint &rPoint, sal_uInt32 nCount)
size_t GetMarkCount() const
Definition: svdmark.hxx:179
virtual const tools::Rectangle & GetCurrentBoundRect() const
Definition: svdobj.cxx:881
void PutMarkedInFrontOfObj(const SdrObject *pRefObj)
Definition: svdedtv2.cxx:255
static bool ImpCanDismantle(const basegfx::B2DPolyPolygon &rPpolyPpolygon, bool bMakeLines)
Definition: svdedtv2.cxx:1459
void EqualizeMarkedObjects(bool bWidth)
Definition: svdedtv2.cxx:1167
static bool ImpCanConvertForCombine1(const SdrObject *pObj)
Definition: svdedtv2.cxx:576
static basegfx::B2DPolyPolygon ImpGetPolyPolygon1(const SdrObject *pObj)
Definition: svdedtv2.cxx:624
void setClosed(bool bNew)
double nSin
Definition: svdtrans.hxx:219
periodic cubic Spline (ni)
Definition: svdobj.hxx:133
static bool ImpCanConvertForCombine(const SdrObject *pObj)
Definition: svdedtv2.cxx:594
static SvxAbstractDialogFactory * Create()
Definition: svxdlg.cxx:23
sal_Int32 getEmbeddedPageNumber() const
Returns the page number of the embedded data (typically to re-render or import it).
Definition: svdograf.cxx:915
bool IsTextFrame() const
Definition: svdotext.hxx:343
void SetNextObject()
Definition: svdetc.cxx:499
long nRotationAngle
Definition: svdtrans.hxx:216
B2DPolyPolygon solvePolygonOperationOr(const B2DPolyPolygon &rCandidateA, const B2DPolyPolygon &rCandidateB)
sal_Int64 n
SdrObject * GetObj(size_t nNum) const
Definition: svdpage.cxx:773
void RecalcObjOrdNums()
recalculate order numbers / ZIndex
Definition: svdpage.cxx:259
size_t GetObjCount() const
Definition: svdpage.cxx:767
void PutMarkedBehindObj(const SdrObject *pRefObj)
Definition: svdedtv2.cxx:356
void appendBezierSegment(const basegfx::B2DPoint &rNextControlPoint, const basegfx::B2DPoint &rPrevControlPoint, const basegfx::B2DPoint &rPoint)
bool IsOver(const tools::Rectangle &rRect) const
static bool isWhiteSpace(const sal_Unicode ch)
void PutMarkedToTop()
Definition: svdedtv2.cxx:250
const std::shared_ptr< std::vector< sal_Int8 > > & getEmbeddedPdfData() const
Definition: svdograf.cxx:910
vector< ImpDistributeEntry > ImpDistributeEntryList
Definition: svdedtv2.cxx:772
#define SDRATTR_NOTPERSIST_LAST
Definition: svddef.hxx:304
virtual OUString TakeObjNameSingul() const
Definition: svdobj.cxx:1045
SdrMark * GetMark(size_t nNum) const
Definition: svdmark.cxx:234
sal_Int32 GetParagraphCount() const
#define SDRATTR_END
Definition: svddef.hxx:407
sal_Int64 getTimeStamp() const
Definition: svdmark.hxx:129
static void Free(SdrObject *&_rpObject)
Definition: svdobj.cxx:423
void RecalcTan()
Definition: svdtrans.cxx:462
virtual void InsertObject(SdrObject *pObj, size_t nPos=SAL_MAX_SIZE)
Definition: svdpage.cxx:358
virtual const tools::Rectangle & GetSnapRect() const override
Definition: svdoattr.cxx:91
virtual SdrObjList * GetSubList() const
Definition: svdobj.cxx:674
polygon, PolyPolygon
Definition: svdobj.hxx:126
virtual bool HasText() const override
Definition: svdotxat.cxx:429
static basegfx::B2DPolyPolygon ImpGetPolyPolygon(const SdrObject *pObj)
Definition: svdedtv2.cxx:671
Rectangle objects (rectangle, circle, ...)
Definition: svdorect.hxx:39
bool IsObjOrdNumsDirty() const
Definition: svdpage.hxx:108
Provides information about various ZObject properties.
Definition: svdobj.hxx:248
bool isEmbeddedPdfData() const
Definition: svdograf.cxx:905
virtual SdrObject * GetMaxToBtmObj(SdrObject *pObj) const
Definition: svdedtv2.cxx:64
B2DPolygon const & getB2DPolygon(sal_uInt32 nIndex) const
void ClearMergedItem(const sal_uInt16 nWhich=0)
Definition: svdobj.cxx:1926
#define SDRATTR_NOTPERSIST_FIRST
Definition: svddef.hxx:267
bool IsMore() const
Definition: svditer.hxx:62
OUString SvxResId(const char *pId)
Definition: dialmgr.cxx:28
void MovMarkedToTop()
Definition: svdedtv2.cxx:73
The transformation of a rectangle into a polygon, by using angle parameters from GeoStat.
Definition: svdtrans.hxx:214
int nCount
void ConvertMarkedToPolyObj()
Definition: svdedtv2.cxx:2052
SfxStyleSheet * GetStyleSheet() const
Definition: svdobj.cxx:2162
const GDIMetaFile & GetGDIMetaFile() const
void SetMergedItemSet(const SfxItemSet &rSet, bool bClearAllItems=false)
Definition: svdobj.cxx:1936
PolyLine.
Definition: svdobj.hxx:127
static SdrObject * MakeNewObject(SdrModel &rSdrModel, SdrInventor nInventor, sal_uInt16 nObjIdentifier, const tools::Rectangle *pSnapRect=nullptr)
Definition: svdobj.cxx:3071
B2DPolyPolygon solvePolygonOperationAnd(const B2DPolyPolygon &rCandidateA, const B2DPolyPolygon &rCandidateB)
const GeoStat & GetGeoStat() const
Definition: svdotext.hxx:399
virtual void NbcRotate(const Point &rRef, long nAngle, double sn, double cs)
Definition: svdobj.cxx:1428
B2DPolyPolygon solvePolygonOperationDiff(const B2DPolyPolygon &rCandidateA, const B2DPolyPolygon &rCandidateB)
sal_uInt32 GetOrdNumDirect() const
Definition: svdobj.hxx:891
void ConvertMarkedToPathObj(bool bLineToArea)
Definition: svdedtv2.cxx:2047
SdrObjList * GetObjList() const
Return current List.
Definition: svdpagv.hxx:176
SdrObject * GetMarkedSdrObj() const
Definition: svdmark.hxx:67
Everything a View needs to know about a selected object.
Definition: svdmark.hxx:43
Graphic GetTransformedGraphic(SdrGrafObjTransformsAttrs nTransformFlags=SdrGrafObjTransformsAttrs::ALL) const
Definition: svdograf.cxx:349
double nCos
Definition: svdtrans.hxx:220
#define DBG_ASSERT(sCon, aError)
uno_Any a
bool IsLayerLocked(const OUString &rName) const
Definition: svdpagv.hxx:200
void ImpCopyAttributes(const SdrObject *pSource, SdrObject *pDest) const
Definition: svdedtv2.cxx:549
int i
SdrPageView * GetPageView() const
Definition: svdmark.hxx:69
size_t DoImport(const GDIMetaFile &rMtf, SdrObjList &rDestList, size_t nInsPos, SvdProgressInfo *pProgrInfo=nullptr)
Definition: svdfmtf.cxx:216
Helper class for the communication between the dialog In order to break open Metafiles (sd/source/ui/...
Definition: svdetc.hxx:111
void CombineMarkedObjects(bool bNoPolyPoly=true)
Definition: svdedtv2.cxx:1285
SvxDistributeVertical
SdrModel & getSdrModelFromSdrObject() const
Definition: svdobj.cxx:299
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:823
#define SDRATTR_SHADOW
Definition: svddef.hxx:171
virtual sal_uInt16 GetObjIdentifier() const override
Definition: svdotext.cxx:432
bool IsGroupObject() const
Definition: svdobj.cxx:669
#define XATTR_LINESTYLE
Definition: xdef.hxx:90
virtual void SetLogicRect(const tools::Rectangle &rRect)
Definition: svdobj.cxx:1658
void DistributeMarkedObjects(weld::Window *pParent)
Definition: svdedtv2.cxx:774
void SetMergedItem(const SfxPoolItem &rItem)
Definition: svdobj.cxx:1921
#define SDRATTR_START
Definition: svddef.hxx:168
OUString GetText(Paragraph const *pPara, sal_Int32 nParaCount=1) const
#define XATTR_FILLSTYLE
Definition: xdef.hxx:107
const SfxPoolItem & GetMergedItem(const sal_uInt16 nWhich) const
Definition: svdobj.cxx:1946
This class represents an embedded or linked bitmap graphic object.
Definition: svdograf.hxx:79
Abstract DrawObject.
Definition: svdobj.hxx:312
bool ReportActions(size_t nActionCount)
Definition: svdetc.cxx:465
virtual SdrObject * RemoveObject(size_t nObjNum)
Definition: svdpage.cxx:436
virtual void ObjOrderChanged(SdrObject *pObj, size_t nOldPos, size_t nNewPos)
Definition: svdedtv2.cxx:69
void UnGroupMarked()
Definition: svdedtv2.cxx:1875
SdrInsertFlags
Definition: svdedtv.hxx:58
Size GetSize() const
virtual SdrInventor GetObjInventor() const
Definition: svdobj.cxx:580
void CombineMarkedTextObjects()
Definition: svdedtv2.cxx:1221
Paragraph * GetParagraph(sal_Int32 nAbsPos) const
virtual SdrLayerID GetLayer() const
Definition: svdobj.cxx:604
const SdrObject * GetSdrObjectFromCustomShape() const
Definition: svdoashp.cxx:412
void append(const B2DPolygon &rPolygon, sal_uInt32 nCount=1)
virtual void NbcShear(const Point &rRef, long nAngle, double tn, bool bVShear)
Definition: svdobj.cxx:1487
bool IsLine() const
Definition: svdopath.hxx:145
SdrObject * Next()
Definition: svditer.hxx:63
std::unique_ptr< OutlinerParaObject > CreateParaObject(sal_Int32 nStartPara=0, sal_Int32 nParaCount=EE_PARA_ALL) const
SdrObjectUniquePtr ConvertToPolyObj(bool bBezier, bool bLineToArea) const
Definition: svdobj.cxx:2532
void ForceSort() const
Definition: svdmark.cxx:146
sal_uInt32 count() const
virtual void NbcSetOutlinerParaObject(std::unique_ptr< OutlinerParaObject > pTextObject)
Definition: svdobj.cxx:1766
virtual SdrObject * ReplaceObject(SdrObject *pNewObj, size_t nObjNum)
Replace existing object by different one.
Definition: svdpage.cxx:492
SdrObjKind
Definition: svdobj.hxx:116
#define SAL_WARN_IF(condition, area, stream)
void GroupMarked()
Definition: svdedtv2.cxx:1775
void DismantleMarkedObjects(bool bMakeLines=false)
Definition: svdedtv2.cxx:1716
virtual OutlinerParaObject * GetOutlinerParaObject() const override
Definition: svdotext.cxx:1362
void AddUndo(std::unique_ptr< SdrUndoAction > pUndo)
Definition: svddrgmt.hxx:168
OUString aName
static basegfx::B2DPolygon ImpCombineToSinglePolygon(const basegfx::B2DPolyPolygon &rPolyPolygon)
Definition: svdedtv2.cxx:694
const SfxItemSet & GetMergedItemSet() const
Definition: svdobj.cxx:1911
bool HasGDIMetaFile() const
Definition: svdograf.cxx:848
RET_OK
bool IsTextPath() const
Definition: svdoashp.cxx:450
void insert(sal_uInt32 nIndex, const B2DPolygon &rPolygon, sal_uInt32 nCount=1)
void AddText(const OutlinerParaObject &, bool bAppend=false)
virtual SdrObject * CloneSdrObject(SdrModel &rTargetModel) const
Definition: svdobj.cxx:1001
void SetOutlinerParaObject(std::unique_ptr< OutlinerParaObject > pTextObject)
Definition: svdobj.cxx:1755
virtual sal_uInt16 GetObjIdentifier() const override
Definition: svdopath.cxx:1821
size_t GetActionSize() const
bool GetTextBounds(tools::Rectangle &rTextBound) const
Definition: svdoashp.cxx:546
std::unique_ptr< SdrObject, SdrObjectFreeOp > SdrObjectUniquePtr
Definition: svdobj.hxx:114
SdrOnOffItem makeSdrShadowItem(bool bShadow)
Definition: sdshitm.hxx:25
double getLength(const B2DPolygon &rCandidate)
const basegfx::B2DPolyPolygon & GetPathPoly() const
Definition: svdopath.hxx:139
virtual OUString TakeObjNamePlural() const
Definition: svdobj.cxx:1060
bool IsOutlText() const
Definition: svdotext.hxx:344
virtual void SetSnapRect(const tools::Rectangle &rRect)
Definition: svdobj.cxx:1649
#define XATTR_FORMTXTSTYLE
Definition: xdef.hxx:131
void ImpConvertTo(bool bPath, bool bLineToArea)
Definition: svdedtv2.cxx:1991
virtual SdrObject * GetMaxToTopObj(SdrObject *pObj) const
Definition: svdedtv2.cxx:59
void ImpDismantleOneObject(const SdrObject *pObj, SdrObjList &rOL, size_t &rPos, SdrPageView *pPV, bool bMakeLines)
Definition: svdedtv2.cxx:1561
virtual SdrObject * SetObjectOrdNum(size_t nOldObjNum, size_t nNewObjNum)
Modify ZOrder of an SdrObject.
Definition: svdpage.cxx:556
void ReverseOrderOfMarked()
Definition: svdedtv2.cxx:436
virtual const tools::Rectangle & GetLogicRect() const
Definition: svdobj.cxx:1634
void PutMarkedToBtm()
Definition: svdedtv2.cxx:351
B2DPolygon simplifyCurveSegments(const B2DPolygon &rCandidate)
SdrObjList * getParentSdrObjListFromSdrObject() const
Definition: svdobj.cxx:325
virtual void NbcSetStyleSheet(SfxStyleSheet *pNewStyleSheet, bool bDontRemoveHardAttr)
Definition: svdobj.cxx:2180
SvxDistributeHorizontal
const OUString & GetMarkDescription() const
Definition: svdmark.cxx:420
SdrMergeMode
Definition: svdedtv.hxx:51
B2DPolyPolygon prepareForPolygonOperation(const B2DPolygon &rCandidate)
void DoImportMarkedMtf(SvdProgressInfo *pProgrInfo=nullptr)
Definition: svdedtv2.cxx:2069
void MergeMarkedObjects(SdrMergeMode eMode)
Definition: svdedtv2.cxx:990
void InsertEntry(const SdrMark &rMark, bool bChkSort=true)
Definition: svdmark.cxx:264
void setWidth(long nWidth)
bool isEmbeddedVectorGraphicData() const
Definition: svdograf.cxx:853
virtual OutlinerParaObject * GetOutlinerParaObject() const
Definition: svdobj.cxx:1770
bool Is3DObj() const
Definition: svdobj.hxx:795
aStr
SdrObject * ImpConvertOneObj(SdrObject *pObj, bool bPath, bool bLineToArea)
Definition: svdedtv2.cxx:1973
open Bezier-curve
Definition: svdobj.hxx:128
Point Center() const
sal_uInt16 nPos
const Graphic * GetGraphic() const
Definition: svdoole2.cxx:1660
virtual const tools::Rectangle & GetLogicRect() const override
Definition: svdotxtr.cxx:73
virtual void NbcSetLayer(SdrLayerID nLayer)
Definition: svdobj.cxx:621
#define EE_ITEMS_END