mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2025-12-17 20:50:34 +01:00
Texts group item can be rotate.
The keybord shortcut for texts group alignment change. Now it's ctrl + arrow-left/up/right git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@5141 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
@@ -39,6 +39,8 @@
|
||||
#include "element.h"
|
||||
#include "diagramview.h"
|
||||
#include "dynamicelementtextitem.h"
|
||||
#include "elementtextitemgroup.h"
|
||||
#include "undocommand/addelementtextcommand.h"
|
||||
|
||||
const int Diagram::xGrid = 10;
|
||||
const int Diagram::yGrid = 10;
|
||||
@@ -291,10 +293,10 @@ void Diagram::wheelEvent(QGraphicsSceneWheelEvent *event)
|
||||
* Else move selected elements
|
||||
* @param e
|
||||
*/
|
||||
void Diagram::keyPressEvent(QKeyEvent *e)
|
||||
void Diagram::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
if (m_event_interface)
|
||||
if(m_event_interface->keyPressEvent(e))
|
||||
if(m_event_interface->keyPressEvent(event))
|
||||
{
|
||||
if(!m_event_interface->isRunning())
|
||||
{
|
||||
@@ -302,44 +304,76 @@ void Diagram::keyPressEvent(QKeyEvent *e)
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool transmit_event = true;
|
||||
if (!isReadOnly()) {
|
||||
|
||||
if (!isReadOnly())
|
||||
{
|
||||
QPointF movement;
|
||||
qreal top_position = 0;
|
||||
qreal left_position = 0;
|
||||
QList<QGraphicsItem*> selected_elmts = this->selectedContent().items();
|
||||
if (!this->selectedContent().items(DiagramContent::All).isEmpty()) {
|
||||
switch(e -> key()) {
|
||||
case Qt::Key_Left:
|
||||
foreach (Element *item, selectedContent().m_elements) {
|
||||
left_position = item->mapRectFromScene(item->boundingRect()).x();
|
||||
if (left_position >= this->sceneRect().left() - item->boundingRect().width())
|
||||
DiagramContent dc(this);
|
||||
if (!dc.items(DiagramContent::All).isEmpty())
|
||||
{
|
||||
//Move item with the keyborb arrow
|
||||
if(event->modifiers() == Qt::NoModifier)
|
||||
{
|
||||
switch(event->key())
|
||||
{
|
||||
case Qt::Key_Left:
|
||||
for (Element *item : dc.m_elements)
|
||||
{
|
||||
left_position = item->mapRectFromScene(item->boundingRect()).x();
|
||||
if (left_position >= this->sceneRect().left() - item->boundingRect().width())
|
||||
return;
|
||||
}
|
||||
movement = QPointF(-xGrid, 0.0);
|
||||
break;
|
||||
case Qt::Key_Right:
|
||||
movement = QPointF(+xGrid, 0.0);
|
||||
break;
|
||||
case Qt::Key_Up:
|
||||
for(Element *item : dc.m_elements)
|
||||
{
|
||||
top_position = item->mapRectFromScene(item->boundingRect()).y();
|
||||
if (top_position >= this->sceneRect().top() - item->boundingRect().height())
|
||||
return;
|
||||
}
|
||||
movement = QPointF(0.0, -yGrid);
|
||||
break;
|
||||
case Qt::Key_Down:
|
||||
movement = QPointF(0.0, +yGrid);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!movement.isNull() && !focusItem())
|
||||
{
|
||||
beginMoveElements();
|
||||
continueMoveElements(movement);
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
movement = QPointF(-xGrid, 0.0);
|
||||
break;
|
||||
case Qt::Key_Right: movement = QPointF(+xGrid, 0.0); break;
|
||||
case Qt::Key_Up:
|
||||
foreach (Element *item, selectedContent().m_elements) {
|
||||
top_position = item->mapRectFromScene(item->boundingRect()).y();
|
||||
if (top_position >= this->sceneRect().top() - item->boundingRect().height())
|
||||
return;
|
||||
}
|
||||
else if(event->modifiers() == Qt::ControlModifier)
|
||||
{
|
||||
//Adjust the alignment of a texts group
|
||||
if(selectedItems().size() == 1 && selectedItems().first()->type() == QGraphicsItemGroup::Type)
|
||||
{
|
||||
if(ElementTextItemGroup *etig = dynamic_cast<ElementTextItemGroup *>(selectedItems().first()))
|
||||
{
|
||||
if(event->key() == Qt::Key_Left && etig->alignment() != Qt::AlignLeft)
|
||||
undoStack().push(new AlignmentTextsGroupCommand(etig, Qt::AlignLeft));
|
||||
|
||||
else if (event->key() == Qt::Key_Up && etig->alignment() != Qt::AlignVCenter)
|
||||
undoStack().push(new AlignmentTextsGroupCommand(etig, Qt::AlignVCenter));
|
||||
|
||||
else if (event->key() == Qt::Key_Right && etig->alignment() != Qt::AlignRight)
|
||||
undoStack().push(new AlignmentTextsGroupCommand(etig, Qt::AlignRight));
|
||||
}
|
||||
}
|
||||
movement = QPointF(0.0, -yGrid);
|
||||
break;
|
||||
case Qt::Key_Down: movement = QPointF(0.0, +yGrid); break;
|
||||
}
|
||||
if (!movement.isNull() && !focusItem()) {
|
||||
beginMoveElements();
|
||||
continueMoveElements(movement);
|
||||
e -> accept();
|
||||
transmit_event = false;
|
||||
}
|
||||
}
|
||||
if (transmit_event) {
|
||||
QGraphicsScene::keyPressEvent(e);
|
||||
}
|
||||
}
|
||||
|
||||
event->ignore();
|
||||
QGraphicsScene::keyPressEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1659,25 +1693,6 @@ QSet<Conductor *> Diagram::selectedConductors() const {
|
||||
return(conductors_set);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Diagram::selectedTexts
|
||||
* @return A list of every selected texts (every kind of texts)
|
||||
*/
|
||||
QSet<DiagramTextItem *> Diagram::selectedTexts() const
|
||||
{
|
||||
QSet<DiagramTextItem *> selected_texts;
|
||||
for(QGraphicsItem *qgi : selectedItems())
|
||||
{
|
||||
if (qgi->type() == ConductorTextItem::Type ||
|
||||
qgi->type() == ElementTextItem::Type ||
|
||||
qgi->type() == IndependentTextItem::Type ||
|
||||
qgi->type() == DynamicElementTextItem::Type)
|
||||
selected_texts << static_cast<DiagramTextItem *>(qgi);
|
||||
}
|
||||
|
||||
return(selected_texts);
|
||||
}
|
||||
|
||||
/// @return true si le presse-papier semble contenir un schema
|
||||
bool Diagram::clipboardMayContainDiagram() {
|
||||
QString clipboard_text = QApplication::clipboard() -> text().trimmed();
|
||||
@@ -1760,62 +1775,6 @@ DiagramContent Diagram::content() const {
|
||||
return(dc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Diagram::selectedContent
|
||||
* @return the selected items, stored in a DiagramContent
|
||||
*/
|
||||
DiagramContent Diagram::selectedContent()
|
||||
{
|
||||
DiagramContent dc;
|
||||
|
||||
//Get the selected items
|
||||
for (QGraphicsItem *item : selectedItems())
|
||||
{
|
||||
if (Element *elmt = qgraphicsitem_cast<Element *>(item))
|
||||
dc.m_elements << elmt;
|
||||
else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item))
|
||||
dc.m_text_fields << iti;
|
||||
else if (Conductor *c = qgraphicsitem_cast<Conductor *>(item))
|
||||
{
|
||||
// recupere les conducteurs selectionnes isoles (= non deplacables mais supprimables)
|
||||
if (
|
||||
!c -> terminal1 -> parentItem() -> isSelected() &&\
|
||||
!c -> terminal2 -> parentItem() -> isSelected()
|
||||
) {
|
||||
dc.m_other_conductors << c;
|
||||
}
|
||||
}
|
||||
else if (DiagramImageItem *dii = qgraphicsitem_cast<DiagramImageItem *>(item))
|
||||
dc.m_images << dii;
|
||||
else if (QetShapeItem *dsi = qgraphicsitem_cast<QetShapeItem *>(item))
|
||||
dc.m_shapes << dsi;
|
||||
else if (DynamicElementTextItem *deti = qgraphicsitem_cast<DynamicElementTextItem *>(item))
|
||||
dc.m_element_texts << deti;
|
||||
}
|
||||
|
||||
//For each selected element, we determine if conductors must be moved or updated.
|
||||
for(Element *elmt : dc.m_elements) {
|
||||
for(Terminal *terminal : elmt -> terminals()) {
|
||||
for(Conductor *conductor : terminal -> conductors()) {
|
||||
Terminal *other_terminal;
|
||||
if (conductor -> terminal1 == terminal) {
|
||||
other_terminal = conductor -> terminal2;
|
||||
} else {
|
||||
other_terminal = conductor -> terminal1;
|
||||
}
|
||||
// si les deux elements du conducteur sont deplaces
|
||||
if (dc.m_elements.contains(other_terminal -> parentElement())) {
|
||||
dc.m_conductors_to_move << conductor;
|
||||
} else {
|
||||
dc.m_conductors_to_update << conductor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(dc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Diagram::canRotateSelection
|
||||
* @return True if a least one of selected items can be rotated
|
||||
@@ -1829,7 +1788,12 @@ bool Diagram::canRotateSelection() const
|
||||
qgi->type() == DiagramImageItem::Type ||
|
||||
qgi->type() == ElementTextItem::Type ||
|
||||
qgi->type() == Element::Type ||
|
||||
qgi->type() == DynamicElementTextItem::Type) return true;
|
||||
qgi->type() == DynamicElementTextItem::Type)
|
||||
return true;
|
||||
|
||||
if(qgi->type() == QGraphicsItemGroup::Type)
|
||||
if(dynamic_cast<ElementTextItemGroup *>(qgi))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -121,7 +121,7 @@ class Diagram : public QGraphicsScene
|
||||
void mouseMoveEvent (QGraphicsSceneMouseEvent *event) override;
|
||||
void mouseReleaseEvent (QGraphicsSceneMouseEvent *event) override;
|
||||
void wheelEvent (QGraphicsSceneWheelEvent *event) override;
|
||||
void keyPressEvent (QKeyEvent *) override;
|
||||
void keyPressEvent (QKeyEvent *event) override;
|
||||
void keyReleaseEvent (QKeyEvent *) override;
|
||||
|
||||
public:
|
||||
@@ -187,10 +187,8 @@ class Diagram : public QGraphicsScene
|
||||
QList<CustomElement *> customElements() const;
|
||||
QList<Element *> elements() const;
|
||||
QList<Conductor *> conductors() const;
|
||||
QSet<DiagramTextItem *> selectedTexts() const;
|
||||
QSet<Conductor *> selectedConductors() const;
|
||||
DiagramContent content() const;
|
||||
DiagramContent selectedContent();
|
||||
bool canRotateSelection() const;
|
||||
int beginMoveElements(QGraphicsItem * = nullptr);
|
||||
void continueMoveElements(const QPointF &);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "diagram.h"
|
||||
#include "qetgraphicsitem/diagramtextitem.h"
|
||||
#include "qetgraphicsitem/diagramimageitem.h"
|
||||
#include "elementtextitemgroup.h"
|
||||
#include <QPropertyAnimation>
|
||||
|
||||
QString itemText(const QetGraphicsItem *item) {
|
||||
@@ -266,32 +267,36 @@ void MoveElementsCommand::redo() {
|
||||
* Move item and conductor to @actual_movement
|
||||
* @param actual_movement movement to be applied
|
||||
*/
|
||||
void MoveElementsCommand::move(const QPointF &actual_movement) {
|
||||
void MoveElementsCommand::move(const QPointF &actual_movement)
|
||||
{
|
||||
typedef DiagramContent dc;
|
||||
|
||||
//Move every movable item, except conductor
|
||||
foreach (QGraphicsItem *qgi, content_to_move.items(dc::Elements | dc::TextFields | dc::Images | dc::Shapes)) {
|
||||
//If curent item have parent, and parent item is in content_to_move
|
||||
//we don't apply movement to this item, because this item will be moved by is parent.
|
||||
if (qgi->parentItem()) {
|
||||
//Move every movable items, except conductor
|
||||
for (QGraphicsItem *qgi : content_to_move.items(dc::Elements | dc::TextFields | dc::Images | dc::Shapes | dc::TextGroup))
|
||||
{
|
||||
//If curent item have parent, and parent item is in content_to_move
|
||||
//we don't apply movement to this item, because this item will be moved by is parent.
|
||||
if (qgi->parentItem())
|
||||
if (content_to_move.items().contains(qgi->parentItem()))
|
||||
continue;
|
||||
}
|
||||
if(qgi->toGraphicsObject()) {
|
||||
|
||||
if(qgi->toGraphicsObject())
|
||||
setupAnimation(qgi->toGraphicsObject(), "pos", qgi->pos(), qgi->pos() + actual_movement);
|
||||
else if(qgi->type() == QGraphicsItemGroup::Type) //ElementTextItemGroup is a QObject but not a QGraphicsObject
|
||||
{
|
||||
if(ElementTextItemGroup *etig = dynamic_cast<ElementTextItemGroup *>(qgi))
|
||||
setupAnimation(etig, "pos", etig->pos(), etig->pos() + actual_movement);
|
||||
}
|
||||
else qgi -> setPos(qgi->pos() + actual_movement);
|
||||
}
|
||||
|
||||
// Move some conductors
|
||||
foreach(Conductor *conductor, content_to_move.m_conductors_to_move) {
|
||||
// Move some conductors
|
||||
for (Conductor *conductor : content_to_move.m_conductors_to_move)
|
||||
setupAnimation(conductor, "pos", conductor->pos(), conductor->pos() + actual_movement);
|
||||
}
|
||||
|
||||
// Recalcul the path of other conductor
|
||||
foreach(Conductor *conductor, content_to_move.m_conductors_to_update) {
|
||||
// Recalcul the path of other conductor
|
||||
for (Conductor *conductor : content_to_move.m_conductors_to_update)
|
||||
setupAnimation(conductor, "animPath", 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -440,137 +445,6 @@ void ChangeDiagramTextCommand::redo() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Constructeur
|
||||
@param elements Elements a pivoter associes a leur orientation d'origine
|
||||
@param texts Textes a pivoter
|
||||
@param parent QUndoCommand parent
|
||||
*/
|
||||
RotateElementsCommand::RotateElementsCommand(const QList<Element *> &elements, const QList<DiagramTextItem *> &texts, const QList<DiagramImageItem *> &images, QUndoCommand *parent) :
|
||||
QUndoCommand(parent),
|
||||
elements_to_rotate(elements),
|
||||
texts_to_rotate(texts),
|
||||
images_to_rotate(images),
|
||||
applied_rotation_angle_(90.0)
|
||||
{
|
||||
if(elements_to_rotate.size()) diagram = elements_to_rotate.first()->diagram();
|
||||
else if (texts_to_rotate.size()) diagram = texts_to_rotate.first()->diagram();
|
||||
else if (images_to_rotate.size()) diagram = images_to_rotate.first()->diagram();
|
||||
|
||||
setText(
|
||||
QString(
|
||||
QObject::tr(
|
||||
"pivoter %1",
|
||||
"undo caption - %1 is a sentence listing the rotated content"
|
||||
)
|
||||
).arg(QET::ElementsAndConductorsSentence(elements.count(), 0, texts.count(), images.count()))
|
||||
);
|
||||
}
|
||||
|
||||
/// Destructeur
|
||||
RotateElementsCommand::~RotateElementsCommand() {
|
||||
}
|
||||
|
||||
/// defait le pivotement
|
||||
void RotateElementsCommand::undo() {
|
||||
diagram -> showMe();
|
||||
foreach(Element *e, elements_to_rotate) {
|
||||
e -> rotateBy(-applied_rotation_angle_);
|
||||
}
|
||||
foreach(DiagramTextItem *dti, texts_to_rotate) {
|
||||
//ConductorTextItem have a default rotation angle, we apply a specific treatment
|
||||
if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(dti)) {
|
||||
cti -> forceRotateByUser(previous_rotate_by_user_[cti]);
|
||||
(cti -> wasRotateByUser()) ? cti -> rotateBy(-applied_rotation_angle_) :
|
||||
cti -> parentConductor() -> calculateTextItemPosition();
|
||||
}
|
||||
else {dti -> rotateBy(-applied_rotation_angle_);}
|
||||
}
|
||||
foreach(DiagramImageItem *dii, images_to_rotate) dii -> rotateBy(-applied_rotation_angle_);
|
||||
}
|
||||
|
||||
/// refait le pivotement
|
||||
void RotateElementsCommand::redo() {
|
||||
diagram -> showMe();
|
||||
foreach(Element *e, elements_to_rotate) {
|
||||
e -> rotateBy(applied_rotation_angle_);
|
||||
}
|
||||
foreach(DiagramTextItem *dti, texts_to_rotate) {
|
||||
//we grab the previous rotation by user of each ConductorTextItem
|
||||
if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(dti)) {
|
||||
previous_rotate_by_user_.insert(cti, cti -> wasRotateByUser());
|
||||
cti -> forceRotateByUser(true);
|
||||
}
|
||||
dti -> rotateBy(applied_rotation_angle_);
|
||||
}
|
||||
foreach(DiagramImageItem *dii, images_to_rotate) dii -> rotateBy(applied_rotation_angle_);
|
||||
}
|
||||
|
||||
/**
|
||||
Constructeur
|
||||
@param texts Liste des textes impactes par l'action. L'objet retiendra leur angle de rotation au moment de sa construction.
|
||||
@param applied_rotation Nouvel angle de rotation, a appliquer au textes concernes
|
||||
@param parent QUndoCommand parent
|
||||
*/
|
||||
RotateTextsCommand::RotateTextsCommand(const QList<DiagramTextItem *> &texts, double applied_rotation, QUndoCommand *parent) :
|
||||
QUndoCommand(parent),
|
||||
m_applied_rotation_angle(applied_rotation),
|
||||
m_diagram(texts.first()->diagram())
|
||||
{
|
||||
foreach(DiagramTextItem *text, texts) {
|
||||
m_texts_to_rotate.insert(text, text -> rotationAngle());
|
||||
}
|
||||
defineCommandName();
|
||||
}
|
||||
|
||||
/**
|
||||
Destructeur
|
||||
*/
|
||||
RotateTextsCommand::~RotateTextsCommand() {
|
||||
}
|
||||
|
||||
/**
|
||||
Annule la rotation des textes
|
||||
*/
|
||||
void RotateTextsCommand::undo() {
|
||||
m_diagram -> showMe();
|
||||
foreach(DiagramTextItem *text, m_texts_to_rotate.keys()) {
|
||||
if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(text))
|
||||
cti -> forceRotateByUser(m_previous_rotate_by_user[cti]);
|
||||
text -> setRotationAngle(m_texts_to_rotate[text]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Applique l'angle de rotation aux textes
|
||||
*/
|
||||
void RotateTextsCommand::redo() {
|
||||
m_diagram -> showMe();
|
||||
foreach(DiagramTextItem *text, m_texts_to_rotate.keys()) {
|
||||
if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(text)) {
|
||||
//we grab the previous rotation by user of each ConductorTextItem
|
||||
m_previous_rotate_by_user.insert(cti, cti -> wasRotateByUser());
|
||||
cti -> forceRotateByUser(true);
|
||||
}
|
||||
text -> setRotationAngle(m_applied_rotation_angle);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Definit le nom de la commande d'annulation
|
||||
*/
|
||||
void RotateTextsCommand::defineCommandName() {
|
||||
setText(
|
||||
QString(
|
||||
QObject::tr(
|
||||
"orienter %1 à %2°",
|
||||
"undo caption - %1 looks like '42 texts', %2 is a rotation angle"
|
||||
)
|
||||
).arg(QET::ElementsAndConductorsSentence(0, 0, m_texts_to_rotate.count()))
|
||||
.arg(m_applied_rotation_angle)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
Constructeur
|
||||
@param c Conducteur modifie
|
||||
|
||||
@@ -215,69 +215,6 @@ class ChangeDiagramTextCommand : public QUndoCommand {
|
||||
Diagram *diagram;
|
||||
};
|
||||
|
||||
/**
|
||||
This command rotates several elements or text items by a particular angle.
|
||||
*/
|
||||
class RotateElementsCommand : public QUndoCommand {
|
||||
// constructors, destructor
|
||||
public:
|
||||
RotateElementsCommand(const QList<Element *> &elements, const QList<DiagramTextItem *> &, const QList<DiagramImageItem *> &, QUndoCommand * = nullptr);
|
||||
~RotateElementsCommand() override;
|
||||
private:
|
||||
RotateElementsCommand(const RotateElementsCommand &);
|
||||
|
||||
// methods
|
||||
public:
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
|
||||
// attributes
|
||||
private:
|
||||
/// hold rotated elements along with their former orientation
|
||||
QList<Element *> elements_to_rotate;
|
||||
/// text items to be rotated
|
||||
QList<DiagramTextItem *> texts_to_rotate;
|
||||
/// images item to be rotated
|
||||
QList<DiagramImageItem *> images_to_rotate;
|
||||
/// angle of rotation to be applied to text items
|
||||
qreal applied_rotation_angle_;
|
||||
/// previous state of each conductor text item
|
||||
QHash<ConductorTextItem *, bool> previous_rotate_by_user_;
|
||||
Diagram *diagram;
|
||||
};
|
||||
|
||||
/**
|
||||
This command directs several text items to a same particular angle of
|
||||
rotation.
|
||||
*/
|
||||
class RotateTextsCommand : public QUndoCommand
|
||||
{
|
||||
// constructors, destructor
|
||||
public:
|
||||
RotateTextsCommand(const QList<DiagramTextItem *> &, double, QUndoCommand * = nullptr);
|
||||
~RotateTextsCommand() override;
|
||||
private:
|
||||
RotateTextsCommand(const RotateTextsCommand &);
|
||||
|
||||
// methods
|
||||
public:
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
|
||||
private:
|
||||
void defineCommandName();
|
||||
|
||||
// attributes
|
||||
private:
|
||||
/// hold rotated text items along with their former angle of rotation
|
||||
QHash<DiagramTextItem *, double> m_texts_to_rotate;
|
||||
/// angle of rotation of all text items after the command
|
||||
double m_applied_rotation_angle;
|
||||
/// previous state of each conductor text item
|
||||
QHash<ConductorTextItem *, bool> m_previous_rotate_by_user;
|
||||
Diagram *m_diagram;
|
||||
};
|
||||
|
||||
/**
|
||||
This command changes a particular conductor.
|
||||
*/
|
||||
|
||||
@@ -24,12 +24,73 @@
|
||||
#include "elementtextitem.h"
|
||||
#include "qetshapeitem.h"
|
||||
#include "dynamicelementtextitem.h"
|
||||
#include "elementtextitemgroup.h"
|
||||
#include "diagram.h"
|
||||
#include "terminal.h"
|
||||
#include "conductortextitem.h"
|
||||
|
||||
/**
|
||||
* @brief DiagramContent::DiagramContent
|
||||
*/
|
||||
DiagramContent::DiagramContent() {}
|
||||
|
||||
/**
|
||||
* @brief DiagramContent::DiagramContent
|
||||
* Constructor
|
||||
* @param diagram : Construct a diagramContent and fill it with the selected item of @diagram
|
||||
*/
|
||||
DiagramContent::DiagramContent(Diagram *diagram) :
|
||||
m_selected_items(diagram->selectedItems())
|
||||
{
|
||||
//Get the selected items
|
||||
for (QGraphicsItem *item : m_selected_items)
|
||||
{
|
||||
if (Element *elmt = qgraphicsitem_cast<Element *>(item))
|
||||
m_elements << elmt;
|
||||
else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item))
|
||||
m_text_fields << iti;
|
||||
else if (Conductor *c = qgraphicsitem_cast<Conductor *>(item))
|
||||
{
|
||||
//Get the isolated selected conductor (= not movable, but deletable)
|
||||
if (!c->terminal1->parentItem()->isSelected() &&\
|
||||
!c->terminal2->parentItem()->isSelected()) {
|
||||
m_other_conductors << c;
|
||||
}
|
||||
}
|
||||
else if (DiagramImageItem *dii = qgraphicsitem_cast<DiagramImageItem *>(item))
|
||||
m_images << dii;
|
||||
else if (QetShapeItem *dsi = qgraphicsitem_cast<QetShapeItem *>(item))
|
||||
m_shapes << dsi;
|
||||
else if (DynamicElementTextItem *deti = qgraphicsitem_cast<DynamicElementTextItem *>(item))
|
||||
m_element_texts << deti;
|
||||
else if (QGraphicsItemGroup *group = qgraphicsitem_cast<QGraphicsItemGroup *>(item))
|
||||
if(ElementTextItemGroup *etig = dynamic_cast<ElementTextItemGroup *>(group))
|
||||
m_texts_groups << etig;
|
||||
}
|
||||
|
||||
//For each selected element, we determine if conductors must be moved or updated.
|
||||
for(Element *elmt : m_elements)
|
||||
{
|
||||
for(Terminal *terminal : elmt->terminals())
|
||||
{
|
||||
for(Conductor *conductor : terminal->conductors())
|
||||
{
|
||||
Terminal *other_terminal;
|
||||
if (conductor->terminal1 == terminal)
|
||||
other_terminal = conductor->terminal2;
|
||||
else
|
||||
other_terminal = conductor->terminal1;
|
||||
|
||||
//If the two elements of conductor are movable
|
||||
if (m_elements.contains(other_terminal -> parentElement()))
|
||||
m_conductors_to_move << conductor;
|
||||
else
|
||||
m_conductors_to_update << conductor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DiagramContent::DiagramContent
|
||||
* Copy constructor
|
||||
@@ -43,7 +104,9 @@ DiagramContent::DiagramContent(const DiagramContent &other) :
|
||||
m_conductors_to_update(other.m_conductors_to_update),
|
||||
m_conductors_to_move(other.m_conductors_to_move),
|
||||
m_other_conductors(other.m_other_conductors),
|
||||
m_element_texts(other.m_element_texts)
|
||||
m_element_texts(other.m_element_texts),
|
||||
m_texts_groups(other.m_texts_groups),
|
||||
m_selected_items(other.m_selected_items)
|
||||
{}
|
||||
|
||||
/**
|
||||
@@ -51,6 +114,47 @@ DiagramContent::DiagramContent(const DiagramContent &other) :
|
||||
*/
|
||||
DiagramContent::~DiagramContent() {}
|
||||
|
||||
|
||||
/**
|
||||
* @brief DiagramContent::selectedTexts
|
||||
* @return a list of every selected texts (every kind of texts)
|
||||
* Note that the returned list of texts, correspond to the selected texts
|
||||
* at the moment of the creation of this DiagramContent,
|
||||
* with the constructor : DiagramContent::DiagramContent(Diagram *diagram)
|
||||
*/
|
||||
QList<DiagramTextItem *> DiagramContent::selectedTexts() const
|
||||
{
|
||||
QList<DiagramTextItem *> selected_texts;
|
||||
for(QGraphicsItem *qgi : m_selected_items)
|
||||
{
|
||||
if (qgi->type() == ConductorTextItem::Type ||
|
||||
qgi->type() == ElementTextItem::Type ||
|
||||
qgi->type() == IndependentTextItem::Type ||
|
||||
qgi->type() == DynamicElementTextItem::Type)
|
||||
selected_texts << static_cast<DiagramTextItem *>(qgi);
|
||||
}
|
||||
return(selected_texts);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DiagramContent::selectedTextsGroup
|
||||
* @return a list of selected texts group
|
||||
* Note that the returned list of texts group, correspond to the selected texts group
|
||||
* at the moment of the creation of this DiagramContent,
|
||||
* with the constructor : DiagramContent::DiagramContent(Diagram *diagram)
|
||||
*/
|
||||
QList<ElementTextItemGroup *> DiagramContent::selectedTextsGroup() const
|
||||
{
|
||||
QList<ElementTextItemGroup *> groups;
|
||||
|
||||
for(QGraphicsItem *qgi : m_selected_items)
|
||||
if(qgi->type() == QGraphicsItemGroup::Type)
|
||||
if(ElementTextItemGroup *grp = dynamic_cast<ElementTextItemGroup *>(qgi))
|
||||
groups << grp;
|
||||
|
||||
return groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DiagramContent::conductors
|
||||
* @param filter
|
||||
@@ -84,6 +188,8 @@ void DiagramContent::clear()
|
||||
m_conductors_to_move.clear();
|
||||
m_other_conductors.clear();
|
||||
m_element_texts.clear();
|
||||
m_texts_groups.clear();
|
||||
m_selected_items.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -138,6 +244,7 @@ QList<QGraphicsItem *> DiagramContent::items(int filter) const
|
||||
if (filter & Images) for(QGraphicsItem *qgi : m_images) items_list << qgi;
|
||||
if (filter & Shapes) for(QGraphicsItem *qgi : m_shapes) items_list << qgi;
|
||||
if (filter & ElementTextFields) for(QGraphicsItem *qgi : m_element_texts) items_list << qgi;
|
||||
if (filter & TextGroup) for(QGraphicsItem *qgi : m_texts_groups) items_list << qgi;
|
||||
|
||||
if (filter & SelectedOnly) {
|
||||
for(QGraphicsItem *qgi : items_list) {
|
||||
@@ -163,7 +270,8 @@ int DiagramContent::count(int filter) const
|
||||
if (filter & ConductorsToMove) for(Conductor *conductor : m_conductors_to_move) { if (conductor -> isSelected()) ++ count; }
|
||||
if (filter & ConductorsToUpdate) for(Conductor *conductor : m_conductors_to_update) { if (conductor -> isSelected()) ++ count; }
|
||||
if (filter & OtherConductors) for(Conductor *conductor : m_other_conductors) { if (conductor -> isSelected()) ++ count; }
|
||||
if (filter & ElementTextFields) for(DynamicElementTextItem *deti : m_element_texts) { if (deti -> isSelected()) ++ count; }
|
||||
if (filter & ElementTextFields) for(DynamicElementTextItem *deti : m_element_texts) { if (deti -> isSelected()) ++ count; }
|
||||
if (filter & TextGroup) for(ElementTextItemGroup *etig : m_texts_groups) { if (etig -> isSelected()) ++ count; }
|
||||
}
|
||||
else {
|
||||
if (filter & Elements) count += m_elements.count();
|
||||
@@ -174,6 +282,7 @@ int DiagramContent::count(int filter) const
|
||||
if (filter & ConductorsToUpdate) count += m_conductors_to_update.count();
|
||||
if (filter & OtherConductors) count += m_other_conductors.count();
|
||||
if (filter & ElementTextFields) count += m_element_texts.count();
|
||||
if (filter & TextGroup) count += m_texts_groups.count();
|
||||
}
|
||||
return(count);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,9 @@ class DiagramImageItem;
|
||||
class ElementTextItem;
|
||||
class QetShapeItem;
|
||||
class DynamicElementTextItem;
|
||||
class ElementTextItemGroup;
|
||||
class Diagram;
|
||||
class DiagramTextItem;
|
||||
|
||||
/**
|
||||
This class provides a container that makes the transmission of diagram content
|
||||
@@ -42,6 +45,7 @@ class DiagramContent
|
||||
{
|
||||
public:
|
||||
DiagramContent();
|
||||
DiagramContent(Diagram *diagram);
|
||||
DiagramContent(const DiagramContent &);
|
||||
~DiagramContent();
|
||||
|
||||
@@ -56,8 +60,9 @@ class DiagramContent
|
||||
OtherConductors = 64,
|
||||
AnyConductor = 112,
|
||||
Shapes = 128,
|
||||
All = 255,
|
||||
SelectedOnly = 256
|
||||
TextGroup = 256,
|
||||
All = 511,
|
||||
SelectedOnly = 512
|
||||
};
|
||||
|
||||
QSet<Element *> m_elements;
|
||||
@@ -68,7 +73,11 @@ class DiagramContent
|
||||
QSet<Conductor *> m_conductors_to_move;
|
||||
QSet<Conductor *> m_other_conductors;
|
||||
QSet<DynamicElementTextItem *> m_element_texts;
|
||||
QSet<ElementTextItemGroup *> m_texts_groups;
|
||||
QList<QGraphicsItem *> m_selected_items;
|
||||
|
||||
QList<DiagramTextItem *> selectedTexts() const;
|
||||
QList<ElementTextItemGroup *> selectedTextsGroup() const;
|
||||
QList<Conductor *> conductors(int = AnyConductor) const;
|
||||
QList<QGraphicsItem *> items(int = All) const;
|
||||
QString sentence(int = All) const;
|
||||
|
||||
@@ -28,14 +28,12 @@
|
||||
#include "qetgraphicsitem/independenttextitem.h"
|
||||
#include "qetgraphicsitem/diagramimageitem.h"
|
||||
#include "templatelocation.h"
|
||||
#include "qetapp.h"
|
||||
#include "qetproject.h"
|
||||
#include "projectview.h"
|
||||
#include "integrationmovetemplateshandler.h"
|
||||
#include "qetdiagrameditor.h"
|
||||
#include "qeticons.h"
|
||||
#include "qetmessagebox.h"
|
||||
#include "qtextorientationspinboxwidget.h"
|
||||
#include <QGraphicsObject>
|
||||
#include <QGraphicsPixmapItem>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
@@ -136,111 +134,12 @@ void DiagramView::deleteSelection()
|
||||
{
|
||||
if (m_diagram -> isReadOnly())
|
||||
return;
|
||||
DiagramContent removed_content = m_diagram->selectedContent();
|
||||
DiagramContent removed_content = DiagramContent(m_diagram);
|
||||
m_diagram->clearSelection();
|
||||
m_diagram->undoStack().push(new DeleteQGraphicsItemCommand(m_diagram, removed_content));
|
||||
adjustSceneRect();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DiagramView::rotateSelection
|
||||
* Rotate the selected items
|
||||
*/
|
||||
void DiagramView::rotateSelection()
|
||||
{
|
||||
if (m_diagram->isReadOnly())
|
||||
return;
|
||||
|
||||
QList<Element *> elements_to_rotate;
|
||||
QList<DiagramTextItem *> texts_to_rotate;
|
||||
QList<DiagramImageItem *> images_to_rotate;
|
||||
|
||||
for (QGraphicsItem *item : m_diagram->selectedItems())
|
||||
{
|
||||
if (Element *e = qgraphicsitem_cast<Element *>(item))
|
||||
elements_to_rotate << e;
|
||||
else if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(item))
|
||||
texts_to_rotate << cti;
|
||||
else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item))
|
||||
texts_to_rotate << iti;
|
||||
else if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(item))
|
||||
{
|
||||
//We rotate element text item only if is parent element is not selected
|
||||
if (eti->parentItem() && !eti->parentItem()->isSelected())
|
||||
texts_to_rotate << eti;
|
||||
}
|
||||
else if (DynamicElementTextItem *deti = qgraphicsitem_cast<DynamicElementTextItem *>(item))
|
||||
{
|
||||
//We rotate dynamic element text item only if is parent element is not selected
|
||||
if (deti->parentItem() && !deti->parentItem()->isSelected())
|
||||
texts_to_rotate << deti;
|
||||
}
|
||||
else if (DiagramImageItem *dii = qgraphicsitem_cast<DiagramImageItem *>(item))
|
||||
images_to_rotate << dii;
|
||||
}
|
||||
|
||||
//Do the rotation
|
||||
if (elements_to_rotate.isEmpty() && texts_to_rotate.isEmpty() && images_to_rotate.isEmpty())
|
||||
return;
|
||||
m_diagram->undoStack().push(new RotateElementsCommand(elements_to_rotate, texts_to_rotate, images_to_rotate));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DiagramView::rotateTexts
|
||||
* Open a dialog to set the rotation angle, and apply it to the selected texts.
|
||||
*/
|
||||
void DiagramView::rotateTexts()
|
||||
{
|
||||
if (m_diagram->isReadOnly())
|
||||
return;
|
||||
|
||||
//Get the texts fields
|
||||
QList<DiagramTextItem *> texts_to_rotate;
|
||||
for (QGraphicsItem *item : m_diagram->selectedItems())
|
||||
{
|
||||
if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(item))
|
||||
texts_to_rotate << cti;
|
||||
else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item))
|
||||
texts_to_rotate << iti;
|
||||
else if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(item))
|
||||
texts_to_rotate << eti;
|
||||
else if (DynamicElementTextItem *deti = qgraphicsitem_cast<DynamicElementTextItem *>(item))
|
||||
texts_to_rotate << deti;
|
||||
}
|
||||
|
||||
if (texts_to_rotate.isEmpty())
|
||||
return;
|
||||
|
||||
//Open the dialog
|
||||
QDialog ori_text_dialog(diagramEditor());
|
||||
ori_text_dialog.setSizeGripEnabled(false);
|
||||
#ifdef Q_OS_MAC
|
||||
ori_text_dialog.setWindowFlags(Qt::Sheet);
|
||||
#endif
|
||||
ori_text_dialog.setWindowTitle(tr("Orienter les textes sélectionnés", "window title"));
|
||||
|
||||
|
||||
QTextOrientationSpinBoxWidget *ori_widget = QETApp::createTextOrientationSpinBoxWidget();
|
||||
ori_widget -> setParent(&ori_text_dialog);
|
||||
if (texts_to_rotate.count() == 1) {
|
||||
ori_widget -> setOrientation(texts_to_rotate.at(0) -> rotationAngle());
|
||||
}
|
||||
ori_widget -> spinBox() -> selectAll();
|
||||
|
||||
QDialogButtonBox buttons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(&buttons, SIGNAL(accepted()), &ori_text_dialog, SLOT(accept()));
|
||||
connect(&buttons, SIGNAL(rejected()), &ori_text_dialog, SLOT(reject()));
|
||||
|
||||
QVBoxLayout layout_v(&ori_text_dialog);
|
||||
layout_v.setSizeConstraint(QLayout::SetFixedSize);
|
||||
layout_v.addWidget(ori_widget);
|
||||
layout_v.addStretch();
|
||||
layout_v.addWidget(&buttons);
|
||||
|
||||
if (ori_text_dialog.exec() == QDialog::Accepted)
|
||||
m_diagram -> undoStack().push(new RotateTextsCommand(texts_to_rotate, ori_widget -> orientation()));
|
||||
}
|
||||
|
||||
/**
|
||||
Accepte ou refuse le drag'n drop en fonction du type de donnees entrant
|
||||
@param e le QDragEnterEvent correspondant au drag'n drop tente
|
||||
@@ -257,14 +156,6 @@ void DiagramView::dragEnterEvent(QDragEnterEvent *e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Gere les dragleave
|
||||
@param e le QDragEnterEvent correspondant au drag'n drop sortant
|
||||
*/
|
||||
void DiagramView::dragLeaveEvent(QDragLeaveEvent *e) {
|
||||
Q_UNUSED(e);
|
||||
}
|
||||
|
||||
/**
|
||||
Accepte ou refuse le drag'n drop en fonction du type de donnees entrant
|
||||
@param e le QDragMoveEvent correspondant au drag'n drop tente
|
||||
@@ -451,7 +342,7 @@ void DiagramView::zoomReset() {
|
||||
*/
|
||||
void DiagramView::cut() {
|
||||
copy();
|
||||
DiagramContent cut_content = m_diagram -> selectedContent();
|
||||
DiagramContent cut_content(m_diagram);
|
||||
m_diagram -> clearSelection();
|
||||
m_diagram -> undoStack().push(new CutDiagramCommand(m_diagram, cut_content));
|
||||
}
|
||||
@@ -651,6 +542,7 @@ void DiagramView::keyPressEvent(QKeyEvent *e)
|
||||
return;
|
||||
|
||||
ProjectView *current_project = this->diagramEditor()->acessCurrentProject();
|
||||
DiagramContent dc(m_diagram);
|
||||
switch(e -> key())
|
||||
{
|
||||
case Qt::Key_PageUp:
|
||||
@@ -702,22 +594,22 @@ void DiagramView::keyPressEvent(QKeyEvent *e)
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Up: {
|
||||
if(!(m_diagram->selectedContent().items(DiagramContent::All).isEmpty()))
|
||||
if(!(dc.items(DiagramContent::All).isEmpty()))
|
||||
scrollOnMovement(e);
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Down: {
|
||||
if(!(m_diagram->selectedContent().items(DiagramContent::All).isEmpty()))
|
||||
if(!(dc.items(DiagramContent::All).isEmpty()))
|
||||
scrollOnMovement(e);
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Left: {
|
||||
if(!(m_diagram->selectedContent().items(DiagramContent::All).isEmpty()))
|
||||
if(!(dc.items(DiagramContent::All).isEmpty()))
|
||||
scrollOnMovement(e);
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Right: {
|
||||
if(!(m_diagram->selectedContent().items(DiagramContent::All).isEmpty()))
|
||||
if(!(dc.items(DiagramContent::All).isEmpty()))
|
||||
scrollOnMovement(e);
|
||||
}
|
||||
break;
|
||||
@@ -743,8 +635,9 @@ void DiagramView::keyReleaseEvent(QKeyEvent *e) {
|
||||
and horizontal bar. If element is moved to the right side of the editor
|
||||
or below the editor SceneRect is expanded
|
||||
*/
|
||||
void DiagramView::scrollOnMovement(QKeyEvent *e){
|
||||
QList<QGraphicsItem *> selected_elmts = m_diagram->selectedContent().items(DiagramContent::All);
|
||||
void DiagramView::scrollOnMovement(QKeyEvent *e)
|
||||
{
|
||||
QList<QGraphicsItem *> selected_elmts = DiagramContent(m_diagram).items(DiagramContent::All);
|
||||
QRectF viewed_scene = viewedSceneRect();
|
||||
foreach (QGraphicsItem *qgi, selected_elmts){
|
||||
if (qgraphicsitem_cast<Conductor *>(qgi)) continue;
|
||||
@@ -822,13 +715,6 @@ void DiagramView::editDiagramProperties() {
|
||||
DiagramPropertiesDialog::diagramPropertiesDialog(m_diagram, diagramEditor());
|
||||
}
|
||||
|
||||
/**
|
||||
@return true s'il y a des items selectionnes sur le schema, false sinon
|
||||
*/
|
||||
bool DiagramView::hasSelectedItems() {
|
||||
return(m_diagram -> selectedItems().size() > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@return true s'il y a des items selectionnes sur le schema et que ceux-ci
|
||||
peuvent etre copies dans le presse-papier, false sinon
|
||||
@@ -1011,11 +897,13 @@ void DiagramView::applyReadOnly() {
|
||||
}
|
||||
|
||||
/**
|
||||
Edite les proprietes des objets selectionnes
|
||||
*/
|
||||
void DiagramView::editSelectionProperties() {
|
||||
// get selection
|
||||
DiagramContent selection = m_diagram -> selectedContent();
|
||||
* @brief DiagramView::editSelectionProperties
|
||||
* Edit the properties of the selected items
|
||||
*/
|
||||
void DiagramView::editSelectionProperties()
|
||||
{
|
||||
// get selection
|
||||
DiagramContent selection(m_diagram);
|
||||
|
||||
// if selection contains nothing return
|
||||
int selected_items_count = selection.count(DiagramContent::All | DiagramContent::SelectedOnly);
|
||||
@@ -1048,13 +936,15 @@ void DiagramView::editSelectionProperties() {
|
||||
}
|
||||
|
||||
/**
|
||||
Edit the color of the selected conductor; does nothing if multiple conductors are selected
|
||||
*/
|
||||
void DiagramView::editSelectedConductorColor() {
|
||||
// retrieve selected content
|
||||
DiagramContent selection = m_diagram -> selectedContent();
|
||||
* @brief DiagramView::editSelectedConductorColor
|
||||
* Edit the color of the selected conductor; does nothing if multiple conductors are selected
|
||||
*/
|
||||
void DiagramView::editSelectedConductorColor()
|
||||
{
|
||||
//retrieve selected content
|
||||
DiagramContent selection(m_diagram);
|
||||
|
||||
// we'll focus on the selected conductor (we do not handle multiple conductors edition)
|
||||
// we'll focus on the selected conductor (we do not handle multiple conductors edition)
|
||||
QList<Conductor *> selected_conductors = selection.conductors(DiagramContent::AnyConductor | DiagramContent::SelectedOnly);
|
||||
if (selected_conductors.count() == 1) {
|
||||
editConductorColor(selected_conductors.at(0));
|
||||
|
||||
@@ -49,10 +49,10 @@ class DiagramView : public QGraphicsView
|
||||
|
||||
// attributes
|
||||
|
||||
Diagram *m_diagram;
|
||||
Diagram *m_diagram = nullptr;
|
||||
DVEventInterface *m_event_interface = nullptr;
|
||||
QMenu *m_context_menu;
|
||||
QAction *m_paste_here;
|
||||
QMenu *m_context_menu = nullptr;
|
||||
QAction *m_paste_here = nullptr;
|
||||
QPoint m_paste_here_pos;
|
||||
QPointF m_rubber_band_origin;
|
||||
bool m_fresh_focus_in,
|
||||
@@ -64,10 +64,8 @@ class DiagramView : public QGraphicsView
|
||||
void removeColumn();
|
||||
void addRow();
|
||||
void removeRow();
|
||||
/// @return the diagram rendered by this view
|
||||
Diagram *diagram() { return(m_diagram); }
|
||||
QETDiagramEditor *diagramEditor() const;
|
||||
bool hasSelectedItems();
|
||||
bool hasCopiableItems();
|
||||
bool hasTextItems();
|
||||
bool hasDeletableItems();
|
||||
@@ -92,7 +90,6 @@ class DiagramView : public QGraphicsView
|
||||
void mouseMoveEvent(QMouseEvent *) override;
|
||||
void mouseReleaseEvent(QMouseEvent *) override;
|
||||
void dragEnterEvent(QDragEnterEvent *) override;
|
||||
void dragLeaveEvent(QDragLeaveEvent *) override;
|
||||
void dragMoveEvent(QDragMoveEvent *) override;
|
||||
void dropEvent(QDropEvent *) override;
|
||||
void handleElementDrop(QDropEvent *);
|
||||
@@ -123,8 +120,6 @@ class DiagramView : public QGraphicsView
|
||||
void selectAll();
|
||||
void selectInvert();
|
||||
void deleteSelection();
|
||||
void rotateSelection();
|
||||
void rotateTexts();
|
||||
void setVisualisationMode();
|
||||
void setSelectionMode();
|
||||
void zoom(const qreal zoom_factor);
|
||||
|
||||
@@ -33,8 +33,8 @@ ElementsMover::ElementsMover() :
|
||||
movement_running_(false),
|
||||
current_movement_(),
|
||||
diagram_(nullptr),
|
||||
movement_driver_(nullptr),
|
||||
moved_content_()
|
||||
m_movement_driver(nullptr),
|
||||
m_moved_content()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -70,21 +70,21 @@ int ElementsMover::beginMovement(Diagram *diagram, QGraphicsItem *driver_item) {
|
||||
diagram_ = diagram;
|
||||
|
||||
// Take count of driver item
|
||||
movement_driver_ = driver_item;
|
||||
m_movement_driver = driver_item;
|
||||
|
||||
// At the beginning of movement, move is NULL
|
||||
current_movement_ = QPointF(0.0, 0.0);
|
||||
|
||||
moved_content_ = diagram -> selectedContent();
|
||||
moved_content_.removeNonMovableItems();
|
||||
m_moved_content = DiagramContent(diagram);
|
||||
m_moved_content.removeNonMovableItems();
|
||||
|
||||
if (!moved_content_.count()) return(-1);
|
||||
if (!m_moved_content.count()) return(-1);
|
||||
|
||||
/* At this point, we've got all info to manage movement.
|
||||
* There is now a move in progress */
|
||||
movement_running_ = true;
|
||||
|
||||
return(moved_content_.count());
|
||||
return(m_moved_content.count());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -99,18 +99,20 @@ void ElementsMover::continueMovement(const QPointF &movement) {
|
||||
|
||||
//Move every movable item, except conductor
|
||||
typedef DiagramContent dc;
|
||||
foreach (QGraphicsItem *qgi, moved_content_.items(dc::Elements | dc::TextFields | dc::Images | dc::Shapes)) {
|
||||
if (qgi == movement_driver_) continue;
|
||||
for (QGraphicsItem *qgi : m_moved_content.items(dc::Elements | dc::TextFields | dc::Images | dc::Shapes | dc::TextGroup))
|
||||
{
|
||||
if (qgi == m_movement_driver)
|
||||
continue;
|
||||
qgi -> setPos(qgi->pos() + movement);
|
||||
}
|
||||
|
||||
// Move some conductors
|
||||
foreach(Conductor *conductor, moved_content_.m_conductors_to_move) {
|
||||
foreach(Conductor *conductor, m_moved_content.m_conductors_to_move) {
|
||||
conductor -> setPos(conductor -> pos() + movement);
|
||||
}
|
||||
|
||||
// Recalcul the path of other conductors
|
||||
foreach(Conductor *conductor, moved_content_.m_conductors_to_update) {
|
||||
foreach(Conductor *conductor, m_moved_content.m_conductors_to_update) {
|
||||
conductor -> updatePath();
|
||||
}
|
||||
}
|
||||
@@ -131,18 +133,18 @@ void ElementsMover::endMovement()
|
||||
|
||||
//Create undo move if there is a movement
|
||||
if (!current_movement_.isNull()) {
|
||||
QUndoCommand *quc = new MoveElementsCommand(diagram_, moved_content_, current_movement_, undo_object);
|
||||
QUndoCommand *quc = new MoveElementsCommand(diagram_, m_moved_content, current_movement_, undo_object);
|
||||
undo_object->setText(quc->text());
|
||||
}
|
||||
|
||||
//There is only one element moved, and project authorize auto conductor,
|
||||
//we try auto connection of conductor;
|
||||
typedef DiagramContent dc;
|
||||
if (moved_content_.items(dc::TextFields | dc::Images | dc::Shapes).size() == 0 &&
|
||||
moved_content_.items(dc::Elements).size() == 1 &&
|
||||
if (m_moved_content.items(dc::TextFields | dc::Images | dc::Shapes).size() == 0 &&
|
||||
m_moved_content.items(dc::Elements).size() == 1 &&
|
||||
diagram_ -> project() -> autoConductor())
|
||||
{
|
||||
Element *elmt = moved_content_.m_elements.toList().first();
|
||||
Element *elmt = m_moved_content.m_elements.toList().first();
|
||||
|
||||
int acc = elmt->AlignedFreeTerminals().size();
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ class ElementsMover {
|
||||
bool movement_running_;
|
||||
QPointF current_movement_;
|
||||
Diagram *diagram_;
|
||||
QGraphicsItem *movement_driver_;
|
||||
DiagramContent moved_content_;
|
||||
QGraphicsItem *m_movement_driver;
|
||||
DiagramContent m_moved_content;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
#include "dynamicelementtextitem.h"
|
||||
#include "conductortextitem.h"
|
||||
#include "elementtextitem.h"
|
||||
#include "undocommand/rotateselectioncommand.h"
|
||||
#include "rotatetextscommand.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QStandardPaths>
|
||||
@@ -1038,12 +1040,15 @@ DiagramView *QETDiagramEditor::currentDiagram() const {
|
||||
* no element is selected
|
||||
* more than one element is selected
|
||||
*/
|
||||
Element *QETDiagramEditor::currentElement() const {
|
||||
Element *QETDiagramEditor::currentElement() const
|
||||
{
|
||||
DiagramView *dv = currentDiagram();
|
||||
if (!dv) return(nullptr);
|
||||
if (!dv)
|
||||
return(nullptr);
|
||||
|
||||
QList<Element *> selected_elements = dv -> diagram() -> selectedContent().m_elements.toList();
|
||||
if (selected_elements.count() != 1) return(nullptr);
|
||||
QList<Element *> selected_elements = DiagramContent(dv->diagram()).m_elements.toList();
|
||||
if (selected_elements.count() != 1)
|
||||
return(nullptr);
|
||||
|
||||
return(selected_elements.first());
|
||||
}
|
||||
@@ -1262,9 +1267,17 @@ void QETDiagramEditor::selectionGroupTriggered(QAction *action)
|
||||
if (value == "delete_selection")
|
||||
dv->deleteSelection();
|
||||
else if (value == "rotate_selection")
|
||||
dv->rotateSelection();
|
||||
{
|
||||
Diagram *d = dv->diagram();
|
||||
RotateSelectionCommand *c = new RotateSelectionCommand(d);
|
||||
if(c->isValid())
|
||||
d->undoStack().push(c);
|
||||
}
|
||||
else if (value == "rotate_selected_text")
|
||||
dv->rotateTexts();
|
||||
{
|
||||
Diagram *d = dv->diagram();
|
||||
d->undoStack().push(new RotateTextsCommand(d));
|
||||
}
|
||||
else if (value == "find_selected_element" && currentCustomElement())
|
||||
findElementInPanel(currentCustomElement()->location());
|
||||
else if (value == "edit_selected_element")
|
||||
@@ -1400,6 +1413,7 @@ void QETDiagramEditor::slot_updateComplexActions()
|
||||
}
|
||||
|
||||
Diagram *diagram_ = dv->diagram();
|
||||
DiagramContent dc(diagram_);
|
||||
bool ro = diagram_->isReadOnly();
|
||||
|
||||
|
||||
@@ -1408,7 +1422,7 @@ void QETDiagramEditor::slot_updateComplexActions()
|
||||
m_conductor_reset->setEnabled(!ro && selected_conductors_count);
|
||||
|
||||
// number of selected elements
|
||||
int selected_elements_count = diagram_->selectedContent().count(DiagramContent::Elements);
|
||||
int selected_elements_count = dc.count(DiagramContent::Elements);
|
||||
m_find_element->setEnabled(selected_elements_count == 1);
|
||||
|
||||
//Action that need items (elements, conductors, texts...) selected, to be enabled
|
||||
@@ -1419,17 +1433,19 @@ void QETDiagramEditor::slot_updateComplexActions()
|
||||
m_delete_selection -> setEnabled(!ro && deletable_items);
|
||||
m_rotate_selection -> setEnabled(!ro && diagram_->canRotateSelection());
|
||||
|
||||
//Action that need selected texts
|
||||
int selected_texts = diagram_->selectedTexts().count();
|
||||
int selected_conductor_texts = 0; for(DiagramTextItem *dti : diagram_->selectedTexts()) {if(dti->type() == ConductorTextItem::Type) selected_conductor_texts++;}
|
||||
int selected_element_texts = 0; for(DiagramTextItem *dti : diagram_->selectedTexts()) {if(dti->type() == ElementTextItem::Type) selected_element_texts++;}
|
||||
int selected_dynamic_elmt_text = 0; for(DiagramTextItem *dti : diagram_->selectedTexts()) {if(dti->type() == DynamicElementTextItem::Type) selected_dynamic_elmt_text++;}
|
||||
m_rotate_texts -> setEnabled(!ro && selected_texts);
|
||||
//Action that need selected texts or texts group
|
||||
QList<DiagramTextItem *> texts = DiagramContent(diagram_).selectedTexts();
|
||||
QList<ElementTextItemGroup *> groups = DiagramContent(diagram_).selectedTextsGroup();
|
||||
int selected_texts = texts.count();
|
||||
int selected_conductor_texts = 0; for(DiagramTextItem *dti : texts) {if(dti->type() == ConductorTextItem::Type) selected_conductor_texts++;}
|
||||
int selected_element_texts = 0; for(DiagramTextItem *dti : texts) {if(dti->type() == ElementTextItem::Type) selected_element_texts++;}
|
||||
int selected_dynamic_elmt_text = 0; for(DiagramTextItem *dti : texts) {if(dti->type() == DynamicElementTextItem::Type) selected_dynamic_elmt_text++;}
|
||||
m_rotate_texts->setEnabled(!ro && (selected_texts || groups.size()));
|
||||
|
||||
// actions need only one editable item
|
||||
int selected_image = diagram_-> selectedContent().count(DiagramContent::Images);
|
||||
int selected_image = dc.count(DiagramContent::Images);
|
||||
|
||||
int selected_shape = diagram_-> selectedContent().count(DiagramContent::Shapes);
|
||||
int selected_shape = dc.count(DiagramContent::Shapes);
|
||||
int selected_editable = selected_elements_count +
|
||||
(selected_texts - selected_conductor_texts - selected_element_texts - selected_dynamic_elmt_text) +
|
||||
selected_image +
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "element.h"
|
||||
#include "diagram.h"
|
||||
#include "addelementtextcommand.h"
|
||||
#include "QPropertyUndoCommand/qpropertyundocommand.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
@@ -37,7 +38,7 @@ ElementTextItemGroup::ElementTextItemGroup(const QString &name, Element *parent)
|
||||
QGraphicsItemGroup(parent),
|
||||
m_name(name)
|
||||
{
|
||||
setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsFocusable);
|
||||
setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable);
|
||||
}
|
||||
|
||||
ElementTextItemGroup::~ElementTextItemGroup()
|
||||
@@ -127,7 +128,6 @@ void ElementTextItemGroup::updateAlignment()
|
||||
item->setPos(ref.x(), ref.y()+y_offset);
|
||||
y_offset+=item->boundingRect().height();
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if(m_alignment == Qt::AlignVCenter)
|
||||
{
|
||||
@@ -139,9 +139,7 @@ void ElementTextItemGroup::updateAlignment()
|
||||
item->setPos(ref.x() - item->boundingRect().width()/2,
|
||||
ref.y() + y_offset);
|
||||
y_offset+=item->boundingRect().height();
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
else if (m_alignment == Qt::AlignRight)
|
||||
{
|
||||
@@ -154,8 +152,9 @@ void ElementTextItemGroup::updateAlignment()
|
||||
ref.y() + y_offset);
|
||||
y_offset+=item->boundingRect().height();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
setTransformOriginPoint(boundingRect().topLeft());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -381,26 +380,30 @@ void ElementTextItemGroup::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
*/
|
||||
void ElementTextItemGroup::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
if(event->key() == Qt::Key_A && m_alignment != Qt::AlignLeft)
|
||||
if(event->modifiers() == Qt::ControlModifier)
|
||||
{
|
||||
if(diagram())
|
||||
diagram()->undoStack().push(new AlignmentTextsGroupCommand(this, Qt::AlignLeft));
|
||||
else
|
||||
setAlignment(Qt::AlignLeft);
|
||||
}
|
||||
else if (event->key() == Qt::Key_Z && m_alignment != Qt::AlignVCenter)
|
||||
{
|
||||
if(diagram())
|
||||
diagram()->undoStack().push(new AlignmentTextsGroupCommand(this, Qt::AlignVCenter));
|
||||
else
|
||||
setAlignment(Qt::AlignVCenter);
|
||||
}
|
||||
else if (event->key() == Qt::Key_E && m_alignment != Qt::AlignRight)
|
||||
{
|
||||
if(diagram())
|
||||
diagram()->undoStack().push(new AlignmentTextsGroupCommand(this, Qt::AlignRight));
|
||||
else
|
||||
setAlignment(Qt::AlignRight);
|
||||
if(event->key() == Qt::Key_Left && m_alignment != Qt::AlignLeft)
|
||||
{
|
||||
if(diagram())
|
||||
diagram()->undoStack().push(new AlignmentTextsGroupCommand(this, Qt::AlignLeft));
|
||||
else
|
||||
setAlignment(Qt::AlignLeft);
|
||||
}
|
||||
else if (event->key() == Qt::Key_Up && m_alignment != Qt::AlignVCenter)
|
||||
{
|
||||
if(diagram())
|
||||
diagram()->undoStack().push(new AlignmentTextsGroupCommand(this, Qt::AlignVCenter));
|
||||
else
|
||||
setAlignment(Qt::AlignVCenter);
|
||||
}
|
||||
else if (event->key() == Qt::Key_Right && m_alignment != Qt::AlignRight)
|
||||
{
|
||||
if(diagram())
|
||||
diagram()->undoStack().push(new AlignmentTextsGroupCommand(this, Qt::AlignRight));
|
||||
else
|
||||
setAlignment(Qt::AlignRight);
|
||||
}
|
||||
}
|
||||
event->ignore();
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ class ElementTextItemGroup : public QObject, public QGraphicsItemGroup
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QPointF pos READ pos WRITE setPos)
|
||||
Q_PROPERTY(qreal rotation READ rotation WRITE setRotation)
|
||||
|
||||
public:
|
||||
ElementTextItemGroup(const QString &name, Element *parent);
|
||||
|
||||
154
sources/undocommand/rotateselectioncommand.cpp
Normal file
154
sources/undocommand/rotateselectioncommand.cpp
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
Copyright 2006-2017 The QElectroTech Team
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
QElectroTech is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "rotateselectioncommand.h"
|
||||
#include "element.h"
|
||||
#include "conductortextitem.h"
|
||||
#include "independenttextitem.h"
|
||||
#include "elementtextitem.h"
|
||||
#include "dynamicelementtextitem.h"
|
||||
#include "elementtextitemgroup.h"
|
||||
#include "diagramimageitem.h"
|
||||
#include "diagram.h"
|
||||
#include "conductor.h"
|
||||
|
||||
#include <QGraphicsItem>
|
||||
|
||||
RotateSelectionCommand::RotateSelectionCommand(Diagram *diagram, qreal angle, QUndoCommand *parent) :
|
||||
QUndoCommand(parent),
|
||||
m_diagram(diagram),
|
||||
m_angle(angle)
|
||||
{
|
||||
setText(QObject::tr("Pivoter la selection"));
|
||||
|
||||
if(!m_diagram->isReadOnly())
|
||||
{
|
||||
for (QGraphicsItem *item : m_diagram->selectedItems())
|
||||
{
|
||||
switch (item->type())
|
||||
{
|
||||
case Element::Type:
|
||||
m_element << static_cast<Element *>(item);
|
||||
break;
|
||||
case ConductorTextItem::Type:
|
||||
m_text << static_cast<DiagramTextItem *>(item);
|
||||
break;
|
||||
case IndependentTextItem::Type:
|
||||
m_text << static_cast<DiagramTextItem *>(item);
|
||||
break;
|
||||
case ElementTextItem::Type:
|
||||
if(item->parentItem() && !item->parentItem()->isSelected())
|
||||
m_text << static_cast<DiagramTextItem *>(item);
|
||||
break;
|
||||
case DynamicElementTextItem::Type:
|
||||
if(item->parentItem() && !item->parentItem()->isSelected())
|
||||
m_text << static_cast<DiagramTextItem *>(item);
|
||||
break;
|
||||
case QGraphicsItemGroup::Type:
|
||||
if(ElementTextItemGroup *grp = dynamic_cast<ElementTextItemGroup *>(item))
|
||||
if(grp->parentElement() && !grp->parentElement()->isSelected())
|
||||
m_group << grp;
|
||||
break;
|
||||
case DiagramImageItem::Type:
|
||||
m_image << static_cast<DiagramImageItem *>(item);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief RotateSelectionCommand::undo
|
||||
*/
|
||||
void RotateSelectionCommand::undo()
|
||||
{
|
||||
m_diagram->showMe();
|
||||
|
||||
for(QPointer<Element> elmt : m_element)
|
||||
if(elmt)
|
||||
elmt.data()->rotateBy(-m_angle);
|
||||
for(QPointer<DiagramTextItem> text : m_text)
|
||||
{
|
||||
if(text)
|
||||
{
|
||||
if(text.data()->type() == ConductorTextItem::Type)
|
||||
{
|
||||
ConductorTextItem *cti = static_cast<ConductorTextItem *>(text.data());
|
||||
cti->forceRotateByUser(m_rotate_by_user.value(text.data()));
|
||||
if(cti->wasRotateByUser())
|
||||
cti->rotateBy(-m_angle);
|
||||
else
|
||||
cti->parentConductor()->calculateTextItemPosition();
|
||||
}
|
||||
else
|
||||
text.data()->rotateBy(-m_angle);
|
||||
}
|
||||
}
|
||||
for(QPointer<DiagramImageItem> image : m_image)
|
||||
if(image)
|
||||
image.data()->rotateBy(-m_angle);
|
||||
for(QPointer<ElementTextItemGroup> group : m_group)
|
||||
if(group)
|
||||
group.data()->setRotation(group.data()->rotation() - m_angle);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief RotateSelectionCommand::redo
|
||||
*/
|
||||
void RotateSelectionCommand::redo()
|
||||
{
|
||||
m_diagram->showMe();
|
||||
|
||||
for(QPointer<Element> elmt : m_element)
|
||||
if(elmt)
|
||||
elmt.data()->rotateBy(m_angle);
|
||||
for(QPointer<DiagramTextItem> text : m_text)
|
||||
{
|
||||
if(text)
|
||||
{
|
||||
if(text.data()->type() == ConductorTextItem::Type)
|
||||
{
|
||||
ConductorTextItem *cti = static_cast<ConductorTextItem *>(text.data());
|
||||
m_rotate_by_user.insert(text.data(), cti->wasRotateByUser());
|
||||
cti->forceRotateByUser(true);
|
||||
}
|
||||
text.data()->rotateBy(m_angle);
|
||||
}
|
||||
}
|
||||
for(QPointer<DiagramImageItem> image : m_image)
|
||||
if(image)
|
||||
image.data()->rotateBy(m_angle);
|
||||
for(QPointer<ElementTextItemGroup> group : m_group)
|
||||
if(group)
|
||||
group.data()->setRotation(group.data()->rotation() + m_angle);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief RotateSelectionCommand::isValid
|
||||
* @return true if this command rotate a least one item.
|
||||
*/
|
||||
bool RotateSelectionCommand::isValid()
|
||||
{
|
||||
if(m_element.size()) return true;
|
||||
if(m_image.size()) return true;
|
||||
if(m_group.size()) return true;
|
||||
if(m_text.size()) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
56
sources/undocommand/rotateselectioncommand.h
Normal file
56
sources/undocommand/rotateselectioncommand.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
Copyright 2006-2017 The QElectroTech Team
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
QElectroTech is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef ROTATESELECTIONCOMMAND_H
|
||||
#define ROTATESELECTIONCOMMAND_H
|
||||
|
||||
#include <QUndoCommand>
|
||||
#include <QPointer>
|
||||
|
||||
class Diagram;
|
||||
class Element;
|
||||
class QGraphicsObject;
|
||||
class ElementTextItemGroup;
|
||||
class DiagramTextItem;
|
||||
class DiagramImageItem;
|
||||
|
||||
/**
|
||||
* @brief The RotateSelectionCommand class
|
||||
* Rotate the selected items in the given diagram
|
||||
*/
|
||||
class RotateSelectionCommand : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
RotateSelectionCommand(Diagram *diagram, qreal angle=90, QUndoCommand *parent=nullptr);
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
|
||||
bool isValid();
|
||||
|
||||
private:
|
||||
Diagram *m_diagram =nullptr;
|
||||
qreal m_angle;
|
||||
|
||||
QList<QPointer<Element>> m_element;
|
||||
QList<QPointer<DiagramImageItem>> m_image;
|
||||
QList<QPointer<ElementTextItemGroup>> m_group;
|
||||
QList<QPointer<DiagramTextItem>> m_text;
|
||||
QHash<DiagramTextItem *, bool> m_rotate_by_user;
|
||||
|
||||
};
|
||||
|
||||
#endif // ROTATESELECTIONCOMMAND_H
|
||||
152
sources/undocommand/rotatetextscommand.cpp
Normal file
152
sources/undocommand/rotatetextscommand.cpp
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
Copyright 2006-2017 The QElectroTech Team
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
QElectroTech is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "rotatetextscommand.h"
|
||||
#include "diagramcontent.h"
|
||||
#include "diagram.h"
|
||||
#include "diagramtextitem.h"
|
||||
#include "elementtextitemgroup.h"
|
||||
#include "conductortextitem.h"
|
||||
#include "qetapp.h"
|
||||
#include "qtextorientationspinboxwidget.h"
|
||||
|
||||
/**
|
||||
* @brief RotateTextsCommand::RotateTextsCommand
|
||||
* @param diagram : Apply the rotation to the selected texts and group of texts
|
||||
* of diagram at construction time.
|
||||
* @param parent : undo parent
|
||||
*/
|
||||
RotateTextsCommand::RotateTextsCommand(Diagram *diagram, QUndoCommand *parent) :
|
||||
QUndoCommand(parent),
|
||||
m_diagram(diagram)
|
||||
{
|
||||
DiagramContent dc(m_diagram);
|
||||
QList <DiagramTextItem *> texts_list;
|
||||
QList <ElementTextItemGroup *> groups_list;
|
||||
|
||||
for(DiagramTextItem *dti : dc.selectedTexts())
|
||||
{
|
||||
texts_list << dti;
|
||||
if(dti->type() == ConductorTextItem::Type)
|
||||
{
|
||||
ConductorTextItem *cti = static_cast<ConductorTextItem *>(dti);
|
||||
m_cond_texts.insert(cti, cti->wasRotateByUser());
|
||||
}
|
||||
}
|
||||
for(ElementTextItemGroup *etig : dc.selectedTextsGroup())
|
||||
groups_list << etig;
|
||||
|
||||
if(texts_list.count() || groups_list.count())
|
||||
{
|
||||
openDialog();
|
||||
|
||||
QString text;
|
||||
if(texts_list.count())
|
||||
text.append(QObject::tr("Pivoter %1 textes").arg(texts_list.count()));
|
||||
if(groups_list.count())
|
||||
{
|
||||
if(text.isEmpty())
|
||||
text.append(QObject::tr("Pivoter"));
|
||||
else
|
||||
text.append(QObject::tr(" et"));
|
||||
|
||||
text.append(QObject::tr(" %1 groupes de textes").arg(groups_list.count()));
|
||||
}
|
||||
if(!text.isNull())
|
||||
setText(text);
|
||||
|
||||
for(DiagramTextItem *dti : texts_list)
|
||||
setupAnimation(dti, "rotation", dti->rotation(), m_rotation);
|
||||
for(ElementTextItemGroup *grp : groups_list)
|
||||
setupAnimation(grp, "rotation", grp->rotation(), m_rotation);
|
||||
}
|
||||
#if QT_VERSION >= 0x050900
|
||||
else
|
||||
setObsolete(true);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void RotateTextsCommand::undo()
|
||||
{
|
||||
if(m_diagram)
|
||||
m_diagram.data()->showMe();
|
||||
|
||||
m_anim_group->setDirection(QAnimationGroup::Backward);
|
||||
m_anim_group->start();
|
||||
|
||||
for(ConductorTextItem *cti : m_cond_texts.keys())
|
||||
cti->forceMovedByUser(m_cond_texts.value(cti));
|
||||
}
|
||||
|
||||
void RotateTextsCommand::redo()
|
||||
{
|
||||
if(m_diagram)
|
||||
m_diagram.data()->showMe();
|
||||
|
||||
m_anim_group->setDirection(QAnimationGroup::Forward);
|
||||
m_anim_group->start();
|
||||
|
||||
for(ConductorTextItem *cti : m_cond_texts.keys())
|
||||
cti->forceMovedByUser(true);
|
||||
}
|
||||
|
||||
void RotateTextsCommand::openDialog()
|
||||
{
|
||||
//Open the dialog
|
||||
QDialog ori_text_dialog;
|
||||
ori_text_dialog.setSizeGripEnabled(false);
|
||||
#ifdef Q_OS_MAC
|
||||
ori_text_dialog.setWindowFlags(Qt::Sheet);
|
||||
#endif
|
||||
ori_text_dialog.setWindowTitle(QObject::tr("Orienter les textes sélectionnés", "window title"));
|
||||
|
||||
|
||||
QTextOrientationSpinBoxWidget *ori_widget = QETApp::createTextOrientationSpinBoxWidget();
|
||||
ori_widget->setParent(&ori_text_dialog);
|
||||
ori_widget->spinBox()->selectAll();
|
||||
|
||||
QDialogButtonBox buttons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
QObject::connect(&buttons, SIGNAL(accepted()), &ori_text_dialog, SLOT(accept()));
|
||||
QObject::connect(&buttons, SIGNAL(rejected()), &ori_text_dialog, SLOT(reject()));
|
||||
|
||||
QVBoxLayout layout_v(&ori_text_dialog);
|
||||
layout_v.setSizeConstraint(QLayout::SetFixedSize);
|
||||
layout_v.addWidget(ori_widget);
|
||||
layout_v.addStretch();
|
||||
layout_v.addWidget(&buttons);
|
||||
|
||||
if (ori_text_dialog.exec() == QDialog::Accepted)
|
||||
m_rotation = ori_widget->orientation();
|
||||
#if QT_VERSION >= 0x050900
|
||||
else
|
||||
setObsolete(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
void RotateTextsCommand::setupAnimation(QObject *target, const QByteArray &propertyName, const QVariant start, const QVariant end)
|
||||
{
|
||||
if(m_anim_group == nullptr)
|
||||
m_anim_group = new QParallelAnimationGroup();
|
||||
|
||||
QPropertyAnimation *animation = new QPropertyAnimation(target, propertyName);
|
||||
animation->setDuration(300);
|
||||
animation->setStartValue(start);
|
||||
animation->setEndValue(end);
|
||||
animation->setEasingCurve(QEasingCurve::OutQuad);
|
||||
m_anim_group->addAnimation(animation);
|
||||
}
|
||||
52
sources/undocommand/rotatetextscommand.h
Normal file
52
sources/undocommand/rotatetextscommand.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
Copyright 2006-2017 The QElectroTech Team
|
||||
This file is part of QElectroTech.
|
||||
|
||||
QElectroTech is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
QElectroTech is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef ROTATETEXTSCOMMAND_H
|
||||
#define ROTATETEXTSCOMMAND_H
|
||||
|
||||
#include <QUndoCommand>
|
||||
#include <QPointer>
|
||||
|
||||
class ConductorTextItem;
|
||||
class Diagram;
|
||||
class QParallelAnimationGroup;
|
||||
|
||||
/**
|
||||
* @brief The RotateTextsCommand class
|
||||
* Open a dialog for edit the rotation of the current selected texts and texts group in diagram.
|
||||
* Just instantiate this undo command and push it in a QUndoStack.
|
||||
*/
|
||||
class RotateTextsCommand : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
RotateTextsCommand(Diagram *diagram, QUndoCommand *parent=nullptr);
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
|
||||
private:
|
||||
void openDialog();
|
||||
void setupAnimation(QObject *target, const QByteArray &propertyName, const QVariant start, const QVariant end);
|
||||
|
||||
private:
|
||||
QPointer<Diagram> m_diagram;
|
||||
QHash<ConductorTextItem *, bool> m_cond_texts;
|
||||
qreal m_rotation=0;
|
||||
QParallelAnimationGroup *m_anim_group = nullptr;
|
||||
};
|
||||
|
||||
#endif // ROTATETEXTSCOMMAND_H
|
||||
Reference in New Issue
Block a user