tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / filter / dif / difexp.cxx
blob3d769e5138f71275a313a369079418761c25ca5e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <dif.hxx>
21 #include <document.hxx>
22 #include <docsh.hxx>
23 #include <formulacell.hxx>
24 #include <globstr.hrc>
25 #include <scresid.hxx>
26 #include <global.hxx>
27 #include <progress.hxx>
28 #include <rtl/tencinfo.h>
29 #include <ftools.hxx>
30 #include <cellvalue.hxx>
31 #include <rtl/strbuf.hxx>
32 #include <osl/diagnose.h>
33 #include <formula/errorcodes.hxx>
34 #include <tools/stream.hxx>
36 void ScFormatFilterPluginImpl::ScExportDif( SvStream& rStream, ScDocument* pDoc,
37 const ScAddress& rOutPos, const rtl_TextEncoding eNach )
39 SCCOL nEndCol;
40 SCROW nEndRow;
41 pDoc->GetTableArea( rOutPos.Tab(), nEndCol, nEndRow );
42 ScAddress aEnd( nEndCol, nEndRow, rOutPos.Tab() );
43 ScAddress aStart( rOutPos );
45 aStart.PutInOrder( aEnd );
47 ScExportDif( rStream, pDoc, ScRange( aStart, aEnd ), eNach );
50 void ScFormatFilterPluginImpl::ScExportDif( SvStream& rOut, ScDocument* pDoc,
51 const ScRange&rRange, const rtl_TextEncoding eCharSet )
53 OSL_ENSURE( rRange.aStart <= rRange.aEnd, "*ScExportDif(): Range not sorted!" );
54 OSL_ENSURE( rRange.aStart.Tab() == rRange.aEnd.Tab(),
55 "ScExportDif(): only one table please!" );
57 const rtl_TextEncoding eStreamCharSet = rOut.GetStreamCharSet();
58 if ( eStreamCharSet != eCharSet )
59 rOut.SetStreamCharSet( eCharSet );
61 sal_Unicode cStrDelim('"');
62 OString aStrDelimEncoded; // only used if not Unicode
63 OUString aStrDelimDecoded; // only used if context encoding
64 bool bContextOrNotAsciiEncoding;
65 if ( eCharSet == RTL_TEXTENCODING_UNICODE )
67 rOut.StartWritingUnicodeText();
68 bContextOrNotAsciiEncoding = false;
70 else
72 aStrDelimEncoded = OString(&cStrDelim, 1, eCharSet);
73 rtl_TextEncodingInfo aInfo;
74 aInfo.StructSize = sizeof(aInfo);
75 if ( rtl_getTextEncodingInfo( eCharSet, &aInfo ) )
77 bContextOrNotAsciiEncoding =
78 (((aInfo.Flags & RTL_TEXTENCODING_INFO_CONTEXT) != 0) ||
79 ((aInfo.Flags & RTL_TEXTENCODING_INFO_ASCII) == 0));
80 if ( bContextOrNotAsciiEncoding )
81 aStrDelimDecoded = OStringToOUString(aStrDelimEncoded, eCharSet);
83 else
84 bContextOrNotAsciiEncoding = false;
87 const char p2DoubleQuotes_LF[] = "\"\"\n";
88 const char pSpecDataType_LF[] = "-1,0\n";
89 const char pEmptyData[] = "1,0\n\"\"\n";
90 const char pStringData[] = "1,0\n";
91 const char pNumData[] = "0,";
92 const char pNumDataERROR[] = "0,0\nERROR\n";
94 OUStringBuffer aOS;
95 OUString aString;
96 SCCOL nEndCol = rRange.aEnd.Col();
97 SCROW nEndRow = rRange.aEnd.Row();
98 SCCOL nNumCols = nEndCol - rRange.aStart.Col() + 1;
99 SCROW nNumRows = nEndRow - rRange.aStart.Row() + 1;
100 SCTAB nTab = rRange.aStart.Tab();
102 ScProgress aPrgrsBar( pDoc->GetDocumentShell(), ScResId( STR_LOAD_DOC ), nNumRows, true );
104 aPrgrsBar.SetState( 0 );
106 // TABLE
107 OSL_ENSURE( pDoc->HasTable( nTab ), "*ScExportDif(): Table not existent!" );
109 pDoc->GetName( nTab, aString );
110 aOS.append(OUString::Concat(pKeyTABLE)
111 + "\n0,1\n\""
112 + aString
113 + "\"\n");
114 rOut.WriteUnicodeOrByteText(aOS);
115 aOS.setLength(0);
117 // VECTORS
118 aOS.append(OUString::Concat(pKeyVECTORS)
119 + "\n0,"
120 + OUString::number(static_cast<sal_Int32>(nNumCols))
121 + "\n"
122 + p2DoubleQuotes_LF);
123 rOut.WriteUnicodeOrByteText(aOS);
124 aOS.setLength(0);
126 // TUPLES
127 aOS.append(OUString::Concat(pKeyTUPLES)
128 + "\n0,"
129 + OUString::number(static_cast<sal_Int32>(nNumRows))
130 + "\n"
131 + p2DoubleQuotes_LF);
132 rOut.WriteUnicodeOrByteText(aOS);
133 aOS.setLength(0);
135 // DATA
136 aOS.append(OUString::Concat(pKeyDATA)
137 + "\n0,0\n"
138 + p2DoubleQuotes_LF);
139 rOut.WriteUnicodeOrByteText(aOS);
140 aOS.setLength(0);
142 SCCOL nColCnt;
143 SCROW nRowCnt;
145 for( nRowCnt = rRange.aStart.Row() ; nRowCnt <= nEndRow ; nRowCnt++ )
147 assert( aOS.isEmpty() && "aOS should be empty");
148 aOS.append(OUString::Concat(pSpecDataType_LF)
149 + pKeyBOT
150 + "\n");
151 rOut.WriteUnicodeOrByteText(aOS);
152 aOS.setLength(0);
153 for( nColCnt = rRange.aStart.Col() ; nColCnt <= nEndCol ; nColCnt++ )
155 assert( aOS.isEmpty() && "aOS should be empty");
156 bool bWriteStringData = false;
157 ScRefCellValue aCell(*pDoc, ScAddress(nColCnt, nRowCnt, nTab));
159 switch (aCell.getType())
161 case CELLTYPE_NONE:
162 aOS.append(pEmptyData);
163 break;
164 case CELLTYPE_VALUE:
165 aString = pDoc->GetInputString( nColCnt, nRowCnt, nTab );
166 aOS.append(pNumData + aString + "\nV\n");
167 break;
168 case CELLTYPE_EDIT:
169 case CELLTYPE_STRING:
170 aString = aCell.getString(pDoc);
171 bWriteStringData = true;
172 break;
173 case CELLTYPE_FORMULA:
174 if (aCell.getFormula()->GetErrCode() != FormulaError::NONE)
175 aOS.append(pNumDataERROR);
176 else if (aCell.getFormula()->IsValue())
178 aString = pDoc->GetInputString( nColCnt, nRowCnt, nTab );
179 aOS.append(pNumData + aString + "\nV\n");
181 else
183 aString = aCell.getFormula()->GetString().getString();
184 bWriteStringData = true;
187 break;
188 default:;
191 if ( !bWriteStringData )
193 rOut.WriteUnicodeOrByteText(aOS);
194 aOS.setLength(0);
196 else
198 // for an explanation why this complicated, see
199 // sc/source/ui/docshell/docsh.cxx:ScDocShell::AsciiSave()
200 // In fact we should create a common method if this would be
201 // needed just one more time...
202 assert( aOS.isEmpty() && "aOS should be empty");
203 OUString aTmpStr = aString;
204 aOS.append(pStringData);
205 rOut.WriteUnicodeOrByteText(aOS, eCharSet);
206 aOS.setLength(0);
207 if ( eCharSet == RTL_TEXTENCODING_UNICODE )
209 // the goal is to replace cStrDelim by cStrDelim+cStrDelim
210 OUString strFrom(cStrDelim);
211 OUString strTo = strFrom + strFrom;
212 aTmpStr = aTmpStr.replaceAll(strFrom, strTo);
213 rOut.WriteUniOrByteChar( cStrDelim, eCharSet );
214 rOut.WriteUnicodeOrByteText(aTmpStr, eCharSet);
215 rOut.WriteUniOrByteChar( cStrDelim, eCharSet );
217 else if ( bContextOrNotAsciiEncoding )
219 // to byte encoding
220 OString aStrEnc = OUStringToOString(aTmpStr, eCharSet);
221 // back to Unicode
222 OUString aStrDec = OStringToOUString(aStrEnc, eCharSet);
223 // search on re-decoded string
224 OUString aStrTo = aStrDelimDecoded + aStrDelimDecoded;
225 aStrDec = aStrDec.replaceAll(aStrDelimDecoded, aStrTo);
226 // write byte re-encoded
227 rOut.WriteUniOrByteChar( cStrDelim, eCharSet );
228 rOut.WriteUnicodeOrByteText( aStrDec, eCharSet );
229 rOut.WriteUniOrByteChar( cStrDelim, eCharSet );
231 else
233 OString aStrEnc = OUStringToOString(aTmpStr, eCharSet);
234 // search on encoded string
235 OString aStrTo = aStrDelimEncoded + aStrDelimEncoded;
236 aStrEnc = aStrEnc.replaceAll(aStrDelimEncoded, aStrTo);
237 // write byte encoded
238 rOut.WriteBytes(aStrDelimEncoded.getStr(), aStrDelimEncoded.getLength());
239 rOut.WriteBytes(aStrEnc.getStr(), aStrEnc.getLength());
240 rOut.WriteBytes(aStrDelimEncoded.getStr(), aStrDelimEncoded.getLength());
242 rOut.WriteUniOrByteChar( '\n', eCharSet );
245 aPrgrsBar.SetState( nRowCnt );
248 assert( aOS.isEmpty() && "aOS should be empty");
249 aOS.append(OUString::Concat(pSpecDataType_LF)
250 + pKeyEOD
251 + "\n");
252 rOut.WriteUnicodeOrByteText(aOS);
253 aOS.setLength(0);
255 // restore original value
256 rOut.SetStreamCharSet( eStreamCharSet );
259 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */