0
0
mirror of https://github.com/fralx/LimeReport.git synced 2024-12-24 08:34:38 +03:00

Fix #61 AutoHeight overlapping

This commit is contained in:
Arin Alex 2017-04-05 00:58:04 +03:00
parent 61a3c20bb2
commit 6dca8b27cb
10 changed files with 200 additions and 163 deletions

View File

@ -691,7 +691,7 @@ bool TextItem::isNeedUpdateSize(RenderPass pass) const
{
Q_UNUSED(pass)
if ((autoHeight() && autoWidth()) || hasFollower()){
if ((autoHeight() || autoWidth()) || hasFollower()){
initTextSizes();
}

View File

@ -89,7 +89,8 @@ SOURCES += \
$$REPORT_PATH/lrsimplecrypt.cpp \
$$REPORT_PATH/lraboutdialog.cpp \
$$REPORT_PATH/lrsettingdialog.cpp \
$$REPORT_PATH/scriptbrowser/lrscriptbrowser.cpp
$$REPORT_PATH/scriptbrowser/lrscriptbrowser.cpp \
$$REPORT_PATH/lritemscontainerdesignitf.cpp
contains(CONFIG, zint){
SOURCES += $$REPORT_PATH/items/lrbarcodeitem.cpp
@ -188,7 +189,8 @@ HEADERS += \
$$REPORT_PATH/lrcallbackdatasourceintf.h \
$$REPORT_PATH/lrsettingdialog.h \
$$REPORT_PATH/lrpreviewreportwidget_p.h \
$$REPORT_PATH/scriptbrowser/lrscriptbrowser.h
$$REPORT_PATH/scriptbrowser/lrscriptbrowser.h \
$$REPORT_PATH/lritemscontainerdesignitf.h
contains(CONFIG,zint){
HEADERS += $$REPORT_PATH/items/lrbarcodeitem.h

View File

@ -99,33 +99,8 @@ void BandMarker::mousePressEvent(QGraphicsSceneMouseEvent *event)
}
}
bool Segment::intersect(Segment value)
{
return ((value.m_end>=m_begin)&&(value.m_end<=m_end)) ||
((value.m_begin>=m_begin)&&(value.m_end>=m_end)) ||
((value.m_begin>=m_begin)&&(value.m_end<=m_end)) ||
((value.m_begin<m_begin)&&(value.m_end>m_end)) ;
}
qreal Segment::intersectValue(Segment value)
{
if ((value.m_end>=m_begin)&&(value.m_end<=m_end)){
return value.m_end-m_begin;
}
if ((value.m_begin>=m_begin)&&(value.m_end>=m_end)){
return m_end-value.m_begin;
}
if ((value.m_begin>=m_begin)&&(value.m_end<=m_end)){
return value.m_end-value.m_begin;
}
if ((value.m_begin<m_begin)&&(value.m_end>m_end)){
return m_end-m_begin;
}
return 0;
}
BandDesignIntf::BandDesignIntf(BandsType bandType, const QString &xmlTypeName, QObject* owner, QGraphicsItem *parent) :
BaseDesignIntf(xmlTypeName, owner,parent),
ItemsContainerDesignInft(xmlTypeName, owner,parent),
m_bandType(bandType),
m_bandIndex(static_cast<int>(bandType)),
m_dataSourceName(""),
@ -581,97 +556,11 @@ void BandDesignIntf::setSplittable(bool value){
}
}
bool itemSortContainerLessThen(const PItemSortContainer c1, const PItemSortContainer c2)
{
VSegment vS1(c1->m_rect),vS2(c2->m_rect);
HSegment hS1(c1->m_rect),hS2(c2->m_rect);
if (vS1.intersectValue(vS2)>hS1.intersectValue(hS2))
return c1->m_rect.x()<c2->m_rect.x();
else return c1->m_rect.y()<c2->m_rect.y();
}
bool bandIndexLessThen(const BandDesignIntf* b1, const BandDesignIntf* b2)
{
return b1->bandIndex()<b2->bandIndex();
}
void BandDesignIntf::snapshotItemsLayout()
{
m_bandItems.clear();
foreach(BaseDesignIntf *childItem,childBaseItems()){
m_bandItems.append(PItemSortContainer(new ItemSortContainer(childItem)));
}
qSort(m_bandItems.begin(),m_bandItems.end(),itemSortContainerLessThen);
}
void BandDesignIntf::arrangeSubItems(RenderPass pass, DataSourceManager *dataManager, ArrangeType type)
{
bool needArrage=(type==Force);
foreach (PItemSortContainer item, m_bandItems) {
if (item->m_item->isNeedUpdateSize(pass)){
item->m_item->updateItemSize(dataManager, pass);
needArrage=true;
}
}
if (needArrage){
//qSort(m_bandItems.begin(),m_bandItems.end(),itemSortContainerLessThen);
for (int i=0;i<m_bandItems.count();i++)
for (int j=i;j<m_bandItems.count();j++){
if ((i!=j) && (m_bandItems[i]->m_item->collidesWithItem(m_bandItems[j]->m_item))){
HSegment hS1(m_bandItems[j]->m_rect),hS2(m_bandItems[i]->m_rect);
VSegment vS1(m_bandItems[j]->m_rect),vS2(m_bandItems[i]->m_rect);
if (m_bandItems[i]->m_rect.bottom()<m_bandItems[i]->m_item->geometry().bottom()){
if (hS1.intersectValue(hS2)>vS1.intersectValue(vS2))
m_bandItems[j]->m_item->setY(m_bandItems[i]->m_item->y()+m_bandItems[i]->m_item->height()
+m_bandItems[j]->m_rect.top()-m_bandItems[i]->m_rect.bottom());
}
if (m_bandItems[i]->m_rect.right()<m_bandItems[i]->m_item->geometry().right()){
if (vS1.intersectValue(vS2)>hS1.intersectValue(hS2))
m_bandItems[j]->m_item->setX(m_bandItems[i]->m_item->geometry().right()+
(m_bandItems[j]->m_rect.x()-m_bandItems[i]->m_rect.right()));
}
}
}
}
if(needArrage||pass==FirstPass){
int maxBottom = findMaxBottom();
foreach(BaseDesignIntf* item,childBaseItems()){
ItemDesignIntf* childItem=dynamic_cast<ItemDesignIntf*>(item);
if (childItem){
if (childItem->stretchToMaxHeight())
childItem->setHeight(maxBottom-childItem->geometry().top());
}
}
}
}
qreal BandDesignIntf::findMaxBottom()
{
qreal maxBottom=0;
foreach(QGraphicsItem* item,childItems()){
BaseDesignIntf* subItem = dynamic_cast<BaseDesignIntf *>(item);
if(subItem)
if ( subItem->isVisible() && (subItem->geometry().bottom()>maxBottom) )
maxBottom=subItem->geometry().bottom();
}
return maxBottom;
}
qreal BandDesignIntf::findMaxHeight(){
qreal maxHeight=0;
foreach(QGraphicsItem* item,childItems()){
BaseDesignIntf* subItem = dynamic_cast<BaseDesignIntf *>(item);
if(subItem)
if (subItem->geometry().height()>maxHeight) maxHeight=subItem->geometry().height();
}
return maxHeight;
}
void BandDesignIntf::trimToMaxHeight(int maxHeight)
{
foreach(BaseDesignIntf* item,childBaseItems()){

View File

@ -31,6 +31,7 @@
#define LRBANDDESIGNINTF_H
#include "lrbasedesignintf.h"
#include "lrdatasourcemanager.h"
#include "lritemscontainerdesignitf.h"
#include <QObject>
namespace LimeReport {
@ -81,10 +82,7 @@ private:
BandDesignIntf* m_band;
};
struct ItemSortContainer;
typedef QSharedPointer< ItemSortContainer > PItemSortContainer;
class BandDesignIntf : public BaseDesignIntf
class BandDesignIntf : public ItemsContainerDesignInft
{
Q_OBJECT
Q_PROPERTY(bool autoHeight READ autoHeight WRITE setAutoHeight )
@ -223,10 +221,6 @@ public:
signals:
void bandRendered(BandDesignIntf* band);
protected:
void snapshotItemsLayout();
void arrangeSubItems(RenderPass pass, DataSourceManager *dataManager, ArrangeType type = AsNeeded);
qreal findMaxBottom();
qreal findMaxHeight();
void trimToMaxHeight(int maxHeight);
void setBandTypeText(const QString& value);
QString bandTypeText(){return m_bandTypeText;}
@ -286,37 +280,7 @@ public:
DataBandDesignIntf(BandsType bandType, QString xmlTypeName, QObject* owner = 0, QGraphicsItem* parent=0);
};
class Segment{
public:
Segment(qreal segmentStart,qreal segmentEnd):m_begin(segmentStart),m_end(segmentEnd){}
bool intersect(Segment value);
qreal intersectValue(Segment value);
private:
qreal m_begin;
qreal m_end;
};
class VSegment : public Segment{
public:
VSegment(QRectF rect):Segment(rect.top(),rect.bottom()){}
};
struct HSegment :public Segment{
public:
HSegment(QRectF rect):Segment(rect.left(),rect.right()){}
};
struct ItemSortContainer {
QRectF m_rect;
BaseDesignIntf * m_item;
ItemSortContainer(BaseDesignIntf *item){
m_item=item;
m_rect=item->geometry();
}
};
bool itemSortContainerLessThen(const PItemSortContainer c1, const PItemSortContainer c2);
bool bandIndexLessThen(const BandDesignIntf* b1, const BandDesignIntf* b2);
}
} // namespace LimeReport
#endif // LRBANDDESIGNINTF_H

View File

@ -39,7 +39,6 @@
#include "serializators/lrxmlreader.h"
#include <memory>
#include <QMetaObject>
#include <QGraphicsSceneMouseEvent>
#include <QApplication>
@ -1525,8 +1524,7 @@ BaseDesignIntf *Marker::object() const
return m_object;
}
}
} //namespace LimeReport

View File

@ -0,0 +1,117 @@
#include "lritemscontainerdesignitf.h"
#include "lritemdesignintf.h"
namespace LimeReport {
bool Segment::intersect(Segment value)
{
return ((value.m_end>=m_begin)&&(value.m_end<=m_end)) ||
((value.m_begin>=m_begin)&&(value.m_end>=m_end)) ||
((value.m_begin>=m_begin)&&(value.m_end<=m_end)) ||
((value.m_begin<m_begin)&&(value.m_end>m_end)) ;
}
qreal Segment::intersectValue(Segment value)
{
if ((value.m_end>=m_begin)&&(value.m_end<=m_end)){
return value.m_end-m_begin;
}
if ((value.m_begin>=m_begin)&&(value.m_end>=m_end)){
return m_end-value.m_begin;
}
if ((value.m_begin>=m_begin)&&(value.m_end<=m_end)){
return value.m_end-value.m_begin;
}
if ((value.m_begin<m_begin)&&(value.m_end>m_end)){
return m_end-m_begin;
}
return 0;
}
bool itemSortContainerLessThen(const PItemSortContainer c1, const PItemSortContainer c2)
{
VSegment vS1(c1->m_rect),vS2(c2->m_rect);
HSegment hS1(c1->m_rect),hS2(c2->m_rect);
if (vS1.intersectValue(vS2)>hS1.intersectValue(hS2))
return c1->m_rect.x()<c2->m_rect.x();
else return c1->m_rect.y()<c2->m_rect.y();
}
void ItemsContainerDesignInft::snapshotItemsLayout()
{
m_containerItems.clear();
foreach(BaseDesignIntf *childItem,childBaseItems()){
m_containerItems.append(PItemSortContainer(new ItemSortContainer(childItem)));
}
qSort(m_containerItems.begin(),m_containerItems.end(),itemSortContainerLessThen);
}
void ItemsContainerDesignInft::arrangeSubItems(RenderPass pass, DataSourceManager *dataManager, ArrangeType type)
{
bool needArrage=(type==Force);
foreach (PItemSortContainer item, m_containerItems) {
if (item->m_item->isNeedUpdateSize(pass)){
item->m_item->updateItemSize(dataManager, pass);
needArrage=true;
}
}
if (needArrage){
for (int i=0;i<m_containerItems.count();i++){
for (int j=i;j<m_containerItems.count();j++){
if ((i!=j) && (m_containerItems[i]->m_item->collidesWithItem(m_containerItems[j]->m_item))){
HSegment hS1(m_containerItems[j]->m_rect),hS2(m_containerItems[i]->m_rect);
VSegment vS1(m_containerItems[j]->m_rect),vS2(m_containerItems[i]->m_rect);
if (m_containerItems[i]->m_rect.bottom()<m_containerItems[i]->m_item->geometry().bottom()){
if (hS1.intersectValue(hS2)>vS1.intersectValue(vS2))
m_containerItems[j]->m_item->setY(m_containerItems[i]->m_item->y()+m_containerItems[i]->m_item->height()
+m_containerItems[j]->m_rect.top()-m_containerItems[i]->m_rect.bottom());
}
if (m_containerItems[i]->m_rect.right()<m_containerItems[i]->m_item->geometry().right()){
if (vS1.intersectValue(vS2)>hS1.intersectValue(hS2))
m_containerItems[j]->m_item->setX(m_containerItems[i]->m_item->geometry().right()+
(m_containerItems[j]->m_rect.x()-m_containerItems[i]->m_rect.right()));
}
}
}
}
}
if (needArrage||pass==FirstPass){
int maxBottom = findMaxBottom();
foreach(BaseDesignIntf* item,childBaseItems()){
ItemDesignIntf* childItem=dynamic_cast<ItemDesignIntf*>(item);
if (childItem){
if (childItem->stretchToMaxHeight())
childItem->setHeight(maxBottom-childItem->geometry().top());
}
}
}
}
qreal ItemsContainerDesignInft::findMaxBottom()
{
qreal maxBottom=0;
foreach(QGraphicsItem* item,childItems()){
BaseDesignIntf* subItem = dynamic_cast<BaseDesignIntf *>(item);
if(subItem)
if ( subItem->isVisible() && (subItem->geometry().bottom()>maxBottom) )
maxBottom=subItem->geometry().bottom();
}
return maxBottom;
}
qreal ItemsContainerDesignInft::findMaxHeight()
{
qreal maxHeight=0;
foreach(QGraphicsItem* item,childItems()){
BaseDesignIntf* subItem = dynamic_cast<BaseDesignIntf *>(item);
if(subItem)
if (subItem->geometry().height()>maxHeight) maxHeight=subItem->geometry().height();
}
return maxHeight;
}
} // namespace LimeReport

View File

@ -0,0 +1,56 @@
#ifndef ITEMSCONTAINERDESIGNITF_H
#define ITEMSCONTAINERDESIGNITF_H
#include "lrbasedesignintf.h"
namespace LimeReport{
class Segment{
public:
Segment(qreal segmentStart,qreal segmentEnd):m_begin(segmentStart),m_end(segmentEnd){}
bool intersect(Segment value);
qreal intersectValue(Segment value);
private:
qreal m_begin;
qreal m_end;
};
class VSegment : public Segment{
public:
VSegment(QRectF rect):Segment(rect.top(),rect.bottom()){}
};
struct HSegment :public Segment{
public:
HSegment(QRectF rect):Segment(rect.left(),rect.right()){}
};
struct ItemSortContainer {
QRectF m_rect;
BaseDesignIntf * m_item;
ItemSortContainer(BaseDesignIntf *item){
m_item=item;
m_rect=item->geometry();
}
};
typedef QSharedPointer< ItemSortContainer > PItemSortContainer;
bool itemSortContainerLessThen(const PItemSortContainer c1, const PItemSortContainer c2);
class ItemsContainerDesignInft : public BaseDesignIntf{
public:
ItemsContainerDesignInft(const QString& xmlTypeName, QObject* owner = 0, QGraphicsItem* parent=0):
BaseDesignIntf(xmlTypeName, owner, parent){}
protected:
void snapshotItemsLayout();
void arrangeSubItems(RenderPass pass, DataSourceManager *dataManager, ArrangeType type = AsNeeded);
qreal findMaxBottom();
qreal findMaxHeight();
private:
QVector<PItemSortContainer> m_containerItems;
};
} // namespace LimeReport
#endif // ITEMSCONTAINERDESIGNITF_H

View File

@ -46,24 +46,26 @@ bool bandSortBandLessThenByIndex(const BandDesignIntf *c1, const BandDesignIntf
}
PageItemDesignIntf::PageItemDesignIntf(QObject *owner, QGraphicsItem *parent) :
BaseDesignIntf("PageItem",owner,parent),
ItemsContainerDesignInft("PageItem",owner,parent),
m_topMargin(0), m_bottomMargin(0), m_leftMargin(0), m_rightMargin(0),
m_pageOrientaion(Portrait), m_pageSize(A4), m_sizeChainging(false),
m_fullPage(false), m_oldPrintMode(false), m_resetPageNumber(false)
{
setFixedPos(true);
setPossibleResizeDirectionFlags(Fixed);
setFlag(QGraphicsItem::ItemClipsChildrenToShape);
initPageSize(m_pageSize);
}
PageItemDesignIntf::PageItemDesignIntf(const PageSize pageSize, const QRectF &rect, QObject *owner, QGraphicsItem *parent) :
BaseDesignIntf("PageItem",owner,parent),
ItemsContainerDesignInft("PageItem",owner,parent),
m_topMargin(0), m_bottomMargin(0), m_leftMargin(0), m_rightMargin(0),
m_pageOrientaion(Portrait), m_pageSize(pageSize), m_sizeChainging(false),
m_fullPage(false), m_oldPrintMode(false), m_resetPageNumber(false)
{
setFixedPos(true);
setPossibleResizeDirectionFlags(Fixed);
setFlag(QGraphicsItem::ItemClipsChildrenToShape);
initPageSize(rect.size());
}
@ -316,6 +318,12 @@ void PageItemDesignIntf::setResetPageNumber(bool resetPageNumber)
}
}
void PageItemDesignIntf::updateSubItemsSize(RenderPass pass, DataSourceManager *dataManager)
{
snapshotItemsLayout();
arrangeSubItems(pass, dataManager);
}
bool PageItemDesignIntf::oldPrintMode() const
{
return m_oldPrintMode;

View File

@ -31,13 +31,14 @@
#define LRPAGEITEM_H
#include "lrbasedesignintf.h"
#include "lrbanddesignintf.h"
#include "lritemscontainerdesignitf.h"
#include <QList>
#include <QColor>
namespace LimeReport{
class ReportRender;
class PageItemDesignIntf : public LimeReport::BaseDesignIntf
class PageItemDesignIntf : public LimeReport::ItemsContainerDesignInft
{
Q_OBJECT
Q_ENUMS(Orientation)
@ -115,6 +116,7 @@ public:
bool canContainChildren(){ return true;}
bool resetPageNumber() const;
void setResetPageNumber(bool resetPageNumber);
void updateSubItemsSize(RenderPass pass, DataSourceManager *dataManager);
protected slots:
void bandDeleted(QObject* band);

View File

@ -608,9 +608,10 @@ void ReportRender::renderPageItems(PageItemDesignIntf* patternPage)
}
}
m_renderPageItem->restoreLinks();
foreach(BaseDesignIntf* item, pageItems){
item->updateItemSize(m_datasources);
}
m_renderPageItem->updateSubItemsSize(FirstPass,m_datasources);
// foreach(BaseDesignIntf* item, pageItems){
// item->updateItemSize(m_datasources);
// }
}
qreal ReportRender::calcPageFooterHeight(PageItemDesignIntf *patternPage)