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