blob: 3a47fe88fbb2b91d5e913b9d746101f593dc9146 [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 "scitems.hxx"
#include <svx/algitem.hxx>
#include <svl/zforlist.hxx>
#include <tools/solar.h>
#include "cell.hxx"
#include "rangenam.hxx"
#include "compiler.hxx"
#include "tool.h"
#include "decl.h"
#include "root.hxx"
#include "lotrange.hxx"
#include "namebuff.hxx"
#include "ftools.hxx"
#include <math.h>
#ifdef _MSC_VER
#pragma optimize("",off)
#endif
//--------------------------------------------------------- EXTERNE VARIABLEN -
extern WKTYP eTyp; // -> filter.cxx, aktueller Dateityp
extern ScDocument* pDoc; // -> filter.cxx, Aufhaenger zum Dokumentzugriff
//--------------------------------------------------------- GLOBALE VARIABLEN -
sal_uInt8 nDefaultFormat; // -> op.cpp, Standard-Zellenformat
extern SvxHorJustifyItem *pAttrRight, *pAttrLeft, *pAttrCenter, *pAttrRepeat, *pAttrStandard;
extern ScProtectionAttr* pAttrUnprot;
extern SfxUInt32Item** pAttrValForms;
SvxHorJustifyItem *pAttrRight, *pAttrLeft, *pAttrCenter, *pAttrRepeat, *pAttrStandard;
// -> in memory.cxx initialisiert
ScProtectionAttr* pAttrUnprot; // -> " memory.cxx "
extern FormCache* pValueFormCache; // -> in memory.cxx initialisiert
FormCache* pValueFormCache;
SCCOL LotusRangeList::nEingCol;
SCROW LotusRangeList::nEingRow;
void PutFormString( SCCOL nCol, SCROW nRow, SCTAB nTab, sal_Char* pString )
{
// Label-Format-Auswertung
DBG_ASSERT( pString != NULL, "PutFormString(): pString == NULL" );
if (!pString)
return;
sal_Char cForm;
SvxHorJustifyItem* pJustify = NULL;
cForm = *pString;
switch( cForm )
{
case '"': // rechtsbuendig
pJustify = pAttrRight;
pString++;
break;
case '\'': // linksbuendig
pJustify = pAttrLeft;
pString++;
break;
case '^': // zentriert
pJustify = pAttrCenter;
pString++;
break;
case '|': // printer command
pString = NULL;
break;
case '\\': // Wiederholung
pJustify = pAttrRepeat;
pString++;
break;
default: // kenn' ich nicht!
pJustify = pAttrStandard;
}
pDoc->ApplyAttr( nCol, nRow, nTab, *pJustify );
ScStringCell* pZelle = new ScStringCell( String( pString, pLotusRoot->eCharsetQ ) );
pDoc->PutCell( nCol, nRow, nTab, pZelle, ( sal_Bool ) sal_True );
}
void SetFormat( SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt8 nFormat, sal_uInt8 nSt )
{
// PREC: nSt = Standard-Dezimalstellenanzahl
pDoc->ApplyAttr( nCol, nRow, nTab, *( pValueFormCache->GetAttr( nFormat, nSt ) ) );
ScProtectionAttr aAttr;
aAttr.SetProtection( nFormat & 0x80 );
pDoc->ApplyAttr( nCol, nRow, nTab, aAttr );
}
void InitPage( void )
{ // Seitenformat initialisieren, d.h. Default-Werte von SC holen
//scGetPageFormat( 0, &aPage );
}
double SnumToDouble( sal_Int16 nVal )
{
const double pFacts[ 8 ] = {
5000.0,
500.0,
0.05,
0.005,
0.0005,
0.00005,
0.0625,
0.015625 };
double fVal;
if( nVal & 0x0001 )
{
fVal = pFacts[ ( nVal >> 1 ) & 0x0007 ];
fVal *= ( sal_Int16 ) ( nVal >> 4 );
}
else
fVal = ( sal_Int16 ) ( nVal >> 1 );
return fVal;
}
double Snum32ToDouble( sal_uInt32 nValue )
{
double fValue, temp;
fValue = nValue >> 6;
temp = nValue & 0x0f;
if (temp)
{
if (nValue & 0x00000010)
fValue /= pow((double)10, temp);
else
fValue *= pow((double)10, temp);
}
if ((nValue & 0x00000020))
fValue = -fValue;
return fValue;
}
FormCache::FormCache( ScDocument* pDoc1, sal_uInt8 nNewDefaultFormat )
{ // Default-Format ist 'Default'
nDefaultFormat = nNewDefaultFormat;
pFormTable = pDoc1->GetFormatTable();
for( sal_uInt16 nC = 0 ; nC < __nSize ; nC++ )
bValid[ nC ] = sal_False;
eLanguage = ScGlobal::eLnge;
}
FormCache::~FormCache()
{
for( sal_uInt16 nC = 0 ; nC < __nSize ; nC++ )
delete aIdents[ nC ].GetAttr();
}
SfxUInt32Item* FormCache::NewAttr( sal_uInt8 nFormat, sal_uInt8 nSt )
{
// neues Format erzeugen
sal_uInt8 nL, nH; // Low-/High-Nibble
sal_uInt8 nForm = nFormat;
String aFormString;
const sal_Char* pFormString = 0;
sal_Int16 eType = NUMBERFORMAT_ALL;
sal_uInt32 nIndex1;
sal_uInt32 nHandle;
sal_Bool bDefault = sal_False;
//void GenerateFormat( aFormString, eType, COUNTRY_SYSTEM, LANGUAGE_SYSTEM,
// sal_Bool bThousand, sal_Bool IsRed, sal_uInt16 nPrecision, sal_uInt16 nAnzLeading );
if( nForm == 0xFF ) // Default-Format?
nForm = nDefaultFormat;
// Aufdroeseln in Low- und High-Nibble
nL = nFormat & 0x0F;
nH = ( nFormat & 0xF0 ) / 16;
nH &= 0x07; // Bits 4-6 'rausziehen
switch( nH )
{
case 0x00: // Festkommaformat (fixed)
//fStandard;nL;
nIndex1 = pFormTable->GetStandardFormat(
NUMBERFORMAT_NUMBER, eLanguage );
pFormTable->GenerateFormat( aFormString, nIndex1,
eLanguage, sal_False, sal_False, nL, 1 );
break;
case 0x01: // Exponentdarstellung (scientific notation)
//fExponent;nL;
nIndex1 = pFormTable->GetStandardFormat(
NUMBERFORMAT_SCIENTIFIC, eLanguage );
pFormTable->GenerateFormat( aFormString, nIndex1,
eLanguage, sal_False, sal_False, nL, 1 );
break;
case 0x02: // Waehrungsdarstellung (currency)
//fMoney;nL;
nIndex1 = pFormTable->GetStandardFormat(
NUMBERFORMAT_CURRENCY, eLanguage );
pFormTable->GenerateFormat( aFormString, nIndex1,
eLanguage, sal_False, sal_False, nL, 1 );
break;
case 0x03: // Prozent
//fPercent;nL;
nIndex1 = pFormTable->GetStandardFormat(
NUMBERFORMAT_PERCENT, eLanguage );
pFormTable->GenerateFormat( aFormString, nIndex1,
eLanguage, sal_False, sal_False, nL, 1 );
break;
case 0x04: // Komma
//fStandard;nL;
nIndex1 = pFormTable->GetStandardFormat(
NUMBERFORMAT_NUMBER, eLanguage );
pFormTable->GenerateFormat( aFormString, nIndex1,
eLanguage, sal_True, sal_False, nL, 1 );
break;
case 0x05: // frei
//fStandard;nL;
nIndex1 = pFormTable->GetStandardFormat(
NUMBERFORMAT_NUMBER, eLanguage );
pFormTable->GenerateFormat( aFormString, nIndex1,
eLanguage, sal_False, sal_False, nL, 1 );
break;
case 0x06: // frei
//fStandard;nL;
nIndex1 = pFormTable->GetStandardFormat(
NUMBERFORMAT_NUMBER, eLanguage );
pFormTable->GenerateFormat( aFormString, nIndex1,
eLanguage, sal_False, sal_False, nL, 1 );
nIndex1 = 0;
break;
case 0x07: // Spezialformat
switch( nL )
{
case 0x00: // +/-
//fStandard;nSt;
nIndex1 = pFormTable->GetStandardFormat(
NUMBERFORMAT_NUMBER, eLanguage );
pFormTable->GenerateFormat( aFormString, nIndex1,
eLanguage, sal_False, sal_True, nSt, 1 );
break;
case 0x01: // generelles Format
//fStandard;nSt;
nIndex1 = pFormTable->GetStandardFormat(
NUMBERFORMAT_NUMBER, eLanguage );
pFormTable->GenerateFormat( aFormString, nIndex1,
eLanguage, sal_False, sal_False, nSt, 1 );
break;
case 0x02: // Datum: Tag, Monat, Jahr
//fDate;dfDayMonthYearLong;
eType = NUMBERFORMAT_DATE;
pFormString = "TT.MM.JJJJ";
break;
case 0x03: // Datum: Tag, Monat
//fDate;dfDayMonthLong;
eType = NUMBERFORMAT_DATE;
pFormString = "TT.MMMM";
break;
case 0x04: // Datum: Monat, Jahr
//fDate;dfMonthYearLong;
eType = NUMBERFORMAT_DATE;
pFormString = "MM.JJJJ";
break;
case 0x05: // Textformate
//fString;nSt;
eType = NUMBERFORMAT_TEXT;
pFormString = "@";
break;
case 0x06: // versteckt
//wFlag |= paHideAll;bSetFormat = sal_False;
eType = NUMBERFORMAT_NUMBER;
pFormString = "";
break;
case 0x07: // Time: hour, min, sec
//fTime;tfHourMinSec24;
eType = NUMBERFORMAT_TIME;
pFormString = "HH:MM:SS";
break;
case 0x08: // Time: hour, min
//fTime;tfHourMin24;
eType = NUMBERFORMAT_TIME;
pFormString = "HH:MM";
break;
case 0x09: // Date, intern sal_Int32 1
//fDate;dfDayMonthYearLong;
eType = NUMBERFORMAT_DATE;
pFormString = "TT.MM.JJJJ";
break;
case 0x0A: // Date, intern sal_Int32 2
//fDate;dfDayMonthYearLong;
eType = NUMBERFORMAT_DATE;
pFormString = "TT.MM.JJJJ";
break;
case 0x0B: // Time, intern sal_Int32 1
//fTime;tfHourMinSec24;
eType = NUMBERFORMAT_TIME;
pFormString = "HH:MM:SS";
break;
case 0x0C: // Time, intern sal_Int32 2
//fTime;tfHourMinSec24;
eType = NUMBERFORMAT_TIME;
pFormString = "HH:MM:SS";
break;
case 0x0F: // Standardeinstellung
//fStandard;nSt;
bDefault = sal_True;
break;
default:
//fStandard;nSt;
bDefault = sal_True;
break;
}
break;
default:
//fStandard;nL;
nIndex1 = pFormTable->GetStandardFormat(
NUMBERFORMAT_NUMBER, eLanguage );
pFormTable->GenerateFormat( aFormString, nIndex1,
eLanguage, sal_False, sal_False, nL, 1 );
nIndex1 = 0;
break;
}
// Format in Table schieben
if( bDefault )
nHandle = 0;
else
{
if( pFormString )
aFormString.AssignAscii( pFormString );
xub_StrLen nDummy;
pFormTable->PutEntry( aFormString, nDummy, eType, nHandle, eLanguage );
}
return new SfxUInt32Item( ATTR_VALUE_FORMAT, ( sal_uInt32 ) nHandle );
}
void LotusRange::MakeHash( void )
{
// 33222222222211111111110000000000
// 10987654321098765432109876543210
// ******** nColS
// ******** nColE
// **************** nRowS
// **************** nRowE
nHash = static_cast<sal_uInt32>(nColStart);
nHash += static_cast<sal_uInt32>(nColEnd) << 6;
nHash += static_cast<sal_uInt32>(nRowStart) << 12;
nHash += static_cast<sal_uInt32>(nRowEnd ) << 16;
}
LotusRange::LotusRange( SCCOL nCol, SCROW nRow )
{
nColStart = nColEnd = nCol;
nRowStart = nRowEnd = nRow;
nId = ID_FAIL;
MakeHash();
}
LotusRange::LotusRange( SCCOL nCS, SCROW nRS, SCCOL nCE, SCROW nRE )
{
nColStart = nCS;
nColEnd = nCE;
nRowStart = nRS;
nRowEnd = nRE;
nId = ID_FAIL;
MakeHash();
}
LotusRange::LotusRange( const LotusRange& rCpy )
{
Copy( rCpy );
}
LotusRangeList::LotusRangeList( void )
{
aComplRef.InitFlags();
ScSingleRefData* pSingRef;
nIdCnt = 1;
pSingRef = &aComplRef.Ref1;
pSingRef->nTab = pSingRef->nRelTab = 0;
pSingRef->SetColRel( sal_False );
pSingRef->SetRowRel( sal_False );
pSingRef->SetTabRel( sal_True );
pSingRef->SetFlag3D( sal_False );
pSingRef = &aComplRef.Ref2;
pSingRef->nTab = pSingRef->nRelTab = 0;
pSingRef->SetColRel( sal_False );
pSingRef->SetRowRel( sal_False );
pSingRef->SetTabRel( sal_True );
pSingRef->SetFlag3D( sal_False );
}
LotusRangeList::~LotusRangeList( void )
{
LotusRange *pDel = ( LotusRange * ) List::First();
while( pDel )
{
delete pDel;
pDel = ( LotusRange * ) List::Next();
}
}
LR_ID LotusRangeList::GetIndex( const LotusRange &rRef )
{
LotusRange* pComp = ( LotusRange* ) List::First();
while( pComp )
{
if( *pComp == rRef )
return pComp->nId;
pComp = ( LotusRange* ) List::Next();
}
return ID_FAIL;
}
void LotusRangeList::Append( LotusRange* pLR, const String& rName )
{
DBG_ASSERT( pLR, "*LotusRangeList::Append(): das wird nichts!" );
List::Insert( pLR, CONTAINER_APPEND );
ScTokenArray aTokArray;
ScSingleRefData* pSingRef = &aComplRef.Ref1;
pSingRef->nCol = pLR->nColStart;
pSingRef->nRow = pLR->nRowStart;
if( pLR->IsSingle() )
aTokArray.AddSingleReference( *pSingRef );
else
{
pSingRef = &aComplRef.Ref2;
pSingRef->nCol = pLR->nColEnd;
pSingRef->nRow = pLR->nRowEnd;
aTokArray.AddDoubleReference( aComplRef );
}
ScRangeData* pData = new ScRangeData(
pLotusRoot->pDoc, rName, aTokArray );
pLotusRoot->pScRangeName->Insert( pData );
pLR->SetId( nIdCnt );
nIdCnt++;
}
RangeNameBufferWK3::RangeNameBufferWK3( void )
{
pScTokenArray = new ScTokenArray;
nIntCount = 1;
}
RangeNameBufferWK3::~RangeNameBufferWK3()
{
ENTRY* pDel = ( ENTRY* ) List::First();
while( pDel )
{
delete pDel;
pDel = ( ENTRY* ) List::Next();
}
delete pScTokenArray;
}
void RangeNameBufferWK3::Add( const String& rOrgName, const ScComplexRefData& rCRD )
{
String aScName( rOrgName );
ScfTools::ConvertToScDefinedName( aScName );
register ENTRY* pInsert = new ENTRY( rOrgName, aScName, rCRD );
List::Insert( pInsert, CONTAINER_APPEND );
pScTokenArray->Clear();
register const ScSingleRefData& rRef1 = rCRD.Ref1;
register const ScSingleRefData& rRef2 = rCRD.Ref2;
if( rRef1.nCol == rRef2.nCol && rRef1.nRow == rRef2.nRow && rRef1.nTab == rRef2.nTab )
{
pScTokenArray->AddSingleReference( rCRD.Ref1 );
pInsert->bSingleRef = sal_True;
}
else
{
pScTokenArray->AddDoubleReference( rCRD );
pInsert->bSingleRef = sal_False;
}
ScRangeData* pData = new ScRangeData( pLotusRoot->pDoc, aScName, *pScTokenArray );
pInsert->nRelInd = nIntCount;
pData->SetIndex( nIntCount );
nIntCount++;
pLotusRoot->pScRangeName->Insert( pData );
}
sal_Bool RangeNameBufferWK3::FindRel( const String& rRef, sal_uInt16& rIndex )
{
StringHashEntry aRef( rRef );
ENTRY* pFind = ( ENTRY* ) List::First();
while( pFind )
{
if( aRef == pFind->aStrHashEntry )
{
rIndex = pFind->nRelInd;
return sal_True;
}
pFind = ( ENTRY* ) List::Next();
}
return sal_False;
}
sal_Bool RangeNameBufferWK3::FindAbs( const String& rRef, sal_uInt16& rIndex )
{
String aTmp( rRef );
StringHashEntry aRef( aTmp.Erase( 0, 1 ) ); // ohne '$' suchen!
ENTRY* pFind = ( ENTRY* ) List::First();
while( pFind )
{
if( aRef == pFind->aStrHashEntry )
{
// eventuell neuen Range Name aufbauen
if( pFind->nAbsInd )
rIndex = pFind->nAbsInd;
else
{
ScSingleRefData* pRef = &pFind->aScComplexRefDataRel.Ref1;
pScTokenArray->Clear();
pRef->SetColRel( sal_False );
pRef->SetRowRel( sal_False );
pRef->SetTabRel( sal_True );
if( pFind->bSingleRef )
pScTokenArray->AddSingleReference( *pRef );
else
{
pRef = &pFind->aScComplexRefDataRel.Ref2;
pRef->SetColRel( sal_False );
pRef->SetRowRel( sal_False );
pRef->SetTabRel( sal_True );
pScTokenArray->AddDoubleReference( pFind->aScComplexRefDataRel );
}
ScRangeData* pData = new ScRangeData( pLotusRoot->pDoc, pFind->aScAbsName, *pScTokenArray );
rIndex = pFind->nAbsInd = nIntCount;
pData->SetIndex( rIndex );
nIntCount++;
pLotusRoot->pScRangeName->Insert( pData );
}
return sal_True;
}
pFind = ( ENTRY* ) List::Next();
}
return sal_False;
}