diff --git a/limereport/exporters/lrpdfexporter.cpp b/limereport/exporters/lrpdfexporter.cpp new file mode 100644 index 0000000..d97bf7b --- /dev/null +++ b/limereport/exporters/lrpdfexporter.cpp @@ -0,0 +1,38 @@ +#include + +#include "lrpdfexporter.h" +#include "lrexportersfactory.h" +#include "lrreportengine_p.h" + +namespace{ + +LimeReport::ReportExporterInterface* createPDFExporter(LimeReport::ReportEnginePrivate* parent){ + return new LimeReport::PDFExporter(parent); +} + +bool VARIABLE_IS_NOT_USED registred = LimeReport::ExportersFactory::instance().registerCreator("PDF", LimeReport::ExporterAttribs(QObject::tr("Export to PDF"), "PDFExporter"), createPDFExporter); + +} + +namespace LimeReport{ + +PDFExporter::PDFExporter(ReportEnginePrivate *parent) : QObject(parent), m_reportEngine(parent) +{} + +bool PDFExporter::exportPages(ReportPages pages, const QString &fileName, const QMap ¶ms) +{ + Q_UNUSED(params); + if (!fileName.isEmpty()){ + QPrinter printer; + printer.setOutputFileName(fileName); + printer.setOutputFormat(QPrinter::PdfFormat); + if (!pages.isEmpty()){ + m_reportEngine->printReport(pages, printer); + } + m_reportEngine->emitPrintedToPDF(fileName); + return true; + } + return false; +} + +} diff --git a/limereport/exporters/lrpdfexporter.h b/limereport/exporters/lrpdfexporter.h new file mode 100644 index 0000000..225c80b --- /dev/null +++ b/limereport/exporters/lrpdfexporter.h @@ -0,0 +1,35 @@ +#ifndef LRPDFEXPORTER_H +#define LRPDFEXPORTER_H + +#include +#include "lrexporterintf.h" + +namespace LimeReport{ +class ReportEnginePrivate; + +class PDFExporter : public QObject, public ReportExporterInterface +{ + Q_OBJECT +public: + explicit PDFExporter(ReportEnginePrivate *parent = nullptr); + // ReportExporterInterface interface + bool exportPages(ReportPages pages, const QString &fileName, const QMap ¶ms); + QString exporterName() + { + return "PDF"; + } + QString exporterFileExt() + { + return "pdf"; + } + QString hint() + { + return tr("Export to PDF"); + } +private: + ReportEnginePrivate* m_reportEngine; +}; + +} //namespace LimeReport + +#endif // LRPDFEXPORTER_H diff --git a/limereport/items/lrhorizontallayout.h b/limereport/items/lrhorizontallayout.h index fa5edf3..1e4c536 100644 --- a/limereport/items/lrhorizontallayout.h +++ b/limereport/items/lrhorizontallayout.h @@ -48,6 +48,7 @@ public: ~HorizontalLayout(); BaseDesignIntf *createSameTypeItem(QObject *owner = 0, QGraphicsItem *parent = 0); bool isSplittable() const { return true;} + bool canContainChildren() const { return true;} protected: void updateLayoutSize(); diff --git a/limereport/limereport.pri b/limereport/limereport.pri index df07a93..5e086a7 100644 --- a/limereport/limereport.pri +++ b/limereport/limereport.pri @@ -66,7 +66,8 @@ SOURCES += \ $$REPORT_PATH/lrcolorindicator.cpp \ $$REPORT_PATH/items/lrchartitem.cpp \ $$REPORT_PATH/items/lrchartitemeditor.cpp \ - $$REPORT_PATH/lrreporttranslation.cpp + $$REPORT_PATH/lrreporttranslation.cpp \ + $$REPORT_PATH/exporters/lrpdfexporter.cpp contains(CONFIG, staticlib){ SOURCES += $$REPORT_PATH/lrfactoryinitializer.cpp @@ -144,7 +145,10 @@ HEADERS += \ $$REPORT_PATH/items/editors/lrtextalignmenteditorwidget.h \ $$REPORT_PATH/items/editors/lritemsborderseditorwidget.h \ $$REPORT_PATH/lrreporttranslation.h \ - $$REPORT_PATH/lrreportdesignwindowintrerface.h + $$REPORT_PATH/lrreportdesignwindowintrerface.h \ + $$REPORT_PATH/lrexporterintf.h \ + $$REPORT_PATH/lrexportersfactory.h \ + $$REPORT_PATH/exporters/lrpdfexporter.h contains(CONFIG, staticlib){ HEADERS += $$REPORT_PATH/lrfactoryinitializer.h diff --git a/limereport/lrbanddesignintf.cpp b/limereport/lrbanddesignintf.cpp index e983b41..67d78c0 100644 --- a/limereport/lrbanddesignintf.cpp +++ b/limereport/lrbanddesignintf.cpp @@ -1015,12 +1015,11 @@ void BandDesignIntf::setKeepFooterTogether(bool value) } } - void BandDesignIntf::updateItemSize(DataSourceManager* dataManager, RenderPass pass, int maxHeight) { qreal spaceBorder=0; if (keepBottomSpaceOption()) spaceBorder = bottomSpace(); - spaceBorder = spaceBorder>0 ? spaceBorder : 0; + spaceBorder = spaceBorder > 0 ? spaceBorder : 0; if (borderLines()!=0){ spaceBorder += borderLineSize(); } diff --git a/limereport/lrbanddesignintf.h b/limereport/lrbanddesignintf.h index f3750b0..c62fb1c 100644 --- a/limereport/lrbanddesignintf.h +++ b/limereport/lrbanddesignintf.h @@ -234,7 +234,7 @@ public: bool startFromNewPage() const; void setStartFromNewPage(bool startFromNewPage); - bool canContainChildren(){ return true;} + bool canContainChildren() const{ return true;} bool printAlways() const; void setPrintAlways(bool printAlways); bool repeatOnEachRow() const; diff --git a/limereport/lrbasedesignintf.cpp b/limereport/lrbasedesignintf.cpp index 9d0d98d..1ad1ee5 100644 --- a/limereport/lrbasedesignintf.cpp +++ b/limereport/lrbasedesignintf.cpp @@ -227,6 +227,16 @@ qreal BaseDesignIntf::getItemPosY() return y() / mmFactor(); } +qreal BaseDesignIntf::getAbsolutePosX() +{ + return calcAbsolutePosX(0,this); +} + +qreal BaseDesignIntf::getAbsolutePosY() +{ + return calcAbsolutePosY(0,this); +} + QString BaseDesignIntf::setItemPosX(qreal xValue) { setItemPos(xValue * mmFactor(),y()); @@ -1485,6 +1495,24 @@ void BaseDesignIntf::addChildItems(QList* list){ } } +qreal BaseDesignIntf::calcAbsolutePosY(qreal currentOffset, BaseDesignIntf *item) +{ + BaseDesignIntf* parent = dynamic_cast(item->parent()); + if (parent) + return calcAbsolutePosY(currentOffset + item->getItemPosY(), parent); + else + return currentOffset + item->getItemPosY(); +} + +qreal BaseDesignIntf::calcAbsolutePosX(qreal currentOffset, BaseDesignIntf *item) +{ + BaseDesignIntf* parent = dynamic_cast(item->parent()); + if (parent) + return calcAbsolutePosX(currentOffset + item->getItemPosX(), parent); + else + return currentOffset + item->getItemPosX(); +} + QList BaseDesignIntf::allChildBaseItems() { QList resList; diff --git a/limereport/lrbasedesignintf.h b/limereport/lrbasedesignintf.h index af80022..df37850 100644 --- a/limereport/lrbasedesignintf.h +++ b/limereport/lrbasedesignintf.h @@ -268,7 +268,7 @@ public: QColor borderColor() const; void setBorderColor(const QColor &borderColor); void setItemVisible(const bool& value); - virtual bool canContainChildren(){ return false;} + virtual bool canContainChildren() const { return false;} ReportSettings* reportSettings() const; void setReportSettings(ReportSettings *reportSettings); void setZValueProperty(qreal value); @@ -288,6 +288,8 @@ public: Q_INVOKABLE qreal getItemHeight(); Q_INVOKABLE qreal getItemPosX(); Q_INVOKABLE qreal getItemPosY(); + Q_INVOKABLE qreal getAbsolutePosX(); + Q_INVOKABLE qreal getAbsolutePosY(); Q_INVOKABLE QString setItemPosX(qreal xValue); Q_INVOKABLE QString setItemPosY(qreal yValue); @@ -352,7 +354,8 @@ protected: virtual void processPopUpAction(QAction* action){Q_UNUSED(action)} void addChildItems(QList* list); - + qreal calcAbsolutePosY(qreal currentOffset, BaseDesignIntf* item); + qreal calcAbsolutePosX(qreal currentOffset, BaseDesignIntf* item); private: void updateSelectionMarker(); int resizeDirectionFlags(QPointF position); @@ -410,7 +413,7 @@ private: QString m_patternName; BaseDesignIntf* m_patternItem; bool m_fillInSecondPass; - bool m_watermark; + bool m_watermark; signals: void geometryChanged(QObject* object, QRectF newGeometry, QRectF oldGeometry); diff --git a/limereport/lrdesignelementsfactory.h b/limereport/lrdesignelementsfactory.h index 9a647a2..986c354 100644 --- a/limereport/lrdesignelementsfactory.h +++ b/limereport/lrdesignelementsfactory.h @@ -31,7 +31,6 @@ #define LRDESIGNELEMENTSFACTORY_H #include "lrbanddesignintf.h" -//#include "lrpageheader.h" #include "lrattribsabstractfactory.h" #include "lrsimpleabstractfactory.h" #include "lrsingleton.h" diff --git a/limereport/lrexporterintf.h b/limereport/lrexporterintf.h new file mode 100644 index 0000000..bbeb043 --- /dev/null +++ b/limereport/lrexporterintf.h @@ -0,0 +1,21 @@ +#ifndef LREXPORTERINTF_H +#define LREXPORTERINTF_H + +#include +#include +#include +#include "lrpageitemdesignintf.h" + +namespace LimeReport { + +class ReportExporterInterface { +public: + virtual ~ReportExporterInterface(){} + virtual bool exportPages(LimeReport::ReportPages pages, const QString& fileName, const QMap& params = QMap()) = 0; + virtual QString exporterName() = 0; + virtual QString exporterFileExt() = 0; + virtual QString hint() = 0; +}; + +} // namespace LimeReport +#endif // LREXPORTERINTF_H diff --git a/limereport/lrexportersfactory.h b/limereport/lrexportersfactory.h new file mode 100644 index 0000000..bbb5e56 --- /dev/null +++ b/limereport/lrexportersfactory.h @@ -0,0 +1,34 @@ +#ifndef LREXPORTERSFACTORY_H +#define LREXPORTERSFACTORY_H + +#include "lrattribsabstractfactory.h" +#include "lrexporterintf.h" + +namespace LimeReport{ + +typedef ReportExporterInterface* (*CreateExporter)(ReportEnginePrivate* parent); + +struct ExporterAttribs{ + QString m_alias; + QString m_tag; + ExporterAttribs(){} + ExporterAttribs(const QString& alias, const QString& tag):m_alias(alias),m_tag(tag){} + bool operator==( const ExporterAttribs &right) const { + return (m_alias==right.m_alias) && (m_tag==right.m_tag); + } +}; + +class ExportersFactory : public AttribsAbstractFactory +{ +private: + friend class Singleton; +private: + ExportersFactory(){} + ~ExportersFactory(){} + ExportersFactory(const ExportersFactory&){} + ExportersFactory& operator = (const ExportersFactory&){return *this;} +}; + +} // namespace LimeReport + +#endif // LREXPORTERSFACTORY_H diff --git a/limereport/lrfactoryinitializer.cpp b/limereport/lrfactoryinitializer.cpp index 8f11ec8..f91e7e6 100644 --- a/limereport/lrfactoryinitializer.cpp +++ b/limereport/lrfactoryinitializer.cpp @@ -41,6 +41,10 @@ #include "serializators/lrxmlqrectserializator.h" #include "serializators/lrxmlserializatorsfactory.h" +#include "lrexportersfactory.h" +#include "lrexporterintf.h" +#include "exporters/lrpdfexporter.h" + void initResources(){ Q_INIT_RESOURCE(report); #ifdef HAVE_REPORT_DESIGNER @@ -442,4 +446,17 @@ void initSerializators() XMLAbstractSerializatorFactory::instance().registerCreator("QRectF", createQRectSerializator); } +LimeReport::ReportExporterInterface* createPDFExporter(ReportEnginePrivate* parent){ + return new LimeReport::PDFExporter(parent); +} + +void initExporters() +{ + ExportersFactory::instance().registerCreator( + "PDF", + LimeReport::ExporterAttribs(QObject::tr("Export to PDF"), "PDFExporter"), + createPDFExporter + ); +} + } //namespace LimeReport diff --git a/limereport/lrfactoryinitializer.h b/limereport/lrfactoryinitializer.h index 679d657..8810e55 100644 --- a/limereport/lrfactoryinitializer.h +++ b/limereport/lrfactoryinitializer.h @@ -3,4 +3,5 @@ namespace LimeReport{ void initReportItems(); void initObjectInspectorProperties(); void initSerializators(); + void initExporters(); } // namespace LimeReport diff --git a/limereport/lrpageitemdesignintf.h b/limereport/lrpageitemdesignintf.h index 4204d06..abcdb72 100644 --- a/limereport/lrpageitemdesignintf.h +++ b/limereport/lrpageitemdesignintf.h @@ -120,7 +120,7 @@ public: bool oldPrintMode() const; void setOldPrintMode(bool oldPrintMode); - bool canContainChildren(){ return true;} + bool canContainChildren() const{ return true;} bool resetPageNumber() const; void setResetPageNumber(bool resetPageNumber); void updateSubItemsSize(RenderPass pass, DataSourceManager *dataManager); diff --git a/limereport/lrpreviewreportwidget.cpp b/limereport/lrpreviewreportwidget.cpp index 5ef2693..756a4ac 100644 --- a/limereport/lrpreviewreportwidget.cpp +++ b/limereport/lrpreviewreportwidget.cpp @@ -13,6 +13,9 @@ #include "lrpreviewreportwidget_p.h" #include "serializators/lrxmlwriter.h" +#include "lrexportersfactory.h" + + namespace LimeReport { bool PreviewReportWidgetPrivate::pageIsVisible(){ @@ -60,6 +63,11 @@ PageItemDesignIntf::Ptr PreviewReportWidgetPrivate::currentPage() else return PageItemDesignIntf::Ptr(0); } +QList PreviewReportWidgetPrivate::aviableExporters() +{ + return ExportersFactory::instance().map().keys(); +} + PreviewReportWidget::PreviewReportWidget(ReportEngine *report, QWidget *parent) : QWidget(parent), ui(new Ui::PreviewReportWidget), d_ptr(new PreviewReportWidgetPrivate(this)) @@ -86,6 +94,31 @@ PreviewReportWidget::~PreviewReportWidget() delete ui; } +QList PreviewReportWidget::aviableExporters() +{ + return d_ptr->aviableExporters(); +} + +bool PreviewReportWidget::exportReport(QString exporterName, const QMap ¶ms) +{ + if (ExportersFactory::instance().map().contains(exporterName)){ + + ReportExporterInterface* e = ExportersFactory::instance().objectCreator(exporterName)(d_ptr->m_report); + + QString filter = QString("%1 (*.%2)").arg(e->exporterName()).arg(e->exporterFileExt()); + QString fileName = QFileDialog::getSaveFileName(this,tr("%1 file name").arg(e->exporterName()),"",filter); + if (!fileName.isEmpty()){ + QFileInfo fi(fileName); + if (fi.suffix().isEmpty()) + fileName += QString(".%1").arg(e->exporterFileExt()); + bool result = e->exportPages(d_ptr->m_reportPages, fileName, params); + delete e; + return result; + } + } + return false; +} + void PreviewReportWidget::initPreview() { if (ui->graphicsView->scene()!=d_ptr->m_previewPage) @@ -185,22 +218,11 @@ void PreviewReportWidget::print() void PreviewReportWidget::printToPDF() { - 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); - if (!d_ptr->m_reportPages.isEmpty()){ - ReportEnginePrivate::printReport(d_ptr->m_reportPages,printer); - } + if (!d_ptr->m_reportPages.isEmpty()){ + exportReport("PDF"); foreach(PageItemDesignIntf::Ptr pageItem, d_ptr->m_reportPages){ d_ptr->m_previewPage->reactivatePageItem(pageItem); } - d_ptr->m_report->emitPrintedToPDF(fileName); } } diff --git a/limereport/lrpreviewreportwidget.h b/limereport/lrpreviewreportwidget.h index e33f75f..c1b571d 100644 --- a/limereport/lrpreviewreportwidget.h +++ b/limereport/lrpreviewreportwidget.h @@ -22,7 +22,9 @@ class LIMEREPORT_EXPORT PreviewReportWidget : public QWidget friend class PreviewReportWidgetPrivate; public: explicit PreviewReportWidget(ReportEngine *report, QWidget *parent = 0); - ~PreviewReportWidget(); + ~PreviewReportWidget(); + QList aviableExporters(); + bool exportReport(QString exporterName, const QMap& params = QMap()); public slots: void refreshPages(); void zoomIn(); diff --git a/limereport/lrpreviewreportwidget_p.h b/limereport/lrpreviewreportwidget_p.h index 9557a5d..c7c2ce1 100644 --- a/limereport/lrpreviewreportwidget_p.h +++ b/limereport/lrpreviewreportwidget_p.h @@ -20,6 +20,7 @@ public: QRectF calcPageShift(); void setPages( ReportPages pages); PageItemDesignIntf::Ptr currentPage(); + QList aviableExporters(); public: PageDesignIntf* m_previewPage; ReportPages m_reportPages; diff --git a/limereport/lrpreviewreportwindow.ui b/limereport/lrpreviewreportwindow.ui index 50487cb..5c6cc24 100644 --- a/limereport/lrpreviewreportwindow.ui +++ b/limereport/lrpreviewreportwindow.ui @@ -35,7 +35,7 @@ 0 0 800 - 19 + 20 @@ -283,6 +283,8 @@ + + diff --git a/limereport/lrreportengine.cpp b/limereport/lrreportengine.cpp index 45ff9f8..c9b44b1 100644 --- a/limereport/lrreportengine.cpp +++ b/limereport/lrreportengine.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include "time.h" @@ -55,6 +56,8 @@ #include "lrpreviewreportwindow.h" #include "lrpreviewreportwidget.h" #include "lrpreviewreportwidget_p.h" +#include "lrexporterintf.h" +#include "lrexportersfactory.h" #ifdef BUILD_WITH_EASY_PROFILER #include "easy/profiler.h" @@ -63,7 +66,6 @@ # define EASY_END_BLOCK #endif - #ifdef HAVE_STATIC_BUILD #include "lrfactoryinitializer.h" #endif @@ -102,7 +104,6 @@ ReportEnginePrivate::ReportEnginePrivate(QObject *parent) : connect(m_datasources,SIGNAL(loadCollectionFinished(QString)),this,SLOT(slotDataSourceCollectionLoaded(QString))); connect(m_fileWatcher,SIGNAL(fileChanged(const QString &)),this,SLOT(slotLoadFromFile(const QString &))); -#ifndef HAVE_REPORT_DESIGNER QDir pluginsDir = QCoreApplication::applicationDirPath(); pluginsDir.cd("../lib" ); if (!pluginsDir.exists()){ @@ -113,13 +114,15 @@ ReportEnginePrivate::ReportEnginePrivate(QObject *parent) : foreach( const QString& pluginName, pluginsDir.entryList( QDir::Files ) ) { QPluginLoader loader( pluginsDir.absoluteFilePath( pluginName ) ); if( loader.load() ) { +#ifndef HAVE_REPORT_DESIGNER if( LimeReportDesignerPluginInterface* designerPlugin = qobject_cast< LimeReportDesignerPluginInterface* >( loader.instance() ) ) { m_designerFactory = designerPlugin; break; } - } - } #endif + } + } + } ReportEnginePrivate::~ReportEnginePrivate() @@ -476,17 +479,31 @@ void ReportEnginePrivate::printToFile(const QString &fileName) bool ReportEnginePrivate::printToPDF(const QString &fileName) { - if (!fileName.isEmpty()){ - QFileInfo fi(fileName); - QString fn = fileName; - if (fi.suffix().isEmpty()) - fn+=".pdf"; - QPrinter printer; - printer.setOutputFileName(fn); - printer.setOutputFormat(QPrinter::PdfFormat); - bool success = printReport(&printer); - if(success) emitPrintedToPDF(fileName); - return success; + return exportReport("PDF"); +} + +bool ReportEnginePrivate::exportReport(QString exporterName, const QString &fileName, const QMap ¶ms) +{ + QString fn = fileName; + if (ExportersFactory::instance().map().contains(exporterName)){ + ReportExporterInterface* e = ExportersFactory::instance().objectCreator(exporterName)(this); + if (fn.isEmpty()){ + QString filter = QString("%1 (*.%2)").arg(e->exporterName()).arg(e->exporterFileExt()); + QString fn = QFileDialog::getSaveFileName(0,tr("%1 file name").arg(e->exporterName()),"",filter); + if (!fn.isEmpty()){ + QFileInfo fi(fn); + if (fi.suffix().isEmpty()) + fn += QString(".%1").arg(e->exporterFileExt()); + + bool designTime = dataManager()->designTime(); + dataManager()->setDesignTime(false); + ReportPages pages = renderToPages(); + dataManager()->setDesignTime(designTime); + bool result = e->exportPages(pages, fn, params); + delete e; + return result; + } + } } return false; } @@ -1221,6 +1238,12 @@ bool ReportEngine::printToPDF(const QString &fileName) return d->printToPDF(fileName); } +bool ReportEngine::exportReport(QString exporterName, const QString &fileName, const QMap ¶ms) +{ + Q_D(ReportEngine); + return d->exportReport(exporterName, fileName, params); +} + void ReportEngine::previewReport(PreviewHints hints) { Q_D(ReportEngine); diff --git a/limereport/lrreportengine.h b/limereport/lrreportengine.h index a319dd1..e3d4ec4 100644 --- a/limereport/lrreportengine.h +++ b/limereport/lrreportengine.h @@ -84,6 +84,7 @@ public: void printToFile(const QString& fileName); PageDesignIntf *createPreviewScene(QObject *parent = 0); bool printToPDF(const QString& fileName); + bool exportReport(QString exporterName, const QString &fileName = "", const QMap& params = QMap()); void previewReport(PreviewHints hints = PreviewBarsUserSetting); void designReport(); ReportDesignWindowInterface* getDesignerWindow(); diff --git a/limereport/lrreportengine_p.h b/limereport/lrreportengine_p.h index ea2ff2a..4756b20 100644 --- a/limereport/lrreportengine_p.h +++ b/limereport/lrreportengine_p.h @@ -48,11 +48,13 @@ class QFileSystemWatcher; + namespace LimeReport{ class PageDesignIntf; class PrintRange; class ReportDesignWindow; +class ReportExporterInterface; class ReportEnginePrivateInterface { public: @@ -132,6 +134,7 @@ public: bool printPages(ReportPages pages, QPrinter *printer); void printToFile(const QString& fileName); bool printToPDF(const QString& fileName); + bool exportReport(QString exporterName, const QString &fileName = "", const QMap& params = QMap()); void previewReport(PreviewHints hints = PreviewBarsUserSetting); ReportDesignWindowInterface* getDesignerWindow(); @@ -267,6 +270,7 @@ private: LimeReportDesignerPluginInterface* m_designerFactory; QString m_styleSheet; QLocale::Language m_currentDesignerLanguage; + QMap exporters; }; }