0
0
mirror of https://github.com/fralx/LimeReport.git synced 2024-12-24 00:33:02 +03:00
This commit is contained in:
Sergey Popovichev 2016-02-17 10:39:17 +03:00
parent 20fe567ab2
commit 9a792e453c
53 changed files with 1525 additions and 428 deletions

View File

@ -1,10 +1,10 @@
# 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
```cpp
#include "lrreportengine.h" to add report engine
#include "lrcallbackdatasourceintf.h" if you want use callback datasources
@ -16,3 +16,47 @@
```
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.

View File

@ -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;
};
}

View File

@ -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;

View File

@ -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:

View File

@ -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

View File

@ -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;}

View File

@ -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;

View File

@ -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;
};

View File

@ -166,6 +166,9 @@
</item>
<item>
<widget class="QToolButton" name="addDataSource">
<property name="toolTip">
<string>Add new datasource</string>
</property>
<property name="text">
<string>...</string>
</property>
@ -189,6 +192,9 @@
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>View data</string>
</property>
<property name="text">
<string>...</string>
</property>
@ -212,6 +218,9 @@
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Change datasource</string>
</property>
<property name="text">
<string>...</string>
</property>
@ -235,6 +244,9 @@
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Delete datasource</string>
</property>
<property name="text">
<string>...</string>
</property>
@ -258,6 +270,9 @@
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Show error</string>
</property>
<property name="text">
<string>...</string>
</property>
@ -338,6 +353,9 @@
</property>
<item>
<widget class="QToolButton" name="addVariable">
<property name="toolTip">
<string>Add new variable</string>
</property>
<property name="text">
<string>...</string>
</property>
@ -364,6 +382,9 @@
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Edit variable</string>
</property>
<property name="text">
<string>...</string>
</property>
@ -387,6 +408,9 @@
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Delete variable</string>
</property>
<property name="text">
<string>...</string>
</property>

View File

@ -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;
}

View File

@ -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:
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;

View File

@ -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;
};
}

View File

@ -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);
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);
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);
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;
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;
}
for(QTextBlock it=m_text->begin();it!=m_text->end();it=it.next()){
for (int i=0;i<it.layout()->lineCount();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;i<it.layout()->lineCount();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;
if (allowHTML())
m_text->setHtml(replaceReturns(value.trimmed()));
m_text->setTextWidth(width());
m_textSize=m_text->size();
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;i<it.layout()->lineCount();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<HtmlContext> 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;curLine<curBlock.layout()->lineCount();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<HtmlContext> 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,8 +452,10 @@ BaseDesignIntf *TextItem::cloneEmpty(int height, QObject *owner, QGraphicsItem *
void TextItem::objectLoadFinished()
{
ItemDesignIntf::objectLoadFinished();
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);
}
}

View File

@ -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;
};
}

View File

@ -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<BandDesignIntf::BandsType> 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<BandDesignIntf*>(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()<findMaxBottom()) setHeight(findMaxBottom()+spaceBorder);
if (autoHeight()){
//if keepBottomSpace()&& height()<findMaxBottom()
setHeight(findMaxBottom()+spaceBorder);
}
if ((maxHeight>0)&&(height()>maxHeight)){
trimToMaxHeight(maxHeight);
setHeight(maxHeight);

View File

@ -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<BandDesignIntf*> childBands() const{return m_childBands;}
QList<BandDesignIntf*> 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<BandsType> groupBands();
QSet<BandsType> 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{

View File

@ -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());
QVector<QRectF *>oldResizeAreas(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;
}
}
}
}
@ -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<BandDesignIntf*>(item);
// if (band){
// break;
// }
// pageItem = dynamic_cast<PageItemDesignIntf*>(item);
// }
// if (band)
// qDebug()<<"band found"<<band->objectName();
// if (pageItem)
// qDebug()<<"page found"<<pageItem->objectName();
// }
int hStep = dynamic_cast<PageDesignIntf*>(scene())->horizontalGridStep();
int vStep = dynamic_cast<PageDesignIntf*>(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<QString>& 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<BaseDesignIntf*>(parentItem());
if(baseItem) baseItem->hoverMoveEvent(event);
}
void SelectionMarker::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
parentItem()->setSelected(true);
BaseDesignIntf* baseItem = dynamic_cast<BaseDesignIntf*>(parentItem());
if(baseItem) baseItem->mousePressEvent(event);
QGraphicsItem::mousePressEvent(event);
}
void SelectionMarker::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
BaseDesignIntf* baseItem = dynamic_cast<BaseDesignIntf*>(parentItem());
if(baseItem) baseItem->mouseReleaseEvent(event);
}
void SelectionMarker::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
{
BaseDesignIntf* baseItem = dynamic_cast<BaseDesignIntf*>(parentItem());
if(baseItem) baseItem->mouseDoubleClickEvent(event);
QGraphicsItem::mouseDoubleClickEvent(event);
}
void SelectionMarker::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
BaseDesignIntf* baseItem = dynamic_cast<BaseDesignIntf*>(parentItem());
if(baseItem) baseItem->mouseMoveEvent(event);
}

View File

@ -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;

View File

@ -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()
{
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)

View File

@ -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;

View File

@ -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);
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<QueryHolder*>(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<QString> DataSourceManager::childDatasources(const QString &parentDatasourceName)
{
QList<QString> result;
foreach(QString datasourceName, dataSourceNames()){
if (isSubQuery(datasourceName)){
SubQueryHolder* sh = dynamic_cast<SubQueryHolder*>(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<SubQueryHolder*>(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);
}
}

View File

@ -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<FieldsCorrelation> 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<QString> childDatasources(const QString& datasourceName);
void invalidateChildren(const QString& parentDatasourceName);
//ICollectionContainer
virtual QObject* createElement(const QString& collectionName,const QString&);
virtual int elementsCount(const QString& collectionName);

View File

@ -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;
};
}

View File

@ -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;

View File

@ -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("<","&lt;");
result.replace(">","&gt;");
return result;
}
Spacer::Spacer(QObject *owner, QGraphicsItem *parent)

View File

@ -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{

View File

@ -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<ReportEnginePrivate *>(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<ItemDesignIntf*>(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<QGraphicsItem*> 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<QGraphicsItem*>& itemsList) const
{
QObject *item = 0;
for (int i = 0; i < items().count(); i++) {
item = dynamic_cast<QObject *>(items()[i]);
//QList<QGraphicsItem*> itemList = items();
for (int i = 0; i < itemsList.count(); i++) {
item = dynamic_cast<QObject *>(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<TextItem*>(item);
QString data = event->mimeData()->text().remove(0,event->mimeData()->text().indexOf(":")+1);
if (isVar) data = data.remove(QRegExp(" \\[.*\\]"));
ti->setContent(data);
}
}
@ -779,22 +806,31 @@ 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<BaseDesignIntf *>(selectedItems()[0]);
if (reportItem && (m_geometryStamp[0].size != reportItem->size())) {
createChangeSizeCommand();
sizeCommand = createChangeSizeCommand();
}
m_geometryStamp.clear();
}
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;
@ -803,7 +839,7 @@ void PageDesignIntf::checkSizeOrPosChanges()
}
void PageDesignIntf::createChangePosCommand()
CommandIf::Ptr PageDesignIntf::createChangePosCommand()
{
QVector<ReportItemPos> 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<ReportItemSize> 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<BaseDesignIntf *>(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,6 +1130,7 @@ void PageDesignIntf::deleteSelected(bool createCommand)
}
foreach(QGraphicsItem* item, selectedItems()){
if (!dynamic_cast<PageItemDesignIntf*>(item))
removeReportItem(dynamic_cast<BaseDesignIntf*>(item),createCommand);
}
}
@ -1223,10 +1319,22 @@ void PageDesignIntf::sameHeight()
void PageDesignIntf::addHLayout()
{
if (selectedItems().size()==0) return;
if (selectedItems().isEmpty()) return;
QList<QGraphicsItem *> si = selectedItems();
QList<QGraphicsItem *>::iterator it = si.begin();
int itemsCount = 0;
for (; it != si.end();) {
if (dynamic_cast<ItemDesignIntf *>(*it)){
itemsCount++;
break;
}
++it;
};
if (itemsCount == 0) return;
for (; it != si.end();) {
if (!dynamic_cast<ItemDesignIntf *>(*it)) {
(*it)->setSelected(false);
@ -1235,6 +1343,7 @@ void PageDesignIntf::addHLayout()
else ++it;
}
if (!si.isEmpty()){
it = si.begin();
QGraphicsItem* elementsParent = (*it)->parentItem();
for (; it != si.end();++it) {
@ -1243,11 +1352,13 @@ void PageDesignIntf::addHLayout()
return;
}
}
CommandIf::Ptr cm = InsertHLayoutCommand::create(this);
saveCommand(cm,true);
}
}
bool hLayoutLessThen(QGraphicsItem *c1, QGraphicsItem *c2)
{
return c1->pos().x() < c2->pos().x();
@ -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();

View File

@ -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<QGraphicsItem *> &itemsList) const;
QRectF getRectByPageSize(PageSize pageSize);
bool isLoading();
@ -154,6 +166,8 @@ namespace LimeReport {
void objectLoadFinished();
HorizontalLayout* internalAddHLayout();
QPointF placePosOnGrid(QPointF point);
QSizeF placeSizeOnGrid(QSizeF size);
signals:
void geometryChanged(QRectF newGeometry);
void insertModeStarted();
@ -161,12 +175,14 @@ namespace LimeReport {
void itemInsertCanceled(const QString& ItemType);
void itemSelected(LimeReport::BaseDesignIntf *item);
void multiItemsSelected(QList<QObject*>* 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<QObject*> 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{

View File

@ -29,6 +29,8 @@
****************************************************************************/
#include "lrpageitemdesignintf.h"
#include "lrbanddesignintf.h"
#include "lrpagedesignintf.h"
#include <QGraphicsScene>
#include <QPrinter>
@ -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<BandDesignIntf::BandsType> groupFooterIgnoredBands;
groupFooterIgnoredBands << BandDesignIntf::DataFooter << BandDesignIntf::GroupHeader;
QSet<BandDesignIntf::BandsType> 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 (bandIndex<band->bandIndex()) 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<qreal> &posByColumns, qreal pos, int columnCount){
posByColumns.clear();
for(int i=0;i<columnCount;++i){
posByColumns.append(pos);
}
}
void PageItemDesignIntf::relocateBands()
{
if (isLoading()) return;
int bandSpace = (itemMode() & DesignMode)?4:0;
QVector<qreal> 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;
}
}
}
}
}
@ -505,6 +533,25 @@ void PageItemDesignIntf::paintGrid(QPainter *ppainter)
ppainter->restore();
}
QList<BandDesignIntf *>& 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));

View File

@ -99,7 +99,9 @@ public:
Orientation pageOrientation() const {return m_pageOrientaion;}
PageSize pageSize() const {return m_pageSize;}
void setPageSize(const PageSize &size);
QList<BandDesignIntf *>& 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<qreal>&posByColumns, qreal pos, int columnCount);
private:
int m_topMargin;
int m_bottomMargin;

View File

@ -37,6 +37,7 @@
#include <QPrintDialog>
#include <QFileDialog>
#include <QScrollBar>
#include <QDesktopWidget>
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()){

View File

@ -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)

View File

@ -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);

View File

@ -39,6 +39,7 @@
#include <QMenuBar>
#include <QCheckBox>
#include <QVBoxLayout>
#include <QDesktopWidget>
#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,7 +744,12 @@ void ReportDesignWindow::slotSaveReportAs()
void ReportDesignWindow::slotLoadReport()
{
if (checkNeedToSave()){
QString fileName = QFileDialog::getOpenFileName(this,tr("Report file name"),"","Report files(*.lrxml);; All files(*)");
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);
@ -741,8 +759,11 @@ void ReportDesignWindow::slotLoadReport()
m_propertyModel->setObject(0);
updateRedoUndo();
unsetCursor();
setWindowTitle(m_reportDesignWidget->report()->reportName() + " - Lime Report Designer");
}
}
}
}
void ReportDesignWindow::slotZoomIn()

View File

@ -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_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);

View File

@ -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:

View File

@ -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<QPrinter> m_printer;
bool m_printerSelected;
bool m_showProgressDialog;
QString m_reportsDir;
QString m_reportName;
};
}

View File

@ -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;i<m_maxHeightByColumn.size();++i){
qreal maxHeight = 0;
int maxHeightColumn = 0;
if (m_maxHeightByColumn[i]>maxHeight){
maxHeight = m_maxHeightByColumn[i];
maxHeightColumn = i;
}
if (maxHeightColumn>0 && columnItemsCount(maxHeightColumn)<avg &&
maxHeight> lastColumnItem(maxHeightColumn-1)->height()
){
return true;
}
}
return false;
}
BandDesignIntf *ReportRender::lastColumnItem(int columnIndex)
{
if (columnIndex<0) return 0;
for(int i=0;i<m_columnedBandItems.size();++i){
if (m_columnedBandItems[i]->columnIndex()>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;i<m_columnedBandItems[0]->columnsCount();++i){
if (columnItemsCount(i)<avg){
int getCount = avg * (m_columnedBandItems[0]->columnsCount()-i) - columnItemsCount(i);
for (int j=0;j<getCount;++j){
BandDesignIntf* band = lastColumnItem(i-1);
band->setPos(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;i<m_columnedBandItems.size();++i){
if (m_columnedBandItems[i]->columnIndex()==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;i<m_columnedBandItems[0]->columnsCount();++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;i<m_maxHeightByColumn.size();++i)
m_maxHeightByColumn[i]+=m_pageFooterHeight;
registerBand(bandClone);
datasources()->clearGroupFunctionValues(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<IGroupBand*>(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<IGroupBand*>(band);
if (groupBand)
if (groupBand){
groupBand->closeGroup();
if (band->reprintOnEachPage()) m_reprintableBands.removeOne(band);
}
closeGroup(band);
}
@ -524,6 +636,8 @@ qreal minVectorValue(QVector<qreal> vector){
bool ReportRender::registerBand(BandDesignIntf *band, bool registerInChildren)
{
if (band->columnsCount()==1 && m_maxHeightByColumn.size()>1){
if (band->bandType()!=BandDesignIntf::PageFooter){
rearrangeColumnsItems();
m_currentColumn = 0;
qreal minValue = minVectorValue(m_maxHeightByColumn);
m_maxHeightByColumn.clear();
@ -532,8 +646,10 @@ bool ReportRender::registerBand(BandDesignIntf *band, bool registerInChildren)
m_currentStartDataPos.clear();
m_currentStartDataPos.append(maxValue);
}
}
if ( (band->columnsCount()>1) && !band->isHeader()){
if (band->columnsCount()>1){
if (m_maxHeightByColumn.size()!=band->columnsCount()){
for(int i=1;i<band->columnsCount();++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]){
if (band->bandType()==BandDesignIntf::PageFooter){
for (int i=0;i<m_maxHeightByColumn.size();++i)
m_maxHeightByColumn[i]+=band->height();
} else {
m_maxHeightByColumn[m_currentColumn]-=band->height();
}
if (band->isHeader() && band->columnsCount()>1){
qreal bandPos = m_currentStartDataPos[m_currentColumn];
m_currentStartDataPos[m_currentColumn]+=band->height();
for (int i=0;i<band->columnsCount();++i){
if (i!=0) band = dynamic_cast<BandDesignIntf*>(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]);
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<BandDesignIntf*>* 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;
QMutableListIterator<BandDesignIntf*>it(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) {

View File

@ -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<PageItemDesignIntf::Ptr> m_renderedPages;
QMultiMap< BandDesignIntf*, GroupBandsHolder* > m_childBands;
QList<BandDesignIntf*> m_reprintableBands;
// QList<BandDesignIntf*> m_lastRenderedHeaders;
//int m_maxHeightByColumn[0];
//int m_currentStartDataPos;
@ -160,6 +167,7 @@ private:
QVector<qreal> m_currentStartDataPos;
int m_currentColumn;
QList<PagesRange> m_ranges;
QVector<BandDesignIntf*> m_columnedBandItems;
};
} // namespace LimeReport
#endif // LRREPORTRENDER_H

View File

@ -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);

View File

@ -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();

View File

@ -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<QObject *>* 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)

View File

@ -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<LimeReport::BaseDesignIntf*>(object());
if (item){

View File

@ -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();
}
}

View File

@ -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);
}

View File

@ -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<GroupBandHeader*>(object());
if (item){

View File

@ -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<QGraphicsItem*> itemsList = m_report->activePage()->items();
foreach (QGraphicsItem* item, itemsList) {
if (item != ignoredItem){
BaseDesignIntf* reportItem = dynamic_cast<BaseDesignIntf*>(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,6 +238,7 @@ void ObjectBrowser::slotItemSelected(LimeReport::BaseDesignIntf *item)
void ObjectBrowser::slotMultiItemSelected()
{
if (!m_changingItemSelection){
m_changingItemSelection = true;
m_treeView->selectionModel()->clear();
@ -244,12 +246,15 @@ void ObjectBrowser::slotMultiItemSelected()
foreach(QGraphicsItem* item, m_report->activePage()->selectedItems()){
BaseDesignIntf* bg = dynamic_cast<BaseDesignIntf*>(item);
if (bg){
m_itemsMap.value(bg)->setSelected(true);
ObjectBrowserNode* node = m_itemsMap.value(bg);
if (node)
node->setSelected(true);
}
}
m_changingItemSelection = false;
}
}
void ObjectBrowser::slotItemDoubleClicked(QTreeWidgetItem *item, int)
{

View File

@ -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);

View File

@ -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(){}
};

View File

@ -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)

View File

@ -44,9 +44,11 @@ public:
XMLWriter(QSharedPointer<QDomDocument> 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);

Binary file not shown.

View File

@ -287,22 +287,62 @@ p, li { white-space: pre-wrap; }
<location filename="src/databrowser/lrdatabrowser.ui" line="91"/>
<location filename="src/databrowser/lrdatabrowser.ui" line="114"/>
<location filename="src/databrowser/lrdatabrowser.ui" line="137"/>
<location filename="src/databrowser/lrdatabrowser.ui" line="170"/>
<location filename="src/databrowser/lrdatabrowser.ui" line="193"/>
<location filename="src/databrowser/lrdatabrowser.ui" line="216"/>
<location filename="src/databrowser/lrdatabrowser.ui" line="239"/>
<location filename="src/databrowser/lrdatabrowser.ui" line="262"/>
<location filename="src/databrowser/lrdatabrowser.ui" line="342"/>
<location filename="src/databrowser/lrdatabrowser.ui" line="368"/>
<location filename="src/databrowser/lrdatabrowser.ui" line="391"/>
<location filename="src/databrowser/lrdatabrowser.ui" line="173"/>
<location filename="src/databrowser/lrdatabrowser.ui" line="199"/>
<location filename="src/databrowser/lrdatabrowser.ui" line="225"/>
<location filename="src/databrowser/lrdatabrowser.ui" line="251"/>
<location filename="src/databrowser/lrdatabrowser.ui" line="277"/>
<location filename="src/databrowser/lrdatabrowser.ui" line="360"/>
<location filename="src/databrowser/lrdatabrowser.ui" line="389"/>
<location filename="src/databrowser/lrdatabrowser.ui" line="415"/>
<source>...</source>
<translation></translation>
</message>
<message>
<location filename="src/databrowser/lrdatabrowser.ui" line="319"/>
<location filename="src/databrowser/lrdatabrowser.ui" line="170"/>
<source>Add new datasource</source>
<translation>Добавить новый источник данных</translation>
</message>
<message>
<location filename="src/databrowser/lrdatabrowser.ui" line="196"/>
<source>View data</source>
<translation>Просмотр данных в источнике</translation>
</message>
<message>
<location filename="src/databrowser/lrdatabrowser.ui" line="222"/>
<source>Change datasource</source>
<translation>Изменить источник данных</translation>
</message>
<message>
<location filename="src/databrowser/lrdatabrowser.ui" line="248"/>
<source>Delete datasource</source>
<translation>Удалить источник данных</translation>
</message>
<message>
<location filename="src/databrowser/lrdatabrowser.ui" line="274"/>
<source>Show error</source>
<translation>Показать ошибки</translation>
</message>
<message>
<location filename="src/databrowser/lrdatabrowser.ui" line="334"/>
<source>Variables</source>
<translation>Переменные</translation>
</message>
<message>
<location filename="src/databrowser/lrdatabrowser.ui" line="357"/>
<source>Add new variable</source>
<translation>Добавить новую переменную</translation>
</message>
<message>
<location filename="src/databrowser/lrdatabrowser.ui" line="386"/>
<source>Edit variable</source>
<translation>Редактировать переменную</translation>
</message>
<message>
<location filename="src/databrowser/lrdatabrowser.ui" line="412"/>
<source>Delete variable</source>
<translation>Удалить переменную</translation>
</message>
</context>
<context>
<name>LRVariableDialog</name>
@ -494,32 +534,32 @@ p, li { white-space: pre-wrap; }
<context>
<name>LimeReport::DataSourceManager</name>
<message>
<location filename="src/lrdatasourcemanager.cpp" line="323"/>
<location filename="src/lrdatasourcemanager.cpp" line="317"/>
<source>Connection &quot;%1&quot; is not open</source>
<translation>Соединение &quot;%1&quot; не открыто</translation>
</message>
<message>
<location filename="src/lrdatasourcemanager.cpp" line="496"/>
<location filename="src/lrdatasourcemanager.cpp" line="722"/>
<location filename="src/lrdatasourcemanager.cpp" line="490"/>
<location filename="src/lrdatasourcemanager.cpp" line="716"/>
<source>Datasource &quot;%1&quot; not found !</source>
<translation>Источник данных &quot;%1&quot; не найден !</translation>
</message>
<message>
<location filename="src/lrdatasourcemanager.cpp" line="573"/>
<location filename="src/lrdatasourcemanager.cpp" line="567"/>
<source>connection with name &quot;%1&quot; already exists !</source>
<translation>соединение &quot;%1&quot; уже существует !</translation>
</message>
<message>
<location filename="src/lrdatasourcemanager.cpp" line="590"/>
<location filename="src/lrdatasourcemanager.cpp" line="597"/>
<location filename="src/lrdatasourcemanager.cpp" line="604"/>
<location filename="src/lrdatasourcemanager.cpp" line="611"/>
<location filename="src/lrdatasourcemanager.cpp" line="584"/>
<location filename="src/lrdatasourcemanager.cpp" line="591"/>
<location filename="src/lrdatasourcemanager.cpp" line="598"/>
<location filename="src/lrdatasourcemanager.cpp" line="605"/>
<source>datasource with name &quot;%1&quot; already exists !</source>
<oldsource>data source with name &quot;%1&quot; already exists !!</oldsource>
<translation>источник данных &quot;%1&quot; уже существует !</translation>
</message>
<message>
<location filename="src/lrdatasourcemanager.cpp" line="699"/>
<location filename="src/lrdatasourcemanager.cpp" line="693"/>
<source>invalid connection</source>
<translation>нет соединения</translation>
</message>
@ -743,12 +783,12 @@ p, li { white-space: pre-wrap; }
<context>
<name>LimeReport::PageDesignIntf</name>
<message>
<location filename="src/lrpagedesignintf.cpp" line="1033"/>
<location filename="src/lrpagedesignintf.cpp" line="1069"/>
<source>Warning</source>
<translation>Предупреждение</translation>
</message>
<message>
<location filename="src/lrpagedesignintf.cpp" line="1033"/>
<location filename="src/lrpagedesignintf.cpp" line="1069"/>
<source>Multi band deletion not allowed</source>
<translation>Удаление нескольких бандов запрещено</translation>
</message>
@ -780,12 +820,12 @@ p, li { white-space: pre-wrap; }
<context>
<name>LimeReport::QObjectPropertyModel</name>
<message>
<location filename="src/objectinspector/lrobjectitemmodel.cpp" line="140"/>
<location filename="src/objectinspector/lrobjectitemmodel.cpp" line="144"/>
<source>Property Name</source>
<translation>Свойство</translation>
</message>
<message>
<location filename="src/objectinspector/lrobjectitemmodel.cpp" line="141"/>
<location filename="src/objectinspector/lrobjectitemmodel.cpp" line="145"/>
<source>Property value</source>
<translation>Значение</translation>
</message>
@ -860,7 +900,7 @@ p, li { white-space: pre-wrap; }
<translation>Правая граница</translation>
</message>
<message>
<location filename="src/objectinspector/lrobjectitemmodel.cpp" line="352"/>
<location filename="src/objectinspector/lrobjectitemmodel.cpp" line="356"/>
<source>Warning</source>
<translation>Предупреждение</translation>
</message>
@ -898,7 +938,7 @@ p, li { white-space: pre-wrap; }
<context>
<name>LimeReport::ReportDesignWidget</name>
<message>
<location filename="src/lrreportdesignwidget.cpp" line="228"/>
<location filename="src/lrreportdesignwidget.cpp" line="230"/>
<source>Report file name</source>
<translation>Файл отчета</translation>
</message>
@ -1010,6 +1050,11 @@ p, li { white-space: pre-wrap; }
<source>Report Tools</source>
<translation>Элементы отчета</translation>
</message>
<message>
<location filename="src/lrreportdesignwindow.cpp" line="233"/>
<source>Main Tools</source>
<translation>Основные инструменты</translation>
</message>
<message>
<location filename="src/lrreportdesignwindow.cpp" line="258"/>
<source>Font</source>
@ -1031,118 +1076,123 @@ p, li { white-space: pre-wrap; }
<translation>Границы</translation>
</message>
<message>
<location filename="src/lrreportdesignwindow.cpp" line="300"/>
<location filename="src/lrreportdesignwindow.cpp" line="297"/>
<source>Report bands</source>
<translation>Банды</translation>
</message>
<message>
<location filename="src/lrreportdesignwindow.cpp" line="301"/>
<source>Report Header</source>
<translation>Заголовок отчета</translation>
</message>
<message>
<location filename="src/lrreportdesignwindow.cpp" line="305"/>
<location filename="src/lrreportdesignwindow.cpp" line="306"/>
<source>Report Footer</source>
<translation>Завершение отчета</translation>
</message>
<message>
<location filename="src/lrreportdesignwindow.cpp" line="310"/>
<location filename="src/lrreportdesignwindow.cpp" line="311"/>
<source>Page Header</source>
<translation>Верхний колонтитул</translation>
</message>
<message>
<location filename="src/lrreportdesignwindow.cpp" line="315"/>
<location filename="src/lrreportdesignwindow.cpp" line="316"/>
<source>Page Footer</source>
<translation>Нижний колонтитул</translation>
</message>
<message>
<location filename="src/lrreportdesignwindow.cpp" line="320"/>
<location filename="src/lrreportdesignwindow.cpp" line="321"/>
<source>Data</source>
<translation>Данные</translation>
</message>
<message>
<location filename="src/lrreportdesignwindow.cpp" line="325"/>
<location filename="src/lrreportdesignwindow.cpp" line="326"/>
<source>Data Header</source>
<translation>Заголовок данных</translation>
</message>
<message>
<location filename="src/lrreportdesignwindow.cpp" line="331"/>
<location filename="src/lrreportdesignwindow.cpp" line="332"/>
<source>Data Footer</source>
<translation>Завершение данных</translation>
</message>
<message>
<location filename="src/lrreportdesignwindow.cpp" line="337"/>
<location filename="src/lrreportdesignwindow.cpp" line="338"/>
<source>SubDetail</source>
<translation>Подчиненные данные</translation>
</message>
<message>
<location filename="src/lrreportdesignwindow.cpp" line="343"/>
<location filename="src/lrreportdesignwindow.cpp" line="344"/>
<source>SubDetailHeader</source>
<translation>Заголовок подчиненных данных</translation>
</message>
<message>
<location filename="src/lrreportdesignwindow.cpp" line="349"/>
<location filename="src/lrreportdesignwindow.cpp" line="350"/>
<source>SubDetailFooter</source>
<translation>Завершение подчиненных данных</translation>
</message>
<message>
<location filename="src/lrreportdesignwindow.cpp" line="355"/>
<location filename="src/lrreportdesignwindow.cpp" line="356"/>
<source>GroupHeader</source>
<translation>Заголовок группы</translation>
</message>
<message>
<location filename="src/lrreportdesignwindow.cpp" line="361"/>
<location filename="src/lrreportdesignwindow.cpp" line="362"/>
<source>GroupFooter</source>
<translation>Завершение группы</translation>
</message>
<message>
<location filename="src/lrreportdesignwindow.cpp" line="372"/>
<location filename="src/lrreportdesignwindow.cpp" line="373"/>
<source>File</source>
<translation>Файл</translation>
</message>
<message>
<location filename="src/lrreportdesignwindow.cpp" line="379"/>
<location filename="src/lrreportdesignwindow.cpp" line="380"/>
<source>Edit</source>
<translation>Правка</translation>
</message>
<message>
<location filename="src/lrreportdesignwindow.cpp" line="385"/>
<location filename="src/lrreportdesignwindow.cpp" line="386"/>
<source>Info</source>
<translation>Информация</translation>
</message>
<message>
<location filename="src/lrreportdesignwindow.cpp" line="433"/>
<location filename="src/lrreportdesignwindow.cpp" line="434"/>
<source>Object Inspector</source>
<translation>Инспектор объектов</translation>
</message>
<message>
<location filename="src/lrreportdesignwindow.cpp" line="442"/>
<location filename="src/lrreportdesignwindow.cpp" line="443"/>
<source>Report structure</source>
<translation>Структура отчета</translation>
</message>
<message>
<location filename="src/lrreportdesignwindow.cpp" line="454"/>
<location filename="src/lrreportdesignwindow.cpp" line="455"/>
<source>Data Browser</source>
<translation>Инспектор данных</translation>
</message>
<message>
<location filename="src/lrreportdesignwindow.cpp" line="520"/>
<location filename="src/lrreportdesignwindow.cpp" line="521"/>
<source>Report has been modified ! Do you want save the report ?</source>
<translation>Отчет был изменен ! Хотите его записать ?</translation>
</message>
<message>
<location filename="src/lrreportdesignwindow.cpp" line="724"/>
<location filename="src/lrreportdesignwindow.cpp" line="734"/>
<location filename="src/lrreportdesignwindow.cpp" line="725"/>
<location filename="src/lrreportdesignwindow.cpp" line="736"/>
<source>Report file name</source>
<translation>Файл отчета</translation>
</message>
<message>
<location filename="src/lrreportdesignwindow.cpp" line="876"/>
<location filename="src/lrreportdesignwindow.cpp" line="879"/>
<source>Rendering report</source>
<translation>Создается отчет</translation>
</message>
<message>
<location filename="src/lrreportdesignwindow.cpp" line="876"/>
<location filename="src/lrreportdesignwindow.cpp" line="879"/>
<source>Abort</source>
<translation>О генераторе</translation>
</message>
<message>
<location filename="src/lrreportdesignwindow.cpp" line="885"/>
<location filename="src/lrreportdesignwindow.cpp" line="888"/>
<source> page rendered</source>
<translation>создается страница</translation>
</message>
@ -1192,30 +1242,34 @@ p, li { white-space: pre-wrap; }
<context>
<name>LimeReport::ScriptEngineManager</name>
<message>
<location filename="src/lrscriptenginemanager.cpp" line="333"/>
<location filename="src/lrscriptenginemanager.cpp" line="351"/>
<source>FieldName</source>
<translation>Имя поля</translation>
</message>
<message>
<location filename="src/lrscriptenginemanager.cpp" line="333"/>
<location filename="src/lrscriptenginemanager.cpp" line="349"/>
<location filename="src/lrscriptenginemanager.cpp" line="351"/>
<location filename="src/lrscriptenginemanager.cpp" line="367"/>
<source>BandName</source>
<translation>Имя банда</translation>
</message>
<message>
<location filename="src/lrscriptenginemanager.cpp" line="350"/>
<location filename="src/lrscriptenginemanager.cpp" line="351"/>
<location filename="src/lrscriptenginemanager.cpp" line="368"/>
<location filename="src/lrscriptenginemanager.cpp" line="369"/>
<location filename="src/lrscriptenginemanager.cpp" line="370"/>
<location filename="src/lrscriptenginemanager.cpp" line="371"/>
<source>Value</source>
<translation>Значение</translation>
</message>
<message>
<location filename="src/lrscriptenginemanager.cpp" line="350"/>
<location filename="src/lrscriptenginemanager.cpp" line="351"/>
<location filename="src/lrscriptenginemanager.cpp" line="368"/>
<location filename="src/lrscriptenginemanager.cpp" line="369"/>
<location filename="src/lrscriptenginemanager.cpp" line="370"/>
<location filename="src/lrscriptenginemanager.cpp" line="371"/>
<source>Format</source>
<translation>Формат</translation>
</message>
<message>
<location filename="src/lrscriptenginemanager.cpp" line="350"/>
<location filename="src/lrscriptenginemanager.cpp" line="368"/>
<source>Precision</source>
<translation>Точность</translation>
</message>
@ -1514,22 +1568,22 @@ p, li { white-space: pre-wrap; }
<translation>источник данных &quot;%1&quot; не найден !</translation>
</message>
<message>
<location filename="src/lrpagedesignintf.cpp" line="1242"/>
<location filename="src/lrpagedesignintf.cpp" line="1292"/>
<source>Attention!</source>
<translation>Внимание!</translation>
</message>
<message>
<location filename="src/lrpagedesignintf.cpp" line="1242"/>
<location filename="src/lrpagedesignintf.cpp" line="1292"/>
<source>Selected elements have different parent containers</source>
<translation>Выделенные элементы имеют различные родительские контейнеры</translation>
</message>
<message>
<location filename="src/lrreportdesignwindow.cpp" line="966"/>
<location filename="src/lrreportdesignwindow.cpp" line="969"/>
<source>Object with name %1 already exists</source>
<translation>Объект с именем %1 уже существует</translation>
</message>
<message>
<location filename="src/lrscriptenginemanager.cpp" line="241"/>
<location filename="src/lrscriptenginemanager.cpp" line="259"/>
<source>Function %1 not found or have wrong arguments</source>
<translation>Функция %1 не найдена или вызвана с неверными аргументами</translation>
</message>
@ -1627,24 +1681,25 @@ p, li { white-space: pre-wrap; }
<translation></translation>
</message>
<message>
<location filename="src/lrglobal.cpp" line="44"/>
<source>TopLine</source>
<translation>Верхняя граница</translation>
<translation type="vanished">Верхняя граница</translation>
</message>
<message>
<location filename="src/lrglobal.cpp" line="45"/>
<source>BottomLine</source>
<translation>Нижняя граница</translation>
<translation type="vanished">Нижняя граница</translation>
</message>
<message>
<location filename="src/lrglobal.cpp" line="46"/>
<source>LeftLine</source>
<translation>Левая граница</translation>
<translation type="vanished">Левая граница</translation>
</message>
<message>
<location filename="src/lrglobal.cpp" line="47"/>
<source>RightLine</source>
<translation>Правая граница</translation>
<translation type="vanished">Правая граница</translation>
</message>
<message>
<location filename="src/objectinspector/propertyItems/lrcontentpropitem.cpp" line="13"/>
<source>content</source>
<translation>содержимое</translation>
</message>
</context>
<context>
@ -1829,14 +1884,12 @@ p, li { white-space: pre-wrap; }
<context>
<name>WaitForm</name>
<message>
<location filename="src/waitform.ui" line="20"/>
<source>Wait</source>
<translation>Ожидайте</translation>
<translation type="vanished">Ожидайте</translation>
</message>
<message>
<location filename="src/waitform.ui" line="48"/>
<source>Please wait ...</source>
<translation>Пожалуста подождите ...</translation>
<translation type="vanished">Пожалуста подождите ...</translation>
</message>
</context>
</TS>