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_sc.hxx"
26
27
28
29 //------------------------------------------------------------------------
30
31 #include <tools/debug.hxx>
32
33 #include "dociter.hxx"
34 #include "cell.hxx"
35 #include "document.hxx"
36
37 #include "exp_op.hxx"
38
39 #if ENABLE_LOTUS123_EXPORT
40 const sal_uInt16 ExportWK1::WK1MAXCOL = 255;
41 const sal_uInt16 ExportWK1::WK1MAXROW = 8191;
42
GenFormByte(const ScPatternAttr &)43 sal_uInt8 ExportWK1::GenFormByte( const ScPatternAttr& /*aAttr*/ )
44 {
45 return 0xFF;
46 }
47
48
Bof()49 inline void ExportWK1::Bof()
50 { // (0x00)
51 aOut << ( sal_uInt16 ) 0x00 << ( sal_uInt16 ) 2 << ( sal_uInt16 ) 0x0406; // Version 1-2-3/2, Symhony/1.1
52 }
53
54
Eof()55 inline void ExportWK1::Eof()
56 { // (0x01)
57 aOut << ( sal_uInt16 ) 0x01 << ( sal_uInt16 ) 0;
58 }
59
60
Calcmode()61 inline void ExportWK1::Calcmode()
62 { // (0x02)
63 // Calculationmode = automatic
64 aOut << ( sal_uInt16 ) 0x02 << ( sal_uInt16 ) 1 << ( sal_uInt8 ) 0xFF;
65 }
66
67
Calcorder()68 inline void ExportWK1::Calcorder()
69 { // (0x03)
70 // order = natural
71 aOut << ( sal_uInt16 ) 0x03 << ( sal_uInt16 ) 1 << ( sal_uInt8 ) 0x00;
72 }
73
74
Split()75 inline void ExportWK1::Split()
76 { // (0x04)
77 // not split
78 aOut << ( sal_uInt16 ) 0x04 << ( sal_uInt16 ) 1 << ( sal_uInt8 ) 0x00;
79 }
80
81
Sync()82 inline void ExportWK1::Sync()
83 { // (0x05)
84 // not synchronized
85 aOut << ( sal_uInt16 ) 0x05 << ( sal_uInt16 ) 1 << ( sal_uInt8 ) 0x00;
86 }
87
88
Dimensions()89 inline void ExportWK1::Dimensions()
90 { // (0x06)
91 SCCOL nEndCol;
92 SCROW nEndRow;
93 aOut << ( sal_uInt16 ) 0x06 << ( sal_uInt16 ) 8 << ( sal_uInt16 ) 0 << ( sal_uInt16 ) 0; // Starting Col/Row
94 pD->GetPrintArea( 0, nEndCol, nEndRow );
95 #if SC_ROWLIMIT_MORE_THAN_64K
96 #error row limit 64k
97 #endif
98 sal_uInt16 nCol = static_cast<sal_uInt16>(nEndCol);
99 sal_uInt16 nRow = static_cast<sal_uInt16>(nEndRow);
100 DBG_ASSERT( nCol <= WK1MAXCOL, "ExportWK1::Dimensions(): Col > WK1MAXCOL" );
101 DBG_ASSERT( nRow <= WK1MAXROW, "ExportWK1::Dimensions(): Row > WK1MAXROW" );
102 aOut << nCol << nRow; // Ending Col/Row
103 }
104
105
Window1()106 inline void ExportWK1::Window1()
107 { // (0x07)
108 aOut << ( sal_uInt16 ) 0x07 << ( sal_uInt16 ) 32
109 << ( sal_uInt16 ) 0 << ( sal_uInt16 ) 0 // Cursor Col/Row
110 << ( sal_uInt8 ) 0xFF // Format: protected, special, default
111 << ( sal_uInt8 ) 0 // Dummy
112 << ( sal_uInt16 ) 9 // Default column width
113 << ( sal_uInt16 ) 8 << ( sal_uInt16 ) 14// Number of cols/rows on screen
114 << ( sal_uInt16 ) 0 << ( sal_uInt16 ) 0 // Left col / top row
115 // Rest aus Doku-Beispiel
116 << ( sal_uInt16 ) 0 << ( sal_uInt16 ) 0 // Number of title cols / rows
117 << ( sal_uInt16 ) 0 << ( sal_uInt16 ) 0 // Left title col / top title row
118 << ( sal_uInt16 ) 0x0004 << ( sal_uInt16 ) 0x0004// Top-left col / row
119 << ( sal_uInt16 ) 0x0048 // Number of cols in window
120 << ( sal_uInt16 ) 0x00; // Dummy
121 }
122
123
Colw()124 inline void ExportWK1::Colw()
125 { // (0x08)
126 // ACHTUNG: muss nach Window1 und vor hidden cols record kommen!
127 sal_uInt16 nWidth;
128 sal_uInt8 nWidthSpaces;
129 for( sal_uInt16 nCol = 0 ; nCol < 256 ; nCol++ )
130 {
131 nWidth = pD->GetColWidth( static_cast<SCCOL>(nCol), 0 );
132 nWidthSpaces = ( sal_uInt8 ) ( nWidth / TWIPS_PER_CHAR );
133 aOut << ( sal_uInt16 ) 0x08 << ( sal_uInt16 ) 3 << nCol << nWidthSpaces;
134 }
135 }
136
137
Blank(const sal_uInt16 nCol,const sal_uInt16 nRow,const ScPatternAttr & aAttr)138 void ExportWK1::Blank( const sal_uInt16 nCol, const sal_uInt16 nRow, const ScPatternAttr& aAttr )
139 { // (0x0C)
140 // PREC: nCol <= WK1MAXCOL, nRow <= WK1MAXROW
141 DBG_ASSERT( nCol <= WK1MAXCOL, "ExportWK1::Blank(): Col > WK1MAXCOL" );
142 DBG_ASSERT( nRow <= WK1MAXROW, "ExportWK1::Blank(): Row > WK1MAXROW" );
143
144 aOut << ( sal_uInt16 ) 0x0C << ( sal_uInt16 ) 5 << GenFormByte( aAttr ) << nCol << nRow;
145 }
146
147
Number(const sal_uInt16 nCol,const sal_uInt16 nRow,const double fWert,const ScPatternAttr & aAttr)148 void ExportWK1::Number( const sal_uInt16 nCol, const sal_uInt16 nRow, const double fWert, const ScPatternAttr &aAttr )
149 { // (0x0E)
150 // PREC: nCol <= WK1MAXCOL, nRow <= WK1MAXROW
151 DBG_ASSERT( nCol <= WK1MAXCOL, "ExportWK1::Number(): Col > WK1MAXCOL" );
152 DBG_ASSERT( nRow <= WK1MAXROW, "ExportWK1::Number(): Row > WK1MAXROW" );
153
154 aOut << ( sal_uInt16 ) 0x0E << ( sal_uInt16 ) 13 << GenFormByte( aAttr ) << nCol << nRow << fWert;
155 }
156
157
Label(const sal_uInt16 nCol,const sal_uInt16 nRow,const String & rStr,const ScPatternAttr & aAttr)158 void ExportWK1::Label( const sal_uInt16 nCol, const sal_uInt16 nRow, const String& rStr, const ScPatternAttr& aAttr )
159 { // (0x0F)
160 // PREC: nCol <= WK1MAXCOL, nRow <= WK1MAXROW
161 DBG_ASSERT( nCol <= WK1MAXCOL, "ExportWK1::Label(): Col > WK1MAXCOL" );
162 DBG_ASSERT( nRow <= WK1MAXROW, "ExportWK1::Label(): Row > WK1MAXROW" );
163
164 ByteString aStr( rStr, eZielChar );
165
166 sal_uInt16 nLaenge = 7; // Anzahl Bytes vor String+Nullbyte am Ende + Alignment-Char
167
168 xub_StrLen nAnz = aStr.Len();
169
170
171 if( nAnz > 240 ) // max. 240 Zeichen im String
172 nAnz = 240;
173
174 nLaenge = nLaenge + ( sal_uInt16 ) nAnz; // + Stringlaenge
175
176 aOut << ( sal_uInt16 ) 0x0F << nLaenge << GenFormByte( aAttr ) << nCol << nRow << ( sal_Char ) '\'';
177 // ACHTUNG: ZUNAECHST NUR LEFT ALIGNMENT
178
179 aOut.Write( aStr.GetBuffer(), nAnz );
180
181 aOut << ( sal_uInt8 ) 0x00; // ...und Nullterminator anhaengen
182 }
183
184
Formula(const sal_uInt16 nCol,const sal_uInt16 nRow,const ScFormulaCell * pFC,const ScPatternAttr & aAttr)185 void ExportWK1::Formula( const sal_uInt16 nCol, const sal_uInt16 nRow, const ScFormulaCell* pFC, const ScPatternAttr& aAttr )
186 { // (0x10)
187 // PREC: nCol <= WK1MAXCOL, nRow <= WK1MAXROW
188 DBG_ASSERT( nCol <= WK1MAXCOL, "ExportWK1::Formula(): Col > WK1MAXCOL" );
189 DBG_ASSERT( nRow <= WK1MAXROW, "ExportWK1::Formula(): Row > WK1MAXROW" );
190
191 sal_uInt16 nLaenge = 15; // Bytes bis Formel
192 double fErgebnis;
193
194 // zunaechst nur Dummy-Angaben (Formel := Ergebnis der Berechnung )
195 nLaenge += 9+1;
196
197 fErgebnis = ( ( ScFormulaCell* ) pFC )->GetValue();
198
199 aOut << ( sal_uInt16 ) 0x10 << ( sal_uInt16 ) nLaenge
200 << GenFormByte( aAttr ) << nCol << nRow
201 << fErgebnis
202 << ( sal_uInt16 ) 9+1 // Dummy-Formula-Size
203 << ( sal_uInt8 ) 0x00 // constant, floating point
204 << fErgebnis
205 << ( sal_uInt8 ) 0x03; // return
206 }
207
208
Protect()209 inline void ExportWK1::Protect()
210 { // (0x24)
211 //Global protection off
212 aOut << ( sal_uInt16 ) 0x24 << ( sal_uInt16 ) 1 << ( sal_uInt8 ) 0x00;
213 }
214
215
Footer()216 inline void ExportWK1::Footer()
217 { // (0x25)
218 // zunaechst nur leerer C-String
219 aOut << ( sal_uInt16 ) 0x25 << ( sal_uInt16 ) 242 << ( sal_Char ) '\''; // linksbuendiger leerer String
220 for( short nLauf = 0 ; nLauf < 241 ; nLauf++ )
221 aOut << ( sal_uInt8 ) 0x00;
222 }
223
224
Header()225 inline void ExportWK1::Header()
226 { // (0x26)
227 // zunaechst nur leerer C-String
228 aOut << ( sal_uInt16 ) 0x26 << ( sal_uInt16 ) 242 << ( sal_Char ) '\''; // linksbuendiger leerer String
229 for( short nLauf = 0 ; nLauf < 241 ; nLauf++ )
230 aOut << ( sal_uInt8 ) 0x00;
231 }
232
233
Margins()234 inline void ExportWK1::Margins()
235 { // (0x28)
236 aOut << ( sal_uInt16 ) 0x28 << ( sal_uInt16 ) 10
237 << ( sal_uInt16 ) 4 << ( sal_uInt16 ) 76 // Left/right margin
238 << ( sal_uInt16 ) 66 // Page length
239 << ( sal_uInt16 ) 2 << ( sal_uInt16 ) 2; // Top/Bottom margin
240 }
241
242
Labelfmt()243 inline void ExportWK1::Labelfmt()
244 { // (0x29)
245 // Global label alignment = left
246 aOut << ( sal_uInt16 ) 0x29 << ( sal_uInt16 ) 1 << ( sal_uInt8 ) 0x27;
247 }
248
249
Calccount()250 inline void ExportWK1::Calccount()
251 { // (0x2F)
252 // Iteration count = 16 (oder so aehnlich)
253 aOut << ( sal_uInt16 ) 0x2F << ( sal_uInt16 ) 1 << ( sal_uInt8 ) 16;
254 }
255
256
Cursorw12()257 inline void ExportWK1::Cursorw12()
258 { // (0x31)
259 // Cursor location in window 1
260 aOut << ( sal_uInt16 ) 0x31 << ( sal_uInt16 ) 1 << ( sal_uInt8 ) 1;
261 }
262
263
WKString(const sal_uInt16,const sal_uInt16,const ScFormulaCell *,const ScPatternAttr &)264 void ExportWK1::WKString( const sal_uInt16 /*nCol*/, const sal_uInt16 /*nRow*/, const ScFormulaCell* /*pFC*/, const ScPatternAttr& /*aAttr*/ )
265 { // (0x33)
266 // PREC: nCol <= WK1MAXCOL, nRow <= WK1MAXROW
267 /* DBG_ASSERT( nCol <= WK1MAXCOL, "ExportWK1::Label(): Col > WK1MAXCOL" );
268 DBG_ASSERT( nRow <= WK1MAXROW, "ExportWK1::Label(): Row > WK1MAXROW" );
269
270 String aStr;
271 ( ( ScFormulaCell * ) pFC )->GetString( aStr ); // Formeltext zunaechst so belassen
272
273 sal_uInt16 nLaenge = 6; // Anzahl Bytes vor String+Nullbyte am Ende
274
275 sal_uInt16 nAnz = aStr.Len();
276
277 if( nAnz > 240 ) // max. 240 Zeichen im String
278 nAnz = 240;
279
280 nLaenge += nAnz; // + Stringlaenge
281
282 aOut << ( sal_uInt16 ) 0x33 << nLaenge
283 << GenFormByte( aAttr ) << nCol << nRow;
284
285 // Zeichenweise String ausgeben
286 for( sal_uInt16 nLauf = 0 ; nLauf < nAnz ; nLauf++ )
287 aOut << aStr[ nLauf ];
288
289 aOut << ( sal_uInt8 ) 0x00; // ...und Nullterminator anhaengen
290 */
291 }
292
293
Snrange()294 inline void ExportWK1::Snrange()
295 { // (0x47)
296 //aOut << ( sal_uInt16 ) 0x47 << ( sal_uInt16 ) x
297 /* ScRangeName *pRanges = pD->GetRangeName();
298 ScRangeData *pData;
299 String aName;
300
301 sal_uInt16 nAnz = pRanges->GetCount();
302
303 for( sal_uInt16 nLauf = 0 ; nLauf < nAnz ; nLauf++ )
304 {
305 pData = pRanges[ nLauf ];
306
307 }
308 */
309 }
310
311
Hidcol()312 inline void ExportWK1::Hidcol()
313 { // (0x64)
314 sal_uInt32 nHide = 0x00000000; // ...niemand ist versteckt
315
316 aOut << ( sal_uInt16 ) 0x64 << ( sal_uInt16 ) 32;
317
318 for( int nLauf = 0 ; nLauf < 8 ; nLauf++ )
319 aOut << nHide; // 8 * 32 Bits = 256
320 }
321
322
Cpi()323 inline void ExportWK1::Cpi()
324 { // (0x96)
325 //aOut << ( sal_uInt16 ) 0x96 << ( sal_uInt16 ) x;
326 }
327
328
Write()329 FltError ExportWK1::Write()
330 {
331 Bof();
332 //Dimensions();
333 //Cpi();
334 //Calccount();
335 //Calcmode();
336 //Calcorder();
337 //Split();
338 //Sync();
339 //Window1();
340 Colw();
341 //Hidcol();
342 //Cursorw12();
343 //Snrange();
344 //Protect();
345 //Footer();
346 //Header();
347 //Margins();
348 //Labelfmt();
349
350 // Zellen-Bemachung
351 ScDocumentIterator aIter( pD, 0, 0 );
352 ScBaseCell* pCell;
353 sal_uInt16 nCol, nRow;
354 SCTAB nTab;
355 const ScPatternAttr* pPatAttr;
356
357 if( aIter.GetFirst() )
358 do
359 { // ueber alle Zellen der ersten Tabelle iterieren
360 pPatAttr = aIter.GetPattern();
361 pCell = aIter.GetCell();
362 SCCOL nScCol;
363 SCROW nScRow;
364 aIter.GetPos( nScCol, nScRow, nTab );
365 #if SC_ROWLIMIT_MORE_THAN_64K
366 #error row limit 64k
367 #endif
368 nCol = static_cast<sal_uInt16>(nScCol);
369 nRow = static_cast<sal_uInt16>(nScRow);
370
371 switch( pCell->GetCellType() )
372 {
373 case CELLTYPE_VALUE:
374 {
375 double fVal;
376 fVal = ( ( ScValueCell * ) pCell)->GetValue();
377 Number( nCol, nRow, fVal, *pPatAttr );
378 }
379 break;
380 case CELLTYPE_STRING:
381 {
382 String aStr;
383 ( ( ScStringCell * ) pCell)->GetString( aStr );
384 Label( nCol, nRow, aStr, *pPatAttr );
385 }
386 break;
387 case CELLTYPE_FORMULA:
388 {
389 Formula( nCol, nRow, ( ScFormulaCell * ) pCell, *pPatAttr );
390 WKString( nCol, nRow, ( ScFormulaCell * ) pCell, *pPatAttr );
391 }
392 break;
393 case CELLTYPE_NOTE:
394 case CELLTYPE_NONE:
395 break;
396 default:
397 DBG_ASSERT( sal_False, "ExportWK1::Write(): unbekannter Celltype!" );
398 }
399 }
400 while( aIter.GetNext() );
401
402 Eof();
403
404 return eERR_OK;
405 }
406 #endif
407
408
409