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 : #include "cellform.hxx"
21 :
22 : #include <sfx2/objsh.hxx>
23 : #include <svl/smplhint.hxx>
24 : #include <svl/zforlist.hxx>
25 : #include <svl/sharedstring.hxx>
26 :
27 : #include "formulacell.hxx"
28 : #include "document.hxx"
29 : #include "cellvalue.hxx"
30 : #include <formula/errorcodes.hxx>
31 : #include "sc.hrc"
32 : #include <editutil.hxx>
33 :
34 : // STATIC DATA
35 : // Err527 Workaround
36 : const ScFormulaCell* pLastFormulaTreeTop = 0;
37 :
38 71292 : void ScCellFormat::GetString( ScRefCellValue& rCell, sal_uLong nFormat, OUString& rString,
39 : Color** ppColor, SvNumberFormatter& rFormatter, const ScDocument* pDoc,
40 : bool bNullVals, bool bFormula, ScForceTextFmt eForceTextFmt,
41 : bool bUseStarFormat )
42 : {
43 71292 : *ppColor = NULL;
44 :
45 71292 : switch (rCell.meType)
46 : {
47 : case CELLTYPE_STRING:
48 20927 : rFormatter.GetOutputString(rCell.mpString->getString(), nFormat, rString, ppColor, bUseStarFormat);
49 20927 : break;
50 : case CELLTYPE_EDIT:
51 212 : rFormatter.GetOutputString(rCell.getString(pDoc), nFormat, rString, ppColor );
52 212 : break;
53 : case CELLTYPE_VALUE:
54 : {
55 43966 : double nValue = rCell.mfValue;
56 43966 : if (!bNullVals && nValue == 0.0)
57 0 : rString.clear();
58 : else
59 : {
60 43966 : if( eForceTextFmt == ftCheck )
61 : {
62 13919 : if( nFormat && rFormatter.IsTextFormat( nFormat ) )
63 109 : eForceTextFmt = ftForce;
64 : }
65 43966 : if( eForceTextFmt == ftForce )
66 : {
67 109 : OUString aTemp;
68 109 : rFormatter.GetOutputString( nValue, 0, aTemp, ppColor );
69 109 : rFormatter.GetOutputString( aTemp, nFormat, rString, ppColor );
70 : }
71 : else
72 43857 : rFormatter.GetOutputString( nValue, nFormat, rString, ppColor, bUseStarFormat );
73 : }
74 : }
75 43966 : break;
76 : case CELLTYPE_FORMULA:
77 : {
78 2911 : ScFormulaCell* pFCell = rCell.mpFormula;
79 2911 : if ( bFormula )
80 : {
81 0 : pFCell->GetFormula( rString );
82 : }
83 : else
84 : {
85 : // A macro started from the interpreter, which has
86 : // access to Formular Cells, becomes a CellText, even if
87 : // that triggers further interpretation, except if those
88 : // cells are already being interpreted.
89 : // IdleCalc generally doesn't trigger further interpretation,
90 : // as not to get Err522 (circular).
91 2911 : if ( pFCell->GetDocument()->IsInInterpreter() &&
92 0 : (!pFCell->GetDocument()->GetMacroInterpretLevel()
93 0 : || pFCell->IsRunning()) )
94 : {
95 0 : rString = "...";
96 : }
97 : else
98 : {
99 2911 : sal_uInt16 nErrCode = pFCell->GetErrCode();
100 :
101 2911 : if (nErrCode != 0)
102 172 : rString = ScGlobal::GetErrorString(nErrCode);
103 2739 : else if ( pFCell->IsEmptyDisplayedAsString() )
104 3 : rString.clear();
105 2736 : else if ( pFCell->IsValue() )
106 : {
107 2282 : double fValue = pFCell->GetValue();
108 2282 : if ( !bNullVals && fValue == 0.0 )
109 0 : rString.clear();
110 2282 : else if ( pFCell->IsHybridValueCell() )
111 0 : rString = pFCell->GetString().getString();
112 : else
113 2282 : rFormatter.GetOutputString( fValue, nFormat, rString, ppColor, bUseStarFormat );
114 : }
115 : else
116 : {
117 : rFormatter.GetOutputString( pFCell->GetString().getString(),
118 454 : nFormat, rString, ppColor, bUseStarFormat );
119 : }
120 : }
121 : }
122 : }
123 2911 : break;
124 : default:
125 3276 : rString.clear();
126 3276 : break;
127 : }
128 71292 : }
129 :
130 6191 : OUString ScCellFormat::GetString(
131 : ScDocument& rDoc, const ScAddress& rPos, sal_uLong nFormat, Color** ppColor,
132 : SvNumberFormatter& rFormatter, bool bNullVals, bool bFormula, ScForceTextFmt eForceTextFmt,
133 : bool bUseStarFormat )
134 : {
135 6191 : OUString aString;
136 6191 : *ppColor = NULL;
137 :
138 6191 : CellType eType = rDoc.GetCellType(rPos);
139 6191 : switch (eType)
140 : {
141 : case CELLTYPE_STRING:
142 : {
143 3248 : ScRefCellValue aCell;
144 3248 : aCell.assign(rDoc, rPos);
145 3248 : rFormatter.GetOutputString(aCell.mpString->getString(), nFormat, aString, ppColor, bUseStarFormat);
146 : }
147 3248 : break;
148 : case CELLTYPE_EDIT:
149 : {
150 90 : ScRefCellValue aCell;
151 90 : aCell.assign(rDoc, rPos);
152 90 : rFormatter.GetOutputString(aCell.getString(&rDoc), nFormat, aString, ppColor);
153 : }
154 90 : break;
155 : case CELLTYPE_VALUE:
156 : {
157 2568 : double nValue = rDoc.GetValue(rPos);
158 2568 : if (!bNullVals && nValue == 0.0) aString.clear();
159 : else
160 : {
161 2568 : if (eForceTextFmt == ftCheck)
162 : {
163 0 : if (nFormat && rFormatter.IsTextFormat(nFormat)) eForceTextFmt = ftForce;
164 : }
165 2568 : if (eForceTextFmt == ftForce)
166 : {
167 0 : OUString aTemp;
168 0 : rFormatter.GetOutputString(nValue, 0, aTemp, ppColor);
169 0 : rFormatter.GetOutputString(aTemp, nFormat, aString, ppColor);
170 : }
171 2568 : else rFormatter.GetOutputString(nValue, nFormat, aString, ppColor, bUseStarFormat);
172 : }
173 : }
174 2568 : break;
175 : case CELLTYPE_FORMULA:
176 : {
177 285 : ScFormulaCell* pFCell = rDoc.GetFormulaCell(rPos);
178 285 : if (!pFCell)
179 0 : return aString;
180 285 : if (bFormula)
181 : {
182 0 : pFCell->GetFormula(aString);
183 : }
184 : else
185 : {
186 : // A macro started from the interpreter, which has
187 : // access to Formular Cells, becomes a CellText, even if
188 : // that triggers further interpretation, except if those
189 : // cells are already being interpreted.
190 : // IdleCalc generally doesn't trigger further interpretation,
191 : // as not to get Err522 (circular).
192 285 : if (pFCell->GetDocument()->IsInInterpreter() &&
193 0 : (!pFCell->GetDocument()->GetMacroInterpretLevel()
194 0 : || pFCell->IsRunning()))
195 : {
196 0 : aString = "...";
197 : }
198 : else
199 : {
200 285 : sal_uInt16 nErrCode = pFCell->GetErrCode();
201 :
202 285 : if (nErrCode != 0) aString = ScGlobal::GetErrorString(nErrCode);
203 284 : else if (pFCell->IsEmptyDisplayedAsString()) aString.clear();
204 284 : else if (pFCell->IsValue())
205 : {
206 257 : double fValue = pFCell->GetValue();
207 257 : if (!bNullVals && fValue == 0.0) aString.clear();
208 257 : else if (pFCell->IsHybridValueCell()) aString = pFCell->GetString().getString();
209 257 : else rFormatter.GetOutputString(fValue, nFormat, aString, ppColor, bUseStarFormat);
210 : }
211 : else
212 : {
213 : rFormatter.GetOutputString(pFCell->GetString().getString(),
214 27 : nFormat, aString, ppColor, bUseStarFormat);
215 : }
216 : }
217 : }
218 : }
219 285 : break;
220 : default:
221 : ;
222 : }
223 6191 : return aString;
224 : }
225 :
226 4316 : void ScCellFormat::GetInputString(
227 : ScRefCellValue& rCell, sal_uLong nFormat, OUString& rString, SvNumberFormatter& rFormatter, const ScDocument* pDoc )
228 : {
229 4316 : OUString aString = rString;
230 4316 : switch (rCell.meType)
231 : {
232 : case CELLTYPE_STRING:
233 : case CELLTYPE_EDIT:
234 1483 : aString = rCell.getString(pDoc);
235 1483 : break;
236 : case CELLTYPE_VALUE:
237 561 : rFormatter.GetInputLineString(rCell.mfValue, nFormat, aString );
238 561 : break;
239 : case CELLTYPE_FORMULA:
240 : {
241 22 : ScFormulaCell* pFC = rCell.mpFormula;
242 22 : if (pFC->IsEmptyDisplayedAsString())
243 0 : aString = EMPTY_OUSTRING;
244 22 : else if (pFC->IsValue())
245 4 : rFormatter.GetInputLineString(pFC->GetValue(), nFormat, aString);
246 : else
247 18 : aString = pFC->GetString().getString();
248 :
249 22 : sal_uInt16 nErrCode = pFC->GetErrCode();
250 22 : if (nErrCode != 0)
251 0 : aString = EMPTY_OUSTRING;
252 : }
253 22 : break;
254 : default:
255 2250 : aString = EMPTY_OUSTRING;
256 2250 : break;
257 : }
258 4316 : rString = aString;
259 4316 : }
260 :
261 2018 : OUString ScCellFormat::GetOutputString( ScDocument& rDoc, const ScAddress& rPos, ScRefCellValue& rCell )
262 : {
263 2018 : if (rCell.isEmpty())
264 47 : return EMPTY_OUSTRING;
265 :
266 1971 : OUString aVal;
267 :
268 1971 : if (rCell.meType == CELLTYPE_EDIT)
269 : {
270 : // GetString converts line breaks into spaces in EditCell,
271 : // but here we need the line breaks
272 1 : const EditTextObject* pData = rCell.mpEditText;
273 1 : if (pData)
274 : {
275 1 : ScFieldEditEngine& rEngine = rDoc.GetEditEngine();
276 1 : rEngine.SetText(*pData);
277 1 : aVal = rEngine.GetText(LINEEND_LF);
278 : }
279 : // also do not format EditCells as numbers
280 : // (fitting to output)
281 : }
282 : else
283 : {
284 : // like in GetString for document (column)
285 : Color* pColor;
286 1970 : sal_uLong nNumFmt = rDoc.GetNumberFormat(rPos);
287 1970 : aVal = GetString(rDoc, rPos, nNumFmt, &pColor, *rDoc.GetFormatTable());
288 : }
289 1971 : return aVal;
290 156 : }
291 :
292 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|