diff options
Diffstat (limited to 'sc/source/filter/dif/difexp.cxx')
-rw-r--r-- | sc/source/filter/dif/difexp.cxx | 279 |
1 files changed, 279 insertions, 0 deletions
diff --git a/sc/source/filter/dif/difexp.cxx b/sc/source/filter/dif/difexp.cxx new file mode 100644 index 000000000..89bafd754 --- /dev/null +++ b/sc/source/filter/dif/difexp.cxx @@ -0,0 +1,279 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#include <dif.hxx> +#include <document.hxx> +#include <formulacell.hxx> +#include <globstr.hrc> +#include <scresid.hxx> +#include <global.hxx> +#include <progress.hxx> +#include <rtl/tencinfo.h> +#include <ftools.hxx> +#include <cellvalue.hxx> +#include <rtl/strbuf.hxx> +#include <osl/diagnose.h> +#include <formula/errorcodes.hxx> +#include <tools/stream.hxx> + +void ScFormatFilterPluginImpl::ScExportDif( SvStream& rStream, ScDocument* pDoc, + const ScAddress& rOutPos, const rtl_TextEncoding eNach ) +{ + SCCOL nEndCol; + SCROW nEndRow; + pDoc->GetTableArea( rOutPos.Tab(), nEndCol, nEndRow ); + ScAddress aEnd( nEndCol, nEndRow, rOutPos.Tab() ); + ScAddress aStart( rOutPos ); + + aStart.PutInOrder( aEnd ); + + ScExportDif( rStream, pDoc, ScRange( aStart, aEnd ), eNach ); +} + +void ScFormatFilterPluginImpl::ScExportDif( SvStream& rOut, ScDocument* pDoc, + const ScRange&rRange, const rtl_TextEncoding eCharSet ) +{ + OSL_ENSURE( rRange.aStart <= rRange.aEnd, "*ScExportDif(): Range not sorted!" ); + OSL_ENSURE( rRange.aStart.Tab() == rRange.aEnd.Tab(), + "ScExportDif(): only one table please!" ); + + const rtl_TextEncoding eStreamCharSet = rOut.GetStreamCharSet(); + if ( eStreamCharSet != eCharSet ) + rOut.SetStreamCharSet( eCharSet ); + + sal_Unicode cStrDelim('"'); + OString aStrDelimEncoded; // only used if not Unicode + OUString aStrDelimDecoded; // only used if context encoding + bool bContextOrNotAsciiEncoding; + if ( eCharSet == RTL_TEXTENCODING_UNICODE ) + { + rOut.StartWritingUnicodeText(); + bContextOrNotAsciiEncoding = false; + } + else + { + aStrDelimEncoded = OString(&cStrDelim, 1, 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 = OStringToOUString(aStrDelimEncoded, eCharSet); + } + else + bContextOrNotAsciiEncoding = false; + } + + const char p2DoubleQuotes_LF[] = "\"\"\n"; + const char pSpecDataType_LF[] = "-1,0\n"; + const char pEmptyData[] = "1,0\n\"\"\n"; + const char pStringData[] = "1,0\n"; + const char pNumData[] = "0,"; + const char pNumDataERROR[] = "0,0\nERROR\n"; + + OUStringBuffer aOS; + OUString 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(); + + ScProgress aPrgrsBar( pDoc->GetDocumentShell(), ScResId( STR_LOAD_DOC ), nNumRows, true ); + + aPrgrsBar.SetState( 0 ); + + // TABLE + OSL_ENSURE( pDoc->HasTable( nTab ), "*ScExportDif(): Table not existent!" ); + + aOS.append(pKeyTABLE); + aOS.append("\n0,1\n\""); + + pDoc->GetName( nTab, aString ); + aOS.append(aString); + aOS.append("\"\n"); + rOut.WriteUnicodeOrByteText(aOS); + aOS.setLength(0); + + // VECTORS + aOS.append(pKeyVECTORS); + aOS.append("\n0,"); + aOS.append(static_cast<sal_Int32>(nNumCols)); + aOS.append('\n'); + aOS.append(p2DoubleQuotes_LF); + rOut.WriteUnicodeOrByteText(aOS); + aOS.setLength(0); + + // TUPLES + aOS.append(pKeyTUPLES); + aOS.append("\n0,"); + aOS.append(static_cast<sal_Int32>(nNumRows)); + aOS.append('\n'); + aOS.append(p2DoubleQuotes_LF); + rOut.WriteUnicodeOrByteText(aOS); + aOS.setLength(0); + + // DATA + aOS.append(pKeyDATA); + aOS.append("\n0,0\n"); + aOS.append(p2DoubleQuotes_LF); + rOut.WriteUnicodeOrByteText(aOS); + aOS.setLength(0); + + SCCOL nColCnt; + SCROW nRowCnt; + + for( nRowCnt = rRange.aStart.Row() ; nRowCnt <= nEndRow ; nRowCnt++ ) + { + assert( aOS.isEmpty() && "aOS should be empty"); + aOS.append(pSpecDataType_LF); + aOS.append(pKeyBOT); + aOS.append('\n'); + rOut.WriteUnicodeOrByteText(aOS); + aOS.setLength(0); + for( nColCnt = rRange.aStart.Col() ; nColCnt <= nEndCol ; nColCnt++ ) + { + assert( aOS.isEmpty() && "aOS should be empty"); + bool bWriteStringData = false; + ScRefCellValue aCell(*pDoc, ScAddress(nColCnt, nRowCnt, nTab)); + + switch (aCell.meType) + { + case CELLTYPE_NONE: + aOS.append(pEmptyData); + break; + case CELLTYPE_VALUE: + aOS.append(pNumData); + aString = pDoc->GetInputString( nColCnt, nRowCnt, nTab ); + aOS.append(aString); + aOS.append("\nV\n"); + break; + case CELLTYPE_EDIT: + case CELLTYPE_STRING: + aString = aCell.getString(pDoc); + bWriteStringData = true; + break; + case CELLTYPE_FORMULA: + if (aCell.mpFormula->GetErrCode() != FormulaError::NONE) + aOS.append(pNumDataERROR); + else if (aCell.mpFormula->IsValue()) + { + aOS.append(pNumData); + aString = pDoc->GetInputString( nColCnt, nRowCnt, nTab ); + aOS.append(aString); + aOS.append("\nV\n"); + } + else + { + aString = aCell.mpFormula->GetString().getString(); + bWriteStringData = true; + } + + break; + default:; + } + + if ( !bWriteStringData ) + { + rOut.WriteUnicodeOrByteText(aOS); + aOS.setLength(0); + } + 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... + assert( aOS.isEmpty() && "aOS should be empty"); + OUString aTmpStr = aString; + aOS.append(pStringData); + rOut.WriteUnicodeOrByteText(aOS, eCharSet); + aOS.setLength(0); + if ( eCharSet == RTL_TEXTENCODING_UNICODE ) + { + sal_Int32 nPos = aTmpStr.indexOf( cStrDelim ); + while ( nPos != -1 ) + { + aTmpStr = aTmpStr.replaceAt( nPos, 0, rtl::OUStringChar(cStrDelim) ); + nPos = aTmpStr.indexOf( cStrDelim, nPos+2 ); + } + rOut.WriteUniOrByteChar( cStrDelim, eCharSet ); + write_uInt16s_FromOUString(rOut, aTmpStr); + rOut.WriteUniOrByteChar( cStrDelim, eCharSet ); + } + else if ( bContextOrNotAsciiEncoding ) + { + // to byte encoding + OString aStrEnc = OUStringToOString(aTmpStr, eCharSet); + // back to Unicode + OUString aStrDec = OStringToOUString(aStrEnc, eCharSet); + // search on re-decoded string + sal_Int32 nPos = aStrDec.indexOf(aStrDelimDecoded); + while (nPos >= 0) + { + OUStringBuffer aBuf(aStrDec); + aBuf.insert(nPos, aStrDelimDecoded); + aStrDec = aBuf.makeStringAndClear(); + nPos = aStrDec.indexOf( + aStrDelimDecoded, nPos+1+aStrDelimDecoded.getLength()); + } + // write byte re-encoded + rOut.WriteUniOrByteChar( cStrDelim, eCharSet ); + rOut.WriteUnicodeOrByteText( aStrDec, eCharSet ); + rOut.WriteUniOrByteChar( cStrDelim, eCharSet ); + } + else + { + OString aStrEnc = OUStringToOString(aTmpStr, eCharSet); + // search on encoded string + sal_Int32 nPos = aStrEnc.indexOf(aStrDelimEncoded); + while (nPos >= 0) + { + OStringBuffer aBuf(aStrEnc); + aBuf.insert(nPos, aStrDelimEncoded); + aStrEnc = aBuf.makeStringAndClear(); + nPos = aStrEnc.indexOf( + aStrDelimEncoded, nPos+1+aStrDelimEncoded.getLength()); + } + // write byte encoded + rOut.WriteBytes(aStrDelimEncoded.getStr(), aStrDelimEncoded.getLength()); + rOut.WriteBytes(aStrEnc.getStr(), aStrEnc.getLength()); + rOut.WriteBytes(aStrDelimEncoded.getStr(), aStrDelimEncoded.getLength()); + } + rOut.WriteUniOrByteChar( '\n', eCharSet ); + } + } + aPrgrsBar.SetState( nRowCnt ); + } + + assert( aOS.isEmpty() && "aOS should be empty"); + aOS.append(pSpecDataType_LF); + aOS.append(pKeyEOD); + aOS.append('\n'); + rOut.WriteUnicodeOrByteText(aOS); + aOS.setLength(0); + + // restore original value + rOut.SetStreamCharSet( eStreamCharSet ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |