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