0
0
mirror of https://github.com/fralx/LimeReport.git synced 2024-12-25 00:54:39 +03:00

Finish Subtotals

This commit is contained in:
Arin Alexander 2018-03-15 23:01:22 +03:00
commit d79aec5faf
7 changed files with 111 additions and 33 deletions

View File

@ -85,7 +85,7 @@ namespace Const{
const QString VARIABLE_RX = "\\$V\\s*\\{\\s*([^{}]*)\\s*\\}"; const QString VARIABLE_RX = "\\$V\\s*\\{\\s*([^{}]*)\\s*\\}";
const QString NAMED_VARIABLE_RX = "\\$V\\s*\\{\\s*(%1)\\s*\\}"; const QString NAMED_VARIABLE_RX = "\\$V\\s*\\{\\s*(%1)\\s*\\}";
const QString SCRIPT_RX = "\\$S\\s*\\{(.*)\\}"; const QString SCRIPT_RX = "\\$S\\s*\\{(.*)\\}";
const QString GROUP_FUNCTION_PARAM_RX = "\\(\\s*((?:(?:\\\")|(?:))(?:(?:\\$(?:(?:D\\{\\s*\\w*.\\w*\\s*\\})|(?:V\\{\\s*\\w*\\s*\\})|(?:S\\{.+\\})))|(?:\\w*))(?:(?:\\\")|(?:)))(?:(?:\\s*,\\s*(?:\\\"(\\w*)\\\"))|(?:))\\)"; const QString GROUP_FUNCTION_PARAM_RX = "\\(\\s*((?:(?:\\\")|(?:))(?:(?:\\$(?:(?:D\\{\\s*\\w*.\\w*\\s*\\})|(?:V\\{\\s*\\w*\\s*\\})|(?:S\\{.+\\})))|(?:\\w*))(?:(?:\\\")|(?:)))(?:(?:\\s*,\\s*(?:\\\"(\\w*)\\\"))|(?:))(?:(?:\\s*,\\s*(?:(\\w*)))|(?:))\\)";
const int DATASOURCE_INDEX = 3; const int DATASOURCE_INDEX = 3;
const int VALUE_INDEX = 2; const int VALUE_INDEX = 2;
const int EXPRESSION_ARGUMENT_INDEX = 1; const int EXPRESSION_ARGUMENT_INDEX = 1;

View File

@ -85,7 +85,7 @@ namespace Const{
const QString VARIABLE_RX = "\\$V\\s*\\{\\s*([^{}]*)\\s*\\}"; const QString VARIABLE_RX = "\\$V\\s*\\{\\s*([^{}]*)\\s*\\}";
const QString NAMED_VARIABLE_RX = "\\$V\\s*\\{\\s*(%1)\\s*\\}"; const QString NAMED_VARIABLE_RX = "\\$V\\s*\\{\\s*(%1)\\s*\\}";
const QString SCRIPT_RX = "\\$S\\s*\\{(.*)\\}"; const QString SCRIPT_RX = "\\$S\\s*\\{(.*)\\}";
const QString GROUP_FUNCTION_PARAM_RX = "\\(\\s*((?:(?:\\\")|(?:))(?:(?:\\$(?:(?:D\\{\\s*\\w*.\\w*\\s*\\})|(?:V\\{\\s*\\w*\\s*\\})|(?:S\\{.+\\})))|(?:\\w*))(?:(?:\\\")|(?:)))(?:(?:\\s*,\\s*(?:\\\"(\\w*)\\\"))|(?:))\\)"; const QString GROUP_FUNCTION_PARAM_RX = "\\(\\s*((?:(?:\\\")|(?:))(?:(?:\\$(?:(?:D\\{\\s*\\w*.\\w*\\s*\\})|(?:V\\{\\s*\\w*\\s*\\})|(?:S\\{.+\\})))|(?:\\w*))(?:(?:\\\")|(?:)))(?:(?:\\s*,\\s*(?:\\\"(\\w*)\\\"))|(?:))(?:(?:\\s*,\\s*(?:(\\w*)))|(?:))\\)";
const int DATASOURCE_INDEX = 3; const int DATASOURCE_INDEX = 3;
const int VALUE_INDEX = 2; const int VALUE_INDEX = 2;
const int EXPRESSION_ARGUMENT_INDEX = 1; const int EXPRESSION_ARGUMENT_INDEX = 1;

View File

@ -32,6 +32,7 @@
#include "lrbanddesignintf.h" #include "lrbanddesignintf.h"
#include "lritemdesignintf.h" #include "lritemdesignintf.h"
#include "lrscriptenginemanager.h" #include "lrscriptenginemanager.h"
#include "lrpageitemdesignintf.h"
#include <QRegExp> #include <QRegExp>
@ -50,6 +51,7 @@ void GroupFunction::slotBandRendered(BandDesignIntf *band)
QString field = rxField.cap(1); QString field = rxField.cap(1);
if (m_dataManager->containsField(field)){ if (m_dataManager->containsField(field)){
m_values.push_back(m_dataManager->fieldData(field)); m_values.push_back(m_dataManager->fieldData(field));
m_valuesByBand.insert(band, m_dataManager->fieldData(field));
} else { } else {
setInvalid(tr("Field \"%1\" not found").arg(m_data)); setInvalid(tr("Field \"%1\" not found").arg(m_data));
} }
@ -60,6 +62,7 @@ void GroupFunction::slotBandRendered(BandDesignIntf *band)
QString var = rxVar.cap(1); QString var = rxVar.cap(1);
if (m_dataManager->containsVariable(var)){ if (m_dataManager->containsVariable(var)){
m_values.push_back(m_dataManager->variable(var)); m_values.push_back(m_dataManager->variable(var));
m_valuesByBand.insert(band, m_dataManager->variable(var));
} else { } else {
setInvalid(tr("Variable \"%1\" not found").arg(m_data)); setInvalid(tr("Variable \"%1\" not found").arg(m_data));
} }
@ -70,6 +73,7 @@ void GroupFunction::slotBandRendered(BandDesignIntf *band)
QVariant value = sm.evaluateScript(m_data); QVariant value = sm.evaluateScript(m_data);
if (value.isValid()){ if (value.isValid()){
m_values.push_back(value); m_values.push_back(value);
m_valuesByBand.insert(band, value);
} else { } else {
setInvalid(tr("Wrong script syntax \"%1\" ").arg(m_data)); setInvalid(tr("Wrong script syntax \"%1\" ").arg(m_data));
} }
@ -78,10 +82,12 @@ void GroupFunction::slotBandRendered(BandDesignIntf *band)
case ContentItem:{ case ContentItem:{
QString itemName = m_data; QString itemName = m_data;
ContentItemDesignIntf* item = dynamic_cast<ContentItemDesignIntf*>(band->childByName(itemName.remove('"'))); ContentItemDesignIntf* item = dynamic_cast<ContentItemDesignIntf*>(band->childByName(itemName.remove('"')));
if (item) if (item){
m_values.push_back(item->content()); m_values.push_back(item->content());
else if (m_name.compare("COUNT",Qt::CaseInsensitive) == 0) { m_valuesByBand.insert(band, item->content());
} else if (m_name.compare("COUNT",Qt::CaseInsensitive) == 0) {
m_values.push_back(1); m_values.push_back(1);
m_valuesByBand.insert(band, 1);
} else setInvalid(tr("Item \"%1\" not found").arg(m_data)); } else setInvalid(tr("Item \"%1\" not found").arg(m_data));
break; break;
@ -153,20 +159,32 @@ GroupFunctionFactory::~GroupFunctionFactory()
m_creators.clear(); m_creators.clear();
} }
QVariant SumGroupFunction::calculate() QVariant SumGroupFunction::calculate(PageItemDesignIntf *page)
{ {
QVariant res=0; QVariant res = 0;
foreach(QVariant value,values()){ if (!page){
res=addition(res,value); foreach(QVariant value,values()){
res = addition(res,value);
}
} else {
foreach (BandDesignIntf* band, page->bands()) {
res = addition(res, m_valuesByBand.value(band));
}
} }
return res; return res;
} }
QVariant AvgGroupFunction::calculate() QVariant AvgGroupFunction::calculate(PageItemDesignIntf *page)
{ {
QVariant res=QVariant(); QVariant res = QVariant();
foreach(QVariant value,values()){ if (!page){
res=addition(res,value); foreach(QVariant value,values()){
res=addition(res,value);
}
} else {
foreach (BandDesignIntf* band, page->bands()) {
res = addition(res, m_valuesByBand.value(band));
}
} }
if (!res.isNull()&&(values().count()>0)){ if (!res.isNull()&&(values().count()>0)){
res=division(res,values().count()); res=division(res,values().count());
@ -174,29 +192,58 @@ QVariant AvgGroupFunction::calculate()
return res; return res;
} }
QVariant MinGroupFunction::calculate() QVariant MinGroupFunction::calculate(PageItemDesignIntf *page)
{ {
//TODO: check variant type //TODO: check variant type
QVariant res = QVariant(); QVariant res = QVariant();
if (!values().empty()) res = values().at(0); if (!page){
foreach(QVariant value, values()){ if (!values().empty()) res = values().at(0);
if (res.toDouble()>value.toDouble()) res = value; foreach(QVariant value, values()){
if (res.toDouble() > value.toDouble()) res = value;
}
} else {
if (!page->bands().empty()) res = m_valuesByBand.value(page->bands().at(0));
foreach (BandDesignIntf* band, page->bands()) {
if (res.toDouble() > m_valuesByBand.value(band).toDouble()) res = m_valuesByBand.value(band);
}
} }
return res; return res;
} }
QVariant MaxGroupFunction::calculate() QVariant MaxGroupFunction::calculate(PageItemDesignIntf *page)
{ {
//TODO: check variant type //TODO: check variant type
QVariant res = QVariant(); QVariant res = QVariant();
if (!values().empty()) res = values().at(0);
foreach(QVariant value, values()){ if (!page){
if (res.toDouble()<value.toDouble()) res = value; if (!values().empty()) res = values().at(0);
foreach(QVariant value, values()){
if (res.toDouble() < value.toDouble()) res = value;
}
} else {
if (!page->bands().empty()) res = m_valuesByBand.value(page->bands().at(0));
foreach (BandDesignIntf* band, page->bands()) {
if (res.toDouble() < m_valuesByBand.value(band).toDouble()) res = m_valuesByBand.value(band);
}
} }
return res; return res;
} }
QVariant CountGroupFunction::calculate(PageItemDesignIntf *page){
if (!page){
return values().count();
} else {
int res = 0;
foreach (BandDesignIntf* band, page->bands()) {
if (!m_valuesByBand.value(band).isNull()){
res++;
}
}
return res;
}
}
} //namespace LimeReport } //namespace LimeReport

View File

@ -38,6 +38,7 @@ namespace LimeReport{
class DataSourceManager; class DataSourceManager;
class BandDesignIntf; class BandDesignIntf;
class PageItemDesignIntf;
class GroupFunction : public QObject{ class GroupFunction : public QObject{
Q_OBJECT Q_OBJECT
@ -50,8 +51,9 @@ public:
const QString& data(){return m_data;} const QString& data(){return m_data;}
const QString& error(){return m_errorMessage;} const QString& error(){return m_errorMessage;}
QVector<QVariant>& values(){return m_values;} QVector<QVariant>& values(){return m_values;}
QHash<BandDesignIntf*, QVariant> m_valuesByBand;
const QString& dataBandName(){return m_dataBandName;} const QString& dataBandName(){return m_dataBandName;}
virtual QVariant calculate()=0; virtual QVariant calculate(PageItemDesignIntf* page = 0)=0;
public slots: public slots:
void slotBandRendered(BandDesignIntf* band); void slotBandRendered(BandDesignIntf* band);
protected: protected:
@ -95,7 +97,7 @@ public:
CountGroupFunction(const QString& expression, const QString& dataBandName, DataSourceManager *dataManager) CountGroupFunction(const QString& expression, const QString& dataBandName, DataSourceManager *dataManager)
:GroupFunction(expression, dataBandName, dataManager){setName("COUNT");} :GroupFunction(expression, dataBandName, dataManager){setName("COUNT");}
protected: protected:
virtual QVariant calculate(){return values().count();} virtual QVariant calculate(PageItemDesignIntf* page = 0);
}; };
class SumGroupFunction :public GroupFunction{ class SumGroupFunction :public GroupFunction{
@ -104,7 +106,7 @@ public:
SumGroupFunction(const QString& expression, const QString& dataBandName, DataSourceManager *dataManager) SumGroupFunction(const QString& expression, const QString& dataBandName, DataSourceManager *dataManager)
:GroupFunction(expression, dataBandName, dataManager){setName("SUM");} :GroupFunction(expression, dataBandName, dataManager){setName("SUM");}
protected: protected:
virtual QVariant calculate(); virtual QVariant calculate(PageItemDesignIntf* page = 0);
}; };
class AvgGroupFunction :public GroupFunction{ class AvgGroupFunction :public GroupFunction{
@ -113,7 +115,7 @@ public:
AvgGroupFunction(const QString& expression, const QString& dataBandName, DataSourceManager *dataManager) AvgGroupFunction(const QString& expression, const QString& dataBandName, DataSourceManager *dataManager)
:GroupFunction(expression, dataBandName, dataManager){setName("AVG");} :GroupFunction(expression, dataBandName, dataManager){setName("AVG");}
protected: protected:
virtual QVariant calculate(); virtual QVariant calculate(PageItemDesignIntf* page = 0);
}; };
class MinGroupFunction :public GroupFunction{ class MinGroupFunction :public GroupFunction{
@ -122,7 +124,7 @@ public:
MinGroupFunction(const QString& expression, const QString& dataBandName, DataSourceManager *dataManager) MinGroupFunction(const QString& expression, const QString& dataBandName, DataSourceManager *dataManager)
:GroupFunction(expression, dataBandName, dataManager){setName("MIN");} :GroupFunction(expression, dataBandName, dataManager){setName("MIN");}
protected: protected:
virtual QVariant calculate(); virtual QVariant calculate(PageItemDesignIntf* page = 0);
}; };
class MaxGroupFunction :public GroupFunction{ class MaxGroupFunction :public GroupFunction{
@ -131,7 +133,7 @@ public:
MaxGroupFunction(const QString& expression, const QString& dataBandName, DataSourceManager *dataManager) MaxGroupFunction(const QString& expression, const QString& dataBandName, DataSourceManager *dataManager)
:GroupFunction(expression, dataBandName, dataManager){setName("MAX");} :GroupFunction(expression, dataBandName, dataManager){setName("MAX");}
protected: protected:
virtual QVariant calculate(); virtual QVariant calculate(PageItemDesignIntf* page = 0);
}; };
template <typename T> template <typename T>

View File

@ -253,7 +253,7 @@ void ReportRender::renderPage(PageItemDesignIntf* patternPage, bool isTOC, bool
} }
#ifndef USE_QJSENGINE #ifndef USE_QJSENGINE
ScriptEngineManager::instance().scriptEngine()->popContext(); Manager::instance().scriptEScriptEnginengine()->popContext();
#endif #endif
} }
@ -294,6 +294,24 @@ void ReportRender::initRenderPage()
m_renderPageItem->setItemMode(PreviewMode); m_renderPageItem->setItemMode(PreviewMode);
m_renderPageItem->setPatternName(m_patternPageItem->objectName()); m_renderPageItem->setPatternName(m_patternPageItem->objectName());
m_renderPageItem->setPatternItem(m_patternPageItem); m_renderPageItem->setPatternItem(m_patternPageItem);
ScriptValueType svCurrentPage;
ScriptEngineType* se = ScriptEngineManager::instance().scriptEngine();
#ifdef USE_QJSENGINE
svCurrentPage = getCppOwnedJSValue(*se, m_renderPageItem);
se->globalObject().setProperty("currentPage", svCurrentPage);
#else
svCurrentPage = se->globalObject().property("currentPage");
if (svCurrentPage.isValid()){
se->newQObject(svCurrentPage, m_renderPageItem);
} else {
svThis = se->newQObject(m_renderPageItem);
se->globalObject().setProperty("currentPage", svCurrentPage);
}
#endif
} }
} }
@ -384,7 +402,15 @@ void ReportRender::replaceGroupFunctionsInItem(ContentItemDesignIntf* contentIte
QVector<QString> captures = normalizeCaptures(rx); QVector<QString> captures = normalizeCaptures(rx);
if (captures.size() >= 3){ if (captures.size() >= 3){
QString expressionIndex = datasources()->putGroupFunctionsExpressions(captures.at(Const::VALUE_INDEX)); QString expressionIndex = datasources()->putGroupFunctionsExpressions(captures.at(Const::VALUE_INDEX));
content.replace(captures.at(0),QString("%1(%2,%3)").arg(functionName).arg('"'+expressionIndex+'"').arg('"'+band->objectName()+'"')); if (captures.size()<5){
content.replace(captures.at(0),QString("%1(%2,%3)").arg(functionName).arg('"'+expressionIndex+'"').arg('"'+band->objectName()+'"'));
} else {
content.replace(captures.at(0),QString("%1(%2,%3,%4)")
.arg(functionName)
.arg('"'+expressionIndex+'"')
.arg('"'+band->objectName()+'"')
.arg(captures.at(4)));
}
} }
pos += rx.matchedLength(); pos += rx.matchedLength();
} }

View File

@ -41,6 +41,7 @@
#include "lrdatasourcemanager.h" #include "lrdatasourcemanager.h"
#include "lrbasedesignintf.h" #include "lrbasedesignintf.h"
#include "lrbanddesignintf.h" #include "lrbanddesignintf.h"
#include "lrpageitemdesignintf.h"
Q_DECLARE_METATYPE(QColor) Q_DECLARE_METATYPE(QColor)
Q_DECLARE_METATYPE(QFont) Q_DECLARE_METATYPE(QFont)
@ -340,8 +341,9 @@ void ScriptEngineManager::setDataManager(DataSourceManager *dataManager){
func+"(\""+tr("FieldName")+"\",\""+tr("BandName")+"\")", func+"(\""+tr("FieldName")+"\",\""+tr("BandName")+"\")",
LimeReport::Const::FUNCTION_MANAGER_NAME, LimeReport::Const::FUNCTION_MANAGER_NAME,
m_functionManager, m_functionManager,
QString("function %1(fieldName,bandName){\ QString("function %1(fieldName, bandName, pageitem){\
return %2.calcGroupFunction(\"%1\",fieldName,bandName);}" pageitem = typeof pageitem !== 'undefined' ? pageitem : 0; \
return %2.calcGroupFunction(\"%1\",fieldName, bandName, pageitem);}"
).arg(func) ).arg(func)
.arg(LimeReport::Const::FUNCTION_MANAGER_NAME) .arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
); );
@ -1444,14 +1446,15 @@ void JSFunctionDesc::setScriptWrapper(const QString &scriptWrapper)
m_scriptWrapper = scriptWrapper; m_scriptWrapper = scriptWrapper;
} }
QVariant ScriptFunctionsManager::calcGroupFunction(const QString &name, const QString &expressionID, const QString &bandName) QVariant ScriptFunctionsManager::calcGroupFunction(const QString &name, const QString &expressionID, const QString &bandName, QObject* currentPage)
{ {
if (m_scriptEngineManager->dataManager()){ if (m_scriptEngineManager->dataManager()){
PageItemDesignIntf* pageItem = dynamic_cast<PageItemDesignIntf*>(currentPage);
QString expression = m_scriptEngineManager->dataManager()->getExpression(expressionID); QString expression = m_scriptEngineManager->dataManager()->getExpression(expressionID);
GroupFunction* gf = m_scriptEngineManager->dataManager()->groupFunction(name,expression,bandName); GroupFunction* gf = m_scriptEngineManager->dataManager()->groupFunction(name,expression,bandName);
if (gf){ if (gf){
if (gf->isValid()){ if (gf->isValid()){
return gf->calculate(); return gf->calculate(pageItem);
}else{ }else{
return gf->error(); return gf->error();
} }

View File

@ -305,7 +305,7 @@ public:
~ScriptFunctionsManager(){ ~ScriptFunctionsManager(){
foreach(IWrapperCreator* wrapper, m_wrappersFactory.values()){ delete wrapper;} m_wrappersFactory.clear(); foreach(IWrapperCreator* wrapper, m_wrappersFactory.values()){ delete wrapper;} m_wrappersFactory.clear();
} }
Q_INVOKABLE QVariant calcGroupFunction(const QString& name, const QString& expressionID, const QString& bandName); Q_INVOKABLE QVariant calcGroupFunction(const QString& name, const QString& expressionID, const QString& bandName, QObject* currentPage);
Q_INVOKABLE QVariant line(const QString& bandName); Q_INVOKABLE QVariant line(const QString& bandName);
Q_INVOKABLE QVariant numberFormat(QVariant value, const char &format, int precision, const QString &locale); Q_INVOKABLE QVariant numberFormat(QVariant value, const char &format, int precision, const QString &locale);
Q_INVOKABLE QVariant dateFormat(QVariant value, const QString& format); Q_INVOKABLE QVariant dateFormat(QVariant value, const QString& format);