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>
24 #include "document.hxx"
25 #include "formulacell.hxx"
26 #include "globstr.hrc"
28 #include "progress.hxx"
29 #include <rtl/tencinfo.h>
31 #include "cellvalue.hxx"
32 #include <rtl/strbuf.hxx>
33 #include <osl/diagnose.h>
35 void ScFormatFilterPluginImpl::ScExportDif( SvStream
& rStream
, ScDocument
* pDoc
,
36 const ScAddress
& rOutPos
, const rtl_TextEncoding eNach
)
40 pDoc
->GetTableArea( rOutPos
.Tab(), nEndCol
, nEndRow
);
41 ScAddress
aEnd( nEndCol
, nEndRow
, rOutPos
.Tab() );
42 ScAddress
aStart( rOutPos
);
44 aStart
.PutInOrder( aEnd
);
46 ScExportDif( rStream
, pDoc
, ScRange( aStart
, aEnd
), eNach
);
49 FltError
ScFormatFilterPluginImpl::ScExportDif( SvStream
& rOut
, ScDocument
* pDoc
,
50 const ScRange
&rRange
, const rtl_TextEncoding eCharSet
)
52 OSL_ENSURE( rRange
.aStart
<= rRange
.aEnd
, "*ScExportDif(): Range not sorted!" );
53 OSL_ENSURE( rRange
.aStart
.Tab() == rRange
.aEnd
.Tab(),
54 "ScExportDif(): only one table please!" );
56 const rtl_TextEncoding eStreamCharSet
= rOut
.GetStreamCharSet();
57 if ( eStreamCharSet
!= eCharSet
)
58 rOut
.SetStreamCharSet( eCharSet
);
60 sal_Unicode
cStrDelim('"');
61 OString aStrDelimEncoded
; // only used if not Unicode
62 OUString aStrDelimDecoded
; // only used if context encoding
63 bool bContextOrNotAsciiEncoding
;
64 if ( eCharSet
== RTL_TEXTENCODING_UNICODE
)
66 rOut
.StartWritingUnicodeText();
67 bContextOrNotAsciiEncoding
= false;
71 aStrDelimEncoded
= OString(&cStrDelim
, 1, eCharSet
);
72 rtl_TextEncodingInfo aInfo
;
73 aInfo
.StructSize
= sizeof(aInfo
);
74 if ( rtl_getTextEncodingInfo( eCharSet
, &aInfo
) )
76 bContextOrNotAsciiEncoding
=
77 (((aInfo
.Flags
& RTL_TEXTENCODING_INFO_CONTEXT
) != 0) ||
78 ((aInfo
.Flags
& RTL_TEXTENCODING_INFO_ASCII
) == 0));
79 if ( bContextOrNotAsciiEncoding
)
80 aStrDelimDecoded
= OStringToOUString(aStrDelimEncoded
, eCharSet
);
83 bContextOrNotAsciiEncoding
= false;
86 const sal_Char
* p2DoubleQuotes_LF
= "\"\"\n";
87 const sal_Char
* pSpecDataType_LF
= "-1,0\n";
88 const sal_Char
* pEmptyData
= "1,0\n\"\"\n";
89 const sal_Char
* pStringData
= "1,0\n";
90 const sal_Char
* pNumData
= "0,";
91 const sal_Char
* pNumDataERROR
= "0,0\nERROR\n";
93 FltError eRet
= eERR_OK
;
96 SCCOL nEndCol
= rRange
.aEnd
.Col();
97 SCROW nEndRow
= rRange
.aEnd
.Row();
98 SCCOL nNumCols
= nEndCol
- rRange
.aStart
.Col() + 1;
99 SCROW nNumRows
= nEndRow
- rRange
.aStart
.Row() + 1;
100 SCTAB nTab
= rRange
.aStart
.Tab();
102 ScProgress
aPrgrsBar( pDoc
->GetDocumentShell(), ScGlobal::GetRscString( STR_LOAD_DOC
), nNumRows
, true );
104 aPrgrsBar
.SetState( 0 );
107 OSL_ENSURE( pDoc
->HasTable( nTab
), "*ScExportDif(): Table not existent!" );
109 aOS
.append(pKeyTABLE
);
110 aOS
.append("\n0,1\n\"");
112 pDoc
->GetName( nTab
, aString
);
115 rOut
.WriteUnicodeOrByteText(aOS
.makeStringAndClear());
118 aOS
.append(pKeyVECTORS
);
120 aOS
.append(static_cast<sal_Int32
>(nNumCols
));
122 aOS
.appendAscii(p2DoubleQuotes_LF
);
123 rOut
.WriteUnicodeOrByteText(aOS
.makeStringAndClear());
126 aOS
.append(pKeyTUPLES
);
128 aOS
.append(static_cast<sal_Int32
>(nNumRows
));
130 aOS
.appendAscii(p2DoubleQuotes_LF
);
131 rOut
.WriteUnicodeOrByteText(aOS
.makeStringAndClear());
134 aOS
.append(pKeyDATA
);
135 aOS
.append("\n0,0\n");
136 aOS
.appendAscii(p2DoubleQuotes_LF
);
137 rOut
.WriteUnicodeOrByteText(aOS
.makeStringAndClear());
142 for( nRowCnt
= rRange
.aStart
.Row() ; nRowCnt
<= nEndRow
; nRowCnt
++ )
144 OSL_ASSERT(aOS
.getLength() == 0);
145 aOS
.appendAscii(pSpecDataType_LF
);
148 rOut
.WriteUnicodeOrByteText(aOS
.makeStringAndClear());
149 for( nColCnt
= rRange
.aStart
.Col() ; nColCnt
<= nEndCol
; nColCnt
++ )
151 OSL_ASSERT(aOS
.getLength() == 0);
152 bool bWriteStringData
= false;
153 ScRefCellValue
aCell(*pDoc
, ScAddress(nColCnt
, nRowCnt
, nTab
));
155 switch (aCell
.meType
)
158 aOS
.appendAscii(pEmptyData
);
161 aOS
.appendAscii(pNumData
);
162 pDoc
->GetInputString( nColCnt
, nRowCnt
, nTab
, aString
);
167 case CELLTYPE_STRING
:
168 aString
= aCell
.getString(pDoc
);
169 bWriteStringData
= true;
171 case CELLTYPE_FORMULA
:
172 if (aCell
.mpFormula
->GetErrCode())
173 aOS
.appendAscii(pNumDataERROR
);
174 else if (aCell
.mpFormula
->IsValue())
176 aOS
.appendAscii(pNumData
);
177 pDoc
->GetInputString( nColCnt
, nRowCnt
, nTab
, aString
);
183 aString
= aCell
.mpFormula
->GetString().getString();
184 bWriteStringData
= true;
191 if ( !bWriteStringData
)
192 rOut
.WriteUnicodeOrByteText(aOS
.makeStringAndClear());
195 // for an explanation why this complicated, see
196 // sc/source/ui/docsh.cxx:ScDocShell::AsciiSave()
197 // In fact we should create a common method if this would be
198 // needed just one more time..
199 OSL_ASSERT(aOS
.getLength() == 0);
200 OUString aTmpStr
= aString
;
201 aOS
.appendAscii(pStringData
);
202 rOut
.WriteUnicodeOrByteText(aOS
.makeStringAndClear(), eCharSet
);
203 if ( eCharSet
== RTL_TEXTENCODING_UNICODE
)
205 sal_Int32 nPos
= aTmpStr
.indexOf( cStrDelim
);
208 aTmpStr
= aTmpStr
.replaceAt( nPos
, 0, OUString(cStrDelim
) );
209 nPos
= aTmpStr
.indexOf( cStrDelim
, nPos
+2 );
211 rOut
.WriteUniOrByteChar( cStrDelim
, eCharSet
);
212 write_uInt16s_FromOUString(rOut
, aTmpStr
);
213 rOut
.WriteUniOrByteChar( cStrDelim
, eCharSet
);
215 else if ( bContextOrNotAsciiEncoding
)
218 OString aStrEnc
= OUStringToOString(aTmpStr
, eCharSet
);
220 OUString aStrDec
= OStringToOUString(aStrEnc
, eCharSet
);
221 // search on re-decoded string
222 sal_Int32 nPos
= aStrDec
.indexOf(aStrDelimDecoded
);
225 OUStringBuffer
aBuf(aStrDec
);
226 aBuf
.insert(nPos
, aStrDelimDecoded
);
227 aStrDec
= aBuf
.makeStringAndClear();
228 nPos
= aStrDec
.indexOf(
229 aStrDelimDecoded
, nPos
+1+aStrDelimDecoded
.getLength());
231 // write byte re-encoded
232 rOut
.WriteUniOrByteChar( cStrDelim
, eCharSet
);
233 rOut
.WriteUnicodeOrByteText( aStrDec
, eCharSet
);
234 rOut
.WriteUniOrByteChar( cStrDelim
, eCharSet
);
238 OString aStrEnc
= OUStringToOString(aTmpStr
, eCharSet
);
239 // search on encoded string
240 sal_Int32 nPos
= aStrEnc
.indexOf(aStrDelimEncoded
);
243 OStringBuffer
aBuf(aStrEnc
);
244 aBuf
.insert(nPos
, aStrDelimEncoded
);
245 aStrEnc
= aBuf
.makeStringAndClear();
246 nPos
= aStrEnc
.indexOf(
247 aStrDelimEncoded
, nPos
+1+aStrDelimEncoded
.getLength());
249 // write byte encoded
250 rOut
.Write(aStrDelimEncoded
.getStr(), aStrDelimEncoded
.getLength());
251 rOut
.Write(aStrEnc
.getStr(), aStrEnc
.getLength());
252 rOut
.Write(aStrDelimEncoded
.getStr(), aStrDelimEncoded
.getLength());
254 rOut
.WriteUniOrByteChar( '\n', eCharSet
);
257 aPrgrsBar
.SetState( nRowCnt
);
260 OSL_ASSERT(aOS
.getLength() == 0);
261 aOS
.appendAscii(pSpecDataType_LF
);
264 rOut
.WriteUnicodeOrByteText(aOS
.makeStringAndClear());
266 // restore original value
267 rOut
.SetStreamCharSet( eStreamCharSet
);
272 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */