xref: /AOO42X/main/sc/source/filter/lotus/expop.cxx (revision b1c5455db1639c48e26c568e4fa7ee78ca5d60ee)
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 
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