mirror of
https://github.com/fralx/LimeReport.git
synced 2024-12-25 00:54: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;
|
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
|
} //namespace LimeReport
|
||||||
|
@ -82,16 +82,21 @@ namespace Const{
|
|||||||
//const int DATASOURCE_INDEX = 6;
|
//const int DATASOURCE_INDEX = 6;
|
||||||
//const int VALUE_INDEX = 2;
|
//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 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 int DATASOURCE_INDEX = 4;
|
const QString GROUP_FUNCTION_PARAM_RX = "\\((?:(.+),|(?:))(?:\\\"(\\w+)\\\")\\)";
|
||||||
const int VALUE_INDEX = 2;
|
const int DATASOURCE_INDEX = 3;//4;
|
||||||
const int EXPRESSION_ARGUMENT_INDEX = 3;
|
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_RX = "(%1\\s*"+GROUP_FUNCTION_PARAM_RX+")";
|
||||||
const QString GROUP_FUNCTION_NAME_RX = "%1\\s*\\((.*[^\\)])\\)";
|
const QString GROUP_FUNCTION_NAME_RX = "%1\\s*\\((.*[^\\)])\\)";
|
||||||
const int SCENE_MARGIN = 50;
|
const int SCENE_MARGIN = 50;
|
||||||
}
|
}
|
||||||
QString extractClassName(QString className);
|
QString extractClassName(QString className);
|
||||||
|
QString escapeSimbols(const QString& value);
|
||||||
|
QString replaceHTMLSymbols(const QString &value);
|
||||||
|
|
||||||
|
enum ExpandType {EscapeSymbols, NoEscapeSymbols, ReplaceHTMLSymbols};
|
||||||
enum RenderPass {FirstPass, SecondPass};
|
enum RenderPass {FirstPass, SecondPass};
|
||||||
enum ArrangeType {AsNeeded, Force};
|
enum ArrangeType {AsNeeded, Force};
|
||||||
enum PreviewHint{ShowAllPreviewBars = 0,
|
enum PreviewHint{ShowAllPreviewBars = 0,
|
||||||
@ -100,6 +105,7 @@ namespace Const{
|
|||||||
HidePreviewStatusBar = 4,
|
HidePreviewStatusBar = 4,
|
||||||
HideAllPreviewBar = 7,
|
HideAllPreviewBar = 7,
|
||||||
PreviewBarsUserSetting = 8};
|
PreviewBarsUserSetting = 8};
|
||||||
|
|
||||||
Q_DECLARE_FLAGS(PreviewHints, PreviewHint)
|
Q_DECLARE_FLAGS(PreviewHints, PreviewHint)
|
||||||
Q_FLAGS(PreviewHints)
|
Q_FLAGS(PreviewHints)
|
||||||
|
|
||||||
|
@ -34,7 +34,6 @@
|
|||||||
#include "lrreportdesignwidget.h"
|
#include "lrreportdesignwidget.h"
|
||||||
#include "qgraphicsitem.h"
|
#include "qgraphicsitem.h"
|
||||||
#include "lrdesignelementsfactory.h"
|
#include "lrdesignelementsfactory.h"
|
||||||
|
|
||||||
#include "lrhorizontallayout.h"
|
#include "lrhorizontallayout.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -241,150 +240,29 @@ QFont BaseDesignIntf::transformToSceneFont(const QFont& value) const
|
|||||||
return f;
|
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)
|
QString BaseDesignIntf::expandDataFields(QString context, ExpandType expandType, DataSourceManager* dataManager)
|
||||||
{
|
{
|
||||||
QRegExp rx(Const::FIELD_RX);
|
ScriptEngineManager& sm = ScriptEngineManager::instance();
|
||||||
|
if (sm.dataManager() != dataManager) sm.setDataManager(dataManager);
|
||||||
if (context.contains(rx)){
|
return sm.expandDataFields(context, expandType, m_varValue, this);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString BaseDesignIntf::expandUserVariables(QString context, RenderPass pass, ExpandType expandType, DataSourceManager* dataManager)
|
QString BaseDesignIntf::expandUserVariables(QString context, RenderPass pass, ExpandType expandType, DataSourceManager* dataManager)
|
||||||
{
|
{
|
||||||
QRegExp rx(Const::VARIABLE_RX);
|
|
||||||
if (context.contains(rx)){
|
ScriptEngineManager& sm = ScriptEngineManager::instance();
|
||||||
int pos = 0;
|
if (sm.dataManager() != dataManager) sm.setDataManager(dataManager);
|
||||||
while ((pos = rx.indexIn(context,pos))!=-1){
|
return sm.expandUserVariables(context, pass, expandType, m_varValue);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString BaseDesignIntf::expandScripts(QString context, DataSourceManager* dataManager)
|
QString BaseDesignIntf::expandScripts(QString context, DataSourceManager* dataManager)
|
||||||
{
|
{
|
||||||
QRegExp rx(Const::SCRIPT_RX);
|
|
||||||
|
|
||||||
if (context.contains(rx)){
|
ScriptEngineManager& sm = ScriptEngineManager::instance();
|
||||||
ScriptEngineManager::instance().setDataManager(dataManager);
|
if (sm.dataManager() != dataManager) sm.setDataManager(dataManager);
|
||||||
QScriptEngine* se = ScriptEngineManager::instance().scriptEngine();
|
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
|
void BaseDesignIntf::setupPainter(QPainter *painter) const
|
||||||
|
@ -131,7 +131,7 @@ public:
|
|||||||
};
|
};
|
||||||
enum ObjectState {ObjectLoading, ObjectLoaded, ObjectCreated};
|
enum ObjectState {ObjectLoading, ObjectLoaded, ObjectCreated};
|
||||||
enum ItemAlign {LeftItemAlign,RightItemAlign,CenterItemAlign,ParentWidthItemAlign,DesignedItemAlign};
|
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(BorderLines, BorderSide)
|
||||||
Q_DECLARE_FLAGS(ItemMode,ItemModes)
|
Q_DECLARE_FLAGS(ItemMode,ItemModes)
|
||||||
friend class SelectionMarker;
|
friend class SelectionMarker;
|
||||||
@ -327,11 +327,9 @@ protected:
|
|||||||
virtual bool drawDesignBorders() const {return true;}
|
virtual bool drawDesignBorders() const {return true;}
|
||||||
virtual QColor selectionMarkerColor(){ return Const::SELECTION_COLOR;}
|
virtual QColor selectionMarkerColor(){ return Const::SELECTION_COLOR;}
|
||||||
|
|
||||||
QString escapeSimbols(const QString& value);
|
QString expandUserVariables(QString context, RenderPass pass, ExpandType expandType, DataSourceManager *dataManager);
|
||||||
QString replaceHTMLSymbols(const QString& value);
|
QString expandDataFields(QString context, ExpandType expandType, DataSourceManager *dataManager);
|
||||||
virtual QString expandUserVariables(QString context, RenderPass pass, ExpandType expandType, DataSourceManager *dataManager);
|
QString expandScripts(QString context, DataSourceManager *dataManager);
|
||||||
virtual QString expandDataFields(QString context, ExpandType expandType, DataSourceManager *dataManager);
|
|
||||||
virtual QString expandScripts(QString context, DataSourceManager *dataManager);
|
|
||||||
|
|
||||||
QVariant m_varValue;
|
QVariant m_varValue;
|
||||||
|
|
||||||
|
@ -238,6 +238,29 @@ void DataSourceManager::setDefaultDatabasePath(const QString &defaultDatabasePat
|
|||||||
{
|
{
|
||||||
m_defaultDatabasePath = defaultDatabasePath;
|
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
|
bool DataSourceManager::designTime() const
|
||||||
{
|
{
|
||||||
return m_designTime;
|
return m_designTime;
|
||||||
@ -702,6 +725,16 @@ bool DataSourceManager::initAndOpenDB(QSqlDatabase& db, ConnectionDesc& connecti
|
|||||||
return connected;
|
return connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReportSettings *DataSourceManager::reportSettings() const
|
||||||
|
{
|
||||||
|
return m_reportSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataSourceManager::setReportSettings(ReportSettings *reportSettings)
|
||||||
|
{
|
||||||
|
m_reportSettings = reportSettings;
|
||||||
|
}
|
||||||
|
|
||||||
bool DataSourceManager::connectConnection(ConnectionDesc *connectionDesc)
|
bool DataSourceManager::connectConnection(ConnectionDesc *connectionDesc)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -192,6 +192,13 @@ public:
|
|||||||
QString defaultDatabasePath() const;
|
QString defaultDatabasePath() const;
|
||||||
void setDefaultDatabasePath(const QString &defaultDatabasePath);
|
void setDefaultDatabasePath(const QString &defaultDatabasePath);
|
||||||
|
|
||||||
|
QString putGroupFunctionsExpressions(QString expression);
|
||||||
|
void clearGroupFuntionsExpressions();
|
||||||
|
QString getExpression(QString index);
|
||||||
|
|
||||||
|
ReportSettings *reportSettings() const;
|
||||||
|
void setReportSettings(ReportSettings *reportSettings);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void loadCollectionFinished(const QString& collectionName);
|
void loadCollectionFinished(const QString& collectionName);
|
||||||
void cleared();
|
void cleared();
|
||||||
@ -240,7 +247,13 @@ private:
|
|||||||
bool m_designTime;
|
bool m_designTime;
|
||||||
bool m_needUpdate;
|
bool m_needUpdate;
|
||||||
QString m_defaultDatabasePath;
|
QString m_defaultDatabasePath;
|
||||||
|
ReportSettings* m_reportSettings;
|
||||||
|
QHash<QString,int> m_groupFunctionsExpressionsMap;
|
||||||
|
QVector<QString> m_groupFunctionsExpressions;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif // LRDATASOURCEMANAGER_H
|
#endif // LRDATASOURCEMANAGER_H
|
||||||
|
|
||||||
|
@ -51,4 +51,20 @@ void ReportSettings::setSuppressAbsentFieldsAndVarsWarnings(bool suppressAbsentF
|
|||||||
m_suppressAbsentFieldsAndVarsWarnings = suppressAbsentFieldsAndVarsWarnings;
|
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
|
} //namespace LimeReport
|
||||||
|
@ -82,16 +82,21 @@ namespace Const{
|
|||||||
//const int DATASOURCE_INDEX = 6;
|
//const int DATASOURCE_INDEX = 6;
|
||||||
//const int VALUE_INDEX = 2;
|
//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 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 int DATASOURCE_INDEX = 4;
|
const QString GROUP_FUNCTION_PARAM_RX = "\\((?:(.+),|(?:))(?:\\\"(\\w+)\\\")\\)";
|
||||||
const int VALUE_INDEX = 2;
|
const int DATASOURCE_INDEX = 3;//4;
|
||||||
const int EXPRESSION_ARGUMENT_INDEX = 3;
|
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_RX = "(%1\\s*"+GROUP_FUNCTION_PARAM_RX+")";
|
||||||
const QString GROUP_FUNCTION_NAME_RX = "%1\\s*\\((.*[^\\)])\\)";
|
const QString GROUP_FUNCTION_NAME_RX = "%1\\s*\\((.*[^\\)])\\)";
|
||||||
const int SCENE_MARGIN = 50;
|
const int SCENE_MARGIN = 50;
|
||||||
}
|
}
|
||||||
QString extractClassName(QString className);
|
QString extractClassName(QString className);
|
||||||
|
QString escapeSimbols(const QString& value);
|
||||||
|
QString replaceHTMLSymbols(const QString &value);
|
||||||
|
|
||||||
|
enum ExpandType {EscapeSymbols, NoEscapeSymbols, ReplaceHTMLSymbols};
|
||||||
enum RenderPass {FirstPass, SecondPass};
|
enum RenderPass {FirstPass, SecondPass};
|
||||||
enum ArrangeType {AsNeeded, Force};
|
enum ArrangeType {AsNeeded, Force};
|
||||||
enum PreviewHint{ShowAllPreviewBars = 0,
|
enum PreviewHint{ShowAllPreviewBars = 0,
|
||||||
@ -100,6 +105,7 @@ namespace Const{
|
|||||||
HidePreviewStatusBar = 4,
|
HidePreviewStatusBar = 4,
|
||||||
HideAllPreviewBar = 7,
|
HideAllPreviewBar = 7,
|
||||||
PreviewBarsUserSetting = 8};
|
PreviewBarsUserSetting = 8};
|
||||||
|
|
||||||
Q_DECLARE_FLAGS(PreviewHints, PreviewHint)
|
Q_DECLARE_FLAGS(PreviewHints, PreviewHint)
|
||||||
Q_FLAGS(PreviewHints)
|
Q_FLAGS(PreviewHints)
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include "lrdatasourcemanager.h"
|
#include "lrdatasourcemanager.h"
|
||||||
#include "lrbanddesignintf.h"
|
#include "lrbanddesignintf.h"
|
||||||
#include "lritemdesignintf.h"
|
#include "lritemdesignintf.h"
|
||||||
|
#include "lrscriptenginemanager.h"
|
||||||
|
|
||||||
#include <QRegExp>
|
#include <QRegExp>
|
||||||
|
|
||||||
@ -38,23 +39,45 @@ namespace LimeReport {
|
|||||||
|
|
||||||
void GroupFunction::slotBandRendered(BandDesignIntf *band)
|
void GroupFunction::slotBandRendered(BandDesignIntf *band)
|
||||||
{
|
{
|
||||||
|
ScriptEngineManager& sm = ScriptEngineManager::instance();
|
||||||
|
|
||||||
|
QRegExp rxField(Const::FIELD_RX);
|
||||||
|
QRegExp rxVar(Const::VARIABLE_RX);
|
||||||
|
|
||||||
switch (m_dataType){
|
switch (m_dataType){
|
||||||
case Field:
|
case Field:
|
||||||
if (m_dataManager->containsField(m_data)){
|
if (rxField.indexIn(m_data) != -1){
|
||||||
m_values.push_back(m_dataManager->fieldData(m_data));
|
QString field = rxField.cap(1);
|
||||||
|
if (m_dataManager->containsField(field)){
|
||||||
|
m_values.push_back(m_dataManager->fieldData(field));
|
||||||
} else {
|
} else {
|
||||||
setInvalid(tr("Field \"%1\" not found").arg(m_data));
|
setInvalid(tr("Field \"%1\" not found").arg(m_data));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Variable:
|
case Variable:
|
||||||
if (m_dataManager->containsVariable(m_data)){
|
if (rxVar.indexIn(m_data) != -1){
|
||||||
m_values.push_back(m_dataManager->variable(m_data));
|
QString var = rxVar.cap(1);
|
||||||
|
if (m_dataManager->containsVariable(var)){
|
||||||
|
m_values.push_back(m_dataManager->variable(var));
|
||||||
} else {
|
} else {
|
||||||
setInvalid(tr("Variable \"%1\" not found").arg(m_data));
|
setInvalid(tr("Variable \"%1\" not found").arg(m_data));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
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:{
|
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)
|
if (item)
|
||||||
m_values.push_back(item->content());
|
m_values.push_back(item->content());
|
||||||
else if (m_name.compare("COUNT",Qt::CaseInsensitive) == 0) {
|
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)
|
GroupFunction::GroupFunction(const QString &expression, const QString &dataBandName, DataSourceManager* dataManager)
|
||||||
:m_dataBandName(dataBandName), m_dataManager(dataManager),m_isValid(true), m_errorMessage("")
|
:m_dataBandName(dataBandName), m_dataManager(dataManager),m_isValid(true), m_errorMessage("")
|
||||||
{
|
{
|
||||||
|
m_data = expression;
|
||||||
QRegExp rxField(Const::FIELD_RX,Qt::CaseInsensitive);
|
QRegExp rxField(Const::FIELD_RX,Qt::CaseInsensitive);
|
||||||
if (rxField.indexIn(expression)>=0){
|
QRegExp rxVariable(Const::VARIABLE_RX,Qt::CaseInsensitive);
|
||||||
m_dataType=Field;
|
QRegExp rxScript(Const::SCRIPT_RX,Qt::CaseInsensitive);
|
||||||
m_data = rxField.cap(1);
|
|
||||||
|
if (rxScript.indexIn(expression) != -1){
|
||||||
|
m_dataType = Script;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QRegExp rxVariable(Const::VARIABLE_RX,Qt::CaseInsensitive);
|
if (rxField.indexIn(expression) != -1){
|
||||||
if (rxVariable.indexIn(expression)>=0){
|
m_dataType=Field;
|
||||||
m_dataType=Variable;
|
return;
|
||||||
m_data = rxVariable.cap(1);
|
}
|
||||||
|
|
||||||
|
if (rxVariable.indexIn(expression) != -1){
|
||||||
|
m_dataType = Variable;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_dataType = ContentItem;
|
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)
|
GroupFunction *GroupFunctionFactory::createGroupFunction(const QString &functionName, const QString &expression, const QString& dataBandName, DataSourceManager *dataManager)
|
||||||
|
@ -42,7 +42,7 @@ class BandDesignIntf;
|
|||||||
class GroupFunction : public QObject{
|
class GroupFunction : public QObject{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
enum DataType{Variable,Field,Srcipt,ContentItem};
|
enum DataType{Variable, Field, Script, ContentItem};
|
||||||
GroupFunction(const QString& expression, const QString& dataBandName, DataSourceManager *dataManager);
|
GroupFunction(const QString& expression, const QString& dataBandName, DataSourceManager *dataManager);
|
||||||
bool isValid(){return m_isValid;}
|
bool isValid(){return m_isValid;}
|
||||||
void setInvalid(QString message){m_isValid=false,m_errorMessage=message;}
|
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_showProgressDialog(true), m_reportName(""), m_activePreview(0),
|
||||||
m_previewWindowIcon(":/report/images/logo32"), m_previewWindowTitle(tr("Preview")), m_reportRendering(false)
|
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_scriptEngineContext = new ScriptEngineContext(this);
|
||||||
m_datasources->setObjectName("datasources");
|
m_datasources->setObjectName("datasources");
|
||||||
connect(m_datasources,SIGNAL(loadCollectionFinished(QString)),this,SLOT(slotDataSourceCollectionLoaded(QString)));
|
connect(m_datasources,SIGNAL(loadCollectionFinished(QString)),this,SLOT(slotDataSourceCollectionLoaded(QString)));
|
||||||
|
@ -236,6 +236,7 @@ void ReportRender::renderPage(PageDesignIntf* patternPage)
|
|||||||
|
|
||||||
try{
|
try{
|
||||||
datasources()->setAllDatasourcesToFirst();
|
datasources()->setAllDatasourcesToFirst();
|
||||||
|
datasources()->clearGroupFuntionsExpressions();
|
||||||
} catch(ReportError &exception){
|
} catch(ReportError &exception){
|
||||||
//TODO possible should thow exeption
|
//TODO possible should thow exeption
|
||||||
QMessageBox::critical(0,tr("Error"),exception.what());
|
QMessageBox::critical(0,tr("Error"),exception.what());
|
||||||
@ -277,7 +278,7 @@ int ReportRender::pageCount()
|
|||||||
|
|
||||||
PageItemDesignIntf::Ptr ReportRender::pageAt(int index)
|
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);
|
else return m_renderedPages.at(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,7 +369,8 @@ void ReportRender::replaceGroupsFunction(BandDesignIntf *band)
|
|||||||
if (rx.indexIn(content)>=0){
|
if (rx.indexIn(content)>=0){
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
while ( (pos = rx.indexIn(content,pos))!= -1 ){
|
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();
|
pos += rx.matchedLength();
|
||||||
}
|
}
|
||||||
contentItem->setContent(content);
|
contentItem->setContent(content);
|
||||||
|
@ -309,7 +309,7 @@ QScriptValue callGroupFunction(const QString& functionName, QScriptContext* pcon
|
|||||||
expression = " ";
|
expression = " ";
|
||||||
band = pcontext->argument(0).toString();
|
band = pcontext->argument(0).toString();
|
||||||
} else {
|
} else {
|
||||||
expression = pcontext->argument(0).toString();
|
expression = dm->getExpression(pcontext->argument(0).toString());
|
||||||
band = pcontext->argument(1).toString();
|
band = pcontext->argument(1).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -427,7 +427,7 @@ void ScriptEngineManager::setDataManager(DataSourceManager *dataManager){
|
|||||||
if (m_dataManager){
|
if (m_dataManager){
|
||||||
foreach(QString func, m_dataManager->groupFunctionNames()){
|
foreach(QString func, m_dataManager->groupFunctionNames()){
|
||||||
if (isFunctionExists(func)) deleteFunction(func);
|
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){
|
foreach(ScriptFunctionDesc func, m_functions){
|
||||||
if (func.type==ScriptFunctionDesc::Native)
|
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()
|
void ScriptEngineManager::updateModel()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -190,6 +190,11 @@ public:
|
|||||||
DataSourceManager* dataManager() const {return m_dataManager;}
|
DataSourceManager* dataManager() const {return m_dataManager;}
|
||||||
void setDataManager(DataSourceManager* 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:
|
protected:
|
||||||
void updateModel();
|
void updateModel();
|
||||||
bool containsFunction(const QString &functionName);
|
bool containsFunction(const QString &functionName);
|
||||||
|
Loading…
Reference in New Issue
Block a user