diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /sc/source/filter/lotus/tool.cxx | |
parent | Initial commit. (diff) | |
download | libreoffice-upstream.tar.xz libreoffice-upstream.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sc/source/filter/lotus/tool.cxx')
-rw-r--r-- | sc/source/filter/lotus/tool.cxx | 524 |
1 files changed, 524 insertions, 0 deletions
diff --git a/sc/source/filter/lotus/tool.cxx b/sc/source/filter/lotus/tool.cxx new file mode 100644 index 000000000..c3bf46b4f --- /dev/null +++ b/sc/source/filter/lotus/tool.cxx @@ -0,0 +1,524 @@ +/* -*- 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 <editeng/justifyitem.hxx> +#include <svl/numformat.hxx> +#include <svl/zforlist.hxx> +#include <sal/log.hxx> + +#include <attrib.hxx> +#include <document.hxx> + +#include <tool.h> +#include <lotrange.hxx> +#include <namebuff.hxx> +#include <stringutil.hxx> +#include <tokenarray.hxx> +#include "lotfilter.hxx" + +#include <math.h> + +void PutFormString(LotusContext& rContext, SCCOL nCol, SCROW nRow, SCTAB nTab, char* pString) +{ + // evaluate Label-Format + SAL_WARN_IF( pString == nullptr, "sc.filter", "PutFormString(): pString == NULL" ); + if (!pString) + return; + + char cForm; + SvxHorJustifyItem* pJustify = nullptr; + + cForm = *pString; + + switch( cForm ) + { + case '"': // align-right + pJustify = rContext.xAttrRight.get(); + pString++; + break; + case '\'': // align-left + pJustify = rContext.xAttrLeft.get(); + pString++; + break; + case '^': // centered + pJustify = rContext.xAttrCenter.get(); + pString++; + break; + case '|': // printer command + pString = nullptr; + break; + case '\\': // repetition + pJustify = rContext.xAttrRepeat.get(); + pString++; + break; + default: // undefined case! + pJustify = rContext.xAttrStandard.get(); + } + + if (!pString) + return; + + nCol = rContext.rDoc.SanitizeCol(nCol); + nRow = rContext.rDoc.SanitizeRow(nRow); + nTab = SanitizeTab(nTab); + + rContext.rDoc.ApplyAttr( nCol, nRow, nTab, *pJustify ); + ScSetStringParam aParam; + aParam.setTextInput(); + rContext.rDoc.SetString(ScAddress(nCol,nRow,nTab), OUString(pString, strlen(pString), rContext.eCharset), &aParam); +} + +void SetFormat(LotusContext& rContext, SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt8 nFormat, sal_uInt8 nSt) +{ + nCol = rContext.rDoc.SanitizeCol(nCol); + nRow = rContext.rDoc.SanitizeRow(nRow); + nTab = SanitizeTab(nTab); + + // PREC: nSt = default number of decimal places + rContext.rDoc.ApplyAttr(nCol, nRow, nTab, *(rContext.xValueFormCache->GetAttr(nFormat, nSt))); + + ScProtectionAttr aAttr; + + aAttr.SetProtection( nFormat & 0x80 ); + + rContext.rDoc.ApplyAttr( nCol, nRow, nTab, aAttr ); +} + +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 *= static_cast<sal_Int16>( nVal >> 4 ); + } + else + fVal = static_cast<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( const ScDocument* pDoc1 ) + : nIndex(0) +{ + pFormTable = pDoc1->GetFormatTable(); + for(bool & rb : bValid) + rb = false; + eLanguage = ScGlobal::eLnge; +} + +FormCache::~FormCache() +{ +} + +SfxUInt32Item* FormCache::NewAttr( sal_uInt8 nFormat, sal_uInt8 nSt ) +{ + // setup new Format + sal_uInt8 nL, nH; // Low-/High-Nibble + OUString aFormString; + SvNumFormatType eType = SvNumFormatType::ALL; + sal_uInt32 nIndex1; + sal_uInt32 nHandle; + NfIndexTableOffset eIndexTableOffset = NF_NUMERIC_START; + bool bDefault = false; + + // split into Low and High byte + nL = nFormat & 0x0F; + nH = ( nFormat & 0xF0 ) / 16; + + nH &= 0x07; // extract bits 4-6 + switch( nH ) + { + case 0x00: // fixed-point number + //fStandard;nL; + nIndex1 = pFormTable->GetStandardFormat( + SvNumFormatType::NUMBER, eLanguage ); + aFormString = pFormTable->GenerateFormat(nIndex1, + eLanguage, false, false, nL); + break; + case 0x01: // scientific notation + //fExponent;nL; + nIndex1 = pFormTable->GetStandardFormat( + SvNumFormatType::SCIENTIFIC, eLanguage ); + aFormString = pFormTable->GenerateFormat(nIndex1, + eLanguage, false, false, nL); + break; + case 0x02: // currency + //fMoney;nL; + nIndex1 = pFormTable->GetStandardFormat( + SvNumFormatType::CURRENCY, eLanguage ); + aFormString = pFormTable->GenerateFormat(nIndex1, + eLanguage, false, false, nL); + break; + case 0x03: // percentage + //fPercent;nL; + nIndex1 = pFormTable->GetStandardFormat( + SvNumFormatType::PERCENT, eLanguage ); + aFormString = pFormTable->GenerateFormat(nIndex1, + eLanguage, false, false, nL); + break; + case 0x04: // Decimal + //fStandard;nL; + nIndex1 = pFormTable->GetStandardFormat( + SvNumFormatType::NUMBER, eLanguage ); + aFormString = pFormTable->GenerateFormat(nIndex1, + eLanguage, true, false, nL); + break; + case 0x05: // unspecified + //fStandard;nL; + nIndex1 = pFormTable->GetStandardFormat( + SvNumFormatType::NUMBER, eLanguage ); + aFormString = pFormTable->GenerateFormat(nIndex1, + eLanguage, false, false, nL); + break; + case 0x06: // unspecified + //fStandard;nL; + nIndex1 = pFormTable->GetStandardFormat( + SvNumFormatType::NUMBER, eLanguage ); + aFormString = pFormTable->GenerateFormat(nIndex1, + eLanguage, false, false, nL); + break; + case 0x07: // Special format + switch( nL ) + { + case 0x00: // +/- + //fStandard;nSt; + nIndex1 = pFormTable->GetStandardFormat( + SvNumFormatType::NUMBER, eLanguage ); + aFormString = pFormTable->GenerateFormat(nIndex1, + eLanguage, false, true, nSt); + break; + case 0x01: // general Format + //fStandard;nSt; + nIndex1 = pFormTable->GetStandardFormat( + SvNumFormatType::NUMBER, eLanguage ); + aFormString = pFormTable->GenerateFormat(nIndex1, + eLanguage, false, false, nSt); + break; + case 0x02: // Date: Day, Month, Year + //fDate;dfDayMonthYearLong; + eType = SvNumFormatType::DATE; + eIndexTableOffset = NF_DATE_SYS_DDMMYYYY; + break; + case 0x03: // Date: Day, Month + //fDate;dfDayMonthLong; + eType = SvNumFormatType::DATE; + aFormString = pFormTable->GetKeyword( eLanguage, NF_KEY_DD) + + pFormTable->GetDateSep() + // matches last eLanguage + pFormTable->GetKeyword( eLanguage, NF_KEY_MMMM); + break; + case 0x04: // Date: Month, Year + //fDate;dfMonthYearLong; + eType = SvNumFormatType::DATE; + aFormString = pFormTable->GetKeyword( eLanguage, NF_KEY_MM) + + pFormTable->GetDateSep() + // matches last eLanguage + pFormTable->GetKeyword( eLanguage, NF_KEY_YYYY); + break; + case 0x05: // Text formats + //fString;nSt; + eType = SvNumFormatType::TEXT; + eIndexTableOffset = NF_TEXT; + break; + case 0x06: // hidden + //wFlag |= paHideAll;bSetFormat = sal_False; + eType = SvNumFormatType::NUMBER; + aFormString = "\"\""; + break; + case 0x07: // Time: hour, min, sec + //fTime;tfHourMinSec24; + eType = SvNumFormatType::TIME; + eIndexTableOffset = NF_TIME_HHMMSS; + break; + case 0x08: // Time: hour, min + //fTime;tfHourMin24; + eType = SvNumFormatType::TIME; + eIndexTableOffset = NF_TIME_HHMM; + break; + case 0x09: // Date, intern sal_Int32 1 + //fDate;dfDayMonthYearLong; + eType = SvNumFormatType::DATE; + eIndexTableOffset = NF_DATE_SYS_DDMMYYYY; + break; + case 0x0A: // Date, intern sal_Int32 2 + //fDate;dfDayMonthYearLong; + eType = SvNumFormatType::DATE; + eIndexTableOffset = NF_DATE_SYS_DDMMYYYY; + break; + case 0x0B: // Time, intern sal_Int32 1 + //fTime;tfHourMinSec24; + eType = SvNumFormatType::TIME; + eIndexTableOffset = NF_TIME_HHMMSS; + break; + case 0x0C: // Time, intern sal_Int32 2 + //fTime;tfHourMinSec24; + eType = SvNumFormatType::TIME; + eIndexTableOffset = NF_TIME_HHMMSS; + break; + case 0x0F: // Default + //fStandard;nSt; + bDefault = true; + break; + default: + //fStandard;nSt; + bDefault = true; + break; + } + break; + } + + // push Format into table + 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, nHandle ); +} + +void LotusRange::MakeHash() +{ + // 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() +{ + 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 () +{ +} + +LR_ID LotusRangeList::GetIndex( const LotusRange &rRef ) +{ + auto pIter = std::find_if(maRanges.begin(), maRanges.end(), + [&rRef](const std::unique_ptr<LotusRange>& pRange) { return rRef == *pRange; }); + if (pIter != maRanges.end()) + return (*pIter)->nId; + + return ID_FAIL; +} + +void LotusRangeList::Append( const ScDocument* pDoc, std::unique_ptr<LotusRange> pLR ) +{ + assert( pLR ); + auto pLRTmp = pLR.get(); + maRanges.push_back(std::move(pLR)); + + ScTokenArray aTokArray(*pDoc); + + ScSingleRefData* pSingRef = &aComplRef.Ref1; + + pSingRef->SetAbsCol(pLRTmp->nColStart); + pSingRef->SetAbsRow(pLRTmp->nRowStart); + + if( pLRTmp->IsSingle() ) + aTokArray.AddSingleReference( *pSingRef ); + else + { + pSingRef = &aComplRef.Ref2; + pSingRef->SetAbsCol(pLRTmp->nColEnd); + pSingRef->SetAbsRow(pLRTmp->nRowEnd); + aTokArray.AddDoubleReference( aComplRef ); + } + + pLRTmp->SetId( nIdCnt ); + + nIdCnt++; +} + +RangeNameBufferWK3::RangeNameBufferWK3(const ScDocument& rDoc) + : pScTokenArray( new ScTokenArray(rDoc) ) +{ + nIntCount = 1; +} + +RangeNameBufferWK3::~RangeNameBufferWK3() +{ +} + +void RangeNameBufferWK3::Add( const ScDocument& rDoc, const OUString& rOrgName, const ScComplexRefData& rCRD ) +{ + Entry aInsert( rOrgName, rCRD ); + + pScTokenArray->Clear(); + + const ScSingleRefData& rRef1 = rCRD.Ref1; + const ScSingleRefData& rRef2 = rCRD.Ref2; + ScAddress aAbs1 = rRef1.toAbs(rDoc, ScAddress()); + ScAddress aAbs2 = rRef2.toAbs(rDoc, ScAddress()); + if (aAbs1 == aAbs2) + { + pScTokenArray->AddSingleReference( rCRD.Ref1 ); + aInsert.bSingleRef = true; + } + else + { + pScTokenArray->AddDoubleReference( rCRD ); + aInsert.bSingleRef = false; + } + + aInsert.nRelInd = nIntCount; + nIntCount++; + + maEntries.push_back( aInsert ); +} + +bool RangeNameBufferWK3::FindRel( const OUString& rRef, sal_uInt16& rIndex ) +{ + StringHashEntry aRef( rRef ); + + std::vector<Entry>::const_iterator itr = std::find_if(maEntries.begin(), maEntries.end(), + [&aRef](const Entry& rEntry) { return aRef == rEntry.aStrHashEntry; }); + if (itr != maEntries.end()) + { + rIndex = itr->nRelInd; + return true; + } + + return false; +} + +bool RangeNameBufferWK3::FindAbs( std::u16string_view rRef, sal_uInt16& rIndex ) +{ + if (rRef.empty()) + return false; + StringHashEntry aRef(OUString(rRef.substr(1))); // search w/o '$'! + + std::vector<Entry>::iterator itr = std::find_if(maEntries.begin(), maEntries.end(), + [&aRef](const Entry& rEntry) { return aRef == rEntry.aStrHashEntry; }); + if (itr != maEntries.end()) + { + // setup new range if needed + 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 ); + } + + rIndex = itr->nAbsInd = nIntCount; + nIntCount++; + } + + return true; + } + + return false; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |