Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 :
21 : #include <svx/svdotext.hxx>
22 : #include <svx/svdmodel.hxx>
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>
30 :
31 :
32 6 : bool SdrTextObj::HasTextEdit() const
33 : {
34 : // linked text objects may be changed (no automatic reload)
35 6 : return true;
36 : }
37 :
38 9 : bool SdrTextObj::BegTextEdit(SdrOutliner& rOutl)
39 : {
40 9 : if (pEdtOutl!=NULL) return false; // Textedit might already run in another View!
41 9 : pEdtOutl=&rOutl;
42 :
43 9 : mbInEditMode = true;
44 :
45 9 : sal_uInt16 nOutlinerMode = OUTLINERMODE_OUTLINEOBJECT;
46 9 : if ( !IsOutlText() )
47 2 : nOutlinerMode = OUTLINERMODE_TEXTOBJECT;
48 9 : rOutl.Init( nOutlinerMode );
49 9 : rOutl.SetRefDevice( pModel->GetRefDevice() );
50 :
51 9 : bool bFitToSize(IsFitToSize());
52 9 : bool bContourFrame=IsContourTextFrame();
53 9 : ImpSetTextEditParams();
54 :
55 9 : if (!bContourFrame) {
56 9 : EEControlBits nStat=rOutl.GetControlWord();
57 9 : nStat|=EEControlBits::AUTOPAGESIZE;
58 9 : if (bFitToSize || IsAutoFit())
59 1 : nStat|=EEControlBits::STRETCHING;
60 : else
61 8 : nStat&=~EEControlBits::STRETCHING;
62 9 : rOutl.SetControlWord(nStat);
63 : }
64 :
65 9 : OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
66 9 : if(pOutlinerParaObject!=NULL)
67 : {
68 9 : rOutl.SetText(*GetOutlinerParaObject());
69 9 : rOutl.SetFixedCellHeight(static_cast<const SdrTextFixedCellHeightItem&>(GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue());
70 : }
71 :
72 : // if necessary, set frame attributes for the first (new) paragraph of the
73 : // outliner
74 9 : if( !HasTextImpl( &rOutl ) )
75 : {
76 : // Outliner has no text so we must set some
77 : // empty text so the outliner initialise itself
78 0 : rOutl.SetText( "", rOutl.GetParagraph( 0 ) );
79 :
80 0 : if(GetStyleSheet())
81 0 : rOutl.SetStyleSheet( 0, GetStyleSheet());
82 :
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 0 : const SfxItemSet& rSet = GetObjectItemSet();
88 0 : SfxItemSet aFilteredSet(*rSet.GetPool(), EE_ITEMS_START, EE_ITEMS_END);
89 0 : aFilteredSet.Put(rSet);
90 0 : rOutl.SetParaAttribs(0, aFilteredSet);
91 : }
92 9 : if (bFitToSize)
93 : {
94 0 : Rectangle aAnchorRect;
95 0 : Rectangle aTextRect;
96 : TakeTextRect(rOutl, aTextRect, false,
97 0 : &aAnchorRect);
98 0 : Fraction aFitXKorreg(1,1);
99 0 : ImpSetCharStretching(rOutl,aTextRect.GetSize(),aAnchorRect.GetSize(),aFitXKorreg);
100 : }
101 9 : else if (IsAutoFit())
102 : {
103 1 : ImpAutoFitText(rOutl);
104 : }
105 :
106 9 : if(pOutlinerParaObject)
107 : {
108 9 : if(aGeo.nRotationAngle || IsFontwork())
109 : {
110 : // only repaint here, no real objectchange
111 0 : BroadcastObjectChange();
112 : }
113 : }
114 :
115 9 : rOutl.UpdateFields();
116 9 : rOutl.ClearModifyFlag();
117 :
118 9 : return true;
119 : }
120 :
121 18 : void SdrTextObj::TakeTextEditArea(Size* pPaperMin, Size* pPaperMax, Rectangle* pViewInit, Rectangle* pViewMin) const
122 : {
123 18 : bool bFitToSize(IsFitToSize());
124 18 : Size aPaperMin,aPaperMax;
125 18 : Rectangle aViewInit;
126 18 : TakeTextAnchorRect(aViewInit);
127 18 : if (aGeo.nRotationAngle!=0) {
128 0 : Point aCenter(aViewInit.Center());
129 0 : aCenter-=aViewInit.TopLeft();
130 0 : Point aCenter0(aCenter);
131 0 : RotatePoint(aCenter,Point(),aGeo.nSin,aGeo.nCos);
132 0 : aCenter-=aCenter0;
133 0 : aViewInit.Move(aCenter.X(),aCenter.Y());
134 : }
135 18 : Size aAnkSiz(aViewInit.GetSize());
136 18 : aAnkSiz.Width()--; aAnkSiz.Height()--; // because GetSize() adds 1
137 18 : Size aMaxSiz(1000000,1000000);
138 18 : if (pModel!=NULL) {
139 18 : Size aTmpSiz(pModel->GetMaxObjSize());
140 18 : if (aTmpSiz.Width()!=0) aMaxSiz.Width()=aTmpSiz.Width();
141 18 : if (aTmpSiz.Height()!=0) aMaxSiz.Height()=aTmpSiz.Height();
142 : }
143 :
144 : // Done earlier since used in else tree below
145 18 : SdrTextHorzAdjust eHAdj(GetTextHorizontalAdjust());
146 18 : SdrTextVertAdjust eVAdj(GetTextVerticalAdjust());
147 :
148 18 : if(IsTextFrame())
149 : {
150 14 : long nMinWdt=GetMinTextFrameWidth();
151 14 : long nMinHgt=GetMinTextFrameHeight();
152 14 : long nMaxWdt=GetMaxTextFrameWidth();
153 14 : long nMaxHgt=GetMaxTextFrameHeight();
154 14 : if (nMinWdt<1) nMinWdt=1;
155 14 : if (nMinHgt<1) nMinHgt=1;
156 14 : if (!bFitToSize) {
157 14 : if (nMaxWdt==0 || nMaxWdt>aMaxSiz.Width()) nMaxWdt=aMaxSiz.Width();
158 14 : if (nMaxHgt==0 || nMaxHgt>aMaxSiz.Height()) nMaxHgt=aMaxSiz.Height();
159 :
160 14 : if (!IsAutoGrowWidth() )
161 : {
162 14 : nMinWdt = aAnkSiz.Width();
163 14 : nMaxWdt = nMinWdt;
164 : }
165 :
166 14 : if (!IsAutoGrowHeight())
167 : {
168 2 : nMinHgt = aAnkSiz.Height();
169 2 : nMaxHgt = nMinHgt;
170 : }
171 :
172 14 : SdrTextAniKind eAniKind=GetTextAniKind();
173 14 : SdrTextAniDirection eAniDirection=GetTextAniDirection();
174 :
175 14 : bool bInEditMode = IsInEditMode();
176 :
177 14 : if (!bInEditMode && (eAniKind==SDRTEXTANI_SCROLL || eAniKind==SDRTEXTANI_ALTERNATE || eAniKind==SDRTEXTANI_SLIDE))
178 : {
179 : // ticker text uses an unlimited paper size
180 0 : if (eAniDirection==SDRTEXTANI_LEFT || eAniDirection==SDRTEXTANI_RIGHT) nMaxWdt=1000000;
181 0 : if (eAniDirection==SDRTEXTANI_UP || eAniDirection==SDRTEXTANI_DOWN) nMaxHgt=1000000;
182 : }
183 :
184 : // #i119885# Do not limit/force height to geometrical frame (vice versa for vertical writing)
185 14 : if(IsVerticalWriting())
186 : {
187 0 : nMaxWdt = 1000000;
188 : }
189 : else
190 : {
191 14 : nMaxHgt = 1000000;
192 : }
193 :
194 14 : aPaperMax.Width()=nMaxWdt;
195 14 : aPaperMax.Height()=nMaxHgt;
196 : }
197 : else
198 : {
199 0 : aPaperMax=aMaxSiz;
200 : }
201 14 : aPaperMin.Width()=nMinWdt;
202 14 : aPaperMin.Height()=nMinHgt;
203 : }
204 : else
205 : {
206 : // aPaperMin needs to be set to object's size if full width is activated
207 : // for hor or ver writing respectively
208 4 : if((SDRTEXTHORZADJUST_BLOCK == eHAdj && !IsVerticalWriting())
209 8 : || (SDRTEXTVERTADJUST_BLOCK == eVAdj && IsVerticalWriting()))
210 : {
211 0 : aPaperMin = aAnkSiz;
212 : }
213 :
214 4 : aPaperMax=aMaxSiz;
215 : }
216 :
217 18 : if (pViewMin!=NULL) {
218 9 : *pViewMin=aViewInit;
219 :
220 9 : long nXFree=aAnkSiz.Width()-aPaperMin.Width();
221 9 : if (eHAdj==SDRTEXTHORZADJUST_LEFT) pViewMin->Right()-=nXFree;
222 9 : else if (eHAdj==SDRTEXTHORZADJUST_RIGHT) pViewMin->Left()+=nXFree;
223 9 : else { pViewMin->Left()+=nXFree/2; pViewMin->Right()=pViewMin->Left()+aPaperMin.Width(); }
224 :
225 9 : long nYFree=aAnkSiz.Height()-aPaperMin.Height();
226 9 : if (eVAdj==SDRTEXTVERTADJUST_TOP) pViewMin->Bottom()-=nYFree;
227 8 : else if (eVAdj==SDRTEXTVERTADJUST_BOTTOM) pViewMin->Top()+=nYFree;
228 8 : else { pViewMin->Top()+=nYFree/2; pViewMin->Bottom()=pViewMin->Top()+aPaperMin.Height(); }
229 : }
230 :
231 : // PaperSize should grow automatically in most cases
232 18 : if(IsVerticalWriting())
233 0 : aPaperMin.Width() = 0;
234 : else
235 18 : aPaperMin.Height() = 0;
236 :
237 18 : if(eHAdj!=SDRTEXTHORZADJUST_BLOCK || bFitToSize) {
238 4 : aPaperMin.Width()=0;
239 : }
240 :
241 : // For complete vertical adjustment support, set paper min height to 0, here.
242 18 : if(SDRTEXTVERTADJUST_BLOCK != eVAdj || bFitToSize)
243 : {
244 18 : aPaperMin.Height() = 0;
245 : }
246 :
247 18 : if (pPaperMin!=NULL) *pPaperMin=aPaperMin;
248 18 : if (pPaperMax!=NULL) *pPaperMax=aPaperMax;
249 18 : if (pViewInit!=NULL) *pViewInit=aViewInit;
250 18 : }
251 :
252 9 : void SdrTextObj::EndTextEdit(SdrOutliner& rOutl)
253 : {
254 9 : if(rOutl.IsModified())
255 : {
256 2 : OutlinerParaObject* pNewText = NULL;
257 :
258 : // to make the gray field background vanish again
259 2 : rOutl.UpdateFields();
260 :
261 2 : sal_Int32 nParaAnz = rOutl.GetParagraphCount();
262 2 : pNewText = rOutl.CreateParaObject( 0, nParaAnz );
263 :
264 : // need to end edit mode early since SetOutlinerParaObject already
265 : // uses GetCurrentBoundRect() which needs to take the text into account
266 : // to work correct
267 2 : mbInEditMode = false;
268 2 : SetOutlinerParaObject(pNewText);
269 : }
270 :
271 9 : pEdtOutl = NULL;
272 9 : rOutl.Clear();
273 9 : EEControlBits nStat = rOutl.GetControlWord();
274 9 : nStat &= ~EEControlBits::AUTOPAGESIZE;
275 9 : rOutl.SetControlWord(nStat);
276 :
277 9 : mbInEditMode = false;
278 9 : }
279 :
280 9 : sal_uInt16 SdrTextObj::GetOutlinerViewAnchorMode() const
281 : {
282 9 : SdrTextHorzAdjust eH=GetTextHorizontalAdjust();
283 9 : SdrTextVertAdjust eV=GetTextVerticalAdjust();
284 9 : EVAnchorMode eRet=ANCHOR_TOP_LEFT;
285 9 : if (IsContourTextFrame()) return (sal_uInt16)eRet;
286 9 : if (eH==SDRTEXTHORZADJUST_LEFT) {
287 0 : if (eV==SDRTEXTVERTADJUST_TOP) {
288 0 : eRet=ANCHOR_TOP_LEFT;
289 0 : } else if (eV==SDRTEXTVERTADJUST_BOTTOM) {
290 0 : eRet=ANCHOR_BOTTOM_LEFT;
291 : } else {
292 0 : eRet=ANCHOR_VCENTER_LEFT;
293 : }
294 9 : } else if (eH==SDRTEXTHORZADJUST_RIGHT) {
295 0 : if (eV==SDRTEXTVERTADJUST_TOP) {
296 0 : eRet=ANCHOR_TOP_RIGHT;
297 0 : } else if (eV==SDRTEXTVERTADJUST_BOTTOM) {
298 0 : eRet=ANCHOR_BOTTOM_RIGHT;
299 : } else {
300 0 : eRet=ANCHOR_VCENTER_RIGHT;
301 : }
302 : } else {
303 9 : if (eV==SDRTEXTVERTADJUST_TOP) {
304 1 : eRet=ANCHOR_TOP_HCENTER;
305 8 : } else if (eV==SDRTEXTVERTADJUST_BOTTOM) {
306 0 : eRet=ANCHOR_BOTTOM_HCENTER;
307 : } else {
308 8 : eRet=ANCHOR_VCENTER_HCENTER;
309 : }
310 : }
311 9 : return (sal_uInt16)eRet;
312 : }
313 :
314 9 : void SdrTextObj::ImpSetTextEditParams() const
315 : {
316 9 : if (pEdtOutl!=NULL) {
317 9 : bool bUpdMerk=pEdtOutl->GetUpdateMode();
318 9 : if (bUpdMerk) pEdtOutl->SetUpdateMode(false);
319 9 : Size aPaperMin;
320 9 : Size aPaperMax;
321 9 : Rectangle aEditArea;
322 9 : TakeTextEditArea(&aPaperMin,&aPaperMax,&aEditArea,NULL);
323 9 : bool bContourFrame=IsContourTextFrame();
324 9 : pEdtOutl->SetMinAutoPaperSize(aPaperMin);
325 9 : pEdtOutl->SetMaxAutoPaperSize(aPaperMax);
326 9 : pEdtOutl->SetPaperSize(Size());
327 9 : if (bContourFrame) {
328 0 : Rectangle aAnchorRect;
329 0 : TakeTextAnchorRect(aAnchorRect);
330 0 : ImpSetContourPolygon(*pEdtOutl,aAnchorRect, true);
331 : }
332 9 : if (bUpdMerk) pEdtOutl->SetUpdateMode(true);
333 : }
334 444 : }
335 :
336 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|