merge the formfield patch from ooo-build
[ooovba.git] / svx / source / svdraw / svdotxdr.cxx
blob14e0ad1d84d0749acd3225357cde4cae6eecc2ef
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: svdotxdr.cxx,v $
10 * $Revision: 1.9 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 #include <svx/svdotext.hxx>
35 #include <svx/svdhdl.hxx>
36 #include <svx/svddrag.hxx>
37 #include <svx/svdview.hxx>
38 #include <svx/svdorect.hxx> // fuer SetXPolyDirty in MovCreate bei SolidDragging
39 #include "svdglob.hxx" // Stringcache
40 #include "svdstr.hrc" // Objektname
41 #include <svx/svdoashp.hxx>
42 #include <tools/bigint.hxx>
43 #include <basegfx/polygon/b2dpolygon.hxx>
44 #include <basegfx/range/b2drange.hxx>
45 #include <basegfx/polygon/b2dpolygontools.hxx>
47 ////////////////////////////////////////////////////////////////////////////////////////////////////
49 // @@@@@@ @@@@@ @@ @@ @@@@@@ @@@@ @@@@@ @@@@@@
50 // @@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@
51 // @@ @@ @@@@@ @@ @@ @@ @@ @@ @@
52 // @@ @@@@ @@@ @@ @@ @@ @@@@@ @@
53 // @@ @@ @@@@@ @@ @@ @@ @@ @@ @@
54 // @@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@ @@
55 // @@ @@@@@ @@ @@ @@ @@@@ @@@@@ @@@@
57 // Dragging, Handles, Create
59 ////////////////////////////////////////////////////////////////////////////////////////////////////
61 sal_uInt32 SdrTextObj::GetHdlCount() const
63 return 8L;
66 SdrHdl* SdrTextObj::GetHdl(sal_uInt32 nHdlNum) const
68 SdrHdl* pH=NULL;
69 Point aPnt;
70 SdrHdlKind eKind=HDL_MOVE;
71 switch (nHdlNum) {
72 case 0: aPnt=aRect.TopLeft(); eKind=HDL_UPLFT; break; // Oben links
73 case 1: aPnt=aRect.TopCenter(); eKind=HDL_UPPER; break; // Oben
74 case 2: aPnt=aRect.TopRight(); eKind=HDL_UPRGT; break; // Oben rechts
75 case 3: aPnt=aRect.LeftCenter(); eKind=HDL_LEFT ; break; // Links
76 case 4: aPnt=aRect.RightCenter(); eKind=HDL_RIGHT; break; // Rechts
77 case 5: aPnt=aRect.BottomLeft(); eKind=HDL_LWLFT; break; // Unten links
78 case 6: aPnt=aRect.BottomCenter(); eKind=HDL_LOWER; break; // Unten
79 case 7: aPnt=aRect.BottomRight(); eKind=HDL_LWRGT; break; // Unten rechts
81 if (aGeo.nShearWink!=0) ShearPoint(aPnt,aRect.TopLeft(),aGeo.nTan);
82 if (aGeo.nDrehWink!=0) RotatePoint(aPnt,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
83 if (eKind!=HDL_MOVE) {
84 pH=new SdrHdl(aPnt,eKind);
85 pH->SetObj((SdrObject*)this);
86 pH->SetDrehWink(aGeo.nDrehWink);
88 return pH;
91 ////////////////////////////////////////////////////////////////////////////////////////////////////
93 bool SdrTextObj::hasSpecialDrag() const
95 return true;
98 Rectangle SdrTextObj::ImpDragCalcRect(const SdrDragStat& rDrag) const
100 Rectangle aTmpRect(aRect);
101 const SdrHdl* pHdl=rDrag.GetHdl();
102 SdrHdlKind eHdl=pHdl==NULL ? HDL_MOVE : pHdl->GetKind();
103 FASTBOOL bEcke=(eHdl==HDL_UPLFT || eHdl==HDL_UPRGT || eHdl==HDL_LWLFT || eHdl==HDL_LWRGT);
104 FASTBOOL bOrtho=rDrag.GetView()!=NULL && rDrag.GetView()->IsOrtho();
105 FASTBOOL bBigOrtho=bEcke && bOrtho && rDrag.GetView()->IsBigOrtho();
106 Point aPos(rDrag.GetNow());
107 // Unrotate:
108 if (aGeo.nDrehWink!=0) RotatePoint(aPos,aTmpRect.TopLeft(),-aGeo.nSin,aGeo.nCos);
109 // Unshear:
110 if (aGeo.nShearWink!=0) ShearPoint(aPos,aTmpRect.TopLeft(),-aGeo.nTan);
112 FASTBOOL bLft=(eHdl==HDL_UPLFT || eHdl==HDL_LEFT || eHdl==HDL_LWLFT);
113 FASTBOOL bRgt=(eHdl==HDL_UPRGT || eHdl==HDL_RIGHT || eHdl==HDL_LWRGT);
114 FASTBOOL bTop=(eHdl==HDL_UPRGT || eHdl==HDL_UPPER || eHdl==HDL_UPLFT);
115 FASTBOOL bBtm=(eHdl==HDL_LWRGT || eHdl==HDL_LOWER || eHdl==HDL_LWLFT);
116 if (bLft) aTmpRect.Left() =aPos.X();
117 if (bRgt) aTmpRect.Right() =aPos.X();
118 if (bTop) aTmpRect.Top() =aPos.Y();
119 if (bBtm) aTmpRect.Bottom()=aPos.Y();
120 if (bOrtho) { // Ortho
121 long nWdt0=aRect.Right() -aRect.Left();
122 long nHgt0=aRect.Bottom()-aRect.Top();
123 long nXMul=aTmpRect.Right() -aTmpRect.Left();
124 long nYMul=aTmpRect.Bottom()-aTmpRect.Top();
125 long nXDiv=nWdt0;
126 long nYDiv=nHgt0;
127 FASTBOOL bXNeg=(nXMul<0)!=(nXDiv<0);
128 FASTBOOL bYNeg=(nYMul<0)!=(nYDiv<0);
129 nXMul=Abs(nXMul);
130 nYMul=Abs(nYMul);
131 nXDiv=Abs(nXDiv);
132 nYDiv=Abs(nYDiv);
133 Fraction aXFact(nXMul,nXDiv); // Fractions zum kuerzen
134 Fraction aYFact(nYMul,nYDiv); // und zum vergleichen
135 nXMul=aXFact.GetNumerator();
136 nYMul=aYFact.GetNumerator();
137 nXDiv=aXFact.GetDenominator();
138 nYDiv=aYFact.GetDenominator();
139 if (bEcke) { // Eckpunkthandles
140 FASTBOOL bUseX=(aXFact<aYFact) != bBigOrtho;
141 if (bUseX) {
142 long nNeed=long(BigInt(nHgt0)*BigInt(nXMul)/BigInt(nXDiv));
143 if (bYNeg) nNeed=-nNeed;
144 if (bTop) aTmpRect.Top()=aTmpRect.Bottom()-nNeed;
145 if (bBtm) aTmpRect.Bottom()=aTmpRect.Top()+nNeed;
146 } else {
147 long nNeed=long(BigInt(nWdt0)*BigInt(nYMul)/BigInt(nYDiv));
148 if (bXNeg) nNeed=-nNeed;
149 if (bLft) aTmpRect.Left()=aTmpRect.Right()-nNeed;
150 if (bRgt) aTmpRect.Right()=aTmpRect.Left()+nNeed;
152 } else { // Scheitelpunkthandles
153 if ((bLft || bRgt) && nXDiv!=0) {
154 long nHgt0b=aRect.Bottom()-aRect.Top();
155 long nNeed=long(BigInt(nHgt0b)*BigInt(nXMul)/BigInt(nXDiv));
156 aTmpRect.Top()-=(nNeed-nHgt0b)/2;
157 aTmpRect.Bottom()=aTmpRect.Top()+nNeed;
159 if ((bTop || bBtm) && nYDiv!=0) {
160 long nWdt0b=aRect.Right()-aRect.Left();
161 long nNeed=long(BigInt(nWdt0b)*BigInt(nYMul)/BigInt(nYDiv));
162 aTmpRect.Left()-=(nNeed-nWdt0b)/2;
163 aTmpRect.Right()=aTmpRect.Left()+nNeed;
167 if (!ISA(SdrObjCustomShape)) // not justifying for CustomShapes to be able to detect if a shape has to be mirrored
168 ImpJustifyRect(aTmpRect);
169 return aTmpRect;
172 ////////////////////////////////////////////////////////////////////////////////////////////////////
173 // drag
175 bool SdrTextObj::applySpecialDrag(SdrDragStat& rDrag)
177 Rectangle aNewRect(ImpDragCalcRect(rDrag));
179 if(aNewRect.TopLeft() != aRect.TopLeft() && (aGeo.nDrehWink || aGeo.nShearWink))
181 Point aNewPos(aNewRect.TopLeft());
183 if(aGeo.nShearWink)
184 ShearPoint(aNewPos,aRect.TopLeft(),aGeo.nTan);
186 if(aGeo.nDrehWink)
187 RotatePoint(aNewPos,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
189 aNewRect.SetPos(aNewPos);
192 if(aNewRect != aRect)
194 NbcSetLogicRect(aNewRect);
197 return true;
200 String SdrTextObj::getSpecialDragComment(const SdrDragStat& /*rDrag*/) const
202 XubString aStr;
203 ImpTakeDescriptionStr(STR_DragRectResize,aStr);
204 return aStr;
207 ////////////////////////////////////////////////////////////////////////////////////////////////////
208 // Create
210 FASTBOOL SdrTextObj::BegCreate(SdrDragStat& rStat)
212 rStat.SetOrtho4Possible();
213 Rectangle aRect1(rStat.GetStart(), rStat.GetNow());
214 aRect1.Justify();
215 rStat.SetActionRect(aRect1);
216 aRect = aRect1;
217 return TRUE;
220 FASTBOOL SdrTextObj::MovCreate(SdrDragStat& rStat)
222 Rectangle aRect1;
223 rStat.TakeCreateRect(aRect1);
224 ImpJustifyRect(aRect1);
225 rStat.SetActionRect(aRect1);
226 aRect=aRect1; // fuer ObjName
227 SetBoundRectDirty();
228 bSnapRectDirty=TRUE;
229 if (HAS_BASE(SdrRectObj,this)) {
230 ((SdrRectObj*)this)->SetXPolyDirty();
232 return TRUE;
235 FASTBOOL SdrTextObj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
237 rStat.TakeCreateRect(aRect);
238 ImpJustifyRect(aRect);
239 if (bTextFrame) {
240 if (IsAutoGrowHeight()) {
241 // MinTextHeight
242 long nHgt=aRect.GetHeight()-1;
243 if (nHgt==1) nHgt=0;
244 NbcSetMinTextFrameHeight(nHgt);
246 if (IsAutoGrowWidth()) {
247 // MinTextWidth
248 long nWdt=aRect.GetWidth()-1;
249 if (nWdt==1) nWdt=0;
250 NbcSetMinTextFrameWidth(nWdt);
252 // Textrahmen neu berechnen
253 NbcAdjustTextFrameWidthAndHeight();
255 SetRectsDirty();
256 if (HAS_BASE(SdrRectObj,this)) {
257 ((SdrRectObj*)this)->SetXPolyDirty();
259 return (eCmd==SDRCREATE_FORCEEND || rStat.GetPointAnz()>=2);
262 void SdrTextObj::BrkCreate(SdrDragStat& /*rStat*/)
266 FASTBOOL SdrTextObj::BckCreate(SdrDragStat& /*rStat*/)
268 return TRUE;
271 basegfx::B2DPolyPolygon SdrTextObj::TakeCreatePoly(const SdrDragStat& rDrag) const
273 Rectangle aRect1;
274 rDrag.TakeCreateRect(aRect1);
275 aRect1.Justify();
277 basegfx::B2DPolyPolygon aRetval;
278 const basegfx::B2DRange aRange(aRect1.Left(), aRect1.Top(), aRect1.Right(), aRect1.Bottom());
279 aRetval.append(basegfx::tools::createPolygonFromRect(aRange));
280 return aRetval;
283 Pointer SdrTextObj::GetCreatePointer() const
285 if (IsTextFrame()) return Pointer(POINTER_DRAW_TEXT);
286 return Pointer(POINTER_CROSS);