210 lines
6.8 KiB
C++
210 lines
6.8 KiB
C++
/* -*- 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, nullptr, *this);
|
|
else
|
|
aStr = ScCellFormat::GetString(*this, rPos, nNumberFormat, &pColor, nullptr);
|
|
|
|
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( GetFormatTable(), 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 (!HasTable(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: */
|