Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <rtl/math.hxx>
30 : :
31 : : #include <stdio.h>
32 : :
33 : : #include "dif.hxx"
34 : : #include "filter.hxx"
35 : : #include "document.hxx"
36 : : #include "cell.hxx"
37 : : #include "globstr.hrc"
38 : : #include "global.hxx"
39 : : #include "progress.hxx"
40 : : #include <rtl/tencinfo.h>
41 : : #include "ftools.hxx"
42 : : #include "rtl/strbuf.hxx"
43 : :
44 : 0 : FltError ScFormatFilterPluginImpl::ScExportDif( SvStream& rStream, ScDocument* pDoc,
45 : : const ScAddress& rOutPos, const CharSet eNach, sal_uInt32 nDifOption )
46 : : {
47 : : SCCOL nEndCol;
48 : : SCROW nEndRow;
49 [ # # ]: 0 : pDoc->GetTableArea( rOutPos.Tab(), nEndCol, nEndRow );
50 : 0 : ScAddress aEnd( nEndCol, nEndRow, rOutPos.Tab() );
51 : 0 : ScAddress aStart( rOutPos );
52 : :
53 : 0 : aStart.PutInOrder( aEnd );
54 : :
55 [ # # ]: 0 : return ScExportDif( rStream, pDoc, ScRange( aStart, aEnd ), eNach, nDifOption );
56 : : }
57 : :
58 : :
59 : 0 : FltError ScFormatFilterPluginImpl::ScExportDif( SvStream& rOut, ScDocument* pDoc,
60 : : const ScRange&rRange, const CharSet eCharSet, sal_uInt32 nDifOption )
61 : : {
62 : : OSL_ENSURE( rRange.aStart <= rRange.aEnd, "*ScExportDif(): Range unsortiert!" );
63 : : OSL_ENSURE( rRange.aStart.Tab() == rRange.aEnd.Tab(),
64 : : "ScExportDif(): nur eine Tabelle bidde!" );
65 : :
66 : 0 : const CharSet eStreamCharSet = rOut.GetStreamCharSet();
67 [ # # ]: 0 : if ( eStreamCharSet != eCharSet )
68 : 0 : rOut.SetStreamCharSet( eCharSet );
69 : :
70 : 0 : sal_Unicode cStrDelim('"');
71 : 0 : rtl::OString aStrDelimEncoded; // only used if not Unicode
72 : 0 : rtl::OUString aStrDelimDecoded; // only used if context encoding
73 : : bool bContextOrNotAsciiEncoding;
74 [ # # ]: 0 : if ( eCharSet == RTL_TEXTENCODING_UNICODE )
75 : : {
76 [ # # ]: 0 : rOut.StartWritingUnicodeText();
77 : 0 : bContextOrNotAsciiEncoding = false;
78 : : }
79 : : else
80 : : {
81 [ # # ]: 0 : aStrDelimEncoded = rtl::OString(&cStrDelim, 1, eCharSet);
82 : : rtl_TextEncodingInfo aInfo;
83 : 0 : aInfo.StructSize = sizeof(aInfo);
84 [ # # ][ # # ]: 0 : if ( rtl_getTextEncodingInfo( eCharSet, &aInfo ) )
85 : : {
86 : : bContextOrNotAsciiEncoding =
87 : : (((aInfo.Flags & RTL_TEXTENCODING_INFO_CONTEXT) != 0) ||
88 [ # # ][ # # ]: 0 : ((aInfo.Flags & RTL_TEXTENCODING_INFO_ASCII) == 0));
89 [ # # ]: 0 : if ( bContextOrNotAsciiEncoding )
90 [ # # ]: 0 : aStrDelimDecoded = rtl::OStringToOUString(aStrDelimEncoded, eCharSet);
91 : : }
92 : : else
93 : 0 : bContextOrNotAsciiEncoding = false;
94 : : }
95 : :
96 : 0 : const sal_Char* p2DoubleQuotes_LF = "\"\"\n";
97 : 0 : const sal_Char* pSpecDataType_LF = "-1,0\n";
98 : 0 : const sal_Char* pEmptyData = "1,0\n\"\"\n";
99 : 0 : const sal_Char* pStringData = "1,0\n";
100 : 0 : const sal_Char* pNumData = "0,";
101 : 0 : const sal_Char* pNumDataERROR = "0,0\nERROR\n";
102 : :
103 : 0 : FltError eRet = eERR_OK;
104 : 0 : rtl::OUStringBuffer aOS;
105 : 0 : rtl::OUString aString;
106 : 0 : SCCOL nEndCol = rRange.aEnd.Col();
107 : 0 : SCROW nEndRow = rRange.aEnd.Row();
108 : 0 : SCCOL nNumCols = nEndCol - rRange.aStart.Col() + 1;
109 : 0 : SCROW nNumRows = nEndRow - rRange.aStart.Row() + 1;
110 : 0 : SCTAB nTab = rRange.aStart.Tab();
111 : :
112 : : double fVal;
113 : :
114 : 0 : const bool bPlain = ( nDifOption == SC_DIFOPT_PLAIN );
115 : :
116 [ # # ][ # # ]: 0 : ScProgress aPrgrsBar( pDoc->GetDocumentShell(), ScGlobal::GetRscString( STR_LOAD_DOC ), nNumRows );
117 : :
118 [ # # ]: 0 : aPrgrsBar.SetState( 0 );
119 : :
120 : : // TABLE
121 : : OSL_ENSURE( pDoc->HasTable( nTab ), "*ScExportDif(): Tabelle nicht vorhanden!" );
122 : :
123 [ # # ]: 0 : aOS.append(pKeyTABLE);
124 [ # # ]: 0 : aOS.appendAscii("\n0,1\n\"");
125 : :
126 [ # # ]: 0 : pDoc->GetName( nTab, aString );
127 [ # # ]: 0 : aOS.append(aString);
128 [ # # ]: 0 : aOS.appendAscii("\"\n");
129 [ # # ][ # # ]: 0 : rOut.WriteUnicodeOrByteText(aOS.makeStringAndClear());
[ # # ][ # # ]
130 : :
131 : : // VECTORS
132 [ # # ]: 0 : aOS.append(pKeyVECTORS);
133 [ # # ]: 0 : aOS.appendAscii("\n0,");
134 [ # # ]: 0 : aOS.append(static_cast<sal_Int32>(nNumCols));
135 [ # # ]: 0 : aOS.append(sal_Unicode('\n'));
136 [ # # ]: 0 : aOS.appendAscii(p2DoubleQuotes_LF);
137 [ # # ][ # # ]: 0 : rOut.WriteUnicodeOrByteText(aOS.makeStringAndClear());
[ # # ][ # # ]
138 : :
139 : : // TUPLES
140 [ # # ]: 0 : aOS.append(pKeyTUPLES);
141 [ # # ]: 0 : aOS.appendAscii("\n0,");
142 [ # # ]: 0 : aOS.append(static_cast<sal_Int32>(nNumRows));
143 [ # # ]: 0 : aOS.append(sal_Unicode('\n'));
144 [ # # ]: 0 : aOS.appendAscii(p2DoubleQuotes_LF);
145 [ # # ][ # # ]: 0 : rOut.WriteUnicodeOrByteText(aOS.makeStringAndClear());
[ # # ][ # # ]
146 : :
147 : : // DATA
148 [ # # ]: 0 : aOS.append(pKeyDATA);
149 [ # # ]: 0 : aOS.appendAscii("\n0,0\n");
150 [ # # ]: 0 : aOS.appendAscii(p2DoubleQuotes_LF);
151 [ # # ][ # # ]: 0 : rOut.WriteUnicodeOrByteText(aOS.makeStringAndClear());
[ # # ][ # # ]
152 : :
153 : : SCCOL nColCnt;
154 : : SCROW nRowCnt;
155 : : ScBaseCell* pAkt;
156 : :
157 [ # # ]: 0 : for( nRowCnt = rRange.aStart.Row() ; nRowCnt <= nEndRow ; nRowCnt++ )
158 : : {
159 : : OSL_ASSERT(aOS.getLength() == 0);
160 [ # # ]: 0 : aOS.appendAscii(pSpecDataType_LF);
161 [ # # ]: 0 : aOS.append(pKeyBOT);
162 [ # # ]: 0 : aOS.append(sal_Unicode('\n'));
163 [ # # ][ # # ]: 0 : rOut.WriteUnicodeOrByteText(aOS.makeStringAndClear());
[ # # ][ # # ]
164 [ # # ]: 0 : for( nColCnt = rRange.aStart.Col() ; nColCnt <= nEndCol ; nColCnt++ )
165 : : {
166 : : OSL_ASSERT(aOS.getLength() == 0);
167 : 0 : bool bWriteStringData = false;
168 [ # # ]: 0 : pDoc->GetCell( nColCnt, nRowCnt, nTab, pAkt );
169 [ # # ]: 0 : if( pAkt )
170 : : {
171 [ # # # # : 0 : switch( pAkt->GetCellType() )
# # ]
172 : : {
173 : : case CELLTYPE_NONE:
174 : : case CELLTYPE_NOTE:
175 [ # # ]: 0 : aOS.appendAscii(pEmptyData);
176 : 0 : break;
177 : : case CELLTYPE_VALUE:
178 [ # # ]: 0 : aOS.appendAscii(pNumData);
179 [ # # ]: 0 : if( bPlain )
180 : : {
181 : 0 : fVal = static_cast<ScValueCell*>(pAkt)->GetValue();
182 : : aOS.append(
183 : : rtl::math::doubleToUString(
184 [ # # ]: 0 : fVal, rtl_math_StringFormat_G, 14, '.', true));
185 : : }
186 : : else
187 : : {
188 [ # # ]: 0 : pDoc->GetInputString( nColCnt, nRowCnt, nTab, aString );
189 [ # # ]: 0 : aOS.append(aString);
190 : : }
191 [ # # ]: 0 : aOS.appendAscii("\nV\n");
192 : 0 : break;
193 : : case CELLTYPE_EDIT:
194 [ # # ]: 0 : aString = static_cast<ScEditCell*>(pAkt)->GetString();
195 : 0 : bWriteStringData = true;
196 : 0 : break;
197 : : case CELLTYPE_STRING:
198 : 0 : aString = static_cast<ScStringCell*>(pAkt)->GetString();
199 : 0 : bWriteStringData = true;
200 : 0 : break;
201 : : case CELLTYPE_FORMULA:
202 [ # # ][ # # ]: 0 : if (static_cast<ScFormulaCell*>(pAkt)->GetErrCode())
[ # # ]
203 [ # # ]: 0 : aOS.appendAscii(pNumDataERROR);
204 [ # # ][ # # ]: 0 : else if( pAkt->HasValueData() )
205 : : {
206 [ # # ]: 0 : aOS.appendAscii(pNumData);
207 [ # # ]: 0 : if( bPlain )
208 : : {
209 [ # # ][ # # ]: 0 : fVal = static_cast<ScFormulaCell*>(pAkt)->GetValue();
210 : : aOS.append(
211 : : rtl::math::doubleToUString(
212 [ # # ]: 0 : fVal, rtl_math_StringFormat_G, 14, '.', true));
213 : : }
214 : : else
215 : : {
216 [ # # ]: 0 : pDoc->GetInputString( nColCnt, nRowCnt, nTab, aString );
217 [ # # ]: 0 : aOS.append(aString);
218 : : }
219 [ # # ]: 0 : aOS.appendAscii("\nV\n");
220 : : }
221 [ # # ][ # # ]: 0 : else if( pAkt->HasStringData() )
222 : : {
223 [ # # ][ # # ]: 0 : aString = static_cast<ScFormulaCell*>(pAkt)->GetString();
224 : 0 : bWriteStringData = true;
225 : : }
226 : : else
227 [ # # ]: 0 : aOS.appendAscii(pNumDataERROR);
228 : :
229 : 0 : break;
230 : : default:;
231 : : }
232 : : }
233 : : else
234 [ # # ]: 0 : aOS.appendAscii(pEmptyData);
235 : :
236 [ # # ]: 0 : if ( !bWriteStringData )
237 [ # # ][ # # ]: 0 : rOut.WriteUnicodeOrByteText(aOS.makeStringAndClear());
[ # # ][ # # ]
238 : : else
239 : : {
240 : : // for an explanation why this complicated, see
241 : : // sc/source/ui/docsh.cxx:ScDocShell::AsciiSave()
242 : : // In fact we should create a common method if this would be
243 : : // needed just one more time..
244 : : OSL_ASSERT(aOS.getLength() == 0);
245 [ # # ]: 0 : String aTmpStr = aString;
246 [ # # ]: 0 : aOS.appendAscii(pStringData);
247 [ # # ][ # # ]: 0 : rOut.WriteUnicodeOrByteText(aOS.makeStringAndClear(), eCharSet);
[ # # ][ # # ]
248 [ # # ]: 0 : if ( eCharSet == RTL_TEXTENCODING_UNICODE )
249 : : {
250 [ # # ]: 0 : xub_StrLen nPos = aTmpStr.Search( cStrDelim );
251 [ # # ]: 0 : while ( nPos != STRING_NOTFOUND )
252 : : {
253 [ # # ]: 0 : aTmpStr.Insert( cStrDelim, nPos );
254 [ # # ]: 0 : nPos = aTmpStr.Search( cStrDelim, nPos+2 );
255 : : }
256 [ # # ]: 0 : rOut.WriteUniOrByteChar( cStrDelim, eCharSet );
257 [ # # ][ # # ]: 0 : write_uInt16s_FromOUString(rOut, aTmpStr);
258 [ # # ]: 0 : rOut.WriteUniOrByteChar( cStrDelim, eCharSet );
259 : : }
260 [ # # ]: 0 : else if ( bContextOrNotAsciiEncoding )
261 : : {
262 : : // to byte encoding
263 [ # # ][ # # ]: 0 : rtl::OString aStrEnc = rtl::OUStringToOString(aTmpStr, eCharSet);
264 : : // back to Unicode
265 [ # # ]: 0 : rtl::OUString aStrDec = rtl::OStringToOUString(aStrEnc, eCharSet);
266 : : // search on re-decoded string
267 : 0 : sal_Int32 nPos = aStrDec.indexOf(aStrDelimDecoded);
268 [ # # ]: 0 : while (nPos >= 0)
269 : : {
270 [ # # ]: 0 : rtl::OUStringBuffer aBuf(aStrDec);
271 [ # # ]: 0 : aBuf.insert(nPos, aStrDelimDecoded);
272 [ # # ]: 0 : aStrDec = aBuf.makeStringAndClear();
273 : : nPos = aStrDec.indexOf(
274 : 0 : aStrDelimDecoded, nPos+1+aStrDelimDecoded.getLength());
275 : 0 : }
276 : : // write byte re-encoded
277 [ # # ]: 0 : rOut.WriteUniOrByteChar( cStrDelim, eCharSet );
278 [ # # ][ # # ]: 0 : rOut.WriteUnicodeOrByteText( aStrDec, eCharSet );
[ # # ]
279 [ # # ]: 0 : rOut.WriteUniOrByteChar( cStrDelim, eCharSet );
280 : : }
281 : : else
282 : : {
283 [ # # ][ # # ]: 0 : rtl::OString aStrEnc = rtl::OUStringToOString(aTmpStr, eCharSet);
284 : : // search on encoded string
285 : 0 : sal_Int32 nPos = aStrEnc.indexOf(aStrDelimEncoded);
286 [ # # ]: 0 : while (nPos >= 0)
287 : : {
288 [ # # ]: 0 : rtl::OStringBuffer aBuf(aStrEnc);
289 [ # # ]: 0 : aBuf.insert(nPos, aStrDelimEncoded);
290 : 0 : aStrEnc = aBuf.makeStringAndClear();
291 : : nPos = aStrEnc.indexOf(
292 : 0 : aStrDelimEncoded, nPos+1+aStrDelimEncoded.getLength());
293 : 0 : }
294 : : // write byte encoded
295 [ # # ]: 0 : rOut.Write(aStrDelimEncoded.getStr(), aStrDelimEncoded.getLength());
296 [ # # ]: 0 : rOut.Write(aStrEnc.getStr(), aStrEnc.getLength());
297 [ # # ]: 0 : rOut.Write(aStrDelimEncoded.getStr(), aStrDelimEncoded.getLength());
298 : : }
299 [ # # ][ # # ]: 0 : rOut.WriteUniOrByteChar( '\n', eCharSet );
300 : : }
301 : : }
302 [ # # ]: 0 : aPrgrsBar.SetState( nRowCnt );
303 : : }
304 : :
305 : : OSL_ASSERT(aOS.getLength() == 0);
306 [ # # ]: 0 : aOS.appendAscii(pSpecDataType_LF);
307 [ # # ]: 0 : aOS.append(pKeyEOD);
308 [ # # ]: 0 : aOS.append(sal_Unicode('\n'));
309 [ # # ][ # # ]: 0 : rOut.WriteUnicodeOrByteText(aOS.makeStringAndClear());
[ # # ][ # # ]
310 : :
311 : : // restore original value
312 : 0 : rOut.SetStreamCharSet( eStreamCharSet );
313 : :
314 [ # # ]: 0 : return eRet;
315 : : }
316 : :
317 : :
318 : :
319 : :
320 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|