diff --git a/limereport/images/vlayuot_4_24.png b/limereport/images/vlayuot_4_24.png new file mode 100644 index 0000000..8f83e79 Binary files /dev/null and b/limereport/images/vlayuot_4_24.png differ diff --git a/limereport/items/lrabstractlayout.cpp b/limereport/items/lrabstractlayout.cpp new file mode 100644 index 0000000..02b8ca8 --- /dev/null +++ b/limereport/items/lrabstractlayout.cpp @@ -0,0 +1,321 @@ +#include "lrabstractlayout.h" + +namespace LimeReport { + +AbstractLayout::AbstractLayout(QString xmlTag, QObject* owner, QGraphicsItem* parent) + : LayoutDesignIntf(xmlTag, owner, parent), m_isRelocating(false), m_layoutType(Layout), + m_hideEmptyItems(false) +{ + setPossibleResizeDirectionFlags(AllDirections); + m_layoutMarker = new LayoutMarker(this); + m_layoutMarker->setParentItem(this); + m_layoutMarker->setColor(Qt::red); + m_layoutMarker->setHeight(height()); + m_layoutMarker->setZValue(1); +} + +AbstractLayout::~AbstractLayout() +{ + if (m_layoutMarker) { + delete m_layoutMarker; m_layoutMarker=0; + } +} + +QList& AbstractLayout::layoutsChildren() +{ + return m_children; +} + +bool AbstractLayout::isRelocating() const +{ + return m_isRelocating; +} + +void AbstractLayout::setIsRelocating(bool isRelocating) +{ + m_isRelocating = isRelocating; +} + +AbstractLayout::LayoutType AbstractLayout::layoutType() const +{ + return m_layoutType; +} + +void AbstractLayout::setLayoutType(const LayoutType& layoutType) +{ + m_layoutType = layoutType; +} + +void AbstractLayout::addChild(BaseDesignIntf* item, bool updateSize) +{ + + placeItemInLayout(item); + + m_children.append(item); + item->setParentItem(this); + item->setParent(this); + item->setFixedPos(true); + item->setPossibleResizeDirectionFlags(ResizeRight | ResizeBottom); + + connect( + item, SIGNAL(destroyed(QObject*)), + this, SLOT(slotOnChildDestroy(QObject*)) + ); + connect( + item,SIGNAL(geometryChanged(QObject*,QRectF,QRectF)), + this,SLOT(slotOnChildGeometryChanged(QObject*,QRectF,QRectF)) + ); + connect( + item, SIGNAL(itemVisibleHasChanged(BaseDesignIntf*)), + this, SLOT(slotOnChildVisibleHasChanged(BaseDesignIntf*)) + ); + connect( + item, SIGNAL(itemSelectedHasBeenChanged(BaseDesignIntf*,bool)), + this, SLOT(slotOnChildSelectionHasChanged(BaseDesignIntf*,bool)) + ); + + if (updateSize){ + relocateChildren(); + updateLayoutSize(); + } +} + +void AbstractLayout::restoreChild(BaseDesignIntf* item) +{ + if (m_children.contains(item)) return; + + m_isRelocating=true; + + insertItemInLayout(item); + + connect(item,SIGNAL(destroyed(QObject*)),this,SLOT(slotOnChildDestroy(QObject*))); + connect(item,SIGNAL(geometryChanged(QObject*,QRectF,QRectF)), + this,SLOT(slotOnChildGeometryChanged(QObject*,QRectF,QRectF))); + connect(item, SIGNAL(itemAlignChanged(BaseDesignIntf*,ItemAlign,ItemAlign)), + this, SLOT(slotOnChildItemAlignChanged(BaseDesignIntf*,ItemAlign,ItemAlign))); + + item->setFixedPos(true); + item->setPossibleResizeDirectionFlags(ResizeRight | ResizeBottom); + item->setParent(this); + item->setParentItem(this); + + updateLayoutSize(); + m_isRelocating=false; +} + +bool AbstractLayout::isEmpty() const +{ + bool isEmpty = true; + bool allItemsIsText = true; + foreach (QGraphicsItem* qgItem, childItems()) { + ContentItemDesignIntf* item = dynamic_cast(qgItem); + if (item && !item->content().isEmpty()) isEmpty = false; + if (!item && dynamic_cast(qgItem)) + allItemsIsText = false; + } + return (isEmpty && allItemsIsText); +} + +void AbstractLayout::paint(QPainter* ppainter, const QStyleOptionGraphicsItem* option, QWidget* widget) +{ + if (isSelected()){ + foreach( BaseDesignIntf* item, m_children){ + ppainter->save(); + ppainter->setPen(Qt::red); + ppainter->drawRect( + QRectF(item->pos().x(),item->pos().y(), + item->rect().bottomRight().rx(), + item->rect().bottomRight().ry() + ) + ); + ppainter->restore(); + } + } + LayoutDesignIntf::paint(ppainter, option, widget); +} + +int AbstractLayout::childrenCount() +{ + return m_children.size(); +} + +void AbstractLayout::beforeDelete() +{ +#ifdef HAVE_QT5 + foreach (QObject *item, children()) { +#else + foreach (QObject *item, QObject::children()) { +#endif + BaseDesignIntf *bi = dynamic_cast(item); + if (bi) { + bi->setParentItem(parentItem()); + bi->setParent(parent()); + bi->setVisible(true); + bi->setPos(mapToParent(bi->pos())); + bi->setFixedPos(false); + bi->setPossibleResizeDirectionFlags(AllDirections); + } + } + m_children.clear(); +} + +void AbstractLayout::childAddedEvent(BaseDesignIntf* child) +{ + addChild(child,false); +} + +void AbstractLayout::geometryChangedEvent(QRectF newRect, QRectF) +{ + layoutMarker()->setHeight(newRect.height()); + relocateChildren(); + if (!isRelocating()){ + divideSpace(); + } +} + +void AbstractLayout::initMode(BaseDesignIntf::ItemMode mode) +{ + BaseDesignIntf::initMode(mode); + if ((mode==PreviewMode)||(mode==PrintMode)){ + layoutMarker()->setVisible(false); + } else { + layoutMarker()->setVisible(true); + } +} + +void AbstractLayout::setBorderLinesFlags(BaseDesignIntf::BorderLines flags) +{ + BaseDesignIntf::setBorderLinesFlags(flags); + if (flags!=0) + relocateChildren(); +} + +void AbstractLayout::collectionLoadFinished(const QString& collectionName) +{ + ItemDesignIntf::collectionLoadFinished(collectionName); + if (collectionName.compare("children",Qt::CaseInsensitive)==0){ +#ifdef HAVE_QT5 + foreach(QObject* obj, children()){ +#else + foreach(QObject* obj,QObject::children()){ +#endif + BaseDesignIntf* item = dynamic_cast(obj); + if (item) { + addChild(item,false); + } + } + } +} + +void AbstractLayout::objectLoadFinished() +{ + layoutMarker()->setHeight(height()); + LayoutDesignIntf::objectLoadFinished(); +} + +bool AbstractLayout::isNeedUpdateSize(RenderPass pass) const +{ + foreach (QGraphicsItem *child, childItems()) { + BaseDesignIntf* item = dynamic_cast(child); + if (item && (item->isNeedUpdateSize(pass) || item->isEmpty())) + return true; + } + return false; +} + +QVariant AbstractLayout::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant& value) +{ + if (change == QGraphicsItem::ItemSelectedHasChanged){ + setIsRelocating(true); + foreach(BaseDesignIntf* item, layoutsChildren()){ + item->setVisible(!value.toBool()); + } + setIsRelocating(false); + } + return LayoutDesignIntf::itemChange(change, value); +} + +void AbstractLayout::updateItemSize(DataSourceManager* dataManager, RenderPass pass, int maxHeight) +{ + setIsRelocating(true); + ItemDesignIntf::updateItemSize(dataManager, pass, maxHeight); + foreach(QGraphicsItem *child, childItems()){ + BaseDesignIntf* item = dynamic_cast(child); + if (item) item->updateItemSize(dataManager, pass, maxHeight); + } + updateLayoutSize(); + relocateChildren(); + setIsRelocating(false); + BaseDesignIntf::updateItemSize(dataManager, pass, maxHeight); +} + +void AbstractLayout::slotOnChildDestroy(QObject* child) +{ + m_children.removeAll(static_cast(child)); + if (m_children.count()<2){ + beforeDelete(); + } else { + relocateChildren(); + updateLayoutSize(); + } +} + +void AbstractLayout::slotOnChildGeometryChanged(QObject* item, QRectF newGeometry, QRectF oldGeometry) +{ + if (!m_isRelocating){ + if (m_layoutType == Layout){ + relocateChildren(); + updateLayoutSize(); + } else { + m_isRelocating = true; + qreal delta = newGeometry.width()-oldGeometry.width(); + BaseDesignIntf* resizingItem = findNext(dynamic_cast(item)); + if (resizingItem) { + resizingItem->setWidth(resizingItem->width()-delta); + resizingItem->setPos(resizingItem->pos().x()+delta,resizingItem->pos().y()); + } + updateLayoutSize(); + m_isRelocating = false; + } + } +} + +void AbstractLayout::slotOnChildItemAlignChanged(BaseDesignIntf* item, const BaseDesignIntf::ItemAlign&, const BaseDesignIntf::ItemAlign&) +{ + item->setPossibleResizeDirectionFlags(ResizeBottom | ResizeRight); +} + +void AbstractLayout::slotOnChildVisibleHasChanged(BaseDesignIntf*) +{ + relocateChildren(); + if (m_layoutType == Table && !m_isRelocating){ + divideSpace(); + } +} + +void AbstractLayout::slotOnChildSelectionHasChanged(BaseDesignIntf* item, bool value) +{ + item->setZValue(value ? item->zValue()+1 : item->zValue()-1); +} + +bool AbstractLayout::hideEmptyItems() const +{ + return m_hideEmptyItems; +} + +void AbstractLayout::setHideEmptyItems(bool hideEmptyItems) +{ + m_hideEmptyItems = hideEmptyItems; + + if (m_hideEmptyItems != hideEmptyItems){ + m_hideEmptyItems = hideEmptyItems; + notify("hideEmptyItems", !m_hideEmptyItems, m_hideEmptyItems); + } +} + +LayoutMarker* AbstractLayout::layoutMarker() const +{ + return m_layoutMarker; +} + +} // namespace LimeReport diff --git a/limereport/items/lrabstractlayout.h b/limereport/items/lrabstractlayout.h new file mode 100644 index 0000000..52deaed --- /dev/null +++ b/limereport/items/lrabstractlayout.h @@ -0,0 +1,68 @@ +#ifndef LRABSTRACTLAYOUT_H +#define LRABSTRACTLAYOUT_H + +#include "lritemdesignintf.h" +#include "lrlayoutmarker.h" + +namespace LimeReport{ +class AbstractLayout: public LayoutDesignIntf +{ + Q_OBJECT + Q_ENUMS(LayoutType) + Q_PROPERTY(bool hideEmptyItems READ hideEmptyItems WRITE setHideEmptyItems) +public: + enum LayoutType{Layout,Table}; + AbstractLayout(QString xmlTag, QObject *owner = 0, QGraphicsItem *parent = 0); + ~AbstractLayout(); + QList& layoutsChildren(); + LayoutMarker* layoutMarker() const; + bool isRelocating() const; + void setIsRelocating(bool isRelocating); + LayoutType layoutType() const; + void setLayoutType(const LayoutType& layoutType); + + void addChild(BaseDesignIntf *item,bool updateSize=true); + void restoreChild(BaseDesignIntf *item); + bool isEmpty() const; + void paint(QPainter* ppainter, const QStyleOptionGraphicsItem* option, QWidget* widget); + + bool hideEmptyItems() const; + void setHideEmptyItems(bool hideEmptyItems); + +protected: + int childrenCount(); + void beforeDelete(); + void childAddedEvent(BaseDesignIntf *child); + void geometryChangedEvent(QRectF newRect, QRectF); + void initMode(ItemMode mode); + void setBorderLinesFlags(BorderLines flags); + void collectionLoadFinished(const QString &collectionName); + void objectLoadFinished(); + bool isNeedUpdateSize(RenderPass pass) const; + QVariant itemChange(GraphicsItemChange change, const QVariant &value); + void updateItemSize(DataSourceManager* dataManager, RenderPass pass, int maxHeight); +private: + virtual void divideSpace() = 0; + virtual void updateLayoutSize() = 0; + virtual void relocateChildren() = 0; + virtual BaseDesignIntf *findNext(BaseDesignIntf *item) = 0; + virtual BaseDesignIntf *findPrior(BaseDesignIntf *item) = 0; + virtual void placeItemInLayout(BaseDesignIntf* item) = 0; + virtual void insertItemInLayout(BaseDesignIntf* item) = 0; +private slots: + void slotOnChildDestroy(QObject *child); + void slotOnChildGeometryChanged(QObject*item, QRectF newGeometry, QRectF oldGeometry); + void slotOnChildItemAlignChanged(BaseDesignIntf* item, const ItemAlign&, const ItemAlign&); + void slotOnChildVisibleHasChanged(BaseDesignIntf*); + void slotOnChildSelectionHasChanged(BaseDesignIntf* item, bool value); +private: + QList m_children; + bool m_isRelocating; + LayoutMarker* m_layoutMarker; + LayoutType m_layoutType; + bool m_hideEmptyItems; +}; + +} // namespace LimeReport + +#endif // LRABSTRACTLAYOUT_H diff --git a/limereport/items/lrhorizontallayout.cpp b/limereport/items/lrhorizontallayout.cpp index d93e545..9a6a55a 100644 --- a/limereport/items/lrhorizontallayout.cpp +++ b/limereport/items/lrhorizontallayout.cpp @@ -55,88 +55,28 @@ bool VARIABLE_IS_NOT_USED registred = LimeReport::DesignElementsFactory::instanc namespace LimeReport { -bool lessThen(BaseDesignIntf *c1, BaseDesignIntf* c2){ +bool horizontalLessThen(BaseDesignIntf *c1, BaseDesignIntf* c2){ return c1->pos().x()pos().x(); } - HorizontalLayout::HorizontalLayout(QObject *owner, QGraphicsItem *parent) - : LayoutDesignIntf(xmlTag, owner, parent),m_isRelocating(false),m_layoutType(Layout) -{ - setPossibleResizeDirectionFlags(AllDirections); - m_layoutMarker = new LayoutMarker(this); - m_layoutMarker->setParentItem(this); - m_layoutMarker->setColor(Qt::red); - m_layoutMarker->setHeight(height()); - m_layoutMarker->setZValue(1); -} + : AbstractLayout(xmlTag, owner, parent) +{} HorizontalLayout::~HorizontalLayout() -{ - if (m_layoutMarker) { - delete m_layoutMarker; m_layoutMarker=0; - } -} +{} BaseDesignIntf *HorizontalLayout::createSameTypeItem(QObject *owner, QGraphicsItem *parent) { return new LimeReport::HorizontalLayout(owner, parent); } -void HorizontalLayout::hoverEnterEvent(QGraphicsSceneHoverEvent *event) -{ - Q_UNUSED(event) - LayoutDesignIntf::hoverEnterEvent(event); -// if ((itemMode() & LayoutEditMode) || isSelected()){ -// setChildVisibility(false); -// } -} - -void HorizontalLayout::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) -{ - Q_UNUSED(event) - LayoutDesignIntf::hoverLeaveEvent(event); -// setChildVisibility(true); -} - -void HorizontalLayout::geometryChangedEvent(QRectF newRect, QRectF ) -{ - m_layoutMarker->setHeight(newRect.height()); - relocateChildren(); - if (/*m_layoutType == Table && */!m_isRelocating){ - divideSpace(); - } -} - -void HorizontalLayout::setChildVisibility(bool value){ - foreach(QGraphicsItem* child,childItems()){ - BaseDesignIntf* item = dynamic_cast(child); - if(item) - item->setVisible(value); - } -} - -int HorizontalLayout::childrenCount() -{ - return m_children.size(); -} - -void HorizontalLayout::initMode(BaseDesignIntf::ItemMode mode) -{ - BaseDesignIntf::initMode(mode); - if ((mode==PreviewMode)||(mode==PrintMode)){ - m_layoutMarker->setVisible(false); - } else { - m_layoutMarker->setVisible(true); - } -} - bool HorizontalLayout::canBeSplitted(int height) const { foreach(QGraphicsItem* qgItem,childItems()){ BaseDesignIntf* item=dynamic_cast(qgItem); if (item) - if (!item->canBeSplitted(height-item->pos().y())) return false; + if (!item->canBeSplitted(height - item->pos().y())) return false; } return true; } @@ -198,149 +138,13 @@ void HorizontalLayout::setItemAlign(const BaseDesignIntf::ItemAlign &itemAlign) BaseDesignIntf::setItemAlign(itemAlign); } -void HorizontalLayout::setBorderLinesFlags(BaseDesignIntf::BorderLines flags) -{ - BaseDesignIntf::setBorderLinesFlags(flags); - if (flags!=0) - relocateChildren(); -} - -QVariant HorizontalLayout::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant& value) -{ - if (change == QGraphicsItem::ItemSelectedHasChanged){ - m_isRelocating = true; - foreach(BaseDesignIntf* item, m_children){ - item->setVisible(!value.toBool()); - } - m_isRelocating = false; - } - return LayoutDesignIntf::itemChange(change, value); -} - -void HorizontalLayout::paint(QPainter* ppainter, const QStyleOptionGraphicsItem* option, QWidget* widget) -{ - if (isSelected()){ - foreach( BaseDesignIntf* item, m_children){ - ppainter->save(); - ppainter->setPen(Qt::red); - ppainter->drawRect( - QRectF(item->pos().x(),item->pos().y(), - item->rect().bottomRight().rx(), - item->rect().bottomRight().ry() - ) - ); - ppainter->restore(); - } - } - LayoutDesignIntf::paint(ppainter, option, widget); -} - -void HorizontalLayout::restoreChild(BaseDesignIntf* item){ - if (m_children.contains(item)) return; - - m_isRelocating=true; - foreach (BaseDesignIntf* child, childBaseItems()) { - if (child->pos()==item->pos()){ - int index = m_children.indexOf(child)-1; - m_children.insert(index,item); - child->setPos(item->pos().x()+item->width(),0); - break; - } - } - - connect(item,SIGNAL(destroyed(QObject*)),this,SLOT(slotOnChildDestroy(QObject*))); - connect(item,SIGNAL(geometryChanged(QObject*,QRectF,QRectF)), - this,SLOT(slotOnChildGeometryChanged(QObject*,QRectF,QRectF))); - connect(item, SIGNAL(itemAlignChanged(BaseDesignIntf*,ItemAlign,ItemAlign)), - this, SLOT(slotOnChildItemAlignChanged(BaseDesignIntf*,ItemAlign,ItemAlign))); - - item->setFixedPos(true); - item->setPossibleResizeDirectionFlags(ResizeRight | ResizeBottom); - item->setParent(this); - item->setParentItem(this); - - updateLayoutSize(); - m_isRelocating=false; -} - -bool HorizontalLayout::isEmpty() const -{ - bool isEmpty = true; - bool allItemsIsText = true; - foreach (QGraphicsItem* qgItem, childItems()) { - ContentItemDesignIntf* item = dynamic_cast(qgItem); - if (item && !item->content().isEmpty()) isEmpty = false; - if (!item && dynamic_cast(qgItem)) - allItemsIsText = false; - } - return (isEmpty && allItemsIsText); -} - -void HorizontalLayout::addChild(BaseDesignIntf *item, bool updateSize) -{ - if (m_children.count() > 0) - item->setPos(m_children.last()->pos().x() + m_children.last()->width(), 0); - else - item->setPos(0, 0); - - m_children.append(item); - item->setParentItem(this); - item->setParent(this); - item->setFixedPos(true); - item->setPossibleResizeDirectionFlags(ResizeRight | ResizeBottom); - - connect( - item, SIGNAL(destroyed(QObject*)), - this, SLOT(slotOnChildDestroy(QObject*)) - ); - connect( - item,SIGNAL(geometryChanged(QObject*,QRectF,QRectF)), - this,SLOT(slotOnChildGeometryChanged(QObject*,QRectF,QRectF)) - ); - connect( - item, SIGNAL(itemVisibleHasChanged(BaseDesignIntf*)), - this,SLOT(slotOnChildVisibleHasChanged(BaseDesignIntf*)) - ); - connect( - item, SIGNAL(itemSelectedHasBeenChanged(BaseDesignIntf*,bool)), - this, SLOT(slotOnChildSelectionHasChanged(BaseDesignIntf*,bool)) - ); - - if (updateSize){ - relocateChildren(); - updateLayoutSize(); - } -} - -void HorizontalLayout::collectionLoadFinished(const QString &collectionName) -{ - ItemDesignIntf::collectionLoadFinished(collectionName); - if (collectionName.compare("children",Qt::CaseInsensitive)==0){ -#ifdef HAVE_QT5 - foreach(QObject* obj,children()){ -#else - foreach(QObject* obj,QObject::children()){ -#endif - BaseDesignIntf* item = dynamic_cast(obj); - if (item) { - addChild(item,false); - } - } - } -} - -void HorizontalLayout::objectLoadFinished() -{ - m_layoutMarker->setHeight(height()); - LayoutDesignIntf::objectLoadFinished(); -} - void HorizontalLayout::updateLayoutSize() { int spaceBorder = (borderLines() != 0) ? borderLineSize() : 0; int w = spaceBorder*2; qreal h = 0; - foreach(BaseDesignIntf* item, m_children){ + foreach(BaseDesignIntf* item, layoutsChildren()){ + if (item->isEmpty() && hideEmptyItems()) item->setVisible(false); if (item->isVisible()){ if (hheight()) h=item->height(); w+=item->width(); @@ -353,121 +157,60 @@ void HorizontalLayout::updateLayoutSize() void HorizontalLayout::relocateChildren() { int spaceBorder = (borderLines() != 0) ? borderLineSize() : 0; - if (m_children.count()isVisible() || itemMode() == DesignMode){ item->setPos(curX,spaceBorder); curX+=item->width(); item->setHeight(height()-(spaceBorder * 2)); } } - m_isRelocating = false; -} - -void HorizontalLayout::beforeDelete() -{ - m_children.clear(); -#ifdef HAVE_QT5 - foreach (QObject *item, children()) { -#else - foreach (QObject *item, QObject::children()) { -#endif - BaseDesignIntf *bdItem = dynamic_cast(item); - if (bdItem) { - bdItem->setParentItem(parentItem()); - bdItem->setParent(parent()); - bdItem->setVisible(true); - bdItem->setPos(mapToParent(bdItem->pos())); - bdItem->setFixedPos(false); - bdItem->setPossibleResizeDirectionFlags(AllDirections); - } - } -} - -void HorizontalLayout::updateItemSize(DataSourceManager* dataManager, RenderPass pass, int maxHeight) -{ - m_isRelocating=true; - ItemDesignIntf::updateItemSize(dataManager, pass, maxHeight); - foreach(QGraphicsItem *child, childItems()){ - BaseDesignIntf* item = dynamic_cast(child); - if (item) item->updateItemSize(dataManager, pass, maxHeight); - } - updateLayoutSize(); - relocateChildren(); - m_isRelocating=false; - BaseDesignIntf::updateItemSize(dataManager, pass, maxHeight); -} - -bool HorizontalLayout::isNeedUpdateSize(RenderPass pass) const -{ - foreach (QGraphicsItem *child, childItems()) { - BaseDesignIntf* item = dynamic_cast(child); - if (item && item->isNeedUpdateSize(pass)) - return true; - } - return false; -} - -void HorizontalLayout::childAddedEvent(BaseDesignIntf *child) -{ - addChild(child,false); -} - -void HorizontalLayout::slotOnChildDestroy(QObject* child) -{ - m_children.removeAll(static_cast(child)); - if (m_children.count()<2){ - beforeDelete(); -// deleteLater(); - } else { - relocateChildren(); - updateLayoutSize(); - } + setIsRelocating(false); } BaseDesignIntf* HorizontalLayout::findNext(BaseDesignIntf* item){ - if (m_children.count()i+1){ return m_children[i+1];} + qSort(layoutsChildren().begin(),layoutsChildren().end(),horizontalLessThen); + for (int i=0; ii+1){ return layoutsChildren()[i+1];} } return 0; } BaseDesignIntf* HorizontalLayout::findPrior(BaseDesignIntf* item){ - if (m_children.count()isVisible() || itemMode() == DesignMode ){ itemsSumSize += item->width(); visibleItemsCount++; @@ -475,128 +218,34 @@ void HorizontalLayout::divideSpace(){ } qreal delta = (width() - (itemsSumSize+spaceBorder*2)) / (visibleItemsCount!=0 ? visibleItemsCount : 1); - for (int i=0; iisVisible() || itemMode() == DesignMode) - m_children[i]->setWidth(m_children[i]->width()+delta); - if ((i+1)isVisible() || itemMode() == DesignMode) - m_children[i+1]->setPos(m_children[i+1]->pos().x()+delta*(i+1),m_children[i+1]->pos().y()); + for (int i=0; iisVisible() || itemMode() == DesignMode) + layoutsChildren()[i]->setWidth(layoutsChildren()[i]->width()+delta); + if ((i+1)isVisible() || itemMode() == DesignMode) + layoutsChildren()[i+1]->setPos(layoutsChildren()[i+1]->pos().x()+delta*(i+1),layoutsChildren()[i+1]->pos().y()); } - m_isRelocating = false; + setIsRelocating(false); } -void HorizontalLayout::slotOnChildGeometryChanged(QObject *item, QRectF newGeometry, QRectF oldGeometry) + +void HorizontalLayout::placeItemInLayout(BaseDesignIntf* item) { - if (!m_isRelocating){ - //setHeight(newGeometry.height()); - if (m_layoutType == Layout){ - relocateChildren(); - updateLayoutSize(); - } else { - m_isRelocating = true; - qreal delta = newGeometry.width()-oldGeometry.width(); - BaseDesignIntf* resizingItem = findNext(dynamic_cast(item)); - if (resizingItem) { - resizingItem->setWidth(resizingItem->width()-delta); - resizingItem->setPos(resizingItem->pos().x()+delta,resizingItem->pos().y()); - } - updateLayoutSize(); - m_isRelocating = false; + if (layoutsChildren().count() > 0) + item->setPos(layoutsChildren().last()->pos().x() + layoutsChildren().last()->width(), 0); + else + item->setPos(0, 0); +} + +void HorizontalLayout::insertItemInLayout(BaseDesignIntf* item) +{ + foreach (BaseDesignIntf* child, childBaseItems()) { + if (child->pos() == item->pos()){ + int index = layoutsChildren().indexOf(child)-1; + layoutsChildren().insert(index, item); + child->setPos(item->pos().x()+item->width(), 0); + break; } } } -void HorizontalLayout::slotOnChildItemAlignChanged(BaseDesignIntf *item, const BaseDesignIntf::ItemAlign &, const BaseDesignIntf::ItemAlign&) -{ - item->setPossibleResizeDirectionFlags(ResizeBottom | ResizeRight); -} - -void HorizontalLayout::slotOnChildVisibleHasChanged(BaseDesignIntf *) -{ - relocateChildren(); - if (m_layoutType == Table && !m_isRelocating){ - divideSpace(); - } -} - -void HorizontalLayout::slotOnChildSelectionHasChanged(BaseDesignIntf* item, bool value) -{ - item->setZValue(value ? item->zValue()+1 : item->zValue()-1); -} - -HorizontalLayout::LayoutType HorizontalLayout::layoutType() const -{ - return m_layoutType; -} - -void HorizontalLayout::setLayoutType(const LayoutType &layoutType) -{ - if (m_layoutType != layoutType){ - LayoutType oldValue = m_layoutType; - m_layoutType = layoutType; - notify("layoutType",oldValue,layoutType); - } - -} - -LayoutMarker::LayoutMarker(HorizontalLayout *layout, QGraphicsItem *parent) - :QGraphicsItem(parent), m_rect(0,0,30,30), m_color(Qt::red), m_layout(layout){ - setFlag(QGraphicsItem::ItemIsMovable); -} - -void LayoutMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) -{ - painter->save(); - painter->setOpacity(Const::LAYOUT_MARKER_OPACITY); - painter->fillRect(boundingRect(),m_color); - - painter->setRenderHint(QPainter::Antialiasing); - qreal size = (boundingRect().width()isSelected()){ - painter->setOpacity(1); - QRectF r = QRectF(0,0,size,size); - painter->setBrush(Qt::white); - painter->setPen(Qt::white); - painter->drawEllipse(r.adjusted(5,5,-5,-5)); - painter->setBrush(m_color); - painter->drawEllipse(r.adjusted(7,7,-7,-7)); - } - painter->restore(); -} - -void LayoutMarker::setHeight(qreal height) -{ - if (m_rect.height()!=height){ - prepareGeometryChange(); - m_rect.setHeight(height); - } -} - -void LayoutMarker::setWidth(qreal width) -{ - if (m_rect.width()!=width){ - prepareGeometryChange(); - m_rect.setWidth(width); - } -} - -void LayoutMarker::setColor(QColor color) -{ - if (m_color!=color){ - m_color = color; - update(boundingRect()); - } -} - -void LayoutMarker::mousePressEvent(QGraphicsSceneMouseEvent *event) -{ - if (event->button()==Qt::LeftButton) { - if (!(event->modifiers() & Qt::ControlModifier)) - m_layout->scene()->clearSelection(); - m_layout->setSelected(true); - //m_layout->setChildVisibility(false); - update(0,0,boundingRect().width(),boundingRect().width()); - } -} - } // namespace LimeReport diff --git a/limereport/items/lrhorizontallayout.h b/limereport/items/lrhorizontallayout.h index 5bfaddc..fa5edf3 100644 --- a/limereport/items/lrhorizontallayout.h +++ b/limereport/items/lrhorizontallayout.h @@ -30,89 +30,41 @@ #ifndef LRHORIZONTALLAYOUT_H #define LRHORIZONTALLAYOUT_H #include "lritemdesignintf.h" +#include "lrlayoutmarker.h" +#include "lrabstractlayout.h" namespace LimeReport { -class HorizontalLayout; - -class LayoutMarker : public QGraphicsItem{ -public: - explicit LayoutMarker(HorizontalLayout* layout, QGraphicsItem *parent=0); - virtual QRectF boundingRect() const{return m_rect;} - virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *); - void setHeight(qreal height); - void setWidth(qreal width); - void setColor(QColor color); - qreal width(){return m_rect.width();} - qreal height(){return m_rect.height();} -protected: - void mousePressEvent(QGraphicsSceneMouseEvent *event); -private: - QRectF m_rect; - QColor m_color; - HorizontalLayout* m_layout; -}; - -class HorizontalLayout : public LayoutDesignIntf +class HorizontalLayout : public AbstractLayout { Q_OBJECT - Q_ENUMS(LayoutType) Q_PROPERTY(LayoutType layoutType READ layoutType WRITE setLayoutType) public: friend class LayoutMarker; - enum LayoutType{Layout,Table}; + friend class BaseDesignIntf; + HorizontalLayout(QObject *owner = 0, QGraphicsItem *parent = 0); ~HorizontalLayout(); BaseDesignIntf *createSameTypeItem(QObject *owner = 0, QGraphicsItem *parent = 0); - void hoverEnterEvent(QGraphicsSceneHoverEvent *event); - void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); - void geometryChangedEvent(QRectF newRect, QRectF); - void addChild(BaseDesignIntf *item,bool updateSize=true); - friend class BaseDesignIntf; - void restoreChild(BaseDesignIntf *item); - bool isEmpty() const; - LayoutType layoutType() const; - void setLayoutType(const LayoutType &layoutType); bool isSplittable() const { return true;} + protected: - void collectionLoadFinished(const QString &collectionName); - void objectLoadFinished(); void updateLayoutSize(); void relocateChildren(); BaseDesignIntf *findNext(BaseDesignIntf *item); BaseDesignIntf *findPrior(BaseDesignIntf *item); - void beforeDelete(); - void updateItemSize(DataSourceManager *dataManager, RenderPass pass, int maxHeight); - bool isNeedUpdateSize(RenderPass pass) const; - void childAddedEvent(BaseDesignIntf *child); - void setChildVisibility(bool value); - int childrenCount(); - void initMode(ItemMode mode); bool canBeSplitted(int height) const; BaseDesignIntf* cloneUpperPart(int height, QObject* owner=0, QGraphicsItem* parent=0); BaseDesignIntf* cloneBottomPart(int height, QObject *owner=0, QGraphicsItem *parent=0); void setItemAlign(const ItemAlign &itemAlign); - void setBorderLinesFlags(BorderLines flags); - QVariant itemChange(GraphicsItemChange change, const QVariant &value); - void paint(QPainter* ppainter, const QStyleOptionGraphicsItem* option, QWidget* widget); -private slots: - void slotOnChildDestroy(QObject *child); - void slotOnChildGeometryChanged(QObject*item, QRectF newGeometry, QRectF oldGeometry); - void slotOnChildItemAlignChanged(BaseDesignIntf* item, const ItemAlign&, const ItemAlign&); - void slotOnChildVisibleHasChanged(BaseDesignIntf*); - void slotOnChildSelectionHasChanged(BaseDesignIntf* item, bool value); - //void slotOnPosChanged(QObject*, QPointF newPos, QPointF ); private: void divideSpace(); -private: - QList m_children; - bool m_isRelocating; - LayoutMarker* m_layoutMarker; - LayoutType m_layoutType; + void placeItemInLayout(BaseDesignIntf* item); + void insertItemInLayout(BaseDesignIntf* item); }; } //namespace LimeReport diff --git a/limereport/items/lrlayoutmarker.cpp b/limereport/items/lrlayoutmarker.cpp new file mode 100644 index 0000000..48b534c --- /dev/null +++ b/limereport/items/lrlayoutmarker.cpp @@ -0,0 +1,69 @@ +#include "lrlayoutmarker.h" +#include +#include + +namespace LimeReport{ + +LayoutMarker::LayoutMarker(BaseDesignIntf* layout, QGraphicsItem *parent) + :QGraphicsItem(parent), m_rect(0,0,30,30), m_color(Qt::red), m_layout(layout){ + setFlag(QGraphicsItem::ItemIsMovable); +} + +void LayoutMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) +{ + painter->save(); + painter->setOpacity(Const::LAYOUT_MARKER_OPACITY); + painter->fillRect(boundingRect(),m_color); + + painter->setRenderHint(QPainter::Antialiasing); + qreal size = (boundingRect().width()isSelected()){ + painter->setOpacity(1); + QRectF r = QRectF(0,0,size,size); + painter->setBrush(Qt::white); + painter->setPen(Qt::white); + painter->drawEllipse(r.adjusted(5,5,-5,-5)); + painter->setBrush(m_color); + painter->drawEllipse(r.adjusted(7,7,-7,-7)); + } + painter->restore(); +} + +void LayoutMarker::setHeight(qreal height) +{ + if (m_rect.height()!=height){ + prepareGeometryChange(); + m_rect.setHeight(height); + } +} + +void LayoutMarker::setWidth(qreal width) +{ + if (m_rect.width()!=width){ + prepareGeometryChange(); + m_rect.setWidth(width); + } +} + +void LayoutMarker::setColor(QColor color) +{ + if (m_color!=color){ + m_color = color; + update(boundingRect()); + } +} + +void LayoutMarker::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if (event->button()==Qt::LeftButton) { + if (!(event->modifiers() & Qt::ControlModifier)) + m_layout->scene()->clearSelection(); + m_layout->setSelected(true); + //m_layout->setChildVisibility(false); + update(0,0,boundingRect().width(),boundingRect().width()); + } +} + + +} // namespace LimeReport diff --git a/limereport/items/lrlayoutmarker.h b/limereport/items/lrlayoutmarker.h new file mode 100644 index 0000000..3eb65b0 --- /dev/null +++ b/limereport/items/lrlayoutmarker.h @@ -0,0 +1,28 @@ +#ifndef LRLAYOUTMARKER_H +#define LRLAYOUTMARKER_H + +#include +#include "lrbanddesignintf.h" + +namespace LimeReport{ + +class LayoutMarker : public QGraphicsItem{ +public: + explicit LayoutMarker(BaseDesignIntf* layout, QGraphicsItem *parent=0); + virtual QRectF boundingRect() const{return m_rect;} + virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *); + void setHeight(qreal height); + void setWidth(qreal width); + void setColor(QColor color); + qreal width(){return m_rect.width();} + qreal height(){return m_rect.height();} +protected: + void mousePressEvent(QGraphicsSceneMouseEvent *event); +private: + QRectF m_rect; + QColor m_color; + BaseDesignIntf* m_layout; +}; + +} // namespace LimeReport +#endif // LRLAYOUTMARKER_H diff --git a/limereport/items/lrtextitem.cpp b/limereport/items/lrtextitem.cpp index 0745e0f..63d856f 100644 --- a/limereport/items/lrtextitem.cpp +++ b/limereport/items/lrtextitem.cpp @@ -62,7 +62,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_replaceCarriageReturns(false), m_followTo(""), m_follower(0), m_textIndent(0), - m_textLayoutDirection(Qt::LayoutDirectionAuto) + m_textLayoutDirection(Qt::LayoutDirectionAuto), m_hideIfEmpty(false) { PageItemDesignIntf* pageItem = dynamic_cast(parent); BaseDesignIntf* parentItem = dynamic_cast(parent); @@ -115,6 +115,11 @@ void TextItem::preparePopUpMenu(QMenu &menu) action = menu.addAction(tr("Watermark")); action->setCheckable(true); action->setChecked(isWatermark()); + + action = menu.addAction(tr("Hide if empty")); + action->setCheckable(true); + action->setChecked(hideIfEmpty()); + } void TextItem::processPopUpAction(QAction *action) @@ -144,6 +149,10 @@ void TextItem::processPopUpAction(QAction *action) if (action->text().compare(tr("Watermark")) == 0){ page()->setPropertyToSelectedItems("watermark",action->isChecked()); } + + if (action->text().compare(tr("Hide if empty")) == 0){ + page()->setPropertyToSelectedItems("hideIfEmpty",action->isChecked()); + } } void TextItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* style, QWidget* widget) { @@ -329,6 +338,7 @@ void TextItem::updateItemSize(DataSourceManager* dataManager, RenderPass pass, i } } BaseDesignIntf::updateItemSize(dataManager, pass, maxHeight); + if (isEmpty() && hideIfEmpty()) setVisible(false); } void TextItem::updateLayout() @@ -538,6 +548,19 @@ TextItem::TextPtr TextItem::textDocument() const } +bool TextItem::hideIfEmpty() const +{ + return m_hideIfEmpty; +} + +void TextItem::setHideIfEmpty(bool hideEmpty) +{ + if (m_hideIfEmpty != hideEmpty){ + m_hideIfEmpty = hideEmpty; + notify("hideIfEmpty",!m_hideIfEmpty, m_hideIfEmpty); + } +} + bool TextItem::isReplaceCarriageReturns() const { return m_replaceCarriageReturns; diff --git a/limereport/items/lrtextitem.h b/limereport/items/lrtextitem.h index 3eb06e2..e57864e 100644 --- a/limereport/items/lrtextitem.h +++ b/limereport/items/lrtextitem.h @@ -74,6 +74,7 @@ class TextItem : public LimeReport::ContentItemDesignIntf, IPageInit { Q_PROPERTY(bool fillInSecondPass READ fillInSecondPass WRITE setFillInSecondPass) Q_PROPERTY(bool watermark READ isWatermark WRITE setWatermark) Q_PROPERTY(bool replaceCRwithBR READ isReplaceCarriageReturns WRITE setReplaceCarriageReturns) + Q_PROPERTY(bool hideIfEmpty READ hideIfEmpty WRITE setHideIfEmpty) public: enum AutoWidth{NoneAutoWidth,MaxWordLength,MaxStringLength}; @@ -107,7 +108,7 @@ public: bool canBeSplitted(int height) const; bool isSplittable() const { return true;} - bool isEmpty() const{return m_strText.trimmed().isEmpty() /*m_text->isEmpty()*/;} + bool isEmpty() const{return m_strText.trimmed().isEmpty();} BaseDesignIntf* cloneUpperPart(int height, QObject *owner, QGraphicsItem *parent); BaseDesignIntf* cloneBottomPart(int height, QObject *owner, QGraphicsItem *parent); BaseDesignIntf* createSameTypeItem(QObject* owner=0, QGraphicsItem* parent=0); @@ -172,6 +173,9 @@ public: bool isReplaceCarriageReturns() const; void setReplaceCarriageReturns(bool isReplaceCarriageReturns); + bool hideIfEmpty() const; + void setHideIfEmpty(bool hideIfEmpty); + protected: void updateLayout(); bool isNeedExpandContent() const; @@ -193,8 +197,6 @@ private: TextPtr textDocument() const; private: QString m_strText; - //QTextLayout m_layout; - //QTextDocument* m_text; Qt::Alignment m_alignment; bool m_autoHeight; AutoWidth m_autoWidth; @@ -217,6 +219,7 @@ private: TextItem* m_follower; qreal m_textIndent; Qt::LayoutDirection m_textLayoutDirection; + bool m_hideIfEmpty; }; diff --git a/limereport/items/lrverticallayout.cpp b/limereport/items/lrverticallayout.cpp new file mode 100644 index 0000000..547225c --- /dev/null +++ b/limereport/items/lrverticallayout.cpp @@ -0,0 +1,220 @@ +#include "lrverticallayout.h" + +#include "lrbasedesignintf.h" +#include "lrdesignelementsfactory.h" + +const QString xmlTag = "VLayout"; + +namespace { + +LimeReport::BaseDesignIntf *createVLayout(QObject *owner, LimeReport::BaseDesignIntf *parent) +{ + return new LimeReport::VerticalLayout(owner, parent); +} +bool VARIABLE_IS_NOT_USED registred = LimeReport::DesignElementsFactory::instance().registerCreator( + xmlTag, + LimeReport::ItemAttribs(QObject::tr("VLayout"), LimeReport::Const::bandTAG), + createVLayout + ); +} + +namespace LimeReport{ + +bool verticalLessThen(BaseDesignIntf *c1, BaseDesignIntf* c2){ + return c1->pos().y()pos().y(); +} + +VerticalLayout::VerticalLayout(QObject* owner, QGraphicsItem* parent) + : AbstractLayout(xmlTag, owner, parent) +{} + +VerticalLayout::~VerticalLayout() +{} + +BaseDesignIntf* VerticalLayout::createSameTypeItem(QObject* owner, QGraphicsItem* parent) +{ + return new LimeReport::VerticalLayout(owner, parent); +} + +void VerticalLayout::updateLayoutSize() +{ + int spaceBorder = (borderLines() != 0) ? borderLineSize() : 0; + int h = spaceBorder*2; + qreal w = 0; + foreach(BaseDesignIntf* item, layoutsChildren()){ + if (item->isEmpty() && hideEmptyItems()) item->setVisible(false); + if (item->isVisible()){ + if (w < item->width()) w = item->width(); + h+=item->height(); + } + } + if (w>0) setWidth(w+spaceBorder*2); + setHeight(h); +} + +void VerticalLayout::relocateChildren() +{ + int spaceBorder = (borderLines() != 0) ? borderLineSize() : 0; + if (layoutsChildren().count() < childItems().size() - 1){ + layoutsChildren().clear(); + foreach (BaseDesignIntf* item, childBaseItems()) { + layoutsChildren().append(item); + } + } + qSort(layoutsChildren().begin(),layoutsChildren().end(), verticalLessThen); + qreal curY = spaceBorder; + setIsRelocating(true); + foreach (BaseDesignIntf* item, layoutsChildren()) { + if (item->isVisible() || itemMode() == DesignMode){ + item->setPos(spaceBorder, curY); + curY+=item->height(); + item->setWidth(width() - (spaceBorder * 2)); + } + } + setIsRelocating(false); +} + +bool VerticalLayout::canBeSplitted(int height) const +{ + if (childItems().isEmpty()) return false; + BaseDesignIntf* item = dynamic_cast(childItems().at(0)); + if (item){ + if (item->height() > height ) + return item->canBeSplitted(height); + else return true; + } + return false; +} + +BaseDesignIntf* VerticalLayout::cloneUpperPart(int height, QObject* owner, QGraphicsItem* parent) +{ + VerticalLayout* upperPart = dynamic_cast(createSameTypeItem(owner,parent)); + upperPart->initFromItem(this); + foreach(BaseDesignIntf* item, childBaseItems()){ + if ((item->geometry().bottom() <= height) ){ + item->cloneItem(item->itemMode(),upperPart,upperPart); + } else { + if ((item->geometry().top() < height) && ( item->geometry().bottom() > height)){ + int sliceHeight = height - item->geometry().top(); + if (item->isSplittable() && item->canBeSplitted(sliceHeight)){ + item->cloneUpperPart(sliceHeight,upperPart,upperPart); + } + } + } + } + + upperPart->setHeight(height); + + return upperPart; +} + +BaseDesignIntf* VerticalLayout::cloneBottomPart(int height, QObject* owner, QGraphicsItem* parent) +{ + VerticalLayout* bottomPart = dynamic_cast(createSameTypeItem(owner,parent)); + bottomPart->initFromItem(this); + + foreach(BaseDesignIntf* item,childBaseItems()){ + if ((item->geometry().top() < height) && ( item->geometry().bottom() > height )){ + int sliceHeight = height - item->geometry().top(); + if (item->canBeSplitted(sliceHeight)){ + BaseDesignIntf* tmpItem = item->cloneBottomPart(sliceHeight, bottomPart, bottomPart); + tmpItem->setPos(tmpItem->pos().x(),0); + tmpItem->setHeight(sliceHeight); + } else { + item->cloneItem(item->itemMode(), bottomPart, bottomPart); + item->setPos(item->pos().x(), 0); + } + } else { + if (item->geometry().top() >= height){ + BaseDesignIntf* tmpItem = item->cloneItem(item->itemMode(), bottomPart, bottomPart); + tmpItem->setPos(item->pos().x(), item->pos().y() - height); + } + } + } + + int currentHeight = 0; + if (!bottomPart->isEmpty()){ + foreach (BaseDesignIntf* item, bottomPart->childBaseItems()) { + currentHeight+=item->height(); + } + bottomPart->setHeight(currentHeight); + } + return bottomPart; +} + +void VerticalLayout::divideSpace() +{ + setIsRelocating(true); + qreal itemsSumSize = 0; + int visibleItemsCount = 0; + int spaceBorder = (borderLines() != 0) ? borderLineSize() : 0; + + foreach(BaseDesignIntf* item, layoutsChildren()){ + if (item->isVisible() || itemMode() == DesignMode ){ + itemsSumSize += item->height(); + visibleItemsCount++; + } + } + qreal delta = (height() - (itemsSumSize+spaceBorder*2)) / (visibleItemsCount!=0 ? visibleItemsCount : 1); + + for (int i=0; iisVisible() || itemMode() == DesignMode) + layoutsChildren()[i]->setHeight(layoutsChildren()[i]->height()+delta); + if ((i+1)isVisible() || itemMode() == DesignMode) + layoutsChildren()[i+1]->setPos(layoutsChildren()[i+1]->pos().x(), layoutsChildren()[i+1]->pos().y()+delta*(i+1)); + } + setIsRelocating(false); +} + +void VerticalLayout::placeItemInLayout(BaseDesignIntf* item) +{ + if (layoutsChildren().count() > 0) + item->setPos(0, layoutsChildren().last()->pos().y() + layoutsChildren().last()->height()); + else + item->setPos(0, 0); +} + +void VerticalLayout::insertItemInLayout(BaseDesignIntf* item) +{ + foreach (BaseDesignIntf* child, childBaseItems()) { + if (child->pos() == item->pos()){ + int index = layoutsChildren().indexOf(child)-1; + layoutsChildren().insert(index, item); + child->setPos(0, item->pos().y()+item->height()); + break; + } + } +} + +BaseDesignIntf*VerticalLayout::findNext(BaseDesignIntf* item) +{ + if (layoutsChildren().count() < childItems().size()-1){ + layoutsChildren().clear(); + foreach (BaseDesignIntf* childItem, childBaseItems()) { + layoutsChildren().append(childItem); + } + } + qSort(layoutsChildren().begin(),layoutsChildren().end(),verticalLessThen); + for (int i=0; ii+1){ return layoutsChildren()[i+1];} + } + return 0; +} + +BaseDesignIntf*VerticalLayout::findPrior(BaseDesignIntf* item) +{ + if (layoutsChildren().count()setEnabled(true); } menu.addSeparator(); - QAction* brinToTopAction = menu.addAction(QIcon(":/report//images/bringToTop"), tr("Bring to top")); - QAction* sendToBackAction = menu.addAction(QIcon(":/report//images/sendToBack"), tr("Send to back")); + QAction* brinToTopAction = menu.addAction(QIcon(":/report/images/bringToTop"), tr("Bring to top")); + QAction* sendToBackAction = menu.addAction(QIcon(":/report/images/sendToBack"), tr("Send to back")); QAction* createHLayout = 0; if( page->selectedItems().count()>1){ createHLayout = menu.addAction(QIcon(":/report/images/hlayout"), tr("Create Horizontal Layout")); } + QAction* createVLayout = 0; + if( page->selectedItems().count()>1){ + createVLayout = menu.addAction(QIcon(":/report/images/vlayout"), tr("Create Vertical Layout")); + } menu.addSeparator(); - QAction* noBordersAction = menu.addAction(QIcon(":/report//images/noLines"), tr("No borders")); - QAction* allBordersAction = menu.addAction(QIcon(":/report//images/allLines"), tr("All borders")); + QAction* noBordersAction = menu.addAction(QIcon(":/report/images/noLines"), tr("No borders")); + QAction* allBordersAction = menu.addAction(QIcon(":/report/images/allLines"), tr("All borders")); preparePopUpMenu(menu); QAction* a = menu.exec(event->screenPos()); if (a){ @@ -1255,6 +1259,8 @@ void BaseDesignIntf::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) page->setBorders(BaseDesignIntf::AllLines); if (a == createHLayout) page->addHLayout(); + if (a == createVLayout) + page->addVLayout(); processPopUpAction(a); } } diff --git a/limereport/lrpagedesignintf.cpp b/limereport/lrpagedesignintf.cpp index 0f5f044..9f60781 100644 --- a/limereport/lrpagedesignintf.cpp +++ b/limereport/lrpagedesignintf.cpp @@ -31,6 +31,7 @@ #include "lrbasedesignintf.h" #include "lrtextitem.h" #include "lrhorizontallayout.h" +#include "lrverticallayout.h" //#include "lrbarcodeitem.h" #include "lrbanddesignintf.h" #include "lrbandsmanager.h" @@ -1546,6 +1547,46 @@ void PageDesignIntf::addHLayout() } +void PageDesignIntf::addVLayout() +{ + if (selectedItems().isEmpty()) return; + + QList si = selectedItems(); + QList::iterator it = si.begin(); + + int itemsCount = 0; + for (; it != si.end();) { + if (dynamic_cast(*it)){ + itemsCount++; + break; + } + ++it; + }; + + if (itemsCount == 0) return; + + for (; it != si.end();) { + if (!dynamic_cast(*it)) { + (*it)->setSelected(false); + it = si.erase(it); + } + else ++it; + } + + if (!si.isEmpty()){ + it = si.begin(); + QGraphicsItem* elementsParent = (*it)->parentItem(); + for (; it != si.end();++it) { + if ((*it)->parentItem()!=elementsParent){ + QMessageBox::information(0,QObject::tr("Attention!"),QObject::tr("Selected elements have different parent containers")); + return; + } + } + CommandIf::Ptr cm = InsertVLayoutCommand::create(this); + saveCommand(cm,true); + } +} + bool hLayoutLessThen(QGraphicsItem *c1, QGraphicsItem *c2) { return c1->pos().x() < c2->pos().x(); @@ -1590,6 +1631,50 @@ HorizontalLayout* PageDesignIntf::internalAddHLayout() return 0; } +bool vLayoutLessThen(QGraphicsItem *c1, QGraphicsItem *c2) +{ + return c1->pos().y() < c2->pos().y(); +} + +VerticalLayout* PageDesignIntf::internalAddVLayout() +{ + if (m_firstSelectedItem && (selectedItems().count() > 1)) { + + QList si = selectedItems(); + QList::iterator it = si.begin(); + qSort(si.begin(), si.end(), vLayoutLessThen); + it = si.begin(); + + if (si.count() > 1) { + + it = si.begin(); + ItemDesignIntf *firstElement = dynamic_cast(*it); + + VerticalLayout *layout = new VerticalLayout(firstElement->parent(), firstElement->parentItem()); + layout->setItemLocation(firstElement->itemLocation()); + layout->setPos(firstElement->pos()); + layout->setWidth(firstElement->width()); + layout->setHeight(0); + + for (; it != si.end(); ++it) { + BaseDesignIntf *bdItem = dynamic_cast(*it); + layout->addChild(bdItem); + } + + foreach(QGraphicsItem * item, selectedItems()) { + item->setSelected(false); + } + + layout->setObjectName(genObjectName(*layout)); + layout->setItemTypeName("VerticalLayout"); + layout->setSelected(true); + registerItem(layout); + return layout; + } + } + return 0; +} + void PageDesignIntf::setFont(const QFont& font) { changeSelectedGroupProperty("font",font); @@ -2240,7 +2325,59 @@ qreal ItemProjections::square(QRectF rect) qreal ItemProjections::square(BaseDesignIntf *item) { - return square(QRectF(item->pos().x(),item->pos().y(),item->width(),item->height())); + return square(QRectF(item->pos().x(),item->pos().y(),item->width(),item->height())); +} + +CommandIf::Ptr InsertVLayoutCommand::create(PageDesignIntf* page) +{ + InsertVLayoutCommand *command = new InsertVLayoutCommand(); + command->setPage(page); + + QList si = page->selectedItems(); + QList::iterator it = si.begin(); + + BaseDesignIntf* parentItem = dynamic_cast((*it)->parentItem()); + command->m_oldParentName = (parentItem)?(parentItem->objectName()):""; + + for(it = si.begin();it!=si.end();++it){ + BaseDesignIntf* bi = dynamic_cast(*it); + if (bi) + command->m_elements.insert(bi->objectName(),bi->pos()); + } + + return CommandIf::Ptr(command); +} + +bool InsertVLayoutCommand::doIt() +{ + foreach (QString itemName, m_elements.keys()) { + BaseDesignIntf* bi = page()->reportItemByName(itemName); + if (bi) + bi->setSelected(true); + } + LayoutDesignIntf* layout = page()->internalAddVLayout(); + if (layout) + m_layoutName = layout->objectName(); + return layout != 0; +} + +void InsertVLayoutCommand::undoIt() +{ + VerticalLayout* layout = dynamic_cast(page()->reportItemByName(m_layoutName)); + if (layout){ + foreach(QGraphicsItem* item, layout->childBaseItems()){ + BaseDesignIntf* bi = dynamic_cast(item); + BaseDesignIntf* parent = page()->reportItemByName(m_oldParentName); + if (bi && parent){ + bi->setParentItem(parent); + bi->setParent(parent); + bi->setPos(m_elements.value(bi->objectName())); + bi->setFixedPos(false); + bi->setPossibleResizeDirectionFlags(BaseDesignIntf::AllDirections); + } + } + page()->removeReportItem(layout,false); + } } } diff --git a/limereport/lrpagedesignintf.h b/limereport/lrpagedesignintf.h index 684df0b..8e228c0 100644 --- a/limereport/lrpagedesignintf.h +++ b/limereport/lrpagedesignintf.h @@ -43,6 +43,7 @@ namespace LimeReport { class ReportEnginePrivate; class PropertyChangedCommand; class HorizontalLayout; + class VerticalLayout; class LayoutDesignIntf; class CommandIf { @@ -102,6 +103,7 @@ namespace LimeReport { public: friend class PropertyChangedCommand; friend class InsertHLayoutCommand; + friend class InsertVLayoutCommand; enum Orientation {Portrait, Landscape}; enum PageSize {A4, B5, Letter, Legal, Executive, A0, A1, A2, A3, A5, A6, A7, A8, A9, B0, B1, @@ -208,6 +210,7 @@ namespace LimeReport { void objectLoadFinished(); HorizontalLayout* internalAddHLayout(); + VerticalLayout* internalAddVLayout(); QPointF placePosOnGrid(QPointF point); QSizeF placeSizeOnGrid(QSizeF size); signals: @@ -250,6 +253,7 @@ namespace LimeReport { void sameWidth(); void sameHeight(); void addHLayout(); + void addVLayout(); void setFont(const QFont &font); void setTextAlign(const Qt::Alignment& alignment); void setBorders(const BaseDesignIntf::BorderLines& border); @@ -339,6 +343,19 @@ namespace LimeReport { QMap m_elements; }; + class InsertVLayoutCommand : public AbstractPageCommand{ + public: + static CommandIf::Ptr create(PageDesignIntf* page); + bool doIt(); + void undoIt(); + private: + InsertVLayoutCommand(){} + private: + QString m_layoutName; + QString m_oldParentName; + QMap m_elements; + }; + class InsertItemCommand : public AbstractPageCommand{ public: static CommandIf::Ptr create(PageDesignIntf* page, const QString& itemType, QPointF pos, QSizeF size); diff --git a/limereport/lrreportdesignwidget.cpp b/limereport/lrreportdesignwidget.cpp index 1a2904b..332dd27 100644 --- a/limereport/lrreportdesignwidget.cpp +++ b/limereport/lrreportdesignwidget.cpp @@ -630,6 +630,12 @@ void ReportDesignWidget::addHLayout() activePage()->addHLayout(); } +void ReportDesignWidget::addVLayout() +{ + if (activePage()) + activePage()->addVLayout(); +} + void ReportDesignWidget::setFont(const QFont& font) { if (activePage()) diff --git a/limereport/lrreportdesignwidget.h b/limereport/lrreportdesignwidget.h index 6204d69..913d85b 100644 --- a/limereport/lrreportdesignwidget.h +++ b/limereport/lrreportdesignwidget.h @@ -150,6 +150,7 @@ public slots: void sameWidth(); void editLayoutMode(bool value); void addHLayout(); + void addVLayout(); void setFont(const QFont &font); void setTextAlign(const bool &horizontalAlign, const Qt::AlignmentFlag &alignment); void setBorders(const BaseDesignIntf::BorderLines& borders); diff --git a/limereport/lrreportdesignwindow.cpp b/limereport/lrreportdesignwindow.cpp index d02cbef..cf8b004 100644 --- a/limereport/lrreportdesignwindow.cpp +++ b/limereport/lrreportdesignwindow.cpp @@ -221,6 +221,10 @@ void ReportDesignWindow::createActions() m_addHLayout->setIcon(QIcon(":/report/images/hlayout")); connect(m_addHLayout,SIGNAL(triggered()),this,SLOT(slotHLayout())); + m_addVLayout = new QAction(tr("Vertical layout"),this); + m_addVLayout->setIcon(QIcon(":/report/images/vlayout")); + connect(m_addVLayout,SIGNAL(triggered()),this,SLOT(slotVLayout())); + m_aboutAction = new QAction(tr("About"),this); m_aboutAction->setIcon(QIcon(":/report/images/copyright")); connect(m_aboutAction,SIGNAL(triggered()),this,SLOT(slotShowAbout())); @@ -258,6 +262,7 @@ void ReportDesignWindow::createReportToolBar() createItemsActions(); m_reportToolBar->addSeparator(); m_reportToolBar->addAction(m_addHLayout); + m_reportToolBar->addAction(m_addVLayout); m_reportToolBar->addSeparator(); m_reportToolBar->addAction(m_deleteItemAction); @@ -1171,6 +1176,11 @@ void ReportDesignWindow::slotHLayout() m_reportDesignWidget->addHLayout(); } +void ReportDesignWindow::slotVLayout() +{ + m_reportDesignWidget->addVLayout(); +} + void ReportDesignWindow::slotTest() { } diff --git a/limereport/lrreportdesignwindow.h b/limereport/lrreportdesignwindow.h index 1beb45a..e7cd514 100644 --- a/limereport/lrreportdesignwindow.h +++ b/limereport/lrreportdesignwindow.h @@ -92,6 +92,7 @@ private slots: void slotDelete(); void slotEditLayoutMode(); void slotHLayout(); + void slotVLayout(); void slotItemSelected(LimeReport::BaseDesignIntf *item); void slotItemPropertyChanged(const QString& objectName, const QString& propertyName, const QVariant &oldValue, const QVariant &newValue); void slotMultiItemSelected(); @@ -223,6 +224,7 @@ private: QAction* m_aboutAction; QAction* m_editLayoutMode; QAction* m_addHLayout; + QAction* m_addVLayout; QAction* m_hideLeftPanel; QAction* m_hideRightPanel; #ifdef HAVE_QTDESIGNER_INTEGRATION diff --git a/limereport/objectinspector/lrobjectitemmodel.cpp b/limereport/objectinspector/lrobjectitemmodel.cpp index 8a1d8a7..b39c4d0 100644 --- a/limereport/objectinspector/lrobjectitemmodel.cpp +++ b/limereport/objectinspector/lrobjectitemmodel.cpp @@ -152,6 +152,8 @@ void QObjectPropertyModel::translatePropertyName() tr("printable"); tr("variable"); tr("replaceCRwithBR"); + tr("hideIfEmpty"); + tr("hideEmptyItems"); } void QObjectPropertyModel::clearObjectsList() diff --git a/limereport/objectinspector/propertyItems/lrenumpropitem.cpp b/limereport/objectinspector/propertyItems/lrenumpropitem.cpp index 6398f12..2c6c6b0 100644 --- a/limereport/objectinspector/propertyItems/lrenumpropitem.cpp +++ b/limereport/objectinspector/propertyItems/lrenumpropitem.cpp @@ -141,6 +141,8 @@ void EnumPropItem::translateEnumItemName() tr("TitleAlignLeft"); tr("TitleAlignRight"); tr("TitleAlignCenter"); + tr("Layout"); + tr("Table"); } void EnumPropItem::setPropertyEditorData(QWidget *propertyEditor, const QModelIndex &) const diff --git a/limereport/report.qrc b/limereport/report.qrc index fe70d36..0d24acb 100644 --- a/limereport/report.qrc +++ b/limereport/report.qrc @@ -182,5 +182,6 @@ images/property.png images/signal.png images/object.png + images/vlayuot_4_24.png