diff options
Diffstat (limited to 'sc/source/core/data/documen6.cxx')
-rw-r--r-- | sc/source/core/data/documen6.cxx | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/sc/source/core/data/documen6.cxx b/sc/source/core/data/documen6.cxx new file mode 100644 index 000000000..49d433ffe --- /dev/null +++ b/sc/source/core/data/documen6.cxx @@ -0,0 +1,210 @@ +/* -*- 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 <com/sun/star/i18n/BreakIterator.hpp> +#include <com/sun/star/i18n/ScriptType.hpp> +#include <comphelper/processfactory.hxx> + +#include <document.hxx> +#include <cellform.hxx> +#include <patattr.hxx> +#include <scrdata.hxx> +#include <poolhelp.hxx> +#include <attrib.hxx> +#include <columnspanset.hxx> +#include <table.hxx> + +using namespace com::sun::star; + +// this file is compiled with exceptions enabled +// put functions here that need exceptions! + +const uno::Reference< i18n::XBreakIterator >& ScDocument::GetBreakIterator() +{ + if ( !pScriptTypeData ) + pScriptTypeData.reset( new ScScriptTypeData ); + if ( !pScriptTypeData->xBreakIter.is() ) + { + pScriptTypeData->xBreakIter = i18n::BreakIterator::create( comphelper::getProcessComponentContext() ); + } + return pScriptTypeData->xBreakIter; +} + +bool ScDocument::HasStringWeakCharacters( const OUString& rString ) +{ + if (!rString.isEmpty()) + { + uno::Reference<i18n::XBreakIterator> xBreakIter = GetBreakIterator(); + if ( xBreakIter.is() ) + { + sal_Int32 nLen = rString.getLength(); + + sal_Int32 nPos = 0; + do + { + sal_Int16 nType = xBreakIter->getScriptType( rString, nPos ); + if ( nType == i18n::ScriptType::WEAK ) + return true; // found + + nPos = xBreakIter->endOfScript( rString, nPos, nType ); + } + while ( nPos >= 0 && nPos < nLen ); + } + } + + return false; // none found +} + +SvtScriptType ScDocument::GetStringScriptType( const OUString& rString ) +{ + SvtScriptType nRet = SvtScriptType::NONE; + if (!rString.isEmpty()) + { + uno::Reference<i18n::XBreakIterator> xBreakIter = GetBreakIterator(); + if ( xBreakIter.is() ) + { + sal_Int32 nLen = rString.getLength(); + + sal_Int32 nPos = 0; + do + { + sal_Int16 nType = xBreakIter->getScriptType( rString, nPos ); + switch ( nType ) + { + case i18n::ScriptType::LATIN: + nRet |= SvtScriptType::LATIN; + break; + case i18n::ScriptType::ASIAN: + nRet |= SvtScriptType::ASIAN; + break; + case i18n::ScriptType::COMPLEX: + nRet |= SvtScriptType::COMPLEX; + break; + // WEAK is ignored + } + nPos = xBreakIter->endOfScript( rString, nPos, nType ); + } + while ( nPos >= 0 && nPos < nLen ); + } + } + return nRet; +} + +SvtScriptType ScDocument::GetCellScriptType( const ScAddress& rPos, sal_uInt32 nNumberFormat, + const ScRefCellValue* pCell ) +{ + SvtScriptType nStored = GetScriptType(rPos); + if ( nStored != SvtScriptType::UNKNOWN ) // stored value valid? + return nStored; // use stored value + + const Color* pColor; + OUString aStr; + if( pCell ) + aStr = ScCellFormat::GetString(*pCell, nNumberFormat, &pColor, *mxPoolHelper->GetFormTable(), *this); + else + aStr = ScCellFormat::GetString(*this, rPos, nNumberFormat, &pColor, *mxPoolHelper->GetFormTable()); + + SvtScriptType nRet = GetStringScriptType( aStr ); + + SetScriptType(rPos, nRet); // store for later calls + + return nRet; +} + +SvtScriptType ScDocument::GetScriptType( SCCOL nCol, SCROW nRow, SCTAB nTab, const ScRefCellValue* pCell ) +{ + // if script type is set, don't have to get number formats + + ScAddress aPos(nCol, nRow, nTab); + SvtScriptType nStored = GetScriptType(aPos); + if ( nStored != SvtScriptType::UNKNOWN ) // stored value valid? + return nStored; // use stored value + + // include number formats from conditional formatting + + const ScPatternAttr* pPattern = GetPattern( nCol, nRow, nTab ); + if (!pPattern) return SvtScriptType::NONE; + const SfxItemSet* pCondSet = nullptr; + if ( !pPattern->GetItem(ATTR_CONDITIONAL).GetCondFormatData().empty() ) + pCondSet = GetCondResult( nCol, nRow, nTab ); + + sal_uInt32 nFormat = pPattern->GetNumberFormat( mxPoolHelper->GetFormTable(), pCondSet ); + + return GetCellScriptType(aPos, nFormat, pCell); +} + +namespace { + +class ScriptTypeAggregator : public sc::ColumnSpanSet::Action +{ + ScDocument& mrDoc; + sc::ColumnBlockPosition maBlockPos; + SvtScriptType mnScriptType; + +public: + explicit ScriptTypeAggregator(ScDocument& rDoc) : mrDoc(rDoc), mnScriptType(SvtScriptType::NONE) {} + + virtual void startColumn(SCTAB nTab, SCCOL nCol) override + { + mrDoc.InitColumnBlockPosition(maBlockPos, nTab, nCol); + } + + virtual void execute(const ScAddress& rPos, SCROW nLength, bool bVal) override + { + if (!bVal) + return; + + mnScriptType |= mrDoc.GetRangeScriptType(maBlockPos, rPos, nLength); + }; + + SvtScriptType getScriptType() const { return mnScriptType; } +}; + +} + +SvtScriptType ScDocument::GetRangeScriptType( + sc::ColumnBlockPosition& rBlockPos, const ScAddress& rPos, SCROW nLength ) +{ + if (!TableExists(rPos.Tab())) + return SvtScriptType::NONE; + + return maTabs[rPos.Tab()]->GetRangeScriptType(rBlockPos, rPos.Col(), rPos.Row(), rPos.Row()+nLength-1); +} + +SvtScriptType ScDocument::GetRangeScriptType( const ScRangeList& rRanges ) +{ + sc::ColumnSpanSet aSet; + for (size_t i = 0, n = rRanges.size(); i < n; ++i) + { + const ScRange& rRange = rRanges[i]; + SCTAB nTab = rRange.aStart.Tab(); + SCROW nRow1 = rRange.aStart.Row(); + SCROW nRow2 = rRange.aEnd.Row(); + for (SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol) + aSet.set(*this, nTab, nCol, nRow1, nRow2, true); + } + + ScriptTypeAggregator aAction(*this); + aSet.executeAction(*this, aAction); + return aAction.getScriptType(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |