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