fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / filter / dif / difexp.cxx
blob79907ce392080683588e5c7d00bd0b256a7d7942
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #include <rtl/math.hxx>
22 #include <stdio.h>
24 #include "dif.hxx"
25 #include "filter.hxx"
26 #include "document.hxx"
27 #include "formulacell.hxx"
28 #include "globstr.hrc"
29 #include "global.hxx"
30 #include "progress.hxx"
31 #include <rtl/tencinfo.h>
32 #include "ftools.hxx"
33 #include "cellvalue.hxx"
34 #include <rtl/strbuf.hxx>
35 #include <osl/diagnose.h>
37 FltError ScFormatFilterPluginImpl::ScExportDif( SvStream& rStream, ScDocument* pDoc,
38 const ScAddress& rOutPos, const rtl_TextEncoding eNach, sal_uInt32 nDifOption )
40 SCCOL nEndCol;
41 SCROW nEndRow;
42 pDoc->GetTableArea( rOutPos.Tab(), nEndCol, nEndRow );
43 ScAddress aEnd( nEndCol, nEndRow, rOutPos.Tab() );
44 ScAddress aStart( rOutPos );
46 aStart.PutInOrder( aEnd );
48 return ScExportDif( rStream, pDoc, ScRange( aStart, aEnd ), eNach, nDifOption );
51 FltError ScFormatFilterPluginImpl::ScExportDif( SvStream& rOut, ScDocument* pDoc,
52 const ScRange&rRange, const rtl_TextEncoding eCharSet, sal_uInt32 nDifOption )
54 OSL_ENSURE( rRange.aStart <= rRange.aEnd, "*ScExportDif(): Range not sorted!" );
55 OSL_ENSURE( rRange.aStart.Tab() == rRange.aEnd.Tab(),
56 "ScExportDif(): only one table please!" );
58 const rtl_TextEncoding eStreamCharSet = rOut.GetStreamCharSet();
59 if ( eStreamCharSet != eCharSet )
60 rOut.SetStreamCharSet( eCharSet );
62 sal_Unicode cStrDelim('"');
63 OString aStrDelimEncoded; // only used if not Unicode
64 OUString aStrDelimDecoded; // only used if context encoding
65 bool bContextOrNotAsciiEncoding;
66 if ( eCharSet == RTL_TEXTENCODING_UNICODE )
68 rOut.StartWritingUnicodeText();
69 bContextOrNotAsciiEncoding = false;
71 else
73 aStrDelimEncoded = OString(&cStrDelim, 1, eCharSet);
74 rtl_TextEncodingInfo aInfo;
75 aInfo.StructSize = sizeof(aInfo);
76 if ( rtl_getTextEncodingInfo( eCharSet, &aInfo ) )
78 bContextOrNotAsciiEncoding =
79 (((aInfo.Flags & RTL_TEXTENCODING_INFO_CONTEXT) != 0) ||
80 ((aInfo.Flags & RTL_TEXTENCODING_INFO_ASCII) == 0));
81 if ( bContextOrNotAsciiEncoding )
82 aStrDelimDecoded = OStringToOUString(aStrDelimEncoded, eCharSet);
84 else
85 bContextOrNotAsciiEncoding = false;
88 const sal_Char* p2DoubleQuotes_LF = "\"\"\n";
89 const sal_Char* pSpecDataType_LF = "-1,0\n";
90 const sal_Char* pEmptyData = "1,0\n\"\"\n";
91 const sal_Char* pStringData = "1,0\n";
92 const sal_Char* pNumData = "0,";
93 const sal_Char* pNumDataERROR = "0,0\nERROR\n";
95 FltError eRet = eERR_OK;
96 OUStringBuffer aOS;
97 OUString aString;
98 SCCOL nEndCol = rRange.aEnd.Col();
99 SCROW nEndRow = rRange.aEnd.Row();
100 SCCOL nNumCols = nEndCol - rRange.aStart.Col() + 1;
101 SCROW nNumRows = nEndRow - rRange.aStart.Row() + 1;
102 SCTAB nTab = rRange.aStart.Tab();
104 double fVal;
106 const bool bPlain = ( nDifOption == SC_DIFOPT_PLAIN );
108 ScProgress aPrgrsBar( pDoc->GetDocumentShell(), ScGlobal::GetRscString( STR_LOAD_DOC ), nNumRows );
110 aPrgrsBar.SetState( 0 );
112 // TABLE
113 OSL_ENSURE( pDoc->HasTable( nTab ), "*ScExportDif(): Table not existent!" );
115 aOS.append(pKeyTABLE);
116 aOS.appendAscii("\n0,1\n\"");
118 pDoc->GetName( nTab, aString );
119 aOS.append(aString);
120 aOS.appendAscii("\"\n");
121 rOut.WriteUnicodeOrByteText(aOS.makeStringAndClear());
123 // VECTORS
124 aOS.append(pKeyVECTORS);
125 aOS.appendAscii("\n0,");
126 aOS.append(static_cast<sal_Int32>(nNumCols));
127 aOS.append('\n');
128 aOS.appendAscii(p2DoubleQuotes_LF);
129 rOut.WriteUnicodeOrByteText(aOS.makeStringAndClear());
131 // TUPLES
132 aOS.append(pKeyTUPLES);
133 aOS.appendAscii("\n0,");
134 aOS.append(static_cast<sal_Int32>(nNumRows));
135 aOS.append('\n');
136 aOS.appendAscii(p2DoubleQuotes_LF);
137 rOut.WriteUnicodeOrByteText(aOS.makeStringAndClear());
139 // DATA
140 aOS.append(pKeyDATA);
141 aOS.appendAscii("\n0,0\n");
142 aOS.appendAscii(p2DoubleQuotes_LF);
143 rOut.WriteUnicodeOrByteText(aOS.makeStringAndClear());
145 SCCOL nColCnt;
146 SCROW nRowCnt;
148 ScRefCellValue aCell;
150 for( nRowCnt = rRange.aStart.Row() ; nRowCnt <= nEndRow ; nRowCnt++ )
152 OSL_ASSERT(aOS.getLength() == 0);
153 aOS.appendAscii(pSpecDataType_LF);
154 aOS.append(pKeyBOT);
155 aOS.append('\n');
156 rOut.WriteUnicodeOrByteText(aOS.makeStringAndClear());
157 for( nColCnt = rRange.aStart.Col() ; nColCnt <= nEndCol ; nColCnt++ )
159 OSL_ASSERT(aOS.getLength() == 0);
160 bool bWriteStringData = false;
161 aCell.assign(*pDoc, ScAddress(nColCnt, nRowCnt, nTab));
163 switch (aCell.meType)
165 case CELLTYPE_NONE:
166 aOS.appendAscii(pEmptyData);
167 break;
168 case CELLTYPE_VALUE:
169 aOS.appendAscii(pNumData);
170 if( bPlain )
172 aOS.append(
173 rtl::math::doubleToUString(
174 aCell.mfValue, rtl_math_StringFormat_G, 14, '.', true));
176 else
178 pDoc->GetInputString( nColCnt, nRowCnt, nTab, aString );
179 aOS.append(aString);
181 aOS.appendAscii("\nV\n");
182 break;
183 case CELLTYPE_EDIT:
184 case CELLTYPE_STRING:
185 aString = aCell.getString(pDoc);
186 bWriteStringData = true;
187 break;
188 case CELLTYPE_FORMULA:
189 if (aCell.mpFormula->GetErrCode())
190 aOS.appendAscii(pNumDataERROR);
191 else if (aCell.mpFormula->IsValue())
193 aOS.appendAscii(pNumData);
194 if( bPlain )
196 fVal = aCell.mpFormula->GetValue();
197 aOS.append(
198 rtl::math::doubleToUString(
199 fVal, rtl_math_StringFormat_G, 14, '.', true));
201 else
203 pDoc->GetInputString( nColCnt, nRowCnt, nTab, aString );
204 aOS.append(aString);
206 aOS.appendAscii("\nV\n");
208 else
210 aString = aCell.mpFormula->GetString().getString();
211 bWriteStringData = true;
214 break;
215 default:;
218 if ( !bWriteStringData )
219 rOut.WriteUnicodeOrByteText(aOS.makeStringAndClear());
220 else
222 // for an explanation why this complicated, see
223 // sc/source/ui/docsh.cxx:ScDocShell::AsciiSave()
224 // In fact we should create a common method if this would be
225 // needed just one more time..
226 OSL_ASSERT(aOS.getLength() == 0);
227 OUString aTmpStr = aString;
228 aOS.appendAscii(pStringData);
229 rOut.WriteUnicodeOrByteText(aOS.makeStringAndClear(), eCharSet);
230 if ( eCharSet == RTL_TEXTENCODING_UNICODE )
232 sal_Int32 nPos = aTmpStr.indexOf( cStrDelim );
233 while ( nPos != -1 )
235 aTmpStr = aTmpStr.replaceAt( nPos, 0, OUString(cStrDelim) );
236 nPos = aTmpStr.indexOf( cStrDelim, nPos+2 );
238 rOut.WriteUniOrByteChar( cStrDelim, eCharSet );
239 write_uInt16s_FromOUString(rOut, aTmpStr);
240 rOut.WriteUniOrByteChar( cStrDelim, eCharSet );
242 else if ( bContextOrNotAsciiEncoding )
244 // to byte encoding
245 OString aStrEnc = OUStringToOString(aTmpStr, eCharSet);
246 // back to Unicode
247 OUString aStrDec = OStringToOUString(aStrEnc, eCharSet);
248 // search on re-decoded string
249 sal_Int32 nPos = aStrDec.indexOf(aStrDelimDecoded);
250 while (nPos >= 0)
252 OUStringBuffer aBuf(aStrDec);
253 aBuf.insert(nPos, aStrDelimDecoded);
254 aStrDec = aBuf.makeStringAndClear();
255 nPos = aStrDec.indexOf(
256 aStrDelimDecoded, nPos+1+aStrDelimDecoded.getLength());
258 // write byte re-encoded
259 rOut.WriteUniOrByteChar( cStrDelim, eCharSet );
260 rOut.WriteUnicodeOrByteText( aStrDec, eCharSet );
261 rOut.WriteUniOrByteChar( cStrDelim, eCharSet );
263 else
265 OString aStrEnc = OUStringToOString(aTmpStr, eCharSet);
266 // search on encoded string
267 sal_Int32 nPos = aStrEnc.indexOf(aStrDelimEncoded);
268 while (nPos >= 0)
270 OStringBuffer aBuf(aStrEnc);
271 aBuf.insert(nPos, aStrDelimEncoded);
272 aStrEnc = aBuf.makeStringAndClear();
273 nPos = aStrEnc.indexOf(
274 aStrDelimEncoded, nPos+1+aStrDelimEncoded.getLength());
276 // write byte encoded
277 rOut.Write(aStrDelimEncoded.getStr(), aStrDelimEncoded.getLength());
278 rOut.Write(aStrEnc.getStr(), aStrEnc.getLength());
279 rOut.Write(aStrDelimEncoded.getStr(), aStrDelimEncoded.getLength());
281 rOut.WriteUniOrByteChar( '\n', eCharSet );
284 aPrgrsBar.SetState( nRowCnt );
287 OSL_ASSERT(aOS.getLength() == 0);
288 aOS.appendAscii(pSpecDataType_LF);
289 aOS.append(pKeyEOD);
290 aOS.append('\n');
291 rOut.WriteUnicodeOrByteText(aOS.makeStringAndClear());
293 // restore original value
294 rOut.SetStreamCharSet( eStreamCharSet );
296 return eRet;
299 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */