From 9a792e453c5433b28219cba7a022af13bf5e4727 Mon Sep 17 00:00:00 2001 From: Sergey Popovichev Date: Wed, 17 Feb 2016 10:39:17 +0300 Subject: [PATCH] 1.3.9 --- README.md | 56 +++- include/lrdatasourcemanagerintf.h | 5 +- include/lrglobal.h | 6 +- include/lrreportengine.h | 8 + report-lib.pri | 10 +- src/bands/lrdataband.h | 3 + src/bands/lrgroupbands.cpp | 17 +- src/bands/lrgroupbands.h | 9 +- src/databrowser/lrdatabrowser.ui | 24 ++ .../editors/lrtextalignmenteditorwidget.cpp | 22 +- src/items/lrshapeitem.cpp | 26 +- src/items/lrshapeitem.h | 4 + src/items/lrtextitem.cpp | 243 +++++++++++------- src/items/lrtextitem.h | 13 +- src/lrbanddesignintf.cpp | 39 ++- src/lrbanddesignintf.h | 34 ++- src/lrbasedesignintf.cpp | 195 +++++++++++--- src/lrbasedesignintf.h | 22 +- src/lrdatadesignintf.cpp | 15 +- src/lrdatadesignintf.h | 8 + src/lrdatasourcemanager.cpp | 57 +++- src/lrdatasourcemanager.h | 5 +- src/lrdatasourcemanagerintf.h | 5 +- src/lrglobal.h | 6 +- src/lritemdesignintf.cpp | 25 +- src/lritemdesignintf.h | 5 +- src/lrpagedesignintf.cpp | 209 +++++++++++---- src/lrpagedesignintf.h | 39 ++- src/lrpageitemdesignintf.cpp | 67 ++++- src/lrpageitemdesignintf.h | 7 +- src/lrpreviewreportwindow.cpp | 12 + src/lrreportdesignwidget.cpp | 12 +- src/lrreportdesignwidget.h | 3 +- src/lrreportdesignwindow.cpp | 45 +++- src/lrreportengine.cpp | 116 ++++++++- src/lrreportengine.h | 8 + src/lrreportengine_p.h | 17 +- src/lrreportrender.cpp | 225 ++++++++++++++-- src/lrreportrender.h | 12 +- src/lrscriptenginemanager.cpp | 26 +- .../editors/lrcomboboxeditor.h | 2 +- src/objectinspector/lrobjectitemmodel.cpp | 40 ++- .../propertyItems/lrdatasourcepropitem.cpp | 2 +- .../propertyItems/lrenumpropitem.cpp | 2 +- .../propertyItems/lrflagspropitem.cpp | 2 +- .../propertyItems/lrgroupfieldpropitem.cpp | 2 +- src/objectsbrowser/lrobjectbrowser.cpp | 27 +- src/objectsbrowser/lrobjectbrowser.h | 2 +- src/serializators/lrstorageintf.h | 1 + src/serializators/lrxmlwriter.cpp | 8 + src/serializators/lrxmlwriter.h | 8 +- translations/limereport_ru.qm | Bin 85584 -> 86199 bytes translations/limereport_ru.ts | 197 ++++++++------ 53 files changed, 1525 insertions(+), 428 deletions(-) diff --git a/README.md b/README.md index 1227378..a4d7fc1 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,62 @@ -# LimeReport +# LimeReport v1.3.9 ##How to use it 1. Build limereport.pro. It will create a limereport shared library 2. In your project connect the limereport library then in source code add: - -```C - #include "lrreportengine.h" to add report engine + +```cpp + #include "lrreportengine.h" to add report engine #include "lrcallbackdatasourceintf.h" if you want use callback datasources report = new LimeReport::ReportEngine(this); to create reportengine report->dataManager()->addModel("string_list",stringListModel,true); to add datasource to report engine report->loadFromFile("File name"); to load report template file report->previewReport(); to generate report and preview - report->printReport(); to print report + report->printReport(); to print report ``` -For more samples see a demo \ No newline at end of file +For more samples see a demo + +## Change log +###1.3.9 +New functions: +```cpp + QString::saveToString(), + loadFromString(const QString& report, const QString& name=""), + QByteArray::saveToByteArray(), + setCurrentReportsDir(const QString& dirName), +``` +added to LimeReport::ReportEngine + +1. printOnEach page and columns have been added to DataHeader band +2. startNewPage added to DataBand + +Performance has been improved + +**WARNING** +From this version the item "Text" by default does not use HTML. +To enable HTML support you need to use the property allowHTML + +###1.3.1 +Added: +1. Columns + Some bands can be divided into columns +2. Items align + Report items now may be aligned to the left,right or center of container + also it can be stretched to the whole width of container +3. Group can start new page +4. Group can reset page number; +5. Table mode added to horizontal layout + This mode allows you to distribute the internal layout's space among grouped items + +Fixed: +1. Postgresql connection +2. The error that prevented normal run of more than one instance of LimeReport::ReportEngine + +###1.2.1 +1. Added buttons to open / hide sidebars; +2. Improved look-and-feel of report elements to clarify designing process; +3. Printing to PDF added. +4. Fixed bug in SQL-editor when it used variables in SQL expression; +5. Fixed bug of variable's initialization if it exists more than once in SQL expression; +6. .. and other minor bugs fixed. \ No newline at end of file diff --git a/include/lrdatasourcemanagerintf.h b/include/lrdatasourcemanagerintf.h index 123f049..7ff5aee 100644 --- a/include/lrdatasourcemanagerintf.h +++ b/include/lrdatasourcemanagerintf.h @@ -43,11 +43,12 @@ public: virtual void deleteVariable(const QString& name)=0; virtual bool containsVariable(const QString& variableName)=0; virtual QVariant variable(const QString& variableName)=0; - virtual void addModel(const QString& name, QAbstractItemModel *model, bool owned)=0; + virtual bool addModel(const QString& name, QAbstractItemModel *model, bool owned)=0; + virtual void removeModel(const QString& name)=0; virtual bool containsDatasource(const QString& dataSourceName)=0; virtual void clearUserVariables()=0; virtual ICallbackDatasource* createCallbackDatasouce(const QString& name) = 0; - virtual void addCallbackDatasource(ICallbackDatasource* datasource, const QString& name) = 0; + //virtual void addCallbackDatasource(ICallbackDatasource* datasource, const QString& name) = 0; }; } diff --git a/include/lrglobal.h b/include/lrglobal.h index e0908fc..c652ad7 100644 --- a/include/lrglobal.h +++ b/include/lrglobal.h @@ -52,7 +52,7 @@ namespace Const{ 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; + double const SELECTION_COLOR_OPACITY = 0.6; const qreal fontFACTOR = 3.5; const int mmFACTOR = 10; const int itemPaleteIconSize = 24; @@ -65,8 +65,8 @@ namespace Const{ const qreal BAND_NAME_AREA_OPACITY = 0.3; const qreal BAND_NAME_TEXT_OPACITY = 0.6; const qreal SELECTION_OPACITY = 0.3; - const QString FIELD_RX = "\\$D\\s*\\{\\s*([^\\s{}]*)\\s*\\}"; - const QString VARIABLE_RX = "\\$V\\s*\\{\\s*([^\\s{}]*)\\s*\\}"; + const QString FIELD_RX = "\\$D\\s*\\{\\s*([^{}]*)\\s*\\}"; + const QString VARIABLE_RX = "\\$V\\s*\\{\\s*([^{}]*)\\s*\\}"; const QString SCRIPT_RX = "\\$S\\s*\\{(.*)\\}"; const QString GROUP_FUNCTION_PARAM_RX = "\\(\\s*(((?:\\\"?\\$D\\s*\\{\\s*)|(?:\\\"?\\$V\\s*\\{\\s*)|(?:\\\"))(\\w+\\.?\\w+)((?:\\\")|(?:\\s*\\}\\\"?\\s*)))\\s*,\\s*\\\"(\\w+)\\\"\\s*\\)"; const int DATASOURCE_INDEX = 6; diff --git a/include/lrreportengine.h b/include/lrreportengine.h index 7bfa6a8..1eb4966 100644 --- a/include/lrreportengine.h +++ b/include/lrreportengine.h @@ -78,14 +78,22 @@ public: bool loadFromFile(const QString& fileName); bool loadFromByteArray(QByteArray *data); + bool loadFromString(const QString& data); QString reportFileName(); bool saveToFile(); bool saveToFile(const QString& fileName); + QByteArray saveToByteArray(); + QString saveToString(); QString lastError(); + void setCurrentReportsDir(const QString& dirName); + void setReportName(const QString& name); + QString reportName(); signals: void renderStarted(); void renderFinished(); void renderPageFinished(int renderedPageCount); + void onLoad(bool& loaded); + void onSave(); public slots: void cancelRender(); protected: diff --git a/report-lib.pri b/report-lib.pri index 86a7da7..61a7b84 100644 --- a/report-lib.pri +++ b/report-lib.pri @@ -3,7 +3,7 @@ REPORT_PATH = $$PWD LIMEREPORT_VERSION_MAJOR = 1 LIMEREPORT_VERSION_MINOR = 3 -LIMEREPORT_VERSION_RELEASE = 1 +LIMEREPORT_VERSION_RELEASE = 9 LIMEREPORT_VERSION = '\\"$${LIMEREPORT_VERSION_MAJOR}.$${LIMEREPORT_VERSION_MINOR}.$${LIMEREPORT_VERSION_RELEASE}\\"' DEFINES += LIMEREPORT_VERSION_STR=\"$${LIMEREPORT_VERSION}\" @@ -71,6 +71,7 @@ SOURCES += \ $$REPORT_PATH/objectinspector/propertyItems/lrcolorpropitem.cpp \ $$REPORT_PATH/objectinspector/propertyItems/lrdatasourcepropitem.cpp \ $$REPORT_PATH/objectinspector/propertyItems/lrgroupfieldpropitem.cpp \ + $$REPORT_PATH/objectinspector/propertyItems/lrcontentpropitem.cpp \ $$REPORT_PATH/objectsbrowser/lrobjectbrowser.cpp \ $$REPORT_PATH/databrowser/lrdatabrowser.cpp \ $$REPORT_PATH/databrowser/lrsqleditdialog.cpp \ @@ -105,7 +106,6 @@ SOURCES += \ $$REPORT_PATH/lrreportengine.cpp \ $$REPORT_PATH/lrdatasourcemanager.cpp \ $$REPORT_PATH/lrreportdesignwindow.cpp \ - $$REPORT_PATH/waitform.cpp \ $$REPORT_PATH/lrreportrender.cpp \ $$REPORT_PATH/lrscriptenginemanager.cpp \ $$REPORT_PATH/lrpreviewreportwindow.cpp \ @@ -162,6 +162,7 @@ HEADERS += \ $$REPORT_PATH/objectinspector/editors/lrcheckboxeditor.h \ $$REPORT_PATH/objectinspector/editors/lrbuttonlineeditor.h \ $$REPORT_PATH/objectinspector/propertyItems/lrgroupfieldpropitem.h \ + $$REPORT_PATH/objectinspector/propertyItems/lrcontentpropitem.h \ $$REPORT_PATH/objectsbrowser/lrobjectbrowser.h \ $$REPORT_PATH/items/lrtextitem.h \ $$REPORT_PATH/items/lrsubitemparentpropitem.h \ @@ -179,7 +180,6 @@ HEADERS += \ $$REPORT_PATH/lrreportengine_p.h \ $$REPORT_PATH/lrdatasourcemanager.h \ $$REPORT_PATH/lrreportdesignwindow.h \ - $$REPORT_PATH/waitform.h \ $$REPORT_PATH/items/lrsimpletagparser.h \ $$REPORT_PATH/bands/lrsubdetailband.h \ $$REPORT_PATH/lrreportrender.h \ @@ -216,7 +216,6 @@ FORMS += \ $$REPORT_PATH/databrowser/lrdatabrowser.ui \ $$REPORT_PATH/databrowser/lrvariabledialog.ui \ $$REPORT_PATH/objectinspector/editors/ltextitempropertyeditor.ui \ - $$REPORT_PATH/waitform.ui \ $$REPORT_PATH/lrpreviewreportwindow.ui \ $$REPORT_PATH/items/lrtextitemeditor.ui \ $$REPORT_PATH/lraboutdialog.ui @@ -226,3 +225,6 @@ RESOURCES += \ $$REPORT_PATH/databrowser/lrdatabrowser.qrc \ $$REPORT_PATH/report.qrc \ $$REPORT_PATH/items/items.qrc + + +TRANSLATIONS += limereport_ru.ts diff --git a/src/bands/lrdataband.h b/src/bands/lrdataband.h index 8288279..cc7b81d 100644 --- a/src/bands/lrdataband.h +++ b/src/bands/lrdataband.h @@ -45,6 +45,7 @@ class DataBand : public DataBandDesignIntf Q_PROPERTY(bool sliceLastRow READ sliceLastRow WRITE setSliceLastRow) Q_PROPERTY(int columnsCount READ columnsCount WRITE setColumnsCount) Q_PROPERTY(BandColumnsLayoutType columnsFillDirection READ columnsFillDirection WRITE setColumnsFillDirection) + Q_PROPERTY(bool startNewPage READ startNewPage WRITE setStartNewPage) public: DataBand(QObject* owner = 0, QGraphicsItem* parent=0); bool isUnique() const; @@ -58,6 +59,8 @@ private: class DataHeaderBand : public BandDesignIntf { Q_OBJECT + Q_PROPERTY(bool reprintOnEachPage READ reprintOnEachPage WRITE setReprintOnEachPage) + Q_PROPERTY(int columnsCount READ columnsCount WRITE setColumnsCount) public: DataHeaderBand(QObject* owner=0, QGraphicsItem* parent=0); bool isUnique() const {return false;} diff --git a/src/bands/lrgroupbands.cpp b/src/bands/lrgroupbands.cpp index 3702d73..752189b 100644 --- a/src/bands/lrgroupbands.cpp +++ b/src/bands/lrgroupbands.cpp @@ -63,7 +63,7 @@ namespace LimeReport{ GroupBandHeader::GroupBandHeader(QObject *owner, QGraphicsItem *parent) : BandDesignIntf(BandDesignIntf::GroupHeader, xmlTagHeader, owner,parent), - m_groupFiledName(""), m_groupStarted(false), m_startNewPage(false), m_resetPageNumber(false) + m_groupFiledName(""), m_groupStarted(false), m_resetPageNumber(false) { setBandTypeText(tr("GroupHeader")); setFixedPos(false); @@ -104,11 +104,6 @@ QColor GroupBandHeader::bandColor() const return QColor(Qt::darkBlue); } -void GroupBandHeader::setStartNewPage(bool value) -{ - m_startNewPage = value; -} - bool GroupBandHeader::isNeedToClose(DataSourceManager* dataManager) { //if (m_groupFieldValue.isNull()) return false; @@ -141,6 +136,16 @@ int GroupBandHeader::index() return bandIndex(); } +bool GroupBandHeader::startNewPage() const +{ + return BandDesignIntf::startNewPage(); +} + +void GroupBandHeader::setStartNewPage(bool startNewPage) +{ + BandDesignIntf::setStartNewPage(startNewPage); +} + bool GroupBandHeader::resetPageNumber() const { return m_resetPageNumber; diff --git a/src/bands/lrgroupbands.h b/src/bands/lrgroupbands.h index 59b0475..53a8098 100644 --- a/src/bands/lrgroupbands.h +++ b/src/bands/lrgroupbands.h @@ -42,6 +42,7 @@ class GroupBandHeader : public BandDesignIntf, public IGroupBand{ Q_PROPERTY(bool keepGroupTogether READ tryToKeepTogether WRITE setTryToKeepTogether) Q_PROPERTY(bool startNewPage READ startNewPage WRITE setStartNewPage) Q_PROPERTY(bool resetPageNumber READ resetPageNumber WRITE setResetPageNumber) + Q_PROPERTY(bool reprintOnEachPage READ reprintOnEachPage WRITE setReprintOnEachPage) public: GroupBandHeader(QObject* owner = 0, QGraphicsItem* parent=0); virtual bool isUnique() const; @@ -50,10 +51,12 @@ public: QString groupFieldName(){return m_groupFiledName;} void setGroupFieldName(QString fieldName){m_groupFiledName=fieldName;} QColor bandColor() const; - bool startNewPage() const {return m_startNewPage;} - void setStartNewPage(bool value); + bool startNewPage() const; + void setStartNewPage(bool startNewPage); bool resetPageNumber() const; void setResetPageNumber(bool resetPageNumber); + bool isHeader() const{return true;} + bool isGroupHeader() const {return true;} private: virtual BaseDesignIntf* createSameTypeItem(QObject* owner=0, QGraphicsItem* parent=0); void startGroup(DataSourceManager* dataManager); @@ -65,7 +68,7 @@ private: QVariant m_groupFieldValue; QString m_groupFiledName; bool m_groupStarted; - bool m_startNewPage; + //bool m_startNewPage; bool m_resetPageNumber; }; diff --git a/src/databrowser/lrdatabrowser.ui b/src/databrowser/lrdatabrowser.ui index f5c4a05..6985bf0 100644 --- a/src/databrowser/lrdatabrowser.ui +++ b/src/databrowser/lrdatabrowser.ui @@ -166,6 +166,9 @@ + + Add new datasource + ... @@ -189,6 +192,9 @@ false + + View data + ... @@ -212,6 +218,9 @@ false + + Change datasource + ... @@ -235,6 +244,9 @@ false + + Delete datasource + ... @@ -258,6 +270,9 @@ false + + Show error + ... @@ -338,6 +353,9 @@ + + Add new variable + ... @@ -364,6 +382,9 @@ false + + Edit variable + ... @@ -387,6 +408,9 @@ false + + Delete variable + ... diff --git a/src/items/editors/lrtextalignmenteditorwidget.cpp b/src/items/editors/lrtextalignmenteditorwidget.cpp index 652f678..50da901 100644 --- a/src/items/editors/lrtextalignmenteditorwidget.cpp +++ b/src/items/editors/lrtextalignmenteditorwidget.cpp @@ -157,8 +157,17 @@ void TextAlignmentEditorWidget::slotTextHAttribsChanged(bool) m_textAliginRight->setChecked(sender()==m_textAliginRight); m_textAliginJustify->setChecked(sender()==m_textAliginJustify); - if (reportEditor()) reportEditor()->setTextAlign(createAlignment()); - if (page()) page()->setTextAlign(createAlignment()); + int flag = 0; + if (sender()==m_textAliginLeft) flag |= Qt::AlignLeft; + if (sender()==m_textAliginHCenter) flag |= Qt::AlignHCenter; + if (sender()==m_textAliginRight) flag |= Qt::AlignRight; + if (sender()==m_textAliginJustify) flag |= Qt::AlignJustify; + + if (reportEditor()) reportEditor()->setTextAlign(true,Qt::AlignmentFlag(flag)); + if (page()) { + //page()->setTextAlign(createAlignment()); + page()->changeSelectedGrpoupTextAlignPropperty(true,Qt::AlignmentFlag(flag)); + } m_textAttibutesIsChanging = false; } @@ -171,8 +180,13 @@ void TextAlignmentEditorWidget::slotTextVAttribsChanged(bool) m_textAliginVCenter->setChecked(sender()==m_textAliginVCenter); m_textAliginBottom->setChecked(sender()==m_textAliginBottom); - if (reportEditor()) reportEditor()->setTextAlign(createAlignment()); - if (page()) page()->setTextAlign(createAlignment()); + int flag = 0; + if (sender()==m_textAliginTop) flag |= Qt::AlignTop; + if (sender()==m_textAliginVCenter) flag |= Qt::AlignVCenter; + if (sender()==m_textAliginBottom) flag |= Qt::AlignBottom; + + if (reportEditor()) reportEditor()->setTextAlign(false,Qt::AlignmentFlag(flag)); + if (page()) page()->changeSelectedGrpoupTextAlignPropperty(false,Qt::AlignmentFlag(flag) ); m_textAttibutesIsChanging = false; } diff --git a/src/items/lrshapeitem.cpp b/src/items/lrshapeitem.cpp index 390ded6..1639fc2 100644 --- a/src/items/lrshapeitem.cpp +++ b/src/items/lrshapeitem.cpp @@ -55,7 +55,8 @@ ShapeItem::ShapeItem(QObject *owner, QGraphicsItem *parent) m_shapeBrushType(Qt::NoBrush), m_lineWidth(1), m_penStyle(Qt::SolidLine), - m_opacity(100) + m_opacity(100), + m_cornerRadius(0) { } @@ -85,8 +86,12 @@ void ShapeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, painter->drawEllipse(rect()); break; case Rectangle: - painter->setRenderHint(QPainter::Antialiasing); - painter->drawRect(rect()); + if (m_cornerRadius!=0){ + painter->setRenderHint(QPainter::Antialiasing); + painter->drawRoundedRect(rect(),m_cornerRadius,m_cornerRadius); + } else { + painter->drawRect(rect()); + } break; } painter->restore(); @@ -164,6 +169,21 @@ BaseDesignIntf *ShapeItem::createSameTypeItem(QObject *owner, QGraphicsItem *par { return new ShapeItem(owner,parent); } + +int ShapeItem::cornerRadius() const +{ + return m_cornerRadius; +} + +void ShapeItem::setCornerRadius(int borderRadius) +{ + if (m_cornerRadius != borderRadius){ + int oldValue = m_cornerRadius; + m_cornerRadius = borderRadius; + update(); + notify("cornerRadius",oldValue,m_cornerRadius); + } +} int ShapeItem::opacity() const { return m_opacity; diff --git a/src/items/lrshapeitem.h b/src/items/lrshapeitem.h index 037d9a6..639faba 100644 --- a/src/items/lrshapeitem.h +++ b/src/items/lrshapeitem.h @@ -44,6 +44,7 @@ class ShapeItem: public LimeReport::ItemDesignIntf Q_PROPERTY(qreal lineWidth READ lineWidth WRITE setLineWidth) Q_PROPERTY(Qt::PenStyle penStyle READ penStyle WRITE setPenStyle) Q_PROPERTY(int opacity READ opacity WRITE setOpacity) + Q_PROPERTY(int cornerRadius READ cornerRadius WRITE setCornerRadius) public: enum ShapeType{HorizontalLine,VerticalLine,Ellipse,Rectangle}; ShapeItem(QObject *owner, QGraphicsItem *parent); @@ -62,6 +63,8 @@ public: void setPenStyle(const Qt::PenStyle &value); int opacity() const; void setOpacity(int opacity); + int cornerRadius() const; + void setCornerRadius(int cornerRadius); protected: BaseDesignIntf* createSameTypeItem(QObject *owner, QGraphicsItem *parent); @@ -74,6 +77,7 @@ private: qreal m_lineWidth; Qt::PenStyle m_penStyle; int m_opacity; + int m_cornerRadius; }; } diff --git a/src/items/lrtextitem.cpp b/src/items/lrtextitem.cpp index f533f67..21094fd 100644 --- a/src/items/lrtextitem.cpp +++ b/src/items/lrtextitem.cpp @@ -55,83 +55,112 @@ bool registred = LimeReport::DesignElementsFactory::instance().registerCreator(x namespace LimeReport{ TextItem::TextItem(QObject *owner, QGraphicsItem *parent) - : ContentItemDesignIntf(xmlTag,owner,parent), m_angle(Angle0),m_trimValue(true){ + : ContentItemDesignIntf(xmlTag,owner,parent), m_angle(Angle0), m_trimValue(true), m_allowHTML(false){ m_text = new QTextDocument(); Init(); } -TextItem::TextItem(const QString& text, QObject* owner /*= 0*/, QGraphicsItem* parent /*= 0*/) - : ContentItemDesignIntf(xmlTag, owner,parent), m_angle(Angle0), m_trimValue(true){ - m_strText = text; - m_text = new QTextDocument(text); - m_text->setHtml(replaceReturns(m_strText)); - initText(); - Init(); -} - TextItem::~TextItem() { delete m_text; } -void TextItem::paint(QPainter* ppainter, const QStyleOptionGraphicsItem* style, QWidget* widget) { +int TextItem::fakeMarginSize(){ + return marginSize()+5; +} + +void TextItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* style, QWidget* widget) { Q_UNUSED(widget); Q_UNUSED(style); - ppainter->save(); + painter->save(); - setupPainter(ppainter); - prepareRect(ppainter,style,widget); + setupPainter(painter); + prepareRect(painter,style,widget); QSizeF tmpSize = rect().size()-m_textSize; - if ((tmpSize.height()>0) && (m_alignment & Qt::AlignVCenter)) //allow html - ppainter->translate(0,tmpSize.height()/2); - - if ((tmpSize.height()>0) && (m_alignment & Qt::AlignBottom)) // allow html - ppainter->translate(0,tmpSize.height()); - - if (!ppainter->clipRegion().isEmpty()){ - QRegion clipReg=ppainter->clipRegion().xored(ppainter->clipRegion().subtracted(rect().toRect())); - ppainter->setClipRegion(clipReg); + if (!painter->clipRegion().isEmpty()){ + QRegion clipReg=painter->clipRegion().xored(painter->clipRegion().subtracted(rect().toRect())); + painter->setClipRegion(clipReg); } else { - ppainter->setClipRect(rect()); + painter->setClipRect(rect()); } + qreal hOffset = 0, vOffset=0; switch (m_angle){ + case Angle0: + hOffset = fakeMarginSize(); + if ((tmpSize.height()>0) && (m_alignment & Qt::AlignVCenter)){ + vOffset = tmpSize.height()/2; + } + if ((tmpSize.height()>0) && (m_alignment & Qt::AlignBottom)) // allow html + vOffset = tmpSize.height(); + painter->translate(hOffset,vOffset); + break; case Angle90: - ppainter->translate(width(),0); - ppainter->rotate(90); - break; + hOffset = width()-fakeMarginSize(); + vOffset = fakeMarginSize(); + if ((tmpSize.width()>0) && (m_alignment & Qt::AlignVCenter)){ + hOffset = (width()-m_text->size().height())/2+m_text->size().height(); + } + + if ((tmpSize.height()>0) && (m_alignment & Qt::AlignBottom)){ + hOffset = (m_text->size().height()); + } + painter->translate(hOffset,vOffset); + painter->rotate(90); + break; case Angle180: - ppainter->translate(width(),height()); - ppainter->rotate(180); - break; + hOffset = width()-fakeMarginSize(); + vOffset = height()-fakeMarginSize(); + if ((tmpSize.width()>0) && (m_alignment & Qt::AlignVCenter)){ + vOffset = tmpSize.height()/2+m_text->size().height(); + } + if ((tmpSize.height()>0) && (m_alignment & Qt::AlignBottom)){ + vOffset = (m_text->size().height()); + } + painter->translate(hOffset,vOffset); + painter->rotate(180); + break; case Angle270: - ppainter->translate(0,height()); - ppainter->rotate(270); - break; + hOffset = fakeMarginSize(); + vOffset = height()-fakeMarginSize(); + if ((tmpSize.width()>0) && (m_alignment & Qt::AlignVCenter)){ + hOffset = (width()-m_text->size().height())/2; + } + + if ((tmpSize.height()>0) && (m_alignment & Qt::AlignBottom)){ + hOffset = (width()-m_text->size().height()); + } + painter->translate(hOffset,vOffset); + painter->rotate(270); + break; case Angle45: - ppainter->translate(width()/2,0); - ppainter->rotate(45); + painter->translate(width()/2,0); + painter->rotate(45); m_text->setTextWidth(sqrt(2*(pow(width()/2,2)))); - break; + break; case Angle315: - ppainter->translate(0,height()/2); - ppainter->rotate(315); + painter->translate(0,height()/2); + painter->rotate(315); m_text->setTextWidth(sqrt(2*(pow(height()/2,2)))); - break; - default: - break; + break; } - for(QTextBlock it=m_text->begin();it!=m_text->end();it=it.next()){ - for (int i=0;ilineCount();i++){ - ppainter->setOpacity(qreal(foregroundOpacity())/100); - it.layout()->lineAt(i).draw(ppainter,QPointF(marginSize(),0)); - } - } +// for(QTextBlock it=m_text->begin();it!=m_text->end();it=it.next()){ +// for (int i=0;ilineCount();i++){ +// painter->setOpacity(qreal(foregroundOpacity())/100); +// it.layout()->lineAt(i).draw(painter,QPointF(0,0)); +// } +// } + painter->setOpacity(qreal(foregroundOpacity())/100); + + //m_text->setDefaultTextOption(); + QAbstractTextDocumentLayout::PaintContext ctx; + ctx.palette.setColor(QPalette::Text, fontColor()); + m_text->documentLayout()->draw(painter,ctx); // m_layout.draw(ppainter,QPointF(marginSize(),0),); // ppainter->setFont(transformToSceneFont(font())); @@ -139,8 +168,8 @@ void TextItem::paint(QPainter* ppainter, const QStyleOptionGraphicsItem* style, // o.setAlignment(alignment()); // ppainter->drawText(rect(), content(), o); - ppainter->restore(); - BaseDesignIntf::paint(ppainter, style, widget); + painter->restore(); + BaseDesignIntf::paint(painter, style, widget); } QString TextItem::content() const{ @@ -152,7 +181,7 @@ void TextItem::Init() m_autoWidth=NoneAutoWidth; m_alignment= Qt::AlignLeft|Qt::AlignTop; m_autoHeight=false; - m_text->setDefaultFont(transformToSceneFont(font())); +// m_text->setDefaultFont(transformToSceneFont(font())); m_textSize=QSizeF(); m_foregroundOpacity = 100; } @@ -162,9 +191,16 @@ void TextItem::setContent(const QString &value) if (m_strText.compare(value)!=0){ QString oldValue = m_strText; m_strText=value; - m_text->setHtml(replaceReturns(value.trimmed())); - m_text->setTextWidth(width()); - m_textSize=m_text->size(); + if (allowHTML()) + m_text->setHtml(replaceReturns(value.trimmed())); + else + m_text->setPlainText(value); + //m_text->setTextWidth(width()); + //m_textSize=m_text->size(); + if (itemMode() == DesignMode){ + initText(); + } + if (!isLoading()){ update(rect()); notify("content",oldValue,value); @@ -181,7 +217,7 @@ void TextItem::updateItemSize(DataSourceManager* dataManager, RenderPass pass, i initText(); if (m_textSize.width()>width() && ((m_autoWidth==MaxWordLength)||(m_autoWidth==MaxStringLength))){ - setWidth(m_textSize.width()); + setWidth(m_textSize.width() + fakeMarginSize()*2); } if ((m_textSize.height()>height()) && (m_autoHeight) ){ @@ -192,18 +228,18 @@ void TextItem::updateItemSize(DataSourceManager* dataManager, RenderPass pass, i void TextItem::updateLayout() { - m_layout.setFont(transformToSceneFont(font())); - m_layout.setText(content()); - qreal linePos = 0; - m_layout.beginLayout(); - while(true){ - QTextLine line = m_layout.createLine(); - if (!line.isValid()) break; - line.setLineWidth(width()-marginSize()*2); - line.setPosition(QPoint(marginSize(),linePos)); - linePos+=line.height(); - } - m_layout.endLayout(); +// m_layout.setFont(transformToSceneFont(font())); +// m_layout.setText(content()); +// qreal linePos = 0; +// m_layout.beginLayout(); +// while(true){ +// QTextLine line = m_layout.createLine(); +// if (!line.isValid()) break; +// line.setLineWidth(width()-marginSize()*2); +// line.setPosition(QPoint(marginSize(),linePos)); +// linePos+=line.height(); +// } +// m_layout.endLayout(); } bool TextItem::isNeedExpandContent() const @@ -233,16 +269,36 @@ void TextItem::initText() to.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); else to.setWrapMode(QTextOption::NoWrap); - m_text->setDocumentMargin(marginSize()); + m_text->setDocumentMargin(0); m_text->setDefaultTextOption(to); m_text->setDefaultFont(transformToSceneFont(font())); if ((m_angle==Angle0)||(m_angle==Angle180)){ - m_text->setTextWidth(rect().width()); + m_text->setTextWidth(rect().width()-fakeMarginSize()*2); } else { - m_text->setTextWidth(rect().height()); + m_text->setTextWidth(rect().height()-fakeMarginSize()*2); } m_textSize=m_text->size(); } + +bool TextItem::allowHTML() const +{ + return m_allowHTML; +} + +void TextItem::setAllowHTML(bool allowHTML) +{ + if (m_allowHTML!=allowHTML){ + m_allowHTML = allowHTML; + if (m_text){ + if (allowHTML) + m_text->setHtml(m_strText); + else + m_text->setPlainText(m_strText); + update(); + } + notify("allowHTML",!m_allowHTML,allowHTML); + } +} bool TextItem::trimValue() const { return m_trimValue; @@ -256,12 +312,13 @@ void TextItem::setTrimValue(bool trimValue) void TextItem::geometryChangedEvent(QRectF , QRectF) { - if ((m_angle==Angle0)||(m_angle==Angle180)){ - m_text->setTextWidth(rect().width()); - } else { - m_text->setTextWidth(rect().height()); - } - m_textSize=m_text->size(); +// if ((m_angle==Angle0)||(m_angle==Angle180)){ +// m_text->setTextWidth(rect().width()-fakeMarginSize()*2); +// } else { +// m_text->setTextWidth(rect().height()-fakeMarginSize()*2); +// } +// m_textSize=m_text->size(); + if (itemMode() == DesignMode) initText(); } bool TextItem::isNeedUpdateSize(RenderPass pass) const @@ -273,24 +330,12 @@ bool TextItem::isNeedUpdateSize(RenderPass pass) const return res; } -//void TextItem::setMarginSize(int value) -//{ -// if (m_margin!=value){ -// int oldValue = m_margin; -// m_margin=value; -// if (!isLoading()){ -// update(rect()); -// notify("margin", oldValue, value); -// } -// } -//} - void TextItem::setAlignment(Qt::Alignment value) { if (m_alignment!=value){ Qt::Alignment oldValue = m_alignment; m_alignment=value; - m_layout.setTextOption(QTextOption(m_alignment)); + //m_layout.setTextOption(QTextOption(m_alignment)); if (!isLoading()){ initText(); update(rect()); @@ -302,17 +347,17 @@ void TextItem::setAlignment(Qt::Alignment value) void TextItem::expandContent(DataSourceManager* dataManager, RenderPass pass) { QString context=content(); + ExpandType expandType = allowHTML()?ReplaceHTMLSymbols:NoEscapeSymbols; switch(pass){ case FirstPass: - context=expandUserVariables(context, pass, NoEscapeSymbols, dataManager); + context=expandUserVariables(context, pass, expandType, dataManager); context=expandScripts(context, dataManager); - context=expandDataFields(context, NoEscapeSymbols, dataManager); + context=expandDataFields(context, expandType, dataManager); break; case SecondPass:; - context=expandUserVariables(context, pass, NoEscapeSymbols, dataManager); + context=expandUserVariables(context, pass, expandType, dataManager); context=expandScripts(context, dataManager); } - setContent(context); } @@ -349,12 +394,12 @@ BaseDesignIntf *TextItem::cloneUpperPart(int height, QObject *owner, QGraphicsIt for (QTextBlock it=m_text->begin();it!=m_text->end();it=it.next()){ for (int i=0;ilineCount();i++){ linesHeight+=it.layout()->lineAt(i).height(); - if (linesHeight>(height-(marginSize()*2))) {linesHeight-=it.layout()->lineAt(i).height(); goto loop_exit;} + if (linesHeight>(height-(fakeMarginSize()*2+borderLineSize()*2))) {linesHeight-=it.layout()->lineAt(i).height(); goto loop_exit;} tmpText+=it.text().mid(it.layout()->lineAt(i).textStart(),it.layout()->lineAt(i).textLength())+'\n'; } } loop_exit: - upperPart->setHeight(linesHeight+marginSize()*2); + upperPart->setHeight(linesHeight+fakeMarginSize()*2+borderLineSize()*2); QScopedPointer context(new HtmlContext(m_strText)); upperPart->setContent(context->extendTextByTags(tmpText,0)); return upperPart; @@ -372,7 +417,7 @@ BaseDesignIntf *TextItem::cloneBottomPart(int height, QObject *owner, QGraphicsI for (curBlock=m_text->begin();curBlock!=m_text->end();curBlock=curBlock.next()){ for (curLine=0;curLinelineCount();curLine++){ linesHeight+=curBlock.layout()->lineAt(curLine).height(); - if (linesHeight>(height-(marginSize()*2))) {goto loop_exit;} + if (linesHeight>(height-(fakeMarginSize()*2+borderLineSize()*2))) {goto loop_exit;} } } loop_exit:; @@ -387,7 +432,7 @@ BaseDesignIntf *TextItem::cloneBottomPart(int height, QObject *owner, QGraphicsI QScopedPointer context(new HtmlContext(m_strText)); bottomPart->setContent(context->extendTextByTags(tmpText,textPos)); - bottomPart->setHeight(bottomPart->m_textSize.height()+5); + bottomPart->setHeight(bottomPart->m_textSize.height()+borderLineSize()*2); return bottomPart; } @@ -407,7 +452,9 @@ BaseDesignIntf *TextItem::cloneEmpty(int height, QObject *owner, QGraphicsItem * void TextItem::objectLoadFinished() { ItemDesignIntf::objectLoadFinished(); - initText(); + if (itemMode() == DesignMode || !isNeedExpandContent()){ + initText(); + } } void TextItem::setTextItemFont(QFont value) @@ -453,7 +500,7 @@ void TextItem::setBackgroundColorProperty(QColor value) if(value!=backgroundColor()){ QColor oldValue = backgroundColor(); setBackgroundColor(value); - notify("backgroundMode",oldValue,value); + notify("backgroundColor",oldValue,value); } } diff --git a/src/items/lrtextitem.h b/src/items/lrtextitem.h index 7b5069e..2c1c702 100644 --- a/src/items/lrtextitem.h +++ b/src/items/lrtextitem.h @@ -57,17 +57,17 @@ class TextItem : public LimeReport::ContentItemDesignIntf { Q_PROPERTY(AngleType angle READ angle WRITE setAngle) Q_PROPERTY(int foregroundOpacity READ foregroundOpacity WRITE setForegroundOpacity()) Q_PROPERTY(bool trimValue READ trimValue WRITE setTrimValue) + Q_PROPERTY(bool allowHTML READ allowHTML WRITE setAllowHTML) public: enum AutoWidth{NoneAutoWidth,MaxWordLength,MaxStringLength}; enum AngleType{Angle0,Angle90,Angle180,Angle270,Angle45,Angle315}; void Init(); - TextItem(QObject* owner,QGraphicsItem* parent); - TextItem(const QString& content,QObject* owner = 0, QGraphicsItem* parent = 0); + TextItem(QObject* owner=0, QGraphicsItem* parent=0); ~TextItem(); - void paint(QPainter* ppainter, const QStyleOptionGraphicsItem*, QWidget*); + void paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*); QString content() const; void setContent(const QString& value); @@ -111,17 +111,21 @@ public: bool trimValue() const; void setTrimValue(bool trimValue); + bool allowHTML() const; + void setAllowHTML(bool allowHTML); + protected: void updateLayout(); bool isNeedExpandContent() const; QString replaceBR(QString text); QString replaceReturns(QString text); + int fakeMarginSize(); private: void initText(); private: QString m_strText; - QTextLayout m_layout; + //QTextLayout m_layout; QTextDocument* m_text; Qt::Alignment m_alignment; bool m_autoHeight; @@ -130,6 +134,7 @@ private: AngleType m_angle; int m_foregroundOpacity; bool m_trimValue; + bool m_allowHTML; }; } diff --git a/src/lrbanddesignintf.cpp b/src/lrbanddesignintf.cpp index 3f93599..32f8ba6 100644 --- a/src/lrbanddesignintf.cpp +++ b/src/lrbanddesignintf.cpp @@ -57,7 +57,7 @@ void BandMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem* /**opt painter->setPen(Qt::white); painter->drawEllipse(r.adjusted(5,5,-5,-5)); if (m_band->isSelected()){ - painter->setBrush(m_color); + painter->setBrush(LimeReport::Const::SELECTION_COLOR); painter->drawEllipse(r.adjusted(7,7,-7,-7)); } painter->restore(); @@ -140,7 +140,9 @@ BandDesignIntf::BandDesignIntf(BandsType bandType, const QString &xmlTypeName, Q m_printIfEmpty(false), m_columnsCount(1), m_columnIndex(0), - m_columnsFillDirection(Horizontal) + m_columnsFillDirection(Horizontal), + m_reprintOnEachPage(false), + m_startNewPage(false) { setPosibleResizeDirectionFlags(ResizeBottom); setPosibleMoveFlags(TopBotom); @@ -299,7 +301,7 @@ bool BandDesignIntf::isConnectedToBand(BandDesignIntf::BandsType bandType) const int BandDesignIntf::maxChildIndex(QSet ignoredBands) const{ int curIndex = bandIndex(); foreach(BandDesignIntf* childBand, childBands()){ - if (!ignoredBands.contains(childBand->bandType())){ + if (!ignoredBands.contains(childBand->bandType()) && childBand->bandIndex()>bandIndex()){ curIndex = std::max(curIndex,childBand->maxChildIndex(ignoredBands)); } } @@ -666,6 +668,9 @@ QVariant BandDesignIntf::itemChange(QGraphicsItem::GraphicsItemChange change, co } } + if (change==ItemChildAddedChange || change==ItemChildRemovedChange){ + update(rect()); + } return BaseDesignIntf::itemChange(change,value); } @@ -692,6 +697,26 @@ void BandDesignIntf::childBandDeleted(QObject *band) m_childBands.removeAt(m_childBands.indexOf(reinterpret_cast(band))); } +bool BandDesignIntf::startNewPage() const +{ + return m_startNewPage; +} + +void BandDesignIntf::setStartNewPage(bool startNewPage) +{ + m_startNewPage = startNewPage; +} + +bool BandDesignIntf::reprintOnEachPage() const +{ + return m_reprintOnEachPage; +} + +void BandDesignIntf::setReprintOnEachPage(bool reprintOnEachPage) +{ + m_reprintOnEachPage = reprintOnEachPage; +} + int BandDesignIntf::columnIndex() const { return m_columnIndex; @@ -715,7 +740,8 @@ void BandDesignIntf::setPrintIfEmpty(bool printIfEmpty) BandDesignIntf *BandDesignIntf::bandHeader() { foreach (BandDesignIntf* band, childBands()) { - if (band->isHeader()) return band; + if (band->isHeader() && !band->isGroupHeader()) + return band; } return 0; } @@ -770,7 +796,10 @@ void BandDesignIntf::updateItemSize(DataSourceManager* dataManager, RenderPass p if (keepBottomSpaceOption()) spaceBorder=height()-findMaxBottom(); snapshotItemsLayout(); arrangeSubItems(pass, dataManager); - if (autoHeight() && height()0)&&(height()>maxHeight)){ trimToMaxHeight(maxHeight); setHeight(maxHeight); diff --git a/src/lrbanddesignintf.h b/src/lrbanddesignintf.h index b190a75..0b09e92 100644 --- a/src/lrbanddesignintf.h +++ b/src/lrbanddesignintf.h @@ -43,8 +43,8 @@ public: virtual bool isStarted() = 0; virtual void closeGroup() = 0; virtual int index() = 0; - virtual bool startNewPage()const = 0 ; - virtual bool resetPageNumber()const = 0 ; + virtual bool startNewPage() const = 0 ; + virtual bool resetPageNumber() const = 0 ; virtual ~IGroupBand(){} }; @@ -113,18 +113,18 @@ public: }; enum BandColumnsLayoutType{ - Horizontal, Vertical + Horizontal, Vertical, VerticalUniform }; BandDesignIntf(BandsType bandType, const QString& xmlTypeName, QObject* owner = 0, QGraphicsItem* parent=0); ~BandDesignIntf(); - virtual void paint(QPainter *ppainter, const QStyleOptionGraphicsItem *option, QWidget *widget); + void paint(QPainter *ppainter, const QStyleOptionGraphicsItem *option, QWidget *widget); virtual BandsType bandType() const; virtual QString bandTitle() const; virtual QIcon bandIcon() const; virtual bool isUnique() const; - virtual void updateItemSize(DataSourceManager *dataManager, RenderPass pass=FirstPass, int maxHeight=0); + void updateItemSize(DataSourceManager *dataManager, RenderPass pass=FirstPass, int maxHeight=0); virtual QColor selectionColor() const; int bandIndex() const; @@ -156,11 +156,12 @@ public: QList childBands() const{return m_childBands;} QList childrenByType(BandDesignIntf::BandsType type); - virtual bool canBeSplitted(int height) const; - virtual bool isEmpty() const; + bool canBeSplitted(int height) const; + bool isEmpty() const; virtual bool isNeedRender() const; virtual bool isFooter() const {return false;} virtual bool isHeader() const {return false;} + virtual bool isGroupHeader() const {return false;} virtual bool isData() const {return false;} void setTryToKeepTogether(bool value); @@ -195,6 +196,12 @@ public: int columnIndex() const; void setColumnIndex(int columnIndex); + bool reprintOnEachPage() const; + void setReprintOnEachPage(bool reprintOnEachPage); + + bool startNewPage() const; + void setStartNewPage(bool startNewPage); + signals: void bandRendered(BandDesignIntf* band); protected: @@ -209,19 +216,20 @@ protected: void setBandTypeText(const QString& value); QString bandTypeText(){return m_bandTypeText;} - virtual void moveDown(){} - virtual void moveUp(){} + void moveDown(){} + void moveUp(){} QSet groupBands(); QSet subdetailBands(); BandDesignIntf *findParentBand(); - virtual void geometryChangedEvent(QRectF, QRectF); - virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); - virtual void initMode(ItemMode mode); + void geometryChangedEvent(QRectF, QRectF); + QVariant itemChange(GraphicsItemChange change, const QVariant &value); + void initMode(ItemMode mode); virtual QColor bandColor() const; void setMarkerColor(QColor color); void checkEmptyTable(); void setColumnsCount(int value); void setColumnsFillDirection(BandColumnsLayoutType value); + private slots: void childBandDeleted(QObject* band); private: @@ -246,6 +254,8 @@ private: int m_columnsCount; int m_columnIndex; BandColumnsLayoutType m_columnsFillDirection; + bool m_reprintOnEachPage; + bool m_startNewPage; }; class DataBandDesignIntf : public BandDesignIntf{ diff --git a/src/lrbasedesignintf.cpp b/src/lrbasedesignintf.cpp index 6de3689..130e0ec 100644 --- a/src/lrbasedesignintf.cpp +++ b/src/lrbasedesignintf.cpp @@ -60,6 +60,7 @@ BaseDesignIntf::BaseDesignIntf(const QString &storageTypeName, QObject *owner, Q m_fontColor(Qt::black), m_mmFactor(Const::mmFACTOR), m_fixedPos(false), + m_borderLineSize(1), m_BGMode(OpaqueMode), m_opacity(100), m_borderLinesFlags(0), @@ -287,14 +288,14 @@ void BaseDesignIntf::mousePressEvent(QGraphicsSceneMouseEvent *event) { if (event->button() == Qt::LeftButton) { m_resizeDirectionFlags = resizeDirectionFlags(event->pos()); - m_startScenePos = event->scenePos(); + //m_startScenePos = event->scenePos(); m_startPos = pos(); m_oldGeometry = geometry(); QGraphicsItem::mousePressEvent(event); QApplication::processEvents(); emit(itemSelected(this)); } - else QGraphicsItem::mouseMoveEvent(event); + else QGraphicsItem::mousePressEvent(event); } void BaseDesignIntf::paint(QPainter *ppainter, const QStyleOptionGraphicsItem *option, QWidget *widget) @@ -341,13 +342,34 @@ void BaseDesignIntf::prepareRect(QPainter *ppainter, const QStyleOptionGraphicsI void BaseDesignIntf::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { if (page()) { - if (!page()->isItemInsertMode()) { + if (!page()->isItemInsertMode() && isSelected()) { if (m_resizeDirectionFlags != resizeDirectionFlags(event->pos())) { m_resizeDirectionFlags = resizeDirectionFlags(event->pos()); QVectoroldResizeAreas(m_resizeAreas); initResizeZones(); invalidateRects(oldResizeAreas); invalidateRects(m_resizeAreas); + switch (m_resizeDirectionFlags) { + case ResizeRight: + case ResizeLeft: + setCursor(Qt::SizeHorCursor); + break; + case ResizeBottom: + case ResizeTop: + setCursor(Qt::SizeVerCursor); + break; + case ResizeRight | ResizeBottom: + case ResizeLeft | ResizeTop: + setCursor(Qt::SizeFDiagCursor); + break; + case ResizeLeft | ResizeBottom: + case ResizeRight | ResizeTop: + setCursor(Qt::SizeBDiagCursor); + break; + default: + setCursor(Qt::ArrowCursor); + break; + } } } } @@ -356,7 +378,7 @@ void BaseDesignIntf::hoverMoveEvent(QGraphicsSceneHoverEvent *event) void BaseDesignIntf::invalidateRects(QVector rects) { foreach(QRectF * rect, rects) - scene()->update(mapToScene(*rect).boundingRect()); + scene()->update(mapToScene(*rect).boundingRect()); } void BaseDesignIntf::hoverLeaveEvent(QGraphicsSceneHoverEvent *) @@ -371,20 +393,39 @@ void BaseDesignIntf::hoverLeaveEvent(QGraphicsSceneHoverEvent *) void BaseDesignIntf::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { +// if (!scene()->items(event->scenePos()).contains(parentItem())){ +// BandDesignIntf* band = 0; +// PageItemDesignIntf* pageItem = 0; +// foreach (QGraphicsItem* item, scene()->items(event->scenePos())) { +// band = dynamic_cast(item); +// if (band){ +// break; +// } +// pageItem = dynamic_cast(item); +// } +// if (band) +// qDebug()<<"band found"<objectName(); +// if (pageItem) +// qDebug()<<"page found"<objectName(); +// } + + int hStep = dynamic_cast(scene())->horizontalGridStep(); + int vStep = dynamic_cast(scene())->verticalGridStep(); + if (m_resizeDirectionFlags & ResizeLeft) { 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()); - setWidth(posRightConner - div(event->scenePos().x(), 2).quot * 2); + setItemPos(mapToParent(mapFromScene(div(event->scenePos().x(), vStep).quot * vStep, y())).x(), y()); + setWidth(posRightConner - div(event->scenePos().x(), vStep).quot * vStep); } } if (m_resizeDirectionFlags & ResizeRight) { 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); + setWidth(div(int(event->scenePos().x()) - int(mapToScene(0, 0).x()), vStep).quot * vStep); } } @@ -392,7 +433,7 @@ void BaseDesignIntf::mouseMoveEvent(QGraphicsSceneMouseEvent *event) if ((event->scenePos().y() > (mapToScene(0, 0).y() + 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); + setHeight(div(int(event->scenePos().y()) - int(mapToScene(0, 0).y()), hStep).quot * hStep); } } @@ -402,8 +443,8 @@ void BaseDesignIntf::mouseMoveEvent(QGraphicsSceneMouseEvent *event) (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); - setHeight(posBottomConner - div(event->scenePos().y(), 2).quot * 2); + setItemPos(x(), div(mapToParent(event->pos()).y(), hStep).quot * hStep); + setHeight(posBottomConner - div(event->scenePos().y(), hStep).quot * hStep); } } @@ -413,16 +454,16 @@ void BaseDesignIntf::mouseMoveEvent(QGraphicsSceneMouseEvent *event) QPointF delta; switch (posibleMoveDirectionFlags()) { case LeftRight: { - delta = QPoint(div(m_startScenePos.x() - event->scenePos().x(), 2).quot * 2, 0); + delta = QPoint(div(event->buttonDownScenePos(Qt::LeftButton).x() - event->scenePos().x(), hStep).quot * hStep, 0); break; } case TopBotom: { - delta = QPoint(0, div(m_startScenePos.y() - event->scenePos().y(), 2).quot * 2); + delta = QPoint(0, div(event->buttonDownScenePos(Qt::LeftButton).y() - event->scenePos().y(), vStep).quot * vStep); break; } case All: { - delta = QPoint(div(m_startScenePos.x() - event->scenePos().x(), 2).quot * 2, - div(m_startScenePos.y() - event->scenePos().y(), 2).quot * 2); + delta = QPoint(div(event->buttonDownScenePos(Qt::LeftButton).x() - event->scenePos().x(), hStep).quot * hStep, + div(event->buttonDownScenePos(Qt::LeftButton).y() - event->scenePos().y(), vStep).quot * vStep); break; } }; @@ -590,32 +631,45 @@ void BaseDesignIntf::emitObjectNamePropertyChanged(const QString &oldName, const emit propertyObjectNameChanged(oldName,newName); } +int BaseDesignIntf::borderLineSize() const +{ + return m_borderLineSize; +} + +void BaseDesignIntf::setBorderLineSize(int value) +{ + int oldValue = m_borderLineSize; + m_borderLineSize = value; + update(); + notify("borderLineSize",oldValue,value); +} + void BaseDesignIntf::moveRight() { - if (!m_fixedPos) setItemPos(pos().x() + 2, pos().y()); + if (!m_fixedPos) setItemPos(pos().x() + page()->horizontalGridStep(), pos().y()); } void BaseDesignIntf::moveLeft() { - if (!m_fixedPos) setItemPos(pos().x() - 2, pos().y()); + if (!m_fixedPos) setItemPos(pos().x() - page()->horizontalGridStep(), pos().y()); } void BaseDesignIntf::moveDown() { - if (!m_fixedPos) setItemPos(pos().x(), pos().y() + 2); + if (!m_fixedPos) setItemPos(pos().x(), pos().y() + page()->verticalGridStep()); } void BaseDesignIntf::moveUp() { - if (!m_fixedPos) setItemPos(pos().x(), pos().y() - 2); + if (!m_fixedPos) setItemPos(pos().x(), pos().y() - page()->verticalGridStep()); } void BaseDesignIntf::sizeRight() { if ((m_posibleResizeDirectionFlags & ResizeLeft) || (m_posibleResizeDirectionFlags & ResizeRight)) { - setWidth(width() + 2); + setWidth(width() + page()->horizontalGridStep()); } } @@ -623,7 +677,7 @@ void BaseDesignIntf::sizeLeft() { if ((m_posibleResizeDirectionFlags & ResizeLeft) || (m_posibleResizeDirectionFlags & ResizeRight)) { - setWidth(width() - 2); + setWidth(width() - page()->horizontalGridStep()); } } @@ -631,7 +685,7 @@ void BaseDesignIntf::sizeUp() { if ((m_posibleResizeDirectionFlags & ResizeTop) || (m_posibleResizeDirectionFlags & ResizeBottom)) { - setHeight(height() - 2); + setHeight(height() - page()->verticalGridStep()); } } @@ -639,7 +693,7 @@ void BaseDesignIntf::sizeDown() { if ((m_posibleResizeDirectionFlags & ResizeTop) || (m_posibleResizeDirectionFlags & ResizeBottom)) { - setHeight(height() + 2); + setHeight(height() + page()->verticalGridStep()); } } @@ -718,10 +772,10 @@ void BaseDesignIntf::setGeometry(QRectF rect) if (!isLoading()) prepareGeometryChange(); m_rect = rect; - m_topRect = QRectF(0, 0, width(), resizeHandleSize()); - m_bottomRect = QRectF(0, height() - resizeHandleSize(), width(), resizeHandleSize()); - m_leftRect = QRectF(0, 0, resizeHandleSize(), height()); - m_rightRect = QRectF(width() - resizeHandleSize(), 0, resizeHandleSize(), height()); + m_topRect = QRectF(0-resizeHandleSize(), 0-resizeHandleSize(), width()+resizeHandleSize()*2, resizeHandleSize()*2); + m_bottomRect = QRectF(0-resizeHandleSize(), height() - resizeHandleSize(), width()+resizeHandleSize()*2, resizeHandleSize()*2); + m_leftRect = QRectF(0-resizeHandleSize(), 0-resizeHandleSize(), resizeHandleSize()*2, height()+resizeHandleSize()*2); + m_rightRect = QRectF(width() - resizeHandleSize(), 0-resizeHandleSize(), resizeHandleSize()*2, height()+resizeHandleSize()*2); m_boundingRect = QRectF(); updateSelectionMarker(); if (!isLoading()){ @@ -751,10 +805,8 @@ void BaseDesignIntf::setGeometryProperty(QRectF rect) setWidth(rect.width()); if (rect.height() != geometry().height()) setHeight(rect.height()); - if (!isLoading()) notify("geometry",oldValue,rect); } - } PageDesignIntf *BaseDesignIntf::page() @@ -770,8 +822,15 @@ void BaseDesignIntf::setPosibleResizeDirectionFlags(int directionsFlags) QPen BaseDesignIntf::borderPen(BorderSide side/*, bool selected*/) const { QPen pen; - if (m_borderLinesFlags & side) {pen.setColor(Qt::black); pen.setStyle(Qt::SolidLine);} - else {pen.setColor(Qt::darkGray); pen.setStyle(Qt::SolidLine);} + if (m_borderLinesFlags & side) { + pen.setColor(Qt::black); + pen.setStyle(Qt::SolidLine); + pen.setWidth(m_borderLineSize); + } else { + pen.setColor(Qt::darkGray); + pen.setStyle(Qt::SolidLine); + pen.setWidth(1); + } return pen; } @@ -969,17 +1028,17 @@ void BaseDesignIntf::updateSelectionMarker() } } -void BaseDesignIntf::drawResizeZone(QPainter *painter) +void BaseDesignIntf::drawResizeZone(QPainter* /*painter*/) { - if (m_resizeAreas.count() > 0) { - painter->save(); - 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(); - } +// if (m_resizeAreas.count() > 0) { +// painter->save(); +// 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(); +// } } @@ -1178,22 +1237,74 @@ void BaseDesignIntf::notify(const QVector& propertyNames) SelectionMarker::SelectionMarker(QGraphicsItem *parent)//, QGraphicsScene *scene) : QGraphicsItem(parent)//, scene) { + setAcceptHoverEvents(true); } QRectF SelectionMarker::boundingRect() const { - return m_rect; + return m_rect.adjusted(-15,-15,15,15); } void SelectionMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) { QPen pen; + const int markerSize = 5; pen.setColor(m_color); pen.setWidth(2); - pen.setStyle(Qt::DashLine); + pen.setStyle(Qt::DotLine); painter->setPen(pen); painter->setOpacity(Const::SELECTION_COLOR_OPACITY); - painter->drawRect(boundingRect()); + painter->drawRect(m_rect); + painter->setBrush(m_color); + painter->setPen(Qt::transparent); + painter->setOpacity(1); + painter->drawRect(QRectF(-markerSize,-markerSize,markerSize*2,markerSize*2)); + painter->drawRect(QRectF(m_rect.right()-markerSize,m_rect.bottom()-markerSize,markerSize*2,markerSize*2)); + painter->drawRect(QRectF(m_rect.right()-markerSize,m_rect.top()-markerSize,markerSize*2,markerSize*2)); + painter->drawRect(QRectF(m_rect.left()-markerSize,m_rect.bottom()-markerSize,markerSize*2,markerSize*2)); + painter->drawRect(QRectF(m_rect.left()-markerSize, + m_rect.bottom()-m_rect.height()/2-markerSize,markerSize*2,markerSize*2)); + painter->drawRect(QRectF(m_rect.right()-markerSize, + m_rect.bottom()-m_rect.height()/2-markerSize,markerSize*2,markerSize*2)); + painter->drawRect(QRectF(m_rect.left()+m_rect.width()/2-markerSize, + m_rect.top()-markerSize,markerSize*2,markerSize*2)); + painter->drawRect(QRectF(m_rect.left()+m_rect.width()/2-markerSize, + m_rect.bottom()-markerSize,markerSize*2,markerSize*2)); + + //painter->drawRect(); +} + +void SelectionMarker::hoverMoveEvent(QGraphicsSceneHoverEvent *event) +{ + BaseDesignIntf* baseItem = dynamic_cast(parentItem()); + if(baseItem) baseItem->hoverMoveEvent(event); +} + +void SelectionMarker::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + parentItem()->setSelected(true); + BaseDesignIntf* baseItem = dynamic_cast(parentItem()); + if(baseItem) baseItem->mousePressEvent(event); + QGraphicsItem::mousePressEvent(event); +} + +void SelectionMarker::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + BaseDesignIntf* baseItem = dynamic_cast(parentItem()); + if(baseItem) baseItem->mouseReleaseEvent(event); +} + +void SelectionMarker::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) +{ + BaseDesignIntf* baseItem = dynamic_cast(parentItem()); + if(baseItem) baseItem->mouseDoubleClickEvent(event); + QGraphicsItem::mouseDoubleClickEvent(event); +} + +void SelectionMarker::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + BaseDesignIntf* baseItem = dynamic_cast(parentItem()); + if(baseItem) baseItem->mouseMoveEvent(event); } diff --git a/src/lrbasedesignintf.h b/src/lrbasedesignintf.h index 15d8834..ffbb05d 100644 --- a/src/lrbasedesignintf.h +++ b/src/lrbasedesignintf.h @@ -55,10 +55,16 @@ public: void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *); void setRect(QRectF rect){prepareGeometryChange();m_rect=rect;} void setColor(QColor color){m_color=color;} +protected: + void hoverMoveEvent(QGraphicsSceneHoverEvent *event); + void mousePressEvent(QGraphicsSceneMouseEvent *event); + void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event); + void mouseMoveEvent(QGraphicsSceneMouseEvent *event); private: QRectF m_rect; QColor m_color; - + BaseDesignIntf* m_object; }; class DataSourceManager; @@ -77,7 +83,9 @@ class BaseDesignIntf : Q_PROPERTY(qreal zOrder READ zValue WRITE setZValueProperty DESIGNABLE false) Q_PROPERTY(BorderLines borders READ borderLines WRITE setBorderLinesFlags) Q_PROPERTY(QString parentName READ parentReportItem WRITE setParentReportItem DESIGNABLE false) - Q_PROPERTY(ItemAlign itemAlign READ itemAlign WRITE setItemAlign) + Q_PROPERTY(int borderLineSize READ borderLineSize WRITE setBorderLineSize) + Q_PROPERTY(bool isVisible READ isVisible WRITE setVisible DESIGNABLE false) + public: enum BGMode { TransparentMode,OpaqueMode}; enum BrushMode{Solid,None}; @@ -101,6 +109,7 @@ public: enum ItemAlign {LeftItemAlign,RightItemAlign,CenterItemAlign,ParentWidthItemAlign,DesignedItemAlign}; Q_DECLARE_FLAGS(BorderLines, BorderSide) Q_DECLARE_FLAGS(ItemMode,ItemModes) + friend class SelectionMarker; public: BaseDesignIntf(const QString& storageTypeName, QObject* owner = 0, QGraphicsItem* parent = 0); virtual ~BaseDesignIntf(); @@ -215,6 +224,8 @@ public: QString itemTypeName() const; void setItemTypeName(const QString &itemTypeName); void emitObjectNamePropertyChanged(const QString& oldName, const QString& newName); + int borderLineSize() const; + void setBorderLineSize(int value); void showEditorDialog(); ItemAlign itemAlign() const; virtual void setItemAlign(const ItemAlign &itemAlign); @@ -254,7 +265,7 @@ protected: void drawBorder(QPainter* painter, QRectF rect) const; void drawDesignModeBorder(QPainter* painter, QRectF rect) const; void drawRenderModeBorder(QPainter *painter, QRectF rect) const; - void drawResizeZone(QPainter *painter); + void drawResizeZone(QPainter*); void drawSelection(QPainter* painter, QRectF) const; void drawPinArea(QPainter* painter) const; @@ -266,7 +277,7 @@ protected: RenderPass currentRenderPass(){return m_currentPass;} virtual bool drawDesignBorders() const {return true;} - + SelectionMarker* selectionMarker() {return m_selectionMarker;} private: void updateSelectionMarker(); int resizeDirectionFlags(QPointF position); @@ -276,7 +287,7 @@ private: void updatePosibleDirectionFlags(); private: QPointF m_startPos; - QPointF m_startScenePos; + //QPointF m_startScenePos; int m_resizeHandleSize; int m_selectionPenSize; int m_posibleResizeDirectionFlags; @@ -288,6 +299,7 @@ private: QColor m_fontColor; qreal m_mmFactor; bool m_fixedPos; + int m_borderLineSize; QRectF m_rect; mutable QRectF m_boundingRect; diff --git a/src/lrdatadesignintf.cpp b/src/lrdatadesignintf.cpp index a4f9f52..1ada829 100644 --- a/src/lrdatadesignintf.cpp +++ b/src/lrdatadesignintf.cpp @@ -58,7 +58,7 @@ IDataSource * ModelHolder::dataSource(IDataSource::DatasourceMode mode) QueryHolder::QueryHolder(QString queryText, QString connectionName, DataSourceManager *dataManager) : m_query(0), m_queryText(queryText), m_connectionName(connectionName), - m_mode(IDataSource::RENDER_MODE), m_dataManager(dataManager) + m_mode(IDataSource::RENDER_MODE), m_dataManager(dataManager), m_prepared(true) { extractParams(); } @@ -77,6 +77,11 @@ bool QueryHolder::runQuery(IDataSource::DatasourceMode mode) return false; } + if (!m_prepared){ + extractParams(); + if (!m_prepared) return false; + } + if (!m_query){ m_query = new QSqlQuery(db); m_query->prepare(m_preparedSQL); @@ -371,7 +376,13 @@ void SubQueryHolder::setMasterDatasource(const QString &value) void SubQueryHolder::extractParams() { - m_preparedSQL = replaceFields(replaceVariables(queryText())); + if (!dataManager()->containsDatasource(m_masterDatasource)){ + setLastError(QObject::tr("Master datasource \"%1\" not found!!!").arg(m_masterDatasource)); + setPrepared(false); + } else { + m_preparedSQL = replaceFields(replaceVariables(queryText())); + setPrepared(true); + } } QString SubQueryHolder::extractField(QString source) diff --git a/src/lrdatadesignintf.h b/src/lrdatadesignintf.h index cb22141..b0807a2 100644 --- a/src/lrdatadesignintf.h +++ b/src/lrdatadesignintf.h @@ -76,6 +76,7 @@ public: virtual bool isRemovable() const = 0; virtual void invalidate(IDataSource::DatasourceMode mode) = 0; virtual void update() = 0; + virtual void clearErrors() = 0; virtual ~IDataSourceHolder(){} }; @@ -92,6 +93,7 @@ public: bool isRemovable() const { return false; } void invalidate(IDataSource::DatasourceMode mode){Q_UNUSED(mode)} void update(){} + void clearErrors(){} signals: void modelStateChanged(); private: @@ -179,13 +181,16 @@ public: bool isInvalid() const { return !m_lastError.isEmpty(); } bool isEditable() const { return true; } bool isRemovable() const { return true; } + bool isPrepared() const {return m_prepared;} QString lastError() const { return m_lastError; } void setLastError(QString value){m_lastError=value; if (m_query) {delete m_query; m_query=0;}} void invalidate(IDataSource::DatasourceMode mode); void update(); + void clearErrors(){setLastError("");} DataSourceManager* dataManager() const {return m_dataManager;} protected: void setDatasource(IDataSource::Ptr value); + void setPrepared(bool prepared){ m_prepared = prepared;} virtual void fillParams(QSqlQuery* query); virtual void extractParams(); QString replaceVariables(QString query); @@ -199,6 +204,7 @@ private: IDataSource::Ptr m_dataSource; IDataSource::DatasourceMode m_mode; DataSourceManager* m_dataManager; + bool m_prepared; }; class SubQueryDesc : public QueryDesc{ @@ -309,6 +315,7 @@ public: QString lastError() const { return m_lastError; } void invalidate(IDataSource::DatasourceMode mode); void update(){} + void clearErrors(){m_lastError = "";} DataSourceManager* dataManager() const {return m_dataManger;} private slots: void slotChildModelDestoroyed(); @@ -408,6 +415,7 @@ public: void invalidate(IDataSource::DatasourceMode mode){Q_UNUSED(mode)} ~CallbackDatasourceHolder(){if (m_datasource) delete m_datasource;} void update(){} + void clearErrors(){} private: IDataSource* m_datasource; bool m_owned; diff --git a/src/lrdatasourcemanager.cpp b/src/lrdatasourcemanager.cpp index 4ac169b..998cf88 100644 --- a/src/lrdatasourcemanager.cpp +++ b/src/lrdatasourcemanager.cpp @@ -252,12 +252,27 @@ void DataSourceManager::connectAllDatabases() } } -void DataSourceManager::addModel(const QString &name, QAbstractItemModel *model, bool owned) +bool DataSourceManager::addModel(const QString &name, QAbstractItemModel *model, bool owned) { + if (m_datasources.contains(name.toLower())) + removeDatasource(name.toLower()); ModelHolder* mh = new ModelHolder(model,owned); - putHolder(name, mh); - connect(mh, SIGNAL(modelStateChanged()), this, SIGNAL(datasourcesChanged())); + try{ + putHolder(name, mh); + connect(mh, SIGNAL(modelStateChanged()), this, SIGNAL(datasourcesChanged())); + } catch (ReportError e){ + putError(e.what()); + setLastError(e.what()); + return false; + } emit datasourcesChanged(); + return true; +} + +void DataSourceManager::removeModel(const QString &name) +{ + if (m_datasources.contains(name.toLower())) + removeDatasource(name.toLower()); } ICallbackDatasource *DataSourceManager::createCallbackDatasouce(const QString& name) @@ -611,6 +626,10 @@ bool DataSourceManager::connectConnection(ConnectionDesc *connectionDesc) clearErrorsList(); QString lastError =""; + foreach(QString datasourceName, dataSourceNames()){ + dataSourceHolder(datasourceName)->clearErrors(); + } + if (!QSqlDatabase::contains(connectionDesc->name())){ { QSqlDatabase db = QSqlDatabase::addDatabase(connectionDesc->driver(),connectionDesc->name()); @@ -630,10 +649,11 @@ bool DataSourceManager::connectConnection(ConnectionDesc *connectionDesc) return false; } else { foreach(QString datasourceName, dataSourceNames()){ - if (isQuery(datasourceName) || isSubQuery(datasourceName)){ + if (isQuery(datasourceName)){ QueryHolder* qh = dynamic_cast(dataSourceHolder(datasourceName)); if (qh){ qh->invalidate(designTime()?IDataSource::DESIGN_MODE:IDataSource::RENDER_MODE); + invalidateChildren(datasourceName); } } } @@ -645,11 +665,34 @@ bool DataSourceManager::connectConnection(ConnectionDesc *connectionDesc) } } } - emit datasourcesChanged(); + if (designTime()) emit datasourcesChanged(); } return true; } +QList DataSourceManager::childDatasources(const QString &parentDatasourceName) +{ + QList result; + foreach(QString datasourceName, dataSourceNames()){ + if (isSubQuery(datasourceName)){ + SubQueryHolder* sh = dynamic_cast(dataSourceHolder(datasourceName)); + if (sh->masterDatasource().compare(parentDatasourceName,Qt::CaseInsensitive)==0){ + result.append(datasourceName); + } + } + } + return result; +} + +void DataSourceManager::invalidateChildren(const QString &parentDatasourceName) +{ + foreach(QString datasourceName, childDatasources(parentDatasourceName)){ + SubQueryHolder* sh = dynamic_cast(dataSourceHolder(datasourceName)); + sh->invalidate(designTime()?IDataSource::DESIGN_MODE:IDataSource::RENDER_MODE); + invalidateChildren(datasourceName); + } +} + bool DataSourceManager::containsDatasource(const QString &dataSourceName) { return m_datasources.contains(dataSourceName.toLower()); @@ -707,7 +750,7 @@ IDataSource *DataSourceManager::dataSource(const QString &name) IDataSourceHolder* holder = m_datasources.value(name.toLower()); if (holder) { if (holder->isInvalid()) { - setLastError(holder->lastError()); + setLastError(name+" : "+holder->lastError()); return 0; } else { return holder->dataSource(designTime()?IDataSource::DESIGN_MODE:IDataSource::RENDER_MODE); @@ -927,7 +970,7 @@ void DataSourceManager::setSystemVariable(const QString &name, const QVariant &v void DataSourceManager::setLastError(const QString &value){ m_lastError = value; - if (!value.isEmpty()) { + if (!value.isEmpty() && !m_errorsList.contains(value)) { m_errorsList.append(value); } } diff --git a/src/lrdatasourcemanager.h b/src/lrdatasourcemanager.h index cb9134f..674bd3f 100644 --- a/src/lrdatasourcemanager.h +++ b/src/lrdatasourcemanager.h @@ -111,7 +111,8 @@ public: void addQuery(const QString& name, const QString& sqlText, const QString& connectionName=""); void addSubQuery(const QString& name, const QString& sqlText, const QString& connectionName, const QString& masterDatasource); void addProxy(const QString& name, QString master, QString detail, QList fields); - void addModel(const QString& name, QAbstractItemModel *model, bool owned); + bool addModel(const QString& name, QAbstractItemModel *model, bool owned); + void removeModel(const QString& name); ICallbackDatasource* createCallbackDatasouce(const QString &name); void addCallbackDatasource(ICallbackDatasource *datasource, const QString &name); void setReportVariable(const QString& name, const QVariant& value); @@ -192,6 +193,8 @@ protected: void putSubQueryDesc(SubQueryDesc *subQueryDesc); void putProxyDesc(ProxyDesc *proxyDesc); bool connectConnection(ConnectionDesc* connectionDesc); + QList childDatasources(const QString& datasourceName); + void invalidateChildren(const QString& parentDatasourceName); //ICollectionContainer virtual QObject* createElement(const QString& collectionName,const QString&); virtual int elementsCount(const QString& collectionName); diff --git a/src/lrdatasourcemanagerintf.h b/src/lrdatasourcemanagerintf.h index 123f049..7ff5aee 100644 --- a/src/lrdatasourcemanagerintf.h +++ b/src/lrdatasourcemanagerintf.h @@ -43,11 +43,12 @@ public: virtual void deleteVariable(const QString& name)=0; virtual bool containsVariable(const QString& variableName)=0; virtual QVariant variable(const QString& variableName)=0; - virtual void addModel(const QString& name, QAbstractItemModel *model, bool owned)=0; + virtual bool addModel(const QString& name, QAbstractItemModel *model, bool owned)=0; + virtual void removeModel(const QString& name)=0; virtual bool containsDatasource(const QString& dataSourceName)=0; virtual void clearUserVariables()=0; virtual ICallbackDatasource* createCallbackDatasouce(const QString& name) = 0; - virtual void addCallbackDatasource(ICallbackDatasource* datasource, const QString& name) = 0; + //virtual void addCallbackDatasource(ICallbackDatasource* datasource, const QString& name) = 0; }; } diff --git a/src/lrglobal.h b/src/lrglobal.h index e0908fc..c652ad7 100644 --- a/src/lrglobal.h +++ b/src/lrglobal.h @@ -52,7 +52,7 @@ namespace Const{ 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; + double const SELECTION_COLOR_OPACITY = 0.6; const qreal fontFACTOR = 3.5; const int mmFACTOR = 10; const int itemPaleteIconSize = 24; @@ -65,8 +65,8 @@ namespace Const{ const qreal BAND_NAME_AREA_OPACITY = 0.3; const qreal BAND_NAME_TEXT_OPACITY = 0.6; const qreal SELECTION_OPACITY = 0.3; - const QString FIELD_RX = "\\$D\\s*\\{\\s*([^\\s{}]*)\\s*\\}"; - const QString VARIABLE_RX = "\\$V\\s*\\{\\s*([^\\s{}]*)\\s*\\}"; + const QString FIELD_RX = "\\$D\\s*\\{\\s*([^{}]*)\\s*\\}"; + const QString VARIABLE_RX = "\\$V\\s*\\{\\s*([^{}]*)\\s*\\}"; const QString SCRIPT_RX = "\\$S\\s*\\{(.*)\\}"; const QString GROUP_FUNCTION_PARAM_RX = "\\(\\s*(((?:\\\"?\\$D\\s*\\{\\s*)|(?:\\\"?\\$V\\s*\\{\\s*)|(?:\\\"))(\\w+\\.?\\w+)((?:\\\")|(?:\\s*\\}\\\"?\\s*)))\\s*,\\s*\\\"(\\w+)\\\"\\s*\\)"; const int DATASOURCE_INDEX = 6; diff --git a/src/lritemdesignintf.cpp b/src/lritemdesignintf.cpp index ef8e869..8f48285 100644 --- a/src/lritemdesignintf.cpp +++ b/src/lritemdesignintf.cpp @@ -141,7 +141,9 @@ QString ContentItemDesignIntf::expandDataFields(QString context, ExpandType expa } } } else { - fieldValue = dataManager->fieldData(field).toString(); + if (expandType == ReplaceHTMLSymbols) + fieldValue = replaceHTMLSymbols(dataManager->fieldData(field).toString()); + else fieldValue = dataManager->fieldData(field).toString(); } context.replace(rx.cap(0),fieldValue); @@ -172,10 +174,16 @@ QString ContentItemDesignIntf::expandUserVariables(QString context, RenderPass p pos += rx.matchedLength(); if (dataManager->containsVariable(variable) ){ if (pass==dataManager->variablePass(variable)){ - if (expandType==EscapeSymbols){ + switch (expandType){ + case EscapeSymbols: context.replace(rx.cap(0),escapeSimbols(dataManager->variable(variable).toString())); - } else { + break; + case NoEscapeSymbols: context.replace(rx.cap(0),dataManager->variable(variable).toString()); + break; + case ReplaceHTMLSymbols: + context.replace(rx.cap(0),replaceHTMLSymbols(dataManager->variable(variable).toString())); + break; } pos=0; } @@ -228,7 +236,16 @@ QString ContentItemDesignIntf::content() const QString ContentItemDesignIntf::escapeSimbols(const QString &value) { QString result = value; - return result.replace("\"","\\\""); + result.replace("\"","\\\""); + return result; +} + +QString ContentItemDesignIntf::replaceHTMLSymbols(const QString &value) +{ + QString result = value; + result.replace("<","<"); + result.replace(">",">"); + return result; } Spacer::Spacer(QObject *owner, QGraphicsItem *parent) diff --git a/src/lritemdesignintf.h b/src/lritemdesignintf.h index 1d185c5..75e11be 100644 --- a/src/lritemdesignintf.h +++ b/src/lritemdesignintf.h @@ -40,6 +40,7 @@ class ItemDesignIntf : public BaseDesignIntf Q_OBJECT Q_PROPERTY(LocationType itemLocation READ itemLocation WRITE setItemLocation) Q_PROPERTY(bool stretchToMaxHeight READ stretchToMaxHeight WRITE setStretchToMaxHeight) + Q_PROPERTY(ItemAlign itemAlign READ itemAlign WRITE setItemAlign) Q_ENUMS(LocationType) public: enum LocationType{Band,Page}; @@ -74,13 +75,13 @@ public: :ItemDesignIntf(xmlTypeName,owner,parent){} virtual QString content() const; virtual void setContent(const QString& value)=0; - enum ExpandType {EscapeSymbols, NoEscapeSymbols}; + enum ExpandType {EscapeSymbols, NoEscapeSymbols, ReplaceHTMLSymbols}; protected: QString escapeSimbols(const QString& value); + QString replaceHTMLSymbols(const QString& value); virtual QString expandUserVariables(QString context, RenderPass pass, ExpandType expandType, DataSourceManager *dataManager); virtual QString expandDataFields(QString context, ExpandType expandType, DataSourceManager *dataManager); virtual QString expandScripts(QString context, DataSourceManager *dataManager); - }; class LayoutDesignIntf : public ItemDesignIntf{ diff --git a/src/lrpagedesignintf.cpp b/src/lrpagedesignintf.cpp index b276098..c26b20f 100644 --- a/src/lrpagedesignintf.cpp +++ b/src/lrpagedesignintf.cpp @@ -82,7 +82,14 @@ PageDesignIntf::PageDesignIntf(QObject *parent): m_isLoading(false), m_executingGroupCommand(false), m_settings(0), - m_selectionRect(0) + m_selectionRect(0), + //m_verticalGridStep(1*Const::mmFACTOR), + //m_horizontalGridStep(1*Const::mmFACTOR) + m_verticalGridStep(2), + m_horizontalGridStep(2), + m_updating(false), + m_currentObjectIndex(1), + m_multiSelectStarted(false) { m_reportEditor = dynamic_cast(parent); updatePageRect(); @@ -289,17 +296,14 @@ 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(); + m_multiSelectStarted = true; } else { QGraphicsScene::mousePressEvent(event); } } + void PageDesignIntf::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { @@ -315,7 +319,7 @@ void PageDesignIntf::mouseMoveEvent(QGraphicsSceneMouseEvent *event) } - if (event->buttons() & Qt::LeftButton && event->modifiers()==Qt::ShiftModifier){ + if (event->buttons() & Qt::LeftButton && m_multiSelectStarted/*event->modifiers()==Qt::ShiftModifier*/){ if (!m_selectionRect){ m_selectionRect = new QGraphicsRectItem(); QBrush brush(QColor(140,190,30,50)); @@ -323,15 +327,20 @@ void PageDesignIntf::mouseMoveEvent(QGraphicsSceneMouseEvent *event) m_selectionRect->setPen(Qt::DashLine); addItem(m_selectionRect); } - m_selectionRect->setRect(m_startSelectionPoint.x(),m_startSelectionPoint.y(), - event->scenePos().x()-m_startSelectionPoint.x(), - event->scenePos().y()-m_startSelectionPoint.y()); - setSelectionRect(m_selectionRect->rect()); + + QRectF selectionRect; + selectionRect.setX(qMin(event->buttonDownScenePos(Qt::LeftButton).x(),event->scenePos().x())); + selectionRect.setY(qMin(event->buttonDownScenePos(Qt::LeftButton).y(),event->scenePos().y())); + selectionRect.setRight(qMax(event->buttonDownScenePos(Qt::LeftButton).x(),event->scenePos().x())); + selectionRect.setBottom(qMax(event->buttonDownScenePos(Qt::LeftButton).y(),event->scenePos().y())); + m_selectionRect->setRect(selectionRect); } if ((m_insertMode) && (pageItem()->rect().contains(pageItem()->mapFromScene(event->scenePos())))) { if (!m_itemInsertRect->isVisible()) m_itemInsertRect->setVisible(true); - m_itemInsertRect->setPos(pageItem()->mapFromScene(event->scenePos())); + qreal posY = div(pageItem()->mapFromScene(event->scenePos()).y(), verticalGridStep()).quot * verticalGridStep(); + qreal posX = div(pageItem()->mapFromScene(event->scenePos()).x(), verticalGridStep()).quot * horizontalGridStep(); + m_itemInsertRect->setPos(posX,posY); } else { if (m_insertMode) m_itemInsertRect->setVisible(false); } @@ -344,8 +353,10 @@ void PageDesignIntf::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) checkSizeOrPosChanges(); } if (m_selectionRect) { + setSelectionRect(m_selectionRect->rect()); delete m_selectionRect; m_selectionRect = 0; + m_multiSelectStarted = false; } QGraphicsScene::mouseReleaseEvent(event); } @@ -423,6 +434,16 @@ void PageDesignIntf::bandGeometryChanged(QObject* /*object*/, QRectF newGeometry pageItem()->relocateBands(); } +QPointF PageDesignIntf::placePosOnGrid(QPointF point){ + return QPointF(div(point.x(), horizontalGridStep()).quot * horizontalGridStep(), + div(point.y(), verticalGridStep()).quot * verticalGridStep()); +} + +QSizeF PageDesignIntf::placeSizeOnGrid(QSizeF size){ + return QSizeF(div(size.width(), horizontalGridStep()).quot * horizontalGridStep(), + div(size.height(), verticalGridStep()).quot * verticalGridStep()); +} + BaseDesignIntf *PageDesignIntf::addReportItem(const QString &itemType, QPointF pos, QSizeF size) { BandDesignIntf *band=0; @@ -433,13 +454,17 @@ BaseDesignIntf *PageDesignIntf::addReportItem(const QString &itemType, QPointF p if (band) { BaseDesignIntf *reportItem = addReportItem(itemType, band, band); - reportItem->setPos(band->mapFromScene(pos)); - reportItem->setSize(size); +// QPointF insertPos = band->mapFromScene(pos); +// insertPos = QPointF(div(insertPos.x(), horizontalGridStep()).quot * horizontalGridStep(), +// div(insertPos.y(), verticalGridStep()).quot * verticalGridStep()); + + reportItem->setPos(placePosOnGrid(band->mapFromScene(pos))); + reportItem->setSize(placeSizeOnGrid(size)); return reportItem; } else { BaseDesignIntf *reportItem = addReportItem(itemType, pageItem(), pageItem()); - reportItem->setPos(pageItem()->mapFromScene(pos)); - reportItem->setSize(size); + reportItem->setPos(placePosOnGrid(pageItem()->mapFromScene(pos))); + reportItem->setSize(placeSizeOnGrid(size)); ItemDesignIntf* ii = dynamic_cast(reportItem); if (ii) ii->setItemLocation(ItemDesignIntf::Page); @@ -563,27 +588,27 @@ void PageDesignIntf::bandPosChanged(QObject * /*object*/, QPointF /*newPos*/, QP QString PageDesignIntf::genObjectName(const QObject &object) { - int index = 1; + //int index = 1; QString className(object.metaObject()->className()); className = className.right(className.length() - (className.lastIndexOf("::") + 2)); - QString tmpName = QString("%1%2").arg(className).arg(index); + QString tmpName = QString("%1%2").arg(className).arg(m_currentObjectIndex); - while (isExistsObjectName(tmpName)) { - index++; - tmpName = QString("%1%2").arg(className).arg(index); + QList itemsList = items(); + while (isExistsObjectName(tmpName,itemsList)) { + ++m_currentObjectIndex; + tmpName = QString("%1%2").arg(className).arg(m_currentObjectIndex); } return tmpName; } -bool PageDesignIntf::isExistsObjectName(const QString &objectName) const +bool PageDesignIntf::isExistsObjectName(const QString &objectName, QList& itemsList) const { QObject *item = 0; - - for (int i = 0; i < items().count(); i++) { - item = dynamic_cast(items()[i]); - + //QList itemList = items(); + for (int i = 0; i < itemsList.count(); i++) { + item = dynamic_cast(itemsList[i]); if (item) if (item->objectName() == objectName) return true; } @@ -658,9 +683,11 @@ void PageDesignIntf::dropEvent(QGraphicsSceneDragDropEvent* event) ((event->mimeData()->text().indexOf("field:")==0) || (event->mimeData()->text().indexOf("variable:")==0)) ){ + bool isVar = 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); + if (isVar) data = data.remove(QRegExp(" \\[.*\\]")); ti->setContent(data); } } @@ -779,31 +806,40 @@ void PageDesignIntf::saveSelectedItemsGeometry() void PageDesignIntf::checkSizeOrPosChanges() { + CommandIf::Ptr posCommand; if ((selectedItems().count() > 0) && (m_positionStamp.count() > 0)) { if (m_positionStamp[0].pos != selectedItems().at(0)->pos()) { - createChangePosCommand(); + posCommand = createChangePosCommand(); } - m_positionStamp.clear(); } + CommandIf::Ptr sizeCommand; if ((selectedItems().count() > 0) && (m_geometryStamp.count() > 0)) { BaseDesignIntf *reportItem = dynamic_cast(selectedItems()[0]); - if (reportItem && (m_geometryStamp[0].size != reportItem->size())) { - createChangeSizeCommand(); + sizeCommand = createChangeSizeCommand(); } - m_geometryStamp.clear(); } + if (sizeCommand && posCommand){ + CommandGroup::Ptr cm = CommandGroup::create(); + cm->addCommand(sizeCommand, false); + cm->addCommand(posCommand, false); + saveCommand(cm); + } else { + if (sizeCommand) saveCommand(sizeCommand); + if (posCommand) saveCommand(posCommand); + } + m_changeSizeMode = false; m_changePosMode = false; m_changePosOrSizeMode = false; } -void PageDesignIntf::createChangePosCommand() +CommandIf::Ptr PageDesignIntf::createChangePosCommand() { QVector newPoses; foreach(ReportItemPos itemPos, m_positionStamp) { @@ -816,11 +852,11 @@ void PageDesignIntf::createChangePosCommand() newPoses.append(newPos); } } - CommandIf::Ptr command = PosChangedCommand::create(this, m_positionStamp, newPoses); - saveCommand(command); + return PosChangedCommand::create(this, m_positionStamp, newPoses); + } -void PageDesignIntf::createChangeSizeCommand() +CommandIf::Ptr PageDesignIntf::createChangeSizeCommand() { QVector newSizes; @@ -834,8 +870,7 @@ void PageDesignIntf::createChangeSizeCommand() newSizes.append(newSize); } } - CommandIf::Ptr command = SizeChangedCommand::create(this, m_geometryStamp, newSizes); - saveCommand(command); + return SizeChangedCommand::create(this, m_geometryStamp, newSizes); } void PageDesignIntf::reactivatePageItem(PageItemDesignIntf::Ptr pageItem) @@ -960,6 +995,66 @@ void PageDesignIntf::changeSelectedGroupProperty(const QString &name, const QVar } } +int PageDesignIntf::horizontalGridStep() const +{ + return m_horizontalGridStep; +} + +void PageDesignIntf::setHorizontalGridStep(int horizontalGridStep) +{ + m_horizontalGridStep = horizontalGridStep; +} + +void PageDesignIntf::endUpdate() +{ + m_updating = false; + emit pageUpdateFinished(this); +} + +int PageDesignIntf::verticalGridStep() const +{ + return m_verticalGridStep; +} + +void PageDesignIntf::setVerticalGridStep(int verticalGridStep) +{ + m_verticalGridStep = verticalGridStep; +} + +Qt::AlignmentFlag transformFlags(bool horizontalAlign, Qt::AlignmentFlag value, Qt::AlignmentFlag flag){ + int tmpValue = value; + if (horizontalAlign){ + tmpValue &= ~(Qt::AlignHCenter | Qt::AlignLeft | Qt::AlignRight | Qt::AlignJustify); + tmpValue |= flag; + } else { + tmpValue &= ~(Qt::AlignVCenter | Qt::AlignTop | Qt::AlignBottom); + tmpValue |= flag; + } + return Qt::AlignmentFlag(tmpValue); +} + +void PageDesignIntf::changeSelectedGrpoupTextAlignPropperty(const bool& horizontalAlign, Qt::AlignmentFlag flag) +{ + if (selectedItems().count() > 0) { + CommandGroup::Ptr cm = CommandGroup::create(); + m_executingCommand = true; + foreach(QGraphicsItem * item, selectedItems()) { + BaseDesignIntf *bdItem = dynamic_cast(item); + if (bdItem) { + QVariant oldValue = bdItem->property("alignment"); + if (oldValue.isValid()){ + QVariant value = transformFlags(horizontalAlign, Qt::AlignmentFlag(oldValue.toInt()), flag); + bdItem->setProperty("alignment",value); + CommandIf::Ptr command = PropertyChangedCommand::create(this, bdItem->objectName(), "alignment", oldValue, value); + cm->addCommand(command, false); + } + } + } + m_executingCommand = false; + saveCommand(cm, false); + } +} + void PageDesignIntf::undo() { if (m_currentCommand >= 0) { @@ -1035,7 +1130,8 @@ void PageDesignIntf::deleteSelected(bool createCommand) } foreach(QGraphicsItem* item, selectedItems()){ - removeReportItem(dynamic_cast(item),createCommand); + if (!dynamic_cast(item)) + removeReportItem(dynamic_cast(item),createCommand); } } @@ -1223,10 +1319,22 @@ void PageDesignIntf::sameHeight() void PageDesignIntf::addHLayout() { - if (selectedItems().size()==0) return; + if (selectedItems().isEmpty()) return; QList si = selectedItems(); QList::iterator it = si.begin(); + + int itemsCount = 0; + for (; it != si.end();) { + if (dynamic_cast(*it)){ + itemsCount++; + break; + } + ++it; + }; + + if (itemsCount == 0) return; + for (; it != si.end();) { if (!dynamic_cast(*it)) { (*it)->setSelected(false); @@ -1235,17 +1343,20 @@ void PageDesignIntf::addHLayout() else ++it; } - it = si.begin(); - QGraphicsItem* elementsParent = (*it)->parentItem(); - for (; it != si.end();++it) { - if ((*it)->parentItem()!=elementsParent){ - QMessageBox::information(0,QObject::tr("Attention!"),QObject::tr("Selected elements have different parent containers")); - return; + if (!si.isEmpty()){ + it = si.begin(); + QGraphicsItem* elementsParent = (*it)->parentItem(); + for (; it != si.end();++it) { + if ((*it)->parentItem()!=elementsParent){ + QMessageBox::information(0,QObject::tr("Attention!"),QObject::tr("Selected elements have different parent containers")); + return; + } } + CommandIf::Ptr cm = InsertHLayoutCommand::create(this); + saveCommand(cm,true); } - CommandIf::Ptr cm = InsertHLayoutCommand::create(this); - saveCommand(cm,true); + } bool hLayoutLessThen(QGraphicsItem *c1, QGraphicsItem *c2) @@ -1493,16 +1604,18 @@ CommandIf::Ptr PasteCommand::create(PageDesignIntf *page, const QString &itemsXM bool PasteCommand::doIt() { m_itemNames.clear(); + ItemsReaderIntf::Ptr reader = StringXMLreader::create(m_itemsXML); if (reader->first() && reader->itemType() == "Object") { + page()->beginUpdate(); insertItem(reader); while (reader->next()) { insertItem(reader); } + page()->endUpdate(); } - else return false; page()->selectedItems().clear(); diff --git a/src/lrpagedesignintf.h b/src/lrpagedesignintf.h index 2ee9f6e..49e308c 100644 --- a/src/lrpagedesignintf.h +++ b/src/lrpagedesignintf.h @@ -130,6 +130,18 @@ namespace LimeReport { void emitItemRemoved(BaseDesignIntf* item); DataSourceManager* datasourceManager(); + bool isSaved(){ return !m_hasHanges;} + void changeSelectedGrpoupTextAlignPropperty(const bool& horizontalAlign, Qt::AlignmentFlag flag); + + int verticalGridStep() const; + void setVerticalGridStep(int verticalGridStep); + + int horizontalGridStep() const; + void setHorizontalGridStep(int horizontalGridStep); + + void beginUpdate(){m_updating = true;} + bool isUpdating(){return m_updating;} + void endUpdate(); protected: virtual void keyPressEvent(QKeyEvent *event); @@ -146,7 +158,7 @@ namespace LimeReport { LimeReport::BandDesignIntf::BandsType findPriorType(LimeReport::BandDesignIntf::BandsType bandType); - bool isExistsObjectName (const QString& objectName) const; + bool isExistsObjectName (const QString& objectName, QList &itemsList) const; QRectF getRectByPageSize(PageSize pageSize); bool isLoading(); @@ -154,19 +166,23 @@ namespace LimeReport { void objectLoadFinished(); HorizontalLayout* internalAddHLayout(); - signals: + QPointF placePosOnGrid(QPointF point); + QSizeF placeSizeOnGrid(QSizeF size); + signals: void geometryChanged(QRectF newGeometry); void insertModeStarted(); void itemInserted(LimeReport::PageDesignIntf* report, QPointF pos, const QString& ItemType); void itemInsertCanceled(const QString& ItemType); void itemSelected(LimeReport::BaseDesignIntf *item); void multiItemsSelected(QList* objectsList); + void miltiItemsSelectionFinished(); void commandHistoryChanged(); void itemPropertyChanged(const QString& objectName, const QString& propertyName, const QVariant& oldValue, const QVariant& newValue); - void itemAdded(LimeReport::PageDesignIntf* report, LimeReport::BaseDesignIntf* item); - void itemRemoved(LimeReport::PageDesignIntf* report, LimeReport::BaseDesignIntf* item); - void bandAdded(LimeReport::PageDesignIntf* report, LimeReport::BandDesignIntf* band); - void bandRemoved(LimeReport::PageDesignIntf* report, LimeReport::BandDesignIntf* band); + void itemAdded(LimeReport::PageDesignIntf* page, LimeReport::BaseDesignIntf* item); + void itemRemoved(LimeReport::PageDesignIntf* page, LimeReport::BaseDesignIntf* item); + void bandAdded(LimeReport::PageDesignIntf* page, LimeReport::BandDesignIntf* band); + void bandRemoved(LimeReport::PageDesignIntf* page, LimeReport::BandDesignIntf* band); + void pageUpdateFinished(LimeReport::PageDesignIntf* page); public slots: BaseDesignIntf* addBand(const QString& bandType); BaseDesignIntf* addBand(BandDesignIntf::BandsType bandType); @@ -210,10 +226,11 @@ namespace LimeReport { void saveSelectedItemsPos(); void saveSelectedItemsGeometry(); void checkSizeOrPosChanges(); - void createChangePosCommand(); - void createChangeSizeCommand(); + CommandIf::Ptr createChangePosCommand(); + CommandIf::Ptr createChangeSizeCommand(); void saveChangeProppertyCommand(const QString& objectName, const QString& propertyName, const QVariant& oldPropertyValue, const QVariant& newPropertyValue); void changeSelectedGroupProperty(const QString& name,const QVariant& value); + private: PageSize m_pageSize; QSizeF m_pageSizeValue; @@ -244,7 +261,11 @@ namespace LimeReport { QList m_animationList; QPointF m_startSelectionPoint; QGraphicsRectItem* m_selectionRect; - QPointF m_startMovePoint; + int m_verticalGridStep; + int m_horizontalGridStep; + bool m_updating; + int m_currentObjectIndex; + bool m_multiSelectStarted; }; class AbstractPageCommand : public CommandIf{ diff --git a/src/lrpageitemdesignintf.cpp b/src/lrpageitemdesignintf.cpp index ec7470c..f55b54e 100644 --- a/src/lrpageitemdesignintf.cpp +++ b/src/lrpageitemdesignintf.cpp @@ -29,6 +29,8 @@ ****************************************************************************/ #include "lrpageitemdesignintf.h" #include "lrbanddesignintf.h" +#include "lrpagedesignintf.h" + #include #include @@ -50,6 +52,7 @@ PageItemDesignIntf::PageItemDesignIntf(QObject *owner, QGraphicsItem *parent) : setFixedPos(true); setPosibleResizeDirectionFlags(Fixed); initPageSize(m_pageSize); + selectionMarker()->setColor(Qt::transparent); } PageItemDesignIntf::PageItemDesignIntf(const PageSize pageSize, const QRectF &rect, QObject *owner, QGraphicsItem *parent) : @@ -192,15 +195,12 @@ int PageItemDesignIntf::calcBandIndex(BandDesignIntf::BandsType bandType, BandDe QSet groupFooterIgnoredBands; groupFooterIgnoredBands << BandDesignIntf::DataFooter << BandDesignIntf::GroupHeader; - QSet dataFooterIgnoredBands; - dataFooterIgnoredBands << BandDesignIntf::GroupHeader; - int bandIndex=-1; qSort(m_bands.begin(),m_bands.end(),bandSortBandLessThenByIndex); foreach(BandDesignIntf* band,m_bands){ if ((band->bandType()==BandDesignIntf::GroupHeader)&&(band->bandType()>bandType)) break; if ((band->bandType()>bandType)) break; - if (bandIndexbandIndex()) bandIndex=band->maxChildIndex()+1; + if (bandIndex<=band->bandIndex()) bandIndex=band->maxChildIndex()+1; } if (bandIndex==-1) { @@ -291,21 +291,49 @@ void PageItemDesignIntf::registerBand(BandDesignIntf *band) } } +void PageItemDesignIntf::initColumnsPos(QVector &posByColumns, qreal pos, int columnCount){ + posByColumns.clear(); + for(int i=0;i posByColumn; + qSort(m_bands.begin(),m_bands.end(),bandSortBandLessThenByIndex); - if (m_bands.count()>0) m_bands[0]->setPos(pageRect().x(),pageRect().y()); + if (m_bands.count()>0) { + initColumnsPos(posByColumn,pageRect().x(),m_bands[0]->columnsCount()); + m_bands[0]->setPos(pageRect().x(),pageRect().y()); + posByColumn[0]+=m_bands[0]->height()+bandSpace; + } if(m_bands.count()>1){ - //m_bands[0]->setBandIndex(0); + for(int i=0;i<(m_bands.count()-1);i++){ - if ((m_bands[i+1]->bandType()!=BandDesignIntf::PageFooter) || (itemMode() & DesignMode)) - m_bands[i+1]->setPos(pageRect().x(),m_bands[i]->pos().y()+m_bands[i]->height()+bandSpace); - //m_bands[i+1]->setBandIndex(i+1); + if ((m_bands[i+1]->bandType()!=BandDesignIntf::PageFooter) || (itemMode() & DesignMode)){ + if (m_bands[i+1]->columnsCount()>1 && + m_bands[i]->columnsCount() != m_bands[i+1]->columnsCount()) + { + qreal curPos = posByColumn[0]; + initColumnsPos(posByColumn, + curPos, + m_bands[i+1]->columnsCount()); + } + if (m_bands[i+1]->columnIndex()==0){ + m_bands[i+1]->setPos(pageRect().x(),posByColumn[0]); + posByColumn[0] += m_bands[i+1]->height()+bandSpace; + } else { + m_bands[i+1]->setPos(m_bands[i+1]->pos().x(),posByColumn[m_bands[i+1]->columnIndex()]); + posByColumn[m_bands[i+1]->columnIndex()] += m_bands[i+1]->height()+bandSpace; + } + } + } } } @@ -457,7 +485,7 @@ void PageItemDesignIntf::collectionLoadFinished(const QString &collectionName) #endif BandDesignIntf* item = dynamic_cast(obj); if (item) { - registerBand(item); + registerBand(item); } } } @@ -505,6 +533,25 @@ void PageItemDesignIntf::paintGrid(QPainter *ppainter) ppainter->restore(); } +QList& PageItemDesignIntf::bands() +{ + return m_bands; +} + +void PageItemDesignIntf::setGridStep(int value) +{ + if (page()) { + page()->setHorizontalGridStep(value); + page()->setVerticalGridStep(value); + } +} + +int PageItemDesignIntf::gridStep() +{ + if (page()) return page()->horizontalGridStep(); + else return 2; +} + PageItemDesignIntf::Ptr PageItemDesignIntf::create(QObject *owner) { return PageItemDesignIntf::Ptr(new PageItemDesignIntf(owner)); diff --git a/src/lrpageitemdesignintf.h b/src/lrpageitemdesignintf.h index 079b621..7a1f776 100644 --- a/src/lrpageitemdesignintf.h +++ b/src/lrpageitemdesignintf.h @@ -47,7 +47,7 @@ class PageItemDesignIntf : public LimeReport::BaseDesignIntf Q_PROPERTY(int rightMargin READ rightMargin WRITE setRightMargin) Q_PROPERTY(int leftMargin READ leftMargin WRITE setLeftMargin) Q_PROPERTY(Orientation pageOrientation READ pageOrientation WRITE setPageOrientation) - Q_PROPERTY(PageSize pageSize READ pageSize WRITE setPageSize ) + Q_PROPERTY(PageSize pageSize READ pageSize WRITE setPageSize) friend class ReportRender; public: enum Orientation { Portrait, Landscape }; @@ -99,7 +99,9 @@ public: Orientation pageOrientation() const {return m_pageOrientaion;} PageSize pageSize() const {return m_pageSize;} void setPageSize(const PageSize &size); - + QList& bands(); + void setGridStep(int value); + int gridStep(); protected slots: void bandDeleted(QObject* band); void bandGeometryChanged(QObject* /*object*/, QRectF newGeometry, QRectF oldGeometry); @@ -112,6 +114,7 @@ protected: void initPageSize(const QSizeF &size); private: void paintGrid(QPainter *ppainter); + void initColumnsPos(QVector&posByColumns, qreal pos, int columnCount); private: int m_topMargin; int m_bottomMargin; diff --git a/src/lrpreviewreportwindow.cpp b/src/lrpreviewreportwindow.cpp index 11c4a90..2681576 100644 --- a/src/lrpreviewreportwindow.cpp +++ b/src/lrpreviewreportwindow.cpp @@ -37,6 +37,7 @@ #include #include #include +#include PreviewReportWindow::PreviewReportWindow(ReportEnginePrivate *report,QWidget *parent, QSettings *settings, Qt::WindowFlags flags) : QMainWindow(parent,flags), @@ -75,6 +76,17 @@ void PreviewReportWindow::restoreSetting() QVariant v = settings()->value("Geometry"); if (v.isValid()){ restoreGeometry(v.toByteArray()); + } else { + QDesktopWidget *desktop = QApplication::desktop(); + + int screenWidth = desktop->width(); + int screenHeight = desktop->height(); + + int x = screenWidth*0.1; + int y = screenHeight*0.1; + + resize(screenWidth*0.8, screenHeight*0.8); + move(x, y); } v = settings()->value("State"); if (v.isValid()){ diff --git a/src/lrreportdesignwidget.cpp b/src/lrreportdesignwidget.cpp index 96b47cc..c204a9c 100644 --- a/src/lrreportdesignwidget.cpp +++ b/src/lrreportdesignwidget.cpp @@ -225,6 +225,8 @@ bool ReportDesignWidget::save() return m_report->saveToFile(); } else { + m_report->emitSaveReport(); + if (m_report->isSaved()) return true; return m_report->saveToFile(QFileDialog::getSaveFileName(this,tr("Report file name"),"","Report files (*.lrxml);; All files (*)")); } } @@ -250,6 +252,11 @@ bool ReportDesignWidget::isNeedToSave() return m_report->isNeedToSave(); } +bool ReportDesignWidget::emitLoadReport() +{ + return m_report->emitLoadReport(); +} + void ReportDesignWidget::updateSize() { activePage()->slotUpdateItemSize(); @@ -349,9 +356,10 @@ void ReportDesignWidget::setFont(const QFont& font) activePage()->setFont(font); } -void ReportDesignWidget::setTextAlign(const Qt::Alignment& alignment) +void ReportDesignWidget::setTextAlign(const bool& horizontalAlign, const Qt::AlignmentFlag& alignment) { - activePage()->setTextAlign(alignment); + //activePage()->setTextAlign(alignment); + activePage()->changeSelectedGrpoupTextAlignPropperty(horizontalAlign, alignment); } void ReportDesignWidget::setBorders(const BaseDesignIntf::BorderLines& borders) diff --git a/src/lrreportdesignwidget.h b/src/lrreportdesignwidget.h index dff1e04..f38f5d5 100644 --- a/src/lrreportdesignwidget.h +++ b/src/lrreportdesignwidget.h @@ -93,6 +93,7 @@ public: ReportEnginePrivate* report(){return m_report;} QString reportFileName(); bool isNeedToSave(); + bool emitLoadReport(); public slots: void saveToFile(const QString&); bool save(); @@ -117,7 +118,7 @@ public slots: void editLayoutMode(bool value); void addHLayout(); void setFont(const QFont &font); - void setTextAlign(const Qt::Alignment& alignment); + void setTextAlign(const bool &horizontalAlign, const Qt::AlignmentFlag &alignment); void setBorders(const BaseDesignIntf::BorderLines& borders); private slots: void slotItemSelected(LimeReport::BaseDesignIntf *item); diff --git a/src/lrreportdesignwindow.cpp b/src/lrreportdesignwindow.cpp index 46c6fdd..4841a6d 100644 --- a/src/lrreportdesignwindow.cpp +++ b/src/lrreportdesignwindow.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include "lrreportdesignwindow.h" #include "lrbandsmanager.h" @@ -230,15 +231,15 @@ void ReportDesignWindow::createToolBars() { createBandsButton(); - m_mainToolBar = addToolBar("Main Tools"); + m_mainToolBar = addToolBar(tr("Main Tools")); m_mainToolBar->setIconSize(QSize(16,16)); m_mainToolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea | Qt::TopToolBarArea ); m_mainToolBar->setFloatable(false); m_mainToolBar->setObjectName("mainTools"); m_mainToolBar->addAction(m_newReportAction); - m_mainToolBar->addAction(m_saveReportAction); m_mainToolBar->addAction(m_loadReportAction); + m_mainToolBar->addAction(m_saveReportAction); m_mainToolBar->addSeparator(); m_mainToolBar->addAction(m_copyAction); @@ -294,6 +295,7 @@ void ReportDesignWindow::createBandsButton() m_newBandButton = new QToolButton(this); m_newBandButton->setPopupMode(QToolButton::InstantPopup); m_newBandButton->setIcon(QIcon(":/report/images/addBand")); + m_newBandButton->setToolTip(tr("Report bands")); m_bandsAddSignalsMap = new QSignalMapper(this); @@ -501,6 +503,17 @@ void ReportDesignWindow::restoreSetting() QVariant v = settings()->value("Geometry"); if (v.isValid()){ restoreGeometry(v.toByteArray()); + } else { + QDesktopWidget *desktop = QApplication::desktop(); + + int screenWidth = desktop->width(); + int screenHeight = desktop->height(); + + int x = screenWidth*0.1; + int y = screenHeight*0.1; + + resize(screenWidth*0.8, screenHeight*0.8); + move(x, y); } v = settings()->value("State"); if (v.isValid()){ @@ -731,17 +744,25 @@ void ReportDesignWindow::slotSaveReportAs() void ReportDesignWindow::slotLoadReport() { if (checkNeedToSave()){ - QString fileName = QFileDialog::getOpenFileName(this,tr("Report file name"),"","Report files(*.lrxml);; All files(*)"); - if (!fileName.isEmpty()) { - QApplication::processEvents(); - setCursor(Qt::WaitCursor); - m_reportDesignWidget->clear(); - m_reportDesignWidget->loadFromFile(fileName); - m_lblReportName->setText(fileName); - m_propertyModel->setObject(0); - updateRedoUndo(); - unsetCursor(); + if (!m_reportDesignWidget->emitLoadReport()){ + QString fileName = QFileDialog::getOpenFileName( + this,tr("Report file name"), + m_reportDesignWidget->report()->currentReportsDir(), + "Report files(*.lrxml);; All files(*)" + ); + if (!fileName.isEmpty()) { + QApplication::processEvents(); + setCursor(Qt::WaitCursor); + m_reportDesignWidget->clear(); + m_reportDesignWidget->loadFromFile(fileName); + m_lblReportName->setText(fileName); + m_propertyModel->setObject(0); + updateRedoUndo(); + unsetCursor(); + setWindowTitle(m_reportDesignWidget->report()->reportName() + " - Lime Report Designer"); + } } + } } diff --git a/src/lrreportengine.cpp b/src/lrreportengine.cpp index 909e399..036d08c 100644 --- a/src/lrreportengine.cpp +++ b/src/lrreportengine.cpp @@ -54,7 +54,8 @@ QSettings* ReportEngine::m_settings = 0; ReportEnginePrivate::ReportEnginePrivate(QObject *parent) : QObject(parent), m_fileName(""), m_settings(0), m_ownedSettings(false), - m_printer(new QPrinter(QPrinter::HighResolution)), m_printerSelected(false), m_showProgressDialog(true) + m_printer(new QPrinter(QPrinter::HighResolution)), m_printerSelected(false), + m_showProgressDialog(true), m_reportName("") { m_datasources= new DataSourceManager(this); m_datasources->setObjectName("datasources"); @@ -313,6 +314,32 @@ PageDesignIntf* ReportEnginePrivate::createPreviewScene(QObject* parent){ return result; } +void ReportEnginePrivate::emitSaveReport() +{ + emit onSave(); +} + +bool ReportEnginePrivate::emitLoadReport() +{ + bool result = false; + emit onLoad(result); + return result; +} + +bool ReportEnginePrivate::isSaved() +{ + foreach (PageDesignIntf* page, m_pages) { + if (!page->isSaved()) return false; + } + return true; +} + +void ReportEnginePrivate::setCurrentReportsDir(const QString &dirName) +{ + if (QDir(dirName).exists()) + m_reportsDir = dirName; +} + void ReportEnginePrivate::cancelRender() { if (m_reportRender) @@ -366,22 +393,42 @@ QSettings*ReportEnginePrivate::settings() bool ReportEnginePrivate::loadFromFile(const QString &fileName) { clearReport(); + ItemsReaderIntf::Ptr reader = FileXMLReader::create(fileName); if (reader->first()){ if (reader->readItem(this)){ m_fileName=fileName; + QFileInfo fi(fileName); + m_reportName = fi.fileName(); return true; }; } return false; } -bool ReportEnginePrivate::loadFromByteArray(QByteArray* data){ +bool ReportEnginePrivate::loadFromByteArray(QByteArray* data, const QString &name){ clearReport(); + ItemsReaderIntf::Ptr reader = ByteArrayXMLReader::create(data); if (reader->first()){ if (reader->readItem(this)){ - m_fileName=""; + m_fileName = ""; + m_reportName = name; + return true; + }; + } + return false; +} + +bool ReportEnginePrivate::loadFromString(const QString &report, const QString &name) +{ + clearReport(); + + ItemsReaderIntf::Ptr reader = StringXMLreader::create(report); + if (reader->first()){ + if (reader->readItem(this)){ + m_fileName = ""; + m_reportName = name; return true; }; } @@ -408,6 +455,31 @@ bool ReportEnginePrivate::saveToFile(const QString &fileName) return saved; } +QByteArray ReportEnginePrivate::saveToByteArray() +{ + QScopedPointer< ItemsWriterIntf > writer(new XMLWriter()); + writer->putItem(this); + QByteArray result = writer->saveToByteArray(); + if (!result.isEmpty()){ + foreach(PageDesignIntf* page, m_pages){ + page->setToSaved(); + } + } + return result; +} + +QString ReportEnginePrivate::saveToString(){ + QScopedPointer< ItemsWriterIntf > writer(new XMLWriter()); + writer->putItem(this); + QString result = writer->saveToString(); + if (!result.isEmpty()){ + foreach(PageDesignIntf* page, m_pages){ + page->setToSaved(); + } + } + return result; +} + bool ReportEnginePrivate::isNeedToSave() { foreach(PageDesignIntf* page, m_pages){ @@ -465,6 +537,8 @@ ReportEngine::ReportEngine(QObject *parent) connect(d, SIGNAL(renderPageFinished(int)), this, SIGNAL(renderPageFinished(int))); connect(d, SIGNAL(renderFinished()), this, SIGNAL(renderFinished())); + connect(d, SIGNAL(onSave()), this, SIGNAL(onSave())); + connect(d, SIGNAL(onLoad(bool&)), this, SIGNAL(onLoad(bool&))); } ReportEngine::~ReportEngine() @@ -535,6 +609,12 @@ bool ReportEngine::loadFromByteArray(QByteArray* data){ return d->loadFromByteArray(data); } +bool ReportEngine::loadFromString(const QString &data) +{ + Q_D(ReportEngine); + return d->loadFromString(data); +} + QString ReportEngine::reportFileName() { Q_D(ReportEngine); @@ -553,12 +633,42 @@ bool ReportEngine::saveToFile(const QString &fileName) return d->saveToFile(fileName); } +QByteArray ReportEngine::saveToByteArray() +{ + Q_D(ReportEngine); + return d->saveToByteArray(); +} + +QString ReportEngine::saveToString() +{ + Q_D(ReportEngine); + return d->saveToString(); +} + QString ReportEngine::lastError() { Q_D(ReportEngine); return d->lastError(); } +void ReportEngine::setCurrentReportsDir(const QString &dirName) +{ + Q_D(ReportEngine); + return d->setCurrentReportsDir(dirName); +} + +void ReportEngine::setReportName(const QString &name) +{ + Q_D(ReportEngine); + return d->setReportName(name); +} + +QString ReportEngine::reportName() +{ + Q_D(ReportEngine); + return d->reportName(); +} + void ReportEngine::cancelRender() { Q_D(ReportEngine); diff --git a/src/lrreportengine.h b/src/lrreportengine.h index 7bfa6a8..1eb4966 100644 --- a/src/lrreportengine.h +++ b/src/lrreportengine.h @@ -78,14 +78,22 @@ public: bool loadFromFile(const QString& fileName); bool loadFromByteArray(QByteArray *data); + bool loadFromString(const QString& data); QString reportFileName(); bool saveToFile(); bool saveToFile(const QString& fileName); + QByteArray saveToByteArray(); + QString saveToString(); QString lastError(); + void setCurrentReportsDir(const QString& dirName); + void setReportName(const QString& name); + QString reportName(); signals: void renderStarted(); void renderFinished(); void renderPageFinished(int renderedPageCount); + void onLoad(bool& loaded); + void onSave(); public slots: void cancelRender(); protected: diff --git a/src/lrreportengine_p.h b/src/lrreportengine_p.h index ade104a..d45f311 100644 --- a/src/lrreportengine_p.h +++ b/src/lrreportengine_p.h @@ -82,14 +82,24 @@ public: void setShowProgressDialog(bool value){m_showProgressDialog = value;} QSettings* settings(); bool loadFromFile(const QString& fileName); - bool loadFromByteArray(QByteArray *data); + bool loadFromByteArray(QByteArray *data, const QString& name = ""); + bool loadFromString(const QString& report, const QString& name = ""); QString reportFileName(){return m_fileName;} bool saveToFile(); bool saveToFile(const QString& fileName); + QByteArray saveToByteArray(); + QString saveToString(); bool isNeedToSave(); QString lastError(); ReportEngine * q_ptr; PageDesignIntf *createPreviewScene(QObject *parent); + void emitSaveReport(); + bool emitLoadReport(); + bool isSaved(); + void setCurrentReportsDir(const QString& dirName); + QString currentReportsDir(){ return m_reportsDir;} + void setReportName(const QString& reportName){ m_reportName=reportName;} + QString reportName(){ return m_reportName;} signals: void pagesLoadFinished(); void datasourceCollectionLoadFinished(const QString& collectionName); @@ -97,6 +107,8 @@ signals: void renderStarted(); void renderFinished(); void renderPageFinished(int renderedPageCount); + void onLoad(bool& loaded); + void onSave(); public slots: void cancelRender(); protected: @@ -125,7 +137,8 @@ private: QScopedPointer m_printer; bool m_printerSelected; bool m_showProgressDialog; - + QString m_reportsDir; + QString m_reportName; }; } diff --git a/src/lrreportrender.cpp b/src/lrreportrender.cpp index 932347e..41ddb4e 100644 --- a/src/lrreportrender.cpp +++ b/src/lrreportrender.cpp @@ -50,6 +50,95 @@ void ReportRender::initColumns(){ m_currentStartDataPos.append(0); } +bool ReportRender::isNeedToRearrangeColumnsItems() +{ + if (m_columnedBandItems.size()<=1) return false; + if (m_columnedBandItems[0]->columnsFillDirection()!=BandDesignIntf::VerticalUniform) + return false; + + int avg = m_columnedBandItems.size()/m_columnedBandItems[0]->columnsCount(); + + for (int i=0;imaxHeight){ + maxHeight = m_maxHeightByColumn[i]; + maxHeightColumn = i; + } + if (maxHeightColumn>0 && columnItemsCount(maxHeightColumn) lastColumnItem(maxHeightColumn-1)->height() + ){ + return true; + } + } + return false; +} + +BandDesignIntf *ReportRender::lastColumnItem(int columnIndex) +{ + if (columnIndex<0) return 0; + for(int i=0;icolumnIndex()>columnIndex) + return m_columnedBandItems[i-1]; + } + return m_columnedBandItems.last(); +} + +void ReportRender::rearrangeColumnsItems() +{ + if (isNeedToRearrangeColumnsItems()){ + qreal startHeight = columnHeigth(0); + int avg = m_columnedBandItems.size()/m_columnedBandItems[0]->columnsCount(); + for (int i=1;icolumnsCount();++i){ + if (columnItemsCount(i)columnsCount()-i) - columnItemsCount(i); + for (int j=0;jsetPos(band->pos().x()+band->width(),m_columnedBandItems[0]->pos().y()); + band->setColumnIndex(i); + } + + } + } + m_renderPageItem->relocateBands(); + m_maxHeightByColumn[0]+=startHeight-maxColumnHeight(); + m_currentStartDataPos[0]-=startHeight-maxColumnHeight(); + m_columnedBandItems.clear(); + } +} + +int ReportRender::columnItemsCount(int columnIndex) +{ + int result = 0; + foreach(BandDesignIntf* band, m_columnedBandItems){ + if (band->columnIndex()==columnIndex) + ++result; + if (band->columnIndex()>columnIndex) break; + } + return result; +} + +qreal ReportRender::columnHeigth(int columnIndex) +{ + qreal result = 0; + for(int i=0;icolumnIndex()==columnIndex) + result += m_columnedBandItems[i]->height(); + if (m_columnedBandItems[i]->columnIndex()>columnIndex) break; + } + return result; +} + +qreal ReportRender::maxColumnHeight() +{ + qreal result = 0; + for (int i=0;icolumnsCount();++i){ + qreal curColumnHeight = columnHeigth(i); + if (curColumnHeight>result) result = curColumnHeight; + } + return result; +} + ReportRender::ReportRender(QObject *parent) :QObject(parent), m_renderPageItem(0), m_pageCount(0), m_currentColumn(0) { @@ -229,7 +318,10 @@ void ReportRender::renderBand(BandDesignIntf *patternBand, ReportRender::DataRen } else { if (mode==StartNewPageAsNeeded){ - if (bandClone->columnsCount()>1 && bandClone->columnsFillDirection()==BandDesignIntf::Vertical){ + if (bandClone->columnsCount()>1 && + (bandClone->columnsFillDirection()==BandDesignIntf::Vertical || + bandClone->columnsFillDirection()==BandDesignIntf::VerticalUniform)) + { startNewColumn(); } else { savePage(); @@ -255,7 +347,7 @@ void ReportRender::renderBand(BandDesignIntf *patternBand, ReportRender::DataRen void ReportRender::renderDataBand(BandDesignIntf *dataBand) { IDataSource* bandDatasource = 0; - if (dataBand) + if (dataBand && !dataBand->datasourceName().isEmpty()) bandDatasource = datasources()->dataSource(dataBand->datasourceName()); if(bandDatasource && !bandDatasource->eof() && !m_renderCanceled){ @@ -264,10 +356,22 @@ void ReportRender::renderDataBand(BandDesignIntf *dataBand) datasources()->setReportVariable(varName,1); renderBand(dataBand->bandHeader()); + + if (dataBand->bandHeader() && dataBand->bandHeader()->reprintOnEachPage()) + m_reprintableBands.append(dataBand->bandHeader()); + renderChildHeader(dataBand,PrintNotAlwaysPrintable); renderGroupHeader(dataBand, bandDatasource, true); + + bool firstTime = true; + while(!bandDatasource->eof() && !m_renderCanceled){ + if (!firstTime && dataBand->startNewPage()) { + savePage(); + startNewPage(); + } + if (dataBand->tryToKeepTogether()) openDataGroup(dataBand); if (dataBand->keepFooterTogether() && !bandDatasource->hasNext()) @@ -290,10 +394,12 @@ void ReportRender::renderDataBand(BandDesignIntf *dataBand) renderGroupHeader(dataBand, bandDatasource, false); if (dataBand->tryToKeepTogether()) closeDataGroup(dataBand); + firstTime = false; } + + m_reprintableBands.removeOne(dataBand->bandHeader()); renderBand(dataBand->bandFooter(),StartNewPageAsNeeded); renderGroupFooter(dataBand); - //renderChildFooter(dataBand,PrintNotAlwaysPrintable); datasources()->deleteVariable(varName); } else if (bandDatasource==0) { renderBand(dataBand,StartNewPageAsNeeded); @@ -315,7 +421,8 @@ void ReportRender::renderPageFooter(PageItemDesignIntf *patternPage) bandClone->updateItemSize(m_datasources); bandClone->setItemPos(m_patternPageItem->pageRect().x(),m_patternPageItem->pageRect().bottom()-bandClone->height()); bandClone->setHeight(m_pageFooterHeight); - m_maxHeightByColumn[0]+=m_pageFooterHeight; + for(int i=0;iclearGroupFunctionValues(band->objectName()); } @@ -399,6 +506,8 @@ void ReportRender::renderGroupHeader(BandDesignIntf *parentBand, IDataSource* da closeDataGroup(band); } if (!gb->isStarted()){ + if (band->reprintOnEachPage()) + m_reprintableBands.append(band); gb->startGroup(m_datasources); openDataGroup(band); if (!firstTime && gb->startNewPage()){ @@ -416,6 +525,7 @@ void ReportRender::renderGroupFooter(BandDesignIntf *parentBand) foreach(BandDesignIntf* band,parentBand->childrenByType(BandDesignIntf::GroupHeader)){ IGroupBand* gb = dynamic_cast(band); if (gb->isStarted()){ + if (band->reprintOnEachPage()) m_reprintableBands.removeOne(band); if (band->childBands().count()>0){ renderBand(band->childBands().at(0),StartNewPageAsNeeded); } @@ -496,8 +606,10 @@ void ReportRender::openFooterGroup(BandDesignIntf *band) void ReportRender::closeDataGroup(BandDesignIntf *band) { IGroupBand* groupBand = dynamic_cast(band); - if (groupBand) + if (groupBand){ groupBand->closeGroup(); + if (band->reprintOnEachPage()) m_reprintableBands.removeOne(band); + } closeGroup(band); } @@ -524,16 +636,20 @@ qreal minVectorValue(QVector vector){ bool ReportRender::registerBand(BandDesignIntf *band, bool registerInChildren) { if (band->columnsCount()==1 && m_maxHeightByColumn.size()>1){ - m_currentColumn = 0; - qreal minValue = minVectorValue(m_maxHeightByColumn); - m_maxHeightByColumn.clear(); - m_maxHeightByColumn.append(minValue); - qreal maxValue = maxVectorValue(m_currentStartDataPos); - m_currentStartDataPos.clear(); - m_currentStartDataPos.append(maxValue); + if (band->bandType()!=BandDesignIntf::PageFooter){ + rearrangeColumnsItems(); + m_currentColumn = 0; + qreal minValue = minVectorValue(m_maxHeightByColumn); + m_maxHeightByColumn.clear(); + m_maxHeightByColumn.append(minValue); + qreal maxValue = maxVectorValue(m_currentStartDataPos); + m_currentStartDataPos.clear(); + m_currentStartDataPos.append(maxValue); + } } - if (band->columnsCount()>1){ + if ( (band->columnsCount()>1) && !band->isHeader()){ + if (m_maxHeightByColumn.size()!=band->columnsCount()){ for(int i=1;icolumnsCount();++i){ m_maxHeightByColumn.append(m_maxHeightByColumn[0]); @@ -548,18 +664,46 @@ bool ReportRender::registerBand(BandDesignIntf *band, bool registerInChildren) m_currentColumn = 0; } } + } if (band->height()<=m_maxHeightByColumn[m_currentColumn]){ - m_maxHeightByColumn[m_currentColumn]-=band->height(); - if (band->bandType()!=BandDesignIntf::PageFooter){ - band->setPos(m_renderPageItem->pageRect().x()+band->width()*m_currentColumn,m_currentStartDataPos[m_currentColumn]); - m_currentStartDataPos[m_currentColumn]+=band->height(); - band->setBandIndex(++m_currentIndex); - band->setColumnIndex(m_currentColumn); + + if (band->bandType()==BandDesignIntf::PageFooter){ + for (int i=0;iheight(); + } else { + m_maxHeightByColumn[m_currentColumn]-=band->height(); } - m_renderPageItem->registerBand(band); + if (band->isHeader() && band->columnsCount()>1){ + + qreal bandPos = m_currentStartDataPos[m_currentColumn]; + m_currentStartDataPos[m_currentColumn]+=band->height(); + for (int i=0;icolumnsCount();++i){ + if (i!=0) band = dynamic_cast(band->cloneItem(PreviewMode)); + band->setPos(m_renderPageItem->pageRect().x()+band->width()*i,bandPos); + band->setBandIndex(++m_currentIndex); + band->setColumnIndex(i); + m_renderPageItem->registerBand(band); + } + + } else { + + if (band->bandType()!=BandDesignIntf::PageFooter){ + band->setPos(m_renderPageItem->pageRect().x()+band->width()*m_currentColumn, + m_currentStartDataPos[m_currentColumn]); + m_currentStartDataPos[m_currentColumn]+=band->height(); + band->setBandIndex(++m_currentIndex); + band->setColumnIndex(m_currentColumn); + } + + if (band->columnsCount()>1){ + m_columnedBandItems.append(band); + } + + m_renderPageItem->registerBand(band); + } foreach(QList* list,m_childBands.values()){ if (registerInChildren && @@ -567,10 +711,12 @@ bool ReportRender::registerBand(BandDesignIntf *band, bool registerInChildren) band->bandType()!=BandDesignIntf::PageFooter && band->bandType()!=BandDesignIntf::ReportHeader && band->bandType()!=BandDesignIntf::ReportFooter && - !list->contains(band) + !list->contains(band) && + !band->reprintOnEachPage() ) list->append(band); } + if (band->isData()) m_renderedDataBandCount++; return true; } else return false; @@ -635,7 +781,9 @@ BandDesignIntf *ReportRender::saveUppperPartReturnBottom(BandDesignIntf *band, i registerBand(upperBandPart); } else delete upperBandPart; - if (band->columnsCount()>1 && band->columnsFillDirection()==BandDesignIntf::Vertical){ + if (band->columnsCount()>1 && + (band->columnsFillDirection()==BandDesignIntf::Vertical || + band->columnsFillDirection()==BandDesignIntf::VerticalUniform)){ startNewColumn(); } else { savePage(); @@ -676,7 +824,6 @@ void ReportRender::startNewPage() m_renderPageItem->setObjectName(QLatin1String("ReportPage")+QString::number(m_pageCount)); m_maxHeightByColumn[m_currentColumn]=m_renderPageItem->pageRect().height(); - m_currentStartDataPos[m_currentColumn]=m_patternPageItem->topMargin()*Const::mmFACTOR; m_currentIndex=0; @@ -687,6 +834,11 @@ void ReportRender::startNewPage() m_dataAreaSize = m_maxHeightByColumn[m_currentColumn]; m_renderedDataBandCount = 0; + foreach (BandDesignIntf* band, m_reprintableBands) { + renderBand(band); + } + checkLostHeadersOnPrevPage(); + pasteGroups(); renderPageItems(m_patternPageItem); } @@ -759,6 +911,31 @@ void ReportRender::pasteGroups() m_popupedValues.clear(); } +void ReportRender::checkLostHeadersOnPrevPage() +{ + if (m_renderedPages.isEmpty()) return; + PageItemDesignIntf::Ptr page = m_renderedPages.last(); + if (page->bands().isEmpty()) return; + + QMutableListIteratorit(page->bands()); + + it.toBack(); + if (it.hasPrevious()) + if (it.previous()->isFooter()) + it.previous(); + + while (it.hasPrevious()){ + if (it.value()->isHeader()){ + if (it.value()->reprintOnEachPage()){ + delete it.value(); + } else { registerBand(it.value());} + it.remove(); + it.previous(); + } else break; + } + +} + BandDesignIntf* ReportRender::findEnclosingGroup() { BandDesignIntf* result=0; @@ -780,6 +957,8 @@ void ReportRender::savePage() { checkFooterGroup(m_lastDataBand); cutGroups(); + rearrangeColumnsItems(); + m_columnedBandItems.clear(); renderPageFooter(m_patternPageItem); if (m_ranges.last().lastPage==0 && m_ranges.count()>1) { diff --git a/src/lrreportrender.h b/src/lrreportrender.h index 136b8ec..1efafed 100644 --- a/src/lrreportrender.h +++ b/src/lrreportrender.h @@ -117,6 +117,7 @@ private: void cutGroups(); void checkFooterGroup(BandDesignIntf* groupBand); void pasteGroups(); + void checkLostHeadersOnPrevPage(); BandDesignIntf* findEnclosingGroup(); bool registerBand(BandDesignIntf* band, bool registerInChildren=true); @@ -133,14 +134,20 @@ private: private: void initColumns(); + bool isNeedToRearrangeColumnsItems(); + BandDesignIntf* lastColumnItem(int columnIndex); + void rearrangeColumnsItems(); + int columnItemsCount(int columnIndex); + qreal columnHeigth(int columnIndex); + qreal maxColumnHeight(); private: DataSourceManager* m_datasources; - PageItemDesignIntf* m_renderPageItem; PageItemDesignIntf* m_patternPageItem; QList m_renderedPages; - QMultiMap< BandDesignIntf*, GroupBandsHolder* > m_childBands; + QList m_reprintableBands; +// QList m_lastRenderedHeaders; //int m_maxHeightByColumn[0]; //int m_currentStartDataPos; @@ -160,6 +167,7 @@ private: QVector m_currentStartDataPos; int m_currentColumn; QList m_ranges; + QVector m_columnedBandItems; }; } // namespace LimeReport #endif // LRREPORTRENDER_H diff --git a/src/lrscriptenginemanager.cpp b/src/lrscriptenginemanager.cpp index e2f3c44..dbd701d 100644 --- a/src/lrscriptenginemanager.cpp +++ b/src/lrscriptenginemanager.cpp @@ -36,6 +36,7 @@ Q_DECLARE_METATYPE(QColor) Q_DECLARE_METATYPE(QFont) +Q_DECLARE_METATYPE(LimeReport::ScriptEngineManager *) QScriptValue constructColor(QScriptContext *context, QScriptEngine *engine) { @@ -217,7 +218,25 @@ QScriptValue dateFormat(QScriptContext* pcontext, QScriptEngine* pengine){ return res; } +QScriptValue timeFormat(QScriptContext* pcontext, QScriptEngine* pengine){ + QVariant value = pcontext->argument(0).toVariant(); + QString format = (pcontext->argumentCount()>1)?pcontext->argument(1).toString().toLatin1():"hh:mm"; + QScriptValue res = pengine->newVariant(QLocale().toString(value.toTime(),format)); + return res; +} + +QScriptValue dateTimeFormat(QScriptContext* pcontext, QScriptEngine* pengine){ + QVariant value = pcontext->argument(0).toVariant(); + QString format = (pcontext->argumentCount()>1)?pcontext->argument(1).toString().toLatin1():"dd.MM.yyyy hh:mm"; + QScriptValue res = pengine->newVariant(QLocale().toString(value.toDateTime(),format)); + return res; +} + QScriptValue now(QScriptContext* /*pcontext*/, QScriptEngine* pengine){ + return pengine->newVariant(QDateTime::currentDateTime()); +} + +QScriptValue date(QScriptContext* /*pcontext*/, QScriptEngine* pengine){ return pengine->newVariant(QDate::currentDate()); } @@ -348,8 +367,11 @@ ScriptEngineManager::ScriptEngineManager() //addFunction("dateToStr",dateToStr,"DATE", "dateToStr(\"value\",\"format\")"); addFunction("line",line,"SYSTEM", "line(\""+tr("BandName")+"\")"); addFunction("numberFormat",numberFormat,"NUMBER", "numberFormat(\""+tr("Value")+"\",\""+tr("Format")+"\",\""+tr("Precision")+"\")"); - addFunction("dateFormat",dateFormat,"DATE", "dateFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")"); - addFunction("now",now,"DATE","now()"); + addFunction("dateFormat",dateFormat,"DATE&TIME", "dateFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")"); + addFunction("timeFormat",timeFormat,"DATE&TIME", "dateFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")"); + addFunction("dateTimeFormat", dateTimeFormat, "DATE&TIME", "dateTimeFormat(\""+tr("Value")+"\",\""+tr("Format")+"\")"); + addFunction("date",date,"DATE&TIME","date()"); + addFunction("now",now,"DATE&TIME","now()"); QScriptValue colorCtor = m_scriptEngine->newFunction(constructColor); m_scriptEngine->globalObject().setProperty("QColor", colorCtor); diff --git a/src/objectinspector/editors/lrcomboboxeditor.h b/src/objectinspector/editors/lrcomboboxeditor.h index ac69c24..d534fe8 100644 --- a/src/objectinspector/editors/lrcomboboxeditor.h +++ b/src/objectinspector/editors/lrcomboboxeditor.h @@ -53,7 +53,7 @@ class ComboBoxEditor : public QWidget Q_OBJECT public: //explicit ComboBoxEditor(QWidget *parent = 0); - ComboBoxEditor(QWidget *parent=0, bool clearable=true); + ComboBoxEditor(QWidget *parent=0, bool clearable=false); void addItems(const QStringList& values); void setTextValue(const QString& value); QString text(); diff --git a/src/objectinspector/lrobjectitemmodel.cpp b/src/objectinspector/lrobjectitemmodel.cpp index 632a7c5..af642ea 100644 --- a/src/objectinspector/lrobjectitemmodel.cpp +++ b/src/objectinspector/lrobjectitemmodel.cpp @@ -51,6 +51,38 @@ void QObjectPropertyModel::translatePropertyName() tr("BottomLine"); tr("LeftLine"); tr("RightLine"); + tr("reprintOnEachPage"); + tr("borderLineSize"); + tr("autoHeight"); + tr("backgroundColor"); + tr("columnCount"); + tr("columnsFillDirection"); + tr("datasource"); + tr("keepBottomSpace"); + tr("keepFooterTogether"); + tr("keepSubdetailTogether"); + tr("printIfEmpty"); + tr("sliceLastRow"); + tr("splittable"); + tr("alignment"); + tr("angle"); + tr("autoWidth"); + tr("backgroundMode"); + tr("backgroundOpacity"); + tr("content"); + tr("font"); + tr("fontColor"); + tr("foregroundOpacity"); + tr("itemLocation"); + tr("margin"); + tr("stretchToMaxHeight"); + tr("trimValue"); + tr("lineWidth"); + tr("opacity"); + tr("penStyle"); + tr("shape"); + tr("shapeBrush"); + tr("shapeBrushColor"); } QObjectPropertyModel::QObjectPropertyModel(QObject *parent/*=0*/) @@ -93,13 +125,17 @@ void QObjectPropertyModel::setMultiObjects(QList* list) { m_objects.clear(); submit(); - if (m_object!=list->at(0)){ + + if (!list->contains(m_object)){ m_object=list->at(0); list->removeAt(0); + } else { + list->removeOne(m_object); } + foreach(QObject* item, *list) m_objects.append(item); - initModel(); + //initModel(); } void QObjectPropertyModel::slotObjectDestroyed(QObject *obj) diff --git a/src/objectinspector/propertyItems/lrdatasourcepropitem.cpp b/src/objectinspector/propertyItems/lrdatasourcepropitem.cpp index e107edb..affcd9e 100644 --- a/src/objectinspector/propertyItems/lrdatasourcepropitem.cpp +++ b/src/objectinspector/propertyItems/lrdatasourcepropitem.cpp @@ -57,7 +57,7 @@ namespace{ } QWidget* LimeReport::DatasourcePropItem::createProperyEditor(QWidget *parent) const{ - ComboBoxEditor *editor = new ComboBoxEditor(parent); + ComboBoxEditor *editor = new ComboBoxEditor(parent,true); editor->setEditable(true); LimeReport::BaseDesignIntf *item=dynamic_cast(object()); if (item){ diff --git a/src/objectinspector/propertyItems/lrenumpropitem.cpp b/src/objectinspector/propertyItems/lrenumpropitem.cpp index 218912a..c90326f 100644 --- a/src/objectinspector/propertyItems/lrenumpropitem.cpp +++ b/src/objectinspector/propertyItems/lrenumpropitem.cpp @@ -69,8 +69,8 @@ void EnumPropItem::slotEnumChanged(const QString &text) { if ( nameByType(object()->property(propertyName().toLatin1()).toInt())!=text){ beginChangeValue(); - setValueToObject(propertyName(),typeByName(text)); setPropertyValue(typeByName(text)); + setValueToObject(propertyName(),typeByName(text)); endChangeValue(); } } diff --git a/src/objectinspector/propertyItems/lrflagspropitem.cpp b/src/objectinspector/propertyItems/lrflagspropitem.cpp index 5d25116..836457a 100644 --- a/src/objectinspector/propertyItems/lrflagspropitem.cpp +++ b/src/objectinspector/propertyItems/lrflagspropitem.cpp @@ -132,7 +132,7 @@ void FlagPropItem::setModelData(QWidget *propertyEditor, QAbstractItemModel *mod int flags = object()->property(parent()->propertyName().toLatin1()).toInt(); if (value) flags=flags | valueByName(displayName()); else if (flags&valueByName(displayName())) flags=flags ^ valueByName(displayName()); - setValueToObject(propertyName(),propertyValue()); + setValueToObject(parent()->propertyName(),flags); parent()->setPropertyValue(flags); } diff --git a/src/objectinspector/propertyItems/lrgroupfieldpropitem.cpp b/src/objectinspector/propertyItems/lrgroupfieldpropitem.cpp index b7027c5..e77614d 100644 --- a/src/objectinspector/propertyItems/lrgroupfieldpropitem.cpp +++ b/src/objectinspector/propertyItems/lrgroupfieldpropitem.cpp @@ -44,7 +44,7 @@ namespace LimeReport { QWidget *GroupFieldPropItem::createProperyEditor(QWidget *parent) const { - ComboBoxEditor *editor = new ComboBoxEditor(parent); + ComboBoxEditor *editor = new ComboBoxEditor(parent,true); editor->setEditable(true); GroupBandHeader *item=dynamic_cast(object()); if (item){ diff --git a/src/objectsbrowser/lrobjectbrowser.cpp b/src/objectsbrowser/lrobjectbrowser.cpp index 75570f8..4ae7d2e 100644 --- a/src/objectsbrowser/lrobjectbrowser.cpp +++ b/src/objectsbrowser/lrobjectbrowser.cpp @@ -112,7 +112,8 @@ void ObjectBrowser::buildTree(BaseDesignIntf* ignoredItem){ m_itemsMap.insert(m_report->activePage(),topLevelItem); m_treeView->addTopLevelItem(topLevelItem); - foreach (QGraphicsItem* item, m_report->activePage()->items()) { + QList itemsList = m_report->activePage()->items(); + foreach (QGraphicsItem* item, itemsList) { if (item != ignoredItem){ BaseDesignIntf* reportItem = dynamic_cast(item); if (reportItem && reportItem->parentItem()==0){ @@ -186,9 +187,9 @@ void ObjectBrowser::slotBandDeleted(PageDesignIntf *, BandDesignIntf * item) buildTree(item); } -void ObjectBrowser::slotItemAdded(PageDesignIntf *, BaseDesignIntf *) +void ObjectBrowser::slotItemAdded(PageDesignIntf *page, BaseDesignIntf *) { - buildTree(); + if (!page->isUpdating()) buildTree(); } void ObjectBrowser::slotItemDeleted(PageDesignIntf *, BaseDesignIntf *item) @@ -237,18 +238,22 @@ void ObjectBrowser::slotItemSelected(LimeReport::BaseDesignIntf *item) void ObjectBrowser::slotMultiItemSelected() { - m_changingItemSelection = true; + if (!m_changingItemSelection){ + m_changingItemSelection = true; - m_treeView->selectionModel()->clear(); + m_treeView->selectionModel()->clear(); - foreach(QGraphicsItem* item, m_report->activePage()->selectedItems()){ - BaseDesignIntf* bg = dynamic_cast(item); - if (bg){ - m_itemsMap.value(bg)->setSelected(true); + foreach(QGraphicsItem* item, m_report->activePage()->selectedItems()){ + BaseDesignIntf* bg = dynamic_cast(item); + if (bg){ + ObjectBrowserNode* node = m_itemsMap.value(bg); + if (node) + node->setSelected(true); + } } - } - m_changingItemSelection = false; + m_changingItemSelection = false; + } } void ObjectBrowser::slotItemDoubleClicked(QTreeWidgetItem *item, int) diff --git a/src/objectsbrowser/lrobjectbrowser.h b/src/objectsbrowser/lrobjectbrowser.h index a0483c3..b39ac1f 100644 --- a/src/objectsbrowser/lrobjectbrowser.h +++ b/src/objectsbrowser/lrobjectbrowser.h @@ -68,7 +68,7 @@ private slots: void slotActivePageChanged(); void slotBandAdded(LimeReport::PageDesignIntf*, LimeReport::BandDesignIntf*); void slotBandDeleted(LimeReport::PageDesignIntf*, LimeReport::BandDesignIntf*item); - void slotItemAdded(LimeReport::PageDesignIntf*, LimeReport::BaseDesignIntf*); + void slotItemAdded(LimeReport::PageDesignIntf*page, LimeReport::BaseDesignIntf*); void slotItemDeleted(LimeReport::PageDesignIntf*, LimeReport::BaseDesignIntf*item); void slotObjectTreeItemSelectionChanged(); void slotItemSelected(LimeReport::BaseDesignIntf* item); diff --git a/src/serializators/lrstorageintf.h b/src/serializators/lrstorageintf.h index c53982c..85fb7ad 100644 --- a/src/serializators/lrstorageintf.h +++ b/src/serializators/lrstorageintf.h @@ -50,6 +50,7 @@ public: virtual void putItem(QObject* item)=0; virtual bool saveToFile(QString fileName) = 0; virtual QString saveToString() = 0; + virtual QByteArray saveToByteArray() = 0; virtual ~ItemsWriterIntf(){} }; diff --git a/src/serializators/lrxmlwriter.cpp b/src/serializators/lrxmlwriter.cpp index 84beaee..016945c 100644 --- a/src/serializators/lrxmlwriter.cpp +++ b/src/serializators/lrxmlwriter.cpp @@ -98,6 +98,14 @@ QString XMLWriter::saveToString() return res; } +QByteArray XMLWriter::saveToByteArray() +{ + QByteArray res; + QTextStream buffer(&res); + m_doc->save(buffer,2); + return res; +} + QDomElement XMLWriter::putQObjectItem(QString name, QObject *item) { Q_UNUSED(name) diff --git a/src/serializators/lrxmlwriter.h b/src/serializators/lrxmlwriter.h index 9a814d6..dc0deaa 100644 --- a/src/serializators/lrxmlwriter.h +++ b/src/serializators/lrxmlwriter.h @@ -44,9 +44,11 @@ public: XMLWriter(QSharedPointer doc); ~XMLWriter() {} private: - virtual void putItem(QObject* item); - virtual bool saveToFile(QString fileName); - virtual QString saveToString(); + void putItem(QObject* item); + bool saveToFile(QString fileName); + QString saveToString(); + QByteArray saveToByteArray(); + QDomElement putQObjectItem(QString name, QObject* item); void putChildQObjectItem(QString name, QObject* item, QDomElement* parentNode); void putCollectionItem(QObject* item, QDomElement* parentNode=0); diff --git a/translations/limereport_ru.qm b/translations/limereport_ru.qm index 4908bc1dd5eed34eed660d791fbf8717262ac40d..8ac1f574394ce98033c48eaa78623ae10de7fe23 100644 GIT binary patch delta 3225 zcmaKu3shBA8ppryo_#L&aW0pqD4JdbK@&lFD-S^~Dn5$Ttke{gOJE8HXf_&GD;ZxQ z6DB#b3>-B_9j!5Aq;&GZLdOhC#ig@G9YHfS6ha9NnE$<}tf^J7&ib8w_TJzA-us@e zkgKcYQZIWckvyH~tCddjs7oqGzewZ~PaM}pG|ZK#@uJEb8BTJ1l1l3)qH)KFJvI|f zC?g(iBzkrRaq?24>FGpwClW1~0y*nQY<~soCX?7vMbz5gNw#}5sV~F6P?-`z;$uPV zRY~IX0AlZxBpM)~hk;~KPuz0`$%D@l-Pum^*hr$=n@L`?m$>&kB!6ndxRK;z824X7 z@`)ovH!LLA*Aa(il6FG?(Sws96dZAow6zDx&atP+rAj7xxSGanSWoOeA3R2MHO)zO zKS-%BK2OxVhf?nb5D$x`aZzt${$rZ3aW*_RNoCs?PO^WV%7C*flL{y;`W#W0H$Ckz zBJkObnSx&vv%KvhQfd>-&km@oGzm_?tjM(l&`(3yzSL@iV4##7g!U^!De;@@7uhDEoD zeHOCU?%Rm*`y63>o#M3bnz+~dcz0%@`EeK_+RNRG} z>OL=R5s=^WJ?VS|40>#-MQZZ!$IAt&Yswv>wpXO?*-&WYG~w-`ke!ebgH9 zPUD!$jiv))c}kMSzQH;BqBt;C+iqUx@L*Tq(!zZ2`S zRQi^vj0zRoZaenRb&`ARQW<_(?3}UOQ6yes=Ltu74->nlBPE)rie2jnp1v#&C{W<5 zUZQ3$S^$wa=;AowkV@ZXl~IeuAp_b-Q-_nB5GoqV-XIQ)7uRuNP!%4 zA1P#hMjjJXW+&>nE>D|-&_x}U(@{+vt(CJbSW(U^@H|13$1d8RX zymrxgBzde{T7%+niIoqmL=k*_SpGES9?g1j$ZkzrV`R|7!Esqu64uYyVJ=^_EXn4u45ox=cdf^3?9K zm-@iM7qz=PCtyLk%Aj5$QWaX9*zPJ0V&gv}qQbPLmV2d^Lwe&2=L zn$ZT{a5230E!K^9SzC`>4enN%tZ})x!$$17MW-1Xf$DD3xjs{Zag5HMYTZvfV2f^D z(KWbuf^J<24oD2rRi;N0$F9d)y-W0CVCx9KfVkTos(k=sLvO>6D?#09RSlN zRN0YWh(G=+8miThGI{{!KQm-hrw|X$GR$%EBZDpSX?V!4HQ080p-tQe;hGWuG3>nR z2TR#ddjl@LovyNVx|1BAWjHZKhKuVACqMIp=RAy}8y<>3XY|e1!LnjwO!5NkUum=r z^(HnhGiK>p5kh}sR?R(PeZ6t{Ie0j1jj{5?C1QKv>&Ex{L4c{zcwsPNWO!U*zY4@i zujrn`U1(e_TIJoeb12sktxysP+YTz>iHJ;RZ_{o2iS8&;qZ%`!LoAHZd~ z%zSN1A#!S24%+KOsT+SfMEGVPdEV6ER|xm_Qa0 zk1t{6Rk0jU*43@Idn9FMT5@eKTQV~WGYaw+=FhRYK$Ovn;i&w)mkVt9Ea5}gZ;2Ag z;t7ZyDI!H8o;W=5_{Y~Dbt1PP&sda^pOZ0r-p@|x@v|d_ik>1`6;QV3L7+oDANS3Wt7b&JXe4ce6EMi2Fd%7i*n) z;gk?r?ia;A-s2x_FigzI$+b+$%bQnFzPt|)tai1qEc^_@-Fa$+_-Uy!$+jRbztA!} zBR5lBT%H-hk=0`ZxXGhBH=1us)f-~DQ&W95foE#U3zGQxKrbAh023S;6a{4+X8okD j%bdL2LR)TO^*@ui&FHZb$!K!t&Oyd*FOBF7HhBIIZW@O( delta 2671 zcmX|@30PFu701t+ci)@sy%`h;iU~_V5y1(DVMk$vC?K`i5;blSbPOskQ8d^lj9Z8c z0V)`(r3x-ckZRTVOCXL1oW!~{ui-~p(8-3K1CjKpe*G9{<9m#e^&^o%O+LMBE`oXsbruKGF=mx-ybw>f7`PqqH5n#@BrpWZj^vQ(u z9&#is0v7qy6X!za<}WE_li{oGazIJ@8#lqGvqJ#->L6FWmm=X0TQ0@|^anygnk55} z6~UhQy8ykf!Oxp0=ibxchOrKyWeGG*Y6KjiK?(O@N~^6!F_?0EZeBznfK08~Z4d z{z9SeZdI&Uy9RJrtzygK#T1DK#i5hYfMfoxXw#*VC@(19R991~S~!QFg8)ryIq!5U zV5G=d0zbJ)VzF?6Uz1vU7jnU_56RFcT=?Y%fSyb)&eBGqo6pVOHVfd@J}$+vfgH%; z=A;z?Mt#Gjd;bye!|hyVcROiA%VqbGW_sGVU5xBHpW*Hp=>V<)Twii4K>HT1Kb0Ja z%xBKJ6u{Aa1^?jOEKz6KU*k^#G??wg@H;Y1U95N-X}Ea=EACNH01bAc<6M~mF|6d_ zOF)O6thCL>ezwQuFd%P{=`vPkpex(kY+Jw1PIRo28IZ#&W~{N*Kmx0%u~qM9Z2xr1 z{PQJje;xq(B(P&5Iq+mKJHB8C(1)E;+BUc&(`A>;z&Y%+hPp(<8#^(=%x)K~2YkPr zHI|d)q)Regzm+-SJ|Fs;lp-$W$NLmm0ABa=)8w(M=h45(-W!(K+nf{5wvO=n*;DN%Qifr@!WCs6T$Y0G- z5oQVd^Ihm*lZ8r4Zz6ekS*WzpYrV|iWZ_@glmh>H;Zk%MwIxsCIdugTf08Lp5c>VU zrfxAri5)G}=hiDVYhTg4xyqbclBVwhnbD!jd*x<8?Fp44&Pc`EtI|!$rT0my_}HVA zB1vV*%X& zsNSkNm2-(Y{wh^hOAIyONSUt>tKJ+aq@r$7OL3(2$Y0eSIv#ay+jKO*s7)6B7PxTnS(^fB>sjk(f^QtYp(c;rb3LQQoOMeeC(mHg0} zVJC(cYig2hH^D>A|)t1!Ur;xX3|LIQlG(Fn8ev}%EGDdzFbzMZyV#?9` zqU!gLs2w$m;y9k#Ot>hi&Xec8q9aEe3|=hL!(FCvl{o0rEHW4+4sNHrvE_{Dj499NMjP#QiFo0f#H_b04+IRFs4qEjmQ?>-zd!pa^$&ObfiM#ByQ%tmuVZu?>{x^n4%2GJF3HGPvM6!>Vzc#^ zaO~!aQY7>)>TyKLdSMJ|xT2d*XtbU;;X*}`!5NK3p0T*VdM+00wM8Wpky#APosD6^ zEPzF@7-nK)SpayjC>k@`$BitM#)7~D47NX#GJrr|eNwtPWx3hoi - - - - - - - - + + + + + + + + ... - + + Add new datasource + Добавить новый источник данных + + + + View data + Просмотр данных в источнике + + + + Change datasource + Изменить источник данных + + + + Delete datasource + Удалить источник данных + + + + Show error + Показать ошибки + + + Variables Переменные + + + Add new variable + Добавить новую переменную + + + + Edit variable + Редактировать переменную + + + + Delete variable + Удалить переменную + LRVariableDialog @@ -494,32 +534,32 @@ p, li { white-space: pre-wrap; } LimeReport::DataSourceManager - + Connection "%1" is not open Соединение "%1" не открыто - - + + Datasource "%1" not found ! Источник данных "%1" не найден ! - + connection with name "%1" already exists ! соединение "%1" уже существует ! - - - - + + + + datasource with name "%1" already exists ! data source with name "%1" already exists !! источник данных "%1" уже существует ! - + invalid connection нет соединения @@ -743,12 +783,12 @@ p, li { white-space: pre-wrap; } LimeReport::PageDesignIntf - + Warning Предупреждение - + Multi band deletion not allowed Удаление нескольких бандов запрещено @@ -780,12 +820,12 @@ p, li { white-space: pre-wrap; } LimeReport::QObjectPropertyModel - + Property Name Свойство - + Property value Значение @@ -860,7 +900,7 @@ p, li { white-space: pre-wrap; } Правая граница - + Warning Предупреждение @@ -898,7 +938,7 @@ p, li { white-space: pre-wrap; } LimeReport::ReportDesignWidget - + Report file name Файл отчета @@ -1010,6 +1050,11 @@ p, li { white-space: pre-wrap; } Report Tools Элементы отчета + + + Main Tools + Основные инструменты + Font @@ -1031,118 +1076,123 @@ p, li { white-space: pre-wrap; } Границы - + + Report bands + Банды + + + Report Header Заголовок отчета - + Report Footer Завершение отчета - + Page Header Верхний колонтитул - + Page Footer Нижний колонтитул - + Data Данные - + Data Header Заголовок данных - + Data Footer Завершение данных - + SubDetail Подчиненные данные - + SubDetailHeader Заголовок подчиненных данных - + SubDetailFooter Завершение подчиненных данных - + GroupHeader Заголовок группы - + GroupFooter Завершение группы - + File Файл - + Edit Правка - + Info Информация - + Object Inspector Инспектор объектов - + Report structure Структура отчета - + Data Browser Инспектор данных - + Report has been modified ! Do you want save the report ? Отчет был изменен ! Хотите его записать ? - - + + Report file name Файл отчета - + Rendering report Создается отчет - + Abort О генераторе - + page rendered создается страница @@ -1192,30 +1242,34 @@ p, li { white-space: pre-wrap; } LimeReport::ScriptEngineManager - + FieldName Имя поля - - + + BandName Имя банда - - + + + + Value Значение - - + + + + Format Формат - + Precision Точность @@ -1514,22 +1568,22 @@ p, li { white-space: pre-wrap; } источник данных "%1" не найден ! - + Attention! Внимание! - + Selected elements have different parent containers Выделенные элементы имеют различные родительские контейнеры - + Object with name %1 already exists Объект с именем %1 уже существует - + Function %1 not found or have wrong arguments Функция %1 не найдена или вызвана с неверными аргументами @@ -1627,24 +1681,25 @@ p, li { white-space: pre-wrap; } - TopLine - Верхняя граница + Верхняя граница - BottomLine - Нижняя граница + Нижняя граница - LeftLine - Левая граница + Левая граница - RightLine - Правая граница + Правая граница + + + + content + содержимое @@ -1829,14 +1884,12 @@ p, li { white-space: pre-wrap; } WaitForm - Wait - Ожидайте + Ожидайте - Please wait ... - Пожалуста подождите ... + Пожалуста подождите ...