blob: 2bc0a20f43c4447b1dfc3d0b7c31f9327d2a48f0 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"
//------------------------------------------------------------------------
#include <tools/debug.hxx>
#include "dociter.hxx"
#include "cell.hxx"
#include "document.hxx"
#include "exp_op.hxx"
#if ENABLE_LOTUS123_EXPORT
const sal_uInt16 ExportWK1::WK1MAXCOL = 255;
const sal_uInt16 ExportWK1::WK1MAXROW = 8191;
sal_uInt8 ExportWK1::GenFormByte( const ScPatternAttr& /*aAttr*/ )
{
return 0xFF;
}
inline void ExportWK1::Bof()
{ // (0x00)
aOut << ( sal_uInt16 ) 0x00 << ( sal_uInt16 ) 2 << ( sal_uInt16 ) 0x0406; // Version 1-2-3/2, Symhony/1.1
}
inline void ExportWK1::Eof()
{ // (0x01)
aOut << ( sal_uInt16 ) 0x01 << ( sal_uInt16 ) 0;
}
inline void ExportWK1::Calcmode()
{ // (0x02)
// Calculationmode = automatic
aOut << ( sal_uInt16 ) 0x02 << ( sal_uInt16 ) 1 << ( sal_uInt8 ) 0xFF;
}
inline void ExportWK1::Calcorder()
{ // (0x03)
// order = natural
aOut << ( sal_uInt16 ) 0x03 << ( sal_uInt16 ) 1 << ( sal_uInt8 ) 0x00;
}
inline void ExportWK1::Split()
{ // (0x04)
// not split
aOut << ( sal_uInt16 ) 0x04 << ( sal_uInt16 ) 1 << ( sal_uInt8 ) 0x00;
}
inline void ExportWK1::Sync()
{ // (0x05)
// not synchronized
aOut << ( sal_uInt16 ) 0x05 << ( sal_uInt16 ) 1 << ( sal_uInt8 ) 0x00;
}
inline void ExportWK1::Dimensions()
{ // (0x06)
SCCOL nEndCol;
SCROW nEndRow;
aOut << ( sal_uInt16 ) 0x06 << ( sal_uInt16 ) 8 << ( sal_uInt16 ) 0 << ( sal_uInt16 ) 0; // Starting Col/Row
pD->GetPrintArea( 0, nEndCol, nEndRow );
#if SC_ROWLIMIT_MORE_THAN_64K
#error row limit 64k
#endif
sal_uInt16 nCol = static_cast<sal_uInt16>(nEndCol);
sal_uInt16 nRow = static_cast<sal_uInt16>(nEndRow);
DBG_ASSERT( nCol <= WK1MAXCOL, "ExportWK1::Dimensions(): Col > WK1MAXCOL" );
DBG_ASSERT( nRow <= WK1MAXROW, "ExportWK1::Dimensions(): Row > WK1MAXROW" );
aOut << nCol << nRow; // Ending Col/Row
}
inline void ExportWK1::Window1()
{ // (0x07)
aOut << ( sal_uInt16 ) 0x07 << ( sal_uInt16 ) 32
<< ( sal_uInt16 ) 0 << ( sal_uInt16 ) 0 // Cursor Col/Row
<< ( sal_uInt8 ) 0xFF // Format: protected, special, default
<< ( sal_uInt8 ) 0 // Dummy
<< ( sal_uInt16 ) 9 // Default column width
<< ( sal_uInt16 ) 8 << ( sal_uInt16 ) 14// Number of cols/rows on screen
<< ( sal_uInt16 ) 0 << ( sal_uInt16 ) 0 // Left col / top row
// Rest aus Doku-Beispiel
<< ( sal_uInt16 ) 0 << ( sal_uInt16 ) 0 // Number of title cols / rows
<< ( sal_uInt16 ) 0 << ( sal_uInt16 ) 0 // Left title col / top title row
<< ( sal_uInt16 ) 0x0004 << ( sal_uInt16 ) 0x0004// Top-left col / row
<< ( sal_uInt16 ) 0x0048 // Number of cols in window
<< ( sal_uInt16 ) 0x00; // Dummy
}
inline void ExportWK1::Colw()
{ // (0x08)
// ACHTUNG: muss nach Window1 und vor hidden cols record kommen!
sal_uInt16 nWidth;
sal_uInt8 nWidthSpaces;
for( sal_uInt16 nCol = 0 ; nCol < 256 ; nCol++ )
{
nWidth = pD->GetColWidth( static_cast<SCCOL>(nCol), 0 );
nWidthSpaces = ( sal_uInt8 ) ( nWidth / TWIPS_PER_CHAR );
aOut << ( sal_uInt16 ) 0x08 << ( sal_uInt16 ) 3 << nCol << nWidthSpaces;
}
}
void ExportWK1::Blank( const sal_uInt16 nCol, const sal_uInt16 nRow, const ScPatternAttr& aAttr )
{ // (0x0C)
// PREC: nCol <= WK1MAXCOL, nRow <= WK1MAXROW
DBG_ASSERT( nCol <= WK1MAXCOL, "ExportWK1::Blank(): Col > WK1MAXCOL" );
DBG_ASSERT( nRow <= WK1MAXROW, "ExportWK1::Blank(): Row > WK1MAXROW" );
aOut << ( sal_uInt16 ) 0x0C << ( sal_uInt16 ) 5 << GenFormByte( aAttr ) << nCol << nRow;
}
void ExportWK1::Number( const sal_uInt16 nCol, const sal_uInt16 nRow, const double fWert, const ScPatternAttr &aAttr )
{ // (0x0E)
// PREC: nCol <= WK1MAXCOL, nRow <= WK1MAXROW
DBG_ASSERT( nCol <= WK1MAXCOL, "ExportWK1::Number(): Col > WK1MAXCOL" );
DBG_ASSERT( nRow <= WK1MAXROW, "ExportWK1::Number(): Row > WK1MAXROW" );
aOut << ( sal_uInt16 ) 0x0E << ( sal_uInt16 ) 13 << GenFormByte( aAttr ) << nCol << nRow << fWert;
}
void ExportWK1::Label( const sal_uInt16 nCol, const sal_uInt16 nRow, const String& rStr, const ScPatternAttr& aAttr )
{ // (0x0F)
// PREC: nCol <= WK1MAXCOL, nRow <= WK1MAXROW
DBG_ASSERT( nCol <= WK1MAXCOL, "ExportWK1::Label(): Col > WK1MAXCOL" );
DBG_ASSERT( nRow <= WK1MAXROW, "ExportWK1::Label(): Row > WK1MAXROW" );
ByteString aStr( rStr, eZielChar );
sal_uInt16 nLaenge = 7; // Anzahl Bytes vor String+Nullbyte am Ende + Alignment-Char
xub_StrLen nAnz = aStr.Len();
if( nAnz > 240 ) // max. 240 Zeichen im String
nAnz = 240;
nLaenge = nLaenge + ( sal_uInt16 ) nAnz; // + Stringlaenge
aOut << ( sal_uInt16 ) 0x0F << nLaenge << GenFormByte( aAttr ) << nCol << nRow << ( sal_Char ) '\'';
// ACHTUNG: ZUNAECHST NUR LEFT ALIGNMENT
aOut.Write( aStr.GetBuffer(), nAnz );
aOut << ( sal_uInt8 ) 0x00; // ...und Nullterminator anhaengen
}
void ExportWK1::Formula( const sal_uInt16 nCol, const sal_uInt16 nRow, const ScFormulaCell* pFC, const ScPatternAttr& aAttr )
{ // (0x10)
// PREC: nCol <= WK1MAXCOL, nRow <= WK1MAXROW
DBG_ASSERT( nCol <= WK1MAXCOL, "ExportWK1::Formula(): Col > WK1MAXCOL" );
DBG_ASSERT( nRow <= WK1MAXROW, "ExportWK1::Formula(): Row > WK1MAXROW" );
sal_uInt16 nLaenge = 15; // Bytes bis Formel
double fErgebnis;
// zunaechst nur Dummy-Angaben (Formel := Ergebnis der Berechnung )
nLaenge += 9+1;
fErgebnis = ( ( ScFormulaCell* ) pFC )->GetValue();
aOut << ( sal_uInt16 ) 0x10 << ( sal_uInt16 ) nLaenge
<< GenFormByte( aAttr ) << nCol << nRow
<< fErgebnis
<< ( sal_uInt16 ) 9+1 // Dummy-Formula-Size
<< ( sal_uInt8 ) 0x00 // constant, floating point
<< fErgebnis
<< ( sal_uInt8 ) 0x03; // return
}
inline void ExportWK1::Protect()
{ // (0x24)
//Global protection off
aOut << ( sal_uInt16 ) 0x24 << ( sal_uInt16 ) 1 << ( sal_uInt8 ) 0x00;
}
inline void ExportWK1::Footer()
{ // (0x25)
// zunaechst nur leerer C-String
aOut << ( sal_uInt16 ) 0x25 << ( sal_uInt16 ) 242 << ( sal_Char ) '\''; // linksbuendiger leerer String
for( short nLauf = 0 ; nLauf < 241 ; nLauf++ )
aOut << ( sal_uInt8 ) 0x00;
}
inline void ExportWK1::Header()
{ // (0x26)
// zunaechst nur leerer C-String
aOut << ( sal_uInt16 ) 0x26 << ( sal_uInt16 ) 242 << ( sal_Char ) '\''; // linksbuendiger leerer String
for( short nLauf = 0 ; nLauf < 241 ; nLauf++ )
aOut << ( sal_uInt8 ) 0x00;
}
inline void ExportWK1::Margins()
{ // (0x28)
aOut << ( sal_uInt16 ) 0x28 << ( sal_uInt16 ) 10
<< ( sal_uInt16 ) 4 << ( sal_uInt16 ) 76 // Left/right margin
<< ( sal_uInt16 ) 66 // Page length
<< ( sal_uInt16 ) 2 << ( sal_uInt16 ) 2; // Top/Bottom margin
}
inline void ExportWK1::Labelfmt()
{ // (0x29)
// Global label alignment = left
aOut << ( sal_uInt16 ) 0x29 << ( sal_uInt16 ) 1 << ( sal_uInt8 ) 0x27;
}
inline void ExportWK1::Calccount()
{ // (0x2F)
// Iteration count = 16 (oder so aehnlich)
aOut << ( sal_uInt16 ) 0x2F << ( sal_uInt16 ) 1 << ( sal_uInt8 ) 16;
}
inline void ExportWK1::Cursorw12()
{ // (0x31)
// Cursor location in window 1
aOut << ( sal_uInt16 ) 0x31 << ( sal_uInt16 ) 1 << ( sal_uInt8 ) 1;
}
void ExportWK1::WKString( const sal_uInt16 /*nCol*/, const sal_uInt16 /*nRow*/, const ScFormulaCell* /*pFC*/, const ScPatternAttr& /*aAttr*/ )
{ // (0x33)
// PREC: nCol <= WK1MAXCOL, nRow <= WK1MAXROW
/* DBG_ASSERT( nCol <= WK1MAXCOL, "ExportWK1::Label(): Col > WK1MAXCOL" );
DBG_ASSERT( nRow <= WK1MAXROW, "ExportWK1::Label(): Row > WK1MAXROW" );
String aStr;
( ( ScFormulaCell * ) pFC )->GetString( aStr ); // Formeltext zunaechst so belassen
sal_uInt16 nLaenge = 6; // Anzahl Bytes vor String+Nullbyte am Ende
sal_uInt16 nAnz = aStr.Len();
if( nAnz > 240 ) // max. 240 Zeichen im String
nAnz = 240;
nLaenge += nAnz; // + Stringlaenge
aOut << ( sal_uInt16 ) 0x33 << nLaenge
<< GenFormByte( aAttr ) << nCol << nRow;
// Zeichenweise String ausgeben
for( sal_uInt16 nLauf = 0 ; nLauf < nAnz ; nLauf++ )
aOut << aStr[ nLauf ];
aOut << ( sal_uInt8 ) 0x00; // ...und Nullterminator anhaengen
*/
}
inline void ExportWK1::Snrange()
{ // (0x47)
//aOut << ( sal_uInt16 ) 0x47 << ( sal_uInt16 ) x
/* ScRangeName *pRanges = pD->GetRangeName();
ScRangeData *pData;
String aName;
sal_uInt16 nAnz = pRanges->GetCount();
for( sal_uInt16 nLauf = 0 ; nLauf < nAnz ; nLauf++ )
{
pData = pRanges[ nLauf ];
}
*/
}
inline void ExportWK1::Hidcol()
{ // (0x64)
sal_uInt32 nHide = 0x00000000; // ...niemand ist versteckt
aOut << ( sal_uInt16 ) 0x64 << ( sal_uInt16 ) 32;
for( int nLauf = 0 ; nLauf < 8 ; nLauf++ )
aOut << nHide; // 8 * 32 Bits = 256
}
inline void ExportWK1::Cpi()
{ // (0x96)
//aOut << ( sal_uInt16 ) 0x96 << ( sal_uInt16 ) x;
}
FltError ExportWK1::Write()
{
Bof();
//Dimensions();
//Cpi();
//Calccount();
//Calcmode();
//Calcorder();
//Split();
//Sync();
//Window1();
Colw();
//Hidcol();
//Cursorw12();
//Snrange();
//Protect();
//Footer();
//Header();
//Margins();
//Labelfmt();
// Zellen-Bemachung
ScDocumentIterator aIter( pD, 0, 0 );
ScBaseCell* pCell;
sal_uInt16 nCol, nRow;
SCTAB nTab;
const ScPatternAttr* pPatAttr;
if( aIter.GetFirst() )
do
{ // ueber alle Zellen der ersten Tabelle iterieren
pPatAttr = aIter.GetPattern();
pCell = aIter.GetCell();
SCCOL nScCol;
SCROW nScRow;
aIter.GetPos( nScCol, nScRow, nTab );
#if SC_ROWLIMIT_MORE_THAN_64K
#error row limit 64k
#endif
nCol = static_cast<sal_uInt16>(nScCol);
nRow = static_cast<sal_uInt16>(nScRow);
switch( pCell->GetCellType() )
{
case CELLTYPE_VALUE:
{
double fVal;
fVal = ( ( ScValueCell * ) pCell)->GetValue();
Number( nCol, nRow, fVal, *pPatAttr );
}
break;
case CELLTYPE_STRING:
{
String aStr;
( ( ScStringCell * ) pCell)->GetString( aStr );
Label( nCol, nRow, aStr, *pPatAttr );
}
break;
case CELLTYPE_FORMULA:
{
Formula( nCol, nRow, ( ScFormulaCell * ) pCell, *pPatAttr );
WKString( nCol, nRow, ( ScFormulaCell * ) pCell, *pPatAttr );
}
break;
case CELLTYPE_NOTE:
case CELLTYPE_NONE:
break;
default:
DBG_ASSERT( sal_False, "ExportWK1::Write(): unbekannter Celltype!" );
}
}
while( aIter.GetNext() );
Eof();
return eERR_OK;
}
#endif