/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * 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 . */ #include "scitems.hxx" #include #include #include #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 "stringutil.hxx" #include "tokenarray.hxx" #include // External variable extern WKTYP eTyp; // -> filter.cxx, aktueller Dateityp extern ScDocument* pDoc; // -> filter.cxx, Aufhaenger zum Dokumentzugriff // Global variable 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 OSL_ENSURE( 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; } if (!pString) return; pDoc->ApplyAttr( nCol, nRow, nTab, *pJustify ); ScSetStringParam aParam; aParam.setTextInput(); pDoc->SetString(ScAddress(nCol,nRow,nTab), OUString(pString, strlen(pString), pLotusRoot->eCharsetQ), &aParam); } 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 ) : nIndex(0) { // Default-Format ist 'Default' nDefaultFormat = nNewDefaultFormat; pFormTable = pDoc1->GetFormatTable(); for( sal_uInt16 nC = 0 ; nC < __nSize ; nC++ ) bValid[ nC ] = 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; OUString aFormString; sal_Int16 eType = NUMBERFORMAT_ALL; sal_uInt32 nIndex1; sal_uInt32 nHandle; NfIndexTableOffset eIndexTableOffset = NF_NUMERIC_START; bool bDefault = false; 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 ); aFormString = pFormTable->GenerateFormat(nIndex1, eLanguage, false, false, nL, 1); break; case 0x01: // Exponentdarstellung (scientific notation) //fExponent;nL; nIndex1 = pFormTable->GetStandardFormat( NUMBERFORMAT_SCIENTIFIC, eLanguage ); aFormString = pFormTable->GenerateFormat(nIndex1, eLanguage, false, false, nL, 1); break; case 0x02: // Waehrungsdarstellung (currency) //fMoney;nL; nIndex1 = pFormTable->GetStandardFormat( NUMBERFORMAT_CURRENCY, eLanguage ); aFormString = pFormTable->GenerateFormat(nIndex1, eLanguage, false, false, nL, 1); break; case 0x03: // Prozent //fPercent;nL; nIndex1 = pFormTable->GetStandardFormat( NUMBERFORMAT_PERCENT, eLanguage ); aFormString = pFormTable->GenerateFormat(nIndex1, eLanguage, false, false, nL, 1); break; case 0x04: // Komma //fStandard;nL; nIndex1 = pFormTable->GetStandardFormat( NUMBERFORMAT_NUMBER, eLanguage ); aFormString = pFormTable->GenerateFormat(nIndex1, eLanguage, true, false, nL, 1); break; case 0x05: // frei //fStandard;nL; nIndex1 = pFormTable->GetStandardFormat( NUMBERFORMAT_NUMBER, eLanguage ); aFormString = pFormTable->GenerateFormat(nIndex1, eLanguage, false, false, nL, 1); break; case 0x06: // frei //fStandard;nL; nIndex1 = pFormTable->GetStandardFormat( NUMBERFORMAT_NUMBER, eLanguage ); aFormString = pFormTable->GenerateFormat(nIndex1, eLanguage, false, false, nL, 1); nIndex1 = 0; break; case 0x07: // Spezialformat switch( nL ) { case 0x00: // +/- //fStandard;nSt; nIndex1 = pFormTable->GetStandardFormat( NUMBERFORMAT_NUMBER, eLanguage ); aFormString = pFormTable->GenerateFormat(nIndex1, eLanguage, false, true, nSt, 1); break; case 0x01: // generelles Format //fStandard;nSt; nIndex1 = pFormTable->GetStandardFormat( NUMBERFORMAT_NUMBER, eLanguage ); aFormString = pFormTable->GenerateFormat(nIndex1, eLanguage, false, false, nSt, 1); break; case 0x02: // Datum: Tag, Monat, Jahr //fDate;dfDayMonthYearLong; eType = NUMBERFORMAT_DATE; eIndexTableOffset = NF_DATE_SYS_DDMMYYYY; break; case 0x03: // Datum: Tag, Monat //fDate;dfDayMonthLong; eType = NUMBERFORMAT_DATE; aFormString = pFormTable->GetKeyword( eLanguage, NF_KEY_DD); aFormString += pFormTable->GetDateSep(); // matches last eLanguage aFormString += pFormTable->GetKeyword( eLanguage, NF_KEY_MMMM); break; case 0x04: // Datum: Monat, Jahr //fDate;dfMonthYearLong; eType = NUMBERFORMAT_DATE; aFormString = pFormTable->GetKeyword( eLanguage, NF_KEY_MM); aFormString += pFormTable->GetDateSep(); // matches last eLanguage aFormString += pFormTable->GetKeyword( eLanguage, NF_KEY_YYYY); break; case 0x05: // Textformate //fString;nSt; eType = NUMBERFORMAT_TEXT; eIndexTableOffset = NF_TEXT; break; case 0x06: // versteckt //wFlag |= paHideAll;bSetFormat = sal_False; eType = NUMBERFORMAT_NUMBER; aFormString = "\"\""; break; case 0x07: // Time: hour, min, sec //fTime;tfHourMinSec24; eType = NUMBERFORMAT_TIME; eIndexTableOffset = NF_TIME_HHMMSS; break; case 0x08: // Time: hour, min //fTime;tfHourMin24; eType = NUMBERFORMAT_TIME; eIndexTableOffset = NF_TIME_HHMM; break; case 0x09: // Date, intern sal_Int32 1 //fDate;dfDayMonthYearLong; eType = NUMBERFORMAT_DATE; eIndexTableOffset = NF_DATE_SYS_DDMMYYYY; break; case 0x0A: // Date, intern sal_Int32 2 //fDate;dfDayMonthYearLong; eType = NUMBERFORMAT_DATE; eIndexTableOffset = NF_DATE_SYS_DDMMYYYY; break; case 0x0B: // Time, intern sal_Int32 1 //fTime;tfHourMinSec24; eType = NUMBERFORMAT_TIME; eIndexTableOffset = NF_TIME_HHMMSS; break; case 0x0C: // Time, intern sal_Int32 2 //fTime;tfHourMinSec24; eType = NUMBERFORMAT_TIME; eIndexTableOffset = NF_TIME_HHMMSS; break; case 0x0F: // Standardeinstellung //fStandard;nSt; bDefault = true; break; default: //fStandard;nSt; bDefault = true; break; } break; } // Format in Table schieben if( bDefault ) nHandle = 0; else if (eIndexTableOffset != NF_NUMERIC_START) nHandle = pFormTable->GetFormatIndex( eIndexTableOffset, eLanguage); else { sal_Int32 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->SetRelTab(0); pSingRef->SetColRel( false ); pSingRef->SetRowRel( false ); pSingRef->SetFlag3D( false ); pSingRef = &aComplRef.Ref2; pSingRef->SetRelTab(0); pSingRef->SetColRel( false ); pSingRef->SetRowRel( false ); pSingRef->SetFlag3D( false ); } LotusRangeList::~LotusRangeList () { std::vector::iterator pIter; for (pIter = maRanges.begin(); pIter != maRanges.end(); ++pIter) delete (*pIter); } LR_ID LotusRangeList::GetIndex( const LotusRange &rRef ) { std::vector::iterator pIter; for (pIter = maRanges.begin(); pIter != maRanges.end(); ++pIter) { if (rRef == *(*pIter)) return (*pIter)->nId; } return ID_FAIL; } void LotusRangeList::Append( LotusRange* pLR, const OUString& rName ) { OSL_ENSURE( pLR, "*LotusRangeList::Append(): das wird nichts!" ); maRanges.push_back(pLR); ScTokenArray aTokArray; ScSingleRefData* pSingRef = &aComplRef.Ref1; pSingRef->SetAbsCol(pLR->nColStart); pSingRef->SetAbsRow(pLR->nRowStart); if( pLR->IsSingle() ) aTokArray.AddSingleReference( *pSingRef ); else { pSingRef = &aComplRef.Ref2; pSingRef->SetAbsCol(pLR->nColEnd); pSingRef->SetAbsRow(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() { delete pScTokenArray; } void RangeNameBufferWK3::Add( const OUString& rOrgName, const ScComplexRefData& rCRD ) { OUString aScName = ScfTools::ConvertToScDefinedName(rOrgName); Entry aInsert( rOrgName, aScName, rCRD ); pScTokenArray->Clear(); const ScSingleRefData& rRef1 = rCRD.Ref1; const ScSingleRefData& rRef2 = rCRD.Ref2; ScAddress aAbs1 = rRef1.toAbs(ScAddress()); ScAddress aAbs2 = rRef2.toAbs(ScAddress()); if (aAbs1 == aAbs2) { pScTokenArray->AddSingleReference( rCRD.Ref1 ); aInsert.bSingleRef = true; } else { pScTokenArray->AddDoubleReference( rCRD ); aInsert.bSingleRef = false; } ScRangeData* pData = new ScRangeData( pLotusRoot->pDoc, aScName, *pScTokenArray ); aInsert.nRelInd = nIntCount; pData->SetIndex( nIntCount ); nIntCount++; maEntries.push_back( aInsert ); pLotusRoot->pScRangeName->insert( pData ); } bool RangeNameBufferWK3::FindRel( const OUString& rRef, sal_uInt16& rIndex ) { StringHashEntry aRef( rRef ); std::vector::const_iterator itr; for ( itr = maEntries.begin(); itr != maEntries.end(); ++itr ) { if ( aRef == itr->aStrHashEntry ) { rIndex = itr->nRelInd; return true; } } return false; } bool RangeNameBufferWK3::FindAbs( const OUString& rRef, sal_uInt16& rIndex ) { OUString aTmp( rRef ); aTmp = aTmp.copy(1); StringHashEntry aRef( aTmp ); // ohne '$' suchen! std::vector::iterator itr; for ( itr = maEntries.begin(); itr != maEntries.end(); ++itr ) { if ( aRef == itr->aStrHashEntry ) { // eventuell neuen Range Name aufbauen if( itr->nAbsInd ) rIndex = itr->nAbsInd; else { ScSingleRefData* pRef = &itr->aScComplexRefDataRel.Ref1; pScTokenArray->Clear(); pRef->SetColRel( false ); pRef->SetRowRel( false ); pRef->SetTabRel( true ); if( itr->bSingleRef ) pScTokenArray->AddSingleReference( *pRef ); else { pRef = &itr->aScComplexRefDataRel.Ref2; pRef->SetColRel( false ); pRef->SetRowRel( false ); pRef->SetTabRel( true ); pScTokenArray->AddDoubleReference( itr->aScComplexRefDataRel ); } ScRangeData* pData = new ScRangeData( pLotusRoot->pDoc, itr->aScAbsName, *pScTokenArray ); rIndex = itr->nAbsInd = nIntCount; pData->SetIndex( rIndex ); nIntCount++; pLotusRoot->pScRangeName->insert( pData ); } return true; } } return false; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */