/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_scfilt.hxx" //------------------------------------------------------------------------ #include #include #include "dif.hxx" #include "filter.hxx" #include "document.hxx" #include "cell.hxx" #include "globstr.hrc" #include "global.hxx" #include "progress.hxx" #include #include "ftools.hxx" FltError ScFormatFilterPluginImpl::ScExportDif( SvStream& rStream, ScDocument* pDoc, const ScAddress& rOutPos, const CharSet eNach, sal_uInt32 nDifOption ) { SCCOL nEndCol; SCROW nEndRow; pDoc->GetTableArea( rOutPos.Tab(), nEndCol, nEndRow ); ScAddress aEnd( nEndCol, nEndRow, rOutPos.Tab() ); ScAddress aStart( rOutPos ); aStart.PutInOrder( aEnd ); return ScExportDif( rStream, pDoc, ScRange( aStart, aEnd ), eNach, nDifOption ); } FltError ScFormatFilterPluginImpl::ScExportDif( SvStream& rOut, ScDocument* pDoc, const ScRange&rRange, const CharSet eCharSet, sal_uInt32 nDifOption ) { DBG_ASSERT( rRange.aStart <= rRange.aEnd, "*ScExportDif(): Range unsortiert!" ); DBG_ASSERTWARNING( rRange.aStart.Tab() == rRange.aEnd.Tab(), "ScExportDif(): nur eine Tabelle bidde!" ); const CharSet eStreamCharSet = rOut.GetStreamCharSet(); if ( eStreamCharSet != eCharSet ) rOut.SetStreamCharSet( eCharSet ); sal_Unicode cStrDelim('"'); ByteString aStrDelimEncoded; // only used if not Unicode UniString aStrDelimDecoded; // only used if context encoding sal_Bool bContextOrNotAsciiEncoding; if ( eCharSet == RTL_TEXTENCODING_UNICODE ) { rOut.StartWritingUnicodeText(); bContextOrNotAsciiEncoding = sal_False; } else { aStrDelimEncoded = ByteString( cStrDelim, eCharSet ); rtl_TextEncodingInfo aInfo; aInfo.StructSize = sizeof(aInfo); if ( rtl_getTextEncodingInfo( eCharSet, &aInfo ) ) { bContextOrNotAsciiEncoding = (((aInfo.Flags & RTL_TEXTENCODING_INFO_CONTEXT) != 0) || ((aInfo.Flags & RTL_TEXTENCODING_INFO_ASCII) == 0)); if ( bContextOrNotAsciiEncoding ) aStrDelimDecoded = String( aStrDelimEncoded, eCharSet ); } else bContextOrNotAsciiEncoding = sal_False; } const sal_Char* p2DoubleQuotes_LF = "\"\"\n"; const sal_Char* pSpecDataType_LF = "-1,0\n"; const sal_Char* pEmptyData = "1,0\n\"\"\n"; const sal_Char* pStringData = "1,0\n"; const sal_Char* pNumData = "0,"; const sal_Char* pNumDataERROR = "0,0\nERROR\n"; FltError eRet = eERR_OK; String aOS; String aString; SCCOL nEndCol = rRange.aEnd.Col(); SCROW nEndRow = rRange.aEnd.Row(); SCCOL nNumCols = nEndCol - rRange.aStart.Col() + 1; SCROW nNumRows = nEndRow - rRange.aStart.Row() + 1; SCTAB nTab = rRange.aStart.Tab(); double fVal; const sal_Bool bPlain = ( nDifOption == SC_DIFOPT_PLAIN ); ScProgress aPrgrsBar( pDoc->GetDocumentShell(), ScGlobal::GetRscString( STR_LOAD_DOC ), nNumRows ); aPrgrsBar.SetState( 0 ); // TABLE DBG_ASSERT( pDoc->HasTable( nTab ), "*ScExportDif(): Tabelle nicht vorhanden!" ); aOS = pKeyTABLE; aOS.AppendAscii( "\n0,1\n\"" ); pDoc->GetName( nTab, aString ); aOS += aString; aOS.AppendAscii( "\"\n" ); rOut.WriteUnicodeOrByteText( aOS ); // VECTORS aOS = pKeyVECTORS; aOS.AppendAscii( "\n0," ); aOS += String::CreateFromInt32( nNumCols ); aOS += sal_Unicode('\n'); aOS.AppendAscii( p2DoubleQuotes_LF ); rOut.WriteUnicodeOrByteText( aOS ); // TUPLES aOS = pKeyTUPLES; aOS.AppendAscii( "\n0," ); aOS += String::CreateFromInt32( nNumRows ); aOS += sal_Unicode('\n'); aOS.AppendAscii( p2DoubleQuotes_LF ); rOut.WriteUnicodeOrByteText( aOS ); // DATA aOS = pKeyDATA; aOS.AppendAscii( "\n0,0\n" ); aOS.AppendAscii( p2DoubleQuotes_LF ); rOut.WriteUnicodeOrByteText( aOS ); SCCOL nColCnt; SCROW nRowCnt; ScBaseCell* pAkt; for( nRowCnt = rRange.aStart.Row() ; nRowCnt <= nEndRow ; nRowCnt++ ) { aOS.AssignAscii( pSpecDataType_LF ); aOS += pKeyBOT; aOS += sal_Unicode('\n'); rOut.WriteUnicodeOrByteText( aOS ); for( nColCnt = rRange.aStart.Col() ; nColCnt <= nEndCol ; nColCnt++ ) { bool bWriteStringData = false; pDoc->GetCell( nColCnt, nRowCnt, nTab, pAkt ); if( pAkt ) { switch( pAkt->GetCellType() ) { case CELLTYPE_NONE: case CELLTYPE_NOTE: aOS.AssignAscii( pEmptyData ); break; case CELLTYPE_VALUE: aOS.AssignAscii( pNumData ); if( bPlain ) { fVal = ( ( ScValueCell * ) pAkt )->GetValue(); aOS += String( ::rtl::math::doubleToUString( fVal, rtl_math_StringFormat_G, 14, '.', sal_True)); } else { pDoc->GetInputString( nColCnt, nRowCnt, nTab, aString ); aOS += aString; } aOS.AppendAscii( "\nV\n" ); break; case CELLTYPE_EDIT: ( ( ScEditCell* ) pAkt )->GetString( aString ); bWriteStringData = true; break; case CELLTYPE_STRING: ( ( ScStringCell* ) pAkt )->GetString( aString ); bWriteStringData = true; break; case CELLTYPE_FORMULA: if ( ((ScFormulaCell*)pAkt)->GetErrCode() ) aOS.AssignAscii( pNumDataERROR ); else if( pAkt->HasValueData() ) { aOS.AssignAscii( pNumData ); if( bPlain ) { fVal = ( ( ScFormulaCell * ) pAkt )->GetValue(); aOS += String( ::rtl::math::doubleToUString( fVal, rtl_math_StringFormat_G, 14, '.', sal_True)); } else { pDoc->GetInputString( nColCnt, nRowCnt, nTab, aString ); aOS += aString; } aOS.AppendAscii( "\nV\n" ); } else if( pAkt->HasStringData() ) { ( ( ScFormulaCell * ) pAkt )->GetString( aString ); bWriteStringData = true; } else aOS.AssignAscii( pNumDataERROR ); break; default:; } } else aOS.AssignAscii( pEmptyData ); if ( !bWriteStringData ) rOut.WriteUnicodeOrByteText( aOS ); else { // for an explanation why this complicated, see // sc/source/ui/docsh.cxx:ScDocShell::AsciiSave() // In fact we should create a common method if this would be // needed just one more time.. aOS.AssignAscii( pStringData ); rOut.WriteUnicodeOrByteText( aOS, eCharSet ); if ( eCharSet == RTL_TEXTENCODING_UNICODE ) { xub_StrLen nPos = aString.Search( cStrDelim ); while ( nPos != STRING_NOTFOUND ) { aString.Insert( cStrDelim, nPos ); nPos = aString.Search( cStrDelim, nPos+2 ); } rOut.WriteUniOrByteChar( cStrDelim, eCharSet ); rOut.WriteUnicodeText( aString ); rOut.WriteUniOrByteChar( cStrDelim, eCharSet ); } else if ( bContextOrNotAsciiEncoding ) { // to byte encoding ByteString aStrEnc( aString, eCharSet ); // back to Unicode UniString aStrDec( aStrEnc, eCharSet ); // search on re-decoded string xub_StrLen nPos = aStrDec.Search( aStrDelimDecoded ); while ( nPos != STRING_NOTFOUND ) { aStrDec.Insert( aStrDelimDecoded, nPos ); nPos = aStrDec.Search( aStrDelimDecoded, nPos+1+aStrDelimDecoded.Len() ); } // write byte re-encoded rOut.WriteUniOrByteChar( cStrDelim, eCharSet ); rOut.WriteUnicodeOrByteText( aStrDec, eCharSet ); rOut.WriteUniOrByteChar( cStrDelim, eCharSet ); } else { ByteString aStrEnc( aString, eCharSet ); // search on encoded string xub_StrLen nPos = aStrEnc.Search( aStrDelimEncoded ); while ( nPos != STRING_NOTFOUND ) { aStrEnc.Insert( aStrDelimEncoded, nPos ); nPos = aStrEnc.Search( aStrDelimEncoded, nPos+1+aStrDelimEncoded.Len() ); } // write byte encoded rOut.Write( aStrDelimEncoded.GetBuffer(), aStrDelimEncoded.Len() ); rOut.Write( aStrEnc.GetBuffer(), aStrEnc.Len() ); rOut.Write( aStrDelimEncoded.GetBuffer(), aStrDelimEncoded.Len() ); } rOut.WriteUniOrByteChar( '\n', eCharSet ); } } aPrgrsBar.SetState( nRowCnt ); } aOS.AssignAscii( pSpecDataType_LF ); aOS += pKeyEOD; aOS += sal_Unicode('\n'); rOut.WriteUnicodeOrByteText( aOS ); // restore original value rOut.SetStreamCharSet( eStreamCharSet ); return eRet; }