LibreOffice Module sc (master)  1
qpro.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <sal/config.h>
21 #include <sal/log.hxx>
22 
23 #include <qproform.hxx>
24 #include <qpro.hxx>
25 #include <qprostyle.hxx>
26 
27 #include <scerrors.hxx>
28 #include <ftools.hxx>
29 #include <document.hxx>
30 #include <formulacell.hxx>
31 #include <tools/stream.hxx>
32 #include <unotools/configmgr.hxx>
33 #include <docoptio.hxx>
34 #include <scdll.hxx>
35 #include <memory>
36 
38 {
39  ErrCode eRet = ERRCODE_NONE;
40  sal_uInt8 nCol, nDummy;
41  sal_uInt16 nRow;
42  sal_uInt16 nStyle;
43  bool bEndOfSheet = false;
44 
45  SAL_INFO("sc", "Read sheet " << nTab);
46 
47  while( ERRCODE_NONE == eRet && !bEndOfSheet && nextRecord() )
48  {
49  switch( getId() )
50  {
51  case 0x000f:{ // Label cell
52  mpStream->ReadUChar( nCol ).ReadUChar( nDummy ).ReadUInt16( nRow ).ReadUInt16( nStyle ).ReadUChar( nDummy );
53  sal_uInt16 nLen = getLength();
54  if (nLen >= 7)
55  {
56  OUString aLabel(readString(nLen - 7));
57  nStyle = nStyle >> 3;
58  pStyle->SetFormat( &rDoc, nCol, nRow, nTab, nStyle );
59  rDoc.EnsureTable(nTab);
60  rDoc.SetTextCell(ScAddress(nCol,nRow,nTab), aLabel);
61  }
62  else
63  eRet = SCERR_IMPORT_FORMAT;
64  }
65  break;
66 
67  case 0x00cb: // End of sheet
68  bEndOfSheet = true;
69  break;
70 
71  case 0x000c: // Blank cell
72  mpStream->ReadUChar( nCol ).ReadUChar( nDummy ).ReadUInt16( nRow ).ReadUInt16( nStyle );
73  nStyle = nStyle >> 3;
74  pStyle->SetFormat( &rDoc, nCol, nRow, nTab, nStyle );
75  break;
76 
77  case 0x000d:{ // Integer cell
78  sal_Int16 nValue;
79  mpStream->ReadUChar( nCol ).ReadUChar( nDummy ).ReadUInt16( nRow ).ReadUInt16( nStyle ).ReadInt16( nValue );
80  nStyle = nStyle >> 3;
81  pStyle->SetFormat( &rDoc, nCol, nRow, nTab, nStyle );
82  rDoc.EnsureTable(nTab);
83  rDoc.SetValue(ScAddress(nCol,nRow,nTab), static_cast<double>(nValue));
84  }
85  break;
86 
87  case 0x000e:{ // Floating point cell
88  double nValue;
89  mpStream->ReadUChar( nCol ).ReadUChar( nDummy ).ReadUInt16( nRow ).ReadUInt16( nStyle ).ReadDouble( nValue );
90  nStyle = nStyle >> 3;
91  pStyle->SetFormat( &rDoc, nCol, nRow, nTab, nStyle );
92  rDoc.EnsureTable(nTab);
93  rDoc.SetValue(ScAddress(nCol,nRow,nTab), nValue);
94  }
95  break;
96 
97  case 0x0010:
98  {
99  // Formula cell
100  double nValue;
101  sal_uInt16 nState, nLen;
102  mpStream->ReadUChar( nCol ).ReadUChar( nDummy ).ReadUInt16( nRow ).ReadUInt16( nStyle ).ReadDouble( nValue ).ReadUInt16( nState ).ReadUInt16( nLen );
103  if (!mpStream->good())
104  {
105  eRet = SCERR_IMPORT_FORMAT;
106  break;
107  }
108  ScAddress aAddr( nCol, nRow, nTab );
109  std::unique_ptr<ScTokenArray> pArray;
110 
111  QProToSc aConv(*mpStream, rDoc.GetSharedStringPool(), aAddr);
112  if (ConvErr::OK != aConv.Convert( rDoc, pArray ))
113  eRet = SCERR_IMPORT_FORMAT;
114  else
115  {
116  ScFormulaCell* pFormula = new ScFormulaCell(rDoc, aAddr, std::move(pArray));
117  nStyle = nStyle >> 3;
118  pFormula->AddRecalcMode( ScRecalcMode::ONLOAD_ONCE );
119  pStyle->SetFormat( &rDoc, nCol, nRow, nTab, nStyle );
120  rDoc.EnsureTable(nTab);
121  rDoc.SetFormulaCell(ScAddress(nCol,nRow,nTab), pFormula);
122  }
123  }
124  break;
125  }
126  }
127  return eRet;
128 }
129 
131 {
132  ScQProReader aReader(pStream);
133  ErrCode eRet = aReader.import(rDoc);
134  return eRet;
135 }
136 
138  : mnId(0)
139  , mnLength(0)
140  , mnOffset(0)
141  , mpStream(pStream)
142  , mbEndOfFile(false)
143  , mnMaxTab(utl::ConfigManager::IsFuzzing() ? 128 : MAXTAB)
144 {
145  if( mpStream )
146  {
147  mpStream->SetBufferSize( 65535 );
148  mpStream->SetStreamCharSet( RTL_TEXTENCODING_MS_1252 );
149  }
150 }
151 
153 {
154  if( mpStream )
155  mpStream->SetBufferSize( 0 );
156 }
157 
159 {
160  ErrCode eRet = ERRCODE_NONE;
161  sal_uInt16 nVersion;
162  sal_uInt16 i = 1, j = 1;
163  SCTAB nTab = 0;
164  SetEof( false );
165 
166  if( !recordsLeft() )
167  return SCERR_IMPORT_OPEN;
168 
169  std::unique_ptr<ScQProStyle> pStyleElement( new ScQProStyle );
170 
171  while( nextRecord() && eRet == ERRCODE_NONE)
172  {
173  switch( getId() )
174  {
175  case 0x0000: // Beginning of file
176  mpStream->ReadUInt16( nVersion );
177  break;
178 
179  case 0x00ca: // Beginning of sheet
180  if (nTab <= mnMaxTab)
181  {
182  if( nTab < 26 )
183  {
184  OUString aName = OUStringChar( sal_Unicode('A' + nTab) );
185  if (!nTab)
186  rDoc.RenameTab( nTab, aName );
187  else
188  rDoc.InsertTab( nTab, aName );
189  }
190  eRet = readSheet( nTab, rDoc, pStyleElement.get() );
191  nTab++;
192  }
193  break;
194 
195  case 0x0001: // End of file
196  SetEof( true );
197  break;
198 
199  case 0x00ce:{ // Attribute cell
200  sal_uInt8 nFormat, nAlign, nFont;
201  sal_Int16 nColor;
202  mpStream->ReadUChar( nFormat ).ReadUChar( nAlign ).ReadInt16( nColor ).ReadUChar( nFont );
203  pStyleElement->setAlign( i, nAlign );
204  pStyleElement->setFont( i, nFont );
205  i++;
206  }
207  break;
208 
209  case 0x00cf:{ // Font description
210  sal_uInt16 nPtSize, nFontAttr;
211  OUString aLabel;
212  mpStream->ReadUInt16( nPtSize ).ReadUInt16( nFontAttr );
213  pStyleElement->setFontRecord( j, nFontAttr, nPtSize );
214  sal_uInt16 nLen = getLength();
215  if (nLen >= 4)
216  aLabel = readString(nLen - 4);
217  else
218  eRet = SCERR_IMPORT_FORMAT;
219  pStyleElement->setFontType( j, aLabel );
220  j++;
221  }
222  break;
223  }
224  }
225  return eRet;
226 }
227 
229 {
230  ErrCode eRet = parse(rDoc);
231  rDoc.CalcAfterLoad();
232  return eRet;
233 }
234 
235 extern "C" SAL_DLLPUBLIC_EXPORT bool TestImportQPW(SvStream &rStream)
236 {
237  ScDLL::Init();
239  ScDocOptions aDocOpt = aDocument.GetDocOptions();
240  aDocOpt.SetLookUpColRowNames(false);
241  aDocument.SetDocOptions(aDocOpt);
242  aDocument.MakeTable(0);
243  aDocument.EnableExecuteLink(false);
244  aDocument.SetInsertingFromOtherDoc(true);
245  aDocument.SetImportingXML(true);
247 
248  ScQProReader aReader(&rStream);
249  ErrCode eRet = aReader.parse(aDocument);
250  return eRet == ERRCODE_NONE;
251 }
252 
254 {
255  return mpStream && mpStream->good();
256 }
257 
259 {
260  if( !recordsLeft() )
261  return false;
262 
263  if( mbEndOfFile )
264  return false;
265 
266  sal_uInt32 nPos = mpStream->Tell();
267  if( nPos != mnOffset + mnLength )
269 
270  mnLength = mnId = 0;
272 
273  mnOffset = mpStream->Tell();
274 #ifdef DEBUG_SC_QPRO
275  fprintf( stderr, "Read record 0x%x length 0x%x at offset 0x%x\n",
276  (unsigned)mnId, (unsigned)mnLength, (unsigned)mnOffset );
277 
278 #if 1 // rather verbose
279  int len = mnLength;
280  while (len > 0) {
281  int i, chunk = std::min(len, 16);
282  unsigned char data[16];
283  mpStream->Read( data, chunk );
284 
285  for (i = 0; i < chunk; i++)
286  fprintf( stderr, "%.2x ", data[i] );
287  fprintf( stderr, "| " );
288  for (i = 0; i < chunk; i++)
289  fprintf( stderr, "%c", data[i] < 127 && data[i] > 30 ? data[i] : '.' );
290  fprintf( stderr, "\n" );
291 
292  len -= chunk;
293  }
294  mpStream->Seek( mnOffset );
295 #endif
296 #endif
297  return true;
298 }
299 
300 OUString ScQProReader::readString(sal_uInt16 nLength)
301 {
303 }
304 
305 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_uInt32 mnOffset
Definition: qpro.hxx:37
SvStream & ReadInt16(sal_Int16 &rInt16)
OUString readString(sal_uInt16 nLength)
Definition: qpro.cxx:300
SC_DLLPUBLIC svl::SharedStringPool & GetSharedStringPool()
Definition: documen2.cxx:563
ScriptDocument aDocument
SvStream & ReadUInt16(sal_uInt16 &rUInt16)
~ScQProReader()
Definition: qpro.cxx:152
sal_uInt64 Seek(sal_uInt64 nPos)
virtual ErrCode ScImportQuattroPro(SvStream *pStream, ScDocument &rDoc) override
Definition: qpro.cxx:130
SC_DLLPUBLIC void SetValue(SCCOL nCol, SCROW nRow, SCTAB nTab, const double &rVal)
Definition: document.cxx:3458
sal_uInt16 mnId
void SetHardRecalcState(HardRecalcState eVal)
Definition: document.hxx:2301
SC_DLLPUBLIC void SetTextCell(const ScAddress &rPos, const OUString &rStr)
Call this if you are not sure whether to put this as an edit text or a simple text.
Definition: document.cxx:3431
SC_DLLPUBLIC void SetImportingXML(bool bVal)
Definition: documen9.cxx:590
sal_uInt16 sal_Unicode
SC_DLLPUBLIC bool RenameTab(SCTAB nTab, const OUString &rName, bool bExternalDocument=false)
Definition: document.cxx:853
SvStream * mpStream
Definition: qpro.hxx:38
ErrCode parse(ScDocument &rDoc)
Definition: qpro.cxx:158
void SetLookUpColRowNames(bool bVal)
Definition: docoptio.hxx:53
bool recordsLeft()
Definition: qpro.cxx:253
void SetInsertingFromOtherDoc(bool bVal)
Definition: document.hxx:2133
SC_DLLPUBLIC const ScDocOptions & GetDocOptions() const
Definition: documen3.cxx:1923
void EnableExecuteLink(bool bVal)
Definition: document.hxx:1539
int i
ErrCode import(ScDocument &rDoc)
Definition: qpro.cxx:228
static SC_DLLPUBLIC void Init()
DLL-init/exit-code must be linked to the DLL only.
Definition: scdll.cxx:105
ScQProReader(SvStream *pStream)
Definition: qpro.cxx:137
sal_uInt16 getLength() const
Definition: qpro.hxx:50
SC_DLLPUBLIC bool InsertTab(SCTAB nPos, const OUString &rName, bool bExternalDocument=false, bool bUndoDeleteTab=false)
Definition: document.cxx:504
ErrCode readSheet(SCTAB nTab, ScDocument &rDoc, ScQProStyle *pStyle)
Definition: qpro.cxx:37
void SetBufferSize(sal_uInt16 m_nBufSize)
SvStream & ReadUChar(unsigned char &rChar)
sal_uInt16 mnId
Definition: qpro.hxx:35
sal_Int16 nVersion
const SCTAB MAXTAB
Definition: address.hxx:71
SvStream & ReadDouble(double &rDouble)
sal_uInt16 mnLength
Definition: qpro.hxx:36
#define SCERR_IMPORT_OPEN
Definition: scerrors.hxx:27
exports com.sun.star.chart2. data
SC_DLLPUBLIC void EnsureTable(SCTAB nTab)
Definition: documen2.cxx:537
SC_DLLPUBLIC void CalcAfterLoad(bool bStartListening=true)
Definition: document.cxx:4026
void SetFormat(ScDocument *pDoc, sal_uInt8 nCol, sal_uInt16 nRow, SCTAB nTab, sal_uInt16 nStyle)
Definition: qprostyle.cxx:39
SC_DLLPUBLIC ScFormulaCell * SetFormulaCell(const ScAddress &rPos, ScFormulaCell *pCell)
Set formula cell, and transfer its ownership to the document.
Definition: documen2.cxx:1081
void SetEof(bool bValue)
Definition: qpro.hxx:47
SC_DLLPUBLIC void SetDocOptions(const ScDocOptions &rOpt)
Definition: documen3.cxx:1929
SAL_DLLPUBLIC_EXPORT bool TestImportQPW(SvStream &rStream)
Definition: qpro.cxx:235
bool mbEndOfFile
Definition: qpro.hxx:39
#define ERRCODE_NONE
unsigned char sal_uInt8
CalcAll() without broadcast/notify but setting up new listeners.
#define SAL_INFO(area, stream)
OUString aName
void SetStreamCharSet(rtl_TextEncoding eCharSet)
rtl_TextEncoding GetStreamCharSet() const
OUString aLabel
sal_uInt64 Tell() const
const SCTAB mnMaxTab
Definition: qpro.hxx:40
#define SCERR_IMPORT_FORMAT
Definition: scerrors.hxx:34
bool good() const
SC_DLLPUBLIC void MakeTable(SCTAB nTab, bool _bNeedsNameCheck=true)
Definition: document.cxx:168
OUString read_uInt8s_ToOUString(SvStream &rStrm, std::size_t nUnits, rtl_TextEncoding eEnc)
bool nextRecord()
Definition: qpro.cxx:258
void AddRecalcMode(ScRecalcMode)
sal_Int32 nState
sal_uInt16 nPos
sal_Int16 SCTAB
Definition: types.hxx:23
sal_Int16 nValue
sal_uInt16 getId() const
Definition: qpro.hxx:49