1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <svx/svdotext.hxx>
22 #include <svx/svdhdl.hxx>
23 #include <svx/svddrag.hxx>
24 #include <svx/svdview.hxx>
25 #include <svx/svdorect.hxx> // for SetXPolyDirty in MovCreate at SolidDragging
26 #include "svx/svdglob.hxx" // Stringcache
27 #include "svx/svdstr.hrc" // the object's name
28 #include <svx/svdoashp.hxx>
29 #include <tools/bigint.hxx>
30 #include <basegfx/polygon/b2dpolygon.hxx>
31 #include <basegfx/range/b2drange.hxx>
32 #include <basegfx/polygon/b2dpolygontools.hxx>
35 sal_uInt32
SdrTextObj::GetHdlCount() const
40 SdrHdl
* SdrTextObj::GetHdl(sal_uInt32 nHdlNum
) const
44 SdrHdlKind eKind
=HDL_MOVE
;
46 case 0: aPnt
=aRect
.TopLeft(); eKind
=HDL_UPLFT
; break;
47 case 1: aPnt
=aRect
.TopCenter(); eKind
=HDL_UPPER
; break;
48 case 2: aPnt
=aRect
.TopRight(); eKind
=HDL_UPRGT
; break;
49 case 3: aPnt
=aRect
.LeftCenter(); eKind
=HDL_LEFT
; break;
50 case 4: aPnt
=aRect
.RightCenter(); eKind
=HDL_RIGHT
; break;
51 case 5: aPnt
=aRect
.BottomLeft(); eKind
=HDL_LWLFT
; break;
52 case 6: aPnt
=aRect
.BottomCenter(); eKind
=HDL_LOWER
; break;
53 case 7: aPnt
=aRect
.BottomRight(); eKind
=HDL_LWRGT
; break;
55 if (aGeo
.nShearWink
!=0) ShearPoint(aPnt
,aRect
.TopLeft(),aGeo
.nTan
);
56 if (aGeo
.nDrehWink
!=0) RotatePoint(aPnt
,aRect
.TopLeft(),aGeo
.nSin
,aGeo
.nCos
);
57 if (eKind
!=HDL_MOVE
) {
58 pH
=new SdrHdl(aPnt
,eKind
);
59 pH
->SetObj((SdrObject
*)this);
60 pH
->SetDrehWink(aGeo
.nDrehWink
);
65 ////////////////////////////////////////////////////////////////////////////////////////////////////
67 bool SdrTextObj::hasSpecialDrag() const
72 Rectangle
SdrTextObj::ImpDragCalcRect(const SdrDragStat
& rDrag
) const
74 Rectangle
aTmpRect(aRect
);
75 const SdrHdl
* pHdl
=rDrag
.GetHdl();
76 SdrHdlKind eHdl
=pHdl
==NULL
? HDL_MOVE
: pHdl
->GetKind();
77 bool bEcke
=(eHdl
==HDL_UPLFT
|| eHdl
==HDL_UPRGT
|| eHdl
==HDL_LWLFT
|| eHdl
==HDL_LWRGT
);
78 bool bOrtho
=rDrag
.GetView()!=NULL
&& rDrag
.GetView()->IsOrtho();
79 bool bBigOrtho
=bEcke
&& bOrtho
&& rDrag
.GetView()->IsBigOrtho();
80 Point
aPos(rDrag
.GetNow());
82 if (aGeo
.nDrehWink
!=0) RotatePoint(aPos
,aTmpRect
.TopLeft(),-aGeo
.nSin
,aGeo
.nCos
);
84 if (aGeo
.nShearWink
!=0) ShearPoint(aPos
,aTmpRect
.TopLeft(),-aGeo
.nTan
);
86 bool bLft
=(eHdl
==HDL_UPLFT
|| eHdl
==HDL_LEFT
|| eHdl
==HDL_LWLFT
);
87 bool bRgt
=(eHdl
==HDL_UPRGT
|| eHdl
==HDL_RIGHT
|| eHdl
==HDL_LWRGT
);
88 bool bTop
=(eHdl
==HDL_UPRGT
|| eHdl
==HDL_UPPER
|| eHdl
==HDL_UPLFT
);
89 bool bBtm
=(eHdl
==HDL_LWRGT
|| eHdl
==HDL_LOWER
|| eHdl
==HDL_LWLFT
);
90 if (bLft
) aTmpRect
.Left() =aPos
.X();
91 if (bRgt
) aTmpRect
.Right() =aPos
.X();
92 if (bTop
) aTmpRect
.Top() =aPos
.Y();
93 if (bBtm
) aTmpRect
.Bottom()=aPos
.Y();
94 if (bOrtho
) { // Ortho
95 long nWdt0
=aRect
.Right() -aRect
.Left();
96 long nHgt0
=aRect
.Bottom()-aRect
.Top();
97 long nXMul
=aTmpRect
.Right() -aTmpRect
.Left();
98 long nYMul
=aTmpRect
.Bottom()-aTmpRect
.Top();
101 bool bXNeg
=(nXMul
<0)!=(nXDiv
<0);
102 bool bYNeg
=(nYMul
<0)!=(nYDiv
<0);
103 nXMul
=std::abs(nXMul
);
104 nYMul
=std::abs(nYMul
);
105 nXDiv
=std::abs(nXDiv
);
106 nYDiv
=std::abs(nYDiv
);
107 Fraction
aXFact(nXMul
,nXDiv
); // fractions for canceling
108 Fraction
aYFact(nYMul
,nYDiv
); // and for comparing
109 nXMul
=aXFact
.GetNumerator();
110 nYMul
=aYFact
.GetNumerator();
111 nXDiv
=aXFact
.GetDenominator();
112 nYDiv
=aYFact
.GetDenominator();
113 if (bEcke
) { // corner point handles
114 bool bUseX
=(aXFact
<aYFact
) != bBigOrtho
;
116 long nNeed
=long(BigInt(nHgt0
)*BigInt(nXMul
)/BigInt(nXDiv
));
117 if (bYNeg
) nNeed
=-nNeed
;
118 if (bTop
) aTmpRect
.Top()=aTmpRect
.Bottom()-nNeed
;
119 if (bBtm
) aTmpRect
.Bottom()=aTmpRect
.Top()+nNeed
;
121 long nNeed
=long(BigInt(nWdt0
)*BigInt(nYMul
)/BigInt(nYDiv
));
122 if (bXNeg
) nNeed
=-nNeed
;
123 if (bLft
) aTmpRect
.Left()=aTmpRect
.Right()-nNeed
;
124 if (bRgt
) aTmpRect
.Right()=aTmpRect
.Left()+nNeed
;
126 } else { // apex handles
127 if ((bLft
|| bRgt
) && nXDiv
!=0) {
128 long nHgt0b
=aRect
.Bottom()-aRect
.Top();
129 long nNeed
=long(BigInt(nHgt0b
)*BigInt(nXMul
)/BigInt(nXDiv
));
130 aTmpRect
.Top()-=(nNeed
-nHgt0b
)/2;
131 aTmpRect
.Bottom()=aTmpRect
.Top()+nNeed
;
133 if ((bTop
|| bBtm
) && nYDiv
!=0) {
134 long nWdt0b
=aRect
.Right()-aRect
.Left();
135 long nNeed
=long(BigInt(nWdt0b
)*BigInt(nYMul
)/BigInt(nYDiv
));
136 aTmpRect
.Left()-=(nNeed
-nWdt0b
)/2;
137 aTmpRect
.Right()=aTmpRect
.Left()+nNeed
;
141 if (!ISA(SdrObjCustomShape
)) // not justifying when in CustomShapes, to be able to detect if a shape has to be mirrored
142 ImpJustifyRect(aTmpRect
);
146 ////////////////////////////////////////////////////////////////////////////////////////////////////
149 bool SdrTextObj::applySpecialDrag(SdrDragStat
& rDrag
)
151 Rectangle
aNewRect(ImpDragCalcRect(rDrag
));
153 if(aNewRect
.TopLeft() != aRect
.TopLeft() && (aGeo
.nDrehWink
|| aGeo
.nShearWink
))
155 Point
aNewPos(aNewRect
.TopLeft());
158 ShearPoint(aNewPos
,aRect
.TopLeft(),aGeo
.nTan
);
161 RotatePoint(aNewPos
,aRect
.TopLeft(),aGeo
.nSin
,aGeo
.nCos
);
163 aNewRect
.SetPos(aNewPos
);
166 if(aNewRect
!= aRect
)
168 NbcSetLogicRect(aNewRect
);
174 String
SdrTextObj::getSpecialDragComment(const SdrDragStat
& /*rDrag*/) const
177 ImpTakeDescriptionStr(STR_DragRectResize
,aStr
);
181 ////////////////////////////////////////////////////////////////////////////////////////////////////
184 bool SdrTextObj::BegCreate(SdrDragStat
& rStat
)
186 rStat
.SetOrtho4Possible();
187 Rectangle
aRect1(rStat
.GetStart(), rStat
.GetNow());
189 rStat
.SetActionRect(aRect1
);
194 bool SdrTextObj::MovCreate(SdrDragStat
& rStat
)
197 rStat
.TakeCreateRect(aRect1
);
198 ImpJustifyRect(aRect1
);
199 rStat
.SetActionRect(aRect1
);
200 aRect
=aRect1
; // for ObjName
202 bSnapRectDirty
=sal_True
;
203 if (HAS_BASE(SdrRectObj
,this)) {
204 ((SdrRectObj
*)this)->SetXPolyDirty();
209 bool SdrTextObj::EndCreate(SdrDragStat
& rStat
, SdrCreateCmd eCmd
)
211 rStat
.TakeCreateRect(aRect
);
212 ImpJustifyRect(aRect
);
214 if (IsAutoGrowHeight()) {
216 long nHgt
=aRect
.GetHeight()-1;
218 NbcSetMinTextFrameHeight(nHgt
);
220 if (IsAutoGrowWidth()) {
222 long nWdt
=aRect
.GetWidth()-1;
224 NbcSetMinTextFrameWidth(nWdt
);
226 // re-calculate text frame
227 NbcAdjustTextFrameWidthAndHeight();
230 if (HAS_BASE(SdrRectObj
,this)) {
231 ((SdrRectObj
*)this)->SetXPolyDirty();
233 return (eCmd
==SDRCREATE_FORCEEND
|| rStat
.GetPointAnz()>=2);
236 void SdrTextObj::BrkCreate(SdrDragStat
& /*rStat*/)
240 bool SdrTextObj::BckCreate(SdrDragStat
& /*rStat*/)
245 basegfx::B2DPolyPolygon
SdrTextObj::TakeCreatePoly(const SdrDragStat
& rDrag
) const
248 rDrag
.TakeCreateRect(aRect1
);
251 basegfx::B2DPolyPolygon aRetval
;
252 const basegfx::B2DRange
aRange(aRect1
.Left(), aRect1
.Top(), aRect1
.Right(), aRect1
.Bottom());
253 aRetval
.append(basegfx::tools::createPolygonFromRect(aRange
));
257 Pointer
SdrTextObj::GetCreatePointer() const
259 if (IsTextFrame()) return Pointer(POINTER_DRAW_TEXT
);
260 return Pointer(POINTER_CROSS
);
263 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */