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