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/svdmodel.hxx> // for GetMaxObjSize
23 #include <svx/svdoutl.hxx>
24 #include <editeng/editdata.hxx>
25 #include <editeng/outliner.hxx>
26 #include <editeng/editstat.hxx>
27 #include <svl/itemset.hxx>
28 #include <editeng/eeitem.hxx>
29 #include <svx/sdtfchim.hxx>
32 bool SdrTextObj::HasTextEdit() const
34 // linked text objects may be changed (no automatic reload)
38 sal_Bool
SdrTextObj::BegTextEdit(SdrOutliner
& rOutl
)
40 if (pEdtOutl
!=NULL
) return sal_False
; // Textedit might already run in another View!
43 mbInEditMode
= sal_True
;
45 sal_uInt16 nOutlinerMode
= OUTLINERMODE_OUTLINEOBJECT
;
47 nOutlinerMode
= OUTLINERMODE_TEXTOBJECT
;
48 rOutl
.Init( nOutlinerMode
);
49 rOutl
.SetRefDevice( pModel
->GetRefDevice() );
51 bool bFitToSize(IsFitToSize());
52 bool bContourFrame
=IsContourTextFrame();
53 ImpSetTextEditParams();
56 sal_uIntPtr nStat
=rOutl
.GetControlWord();
57 nStat
|=EE_CNTRL_AUTOPAGESIZE
;
58 if (bFitToSize
|| IsAutoFit())
59 nStat
|=EE_CNTRL_STRETCHING
;
61 nStat
&=~EE_CNTRL_STRETCHING
;
62 rOutl
.SetControlWord(nStat
);
65 OutlinerParaObject
* pOutlinerParaObject
= GetOutlinerParaObject();
66 if(pOutlinerParaObject
!=NULL
)
68 rOutl
.SetText(*GetOutlinerParaObject());
69 rOutl
.SetFixedCellHeight(((const SdrTextFixedCellHeightItem
&)GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT
)).GetValue());
72 // if necessary, set frame attributes for the first (new) paragraph of the
74 if( !HasTextImpl( &rOutl
) )
76 // Outliner has no text so we must set some
77 // empty text so the outliner initialise itself
78 rOutl
.SetText( String(), rOutl
.GetParagraph( 0 ) );
81 rOutl
.SetStyleSheet( 0, GetStyleSheet());
83 // When setting the "hard" attributes for first paragraph, the Parent
84 // pOutlAttr (i. e. the template) has to be removed temporarily. Else,
85 // at SetParaAttribs(), all attributes contained in the parent become
86 // attributed hard to the paragraph.
87 const SfxItemSet
& rSet
= GetObjectItemSet();
88 SfxItemSet
aFilteredSet(*rSet
.GetPool(), EE_ITEMS_START
, EE_ITEMS_END
);
89 aFilteredSet
.Put(rSet
);
90 rOutl
.SetParaAttribs(0, aFilteredSet
);
94 Rectangle aAnchorRect
;
96 TakeTextRect(rOutl
, aTextRect
, sal_False
,
98 Fraction
aFitXKorreg(1,1);
99 ImpSetCharStretching(rOutl
,aTextRect
.GetSize(),aAnchorRect
.GetSize(),aFitXKorreg
);
101 else if (IsAutoFit())
103 ImpAutoFitText(rOutl
);
106 if(pOutlinerParaObject
)
108 if(aGeo
.nDrehWink
|| IsFontwork())
110 // only repaint here, no real objectchange
111 BroadcastObjectChange();
115 rOutl
.UpdateFields();
116 rOutl
.ClearModifyFlag();
121 void SdrTextObj::TakeTextEditArea(Size
* pPaperMin
, Size
* pPaperMax
, Rectangle
* pViewInit
, Rectangle
* pViewMin
) const
123 bool bFitToSize(IsFitToSize());
124 Size aPaperMin
,aPaperMax
;
126 TakeTextAnchorRect(aViewInit
);
127 if (aGeo
.nDrehWink
!=0) {
128 Point
aCenter(aViewInit
.Center());
129 aCenter
-=aViewInit
.TopLeft();
130 Point
aCenter0(aCenter
);
131 RotatePoint(aCenter
,Point(),aGeo
.nSin
,aGeo
.nCos
);
133 aViewInit
.Move(aCenter
.X(),aCenter
.Y());
135 Size
aAnkSiz(aViewInit
.GetSize());
136 aAnkSiz
.Width()--; aAnkSiz
.Height()--; // because GetSize() adds 1
137 Size
aMaxSiz(1000000,1000000);
139 Size
aTmpSiz(pModel
->GetMaxObjSize());
140 if (aTmpSiz
.Width()!=0) aMaxSiz
.Width()=aTmpSiz
.Width();
141 if (aTmpSiz
.Height()!=0) aMaxSiz
.Height()=aTmpSiz
.Height();
144 // Done earlier since used in else tree below
145 SdrTextHorzAdjust
eHAdj(GetTextHorizontalAdjust());
146 SdrTextVertAdjust
eVAdj(GetTextVerticalAdjust());
150 long nMinWdt
=GetMinTextFrameWidth();
151 long nMinHgt
=GetMinTextFrameHeight();
152 long nMaxWdt
=GetMaxTextFrameWidth();
153 long nMaxHgt
=GetMaxTextFrameHeight();
154 if (nMinWdt
<1) nMinWdt
=1;
155 if (nMinHgt
<1) nMinHgt
=1;
157 if (nMaxWdt
==0 || nMaxWdt
>aMaxSiz
.Width()) nMaxWdt
=aMaxSiz
.Width();
158 if (nMaxHgt
==0 || nMaxHgt
>aMaxSiz
.Height()) nMaxHgt
=aMaxSiz
.Height();
160 if (!IsAutoGrowWidth() )
162 nMinWdt
= aAnkSiz
.Width();
166 if (!IsAutoGrowHeight())
168 nMinHgt
= aAnkSiz
.Height();
172 SdrTextAniKind eAniKind
=GetTextAniKind();
173 SdrTextAniDirection eAniDirection
=GetTextAniDirection();
175 sal_Bool bInEditMode
= IsInEditMode();
177 if (!bInEditMode
&& (eAniKind
==SDRTEXTANI_SCROLL
|| eAniKind
==SDRTEXTANI_ALTERNATE
|| eAniKind
==SDRTEXTANI_SLIDE
))
179 // ticker text uses an unlimited paper size
180 if (eAniDirection
==SDRTEXTANI_LEFT
|| eAniDirection
==SDRTEXTANI_RIGHT
) nMaxWdt
=1000000;
181 if (eAniDirection
==SDRTEXTANI_UP
|| eAniDirection
==SDRTEXTANI_DOWN
) nMaxHgt
=1000000;
184 // #i119885# Do not limit/force height to geometrical frame (vice versa for vertical writing)
185 if(IsVerticalWriting())
194 aPaperMax
.Width()=nMaxWdt
;
195 aPaperMax
.Height()=nMaxHgt
;
201 aPaperMin
.Width()=nMinWdt
;
202 aPaperMin
.Height()=nMinHgt
;
206 // aPaperMin needs to be set to object's size if full width is activated
207 // for hor or ver writing respectively
208 if((SDRTEXTHORZADJUST_BLOCK
== eHAdj
&& !IsVerticalWriting())
209 || (SDRTEXTVERTADJUST_BLOCK
== eVAdj
&& IsVerticalWriting()))
217 if (pViewMin
!=NULL
) {
220 long nXFree
=aAnkSiz
.Width()-aPaperMin
.Width();
221 if (eHAdj
==SDRTEXTHORZADJUST_LEFT
) pViewMin
->Right()-=nXFree
;
222 else if (eHAdj
==SDRTEXTHORZADJUST_RIGHT
) pViewMin
->Left()+=nXFree
;
223 else { pViewMin
->Left()+=nXFree
/2; pViewMin
->Right()=pViewMin
->Left()+aPaperMin
.Width(); }
225 long nYFree
=aAnkSiz
.Height()-aPaperMin
.Height();
226 if (eVAdj
==SDRTEXTVERTADJUST_TOP
) pViewMin
->Bottom()-=nYFree
;
227 else if (eVAdj
==SDRTEXTVERTADJUST_BOTTOM
) pViewMin
->Top()+=nYFree
;
228 else { pViewMin
->Top()+=nYFree
/2; pViewMin
->Bottom()=pViewMin
->Top()+aPaperMin
.Height(); }
231 // PaperSize should grow automatically in most cases
232 if(IsVerticalWriting())
233 aPaperMin
.Width() = 0;
235 aPaperMin
.Height() = 0;
237 if(eHAdj
!=SDRTEXTHORZADJUST_BLOCK
|| bFitToSize
) {
241 // For complete vertical adjustment support, set paper min height to 0, here.
242 if(SDRTEXTVERTADJUST_BLOCK
!= eVAdj
|| bFitToSize
)
244 aPaperMin
.Height() = 0;
247 if (pPaperMin
!=NULL
) *pPaperMin
=aPaperMin
;
248 if (pPaperMax
!=NULL
) *pPaperMax
=aPaperMax
;
249 if (pViewInit
!=NULL
) *pViewInit
=aViewInit
;
252 void SdrTextObj::EndTextEdit(SdrOutliner
& rOutl
)
254 if(rOutl
.IsModified())
256 OutlinerParaObject
* pNewText
= NULL
;
258 // to make the gray field background vanish again
259 rOutl
.UpdateFields();
261 sal_Int32 nParaAnz
= rOutl
.GetParagraphCount();
262 pNewText
= rOutl
.CreateParaObject( 0, nParaAnz
);
264 // need to end edit mode early since SetOutlinerParaObject already
265 // uses GetCurrentBoundRect() which needs to take the text into account
267 mbInEditMode
= sal_False
;
268 SetOutlinerParaObject(pNewText
);
273 sal_uInt32 nStat
= rOutl
.GetControlWord();
274 nStat
&= ~EE_CNTRL_AUTOPAGESIZE
;
275 rOutl
.SetControlWord(nStat
);
277 mbInEditMode
= sal_False
;
280 sal_uInt16
SdrTextObj::GetOutlinerViewAnchorMode() const
282 SdrTextHorzAdjust eH
=GetTextHorizontalAdjust();
283 SdrTextVertAdjust eV
=GetTextVerticalAdjust();
284 EVAnchorMode eRet
=ANCHOR_TOP_LEFT
;
285 if (IsContourTextFrame()) return (sal_uInt16
)eRet
;
286 if (eH
==SDRTEXTHORZADJUST_LEFT
) {
287 if (eV
==SDRTEXTVERTADJUST_TOP
) {
288 eRet
=ANCHOR_TOP_LEFT
;
289 } else if (eV
==SDRTEXTVERTADJUST_BOTTOM
) {
290 eRet
=ANCHOR_BOTTOM_LEFT
;
292 eRet
=ANCHOR_VCENTER_LEFT
;
294 } else if (eH
==SDRTEXTHORZADJUST_RIGHT
) {
295 if (eV
==SDRTEXTVERTADJUST_TOP
) {
296 eRet
=ANCHOR_TOP_RIGHT
;
297 } else if (eV
==SDRTEXTVERTADJUST_BOTTOM
) {
298 eRet
=ANCHOR_BOTTOM_RIGHT
;
300 eRet
=ANCHOR_VCENTER_RIGHT
;
303 if (eV
==SDRTEXTVERTADJUST_TOP
) {
304 eRet
=ANCHOR_TOP_HCENTER
;
305 } else if (eV
==SDRTEXTVERTADJUST_BOTTOM
) {
306 eRet
=ANCHOR_BOTTOM_HCENTER
;
308 eRet
=ANCHOR_VCENTER_HCENTER
;
311 return (sal_uInt16
)eRet
;
314 void SdrTextObj::ImpSetTextEditParams() const
316 if (pEdtOutl
!=NULL
) {
317 bool bUpdMerk
=pEdtOutl
->GetUpdateMode();
318 if (bUpdMerk
) pEdtOutl
->SetUpdateMode(sal_False
);
322 TakeTextEditArea(&aPaperMin
,&aPaperMax
,&aEditArea
,NULL
);
323 bool bContourFrame
=IsContourTextFrame();
324 pEdtOutl
->SetMinAutoPaperSize(aPaperMin
);
325 pEdtOutl
->SetMaxAutoPaperSize(aPaperMax
);
326 pEdtOutl
->SetPaperSize(Size());
328 Rectangle aAnchorRect
;
329 TakeTextAnchorRect(aAnchorRect
);
330 ImpSetContourPolygon(*pEdtOutl
,aAnchorRect
, sal_True
);
332 if (bUpdMerk
) pEdtOutl
->SetUpdateMode(sal_True
);
336 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */