0
0
mirror of https://github.com/fralx/LimeReport.git synced 2025-01-11 17:18:10 +03:00

Merge pull request #383 from emil-sawicki9/bugfix/crash-when-removing-items

Designer fix: undoing delete layout inside the layout
This commit is contained in:
Alexander Arin 2022-02-07 16:38:47 +03:00 committed by GitHub
commit 667ff4adb4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 109 additions and 33 deletions

View File

@ -48,7 +48,6 @@ void AbstractLayout::setLayoutType(const LayoutType& layoutType)
void AbstractLayout::addChild(BaseDesignIntf* item, bool updateSize) void AbstractLayout::addChild(BaseDesignIntf* item, bool updateSize)
{ {
placeItemInLayout(item); placeItemInLayout(item);
m_children.append(item); m_children.append(item);
@ -57,22 +56,7 @@ void AbstractLayout::addChild(BaseDesignIntf* item, bool updateSize)
item->setFixedPos(true); item->setFixedPos(true);
item->setPossibleResizeDirectionFlags(ResizeRight | ResizeBottom); item->setPossibleResizeDirectionFlags(ResizeRight | ResizeBottom);
connect( connectToLayout(item);
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){ if (updateSize){
relocateChildren(); relocateChildren();
@ -80,19 +64,23 @@ void AbstractLayout::addChild(BaseDesignIntf* item, bool updateSize)
} }
} }
void AbstractLayout::removeChild(BaseDesignIntf *item)
{
if (!item) {
return;
}
m_children.removeAll(item);
disconnectFromLayout(item);
}
void AbstractLayout::restoreChild(BaseDesignIntf* item) void AbstractLayout::restoreChild(BaseDesignIntf* item)
{ {
if (m_children.contains(item)) return; if (m_children.contains(item)) return;
m_isRelocating=true; m_isRelocating=true;
insertItemInLayout(item); insertItemInLayout(item);
connect(item,SIGNAL(destroyed(QObject*)),this,SLOT(slotOnChildDestroy(QObject*))); connectToLayout(item);
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->setFixedPos(true);
item->setPossibleResizeDirectionFlags(ResizeRight | ResizeBottom); item->setPossibleResizeDirectionFlags(ResizeRight | ResizeBottom);
@ -267,6 +255,54 @@ void AbstractLayout::rebuildChildrenIfNeeded(){
} }
} }
void AbstractLayout::connectToLayout(BaseDesignIntf *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(itemVisibleHasChanged(BaseDesignIntf*)),
this, SLOT(slotOnChildVisibleHasChanged(BaseDesignIntf*))
);
connect(
item, SIGNAL(itemSelectedHasBeenChanged(BaseDesignIntf*,bool)),
this, SLOT(slotOnChildSelectionHasChanged(BaseDesignIntf*,bool))
);
connect(
item, SIGNAL(itemAlignChanged(BaseDesignIntf*, const ItemAlign&, const ItemAlign&)),
this, SLOT(slotOnChildItemAlignChanged(BaseDesignIntf*,const ItemAlign&,const ItemAlign&))
);
}
void AbstractLayout::disconnectFromLayout(BaseDesignIntf *item)
{
disconnect(
item, SIGNAL(destroyed(QObject*)),
this, SLOT(slotOnChildDestroy(QObject*))
);
disconnect(
item,SIGNAL(geometryChanged(QObject*,QRectF,QRectF)),
this,SLOT(slotOnChildGeometryChanged(QObject*,QRectF,QRectF))
);
disconnect(
item, SIGNAL(itemVisibleHasChanged(BaseDesignIntf*)),
this, SLOT(slotOnChildVisibleHasChanged(BaseDesignIntf*))
);
disconnect(
item, SIGNAL(itemSelectedHasBeenChanged(BaseDesignIntf*,bool)),
this, SLOT(slotOnChildSelectionHasChanged(BaseDesignIntf*,bool))
);
disconnect(
item, SIGNAL(itemAlignChanged(BaseDesignIntf*, const ItemAlign&, const ItemAlign&)),
this, SLOT(slotOnChildItemAlignChanged(BaseDesignIntf*,const ItemAlign&,const ItemAlign&))
);
}
BaseDesignIntf *AbstractLayout::findNext(BaseDesignIntf *item) BaseDesignIntf *AbstractLayout::findNext(BaseDesignIntf *item)
{ {
rebuildChildrenIfNeeded(); rebuildChildrenIfNeeded();
@ -288,7 +324,7 @@ BaseDesignIntf *AbstractLayout::findPrior(BaseDesignIntf *item)
void AbstractLayout::slotOnChildDestroy(QObject* child) void AbstractLayout::slotOnChildDestroy(QObject* child)
{ {
m_children.removeAll(static_cast<BaseDesignIntf*>(child)); m_children.removeAll(static_cast<BaseDesignIntf*>(child));
if (m_children.count()<2){ if (m_children.count() < 2 && !static_cast<LayoutDesignIntf*>(child)){
beforeDelete(); beforeDelete();
} else { } else {
relocateChildren(); relocateChildren();
@ -316,7 +352,7 @@ void AbstractLayout::slotOnChildGeometryChanged(QObject* item, QRectF newGeometr
} }
} }
void AbstractLayout::slotOnChildItemAlignChanged(BaseDesignIntf* item, const BaseDesignIntf::ItemAlign&, const BaseDesignIntf::ItemAlign&) void AbstractLayout::slotOnChildItemAlignChanged(BaseDesignIntf* item, const ItemAlign&, const ItemAlign&)
{ {
item->setPossibleResizeDirectionFlags(ResizeBottom | ResizeRight); item->setPossibleResizeDirectionFlags(ResizeBottom | ResizeRight);
} }

View File

@ -28,6 +28,7 @@ public:
void setLayoutType(const LayoutType& layoutType); void setLayoutType(const LayoutType& layoutType);
void addChild(BaseDesignIntf *item,bool updateSize=true); void addChild(BaseDesignIntf *item,bool updateSize=true);
void removeChild(BaseDesignIntf *item);
void restoreChild(BaseDesignIntf *item); void restoreChild(BaseDesignIntf *item);
bool isEmpty() const; bool isEmpty() const;
void paintChild(BaseDesignIntf* child, QPointF parentPos, QPainter* painter); void paintChild(BaseDesignIntf* child, QPointF parentPos, QPainter* painter);
@ -52,6 +53,8 @@ protected:
QVariant itemChange(GraphicsItemChange change, const QVariant &value); QVariant itemChange(GraphicsItemChange change, const QVariant &value);
void updateItemSize(DataSourceManager* dataManager, RenderPass pass, int maxHeight); void updateItemSize(DataSourceManager* dataManager, RenderPass pass, int maxHeight);
void rebuildChildrenIfNeeded(); void rebuildChildrenIfNeeded();
void connectToLayout(BaseDesignIntf* item);
void disconnectFromLayout(BaseDesignIntf* item);
private: private:
virtual void sortChildren() = 0; virtual void sortChildren() = 0;
virtual void divideSpace() = 0; virtual void divideSpace() = 0;

View File

@ -171,9 +171,14 @@ void HorizontalLayout::updateLayoutSize()
void HorizontalLayout::relocateChildren() void HorizontalLayout::relocateChildren()
{ {
int spaceBorder = (borderLines() != 0) ? borderLineSize() : 0; int spaceBorder = (borderLines() != 0) ? borderLineSize() : 0;
QList<BaseDesignIntf*> newChildren;
if (layoutsChildren().count() < childItems().size()-1){ if (layoutsChildren().count() < childItems().size()-1){
auto oldChildren = layoutsChildren();
layoutsChildren().clear(); layoutsChildren().clear();
foreach (BaseDesignIntf* item, childBaseItems()) { foreach (BaseDesignIntf* item, childBaseItems()) {
if (!oldChildren.contains(item)) {
newChildren.append(item);
}
layoutsChildren().append(item); layoutsChildren().append(item);
} }
} }
@ -188,6 +193,10 @@ void HorizontalLayout::relocateChildren()
} }
} }
setIsRelocating(false); setIsRelocating(false);
for (BaseDesignIntf* item : newChildren) {
connectToLayout(item);
}
} }
void HorizontalLayout::divideSpace(){ void HorizontalLayout::divideSpace(){

View File

@ -57,9 +57,14 @@ void VerticalLayout::updateLayoutSize()
void VerticalLayout::relocateChildren() void VerticalLayout::relocateChildren()
{ {
int spaceBorder = (borderLines() != 0) ? borderLineSize() : 0; int spaceBorder = (borderLines() != 0) ? borderLineSize() : 0;
QList<BaseDesignIntf*> newChildren;
if (layoutsChildren().count() < childItems().size() - 1){ if (layoutsChildren().count() < childItems().size() - 1){
auto oldChildren = layoutsChildren();
layoutsChildren().clear(); layoutsChildren().clear();
foreach (BaseDesignIntf* item, childBaseItems()) { foreach (BaseDesignIntf* item, childBaseItems()) {
if (!oldChildren.contains(item)) {
newChildren.append(item);
}
layoutsChildren().append(item); layoutsChildren().append(item);
} }
} }
@ -74,6 +79,10 @@ void VerticalLayout::relocateChildren()
} }
} }
setIsRelocating(false); setIsRelocating(false);
for (BaseDesignIntf* item : newChildren) {
connectToLayout(item);
}
} }
bool VerticalLayout::canBeSplitted(int height) const bool VerticalLayout::canBeSplitted(int height) const

View File

@ -480,7 +480,7 @@ signals:
void propertyChanged(const QString& propertName, const QVariant& oldValue,const QVariant& newValue); void propertyChanged(const QString& propertName, const QVariant& oldValue,const QVariant& newValue);
void propertyObjectNameChanged(const QString& oldValue, const QString& newValue); void propertyObjectNameChanged(const QString& oldValue, const QString& newValue);
void propertyesChanged(QVector<QString> propertyNames); void propertyesChanged(QVector<QString> propertyNames);
void itemAlignChanged(BaseDesignIntf* item, const BaseDesignIntf::ItemAlign& oldValue, const BaseDesignIntf::ItemAlign& newValue); void itemAlignChanged(BaseDesignIntf* item, const ItemAlign& oldValue, const ItemAlign& newValue);
void itemVisibleHasChanged(BaseDesignIntf* item); void itemVisibleHasChanged(BaseDesignIntf* item);
void beforeRender(); void beforeRender();
void afterData(); void afterData();

View File

@ -97,6 +97,7 @@ public:
LayoutDesignIntf(const QString& xmlTypeName, QObject* owner = 0,QGraphicsItem* parent = 0): LayoutDesignIntf(const QString& xmlTypeName, QObject* owner = 0,QGraphicsItem* parent = 0):
ItemDesignIntf(xmlTypeName,owner,parent){} ItemDesignIntf(xmlTypeName,owner,parent){}
virtual void addChild(BaseDesignIntf *item,bool updateSize=true) = 0; virtual void addChild(BaseDesignIntf *item,bool updateSize=true) = 0;
virtual void removeChild(BaseDesignIntf *item) = 0;
virtual void restoreChild(BaseDesignIntf *item) = 0; virtual void restoreChild(BaseDesignIntf *item) = 0;
virtual int childrenCount() = 0; virtual int childrenCount() = 0;
friend class BaseDesignIntf; friend class BaseDesignIntf;

View File

@ -554,17 +554,16 @@ CommandIf::Ptr PageDesignIntf::removeReportItemCommand(BaseDesignIntf *item){
CommandIf::Ptr command = createBandDeleteCommand(this,band); CommandIf::Ptr command = createBandDeleteCommand(this,band);
return command; return command;
} else { } else {
LayoutDesignIntf* layout = dynamic_cast<LayoutDesignIntf*>(item->parent()); LayoutDesignIntf* parentLayout = dynamic_cast<LayoutDesignIntf*>(item->parent());
if (layout && (layout->childrenCount()==2)){ LayoutDesignIntf* layout = dynamic_cast<LayoutDesignIntf*>(item);
// When removing layout child all his children will be assigned to parent
if (!layout && parentLayout && (parentLayout->childrenCount() == 2)) {
CommandGroup::Ptr commandGroup = CommandGroup::create(); CommandGroup::Ptr commandGroup = CommandGroup::create();
commandGroup->addCommand(DeleteLayoutCommand::create(this, layout),false); commandGroup->addCommand(DeleteLayoutCommand::create(this, parentLayout),false);
commandGroup->addCommand(DeleteItemCommand::create(this,item),false); commandGroup->addCommand(DeleteItemCommand::create(this,item),false);
return commandGroup; return commandGroup;
} else { } else {
CommandIf::Ptr command = (dynamic_cast<LayoutDesignIntf*>(item))? return layout ? DeleteLayoutCommand::create(this, layout) : DeleteItemCommand::create(this, item) ;
DeleteLayoutCommand::create(this, dynamic_cast<LayoutDesignIntf*>(item)) :
DeleteItemCommand::create(this, item) ;
return command;
} }
} }
} }
@ -2008,6 +2007,9 @@ CommandIf::Ptr DeleteLayoutCommand::create(PageDesignIntf *page, LayoutDesignInt
foreach (BaseDesignIntf* childItem, item->childBaseItems()){ foreach (BaseDesignIntf* childItem, item->childBaseItems()){
command->m_childItems.append(childItem->objectName()); command->m_childItems.append(childItem->objectName());
} }
LayoutDesignIntf* layout = dynamic_cast<LayoutDesignIntf*>(item->parent());
if (layout)
command->m_layoutName = layout->objectName();
return CommandIf::Ptr(command); return CommandIf::Ptr(command);
} }
@ -2032,9 +2034,20 @@ void DeleteLayoutCommand::undoIt()
BaseDesignIntf *item = page()->addReportItem(m_itemType); BaseDesignIntf *item = page()->addReportItem(m_itemType);
ItemsReaderIntf::Ptr reader = StringXMLreader::create(m_itemXML); ItemsReaderIntf::Ptr reader = StringXMLreader::create(m_itemXML);
if (reader->first()) reader->readItem(item); if (reader->first()) reader->readItem(item);
if (!m_layoutName.isEmpty()) {
LayoutDesignIntf* layout = dynamic_cast<LayoutDesignIntf*>(page()->reportItemByName(m_layoutName));
if (layout){
layout->restoreChild(item);
}
page()->emitRegisterdItem(item);
}
foreach(QString ci, m_childItems){ foreach(QString ci, m_childItems){
BaseDesignIntf* ri = page()->reportItemByName(ci); BaseDesignIntf* ri = page()->reportItemByName(ci);
if (ri){ if (ri){
LayoutDesignIntf* parentLayout = dynamic_cast<LayoutDesignIntf*>(ri->parent());
if (parentLayout) {
parentLayout->removeChild(ri);
}
dynamic_cast<LayoutDesignIntf*>(item)->addChild(ri); dynamic_cast<LayoutDesignIntf*>(item)->addChild(ri);
} }
page()->emitRegisterdItem(item); page()->emitRegisterdItem(item);

View File

@ -415,6 +415,7 @@ namespace LimeReport {
void setItem(BaseDesignIntf* item); void setItem(BaseDesignIntf* item);
private: private:
QStringList m_childItems; QStringList m_childItems;
QString m_layoutName;
QString m_itemXML; QString m_itemXML;
QString m_itemType; QString m_itemType;
QString m_itemName; QString m_itemName;

View File

@ -222,6 +222,10 @@ void QObjectPropertyModel::setMultiObjects(QList<QObject *>* list)
m_objects.clear(); m_objects.clear();
submit(); submit();
if (list->isEmpty()) {
return;
}
if (!list->contains(m_object)){ if (!list->contains(m_object)){
m_object=list->at(0); m_object=list->at(0);
list->removeAt(0); list->removeAt(0);