From 4c162e0e470c16e1868490d405759dc938ed94e4 Mon Sep 17 00:00:00 2001 From: Arin Alex Date: Wed, 14 Mar 2018 11:22:03 +0300 Subject: [PATCH] Group functions have been changed --- include/lrglobal.h | 2 +- limereport/lrglobal.h | 2 +- limereport/lrgroupfunctions.cpp | 83 ++++++++++++++++++++++------ limereport/lrgroupfunctions.h | 14 +++-- limereport/lrreportrender.cpp | 30 +++++++++- limereport/lrscriptenginemanager.cpp | 11 ++-- limereport/lrscriptenginemanager.h | 2 +- 7 files changed, 111 insertions(+), 33 deletions(-) diff --git a/include/lrglobal.h b/include/lrglobal.h index 4829390..4ddad30 100644 --- a/include/lrglobal.h +++ b/include/lrglobal.h @@ -85,7 +85,7 @@ namespace Const{ const QString VARIABLE_RX = "\\$V\\s*\\{\\s*([^{}]*)\\s*\\}"; const QString NAMED_VARIABLE_RX = "\\$V\\s*\\{\\s*(%1)\\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 VALUE_INDEX = 2; const int EXPRESSION_ARGUMENT_INDEX = 1; diff --git a/limereport/lrglobal.h b/limereport/lrglobal.h index 4829390..4ddad30 100644 --- a/limereport/lrglobal.h +++ b/limereport/lrglobal.h @@ -85,7 +85,7 @@ namespace Const{ const QString VARIABLE_RX = "\\$V\\s*\\{\\s*([^{}]*)\\s*\\}"; const QString NAMED_VARIABLE_RX = "\\$V\\s*\\{\\s*(%1)\\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 VALUE_INDEX = 2; const int EXPRESSION_ARGUMENT_INDEX = 1; diff --git a/limereport/lrgroupfunctions.cpp b/limereport/lrgroupfunctions.cpp index c265dfc..b3ea189 100644 --- a/limereport/lrgroupfunctions.cpp +++ b/limereport/lrgroupfunctions.cpp @@ -32,6 +32,7 @@ #include "lrbanddesignintf.h" #include "lritemdesignintf.h" #include "lrscriptenginemanager.h" +#include "lrpageitemdesignintf.h" #include @@ -50,6 +51,7 @@ void GroupFunction::slotBandRendered(BandDesignIntf *band) QString field = rxField.cap(1); if (m_dataManager->containsField(field)){ m_values.push_back(m_dataManager->fieldData(field)); + m_valuesByBand.insert(band, m_dataManager->fieldData(field)); } else { setInvalid(tr("Field \"%1\" not found").arg(m_data)); } @@ -60,6 +62,7 @@ void GroupFunction::slotBandRendered(BandDesignIntf *band) QString var = rxVar.cap(1); if (m_dataManager->containsVariable(var)){ m_values.push_back(m_dataManager->variable(var)); + m_valuesByBand.insert(band, m_dataManager->variable(var)); } else { setInvalid(tr("Variable \"%1\" not found").arg(m_data)); } @@ -70,6 +73,7 @@ void GroupFunction::slotBandRendered(BandDesignIntf *band) QVariant value = sm.evaluateScript(m_data); if (value.isValid()){ m_values.push_back(value); + m_valuesByBand.insert(band, value); } else { setInvalid(tr("Wrong script syntax \"%1\" ").arg(m_data)); } @@ -78,10 +82,12 @@ void GroupFunction::slotBandRendered(BandDesignIntf *band) case ContentItem:{ QString itemName = m_data; ContentItemDesignIntf* item = dynamic_cast(band->childByName(itemName.remove('"'))); - if (item) + if (item){ 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_valuesByBand.insert(band, 1); } else setInvalid(tr("Item \"%1\" not found").arg(m_data)); break; @@ -153,20 +159,32 @@ GroupFunctionFactory::~GroupFunctionFactory() m_creators.clear(); } -QVariant SumGroupFunction::calculate() +QVariant SumGroupFunction::calculate(PageItemDesignIntf *page) { - QVariant res=0; - foreach(QVariant value,values()){ - res=addition(res,value); + QVariant res = 0; + if (!page){ + foreach(QVariant value,values()){ + res = addition(res,value); + } + } else { + foreach (BandDesignIntf* band, page->bands()) { + res = addition(res, m_valuesByBand.value(band)); + } } return res; } -QVariant AvgGroupFunction::calculate() +QVariant AvgGroupFunction::calculate(PageItemDesignIntf *page) { - QVariant res=QVariant(); - foreach(QVariant value,values()){ - res=addition(res,value); + QVariant res = QVariant(); + if (!page){ + 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)){ res=division(res,values().count()); @@ -174,29 +192,58 @@ QVariant AvgGroupFunction::calculate() return res; } -QVariant MinGroupFunction::calculate() +QVariant MinGroupFunction::calculate(PageItemDesignIntf *page) { //TODO: check variant type QVariant res = QVariant(); - if (!values().empty()) res = values().at(0); - foreach(QVariant value, values()){ - if (res.toDouble()>value.toDouble()) res = value; + if (!page){ + 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; } -QVariant MaxGroupFunction::calculate() +QVariant MaxGroupFunction::calculate(PageItemDesignIntf *page) { //TODO: check variant type QVariant res = QVariant(); - if (!values().empty()) res = values().at(0); - foreach(QVariant value, values()){ - if (res.toDouble()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; } +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 diff --git a/limereport/lrgroupfunctions.h b/limereport/lrgroupfunctions.h index f85a0bd..28cc08b 100644 --- a/limereport/lrgroupfunctions.h +++ b/limereport/lrgroupfunctions.h @@ -38,6 +38,7 @@ namespace LimeReport{ class DataSourceManager; class BandDesignIntf; +class PageItemDesignIntf; class GroupFunction : public QObject{ Q_OBJECT @@ -50,8 +51,9 @@ public: const QString& data(){return m_data;} const QString& error(){return m_errorMessage;} QVector& values(){return m_values;} + QHash m_valuesByBand; const QString& dataBandName(){return m_dataBandName;} - virtual QVariant calculate()=0; + virtual QVariant calculate(PageItemDesignIntf* page = 0)=0; public slots: void slotBandRendered(BandDesignIntf* band); protected: @@ -95,7 +97,7 @@ public: CountGroupFunction(const QString& expression, const QString& dataBandName, DataSourceManager *dataManager) :GroupFunction(expression, dataBandName, dataManager){setName("COUNT");} protected: - virtual QVariant calculate(){return values().count();} + virtual QVariant calculate(PageItemDesignIntf* page = 0); }; class SumGroupFunction :public GroupFunction{ @@ -104,7 +106,7 @@ public: SumGroupFunction(const QString& expression, const QString& dataBandName, DataSourceManager *dataManager) :GroupFunction(expression, dataBandName, dataManager){setName("SUM");} protected: - virtual QVariant calculate(); + virtual QVariant calculate(PageItemDesignIntf* page = 0); }; class AvgGroupFunction :public GroupFunction{ @@ -113,7 +115,7 @@ public: AvgGroupFunction(const QString& expression, const QString& dataBandName, DataSourceManager *dataManager) :GroupFunction(expression, dataBandName, dataManager){setName("AVG");} protected: - virtual QVariant calculate(); + virtual QVariant calculate(PageItemDesignIntf* page = 0); }; class MinGroupFunction :public GroupFunction{ @@ -122,7 +124,7 @@ public: MinGroupFunction(const QString& expression, const QString& dataBandName, DataSourceManager *dataManager) :GroupFunction(expression, dataBandName, dataManager){setName("MIN");} protected: - virtual QVariant calculate(); + virtual QVariant calculate(PageItemDesignIntf* page = 0); }; class MaxGroupFunction :public GroupFunction{ @@ -131,7 +133,7 @@ public: MaxGroupFunction(const QString& expression, const QString& dataBandName, DataSourceManager *dataManager) :GroupFunction(expression, dataBandName, dataManager){setName("MAX");} protected: - virtual QVariant calculate(); + virtual QVariant calculate(PageItemDesignIntf* page = 0); }; template diff --git a/limereport/lrreportrender.cpp b/limereport/lrreportrender.cpp index d6876b9..725c969 100644 --- a/limereport/lrreportrender.cpp +++ b/limereport/lrreportrender.cpp @@ -253,7 +253,7 @@ void ReportRender::renderPage(PageItemDesignIntf* patternPage, bool isTOC, bool } #ifndef USE_QJSENGINE - ScriptEngineManager::instance().scriptEngine()->popContext(); + Manager::instance().scriptEScriptEnginengine()->popContext(); #endif } @@ -294,6 +294,24 @@ void ReportRender::initRenderPage() m_renderPageItem->setItemMode(PreviewMode); m_renderPageItem->setPatternName(m_patternPageItem->objectName()); 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 captures = normalizeCaptures(rx); if (captures.size() >= 3){ 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(); } diff --git a/limereport/lrscriptenginemanager.cpp b/limereport/lrscriptenginemanager.cpp index 2bc89a5..50ef677 100644 --- a/limereport/lrscriptenginemanager.cpp +++ b/limereport/lrscriptenginemanager.cpp @@ -41,6 +41,7 @@ #include "lrdatasourcemanager.h" #include "lrbasedesignintf.h" #include "lrbanddesignintf.h" +#include "lrpageitemdesignintf.h" Q_DECLARE_METATYPE(QColor) Q_DECLARE_METATYPE(QFont) @@ -340,8 +341,9 @@ void ScriptEngineManager::setDataManager(DataSourceManager *dataManager){ func+"(\""+tr("FieldName")+"\",\""+tr("BandName")+"\")", LimeReport::Const::FUNCTION_MANAGER_NAME, m_functionManager, - QString("function %1(fieldName,bandName){\ - return %2.calcGroupFunction(\"%1\",fieldName,bandName);}" + QString("function %1(fieldName, bandName, pageitem){\ + pageitem = typeof pageitem !== 'undefined' ? pageitem : 0; \ + return %2.calcGroupFunction(\"%1\",fieldName, bandName, pageitem);}" ).arg(func) .arg(LimeReport::Const::FUNCTION_MANAGER_NAME) ); @@ -1444,14 +1446,15 @@ void JSFunctionDesc::setScriptWrapper(const QString &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()){ + PageItemDesignIntf* pageItem = dynamic_cast(currentPage); QString expression = m_scriptEngineManager->dataManager()->getExpression(expressionID); GroupFunction* gf = m_scriptEngineManager->dataManager()->groupFunction(name,expression,bandName); if (gf){ if (gf->isValid()){ - return gf->calculate(); + return gf->calculate(pageItem); }else{ return gf->error(); } diff --git a/limereport/lrscriptenginemanager.h b/limereport/lrscriptenginemanager.h index dc30657..c263b39 100644 --- a/limereport/lrscriptenginemanager.h +++ b/limereport/lrscriptenginemanager.h @@ -305,7 +305,7 @@ public: ~ScriptFunctionsManager(){ 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 numberFormat(QVariant value, const char &format, int precision, const QString &locale); Q_INVOKABLE QVariant dateFormat(QVariant value, const QString& format);