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