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