xref: /aoo41x/main/svx/source/svdraw/svdedtv1.cxx (revision f6e50924)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26 
27 #include <svx/svdedtv.hxx>
28 #include <math.h>
29 
30 #ifndef _MATH_H
31 #define _MATH_H
32 #endif
33 #include <tools/bigint.hxx>
34 #include <svl/itemiter.hxx>
35 #include <vcl/msgbox.hxx>
36 #include <svx/rectenum.hxx>
37 #include <svx/svxids.hrc>   // fuer SID_ATTR_TRANSFORM_...
38 #include <svx/svdattr.hxx>  // fuer Get/SetGeoAttr
39 #include "svx/svditext.hxx"
40 #include "svx/svditer.hxx"
41 #include <svx/svdtrans.hxx>
42 #include <svx/svdundo.hxx>
43 #include <svx/svdpage.hxx>
44 #include <svx/svdpagv.hxx>
45 #include <svx/svdlayer.hxx> // fuer MergeNotPersistAttr
46 #include <svx/svdattrx.hxx> // fuer MergeNotPersistAttr
47 #include <svx/svdetc.hxx>   // fuer SearchOutlinerItems
48 #include <svx/svdopath.hxx>  // fuer Crook
49 #include "svx/svdstr.hrc"   // Namen aus der Resource
50 #include "svx/svdglob.hxx"  // StringCache
51 #include <editeng/eeitem.hxx>
52 #include <svl/aeitem.hxx>
53 #include <svl/whiter.hxx>
54 #include <svx/sdr/contact/objectcontact.hxx>
55 #include <svx/sdr/contact/viewcontact.hxx>
56 #include <svx/e3dsceneupdater.hxx>
57 #include <svx/obj3d.hxx>
58 
59 ////////////////////////////////////////////////////////////////////////////////////////////////////
60 ////////////////////////////////////////////////////////////////////////////////////////////////////
61 ////////////////////////////////////////////////////////////////////////////////////////////////////
62 ////////////////////////////////////////////////////////////////////////////////////////////////////
63 //
64 //  @@@@@ @@@@@  @@ @@@@@@  @@ @@ @@ @@@@@ @@   @@
65 //  @@    @@  @@ @@   @@    @@ @@ @@ @@    @@   @@
66 //  @@    @@  @@ @@   @@    @@ @@ @@ @@    @@ @ @@
67 //  @@@@  @@  @@ @@   @@    @@@@@ @@ @@@@  @@@@@@@
68 //  @@    @@  @@ @@   @@     @@@  @@ @@    @@@@@@@
69 //  @@    @@  @@ @@   @@     @@@  @@ @@    @@@ @@@
70 //  @@@@@ @@@@@  @@   @@      @   @@ @@@@@ @@   @@
71 //
72 ////////////////////////////////////////////////////////////////////////////////////////////////////
73 ////////////////////////////////////////////////////////////////////////////////////////////////////
74 
75 void SdrEditView::SetMarkedObjRect(const Rectangle& rRect, sal_Bool bCopy)
76 {
77 	DBG_ASSERT(!rRect.IsEmpty(),"SetMarkedObjRect() mit leerem Rect mach keinen Sinn");
78 	if (rRect.IsEmpty()) return;
79 	sal_uIntPtr nAnz=GetMarkedObjectCount();
80 	if (nAnz==0) return;
81 	Rectangle aR0(GetMarkedObjRect());
82 	DBG_ASSERT(!aR0.IsEmpty(),"SetMarkedObjRect(): GetMarkedObjRect() ist leer");
83 	if (aR0.IsEmpty()) return;
84 	long x0=aR0.Left();
85 	long y0=aR0.Top();
86 	long w0=aR0.Right()-x0;
87 	long h0=aR0.Bottom()-y0;
88 	long x1=rRect.Left();
89 	long y1=rRect.Top();
90 	long w1=rRect.Right()-x1;
91 	long h1=rRect.Bottom()-y1;
92 	XubString aStr;
93 	ImpTakeDescriptionStr(STR_EditPosSize,aStr);
94 	if (bCopy)
95 		aStr+=ImpGetResStr(STR_EditWithCopy);
96 
97 	const bool bUndo = IsUndoEnabled();
98 	if( bUndo )
99 		BegUndo(aStr);
100 
101 	if (bCopy)
102 		CopyMarkedObj();
103 
104 	for (sal_uIntPtr nm=0; nm<nAnz; nm++)
105 	{
106 		SdrMark* pM=GetSdrMarkByIndex(nm);
107 		SdrObject* pO=pM->GetMarkedSdrObj();
108 		if( bUndo )
109 			AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO));
110 
111 		Rectangle aR1(pO->GetSnapRect());
112 		if (!aR1.IsEmpty())
113 		{
114 			if (aR1==aR0)
115 			{
116 				aR1=rRect;
117 			}
118 			else
119 			{ // aR1 von aR0 nach rRect transformieren
120 				aR1.Move(-x0,-y0);
121 				BigInt l(aR1.Left());
122 				BigInt r(aR1.Right());
123 				BigInt t(aR1.Top());
124 				BigInt b(aR1.Bottom());
125 				if (w0!=0) {
126 					l*=w1; l/=w0;
127 					r*=w1; r/=w0;
128 				} else {
129 					l=0; r=w1;
130 				}
131 				if (h0!=0) {
132 					t*=h1; t/=h0;
133 					b*=h1; b/=h0;
134 				} else {
135 					t=0; b=h1;
136 				}
137 				aR1.Left  ()=long(l);
138 				aR1.Right ()=long(r);
139 				aR1.Top   ()=long(t);
140 				aR1.Bottom()=long(b);
141 				aR1.Move(x1,y1);
142 			}
143 			pO->SetSnapRect(aR1);
144 		} else {
145 			DBG_ERROR("SetMarkedObjRect(): pObj->GetSnapRect() liefert leeres Rect");
146 		}
147 	}
148 	if( bUndo )
149 		EndUndo();
150 }
151 
152 std::vector< SdrUndoAction* > SdrEditView::CreateConnectorUndo( SdrObject& rO )
153 {
154 	std::vector< SdrUndoAction* > vUndoActions;
155 
156 	if ( rO.GetBroadcaster() )
157 	{
158 		const SdrPage* pPage = rO.GetPage();
159 		if ( pPage )
160 		{
161 			SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS );
162 			while( aIter.IsMore() )
163 			{
164 				SdrObject* pPartObj = aIter.Next();
165 				if ( pPartObj->ISA( SdrEdgeObj ) )
166 				{
167 					if ( ( pPartObj->GetConnectedNode( sal_False ) == &rO ) ||
168 						 ( pPartObj->GetConnectedNode( sal_True  ) == &rO ) )
169 					{
170 						vUndoActions.push_back( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject( *pPartObj ) );
171 					}
172 				}
173 			}
174 		}
175 	}
176 	return vUndoActions;
177 }
178 
179 void SdrEditView::AddUndoActions( std::vector< SdrUndoAction* >& rUndoActions )
180 {
181 	std::vector< SdrUndoAction* >::iterator aUndoActionIter( rUndoActions.begin() );
182 	while( aUndoActionIter != rUndoActions.end() )
183 		AddUndo( *aUndoActionIter++ );
184 }
185 
186 void SdrEditView::MoveMarkedObj(const Size& rSiz, bool bCopy)
187 {
188 	const bool bUndo = IsUndoEnabled();
189 
190 	if( bUndo )
191 	{
192 		XubString aStr(ImpGetResStr(STR_EditMove));
193 		if (bCopy)
194 			aStr+=ImpGetResStr(STR_EditWithCopy);
195 		// benoetigt eigene UndoGroup wegen Parameter
196 		BegUndo(aStr,GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_MOVE);
197 	}
198 
199 	if (bCopy)
200 		CopyMarkedObj();
201 
202 	sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
203 	for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++)
204 	{
205 		SdrMark* pM=GetSdrMarkByIndex(nm);
206 		SdrObject* pO=pM->GetMarkedSdrObj();
207 		if( bUndo )
208 		{
209 			std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pO ) );
210 			AddUndoActions( vConnectorUndoActions );
211 			AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoMoveObject(*pO,rSiz));
212 		}
213 		pO->Move(rSiz);
214 	}
215 
216 	if( bUndo )
217 		EndUndo();
218 }
219 
220 void SdrEditView::ResizeMarkedObj(const Point& rRef, const Fraction& xFact, const Fraction& yFact, bool bCopy)
221 {
222 	const bool bUndo = IsUndoEnabled();
223 	if( bUndo )
224 	{
225 		XubString aStr;
226 		ImpTakeDescriptionStr(STR_EditResize,aStr);
227 		if (bCopy)
228 			aStr+=ImpGetResStr(STR_EditWithCopy);
229 		BegUndo(aStr);
230 	}
231 
232 	if (bCopy)
233 		CopyMarkedObj();
234 
235 	sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
236 	for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++)
237 	{
238 		SdrMark* pM=GetSdrMarkByIndex(nm);
239 		SdrObject* pO=pM->GetMarkedSdrObj();
240 		if( bUndo )
241 		{
242 			std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pO ) );
243 			AddUndoActions( vConnectorUndoActions );
244 			AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO));
245 		}
246 		pO->Resize(rRef,xFact,yFact);
247 	}
248 
249 	if( bUndo )
250 		EndUndo();
251 }
252 
253 long SdrEditView::GetMarkedObjRotate() const
254 {
255 	sal_Bool b1st=sal_True;
256 	sal_Bool bOk=sal_True;
257 	long nWink=0;
258 	sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
259 	for (sal_uIntPtr nm=0; nm<nMarkAnz && bOk; nm++) {
260 		SdrMark* pM=GetSdrMarkByIndex(nm);
261 		SdrObject* pO=pM->GetMarkedSdrObj();
262 		long nWink2=pO->GetRotateAngle();
263 		if (b1st) nWink=nWink2;
264 		else if (nWink2!=nWink) bOk=sal_False;
265 		b1st=sal_False;
266 	}
267 	if (!bOk) nWink=0;
268 	return nWink;
269 }
270 
271 void SdrEditView::RotateMarkedObj(const Point& rRef, long nWink, bool bCopy)
272 {
273 	const bool bUndo = IsUndoEnabled();
274 	if( bUndo )
275 	{
276 		XubString aStr;
277 		ImpTakeDescriptionStr(STR_EditRotate,aStr);
278 		if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy);
279 		BegUndo(aStr);
280 	}
281 
282 	if (bCopy)
283 		CopyMarkedObj();
284 
285 	double nSin=sin(nWink*nPi180);
286 	double nCos=cos(nWink*nPi180);
287 	const sal_uInt32 nMarkAnz(GetMarkedObjectCount());
288 
289     if(nMarkAnz)
290     {
291         std::vector< E3DModifySceneSnapRectUpdater* > aUpdaters;
292 
293         for(sal_uInt32 nm(0); nm < nMarkAnz; nm++)
294         {
295 		    SdrMark* pM = GetSdrMarkByIndex(nm);
296 		    SdrObject* pO = pM->GetMarkedSdrObj();
297 
298 			if( bUndo )
299 			{
300 				// extra undo actions for changed connector which now may hold it's layouted path (SJ)
301 				std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pO ) );
302 				AddUndoActions( vConnectorUndoActions );
303 
304 				AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO));
305 			}
306 
307             // set up a scene updater if object is a 3d object
308             if(dynamic_cast< E3dObject* >(pO))
309             {
310                 aUpdaters.push_back(new E3DModifySceneSnapRectUpdater(pO));
311             }
312 
313             pO->Rotate(rRef,nWink,nSin,nCos);
314 	    }
315 
316         // fire scene updaters
317         while(!aUpdaters.empty())
318         {
319             delete aUpdaters.back();
320             aUpdaters.pop_back();
321         }
322     }
323 
324 	if( bUndo )
325 		EndUndo();
326 }
327 
328 void SdrEditView::MirrorMarkedObj(const Point& rRef1, const Point& rRef2, bool bCopy)
329 {
330 	const bool bUndo = IsUndoEnabled();
331 
332 	if( bUndo )
333 	{
334 		XubString aStr;
335 		Point aDif(rRef2-rRef1);
336 		if (aDif.X()==0) ImpTakeDescriptionStr(STR_EditMirrorHori,aStr);
337 		else if (aDif.Y()==0) ImpTakeDescriptionStr(STR_EditMirrorVert,aStr);
338 		else if (Abs(aDif.X())==Abs(aDif.Y())) ImpTakeDescriptionStr(STR_EditMirrorDiag,aStr);
339 		else ImpTakeDescriptionStr(STR_EditMirrorFree,aStr);
340 		if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy);
341 		BegUndo(aStr);
342 	}
343 
344 	if (bCopy)
345 		CopyMarkedObj();
346 
347 	const sal_uInt32 nMarkAnz(GetMarkedObjectCount());
348 
349     if(nMarkAnz)
350     {
351         std::vector< E3DModifySceneSnapRectUpdater* > aUpdaters;
352 
353         for(sal_uInt32 nm(0); nm < nMarkAnz; nm++)
354         {
355 		    SdrMark* pM = GetSdrMarkByIndex(nm);
356 		    SdrObject* pO = pM->GetMarkedSdrObj();
357 
358 			if( bUndo )
359 			{
360 				// extra undo actions for changed connector which now may hold it's layouted path (SJ)
361 				std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pO ) );
362 				AddUndoActions( vConnectorUndoActions );
363 
364 				AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO));
365 			}
366 
367             // set up a scene updater if object is a 3d object
368             if(dynamic_cast< E3dObject* >(pO))
369             {
370                 aUpdaters.push_back(new E3DModifySceneSnapRectUpdater(pO));
371             }
372 
373             pO->Mirror(rRef1,rRef2);
374 	    }
375 
376         // fire scene updaters
377         while(!aUpdaters.empty())
378         {
379             delete aUpdaters.back();
380             aUpdaters.pop_back();
381         }
382     }
383 
384 	if( bUndo )
385 		EndUndo();
386 }
387 
388 void SdrEditView::MirrorMarkedObjHorizontal(sal_Bool bCopy)
389 {
390 	Point aCenter(GetMarkedObjRect().Center());
391 	Point aPt2(aCenter);
392 	aPt2.Y()++;
393 	MirrorMarkedObj(aCenter,aPt2,bCopy);
394 }
395 
396 void SdrEditView::MirrorMarkedObjVertical(sal_Bool bCopy)
397 {
398 	Point aCenter(GetMarkedObjRect().Center());
399 	Point aPt2(aCenter);
400 	aPt2.X()++;
401 	MirrorMarkedObj(aCenter,aPt2,bCopy);
402 }
403 
404 long SdrEditView::GetMarkedObjShear() const
405 {
406 	sal_Bool b1st=sal_True;
407 	sal_Bool bOk=sal_True;
408 	long nWink=0;
409 	sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
410 	for (sal_uIntPtr nm=0; nm<nMarkAnz && bOk; nm++) {
411 		SdrMark* pM=GetSdrMarkByIndex(nm);
412 		SdrObject* pO=pM->GetMarkedSdrObj();
413 		long nWink2=pO->GetShearAngle();
414 		if (b1st) nWink=nWink2;
415 		else if (nWink2!=nWink) bOk=sal_False;
416 		b1st=sal_False;
417 	}
418 	if (nWink>SDRMAXSHEAR) nWink=SDRMAXSHEAR;
419 	if (nWink<-SDRMAXSHEAR) nWink=-SDRMAXSHEAR;
420 	if (!bOk) nWink=0;
421 	return nWink;
422 }
423 
424 void SdrEditView::ShearMarkedObj(const Point& rRef, long nWink, bool bVShear, bool bCopy)
425 {
426 	const bool bUndo = IsUndoEnabled();
427 
428 	if( bUndo )
429 	{
430 		XubString aStr;
431 		ImpTakeDescriptionStr(STR_EditShear,aStr);
432 		if (bCopy)
433 			aStr+=ImpGetResStr(STR_EditWithCopy);
434 		BegUndo(aStr);
435 	}
436 
437 	if (bCopy)
438 		CopyMarkedObj();
439 
440 	double nTan=tan(nWink*nPi180);
441 	sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
442 	for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++)
443 	{
444 		SdrMark* pM=GetSdrMarkByIndex(nm);
445 		SdrObject* pO=pM->GetMarkedSdrObj();
446 		if( bUndo )
447 		{
448 			std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pO ) );
449 			AddUndoActions( vConnectorUndoActions );
450 			AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO));
451 		}
452 		pO->Shear(rRef,nWink,nTan,bVShear);
453 	}
454 
455 	if( bUndo )
456 		EndUndo();
457 }
458 
459 void SdrEditView::ImpCrookObj(SdrObject* pO, const Point& rRef, const Point& rRad,
460 	SdrCrookMode eMode, sal_Bool bVertical, sal_Bool bNoContortion, sal_Bool bRotate, const Rectangle& rMarkRect)
461 {
462 	SdrPathObj* pPath=PTR_CAST(SdrPathObj,pO);
463 	sal_Bool bDone = sal_False;
464 
465 	if(pPath!=NULL && !bNoContortion)
466 	{
467 		XPolyPolygon aXPP(pPath->GetPathPoly());
468 		switch (eMode) {
469 			case SDRCROOK_ROTATE : CrookRotatePoly (aXPP,rRef,rRad,bVertical);           break;
470 			case SDRCROOK_SLANT  : CrookSlantPoly  (aXPP,rRef,rRad,bVertical);           break;
471 			case SDRCROOK_STRETCH: CrookStretchPoly(aXPP,rRef,rRad,bVertical,rMarkRect); break;
472 		} // switch
473 		pPath->SetPathPoly(aXPP.getB2DPolyPolygon());
474 		bDone = sal_True;
475 	}
476 
477 	if(!bDone && !pPath && pO->IsPolyObj() && 0L != pO->GetPointCount())
478 	{
479 		// FuerPolyObj's, aber NICHT fuer SdrPathObj's, z.B. fuer's Bemassungsobjekt
480 		sal_uInt32 nPtAnz(pO->GetPointCount());
481 		XPolygon aXP((sal_uInt16)nPtAnz);
482 		sal_uInt32 nPtNum;
483 
484 		for(nPtNum = 0L; nPtNum < nPtAnz; nPtNum++)
485 		{
486 			Point aPt(pO->GetPoint(nPtNum));
487 			aXP[(sal_uInt16)nPtNum]=aPt;
488 		}
489 
490 		switch (eMode)
491 		{
492 			case SDRCROOK_ROTATE : CrookRotatePoly (aXP,rRef,rRad,bVertical);           break;
493 			case SDRCROOK_SLANT  : CrookSlantPoly  (aXP,rRef,rRad,bVertical);           break;
494 			case SDRCROOK_STRETCH: CrookStretchPoly(aXP,rRef,rRad,bVertical,rMarkRect); break;
495 		}
496 
497 		for(nPtNum = 0L; nPtNum < nPtAnz; nPtNum++)
498 		{
499 			// hier koennte man vieleicht auch mal das Broadcasting optimieren
500 			// ist aber z.Zt. bei den 2 Punkten des Bemassungsobjekts noch nicht so tragisch
501 			pO->SetPoint(aXP[(sal_uInt16)nPtNum],nPtNum);
502 		}
503 
504 		bDone = sal_True;
505 	}
506 
507 	if(!bDone)
508 	{
509 		// Fuer alle anderen oder wenn bNoContortion
510 		Point aCtr0(pO->GetSnapRect().Center());
511 		Point aCtr1(aCtr0);
512 		sal_Bool bRotOk(sal_False);
513 		double nSin(0.0), nCos(1.0);
514 		double nWink(0.0);
515 
516 		if(0 != rRad.X() && 0 != rRad.Y())
517 		{
518 			bRotOk = bRotate;
519 
520 			switch (eMode)
521 			{
522 				case SDRCROOK_ROTATE : nWink=CrookRotateXPoint (aCtr1,NULL,NULL,rRef,rRad,nSin,nCos,bVertical); bRotOk=bRotate; break;
523 				case SDRCROOK_SLANT  : nWink=CrookSlantXPoint  (aCtr1,NULL,NULL,rRef,rRad,nSin,nCos,bVertical);           break;
524 				case SDRCROOK_STRETCH: nWink=CrookStretchXPoint(aCtr1,NULL,NULL,rRef,rRad,nSin,nCos,bVertical,rMarkRect); break;
525 			}
526 		}
527 
528 		aCtr1 -= aCtr0;
529 
530 		if(bRotOk)
531 			pO->Rotate(aCtr0, Round(nWink/nPi180), nSin, nCos);
532 
533 		pO->Move(Size(aCtr1.X(),aCtr1.Y()));
534 	}
535 }
536 
537 void SdrEditView::CrookMarkedObj(const Point& rRef, const Point& rRad, SdrCrookMode eMode,
538 	bool bVertical, bool bNoContortion, bool bCopy)
539 {
540 	Rectangle aMarkRect(GetMarkedObjRect());
541 	const bool bUndo = IsUndoEnabled();
542 
543 	bool bRotate=bNoContortion && eMode==SDRCROOK_ROTATE && IsRotateAllowed(sal_False);
544 
545 	if( bUndo )
546 	{
547 		XubString aStr;
548 		ImpTakeDescriptionStr(bNoContortion?STR_EditCrook:STR_EditCrookContortion,aStr);
549 		if (bCopy)
550 			aStr+=ImpGetResStr(STR_EditWithCopy);
551 		BegUndo(aStr);
552 	}
553 
554 	if (bCopy)
555 		CopyMarkedObj();
556 
557 	sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
558 	for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++)
559 	{
560 		SdrMark* pM=GetSdrMarkByIndex(nm);
561 		SdrObject* pO=pM->GetMarkedSdrObj();
562 		if( bUndo )
563 			AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO));
564 
565 		const SdrObjList* pOL=pO->GetSubList();
566 		if (bNoContortion || pOL==NULL) {
567 			ImpCrookObj(pO,rRef,rRad,eMode,bVertical,bNoContortion,bRotate,aMarkRect);
568 		} else {
569 			SdrObjListIter aIter(*pOL,IM_DEEPNOGROUPS);
570 			while (aIter.IsMore()) {
571 				SdrObject* pO1=aIter.Next();
572 				ImpCrookObj(pO1,rRef,rRad,eMode,bVertical,bNoContortion,bRotate,aMarkRect);
573 			}
574 		}
575 	}
576 
577 	if( bUndo )
578 		EndUndo();
579 }
580 
581 void SdrEditView::ImpDistortObj(SdrObject* pO, const Rectangle& rRef, const XPolygon& rDistortedRect, sal_Bool bNoContortion)
582 {
583 	SdrPathObj* pPath = PTR_CAST(SdrPathObj, pO);
584 
585 	if(!bNoContortion && pPath)
586 	{
587 		XPolyPolygon aXPP(pPath->GetPathPoly());
588 		aXPP.Distort(rRef, rDistortedRect);
589 		pPath->SetPathPoly(aXPP.getB2DPolyPolygon());
590 	}
591 	else if(pO->IsPolyObj())
592 	{
593 		// z.B. fuer's Bemassungsobjekt
594 		sal_uInt32 nPtAnz(pO->GetPointCount());
595 		XPolygon aXP((sal_uInt16)nPtAnz);
596 		sal_uInt32 nPtNum;
597 
598 		for(nPtNum = 0L; nPtNum < nPtAnz; nPtNum++)
599 		{
600 			Point aPt(pO->GetPoint(nPtNum));
601 			aXP[(sal_uInt16)nPtNum]=aPt;
602 		}
603 
604 		aXP.Distort(rRef, rDistortedRect);
605 
606 		for(nPtNum = 0L; nPtNum < nPtAnz; nPtNum++)
607 		{
608 			// hier koennte man vieleicht auch mal das Broadcasting optimieren
609 			// ist aber z.Zt. bei den 2 Punkten des Bemassungsobjekts noch nicht so tragisch
610 			pO->SetPoint(aXP[(sal_uInt16)nPtNum],nPtNum);
611 		}
612 	}
613 }
614 
615 void SdrEditView::DistortMarkedObj(const Rectangle& rRef, const XPolygon& rDistortedRect, bool bNoContortion, bool bCopy)
616 {
617 	const bool bUndo = IsUndoEnabled();
618 
619 	if( bUndo )
620 	{
621 		XubString aStr;
622 		ImpTakeDescriptionStr(STR_EditDistort,aStr);
623 		if (bCopy)
624 			aStr+=ImpGetResStr(STR_EditWithCopy);
625 		BegUndo(aStr);
626 	}
627 
628 	if (bCopy)
629 		CopyMarkedObj();
630 
631 	sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
632 	for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++)
633 	{
634 		SdrMark* pM=GetSdrMarkByIndex(nm);
635 		SdrObject* pO=pM->GetMarkedSdrObj();
636 		if( bUndo )
637 			AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO));
638 
639 		Rectangle aRefRect(rRef);
640 		XPolygon  aRefPoly(rDistortedRect);
641 		const SdrObjList* pOL=pO->GetSubList();
642 		if (bNoContortion || pOL==NULL) {
643 			ImpDistortObj(pO,aRefRect,aRefPoly,bNoContortion);
644 		} else {
645 			SdrObjListIter aIter(*pOL,IM_DEEPNOGROUPS);
646 			while (aIter.IsMore()) {
647 				SdrObject* pO1=aIter.Next();
648 				ImpDistortObj(pO1,aRefRect,aRefPoly,bNoContortion);
649 			}
650 		}
651 	}
652 	if( bUndo )
653 		EndUndo();
654 }
655 
656 ////////////////////////////////////////////////////////////////////////////////////////////////////
657 
658 void SdrEditView::SetNotPersistAttrToMarked(const SfxItemSet& rAttr, sal_Bool /*bReplaceAll*/)
659 {
660 	// bReplaceAll hat hier keinerlei Wirkung
661 	Rectangle aAllSnapRect(GetMarkedObjRect());
662 	const SfxPoolItem *pPoolItem=NULL;
663 	if (rAttr.GetItemState(SDRATTR_TRANSFORMREF1X,sal_True,&pPoolItem)==SFX_ITEM_SET) {
664 		long n=((const SdrTransformRef1XItem*)pPoolItem)->GetValue();
665 		SetRef1(Point(n,GetRef1().Y()));
666 	}
667 	if (rAttr.GetItemState(SDRATTR_TRANSFORMREF1Y,sal_True,&pPoolItem)==SFX_ITEM_SET) {
668 		long n=((const SdrTransformRef1YItem*)pPoolItem)->GetValue();
669 		SetRef1(Point(GetRef1().X(),n));
670 	}
671 	if (rAttr.GetItemState(SDRATTR_TRANSFORMREF2X,sal_True,&pPoolItem)==SFX_ITEM_SET) {
672 		long n=((const SdrTransformRef2XItem*)pPoolItem)->GetValue();
673 		SetRef2(Point(n,GetRef2().Y()));
674 	}
675 	if (rAttr.GetItemState(SDRATTR_TRANSFORMREF2Y,sal_True,&pPoolItem)==SFX_ITEM_SET) {
676 		long n=((const SdrTransformRef2YItem*)pPoolItem)->GetValue();
677 		SetRef2(Point(GetRef2().X(),n));
678 	}
679 	long nAllPosX=0; sal_Bool bAllPosX=sal_False;
680 	long nAllPosY=0; sal_Bool bAllPosY=sal_False;
681 	long nAllWdt=0;  sal_Bool bAllWdt=sal_False;
682 	long nAllHgt=0;  sal_Bool bAllHgt=sal_False;
683 	sal_Bool bDoIt=sal_False;
684 	if (rAttr.GetItemState(SDRATTR_ALLPOSITIONX,sal_True,&pPoolItem)==SFX_ITEM_SET) {
685 		nAllPosX=((const SdrAllPositionXItem*)pPoolItem)->GetValue();
686 		bAllPosX=sal_True; bDoIt=sal_True;
687 	}
688 	if (rAttr.GetItemState(SDRATTR_ALLPOSITIONY,sal_True,&pPoolItem)==SFX_ITEM_SET) {
689 		nAllPosY=((const SdrAllPositionYItem*)pPoolItem)->GetValue();
690 		bAllPosY=sal_True; bDoIt=sal_True;
691 	}
692 	if (rAttr.GetItemState(SDRATTR_ALLSIZEWIDTH,sal_True,&pPoolItem)==SFX_ITEM_SET) {
693 		nAllWdt=((const SdrAllSizeWidthItem*)pPoolItem)->GetValue();
694 		bAllWdt=sal_True; bDoIt=sal_True;
695 	}
696 	if (rAttr.GetItemState(SDRATTR_ALLSIZEHEIGHT,sal_True,&pPoolItem)==SFX_ITEM_SET) {
697 		nAllHgt=((const SdrAllSizeHeightItem*)pPoolItem)->GetValue();
698 		bAllHgt=sal_True; bDoIt=sal_True;
699 	}
700 	if (bDoIt) {
701 		Rectangle aRect(aAllSnapRect); // !!! fuer PolyPt's und GluePt's aber bitte noch aendern !!!
702 		if (bAllPosX) aRect.Move(nAllPosX-aRect.Left(),0);
703 		if (bAllPosY) aRect.Move(0,nAllPosY-aRect.Top());
704 		if (bAllWdt)  aRect.Right()=aAllSnapRect.Left()+nAllWdt;
705 		if (bAllHgt)  aRect.Bottom()=aAllSnapRect.Top()+nAllHgt;
706 		SetMarkedObjRect(aRect);
707 	}
708 	if (rAttr.GetItemState(SDRATTR_RESIZEXALL,sal_True,&pPoolItem)==SFX_ITEM_SET) {
709 		Fraction aXFact=((const SdrResizeXAllItem*)pPoolItem)->GetValue();
710 		ResizeMarkedObj(aAllSnapRect.TopLeft(),aXFact,Fraction(1,1));
711 	}
712 	if (rAttr.GetItemState(SDRATTR_RESIZEYALL,sal_True,&pPoolItem)==SFX_ITEM_SET) {
713 		Fraction aYFact=((const SdrResizeYAllItem*)pPoolItem)->GetValue();
714 		ResizeMarkedObj(aAllSnapRect.TopLeft(),Fraction(1,1),aYFact);
715 	}
716 	if (rAttr.GetItemState(SDRATTR_ROTATEALL,sal_True,&pPoolItem)==SFX_ITEM_SET) {
717 		long nAngle=((const SdrRotateAllItem*)pPoolItem)->GetValue();
718 		RotateMarkedObj(aAllSnapRect.Center(),nAngle);
719 	}
720 	if (rAttr.GetItemState(SDRATTR_HORZSHEARALL,sal_True,&pPoolItem)==SFX_ITEM_SET) {
721 		long nAngle=((const SdrHorzShearAllItem*)pPoolItem)->GetValue();
722 		ShearMarkedObj(aAllSnapRect.Center(),nAngle,sal_False);
723 	}
724 	if (rAttr.GetItemState(SDRATTR_VERTSHEARALL,sal_True,&pPoolItem)==SFX_ITEM_SET) {
725 		long nAngle=((const SdrVertShearAllItem*)pPoolItem)->GetValue();
726 		ShearMarkedObj(aAllSnapRect.Center(),nAngle,sal_True);
727 	}
728 
729 	const bool bUndo = IsUndoEnabled();
730 
731 	// Todo: WhichRange nach Notwendigkeit ueberpruefen.
732 	sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
733 	for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++)
734 	{
735 		const SdrMark* pM=GetSdrMarkByIndex(nm);
736 		SdrObject* pObj=pM->GetMarkedSdrObj();
737 		//const SdrPageView* pPV=pM->GetPageView();
738 		if( bUndo )
739 			AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
740 
741 		pObj->ApplyNotPersistAttr(rAttr);
742 	}
743 }
744 
745 void SdrEditView::MergeNotPersistAttrFromMarked(SfxItemSet& rAttr, sal_Bool /*bOnlyHardAttr*/) const
746 {
747 	// bOnlyHardAttr hat hier keinerlei Wirkung
748 	// Hier muss ausserdem noch der Nullpunkt und
749 	// die PvPos berueksichtigt werden.
750 	Rectangle aAllSnapRect(GetMarkedObjRect()); // !!! fuer PolyPt's und GluePt's aber bitte noch aendern !!!
751 	long nAllSnapPosX=aAllSnapRect.Left();
752 	long nAllSnapPosY=aAllSnapRect.Top();
753 	long nAllSnapWdt=aAllSnapRect.GetWidth()-1;
754 	long nAllSnapHgt=aAllSnapRect.GetHeight()-1;
755 	// koennte mal zu CheckPossibilities mit rein
756 	sal_Bool bMovProtect=sal_False,bMovProtectDC=sal_False;
757 	sal_Bool bSizProtect=sal_False,bSizProtectDC=sal_False;
758 	sal_Bool bPrintable =sal_True ,bPrintableDC=sal_False;
759 	sal_Bool bVisible = sal_True, bVisibleDC=sal_False;
760 	SdrLayerID nLayerId=0; sal_Bool bLayerDC=sal_False;
761 	XubString aObjName;     sal_Bool bObjNameDC=sal_False,bObjNameSet=sal_False;
762 	long nSnapPosX=0;      sal_Bool bSnapPosXDC=sal_False;
763 	long nSnapPosY=0;      sal_Bool bSnapPosYDC=sal_False;
764 	long nSnapWdt=0;       sal_Bool bSnapWdtDC=sal_False;
765 	long nSnapHgt=0;       sal_Bool bSnapHgtDC=sal_False;
766 	long nLogicWdt=0;      sal_Bool bLogicWdtDC=sal_False,bLogicWdtDiff=sal_False;
767 	long nLogicHgt=0;      sal_Bool bLogicHgtDC=sal_False,bLogicHgtDiff=sal_False;
768 	long nRotAngle=0;      sal_Bool bRotAngleDC=sal_False;
769 	long nShrAngle=0;      sal_Bool bShrAngleDC=sal_False;
770 	Rectangle aSnapRect;
771 	Rectangle aLogicRect;
772 	sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
773 	for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++) {
774 		const SdrMark* pM=GetSdrMarkByIndex(nm);
775 		const SdrObject* pObj=pM->GetMarkedSdrObj();
776 		if (nm==0) {
777 			nLayerId=pObj->GetLayer();
778 			bMovProtect=pObj->IsMoveProtect();
779 			bSizProtect=pObj->IsResizeProtect();
780 			bPrintable =pObj->IsPrintable();
781 			bVisible = pObj->IsVisible();
782 			Rectangle aSnapRect2(pObj->GetSnapRect());
783 			Rectangle aLogicRect2(pObj->GetLogicRect());
784 			nSnapPosX=aSnapRect2.Left();
785 			nSnapPosY=aSnapRect2.Top();
786 			nSnapWdt=aSnapRect2.GetWidth()-1;
787 			nSnapHgt=aSnapRect2.GetHeight()-1;
788 			nLogicWdt=aLogicRect2.GetWidth()-1;
789 			nLogicHgt=aLogicRect2.GetHeight()-1;
790 			bLogicWdtDiff=nLogicWdt!=nSnapWdt;
791 			bLogicHgtDiff=nLogicHgt!=nSnapHgt;
792 			nRotAngle=pObj->GetRotateAngle();
793 			nShrAngle=pObj->GetShearAngle();
794 		} else {
795 			if (!bLayerDC      && nLayerId   !=pObj->GetLayer())        bLayerDC=sal_True;
796 			if (!bMovProtectDC && bMovProtect!=pObj->IsMoveProtect())   bMovProtectDC=sal_True;
797 			if (!bSizProtectDC && bSizProtect!=pObj->IsResizeProtect()) bSizProtectDC=sal_True;
798 			if (!bPrintableDC  && bPrintable !=pObj->IsPrintable())     bPrintableDC=sal_True;
799 			if (!bVisibleDC	   && bVisible !=pObj->IsVisible())         bVisibleDC=sal_True;
800 			if (!bRotAngleDC   && nRotAngle  !=pObj->GetRotateAngle())  bRotAngleDC=sal_True;
801 			if (!bShrAngleDC   && nShrAngle  !=pObj->GetShearAngle())   bShrAngleDC=sal_True;
802 			if (!bSnapWdtDC || !bSnapHgtDC || !bSnapPosXDC || !bSnapPosYDC || !bLogicWdtDiff || !bLogicHgtDiff) {
803 				aSnapRect=pObj->GetSnapRect();
804 				if (nSnapPosX!=aSnapRect.Left()) bSnapPosXDC=sal_True;
805 				if (nSnapPosY!=aSnapRect.Top()) bSnapPosYDC=sal_True;
806 				if (nSnapWdt!=aSnapRect.GetWidth()-1) bSnapWdtDC=sal_True;
807 				if (nSnapHgt!=aSnapRect.GetHeight()-1) bSnapHgtDC=sal_True;
808 			}
809 			if (!bLogicWdtDC || !bLogicHgtDC || !bLogicWdtDiff || !bLogicHgtDiff) {
810 				aLogicRect=pObj->GetLogicRect();
811 				if (nLogicWdt!=aLogicRect.GetWidth()-1) bLogicWdtDC=sal_True;
812 				if (nLogicHgt!=aLogicRect.GetHeight()-1) bLogicHgtDC=sal_True;
813 				if (!bLogicWdtDiff && aSnapRect.GetWidth()!=aLogicRect.GetWidth()) bLogicWdtDiff=sal_True;
814 				if (!bLogicHgtDiff && aSnapRect.GetHeight()!=aLogicRect.GetHeight()) bLogicHgtDiff=sal_True;
815 			}
816 		}
817 		if (!bObjNameDC ) {
818 			if (!bObjNameSet) {
819 				aObjName=pObj->GetName();
820 			} else {
821 				if (aObjName!=pObj->GetName()) bObjNameDC=sal_True;
822 			}
823 		}
824 	}
825 
826 	if (bSnapPosXDC || nAllSnapPosX!=nSnapPosX) rAttr.Put(SdrAllPositionXItem(nAllSnapPosX));
827 	if (bSnapPosYDC || nAllSnapPosY!=nSnapPosY) rAttr.Put(SdrAllPositionYItem(nAllSnapPosY));
828 	if (bSnapWdtDC  || nAllSnapWdt !=nSnapWdt ) rAttr.Put(SdrAllSizeWidthItem(nAllSnapWdt));
829 	if (bSnapHgtDC  || nAllSnapHgt !=nSnapHgt ) rAttr.Put(SdrAllSizeHeightItem(nAllSnapHgt));
830 
831 	// Items fuer reine Transformationen
832 	rAttr.Put(SdrMoveXItem());
833 	rAttr.Put(SdrMoveYItem());
834 	rAttr.Put(SdrResizeXOneItem());
835 	rAttr.Put(SdrResizeYOneItem());
836 	rAttr.Put(SdrRotateOneItem());
837 	rAttr.Put(SdrHorzShearOneItem());
838 	rAttr.Put(SdrVertShearOneItem());
839 
840 	if (nMarkAnz>1) {
841 		rAttr.Put(SdrResizeXAllItem());
842 		rAttr.Put(SdrResizeYAllItem());
843 		rAttr.Put(SdrRotateAllItem());
844 		rAttr.Put(SdrHorzShearAllItem());
845 		rAttr.Put(SdrVertShearAllItem());
846 	}
847 
848 	if(eDragMode == SDRDRAG_ROTATE || eDragMode == SDRDRAG_MIRROR)
849 	{
850 		rAttr.Put(SdrTransformRef1XItem(GetRef1().X()));
851 		rAttr.Put(SdrTransformRef1YItem(GetRef1().Y()));
852 	}
853 
854 	if(eDragMode == SDRDRAG_MIRROR)
855 	{
856 		rAttr.Put(SdrTransformRef2XItem(GetRef2().X()));
857 		rAttr.Put(SdrTransformRef2YItem(GetRef2().Y()));
858 	}
859 }
860 
861 SfxItemSet SdrEditView::GetAttrFromMarked(sal_Bool bOnlyHardAttr) const
862 {
863 	SfxItemSet aSet(pMod->GetItemPool());
864 	MergeAttrFromMarked(aSet,bOnlyHardAttr);
865     //the EE_FEATURE items should not be set with SetAttrToMarked (see error message there)
866     //so we do not set them here
867 	// #i32448#
868 	// Do not disable, but clear the items.
869     aSet.ClearItem(EE_FEATURE_TAB);
870     aSet.ClearItem(EE_FEATURE_LINEBR);
871     aSet.ClearItem(EE_FEATURE_NOTCONV);
872     aSet.ClearItem(EE_FEATURE_FIELD);
873 	return aSet;
874 }
875 
876 void SdrEditView::MergeAttrFromMarked(SfxItemSet& rAttr, sal_Bool bOnlyHardAttr) const
877 {
878 	sal_uInt32 nMarkAnz(GetMarkedObjectCount());
879 
880 	for(sal_uInt32 a(0); a < nMarkAnz; a++)
881 	{
882 		// #80277# merging was done wrong in the prev version
883 		//const SfxItemSet& rSet = GetMarkedObjectByIndex()->GetItemSet();
884 		const SfxItemSet& rSet = GetMarkedObjectByIndex(a)->GetMergedItemSet();
885 		SfxWhichIter aIter(rSet);
886 		sal_uInt16 nWhich(aIter.FirstWhich());
887 
888 		while(nWhich)
889 		{
890 			if(!bOnlyHardAttr)
891 			{
892 				if(SFX_ITEM_DONTCARE == rSet.GetItemState(nWhich, sal_False))
893 					rAttr.InvalidateItem(nWhich);
894 				else
895 					rAttr.MergeValue(rSet.Get(nWhich), sal_True);
896 			}
897 			else if(SFX_ITEM_SET == rSet.GetItemState(nWhich, sal_False))
898 			{
899 				const SfxPoolItem& rItem = rSet.Get(nWhich);
900 				rAttr.MergeValue(rItem, sal_True);
901 			}
902 
903 			nWhich = aIter.NextWhich();
904 		}
905 	}
906 }
907 
908 void SdrEditView::SetAttrToMarked(const SfxItemSet& rAttr, sal_Bool bReplaceAll)
909 {
910 	if (AreObjectsMarked())
911 	{
912 #ifdef DBG_UTIL
913 		{
914 			sal_Bool bHasEEFeatureItems=sal_False;
915 			SfxItemIter aIter(rAttr);
916 			const SfxPoolItem* pItem=aIter.FirstItem();
917 			while (!bHasEEFeatureItems && pItem!=NULL) {
918 				if (!IsInvalidItem(pItem)) {
919 					sal_uInt16 nW=pItem->Which();
920 					if (nW>=EE_FEATURE_START && nW<=EE_FEATURE_END) bHasEEFeatureItems=sal_True;
921 				}
922 				pItem=aIter.NextItem();
923 			}
924 			if(bHasEEFeatureItems)
925 			{
926 				String aMessage;
927 				aMessage.AppendAscii("SdrEditView::SetAttrToMarked(): Das setzen von EE_FEATURE-Items an der SdrView macht keinen Sinn! Es fuehrt nur zu Overhead und nicht mehr lesbaren Dokumenten.");
928 				InfoBox(NULL, aMessage).Execute();
929 			}
930 		}
931 #endif
932 
933 		// #103836# if the user thets character attributes to the complete shape,
934 		//			we want to remove all hard set character attributes with same
935 		//			which ids from the text. We do that later but here we remember
936 		//			all character attribute which id's that are set.
937 		std::vector<sal_uInt16> aCharWhichIds;
938 		{
939 			SfxItemIter aIter(rAttr);
940 			const SfxPoolItem* pItem=aIter.FirstItem();
941 			while( pItem!=NULL )
942 			{
943 				if (!IsInvalidItem(pItem))
944 				{
945 					sal_uInt16 nWhich = pItem->Which();
946 					if (nWhich>=EE_CHAR_START && nWhich<=EE_CHAR_END)
947 						aCharWhichIds.push_back( nWhich );
948 				}
949 				pItem=aIter.NextItem();
950 			}
951 		}
952 
953 		// Joe, 2.7.98: Damit Undo nach Format.Standard auch die Textattribute korrekt restauriert
954 		sal_Bool bHasEEItems=SearchOutlinerItems(rAttr,bReplaceAll);
955 
956 		// AW 030100: save additional geom info when para or char attributes
957 		// are changed and the geom form of the text object might be changed
958 		sal_Bool bPossibleGeomChange(sal_False);
959 		SfxWhichIter aIter(rAttr);
960 		sal_uInt16 nWhich = aIter.FirstWhich();
961 		while(!bPossibleGeomChange && nWhich)
962 		{
963 			SfxItemState eState = rAttr.GetItemState(nWhich);
964 			if(eState == SFX_ITEM_SET)
965 			{
966 				if((nWhich >= SDRATTR_TEXT_MINFRAMEHEIGHT && nWhich <= SDRATTR_TEXT_CONTOURFRAME)
967 					|| nWhich == SDRATTR_3DOBJ_PERCENT_DIAGONAL
968 					|| nWhich == SDRATTR_3DOBJ_BACKSCALE
969 					|| nWhich == SDRATTR_3DOBJ_DEPTH
970 					|| nWhich == SDRATTR_3DOBJ_END_ANGLE
971 					|| nWhich == SDRATTR_3DSCENE_DISTANCE)
972 				{
973 					bPossibleGeomChange = sal_True;
974 				}
975 			}
976 			nWhich = aIter.NextWhich();
977 		}
978 
979 		const bool bUndo = IsUndoEnabled();
980 		if( bUndo )
981 		{
982 			XubString aStr;
983 			ImpTakeDescriptionStr(STR_EditSetAttributes,aStr);
984 			BegUndo(aStr);
985 		}
986 
987 		const sal_uInt32 nMarkAnz(GetMarkedObjectCount());
988         std::vector< E3DModifySceneSnapRectUpdater* > aUpdaters;
989 
990 		// create ItemSet without SFX_ITEM_DONTCARE. Put()
991 		// uses it's second parameter (bInvalidAsDefault) to
992 		// remove all such items to set them to default.
993 		SfxItemSet aAttr(*rAttr.GetPool(), rAttr.GetRanges());
994 		aAttr.Put(rAttr, sal_True);
995 
996 		// #i38135#
997 		bool bResetAnimationTimer(false);
998 
999 		for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++)
1000 		{
1001 			SdrMark* pM=GetSdrMarkByIndex(nm);
1002 			SdrObject* pObj = pM->GetMarkedSdrObj();
1003 
1004 			if( bUndo )
1005 			{
1006 				std::vector< SdrUndoAction* > vConnectorUndoActions;
1007 				SdrEdgeObj* pEdgeObj = dynamic_cast< SdrEdgeObj* >( pObj );
1008 				if ( pEdgeObj )
1009 					bPossibleGeomChange = sal_True;
1010 				else if( bUndo )
1011 					vConnectorUndoActions = CreateConnectorUndo( *pObj );
1012 
1013 				AddUndoActions( vConnectorUndoActions );
1014 			}
1015 
1016 			// new geometry undo
1017 			if(bPossibleGeomChange && bUndo)
1018 			{
1019 				// save position and size of obect, too
1020 				AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
1021 			}
1022 
1023 			if( bUndo )
1024 			{
1025 				// #i8508#
1026 				// If this is a text object also rescue the OutlinerParaObject since
1027 				// applying attributes to the object may change text layout when
1028 				// multiple portions exist with multiple formats. If a OutlinerParaObject
1029 				// really exists and needs to be rescued is evaluated in the undo
1030 				// implementation itself.
1031 				const bool bRescueText = dynamic_cast< SdrTextObj* >(pObj) != 0;
1032 
1033 				// add attribute undo
1034 				AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj,sal_False,bHasEEItems || bPossibleGeomChange || bRescueText));
1035 			}
1036 
1037             // set up a scxene updater if object is a 3d object
1038             if(dynamic_cast< E3dObject* >(pObj))
1039             {
1040                 aUpdaters.push_back(new E3DModifySceneSnapRectUpdater(pObj));
1041             }
1042 
1043             // set attributes at object
1044 			pObj->SetMergedItemSetAndBroadcast(aAttr, bReplaceAll);
1045 
1046 			if(pObj->ISA(SdrTextObj))
1047 			{
1048 				SdrTextObj* pTextObj = ((SdrTextObj*)pObj);
1049 
1050 				if(!aCharWhichIds.empty())
1051 				{
1052 					Rectangle aOldBoundRect = pTextObj->GetLastBoundRect();
1053 
1054 					// #110094#-14 pTextObj->SendRepaintBroadcast(pTextObj->GetBoundRect());
1055 					pTextObj->RemoveOutlinerCharacterAttribs( aCharWhichIds );
1056 
1057 					// object has changed, should be called form
1058 					// RemoveOutlinerCharacterAttribs. This will change when the text
1059 					// object implementation changes.
1060 					pTextObj->SetChanged();
1061 
1062 					pTextObj->BroadcastObjectChange();
1063 					pTextObj->SendUserCall(SDRUSERCALL_CHGATTR, aOldBoundRect);
1064 				}
1065 			}
1066 
1067 			// #i38495#
1068 			if(!bResetAnimationTimer)
1069 			{
1070     			if(pObj->GetViewContact().isAnimatedInAnyViewObjectContact())
1071 				{
1072 					bResetAnimationTimer = true;
1073 				}
1074 			}
1075 		}
1076 
1077         // fire scene updaters
1078         while(!aUpdaters.empty())
1079         {
1080             delete aUpdaters.back();
1081             aUpdaters.pop_back();
1082         }
1083 
1084         // #i38135#
1085 		if(bResetAnimationTimer)
1086 		{
1087 			SetAnimationTimer(0L);
1088 		}
1089 
1090 		// besser vorher checken, was gemacht werden soll:
1091 		// pObj->SetAttr() oder SetNotPersistAttr()
1092 		// !!! fehlende Implementation !!!
1093 		SetNotPersistAttrToMarked(rAttr,bReplaceAll);
1094 
1095 		if( bUndo )
1096 			EndUndo();
1097 	}
1098 }
1099 
1100 SfxStyleSheet* SdrEditView::GetStyleSheetFromMarked() const
1101 {
1102 	SfxStyleSheet* pRet=NULL;
1103 	sal_Bool b1st=sal_True;
1104 	sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
1105 	for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++) {
1106 		SdrMark* pM=GetSdrMarkByIndex(nm);
1107 		SfxStyleSheet* pSS=pM->GetMarkedSdrObj()->GetStyleSheet();
1108 		if (b1st) pRet=pSS;
1109 		else if (pRet!=pSS) return NULL; // verschiedene StyleSheets
1110 		b1st=sal_False;
1111 	}
1112 	return pRet;
1113 }
1114 
1115 void SdrEditView::SetStyleSheetToMarked(SfxStyleSheet* pStyleSheet, sal_Bool bDontRemoveHardAttr)
1116 {
1117 	if (AreObjectsMarked())
1118 	{
1119 		const bool bUndo = IsUndoEnabled();
1120 
1121 		if( bUndo )
1122 		{
1123 			XubString aStr;
1124 			if (pStyleSheet!=NULL)
1125 				ImpTakeDescriptionStr(STR_EditSetStylesheet,aStr);
1126 			else
1127 				ImpTakeDescriptionStr(STR_EditDelStylesheet,aStr);
1128 			BegUndo(aStr);
1129 		}
1130 
1131 		sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
1132 		for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++)
1133 		{
1134 			SdrMark* pM=GetSdrMarkByIndex(nm);
1135 			if( bUndo )
1136 			{
1137 	            AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pM->GetMarkedSdrObj()));
1138 				AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pM->GetMarkedSdrObj(),true,true));
1139 			}
1140 			pM->GetMarkedSdrObj()->SetStyleSheet(pStyleSheet,bDontRemoveHardAttr);
1141 		}
1142 
1143 		if( bUndo )
1144 			EndUndo();
1145 	}
1146 }
1147 
1148 ////////////////////////////////////////////////////////////////////////////////////////////////////
1149 
1150 /* new interface src537 */
1151 sal_Bool SdrEditView::GetAttributes(SfxItemSet& rTargetSet, sal_Bool bOnlyHardAttr) const
1152 {
1153 	if(GetMarkedObjectCount())
1154 	{
1155 		rTargetSet.Put(GetAttrFromMarked(bOnlyHardAttr), sal_False);
1156 		return sal_True;
1157 	}
1158 	else
1159 	{
1160 		return SdrMarkView::GetAttributes(rTargetSet, bOnlyHardAttr);
1161 	}
1162 }
1163 
1164 sal_Bool SdrEditView::SetAttributes(const SfxItemSet& rSet, sal_Bool bReplaceAll)
1165 {
1166 	if (GetMarkedObjectCount()!=0) {
1167 		SetAttrToMarked(rSet,bReplaceAll);
1168 		return sal_True;
1169 	} else {
1170 		return SdrMarkView::SetAttributes(rSet,bReplaceAll);
1171 	}
1172 }
1173 
1174 SfxStyleSheet* SdrEditView::GetStyleSheet() const // SfxStyleSheet* SdrEditView::GetStyleSheet(sal_Bool& rOk) const
1175 {
1176 	if (GetMarkedObjectCount()!=0) {
1177 		//rOk=sal_True;
1178 		return GetStyleSheetFromMarked();
1179 	} else {
1180 		return SdrMarkView::GetStyleSheet(); // SdrMarkView::GetStyleSheet(rOk);
1181 	}
1182 }
1183 
1184 sal_Bool SdrEditView::SetStyleSheet(SfxStyleSheet* pStyleSheet, sal_Bool bDontRemoveHardAttr)
1185 {
1186 	if (GetMarkedObjectCount()!=0) {
1187 		SetStyleSheetToMarked(pStyleSheet,bDontRemoveHardAttr);
1188 		return sal_True;
1189 	} else {
1190 		return SdrMarkView::SetStyleSheet(pStyleSheet,bDontRemoveHardAttr);
1191 	}
1192 }
1193 
1194 ////////////////////////////////////////////////////////////////////////////////////////////////////
1195 
1196 SfxItemSet SdrEditView::GetGeoAttrFromMarked() const
1197 {
1198 	SfxItemSet aRetSet(pMod->GetItemPool(),   // SID_ATTR_TRANSFORM_... aus s:svxids.hrc
1199 					   SID_ATTR_TRANSFORM_POS_X,SID_ATTR_TRANSFORM_ANGLE,
1200 					   SID_ATTR_TRANSFORM_PROTECT_POS,SID_ATTR_TRANSFORM_AUTOHEIGHT,
1201 					   SDRATTR_ECKENRADIUS,SDRATTR_ECKENRADIUS,
1202 					   0);
1203 	if (AreObjectsMarked()) {
1204 		SfxItemSet aMarkAttr(GetAttrFromMarked(sal_False)); // wg. AutoGrowHeight und Eckenradius
1205 		Rectangle aRect(GetMarkedObjRect());
1206 
1207 		if(GetSdrPageView())
1208 		{
1209 			GetSdrPageView()->LogicToPagePos(aRect);
1210 		}
1211 
1212 		// Position
1213 		aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_POS_X,aRect.Left()));
1214 		aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_POS_Y,aRect.Top()));
1215 
1216 		// Groesse
1217 		long nResizeRefX=aRect.Left();
1218 		long nResizeRefY=aRect.Top();
1219 		if (eDragMode==SDRDRAG_ROTATE) { // Drehachse auch als Referenz fuer Resize
1220 			nResizeRefX=aRef1.X();
1221 			nResizeRefY=aRef1.Y();
1222 		}
1223 		aRetSet.Put(SfxUInt32Item(SID_ATTR_TRANSFORM_WIDTH,aRect.Right()-aRect.Left()));
1224 		aRetSet.Put(SfxUInt32Item(SID_ATTR_TRANSFORM_HEIGHT,aRect.Bottom()-aRect.Top()));
1225 		aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_RESIZE_REF_X,nResizeRefX));
1226 		aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_RESIZE_REF_Y,nResizeRefY));
1227 
1228 		Point aRotateAxe(aRef1);
1229 
1230 		if(GetSdrPageView())
1231 		{
1232 			GetSdrPageView()->LogicToPagePos(aRotateAxe);
1233 		}
1234 
1235 		// Drehung
1236 		long nRotateRefX=aRect.Center().X();
1237 		long nRotateRefY=aRect.Center().Y();
1238 		if (eDragMode==SDRDRAG_ROTATE) {
1239 			nRotateRefX=aRotateAxe.X();
1240 			nRotateRefY=aRotateAxe.Y();
1241 		}
1242 		aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_ANGLE,GetMarkedObjRotate()));
1243 		aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_ROT_X,nRotateRefX));
1244 		aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_ROT_Y,nRotateRefY));
1245 
1246 		// Shear
1247 		long nShearRefX=aRect.Left();
1248 		long nShearRefY=aRect.Bottom();
1249 		if (eDragMode==SDRDRAG_ROTATE) { // Drehachse auch als Referenz fuer Shear
1250 			nShearRefX=aRotateAxe.X();
1251 			nShearRefY=aRotateAxe.Y();
1252 		}
1253 		aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR,GetMarkedObjShear()));
1254 		aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_X,nShearRefX));
1255 		aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_Y,nShearRefY));
1256 
1257 		// Pruefen der einzelnen Objekte, ob Objekte geschuetzt sind
1258 		const SdrMarkList& rMarkList=GetMarkedObjectList();
1259 		sal_uIntPtr nMarkCount=rMarkList.GetMarkCount();
1260 		SdrObject* pObj=rMarkList.GetMark(0)->GetMarkedSdrObj();
1261 		sal_Bool bPosProt=pObj->IsMoveProtect();
1262 		sal_Bool bSizProt=pObj->IsResizeProtect();
1263 		sal_Bool bPosProtDontCare=sal_False;
1264 		sal_Bool bSizProtDontCare=sal_False;
1265 		for (sal_uIntPtr i=1; i<nMarkCount && (!bPosProtDontCare || !bSizProtDontCare); i++) {
1266 			pObj=rMarkList.GetMark(i)->GetMarkedSdrObj();
1267 			if (bPosProt!=pObj->IsMoveProtect()) bPosProtDontCare=sal_True;
1268 			if (bSizProt!=pObj->IsResizeProtect()) bSizProtDontCare=sal_True;
1269 		}
1270 
1271 		// InvalidateItem setzt das Item auf DONT_CARE
1272 		if (bPosProtDontCare) {
1273 			aRetSet.InvalidateItem(SID_ATTR_TRANSFORM_PROTECT_POS);
1274 		} else {
1275 			aRetSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_PROTECT_POS,bPosProt));
1276 		}
1277 		if (bSizProtDontCare) {
1278 			aRetSet.InvalidateItem(SID_ATTR_TRANSFORM_PROTECT_SIZE);
1279 		} else {
1280 			aRetSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_PROTECT_SIZE,bSizProt));
1281 		}
1282 
1283 		SfxItemState eState=aMarkAttr.GetItemState(SDRATTR_TEXT_AUTOGROWWIDTH);
1284 		sal_Bool bAutoGrow=((SdrTextAutoGrowWidthItem&)(aMarkAttr.Get(SDRATTR_TEXT_AUTOGROWWIDTH))).GetValue();
1285 		if (eState==SFX_ITEM_DONTCARE) {
1286 			aRetSet.InvalidateItem(SID_ATTR_TRANSFORM_AUTOWIDTH);
1287 		} else if (eState==SFX_ITEM_SET) {
1288 			aRetSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_AUTOWIDTH,bAutoGrow));
1289 		}
1290 
1291 		eState=aMarkAttr.GetItemState(SDRATTR_TEXT_AUTOGROWHEIGHT);
1292 		bAutoGrow=((SdrTextAutoGrowHeightItem&)(aMarkAttr.Get(SDRATTR_TEXT_AUTOGROWHEIGHT))).GetValue();
1293 		if (eState==SFX_ITEM_DONTCARE) {
1294 			aRetSet.InvalidateItem(SID_ATTR_TRANSFORM_AUTOHEIGHT);
1295 		} else if (eState==SFX_ITEM_SET) {
1296 			aRetSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_AUTOHEIGHT,bAutoGrow));
1297 		}
1298 
1299 		eState=aMarkAttr.GetItemState(SDRATTR_ECKENRADIUS);
1300 		long nRadius=((SdrEckenradiusItem&)(aMarkAttr.Get(SDRATTR_ECKENRADIUS))).GetValue();
1301 		if (eState==SFX_ITEM_DONTCARE) {
1302 			aRetSet.InvalidateItem(SDRATTR_ECKENRADIUS);
1303 		} else if (eState==SFX_ITEM_SET) {
1304 			aRetSet.Put(SdrEckenradiusItem(nRadius));
1305 		}
1306 
1307 	}
1308 	return aRetSet;
1309 }
1310 
1311 Point ImpGetPoint(Rectangle aRect, RECT_POINT eRP)
1312 {
1313 	switch(eRP) {
1314 		case RP_LT: return aRect.TopLeft();
1315 		case RP_MT: return aRect.TopCenter();
1316 		case RP_RT: return aRect.TopRight();
1317 		case RP_LM: return aRect.LeftCenter();
1318 		case RP_MM: return aRect.Center();
1319 		case RP_RM: return aRect.RightCenter();
1320 		case RP_LB: return aRect.BottomLeft();
1321 		case RP_MB: return aRect.BottomCenter();
1322 		case RP_RB: return aRect.BottomRight();
1323 	}
1324 	return Point(); // Sollte nicht vorkommen !
1325 }
1326 
1327 void SdrEditView::SetGeoAttrToMarked(const SfxItemSet& rAttr)
1328 {
1329 	Rectangle aRect(GetMarkedObjRect());
1330 
1331 	if(GetSdrPageView())
1332 	{
1333 		GetSdrPageView()->LogicToPagePos(aRect);
1334 	}
1335 
1336 	long nOldRotateAngle=GetMarkedObjRotate();
1337 	long nOldShearAngle=GetMarkedObjShear();
1338 	const SdrMarkList& rMarkList=GetMarkedObjectList();
1339 	sal_uIntPtr nMarkCount=rMarkList.GetMarkCount();
1340 	SdrObject* pObj=NULL;
1341 
1342 	RECT_POINT eSizePoint=RP_MM;
1343 	long nPosDX=0;
1344 	long nPosDY=0;
1345 	long nSizX=0;
1346 	long nSizY=0;
1347 	long nRotateAngle=0;
1348 
1349 	// #86909#
1350 	sal_Bool bModeIsRotate(eDragMode == SDRDRAG_ROTATE);
1351 	long nRotateX(0);
1352 	long nRotateY(0);
1353 	long nOldRotateX(0);
1354 	long nOldRotateY(0);
1355 	if(bModeIsRotate)
1356 	{
1357 		Point aRotateAxe(aRef1);
1358 
1359 		if(GetSdrPageView())
1360 		{
1361 			GetSdrPageView()->LogicToPagePos(aRotateAxe);
1362 		}
1363 
1364 		nRotateX = nOldRotateX = aRotateAxe.X();
1365 		nRotateY = nOldRotateY = aRotateAxe.Y();
1366 	}
1367 
1368 	long nNewShearAngle=0;
1369 	long nShearAngle=0;
1370 	long nShearX=0;
1371 	long nShearY=0;
1372 	sal_Bool bShearVert=sal_False;
1373 
1374 	sal_Bool bChgPos=sal_False;
1375 	sal_Bool bChgSiz=sal_False;
1376 	sal_Bool bChgHgt=sal_False;
1377 	sal_Bool bRotate=sal_False;
1378 	sal_Bool bShear =sal_False;
1379 
1380 	sal_Bool bSetAttr=sal_False;
1381 	SfxItemSet aSetAttr(pMod->GetItemPool());
1382 
1383 	const SfxPoolItem* pPoolItem=NULL;
1384 
1385 	// Position
1386 	if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_POS_X,sal_True,&pPoolItem)) {
1387 		nPosDX=((const SfxInt32Item*)pPoolItem)->GetValue()-aRect.Left();
1388 		bChgPos=sal_True;
1389 	}
1390 	if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_POS_Y,sal_True,&pPoolItem)){
1391 		nPosDY=((const SfxInt32Item*)pPoolItem)->GetValue()-aRect.Top();
1392 		bChgPos=sal_True;
1393 	}
1394 	// Groesse
1395 	if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_WIDTH,sal_True,&pPoolItem)) {
1396 		nSizX=((const SfxUInt32Item*)pPoolItem)->GetValue();
1397 		bChgSiz=sal_True;
1398 	}
1399 	if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_HEIGHT,sal_True,&pPoolItem)) {
1400 		nSizY=((const SfxUInt32Item*)pPoolItem)->GetValue();
1401 		bChgSiz=sal_True;
1402 		bChgHgt=sal_True;
1403 	}
1404 	if (bChgSiz) {
1405 		eSizePoint=(RECT_POINT)((const SfxAllEnumItem&)rAttr.Get(SID_ATTR_TRANSFORM_SIZE_POINT)).GetValue();
1406 	}
1407 
1408 	// Rotation
1409 	if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_ANGLE,sal_True,&pPoolItem)) {
1410 		nRotateAngle=((const SfxInt32Item*)pPoolItem)->GetValue()-nOldRotateAngle;
1411 		bRotate = (nRotateAngle != 0);
1412 	}
1413 
1414 	// #86909# pos rot point x
1415 	if(bRotate || SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_ROT_X, sal_True ,&pPoolItem))
1416 		nRotateX = ((const SfxInt32Item&)rAttr.Get(SID_ATTR_TRANSFORM_ROT_X)).GetValue();
1417 
1418 	// #86909# pos rot point y
1419 	if(bRotate || SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_ROT_Y, sal_True ,&pPoolItem))
1420 		nRotateY = ((const SfxInt32Item&)rAttr.Get(SID_ATTR_TRANSFORM_ROT_Y)).GetValue();
1421 
1422 	// Shear
1423 	if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_SHEAR,sal_True,&pPoolItem)) {
1424 		nNewShearAngle=((const SfxInt32Item*)pPoolItem)->GetValue();
1425 		if (nNewShearAngle>SDRMAXSHEAR) nNewShearAngle=SDRMAXSHEAR;
1426 		if (nNewShearAngle<-SDRMAXSHEAR) nNewShearAngle=-SDRMAXSHEAR;
1427 		if (nNewShearAngle!=nOldShearAngle) {
1428 			bShearVert=((const SfxBoolItem&)rAttr.Get(SID_ATTR_TRANSFORM_SHEAR_VERTICAL)).GetValue();
1429 			if (bShearVert) {
1430 				nShearAngle=nNewShearAngle;
1431 			} else {
1432 				if (nNewShearAngle!=0 && nOldShearAngle!=0) {
1433 					// Bugfix #25714#.
1434 					double nOld=tan((double)nOldShearAngle*nPi180);
1435 					double nNew=tan((double)nNewShearAngle*nPi180);
1436 					nNew-=nOld;
1437 					nNew=atan(nNew)/nPi180;
1438 					nShearAngle=Round(nNew);
1439 				} else {
1440 					nShearAngle=nNewShearAngle-nOldShearAngle;
1441 				}
1442 			}
1443 			bShear=nShearAngle!=0;
1444 			if (bShear) {
1445 				nShearX=((const SfxInt32Item&)rAttr.Get(SID_ATTR_TRANSFORM_SHEAR_X)).GetValue();
1446 				nShearY=((const SfxInt32Item&)rAttr.Get(SID_ATTR_TRANSFORM_SHEAR_Y)).GetValue();
1447 			}
1448 		}
1449 	}
1450 
1451 	// AutoGrow
1452 	if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_AUTOWIDTH,sal_True,&pPoolItem)) {
1453 		sal_Bool bAutoGrow=((const SfxBoolItem*)pPoolItem)->GetValue();
1454 		aSetAttr.Put(SdrTextAutoGrowWidthItem(bAutoGrow));
1455 		bSetAttr=sal_True;
1456 	}
1457 
1458 	if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_AUTOHEIGHT,sal_True,&pPoolItem)) {
1459 		sal_Bool bAutoGrow=((const SfxBoolItem*)pPoolItem)->GetValue();
1460 		aSetAttr.Put(SdrTextAutoGrowHeightItem(bAutoGrow));
1461 		bSetAttr=sal_True;
1462 	}
1463 
1464 	// Eckenradius
1465 	if (bEdgeRadiusAllowed && SFX_ITEM_SET==rAttr.GetItemState(SDRATTR_ECKENRADIUS,sal_True,&pPoolItem)) {
1466 		long nRadius=((SdrEckenradiusItem*)pPoolItem)->GetValue();
1467 		aSetAttr.Put(SdrEckenradiusItem(nRadius));
1468 		bSetAttr=sal_True;
1469 	}
1470 
1471 	ForcePossibilities();
1472 
1473 	BegUndo(ImpGetResStr(STR_EditTransform),GetDescriptionOfMarkedObjects());
1474 
1475 	if (bSetAttr) {
1476 		SetAttrToMarked(aSetAttr,sal_False);
1477 	}
1478 
1479 	// Groesse und Hoehe aendern
1480 	if (bChgSiz && (bResizeFreeAllowed || bResizePropAllowed)) {
1481 		Fraction aWdt(nSizX,aRect.Right()-aRect.Left());
1482 		Fraction aHgt(nSizY,aRect.Bottom()-aRect.Top());
1483 		Point aRef(ImpGetPoint(aRect,eSizePoint));
1484 
1485 		if(GetSdrPageView())
1486 		{
1487 			GetSdrPageView()->PagePosToLogic(aRef);
1488 		}
1489 
1490 		ResizeMarkedObj(aRef,aWdt,aHgt);
1491 	}
1492 
1493 	// Rotieren
1494 	if (bRotate && (bRotateFreeAllowed || bRotate90Allowed)) {
1495 		Point aRef(nRotateX,nRotateY);
1496 
1497 		if(GetSdrPageView())
1498 		{
1499 			GetSdrPageView()->PagePosToLogic(aRef);
1500 		}
1501 
1502 		RotateMarkedObj(aRef,nRotateAngle);
1503 	}
1504 
1505 	// #86909# set rotation point position
1506 	if(bModeIsRotate && (nRotateX != nOldRotateX || nRotateY != nOldRotateY))
1507 	{
1508 		Point aNewRef1(nRotateX, nRotateY);
1509 
1510 		if(GetSdrPageView())
1511 		{
1512 			GetSdrPageView()->PagePosToLogic(aNewRef1);
1513 		}
1514 
1515 		SetRef1(aNewRef1);
1516 	}
1517 
1518 	// Shear
1519 	if (bShear && bShearAllowed) {
1520 		Point aRef(nShearX,nShearY);
1521 
1522 		if(GetSdrPageView())
1523 		{
1524 			GetSdrPageView()->PagePosToLogic(aRef);
1525 		}
1526 
1527 		ShearMarkedObj(aRef,nShearAngle,bShearVert);
1528 
1529         // #i74358#
1530 		// ShearMarkedObj creates a linear combination of the existing transformation and
1531 		// the new shear to apply. If the object is already transformed (e.g. rotated) the
1532 		// linear combination will not decompose to the same start values again, but to a
1533 		// new combination. Thus it makes no sense to check if the wanted shear is reached
1534 		// or not. Taking out.
1535 #if 0
1536         long nTempAngle=GetMarkedObjShear();
1537 		if (nTempAngle!=0 && nTempAngle!=nNewShearAngle && !bShearVert) {
1538 			// noch eine 2. Iteration zur Kompensation der Rundungsfehler
1539 			double nOld=tan((double)nTempAngle*nPi180);
1540 			double nNew=tan((double)nNewShearAngle*nPi180);
1541 			nNew-=nOld;
1542 			nNew=atan(nNew)/nPi180;
1543 			nTempAngle=Round(nNew);
1544 			if (nTempAngle!=0) {
1545 				ShearMarkedObj(aRef,nTempAngle,bShearVert);
1546 			}
1547 		}
1548 #endif
1549 	}
1550 
1551 	// Position aendern
1552 	if (bChgPos && bMoveAllowed) {
1553 		MoveMarkedObj(Size(nPosDX,nPosDY));
1554 	}
1555 
1556 	// protect position
1557 	if(SFX_ITEM_SET == rAttr.GetItemState(SID_ATTR_TRANSFORM_PROTECT_POS, sal_True, &pPoolItem))
1558 	{
1559 		const sal_Bool bProtPos(((const SfxBoolItem*)pPoolItem)->GetValue());
1560 		bool bChanged(false);
1561 
1562 		for(sal_uInt32 i(0); i < nMarkCount; i++)
1563 		{
1564 			pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
1565 
1566 			if(pObj->IsMoveProtect() != bProtPos)
1567 			{
1568 				bChanged = true;
1569 				pObj->SetMoveProtect(bProtPos);
1570 
1571 				if(bProtPos)
1572 				{
1573 					pObj->SetResizeProtect(true);
1574 				}
1575 			}
1576 		}
1577 
1578 		if(bChanged)
1579 		{
1580 			bMoveProtect = bProtPos;
1581 
1582 			if(bProtPos)
1583 			{
1584 				bResizeProtect = true;
1585 			}
1586 
1587 			// #i77187# there is no simple method to get the toolbars updated
1588 			// in the application. The App is listening to selection change and i
1589 			// will use it here (even if not true). It's acceptable since changing
1590 			// this model data is pretty rare and only possible using the F4 dialog
1591 			MarkListHasChanged();
1592 		}
1593 	}
1594 
1595 	if(!bMoveProtect)
1596 	{
1597 		// protect size
1598 		if(SFX_ITEM_SET == rAttr.GetItemState(SID_ATTR_TRANSFORM_PROTECT_SIZE, sal_True, &pPoolItem))
1599 		{
1600 			const sal_Bool bProtSize(((const SfxBoolItem*)pPoolItem)->GetValue());
1601 			bool bChanged(false);
1602 
1603 			for(sal_uInt32 i(0); i < nMarkCount; i++)
1604 			{
1605 				pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
1606 
1607 				if(pObj->IsResizeProtect() != bProtSize)
1608 				{
1609 					bChanged = true;
1610 					pObj->SetResizeProtect(bProtSize);
1611 				}
1612 			}
1613 
1614 			if(bChanged)
1615 			{
1616 				bResizeProtect = bProtSize;
1617 
1618 				// #i77187# see above
1619 				MarkListHasChanged();
1620 			}
1621 		}
1622 	}
1623 
1624 	EndUndo();
1625 }
1626 
1627 ////////////////////////////////////////////////////////////////////////////////////////////////////
1628 
1629 sal_Bool SdrEditView::IsAlignPossible() const
1630 {  // Mindestens 2 markierte Objekte, davon mind. 1 beweglich
1631 	ForcePossibilities();
1632 	sal_uIntPtr nAnz=GetMarkedObjectCount();
1633 	if (nAnz==0) return sal_False;         // Nix markiert!
1634 	if (nAnz==1) return bMoveAllowed;  // einzelnes Obj an der Seite ausrichten
1635 	return bOneOrMoreMovable;          // ansonsten ist MarkCount>=2
1636 }
1637 
1638 void SdrEditView::AlignMarkedObjects(SdrHorAlign eHor, SdrVertAlign eVert, sal_Bool bBoundRects)
1639 {
1640 	if (eHor==SDRHALIGN_NONE && eVert==SDRVALIGN_NONE)
1641 		return;
1642 
1643 	SortMarkedObjects();
1644 	if (GetMarkedObjectCount()<1)
1645 		return;
1646 
1647 	const bool bUndo = IsUndoEnabled();
1648 	if( bUndo )
1649 	{
1650 		XubString aStr(GetDescriptionOfMarkedObjects());
1651 		if (eHor==SDRHALIGN_NONE)
1652 		{
1653 			switch (eVert)
1654 			{
1655 				case SDRVALIGN_TOP   : ImpTakeDescriptionStr(STR_EditAlignVTop   ,aStr); break;
1656 				case SDRVALIGN_BOTTOM: ImpTakeDescriptionStr(STR_EditAlignVBottom,aStr); break;
1657 				case SDRVALIGN_CENTER: ImpTakeDescriptionStr(STR_EditAlignVCenter,aStr); break;
1658 				default: break;
1659 			}
1660 		}
1661 		else if (eVert==SDRVALIGN_NONE)
1662 		{
1663 			switch (eHor)
1664 			{
1665 				case SDRHALIGN_LEFT  : ImpTakeDescriptionStr(STR_EditAlignHLeft  ,aStr); break;
1666 				case SDRHALIGN_RIGHT : ImpTakeDescriptionStr(STR_EditAlignHRight ,aStr); break;
1667 				case SDRHALIGN_CENTER: ImpTakeDescriptionStr(STR_EditAlignHCenter,aStr); break;
1668 				default: break;
1669 			}
1670 		}
1671 		else if (eHor==SDRHALIGN_CENTER && eVert==SDRVALIGN_CENTER)
1672 		{
1673 			ImpTakeDescriptionStr(STR_EditAlignCenter,aStr);
1674 		}
1675 		else
1676 		{
1677 			ImpTakeDescriptionStr(STR_EditAlign,aStr);
1678 		}
1679 		BegUndo(aStr);
1680 	}
1681 
1682 	Rectangle aBound;
1683 	sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
1684 	sal_uIntPtr nm;
1685 	sal_Bool bHasFixed=sal_False;
1686 	for (nm=0; nm<nMarkAnz; nm++)
1687 	{
1688 		SdrMark* pM=GetSdrMarkByIndex(nm);
1689 		SdrObject* pObj=pM->GetMarkedSdrObj();
1690 		SdrObjTransformInfoRec aInfo;
1691 		pObj->TakeObjInfo(aInfo);
1692 		if (!aInfo.bMoveAllowed || pObj->IsMoveProtect())
1693 		{
1694 			Rectangle aObjRect(bBoundRects?pObj->GetCurrentBoundRect():pObj->GetSnapRect());
1695 			aBound.Union(aObjRect);
1696 			bHasFixed=sal_True;
1697 		}
1698 	}
1699 	if (!bHasFixed)
1700 	{
1701 		if (nMarkAnz==1)
1702 		{	// einzelnes Obj an der Seite ausrichten
1703 			const SdrObject* pObj=GetMarkedObjectByIndex(0L);
1704 			const SdrPage* pPage=pObj->GetPage();
1705 			const SdrPageGridFrameList* pGFL=pPage->GetGridFrameList(GetSdrPageViewOfMarkedByIndex(0),&(pObj->GetSnapRect()));
1706 			const SdrPageGridFrame* pFrame=NULL;
1707 			if (pGFL!=NULL && pGFL->GetCount()!=0)
1708 			{ // Writer
1709 				pFrame=&((*pGFL)[0]);
1710 			}
1711 
1712 			if (pFrame!=NULL)
1713 			{ // Writer
1714 				aBound=pFrame->GetUserArea();
1715 			}
1716 			else
1717 			{
1718 				aBound=Rectangle(pPage->GetLftBorder(),pPage->GetUppBorder(),
1719 								 pPage->GetWdt()-pPage->GetRgtBorder(),
1720 								 pPage->GetHgt()-pPage->GetLwrBorder());
1721 			}
1722 		}
1723 		else
1724 		{
1725 			if (bBoundRects)
1726 				aBound=GetMarkedObjBoundRect();
1727 			else
1728 				aBound=GetMarkedObjRect();
1729 		}
1730 	}
1731 	Point aCenter(aBound.Center());
1732 	for (nm=0; nm<nMarkAnz; nm++)
1733 	{
1734 		SdrMark* pM=GetSdrMarkByIndex(nm);
1735 		SdrObject* pObj=pM->GetMarkedSdrObj();
1736 		SdrObjTransformInfoRec aInfo;
1737 		pObj->TakeObjInfo(aInfo);
1738 		if (aInfo.bMoveAllowed && !pObj->IsMoveProtect())
1739 		{
1740 			// SdrPageView* pPV=pM->GetPageView();
1741 			long nXMov=0;
1742 			long nYMov=0;
1743 			Rectangle aObjRect(bBoundRects?pObj->GetCurrentBoundRect():pObj->GetSnapRect());
1744 			switch (eVert)
1745 			{
1746 				case SDRVALIGN_TOP   : nYMov=aBound.Top()   -aObjRect.Top()       ; break;
1747 				case SDRVALIGN_BOTTOM: nYMov=aBound.Bottom()-aObjRect.Bottom()    ; break;
1748 				case SDRVALIGN_CENTER: nYMov=aCenter.Y()    -aObjRect.Center().Y(); break;
1749 				default: break;
1750 			}
1751 			switch (eHor)
1752 			{
1753 				case SDRHALIGN_LEFT  : nXMov=aBound.Left()  -aObjRect.Left()      ; break;
1754 				case SDRHALIGN_RIGHT : nXMov=aBound.Right() -aObjRect.Right()     ; break;
1755 				case SDRHALIGN_CENTER: nXMov=aCenter.X()    -aObjRect.Center().X(); break;
1756 				default: break;
1757 			}
1758 			if (nXMov!=0 || nYMov!=0)
1759 			{
1760 				// #104104# SdrEdgeObj needs an extra SdrUndoGeoObj since the
1761 				// connections may need to be saved
1762 				if( bUndo )
1763 				{
1764 					if( dynamic_cast<SdrEdgeObj*>(pObj) )
1765 					{
1766 						AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
1767 					}
1768 
1769 					AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoMoveObject(*pObj,Size(nXMov,nYMov)));
1770 				}
1771 
1772 				pObj->Move(Size(nXMov,nYMov));
1773 			}
1774 		}
1775 	}
1776 
1777 	if( bUndo )
1778 		EndUndo();
1779 }
1780 
1781