1 /*
2 	Copyright 2006-2012 Xavier Guerrin
3 	This file is part of QElectroTech.
4 
5 	QElectroTech is free software: you can redistribute it and/or modify
6 	it under the terms of the GNU General Public License as published by
7 	the Free Software Foundation, either version 2 of the License, or
8 	(at your option) any later version.
9 
10 	QElectroTech is distributed in the hope that it will be useful,
11 	but WITHOUT ANY WARRANTY; without even the implied warranty of
12 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 	GNU General Public License for more details.
14 
15 	You should have received a copy of the GNU General Public License
16 	along with QElectroTech.  If not, see <http://www.gnu.org/licenses/>.
17 */
18 #include "elementtextsmover.h"
19 #include "diagram.h"
20 #include "QPropertyUndoCommand/qpropertyundocommand.h"
21 #include "dynamicelementtextitem.h"
22 #include "elementtextitemgroup.h"
23 #include <QObject>
24 
25 /**
26  * @brief ElementTextsMover::ElementTextsMover
27  */
ElementTextsMover()28 ElementTextsMover::ElementTextsMover() {}
29 
30 /**
31  * @brief ElementTextsMover::isReady
32  * @return true if this ElementTextsMover is ready to process a new movement.
33  * False if this ElementTextsMover is actually process a movement
34  */
isReady() const35 bool ElementTextsMover::isReady() const {
36 	return(!m_movement_running);
37 }
38 
39 /**
40  * @brief ElementTextsMover::beginMovement
41  * Begin a movement
42  * @param diagram : diagram where the movement is apply
43  * @param driver_item : item moved by the mouse
44  * @return : the number of moved text (driver_item include), or -1 if this ElementTextsMover can't begin a movement
45  */
beginMovement(Diagram * diagram,QGraphicsItem * driver_item)46 int ElementTextsMover::beginMovement(Diagram *diagram, QGraphicsItem *driver_item)
47 {
48 	if (m_movement_running || !diagram)
49 		return(-1);
50 
51 	m_diagram = diagram;
52 	m_movement_driver = driver_item;
53 	m_items_hash.clear();
54 	m_text_count = m_group_count =0;
55 
56 	for(QGraphicsItem *item : diagram->selectedItems())
57 	{
58 		 if(item->type() == DynamicElementTextItem::Type)
59 		 {
60 			 m_items_hash.insert(item, item->pos());
61 			 m_text_count++;
62 		 }
63 		 else if(item->type() == QGraphicsItemGroup::Type)
64 		 {
65 			 if(dynamic_cast<ElementTextItemGroup *>(item))
66 			 {
67 				 m_items_hash.insert(item, item->pos());
68 				 m_group_count++;
69 			 }
70 		 }
71 	}
72 
73 
74 	if(m_items_hash.isEmpty())
75 		return -1;
76 
77 	m_movement_running = true;
78 
79 	return m_items_hash.size();
80 }
81 
continueMovement(QGraphicsSceneMouseEvent * event)82 void ElementTextsMover::continueMovement(QGraphicsSceneMouseEvent *event)
83 {
84 	if(!m_movement_running)
85 		return;
86 
87 	for(QGraphicsItem *qgi : m_items_hash.keys())
88 	{
89 		if(qgi == m_movement_driver)
90 			continue;
91 
92 		QPointF current_parent_pos;
93 		QPointF button_down_parent_pos;
94 
95 		current_parent_pos = qgi->mapToParent(qgi->mapFromScene(event->scenePos()));
96 		button_down_parent_pos = qgi->mapToParent(qgi->mapFromScene(event->buttonDownScenePos(Qt::LeftButton)));
97 
98 		QPointF new_pos = m_items_hash.value(qgi) + current_parent_pos - button_down_parent_pos;
99 		event->modifiers() == Qt::ControlModifier ? qgi->setPos(new_pos) : qgi->setPos(Diagram::snapToGrid(new_pos));
100 	}
101 }
102 
103 /**
104  * @brief ElementTextsMover::endMovement
105  * Finish the movement by pushing an undo command to the parent diagram of text item
106  */
endMovement()107 void ElementTextsMover::endMovement()
108 {
109 		//No movement or no items to move
110 	if(!m_movement_running || m_items_hash.isEmpty())
111 		return;
112 
113 		//Movement is null
114 	QGraphicsItem *qgi = m_items_hash.keys().first();
115 	if(qgi->pos() == m_items_hash.value(qgi))
116 		return;
117 
118 	QUndoCommand *undo = new QUndoCommand(undoText());
119 
120 	for (QGraphicsItem *qgi : m_items_hash.keys())
121 	{
122 		if(QObject *object = dynamic_cast<QObject *>(qgi))
123 		{
124 			QPropertyUndoCommand *child_undo = new QPropertyUndoCommand(object, "pos", m_items_hash.value(qgi), qgi->pos(), undo);
125 			child_undo->enableAnimation();
126 		}
127 	}
128 
129 	m_diagram->undoStack().push(undo);
130 
131 	m_movement_running = false;
132 }
133 
undoText() const134 QString ElementTextsMover::undoText() const
135 {
136 	QString undo_text;
137 
138 	if(m_text_count == 1)
139 		undo_text.append(QObject::tr("Déplacer un texte d'élément"));
140 	else if(m_text_count > 1)
141 		undo_text.append(QObject::tr("Déplacer %1 textes d'élément").arg(m_items_hash.size()));
142 
143 	if(m_group_count >= 1)
144 	{
145 		if(undo_text.isEmpty())
146 			undo_text.append(QObject::tr("Déplacer"));
147 		else
148 			undo_text.append(QObject::tr(" et"));
149 
150 		if(m_group_count == 1)
151 			undo_text.append(QObject::tr(" un groupe de texte"));
152 		else
153 			undo_text.append(QObject::tr((" %1 groupes de textes")).arg(m_group_count));
154 	}
155 
156 	return undo_text;
157 }
158