Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / sc / source / filter / lotus / lotimpop.cxx
blobfa937c510021bd69d95a447d92d375ba90a4bd72
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "lotfilter.hxx"
21 #include "lotimpop.hxx"
22 #include <osl/mutex.hxx>
24 #include "attrib.hxx"
25 #include "document.hxx"
26 #include "rangenam.hxx"
27 #include "formulacell.hxx"
28 #include "patattr.hxx"
29 #include "docpool.hxx"
30 #include "compiler.hxx"
31 #include "global.hxx"
33 #include "root.hxx"
34 #include "lotfntbf.hxx"
35 #include "lotform.hxx"
36 #include "tool.h"
37 #include "namebuff.hxx"
38 #include "lotrange.hxx"
39 #include "lotattr.hxx"
40 #include "stringutil.hxx"
42 LOTUS_ROOT::LOTUS_ROOT( ScDocument* pDocP, rtl_TextEncoding eQ )
44 pDoc( pDocP),
45 pRangeNames( new LotusRangeList(this)),
46 pScRangeName( pDocP->GetRangeName()),
47 eCharsetQ( eQ),
48 eFirstType( Lotus_X),
49 eActType( Lotus_X),
50 pRngNmBffWK3( new RangeNameBufferWK3(this)),
51 pFontBuff( new LotusFontBuffer),
52 pAttrTable( new LotAttrTable(this))
56 LOTUS_ROOT::~LOTUS_ROOT()
58 delete pRangeNames;
59 delete pRngNmBffWK3;
60 delete pFontBuff;
61 delete pAttrTable;
64 static osl::Mutex aLotImpSemaphore;
66 ImportLotus::ImportLotus(LotusContext &rContext, SvStream& aStream, ScDocument* pDoc, rtl_TextEncoding eQ)
67 : ImportTyp(pDoc, eQ)
68 , pIn(&aStream)
69 , aConv(rContext, *pIn, pDoc->GetSharedStringPool(), eQ, false)
70 , nTab(0)
71 , nExtTab(0)
73 // good point to start locking of import lotus
74 aLotImpSemaphore.acquire();
76 rContext.pLotusRoot = new LOTUS_ROOT(pDoc, eQ);
79 ImportLotus::~ImportLotus()
81 LotusContext &rContext = aConv.getContext();
82 delete rContext.pLotusRoot;
83 rContext.pLotusRoot = nullptr;
85 // no need 4 pLotusRoot anymore
86 aLotImpSemaphore.release();
89 void ImportLotus::Bof()
91 sal_uInt16 nFileCode, nFileSub, nSaveCnt;
92 sal_uInt8 nMajorId, nMinorId, nFlags;
94 Read( nFileCode );
95 Read( nFileSub );
96 LotusContext &rContext = aConv.getContext();
97 Read( rContext.pLotusRoot->aActRange );
98 Read( nSaveCnt );
99 Read( nMajorId );
100 Read( nMinorId );
101 Skip( 1 );
102 Read( nFlags );
104 if( nFileSub == 0x0004 )
106 if( nFileCode == 0x1000 )
107 {// <= WK3
108 rContext.pLotusRoot->eFirstType = rContext.pLotusRoot->eActType = Lotus_WK3;
110 else if( nFileCode == 0x1002 )
111 {// WK4
112 rContext.pLotusRoot->eFirstType = rContext.pLotusRoot->eActType = Lotus_WK4;
117 bool ImportLotus::BofFm3()
119 sal_uInt16 nFileCode, nFileSub;
121 Read( nFileCode );
122 Read( nFileSub );
124 return ( nFileCode == 0x8007 && ( nFileSub == 0x0000 || nFileSub == 0x00001 ) );
127 void ImportLotus::Columnwidth( sal_uInt16 nRecLen )
129 OSL_ENSURE( nRecLen >= 4, "*ImportLotus::Columnwidth(): Record zu kurz!" );
131 sal_uInt8 nLTab, nWindow2;
132 sal_uInt16 nCnt = (nRecLen < 4) ? 0 : ( nRecLen - 4 ) / 2;
134 Read( nLTab );
135 Read( nWindow2 );
137 if( !pD->HasTable( static_cast<SCTAB> (nLTab) ) )
138 pD->MakeTable( static_cast<SCTAB> (nLTab) );
140 if( !nWindow2 )
142 Skip( 2 );
144 sal_uInt8 nCol, nSpaces;
146 while( nCnt )
148 Read( nCol );
149 Read( nSpaces );
150 // Attention: ambiguous Correction factor!
151 pD->SetColWidth( static_cast<SCCOL> (nCol), static_cast<SCTAB> (nLTab), ( sal_uInt16 ) ( TWIPS_PER_CHAR * 1.28 * nSpaces ) );
153 nCnt--;
158 void ImportLotus::Hiddencolumn( sal_uInt16 nRecLen )
160 OSL_ENSURE( nRecLen >= 4, "*ImportLotus::Hiddencolumn(): Record too short!" );
162 sal_uInt8 nLTab, nWindow2;
163 sal_uInt16 nCnt = (nRecLen < 4) ? 0 : ( nRecLen - 4 ) / 2;
165 Read( nLTab );
166 Read( nWindow2 );
168 if( !nWindow2 )
170 Skip( 2 );
172 sal_uInt8 nCol;
174 while( nCnt )
176 Read( nCol );
178 pD->SetColHidden(static_cast<SCCOL>(nCol), static_cast<SCCOL>(nCol), static_cast<SCTAB>(nLTab), true);
179 nCnt--;
184 void ImportLotus::Userrange()
186 sal_uInt16 nRangeType;
187 ScRange aScRange;
189 Read( nRangeType );
191 sal_Char aBuffer[ 17 ];
192 pIn->Read( aBuffer, 16 );
193 aBuffer[ 16 ] = 0;
194 OUString aName( aBuffer, strlen(aBuffer), eQuellChar );
196 Read( aScRange );
198 LotusContext &rContext = aConv.getContext();
199 rContext.pLotusRoot->pRngNmBffWK3->Add( aName, aScRange );
202 void ImportLotus::Errcell()
204 ScAddress aA;
206 Read( aA );
208 ScSetStringParam aParam;
209 aParam.setTextInput();
210 pD->EnsureTable(aA.Tab());
211 pD->SetString(aA, "#ERR!", &aParam);
214 void ImportLotus::Nacell()
216 ScAddress aA;
218 Read( aA );
220 ScSetStringParam aParam;
221 aParam.setTextInput();
222 pD->EnsureTable(aA.Tab());
223 pD->SetString(aA, "#NA!", &aParam);
226 void ImportLotus::Labelcell()
228 ScAddress aA;
229 OUString aLabel;
230 sal_Char cAlign;
232 Read( aA );
233 Read( cAlign );
234 Read( aLabel );
236 ScSetStringParam aParam;
237 aParam.setTextInput();
238 pD->EnsureTable(aA.Tab());
239 pD->SetString(aA, aLabel, &aParam);
242 void ImportLotus::Numbercell()
244 ScAddress aAddr;
245 double fVal;
247 Read( aAddr );
248 Read( fVal );
250 pD->EnsureTable(aAddr.Tab());
251 pD->SetValue(aAddr, fVal);
254 void ImportLotus::Smallnumcell()
256 ScAddress aAddr;
257 sal_Int16 nVal;
259 Read( aAddr );
260 Read( nVal );
262 pD->EnsureTable(aAddr.Tab());
263 pD->SetValue(aAddr, SnumToDouble(nVal));
266 void ImportLotus::Formulacell( sal_uInt16 n )
268 OSL_ENSURE( pIn, "-ImportLotus::Formulacell(): Null-Stream!" );
270 ScAddress aAddr;
272 Read( aAddr );
273 Skip( 10 );
275 n -= (n > 14) ? 14 : n;
277 const ScTokenArray* pErg;
278 sal_Int32 nRest = n;
280 aConv.Reset( aAddr );
281 aConv.SetWK3();
282 aConv.Convert( pErg, nRest );
284 ScFormulaCell* pCell = pErg ? new ScFormulaCell(pD, aAddr, *pErg) : new ScFormulaCell(pD, aAddr);
285 pCell->AddRecalcMode( ScRecalcMode::ONLOAD_ONCE );
286 pD->EnsureTable(aAddr.Tab());
287 pD->SetFormulaCell(aAddr, pCell);
290 void ImportLotus::Read( OUString &r )
292 ScfTools::AppendCString( *pIn, r, eQuellChar );
295 void ImportLotus::RowPresentation( sal_uInt16 nRecLen )
297 OSL_ENSURE( nRecLen > 4, "*ImportLotus::RowPresentation(): Record too short!" );
299 sal_uInt8 nLTab, nFlags;
300 sal_uInt16 nRow, nHeight;
301 sal_uInt16 nCnt = (nRecLen < 4) ? 0 : ( nRecLen - 4 ) / 8;
303 Read( nLTab );
304 Skip( 1 );
306 while( nCnt )
308 Read( nRow );
309 Read( nHeight );
310 Skip( 2 );
311 Read( nFlags );
312 Skip( 1 );
314 if( nFlags & 0x02 ) // Fixed / Stretch to fit fonts
315 { // fixed
316 // Height in Lotus in 1/32 Points
317 nHeight *= 20; // -> 32 * TWIPS
318 nHeight /= 32; // -> TWIPS
320 pD->SetRowFlags( static_cast<SCROW> (nRow), static_cast<SCTAB> (nLTab), pD->GetRowFlags( static_cast<SCROW> (nRow), static_cast<SCTAB> (nLTab) ) | CR_MANUALSIZE );
322 pD->SetRowHeight( static_cast<SCROW> (nRow), static_cast<SCTAB> (nLTab), nHeight );
325 nCnt--;
329 void ImportLotus::NamedSheet()
331 sal_uInt16 nTmpTab(0);
332 Read(nTmpTab);
333 OUString aName;
334 Read(aName);
336 SCTAB nLTab(SanitizeTab(static_cast<SCTAB>(nTmpTab)));
338 if (pD->HasTable(nLTab))
339 pD->RenameTab(nLTab, aName);
340 else
341 pD->InsertTab(nLTab, aName);
344 void ImportLotus::Font_Face()
346 sal_uInt8 nNum;
347 OUString aName;
349 Read( nNum );
351 if( nNum >= LotusFontBuffer::nSize )
352 return; // nonsense
354 Read( aName );
356 LotusContext &rContext = aConv.getContext();
357 rContext.pLotusRoot->pFontBuff->SetName( nNum, aName );
360 void ImportLotus::Font_Type()
362 LotusContext &rContext = aConv.getContext();
363 for( sal_uInt16 nCnt = 0 ; nCnt < LotusFontBuffer::nSize ; nCnt++ )
365 sal_uInt16 nType;
366 Read( nType );
367 rContext.pLotusRoot->pFontBuff->SetType( nCnt, nType );
371 void ImportLotus::Font_Ysize()
373 LotusContext &rContext = aConv.getContext();
374 for( sal_uInt16 nCnt = 0 ; nCnt < LotusFontBuffer::nSize ; nCnt++ )
376 sal_uInt16 nSize;
377 Read( nSize );
378 rContext.pLotusRoot->pFontBuff->SetHeight( nCnt, nSize );
382 void ImportLotus::Row_( const sal_uInt16 nRecLen )
384 OSL_ENSURE( nExtTab >= 0, "*ImportLotus::Row_(): not possible!" );
386 sal_uInt16 nCntDwn = (nRecLen < 4) ? 0 : ( nRecLen - 4 ) / 5;
387 SCCOL nColCnt = 0;
388 sal_uInt8 nRepeats;
389 LotAttrWK3 aAttr;
391 bool bCenter = false;
392 SCCOL nCenterStart = 0, nCenterEnd = 0;
394 sal_uInt16 nTmpRow(0);
395 Read(nTmpRow);
396 SCROW nRow(SanitizeRow(static_cast<SCROW>(nTmpRow)));
397 sal_uInt16 nHeight(0);
398 Read(nHeight);
400 nHeight &= 0x0FFF;
401 nHeight *= 22;
403 SCTAB nDestTab(static_cast<SCTAB>(nExtTab));
405 if( nHeight )
406 pD->SetRowHeight(nRow, nDestTab, nHeight);
408 LotusContext &rContext = aConv.getContext();
409 while( nCntDwn )
411 Read( aAttr );
412 Read( nRepeats );
414 if( aAttr.HasStyles() )
415 rContext.pLotusRoot->pAttrTable->SetAttr(
416 nColCnt, static_cast<SCCOL> ( nColCnt + nRepeats ), nRow, aAttr );
418 // Do this here and NOT in class LotAttrTable, as we only add attributes if the other
419 // attributes are set
420 // -> for Center-Attribute default is centered
421 if( aAttr.IsCentered() )
423 if( bCenter )
425 if (pD->HasData(nColCnt, nRow, nDestTab))
427 // new Center after previous Center
428 pD->DoMerge(nDestTab, nCenterStart, nRow, nCenterEnd, nRow);
429 nCenterStart = nColCnt;
432 else
434 // fully new Center
435 bCenter = true;
436 nCenterStart = nColCnt;
438 nCenterEnd = nColCnt + static_cast<SCCOL>(nRepeats);
440 else
442 if( bCenter )
444 // possibly reset old Center
445 pD->DoMerge(nDestTab, nCenterStart, nRow, nCenterEnd, nRow);
446 bCenter = false;
450 nColCnt = nColCnt + static_cast<SCCOL>(nRepeats);
451 nColCnt++;
453 nCntDwn--;
456 if( bCenter )
457 // possibly reset old Center
458 pD->DoMerge(nDestTab, nCenterStart, nRow, nCenterEnd, nRow);
460 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */