1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: difexp.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 //------------------------------------------------------------------------
38 #include <rtl/math.hxx>
44 #include "document.hxx"
46 #include "globstr.hrc"
48 #include "progress.hxx"
49 #include <rtl/tencinfo.h>
52 FltError
ScFormatFilterPluginImpl::ScExportDif( SvStream
& rStream
, ScDocument
* pDoc
,
53 const ScAddress
& rOutPos
, const CharSet eNach
, UINT32 nDifOption
)
57 pDoc
->GetTableArea( rOutPos
.Tab(), nEndCol
, nEndRow
);
58 ScAddress
aEnd( nEndCol
, nEndRow
, rOutPos
.Tab() );
59 ScAddress
aStart( rOutPos
);
61 aStart
.PutInOrder( aEnd
);
63 return ScExportDif( rStream
, pDoc
, ScRange( aStart
, aEnd
), eNach
, nDifOption
);
67 FltError
ScFormatFilterPluginImpl::ScExportDif( SvStream
& rOut
, ScDocument
* pDoc
,
68 const ScRange
&rRange
, const CharSet eCharSet
, UINT32 nDifOption
)
70 DBG_ASSERT( rRange
.aStart
<= rRange
.aEnd
, "*ScExportDif(): Range unsortiert!" );
71 DBG_ASSERTWARNING( rRange
.aStart
.Tab() == rRange
.aEnd
.Tab(),
72 "ScExportDif(): nur eine Tabelle bidde!" );
74 const CharSet eStreamCharSet
= rOut
.GetStreamCharSet();
75 if ( eStreamCharSet
!= eCharSet
)
76 rOut
.SetStreamCharSet( eCharSet
);
78 sal_Unicode
cStrDelim('"');
79 ByteString aStrDelimEncoded
; // only used if not Unicode
80 UniString aStrDelimDecoded
; // only used if context encoding
81 BOOL bContextOrNotAsciiEncoding
;
82 if ( eCharSet
== RTL_TEXTENCODING_UNICODE
)
84 rOut
.StartWritingUnicodeText();
85 bContextOrNotAsciiEncoding
= FALSE
;
89 aStrDelimEncoded
= ByteString( cStrDelim
, eCharSet
);
90 rtl_TextEncodingInfo aInfo
;
91 aInfo
.StructSize
= sizeof(aInfo
);
92 if ( rtl_getTextEncodingInfo( eCharSet
, &aInfo
) )
94 bContextOrNotAsciiEncoding
=
95 (((aInfo
.Flags
& RTL_TEXTENCODING_INFO_CONTEXT
) != 0) ||
96 ((aInfo
.Flags
& RTL_TEXTENCODING_INFO_ASCII
) == 0));
97 if ( bContextOrNotAsciiEncoding
)
98 aStrDelimDecoded
= String( aStrDelimEncoded
, eCharSet
);
101 bContextOrNotAsciiEncoding
= FALSE
;
104 const sal_Char
* p2DoubleQuotes_LF
= "\"\"\n";
105 const sal_Char
* pSpecDataType_LF
= "-1,0\n";
106 const sal_Char
* pEmptyData
= "1,0\n\"\"\n";
107 const sal_Char
* pStringData
= "1,0\n";
108 const sal_Char
* pNumData
= "0,";
109 const sal_Char
* pNumDataERROR
= "0,0\nERROR\n";
111 FltError eRet
= eERR_OK
;
114 SCCOL nEndCol
= rRange
.aEnd
.Col();
115 SCROW nEndRow
= rRange
.aEnd
.Row();
116 SCCOL nNumCols
= nEndCol
- rRange
.aStart
.Col() + 1;
117 SCROW nNumRows
= nEndRow
- rRange
.aStart
.Row() + 1;
118 SCTAB nTab
= rRange
.aStart
.Tab();
122 const BOOL bPlain
= ( nDifOption
== SC_DIFOPT_PLAIN
);
124 ScProgress
aPrgrsBar( pDoc
->GetDocumentShell(), ScGlobal::GetRscString( STR_LOAD_DOC
), nNumRows
);
126 aPrgrsBar
.SetState( 0 );
129 DBG_ASSERT( pDoc
->HasTable( nTab
), "*ScExportDif(): Tabelle nicht vorhanden!" );
132 aOS
.AppendAscii( "\n0,1\n\"" );
134 pDoc
->GetName( nTab
, aString
);
136 aOS
.AppendAscii( "\"\n" );
137 rOut
.WriteUnicodeOrByteText( aOS
);
141 aOS
.AppendAscii( "\n0," );
142 aOS
+= String::CreateFromInt32( nNumCols
);
143 aOS
+= sal_Unicode('\n');
144 aOS
.AppendAscii( p2DoubleQuotes_LF
);
145 rOut
.WriteUnicodeOrByteText( aOS
);
149 aOS
.AppendAscii( "\n0," );
150 aOS
+= String::CreateFromInt32( nNumRows
);
151 aOS
+= sal_Unicode('\n');
152 aOS
.AppendAscii( p2DoubleQuotes_LF
);
153 rOut
.WriteUnicodeOrByteText( aOS
);
157 aOS
.AppendAscii( "\n0,0\n" );
158 aOS
.AppendAscii( p2DoubleQuotes_LF
);
159 rOut
.WriteUnicodeOrByteText( aOS
);
165 for( nRowCnt
= rRange
.aStart
.Row() ; nRowCnt
<= nEndRow
; nRowCnt
++ )
167 aOS
.AssignAscii( pSpecDataType_LF
);
169 aOS
+= sal_Unicode('\n');
170 rOut
.WriteUnicodeOrByteText( aOS
);
171 for( nColCnt
= rRange
.aStart
.Col() ; nColCnt
<= nEndCol
; nColCnt
++ )
173 bool bWriteStringData
= false;
174 pDoc
->GetCell( nColCnt
, nRowCnt
, nTab
, pAkt
);
177 switch( pAkt
->GetCellType() )
181 aOS
.AssignAscii( pEmptyData
);
184 aOS
.AssignAscii( pNumData
);
187 fVal
= ( ( ScValueCell
* ) pAkt
)->GetValue();
188 aOS
+= String( ::rtl::math::doubleToUString(
189 fVal
, rtl_math_StringFormat_G
, 14, '.',
194 pDoc
->GetInputString( nColCnt
, nRowCnt
, nTab
, aString
);
197 aOS
.AppendAscii( "\nV\n" );
200 ( ( ScEditCell
* ) pAkt
)->GetString( aString
);
201 bWriteStringData
= true;
203 case CELLTYPE_STRING
:
204 ( ( ScStringCell
* ) pAkt
)->GetString( aString
);
205 bWriteStringData
= true;
207 case CELLTYPE_FORMULA
:
208 if ( ((ScFormulaCell
*)pAkt
)->GetErrCode() )
209 aOS
.AssignAscii( pNumDataERROR
);
210 else if( pAkt
->HasValueData() )
212 aOS
.AssignAscii( pNumData
);
215 fVal
= ( ( ScFormulaCell
* ) pAkt
)->GetValue();
216 aOS
+= String( ::rtl::math::doubleToUString(
217 fVal
, rtl_math_StringFormat_G
, 14,
222 pDoc
->GetInputString( nColCnt
, nRowCnt
, nTab
, aString
);
225 aOS
.AppendAscii( "\nV\n" );
227 else if( pAkt
->HasStringData() )
229 ( ( ScFormulaCell
* ) pAkt
)->GetString( aString
);
230 bWriteStringData
= true;
233 aOS
.AssignAscii( pNumDataERROR
);
240 aOS
.AssignAscii( pEmptyData
);
242 if ( !bWriteStringData
)
243 rOut
.WriteUnicodeOrByteText( aOS
);
246 // for an explanation why this complicated, see
247 // sc/source/ui/docsh.cxx:ScDocShell::AsciiSave()
248 // In fact we should create a common method if this would be
249 // needed just one more time..
250 aOS
.AssignAscii( pStringData
);
251 rOut
.WriteUnicodeOrByteText( aOS
, eCharSet
);
252 if ( eCharSet
== RTL_TEXTENCODING_UNICODE
)
254 xub_StrLen nPos
= aString
.Search( cStrDelim
);
255 while ( nPos
!= STRING_NOTFOUND
)
257 aString
.Insert( cStrDelim
, nPos
);
258 nPos
= aString
.Search( cStrDelim
, nPos
+2 );
260 rOut
.WriteUniOrByteChar( cStrDelim
, eCharSet
);
261 rOut
.WriteUnicodeText( aString
);
262 rOut
.WriteUniOrByteChar( cStrDelim
, eCharSet
);
264 else if ( bContextOrNotAsciiEncoding
)
267 ByteString
aStrEnc( aString
, eCharSet
);
269 UniString
aStrDec( aStrEnc
, eCharSet
);
270 // search on re-decoded string
271 xub_StrLen nPos
= aStrDec
.Search( aStrDelimDecoded
);
272 while ( nPos
!= STRING_NOTFOUND
)
274 aStrDec
.Insert( aStrDelimDecoded
, nPos
);
275 nPos
= aStrDec
.Search( aStrDelimDecoded
,
276 nPos
+1+aStrDelimDecoded
.Len() );
278 // write byte re-encoded
279 rOut
.WriteUniOrByteChar( cStrDelim
, eCharSet
);
280 rOut
.WriteUnicodeOrByteText( aStrDec
, eCharSet
);
281 rOut
.WriteUniOrByteChar( cStrDelim
, eCharSet
);
285 ByteString
aStrEnc( aString
, eCharSet
);
286 // search on encoded string
287 xub_StrLen nPos
= aStrEnc
.Search( aStrDelimEncoded
);
288 while ( nPos
!= STRING_NOTFOUND
)
290 aStrEnc
.Insert( aStrDelimEncoded
, nPos
);
291 nPos
= aStrEnc
.Search( aStrDelimEncoded
,
292 nPos
+1+aStrDelimEncoded
.Len() );
294 // write byte encoded
295 rOut
.Write( aStrDelimEncoded
.GetBuffer(),
296 aStrDelimEncoded
.Len() );
297 rOut
.Write( aStrEnc
.GetBuffer(), aStrEnc
.Len() );
298 rOut
.Write( aStrDelimEncoded
.GetBuffer(),
299 aStrDelimEncoded
.Len() );
301 rOut
.WriteUniOrByteChar( '\n', eCharSet
);
304 aPrgrsBar
.SetState( nRowCnt
);
307 aOS
.AssignAscii( pSpecDataType_LF
);
309 aOS
+= sal_Unicode('\n');
310 rOut
.WriteUnicodeOrByteText( aOS
);
312 // restore original value
313 rOut
.SetStreamCharSet( eStreamCharSet
);