xref: /core/sc/source/core/tool/cellform.cxx (revision fce7c123)
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/zforlist.hxx>
24 #include <svl/sharedstring.hxx>
25 
26 #include <formulacell.hxx>
27 #include <document.hxx>
28 #include <cellvalue.hxx>
29 #include <formula/errorcodes.hxx>
30 #include <sc.hrc>
31 #include <editutil.hxx>
32 
33 void ScCellFormat::GetString( const ScRefCellValue& rCell, sal_uInt32 nFormat, OUString& rString,
34                               Color** ppColor, SvNumberFormatter& rFormatter, const ScDocument* pDoc,
35                               bool bNullVals, bool bFormula, bool bUseStarFormat )
36 {
37     *ppColor = nullptr;
38 
39     switch (rCell.meType)
40     {
41         case CELLTYPE_STRING:
42             rFormatter.GetOutputString(rCell.mpString->getString(), nFormat, rString, ppColor, bUseStarFormat);
43         break;
44         case CELLTYPE_EDIT:
45             rFormatter.GetOutputString(rCell.getString(pDoc), nFormat, rString, ppColor );
46         break;
47         case CELLTYPE_VALUE:
48         {
49             const double & nValue = rCell.mfValue;
50             if (!bNullVals && nValue == 0.0)
51                 rString.clear();
52             else
53                 rFormatter.GetOutputString( nValue, nFormat, rString, ppColor, bUseStarFormat );
54         }
55         break;
56         case CELLTYPE_FORMULA:
57         {
58             ScFormulaCell*  pFCell = rCell.mpFormula;
59             if ( bFormula )
60             {
61                 pFCell->GetFormula( rString );
62             }
63             else
64             {
65                 // A macro started from the interpreter, which has
66                 // access to Formula Cells, becomes a CellText, even if
67                 // that triggers further interpretation, except if those
68                 // cells are already being interpreted.
69                 // IdleCalc generally doesn't trigger further interpretation,
70                 // as not to get Err522 (circular).
71                 if ( pFCell->GetDocument()->IsInInterpreter() &&
72                         (!pFCell->GetDocument()->GetMacroInterpretLevel()
73                         || pFCell->IsRunning()) )
74                 {
75                     rString = "...";
76                 }
77                 else
78                 {
79                     const FormulaError nErrCode = pFCell->GetErrCode();
80 
81                     if (nErrCode != FormulaError::NONE)
82                         rString = ScGlobal::GetErrorString(nErrCode);
83                     else if ( pFCell->IsEmptyDisplayedAsString() )
84                         rString.clear();
85                     else if ( pFCell->IsValue() )
86                     {
87                         double fValue = pFCell->GetValue();
88                         if ( !bNullVals && fValue == 0.0 )
89                             rString.clear();
90                         else
91                             rFormatter.GetOutputString( fValue, nFormat, rString, ppColor, bUseStarFormat );
92                     }
93                     else
94                     {
95                         rFormatter.GetOutputString( pFCell->GetString().getString(),
96                                                     nFormat, rString, ppColor, bUseStarFormat );
97                     }
98                 }
99             }
100         }
101         break;
102         default:
103             rString.clear();
104             break;
105     }
106 }
107 
108 OUString ScCellFormat::GetString(
109     ScDocument& rDoc, const ScAddress& rPos, sal_uInt32 nFormat, Color** ppColor,
110     SvNumberFormatter& rFormatter, bool bNullVals, bool bFormula )
111 {
112     OUString aString;
113     *ppColor = nullptr;
114 
115     ScRefCellValue aCell(rDoc, rPos);
116     GetString(aCell, nFormat, aString, ppColor, rFormatter, &rDoc, bNullVals, bFormula);
117     return aString;
118 }
119 
120 void ScCellFormat::GetInputString(
121     const ScRefCellValue& rCell, sal_uInt32 nFormat, OUString& rString, SvNumberFormatter& rFormatter, const ScDocument* pDoc )
122 {
123     switch (rCell.meType)
124     {
125         case CELLTYPE_STRING:
126         case CELLTYPE_EDIT:
127             rString = rCell.getString(pDoc);
128         break;
129         case CELLTYPE_VALUE:
130             rFormatter.GetInputLineString(rCell.mfValue, nFormat, rString );
131         break;
132         case CELLTYPE_FORMULA:
133         {
134             ScFormulaCell* pFC = rCell.mpFormula;
135             if (pFC->IsEmptyDisplayedAsString())
136                 rString = EMPTY_OUSTRING;
137             else if (pFC->IsValue())
138                 rFormatter.GetInputLineString(pFC->GetValue(), nFormat, rString);
139             else
140                 rString = pFC->GetString().getString();
141 
142             const FormulaError nErrCode = pFC->GetErrCode();
143             if (nErrCode != FormulaError::NONE)
144                 rString = EMPTY_OUSTRING;
145         }
146         break;
147         default:
148             rString = EMPTY_OUSTRING;
149             break;
150     }
151 }
152 
153 OUString ScCellFormat::GetOutputString( ScDocument& rDoc, const ScAddress& rPos, ScRefCellValue& rCell )
154 {
155     if (rCell.isEmpty())
156         return EMPTY_OUSTRING;
157 
158     OUString aVal;
159 
160     if (rCell.meType == CELLTYPE_EDIT)
161     {
162         //  GetString converts line breaks into spaces in EditCell,
163         //  but here we need the line breaks
164         const EditTextObject* pData = rCell.mpEditText;
165         if (pData)
166         {
167             ScFieldEditEngine& rEngine = rDoc.GetEditEngine();
168             rEngine.SetText(*pData);
169             aVal = rEngine.GetText();
170         }
171         //  also do not format EditCells as numbers
172         //  (fitting to output)
173     }
174     else
175     {
176         //  like in GetString for document (column)
177         Color* pColor;
178         sal_uInt32 nNumFmt = rDoc.GetNumberFormat(rPos);
179         GetString(rCell, nNumFmt, aVal, &pColor, *rDoc.GetFormatTable(), &rDoc);
180     }
181     return aVal;
182 }
183 
184 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
185