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