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