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