1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
26 #include "document.hxx"
27 #include "formulacell.hxx"
28 #include "globstr.hrc"
30 #include "progress.hxx"
31 #include <rtl/tencinfo.h>
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
)
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;
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
);
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
;
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();
106 const bool bPlain
= ( nDifOption
== SC_DIFOPT_PLAIN
);
108 ScProgress
aPrgrsBar( pDoc
->GetDocumentShell(), ScGlobal::GetRscString( STR_LOAD_DOC
), nNumRows
);
110 aPrgrsBar
.SetState( 0 );
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
);
120 aOS
.appendAscii("\"\n");
121 rOut
.WriteUnicodeOrByteText(aOS
.makeStringAndClear());
124 aOS
.append(pKeyVECTORS
);
125 aOS
.appendAscii("\n0,");
126 aOS
.append(static_cast<sal_Int32
>(nNumCols
));
128 aOS
.appendAscii(p2DoubleQuotes_LF
);
129 rOut
.WriteUnicodeOrByteText(aOS
.makeStringAndClear());
132 aOS
.append(pKeyTUPLES
);
133 aOS
.appendAscii("\n0,");
134 aOS
.append(static_cast<sal_Int32
>(nNumRows
));
136 aOS
.appendAscii(p2DoubleQuotes_LF
);
137 rOut
.WriteUnicodeOrByteText(aOS
.makeStringAndClear());
140 aOS
.append(pKeyDATA
);
141 aOS
.appendAscii("\n0,0\n");
142 aOS
.appendAscii(p2DoubleQuotes_LF
);
143 rOut
.WriteUnicodeOrByteText(aOS
.makeStringAndClear());
148 ScRefCellValue aCell
;
150 for( nRowCnt
= rRange
.aStart
.Row() ; nRowCnt
<= nEndRow
; nRowCnt
++ )
152 OSL_ASSERT(aOS
.getLength() == 0);
153 aOS
.appendAscii(pSpecDataType_LF
);
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
)
166 aOS
.appendAscii(pEmptyData
);
169 aOS
.appendAscii(pNumData
);
173 rtl::math::doubleToUString(
174 aCell
.mfValue
, rtl_math_StringFormat_G
, 14, '.', true));
178 pDoc
->GetInputString( nColCnt
, nRowCnt
, nTab
, aString
);
181 aOS
.appendAscii("\nV\n");
184 case CELLTYPE_STRING
:
185 aString
= aCell
.getString(pDoc
);
186 bWriteStringData
= true;
188 case CELLTYPE_FORMULA
:
189 if (aCell
.mpFormula
->GetErrCode())
190 aOS
.appendAscii(pNumDataERROR
);
191 else if (aCell
.mpFormula
->IsValue())
193 aOS
.appendAscii(pNumData
);
196 fVal
= aCell
.mpFormula
->GetValue();
198 rtl::math::doubleToUString(
199 fVal
, rtl_math_StringFormat_G
, 14, '.', true));
203 pDoc
->GetInputString( nColCnt
, nRowCnt
, nTab
, aString
);
206 aOS
.appendAscii("\nV\n");
210 aString
= aCell
.mpFormula
->GetString().getString();
211 bWriteStringData
= true;
218 if ( !bWriteStringData
)
219 rOut
.WriteUnicodeOrByteText(aOS
.makeStringAndClear());
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
);
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
)
245 OString aStrEnc
= OUStringToOString(aTmpStr
, eCharSet
);
247 OUString aStrDec
= OStringToOUString(aStrEnc
, eCharSet
);
248 // search on re-decoded string
249 sal_Int32 nPos
= aStrDec
.indexOf(aStrDelimDecoded
);
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
);
265 OString aStrEnc
= OUStringToOString(aTmpStr
, eCharSet
);
266 // search on encoded string
267 sal_Int32 nPos
= aStrEnc
.indexOf(aStrDelimEncoded
);
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
);
291 rOut
.WriteUnicodeOrByteText(aOS
.makeStringAndClear());
293 // restore original value
294 rOut
.SetStreamCharSet( eStreamCharSet
);
299 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */