/* -*- 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/.
*/
#include <limits>
#include <memory>
#include <orcusinterface.hxx>
#include <document.hxx>
#include <formulacell.hxx>
#include <rangenam.hxx>
#include <tokenarray.hxx>
#include <globalnames.hxx>
#include <globstr.hrc>
#include <scresid.hxx>
#include <compiler.hxx>
#include <stlpool.hxx>
#include <scitems.hxx>
#include <patattr.hxx>
#include <docpool.hxx>
#include <attrib.hxx>
#include <editeng/postitem.hxx>
#include <editeng/wghtitem.hxx>
#include <editeng/colritem.hxx>
#include <editeng/brushitem.hxx>
#include <editeng/udlnitem.hxx>
#include <editeng/boxitem.hxx>
#include <editeng/borderline.hxx>
#include <editeng/fontitem.hxx>
#include <editeng/fhgtitem.hxx>
#include <editeng/lineitem.hxx>
#include <editeng/crossedoutitem.hxx>
#include <editeng/justifyitem.hxx>
#include <editeng/eeitem.hxx>
#include <svl/sharedstringpool.hxx>
#include <svl/numformat.hxx>
#include <svl/zforlist.hxx>
#include <svl/intitem.hxx>
#include <com/sun/star/task/XStatusIndicator.hpp>
#include <i18nlangtag/lang.h>
#include <o3tl/unit_conversion.hxx>
#include <tools/fontenum.hxx>
#include <sal/log.hxx>
#include <stylesbuffer.hxx>
#include <orcus/exception.hpp>
#include <stylehelper.hxx>
#include <utility>
#include <unordered_map>
#include <frozen/bits/defines.h>
#include <frozen/bits/elsa_std.h>
#include <frozen/unordered_map.h>
using namespace com::sun::star;
namespace os = orcus::spreadsheet;
namespace {
formula::FormulaGrammar::Grammar getCalcGrammarFromOrcus( os::formula_grammar_t grammar )
{
formula::FormulaGrammar::Grammar eGrammar = formula::FormulaGrammar::GRAM_ODFF;
switch(grammar)
{
case orcus::spreadsheet::formula_grammar_t::ods:
eGrammar = formula::FormulaGrammar::GRAM_ODFF;
break;
case orcus::spreadsheet::formula_grammar_t::xlsx:
eGrammar = formula::FormulaGrammar::GRAM_OOXML;
break;
case orcus::spreadsheet::formula_grammar_t::gnumeric:
eGrammar = formula::FormulaGrammar::GRAM_ENGLISH_XL_A1;
break;
case orcus::spreadsheet::formula_grammar_t::xls_xml:
eGrammar = formula::FormulaGrammar::GRAM_ENGLISH_XL_R1C1;
break;
case orcus::spreadsheet::formula_grammar_t::unknown:
break;
}
return eGrammar;
}
}
ScOrcusGlobalSettings::ScOrcusGlobalSettings(ScDocumentImport& rDoc)
: mrDoc(rDoc)
, meCalcGrammar(formula::FormulaGrammar::GRAM_UNSPECIFIED)
, meOrcusGrammar(os::formula_grammar_t::unknown)
, mnTextEncoding(RTL_TEXTENCODING_UTF8)
{
}
void ScOrcusGlobalSettings::set_origin_date(int year, int month, int day)
{
mrDoc.setOriginDate(year, month, day);
}
void ScOrcusGlobalSettings::set_character_set(orcus::character_set_t cs)
{
// Keep the entries sorted by the key.
static constexpr auto rules = frozen::make_unordered_map<orcus::character_set_t, rtl_TextEncoding>({
{ orcus::character_set_t::big5, RTL_TEXTENCODING_BIG5 },
{ orcus::character_set_t::euc_jp, RTL_TEXTENCODING_EUC_JP },
{ orcus::character_set_t::euc_kr, RTL_TEXTENCODING_EUC_KR },
{ orcus::character_set_t::gb2312, RTL_TEXTENCODING_GB_2312 },
{ orcus::character_set_t::gbk, RTL_TEXTENCODING_GBK },
{ orcus::character_set_t::iso_2022_cn, RTL_TEXTENCODING_ISO_2022_CN },
{ orcus::character_set_t::iso_2022_cn_ext, RTL_TEXTENCODING_ISO_2022_CN },
{ orcus::character_set_t::iso_2022_jp, RTL_TEXTENCODING_ISO_2022_JP },
{ orcus::character_set_t::iso_2022_jp_2, RTL_TEXTENCODING_ISO_2022_JP },
{ orcus::character_set_t::iso_8859_1, RTL_TEXTENCODING_ISO_8859_1 },
{ orcus::character_set_t::iso_8859_14, RTL_TEXTENCODING_ISO_8859_14 },
{ orcus::character_set_t::iso_8859_15, RTL_TEXTENCODING_ISO_8859_15 },
{ orcus::character_set_t::iso_8859_1_windows_3_0_latin_1, RTL_TEXTENCODING_ISO_8859_1 },
{ orcus::character_set_t::iso_8859_1_windows_3_1_latin_1, RTL_TEXTENCODING_ISO_8859_1 },
{ orcus::character_set_t::iso_8859_2, RTL_TEXTENCODING_ISO_8859_2 },
{ orcus::character_set_t::iso_8859_2_windows_latin_2, RTL_TEXTENCODING_ISO_8859_2 },
{ orcus::character_set_t::iso_8859_3, RTL_TEXTENCODING_ISO_8859_3 },
{ orcus::character_set_t::iso_8859_4, RTL_TEXTENCODING_ISO_8859_4 },
{ orcus::character_set_t::iso_8859_5, RTL_TEXTENCODING_ISO_8859_5 },
{ orcus::character_set_t::iso_8859_6, RTL_TEXTENCODING_ISO_8859_6 },
{ orcus::character_set_t::iso_8859_6_e, RTL_TEXTENCODING_ISO_8859_6 },
{ orcus::character_set_t::iso_8859_6_i, RTL_TEXTENCODING_ISO_8859_6 },
{ orcus::character_set_t::iso_8859_7, RTL_TEXTENCODING_ISO_8859_7 },
{ orcus::character_set_t::iso_8859_8, RTL_TEXTENCODING_ISO_8859_8 },
{ orcus::character_set_t::iso_8859_8_e, RTL_TEXTENCODING_ISO_8859_8 },
{ orcus::character_set_t::iso_8859_8_i, RTL_TEXTENCODING_ISO_8859_8 },
{ orcus::character_set_t::iso_8859_9, RTL_TEXTENCODING_ISO_8859_9 },
{ orcus::character_set_t::iso_8859_9_windows_latin_5, RTL_TEXTENCODING_ISO_8859_9 },
{ orcus::character_set_t::jis_x0201, RTL_TEXTENCODING_JIS_X_0201 },
{ orcus::character_set_t::jis_x0212_1990, RTL_TEXTENCODING_JIS_X_0212 },
{ orcus::character_set_t::shift_jis, RTL_TEXTENCODING_SHIFT_JIS },
{ orcus::character_set_t::us_ascii, RTL_TEXTENCODING_ASCII_US },
{ orcus::character_set_t::utf_7, RTL_TEXTENCODING_UTF7 },
{ orcus::character_set_t::utf_8, RTL_TEXTENCODING_UTF8 },
{ orcus::character_set_t::windows_1250, RTL_TEXTENCODING_MS_1250 },
{ orcus::character_set_t::windows_1251, RTL_TEXTENCODING_MS_1251 },
{ orcus::character_set_t::windows_1252, RTL_TEXTENCODING_MS_1252 },
{ orcus::character_set_t::windows_1253, RTL_TEXTENCODING_MS_1253 },
{ orcus::character_set_t::windows_1254, RTL_TEXTENCODING_MS_1254 },
{ orcus::character_set_t::windows_1255, RTL_TEXTENCODING_MS_1255 },
{ orcus::character_set_t::windows_1256, RTL_TEXTENCODING_MS_1256 },
{ orcus::character_set_t::windows_1257, RTL_TEXTENCODING_MS_1257 },
{ orcus::character_set_t::windows_1258, RTL_TEXTENCODING_MS_1258 },
});
if (auto it = rules.find(cs); it != rules.end())
mnTextEncoding = it->second;
}
void ScOrcusGlobalSettings::set_default_formula_grammar(os::formula_grammar_t grammar)
{
meCalcGrammar = getCalcGrammarFromOrcus(grammar);
meOrcusGrammar = grammar;
}
orcus::spreadsheet::formula_grammar_t ScOrcusGlobalSettings::get_default_formula_grammar() const
{
return meOrcusGrammar;
}
ScOrcusRefResolver::ScOrcusRefResolver( const ScOrcusGlobalSettings& rGS ) :
mrGlobalSettings(rGS) {}
os::src_address_t ScOrcusRefResolver::resolve_address(std::string_view address)
{
OUString aStr(address.data(), address.size(), mrGlobalSettings.getTextEncoding());
ScAddress aAddr;
aAddr.Parse(aStr, mrGlobalSettings.getDoc().getDoc(),
formula::FormulaGrammar::extractRefConvention(
mrGlobalSettings.getCalcGrammar()));
if (!aAddr.IsValid())
{
std::ostringstream os;
os << "'" << address << "' is not a valid address expression.";
throw orcus::invalid_arg_error(os.str());
}
os::src_address_t ret;
ret.sheet = aAddr.Tab();
ret.column = aAddr.Col();
ret.row = aAddr.Row();
return ret;
}
os::src_range_t ScOrcusRefResolver::resolve_range(std::string_view range)
{
OUString aStr(range.data(), range.size(), mrGlobalSettings.getTextEncoding());
ScRange aRange;
aRange.Parse(aStr, mrGlobalSettings.getDoc().getDoc(),
formula::FormulaGrammar::extractRefConvention(
mrGlobalSettings.getCalcGrammar()));
if (!aRange.IsValid())
{
std::ostringstream os;
os << "'" << range << "' is not a valid range expression.";
throw orcus::invalid_arg_error(os.str());
}
os::src_range_t ret;
ret.first.sheet = aRange.aStart.Tab();
ret.first.column = aRange.aStart.Col();
ret.first.row = aRange.aStart.Row();
ret.last.sheet = aRange.aEnd.Tab();
ret.last.column = aRange.aEnd.Col();
ret.last.row = aRange.aEnd.Row();
return ret;
}
ScOrcusNamedExpression::ScOrcusNamedExpression(
ScDocumentImport& rDoc, const ScOrcusGlobalSettings& rGS, SCTAB nTab ) :
mrDoc(rDoc), mrGlobalSettings(rGS), mnTab(nTab) {}
void ScOrcusNamedExpression::reset()
{
maBasePos.SetTab(0);
maBasePos.SetCol(0);
maBasePos.SetRow(0);
maName.clear();
maExpr.clear();
}
void ScOrcusNamedExpression::set_base_position(const orcus::spreadsheet::src_address_t& pos)
{
maBasePos.SetTab(pos.sheet);
maBasePos.SetCol(pos.column);
maBasePos.SetRow(pos.row);
}
void ScOrcusNamedExpression::set_named_expression(std::string_view name, std::string_view expression)
{
maName = OUString(name.data(), name.size(), mrGlobalSettings.getTextEncoding());
maExpr = OUString(expression.data(), expression.size(), mrGlobalSettings.getTextEncoding());
}
void ScOrcusNamedExpression::set_named_range(std::string_view /*name*/, std::string_view /*range*/)
{
throw std::runtime_error("ScOrcusNamedExpression::set_named_range not implemented yet.");
}
void ScOrcusNamedExpression::commit()
{
ScRangeName* pNames = mnTab >= 0 ? mrDoc.getDoc().GetRangeName(mnTab) : mrDoc.getDoc().GetRangeName();
if (!pNames)
return;
ScRangeData* pRange = new ScRangeData(
mrDoc.getDoc(), maName, maExpr, maBasePos, ScRangeData::Type::Name,
mrGlobalSettings.getCalcGrammar());
pNames->insert(pRange, false);
reset(); // make sure to reset the state for the next run.
}
ScOrcusFactory::CellStoreToken::CellStoreToken(const ScAddress& rPos, Type eType)
: mfValue(std::numeric_limits<double>::quiet_NaN())
, maPos(rPos)
, meType(eType)
, mnIndex1(0)
, mnIndex2(0)
, meGrammar(formula::FormulaGrammar::GRAM_UNSPECIFIED)
{
}
ScOrcusFactory::CellStoreToken::CellStoreToken(const ScAddress& rPos, double fValue)
: mfValue(fValue)
, maPos(rPos)
, meType(Type::Numeric)
, mnIndex1(0)
, mnIndex2(0)
, meGrammar(formula::FormulaGrammar::GRAM_UNSPECIFIED)
{
}
ScOrcusFactory::CellStoreToken::CellStoreToken(const ScAddress& rPos, uint32_t nIndex)
: mfValue(std::numeric_limits<double>::quiet_NaN())
, maPos(rPos)
, meType(Type::String)
, mnIndex1(nIndex)
, mnIndex2(0)
, meGrammar(formula::FormulaGrammar::GRAM_UNSPECIFIED)
{
}
ScOrcusFactory::CellStoreToken::CellStoreToken(const ScAddress& rPos, OUString aFormula,
formula::FormulaGrammar::Grammar eGrammar)
: maStr1(std::move(aFormula))
, mfValue(std::numeric_limits<double>::quiet_NaN())
, maPos(rPos)
, meType(Type::Formula)
, mnIndex1(0)
, mnIndex2(0)
, meGrammar(eGrammar)
{
}
ScOrcusFactory::ScOrcusFactory(ScDocument& rDoc, bool bSkipDefaultStyles) :
maDoc(rDoc),
maGlobalSettings(maDoc),
maRefResolver(maGlobalSettings),
maSharedStrings(*this),
maNamedExpressions(maDoc, maGlobalSettings),
maStyles(*this, bSkipDefaultStyles),
mnProgress(0) {}
orcus::spreadsheet::iface::import_sheet* ScOrcusFactory::append_sheet(
orcus::spreadsheet::sheet_t sheet_index, std::string_view sheet_name)
{
OUString aTabName(sheet_name.data(), sheet_name.size(), maGlobalSettings.getTextEncoding());
if (sheet_index == 0)
{
// The calc document initializes with one sheet already present.
assert(maDoc.getSheetCount() == 1);
maDoc.setSheetName(0, aTabName);
maSheets.push_back(std::make_unique<ScOrcusSheet>(maDoc, 0, *this));
return maSheets.back().get();
}
if (!maDoc.appendSheet(aTabName))
return nullptr;
SCTAB nTab = maDoc.getSheetCount() - 1;
maSheets.push_back(std::make_unique<ScOrcusSheet>(maDoc, nTab, *this));
return maSheets.back().get();
}
namespace {
class FindSheetByIndex
{
SCTAB mnTab;
public:
explicit FindSheetByIndex(SCTAB nTab) : mnTab(nTab) {}
bool operator() (const std::unique_ptr<ScOrcusSheet>& rSheet) const
{
return rSheet->getIndex() == mnTab;
}
};
}
orcus::spreadsheet::iface::import_sheet* ScOrcusFactory::get_sheet(std::string_view sheet_name)
{
OUString aTabName(sheet_name.data(), sheet_name.size(), maGlobalSettings.getTextEncoding());
SCTAB nTab = maDoc.getSheetIndex(aTabName);
if (nTab < 0)
// Sheet by that name not found.
return nullptr;
// See if we already have an orcus sheet instance by that index.
std::vector< std::unique_ptr<ScOrcusSheet> >::iterator it =
std::find_if(maSheets.begin(), maSheets.end(), FindSheetByIndex(nTab));
if (it != maSheets.end())
// We already have one. Return it.
return it->get();
// Create a new orcus sheet instance for this.
maSheets.push_back(std::make_unique<ScOrcusSheet>(maDoc, nTab, *this));
return maSheets.back().get();
}
orcus::spreadsheet::iface::import_sheet* ScOrcusFactory::get_sheet(orcus::spreadsheet::sheet_t sheet_index)
{
SCTAB nTab = static_cast<SCTAB>(sheet_index);
// See if we already have an orcus sheet instance by that index.
std::vector< std::unique_ptr<ScOrcusSheet> >::iterator it =
std::find_if(maSheets.begin(), maSheets.end(), FindSheetByIndex(nTab));
if (it != maSheets.end())
// We already have one. Return it.
return it->get();
// Create a new orcus sheet instance for this.
maSheets.push_back(std::make_unique<ScOrcusSheet>(maDoc, nTab, *this));
return maSheets.back().get();
}
orcus::spreadsheet::iface::import_global_settings* ScOrcusFactory::get_global_settings()
{
return &maGlobalSettings;
}
orcus::spreadsheet::iface::import_shared_strings* ScOrcusFactory::get_shared_strings()
{
return &maSharedStrings;
}
orcus::spreadsheet::iface::import_named_expression* ScOrcusFactory::get_named_expression()
{
return &maNamedExpressions;
}
orcus::spreadsheet::iface::import_styles* ScOrcusFactory::get_styles()
{
return &maStyles;
}
os::iface::import_reference_resolver* ScOrcusFactory::get_reference_resolver(os::formula_ref_context_t cxt)
{
switch (cxt)
{
case os::formula_ref_context_t::global:
return &maRefResolver;
case os::formula_ref_context_t::named_expression_base:
case os::formula_ref_context_t::named_range:
return nullptr;
}
return nullptr;
}
void ScOrcusFactory::finalize()
{
auto toFormulaCell = [this]( const CellStoreToken& rToken ) -> std::unique_ptr<ScFormulaCell>
{
const ScOrcusSheet& rSheet = *maSheets.at(rToken.maPos.Tab());
const sc::SharedFormulaGroups& rSFG = rSheet.getSharedFormulaGroups();
const ScTokenArray* pArray = rSFG.get(rToken.mnIndex1);
if (!pArray)
return std::unique_ptr<ScFormulaCell>();
return std::make_unique<ScFormulaCell>(maDoc.getDoc(), rToken.maPos, *pArray);
};
int nCellCount = 0;
for (const CellStoreToken& rToken : maCellStoreTokens)
{
switch (rToken.meType)
{
case CellStoreToken::Type::Auto:
{
maDoc.setAutoInput(rToken.maPos, rToken.maStr1);
++nCellCount;
break;
}
case CellStoreToken::Type::String:
{
if (rToken.mnIndex1 >= maStrings.size())
// String index out-of-bound! Something is up.
break;
const auto& s = maStrings[rToken.mnIndex1];
switch (s.index())
{
case 0: // OUString
maDoc.setStringCell(rToken.maPos, std::get<0>(s));
break;
case 1: // std::unique_ptr<EditTextObject>
maDoc.setEditCell(rToken.maPos, std::get<1>(s)->Clone());
break;
}
++nCellCount;
break;
}
case CellStoreToken::Type::Numeric:
{
maDoc.setNumericCell(rToken.maPos, rToken.mfValue);
++nCellCount;
break;
}
case CellStoreToken::Type::Formula:
{
maDoc.setFormulaCell(
rToken.maPos, rToken.maStr1, rToken.meGrammar);
++nCellCount;
break;
}
case CellStoreToken::Type::FormulaWithResult:
{
if (std::isfinite(rToken.mfValue))
maDoc.setFormulaCell(rToken.maPos, rToken.maStr1, rToken.meGrammar, &rToken.mfValue);
else
maDoc.setFormulaCell(rToken.maPos, rToken.maStr1, rToken.meGrammar, rToken.maStr2);
++nCellCount;
break;
}
case CellStoreToken::Type::SharedFormula:
{
std::unique_ptr<ScFormulaCell> pCell = toFormulaCell(rToken);
if (!pCell)
break;
maDoc.setFormulaCell(rToken.maPos, pCell.release());
++nCellCount;
break;
}
case CellStoreToken::Type::SharedFormulaWithResult:
{
std::unique_ptr<ScFormulaCell> pCell = toFormulaCell(rToken);
if (!pCell)
break;
if (std::isfinite(rToken.mfValue))
pCell->SetResultDouble(rToken.mfValue);
else
pCell->SetHybridString(
maDoc.getDoc().GetSharedStringPool().intern(rToken.maStr2));
maDoc.setFormulaCell(rToken.maPos, pCell.release());
++nCellCount;
break;
}
case CellStoreToken::Type::Matrix:
{
if (!rToken.mnIndex1 || !rToken.mnIndex2)
break;
ScRange aRange(rToken.maPos);
aRange.aEnd.IncCol(rToken.mnIndex1-1);
aRange.aEnd.IncRow(rToken.mnIndex2-1);
ScCompiler aComp(maDoc.getDoc(), aRange.aStart, rToken.meGrammar);
std::unique_ptr<ScTokenArray> pArray(aComp.CompileString(rToken.maStr1));
if (!pArray)
break;
maDoc.setMatrixCells(aRange, *pArray, rToken.meGrammar);
break;
}
case CellStoreToken::Type::FillDownCells:
{
if (!rToken.mnIndex1)
break;
maDoc.fillDownCells(rToken.maPos, rToken.mnIndex1);
break;
}
default:
;
}
if (nCellCount == 100000)
{
incrementProgress();
nCellCount = 0;
}
}
if (mxStatusIndicator.is())
mxStatusIndicator->end();
maDoc.finalize();
}
ScDocumentImport& ScOrcusFactory::getDoc()
{
return maDoc;
}
size_t ScOrcusFactory::appendString(const OUString& rStr)
{
size_t nPos = maStrings.size();
maStrings.push_back(rStr);
maStringHash.emplace(rStr, nPos);
return nPos;
}
size_t ScOrcusFactory::addString(const OUString& rStr)
{
// Add only if the string is not yet present in the string pool.
StringHashType::iterator it = maStringHash.find(rStr);
if (it != maStringHash.end())
return it->second;
return appendString(rStr);
}
std::size_t ScOrcusFactory::appendFormattedString(std::unique_ptr<EditTextObject> pEditText)
{
std::size_t nPos = maStrings.size();
maStrings.push_back(std::move(pEditText));
return nPos;
}
const OUString* ScOrcusFactory::getString(size_t nIndex) const
{
if (nIndex >= maStrings.size())
return nullptr;
const StringValueType& rStr = maStrings[nIndex];
if (rStr.index() != 0)
return nullptr;
return &std::get<OUString>(rStr);
}
void ScOrcusFactory::pushCellStoreAutoToken( const ScAddress& rPos, const OUString& rVal )
{
maCellStoreTokens.emplace_back(rPos, CellStoreToken::Type::Auto);
maCellStoreTokens.back().maStr1 = rVal;
}
void ScOrcusFactory::pushCellStoreToken( const ScAddress& rPos, uint32_t nStrIndex )
{
maCellStoreTokens.emplace_back(rPos, nStrIndex);
}
void ScOrcusFactory::pushCellStoreToken( const ScAddress& rPos, double fValue )
{
maCellStoreTokens.emplace_back(rPos, fValue);
}
void ScOrcusFactory::pushCellStoreToken(
const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar )
{
maCellStoreTokens.emplace_back(rPos, rFormula, eGrammar);
}
void ScOrcusFactory::pushFillDownCellsToken( const ScAddress& rPos, uint32_t nFillSize )
{
maCellStoreTokens.emplace_back(rPos, CellStoreToken::Type::FillDownCells);
maCellStoreTokens.back().mnIndex1 = nFillSize;
}
void ScOrcusFactory::pushSharedFormulaToken( const ScAddress& rPos, uint32_t nIndex )
{
maCellStoreTokens.emplace_back(rPos, CellStoreToken::Type::SharedFormula);
maCellStoreTokens.back().mnIndex1 = nIndex;
}
void ScOrcusFactory::pushMatrixFormulaToken(
const ScAddress& rPos, const OUString& rFormula, formula::FormulaGrammar::Grammar eGrammar,
uint32_t nRowRange, uint32_t nColRange )
{
maCellStoreTokens.emplace_back(rPos, CellStoreToken::Type::Matrix);
CellStoreToken& rT = maCellStoreTokens.back();
rT.maStr1 = rFormula;
rT.meGrammar = eGrammar;
rT.mnIndex1 = nColRange;
rT.mnIndex2 = nRowRange;
}
void ScOrcusFactory::pushFormulaResult( const ScAddress& rPos, double fValue )
{
// Formula result is expected to be pushed immediately following the
// formula token it belongs.
if (maCellStoreTokens.empty())
return;
CellStoreToken& rToken = maCellStoreTokens.back();
if (rToken.maPos != rPos)
return;
switch (rToken.meType)
{
case CellStoreToken::Type::Formula:
rToken.meType = CellStoreToken::Type::FormulaWithResult;
break;
case CellStoreToken::Type::SharedFormula:
rToken.meType = CellStoreToken::Type::SharedFormulaWithResult;
break;
default:
return;
}
rToken.mfValue = fValue;
}
void ScOrcusFactory::pushFormulaResult( const ScAddress& rPos, const OUString& rValue )
{
// Formula result is expected to be pushed immediately following the
// formula token it belongs.
if (maCellStoreTokens.empty())
return;
CellStoreToken& rToken = maCellStoreTokens.back();
if (rToken.maPos != rPos)
return;
switch (rToken.meType)
{
case CellStoreToken::Type::Formula:
rToken.meType = CellStoreToken::Type::FormulaWithResult;
break;
case CellStoreToken::Type::SharedFormula:
rToken.meType = CellStoreToken::Type::SharedFormulaWithResult;
break;
default:
return;
}
rToken.maStr2 = rValue;
}
void ScOrcusFactory::incrementProgress()
{
if (!mxStatusIndicator.is())
// Status indicator object not set.
return;
// For now, we'll hard-code the progress range to be 100, and stops at 99
// in all cases.
if (!mnProgress)
mxStatusIndicator->start(ScResId(STR_LOAD_DOC), 100);
if (mnProgress == 99)
return;
++mnProgress;
mxStatusIndicator->setValue(mnProgress);
}
void ScOrcusFactory::setStatusIndicator(const uno::Reference<task::XStatusIndicator>& rIndicator)
{
mxStatusIndicator = rIndicator;
}
const ScOrcusGlobalSettings& ScOrcusFactory::getGlobalSettings() const
{
return maGlobalSettings;
}
ScOrcusSheetProperties::ScOrcusSheetProperties(SCTAB nTab, ScDocumentImport& rDoc):
mrDoc(rDoc),
mnTab(nTab)
{
}
ScOrcusSheetProperties::~ScOrcusSheetProperties()
{
}
namespace {
double translateToInternal(double nVal, orcus::length_unit_t unit)
{
switch(unit)
{
case orcus::length_unit_t::inch:
return o3tl::convert(nVal, o3tl::Length::in, o3tl::Length::twip);
case orcus::length_unit_t::twip:
return nVal;
case orcus::length_unit_t::point:
return o3tl::convert(nVal, o3tl::Length::pt, o3tl::Length::twip);
case orcus::length_unit_t::centimeter:
return o3tl::convert(nVal, o3tl::Length::cm, o3tl::Length::twip);
case orcus::length_unit_t::millimeter:
return o3tl::convert(nVal, o3tl::Length::mm, o3tl::Length::twip);
case orcus::length_unit_t::unknown:
if (nVal != 0)
SAL_WARN("sc.orcus", "unknown unit");
break;
default:
break;
}
return nVal;
}
}
void ScOrcusSheetProperties::set_column_width(os::col_t col, os::col_t col_span, double width, orcus::length_unit_t unit)
{
double nNewWidth = translateToInternal(width, unit);
for (os::col_t offset = 0; offset < col_span; ++offset)
mrDoc.getDoc().SetColWidthOnly(col + offset, mnTab, nNewWidth);
}
void ScOrcusSheetProperties::set_column_hidden(os::col_t col, os::col_t col_span, bool hidden)
{
if (hidden)
mrDoc.getDoc().SetColHidden(col, col + col_span - 1, mnTab, hidden);
}
void ScOrcusSheetProperties::set_row_height(os::row_t row, double height, orcus::length_unit_t unit)
{
double nNewHeight = translateToInternal(height, unit);
mrDoc.getDoc().SetRowHeightOnly(row, row,mnTab, nNewHeight);
}
void ScOrcusSheetProperties::set_row_hidden(os::row_t row, bool hidden)
{
if (hidden)
mrDoc.getDoc().SetRowHidden(row, row, mnTab, hidden);
}
void ScOrcusSheetProperties::set_merge_cell_range(const orcus::spreadsheet::range_t& range)
{
mrDoc.setMergedCells(mnTab, range.first.column, range.first.row, range.last.column, range.last.row);
}
ScOrcusConditionalFormat::ScOrcusConditionalFormat(SCTAB nTab, ScDocument& rDoc):
mnTab(nTab),
mrDoc(rDoc),
mpCurrentFormat(new ScConditionalFormat(0, &mrDoc)),
meEntryType(ScFormatEntry::Type::Condition)
{
}
ScOrcusConditionalFormat::~ScOrcusConditionalFormat()
{
}
void ScOrcusConditionalFormat::set_color(os::color_elem_t /*alpha*/, os::color_elem_t /*red*/,
os::color_elem_t /*green*/, os::color_elem_t /*blue*/)
{
SAL_INFO("sc.orcus.condformat", "set_color");
}
void ScOrcusConditionalFormat::set_condition_type(os::condition_type_t /*type*/)
{
assert(meEntryType == ScFormatEntry::Type::Condition);
SAL_INFO("sc.orcus.condformat", "set_condition_type");
}
void ScOrcusConditionalFormat::set_formula(std::string_view /*formula*/)
{
SAL_INFO("sc.orcus.condformat", "set_formula");
}
void ScOrcusConditionalFormat::set_date(os::condition_date_t /*date*/)
{
assert(meEntryType == ScFormatEntry::Type::Date);
SAL_INFO("sc.orcus.condformat", "set_date");
}
void ScOrcusConditionalFormat::commit_condition()
{
SAL_INFO("sc.orcus.condformat", "commit_condition");
}
void ScOrcusConditionalFormat::set_icon_name(std::string_view /*name*/)
{
assert(meEntryType == ScFormatEntry::Type::Iconset);
SAL_INFO("sc.orcus.condformat", "set_icon_name");
}
void ScOrcusConditionalFormat::set_databar_gradient(bool /*gradient*/)
{
assert(meEntryType == ScFormatEntry::Type::Databar);
SAL_INFO("sc.orcus.condformat", "set_databar_gradient");
}
void ScOrcusConditionalFormat::set_databar_axis(os::databar_axis_t /*axis*/)
{
assert(meEntryType == ScFormatEntry::Type::Databar);
SAL_INFO("sc.orcus.condformat", "set_databar_axis");
}
void ScOrcusConditionalFormat::set_databar_color_positive(os::color_elem_t /*alpha*/, os::color_elem_t /*red*/,
os::color_elem_t /*green*/, os::color_elem_t /*blue*/)
{
assert(meEntryType == ScFormatEntry::Type::Databar);
SAL_INFO("sc.orcus.condformat", "set_databar_color_positive");
}
void ScOrcusConditionalFormat::set_databar_color_negative(os::color_elem_t /*alpha*/, os::color_elem_t /*red*/,
os::color_elem_t /*green*/, os::color_elem_t /*blue*/)
{
assert(meEntryType == ScFormatEntry::Type::Databar);
SAL_INFO("sc.orcus.condformat", "set_databar_color_negative");
}
void ScOrcusConditionalFormat::set_min_databar_length(double /*length*/)
{
assert(meEntryType == ScFormatEntry::Type::Databar);
SAL_INFO("sc.orcus.condformat", "set_min_databar_length");
}
void ScOrcusConditionalFormat::set_max_databar_length(double /*length*/)
{
assert(meEntryType == ScFormatEntry::Type::Databar);
SAL_INFO("sc.orcus.condformat", "set_max_databar_length");
}
void ScOrcusConditionalFormat::set_show_value(bool /*show*/)
{
SAL_INFO("sc.orcus.condformat", "set_show_value");
}
void ScOrcusConditionalFormat::set_iconset_reverse(bool /*reverse*/)
{
assert(meEntryType == ScFormatEntry::Type::Iconset);
SAL_INFO("sc.orcus.condformat", "set_iconset_reverse");
}
void ScOrcusConditionalFormat::set_xf_id(size_t /*xf*/)
{
SAL_INFO("sc.orcus.condformat", "set_xf_id");
}
void ScOrcusConditionalFormat::set_operator(os::condition_operator_t /*condition_type*/)
{
SAL_INFO("sc.orcus.condformat", "set_operator");
}
void ScOrcusConditionalFormat::set_type(os::conditional_format_t type)
{
switch (type)
{
case os::conditional_format_t::condition:
case os::conditional_format_t::formula:
meEntryType = ScFormatEntry::Type::Condition;
// mpCurrentEntry.reset(new ScCondFormatEntry());
break;
case os::conditional_format_t::date:
break;
case os::conditional_format_t::colorscale:
break;
case os::conditional_format_t::databar:
break;
case os::conditional_format_t::iconset:
break;
default:
SAL_INFO("sc.orcus.condformat", "unknown conditional_format_t value");
break;
}
SAL_INFO("sc.orcus.condformat", "set_type");
}
void ScOrcusConditionalFormat::commit_entry()
{
SAL_INFO("sc.orcus.condformat", "commit_entry");
}
void ScOrcusConditionalFormat::set_range(std::string_view /*range*/)
{
SAL_INFO("sc.orcus.condformat", "set_range");
}
void ScOrcusConditionalFormat::set_range(os::row_t row_start, os::col_t col_start,
os::row_t row_end, os::col_t col_end)
{
SAL_INFO("sc.orcus.condformat", "set_range");
ScRange aRange(col_start, row_start, mnTab, col_end, row_end, mnTab);
mpCurrentFormat->SetRange(aRange);
}
void ScOrcusConditionalFormat::commit_format()
{
SAL_INFO("sc.orcus.condformat", "commit_format");
mpCurrentFormat.reset(new ScConditionalFormat(0, &mrDoc));
}
ScOrcusSheet::ScOrcusSheet(ScDocumentImport& rDoc, SCTAB nTab, ScOrcusFactory& rFactory) :
mrDoc(rDoc),
mnTab(nTab),
mrFactory(rFactory),
mrStyles(static_cast<ScOrcusStyles&>(*mrFactory.get_styles())),
maAutoFilter(rFactory.getGlobalSettings()),
maProperties(mnTab, mrDoc),
maConditionalFormat(mnTab, rDoc.getDoc()),
maNamedExpressions(rDoc, rFactory.getGlobalSettings(), nTab),
maFormula(*this),
maArrayFormula(*this),
mnCellCount(0)
{
}
void ScOrcusFormula::reset()
{
mnCol = -1;
mnRow = -1;
maFormula.clear();
meGrammar = formula::FormulaGrammar::GRAM_UNSPECIFIED;
mnSharedFormulaIndex = 0;
mbShared = false;
meResType = ResultType::NotSet;
maResult.clear();
mfResult = 0.0;
}
ScOrcusFormula::ScOrcusFormula( ScOrcusSheet& rSheet ) :
mrSheet(rSheet),
mnCol(-1),
mnRow(-1),
meGrammar(formula::FormulaGrammar::GRAM_UNSPECIFIED),
mnSharedFormulaIndex(0),
mbShared(false),
meResType(ResultType::NotSet),
mfResult(0.0) {}
ScOrcusFormula::~ScOrcusFormula() {}
void ScOrcusFormula::set_position(os::row_t row, os::col_t col)
{
mnCol = col;
mnRow = row;
}
void ScOrcusFormula::set_formula(os::formula_grammar_t grammar, std::string_view formula)
{
maFormula = OUString(formula.data(), formula.size(), mrSheet.getFactory().getGlobalSettings().getTextEncoding());
meGrammar = getCalcGrammarFromOrcus(grammar);
}
void ScOrcusFormula::set_shared_formula_index(size_t index)
{
mnSharedFormulaIndex = index;
mbShared = true;
}
void ScOrcusFormula::set_result_value(double value)
{
meResType = ResultType::Value;
mfResult = value;
}
void ScOrcusFormula::set_result_string(std::string_view value)
{
meResType = ResultType::String;
maResult = OUString(value.data(), value.size(), mrSheet.getFactory().getGlobalSettings().getTextEncoding());
}
void ScOrcusFormula::set_result_empty()
{
meResType = ResultType::Empty;
}
void ScOrcusFormula::set_result_bool(bool value)
{
meResType = ResultType::Value;
mfResult = value ? 1.0 : 0.0;
}
void ScOrcusFormula::commit()
{
ScOrcusFactory& rFactory = mrSheet.getFactory();
sc::SharedFormulaGroups& rGroups = mrSheet.getSharedFormulaGroups();
ScAddress aPos(mnCol, mnRow, mrSheet.getIndex());
if (mbShared)
{
if (maFormula.isEmpty())
{
// shared formula that references existing formula token.
const ScTokenArray* pArray = rGroups.get(mnSharedFormulaIndex);
if (!pArray)
return;
}
else
{
// topmost shared formula with new formula token.
// Compile the formula expression into tokens.
ScCompiler aComp(mrSheet.getDoc().getDoc(), aPos, meGrammar);
std::unique_ptr<ScTokenArray> pArray = aComp.CompileString(maFormula);
if (!pArray)
// Tokenization failed.
return;
rGroups.set(mnSharedFormulaIndex, std::move(pArray));
}
rFactory.pushSharedFormulaToken(aPos, mnSharedFormulaIndex);
}
else
{
// non-shared formula
rFactory.pushCellStoreToken(aPos, maFormula, meGrammar);
}
switch (meResType)
{
case ResultType::String:
{
rFactory.pushFormulaResult(aPos, maResult);
break;
}
case ResultType::Value:
rFactory.pushFormulaResult(aPos, mfResult);
break;
default:
;
}
mrSheet.cellInserted();
}
void ScOrcusArrayFormula::reset()
{
mnCol = -1;
mnRow = -1;
mnColRange = 0;
mnRowRange = 0;
maFormula.clear();
meGrammar = formula::FormulaGrammar::GRAM_UNSPECIFIED;
}
ScOrcusArrayFormula::ScOrcusArrayFormula( ScOrcusSheet& rSheet ) :
mrSheet(rSheet),
mnCol(-1),
mnRow(-1),
mnColRange(0),
mnRowRange(0),
meGrammar(formula::FormulaGrammar::GRAM_UNSPECIFIED) {}
ScOrcusArrayFormula::~ScOrcusArrayFormula() {}
void ScOrcusArrayFormula::set_range(const os::range_t& range)
{
mnCol = range.first.column;
mnRow = range.first.row;
mnColRange = range.last.column - range.first.column + 1;
mnRowRange = range.last.row - range.first.column + 1;
}
void ScOrcusArrayFormula::set_formula(os::formula_grammar_t grammar, std::string_view formula)
{
meGrammar = getCalcGrammarFromOrcus(grammar);
maFormula = OUString(formula.data(), formula.size(), mrSheet.getFactory().getGlobalSettings().getTextEncoding());
}
void ScOrcusArrayFormula::set_result_value(os::row_t /*row*/, os::col_t /*col*/, double /*value*/)
{
// TODO : implement result cache for matrix
}
void ScOrcusArrayFormula::set_result_string(os::row_t /*row*/, os::col_t /*col*/, std::string_view /*value*/)
{
// TODO : implement result cache for matrix
}
void ScOrcusArrayFormula::set_result_empty(os::row_t /*row*/, os::col_t /*col*/)
{
// TODO : implement result cache for matrix
}
void ScOrcusArrayFormula::set_result_bool(os::row_t /*row*/, os::col_t /*col*/, bool /*value*/)
{
// TODO : implement result cache for matrix
}
void ScOrcusArrayFormula::commit()
{
ScAddress aPos(mnCol, mnRow, mrSheet.getIndex());
mrSheet.getFactory().pushMatrixFormulaToken(aPos, maFormula, meGrammar, mnRowRange, mnColRange);
mrSheet.cellInserted();
}
void ScOrcusSheet::cellInserted()
{
++mnCellCount;
if (mnCellCount == 100000)
{
mrFactory.incrementProgress();
mnCellCount = 0;
}
}
ScDocumentImport& ScOrcusSheet::getDoc()
{
return mrDoc;
}
os::iface::import_auto_filter* ScOrcusSheet::get_auto_filter()
{
return &maAutoFilter;
}
os::iface::import_table* ScOrcusSheet::get_table()
{
return nullptr;
}
os::iface::import_sheet_properties* ScOrcusSheet::get_sheet_properties()
{
return &maProperties;
}
os::iface::import_conditional_format* ScOrcusSheet::get_conditional_format()
{
return &maConditionalFormat;
}
os::iface::import_named_expression* ScOrcusSheet::get_named_expression()
{
return &maNamedExpressions;
}
os::iface::import_formula* ScOrcusSheet::get_formula()
{
maFormula.reset();
return &maFormula;
}
os::iface::import_array_formula* ScOrcusSheet::get_array_formula()
{
maArrayFormula.reset();
return &maArrayFormula;
}
void ScOrcusSheet::set_auto(os::row_t row, os::col_t col, std::string_view value)
{
OUString aVal(value.data(), value.size(), mrFactory.getGlobalSettings().getTextEncoding());
mrFactory.pushCellStoreAutoToken(ScAddress(col, row, mnTab), aVal);
cellInserted();
}
void ScOrcusSheet::set_string(os::row_t row, os::col_t col, os::string_id_t sindex)
{
mrFactory.pushCellStoreToken(ScAddress(col, row, mnTab), sindex);
cellInserted();
}
void ScOrcusSheet::set_value(os::row_t row, os::col_t col, double value)
{
mrFactory.pushCellStoreToken(ScAddress(col, row, mnTab), value);
cellInserted();
}
void ScOrcusSheet::set_bool(os::row_t row, os::col_t col, bool value)
{
mrFactory.pushCellStoreToken(ScAddress(col, row, mnTab), value ? 1.0 : 0.0);
cellInserted();
}
void ScOrcusSheet::set_date_time(
os::row_t row, os::col_t col, int year, int month, int day, int hour, int minute, double second)
{
SvNumberFormatter* pFormatter = mrDoc.getDoc().GetFormatTable();
Date aDate(day, month, year);
sal_uInt32 nSec = floor(second);
sal_uInt32 nNanoSec = (second - nSec) * ::tools::Time::nanoSecPerSec;
tools::Time aTime(hour, minute, nSec, nNanoSec);
tools::Long nDateDiff = aDate - pFormatter->GetNullDate();
double fTime =
static_cast<double>(aTime.GetNanoSec()) / ::tools::Time::nanoSecPerSec +
aTime.GetSec() +
aTime.GetMin() * ::tools::Time::secondPerMinute +
aTime.GetHour() * ::tools::Time::secondPerHour;
fTime /= DATE_TIME_FACTOR;
mrFactory.pushCellStoreToken(ScAddress(col, row, mnTab), nDateDiff + fTime);
cellInserted();
}
void ScOrcusSheet::set_format(os::row_t row, os::col_t col, size_t xf_index)
{
SAL_INFO("sc.orcus.style", "set format: " << xf_index);
ScPatternAttr aPattern(mrDoc.getDoc().getCellAttributeHelper());
mrStyles.applyXfToItemSet(aPattern.GetItemSet(), xf_index);
mrDoc.getDoc().ApplyPattern(col, row, mnTab, aPattern);
}
void ScOrcusSheet::set_format(os::row_t row_start, os::col_t col_start,
os::row_t row_end, os::col_t col_end, size_t xf_index)
{
SAL_INFO("sc.orcus.style", "set format range: " << xf_index);
ScPatternAttr aPattern(mrDoc.getDoc().getCellAttributeHelper());
mrStyles.applyXfToItemSet(aPattern.GetItemSet(), xf_index);
mrDoc.getDoc().ApplyPatternAreaTab(col_start, row_start, col_end, row_end, mnTab, aPattern);
}
void ScOrcusSheet::set_column_format(
os::col_t col, os::col_t col_span, std::size_t xf_index)
{
ScPatternAttr aPattern(mrDoc.getDoc().getCellAttributeHelper());
mrStyles.applyXfToItemSet(aPattern.GetItemSet(), xf_index);
mrDoc.getDoc().ApplyPatternAreaTab(
col, 0, col + col_span - 1, mrDoc.getDoc().MaxRow(), mnTab, aPattern);
}
void ScOrcusSheet::set_row_format(os::row_t row, std::size_t xf_index)
{
ScPatternAttr aPattern(mrDoc.getDoc().getCellAttributeHelper());
mrStyles.applyXfToItemSet(aPattern.GetItemSet(), xf_index);
mrDoc.getDoc().ApplyPatternAreaTab(
0, row, mrDoc.getDoc().MaxCol(), row, mnTab, aPattern);
}
orcus::spreadsheet::range_size_t ScOrcusSheet::get_sheet_size() const
{
orcus::spreadsheet::range_size_t ret;
ret.rows = MAXROWCOUNT;
ret.columns = MAXCOLCOUNT;
return ret;
}
void ScOrcusSheet::fill_down_cells(os::row_t row, os::col_t col, os::row_t range_size)
{
mrFactory.pushFillDownCellsToken(ScAddress(col, row, mnTab), range_size);
cellInserted();
}
const sc::SharedFormulaGroups& ScOrcusSheet::getSharedFormulaGroups() const
{
return maFormulaGroups;
}
sc::SharedFormulaGroups& ScOrcusSheet::getSharedFormulaGroups()
{
return maFormulaGroups;
}
ScOrcusFactory& ScOrcusSheet::getFactory()
{
return mrFactory;
}
OUString ScOrcusSharedStrings::toOUString(std::string_view s)
{
return {s.data(), sal_Int32(s.size()), mrFactory.getGlobalSettings().getTextEncoding()};
}
ScOrcusSharedStrings::ScOrcusSharedStrings(ScOrcusFactory& rFactory) :
mrFactory(rFactory),
mrEditEngine(rFactory.getDoc().getDoc().GetEditEngine()),
maCurFormat(mrEditEngine.GetEmptyItemSet())
{
mrEditEngine.Clear();
}
size_t ScOrcusSharedStrings::append(std::string_view s)
{
return mrFactory.appendString(toOUString(s));
}
size_t ScOrcusSharedStrings::add(std::string_view s)
{
return mrFactory.addString(toOUString(s));
}
void ScOrcusSharedStrings::set_segment_font(size_t /*font_index*/)
{
}
void ScOrcusSharedStrings::set_segment_bold(bool b)
{
FontWeight eWeight = b ? WEIGHT_BOLD : WEIGHT_NORMAL;
maCurFormat.Put(SvxWeightItem(eWeight, EE_CHAR_WEIGHT));
}
void ScOrcusSharedStrings::set_segment_italic(bool b)
{
FontItalic eItalic = b ? ITALIC_NORMAL : ITALIC_NONE;
maCurFormat.Put(SvxPostureItem(eItalic, EE_CHAR_ITALIC));
}
void ScOrcusSharedStrings::set_segment_font_name(std::string_view s)
{
OUString aName = toOUString(s);
maCurFormat.Put(
SvxFontItem(
FAMILY_DONTKNOW, aName, aName, PITCH_DONTKNOW,
mrFactory.getGlobalSettings().getTextEncoding(),
EE_CHAR_FONTINFO
)
);
}
void ScOrcusSharedStrings::set_segment_font_size(double point)
{
// points to 100th of millimeters
tools::Long nMM = o3tl::convert(point, o3tl::Length::pt, o3tl::Length::mm100);
maCurFormat.Put(SvxFontHeightItem(nMM, 100, EE_CHAR_FONTHEIGHT));
}
void ScOrcusSharedStrings::set_segment_font_color(
os::color_elem_t alpha, os::color_elem_t red, os::color_elem_t green, os::color_elem_t blue)
{
Color aColor(ColorAlpha, alpha, red, green, blue);
maCurFormat.Put(SvxColorItem(aColor, EE_CHAR_COLOR));
}
void ScOrcusSharedStrings::append_segment(std::string_view s)
{
sal_Int32 nPos = mrEditEngine.GetText().getLength();
ESelection aSel{0, nPos, 0, nPos}; // end of current text
OUString aStr = toOUString(s);
mrEditEngine.QuickInsertText(aStr, aSel);
aSel.nEndPos += aStr.getLength(); // expand the selection over the current segment
maFormatSegments.emplace_back(aSel, maCurFormat);
maCurFormat.ClearItem();
}
size_t ScOrcusSharedStrings::commit_segments()
{
for (const auto& [rSel, rFormat] : maFormatSegments)
mrEditEngine.QuickSetAttribs(rFormat, rSel);
auto nPos = mrFactory.appendFormattedString(mrEditEngine.CreateTextObject());
mrEditEngine.Clear();
maFormatSegments.clear();
return nPos;
}
void ScOrcusFont::applyToItemSet( SfxItemSet& rSet ) const
{
if (mbBold)
{
FontWeight eWeight = *mbBold ? WEIGHT_BOLD : WEIGHT_NORMAL;
rSet.Put(SvxWeightItem(eWeight, ATTR_FONT_WEIGHT));
}
if (mbBoldAsian)
{
FontWeight eWeight = *mbBoldAsian ? WEIGHT_BOLD : WEIGHT_NORMAL;
rSet.Put(SvxWeightItem(eWeight, ATTR_CJK_FONT_WEIGHT));
}
if (mbBoldComplex)
{
FontWeight eWeight = *mbBoldComplex ? WEIGHT_BOLD : WEIGHT_NORMAL;
rSet.Put(SvxWeightItem(eWeight, ATTR_CTL_FONT_WEIGHT));
}
if (mbItalic)
{
FontItalic eItalic = *mbItalic ? ITALIC_NORMAL : ITALIC_NONE;
rSet.Put(SvxPostureItem(eItalic, ATTR_FONT_POSTURE));
}
if (mbItalicAsian)
{
FontItalic eItalic = *mbItalicAsian ? ITALIC_NORMAL : ITALIC_NONE;
rSet.Put(SvxPostureItem(eItalic, ATTR_CJK_FONT_POSTURE));
}
if (mbItalicComplex)
{
FontItalic eItalic = *mbItalicComplex ? ITALIC_NORMAL : ITALIC_NONE;
rSet.Put(SvxPostureItem(eItalic, ATTR_CTL_FONT_POSTURE));
}
if (maColor)
rSet.Put( SvxColorItem(*maColor, ATTR_FONT_COLOR));
if (maName && !maName->isEmpty())
rSet.Put( SvxFontItem( FAMILY_DONTKNOW, *maName, *maName, PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, ATTR_FONT ));
if (maNameAsian && !maNameAsian->isEmpty())
rSet.Put( SvxFontItem( FAMILY_DONTKNOW, *maNameAsian, *maNameAsian, PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, ATTR_CJK_FONT ));
if (maNameComplex && !maNameComplex->isEmpty())
rSet.Put( SvxFontItem( FAMILY_DONTKNOW, *maNameComplex, *maNameComplex, PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, ATTR_CTL_FONT ));
if (mnSize)
{
double fSize = translateToInternal(*mnSize, orcus::length_unit_t::point);
rSet.Put(SvxFontHeightItem(fSize, 100, ATTR_FONT_HEIGHT));
}
if (mnSizeAsian)
{
double fSize = translateToInternal(*mnSizeAsian, orcus::length_unit_t::point);
rSet.Put(SvxFontHeightItem(fSize, 100, ATTR_CJK_FONT_HEIGHT));
}
if (mnSizeComplex)
{
double fSize = translateToInternal(*mnSizeComplex, orcus::length_unit_t::point);
rSet.Put(SvxFontHeightItem(fSize, 100, ATTR_CTL_FONT_HEIGHT));
}
if (meUnderline)
{
SvxUnderlineItem aUnderline(*meUnderline, ATTR_FONT_UNDERLINE);
if (maUnderlineColor)
// Separate color specified for the underline
aUnderline.SetColor(*maUnderlineColor);
else if (maColor)
// Use font color
aUnderline.SetColor(*maColor);
rSet.Put(aUnderline);
}
if (meStrikeout)
rSet.Put(SvxCrossedOutItem(*meStrikeout, ATTR_FONT_CROSSEDOUT));
}
void ScOrcusFill::applyToItemSet( SfxItemSet& rSet ) const
{
if (!mePattern || !maFgColor)
return;
if (*mePattern == os::fill_pattern_t::solid)
rSet.Put(SvxBrushItem(*maFgColor, ATTR_BACKGROUND));
}
void ScOrcusBorder::applyToItemSet( SfxItemSet& rSet ) const
{
auto getDirection = [](os::border_direction_t dir) -> SvxBoxItemLine
{
switch (dir)
{
case os::border_direction_t::right:
return SvxBoxItemLine::RIGHT;
case os::border_direction_t::left:
return SvxBoxItemLine::LEFT;
case os::border_direction_t::top:
return SvxBoxItemLine::TOP;
case os::border_direction_t::bottom:
return SvxBoxItemLine::BOTTOM;
default:
;
}
return SvxBoxItemLine::RIGHT;
};
if (maBorders.empty())
return;
SvxBoxItem aBoxItem(ATTR_BORDER);
SvxLineItem aDiagonal_TLBR(ATTR_BORDER_TLBR);
SvxLineItem aDiagonal_BLTR(ATTR_BORDER_BLTR);
for (const auto& [dir, attrs] : maBorders)
{
SvxBoxItemLine eDir = getDirection(dir);
SvxBorderLineStyle eStyle = attrs.meStyle.value_or(SvxBorderLineStyle::SOLID);
Color aColor = attrs.maColor.value_or(COL_BLACK);
double nWidth = attrs.mnWidth.value_or(0.0);
switch (dir)
{
case os::border_direction_t::diagonal_tl_br:
{
editeng::SvxBorderLine aLine(&aColor, nWidth, eStyle);
aDiagonal_TLBR.SetLine(&aLine);
break;
}
case os::border_direction_t::diagonal_bl_tr:
{
editeng::SvxBorderLine aLine(&aColor, nWidth, eStyle);
aDiagonal_BLTR.SetLine(&aLine);
break;
}
default:
{
editeng::SvxBorderLine aLine(&aColor, nWidth, eStyle);
aBoxItem.SetLine(&aLine, eDir);
}
}
}
rSet.Put(aDiagonal_BLTR);
rSet.Put(aDiagonal_TLBR);
rSet.Put(aBoxItem);
}
void ScOrcusProtection::applyToItemSet( SfxItemSet& rSet ) const
{
if (!mbLocked.has_value() && !mbHidden.has_value() && !mbPrintContent.has_value() && !mbFormulaHidden.has_value())
return;
bool bLocked = mbLocked.value_or(true); // defaults to true.
bool bHidden = mbHidden.value_or(false);
bool bFormulaHidden = mbFormulaHidden.value_or(false);
bool bPrintContent = mbPrintContent.value_or(false);
rSet.Put(ScProtectionAttr(bLocked, bFormulaHidden, bHidden, bPrintContent));
}
void ScOrcusNumberFormat::applyToItemSet( SfxItemSet& rSet, const ScDocument& rDoc ) const
{
if (!maCode)
return;
sal_uInt32 nKey;
sal_Int32 nCheckPos;
SvNumberFormatter* pFormatter = rDoc.GetFormatTable();
OUString Code = *maCode; /* <-- Done because the SvNumberFormatter::PutEntry demands a non const NumFormat Code*/
SvNumFormatType type = SvNumFormatType::ALL;
pFormatter->PutEntry(Code, nCheckPos, type, nKey, LANGUAGE_ENGLISH_US);
if (!nCheckPos)
rSet.Put(SfxUInt32Item(ATTR_VALUE_FORMAT, nKey));
}
ScOrcusXf::ScOrcusXf() :
mnFontId(0),
mnFillId(0),
mnBorderId(0),
mnProtectionId(0),
mnNumberFormatId(0),
mnStyleXf(0),
mbApplyAlignment(false),
mbWrapText(false),
mbShrinkToFit(false),
meHorAlignment(SvxCellHorJustify::Standard),
meVerAlignment(SvxCellVerJustify::Standard),
meHorAlignMethod(SvxCellJustifyMethod::Auto),
meVerAlignMethod(SvxCellJustifyMethod::Auto)
{
}
ScOrcusCellStyle::ScOrcusCellStyle() :
maParentName(SC_STYLE_PROG_STANDARD),
mnXFId(0),
mnBuiltInId(0)
{
}
ScOrcusImportFontStyle::ScOrcusImportFontStyle( ScOrcusFactory& rFactory, std::vector<ScOrcusFont>& rFonts ) :
mrFactory(rFactory),
mrFonts(rFonts)
{
}
void ScOrcusImportFontStyle::reset()
{
maCurrentFont = ScOrcusFont();
}
void ScOrcusImportFontStyle::set_bold(bool b)
{
maCurrentFont.mbBold = b;
}
void ScOrcusImportFontStyle::set_bold_asian(bool b)
{
maCurrentFont.mbBoldAsian = b;
}
void ScOrcusImportFontStyle::set_bold_complex(bool b)
{
maCurrentFont.mbBoldComplex = b;
}
void ScOrcusImportFontStyle::set_italic(bool b)
{
maCurrentFont.mbItalic = b;
}
void ScOrcusImportFontStyle::set_italic_asian(bool b)
{
maCurrentFont.mbItalicAsian = b;
}
void ScOrcusImportFontStyle::set_italic_complex(bool b)
{
maCurrentFont.mbItalicComplex = b;
}
void ScOrcusImportFontStyle::set_name(std::string_view name)
{
OUString aName(name.data(), name.size(), mrFactory.getGlobalSettings().getTextEncoding());
maCurrentFont.maName = aName;
}
void ScOrcusImportFontStyle::set_name_asian(std::string_view name)
{
OUString aName(name.data(), name.size(), mrFactory.getGlobalSettings().getTextEncoding());
maCurrentFont.maNameAsian = aName;
}
void ScOrcusImportFontStyle::set_name_complex(std::string_view name)
{
OUString aName(name.data(), name.size(), mrFactory.getGlobalSettings().getTextEncoding());
maCurrentFont.maNameComplex = aName;
}
void ScOrcusImportFontStyle::set_size(double point)
{
maCurrentFont.mnSize = point;
}
void ScOrcusImportFontStyle::set_size_asian(double point)
{
maCurrentFont.mnSizeAsian = point;
}
void ScOrcusImportFontStyle::set_size_complex(double point)
{
maCurrentFont.mnSizeComplex = point;
}
void ScOrcusImportFontStyle::set_underline(os::underline_t e)
{
switch(e)
{
case os::underline_t::single_line:
case os::underline_t::single_accounting:
maCurrentFont.meUnderline = LINESTYLE_SINGLE;
break;
case os::underline_t::double_line:
case os::underline_t::double_accounting:
maCurrentFont.meUnderline = LINESTYLE_DOUBLE;
break;
case os::underline_t::none:
maCurrentFont.meUnderline = LINESTYLE_NONE;
break;
case os::underline_t::dotted:
maCurrentFont.meUnderline = LINESTYLE_DOTTED;
break;
case os::underline_t::dash:
maCurrentFont.meUnderline = LINESTYLE_DASH;
break;
case os::underline_t::long_dash:
maCurrentFont.meUnderline = LINESTYLE_LONGDASH;
break;
case os::underline_t::dot_dash:
maCurrentFont.meUnderline = LINESTYLE_DASHDOT;
break;
case os::underline_t::dot_dot_dash:
maCurrentFont.meUnderline = LINESTYLE_DASHDOTDOT;
break;
case os::underline_t::wave:
maCurrentFont.meUnderline = LINESTYLE_WAVE;
break;
default:
;
}
}
void ScOrcusImportFontStyle::set_underline_width(os::underline_width_t e)
{
if (e == os::underline_width_t::bold || e == os::underline_width_t::thick)
{
if (maCurrentFont.meUnderline)
{
switch (*maCurrentFont.meUnderline)
{
case LINESTYLE_NONE:
case LINESTYLE_SINGLE:
maCurrentFont.meUnderline = LINESTYLE_BOLD;
break;
case LINESTYLE_DOTTED:
maCurrentFont.meUnderline = LINESTYLE_BOLDDOTTED;
break;
case LINESTYLE_DASH:
maCurrentFont.meUnderline = LINESTYLE_BOLDDASH;
break;
case LINESTYLE_LONGDASH:
maCurrentFont.meUnderline = LINESTYLE_BOLDLONGDASH;
break;
case LINESTYLE_DASHDOT:
maCurrentFont.meUnderline = LINESTYLE_BOLDDASHDOT;
break;
case LINESTYLE_DASHDOTDOT:
maCurrentFont.meUnderline = LINESTYLE_BOLDDASHDOTDOT;
break;
case LINESTYLE_WAVE:
maCurrentFont.meUnderline = LINESTYLE_BOLDWAVE;
break;
default:
;
}
}
else
maCurrentFont.meUnderline = LINESTYLE_BOLD;
}
}
void ScOrcusImportFontStyle::set_underline_mode(os::underline_mode_t /*e*/)
{
}
void ScOrcusImportFontStyle::set_underline_type(os::underline_type_t e )
{
if (e == os::underline_type_t::double_type)
{
if (maCurrentFont.meUnderline)
{
switch (*maCurrentFont.meUnderline)
{
case LINESTYLE_NONE:
case LINESTYLE_SINGLE:
maCurrentFont.meUnderline = LINESTYLE_DOUBLE;
break;
case LINESTYLE_WAVE:
maCurrentFont.meUnderline = LINESTYLE_DOUBLEWAVE;
break;
default:
;
}
}
else
maCurrentFont.meUnderline = LINESTYLE_DOUBLE;
}
}
void ScOrcusImportFontStyle::set_underline_color(
os::color_elem_t alpha, os::color_elem_t red, os::color_elem_t green, os::color_elem_t blue)
{
maCurrentFont.maUnderlineColor = Color(ColorAlpha, alpha, red, green, blue);
}
void ScOrcusImportFontStyle::set_color(
os::color_elem_t alpha, os::color_elem_t red, os::color_elem_t green, os::color_elem_t blue)
{
maCurrentFont.maColor = Color(ColorAlpha, alpha, red, green, blue);
}
void ScOrcusImportFontStyle::set_strikethrough_style(os::strikethrough_style_t /*s*/)
{
}
void ScOrcusImportFontStyle::set_strikethrough_type(os::strikethrough_type_t s)
{
if (maCurrentFont.meStrikeout)
{
if (*maCurrentFont.meStrikeout == STRIKEOUT_BOLD ||
*maCurrentFont.meStrikeout == STRIKEOUT_SLASH ||
*maCurrentFont.meStrikeout == STRIKEOUT_X)
return;
}
switch (s)
{
case os::strikethrough_type_t::unknown:
maCurrentFont.meStrikeout = STRIKEOUT_DONTKNOW;
break;
case os::strikethrough_type_t::none:
maCurrentFont.meStrikeout = STRIKEOUT_NONE;
break;
case os::strikethrough_type_t::single_type:
maCurrentFont.meStrikeout = STRIKEOUT_SINGLE;
break;
case os::strikethrough_type_t::double_type:
maCurrentFont.meStrikeout = STRIKEOUT_DOUBLE;
break;
default:
;
}
}
void ScOrcusImportFontStyle::set_strikethrough_width(os::strikethrough_width_t s)
{
switch (s)
{
case os::strikethrough_width_t::bold:
maCurrentFont.meStrikeout = STRIKEOUT_BOLD;
break;
default:
;
}
}
void ScOrcusImportFontStyle::set_strikethrough_text(os::strikethrough_text_t s)
{
switch (s)
{
case os::strikethrough_text_t::slash:
maCurrentFont.meStrikeout = STRIKEOUT_SLASH;
break;
case os::strikethrough_text_t::cross:
maCurrentFont.meStrikeout = STRIKEOUT_X;
break;
default:
;
}
}
std::size_t ScOrcusImportFontStyle::commit()
{
SAL_INFO("sc.orcus.style", "commit font");
mrFonts.push_back(maCurrentFont);
maCurrentFont = ScOrcusFont();
return mrFonts.size() - 1;
}
ScOrcusImportFillStyle::ScOrcusImportFillStyle( std::vector<ScOrcusFill>& rFills ) :
mrFills(rFills)
{
}
void ScOrcusImportFillStyle::reset()
{
maCurrentFill = ScOrcusFill();
}
void ScOrcusImportFillStyle::set_pattern_type(os::fill_pattern_t fp)
{
maCurrentFill.mePattern = fp;
}
void ScOrcusImportFillStyle::set_fg_color(
os::color_elem_t alpha, os::color_elem_t red, os::color_elem_t green, os::color_elem_t blue)
{
maCurrentFill.maFgColor = Color(ColorAlpha, alpha, red, green, blue);
}
void ScOrcusImportFillStyle::set_bg_color(
os::color_elem_t alpha, os::color_elem_t red, os::color_elem_t green, os::color_elem_t blue)
{
maCurrentFill.maBgColor = Color(ColorAlpha, alpha, red, green, blue);
}
std::size_t ScOrcusImportFillStyle::commit()
{
SAL_INFO("sc.orcus.style", "commit fill");
mrFills.push_back(maCurrentFill);
maCurrentFill = ScOrcusFill();
return mrFills.size() - 1;
}
ScOrcusImportBorderStyle::ScOrcusImportBorderStyle( std::vector<ScOrcusBorder>& rBorders ) :
mrBorders(rBorders)
{
}
void ScOrcusImportBorderStyle::set_style(
os::border_direction_t dir, os::border_style_t style)
{
ScOrcusBorder::BorderLine& rBorderLine = maCurrentBorder.maBorders[dir];
switch (style)
{
case os::border_style_t::solid:
rBorderLine.meStyle = SvxBorderLineStyle::SOLID;
rBorderLine.mnWidth = oox::xls::API_LINE_THIN;
break;
case os::border_style_t::hair:
rBorderLine.meStyle = SvxBorderLineStyle::SOLID;
rBorderLine.mnWidth = oox::xls::API_LINE_HAIR;
break;
case os::border_style_t::medium:
rBorderLine.meStyle = SvxBorderLineStyle::SOLID;
rBorderLine.mnWidth = oox::xls::API_LINE_MEDIUM;
break;
case os::border_style_t::thick:
rBorderLine.meStyle = SvxBorderLineStyle::SOLID;
rBorderLine.mnWidth = oox::xls::API_LINE_THICK;
break;
case os::border_style_t::thin:
rBorderLine.meStyle = SvxBorderLineStyle::SOLID;
rBorderLine.mnWidth = oox::xls::API_LINE_THIN;
break;
case os::border_style_t::dash_dot:
rBorderLine.meStyle = SvxBorderLineStyle::DASH_DOT;
rBorderLine.mnWidth = oox::xls::API_LINE_THIN;
break;
case os::border_style_t::dash_dot_dot:
rBorderLine.meStyle = SvxBorderLineStyle::DASH_DOT_DOT;
rBorderLine.mnWidth = oox::xls::API_LINE_THIN;
break;
case os::border_style_t::dashed:
rBorderLine.meStyle = SvxBorderLineStyle::DASHED;
rBorderLine.mnWidth = oox::xls::API_LINE_THIN;
break;
case os::border_style_t::dotted:
rBorderLine.meStyle = SvxBorderLineStyle::DOTTED;
rBorderLine.mnWidth = oox::xls::API_LINE_THIN;
break;
case os::border_style_t::double_border:
rBorderLine.meStyle = SvxBorderLineStyle::DOUBLE;
rBorderLine.mnWidth = oox::xls::API_LINE_THICK;
break;
case os::border_style_t::medium_dash_dot:
case os::border_style_t::slant_dash_dot:
rBorderLine.meStyle = SvxBorderLineStyle::DASH_DOT;
rBorderLine.mnWidth = oox::xls::API_LINE_MEDIUM;
break;
case os::border_style_t::medium_dash_dot_dot:
rBorderLine.meStyle = SvxBorderLineStyle::DASH_DOT_DOT;
rBorderLine.mnWidth = oox::xls::API_LINE_MEDIUM;
break;
case os::border_style_t::medium_dashed:
rBorderLine.meStyle = SvxBorderLineStyle::DASHED;
rBorderLine.mnWidth = oox::xls::API_LINE_MEDIUM;
break;
case os::border_style_t::unknown:
case os::border_style_t::none:
rBorderLine.mnWidth = oox::xls::API_LINE_NONE;
break;
default:
;
}
}
void ScOrcusImportBorderStyle::set_color(
os::border_direction_t dir, os::color_elem_t alpha, os::color_elem_t red,
os::color_elem_t green, os::color_elem_t blue)
{
ScOrcusBorder::BorderLine& rBorderLine = maCurrentBorder.maBorders[dir];
rBorderLine.maColor = Color(ColorAlpha, alpha, red, green, blue);
}
void ScOrcusImportBorderStyle::reset()
{
maCurrentBorder = ScOrcusBorder();
}
void ScOrcusImportBorderStyle::set_width(os::border_direction_t dir, double val, orcus::length_unit_t unit)
{
ScOrcusBorder::BorderLine& rBorderLine = maCurrentBorder.maBorders[dir];
rBorderLine.mnWidth = translateToInternal(val, unit);
}
std::size_t ScOrcusImportBorderStyle::commit()
{
SAL_INFO("sc.orcus.style", "commit border");
mrBorders.push_back(maCurrentBorder);
maCurrentBorder = ScOrcusBorder();
return mrBorders.size() - 1;
}
ScOrcusImportCellProtection::ScOrcusImportCellProtection( std::vector<ScOrcusProtection>& rProtections ) :
mrProtections(rProtections)
{
}
void ScOrcusImportCellProtection::reset()
{
maCurrentProtection = ScOrcusProtection();
}
void ScOrcusImportCellProtection::set_hidden(bool b)
{
maCurrentProtection.mbHidden = b;
}
void ScOrcusImportCellProtection::set_locked(bool b)
{
maCurrentProtection.mbLocked = b;
}
void ScOrcusImportCellProtection::set_print_content(bool b )
{
maCurrentProtection.mbPrintContent = b;
}
void ScOrcusImportCellProtection::set_formula_hidden(bool b )
{
maCurrentProtection.mbFormulaHidden = b;
}
std::size_t ScOrcusImportCellProtection::commit()
{
SAL_INFO("sc.orcus.style", "commit cell protection");
mrProtections.push_back(maCurrentProtection);
maCurrentProtection = ScOrcusProtection();
return mrProtections.size() - 1;
}
ScOrcusImportNumberFormat::ScOrcusImportNumberFormat( ScOrcusFactory& rFactory, std::vector<ScOrcusNumberFormat>& rFormats ) :
mrFactory(rFactory), mrNumberFormats(rFormats)
{
}
void ScOrcusImportNumberFormat::reset()
{
maCurrentFormat = ScOrcusNumberFormat();
}
void ScOrcusImportNumberFormat::set_identifier(std::size_t /*id*/)
{
}
void ScOrcusImportNumberFormat::set_code(std::string_view s)
{
OUString aCode(s.data(), s.size(), mrFactory.getGlobalSettings().getTextEncoding());
maCurrentFormat.maCode = aCode;
}
std::size_t ScOrcusImportNumberFormat::commit()
{
SAL_INFO("sc.orcus.style", "commit number format");
mrNumberFormats.push_back(maCurrentFormat);
maCurrentFormat = ScOrcusNumberFormat();
return mrNumberFormats.size() - 1;
}
ScOrucsImportCellStyle::ScOrucsImportCellStyle(
ScOrcusFactory& rFactory, ScOrcusStyles& rStyles, const std::vector<ScOrcusXf>& rXfs ) :
mrFactory(rFactory),
mrStyles(rStyles),
mrXfs(rXfs)
{
}
void ScOrucsImportCellStyle::reset()
{
maCurrentStyle = ScOrcusCellStyle();
}
void ScOrucsImportCellStyle::set_name(std::string_view name)
{
maCurrentStyle.maName = OUString(name.data(), name.size(), mrFactory.getGlobalSettings().getTextEncoding());
}
void ScOrucsImportCellStyle::set_display_name(std::string_view name)
{
maCurrentStyle.maDisplayName = OUString(name.data(), name.size(), mrFactory.getGlobalSettings().getTextEncoding());
}
void ScOrucsImportCellStyle::set_xf(size_t index)
{
maCurrentStyle.mnXFId = index;
}
void ScOrucsImportCellStyle::set_builtin(size_t index)
{
maCurrentStyle.mnBuiltInId = index;
}
void ScOrucsImportCellStyle::set_parent_name(std::string_view name)
{
maCurrentStyle.maParentName = OUString(name.data(), name.size(), mrFactory.getGlobalSettings().getTextEncoding());
}
void ScOrucsImportCellStyle::commit()
{
SAL_INFO("sc.orcus.style", "commit cell style: " << maCurrentStyle.maName);
if (maCurrentStyle.mnXFId >= mrXfs.size())
{
SAL_WARN("sc.orcus.style", "invalid xf id for commit cell style");
return;
}
if (maCurrentStyle.mnXFId == 0)
return;
ScStyleSheetPool* pPool = mrFactory.getDoc().getDoc().GetStyleSheetPool();
SfxStyleSheetBase& rBase = pPool->Make(maCurrentStyle.maName, SfxStyleFamily::Para);
// Need to convert the parent name to localized UI name, see tdf#139205.
rBase.SetParent(
ScStyleNameConversion::ProgrammaticToDisplayName(
maCurrentStyle.maParentName, SfxStyleFamily::Para));
SfxItemSet& rSet = rBase.GetItemSet();
const ScOrcusXf& rXf = mrXfs[maCurrentStyle.mnXFId];
mrStyles.applyXfToItemSet(rSet, rXf);
maCurrentStyle = ScOrcusCellStyle();
}
void ScOrcusImportXf::reset( std::vector<ScOrcusXf>& rXfs )
{
mpXfs = &rXfs;
maCurrentXf = ScOrcusXf();
}
void ScOrcusImportXf::set_font(std::size_t index)
{
maCurrentXf.mnFontId = index;
}
void ScOrcusImportXf::set_fill(std::size_t index)
{
maCurrentXf.mnFillId = index;
}
void ScOrcusImportXf::set_border(std::size_t index)
{
maCurrentXf.mnBorderId = index;
}
void ScOrcusImportXf::set_protection(std::size_t index)
{
maCurrentXf.mnProtectionId = index;
}
void ScOrcusImportXf::set_number_format(std::size_t index)
{
maCurrentXf.mnNumberFormatId = index;
}
void ScOrcusImportXf::set_style_xf(std::size_t index)
{
maCurrentXf.mnStyleXf = index;
}
void ScOrcusImportXf::set_apply_alignment(bool b)
{
maCurrentXf.mbApplyAlignment = b;
}
void ScOrcusImportXf::set_horizontal_alignment(os::hor_alignment_t align)
{
switch (align)
{
case os::hor_alignment_t::left:
maCurrentXf.meHorAlignment = SvxCellHorJustify::Left;
break;
case os::hor_alignment_t::right:
maCurrentXf.meHorAlignment = SvxCellHorJustify::Right;
break;
case os::hor_alignment_t::center:
maCurrentXf.meHorAlignment = SvxCellHorJustify::Center;
break;
case os::hor_alignment_t::justified:
maCurrentXf.meHorAlignment = SvxCellHorJustify::Block;
break;
case os::hor_alignment_t::distributed:
maCurrentXf.meHorAlignment = SvxCellHorJustify::Block;
maCurrentXf.meHorAlignMethod = SvxCellJustifyMethod::Distribute;
break;
case os::hor_alignment_t::unknown:
maCurrentXf.meHorAlignment = SvxCellHorJustify::Standard;
break;
default:
;
}
maCurrentXf.mbApplyAlignment = true;
}
void ScOrcusImportXf::set_vertical_alignment(os::ver_alignment_t align)
{
switch (align)
{
case os::ver_alignment_t::top:
maCurrentXf.meVerAlignment = SvxCellVerJustify::Top;
break;
case os::ver_alignment_t::bottom:
maCurrentXf.meVerAlignment = SvxCellVerJustify::Bottom;
break;
case os::ver_alignment_t::middle:
maCurrentXf.meVerAlignment = SvxCellVerJustify::Center;
break;
case os::ver_alignment_t::justified:
maCurrentXf.meVerAlignment = SvxCellVerJustify::Block;
break;
case os::ver_alignment_t::distributed:
maCurrentXf.meVerAlignment = SvxCellVerJustify::Block;
maCurrentXf.meVerAlignMethod = SvxCellJustifyMethod::Distribute;
break;
case os::ver_alignment_t::unknown:
maCurrentXf.meVerAlignment = SvxCellVerJustify::Standard;
break;
default:
;
}
maCurrentXf.mbApplyAlignment = true;
}
void ScOrcusImportXf::set_wrap_text(bool b)
{
maCurrentXf.mbWrapText = b;
}
void ScOrcusImportXf::set_shrink_to_fit(bool b)
{
maCurrentXf.mbShrinkToFit = b;
}
std::size_t ScOrcusImportXf::commit()
{
mpXfs->push_back(maCurrentXf);
return mpXfs->size() - 1;
}
ScOrcusStyles::ScOrcusStyles( ScOrcusFactory& rFactory, bool bSkipDefaultStyles ) :
mrFactory(rFactory),
maFontStyle(rFactory, maFonts),
maFillStyle(maFills),
maBorderStyle(maBorders),
maCellProtection(maProtections),
maNumberFormat(rFactory, maNumberFormats),
maCellStyle(rFactory, *this, maCellStyleXfs)
{
ScDocument& rDoc = rFactory.getDoc().getDoc();
if (!bSkipDefaultStyles && !rDoc.GetStyleSheetPool()->HasStandardStyles())
rDoc.GetStyleSheetPool()->CreateStandardStyles();
}
/*
namespace {
std::ostream& operator<<(std::ostream& rStrm, const Color& rColor)
{
rStrm << "Red: " << (int)rColor.GetRed() << ", Green: " << (int)rColor.GetGreen() << ", Blue: " << (int)rColor.GetBlue();
return rStrm;
}
}
*/
void ScOrcusStyles::applyXfToItemSet( SfxItemSet& rSet, const ScOrcusXf& rXf )
{
size_t nFontId = rXf.mnFontId;
if (nFontId >= maFonts.size())
{
SAL_WARN("sc.orcus.style", "invalid font id");
return;
}
maFonts[nFontId].applyToItemSet(rSet);
size_t nFillId = rXf.mnFillId;
if (nFillId >= maFills.size())
{
SAL_WARN("sc.orcus.style", "invalid fill id");
return;
}
maFills[nFillId].applyToItemSet(rSet);
size_t nBorderId = rXf.mnBorderId;
if (nBorderId >= maBorders.size())
{
SAL_WARN("sc.orcus.style", "invalid border id");
return;
}
maBorders[nBorderId].applyToItemSet(rSet);
size_t nProtectionId = rXf.mnProtectionId;
if (nProtectionId >= maProtections.size())
{
SAL_WARN("sc.orcus.style", "invalid protection id");
return;
}
maProtections[nProtectionId].applyToItemSet(rSet);
size_t nNumberFormatId = rXf.mnNumberFormatId;
if (nNumberFormatId >= maNumberFormats.size())
{
SAL_WARN("sc.orcus.style", "invalid number format id");
return;
}
const ScOrcusNumberFormat& rFormat = maNumberFormats[nNumberFormatId];
rFormat.applyToItemSet(rSet, mrFactory.getDoc().getDoc());
if (rXf.mbApplyAlignment)
{
rSet.Put(SvxHorJustifyItem(rXf.meHorAlignment, ATTR_HOR_JUSTIFY));
rSet.Put(SvxVerJustifyItem(rXf.meVerAlignment, ATTR_VER_JUSTIFY));
rSet.Put(SvxJustifyMethodItem(rXf.meHorAlignMethod, ATTR_HOR_JUSTIFY_METHOD));
rSet.Put(SvxJustifyMethodItem(rXf.meVerAlignMethod, ATTR_VER_JUSTIFY_METHOD));
}
if (rXf.mbWrapText)
rSet.Put(ScLineBreakCell(*rXf.mbWrapText));
if (rXf.mbShrinkToFit)
rSet.Put(ScShrinkToFitCell(*rXf.mbShrinkToFit));
}
void ScOrcusStyles::applyXfToItemSet( SfxItemSet& rSet, std::size_t xfId )
{
SAL_INFO("sc.orcus.style", "applyXfToitemSet: " << xfId);
if (maCellXfs.size() <= xfId)
{
SAL_WARN("sc.orcus.style", "invalid xf id");
return;
}
applyXfToItemSet(rSet, maCellXfs[xfId]);
}
os::iface::import_font_style* ScOrcusStyles::start_font_style()
{
maFontStyle.reset();
return &maFontStyle;
}
os::iface::import_fill_style* ScOrcusStyles::start_fill_style()
{
maFillStyle.reset();
return &maFillStyle;
}
os::iface::import_border_style* ScOrcusStyles::start_border_style()
{
maBorderStyle.reset();
return &maBorderStyle;
}
os::iface::import_cell_protection* ScOrcusStyles::start_cell_protection()
{
maCellProtection.reset();
return &maCellProtection;
}
os::iface::import_number_format* ScOrcusStyles::start_number_format()
{
maNumberFormat.reset();
return &maNumberFormat;
}
os::iface::import_xf* ScOrcusStyles::start_xf(os::xf_category_t cat)
{
switch (cat)
{
case os::xf_category_t::cell:
maXf.reset(maCellXfs);
break;
case os::xf_category_t::cell_style:
maXf.reset(maCellStyleXfs);
break;
case os::xf_category_t::differential:
maXf.reset(maCellDiffXfs);
break;
case os::xf_category_t::unknown:
SAL_WARN("sc.orcus.style", "unknown xf category");
return nullptr;
}
return &maXf;
}
os::iface::import_cell_style* ScOrcusStyles::start_cell_style()
{
maCellStyle.reset();
return &maCellStyle;
}
void ScOrcusStyles::set_font_count(size_t /*n*/)
{
}
void ScOrcusStyles::set_fill_count(size_t /*n*/)
{
}
void ScOrcusStyles::set_border_count(size_t /*n*/)
{
}
void ScOrcusStyles::set_number_format_count(size_t /*n*/)
{
}
void ScOrcusStyles::set_xf_count(os::xf_category_t /*cat*/, size_t /*n*/)
{
}
void ScOrcusStyles::set_cell_style_count(size_t /*n*/)
{
}
// auto filter import
ScOrcusAutoFilter::ScOrcusAutoFilter( const ScOrcusGlobalSettings& rGS ) :
mrGlobalSettings(rGS)
{
}
ScOrcusAutoFilter::~ScOrcusAutoFilter()
{
}
void ScOrcusAutoFilter::set_range(const os::range_t& range)
{
maRange.aStart.SetRow(range.first.row);
maRange.aStart.SetCol(range.first.column);
maRange.aEnd.SetRow(range.last.row);
maRange.aEnd.SetCol(range.last.column);
}
void ScOrcusAutoFilter::set_column(os::col_t col)
{
SAL_INFO("sc.orcus.autofilter", "set_column: " << col);
}
void ScOrcusAutoFilter::append_column_match_value(std::string_view value)
{
OUString aString(value.data(), value.size(), mrGlobalSettings.getTextEncoding());
SAL_INFO("sc.orcus.autofilter", "append_column_match_value: " << aString);
}
void ScOrcusAutoFilter::commit_column()
{
SAL_INFO("sc.orcus.autofilter", "commit column");
}
void ScOrcusAutoFilter::commit()
{
SAL_INFO("sc.orcus.autofilter", "commit");
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
↑ V1037 Two or more case-branches perform the same actions. Check lines: 1927, 1943