diff --git a/.travis.yml b/.travis.yml
index b89e1f8..dadebf9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -10,7 +10,7 @@ env:
- QT_BASE=56
before_install:
- - if [ "$QT_BASE" = "56" ]; then sudo add-apt-repository ppa:beineri/opt-qt561-trusty -y; fi
+ - if [ "$QT_BASE" = "56" ]; then sudo add-apt-repository ppa:beineri/opt-qt562-trusty -y; fi
- sudo apt-get update -qq
install:
diff --git a/demo_r1/demo_reports/simple_group.lrxml b/demo_r1/demo_reports/simple_group.lrxml
new file mode 100644
index 0000000..e41daf7
--- /dev/null
+++ b/demo_r1/demo_reports/simple_group.lrxml
@@ -0,0 +1,636 @@
+
+
+
+
diff --git a/demo_r1/demo_reports/simple_list.lrxml b/demo_r1/demo_reports/simple_list.lrxml
new file mode 100644
index 0000000..8cdc401
--- /dev/null
+++ b/demo_r1/demo_reports/simple_list.lrxml
@@ -0,0 +1,521 @@
+
+
+
+
diff --git a/demo_r1/mainwindow.cpp b/demo_r1/mainwindow.cpp
index 0634a15..c459715 100644
--- a/demo_r1/mainwindow.cpp
+++ b/demo_r1/mainwindow.cpp
@@ -33,8 +33,8 @@
#include
#include
#include
-#include "lrreportengine.h"
-#include "lrcallbackdatasourceintf.h"
+#include
+#include
#include
#include
@@ -76,14 +76,16 @@ MainWindow::MainWindow(QWidget *parent) :
this, SLOT(slotGetCallbackData(LimeReport::CallbackInfo,QVariant&)));
connect(callbackDatasource, SIGNAL(changePos(const LimeReport::CallbackInfo::ChangePosType&,bool&)),
this, SLOT(slotChangePos(const LimeReport::CallbackInfo::ChangePosType&,bool&)));
- //report->dataManager()->addCallbackDatasource(callbackDatasource,"master");
callbackDatasource = report->dataManager()->createCallbackDatasouce("detail");
connect(callbackDatasource, SIGNAL(getCallbackData(LimeReport::CallbackInfo,QVariant&)),
this, SLOT(slotGetCallbackChildData(LimeReport::CallbackInfo,QVariant&)));
connect(callbackDatasource, SIGNAL(changePos(const LimeReport::CallbackInfo::ChangePosType&,bool&)),
this, SLOT(slotChangeChildPos(const LimeReport::CallbackInfo::ChangePosType&,bool&)));
- //report->dataManager()->addCallbackDatasource(callbackDatasource,"detail");
+
+ callbackDatasource = report->dataManager()->createCallbackDatasouce("oneSlotDS");
+ connect(callbackDatasource, SIGNAL(getCallbackData(LimeReport::CallbackInfo,QVariant&)),
+ this, SLOT(slotOneSlotDS(LimeReport::CallbackInfo,QVariant&)));
QStringList simpleData;
simpleData << "value1" << "value2" << "value3";
@@ -102,6 +104,8 @@ MainWindow::MainWindow(QWidget *parent) :
MainWindow::~MainWindow()
{
delete ui;
+ delete m_customers;
+ delete m_orders;
}
void MainWindow::on_pushButton_clicked()
@@ -208,3 +212,32 @@ void MainWindow::slotChangeChildPos(const LimeReport::CallbackInfo::ChangePosTyp
if (type == LimeReport::CallbackInfo::First) result = ds->first();
else result = ds->next();
}
+
+void MainWindow::slotOneSlotDS(LimeReport::CallbackInfo info, QVariant &data)
+{
+ QStringList columns;
+ columns << "Name" << "Value" << "Image";
+ switch (info.dataType) {
+ case LimeReport::CallbackInfo::RowCount:
+ data = 4;
+ break;
+ case LimeReport::CallbackInfo::ColumnCount:
+ data = columns.size();
+ break;
+// case LimeReport::CallbackInfo::IsEmpty:
+// data = false;
+// break;
+ case LimeReport::CallbackInfo::ColumnHeaderData: {
+ data = columns.at(info.index);
+ break;
+ }
+ case LimeReport::CallbackInfo::ColumnData:
+ if (info.columnName == "Image")
+ data = QImage(":/report//images/logo32");
+ else {
+ data = info.columnName+" "+QString::number(info.index);
+ }
+ break;
+ default: break;
+ }
+}
diff --git a/demo_r1/mainwindow.h b/demo_r1/mainwindow.h
index e5bbd32..e8d7ff1 100644
--- a/demo_r1/mainwindow.h
+++ b/demo_r1/mainwindow.h
@@ -57,6 +57,7 @@ private slots:
void slotChangePos(const LimeReport::CallbackInfo::ChangePosType& type, bool& result);
void slotGetCallbackChildData(LimeReport::CallbackInfo info, QVariant& data);
void slotChangeChildPos(const LimeReport::CallbackInfo::ChangePosType& type, bool& result);
+ void slotOneSlotDS(LimeReport::CallbackInfo info, QVariant& data);
private:
void prepareData(QSqlQuery* ds, LimeReport::CallbackInfo info, QVariant &data);
private:
diff --git a/demo_r2/mainwindow.cpp b/demo_r2/mainwindow.cpp
index 23c4d35..5ad3ac4 100644
--- a/demo_r2/mainwindow.cpp
+++ b/demo_r2/mainwindow.cpp
@@ -107,7 +107,6 @@ void MainWindow::slotPagesSet(int pagesCount)
void MainWindow::slotPageChanged(int page)
{
-// ui->sbPageNavigator->setValue(page);
m_pageNavigator->setValue(page);
}
@@ -118,8 +117,10 @@ void MainWindow::slotPageNavigatorChanged(int page)
void MainWindow::on_treeWidget_itemClicked(QTreeWidgetItem *item, int )
{
- m_report.loadFromFile(item->data(0,Qt::UserRole).toString());
- m_preview->refreshPages();
+ if (!m_report.isBusy()){
+ m_report.loadFromFile(item->data(0,Qt::UserRole).toString());
+ m_preview->refreshPages();
+ }
}
void MainWindow::initPercentCombobox()
diff --git a/designer/main.cpp b/designer/main.cpp
index 7d5084c..6ecf8ef 100644
--- a/designer/main.cpp
+++ b/designer/main.cpp
@@ -5,6 +5,9 @@ int main(int argc, char *argv[])
{
QApplication a(argc, argv);
LimeReport::ReportEngine report;
+ if (a.arguments().count()>1){
+ report.loadFromFile(a.arguments().at(1));
+ }
report.designReport();
return a.exec();
}
diff --git a/followTo.patch b/followTo.patch
new file mode 100644
index 0000000..966e2ae
--- /dev/null
+++ b/followTo.patch
@@ -0,0 +1,497 @@
+diff --git a/limereport/items/lrtextitem.cpp b/limereport/items/lrtextitem.cpp
+index 7d61562..041a737 100644
+--- a/limereport/items/lrtextitem.cpp
++++ b/limereport/items/lrtextitem.cpp
+@@ -31,6 +31,7 @@
+ #include
+ #include
+ #include
++#include
+ #include
+
+ #include "lrpagedesignintf.h"
+@@ -57,7 +58,7 @@ namespace LimeReport{
+
+ TextItem::TextItem(QObject *owner, QGraphicsItem *parent)
+ : ContentItemDesignIntf(xmlTag,owner,parent), m_angle(Angle0), m_trimValue(true), m_allowHTML(false),
+- m_allowHTMLInFields(false)
++ m_allowHTMLInFields(false), m_followTo(""), m_follower(0)
+ {
+ m_text = new QTextDocument();
+
+@@ -265,8 +266,13 @@ void TextItem::updateItemSize(DataSourceManager* dataManager, RenderPass pass, i
+ setWidth(m_textSize.width() + fakeMarginSize()*2);
+ }
+
+- if ((m_textSize.height()>height()) && (m_autoHeight) ){
+- setHeight(m_textSize.height()+borderLineSize()*2);
++ if (m_textSize.height()>height()) {
++ if (m_autoHeight)
++ setHeight(m_textSize.height()+borderLineSize()*2);
++ else if (hasFollower() && !content().isEmpty()){
++ follower()->setContent(getTextPart(0,height()));
++ setContent(getTextPart(height(),0));
++ }
+ }
+ BaseDesignIntf::updateItemSize(dataManager, pass, maxHeight);
+ }
+@@ -353,6 +359,7 @@ void TextItem::setLineSpacing(int value)
+
+ void TextItem::initText()
+ {
++ if (!m_text) return;
+ QTextOption to;
+ to.setAlignment(m_alignment);
+
+@@ -454,6 +461,66 @@ QString TextItem::formatFieldValue()
+ }
+ }
+
++QString TextItem::followTo() const
++{
++ return m_followTo;
++}
++
++void TextItem::setFollowTo(const QString &followTo)
++{
++ if (m_followTo != followTo){
++ QString oldValue = m_followTo;
++ m_followTo = followTo;
++ if (!isLoading()){
++ TextItem* fi = scene()->findChild(followTo);
++ if (fi && initFollower(followTo)){
++ notify("followTo",oldValue,followTo);
++ } else {
++ m_followTo = "";
++ QMessageBox::critical(
++ 0,
++ tr("Error"),
++ tr("TextItem \" %1 \" already has folower \" %2 \" ")
++ .arg(fi->objectName())
++ .arg(fi->follower()->objectName())
++ );
++ notify("followTo",followTo,"");
++ }
++ }
++ }
++}
++
++void TextItem::setFollower(TextItem *follower)
++{
++ if (!m_follower){
++ m_follower = follower;
++ }
++}
++
++bool TextItem::hasFollower()
++{
++ return m_follower != 0;
++}
++
++bool TextItem::initFollower(QString follower)
++{
++ TextItem* fi = scene()->findChild(follower);
++ if (fi){
++ if (!fi->hasFollower()){
++ fi->setFollower(this);
++ return true;
++ }
++ }
++ return false;
++}
++
++void TextItem::pageObjectHasBeenLoaded()
++{
++ if (!m_followTo.isEmpty()){
++ initFollower(m_followTo);
++ }
++}
++
+ TextItem::ValueType TextItem::valueType() const
+ {
+ return m_valueType;
+@@ -537,6 +604,7 @@ bool TextItem::isNeedUpdateSize(RenderPass pass) const
+ Q_UNUSED(pass)
+ bool res = (m_textSize.height()>geometry().height()&&autoHeight()) ||
+ (m_textSize.width()>geometry().width()&&autoWidth()) ||
++ m_follower ||
+ isNeedExpandContent();
+ return res;
+ }
+@@ -557,6 +625,7 @@ void TextItem::setAlignment(Qt::Alignment value)
+
+ void TextItem::expandContent(DataSourceManager* dataManager, RenderPass pass)
+ {
++
+ QString context=content();
+ ExpandType expandType = (allowHTML() && !allowHTMLInFields())?ReplaceHTMLSymbols:NoEscapeSymbols;
+ switch(pass){
+@@ -575,6 +644,7 @@ void TextItem::expandContent(DataSourceManager* dataManager, RenderPass pass)
+ } else {
+ setContent(context);
+ }
++
+ }
+
+ void TextItem::setAutoHeight(bool value)
+@@ -611,63 +681,79 @@ bool TextItem::canBeSplitted(int height) const
+ return height>(m_text->begin().layout()->lineAt(0).height());
+ }
+
+-BaseDesignIntf *TextItem::cloneUpperPart(int height, QObject *owner, QGraphicsItem *parent)
+-{
++QString TextItem::getTextPart(int height, int skipHeight){
+ int linesHeight=0;
+- QString tmpText="";
+- TextItem* upperPart = dynamic_cast(cloneItem(itemMode(),owner,parent));
++ int curLine=0;
++ int textPos=0;
+
+- for (QTextBlock it=m_text->begin();it!=m_text->end();it=it.next()){
+- for (int i=0;ilineCount();i++){
+- linesHeight+=it.layout()->lineAt(i).height()+lineSpacing();
+- if (linesHeight>(height-(fakeMarginSize()*2+borderLineSize()*2))) {
+- linesHeight-=it.layout()->lineAt(i).height();
+- goto loop_exit;
++ QTextBlock curBlock = m_text->begin();
++ QString resultText="";
++
++ if (skipHeight>0){
++ for (;curBlock!=m_text->end();curBlock=curBlock.next()){
++ for (curLine=0;curLinelineCount();curLine++){
++ linesHeight+=curBlock.layout()->lineAt(curLine).height()+lineSpacing();
++ if (linesHeight>(skipHeight-(/*fakeMarginSize()*2+*/borderLineSize()*2))) {goto loop_exit;}
++ }
++ }
++ loop_exit:;
++ }
++
++ linesHeight = 0;
++ qDebug()<end());
++ for (;curBlock!=m_text->end() || curLinelineCount();curLine++){
++ if (resultText=="") textPos= curBlock.layout()->lineAt(curLine).textStart();
++ linesHeight+=curBlock.layout()->lineAt(curLine).height()+lineSpacing();
++ if ( (height>0) && (linesHeight>(height-(/*fakeMarginSize()*2+*/borderLineSize()*2))) ) {
++ linesHeight-=curBlock.layout()->lineAt(curLine).height();
++ goto loop_exit1;
+ }
+- tmpText+=it.text().mid(it.layout()->lineAt(i).textStart(),it.layout()->lineAt(i).textLength())+'\n';
++ resultText+=curBlock.text().mid(curBlock.layout()->lineAt(curLine).textStart(),
++ curBlock.layout()->lineAt(curLine).textLength());
+ }
+ }
+- loop_exit:
+- tmpText.chop(1);
++ loop_exit1:;
++
++ resultText.chop(1);
+
+- upperPart->setHeight(linesHeight+fakeMarginSize()*2+borderLineSize()*2);
+ QScopedPointer context(new HtmlContext(m_strText));
+- upperPart->setContent(context->extendTextByTags(tmpText,0));
+- upperPart->initText();
+- return upperPart;
++ return context->extendTextByTags(resultText,textPos);
+ }
+
+-BaseDesignIntf *TextItem::cloneBottomPart(int height, QObject *owner, QGraphicsItem *parent)
++void TextItem::restoreLinksEvent()
+ {
+- TextItem* bottomPart = dynamic_cast(cloneItem(itemMode(),owner,parent));
+- int linesHeight=0;
+- int curLine=0;
+- QTextBlock curBlock;
+-
+- QString tmpText="";
+-
+- for (curBlock=m_text->begin();curBlock!=m_text->end();curBlock=curBlock.next()){
+- for (curLine=0;curLinelineCount();curLine++){
+- linesHeight+=curBlock.layout()->lineAt(curLine).height()+lineSpacing();
+- if (linesHeight>(height-(fakeMarginSize()*2+borderLineSize()*2))) {goto loop_exit;}
++ if (!followTo().isEmpty()){
++ BaseDesignIntf* pi = dynamic_cast(parentItem());
++ if (pi){
++ foreach (BaseDesignIntf* bi, pi->childBaseItems()) {
++ if (bi->patternName().compare(followTo())==0){
++ TextItem* ti = dynamic_cast(bi);
++ if (ti){
++ ti->setFollower(this);
++ }
++ }
++ }
+ }
+ }
+- loop_exit:;
++}
+
+- int textPos=0;
+- for (;curBlock!=m_text->end();curBlock=curBlock.next(),curLine=0){
+- for (;curLinelineCount();curLine++){
+- if (tmpText=="") textPos= curBlock.layout()->lineAt(curLine).textStart();
+- tmpText+=curBlock.text().mid(curBlock.layout()->lineAt(curLine).textStart(),
+- curBlock.layout()->lineAt(curLine).textLength()) + "\n";
+- }
+- }
+- tmpText.chop(1);
++BaseDesignIntf *TextItem::cloneUpperPart(int height, QObject *owner, QGraphicsItem *parent)
++{
++ TextItem* upperPart = dynamic_cast(cloneItem(itemMode(),owner,parent));
++ upperPart->setContent(getTextPart(height,0));
++ upperPart->initText();
++ upperPart->setHeight(upperPart->textSize().height()+borderLineSize()*2);
++ return upperPart;
++}
+
+- QScopedPointer context(new HtmlContext(m_strText));
+- bottomPart->setContent(context->extendTextByTags(tmpText,textPos));
++BaseDesignIntf *TextItem::cloneBottomPart(int height, QObject *owner, QGraphicsItem *parent)
++{
++ TextItem* bottomPart = dynamic_cast(cloneItem(itemMode(),owner,parent));
++ bottomPart->setContent(getTextPart(0,height));
+ bottomPart->initText();
+- bottomPart->setHeight(bottomPart->m_textSize.height()+borderLineSize()*2);
++ bottomPart->setHeight(bottomPart->textSize().height()+borderLineSize()*2);
+ return bottomPart;
+ }
+
+diff --git a/limereport/items/lrtextitem.h b/limereport/items/lrtextitem.h
+index 07c3412..bda15d8 100644
+--- a/limereport/items/lrtextitem.h
++++ b/limereport/items/lrtextitem.h
+@@ -32,15 +32,16 @@
+ #include
+ #include
+ #include
+-#include "lritemdesignintf.h"
+-#include
+-
+ #include
+
++#include "lritemdesignintf.h"
++#include "lritemdesignintf.h"
++#include "lrpageinitintf.h"
++
+ namespace LimeReport {
+
+ class Tag;
+-class TextItem : public LimeReport::ContentItemDesignIntf {
++class TextItem : public LimeReport::ContentItemDesignIntf, IPageInit {
+ Q_OBJECT
+ Q_ENUMS(AutoWidth)
+ Q_ENUMS(AngleType)
+@@ -66,6 +67,7 @@ class TextItem : public LimeReport::ContentItemDesignIntf {
+ Q_PROPERTY(bool allowHTMLInFields READ allowHTMLInFields WRITE setAllowHTMLInFields)
+ Q_PROPERTY(QString format READ format WRITE setFormat)
+ Q_PROPERTY(ValueType valueType READ valueType WRITE setValueType)
++ Q_PROPERTY(QString followTo READ followTo WRITE setFollowTo)
+ public:
+
+ enum AutoWidth{NoneAutoWidth,MaxWordLength,MaxStringLength};
+@@ -140,12 +142,25 @@ public:
+ ValueType valueType() const;
+ void setValueType(const ValueType valueType);
+
++ QSizeF textSize(){ return m_textSize;}
++ QString followTo() const;
++ void setFollowTo(const QString &followTo);
++ void setFollower(TextItem* follower);
++ bool hasFollower();
++ TextItem* follower(){ return m_follower;}
++ bool initFollower(QString follower);
++
++ // IPageInit interface
++ void pageObjectHasBeenLoaded();
++
+ protected:
+ void updateLayout();
+ bool isNeedExpandContent() const;
+ QString replaceBR(QString text);
+ QString replaceReturns(QString text);
+ int fakeMarginSize();
++ QString getTextPart(int height, int skipHeight);
++ void restoreLinksEvent();
+ private:
+ void initText();
+ void setTextFont(const QFont &value);
+@@ -174,6 +189,8 @@ private:
+
+ QString m_format;
+ ValueType m_valueType;
++ QString m_followTo;
++ TextItem* m_follower;
+ };
+
+ }
+diff --git a/limereport/lrbanddesignintf.cpp b/limereport/lrbanddesignintf.cpp
+index a55f74c..c7b3dcc 100644
+--- a/limereport/lrbanddesignintf.cpp
++++ b/limereport/lrbanddesignintf.cpp
+@@ -889,6 +889,7 @@ void BandDesignIntf::updateItemSize(DataSourceManager* dataManager, RenderPass p
+ if (borderLines()!=0){
+ spaceBorder += borderLineSize();
+ }
++ restoreLinks();
+ snapshotItemsLayout();
+ arrangeSubItems(pass, dataManager);
+ if (autoHeight()){
+diff --git a/limereport/lrbasedesignintf.cpp b/limereport/lrbasedesignintf.cpp
+index 8b632d5..a901997 100644
+--- a/limereport/lrbasedesignintf.cpp
++++ b/limereport/lrbasedesignintf.cpp
+@@ -76,7 +76,8 @@ BaseDesignIntf::BaseDesignIntf(const QString &storageTypeName, QObject *owner, Q
+ m_itemAlign(DesignedItemAlign),
+ m_changingItemAlign(false),
+ m_borderColor(Qt::black),
+- m_reportSettings(0)
++ m_reportSettings(0),
++ m_patternName("")
+ {
+ setGeometry(QRectF(0, 0, m_width, m_height));
+ if (BaseDesignIntf *item = dynamic_cast(parent)) {
+@@ -672,6 +673,16 @@ void BaseDesignIntf::turnOnSelectionMarker(bool value)
+ }
+ }
+
++QString BaseDesignIntf::patternName() const
++{
++ return m_patternName;
++}
++
++void BaseDesignIntf::setPatternName(const QString &patternName)
++{
++ m_patternName = patternName;
++}
++
+ ReportSettings *BaseDesignIntf::reportSettings() const
+ {
+ return m_reportSettings;
+@@ -737,7 +748,7 @@ void BaseDesignIntf::emitObjectNamePropertyChanged(const QString &oldName, const
+
+ int BaseDesignIntf::borderLineSize() const
+ {
+- return m_borderLineSize;
++ return 0 /*m_borderLineSize*/;
+ }
+
+ void BaseDesignIntf::setBorderLineSize(int value)
+@@ -987,6 +998,19 @@ void BaseDesignIntf::parentChangedEvent(BaseDesignIntf *)
+
+ }
+
++void BaseDesignIntf::restoreLinks()
++{
++#ifdef HAVE_QT5
++ foreach(QObject * child, children()) {
++#else
++ foreach(QObject * child, QObject::children()) {
++#endif
++ BaseDesignIntf *childItem = dynamic_cast(child);
++ if (childItem) {childItem->restoreLinks();}
++ }
++ restoreLinksEvent();
++}
++
+ QPainterPath BaseDesignIntf::shape() const
+ {
+ QPainterPath path;
+@@ -1229,6 +1253,7 @@ void BaseDesignIntf::collectionLoadFinished(const QString &collectionName)
+ BaseDesignIntf *BaseDesignIntf::cloneItem(ItemMode mode, QObject *owner, QGraphicsItem *parent)
+ {
+ BaseDesignIntf *clone = cloneItemWOChild(mode, owner, parent);
++ clone->setPatternName(this->objectName());
+ #ifdef HAVE_QT5
+ foreach(QObject * child, children()) {
+ #else
+diff --git a/limereport/lrbasedesignintf.h b/limereport/lrbasedesignintf.h
+index f31bf73..dae9cf4 100644
+--- a/limereport/lrbasedesignintf.h
++++ b/limereport/lrbasedesignintf.h
+@@ -249,6 +249,8 @@ public:
+ ReportSettings* reportSettings() const;
+ void setReportSettings(ReportSettings *reportSettings);
+ void setZValueProperty(qreal value);
++ QString patternName() const;
++ void setPatternName(const QString &patternName);
+
+ Q_INVOKABLE QString setItemWidth(qreal width);
+ Q_INVOKABLE QString setItemHeight(qreal height);
+@@ -258,6 +260,7 @@ public:
+ Q_INVOKABLE qreal getItemPosY();
+ Q_INVOKABLE QString setItemPosX(qreal xValue);
+ Q_INVOKABLE QString setItemPosY(qreal yValue);
++
+ protected:
+
+ //ICollectionContainer
+@@ -283,6 +286,8 @@ protected:
+ virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+ virtual void childAddedEvent(BaseDesignIntf* child);
+ virtual void parentChangedEvent(BaseDesignIntf*);
++ void restoreLinks();
++ virtual void restoreLinksEvent(){}
+
+ void drawTopLine(QPainter *painter, QRectF rect) const;
+ void drawBootomLine(QPainter *painter, QRectF rect) const;
+@@ -359,6 +364,7 @@ private:
+ bool m_changingItemAlign;
+ QColor m_borderColor;
+ ReportSettings* m_reportSettings;
++ QString m_patternName;
+ signals:
+ void geometryChanged(QObject* object, QRectF newGeometry, QRectF oldGeometry);
+ void posChanged(QObject* object, QPointF newPos, QPointF oldPos);
+diff --git a/limereport/lrreportrender.cpp b/limereport/lrreportrender.cpp
+index 42dacef..3d39635 100644
+--- a/limereport/lrreportrender.cpp
++++ b/limereport/lrreportrender.cpp
+@@ -204,7 +204,6 @@ void ReportRender::renderPage(PageDesignIntf* patternPage)
+ resetPageNumber(PageReset);
+
+ }
+- //m_pageCount = 1;
+ m_renderCanceled = false;
+ BandDesignIntf* reportFooter = m_patternPageItem->bandByType(BandDesignIntf::ReportFooter);
+ m_reportFooterHeight = 0;
+@@ -225,9 +224,7 @@ void ReportRender::renderPage(PageDesignIntf* patternPage)
+ QMessageBox::critical(0,tr("Error"),exception.what());
+ return;
+ }
+-
+ clearPageMap();
+-
+ startNewPage();
+
+ renderBand(m_patternPageItem->bandByType(BandDesignIntf::ReportHeader),StartNewPageAsNeeded);
+@@ -543,15 +540,21 @@ void ReportRender::renderPageFooter(PageItemDesignIntf *patternPage)
+
+ void ReportRender::renderPageItems(PageItemDesignIntf* patternPage)
+ {
++ QList pageItems;
+ foreach (BaseDesignIntf* item, patternPage->childBaseItems()) {
+ ItemDesignIntf* id = dynamic_cast(item);
+ if (id&&id->itemLocation()==ItemDesignIntf::Page){
+ BaseDesignIntf* cloneItem = item->cloneItem(m_renderPageItem->itemMode(),
+ m_renderPageItem,
+ m_renderPageItem);
+- cloneItem->updateItemSize(m_datasources);
++ pageItems.append(cloneItem);
++ //cloneItem->updateItemSize(m_datasources);
+ }
+ }
++ m_renderPageItem->restoreLinks();
++ foreach(BaseDesignIntf* item, pageItems){
++ item->updateItemSize(m_datasources);
++ }
+ }
+
+ qreal ReportRender::calcPageFooterHeight(PageItemDesignIntf *patternPage)
+@@ -978,7 +981,6 @@ void ReportRender::startNewPage()
+ renderBand(band);
+ }
+ checkLostHeadersOnPrevPage();
+-
+ pasteGroups();
+ renderPageItems(m_patternPageItem);
+ }
diff --git a/include/lrglobal.cpp b/include/lrglobal.cpp
index 47b31f0..5b2cdff 100644
--- a/include/lrglobal.cpp
+++ b/include/lrglobal.cpp
@@ -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
diff --git a/include/lrglobal.h b/include/lrglobal.h
index ea1d3ce..82a0364 100644
--- a/include/lrglobal.h
+++ b/include/lrglobal.h
@@ -83,15 +83,27 @@ namespace Const{
const QString FIELD_RX = "\\$D\\s*\\{\\s*([^{}]*)\\s*\\}";
const QString VARIABLE_RX = "\\$V\\s*\\{\\s*([^{}]*)\\s*\\}";
const QString SCRIPT_RX = "\\$S\\s*\\{(.*)\\}";
- const QString GROUP_FUNCTION_PARAM_RX = "\\(\\s*(((?:\\\"?\\$D\\s*\\{\\s*)|(?:\\\"?\\$V\\s*\\{\\s*)|(?:\\\"))(\\w+\\.?\\w+)((?:\\\")|(?:\\s*\\}\\\"?\\s*)))\\s*,\\s*\\\"(\\w+)\\\"\\s*\\)";
- 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+)((?:\\\")|(?:\\s*\\}\\\"?\\s*)))\\s*,\\s*\\\"(\\w+)\\\"\\s*\\)";
+ //const int DATASOURCE_INDEX = 6;
+ //const int VALUE_INDEX = 2;
+
+ //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;
const QString FUNCTION_MANAGER_NAME = "LimeReport";
}
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 +112,7 @@ namespace Const{
HidePreviewStatusBar = 4,
HideAllPreviewBar = 7,
PreviewBarsUserSetting = 8};
+
Q_DECLARE_FLAGS(PreviewHints, PreviewHint)
Q_FLAGS(PreviewHints)
diff --git a/include/lrreportengine.h b/include/lrreportengine.h
index 804e764..a07d519 100644
--- a/include/lrreportengine.h
+++ b/include/lrreportengine.h
@@ -99,6 +99,9 @@ public:
PreviewReportWidget *createPreviewWidget(QWidget *parent = 0);
void setPreviewWindowTitle(const QString& title);
void setPreviewWindowIcon(const QIcon& icon);
+ void setResultEditable(bool value);
+ bool resultIsEditable();
+ bool isBusy();
signals:
void renderStarted();
void renderFinished();
diff --git a/limereport.pri b/limereport.pri
new file mode 100644
index 0000000..a7f272f
--- /dev/null
+++ b/limereport.pri
@@ -0,0 +1,5 @@
+CONFIG += zint
+include(./limereport/limereport.pri)
+contains(CONFIG, zint){
+ include(./qzint.pri)
+}
diff --git a/limereport/LRCallbackDS b/limereport/LRCallbackDS
new file mode 100644
index 0000000..fd5f8c4
--- /dev/null
+++ b/limereport/LRCallbackDS
@@ -0,0 +1 @@
+#include "lrcallbackdatasourceintf.h"
\ No newline at end of file
diff --git a/limereport/LRDataManager b/limereport/LRDataManager
new file mode 100644
index 0000000..720a2ed
--- /dev/null
+++ b/limereport/LRDataManager
@@ -0,0 +1 @@
+#include "lrdatasourcemanagerintf.h"
\ No newline at end of file
diff --git a/limereport/LRScriptManager b/limereport/LRScriptManager
new file mode 100644
index 0000000..05ab2f8
--- /dev/null
+++ b/limereport/LRScriptManager
@@ -0,0 +1 @@
+#include "lrscriptenginemanagerintf.h"
\ No newline at end of file
diff --git a/limereport/LimeReport b/limereport/LimeReport
new file mode 100644
index 0000000..037cf8c
--- /dev/null
+++ b/limereport/LimeReport
@@ -0,0 +1 @@
+#include "lrreportengine.h"
diff --git a/limereport/bands/lrgroupbands.cpp b/limereport/bands/lrgroupbands.cpp
index 965982b..74b55eb 100644
--- a/limereport/bands/lrgroupbands.cpp
+++ b/limereport/bands/lrgroupbands.cpp
@@ -31,7 +31,6 @@
#include "lrglobal.h"
#include "lrdatasourcemanager.h"
-
const QString xmlTagHeader = QLatin1String("GroupHeader");
const QString xmlTagFooter = QLatin1String("GroupFooter");
@@ -98,6 +97,8 @@ void GroupBandHeader::startGroup(DataSourceManager* dataManager)
if (ds && ds->columnIndexByName(m_groupFiledName)!=-1)
m_groupFieldValue=ds->data(m_groupFiledName);
}
+
+ if (!m_condition.isEmpty()) m_conditionValue = calcCondition(dataManager);
}
QColor GroupBandHeader::bandColor() const
@@ -114,20 +115,47 @@ QString GroupBandHeader::findDataSourceName(BandDesignIntf* parentBand){
}
+QString GroupBandHeader::condition() const
+{
+ return m_condition;
+}
+
+void GroupBandHeader::setCondition(const QString &condition)
+{
+ m_condition = condition;
+}
+
+QString GroupBandHeader::calcCondition(DataSourceManager* dataManager){
+ QString result = m_condition;
+ if (!m_condition.isEmpty()){
+ result=expandUserVariables(result, FirstPass, NoEscapeSymbols, dataManager);
+ result=expandScripts(result, dataManager);
+ result=expandDataFields(result, NoEscapeSymbols, dataManager);
+ }
+ return result;
+}
+
bool GroupBandHeader::isNeedToClose(DataSourceManager* dataManager)
{
if (!m_groupStarted) return false;
- if (m_groupFiledName.isNull() || m_groupFiledName.isEmpty())
+ if ((m_groupFiledName.isNull() || m_groupFiledName.isEmpty()) && condition().isEmpty()){
dataManager->putError(tr("Group field not found"));
- QString datasourceName = findDataSourceName(parentBand());
- if (dataManager->containsDatasource(datasourceName)){
- IDataSource* ds = dataManager->dataSource(datasourceName);
- if (ds){
- if (ds->data(m_groupFiledName).isNull() && m_groupFieldValue.isNull()) return false;
- return ds->data(m_groupFiledName)!=m_groupFieldValue;
- }
+ return false;
+ }
+
+ if (!m_condition.isEmpty()){
+ return m_conditionValue != calcCondition(dataManager);
} else {
- dataManager->putError(tr("Datasource \"%1\" not found !!!").arg(datasourceName));
+ QString datasourceName = findDataSourceName(parentBand());
+ if (dataManager->containsDatasource(datasourceName)){
+ IDataSource* ds = dataManager->dataSource(datasourceName);
+ if (ds){
+ if (ds->data(m_groupFiledName).isNull() && m_groupFieldValue.isNull()) return false;
+ return ds->data(m_groupFiledName)!=m_groupFieldValue;
+ }
+ } else {
+ dataManager->putError(tr("Datasource \"%1\" not found !!!").arg(datasourceName));
+ }
}
return false;
@@ -141,6 +169,7 @@ bool GroupBandHeader::isStarted()
void GroupBandHeader::closeGroup()
{
m_groupFieldValue=QVariant();
+ m_conditionValue="";
m_groupStarted=false;
}
diff --git a/limereport/bands/lrgroupbands.h b/limereport/bands/lrgroupbands.h
index 9fa3eaa..42285d8 100644
--- a/limereport/bands/lrgroupbands.h
+++ b/limereport/bands/lrgroupbands.h
@@ -43,6 +43,7 @@ class GroupBandHeader : public BandDesignIntf, public IGroupBand{
Q_PROPERTY(bool startNewPage READ startNewPage WRITE setStartNewPage)
Q_PROPERTY(bool resetPageNumber READ resetPageNumber WRITE setResetPageNumber)
Q_PROPERTY(bool reprintOnEachPage READ reprintOnEachPage WRITE setReprintOnEachPage)
+ Q_PROPERTY(QString condition READ condition WRITE setCondition)
public:
GroupBandHeader(QObject* owner = 0, QGraphicsItem* parent=0);
virtual bool isUnique() const;
@@ -57,6 +58,8 @@ public:
void setResetPageNumber(bool resetPageNumber);
bool isHeader() const{return true;}
bool isGroupHeader() const {return true;}
+ QString condition() const;
+ void setCondition(const QString &condition);
private:
virtual BaseDesignIntf* createSameTypeItem(QObject* owner=0, QGraphicsItem* parent=0);
void startGroup(DataSourceManager* dataManager);
@@ -65,12 +68,15 @@ private:
void closeGroup();
int index();
QString findDataSourceName(BandDesignIntf *parentBand);
+ QString calcCondition(DataSourceManager *dataManager);
private:
QVariant m_groupFieldValue;
QString m_groupFiledName;
bool m_groupStarted;
//bool m_startNewPage;
bool m_resetPageNumber;
+ QString m_condition;
+ QString m_conditionValue;
};
class GroupBandFooter : public BandDesignIntf{
diff --git a/limereport/items/lrimageitem.cpp b/limereport/items/lrimageitem.cpp
index a8e255e..ede6a1f 100644
--- a/limereport/items/lrimageitem.cpp
+++ b/limereport/items/lrimageitem.cpp
@@ -56,16 +56,21 @@ BaseDesignIntf *ImageItem::createSameTypeItem(QObject *owner, QGraphicsItem *par
void ImageItem::updateItemSize(DataSourceManager* dataManager, RenderPass pass, int maxHeight)
{
- if (!m_datasource.isEmpty() && !m_field.isEmpty() && m_picture.isNull()){
- IDataSource* ds = dataManager->dataSource(m_datasource);
- if (ds) {
- QVariant data = ds->data(m_field);
- if (data.isValid()){
- if (data.type()==QVariant::Image){
- m_picture = data.value();
- } else
- m_picture.loadFromData(data.toByteArray());
- }
+
+ if (m_picture.isNull()){
+ if (!m_datasource.isEmpty() && !m_field.isEmpty()){
+ IDataSource* ds = dataManager->dataSource(m_datasource);
+ if (ds) {
+ QVariant data = ds->data(m_field);
+ if (data.isValid()){
+ if (data.type()==QVariant::Image){
+ m_picture = data.value();
+ } else
+ m_picture.loadFromData(data.toByteArray());
+ }
+ }
+ } else if (!m_resourcePath.isEmpty()){
+ m_picture = QImage(m_resourcePath);
}
}
if (m_autoSize){
@@ -80,6 +85,11 @@ bool ImageItem::isNeedUpdateSize(RenderPass) const
return m_picture.isNull() || m_autoSize;
}
+QString ImageItem::resourcePath() const
+{
+ return m_resourcePath;
+}
+
qreal ImageItem::minHeight() const{
if (!m_picture.isNull() && autoSize())
{
@@ -231,6 +241,7 @@ void ImageItem::paint(QPainter *ppainter, const QStyleOptionGraphicsItem *option
if (img.isNull() && itemMode()==DesignMode){
QString text;
ppainter->setFont(transformToSceneFont(QFont("Arial",10)));
+ ppainter->setPen(Qt::black);
if (!datasource().isEmpty() && !field().isEmpty())
text = datasource()+"."+field();
else text = tr("Image");
diff --git a/limereport/items/lrimageitem.h b/limereport/items/lrimageitem.h
index 4e3fa23..631f292 100644
--- a/limereport/items/lrimageitem.h
+++ b/limereport/items/lrimageitem.h
@@ -44,12 +44,14 @@ class ImageItem : public LimeReport::ItemDesignIntf
Q_PROPERTY(bool scale READ scale WRITE setScale)
Q_PROPERTY(bool keepAspectRatio READ keepAspectRatio WRITE setKeepAspectRatio)
Q_PROPERTY(bool center READ center WRITE setCenter)
+ Q_PROPERTY(QString resourcePath READ resourcePath WRITE setResourcePath)
public:
ImageItem(QObject *owner, QGraphicsItem *parent);
virtual void paint(QPainter *ppainter, const QStyleOptionGraphicsItem *option, QWidget *widget);
void setImage(QImage value);
QImage image(){return m_picture;}
- void setContent(const QString &value){m_content=value;}
+ void setResourcePath(const QString &value){m_resourcePath=value;}
+ QString resourcePath() const;
QString datasource() const;
void setDatasource(const QString &datasource);
QString field() const;
@@ -72,8 +74,8 @@ protected:
bool isNeedUpdateSize(RenderPass) const;
bool drawDesignBorders() const {return m_picture.isNull();}
private:
- QImage m_picture;
- QString m_content;
+ QImage m_picture;
+ QString m_resourcePath;
QString m_datasource;
QString m_field;
bool m_autoSize;
diff --git a/limereport/items/lrshapeitem.cpp b/limereport/items/lrshapeitem.cpp
index f52b1c8..a1b37d9 100644
--- a/limereport/items/lrshapeitem.cpp
+++ b/limereport/items/lrshapeitem.cpp
@@ -85,7 +85,7 @@ void ShapeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
pen.setStyle(m_penStyle);
painter->setPen(pen);
QBrush brush(m_shapeBrushColor,m_shapeBrushType);
-
+ brush.setTransform(painter->worldTransform().inverted());
painter->setBrush(brush);
painter->setBackground(QBrush(Qt::NoBrush));
painter->setOpacity(qreal(m_opacity)/100);
diff --git a/limereport/items/lrtextitem.cpp b/limereport/items/lrtextitem.cpp
index 421675d..cddcfee 100644
--- a/limereport/items/lrtextitem.cpp
+++ b/limereport/items/lrtextitem.cpp
@@ -31,6 +31,7 @@
#include
#include
#include
+#include
#include
#include "lrpagedesignintf.h"
@@ -57,10 +58,8 @@ namespace LimeReport{
TextItem::TextItem(QObject *owner, QGraphicsItem *parent)
: ContentItemDesignIntf(xmlTag,owner,parent), m_angle(Angle0), m_trimValue(true), m_allowHTML(false),
- m_allowHTMLInFields(false)
+ m_allowHTMLInFields(false), m_followTo(""), m_follower(0), m_textIndent(0), m_textLayoutDirection(Qt::LayoutDirectionAuto)
{
- m_text = new QTextDocument();
-
PageItemDesignIntf* pageItem = dynamic_cast(parent);
BaseDesignIntf* parentItem = dynamic_cast(parent);
while (!pageItem && parentItem){
@@ -75,12 +74,9 @@ TextItem::TextItem(QObject *owner, QGraphicsItem *parent)
Init();
}
-TextItem::~TextItem()
-{
- delete m_text;
-}
+TextItem::~TextItem(){}
-int TextItem::fakeMarginSize(){
+int TextItem::fakeMarginSize() const{
return marginSize()+5;
}
@@ -88,12 +84,15 @@ void TextItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* style, Q
Q_UNUSED(widget);
Q_UNUSED(style);
+
+ TextPtr text = textDocument();
+
painter->save();
setupPainter(painter);
prepareRect(painter,style,widget);
- QSizeF tmpSize = rect().size()-m_textSize;
+ QSizeF tmpSize = rect().size()-text->size();
if (!painter->clipRegion().isEmpty()){
QRegion clipReg=painter->clipRegion().xored(painter->clipRegion().subtracted(rect().toRect()));
@@ -102,38 +101,38 @@ void TextItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* style, Q
painter->setClipRect(rect());
}
- qreal hOffset = 0, vOffset=0;
+ qreal hOffset = 0, vOffset = 0;
switch (m_angle){
case Angle0:
hOffset = fakeMarginSize();
- if ((tmpSize.height()>0) && (m_alignment & Qt::AlignVCenter)){
- vOffset = tmpSize.height()/2;
+ if ((tmpSize.height() > 0) && (m_alignment & Qt::AlignVCenter)){
+ vOffset = tmpSize.height() / 2;
}
- if ((tmpSize.height()>0) && (m_alignment & Qt::AlignBottom)) // allow html
+ if ((tmpSize.height() > 0) && (m_alignment & Qt::AlignBottom)) // allow html
vOffset = tmpSize.height();
painter->translate(hOffset,vOffset);
break;
case Angle90:
- hOffset = width()-fakeMarginSize();
+ hOffset = width() - fakeMarginSize();
vOffset = fakeMarginSize();
if (m_alignment & Qt::AlignVCenter){
- hOffset = (width()-m_text->size().height())/2+m_text->size().height();
+ hOffset = (width() - text->size().height()) / 2 + text->size().height();
}
if (m_alignment & Qt::AlignBottom){
- hOffset = (m_text->size().height());
+ hOffset = (text->size().height());
}
painter->translate(hOffset,vOffset);
painter->rotate(90);
break;
case Angle180:
- hOffset = width()-fakeMarginSize();
- vOffset = height()-fakeMarginSize();
+ hOffset = width() - fakeMarginSize();
+ vOffset = height() - fakeMarginSize();
if ((tmpSize.width()>0) && (m_alignment & Qt::AlignVCenter)){
- vOffset = tmpSize.height()/2+m_text->size().height();
+ vOffset = tmpSize.height() / 2+ text->size().height();
}
if ((tmpSize.height()>0) && (m_alignment & Qt::AlignBottom)){
- vOffset = (m_text->size().height());
+ vOffset = (text->size().height());
}
painter->translate(hOffset,vOffset);
painter->rotate(180);
@@ -142,11 +141,11 @@ void TextItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* style, Q
hOffset = fakeMarginSize();
vOffset = height()-fakeMarginSize();
if (m_alignment & Qt::AlignVCenter){
- hOffset = (width()-m_text->size().height())/2;
+ hOffset = (width() - text->size().height())/2;
}
if (m_alignment & Qt::AlignBottom){
- hOffset = (width()-m_text->size().height());
+ hOffset = (width() - text->size().height());
}
painter->translate(hOffset,vOffset);
painter->rotate(270);
@@ -154,12 +153,12 @@ void TextItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* style, Q
case Angle45:
painter->translate(width()/2,0);
painter->rotate(45);
- m_text->setTextWidth(sqrt(2*(pow(width()/2,2))));
+ text->setTextWidth(sqrt(2*(pow(width()/2,2))));
break;
case Angle315:
painter->translate(0,height()/2);
painter->rotate(315);
- m_text->setTextWidth(sqrt(2*(pow(height()/2,2))));
+ text->setTextWidth(sqrt(2*(pow(height()/2,2))));
break;
}
@@ -175,7 +174,8 @@ void TextItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* style, Q
painter->setOpacity(qreal(foregroundOpacity())/100);
QAbstractTextDocumentLayout::PaintContext ctx;
ctx.palette.setColor(QPalette::Text, fontColor());
- for(QTextBlock it=m_text->begin();it!=m_text->end();it=it.next()){
+
+ for(QTextBlock it = text->begin(); it != text->end(); it=it.next()){
it.blockFormat().setLineHeight(m_lineSpacing,QTextBlockFormat::LineDistanceHeight);
for (int i=0;ilineCount();i++){
QTextLine line = it.layout()->lineAt(i);
@@ -186,7 +186,8 @@ void TextItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* style, Q
}
}
}
- m_text->documentLayout()->draw(painter,ctx);
+
+ text->documentLayout()->draw(painter,ctx);
if (m_underlines){
if (lineHeight<0) lineHeight = painter->fontMetrics().height();
@@ -195,19 +196,6 @@ void TextItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* style, Q
}
}
- //painter->setOpacity(qreal(foregroundOpacity())/100);
-
- //m_text->setDefaultTextOption();
- //QAbstractTextDocumentLayout::PaintContext ctx;
- //ctx.palette.setColor(QPalette::Text, fontColor());
- //m_text->documentLayout()->draw(painter,ctx);
-
-// m_layout.draw(ppainter,QPointF(marginSize(),0),);
-// ppainter->setFont(transformToSceneFont(font()));
-// QTextOption o;
-// o.setAlignment(alignment());
-// ppainter->drawText(rect(), content(), o);
-
painter->restore();
BaseDesignIntf::paint(painter, style, widget);
}
@@ -218,11 +206,11 @@ QString TextItem::content() const{
void TextItem::Init()
{
- m_autoWidth=NoneAutoWidth;
- m_alignment= Qt::AlignLeft|Qt::AlignTop;
- m_autoHeight=false;
-// m_text->setDefaultFont(transformToSceneFont(font()));
- m_textSize=QSizeF();
+ m_autoWidth = NoneAutoWidth;
+ m_alignment = Qt::AlignLeft|Qt::AlignTop;
+ m_autoHeight = false;
+ m_textSize = QSizeF();
+ m_firstLineSize = 0;
m_foregroundOpacity = 100;
m_underlines = false;
m_adaptFontToSize = false;
@@ -235,19 +223,18 @@ void TextItem::setContent(const QString &value)
{
if (m_strText.compare(value)!=0){
QString oldValue = m_strText;
- m_strText=value;
- if (allowHTML())
- m_text->setHtml(replaceReturns(value.trimmed()));
+ if (m_trimValue)
+ m_strText=value.trimmed();
else
- m_text->setPlainText(value);
- //m_text->setTextWidth(width());
- //m_textSize=m_text->size();
- if (itemMode() == DesignMode){
- initText();
- }
+ m_strText=value;
+
+// if (itemMode() == DesignMode && (autoHeight())){
+// initTextSizes();
+// }
if (!isLoading()){
- initText();
+ if (autoHeight() || autoWidth() || hasFollower())
+ initTextSizes();
update(rect());
notify("content",oldValue,value);
}
@@ -258,15 +245,20 @@ void TextItem::updateItemSize(DataSourceManager* dataManager, RenderPass pass, i
{
if (isNeedExpandContent())
expandContent(dataManager, pass);
- if (!isLoading())
- initText();
+ if (!isLoading() && (autoHeight() || autoWidth() || hasFollower()) )
+ initTextSizes();
if (m_textSize.width()>width() && ((m_autoWidth==MaxWordLength)||(m_autoWidth==MaxStringLength))){
setWidth(m_textSize.width() + fakeMarginSize()*2);
}
- if ((m_textSize.height()>height()) && (m_autoHeight) ){
- setHeight(m_textSize.height()+borderLineSize()*2);
+ if (m_textSize.height()>height()) {
+ if (m_autoHeight)
+ setHeight(m_textSize.height()+borderLineSize()*2);
+ else if (hasFollower() && !content().isEmpty()){
+ follower()->setContent(getTextPart(0,height()));
+ setContent(getTextPart(height(),0));
+ }
}
BaseDesignIntf::updateItemSize(dataManager, pass, maxHeight);
}
@@ -305,24 +297,25 @@ QString TextItem::replaceReturns(QString text)
return result;
}
-void TextItem::setTextFont(const QFont& value){
- m_text->setDefaultFont(value);
+void TextItem::setTextFont(TextPtr text, const QFont& value) const {
+ text->setDefaultFont(value);
if ((m_angle==Angle0)||(m_angle==Angle180)){
- m_text->setTextWidth(rect().width()-fakeMarginSize()*2);
+ text->setTextWidth(rect().width()-fakeMarginSize()*2);
} else {
- m_text->setTextWidth(rect().height()-fakeMarginSize()*2);
+ text->setTextWidth(rect().height()-fakeMarginSize()*2);
}
}
-void TextItem::adaptFontSize(){
+void TextItem::adaptFontSize(TextPtr text) const{
QFont _font = transformToSceneFont(font());
do{
- setTextFont(_font);
+ setTextFont(text,_font);
if (_font.pixelSize()>2)
_font.setPixelSize(_font.pixelSize()-1);
else break;
- } while(m_text->size().height()>this->height() || m_text->size().width()>(this->width())-fakeMarginSize()*2);
+ } while(text->size().height()>this->height() || text->size().width()>(this->width()) - fakeMarginSize() * 2);
}
+
int TextItem::underlineLineSize() const
{
return m_underlineLineSize;
@@ -345,52 +338,19 @@ void TextItem::setLineSpacing(int value)
{
int oldValue = m_lineSpacing;
m_lineSpacing = value;
- initText();
+// if (autoHeight())
+// initTextSizes();
update();
notify("lineSpacing",oldValue,value);
}
-void TextItem::initText()
+void TextItem::initTextSizes() const
{
- QTextOption to;
- to.setAlignment(m_alignment);
-
- if (m_autoWidth!=MaxStringLength)
- if (m_adaptFontToSize && (!(m_autoHeight || m_autoWidth)))
- to.setWrapMode(QTextOption::WordWrap);
- else
- to.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
- else to.setWrapMode(QTextOption::NoWrap);
-
- m_text->setDocumentMargin(0);
- m_text->setDefaultTextOption(to);
-
- QFont _font = transformToSceneFont(font());
- if (m_adaptFontToSize && (!(m_autoHeight || m_autoWidth))){
- adaptFontSize();
- } else {
- setTextFont(transformToSceneFont(font()));
- }
-
- if ((m_angle==Angle0)||(m_angle==Angle180)){
- m_text->setTextWidth(rect().width()-fakeMarginSize()*2);
- } else {
- m_text->setTextWidth(rect().height()-fakeMarginSize()*2);
- }
-
- for ( QTextBlock block = m_text->begin(); block.isValid(); block = block.next())
- {
- QTextCursor tc = QTextCursor(block);
- QTextBlockFormat fmt = block.blockFormat();
-
- if(fmt.lineHeight() != m_lineSpacing) {
- fmt.setLineHeight(m_lineSpacing,QTextBlockFormat::LineDistanceHeight);
- tc.setBlockFormat( fmt );
- }
- }
-
- m_textSize=m_text->size();
+ TextPtr text = textDocument();
+ m_textSize= text->size();
+ if (text->begin().isValid() && text->begin().layout()->lineAt(0).isValid())
+ m_firstLineSize = text->begin().layout()->lineAt(0).height();
}
QString TextItem::formatDateTime(const QDateTime &value)
@@ -454,6 +414,163 @@ QString TextItem::formatFieldValue()
}
}
+TextItem::TextPtr TextItem::textDocument() const
+{
+ TextPtr text(new QTextDocument);
+
+ if (allowHTML())
+ text->setHtml(m_strText);
+ else
+ text->setPlainText(m_strText);
+
+ QTextOption to;
+ to.setAlignment(m_alignment);
+ to.setTextDirection(m_textLayoutDirection);
+ //to.setTextDirection(QApplication::layoutDirection());
+
+ if (m_autoWidth!=MaxStringLength)
+ if (m_adaptFontToSize && (!(m_autoHeight || m_autoWidth)))
+ to.setWrapMode(QTextOption::WordWrap);
+ else
+ to.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
+ else to.setWrapMode(QTextOption::NoWrap);
+
+ text->setDocumentMargin(0);
+ text->setDefaultTextOption(to);
+
+ QFont _font = transformToSceneFont(font());
+ if (m_adaptFontToSize && (!(m_autoHeight || m_autoWidth))){
+ adaptFontSize(text);
+ } else {
+ setTextFont(text,_font);
+ }
+
+ text->documentLayout();
+
+ for ( QTextBlock block = text->begin(); block.isValid(); block = block.next())
+ {
+ QTextCursor tc = QTextCursor(block);
+ QTextBlockFormat fmt = block.blockFormat();
+ fmt.setTextIndent(m_textIndent);
+
+ if(fmt.lineHeight() != m_lineSpacing) {
+ fmt.setLineHeight(m_lineSpacing,QTextBlockFormat::LineDistanceHeight);
+ tc.setBlockFormat( fmt );
+ }
+ }
+
+ return text;
+
+}
+
+qreal TextItem::textIndent() const
+{
+ return m_textIndent;
+}
+
+void TextItem::setTextIndent(const qreal &textIndent)
+{
+ if (m_textIndent != textIndent){
+ qreal oldValue = m_textIndent;
+ m_textIndent = textIndent;
+ update();
+ notify("textIndent", oldValue, textIndent);
+ }
+}
+
+Qt::LayoutDirection TextItem::textLayoutDirection() const
+{
+ return m_textLayoutDirection;
+}
+
+void TextItem::setTextLayoutDirection(const Qt::LayoutDirection &textLayoutDirection)
+{
+ if (m_textLayoutDirection != textLayoutDirection){
+ int oldValue = int(m_textLayoutDirection);
+ m_textLayoutDirection = textLayoutDirection;
+ update();
+ notify("textLayoutDirection",oldValue,int(textLayoutDirection));
+ }
+}
+
+
+QString TextItem::followTo() const
+{
+ return m_followTo;
+}
+
+void TextItem::setFollowTo(const QString &followTo)
+{
+ if (m_followTo != followTo){
+ QString oldValue = m_followTo;
+ m_followTo = followTo;
+ if (!isLoading()){
+ TextItem* fi = scene()->findChild(oldValue);
+ if (fi) fi->clearFollower();
+ fi = scene()->findChild(followTo);
+ if (fi && fi != this){
+ if (initFollower(followTo)){
+ notify("followTo",oldValue,followTo);
+ } else {
+ m_followTo = "";
+ QMessageBox::critical(
+ 0,
+ tr("Error"),
+ tr("TextItem \" %1 \" already has folower \" %2 \" ")
+ .arg(fi->objectName())
+ .arg(fi->follower()->objectName())
+ );
+ notify("followTo",followTo,"");
+ }
+ } else if (m_followTo != ""){
+ QMessageBox::critical(
+ 0,
+ tr("Error"),
+ tr("TextItem \" %1 \" not found !")
+ .arg(m_followTo)
+ );
+ notify("followTo",followTo,"");
+ }
+ }
+ }
+}
+
+void TextItem::setFollower(TextItem *follower)
+{
+ if (!m_follower){
+ m_follower = follower;
+ }
+}
+
+void TextItem::clearFollower()
+{
+ m_follower = 0;
+}
+
+bool TextItem::hasFollower() const
+{
+ return m_follower != 0;
+}
+
+bool TextItem::initFollower(QString follower)
+{
+ TextItem* fi = scene()->findChild(follower);
+ if (fi){
+ if (!fi->hasFollower()){
+ fi->setFollower(this);
+ return true;
+ }
+ }
+ return false;
+}
+
+void TextItem::pageObjectHasBeenLoaded()
+{
+ if (!m_followTo.isEmpty()){
+ initFollower(m_followTo);
+ }
+}
+
TextItem::ValueType TextItem::valueType() const
{
return m_valueType;
@@ -497,13 +614,14 @@ void TextItem::setAllowHTML(bool allowHTML)
{
if (m_allowHTML!=allowHTML){
m_allowHTML = allowHTML;
- if (m_text){
- if (allowHTML)
- m_text->setHtml(m_strText);
- else
- m_text->setPlainText(m_strText);
- update();
- }
+// if (m_text){
+// if (allowHTML)
+// m_text->setHtml(m_strText);
+// else
+// m_text->setPlainText(m_strText);
+// update();
+// }
+ update();
notify("allowHTML",!m_allowHTML,allowHTML);
}
}
@@ -521,22 +639,19 @@ void TextItem::setTrimValue(bool value)
void TextItem::geometryChangedEvent(QRectF , QRectF)
-{
-// if ((m_angle==Angle0)||(m_angle==Angle180)){
-// m_text->setTextWidth(rect().width()-fakeMarginSize()*2);
-// } else {
-// m_text->setTextWidth(rect().height()-fakeMarginSize()*2);
-// }
- if (itemMode() == DesignMode) initText();
- else if (adaptFontToSize()) initText();
-
-}
+{}
bool TextItem::isNeedUpdateSize(RenderPass pass) const
{
Q_UNUSED(pass)
+
+ if ((autoHeight() && autoWidth()) || hasFollower()){
+ initTextSizes();
+ }
+
bool res = (m_textSize.height()>geometry().height()&&autoHeight()) ||
(m_textSize.width()>geometry().width()&&autoWidth()) ||
+ m_follower ||
isNeedExpandContent();
return res;
}
@@ -548,7 +663,6 @@ void TextItem::setAlignment(Qt::Alignment value)
m_alignment=value;
//m_layout.setTextOption(QTextOption(m_alignment));
if (!isLoading()){
- initText();
update(rect());
notify("alignment",QVariant(oldValue),QVariant(value));
}
@@ -575,6 +689,7 @@ void TextItem::expandContent(DataSourceManager* dataManager, RenderPass pass)
} else {
setContent(context);
}
+
}
void TextItem::setAutoHeight(bool value)
@@ -600,7 +715,7 @@ void TextItem::setAdaptFontToSize(bool value)
if (m_adaptFontToSize!=value){
bool oldValue = m_adaptFontToSize;
m_adaptFontToSize=value;
- initText();
+// initText();
invalidateRect(rect());
notify("updateFontToSize",oldValue,value);
}
@@ -608,66 +723,84 @@ void TextItem::setAdaptFontToSize(bool value)
bool TextItem::canBeSplitted(int height) const
{
- return height>(m_text->begin().layout()->lineAt(0).height());
+ QFontMetrics fm(font());
+ return height > m_firstLineSize;
+}
+
+QString TextItem::getTextPart(int height, int skipHeight){
+ int linesHeight = 0;
+ int curLine = 0;
+ int textPos = 0;
+
+ TextPtr text = textDocument();
+
+ QTextBlock curBlock = text->begin();
+ QString resultText = "";
+
+ if (skipHeight > 0){
+ for (;curBlock != text->end(); curBlock=curBlock.next()){
+ for (curLine = 0; curLine < curBlock.layout()->lineCount(); curLine++){
+ linesHeight += curBlock.layout()->lineAt(curLine).height() + lineSpacing();
+ if (linesHeight > (skipHeight-(/*fakeMarginSize()*2+*/borderLineSize() * 2))) {goto loop_exit;}
+ }
+ }
+ loop_exit:;
+ }
+
+ linesHeight = 0;
+
+ for (;curBlock != text->end() || curLinelineCount(); curLine++){
+ if (resultText == "") textPos= curBlock.layout()->lineAt(curLine).textStart();
+ linesHeight += curBlock.layout()->lineAt(curLine).height() + lineSpacing();
+ if ( (height>0) && (linesHeight>(height-(/*fakeMarginSize()*2+*/borderLineSize()*2))) ) {
+ linesHeight-=curBlock.layout()->lineAt(curLine).height();
+ goto loop_exit1;
+ }
+ resultText+=curBlock.text().mid(curBlock.layout()->lineAt(curLine).textStart(),
+ curBlock.layout()->lineAt(curLine).textLength());
+ }
+ }
+ loop_exit1:;
+
+ resultText.chop(1);
+
+ QScopedPointer context(new HtmlContext(m_strText));
+ return context->extendTextByTags(resultText,textPos);
+}
+
+void TextItem::restoreLinksEvent()
+{
+ if (!followTo().isEmpty()){
+ BaseDesignIntf* pi = dynamic_cast(parentItem());
+ if (pi){
+ foreach (BaseDesignIntf* bi, pi->childBaseItems()) {
+ if (bi->patternName().compare(followTo())==0){
+ TextItem* ti = dynamic_cast(bi);
+ if (ti){
+ ti->setFollower(this);
+ }
+ }
+ }
+ }
+ }
}
BaseDesignIntf *TextItem::cloneUpperPart(int height, QObject *owner, QGraphicsItem *parent)
{
- int linesHeight=0;
- QString tmpText="";
TextItem* upperPart = dynamic_cast(cloneItem(itemMode(),owner,parent));
-
- for (QTextBlock it=m_text->begin();it!=m_text->end();it=it.next()){
- for (int i=0;ilineCount();i++){
- linesHeight+=it.layout()->lineAt(i).height()+lineSpacing();
- if (linesHeight>(height-(fakeMarginSize()*2+borderLineSize()*2))) {
- linesHeight-=it.layout()->lineAt(i).height();
- goto loop_exit;
- }
- tmpText+=it.text().mid(it.layout()->lineAt(i).textStart(),it.layout()->lineAt(i).textLength())+'\n';
- }
- }
- loop_exit:
- tmpText.chop(1);
-
- upperPart->setHeight(linesHeight+fakeMarginSize()*2+borderLineSize()*2);
- QScopedPointer context(new HtmlContext(m_strText));
- upperPart->setContent(context->extendTextByTags(tmpText,0));
- upperPart->initText();
+ upperPart->setContent(getTextPart(height,0));
+ upperPart->initTextSizes();
+ upperPart->setHeight(upperPart->textSize().height()+borderLineSize()*2);
return upperPart;
}
BaseDesignIntf *TextItem::cloneBottomPart(int height, QObject *owner, QGraphicsItem *parent)
{
TextItem* bottomPart = dynamic_cast(cloneItem(itemMode(),owner,parent));
- int linesHeight=0;
- int curLine=0;
- QTextBlock curBlock;
-
- QString tmpText="";
-
- for (curBlock=m_text->begin();curBlock!=m_text->end();curBlock=curBlock.next()){
- for (curLine=0;curLinelineCount();curLine++){
- linesHeight+=curBlock.layout()->lineAt(curLine).height()+lineSpacing();
- if (linesHeight>(height-(fakeMarginSize()*2+borderLineSize()*2))) {goto loop_exit;}
- }
- }
- loop_exit:;
-
- int textPos=0;
- for (;curBlock!=m_text->end() || curLinelineCount();curLine++){
- if (tmpText=="") textPos= curBlock.layout()->lineAt(curLine).textStart();
- tmpText+=curBlock.text().mid(curBlock.layout()->lineAt(curLine).textStart(),
- curBlock.layout()->lineAt(curLine).textLength());
- }
- }
- tmpText.chop(1);
-
- QScopedPointer context(new HtmlContext(m_strText));
- bottomPart->setContent(context->extendTextByTags(tmpText,textPos));
- bottomPart->initText();
- bottomPart->setHeight(bottomPart->m_textSize.height()+borderLineSize()*2);
+ bottomPart->setContent(getTextPart(0,height));
+ bottomPart->initTextSizes();
+ bottomPart->setHeight(bottomPart->textSize().height()+borderLineSize()*2);
return bottomPart;
}
@@ -687,9 +820,10 @@ BaseDesignIntf *TextItem::cloneEmpty(int height, QObject *owner, QGraphicsItem *
void TextItem::objectLoadFinished()
{
ItemDesignIntf::objectLoadFinished();
- if (itemMode() == DesignMode || !isNeedExpandContent()){
- initText();
- }
+// if (itemMode() == DesignMode || !isNeedExpandContent()){
+// if (autoHeight() && autoWidth())
+// initTextSizes();
+// }
}
void TextItem::setTextItemFont(QFont value)
@@ -697,7 +831,7 @@ void TextItem::setTextItemFont(QFont value)
if (font()!=value){
QFont oldValue = font();
setFont(value);
- m_text->setDefaultFont(transformToSceneFont(value));
+ update();
notify("font",oldValue,value);
}
}
@@ -759,7 +893,6 @@ void TextItem::setAngle(const AngleType& value)
AngleType oldValue = m_angle;
m_angle = value;
if (!isLoading()){
- initText();
update();
notify("angle",oldValue,value);
}
diff --git a/limereport/items/lrtextitem.h b/limereport/items/lrtextitem.h
index 07c3412..ac9b5b6 100644
--- a/limereport/items/lrtextitem.h
+++ b/limereport/items/lrtextitem.h
@@ -32,15 +32,16 @@
#include
#include
#include
-#include "lritemdesignintf.h"
-#include
-
#include
+#include "lritemdesignintf.h"
+#include "lritemdesignintf.h"
+#include "lrpageinitintf.h"
+
namespace LimeReport {
class Tag;
-class TextItem : public LimeReport::ContentItemDesignIntf {
+class TextItem : public LimeReport::ContentItemDesignIntf, IPageInit {
Q_OBJECT
Q_ENUMS(AutoWidth)
Q_ENUMS(AngleType)
@@ -66,6 +67,10 @@ class TextItem : public LimeReport::ContentItemDesignIntf {
Q_PROPERTY(bool allowHTMLInFields READ allowHTMLInFields WRITE setAllowHTMLInFields)
Q_PROPERTY(QString format READ format WRITE setFormat)
Q_PROPERTY(ValueType valueType READ valueType WRITE setValueType)
+ Q_PROPERTY(QString followTo READ followTo WRITE setFollowTo)
+ Q_PROPERTY(BrushStyle backgroundBrushStyle READ backgroundBrushStyle WRITE setBackgroundBrushStyle)
+ Q_PROPERTY(qreal textIndent READ textIndent WRITE setTextIndent)
+ Q_PROPERTY(Qt::LayoutDirection textLayoutDirection READ textLayoutDirection WRITE setTextLayoutDirection)
public:
enum AutoWidth{NoneAutoWidth,MaxWordLength,MaxStringLength};
@@ -99,7 +104,7 @@ public:
bool canBeSplitted(int height) const;
bool isSplittable() const { return true;}
- bool isEmpty() const{return m_text->isEmpty();}
+ bool isEmpty() const{return m_strText.trimmed().isEmpty() /*m_text->isEmpty()*/;}
BaseDesignIntf* cloneUpperPart(int height, QObject *owner, QGraphicsItem *parent);
BaseDesignIntf* cloneBottomPart(int height, QObject *owner, QGraphicsItem *parent);
BaseDesignIntf* createSameTypeItem(QObject* owner=0, QGraphicsItem* parent=0);
@@ -140,28 +145,51 @@ public:
ValueType valueType() const;
void setValueType(const ValueType valueType);
+ QSizeF textSize(){ return m_textSize;}
+ QString followTo() const;
+ void setFollowTo(const QString &followTo);
+ void setFollower(TextItem* follower);
+ void clearFollower();
+ bool hasFollower() const;
+ TextItem* follower() const { return m_follower;}
+ bool initFollower(QString follower);
+
+ // IPageInit interface
+ void pageObjectHasBeenLoaded();
+
+ typedef QSharedPointer TextPtr;
+
+ qreal textIndent() const;
+ void setTextIndent(const qreal &textIndent);
+ Qt::LayoutDirection textLayoutDirection() const;
+ void setTextLayoutDirection(const Qt::LayoutDirection &textLayoutDirection);
+
protected:
void updateLayout();
bool isNeedExpandContent() const;
QString replaceBR(QString text);
QString replaceReturns(QString text);
- int fakeMarginSize();
+ int fakeMarginSize() const;
+ QString getTextPart(int height, int skipHeight);
+ void restoreLinksEvent();
private:
- void initText();
- void setTextFont(const QFont &value);
- void adaptFontSize();
+ void initTextSizes() const;
+ void setTextFont(TextPtr text, const QFont &value) const;
+ void adaptFontSize(TextPtr text) const;
QString formatDateTime(const QDateTime &value);
QString formatNumber(const double value);
QString formatFieldValue();
+
+ TextPtr textDocument() const;
private:
QString m_strText;
-
//QTextLayout m_layout;
- QTextDocument* m_text;
+ //QTextDocument* m_text;
Qt::Alignment m_alignment;
bool m_autoHeight;
AutoWidth m_autoWidth;
- QSizeF m_textSize;
+ QSizeF mutable m_textSize;
+ qreal mutable m_firstLineSize;
AngleType m_angle;
int m_foregroundOpacity;
bool m_underlines;
@@ -174,6 +202,10 @@ private:
QString m_format;
ValueType m_valueType;
+ QString m_followTo;
+ TextItem* m_follower;
+ qreal m_textIndent;
+ Qt::LayoutDirection m_textLayoutDirection;
};
}
diff --git a/limereport/limereport.pro b/limereport/limereport.pro
index f287154..6397a71 100644
--- a/limereport/limereport.pro
+++ b/limereport/limereport.pro
@@ -67,7 +67,7 @@ contains(CONFIG,zint){
####Automatically build required translation files (*.qm)
contains(CONFIG,build_translations){
- LANGUAGES = ru es_ES
+ LANGUAGES = ru es_ES ar
defineReplace(prependAll) {
for(a,$$1):result += $$2$${a}$$3
diff --git a/limereport/lrbanddesignintf.cpp b/limereport/lrbanddesignintf.cpp
index a55f74c..c6993ad 100644
--- a/limereport/lrbanddesignintf.cpp
+++ b/limereport/lrbanddesignintf.cpp
@@ -183,16 +183,20 @@ BandDesignIntf::~BandDesignIntf()
delete m_bandNameLabel;
}
-void BandDesignIntf::paint(QPainter *ppainter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+void BandDesignIntf::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
- if (backgroundColor()!=Qt::white) {
- ppainter->fillRect(rect(),backgroundColor());
+
+ if ( !(backgroundColor() == Qt::white && backgroundBrushStyle() == SolidPattern) ) {
+ QBrush brush(backgroundColor(), static_cast(backgroundBrushStyle()));
+ brush.setTransform(painter->worldTransform().inverted());
+ painter->fillRect(rect(), brush);
}
- if (itemMode()&DesignMode){
- ppainter->save();
+
+ if (itemMode() & DesignMode){
+ painter->save();
QString bandText = objectName();
if (parentBand()) bandText+=QLatin1String(" connected to ")+parentBand()->objectName();
- QFont font("Arial",7*Const::fontFACTOR,-1,true);
+ QFont font("Arial", 7 * Const::fontFACTOR, -1, true);
QFontMetrics fontMetrics(font);
QVector bandNameRects;
@@ -204,22 +208,22 @@ void BandDesignIntf::paint(QPainter *ppainter, const QStyleOptionGraphicsItem *o
//if (isSelected()) ppainter->setPen(QColor(167,244,167));
// else ppainter->setPen(QColor(220,220,220));
- ppainter->setFont(font);
+ painter->setFont(font);
for (int i=0;isetRenderHint(QPainter::Antialiasing);
- ppainter->setBrush(bandColor());
- ppainter->setOpacity(Const::BAND_NAME_AREA_OPACITY);
- ppainter->drawRoundedRect(labelRect,8,8);
- ppainter->setOpacity(Const::BAND_NAME_TEXT_OPACITY);
- ppainter->setPen(Qt::black);
- ppainter->drawText(bandNameRects[i],Qt::AlignHCenter,bandText);
+ painter->setRenderHint(QPainter::Antialiasing);
+ painter->setBrush(bandColor());
+ painter->setOpacity(Const::BAND_NAME_AREA_OPACITY);
+ painter->drawRoundedRect(labelRect,8,8);
+ painter->setOpacity(Const::BAND_NAME_TEXT_OPACITY);
+ painter->setPen(Qt::black);
+ painter->drawText(bandNameRects[i],Qt::AlignHCenter,bandText);
}
}
- ppainter->restore();
+ painter->restore();
}
- BaseDesignIntf::paint(ppainter,option,widget);
+ BaseDesignIntf::paint(painter,option,widget);
}
BandDesignIntf::BandsType BandDesignIntf::bandType() const
@@ -357,6 +361,7 @@ bool BandDesignIntf::canBeSplitted(int height) const
bool BandDesignIntf::isEmpty() const
{
+ if (!isVisible()) return true;
foreach(QGraphicsItem* qgItem,childItems()){
BaseDesignIntf* item = dynamic_cast(qgItem);
if ((item)&&(!item->isEmpty())) return false;
@@ -889,6 +894,7 @@ void BandDesignIntf::updateItemSize(DataSourceManager* dataManager, RenderPass p
if (borderLines()!=0){
spaceBorder += borderLineSize();
}
+ restoreLinks();
snapshotItemsLayout();
arrangeSubItems(pass, dataManager);
if (autoHeight()){
diff --git a/limereport/lrbanddesignintf.h b/limereport/lrbanddesignintf.h
index 1f21919..fea245a 100644
--- a/limereport/lrbanddesignintf.h
+++ b/limereport/lrbanddesignintf.h
@@ -92,6 +92,7 @@ class BandDesignIntf : public BaseDesignIntf
Q_PROPERTY(bool keepBottomSpace READ keepBottomSpaceOption WRITE setKeepBottomSpaceOption )
Q_PROPERTY(QString parentBand READ parentBandName WRITE setParentBandName DESIGNABLE false )
Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor)
+ Q_PROPERTY(BrushStyle backgroundBrushStyle READ backgroundBrushStyle WRITE setBackgroundBrushStyle)
Q_PROPERTY(bool printIfEmpty READ printIfEmpty WRITE setPrintIfEmpty)
Q_ENUMS(BandColumnsLayoutType)
friend class BandMarker;
@@ -121,7 +122,7 @@ public:
BandDesignIntf(BandsType bandType, const QString& xmlTypeName, QObject* owner = 0, QGraphicsItem* parent=0);
~BandDesignIntf();
- void paint(QPainter *ppainter, const QStyleOptionGraphicsItem *option, QWidget *widget);
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
virtual BandsType bandType() const;
virtual QString bandTitle() const;
virtual QIcon bandIcon() const;
diff --git a/limereport/lrbasedesignintf.cpp b/limereport/lrbasedesignintf.cpp
index 8b632d5..f0f7e2b 100644
--- a/limereport/lrbasedesignintf.cpp
+++ b/limereport/lrbasedesignintf.cpp
@@ -34,7 +34,6 @@
#include "lrreportdesignwidget.h"
#include "qgraphicsitem.h"
#include "lrdesignelementsfactory.h"
-
#include "lrhorizontallayout.h"
#include
@@ -64,19 +63,19 @@ BaseDesignIntf::BaseDesignIntf(const QString &storageTypeName, QObject *owner, Q
m_BGMode(OpaqueMode),
m_opacity(100),
m_borderLinesFlags(0),
- m_hintFrame(0),
m_storageTypeName(storageTypeName),
m_itemMode(DesignMode),
m_objectState(ObjectCreated),
m_selectionMarker(0),
m_joinMarker(0),
- m_backgroundBrush(Solid),
- m_backgroundBrushcolor(Qt::white),
+ m_backgroundBrushStyle(SolidPattern),
+ m_backgroundColor(Qt::white),
m_margin(4),
m_itemAlign(DesignedItemAlign),
m_changingItemAlign(false),
m_borderColor(Qt::black),
- m_reportSettings(0)
+ m_reportSettings(0),
+ m_patternName("")
{
setGeometry(QRectF(0, 0, m_width, m_height));
if (BaseDesignIntf *item = dynamic_cast(parent)) {
@@ -85,9 +84,6 @@ BaseDesignIntf::BaseDesignIntf(const QString &storageTypeName, QObject *owner, Q
m_font = QFont("Arial",10);
}
initFlags();
-
-
- //connect(this,SIGNAL(objectNameChanged(QString)),this,SLOT(slotObjectNameChanged(QString)));
}
QRectF BaseDesignIntf::boundingRect() const
@@ -124,21 +120,23 @@ QString BaseDesignIntf::parentReportItemName() const
else return "";
}
-void BaseDesignIntf::setBackgroundBrushMode(BaseDesignIntf::BrushMode value)
+void BaseDesignIntf::setBackgroundBrushStyle(BrushStyle value)
{
- if ( value != m_backgroundBrush ){
- m_backgroundBrush=value;
+ if ( value != m_backgroundBrushStyle ){
+ BrushStyle oldValue = m_backgroundBrushStyle;
+ m_backgroundBrushStyle=value;
if (!isLoading()) update();
+ notify("backgroundBrushStyle", static_cast(oldValue), static_cast(value));
}
}
void BaseDesignIntf::setBackgroundColor(QColor value)
{
- if (value != m_backgroundBrushcolor){
- QColor oldValue = m_backgroundBrushcolor;
- m_backgroundBrushcolor=value;
+ if (value != m_backgroundColor){
+ QColor oldValue = m_backgroundColor;
+ m_backgroundColor=value;
if (!isLoading()) update();
- notify("backgroundColor",oldValue,m_backgroundBrushcolor);
+ notify("backgroundColor", oldValue, value);
}
}
@@ -242,6 +240,31 @@ QFont BaseDesignIntf::transformToSceneFont(const QFont& value) const
return f;
}
+QString BaseDesignIntf::expandDataFields(QString context, ExpandType expandType, DataSourceManager* dataManager)
+{
+ 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)
+{
+
+ 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)
+{
+
+ ScriptEngineManager& sm = ScriptEngineManager::instance();
+ if (sm.dataManager() != dataManager) sm.setDataManager(dataManager);
+ return sm.expandScripts(context,m_varValue,this);
+
+}
+
void BaseDesignIntf::setupPainter(QPainter *painter) const
{
if (!painter) {
@@ -352,7 +375,6 @@ void BaseDesignIntf::paint(QPainter *ppainter, const QStyleOptionGraphicsItem *o
Q_UNUSED(option);
Q_UNUSED(widget);
setupPainter(ppainter);
-
drawBorder(ppainter, rect());
if (isSelected()) {drawSelection(ppainter, rect());}
drawResizeZone(ppainter);
@@ -368,24 +390,28 @@ QColor calcColor(QColor color){
return Qt::white;
else
return Qt::black;
-};
+}
-void BaseDesignIntf::prepareRect(QPainter *ppainter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
+void BaseDesignIntf::prepareRect(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
{
- ppainter->save();
+ painter->save();
+
+ QBrush brush(m_backgroundColor,static_cast(m_backgroundBrushStyle));
+ brush.setTransform(painter->worldTransform().inverted());
+
if (isSelected() && (opacity() == 100) && (m_BGMode!=TransparentMode)) {
- ppainter->fillRect(rect(), QBrush(QColor(m_backgroundBrushcolor)));
+ painter->fillRect(rect(), brush);
}
else {
if (m_BGMode == OpaqueMode) {
- ppainter->setOpacity(qreal(m_opacity) / 100);
- ppainter->fillRect(rect(), QBrush(m_backgroundBrushcolor));
+ painter->setOpacity(qreal(m_opacity) / 100);
+ painter->fillRect(rect(), brush);
} else if (itemMode() & DesignMode){
- ppainter->setOpacity(0.1);
- ppainter->fillRect(rect(), QBrush(QPixmap(":/report/empty")));
+ painter->setOpacity(0.1);
+ painter->fillRect(rect(), QBrush(QPixmap(":/report/images/empty")));
}
}
- ppainter->restore();
+ painter->restore();
}
void BaseDesignIntf::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
@@ -672,6 +698,16 @@ void BaseDesignIntf::turnOnSelectionMarker(bool value)
}
}
+QString BaseDesignIntf::patternName() const
+{
+ return (m_patternName.isEmpty()) ? objectName() : m_patternName;
+}
+
+void BaseDesignIntf::setPatternName(const QString &patternName)
+{
+ m_patternName = patternName;
+}
+
ReportSettings *BaseDesignIntf::reportSettings() const
{
return m_reportSettings;
@@ -737,7 +773,7 @@ void BaseDesignIntf::emitObjectNamePropertyChanged(const QString &oldName, const
int BaseDesignIntf::borderLineSize() const
{
- return m_borderLineSize;
+ return 0 /*m_borderLineSize*/;
}
void BaseDesignIntf::setBorderLineSize(int value)
@@ -987,6 +1023,19 @@ void BaseDesignIntf::parentChangedEvent(BaseDesignIntf *)
}
+void BaseDesignIntf::restoreLinks()
+{
+#ifdef HAVE_QT5
+ foreach(QObject * child, children()) {
+#else
+ foreach(QObject * child, QObject::children()) {
+#endif
+ BaseDesignIntf *childItem = dynamic_cast(child);
+ if (childItem) {childItem->restoreLinks();}
+ }
+ restoreLinksEvent();
+}
+
QPainterPath BaseDesignIntf::shape() const
{
QPainterPath path;
@@ -1229,6 +1278,7 @@ void BaseDesignIntf::collectionLoadFinished(const QString &collectionName)
BaseDesignIntf *BaseDesignIntf::cloneItem(ItemMode mode, QObject *owner, QGraphicsItem *parent)
{
BaseDesignIntf *clone = cloneItemWOChild(mode, owner, parent);
+ clone->setPatternName(this->objectName());
#ifdef HAVE_QT5
foreach(QObject * child, children()) {
#else
diff --git a/limereport/lrbasedesignintf.h b/limereport/lrbasedesignintf.h
index f31bf73..253da8d 100644
--- a/limereport/lrbasedesignintf.h
+++ b/limereport/lrbasedesignintf.h
@@ -83,7 +83,7 @@ class BaseDesignIntf :
Q_INTERFACES(QGraphicsItem)
Q_ENUMS(BGMode)
Q_ENUMS(Qt::BrushStyle)
- Q_ENUMS(BrushMode)
+ Q_ENUMS(BrushStyle)
Q_ENUMS(ItemAlign)
Q_FLAGS(BorderLines)
Q_PROPERTY(QRectF geometry READ geometry WRITE setGeometryProperty NOTIFY geometryChanged)
@@ -96,8 +96,23 @@ class BaseDesignIntf :
Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor)
public:
- enum BGMode { TransparentMode,OpaqueMode};
- enum BrushMode{Solid,None};
+ enum BGMode { TransparentMode, OpaqueMode};
+
+ enum BrushStyle{ NoBrush,
+ SolidPattern,
+ Dense1Pattern,
+ Dense2Pattern,
+ Dense3Pattern,
+ Dense4Pattern,
+ Dense5Pattern,
+ Dense6Pattern,
+ Dense7Pattern,
+ HorPattern,
+ VerPattern,
+ CrossPattern,
+ BDiagPattern,
+ FDiagPattern };
+
enum ResizeFlags { Fixed = 0,
ResizeLeft = 1,
ResizeRight = 2,
@@ -116,6 +131,7 @@ public:
};
enum ObjectState {ObjectLoading, ObjectLoaded, ObjectCreated};
enum ItemAlign {LeftItemAlign,RightItemAlign,CenterItemAlign,ParentWidthItemAlign,DesignedItemAlign};
+// enum ExpandType {EscapeSymbols, NoEscapeSymbols, ReplaceHTMLSymbols};
Q_DECLARE_FLAGS(BorderLines, BorderSide)
Q_DECLARE_FLAGS(ItemMode,ItemModes)
friend class SelectionMarker;
@@ -123,13 +139,13 @@ public:
BaseDesignIntf(const QString& storageTypeName, QObject* owner = 0, QGraphicsItem* parent = 0);
virtual ~BaseDesignIntf();
- void setParentReportItem(const QString& value);
+ void setParentReportItem(const QString& value);
QString parentReportItemName() const;
- BrushMode backgroundBrushMode() const {return m_backgroundBrush;}
- void setBackgroundBrushMode(BrushMode value);
- QColor backgroundColor() const {return m_backgroundBrushcolor;}
- void setBackgroundColor(QColor value);
+ BrushStyle backgroundBrushStyle() const {return m_backgroundBrushStyle;}
+ void setBackgroundBrushStyle(BrushStyle value);
+ QColor backgroundColor() const {return m_backgroundColor;}
+ void setBackgroundColor(QColor value);
QPen pen() const;
void setPen(QPen& pen);
@@ -154,7 +170,7 @@ public:
virtual QSizeF sizeMM() const;
void paint(QPainter* ppainter, const QStyleOptionGraphicsItem* option, QWidget* widget);
- void prepareRect(QPainter* ppainter, const QStyleOptionGraphicsItem*, QWidget*);
+ void prepareRect(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*);
virtual QPainterPath shape() const;
void setFixedPos(bool fixedPos);
@@ -249,6 +265,8 @@ public:
ReportSettings* reportSettings() const;
void setReportSettings(ReportSettings *reportSettings);
void setZValueProperty(qreal value);
+ QString patternName() const;
+ void setPatternName(const QString &patternName);
Q_INVOKABLE QString setItemWidth(qreal width);
Q_INVOKABLE QString setItemHeight(qreal height);
@@ -258,6 +276,7 @@ public:
Q_INVOKABLE qreal getItemPosY();
Q_INVOKABLE QString setItemPosX(qreal xValue);
Q_INVOKABLE QString setItemPosY(qreal yValue);
+
protected:
//ICollectionContainer
@@ -283,6 +302,8 @@ protected:
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
virtual void childAddedEvent(BaseDesignIntf* child);
virtual void parentChangedEvent(BaseDesignIntf*);
+ void restoreLinks();
+ virtual void restoreLinksEvent(){}
void drawTopLine(QPainter *painter, QRectF rect) const;
void drawBootomLine(QPainter *painter, QRectF rect) const;
@@ -305,6 +326,13 @@ protected:
virtual bool drawDesignBorders() const {return true;}
virtual QColor selectionMarkerColor(){ return Const::SELECTION_COLOR;}
+
+ 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;
+
private:
void updateSelectionMarker();
int resizeDirectionFlags(QPointF position);
@@ -314,13 +342,13 @@ private:
void turnOnSelectionMarker(bool value);
private:
QPointF m_startPos;
- //QPointF m_startScenePos;
int m_resizeHandleSize;
int m_selectionPenSize;
int m_possibleResizeDirectionFlags;
int m_possibleMoveDirectionFlags;
int m_resizeDirectionFlags;
- qreal m_width, m_height;
+ qreal m_width;
+ qreal m_height;
QPen m_pen;
QFont m_font;
QColor m_fontColor;
@@ -342,7 +370,6 @@ private:
QRectF m_rightRect;
QVector m_resizeAreas;
- QFrame* m_hintFrame;
QString m_storageTypeName;
ItemMode m_itemMode;
@@ -350,8 +377,9 @@ private:
SelectionMarker* m_selectionMarker;
Marker* m_joinMarker;
- BrushMode m_backgroundBrush;
- QColor m_backgroundBrushcolor;
+ BrushStyle m_backgroundBrushStyle;
+ QColor m_backgroundColor;
+
RenderPass m_currentPass;
int m_margin;
QString m_itemTypeName;
@@ -359,6 +387,7 @@ private:
bool m_changingItemAlign;
QColor m_borderColor;
ReportSettings* m_reportSettings;
+ QString m_patternName;
signals:
void geometryChanged(QObject* object, QRectF newGeometry, QRectF oldGeometry);
void posChanged(QObject* object, QPointF newPos, QPointF oldPos);
@@ -371,6 +400,10 @@ signals:
void propertyesChanged(QVector propertyNames);
void itemAlignChanged(BaseDesignIntf* item, const ItemAlign& oldValue, const ItemAlign& newValue);
void itemVisibleHasChanged(BaseDesignIntf* item);
+
+ void beforeRender();
+ void afterData();
+ void afterRender();
};
} //namespace LimeReport
diff --git a/limereport/lrdatadesignintf.cpp b/limereport/lrdatadesignintf.cpp
index 3b24e66..f20f891 100644
--- a/limereport/lrdatadesignintf.cpp
+++ b/limereport/lrdatadesignintf.cpp
@@ -736,11 +736,15 @@ bool CallbackDatasource::checkIfEmpty(){
if (m_rowCount == 0) {
return true;
} else {
- QVariant result = true;
+ QVariant isEmpty = true;
+ QVariant recordCount = 0;
CallbackInfo info;
+ info.dataType = CallbackInfo::RowCount;
+ emit getCallbackData(info, recordCount);
+ if (recordCount.toInt()>0) return false;
info.dataType = CallbackInfo::IsEmpty;
- emit getCallbackData(info,result);
- return result.toBool();
+ emit getCallbackData(info,isEmpty);
+ return isEmpty.toBool();
}
}
diff --git a/limereport/lrdatasourcemanager.cpp b/limereport/lrdatasourcemanager.cpp
index 42ec024..bab241d 100644
--- a/limereport/lrdatasourcemanager.cpp
+++ b/limereport/lrdatasourcemanager.cpp
@@ -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)
{
diff --git a/limereport/lrdatasourcemanager.h b/limereport/lrdatasourcemanager.h
index a6043f0..7670b2e 100644
--- a/limereport/lrdatasourcemanager.h
+++ b/limereport/lrdatasourcemanager.h
@@ -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 m_groupFunctionsExpressionsMap;
+ QVector m_groupFunctionsExpressions;
+
+
};
}
#endif // LRDATASOURCEMANAGER_H
+
diff --git a/limereport/lrglobal.cpp b/limereport/lrglobal.cpp
index 47b31f0..5b2cdff 100644
--- a/limereport/lrglobal.cpp
+++ b/limereport/lrglobal.cpp
@@ -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
diff --git a/limereport/lrglobal.h b/limereport/lrglobal.h
index ea1d3ce..82a0364 100644
--- a/limereport/lrglobal.h
+++ b/limereport/lrglobal.h
@@ -83,15 +83,27 @@ namespace Const{
const QString FIELD_RX = "\\$D\\s*\\{\\s*([^{}]*)\\s*\\}";
const QString VARIABLE_RX = "\\$V\\s*\\{\\s*([^{}]*)\\s*\\}";
const QString SCRIPT_RX = "\\$S\\s*\\{(.*)\\}";
- const QString GROUP_FUNCTION_PARAM_RX = "\\(\\s*(((?:\\\"?\\$D\\s*\\{\\s*)|(?:\\\"?\\$V\\s*\\{\\s*)|(?:\\\"))(\\w+\\.?\\w+)((?:\\\")|(?:\\s*\\}\\\"?\\s*)))\\s*,\\s*\\\"(\\w+)\\\"\\s*\\)";
- 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+)((?:\\\")|(?:\\s*\\}\\\"?\\s*)))\\s*,\\s*\\\"(\\w+)\\\"\\s*\\)";
+ //const int DATASOURCE_INDEX = 6;
+ //const int VALUE_INDEX = 2;
+
+ //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;
const QString FUNCTION_MANAGER_NAME = "LimeReport";
}
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 +112,7 @@ namespace Const{
HidePreviewStatusBar = 4,
HideAllPreviewBar = 7,
PreviewBarsUserSetting = 8};
+
Q_DECLARE_FLAGS(PreviewHints, PreviewHint)
Q_FLAGS(PreviewHints)
diff --git a/limereport/lrgroupfunctions.cpp b/limereport/lrgroupfunctions.cpp
index 821b969..c265dfc 100644
--- a/limereport/lrgroupfunctions.cpp
+++ b/limereport/lrgroupfunctions.cpp
@@ -31,6 +31,7 @@
#include "lrdatasourcemanager.h"
#include "lrbanddesignintf.h"
#include "lritemdesignintf.h"
+#include "lrscriptenginemanager.h"
#include
@@ -38,26 +39,51 @@ 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));
- } else {
- setInvalid(tr("Field \"%1\" not found").arg(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));
- } else {
- setInvalid(tr("Variable \"%1\" not found").arg(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(band->childByName(m_data));
+ QString itemName = m_data;
+ ContentItemDesignIntf* item = dynamic_cast(band->childByName(itemName.remove('"')));
if (item)
m_values.push_back(item->content());
- else setInvalid(tr("Item \"%1\" not found").arg(m_data));
+ else if (m_name.compare("COUNT",Qt::CaseInsensitive) == 0) {
+ m_values.push_back(1);
+ } else setInvalid(tr("Item \"%1\" not found").arg(m_data));
+
break;
}
default:
@@ -88,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)
diff --git a/limereport/lrgroupfunctions.h b/limereport/lrgroupfunctions.h
index cfe59c2..f85a0bd 100644
--- a/limereport/lrgroupfunctions.h
+++ b/limereport/lrgroupfunctions.h
@@ -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;}
diff --git a/limereport/lritemdesignintf.cpp b/limereport/lritemdesignintf.cpp
index 655c39b..5987086 100644
--- a/limereport/lritemdesignintf.cpp
+++ b/limereport/lritemdesignintf.cpp
@@ -113,157 +113,6 @@ void ItemDesignIntf::initFlags()
}
}
-QString ContentItemDesignIntf::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;
-}
-
-QString ContentItemDesignIntf::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;
-}
-
-QString ContentItemDesignIntf::expandScripts(QString context, DataSourceManager* dataManager)
-{
- QRegExp rx(Const::SCRIPT_RX);
-
- if (context.contains(rx)){
- ScriptEngineManager::instance().setDataManager(dataManager);
- ScriptEngineType* se = ScriptEngineManager::instance().scriptEngine();
-
- //QJSValue svThis = se->globalObject().property("THIS");
- //if (!svThis.isUndefined()){
- // se->newQObject(svThis, this);
- //} else {
- ScriptValueType svThis = se->newQObject(this);
- se->globalObject().setProperty("THIS",svThis);
- //}
-
- ScriptExtractor scriptExtractor(context);
- if (scriptExtractor.parse()){
- for(int i=0; ievaluate(scriptBody);
- if (!value.isError()) {
- m_varValue = value.toVariant();
- context.replace(scriptExtractor.scriptAt(i),value.toString());
- } else {
- context.replace(scriptExtractor.scriptAt(i),value.toString());
- }
- }
- }
- }
- return context;
-}
-
-QString ContentItemDesignIntf::content() const
-{
- return "";
-}
-
-QString ContentItemDesignIntf::escapeSimbols(const QString &value)
-{
- QString result = value;
- result.replace("\"","\\\"");
- result.replace('\n',"\\n");
- return result;
-}
-
-QString ContentItemDesignIntf::replaceHTMLSymbols(const QString &value)
-{
- QString result = value;
- result.replace("<","<");
- result.replace(">",">");
- return result;
-}
-
Spacer::Spacer(QObject *owner, QGraphicsItem *parent)
:ItemDesignIntf("Spacer",owner,parent){}
diff --git a/limereport/lritemdesignintf.h b/limereport/lritemdesignintf.h
index e6f6170..a9c8d7a 100644
--- a/limereport/lritemdesignintf.h
+++ b/limereport/lritemdesignintf.h
@@ -73,17 +73,8 @@ class ContentItemDesignIntf : public ItemDesignIntf
public:
ContentItemDesignIntf(const QString& xmlTypeName, QObject* owner = 0,QGraphicsItem* parent = 0)
:ItemDesignIntf(xmlTypeName,owner,parent){}
- virtual QString content() const;
- virtual void setContent(const QString& value)=0;
- enum ExpandType {EscapeSymbols, NoEscapeSymbols, ReplaceHTMLSymbols};
-protected:
- 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);
-
- QVariant m_varValue;
+ virtual QString content() const = 0;
+ virtual void setContent(const QString& value) = 0;
};
class LayoutDesignIntf : public ItemDesignIntf{
diff --git a/limereport/lrpageinitintf.h b/limereport/lrpageinitintf.h
new file mode 100644
index 0000000..346138b
--- /dev/null
+++ b/limereport/lrpageinitintf.h
@@ -0,0 +1,9 @@
+#ifndef LRPAGEINITINTF_H
+#define LRPAGEINITINTF_H
+
+class IPageInit{
+public:
+ virtual void pageObjectHasBeenLoaded() = 0;
+};
+
+#endif // LRPAGEINITINTF_H
diff --git a/limereport/lrpreviewreportwidget.cpp b/limereport/lrpreviewreportwidget.cpp
index b405710..986e95d 100644
--- a/limereport/lrpreviewreportwidget.cpp
+++ b/limereport/lrpreviewreportwidget.cpp
@@ -16,6 +16,8 @@ namespace LimeReport {
bool PreviewReportWidgetPrivate::pageIsVisible(){
QGraphicsView* view = q_ptr->ui->graphicsView;
+ if ( m_currentPage-1 >= m_reportPages.size() || m_currentPage <= 0 )
+ return false;
PageItemDesignIntf::Ptr page = m_reportPages.at(m_currentPage-1);
return page->mapToScene(page->rect()).boundingRect().intersects(
view->mapToScene(view->viewport()->geometry()).boundingRect()
@@ -172,8 +174,12 @@ void PreviewReportWidget::print()
void PreviewReportWidget::printToPDF()
{
- QString fileName = QFileDialog::getSaveFileName(this,tr("PDF file name"),"","PDF(*.pdf)" );
+ QString filter = "PDF (*.pdf)";
+ QString fileName = QFileDialog::getSaveFileName(this,tr("PDF file name"),"","PDF (*.pdf)");
if (!fileName.isEmpty()){
+ QFileInfo fi(fileName);
+ if (fi.suffix().isEmpty())
+ fileName+=".pdf";
QPrinter printer;
printer.setOutputFileName(fileName);
printer.setOutputFormat(QPrinter::PdfFormat);
diff --git a/limereport/lrpreviewreportwindow.cpp b/limereport/lrpreviewreportwindow.cpp
index 2d05ad5..b000547 100644
--- a/limereport/lrpreviewreportwindow.cpp
+++ b/limereport/lrpreviewreportwindow.cpp
@@ -166,6 +166,11 @@ void PreviewReportWindow::setMenuVisible(bool value)
ui->menubar->setVisible(value);
}
+void PreviewReportWindow::setHideResultEditButton(bool value)
+{
+ ui->actionEdit_Mode->setVisible(value);
+}
+
QSettings*PreviewReportWindow::settings()
{
if (m_settings){
diff --git a/limereport/lrpreviewreportwindow.h b/limereport/lrpreviewreportwindow.h
index 26cf181..bc942be 100644
--- a/limereport/lrpreviewreportwindow.h
+++ b/limereport/lrpreviewreportwindow.h
@@ -65,6 +65,7 @@ public:
void setToolBarVisible(bool value);
void setStatusBarVisible(bool value);
void setMenuVisible(bool value);
+ void setHideResultEditButton(bool value);
QSettings* settings();
protected:
void writeSetting();
diff --git a/limereport/lrreportengine.cpp b/limereport/lrreportengine.cpp
index 2ce78ee..113dbfa 100644
--- a/limereport/lrreportengine.cpp
+++ b/limereport/lrreportengine.cpp
@@ -58,9 +58,11 @@ ReportEnginePrivate::ReportEnginePrivate(QObject *parent) :
QObject(parent), m_fileName(""), m_settings(0), m_ownedSettings(false),
m_printer(new QPrinter(QPrinter::HighResolution)), m_printerSelected(false),
m_showProgressDialog(true), m_reportName(""), m_activePreview(0),
- m_previewWindowIcon(":/report/images/logo32"), m_previewWindowTitle(tr("Preview"))
+ m_previewWindowIcon(":/report/images/logo32"), m_previewWindowTitle(tr("Preview")),
+ m_reportRendering(false), m_resultIsEditable(true)
{
- 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)));
@@ -382,6 +384,8 @@ void ReportEnginePrivate::previewReport(PreviewHints hints)
w->setToolBarVisible(!hints.testFlag(HidePreviewToolBar));
}
+ w->setHideResultEditButton(resultIsEditable());
+
m_activePreview = w;
connect(w,SIGNAL(destroyed(QObject*)), this, SLOT(slotPreviewWindowDestroed(QObject*)));
qDebug()<<"render time ="<cancelRender();
+ m_reportRendering = false;
}
PageDesignIntf* ReportEngine::createPreviewScene(QObject* parent){
@@ -624,6 +629,16 @@ QString ReportEnginePrivate::renderToString()
}else return QString();
}
+bool ReportEnginePrivate::resultIsEditable() const
+{
+ return m_resultIsEditable;
+}
+
+void ReportEnginePrivate::setResultEditable(bool value)
+{
+ m_resultIsEditable = value;
+}
+
bool ReportEnginePrivate::suppressFieldAndVarError() const
{
return m_reportSettings.suppressAbsentFieldsAndVarsWarnings();
@@ -634,6 +649,11 @@ void ReportEnginePrivate::setSuppressFieldAndVarError(bool suppressFieldAndVarEr
m_reportSettings.setSuppressAbsentFieldsAndVarsWarnings(suppressFieldAndVarError);
}
+bool ReportEnginePrivate::isBusy()
+{
+ return m_reportRendering;
+}
+
QString ReportEnginePrivate::previewWindowTitle() const
{
return m_previewWindowTitle;
@@ -656,14 +676,19 @@ void ReportEnginePrivate::setPreviewWindowIcon(const QIcon &previewWindowIcon)
ReportPages ReportEnginePrivate::renderToPages()
{
+ if (m_reportRendering) return ReportPages();
m_reportRender = ReportRender::Ptr(new ReportRender);
+
dataManager()->clearErrors();
dataManager()->connectAllDatabases();
dataManager()->setDesignTime(false);
+ dataManager()->updateDatasourceModel();
+
connect(m_reportRender.data(),SIGNAL(pageRendered(int)),
this, SIGNAL(renderPageFinished(int)));
if (m_pages.count()){
ReportPages result;
+ m_reportRendering = true;
emit renderStarted();
m_reportRender->setDatasources(dataManager());
m_reportRender->setScriptContext(scriptContext());
@@ -676,6 +701,7 @@ ReportPages ReportEnginePrivate::renderToPages()
m_reportRender->secondRenderPass(result);
emit renderFinished();
m_reportRender.clear();
+ m_reportRendering = false;
return result;
} else {
return ReportPages();
@@ -763,6 +789,24 @@ void ReportEngine::setPreviewWindowIcon(const QIcon &icon)
d->setPreviewWindowIcon(icon);
}
+void ReportEngine::setResultEditable(bool value)
+{
+ Q_D(ReportEngine);
+ d->setResultEditable(value);
+}
+
+bool ReportEngine::resultIsEditable()
+{
+ Q_D(ReportEngine);
+ return d->resultIsEditable();
+}
+
+bool ReportEngine::isBusy()
+{
+ Q_D(ReportEngine);
+ return d->isBusy();
+}
+
void ReportEngine::setShowProgressDialog(bool value)
{
Q_D(ReportEngine);
diff --git a/limereport/lrreportengine.h b/limereport/lrreportengine.h
index 804e764..a07d519 100644
--- a/limereport/lrreportengine.h
+++ b/limereport/lrreportengine.h
@@ -99,6 +99,9 @@ public:
PreviewReportWidget *createPreviewWidget(QWidget *parent = 0);
void setPreviewWindowTitle(const QString& title);
void setPreviewWindowIcon(const QIcon& icon);
+ void setResultEditable(bool value);
+ bool resultIsEditable();
+ bool isBusy();
signals:
void renderStarted();
void renderFinished();
diff --git a/limereport/lrreportengine_p.h b/limereport/lrreportengine_p.h
index 614bc88..85aff24 100644
--- a/limereport/lrreportengine_p.h
+++ b/limereport/lrreportengine_p.h
@@ -121,6 +121,9 @@ public:
bool suppressFieldAndVarError() const;
void setSuppressFieldAndVarError(bool suppressFieldAndVarError);
+ bool isBusy();
+ bool resultIsEditable() const;
+ void setResultEditable(bool value);
signals:
void pagesLoadFinished();
@@ -170,6 +173,8 @@ private:
QString m_previewWindowTitle;
QPointer m_designerWindow;
ReportSettings m_reportSettings;
+ bool m_reportRendering;
+ bool m_resultIsEditable;
};
}
diff --git a/limereport/lrreportrender.cpp b/limereport/lrreportrender.cpp
index fc08cc9..2d0701c 100644
--- a/limereport/lrreportrender.cpp
+++ b/limereport/lrreportrender.cpp
@@ -167,8 +167,17 @@ void ReportRender::setScriptContext(ScriptEngineContext* scriptContext)
bool ReportRender::runInitScript(){
if (m_scriptEngineContext){
- ScriptValueType res = ScriptEngineManager::instance().scriptEngine()->evaluate(m_scriptEngineContext->initScript());
+ QScriptEngine* engine = ScriptEngineManager::instance().scriptEngine();
+ engine->pushContext();
+ QScriptValue res = engine->evaluate(m_scriptEngineContext->initScript());
if (res.isBool()) return res.toBool();
+ if (engine->hasUncaughtException()) {
+ QMessageBox::critical(0,tr("Error"),
+ QString("Line %1: %2 ").arg(engine->uncaughtExceptionLineNumber())
+ .arg(engine->uncaughtException().toString())
+ );
+ return false;
+ }
}
return true;
}
@@ -200,11 +209,11 @@ void ReportRender::renderPage(PageDesignIntf* patternPage)
{
m_curentNameIndex = 0;
m_patternPageItem = patternPage->pageItem();
+
+
if (m_patternPageItem->resetPageNumber() && m_pageCount>0) {
resetPageNumber(PageReset);
-
}
- //m_pageCount = 1;
m_renderCanceled = false;
BandDesignIntf* reportFooter = m_patternPageItem->bandByType(BandDesignIntf::ReportFooter);
m_reportFooterHeight = 0;
@@ -214,12 +223,21 @@ void ReportRender::renderPage(PageDesignIntf* patternPage)
#ifdef HAVE_UI_LOADER
initDialogs();
#endif
+
+ if (m_scriptEngineContext){
+ baseDesignIntfToScript(patternPage->pageItem());
+ foreach (BaseDesignIntf* item, patternPage->pageItem()->childBaseItems()){
+ baseDesignIntfToScript(item);
+ }
+ }
+
if (runInitScript()){
clearPageMap();
try{
datasources()->setAllDatasourcesToFirst();
+ datasources()->clearGroupFuntionsExpressions();
} catch(ReportError &exception){
//TODO possible should thow exeption
QMessageBox::critical(0,tr("Error"),exception.what());
@@ -227,10 +245,11 @@ void ReportRender::renderPage(PageDesignIntf* patternPage)
}
clearPageMap();
-
startNewPage();
- renderBand(m_patternPageItem->bandByType(BandDesignIntf::ReportHeader),StartNewPageAsNeeded);
+
+
+ renderBand(m_patternPageItem->bandByType(BandDesignIntf::ReportHeader), 0, StartNewPageAsNeeded);
BandDesignIntf* lastRenderedBand = 0;
for (int i=0;idataBandCount() && !m_renderCanceled;i++){
@@ -241,16 +260,17 @@ void ReportRender::renderPage(PageDesignIntf* patternPage)
}
if (reportFooter)
- renderBand(reportFooter,StartNewPageAsNeeded);
+ renderBand(reportFooter, 0, StartNewPageAsNeeded);
if (lastRenderedBand && lastRenderedBand->keepFooterTogether())
closeFooterGroup(lastRenderedBand);
- BandDesignIntf* tearOffBand = m_patternPageItem->bandByType(BandDesignIntf::TearOffBand);
- if (tearOffBand)
- renderBand(tearOffBand,StartNewPageAsNeeded);
+ BandDesignIntf* tearOffBand = m_patternPageItem->bandByType(BandDesignIntf::TearOffBand);
+ if (tearOffBand)
+ renderBand(tearOffBand, 0, StartNewPageAsNeeded);
savePage(true);
+ ScriptEngineManager::instance().scriptEngine()->popContext();
}
}
@@ -261,7 +281,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);
}
@@ -283,6 +303,7 @@ void ReportRender::initRenderPage()
m_renderPageItem = new PageItemDesignIntf(m_patternPageItem->pageSize(), m_patternPageItem->pageRect());
m_renderPageItem->initFromItem(m_patternPageItem);
m_renderPageItem->setItemMode(PreviewMode);
+ m_renderPageItem->setPatternName(m_patternPageItem->objectName());
}
}
@@ -365,7 +386,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(4)+'"').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);
@@ -375,11 +397,19 @@ void ReportRender::replaceGroupsFunction(BandDesignIntf *band)
}
}
-void ReportRender::renderBand(BandDesignIntf *patternBand, ReportRender::DataRenderMode mode, bool isLast)
+BandDesignIntf* ReportRender::renderBand(BandDesignIntf *patternBand, BandDesignIntf* bandData, ReportRender::DataRenderMode mode, bool isLast)
{
QApplication::processEvents();
if (patternBand){
+ BandDesignIntf* bandClone = 0;
+
+ if (bandData){
+ bandClone = bandData;
+ } else {
+ bandClone=renderData(patternBand);
+ }
+
if (mode == ForcedStartPage){
savePage();
startNewPage();
@@ -388,14 +418,16 @@ void ReportRender::renderBand(BandDesignIntf *patternBand, ReportRender::DataRen
if (patternBand->isFooter())
m_lastRenderedFooter = patternBand;
- BandDesignIntf* bandClone=renderData(patternBand);
+
bandClone->setBackgroundColor(
(datasources()->variable(QLatin1String("line_")+patternBand->objectName().toLower()).toInt()%2!=0 ?
- patternBand->backgroundColor():
- patternBand->alternateBackgroundColor()
+ bandClone->backgroundColor():
+ bandClone->alternateBackgroundColor()
)
);
+
patternBand->emitBandRendered(bandClone);
+ emit(patternBand->afterRender());
if ( isLast && bandClone->keepFooterTogether() && bandClone->sliceLastRow() ){
if (m_maxHeightByColumn[m_currentColumn] < (bandClone->height()+m_reportFooterHeight))
@@ -440,10 +472,16 @@ void ReportRender::renderBand(BandDesignIntf *patternBand, ReportRender::DataRen
}
}
}
- } else {delete bandClone;}
+ } else {
+ delete bandClone;
+ return 0;
+ }
+
if (patternBand->isFooter())
datasources()->clearGroupFunctionValues(patternBand->objectName());
+ return bandClone;
}
+ return 0;
}
void ReportRender::renderDataBand(BandDesignIntf *dataBand)
@@ -456,7 +494,7 @@ void ReportRender::renderDataBand(BandDesignIntf *dataBand)
BandDesignIntf* header = dataBand->bandHeader();
BandDesignIntf* footer = dataBand->bandFooter();
- if (header && header->printAlways()) renderBand(header);
+ if (header && header->printAlways()) renderBand(header, 0);
if(bandDatasource && !bandDatasource->eof() && !m_renderCanceled){
@@ -464,7 +502,7 @@ void ReportRender::renderDataBand(BandDesignIntf *dataBand)
datasources()->setReportVariable(varName,1);
if (header && !header->printAlways())
- renderBand(header);
+ renderBand(header, 0);
if (dataBand->bandHeader() && dataBand->bandHeader()->reprintOnEachPage())
m_reprintableBands.append(dataBand->bandHeader());
@@ -474,28 +512,35 @@ void ReportRender::renderDataBand(BandDesignIntf *dataBand)
bool firstTime = true;
+
while(!bandDatasource->eof() && !m_renderCanceled){
- if ((firstTime && dataBand->startFromNewPage()) ||
- (!firstTime && dataBand->startNewPage())) {
- savePage();
- startNewPage();
+ BandDesignIntf* rawData = renderData(dataBand);
+
+ if (!rawData->isEmpty() || dataBand->printIfEmpty()){
+
+ if ((firstTime && dataBand->startFromNewPage()) ||
+ (!firstTime && dataBand->startNewPage())) {
+ savePage();
+ startNewPage();
+ }
+
+ if (dataBand->tryToKeepTogether()) openDataGroup(dataBand);
+
+ if (dataBand->keepFooterTogether() && !bandDatasource->hasNext())
+ openFooterGroup(dataBand);
+
+ datasources()->updateChildrenData(dataBand->datasourceName());
+ m_lastDataBand = dataBand;
+
+ if (header && !firstTime && header->repeatOnEachRow())
+ renderBand(header, 0, StartNewPageAsNeeded);
+
+ renderBand(dataBand, rawData, StartNewPageAsNeeded, !bandDatasource->hasNext());
+ renderChildBands(dataBand);
+
}
- if (dataBand->tryToKeepTogether()) openDataGroup(dataBand);
-
- if (dataBand->keepFooterTogether() && !bandDatasource->hasNext())
- openFooterGroup(dataBand);
-
- datasources()->updateChildrenData(dataBand->datasourceName());
- m_lastDataBand = dataBand;
-
- if (header && !firstTime && header->repeatOnEachRow())
- renderBand(header,StartNewPageAsNeeded);
-
- renderBand(dataBand,StartNewPageAsNeeded,!bandDatasource->hasNext());
- renderChildBands(dataBand);
-
bandDatasource->next();
datasources()->setReportVariable(varName,datasources()->variable(varName).toInt()+1);
@@ -515,16 +560,16 @@ void ReportRender::renderDataBand(BandDesignIntf *dataBand)
renderGroupFooter(dataBand);
if (footer && !footer->printAlways())
- renderBand(footer,StartNewPageAsNeeded);
+ renderBand(footer, 0, StartNewPageAsNeeded);
datasources()->deleteVariable(varName);
} else if (bandDatasource==0) {
- renderBand(dataBand,StartNewPageAsNeeded);
+ renderBand(dataBand, 0, StartNewPageAsNeeded);
}
if (footer && footer->printAlways())
- renderBand(footer,StartNewPageAsNeeded);
+ renderBand(footer, 0, StartNewPageAsNeeded);
}
void ReportRender::renderPageHeader(PageItemDesignIntf *patternPage)
@@ -534,7 +579,7 @@ void ReportRender::renderPageHeader(PageItemDesignIntf *patternPage)
if (m_datasources->variable("#PAGE").toInt()!=1 ||
band->property("printOnFirstPage").toBool()
)
- renderBand(band);
+ renderBand(band, 0);
}
}
@@ -556,15 +601,21 @@ void ReportRender::renderPageFooter(PageItemDesignIntf *patternPage)
void ReportRender::renderPageItems(PageItemDesignIntf* patternPage)
{
+ QList pageItems;
foreach (BaseDesignIntf* item, patternPage->childBaseItems()) {
ItemDesignIntf* id = dynamic_cast(item);
if (id&&id->itemLocation()==ItemDesignIntf::Page){
BaseDesignIntf* cloneItem = item->cloneItem(m_renderPageItem->itemMode(),
m_renderPageItem,
m_renderPageItem);
- cloneItem->updateItemSize(m_datasources);
+ pageItems.append(cloneItem);
+ //cloneItem->updateItemSize(m_datasources);
}
}
+ m_renderPageItem->restoreLinks();
+ foreach(BaseDesignIntf* item, pageItems){
+ item->updateItemSize(m_datasources);
+ }
}
qreal ReportRender::calcPageFooterHeight(PageItemDesignIntf *patternPage)
@@ -586,7 +637,7 @@ void ReportRender::renderChildHeader(BandDesignIntf *parent, BandPrintMode print
if (band->metaObject()->indexOfProperty("printAlways")>0){
printAlways=band->property("printAlways").toBool();
}
- if (printAlways == (printMode==PrintAlwaysPrintable) ) renderBand(band,StartNewPageAsNeeded);
+ if (printAlways == (printMode==PrintAlwaysPrintable) ) renderBand(band, 0, StartNewPageAsNeeded);
}
}
@@ -599,14 +650,16 @@ void ReportRender::renderChildFooter(BandDesignIntf *parent, BandPrintMode print
}
if ( (band != m_lastRenderedFooter) && (printAlways == (printMode == PrintAlwaysPrintable)) )
- renderBand(band,StartNewPageAsNeeded);
+ renderBand(band, 0, StartNewPageAsNeeded);
}
}
void ReportRender::renderChildBands(BandDesignIntf *parentBand)
{
foreach(BandDesignIntf* band,parentBand->childrenByType(BandDesignIntf::SubDetailBand)){
- IDataSource* ds = m_datasources->dataSource(band->datasourceName());
+ IDataSource* ds = 0;
+ if (!band->datasourceName().isEmpty())
+ ds = m_datasources->dataSource(band->datasourceName());
if (ds) ds->first();
renderChildHeader(band,PrintAlwaysPrintable);
renderDataBand(band);
@@ -624,13 +677,13 @@ void ReportRender::renderGroupHeader(BandDesignIntf *parentBand, IDataSource* da
dataSource->prior();
foreach (BandDesignIntf* subBand, band->childrenByType(BandDesignIntf::GroupHeader)) {
foreach(BandDesignIntf* footer, subBand->childrenByType(BandDesignIntf::GroupFooter)){
- renderBand(footer);
+ renderBand(footer, 0);
closeDataGroup(subBand);
}
}
foreach (BandDesignIntf* footer, band->childrenByType(BandDesignIntf::GroupFooter)) {
- renderBand(footer,StartNewPageAsNeeded);
+ renderBand(footer, 0, StartNewPageAsNeeded);
}
dataSource->next();
@@ -649,9 +702,9 @@ void ReportRender::renderGroupHeader(BandDesignIntf *parentBand, IDataSource* da
openDataGroup(band);
if (!firstTime && gb->startNewPage()){
if (gb->resetPageNumber()) resetPageNumber(BandReset);
- renderBand(band,ForcedStartPage);
+ renderBand(band, 0, ForcedStartPage);
} else {
- renderBand(band,StartNewPageAsNeeded);
+ renderBand(band, 0, StartNewPageAsNeeded);
}
}
@@ -666,7 +719,7 @@ void ReportRender::renderGroupFooter(BandDesignIntf *parentBand)
if (gb && gb->isStarted()){
if (band->reprintOnEachPage()) m_reprintableBands.removeOne(band);
if (band->childBands().count()>0){
- renderBand(band->childBands().at(0),StartNewPageAsNeeded);
+ renderBand(band->childBands().at(0), 0, StartNewPageAsNeeded);
}
closeDataGroup(band);
}
@@ -950,10 +1003,18 @@ BandDesignIntf *ReportRender::saveUppperPartReturnBottom(BandDesignIntf *band, i
BandDesignIntf *ReportRender::renderData(BandDesignIntf *patternBand)
{
BandDesignIntf* bandClone = dynamic_cast(patternBand->cloneItem(PreviewMode));
+
+ baseDesignIntfToScript(bandClone);
+ emit(patternBand->beforeRender());
+
if (patternBand->isFooter()){
replaceGroupsFunction(bandClone);
}
bandClone->updateItemSize(m_datasources);
+
+ baseDesignIntfToScript(bandClone);
+ emit(patternBand->afterData());
+
return bandClone;
}
@@ -974,24 +1035,29 @@ void ReportRender::startNewPage()
initColumns();
initRenderPage();
+ baseDesignIntfToScript(m_renderPageItem);
+
m_renderPageItem->setObjectName(QLatin1String("ReportPage")+QString::number(m_pageCount));
m_maxHeightByColumn[m_currentColumn]=m_renderPageItem->pageRect().height();
m_currentStartDataPos[m_currentColumn]=m_patternPageItem->topMargin()*Const::mmFACTOR;
m_currentIndex=0;
+ emit m_patternPageItem->beforeRender();
+
renderPageHeader(m_patternPageItem);
- //renderPageFooter(m_patternPageItem);
+
m_pageFooterHeight = calcPageFooterHeight(m_patternPageItem);
m_maxHeightByColumn[m_currentColumn] -= m_pageFooterHeight;
m_currentIndex=10;
m_dataAreaSize = m_maxHeightByColumn[m_currentColumn];
m_renderedDataBandCount = 0;
- foreach (BandDesignIntf* band, m_reprintableBands) {
- renderBand(band);
- }
- checkLostHeadersOnPrevPage();
+ foreach (BandDesignIntf* band, m_reprintableBands) {
+ renderBand(band, 0);
+ }
+
+ checkLostHeadersOnPrevPage();
pasteGroups();
renderPageItems(m_patternPageItem);
}
@@ -1164,6 +1230,7 @@ void ReportRender::savePage(bool isLast)
}
moveTearOffBand();
+ emit m_patternPageItem->afterRender();
}
@@ -1184,4 +1251,29 @@ void ReportRender::cancelRender(){
m_renderCanceled = true;
}
+void ReportRender::baseDesignIntfToScript(BaseDesignIntf *item)
+{
+ if ( item ) {
+
+ if (item->metaObject()->indexOfSignal("beforeRender()")!=-1)
+ item->disconnect(SIGNAL(beforeRender()));
+ if (item->metaObject()->indexOfSignal("afterData()")!=-1)
+ item->disconnect(SIGNAL(afterData()));
+ if (item->metaObject()->indexOfSignal("afterRender()")!=-1)
+ item->disconnect(SIGNAL(afterRender()));
+
+ QScriptEngine* engine = ScriptEngineManager::instance().scriptEngine();
+ QScriptValue sItem = engine->globalObject().property(item->patternName());
+ if (sItem.isValid()){
+ engine->newQObject(sItem, item);
+ } else {
+ sItem = engine->newQObject(item);
+ engine->globalObject().setProperty(item->patternName(),sItem);
+ }
+ foreach(BaseDesignIntf* child, item->childBaseItems()){
+ baseDesignIntfToScript(child);
+ }
+ }
+}
+
}
diff --git a/limereport/lrreportrender.h b/limereport/lrreportrender.h
index ab128d8..16e8176 100644
--- a/limereport/lrreportrender.h
+++ b/limereport/lrreportrender.h
@@ -86,6 +86,9 @@ signals:
public slots:
void cancelRender();
private:
+
+ void baseDesignIntfToScript(BaseDesignIntf* item);
+
void renderPage(PageDesignIntf *patternPage);
void initDatasources();
void initDatasource(const QString &name);
@@ -96,7 +99,7 @@ private:
void initVariables();
bool runInitScript();
void clearPageMap();
- void renderBand(BandDesignIntf *patternBand, DataRenderMode mode = NotStartNewPage, bool isLast = false);
+ BandDesignIntf* renderBand(BandDesignIntf *patternBand, BandDesignIntf *bandData, DataRenderMode mode = NotStartNewPage, bool isLast = false);
void renderDataBand(BandDesignIntf* dataBand);
void renderPageHeader(PageItemDesignIntf* patternPage);
void renderPageFooter(PageItemDesignIntf* patternPage);
diff --git a/limereport/lrscriptenginemanager.cpp b/limereport/lrscriptenginemanager.cpp
index 6aaedca..ad0d84d 100644
--- a/limereport/lrscriptenginemanager.cpp
+++ b/limereport/lrscriptenginemanager.cpp
@@ -220,6 +220,28 @@ QScriptValue setVariable(QScriptContext* pcontext, QScriptEngine* /*pengine*/){
return QScriptValue();
}
+QScriptValue getVariable(QScriptContext* pcontext, QScriptEngine* pengine){
+
+ QString name = pcontext->argument(0).toString();
+
+ ScriptEngineManager* sm = qscriptvalue_cast(pcontext->callee().data());
+ DataSourceManager* dm = sm->dataManager();
+ QScriptValue res = pengine->newVariant(dm->variable(name));
+
+ return res;
+}
+
+QScriptValue getField(QScriptContext* pcontext, QScriptEngine* pengine){
+
+ QString name = pcontext->argument(0).toString();
+
+ ScriptEngineManager* sm = qscriptvalue_cast(pcontext->callee().data());
+ DataSourceManager* dm = sm->dataManager();
+ QScriptValue res = pengine->newVariant(dm->fieldData(name));
+
+ return res;
+}
+
QScriptValue numberFormat(QScriptContext* pcontext, QScriptEngine* pengine){
QVariant value = pcontext->argument(0).toVariant();
char format = (pcontext->argumentCount()>1)?pcontext->argument(1).toString()[0].toLatin1():'f';
@@ -280,8 +302,17 @@ QScriptValue callGroupFunction(const QString& functionName, QScriptContext* pcon
ScriptEngineManager* sm = qscriptvalue_cast(pcontext->callee().data());
DataSourceManager* dm = sm->dataManager();
- QString expression = pcontext->argument(0).toString();
- QString band = pcontext->argument(1).toString();
+ QString expression;
+ QString band;
+
+ if (functionName.compare("COUNT",Qt::CaseInsensitive) == 0 && pcontext->argumentCount()==1){
+ expression = " ";
+ band = pcontext->argument(0).toString();
+ } else {
+ expression = dm->getExpression(pcontext->argument(0).toString());
+ band = pcontext->argument(1).toString();
+ }
+
QScriptValue res;
GroupFunction* gf = dm->groupFunction(functionName,expression,band);
if (gf){
@@ -446,11 +477,173 @@ void ScriptEngineManager::setDataManager(DataSourceManager *dataManager){
.arg(LimeReport::Const::FUNCTION_MANAGER_NAME)
);
addFunction(describer);
+
}
}
}
}
+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; ievaluate(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()
{
diff --git a/limereport/lrscriptenginemanager.h b/limereport/lrscriptenginemanager.h
index 63a2f45..b338bbb 100644
--- a/limereport/lrscriptenginemanager.h
+++ b/limereport/lrscriptenginemanager.h
@@ -263,6 +263,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);
diff --git a/qzint.pri b/qzint.pri
new file mode 100644
index 0000000..51a6a50
--- /dev/null
+++ b/qzint.pri
@@ -0,0 +1,64 @@
+DEFINES += _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS ZINT_VERSION=\\\"$$ZINT_VERSION\\\" NO_PNG
+
+!contains(DEFINES, NO_PNG) {
+ LIBS += -lpng
+}
+
+INCLUDEPATH += \
+ $$ZINT_PATH/backend \
+ $$ZINT_PATH/backend_qt4
+
+HEADERS += $$ZINT_PATH/backend/aztec.h \
+ $$ZINT_PATH/backend/code1.h \
+ $$ZINT_PATH/backend/code49.h \
+ $$ZINT_PATH/backend/common.h \
+ $$ZINT_PATH/backend/composite.h \
+ $$ZINT_PATH/backend/dmatrix.h \
+ $$ZINT_PATH/backend/font.h \
+ $$ZINT_PATH/backend/gb2312.h \
+ $$ZINT_PATH/backend/gridmtx.h \
+ $$ZINT_PATH/backend/gs1.h \
+ $$ZINT_PATH/backend/large.h \
+ $$ZINT_PATH/backend/maxicode.h \
+ $$ZINT_PATH/backend/maxipng.h \
+ $$ZINT_PATH/backend/ms_stdint.h \
+ $$ZINT_PATH/backend/pdf417.h \
+ $$ZINT_PATH/backend/qr.h \
+ $$ZINT_PATH/backend/reedsol.h \
+ $$ZINT_PATH/backend/rss.h \
+ $$ZINT_PATH/backend/sjis.h \
+ $$ZINT_PATH/backend/zint.h \
+ $$ZINT_PATH/backend_qt4/qzint.h
+
+SOURCES += $$ZINT_PATH/backend/2of5.c \
+ $$ZINT_PATH/backend/auspost.c \
+ $$ZINT_PATH/backend/aztec.c \
+ $$ZINT_PATH/backend/code.c \
+ $$ZINT_PATH/backend/code1.c \
+ $$ZINT_PATH/backend/code128.c \
+ $$ZINT_PATH/backend/code16k.c \
+ $$ZINT_PATH/backend/code49.c \
+ $$ZINT_PATH/backend/common.c \
+ $$ZINT_PATH/backend/composite.c \
+ $$ZINT_PATH/backend/dmatrix.c \
+ $$ZINT_PATH/backend/gridmtx.c \
+ $$ZINT_PATH/backend/gs1.c \
+ $$ZINT_PATH/backend/imail.c \
+ $$ZINT_PATH/backend/large.c \
+ $$ZINT_PATH/backend/library.c \
+ $$ZINT_PATH/backend/maxicode.c \
+ $$ZINT_PATH/backend/medical.c \
+ $$ZINT_PATH/backend/pdf417.c \
+ $$ZINT_PATH/backend/plessey.c \
+ $$ZINT_PATH/backend/postal.c \
+ $$ZINT_PATH/backend/ps.c \
+ $$ZINT_PATH/backend/qr.c \
+ $$ZINT_PATH/backend/reedsol.c \
+ $$ZINT_PATH/backend/render.c \
+ $$ZINT_PATH/backend/rss.c \
+ $$ZINT_PATH/backend/svg.c \
+ $$ZINT_PATH/backend/telepen.c \
+ $$ZINT_PATH/backend/upcean.c \
+ $$ZINT_PATH/backend/dllversion.c \
+ $$ZINT_PATH/backend/png.c \
+ $$ZINT_PATH/backend_qt4/qzint.cpp
diff --git a/translations/limereport_ar.ts b/translations/limereport_ar.ts
new file mode 100644
index 0000000..aa037f9
--- /dev/null
+++ b/translations/limereport_ar.ts
@@ -0,0 +1,2192 @@
+
+
+
+
+ AboutDialog
+
+
+ حول البرنامج
+
+
+
+ المؤلف
+
+
+
+ إتفاقية الترخيص
+
+
+
+ إغلاق
+
+
+
+ الإصدار 1.1.1
+
+
+
+ ConnectionDialog
+
+
+ إتصال بقاعدة بيانات
+
+
+
+ أسم الإتصال
+
+
+
+ المشغل
+
+
+
+ الخادم
+
+
+
+ المستخدم
+
+
+
+ كلمة المرور
+
+
+
+ قاعدة البيانات
+
+
+
+ إتصال تلقائي
+
+
+
+ فحص الإتصال
+
+
+
+ إلغاء الأمر
+
+
+
+ خطأ
+
+
+
+ تم الإتصال بنجاح!!
+
+
+
+ أسم الإتصال فارغ
+
+
+
+ إتصال بأسم
+
+
+
+ موجود مسبقاً
+
+
+
+ DataBrowser
+
+
+ مصدر البيانات
+
+
+
+ إضافة إتصال قاعدة بيانات
+
+
+
+ إضافة مصدر بيانات جديد
+
+
+
+ عرض البيانات
+
+
+
+ تغيير مصدر البيانات
+
+
+
+ حذف مصدر البيانات
+
+
+
+ عرض الأخطاء
+
+
+
+ المتغيرات
+
+
+
+ إضافة متغير
+
+
+
+ تعديل متغير
+
+
+
+ حذف متغير
+
+
+
+ LRVariableDialog
+
+
+ متغير
+
+
+
+ الأسم
+
+
+
+ القيمة
+
+
+
+ النوع
+
+
+
+ Attention
+
+
+
+ LimeReport::AVariablesHolder
+
+
+ متغير بأسم
+
+
+
+ موجود مسبقاً !!
+
+
+
+ غير موجود !!
+
+
+
+ LimeReport::AboutDialog
+
+
+ حول البرنامج
+
+
+
+ المؤلف
+
+
+
+ إتفاقية الترخيص
+
+
+
+ إغلاق
+
+
+
+ الإصدار 1.1.1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ LimeReport::AlignmentPropItem
+
+
+ محاذاة يسار
+
+
+
+ محاذاة يمين
+
+
+
+ محاذاة وسط
+
+
+
+ ملأ السطر
+
+
+
+ محاذاة لأعلى
+
+
+
+ محاذاة لأسفل
+
+
+
+ أفقي
+
+
+
+ عمودي
+
+
+
+ LimeReport::BandDesignIntf
+
+
+ إتصال ب
+
+
+
+ LimeReport::ConnectionDialog
+
+
+ إتصال بقاعدة بيانات
+
+
+
+ أسم الإتصال
+
+
+
+ المشغل
+
+
+
+ الخادم
+
+
+
+ المستخدم
+
+
+
+ كلمة المرور
+
+
+
+ قاعدة البيانات
+
+
+
+ إتصال تلقائي
+
+
+
+ فحص الإتصال
+
+
+
+ إلغاء الأمر
+
+
+
+ خطأ
+
+
+
+ تم الإتصال بنجاح!
+
+
+
+ أسم الإتصال فارغ
+
+
+
+ إتصال بأسم
+
+
+
+ موجود مسبقاً
+
+
+
+
+
+
+
+ موافق
+
+
+
+ LimeReport::ContentItemDesignIntf
+
+
+ المتغير %1 غير موجود
+
+
+
+ LimeReport::DataBand
+
+
+ بيانات
+
+
+
+ LimeReport::DataBrowser
+
+
+ مصدر البيانات
+
+
+
+ إضافة إتصال قاعدة بيانات
+
+
+
+ إضافة مصدر بيانات جديد
+
+
+
+ عرض البيانات
+
+
+
+ تغيير مصدر البيانات
+
+
+
+ حذف مصدر البيانات
+
+
+
+ عرض الأخطاء
+
+
+
+ المتغيرات
+
+
+
+ إضافة متغير جديد
+
+
+
+ تعديل متغير
+
+
+
+ حذف متغير
+
+
+
+ Attention
+
+
+
+ Do you really want delete "%1" connection ?
+ هل ترغب في حذف الإتصال "%1" ?
+
+
+
+ متغيرات المستخدم
+
+
+
+ متغيرات النظام
+
+
+
+ Do you really want delete "%1" datasource ?
+ هل ترغب في حذف مصدر البيانات "%1" ?
+
+
+
+ هل ترغب في حذف المتغير "%1" ?
+
+
+
+ خطأ
+
+
+
+
+
+
+
+ هل ترغب في حذف المتغير "%1" ?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ LimeReport::DataFooterBand
+
+
+ ذيل جدول البيانات
+
+
+
+ LimeReport::DataHeaderBand
+
+
+ رأس جدول البيانات
+
+
+
+ LimeReport::DataSourceManager
+
+
+ الإتصال "%1" غير مفتوح
+
+
+
+ الإتصال "%1" غير موجود !
+
+
+
+ الإتصال بأسم "%1" موجود مسبقاً !
+
+
+
+ data source with name "%1" already exists !!
+ مصدر البيانات بأسم "%1" موجود مسبقاً !
+
+
+
+ خطأ بالإتصال
+
+
+
+
+
+
+
+
+
+
+
+ LimeReport::DataSourceModel
+
+
+ مصدر البيانات
+
+
+
+ المتغيرات
+
+
+
+
+
+
+
+ LimeReport::FontEditorWidget
+
+
+ خط ثخين
+
+
+
+ خط مائل
+
+
+
+ تحته خط
+
+
+
+ LimeReport::FontPropItem
+
+
+ ثخين
+
+
+
+ مائل
+
+
+
+ تحته خط
+
+
+
+ حجم
+
+
+
+ الفئة
+
+
+
+ LimeReport::GroupBandFooter
+
+
+ ذيل المجموعة
+
+
+
+ LimeReport::GroupBandHeader
+
+
+ رأس المجموعة
+
+
+
+
+
+
+
+
+
+
+
+ LimeReport::GroupFunction
+
+
+ الحقل "%1" غير موجود
+
+
+
+ المتغير "%1" غير موجود
+
+
+
+ العنصر "%1" غير موجود
+
+
+
+ LimeReport::ImageItem
+
+
+ صورة
+
+
+
+ LimeReport::ItemsAlignmentEditorWidget
+
+
+ إحضار للأمام
+
+
+
+ إرسال للخلف
+
+
+
+ محاذاة يسار
+
+
+
+ محاذاة يمين
+
+
+
+ محاذاة وسط(عمودي)
+
+
+
+ محاذاة لأعلى
+
+
+
+ محاذاة لأسفل
+
+
+
+ محاذاة وسط (أفقي)
+
+
+
+ مساواة الارتفاع
+
+
+
+ مساواة العرض
+
+
+
+ LimeReport::ItemsBordersEditorWidget
+
+
+ خط علوي
+
+
+
+ خط سفلي
+
+
+
+ خط أيسر
+
+
+
+ خط أيمن
+
+
+
+ بدون إطار
+
+
+
+ محاط بإطار
+
+
+
+ LimeReport::MasterDetailProxyModel
+
+
+ الحقل: "%1" غير موجود في مصدر البيانات الفرعي "%2"
+
+
+
+ الحقل: "%1" غير موجود في مصدر البيانات الرئيسي "%2"
+
+
+
+ LimeReport::ModelToDataSource
+
+
+
+
+
+
+ LimeReport::ObjectBrowser
+
+
+ الكائن
+
+
+
+ LimeReport::PageDesignIntf
+
+
+ تحذير
+
+
+
+ لا يمكن حذف فقرات متعددة
+
+
+
+ LimeReport::PageFooter
+
+
+ ذيل الصفحة
+
+
+
+ LimeReport::PageHeader
+
+
+ رأس الصفحة
+
+
+
+ LimeReport::PreviewReportWidget
+
+
+ نموذج
+
+
+
+ أسم ملف PDF
+
+
+
+ أسم التقرير
+
+
+
+ LimeReport::PreviewReportWindow
+
+
+ عرض
+
+
+
+ تقرير
+
+
+
+ شريط الأدوات
+
+
+
+ طباعة
+
+
+
+ تكبير
+
+
+
+ تصغير
+
+
+
+ الصفحة السابقة
+
+
+
+ الصفحة التالية
+
+
+
+ أغلاق
+
+
+
+ وضع التعديل
+
+
+
+ حفظ إلى ملف
+
+
+
+ عرض الأخطاء
+
+
+
+ الصفحة الأولى
+
+
+
+ الصفحة الأولى
+
+
+
+ الصفحة الأخيرة
+
+
+
+ تحويل إلى PDF
+
+
+
+ صفحة:
+
+
+
+ من %1
+
+
+
+ أسم التقرير
+
+
+
+ أسم ملف PDF
+
+
+
+ معاينة
+
+
+
+
+
+
+
+ تمديد ليتاسب عرض الصفحة
+
+
+
+ تمديد ليناسب الصفحة بالكامل
+
+
+
+
+
+
+
+ عرض شريط الأدوات
+
+
+
+ عرض شريط الأدوات
+
+
+
+ LimeReport::ProxyHolder
+
+
+ مصدر البيانات غير صحيح
+
+
+
+ LimeReport::QObjectPropertyModel
+
+
+ الخاصية
+
+
+
+ القيمة
+
+
+
+ الهامش الأيسر
+
+
+
+ الهامش الأيمن
+
+
+
+ الهامش العلوي
+
+
+
+ Отступ нижний
+
+
+
+ أسم الكائن
+
+
+
+ الإطار
+
+
+
+ الأبعاد
+
+
+
+ محاذاة
+
+
+
+ أتجاة الصفحة
+
+
+
+ حجم الصفحة
+
+
+
+ خط علوي
+
+
+
+ خط سفلي
+
+
+
+ خط أيسر
+
+
+
+ خط أيمن
+
+
+
+ مصدر البيانات
+
+
+
+ расположение
+
+
+
+ المحتوى
+
+
+
+ قفل
+
+
+
+ تحذير
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ LimeReport::RectMMPropItem
+
+
+ العرض
+
+
+
+ الأرتفاع
+
+
+
+ LimeReport::RectPropItem
+
+
+ العرض
+
+
+
+ الأرتفاع
+
+
+
+ LimeReport::ReportDesignWidget
+
+
+ أسم التقرير
+
+
+
+ LimeReport::ReportDesignWindow
+
+
+ تقرير جديد
+
+
+
+ وضع التعديل
+
+
+
+ تراجع
+
+
+
+ أعادة التراجع
+
+
+
+ نسخ
+
+
+
+ لصق
+
+
+
+ قص
+
+
+
+ إعدادات
+
+
+
+ عرض الشبكة
+
+
+
+ نص
+
+
+
+ حفظ التقرير
+
+
+
+ حفظ التقرير بأسم
+
+
+
+ تحميل التقرير
+
+
+
+ حذف
+
+
+
+ تكبير
+
+
+
+ تصغير
+
+
+
+ إنشاء التقرير
+
+
+
+ Режим редактирования группировок
+
+
+
+ Горизонтальная группировка
+
+
+
+ О программе
+
+
+
+ إخفاء المقطع الأيسر
+
+
+
+ إخفاء المقطع الأيمن
+
+
+
+ أدوات التقرير
+
+
+
+ الأدوات الرئيسة
+
+
+
+ خط
+
+
+
+ محاذاة النص
+
+
+
+ محاذاة
+
+
+
+ الإطار
+
+
+
+ فقرات التقرير
+
+
+
+ رأس التقرير
+
+
+
+ ذيل التقرير
+
+
+
+ رأس الصفحة
+
+
+
+ ذيل الصفحة
+
+
+
+ جدول البيانات
+
+
+
+ رأس جدول البيانات
+
+
+
+ ذيل جدول البيانات
+
+
+
+ بيانات فرعية
+
+
+
+ رأس البيانات الفرعية
+
+
+
+ ذيل البيانات الفرعية
+
+
+
+ رأس المجموعة
+
+
+
+ ذيل المجموعة
+
+
+
+ ملف
+
+
+
+ تحرير
+
+
+
+ معلومات
+
+
+
+ فاحص الكائن
+
+
+
+ بنية التقرير
+
+
+
+ إستعراض البيانات
+
+
+
+ تم تعديل التقرير ! هل تريد حفظ التعديلات ?
+
+
+
+ أسم التقرير
+
+
+
+ جاري قراءة التقرير
+
+
+
+ إجهاض
+
+
+
+ تم إنشاء الصفحة
+
+
+
+ تحذير
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ LimeReport::ReportEnginePrivate
+
+
+ Ошибка
+
+
+
+
+
+
+
+ LimeReport::ReportFooter
+
+
+ Завершение отчета
+
+
+
+ LimeReport::ReportHeader
+
+
+ رأس التقرير
+
+
+
+ LimeReport::ReportRender
+
+
+ خطأ
+
+
+
+ فقرة جدول البيانات "%1" غير موجودة
+
+
+
+ خطأ في إستخدام الدالة %1
+
+
+
+ LimeReport::SQLEditDialog
+
+
+ مصدر البيانات
+
+
+
+ الإتصال
+
+
+
+ أسم مصدر البيانات
+
+
+
+ البيانات الفرعية
+
+
+
+ مصدر البيانات الرئيسي
+
+
+
+ وضع الاستعلام الفرعي
+
+
+
+ وضع التصفية
+
+
+
+
+
+
+
+ إخفاء المعاينة
+
+
+
+ مصدر البيانات الفرعي
+
+
+
+
+
+
+
+ معاينة البيانات
+
+
+
+ إلغاء الأمر
+
+
+
+ خطأ
+
+
+
+ أسم مصدر البيانات فارغ !
+
+
+
+ SQL فارغة !
+
+
+
+ مصدر البيانات بأسم: "%1" موجود مسبقاً !
+
+
+
+ مصدر البيانات بأسم: "%1" موجود مسبقاً
+
+
+
+
+
+
+
+ إتصال غير محدد
+
+
+
+ تحديث
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ LimeReport::ScriptEngineManager
+
+
+ Имя поля
+
+
+
+ أسم الفقرة
+
+
+
+ القيمة
+
+
+
+ الصيغة
+
+
+
+ الموقع
+
+
+
+
+
+
+
+
+
+
+
+ الأسم
+
+
+
+ LimeReport::SettingDialog
+
+
+ إعدادات
+
+
+
+ الخط الإفتراضي
+
+
+
+ شبكة
+
+
+
+ تباعد الشبكة العمودي
+
+
+
+ تباعد الشبكة الأفقي
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ LimeReport::SubDetailBand
+
+
+ البيانات الفرعية
+
+
+
+ LimeReport::SubDetailHeaderBand
+
+
+ رأس البيانات الفرعية
+
+
+
+ LimeReport::TearOffBand
+
+
+
+
+
+
+ LimeReport::TextAlignmentEditorWidget
+
+
+ محاذاة النص لليسار
+
+
+
+ محاذاة النص للوسط
+
+
+
+ محاذاة النص لليمين
+
+
+
+ ملأ السطر
+
+
+
+ محاذاة النص لأعلى
+
+
+
+ محاذاة السطر لأسفل
+
+
+
+ LimeReport::TextItemEditor
+
+
+ تحرير النص
+
+
+
+ المحتوى
+
+
+
+ الدوال
+
+
+
+ إعدادات المحرر
+
+
+
+ خطوط المحرر
+
+
+
+ إلغاء الأمر
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ LimeReport::VariablesHolder
+
+
+ متغير بأسم
+
+
+
+ موجود مسبقاً !!
+
+
+
+ غير موجود !!
+
+
+
+ PreviewReportWindow
+
+
+ معاينة
+
+
+
+ عرض
+
+
+
+ تقرير
+
+
+
+ شريط الأدوات
+
+
+
+ طباعة
+
+
+
+ تكبير
+
+
+
+ تصغير
+
+
+
+ الصفحة السابقة
+
+
+
+ الصفحة التالية
+
+
+
+ أغلاق
+
+
+
+ وضع التعديل
+
+
+
+ حفظ إلى ملف
+
+
+
+ عرض الأخطاء
+
+
+
+ الصفحة الأولى
+
+
+
+ الصفحة الأولى
+
+
+
+ الصفحة الأخيرة
+
+
+
+ تحويل إلى PDF
+
+
+
+ صفحة:
+
+
+
+ من %1
+
+
+
+ أسم التقرير
+
+
+
+ أسم ملف PDF
+
+
+
+ QObject
+
+
+ جدول البرنامج
+
+
+
+ رأس جدول البيانات
+
+
+
+ ذيل جدول البيانات
+
+
+
+ رأس المجموعة
+
+
+
+ ذيل المجموعة
+
+
+
+ ذيل الصفحة
+
+
+
+ رأس الصفحة
+
+
+
+ ذيل التقرير
+
+
+
+ رأس التقرير
+
+
+
+ البيانات الفرعية
+
+
+
+ رأس البيانات الفرعية
+
+
+
+ ذيل البيانات الفرعية
+
+
+
+ محاذاة
+
+
+
+ باركود
+
+
+
+ نسق أفقي
+
+
+
+ صورة
+
+
+
+ رسم
+
+
+
+ الموقع
+
+
+
+ نص
+
+
+
+ خطأ بإتصال %1
+
+
+
+ مصدر البيانات الرئيسي "%1" غير موجود!
+
+
+
+ بيانات فرعية
+
+
+
+ و بيانات فرعية
+
+
+
+ مصدر البيانات الرئيسي "%1" غير موجود !
+
+
+
+
+
+
+
+ العناصر المحددة مختلفة البنية
+
+
+
+ أسم الكائن %1 уже موجود مسبقاً
+
+
+
+ الدالة %1 غير موجودة او الباريميترات خاطئة
+
+
+
+ مصدر البيانات
+
+
+
+ الحقل
+
+
+
+
+
+
+
+
+
+
+
+ الأبعاد
+
+
+
+
+
+
+
+ الحقل %1 غير مفتوح
+
+
+
+ خط علوي
+
+
+
+ خط سفلي
+
+
+
+ خط أيسر
+
+
+
+ خط أيمن
+
+
+
+ المحتوى
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ SQLEditDialog
+
+
+ مصدر البيانات
+
+
+
+ الإتصال
+
+
+
+ أسم مصدر البيانات
+
+
+
+ البيانات الفرعية
+
+
+
+ مصدر البيانات الرئيسي
+
+
+
+ وضع الاستعلام الفرعي
+
+
+
+ وضع التصفية
+
+
+
+ معاينة
+
+
+
+ إخفاء المعاينة
+
+
+
+ مصدر البيانات الفرعي
+
+
+
+ معاينة البيانات
+
+
+
+ إلغاء الأمر
+
+
+
+ خطأ
+
+
+
+ أسم مصدر البيانات فارغ !
+
+
+
+ SQL فارغة !
+
+
+
+ مصدر البيانات بأسم: "%1" موجود مسبقاً !
+
+
+
+ مصدر البيانات بأسم: "%1" موجود مسبقاً
+
+
+
+ إتصال غير محدد
+
+
+
+ تحديث
+
+
+
+ SettingDialog
+
+
+ إعدادات
+
+
+
+ الخط الإفتراضي
+
+
+
+ شبكة
+
+
+
+ تباعد الشبكة العمودي
+
+
+
+ تباعد الشبكة الأفقي
+
+
+
+ TextItemEditor
+
+
+ محرر النص
+
+
+
+ المحتوى
+
+
+
+ جدول البيانات
+
+
+
+ الدوال
+
+
+
+ إعدادات المحرر
+
+
+
+ محرر الخطوط
+
+
+
+ إلغاء الأمر
+
+
+
+ WaitForm
+
+
+ انتظر
+
+
+
+ يرجى الإنتظار ...
+
+
+