Files
libreoffice/sc/source/ui/StatisticsDialogs/TableFillingAndNavigationTools.cxx
Eike Rathke 9570a27d3e resolved fdo#73555 compile statistics templates using English grammar
The statistics templates' formula expressions are setup using English
function names, so compile the resulting expressions using an English
grammar merged with the current address conventions.

Change-Id: I7c782a42d007daeaaf99463beb8aa580c05c7363
2014-01-13 18:08:52 +01:00

354 lines
8.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/.
*
*/
#include <boost/scoped_ptr.hpp>
#include <editeng/editobj.hxx>
#include <editeng/wghtitem.hxx>
#include <editeng/eeitem.hxx>
#include "editutil.hxx"
#include "TableFillingAndNavigationTools.hxx"
FormulaTemplate::FormulaTemplate(ScDocument* aDocument, ScAddress::Details aAddressDetails) :
mDocument(aDocument),
mAddressDetails(aAddressDetails)
{}
void FormulaTemplate::setTemplate(OUString aTemplate)
{
mTemplate = aTemplate;
}
void FormulaTemplate::setTemplate(const char* aTemplate)
{
mTemplate = OUString::createFromAscii(aTemplate);
}
OUString& FormulaTemplate::getTemplate()
{
RangeReplacementMap::iterator itRange;
for (itRange = mRangeReplacementMap.begin(); itRange != mRangeReplacementMap.end(); ++itRange)
{
applyRange(itRange->first, itRange->second);
}
AddressReplacementMap::iterator itAddress;
for (itAddress = mAddressReplacementMap.begin(); itAddress != mAddressReplacementMap.end(); ++itAddress)
{
applyAddress(itAddress->first, itAddress->second);
}
return mTemplate;
}
void FormulaTemplate::autoReplaceRange(OUString aVariable, ScRange aRange)
{
mRangeReplacementMap.insert ( std::pair<OUString, ScRange>(aVariable, aRange) );
}
void FormulaTemplate::autoReplaceAddress(OUString aVariable, ScAddress aAddress)
{
mAddressReplacementMap.insert ( std::pair<OUString, ScAddress>(aVariable, aAddress) );
}
void FormulaTemplate::applyRange(OUString aVariable, ScRange aRange)
{
OUString aString = aRange.Format(SCR_ABS, mDocument, mAddressDetails);
mTemplate = mTemplate.replaceAll(aVariable, aString);
}
void FormulaTemplate::applyRangeList(OUString aVariable, ScRangeList aRangeList)
{
OUString aString;
aRangeList.Format(aString, SCR_ABS, mDocument);
mTemplate = mTemplate.replaceAll(aVariable, aString);
}
void FormulaTemplate::applyAddress(OUString aVariable, ScAddress aAddress)
{
OUString aString = aAddress.Format(SCR_ABS, mDocument, mAddressDetails);
mTemplate = mTemplate.replaceAll(aVariable, aString);
}
void FormulaTemplate::applyString(OUString aVariable, OUString aValue)
{
mTemplate = mTemplate.replaceAll(aVariable, aValue);
}
void FormulaTemplate::applyNumber(OUString aVariable, sal_Int32 aValue)
{
mTemplate = mTemplate.replaceAll(aVariable, OUString::number(aValue));
}
AddressWalker::AddressWalker(ScAddress aInitialAddress, bool aTrackRange) :
mCurrentAddress(aInitialAddress),
mMinimumAddress(aInitialAddress),
mMaximumAddress(aInitialAddress),
mTrackRange(aTrackRange)
{
mAddressStack.push_back(mCurrentAddress);
}
void AddressWalker::resetColumn()
{
mCurrentAddress.SetCol(mAddressStack.back().Col());
}
void AddressWalker::resetRow()
{
mCurrentAddress.SetRow(mAddressStack.back().Row());
}
void AddressWalker::reset()
{
mCurrentAddress = mAddressStack.back();
}
ScAddress AddressWalker::current(SCCOL aRelCol, SCROW aRelRow, SCTAB aRelTab)
{
return ScAddress(
mCurrentAddress.Col() + aRelCol,
mCurrentAddress.Row() + aRelRow,
mCurrentAddress.Tab() + aRelTab);
}
void AddressWalker::nextColumn()
{
mCurrentAddress.IncCol();
if (mTrackRange)
{
if(mMaximumAddress.Col() < mCurrentAddress.Col())
mMaximumAddress.SetCol(mCurrentAddress.Col());
}
}
void AddressWalker::nextRow()
{
mCurrentAddress.IncRow();
if (mTrackRange)
{
if(mMaximumAddress.Row() < mCurrentAddress.Row())
mMaximumAddress.SetRow(mCurrentAddress.Row());
}
}
void AddressWalker::push(SCCOL aRelativeCol, SCROW aRelativeRow, SCTAB aRelativeTab)
{
mCurrentAddress = current(aRelativeCol, aRelativeRow, aRelativeTab);
mAddressStack.push_back(mCurrentAddress);
}
void AddressWalker::pop()
{
mCurrentAddress = mAddressStack.back();
mAddressStack.pop_back();
}
AddressWalkerWriter::AddressWalkerWriter(ScAddress aInitialAddress, ScDocShell* pDocShell, ScDocument* pDocument,
formula::FormulaGrammar::Grammar eGrammar ) :
AddressWalker(aInitialAddress, true),
mpDocShell(pDocShell),
mpDocument(pDocument),
meGrammar(eGrammar)
{}
void AddressWalkerWriter::writeFormula(OUString aFormula)
{
mpDocShell->GetDocFunc().SetFormulaCell(mCurrentAddress,
new ScFormulaCell(mpDocument, mCurrentAddress, aFormula, meGrammar), true);
}
void AddressWalkerWriter::writeMatrixFormula(OUString aFormula)
{
ScRange aRange;
aRange.aStart = mCurrentAddress;
aRange.aEnd = mCurrentAddress;
mpDocShell->GetDocFunc().EnterMatrix(aRange, NULL, NULL, aFormula, false, false, OUString(), meGrammar );
}
void AddressWalkerWriter::writeString(OUString aString)
{
mpDocShell->GetDocFunc().SetStringCell(mCurrentAddress, aString, true);
}
void AddressWalkerWriter::writeString(const char* aCharArray)
{
writeString(OUString::createFromAscii(aCharArray));
}
void AddressWalkerWriter::writeBoldString(OUString aString)
{
ScFieldEditEngine& rEngine = mpDocument->GetEditEngine();
rEngine.SetText(aString);
SfxItemSet aItemSet = rEngine.GetEmptyItemSet();
SvxWeightItem aWeight(WEIGHT_BOLD, EE_CHAR_WEIGHT);
aItemSet.Put(aWeight);
rEngine.QuickSetAttribs(aItemSet, ESelection(0, 0, 0, aString.getLength()) );
boost::scoped_ptr<EditTextObject> pEditText(rEngine.CreateTextObject());
mpDocShell->GetDocFunc().SetEditCell(mCurrentAddress, *pEditText, true);
}
void AddressWalkerWriter::writeValue(double aValue)
{
mpDocShell->GetDocFunc().SetValueCell(mCurrentAddress, aValue, true);
}
// DataCellIterator
DataCellIterator::DataCellIterator(ScRange aInputRange, bool aByColumn) :
mInputRange(aInputRange),
mByColumn(aByColumn)
{
if(aByColumn)
mCol = aInputRange.aStart.Col();
else
mRow = aInputRange.aStart.Row();
}
DataCellIterator::~DataCellIterator()
{}
bool DataCellIterator::hasNext()
{
if(mByColumn)
return mCol <= mInputRange.aEnd.Col();
else
return mRow <= mInputRange.aEnd.Row();
}
void DataCellIterator::next()
{
if(mByColumn)
mCol++;
else
mRow++;
}
ScAddress DataCellIterator::get()
{
return getRelative(0);
}
ScAddress DataCellIterator::getRelative(int aDelta)
{
if(mByColumn)
{
SCCOL aNewColumn = mCol + aDelta;
if(aNewColumn < mInputRange.aStart.Col() || aNewColumn > mInputRange.aEnd.Col())
{
ScAddress aResult;
aResult.SetInvalid();
return aResult;
}
return ScAddress(aNewColumn, mInputRange.aStart.Row(), mInputRange.aStart.Tab());
}
else
{
SCROW aNewRow = mRow + aDelta;
if(aNewRow < mInputRange.aStart.Row() || aNewRow > mInputRange.aEnd.Row())
{
ScAddress aResult;
aResult.SetInvalid();
return aResult;
}
return ScAddress(mInputRange.aStart.Col(), aNewRow, mInputRange.aStart.Tab());
}
}
// DataRangeIterator
DataRangeIterator::DataRangeIterator(ScRange aInputRange) :
mInputRange(aInputRange),
mIndex(0)
{}
DataRangeIterator::~DataRangeIterator()
{}
sal_Int32 DataRangeIterator::index()
{
return mIndex;
}
// DataRangeByColumnIterator
DataRangeByColumnIterator::DataRangeByColumnIterator(ScRange aInputRange) :
DataRangeIterator(aInputRange),
mCol(aInputRange.aStart.Col())
{}
bool DataRangeByColumnIterator::hasNext()
{
return mCol <= mInputRange.aEnd.Col();
}
void DataRangeByColumnIterator::next()
{
mCol++;
mIndex++;
}
ScRange DataRangeByColumnIterator::get()
{
return ScRange(
ScAddress(mCol, mInputRange.aStart.Row(), mInputRange.aStart.Tab()),
ScAddress(mCol, mInputRange.aEnd.Row(), mInputRange.aEnd.Tab())
);
}
void DataRangeByColumnIterator::reset()
{
mCol = mInputRange.aStart.Col();
}
DataCellIterator DataRangeByColumnIterator::iterateCells()
{
return DataCellIterator(get(), false);
}
// DataRangeByRowIterator
DataRangeByRowIterator::DataRangeByRowIterator(ScRange aInputRange) :
DataRangeIterator(aInputRange),
mRow(aInputRange.aStart.Row())
{}
bool DataRangeByRowIterator::hasNext()
{
return mRow <= mInputRange.aEnd.Row();
}
void DataRangeByRowIterator::next()
{
mRow++;
mIndex++;
}
ScRange DataRangeByRowIterator::get()
{
return ScRange(
ScAddress(mInputRange.aStart.Col(), mRow, mInputRange.aStart.Tab()),
ScAddress(mInputRange.aEnd.Col(), mRow, mInputRange.aEnd.Tab())
);
}
void DataRangeByRowIterator::reset()
{
mRow = mInputRange.aStart.Row();
}
DataCellIterator DataRangeByRowIterator::iterateCells()
{
return DataCellIterator(get(), true);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */