From 54c5bc65edc847968ac7ed94a860c087ce487958 Mon Sep 17 00:00:00 2001 From: Arin Alexander Date: Fri, 18 Aug 2017 22:55:29 +0300 Subject: [PATCH] TOC has been added --- limereport/lrbanddesignintf.h | 1 + limereport/lrdatadesignintf.cpp | 1 + limereport/lrdatasourcemanager.cpp | 1 + limereport/lrpageitemdesignintf.cpp | 34 ++++- limereport/lrpageitemdesignintf.h | 12 ++ limereport/lrreportengine.cpp | 34 ++++- limereport/lrreportengine_p.h | 2 +- limereport/lrreportrender.cpp | 15 +- limereport/lrscriptenginemanager.cpp | 129 +++++++++++++++++- limereport/lrscriptenginemanager.h | 32 ++++- .../editors/lrbuttonlineeditor.cpp | 1 + 11 files changed, 241 insertions(+), 21 deletions(-) diff --git a/limereport/lrbanddesignintf.h b/limereport/lrbanddesignintf.h index 92a171d..4e205cb 100644 --- a/limereport/lrbanddesignintf.h +++ b/limereport/lrbanddesignintf.h @@ -240,6 +240,7 @@ public: qreal bottomSpace() const; signals: void bandRendered(BandDesignIntf* band); + void bandRegistred(); protected: void trimToMaxHeight(int maxHeight); void setBandTypeText(const QString& value); diff --git a/limereport/lrdatadesignintf.cpp b/limereport/lrdatadesignintf.cpp index 2bc5e3a..9f5e64d 100644 --- a/limereport/lrdatadesignintf.cpp +++ b/limereport/lrdatadesignintf.cpp @@ -687,6 +687,7 @@ bool CallbackDatasource::prior(){ void CallbackDatasource::first(){ m_currentRow = 0; + m_getDataFromCache = false; m_eof=checkIfEmpty(); bool result=false; diff --git a/limereport/lrdatasourcemanager.cpp b/limereport/lrdatasourcemanager.cpp index 6ff7d9e..83b438c 100644 --- a/limereport/lrdatasourcemanager.cpp +++ b/limereport/lrdatasourcemanager.cpp @@ -389,6 +389,7 @@ QSharedPointerDataSourceManager::previewSQL(const QString &c void DataSourceManager::updateDatasourceModel() { m_datasourcesModel.updateModel(); + emit datasourcesChanged(); m_needUpdate = false; } diff --git a/limereport/lrpageitemdesignintf.cpp b/limereport/lrpageitemdesignintf.cpp index 2f8f3ff..72c4327 100644 --- a/limereport/lrpageitemdesignintf.cpp +++ b/limereport/lrpageitemdesignintf.cpp @@ -50,7 +50,7 @@ PageItemDesignIntf::PageItemDesignIntf(QObject *owner, QGraphicsItem *parent) : m_topMargin(0), m_bottomMargin(0), m_leftMargin(0), m_rightMargin(0), m_pageOrientaion(Portrait), m_pageSize(A4), m_sizeChainging(false), m_fullPage(false), m_oldPrintMode(false), m_resetPageNumber(false), - m_isExtendedInDesignMode(false), m_extendedHeight(1000) + m_isExtendedInDesignMode(false), m_extendedHeight(1000), m_isTOC(false) { setFixedPos(true); setPossibleResizeDirectionFlags(Fixed); @@ -63,7 +63,7 @@ PageItemDesignIntf::PageItemDesignIntf(const PageSize pageSize, const QRectF &re m_topMargin(0), m_bottomMargin(0), m_leftMargin(0), m_rightMargin(0), m_pageOrientaion(Portrait), m_pageSize(pageSize), m_sizeChainging(false), m_fullPage(false), m_oldPrintMode(false), m_resetPageNumber(false), - m_isExtendedInDesignMode(false), m_extendedHeight(1000) + m_isExtendedInDesignMode(false), m_extendedHeight(1000), m_isTOC(false) { setFixedPos(true); setPossibleResizeDirectionFlags(Fixed); @@ -331,6 +331,36 @@ void PageItemDesignIntf::initColumnsPos(QVector &posByColumns, qreal pos, } } +QString PageItemDesignIntf::initScript() const +{ + return m_initScript; +} + +void PageItemDesignIntf::setInitScript(const QString& value) +{ + if (m_initScript.compare(value) != 0){ + QString old_value = m_initScript; + m_initScript = value; + if (!isLoading()) + notify("initScript", old_value, value); + } +} + +bool PageItemDesignIntf::getIsTOC() const +{ + return m_isTOC; +} + +void PageItemDesignIntf::setIsTOC(bool isTOC) +{ + if (m_isTOC != isTOC){ + m_isTOC = isTOC; + if (!isLoading()){ + notify("pageIsTOC", !isTOC, isTOC); + } + } +} + int PageItemDesignIntf::extendedHeight() const { return m_extendedHeight; diff --git a/limereport/lrpageitemdesignintf.h b/limereport/lrpageitemdesignintf.h index f488b07..3910d75 100644 --- a/limereport/lrpageitemdesignintf.h +++ b/limereport/lrpageitemdesignintf.h @@ -55,6 +55,8 @@ class PageItemDesignIntf : public LimeReport::ItemsContainerDesignInft Q_PROPERTY(bool resetPageNumber READ resetPageNumber WRITE setResetPageNumber) Q_PROPERTY(bool isExtendedInDesignMode READ isExtendedInDesignMode WRITE setExtendedInDesignMode) Q_PROPERTY(int extendedHeight READ extendedHeight WRITE setExtendedHeight) + Q_PROPERTY(bool pageIsTOC READ getIsTOC WRITE setIsTOC) + Q_PROPERTY(QString initScript READ initScript WRITE setInitScript) friend class ReportRender; public: enum Orientation { Portrait, Landscape }; @@ -126,6 +128,14 @@ public: int extendedHeight() const; void setExtendedHeight(int extendedHeight); + bool getIsTOC() const; + void setIsTOC(bool isTOC); + + QString initScript() const; + void setInitScript(const QString& value); +signals: + void beforeFirstPageRendered(); + void afterLastPageRendered(); protected slots: void bandDeleted(QObject* band); void bandGeometryChanged(QObject* object, QRectF newGeometry, QRectF oldGeometry); @@ -156,6 +166,8 @@ private: bool m_resetPageNumber; bool m_isExtendedInDesignMode; int m_extendedHeight; + bool m_isTOC; + QString m_initScript; }; typedef QList ReportPages; diff --git a/limereport/lrreportengine.cpp b/limereport/lrreportengine.cpp index 50d1d48..eb23fab 100644 --- a/limereport/lrreportengine.cpp +++ b/limereport/lrreportengine.cpp @@ -574,7 +574,7 @@ void ReportEnginePrivate::designReport() m_designerWindow->setWindowIcon(QIcon(":report/images/logo32")); m_designerWindow->setShowProgressDialog(m_showProgressDialog); } - + m_datasources->updateDatasourceModel(); #ifdef Q_OS_WIN m_designerWindow->setWindowModality(Qt::ApplicationModal); #endif @@ -893,22 +893,41 @@ ReportPages ReportEnginePrivate::renderToPages() m_reportRender->setScriptContext(scriptContext()); foreach (PageDesignIntf* page, m_pages) { - scriptContext()->baseDesignIntfToScript(page->pageItem()); + scriptContext()->baseDesignIntfToScript(page->pageItem()->objectName(), page->pageItem()); } if (m_scriptEngineContext->runInitScript()){ emit renderStarted(); foreach(PageDesignIntf* page , m_pages){ - page->setReportSettings(&m_reportSettings); - result.append(m_reportRender->renderPageToPages(page)); + if (!page->pageItem()->getIsTOC()){ + page->setReportSettings(&m_reportSettings); + result.append(m_reportRender->renderPageToPages(page)); + } + } + + bool isFirst = true; + + foreach(PageDesignIntf* page , m_pages){ + if (page->pageItem()->getIsTOC()){ + page->setReportSettings(&m_reportSettings); + if (isFirst){ + ReportPages pages = m_reportRender->renderPageToPages(page); + for (int i=0; irenderPageToPages(page)); + } + isFirst = false; } m_reportRender->secondRenderPass(result); emit renderFinished(); m_reportRender.clear(); - m_reportRendering = false; } + m_reportRendering = false; activateLanguage(QLocale::AnyLanguage); return result; } else { @@ -1145,5 +1164,10 @@ ReportEngine::ReportEngine(ReportEnginePrivate &dd, QObject *parent) connect(d, SIGNAL(renderFinished()), this, SIGNAL(renderFinished())); } +ScriptEngineManager*LimeReport::ReportEnginePrivate::scriptManager(){ + ScriptEngineManager::instance().setDataManager(dataManager()); + return &ScriptEngineManager::instance(); +} + }// namespace LimeReport diff --git a/limereport/lrreportengine_p.h b/limereport/lrreportengine_p.h index c8d6307..29d0aa3 100644 --- a/limereport/lrreportengine_p.h +++ b/limereport/lrreportengine_p.h @@ -78,7 +78,7 @@ public: int pageCount() {return m_pages.count();} DataSourceManager* dataManager(){return m_datasources;} ScriptEngineContext* scriptContext(){return m_scriptEngineContext;} - ScriptEngineManager* scriptManager(){return &ScriptEngineManager::instance();} + ScriptEngineManager* scriptManager(); IDataSourceManager* dataManagerIntf(){return m_datasources;} IScriptEngineManager* scriptManagerIntf(){ diff --git a/limereport/lrreportrender.cpp b/limereport/lrreportrender.cpp index 5af0b3d..710b5f5 100644 --- a/limereport/lrreportrender.cpp +++ b/limereport/lrreportrender.cpp @@ -982,6 +982,8 @@ bool ReportRender::registerBand(BandDesignIntf *band, bool registerInChildren) if (band->isData()) m_renderedDataBandCount++; band->setObjectName(band->objectName()+QString::number(++m_curentNameIndex)); renameChildItems(band); + if (m_lastDataBand) + emit m_lastDataBand->bandRegistred(); return true; } else return false; } @@ -1065,7 +1067,7 @@ BandDesignIntf *ReportRender::renderData(BandDesignIntf *patternBand) { BandDesignIntf* bandClone = dynamic_cast(patternBand->cloneItem(PreviewMode)); - m_scriptEngineContext->baseDesignIntfToScript(bandClone); + m_scriptEngineContext->baseDesignIntfToScript(patternBand->page()->pageItem()->objectName(), bandClone); emit(patternBand->beforeRender()); if (patternBand->isFooter()){ @@ -1078,7 +1080,7 @@ BandDesignIntf *ReportRender::renderData(BandDesignIntf *patternBand) bandClone->updateItemSize(m_datasources); - m_scriptEngineContext->baseDesignIntfToScript(bandClone); + //m_scriptEngineContext->baseDesignIntfToScript(bandClone); emit(patternBand->afterData()); return bandClone; @@ -1101,7 +1103,7 @@ void ReportRender::startNewPage(bool isFirst) initColumns(); initRenderPage(); - m_scriptEngineContext->baseDesignIntfToScript(m_renderPageItem); + m_scriptEngineContext->baseDesignIntfToScript(m_renderPageItem->patternName(), m_renderPageItem); m_renderPageItem->setObjectName(QLatin1String("ReportPage")+QString::number(m_pageCount)); m_maxHeightByColumn[m_currentColumn]=m_renderPageItem->pageRect().height(); @@ -1110,7 +1112,11 @@ void ReportRender::startNewPage(bool isFirst) emit m_patternPageItem->beforeRender(); - if (isFirst) renderReportHeader(m_patternPageItem, BeforePageHeader); + if (isFirst) { + renderReportHeader(m_patternPageItem, BeforePageHeader); + emit m_patternPageItem->beforeFirstPageRendered(); + } + renderPageHeader(m_patternPageItem); m_pageFooterHeight = calcPageFooterHeight(m_patternPageItem); @@ -1303,6 +1309,7 @@ void ReportRender::savePage(bool isLast) moveTearOffBand(); emit m_patternPageItem->afterRender(); + if (isLast) emit m_patternPageItem->afterLastPageRendered(); } diff --git a/limereport/lrscriptenginemanager.cpp b/limereport/lrscriptenginemanager.cpp index 11b4cbc..5f18bc8 100644 --- a/limereport/lrscriptenginemanager.cpp +++ b/limereport/lrscriptenginemanager.cpp @@ -201,6 +201,8 @@ ScriptEngineManager::~ScriptEngineManager() { delete m_model; m_model = 0; + delete m_tableOfContens; + m_tableOfContens = 0; delete m_scriptEngine; } @@ -342,8 +344,10 @@ void ScriptEngineManager::setDataManager(DataSourceManager *dataManager){ .arg(LimeReport::Const::FUNCTION_MANAGER_NAME) ); addFunction(describer); - } + ICallbackDatasource* tableOfContens = m_dataManager->createCallbackDatasource("tableofcontens"); + connect(tableOfContens, SIGNAL(getCallbackData(LimeReport::CallbackInfo,QVariant&)), + m_tableOfContens, SLOT(slotOneSlotDS(LimeReport::CallbackInfo,QVariant&))); } } } @@ -534,6 +538,11 @@ QVariant ScriptEngineManager::evaluateScript(const QString& script){ return QVariant(); } +void ScriptEngineManager::addTableOfContensItem(const QString& content, int pageNumber, int indent) +{ + m_tableOfContens->setItem(content, pageNumber, indent); +} + void ScriptEngineManager::updateModel() { @@ -740,6 +749,36 @@ bool ScriptEngineManager::createGetFieldFunction() return addFunction(fd); } +bool ScriptEngineManager::createAddTableOfContensItemFunction() +{ + JSFunctionDesc fd; + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory(tr("GENERAL")); + fd.setName("addTableOfContensItem"); + fd.setDescription("addTableOfContensItem(\""+tr("Content")+"\", \""+tr("Page Number")+", \""+tr("Indent")+"\")"); + fd.setScriptWrapper(QString("function addTableOfContensItem(content, pageNumber, indent){" + "return %1.addTableOfContensItem(content, pageNumber, indent);}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + +bool ScriptEngineManager::createClearTableOfContensFunction() +{ + JSFunctionDesc fd; + fd.setManager(m_functionManager); + fd.setManagerName(LimeReport::Const::FUNCTION_MANAGER_NAME); + fd.setCategory(tr("GENERAL")); + fd.setName("clearTableOfContens"); + fd.setDescription("clearTableOfContens()"); + fd.setScriptWrapper(QString("function clearTableOfContens(){" + "return %1.clearTableOfContens();}" + ).arg(LimeReport::Const::FUNCTION_MANAGER_NAME) + ); + return addFunction(fd); +} + ScriptEngineManager::ScriptEngineManager() :m_model(0), m_dataManager(0) { @@ -770,8 +809,11 @@ ScriptEngineManager::ScriptEngineManager() QScriptValue fontConstructor = m_scriptEngine->newFunction(QFontPrototype::constructorQFont, fontProto); m_scriptEngine->globalObject().setProperty("QFont", fontConstructor); #endif - m_model = new ScriptEngineModel(this); + createAddTableOfContensItemFunction(); + createClearTableOfContensFunction(); + m_model = new ScriptEngineModel(this); + m_tableOfContens = new TableOfContens(); } bool ScriptExtractor::parse() @@ -1118,10 +1160,9 @@ QString ScriptEngineContext::getNewDialogName() #endif -void ScriptEngineContext::baseDesignIntfToScript(BaseDesignIntf* item) +void ScriptEngineContext::baseDesignIntfToScript(const QString& pageName, BaseDesignIntf* item) { if ( item ) { - if (item->metaObject()->indexOfSignal("beforeRender()")!=-1) item->disconnect(SIGNAL(beforeRender())); if (item->metaObject()->indexOfSignal("afterData()")!=-1) @@ -1134,9 +1175,9 @@ void ScriptEngineContext::baseDesignIntfToScript(BaseDesignIntf* item) #ifdef USE_QJSENGINE //sItem = engine->newQObject(item); ScriptValueType sItem = getCppOwnedJSValue(*engine, item); - engine->globalObject().setProperty(item->patternName(), sItem); + engine->globalObject().setProperty(pageName+"_"+item->patternName(), sItem); #else - ScriptValueType sItem = engine->globalObject().property(item->patternName()); + ScriptValueType sItem = engine->globalObject().property(pageName+"_"+item->patternName()); if (sItem.isValid()){ engine->newQObject(sItem, item); } else { @@ -1145,7 +1186,7 @@ void ScriptEngineContext::baseDesignIntfToScript(BaseDesignIntf* item) } #endif foreach(BaseDesignIntf* child, item->childBaseItems()){ - baseDesignIntfToScript(child); + baseDesignIntfToScript(pageName, child); } } } @@ -1179,6 +1220,7 @@ void ScriptEngineContext::initDialogs(){ bool ScriptEngineContext::runInitScript(){ ScriptEngineType* engine = ScriptEngineManager::instance().scriptEngine(); + ScriptEngineManager::instance().clearTableOfContens(); #ifndef USE_QJSENGINE engine->pushContext(); #endif @@ -1376,6 +1418,16 @@ QVariant ScriptFunctionsManager::getField(const QString &field) return dm->fieldData(field); } +void ScriptFunctionsManager::addTableOfContensItem(const QString& content, int pageNumber, int indent) +{ + scriptEngineManager()->addTableOfContensItem(content, pageNumber, indent); +} + +void ScriptFunctionsManager::clearTableOfContens() +{ + scriptEngineManager()->clearTableOfContens(); +} + #ifdef USE_QJSENGINE QFont ScriptFunctionsManager::font(const QString &family, int pointSize, bool bold, bool italic, bool underLine) { @@ -1413,5 +1465,68 @@ void ScriptFunctionsManager::setScriptEngineManager(ScriptEngineManager *scriptE m_scriptEngineManager = scriptEngineManager; } +TableOfContens::~TableOfContens() +{ + clear(); +} + +void TableOfContens::setItem(const QString& content, int pageNumber, int indent) +{ + ContentItem * item = 0; + if (m_hash.contains(content)){ + ContentItem* item = m_hash.value(content); + item->pageNumber = pageNumber; + item->indent = indent; + } else { + ContentItem* item = new ContentItem; + item->content = content; + item->pageNumber = pageNumber; + item->indent = indent; + + m_tableOfContens.append(item); + m_hash.insert(content, item); + } + +} + +void TableOfContens::slotOneSlotDS(CallbackInfo info, QVariant& data) +{ + QStringList columns; + columns << "Content" << "Page number"; + + switch (info.dataType) { + case LimeReport::CallbackInfo::RowCount: + data = m_tableOfContens.count(); + break; + case LimeReport::CallbackInfo::ColumnCount: + data = columns.size(); + break; + case LimeReport::CallbackInfo::ColumnHeaderData: { + data = columns.at(info.index); + break; + } + case LimeReport::CallbackInfo::ColumnData: + if (info.index < m_tableOfContens.count()){ + ContentItem* item = m_tableOfContens.at(info.index); + if (info.columnName == "Content") + data = item->content.rightJustified(item->indent+item->content.size()); + else + data = QString::number(item->pageNumber); + } + break; + default: break; + } +} + +void LimeReport::TableOfContens::clear(){ + + m_hash.clear(); + foreach(ContentItem* item, m_tableOfContens){ + delete item; + } + m_tableOfContens.clear(); + +} + } //namespace LimeReport diff --git a/limereport/lrscriptenginemanager.h b/limereport/lrscriptenginemanager.h index 2e5786f..7e46490 100644 --- a/limereport/lrscriptenginemanager.h +++ b/limereport/lrscriptenginemanager.h @@ -49,6 +49,7 @@ #include "base/lrsingleton.h" #include "lrglobal.h" #include "lrscriptenginemanagerintf.h" +#include "lrcallbackdatasourceintf.h" #include "lrcollection.h" namespace LimeReport{ @@ -56,6 +57,26 @@ namespace LimeReport{ class DataSourceManager; class BaseDesignIntf; +struct ContentItem { + QString content; + int indent; + int pageNumber; +}; + +class TableOfContens : public QObject{ + Q_OBJECT +public: + ~TableOfContens(); + void setItem(const QString& content, int pageNumber, int indent = 0); + void clear(); +private slots: + void slotOneSlotDS(LimeReport::CallbackInfo info, QVariant &data); +private: + QVector m_tableOfContens; + QHash m_hash; +}; + + struct ScriptFunctionDesc{ enum FuncType {Native,Script}; ScriptValueType scriptValue; @@ -156,7 +177,7 @@ public: QString getNewDialogName(); void initDialogs(); #endif - void baseDesignIntfToScript(BaseDesignIntf *item); + void baseDesignIntfToScript(const QString& pageName, BaseDesignIntf *item); void clear(); QString initScript() const; void setInitScript(const QString& initScript); @@ -242,7 +263,9 @@ public: Q_INVOKABLE void setVariable(const QString& name, QVariant value); Q_INVOKABLE QVariant getVariable(const QString& name); Q_INVOKABLE QVariant getField(const QString& field); - Q_INVOKABLE QVariant color(const QString& color){ return QColor(color);} + Q_INVOKABLE QVariant color(const QString& color){ return QColor(color);} + Q_INVOKABLE void addTableOfContensItem(const QString& content, int pageNumber, int indent = 0); + Q_INVOKABLE void clearTableOfContens(); #ifdef USE_QJSENGINE Q_INVOKABLE QFont font(const QString& family, int pointSize = -1, bool bold = false, bool italic = false, bool underLine = false); #endif @@ -282,6 +305,8 @@ public: QString expandDataFields(QString context, ExpandType expandType, QVariant &varValue, QObject* reportItem); QString expandScripts(QString context, QVariant &varValue, QObject* reportItem); QVariant evaluateScript(const QString &script); + void addTableOfContensItem(const QString& content, int pageNumber, int indent); + void clearTableOfContens(){ m_tableOfContens->clear(); } protected: void updateModel(); @@ -300,6 +325,8 @@ private: bool createSetVariableFunction(); bool createGetVariableFunction(); bool createGetFieldFunction(); + bool createAddTableOfContensItemFunction(); + bool createClearTableOfContensFunction(); private: ScriptEngineManager(); ScriptEngineType* m_scriptEngine; @@ -309,6 +336,7 @@ private: ScriptEngineContext* m_context; DataSourceManager* m_dataManager; ScriptFunctionsManager* m_functionManager; + TableOfContens* m_tableOfContens; }; class ScriptExtractor diff --git a/limereport/objectinspector/editors/lrbuttonlineeditor.cpp b/limereport/objectinspector/editors/lrbuttonlineeditor.cpp index 4f1bc64..8459594 100644 --- a/limereport/objectinspector/editors/lrbuttonlineeditor.cpp +++ b/limereport/objectinspector/editors/lrbuttonlineeditor.cpp @@ -131,6 +131,7 @@ void ButtonLineEditor::editingByEditorFinished() { setText(qobject_cast(sender())->text()); m_lineEdit->setFocus(); + emit editingFinished(); } } //namespace LimeReport