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