xref: /trunk/main/sc/source/filter/lotus/expop.cxx (revision b77af630)
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 
408 
409