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
QetShapItem + 1008
crossRefItem + 1009
DynamiqueElementTextItem + 1010
ElementPrimitiveDecorator + 2200
###ELEMENT EDITOR###
@ -21,3 +22,6 @@ part terminal + 1106
part text + 1107
part text field + 1108
part rectangle + 1109
###QetGraphicsHandlerItem###
QetGraphicsHandlerItem = 1200

View File

@ -38,6 +38,7 @@
#include "elementcollectionhandler.h"
#include "element.h"
#include "diagramview.h"
#include "dynamicelementtextitem.h"
const int Diagram::xGrid = 10;
const int Diagram::yGrid = 10;
@ -75,7 +76,7 @@ Diagram::Diagram(QETProject *project) :
//Init object for manage movement
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(diagramTitleChanged(const QString &)), this, SLOT(titleChanged(const QString &)));
@ -91,7 +92,10 @@ Diagram::Diagram(QETProject *project) :
* @brief Diagram::~Diagram
* Destructor
*/
Diagram::~Diagram() {
Diagram::~Diagram()
{
//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();
//delete of QGIManager, every elements he knows are removed
@ -101,21 +105,17 @@ Diagram::~Diagram() {
// delete of object for manage movement
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
QList<QGraphicsItem *> deletable_items;
for(QGraphicsItem *qgi : items())
{
if (qgi->parentItem())
continue;
if (qgi->type() == Conductor::Type)
continue;
if (qgi->type() == QetGraphicsHandlerItem::Type)
continue;
if (qgi -> parentItem()) continue;
if (qgraphicsitem_cast<Conductor *>(qgi)) continue;
deletable_items << qgi;
}
@ -302,10 +302,10 @@ void Diagram::keyPressEvent(QKeyEvent *e)
qreal top_position = 0;
qreal left_position = 0;
QList<QGraphicsItem*> selected_elmts = this->selectedContent().items();
if (!this->selectedContent().items(255).isEmpty()) {
if (!this->selectedContent().items(DiagramContent::All).isEmpty()) {
switch(e -> key()) {
case Qt::Key_Left:
foreach (Element *item, selectedContent().elements) {
foreach (Element *item, selectedContent().m_elements) {
left_position = item->mapRectFromScene(item->boundingRect()).x();
if (left_position >= this->sceneRect().left() - item->boundingRect().width())
return;
@ -314,7 +314,7 @@ void Diagram::keyPressEvent(QKeyEvent *e)
break;
case Qt::Key_Right: movement = QPointF(+xGrid, 0.0); break;
case Qt::Key_Up:
foreach (Element *item, selectedContent().elements) {
foreach (Element *item, selectedContent().m_elements) {
top_position = item->mapRectFromScene(item->boundingRect()).y();
if (top_position >= this->sceneRect().top() - item->boundingRect().height())
return;
@ -378,8 +378,6 @@ void Diagram::keyReleaseEvent(QKeyEvent *e)
* Diagram become the ownership of event_interface
* If there is a previous interface, they will be delete before
* 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
*/
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_);
}
//Filling of optional lists
// remplissage des listes facultatives
if (content_ptr) {
content_ptr -> elements = added_elements.toSet();
content_ptr -> conductorsToMove = added_conductors.toSet();
content_ptr -> textFields = added_texts.toSet();
content_ptr -> images = added_images.toSet();
content_ptr -> shapes = added_shapes.toSet();
content_ptr -> m_elements = added_elements.toSet();
content_ptr -> m_conductors_to_move = added_conductors.toSet();
content_ptr -> m_text_fields = added_texts.toSet();
content_ptr -> m_images = added_images.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();
return(true);
}
@ -1438,7 +1430,7 @@ void Diagram::endMoveElements() {
@see ElementTextsMover
*/
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
*/
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
*/
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,
mais aussi ceux rattaches a des conducteurs ou des elements
* @brief Diagram::selectedTexts
* @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;
foreach(QGraphicsItem *item, selectedItems()) {
if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(item)) {
selected_texts << cti;
} else if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(item)) {
selected_texts << eti;
} else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item)) {
selected_texts << iti;
}
for(QGraphicsItem *qgi : selectedItems())
{
if (qgi->type() == ConductorTextItem::Type ||
qgi->type() == ElementTextItem::Type ||
qgi->type() == IndependentTextItem::Type ||
qgi->type() == DynamicElementTextItem::Type)
selected_texts << static_cast<DiagramTextItem *>(qgi);
}
return(selected_texts);
}
/**
* @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
bool Diagram::clipboardMayContainDiagram() {
QString clipboard_text = QApplication::clipboard() -> text().trimmed();
@ -1775,47 +1738,53 @@ DiagramContent Diagram::content() const {
DiagramContent dc;
foreach(QGraphicsItem *qgi, items()) {
if (Element *e = qgraphicsitem_cast<Element *>(qgi)) {
dc.elements << e;
dc.m_elements << e;
} else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(qgi)) {
dc.textFields << iti;
dc.m_text_fields << iti;
} else if (Conductor *c = qgraphicsitem_cast<Conductor *>(qgi)) {
dc.conductorsToMove << c;
dc.m_conductors_to_move << c;
}
}
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;
// recupere les elements deplaces
foreach (QGraphicsItem *item, selectedItems()) {
if (Element *elmt = qgraphicsitem_cast<Element *>(item)) {
dc.elements << elmt;
} else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item)) {
dc.textFields << iti;
} else if (Conductor *c = qgraphicsitem_cast<Conductor *>(item)) {
//Get the selected items
for (QGraphicsItem *item : selectedItems())
{
if (Element *elmt = qgraphicsitem_cast<Element *>(item))
dc.m_elements << elmt;
else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item))
dc.m_text_fields << iti;
else if (Conductor *c = qgraphicsitem_cast<Conductor *>(item))
{
// recupere les conducteurs selectionnes isoles (= non deplacables mais supprimables)
if (
!c -> terminal1 -> parentItem() -> isSelected() &&\
!c -> terminal2 -> parentItem() -> isSelected()
) {
dc.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
foreach(Element *elmt, dc.elements) {
foreach(Terminal *terminal, elmt -> terminals()) {
foreach(Conductor *conductor, terminal -> conductors()) {
//For each selected element, we determine if conductors must be moved or updated.
for(Element *elmt : dc.m_elements) {
for(Terminal *terminal : elmt -> terminals()) {
for(Conductor *conductor : terminal -> conductors()) {
Terminal *other_terminal;
if (conductor -> terminal1 == terminal) {
other_terminal = conductor -> terminal2;
@ -1823,10 +1792,10 @@ DiagramContent Diagram::selectedContent() {
other_terminal = conductor -> terminal1;
}
// si les deux elements du conducteur sont deplaces
if (dc.elements.contains(other_terminal -> parentElement())) {
dc.conductorsToMove << conductor;
if (dc.m_elements.contains(other_terminal -> parentElement())) {
dc.m_conductors_to_move << conductor;
} 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.
Concretement, cette methode retourne true s'il y a des elements selectionnes
et qu'au moins l'un d'entre eux peut etre pivote.
* @brief Diagram::canRotateSelection
* @return True if a least one of selected items can be rotated
*/
bool Diagram::canRotateSelection() const {
foreach(QGraphicsItem * qgi, selectedItems()) {
if (qgraphicsitem_cast<IndependentTextItem *>(qgi) ||
qgraphicsitem_cast<ConductorTextItem *>(qgi) ||
qgraphicsitem_cast<DiagramImageItem *>(qgi) ||
qgraphicsitem_cast<ElementTextItem *>(qgi) ||
qgraphicsitem_cast<Element *>(qgi)) return (true);
bool Diagram::canRotateSelection() const
{
for (QGraphicsItem *qgi : selectedItems())
{
if (qgi->type() == IndependentTextItem::Type ||
qgi->type() == ConductorTextItem::Type ||
qgi->type() == DiagramImageItem::Type ||
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 ElementsLocation;
class ElementsMover;
class ElementTextItem;
class IndependentTextItem;
class QETProject;
class Terminal;
class ConductorTextItem;
class DiagramImageItem;
class ElementTextsMover;
class DiagramEventInterface;
@ -96,7 +93,7 @@ class Diagram : public QGraphicsScene
private:
QGraphicsLineItem *conductor_setter_;
ElementsMover *elements_mover_;
ElementTextsMover *element_texts_mover_;
ElementTextsMover *m_element_texts_mover;
QGIManager *qgi_manager_;
QETProject *m_project;
@ -191,8 +188,6 @@ class Diagram : public QGraphicsScene
QList<Element *> elements() const;
QList<Conductor *> conductors() const;
QSet<DiagramTextItem *> selectedTexts() const;
QSet<ConductorTextItem *> selectedConductorTexts() const;
QSet<ElementTextItem*> selectedElementTexts() const;
QSet<Conductor *> selectedConductors() const;
DiagramContent content() const;
DiagramContent selectedContent();

View File

@ -42,88 +42,6 @@ QString itemText(const Conductor *item) {
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
* Constructor
@ -176,7 +94,7 @@ void PasteDiagramCommand::redo()
first_redo = false;
//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)
{
//make new uuid, because old uuid are the uuid of the copied element
@ -211,7 +129,7 @@ void PasteDiagramCommand::redo()
eti -> setPlainText("_");
//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)
{
ConductorProperties cp = c -> properties();
@ -253,7 +171,7 @@ CutDiagramCommand::CutDiagramCommand(
const DiagramContent &content,
QUndoCommand *parent
) :
DeleteElementsCommand(dia, content, parent)
DeleteQGraphicsItemCommand(dia, content, parent)
{
setText(
QString(
@ -366,12 +284,12 @@ void MoveElementsCommand::move(const QPointF &actual_movement) {
}
// 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);
}
// 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);
}
}
@ -588,21 +506,6 @@ void RotateElementsCommand::redo() {
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
@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) :
QUndoCommand(parent),
applied_rotation_angle_(applied_rotation),
diagram(texts.first()->diagram())
m_applied_rotation_angle(applied_rotation),
m_diagram(texts.first()->diagram())
{
foreach(DiagramTextItem *text, texts) {
texts_to_rotate.insert(text, text -> rotationAngle());
m_texts_to_rotate.insert(text, text -> rotationAngle());
}
defineCommandName();
}
@ -630,11 +533,11 @@ RotateTextsCommand::~RotateTextsCommand() {
Annule la rotation des textes
*/
void RotateTextsCommand::undo() {
diagram -> showMe();
foreach(DiagramTextItem *text, texts_to_rotate.keys()) {
m_diagram -> showMe();
foreach(DiagramTextItem *text, m_texts_to_rotate.keys()) {
if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(text))
cti -> forceRotateByUser(previous_rotate_by_user_[cti]);
text -> setRotationAngle(texts_to_rotate[text]);
cti -> forceRotateByUser(m_previous_rotate_by_user[cti]);
text -> setRotationAngle(m_texts_to_rotate[text]);
}
}
@ -642,14 +545,14 @@ void RotateTextsCommand::undo() {
Applique l'angle de rotation aux textes
*/
void RotateTextsCommand::redo() {
diagram -> showMe();
foreach(DiagramTextItem *text, texts_to_rotate.keys()) {
m_diagram -> showMe();
foreach(DiagramTextItem *text, m_texts_to_rotate.keys()) {
if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(text)) {
//we grab the previous rotation by user of each ConductorTextItem
previous_rotate_by_user_.insert(cti, cti -> wasRotateByUser());
m_previous_rotate_by_user.insert(cti, cti -> wasRotateByUser());
cti -> forceRotateByUser(true);
}
text -> setRotationAngle(applied_rotation_angle_);
text -> setRotationAngle(m_applied_rotation_angle);
}
}
@ -663,8 +566,8 @@ void RotateTextsCommand::defineCommandName() {
"orienter %1 à %2°",
"undo caption - %1 looks like '42 texts', %2 is a rotation angle"
)
).arg(QET::ElementsAndConductorsSentence(0, 0, texts_to_rotate.count()))
.arg(applied_rotation_angle_)
).arg(QET::ElementsAndConductorsSentence(0, 0, m_texts_to_rotate.count()))
.arg(m_applied_rotation_angle)
);
}

View File

@ -26,6 +26,7 @@
#include "qetgraphicsitem/qetshapeitem.h"
#include "conductorprofile.h"
#include "diagram.h"
#include "undocommand/deleteqgraphicsitemcommand.h"
class DiagramTextItem;
class Element;
@ -80,32 +81,6 @@ QString itemText(const QetGraphicsItem *item);
QString itemText(const IndependentTextItem *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.
*/
@ -137,7 +112,7 @@ class PasteDiagramCommand : public QUndoCommand {
/**
This command cuts content from a particular diagram.
*/
class CutDiagramCommand : public DeleteElementsCommand {
class CutDiagramCommand : public DeleteQGraphicsItemCommand {
// constructors, destructor
public:
CutDiagramCommand(Diagram *, const DiagramContent &, QUndoCommand * = 0);
@ -275,19 +250,19 @@ class RotateElementsCommand : public QUndoCommand {
This command directs several text items to a same particular angle of
rotation.
*/
class RotateTextsCommand : public QUndoCommand {
class RotateTextsCommand : public QUndoCommand
{
// constructors, destructor
public:
RotateTextsCommand(const QHash<DiagramTextItem *, double> &, double, QUndoCommand * = 0);
RotateTextsCommand(const QList<DiagramTextItem *> &, double, QUndoCommand * = 0);
virtual ~RotateTextsCommand();
RotateTextsCommand(const QList<DiagramTextItem *> &, double, QUndoCommand * = nullptr);
virtual ~RotateTextsCommand() override;
private:
RotateTextsCommand(const RotateTextsCommand &);
// methods
public:
virtual void undo();
virtual void redo();
virtual void undo() override;
virtual void redo() override;
private:
void defineCommandName();
@ -295,12 +270,12 @@ class RotateTextsCommand : public QUndoCommand {
// attributes
private:
/// 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
double applied_rotation_angle_;
double m_applied_rotation_angle;
/// previous state of each conductor text item
QHash<ConductorTextItem *, bool> previous_rotate_by_user_;
Diagram *diagram;
QHash<ConductorTextItem *, bool> m_previous_rotate_by_user;
Diagram *m_diagram;
};
/**

View File

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

View File

@ -27,6 +27,7 @@ class IndependentTextItem;
class DiagramImageItem;
class ElementTextItem;
class QetShapeItem;
class DynamicElementTextItem;
/**
This class provides a container that makes the transmission of diagram content
@ -37,7 +38,8 @@ class QetShapeItem;
Please note this container does not systematically contains a whole
diagram: it may describe only a part of it, e.g. selected items.
*/
class DiagramContent {
class DiagramContent
{
public:
DiagramContent();
DiagramContent(const DiagramContent &);
@ -58,20 +60,14 @@ class DiagramContent {
SelectedOnly = 256
};
/// Hold electrical elements
QSet<Element *> elements;
/// Hold independent text items
QSet<IndependentTextItem *> textFields;
/// Hold image
QSet<DiagramImageItem *> images;
/// Hold shape
QSet<QetShapeItem *> shapes;
/// 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;
QSet<Element *> m_elements;
QSet<IndependentTextItem *> m_text_fields;
QSet<DiagramImageItem *> m_images;
QSet<QetShapeItem *> m_shapes;
QSet<Conductor *> m_conductors_to_update;
QSet<Conductor *> m_conductors_to_move;
QSet<Conductor *> m_other_conductors;
QSet<DynamicElementTextItem *> m_element_texts;
QList<Conductor *> conductors(int = AnyConductor) const;
QList<QGraphicsItem *> items(int = All) const;

View File

@ -45,6 +45,8 @@
#include "diagrameventaddelement.h"
#include "QPropertyUndoCommand/qpropertyundocommand.h"
#include "qetshapeitem.h"
#include "undocommand/deleteqgraphicsitemcommand.h"
#include "dynamicelementtextitem.h"
/**
Constructeur
@ -53,9 +55,7 @@
*/
DiagramView::DiagramView(Diagram *diagram, QWidget *parent) :
QGraphicsView (parent),
m_scene (diagram),
m_event_interface (nullptr),
m_first_activation (true)
m_diagram (diagram)
{
grabGesture(Qt::PinchGesture);
setAttribute(Qt::WA_DeleteOnClose, true);
@ -74,8 +74,8 @@ DiagramView::DiagramView(Diagram *diagram, QWidget *parent) :
setRenderHint(QPainter::TextAntialiasing, true);
setRenderHint(QPainter::SmoothPixmapTransform, true);
setScene(m_scene);
m_scene -> undoStack().setClean();
setScene(m_diagram);
m_diagram -> undoStack().setClean();
setWindowIcon(QET::Icons::QETLogo);
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
setResizeAnchor(QGraphicsView::AnchorUnderMouse);
@ -83,17 +83,17 @@ DiagramView::DiagramView(Diagram *diagram, QWidget *parent) :
setSelectionMode();
adjustSceneRect();
updateWindowTitle();
m_scene->loadElmtFolioSeq();
m_scene->loadCndFolioSeq();
m_diagram->loadElmtFolioSeq();
m_diagram->loadCndFolioSeq();
context_menu = new QMenu(this);
paste_here = new QAction(QET::Icons::EditPaste, tr("Coller ici", "context menu action"), this);
connect(paste_here, SIGNAL(triggered()), this, SLOT(pasteHere()));
m_context_menu = new QMenu(this);
m_paste_here = new QAction(QET::Icons::EditPaste, tr("Coller ici", "context menu action"), this);
connect(m_paste_here, SIGNAL(triggered()), this, SLOT(pasteHere()));
connect(m_scene, SIGNAL(showDiagram(Diagram*)), this, SIGNAL(showDiagram(Diagram*)));
connect(m_scene, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged()));
connect(m_scene, SIGNAL(sceneRectChanged(QRectF)), this, SLOT(adjustSceneRect()));
connect(&(m_scene -> border_and_titleblock), SIGNAL(diagramTitleChanged(const QString &)), this, SLOT(updateWindowTitle()));
connect(m_diagram, SIGNAL(showDiagram(Diagram*)), this, SIGNAL(showDiagram(Diagram*)));
connect(m_diagram, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged()));
connect(m_diagram, SIGNAL(sceneRectChanged(QRectF)), this, SLOT(adjustSceneRect()));
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(findElementRequired(ElementsLocation)), this, SIGNAL(findElementRequired(ElementsLocation)));
@ -111,93 +111,113 @@ DiagramView::~DiagramView() {
Selectionne tous les objets du schema
*/
void DiagramView::selectAll() {
m_scene -> selectAll();
m_diagram -> selectAll();
}
/**
Deslectionne tous les objets selectionnes
*/
void DiagramView::selectNothing() {
m_scene -> deselectAll();
m_diagram -> deselectAll();
}
/**
Inverse l'etat de selection de tous les objets du schema
*/
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;
DiagramContent removed_content = m_scene -> selectedContent();
m_scene -> clearSelection();
m_scene -> undoStack().push(new DeleteElementsCommand(m_scene, removed_content));
void DiagramView::deleteSelection()
{
if (m_diagram -> isReadOnly())
return;
DiagramContent removed_content = m_diagram->selectedContent();
m_diagram->clearSelection();
m_diagram->undoStack().push(new DeleteQGraphicsItemCommand(m_diagram, removed_content));
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<DiagramTextItem *> texts_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;
} else if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(item)) {
else if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(item))
texts_to_rotate << cti;
} else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item)) {
else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item))
texts_to_rotate << iti;
} 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()) {
else if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(item))
{
//We rotate element text item only if is parent element is not selected
if (eti->parentItem() && !eti->parentItem()->isSelected())
texts_to_rotate << eti;
}
} else if (DiagramImageItem *dii = qgraphicsitem_cast<DiagramImageItem *>(item)) {
else if (DynamicElementTextItem *deti = qgraphicsitem_cast<DynamicElementTextItem *>(item))
{
//We rotate dynamic element text item only if is parent element is not selected
if (deti->parentItem() && !deti->parentItem()->isSelected())
texts_to_rotate << deti;
}
else if (DiagramImageItem *dii = qgraphicsitem_cast<DiagramImageItem *>(item))
images_to_rotate << dii;
}
//Do the rotation
if (elements_to_rotate.isEmpty() && texts_to_rotate.isEmpty() && images_to_rotate.isEmpty())
return;
m_diagram->undoStack().push(new RotateElementsCommand(elements_to_rotate, texts_to_rotate, images_to_rotate));
}
// effectue les rotations s'il y a quelque chose a pivoter
if (elements_to_rotate.isEmpty() && texts_to_rotate.isEmpty() && images_to_rotate.isEmpty()) return;
m_scene -> undoStack().push(new RotateElementsCommand(elements_to_rotate, texts_to_rotate, images_to_rotate));
}
/**
* @brief DiagramView::rotateTexts
* Open a dialog to set the rotation angle, and apply it to the selected texts.
*/
void DiagramView::rotateTexts()
{
if (m_diagram->isReadOnly())
return;
void DiagramView::rotateTexts() {
if (m_scene -> isReadOnly()) return;
// recupere les champs de texte a orienter
//Get the texts fields
QList<DiagramTextItem *> texts_to_rotate;
foreach (QGraphicsItem *item, m_scene -> selectedItems()) {
if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(item)) {
for (QGraphicsItem *item : m_diagram->selectedItems())
{
if (ConductorTextItem *cti = qgraphicsitem_cast<ConductorTextItem *>(item))
texts_to_rotate << cti;
} else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item)) {
else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(item))
texts_to_rotate << iti;
} else if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(item)) {
// ici, on pivote un texte d'element meme si son parent est selectionne
else if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(item))
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()) return;
if (texts_to_rotate.isEmpty())
return;
// demande un angle a l'utilisateur
//Open the dialog
QDialog ori_text_dialog(diagramEditor());
ori_text_dialog.setSizeGripEnabled(false);
#ifdef Q_OS_MAC
ori_text_dialog.setWindowFlags(Qt::Sheet);
#endif
ori_text_dialog.setWindowTitle(tr("Orienter les textes sélectionnés", "window title"));
// ori_text_dialog.setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
QTextOrientationSpinBoxWidget *ori_widget = QETApp::createTextOrientationSpinBoxWidget();
@ -207,22 +227,18 @@ void DiagramView::rotateTexts() {
}
ori_widget -> spinBox() -> selectAll();
// boutons
QDialogButtonBox buttons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
connect(&buttons, SIGNAL(accepted()), &ori_text_dialog, SLOT(accept()));
connect(&buttons, SIGNAL(rejected()), &ori_text_dialog, SLOT(reject()));
// ajout dans une disposition verticale
QVBoxLayout layout_v(&ori_text_dialog);
layout_v.setSizeConstraint(QLayout::SetFixedSize);
layout_v.addWidget(ori_widget);
layout_v.addStretch();
layout_v.addWidget(&buttons);
// si le dialogue est accepte
if (ori_text_dialog.exec() == QDialog::Accepted) {
m_scene -> undoStack().push(new RotateTextsCommand(texts_to_rotate, ori_widget -> orientation()));
}
if (ori_text_dialog.exec() == QDialog::Accepted)
m_diagram -> undoStack().push(new RotateTextsCommand(texts_to_rotate, ori_widget -> orientation()));
}
/**
@ -307,11 +323,11 @@ void DiagramView::handleTitleBlockDrop(QDropEvent *e) {
if (tbt_loc.isValid())
{
// 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
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
if (tbt_loc.name() == titleblock_properties_before.template_name)
@ -324,7 +340,7 @@ void DiagramView::handleTitleBlockDrop(QDropEvent *e) {
{
IntegrationMoveTitleBlockTemplatesHandler *handler = new IntegrationMoveTitleBlockTemplatesHandler(this);
//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())
return;
@ -336,7 +352,7 @@ void DiagramView::handleTitleBlockDrop(QDropEvent *e) {
TitleBlockProperties titleblock_properties_after = titleblock_properties_before;
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();
}
@ -348,7 +364,7 @@ void DiagramView::handleTitleBlockDrop(QDropEvent *e) {
* @param e the QDropEvent describing the current drag'n drop
*/
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());
@ -356,7 +372,7 @@ void DiagramView::handleTextDrop(QDropEvent *e) {
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()) )
scale(zoom_factor, zoom_factor);
}
m_scene->adjustSceneRect();
m_diagram->adjustSceneRect();
adjustGridToZoom();
adjustSceneRect();
}
/**
@ -410,7 +425,7 @@ void DiagramView::zoom(const qreal zoom_factor)
*/
void DiagramView::zoomFit() {
adjustSceneRect();
fitInView(m_scene->sceneRect(), Qt::KeepAspectRatio);
fitInView(m_diagram->sceneRect(), Qt::KeepAspectRatio);
adjustGridToZoom();
}
@ -418,7 +433,7 @@ void DiagramView::zoomFit() {
Adjust zoom to fit all elements in the view, regardless of diagram borders.
*/
void DiagramView::zoomContent() {
fitInView(m_scene -> itemsBoundingRect(), Qt::KeepAspectRatio);
fitInView(m_diagram -> itemsBoundingRect(), Qt::KeepAspectRatio);
adjustGridToZoom();
}
@ -435,9 +450,9 @@ void DiagramView::zoomReset() {
*/
void DiagramView::cut() {
copy();
DiagramContent cut_content = m_scene -> selectedContent();
m_scene -> clearSelection();
m_scene -> undoStack().push(new CutDiagramCommand(m_scene, cut_content));
DiagramContent cut_content = m_diagram -> selectedContent();
m_diagram -> clearSelection();
m_diagram -> undoStack().push(new CutDiagramCommand(m_diagram, cut_content));
}
/**
@ -445,7 +460,7 @@ void DiagramView::cut() {
*/
void DiagramView::copy() {
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);
presse_papier -> setText(contenu_presse_papier);
}
@ -457,7 +472,7 @@ void DiagramView::copy() {
@param clipboard_mode Type de presse-papier a prendre en compte
*/
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);
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
DiagramContent content_pasted;
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
if (content_pasted.count()) {
m_scene -> clearSelection();
m_scene -> undoStack().push(new PasteDiagramCommand(m_scene, content_pasted));
m_diagram -> clearSelection();
m_diagram -> undoStack().push(new PasteDiagramCommand(m_diagram, content_pasted));
adjustSceneRect();
}
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
*/
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)
{
if (fresh_focus_in_)
if (m_fresh_focus_in)
{
switchToVisualisationModeIfNeeded(e);
fresh_focus_in_ = false;
m_fresh_focus_in = false;
}
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
if (e->button() == Qt::MidButton)
{
rubber_band_origin = e->pos();
m_rubber_band_origin = e->pos();
viewport()->setCursor(Qt::ClosedHandCursor);
}
@ -523,11 +538,10 @@ void DiagramView::mouseMoveEvent(QMouseEvent *e)
{
QScrollBar *h = horizontalScrollBar();
QScrollBar *v = verticalScrollBar();
QPointF pos = rubber_band_origin - e -> pos();
rubber_band_origin = e -> pos();
QPointF pos = m_rubber_band_origin - e -> pos();
m_rubber_band_origin = e -> pos();
h -> setValue(h -> value() + pos.x());
v -> setValue(v -> value() + pos.y());
adjustSceneRect();
}
else QGraphicsView::mouseMoveEvent(e);
@ -619,7 +633,7 @@ bool DiagramView::gestureEvent(QGestureEvent *event)
*/
void DiagramView::focusInEvent(QFocusEvent *e) {
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:
if (!hasTextItems()) {
if (
qgraphicsitem_cast<IndependentTextItem *>(m_scene->focusItem()) ||
qgraphicsitem_cast<ElementTextItem *>(m_scene->focusItem()) ||
qgraphicsitem_cast<ConductorTextItem *>(m_scene->focusItem()) ||
qgraphicsitem_cast<DiagramTextItem *>(m_scene->focusItem())
qgraphicsitem_cast<IndependentTextItem *>(m_diagram->focusItem()) ||
qgraphicsitem_cast<ElementTextItem *>(m_diagram->focusItem()) ||
qgraphicsitem_cast<ConductorTextItem *>(m_diagram->focusItem()) ||
qgraphicsitem_cast<DiagramTextItem *>(m_diagram->focusItem())
)
break;
current_project->changeFirstTab();
@ -654,10 +668,10 @@ switch(e -> key())
case Qt::Key_End:
if (!hasTextItems()) {
if (
qgraphicsitem_cast<IndependentTextItem *>(m_scene->focusItem()) ||
qgraphicsitem_cast<ElementTextItem *>(m_scene->focusItem()) ||
qgraphicsitem_cast<ConductorTextItem *>(m_scene->focusItem()) ||
qgraphicsitem_cast<DiagramTextItem *>(m_scene->focusItem())
qgraphicsitem_cast<IndependentTextItem *>(m_diagram->focusItem()) ||
qgraphicsitem_cast<ElementTextItem *>(m_diagram->focusItem()) ||
qgraphicsitem_cast<ConductorTextItem *>(m_diagram->focusItem()) ||
qgraphicsitem_cast<DiagramTextItem *>(m_diagram->focusItem())
)
break;
current_project->changeLastTab();
@ -677,19 +691,19 @@ switch(e -> key())
if (e->modifiers() & Qt::ControlModifier)
zoom(1.15);
case Qt::Key_Up:
if(!(m_scene->selectedContent().items(255).isEmpty())){
if(!(m_diagram->selectedContent().items(DiagramContent::All).isEmpty())){
scrollOnMovement(e);
}
case Qt::Key_Down:
if(!(m_scene->selectedContent().items(255).isEmpty())){
if(!(m_diagram->selectedContent().items(DiagramContent::All).isEmpty())){
scrollOnMovement(e);
}
case Qt::Key_Left:
if(!(m_scene->selectedContent().items(255).isEmpty())){
if(!(m_diagram->selectedContent().items(DiagramContent::All).isEmpty())){
scrollOnMovement(e);
}
case Qt::Key_Right:
if(!(m_scene->selectedContent().items(255).isEmpty())){
if(!(m_diagram->selectedContent().items(DiagramContent::All).isEmpty())){
scrollOnMovement(e);
}
}
@ -714,7 +728,7 @@ void DiagramView::keyReleaseEvent(QKeyEvent *e) {
or below the editor SceneRect is expanded
*/
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();
foreach (QGraphicsItem *qgi, selected_elmts){
if (qgraphicsitem_cast<Conductor *>(qgi)) continue;
@ -755,10 +769,10 @@ void DiagramView::scrollOnMovement(QKeyEvent *e){
h_increment = 2*qgi->boundingRect().right();
if (h_increment == 0) h_increment = -2*qgi->boundingRect().width();
}
if (((elmt_right >= m_scene->sceneRect().right() - qgi->boundingRect().right()) ||
(elmt_bottom >= m_scene->sceneRect().bottom() - qgi->boundingRect().bottom())) &&
if (((elmt_right >= m_diagram->sceneRect().right() - qgi->boundingRect().right()) ||
(elmt_bottom >= m_diagram->sceneRect().bottom() - qgi->boundingRect().bottom())) &&
(e->key()==Qt::Key_Right || e->key()==Qt::Key_Down)){
m_scene->adjustSceneRect();
m_diagram->adjustSceneRect();
}
h -> setValue(h -> value() + h_increment);
v -> setValue(v -> value() + v_increment);
@ -775,7 +789,7 @@ void DiagramView::scrollOnMovement(QKeyEvent *e){
*/
QString DiagramView::title() const {
QString view_title;
QString diagram_title(m_scene -> title());
QString diagram_title(m_diagram -> title());
if (diagram_title.isEmpty()) {
view_title = tr("Sans titre", "what to display for untitled diagrams");
} else {
@ -789,14 +803,14 @@ QString DiagramView::title() const {
* Edit the properties of the viewed digram
*/
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
*/
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
*/
bool DiagramView::hasCopiableItems() {
foreach(QGraphicsItem *qgi, m_scene -> selectedItems()) {
foreach(QGraphicsItem *qgi, m_diagram -> selectedItems()) {
if (
qgraphicsitem_cast<Element *>(qgi) ||
qgraphicsitem_cast<IndependentTextItem *>(qgi) ||
@ -821,7 +835,7 @@ bool DiagramView::hasCopiableItems() {
@return true if there is any Text Item selected
*/
bool DiagramView::hasTextItems() {
foreach(QGraphicsItem *qgi, m_scene -> selectedItems()) {
foreach(QGraphicsItem *qgi, m_diagram -> selectedItems()) {
if (
qgraphicsitem_cast<IndependentTextItem *>(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
peuvent etre supprimes, false sinon
* @brief DiagramView::hasDeletableItems
* @return True if a least on of selected item can be deleted
*/
bool DiagramView::hasDeletableItems() {
foreach(QGraphicsItem *qgi, m_scene -> selectedItems()) {
if (
qgraphicsitem_cast<Element *>(qgi) ||
qgraphicsitem_cast<Conductor *>(qgi) ||
qgraphicsitem_cast<IndependentTextItem *>(qgi) ||
qgraphicsitem_cast<QetShapeItem *>(qgi) ||
qgraphicsitem_cast<DiagramImageItem *>(qgi)
) {
return(true);
}
bool DiagramView::hasDeletableItems()
{
for(QGraphicsItem *qgi : m_diagram->selectedItems())
{
if (qgi->type() == Element::Type ||
qgi->type() == Conductor::Type ||
qgi->type() == IndependentTextItem::Type ||
qgi->type() == QetShapeItem::Type ||
qgi->type() == DiagramImageItem::Type ||
qgi->type() == DynamicElementTextItem::Type)
return true;
}
return(false);
}
@ -857,64 +871,55 @@ bool DiagramView::hasDeletableItems() {
Ajoute une colonne au schema.
*/
void DiagramView::addColumn() {
if (m_scene -> isReadOnly()) return;
BorderProperties old_bp = m_scene -> border_and_titleblock.exportBorder();
BorderProperties new_bp = m_scene -> border_and_titleblock.exportBorder();
if (m_diagram -> isReadOnly()) return;
BorderProperties old_bp = m_diagram -> border_and_titleblock.exportBorder();
BorderProperties new_bp = m_diagram -> border_and_titleblock.exportBorder();
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.
*/
void DiagramView::removeColumn() {
if (m_scene -> isReadOnly()) return;
BorderProperties old_bp = m_scene -> border_and_titleblock.exportBorder();
BorderProperties new_bp = m_scene -> border_and_titleblock.exportBorder();
if (m_diagram -> isReadOnly()) return;
BorderProperties old_bp = m_diagram -> border_and_titleblock.exportBorder();
BorderProperties new_bp = m_diagram -> border_and_titleblock.exportBorder();
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
*/
void DiagramView::addRow() {
if (m_scene -> isReadOnly()) return;
BorderProperties old_bp = m_scene -> border_and_titleblock.exportBorder();
BorderProperties new_bp = m_scene -> border_and_titleblock.exportBorder();
if (m_diagram -> isReadOnly()) return;
BorderProperties old_bp = m_diagram -> border_and_titleblock.exportBorder();
BorderProperties new_bp = m_diagram -> border_and_titleblock.exportBorder();
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
*/
void DiagramView::removeRow() {
if (m_scene -> isReadOnly()) return;
BorderProperties old_bp = m_scene -> border_and_titleblock.exportBorder();
BorderProperties new_bp = m_scene -> border_and_titleblock.exportBorder();
if (m_diagram -> isReadOnly()) return;
BorderProperties old_bp = m_diagram -> border_and_titleblock.exportBorder();
BorderProperties new_bp = m_diagram -> border_and_titleblock.exportBorder();
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
* Calcul and set the area of the scene visualized by this view
* The area are diagram sceneRect * 2.
*/
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);
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);
}
@ -931,9 +936,9 @@ void DiagramView::updateWindowTitle() {
void DiagramView::adjustGridToZoom() {
QRectF viewed_scene = viewedSceneRect();
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
m_scene->setDisplayGrid(false);
m_diagram->setDisplayGrid(false);
}
/**
@ -965,7 +970,7 @@ bool DiagramView::mustIntegrateTitleBlockTemplate(const TitleBlockTemplateLocati
QETProject *tbt_parent_project = tbt_loc.parentProject();
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
*/
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);
setAcceptDrops(is_writable);
}
@ -985,7 +990,7 @@ void DiagramView::applyReadOnly() {
*/
void DiagramView::editSelectionProperties() {
// get selection
DiagramContent selection = m_scene -> selectedContent();
DiagramContent selection = m_diagram -> selectedContent();
// if selection contains nothing return
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())
selection.conductors().first()->editProperty();
// edit element
else if (selection.elements.size())
selection.elements.toList().first() -> editProperty();
else if (selection.m_elements.size())
selection.m_elements.toList().first() -> editProperty();
}
else {
@ -1022,7 +1027,7 @@ void DiagramView::editSelectionProperties() {
*/
void DiagramView::editSelectedConductorColor() {
// 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)
QList<Conductor *> selected_conductors = selection.conductors(DiagramContent::AnyConductor | DiagramContent::SelectedOnly);
@ -1037,7 +1042,7 @@ void DiagramView::editSelectedConductorColor() {
*/
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
ConductorProperties initial_properties = edited_conductor -> properties();
@ -1073,9 +1078,9 @@ void DiagramView::editConductorColor(Conductor *edited_conductor)
Reinitialise le profil des conducteurs selectionnes
*/
void DiagramView::resetConductors() {
if (m_scene -> isReadOnly()) return;
if (m_diagram -> isReadOnly()) return;
// 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)
QHash<Conductor *, ConductorProfilesGroup> conductors_and_profiles;
@ -1092,7 +1097,7 @@ void DiagramView::resetConductors() {
}
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() {
return(
m_scene -> hasFocus() &&
m_scene -> focusItem() &&
m_scene -> focusItem() -> isSelected()
m_diagram -> hasFocus() &&
m_diagram -> focusItem() &&
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
*/
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
//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
*/
void DiagramView::contextMenuEvent(QContextMenuEvent *e) {
if (QGraphicsItem *qgi = m_scene -> itemAt(mapToScene(e -> pos()), transform())) {
if (!qgi -> isSelected()) m_scene -> clearSelection();
if (QGraphicsItem *qgi = m_diagram -> itemAt(mapToScene(e -> pos()), transform())) {
if (!qgi -> isSelected()) m_diagram -> clearSelection();
qgi -> setSelected(true);
}
if (QETDiagramEditor *qde = diagramEditor()) {
context_menu -> clear();
if (m_scene -> selectedItems().isEmpty()) {
paste_here_pos = e -> pos();
paste_here -> setEnabled(Diagram::clipboardMayContainDiagram());
context_menu -> addAction(paste_here);
context_menu -> addSeparator();
context_menu -> addAction(qde -> infos_diagram);
context_menu -> addActions(qde -> m_row_column_actions_group.actions());
m_context_menu -> clear();
if (m_diagram -> selectedItems().isEmpty()) {
m_paste_here_pos = e -> pos();
m_paste_here -> setEnabled(Diagram::clipboardMayContainDiagram());
m_context_menu -> addAction(m_paste_here);
m_context_menu -> addSeparator();
m_context_menu -> addAction(qde -> infos_diagram);
m_context_menu -> addActions(qde -> m_row_column_actions_group.actions());
} else {
context_menu -> addAction(qde -> cut);
context_menu -> addAction(qde -> copy);
context_menu -> addSeparator();
context_menu -> addAction(qde -> conductor_reset);
context_menu -> addSeparator();
context_menu -> addActions(qde -> m_selection_actions_group.actions());
m_context_menu -> addAction(qde -> m_cut);
m_context_menu -> addAction(qde -> m_copy);
m_context_menu -> addSeparator();
m_context_menu -> addAction(qde -> m_conductor_reset);
m_context_menu -> addSeparator();
m_context_menu -> addActions(qde -> m_selection_actions_group.actions());
}
// affiche le menu contextuel
context_menu -> popup(e -> globalPos());
m_context_menu -> popup(e -> globalPos());
}
e -> accept();
}
@ -1280,7 +1285,7 @@ void DiagramView::mouseDoubleClickEvent(QMouseEvent *e)
{
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
QPointF click_pos = viewportTransform().inverted().map(e -> pos());

View File

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

View File

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

View File

@ -19,15 +19,12 @@
#include "elementtextitem.h"
#include "diagram.h"
#include "QPropertyUndoCommand/qpropertyundocommand.h"
#include "dynamicelementtextitem.h"
/**
* @brief ElementTextsMover::ElementTextsMover
*/
ElementTextsMover::ElementTextsMover() :
movement_running_(false),
diagram_(nullptr),
movement_driver_(nullptr)
{}
ElementTextsMover::ElementTextsMover() {}
/**
* @brief ElementTextsMover::isReady
@ -35,7 +32,7 @@ ElementTextsMover::ElementTextsMover() :
* False if this ElementTextsMover is actually process a movement
*/
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)
{
if (movement_running_ || !diagram) return(-1);
if (m_movement_running || !diagram) return(-1);
diagram_ = diagram;
movement_driver_ = driver_item;
m_diagram = diagram;
m_movement_driver = driver_item;
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);
m_texts_item_H.insert(eti, eti->pos());
DiagramTextItem *dti = static_cast<DiagramTextItem *> (item);
m_texts_item_H.insert(dti, dti->pos());
}
}
if (!m_texts_item_H.size()) return(-1);
movement_running_ = true;
m_movement_running = true;
return(m_texts_item_H.size());
}
@ -77,11 +74,12 @@ int ElementTextsMover::beginMovement(Diagram *diagram, QGraphicsItem *driver_ite
*/
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)
continue;
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()
{
//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
ElementTextItem *eti = m_texts_item_H.keys().first();
if (eti->pos() == m_texts_item_H.value(eti)) return;
DiagramTextItem *dti = m_texts_item_H.keys().first();
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(eti, "pos", m_texts_item_H.value(eti), eti->pos(), undo);
QPropertyUndoCommand *child_undo = new QPropertyUndoCommand(dti, "pos", m_texts_item_H.value(dti), dti->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>
class QGraphicsItem;
class ElementTextItem;
class DiagramTextItem;
class Diagram;
/**
@ -38,14 +38,14 @@ class ElementTextsMover
public:
bool isReady() const;
int beginMovement(Diagram *, QGraphicsItem * = 0);
int beginMovement(Diagram *diagram, QGraphicsItem *driver_item = nullptr);
void continueMovement(const QPointF &);
void endMovement();
private:
bool movement_running_;
Diagram *diagram_;
QGraphicsItem *movement_driver_;
QHash <ElementTextItem *, QPointF> m_texts_item_H;
bool m_movement_running = false;
Diagram *m_diagram = nullptr;
QGraphicsItem *m_movement_driver = nullptr;
QHash <DiagramTextItem *, QPointF> m_texts_item_H;
};
#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
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;
if (elements_count) {
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",
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 (!text.isEmpty()) text += ", ";
text += QObject::tr(
"%n conducteur(s)",
"part of a sentence listing the content of a diagram",
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 (!text.isEmpty()) text += ", ";
text += QObject::tr(
"%n champ(s) de texte",
"part of a sentence listing the content of a diagram",
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 (!text.isEmpty()) text += ", ";
text += QObject::tr(
"%n image(s)",
"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 (!text.isEmpty()) text += ", ";
text += QObject::tr(
"%n forme(s)",
"part of a sentence listing the content of a diagram",
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);
}

View File

@ -143,7 +143,7 @@ namespace QET {
bool orthogonalProjection(const QPointF &, const QLineF &, QPointF * = 0);
bool attributeIsAnInteger(const QDomElement &, QString , int * = 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 &, const QString &);
QList<QChar> forbiddenCharacters();

View File

@ -42,6 +42,9 @@
#include "diagrameventaddtext.h"
#include "elementscollectionwidget.h"
#include "autonumberingdockwidget.h"
#include "dynamicelementtextitem.h"
#include "conductortextitem.h"
#include "elementtextitem.h"
#include <QMessageBox>
#include <QStandardPaths>
@ -242,24 +245,24 @@ void QETDiagramEditor::setUpActions()
redo -> setStatusTip(tr("Restaure l'action annulée", "status bar tip"));
//cut copy past action
cut = new QAction(QET::Icons::EditCut, tr("Co&uper"), this);
copy = new QAction(QET::Icons::EditCopy, tr("Cop&ier"), this);
m_cut = new QAction(QET::Icons::EditCut, tr("Co&uper"), this);
m_copy = new QAction(QET::Icons::EditCopy, tr("Cop&ier"), this);
paste = new QAction(QET::Icons::EditPaste, tr("C&oller"), this);
cut -> setShortcut(QKeySequence::Cut);
copy -> setShortcut(QKeySequence::Copy);
m_cut -> setShortcut(QKeySequence::Cut);
m_copy -> setShortcut(QKeySequence::Copy);
paste -> setShortcut(QKeySequence::Paste);
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_cut -> setStatusTip(tr("Transfère 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"));
connect(cut, SIGNAL(triggered()), this, SLOT(slot_cut()));
connect(copy, SIGNAL(triggered()), this, SLOT(slot_copy()));
connect(m_cut, SIGNAL(triggered()), this, SLOT(slot_cut()));
connect(m_copy, SIGNAL(triggered()), this, SLOT(slot_copy()));
connect(paste, SIGNAL(triggered()), this, SLOT(slot_paste()));
conductor_reset = new QAction(QET::Icons::ConductorSettings, tr("Réinitialiser les conducteurs"), this);
conductor_reset -> setShortcut( QKeySequence( tr("Ctrl+K") ) );
m_conductor_reset = new QAction(QET::Icons::ConductorSettings, tr("Réinitialiser les conducteurs"), this);
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 -> 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);
//Selections Actions (related to a selected item)
delete_selection = m_selection_actions_group.addAction( QET::Icons::EditDelete, tr("Supprimer") );
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") );
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_delete_selection = m_selection_actions_group.addAction( QET::Icons::EditDelete, tr("Supprimer") );
m_rotate_selection = m_selection_actions_group.addAction( QET::Icons::ObjectRotateRight, tr("Pivoter") );
m_rotate_texts = m_selection_actions_group.addAction( QET::Icons::ObjectRotateRight, tr("Orienter les textes") );
m_find_element = m_selection_actions_group.addAction( tr("Retrouver dans le panel") );
m_edit_selection = m_selection_actions_group.addAction( QET::Icons::ElementEdit, tr("Éditer l'item sélectionné") );
delete_selection -> setShortcut( QKeySequence::Delete);
rotate_selection -> setShortcut( QKeySequence( tr("Space") ) );
rotate_texts -> setShortcut( QKeySequence( tr("Ctrl+Space") ) );
edit_selection -> setShortcut( QKeySequence( tr("Ctrl+E") ) );
m_delete_selection -> setShortcut( QKeySequence::Delete);
m_rotate_selection -> setShortcut( QKeySequence( tr("Space") ) );
m_rotate_texts -> setShortcut( QKeySequence( tr("Ctrl+Space") ) );
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"));
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"));
find_element -> setStatusTip( tr("Retrouve l'élément sélectionné dans le panel", "status bar tip"));
m_delete_selection -> setStatusTip( tr("Enlève les éléments sélectionnés du folio", "status bar tip"));
m_rotate_selection -> setStatusTip( tr("Pivote les éléments et textes sélectionnés", "status bar tip"));
m_rotate_texts -> setStatusTip( tr("Pivote les textes sélectionnés à un angle précis", "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");
rotate_selection ->setData("rotate_selection");
rotate_texts ->setData("rotate_selected_text");
find_element ->setData("find_selected_element");
edit_selection ->setData("edit_selected_element");
m_delete_selection ->setData("delete_selection");
m_rotate_selection ->setData("rotate_selection");
m_rotate_texts ->setData("rotate_selected_text");
m_find_element ->setData("find_selected_element");
m_edit_selection ->setData("edit_selected_element");
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"));
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"));
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"));
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(next_window, SIGNAL(triggered()), &workspace, SLOT(activateNextSubWindow()) );
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()));
}
@ -526,12 +529,12 @@ void QETDiagramEditor::setUpToolBar() {
main_bar -> addAction(undo);
main_bar -> addAction(redo);
main_bar -> addSeparator();
main_bar -> addAction(cut);
main_bar -> addAction(copy);
main_bar -> addAction(m_cut);
main_bar -> addAction(m_copy);
main_bar -> addAction(paste);
main_bar -> addSeparator();
main_bar -> addAction(delete_selection);
main_bar -> addAction(rotate_selection);
main_bar -> addAction(m_delete_selection);
main_bar -> addAction(m_rotate_selection);
// Modes selection / visualisation et zoom
view_bar -> addAction(mode_selection);
@ -543,7 +546,7 @@ void QETDiagramEditor::setUpToolBar() {
view_bar -> addActions(m_zoom_action_toolBar);
diagram_bar -> addAction (infos_diagram);
diagram_bar -> addAction (conductor_reset);
diagram_bar -> addAction (m_conductor_reset);
diagram_bar -> addAction (m_auto_conductor);
m_add_item_toolBar = new QToolBar(tr("Ajouter"), this);
@ -592,15 +595,15 @@ void QETDiagramEditor::setUpMenu() {
menu_edition -> addAction(undo);
menu_edition -> addAction(redo);
menu_edition -> addSeparator();
menu_edition -> addAction(cut);
menu_edition -> addAction(copy);
menu_edition -> addAction(m_cut);
menu_edition -> addAction(m_copy);
menu_edition -> addAction(paste);
menu_edition -> addSeparator();
menu_edition -> addActions(m_select_actions_group.actions());
menu_edition -> addSeparator();
menu_edition -> addActions(m_selection_actions_group.actions());
menu_edition -> addSeparator();
menu_edition -> addAction(conductor_reset);
menu_edition -> addAction(m_conductor_reset);
menu_edition -> addSeparator();
menu_edition -> addAction(infos_diagram);
menu_edition -> addActions(m_row_column_actions_group.actions());
@ -1039,7 +1042,7 @@ Element *QETDiagramEditor::currentElement() const {
DiagramView *dv = currentDiagram();
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);
return(selected_elements.first());
@ -1383,76 +1386,90 @@ void QETDiagramEditor::slot_updateUndoStack()
* Manage the actions who need some conditions to be enable or not.
* This method does nothing if there is no project opened
*/
void QETDiagramEditor::slot_updateComplexActions() {
void QETDiagramEditor::slot_updateComplexActions()
{
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
int selected_conductors_count = dv ? dv -> diagram() -> selectedConductors().count() : 0;
conductor_reset -> setEnabled(editable_diagram && selected_conductors_count);
int selected_conductors_count = diagram_->selectedConductors().count();
m_conductor_reset->setEnabled(!ro && selected_conductors_count);
// number of selected elements
int selected_elements_count = dv ? dv -> diagram() -> selectedContent().count(DiagramContent::Elements) : 0;
find_element -> setEnabled(selected_elements_count == 1);
int selected_elements_count = diagram_->selectedContent().count(DiagramContent::Elements);
m_find_element->setEnabled(selected_elements_count == 1);
//Action that need items (elements, conductors, texts...) selected, to be enabled
bool copiable_items = dv ? (dv -> hasCopiableItems()) : false;
bool deletable_items = dv ? (dv -> hasDeletableItems()) : false;
cut -> setEnabled(editable_diagram && copiable_items);
copy -> setEnabled(copiable_items);
delete_selection -> setEnabled(editable_diagram && deletable_items);
rotate_selection -> setEnabled(editable_diagram && dv -> diagram() -> canRotateSelection());
bool copiable_items = dv->hasCopiableItems();
bool deletable_items = dv->hasDeletableItems();
m_cut -> setEnabled(!ro && copiable_items);
m_copy -> setEnabled(copiable_items);
m_delete_selection -> setEnabled(!ro && deletable_items);
m_rotate_selection -> setEnabled(!ro && diagram_->canRotateSelection());
//Action that need selected texts
int selected_texts = dv ? (dv -> diagram() -> selectedTexts().count()) : 0;
int selected_conductor_texts = dv ? (dv -> diagram() -> selectedConductorTexts().count()) : 0;
int selected_element_texts = dv ? (dv -> diagram() -> selectedElementTexts().count()) : 0;
rotate_texts -> setEnabled(editable_diagram && selected_texts);
int selected_texts = diagram_->selectedTexts().count();
int selected_conductor_texts = 0; for(DiagramTextItem *dti : diagram_->selectedTexts()) {if(dti->type() == ConductorTextItem::Type) selected_conductor_texts++;}
int selected_element_texts = 0; for(DiagramTextItem *dti : diagram_->selectedTexts()) {if(dti->type() == ElementTextItem::Type) selected_element_texts++;}
int selected_dynamic_elmt_text = 0; for(DiagramTextItem *dti : diagram_->selectedTexts()) {if(dti->type() == DynamicElementTextItem::Type) selected_dynamic_elmt_text++;}
m_rotate_texts -> setEnabled(!ro && selected_texts);
// 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 +
(selected_texts - selected_conductor_texts - selected_element_texts) +
(selected_texts - selected_conductor_texts - selected_element_texts - selected_dynamic_elmt_text) +
selected_image +
selected_shape +
selected_conductors_count;
if (selected_editable == 1)
{
edit_selection -> setEnabled(true);
m_edit_selection -> setEnabled(true);
//edit element
if (selected_elements_count)
{
edit_selection -> setText(tr("Éditer l'élement", "edit element"));
edit_selection -> setIcon(QET::Icons::ElementEdit);
m_edit_selection -> setText(tr("Éditer l'élement", "edit element"));
m_edit_selection -> setIcon(QET::Icons::ElementEdit);
}
//edit text field
else if (selected_texts)
{
edit_selection -> setText(tr("Éditer le champ de texte", "edit text field"));
edit_selection -> setIcon(QET::Icons::EditText);
m_edit_selection -> setText(tr("Éditer le champ de texte", "edit text field"));
m_edit_selection -> setIcon(QET::Icons::EditText);
}
//edit image
else if (selected_image)
{
edit_selection -> setText(tr("Éditer l'image", "edit image"));
edit_selection -> setIcon(QET::Icons::resize_image);
m_edit_selection -> setText(tr("Éditer l'image", "edit image"));
m_edit_selection -> setIcon(QET::Icons::resize_image);
}
//edit conductor
else if (selected_conductors_count)
{
edit_selection -> setText(tr("Éditer le conducteur", "edit conductor"));
edit_selection -> setIcon(QET::Icons::ElementEdit);
m_edit_selection -> setText(tr("Éditer le conducteur", "edit conductor"));
m_edit_selection -> setIcon(QET::Icons::ElementEdit);
}
}
//not an editable item
else
{
edit_selection -> setText(tr("Éditer l'objet sélectionné", "edit selected item"));
edit_selection -> setIcon(QET::Icons::ElementEdit);
edit_selection -> setEnabled(false);
m_edit_selection -> setText(tr("Éditer l'objet sélectionné", "edit selected item"));
m_edit_selection -> setIcon(QET::Icons::ElementEdit);
m_edit_selection -> setEnabled(false);
}
}

View File

@ -174,9 +174,9 @@ class QETDiagramEditor : public QETMainWindow {
QAction *redo; ///< Redo the latest cancelled operation
public:
QAction *infos_diagram; ///< Show a dialog to edit diagram properties
QAction *conductor_reset; ///< Reset paths of selected conductors
QAction *cut; ///< Cut selection to clipboard
QAction *copy; ///< Copy selection to clipboard
QAction *m_conductor_reset; ///< Reset paths of selected conductors
QAction *m_cut; ///< Cut selection to clipboard
QAction *m_copy; ///< Copy selection to clipboard
private:
QAction *paste; ///< Paste clipboard content on the current diagram
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 *prev_window; ///< Switch to the previous 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...)
@ -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_selection_actions_group; ///Action related to edit a selected item
private:
QAction *delete_selection; ///< Delete selection
QAction *rotate_selection; ///< Rotate selected elements and text items by 90 degrees
QAction *rotate_texts; ///< Direct selected text items to a specific angle
QAction *find_element; ///< Find the selected element in the panel
QAction *m_delete_selection; ///< Delete selection
QAction *m_rotate_selection; ///< Rotate selected elements and text items by 90 degrees
QAction *m_rotate_texts; ///< Direct selected text items to a specific angle
QAction *m_find_element; ///< Find the selected element in the panel
QActionGroup m_file_actions_group; ///Actions related to file (open, close, save...)
QAction *close_file; ///< Close current project file

View File

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

View File

@ -33,6 +33,13 @@ class DiagramTextItem : public QGraphicsTextItem
{
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:
DiagramTextItem(QGraphicsItem * = 0);
DiagramTextItem(const QString &, QGraphicsItem * = 0);
@ -42,7 +49,7 @@ class DiagramTextItem : public QGraphicsTextItem
public:
enum { Type = UserType + 1004 };
virtual int type() const { return Type; }
virtual int type() const override { return Type; }
Diagram *diagram() const;
virtual void fromXml(const QDomElement &) = 0;
@ -57,35 +64,43 @@ class DiagramTextItem : public QGraphicsTextItem
QPointF mapMovementToParent (const QPointF &) const;
QPointF mapMovementFromParent (const QPointF &) const;
void setFontSize(int &s);
void setNoEditable(bool e = true) {no_editable = e;}
void setFontSize(int s);
int fontSize()const;
void setColor(QColor color);
QColor color() const;
void setNoEditable(bool e = true) {m_no_editable = e;}
protected:
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
virtual void focusInEvent(QFocusEvent *);
virtual void focusOutEvent(QFocusEvent *);
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) override;
virtual void focusInEvent(QFocusEvent *) override;
virtual void focusOutEvent(QFocusEvent *) override;
virtual void mouseDoubleClickEvent (QGraphicsSceneMouseEvent *event);
virtual void mousePressEvent (QGraphicsSceneMouseEvent *event);
virtual void mouseMoveEvent (QGraphicsSceneMouseEvent *event);
virtual void mouseReleaseEvent (QGraphicsSceneMouseEvent *event);
virtual void mouseDoubleClickEvent (QGraphicsSceneMouseEvent *event) override;
virtual void mousePressEvent (QGraphicsSceneMouseEvent *event) override;
virtual void mouseMoveEvent (QGraphicsSceneMouseEvent *event) override;
virtual void mouseReleaseEvent (QGraphicsSceneMouseEvent *event) override;
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *);
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *);
virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *);
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *) override;
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *) override;
virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *) override;
virtual void applyRotation(const qreal &);
signals:
/// signal emitted after text was changed
void diagramTextChanged(DiagramTextItem *, const QString &, const QString &);
void textEdited(const QString &old_str, const QString &new_str);
protected:
bool m_mouse_hover;
QString previous_text_;
qreal rotation_angle_;
bool no_editable;
bool m_first_move;
bool m_mouse_hover = false,
m_first_move = true,
m_no_editable;
QString m_previous_html_text,
m_previous_text;
qreal m_rotation_angle;
QPointF m_mouse_to_origin_movement;
};
#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 "diagramcontext.h"
#include "changeelementinformationcommand.h"
#include "dynamicelementtextitem.h"
class ElementXmlRetroCompatibility
{
@ -77,7 +78,9 @@ Element::Element(QGraphicsItem *parent) :
/**
Destructeur
*/
Element::~Element() {
Element::~Element()
{
qDeleteAll(m_dynamic_text_list);
}
void Element::editProperty()
@ -529,6 +532,15 @@ bool Element::fromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr, bool
} else {
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);
}
@ -615,9 +627,54 @@ QDomElement Element::toXml(QDomDocument &document, QHash<Terminal *, int> &table
element.appendChild(infos);
}
//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;
}
/**
* @brief Element::AlignedFreeTerminals
* @return a list of terminal (owned by this element) aligned to other terminal (from other element)

View File

@ -30,6 +30,7 @@ class Terminal;
class Conductor;
class NumerotationContext;
class DiagramTextItem;
class DynamicElementTextItem;
/**
This is the base class for electrical elements.
@ -158,9 +159,6 @@ class Element : public QetGraphicsItem
bool m_freeze_label = false;
QString m_F_str;
/**
Draw this element
*/
public:
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *) = 0;
/// @return This element type ID
@ -197,6 +195,10 @@ class Element : public QetGraphicsItem
// orientation-related methods
int orientation() const;
void addDynamicTextItem(DynamicElementTextItem *deti = nullptr);
void removeDynamicTextItem(DynamicElementTextItem *deti);
QList<DynamicElementTextItem *> dynamicTextItems() const;
protected:
void drawAxes(QPainter *, const QStyleOptionGraphicsItem *);
@ -216,6 +218,7 @@ class Element : public QetGraphicsItem
private:
bool m_mouse_over;
QString m_prefix;
QList <DynamicElementTextItem *> m_dynamic_text_list;
};

View File

@ -23,6 +23,7 @@
#include "imagepropertieswidget.h"
#include "qetshapeitem.h"
#include "shapegraphicsitempropertieswidget.h"
#include "dynamicelementtextitem.h"
/**
* @brief DiagramPropertiesEditorDockWidget::DiagramPropertiesEditorDockWidget
@ -56,7 +57,7 @@ void DiagramPropertiesEditorDockWidget::setDiagram(Diagram *diagram)
if (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()));
selectionChanged();
}
@ -120,6 +121,22 @@ void DiagramPropertiesEditorDockWidget::selectionChanged()
addEditor(new ShapeGraphicsItemPropertiesWidget(static_cast<QetShapeItem*>(item), this));
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:
m_edited_qgi_type = -1;
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 "diagramposition.h"
#include "qeticons.h"
#include "dynamicelementtextitemeditor.h"
#include <QVBoxLayout>
#include <QLabel>
@ -203,9 +204,10 @@ void ElementPropertiesWidget::updateUi()
default:
break;
}
m_list_editor << new DynamicElementTextItemEditor(m_element, this);
//Add each editors in tab widget
foreach (AbstractElementPropertiesEditorWidget *aepew, m_list_editor)
for (AbstractElementPropertiesEditorWidget *aepew : m_list_editor)
{
aepew->setLiveEdit(m_live_edit);
m_tab->addTab(aepew, aepew->title());

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