diff --git a/limereport/items/lrtextitem.cpp b/limereport/items/lrtextitem.cpp index 7d61562..041a737 100644 --- a/limereport/items/lrtextitem.cpp +++ b/limereport/items/lrtextitem.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "lrpagedesignintf.h" @@ -57,7 +58,7 @@ namespace LimeReport{ TextItem::TextItem(QObject *owner, QGraphicsItem *parent) : ContentItemDesignIntf(xmlTag,owner,parent), m_angle(Angle0), m_trimValue(true), m_allowHTML(false), - m_allowHTMLInFields(false) + m_allowHTMLInFields(false), m_followTo(""), m_follower(0) { m_text = new QTextDocument(); @@ -265,8 +266,13 @@ void TextItem::updateItemSize(DataSourceManager* dataManager, RenderPass pass, i setWidth(m_textSize.width() + fakeMarginSize()*2); } - if ((m_textSize.height()>height()) && (m_autoHeight) ){ - setHeight(m_textSize.height()+borderLineSize()*2); + if (m_textSize.height()>height()) { + if (m_autoHeight) + setHeight(m_textSize.height()+borderLineSize()*2); + else if (hasFollower() && !content().isEmpty()){ + follower()->setContent(getTextPart(0,height())); + setContent(getTextPart(height(),0)); + } } BaseDesignIntf::updateItemSize(dataManager, pass, maxHeight); } @@ -353,6 +359,7 @@ void TextItem::setLineSpacing(int value) void TextItem::initText() { + if (!m_text) return; QTextOption to; to.setAlignment(m_alignment); @@ -454,6 +461,66 @@ QString TextItem::formatFieldValue() } } +QString TextItem::followTo() const +{ + return m_followTo; +} + +void TextItem::setFollowTo(const QString &followTo) +{ + if (m_followTo != followTo){ + QString oldValue = m_followTo; + m_followTo = followTo; + if (!isLoading()){ + TextItem* fi = scene()->findChild(followTo); + if (fi && initFollower(followTo)){ + notify("followTo",oldValue,followTo); + } else { + m_followTo = ""; + QMessageBox::critical( + 0, + tr("Error"), + tr("TextItem \" %1 \" already has folower \" %2 \" ") + .arg(fi->objectName()) + .arg(fi->follower()->objectName()) + ); + notify("followTo",followTo,""); + } + } + } +} + +void TextItem::setFollower(TextItem *follower) +{ + if (!m_follower){ + m_follower = follower; + } +} + +bool TextItem::hasFollower() +{ + return m_follower != 0; +} + +bool TextItem::initFollower(QString follower) +{ + TextItem* fi = scene()->findChild(follower); + if (fi){ + if (!fi->hasFollower()){ + fi->setFollower(this); + return true; + } + } + return false; +} + +void TextItem::pageObjectHasBeenLoaded() +{ + if (!m_followTo.isEmpty()){ + initFollower(m_followTo); + } +} + TextItem::ValueType TextItem::valueType() const { return m_valueType; @@ -537,6 +604,7 @@ bool TextItem::isNeedUpdateSize(RenderPass pass) const Q_UNUSED(pass) bool res = (m_textSize.height()>geometry().height()&&autoHeight()) || (m_textSize.width()>geometry().width()&&autoWidth()) || + m_follower || isNeedExpandContent(); return res; } @@ -557,6 +625,7 @@ void TextItem::setAlignment(Qt::Alignment value) void TextItem::expandContent(DataSourceManager* dataManager, RenderPass pass) { + QString context=content(); ExpandType expandType = (allowHTML() && !allowHTMLInFields())?ReplaceHTMLSymbols:NoEscapeSymbols; switch(pass){ @@ -575,6 +644,7 @@ void TextItem::expandContent(DataSourceManager* dataManager, RenderPass pass) } else { setContent(context); } + } void TextItem::setAutoHeight(bool value) @@ -611,63 +681,79 @@ bool TextItem::canBeSplitted(int height) const return height>(m_text->begin().layout()->lineAt(0).height()); } -BaseDesignIntf *TextItem::cloneUpperPart(int height, QObject *owner, QGraphicsItem *parent) -{ +QString TextItem::getTextPart(int height, int skipHeight){ int linesHeight=0; - QString tmpText=""; - TextItem* upperPart = dynamic_cast(cloneItem(itemMode(),owner,parent)); + int curLine=0; + int textPos=0; - for (QTextBlock it=m_text->begin();it!=m_text->end();it=it.next()){ - for (int i=0;ilineCount();i++){ - linesHeight+=it.layout()->lineAt(i).height()+lineSpacing(); - if (linesHeight>(height-(fakeMarginSize()*2+borderLineSize()*2))) { - linesHeight-=it.layout()->lineAt(i).height(); - goto loop_exit; + QTextBlock curBlock = m_text->begin(); + QString resultText=""; + + if (skipHeight>0){ + for (;curBlock!=m_text->end();curBlock=curBlock.next()){ + for (curLine=0;curLinelineCount();curLine++){ + linesHeight+=curBlock.layout()->lineAt(curLine).height()+lineSpacing(); + if (linesHeight>(skipHeight-(/*fakeMarginSize()*2+*/borderLineSize()*2))) {goto loop_exit;} + } + } + loop_exit:; + } + + linesHeight = 0; + qDebug()<end()); + for (;curBlock!=m_text->end() || curLinelineCount();curLine++){ + if (resultText=="") textPos= curBlock.layout()->lineAt(curLine).textStart(); + linesHeight+=curBlock.layout()->lineAt(curLine).height()+lineSpacing(); + if ( (height>0) && (linesHeight>(height-(/*fakeMarginSize()*2+*/borderLineSize()*2))) ) { + linesHeight-=curBlock.layout()->lineAt(curLine).height(); + goto loop_exit1; } - tmpText+=it.text().mid(it.layout()->lineAt(i).textStart(),it.layout()->lineAt(i).textLength())+'\n'; + resultText+=curBlock.text().mid(curBlock.layout()->lineAt(curLine).textStart(), + curBlock.layout()->lineAt(curLine).textLength()); } } - loop_exit: - tmpText.chop(1); + loop_exit1:; + + resultText.chop(1); - upperPart->setHeight(linesHeight+fakeMarginSize()*2+borderLineSize()*2); QScopedPointer context(new HtmlContext(m_strText)); - upperPart->setContent(context->extendTextByTags(tmpText,0)); - upperPart->initText(); - return upperPart; + return context->extendTextByTags(resultText,textPos); } -BaseDesignIntf *TextItem::cloneBottomPart(int height, QObject *owner, QGraphicsItem *parent) +void TextItem::restoreLinksEvent() { - TextItem* bottomPart = dynamic_cast(cloneItem(itemMode(),owner,parent)); - int linesHeight=0; - int curLine=0; - QTextBlock curBlock; - - QString tmpText=""; - - for (curBlock=m_text->begin();curBlock!=m_text->end();curBlock=curBlock.next()){ - for (curLine=0;curLinelineCount();curLine++){ - linesHeight+=curBlock.layout()->lineAt(curLine).height()+lineSpacing(); - if (linesHeight>(height-(fakeMarginSize()*2+borderLineSize()*2))) {goto loop_exit;} + if (!followTo().isEmpty()){ + BaseDesignIntf* pi = dynamic_cast(parentItem()); + if (pi){ + foreach (BaseDesignIntf* bi, pi->childBaseItems()) { + if (bi->patternName().compare(followTo())==0){ + TextItem* ti = dynamic_cast(bi); + if (ti){ + ti->setFollower(this); + } + } + } } } - loop_exit:; +} - int textPos=0; - for (;curBlock!=m_text->end();curBlock=curBlock.next(),curLine=0){ - for (;curLinelineCount();curLine++){ - if (tmpText=="") textPos= curBlock.layout()->lineAt(curLine).textStart(); - tmpText+=curBlock.text().mid(curBlock.layout()->lineAt(curLine).textStart(), - curBlock.layout()->lineAt(curLine).textLength()) + "\n"; - } - } - tmpText.chop(1); +BaseDesignIntf *TextItem::cloneUpperPart(int height, QObject *owner, QGraphicsItem *parent) +{ + TextItem* upperPart = dynamic_cast(cloneItem(itemMode(),owner,parent)); + upperPart->setContent(getTextPart(height,0)); + upperPart->initText(); + upperPart->setHeight(upperPart->textSize().height()+borderLineSize()*2); + return upperPart; +} - QScopedPointer context(new HtmlContext(m_strText)); - bottomPart->setContent(context->extendTextByTags(tmpText,textPos)); +BaseDesignIntf *TextItem::cloneBottomPart(int height, QObject *owner, QGraphicsItem *parent) +{ + TextItem* bottomPart = dynamic_cast(cloneItem(itemMode(),owner,parent)); + bottomPart->setContent(getTextPart(0,height)); bottomPart->initText(); - bottomPart->setHeight(bottomPart->m_textSize.height()+borderLineSize()*2); + bottomPart->setHeight(bottomPart->textSize().height()+borderLineSize()*2); return bottomPart; } diff --git a/limereport/items/lrtextitem.h b/limereport/items/lrtextitem.h index 07c3412..bda15d8 100644 --- a/limereport/items/lrtextitem.h +++ b/limereport/items/lrtextitem.h @@ -32,15 +32,16 @@ #include #include #include -#include "lritemdesignintf.h" -#include - #include +#include "lritemdesignintf.h" +#include "lritemdesignintf.h" +#include "lrpageinitintf.h" + namespace LimeReport { class Tag; -class TextItem : public LimeReport::ContentItemDesignIntf { +class TextItem : public LimeReport::ContentItemDesignIntf, IPageInit { Q_OBJECT Q_ENUMS(AutoWidth) Q_ENUMS(AngleType) @@ -66,6 +67,7 @@ class TextItem : public LimeReport::ContentItemDesignIntf { Q_PROPERTY(bool allowHTMLInFields READ allowHTMLInFields WRITE setAllowHTMLInFields) Q_PROPERTY(QString format READ format WRITE setFormat) Q_PROPERTY(ValueType valueType READ valueType WRITE setValueType) + Q_PROPERTY(QString followTo READ followTo WRITE setFollowTo) public: enum AutoWidth{NoneAutoWidth,MaxWordLength,MaxStringLength}; @@ -140,12 +142,25 @@ public: ValueType valueType() const; void setValueType(const ValueType valueType); + QSizeF textSize(){ return m_textSize;} + QString followTo() const; + void setFollowTo(const QString &followTo); + void setFollower(TextItem* follower); + bool hasFollower(); + TextItem* follower(){ return m_follower;} + bool initFollower(QString follower); + + // IPageInit interface + void pageObjectHasBeenLoaded(); + protected: void updateLayout(); bool isNeedExpandContent() const; QString replaceBR(QString text); QString replaceReturns(QString text); int fakeMarginSize(); + QString getTextPart(int height, int skipHeight); + void restoreLinksEvent(); private: void initText(); void setTextFont(const QFont &value); @@ -174,6 +189,8 @@ private: QString m_format; ValueType m_valueType; + QString m_followTo; + TextItem* m_follower; }; } diff --git a/limereport/lrbanddesignintf.cpp b/limereport/lrbanddesignintf.cpp index a55f74c..c7b3dcc 100644 --- a/limereport/lrbanddesignintf.cpp +++ b/limereport/lrbanddesignintf.cpp @@ -889,6 +889,7 @@ void BandDesignIntf::updateItemSize(DataSourceManager* dataManager, RenderPass p if (borderLines()!=0){ spaceBorder += borderLineSize(); } + restoreLinks(); snapshotItemsLayout(); arrangeSubItems(pass, dataManager); if (autoHeight()){ diff --git a/limereport/lrbasedesignintf.cpp b/limereport/lrbasedesignintf.cpp index 8b632d5..a901997 100644 --- a/limereport/lrbasedesignintf.cpp +++ b/limereport/lrbasedesignintf.cpp @@ -76,7 +76,8 @@ BaseDesignIntf::BaseDesignIntf(const QString &storageTypeName, QObject *owner, Q m_itemAlign(DesignedItemAlign), m_changingItemAlign(false), m_borderColor(Qt::black), - m_reportSettings(0) + m_reportSettings(0), + m_patternName("") { setGeometry(QRectF(0, 0, m_width, m_height)); if (BaseDesignIntf *item = dynamic_cast(parent)) { @@ -672,6 +673,16 @@ void BaseDesignIntf::turnOnSelectionMarker(bool value) } } +QString BaseDesignIntf::patternName() const +{ + return m_patternName; +} + +void BaseDesignIntf::setPatternName(const QString &patternName) +{ + m_patternName = patternName; +} + ReportSettings *BaseDesignIntf::reportSettings() const { return m_reportSettings; @@ -737,7 +748,7 @@ void BaseDesignIntf::emitObjectNamePropertyChanged(const QString &oldName, const int BaseDesignIntf::borderLineSize() const { - return m_borderLineSize; + return 0 /*m_borderLineSize*/; } void BaseDesignIntf::setBorderLineSize(int value) @@ -987,6 +998,19 @@ void BaseDesignIntf::parentChangedEvent(BaseDesignIntf *) } +void BaseDesignIntf::restoreLinks() +{ +#ifdef HAVE_QT5 + foreach(QObject * child, children()) { +#else + foreach(QObject * child, QObject::children()) { +#endif + BaseDesignIntf *childItem = dynamic_cast(child); + if (childItem) {childItem->restoreLinks();} + } + restoreLinksEvent(); +} + QPainterPath BaseDesignIntf::shape() const { QPainterPath path; @@ -1229,6 +1253,7 @@ void BaseDesignIntf::collectionLoadFinished(const QString &collectionName) BaseDesignIntf *BaseDesignIntf::cloneItem(ItemMode mode, QObject *owner, QGraphicsItem *parent) { BaseDesignIntf *clone = cloneItemWOChild(mode, owner, parent); + clone->setPatternName(this->objectName()); #ifdef HAVE_QT5 foreach(QObject * child, children()) { #else diff --git a/limereport/lrbasedesignintf.h b/limereport/lrbasedesignintf.h index f31bf73..dae9cf4 100644 --- a/limereport/lrbasedesignintf.h +++ b/limereport/lrbasedesignintf.h @@ -249,6 +249,8 @@ public: ReportSettings* reportSettings() const; void setReportSettings(ReportSettings *reportSettings); void setZValueProperty(qreal value); + QString patternName() const; + void setPatternName(const QString &patternName); Q_INVOKABLE QString setItemWidth(qreal width); Q_INVOKABLE QString setItemHeight(qreal height); @@ -258,6 +260,7 @@ public: Q_INVOKABLE qreal getItemPosY(); Q_INVOKABLE QString setItemPosX(qreal xValue); Q_INVOKABLE QString setItemPosY(qreal yValue); + protected: //ICollectionContainer @@ -283,6 +286,8 @@ protected: virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); virtual void childAddedEvent(BaseDesignIntf* child); virtual void parentChangedEvent(BaseDesignIntf*); + void restoreLinks(); + virtual void restoreLinksEvent(){} void drawTopLine(QPainter *painter, QRectF rect) const; void drawBootomLine(QPainter *painter, QRectF rect) const; @@ -359,6 +364,7 @@ private: bool m_changingItemAlign; QColor m_borderColor; ReportSettings* m_reportSettings; + QString m_patternName; signals: void geometryChanged(QObject* object, QRectF newGeometry, QRectF oldGeometry); void posChanged(QObject* object, QPointF newPos, QPointF oldPos); diff --git a/limereport/lrreportrender.cpp b/limereport/lrreportrender.cpp index 42dacef..3d39635 100644 --- a/limereport/lrreportrender.cpp +++ b/limereport/lrreportrender.cpp @@ -204,7 +204,6 @@ void ReportRender::renderPage(PageDesignIntf* patternPage) resetPageNumber(PageReset); } - //m_pageCount = 1; m_renderCanceled = false; BandDesignIntf* reportFooter = m_patternPageItem->bandByType(BandDesignIntf::ReportFooter); m_reportFooterHeight = 0; @@ -225,9 +224,7 @@ void ReportRender::renderPage(PageDesignIntf* patternPage) QMessageBox::critical(0,tr("Error"),exception.what()); return; } - clearPageMap(); - startNewPage(); renderBand(m_patternPageItem->bandByType(BandDesignIntf::ReportHeader),StartNewPageAsNeeded); @@ -543,15 +540,21 @@ void ReportRender::renderPageFooter(PageItemDesignIntf *patternPage) void ReportRender::renderPageItems(PageItemDesignIntf* patternPage) { + QList pageItems; foreach (BaseDesignIntf* item, patternPage->childBaseItems()) { ItemDesignIntf* id = dynamic_cast(item); if (id&&id->itemLocation()==ItemDesignIntf::Page){ BaseDesignIntf* cloneItem = item->cloneItem(m_renderPageItem->itemMode(), m_renderPageItem, m_renderPageItem); - cloneItem->updateItemSize(m_datasources); + pageItems.append(cloneItem); + //cloneItem->updateItemSize(m_datasources); } } + m_renderPageItem->restoreLinks(); + foreach(BaseDesignIntf* item, pageItems){ + item->updateItemSize(m_datasources); + } } qreal ReportRender::calcPageFooterHeight(PageItemDesignIntf *patternPage) @@ -978,7 +981,6 @@ void ReportRender::startNewPage() renderBand(band); } checkLostHeadersOnPrevPage(); - pasteGroups(); renderPageItems(m_patternPageItem); }