xref: /AOO41X/main/svx/source/svdraw/svdotxdr.cxx (revision 54628ca40d27d15cc98fe861da7fff7e60c2f7d6)
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/svdotext.hxx>
28 #include <svx/svdhdl.hxx>
29 #include <svx/svddrag.hxx>
30 #include <svx/svdview.hxx>
31 #include <svx/svdorect.hxx> // fuer SetXPolyDirty in MovCreate bei SolidDragging
32 #include "svx/svdglob.hxx"  // Stringcache
33 #include "svx/svdstr.hrc"   // Objektname
34 #include <svx/svdoashp.hxx>
35 #include <tools/bigint.hxx>
36 #include <basegfx/polygon/b2dpolygon.hxx>
37 #include <basegfx/range/b2drange.hxx>
38 #include <basegfx/polygon/b2dpolygontools.hxx>
39 
40 ////////////////////////////////////////////////////////////////////////////////////////////////////
41 //
42 //  @@@@@@ @@@@@ @@   @@ @@@@@@  @@@@  @@@@@  @@@@@@
43 //    @@   @@    @@@ @@@   @@   @@  @@ @@  @@     @@
44 //    @@   @@     @@@@@    @@   @@  @@ @@  @@     @@
45 //    @@   @@@@    @@@     @@   @@  @@ @@@@@      @@
46 //    @@   @@     @@@@@    @@   @@  @@ @@  @@     @@
47 //    @@   @@    @@@ @@@   @@   @@  @@ @@  @@ @@  @@
48 //    @@   @@@@@ @@   @@   @@    @@@@  @@@@@   @@@@
49 //
50 //  Dragging, Handles, Create
51 //
52 ////////////////////////////////////////////////////////////////////////////////////////////////////
53 
54 sal_uInt32 SdrTextObj::GetHdlCount() const
55 {
56     return 8L;
57 }
58 
59 SdrHdl* SdrTextObj::GetHdl(sal_uInt32 nHdlNum) const
60 {
61     SdrHdl* pH=NULL;
62     Point aPnt;
63     SdrHdlKind eKind=HDL_MOVE;
64     switch (nHdlNum) {
65         case 0: aPnt=aRect.TopLeft();      eKind=HDL_UPLFT; break; // Oben links
66         case 1: aPnt=aRect.TopCenter();    eKind=HDL_UPPER; break; // Oben
67         case 2: aPnt=aRect.TopRight();     eKind=HDL_UPRGT; break; // Oben rechts
68         case 3: aPnt=aRect.LeftCenter();   eKind=HDL_LEFT ; break; // Links
69         case 4: aPnt=aRect.RightCenter();  eKind=HDL_RIGHT; break; // Rechts
70         case 5: aPnt=aRect.BottomLeft();   eKind=HDL_LWLFT; break; // Unten links
71         case 6: aPnt=aRect.BottomCenter(); eKind=HDL_LOWER; break; // Unten
72         case 7: aPnt=aRect.BottomRight();  eKind=HDL_LWRGT; break; // Unten rechts
73     }
74     if (aGeo.nShearWink!=0) ShearPoint(aPnt,aRect.TopLeft(),aGeo.nTan);
75     if (aGeo.nDrehWink!=0) RotatePoint(aPnt,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
76     if (eKind!=HDL_MOVE) {
77         pH=new SdrHdl(aPnt,eKind);
78         pH->SetObj((SdrObject*)this);
79         pH->SetDrehWink(aGeo.nDrehWink);
80     }
81     return pH;
82 }
83 
84 ////////////////////////////////////////////////////////////////////////////////////////////////////
85 
86 bool SdrTextObj::hasSpecialDrag() const
87 {
88     return true;
89 }
90 
91 Rectangle SdrTextObj::ImpDragCalcRect(const SdrDragStat& rDrag) const
92 {
93     Rectangle aTmpRect(aRect);
94     const SdrHdl* pHdl=rDrag.GetHdl();
95     SdrHdlKind eHdl=pHdl==NULL ? HDL_MOVE : pHdl->GetKind();
96     FASTBOOL bEcke=(eHdl==HDL_UPLFT || eHdl==HDL_UPRGT || eHdl==HDL_LWLFT || eHdl==HDL_LWRGT);
97     FASTBOOL bOrtho=rDrag.GetView()!=NULL && rDrag.GetView()->IsOrtho();
98     FASTBOOL bBigOrtho=bEcke && bOrtho && rDrag.GetView()->IsBigOrtho();
99     Point aPos(rDrag.GetNow());
100     // Unrotate:
101     if (aGeo.nDrehWink!=0) RotatePoint(aPos,aTmpRect.TopLeft(),-aGeo.nSin,aGeo.nCos);
102     // Unshear:
103     if (aGeo.nShearWink!=0) ShearPoint(aPos,aTmpRect.TopLeft(),-aGeo.nTan);
104     //
105     FASTBOOL bLft=(eHdl==HDL_UPLFT || eHdl==HDL_LEFT  || eHdl==HDL_LWLFT);
106     FASTBOOL bRgt=(eHdl==HDL_UPRGT || eHdl==HDL_RIGHT || eHdl==HDL_LWRGT);
107     FASTBOOL bTop=(eHdl==HDL_UPRGT || eHdl==HDL_UPPER || eHdl==HDL_UPLFT);
108     FASTBOOL bBtm=(eHdl==HDL_LWRGT || eHdl==HDL_LOWER || eHdl==HDL_LWLFT);
109     if (bLft) aTmpRect.Left()  =aPos.X();
110     if (bRgt) aTmpRect.Right() =aPos.X();
111     if (bTop) aTmpRect.Top()   =aPos.Y();
112     if (bBtm) aTmpRect.Bottom()=aPos.Y();
113     if (bOrtho) { // Ortho
114         long nWdt0=aRect.Right() -aRect.Left();
115         long nHgt0=aRect.Bottom()-aRect.Top();
116         long nXMul=aTmpRect.Right() -aTmpRect.Left();
117         long nYMul=aTmpRect.Bottom()-aTmpRect.Top();
118         long nXDiv=nWdt0;
119         long nYDiv=nHgt0;
120         FASTBOOL bXNeg=(nXMul<0)!=(nXDiv<0);
121         FASTBOOL bYNeg=(nYMul<0)!=(nYDiv<0);
122         nXMul=Abs(nXMul);
123         nYMul=Abs(nYMul);
124         nXDiv=Abs(nXDiv);
125         nYDiv=Abs(nYDiv);
126         Fraction aXFact(nXMul,nXDiv); // Fractions zum kuerzen
127         Fraction aYFact(nYMul,nYDiv); // und zum vergleichen
128         nXMul=aXFact.GetNumerator();
129         nYMul=aYFact.GetNumerator();
130         nXDiv=aXFact.GetDenominator();
131         nYDiv=aYFact.GetDenominator();
132         if (bEcke) { // Eckpunkthandles
133             FASTBOOL bUseX=(aXFact<aYFact) != bBigOrtho;
134             if (bUseX) {
135                 long nNeed=long(BigInt(nHgt0)*BigInt(nXMul)/BigInt(nXDiv));
136                 if (bYNeg) nNeed=-nNeed;
137                 if (bTop) aTmpRect.Top()=aTmpRect.Bottom()-nNeed;
138                 if (bBtm) aTmpRect.Bottom()=aTmpRect.Top()+nNeed;
139             } else {
140                 long nNeed=long(BigInt(nWdt0)*BigInt(nYMul)/BigInt(nYDiv));
141                 if (bXNeg) nNeed=-nNeed;
142                 if (bLft) aTmpRect.Left()=aTmpRect.Right()-nNeed;
143                 if (bRgt) aTmpRect.Right()=aTmpRect.Left()+nNeed;
144             }
145         } else { // Scheitelpunkthandles
146             if ((bLft || bRgt) && nXDiv!=0) {
147                 long nHgt0b=aRect.Bottom()-aRect.Top();
148                 long nNeed=long(BigInt(nHgt0b)*BigInt(nXMul)/BigInt(nXDiv));
149                 aTmpRect.Top()-=(nNeed-nHgt0b)/2;
150                 aTmpRect.Bottom()=aTmpRect.Top()+nNeed;
151             }
152             if ((bTop || bBtm) && nYDiv!=0) {
153                 long nWdt0b=aRect.Right()-aRect.Left();
154                 long nNeed=long(BigInt(nWdt0b)*BigInt(nYMul)/BigInt(nYDiv));
155                 aTmpRect.Left()-=(nNeed-nWdt0b)/2;
156                 aTmpRect.Right()=aTmpRect.Left()+nNeed;
157             }
158         }
159     }
160     if (!ISA(SdrObjCustomShape))        // not justifying for CustomShapes to be able to detect if a shape has to be mirrored
161         ImpJustifyRect(aTmpRect);
162     return aTmpRect;
163 }
164 
165 ////////////////////////////////////////////////////////////////////////////////////////////////////
166 // drag
167 
168 bool SdrTextObj::applySpecialDrag(SdrDragStat& rDrag)
169 {
170     Rectangle aNewRect(ImpDragCalcRect(rDrag));
171 
172     if(aNewRect.TopLeft() != aRect.TopLeft() && (aGeo.nDrehWink || aGeo.nShearWink))
173     {
174         Point aNewPos(aNewRect.TopLeft());
175 
176         if(aGeo.nShearWink)
177             ShearPoint(aNewPos,aRect.TopLeft(),aGeo.nTan);
178 
179         if(aGeo.nDrehWink)
180             RotatePoint(aNewPos,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
181 
182         aNewRect.SetPos(aNewPos);
183     }
184 
185     if(aNewRect != aRect)
186     {
187         NbcSetLogicRect(aNewRect);
188     }
189 
190     return true;
191 }
192 
193 String SdrTextObj::getSpecialDragComment(const SdrDragStat& /*rDrag*/) const
194 {
195     XubString aStr;
196     ImpTakeDescriptionStr(STR_DragRectResize,aStr);
197     return aStr;
198 }
199 
200 ////////////////////////////////////////////////////////////////////////////////////////////////////
201 // Create
202 
203 FASTBOOL SdrTextObj::BegCreate(SdrDragStat& rStat)
204 {
205     rStat.SetOrtho4Possible();
206     Rectangle aRect1(rStat.GetStart(), rStat.GetNow());
207     aRect1.Justify();
208     rStat.SetActionRect(aRect1);
209     aRect = aRect1;
210     return sal_True;
211 }
212 
213 FASTBOOL SdrTextObj::MovCreate(SdrDragStat& rStat)
214 {
215     Rectangle aRect1;
216     rStat.TakeCreateRect(aRect1);
217     ImpJustifyRect(aRect1);
218     rStat.SetActionRect(aRect1);
219     aRect=aRect1; // fuer ObjName
220     SetBoundRectDirty();
221     bSnapRectDirty=sal_True;
222     if (HAS_BASE(SdrRectObj,this)) {
223         ((SdrRectObj*)this)->SetXPolyDirty();
224     }
225     return sal_True;
226 }
227 
228 FASTBOOL SdrTextObj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
229 {
230     rStat.TakeCreateRect(aRect);
231     ImpJustifyRect(aRect);
232     if (bTextFrame) {
233         if (IsAutoGrowHeight()) {
234             // MinTextHeight
235             long nHgt=aRect.GetHeight()-1;
236             if (nHgt==1) nHgt=0;
237             NbcSetMinTextFrameHeight(nHgt);
238         }
239         if (IsAutoGrowWidth()) {
240             // MinTextWidth
241             long nWdt=aRect.GetWidth()-1;
242             if (nWdt==1) nWdt=0;
243             NbcSetMinTextFrameWidth(nWdt);
244         }
245         // Textrahmen neu berechnen
246         NbcAdjustTextFrameWidthAndHeight();
247     }
248     SetRectsDirty();
249     if (HAS_BASE(SdrRectObj,this)) {
250         ((SdrRectObj*)this)->SetXPolyDirty();
251     }
252     return (eCmd==SDRCREATE_FORCEEND || rStat.GetPointAnz()>=2);
253 }
254 
255 void SdrTextObj::BrkCreate(SdrDragStat& /*rStat*/)
256 {
257 }
258 
259 FASTBOOL SdrTextObj::BckCreate(SdrDragStat& /*rStat*/)
260 {
261     return sal_True;
262 }
263 
264 basegfx::B2DPolyPolygon SdrTextObj::TakeCreatePoly(const SdrDragStat& rDrag) const
265 {
266     Rectangle aRect1;
267     rDrag.TakeCreateRect(aRect1);
268     aRect1.Justify();
269 
270     basegfx::B2DPolyPolygon aRetval;
271     const basegfx::B2DRange aRange(aRect1.Left(), aRect1.Top(), aRect1.Right(), aRect1.Bottom());
272     aRetval.append(basegfx::tools::createPolygonFromRect(aRange));
273     return aRetval;
274 }
275 
276 Pointer SdrTextObj::GetCreatePointer() const
277 {
278     if (IsTextFrame()) return Pointer(POINTER_DRAW_TEXT);
279     return Pointer(POINTER_CROSS);
280 }
281 
282