diff --git a/demo/r1/lr1.ico b/demo/r1/lr1.ico new file mode 100644 index 0000000..2eba2a4 Binary files /dev/null and b/demo/r1/lr1.ico differ diff --git a/demo/r1/lr6.ico b/demo/r1/lr6.ico new file mode 100644 index 0000000..6bd0818 Binary files /dev/null and b/demo/r1/lr6.ico differ diff --git a/demo/r1/mainwindow.cpp b/demo/r1/mainwindow.cpp index 2926572..cb28e42 100644 --- a/demo/r1/mainwindow.cpp +++ b/demo/r1/mainwindow.cpp @@ -65,7 +65,8 @@ MainWindow::MainWindow(QWidget *parent) : m_customers->first(); m_orders = new QSqlQuery(m_db); m_orders->prepare("Select * from orders where CustomerID = :id"); - m_orders->bindValue(":id",m_customers->value("CustomerID")); + int index = m_customers->record().indexOf("CustomerID"); + m_orders->bindValue(":id",m_customers->value(index)); m_orders->exec(); }; } @@ -160,7 +161,7 @@ void MainWindow::prepareData(QSqlQuery* ds, LimeReport::CallbackInfo info, QVari data = ds->record().fieldName(info.index); break; case LimeReport::CallbackInfo::ColumnData: - data = ds->value(info.columnName); + data = ds->value(ds->record().indexOf(info.columnName)); break; } } @@ -177,7 +178,7 @@ void MainWindow::slotChangePos(const LimeReport::CallbackInfo::ChangePosType &ty if (!ds) return; if (type == LimeReport::CallbackInfo::First) result = ds->first(); else result = ds->next(); - m_orders->bindValue(":id",m_customers->value("CustomerID")); + m_orders->bindValue(":id",m_customers->value(m_customers->record().indexOf("CustomerID"))); m_orders->exec(); } diff --git a/include/lrglobal.h b/include/lrglobal.h index a701619..e0908fc 100644 --- a/include/lrglobal.h +++ b/include/lrglobal.h @@ -42,19 +42,29 @@ #endif namespace LimeReport { + +namespace Const{ + int const RESIZE_HANDLE_SIZE = 10; + int const SELECTION_PEN_SIZE = 4; + int const MINIMUM_ITEM_WIDTH = 2*RESIZE_HANDLE_SIZE; + int const MINIMUM_ITEM_HEIGHT = 2*RESIZE_HANDLE_SIZE; + double const RESIZE_ZONE_OPACITY = 0.5; + double const SELECTED_RESIZE_ZONE_OPACITY = 0.6; + Qt::GlobalColor const RESIZE_ZONE_COLOR = Qt::green; + Qt::GlobalColor const SELECTION_COLOR = Qt::red; + double const SELECTION_COLOR_OPACITY = 0.9; const qreal fontFACTOR = 3.5; const int mmFACTOR = 10; const int itemPaleteIconSize = 24; const qreal minSpaceBorder = 10; - QString extractClassName(QString className); const QString bandTAG = "band"; + const Qt::GlobalColor BAND_NAME_LABEL_COLOR = Qt::yellow; + const Qt::GlobalColor BAND_NAME_BORDER_COLOR = Qt::darkYellow; const qreal BAND_MARKER_OPACITY = 1; const qreal LAYOUT_MARKER_OPACITY = 0.3; const qreal BAND_NAME_AREA_OPACITY = 0.3; const qreal BAND_NAME_TEXT_OPACITY = 0.6; const qreal SELECTION_OPACITY = 0.3; - enum RenderPass {FirstPass, SecondPass}; - enum ArrangeType {AsNeeded, Force}; const QString FIELD_RX = "\\$D\\s*\\{\\s*([^\\s{}]*)\\s*\\}"; const QString VARIABLE_RX = "\\$V\\s*\\{\\s*([^\\s{}]*)\\s*\\}"; const QString SCRIPT_RX = "\\$S\\s*\\{(.*)\\}"; @@ -64,6 +74,10 @@ namespace LimeReport { const QString GROUP_FUNCTION_RX = "(%1\\s*"+GROUP_FUNCTION_PARAM_RX+")"; const QString GROUP_FUNCTION_NAME_RX = "%1\\s*\\((.*[^\\)])\\)"; const int SCENE_MARGIN = 50; +} + QString extractClassName(QString className); + enum RenderPass {FirstPass, SecondPass}; + enum ArrangeType {AsNeeded, Force}; class ReportError : public std::runtime_error{ public: ReportError(const QString& message):std::runtime_error(message.toStdString()){} diff --git a/include/lrreportengine.h b/include/lrreportengine.h index 924976a..7bfa6a8 100644 --- a/include/lrreportengine.h +++ b/include/lrreportengine.h @@ -37,13 +37,11 @@ #include "lrglobal.h" #include "lrdatasourcemanagerintf.h" #include "lrscriptenginemanagerintf.h" -//#include "lrreportrender.h" class QPrinter; namespace LimeReport { - class PrintRange{ public: int fromPage() const { return m_fromPage;} @@ -61,7 +59,6 @@ private: class DataSourceManager; class ReportEnginePrivate; -//class PageDesignIntf; class LIMEREPORT_EXPORT ReportEngine : public QObject{ Q_OBJECT @@ -71,9 +68,8 @@ public: explicit ReportEngine(QObject *parent = 0); ~ReportEngine(); bool printReport(QPrinter *printer=0); - //void printReport(ReportPages pages, QPrinter &printer); void printToFile(const QString& fileName); - //PageDesignIntf *createPreviewScene(QObject *parent = 0); + bool printToPDF(const QString& fileName); void previewReport(); void designReport(); void setShowProgressDialog(bool value); diff --git a/limereport.pro b/limereport.pro index e2c488b..6ae3a53 100644 --- a/limereport.pro +++ b/limereport.pro @@ -1,5 +1,5 @@ #CONFIG +=zint -QMAKE_CFLAGS += -std=c99 +#QMAKE_CFLAGS += -std=c99 #ZINT_PATH = $$PWD/../zint-2.4.3 #ZINT_VERSION = 2.4.3 #include(qzint.pri) diff --git a/report-lib.pri b/report-lib.pri index 5563ea5..86a7da7 100644 --- a/report-lib.pri +++ b/report-lib.pri @@ -2,7 +2,7 @@ QT += script xml sql REPORT_PATH = $$PWD LIMEREPORT_VERSION_MAJOR = 1 -LIMEREPORT_VERSION_MINOR = 0 +LIMEREPORT_VERSION_MINOR = 3 LIMEREPORT_VERSION_RELEASE = 1 LIMEREPORT_VERSION = '\\"$${LIMEREPORT_VERSION_MAJOR}.$${LIMEREPORT_VERSION_MINOR}.$${LIMEREPORT_VERSION_RELEASE}\\"' diff --git a/src/bands/lrdataband.cpp b/src/bands/lrdataband.cpp index eeb2412..82c5186 100644 --- a/src/bands/lrdataband.cpp +++ b/src/bands/lrdataband.cpp @@ -49,17 +49,17 @@ LimeReport::BaseDesignIntf * createFooter(QObject* owner, LimeReport::BaseDesign bool registred = LimeReport::DesignElementsFactory::instance().registerCreator( xmlTag, - LimeReport::ItemAttribs(QObject::tr("Data"),LimeReport::bandTAG), + LimeReport::ItemAttribs(QObject::tr("Data"),LimeReport::Const::bandTAG), createBand ); bool registredHeader = LimeReport::DesignElementsFactory::instance().registerCreator( xmlTagHeader, - LimeReport::ItemAttribs(QObject::tr("DataHeader"),LimeReport::bandTAG), + LimeReport::ItemAttribs(QObject::tr("DataHeader"),LimeReport::Const::bandTAG), createHeader ); bool registredFooter = LimeReport::DesignElementsFactory::instance().registerCreator( xmlTagFooter, - LimeReport::ItemAttribs(QObject::tr("DataFooter"),LimeReport::bandTAG), + LimeReport::ItemAttribs(QObject::tr("DataFooter"),LimeReport::Const::bandTAG), createFooter ); diff --git a/src/bands/lrgroupbands.cpp b/src/bands/lrgroupbands.cpp index 4e9905e..01a7856 100644 --- a/src/bands/lrgroupbands.cpp +++ b/src/bands/lrgroupbands.cpp @@ -43,7 +43,7 @@ LimeReport::BaseDesignIntf* createHeader(QObject* owner, LimeReport::BaseDesignI bool registredHeader = LimeReport::DesignElementsFactory::instance().registerCreator( xmlTagHeader, - LimeReport::ItemAttribs(QObject::tr("GroupHeader"),LimeReport::bandTAG), + LimeReport::ItemAttribs(QObject::tr("GroupHeader"),LimeReport::Const::bandTAG), createHeader ); @@ -53,7 +53,7 @@ LimeReport::BaseDesignIntf * createFooter(QObject* owner, LimeReport::BaseDesign bool registredFooter = LimeReport::DesignElementsFactory::instance().registerCreator( xmlTagFooter, - LimeReport::ItemAttribs(QObject::tr("GroupFooter"),LimeReport::bandTAG), + LimeReport::ItemAttribs(QObject::tr("GroupFooter"),LimeReport::Const::bandTAG), createFooter ); diff --git a/src/bands/lrpagefooter.cpp b/src/bands/lrpagefooter.cpp index addefe7..5974abf 100644 --- a/src/bands/lrpagefooter.cpp +++ b/src/bands/lrpagefooter.cpp @@ -40,7 +40,7 @@ LimeReport::BaseDesignIntf * createBand(QObject* owner, LimeReport::BaseDesignIn bool registred = LimeReport::DesignElementsFactory::instance().registerCreator( xmlTag, - LimeReport::ItemAttribs(QObject::tr("Page Footer"),LimeReport::bandTAG), + LimeReport::ItemAttribs(QObject::tr("Page Footer"),LimeReport::Const::bandTAG), createBand ); } diff --git a/src/bands/lrpageheader.cpp b/src/bands/lrpageheader.cpp index 5b41734..df3fa22 100644 --- a/src/bands/lrpageheader.cpp +++ b/src/bands/lrpageheader.cpp @@ -44,7 +44,7 @@ LimeReport::BaseDesignIntf * createBand(QObject* owner, LimeReport::BaseDesignIn bool registred = LimeReport::DesignElementsFactory::instance().registerCreator( xmlTag, - LimeReport::ItemAttribs(QObject::tr("Page Header"),LimeReport::bandTAG), + LimeReport::ItemAttribs(QObject::tr("Page Header"),LimeReport::Const::bandTAG), createBand ); } diff --git a/src/bands/lrreportfooter.cpp b/src/bands/lrreportfooter.cpp index 66f6694..7425bf7 100644 --- a/src/bands/lrreportfooter.cpp +++ b/src/bands/lrreportfooter.cpp @@ -40,7 +40,7 @@ LimeReport::BaseDesignIntf * createBand(QObject* owner, LimeReport::BaseDesignIn } bool registred = LimeReport::DesignElementsFactory::instance().registerCreator( xmlTag, - LimeReport::ItemAttribs(QObject::tr("Report Footer"),LimeReport::bandTAG), + LimeReport::ItemAttribs(QObject::tr("Report Footer"),LimeReport::Const::bandTAG), createBand ); } diff --git a/src/bands/lrreportheader.cpp b/src/bands/lrreportheader.cpp index aa261fc..83fc9ad 100644 --- a/src/bands/lrreportheader.cpp +++ b/src/bands/lrreportheader.cpp @@ -39,7 +39,7 @@ LimeReport::BaseDesignIntf * createBand(QObject* owner, LimeReport::BaseDesignIn } bool registred = LimeReport::DesignElementsFactory::instance().registerCreator( xmlTag, - LimeReport::ItemAttribs(QObject::tr("Report Header"),LimeReport::bandTAG), + LimeReport::ItemAttribs(QObject::tr("Report Header"),LimeReport::Const::bandTAG), createBand ); } diff --git a/src/bands/lrsubdetailband.cpp b/src/bands/lrsubdetailband.cpp index 7638c1f..2d5a0e7 100644 --- a/src/bands/lrsubdetailband.cpp +++ b/src/bands/lrsubdetailband.cpp @@ -45,7 +45,7 @@ LimeReport::BaseDesignIntf * createBand(QObject* owner, LimeReport::BaseDesignIn bool registred = LimeReport::DesignElementsFactory::instance().registerCreator( xmlTagBand, - LimeReport::ItemAttribs(QObject::tr("SubDetail"),LimeReport::bandTAG), + LimeReport::ItemAttribs(QObject::tr("SubDetail"),LimeReport::Const::bandTAG), createBand ); @@ -55,7 +55,7 @@ LimeReport::BaseDesignIntf * createHeader(QObject* owner, LimeReport::BaseDesign bool registredHeader = LimeReport::DesignElementsFactory::instance().registerCreator( xmlTagHeader, - LimeReport::ItemAttribs(QObject::tr("SubDetailHeader"),LimeReport::bandTAG), + LimeReport::ItemAttribs(QObject::tr("SubDetailHeader"),LimeReport::Const::bandTAG), createHeader ); @@ -65,7 +65,7 @@ LimeReport::BaseDesignIntf * createFooter(QObject* owner, LimeReport::BaseDesign bool registredFooter = LimeReport::DesignElementsFactory::instance().registerCreator( xmlTagFooter, - LimeReport::ItemAttribs(QObject::tr("SubDetailFooter"),LimeReport::bandTAG), + LimeReport::ItemAttribs(QObject::tr("SubDetailFooter"),LimeReport::Const::bandTAG), createFooter ); diff --git a/src/databrowser/lrdatabrowser.cpp b/src/databrowser/lrdatabrowser.cpp index 8e707bf..c44aae8 100644 --- a/src/databrowser/lrdatabrowser.cpp +++ b/src/databrowser/lrdatabrowser.cpp @@ -192,7 +192,7 @@ void DataBrowser::updateDataTree() } else item->setIcon(0,QIcon(":/databrowser/images/table_error")); - } catch(ReportError& exception) { + } catch(ReportError& /*exception*/) { item->setIcon(0,QIcon(":/databrowser/images/table_error")); //qDebug()<dataManager()->dataSourceHolder(datasourceName); + if (holder) holder->update(); IDataSource* datasource = m_report->dataManager()->dataSource(datasourceName); if (datasource){ tableView->setModel(datasource->model()); @@ -594,6 +596,7 @@ void DataBrowser::addConnectionDesc(ConnectionDesc *connection) void DataBrowser::changeConnectionDesc(ConnectionDesc *connection) { Q_UNUSED(connection) + if (connection->autoconnect()) m_report->dataManager()->connectConnection(connection->name()); updateDataTree(); } diff --git a/src/databrowser/lrdatabrowsertree.cpp b/src/databrowser/lrdatabrowsertree.cpp index b1fb944..a7c06ad 100644 --- a/src/databrowser/lrdatabrowsertree.cpp +++ b/src/databrowser/lrdatabrowsertree.cpp @@ -38,10 +38,10 @@ QMimeData *DataBrowserTree::mimeData(const QList items) const { QMimeData* result = QTreeWidget::mimeData(items); if (items.at(0)->type()==Row){ - result->setText("$D{"+items.at(0)->parent()->text(0)+"."+items.at(0)->data(0,Qt::DisplayRole).toString()+"}"); + result->setText("field:$D{"+items.at(0)->parent()->text(0)+"."+items.at(0)->data(0,Qt::DisplayRole).toString()+"}"); } if (items.at(0)->type()==Variable){ - result->setText("$V{"+items.at(0)->text(0)+"}"); + result->setText("variable:$V{"+items.at(0)->text(0)+"}"); } return result; } diff --git a/src/databrowser/lrsqleditdialog.cpp b/src/databrowser/lrsqleditdialog.cpp index ca20a32..395ffed 100644 --- a/src/databrowser/lrsqleditdialog.cpp +++ b/src/databrowser/lrsqleditdialog.cpp @@ -296,7 +296,7 @@ void SQLEditDialog::slotPreviewData() QMessageBox::critical(this,tr("Attention"),tr("Connection is not specified")); return; } - m_previewModel = m_datasources->previewSQL(ui->cbbConnection->currentText(),ui->textEditSQL->toPlainText()); + m_previewModel = m_datasources->previewSQL(ui->cbbConnection->currentText(),ui->textEditSQL->toPlainText(),ui->leMaster->text()); if (m_previewModel){ ui->tvPreview->setModel(m_previewModel.data()); ui->gbDataPreview->setVisible(true); diff --git a/src/images/PDF1.png b/src/images/PDF1.png new file mode 100644 index 0000000..3caba4e Binary files /dev/null and b/src/images/PDF1.png differ diff --git a/src/images/PDF2.png b/src/images/PDF2.png new file mode 100644 index 0000000..c931312 Binary files /dev/null and b/src/images/PDF2.png differ diff --git a/src/images/empty.png b/src/images/empty.png new file mode 100644 index 0000000..f5cbc09 Binary files /dev/null and b/src/images/empty.png differ diff --git a/src/images/hideLeftPanel.png b/src/images/hideLeftPanel.png new file mode 100644 index 0000000..fdd2965 Binary files /dev/null and b/src/images/hideLeftPanel.png differ diff --git a/src/images/hideRightPanel.png b/src/images/hideRightPanel.png new file mode 100644 index 0000000..0345c2e Binary files /dev/null and b/src/images/hideRightPanel.png differ diff --git a/src/items/lrbarcodeitem.cpp b/src/items/lrbarcodeitem.cpp index 5647c21..14dc8f8 100644 --- a/src/items/lrbarcodeitem.cpp +++ b/src/items/lrbarcodeitem.cpp @@ -73,7 +73,7 @@ void BarcodeItem::paint(QPainter *ppainter, const QStyleOptionGraphicsItem *opti bc.setSecurityLevel(m_securityLevel); bc.setPdf417CodeWords(m_pdf417CodeWords); - if (isSelected()) ppainter->setOpacity(SELECTION_OPACITY); + if (isSelected()) ppainter->setOpacity(Const::SELECTION_OPACITY); QRectF bcRect; diff --git a/src/items/lrhorizontallayout.cpp b/src/items/lrhorizontallayout.cpp index 340b10b..4e645e2 100644 --- a/src/items/lrhorizontallayout.cpp +++ b/src/items/lrhorizontallayout.cpp @@ -47,7 +47,7 @@ LimeReport::BaseDesignIntf *createHLayout(QObject *owner, LimeReport::BaseDesign } bool registred = LimeReport::DesignElementsFactory::instance().registerCreator( xmlTag, - LimeReport::ItemAttribs(QObject::tr("HLayout"), LimeReport::bandTAG), + LimeReport::ItemAttribs(QObject::tr("HLayout"), LimeReport::Const::bandTAG), createHLayout ); } @@ -376,7 +376,7 @@ LayoutMarker::LayoutMarker(HorizontalLayout *layout, QGraphicsItem *parent) void LayoutMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) { painter->save(); - painter->setOpacity(LAYOUT_MARKER_OPACITY); + painter->setOpacity(Const::LAYOUT_MARKER_OPACITY); painter->fillRect(boundingRect(),m_color); painter->setRenderHint(QPainter::Antialiasing); diff --git a/src/items/lrimageitem.cpp b/src/items/lrimageitem.cpp index c573167..674186a 100644 --- a/src/items/lrimageitem.cpp +++ b/src/items/lrimageitem.cpp @@ -185,7 +185,7 @@ void ImageItem::setDatasource(const QString &datasource) void ImageItem::paint(QPainter *ppainter, const QStyleOptionGraphicsItem *option, QWidget *widget) { ppainter->save(); - if (isSelected()) ppainter->setOpacity(SELECTION_OPACITY); + if (isSelected()) ppainter->setOpacity(Const::SELECTION_OPACITY); else ppainter->setOpacity(qreal(opacity())/100); QPointF point = rect().topLeft(); diff --git a/src/items/lrimageitem.h b/src/items/lrimageitem.h index 7a0f734..f9e6e7e 100644 --- a/src/items/lrimageitem.h +++ b/src/items/lrimageitem.h @@ -70,6 +70,7 @@ protected: BaseDesignIntf* createSameTypeItem(QObject *owner, QGraphicsItem *parent); void updateItemSize(RenderPass, int); bool isNeedUpdateSize(RenderPass) const; + bool drawDesignBorders() const {return m_picture.isNull();} private: QImage m_picture; QString m_content; diff --git a/src/items/lrshapeitem.h b/src/items/lrshapeitem.h index 84cc6d9..037d9a6 100644 --- a/src/items/lrshapeitem.h +++ b/src/items/lrshapeitem.h @@ -64,7 +64,8 @@ public: void setOpacity(int opacity); protected: - virtual BaseDesignIntf* createSameTypeItem(QObject *owner, QGraphicsItem *parent); + BaseDesignIntf* createSameTypeItem(QObject *owner, QGraphicsItem *parent); + bool drawDesignBorders() const {return false;} private: ShapeType m_shape; QColor m_shapeColor; diff --git a/src/lrbanddesignintf.cpp b/src/lrbanddesignintf.cpp index f453dd7..d71069f 100644 --- a/src/lrbanddesignintf.cpp +++ b/src/lrbanddesignintf.cpp @@ -47,7 +47,7 @@ QRectF BandMarker::boundingRect() const void BandMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem* /**option*/, QWidget* /*widget*/) { painter->save(); - painter->setOpacity(BAND_MARKER_OPACITY); + painter->setOpacity(Const::BAND_MARKER_OPACITY); painter->fillRect(boundingRect(),m_color); painter->setOpacity(1); painter->setRenderHint(QPainter::Antialiasing); @@ -155,6 +155,10 @@ BandDesignIntf::BandDesignIntf(BandsType bandType, const QString &xmlTypeName, Q m_bandMarker->setHeight(height()); m_bandMarker->setPos(pos().x()-m_bandMarker->width(),pos().y()); if (scene()) scene()->addItem(m_bandMarker); + + m_bandNameLabel = new BandNameLabel(this); + m_bandNameLabel->setVisible(false); + if (scene()) scene()->addItem(m_bandNameLabel); } BandDesignIntf::~BandDesignIntf() @@ -169,6 +173,9 @@ BandDesignIntf::~BandDesignIntf() if (m_bandMarker) { delete m_bandMarker; } + if (m_bandNameLabel){ + delete m_bandNameLabel; + } } void BandDesignIntf::paint(QPainter *ppainter, const QStyleOptionGraphicsItem *option, QWidget *widget) @@ -180,7 +187,7 @@ void BandDesignIntf::paint(QPainter *ppainter, const QStyleOptionGraphicsItem *o ppainter->save(); QString bandText = objectName(); if (parentBand()) bandText+=QLatin1String(" connected to ")+parentBand()->objectName(); - QFont font("Arial",7*fontFACTOR,-1,true); + QFont font("Arial",7*Const::fontFACTOR,-1,true); QFontMetrics fontMetrics(font); QVector bandNameRects; @@ -195,14 +202,14 @@ void BandDesignIntf::paint(QPainter *ppainter, const QStyleOptionGraphicsItem *o ppainter->setFont(font); for (int i=0;isetRenderHint(QPainter::Antialiasing); ppainter->setBrush(bandColor()); - ppainter->setOpacity(BAND_NAME_AREA_OPACITY); + ppainter->setOpacity(Const::BAND_NAME_AREA_OPACITY); ppainter->drawRoundedRect(labelRect,8,8); - ppainter->setOpacity(BAND_NAME_TEXT_OPACITY); + ppainter->setOpacity(Const::BAND_NAME_TEXT_OPACITY); ppainter->setPen(Qt::black); - ppainter->drawText(bandNameRects[i]," "+bandText+" "); + ppainter->drawText(bandNameRects[i],Qt::AlignHCenter,bandText); } } ppainter->restore(); @@ -217,7 +224,9 @@ BandDesignIntf::BandsType BandDesignIntf::bandType() const QString BandDesignIntf::bandTitle() const { - return m_bandTypeText; + QString result = objectName(); + if (parentBand()) result +=tr(" connected to ")+parentBand()->objectName(); + return result; } QIcon BandDesignIntf::bandIcon() const @@ -323,7 +332,7 @@ bool BandDesignIntf::canBeSplitted(int height) const if ((item->minHeight()>height) && (item->minHeight()>(this->height()-height))) return false; } } - return true; + return isSplittable(); } bool BandDesignIntf::isEmpty() const @@ -561,6 +570,11 @@ void BandDesignIntf::trimToMaxHeight(int maxHeight) } } +void BandDesignIntf::setBandTypeText(const QString &value){ + m_bandTypeText=value; + m_bandNameLabel->updateLabel(); +} + QSet BandDesignIntf::groupBands() { QSet result; @@ -611,6 +625,9 @@ QVariant BandDesignIntf::itemChange(QGraphicsItem::GraphicsItemChange change, co m_bandMarker->update(0,0, m_bandMarker->boundingRect().width(), m_bandMarker->boundingRect().width()); + m_bandNameLabel->updateLabel(); + m_bandNameLabel->setVisible(value.toBool()); + } } return BaseDesignIntf::itemChange(change,value); @@ -720,6 +737,52 @@ DataBandDesignIntf::DataBandDesignIntf(BandDesignIntf::BandsType bandType, QStri { } +BandNameLabel::BandNameLabel(BandDesignIntf *band, QGraphicsItem *parent) + :QGraphicsItem(parent),m_rect(5,5,30,30),m_band(band) +{ + setAcceptHoverEvents(true); +} + +void BandNameLabel::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + painter->setFont(QFont("Arial",7*Const::fontFACTOR,-1,true)); + painter->setOpacity(1); + QPen pen(Const::BAND_NAME_BORDER_COLOR); + pen.setWidth(2); + painter->setBrush(Qt::yellow); + painter->setPen(pen); + painter->drawRect(m_rect); + painter->setOpacity(0.8); + painter->setPen(Qt::black); + painter->drawText(m_rect,Qt::AlignCenter,m_band->bandTitle()); + Q_UNUSED(option) + Q_UNUSED(widget) +} + +QRectF BandNameLabel::boundingRect() const +{ + return m_rect; +} + +void BandNameLabel::updateLabel() +{ + QFont font("Arial",7*Const::fontFACTOR,-1,true); + QFontMetrics fontMetrics(font); + prepareGeometryChange(); + m_rect = QRectF( + m_band->pos().x()+10, + m_band->pos().y()-(fontMetrics.height()+10), + fontMetrics.width(m_band->bandTitle())+20,fontMetrics.height()+10 + ); + update(); +} + +void BandNameLabel::hoverEnterEvent(QGraphicsSceneHoverEvent *event) +{ + setVisible(false); + Q_UNUSED(event) +} + } diff --git a/src/lrbanddesignintf.h b/src/lrbanddesignintf.h index 6a4179b..fbf3f3f 100644 --- a/src/lrbanddesignintf.h +++ b/src/lrbanddesignintf.h @@ -50,8 +50,8 @@ class BandDesignIntf; class BandMarker : public QGraphicsItem{ public: explicit BandMarker(BandDesignIntf* band, QGraphicsItem *parent=0); - virtual QRectF boundingRect() const; - virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *); + QRectF boundingRect() const; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *); void setHeight(qreal height); void setWidth(qreal width); void setColor(QColor color); @@ -65,6 +65,19 @@ private: BandDesignIntf* m_band; }; +class BandNameLabel : public QGraphicsItem{ +public: + explicit BandNameLabel(BandDesignIntf* band, QGraphicsItem* parent=0); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + QRectF boundingRect() const; + void updateLabel(); + void hoverEnterEvent(QGraphicsSceneHoverEvent *event); +private: + QRectF m_rect; + QColor m_color; + BandDesignIntf* m_band; +}; + struct ItemSortContainer; typedef QSharedPointer< ItemSortContainer > PItemSortContainer; class BandDesignIntf : public BaseDesignIntf @@ -77,6 +90,7 @@ class BandDesignIntf : public BaseDesignIntf Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor) Q_PROPERTY(bool printIfEmpty READ printIfEmpty WRITE setPrintIfEmpty) friend class BandMarker; + friend class BandNameLabel; public: enum BandsType { @@ -180,7 +194,7 @@ protected: void setAutoHeight(bool value){m_autoHeight=value;} bool autoHeight(){return m_autoHeight;} - void setBandTypeText(const QString& value){m_bandTypeText=value;} + void setBandTypeText(const QString& value); QString bandTypeText(){return m_bandTypeText;} virtual void moveDown(){} virtual void moveUp(){} @@ -213,6 +227,7 @@ private: int m_maxScalePercent; bool m_sliceLastRow; bool m_printIfEmpty; + BandNameLabel* m_bandNameLabel; }; class DataBandDesignIntf : public BandDesignIntf{ diff --git a/src/lrbandsmanager.cpp b/src/lrbandsmanager.cpp index eab473a..889e7b3 100644 --- a/src/lrbandsmanager.cpp +++ b/src/lrbandsmanager.cpp @@ -49,7 +49,7 @@ QStringList BandsManager::bandNames() <(LimeReport::DesignElementsFactory::instance().objectCreator(identity)(owner,parent)); } diff --git a/src/lrbasedesignintf.cpp b/src/lrbasedesignintf.cpp index b17e31d..bbc3395 100644 --- a/src/lrbasedesignintf.cpp +++ b/src/lrbasedesignintf.cpp @@ -50,15 +50,15 @@ namespace LimeReport BaseDesignIntf::BaseDesignIntf(const QString &storageTypeName, QObject *owner, QGraphicsItem *parent) : QObject(owner), QGraphicsItem(parent), - m_resizeHandleSize(Consts::RESIZE_HANDLE_SIZE), - m_selectionPenSize(Consts::SELECTION_PEN_SIZE), + m_resizeHandleSize(Const::RESIZE_HANDLE_SIZE), + m_selectionPenSize(Const::SELECTION_PEN_SIZE), m_posibleResizeDirectionFlags(ResizeTop | ResizeBottom | ResizeLeft | ResizeRight), m_posibleMoveDirectionFlags(All), m_resizeDirectionFlags(0), m_width(200), m_height(50), m_fontColor(Qt::black), - m_mmFactor(mmFACTOR), + m_mmFactor(Const::mmFACTOR), m_fixedPos(false), m_BGMode(OpaqueMode), m_opacity(100), @@ -80,7 +80,7 @@ BaseDesignIntf::BaseDesignIntf(const QString &storageTypeName, QObject *owner, Q } initFlags(); m_selectionMarker = new SelectionMarker(this); - m_selectionMarker->setColor(Consts::SELECTION_COLOR); + m_selectionMarker->setColor(Const::SELECTION_COLOR); m_selectionMarker->setVisible(false); //connect(this,SIGNAL(objectNameChanged(QString)),this,SLOT(slotObjectNameChanged(QString))); } @@ -184,7 +184,7 @@ void BaseDesignIntf::setHeight(qreal height) QFont BaseDesignIntf::transformToSceneFont(const QFont& value) const { QFont f = value; - f.setPixelSize(f.pointSize()*fontFACTOR); + f.setPixelSize(f.pointSize()*Const::fontFACTOR); return f; } @@ -304,6 +304,18 @@ void BaseDesignIntf::paint(QPainter *ppainter, const QStyleOptionGraphicsItem *o drawResizeZone(ppainter); } +QColor calcColor(QColor color){ + + int R = color.red(); + int G = color.green(); + int B = color.blue(); + + if (0.222*R + 0.707*G + 0.071*B <= 127) + return Qt::white; + else + return Qt::black; +}; + void BaseDesignIntf::prepareRect(QPainter *ppainter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/) { ppainter->save(); @@ -314,6 +326,9 @@ void BaseDesignIntf::prepareRect(QPainter *ppainter, const QStyleOptionGraphicsI if (m_BGMode == OpaqueMode) { ppainter->setOpacity(qreal(m_opacity) / 100); ppainter->fillRect(rect(), QBrush(m_backgroundBrushcolor)); + } else if (itemMode() & DesignMode){ + ppainter->setOpacity(0.1); + ppainter->fillRect(rect(), QBrush(QPixmap(":/report/empty"))); } } ppainter->restore(); @@ -353,8 +368,8 @@ void BaseDesignIntf::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { if (m_resizeDirectionFlags & ResizeLeft) { - if ((event->scenePos().x()) <= (mapToScene(0, 0).x() + (width() - Consts::MINIMUM_ITEM_WIDTH)) && - (width() + (event->lastScenePos().x() - event->scenePos().x()) > Consts::MINIMUM_ITEM_WIDTH) + if ((event->scenePos().x()) <= (mapToScene(0, 0).x() + (width() - Const::MINIMUM_ITEM_WIDTH)) && + (width() + (event->lastScenePos().x() - event->scenePos().x()) > Const::MINIMUM_ITEM_WIDTH) ) { qreal posRightConner = mapToScene(0, 0).x() + width(); setItemPos(mapToParent(mapFromScene(div(event->scenePos().x(), 2).quot * 2, y())).x(), y()); @@ -363,7 +378,7 @@ void BaseDesignIntf::mouseMoveEvent(QGraphicsSceneMouseEvent *event) } if (m_resizeDirectionFlags & ResizeRight) { - if ((event->scenePos().x() >= (mapToScene(0, 0).x() + Consts::MINIMUM_ITEM_WIDTH)) || + if ((event->scenePos().x() >= (mapToScene(0, 0).x() + Const::MINIMUM_ITEM_WIDTH)) || (event->scenePos().x() >= (mapToScene(0, 0).x() + width()))) { setWidth(div(int(event->scenePos().x()) - int(mapToScene(0, 0).x()), 2).quot * 2); } @@ -371,7 +386,7 @@ void BaseDesignIntf::mouseMoveEvent(QGraphicsSceneMouseEvent *event) if (m_resizeDirectionFlags & ResizeBottom) { if ((event->scenePos().y() > (mapToScene(0, 0).y() + height())) || - (event->scenePos().y() > (mapToScene(0, 0).y() + Consts::MINIMUM_ITEM_HEIGHT)) + (event->scenePos().y() > (mapToScene(0, 0).y() + Const::MINIMUM_ITEM_HEIGHT)) ) { setHeight(div(int(event->scenePos().y()) - int(mapToScene(0, 0).y()), 2).quot * 2); } @@ -379,8 +394,8 @@ void BaseDesignIntf::mouseMoveEvent(QGraphicsSceneMouseEvent *event) if (m_resizeDirectionFlags & ResizeTop) { - if ((event->scenePos().y()) <= (mapToScene(0, 0).y() + (height() - Consts::MINIMUM_ITEM_HEIGHT)) && - (height() + (event->lastScenePos().y() - event->scenePos().y()) > Consts::MINIMUM_ITEM_HEIGHT) + if ((event->scenePos().y()) <= (mapToScene(0, 0).y() + (height() - Const::MINIMUM_ITEM_HEIGHT)) && + (height() + (event->lastScenePos().y() - event->scenePos().y()) > Const::MINIMUM_ITEM_HEIGHT) ) { qreal posBottomConner = int(mapToScene(0, 0).y()) + int(height()); setItemPos(x(), div(mapToParent(event->pos()).y(), 2).quot * 2); @@ -619,7 +634,7 @@ void BaseDesignIntf::drawRenderModeBorder(QPainter *painter, QRectF rect) const void BaseDesignIntf::drawBorder(QPainter *painter, QRectF rect) const { painter->save(); - if (itemMode() & DesignMode) { + if (itemMode() & DesignMode && drawDesignBorders()) { drawDesignModeBorder(painter, rect); } else drawRenderModeBorder(painter, rect); @@ -692,7 +707,7 @@ QPen BaseDesignIntf::borderPen(BorderSide side/*, bool selected*/) const QColor BaseDesignIntf::selectionColor() const { - return Consts::SELECTION_COLOR; + return Const::SELECTION_COLOR; } void BaseDesignIntf::initFlags() @@ -879,8 +894,8 @@ void BaseDesignIntf::drawResizeZone(QPainter *painter) if (m_resizeAreas.count() > 0) { painter->save(); - painter->setPen(QPen(Consts::RESIZE_ZONE_COLOR)); - (isSelected()) ? painter->setOpacity(Consts::SELECTED_RESIZE_ZONE_OPACITY) : painter->setOpacity(Consts::RESIZE_ZONE_OPACITY); + painter->setPen(QPen(Const::RESIZE_ZONE_COLOR)); + (isSelected()) ? painter->setOpacity(Const::SELECTED_RESIZE_ZONE_OPACITY) : painter->setOpacity(Const::RESIZE_ZONE_OPACITY); painter->setBrush(QBrush(Qt::green, Qt::SolidPattern)); foreach(QRectF * resizeArea, m_resizeAreas) painter->drawRect(*resizeArea); painter->restore(); @@ -1093,7 +1108,7 @@ void SelectionMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *, pen.setWidth(2); pen.setStyle(Qt::DashLine); painter->setPen(pen); - painter->setOpacity(Consts::SELECTION_COLOR_OPACITY); + painter->setOpacity(Const::SELECTION_COLOR_OPACITY); painter->drawRect(boundingRect()); } diff --git a/src/lrbasedesignintf.h b/src/lrbasedesignintf.h index 4171250..cc40136 100644 --- a/src/lrbasedesignintf.h +++ b/src/lrbasedesignintf.h @@ -44,18 +44,6 @@ namespace LimeReport { enum ItemModes{ DesignMode=1, PreviewMode=2, PrintMode=4, EditMode=8, LayoutEditMode=16 }; -namespace Consts { - int const RESIZE_HANDLE_SIZE = 10; - int const SELECTION_PEN_SIZE = 4; - int const MINIMUM_ITEM_WIDTH = 2*RESIZE_HANDLE_SIZE; - int const MINIMUM_ITEM_HEIGHT = 2*RESIZE_HANDLE_SIZE; - double const RESIZE_ZONE_OPACITY = 0.5; - double const SELECTED_RESIZE_ZONE_OPACITY = 0.6; - QColor const RESIZE_ZONE_COLOR = Qt::green; - QColor const SELECTION_COLOR = Qt::red; - double const SELECTION_COLOR_OPACITY = 0.9; -} - class ReportEnginePrivate; class PageDesignIntf; class BaseDesignIntf; @@ -268,6 +256,7 @@ protected: RenderPass currentRenderPass(){return m_currentPass;} + virtual bool drawDesignBorders() const {return true;} private: void updateSelectionMarker(); int resizeDirectionFlags(QPointF position); diff --git a/src/lrdatadesignintf.cpp b/src/lrdatadesignintf.cpp index c78b249..e410fbc 100644 --- a/src/lrdatadesignintf.cpp +++ b/src/lrdatadesignintf.cpp @@ -112,6 +112,11 @@ void QueryHolder::setConnectionName(QString connectionName) m_connectionName=connectionName; } +void QueryHolder::update() +{ + runQuery(m_mode); +} + void QueryHolder::setDatasource(IDataSource::Ptr value){ m_dataSource.clear(); m_dataSource=value; @@ -120,13 +125,13 @@ void QueryHolder::setDatasource(IDataSource::Ptr value){ void QueryHolder::fillParams(QSqlQuery *query) { DataSourceManager* dm=DataSourceManager::instance(); - foreach(QString param,m_params){ + foreach(QString param,m_aliasesToParam.keys()){ QVariant value; if (param.contains(".")){ - value = dm->fieldData(param); + value = dm->fieldData(m_aliasesToParam.value(param)); param=param.right(param.length()-param.indexOf('.')-1); } else { - value = dm->variable(param); + value = dm->variable(m_aliasesToParam.value(param)); } if (value.isValid() || m_mode == IDataSource::DESIGN_MODE) query->bindValue(':'+param,value); @@ -135,19 +140,31 @@ void QueryHolder::fillParams(QSqlQuery *query) void QueryHolder::extractParams() { - m_preparedSQL = replaceVriables(m_queryText); + m_preparedSQL = replaceVariables(m_queryText); } -QString QueryHolder::replaceVriables(QString query) +QString QueryHolder::replaceVariables(QString query) { - QRegExp rx(VARIABLE_RX); + QRegExp rx(Const::VARIABLE_RX); + int curentAliasIndex = 0; if (query.contains(rx)){ - while ((rx.indexIn(query))!=-1){ + int pos = -1; + while ((pos=rx.indexIn(query))!=-1){ + QString variable=rx.cap(0); variable.remove("$V{"); variable.remove("}"); - m_params.append(variable); - query.replace(rx.cap(0),":"+variable); + + if (m_aliasesToParam.contains(variable)){ + curentAliasIndex++; + m_aliasesToParam.insert(variable+"_alias"+QString::number(curentAliasIndex),variable); + variable += "_alias"+QString::number(curentAliasIndex); + } else { + m_aliasesToParam.insert(variable,variable); + } + + query.replace(pos,rx.cap(0).length(),":"+variable); + } } return query; @@ -344,7 +361,7 @@ void SubQueryHolder::setMasterDatasource(const QString &value) void SubQueryHolder::extractParams() { - m_preparedSQL = replaceFields(replaceVriables(queryText())); + m_preparedSQL = replaceFields(replaceVariables(queryText())); } QString SubQueryHolder::extractField(QString source) @@ -357,17 +374,29 @@ QString SubQueryHolder::extractField(QString source) QString SubQueryHolder::replaceFields(QString query) { - QRegExp rx(FIELD_RX); + QRegExp rx(Const::FIELD_RX); + int curentAliasIndex=0; if (query.contains(rx)){ - while ((rx.indexIn(query))!=-1){ + int pos; + while ((pos=rx.indexIn(query))!=-1){ QString field=rx.cap(0); field.remove("$D{"); field.remove("}"); - if (field.contains(".")) - m_params.append(field); - else - m_params.append(m_masterDatasource+"."+field); - query.replace(rx.cap(0),":"+extractField(field)); + + if (!m_aliasesToParam.contains(field)){ + if (field.contains(".")) + m_aliasesToParam.insert(field,field); + else + m_aliasesToParam.insert(field,m_masterDatasource+"."+field); + } else { + curentAliasIndex++; + if (field.contains(".")) + m_aliasesToParam.insert(field+"_alias"+QString::number(curentAliasIndex),field); + else + m_aliasesToParam.insert(field+"_alias"+QString::number(curentAliasIndex),m_masterDatasource+"."+field); + field+="_alias"+QString::number(curentAliasIndex); + } + query.replace(pos,rx.cap(0).length(),":"+extractField(field)); } } return query; diff --git a/src/lrdatadesignintf.h b/src/lrdatadesignintf.h index c064190..1aaaab1 100644 --- a/src/lrdatadesignintf.h +++ b/src/lrdatadesignintf.h @@ -73,6 +73,7 @@ public: virtual bool isEditable() const = 0; virtual bool isRemovable() const = 0; virtual void invalidate() = 0; + virtual void update() = 0; virtual ~IDataSourceHolder(){} }; @@ -88,6 +89,7 @@ public: bool isEditable() const { return false; } bool isRemovable() const { return false; } void invalidate(){} + void update(){} signals: void modelStateChanged(); private: @@ -178,12 +180,13 @@ public: QString lastError() const { return m_lastError; } void setLastError(QString value){m_lastError=value; if (m_query) {delete m_query; m_query=0;}} void invalidate(){} + void update(); protected: void setDatasource(IDataSource::Ptr value); virtual void fillParams(QSqlQuery* query); virtual void extractParams(); - QString replaceVriables(QString query); - QList m_params; + QString replaceVariables(QString query); + QMap m_aliasesToParam; QSqlQuery* m_query; QString m_preparedSQL; private: @@ -299,6 +302,7 @@ public: bool isRemovable() const { return true; } QString lastError() const { return m_lastError; } void invalidate(){m_invalid = true; m_lastError = tr("Datasource has been invalidated");} + void update(){}; private slots: void slotChildModelDestoroyed(){m_datasource.clear();} private: @@ -395,6 +399,7 @@ public: bool isRemovable() const {return false;} void invalidate(){} ~CallbackDatasourceHolder(){if (m_datasource) delete m_datasource;} + void update(){} private: IDataSource* m_datasource; bool m_owned; diff --git a/src/lrdatasourcemanager.cpp b/src/lrdatasourcemanager.cpp index 1db8034..6275c07 100644 --- a/src/lrdatasourcemanager.cpp +++ b/src/lrdatasourcemanager.cpp @@ -30,6 +30,7 @@ #include "lrdatasourcemanager.h" #include "lrdatadesignintf.h" #include +#include #include #include #include @@ -284,12 +285,34 @@ void DataSourceManager::addCallbackDatasource(ICallbackDatasource *datasource, c } } -QSharedPointerDataSourceManager::previewSQL(const QString &connectionName, const QString &sqlText) +QSharedPointerDataSourceManager::previewSQL(const QString &connectionName, const QString &sqlText, QString masterDatasource) { QSqlDatabase db = QSqlDatabase::database(connectionName); + if (db.isValid() && db.isOpen()){ + QSqlQueryModel* model = new QSqlQueryModel(); - model->setQuery(sqlText,db); + QMap aliasesToParam; + QString queryText = replaceVariables(sqlText,aliasesToParam); + queryText = replaceFields(queryText,aliasesToParam,masterDatasource); + QSqlQuery query(db); + query.prepare(queryText); + + + foreach(QString param,aliasesToParam.keys()){ + QVariant value; + if (param.contains(".")){ + value = fieldData(aliasesToParam.value(param)); + param=param.right(param.length()-param.indexOf('.')-1); + } else { + value = variable(aliasesToParam.value(param)); + } + if (value.isValid() || m_designTime) + query.bindValue(':'+param,value); + } + + query.exec(); + model->setQuery(query); m_lastError = model->lastError().text(); if (model->query().isActive()) return QSharedPointer(model); @@ -301,6 +324,86 @@ QSharedPointerDataSourceManager::previewSQL(const QString &c return QSharedPointer(0); } +QString DataSourceManager::extractField(QString source) +{ + if (source.contains('.')) { + return source.right(source.length()-(source.indexOf('.')+1)); + } + return source; +} + +QString DataSourceManager::replaceVariables(QString query, QMap &aliasesToParam) +{ + QRegExp rx(Const::VARIABLE_RX); + int curentAliasIndex = 0; + if (query.contains(rx)){ + int pos = -1; + while ((pos=rx.indexIn(query))!=-1){ + + QString var=rx.cap(0); + var.remove("$V{"); + var.remove("}"); + + if (aliasesToParam.contains(var)){ + curentAliasIndex++; + aliasesToParam.insert(var+"_v_alias"+QString::number(curentAliasIndex),var); + var += "_v_alias"+QString::number(curentAliasIndex); + } else { + aliasesToParam.insert(var,var); + } + + query.replace(pos,rx.cap(0).length(),":"+var); + + } + } + return query; +} + +QString DataSourceManager::replaceFields(QString query, QMap &aliasesToParam, QString masterDatasource) +{ + QRegExp rx(Const::FIELD_RX); + int curentAliasIndex=0; + if (query.contains(rx)){ + int pos; + while ((pos=rx.indexIn(query))!=-1){ + QString field=rx.cap(0); + field.remove("$D{"); + field.remove("}"); + + if (!aliasesToParam.contains(field)){ + if (field.contains(".")) + aliasesToParam.insert(field,field); + else + aliasesToParam.insert(field,masterDatasource+"."+field); + } else { + curentAliasIndex++; + if (field.contains(".")) + aliasesToParam.insert(field+"_f_alias"+QString::number(curentAliasIndex),field); + else + aliasesToParam.insert(field+"_f_alias"+QString::number(curentAliasIndex),masterDatasource+"."+field); + field+="_f_alias"+QString::number(curentAliasIndex); + } + query.replace(pos,rx.cap(0).length(),":"+extractField(field)); + } + } + return query; + +// QRegExp rx(Const::FIELD_RX); +// if (query.contains(rx)){ +// while ((rx.indexIn(query))!=-1){ +// QString field=rx.cap(0); +// field.remove("$D{"); +// field.remove("}"); +// if (field.contains(".")) +// aliasesToParam.append(field); +// else +// aliasesToParam.append(masterDatasource+"."+field); +// query.replace(rx.cap(0),":"+extractField(field)); +// } +// } +// return query; +} + void DataSourceManager::setReportVariable(const QString &name, const QVariant &value) { if (!containsVariable(name)){ @@ -525,18 +628,22 @@ void DataSourceManager::putProxyDesc(ProxyDesc *proxyDesc) bool DataSourceManager::connectConnection(ConnectionDesc *connectionDesc) { - if (QSqlDatabase::contains(connectionDesc->name())) return QSqlDatabase::database(connectionDesc->name()).isOpen(); - bool connected = false; + clearErrorsList(); QString lastError =""; - { - QSqlDatabase db = QSqlDatabase::addDatabase(connectionDesc->driver(),connectionDesc->name()); - db.setHostName(connectionDesc->host()); - db.setUserName(connectionDesc->userName()); - db.setPassword(connectionDesc->password()); - db.setDatabaseName(connectionDesc->databaseName()); - connected=db.open(); - if (!connected) lastError=db.lastError().text(); + + if (!QSqlDatabase::contains(connectionDesc->name())){ + { + QSqlDatabase db = QSqlDatabase::addDatabase(connectionDesc->driver(),connectionDesc->name()); + db.setHostName(connectionDesc->host()); + db.setUserName(connectionDesc->userName()); + db.setPassword(connectionDesc->password()); + db.setDatabaseName(connectionDesc->databaseName()); + connected=db.open(); + if (!connected) lastError=db.lastError().text(); + } + } else { + connected = QSqlDatabase::database(connectionDesc->name()).isOpen(); } if (!connected) { QSqlDatabase::removeDatabase(connectionDesc->name()); @@ -865,14 +972,6 @@ void DataSourceManager::slotConnectionRenamed(const QString &oldName, const QStr void DataSourceManager::clear(ClearMethod method) { - - QList::iterator cit = m_connections.begin(); - while( cit != m_connections.end() ){ - QSqlDatabase::removeDatabase( (*cit)->name() ); - delete (*cit); - cit = m_connections.erase(cit); - } - DataSourcesMap::iterator dit; for( dit = m_datasources.begin(); dit != m_datasources.end(); ){ bool owned = (*dit)->isOwned() && (*dit)->isRemovable(); @@ -894,6 +993,13 @@ void DataSourceManager::clear(ClearMethod method) } + QList::iterator cit = m_connections.begin(); + while( cit != m_connections.end() ){ + QSqlDatabase::removeDatabase( (*cit)->name() ); + delete (*cit); + cit = m_connections.erase(cit); + } + //TODO: add smart pointes to collections foreach(QueryDesc *desc, m_queries) delete desc; foreach(SubQueryDesc* desc, m_subqueries) delete desc; diff --git a/src/lrdatasourcemanager.h b/src/lrdatasourcemanager.h index 92c57d7..4a9179d 100644 --- a/src/lrdatasourcemanager.h +++ b/src/lrdatasourcemanager.h @@ -177,7 +177,11 @@ public: QStringList errorsList(){ return m_errorsList;} bool designTime() const; void setDesignTime(bool designTime); - QSharedPointer previewSQL(const QString& connectionName, const QString& sqlText); + + QString extractField(QString source); + QString replaceVariables(QString query, QMap &aliasesToParam); + QString replaceFields(QString query, QMap &aliasesToParam, QString masterDatasource = ""); + QSharedPointer previewSQL(const QString& connectionName, const QString& sqlText, QString masterDatasource=""); signals: void loadCollectionFinished(const QString& collectionName); diff --git a/src/lrglobal.h b/src/lrglobal.h index a701619..e0908fc 100644 --- a/src/lrglobal.h +++ b/src/lrglobal.h @@ -42,19 +42,29 @@ #endif namespace LimeReport { + +namespace Const{ + int const RESIZE_HANDLE_SIZE = 10; + int const SELECTION_PEN_SIZE = 4; + int const MINIMUM_ITEM_WIDTH = 2*RESIZE_HANDLE_SIZE; + int const MINIMUM_ITEM_HEIGHT = 2*RESIZE_HANDLE_SIZE; + double const RESIZE_ZONE_OPACITY = 0.5; + double const SELECTED_RESIZE_ZONE_OPACITY = 0.6; + Qt::GlobalColor const RESIZE_ZONE_COLOR = Qt::green; + Qt::GlobalColor const SELECTION_COLOR = Qt::red; + double const SELECTION_COLOR_OPACITY = 0.9; const qreal fontFACTOR = 3.5; const int mmFACTOR = 10; const int itemPaleteIconSize = 24; const qreal minSpaceBorder = 10; - QString extractClassName(QString className); const QString bandTAG = "band"; + const Qt::GlobalColor BAND_NAME_LABEL_COLOR = Qt::yellow; + const Qt::GlobalColor BAND_NAME_BORDER_COLOR = Qt::darkYellow; const qreal BAND_MARKER_OPACITY = 1; const qreal LAYOUT_MARKER_OPACITY = 0.3; const qreal BAND_NAME_AREA_OPACITY = 0.3; const qreal BAND_NAME_TEXT_OPACITY = 0.6; const qreal SELECTION_OPACITY = 0.3; - enum RenderPass {FirstPass, SecondPass}; - enum ArrangeType {AsNeeded, Force}; const QString FIELD_RX = "\\$D\\s*\\{\\s*([^\\s{}]*)\\s*\\}"; const QString VARIABLE_RX = "\\$V\\s*\\{\\s*([^\\s{}]*)\\s*\\}"; const QString SCRIPT_RX = "\\$S\\s*\\{(.*)\\}"; @@ -64,6 +74,10 @@ namespace LimeReport { const QString GROUP_FUNCTION_RX = "(%1\\s*"+GROUP_FUNCTION_PARAM_RX+")"; const QString GROUP_FUNCTION_NAME_RX = "%1\\s*\\((.*[^\\)])\\)"; const int SCENE_MARGIN = 50; +} + QString extractClassName(QString className); + enum RenderPass {FirstPass, SecondPass}; + enum ArrangeType {AsNeeded, Force}; class ReportError : public std::runtime_error{ public: ReportError(const QString& message):std::runtime_error(message.toStdString()){} diff --git a/src/lrgroupfunctions.cpp b/src/lrgroupfunctions.cpp index 1f2ab18..821b969 100644 --- a/src/lrgroupfunctions.cpp +++ b/src/lrgroupfunctions.cpp @@ -88,14 +88,14 @@ 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("") { - QRegExp rxField(FIELD_RX,Qt::CaseInsensitive); + QRegExp rxField(Const::FIELD_RX,Qt::CaseInsensitive); if (rxField.indexIn(expression)>=0){ m_dataType=Field; m_data = rxField.cap(1); return; } - QRegExp rxVariable(VARIABLE_RX,Qt::CaseInsensitive); + QRegExp rxVariable(Const::VARIABLE_RX,Qt::CaseInsensitive); if (rxVariable.indexIn(expression)>=0){ m_dataType=Variable; m_data = rxVariable.cap(1); diff --git a/src/lritemdesignintf.cpp b/src/lritemdesignintf.cpp index 0ce0542..067b998 100644 --- a/src/lritemdesignintf.cpp +++ b/src/lritemdesignintf.cpp @@ -116,7 +116,7 @@ void ItemDesignIntf::initFlags() QString ContentItemDesignIntf::expandDataFields(QString context, ExpandType expandType) { DataSourceManager* dm = DataSourceManager::instance(); - QRegExp rx(FIELD_RX); + QRegExp rx(Const::FIELD_RX); if (context.contains(rx)){ while ((rx.indexIn(context))!=-1){ @@ -165,9 +165,8 @@ QString ContentItemDesignIntf::expandDataFields(QString context, ExpandType expa QString ContentItemDesignIntf::expandUserVariables(QString context, RenderPass pass, ExpandType expandType) { - DataSourceManager* dm=DataSourceManager::instance(); - //QRegExp rx("\\$V\\{([^{}]*)\\}"); - QRegExp rx(VARIABLE_RX); + DataSourceManager* dm=DataSourceManager::instance(); + QRegExp rx(Const::VARIABLE_RX); if (context.contains(rx)){ int pos = 0; while ((pos = rx.indexIn(context,pos))!=-1){ @@ -192,7 +191,7 @@ QString ContentItemDesignIntf::expandUserVariables(QString context, RenderPass p QString ContentItemDesignIntf::expandScripts(QString context) { - QRegExp rx(SCRIPT_RX); + QRegExp rx(Const::SCRIPT_RX); if (context.contains(rx)){ QScriptEngine* se = ScriptEngineManager::instance().scriptEngine(); diff --git a/src/lrpagedesignintf.cpp b/src/lrpagedesignintf.cpp index 7ef320c..7651504 100644 --- a/src/lrpagedesignintf.cpp +++ b/src/lrpagedesignintf.cpp @@ -46,7 +46,6 @@ #include "lrglobal.h" - #include #include #include @@ -117,9 +116,9 @@ void PageDesignIntf::updatePageRect() connect(m_pageItem.data(), SIGNAL(geometryChanged(QObject *, QRectF, QRectF)), this, SLOT(slotPageGeomertyChanged(QObject *, QRectF, QRectF))); connect(m_pageItem.data(), SIGNAL(objectLoaded(QObject *)), this, SLOT(slotPageItemLoaded(QObject *))); } - this->setSceneRect(-SCENE_MARGIN, -SCENE_MARGIN, - pageItem()->geometry().width() + SCENE_MARGIN*2, - pageItem()->geometry().height() + SCENE_MARGIN*2); + this->setSceneRect(-Const::SCENE_MARGIN, -Const::SCENE_MARGIN, + pageItem()->geometry().width() + Const::SCENE_MARGIN*2, + pageItem()->geometry().height() + Const::SCENE_MARGIN*2); emit sceneRectChanged(sceneRect()); } @@ -256,7 +255,7 @@ void PageDesignIntf::setPageItem(PageItemDesignIntf::Ptr pageItem) } m_pageItem = pageItem; m_pageItem->setItemMode(itemMode()); - setSceneRect(pageItem->rect().adjusted(-10*mmFACTOR,-10*mmFACTOR,10*mmFACTOR,10*mmFACTOR)); + setSceneRect(pageItem->rect().adjusted(-10*Const::mmFACTOR,-10*Const::mmFACTOR,10*Const::mmFACTOR,10*Const::mmFACTOR)); addItem(m_pageItem.data()); registerItem(m_pageItem.data()); } @@ -278,7 +277,7 @@ void PageDesignIntf::setPageItems(QList pages) curHeight+=pageItem->height()+20; if (curWidthwidth()) curWidth=pageItem->width(); } - setSceneRect(QRectF(0,0,curWidth,curHeight).adjusted(-10*mmFACTOR,-10*mmFACTOR,10*mmFACTOR,10*mmFACTOR)); + setSceneRect(QRectF(0,0,curWidth,curHeight).adjusted(-10*Const::mmFACTOR,-10*Const::mmFACTOR,10*Const::mmFACTOR,10*Const::mmFACTOR)); } @@ -290,6 +289,10 @@ void PageDesignIntf::mousePressEvent(QGraphicsSceneMouseEvent *event) saveCommand(command); emit itemInserted(this, event->scenePos(), m_insertItemType); } + if (event->buttons() & Qt::LeftButton && !selectedItems().isEmpty()){ + m_startMovePoint = event->scenePos(); + } + if (event->buttons() & Qt::LeftButton && event->modifiers()==Qt::ShiftModifier){ m_startSelectionPoint = event->scenePos(); } else { @@ -308,6 +311,10 @@ void PageDesignIntf::mouseMoveEvent(QGraphicsSceneMouseEvent *event) } } + if (event->button() & Qt::LeftButton && event->modifiers()==0){ + + } + if (event->buttons() & Qt::LeftButton && event->modifiers()==Qt::ShiftModifier){ if (!m_selectionRect){ m_selectionRect = new QGraphicsRectItem(); @@ -647,22 +654,15 @@ void PageDesignIntf::dragMoveEvent(QGraphicsSceneDragDropEvent* /**event*/) void PageDesignIntf::dropEvent(QGraphicsSceneDragDropEvent* event) { - -// if (m_itemInsertRect) { -// removeItem(m_itemInsertRect); -// delete m_itemInsertRect; -// m_itemInsertRect = 0; -// } - -// if (event->mimeData()->text() == "Text Item") { -// addReportItem(event->mimeData()->text(), event->scenePos(), QSizeF(200, 50)); -// } - -// else addBand(event->mimeData()->text()); - BaseDesignIntf* item = addReportItem("TextItem",event->scenePos(),QSize(250, 50)); - TextItem* ti = dynamic_cast(item); - ti->setContent(event->mimeData()->text()); - + if (event->mimeData()->hasText() && + ((event->mimeData()->text().indexOf("field:")==0) || + (event->mimeData()->text().indexOf("variable:")==0)) + ){ + BaseDesignIntf* item = addReportItem("TextItem",event->scenePos(),QSize(250, 50)); + TextItem* ti = dynamic_cast(item); + QString data = event->mimeData()->text().remove(0,event->mimeData()->text().indexOf(":")+1); + ti->setContent(data); + } } void PageDesignIntf::dragLeaveEvent(QGraphicsSceneDragDropEvent *) @@ -1250,9 +1250,10 @@ HorizontalLayout* PageDesignIntf::internalAddHLayout() if (si.count() > 1) { it = si.begin(); - BaseDesignIntf *firstElement = dynamic_cast(*it); + ItemDesignIntf *firstElement = dynamic_cast(*it); HorizontalLayout *layout = new HorizontalLayout(firstElement->parent(), firstElement->parentItem()); + layout->setItemLocation(firstElement->itemLocation()); layout->setPos(firstElement->pos()); layout->setWidth(0); layout->setHeight(firstElement->height()); @@ -1266,9 +1267,9 @@ HorizontalLayout* PageDesignIntf::internalAddHLayout() item->setSelected(false); } - layout->setSelected(true); layout->setObjectName(genObjectName(*layout)); layout->setItemTypeName("HorizontalLayout"); + layout->setSelected(true); registerItem(layout); return layout; } diff --git a/src/lrpagedesignintf.h b/src/lrpagedesignintf.h index d7f93cc..71ad8ac 100644 --- a/src/lrpagedesignintf.h +++ b/src/lrpagedesignintf.h @@ -244,6 +244,7 @@ namespace LimeReport { QList m_animationList; QPointF m_startSelectionPoint; QGraphicsRectItem* m_selectionRect; + QPointF m_startMovePoint; }; class AbstractPageCommand : public CommandIf{ diff --git a/src/lrpreviewreportwindow.cpp b/src/lrpreviewreportwindow.cpp index 5c4ba90..11c4a90 100644 --- a/src/lrpreviewreportwindow.cpp +++ b/src/lrpreviewreportwindow.cpp @@ -385,6 +385,26 @@ void PreviewReportWindow::slotLastPage() m_changingPage=false; } +void PreviewReportWindow::slotPrintToPDF() +{ + QString fileName = QFileDialog::getSaveFileName(this,tr("PDF file name"),"","PDF(*.pdf)" ); + qDebug()<reactivatePageItem(pageItem); + } + } +} + void PreviewReportWindow::slotSliderMoved(int value) { if (ui->graphicsView->verticalScrollBar()->minimum()==value){ diff --git a/src/lrpreviewreportwindow.h b/src/lrpreviewreportwindow.h index d6f1bef..0033201 100644 --- a/src/lrpreviewreportwindow.h +++ b/src/lrpreviewreportwindow.h @@ -73,6 +73,7 @@ public slots: void on_actionSaveToFile_triggered(); void slotFirstPage(); void slotLastPage(); + void slotPrintToPDF(); private slots: void slotSliderMoved(int value); private: diff --git a/src/lrpreviewreportwindow.ui b/src/lrpreviewreportwindow.ui index b4e2870..19c51c6 100644 --- a/src/lrpreviewreportwindow.ui +++ b/src/lrpreviewreportwindow.ui @@ -41,7 +41,7 @@ 0 0 800 - 20 + 21 @@ -56,6 +56,7 @@ Report + @@ -78,7 +79,7 @@ false - + @@ -220,10 +221,19 @@ Last Page + + + + :/report/images/pdf:/report/images/pdf + + + Print To PDF + + - + @@ -354,6 +364,22 @@ + + actionPrint_To_PDF + triggered() + PreviewReportWindow + slotPrintToPDF() + + + -1 + -1 + + + 399 + 299 + + + slotNextPage() @@ -363,5 +389,6 @@ slotPrint() slotFirstPage() slotLastPage() + slotPrintToPDF() diff --git a/src/lrreportdesignwidget.cpp b/src/lrreportdesignwidget.cpp index 938496d..2c612d1 100644 --- a/src/lrreportdesignwidget.cpp +++ b/src/lrreportdesignwidget.cpp @@ -39,10 +39,62 @@ #include #include #include +#include namespace LimeReport { +//GraphicsViewZoom +GraphicsViewZoom::GraphicsViewZoom(QGraphicsView* view) + : QObject(view), m_view(view) +{ + m_view->viewport()->installEventFilter(this); + m_view->setMouseTracking(true); + m_modifiers = Qt::ControlModifier; + m_zoomFactorBase = 1.0015; +} + +void GraphicsViewZoom::gentleZoom(double factor) { + m_view->scale(factor, factor); + m_view->centerOn(m_targetScenePos); + QPointF delta_viewport_pos = m_targetViewportPos - QPointF(m_view->viewport()->width() / 2.0, + m_view->viewport()->height() / 2.0); + QPointF viewport_center = m_view->mapFromScene(m_targetScenePos) - delta_viewport_pos; + m_view->centerOn(m_view->mapToScene(viewport_center.toPoint())); + emit zoomed(); +} + +void GraphicsViewZoom::setModifiers(Qt::KeyboardModifiers modifiers) { + m_modifiers = modifiers; +} + +void GraphicsViewZoom::setZoomFactorBase(double value) { + m_zoomFactorBase = value; +} + +bool GraphicsViewZoom::eventFilter(QObject *object, QEvent *event) { + if (event->type() == QEvent::MouseMove) { + QMouseEvent* mouse_event = static_cast(event); + QPointF delta = m_targetViewportPos - mouse_event->pos(); + if (qAbs(delta.x()) > 5 || qAbs(delta.y()) > 5) { + m_targetViewportPos = mouse_event->pos(); + m_targetScenePos = m_view->mapToScene(mouse_event->pos()); + } + } else if (event->type() == QEvent::Wheel) { + QWheelEvent* wheel_event = static_cast(event); + if (QApplication::keyboardModifiers() == m_modifiers) { + if (wheel_event->orientation() == Qt::Vertical) { + double angle = wheel_event->angleDelta().y(); + double factor = qPow(m_zoomFactorBase, angle); + gentleZoom(factor); + return true; + } + } + } + Q_UNUSED(object) + return false; +} + // ReportDesignIntf ReportDesignWidget* ReportDesignWidget::m_instance=0; @@ -74,6 +126,8 @@ ReportDesignWidget::ReportDesignWidget(ReportEnginePrivate *report, QMainWindow connect(m_report,SIGNAL(cleared()),this,SIGNAL(cleared())); m_view->scale(0.5,0.5); m_instance=this; + //m_view->viewport()->installEventFilter(this); + m_zoomer = new GraphicsViewZoom(m_view); } ReportDesignWidget::~ReportDesignWidget() @@ -350,6 +404,18 @@ void ReportDesignWidget::slotSceneRectChanged(QRectF) m_view->centerOn(0,0); } +bool ReportDesignWidget::eventFilter(QObject *target, QEvent *event) +{ + if (event->type() == QEvent::Wheel){ + QWheelEvent* we = dynamic_cast(event); + if (QApplication::keyboardModifiers()==Qt::ControlModifier){ + if(we->delta()<0) scale(1.2,1.2); + else scale(1/1.2,1/1.2); + } + } + return QWidget::eventFilter(target,event); +} + void ReportDesignWidget::clear() { m_report->clearReport(); diff --git a/src/lrreportdesignwidget.h b/src/lrreportdesignwidget.h index 7154ad6..dff1e04 100644 --- a/src/lrreportdesignwidget.h +++ b/src/lrreportdesignwidget.h @@ -47,6 +47,24 @@ class ReportEnginePrivate; class DataBrowser; class ReportDesignWindow; + +class GraphicsViewZoom : public QObject { + Q_OBJECT +public: + GraphicsViewZoom(QGraphicsView* view); + void gentleZoom(double factor); + void setModifiers(Qt::KeyboardModifiers modifiers); + void setZoomFactorBase(double value); +private: + QGraphicsView* m_view; + Qt::KeyboardModifiers m_modifiers; + double m_zoomFactorBase; + QPointF m_targetScenePos, m_targetViewportPos; + bool eventFilter(QObject* object, QEvent* event); +signals: + void zoomed(); +}; + class ReportDesignWidget : public QWidget { Q_OBJECT @@ -123,11 +141,13 @@ signals: void itemAdded(LimeReport::PageDesignIntf*, LimeReport::BaseDesignIntf*); void itemDeleted(LimeReport::PageDesignIntf*, LimeReport::BaseDesignIntf*); private: + bool eventFilter(QObject *target, QEvent *event); ReportDesignWidget(ReportEnginePrivate* report,QMainWindow *mainWindow,QWidget *parent = 0); private: ReportEnginePrivate* m_report; QGraphicsView *m_view; QMainWindow *m_mainWindow; + GraphicsViewZoom* m_zoomer; static ReportDesignWidget* m_instance; }; diff --git a/src/lrreportdesignwindow.cpp b/src/lrreportdesignwindow.cpp index 30b8fec..b5cca65 100644 --- a/src/lrreportdesignwindow.cpp +++ b/src/lrreportdesignwindow.cpp @@ -49,7 +49,6 @@ #include "lrbasedesignintf.h" #include "lrpagedesignintf.h" -#include "waitform.h" #include "lrpreviewreportwindow.h" #include "serializators/lrstorageintf.h" #include "serializators/lrxmlreader.h" @@ -78,6 +77,8 @@ ReportDesignWindow::ReportDesignWindow(ReportEnginePrivate *report, QWidget *par setStatusBar(m_statusBar); setWindowTitle("Lime Report Designer"); restoreSetting(); + m_hideLeftPanel->setChecked(isDockAreaVisible(Qt::LeftDockWidgetArea)); + m_hideRightPanel->setChecked(isDockAreaVisible(Qt::RightDockWidgetArea)); } ReportDesignWindow::~ReportDesignWindow() @@ -187,6 +188,17 @@ void ReportDesignWindow::createActions() m_aboutAction->setIcon(QIcon(":/report/images/copyright")); connect(m_aboutAction,SIGNAL(triggered()),this,SLOT(slotShowAbout())); + m_hideLeftPanel = new QAction(tr("Hide left panel"),this); + m_hideLeftPanel->setCheckable(true); + m_hideLeftPanel->setChecked(true); + m_hideLeftPanel->setIcon(QIcon(":/report/images/hideLeftPanel")); + connect(m_hideLeftPanel,SIGNAL(toggled(bool)), this, SLOT(slotHideLeftPanel(bool))); + + m_hideRightPanel = new QAction(tr("Hide left panel"),this); + m_hideRightPanel->setCheckable(true); + m_hideRightPanel->setChecked(true); + m_hideRightPanel->setIcon(QIcon(":/report/images/hideRightPanel")); + connect(m_hideRightPanel,SIGNAL(toggled(bool)), this, SLOT(slotHideRightPanel(bool))); } void ReportDesignWindow::createReportToolBar() @@ -203,7 +215,15 @@ void ReportDesignWindow::createReportToolBar() m_reportToolBar->addAction(m_addHLayout); m_reportToolBar->addSeparator(); m_reportToolBar->addAction(m_deleteItemAction); + + QWidget* empty = new QWidget(); + empty->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); + m_reportToolBar->addWidget(empty); + + m_reportToolBar->addAction(m_hideLeftPanel); + m_reportToolBar->addAction(m_hideRightPanel); addToolBar(Qt::LeftToolBarArea,m_reportToolBar); + } void ReportDesignWindow::createToolBars() @@ -880,6 +900,34 @@ void ReportDesignWindow::slotShowAbout() about->exec(); } +void ReportDesignWindow::hideDockWidgets(Qt::DockWidgetArea area, bool value){ + QList dockWidgets = findChildren(); + foreach (QDockWidget* dw, dockWidgets) { + if (dockWidgetArea(dw) == area) + value ? dw->show(): dw->hide(); + } +} + +bool ReportDesignWindow::isDockAreaVisible(Qt::DockWidgetArea area) +{ + QList dockWidgets = findChildren(); + foreach (QDockWidget* dw, dockWidgets){ + if ((dockWidgetArea(dw) == area) && !dw->isHidden()) + return true; + } + return false; +} + +void ReportDesignWindow::slotHideLeftPanel(bool value) +{ + hideDockWidgets(Qt::LeftDockWidgetArea,value); +} + +void ReportDesignWindow::slotHideRightPanel(bool value) +{ + hideDockWidgets(Qt::RightDockWidgetArea,value); +} + void ReportDesignWindow::closeEvent(QCloseEvent * event) { if (checkNeedToSave()){ diff --git a/src/lrreportdesignwindow.h b/src/lrreportdesignwindow.h index 98ef864..6be217f 100644 --- a/src/lrreportdesignwindow.h +++ b/src/lrreportdesignwindow.h @@ -107,10 +107,14 @@ private slots: void renderPageFinished(int renderedPageCount); void renderFinished(); void slotShowAbout(); + void slotHideLeftPanel(bool value); + void slotHideRightPanel(bool value); protected: void closeEvent(QCloseEvent *event); void resizeEvent(QResizeEvent *); void moveEvent(QMoveEvent *); + void hideDockWidgets(Qt::DockWidgetArea area, bool value); + bool isDockAreaVisible(Qt::DockWidgetArea area); private: void createActions(); void createBandsButton(); @@ -177,6 +181,8 @@ private: QAction* m_aboutAction; QAction* m_editLayoutMode; QAction* m_addHLayout; + QAction* m_hideLeftPanel; + QAction* m_hideRightPanel; QSignalMapper* m_bandsAddSignalsMap; diff --git a/src/lrreportengine.cpp b/src/lrreportengine.cpp index 728b498..909e399 100644 --- a/src/lrreportengine.cpp +++ b/src/lrreportengine.cpp @@ -58,8 +58,6 @@ ReportEnginePrivate::ReportEnginePrivate(QObject *parent) : { m_datasources= new DataSourceManager(this); m_datasources->setObjectName("datasources"); - //m_reportRender=ReportRender::Ptr(new ReportRender()); - //m_reportRender->setDatasources(m_datasources); connect(m_datasources,SIGNAL(loadCollectionFinished(QString)),this,SLOT(slotDataSourceCollectionLoaded(QString))); } @@ -85,7 +83,6 @@ PageDesignIntf *ReportEnginePrivate::createPage(const QString &pageName) PageDesignIntf* page =new PageDesignIntf(this); page->setObjectName(pageName); page->setReportEditor(this); - //m_pages.append(page); return page; } @@ -110,9 +107,9 @@ void ReportEnginePrivate::collectionLoadFinished(const QString &) { foreach (PageDesignIntf* page, m_pages) { page->setReportEditor(this); - page->setSceneRect(-SCENE_MARGIN,-SCENE_MARGIN, - page->pageItem()->width()+SCENE_MARGIN*2, - page->pageItem()->height()+SCENE_MARGIN*2); + page->setSceneRect(-Const::SCENE_MARGIN,-Const::SCENE_MARGIN, + page->pageItem()->width()+Const::SCENE_MARGIN*2, + page->pageItem()->height()+Const::SCENE_MARGIN*2); } emit pagesLoadFinished(); } @@ -228,7 +225,6 @@ void ReportEnginePrivate::printReport(ReportPages pages, QPrinter &printer, cons bool ReportEnginePrivate::printReport(QPrinter* printer) { - //QScopedPointerl_printer(new QPrinter(QPrinter::HighResolution)); if (!printer&&!m_printerSelected){ QPrintDialog dialog(m_printer.data(),QApplication::activeWindow()); m_printerSelected = dialog.exec()!=QDialog::Rejected; @@ -266,6 +262,17 @@ void ReportEnginePrivate::printToFile(const QString &fileName) } } +bool ReportEnginePrivate::printToPDF(const QString &fileName) +{ + if (!fileName.isEmpty()){ + QPrinter printer; + printer.setOutputFileName(fileName); + printer.setOutputFormat(QPrinter::PdfFormat); + return printReport(&printer); + } + return false; +} + void ReportEnginePrivate::previewReport() { QTime start = QTime::currentTime(); @@ -312,11 +319,6 @@ void ReportEnginePrivate::cancelRender() m_reportRender->cancelRender(); } -//PageDesignIntf* ReportEngine::createPreviewScene(QObject* parent){ -// Q_D(ReportEngine); -// return d->createPreviewScene(parent); -//} - void ReportEnginePrivate::designReport() { LimeReport::ReportDesignWindow* w = new LimeReport::ReportDesignWindow(this,QApplication::activeWindow(),settings()); @@ -364,7 +366,6 @@ QSettings*ReportEnginePrivate::settings() bool ReportEnginePrivate::loadFromFile(const QString &fileName) { clearReport(); - //QScopedPointer< ItemsReaderIntf > reader(new FileXMLReader(fileName)); ItemsReaderIntf::Ptr reader = FileXMLReader::create(fileName); if (reader->first()){ if (reader->readItem(this)){ @@ -434,8 +435,6 @@ QString ReportEnginePrivate::renderToString() ReportPages ReportEnginePrivate::renderToPages() { - - //ReportRender render; m_reportRender = ReportRender::Ptr(new ReportRender); dataManager()->clearErrorsList(); dataManager()->connectAllDatabases(); @@ -479,17 +478,18 @@ bool ReportEngine::printReport(QPrinter *printer) return d->printReport(printer); } -//void ReportEngine::printReport(ReportPages pages, QPrinter &printer){ -// Q_D(ReportEngine); -// d->printReport(pages,printer,PrintRange()); -//} - void ReportEngine::printToFile(const QString &fileName) { Q_D(ReportEngine); d->printToFile(fileName); } +bool ReportEngine::printToPDF(const QString &fileName) +{ + Q_D(ReportEngine); + return d->printToPDF(fileName); +} + void ReportEngine::previewReport() { Q_D(ReportEngine); @@ -541,12 +541,6 @@ QString ReportEngine::reportFileName() return d->reportFileName(); } -//void ReportDesignIntf::setPrinter(QPrinter *printer) -//{ -// Q_D(ReportDesignIntf); -// d->setPrinter(printer); -//} - bool ReportEngine::saveToFile() { Q_D(ReportEngine); diff --git a/src/lrreportengine.h b/src/lrreportengine.h index 924976a..7bfa6a8 100644 --- a/src/lrreportengine.h +++ b/src/lrreportengine.h @@ -37,13 +37,11 @@ #include "lrglobal.h" #include "lrdatasourcemanagerintf.h" #include "lrscriptenginemanagerintf.h" -//#include "lrreportrender.h" class QPrinter; namespace LimeReport { - class PrintRange{ public: int fromPage() const { return m_fromPage;} @@ -61,7 +59,6 @@ private: class DataSourceManager; class ReportEnginePrivate; -//class PageDesignIntf; class LIMEREPORT_EXPORT ReportEngine : public QObject{ Q_OBJECT @@ -71,9 +68,8 @@ public: explicit ReportEngine(QObject *parent = 0); ~ReportEngine(); bool printReport(QPrinter *printer=0); - //void printReport(ReportPages pages, QPrinter &printer); void printToFile(const QString& fileName); - //PageDesignIntf *createPreviewScene(QObject *parent = 0); + bool printToPDF(const QString& fileName); void previewReport(); void designReport(); void setShowProgressDialog(bool value); diff --git a/src/lrreportengine_p.h b/src/lrreportengine_p.h index 6e67427..9273fa8 100644 --- a/src/lrreportengine_p.h +++ b/src/lrreportengine_p.h @@ -71,6 +71,7 @@ public: void clearReport(); bool printReport(QPrinter *printer=0); void printToFile(const QString& fileName); + bool printToPDF(const QString& fileName); void previewReport(); void designReport(); void setSettings(QSettings* value); diff --git a/src/lrreportrender.cpp b/src/lrreportrender.cpp index 12cfe5f..41121a3 100644 --- a/src/lrreportrender.cpp +++ b/src/lrreportrender.cpp @@ -124,6 +124,7 @@ void ReportRender::initRenderPage() if (!m_renderPageItem) { m_renderPageItem = new PageItemDesignIntf(m_patternPageItem->pageSize(), m_patternPageItem->pageRect()); m_renderPageItem->initFromItem(m_patternPageItem); + m_renderPageItem->setItemMode(PreviewMode); } } @@ -144,18 +145,18 @@ void ReportRender::extractGroupsFunction(BandDesignIntf *band) ContentItemDesignIntf* contentItem = dynamic_cast(item); if (contentItem&&(contentItem->content().contains(QRegExp("\\$S\\s*\\{.*\\}")))){ foreach(QString functionName, DataSourceManager::instance()->groupFunctionNames()){ - QRegExp rx(QString(GROUP_FUNCTION_RX).arg(functionName)); - QRegExp rxName(QString(GROUP_FUNCTION_NAME_RX).arg(functionName)); + QRegExp rx(QString(Const::GROUP_FUNCTION_RX).arg(functionName)); + QRegExp rxName(QString(Const::GROUP_FUNCTION_NAME_RX).arg(functionName)); if (rx.indexIn(contentItem->content())>=0){ - BandDesignIntf* dataBand = m_patternPageItem->bandByName(rx.cap(DATASOURCE_INDEX)); + BandDesignIntf* dataBand = m_patternPageItem->bandByName(rx.cap(Const::DATASOURCE_INDEX)); if (dataBand){ - GroupFunction* gf = datasources()->addGroupFunction(functionName,rx.cap(VALUE_INDEX),band->objectName(),dataBand->objectName()); + GroupFunction* gf = datasources()->addGroupFunction(functionName,rx.cap(Const::VALUE_INDEX),band->objectName(),dataBand->objectName()); if (gf){ connect(dataBand,SIGNAL(bandRendered(BandDesignIntf*)),gf,SLOT(slotBandRendered(BandDesignIntf*))); } } else { - GroupFunction* gf = datasources()->addGroupFunction(functionName,rx.cap(VALUE_INDEX),band->objectName(),rx.cap(DATASOURCE_INDEX)); - gf->setInvalid(tr("Databand \"%1\" not found").arg(rx.cap(DATASOURCE_INDEX))); + GroupFunction* gf = datasources()->addGroupFunction(functionName,rx.cap(Const::VALUE_INDEX),band->objectName(),rx.cap(Const::DATASOURCE_INDEX)); + gf->setInvalid(tr("Databand \"%1\" not found").arg(rx.cap(Const::DATASOURCE_INDEX))); } } else if (rxName.indexIn(contentItem->content())>=0){ GroupFunction* gf = datasources()->addGroupFunction(functionName,rxName.cap(1),band->objectName(),""); @@ -173,7 +174,7 @@ void ReportRender::replaceGroupsFunction(BandDesignIntf *band) if (contentItem){ QString content = contentItem->content(); foreach(QString functionName, DataSourceManager::instance()->groupFunctionNames()){ - QRegExp rx(QString(GROUP_FUNCTION_RX).arg(functionName)); + QRegExp rx(QString(Const::GROUP_FUNCTION_RX).arg(functionName)); if (rx.indexIn(content)>=0){ content.replace(rx,QString("%1(%2,%3)").arg(functionName).arg('"'+rx.cap(4)+'"').arg('"'+band->objectName()+'"')); contentItem->setContent(content); @@ -272,7 +273,7 @@ void ReportRender::renderDataBand(BandDesignIntf *dataBand) renderGroupHeader(dataBand,bandDatasource); if (dataBand->tryToKeepTogether()) closeDataGroup(dataBand); } - renderBand(dataBand->bandFooter()); + renderBand(dataBand->bandFooter(),StartNewPage); renderGroupFooter(dataBand); //renderChildFooter(dataBand,PrintNotAlwaysPrintable); datasources()->deleteVariable(varName); @@ -590,7 +591,7 @@ void ReportRender::startNewPage() m_renderPageItem->setObjectName(QLatin1String("ReportPage")+QString::number(m_pageCount)); m_currentMaxHeight=m_renderPageItem->pageRect().height(); - m_currentStartDataPos=m_patternPageItem->topMargin()*mmFACTOR; + m_currentStartDataPos=m_patternPageItem->topMargin()*Const::mmFACTOR; m_currentIndex=0; renderPageHeader(m_patternPageItem); diff --git a/src/report.qrc b/src/report.qrc index 8e711c0..5d48873 100644 --- a/src/report.qrc +++ b/src/report.qrc @@ -154,5 +154,9 @@ images/logo.png images/cpyright_logo.png images/logo_100.png + images/empty.png + images/hideLeftPanel.png + images/hideRightPanel.png + images/PDF2.png diff --git a/src/scriptbrowser/lrscriptbrowser.cpp b/src/scriptbrowser/lrscriptbrowser.cpp new file mode 100644 index 0000000..ea38798 --- /dev/null +++ b/src/scriptbrowser/lrscriptbrowser.cpp @@ -0,0 +1,195 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + ****************************************************************************/ +#include "lrscriptbrowser.h" +#include "ui_lrscriptbrowser.h" + +#ifdef HAVE_UI_LOADER +#include +#include +#endif +#include + +namespace LimeReport{ + +ScriptBrowser::ScriptBrowser(QWidget *parent) : + QWidget(parent), + ui(new Ui::ScriptBrowser) +{ + ui->setupUi(this); +#ifndef HAVE_UI_LOADER + ui->tpDialogs->setVisible(false); + ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tpDialogs)); +#endif +} + +ScriptBrowser::~ScriptBrowser() +{ + delete ui; +} + +void ScriptBrowser::setReportEditor(ReportDesignWidget* report) +{ + m_report=report; + connect(m_report,SIGNAL(cleared()),this,SLOT(slotClear())); + connect(m_report,SIGNAL(loaded()),this,SLOT(slotUpdate())); + updateFunctionTree(); +} + +void ScriptBrowser::updateFunctionTree() +{ + ScriptEngineManager* sm = reportEditor()->scriptManager(); + QMap categ; + foreach(ScriptFunctionDesc fd, sm->functionsDescriber()){ + QString functionCategory = (fd.category!="") ? fd.category : tr("NO CATEGORY"); + if (categ.contains(functionCategory)){ + QTreeWidgetItem* item = new QTreeWidgetItem(categ.value(fd.category),QStringList(fd.name)); + item->setIcon(0,QIcon(":/report/images/function")); + } else { + QTreeWidgetItem* categItem = new QTreeWidgetItem(ui->twFunctions,QStringList(functionCategory)); + categItem->setIcon(0,QIcon(":/report/images/folder")); + categ.insert(functionCategory,categItem); + QTreeWidgetItem* item = new QTreeWidgetItem(categItem,QStringList(fd.name)); + item->setIcon(0,QIcon(":/report/images/function")); + } + } +} + +#ifdef HAVE_UI_LOADER +void ScriptBrowser::fillProperties(QTreeWidgetItem* objectItem, QObject* item){ + for(int i=0; imetaObject()->propertyCount(); ++i){ + QStringList row; + row<metaObject()->property(i).typeName()<metaObject()->property(i).name(); + /*QTreeWidgetItem* propItem = */new QTreeWidgetItem(objectItem,row); + } +} + +void ScriptBrowser::fillDialog(QTreeWidgetItem* dialogItem,const QString& description){ + + QUiLoader loader; + QByteArray baDesc = description.toUtf8(); + QBuffer buff(&baDesc); + buff.open(QIODevice::ReadOnly); + QDialog* dialog = dynamic_cast(loader.load(&buff)); + if (dialog){ + foreach (QObject* child, dialog->children()) { + if (!child->objectName().isEmpty()){ + QStringList row; + row<metaObject()->className()<objectName(); + QTreeWidgetItem* item = new QTreeWidgetItem(dialogItem,row); + item->setIcon(0,QIcon(":/scriptbrowser/images/item")); + fillProperties(item,child); + } + } + delete dialog; + } + +} + +void ScriptBrowser::updateDialogsTree() +{ + ui->twDialogs->clear(); + ScriptEngineContext* sc = reportEditor()->scriptContext(); + foreach(DialogDescriber::Ptr dc, sc->dialogsDescriber()){ + QTreeWidgetItem* dialogItem = new QTreeWidgetItem(ui->twDialogs,QStringList(dc->name())); + dialogItem->setIcon(0,QIcon(":/scriptbrowser/images/dialog")); + fillDialog(dialogItem,dc->description()); + } +} +#endif +void ScriptBrowser::slotClear() +{ + ui->twDialogs->clear(); + ui->twFunctions->clear(); +} + +void ScriptBrowser::slotUpdate() +{ +#ifdef HAVE_UI_LOADER + updateDialogsTree(); +#endif + updateFunctionTree(); +} + +#ifdef HAVE_UI_LOADER +void ScriptBrowser::on_tbAddDialog_clicked() +{ + QFileDialog fileDialog(this); + if (fileDialog.exec()==QDialog::Accepted){ + QStringList fileNames = fileDialog.selectedFiles(); + QUiLoader loader; + + if (!fileNames.isEmpty()){ + foreach (QString fileName, fileNames) { + QFile file(fileName); + file.open(QIODevice::ReadOnly); + if (file.isOpen()){ + QWidget* widget = loader.load(&file); + QDialog* dialog = dynamic_cast(widget); + if (dialog){ + if (!m_report->scriptContext()->containsDialog(dialog->objectName())){ + file.seek(0); + m_report->scriptContext()->addDialog(dialog->objectName(),file.readAll()); + updateDialogsTree(); + } else { + QMessageBox::critical(this,tr("Error"),tr("Dialog with name: %1 already exists").arg(dialog->objectName())); + } + } else { + if (widget) + QMessageBox::critical(this,tr("Error"),tr("ui file must cointain QDialog instead QWidget or QMainWindow")); + else + QMessageBox::critical(this,tr("Error"),tr("wrong file format")); + } + if (widget) delete widget; + } + } + } + } +} + +void ScriptBrowser::on_tbRunDialog_clicked() +{ + if (ui->twDialogs->currentItem()&& ui->twDialogs->currentItem()->parent()==0){ + m_report->scriptContext()->previewDialog(ui->twDialogs->currentItem()->text(0)); + } +} + +void ScriptBrowser::on_tbDeleteDialog_clicked() +{ + if (ui->twDialogs->currentItem()&& ui->twDialogs->currentItem()->parent()==0){ + m_report->scriptContext()->deleteDialog(ui->twDialogs->currentItem()->text(0)); + updateDialogsTree(); + } +} + +#endif + +} //namespace LimeReport + + diff --git a/src/scriptbrowser/lrscriptbrowser.h b/src/scriptbrowser/lrscriptbrowser.h new file mode 100644 index 0000000..214977b --- /dev/null +++ b/src/scriptbrowser/lrscriptbrowser.h @@ -0,0 +1,77 @@ +/*************************************************************************** + * This file is part of the Lime Report project * + * Copyright (C) 2015 by Alexander Arin * + * arin_a@bk.ru * + * * + ** GNU General Public License Usage ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + * * + ** GNU Lesser General Public License ** + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library. * + * If not, see . * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + ****************************************************************************/ +#ifndef LRSCRIPTBROWSER_H +#define LRSCRIPTBROWSER_H + +#include +#include +#include +#include "lrreportdesignwidget.h" + +namespace Ui { +class ScriptBrowser; +} + +namespace LimeReport{ + +class ScriptBrowser : public QWidget +{ + Q_OBJECT + +public: + explicit ScriptBrowser(QWidget *parent = 0); + ~ScriptBrowser(); + void setReportEditor(LimeReport::ReportDesignWidget* report); + inline ReportDesignWidget* reportEditor(){return m_report;} + void updateFunctionTree(); +#ifdef HAVE_UI_LOADER + void updateDialogsTree(); +#endif +protected: +#ifdef HAVE_UI_LOADER + void fillDialog(QTreeWidgetItem *dialogItem, const QString &description); + void fillProperties(QTreeWidgetItem *objectItem, QObject *item); +#endif +private slots: + void slotClear(); + void slotUpdate(); +#ifdef HAVE_UI_LOADER + void on_tbAddDialog_clicked(); + void on_tbRunDialog_clicked(); + void on_tbDeleteDialog_clicked(); +#endif + +private: + Ui::ScriptBrowser *ui; + ReportDesignWidget* m_report; +}; + +} // namespace LimeReport +#endif // LRSCRIPTBROWSER_H