mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-09-29 14:14:15 +02:00
Merge pull request #1151 from ispyisail/fix/1146-locked-group-member
Fix a group splitting apart when one of its items is locked (#1146)
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
#include "diagramcontent.h"
|
||||
|
||||
#include "diagram.h"
|
||||
#include "itemgroups.h"
|
||||
#include "qetgraphicsitem/ViewItem/qetgraphicstableitem.h"
|
||||
#include "qetgraphicsitem/conductor.h"
|
||||
#include "qetgraphicsitem/conductortextitem.h"
|
||||
@@ -261,7 +262,7 @@ void DiagramContent::clear()
|
||||
*/
|
||||
int DiagramContent::removeNonMovableItems()
|
||||
{
|
||||
int count_ = 0;
|
||||
int count_ = removePinnedGroups();
|
||||
|
||||
const QList<Element *> elements_set = m_elements;
|
||||
for(Element *elmt : elements_set) {
|
||||
@@ -287,9 +288,55 @@ int DiagramContent::removeNonMovableItems()
|
||||
}
|
||||
}
|
||||
|
||||
//A wire whose two ends no longer both move is redrawn, not moved,
|
||||
//or its text would be carried off with the end that still moves
|
||||
const QList<Conductor *> conductors_to_move = m_conductors_to_move;
|
||||
for (Conductor *conductor : conductors_to_move) {
|
||||
if (!m_elements.contains(conductor->terminal1->parentElement()) ||
|
||||
!m_elements.contains(conductor->terminal2->parentElement())) {
|
||||
m_conductors_to_move.removeAll(conductor);
|
||||
if (!m_conductors_to_update.contains(conductor))
|
||||
m_conductors_to_update << conductor;
|
||||
}
|
||||
}
|
||||
|
||||
return count_;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief DiagramContent::removePinnedGroups
|
||||
A group (#1070) with a locked member does not move at all: moving the
|
||||
rest would pull the group apart around the member that stays (#1146).
|
||||
Only a locked member that is in this content pins its group.
|
||||
Called first by removeNonMovableItems(), while the locked items are
|
||||
still here to be found.
|
||||
@return the number of removed items
|
||||
*/
|
||||
int DiagramContent::removePinnedGroups()
|
||||
{
|
||||
QSet<QUuid> pinned;
|
||||
for (Element *elmt : std::as_const(m_elements))
|
||||
if (!elmt->isMovable())
|
||||
pinned << ItemGroups::groupOf(elmt);
|
||||
for (DiagramImageItem *img : std::as_const(m_images))
|
||||
if (!img->isMovable())
|
||||
pinned << ItemGroups::groupOf(img);
|
||||
for (QetShapeItem *shape : std::as_const(m_shapes))
|
||||
if (!shape->isMovable())
|
||||
pinned << ItemGroups::groupOf(shape);
|
||||
pinned.remove(QUuid());
|
||||
if (pinned.isEmpty())
|
||||
return 0;
|
||||
|
||||
auto isPinned = [&pinned](const QGraphicsItem *item) {
|
||||
return pinned.contains(ItemGroups::groupOf(item));
|
||||
};
|
||||
return int(m_elements.removeIf(isPinned)
|
||||
+ m_images.removeIf(isPinned)
|
||||
+ m_shapes.removeIf(isPinned)
|
||||
+ m_text_fields.removeIf(isPinned));
|
||||
}
|
||||
|
||||
DiagramContent &DiagramContent::operator+=(const DiagramContent &other)
|
||||
{
|
||||
for(Element *elmt : other.m_elements)
|
||||
|
||||
@@ -100,6 +100,9 @@ class DiagramContent
|
||||
DiagramContent& operator+=(const DiagramContent& other);
|
||||
bool potentialIsManaged(QList<Conductor *>conductors);
|
||||
bool hasTextEditing();
|
||||
|
||||
private:
|
||||
int removePinnedGroups();
|
||||
};
|
||||
QDebug &operator<<(QDebug, DiagramContent &);
|
||||
#endif
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "autobreakconductor.h"
|
||||
#include "conductorautonumerotation.h"
|
||||
#include "diagram.h"
|
||||
#include "itemgroups.h"
|
||||
#include "qetgraphicsitem/conductor.h"
|
||||
#include "qetgraphicsitem/conductortextitem.h"
|
||||
#include "qetgraphicsitem/diagramimageitem.h"
|
||||
@@ -61,6 +62,8 @@ bool ElementsMover::isReady() const
|
||||
*/
|
||||
int ElementsMover::beginMovement(Diagram *diagram, QGraphicsItem *driver_item)
|
||||
{
|
||||
m_driver_held = false;
|
||||
|
||||
// They must be no movement in progress
|
||||
if (m_movement_running) return(-1);
|
||||
|
||||
@@ -86,6 +89,17 @@ int ElementsMover::beginMovement(Diagram *diagram, QGraphicsItem *driver_item)
|
||||
m_moved_content = DiagramContent(diagram);
|
||||
m_moved_content.removeNonMovableItems();
|
||||
|
||||
//A grouped driver left out of the move belongs to a group that one
|
||||
//locked member holds in place: it stays with the group
|
||||
m_driver_held = driver_item
|
||||
&& !ItemGroups::groupOf(driver_item).isNull()
|
||||
&& !m_moved_content.items().contains(driver_item);
|
||||
if (m_driver_held && m_status_bar) {
|
||||
m_status_bar->showMessage(QObject::tr(
|
||||
"Ce groupe ne peut pas être déplacé : "
|
||||
"la position d'un de ses éléments est verrouillée."));
|
||||
}
|
||||
|
||||
//Remove element text and text group, if the parent element is selected.
|
||||
const auto element_text{m_moved_content.m_element_texts};
|
||||
for(const auto &deti : element_text) {
|
||||
@@ -109,6 +123,17 @@ int ElementsMover::beginMovement(Diagram *diagram, QGraphicsItem *driver_item)
|
||||
return(m_moved_content.count());
|
||||
}
|
||||
|
||||
/**
|
||||
@brief ElementsMover::holds
|
||||
@return true if @a item is the item the user drags and it must not move:
|
||||
it is in a group that a locked member keeps in place (#1146). Each item
|
||||
that drives a movement asks before moving itself.
|
||||
*/
|
||||
bool ElementsMover::holds(const QGraphicsItem *item) const
|
||||
{
|
||||
return m_driver_held && item && item == m_movement_driver;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief ElementsMover::continueMovement
|
||||
Add a move to the current movement.
|
||||
@@ -255,7 +280,8 @@ void ElementsMover::endMovement()
|
||||
m_movement_running = false;
|
||||
m_moved_content.clear();
|
||||
|
||||
if (m_status_bar) {
|
||||
//Keep saying why a held group did not move
|
||||
if (m_status_bar && !m_driver_held) {
|
||||
m_status_bar->clearMessage();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ class ElementsMover {
|
||||
int beginMovement(Diagram *, QGraphicsItem * = nullptr);
|
||||
void continueMovement(const QPointF &);
|
||||
void endMovement();
|
||||
bool holds(const QGraphicsItem *item) const;
|
||||
|
||||
// attributes
|
||||
private:
|
||||
@@ -59,6 +60,7 @@ class ElementsMover {
|
||||
QPointF m_current_movement;
|
||||
Diagram *m_diagram{nullptr};
|
||||
QGraphicsItem *m_movement_driver{nullptr};
|
||||
bool m_driver_held{false};
|
||||
DiagramContent m_moved_content;
|
||||
QPointer<QStatusBar> m_status_bar;
|
||||
|
||||
|
||||
@@ -366,6 +366,12 @@ void DiagramTextItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
|
||||
if(diagram_ && m_first_move)
|
||||
diagram_->elementsMover().beginMovement(diagram_, this);
|
||||
|
||||
if (diagram_ && diagram_->elementsMover().holds(this)) {
|
||||
m_first_move = false;
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
QPointF old_pos = pos();
|
||||
|
||||
//Set the actual pos
|
||||
|
||||
@@ -144,6 +144,11 @@ void QetGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
//It's the first movement, we signal it to parent diagram
|
||||
diagram()->elementsMover().beginMovement(diagram(), this);
|
||||
}
|
||||
if (diagram() && diagram()->elementsMover().holds(this)) {
|
||||
m_first_move = false;
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
//we apply the mouse movement
|
||||
QPointF old_pos = pos();
|
||||
|
||||
Reference in New Issue
Block a user