mirror of
https://github.com/python-LimeReport/LimeReport.git
synced 2024-12-24 12:34:39 +03:00
Group functions have been refactored. From now they can use script expression in value parameter
This commit is contained in:
parent
887710d728
commit
afc8ad77b2
@ -51,4 +51,20 @@ void ReportSettings::setSuppressAbsentFieldsAndVarsWarnings(bool suppressAbsentF
|
||||
m_suppressAbsentFieldsAndVarsWarnings = suppressAbsentFieldsAndVarsWarnings;
|
||||
}
|
||||
|
||||
QString escapeSimbols(const QString &value)
|
||||
{
|
||||
QString result = value;
|
||||
result.replace("\"","\\\"");
|
||||
result.replace('\n',"\\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
QString replaceHTMLSymbols(const QString &value)
|
||||
{
|
||||
QString result = value;
|
||||
result.replace("<","<");
|
||||
result.replace(">",">");
|
||||
return result;
|
||||
}
|
||||
|
||||
} //namespace LimeReport
|
||||
|
@ -82,16 +82,21 @@ namespace Const{
|
||||
//const int DATASOURCE_INDEX = 6;
|
||||
//const int VALUE_INDEX = 2;
|
||||
|
||||
const QString GROUP_FUNCTION_PARAM_RX = "\\(\\s*(?:(?:((?:(?:\\\"?\\$D\\s*\\{\\s*)|(?:\\\"?\\$V\\s*\\{\\s*)|(?:\\\"))((?:\\w+\\.?\\w+)|(?:\\w+))(?:(?:\\\")|(?:\\s*\\}\\\"?\\s*)))\\s*,)|(?:))\\s*\\\"(\\w+)\\\"\\s*\\)";
|
||||
const int DATASOURCE_INDEX = 4;
|
||||
const int VALUE_INDEX = 2;
|
||||
const int EXPRESSION_ARGUMENT_INDEX = 3;
|
||||
//const QString GROUP_FUNCTION_PARAM_RX = "\\(\\s*(?:(?:((?:(?:\\\"?\\$D\\s*\\{\\s*)|(?:\\\"?\\$V\\s*\\{\\s*)|(?:\\\"?\\$S\\s*\\{\\s*)|(?:\\\"))((?:\\w+\\.?\\w+)|(?:\\w+))(?:(?:\\\")|(?:\\s*\\}\\\"?\\s*)))\\s*,)|(?:))\\s*\\\"(\\w+)\\\"\\s*\\)";
|
||||
const QString GROUP_FUNCTION_PARAM_RX = "\\((?:(.+),|(?:))(?:\\\"(\\w+)\\\")\\)";
|
||||
const int DATASOURCE_INDEX = 3;//4;
|
||||
const int VALUE_INDEX = 2; //2;
|
||||
const int EXPRESSION_ARGUMENT_INDEX = 1;//3;
|
||||
|
||||
const QString GROUP_FUNCTION_RX = "(%1\\s*"+GROUP_FUNCTION_PARAM_RX+")";
|
||||
const QString GROUP_FUNCTION_NAME_RX = "%1\\s*\\((.*[^\\)])\\)";
|
||||
const int SCENE_MARGIN = 50;
|
||||
}
|
||||
QString extractClassName(QString className);
|
||||
QString escapeSimbols(const QString& value);
|
||||
QString replaceHTMLSymbols(const QString &value);
|
||||
|
||||
enum ExpandType {EscapeSymbols, NoEscapeSymbols, ReplaceHTMLSymbols};
|
||||
enum RenderPass {FirstPass, SecondPass};
|
||||
enum ArrangeType {AsNeeded, Force};
|
||||
enum PreviewHint{ShowAllPreviewBars = 0,
|
||||
@ -100,6 +105,7 @@ namespace Const{
|
||||
HidePreviewStatusBar = 4,
|
||||
HideAllPreviewBar = 7,
|
||||
PreviewBarsUserSetting = 8};
|
||||
|
||||
Q_DECLARE_FLAGS(PreviewHints, PreviewHint)
|
||||
Q_FLAGS(PreviewHints)
|
||||
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include "lrreportdesignwidget.h"
|
||||
#include "qgraphicsitem.h"
|
||||
#include "lrdesignelementsfactory.h"
|
||||
|
||||
#include "lrhorizontallayout.h"
|
||||
|
||||
#include <memory>
|
||||
@ -241,150 +240,29 @@ QFont BaseDesignIntf::transformToSceneFont(const QFont& value) const
|
||||
return f;
|
||||
}
|
||||
|
||||
QString BaseDesignIntf::escapeSimbols(const QString &value)
|
||||
{
|
||||
QString result = value;
|
||||
result.replace("\"","\\\"");
|
||||
result.replace('\n',"\\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
QString BaseDesignIntf::replaceHTMLSymbols(const QString &value)
|
||||
{
|
||||
QString result = value;
|
||||
result.replace("<","<");
|
||||
result.replace(">",">");
|
||||
return result;
|
||||
}
|
||||
|
||||
QString BaseDesignIntf::expandDataFields(QString context, ExpandType expandType, DataSourceManager* dataManager)
|
||||
{
|
||||
QRegExp rx(Const::FIELD_RX);
|
||||
|
||||
if (context.contains(rx)){
|
||||
while ((rx.indexIn(context))!=-1){
|
||||
QString field=rx.cap(1);
|
||||
|
||||
if (dataManager->containsField(field)) {
|
||||
QString fieldValue;
|
||||
m_varValue = dataManager->fieldData(field);
|
||||
if (expandType == EscapeSymbols) {
|
||||
if (dataManager->fieldData(field).isNull()) {
|
||||
fieldValue="\"\"";
|
||||
} else {
|
||||
fieldValue = escapeSimbols(m_varValue.toString());
|
||||
switch (dataManager->fieldData(field).type()) {
|
||||
case QVariant::Char:
|
||||
case QVariant::String:
|
||||
case QVariant::StringList:
|
||||
case QVariant::Date:
|
||||
case QVariant::DateTime:
|
||||
fieldValue = "\""+fieldValue+"\"";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (expandType == ReplaceHTMLSymbols)
|
||||
fieldValue = replaceHTMLSymbols(m_varValue.toString());
|
||||
else fieldValue = m_varValue.toString();
|
||||
}
|
||||
|
||||
context.replace(rx.cap(0),fieldValue);
|
||||
|
||||
} else {
|
||||
QString error = QString("Field %1 not found in %2 !!! ").arg(field).arg(this->objectName());
|
||||
dataManager->putError(error);
|
||||
if (!reportSettings() || !reportSettings()->suppressAbsentFieldsAndVarsWarnings())
|
||||
context.replace(rx.cap(0),error);
|
||||
else
|
||||
context.replace(rx.cap(0),"");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return context;
|
||||
ScriptEngineManager& sm = ScriptEngineManager::instance();
|
||||
if (sm.dataManager() != dataManager) sm.setDataManager(dataManager);
|
||||
return sm.expandDataFields(context, expandType, m_varValue, this);
|
||||
}
|
||||
|
||||
QString BaseDesignIntf::expandUserVariables(QString context, RenderPass pass, ExpandType expandType, DataSourceManager* dataManager)
|
||||
{
|
||||
QRegExp rx(Const::VARIABLE_RX);
|
||||
if (context.contains(rx)){
|
||||
int pos = 0;
|
||||
while ((pos = rx.indexIn(context,pos))!=-1){
|
||||
QString variable=rx.cap(1);
|
||||
pos += rx.matchedLength();
|
||||
if (dataManager->containsVariable(variable) ){
|
||||
try {
|
||||
if (pass==dataManager->variablePass(variable)){
|
||||
m_varValue = dataManager->variable(variable);
|
||||
switch (expandType){
|
||||
case EscapeSymbols:
|
||||
context.replace(rx.cap(0),escapeSimbols(m_varValue.toString()));
|
||||
break;
|
||||
case NoEscapeSymbols:
|
||||
context.replace(rx.cap(0),m_varValue.toString());
|
||||
break;
|
||||
case ReplaceHTMLSymbols:
|
||||
context.replace(rx.cap(0),replaceHTMLSymbols(m_varValue.toString()));
|
||||
break;
|
||||
}
|
||||
pos=0;
|
||||
}
|
||||
} catch (ReportError e){
|
||||
dataManager->putError(e.what());
|
||||
if (!reportSettings() || reportSettings()->suppressAbsentFieldsAndVarsWarnings())
|
||||
context.replace(rx.cap(0),e.what());
|
||||
else
|
||||
context.replace(rx.cap(0),"");
|
||||
}
|
||||
} else {
|
||||
QString error;
|
||||
error = tr("Variable %1 not found").arg(variable);
|
||||
dataManager->putError(error);
|
||||
if (!reportSettings() || reportSettings()->suppressAbsentFieldsAndVarsWarnings())
|
||||
context.replace(rx.cap(0),error);
|
||||
else
|
||||
context.replace(rx.cap(0),"");
|
||||
}
|
||||
}
|
||||
}
|
||||
return context;
|
||||
|
||||
ScriptEngineManager& sm = ScriptEngineManager::instance();
|
||||
if (sm.dataManager() != dataManager) sm.setDataManager(dataManager);
|
||||
return sm.expandUserVariables(context, pass, expandType, m_varValue);
|
||||
|
||||
}
|
||||
|
||||
QString BaseDesignIntf::expandScripts(QString context, DataSourceManager* dataManager)
|
||||
{
|
||||
QRegExp rx(Const::SCRIPT_RX);
|
||||
|
||||
if (context.contains(rx)){
|
||||
ScriptEngineManager::instance().setDataManager(dataManager);
|
||||
QScriptEngine* se = ScriptEngineManager::instance().scriptEngine();
|
||||
ScriptEngineManager& sm = ScriptEngineManager::instance();
|
||||
if (sm.dataManager() != dataManager) sm.setDataManager(dataManager);
|
||||
return sm.expandScripts(context,m_varValue,this);
|
||||
|
||||
QScriptValue svThis = se->globalObject().property("THIS");
|
||||
if (svThis.isValid()){
|
||||
se->newQObject(svThis, this);
|
||||
} else {
|
||||
svThis = se->newQObject(this);
|
||||
se->globalObject().setProperty("THIS",svThis);
|
||||
}
|
||||
|
||||
ScriptExtractor scriptExtractor(context);
|
||||
if (scriptExtractor.parse()){
|
||||
for(int i=0; i<scriptExtractor.count();++i){
|
||||
QString scriptBody = expandDataFields(scriptExtractor.bodyAt(i),EscapeSymbols, dataManager);
|
||||
scriptBody = expandUserVariables(scriptBody, FirstPass, EscapeSymbols, dataManager);
|
||||
QScriptValue value = se->evaluate(scriptBody);
|
||||
if (!se->hasUncaughtException()) {
|
||||
m_varValue = value.toVariant();
|
||||
context.replace(scriptExtractor.scriptAt(i),value.toString());
|
||||
} else {
|
||||
context.replace(scriptExtractor.scriptAt(i),se->uncaughtException().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
void BaseDesignIntf::setupPainter(QPainter *painter) const
|
||||
|
@ -131,7 +131,7 @@ public:
|
||||
};
|
||||
enum ObjectState {ObjectLoading, ObjectLoaded, ObjectCreated};
|
||||
enum ItemAlign {LeftItemAlign,RightItemAlign,CenterItemAlign,ParentWidthItemAlign,DesignedItemAlign};
|
||||
enum ExpandType {EscapeSymbols, NoEscapeSymbols, ReplaceHTMLSymbols};
|
||||
// enum ExpandType {EscapeSymbols, NoEscapeSymbols, ReplaceHTMLSymbols};
|
||||
Q_DECLARE_FLAGS(BorderLines, BorderSide)
|
||||
Q_DECLARE_FLAGS(ItemMode,ItemModes)
|
||||
friend class SelectionMarker;
|
||||
@ -327,11 +327,9 @@ protected:
|
||||
virtual bool drawDesignBorders() const {return true;}
|
||||
virtual QColor selectionMarkerColor(){ return Const::SELECTION_COLOR;}
|
||||
|
||||
QString escapeSimbols(const QString& value);
|
||||
QString replaceHTMLSymbols(const QString& value);
|
||||
virtual QString expandUserVariables(QString context, RenderPass pass, ExpandType expandType, DataSourceManager *dataManager);
|
||||
virtual QString expandDataFields(QString context, ExpandType expandType, DataSourceManager *dataManager);
|
||||
virtual QString expandScripts(QString context, DataSourceManager *dataManager);
|
||||
QString expandUserVariables(QString context, RenderPass pass, ExpandType expandType, DataSourceManager *dataManager);
|
||||
QString expandDataFields(QString context, ExpandType expandType, DataSourceManager *dataManager);
|
||||
QString expandScripts(QString context, DataSourceManager *dataManager);
|
||||
|
||||
QVariant m_varValue;
|
||||
|
||||
|
@ -238,6 +238,29 @@ void DataSourceManager::setDefaultDatabasePath(const QString &defaultDatabasePat
|
||||
{
|
||||
m_defaultDatabasePath = defaultDatabasePath;
|
||||
}
|
||||
|
||||
QString DataSourceManager::putGroupFunctionsExpressions(QString expression)
|
||||
{
|
||||
if (m_groupFunctionsExpressionsMap.contains(expression)){
|
||||
return QString::number(m_groupFunctionsExpressionsMap.value(expression));
|
||||
} else {
|
||||
m_groupFunctionsExpressions.append(expression);
|
||||
m_groupFunctionsExpressionsMap.insert(expression, m_groupFunctionsExpressions.size()-1);
|
||||
return QString::number(m_groupFunctionsExpressions.size()-1);
|
||||
}
|
||||
}
|
||||
|
||||
void DataSourceManager::clearGroupFuntionsExpressions()
|
||||
{
|
||||
m_groupFunctionsExpressionsMap.clear();
|
||||
m_groupFunctionsExpressions.clear();
|
||||
}
|
||||
|
||||
QString DataSourceManager::getExpression(QString index)
|
||||
{
|
||||
return m_groupFunctionsExpressions.at(index.toInt());
|
||||
}
|
||||
|
||||
bool DataSourceManager::designTime() const
|
||||
{
|
||||
return m_designTime;
|
||||
@ -702,6 +725,16 @@ bool DataSourceManager::initAndOpenDB(QSqlDatabase& db, ConnectionDesc& connecti
|
||||
return connected;
|
||||
}
|
||||
|
||||
ReportSettings *DataSourceManager::reportSettings() const
|
||||
{
|
||||
return m_reportSettings;
|
||||
}
|
||||
|
||||
void DataSourceManager::setReportSettings(ReportSettings *reportSettings)
|
||||
{
|
||||
m_reportSettings = reportSettings;
|
||||
}
|
||||
|
||||
bool DataSourceManager::connectConnection(ConnectionDesc *connectionDesc)
|
||||
{
|
||||
|
||||
|
@ -192,6 +192,13 @@ public:
|
||||
QString defaultDatabasePath() const;
|
||||
void setDefaultDatabasePath(const QString &defaultDatabasePath);
|
||||
|
||||
QString putGroupFunctionsExpressions(QString expression);
|
||||
void clearGroupFuntionsExpressions();
|
||||
QString getExpression(QString index);
|
||||
|
||||
ReportSettings *reportSettings() const;
|
||||
void setReportSettings(ReportSettings *reportSettings);
|
||||
|
||||
signals:
|
||||
void loadCollectionFinished(const QString& collectionName);
|
||||
void cleared();
|
||||
@ -240,7 +247,13 @@ private:
|
||||
bool m_designTime;
|
||||
bool m_needUpdate;
|
||||
QString m_defaultDatabasePath;
|
||||
ReportSettings* m_reportSettings;
|
||||
QHash<QString,int> m_groupFunctionsExpressionsMap;
|
||||
QVector<QString> m_groupFunctionsExpressions;
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#endif // LRDATASOURCEMANAGER_H
|
||||
|
||||
|
@ -51,4 +51,20 @@ void ReportSettings::setSuppressAbsentFieldsAndVarsWarnings(bool suppressAbsentF
|
||||
m_suppressAbsentFieldsAndVarsWarnings = suppressAbsentFieldsAndVarsWarnings;
|
||||
}
|
||||
|
||||
QString escapeSimbols(const QString &value)
|
||||
{
|
||||
QString result = value;
|
||||
result.replace("\"","\\\"");
|
||||
result.replace('\n',"\\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
QString replaceHTMLSymbols(const QString &value)
|
||||
{
|
||||
QString result = value;
|
||||
result.replace("<","<");
|
||||
result.replace(">",">");
|
||||
return result;
|
||||
}
|
||||
|
||||
} //namespace LimeReport
|
||||
|
@ -82,16 +82,21 @@ namespace Const{
|
||||
//const int DATASOURCE_INDEX = 6;
|
||||
//const int VALUE_INDEX = 2;
|
||||
|
||||
const QString GROUP_FUNCTION_PARAM_RX = "\\(\\s*(?:(?:((?:(?:\\\"?\\$D\\s*\\{\\s*)|(?:\\\"?\\$V\\s*\\{\\s*)|(?:\\\"))((?:\\w+\\.?\\w+)|(?:\\w+))(?:(?:\\\")|(?:\\s*\\}\\\"?\\s*)))\\s*,)|(?:))\\s*\\\"(\\w+)\\\"\\s*\\)";
|
||||
const int DATASOURCE_INDEX = 4;
|
||||
const int VALUE_INDEX = 2;
|
||||
const int EXPRESSION_ARGUMENT_INDEX = 3;
|
||||
//const QString GROUP_FUNCTION_PARAM_RX = "\\(\\s*(?:(?:((?:(?:\\\"?\\$D\\s*\\{\\s*)|(?:\\\"?\\$V\\s*\\{\\s*)|(?:\\\"?\\$S\\s*\\{\\s*)|(?:\\\"))((?:\\w+\\.?\\w+)|(?:\\w+))(?:(?:\\\")|(?:\\s*\\}\\\"?\\s*)))\\s*,)|(?:))\\s*\\\"(\\w+)\\\"\\s*\\)";
|
||||
const QString GROUP_FUNCTION_PARAM_RX = "\\((?:(.+),|(?:))(?:\\\"(\\w+)\\\")\\)";
|
||||
const int DATASOURCE_INDEX = 3;//4;
|
||||
const int VALUE_INDEX = 2; //2;
|
||||
const int EXPRESSION_ARGUMENT_INDEX = 1;//3;
|
||||
|
||||
const QString GROUP_FUNCTION_RX = "(%1\\s*"+GROUP_FUNCTION_PARAM_RX+")";
|
||||
const QString GROUP_FUNCTION_NAME_RX = "%1\\s*\\((.*[^\\)])\\)";
|
||||
const int SCENE_MARGIN = 50;
|
||||
}
|
||||
QString extractClassName(QString className);
|
||||
QString escapeSimbols(const QString& value);
|
||||
QString replaceHTMLSymbols(const QString &value);
|
||||
|
||||
enum ExpandType {EscapeSymbols, NoEscapeSymbols, ReplaceHTMLSymbols};
|
||||
enum RenderPass {FirstPass, SecondPass};
|
||||
enum ArrangeType {AsNeeded, Force};
|
||||
enum PreviewHint{ShowAllPreviewBars = 0,
|
||||
@ -100,6 +105,7 @@ namespace Const{
|
||||
HidePreviewStatusBar = 4,
|
||||
HideAllPreviewBar = 7,
|
||||
PreviewBarsUserSetting = 8};
|
||||
|
||||
Q_DECLARE_FLAGS(PreviewHints, PreviewHint)
|
||||
Q_FLAGS(PreviewHints)
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "lrdatasourcemanager.h"
|
||||
#include "lrbanddesignintf.h"
|
||||
#include "lritemdesignintf.h"
|
||||
#include "lrscriptenginemanager.h"
|
||||
|
||||
#include <QRegExp>
|
||||
|
||||
@ -38,23 +39,45 @@ namespace LimeReport {
|
||||
|
||||
void GroupFunction::slotBandRendered(BandDesignIntf *band)
|
||||
{
|
||||
ScriptEngineManager& sm = ScriptEngineManager::instance();
|
||||
|
||||
QRegExp rxField(Const::FIELD_RX);
|
||||
QRegExp rxVar(Const::VARIABLE_RX);
|
||||
|
||||
switch (m_dataType){
|
||||
case Field:
|
||||
if (m_dataManager->containsField(m_data)){
|
||||
m_values.push_back(m_dataManager->fieldData(m_data));
|
||||
if (rxField.indexIn(m_data) != -1){
|
||||
QString field = rxField.cap(1);
|
||||
if (m_dataManager->containsField(field)){
|
||||
m_values.push_back(m_dataManager->fieldData(field));
|
||||
} else {
|
||||
setInvalid(tr("Field \"%1\" not found").arg(m_data));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Variable:
|
||||
if (m_dataManager->containsVariable(m_data)){
|
||||
m_values.push_back(m_dataManager->variable(m_data));
|
||||
if (rxVar.indexIn(m_data) != -1){
|
||||
QString var = rxVar.cap(1);
|
||||
if (m_dataManager->containsVariable(var)){
|
||||
m_values.push_back(m_dataManager->variable(var));
|
||||
} else {
|
||||
setInvalid(tr("Variable \"%1\" not found").arg(m_data));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Script:
|
||||
{
|
||||
QVariant value = sm.evaluateScript(m_data);
|
||||
if (value.isValid()){
|
||||
m_values.push_back(value);
|
||||
} else {
|
||||
setInvalid(tr("Wrong script syntax \"%1\" ").arg(m_data));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ContentItem:{
|
||||
ContentItemDesignIntf* item = dynamic_cast<ContentItemDesignIntf*>(band->childByName(m_data));
|
||||
QString itemName = m_data;
|
||||
ContentItemDesignIntf* item = dynamic_cast<ContentItemDesignIntf*>(band->childByName(itemName.remove('"')));
|
||||
if (item)
|
||||
m_values.push_back(item->content());
|
||||
else if (m_name.compare("COUNT",Qt::CaseInsensitive) == 0) {
|
||||
@ -91,24 +114,27 @@ QVariant GroupFunction::multiplication(QVariant value1, QVariant value2)
|
||||
GroupFunction::GroupFunction(const QString &expression, const QString &dataBandName, DataSourceManager* dataManager)
|
||||
:m_dataBandName(dataBandName), m_dataManager(dataManager),m_isValid(true), m_errorMessage("")
|
||||
{
|
||||
m_data = expression;
|
||||
QRegExp rxField(Const::FIELD_RX,Qt::CaseInsensitive);
|
||||
if (rxField.indexIn(expression)>=0){
|
||||
m_dataType=Field;
|
||||
m_data = rxField.cap(1);
|
||||
QRegExp rxVariable(Const::VARIABLE_RX,Qt::CaseInsensitive);
|
||||
QRegExp rxScript(Const::SCRIPT_RX,Qt::CaseInsensitive);
|
||||
|
||||
if (rxScript.indexIn(expression) != -1){
|
||||
m_dataType = Script;
|
||||
return;
|
||||
}
|
||||
|
||||
QRegExp rxVariable(Const::VARIABLE_RX,Qt::CaseInsensitive);
|
||||
if (rxVariable.indexIn(expression)>=0){
|
||||
m_dataType=Variable;
|
||||
m_data = rxVariable.cap(1);
|
||||
if (rxField.indexIn(expression) != -1){
|
||||
m_dataType=Field;
|
||||
return;
|
||||
}
|
||||
|
||||
if (rxVariable.indexIn(expression) != -1){
|
||||
m_dataType = Variable;
|
||||
return;
|
||||
}
|
||||
|
||||
m_dataType = ContentItem;
|
||||
m_data = expression;
|
||||
m_data = m_data.remove('"');
|
||||
|
||||
}
|
||||
|
||||
GroupFunction *GroupFunctionFactory::createGroupFunction(const QString &functionName, const QString &expression, const QString& dataBandName, DataSourceManager *dataManager)
|
||||
|
@ -42,7 +42,7 @@ class BandDesignIntf;
|
||||
class GroupFunction : public QObject{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum DataType{Variable,Field,Srcipt,ContentItem};
|
||||
enum DataType{Variable, Field, Script, ContentItem};
|
||||
GroupFunction(const QString& expression, const QString& dataBandName, DataSourceManager *dataManager);
|
||||
bool isValid(){return m_isValid;}
|
||||
void setInvalid(QString message){m_isValid=false,m_errorMessage=message;}
|
||||
|
@ -60,7 +60,8 @@ ReportEnginePrivate::ReportEnginePrivate(QObject *parent) :
|
||||
m_showProgressDialog(true), m_reportName(""), m_activePreview(0),
|
||||
m_previewWindowIcon(":/report/images/logo32"), m_previewWindowTitle(tr("Preview")), m_reportRendering(false)
|
||||
{
|
||||
m_datasources= new DataSourceManager(this);
|
||||
m_datasources = new DataSourceManager(this);
|
||||
m_datasources->setReportSettings(&m_reportSettings);
|
||||
m_scriptEngineContext = new ScriptEngineContext(this);
|
||||
m_datasources->setObjectName("datasources");
|
||||
connect(m_datasources,SIGNAL(loadCollectionFinished(QString)),this,SLOT(slotDataSourceCollectionLoaded(QString)));
|
||||
|
@ -236,6 +236,7 @@ void ReportRender::renderPage(PageDesignIntf* patternPage)
|
||||
|
||||
try{
|
||||
datasources()->setAllDatasourcesToFirst();
|
||||
datasources()->clearGroupFuntionsExpressions();
|
||||
} catch(ReportError &exception){
|
||||
//TODO possible should thow exeption
|
||||
QMessageBox::critical(0,tr("Error"),exception.what());
|
||||
@ -277,7 +278,7 @@ int ReportRender::pageCount()
|
||||
|
||||
PageItemDesignIntf::Ptr ReportRender::pageAt(int index)
|
||||
{
|
||||
if ((index>m_renderedPages.count()-1)||(index<0)) throw ReportError("page index out of range");
|
||||
if ((index>m_renderedPages.count()-1)||(index<0)) throw ReportError(tr("page index out of range"));
|
||||
else return m_renderedPages.at(index);
|
||||
}
|
||||
|
||||
@ -368,7 +369,8 @@ void ReportRender::replaceGroupsFunction(BandDesignIntf *band)
|
||||
if (rx.indexIn(content)>=0){
|
||||
int pos = 0;
|
||||
while ( (pos = rx.indexIn(content,pos))!= -1 ){
|
||||
content.replace(rx.capturedTexts().at(0),QString("%1(%2,%3)").arg(functionName).arg('"'+rx.cap(Const::EXPRESSION_ARGUMENT_INDEX)+'"').arg('"'+band->objectName()+'"'));
|
||||
QString expressionIndex = datasources()->putGroupFunctionsExpressions(rx.cap(Const::VALUE_INDEX));
|
||||
content.replace(rx.capturedTexts().at(0),QString("%1(%2,%3)").arg(functionName).arg('"'+expressionIndex+'"').arg('"'+band->objectName()+'"'));
|
||||
pos += rx.matchedLength();
|
||||
}
|
||||
contentItem->setContent(content);
|
||||
|
@ -309,7 +309,7 @@ QScriptValue callGroupFunction(const QString& functionName, QScriptContext* pcon
|
||||
expression = " ";
|
||||
band = pcontext->argument(0).toString();
|
||||
} else {
|
||||
expression = pcontext->argument(0).toString();
|
||||
expression = dm->getExpression(pcontext->argument(0).toString());
|
||||
band = pcontext->argument(1).toString();
|
||||
}
|
||||
|
||||
@ -427,7 +427,7 @@ void ScriptEngineManager::setDataManager(DataSourceManager *dataManager){
|
||||
if (m_dataManager){
|
||||
foreach(QString func, m_dataManager->groupFunctionNames()){
|
||||
if (isFunctionExists(func)) deleteFunction(func);
|
||||
addFunction(func, groupFunction,"GROUP FUNCTIONS", func+"(\""+tr("FieldName")+"\",\""+tr("BandName")+"\")");
|
||||
addFunction(func, groupFunction,"GROUP FUNCTIONS", func+"(\""+tr("Value")+"\",\""+tr("BandName")+"\")");
|
||||
}
|
||||
foreach(ScriptFunctionDesc func, m_functions){
|
||||
if (func.type==ScriptFunctionDesc::Native)
|
||||
@ -437,6 +437,167 @@ void ScriptEngineManager::setDataManager(DataSourceManager *dataManager){
|
||||
}
|
||||
}
|
||||
|
||||
QString ScriptEngineManager::expandUserVariables(QString context, RenderPass pass, ExpandType expandType, QVariant &varValue)
|
||||
{
|
||||
QRegExp rx(Const::VARIABLE_RX);
|
||||
if (context.contains(rx)){
|
||||
int pos = 0;
|
||||
while ((pos = rx.indexIn(context,pos))!=-1){
|
||||
QString variable=rx.cap(1);
|
||||
pos += rx.matchedLength();
|
||||
if (dataManager()->containsVariable(variable) ){
|
||||
try {
|
||||
if (pass==dataManager()->variablePass(variable)){
|
||||
varValue = dataManager()->variable(variable);
|
||||
switch (expandType){
|
||||
case EscapeSymbols:
|
||||
context.replace(rx.cap(0),escapeSimbols(varValue.toString()));
|
||||
break;
|
||||
case NoEscapeSymbols:
|
||||
context.replace(rx.cap(0),varValue.toString());
|
||||
break;
|
||||
case ReplaceHTMLSymbols:
|
||||
context.replace(rx.cap(0),replaceHTMLSymbols(varValue.toString()));
|
||||
break;
|
||||
}
|
||||
pos=0;
|
||||
}
|
||||
} catch (ReportError e){
|
||||
dataManager()->putError(e.what());
|
||||
if (!dataManager()->reportSettings() || dataManager()->reportSettings()->suppressAbsentFieldsAndVarsWarnings())
|
||||
context.replace(rx.cap(0),e.what());
|
||||
else
|
||||
context.replace(rx.cap(0),"");
|
||||
}
|
||||
} else {
|
||||
QString error;
|
||||
error = tr("Variable %1 not found").arg(variable);
|
||||
dataManager()->putError(error);
|
||||
if (!dataManager()->reportSettings() || dataManager()->reportSettings()->suppressAbsentFieldsAndVarsWarnings())
|
||||
context.replace(rx.cap(0),error);
|
||||
else
|
||||
context.replace(rx.cap(0),"");
|
||||
}
|
||||
}
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
QString ScriptEngineManager::expandDataFields(QString context, ExpandType expandType, QVariant &varValue, QObject *reportItem)
|
||||
{
|
||||
QRegExp rx(Const::FIELD_RX);
|
||||
|
||||
if (context.contains(rx)){
|
||||
while ((rx.indexIn(context))!=-1){
|
||||
QString field=rx.cap(1);
|
||||
|
||||
if (dataManager()->containsField(field)) {
|
||||
QString fieldValue;
|
||||
varValue = dataManager()->fieldData(field);
|
||||
if (expandType == EscapeSymbols) {
|
||||
if (dataManager()->fieldData(field).isNull()) {
|
||||
fieldValue="\"\"";
|
||||
} else {
|
||||
fieldValue = escapeSimbols(varValue.toString());
|
||||
switch (dataManager()->fieldData(field).type()) {
|
||||
case QVariant::Char:
|
||||
case QVariant::String:
|
||||
case QVariant::StringList:
|
||||
case QVariant::Date:
|
||||
case QVariant::DateTime:
|
||||
fieldValue = "\""+fieldValue+"\"";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (expandType == ReplaceHTMLSymbols)
|
||||
fieldValue = replaceHTMLSymbols(varValue.toString());
|
||||
else fieldValue = varValue.toString();
|
||||
}
|
||||
|
||||
context.replace(rx.cap(0),fieldValue);
|
||||
|
||||
} else {
|
||||
QString error = QString("Field %1 not found in %2 !!! ").arg(field).arg(reportItem->objectName());
|
||||
dataManager()->putError(error);
|
||||
varValue = QVariant();
|
||||
if (!dataManager()->reportSettings() || !dataManager()->reportSettings()->suppressAbsentFieldsAndVarsWarnings())
|
||||
context.replace(rx.cap(0),error);
|
||||
else
|
||||
context.replace(rx.cap(0),"");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
QString ScriptEngineManager::expandScripts(QString context, QVariant& varValue, QObject *reportItem)
|
||||
{
|
||||
QRegExp rx(Const::SCRIPT_RX);
|
||||
|
||||
if (context.contains(rx)){
|
||||
|
||||
if (ScriptEngineManager::instance().dataManager()!=dataManager())
|
||||
ScriptEngineManager::instance().setDataManager(dataManager());
|
||||
|
||||
QScriptEngine* se = ScriptEngineManager::instance().scriptEngine();
|
||||
|
||||
if (reportItem){
|
||||
QScriptValue svThis = se->globalObject().property("THIS");
|
||||
if (svThis.isValid()){
|
||||
se->newQObject(svThis, this);
|
||||
} else {
|
||||
svThis = se->newQObject(this);
|
||||
se->globalObject().setProperty("THIS",svThis);
|
||||
}
|
||||
}
|
||||
|
||||
ScriptExtractor scriptExtractor(context);
|
||||
if (scriptExtractor.parse()){
|
||||
for(int i=0; i<scriptExtractor.count();++i){
|
||||
QString scriptBody = expandDataFields(scriptExtractor.bodyAt(i),EscapeSymbols, varValue, reportItem);
|
||||
scriptBody = expandUserVariables(scriptBody, FirstPass, EscapeSymbols, varValue);
|
||||
QScriptValue value = se->evaluate(scriptBody);
|
||||
if (!se->hasUncaughtException()) {
|
||||
varValue = value.toVariant();
|
||||
context.replace(scriptExtractor.scriptAt(i),value.toString());
|
||||
} else {
|
||||
context.replace(scriptExtractor.scriptAt(i),se->uncaughtException().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
QVariant ScriptEngineManager::evaluateScript(const QString& script){
|
||||
|
||||
QRegExp rx(Const::SCRIPT_RX);
|
||||
QVariant varValue;
|
||||
|
||||
if (script.contains(rx)){
|
||||
|
||||
if (ScriptEngineManager::instance().dataManager()!=dataManager())
|
||||
ScriptEngineManager::instance().setDataManager(dataManager());
|
||||
|
||||
QScriptEngine* se = ScriptEngineManager::instance().scriptEngine();
|
||||
|
||||
ScriptExtractor scriptExtractor(script);
|
||||
if (scriptExtractor.parse()){
|
||||
QString scriptBody = expandDataFields(scriptExtractor.bodyAt(0),EscapeSymbols, varValue, 0);
|
||||
scriptBody = expandUserVariables(scriptBody, FirstPass, EscapeSymbols, varValue);
|
||||
QScriptValue value = se->evaluate(scriptBody);
|
||||
if (!se->hasUncaughtException()) {
|
||||
return value.toVariant();
|
||||
}
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void ScriptEngineManager::updateModel()
|
||||
{
|
||||
|
||||
|
@ -190,6 +190,11 @@ public:
|
||||
DataSourceManager* dataManager() const {return m_dataManager;}
|
||||
void setDataManager(DataSourceManager* dataManager);
|
||||
|
||||
QString expandUserVariables(QString context, RenderPass pass, ExpandType expandType, QVariant &varValue);
|
||||
QString expandDataFields(QString context, ExpandType expandType, QVariant &varValue, QObject* reportItem);
|
||||
QString expandScripts(QString context, QVariant &varValue, QObject* reportItem);
|
||||
QVariant evaluateScript(const QString &script);
|
||||
|
||||
protected:
|
||||
void updateModel();
|
||||
bool containsFunction(const QString &functionName);
|
||||
|
Loading…
Reference in New Issue
Block a user