Line data Source code
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 "lotimpop.hxx"
21 : #include <osl/mutex.hxx>
22 :
23 : #include "attrib.hxx"
24 : #include "document.hxx"
25 : #include "rangenam.hxx"
26 : #include "cell.hxx"
27 : #include "patattr.hxx"
28 : #include "docpool.hxx"
29 : #include "compiler.hxx"
30 : #include "global.hxx"
31 :
32 : #include "root.hxx"
33 : #include "lotfntbf.hxx"
34 : #include "lotform.hxx"
35 : #include "tool.h"
36 : #include "namebuff.hxx"
37 : #include "lotrange.hxx"
38 : #include "lotattr.hxx"
39 :
40 1 : LOTUS_ROOT::LOTUS_ROOT( ScDocument* pDocP, CharSet eQ )
41 : :
42 : pDoc( pDocP),
43 1 : pRangeNames( new LotusRangeList),
44 1 : pScRangeName( pDocP->GetRangeName()),
45 : eCharsetQ( eQ),
46 : eFirstType( Lotus_X),
47 : eActType( Lotus_X),
48 1 : pRngNmBffWK3( new RangeNameBufferWK3),
49 1 : pFontBuff( new LotusFontBuffer),
50 5 : pAttrTable( new LotAttrTable(this))
51 : {
52 1 : }
53 :
54 :
55 1 : LOTUS_ROOT::~LOTUS_ROOT()
56 : {
57 1 : delete pRangeNames;
58 1 : delete pRngNmBffWK3;
59 1 : delete pFontBuff;
60 1 : delete pAttrTable;
61 1 : }
62 :
63 :
64 3 : static osl::Mutex aLotImpSemaphore;
65 :
66 :
67 1 : ImportLotus::ImportLotus( SvStream& aStream, ScDocument* pDoc, CharSet eQ ) :
68 : ImportTyp( pDoc, eQ ),
69 : pIn( &aStream ),
70 1 : aConv( *pIn, eQ, false )
71 : {
72 : // good point to start locking of import lotus
73 1 : aLotImpSemaphore.acquire();
74 :
75 1 : pLotusRoot = new LOTUS_ROOT( pDoc, eQ);
76 1 : }
77 :
78 :
79 2 : ImportLotus::~ImportLotus()
80 : {
81 1 : delete pLotusRoot;
82 1 : pLotusRoot = NULL;
83 :
84 : // no need 4 pLotusRoot anymore
85 1 : aLotImpSemaphore.release();
86 1 : }
87 :
88 :
89 0 : void ImportLotus::Bof( void )
90 : {
91 : sal_uInt16 nFileCode, nFileSub, nSaveCnt;
92 : sal_uInt8 nMajorId, nMinorId, nFlags;
93 :
94 0 : Read( nFileCode );
95 0 : Read( nFileSub );
96 0 : Read( pLotusRoot->aActRange );
97 0 : Read( nSaveCnt );
98 0 : Read( nMajorId );
99 0 : Read( nMinorId );
100 0 : Skip( 1 );
101 0 : Read( nFlags );
102 :
103 0 : if( nFileSub == 0x0004 )
104 : {
105 0 : if( nFileCode == 0x1000 )
106 : {// <= WK3
107 0 : pLotusRoot->eFirstType = pLotusRoot->eActType = Lotus_WK3;
108 : }
109 0 : else if( nFileCode == 0x1002 )
110 : {// WK4
111 0 : pLotusRoot->eFirstType = pLotusRoot->eActType = Lotus_WK4;
112 : }
113 : }
114 0 : }
115 :
116 :
117 0 : sal_Bool ImportLotus::BofFm3( void )
118 : {
119 : sal_uInt16 nFileCode, nFileSub;
120 :
121 0 : Read( nFileCode );
122 0 : Read( nFileSub );
123 :
124 0 : return ( nFileCode == 0x8007 && ( nFileSub == 0x0000 || nFileSub == 0x00001 ) );
125 : }
126 :
127 :
128 0 : void ImportLotus::Columnwidth( sal_uInt16 nRecLen )
129 : {
130 : OSL_ENSURE( nRecLen >= 4, "*ImportLotus::Columnwidth(): Record zu kurz!" );
131 :
132 : sal_uInt8 nLTab, nWindow2;
133 0 : sal_uInt16 nCnt = (nRecLen < 4) ? 0 : ( nRecLen - 4 ) / 2;
134 :
135 0 : Read( nLTab );
136 0 : Read( nWindow2 );
137 :
138 0 : if( !pD->HasTable( static_cast<SCTAB> (nLTab) ) )
139 0 : pD->MakeTable( static_cast<SCTAB> (nLTab) );
140 :
141 0 : if( !nWindow2 )
142 : {
143 0 : Skip( 2 );
144 :
145 : sal_uInt8 nCol, nSpaces;
146 :
147 0 : while( nCnt )
148 : {
149 0 : Read( nCol );
150 0 : Read( nSpaces );
151 : // ACHTUNG: Korrekturfaktor nach 'Augenmass' ermittelt!
152 0 : pD->SetColWidth( static_cast<SCCOL> (nCol), static_cast<SCTAB> (nLTab), ( sal_uInt16 ) ( TWIPS_PER_CHAR * 1.28 * nSpaces ) );
153 :
154 0 : nCnt--;
155 : }
156 : }
157 0 : }
158 :
159 :
160 0 : void ImportLotus::Hiddencolumn( sal_uInt16 nRecLen )
161 : {
162 : OSL_ENSURE( nRecLen >= 4, "*ImportLotus::Hiddencolumn(): Record zu kurz!" );
163 :
164 : sal_uInt8 nLTab, nWindow2;
165 0 : sal_uInt16 nCnt = (nRecLen < 4) ? 0 : ( nRecLen - 4 ) / 2;
166 :
167 0 : Read( nLTab );
168 0 : Read( nWindow2 );
169 :
170 0 : if( !nWindow2 )
171 : {
172 0 : Skip( 2 );
173 :
174 : sal_uInt8 nCol;
175 :
176 0 : while( nCnt )
177 : {
178 0 : Read( nCol );
179 :
180 0 : pD->SetColHidden(static_cast<SCCOL>(nCol), static_cast<SCCOL>(nCol), static_cast<SCTAB>(nLTab), true);
181 0 : nCnt--;
182 : }
183 : }
184 0 : }
185 :
186 :
187 0 : void ImportLotus::Userrange( void )
188 : {
189 : sal_uInt16 nRangeType;
190 0 : ScRange aScRange;
191 :
192 0 : Read( nRangeType );
193 :
194 : sal_Char aBuffer[ 17 ];
195 0 : pIn->Read( aBuffer, 16 );
196 0 : aBuffer[ 16 ] = 0;
197 0 : String aName( aBuffer, eQuellChar );
198 :
199 0 : Read( aScRange );
200 :
201 0 : pLotusRoot->pRngNmBffWK3->Add( aName, aScRange );
202 0 : }
203 :
204 :
205 0 : void ImportLotus::Errcell( void )
206 : {
207 0 : ScAddress aA;
208 :
209 0 : Read( aA );
210 :
211 0 : pD->PutCell( aA.Col(), aA.Row(), aA.Tab(), new ScStringCell( CREATE_STRING( "#ERR!" ) ), true );
212 0 : }
213 :
214 :
215 0 : void ImportLotus::Nacell( void )
216 : {
217 0 : ScAddress aA;
218 :
219 0 : Read( aA );
220 :
221 0 : pD->PutCell( aA.Col(), aA.Row(), aA.Tab(), new ScStringCell( CREATE_STRING( "#NA!" ) ), true );
222 0 : }
223 :
224 :
225 0 : void ImportLotus::Labelcell( void )
226 : {
227 0 : ScAddress aA;
228 0 : String aLabel;
229 : sal_Char cAlign;
230 :
231 0 : Read( aA );
232 0 : Read( cAlign );
233 0 : Read( aLabel );
234 :
235 : // aLabel.Convert( pLotusRoot->eCharsetQ );
236 :
237 0 : pD->PutCell( aA.Col(), aA.Row(), aA.Tab(), new ScStringCell( aLabel ), true );
238 0 : }
239 :
240 :
241 0 : void ImportLotus::Numbercell( void )
242 : {
243 0 : ScAddress aAddr;
244 : double fVal;
245 :
246 0 : Read( aAddr );
247 0 : Read( fVal );
248 :
249 0 : pD->PutCell( aAddr.Col(), aAddr.Row(), aAddr.Tab(),
250 0 : new ScValueCell( fVal ), true );
251 0 : }
252 :
253 :
254 0 : void ImportLotus::Smallnumcell( void )
255 : {
256 0 : ScAddress aAddr;
257 : sal_Int16 nVal;
258 :
259 0 : Read( aAddr );
260 0 : Read( nVal );
261 :
262 0 : pD->PutCell( aAddr.Col(), aAddr.Row(), aAddr.Tab(),
263 0 : new ScValueCell( SnumToDouble( nVal ) ), true );
264 0 : }
265 :
266 :
267 0 : ScFormulaCell *ImportLotus::Formulacell( sal_uInt16 n )
268 : {
269 : OSL_ENSURE( pIn, "-ImportLotus::Formulacell(): Null-Stream -> Rums!" );
270 :
271 0 : ScAddress aAddr;
272 :
273 0 : Read( aAddr );
274 0 : Skip( 10 );
275 :
276 0 : n -= (n > 14) ? 14 : n;
277 :
278 : const ScTokenArray* pErg;
279 0 : sal_Int32 nRest = n;
280 :
281 0 : aConv.Reset( aAddr );
282 0 : aConv.SetWK3();
283 0 : aConv.Convert( pErg, nRest );
284 :
285 0 : ScFormulaCell* pZelle = new ScFormulaCell( pD, aAddr, pErg );
286 :
287 0 : pZelle->AddRecalcMode( RECALCMODE_ONLOAD_ONCE );
288 :
289 0 : pD->PutCell( aAddr.Col(), aAddr.Row(), aAddr.Tab(), pZelle, true );
290 :
291 0 : return NULL;
292 : }
293 :
294 :
295 0 : void ImportLotus::Read( String &r )
296 : {
297 0 : ScfTools::AppendCString( *pIn, r, eQuellChar );
298 0 : }
299 :
300 :
301 0 : void ImportLotus::RowPresentation( sal_uInt16 nRecLen )
302 : {
303 : OSL_ENSURE( nRecLen > 4, "*ImportLotus::RowPresentation(): Record zu kurz!" );
304 :
305 : sal_uInt8 nLTab, nFlags;
306 : sal_uInt16 nRow, nHeight;
307 0 : sal_uInt16 nCnt = (nRecLen < 4) ? 0 : ( nRecLen - 4 ) / 8;
308 :
309 0 : Read( nLTab );
310 0 : Skip( 1 );
311 :
312 0 : while( nCnt )
313 : {
314 0 : Read( nRow );
315 0 : Read( nHeight );
316 0 : Skip( 2 );
317 0 : Read( nFlags );
318 0 : Skip( 1 );
319 :
320 0 : if( nFlags & 0x02 ) // Fixed / Strech to fit fonts
321 : { // fixed
322 : // Height in Lotus in 1/32 Points
323 0 : nHeight *= 20; // -> 32 * TWIPS
324 0 : nHeight /= 32; // -> TWIPS
325 :
326 0 : pD->SetRowFlags( static_cast<SCROW> (nRow), static_cast<SCTAB> (nLTab), pD->GetRowFlags( static_cast<SCROW> (nRow), static_cast<SCTAB> (nLTab) ) | CR_MANUALSIZE );
327 :
328 0 : pD->SetRowHeight( static_cast<SCROW> (nRow), static_cast<SCTAB> (nLTab), nHeight );
329 : }
330 :
331 0 : nCnt--;
332 : }
333 0 : }
334 :
335 :
336 0 : void ImportLotus::NamedSheet( void )
337 : {
338 : sal_uInt16 nLTab;
339 0 : String aName;
340 :
341 0 : Read( nLTab );
342 0 : Read( aName );
343 :
344 0 : if( pD->HasTable( static_cast<SCTAB> (nLTab) ) )
345 0 : pD->RenameTab( static_cast<SCTAB> (nLTab), aName );
346 : else
347 0 : pD->InsertTab( static_cast<SCTAB> (nLTab), aName );
348 0 : }
349 :
350 :
351 0 : void ImportLotus::Font_Face( void )
352 : {
353 : sal_uInt8 nNum;
354 0 : String aName;
355 :
356 0 : Read( nNum );
357 :
358 0 : if( nNum >= LotusFontBuffer::nSize )
359 0 : return; // nonsense
360 :
361 0 : Read( aName );
362 :
363 0 : pLotusRoot->pFontBuff->SetName( nNum, aName );
364 : }
365 :
366 :
367 0 : void ImportLotus::Font_Type( void )
368 : {
369 0 : for( sal_uInt16 nCnt = 0 ; nCnt < LotusFontBuffer::nSize ; nCnt++ )
370 : {
371 : sal_uInt16 nType;
372 0 : Read( nType );
373 0 : pLotusRoot->pFontBuff->SetType( nCnt, nType );
374 : }
375 0 : }
376 :
377 :
378 0 : void ImportLotus::Font_Ysize( void )
379 : {
380 0 : for( sal_uInt16 nCnt = 0 ; nCnt < LotusFontBuffer::nSize ; nCnt++ )
381 : {
382 : sal_uInt16 nSize;
383 0 : Read( nSize );
384 0 : pLotusRoot->pFontBuff->SetHeight( nCnt, nSize );
385 : }
386 0 : }
387 :
388 :
389 0 : void ImportLotus::_Row( const sal_uInt16 nRecLen )
390 : {
391 : OSL_ENSURE( nExtTab >= 0, "*ImportLotus::_Row(): Kann hier nicht sein!" );
392 :
393 : sal_uInt16 nRow;
394 : sal_uInt16 nHeight;
395 0 : sal_uInt16 nCntDwn = (nRecLen < 4) ? 0 : ( nRecLen - 4 ) / 5;
396 0 : SCCOL nColCnt = 0;
397 : sal_uInt8 nRepeats;
398 : LotAttrWK3 aAttr;
399 :
400 0 : sal_Bool bCenter = false;
401 0 : SCCOL nCenterStart = 0, nCenterEnd = 0;
402 :
403 0 : Read( nRow );
404 0 : Read( nHeight );
405 :
406 0 : nHeight &= 0x0FFF;
407 0 : nHeight *= 22;
408 :
409 0 : if( nHeight )
410 0 : pD->SetRowHeight( static_cast<SCROW> (nRow), static_cast<SCTAB> (nExtTab), nHeight );
411 :
412 0 : while( nCntDwn )
413 : {
414 0 : Read( aAttr );
415 0 : Read( nRepeats );
416 :
417 0 : if( aAttr.HasStyles() )
418 : pLotusRoot->pAttrTable->SetAttr(
419 0 : nColCnt, static_cast<SCCOL> ( nColCnt + nRepeats ), static_cast<SCROW> (nRow), aAttr );
420 :
421 : // hier und NICHT in class LotAttrTable, weil nur Attributiert wird,
422 : // wenn die anderen Attribute gesetzt sind
423 : // -> bei Center-Attribute wird generell zentriert gesetzt
424 0 : if( aAttr.IsCentered() )
425 : {
426 0 : if( bCenter )
427 : {
428 0 : if( pD->HasData( nColCnt, static_cast<SCROW> (nRow), static_cast<SCTAB> (nExtTab) ) )
429 : {// neue Center nach vorheriger Center
430 0 : pD->DoMerge( static_cast<SCTAB> (nExtTab), nCenterStart, static_cast<SCROW> (nRow), nCenterEnd, static_cast<SCROW> (nRow) );
431 0 : nCenterStart = nColCnt;
432 : }
433 : }
434 : else
435 : {// ganz neue Center
436 0 : bCenter = sal_True;
437 0 : nCenterStart = nColCnt;
438 : }
439 0 : nCenterEnd = nColCnt + static_cast<SCCOL>(nRepeats);
440 : }
441 : else
442 : {
443 0 : if( bCenter )
444 : {// evtl. alte Center bemachen
445 0 : pD->DoMerge( static_cast<SCTAB> (nExtTab), nCenterStart, static_cast<SCROW> (nRow), nCenterEnd, static_cast<SCROW> (nRow) );
446 0 : bCenter = false;
447 : }
448 : }
449 :
450 0 : nColCnt = nColCnt + static_cast<SCCOL>(nRepeats);
451 0 : nColCnt++;
452 :
453 0 : nCntDwn--;
454 : }
455 :
456 0 : if( bCenter )
457 : // evtl. alte Center bemachen
458 0 : pD->DoMerge( static_cast<SCTAB> (nExtTab), nCenterStart, static_cast<SCROW> (nRow), nCenterEnd, static_cast<SCROW> (nRow) );
459 9 : }
460 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|