From 4559925af437b8012f128ff21435e277b0b27719 Mon Sep 17 00:00:00 2001 From: Arin Alexander Date: Tue, 21 Mar 2017 18:01:35 +0300 Subject: [PATCH] aggregate functions can be called in data header --- limereport/bands/lrsubdetailband.h | 1 + limereport/lrbanddesignintf.cpp | 24 ++++++++ limereport/lrbanddesignintf.h | 7 ++- limereport/lrbasedesignintf.cpp | 14 ++++- limereport/lrbasedesignintf.h | 3 + limereport/lrdatasourcemanager.cpp | 6 +- limereport/lrreportrender.cpp | 90 ++++++++++++++++++++++++------ limereport/lrreportrender.h | 7 +++ 8 files changed, 131 insertions(+), 21 deletions(-) diff --git a/limereport/bands/lrsubdetailband.h b/limereport/bands/lrsubdetailband.h index ae094e4..afbc6c5 100644 --- a/limereport/bands/lrsubdetailband.h +++ b/limereport/bands/lrsubdetailband.h @@ -64,6 +64,7 @@ class SubDetailHeaderBand : public BandDesignIntf public: SubDetailHeaderBand(QObject* owner = 0, QGraphicsItem* parent=0); bool isUnique() const; + bool isHeader() const {return true;} protected: QColor bandColor() const; private: diff --git a/limereport/lrbanddesignintf.cpp b/limereport/lrbanddesignintf.cpp index ed9a534..42342ad 100644 --- a/limereport/lrbanddesignintf.cpp +++ b/limereport/lrbanddesignintf.cpp @@ -461,6 +461,19 @@ void BandDesignIntf::processPopUpAction(QAction *action) } } +void BandDesignIntf::recalcItems(DataSourceManager* dataManager) +{ + foreach(BaseDesignIntf* bi, childBaseItems()){ + ContentItemDesignIntf* ci = dynamic_cast(bi); + if (bi){ + ContentItemDesignIntf* pci = dynamic_cast(bi->patternItem()); + ci->setContent(pci->content()); + } + } + + updateItemSize(dataManager,FirstPass,height()); +} + BaseDesignIntf* BandDesignIntf::cloneUpperPart(int height, QObject *owner, QGraphicsItem *parent) { int maxBottom = 0; @@ -966,6 +979,17 @@ void BandDesignIntf::updateItemSize(DataSourceManager* dataManager, RenderPass p BaseDesignIntf::updateItemSize(dataManager, pass, maxHeight); } +void BandDesignIntf::restoreItems() +{ + foreach(BaseDesignIntf* bi, childBaseItems()){ + ContentItemDesignIntf* ci = dynamic_cast(bi); + if (ci){ + ContentItemDesignIntf* pci = dynamic_cast(bi->patternItem()); + ci->setContent(pci->content()); + } + } +} + void BandDesignIntf::updateBandNameLabel() { if (m_bandNameLabel) m_bandNameLabel->updateLabel(); diff --git a/limereport/lrbanddesignintf.h b/limereport/lrbanddesignintf.h index c53b9e3..c440aab 100644 --- a/limereport/lrbanddesignintf.h +++ b/limereport/lrbanddesignintf.h @@ -128,6 +128,8 @@ public: virtual QIcon bandIcon() const; virtual bool isUnique() const; void updateItemSize(DataSourceManager *dataManager, RenderPass pass=FirstPass, int maxHeight=0); + void restoreItems(); + void recalcItems(DataSourceManager* dataManager); void updateBandNameLabel(); virtual QColor selectionColor() const; @@ -220,8 +222,8 @@ public: QColor alternateBackgroundColor() const; void setAlternateBackgroundColor(const QColor &alternateBackgroundColor); bool useAlternateBackgroundColor() const; - void setUseAlternateBackgroundColor(bool useAlternateBackgroundColor); - + void setUseAlternateBackgroundColor(bool useAlternateBackgroundColor); + void replaceGroupsFunction(BandDesignIntf *band); signals: void bandRendered(BandDesignIntf* band); protected: @@ -248,6 +250,7 @@ protected: void moveItemsDown(qreal startPos, qreal offset); void preparePopUpMenu(QMenu &menu); void processPopUpAction(QAction *action); + private slots: void childBandDeleted(QObject* band); private: diff --git a/limereport/lrbasedesignintf.cpp b/limereport/lrbasedesignintf.cpp index 944277e..1e02ecf 100644 --- a/limereport/lrbasedesignintf.cpp +++ b/limereport/lrbasedesignintf.cpp @@ -79,7 +79,8 @@ BaseDesignIntf::BaseDesignIntf(const QString &storageTypeName, QObject *owner, Q m_changingItemAlign(false), m_borderColor(Qt::black), m_reportSettings(0), - m_patternName("") + m_patternName(""), + m_patternItem(0) { setGeometry(QRectF(0, 0, m_width, m_height)); if (BaseDesignIntf *item = dynamic_cast(parent)) { @@ -712,6 +713,16 @@ void BaseDesignIntf::setPatternName(const QString &patternName) m_patternName = patternName; } +BaseDesignIntf* BaseDesignIntf::patternItem() const +{ + return m_patternItem; +} + +void BaseDesignIntf::setPatternItem(BaseDesignIntf *patternItem) +{ + m_patternItem = patternItem; +} + ReportSettings *BaseDesignIntf::reportSettings() const { return m_reportSettings; @@ -1330,6 +1341,7 @@ BaseDesignIntf *BaseDesignIntf::cloneItem(ItemMode mode, QObject *owner, QGraphi { BaseDesignIntf *clone = cloneItemWOChild(mode, owner, parent); clone->setPatternName(this->objectName()); + clone->setPatternItem(this); #ifdef HAVE_QT5 foreach(QObject * child, children()) { #else diff --git a/limereport/lrbasedesignintf.h b/limereport/lrbasedesignintf.h index c925579..812fefc 100644 --- a/limereport/lrbasedesignintf.h +++ b/limereport/lrbasedesignintf.h @@ -272,6 +272,8 @@ public: void setZValueProperty(qreal value); QString patternName() const; void setPatternName(const QString &patternName); + BaseDesignIntf* patternItem() const; + void setPatternItem(BaseDesignIntf* patternItem); Q_INVOKABLE QString setItemWidth(qreal width); Q_INVOKABLE QString setItemHeight(qreal height); @@ -397,6 +399,7 @@ private: QColor m_borderColor; ReportSettings* m_reportSettings; QString m_patternName; + BaseDesignIntf* m_patternItem; signals: void geometryChanged(QObject* object, QRectF newGeometry, QRectF oldGeometry); void posChanged(QObject* object, QPointF newPos, QPointF oldPos); diff --git a/limereport/lrdatasourcemanager.cpp b/limereport/lrdatasourcemanager.cpp index dc2c32e..1198f8b 100644 --- a/limereport/lrdatasourcemanager.cpp +++ b/limereport/lrdatasourcemanager.cpp @@ -258,7 +258,11 @@ void DataSourceManager::clearGroupFuntionsExpressions() QString DataSourceManager::getExpression(QString index) { - return m_groupFunctionsExpressions.at(index.toInt()); + bool ok = false; + int i = index.toInt(&ok); + if (ok && m_groupFunctionsExpressions.size()>i) + return m_groupFunctionsExpressions.at(index.toInt()); + else return ""; } bool DataSourceManager::designTime() const diff --git a/limereport/lrreportrender.cpp b/limereport/lrreportrender.cpp index 2476930..99d5cf3 100644 --- a/limereport/lrreportrender.cpp +++ b/limereport/lrreportrender.cpp @@ -259,11 +259,8 @@ void ReportRender::renderPage(PageDesignIntf* patternPage) clearPageMap(); startNewPage(true); - renderReportHeader(m_patternPageItem, AfterPageHeader); -// renderBand(m_patternPageItem->bandByType(BandDesignIntf::ReportHeader), 0, StartNewPageAsNeeded); - BandDesignIntf* lastRenderedBand = 0; for (int i=0;idataBandCount() && !m_renderCanceled;i++){ lastRenderedBand = m_patternPageItem->dataBandAt(i); @@ -318,6 +315,7 @@ void ReportRender::initRenderPage() m_renderPageItem->initFromItem(m_patternPageItem); m_renderPageItem->setItemMode(PreviewMode); m_renderPageItem->setPatternName(m_patternPageItem->objectName()); + m_renderPageItem->setPatternItem(m_patternPageItem); } } @@ -393,6 +391,21 @@ void ReportRender::extractGroupsFunction(BandDesignIntf *band) } } +bool ReportRender::containsGroupsFunction(BandDesignIntf *band){ + foreach(BaseDesignIntf* item,band->childBaseItems()){ + ContentItemDesignIntf* contentItem = dynamic_cast(item); + if (contentItem){ + QString content = contentItem->content(); + foreach(QString functionName, m_datasources->groupFunctionNames()){ + QRegExp rx(QString(Const::GROUP_FUNCTION_RX).arg(functionName)); + if (rx.indexIn(content)>=0){ + return true; + } + } + } + } + return false; +} void ReportRender::replaceGroupsFunction(BandDesignIntf *band) { @@ -517,20 +530,20 @@ void ReportRender::renderDataBand(BandDesignIntf *dataBand) BandDesignIntf* header = dataBand->bandHeader(); BandDesignIntf* footer = dataBand->bandFooter(); - if (header && header->printAlways()) renderBand(header, 0); + if (header && header->printAlways()) renderDataHeader(header); if(bandDatasource && !bandDatasource->eof() && !m_renderCanceled){ QString varName = QLatin1String("line_")+dataBand->objectName().toLower(); datasources()->setReportVariable(varName,1); - if (header && !header->printAlways()) - renderBand(header, 0); - - if (dataBand->bandHeader() && dataBand->bandHeader()->reprintOnEachPage()) + if (header && header->reprintOnEachPage()) m_reprintableBands.append(dataBand->bandHeader()); - renderChildHeader(dataBand,PrintNotAlwaysPrintable); + if (header && !header->printAlways()) + renderDataHeader(header); + + //renderChildHeader(dataBand,PrintNotAlwaysPrintable); renderGroupHeader(dataBand, bandDatasource, true); bool firstTime = true; @@ -578,7 +591,8 @@ void ReportRender::renderDataBand(BandDesignIntf *dataBand) firstTime = false; } - m_reprintableBands.removeOne(dataBand->bandHeader()); + m_reprintableBands.removeOne(header); + if (header) recalcIfNeeded(header); renderGroupFooter(dataBand); @@ -702,13 +716,48 @@ void ReportRender::renderChildBands(BandDesignIntf *parentBand) } } +BandDesignIntf* ReportRender::findRecalcableBand(BandDesignIntf* patternBand){ + + QList::iterator it = m_recalcBands.begin(); + for (;it !=m_recalcBands.end() ;++it){ + if ((*it)->patternItem() == patternBand){ + BandDesignIntf* result = (*it); + m_recalcBands.erase(it); + return result; + } + } + return 0; +} + +void ReportRender::recalcIfNeeded(BandDesignIntf* band){ + BandDesignIntf* recalcBand = findRecalcableBand(band); + if (recalcBand){ + QString bandName = recalcBand->objectName(); + recalcBand->restoreItems(); + recalcBand->setObjectName(recalcBand->patternItem()->objectName()); + replaceGroupsFunction(recalcBand); + recalcBand->updateItemSize(datasources()); + recalcBand->setObjectName(bandName); + datasources()->clearGroupFunctionValues(recalcBand->patternItem()->objectName()); + } +} + +void ReportRender::renderDataHeader(BandDesignIntf *header) +{ + recalcIfNeeded(header); + BandDesignIntf* renderedHeader = renderBand(header, 0); + if (containsGroupsFunction(header)) + m_recalcBands.append(renderedHeader); +} + void ReportRender::renderGroupHeader(BandDesignIntf *parentBand, IDataSource* dataSource, bool firstTime) { foreach(BandDesignIntf* band,parentBand->childrenByType(BandDesignIntf::GroupHeader)){ IGroupBand* gb = dynamic_cast(band); - if (gb&&gb->isNeedToClose(m_datasources)){ + if (gb&&gb->isNeedToClose(datasources())){ if (band->childBands().count()>0){ dataSource->prior(); + foreach (BandDesignIntf* subBand, band->childrenByType(BandDesignIntf::GroupHeader)) { foreach(BandDesignIntf* footer, subBand->childrenByType(BandDesignIntf::GroupFooter)){ renderBand(footer, 0); @@ -723,10 +772,6 @@ void ReportRender::renderGroupHeader(BandDesignIntf *parentBand, IDataSource* da dataSource->next(); } closeDataGroup(band); -// if (gb->isNeedToStartNewPage()){ -// savePage(); -// startNewPage(); -// } } if (!gb->isStarted()){ @@ -734,12 +779,15 @@ void ReportRender::renderGroupHeader(BandDesignIntf *parentBand, IDataSource* da m_reprintableBands.append(band); gb->startGroup(m_datasources); openDataGroup(band); + BandDesignIntf* renderedHeader = 0; if (!firstTime && gb->startNewPage()){ if (gb->resetPageNumber()) resetPageNumber(BandReset); - renderBand(band, 0, ForcedStartPage); + renderedHeader = renderBand(band, 0, ForcedStartPage); } else { - renderBand(band, 0, StartNewPageAsNeeded); + renderedHeader = renderBand(band, 0, StartNewPageAsNeeded); } + if (containsGroupsFunction(band)) + m_recalcBands.append(renderedHeader); } renderGroupHeader(band, dataSource, firstTime); @@ -753,6 +801,7 @@ void ReportRender::renderGroupFooterByHeader(BandDesignIntf* groupHeader){ foreach (BandDesignIntf* footer, groupHeader->childrenByType(BandDesignIntf::GroupFooter)){ renderBand(footer, 0, StartNewPageAsNeeded); } + recalcIfNeeded(groupHeader); } void ReportRender::renderGroupFooter(BandDesignIntf *parentBand) @@ -780,6 +829,7 @@ void ReportRender::initGroups() if (band->isHeader()){ IGroupBand* gb = dynamic_cast(band); if (gb) gb->closeGroup(); + extractGroupsFunction(band); } } } @@ -852,6 +902,7 @@ void ReportRender::closeDataGroup(BandDesignIntf *band) groupBand->closeGroup(); if (band->reprintOnEachPage()) m_reprintableBands.removeOne(band); } + recalcIfNeeded(band); closeGroup(band); } @@ -1056,6 +1107,11 @@ BandDesignIntf *ReportRender::renderData(BandDesignIntf *patternBand) if (patternBand->isFooter()){ replaceGroupsFunction(bandClone); } + + if (patternBand->isHeader()){ + replaceGroupsFunction(bandClone); + } + bandClone->updateItemSize(m_datasources); baseDesignIntfToScript(bandClone); diff --git a/limereport/lrreportrender.h b/limereport/lrreportrender.h index 1759712..21048c9 100644 --- a/limereport/lrreportrender.h +++ b/limereport/lrreportrender.h @@ -90,6 +90,7 @@ private: void baseDesignIntfToScript(BaseDesignIntf* item); + void renderPage(PageDesignIntf *patternPage); void initDatasources(); void initDatasource(const QString &name); @@ -112,13 +113,18 @@ private: void renderChildHeader(BandDesignIntf* parent, BandPrintMode printMode); void renderChildFooter(BandDesignIntf* parent, BandPrintMode printMode); void renderChildBands(BandDesignIntf* parentBand); + void recalcIfNeeded(BandDesignIntf *band); + void renderDataHeader(BandDesignIntf* header); void renderGroupHeader(BandDesignIntf* parentBand, IDataSource* dataSource, bool firstTime); void renderGroupFooter(BandDesignIntf* parentBand); void initGroups(); + bool containsGroupsFunction(BandDesignIntf* band); void extractGroupsFunction(BandDesignIntf* band); void replaceGroupsFunction(BandDesignIntf* band); + BandDesignIntf *findRecalcableBand(BandDesignIntf *patternBand); + void popPageFooterGroupValues(BandDesignIntf* dataBand); void pushPageFooterGroupValues(BandDesignIntf* dataBand); @@ -162,6 +168,7 @@ private: QList m_renderedPages; QMultiMap< BandDesignIntf*, GroupBandsHolder* > m_childBands; QList m_reprintableBands; + QList m_recalcBands; // QList m_lastRenderedHeaders; //int m_maxHeightByColumn[0];