mirror of
				https://github.com/fralx/LimeReport.git
				synced 2025-10-31 21:31:21 +03:00 
			
		
		
		
	Vertical Layout has been added
This commit is contained in:
		
							
								
								
									
										
											BIN
										
									
								
								limereport/images/vlayuot_4_24.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								limereport/images/vlayuot_4_24.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 201 B | 
							
								
								
									
										321
									
								
								limereport/items/lrabstractlayout.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										321
									
								
								limereport/items/lrabstractlayout.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -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<BaseDesignIntf*>& 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<ContentItemDesignIntf*>(qgItem); | ||||
|         if (item && !item->content().isEmpty()) isEmpty = false; | ||||
|         if (!item && dynamic_cast<BaseDesignIntf*>(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<BaseDesignIntf*>(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<BaseDesignIntf*>(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<BaseDesignIntf*>(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<BaseDesignIntf*>(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<BaseDesignIntf*>(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<BaseDesignIntf*>(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 | ||||
							
								
								
									
										68
									
								
								limereport/items/lrabstractlayout.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								limereport/items/lrabstractlayout.h
									
									
									
									
									
										Normal file
									
								
							| @@ -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<BaseDesignIntf*>& 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<BaseDesignIntf *> m_children; | ||||
|     bool m_isRelocating; | ||||
|     LayoutMarker* m_layoutMarker; | ||||
|     LayoutType m_layoutType; | ||||
|     bool m_hideEmptyItems; | ||||
| }; | ||||
|  | ||||
| } // namespace LimeReport | ||||
|  | ||||
| #endif // LRABSTRACTLAYOUT_H | ||||
| @@ -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()<c2->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<BaseDesignIntf*>(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<BaseDesignIntf*>(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<ContentItemDesignIntf*>(qgItem); | ||||
|         if (item && !item->content().isEmpty()) isEmpty = false; | ||||
|         if (!item && dynamic_cast<BaseDesignIntf*>(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<BaseDesignIntf*>(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 (h<item->height()) 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()<childItems().size()-1){ | ||||
|         m_children.clear(); | ||||
|     if (layoutsChildren().count()<childItems().size()-1){ | ||||
|         layoutsChildren().clear(); | ||||
|         foreach (BaseDesignIntf* item, childBaseItems()) { | ||||
|             m_children.append(item); | ||||
|             layoutsChildren().append(item); | ||||
|         } | ||||
|     } | ||||
|     qSort(m_children.begin(),m_children.end(),lessThen); | ||||
|     qSort(layoutsChildren().begin(),layoutsChildren().end(),horizontalLessThen); | ||||
|     qreal curX = spaceBorder; | ||||
|     m_isRelocating = true; | ||||
|     foreach (BaseDesignIntf* item, m_children) { | ||||
|     setIsRelocating(true); | ||||
|     foreach (BaseDesignIntf* item, layoutsChildren()) { | ||||
|         if (item->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<BaseDesignIntf*>(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<BaseDesignIntf*>(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<BaseDesignIntf*>(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<BaseDesignIntf*>(child)); | ||||
|     if (m_children.count()<2){ | ||||
|         beforeDelete(); | ||||
| //        deleteLater(); | ||||
|     } else { | ||||
|         relocateChildren(); | ||||
|         updateLayoutSize(); | ||||
|     } | ||||
|     setIsRelocating(false); | ||||
| } | ||||
|  | ||||
| BaseDesignIntf* HorizontalLayout::findNext(BaseDesignIntf* item){ | ||||
|     if (m_children.count()<childItems().size()-1){ | ||||
|         m_children.clear(); | ||||
|     if (layoutsChildren().count() < childItems().size()-1){ | ||||
|         layoutsChildren().clear(); | ||||
|         foreach (BaseDesignIntf* childItem, childBaseItems()) { | ||||
|             m_children.append(childItem); | ||||
|             layoutsChildren().append(childItem); | ||||
|         } | ||||
|     } | ||||
|     qSort(m_children.begin(),m_children.end(),lessThen); | ||||
|     for (int i=0; i<m_children.count();++i){ | ||||
|         if (m_children[i]==item && m_children.size()>i+1){ return m_children[i+1];} | ||||
|     qSort(layoutsChildren().begin(),layoutsChildren().end(),horizontalLessThen); | ||||
|     for (int i=0; i<layoutsChildren().count();++i){ | ||||
|         if (layoutsChildren()[i]==item && layoutsChildren().size()>i+1){ return layoutsChildren()[i+1];} | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| BaseDesignIntf* HorizontalLayout::findPrior(BaseDesignIntf* item){ | ||||
|     if (m_children.count()<childItems().size()-1){ | ||||
|         m_children.clear(); | ||||
|     if (layoutsChildren().count()<childItems().size()-1){ | ||||
|         layoutsChildren().clear(); | ||||
|         foreach (BaseDesignIntf* childItem, childBaseItems()) { | ||||
|             m_children.append(childItem); | ||||
|             layoutsChildren().append(childItem); | ||||
|         } | ||||
|     } | ||||
|     qSort(m_children.begin(),m_children.end(),lessThen); | ||||
|     for (int i=0; i<m_children.count();++i){ | ||||
|         if (m_children[i]==item && i!=0){ return m_children[i-1];} | ||||
|     qSort(layoutsChildren().begin(),layoutsChildren().end(),horizontalLessThen); | ||||
|     for (int i=0; i<layoutsChildren().count();++i){ | ||||
|         if (layoutsChildren()[i]==item && i!=0){ return layoutsChildren()[i-1];} | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| void HorizontalLayout::divideSpace(){ | ||||
|     m_isRelocating = true; | ||||
|     setIsRelocating(true); | ||||
|     qreal itemsSumSize = 0; | ||||
|     int visibleItemsCount = 0; | ||||
|     int spaceBorder = (borderLines() != 0) ? borderLineSize() : 0; | ||||
|  | ||||
|     foreach(BaseDesignIntf* item, m_children){ | ||||
|     foreach(BaseDesignIntf* item, layoutsChildren()){ | ||||
|         if (item->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; i<m_children.size(); ++i){ | ||||
|         if (m_children[i]->isVisible() || itemMode() == DesignMode) | ||||
|             m_children[i]->setWidth(m_children[i]->width()+delta); | ||||
|         if ((i+1)<m_children.size()) | ||||
|             if (m_children[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; i<layoutsChildren().size(); ++i){ | ||||
|         if (layoutsChildren()[i]->isVisible() || itemMode() == DesignMode) | ||||
|             layoutsChildren()[i]->setWidth(layoutsChildren()[i]->width()+delta); | ||||
|         if ((i+1)<layoutsChildren().size()) | ||||
|             if (layoutsChildren()[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<BaseDesignIntf*>(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()<boundingRect().height()) ? boundingRect().width() : boundingRect().height(); | ||||
|  | ||||
|     if (m_layout->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 | ||||
|   | ||||
| @@ -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<BaseDesignIntf *> m_children; | ||||
|     bool m_isRelocating; | ||||
|     LayoutMarker* m_layoutMarker; | ||||
|     LayoutType m_layoutType; | ||||
|     void placeItemInLayout(BaseDesignIntf* item); | ||||
|     void insertItemInLayout(BaseDesignIntf* item); | ||||
| }; | ||||
|  | ||||
| } //namespace LimeReport | ||||
|   | ||||
							
								
								
									
										69
									
								
								limereport/items/lrlayoutmarker.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								limereport/items/lrlayoutmarker.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,69 @@ | ||||
| #include "lrlayoutmarker.h" | ||||
| #include <QGraphicsSceneMouseEvent> | ||||
| #include <QGraphicsScene> | ||||
|  | ||||
| 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()<boundingRect().height()) ? boundingRect().width() : boundingRect().height(); | ||||
|  | ||||
|     if (m_layout->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 | ||||
							
								
								
									
										28
									
								
								limereport/items/lrlayoutmarker.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								limereport/items/lrlayoutmarker.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| #ifndef LRLAYOUTMARKER_H | ||||
| #define LRLAYOUTMARKER_H | ||||
|  | ||||
| #include <QGraphicsItem> | ||||
| #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 | ||||
| @@ -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<PageItemDesignIntf*>(parent); | ||||
|     BaseDesignIntf* parentItem = dynamic_cast<BaseDesignIntf*>(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; | ||||
|   | ||||
| @@ -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; | ||||
|  | ||||
| }; | ||||
|  | ||||
|   | ||||
							
								
								
									
										220
									
								
								limereport/items/lrverticallayout.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										220
									
								
								limereport/items/lrverticallayout.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -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()<c2->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<BaseDesignIntf*>(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<VerticalLayout*>(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<VerticalLayout*>(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; i<layoutsChildren().size(); ++i){ | ||||
|         if (layoutsChildren()[i]->isVisible() || itemMode() == DesignMode) | ||||
|             layoutsChildren()[i]->setHeight(layoutsChildren()[i]->height()+delta); | ||||
|         if ((i+1)<layoutsChildren().size()) | ||||
|             if (layoutsChildren()[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; i<layoutsChildren().count();++i){ | ||||
|         if (layoutsChildren()[i]==item && layoutsChildren().size()>i+1){ return layoutsChildren()[i+1];} | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| BaseDesignIntf*VerticalLayout::findPrior(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; i<layoutsChildren().count();++i){ | ||||
|         if (layoutsChildren()[i]==item && i!=0){ return layoutsChildren()[i-1];} | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| } | ||||
							
								
								
									
										37
									
								
								limereport/items/lrverticallayout.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								limereport/items/lrverticallayout.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| #ifndef LRVERTICALLAYOUT_H | ||||
| #define LRVERTICALLAYOUT_H | ||||
|  | ||||
| #include "lritemdesignintf.h" | ||||
| #include "lrlayoutmarker.h" | ||||
| #include "lrabstractlayout.h" | ||||
|  | ||||
| namespace LimeReport{ | ||||
|  | ||||
| class VerticalLayout : public AbstractLayout | ||||
| { | ||||
|     Q_OBJECT | ||||
| public: | ||||
|     friend class BaseDesignIntf; | ||||
|     VerticalLayout(QObject *owner = 0, QGraphicsItem *parent = 0); | ||||
|     ~VerticalLayout(); | ||||
|     // BaseDesignIntf interface | ||||
|     BaseDesignIntf*createSameTypeItem(QObject* owner, QGraphicsItem* parent); | ||||
|     bool isSplittable() const { return true;} | ||||
| protected: | ||||
|     void updateLayoutSize(); | ||||
|     void relocateChildren(); | ||||
|     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); | ||||
| private: | ||||
|     void divideSpace(); | ||||
|     void placeItemInLayout(BaseDesignIntf* item); | ||||
|     void insertItemInLayout(BaseDesignIntf* item); | ||||
|     BaseDesignIntf *findNext(BaseDesignIntf *item); | ||||
|     BaseDesignIntf *findPrior(BaseDesignIntf* item); | ||||
| private: | ||||
|  | ||||
| }; | ||||
|  | ||||
| } // namespace LimeReport | ||||
| #endif // LRVERTICALLAYOUT_H | ||||
| @@ -45,6 +45,9 @@ SOURCES += \ | ||||
|     $$REPORT_PATH/items/lrtextitemeditor.cpp \ | ||||
|     $$REPORT_PATH/items/lrshapeitem.cpp \ | ||||
|     $$REPORT_PATH/items/lrtextitem.cpp \ | ||||
|     $$REPORT_PATH/items/lrverticallayout.cpp \ | ||||
|     $$REPORT_PATH/items/lrlayoutmarker.cpp \ | ||||
|     $$REPORT_PATH/items/lrabstractlayout.cpp \ | ||||
|     $$REPORT_PATH/lrbanddesignintf.cpp \ | ||||
|     $$REPORT_PATH/lrpageitemdesignintf.cpp \ | ||||
|     $$REPORT_PATH/lrpagedesignintf.cpp \ | ||||
| @@ -71,6 +74,7 @@ SOURCES += \ | ||||
|     $$REPORT_PATH/items/lrchartitemeditor.cpp \ | ||||
|     $$REPORT_PATH/lrreporttranslation.cpp | ||||
|  | ||||
|  | ||||
| contains(CONFIG, embedded_designer){ | ||||
| SOURCES += \ | ||||
|     $$REPORT_PATH/databrowser/lrdatabrowser.cpp \ | ||||
| @@ -152,6 +156,9 @@ HEADERS += \ | ||||
|     $$REPORT_PATH/items/lrshapeitem.h \ | ||||
|     $$REPORT_PATH/items/lrimageitem.h \ | ||||
|     $$REPORT_PATH/items/lrsimpletagparser.h \ | ||||
|     $$REPORT_PATH/items/lrverticallayout.h \ | ||||
|     $$REPORT_PATH/items/lrlayoutmarker.h \ | ||||
|     $$REPORT_PATH/items/lrabstractlayout.h \ | ||||
|     $$REPORT_PATH/lrbanddesignintf.h \ | ||||
|     $$REPORT_PATH/lrpageitemdesignintf.h \ | ||||
|     $$REPORT_PATH/lrbandsmanager.h \ | ||||
| @@ -189,6 +196,7 @@ HEADERS += \ | ||||
|     $$REPORT_PATH/lrreporttranslation.h \ | ||||
|     $$REPORT_PATH/lrreportdesignwindowintrerface.h | ||||
|  | ||||
|  | ||||
| contains(CONFIG, embedded_designer){ | ||||
| HEADERS += \ | ||||
|     $$REPORT_PATH/databrowser/lrdatabrowser.h \ | ||||
|   | ||||
| @@ -1224,15 +1224,19 @@ void BaseDesignIntf::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) | ||||
|         pasteAction->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); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -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<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); | ||||
|             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<QGraphicsItem *> si = selectedItems(); | ||||
|         QList<QGraphicsItem *>::iterator it = si.begin(); | ||||
|         qSort(si.begin(), si.end(), vLayoutLessThen); | ||||
|         it = si.begin(); | ||||
|  | ||||
|         if (si.count() > 1) { | ||||
|  | ||||
|             it = si.begin(); | ||||
|             ItemDesignIntf *firstElement = dynamic_cast<ItemDesignIntf *>(*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<BaseDesignIntf *>(*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<QGraphicsItem *> si = page->selectedItems(); | ||||
|     QList<QGraphicsItem *>::iterator it = si.begin(); | ||||
|  | ||||
|     BaseDesignIntf* parentItem = dynamic_cast<BaseDesignIntf*>((*it)->parentItem()); | ||||
|     command->m_oldParentName = (parentItem)?(parentItem->objectName()):""; | ||||
|  | ||||
|     for(it = si.begin();it!=si.end();++it){ | ||||
|         BaseDesignIntf* bi = dynamic_cast<BaseDesignIntf*>(*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<VerticalLayout*>(page()->reportItemByName(m_layoutName)); | ||||
|     if (layout){ | ||||
|         foreach(QGraphicsItem* item, layout->childBaseItems()){ | ||||
|             BaseDesignIntf* bi = dynamic_cast<BaseDesignIntf*>(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); | ||||
|     } | ||||
| } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -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<QString,QPointF> 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<QString,QPointF> m_elements; | ||||
|     }; | ||||
|  | ||||
|     class InsertItemCommand : public AbstractPageCommand{ | ||||
|     public: | ||||
|         static CommandIf::Ptr create(PageDesignIntf* page, const QString& itemType, QPointF pos, QSizeF size); | ||||
|   | ||||
| @@ -630,6 +630,12 @@ void ReportDesignWidget::addHLayout() | ||||
|         activePage()->addHLayout(); | ||||
| } | ||||
|  | ||||
| void ReportDesignWidget::addVLayout() | ||||
| { | ||||
|     if (activePage()) | ||||
|         activePage()->addVLayout(); | ||||
| } | ||||
|  | ||||
| void ReportDesignWidget::setFont(const QFont& font) | ||||
| { | ||||
|     if (activePage()) | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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() | ||||
| { | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -152,6 +152,8 @@ void QObjectPropertyModel::translatePropertyName() | ||||
|     tr("printable"); | ||||
|     tr("variable"); | ||||
|     tr("replaceCRwithBR"); | ||||
|     tr("hideIfEmpty"); | ||||
|     tr("hideEmptyItems"); | ||||
| } | ||||
|  | ||||
| void QObjectPropertyModel::clearObjectsList() | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -182,5 +182,6 @@ | ||||
|         <file alias="/images/property">images/property.png</file> | ||||
|         <file alias="/images/signal">images/signal.png</file> | ||||
|         <file alias="/images/object">images/object.png</file> | ||||
|         <file alias="/images/vlayout">images/vlayuot_4_24.png</file> | ||||
|     </qresource> | ||||
| </RCC> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user