Element editor : dynamic text item can be added directly from the element editor (WIP)

git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@5046 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
blacksun 2017-09-25 17:44:02 +00:00
parent 0c01bc4406
commit aa5241896c
17 changed files with 1355 additions and 249 deletions

View File

@ -22,6 +22,7 @@ part terminal + 1106
part text + 1107
part text field + 1108
part rectangle + 1109
part dynamic text field + 1110
###QetGraphicsHandlerItem###
QetGraphicsHandlerItem = 1200

View File

@ -33,6 +33,7 @@
#include "ui/elementpropertieseditorwidget.h"
#include "eseventinterface.h"
#include "QetGraphicsItemModeler/qetgraphicshandleritem.h"
#include "partdynamictextfield.h"
#include <algorithm>
#include <QKeyEvent>
@ -395,33 +396,25 @@ QRectF ElementScene::boundingRectFromXml(const QDomDocument &xml_document) {
il sera rempli avec le contenu ajoute a l'element par le fromXml
@return true si l'import a reussi, false sinon
*/
void ElementScene::fromXml(
const QDomDocument &xml_document,
const QPointF &position,
bool consider_informations,
ElementContent *content_ptr
) {
QString error_message;
void ElementScene::fromXml(const QDomDocument &xml_document, const QPointF &position, bool consider_informations, ElementContent *content_ptr)
{
bool state = true;
// prend en compte les informations de l'element
//Consider the informations of the element
if (consider_informations) {
state = applyInformations(xml_document, &error_message);
state = applyInformations(xml_document);
}
// parcours des enfants de la definition : parties de l'element
if (state) {
ElementContent loaded_content = loadContent(xml_document, &error_message);
if (position != QPointF()) {
addContentAtPos(loaded_content, position, &error_message);
} else {
addContent(loaded_content, &error_message);
}
if (state)
{
ElementContent loaded_content = loadContent(xml_document);
if (position != QPointF())
addContentAtPos(loaded_content, position);
else
addContent(loaded_content);
// renvoie le contenu ajoute a l'element
if (content_ptr) {
if (content_ptr)
*content_ptr = loaded_content;
}
}
}
@ -433,9 +426,10 @@ void ElementScene::fromXml(
QRectF ElementScene::elementSceneGeometricRect() const{
QRectF esgr;
foreach (QGraphicsItem *qgi, items()) {
if (qgi -> type() == ElementPrimitiveDecorator::Type) continue;
if (qgi -> type() == QGraphicsRectItem::Type) continue;
if (qgi -> type() == PartTextField::Type) continue;
if (qgi->type() == ElementPrimitiveDecorator::Type) continue;
if (qgi->type() == QGraphicsRectItem::Type) continue;
if (qgi->type() == PartTextField::Type) continue;
if (qgi->type() == PartDynamicTextField::Type) continue;
if (CustomElementPart *cep = dynamic_cast <CustomElementPart*> (qgi)) {
esgr |= cep -> sceneGeometricRect();
}
@ -869,20 +863,16 @@ QRectF ElementScene::elementContentBoundingRect(const ElementContent &content) c
Applique les informations (dimensions, hostpot, orientations, connexions
internes, noms et informations complementaires) contenu dans un document XML.
@param xml_document Document XML a analyser
@param error_message pointeur vers une QString ; si error_message est
different de 0, un message d'erreur sera stocke dedans si necessaire
@return true si la lecture et l'application des informations s'est bien
passee, false sinon.
*/
bool ElementScene::applyInformations(const QDomDocument &xml_document, QString *error_message) {
// Root must be an element definition
bool ElementScene::applyInformations(const QDomDocument &xml_document)
{
// Root must be an element definition
QDomElement root = xml_document.documentElement();
if (root.tagName() != "definition" || root.attribute("type") != "element") {
if (error_message) {
*error_message = tr("Ce document XML n'est pas une définition d'élément.", "error message");
}
if (root.tagName() != "definition" || root.attribute("type") != "element")
return(false);
}
//Extract info about element type
m_elmt_type = root.attribute("link_type", "simple");
@ -912,30 +902,44 @@ bool ElementScene::applyInformations(const QDomDocument &xml_document, QString *
@param error_message pointeur vers une QString ; si error_message est
different de 0, un message d'erreur sera stocke dedans si necessaire
*/
ElementContent ElementScene::loadContent(const QDomDocument &xml_document, QString *error_message) {
/**
* @brief ElementScene::loadContent
* @param xml_document : xml dom document to analyze
* @return
*/
/**
* @brief ElementScene::loadContent
* Create and load the content describe in the xml document.
* @param xml_document
* @return the loaded content
*/
ElementContent ElementScene::loadContent(const QDomDocument &xml_document)
{
ElementContent loaded_parts;
// la racine est supposee etre une definition d'element
//The root is supposed to be an element definition
QDomElement root = xml_document.documentElement();
if (root.tagName() != "definition" || root.attribute("type") != "element") {
if (error_message) {
*error_message = tr("Ce document XML n'est pas une définition d'élément.", "error message");
}
return(loaded_parts);
}
// chargement de la description graphique de l'element
for (QDomNode node = root.firstChild() ; !node.isNull() ; node = node.nextSibling()) {
if (root.tagName() != "definition" || root.attribute("type") != "element")
return(loaded_parts);
//Load the graphic description of the element
for (QDomNode node = root.firstChild() ; !node.isNull() ; node = node.nextSibling())
{
QDomElement elmts = node.toElement();
if (elmts.isNull()) continue;
if (elmts.tagName() == "description") {
// = parcours des differentes parties du dessin
if (elmts.isNull())
continue;
if (elmts.tagName() == "description")
{
int z = 1;
for (QDomNode n = node.firstChild() ; !n.isNull() ; n = n.nextSibling()) {
for (QDomNode n = node.firstChild() ; !n.isNull() ; n = n.nextSibling())
{
QDomElement qde = n.toElement();
if (qde.isNull()) continue;
CustomElementPart *cep;
if (qde.isNull())
continue;
CustomElementPart *cep = nullptr;
if (qde.tagName() == "line") cep = new PartLine (m_element_editor);
else if (qde.tagName() == "rect") cep = new PartRectangle(m_element_editor);
else if (qde.tagName() == "ellipse") cep = new PartEllipse (m_element_editor);
@ -945,12 +949,19 @@ ElementContent ElementScene::loadContent(const QDomDocument &xml_document, QStri
else if (qde.tagName() == "text") cep = new PartText (m_element_editor);
else if (qde.tagName() == "input") cep = new PartTextField(m_element_editor);
else if (qde.tagName() == "arc") cep = new PartArc (m_element_editor);
else if (qde.tagName() == "dynamic_text") cep = new PartDynamicTextField (m_element_editor);
else continue;
if (QGraphicsItem *qgi = dynamic_cast<QGraphicsItem *>(cep)) {
if (!qgi -> zValue()) qgi -> setZValue(z++);
loaded_parts << qgi;
if (QGraphicsItem *qgi = dynamic_cast<QGraphicsItem *>(cep))
{
if (!qgi->zValue())
qgi->setZValue(z++);
loaded_parts<<qgi;
cep->fromXml(qde);
}
cep -> fromXml(qde);
else
delete cep;
}
}
}
@ -961,12 +972,9 @@ ElementContent ElementScene::loadContent(const QDomDocument &xml_document, QStri
/**
Ajoute le contenu content a cet element
@param content contenu ( = liste de parties) a charger
@param error_message pointeur vers une QString ; si error_message est
different de 0, un message d'erreur sera stocke dedans si necessaire
@return Le contenu ajoute
*/
ElementContent ElementScene::addContent(const ElementContent &content, QString *error_message) {
Q_UNUSED(error_message);
ElementContent ElementScene::addContent(const ElementContent &content) {
foreach(QGraphicsItem *part, content) {
addPrimitive(part);
}
@ -977,12 +985,9 @@ ElementContent ElementScene::addContent(const ElementContent &content, QString *
Ajoute le contenu content a cet element
@param content contenu ( = liste de parties) a charger
@param pos Position du coin superieur gauche du contenu apres avoir ete ajoute
@param error_message pointeur vers une QString ; si error_message est
different de 0, un message d'erreur sera stocke dedans si necessaire
@return Le contenu ajoute
*/
ElementContent ElementScene::addContentAtPos(const ElementContent &content, const QPointF &pos, QString *error_message) {
Q_UNUSED(error_message);
ElementContent ElementScene::addContentAtPos(const ElementContent &content, const QPointF &pos) {
// calcule le boundingRect du contenu a ajouter
QRectF bounding_rect = elementContentBoundingRect(content);

View File

@ -141,10 +141,10 @@ class ElementScene : public QGraphicsScene
private:
QRectF elementContentBoundingRect(const ElementContent &) const;
bool applyInformations(const QDomDocument &, QString * = nullptr);
ElementContent loadContent(const QDomDocument &, QString * = nullptr);
ElementContent addContent(const ElementContent &, QString * = nullptr);
ElementContent addContentAtPos(const ElementContent &, const QPointF &, QString * = nullptr);
bool applyInformations(const QDomDocument &);
ElementContent loadContent(const QDomDocument &);
ElementContent addContent(const ElementContent &);
ElementContent addContentAtPos(const ElementContent &, const QPointF &);
void addPrimitive(QGraphicsItem *);
void initPasteArea();
static bool zValueLessThan(QGraphicsItem *, QGraphicsItem *);

View File

@ -0,0 +1,82 @@
/*
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 "eseventadddynamictextfield.h"
#include "elementscene.h"
#include "editorcommands.h"
#include "partdynamictextfield.h"
#include <QUndoStack>
/**
* @brief ESEventAddDynamicTextField::ESEventAddDynamicTextField
* @param scene
*/
ESEventAddDynamicTextField::ESEventAddDynamicTextField(ElementScene *scene) :
ESEventInterface(scene)
{
m_text = new PartDynamicTextField(m_editor);
m_scene->addItem(m_text);
m_running = true;
}
/**
* @brief ESEventAddDynamicTextField::~ESEventAddDynamicTextField
*/
ESEventAddDynamicTextField::~ESEventAddDynamicTextField() {
delete m_text;
}
/**
* @brief ESEventAddDynamicTextField::mouseMoveEvent
* @param event
* @return
*/
bool ESEventAddDynamicTextField::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
QPointF pos = m_scene->snapToGrid(event->scenePos());
updateHelpCross(pos);
m_text->setPos(pos);
return true;
}
/**
* @brief ESEventAddDynamicTextField::mouseReleaseEvent
* @param event
* @return
*/
bool ESEventAddDynamicTextField::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
{
m_scene->undoStack().push(new AddPartCommand(QObject::tr("Champ texte dynamique"), m_scene, m_text));
//Set new text
m_text = new PartDynamicTextField(m_editor);
m_scene->addItem(m_text);
m_text->setPos(m_scene->snapToGrid(event->scenePos()));
return true;
}
else if (event->button() == Qt::RightButton)
{
m_running = false;
return true;
}
return false;
}

View File

@ -0,0 +1,44 @@
/*
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 ESEVENTADDDYNAMICTEXTFIELD_H
#define ESEVENTADDDYNAMICTEXTFIELD_H
#include "eseventinterface.h"
class ElementScene;
class PartDynamicTextField;
class QGraphicsSceneMouseEvent;
/**
* @brief The ESEventAddDynamicTextField class
* This ESEvent manage creation of dynamic text field in an ElementScene
*/
class ESEventAddDynamicTextField : public ESEventInterface
{
public:
ESEventAddDynamicTextField(ElementScene *scene);
~ESEventAddDynamicTextField() override;
bool mouseMoveEvent (QGraphicsSceneMouseEvent *event) override;
bool mouseReleaseEvent (QGraphicsSceneMouseEvent *event) override;
private:
PartDynamicTextField *m_text;
};
#endif // ESEVENTADDDYNAMICTEXTFIELD_H

View File

@ -0,0 +1,369 @@
/*
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 "partdynamictextfield.h"
#include "QPropertyUndoCommand/qpropertyundocommand.h"
#include "qetapp.h"
#include "elementscene.h"
#include <QGraphicsSceneMouseEvent>
#include <QFont>
#include <QColor>
/**
* @brief PartDynamicTextField::PartDynamicTextField
* @param editor
* @param parent
*/
PartDynamicTextField::PartDynamicTextField(QETElementEditor *editor, QGraphicsItem *parent) :
QGraphicsTextItem(parent),
CustomElementPart(editor),
m_uuid(QUuid::createUuid())
{
setFont(QETApp::diagramTextsFont(9));
setText("_");
setTextFrom(DynamicElementTextItem::UserText);
setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemSendsGeometryChanges | QGraphicsItem::ItemIsMovable);
}
QString PartDynamicTextField::name() const
{
return tr("Champ de texte dynamique", "element part name");
}
QString PartDynamicTextField::xmlName() const
{
return QString("dynamic_text");
}
/**
* @brief PartDynamicTextField::startUserTransformation
* @param initial_selection_rect
* Start the user-induced transformation, provided this primitive is contained
* within the initial_selection_rect bounding rectangle.
*/
void PartDynamicTextField::startUserTransformation(const QRectF &initial_selection_rect)
{
Q_UNUSED(initial_selection_rect)
m_saved_point = pos(); // scene coordinates, no need to mapFromScene()
}
/**
* @brief PartDynamicTextField::handleUserTransformation
* @param initial_selection_rect
* @param new_selection_rect
* Handle the user-induced transformation from initial_selection_rect to new_selection_rect
*/
void PartDynamicTextField::handleUserTransformation(const QRectF &initial_selection_rect, const QRectF &new_selection_rect)
{
QPointF new_pos = mapPoints(initial_selection_rect, new_selection_rect, QList<QPointF>() << m_saved_point).first();
setPos(new_pos);
}
/**
* @brief PartDynamicTextField::toXml
* @param document
* @return
*/
const QDomElement PartDynamicTextField::toXml(QDomDocument &dom_doc) const
{
QDomElement root_element = dom_doc.createElement(xmlName());
root_element.setAttribute("x", QString::number(pos().x()));
root_element.setAttribute("y", QString::number(pos().y()));
root_element.setAttribute("z", QString::number(zValue()));
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 = DynamicElementTextItem::textFromMetaEnum();
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);
//Info name
if(!m_info_name.isEmpty())
{
QDomElement dom_info_name = dom_doc.createElement("info_name");
dom_info_name.appendChild(dom_doc.createTextNode(m_info_name));
root_element.appendChild(dom_info_name);
}
//Composite text
if(!m_composite_text.isEmpty())
{
QDomElement dom_comp_text = dom_doc.createElement("composite_text");
dom_comp_text.appendChild(dom_doc.createTextNode(m_composite_text));
root_element.appendChild(dom_comp_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 PartDynamicTextField::fromXml
* @param element
*/
void PartDynamicTextField::fromXml(const QDomElement &dom_elmt)
{
if (dom_elmt.tagName() != xmlName()) {
qDebug() << "PartDynamicTextField::fromXml : Wrong tagg name";
return;
}
QGraphicsTextItem::setPos(dom_elmt.attribute("x", QString::number(0)).toDouble(),
dom_elmt.attribute("y", QString::number(0)).toDouble());
setZValue(dom_elmt.attribute("z", QString::number(zValue())).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 = DynamicElementTextItem::textFromMetaEnum();
m_text_from = DynamicElementTextItem::TextFrom(me.keyToValue(dom_elmt.attribute("text_from").toStdString().data()));
//Text
QDomElement dom_text = dom_elmt.firstChildElement("text");
if (!dom_text.isNull())
{
m_text = dom_text.text();
setPlainText(m_text);
}
//Info name
QDomElement dom_info_name = dom_elmt.firstChildElement("info_name");
if(!dom_info_name.isNull())
m_info_name = dom_info_name.text();
//Composite text
QDomElement dom_comp_text = dom_elmt.firstChildElement("composite_text");
if(!dom_comp_text.isNull())
m_composite_text = dom_comp_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 PartDynamicTextField::textFrom
* @return what the final text is created from.
*/
DynamicElementTextItem::TextFrom PartDynamicTextField::textFrom() const {
return m_text_from;
}
/**
* @brief PartDynamicTextField::setTextFrom
* Set the final text is created from.
* @param text_from
*/
void PartDynamicTextField::setTextFrom(DynamicElementTextItem::TextFrom text_from)
{
m_text_from = text_from;
emit textFromChanged(m_text_from);
}
/**
* @brief PartDynamicTextField::tagg
* @return the tagg of this text
*/
QString PartDynamicTextField::tagg() const {
return m_tagg;
}
/**
* @brief PartDynamicTextField::setTagg
* set the taggof this text
* @param tagg
*/
void PartDynamicTextField::setTagg(const QString &tagg)
{
m_tagg = tagg;
emit taggChanged(m_tagg);
}
/**
* @brief PartDynamicTextField::text
* @return the text of this text
*/
QString PartDynamicTextField::text() const {
return m_text;
}
/**
* @brief PartDynamicTextField::setText
* Set the text of this text
* @param text
*/
void PartDynamicTextField::setText(const QString &text)
{
m_text = text;
setPlainText(m_text);
emit textChanged(m_text);
}
void PartDynamicTextField::setInfoName(const QString &info_name)
{
m_info_name = info_name;
emit infoNameChanged(m_info_name);
}
/**
* @brief PartDynamicTextField::infoName
* @return the info name of this text
*/
QString PartDynamicTextField::infoName() const{
return m_info_name;
}
/**
* @brief PartDynamicTextField::setCompositeText
* Set the composite text of this text item to @text
* @param text
*/
void PartDynamicTextField::setCompositeText(const QString &text)
{
m_composite_text = text;
emit compositeTextChanged(m_composite_text);
}
/**
* @brief PartDynamicTextField::compositeText
* @return the composite text of this text
*/
QString PartDynamicTextField::compositeText() const{
return m_composite_text;
}
/**
* @brief PartDynamicTextField::setColor
* @param color set text color to color
*/
void PartDynamicTextField::setColor(QColor color)
{
setDefaultTextColor(color);
emit colorChanged(color);
}
/**
* @brief PartDynamicTextField::color
* @return The color of this text
*/
QColor PartDynamicTextField::color() const {
return defaultTextColor();
}
/**
* @brief PartDynamicTextField::setFontSize
* @param s
*/
void PartDynamicTextField::setFontSize(int s) {
setFont(QETApp::diagramTextsFont(s));
emit fontSizeChanged(s);
}
int PartDynamicTextField::fontSize() const {
return font().pointSize();
}
/**
* @brief PartDynamicTextField::mouseMoveEvent
* @param event
*/
void PartDynamicTextField::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
if((event->buttons() & Qt::LeftButton) && (flags() & QGraphicsItem::ItemIsMovable))
{
QPointF pos = event->scenePos() + (m_origine_pos - event->buttonDownScenePos(Qt::LeftButton));
event->modifiers() == Qt::ControlModifier ? setPos(pos) : setPos(elementScene()->snapToGrid(pos));
}
else
QGraphicsObject::mouseMoveEvent(event);
}
/**
* @brief PartDynamicTextField::mousePressEvent
* @param event
*/
void PartDynamicTextField::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if(event->button() == Qt::LeftButton)
m_origine_pos = this->pos();
QGraphicsObject::mousePressEvent(event);
}
/**
* @brief PartDynamicTextField::mouseReleaseEvent
* @param event
*/
void PartDynamicTextField::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
if((event->button() & Qt::LeftButton) && (flags() & QGraphicsItem::ItemIsMovable) && m_origine_pos != pos())
{
QPropertyUndoCommand *undo = new QPropertyUndoCommand(this, "pos", QVariant(m_origine_pos), QVariant(pos()));
undo->setText(tr("Déplacer un champ texte"));
undo->enableAnimation();
elementScene()->undoStack().push(undo);
}
QGraphicsObject::mouseReleaseEvent(event);
}
/**
* @brief PartDynamicTextField::itemChange
* @param change
* @param value
* @return
*/
QVariant PartDynamicTextField::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
{
if (change == QGraphicsItem::ItemPositionHasChanged || change == QGraphicsItem::ItemSceneHasChanged) {
updateCurrentPartEditor();
} else if (change == QGraphicsItem::ItemSelectedHasChanged) {
if (value.toBool() == true) {
updateCurrentPartEditor();
}
}
return(QGraphicsTextItem::itemChange(change, value));
}

View File

@ -0,0 +1,108 @@
/*
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 PARTDYNAMICTEXTFIELD_H
#define PARTDYNAMICTEXTFIELD_H
#include "customelementpart.h"
#include "QGraphicsTextItem"
#include "dynamicelementtextitem.h"
/**
* @brief The PartDynamicTextField class
* This class represents an editable dynamic text field which may be used to compose the
* drawing of an electrical element within the element editor.
* The field will remain editable once the element is added onto
* a diagram
*/
class PartDynamicTextField : public QGraphicsTextItem, public CustomElementPart
{
Q_OBJECT
Q_PROPERTY(QString tagg READ tagg WRITE setTagg NOTIFY taggChanged)
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
Q_PROPERTY(DynamicElementTextItem::TextFrom textFrom READ textFrom WRITE setTextFrom NOTIFY textFromChanged)
Q_PROPERTY(QString infoName READ infoName WRITE setInfoName NOTIFY infoNameChanged)
Q_PROPERTY(QString compositeText READ compositeText WRITE setCompositeText NOTIFY compositeTextChanged)
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
Q_PROPERTY(int fontSize READ fontSize WRITE setFontSize NOTIFY fontSizeChanged)
public:
///PROPERTY
void setProperty(const char *name, const QVariant &value) override {QGraphicsTextItem::setProperty(name, value);}
QVariant property(const char *name) const override {return QGraphicsTextItem::property(name);}
signals:
void taggChanged(QString tagg);
void textChanged(QString text);
void textFromChanged(DynamicElementTextItem::TextFrom text_from);
void infoNameChanged(QString info);
void compositeTextChanged(QString text);
void colorChanged(QColor color);
void fontSizeChanged(int size);
public:
PartDynamicTextField(QETElementEditor *editor, QGraphicsItem *parent = nullptr);
enum {Type = UserType + 1110};
int type() const override {return Type;}
QString name() const override;
QString xmlName() const override;
bool isUseless() const override {return false;}
QRectF sceneGeometricRect() const override {return sceneBoundingRect();}
void startUserTransformation(const QRectF &initial_selection_rect) override;
void handleUserTransformation(const QRectF &initial_selection_rect, const QRectF &new_selection_rect) override;
const QDomElement toXml(QDomDocument &dom_doc) const override;
void fromXml(const QDomElement &dom_elmt) override;
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);
void setInfoName(const QString &info_name);
QString infoName() const;
void setCompositeText(const QString &text);
QString compositeText() const;
void setColor(QColor color);
QColor color() const;
void setFontSize(int s);
int fontSize()const;
protected:
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
private:
QPointF m_origine_pos,
m_saved_point;
QString m_tagg,
m_text,
m_info_name,
m_composite_text;
DynamicElementTextItem::TextFrom m_text_from = DynamicElementTextItem::UserText;
QUuid m_uuid;
};
#endif // PARTDYNAMICTEXTFIELD_H

View File

@ -40,6 +40,7 @@
#include "partterminal.h"
#include "parttextfield.h"
#include "styleeditor.h"
#include "dynamictextfieldeditor.h"
#include "eseventaddline.h"
#include "eseventaddrect.h"
@ -49,6 +50,7 @@
#include "eseventaddtext.h"
#include "eseventaddtextfield.h"
#include "eseventaddterminal.h"
#include "eseventadddynamictextfield.h"
#include <QMessageBox>
#include <QTextStream>
@ -101,8 +103,8 @@ QETElementEditor::~QETElementEditor() {
clearToolsDock();
// supprime les editeurs de primitives
qDeleteAll(editors_.begin(), editors_.end());
editors_.clear();
qDeleteAll(m_editors.begin(), m_editors.end());
m_editors.clear();
}
/**
@ -202,10 +204,10 @@ void QETElementEditor::setupActions() {
connect(selectall, SIGNAL(triggered()), m_elmt_scene, SLOT(slot_selectAll()));
connect(deselectall, SIGNAL(triggered()), m_elmt_scene, SLOT(slot_deselectAll()));
connect(inv_select, SIGNAL(triggered()), m_elmt_scene, SLOT(slot_invertSelection()));
connect(cut, SIGNAL(triggered()), ce_view, SLOT(cut()));
connect(copy, SIGNAL(triggered()), ce_view, SLOT(copy()));
connect(paste, SIGNAL(triggered()), ce_view, SLOT(paste()));
connect(paste_in_area, SIGNAL(triggered()), ce_view, SLOT(pasteInArea()));
connect(cut, SIGNAL(triggered()), m_view, SLOT(cut()));
connect(copy, SIGNAL(triggered()), m_view, SLOT(copy()));
connect(paste, SIGNAL(triggered()), m_view, SLOT(paste()));
connect(paste_in_area, SIGNAL(triggered()), m_view, SLOT(pasteInArea()));
connect(paste_from_file, SIGNAL(triggered()), this, SLOT(pasteFromFile()));
connect(paste_from_elmt, SIGNAL(triggered()), this, SLOT(pasteFromElement()));
connect(edit_delete, SIGNAL(triggered()), m_elmt_scene, SLOT(slot_delete()));
@ -255,10 +257,10 @@ void QETElementEditor::setupActions() {
zoom_fit -> setShortcut(QKeySequence(tr("Ctrl+9")));
zoom_reset -> setShortcut(QKeySequence(tr("Ctrl+0")));
connect(zoom_in, SIGNAL(triggered()), ce_view, SLOT(zoomIn() ));
connect(zoom_out, SIGNAL(triggered()), ce_view, SLOT(zoomOut() ));
connect(zoom_fit, SIGNAL(triggered()), ce_view, SLOT(zoomFit() ));
connect(zoom_reset, SIGNAL(triggered()), ce_view, SLOT(zoomReset() ));
connect(zoom_in, SIGNAL(triggered()), m_view, SLOT(zoomIn() ));
connect(zoom_out, SIGNAL(triggered()), m_view, SLOT(zoomOut() ));
connect(zoom_fit, SIGNAL(triggered()), m_view, SLOT(zoomFit() ));
connect(zoom_reset, SIGNAL(triggered()), m_view, SLOT(zoomReset() ));
/*
@ -275,6 +277,7 @@ void QETElementEditor::setupActions() {
QAction *add_arc = new QAction(QET::Icons::PartArc, tr("Ajouter un arc de cercle"), parts);
QAction *add_terminal = new QAction(QET::Icons::Terminal, tr("Ajouter une borne"), parts);
QAction *add_textfield = new QAction(QET::Icons::PartTextField, tr("Ajouter un champ de texte"), parts);
QAction *add_dynamic_text_field = new QAction(QET::Icons::PartTextField, tr("Ajouter un champ texte dynamique"), parts);
foreach (QAction *action, parts -> actions()) action -> setCheckable(true);
@ -286,6 +289,7 @@ void QETElementEditor::setupActions() {
connect(add_arc, SIGNAL(triggered()), this, SLOT(addArc() ));
connect(add_terminal, SIGNAL(triggered()), this, SLOT(addTerminal() ));
connect(add_textfield, SIGNAL(triggered()), this, SLOT(addTextField() ));
connect(add_dynamic_text_field, &QAction::triggered, this, &QETElementEditor::addDynamicTextField);
parts_toolbar = addToolBar(tr("Parties", "toolbar title"));
@ -440,7 +444,7 @@ void QETElementEditor::slot_updateMenus() {
inv_select -> setEnabled(!read_only);
paste_from_file -> setEnabled(!read_only);
paste_from_elmt -> setEnabled(!read_only);
parts_list -> setEnabled(!read_only);
m_parts_list -> setEnabled(!read_only);
// Action enabled if primitive selected
deselectall -> setEnabled(selected_items);
@ -479,69 +483,70 @@ void QETElementEditor::slot_updateTitle() {
void QETElementEditor::setupInterface() {
// editeur
m_elmt_scene = new ElementScene(this, this);
ce_view = new ElementView(m_elmt_scene, this);
m_view = new ElementView(m_elmt_scene, this);
slot_setRubberBandToView();
setCentralWidget(ce_view);
setCentralWidget(m_view);
// widget par defaut dans le QDockWidget
default_informations = new QLabel();
m_default_informations = new QLabel();
// ScrollArea pour accueillir un widget d'edition (change a la volee)
tools_dock_scroll_area_ = new QScrollArea();
tools_dock_scroll_area_ -> setFrameStyle(QFrame::NoFrame);
tools_dock_scroll_area_ -> setAlignment(Qt::AlignHCenter|Qt::AlignTop);
m_tools_dock_scroll_area = new QScrollArea();
m_tools_dock_scroll_area -> setFrameStyle(QFrame::NoFrame);
m_tools_dock_scroll_area -> setAlignment(Qt::AlignHCenter|Qt::AlignTop);
// Pile de widgets pour accueillir les deux widgets precedents
tools_dock_stack_ = new QStackedWidget();
tools_dock_stack_ -> insertWidget(0, default_informations);
tools_dock_stack_ -> insertWidget(1, tools_dock_scroll_area_);
m_tools_dock_stack = new QStackedWidget();
m_tools_dock_stack -> insertWidget(0, m_default_informations);
m_tools_dock_stack -> insertWidget(1, m_tools_dock_scroll_area);
// widgets d'editions pour les parties
editors_["arc"] = new ArcEditor(this);
editors_["ellipse"] = new EllipseEditor(this);
editors_["line"] = new LineEditor(this);
editors_["polygon"] = new PolygonEditor(this);
editors_["rect"] = new RectangleEditor(this);
editors_["terminal"] = new TerminalEditor(this);
editors_["text"] = new TextEditor(this);
editors_["input"] = new TextFieldEditor(this);
editors_["style"] = new StyleEditor(this);
m_editors["arc"] = new ArcEditor(this);
m_editors["ellipse"] = new EllipseEditor(this);
m_editors["line"] = new LineEditor(this);
m_editors["polygon"] = new PolygonEditor(this);
m_editors["rect"] = new RectangleEditor(this);
m_editors["terminal"] = new TerminalEditor(this);
m_editors["text"] = new TextEditor(this);
m_editors["input"] = new TextFieldEditor(this);
m_editors["style"] = new StyleEditor(this);
m_editors["dynamic_text"] = new DynamicTextFieldEditor(this);
// panel sur le cote pour editer les parties
tools_dock = new QDockWidget(tr("Informations", "dock title"), this);
tools_dock -> setObjectName("informations");
tools_dock -> setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
tools_dock -> setFeatures(QDockWidget::AllDockWidgetFeatures);
tools_dock -> setMinimumWidth(380);
addDockWidget(Qt::RightDockWidgetArea, tools_dock);
tools_dock -> setWidget(tools_dock_stack_);
m_tools_dock = new QDockWidget(tr("Informations", "dock title"), this);
m_tools_dock -> setObjectName("informations");
m_tools_dock -> setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
m_tools_dock -> setFeatures(QDockWidget::AllDockWidgetFeatures);
//m_tools_dock -> setMinimumWidth(380);
addDockWidget(Qt::RightDockWidgetArea, m_tools_dock);
m_tools_dock -> setWidget(m_tools_dock_stack);
// panel sur le cote pour les annulations
undo_dock = new QDockWidget(tr("Annulations", "dock title"), this);
undo_dock -> setObjectName("undo");
undo_dock -> setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
undo_dock -> setFeatures(QDockWidget::AllDockWidgetFeatures);
undo_dock -> setMinimumWidth(290);
addDockWidget(Qt::RightDockWidgetArea, undo_dock);
m_undo_dock = new QDockWidget(tr("Annulations", "dock title"), this);
m_undo_dock -> setObjectName("undo");
m_undo_dock -> setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
m_undo_dock -> setFeatures(QDockWidget::AllDockWidgetFeatures);
m_undo_dock -> setMinimumWidth(290);
addDockWidget(Qt::RightDockWidgetArea, m_undo_dock);
QUndoView* undo_view = new QUndoView(&(m_elmt_scene -> undoStack()), this);
undo_view -> setEmptyLabel(tr("Aucune modification"));
undo_dock -> setWidget(undo_view);
m_undo_dock -> setWidget(undo_view);
// panel sur le cote pour la liste des parties
parts_list = new QListWidget(this);
parts_list -> setSelectionMode(QAbstractItemView::ExtendedSelection);
m_parts_list = new QListWidget(this);
m_parts_list -> setSelectionMode(QAbstractItemView::ExtendedSelection);
connect(m_elmt_scene, SIGNAL(partsAdded()), this, SLOT(slot_createPartsList()));
connect(m_elmt_scene, SIGNAL(partsRemoved()), this, SLOT(slot_createPartsList()));
connect(m_elmt_scene, SIGNAL(partsZValueChanged()), this, SLOT(slot_createPartsList()));
connect(m_elmt_scene, SIGNAL(selectionChanged()), this, SLOT(slot_updatePartsList()));
connect(parts_list, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateSelectionFromPartsList()));
parts_dock = new QDockWidget(tr("Parties", "dock title"), this);
parts_dock -> setObjectName("parts_list");
parts_dock -> setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
parts_dock -> setFeatures(QDockWidget::AllDockWidgetFeatures);
parts_dock -> setMinimumWidth(290);
tabifyDockWidget(undo_dock, parts_dock);
parts_dock -> setWidget(parts_list);
connect(m_parts_list, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateSelectionFromPartsList()));
m_parts_dock = new QDockWidget(tr("Parties", "dock title"), this);
m_parts_dock -> setObjectName("parts_list");
m_parts_dock -> setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
m_parts_dock -> setFeatures(QDockWidget::AllDockWidgetFeatures);
m_parts_dock -> setMinimumWidth(290);
tabifyDockWidget(m_undo_dock, m_parts_dock);
m_parts_dock -> setWidget(m_parts_list);
slot_updateInformations();
slot_createPartsList();
@ -555,14 +560,14 @@ void QETElementEditor::setupInterface() {
elements selectionnes et il est possible d'utiliser un rectangle de selection.
*/
void QETElementEditor::slot_setRubberBandToView() {
ce_view -> setDragMode(QGraphicsView::RubberBandDrag);
m_view -> setDragMode(QGraphicsView::RubberBandDrag);
}
/**
Passe l'editeur d'element en mode immobile (utilise pour la lecture seule)
*/
void QETElementEditor::slot_setNoDragToView() {
ce_view -> setDragMode(QGraphicsView::NoDrag);
m_view -> setDragMode(QGraphicsView::NoDrag);
}
/**
@ -570,7 +575,8 @@ void QETElementEditor::slot_setNoDragToView() {
Si plusieurs primitives sont selectionnees, seule leur quantite est
affichee. Sinon, un widget d'edition approprie est mis en place.
*/
void QETElementEditor::slot_updateInformations() {
void QETElementEditor::slot_updateInformations()
{
QList<QGraphicsItem *> selected_qgis = m_elmt_scene -> selectedItems();
QList<CustomElementPart *> cep_list;
bool style_editable = false;
@ -591,7 +597,21 @@ void QETElementEditor::slot_updateInformations() {
}
clearToolsDock();
if(selected_qgis.size() == 1)
{
QGraphicsItem *qgi = selected_qgis.first();
if (CustomElementPart *selection = dynamic_cast<CustomElementPart *>(qgi))
{
if (QWidget *widget = m_tools_dock_scroll_area->widget())
{
if (ElementItemEditor *editor = dynamic_cast<ElementItemEditor *>(widget))
{
if(editor->currentPart() == selection)
return;
}
}
}
}
//There's one selected item
if (selected_qgis.size() == 1)
@ -599,15 +619,22 @@ void QETElementEditor::slot_updateInformations() {
QGraphicsItem *qgi = selected_qgis.first();
if (CustomElementPart *selection = dynamic_cast<CustomElementPart *>(qgi))
{
// on en ajoute le widget d'edition
//The current editor already edit the selected part
if (QWidget *widget = m_tools_dock_scroll_area->widget())
if (ElementItemEditor *editor = dynamic_cast<ElementItemEditor *>(widget))
if(editor->currentPart() == selection)
return;
clearToolsDock();
//We add the editor widget
QString selection_xml_name = selection -> xmlName();
ElementItemEditor *selection_editor = editors_[selection_xml_name];
ElementItemEditor *selection_editor = m_editors[selection_xml_name];
if (selection_editor)
{
if (selection_editor -> setPart(selection))
if (selection_editor->setPart(selection))
{
tools_dock_scroll_area_ -> setWidget(selection_editor);
tools_dock_stack_ -> setCurrentIndex(1);
m_tools_dock_scroll_area -> setWidget(selection_editor);
m_tools_dock_stack -> setCurrentIndex(1);
}
else
{
@ -619,13 +646,14 @@ void QETElementEditor::slot_updateInformations() {
//There's several parts selecteds and all can be edited by style editor.
else if (style_editable)
{
ElementItemEditor *selection_editor = editors_["style"];
clearToolsDock();
ElementItemEditor *selection_editor = m_editors["style"];
if (selection_editor)
{
if (selection_editor -> setParts(cep_list))
{
tools_dock_scroll_area_ -> setWidget(selection_editor);
tools_dock_stack_ -> setCurrentIndex(1);
m_tools_dock_scroll_area -> setWidget(selection_editor);
m_tools_dock_stack -> setCurrentIndex(1);
}
else
{
@ -636,26 +664,15 @@ void QETElementEditor::slot_updateInformations() {
//Else we only display the number of selected items
else
{
default_informations -> setText(tr("%n partie(s) sélectionnée(s).",
clearToolsDock();
m_default_informations -> setText(tr("%n partie(s) sélectionnée(s).",
"",
selected_qgis.size()));
default_informations -> setAlignment(Qt::AlignHCenter | Qt::AlignTop);
tools_dock_stack_ -> setCurrentIndex(0);
m_default_informations -> setAlignment(Qt::AlignHCenter | Qt::AlignTop);
m_tools_dock_stack -> setCurrentIndex(0);
}
}
/**
Affiche le code XML correspondant a l'element dans son etat actuel dans
une boite de dialogue.
*/
void QETElementEditor::xmlPreview() {
QET::QetMessageBox::information(
this,
"Export XML",
m_elmt_scene -> toXml().toString(4)
);
}
/**
* @brief QETElementEditor::checkElement
* Do several check about element.
@ -919,7 +936,7 @@ void QETElementEditor::setReadOnly(bool ro) {
read_only = ro;
// active / desactive les interactions avec la scene
ce_view -> setInteractive(!ro);
m_view -> setInteractive(!ro);
slot_updateMenus();
}
@ -995,6 +1012,14 @@ void QETElementEditor::addTerminal() {
m_elmt_scene -> setEventInterface(new ESEventAddTerminal(m_elmt_scene));
}
/**
* @brief QETElementEditor::addDynamicTextField
* Set dynamic text field creation interface to scene
*/
void QETElementEditor::addDynamicTextField() {
m_elmt_scene->setEventInterface(new ESEventAddDynamicTextField(m_elmt_scene));
}
/**
* @brief QETElementEditor::UncheckAddPrimitive
* Uncheck all action related to primitive
@ -1266,7 +1291,7 @@ bool QETElementEditor::canClose() {
@return le widget enleve, ou 0 s'il n'y avait pas de widget a enlever
*/
QWidget *QETElementEditor::clearToolsDock() {
if (QWidget *previous_widget = tools_dock_scroll_area_ -> takeWidget()) {
if (QWidget *previous_widget = m_tools_dock_scroll_area -> takeWidget()) {
previous_widget -> setParent(nullptr);
previous_widget -> hide();
return(previous_widget);
@ -1293,7 +1318,7 @@ void QETElementEditor::copyAndPasteXml(const QDomDocument &xml_document) {
}
clipboard -> setText(clipboard_content);
ce_view -> pasteInArea();
m_view -> pasteInArea();
}
/**
@ -1314,15 +1339,15 @@ void QETElementEditor::closeEvent(QCloseEvent *qce) {
*/
void QETElementEditor::firstActivation(QEvent *event) {
Q_UNUSED(event)
QTimer::singleShot(250, ce_view, SLOT(zoomFit()));
QTimer::singleShot(250, m_view, SLOT(zoomFit()));
}
/**
Remplit la liste des parties
*/
void QETElementEditor::slot_createPartsList() {
parts_list -> blockSignals(true);
parts_list -> clear();
m_parts_list -> blockSignals(true);
m_parts_list -> clear();
QList<QGraphicsItem *> qgis = m_elmt_scene -> zItems();
// on ne construit plus la liste a partir de 200 primitives
@ -1337,14 +1362,14 @@ void QETElementEditor::slot_createPartsList() {
QVariant v;
v.setValue<QGraphicsItem *>(qgi);
qlwi -> setData(42, v);
parts_list -> addItem(qlwi);
m_parts_list -> addItem(qlwi);
qlwi -> setSelected(qgi -> isSelected());
}
}
} else {
parts_list -> addItem(new QListWidgetItem(tr("Trop de primitives, liste non générée.")));
m_parts_list -> addItem(new QListWidgetItem(tr("Trop de primitives, liste non générée.")));
}
parts_list -> blockSignals(false);
m_parts_list -> blockSignals(false);
}
/**
@ -1352,19 +1377,19 @@ void QETElementEditor::slot_createPartsList() {
*/
void QETElementEditor::slot_updatePartsList() {
int items_count = m_elmt_scene -> items().count();
if (parts_list -> count() != items_count) {
if (m_parts_list -> count() != items_count) {
slot_createPartsList();
} else if (items_count <= QET_MAX_PARTS_IN_ELEMENT_EDITOR_LIST) {
parts_list -> blockSignals(true);
m_parts_list -> blockSignals(true);
int i = 0;
QList<QGraphicsItem *> items = m_elmt_scene -> zItems();
for (int j = items.count() - 1 ; j >= 0 ; -- j) {
QGraphicsItem *qgi = items[j];
QListWidgetItem *qlwi = parts_list -> item(i);
QListWidgetItem *qlwi = m_parts_list -> item(i);
if (qlwi) qlwi -> setSelected(qgi -> isSelected());
++ i;
}
parts_list -> blockSignals(false);
m_parts_list -> blockSignals(false);
}
}
@ -1374,15 +1399,15 @@ void QETElementEditor::slot_updatePartsList() {
*/
void QETElementEditor::slot_updateSelectionFromPartsList() {
m_elmt_scene -> blockSignals(true);
parts_list -> blockSignals(true);
for (int i = 0 ; i < parts_list -> count() ; ++ i) {
QListWidgetItem *qlwi = parts_list -> item(i);
m_parts_list -> blockSignals(true);
for (int i = 0 ; i < m_parts_list -> count() ; ++ i) {
QListWidgetItem *qlwi = m_parts_list -> item(i);
QGraphicsItem *qgi = qlwi -> data(42).value<QGraphicsItem *>();
if (qgi) {
qgi -> setSelected(qlwi -> isSelected());
}
}
parts_list -> blockSignals(false);
m_parts_list -> blockSignals(false);
m_elmt_scene -> blockSignals(false);
slot_updateInformations();
slot_updateMenus();
@ -1570,10 +1595,10 @@ void QETElementEditor::pasteFromElement()
*/
void QETElementEditor::updateCurrentPartEditor() {
// si aucun widget d'edition n'est affiche, on ne fait rien
if (!tools_dock_stack_ -> currentIndex()) return;
if (!m_tools_dock_stack -> currentIndex()) return;
// s'il y a un widget d'edition affiche, on le met a jour
if (ElementItemEditor *current_editor = dynamic_cast<ElementItemEditor *>(tools_dock_scroll_area_ -> widget())) {
if (ElementItemEditor *current_editor = dynamic_cast<ElementItemEditor *>(m_tools_dock_scroll_area -> widget())) {
current_editor -> updateForm();
}
}

View File

@ -51,25 +51,25 @@ class QETElementEditor : public QETMainWindow {
/// menus
QMenu *file_menu, *edit_menu, *paste_from_menu, *display_menu, *tools_menu;
/// view widget for the editing scene
ElementView *ce_view;
ElementView *m_view;
/// editing scene
ElementScene *m_elmt_scene;
/// container for widgets dedicated to primitive edition
QDockWidget *tools_dock;
QDockWidget *m_tools_dock;
/// Stack of widgets for tools_dock
QStackedWidget *tools_dock_stack_;
QStackedWidget *m_tools_dock_stack;
/// label displayed when several primitives are selected
QLabel *default_informations;
QLabel *m_default_informations;
/// Hash associating primitive names with their matching edition widget
QHash<QString, ElementItemEditor *> editors_;
QHash<QString, ElementItemEditor *> m_editors;
/// ScrollArea for the tools_dock DockWidget
QScrollArea *tools_dock_scroll_area_;
QScrollArea *m_tools_dock_scroll_area;
/// container for the undo list
QDockWidget *undo_dock;
QDockWidget *m_undo_dock;
/// Container for the list of existing primitives
QDockWidget *parts_dock;
QDockWidget *m_parts_dock;
/// List of primitives
QListWidget *parts_list;
QListWidget *m_parts_list;
/// actions for the "file" menu
QAction *new_element, *open, *open_dxf, *open_file, *save, *save_as, *save_as_file, *reload, *quit;
/// actions for the "edit" menu
@ -133,6 +133,7 @@ class QETElementEditor : public QETMainWindow {
void addText();
void addTextField();
void addTerminal();
void addDynamicTextField();
void UncheckAddPrimitive();
void slot_new();
@ -153,7 +154,6 @@ class QETElementEditor : public QETMainWindow {
void slot_createPartsList();
void slot_updatePartsList();
void slot_updateSelectionFromPartsList();
void xmlPreview();
bool checkElement();
void pasteFromFile();
void pasteFromElement();

View File

@ -0,0 +1,162 @@
/*
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 "dynamictextfieldeditor.h"
#include "ui_dynamictextfieldeditor.h"
#include "customelementpart.h"
#include "partdynamictextfield.h"
#include "QPropertyUndoCommand/qpropertyundocommand.h"
#include <QPointer>
#include <QGraphicsItem>
#include <QColorDialog>
DynamicTextFieldEditor::DynamicTextFieldEditor(QETElementEditor *editor, PartDynamicTextField *text_field, QWidget *parent) :
ElementItemEditor(editor, parent),
ui(new Ui::DynamicTextFieldEditor)
{
ui->setupUi(this);
ui->m_composite_text_pb->setDisabled(true);
ui->m_elmt_info_cb->setDisabled(true);
if(text_field)
setPart(text_field);
}
DynamicTextFieldEditor::~DynamicTextFieldEditor()
{
delete ui;
if(!m_connection_list.isEmpty())
for(QMetaObject::Connection con : m_connection_list)
disconnect(con);
}
/**
* @brief DynamicTextFieldEditor::setPart
* Set @part as current edited part of this widget.
* @param part
* @return true if @part can be edited by this widget
*/
bool DynamicTextFieldEditor::setPart(CustomElementPart *part)
{
//Remove previous connection
if(!m_connection_list.isEmpty())
for(QMetaObject::Connection con : m_connection_list)
disconnect(con);
QGraphicsItem *qgi = part->toItem();
if(!qgi)
return false;
else if (qgi->type() != PartDynamicTextField::Type)
return false;
m_text_field = static_cast<PartDynamicTextField *>(qgi);
updateForm();
//Setup the connection
m_connection_list << connect(m_text_field, &PartDynamicTextField::colorChanged, [this](){this->updateForm();});
m_connection_list << connect(m_text_field, &PartDynamicTextField::fontSizeChanged, [this](){this->updateForm();});
m_connection_list << connect(m_text_field, &PartDynamicTextField::taggChanged, [this](){this->updateForm();});
m_connection_list << connect(m_text_field, &PartDynamicTextField::textFromChanged, [this](){this->updateForm();});
m_connection_list << connect(m_text_field, &PartDynamicTextField::textChanged, [this](){this->updateForm();});
m_connection_list << connect(m_text_field, &PartDynamicTextField::infoNameChanged, [this](){this->updateForm();});
m_connection_list << connect(m_text_field, &PartDynamicTextField::rotationChanged, [this](){this->updateForm();});
m_connection_list << connect(m_text_field, &PartDynamicTextField::compositeTextChanged, [this]() {this->updateForm();});
return true;
}
/**
* @brief DynamicTextFieldEditor::currentPart
* @return The current edited part, note they can return nullptr if
* there is not a currently edited part.
*/
CustomElementPart *DynamicTextFieldEditor::currentPart() const {
return m_text_field.data();
}
void DynamicTextFieldEditor::updateForm()
{
if(m_text_field)
{
ui->m_x_sb->setValue(m_text_field.data()->x());
ui->m_y_sb->setValue(m_text_field.data()->y());
ui->m_rotation_sb->setValue(QET::correctAngle(m_text_field.data()->rotation()));
ui->m_user_text_le->setText(m_text_field.data()->text());
ui->m_size_sb->setValue(m_text_field.data()->fontSize());
ui->m_tagg_le->setText(m_text_field.data()->tagg());
setColorPushButton(m_text_field.data()->color());
}
}
void DynamicTextFieldEditor::setColorPushButton(QColor color)
{
QPalette palette;
palette.setColor(QPalette::Button, color);
ui->m_color_pb->setStyleSheet(QString("background-color: %1; min-height: 1.5em; border-style: outset; border-width: 2px; border-color: gray; border-radius: 4px;").arg(color.name()));
}
void DynamicTextFieldEditor::on_m_x_sb_editingFinished()
{
QPropertyUndoCommand *undo = new QPropertyUndoCommand(m_text_field, "x", m_text_field.data()->x(), ui->m_x_sb->value());
undo->setText(tr("Déplacer un champ texte dynamique"));
undo->enableAnimation(true);
undoStack().push(undo);
}
void DynamicTextFieldEditor::on_m_y_sb_editingFinished()
{
QPropertyUndoCommand *undo = new QPropertyUndoCommand(m_text_field, "y", m_text_field.data()->y(), ui->m_y_sb->value());
undo->setText(tr("Déplacer un champ texte dynamique"));
undo->enableAnimation(true);
undoStack().push(undo);
}
void DynamicTextFieldEditor::on_m_rotation_sb_editingFinished()
{
QPropertyUndoCommand *undo = new QPropertyUndoCommand(m_text_field, "rotation", m_text_field.data()->rotation(), ui->m_rotation_sb->value());
undo->setText(tr("Pivoter 2un champ texte dynamique"));
undo->enableAnimation(true);
undoStack().push(undo);
}
void DynamicTextFieldEditor::on_m_user_text_le_editingFinished()
{
QPropertyUndoCommand *undo = new QPropertyUndoCommand(m_text_field, "text", m_text_field.data()->text(), ui->m_user_text_le->text());
undo->setText(tr("Modifier le texte d'un champ texte dynamique"));
undoStack().push(undo);
}
void DynamicTextFieldEditor::on_m_size_sb_editingFinished()
{
QPropertyUndoCommand *undo = new QPropertyUndoCommand(m_text_field, "fontSize", m_text_field.data()->fontSize(), ui->m_size_sb->value());
undo->setText(tr("Modifier la taille d'un champ texte dynamique"));
undo->enableAnimation(true);
undoStack().push(undo);
}
void DynamicTextFieldEditor::on_m_color_pb_clicked()
{
QColor color = QColorDialog::getColor(m_text_field.data()->color(), this, tr("Couleur du texte"));
if(color.isValid() && color != m_text_field.data()->color())
{
QPropertyUndoCommand *undo = new QPropertyUndoCommand(m_text_field, "color", m_text_field.data()->color(), color);
undo->setText(tr("Modifier la couleur d'un champ texte dynamique"));
undoStack().push(undo);
setColorPushButton(m_text_field.data()->color());
}
}

View File

@ -0,0 +1,61 @@
/*
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 DYNAMICTEXTFIELDEDITOR_H
#define DYNAMICTEXTFIELDEDITOR_H
#include "elementitemeditor.h"
#include "partdynamictextfield.h"
namespace Ui {
class DynamicTextFieldEditor;
}
/**
* @brief The DynamicTextFieldEditor class
* This class provide a widget used to edit the property of a dynamic text field
*/
class DynamicTextFieldEditor : public ElementItemEditor
{
Q_OBJECT
public:
explicit DynamicTextFieldEditor(QETElementEditor *editor, PartDynamicTextField *text_field = nullptr, QWidget *parent = nullptr);
~DynamicTextFieldEditor();
bool setPart(CustomElementPart *part) override;
CustomElementPart *currentPart() const override;
void updateForm() override;
private:
void setColorPushButton(QColor color);
private slots:
void on_m_x_sb_editingFinished();
void on_m_y_sb_editingFinished();
void on_m_rotation_sb_editingFinished();
void on_m_user_text_le_editingFinished();
void on_m_size_sb_editingFinished();
void on_m_color_pb_clicked();
private:
Ui::DynamicTextFieldEditor *ui;
QPointer<PartDynamicTextField> m_text_field;
QList<QMetaObject::Connection> m_connection_list;
};
#endif // DYNAMICTEXTFIELDEDITOR_H

View File

@ -0,0 +1,176 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DynamicTextFieldEditor</class>
<widget class="QWidget" name="DynamicTextFieldEditor">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>336</width>
<height>264</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="5" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Taille</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Source du texte</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Couleur</string>
</property>
</widget>
</item>
<item row="3" column="1" colspan="6">
<widget class="QComboBox" name="m_elmt_info_cb"/>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Tagg</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="6">
<widget class="QComboBox" name="m_text_from_cb">
<item>
<property name="text">
<string>Texte utilisateur</string>
</property>
</item>
<item>
<property name="text">
<string>Information de l'élément</string>
</property>
</item>
<item>
<property name="text">
<string>Texte composé</string>
</property>
</item>
</widget>
</item>
<item row="6" column="1" colspan="6">
<widget class="QLineEdit" name="m_tagg_le"/>
</item>
<item row="5" column="1" colspan="6">
<widget class="QSpinBox" name="m_size_sb"/>
</item>
<item row="4" column="1" colspan="6">
<widget class="QPushButton" name="m_composite_text_pb">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="0" colspan="7">
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>X</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="m_x_sb">
<property name="minimum">
<double>-5000.000000000000000</double>
</property>
<property name="maximum">
<double>5000.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>Y</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="m_y_sb">
<property name="minimum">
<double>-5000.000000000000000</double>
</property>
<property name="maximum">
<double>5000.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>Rotation</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="m_rotation_sb">
<property name="maximum">
<number>359</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="1" colspan="6">
<widget class="QLineEdit" name="m_user_text_le"/>
</item>
<item row="7" column="1" colspan="6">
<widget class="QPushButton" name="m_color_pb">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="8" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -24,6 +24,7 @@
#include "terminal.h"
#include "diagramposition.h"
#include "diagramcontent.h"
#include "dynamicelementtextitem.h"
/**
Constructeur de la classe CustomElement. Permet d'instancier un element
@ -95,11 +96,13 @@ bool CustomElement::buildFromXml(const QDomElement &xml_def_elmt, int *state) {
return(false);
}
// verifie basiquement que la version actuelle est capable de lire ce fichier
if (xml_def_elmt.hasAttribute("version")) {
//Check if the curent version can read the xml description
if (xml_def_elmt.hasAttribute("version"))
{
bool conv_ok;
qreal element_version = xml_def_elmt.attribute("version").toDouble(&conv_ok);
if (conv_ok && QET::version.toDouble() < element_version) {
if (conv_ok && QET::version.toDouble() < element_version)
{
std::cerr << qPrintable(
QObject::tr("Avertissement : l'élément "
" a été enregistré avec une version"
@ -108,7 +111,7 @@ bool CustomElement::buildFromXml(const QDomElement &xml_def_elmt, int *state) {
}
}
// ces attributs doivent etre presents et valides
//This attribute must be present and valid
int w, h, hot_x, hot_y;
if (
!QET::attributeIsAnInteger(xml_def_elmt, QString("width"), &w) ||\
@ -131,61 +134,81 @@ bool CustomElement::buildFromXml(const QDomElement &xml_def_elmt, int *state) {
return(false);
}
// initialisation du QPainter (pour dessiner l'element)
//Init the QPainter for draw the elemennt
QPainter qp;
qp.begin(&drawing);
QPainter low_zoom_qp;
low_zoom_qp.begin(&low_zoom_drawing);
QPen tmp;
tmp.setWidthF(1.0); // ligne vaudou pour prise en compte du setCosmetic - ne pas enlever
tmp.setWidthF(1.0); //Vaudoo line to take into account the setCosmetic - don't remove
tmp.setCosmetic(true);
low_zoom_qp.setPen(tmp);
// extrait les noms de la definition XML
//Extract the names
names.fromXml(xml_def_elmt);
setToolTip(name());
//load kind informations
//load kind informations
kind_informations_.fromXml(xml_def_elmt.firstChildElement("kindInformations"), "kindInformation");
// parcours des enfants de la definition : parties du dessin
//scroll of the Children of the Definition: Parts of the Drawing
int parsed_elements_count = 0;
for (QDomNode node = xml_def_elmt.firstChild() ; !node.isNull() ; node = node.nextSibling()) {
for (QDomNode node = xml_def_elmt.firstChild() ; !node.isNull() ; node = node.nextSibling())
{
QDomElement elmts = node.toElement();
if (elmts.isNull()) continue;
if (elmts.tagName() == "description") {
// gestion de la description graphique de l'element
// = parcours des differentes parties du dessin
for (QDomNode n = node.firstChild() ; !n.isNull() ; n = n.nextSibling()) {
if (elmts.isNull())
continue;
if (elmts.tagName() == "description")
{
//Manage the graphic description = part of drawing
for (QDomNode n = node.firstChild() ; !n.isNull() ; n = n.nextSibling())
{
QDomElement qde = n.toElement();
if (qde.isNull()) continue;
if (parseElement(qde, qp)) {
if (qde.isNull())
continue;
if (parseElement(qde, qp))
{
++ parsed_elements_count;
QString current_tag = qde.tagName();
if (current_tag != "terminal" && current_tag != "input") {
if (current_tag != "terminal" && current_tag != "input" && current_tag != "dynamic_text")
{
forbid_antialiasing = true;
parseElement(qde, low_zoom_qp);
forbid_antialiasing = false;
}
} else {
if (state) *state = 7;
}
else
{
if (state)
*state = 7;
return(false);
}
}
}
}
// fin du dessin
//End of the drawing
qp.end();
low_zoom_qp.end();
// il doit y avoir au moins un element charge
if (!parsed_elements_count) {
if (state) *state = 8;
//They must be at least one parsed graphics part
if (!parsed_elements_count)
{
if (state)
*state = 8;
return(false);
} else {
if (state) *state = 0;
}
else
{
if (state)
*state = 0;
return(true);
}
}
@ -277,17 +300,19 @@ void CustomElement::paint(QPainter *qp, const QStyleOptionGraphicsItem *options)
@param qp Le QPainter a utiliser pour dessiner l'element perso
@return true si l'analyse reussit, false sinon
*/
bool CustomElement::parseElement(QDomElement &e, QPainter &qp) {
if (e.tagName() == "terminal") return(parseTerminal(e));
else if (e.tagName() == "line") return(parseLine(e, qp));
else if (e.tagName() == "rect") return(parseRect(e, qp));
else if (e.tagName() == "ellipse") return(parseEllipse(e, qp));
else if (e.tagName() == "circle") return(parseCircle(e, qp));
else if (e.tagName() == "arc") return(parseArc(e, qp));
else if (e.tagName() == "polygon") return(parsePolygon(e, qp));
else if (e.tagName() == "text") return(parseText(e, qp));
else if (e.tagName() == "input") return(parseInput(e));
else return(true); // on n'est pas chiant, on ignore l'element inconnu
bool CustomElement::parseElement(QDomElement &e, QPainter &qp)
{
if (e.tagName() == "terminal") return(parseTerminal(e));
else if (e.tagName() == "line") return(parseLine(e, qp));
else if (e.tagName() == "rect") return(parseRect(e, qp));
else if (e.tagName() == "ellipse") return(parseEllipse(e, qp));
else if (e.tagName() == "circle") return(parseCircle(e, qp));
else if (e.tagName() == "arc") return(parseArc(e, qp));
else if (e.tagName() == "polygon") return(parsePolygon(e, qp));
else if (e.tagName() == "text") return(parseText(e, qp));
else if (e.tagName() == "input") return(parseInput(e));
else if (e.tagName() == "dynamic_text") return(parseDynamicText(e));
else return(true);
}
/**
@ -719,6 +744,27 @@ ElementTextItem *CustomElement::parseInput(QDomElement &e) {
return(eti);
}
/**
* @brief CustomElement::parseDynamicText
* Create the dynamic text field describ in @dom_element
* @param dom_element
* @return
*/
DynamicElementTextItem *CustomElement::parseDynamicText(QDomElement &dom_element)
{
DynamicElementTextItem *deti = new DynamicElementTextItem(this);
//Because the xml description of a .elmt file is the same as how a dynamic text field is save to xml in a .qet file
//wa call fromXml, we just change the tagg name (.elmt = dynamic_text, .qet = dynamic_elmt_text)
//and the uuid (because the uuid, is the uuid of the descritpion and not the uuid of instantiated dynamic text field)
QDomElement dom(dom_element.cloneNode(true).toElement());
dom.setTagName(DynamicElementTextItem::xmlTaggName());
deti->fromXml(dom);
deti->m_uuid = QUuid::createUuid();
this->addDynamicTextItem(deti);
return deti;
}
/**
Analyse un element XML suppose representer une borne. Si l'analyse
reussit, la borne est ajoutee a l'element.

View File

@ -54,45 +54,47 @@ class CustomElement : public FixedElement
bool forbid_antialiasing;
QList<QLineF *> list_lines_;
QList<QRectF *> list_rectangles_;
QList<QRectF *> list_circles_;
QList<QVector<QPointF> *> list_polygons_;
QList<QVector<qreal> *> list_arcs_;
QList<QLineF *> list_lines_;
QList<QRectF *> list_rectangles_;
QList<QRectF *> list_circles_;
QList<QVector<QPointF> *> list_polygons_;
QList<QVector<qreal> *> list_arcs_;
// methods
public:
QList<Terminal *> terminals() const override;
QList<Conductor *> conductors() const override;
QList<ElementTextItem *> texts() const override;
QList<QLineF *> lines() const override;
QList<QRectF *> rectangles() const override;
QList<QRectF *> circles() const override;
QList<QVector<QPointF> *> polygons() const override;
QList<QVector<qreal> *> arcs() const override;
int terminalsCount() const override;
void paint(QPainter *, const QStyleOptionGraphicsItem *) override;
QString typeId() const override;
ElementsLocation location() const;
QString name() const override;
ElementTextItem* taggedText(const QString &tagg) const override;
QList<Terminal *> terminals() const override;
QList<Conductor *> conductors() const override;
QList<ElementTextItem *> texts() const override;
QList<QLineF *> lines() const override;
QList<QRectF *> rectangles() const override;
QList<QRectF *> circles() const override;
QList<QVector<QPointF> *> polygons() const override;
QList<QVector<qreal> *> arcs() const override;
int terminalsCount() const override;
void paint(QPainter *, const QStyleOptionGraphicsItem *) override;
QString typeId() const override;
ElementsLocation location() const;
QString name() const override;
ElementTextItem* taggedText(const QString &tagg) const override;
protected:
virtual bool buildFromXml(const QDomElement &, int * = nullptr);
virtual bool parseElement(QDomElement &, QPainter &);
virtual bool parseLine(QDomElement &, QPainter &);
virtual bool parseRect(QDomElement &, QPainter &);
virtual bool parseEllipse(QDomElement &, QPainter &);
virtual bool parseCircle(QDomElement &, QPainter &);
virtual bool parseArc(QDomElement &, QPainter &);
virtual bool parsePolygon(QDomElement &, QPainter &);
virtual bool parseText(QDomElement &, QPainter &);
virtual ElementTextItem *parseInput(QDomElement &);
virtual Terminal *parseTerminal(QDomElement &);
virtual void setQPainterAntiAliasing(QPainter &, bool);
virtual bool validOrientationAttribute(const QDomElement &);
virtual void setPainterStyle(QDomElement &, QPainter &);
ElementTextItem* setTaggedText(const QString &tagg, const QString &newstr, const bool noeditable=false);
virtual bool buildFromXml(const QDomElement &, int * = nullptr);
virtual bool parseElement(QDomElement &, QPainter &);
virtual bool parseLine(QDomElement &, QPainter &);
virtual bool parseRect(QDomElement &, QPainter &);
virtual bool parseEllipse(QDomElement &, QPainter &);
virtual bool parseCircle(QDomElement &, QPainter &);
virtual bool parseArc(QDomElement &, QPainter &);
virtual bool parsePolygon(QDomElement &, QPainter &);
virtual bool parseText(QDomElement &, QPainter &);
virtual ElementTextItem *parseInput(QDomElement &);
virtual DynamicElementTextItem *parseDynamicText(QDomElement &);
virtual Terminal *parseTerminal(QDomElement &);
virtual void setQPainterAntiAliasing(QPainter &, bool);
virtual bool validOrientationAttribute(const QDomElement &);
virtual void setPainterStyle(QDomElement &, QPainter &);
ElementTextItem* setTaggedText(const QString &tagg, const QString &newstr, const bool noeditable=false);
};

View File

@ -86,6 +86,19 @@ DynamicElementTextItem::DynamicElementTextItem(Element *parent_element) :
DynamicElementTextItem::~DynamicElementTextItem()
{}
/**
* @brief DynamicElementTextItem::textFromMetaEnum
* @return The QMetaEnum of the enum TextFrom
*/
QMetaEnum DynamicElementTextItem::textFromMetaEnum()
{
DynamicElementTextItem deti;
return deti.metaObject()->enumerator(deti.metaObject()->indexOfEnumerator("TextFrom"));
}
DynamicElementTextItem::DynamicElementTextItem()
{}
/**
* @brief DynamicElementTextItem::toXml
* Export this text to xml
@ -102,7 +115,7 @@ QDomElement DynamicElementTextItem::toXml(QDomDocument &dom_doc) const
root_element.setAttribute("font_size", font().pointSize());
root_element.setAttribute("uuid", m_uuid.toString());
QMetaEnum me = metaObject()->enumerator(metaObject()->indexOfEnumerator("TextFrom"));
QMetaEnum me = textFromMetaEnum();
root_element.setAttribute("text_from", me.valueToKey(m_text_from));
QDomElement dom_text = dom_doc.createElement("text");
@ -162,7 +175,7 @@ void DynamicElementTextItem::fromXml(const QDomElement &dom_elmt)
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"));
QMetaEnum me = textFromMetaEnum();
m_text_from = DynamicElementTextItem::TextFrom(me.keyToValue(dom_elmt.attribute("text_from").toStdString().data()));
if(m_text_from == ElementInfo || m_text_from == CompositeText)
{
@ -178,7 +191,10 @@ void DynamicElementTextItem::fromXml(const QDomElement &dom_elmt)
//Text
QDomElement dom_text = dom_elmt.firstChildElement("text");
if (!dom_text.isNull())
setPlainText(dom_text.text());
{
m_text = dom_text.text();
setPlainText(m_text);
}
//Info name
QDomElement dom_info_name = dom_elmt.firstChildElement("info_name");

View File

@ -35,6 +35,7 @@ class DynamicElementTextItem : public DiagramTextItem
{
friend class DynamicTextItemDelegate;
friend class CompositeTextEditDialog;
friend class CustomElement;
Q_OBJECT
@ -64,7 +65,9 @@ class DynamicElementTextItem : public DiagramTextItem
public:
DynamicElementTextItem(Element *parent_element);
~DynamicElementTextItem() override;
static QMetaEnum textFromMetaEnum();
private:
DynamicElementTextItem ();
DynamicElementTextItem(const DynamicElementTextItem &);
public:

View File

@ -532,6 +532,12 @@ bool Element::fromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr, bool
} else {
applyRotation(90*read_ori);
}
//Befor load the dynamic text field,
//we remove the dynamic text field created from the description of this element, to avoid doublons.
for(DynamicElementTextItem *deti : m_dynamic_text_list)
delete deti;
m_dynamic_text_list.clear();
//Dynamic texts
for (QDomElement qde : QET::findInDomElement(e, "dynamic_texts", DynamicElementTextItem::xmlTaggName()))
@ -626,7 +632,7 @@ QDomElement Element::toXml(QDomDocument &document, QHash<Terminal *, int> &table
m_element_informations.toXml(infos, "elementInformation");
element.appendChild(infos);
}
//Dynamic texts
QDomElement dyn_text = document.createElement("dynamic_texts");
for (DynamicElementTextItem *deti : m_dynamic_text_list)