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