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 + 1107
part text field + 1108 part text field + 1108
part rectangle + 1109 part rectangle + 1109
part dynamic text field + 1110
###QetGraphicsHandlerItem### ###QetGraphicsHandlerItem###
QetGraphicsHandlerItem = 1200 QetGraphicsHandlerItem = 1200

View File

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

View File

@ -141,10 +141,10 @@ class ElementScene : public QGraphicsScene
private: private:
QRectF elementContentBoundingRect(const ElementContent &) const; QRectF elementContentBoundingRect(const ElementContent &) const;
bool applyInformations(const QDomDocument &, QString * = nullptr); bool applyInformations(const QDomDocument &);
ElementContent loadContent(const QDomDocument &, QString * = nullptr); ElementContent loadContent(const QDomDocument &);
ElementContent addContent(const ElementContent &, QString * = nullptr); ElementContent addContent(const ElementContent &);
ElementContent addContentAtPos(const ElementContent &, const QPointF &, QString * = nullptr); ElementContent addContentAtPos(const ElementContent &, const QPointF &);
void addPrimitive(QGraphicsItem *); void addPrimitive(QGraphicsItem *);
void initPasteArea(); void initPasteArea();
static bool zValueLessThan(QGraphicsItem *, QGraphicsItem *); 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 "partterminal.h"
#include "parttextfield.h" #include "parttextfield.h"
#include "styleeditor.h" #include "styleeditor.h"
#include "dynamictextfieldeditor.h"
#include "eseventaddline.h" #include "eseventaddline.h"
#include "eseventaddrect.h" #include "eseventaddrect.h"
@ -49,6 +50,7 @@
#include "eseventaddtext.h" #include "eseventaddtext.h"
#include "eseventaddtextfield.h" #include "eseventaddtextfield.h"
#include "eseventaddterminal.h" #include "eseventaddterminal.h"
#include "eseventadddynamictextfield.h"
#include <QMessageBox> #include <QMessageBox>
#include <QTextStream> #include <QTextStream>
@ -101,8 +103,8 @@ QETElementEditor::~QETElementEditor() {
clearToolsDock(); clearToolsDock();
// supprime les editeurs de primitives // supprime les editeurs de primitives
qDeleteAll(editors_.begin(), editors_.end()); qDeleteAll(m_editors.begin(), m_editors.end());
editors_.clear(); m_editors.clear();
} }
/** /**
@ -202,10 +204,10 @@ void QETElementEditor::setupActions() {
connect(selectall, SIGNAL(triggered()), m_elmt_scene, SLOT(slot_selectAll())); connect(selectall, SIGNAL(triggered()), m_elmt_scene, SLOT(slot_selectAll()));
connect(deselectall, SIGNAL(triggered()), m_elmt_scene, SLOT(slot_deselectAll())); connect(deselectall, SIGNAL(triggered()), m_elmt_scene, SLOT(slot_deselectAll()));
connect(inv_select, SIGNAL(triggered()), m_elmt_scene, SLOT(slot_invertSelection())); connect(inv_select, SIGNAL(triggered()), m_elmt_scene, SLOT(slot_invertSelection()));
connect(cut, SIGNAL(triggered()), ce_view, SLOT(cut())); connect(cut, SIGNAL(triggered()), m_view, SLOT(cut()));
connect(copy, SIGNAL(triggered()), ce_view, SLOT(copy())); connect(copy, SIGNAL(triggered()), m_view, SLOT(copy()));
connect(paste, SIGNAL(triggered()), ce_view, SLOT(paste())); connect(paste, SIGNAL(triggered()), m_view, SLOT(paste()));
connect(paste_in_area, SIGNAL(triggered()), ce_view, SLOT(pasteInArea())); connect(paste_in_area, SIGNAL(triggered()), m_view, SLOT(pasteInArea()));
connect(paste_from_file, SIGNAL(triggered()), this, SLOT(pasteFromFile())); connect(paste_from_file, SIGNAL(triggered()), this, SLOT(pasteFromFile()));
connect(paste_from_elmt, SIGNAL(triggered()), this, SLOT(pasteFromElement())); connect(paste_from_elmt, SIGNAL(triggered()), this, SLOT(pasteFromElement()));
connect(edit_delete, SIGNAL(triggered()), m_elmt_scene, SLOT(slot_delete())); 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_fit -> setShortcut(QKeySequence(tr("Ctrl+9")));
zoom_reset -> setShortcut(QKeySequence(tr("Ctrl+0"))); zoom_reset -> setShortcut(QKeySequence(tr("Ctrl+0")));
connect(zoom_in, SIGNAL(triggered()), ce_view, SLOT(zoomIn() )); connect(zoom_in, SIGNAL(triggered()), m_view, SLOT(zoomIn() ));
connect(zoom_out, SIGNAL(triggered()), ce_view, SLOT(zoomOut() )); connect(zoom_out, SIGNAL(triggered()), m_view, SLOT(zoomOut() ));
connect(zoom_fit, SIGNAL(triggered()), ce_view, SLOT(zoomFit() )); connect(zoom_fit, SIGNAL(triggered()), m_view, SLOT(zoomFit() ));
connect(zoom_reset, SIGNAL(triggered()), ce_view, SLOT(zoomReset() )); 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_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_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_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); 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_arc, SIGNAL(triggered()), this, SLOT(addArc() ));
connect(add_terminal, SIGNAL(triggered()), this, SLOT(addTerminal() )); connect(add_terminal, SIGNAL(triggered()), this, SLOT(addTerminal() ));
connect(add_textfield, SIGNAL(triggered()), this, SLOT(addTextField() )); 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")); parts_toolbar = addToolBar(tr("Parties", "toolbar title"));
@ -440,7 +444,7 @@ void QETElementEditor::slot_updateMenus() {
inv_select -> setEnabled(!read_only); inv_select -> setEnabled(!read_only);
paste_from_file -> setEnabled(!read_only); paste_from_file -> setEnabled(!read_only);
paste_from_elmt -> 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 // Action enabled if primitive selected
deselectall -> setEnabled(selected_items); deselectall -> setEnabled(selected_items);
@ -479,69 +483,70 @@ void QETElementEditor::slot_updateTitle() {
void QETElementEditor::setupInterface() { void QETElementEditor::setupInterface() {
// editeur // editeur
m_elmt_scene = new ElementScene(this, this); 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(); slot_setRubberBandToView();
setCentralWidget(ce_view); setCentralWidget(m_view);
// widget par defaut dans le QDockWidget // 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) // ScrollArea pour accueillir un widget d'edition (change a la volee)
tools_dock_scroll_area_ = new QScrollArea(); m_tools_dock_scroll_area = new QScrollArea();
tools_dock_scroll_area_ -> setFrameStyle(QFrame::NoFrame); m_tools_dock_scroll_area -> setFrameStyle(QFrame::NoFrame);
tools_dock_scroll_area_ -> setAlignment(Qt::AlignHCenter|Qt::AlignTop); m_tools_dock_scroll_area -> setAlignment(Qt::AlignHCenter|Qt::AlignTop);
// Pile de widgets pour accueillir les deux widgets precedents // Pile de widgets pour accueillir les deux widgets precedents
tools_dock_stack_ = new QStackedWidget(); m_tools_dock_stack = new QStackedWidget();
tools_dock_stack_ -> insertWidget(0, default_informations); m_tools_dock_stack -> insertWidget(0, m_default_informations);
tools_dock_stack_ -> insertWidget(1, tools_dock_scroll_area_); m_tools_dock_stack -> insertWidget(1, m_tools_dock_scroll_area);
// widgets d'editions pour les parties // widgets d'editions pour les parties
editors_["arc"] = new ArcEditor(this); m_editors["arc"] = new ArcEditor(this);
editors_["ellipse"] = new EllipseEditor(this); m_editors["ellipse"] = new EllipseEditor(this);
editors_["line"] = new LineEditor(this); m_editors["line"] = new LineEditor(this);
editors_["polygon"] = new PolygonEditor(this); m_editors["polygon"] = new PolygonEditor(this);
editors_["rect"] = new RectangleEditor(this); m_editors["rect"] = new RectangleEditor(this);
editors_["terminal"] = new TerminalEditor(this); m_editors["terminal"] = new TerminalEditor(this);
editors_["text"] = new TextEditor(this); m_editors["text"] = new TextEditor(this);
editors_["input"] = new TextFieldEditor(this); m_editors["input"] = new TextFieldEditor(this);
editors_["style"] = new StyleEditor(this); m_editors["style"] = new StyleEditor(this);
m_editors["dynamic_text"] = new DynamicTextFieldEditor(this);
// panel sur le cote pour editer les parties // panel sur le cote pour editer les parties
tools_dock = new QDockWidget(tr("Informations", "dock title"), this); m_tools_dock = new QDockWidget(tr("Informations", "dock title"), this);
tools_dock -> setObjectName("informations"); m_tools_dock -> setObjectName("informations");
tools_dock -> setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); m_tools_dock -> setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
tools_dock -> setFeatures(QDockWidget::AllDockWidgetFeatures); m_tools_dock -> setFeatures(QDockWidget::AllDockWidgetFeatures);
tools_dock -> setMinimumWidth(380); //m_tools_dock -> setMinimumWidth(380);
addDockWidget(Qt::RightDockWidgetArea, tools_dock); addDockWidget(Qt::RightDockWidgetArea, m_tools_dock);
tools_dock -> setWidget(tools_dock_stack_); m_tools_dock -> setWidget(m_tools_dock_stack);
// panel sur le cote pour les annulations // panel sur le cote pour les annulations
undo_dock = new QDockWidget(tr("Annulations", "dock title"), this); m_undo_dock = new QDockWidget(tr("Annulations", "dock title"), this);
undo_dock -> setObjectName("undo"); m_undo_dock -> setObjectName("undo");
undo_dock -> setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); m_undo_dock -> setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
undo_dock -> setFeatures(QDockWidget::AllDockWidgetFeatures); m_undo_dock -> setFeatures(QDockWidget::AllDockWidgetFeatures);
undo_dock -> setMinimumWidth(290); m_undo_dock -> setMinimumWidth(290);
addDockWidget(Qt::RightDockWidgetArea, undo_dock); addDockWidget(Qt::RightDockWidgetArea, m_undo_dock);
QUndoView* undo_view = new QUndoView(&(m_elmt_scene -> undoStack()), this); QUndoView* undo_view = new QUndoView(&(m_elmt_scene -> undoStack()), this);
undo_view -> setEmptyLabel(tr("Aucune modification")); 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 // panel sur le cote pour la liste des parties
parts_list = new QListWidget(this); m_parts_list = new QListWidget(this);
parts_list -> setSelectionMode(QAbstractItemView::ExtendedSelection); m_parts_list -> setSelectionMode(QAbstractItemView::ExtendedSelection);
connect(m_elmt_scene, SIGNAL(partsAdded()), this, SLOT(slot_createPartsList())); 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(partsRemoved()), this, SLOT(slot_createPartsList()));
connect(m_elmt_scene, SIGNAL(partsZValueChanged()), 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(m_elmt_scene, SIGNAL(selectionChanged()), this, SLOT(slot_updatePartsList()));
connect(parts_list, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateSelectionFromPartsList())); connect(m_parts_list, SIGNAL(itemSelectionChanged()), this, SLOT(slot_updateSelectionFromPartsList()));
parts_dock = new QDockWidget(tr("Parties", "dock title"), this); m_parts_dock = new QDockWidget(tr("Parties", "dock title"), this);
parts_dock -> setObjectName("parts_list"); m_parts_dock -> setObjectName("parts_list");
parts_dock -> setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); m_parts_dock -> setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
parts_dock -> setFeatures(QDockWidget::AllDockWidgetFeatures); m_parts_dock -> setFeatures(QDockWidget::AllDockWidgetFeatures);
parts_dock -> setMinimumWidth(290); m_parts_dock -> setMinimumWidth(290);
tabifyDockWidget(undo_dock, parts_dock); tabifyDockWidget(m_undo_dock, m_parts_dock);
parts_dock -> setWidget(parts_list); m_parts_dock -> setWidget(m_parts_list);
slot_updateInformations(); slot_updateInformations();
slot_createPartsList(); slot_createPartsList();
@ -555,14 +560,14 @@ void QETElementEditor::setupInterface() {
elements selectionnes et il est possible d'utiliser un rectangle de selection. elements selectionnes et il est possible d'utiliser un rectangle de selection.
*/ */
void QETElementEditor::slot_setRubberBandToView() { 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) Passe l'editeur d'element en mode immobile (utilise pour la lecture seule)
*/ */
void QETElementEditor::slot_setNoDragToView() { 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 Si plusieurs primitives sont selectionnees, seule leur quantite est
affichee. Sinon, un widget d'edition approprie est mis en place. 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<QGraphicsItem *> selected_qgis = m_elmt_scene -> selectedItems();
QList<CustomElementPart *> cep_list; QList<CustomElementPart *> cep_list;
bool style_editable = false; 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 //There's one selected item
if (selected_qgis.size() == 1) if (selected_qgis.size() == 1)
@ -599,15 +619,22 @@ void QETElementEditor::slot_updateInformations() {
QGraphicsItem *qgi = selected_qgis.first(); QGraphicsItem *qgi = selected_qgis.first();
if (CustomElementPart *selection = dynamic_cast<CustomElementPart *>(qgi)) 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(); 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)
{ {
if (selection_editor -> setPart(selection)) if (selection_editor->setPart(selection))
{ {
tools_dock_scroll_area_ -> setWidget(selection_editor); m_tools_dock_scroll_area -> setWidget(selection_editor);
tools_dock_stack_ -> setCurrentIndex(1); m_tools_dock_stack -> setCurrentIndex(1);
} }
else else
{ {
@ -619,13 +646,14 @@ void QETElementEditor::slot_updateInformations() {
//There's several parts selecteds and all can be edited by style editor. //There's several parts selecteds and all can be edited by style editor.
else if (style_editable) else if (style_editable)
{ {
ElementItemEditor *selection_editor = editors_["style"]; clearToolsDock();
ElementItemEditor *selection_editor = m_editors["style"];
if (selection_editor) if (selection_editor)
{ {
if (selection_editor -> setParts(cep_list)) if (selection_editor -> setParts(cep_list))
{ {
tools_dock_scroll_area_ -> setWidget(selection_editor); m_tools_dock_scroll_area -> setWidget(selection_editor);
tools_dock_stack_ -> setCurrentIndex(1); m_tools_dock_stack -> setCurrentIndex(1);
} }
else else
{ {
@ -636,26 +664,15 @@ void QETElementEditor::slot_updateInformations() {
//Else we only display the number of selected items //Else we only display the number of selected items
else 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())); selected_qgis.size()));
default_informations -> setAlignment(Qt::AlignHCenter | Qt::AlignTop); m_default_informations -> setAlignment(Qt::AlignHCenter | Qt::AlignTop);
tools_dock_stack_ -> setCurrentIndex(0); 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 * @brief QETElementEditor::checkElement
* Do several check about element. * Do several check about element.
@ -919,7 +936,7 @@ void QETElementEditor::setReadOnly(bool ro) {
read_only = ro; read_only = ro;
// active / desactive les interactions avec la scene // active / desactive les interactions avec la scene
ce_view -> setInteractive(!ro); m_view -> setInteractive(!ro);
slot_updateMenus(); slot_updateMenus();
} }
@ -995,6 +1012,14 @@ void QETElementEditor::addTerminal() {
m_elmt_scene -> setEventInterface(new ESEventAddTerminal(m_elmt_scene)); 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 * @brief QETElementEditor::UncheckAddPrimitive
* Uncheck all action related to primitive * 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 @return le widget enleve, ou 0 s'il n'y avait pas de widget a enlever
*/ */
QWidget *QETElementEditor::clearToolsDock() { 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 -> setParent(nullptr);
previous_widget -> hide(); previous_widget -> hide();
return(previous_widget); return(previous_widget);
@ -1293,7 +1318,7 @@ void QETElementEditor::copyAndPasteXml(const QDomDocument &xml_document) {
} }
clipboard -> setText(clipboard_content); clipboard -> setText(clipboard_content);
ce_view -> pasteInArea(); m_view -> pasteInArea();
} }
/** /**
@ -1314,15 +1339,15 @@ void QETElementEditor::closeEvent(QCloseEvent *qce) {
*/ */
void QETElementEditor::firstActivation(QEvent *event) { void QETElementEditor::firstActivation(QEvent *event) {
Q_UNUSED(event) Q_UNUSED(event)
QTimer::singleShot(250, ce_view, SLOT(zoomFit())); QTimer::singleShot(250, m_view, SLOT(zoomFit()));
} }
/** /**
Remplit la liste des parties Remplit la liste des parties
*/ */
void QETElementEditor::slot_createPartsList() { void QETElementEditor::slot_createPartsList() {
parts_list -> blockSignals(true); m_parts_list -> blockSignals(true);
parts_list -> clear(); m_parts_list -> clear();
QList<QGraphicsItem *> qgis = m_elmt_scene -> zItems(); QList<QGraphicsItem *> qgis = m_elmt_scene -> zItems();
// on ne construit plus la liste a partir de 200 primitives // on ne construit plus la liste a partir de 200 primitives
@ -1337,14 +1362,14 @@ void QETElementEditor::slot_createPartsList() {
QVariant v; QVariant v;
v.setValue<QGraphicsItem *>(qgi); v.setValue<QGraphicsItem *>(qgi);
qlwi -> setData(42, v); qlwi -> setData(42, v);
parts_list -> addItem(qlwi); m_parts_list -> addItem(qlwi);
qlwi -> setSelected(qgi -> isSelected()); qlwi -> setSelected(qgi -> isSelected());
} }
} }
} else { } 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() { void QETElementEditor::slot_updatePartsList() {
int items_count = m_elmt_scene -> items().count(); int items_count = m_elmt_scene -> items().count();
if (parts_list -> count() != items_count) { if (m_parts_list -> count() != items_count) {
slot_createPartsList(); slot_createPartsList();
} else if (items_count <= QET_MAX_PARTS_IN_ELEMENT_EDITOR_LIST) { } else if (items_count <= QET_MAX_PARTS_IN_ELEMENT_EDITOR_LIST) {
parts_list -> blockSignals(true); m_parts_list -> blockSignals(true);
int i = 0; int i = 0;
QList<QGraphicsItem *> items = m_elmt_scene -> zItems(); QList<QGraphicsItem *> items = m_elmt_scene -> zItems();
for (int j = items.count() - 1 ; j >= 0 ; -- j) { for (int j = items.count() - 1 ; j >= 0 ; -- j) {
QGraphicsItem *qgi = items[j]; QGraphicsItem *qgi = items[j];
QListWidgetItem *qlwi = parts_list -> item(i); QListWidgetItem *qlwi = m_parts_list -> item(i);
if (qlwi) qlwi -> setSelected(qgi -> isSelected()); if (qlwi) qlwi -> setSelected(qgi -> isSelected());
++ i; ++ i;
} }
parts_list -> blockSignals(false); m_parts_list -> blockSignals(false);
} }
} }
@ -1374,15 +1399,15 @@ void QETElementEditor::slot_updatePartsList() {
*/ */
void QETElementEditor::slot_updateSelectionFromPartsList() { void QETElementEditor::slot_updateSelectionFromPartsList() {
m_elmt_scene -> blockSignals(true); m_elmt_scene -> blockSignals(true);
parts_list -> blockSignals(true); m_parts_list -> blockSignals(true);
for (int i = 0 ; i < parts_list -> count() ; ++ i) { for (int i = 0 ; i < m_parts_list -> count() ; ++ i) {
QListWidgetItem *qlwi = parts_list -> item(i); QListWidgetItem *qlwi = m_parts_list -> item(i);
QGraphicsItem *qgi = qlwi -> data(42).value<QGraphicsItem *>(); QGraphicsItem *qgi = qlwi -> data(42).value<QGraphicsItem *>();
if (qgi) { if (qgi) {
qgi -> setSelected(qlwi -> isSelected()); qgi -> setSelected(qlwi -> isSelected());
} }
} }
parts_list -> blockSignals(false); m_parts_list -> blockSignals(false);
m_elmt_scene -> blockSignals(false); m_elmt_scene -> blockSignals(false);
slot_updateInformations(); slot_updateInformations();
slot_updateMenus(); slot_updateMenus();
@ -1570,10 +1595,10 @@ void QETElementEditor::pasteFromElement()
*/ */
void QETElementEditor::updateCurrentPartEditor() { void QETElementEditor::updateCurrentPartEditor() {
// si aucun widget d'edition n'est affiche, on ne fait rien // 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 // 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(); current_editor -> updateForm();
} }
} }

View File

@ -51,25 +51,25 @@ class QETElementEditor : public QETMainWindow {
/// menus /// menus
QMenu *file_menu, *edit_menu, *paste_from_menu, *display_menu, *tools_menu; QMenu *file_menu, *edit_menu, *paste_from_menu, *display_menu, *tools_menu;
/// view widget for the editing scene /// view widget for the editing scene
ElementView *ce_view; ElementView *m_view;
/// editing scene /// editing scene
ElementScene *m_elmt_scene; ElementScene *m_elmt_scene;
/// container for widgets dedicated to primitive edition /// container for widgets dedicated to primitive edition
QDockWidget *tools_dock; QDockWidget *m_tools_dock;
/// Stack of widgets for tools_dock /// Stack of widgets for tools_dock
QStackedWidget *tools_dock_stack_; QStackedWidget *m_tools_dock_stack;
/// label displayed when several primitives are selected /// label displayed when several primitives are selected
QLabel *default_informations; QLabel *m_default_informations;
/// Hash associating primitive names with their matching edition widget /// Hash associating primitive names with their matching edition widget
QHash<QString, ElementItemEditor *> editors_; QHash<QString, ElementItemEditor *> m_editors;
/// ScrollArea for the tools_dock DockWidget /// ScrollArea for the tools_dock DockWidget
QScrollArea *tools_dock_scroll_area_; QScrollArea *m_tools_dock_scroll_area;
/// container for the undo list /// container for the undo list
QDockWidget *undo_dock; QDockWidget *m_undo_dock;
/// Container for the list of existing primitives /// Container for the list of existing primitives
QDockWidget *parts_dock; QDockWidget *m_parts_dock;
/// List of primitives /// List of primitives
QListWidget *parts_list; QListWidget *m_parts_list;
/// actions for the "file" menu /// actions for the "file" menu
QAction *new_element, *open, *open_dxf, *open_file, *save, *save_as, *save_as_file, *reload, *quit; QAction *new_element, *open, *open_dxf, *open_file, *save, *save_as, *save_as_file, *reload, *quit;
/// actions for the "edit" menu /// actions for the "edit" menu
@ -133,6 +133,7 @@ class QETElementEditor : public QETMainWindow {
void addText(); void addText();
void addTextField(); void addTextField();
void addTerminal(); void addTerminal();
void addDynamicTextField();
void UncheckAddPrimitive(); void UncheckAddPrimitive();
void slot_new(); void slot_new();
@ -153,7 +154,6 @@ class QETElementEditor : public QETMainWindow {
void slot_createPartsList(); void slot_createPartsList();
void slot_updatePartsList(); void slot_updatePartsList();
void slot_updateSelectionFromPartsList(); void slot_updateSelectionFromPartsList();
void xmlPreview();
bool checkElement(); bool checkElement();
void pasteFromFile(); void pasteFromFile();
void pasteFromElement(); 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 "terminal.h"
#include "diagramposition.h" #include "diagramposition.h"
#include "diagramcontent.h" #include "diagramcontent.h"
#include "dynamicelementtextitem.h"
/** /**
Constructeur de la classe CustomElement. Permet d'instancier un element 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); return(false);
} }
// verifie basiquement que la version actuelle est capable de lire ce fichier //Check if the curent version can read the xml description
if (xml_def_elmt.hasAttribute("version")) { if (xml_def_elmt.hasAttribute("version"))
{
bool conv_ok; bool conv_ok;
qreal element_version = xml_def_elmt.attribute("version").toDouble(&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( std::cerr << qPrintable(
QObject::tr("Avertissement : l'élément " QObject::tr("Avertissement : l'élément "
" a été enregistré avec une version" " 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; int w, h, hot_x, hot_y;
if ( if (
!QET::attributeIsAnInteger(xml_def_elmt, QString("width"), &w) ||\ !QET::attributeIsAnInteger(xml_def_elmt, QString("width"), &w) ||\
@ -131,61 +134,81 @@ bool CustomElement::buildFromXml(const QDomElement &xml_def_elmt, int *state) {
return(false); return(false);
} }
// initialisation du QPainter (pour dessiner l'element) //Init the QPainter for draw the elemennt
QPainter qp; QPainter qp;
qp.begin(&drawing); qp.begin(&drawing);
QPainter low_zoom_qp; QPainter low_zoom_qp;
low_zoom_qp.begin(&low_zoom_drawing); low_zoom_qp.begin(&low_zoom_drawing);
QPen tmp; 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); tmp.setCosmetic(true);
low_zoom_qp.setPen(tmp); low_zoom_qp.setPen(tmp);
// extrait les noms de la definition XML //Extract the names
names.fromXml(xml_def_elmt); names.fromXml(xml_def_elmt);
setToolTip(name()); setToolTip(name());
//load kind informations //load kind informations
kind_informations_.fromXml(xml_def_elmt.firstChildElement("kindInformations"), "kindInformation"); 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; 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(); QDomElement elmts = node.toElement();
if (elmts.isNull()) continue; if (elmts.isNull())
if (elmts.tagName() == "description") { continue;
// gestion de la description graphique de l'element
// = parcours des differentes parties du dessin if (elmts.tagName() == "description")
for (QDomNode n = node.firstChild() ; !n.isNull() ; n = n.nextSibling()) { {
//Manage the graphic description = part of drawing
for (QDomNode n = node.firstChild() ; !n.isNull() ; n = n.nextSibling())
{
QDomElement qde = n.toElement(); QDomElement qde = n.toElement();
if (qde.isNull()) continue; if (qde.isNull())
if (parseElement(qde, qp)) { continue;
if (parseElement(qde, qp))
{
++ parsed_elements_count; ++ parsed_elements_count;
QString current_tag = qde.tagName(); 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; forbid_antialiasing = true;
parseElement(qde, low_zoom_qp); parseElement(qde, low_zoom_qp);
forbid_antialiasing = false; forbid_antialiasing = false;
} }
} else { }
if (state) *state = 7; else
{
if (state)
*state = 7;
return(false); return(false);
} }
} }
} }
} }
// fin du dessin //End of the drawing
qp.end(); qp.end();
low_zoom_qp.end(); low_zoom_qp.end();
// il doit y avoir au moins un element charge
if (!parsed_elements_count) { //They must be at least one parsed graphics part
if (state) *state = 8; if (!parsed_elements_count)
{
if (state)
*state = 8;
return(false); return(false);
} else { }
if (state) *state = 0; else
{
if (state)
*state = 0;
return(true); 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 @param qp Le QPainter a utiliser pour dessiner l'element perso
@return true si l'analyse reussit, false sinon @return true si l'analyse reussit, false sinon
*/ */
bool CustomElement::parseElement(QDomElement &e, QPainter &qp) { bool CustomElement::parseElement(QDomElement &e, QPainter &qp)
if (e.tagName() == "terminal") return(parseTerminal(e)); {
else if (e.tagName() == "line") return(parseLine(e, qp)); if (e.tagName() == "terminal") return(parseTerminal(e));
else if (e.tagName() == "rect") return(parseRect(e, qp)); else if (e.tagName() == "line") return(parseLine(e, qp));
else if (e.tagName() == "ellipse") return(parseEllipse(e, qp)); else if (e.tagName() == "rect") return(parseRect(e, qp));
else if (e.tagName() == "circle") return(parseCircle(e, qp)); else if (e.tagName() == "ellipse") return(parseEllipse(e, qp));
else if (e.tagName() == "arc") return(parseArc(e, qp)); else if (e.tagName() == "circle") return(parseCircle(e, qp));
else if (e.tagName() == "polygon") return(parsePolygon(e, qp)); else if (e.tagName() == "arc") return(parseArc(e, qp));
else if (e.tagName() == "text") return(parseText(e, qp)); else if (e.tagName() == "polygon") return(parsePolygon(e, qp));
else if (e.tagName() == "input") return(parseInput(e)); else if (e.tagName() == "text") return(parseText(e, qp));
else return(true); // on n'est pas chiant, on ignore l'element inconnu 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); 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 Analyse un element XML suppose representer une borne. Si l'analyse
reussit, la borne est ajoutee a l'element. reussit, la borne est ajoutee a l'element.

View File

@ -54,45 +54,47 @@ class CustomElement : public FixedElement
bool forbid_antialiasing; bool forbid_antialiasing;
QList<QLineF *> list_lines_; QList<QLineF *> list_lines_;
QList<QRectF *> list_rectangles_; QList<QRectF *> list_rectangles_;
QList<QRectF *> list_circles_; QList<QRectF *> list_circles_;
QList<QVector<QPointF> *> list_polygons_; QList<QVector<QPointF> *> list_polygons_;
QList<QVector<qreal> *> list_arcs_; QList<QVector<qreal> *> list_arcs_;
// methods // methods
public: public:
QList<Terminal *> terminals() const override; QList<Terminal *> terminals() const override;
QList<Conductor *> conductors() const override; QList<Conductor *> conductors() const override;
QList<ElementTextItem *> texts() const override; QList<ElementTextItem *> texts() const override;
QList<QLineF *> lines() const override; QList<QLineF *> lines() const override;
QList<QRectF *> rectangles() const override; QList<QRectF *> rectangles() const override;
QList<QRectF *> circles() const override; QList<QRectF *> circles() const override;
QList<QVector<QPointF> *> polygons() const override; QList<QVector<QPointF> *> polygons() const override;
QList<QVector<qreal> *> arcs() const override; QList<QVector<qreal> *> arcs() const override;
int terminalsCount() const override; int terminalsCount() const override;
void paint(QPainter *, const QStyleOptionGraphicsItem *) override; void paint(QPainter *, const QStyleOptionGraphicsItem *) override;
QString typeId() const override; QString typeId() const override;
ElementsLocation location() const; ElementsLocation location() const;
QString name() const override; QString name() const override;
ElementTextItem* taggedText(const QString &tagg) const override; ElementTextItem* taggedText(const QString &tagg) const override;
protected: protected:
virtual bool buildFromXml(const QDomElement &, int * = nullptr); virtual bool buildFromXml(const QDomElement &, int * = nullptr);
virtual bool parseElement(QDomElement &, QPainter &); virtual bool parseElement(QDomElement &, QPainter &);
virtual bool parseLine(QDomElement &, QPainter &); virtual bool parseLine(QDomElement &, QPainter &);
virtual bool parseRect(QDomElement &, QPainter &); virtual bool parseRect(QDomElement &, QPainter &);
virtual bool parseEllipse(QDomElement &, QPainter &); virtual bool parseEllipse(QDomElement &, QPainter &);
virtual bool parseCircle(QDomElement &, QPainter &); virtual bool parseCircle(QDomElement &, QPainter &);
virtual bool parseArc(QDomElement &, QPainter &); virtual bool parseArc(QDomElement &, QPainter &);
virtual bool parsePolygon(QDomElement &, QPainter &); virtual bool parsePolygon(QDomElement &, QPainter &);
virtual bool parseText(QDomElement &, QPainter &); virtual bool parseText(QDomElement &, QPainter &);
virtual ElementTextItem *parseInput(QDomElement &); virtual ElementTextItem *parseInput(QDomElement &);
virtual Terminal *parseTerminal(QDomElement &); virtual DynamicElementTextItem *parseDynamicText(QDomElement &);
virtual void setQPainterAntiAliasing(QPainter &, bool); virtual Terminal *parseTerminal(QDomElement &);
virtual bool validOrientationAttribute(const QDomElement &);
virtual void setPainterStyle(QDomElement &, QPainter &); virtual void setQPainterAntiAliasing(QPainter &, bool);
ElementTextItem* setTaggedText(const QString &tagg, const QString &newstr, const bool noeditable=false); 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() 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 * @brief DynamicElementTextItem::toXml
* Export this text to xml * 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("font_size", font().pointSize());
root_element.setAttribute("uuid", m_uuid.toString()); 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)); root_element.setAttribute("text_from", me.valueToKey(m_text_from));
QDomElement dom_text = dom_doc.createElement("text"); 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())); setFont(QETApp::diagramTextsFont(dom_elmt.attribute("font_size", QString::number(9)).toInt()));
m_uuid = QUuid(dom_elmt.attribute("uuid", QUuid::createUuid().toString())); 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())); m_text_from = DynamicElementTextItem::TextFrom(me.keyToValue(dom_elmt.attribute("text_from").toStdString().data()));
if(m_text_from == ElementInfo || m_text_from == CompositeText) if(m_text_from == ElementInfo || m_text_from == CompositeText)
{ {
@ -178,7 +191,10 @@ void DynamicElementTextItem::fromXml(const QDomElement &dom_elmt)
//Text //Text
QDomElement dom_text = dom_elmt.firstChildElement("text"); QDomElement dom_text = dom_elmt.firstChildElement("text");
if (!dom_text.isNull()) if (!dom_text.isNull())
setPlainText(dom_text.text()); {
m_text = dom_text.text();
setPlainText(m_text);
}
//Info name //Info name
QDomElement dom_info_name = dom_elmt.firstChildElement("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 DynamicTextItemDelegate;
friend class CompositeTextEditDialog; friend class CompositeTextEditDialog;
friend class CustomElement;
Q_OBJECT Q_OBJECT
@ -64,7 +65,9 @@ class DynamicElementTextItem : public DiagramTextItem
public: public:
DynamicElementTextItem(Element *parent_element); DynamicElementTextItem(Element *parent_element);
~DynamicElementTextItem() override; ~DynamicElementTextItem() override;
static QMetaEnum textFromMetaEnum();
private: private:
DynamicElementTextItem ();
DynamicElementTextItem(const DynamicElementTextItem &); DynamicElementTextItem(const DynamicElementTextItem &);
public: public:

View File

@ -532,6 +532,12 @@ bool Element::fromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr, bool
} else { } else {
applyRotation(90*read_ori); 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 //Dynamic texts
for (QDomElement qde : QET::findInDomElement(e, "dynamic_texts", DynamicElementTextItem::xmlTaggName())) 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"); m_element_informations.toXml(infos, "elementInformation");
element.appendChild(infos); element.appendChild(infos);
} }
//Dynamic texts //Dynamic texts
QDomElement dyn_text = document.createElement("dynamic_texts"); QDomElement dyn_text = document.createElement("dynamic_texts");
for (DynamicElementTextItem *deti : m_dynamic_text_list) for (DynamicElementTextItem *deti : m_dynamic_text_list)