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_scfilt.hxx"
26
27 #include <sal/config.h>
28 #include <stdio.h>
29 #include <sfx2/docfile.hxx>
30
31 #include "qproform.hxx"
32 #include "qpro.hxx"
33 #include "qprostyle.hxx"
34
35 #include "global.hxx"
36 #include "scerrors.hxx"
37 #include "docpool.hxx"
38 #include "patattr.hxx"
39 #include "filter.hxx"
40 #include "document.hxx"
41 #include "cell.hxx"
42 #include "biff.hxx"
43 #include <tools/stream.hxx>
44
readSheet(SCTAB nTab,ScDocument * pDoc,ScQProStyle * pStyle)45 FltError ScQProReader::readSheet( SCTAB nTab, ScDocument* pDoc, ScQProStyle *pStyle )
46 {
47 FltError eRet = eERR_OK;
48 sal_uInt8 nCol, nDummy;
49 sal_uInt16 nRow;
50 sal_uInt16 nStyle;
51 bool bEndOfSheet = false;
52
53 #ifdef DEBUG
54 fprintf( stderr, "Read sheet (%d)\n", nTab );
55 #endif
56
57 while( eERR_OK == eRet && !bEndOfSheet && nextRecord() )
58 {
59 switch( getId() )
60 {
61 case 0x000f:{ // Label cell
62 String aLabel;
63 *mpStream >> nCol >> nDummy >> nRow >> nStyle >> nDummy;
64 sal_uInt16 nLen = getLength();
65 if (nLen >= 7)
66 {
67 readString( aLabel, nLen - 7 );
68 nStyle = nStyle >> 3;
69 pStyle->SetFormat( pDoc, nCol, nRow, nTab, nStyle );
70 pDoc->PutCell( nCol, nRow, nTab, ScBaseCell::CreateTextCell( aLabel, pDoc ), (sal_Bool) sal_True );
71 }
72 else
73 eRet = eERR_FORMAT;
74 }
75 break;
76
77 case 0x00cb: // End of sheet
78 bEndOfSheet = true;
79 break;
80
81 case 0x000c: // Blank cell
82 *mpStream >> nCol >> nDummy >> nRow >> nStyle;
83 nStyle = nStyle >> 3;
84 pStyle->SetFormat( pDoc, nCol, nRow, nTab, nStyle );
85 break;
86
87 case 0x000d:{ // Integer cell
88 sal_Int16 nValue;
89 *mpStream >> nCol >> nDummy >> nRow >> nStyle >> nValue;
90 ScValueCell* pInteger = new ScValueCell( ( double ) nValue );
91 nStyle = nStyle >> 3;
92 pStyle->SetFormat( pDoc, nCol, nRow, nTab, nStyle );
93 pDoc->PutCell(nCol ,nRow, nTab ,pInteger,(sal_Bool) sal_True);
94 }
95 break;
96
97 case 0x000e:{ // Floating point cell
98 double nValue;
99 *mpStream >> nCol >> nDummy >> nRow >> nStyle >> nValue;
100 ScValueCell* pFloat = new ScValueCell( nValue );
101 nStyle = nStyle >> 3;
102 pStyle->SetFormat( pDoc, nCol, nRow, nTab, nStyle );
103 pDoc->PutCell( nCol, nRow, nTab, pFloat, (sal_Bool) sal_True );
104 }
105 break;
106
107 case 0x0010:{ // Formula cell
108 double nValue;
109 sal_uInt16 nState, nLen;
110 *mpStream >> nCol >> nDummy >> nRow >> nStyle >> nValue >> nState >> nLen;
111 ScAddress aAddr( nCol, nRow, nTab );
112 const ScTokenArray *pArray;
113 QProToSc aConv( *mpStream, aAddr );
114 if (ConvOK != aConv.Convert( pArray, nLen ))
115 eRet = eERR_FORMAT;
116 else
117 {
118 ScFormulaCell *pFormula = new ScFormulaCell( pDoc, aAddr, pArray );
119 nStyle = nStyle >> 3;
120 pFormula->AddRecalcMode( RECALCMODE_ONLOAD_ONCE );
121 pStyle->SetFormat( pDoc, nCol, nRow, nTab, nStyle );
122 pDoc->PutCell( nCol, nRow, nTab, pFormula, ( sal_Bool ) sal_True );
123 }
124 }
125 break;
126 }
127 }
128 return eRet;
129 }
130
ScImportQuattroPro(SfxMedium & rMedium,ScDocument * pDoc)131 FltError ScFormatFilterPluginImpl::ScImportQuattroPro( SfxMedium &rMedium, ScDocument *pDoc )
132 {
133 FltError eRet = eERR_OK;
134 ScQProReader aReader( rMedium );
135 eRet = aReader.import( pDoc );
136 return eRet;
137 }
138
ScQProReader(SfxMedium & rMedium)139 ScQProReader::ScQProReader( SfxMedium &rMedium ):
140 ScBiffReader( rMedium )
141 {
142 }
143
import(ScDocument * pDoc)144 FltError ScQProReader::import( ScDocument *pDoc )
145 {
146 FltError eRet = eERR_OK;
147 sal_uInt16 nVersion;
148 sal_uInt16 i = 1, j = 1;
149 SCTAB nTab = 0;
150 SetEof( sal_False );
151
152 if( !recordsLeft() )
153 return eERR_OPEN;
154
155 ScQProStyle *pStyleElement = new ScQProStyle;
156
157 while( nextRecord() && eRet == eERR_OK)
158 {
159 switch( getId() )
160 {
161 case 0x0000: // Begginning of file
162 *mpStream >> nVersion;
163 break;
164
165 case 0x00ca: // Beginning of sheet
166 if( nTab <= MAXTAB )
167 {
168 if( nTab < 26 )
169 {
170 String aName;
171 aName.Append( sal_Unicode( 'A' + nTab ) );
172 if (!nTab)
173 pDoc->RenameTab( nTab, aName, sal_False, sal_False);
174 else
175 pDoc->InsertTab( nTab, aName );
176 }
177 eRet = readSheet( nTab, pDoc, pStyleElement );
178 nTab++;
179 }
180 break;
181
182 case 0x0001: // End of file
183 SetEof( sal_True );
184 break;
185
186 case 0x00ce:{ // Attribute cell
187 sal_uInt8 nFormat, nAlign, nFont;
188 sal_Int16 nColor;
189 *mpStream >> nFormat >> nAlign >> nColor >> nFont;
190 pStyleElement->setAlign( i, nAlign );
191 pStyleElement->setFont( i, nFont );
192 i++;
193 }
194 break;
195
196 case 0x00cf:{ // Font description
197 sal_uInt16 nPtSize, nFontAttr;
198 String aLabel;
199 *mpStream >> nPtSize >> nFontAttr;
200 pStyleElement->setFontRecord( j, nFontAttr, nPtSize );
201 sal_uInt16 nLen = getLength();
202 if (nLen >= 4)
203 readString( aLabel, nLen - 4 );
204 else
205 eRet = eERR_FORMAT;
206 pStyleElement->setFontType( j, aLabel );
207 j++;
208 }
209 break;
210 }
211 }
212 pDoc->CalcAfterLoad();
213 delete pStyleElement;
214 return eRet;
215 }
216
recordsLeft()217 bool ScQProReader::recordsLeft()
218 {
219 bool bValue = ScBiffReader::recordsLeft();
220 return bValue;
221 }
222
nextRecord()223 bool ScQProReader::nextRecord()
224 {
225 bool bValue = ScBiffReader::nextRecord();
226 return bValue;
227 }
228
readString(String & rString,sal_uInt16 nLength)229 void ScQProReader::readString( String &rString, sal_uInt16 nLength )
230 {
231 sal_Char* pText = new sal_Char[ nLength + 1 ];
232 mpStream->Read( pText, nLength );
233 pText[ nLength ] = 0;
234 rString = String( pText, mpStream->GetStreamCharSet() );
235 delete [] pText;
236 }
237