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 <dstribut_enum.hxx>
54#include <osl/diagnose.h>
55
56using namespace com::sun::star;
57
59{
60 return nullptr;
61}
62
64{
65 return nullptr;
66}
67
68void 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 )
82
84 for (size_t nm=0; nm<nCount; ++nm)
85 { // All Ordnums have to be correct!
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;
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.Overlaps(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)
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 )
169
171 for (size_t nm=0; nm<nCount; ++nm)
172 { // All Ordnums have to be correct!
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 {
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.Overlaps(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)
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 )
263
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);
276 }
278 if (nRefMark!=SAL_MAX_SIZE)
279 {
282 }
283 }
284 for (size_t nm=0; nm<nCount; ++nm)
285 { // All Ordnums have to be correct!
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;
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)
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 )
365
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);
377 }
379 if (nRefMark!=SAL_MAX_SIZE)
380 {
383 }
384 }
385 for (size_t nm=0; nm<nCount; ++nm) { // All Ordnums have to be correct!
387 }
388 bool bChg=false;
389 SdrObjList* pOL0=nullptr;
390 size_t nNewPos=0;
391 for (size_t nm=0; nm<nCount; ++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)
432
433}
434
436{
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 )
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;
455 size_t c=b;
456 if (a<c) { // make sure OrdNums aren't dirty
458 }
459 while (a<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)
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
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'
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;
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
548void 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
563 EE_ITEMS_START, EE_ITEMS_END> aSet(GetModel().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{
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 rtl::Reference<SdrObject> 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 {
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
758namespace {
759
760// for distribution dialog function
761struct ImpDistributeEntry
762{
763 SdrObject* mpObj;
764 sal_Int32 mnPos;
765 sal_Int32 mnLength;
766};
767
768}
769
770typedef 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
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 GetModel().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;
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);
1020 OSL_ENSURE(AreObjectsMarked(), "no more objects selected after preparations (!)");
1021
1022 for(size_t a=0; a<GetMarkedObjectCount(); ++a)
1023 {
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 {
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 rtl::Reference<SdrPathObj> pPath = new SdrPathObj(pAttrObj->getSdrModelFromSdrObject(), SdrObjKind::PathFill, std::move(aMergePolyPolygonA));
1124 ImpCopyAttributes(pAttrObj, pPath.get());
1125 pInsOL->InsertObject(pPath.get(), 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.get(), pInsPV, false, true);
1135 }
1136
1137 aRemove.ForceSort();
1138 switch(eMode)
1139 {
1141 {
1143 SvxResId(STR_EditMergeMergePoly),
1144 aRemove.GetMarkDescription());
1145 break;
1146 }
1148 {
1150 SvxResId(STR_EditMergeSubstractPoly),
1151 aRemove.GetMarkDescription());
1152 break;
1153 }
1155 {
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
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
1235
1237 while ( aIter.IsMore() )
1238 {
1239 SdrObject* pObj = aIter.Next();
1240 SdrTextObj* pTextObj = DynCastSdrTextObj( pObj );
1241 const OutlinerParaObject* pOPO = pTextObj ? pTextObj->GetOutlinerParaObject() : nullptr;
1242 if ( pOPO && pTextObj->IsTextFrame()
1243 && pTextObj->GetObjIdentifier() == SdrObjKind::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
1267 AdjustMarkHdl();
1268
1269 if ( GetMarkedObjectCount() > 1 )
1270 {
1272 pReplacement->SetOutlinerParaObject( rDrawOutliner.CreateParaObject() );
1273 pReplacement->SetSnapRect( GetMarkedObjRect() );
1274
1276 if ( InsertObjectAtView( pReplacement.get(), *pPageView, nFlags ) )
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 )
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
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;
1338 SdrObject* pObj = pM->GetMarkedSdrObj();
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.
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 {
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 = SdrObjKind::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 = SdrObjKind::PathLine;
1411 }
1412 }
1413 }
1414 }
1415
1416 rtl::Reference<SdrPathObj> pPath = new SdrPathObj(pAttrObj->getSdrModelFromSdrObject(), eKind, std::move(aPolyPolygon));
1417
1418 // attributes of the lowest object
1419 ImpCopyAttributes(pAttrObj, pPath.get());
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 = false;
1427 if (auto pPathObj = dynamic_cast<const SdrPathObj*>(pAttrObj))
1428 if (pPathObj->IsClosed())
1429 bIsClosedPathObj = true;
1430
1431 if(drawing::LineStyle_NONE == eLineStyle && (drawing::FillStyle_NONE == eFillStyle || !bIsClosedPathObj))
1432 {
1433 pPath->SetMergedItem(XLineStyleItem(drawing::LineStyle_SOLID));
1434 }
1435
1436 pInsOL->InsertObject(pPath.get(),nInsPos);
1437 if( bUndo )
1438 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoNewObject(*pPath));
1439
1440 // Here was a severe error: Without UnmarkAllObj, the new object was marked
1441 // additionally to the two ones which are deleted below. As long as those are
1442 // in the UNDO there is no problem, but as soon as they get deleted, the
1443 // MarkList will contain deleted objects -> GPF.
1444 UnmarkAllObj(pInsPV);
1445 MarkObj(pPath.get(), pInsPV, false, true);
1446 }
1447
1448 // build an UndoComment from the objects actually used
1449 aRemoveBuffer.ForceSort(); // important for remove (see below)
1450 if( bUndo )
1451 SetUndoComment(SvxResId(bNoPolyPoly?STR_EditCombine_OnePoly:STR_EditCombine_PolyPoly),aRemoveBuffer.GetMarkDescription());
1452
1453 // remove objects actually used from the list
1454 DeleteMarkedList(aRemoveBuffer);
1455 if( bUndo )
1456 EndUndo();
1457}
1458
1459
1460// Dismantle
1461
1462
1463bool SdrEditView::ImpCanDismantle(const basegfx::B2DPolyPolygon& rPpolyPolygon, bool bMakeLines)
1464{
1465 bool bCan(false);
1466 const sal_uInt32 nPolygonCount(rPpolyPolygon.count());
1467
1468 if(nPolygonCount >= 2)
1469 {
1470 // #i69172# dismantle makes sense with 2 or more polygons in a polyPolygon
1471 bCan = true;
1472 }
1473 else if(bMakeLines && 1 == nPolygonCount)
1474 {
1475 // #i69172# ..or with at least 2 edges (curves or lines)
1476 const basegfx::B2DPolygon& aPolygon(rPpolyPolygon.getB2DPolygon(0));
1477 const sal_uInt32 nPointCount(aPolygon.count());
1478
1479 if(nPointCount > 2)
1480 {
1481 bCan = true;
1482 }
1483 }
1484
1485 return bCan;
1486}
1487
1488bool SdrEditView::ImpCanDismantle(const SdrObject* pObj, bool bMakeLines)
1489{
1490 bool bOtherObjs(false); // true=objects other than PathObj's existent
1491 bool bMin1PolyPoly(false); // true=at least 1 tools::PolyPolygon with more than one Polygon existent
1492 SdrObjList* pOL = pObj->GetSubList();
1493
1494 if(pOL)
1495 {
1496 // group object -- check all members if they're PathObjs
1498
1499 while(aIter.IsMore() && !bOtherObjs)
1500 {
1501 const SdrObject* pObj1 = aIter.Next();
1502 const SdrPathObj* pPath = dynamic_cast<const SdrPathObj*>( pObj1 );
1503
1504 if(pPath)
1505 {
1506 if(ImpCanDismantle(pPath->GetPathPoly(), bMakeLines))
1507 {
1508 bMin1PolyPoly = true;
1509 }
1510
1512 pObj1->TakeObjInfo(aInfo);
1513
1514 if(!aInfo.bCanConvToPath)
1515 {
1516 // happens e. g. in the case of FontWork
1517 bOtherObjs = true;
1518 }
1519 }
1520 else
1521 {
1522 bOtherObjs = true;
1523 }
1524 }
1525 }
1526 else
1527 {
1528 const SdrPathObj* pPath = dynamic_cast<const SdrPathObj*>(pObj);
1529 const SdrObjCustomShape* pCustomShape = dynamic_cast<const SdrObjCustomShape*>(pObj);
1530
1531 // #i37011#
1532 if(pPath)
1533 {
1534 if(ImpCanDismantle(pPath->GetPathPoly(),bMakeLines))
1535 {
1536 bMin1PolyPoly = true;
1537 }
1538
1540 pObj->TakeObjInfo(aInfo);
1541
1542 // new condition IsLine() to be able to break simple Lines
1543 if(!(aInfo.bCanConvToPath || aInfo.bCanConvToPoly) && !pPath->IsLine())
1544 {
1545 // happens e. g. in the case of FontWork
1546 bOtherObjs = true;
1547 }
1548 }
1549 else if(pCustomShape)
1550 {
1551 if(bMakeLines)
1552 {
1553 // allow break command
1554 bMin1PolyPoly = true;
1555 }
1556 }
1557 else
1558 {
1559 bOtherObjs = true;
1560 }
1561 }
1562 return bMin1PolyPoly && !bOtherObjs;
1563}
1564
1565void SdrEditView::ImpDismantleOneObject(const SdrObject* pObj, SdrObjList& rOL, size_t& rPos, SdrPageView* pPV, bool bMakeLines)
1566{
1567 const SdrPathObj* pSrcPath = dynamic_cast<const SdrPathObj*>( pObj );
1568 const SdrObjCustomShape* pCustomShape = dynamic_cast<const SdrObjCustomShape*>( pObj );
1569
1570 const bool bUndo = IsUndoEnabled();
1571
1572 if(pSrcPath)
1573 {
1574 // #i74631# redesigned due to XpolyPolygon removal and explicit constructors
1575 SdrObject* pLast = nullptr; // to be able to apply OutlinerParaObject
1576 const basegfx::B2DPolyPolygon& rPolyPolygon(pSrcPath->GetPathPoly());
1577 const sal_uInt32 nPolyCount(rPolyPolygon.count());
1578
1579 for(sal_uInt32 a(0); a < nPolyCount; a++)
1580 {
1581 const basegfx::B2DPolygon& rCandidate(rPolyPolygon.getB2DPolygon(a));
1582 const sal_uInt32 nPointCount(rCandidate.count());
1583
1584 if(!bMakeLines || nPointCount < 2)
1585 {
1587 pSrcPath->getSdrModelFromSdrObject(),
1588 pSrcPath->GetObjIdentifier(),
1589 basegfx::B2DPolyPolygon(rCandidate));
1590 ImpCopyAttributes(pSrcPath, pPath.get());
1591 pLast = pPath.get();
1592 rOL.InsertObject(pPath.get(), rPos);
1593 if( bUndo )
1594 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoNewObject(*pPath, true));
1595 MarkObj(pPath.get(), pPV, false, true);
1596 rPos++;
1597 }
1598 else
1599 {
1600 const sal_uInt32 nLoopCount(rCandidate.isClosed() ? nPointCount : nPointCount - 1);
1601
1602 for(sal_uInt32 b(0); b < nLoopCount; b++)
1603 {
1605 basegfx::B2DPolygon aNewPolygon;
1606 const sal_uInt32 nNextIndex((b + 1) % nPointCount);
1607
1608 aNewPolygon.append(rCandidate.getB2DPoint(b));
1609
1610 if(rCandidate.areControlPointsUsed())
1611 {
1612 aNewPolygon.appendBezierSegment(
1613 rCandidate.getNextControlPoint(b),
1614 rCandidate.getPrevControlPoint(nNextIndex),
1615 rCandidate.getB2DPoint(nNextIndex));
1616 eKind = SdrObjKind::PathLine;
1617 }
1618 else
1619 {
1620 aNewPolygon.append(rCandidate.getB2DPoint(nNextIndex));
1621 }
1622
1624 pSrcPath->getSdrModelFromSdrObject(),
1625 eKind,
1626 basegfx::B2DPolyPolygon(aNewPolygon));
1627 ImpCopyAttributes(pSrcPath, pPath.get());
1628 pLast = pPath.get();
1629 rOL.InsertObject(pPath.get(), rPos);
1630 if( bUndo )
1631 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoNewObject(*pPath, true));
1632 MarkObj(pPath.get(), pPV, false, true);
1633 rPos++;
1634 }
1635 }
1636 }
1637
1638 if(pLast && pSrcPath->GetOutlinerParaObject())
1639 {
1640 pLast->SetOutlinerParaObject(*pSrcPath->GetOutlinerParaObject());
1641 }
1642 }
1643 else if(pCustomShape)
1644 {
1645 if(bMakeLines)
1646 {
1647 // break up custom shape
1648 const SdrObject* pReplacement = pCustomShape->GetSdrObjectFromCustomShape();
1649
1650 if(pReplacement)
1651 {
1652 rtl::Reference<SdrObject> pCandidate(pReplacement->CloneSdrObject(pReplacement->getSdrModelFromSdrObject()));
1653 DBG_ASSERT(pCandidate, "SdrEditView::ImpDismantleOneObject: Could not clone SdrObject (!)");
1654
1655 if(pCustomShape->GetMergedItem(SDRATTR_SHADOW).GetValue())
1656 {
1657 if(dynamic_cast<const SdrObjGroup*>( pReplacement) != nullptr)
1658 {
1659 pCandidate->SetMergedItem(makeSdrShadowItem(true));
1660 }
1661 }
1662
1663 rOL.InsertObject(pCandidate.get(), rPos);
1664 if( bUndo )
1665 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoNewObject(*pCandidate, true));
1666 MarkObj(pCandidate.get(), pPV, false, true);
1667
1668 if(pCustomShape->HasText() && !pCustomShape->IsTextPath())
1669 {
1670 // #i37011# also create a text object and add at rPos + 1
1672 pCustomShape->getSdrModelFromSdrObject(),
1673 pCustomShape->GetObjInventor(),
1675
1676 // Copy text content
1677 OutlinerParaObject* pParaObj = pCustomShape->GetOutlinerParaObject();
1678 if(pParaObj)
1679 {
1680 pTextObj->NbcSetOutlinerParaObject(*pParaObj);
1681 }
1682
1683 // copy all attributes
1684 SfxItemSet aTargetItemSet(pCustomShape->GetMergedItemSet());
1685
1686 // clear fill and line style
1687 aTargetItemSet.Put(XLineStyleItem(drawing::LineStyle_NONE));
1688 aTargetItemSet.Put(XFillStyleItem(drawing::FillStyle_NONE));
1689
1690 // get the text bounds and set at text object
1691 tools::Rectangle aTextBounds = pCustomShape->GetSnapRect();
1692 if(pCustomShape->GetTextBounds(aTextBounds))
1693 {
1694 pTextObj->SetSnapRect(aTextBounds);
1695 }
1696
1697 // if rotated, copy GeoStat, too.
1698 const GeoStat& rSourceGeo = pCustomShape->GetGeoStat();
1699 if(rSourceGeo.m_nRotationAngle)
1700 {
1701 pTextObj->NbcRotate(
1702 pCustomShape->GetSnapRect().Center(), rSourceGeo.m_nRotationAngle,
1703 rSourceGeo.mfSinRotationAngle, rSourceGeo.mfCosRotationAngle);
1704 }
1705
1706 // set modified ItemSet at text object
1707 pTextObj->SetMergedItemSet(aTargetItemSet);
1708
1709 // insert object
1710 rOL.InsertObject(pTextObj.get(), rPos + 1);
1711 if( bUndo )
1712 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoNewObject(*pTextObj, true));
1713 MarkObj(pTextObj.get(), pPV, false, true);
1714 }
1715 }
1716 }
1717 }
1718}
1719
1721{
1722 // temporary MarkList
1723 SdrMarkList aRemoveBuffer;
1724
1726
1727 const bool bUndo = IsUndoEnabled();
1728
1729 if( bUndo )
1730 {
1731 // comment is constructed later
1733 }
1734
1735 SdrObjList* pOL0=nullptr;
1736 const bool bWasLocked = GetModel().isLocked();
1737 GetModel().setLock(true);
1738 for (size_t nm=GetMarkedObjectCount(); nm>0;) {
1739 --nm;
1740 SdrMark* pM=GetSdrMarkByIndex(nm);
1741 SdrObject* pObj=pM->GetMarkedSdrObj();
1742 SdrPageView* pPV=pM->GetPageView();
1744 if (pOL!=pOL0) { pOL0=pOL; pObj->GetOrdNum(); } // make sure OrdNums are correct!
1745 if (ImpCanDismantle(pObj,bMakeLines)) {
1746 aRemoveBuffer.InsertEntry(SdrMark(pObj,pM->GetPageView()));
1747 const size_t nPos0=pObj->GetOrdNumDirect();
1748 size_t nPos=nPos0+1;
1749 SdrObjList* pSubList=pObj->GetSubList();
1750 if (pSubList!=nullptr && !pObj->Is3DObj()) {
1752 while (aIter.IsMore()) {
1753 const SdrObject* pObj1=aIter.Next();
1754 ImpDismantleOneObject(pObj1,*pOL,nPos,pPV,bMakeLines);
1755 }
1756 } else {
1757 ImpDismantleOneObject(pObj,*pOL,nPos,pPV,bMakeLines);
1758 }
1759 if( bUndo )
1760 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoDeleteObject(*pObj,true));
1761 pOL->RemoveObject(nPos0);
1762 }
1763 }
1764 GetModel().setLock(bWasLocked);
1765
1766 if( bUndo )
1767 {
1768 // construct UndoComment from objects actually used
1769 SetUndoComment(SvxResId(bMakeLines?STR_EditDismantle_Lines:STR_EditDismantle_Polys),aRemoveBuffer.GetMarkDescription());
1770 // remove objects actually used from the list
1771 EndUndo();
1772 }
1773}
1774
1775
1776// Group
1777
1778
1780{
1781 if (!AreObjectsMarked())
1782 return;
1783
1785
1786 const bool bUndo = IsUndoEnabled();
1787 if( bUndo )
1788 {
1790
1791 for(size_t nm = GetMarkedObjectCount(); nm>0; )
1792 {
1793 // add UndoActions for all affected objects
1794 --nm;
1795 SdrMark* pM=GetSdrMarkByIndex(nm);
1796 SdrObject* pObj = pM->GetMarkedSdrObj();
1798 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoRemoveObject( *pObj ));
1799 }
1800 }
1801
1802 SdrMarkList aNewMark;
1803 SdrPageView* pPV = GetSdrPageView();
1804
1805 if(pPV)
1806 {
1807 SdrObjList* pCurrentLst=pPV->GetObjList();
1808 SdrObjList* pSrcLst=pCurrentLst;
1809 SdrObjList* pSrcLst0=pSrcLst;
1810 // make sure OrdNums are correct
1811 if (pSrcLst->IsObjOrdNumsDirty())
1812 pSrcLst->RecalcObjOrdNums();
1814 SdrObjList* pDstLst=nullptr;
1815 // if all selected objects come from foreign object lists.
1816 // the group object is the last one in the list.
1817 size_t nInsPos=pSrcLst->GetObjCount();
1818 bool bNeedInsPos=true;
1819 for (size_t nm=GetMarkedObjectCount(); nm>0;)
1820 {
1821 --nm;
1822 SdrMark* pM=GetSdrMarkByIndex(nm);
1823 if (pM->GetPageView()==pPV)
1824 {
1825 SdrObject* pObj=pM->GetMarkedSdrObj();
1826 if (!pGrp)
1827 {
1828 pGrp = new SdrObjGroup(pObj->getSdrModelFromSdrObject());
1829 pDstLst=pGrp->GetSubList();
1830 assert(pDstLst && "Alleged group object doesn't return object list.");
1831 }
1832 pSrcLst=pObj->getParentSdrObjListFromSdrObject();
1833 if (pSrcLst!=pSrcLst0)
1834 {
1835 if (pSrcLst->IsObjOrdNumsDirty())
1836 pSrcLst->RecalcObjOrdNums();
1837 }
1838 bool bForeignList=pSrcLst!=pCurrentLst;
1839 if (!bForeignList && bNeedInsPos)
1840 {
1841 nInsPos=pObj->GetOrdNum(); // this way, all ObjOrdNum of the page are set
1842 nInsPos++;
1843 bNeedInsPos=false;
1844 }
1845 pSrcLst->RemoveObject(pObj->GetOrdNumDirect());
1846 if (!bForeignList)
1847 nInsPos--; // correct InsertPos
1848 pDstLst->InsertObject(pObj,0);
1850 pSrcLst0=pSrcLst;
1851 }
1852 }
1853 if (pGrp!=nullptr)
1854 {
1855 assert(pDstLst); // keep coverity happy
1856 aNewMark.InsertEntry(SdrMark(pGrp.get(),pPV));
1857 const size_t nCount=pDstLst->GetObjCount();
1858 pCurrentLst->InsertObject(pGrp.get(),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 }
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 )
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 size_t nObjCount=pSrcLst->GetObjCount();
1915 const bool bIsDiagram(pGrp->isDiagram());
1916
1917 // If the Group is a Diagram, it has a filler BG object to guarantee
1918 // the Diagam's dimensions. Identify that shape
1919 if(bIsDiagram && nObjCount)
1920 {
1921 SdrObject* pObj(pSrcLst->GetObj(0));
1922
1923 if(nullptr != pObj && !pObj->IsGroupObject() &&
1924 !pObj->HasLineStyle() &&
1925 pObj->IsMoveProtect() && pObj->IsResizeProtect())
1926 {
1927 if(pObj->HasFillStyle())
1928 {
1929 // If it has FillStyle it is a useful object representing that possible
1930 // defined fill from oox import. In this case, we should remove the
1931 // Move/Resize protection to allow seamless further processing.
1932
1933 // Undo of these is handled by SdrUndoGeoObj which holds a SdrObjGeoData,
1934 // create one
1935 if( bUndo )
1936 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
1937
1938 pObj->SetMoveProtect(false);
1939 pObj->SetResizeProtect(false);
1940 }
1941 else
1942 {
1943 // If it has no FillStyle it is not useful for any further processing
1944 // but only was used as a placeholder, get directly rid of it
1945 if( bUndo )
1946 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoDeleteObject(*pObj));
1947
1948 pSrcLst->RemoveObject(0);
1949
1950 nObjCount = pSrcLst->GetObjCount();
1951 }
1952 }
1953 }
1954
1955 // FIRST move contained objects to parent of group, so that
1956 // the contained objects are NOT migrated to the UNDO-ItemPool
1957 // when AddUndo(new SdrUndoDelObj(*pGrp)) is called.
1958 if( bUndo )
1959 {
1960 for (size_t no=nObjCount; no>0;)
1961 {
1962 no--;
1963 SdrObject* pObj=pSrcLst->GetObj(no);
1964 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoRemoveObject(*pObj));
1965 }
1966 }
1967
1968 for (size_t no=0; no<nObjCount; ++no)
1969 {
1970 rtl::Reference<SdrObject> pObj=pSrcLst->RemoveObject(0);
1971 pDstLst->InsertObject(pObj.get(),nDstCnt);
1972 if( bUndo )
1973 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoInsertObject(*pObj,true));
1974 nDstCnt++;
1975 // No SortCheck when inserting into MarkList, because that would
1976 // provoke a RecalcOrdNums() each time because of pObj->GetOrdNum():
1977 aNewMark.InsertEntry(SdrMark(pObj.get(),pM->GetPageView()),false);
1978 }
1979
1980 if( bUndo )
1981 {
1982 // Now it is safe to add the delete-UNDO which triggers the
1983 // MigrateItemPool now only for itself, not for the sub-objects.
1984 // nDstCnt is right, because previous inserts move group
1985 // object deeper and increase nDstCnt.
1986 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoDeleteObject(*pGrp));
1987 }
1988 pDstLst->RemoveObject(nDstCnt);
1989
1991 }
1992 }
1993 if (nCount!=0)
1994 {
1995 if (!bNameOk)
1996 aName=SvxResId(STR_ObjNamePluralGRUP); // Use the term "Group Objects," if different objects are grouped.
1997 SetUndoComment(SvxResId(STR_EditUngroup),aName);
1998 }
1999
2000 if( bUndo )
2001 EndUndo();
2002
2003 if (nCount!=0)
2004 {
2005 GetMarkedObjectListWriteAccess().Merge(aNewMark,true); // Because of the sorting above, aNewMark is reversed
2007 }
2008}
2009
2010
2011// ConvertToPoly
2012
2013
2015{
2016 rtl::Reference<SdrObject> pNewObj = pObj->ConvertToPolyObj(bPath, bLineToArea);
2017 if (pNewObj)
2018 {
2020 const bool bUndo = IsUndoEnabled();
2021 if( bUndo )
2022 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoReplaceObject(*pObj,*pNewObj));
2023
2024 pOL->ReplaceObject(pNewObj.get(), pObj->GetOrdNum());
2025 }
2026 return pNewObj;
2027}
2028
2029void SdrEditView::ImpConvertTo(bool bPath, bool bLineToArea)
2030{
2031 if (!AreObjectsMarked()) return;
2032
2033 bool bMrkChg = false;
2034 const size_t nMarkCount=GetMarkedObjectCount();
2035 TranslateId pDscrID;
2036 if(bLineToArea)
2037 {
2038 if(nMarkCount == 1)
2039 pDscrID = STR_EditConvToContour;
2040 else
2041 pDscrID = STR_EditConvToContours;
2042
2044 }
2045 else
2046 {
2047 if (bPath) {
2048 if (nMarkCount==1) pDscrID=STR_EditConvToCurve;
2049 else pDscrID=STR_EditConvToCurves;
2051 } else {
2052 if (nMarkCount==1) pDscrID=STR_EditConvToPoly;
2053 else pDscrID=STR_EditConvToPolys;
2055 }
2056 }
2057 for (size_t nm=nMarkCount; nm>0;) {
2058 --nm;
2059 SdrMark* pM=GetSdrMarkByIndex(nm);
2060 SdrObject* pObj=pM->GetMarkedSdrObj();
2061 SdrPageView* pPV=pM->GetPageView();
2062 if (pObj->IsGroupObject() && !pObj->Is3DObj()) {
2063 SdrObject* pGrp=pObj;
2065 while (aIter.IsMore()) {
2066 pObj=aIter.Next();
2067 ImpConvertOneObj(pObj,bPath,bLineToArea);
2068 }
2069 } else {
2070 rtl::Reference<SdrObject> pNewObj=ImpConvertOneObj(pObj,bPath,bLineToArea);
2071 if (pNewObj) {
2072 bMrkChg=true;
2073 GetMarkedObjectListWriteAccess().ReplaceMark(SdrMark(pNewObj.get(),pPV),nm);
2074 }
2075 }
2076 }
2077 EndUndo();
2078 if (bMrkChg)
2079 {
2080 AdjustMarkHdl();
2082 }
2083}
2084
2086{
2087 ImpConvertTo(true, bLineToArea);
2088}
2089
2091{
2092 ImpConvertTo(false, false/*bLineToArea*/);
2093}
2094
2095namespace
2096{
2097 GDIMetaFile GetMetaFile(SdrGrafObj const * pGraf)
2098 {
2099 if (pGraf->HasGDIMetaFile())
2101 assert(pGraf->isEmbeddedVectorGraphicData());
2103 }
2104}
2105
2106// Metafile Import
2108{
2109 const bool bUndo = IsUndoEnabled();
2110
2111 if( bUndo )
2113
2115 SdrMarkList aForTheDescription;
2116 SdrMarkList aNewMarked;
2117 for (size_t nm =GetMarkedObjectCount(); nm > 0; )
2118 {
2119 // create Undo objects for all new objects
2120 // check for cancellation between the metafiles
2121 if (pProgrInfo != nullptr)
2122 {
2123 pProgrInfo->SetNextObject();
2124 if (!pProgrInfo->ReportActions(0))
2125 break;
2126 }
2127
2128 --nm;
2129 SdrMark* pM=GetSdrMarkByIndex(nm);
2130 SdrObject* pObj=pM->GetMarkedSdrObj();
2131 SdrPageView* pPV=pM->GetPageView();
2133 const size_t nInsPos=pObj->GetOrdNum()+1;
2134 size_t nInsCnt=0;
2135 tools::Rectangle aLogicRect;
2136
2137 SdrGrafObj* pGraf = dynamic_cast<SdrGrafObj*>( pObj );
2138 if (pGraf != nullptr)
2139 {
2140 Graphic aGraphic = pGraf->GetGraphic();
2141 auto const & pVectorGraphicData = aGraphic.getVectorGraphicData();
2142
2143 if (pVectorGraphicData && pVectorGraphicData->getType() == VectorGraphicDataType::Pdf)
2144 {
2145 auto pPdfium = vcl::pdf::PDFiumLibrary::get();
2146 if (pPdfium)
2147 {
2148 aLogicRect = pGraf->GetLogicRect();
2149 ImpSdrPdfImport aFilter(GetModel(), pObj->GetLayer(), aLogicRect, aGraphic);
2150 if (aGraphic.getPageNumber() < aFilter.GetPageCount())
2151 {
2152 nInsCnt = aFilter.DoImport(*pOL, nInsPos, aGraphic.getPageNumber(), pProgrInfo);
2153 }
2154 }
2155 }
2156 else if (pGraf->HasGDIMetaFile() || pGraf->isEmbeddedVectorGraphicData() )
2157 {
2158 GDIMetaFile aMetaFile(GetMetaFile(pGraf));
2159 if (aMetaFile.GetActionSize())
2160 {
2161 aLogicRect = pGraf->GetLogicRect();
2162 ImpSdrGDIMetaFileImport aFilter(GetModel(), pObj->GetLayer(), aLogicRect);
2163 nInsCnt = aFilter.DoImport(aMetaFile, *pOL, nInsPos, pProgrInfo);
2164 }
2165 }
2166 }
2167
2168 SdrOle2Obj* pOle2 = dynamic_cast<SdrOle2Obj*>(pObj);
2169 if (pOle2 != nullptr && pOle2->GetGraphic())
2170 {
2171 aLogicRect = pOle2->GetLogicRect();
2172 ImpSdrGDIMetaFileImport aFilter(GetModel(), pObj->GetLayer(), aLogicRect);
2173 nInsCnt = aFilter.DoImport(pOle2->GetGraphic()->GetGDIMetaFile(), *pOL, nInsPos, pProgrInfo);
2174 }
2175
2176 if (nInsCnt != 0)
2177 {
2178 // transformation
2179 GeoStat aGeoStat(pGraf ? pGraf->GetGeoStat() : pOle2->GetGeoStat());
2180 size_t nObj = nInsPos;
2181
2182 if (aGeoStat.m_nShearAngle)
2183 aGeoStat.RecalcTan();
2184
2185 if (aGeoStat.m_nRotationAngle)
2186 aGeoStat.RecalcSinCos();
2187
2188 for (size_t i = 0; i < nInsCnt; i++)
2189 {
2190 if (bUndo)
2191 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoNewObject(*pOL->GetObj(nObj)));
2192
2193 // update new MarkList
2194 SdrObject* pCandidate = pOL->GetObj(nObj);
2195
2196 // apply original transformation
2197 if (aGeoStat.m_nShearAngle)
2198 pCandidate->NbcShear(aLogicRect.TopLeft(), aGeoStat.m_nShearAngle, aGeoStat.mfTanShearAngle, false);
2199
2200 if (aGeoStat.m_nRotationAngle)
2201 pCandidate->NbcRotate(aLogicRect.TopLeft(), aGeoStat.m_nRotationAngle, aGeoStat.mfSinRotationAngle, aGeoStat.mfCosRotationAngle);
2202
2203 SdrMark aNewMark(pCandidate, pPV);
2204 aNewMarked.InsertEntry(aNewMark);
2205
2206 nObj++;
2207 }
2208
2209 aForTheDescription.InsertEntry(*pM);
2210
2211 if (bUndo)
2212 AddUndo(GetModel().GetSdrUndoFactory().CreateUndoDeleteObject(*pObj));
2213
2214 // remove object from selection and delete
2216 pOL->RemoveObject(nInsPos-1);
2217 }
2218 }
2219
2220 if (aNewMarked.GetMarkCount())
2221 {
2222 // create new selection
2223 for (size_t a = 0; a < aNewMarked.GetMarkCount(); ++a)
2224 {
2226 }
2227
2229 }
2230
2231 if (bUndo)
2232 {
2233 SetUndoComment(SvxResId(STR_EditImportMtf),aForTheDescription.GetMarkDescription());
2234 EndUndo();
2235 }
2236}
2237
2238/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
size_t GetActionSize() const
The transformation of a rectangle into a polygon, by using angle parameters from GeoStat.
Definition: svdtrans.hxx:201
double mfTanShearAngle
Definition: svdtrans.hxx:205
double mfCosRotationAngle
Definition: svdtrans.hxx:207
double mfSinRotationAngle
Definition: svdtrans.hxx:206
void RecalcTan()
Definition: svdtrans.cxx:456
void RecalcSinCos()
Definition: svdtrans.cxx:444
Degree100 m_nShearAngle
Definition: svdtrans.hxx:204
Degree100 m_nRotationAngle
Definition: svdtrans.hxx:203
const GDIMetaFile & GetGDIMetaFile() const
sal_Int32 getPageNumber() const
const std::shared_ptr< VectorGraphicData > & getVectorGraphicData() const
size_t DoImport(const GDIMetaFile &rMtf, SdrObjList &rDestList, size_t nInsPos, SvdProgressInfo *pProgrInfo=nullptr)
Definition: svdfmtf.cxx:207
size_t DoImport(SdrObjList &rDestList, size_t nInsPos, int nPageNumber, SvdProgressInfo *pProgrInfo=nullptr)
Definition: svdpdf.cxx:213
int GetPageCount() const
Definition: svdpdf.hxx:135
OUString GetText(Paragraph const *pPara, sal_Int32 nParaCount=1) const
void AddText(const OutlinerParaObject &, bool bAppend=false)
Paragraph * GetParagraph(sal_Int32 nAbsPos) const
std::optional< OutlinerParaObject > CreateParaObject(sal_Int32 nStartPara=0, sal_Int32 nParaCount=EE_PARA_ALL) const
sal_Int32 GetParagraphCount() const
virtual const tools::Rectangle & GetSnapRect() const override
Definition: svdoattr.cxx:49
bool m_bToTopPossible
Definition: svdedtv.hxx:85
void PutMarkedToTop()
Definition: svdedtv2.cxx:249
static bool ImpCanDismantle(const basegfx::B2DPolyPolygon &rPpolyPpolygon, bool bMakeLines)
Definition: svdedtv2.cxx:1463
void UnGroupMarked()
Definition: svdedtv2.cxx:1880
void PutMarkedBehindObj(const SdrObject *pRefObj)
Definition: svdedtv2.cxx:355
bool IsUndoEnabled() const
Definition: svdedtv.cxx:1056
void EqualizeMarkedObjects(bool bWidth)
Definition: svdedtv2.cxx:1168
virtual void MarkListHasChanged() override
Definition: svdedtv.cxx:371
virtual void ObjOrderChanged(SdrObject *pObj, size_t nOldPos, size_t nNewPos)
Definition: svdedtv2.cxx:68
void ConvertMarkedToPathObj(bool bLineToArea)
Definition: svdedtv2.cxx:2085
static basegfx::B2DPolyPolygon ImpGetPolyPolygon(const SdrObject *pObj)
Definition: svdedtv2.cxx:669
static bool ImpCanConvertForCombine1(const SdrObject *pObj)
Definition: svdedtv2.cxx:574
void MergeMarkedObjects(SdrMergeMode eMode)
Definition: svdedtv2.cxx:991
void ReverseOrderOfMarked()
Definition: svdedtv2.cxx:435
void MovMarkedToTop()
Definition: svdedtv2.cxx:72
virtual SdrObject * GetMaxToTopObj(SdrObject *pObj) const
Definition: svdedtv2.cxx:58
std::vector< rtl::Reference< SdrObject > > DeleteMarkedList(SdrMarkList const &rMark)
Definition: svdedtv.cxx:715
void AddUndo(std::unique_ptr< SdrUndoAction > pUndo)
Definition: svdedtv.hxx:196
void GroupMarked()
Definition: svdedtv2.cxx:1779
void BegUndo()
Definition: svdedtv.hxx:178
void ImpDismantleOneObject(const SdrObject *pObj, SdrObjList &rOL, size_t &rPos, SdrPageView *pPV, bool bMakeLines)
Definition: svdedtv2.cxx:1565
std::vector< std::unique_ptr< SdrUndoAction > > CreateConnectorUndo(const SdrObject &rO)
Definition: svdedtv1.cxx:150
virtual SdrObject * GetMaxToBtmObj(SdrObject *pObj) const
Definition: svdedtv2.cxx:63
bool InsertObjectAtView(SdrObject *pObj, SdrPageView &rPV, SdrInsertFlags nOptions=SdrInsertFlags::NONE)
Definition: svdedtv.cxx:978
void DeleteMarkedObj()
Definition: svdedtv.cxx:794
void DismantleMarkedObjects(bool bMakeLines=false)
Definition: svdedtv2.cxx:1720
void AddUndoActions(std::vector< std::unique_ptr< SdrUndoAction > >)
Definition: svdedtv1.cxx:177
void CombineMarkedTextObjects()
Definition: svdedtv2.cxx:1222
void MovMarkedToBtm()
Definition: svdedtv2.cxx:159
void DoImportMarkedMtf(SvdProgressInfo *pProgrInfo=nullptr)
Definition: svdedtv2.cxx:2107
void ImpConvertTo(bool bPath, bool bLineToArea)
Definition: svdedtv2.cxx:2029
void CombineMarkedObjects(bool bNoPolyPoly=true)
Definition: svdedtv2.cxx:1286
void ConvertMarkedToPolyObj()
Definition: svdedtv2.cxx:2090
bool m_bToBtmPossible
Definition: svdedtv.hxx:86
void SetUndoComment(const OUString &rComment, const OUString &rObjDescr)
Definition: svdedtv.hxx:203
void ImpCheckToTopBtmPossible()
Definition: svdedtv2.cxx:487
void PutMarkedInFrontOfObj(const SdrObject *pRefObj)
Definition: svdedtv2.cxx:254
void PutMarkedToBtm()
Definition: svdedtv2.cxx:350
void DistributeMarkedObjects(sal_uInt16 SlotID)
Definition: svdedtv2.cxx:772
static bool ImpCanConvertForCombine(const SdrObject *pObj)
Definition: svdedtv2.cxx:592
rtl::Reference< SdrObject > ImpConvertOneObj(SdrObject *pObj, bool bPath, bool bLineToArea)
Definition: svdedtv2.cxx:2014
void ImpCopyAttributes(const SdrObject *pSource, SdrObject *pDest) const
Definition: svdedtv2.cxx:548
static basegfx::B2DPolyPolygon ImpGetPolyPolygon1(const SdrObject *pObj)
Definition: svdedtv2.cxx:622
static basegfx::B2DPolygon ImpCombineToSinglePolygon(const basegfx::B2DPolyPolygon &rPolyPolygon)
Definition: svdedtv2.cxx:692
void EndUndo()
Definition: svdedtv.cxx:295
This class represents an embedded or linked bitmap graphic object.
Definition: svdograf.hxx:68
bool HasGDIMetaFile() const
Definition: svdograf.cxx:844
GDIMetaFile getMetafileFromEmbeddedVectorGraphicData() const
Definition: svdograf.cxx:854
Graphic GetTransformedGraphic(SdrGrafObjTransformsAttrs nTransformFlags=SdrGrafObjTransformsAttrs::ALL) const
Definition: svdograf.cxx:386
const Graphic & GetGraphic() const
Definition: svdograf.cxx:381
bool isEmbeddedVectorGraphicData() const
Definition: svdograf.cxx:849
const OUString & GetMarkDescription() const
Definition: svdmark.cxx:416
void ForceSort() const
Definition: svdmark.cxx:142
void ReplaceMark(const SdrMark &rNewMark, size_t nNum)
Definition: svdmark.cxx:330
size_t GetMarkCount() const
Definition: svdmark.hxx:178
void InsertEntry(const SdrMark &rMark, bool bChkSort=true)
Definition: svdmark.cxx:260
SdrMark * GetMark(size_t nNum) const
Definition: svdmark.cxx:230
void DeleteMark(size_t nNum)
Definition: svdmark.cxx:316
void Merge(const SdrMarkList &rSrcList, bool bReverse=false)
Definition: svdmark.cxx:343
const SdrMarkList & GetMarkedObjectList() const
Definition: svdmrkv.hxx:258
bool AreObjectsMarked() const
Definition: svdmrkv.hxx:266
void SortMarkedObjects() const
Definition: svdmrkv.hxx:265
SdrObject * GetMarkedObjectByIndex(size_t nNum) const
Definition: svdmrkv.hxx:263
SdrMarkList & GetMarkedObjectListWriteAccess()
Definition: svdmrkv.hxx:254
tools::Rectangle GetAllMarkedBoundRect() const
Definition: svdmrkv.hxx:427
size_t GetMarkedObjectCount() const
Definition: svdmrkv.hxx:264
SdrMark * GetSdrMarkByIndex(size_t nNum) const
Definition: svdmrkv.hxx:262
void UnmarkAllObj(SdrPageView const *pPV=nullptr)
Definition: svdmrkv.cxx:2567
OUString const & GetDescriptionOfMarkedObjects() const
Definition: svdmrkv.hxx:267
SdrPageView * GetSdrPageViewOfMarkedByIndex(size_t nNum) const
Definition: svdmrkv.hxx:261
const tools::Rectangle & GetMarkedObjRect() const
Definition: svdmrkv.cxx:2636
size_t TryToFindMarkedObject(const SdrObject *pObj) const
Definition: svdmrkv.hxx:260
void AdjustMarkHdl(SfxViewShell *pOtherShell=nullptr)
Definition: svdmrkv.cxx:2614
bool MarkObj(const Point &rPnt, short nTol=-2, bool bToggle=false, bool bDeep=false)
Definition: svdmrkv.cxx:1941
Everything a View needs to know about a selected object.
Definition: svdmark.hxx:45
SdrPageView * GetPageView() const
Definition: svdmark.hxx:70
SdrObject * GetMarkedSdrObj() const
Definition: svdmark.hxx:68
sal_Int64 getTimeStamp() const
Definition: svdmark.hxx:130
bool isLocked() const
Definition: svdmodel.hxx:555
SdrOutliner & GetDrawOutliner(const SdrTextObj *pObj=nullptr) const
Definition: svdmodel.cxx:664
void setLock(bool bLock)
Definition: svdmodel.cxx:1607
void SetUndoComment(const OUString &rComment)
Definition: svdmodel.cxx:485
virtual bool IsTextPath() const override
Definition: svdoashp.cxx:445
const SdrObject * GetSdrObjectFromCustomShape() const
Definition: svdoashp.cxx:407
bool GetTextBounds(tools::Rectangle &rTextBound) const
Definition: svdoashp.cxx:538
static rtl::Reference< SdrObject > MakeNewObject(SdrModel &rSdrModel, SdrInventor nInventor, SdrObjKind nObjIdentifier, const tools::Rectangle *pSnapRect=nullptr)
Definition: svdobj.cxx:3279
SdrObject * Next()
Definition: svditer.hxx:63
bool IsMore() const
Definition: svditer.hxx:62
virtual rtl::Reference< SdrObject > ReplaceObject(SdrObject *pNewObj, size_t nObjNum)
Replace existing object by different one.
Definition: svdpage.cxx:429
virtual SdrObject * SetObjectOrdNum(size_t nOldObjNum, size_t nNewObjNum)
Modify ZOrder of an SdrObject.
Definition: svdpage.cxx:493
virtual void InsertObject(SdrObject *pObj, size_t nPos=SAL_MAX_SIZE)
Definition: svdpage.cxx:295
SdrObject * GetObj(size_t nNum) const
Definition: svdpage.cxx:785
size_t GetObjCount() const
Definition: svdpage.cxx:779
void RecalcObjOrdNums()
recalculate order numbers / ZIndex
Definition: svdpage.cxx:198
bool IsObjOrdNumsDirty() const
Definition: svdpage.hxx:104
virtual rtl::Reference< SdrObject > RemoveObject(size_t nObjNum)
Definition: svdpage.cxx:373
Provides information about various ZObject properties.
Definition: svdobj.hxx:196
Abstract DrawObject.
Definition: svdobj.hxx:260
sal_uInt32 GetOrdNumDirect() const
Definition: svdobj.hxx:844
bool IsResizeProtect() const
Definition: svdobj.hxx:758
const SfxPoolItem & GetMergedItem(const sal_uInt16 nWhich) const
Definition: svdobj.cxx:2009
virtual void NbcSetLayer(SdrLayerID nLayer)
Definition: svdobj.cxx:664
void SetOutlinerParaObject(std::optional< OutlinerParaObject > pTextObject)
Definition: svdobj.cxx:1798
virtual OUString TakeObjNamePlural() const
Definition: svdobj.cxx:1097
bool isDiagram() const
Definition: svdobj.hxx:264
bool IsMoveProtect() const
Definition: svdobj.hxx:756
virtual SdrInventor GetObjInventor() const
Definition: svdobj.cxx:621
virtual OutlinerParaObject * GetOutlinerParaObject() const
Definition: svdobj.cxx:1833
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:905
virtual SdrObjList * GetSubList() const
Definition: svdobj.cxx:717
void SetMergedItemSet(const SfxItemSet &rSet, bool bClearAllItems=false)
Definition: svdobj.cxx:1999
rtl::Reference< SdrObject > ConvertToPolyObj(bool bBezier, bool bLineToArea) const
Definition: svdobj.cxx:2620
void NbcSetStyleSheet(SfxStyleSheet *pNewStyleSheet, bool bDontRemoveHardAttr)
Definition: svdobj.cxx:2262
bool Is3DObj() const
Definition: svdobj.hxx:753
virtual const tools::Rectangle & GetCurrentBoundRect() const
Definition: svdobj.cxx:962
void SetResizeProtect(bool bProt)
Definition: svdobj.cxx:2677
SdrObjList * getParentSdrObjListFromSdrObject() const
Definition: svdobj.cxx:318
SdrModel & getSdrModelFromSdrObject() const
Definition: svdobj.cxx:289
virtual void NbcShear(const Point &rRef, Degree100 nAngle, double tn, bool bVShear)
Definition: svdobj.cxx:1524
virtual void SetLogicRect(const tools::Rectangle &rRect)
Definition: svdobj.cxx:1696
SfxStyleSheet * GetStyleSheet() const
Definition: svdobj.cxx:2244
void SetMoveProtect(bool bProt)
Definition: svdobj.cxx:2666
bool IsGroupObject() const
Definition: svdobj.cxx:712
bool HasLineStyle() const
Definition: svdobj.cxx:3053
virtual rtl::Reference< SdrObject > CloneSdrObject(SdrModel &rTargetModel) const =0
const SfxItemSet & GetMergedItemSet() const
Definition: svdobj.cxx:1974
virtual OUString TakeObjNameSingul() const
Definition: svdobj.cxx:1087
void ClearMergedItem(const sal_uInt16 nWhich=0)
Definition: svdobj.cxx:1989
virtual SdrLayerID GetLayer() const
Definition: svdobj.cxx:645
bool HasFillStyle() const
Definition: svdobj.cxx:3048
virtual void TakeObjInfo(SdrObjTransformInfoRec &rInfo) const
Definition: svdobj.cxx:631
virtual const tools::Rectangle & GetLogicRect() const
Definition: svdobj.cxx:1672
virtual void NbcRotate(const Point &rRef, Degree100 nAngle, double sn, double cs)=0
const Graphic * GetGraphic() const
Definition: svdoole2.cxx:1700
SdrObjList * GetObjList() const
Return current List.
Definition: svdpagv.hxx:169
bool IsLayerLocked(const OUString &rName) const
Definition: svdpagv.hxx:193
SdrModel & getSdrModelFromSdrView() const
Definition: svdpntv.hxx:280
SdrPageView * GetSdrPageView() const
Definition: svdpntv.hxx:323
SdrModel & GetModel() const
Definition: svdpntv.hxx:282
const OUString & GetActiveLayer() const
Definition: svdpntv.hxx:443
bool IsLine() const
Definition: svdopath.hxx:147
virtual SdrObjKind GetObjIdentifier() const override
Definition: svdopath.cxx:1818
const basegfx::B2DPolyPolygon & GetPathPoly() const
Definition: svdopath.hxx:141
Rectangle objects (rectangle, circle, ...)
Definition: svdorect.hxx:39
virtual OutlinerParaObject * GetOutlinerParaObject() const override
Definition: svdotext.cxx:1412
virtual const tools::Rectangle & GetLogicRect() const override
Definition: svdotxtr.cxx:70
virtual bool HasText() const override
Definition: svdotxat.cxx:420
bool IsOutlText() const
Definition: svdotext.hxx:360
bool IsTextFrame() const
Definition: svdotext.hxx:359
virtual SdrObjKind GetObjIdentifier() const override
Definition: svdotext.cxx:453
const GeoStat & GetGeoStat() const
Definition: svdotext.hxx:419
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
constexpr tools::Long Height() const
void setWidth(tools::Long nWidth)
void setHeight(tools::Long nHeight)
constexpr tools::Long Width() const
Helper class for the communication between the dialog In order to break open Metafiles (sd/source/ui/...
Definition: svdetc.hxx:111
bool ReportActions(size_t nActionCount)
Definition: svdetc.cxx:425
void SetNextObject()
Definition: svdetc.cxx:459
void insert(sal_uInt32 nIndex, const B2DPolygon &rPolygon, sal_uInt32 nCount=1)
B2DPolygon const & getB2DPolygon(sal_uInt32 nIndex) const
void append(const B2DPolygon &rPolygon, sal_uInt32 nCount=1)
void setClosed(bool bNew)
sal_uInt32 count() const
bool isClosed() const
basegfx::B2DPoint const & getB2DPoint(sal_uInt32 nIndex) const
basegfx::B2DPoint getPrevControlPoint(sal_uInt32 nIndex) const
bool areControlPointsUsed() const
void append(const basegfx::B2DPoint &rPoint, sal_uInt32 nCount)
sal_uInt32 count() const
basegfx::B2DPoint getNextControlPoint(sal_uInt32 nIndex) const
void appendBezierSegment(const basegfx::B2DPoint &rNextControlPoint, const basegfx::B2DPoint &rPrevControlPoint, const basegfx::B2DPoint &rPoint)
constexpr Point Center() const
constexpr tools::Long GetWidth() const
bool Overlaps(const tools::Rectangle &rRect) const
void SetSize(const Size &)
constexpr Point TopLeft() const
constexpr Size GetSize() const
constexpr tools::Long GetHeight() const
static bool isWhiteSpace(const sal_uInt32 ch)
int nCount
#define DBG_ASSERT(sCon, aError)
OUString SvxResId(TranslateId aId)
Definition: dialmgr.cxx:24
SvxDistributeVertical
SvxDistributeHorizontal
constexpr sal_uInt16 EE_ITEMS_END(EE_FEATURE_END)
constexpr sal_uInt16 EE_ITEMS_START(OWN_ATTR_VALUE_END+1)
OUString aName
Mode eMode
sal_Int64 n
uno_Any a
sal_uInt16 nPos
#define SAL_WARN_IF(condition, area, stream)
aStr
B2DPolyPolygon prepareForPolygonOperation(const B2DPolygon &rCandidate)
double getLength(const B2DPolygon &rCandidate)
B2DPolyPolygon solvePolygonOperationOr(const B2DPolyPolygon &rCandidateA, const B2DPolyPolygon &rCandidateB)
B2DPolyPolygon solvePolygonOperationAnd(const B2DPolyPolygon &rCandidateA, const B2DPolyPolygon &rCandidateB)
B2DPolygon simplifyCurveSegments(const B2DPolygon &rCandidate)
B2DPolyPolygon solvePolygonOperationDiff(const B2DPolyPolygon &rCandidateA, const B2DPolyPolygon &rCandidateB)
int i
SdrOnOffItem makeSdrShadowItem(bool bShadow)
Definition: sdshitm.hxx:25
static std::shared_ptr< PDFium > & get()
constexpr TypedWhichId< SdrOnOffItem > SDRATTR_SHADOW(SDRATTR_SHADOW_FIRST+0)
constexpr sal_uInt16 SDRATTR_START(XATTR_START)
constexpr sal_uInt16 SDRATTR_NOTPERSIST_LAST(SDRATTR_OBJVISIBLE)
constexpr sal_uInt16 SDRATTR_NOTPERSIST_FIRST(SDRATTR_CIRC_LAST+1)
constexpr sal_uInt16 SDRATTR_END(SDRATTR_WRITINGMODE2_LAST)
std::vector< ImpDistributeEntry > ImpDistributeEntryList
Definition: svdedtv2.cxx:770
SdrMergeMode
Definition: svdedtv.hxx:51
SdrInsertFlags
Definition: svdedtv.hxx:59
SdrTextObj * DynCastSdrTextObj(SdrObject *pObj)
Definition: svdobj.cxx:3212
SdrObjKind
Definition: svdobjkind.hxx:25
@ PathFill
open Bezier-curve
@ PathLine
PolyLine.
@ Text
closed free-hand line
@ PolyLine
polygon, PolyPolygon
constexpr TypedWhichId< XFormTextStyleItem > XATTR_FORMTXTSTYLE(XATTR_TEXT_FIRST)
constexpr TypedWhichId< XLineStyleItem > XATTR_LINESTYLE(XATTR_LINE_FIRST)
constexpr TypedWhichId< XFillStyleItem > XATTR_FILLSTYLE(XATTR_FILL_FIRST)