First step for the dynamic element text : Now user can add directly from the diagram editor an editable text of an element.

git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@5005 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
blacksun 2017-08-03 17:36:08 +00:00
parent 0df5391491
commit 3ef55906a4
33 changed files with 2222 additions and 863 deletions

View File

@ -10,6 +10,7 @@ ConductorTextItem + 1006
DiagramImageItem + 1007 DiagramImageItem + 1007
QetShapItem + 1008 QetShapItem + 1008
crossRefItem + 1009 crossRefItem + 1009
DynamiqueElementTextItem + 1010
ElementPrimitiveDecorator + 2200 ElementPrimitiveDecorator + 2200
###ELEMENT EDITOR### ###ELEMENT EDITOR###
@ -21,3 +22,6 @@ part terminal + 1106
part text + 1107 part text + 1107
part text field + 1108 part text field + 1108
part rectangle + 1109 part rectangle + 1109
###QetGraphicsHandlerItem###
QetGraphicsHandlerItem = 1200

View File

@ -38,6 +38,7 @@
#include "elementcollectionhandler.h" #include "elementcollectionhandler.h"
#include "element.h" #include "element.h"
#include "diagramview.h" #include "diagramview.h"
#include "dynamicelementtextitem.h"
const int Diagram::xGrid = 10; const int Diagram::xGrid = 10;
const int Diagram::yGrid = 10; const int Diagram::yGrid = 10;
@ -75,7 +76,7 @@ Diagram::Diagram(QETProject *project) :
//Init object for manage movement //Init object for manage movement
elements_mover_ = new ElementsMover(); elements_mover_ = new ElementsMover();
element_texts_mover_ = new ElementTextsMover(); m_element_texts_mover = new ElementTextsMover();
connect(&border_and_titleblock, SIGNAL(needTitleBlockTemplate(const QString &)), this, SLOT(setTitleBlockTemplate(const QString &))); connect(&border_and_titleblock, SIGNAL(needTitleBlockTemplate(const QString &)), this, SLOT(setTitleBlockTemplate(const QString &)));
connect(&border_and_titleblock, SIGNAL(diagramTitleChanged(const QString &)), this, SLOT(titleChanged(const QString &))); connect(&border_and_titleblock, SIGNAL(diagramTitleChanged(const QString &)), this, SLOT(titleChanged(const QString &)));
@ -91,31 +92,30 @@ Diagram::Diagram(QETProject *project) :
* @brief Diagram::~Diagram * @brief Diagram::~Diagram
* Destructor * Destructor
*/ */
Diagram::~Diagram() { Diagram::~Diagram()
// clear undo stack to prevent errors, because contains pointers to this diagram and is elements. {
//First clear every selection to close an hypothetical editor
clearSelection();
// clear undo stack to prevent errors, because contains pointers to this diagram and is elements.
undoStack().clear(); undoStack().clear();
//delete of QGIManager, every elements he knows are removed //delete of QGIManager, every elements he knows are removed
delete qgi_manager_; delete qgi_manager_;
// remove of conductor setter // remove of conductor setter
delete conductor_setter_; delete conductor_setter_;
// delete of object for manage movement // delete of object for manage movement
delete elements_mover_; delete elements_mover_;
delete element_texts_mover_; delete m_element_texts_mover;
if (m_event_interface) delete m_event_interface; if (m_event_interface)
delete m_event_interface;
// list removable items // list removable items
QList<QGraphicsItem *> deletable_items; QList<QGraphicsItem *> deletable_items;
for(QGraphicsItem *qgi : items()) for(QGraphicsItem *qgi : items())
{ {
if (qgi->parentItem()) if (qgi -> parentItem()) continue;
continue; if (qgraphicsitem_cast<Conductor *>(qgi)) continue;
if (qgi->type() == Conductor::Type)
continue;
if (qgi->type() == QetGraphicsHandlerItem::Type)
continue;
deletable_items << qgi; deletable_items << qgi;
} }
@ -302,10 +302,10 @@ void Diagram::keyPressEvent(QKeyEvent *e)
qreal top_position = 0; qreal top_position = 0;
qreal left_position = 0; qreal left_position = 0;
QList<QGraphicsItem*> selected_elmts = this->selectedContent().items(); QList<QGraphicsItem*> selected_elmts = this->selectedContent().items();
if (!this->selectedContent().items(255).isEmpty()) { if (!this->selectedContent().items(DiagramContent::All).isEmpty()) {
switch(e -> key()) { switch(e -> key()) {
case Qt::Key_Left: case Qt::Key_Left:
foreach (Element *item, selectedContent().elements) { foreach (Element *item, selectedContent().m_elements) {
left_position = item->mapRectFromScene(item->boundingRect()).x(); left_position = item->mapRectFromScene(item->boundingRect()).x();
if (left_position >= this->sceneRect().left() - item->boundingRect().width()) if (left_position >= this->sceneRect().left() - item->boundingRect().width())
return; return;
@ -314,7 +314,7 @@ void Diagram::keyPressEvent(QKeyEvent *e)
break; break;
case Qt::Key_Right: movement = QPointF(+xGrid, 0.0); break; case Qt::Key_Right: movement = QPointF(+xGrid, 0.0); break;
case Qt::Key_Up: case Qt::Key_Up:
foreach (Element *item, selectedContent().elements) { foreach (Element *item, selectedContent().m_elements) {
top_position = item->mapRectFromScene(item->boundingRect()).y(); top_position = item->mapRectFromScene(item->boundingRect()).y();
if (top_position >= this->sceneRect().top() - item->boundingRect().height()) if (top_position >= this->sceneRect().top() - item->boundingRect().height())
return; return;
@ -378,8 +378,6 @@ void Diagram::keyReleaseEvent(QKeyEvent *e)
* Diagram become the ownership of event_interface * Diagram become the ownership of event_interface
* If there is a previous interface, they will be delete before * If there is a previous interface, they will be delete before
* and call init() to the new interface. * and call init() to the new interface.
* The derivated class of DiagramEventInterface need to emit the signal "finish" when the job is done,
* diagram use this signal to delete the interface. If the signal isn't send, the interface will never be deleted.
* @param event_interface * @param event_interface
*/ */
void Diagram::setEventInterface(DiagramEventInterface *event_interface) void Diagram::setEventInterface(DiagramEventInterface *event_interface)
@ -968,20 +966,14 @@ bool Diagram::fromXml(QDomElement &document, QPointF position, bool consider_inf
qgi -> setPos( qgi -> pos() += pos_); qgi -> setPos( qgi -> pos() += pos_);
} }
//Filling of optional lists // remplissage des listes facultatives
if (content_ptr) { if (content_ptr) {
content_ptr -> elements = added_elements.toSet(); content_ptr -> m_elements = added_elements.toSet();
content_ptr -> conductorsToMove = added_conductors.toSet(); content_ptr -> m_conductors_to_move = added_conductors.toSet();
content_ptr -> textFields = added_texts.toSet(); content_ptr -> m_text_fields = added_texts.toSet();
content_ptr -> images = added_images.toSet(); content_ptr -> m_images = added_images.toSet();
content_ptr -> shapes = added_shapes.toSet(); content_ptr -> m_shapes = added_shapes.toSet();
} }
//Ensure the texts of conductor are inside the border of the folio
//and so don't cause the annoying margin on the left border of the folio.
for(Conductor *cond : added_conductors)
cond->textItem()->setPos(cond->textItem()->pos());
adjustSceneRect(); adjustSceneRect();
return(true); return(true);
} }
@ -1438,7 +1430,7 @@ void Diagram::endMoveElements() {
@see ElementTextsMover @see ElementTextsMover
*/ */
int Diagram::beginMoveElementTexts(QGraphicsItem *driver_item) { int Diagram::beginMoveElementTexts(QGraphicsItem *driver_item) {
return(element_texts_mover_ -> beginMovement(this, driver_item)); return(m_element_texts_mover -> beginMovement(this, driver_item));
} }
/** /**
@ -1447,7 +1439,7 @@ int Diagram::beginMoveElementTexts(QGraphicsItem *driver_item) {
@see ElementTextsMover @see ElementTextsMover
*/ */
void Diagram::continueMoveElementTexts(const QPointF &movement) { void Diagram::continueMoveElementTexts(const QPointF &movement) {
element_texts_mover_ -> continueMovement(movement); m_element_texts_mover -> continueMovement(movement);
} }
/** /**
@ -1455,7 +1447,7 @@ void Diagram::continueMoveElementTexts(const QPointF &movement) {
@see ElementTextsMover @see ElementTextsMover
*/ */
void Diagram::endMoveElementTexts() { void Diagram::endMoveElementTexts() {
element_texts_mover_ -> endMovement(); m_element_texts_mover -> endMovement();
} }
/** /**
@ -1656,53 +1648,24 @@ QSet<Conductor *> Diagram::selectedConductors() const {
} }
/** /**
@return la liste de tous les textes selectionnes : les textes independants, * @brief Diagram::selectedTexts
mais aussi ceux rattaches a des conducteurs ou des elements * @return A list of every selected texts (every kind of texts)
*/ */
QSet<DiagramTextItem *> Diagram::selectedTexts() const { QSet<DiagramTextItem *> Diagram::selectedTexts() const
{
QSet<DiagramTextItem *> selected_texts; QSet<DiagramTextItem *> selected_texts;
foreach(QGraphicsItem *item, selectedItems()) { for(QGraphicsItem *qgi : selectedItems())
if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(item)) { {
selected_texts << cti; if (qgi->type() == ConductorTextItem::Type ||
} else if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(item)) { qgi->type() == ElementTextItem::Type ||
selected_texts << eti; qgi->type() == IndependentTextItem::Type ||
} else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item)) { qgi->type() == DynamicElementTextItem::Type)
selected_texts << iti; selected_texts << static_cast<DiagramTextItem *>(qgi);
}
} }
return(selected_texts); return(selected_texts);
} }
/**
* @brief Diagram::selectedConductorTexts
* @return the list of conductor texts selected
*/
QSet<ConductorTextItem *> Diagram::selectedConductorTexts() const {
QSet<ConductorTextItem *> selected_texts;
foreach(QGraphicsItem *item, selectedItems()) {
if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(item)) {
selected_texts << cti;
}
}
return(selected_texts);
}
/**
* @brief Diagram::selectedElementTexts
* @return the list of element texts selected
*/
QSet<ElementTextItem*> Diagram::selectedElementTexts() const {
QSet<ElementTextItem *> selected_texts;
foreach(QGraphicsItem *item, selectedItems()) {
if (ElementTextItem *cti = qgraphicsitem_cast< ElementTextItem*>(item)) {
selected_texts << cti;
}
}
return(selected_texts);
}
/// @return true si le presse-papier semble contenir un schema /// @return true si le presse-papier semble contenir un schema
bool Diagram::clipboardMayContainDiagram() { bool Diagram::clipboardMayContainDiagram() {
QString clipboard_text = QApplication::clipboard() -> text().trimmed(); QString clipboard_text = QApplication::clipboard() -> text().trimmed();
@ -1775,47 +1738,53 @@ DiagramContent Diagram::content() const {
DiagramContent dc; DiagramContent dc;
foreach(QGraphicsItem *qgi, items()) { foreach(QGraphicsItem *qgi, items()) {
if (Element *e = qgraphicsitem_cast<Element *>(qgi)) { if (Element *e = qgraphicsitem_cast<Element *>(qgi)) {
dc.elements << e; dc.m_elements << e;
} else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(qgi)) { } else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(qgi)) {
dc.textFields << iti; dc.m_text_fields << iti;
} else if (Conductor *c = qgraphicsitem_cast<Conductor *>(qgi)) { } else if (Conductor *c = qgraphicsitem_cast<Conductor *>(qgi)) {
dc.conductorsToMove << c; dc.m_conductors_to_move << c;
} }
} }
return(dc); return(dc);
} }
/** /**
@return le contenu selectionne du schema. * @brief Diagram::selectedContent
*/ * @return the selected items, stored in a DiagramContent
DiagramContent Diagram::selectedContent() { */
DiagramContent Diagram::selectedContent()
{
DiagramContent dc; DiagramContent dc;
// recupere les elements deplaces //Get the selected items
foreach (QGraphicsItem *item, selectedItems()) { for (QGraphicsItem *item : selectedItems())
if (Element *elmt = qgraphicsitem_cast<Element *>(item)) { {
dc.elements << elmt; if (Element *elmt = qgraphicsitem_cast<Element *>(item))
} else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item)) { dc.m_elements << elmt;
dc.textFields << iti; else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item))
} else if (Conductor *c = qgraphicsitem_cast<Conductor *>(item)) { dc.m_text_fields << iti;
else if (Conductor *c = qgraphicsitem_cast<Conductor *>(item))
{
// recupere les conducteurs selectionnes isoles (= non deplacables mais supprimables) // recupere les conducteurs selectionnes isoles (= non deplacables mais supprimables)
if ( if (
!c -> terminal1 -> parentItem() -> isSelected() &&\ !c -> terminal1 -> parentItem() -> isSelected() &&\
!c -> terminal2 -> parentItem() -> isSelected() !c -> terminal2 -> parentItem() -> isSelected()
) { ) {
dc.otherConductors << c; dc.m_other_conductors << c;
} }
} else if (DiagramImageItem *dii = qgraphicsitem_cast<DiagramImageItem *>(item)) {
dc.images << dii;
} else if (QetShapeItem *dsi = qgraphicsitem_cast<QetShapeItem *>(item)) {
dc.shapes << dsi;
} }
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;
} }
// pour chaque element deplace, determine les conducteurs qui seront modifies //For each selected element, we determine if conductors must be moved or updated.
foreach(Element *elmt, dc.elements) { for(Element *elmt : dc.m_elements) {
foreach(Terminal *terminal, elmt -> terminals()) { for(Terminal *terminal : elmt -> terminals()) {
foreach(Conductor *conductor, terminal -> conductors()) { for(Conductor *conductor : terminal -> conductors()) {
Terminal *other_terminal; Terminal *other_terminal;
if (conductor -> terminal1 == terminal) { if (conductor -> terminal1 == terminal) {
other_terminal = conductor -> terminal2; other_terminal = conductor -> terminal2;
@ -1823,10 +1792,10 @@ DiagramContent Diagram::selectedContent() {
other_terminal = conductor -> terminal1; other_terminal = conductor -> terminal1;
} }
// si les deux elements du conducteur sont deplaces // si les deux elements du conducteur sont deplaces
if (dc.elements.contains(other_terminal -> parentElement())) { if (dc.m_elements.contains(other_terminal -> parentElement())) {
dc.conductorsToMove << conductor; dc.m_conductors_to_move << conductor;
} else { } else {
dc.conductorsToUpdate << conductor; dc.m_conductors_to_update << conductor;
} }
} }
} }
@ -1836,17 +1805,20 @@ DiagramContent Diagram::selectedContent() {
} }
/** /**
@return true s'il est possible de tourner les elements selectionnes. * @brief Diagram::canRotateSelection
Concretement, cette methode retourne true s'il y a des elements selectionnes * @return True if a least one of selected items can be rotated
et qu'au moins l'un d'entre eux peut etre pivote. */
*/ bool Diagram::canRotateSelection() const
bool Diagram::canRotateSelection() const { {
foreach(QGraphicsItem * qgi, selectedItems()) { for (QGraphicsItem *qgi : selectedItems())
if (qgraphicsitem_cast<IndependentTextItem *>(qgi) || {
qgraphicsitem_cast<ConductorTextItem *>(qgi) || if (qgi->type() == IndependentTextItem::Type ||
qgraphicsitem_cast<DiagramImageItem *>(qgi) || qgi->type() == ConductorTextItem::Type ||
qgraphicsitem_cast<ElementTextItem *>(qgi) || qgi->type() == DiagramImageItem::Type ||
qgraphicsitem_cast<Element *>(qgi)) return (true); qgi->type() == ElementTextItem::Type ||
qgi->type() == Element::Type ||
qgi->type() == DynamicElementTextItem::Type) return true;
} }
return(false);
return false;
} }

View File

@ -36,11 +36,8 @@ class DiagramTextItem;
class Element; class Element;
class ElementsLocation; class ElementsLocation;
class ElementsMover; class ElementsMover;
class ElementTextItem;
class IndependentTextItem;
class QETProject; class QETProject;
class Terminal; class Terminal;
class ConductorTextItem;
class DiagramImageItem; class DiagramImageItem;
class ElementTextsMover; class ElementTextsMover;
class DiagramEventInterface; class DiagramEventInterface;
@ -96,7 +93,7 @@ class Diagram : public QGraphicsScene
private: private:
QGraphicsLineItem *conductor_setter_; QGraphicsLineItem *conductor_setter_;
ElementsMover *elements_mover_; ElementsMover *elements_mover_;
ElementTextsMover *element_texts_mover_; ElementTextsMover *m_element_texts_mover;
QGIManager *qgi_manager_; QGIManager *qgi_manager_;
QETProject *m_project; QETProject *m_project;
@ -191,8 +188,6 @@ class Diagram : public QGraphicsScene
QList<Element *> elements() const; QList<Element *> elements() const;
QList<Conductor *> conductors() const; QList<Conductor *> conductors() const;
QSet<DiagramTextItem *> selectedTexts() const; QSet<DiagramTextItem *> selectedTexts() const;
QSet<ConductorTextItem *> selectedConductorTexts() const;
QSet<ElementTextItem*> selectedElementTexts() const;
QSet<Conductor *> selectedConductors() const; QSet<Conductor *> selectedConductors() const;
DiagramContent content() const; DiagramContent content() const;
DiagramContent selectedContent(); DiagramContent selectedContent();

View File

@ -42,88 +42,6 @@ QString itemText(const Conductor *item) {
return QObject::tr("un conducteur"); return QObject::tr("un conducteur");
} }
/**
Constructeur
@param dia Schema dont on supprime des elements et conducteurs
@param content Contenu supprime
@param parent QUndoCommand parent
*/
DeleteElementsCommand::DeleteElementsCommand(
Diagram *dia,
const DiagramContent &content,
QUndoCommand *parent
) :
QUndoCommand(parent),
removed_content(content),
diagram(dia)
{
setText(
QString(
QObject::tr(
"supprimer %1",
"undo caption - %1 is a sentence listing the removed content"
)
).arg(removed_content.sentence(DiagramContent::All))
);
diagram -> qgiManager().manage(removed_content.items(DiagramContent::All));
}
/// Destructeur
DeleteElementsCommand::~DeleteElementsCommand() {
diagram -> qgiManager().release(removed_content.items(DiagramContent::All));
}
/**
* @brief DeleteElementsCommand::undo
* Undo this command
*/
void DeleteElementsCommand::undo()
{
diagram -> showMe();
foreach(QGraphicsItem *item, removed_content.items())
diagram->addItem(item);
//We relink element after every element was added to diagram
foreach(Element *e, removed_content.elements)
foreach (Element *elmt, m_link_hash[e])
e -> linkToElement(elmt);
}
/**
* @brief DeleteElementsCommand::redo
* Redo the delete command
*/
void DeleteElementsCommand::redo()
{
diagram -> showMe();
foreach(Conductor *c, removed_content.conductors(DiagramContent::AnyConductor))
{
//If option one text per folio is enable, and the text item of
//current conductor is visible (that mean the conductor have the single displayed text)
//We call adjustTextItemPosition to other conductor at the same potential to keep
//a visible text on this potential.
if (diagram -> defaultConductorProperties.m_one_text_per_folio && c -> textItem() -> isVisible())
{
QList <Conductor *> conductor_list;
conductor_list << c -> relatedPotentialConductors(false).toList();
if (conductor_list.count())
conductor_list.first() -> calculateTextItemPosition();
}
}
foreach(Element *e, removed_content.elements)
{
//Get linked element, for relink it at undo
if (!e->linkedElements().isEmpty())
m_link_hash.insert(e, e->linkedElements());
}
foreach(QGraphicsItem *item, removed_content.items())
diagram->removeItem(item);
}
/** /**
* @brief PasteDiagramCommand::PasteDiagramCommand * @brief PasteDiagramCommand::PasteDiagramCommand
* Constructor * Constructor
@ -176,7 +94,7 @@ void PasteDiagramCommand::redo()
first_redo = false; first_redo = false;
//this is the first paste, we do some actions for the new element //this is the first paste, we do some actions for the new element
const QList <Element *> elmts_list = content.elements.toList(); const QList <Element *> elmts_list = content.m_elements.toList();
for (Element *e : elmts_list) for (Element *e : elmts_list)
{ {
//make new uuid, because old uuid are the uuid of the copied element //make new uuid, because old uuid are the uuid of the copied element
@ -211,7 +129,7 @@ void PasteDiagramCommand::redo()
eti -> setPlainText("_"); eti -> setPlainText("_");
//Reset the text of conductors //Reset the text of conductors
const QList <Conductor *> conductors_list = content.conductorsToMove.toList(); const QList <Conductor *> conductors_list = content.m_conductors_to_move.toList();
for (Conductor *c : conductors_list) for (Conductor *c : conductors_list)
{ {
ConductorProperties cp = c -> properties(); ConductorProperties cp = c -> properties();
@ -253,7 +171,7 @@ CutDiagramCommand::CutDiagramCommand(
const DiagramContent &content, const DiagramContent &content,
QUndoCommand *parent QUndoCommand *parent
) : ) :
DeleteElementsCommand(dia, content, parent) DeleteQGraphicsItemCommand(dia, content, parent)
{ {
setText( setText(
QString( QString(
@ -366,12 +284,12 @@ void MoveElementsCommand::move(const QPointF &actual_movement) {
} }
// Move some conductors // Move some conductors
foreach(Conductor *conductor, content_to_move.conductorsToMove) { foreach(Conductor *conductor, content_to_move.m_conductors_to_move) {
setupAnimation(conductor, "pos", conductor->pos(), conductor->pos() + actual_movement); setupAnimation(conductor, "pos", conductor->pos(), conductor->pos() + actual_movement);
} }
// Recalcul the path of other conductor // Recalcul the path of other conductor
foreach(Conductor *conductor, content_to_move.conductorsToUpdate) { foreach(Conductor *conductor, content_to_move.m_conductors_to_update) {
setupAnimation(conductor, "animPath", 1, 1); setupAnimation(conductor, "animPath", 1, 1);
} }
} }
@ -588,21 +506,6 @@ void RotateElementsCommand::redo() {
foreach(DiagramImageItem *dii, images_to_rotate) dii -> rotateBy(applied_rotation_angle_); foreach(DiagramImageItem *dii, images_to_rotate) dii -> rotateBy(applied_rotation_angle_);
} }
/**
Constructeur
@param previous_state Hash associant les textes impactes par l'action et leur angle de rotation avant l'action
@param applied_rotation Nouvel angle de rotation, a appliquer au textes concernes
@param parent QUndoCommand parent
*/
RotateTextsCommand::RotateTextsCommand(const QHash<DiagramTextItem *, double> &previous_state, double applied_rotation, QUndoCommand *parent) :
QUndoCommand(parent),
texts_to_rotate(previous_state),
applied_rotation_angle_(applied_rotation),
diagram(previous_state.key(0)->diagram())
{
defineCommandName();
}
/** /**
Constructeur Constructeur
@param texts Liste des textes impactes par l'action. L'objet retiendra leur angle de rotation au moment de sa construction. @param texts Liste des textes impactes par l'action. L'objet retiendra leur angle de rotation au moment de sa construction.
@ -611,11 +514,11 @@ RotateTextsCommand::RotateTextsCommand(const QHash<DiagramTextItem *, double> &p
*/ */
RotateTextsCommand::RotateTextsCommand(const QList<DiagramTextItem *> &texts, double applied_rotation, QUndoCommand *parent) : RotateTextsCommand::RotateTextsCommand(const QList<DiagramTextItem *> &texts, double applied_rotation, QUndoCommand *parent) :
QUndoCommand(parent), QUndoCommand(parent),
applied_rotation_angle_(applied_rotation), m_applied_rotation_angle(applied_rotation),
diagram(texts.first()->diagram()) m_diagram(texts.first()->diagram())
{ {
foreach(DiagramTextItem *text, texts) { foreach(DiagramTextItem *text, texts) {
texts_to_rotate.insert(text, text -> rotationAngle()); m_texts_to_rotate.insert(text, text -> rotationAngle());
} }
defineCommandName(); defineCommandName();
} }
@ -630,11 +533,11 @@ RotateTextsCommand::~RotateTextsCommand() {
Annule la rotation des textes Annule la rotation des textes
*/ */
void RotateTextsCommand::undo() { void RotateTextsCommand::undo() {
diagram -> showMe(); m_diagram -> showMe();
foreach(DiagramTextItem *text, texts_to_rotate.keys()) { foreach(DiagramTextItem *text, m_texts_to_rotate.keys()) {
if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(text)) if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(text))
cti -> forceRotateByUser(previous_rotate_by_user_[cti]); cti -> forceRotateByUser(m_previous_rotate_by_user[cti]);
text -> setRotationAngle(texts_to_rotate[text]); text -> setRotationAngle(m_texts_to_rotate[text]);
} }
} }
@ -642,14 +545,14 @@ void RotateTextsCommand::undo() {
Applique l'angle de rotation aux textes Applique l'angle de rotation aux textes
*/ */
void RotateTextsCommand::redo() { void RotateTextsCommand::redo() {
diagram -> showMe(); m_diagram -> showMe();
foreach(DiagramTextItem *text, texts_to_rotate.keys()) { foreach(DiagramTextItem *text, m_texts_to_rotate.keys()) {
if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(text)) { if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(text)) {
//we grab the previous rotation by user of each ConductorTextItem //we grab the previous rotation by user of each ConductorTextItem
previous_rotate_by_user_.insert(cti, cti -> wasRotateByUser()); m_previous_rotate_by_user.insert(cti, cti -> wasRotateByUser());
cti -> forceRotateByUser(true); cti -> forceRotateByUser(true);
} }
text -> setRotationAngle(applied_rotation_angle_); text -> setRotationAngle(m_applied_rotation_angle);
} }
} }
@ -663,8 +566,8 @@ void RotateTextsCommand::defineCommandName() {
"orienter %1 à %2°", "orienter %1 à %2°",
"undo caption - %1 looks like '42 texts', %2 is a rotation angle" "undo caption - %1 looks like '42 texts', %2 is a rotation angle"
) )
).arg(QET::ElementsAndConductorsSentence(0, 0, texts_to_rotate.count())) ).arg(QET::ElementsAndConductorsSentence(0, 0, m_texts_to_rotate.count()))
.arg(applied_rotation_angle_) .arg(m_applied_rotation_angle)
); );
} }

View File

@ -26,6 +26,7 @@
#include "qetgraphicsitem/qetshapeitem.h" #include "qetgraphicsitem/qetshapeitem.h"
#include "conductorprofile.h" #include "conductorprofile.h"
#include "diagram.h" #include "diagram.h"
#include "undocommand/deleteqgraphicsitemcommand.h"
class DiagramTextItem; class DiagramTextItem;
class Element; class Element;
@ -80,32 +81,6 @@ QString itemText(const QetGraphicsItem *item);
QString itemText(const IndependentTextItem *item); QString itemText(const IndependentTextItem *item);
QString itemText(const Conductor *item); QString itemText(const Conductor *item);
/**
This command removes content from a particular diagram.
*/
class DeleteElementsCommand : public QUndoCommand {
// constructors, destructor
public:
DeleteElementsCommand(Diagram *, const DiagramContent &, QUndoCommand * = 0);
virtual ~DeleteElementsCommand();
private:
DeleteElementsCommand(const DeleteElementsCommand &);
// methods
public:
virtual void undo();
virtual void redo();
// attributes
private:
/// removed content
DiagramContent removed_content;
/// diagram which the content is removed from
Diagram *diagram;
/// keep linked element for each removed element linked to other element.
QHash <Element *, QList<Element *> > m_link_hash;
};
/** /**
This command pastes some content onto a particular diagram. This command pastes some content onto a particular diagram.
*/ */
@ -137,7 +112,7 @@ class PasteDiagramCommand : public QUndoCommand {
/** /**
This command cuts content from a particular diagram. This command cuts content from a particular diagram.
*/ */
class CutDiagramCommand : public DeleteElementsCommand { class CutDiagramCommand : public DeleteQGraphicsItemCommand {
// constructors, destructor // constructors, destructor
public: public:
CutDiagramCommand(Diagram *, const DiagramContent &, QUndoCommand * = 0); CutDiagramCommand(Diagram *, const DiagramContent &, QUndoCommand * = 0);
@ -275,32 +250,32 @@ class RotateElementsCommand : public QUndoCommand {
This command directs several text items to a same particular angle of This command directs several text items to a same particular angle of
rotation. rotation.
*/ */
class RotateTextsCommand : public QUndoCommand { class RotateTextsCommand : public QUndoCommand
{
// constructors, destructor // constructors, destructor
public: public:
RotateTextsCommand(const QHash<DiagramTextItem *, double> &, double, QUndoCommand * = 0); RotateTextsCommand(const QList<DiagramTextItem *> &, double, QUndoCommand * = nullptr);
RotateTextsCommand(const QList<DiagramTextItem *> &, double, QUndoCommand * = 0); virtual ~RotateTextsCommand() override;
virtual ~RotateTextsCommand();
private: private:
RotateTextsCommand(const RotateTextsCommand &); RotateTextsCommand(const RotateTextsCommand &);
// methods // methods
public: public:
virtual void undo(); virtual void undo() override;
virtual void redo(); virtual void redo() override;
private: private:
void defineCommandName(); void defineCommandName();
// attributes // attributes
private: private:
/// hold rotated text items along with their former angle of rotation /// hold rotated text items along with their former angle of rotation
QHash<DiagramTextItem *, double> texts_to_rotate; QHash<DiagramTextItem *, double> m_texts_to_rotate;
/// angle of rotation of all text items after the command /// angle of rotation of all text items after the command
double applied_rotation_angle_; double m_applied_rotation_angle;
/// previous state of each conductor text item /// previous state of each conductor text item
QHash<ConductorTextItem *, bool> previous_rotate_by_user_; QHash<ConductorTextItem *, bool> m_previous_rotate_by_user;
Diagram *diagram; Diagram *m_diagram;
}; };
/** /**

View File

@ -23,61 +23,67 @@
#include "diagramimageitem.h" #include "diagramimageitem.h"
#include "elementtextitem.h" #include "elementtextitem.h"
#include "qetshapeitem.h" #include "qetshapeitem.h"
#include "dynamicelementtextitem.h"
/** /**
Constructeur par defaut. Ne contient rien. * @brief DiagramContent::DiagramContent
*/ */
DiagramContent::DiagramContent() { DiagramContent::DiagramContent() {}
}
/** /**
Constructeur de copie. * @brief DiagramContent::DiagramContent
*/ * Copy constructor
* @param other
*/
DiagramContent::DiagramContent(const DiagramContent &other) : DiagramContent::DiagramContent(const DiagramContent &other) :
elements(other.elements), m_elements(other.m_elements),
textFields(other.textFields), m_text_fields(other.m_text_fields),
images(other.images), m_images(other.m_images),
shapes(other.shapes), m_shapes(other.m_shapes),
conductorsToUpdate(other.conductorsToUpdate), m_conductors_to_update(other.m_conductors_to_update),
conductorsToMove(other.conductorsToMove), m_conductors_to_move(other.m_conductors_to_move),
otherConductors(other.otherConductors) m_other_conductors(other.m_other_conductors),
m_element_texts(other.m_element_texts)
{}
/**
* @brief DiagramContent::~DiagramContent
*/
DiagramContent::~DiagramContent() {}
/**
* @brief DiagramContent::conductors
* @param filter
* @return Every conductors according to the filter
*/
QList<Conductor *> DiagramContent::conductors(int filter) const
{ {
}
/**
Constructeur
*/
DiagramContent::~DiagramContent() {
}
/**
@param filter Types de conducteurs desires
@return tous les conducteurs
*/
QList<Conductor *> DiagramContent::conductors(int filter) const {
QSet<Conductor *> result; QSet<Conductor *> result;
if (filter & ConductorsToMove) result += conductorsToMove; if (filter & ConductorsToMove) result += m_conductors_to_move;
if (filter & ConductorsToUpdate) result += conductorsToUpdate; if (filter & ConductorsToUpdate) result += m_conductors_to_update;
if (filter & OtherConductors) result += otherConductors; if (filter & OtherConductors) result += m_other_conductors;
if (filter & SelectedOnly) { if (filter & SelectedOnly) {
foreach(Conductor *conductor, result) { for(Conductor *conductor : result) {
if (!conductor -> isSelected()) result.remove(conductor); if (!conductor->isSelected()) result.remove(conductor);
} }
} }
return(result.toList()); return(result.toList());
} }
/** /**
Vide le conteneur * @brief DiagramContent::clear
*/ * Remove all items from the diagram content
void DiagramContent::clear() { */
elements.clear(); void DiagramContent::clear()
textFields.clear(); {
images.clear(); m_elements.clear();
shapes.clear(); m_text_fields.clear();
conductorsToUpdate.clear(); m_images.clear();
conductorsToMove.clear(); m_shapes.clear();
otherConductors.clear(); m_conductors_to_update.clear();
m_conductors_to_move.clear();
m_other_conductors.clear();
m_element_texts.clear();
} }
/** /**
@ -89,42 +95,47 @@ int DiagramContent::removeNonMovableItems()
{ {
int count_ = 0; int count_ = 0;
foreach(Element *elmt, elements) { for(Element *elmt : m_elements) {
if (!elmt->isMovable()) { if (!elmt->isMovable()) {
elements.remove(elmt); m_elements.remove(elmt);
++count_; ++count_;
} }
} }
foreach(DiagramImageItem *img, images) { for(DiagramImageItem *img : m_images) {
if (!img->isMovable()) { if (!img->isMovable()) {
images.remove(img); m_images.remove(img);
++count_; ++count_;
} }
} }
foreach (QetShapeItem *shape, shapes) { for(QetShapeItem *shape : m_shapes) {
if (!shape->isMovable()) { if (!shape->isMovable()) {
shapes.remove(shape); m_shapes.remove(shape);
++count_; ++count_;
} }
} }
return count_; return count_;
} }
/**
@param filter Types desires
@return la liste des items formant le contenu du schema
*/
QList<QGraphicsItem *> DiagramContent::items(int filter) const {
QList<QGraphicsItem *> items_list;
foreach(QGraphicsItem *qgi, conductors(filter)) items_list << qgi;
if (filter & Elements) foreach(QGraphicsItem *qgi, elements) items_list << qgi; /**
if (filter & TextFields) foreach(QGraphicsItem *qgi, textFields) items_list << qgi; * @brief DiagramContent::items
if (filter & Images) foreach(QGraphicsItem *qgi, images) items_list << qgi; * @param filter
if (filter & Shapes) foreach(QGraphicsItem *qgi, shapes) items_list << qgi; * @return The items of this diagram content according to @filter
*/
QList<QGraphicsItem *> DiagramContent::items(int filter) const
{
QList<QGraphicsItem *> items_list;
for(QGraphicsItem *qgi : conductors(filter)) items_list << qgi;
if (filter & Elements) for(QGraphicsItem *qgi : m_elements) items_list << qgi;
if (filter & TextFields) for(QGraphicsItem *qgi : m_text_fields) items_list << qgi;
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 & SelectedOnly) { if (filter & SelectedOnly) {
foreach(QGraphicsItem *qgi, items_list) { for(QGraphicsItem *qgi : items_list) {
if (!qgi -> isSelected()) items_list.removeOne(qgi); if (!qgi -> isSelected()) items_list.removeOne(qgi);
} }
} }
@ -132,44 +143,50 @@ QList<QGraphicsItem *> DiagramContent::items(int filter) const {
} }
/** /**
@param filter Types desires * @brief DiagramContent::count
@return le nombre d'items formant le contenu du schema * @param filter
*/ * @return The number of items, according to @filter
int DiagramContent::count(int filter) const { */
int DiagramContent::count(int filter) const
{
int count = 0; int count = 0;
if (filter & SelectedOnly) { if (filter & SelectedOnly) {
if (filter & Elements) foreach(Element *element, elements) { if (element -> isSelected()) ++ count; } if (filter & Elements) for(Element *element : m_elements) { if (element -> isSelected()) ++ count; }
if (filter & TextFields) foreach(DiagramTextItem *dti, textFields) { if (dti -> isSelected()) ++ count; } if (filter & TextFields) for(DiagramTextItem *dti : m_text_fields) { if (dti -> isSelected()) ++ count; }
if (filter & Images) foreach(DiagramImageItem *dii, images) { if (dii -> isSelected()) ++ count; } if (filter & Images) for(DiagramImageItem *dii : m_images) { if (dii -> isSelected()) ++ count; }
if (filter & Shapes) foreach(QetShapeItem *dsi, shapes) { if (dsi -> isSelected()) ++ count; } if (filter & Shapes) for(QetShapeItem *dsi : m_shapes) { if (dsi -> isSelected()) ++ count; }
if (filter & ConductorsToMove) foreach(Conductor *conductor, conductorsToMove) { if (conductor -> isSelected()) ++ count; } if (filter & ConductorsToMove) for(Conductor *conductor : m_conductors_to_move) { if (conductor -> isSelected()) ++ count; }
if (filter & ConductorsToUpdate) foreach(Conductor *conductor, conductorsToUpdate) { if (conductor -> isSelected()) ++ count; } if (filter & ConductorsToUpdate) for(Conductor *conductor : m_conductors_to_update) { if (conductor -> isSelected()) ++ count; }
if (filter & OtherConductors) foreach(Conductor *conductor, otherConductors) { 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; }
} }
else { else {
if (filter & Elements) count += elements.count(); if (filter & Elements) count += m_elements.count();
if (filter & TextFields) count += textFields.count(); if (filter & TextFields) count += m_text_fields.count();
if (filter & Images) count += images.count(); if (filter & Images) count += m_images.count();
if (filter & Shapes) count += shapes.count(); if (filter & Shapes) count += m_shapes.count();
if (filter & ConductorsToMove) count += conductorsToMove.count(); if (filter & ConductorsToMove) count += m_conductors_to_move.count();
if (filter & ConductorsToUpdate) count += conductorsToUpdate.count(); if (filter & ConductorsToUpdate) count += m_conductors_to_update.count();
if (filter & OtherConductors) count += otherConductors.count(); if (filter & OtherConductors) count += m_other_conductors.count();
if (filter & ElementTextFields) count += m_element_texts.count();
} }
return(count); return(count);
} }
/** /**
Permet de composer rapidement la proposition "x elements, y conducteurs et * @brief DiagramContent::sentence
z champs de texte". * @param filter
@param filter Types desires * @return A string that describe the items of the diagram content according to @filter.
@return la proposition decrivant le contenu. * Exemple : X elements, Y conductors etc....
*/ */
QString DiagramContent::sentence(int filter) const { QString DiagramContent::sentence(int filter) const
int elements_count = (filter & Elements) ? elements.count() : 0; {
int elements_count = (filter & Elements) ? m_elements.count() : 0;
int conductors_count = conductors(filter).count(); int conductors_count = conductors(filter).count();
int textfields_count = (filter & TextFields) ? (textFields.count()) : 0; int textfields_count = (filter & TextFields) ? (m_text_fields.count()) : 0;
int images_count = (filter & Images) ? images.count() : 0; int images_count = (filter & Images) ? m_images.count() : 0;
int shapes_count = (filter & Shapes) ? shapes.count() : 0; int shapes_count = (filter & Shapes) ? m_shapes.count() : 0;
int elmt_text_count = (filter & ElementTextFields) ? m_element_texts.count() : 0;
return( return(
QET::ElementsAndConductorsSentence( QET::ElementsAndConductorsSentence(
@ -177,16 +194,18 @@ QString DiagramContent::sentence(int filter) const {
conductors_count, conductors_count,
textfields_count, textfields_count,
images_count, images_count,
shapes_count shapes_count,
elmt_text_count
) )
); );
} }
/** /**
Permet de debugger un contenu de schema * @brief operator << Use to debug a diagram content
@param d Object QDebug a utiliser pour l'affichage des informations de debug * @param d : QDebug to use for display the debug info
@param content Contenu de schema a debugger * @param content : content to debug
*/ * @return
*/
QDebug &operator<<(QDebug d, DiagramContent &content) { QDebug &operator<<(QDebug d, DiagramContent &content) {
Q_UNUSED(content); Q_UNUSED(content);
d << "DiagramContent {" << "\n"; d << "DiagramContent {" << "\n";

View File

@ -27,6 +27,7 @@ class IndependentTextItem;
class DiagramImageItem; class DiagramImageItem;
class ElementTextItem; class ElementTextItem;
class QetShapeItem; class QetShapeItem;
class DynamicElementTextItem;
/** /**
This class provides a container that makes the transmission of diagram content This class provides a container that makes the transmission of diagram content
@ -37,48 +38,43 @@ class QetShapeItem;
Please note this container does not systematically contains a whole Please note this container does not systematically contains a whole
diagram: it may describe only a part of it, e.g. selected items. diagram: it may describe only a part of it, e.g. selected items.
*/ */
class DiagramContent { class DiagramContent
{
public: public:
DiagramContent(); DiagramContent();
DiagramContent(const DiagramContent &); DiagramContent(const DiagramContent &);
~DiagramContent(); ~DiagramContent();
/// Used to filter the different items carried by this container. /// Used to filter the different items carried by this container.
enum Filter { enum Filter {
Elements = 1, Elements = 1,
TextFields = 2, TextFields = 2,
ElementTextFields = 4, ElementTextFields = 4,
Images = 8, Images = 8,
ConductorsToMove = 16, ConductorsToMove = 16,
ConductorsToUpdate = 32, ConductorsToUpdate = 32,
OtherConductors = 64, OtherConductors = 64,
AnyConductor = 112, AnyConductor = 112,
Shapes = 128, Shapes = 128,
All = 255, All = 255,
SelectedOnly = 256 SelectedOnly = 256
}; };
/// Hold electrical elements QSet<Element *> m_elements;
QSet<Element *> elements; QSet<IndependentTextItem *> m_text_fields;
/// Hold independent text items QSet<DiagramImageItem *> m_images;
QSet<IndependentTextItem *> textFields; QSet<QetShapeItem *> m_shapes;
/// Hold image QSet<Conductor *> m_conductors_to_update;
QSet<DiagramImageItem *> images; QSet<Conductor *> m_conductors_to_move;
/// Hold shape QSet<Conductor *> m_other_conductors;
QSet<QetShapeItem *> shapes; QSet<DynamicElementTextItem *> m_element_texts;
/// Hold conductors that would get updated considering electrical elements are moved
QSet<Conductor *> conductorsToUpdate;
/// Hold conductors that would be moved as is considering electrical elements are moved
QSet<Conductor *> conductorsToMove;
/// Hold conductors that would be left untouched considering electrical elements are moved
QSet<Conductor *> otherConductors;
QList<Conductor *> conductors(int = AnyConductor) const; QList<Conductor *> conductors(int = AnyConductor) const;
QList<QGraphicsItem *> items(int = All) const; QList<QGraphicsItem *> items(int = All) const;
QString sentence(int = All) const; QString sentence(int = All) const;
int count(int = All) const; int count(int = All) const;
void clear(); void clear();
int removeNonMovableItems(); int removeNonMovableItems();
}; };
QDebug &operator<<(QDebug, DiagramContent &); QDebug &operator<<(QDebug, DiagramContent &);
#endif #endif

View File

@ -45,6 +45,8 @@
#include "diagrameventaddelement.h" #include "diagrameventaddelement.h"
#include "QPropertyUndoCommand/qpropertyundocommand.h" #include "QPropertyUndoCommand/qpropertyundocommand.h"
#include "qetshapeitem.h" #include "qetshapeitem.h"
#include "undocommand/deleteqgraphicsitemcommand.h"
#include "dynamicelementtextitem.h"
/** /**
Constructeur Constructeur
@ -52,10 +54,8 @@
@param parent Le QWidget parent de cette vue de schema @param parent Le QWidget parent de cette vue de schema
*/ */
DiagramView::DiagramView(Diagram *diagram, QWidget *parent) : DiagramView::DiagramView(Diagram *diagram, QWidget *parent) :
QGraphicsView (parent), QGraphicsView (parent),
m_scene (diagram), m_diagram (diagram)
m_event_interface (nullptr),
m_first_activation (true)
{ {
grabGesture(Qt::PinchGesture); grabGesture(Qt::PinchGesture);
setAttribute(Qt::WA_DeleteOnClose, true); setAttribute(Qt::WA_DeleteOnClose, true);
@ -74,8 +74,8 @@ DiagramView::DiagramView(Diagram *diagram, QWidget *parent) :
setRenderHint(QPainter::TextAntialiasing, true); setRenderHint(QPainter::TextAntialiasing, true);
setRenderHint(QPainter::SmoothPixmapTransform, true); setRenderHint(QPainter::SmoothPixmapTransform, true);
setScene(m_scene); setScene(m_diagram);
m_scene -> undoStack().setClean(); m_diagram -> undoStack().setClean();
setWindowIcon(QET::Icons::QETLogo); setWindowIcon(QET::Icons::QETLogo);
setTransformationAnchor(QGraphicsView::AnchorUnderMouse); setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
setResizeAnchor(QGraphicsView::AnchorUnderMouse); setResizeAnchor(QGraphicsView::AnchorUnderMouse);
@ -83,17 +83,17 @@ DiagramView::DiagramView(Diagram *diagram, QWidget *parent) :
setSelectionMode(); setSelectionMode();
adjustSceneRect(); adjustSceneRect();
updateWindowTitle(); updateWindowTitle();
m_scene->loadElmtFolioSeq(); m_diagram->loadElmtFolioSeq();
m_scene->loadCndFolioSeq(); m_diagram->loadCndFolioSeq();
context_menu = new QMenu(this); m_context_menu = new QMenu(this);
paste_here = new QAction(QET::Icons::EditPaste, tr("Coller ici", "context menu action"), this); m_paste_here = new QAction(QET::Icons::EditPaste, tr("Coller ici", "context menu action"), this);
connect(paste_here, SIGNAL(triggered()), this, SLOT(pasteHere())); connect(m_paste_here, SIGNAL(triggered()), this, SLOT(pasteHere()));
connect(m_scene, SIGNAL(showDiagram(Diagram*)), this, SIGNAL(showDiagram(Diagram*))); connect(m_diagram, SIGNAL(showDiagram(Diagram*)), this, SIGNAL(showDiagram(Diagram*)));
connect(m_scene, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged())); connect(m_diagram, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged()));
connect(m_scene, SIGNAL(sceneRectChanged(QRectF)), this, SLOT(adjustSceneRect())); connect(m_diagram, SIGNAL(sceneRectChanged(QRectF)), this, SLOT(adjustSceneRect()));
connect(&(m_scene -> border_and_titleblock), SIGNAL(diagramTitleChanged(const QString &)), this, SLOT(updateWindowTitle())); connect(&(m_diagram -> border_and_titleblock), SIGNAL(diagramTitleChanged(const QString &)), this, SLOT(updateWindowTitle()));
connect(diagram, SIGNAL(editElementRequired(ElementsLocation)), this, SIGNAL(editElementRequired(ElementsLocation))); connect(diagram, SIGNAL(editElementRequired(ElementsLocation)), this, SIGNAL(editElementRequired(ElementsLocation)));
connect(diagram, SIGNAL(findElementRequired(ElementsLocation)), this, SIGNAL(findElementRequired(ElementsLocation))); connect(diagram, SIGNAL(findElementRequired(ElementsLocation)), this, SIGNAL(findElementRequired(ElementsLocation)));
@ -111,93 +111,113 @@ DiagramView::~DiagramView() {
Selectionne tous les objets du schema Selectionne tous les objets du schema
*/ */
void DiagramView::selectAll() { void DiagramView::selectAll() {
m_scene -> selectAll(); m_diagram -> selectAll();
} }
/** /**
Deslectionne tous les objets selectionnes Deslectionne tous les objets selectionnes
*/ */
void DiagramView::selectNothing() { void DiagramView::selectNothing() {
m_scene -> deselectAll(); m_diagram -> deselectAll();
} }
/** /**
Inverse l'etat de selection de tous les objets du schema Inverse l'etat de selection de tous les objets du schema
*/ */
void DiagramView::selectInvert() { void DiagramView::selectInvert() {
m_scene -> invertSelection(); m_diagram -> invertSelection();
} }
/** /**
Supprime les composants selectionnes * @brief DiagramView::deleteSelection
*/ * Delete the selected items
void DiagramView::deleteSelection() { */
if (m_scene -> isReadOnly()) return; void DiagramView::deleteSelection()
DiagramContent removed_content = m_scene -> selectedContent(); {
m_scene -> clearSelection(); if (m_diagram -> isReadOnly())
m_scene -> undoStack().push(new DeleteElementsCommand(m_scene, removed_content)); return;
DiagramContent removed_content = m_diagram->selectedContent();
m_diagram->clearSelection();
m_diagram->undoStack().push(new DeleteQGraphicsItemCommand(m_diagram, removed_content));
adjustSceneRect(); adjustSceneRect();
} }
/** /**
Pivote les composants selectionnes * @brief DiagramView::rotateSelection
*/ * Rotate the selected items
void DiagramView::rotateSelection() { */
if (m_scene -> isReadOnly()) return; void DiagramView::rotateSelection()
{
if (m_diagram->isReadOnly())
return;
// recupere les elements et les champs de texte a pivoter
QList<Element *> elements_to_rotate; QList<Element *> elements_to_rotate;
QList<DiagramTextItem *> texts_to_rotate; QList<DiagramTextItem *> texts_to_rotate;
QList<DiagramImageItem *> images_to_rotate; QList<DiagramImageItem *> images_to_rotate;
foreach (QGraphicsItem *item, m_scene -> selectedItems()) {
if (Element *e = qgraphicsitem_cast<Element *>(item)) { for (QGraphicsItem *item : m_diagram->selectedItems())
{
if (Element *e = qgraphicsitem_cast<Element *>(item))
elements_to_rotate << e; elements_to_rotate << e;
} else if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(item)) { else if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(item))
texts_to_rotate << cti; texts_to_rotate << cti;
} else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item)) { else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item))
texts_to_rotate << iti; texts_to_rotate << iti;
} else if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(item)) { else if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(item))
// on ne pivote un texte d'element que si son parent n'est pas selectionne {
if (eti -> parentItem() && !eti -> parentItem() -> isSelected()) { //We rotate element text item only if is parent element is not selected
if (eti->parentItem() && !eti->parentItem()->isSelected())
texts_to_rotate << eti; texts_to_rotate << eti;
}
} else if (DiagramImageItem *dii = qgraphicsitem_cast<DiagramImageItem *>(item)) {
images_to_rotate << dii;
} }
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;
} }
// effectue les rotations s'il y a quelque chose a pivoter //Do the rotation
if (elements_to_rotate.isEmpty() && texts_to_rotate.isEmpty() && images_to_rotate.isEmpty()) return; if (elements_to_rotate.isEmpty() && texts_to_rotate.isEmpty() && images_to_rotate.isEmpty())
m_scene -> undoStack().push(new RotateElementsCommand(elements_to_rotate, texts_to_rotate, images_to_rotate)); return;
m_diagram->undoStack().push(new RotateElementsCommand(elements_to_rotate, texts_to_rotate, images_to_rotate));
} }
void DiagramView::rotateTexts() { /**
if (m_scene -> isReadOnly()) return; * @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;
// recupere les champs de texte a orienter //Get the texts fields
QList<DiagramTextItem *> texts_to_rotate; QList<DiagramTextItem *> texts_to_rotate;
foreach (QGraphicsItem *item, m_scene -> selectedItems()) { for (QGraphicsItem *item : m_diagram->selectedItems())
if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(item)) { {
if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(item))
texts_to_rotate << cti; texts_to_rotate << cti;
} else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item)) { else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item))
texts_to_rotate << iti; texts_to_rotate << iti;
} else if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(item)) { else if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(item))
// ici, on pivote un texte d'element meme si son parent est selectionne
texts_to_rotate << eti; texts_to_rotate << eti;
} else if (DynamicElementTextItem *deti = qgraphicsitem_cast<DynamicElementTextItem *>(item))
texts_to_rotate << deti;
} }
// effectue les rotations s'il y a quelque chose a pivoter if (texts_to_rotate.isEmpty())
if (texts_to_rotate.isEmpty()) return; return;
// demande un angle a l'utilisateur //Open the dialog
QDialog ori_text_dialog(diagramEditor()); QDialog ori_text_dialog(diagramEditor());
ori_text_dialog.setSizeGripEnabled(false); ori_text_dialog.setSizeGripEnabled(false);
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
ori_text_dialog.setWindowFlags(Qt::Sheet); ori_text_dialog.setWindowFlags(Qt::Sheet);
#endif #endif
ori_text_dialog.setWindowTitle(tr("Orienter les textes sélectionnés", "window title")); ori_text_dialog.setWindowTitle(tr("Orienter les textes sélectionnés", "window title"));
// ori_text_dialog.setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
QTextOrientationSpinBoxWidget *ori_widget = QETApp::createTextOrientationSpinBoxWidget(); QTextOrientationSpinBoxWidget *ori_widget = QETApp::createTextOrientationSpinBoxWidget();
@ -207,22 +227,18 @@ void DiagramView::rotateTexts() {
} }
ori_widget -> spinBox() -> selectAll(); ori_widget -> spinBox() -> selectAll();
// boutons
QDialogButtonBox buttons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); QDialogButtonBox buttons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
connect(&buttons, SIGNAL(accepted()), &ori_text_dialog, SLOT(accept())); connect(&buttons, SIGNAL(accepted()), &ori_text_dialog, SLOT(accept()));
connect(&buttons, SIGNAL(rejected()), &ori_text_dialog, SLOT(reject())); connect(&buttons, SIGNAL(rejected()), &ori_text_dialog, SLOT(reject()));
// ajout dans une disposition verticale
QVBoxLayout layout_v(&ori_text_dialog); QVBoxLayout layout_v(&ori_text_dialog);
layout_v.setSizeConstraint(QLayout::SetFixedSize); layout_v.setSizeConstraint(QLayout::SetFixedSize);
layout_v.addWidget(ori_widget); layout_v.addWidget(ori_widget);
layout_v.addStretch(); layout_v.addStretch();
layout_v.addWidget(&buttons); layout_v.addWidget(&buttons);
// si le dialogue est accepte if (ori_text_dialog.exec() == QDialog::Accepted)
if (ori_text_dialog.exec() == QDialog::Accepted) { m_diagram -> undoStack().push(new RotateTextsCommand(texts_to_rotate, ori_widget -> orientation()));
m_scene -> undoStack().push(new RotateTextsCommand(texts_to_rotate, ori_widget -> orientation()));
}
} }
/** /**
@ -307,11 +323,11 @@ void DiagramView::handleTitleBlockDrop(QDropEvent *e) {
if (tbt_loc.isValid()) if (tbt_loc.isValid())
{ {
// fetch the current title block properties // fetch the current title block properties
TitleBlockProperties titleblock_properties_before = m_scene->border_and_titleblock.exportTitleBlock(); TitleBlockProperties titleblock_properties_before = m_diagram->border_and_titleblock.exportTitleBlock();
// check the provided template is not already applied // check the provided template is not already applied
QETProject *tbt_parent_project = tbt_loc.parentProject(); QETProject *tbt_parent_project = tbt_loc.parentProject();
if (tbt_parent_project && tbt_parent_project == m_scene -> project()) if (tbt_parent_project && tbt_parent_project == m_diagram -> project())
{ {
// same parent project and same name = same title block template // same parent project and same name = same title block template
if (tbt_loc.name() == titleblock_properties_before.template_name) if (tbt_loc.name() == titleblock_properties_before.template_name)
@ -324,7 +340,7 @@ void DiagramView::handleTitleBlockDrop(QDropEvent *e) {
{ {
IntegrationMoveTitleBlockTemplatesHandler *handler = new IntegrationMoveTitleBlockTemplatesHandler(this); IntegrationMoveTitleBlockTemplatesHandler *handler = new IntegrationMoveTitleBlockTemplatesHandler(this);
//QString error_message; //QString error_message;
integrated_template_name = m_scene->project()->integrateTitleBlockTemplate(tbt_loc, handler); integrated_template_name = m_diagram->project()->integrateTitleBlockTemplate(tbt_loc, handler);
if (integrated_template_name.isEmpty()) if (integrated_template_name.isEmpty())
return; return;
@ -336,7 +352,7 @@ void DiagramView::handleTitleBlockDrop(QDropEvent *e) {
TitleBlockProperties titleblock_properties_after = titleblock_properties_before; TitleBlockProperties titleblock_properties_after = titleblock_properties_before;
titleblock_properties_after.template_name = integrated_template_name; titleblock_properties_after.template_name = integrated_template_name;
m_scene->undoStack().push(new ChangeTitleBlockCommand(m_scene, titleblock_properties_before, titleblock_properties_after)); m_diagram->undoStack().push(new ChangeTitleBlockCommand(m_diagram, titleblock_properties_before, titleblock_properties_after));
adjustSceneRect(); adjustSceneRect();
} }
@ -348,7 +364,7 @@ void DiagramView::handleTitleBlockDrop(QDropEvent *e) {
* @param e the QDropEvent describing the current drag'n drop * @param e the QDropEvent describing the current drag'n drop
*/ */
void DiagramView::handleTextDrop(QDropEvent *e) { void DiagramView::handleTextDrop(QDropEvent *e) {
if (m_scene -> isReadOnly() || (e -> mimeData() -> hasText() == false) ) return; if (m_diagram -> isReadOnly() || (e -> mimeData() -> hasText() == false) ) return;
IndependentTextItem *iti = new IndependentTextItem (e -> mimeData() -> text()); IndependentTextItem *iti = new IndependentTextItem (e -> mimeData() -> text());
@ -356,7 +372,7 @@ void DiagramView::handleTextDrop(QDropEvent *e) {
iti -> setHtml (e -> mimeData() -> text()); iti -> setHtml (e -> mimeData() -> text());
} }
m_scene -> undoStack().push(new AddItemCommand<IndependentTextItem *>(iti, m_scene, mapToScene(e->pos()))); m_diagram -> undoStack().push(new AddItemCommand<IndependentTextItem *>(iti, m_diagram, mapToScene(e->pos())));
} }
/** /**
@ -398,9 +414,8 @@ void DiagramView::zoom(const qreal zoom_factor)
(horizontalScrollBar()->maximum() || verticalScrollBar()->maximum()) ) (horizontalScrollBar()->maximum() || verticalScrollBar()->maximum()) )
scale(zoom_factor, zoom_factor); scale(zoom_factor, zoom_factor);
} }
m_scene->adjustSceneRect(); m_diagram->adjustSceneRect();
adjustGridToZoom(); adjustGridToZoom();
adjustSceneRect();
} }
/** /**
@ -410,7 +425,7 @@ void DiagramView::zoom(const qreal zoom_factor)
*/ */
void DiagramView::zoomFit() { void DiagramView::zoomFit() {
adjustSceneRect(); adjustSceneRect();
fitInView(m_scene->sceneRect(), Qt::KeepAspectRatio); fitInView(m_diagram->sceneRect(), Qt::KeepAspectRatio);
adjustGridToZoom(); adjustGridToZoom();
} }
@ -418,7 +433,7 @@ void DiagramView::zoomFit() {
Adjust zoom to fit all elements in the view, regardless of diagram borders. Adjust zoom to fit all elements in the view, regardless of diagram borders.
*/ */
void DiagramView::zoomContent() { void DiagramView::zoomContent() {
fitInView(m_scene -> itemsBoundingRect(), Qt::KeepAspectRatio); fitInView(m_diagram -> itemsBoundingRect(), Qt::KeepAspectRatio);
adjustGridToZoom(); adjustGridToZoom();
} }
@ -435,9 +450,9 @@ void DiagramView::zoomReset() {
*/ */
void DiagramView::cut() { void DiagramView::cut() {
copy(); copy();
DiagramContent cut_content = m_scene -> selectedContent(); DiagramContent cut_content = m_diagram -> selectedContent();
m_scene -> clearSelection(); m_diagram -> clearSelection();
m_scene -> undoStack().push(new CutDiagramCommand(m_scene, cut_content)); m_diagram -> undoStack().push(new CutDiagramCommand(m_diagram, cut_content));
} }
/** /**
@ -445,7 +460,7 @@ void DiagramView::cut() {
*/ */
void DiagramView::copy() { void DiagramView::copy() {
QClipboard *presse_papier = QApplication::clipboard(); QClipboard *presse_papier = QApplication::clipboard();
QString contenu_presse_papier = m_scene -> toXml(false).toString(4); QString contenu_presse_papier = m_diagram -> toXml(false).toString(4);
if (presse_papier -> supportsSelection()) presse_papier -> setText(contenu_presse_papier, QClipboard::Selection); if (presse_papier -> supportsSelection()) presse_papier -> setText(contenu_presse_papier, QClipboard::Selection);
presse_papier -> setText(contenu_presse_papier); presse_papier -> setText(contenu_presse_papier);
} }
@ -457,7 +472,7 @@ void DiagramView::copy() {
@param clipboard_mode Type de presse-papier a prendre en compte @param clipboard_mode Type de presse-papier a prendre en compte
*/ */
void DiagramView::paste(const QPointF &pos, QClipboard::Mode clipboard_mode) { void DiagramView::paste(const QPointF &pos, QClipboard::Mode clipboard_mode) {
if (!isInteractive() || m_scene -> isReadOnly()) return; if (!isInteractive() || m_diagram -> isReadOnly()) return;
QString texte_presse_papier = QApplication::clipboard() -> text(clipboard_mode); QString texte_presse_papier = QApplication::clipboard() -> text(clipboard_mode);
if ((texte_presse_papier).isEmpty()) return; if ((texte_presse_papier).isEmpty()) return;
@ -468,12 +483,12 @@ void DiagramView::paste(const QPointF &pos, QClipboard::Mode clipboard_mode) {
// objet pour recuperer le contenu ajoute au schema par le coller // objet pour recuperer le contenu ajoute au schema par le coller
DiagramContent content_pasted; DiagramContent content_pasted;
this->diagram()->item_paste = true; this->diagram()->item_paste = true;
m_scene -> fromXml(document_xml, pos, false, &content_pasted); m_diagram -> fromXml(document_xml, pos, false, &content_pasted);
// si quelque chose a effectivement ete ajoute au schema, on cree un objet d'annulation // si quelque chose a effectivement ete ajoute au schema, on cree un objet d'annulation
if (content_pasted.count()) { if (content_pasted.count()) {
m_scene -> clearSelection(); m_diagram -> clearSelection();
m_scene -> undoStack().push(new PasteDiagramCommand(m_scene, content_pasted)); m_diagram -> undoStack().push(new PasteDiagramCommand(m_diagram, content_pasted));
adjustSceneRect(); adjustSceneRect();
} }
this->diagram()->item_paste = false; this->diagram()->item_paste = false;
@ -483,7 +498,7 @@ void DiagramView::paste(const QPointF &pos, QClipboard::Mode clipboard_mode) {
Colle le contenu du presse-papier sur le schema a la position de la souris Colle le contenu du presse-papier sur le schema a la position de la souris
*/ */
void DiagramView::pasteHere() { void DiagramView::pasteHere() {
paste(mapToScene(paste_here_pos)); paste(mapToScene(m_paste_here_pos));
} }
/** /**
@ -492,10 +507,10 @@ void DiagramView::pasteHere() {
*/ */
void DiagramView::mousePressEvent(QMouseEvent *e) void DiagramView::mousePressEvent(QMouseEvent *e)
{ {
if (fresh_focus_in_) if (m_fresh_focus_in)
{ {
switchToVisualisationModeIfNeeded(e); switchToVisualisationModeIfNeeded(e);
fresh_focus_in_ = false; m_fresh_focus_in = false;
} }
if (m_event_interface && m_event_interface->mousePressEvent(e)) return; if (m_event_interface && m_event_interface->mousePressEvent(e)) return;
@ -503,7 +518,7 @@ void DiagramView::mousePressEvent(QMouseEvent *e)
//Start drag view when hold the middle button //Start drag view when hold the middle button
if (e->button() == Qt::MidButton) if (e->button() == Qt::MidButton)
{ {
rubber_band_origin = e->pos(); m_rubber_band_origin = e->pos();
viewport()->setCursor(Qt::ClosedHandCursor); viewport()->setCursor(Qt::ClosedHandCursor);
} }
@ -523,11 +538,10 @@ void DiagramView::mouseMoveEvent(QMouseEvent *e)
{ {
QScrollBar *h = horizontalScrollBar(); QScrollBar *h = horizontalScrollBar();
QScrollBar *v = verticalScrollBar(); QScrollBar *v = verticalScrollBar();
QPointF pos = rubber_band_origin - e -> pos(); QPointF pos = m_rubber_band_origin - e -> pos();
rubber_band_origin = e -> pos(); m_rubber_band_origin = e -> pos();
h -> setValue(h -> value() + pos.x()); h -> setValue(h -> value() + pos.x());
v -> setValue(v -> value() + pos.y()); v -> setValue(v -> value() + pos.y());
adjustSceneRect();
} }
else QGraphicsView::mouseMoveEvent(e); else QGraphicsView::mouseMoveEvent(e);
@ -619,7 +633,7 @@ bool DiagramView::gestureEvent(QGestureEvent *event)
*/ */
void DiagramView::focusInEvent(QFocusEvent *e) { void DiagramView::focusInEvent(QFocusEvent *e) {
if (e -> reason() == Qt::MouseFocusReason) { if (e -> reason() == Qt::MouseFocusReason) {
fresh_focus_in_ = true; m_fresh_focus_in = true;
} }
} }
@ -641,10 +655,10 @@ switch(e -> key())
case Qt::Key_Home: case Qt::Key_Home:
if (!hasTextItems()) { if (!hasTextItems()) {
if ( if (
qgraphicsitem_cast<IndependentTextItem *>(m_scene->focusItem()) || qgraphicsitem_cast<IndependentTextItem *>(m_diagram->focusItem()) ||
qgraphicsitem_cast<ElementTextItem *>(m_scene->focusItem()) || qgraphicsitem_cast<ElementTextItem *>(m_diagram->focusItem()) ||
qgraphicsitem_cast<ConductorTextItem *>(m_scene->focusItem()) || qgraphicsitem_cast<ConductorTextItem *>(m_diagram->focusItem()) ||
qgraphicsitem_cast<DiagramTextItem *>(m_scene->focusItem()) qgraphicsitem_cast<DiagramTextItem *>(m_diagram->focusItem())
) )
break; break;
current_project->changeFirstTab(); current_project->changeFirstTab();
@ -654,10 +668,10 @@ switch(e -> key())
case Qt::Key_End: case Qt::Key_End:
if (!hasTextItems()) { if (!hasTextItems()) {
if ( if (
qgraphicsitem_cast<IndependentTextItem *>(m_scene->focusItem()) || qgraphicsitem_cast<IndependentTextItem *>(m_diagram->focusItem()) ||
qgraphicsitem_cast<ElementTextItem *>(m_scene->focusItem()) || qgraphicsitem_cast<ElementTextItem *>(m_diagram->focusItem()) ||
qgraphicsitem_cast<ConductorTextItem *>(m_scene->focusItem()) || qgraphicsitem_cast<ConductorTextItem *>(m_diagram->focusItem()) ||
qgraphicsitem_cast<DiagramTextItem *>(m_scene->focusItem()) qgraphicsitem_cast<DiagramTextItem *>(m_diagram->focusItem())
) )
break; break;
current_project->changeLastTab(); current_project->changeLastTab();
@ -677,19 +691,19 @@ switch(e -> key())
if (e->modifiers() & Qt::ControlModifier) if (e->modifiers() & Qt::ControlModifier)
zoom(1.15); zoom(1.15);
case Qt::Key_Up: case Qt::Key_Up:
if(!(m_scene->selectedContent().items(255).isEmpty())){ if(!(m_diagram->selectedContent().items(DiagramContent::All).isEmpty())){
scrollOnMovement(e); scrollOnMovement(e);
} }
case Qt::Key_Down: case Qt::Key_Down:
if(!(m_scene->selectedContent().items(255).isEmpty())){ if(!(m_diagram->selectedContent().items(DiagramContent::All).isEmpty())){
scrollOnMovement(e); scrollOnMovement(e);
} }
case Qt::Key_Left: case Qt::Key_Left:
if(!(m_scene->selectedContent().items(255).isEmpty())){ if(!(m_diagram->selectedContent().items(DiagramContent::All).isEmpty())){
scrollOnMovement(e); scrollOnMovement(e);
} }
case Qt::Key_Right: case Qt::Key_Right:
if(!(m_scene->selectedContent().items(255).isEmpty())){ if(!(m_diagram->selectedContent().items(DiagramContent::All).isEmpty())){
scrollOnMovement(e); scrollOnMovement(e);
} }
} }
@ -714,7 +728,7 @@ void DiagramView::keyReleaseEvent(QKeyEvent *e) {
or below the editor SceneRect is expanded or below the editor SceneRect is expanded
*/ */
void DiagramView::scrollOnMovement(QKeyEvent *e){ void DiagramView::scrollOnMovement(QKeyEvent *e){
QList<QGraphicsItem *> selected_elmts = m_scene->selectedContent().items(255); QList<QGraphicsItem *> selected_elmts = m_diagram->selectedContent().items(DiagramContent::All);
QRectF viewed_scene = viewedSceneRect(); QRectF viewed_scene = viewedSceneRect();
foreach (QGraphicsItem *qgi, selected_elmts){ foreach (QGraphicsItem *qgi, selected_elmts){
if (qgraphicsitem_cast<Conductor *>(qgi)) continue; if (qgraphicsitem_cast<Conductor *>(qgi)) continue;
@ -755,10 +769,10 @@ void DiagramView::scrollOnMovement(QKeyEvent *e){
h_increment = 2*qgi->boundingRect().right(); h_increment = 2*qgi->boundingRect().right();
if (h_increment == 0) h_increment = -2*qgi->boundingRect().width(); if (h_increment == 0) h_increment = -2*qgi->boundingRect().width();
} }
if (((elmt_right >= m_scene->sceneRect().right() - qgi->boundingRect().right()) || if (((elmt_right >= m_diagram->sceneRect().right() - qgi->boundingRect().right()) ||
(elmt_bottom >= m_scene->sceneRect().bottom() - qgi->boundingRect().bottom())) && (elmt_bottom >= m_diagram->sceneRect().bottom() - qgi->boundingRect().bottom())) &&
(e->key()==Qt::Key_Right || e->key()==Qt::Key_Down)){ (e->key()==Qt::Key_Right || e->key()==Qt::Key_Down)){
m_scene->adjustSceneRect(); m_diagram->adjustSceneRect();
} }
h -> setValue(h -> value() + h_increment); h -> setValue(h -> value() + h_increment);
v -> setValue(v -> value() + v_increment); v -> setValue(v -> value() + v_increment);
@ -775,7 +789,7 @@ void DiagramView::scrollOnMovement(QKeyEvent *e){
*/ */
QString DiagramView::title() const { QString DiagramView::title() const {
QString view_title; QString view_title;
QString diagram_title(m_scene -> title()); QString diagram_title(m_diagram -> title());
if (diagram_title.isEmpty()) { if (diagram_title.isEmpty()) {
view_title = tr("Sans titre", "what to display for untitled diagrams"); view_title = tr("Sans titre", "what to display for untitled diagrams");
} else { } else {
@ -789,14 +803,14 @@ QString DiagramView::title() const {
* Edit the properties of the viewed digram * Edit the properties of the viewed digram
*/ */
void DiagramView::editDiagramProperties() { void DiagramView::editDiagramProperties() {
DiagramPropertiesDialog::diagramPropertiesDialog(m_scene, diagramEditor()); DiagramPropertiesDialog::diagramPropertiesDialog(m_diagram, diagramEditor());
} }
/** /**
@return true s'il y a des items selectionnes sur le schema, false sinon @return true s'il y a des items selectionnes sur le schema, false sinon
*/ */
bool DiagramView::hasSelectedItems() { bool DiagramView::hasSelectedItems() {
return(m_scene -> selectedItems().size() > 0); return(m_diagram -> selectedItems().size() > 0);
} }
/** /**
@ -804,7 +818,7 @@ bool DiagramView::hasSelectedItems() {
peuvent etre copies dans le presse-papier, false sinon peuvent etre copies dans le presse-papier, false sinon
*/ */
bool DiagramView::hasCopiableItems() { bool DiagramView::hasCopiableItems() {
foreach(QGraphicsItem *qgi, m_scene -> selectedItems()) { foreach(QGraphicsItem *qgi, m_diagram -> selectedItems()) {
if ( if (
qgraphicsitem_cast<Element *>(qgi) || qgraphicsitem_cast<Element *>(qgi) ||
qgraphicsitem_cast<IndependentTextItem *>(qgi) || qgraphicsitem_cast<IndependentTextItem *>(qgi) ||
@ -821,7 +835,7 @@ bool DiagramView::hasCopiableItems() {
@return true if there is any Text Item selected @return true if there is any Text Item selected
*/ */
bool DiagramView::hasTextItems() { bool DiagramView::hasTextItems() {
foreach(QGraphicsItem *qgi, m_scene -> selectedItems()) { foreach(QGraphicsItem *qgi, m_diagram -> selectedItems()) {
if ( if (
qgraphicsitem_cast<IndependentTextItem *>(qgi) || qgraphicsitem_cast<IndependentTextItem *>(qgi) ||
qgraphicsitem_cast<ElementTextItem *>(qgi) || qgraphicsitem_cast<ElementTextItem *>(qgi) ||
@ -835,20 +849,20 @@ bool DiagramView::hasTextItems() {
} }
/** /**
@return true s'il y a des items selectionnes sur le schema et que ceux-ci * @brief DiagramView::hasDeletableItems
peuvent etre supprimes, false sinon * @return True if a least on of selected item can be deleted
*/ */
bool DiagramView::hasDeletableItems() { bool DiagramView::hasDeletableItems()
foreach(QGraphicsItem *qgi, m_scene -> selectedItems()) { {
if ( for(QGraphicsItem *qgi : m_diagram->selectedItems())
qgraphicsitem_cast<Element *>(qgi) || {
qgraphicsitem_cast<Conductor *>(qgi) || if (qgi->type() == Element::Type ||
qgraphicsitem_cast<IndependentTextItem *>(qgi) || qgi->type() == Conductor::Type ||
qgraphicsitem_cast<QetShapeItem *>(qgi) || qgi->type() == IndependentTextItem::Type ||
qgraphicsitem_cast<DiagramImageItem *>(qgi) qgi->type() == QetShapeItem::Type ||
) { qgi->type() == DiagramImageItem::Type ||
return(true); qgi->type() == DynamicElementTextItem::Type)
} return true;
} }
return(false); return(false);
} }
@ -857,64 +871,55 @@ bool DiagramView::hasDeletableItems() {
Ajoute une colonne au schema. Ajoute une colonne au schema.
*/ */
void DiagramView::addColumn() { void DiagramView::addColumn() {
if (m_scene -> isReadOnly()) return; if (m_diagram -> isReadOnly()) return;
BorderProperties old_bp = m_scene -> border_and_titleblock.exportBorder(); BorderProperties old_bp = m_diagram -> border_and_titleblock.exportBorder();
BorderProperties new_bp = m_scene -> border_and_titleblock.exportBorder(); BorderProperties new_bp = m_diagram -> border_and_titleblock.exportBorder();
new_bp.columns_count += 1; new_bp.columns_count += 1;
m_scene -> undoStack().push(new ChangeBorderCommand(m_scene, old_bp, new_bp)); m_diagram -> undoStack().push(new ChangeBorderCommand(m_diagram, old_bp, new_bp));
} }
/** /**
Enleve une colonne au schema. Enleve une colonne au schema.
*/ */
void DiagramView::removeColumn() { void DiagramView::removeColumn() {
if (m_scene -> isReadOnly()) return; if (m_diagram -> isReadOnly()) return;
BorderProperties old_bp = m_scene -> border_and_titleblock.exportBorder(); BorderProperties old_bp = m_diagram -> border_and_titleblock.exportBorder();
BorderProperties new_bp = m_scene -> border_and_titleblock.exportBorder(); BorderProperties new_bp = m_diagram -> border_and_titleblock.exportBorder();
new_bp.columns_count -= 1; new_bp.columns_count -= 1;
m_scene -> undoStack().push(new ChangeBorderCommand(m_scene, old_bp, new_bp)); m_diagram -> undoStack().push(new ChangeBorderCommand(m_diagram, old_bp, new_bp));
} }
/** /**
Agrandit le schema en hauteur Agrandit le schema en hauteur
*/ */
void DiagramView::addRow() { void DiagramView::addRow() {
if (m_scene -> isReadOnly()) return; if (m_diagram -> isReadOnly()) return;
BorderProperties old_bp = m_scene -> border_and_titleblock.exportBorder(); BorderProperties old_bp = m_diagram -> border_and_titleblock.exportBorder();
BorderProperties new_bp = m_scene -> border_and_titleblock.exportBorder(); BorderProperties new_bp = m_diagram -> border_and_titleblock.exportBorder();
new_bp.rows_count += 1; new_bp.rows_count += 1;
m_scene -> undoStack().push(new ChangeBorderCommand(m_scene, old_bp, new_bp)); m_diagram -> undoStack().push(new ChangeBorderCommand(m_diagram, old_bp, new_bp));
} }
/** /**
Retrecit le schema en hauteur Retrecit le schema en hauteur
*/ */
void DiagramView::removeRow() { void DiagramView::removeRow() {
if (m_scene -> isReadOnly()) return; if (m_diagram -> isReadOnly()) return;
BorderProperties old_bp = m_scene -> border_and_titleblock.exportBorder(); BorderProperties old_bp = m_diagram -> border_and_titleblock.exportBorder();
BorderProperties new_bp = m_scene -> border_and_titleblock.exportBorder(); BorderProperties new_bp = m_diagram -> border_and_titleblock.exportBorder();
new_bp.rows_count -= 1; new_bp.rows_count -= 1;
m_scene -> undoStack().push(new ChangeBorderCommand(m_scene, old_bp, new_bp)); m_diagram -> undoStack().push(new ChangeBorderCommand(m_diagram, old_bp, new_bp));
} }
/** /**
* @brief DiagramView::adjustSceneRect * @brief DiagramView::adjustSceneRect
* Calcul and set the area of the scene visualized by this view * Calcul and set the area of the scene visualized by this view
* The area are diagram sceneRect * 2.
*/ */
void DiagramView::adjustSceneRect() void DiagramView::adjustSceneRect()
{ {
QRectF scene_rect = m_scene->sceneRect(); QRectF scene_rect = m_diagram->sceneRect();
scene_rect.adjust(-Diagram::margin, -Diagram::margin, Diagram::margin, Diagram::margin); scene_rect.adjust(-Diagram::margin, -Diagram::margin, Diagram::margin, Diagram::margin);
QSettings settings;
if (settings.value("diagrameditor/zoom-out-beyond-of-folio", false).toBool())
{
//When zoom out beyong of folio is active,
//we always adjust the scene rect to be 1/3 bigger than the wiewport
QRectF vpbr = mapToScene(viewport()->rect()).boundingRect();
vpbr.adjust(0, 0, vpbr.width()/3, vpbr.height()/3);
scene_rect = scene_rect.united(vpbr);
}
setSceneRect(scene_rect); setSceneRect(scene_rect);
} }
@ -931,9 +936,9 @@ void DiagramView::updateWindowTitle() {
void DiagramView::adjustGridToZoom() { void DiagramView::adjustGridToZoom() {
QRectF viewed_scene = viewedSceneRect(); QRectF viewed_scene = viewedSceneRect();
if (diagramEditor()->drawGrid()) if (diagramEditor()->drawGrid())
m_scene->setDisplayGrid(viewed_scene.width() < 2000 || viewed_scene.height() < 2000); m_diagram->setDisplayGrid(viewed_scene.width() < 2000 || viewed_scene.height() < 2000);
else else
m_scene->setDisplayGrid(false); m_diagram->setDisplayGrid(false);
} }
/** /**
@ -965,7 +970,7 @@ bool DiagramView::mustIntegrateTitleBlockTemplate(const TitleBlockTemplateLocati
QETProject *tbt_parent_project = tbt_loc.parentProject(); QETProject *tbt_parent_project = tbt_loc.parentProject();
if (!tbt_parent_project) return(true); if (!tbt_parent_project) return(true);
return(tbt_parent_project != m_scene -> project()); return(tbt_parent_project != m_diagram -> project());
} }
/** /**
@ -973,9 +978,9 @@ bool DiagramView::mustIntegrateTitleBlockTemplate(const TitleBlockTemplateLocati
seule seule
*/ */
void DiagramView::applyReadOnly() { void DiagramView::applyReadOnly() {
if (!m_scene) return; if (!m_diagram) return;
bool is_writable = !m_scene -> isReadOnly(); bool is_writable = !m_diagram -> isReadOnly();
setInteractive(is_writable); setInteractive(is_writable);
setAcceptDrops(is_writable); setAcceptDrops(is_writable);
} }
@ -985,7 +990,7 @@ void DiagramView::applyReadOnly() {
*/ */
void DiagramView::editSelectionProperties() { void DiagramView::editSelectionProperties() {
// get selection // get selection
DiagramContent selection = m_scene -> selectedContent(); DiagramContent selection = m_diagram -> selectedContent();
// if selection contains nothing return // if selection contains nothing return
int selected_items_count = selection.count(DiagramContent::All | DiagramContent::SelectedOnly); int selected_items_count = selection.count(DiagramContent::All | DiagramContent::SelectedOnly);
@ -999,8 +1004,8 @@ void DiagramView::editSelectionProperties() {
if (selection.conductors(DiagramContent::AnyConductor | DiagramContent::SelectedOnly).size()) if (selection.conductors(DiagramContent::AnyConductor | DiagramContent::SelectedOnly).size())
selection.conductors().first()->editProperty(); selection.conductors().first()->editProperty();
// edit element // edit element
else if (selection.elements.size()) else if (selection.m_elements.size())
selection.elements.toList().first() -> editProperty(); selection.m_elements.toList().first() -> editProperty();
} }
else { else {
@ -1022,7 +1027,7 @@ void DiagramView::editSelectionProperties() {
*/ */
void DiagramView::editSelectedConductorColor() { void DiagramView::editSelectedConductorColor() {
// retrieve selected content // retrieve selected content
DiagramContent selection = m_scene -> selectedContent(); DiagramContent selection = m_diagram -> selectedContent();
// 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); QList<Conductor *> selected_conductors = selection.conductors(DiagramContent::AnyConductor | DiagramContent::SelectedOnly);
@ -1037,7 +1042,7 @@ void DiagramView::editSelectedConductorColor() {
*/ */
void DiagramView::editConductorColor(Conductor *edited_conductor) void DiagramView::editConductorColor(Conductor *edited_conductor)
{ {
if (m_scene -> isReadOnly() || !edited_conductor) return; if (m_diagram -> isReadOnly() || !edited_conductor) return;
// store the initial properties of the provided conductor // store the initial properties of the provided conductor
ConductorProperties initial_properties = edited_conductor -> properties(); ConductorProperties initial_properties = edited_conductor -> properties();
@ -1073,9 +1078,9 @@ void DiagramView::editConductorColor(Conductor *edited_conductor)
Reinitialise le profil des conducteurs selectionnes Reinitialise le profil des conducteurs selectionnes
*/ */
void DiagramView::resetConductors() { void DiagramView::resetConductors() {
if (m_scene -> isReadOnly()) return; if (m_diagram -> isReadOnly()) return;
// recupere les conducteurs selectionnes // recupere les conducteurs selectionnes
QSet<Conductor *> selected_conductors = m_scene -> selectedConductors(); QSet<Conductor *> selected_conductors = m_diagram -> selectedConductors();
// repere les conducteurs modifies (= profil non nul) // repere les conducteurs modifies (= profil non nul)
QHash<Conductor *, ConductorProfilesGroup> conductors_and_profiles; QHash<Conductor *, ConductorProfilesGroup> conductors_and_profiles;
@ -1092,7 +1097,7 @@ void DiagramView::resetConductors() {
} }
if (conductors_and_profiles.isEmpty()) return; if (conductors_and_profiles.isEmpty()) return;
m_scene -> undoStack().push(new ResetConductorCommand(conductors_and_profiles)); m_diagram -> undoStack().push(new ResetConductorCommand(conductors_and_profiles));
} }
/** /**
@ -1186,9 +1191,9 @@ bool DiagramView::isCtrlShifting(QInputEvent *e) {
*/ */
bool DiagramView::selectedItemHasFocus() { bool DiagramView::selectedItemHasFocus() {
return( return(
m_scene -> hasFocus() && m_diagram -> hasFocus() &&
m_scene -> focusItem() && m_diagram -> focusItem() &&
m_scene -> focusItem() -> isSelected() m_diagram -> focusItem() -> isSelected()
); );
} }
@ -1197,9 +1202,9 @@ bool DiagramView::selectedItemHasFocus() {
* Edit the selected item if he can be edited and if only one item is selected * Edit the selected item if he can be edited and if only one item is selected
*/ */
void DiagramView::editSelection() { void DiagramView::editSelection() {
if (m_scene -> isReadOnly() || m_scene -> selectedItems().size() != 1 ) return; if (m_diagram -> isReadOnly() || m_diagram -> selectedItems().size() != 1 ) return;
QGraphicsItem *item = m_scene->selectedItems().first(); QGraphicsItem *item = m_diagram->selectedItems().first();
//We use dynamic_cast instead of qgraphicsitem_cast for QetGraphicsItem //We use dynamic_cast instead of qgraphicsitem_cast for QetGraphicsItem
//because they haven't got they own type(). //because they haven't got they own type().
@ -1230,31 +1235,31 @@ void DiagramView::setEventInterface(DVEventInterface *event_interface)
@param e Evenement decrivant la demande de menu contextuel @param e Evenement decrivant la demande de menu contextuel
*/ */
void DiagramView::contextMenuEvent(QContextMenuEvent *e) { void DiagramView::contextMenuEvent(QContextMenuEvent *e) {
if (QGraphicsItem *qgi = m_scene -> itemAt(mapToScene(e -> pos()), transform())) { if (QGraphicsItem *qgi = m_diagram -> itemAt(mapToScene(e -> pos()), transform())) {
if (!qgi -> isSelected()) m_scene -> clearSelection(); if (!qgi -> isSelected()) m_diagram -> clearSelection();
qgi -> setSelected(true); qgi -> setSelected(true);
} }
if (QETDiagramEditor *qde = diagramEditor()) { if (QETDiagramEditor *qde = diagramEditor()) {
context_menu -> clear(); m_context_menu -> clear();
if (m_scene -> selectedItems().isEmpty()) { if (m_diagram -> selectedItems().isEmpty()) {
paste_here_pos = e -> pos(); m_paste_here_pos = e -> pos();
paste_here -> setEnabled(Diagram::clipboardMayContainDiagram()); m_paste_here -> setEnabled(Diagram::clipboardMayContainDiagram());
context_menu -> addAction(paste_here); m_context_menu -> addAction(m_paste_here);
context_menu -> addSeparator(); m_context_menu -> addSeparator();
context_menu -> addAction(qde -> infos_diagram); m_context_menu -> addAction(qde -> infos_diagram);
context_menu -> addActions(qde -> m_row_column_actions_group.actions()); m_context_menu -> addActions(qde -> m_row_column_actions_group.actions());
} else { } else {
context_menu -> addAction(qde -> cut); m_context_menu -> addAction(qde -> m_cut);
context_menu -> addAction(qde -> copy); m_context_menu -> addAction(qde -> m_copy);
context_menu -> addSeparator(); m_context_menu -> addSeparator();
context_menu -> addAction(qde -> conductor_reset); m_context_menu -> addAction(qde -> m_conductor_reset);
context_menu -> addSeparator(); m_context_menu -> addSeparator();
context_menu -> addActions(qde -> m_selection_actions_group.actions()); m_context_menu -> addActions(qde -> m_selection_actions_group.actions());
} }
// affiche le menu contextuel // affiche le menu contextuel
context_menu -> popup(e -> globalPos()); m_context_menu -> popup(e -> globalPos());
} }
e -> accept(); e -> accept();
} }
@ -1280,7 +1285,7 @@ void DiagramView::mouseDoubleClickEvent(QMouseEvent *e)
{ {
if (m_event_interface && m_event_interface -> mouseDoubleClickEvent(e)) return; if (m_event_interface && m_event_interface -> mouseDoubleClickEvent(e)) return;
BorderTitleBlock &bi = m_scene -> border_and_titleblock; BorderTitleBlock &bi = m_diagram -> border_and_titleblock;
//Get the click pos on the diagram //Get the click pos on the diagram
QPointF click_pos = viewportTransform().inverted().map(e -> pos()); QPointF click_pos = viewportTransform().inverted().map(e -> pos());

View File

@ -49,15 +49,14 @@ class DiagramView : public QGraphicsView
// attributes // attributes
Diagram *m_scene; Diagram *m_diagram;
DVEventInterface *m_event_interface; DVEventInterface *m_event_interface = nullptr;
QMenu *context_menu; QMenu *m_context_menu;
QAction *paste_here; QAction *m_paste_here;
QPoint paste_here_pos; QPoint m_paste_here_pos;
QPointF rubber_band_origin; QPointF m_rubber_band_origin;
bool fresh_focus_in_; ///< Indicate the focus was freshly gained bool m_fresh_focus_in,
bool m_first_activation; m_first_activation = true;
public: public:
QString title() const; QString title() const;
void editDiagramProperties(); void editDiagramProperties();
@ -66,7 +65,7 @@ class DiagramView : public QGraphicsView
void addRow(); void addRow();
void removeRow(); void removeRow();
/// @return the diagram rendered by this view /// @return the diagram rendered by this view
Diagram *diagram() { return(m_scene); } Diagram *diagram() { return(m_diagram); }
QETDiagramEditor *diagramEditor() const; QETDiagramEditor *diagramEditor() const;
bool hasSelectedItems(); bool hasSelectedItems();
bool hasCopiableItems(); bool hasCopiableItems();

View File

@ -105,12 +105,12 @@ void ElementsMover::continueMovement(const QPointF &movement) {
} }
// Move some conductors // Move some conductors
foreach(Conductor *conductor, moved_content_.conductorsToMove) { foreach(Conductor *conductor, moved_content_.m_conductors_to_move) {
conductor -> setPos(conductor -> pos() + movement); conductor -> setPos(conductor -> pos() + movement);
} }
// Recalcul the path of other conductors // Recalcul the path of other conductors
foreach(Conductor *conductor, moved_content_.conductorsToUpdate) { foreach(Conductor *conductor, moved_content_.m_conductors_to_update) {
conductor -> updatePath(); conductor -> updatePath();
} }
} }
@ -142,7 +142,7 @@ void ElementsMover::endMovement()
moved_content_.items(dc::Elements).size() == 1 && moved_content_.items(dc::Elements).size() == 1 &&
diagram_ -> project() -> autoConductor()) diagram_ -> project() -> autoConductor())
{ {
Element *elmt = moved_content_.elements.toList().first(); Element *elmt = moved_content_.m_elements.toList().first();
int acc = elmt->AlignedFreeTerminals().size(); int acc = elmt->AlignedFreeTerminals().size();

View File

@ -19,15 +19,12 @@
#include "elementtextitem.h" #include "elementtextitem.h"
#include "diagram.h" #include "diagram.h"
#include "QPropertyUndoCommand/qpropertyundocommand.h" #include "QPropertyUndoCommand/qpropertyundocommand.h"
#include "dynamicelementtextitem.h"
/** /**
* @brief ElementTextsMover::ElementTextsMover * @brief ElementTextsMover::ElementTextsMover
*/ */
ElementTextsMover::ElementTextsMover() : ElementTextsMover::ElementTextsMover() {}
movement_running_(false),
diagram_(nullptr),
movement_driver_(nullptr)
{}
/** /**
* @brief ElementTextsMover::isReady * @brief ElementTextsMover::isReady
@ -35,7 +32,7 @@ ElementTextsMover::ElementTextsMover() :
* False if this ElementTextsMover is actually process a movement * False if this ElementTextsMover is actually process a movement
*/ */
bool ElementTextsMover::isReady() const { bool ElementTextsMover::isReady() const {
return(!movement_running_); return(!m_movement_running);
} }
/** /**
@ -47,24 +44,24 @@ bool ElementTextsMover::isReady() const {
*/ */
int ElementTextsMover::beginMovement(Diagram *diagram, QGraphicsItem *driver_item) int ElementTextsMover::beginMovement(Diagram *diagram, QGraphicsItem *driver_item)
{ {
if (movement_running_ || !diagram) return(-1); if (m_movement_running || !diagram) return(-1);
diagram_ = diagram; m_diagram = diagram;
movement_driver_ = driver_item; m_movement_driver = driver_item;
m_texts_item_H.clear(); m_texts_item_H.clear();
foreach(QGraphicsItem *item, diagram -> selectedItems()) for(QGraphicsItem *item : diagram->selectedItems())
{ {
if (item->type() == ElementTextItem::Type) if (item->type() == ElementTextItem::Type || item->type() == DynamicElementTextItem::Type)
{ {
ElementTextItem *eti = static_cast<ElementTextItem *> (item); DiagramTextItem *dti = static_cast<DiagramTextItem *> (item);
m_texts_item_H.insert(eti, eti->pos()); m_texts_item_H.insert(dti, dti->pos());
} }
} }
if (!m_texts_item_H.size()) return(-1); if (!m_texts_item_H.size()) return(-1);
movement_running_ = true; m_movement_running = true;
return(m_texts_item_H.size()); return(m_texts_item_H.size());
} }
@ -77,13 +74,14 @@ int ElementTextsMover::beginMovement(Diagram *diagram, QGraphicsItem *driver_ite
*/ */
void ElementTextsMover::continueMovement(const QPointF &movement) void ElementTextsMover::continueMovement(const QPointF &movement)
{ {
if (!movement_running_ || movement.isNull()) return; if (!m_movement_running || movement.isNull()) return;
foreach(ElementTextItem *text_item, m_texts_item_H.keys()) for(DiagramTextItem *text_item : m_texts_item_H.keys())
{ {
if (text_item == movement_driver_) continue; if (text_item == m_movement_driver)
QPointF applied_movement = text_item -> mapMovementToParent(text_item-> mapMovementFromScene(movement)); continue;
text_item -> setPos(text_item -> pos() + applied_movement); QPointF applied_movement = text_item->mapMovementToParent(text_item->mapMovementFromScene(movement));
text_item->setPos(text_item->pos() + applied_movement);
} }
} }
@ -94,31 +92,25 @@ void ElementTextsMover::continueMovement(const QPointF &movement)
void ElementTextsMover::endMovement() void ElementTextsMover::endMovement()
{ {
//No movement running, or no text to move //No movement running, or no text to move
if (!movement_running_ || m_texts_item_H.isEmpty()) return; if (!m_movement_running || m_texts_item_H.isEmpty())
return;
//Movement is null //Movement is null
ElementTextItem *eti = m_texts_item_H.keys().first(); DiagramTextItem *dti = m_texts_item_H.keys().first();
if (eti->pos() == m_texts_item_H.value(eti)) return; if (dti->pos() == m_texts_item_H.value(dti))
return;
QPropertyUndoCommand *undo = nullptr; QUndoCommand *undo = new QUndoCommand(m_texts_item_H.size() == 1 ? QString(QObject::tr("Déplacer un texte d'élément")) :
QString(QObject::tr("Déplacer %1 textes d'élément").arg(m_texts_item_H.size())));
foreach (ElementTextItem *eti, m_texts_item_H.keys()) for (DiagramTextItem *dti : m_texts_item_H.keys())
{ {
if (undo) QPropertyUndoCommand *child_undo = new QPropertyUndoCommand(dti, "pos", m_texts_item_H.value(dti), dti->pos(), undo);
{ child_undo->enableAnimation();
QPropertyUndoCommand *child_undo = new QPropertyUndoCommand(eti, "pos", m_texts_item_H.value(eti), eti->pos(), undo);
child_undo->enableAnimation();
}
else
{
undo = new QPropertyUndoCommand(eti, "pos", m_texts_item_H.value(eti), eti->pos());
undo->enableAnimation();
QString txt = m_texts_item_H.size() == 1? QString(QObject::tr("Déplacer un texte d'élément")) :
QString(QObject::tr("Déplacer %1 textes d'élément").arg(m_texts_item_H.size()));
undo->setText(txt);
}
} }
diagram_->undoStack().push(undo); m_diagram->undoStack().push(undo);
movement_running_ = false; m_movement_running = false;
} }

View File

@ -22,7 +22,7 @@
#include <QPointF> #include <QPointF>
class QGraphicsItem; class QGraphicsItem;
class ElementTextItem; class DiagramTextItem;
class Diagram; class Diagram;
/** /**
@ -38,14 +38,14 @@ class ElementTextsMover
public: public:
bool isReady() const; bool isReady() const;
int beginMovement(Diagram *, QGraphicsItem * = 0); int beginMovement(Diagram *diagram, QGraphicsItem *driver_item = nullptr);
void continueMovement(const QPointF &); void continueMovement(const QPointF &);
void endMovement(); void endMovement();
private: private:
bool movement_running_; bool m_movement_running = false;
Diagram *diagram_; Diagram *m_diagram = nullptr;
QGraphicsItem *movement_driver_; QGraphicsItem *m_movement_driver = nullptr;
QHash <ElementTextItem *, QPointF> m_texts_item_H; QHash <DiagramTextItem *, QPointF> m_texts_item_H;
}; };
#endif #endif

View File

@ -232,7 +232,7 @@ bool QET::attributeIsAReal(const QDomElement &e, QString nom_attribut, qreal *re
@return la proposition decrivant le nombre d'elements, de conducteurs et de @return la proposition decrivant le nombre d'elements, de conducteurs et de
textes textes
*/ */
QString QET::ElementsAndConductorsSentence(int elements_count, int conductors_count, int texts_count, int images_count, int shapes_count) { QString QET::ElementsAndConductorsSentence(int elements_count, int conductors_count, int texts_count, int images_count, int shapes_count, int element_text_count) {
QString text; QString text;
if (elements_count) { if (elements_count) {
text += QObject::tr( text += QObject::tr(
@ -240,61 +240,28 @@ QString QET::ElementsAndConductorsSentence(int elements_count, int conductors_co
"part of a sentence listing the content of a diagram", "part of a sentence listing the content of a diagram",
elements_count elements_count
); );
if ((conductors_count && texts_count) ||
(conductors_count && images_count) ||
(texts_count && images_count)) {
text += QObject::tr(
", ",
"separator between elements and conductors in a sentence "
"listing the content of a diagram"
);
} else if (conductors_count || texts_count || images_count) {
text += QObject::tr(
" et ",
"separator between elements and conductors (or texts) in a "
"sentence listing the content of a diagram"
);
}
} }
if (conductors_count) { if (conductors_count) {
if (!text.isEmpty()) text += ", ";
text += QObject::tr( text += QObject::tr(
"%n conducteur(s)", "%n conducteur(s)",
"part of a sentence listing the content of a diagram", "part of a sentence listing the content of a diagram",
conductors_count conductors_count
); );
if (texts_count && images_count) {
text += QObject::tr(
", ",
"separator between elements and conductors in a sentence "
"listing the content of a diagram"
);
}
else if (texts_count || images_count) {
text += QObject::tr(
" et ",
"separator between conductors and texts in a sentence listing "
"the content of a diagram"
);
}
} }
if (texts_count) { if (texts_count) {
if (!text.isEmpty()) text += ", ";
text += QObject::tr( text += QObject::tr(
"%n champ(s) de texte", "%n champ(s) de texte",
"part of a sentence listing the content of a diagram", "part of a sentence listing the content of a diagram",
texts_count texts_count
); );
if (images_count) {
text += QObject::tr(
" et ",
"separator between conductors and texts in a sentence listing "
"the content of a diagram"
);
}
} }
if (images_count) { if (images_count) {
if (!text.isEmpty()) text += ", ";
text += QObject::tr( text += QObject::tr(
"%n image(s)", "%n image(s)",
"part of a sentence listing the content of a diagram", "part of a sentence listing the content of a diagram",
@ -303,12 +270,22 @@ QString QET::ElementsAndConductorsSentence(int elements_count, int conductors_co
} }
if (shapes_count) { if (shapes_count) {
if (!text.isEmpty()) text += ", ";
text += QObject::tr( text += QObject::tr(
"%n forme(s)", "%n forme(s)",
"part of a sentence listing the content of a diagram", "part of a sentence listing the content of a diagram",
shapes_count shapes_count
); );
} }
if (element_text_count) {
if (!text.isEmpty()) text += ", ";
text += QObject::tr(
"%n texte(s) d'élément",
"part of a sentence listing the content of a diagram",
element_text_count);
}
return(text); return(text);
} }

View File

@ -143,7 +143,7 @@ namespace QET {
bool orthogonalProjection(const QPointF &, const QLineF &, QPointF * = 0); bool orthogonalProjection(const QPointF &, const QLineF &, QPointF * = 0);
bool attributeIsAnInteger(const QDomElement &, QString , int * = NULL); bool attributeIsAnInteger(const QDomElement &, QString , int * = NULL);
bool attributeIsAReal(const QDomElement &, QString , qreal * = NULL); bool attributeIsAReal(const QDomElement &, QString , qreal * = NULL);
QString ElementsAndConductorsSentence(int, int, int = 0, int = 0, int = 0); QString ElementsAndConductorsSentence(int, int, int = 0, int = 0, int = 0, int = 0);
QList<QDomElement> findInDomElement(const QDomElement &, const QString &); QList<QDomElement> findInDomElement(const QDomElement &, const QString &);
QList<QDomElement> findInDomElement(const QDomElement &, const QString &, const QString &); QList<QDomElement> findInDomElement(const QDomElement &, const QString &, const QString &);
QList<QChar> forbiddenCharacters(); QList<QChar> forbiddenCharacters();

View File

@ -42,6 +42,9 @@
#include "diagrameventaddtext.h" #include "diagrameventaddtext.h"
#include "elementscollectionwidget.h" #include "elementscollectionwidget.h"
#include "autonumberingdockwidget.h" #include "autonumberingdockwidget.h"
#include "dynamicelementtextitem.h"
#include "conductortextitem.h"
#include "elementtextitem.h"
#include <QMessageBox> #include <QMessageBox>
#include <QStandardPaths> #include <QStandardPaths>
@ -242,24 +245,24 @@ void QETDiagramEditor::setUpActions()
redo -> setStatusTip(tr("Restaure l'action annulée", "status bar tip")); redo -> setStatusTip(tr("Restaure l'action annulée", "status bar tip"));
//cut copy past action //cut copy past action
cut = new QAction(QET::Icons::EditCut, tr("Co&uper"), this); m_cut = new QAction(QET::Icons::EditCut, tr("Co&uper"), this);
copy = new QAction(QET::Icons::EditCopy, tr("Cop&ier"), this); m_copy = new QAction(QET::Icons::EditCopy, tr("Cop&ier"), this);
paste = new QAction(QET::Icons::EditPaste, tr("C&oller"), this); paste = new QAction(QET::Icons::EditPaste, tr("C&oller"), this);
cut -> setShortcut(QKeySequence::Cut); m_cut -> setShortcut(QKeySequence::Cut);
copy -> setShortcut(QKeySequence::Copy); m_copy -> setShortcut(QKeySequence::Copy);
paste -> setShortcut(QKeySequence::Paste); paste -> setShortcut(QKeySequence::Paste);
cut -> setStatusTip(tr("Transfère les éléments sélectionnés dans le presse-papier", "status bar tip")); m_cut -> setStatusTip(tr("Transfère les éléments sélectionnés dans le presse-papier", "status bar tip"));
copy -> setStatusTip(tr("Copie les éléments sélectionnés dans le presse-papier", "status bar tip")); m_copy -> setStatusTip(tr("Copie les éléments sélectionnés dans le presse-papier", "status bar tip"));
paste -> setStatusTip(tr("Place les éléments du presse-papier sur le folio", "status bar tip")); paste -> setStatusTip(tr("Place les éléments du presse-papier sur le folio", "status bar tip"));
connect(cut, SIGNAL(triggered()), this, SLOT(slot_cut())); connect(m_cut, SIGNAL(triggered()), this, SLOT(slot_cut()));
connect(copy, SIGNAL(triggered()), this, SLOT(slot_copy())); connect(m_copy, SIGNAL(triggered()), this, SLOT(slot_copy()));
connect(paste, SIGNAL(triggered()), this, SLOT(slot_paste())); connect(paste, SIGNAL(triggered()), this, SLOT(slot_paste()));
conductor_reset = new QAction(QET::Icons::ConductorSettings, tr("Réinitialiser les conducteurs"), this); m_conductor_reset = new QAction(QET::Icons::ConductorSettings, tr("Réinitialiser les conducteurs"), this);
conductor_reset -> setShortcut( QKeySequence( tr("Ctrl+K") ) ); m_conductor_reset -> setShortcut( QKeySequence( tr("Ctrl+K") ) );
m_auto_conductor = new QAction (QET::Icons::Autoconnect, tr("Création automatique de conducteur(s)","Tool tip of auto conductor"), this); m_auto_conductor = new QAction (QET::Icons::Autoconnect, tr("Création automatique de conducteur(s)","Tool tip of auto conductor"), this);
m_auto_conductor -> setStatusTip (tr("Utiliser la création automatique de conducteur(s) quand cela est possible", "Status tip of auto conductor")); m_auto_conductor -> setStatusTip (tr("Utiliser la création automatique de conducteur(s) quand cela est possible", "Status tip of auto conductor"));
@ -348,27 +351,27 @@ void QETDiagramEditor::setUpActions()
connect(&m_row_column_actions_group, &QActionGroup::triggered, this, &QETDiagramEditor::rowColumnGroupTriggered); connect(&m_row_column_actions_group, &QActionGroup::triggered, this, &QETDiagramEditor::rowColumnGroupTriggered);
//Selections Actions (related to a selected item) //Selections Actions (related to a selected item)
delete_selection = m_selection_actions_group.addAction( QET::Icons::EditDelete, tr("Supprimer") ); m_delete_selection = m_selection_actions_group.addAction( QET::Icons::EditDelete, tr("Supprimer") );
rotate_selection = m_selection_actions_group.addAction( QET::Icons::ObjectRotateRight, tr("Pivoter") ); m_rotate_selection = m_selection_actions_group.addAction( QET::Icons::ObjectRotateRight, tr("Pivoter") );
rotate_texts = m_selection_actions_group.addAction( QET::Icons::ObjectRotateRight, tr("Orienter les textes") ); m_rotate_texts = m_selection_actions_group.addAction( QET::Icons::ObjectRotateRight, tr("Orienter les textes") );
find_element = m_selection_actions_group.addAction( tr("Retrouver dans le panel") ); m_find_element = m_selection_actions_group.addAction( tr("Retrouver dans le panel") );
edit_selection = m_selection_actions_group.addAction( QET::Icons::ElementEdit, tr("Éditer l'item sélectionné") ); m_edit_selection = m_selection_actions_group.addAction( QET::Icons::ElementEdit, tr("Éditer l'item sélectionné") );
delete_selection -> setShortcut( QKeySequence::Delete); m_delete_selection -> setShortcut( QKeySequence::Delete);
rotate_selection -> setShortcut( QKeySequence( tr("Space") ) ); m_rotate_selection -> setShortcut( QKeySequence( tr("Space") ) );
rotate_texts -> setShortcut( QKeySequence( tr("Ctrl+Space") ) ); m_rotate_texts -> setShortcut( QKeySequence( tr("Ctrl+Space") ) );
edit_selection -> setShortcut( QKeySequence( tr("Ctrl+E") ) ); m_edit_selection -> setShortcut( QKeySequence( tr("Ctrl+E") ) );
delete_selection -> setStatusTip( tr("Enlève les éléments sélectionnés du folio", "status bar tip")); m_delete_selection -> setStatusTip( tr("Enlève les éléments sélectionnés du folio", "status bar tip"));
rotate_selection -> setStatusTip( tr("Pivote les éléments et textes sélectionnés", "status bar tip")); m_rotate_selection -> setStatusTip( tr("Pivote les éléments et textes sélectionnés", "status bar tip"));
rotate_texts -> setStatusTip( tr("Pivote les textes sélectionnés à un angle précis", "status bar tip")); m_rotate_texts -> setStatusTip( tr("Pivote les textes sélectionnés à un angle précis", "status bar tip"));
find_element -> setStatusTip( tr("Retrouve l'élément sélectionné dans le panel", "status bar tip")); m_find_element -> setStatusTip( tr("Retrouve l'élément sélectionné dans le panel", "status bar tip"));
delete_selection ->setData("delete_selection"); m_delete_selection ->setData("delete_selection");
rotate_selection ->setData("rotate_selection"); m_rotate_selection ->setData("rotate_selection");
rotate_texts ->setData("rotate_selected_text"); m_rotate_texts ->setData("rotate_selected_text");
find_element ->setData("find_selected_element"); m_find_element ->setData("find_selected_element");
edit_selection ->setData("edit_selected_element"); m_edit_selection ->setData("edit_selected_element");
connect(&m_selection_actions_group, &QActionGroup::triggered, this, &QETDiagramEditor::selectionGroupTriggered); connect(&m_selection_actions_group, &QActionGroup::triggered, this, &QETDiagramEditor::selectionGroupTriggered);
@ -452,7 +455,7 @@ void QETDiagramEditor::setUpActions()
export_diagram -> setStatusTip(tr("Exporte le folio courant dans un autre format", "status bar tip")); export_diagram -> setStatusTip(tr("Exporte le folio courant dans un autre format", "status bar tip"));
print -> setStatusTip(tr("Imprime un ou plusieurs folios du projet courant", "status bar tip")); print -> setStatusTip(tr("Imprime un ou plusieurs folios du projet courant", "status bar tip"));
quit_editor -> setStatusTip(tr("Ferme l'application QElectroTech", "status bar tip")); quit_editor -> setStatusTip(tr("Ferme l'application QElectroTech", "status bar tip"));
conductor_reset -> setStatusTip(tr("Recalcule les chemins des conducteurs sans tenir compte des modifications", "status bar tip")); m_conductor_reset -> setStatusTip(tr("Recalcule les chemins des conducteurs sans tenir compte des modifications", "status bar tip"));
infos_diagram -> setStatusTip(tr("Édite les propriétés du folio (dimensions, informations du cartouche, propriétés des conducteurs...)", "status bar tip")); infos_diagram -> setStatusTip(tr("Édite les propriétés du folio (dimensions, informations du cartouche, propriétés des conducteurs...)", "status bar tip"));
windowed_view_mode -> setStatusTip(tr("Présente les différents projets ouverts dans des sous-fenêtres", "status bar tip")); windowed_view_mode -> setStatusTip(tr("Présente les différents projets ouverts dans des sous-fenêtres", "status bar tip"));
@ -503,7 +506,7 @@ void QETDiagramEditor::setUpActions()
connect(cascade_window, SIGNAL(triggered()), &workspace, SLOT(cascadeSubWindows()) ); connect(cascade_window, SIGNAL(triggered()), &workspace, SLOT(cascadeSubWindows()) );
connect(next_window, SIGNAL(triggered()), &workspace, SLOT(activateNextSubWindow()) ); connect(next_window, SIGNAL(triggered()), &workspace, SLOT(activateNextSubWindow()) );
connect(prev_window, SIGNAL(triggered()), &workspace, SLOT(activatePreviousSubWindow()) ); connect(prev_window, SIGNAL(triggered()), &workspace, SLOT(activatePreviousSubWindow()) );
connect(conductor_reset, SIGNAL(triggered()), this, SLOT(slot_resetConductors()) ); connect(m_conductor_reset, SIGNAL(triggered()), this, SLOT(slot_resetConductors()) );
connect(infos_diagram, SIGNAL(triggered()), this, SLOT(editCurrentDiagramProperties())); connect(infos_diagram, SIGNAL(triggered()), this, SLOT(editCurrentDiagramProperties()));
} }
@ -526,12 +529,12 @@ void QETDiagramEditor::setUpToolBar() {
main_bar -> addAction(undo); main_bar -> addAction(undo);
main_bar -> addAction(redo); main_bar -> addAction(redo);
main_bar -> addSeparator(); main_bar -> addSeparator();
main_bar -> addAction(cut); main_bar -> addAction(m_cut);
main_bar -> addAction(copy); main_bar -> addAction(m_copy);
main_bar -> addAction(paste); main_bar -> addAction(paste);
main_bar -> addSeparator(); main_bar -> addSeparator();
main_bar -> addAction(delete_selection); main_bar -> addAction(m_delete_selection);
main_bar -> addAction(rotate_selection); main_bar -> addAction(m_rotate_selection);
// Modes selection / visualisation et zoom // Modes selection / visualisation et zoom
view_bar -> addAction(mode_selection); view_bar -> addAction(mode_selection);
@ -543,7 +546,7 @@ void QETDiagramEditor::setUpToolBar() {
view_bar -> addActions(m_zoom_action_toolBar); view_bar -> addActions(m_zoom_action_toolBar);
diagram_bar -> addAction (infos_diagram); diagram_bar -> addAction (infos_diagram);
diagram_bar -> addAction (conductor_reset); diagram_bar -> addAction (m_conductor_reset);
diagram_bar -> addAction (m_auto_conductor); diagram_bar -> addAction (m_auto_conductor);
m_add_item_toolBar = new QToolBar(tr("Ajouter"), this); m_add_item_toolBar = new QToolBar(tr("Ajouter"), this);
@ -592,15 +595,15 @@ void QETDiagramEditor::setUpMenu() {
menu_edition -> addAction(undo); menu_edition -> addAction(undo);
menu_edition -> addAction(redo); menu_edition -> addAction(redo);
menu_edition -> addSeparator(); menu_edition -> addSeparator();
menu_edition -> addAction(cut); menu_edition -> addAction(m_cut);
menu_edition -> addAction(copy); menu_edition -> addAction(m_copy);
menu_edition -> addAction(paste); menu_edition -> addAction(paste);
menu_edition -> addSeparator(); menu_edition -> addSeparator();
menu_edition -> addActions(m_select_actions_group.actions()); menu_edition -> addActions(m_select_actions_group.actions());
menu_edition -> addSeparator(); menu_edition -> addSeparator();
menu_edition -> addActions(m_selection_actions_group.actions()); menu_edition -> addActions(m_selection_actions_group.actions());
menu_edition -> addSeparator(); menu_edition -> addSeparator();
menu_edition -> addAction(conductor_reset); menu_edition -> addAction(m_conductor_reset);
menu_edition -> addSeparator(); menu_edition -> addSeparator();
menu_edition -> addAction(infos_diagram); menu_edition -> addAction(infos_diagram);
menu_edition -> addActions(m_row_column_actions_group.actions()); menu_edition -> addActions(m_row_column_actions_group.actions());
@ -1039,7 +1042,7 @@ Element *QETDiagramEditor::currentElement() const {
DiagramView *dv = currentDiagram(); DiagramView *dv = currentDiagram();
if (!dv) return(0); if (!dv) return(0);
QList<Element *> selected_elements = dv -> diagram() -> selectedContent().elements.toList(); QList<Element *> selected_elements = dv -> diagram() -> selectedContent().m_elements.toList();
if (selected_elements.count() != 1) return(0); if (selected_elements.count() != 1) return(0);
return(selected_elements.first()); return(selected_elements.first());
@ -1383,76 +1386,90 @@ void QETDiagramEditor::slot_updateUndoStack()
* Manage the actions who need some conditions to be enable or not. * Manage the actions who need some conditions to be enable or not.
* This method does nothing if there is no project opened * This method does nothing if there is no project opened
*/ */
void QETDiagramEditor::slot_updateComplexActions() { void QETDiagramEditor::slot_updateComplexActions()
{
DiagramView *dv = currentDiagram(); DiagramView *dv = currentDiagram();
bool editable_diagram = (dv && !dv -> diagram() -> isReadOnly()); if(!dv)
{
QList <QAction *> action_list;
action_list << m_conductor_reset << m_find_element << m_cut << m_copy << m_delete_selection << m_rotate_selection << m_edit_selection;
for(QAction *action : action_list)
action->setEnabled(false);
return;
}
Diagram *diagram_ = dv->diagram();
bool ro = diagram_->isReadOnly();
//Number of selected conductors //Number of selected conductors
int selected_conductors_count = dv ? dv -> diagram() -> selectedConductors().count() : 0; int selected_conductors_count = diagram_->selectedConductors().count();
conductor_reset -> setEnabled(editable_diagram && selected_conductors_count); m_conductor_reset->setEnabled(!ro && selected_conductors_count);
// number of selected elements // number of selected elements
int selected_elements_count = dv ? dv -> diagram() -> selectedContent().count(DiagramContent::Elements) : 0; int selected_elements_count = diagram_->selectedContent().count(DiagramContent::Elements);
find_element -> setEnabled(selected_elements_count == 1); m_find_element->setEnabled(selected_elements_count == 1);
//Action that need items (elements, conductors, texts...) selected, to be enabled //Action that need items (elements, conductors, texts...) selected, to be enabled
bool copiable_items = dv ? (dv -> hasCopiableItems()) : false; bool copiable_items = dv->hasCopiableItems();
bool deletable_items = dv ? (dv -> hasDeletableItems()) : false; bool deletable_items = dv->hasDeletableItems();
cut -> setEnabled(editable_diagram && copiable_items); m_cut -> setEnabled(!ro && copiable_items);
copy -> setEnabled(copiable_items); m_copy -> setEnabled(copiable_items);
delete_selection -> setEnabled(editable_diagram && deletable_items); m_delete_selection -> setEnabled(!ro && deletable_items);
rotate_selection -> setEnabled(editable_diagram && dv -> diagram() -> canRotateSelection()); m_rotate_selection -> setEnabled(!ro && diagram_->canRotateSelection());
//Action that need selected texts //Action that need selected texts
int selected_texts = dv ? (dv -> diagram() -> selectedTexts().count()) : 0; int selected_texts = diagram_->selectedTexts().count();
int selected_conductor_texts = dv ? (dv -> diagram() -> selectedConductorTexts().count()) : 0; int selected_conductor_texts = 0; for(DiagramTextItem *dti : diagram_->selectedTexts()) {if(dti->type() == ConductorTextItem::Type) selected_conductor_texts++;}
int selected_element_texts = dv ? (dv -> diagram() -> selectedElementTexts().count()) : 0; int selected_element_texts = 0; for(DiagramTextItem *dti : diagram_->selectedTexts()) {if(dti->type() == ElementTextItem::Type) selected_element_texts++;}
rotate_texts -> setEnabled(editable_diagram && selected_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);
// actions need only one editable item // actions need only one editable item
int selected_image = dv ? dv -> diagram() -> selectedContent().count(DiagramContent::Images) : 0; int selected_image = diagram_-> selectedContent().count(DiagramContent::Images);
int selected_shape = dv ? dv -> diagram() -> selectedContent().count(DiagramContent::Shapes) : 0; int selected_shape = diagram_-> selectedContent().count(DiagramContent::Shapes);
int selected_editable = selected_elements_count + int selected_editable = selected_elements_count +
(selected_texts - selected_conductor_texts - selected_element_texts) + (selected_texts - selected_conductor_texts - selected_element_texts - selected_dynamic_elmt_text) +
selected_image + selected_image +
selected_shape + selected_shape +
selected_conductors_count; selected_conductors_count;
if (selected_editable == 1) if (selected_editable == 1)
{ {
edit_selection -> setEnabled(true); m_edit_selection -> setEnabled(true);
//edit element //edit element
if (selected_elements_count) if (selected_elements_count)
{ {
edit_selection -> setText(tr("Éditer l'élement", "edit element")); m_edit_selection -> setText(tr("Éditer l'élement", "edit element"));
edit_selection -> setIcon(QET::Icons::ElementEdit); m_edit_selection -> setIcon(QET::Icons::ElementEdit);
} }
//edit text field //edit text field
else if (selected_texts) else if (selected_texts)
{ {
edit_selection -> setText(tr("Éditer le champ de texte", "edit text field")); m_edit_selection -> setText(tr("Éditer le champ de texte", "edit text field"));
edit_selection -> setIcon(QET::Icons::EditText); m_edit_selection -> setIcon(QET::Icons::EditText);
} }
//edit image //edit image
else if (selected_image) else if (selected_image)
{ {
edit_selection -> setText(tr("Éditer l'image", "edit image")); m_edit_selection -> setText(tr("Éditer l'image", "edit image"));
edit_selection -> setIcon(QET::Icons::resize_image); m_edit_selection -> setIcon(QET::Icons::resize_image);
} }
//edit conductor //edit conductor
else if (selected_conductors_count) else if (selected_conductors_count)
{ {
edit_selection -> setText(tr("Éditer le conducteur", "edit conductor")); m_edit_selection -> setText(tr("Éditer le conducteur", "edit conductor"));
edit_selection -> setIcon(QET::Icons::ElementEdit); m_edit_selection -> setIcon(QET::Icons::ElementEdit);
} }
} }
//not an editable item //not an editable item
else else
{ {
edit_selection -> setText(tr("Éditer l'objet sélectionné", "edit selected item")); m_edit_selection -> setText(tr("Éditer l'objet sélectionné", "edit selected item"));
edit_selection -> setIcon(QET::Icons::ElementEdit); m_edit_selection -> setIcon(QET::Icons::ElementEdit);
edit_selection -> setEnabled(false); m_edit_selection -> setEnabled(false);
} }
} }

View File

@ -174,9 +174,9 @@ class QETDiagramEditor : public QETMainWindow {
QAction *redo; ///< Redo the latest cancelled operation QAction *redo; ///< Redo the latest cancelled operation
public: public:
QAction *infos_diagram; ///< Show a dialog to edit diagram properties QAction *infos_diagram; ///< Show a dialog to edit diagram properties
QAction *conductor_reset; ///< Reset paths of selected conductors QAction *m_conductor_reset; ///< Reset paths of selected conductors
QAction *cut; ///< Cut selection to clipboard QAction *m_cut; ///< Cut selection to clipboard
QAction *copy; ///< Copy selection to clipboard QAction *m_copy; ///< Copy selection to clipboard
private: private:
QAction *paste; ///< Paste clipboard content on the current diagram QAction *paste; ///< Paste clipboard content on the current diagram
QAction *m_auto_conductor; ///< Enable/Disable the use of auto conductor QAction *m_auto_conductor; ///< Enable/Disable the use of auto conductor
@ -194,7 +194,7 @@ class QETDiagramEditor : public QETMainWindow {
QAction *cascade_window; ///< Show MDI subwindows as cascade QAction *cascade_window; ///< Show MDI subwindows as cascade
QAction *prev_window; ///< Switch to the previous document QAction *prev_window; ///< Switch to the previous document
QAction *next_window; ///< Switch to the next document QAction *next_window; ///< Switch to the next document
QAction *edit_selection; ///< To edit selected item QAction *m_edit_selection; ///< To edit selected item
QActionGroup m_add_item_actions_group; ///Action related to adding (add text image shape...) QActionGroup m_add_item_actions_group; ///Action related to adding (add text image shape...)
@ -207,10 +207,10 @@ class QETDiagramEditor : public QETMainWindow {
QActionGroup m_row_column_actions_group; /// Action related to add/remove rows/column in diagram QActionGroup m_row_column_actions_group; /// Action related to add/remove rows/column in diagram
QActionGroup m_selection_actions_group; ///Action related to edit a selected item QActionGroup m_selection_actions_group; ///Action related to edit a selected item
private: private:
QAction *delete_selection; ///< Delete selection QAction *m_delete_selection; ///< Delete selection
QAction *rotate_selection; ///< Rotate selected elements and text items by 90 degrees QAction *m_rotate_selection; ///< Rotate selected elements and text items by 90 degrees
QAction *rotate_texts; ///< Direct selected text items to a specific angle QAction *m_rotate_texts; ///< Direct selected text items to a specific angle
QAction *find_element; ///< Find the selected element in the panel QAction *m_find_element; ///< Find the selected element in the panel
QActionGroup m_file_actions_group; ///Actions related to file (open, close, save...) QActionGroup m_file_actions_group; ///Actions related to file (open, close, save...)
QAction *close_file; ///< Close current project file QAction *close_file; ///< Close current project file

View File

@ -27,10 +27,7 @@
*/ */
DiagramTextItem::DiagramTextItem(QGraphicsItem *parent) : DiagramTextItem::DiagramTextItem(QGraphicsItem *parent) :
QGraphicsTextItem(parent), QGraphicsTextItem(parent),
m_mouse_hover(false), m_rotation_angle(0.0)
previous_text_(),
rotation_angle_(0.0),
m_first_move (true)
{ build(); } { build(); }
/** /**
@ -41,8 +38,8 @@ DiagramTextItem::DiagramTextItem(QGraphicsItem *parent) :
DiagramTextItem::DiagramTextItem(const QString &text, QGraphicsItem *parent) : DiagramTextItem::DiagramTextItem(const QString &text, QGraphicsItem *parent) :
QGraphicsTextItem(text, parent), QGraphicsTextItem(text, parent),
m_mouse_hover(false), m_mouse_hover(false),
previous_text_(text), m_previous_html_text(text),
rotation_angle_(0.0) m_rotation_angle(0.0)
{ build(); } { build(); }
/** /**
@ -83,7 +80,7 @@ QDomElement DiagramTextItem::toXml(QDomDocument &) const {
@return l'angle de rotation actuel de ce texte @return l'angle de rotation actuel de ce texte
*/ */
qreal DiagramTextItem::rotationAngle() const { qreal DiagramTextItem::rotationAngle() const {
return(rotation_angle_); return(m_rotation_angle);
} }
/** /**
@ -94,8 +91,8 @@ qreal DiagramTextItem::rotationAngle() const {
*/ */
void DiagramTextItem::setRotationAngle(const qreal &rotation) { void DiagramTextItem::setRotationAngle(const qreal &rotation) {
qreal applied_rotation = QET::correctAngle(rotation); qreal applied_rotation = QET::correctAngle(rotation);
applyRotation(applied_rotation - rotation_angle_); applyRotation(applied_rotation - m_rotation_angle);
rotation_angle_ = applied_rotation; m_rotation_angle = applied_rotation;
} }
/** /**
@ -106,7 +103,7 @@ void DiagramTextItem::setRotationAngle(const qreal &rotation) {
*/ */
void DiagramTextItem::rotateBy(const qreal &added_rotation) { void DiagramTextItem::rotateBy(const qreal &added_rotation) {
qreal applied_added_rotation = QET::correctAngle(added_rotation); qreal applied_added_rotation = QET::correctAngle(added_rotation);
rotation_angle_ = QET::correctAngle(rotation_angle_ + applied_added_rotation); m_rotation_angle = QET::correctAngle(m_rotation_angle + applied_added_rotation);
applyRotation(applied_added_rotation); applyRotation(applied_added_rotation);
} }
@ -186,8 +183,25 @@ QPointF DiagramTextItem::mapMovementFromParent(const QPointF &movement) const {
return(local_movement_point - local_origin); return(local_movement_point - local_origin);
} }
void DiagramTextItem::setFontSize(int &s) { void DiagramTextItem::setFontSize(int s)
setFont(QETApp::diagramTextsFont(s)); {
setFont(QETApp::diagramTextsFont(s));
emit fontSizeChanged(s);
}
int DiagramTextItem::fontSize() const
{
return font().pointSize();
}
void DiagramTextItem::setColor(QColor color)
{
setDefaultTextColor(color);
emit colorChanged(color);
}
QColor DiagramTextItem::color() const {
return defaultTextColor();
} }
/** /**
@ -226,42 +240,39 @@ void DiagramTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *o
} }
/** /**
Gere la prise de focus du champ de texte * @brief DiagramTextItem::focusInEvent
@param e Objet decrivant la prise de focus * @param e
*/ */
void DiagramTextItem::focusInEvent(QFocusEvent *e) { void DiagramTextItem::focusInEvent(QFocusEvent *event)
QGraphicsTextItem::focusInEvent(e); {
QGraphicsTextItem::focusInEvent(event);
// empeche le deplacement du texte pendant son edition
setFlag(QGraphicsItem::ItemIsMovable, false); setFlag(QGraphicsItem::ItemIsMovable, false);
// memorise le texte avant que l'utilisateur n'y touche m_previous_html_text = toHtml();
previous_text_ = toHtml(); m_previous_text = toPlainText();
// cela permettra de determiner si l'utilisateur a modifie le texte a la fin de l'edition
} }
/** /**
Gere la perte de focus du champ de texte * @brief DiagramTextItem::focusOutEvent
@param e Objet decrivant la perte de focus * @param event
*/ */
void DiagramTextItem::focusOutEvent(QFocusEvent *e) { void DiagramTextItem::focusOutEvent(QFocusEvent *event)
QGraphicsTextItem::focusOutEvent(e); {
QGraphicsTextItem::focusOutEvent(event);
// signale la modification du texte si besoin if (toHtml() != m_previous_html_text)
if (toPlainText() != previous_text_) { emit(diagramTextChanged(this, m_previous_html_text, toHtml()));
emit(diagramTextChanged(this, previous_text_, toHtml())); if(toPlainText() != m_previous_text)
previous_text_ = toHtml(); emit textEdited(m_previous_text, toPlainText());
}
// deselectionne le texte
QTextCursor cursor = textCursor(); QTextCursor cursor = textCursor();
cursor.clearSelection(); cursor.clearSelection();
setTextCursor(cursor); setTextCursor(cursor);
// hack a la con pour etre re-entrant //Bad hack to be re-entrant
setTextInteractionFlags(Qt::NoTextInteraction); setTextInteractionFlags(Qt::NoTextInteraction);
// autorise de nouveau le deplacement du texte
setFlag(QGraphicsItem::ItemIsMovable, true); setFlag(QGraphicsItem::ItemIsMovable, true);
setFlag(QGraphicsTextItem::ItemIsFocusable, false); setFlag(QGraphicsTextItem::ItemIsFocusable, false);
} }
@ -271,7 +282,7 @@ void DiagramTextItem::focusOutEvent(QFocusEvent *e) {
@param event un QGraphicsSceneMouseEvent decrivant le double-clic @param event un QGraphicsSceneMouseEvent decrivant le double-clic
*/ */
void DiagramTextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) { void DiagramTextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) {
if (!(textInteractionFlags() & Qt::TextEditable) && !no_editable) { if (!(textInteractionFlags() & Qt::TextEditable) && !m_no_editable) {
// rend le champ de texte editable // rend le champ de texte editable
setTextInteractionFlags(Qt::TextEditorInteraction); setTextInteractionFlags(Qt::TextEditorInteraction);

View File

@ -33,6 +33,13 @@ class DiagramTextItem : public QGraphicsTextItem
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(int fontSize READ fontSize WRITE setFontSize NOTIFY fontSizeChanged)
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
signals:
void fontSizeChanged(int size);
void colorChanged(QColor color);
public: public:
DiagramTextItem(QGraphicsItem * = 0); DiagramTextItem(QGraphicsItem * = 0);
DiagramTextItem(const QString &, QGraphicsItem * = 0); DiagramTextItem(const QString &, QGraphicsItem * = 0);
@ -42,7 +49,7 @@ class DiagramTextItem : public QGraphicsTextItem
public: public:
enum { Type = UserType + 1004 }; enum { Type = UserType + 1004 };
virtual int type() const { return Type; } virtual int type() const override { return Type; }
Diagram *diagram() const; Diagram *diagram() const;
virtual void fromXml(const QDomElement &) = 0; virtual void fromXml(const QDomElement &) = 0;
@ -57,35 +64,43 @@ class DiagramTextItem : public QGraphicsTextItem
QPointF mapMovementToParent (const QPointF &) const; QPointF mapMovementToParent (const QPointF &) const;
QPointF mapMovementFromParent (const QPointF &) const; QPointF mapMovementFromParent (const QPointF &) const;
void setFontSize(int &s); void setFontSize(int s);
void setNoEditable(bool e = true) {no_editable = e;} int fontSize()const;
void setColor(QColor color);
QColor color() const;
void setNoEditable(bool e = true) {m_no_editable = e;}
protected: protected:
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *); virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) override;
virtual void focusInEvent(QFocusEvent *); virtual void focusInEvent(QFocusEvent *) override;
virtual void focusOutEvent(QFocusEvent *); virtual void focusOutEvent(QFocusEvent *) override;
virtual void mouseDoubleClickEvent (QGraphicsSceneMouseEvent *event); virtual void mouseDoubleClickEvent (QGraphicsSceneMouseEvent *event) override;
virtual void mousePressEvent (QGraphicsSceneMouseEvent *event); virtual void mousePressEvent (QGraphicsSceneMouseEvent *event) override;
virtual void mouseMoveEvent (QGraphicsSceneMouseEvent *event); virtual void mouseMoveEvent (QGraphicsSceneMouseEvent *event) override;
virtual void mouseReleaseEvent (QGraphicsSceneMouseEvent *event); virtual void mouseReleaseEvent (QGraphicsSceneMouseEvent *event) override;
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *); virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *) override;
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *); virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *) override;
virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *); virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *) override;
virtual void applyRotation(const qreal &); virtual void applyRotation(const qreal &);
signals: signals:
/// signal emitted after text was changed
void diagramTextChanged(DiagramTextItem *, const QString &, const QString &); void diagramTextChanged(DiagramTextItem *, const QString &, const QString &);
void textEdited(const QString &old_str, const QString &new_str);
protected: protected:
bool m_mouse_hover; bool m_mouse_hover = false,
QString previous_text_; m_first_move = true,
qreal rotation_angle_; m_no_editable;
bool no_editable;
bool m_first_move; QString m_previous_html_text,
m_previous_text;
qreal m_rotation_angle;
QPointF m_mouse_to_origin_movement; QPointF m_mouse_to_origin_movement;
}; };
#endif #endif

View File

@ -0,0 +1,255 @@
/*
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 "dynamicelementtextitem.h"
#include "qet.h"
#include "element.h"
#include "qetapp.h"
#include "diagram.h"
#include "QPropertyUndoCommand/qpropertyundocommand.h"
#include <QDomDocument>
#include <QDomElement>
#include <QGraphicsSceneMouseEvent>
/**
* @brief DynamicElementTextItem::DynamicElementTextItem
* Constructor
* @param parent_element
*/
DynamicElementTextItem::DynamicElementTextItem(Element *parent_element) :
m_parent_element(parent_element),
m_uuid(QUuid::createUuid())
{
setFont(QETApp::diagramTextsFont(9));
setText(tr("Texte"));
setParentItem(parent_element);
connect(this, &DynamicElementTextItem::textEdited, [this](const QString &old_str, const QString &new_str)
{
if(this->m_parent_element && this->m_parent_element->diagram())
{
QUndoCommand *undo = new QPropertyUndoCommand(this, "text", old_str, new_str);
undo->setText(tr("Éditer un texte d'élément"));
this->m_parent_element->diagram()->undoStack().push(undo);
}
});
}
DynamicElementTextItem::~DynamicElementTextItem()
{}
/**
* @brief DynamicElementTextItem::toXml
* Export this text to xml
* @param dom_doc
* @return
*/
QDomElement DynamicElementTextItem::toXml(QDomDocument &dom_doc) const
{
QDomElement root_element = dom_doc.createElement(xmlTaggName());
root_element.setAttribute("x", QString::number(pos().x()));
root_element.setAttribute("y", QString::number(pos().y()));
root_element.setAttribute("rotation", QString::number(QET::correctAngle(rotation())));
root_element.setAttribute("font_size", font().pointSize());
root_element.setAttribute("uuid", m_uuid.toString());
QMetaEnum me = metaObject()->enumerator(metaObject()->indexOfEnumerator("TextFrom"));
root_element.setAttribute("text_from", me.valueToKey(m_text_from));
QDomElement dom_text = dom_doc.createElement("text");
dom_text.appendChild(dom_doc.createTextNode(toPlainText()));
root_element.appendChild(dom_text);
//tagg
if (!m_tagg.isEmpty())
{
QDomElement dom_tagg = dom_doc.createElement("tagg");
dom_tagg.appendChild(dom_doc.createTextNode(m_tagg));
root_element.appendChild(dom_tagg);
}
//Color
if(color() != QColor(Qt::black))
{
QDomElement dom_color = dom_doc.createElement("color");
dom_color.appendChild(dom_doc.createTextNode(color().name()));
root_element.appendChild(dom_color);
}
return root_element;
}
/**
* @brief DynamicElementTextItem::fromXml
* Import this text from xml
* @param dom_elmt
*/
void DynamicElementTextItem::fromXml(const QDomElement &dom_elmt)
{
if (dom_elmt.tagName() != xmlTaggName()) {
qDebug() << "DynamicElementTextItem::fromXml : Wrong tagg name";
return;
}
QGraphicsTextItem::setPos(dom_elmt.attribute("x", QString::number(0)).toDouble(),
dom_elmt.attribute("y", QString::number(0)).toDouble());
QGraphicsTextItem::setRotation(dom_elmt.attribute("rotation", QString::number(0)).toDouble());
setFont(QETApp::diagramTextsFont(dom_elmt.attribute("font_size", QString::number(9)).toInt()));
m_uuid = QUuid(dom_elmt.attribute("uuid", QUuid::createUuid().toString()));
QMetaEnum me = metaObject()->enumerator(metaObject()->indexOfEnumerator("TextFrom"));
m_text_from = DynamicElementTextItem::TextFrom(me.keyToValue(dom_elmt.attribute("text_from").toStdString().data()));
setNoEditable(m_text_from == ElementInfo? true : false);
//Text
QDomElement dom_text = dom_elmt.firstChildElement("text");
if (!dom_text.isNull())
setPlainText(dom_text.text());
//tagg
QDomElement dom_tagg = dom_elmt.firstChildElement("tagg");
if (!dom_tagg.isNull())
m_tagg = dom_tagg.text();
//Color
QDomElement dom_color = dom_elmt.firstChildElement("color");
if(!dom_color.isNull())
setColor(QColor(dom_color.text()));
}
/**
* @brief DynamicElementTextItem::ParentElement
* @return a pointer to the parent element. Note the pointer can be null.
*/
Element *DynamicElementTextItem::ParentElement() const {
return m_parent_element;
}
/**
* @brief DynamicElementTextItem::textFrom
* @return what the final text is created from.
*/
DynamicElementTextItem::TextFrom DynamicElementTextItem::textFrom() const {
return m_text_from;
}
/**
* @brief DynamicElementTextItem::setTextFrom
* Set the final text is created from.
* @param text_from
*/
void DynamicElementTextItem::setTextFrom(DynamicElementTextItem::TextFrom text_from)
{
m_text_from = text_from;
setNoEditable(m_text_from == ElementInfo? true : false);
emit TextFromChanged(m_text_from);
}
/**
* @brief DynamicElementTextItem::tagg
* @return the tagg of this text
*/
QString DynamicElementTextItem::tagg() const {
return m_tagg;
}
/**
* @brief DynamicElementTextItem::setTagg
* set the taggof this text
* @param tagg
*/
void DynamicElementTextItem::setTagg(const QString &tagg)
{
m_tagg = tagg;
emit taggChanged(m_tagg);
}
/**
* @brief DynamicElementTextItem::text
* @return the text of this text
*/
QString DynamicElementTextItem::text() const {
return m_text;
}
/**
* @brief DynamicElementTextItem::setText
* Set the text of this text
* @param formula
*/
void DynamicElementTextItem::setText(const QString &text)
{
m_text = text;
setPlainText(m_text);
emit textChanged(m_text);
}
/**
* @brief DynamicElementTextItem::mouseMoveEvent
* @param event
*/
void DynamicElementTextItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
if(event->buttons() & Qt::LeftButton)
{
QPointF old_pos = pos(); //The old pos
QPointF movement = event->pos() - event->buttonDownPos(Qt::LeftButton); //The movement since the button down pos
QPointF new_pos = pos() + mapMovementToParent(movement); //The new pos with this event
event->modifiers() == Qt::ControlModifier ? setPos(new_pos) : setPos(Diagram::snapToGrid(new_pos));
if(m_parent_element && m_parent_element->diagram())
{
Diagram *diagram = m_parent_element->diagram();
if(m_first_move)
{
if(diagram->beginMoveElementTexts(this) == 1)
m_parent_element->setHighlighted(true);
}
//Because setPos() can be snaped to grid or not, we calcule the real movement
QPointF effective_movement = pos() - old_pos;
QPointF scene_effective_movement = mapMovementToScene(mapMovementFromParent(effective_movement));
diagram->continueMoveElementTexts(scene_effective_movement);
}
}
else
event->ignore();
if(m_first_move)
m_first_move = false;
}
/**
* @brief DynamicElementTextItem::mouseReleaseEvent
* @param event
*/
void DynamicElementTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
if (m_parent_element)
m_parent_element->setHighlighted(false);
if(m_parent_element && m_parent_element->diagram())
m_parent_element->diagram()->endMoveElementTexts();
if(!(event->modifiers() & Qt::ControlModifier))
QGraphicsTextItem::mouseReleaseEvent(event);
}

View File

@ -0,0 +1,87 @@
/*
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 DYNAMICELEMENTTEXTITEM_H
#define DYNAMICELEMENTTEXTITEM_H
#include "diagramtextitem.h"
#include <QUuid>
class Element;
/**
* @brief The DynamicElementTextItem class
* This class provide a simple text field of element who can be added or removed directly from the diagram editor.
* This text is created to compensate a big lack of the ElementTextItem : ElementTextItem can't be added or removed directly in the diagram editor
*
*/
class DynamicElementTextItem : public DiagramTextItem
{
Q_OBJECT
Q_PROPERTY(QString tagg READ tagg WRITE setTagg NOTIFY taggChanged)
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
Q_PROPERTY(TextFrom textFrom READ textFrom WRITE setTextFrom NOTIFY TextFromChanged)
public:
Q_ENUMS(TextFrom)
enum TextFrom {
UserText,
ElementInfo
};
enum {Type = UserType + 1010};
virtual int type() const override {return Type;}
signals:
void taggChanged(QString tagg);
void textChanged(QString text);
void TextFromChanged(DynamicElementTextItem::TextFrom text_from);
public:
DynamicElementTextItem(Element *parent_element);
virtual ~DynamicElementTextItem() override;
private:
DynamicElementTextItem(const DynamicElementTextItem &);
public:
virtual QDomElement toXml(QDomDocument &dom_doc) const override;
virtual void fromXml(const QDomElement &dom_elmt) override;
Element *ParentElement() const;
DynamicElementTextItem::TextFrom textFrom() const;
void setTextFrom (DynamicElementTextItem::TextFrom text_from);
QString tagg() const;
void setTagg(const QString &tagg);
QString text() const;
void setText(const QString &text);
static QString xmlTaggName() {return QString("dynamic_elmt_text");}
protected:
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
private:
Element *m_parent_element = nullptr;
QString m_tagg,
m_text,
m_elmt_info_name;
DynamicElementTextItem::TextFrom m_text_from = UserText;
QUuid m_uuid;
};
#endif // DYNAMICELEMENTTEXTITEM_H

View File

@ -29,6 +29,7 @@
#include "numerotationcontextcommands.h" #include "numerotationcontextcommands.h"
#include "diagramcontext.h" #include "diagramcontext.h"
#include "changeelementinformationcommand.h" #include "changeelementinformationcommand.h"
#include "dynamicelementtextitem.h"
class ElementXmlRetroCompatibility class ElementXmlRetroCompatibility
{ {
@ -77,7 +78,9 @@ Element::Element(QGraphicsItem *parent) :
/** /**
Destructeur Destructeur
*/ */
Element::~Element() { Element::~Element()
{
qDeleteAll(m_dynamic_text_list);
} }
void Element::editProperty() void Element::editProperty()
@ -529,6 +532,15 @@ bool Element::fromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr, bool
} else { } else {
applyRotation(90*read_ori); applyRotation(90*read_ori);
} }
//Dynamic texts
for (QDomElement qde : QET::findInDomElement(e, "dynamic_texts", DynamicElementTextItem::xmlTaggName()))
{
DynamicElementTextItem *deti = new DynamicElementTextItem(this);
addDynamicTextItem(deti);
deti->fromXml(qde);
}
return(true); return(true);
} }
@ -608,14 +620,59 @@ QDomElement Element::toXml(QDomDocument &document, QHash<Terminal *, int> &table
element.appendChild(links_uuids); element.appendChild(links_uuids);
} }
//save information of this element //save information of this element
if (! m_element_informations.keys().isEmpty()) { if (! m_element_informations.keys().isEmpty()) {
QDomElement infos = document.createElement("elementInformations"); QDomElement infos = document.createElement("elementInformations");
m_element_informations.toXml(infos, "elementInformation"); m_element_informations.toXml(infos, "elementInformation");
element.appendChild(infos); element.appendChild(infos);
} }
return(element); //Dynamic texts
QDomElement dyn_text = document.createElement("dynamic_texts");
for (DynamicElementTextItem *deti : m_dynamic_text_list)
dyn_text.appendChild(deti->toXml(document));
element.appendChild(dyn_text);
return(element);
}
/**
* @brief Element::addDynamiqueTextItem
* Add @deti as a dynamic text item of this element
* If @deti is null, a new DynamicElementTextItem is created and added to this element.
* @param deti
*/
void Element::addDynamicTextItem(DynamicElementTextItem *deti)
{
if (deti && !m_dynamic_text_list.contains(deti))
{
m_dynamic_text_list.append(deti);
}
else
{
DynamicElementTextItem *text = new DynamicElementTextItem(this);
m_dynamic_text_list.append(text);
}
}
/**
* @brief Element::removeDynamicTextItem
* Remove @deti as dynamic text item of this element.
* The parent item of deti stay this item.
* @param deti
*/
void Element::removeDynamicTextItem(DynamicElementTextItem *deti)
{
if (m_dynamic_text_list.contains(deti))
m_dynamic_text_list.removeOne(deti);
}
/**
* @brief Element::dynamicTextItems
* @return all dynamic text items of this element
*/
QList<DynamicElementTextItem *> Element::dynamicTextItems() const {
return m_dynamic_text_list;
} }
/** /**

View File

@ -30,6 +30,7 @@ class Terminal;
class Conductor; class Conductor;
class NumerotationContext; class NumerotationContext;
class DiagramTextItem; class DiagramTextItem;
class DynamicElementTextItem;
/** /**
This is the base class for electrical elements. This is the base class for electrical elements.
@ -158,9 +159,6 @@ class Element : public QetGraphicsItem
bool m_freeze_label = false; bool m_freeze_label = false;
QString m_F_str; QString m_F_str;
/**
Draw this element
*/
public: public:
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *) = 0; virtual void paint(QPainter *, const QStyleOptionGraphicsItem *) = 0;
/// @return This element type ID /// @return This element type ID
@ -177,25 +175,29 @@ class Element : public QetGraphicsItem
QSize size() const; QSize size() const;
QPixmap pixmap(); QPixmap pixmap();
// methods related to the hotspot // methods related to the hotspot
QPoint setHotspot(QPoint); QPoint setHotspot(QPoint);
QPoint hotspot() const; QPoint hotspot() const;
// selection-related methods // selection-related methods
void select(); void select();
void deselect(); void deselect();
virtual void rotateBy(const qreal &); virtual void rotateBy(const qreal &);
virtual void editProperty(); virtual void editProperty();
// methods related to XML import/export // methods related to XML import/export
static bool valideXml(QDomElement &); static bool valideXml(QDomElement &);
virtual bool fromXml(QDomElement &, QHash<int, Terminal *> &, bool = false); virtual bool fromXml(QDomElement &, QHash<int, Terminal *> &, bool = false);
virtual QDomElement toXml(QDomDocument &, QHash<Terminal *, int> &) const; virtual QDomElement toXml(QDomDocument &, QHash<Terminal *, int> &) const;
QUuid uuid() const; QUuid uuid() const;
// orientation-related methods // orientation-related methods
int orientation() const; int orientation() const;
void addDynamicTextItem(DynamicElementTextItem *deti = nullptr);
void removeDynamicTextItem(DynamicElementTextItem *deti);
QList<DynamicElementTextItem *> dynamicTextItems() const;
protected: protected:
void drawAxes(QPainter *, const QStyleOptionGraphicsItem *); void drawAxes(QPainter *, const QStyleOptionGraphicsItem *);
@ -216,6 +218,7 @@ class Element : public QetGraphicsItem
private: private:
bool m_mouse_over; bool m_mouse_over;
QString m_prefix; QString m_prefix;
QList <DynamicElementTextItem *> m_dynamic_text_list;
}; };

View File

@ -23,6 +23,7 @@
#include "imagepropertieswidget.h" #include "imagepropertieswidget.h"
#include "qetshapeitem.h" #include "qetshapeitem.h"
#include "shapegraphicsitempropertieswidget.h" #include "shapegraphicsitempropertieswidget.h"
#include "dynamicelementtextitem.h"
/** /**
* @brief DiagramPropertiesEditorDockWidget::DiagramPropertiesEditorDockWidget * @brief DiagramPropertiesEditorDockWidget::DiagramPropertiesEditorDockWidget
@ -56,7 +57,7 @@ void DiagramPropertiesEditorDockWidget::setDiagram(Diagram *diagram)
if (diagram) if (diagram)
{ {
m_diagram = diagram; m_diagram = diagram;
connect(m_diagram, SIGNAL(selectionChanged()), this, SLOT(selectionChanged())); connect(m_diagram, SIGNAL(selectionChanged()), this, SLOT(selectionChanged()), Qt::QueuedConnection);
connect(m_diagram, SIGNAL(destroyed()), this, SLOT(diagramWasDeleted())); connect(m_diagram, SIGNAL(destroyed()), this, SLOT(diagramWasDeleted()));
selectionChanged(); selectionChanged();
} }
@ -120,6 +121,22 @@ void DiagramPropertiesEditorDockWidget::selectionChanged()
addEditor(new ShapeGraphicsItemPropertiesWidget(static_cast<QetShapeItem*>(item), this)); addEditor(new ShapeGraphicsItemPropertiesWidget(static_cast<QetShapeItem*>(item), this));
break; } break; }
case DynamicElementTextItem::Type: {
DynamicElementTextItem *deti = static_cast<DynamicElementTextItem *>(item);
//For dynamic element text, we open the element editor
//We already edit an element, just update the editor with a new element
if (m_edited_qgi_type == Element::Type)
{
static_cast<ElementPropertiesWidget*>(editors().first())->setElement(deti->ParentElement());
return;
}
clear();
m_edited_qgi_type = Element::Type;
addEditor(new ElementPropertiesWidget(deti->ParentElement(), this));
break; }
default: default:
m_edited_qgi_type = -1; m_edited_qgi_type = -1;
clear(); clear();

View 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 "dynamicelementtextitemeditor.h"
#include "ui_dynamicelementtextitemeditor.h"
#include "dynamicelementtextitem.h"
#include "element.h"
#include "dynamicelementtextmodel.h"
#include "diagram.h"
#include "undocommand/deleteqgraphicsitemcommand.h"
#include "undocommand/addelementtextcommand.h"
#include <QTreeView>
#include <QUndoCommand>
DynamicElementTextItemEditor::DynamicElementTextItemEditor(Element *element, QWidget *parent) :
AbstractElementPropertiesEditorWidget(parent),
ui(new Ui::DynamicElementTextItemEditor)
{
ui->setupUi(this);
m_tree_view = new QTreeView(this);
m_tree_view->header()->setDefaultSectionSize(150);
m_tree_view->setItemDelegate(new DynamicTextItemDelegate(m_tree_view));
m_tree_view->setAlternatingRowColors(true);
ui->verticalLayout->addWidget(m_tree_view);
setElement(element);
}
DynamicElementTextItemEditor::~DynamicElementTextItemEditor()
{
delete ui;
}
void DynamicElementTextItemEditor::setElement(Element *element)
{
if (m_element == element)
return;
m_element = element;
DynamicElementTextModel *old_model = m_model;
m_model = new DynamicElementTextModel(m_tree_view);
connect(m_model, &DynamicElementTextModel::itemChanged, this, &DynamicElementTextItemEditor::dataEdited);
for (DynamicElementTextItem *deti : m_element->dynamicTextItems())
m_model->addText(deti);
m_tree_view->setModel(m_model);
if(old_model)
delete old_model;
}
bool DynamicElementTextItemEditor::setLiveEdit(bool live_edit)
{
m_live_edit = live_edit;
return true;
}
void DynamicElementTextItemEditor::apply()
{
QList <QUndoCommand *> undo_list;
for (DynamicElementTextItem *deti : m_element->dynamicTextItems())
{
QUndoCommand *undo = m_model->undoForEditedText(deti);
if(undo->childCount())
undo_list << undo;
else
delete undo;
}
for (DynamicElementTextItem *deti : m_element->dynamicTextItems())
deti->blockSignals(true);
if(!undo_list.isEmpty() && m_element->diagram())
{
if (undo_list.size() == 1)
m_element->diagram()->undoStack().push(undo_list.first());
else
{
QUndoStack &us = m_element->diagram()->undoStack();
us.beginMacro(tr("Modifier des texte d'élément"));
for (QUndoCommand *quc : undo_list)
us.push(quc);
us.endMacro();
}
}
for (DynamicElementTextItem *deti : m_element->dynamicTextItems())
deti->blockSignals(false);
}
void DynamicElementTextItemEditor::dataEdited(QStandardItem *qsi)
{
Q_UNUSED(qsi)
if (m_live_edit)
apply();
}
/**
* @brief DynamicElementTextItemEditor::on_m_add_text_clicked
* Add a new dynamic text
*/
void DynamicElementTextItemEditor::on_m_add_text_clicked()
{
if (!m_element)
return;
DynamicElementTextItem *deti = new DynamicElementTextItem(m_element);
if (m_element->diagram())
{
m_element->diagram()->undoStack().push(new AddElementTextCommand(m_element, deti));
m_model->addText(deti);
}
else
{
delete deti;
}
}
/**
* @brief DynamicElementTextItemEditor::on_m_remove_text_clicked
* Remove the selected text field
*/
void DynamicElementTextItemEditor::on_m_remove_text_clicked()
{
DynamicElementTextItem *deti = m_model->textFromIndex(m_tree_view->currentIndex());
if(deti)
{
if(m_element->diagram())
{
DiagramContent dc;
dc.m_element_texts << deti;
m_element->diagram()->undoStack().push(new DeleteQGraphicsItemCommand(m_element->diagram(), dc));
m_model->removeText(deti);
}
}
}

View File

@ -0,0 +1,59 @@
/*
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 DYNAMICELEMENTTEXTITEMEDITOR_H
#define DYNAMICELEMENTTEXTITEMEDITOR_H
#include "abstractelementpropertieseditorwidget.h"
class DynamicElementTextItem;
class DynamicElementTextModel;
class QTreeView;
class QStandardItem;
namespace Ui {
class DynamicElementTextItemEditor;
}
class DynamicElementTextItemEditor : public AbstractElementPropertiesEditorWidget
{
Q_OBJECT
public:
explicit DynamicElementTextItemEditor(Element *element, QWidget *parent = 0);
~DynamicElementTextItemEditor();
virtual void setElement(Element *element);
virtual QString title() const {return tr("Textes");}
virtual bool setLiveEdit(bool live_edit);
virtual void apply();
private:
void dataEdited(QStandardItem *qsi);
private slots:
void on_m_add_text_clicked();
void on_m_remove_text_clicked();
private:
Ui::DynamicElementTextItemEditor *ui;
QTreeView *m_tree_view = nullptr;
DynamicElementTextModel *m_model = nullptr;
};
#endif // DYNAMICELEMENTTEXTITEMEDITOR_H

View File

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DynamicElementTextItemEditor</class>
<widget class="QWidget" name="DynamicElementTextItemEditor">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="m_add_text">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../qelectrotech.qrc">
<normaloff>:/ico/16x16/list-add.png</normaloff>:/ico/16x16/list-add.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_remove_text">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../qelectrotech.qrc">
<normaloff>:/ico/16x16/list-remove.png</normaloff>:/ico/16x16/list-remove.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources>
<include location="../../qelectrotech.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -0,0 +1,407 @@
/*
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 "dynamicelementtextmodel.h"
#include "dynamicelementtextitem.h"
#include <QStandardItem>
#include <QHash>
#include <QColorDialog>
#include <QModelIndex>
#include <QComboBox>
#include <QUndoCommand>
#include "QPropertyUndoCommand/qpropertyundocommand.h"
DynamicElementTextModel::DynamicElementTextModel(QObject *parent) :
QStandardItemModel(parent)
{
setColumnCount(2);
setHeaderData(0, Qt::Horizontal, tr("Propriété"), Qt::DisplayRole);
setHeaderData(1, Qt::Horizontal, tr("Valeur"), Qt::DisplayRole);
connect(this, &DynamicElementTextModel::itemChanged, this, &DynamicElementTextModel::dataEdited);
}
DynamicElementTextModel::~DynamicElementTextModel()
{
//Connection is not destroy automaticaly,
//because was not connected to a slot, but a lambda
for(DynamicElementTextItem *deti : m_hash_text_connect.keys())
setConnection(deti, false);
}
/**
* @brief DynamicElementTextModel::addText
* @param deti
*/
void DynamicElementTextModel::addText(DynamicElementTextItem *deti)
{
if(m_texts_list.keys().contains(deti))
return;
QList <QStandardItem *> qsi_list;
QStandardItem *qsi = new QStandardItem(deti->toPlainText());
qsi->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
//Source of text
QStandardItem *src = new QStandardItem(tr("Source du texte"));
src->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
QStandardItem *srca = new QStandardItem(deti->textFrom() == DynamicElementTextItem::UserText ? tr("Texte utilisateur") : tr("Information de l'élément"));
srca->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
srca->setData(textFrom, Qt::UserRole+1);
qsi_list << src << srca;
qsi->appendRow(qsi_list);
//User text
QStandardItem *usr = new QStandardItem(tr("Texte"));
usr->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
QStandardItem *usra = new QStandardItem(deti->toPlainText());
usra->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
usra->setData(DynamicElementTextModel::userText, Qt::UserRole+1);
qsi_list.clear();
qsi_list << usr << usra;
src->appendRow(qsi_list);
//Info text
QStandardItem *info = new QStandardItem(tr("Information"));
info->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
QStandardItem *infoa = new QStandardItem(deti->toPlainText());
infoa->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
infoa->setData(DynamicElementTextModel::infoText, Qt::UserRole+1);
qsi_list.clear();
qsi_list << info << infoa;
src->appendRow(qsi_list);
//Size
QStandardItem *size = new QStandardItem(tr("Taille"));
size->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
QStandardItem *siza = new QStandardItem();
siza->setData(deti->fontSize(), Qt::EditRole);
siza->setData(DynamicElementTextModel::size, Qt::UserRole+1);
siza->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
qsi_list.clear();
qsi_list << size << siza;
qsi->appendRow(qsi_list);
//Tagg
QStandardItem *tagg = new QStandardItem(tr("Tagg"));
tagg->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
QStandardItem *tagga = new QStandardItem(deti->tagg());
tagga->setData(DynamicElementTextModel::tagg, Qt::UserRole+1);
tagga->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
qsi_list.clear();
qsi_list << tagg << tagga;
qsi->appendRow(qsi_list);
//Color
QStandardItem *color = new QStandardItem(tr("Couleur"));
color->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
QStandardItem *colora = new QStandardItem;
colora->setData(deti->color(), Qt::ForegroundRole);
colora->setData(deti->color(), Qt::EditRole);
colora->setData(DynamicElementTextModel::color, Qt::UserRole+1);
colora->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
qsi_list.clear();
qsi_list << color << colora;
qsi->appendRow(qsi_list);
qsi_list.clear();
QStandardItem *empty_qsi = new QStandardItem(0);
empty_qsi->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
qsi_list << qsi << empty_qsi;
this->appendRow(qsi_list);
m_texts_list.insert(deti, qsi);
blockSignals(true);
enableSourceText(deti, deti->textFrom());
blockSignals(false);
setConnection(deti, true);
}
/**
* @brief DynamicElementTextModel::removeText
* @param deti
*/
void DynamicElementTextModel::removeText(DynamicElementTextItem *deti)
{
if (!m_texts_list.contains(deti))
return;
QModelIndex text_index = m_texts_list.value(deti)->index();
this->removeRow(text_index.row(), text_index.parent());
m_texts_list.remove(deti);
setConnection(deti, false);
}
/**
* @brief DynamicElementTextModel::textFromIndex
* @param index
* @return the text associated with @index. Return value can be nullptr
* @Index can be a child of an index associated with a text
*/
DynamicElementTextItem *DynamicElementTextModel::textFromIndex(const QModelIndex &index) const
{
if(!index.isValid())
return nullptr;
if (QStandardItem *item = itemFromIndex(index))
return textFromItem(item);
else
return nullptr;
}
/**
* @brief DynamicElementTextModel::textFromItem
* @param item
* @return the text associated with @item. Return value can be nullptr
* @item can be a child of an item associated with a text
*/
DynamicElementTextItem *DynamicElementTextModel::textFromItem(QStandardItem *item) const
{
QStandardItem *text_item = item;
while (text_item->parent())
text_item = text_item->parent();
if (m_texts_list.values().contains(text_item))
return m_texts_list.key(text_item);
else
return nullptr;
}
/**
* @brief DynamicElementTextModel::undoForEditedText
* @param deti
* @return A QUndoCommand that describe all changes made for @deti.
* Each change made for @deti is append as a child of the returned QUndoCommand.
* In other word, if the returned QUndoCommand have no child, that mean there is no change.
*/
QUndoCommand *DynamicElementTextModel::undoForEditedText(DynamicElementTextItem *deti) const
{
QUndoCommand *undo = new QUndoCommand(tr("Éditer un texte d'élément"));
if (!m_texts_list.contains(deti))
return undo;
QStandardItem *text_qsi = m_texts_list.value(deti);
QString from = text_qsi->child(0,1)->data(Qt::DisplayRole).toString();
if ((from == tr("Texte utilisateur")) && (deti->textFrom() != DynamicElementTextItem::UserText))
new QPropertyUndoCommand(deti, "textFrom", QVariant(deti->textFrom()), QVariant(DynamicElementTextItem::UserText), undo);
else if ((from == tr("Information de l'élément")) && (deti->textFrom() != DynamicElementTextItem::ElementInfo))
new QPropertyUndoCommand(deti, "textFrom", QVariant(deti->textFrom()), QVariant(DynamicElementTextItem::ElementInfo), undo);
QString text = text_qsi->child(0,0)->child(0,1)->data(Qt::DisplayRole).toString();
if (text != deti->text())
new QPropertyUndoCommand(deti, "text", QVariant(deti->text()), QVariant(text), undo);
int fs = text_qsi->child(1,1)->data(Qt::EditRole).toInt();
if (fs != deti->fontSize())
new QPropertyUndoCommand(deti, "fontSize", QVariant(deti->fontSize()), QVariant(fs), undo);
QString tagg = text_qsi->child(2,1)->data(Qt::DisplayRole).toString();
if(tagg != deti->tagg())
new QPropertyUndoCommand(deti, "tagg", QVariant(deti->tagg()), QVariant(tagg), undo);
QColor color = text_qsi->child(3,1)->data(Qt::EditRole).value<QColor>();
if(color != deti->color())
new QPropertyUndoCommand(deti, "color", QVariant(deti->color()), QVariant(color), undo);
return undo;
}
/**
* @brief DynamicElementTextModel::enableSourceText
* Enable the good field, according to the current source of text, for the edited text @deti
* @param deti
* @param tf
*/
void DynamicElementTextModel::enableSourceText(DynamicElementTextItem *deti, DynamicElementTextItem::TextFrom tf)
{
if (!m_texts_list.contains(deti))
return;
QStandardItem *qsi = m_texts_list.value(deti)->child(0,0);
bool usr = true, info = false;
if(tf == DynamicElementTextItem::ElementInfo) {
usr = false; info = true;}
//User text
qsi->child(0,0)->setEnabled(usr);
qsi->child(0,1)->setEnabled(usr);
//Info text
qsi->child(1,0)->setEnabled(info);
qsi->child(1,1)->setEnabled(info);
}
void DynamicElementTextModel::dataEdited(QStandardItem *qsi)
{
DynamicElementTextItem *deti = textFromItem(qsi);
if (!deti)
return;
if (qsi->data().toInt() == textFrom)
{
QString from = qsi->data(Qt::DisplayRole).toString();
if (from == tr("Texte utilisateur"))
enableSourceText(deti, DynamicElementTextItem::UserText);
else
enableSourceText(deti, DynamicElementTextItem::ElementInfo);
}
else if (qsi->data().toInt() == userText)
{
QString text = qsi->data(Qt::DisplayRole).toString();
m_texts_list.value(deti)->setData(text, Qt::DisplayRole);
}
}
/**
* @brief DynamicElementTextModel::setConnection
* Set up the connection for @deti to keep up to date the data of this model and the text.
* Is notably use with the use of QUndoCommand.
* @param deti - text to setup connection
* @param set - true = set connection - false unset connection
*/
void DynamicElementTextModel::setConnection(DynamicElementTextItem *deti, bool set)
{
if(set)
{
if(m_hash_text_connect.keys().contains(deti))
return;
QList<QMetaObject::Connection> connection_list;
connection_list << connect(deti, &DynamicElementTextItem::colorChanged, [deti,this](){this->updateDataFromText(deti, color);});
connection_list << connect(deti, &DynamicElementTextItem::fontSizeChanged, [deti,this](){this->updateDataFromText(deti, size);});
connection_list << connect(deti, &DynamicElementTextItem::taggChanged, [deti,this](){this->updateDataFromText(deti, tagg);});
connection_list << connect(deti, &DynamicElementTextItem::textChanged, [deti,this](){this->updateDataFromText(deti, userText);});
connection_list << connect(deti, &DynamicElementTextItem::TextFromChanged, [deti,this](){this->updateDataFromText(deti, textFrom);});
m_hash_text_connect.insert(deti, connection_list);
}
else
{
if(!m_hash_text_connect.keys().contains(deti))
return;
for (QMetaObject::Connection con : m_hash_text_connect.value(deti))
disconnect(con);
m_hash_text_connect.remove(deti);
}
}
void DynamicElementTextModel::updateDataFromText(DynamicElementTextItem *deti, ValueType type)
{
QStandardItem *qsi = m_texts_list.value(deti);
if (!qsi)
return;
switch (type)
{
case textFrom:
qsi->child(0,1)->setData(deti->textFrom() == DynamicElementTextItem::UserText ? tr("Texte utilisateur") : tr("Information de l'élément"), Qt::DisplayRole);
break;
case userText:
{
QStandardItem *qsia = qsi->child(0,0);
qsia->child(0,1)->setData(deti->toPlainText(), Qt::DisplayRole);
qsi->setData(deti->toPlainText(), Qt::DisplayRole);
break;
}
case infoText:
break;
case size:
qsi->child(1,1)->setData(deti->fontSize(), Qt::EditRole);
break;
case tagg:
qsi->child(2,1)->setData(deti->tagg(), Qt::DisplayRole);
break;
case color:
{
qsi->child(3,1)->setData(deti->color(), Qt::EditRole);
qsi->child(3,1)->setData(deti->color(), Qt::ForegroundRole);
break;
}
}
}
/***************************************************
* A little delegate only for add a combobox and a color dialog,
* for use with the model
***************************************************/
DynamicTextItemDelegate::DynamicTextItemDelegate(QObject *parent) :
QStyledItemDelegate(parent)
{}
QWidget *DynamicTextItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
switch (index.data(Qt::UserRole+1).toInt())
{
case DynamicElementTextModel::textFrom:
{
QComboBox *qcb = new QComboBox(parent);
qcb->addItem(tr("Texte utilisateur"));
qcb->addItem(tr("Information de l'élément"));
return qcb;
}
case DynamicElementTextModel::color:
{
QColorDialog *cd = new QColorDialog(index.data(Qt::EditRole).value<QColor>());
return cd;
}
}
return QStyledItemDelegate::createEditor(parent, option, index);
}
void DynamicTextItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
if (index.isValid())
{
if (QStandardItemModel *qsim = dynamic_cast<QStandardItemModel *>(model))
{
QStandardItem *qsi = qsim->itemFromIndex(index);
if(qsi)
{
if(QColorDialog *cd = dynamic_cast<QColorDialog *> (editor))
{
qsi->setData(cd->selectedColor(), Qt::EditRole);
qsi->setData(cd->selectedColor(), Qt::ForegroundRole);
return;
}
}
}
}
QStyledItemDelegate::setModelData(editor, model, index);
}

View File

@ -0,0 +1,76 @@
/*
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 DYNAMICELEMENTTEXTMODEL_H
#define DYNAMICELEMENTTEXTMODEL_H
#include <QStandardItemModel>
#include <qstyleditemdelegate.h>
#include "dynamicelementtextitem.h"
class QUndoCommand;
/**
* @brief The DynamicElementTextModel class
* A model to use with QtView.
* This model display and can edit the value of dynamic text of an element.
* Set the delegate DynamicTextItemDelegate as delegate of this model.
*/
class DynamicElementTextModel : public QStandardItemModel
{
Q_OBJECT
public:
enum ValueType {
textFrom =1,
userText,
infoText,
size,
tagg,
color
};
DynamicElementTextModel(QObject *parent = nullptr);
~DynamicElementTextModel();
void addText(DynamicElementTextItem *deti);
void removeText(DynamicElementTextItem *deti);
DynamicElementTextItem *textFromIndex(const QModelIndex &index) const;
DynamicElementTextItem *textFromItem(QStandardItem *item) const;
QUndoCommand *undoForEditedText(DynamicElementTextItem *deti) const;
private:
void enableSourceText(DynamicElementTextItem *deti, DynamicElementTextItem::TextFrom tf );
void dataEdited(QStandardItem *qsi);
void setConnection(DynamicElementTextItem *deti, bool set);
void updateDataFromText(DynamicElementTextItem *deti, DynamicElementTextModel::ValueType type);
private:
QHash <DynamicElementTextItem *, QStandardItem *> m_texts_list;
QHash <DynamicElementTextItem *, QList<QMetaObject::Connection>> m_hash_text_connect;
};
class DynamicTextItemDelegate : public QStyledItemDelegate
{
public:
DynamicTextItemDelegate(QObject *parent = Q_NULLPTR);
virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
};
#endif // DYNAMICELEMENTTEXTMODEL_H

View File

@ -24,6 +24,7 @@
#include "diagram.h" #include "diagram.h"
#include "diagramposition.h" #include "diagramposition.h"
#include "qeticons.h" #include "qeticons.h"
#include "dynamicelementtextitemeditor.h"
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QLabel> #include <QLabel>
@ -203,9 +204,10 @@ void ElementPropertiesWidget::updateUi()
default: default:
break; break;
} }
m_list_editor << new DynamicElementTextItemEditor(m_element, this);
//Add each editors in tab widget //Add each editors in tab widget
foreach (AbstractElementPropertiesEditorWidget *aepew, m_list_editor) for (AbstractElementPropertiesEditorWidget *aepew : m_list_editor)
{ {
aepew->setLiveEdit(m_live_edit); aepew->setLiveEdit(m_live_edit);
m_tab->addTab(aepew, aepew->title()); m_tab->addTab(aepew, aepew->title());
@ -296,7 +298,7 @@ QWidget *ElementPropertiesWidget::generalWidget()
connect(find_in_panel, SIGNAL(clicked()), this, SLOT(findInPanel())); connect(find_in_panel, SIGNAL(clicked()), this, SLOT(findInPanel()));
QPushButton *edit_element = new QPushButton(QET::Icons::ElementEdit, tr("Éditer l'élément"), general_widget); QPushButton *edit_element = new QPushButton(QET::Icons::ElementEdit, tr("Éditer l'élément"), general_widget);
connect(edit_element, SIGNAL(clicked()), this, SLOT(editElement())); connect(edit_element, SIGNAL(clicked()), this, SLOT(editElement()));
QHBoxLayout *hlayout_ = new QHBoxLayout; QHBoxLayout *hlayout_ = new QHBoxLayout;
hlayout_->addWidget(find_in_panel); hlayout_->addWidget(find_in_panel);
hlayout_->addWidget(edit_element); hlayout_->addWidget(edit_element);
vlayout_->addLayout(hlayout_); vlayout_->addLayout(hlayout_);

View File

@ -0,0 +1,83 @@
/*
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 "addelementtextcommand.h"
#include "element.h"
#include "dynamicelementtextitem.h"
#include <QGraphicsScene>
AddElementTextCommand::AddElementTextCommand(Element *element, DynamicElementTextItem *deti, QUndoCommand *parent):
QUndoCommand(parent),
m_element(element),
m_text(deti)
{
setText(QObject::tr("Ajouter un texte d'élément"));
}
AddElementTextCommand::~AddElementTextCommand()
{
if(!m_element->dynamicTextItems().contains(m_text))
delete m_text;
}
void AddElementTextCommand::undo()
{
m_element->removeDynamicTextItem(m_text);
m_text->setParentItem(nullptr);
if(m_text->scene())
m_text->scene()->removeItem(m_text);
}
void AddElementTextCommand::redo()
{
m_text->setParentItem(m_element);
m_element->addDynamicTextItem(m_text);
}
//RemoveElementTextCommand::RemoveElementTextCommand(DynamicElementTextItem *deti, QUndoCommand *parent) :
// QUndoCommand(parent),
// m_text(deti)
//{
// setText(QObject::tr("Supprimer un texte d'élément"));
// m_element = deti->ParentElement();
//}
//RemoveElementTextCommand::~RemoveElementTextCommand()
//{
// if(m_element && !m_element->dynamicTextItems().contains(m_text))
// delete m_text;
//}
//void RemoveElementTextCommand::undo()
//{
// if(m_element)
// {
// m_text->setParentItem(m_element);
// m_element->addDynamicTextItem(m_text);
// }
//}
//void RemoveElementTextCommand::redo()
//{
// if(m_element && m_text->scene())
// {
// m_element->removeDynamicTextItem(m_text);
// m_text->setParentItem(nullptr);
// m_text->scene()->removeItem(m_text);
// }
//}

View File

@ -0,0 +1,54 @@
/*
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 ADDELEMENTTEXTCOMMAND_H
#define ADDELEMENTTEXTCOMMAND_H
#include <QUndoCommand>
class Element;
class DynamicElementTextItem;
class AddElementTextCommand : public QUndoCommand
{
public:
AddElementTextCommand(Element *element, DynamicElementTextItem *deti, QUndoCommand *parent = nullptr);
virtual ~AddElementTextCommand();
virtual void undo();
virtual void redo();
private:
Element *m_element = nullptr;
DynamicElementTextItem *m_text = nullptr;
};
//class RemoveElementTextCommand : public QUndoCommand
//{
// public:
// RemoveElementTextCommand(DynamicElementTextItem *deti, QUndoCommand *parent = nullptr);
// virtual ~RemoveElementTextCommand();
// virtual void undo();
// virtual void redo();
// private:
// Element *m_element = nullptr;
// DynamicElementTextItem *m_text = nullptr;
//};
#endif // ADDELEMENTTEXTCOMMAND_H

View File

@ -0,0 +1,119 @@
/*
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 "deleteqgraphicsitemcommand.h"
#include "dynamicelementtextitem.h"
#include "diagram.h"
#include "element.h"
#include "conductor.h"
#include "conductortextitem.h"
/**
* @brief DeleteQGraphicsItemCommand::DeleteQGraphicsItemCommand
* @param diagram : deigram where this undo work
* @param content : content to remove
* @param parent : parent undo
*/
DeleteQGraphicsItemCommand::DeleteQGraphicsItemCommand(Diagram *diagram, const DiagramContent &content, QUndoCommand *parent) :
QUndoCommand(parent),
m_removed_contents(content),
m_diagram(diagram)
{
//If parent element of a dynamic element text item is also in @m_removed_content,
//we remove it, because when the element will be removed from the scene every child's will also be removed.
const QSet<DynamicElementTextItem *> elmt_set = m_removed_contents.m_element_texts;
for(DynamicElementTextItem *deti : elmt_set)
{
if (m_removed_contents.m_elements.contains(deti->ParentElement()))
m_removed_contents.m_element_texts.remove(deti);
}
for(DynamicElementTextItem *deti : m_removed_contents.m_element_texts)
m_elmt_text_hash.insert(deti, deti->ParentElement());
setText(QString(QObject::tr("supprimer %1", "undo caption - %1 is a sentence listing the removed content")).arg(m_removed_contents.sentence(DiagramContent::All)));
m_diagram->qgiManager().manage(m_removed_contents.items(DiagramContent::All));
}
DeleteQGraphicsItemCommand::~DeleteQGraphicsItemCommand() {
m_diagram->qgiManager().release(m_removed_contents.items(DiagramContent::All));
}
/**
* @brief DeleteQGraphicsItemCommand::undo
* Undo this command
*/
void DeleteQGraphicsItemCommand::undo()
{
m_diagram->showMe();
for(QGraphicsItem *item : m_removed_contents.items())
m_diagram->addItem(item);
//We relink element after every element was added to diagram
for(Element *e : m_removed_contents.m_elements)
for(Element *elmt : m_link_hash[e])
e->linkToElement(elmt);
for(DynamicElementTextItem *deti : m_removed_contents.m_element_texts)
{
deti->setParentItem(m_elmt_text_hash.value(deti));
m_elmt_text_hash.value(deti)->addDynamicTextItem(deti);
}
}
/**
* @brief DeleteQGraphicsItemCommand::redo
* Redo the delete command
*/
void DeleteQGraphicsItemCommand::redo()
{
m_diagram -> showMe();
for(Conductor *c : m_removed_contents.conductors(DiagramContent::AnyConductor))
{
//If option one text per folio is enable, and the text item of
//current conductor is visible (that mean the conductor have the single displayed text)
//We call adjustTextItemPosition to other conductor at the same potential to keep
//a visible text on this potential.
if (m_diagram -> defaultConductorProperties.m_one_text_per_folio && c -> textItem() -> isVisible())
{
QList <Conductor *> conductor_list;
conductor_list << c -> relatedPotentialConductors(false).toList();
if (conductor_list.count())
conductor_list.first() -> calculateTextItemPosition();
}
}
for(Element *e : m_removed_contents.m_elements)
{
//Get linked element, for relink it at undo
if (!e->linkedElements().isEmpty())
m_link_hash.insert(e, e->linkedElements());
}
for(DynamicElementTextItem *deti : m_removed_contents.m_element_texts)
{
deti->ParentElement()->removeDynamicTextItem(deti);
deti->setParentItem(nullptr);
}
for(QGraphicsItem *item : m_removed_contents.items())
m_diagram->removeItem(item);
}

View File

@ -0,0 +1,46 @@
/*
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 DELETEQGRAPHICSITEMCOMMAND_H
#define DELETEQGRAPHICSITEMCOMMAND_H
#include <QUndoCommand>
#include "diagramcontent.h"
class Diagram;
class DeleteQGraphicsItemCommand : public QUndoCommand
{
public:
DeleteQGraphicsItemCommand(Diagram *diagram, const DiagramContent &content, QUndoCommand * parent = nullptr);
virtual ~DeleteQGraphicsItemCommand() override;
private:
DeleteQGraphicsItemCommand(const DeleteQGraphicsItemCommand &);
public:
virtual void undo() override;
virtual void redo() override;
// attributes
private:
DiagramContent m_removed_contents;
Diagram *m_diagram;
QHash <Element *, QList<Element *> > m_link_hash; /// keep linked element for each removed element linked to other element.
QHash <DynamicElementTextItem *, Element *> m_elmt_text_hash; /// Keep the parent element of each deleted dynamic element text item
};
#endif // DELETEQGRAPHICSITEMCOMMAND_H