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