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/svditext.hxx"
23 : #include <svx/svdmodel.hxx> // for GetMaxObjSize
24 : #include <svx/svdoutl.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 0 : bool SdrTextObj::HasTextEdit() const
33 : {
34 : // linked text objects may be changed (no automatic reload)
35 0 : return true;
36 : }
37 :
38 0 : sal_Bool SdrTextObj::BegTextEdit(SdrOutliner& rOutl)
39 : {
40 0 : if (pEdtOutl!=NULL) return sal_False; // Textedit might already run in another View!
41 0 : pEdtOutl=&rOutl;
42 :
43 0 : mbInEditMode = sal_True;
44 :
45 0 : sal_uInt16 nOutlinerMode = OUTLINERMODE_OUTLINEOBJECT;
46 0 : if ( !IsOutlText() )
47 0 : nOutlinerMode = OUTLINERMODE_TEXTOBJECT;
48 0 : rOutl.Init( nOutlinerMode );
49 0 : rOutl.SetRefDevice( pModel->GetRefDevice() );
50 :
51 0 : bool bFitToSize(IsFitToSize());
52 0 : bool bContourFrame=IsContourTextFrame();
53 0 : ImpSetTextEditParams();
54 :
55 0 : if (!bContourFrame) {
56 0 : sal_uIntPtr nStat=rOutl.GetControlWord();
57 0 : nStat|=EE_CNTRL_AUTOPAGESIZE;
58 0 : if (bFitToSize || IsAutoFit())
59 0 : nStat|=EE_CNTRL_STRETCHING;
60 : else
61 0 : nStat&=~EE_CNTRL_STRETCHING;
62 0 : rOutl.SetControlWord(nStat);
63 : }
64 :
65 0 : OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
66 0 : if(pOutlinerParaObject!=NULL)
67 : {
68 0 : rOutl.SetText(*GetOutlinerParaObject());
69 0 : rOutl.SetFixedCellHeight(((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 0 : 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( String(), 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 0 : if (bFitToSize)
93 : {
94 0 : Rectangle aAnchorRect;
95 0 : Rectangle aTextRect;
96 : TakeTextRect(rOutl, aTextRect, sal_False,
97 0 : &aAnchorRect);
98 0 : Fraction aFitXKorreg(1,1);
99 0 : ImpSetCharStretching(rOutl,aTextRect.GetSize(),aAnchorRect.GetSize(),aFitXKorreg);
100 : }
101 0 : else if (IsAutoFit())
102 : {
103 0 : ImpAutoFitText(rOutl);
104 : }
105 :
106 0 : if(pOutlinerParaObject)
107 : {
108 0 : if(aGeo.nDrehWink || IsFontwork())
109 : {
110 : // only repaint here, no real objectchange
111 0 : BroadcastObjectChange();
112 : }
113 : }
114 :
115 0 : rOutl.UpdateFields();
116 0 : rOutl.ClearModifyFlag();
117 :
118 0 : return sal_True;
119 : }
120 :
121 0 : void SdrTextObj::TakeTextEditArea(Size* pPaperMin, Size* pPaperMax, Rectangle* pViewInit, Rectangle* pViewMin) const
122 : {
123 0 : bool bFitToSize(IsFitToSize());
124 0 : Size aPaperMin,aPaperMax;
125 0 : Rectangle aViewInit;
126 0 : TakeTextAnchorRect(aViewInit);
127 0 : if (aGeo.nDrehWink!=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 0 : Size aAnkSiz(aViewInit.GetSize());
136 0 : aAnkSiz.Width()--; aAnkSiz.Height()--; // because GetSize() adds 1
137 0 : Size aMaxSiz(1000000,1000000);
138 0 : if (pModel!=NULL) {
139 0 : Size aTmpSiz(pModel->GetMaxObjSize());
140 0 : if (aTmpSiz.Width()!=0) aMaxSiz.Width()=aTmpSiz.Width();
141 0 : if (aTmpSiz.Height()!=0) aMaxSiz.Height()=aTmpSiz.Height();
142 : }
143 :
144 : // Done earlier since used in else tree below
145 0 : SdrTextHorzAdjust eHAdj(GetTextHorizontalAdjust());
146 0 : SdrTextVertAdjust eVAdj(GetTextVerticalAdjust());
147 :
148 0 : if(IsTextFrame())
149 : {
150 0 : long nMinWdt=GetMinTextFrameWidth();
151 0 : long nMinHgt=GetMinTextFrameHeight();
152 0 : long nMaxWdt=GetMaxTextFrameWidth();
153 0 : long nMaxHgt=GetMaxTextFrameHeight();
154 0 : if (nMinWdt<1) nMinWdt=1;
155 0 : if (nMinHgt<1) nMinHgt=1;
156 0 : if (!bFitToSize) {
157 0 : if (nMaxWdt==0 || nMaxWdt>aMaxSiz.Width()) nMaxWdt=aMaxSiz.Width();
158 0 : if (nMaxHgt==0 || nMaxHgt>aMaxSiz.Height()) nMaxHgt=aMaxSiz.Height();
159 0 : if (!IsAutoGrowWidth() ) { nMaxWdt=aAnkSiz.Width(); nMinWdt=nMaxWdt; }
160 0 : if (!IsAutoGrowHeight()) { nMaxHgt=aAnkSiz.Height(); nMinHgt=nMaxHgt; }
161 0 : SdrTextAniKind eAniKind=GetTextAniKind();
162 0 : SdrTextAniDirection eAniDirection=GetTextAniDirection();
163 :
164 0 : sal_Bool bInEditMode = IsInEditMode();
165 :
166 0 : if (!bInEditMode && (eAniKind==SDRTEXTANI_SCROLL || eAniKind==SDRTEXTANI_ALTERNATE || eAniKind==SDRTEXTANI_SLIDE))
167 : {
168 : // ticker text uses an unlimited paper size
169 0 : if (eAniDirection==SDRTEXTANI_LEFT || eAniDirection==SDRTEXTANI_RIGHT) nMaxWdt=1000000;
170 0 : if (eAniDirection==SDRTEXTANI_UP || eAniDirection==SDRTEXTANI_DOWN) nMaxHgt=1000000;
171 : }
172 0 : aPaperMax.Width()=nMaxWdt;
173 0 : aPaperMax.Height()=nMaxHgt;
174 : } else {
175 0 : aPaperMax=aMaxSiz;
176 : }
177 0 : aPaperMin.Width()=nMinWdt;
178 0 : aPaperMin.Height()=nMinHgt;
179 : }
180 : else
181 : {
182 : // aPaperMin needs to be set to object's size if full width is activated
183 : // for hor or ver writing respectively
184 0 : if((SDRTEXTHORZADJUST_BLOCK == eHAdj && !IsVerticalWriting())
185 0 : || (SDRTEXTVERTADJUST_BLOCK == eVAdj && IsVerticalWriting()))
186 : {
187 0 : aPaperMin = aAnkSiz;
188 : }
189 :
190 0 : aPaperMax=aMaxSiz;
191 : }
192 :
193 0 : if (pViewMin!=NULL) {
194 0 : *pViewMin=aViewInit;
195 :
196 0 : long nXFree=aAnkSiz.Width()-aPaperMin.Width();
197 0 : if (eHAdj==SDRTEXTHORZADJUST_LEFT) pViewMin->Right()-=nXFree;
198 0 : else if (eHAdj==SDRTEXTHORZADJUST_RIGHT) pViewMin->Left()+=nXFree;
199 0 : else { pViewMin->Left()+=nXFree/2; pViewMin->Right()=pViewMin->Left()+aPaperMin.Width(); }
200 :
201 0 : long nYFree=aAnkSiz.Height()-aPaperMin.Height();
202 0 : if (eVAdj==SDRTEXTVERTADJUST_TOP) pViewMin->Bottom()-=nYFree;
203 0 : else if (eVAdj==SDRTEXTVERTADJUST_BOTTOM) pViewMin->Top()+=nYFree;
204 0 : else { pViewMin->Top()+=nYFree/2; pViewMin->Bottom()=pViewMin->Top()+aPaperMin.Height(); }
205 : }
206 :
207 : // PaperSize should grow automatically in most cases
208 0 : if(IsVerticalWriting())
209 0 : aPaperMin.Width() = 0;
210 : else
211 0 : aPaperMin.Height() = 0;
212 :
213 0 : if(eHAdj!=SDRTEXTHORZADJUST_BLOCK || bFitToSize) {
214 0 : aPaperMin.Width()=0;
215 : }
216 :
217 : // For complete vertical adjustment support, set paper min height to 0, here.
218 0 : if(SDRTEXTVERTADJUST_BLOCK != eVAdj || bFitToSize)
219 : {
220 0 : aPaperMin.Height() = 0;
221 : }
222 :
223 0 : if (pPaperMin!=NULL) *pPaperMin=aPaperMin;
224 0 : if (pPaperMax!=NULL) *pPaperMax=aPaperMax;
225 0 : if (pViewInit!=NULL) *pViewInit=aViewInit;
226 0 : }
227 :
228 0 : void SdrTextObj::EndTextEdit(SdrOutliner& rOutl)
229 : {
230 0 : if(rOutl.IsModified())
231 : {
232 0 : OutlinerParaObject* pNewText = NULL;
233 :
234 0 : if(HasTextImpl( &rOutl ) )
235 : {
236 : // to make the gray field background vanish again
237 0 : rOutl.UpdateFields();
238 :
239 0 : sal_uInt16 nParaAnz = static_cast< sal_uInt16 >( rOutl.GetParagraphCount() );
240 0 : pNewText = rOutl.CreateParaObject( 0, nParaAnz );
241 : }
242 :
243 : // need to end edit mode early since SetOutlinerParaObject already
244 : // uses GetCurrentBoundRect() which needs to take the text into account
245 : // to work correct
246 0 : mbInEditMode = sal_False;
247 0 : SetOutlinerParaObject(pNewText);
248 : }
249 :
250 0 : pEdtOutl = NULL;
251 0 : rOutl.Clear();
252 0 : sal_uInt32 nStat = rOutl.GetControlWord();
253 0 : nStat &= ~EE_CNTRL_AUTOPAGESIZE;
254 0 : rOutl.SetControlWord(nStat);
255 :
256 0 : mbInEditMode = sal_False;
257 0 : }
258 :
259 0 : sal_uInt16 SdrTextObj::GetOutlinerViewAnchorMode() const
260 : {
261 0 : SdrTextHorzAdjust eH=GetTextHorizontalAdjust();
262 0 : SdrTextVertAdjust eV=GetTextVerticalAdjust();
263 0 : EVAnchorMode eRet=ANCHOR_TOP_LEFT;
264 0 : if (IsContourTextFrame()) return (sal_uInt16)eRet;
265 0 : if (eH==SDRTEXTHORZADJUST_LEFT) {
266 0 : if (eV==SDRTEXTVERTADJUST_TOP) {
267 0 : eRet=ANCHOR_TOP_LEFT;
268 0 : } else if (eV==SDRTEXTVERTADJUST_BOTTOM) {
269 0 : eRet=ANCHOR_BOTTOM_LEFT;
270 : } else {
271 0 : eRet=ANCHOR_VCENTER_LEFT;
272 : }
273 0 : } else if (eH==SDRTEXTHORZADJUST_RIGHT) {
274 0 : if (eV==SDRTEXTVERTADJUST_TOP) {
275 0 : eRet=ANCHOR_TOP_RIGHT;
276 0 : } else if (eV==SDRTEXTVERTADJUST_BOTTOM) {
277 0 : eRet=ANCHOR_BOTTOM_RIGHT;
278 : } else {
279 0 : eRet=ANCHOR_VCENTER_RIGHT;
280 : }
281 : } else {
282 0 : if (eV==SDRTEXTVERTADJUST_TOP) {
283 0 : eRet=ANCHOR_TOP_HCENTER;
284 0 : } else if (eV==SDRTEXTVERTADJUST_BOTTOM) {
285 0 : eRet=ANCHOR_BOTTOM_HCENTER;
286 : } else {
287 0 : eRet=ANCHOR_VCENTER_HCENTER;
288 : }
289 : }
290 0 : return (sal_uInt16)eRet;
291 : }
292 :
293 0 : void SdrTextObj::ImpSetTextEditParams() const
294 : {
295 0 : if (pEdtOutl!=NULL) {
296 0 : bool bUpdMerk=pEdtOutl->GetUpdateMode();
297 0 : if (bUpdMerk) pEdtOutl->SetUpdateMode(sal_False);
298 0 : Size aPaperMin;
299 0 : Size aPaperMax;
300 0 : Rectangle aEditArea;
301 0 : TakeTextEditArea(&aPaperMin,&aPaperMax,&aEditArea,NULL);
302 0 : bool bContourFrame=IsContourTextFrame();
303 0 : pEdtOutl->SetMinAutoPaperSize(aPaperMin);
304 0 : pEdtOutl->SetMaxAutoPaperSize(aPaperMax);
305 0 : pEdtOutl->SetPaperSize(Size());
306 0 : if (bContourFrame) {
307 0 : Rectangle aAnchorRect;
308 0 : TakeTextAnchorRect(aAnchorRect);
309 0 : ImpSetContourPolygon(*pEdtOutl,aAnchorRect, sal_True);
310 : }
311 0 : if (bUpdMerk) pEdtOutl->SetUpdateMode(sal_True);
312 : }
313 0 : }
314 :
315 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|