2007-12-01 10:47:15 +00:00
|
|
|
/*
|
2017-01-20 10:55:49 +00:00
|
|
|
Copyright 2006-2017 The QElectroTech Team
|
2007-12-01 10:47:15 +00:00
|
|
|
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/>.
|
|
|
|
*/
|
2006-10-27 15:47:22 +00:00
|
|
|
#include "element.h"
|
2007-01-29 00:41:12 +00:00
|
|
|
#include "diagram.h"
|
2007-10-03 17:02:39 +00:00
|
|
|
#include "conductor.h"
|
2007-02-24 00:26:04 +00:00
|
|
|
#include "elementtextitem.h"
|
2007-09-26 17:14:09 +00:00
|
|
|
#include "diagramcommands.h"
|
2006-10-27 15:47:22 +00:00
|
|
|
#include <QtDebug>
|
2013-12-31 14:39:34 +00:00
|
|
|
#include "elementprovider.h"
|
2014-03-18 12:35:36 +00:00
|
|
|
#include "diagramposition.h"
|
2014-07-21 20:44:32 +00:00
|
|
|
#include "terminal.h"
|
2015-06-23 20:40:05 +00:00
|
|
|
#include "PropertiesEditor/propertieseditordialog.h"
|
|
|
|
#include "elementpropertieswidget.h"
|
2016-07-10 01:33:49 +00:00
|
|
|
#include "numerotationcontextcommands.h"
|
2016-07-20 15:07:21 +00:00
|
|
|
#include "diagramcontext.h"
|
2016-12-08 16:54:41 +00:00
|
|
|
#include "changeelementinformationcommand.h"
|
2017-08-03 17:36:08 +00:00
|
|
|
#include "dynamicelementtextitem.h"
|
2017-11-27 19:37:39 +00:00
|
|
|
#include "elementtextitemgroup.h"
|
2006-10-27 15:47:22 +00:00
|
|
|
|
2016-12-08 15:06:46 +00:00
|
|
|
class ElementXmlRetroCompatibility
|
|
|
|
{
|
|
|
|
friend class Element;
|
|
|
|
|
|
|
|
static void loadSequential(const QDomElement &dom_element, QString seq, QStringList* list)
|
|
|
|
{
|
|
|
|
int i = 0;
|
|
|
|
while (!dom_element.attribute(seq + QString::number(i+1)).isEmpty())
|
|
|
|
{
|
|
|
|
list->append(dom_element.attribute(seq + QString::number(i+1)));
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void loadSequential(const QDomElement &dom_element, Element *element)
|
|
|
|
{
|
|
|
|
autonum::sequentialNumbers sn;
|
|
|
|
|
|
|
|
loadSequential(dom_element,"sequ_",&sn.unit);
|
|
|
|
loadSequential(dom_element,"sequf_",&sn.unit_folio);
|
|
|
|
loadSequential(dom_element,"seqt_",&sn.ten);
|
|
|
|
loadSequential(dom_element,"seqtf_",&sn.ten_folio);
|
|
|
|
loadSequential(dom_element,"seqh_",&sn.hundred);
|
|
|
|
loadSequential(dom_element,"seqhf_",&sn.hundred_folio);
|
|
|
|
|
|
|
|
element->rSequenceStruct() = sn;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2006-10-27 15:47:22 +00:00
|
|
|
/**
|
|
|
|
Constructeur pour un element sans scene ni parent
|
|
|
|
*/
|
2014-12-14 13:06:21 +00:00
|
|
|
Element::Element(QGraphicsItem *parent) :
|
2013-11-14 10:11:22 +00:00
|
|
|
QetGraphicsItem(parent),
|
2014-11-16 14:15:32 +00:00
|
|
|
must_highlight_(false),
|
2014-12-14 18:51:49 +00:00
|
|
|
m_mouse_over(false)
|
2007-12-09 10:30:35 +00:00
|
|
|
{
|
2018-01-19 12:17:20 +00:00
|
|
|
m_link_type = Simple;
|
2013-12-31 14:39:34 +00:00
|
|
|
uuid_ = QUuid::createUuid();
|
2006-12-03 12:48:33 +00:00
|
|
|
setZValue(10);
|
2014-10-10 08:58:44 +00:00
|
|
|
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
|
2015-03-02 20:14:56 +00:00
|
|
|
setAcceptHoverEvents(true);
|
2006-10-27 15:47:22 +00:00
|
|
|
}
|
|
|
|
|
2007-04-12 03:13:13 +00:00
|
|
|
/**
|
|
|
|
Destructeur
|
|
|
|
*/
|
2017-08-03 17:36:08 +00:00
|
|
|
Element::~Element()
|
|
|
|
{
|
|
|
|
qDeleteAll(m_dynamic_text_list);
|
2007-04-12 03:13:13 +00:00
|
|
|
}
|
|
|
|
|
2015-06-23 20:40:05 +00:00
|
|
|
void Element::editProperty()
|
|
|
|
{
|
|
|
|
if (diagram() && !diagram()->isReadOnly())
|
|
|
|
{
|
|
|
|
ElementPropertiesWidget *epw = new ElementPropertiesWidget(this);
|
|
|
|
PropertiesEditorDialog dialog(epw, QApplication::activeWindow());
|
|
|
|
connect(epw, &ElementPropertiesWidget::findEditClicked, &dialog, &QDialog::reject);
|
|
|
|
dialog.exec();
|
|
|
|
}
|
2013-11-29 14:42:03 +00:00
|
|
|
}
|
|
|
|
|
2014-03-18 12:35:36 +00:00
|
|
|
|
|
|
|
|
2010-04-25 12:12:59 +00:00
|
|
|
/**
|
|
|
|
@return true si l'element est mis en evidence
|
|
|
|
*/
|
|
|
|
bool Element::isHighlighted() const {
|
|
|
|
return(must_highlight_);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
@param hl true pour mettre l'element en evidence, false sinon
|
|
|
|
*/
|
|
|
|
void Element::setHighlighted(bool hl) {
|
|
|
|
must_highlight_ = hl;
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
2015-03-04 21:13:13 +00:00
|
|
|
/**
|
|
|
|
* @brief Element::displayHelpLine
|
|
|
|
* Display the help line of each terminal if b is true
|
|
|
|
* @param b
|
|
|
|
*/
|
|
|
|
void Element::displayHelpLine(bool b)
|
|
|
|
{
|
2017-02-05 16:18:50 +00:00
|
|
|
foreach (Terminal *t, terminals())
|
2015-03-04 21:13:13 +00:00
|
|
|
t->drawHelpLine(b);
|
|
|
|
}
|
|
|
|
|
2006-10-27 15:47:22 +00:00
|
|
|
/**
|
2015-09-16 15:11:13 +00:00
|
|
|
* @brief Element::paint
|
|
|
|
* @param painter
|
|
|
|
* @param options
|
|
|
|
* @param widget
|
|
|
|
*/
|
2015-11-19 15:19:45 +00:00
|
|
|
void Element::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *)
|
2015-09-16 15:11:13 +00:00
|
|
|
{
|
2015-11-19 15:19:45 +00:00
|
|
|
|
2010-04-25 12:12:59 +00:00
|
|
|
if (must_highlight_) drawHighlight(painter, options);
|
|
|
|
|
2014-12-14 18:51:49 +00:00
|
|
|
//Draw the element himself
|
2006-10-27 15:47:22 +00:00
|
|
|
paint(painter, options);
|
|
|
|
|
2014-12-14 18:51:49 +00:00
|
|
|
//Draw the selection rectangle
|
|
|
|
if ( isSelected() || m_mouse_over ) drawSelection(painter, options);
|
2006-10-27 15:47:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
@return Le rectangle delimitant le contour de l'element
|
|
|
|
*/
|
|
|
|
QRectF Element::boundingRect() const {
|
|
|
|
return(QRectF(QPointF(-hotspot_coord.x(), -hotspot_coord.y()), dimensions));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Definit la taille de l'element sur le schema. Les tailles doivent etre
|
|
|
|
des multiples de 10 ; si ce n'est pas le cas, les dimensions indiquees
|
|
|
|
seront arrrondies aux dizaines superieures.
|
|
|
|
@param wid Largeur de l'element
|
|
|
|
@param hei Hauteur de l'element
|
|
|
|
@return La taille finale de l'element
|
|
|
|
*/
|
|
|
|
QSize Element::setSize(int wid, int hei) {
|
|
|
|
prepareGeometryChange();
|
|
|
|
// chaque dimension indiquee est arrondie a la dizaine superieure
|
|
|
|
while (wid % 10) ++ wid;
|
|
|
|
while (hei % 10) ++ hei;
|
|
|
|
// les dimensions finales sont conservees et retournees
|
|
|
|
return(dimensions = QSize(wid, hei));
|
|
|
|
}
|
|
|
|
|
2009-05-17 02:13:40 +00:00
|
|
|
/**
|
|
|
|
@return la taille de l'element sur le schema
|
|
|
|
*/
|
|
|
|
QSize Element::size() const {
|
|
|
|
return(dimensions);
|
|
|
|
}
|
|
|
|
|
2006-10-27 15:47:22 +00:00
|
|
|
/**
|
|
|
|
Definit le hotspot de l'element par rapport au coin superieur gauche de son rectangle delimitant.
|
|
|
|
Necessite que la taille ait deja ete definie
|
2007-10-21 16:10:21 +00:00
|
|
|
@param hs Coordonnees du hotspot
|
2006-10-27 15:47:22 +00:00
|
|
|
*/
|
|
|
|
QPoint Element::setHotspot(QPoint hs) {
|
|
|
|
// la taille doit avoir ete definie
|
|
|
|
prepareGeometryChange();
|
|
|
|
if (dimensions.isNull()) hotspot_coord = QPoint(0, 0);
|
|
|
|
else {
|
|
|
|
// les coordonnees indiquees ne doivent pas depasser les dimensions de l'element
|
2007-01-20 18:11:42 +00:00
|
|
|
int hsx = qMin(hs.x(), dimensions.width());
|
|
|
|
int hsy = qMin(hs.y(), dimensions.height());
|
2006-10-27 15:47:22 +00:00
|
|
|
hotspot_coord = QPoint(hsx, hsy);
|
|
|
|
}
|
|
|
|
return(hotspot_coord);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
@return Le hotspot courant de l'element
|
|
|
|
*/
|
|
|
|
QPoint Element::hotspot() const {
|
|
|
|
return(hotspot_coord);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Selectionne l'element
|
|
|
|
*/
|
|
|
|
void Element::select() {
|
|
|
|
setSelected(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Deselectionne l'element
|
|
|
|
*/
|
|
|
|
void Element::deselect() {
|
|
|
|
setSelected(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
@return La pixmap de l'element
|
|
|
|
*/
|
|
|
|
QPixmap Element::pixmap() {
|
2009-04-03 19:30:25 +00:00
|
|
|
if (preview.isNull()) updatePixmap(); // on genere la pixmap si ce n'est deja fait
|
|
|
|
return(preview);
|
2006-10-27 15:47:22 +00:00
|
|
|
}
|
|
|
|
|
2007-04-09 02:56:47 +00:00
|
|
|
/**
|
2013-11-14 10:11:22 +00:00
|
|
|
* @brief Element::rotateBy
|
|
|
|
* this methode is redefined for handle child item
|
|
|
|
* @param angle
|
|
|
|
*/
|
|
|
|
void Element::rotateBy(const qreal &angle) {
|
|
|
|
qreal applied_angle = QET::correctAngle(angle);
|
|
|
|
applyRotation(applied_angle + rotation());
|
|
|
|
|
|
|
|
//update the path of conductor
|
2017-02-05 16:18:50 +00:00
|
|
|
foreach(QGraphicsItem *qgi, childItems()) {
|
2010-04-11 16:03:40 +00:00
|
|
|
if (Terminal *p = qgraphicsitem_cast<Terminal *>(qgi)) {
|
|
|
|
p -> updateConductor();
|
2007-02-24 00:26:04 +00:00
|
|
|
}
|
2006-12-02 23:42:59 +00:00
|
|
|
}
|
2013-11-14 10:11:22 +00:00
|
|
|
|
|
|
|
// repositionne les textes de l'element qui ne comportent pas l'option "FollowParentRotations"
|
2017-02-05 16:18:50 +00:00
|
|
|
foreach(ElementTextItem *eti, texts()) {
|
2013-11-14 10:11:22 +00:00
|
|
|
if (!eti -> followParentRotations()) {
|
|
|
|
// on souhaite pivoter le champ de texte par rapport a son centre
|
|
|
|
QPointF eti_center = eti -> boundingRect().center();
|
|
|
|
// pour ce faire, on repere la position de son centre par rapport a son parent
|
|
|
|
QPointF parent_eti_center_before = eti -> mapToParent(eti_center);
|
|
|
|
// on applique ensuite une simple rotation contraire, qui sera donc appliquee sur le milieu du cote gauche du champ de texte
|
|
|
|
eti -> rotateBy(-applied_angle);
|
|
|
|
// on regarde ensuite la nouvelle position du centre du champ de texte par rapport a son parent
|
|
|
|
QPointF parent_eti_center_after = eti -> mapToParent(eti_center);
|
|
|
|
// on determine la translation a appliquer
|
|
|
|
QPointF eti_translation = parent_eti_center_before - parent_eti_center_after;
|
|
|
|
// on applique cette translation
|
|
|
|
eti -> setPos(eti -> pos() + eti_translation);
|
|
|
|
}
|
|
|
|
}
|
2006-10-27 15:47:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*** Methodes protegees ***/
|
|
|
|
|
|
|
|
/**
|
|
|
|
Dessine un petit repere (axes x et y) relatif a l'element
|
|
|
|
@param painter Le QPainter a utiliser pour dessiner les axes
|
|
|
|
@param options Les options de style a prendre en compte
|
|
|
|
*/
|
2009-11-22 16:12:22 +00:00
|
|
|
void Element::drawAxes(QPainter *painter, const QStyleOptionGraphicsItem *options) {
|
|
|
|
Q_UNUSED(options);
|
2006-10-27 15:47:22 +00:00
|
|
|
painter -> setPen(Qt::blue);
|
|
|
|
painter -> drawLine(0, 0, 10, 0);
|
|
|
|
painter -> drawLine(7,-3, 10, 0);
|
|
|
|
painter -> drawLine(7, 3, 10, 0);
|
|
|
|
painter -> setPen(Qt::red);
|
|
|
|
painter -> drawLine(0, 0, 0, 10);
|
|
|
|
painter -> drawLine(0, 10,-3, 7);
|
|
|
|
painter -> drawLine(0, 10, 3, 7);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*** Methodes privees ***/
|
|
|
|
|
|
|
|
/**
|
|
|
|
Dessine le cadre de selection de l'element de maniere systematiquement non antialiasee.
|
2009-11-22 16:12:22 +00:00
|
|
|
@param painter Le QPainter a utiliser pour dessiner les bornes.
|
2006-10-27 15:47:22 +00:00
|
|
|
@param options Les options de style a prendre en compte
|
|
|
|
*/
|
2009-11-22 16:12:22 +00:00
|
|
|
void Element::drawSelection(QPainter *painter, const QStyleOptionGraphicsItem *options) {
|
|
|
|
Q_UNUSED(options);
|
2006-10-27 15:47:22 +00:00
|
|
|
painter -> save();
|
|
|
|
// Annulation des renderhints
|
|
|
|
painter -> setRenderHint(QPainter::Antialiasing, false);
|
|
|
|
painter -> setRenderHint(QPainter::TextAntialiasing, false);
|
|
|
|
painter -> setRenderHint(QPainter::SmoothPixmapTransform, false);
|
|
|
|
// Dessin du cadre de selection en gris
|
|
|
|
QPen t;
|
|
|
|
t.setColor(Qt::gray);
|
|
|
|
t.setStyle(Qt::DashDotLine);
|
2015-03-02 20:14:56 +00:00
|
|
|
t.setCosmetic(true);
|
2006-10-27 15:47:22 +00:00
|
|
|
painter -> setPen(t);
|
|
|
|
// Le dessin se fait a partir du rectangle delimitant
|
2014-11-16 20:32:55 +00:00
|
|
|
painter -> drawRoundRect(boundingRect().adjusted(1, 1, -1, -1), 10, 10);
|
2010-04-25 12:12:59 +00:00
|
|
|
painter -> restore();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Dessine le cadre de selection de l'element de maniere systematiquement non antialiasee.
|
|
|
|
@param painter Le QPainter a utiliser pour dessiner les bornes.
|
|
|
|
@param options Les options de style a prendre en compte
|
|
|
|
*/
|
|
|
|
void Element::drawHighlight(QPainter *painter, const QStyleOptionGraphicsItem *options) {
|
|
|
|
Q_UNUSED(options);
|
|
|
|
painter -> save();
|
|
|
|
|
|
|
|
qreal gradient_radius = qMin(boundingRect().width(), boundingRect().height()) / 2.0;
|
|
|
|
QRadialGradient gradient(
|
|
|
|
boundingRect().center(),
|
|
|
|
gradient_radius,
|
|
|
|
boundingRect().center()
|
|
|
|
);
|
|
|
|
gradient.setColorAt(0.0, QColor::fromRgb(69, 137, 255, 255));
|
|
|
|
gradient.setColorAt(1.0, QColor::fromRgb(69, 137, 255, 0));
|
|
|
|
QBrush brush(gradient);
|
|
|
|
|
|
|
|
painter -> setPen(Qt::NoPen);
|
|
|
|
painter -> setBrush(brush);
|
|
|
|
// Le dessin se fait a partir du rectangle delimitant
|
2014-11-16 20:32:55 +00:00
|
|
|
painter -> drawRoundRect(boundingRect().adjusted(1, 1, -1, -1), 10, 10);
|
2006-10-27 15:47:22 +00:00
|
|
|
painter -> restore();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Fonction initialisant et dessinant la pixmap de l'element.
|
|
|
|
*/
|
|
|
|
void Element::updatePixmap() {
|
|
|
|
// Pixmap transparente faisant la taille de base de l'element
|
2009-04-03 19:30:25 +00:00
|
|
|
preview = QPixmap(dimensions);
|
|
|
|
preview.fill(QColor(255, 255, 255, 0));
|
2006-10-27 15:47:22 +00:00
|
|
|
// QPainter sur la pixmap, avec antialiasing
|
2009-04-03 19:30:25 +00:00
|
|
|
QPainter p(&preview);
|
2006-10-27 15:47:22 +00:00
|
|
|
p.setRenderHint(QPainter::Antialiasing, true);
|
|
|
|
p.setRenderHint(QPainter::SmoothPixmapTransform, true);
|
|
|
|
// Translation de l'origine du repere de la pixmap
|
|
|
|
p.translate(hotspot_coord);
|
|
|
|
// L'element se dessine sur la pixmap
|
2017-08-05 02:06:59 +00:00
|
|
|
paint(&p, nullptr);
|
2006-10-27 15:47:22 +00:00
|
|
|
}
|
|
|
|
|
2016-07-25 19:18:26 +00:00
|
|
|
/**
|
|
|
|
This class is used to retrieve label and function information from element
|
|
|
|
and add it to Diagram Context. Used to make older versions work correctly
|
|
|
|
@param Element Text item to check information
|
|
|
|
*/
|
|
|
|
void Element::etiToElementLabels(ElementTextItem *eti) {
|
|
|
|
if (eti->tagg() == "label" && eti->toPlainText()!= "_") {
|
|
|
|
DiagramContext &dc = this->rElementInformations();
|
|
|
|
dc.addValue("label", eti->toPlainText());
|
|
|
|
this->setElementInformations(dc);
|
|
|
|
this->setTaggedText("label", eti->toPlainText());
|
|
|
|
}
|
|
|
|
else if(eti->tagg() == "function" && eti->toPlainText() != "_") {
|
|
|
|
DiagramContext &dc = this->rElementInformations();
|
|
|
|
dc.addValue("function", eti->toPlainText());
|
|
|
|
this->setElementInformations(dc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-10-27 15:47:22 +00:00
|
|
|
/**
|
|
|
|
Permet de savoir si un element XML (QDomElement) represente bien un element
|
|
|
|
@param e Le QDomElement a valide
|
|
|
|
@return true si l'element XML est un Element, false sinon
|
|
|
|
*/
|
|
|
|
bool Element::valideXml(QDomElement &e) {
|
|
|
|
// verifie le nom du tag
|
|
|
|
if (e.tagName() != "element") return(false);
|
|
|
|
|
|
|
|
// verifie la presence des attributs minimaux
|
|
|
|
if (!e.hasAttribute("type")) return(false);
|
|
|
|
if (!e.hasAttribute("x")) return(false);
|
|
|
|
if (!e.hasAttribute("y")) return(false);
|
|
|
|
|
|
|
|
bool conv_ok;
|
|
|
|
// parse l'abscisse
|
|
|
|
e.attribute("x").toDouble(&conv_ok);
|
|
|
|
if (!conv_ok) return(false);
|
|
|
|
|
|
|
|
// parse l'ordonnee
|
|
|
|
e.attribute("y").toDouble(&conv_ok);
|
|
|
|
if (!conv_ok) return(false);
|
|
|
|
return(true);
|
|
|
|
}
|
2007-02-24 18:37:07 +00:00
|
|
|
|
|
|
|
/**
|
2018-01-19 12:17:20 +00:00
|
|
|
* @brief Element::fromXml
|
|
|
|
* Import the parameters of this element from a xml document.
|
|
|
|
* When call this function ensure this element is already in a scene, because
|
|
|
|
* the dynamic text item and element text item group (in the xml file) are created in this function
|
|
|
|
* and need a diagram for create their Xref, when this element is linked to another.
|
|
|
|
* If not the Xref can be not displayed, until the next call of update Xref of the group or text item.
|
|
|
|
* @param e : the dom element where the parameter is stored
|
|
|
|
* @param table_id_adr : Reference to the mapping table between IDs of the XML file
|
|
|
|
* and the addresses in memory. If the import succeeds, it must be add the right couples (id, address).
|
|
|
|
* @param handle_inputs_rotation : apply the rotation of this element to his child text
|
|
|
|
* @return
|
|
|
|
*/
|
2017-03-31 17:09:04 +00:00
|
|
|
bool Element::fromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr, bool handle_inputs_rotation)
|
|
|
|
{
|
|
|
|
QDomDocument doc = e.ownerDocument();
|
|
|
|
QDomElement root = doc.documentElement();
|
|
|
|
double saved_version = -1;
|
|
|
|
if(root.tagName() == "project")
|
|
|
|
saved_version = root.attribute("version", "-1").toDouble();
|
|
|
|
|
2007-02-24 18:37:07 +00:00
|
|
|
/*
|
2007-12-05 21:16:01 +00:00
|
|
|
les bornes vont maintenant etre recensees pour associer leurs id a leur adresse reelle
|
2007-02-24 18:37:07 +00:00
|
|
|
ce recensement servira lors de la mise en place des fils
|
|
|
|
*/
|
|
|
|
QList<QDomElement> liste_terminals;
|
2017-02-05 16:18:50 +00:00
|
|
|
foreach(QDomElement qde, QET::findInDomElement(e, "terminals", "terminal")) {
|
2007-02-24 19:56:29 +00:00
|
|
|
if (Terminal::valideXml(qde)) liste_terminals << qde;
|
2007-02-24 18:37:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QHash<int, Terminal *> priv_id_adr;
|
|
|
|
int terminals_non_trouvees = 0;
|
2017-02-05 16:18:50 +00:00
|
|
|
foreach(QGraphicsItem *qgi, childItems()) {
|
2007-02-24 18:37:07 +00:00
|
|
|
if (Terminal *p = qgraphicsitem_cast<Terminal *>(qgi)) {
|
|
|
|
bool terminal_trouvee = false;
|
2017-02-05 16:18:50 +00:00
|
|
|
foreach(QDomElement qde, liste_terminals) {
|
2007-02-24 18:37:07 +00:00
|
|
|
if (p -> fromXml(qde)) {
|
|
|
|
priv_id_adr.insert(qde.attribute("id").toInt(), p);
|
|
|
|
terminal_trouvee = true;
|
2011-12-29 17:37:24 +00:00
|
|
|
// We used to break here, because we did not expect
|
|
|
|
// several terminals to share the same position.
|
|
|
|
// Of course, it finally happened.
|
2007-02-24 18:37:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!terminal_trouvee) ++ terminals_non_trouvees;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (terminals_non_trouvees > 0) {
|
|
|
|
return(false);
|
|
|
|
} else {
|
|
|
|
// verifie que les associations id / adr n'entrent pas en conflit avec table_id_adr
|
2017-02-05 16:18:50 +00:00
|
|
|
foreach(int id_trouve, priv_id_adr.keys()) {
|
2007-02-24 18:37:07 +00:00
|
|
|
if (table_id_adr.contains(id_trouve)) {
|
|
|
|
// cet element possede un id qui est deja reference (= conflit)
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// copie des associations id / adr
|
2017-02-05 16:18:50 +00:00
|
|
|
foreach(int id_trouve, priv_id_adr.keys()) {
|
2007-02-24 18:37:07 +00:00
|
|
|
table_id_adr.insert(id_trouve, priv_id_adr.value(id_trouve));
|
|
|
|
}
|
|
|
|
}
|
2016-12-08 16:54:41 +00:00
|
|
|
|
2013-12-31 14:39:34 +00:00
|
|
|
//load uuid of connected elements
|
|
|
|
QList <QDomElement> uuid_list = QET::findInDomElement(e, "links_uuids", "link_uuid");
|
2017-02-05 16:18:50 +00:00
|
|
|
foreach (QDomElement qdo, uuid_list) tmp_uuids_link << qdo.attribute("uuid");
|
2007-02-24 19:56:29 +00:00
|
|
|
|
2013-12-31 14:39:34 +00:00
|
|
|
//uuid of this element
|
|
|
|
uuid_= QUuid(e.attribute("uuid", QUuid::createUuid().toString()));
|
|
|
|
|
2016-12-08 15:06:46 +00:00
|
|
|
//load prefix
|
2016-07-13 23:28:00 +00:00
|
|
|
m_prefix = e.attribute("prefix");
|
|
|
|
|
2016-12-10 12:00:52 +00:00
|
|
|
QString fl = e.attribute("freezeLabel", "false");
|
|
|
|
m_freeze_label = fl == "false"? false : true;
|
|
|
|
|
2016-12-08 15:06:46 +00:00
|
|
|
//Load Sequential Values
|
|
|
|
if (e.hasAttribute("sequ_1") || e.hasAttribute("sequf_1") || e.hasAttribute("seqt_1") || e.hasAttribute("seqtf_1") || e.hasAttribute("seqh_1") || e.hasAttribute("sequf_1"))
|
|
|
|
ElementXmlRetroCompatibility::loadSequential(e, this);
|
|
|
|
else
|
|
|
|
m_autoNum_seq.fromXml(e.firstChildElement("sequentialNumbers"));
|
2016-07-14 17:16:14 +00:00
|
|
|
|
2017-10-19 09:10:23 +00:00
|
|
|
//Position and selection.
|
|
|
|
//We directly call setPos from QGraphicsObject, because QetGraphicsItem will snap to grid
|
|
|
|
QGraphicsObject::setPos(e.attribute("x").toDouble(), e.attribute("y").toDouble());
|
|
|
|
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
|
|
|
|
|
|
|
|
// orientation
|
|
|
|
bool conv_ok;
|
|
|
|
int read_ori = e.attribute("orientation").toInt(&conv_ok);
|
|
|
|
if (!conv_ok || read_ori < 0 || read_ori > 3) read_ori = 0;
|
|
|
|
if (handle_inputs_rotation) {
|
|
|
|
rotateBy(90*read_ori);
|
|
|
|
} 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();
|
2017-12-30 14:41:25 +00:00
|
|
|
|
2017-10-19 09:10:23 +00:00
|
|
|
//************************//
|
|
|
|
//***Dynamic texts item***//
|
|
|
|
//************************//
|
2017-12-30 14:41:25 +00:00
|
|
|
for (QDomElement qde : QET::findInDomElement(e, "dynamic_texts", DynamicElementTextItem::xmlTaggName()))
|
|
|
|
{
|
|
|
|
DynamicElementTextItem *deti = new DynamicElementTextItem(this);
|
|
|
|
addDynamicTextItem(deti);
|
|
|
|
deti->fromXml(qde);
|
|
|
|
}
|
2017-10-19 09:10:23 +00:00
|
|
|
|
|
|
|
|
|
|
|
//************************//
|
|
|
|
//***Element texts item***//
|
|
|
|
//************************//
|
|
|
|
QList<QDomElement> inputs = QET::findInDomElement(e, "inputs", "input");
|
|
|
|
|
|
|
|
//First case, we check for the text item converted to dynamic text item
|
|
|
|
const QList <DynamicElementTextItem *> conv_deti_list = m_converted_text_from_xml_description.keys();
|
2018-01-19 12:17:20 +00:00
|
|
|
QList <DynamicElementTextItem *> successfully_converted;
|
2017-10-19 09:10:23 +00:00
|
|
|
const QList <QDomElement> dom_inputs = inputs;
|
|
|
|
|
|
|
|
for (DynamicElementTextItem *deti : conv_deti_list)
|
|
|
|
{
|
|
|
|
for(QDomElement dom_input : dom_inputs)
|
|
|
|
{
|
|
|
|
//we use the same method used in ElementTextItem::fromXml to compar and know if the input dom element is for one of the text stored.
|
|
|
|
//The comparaison is made from the text position : if the position of the text is the same as the position stored in 'input' dom element
|
|
|
|
//that mean this is the good text
|
|
|
|
if (qFuzzyCompare(qreal(dom_input.attribute("x").toDouble()), m_converted_text_from_xml_description.value(deti).x()) &&
|
|
|
|
qFuzzyCompare(qreal(dom_input.attribute("y").toDouble()), m_converted_text_from_xml_description.value(deti).y()))
|
2018-02-01 18:40:12 +00:00
|
|
|
{
|
|
|
|
//Once again this 'if', is only for retrocompatibility with old old old project
|
|
|
|
//when element text with tagg "label" is not null, but the element information "label" is.
|
|
|
|
if((deti->textFrom() == DynamicElementTextItem::ElementInfo) && (deti->infoName() == "label"))
|
|
|
|
m_element_informations.addValue("label", dom_input.attribute("text"));
|
|
|
|
|
2017-10-19 09:10:23 +00:00
|
|
|
deti->setText(dom_input.attribute("text"));
|
|
|
|
|
|
|
|
qreal rotation = deti->rotation();
|
|
|
|
QPointF xml_pos = m_converted_text_from_xml_description.value(deti);
|
|
|
|
|
|
|
|
if (dom_input.attribute("userrotation").toDouble())
|
|
|
|
rotation = dom_input.attribute("userrotation").toDouble();
|
|
|
|
|
|
|
|
if (dom_input.hasAttribute("userx"))
|
|
|
|
xml_pos.setX(dom_input.attribute("userx").toDouble());
|
|
|
|
if(dom_input.hasAttribute("usery"))
|
|
|
|
xml_pos.setY(dom_input.attribute("usery", "0").toDouble());
|
|
|
|
|
|
|
|
//the origin transformation point of PartDynamicTextField is the top left corner, no matter the font size
|
|
|
|
//The origin transformation point of PartTextField is the middle of left edge, and so by definition, change with the size of the font
|
|
|
|
//We need to use a QMatrix to find the pos of this text from the saved pos of text item
|
|
|
|
|
|
|
|
deti->setPos(xml_pos);
|
|
|
|
deti->setRotation(rotation);
|
|
|
|
|
|
|
|
QMatrix matrix;
|
|
|
|
//First make the rotation
|
|
|
|
matrix.rotate(rotation);
|
|
|
|
QPointF pos = matrix.map(QPointF(0, -deti->boundingRect().height()/2));
|
|
|
|
matrix.reset();
|
|
|
|
//Second translate to the pos
|
|
|
|
matrix.translate(xml_pos.x(), xml_pos.y());
|
|
|
|
deti->setPos(matrix.map(pos));
|
|
|
|
|
|
|
|
//dom_input and deti matched we remove the dom_input from @inputs list,
|
|
|
|
//to avoid unnecessary checking made below
|
|
|
|
//we also move deti from the m_converted_text_from_xml_description to m_dynamic_text_list
|
|
|
|
inputs.removeAll(dom_input);
|
|
|
|
m_dynamic_text_list.append(deti);
|
|
|
|
m_converted_text_from_xml_description.remove(deti);
|
2018-01-19 12:17:20 +00:00
|
|
|
successfully_converted << deti;
|
2017-10-19 09:10:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//###Firts case : if this is the first time the user open the project since text item are converted to dynamic text,
|
|
|
|
//in the previous opening of the project, every texts field present in the element description was created.
|
|
|
|
//At save time, the values of each of them was save in the 'input' dom element.
|
|
|
|
//The loop upper is made for the first case, to import the values in 'input' to the new converted dynamic texts field.
|
|
|
|
//###Second case : this is not the first time the user open the project since text item are converted to dynamic text.
|
|
|
|
//That mean, in a previous opening of the project, the text item was already converted and save as a dynamic text field.
|
|
|
|
//So there isn't 'input' dom element in the project, and every dynamic text item present in m_converted_text_from_xml_description
|
|
|
|
//need to be deleted (because already exist in m_dynamic_text_list, from a previous save)
|
|
|
|
for (DynamicElementTextItem *deti : m_converted_text_from_xml_description.keys())
|
|
|
|
delete deti;
|
|
|
|
m_converted_text_from_xml_description.clear();
|
|
|
|
|
|
|
|
//For the moment the text item with a tagg are not converted to dynamic text item
|
|
|
|
//so we must to check it
|
|
|
|
foreach(QGraphicsItem *qgi, childItems())
|
|
|
|
{
|
|
|
|
if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(qgi))
|
|
|
|
{
|
|
|
|
foreach(QDomElement input, inputs)
|
|
|
|
{
|
|
|
|
eti -> fromXml(input);
|
|
|
|
etiToElementLabels(eti);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-30 14:41:25 +00:00
|
|
|
for (QDomElement qde : QET::findInDomElement(e, "texts_groups", ElementTextItemGroup::xmlTaggName()))
|
2017-11-27 19:37:39 +00:00
|
|
|
{
|
|
|
|
ElementTextItemGroup *group = addTextGroup("loaded_from_xml_group");
|
|
|
|
group->fromXml(qde);
|
|
|
|
}
|
|
|
|
|
2016-11-24 16:45:55 +00:00
|
|
|
//load informations
|
2018-01-19 12:17:20 +00:00
|
|
|
DiagramContext dc;
|
|
|
|
dc.fromXml(e.firstChildElement("elementInformations"), "elementInformation");
|
2016-11-24 16:45:55 +00:00
|
|
|
/**
|
|
|
|
* Since the commit 4791, the value used as "label" and "formula" is stored in differents keys (instead of the same key, "label" in previous version),
|
|
|
|
* so, if "label" contain "%" (Use variable value), and "formula" does not exist,
|
|
|
|
* this mean the label was made before commit 4791 (0.51 dev). So we swap the value stored in "label" to "formula" as expected.
|
|
|
|
* @TODO remove this code at version 0.7 or more (probably useless).
|
|
|
|
*/
|
2018-01-19 12:17:20 +00:00
|
|
|
if (dc["label"].toString().contains("%") && dc["formula"].toString().isNull())
|
2016-11-24 16:45:55 +00:00
|
|
|
{
|
2018-01-19 12:17:20 +00:00
|
|
|
dc.addValue("formula", dc["label"]);
|
2016-11-24 16:45:55 +00:00
|
|
|
}
|
2018-02-01 18:40:12 +00:00
|
|
|
//retrocompatibility with older version
|
|
|
|
if(dc.value("label").toString().isEmpty() &&
|
|
|
|
!m_element_informations.value("label").toString().isEmpty())
|
|
|
|
dc.addValue("label", m_element_informations.value("label"));
|
|
|
|
|
2018-01-19 12:17:20 +00:00
|
|
|
setElementInformations(dc);
|
2017-03-31 17:09:04 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* At the start of the 0.51 devel, if the text item with tagg "label" was edited directly in the diagram,
|
|
|
|
* the text was not write to the element information value "formula".
|
|
|
|
* During the devel, this behavior change, when user edit the text item direclty in the diagram,
|
|
|
|
* the text was also write in the element information.
|
|
|
|
* Then when open a .qet file, the text item with tagg "label", is write with the value stored in the element information.
|
|
|
|
* The mistake is :
|
|
|
|
* if user write directly in the diagram with a version befor the change (so the text is not in the element information),
|
|
|
|
* and open the project with a version after the change, then the text item with tagg "label" is empty.
|
|
|
|
* The code below fix this.
|
|
|
|
*/
|
|
|
|
if (saved_version > -1 && saved_version <= 0.51)
|
|
|
|
{
|
|
|
|
if (ElementTextItem *eti = taggedText("label"))
|
|
|
|
{
|
|
|
|
if (m_element_informations["label"].toString().isEmpty() &&
|
|
|
|
m_element_informations["formula"].toString().isEmpty() &&
|
|
|
|
!eti->toPlainText().isEmpty())
|
|
|
|
{
|
|
|
|
m_element_informations.addValue("formula", eti->toPlainText());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-01-19 12:17:20 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
During the devel of the version 0.7, the "old text" was replaced by the dynamic element text item.
|
|
|
|
When open a project made befor the 0.7, we must to reproduce the same visual when the label are not empty and visible,
|
|
|
|
and comment are not empty and visible and/or location are not empty and visible.
|
|
|
|
we create a text group with inside the needed texts, label and comment and/or location.
|
|
|
|
*/
|
|
|
|
//#1 There must be old text converted to dynamic text
|
|
|
|
if(!successfully_converted.isEmpty())
|
|
|
|
{
|
|
|
|
//#2 the element information must have label not empty and visible
|
|
|
|
//and a least comment or location not empty and visible
|
|
|
|
QString label = m_element_informations.value("label").toString();
|
|
|
|
QString comment = m_element_informations.value("comment").toString();
|
|
|
|
QString location = m_element_informations.value("location").toString();
|
|
|
|
bool la = m_element_informations.keyMustShow("label");
|
|
|
|
bool c = m_element_informations.keyMustShow("comment");
|
|
|
|
bool lo = m_element_informations.keyMustShow("location");
|
2018-02-01 18:40:12 +00:00
|
|
|
|
|
|
|
if((m_link_type != Master) ||
|
|
|
|
((m_link_type == Master) &&
|
|
|
|
(diagram()->project()->defaultXRefProperties(m_kind_informations["type"].toString()).snapTo() == XRefProperties::Label))
|
|
|
|
)
|
2018-01-19 12:17:20 +00:00
|
|
|
{
|
2018-02-01 18:40:12 +00:00
|
|
|
if(!label.isEmpty() && la &&
|
|
|
|
((!comment.isEmpty() && c) || (!location.isEmpty() && lo)))
|
2018-01-19 12:17:20 +00:00
|
|
|
{
|
2018-02-01 18:40:12 +00:00
|
|
|
//#2 in the converted list one text must have text from = element info and info name = label
|
|
|
|
for(DynamicElementTextItem *deti : successfully_converted)
|
2018-01-19 12:17:20 +00:00
|
|
|
{
|
2018-02-01 18:40:12 +00:00
|
|
|
if(deti->textFrom() == DynamicElementTextItem::ElementInfo && deti->infoName() == "label")
|
2018-01-19 12:17:20 +00:00
|
|
|
{
|
2018-02-01 18:40:12 +00:00
|
|
|
qreal rotation = deti->rotation();
|
|
|
|
|
|
|
|
//Create the comment item
|
|
|
|
DynamicElementTextItem *comment_text = nullptr;
|
|
|
|
if(!comment.isEmpty() && c)
|
|
|
|
{
|
|
|
|
comment_text = new DynamicElementTextItem(this);
|
|
|
|
comment_text->setTextFrom(DynamicElementTextItem::ElementInfo);
|
|
|
|
comment_text->setInfoName("comment");
|
|
|
|
comment_text->setFontSize(6);
|
|
|
|
comment_text->setFrame(true);
|
|
|
|
if(comment_text->toPlainText().count() > 17)
|
|
|
|
comment_text->setTextWidth(80);
|
|
|
|
comment_text->setPos(deti->x(), deti->y()+10); //+10 is arbitrary, comment_text must be below deti
|
|
|
|
addDynamicTextItem(comment_text);
|
|
|
|
}
|
|
|
|
//create the location item
|
|
|
|
DynamicElementTextItem *location_text = nullptr;
|
|
|
|
if(!location.isEmpty() && lo)
|
|
|
|
{
|
|
|
|
location_text = new DynamicElementTextItem(this);
|
|
|
|
location_text->setTextFrom(DynamicElementTextItem::ElementInfo);
|
|
|
|
location_text->setInfoName("location");
|
|
|
|
location_text->setFontSize(6);
|
|
|
|
if(comment_text->toPlainText().count() > 17)
|
|
|
|
location_text->setTextWidth(80);
|
|
|
|
location_text->setPos(deti->x(), deti->y()+20); //+20 is arbitrary, location_text must be below deti and comment
|
|
|
|
addDynamicTextItem(location_text);
|
|
|
|
}
|
|
|
|
|
|
|
|
QPointF pos = deti->pos();
|
|
|
|
//Create the group
|
|
|
|
ElementTextItemGroup *group = addTextGroup(tr("Label + commentaire"));
|
|
|
|
addTextToGroup(deti, group);
|
|
|
|
if(comment_text)
|
|
|
|
addTextToGroup(comment_text, group);
|
|
|
|
if(location_text)
|
|
|
|
addTextToGroup(location_text, group);
|
|
|
|
group->setAlignment(Qt::AlignVCenter);
|
|
|
|
group->setVerticalAdjustment(-4);
|
|
|
|
group->setRotation(rotation);
|
|
|
|
//Change the position of the group, so that the text "label" stay in the same
|
|
|
|
//position in scene coordinate
|
|
|
|
group->setPos(pos - deti->pos());
|
|
|
|
|
|
|
|
break;
|
2018-01-19 12:17:20 +00:00
|
|
|
}
|
2018-02-01 18:40:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//This element is supposed to be a master and Xref property snap to bottom
|
|
|
|
if((!comment.isEmpty() && c) || (!location.isEmpty() && lo))
|
|
|
|
{
|
|
|
|
//Create the comment item
|
|
|
|
DynamicElementTextItem *comment_text = nullptr;
|
|
|
|
if(!comment.isEmpty() && c)
|
|
|
|
{
|
|
|
|
comment_text = new DynamicElementTextItem(this);
|
|
|
|
comment_text->setTextFrom(DynamicElementTextItem::ElementInfo);
|
|
|
|
comment_text->setInfoName("comment");
|
|
|
|
comment_text->setFontSize(6);
|
|
|
|
comment_text->setFrame(true);
|
|
|
|
comment_text->setTextWidth(80);
|
|
|
|
addDynamicTextItem(comment_text);
|
|
|
|
}
|
|
|
|
//create the location item
|
|
|
|
DynamicElementTextItem *location_text = nullptr;
|
|
|
|
if(!location.isEmpty() && lo)
|
|
|
|
{
|
|
|
|
location_text = new DynamicElementTextItem(this);
|
|
|
|
location_text->setTextFrom(DynamicElementTextItem::ElementInfo);
|
|
|
|
location_text->setInfoName("location");
|
|
|
|
location_text->setFontSize(6);
|
|
|
|
location_text->setTextWidth(80);
|
2018-01-19 12:17:20 +00:00
|
|
|
if(comment_text)
|
2018-02-01 18:40:12 +00:00
|
|
|
location_text->setPos(comment_text->x(), comment_text->y()+10); //+10 is arbitrary, location_text must be below the comment
|
|
|
|
addDynamicTextItem(location_text);
|
2018-01-19 12:17:20 +00:00
|
|
|
}
|
2018-02-01 18:40:12 +00:00
|
|
|
|
|
|
|
//Create the group
|
|
|
|
ElementTextItemGroup *group = addTextGroup(tr("Label + commentaire"));
|
|
|
|
if(comment_text)
|
|
|
|
addTextToGroup(comment_text, group);
|
|
|
|
if(location_text)
|
|
|
|
addTextToGroup(location_text, group);
|
|
|
|
group->setAlignment(Qt::AlignVCenter);
|
|
|
|
group->setVerticalAdjustment(-4);
|
|
|
|
group->setHoldToBottomPage(true);
|
2018-01-19 12:17:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-12-30 14:41:25 +00:00
|
|
|
|
2007-02-24 18:37:07 +00:00
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Permet d'exporter l'element en XML
|
|
|
|
@param document Document XML a utiliser
|
|
|
|
@param table_adr_id Table de correspondance entre les adresses des bornes
|
|
|
|
et leur id dans la representation XML ; cette table completee par cette
|
|
|
|
methode
|
|
|
|
@return L'element XML representant cet element electrique
|
|
|
|
*/
|
2016-12-08 15:06:46 +00:00
|
|
|
QDomElement Element::toXml(QDomDocument &document, QHash<Terminal *, int> &table_adr_id) const
|
|
|
|
{
|
2007-02-24 18:37:07 +00:00
|
|
|
QDomElement element = document.createElement("element");
|
|
|
|
|
2016-12-08 15:06:46 +00:00
|
|
|
// type
|
2009-04-03 19:30:25 +00:00
|
|
|
element.setAttribute("type", typeId());
|
2016-07-26 18:52:49 +00:00
|
|
|
|
2016-12-08 15:06:46 +00:00
|
|
|
// uuid
|
|
|
|
element.setAttribute("uuid", uuid().toString());
|
2016-07-26 18:52:49 +00:00
|
|
|
|
2016-12-08 15:06:46 +00:00
|
|
|
// prefix
|
|
|
|
element.setAttribute("prefix", m_prefix);
|
2016-07-26 18:52:49 +00:00
|
|
|
|
2016-12-10 12:00:52 +00:00
|
|
|
//frozen label
|
|
|
|
element.setAttribute("freezeLabel", m_freeze_label? "true" : "false");
|
|
|
|
|
2016-12-08 15:06:46 +00:00
|
|
|
// sequential num
|
|
|
|
QDomElement seq = m_autoNum_seq.toXml(document);
|
|
|
|
if (seq.hasChildNodes())
|
|
|
|
element.appendChild(seq);
|
2017-12-30 14:41:25 +00:00
|
|
|
|
2007-02-24 18:37:07 +00:00
|
|
|
// position, selection et orientation
|
2008-08-23 19:27:14 +00:00
|
|
|
element.setAttribute("x", QString("%1").arg(pos().x()));
|
|
|
|
element.setAttribute("y", QString("%1").arg(pos().y()));
|
2013-11-14 10:11:22 +00:00
|
|
|
element.setAttribute("orientation", QString("%1").arg(orientation()));
|
2007-02-24 18:37:07 +00:00
|
|
|
|
|
|
|
/* recupere le premier id a utiliser pour les bornes de cet element */
|
|
|
|
int id_terminal = 0;
|
|
|
|
if (!table_adr_id.isEmpty()) {
|
|
|
|
// trouve le plus grand id
|
|
|
|
int max_id_t = -1;
|
2017-02-05 16:18:50 +00:00
|
|
|
foreach (int id_t, table_adr_id.values()) {
|
2007-02-24 18:37:07 +00:00
|
|
|
if (id_t > max_id_t) max_id_t = id_t;
|
|
|
|
}
|
|
|
|
id_terminal = max_id_t + 1;
|
|
|
|
}
|
2017-12-30 14:41:25 +00:00
|
|
|
|
2007-02-24 18:37:07 +00:00
|
|
|
// enregistrement des bornes de l'appareil
|
2009-04-04 21:47:07 +00:00
|
|
|
QDomElement xml_terminals = document.createElement("terminals");
|
2007-02-24 18:37:07 +00:00
|
|
|
// pour chaque enfant de l'element
|
2017-02-05 16:18:50 +00:00
|
|
|
foreach(Terminal *t, terminals()) {
|
2009-04-04 21:47:07 +00:00
|
|
|
// alors on enregistre la borne
|
|
|
|
QDomElement terminal = t -> toXml(document);
|
|
|
|
terminal.setAttribute("id", id_terminal);
|
|
|
|
table_adr_id.insert(t, id_terminal ++);
|
|
|
|
xml_terminals.appendChild(terminal);
|
2007-02-24 18:37:07 +00:00
|
|
|
}
|
2009-04-04 21:47:07 +00:00
|
|
|
element.appendChild(xml_terminals);
|
2017-12-30 14:41:25 +00:00
|
|
|
|
2007-02-24 19:56:29 +00:00
|
|
|
// enregistrement des champ de texte de l'appareil
|
|
|
|
QDomElement inputs = document.createElement("inputs");
|
2017-02-05 16:18:50 +00:00
|
|
|
foreach(ElementTextItem *eti, texts()) {
|
2009-04-04 21:47:07 +00:00
|
|
|
inputs.appendChild(eti -> toXml(document));
|
2007-02-24 19:56:29 +00:00
|
|
|
}
|
|
|
|
element.appendChild(inputs);
|
2013-12-31 14:39:34 +00:00
|
|
|
|
|
|
|
//if this element is linked to other elements,
|
|
|
|
//save the uuid of each other elements
|
|
|
|
if (! isFree()) {
|
|
|
|
QDomElement links_uuids = document.createElement("links_uuids");
|
2017-02-05 16:18:50 +00:00
|
|
|
foreach (Element *elmt, connected_elements) {
|
2013-12-31 14:39:34 +00:00
|
|
|
QDomElement link_uuid = document.createElement("link_uuid");
|
|
|
|
link_uuid.setAttribute("uuid", elmt->uuid().toString());
|
|
|
|
links_uuids.appendChild(link_uuid);
|
|
|
|
}
|
|
|
|
element.appendChild(links_uuids);
|
|
|
|
}
|
2014-02-12 17:36:35 +00:00
|
|
|
|
2017-12-30 14:41:25 +00:00
|
|
|
//save information of this element
|
2015-05-31 15:02:41 +00:00
|
|
|
if (! m_element_informations.keys().isEmpty()) {
|
2014-02-22 17:24:20 +00:00
|
|
|
QDomElement infos = document.createElement("elementInformations");
|
2015-05-31 15:02:41 +00:00
|
|
|
m_element_informations.toXml(infos, "elementInformation");
|
2014-02-22 17:24:20 +00:00
|
|
|
element.appendChild(infos);
|
|
|
|
}
|
2017-12-30 14:41:25 +00:00
|
|
|
|
|
|
|
//Dynamic texts
|
|
|
|
QDomElement dyn_text = document.createElement("dynamic_texts");
|
|
|
|
for (DynamicElementTextItem *deti : m_dynamic_text_list)
|
|
|
|
dyn_text.appendChild(deti->toXml(document));
|
2017-11-27 19:37:39 +00:00
|
|
|
|
2017-12-30 14:41:25 +00:00
|
|
|
QDomElement texts_group = document.createElement("texts_groups");
|
2017-11-27 19:37:39 +00:00
|
|
|
|
2017-12-30 14:41:25 +00:00
|
|
|
//Dynamic texts owned by groups
|
2017-11-27 19:37:39 +00:00
|
|
|
for(ElementTextItemGroup *group : m_texts_group)
|
|
|
|
{
|
2018-02-01 18:40:12 +00:00
|
|
|
group->blockAlignmentUpdate(true);
|
2017-11-27 19:37:39 +00:00
|
|
|
//temporarily remove the texts from group to get the pos relative to element and not group.
|
|
|
|
//Set the alignment to top, because top is not used by groupand so,
|
|
|
|
//each time a text is removed from the group, the alignement is not updated
|
|
|
|
Qt::Alignment al = group->alignment();
|
2017-11-29 14:49:12 +00:00
|
|
|
group->setAlignment(Qt::AlignTop);
|
2017-11-27 19:37:39 +00:00
|
|
|
|
|
|
|
//Remove the texts from group
|
|
|
|
QList<DynamicElementTextItem *> deti_list = group->texts();
|
|
|
|
for(DynamicElementTextItem *deti : deti_list)
|
|
|
|
group->removeFromGroup(deti);
|
|
|
|
|
|
|
|
//Save the texts to xml
|
2017-12-30 14:41:25 +00:00
|
|
|
for (DynamicElementTextItem *deti : deti_list)
|
2017-11-27 19:37:39 +00:00
|
|
|
dyn_text.appendChild(deti->toXml(document));
|
|
|
|
|
|
|
|
//Re add texts to group
|
|
|
|
for(DynamicElementTextItem *deti : deti_list)
|
|
|
|
group->addToGroup(deti);
|
|
|
|
|
|
|
|
//Restor the alignement
|
2017-11-29 14:49:12 +00:00
|
|
|
group->setAlignment(al);
|
2017-11-27 19:37:39 +00:00
|
|
|
|
|
|
|
//Save the group to xml
|
|
|
|
texts_group.appendChild(group->toXml(document));
|
2018-02-01 18:40:12 +00:00
|
|
|
group->blockAlignmentUpdate(false);
|
2017-11-27 19:37:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//Append the dynamic texts to element
|
|
|
|
element.appendChild(dyn_text);
|
|
|
|
//Append the texts group to element
|
|
|
|
element.appendChild(texts_group);
|
2017-08-03 17:36:08 +00:00
|
|
|
|
2017-12-30 14:41:25 +00:00
|
|
|
return(element);
|
2017-08-03 17:36:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Element::addDynamiqueTextItem
|
2017-11-29 14:49:12 +00:00
|
|
|
* Add @deti as a dynamic text item of this element, @deti is reparented to this
|
2017-08-03 17:36:08 +00:00
|
|
|
* If @deti is null, a new DynamicElementTextItem is created and added to this element.
|
|
|
|
* @param deti
|
|
|
|
*/
|
|
|
|
void Element::addDynamicTextItem(DynamicElementTextItem *deti)
|
|
|
|
{
|
2017-12-30 14:41:25 +00:00
|
|
|
if (deti && !m_dynamic_text_list.contains(deti))
|
2017-08-03 17:36:08 +00:00
|
|
|
{
|
2017-12-30 14:41:25 +00:00
|
|
|
m_dynamic_text_list.append(deti);
|
2017-11-29 14:49:12 +00:00
|
|
|
deti->setParentItem(this);
|
2017-11-27 19:37:39 +00:00
|
|
|
emit textAdded(deti);
|
2017-08-03 17:36:08 +00:00
|
|
|
}
|
2017-12-30 14:41:25 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
DynamicElementTextItem *text = new DynamicElementTextItem(this);
|
|
|
|
m_dynamic_text_list.append(text);
|
2017-11-27 19:37:39 +00:00
|
|
|
emit textAdded(text);
|
2017-12-30 14:41:25 +00:00
|
|
|
}
|
2017-08-03 17:36:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Element::removeDynamicTextItem
|
2017-11-29 14:49:12 +00:00
|
|
|
* Remove @deti, no matter if is a child of this element or a child of a group of this element.
|
|
|
|
* Set he parent item of @deti to 0, @deti is not deleted.
|
2017-08-03 17:36:08 +00:00
|
|
|
* @param deti
|
|
|
|
*/
|
|
|
|
void Element::removeDynamicTextItem(DynamicElementTextItem *deti)
|
|
|
|
{
|
2017-12-30 14:41:25 +00:00
|
|
|
if (m_dynamic_text_list.contains(deti))
|
2017-11-27 19:37:39 +00:00
|
|
|
{
|
2017-12-30 14:41:25 +00:00
|
|
|
m_dynamic_text_list.removeOne(deti);
|
2017-11-29 14:49:12 +00:00
|
|
|
deti->setParentItem(nullptr);
|
2017-11-27 19:37:39 +00:00
|
|
|
emit textRemoved(deti);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(ElementTextItemGroup *group : m_texts_group)
|
|
|
|
{
|
|
|
|
if(group->texts().contains(deti))
|
|
|
|
{
|
|
|
|
removeTextFromGroup(deti, group);
|
|
|
|
m_dynamic_text_list.removeOne(deti);
|
2017-11-29 14:49:12 +00:00
|
|
|
deti->setParentItem(nullptr);
|
2017-11-27 19:37:39 +00:00
|
|
|
emit textRemoved(deti);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2017-08-03 17:36:08 +00:00
|
|
|
}
|
2014-02-22 17:24:20 +00:00
|
|
|
|
2017-08-03 17:36:08 +00:00
|
|
|
/**
|
|
|
|
* @brief Element::dynamicTextItems
|
|
|
|
* @return all dynamic text items of this element
|
|
|
|
*/
|
|
|
|
QList<DynamicElementTextItem *> Element::dynamicTextItems() const {
|
2017-11-27 19:37:39 +00:00
|
|
|
return m_dynamic_text_list;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Element::addTextGroup
|
|
|
|
* Create and add an element text item group to this element.
|
|
|
|
* If this element already have a group with the same name,
|
|
|
|
* then @name will renamed to name1 or name2 etc....
|
|
|
|
* @param name : the name of the group
|
|
|
|
* @return the created group.
|
|
|
|
*/
|
|
|
|
ElementTextItemGroup *Element::addTextGroup(const QString &name)
|
|
|
|
{
|
|
|
|
if(m_texts_group.isEmpty())
|
|
|
|
{
|
|
|
|
ElementTextItemGroup *group = new ElementTextItemGroup(name, this);
|
|
|
|
m_texts_group << group;
|
|
|
|
emit textsGroupAdded(group);
|
|
|
|
return group;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Set a new name if name already exist
|
|
|
|
QString rename = name;
|
|
|
|
int i=1;
|
|
|
|
while (textGroup(rename))
|
|
|
|
{
|
|
|
|
rename = name+QString::number(i);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Create the group
|
|
|
|
ElementTextItemGroup *group = new ElementTextItemGroup(rename, this);
|
|
|
|
m_texts_group << group;
|
|
|
|
emit textsGroupAdded(group);
|
|
|
|
return group;
|
|
|
|
}
|
|
|
|
|
2017-11-29 14:49:12 +00:00
|
|
|
/**
|
|
|
|
* @brief Element::addTextGroup
|
|
|
|
* @param group add group @group to the group of this element.
|
|
|
|
* the group must not be owned by an element.
|
|
|
|
*/
|
|
|
|
void Element::addTextGroup(ElementTextItemGroup *group)
|
|
|
|
{
|
|
|
|
if(group->parentElement())
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_texts_group << group;
|
|
|
|
group->setParentItem(this);
|
|
|
|
emit textsGroupAdded(group);
|
|
|
|
}
|
|
|
|
|
2017-11-27 19:37:39 +00:00
|
|
|
/**
|
|
|
|
* @brief Element::removeTextGroup
|
2017-11-29 14:49:12 +00:00
|
|
|
* Remove the text group @group from this element, and set the parent of group to 0.
|
|
|
|
* group is not deleted.
|
|
|
|
* All texts owned by the group will be reparented to this element
|
2017-11-27 19:37:39 +00:00
|
|
|
* @param name
|
|
|
|
*/
|
|
|
|
void Element::removeTextGroup(ElementTextItemGroup *group)
|
|
|
|
{
|
|
|
|
if(!m_texts_group.contains(group))
|
|
|
|
return;
|
|
|
|
|
|
|
|
const QList <QGraphicsItem *> items_list = group->childItems();
|
|
|
|
|
|
|
|
for(QGraphicsItem *qgi : items_list)
|
|
|
|
{
|
|
|
|
if(qgi->type() == DynamicElementTextItem::Type)
|
|
|
|
{
|
|
|
|
DynamicElementTextItem *deti = static_cast<DynamicElementTextItem *>(qgi);
|
|
|
|
removeTextFromGroup(deti, group);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-29 14:49:12 +00:00
|
|
|
|
2017-11-27 19:37:39 +00:00
|
|
|
emit textsGroupAboutToBeRemoved(group);
|
2017-11-29 14:49:12 +00:00
|
|
|
m_texts_group.removeOne(group);
|
|
|
|
group->setParentItem(nullptr);
|
2017-11-27 19:37:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Element::textGroup
|
|
|
|
* @param name
|
|
|
|
* @return the text group named @name or nullptr if this element
|
|
|
|
* haven't got a group with this name
|
|
|
|
*/
|
|
|
|
ElementTextItemGroup *Element::textGroup(const QString &name) const
|
|
|
|
{
|
|
|
|
for (ElementTextItemGroup *group : m_texts_group)
|
|
|
|
if(group->name() == name)
|
|
|
|
return group;
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Element::textGroups
|
|
|
|
* @return All texts groups of this element
|
|
|
|
*/
|
|
|
|
QList<ElementTextItemGroup *> Element::textGroups() const
|
|
|
|
{
|
|
|
|
return m_texts_group;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Element::addTextToGroup
|
|
|
|
* Add the text @text to the group @group;
|
|
|
|
* If @group isn't owned by this element return false.
|
|
|
|
* The text must be a text of this element.
|
|
|
|
* @return : true if the text was succesfully added to the group.
|
|
|
|
*/
|
|
|
|
bool Element::addTextToGroup(DynamicElementTextItem *text, ElementTextItemGroup *group)
|
|
|
|
{
|
|
|
|
if(!m_dynamic_text_list.contains(text))
|
|
|
|
return false;
|
|
|
|
if(!m_texts_group.contains(group))
|
|
|
|
return false;
|
2017-11-29 14:49:12 +00:00
|
|
|
|
|
|
|
m_dynamic_text_list.removeOne(text);
|
|
|
|
emit textRemoved(text);
|
2017-11-27 19:37:39 +00:00
|
|
|
|
|
|
|
group->addToGroup(text);
|
|
|
|
emit textAddedToGroup(text, group);
|
2017-11-29 14:49:12 +00:00
|
|
|
|
2017-11-27 19:37:39 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Element::removeTextFromGroup
|
|
|
|
* Remove the text @text from the group @group, en reparent @text to this element
|
|
|
|
* @return true if text was succesfully removed
|
|
|
|
*/
|
|
|
|
bool Element::removeTextFromGroup(DynamicElementTextItem *text, ElementTextItemGroup *group)
|
|
|
|
{
|
|
|
|
if(!m_texts_group.contains(group))
|
|
|
|
return false;
|
|
|
|
|
2017-11-29 14:49:12 +00:00
|
|
|
if(group->texts().contains(text))
|
2017-11-27 19:37:39 +00:00
|
|
|
{
|
|
|
|
group->removeFromGroup(text);
|
|
|
|
emit textRemovedFromGroup(text, group);
|
|
|
|
addDynamicTextItem(text);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
2007-02-24 18:37:07 +00:00
|
|
|
}
|
2013-12-31 14:39:34 +00:00
|
|
|
|
2015-01-09 17:18:16 +00:00
|
|
|
/**
|
|
|
|
* @brief Element::AlignedFreeTerminals
|
|
|
|
* @return a list of terminal (owned by this element) aligned to other terminal (from other element)
|
|
|
|
* The first Terminal of QPair is a Terminal owned by this element,
|
|
|
|
* this terminal haven't got any conductor docked.
|
|
|
|
* The second Terminal of QPair is a Terminal owned by an other element,
|
|
|
|
* which is aligned with the first Terminal. The second Terminal can have or not docked conductors.
|
|
|
|
*/
|
|
|
|
QList <QPair <Terminal *, Terminal *> > Element::AlignedFreeTerminals() const
|
|
|
|
{
|
|
|
|
QList <QPair <Terminal *, Terminal *> > list;
|
|
|
|
|
2017-02-05 16:18:50 +00:00
|
|
|
foreach (Terminal *terminal, terminals())
|
2015-01-09 17:18:16 +00:00
|
|
|
{
|
|
|
|
if (terminal->conductors().isEmpty())
|
|
|
|
{
|
|
|
|
Terminal *other_terminal = terminal -> alignedWithTerminal();
|
|
|
|
if (other_terminal)
|
|
|
|
list << qMakePair(terminal, other_terminal);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
2015-01-07 19:35:42 +00:00
|
|
|
/**
|
|
|
|
* @brief Element::initLink
|
|
|
|
* Initialise the link between this element and other elements.
|
|
|
|
* This method can be call once because init the link according to
|
|
|
|
* uuid store in a private list, after link, the list is clear, so
|
|
|
|
* call another time do nothing.
|
|
|
|
*
|
|
|
|
* @param prj, ownership project of this element and other element to be linked
|
|
|
|
*/
|
|
|
|
void Element::initLink(QETProject *prj)
|
|
|
|
{
|
|
|
|
// if nothing to link return now
|
2013-12-31 14:39:34 +00:00
|
|
|
if (tmp_uuids_link.isEmpty()) return;
|
|
|
|
|
|
|
|
ElementProvider ep(prj);
|
2017-02-05 16:18:50 +00:00
|
|
|
foreach (Element *elmt, ep.fromUuids(tmp_uuids_link)) {
|
2013-12-31 14:39:34 +00:00
|
|
|
elmt->linkToElement(this);
|
|
|
|
}
|
|
|
|
tmp_uuids_link.clear();
|
|
|
|
}
|
2014-03-18 12:35:36 +00:00
|
|
|
|
2014-03-21 14:40:33 +00:00
|
|
|
/**
|
|
|
|
* @brief Element::setElementInformations
|
|
|
|
* Set new information for this element.
|
2015-05-31 15:02:41 +00:00
|
|
|
* If new information is different of current infotmation emit @elementInfoChange
|
2014-03-21 14:40:33 +00:00
|
|
|
* @param dc
|
|
|
|
*/
|
2015-05-31 15:02:41 +00:00
|
|
|
void Element::setElementInformations(DiagramContext dc)
|
|
|
|
{
|
|
|
|
if (m_element_informations == dc) return;
|
|
|
|
DiagramContext old_info = m_element_informations;
|
|
|
|
m_element_informations = dc;
|
|
|
|
emit elementInfoChange(old_info, m_element_informations);
|
2014-03-21 14:40:33 +00:00
|
|
|
}
|
|
|
|
|
2014-03-18 12:35:36 +00:00
|
|
|
/**
|
|
|
|
* @brief comparPos
|
|
|
|
* Compare position of the two elements. Compare 3 points:
|
|
|
|
* 1 folio - 2 row - 3 line
|
|
|
|
* returns a response when a comparison is found.
|
|
|
|
* @return true if elmt1 is at lower position than elmt 2, else false
|
|
|
|
*/
|
|
|
|
bool comparPos(const Element *elmt1, const Element *elmt2) {
|
|
|
|
//Compare folio first
|
|
|
|
if (elmt1->diagram()->folioIndex() != elmt2->diagram()->folioIndex())
|
|
|
|
return elmt1->diagram()->folioIndex() < elmt2->diagram()->folioIndex();
|
2014-03-26 10:41:06 +00:00
|
|
|
//Compare the row(in letter pos) in second
|
2014-03-18 12:35:36 +00:00
|
|
|
QString a = elmt1->diagram()->convertPosition(elmt1->scenePos()).letter();
|
|
|
|
QString b = elmt2->diagram()->convertPosition(elmt2->scenePos()).letter();
|
|
|
|
if (a != b)
|
|
|
|
return a<b;
|
2014-03-26 10:41:06 +00:00
|
|
|
//In last compare the line, if line is egal, return sorted by row in real pos
|
|
|
|
if (elmt1->pos().x() == elmt2->pos().x())
|
|
|
|
return elmt1->y() <= elmt2->pos().y();
|
2014-03-18 12:35:36 +00:00
|
|
|
return elmt1->pos().x() <= elmt2->pos().x();
|
|
|
|
}
|
2014-11-16 14:15:32 +00:00
|
|
|
|
2015-01-09 17:18:16 +00:00
|
|
|
/**
|
|
|
|
* @brief Element::mouseMoveEvent
|
|
|
|
* @param event
|
|
|
|
*/
|
2015-01-07 19:35:42 +00:00
|
|
|
void Element::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
|
|
|
{
|
|
|
|
QetGraphicsItem::mouseMoveEvent(event);
|
2017-02-05 16:18:50 +00:00
|
|
|
foreach (Terminal *t, terminals())
|
2015-01-07 19:35:42 +00:00
|
|
|
{
|
|
|
|
t -> drawHelpLine(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-09 17:18:16 +00:00
|
|
|
/**
|
|
|
|
* @brief Element::mouseReleaseEvent
|
|
|
|
* @param event
|
|
|
|
*/
|
2015-01-07 19:35:42 +00:00
|
|
|
void Element::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
|
|
|
{
|
|
|
|
QetGraphicsItem::mouseReleaseEvent(event);
|
2017-02-05 16:18:50 +00:00
|
|
|
foreach (Terminal *t, terminals())
|
2015-01-07 19:35:42 +00:00
|
|
|
{
|
|
|
|
t -> drawHelpLine(false);
|
|
|
|
}
|
|
|
|
}
|
2014-11-16 14:15:32 +00:00
|
|
|
|
|
|
|
/**
|
2014-12-14 18:51:49 +00:00
|
|
|
* When mouse over element
|
|
|
|
* change m_mouse_over to true (used in paint() function )
|
|
|
|
* Also highlight linked elements
|
|
|
|
* @param e QGraphicsSceneHoverEvent
|
2014-11-16 14:15:32 +00:00
|
|
|
*/
|
|
|
|
void Element::hoverEnterEvent(QGraphicsSceneHoverEvent *e) {
|
|
|
|
Q_UNUSED(e);
|
|
|
|
|
2017-02-05 16:18:50 +00:00
|
|
|
foreach (Element *elmt, linkedElements())
|
2014-12-14 18:51:49 +00:00
|
|
|
elmt -> setHighlighted(true);
|
|
|
|
|
|
|
|
m_mouse_over = true;
|
|
|
|
setToolTip( name() );
|
2014-11-16 14:15:32 +00:00
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-12-14 18:51:49 +00:00
|
|
|
* When mouse over element leave the position
|
|
|
|
* change m_mouse_over to false(used in paint() function )
|
|
|
|
* Also un-highlight linked elements
|
|
|
|
* @param e QGraphicsSceneHoverEvent
|
2014-11-16 14:15:32 +00:00
|
|
|
*/
|
|
|
|
void Element::hoverLeaveEvent(QGraphicsSceneHoverEvent *e) {
|
|
|
|
Q_UNUSED(e);
|
|
|
|
|
2017-02-05 16:18:50 +00:00
|
|
|
foreach (Element *elmt, linkedElements())
|
2014-12-14 18:51:49 +00:00
|
|
|
elmt -> setHighlighted(false);
|
|
|
|
|
|
|
|
m_mouse_over = false;
|
|
|
|
update();
|
2014-11-16 14:15:32 +00:00
|
|
|
}
|
2016-05-25 14:49:33 +00:00
|
|
|
|
2016-07-10 01:33:49 +00:00
|
|
|
/**
|
2016-12-01 09:09:50 +00:00
|
|
|
* @brief Element::setUpFormula
|
|
|
|
* Set up the formula used to create the label of this element
|
|
|
|
* @param : if true set tagged text to code letter (ex K for coil) with condition :
|
|
|
|
* formula is empty, text tagged "label" is emptty or "_";
|
2016-07-10 01:33:49 +00:00
|
|
|
*/
|
2016-12-01 09:09:50 +00:00
|
|
|
void Element::setUpFormula(bool code_letter)
|
2016-11-22 17:21:53 +00:00
|
|
|
{
|
2016-12-01 09:09:50 +00:00
|
|
|
if (linkType() == Element::Slave || linkType() & Element::AllReport)
|
|
|
|
return;
|
|
|
|
|
2016-11-22 17:21:53 +00:00
|
|
|
if (diagram())
|
|
|
|
{
|
2016-12-01 09:09:50 +00:00
|
|
|
QString formula = diagram()->project()->elementAutoNumCurrentFormula();
|
|
|
|
|
|
|
|
if (formula.isEmpty())
|
|
|
|
{
|
|
|
|
if (code_letter && !m_prefix.isEmpty())
|
|
|
|
{
|
|
|
|
if (ElementTextItem *eti = taggedText("label"))
|
|
|
|
{
|
|
|
|
QString text = eti->toPlainText();
|
|
|
|
if (text.isEmpty() || text == "_")
|
|
|
|
{
|
|
|
|
m_element_informations.addValue("formula", "%prefix");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_element_informations.addValue("formula", formula);
|
2016-07-26 18:52:49 +00:00
|
|
|
|
2016-12-01 09:09:50 +00:00
|
|
|
QString element_currentAutoNum = diagram()->project()->elementCurrentAutoNum();
|
|
|
|
NumerotationContext nc = diagram()->project()->elementAutoNum(element_currentAutoNum);
|
|
|
|
NumerotationContextCommands ncc (nc);
|
|
|
|
|
|
|
|
autonum::setSequential(formula, m_autoNum_seq, nc, diagram(), element_currentAutoNum);
|
|
|
|
diagram()->project()->addElementAutoNum(element_currentAutoNum, ncc.next());
|
|
|
|
}
|
2016-07-10 01:33:49 +00:00
|
|
|
}
|
2016-07-14 17:16:14 +00:00
|
|
|
}
|
|
|
|
|
2016-07-10 01:33:49 +00:00
|
|
|
/**
|
|
|
|
* @brief ElementTextItem::setTaggedText
|
|
|
|
* Set text @newstr to the text tagged with @tagg.
|
|
|
|
* If tagg is found return the text item, else return NULL.
|
|
|
|
* @param tagg required tagg
|
|
|
|
* @param newstr new label
|
|
|
|
* @param noeditable set editable or not (by default, set editable)
|
|
|
|
*/
|
|
|
|
ElementTextItem* Element::setTaggedText(const QString &tagg, const QString &newstr, const bool noeditable) {
|
|
|
|
ElementTextItem *eti = taggedText(tagg);
|
|
|
|
if (eti) {
|
|
|
|
eti -> setPlainText(newstr);
|
|
|
|
eti -> setNoEditable(noeditable);
|
|
|
|
}
|
|
|
|
return eti;
|
|
|
|
}
|
|
|
|
|
2016-12-08 16:54:41 +00:00
|
|
|
/**
|
|
|
|
* @brief Element::textItemChanged
|
|
|
|
* Use to keep up to date the element information when text item changed.
|
|
|
|
* @param dti
|
|
|
|
* @param old_str
|
|
|
|
* @param new_str
|
|
|
|
*/
|
|
|
|
void Element::textItemChanged(DiagramTextItem *dti, QString old_str, QString new_str)
|
|
|
|
{
|
|
|
|
Q_UNUSED(new_str)
|
|
|
|
|
|
|
|
if (!diagram())
|
|
|
|
return;
|
|
|
|
|
|
|
|
ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(dti);
|
|
|
|
if (!eti)
|
|
|
|
return;
|
|
|
|
|
|
|
|
QString tagg = eti->tagg();
|
|
|
|
if (m_element_informations.contains(tagg))
|
|
|
|
{
|
|
|
|
DiagramContext dc = m_element_informations;
|
|
|
|
dc.addValue(tagg, eti->toPlainText(), dc.keyMustShow(tagg));
|
|
|
|
if (tagg == "label")
|
|
|
|
dc.addValue("formula", eti->toPlainText(), dc.keyMustShow("formula"));
|
|
|
|
|
|
|
|
diagram()->undoStack().push(new ChangeElementInformationCommand(this, m_element_informations, dc));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
diagram()->undoStack().push(new ChangeDiagramTextCommand(eti, old_str, eti->toPlainText()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-13 21:25:29 +00:00
|
|
|
/**
|
|
|
|
* @brief Element::getPrefix
|
|
|
|
* get Element Prefix
|
|
|
|
*/
|
2016-11-16 16:01:53 +00:00
|
|
|
QString Element::getPrefix() const{
|
2016-07-13 21:25:29 +00:00
|
|
|
return m_prefix;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Element::setPrefix
|
|
|
|
* set Element Prefix
|
|
|
|
*/
|
|
|
|
void Element::setPrefix(QString prefix) {
|
|
|
|
m_prefix = prefix;
|
|
|
|
}
|
2016-07-20 15:07:21 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Element::freezeLabel
|
|
|
|
* Freeze this element label
|
|
|
|
*/
|
2016-12-10 12:00:52 +00:00
|
|
|
void Element::freezeLabel(bool freeze)
|
2016-11-09 16:06:04 +00:00
|
|
|
{
|
2016-12-10 12:00:52 +00:00
|
|
|
if (m_freeze_label != freeze)
|
2016-11-09 16:06:04 +00:00
|
|
|
{
|
2016-12-10 12:00:52 +00:00
|
|
|
m_freeze_label = freeze;
|
|
|
|
QString f = m_element_informations["formula"].toString();
|
|
|
|
setUpConnectionForFormula(f,f);
|
2016-07-20 15:07:21 +00:00
|
|
|
|
2016-12-10 12:00:52 +00:00
|
|
|
if (m_freeze_label == true)
|
|
|
|
updateLabel();
|
|
|
|
}
|
2016-07-20 15:07:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Element::freezeNewAddedElement
|
|
|
|
* Freeze this label if needed
|
|
|
|
*/
|
|
|
|
void Element::freezeNewAddedElement() {
|
2016-12-12 10:52:44 +00:00
|
|
|
if (this->diagram()->freezeNewElements() || this->diagram()->project()->isFreezeNewElements()) {
|
2016-12-10 12:00:52 +00:00
|
|
|
freezeLabel(true);
|
2016-07-20 15:07:21 +00:00
|
|
|
}
|
|
|
|
else return;
|
|
|
|
}
|
2016-12-01 09:09:50 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Element::setUpConnectionForFormula
|
|
|
|
* setup connection according to the variable of formula
|
|
|
|
* @param old_formula
|
|
|
|
* @param new_formula
|
|
|
|
*/
|
|
|
|
void Element::setUpConnectionForFormula(QString old_formula, QString new_formula)
|
|
|
|
{
|
2017-01-19 14:55:19 +00:00
|
|
|
//Because the variable %F is a reference to another text which can contain variables,
|
|
|
|
//we must to replace %F by the real text, to check if the real text contain the variable %id
|
|
|
|
if (diagram() && old_formula.contains("%F"))
|
2017-02-11 11:42:52 +00:00
|
|
|
{
|
|
|
|
disconnect(&diagram()->border_and_titleblock, &BorderTitleBlock::titleBlockFolioChanged, this, &Element::updateLabel);
|
|
|
|
old_formula.replace("%F", m_F_str);
|
|
|
|
}
|
2017-01-19 14:55:19 +00:00
|
|
|
|
2016-12-01 09:09:50 +00:00
|
|
|
if (diagram() && (old_formula.contains("%f") || old_formula.contains("%id")))
|
|
|
|
disconnect(diagram()->project(), &QETProject::projectDiagramsOrderChanged, this, &Element::updateLabel);
|
|
|
|
if (old_formula.contains("%l"))
|
|
|
|
disconnect(this, &Element::yChanged, this, &Element::updateLabel);
|
|
|
|
if (old_formula.contains("%c"))
|
|
|
|
disconnect(this, &Element::xChanged, this, &Element::updateLabel);
|
|
|
|
|
2016-12-10 12:00:52 +00:00
|
|
|
//Label is frozen, so we don't update it.
|
|
|
|
if (m_freeze_label == true)
|
|
|
|
return;
|
2017-01-19 14:55:19 +00:00
|
|
|
|
|
|
|
if (diagram() && new_formula.contains("%F"))
|
2017-02-11 11:42:52 +00:00
|
|
|
{
|
|
|
|
m_F_str = diagram()->border_and_titleblock.folio();
|
|
|
|
new_formula.replace("%F", m_F_str);
|
|
|
|
connect(&diagram()->border_and_titleblock, &BorderTitleBlock::titleBlockFolioChanged, this, &Element::updateLabel);
|
|
|
|
}
|
2017-01-19 14:55:19 +00:00
|
|
|
|
2016-12-01 09:09:50 +00:00
|
|
|
if (diagram() && (new_formula.contains("%f") || new_formula.contains("%id")))
|
|
|
|
connect(diagram()->project(), &QETProject::projectDiagramsOrderChanged, this, &Element::updateLabel);
|
|
|
|
if (new_formula.contains("%l"))
|
|
|
|
connect(this, &Element::yChanged, this, &Element::updateLabel);
|
|
|
|
if (new_formula.contains("%c"))
|
|
|
|
connect(this, &Element::xChanged, this, &Element::updateLabel);
|
|
|
|
}
|