/************************************************************** * * 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_scfilt.hxx" //------------------------------------------------------------------------ #include "scitems.hxx" #include #include #include #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 #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(nColStart); nHash += static_cast(nColEnd) << 6; nHash += static_cast(nRowStart) << 12; nHash += static_cast(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; }