1-Use the "implicite shared" of Qt for the QPicture and QPixmap of element (https://doc.qt.io/qt-5/implicit-sharing.html).

This avoid to parse the same element definition each time user drop the same element in the diagram.
Only the first element build the picture, all other get the created picture which is shared.

2- For use the "implicite shared" QPicture and QPixmap of element, now this isn't the element who build her picture, but a dedicated class who made only this job : build the QPicture and QPixmap of elements.

3- With the two previous novelty, the class CustomElement and GhostElement are became useless, and so was removed.
Some few member function of CustomElement was moved to Element.


git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@5492 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
blacksun 2018-08-23 19:41:58 +00:00
parent 1d871e0625
commit e6d73977c1
30 changed files with 1250 additions and 1712 deletions

View File

@ -20,9 +20,10 @@
#include "xmlelementcollection.h"
#include "qetproject.h"
#include "elementscollectioncache.h"
#include "elementfactory.h"
#include "elementpicturefactory.h"
#include "element.h"
#include "qetxml.h"
#include <QPicture>
// make this class usable with QVariant
int ElementsLocation::MetaTypeId = qRegisterMetaType<ElementsLocation>("ElementsLocation");
@ -645,14 +646,8 @@ QIcon ElementsLocation::icon() const
if (cache->fetchElement(loc))
return QIcon(cache->pixmap());
}
else
{
ElementFactory *factory = ElementFactory::Instance();
int state;
Element *elmt = factory->createElement(*this, nullptr, &state);
if (state == 0)
return QIcon(elmt->pixmap());
else {
return QIcon(ElementPictureFactory::instance()->pixmap(*this));
}
return QIcon();
@ -664,21 +659,9 @@ QIcon ElementsLocation::icon() const
*/
QString ElementsLocation::name() const
{
// if (!m_project)
// {
// ElementsCollectionCache *cache = QETApp::collectionCache();
// ElementsLocation loc(*this); //Make a copy of this to keep this method const
// if (cache->fetchElement(loc))
// return cache->name();
// else
// return QString();
// }
// else
// {
NamesList nl;
nl.fromXml(xml());
return nl.name(fileName());
// }
}
/**

View File

@ -18,14 +18,12 @@
#include <math.h>
#include "qetgraphicsitem/conductor.h"
#include "qetgraphicsitem/conductortextitem.h"
#include "qetgraphicsitem/customelement.h"
#include "factory/elementfactory.h"
#include "diagram.h"
#include "diagramcommands.h"
#include "diagramcontent.h"
#include "diagramposition.h"
#include "exportdialog.h"
#include "qetgraphicsitem/ghostelement.h"
#include "qetgraphicsitem/independenttextitem.h"
#include "qetgraphicsitem/diagramimageitem.h"
#include "qetgraphicsitem/qetshapeitem.h"
@ -900,9 +898,6 @@ bool Diagram::fromXml(QDomElement &document, QPointF position, bool consider_inf
QString debug_message = QString("Diagram::fromXml() : Le chargement de la description de l'element %1 a echoue avec le code d'erreur %2").arg(element_location.path()).arg(state);
qDebug() << qPrintable(debug_message);
delete nvel_elmt;
qDebug() << "Diagram::fromXml() : Utilisation d'un GhostElement en lieu et place de cet element.";
nvel_elmt = new GhostElement(element_location);
}
addItem(nvel_elmt);
@ -1450,19 +1445,6 @@ QString Diagram::title() const {
return(border_and_titleblock.title());
}
/**
@return la liste des elements de ce schema
*/
QList<CustomElement *> Diagram::customElements() const {
QList<CustomElement *> elements_list;
foreach(QGraphicsItem *qgi, items()) {
if (CustomElement *elmt = qgraphicsitem_cast<CustomElement *>(qgi)) {
elements_list << elmt;
}
}
return(elements_list);
}
QList <Element *> Diagram::elements() const {
QList<Element *> element_list;
foreach (QGraphicsItem *qgi, items()) {
@ -1498,8 +1480,9 @@ ElementTextsMover &Diagram::elementTextsMover() {
@param location Emplacement d'un element
@return true si l'element location est utilise sur ce schema, false sinon
*/
bool Diagram::usesElement(const ElementsLocation &location) {
foreach(CustomElement *element, customElements()) {
bool Diagram::usesElement(const ElementsLocation &location)
{
for(Element *element : elements()) {
if (element -> location() == location) {
return(true);
}

View File

@ -184,7 +184,6 @@ class Diagram : public QGraphicsScene
bool isEmpty() const;
QList<CustomElement *> customElements() const;
QList<Element *> elements() const;
QList<Conductor *> conductors() const;
QSet<Conductor *> selectedConductors() const;

View File

@ -17,8 +17,6 @@
*/
#include "diagramview.h"
#include "diagram.h"
#include "qetgraphicsitem/customelement.h"
#include "qetgraphicsitem/ghostelement.h"
#include "qetgraphicsitem/conductor.h"
#include "diagramcommands.h"
#include "diagramposition.h"

View File

@ -16,7 +16,6 @@
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include "customelementpart.h"
#include "qetgraphicsitem/customelement.h"
#include "qetelementeditor.h"
/// @return le QETElementEditor auquel cet editeur appartient

View File

@ -28,12 +28,12 @@
#include "qetgraphicsitem/conductor.h"
#include "qetgraphicsitem/diagramtextitem.h"
#include "qetgraphicsitem/conductortextitem.h"
#include "qetgraphicsitem/customelement.h"
#include "qetgraphicsitem/ghostelement.h"
#include "qetgraphicsitem/independenttextitem.h"
#include "qetgraphicsitem/diagramimageitem.h"
#include "qetgraphicsitem/qetshapeitem.h"
#include "diagramfoliolist.h"
#include "elementpicturefactory.h"
#include "element.h"
/**
Constructeur
@ -496,27 +496,29 @@ void ExportDialog::generateDxf(Diagram *diagram, int width, int height, bool kee
qreal hotspot_x = (elem_pos_x) * Createdxf::xScale;
qreal hotspot_y = Createdxf::sheetHeight - (elem_pos_y) * Createdxf::yScale;
QList<QLineF *> elmt_line = elmt -> lines();
foreach(QLineF *line, elmt_line) {
qreal x1 = (elem_pos_x + line -> p1().x()) * Createdxf::xScale;
qreal y1 = Createdxf::sheetHeight - (elem_pos_y + line -> p1().y()) * Createdxf::yScale;
ElementPictureFactory::primitives primitives = ElementPictureFactory::instance()->getPrimitives(elmt->location());
for (QLineF line : primitives.m_lines)
{
qreal x1 = (elem_pos_x + line.p1().x()) * Createdxf::xScale;
qreal y1 = Createdxf::sheetHeight - (elem_pos_y + line.p1().y()) * Createdxf::yScale;
QPointF transformed_point = rotation_transformed(x1, y1, hotspot_x, hotspot_y, rotation_angle);
x1 = transformed_point.x();
y1 = transformed_point.y();
qreal x2 = (elem_pos_x + line -> p2().x()) * Createdxf::xScale;
qreal y2 = Createdxf::sheetHeight - (elem_pos_y + line -> p2().y()) * Createdxf::yScale;
qreal x2 = (elem_pos_x + line.p2().x()) * Createdxf::xScale;
qreal y2 = Createdxf::sheetHeight - (elem_pos_y + line.p2().y()) * Createdxf::yScale;
transformed_point = rotation_transformed(x2, y2, hotspot_x, hotspot_y, rotation_angle);
x2 = transformed_point.x();
y2 = transformed_point.y();
Createdxf::drawLine(file_path, x1, y1, x2, y2, 0);
}
QList<QRectF *> elmt_rectangle = elmt -> rectangles();
foreach(QRectF *rect, elmt_rectangle) {
qreal x1 = (elem_pos_x + rect -> bottomLeft().x()) * Createdxf::xScale;
qreal y1 = Createdxf::sheetHeight - (elem_pos_y + rect -> bottomLeft().y()) * Createdxf::yScale;
qreal w = rect -> width() * Createdxf::xScale;
qreal h = rect -> height() * Createdxf::yScale;
for (QRectF rect : primitives.m_rectangles)
{
qreal x1 = (elem_pos_x + rect.bottomLeft().x()) * Createdxf::xScale;
qreal y1 = Createdxf::sheetHeight - (elem_pos_y + rect.bottomLeft().y()) * Createdxf::yScale;
qreal w = rect.width() * Createdxf::xScale;
qreal h = rect.height() * Createdxf::yScale;
// opposite corner
qreal x2 = x1 + w;
qreal y2 = y1 + h;
@ -533,29 +535,29 @@ void ExportDialog::generateDxf(Diagram *diagram, int width, int height, bool kee
Createdxf::drawRectangle(file_path, bottom_left_x, bottom_left_y, w, h, 0);
}
QList<QRectF *> elmt_circle = elmt -> circles();
foreach(QRectF *circle_rect, elmt_circle) {
qreal x1 = (elem_pos_x + circle_rect ->center().x()) * Createdxf::xScale;
qreal y1 = Createdxf::sheetHeight - (elem_pos_y + circle_rect -> center().y()) * Createdxf::yScale;
qreal r = circle_rect -> width() * Createdxf::xScale / 2;
for (QRectF circle_rect : primitives.m_circles)
{
qreal x1 = (elem_pos_x + circle_rect.center().x()) * Createdxf::xScale;
qreal y1 = Createdxf::sheetHeight - (elem_pos_y + circle_rect.center().y()) * Createdxf::yScale;
qreal r = circle_rect.width() * Createdxf::xScale / 2;
QPointF transformed_point = rotation_transformed(x1, y1, hotspot_x, hotspot_y, rotation_angle);
x1 = transformed_point.x();
y1 = transformed_point.y();
Createdxf::drawCircle(file_path, r, x1, y1, 0);
}
QList<QVector<QPointF> *> elmt_polygon = elmt -> polygons();
foreach(QVector<QPointF> *polygon, elmt_polygon) {
if (polygon -> size() == 0)
for (QVector<QPointF> polygon : primitives.m_polygons)
{
if (polygon.size() == 0)
continue;
qreal x1 = (elem_pos_x + polygon -> at(0).x()) * Createdxf::xScale;
qreal y1 = Createdxf::sheetHeight - (elem_pos_y + polygon -> at(0).y()) * Createdxf::yScale;
qreal x1 = (elem_pos_x + polygon.at(0).x()) * Createdxf::xScale;
qreal y1 = Createdxf::sheetHeight - (elem_pos_y + polygon.at(0).y()) * Createdxf::yScale;
QPointF transformed_point = rotation_transformed(x1, y1, hotspot_x, hotspot_y, rotation_angle);
x1 = transformed_point.x();
y1 = transformed_point.y();
for (int i = 1; i < polygon -> size(); ++i ) {
qreal x2 = (elem_pos_x + polygon -> at(i).x()) * Createdxf::xScale;
qreal y2 = Createdxf::sheetHeight - (elem_pos_y + polygon -> at(i).y()) * Createdxf::yScale;
for (int i = 1; i < polygon.size(); ++i ) {
qreal x2 = (elem_pos_x + polygon.at(i).x()) * Createdxf::xScale;
qreal y2 = Createdxf::sheetHeight - (elem_pos_y + polygon.at(i).y()) * Createdxf::yScale;
QPointF transformed_point = rotation_transformed(x2, y2, hotspot_x, hotspot_y, rotation_angle);
x2 = transformed_point.x();
y2 = transformed_point.y();
@ -566,16 +568,16 @@ void ExportDialog::generateDxf(Diagram *diagram, int width, int height, bool kee
}
// Draw arcs and ellipses
QList<QVector<qreal> *> elmt_arc = elmt -> arcs();
foreach(QVector<qreal> *arc, elmt_arc) {
if (arc -> size() == 0)
for (QVector<qreal> arc : primitives.m_arcs)
{
if (arc.size() == 0)
continue;
qreal x = (elem_pos_x + arc -> at(0)) * Createdxf::xScale;
qreal y = Createdxf::sheetHeight - (elem_pos_y + arc -> at(1)) * Createdxf::yScale;
qreal w = arc -> at(2) * Createdxf::xScale;
qreal h = arc -> at(3) * Createdxf::yScale;
qreal startAngle = arc -> at(4);
qreal spanAngle = arc -> at(5);
qreal x = (elem_pos_x + arc.at(0)) * Createdxf::xScale;
qreal y = Createdxf::sheetHeight - (elem_pos_y + arc.at(1)) * Createdxf::yScale;
qreal w = arc.at(2) * Createdxf::xScale;
qreal h = arc.at(3) * Createdxf::yScale;
qreal startAngle = arc.at(4);
qreal spanAngle = arc .at(5);
Createdxf::drawArcEllipse(file_path, x, y, w, h, startAngle, spanAngle, hotspot_x, hotspot_y, rotation_angle, 0);
}
}

View File

@ -0,0 +1,624 @@
/*
Copyright 2006-2018 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 "elementpicturefactory.h"
#include "elementslocation.h"
#include "qet.h"
#include "qetapp.h"
#include "partline.h"
#include <QDomElement>
#include <QPainter>
#include <QTextDocument>
#include <QPicture>
#include <iostream>
#include <QAbstractTextDocumentLayout>
ElementPictureFactory* ElementPictureFactory::m_factory = nullptr;
/**
* @brief ElementPictureFactory::getPictures
* Set the picture of the element at location.
* Note, picture can be null
* @param location
* @param picture
* @param low_picture
*/
void ElementPictureFactory::getPictures(const ElementsLocation &location, QPicture &picture, QPicture &low_picture)
{
if(!location.exist()) {
return;
}
QUuid uuid = location.uuid();
if(m_pictures_H.keys().contains(uuid))
{
picture = m_pictures_H.value(uuid);
low_picture = m_low_pictures_H.value(uuid);
}
else
{
if (build(location))
{
picture = m_pictures_H.value(uuid);
low_picture = m_low_pictures_H.value(uuid);
}
}
}
/**
* @brief ElementPictureFactory::pixmap
* @param location
* @return the pixmap of the element at @location
* Note pixmap can be null
*/
QPixmap ElementPictureFactory::pixmap(const ElementsLocation &location)
{
QUuid uuid = location.uuid();
if (m_pixmap_H.contains(uuid)) {
return m_pixmap_H.value(uuid);
}
if(build(location))
{
QDomElement dom = location.xml();
//size
int w = dom.attribute("width").toInt();
int h = dom.attribute("height").toInt();
while (w % 10) ++ w;
while (h % 10) ++ h;
//hotspot
int hsx = qMin(dom.attribute("hotspot_x").toInt(), w);
int hsy = qMin(dom.attribute("hotspot_y").toInt(), h);
QPixmap pix(w, h);
pix.fill(QColor(255, 255, 255, 0));
QPainter painter(&pix);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
painter.translate(hsx, hsy);
painter.drawPicture(0, 0, m_pictures_H.value(uuid));
m_pixmap_H.insert(uuid, pix);
return pix;
}
return QPixmap();
}
/**
* @brief ElementPictureFactory::getPrimitives
* @param location
* @return The primtive used to draw the element at @location
*/
ElementPictureFactory::primitives ElementPictureFactory::getPrimitives(const ElementsLocation &location)
{
if(!m_primitives_H.contains(location.uuid()))
build(location);
return m_primitives_H.value(location.uuid());
}
bool ElementPictureFactory::build(const ElementsLocation &location)
{
QDomElement dom = location.xml();
//Check if the curent version can read the xml description
if (dom.hasAttribute("version"))
{
bool conv_ok;
qreal element_version = dom.attribute("version").toDouble(&conv_ok);
if (conv_ok && QET::version.toDouble() < element_version)
{
std::cerr << qPrintable(
QObject::tr("Avertissement : l'élément "
" a été enregistré avec une version"
" ultérieure de QElectroTech.")
) << std::endl;
}
}
//This attributes must be present and valid
int w, h, hot_x, hot_y;
if (!QET::attributeIsAnInteger(dom, QString("width"), &w) ||\
!QET::attributeIsAnInteger(dom, QString("height"), &h) ||\
!QET::attributeIsAnInteger(dom, QString("hotspot_x"), &hot_x) ||\
!QET::attributeIsAnInteger(dom, QString("hotspot_y"), &hot_y))
{
return(false);
}
QPicture pic;
QPicture low_pic;
primitives primitives_;
m_pictures_H.insert(location.uuid(), pic);
m_low_pictures_H.insert(location.uuid(), low_pic);
m_primitives_H.insert(location.uuid(), primitives_);
QPainter painter;
painter.begin(&pic);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setRenderHint(QPainter::TextAntialiasing, true);
painter.setRenderHint(QPainter::SmoothPixmapTransform,true);
QPainter low_painter;
low_painter.begin(&low_pic);
low_painter.setRenderHint(QPainter::Antialiasing, true);
low_painter.setRenderHint(QPainter::TextAntialiasing, true);
low_painter.setRenderHint(QPainter::SmoothPixmapTransform,true);
QPen tmp;
tmp.setWidthF(1.0); //Vaudoo line to take into account the setCosmetic - don't remove
tmp.setCosmetic(true);
low_painter.setPen(tmp);
//scroll of the Children of the Definition: Parts of the Drawing
for (QDomNode node = dom.firstChild() ; !node.isNull() ; node = node.nextSibling())
{
QDomElement elmts = node.toElement();
if (elmts.isNull()) {
continue;
}
if (elmts.tagName() == "description")
{
//Manage the graphic description = part of drawing
for (QDomNode n = node.firstChild() ; !n.isNull() ; n = n.nextSibling())
{
QDomElement qde = n.toElement();
if (qde.isNull()) {
continue;
}
parseElement(qde, painter, primitives_);
primitives fake_prim;
parseElement(qde, low_painter, fake_prim);
}
}
}
//End of the drawing
painter.end();
low_painter.end();
return true;
}
void ElementPictureFactory::parseElement(const QDomElement &dom, QPainter &painter, primitives &prim) const
{
if (dom.tagName() == "line") (parseLine (dom, painter, prim));
else if (dom.tagName() == "rect") (parseRect (dom, painter, prim));
else if (dom.tagName() == "ellipse") (parseEllipse(dom, painter, prim));
else if (dom.tagName() == "circle") (parseCircle (dom, painter, prim));
else if (dom.tagName() == "arc") (parseArc (dom, painter, prim));
else if (dom.tagName() == "polygon") (parsePolygon(dom, painter, prim));
else if (dom.tagName() == "text") (parseText (dom, painter, prim));
}
void ElementPictureFactory::parseLine(const QDomElement &dom, QPainter &painter, primitives &prim) const
{
//This attributes must be present and valid
qreal x1, y1, x2, y2;
if (!QET::attributeIsAReal(dom, QString("x1"), &x1)) return;
if (!QET::attributeIsAReal(dom, QString("y1"), &y1)) return;
if (!QET::attributeIsAReal(dom, QString("x2"), &x2)) return;
if (!QET::attributeIsAReal(dom, QString("y2"), &y2)) return;
Qet::EndType first_end = Qet::endTypeFromString(dom.attribute("end1"));
Qet::EndType second_end = Qet::endTypeFromString(dom.attribute("end2"));
qreal length1, length2;
if (!QET::attributeIsAReal(dom, QString("length1"), &length1)) length1 = 1.5;
if (!QET::attributeIsAReal(dom, QString("length2"), &length2)) length2 = 1.5;
painter.save();
setPainterStyle(dom, painter);
QPen t = painter.pen();
t.setJoinStyle(Qt::MiterJoin);
painter.setPen(t);
QLineF line(x1, y1, x2, y2);
prim.m_lines << line;
QPointF point1(line.p1());
QPointF point2(line.p2());
qreal line_length(line.length());
qreal pen_width = painter.pen().widthF();
//Check if we must to draw extremity
bool draw_1st_end, draw_2nd_end;
qreal reduced_line_length = line_length - (length1 * PartLine::requiredLengthForEndType(first_end));
draw_1st_end = first_end && reduced_line_length >= 0;
if (draw_1st_end) {
reduced_line_length -= (length2 * PartLine::requiredLengthForEndType(second_end));
} else {
reduced_line_length = line_length - (length2 * PartLine::requiredLengthForEndType(second_end));
}
draw_2nd_end = second_end && reduced_line_length >= 0;
//Draw first extremity
QPointF start_point, stop_point;
if (draw_1st_end) {
QList<QPointF> four_points1(PartLine::fourEndPoints(point1, point2, length1));
if (first_end == Qet::Circle) {
painter.drawEllipse(QRectF(four_points1[0] - QPointF(length1, length1), QSizeF(length1 * 2.0, length1 * 2.0)));
start_point = four_points1[1];
} else if (first_end == Qet::Diamond) {
painter.drawPolygon(QPolygonF() << four_points1[1] << four_points1[2] << point1 << four_points1[3]);
start_point = four_points1[1];
} else if (first_end == Qet::Simple) {
painter.drawPolyline(QPolygonF() << four_points1[3] << point1 << four_points1[2]);
start_point = point1;
} else if (first_end == Qet::Triangle) {
painter.drawPolygon(QPolygonF() << four_points1[0] << four_points1[2] << point1 << four_points1[3]);
start_point = four_points1[0];
}
//Adjust the begining according to the width of the pen
if (pen_width && (first_end == Qet::Simple || first_end == Qet::Circle)) {
start_point = QLineF(start_point, point2).pointAt(pen_width / 2.0 / line_length);
}
} else {
start_point = point1;
}
//Draw second extremity
if (draw_2nd_end) {
QList<QPointF> four_points2(PartLine::fourEndPoints(point2, point1, length2));
if (second_end == Qet::Circle) {
painter.drawEllipse(QRectF(four_points2[0] - QPointF(length2, length2), QSizeF(length2 * 2.0, length2 * 2.0)));
stop_point = four_points2[1];
} else if (second_end == Qet::Diamond) {
painter.drawPolygon(QPolygonF() << four_points2[2] << point2 << four_points2[3] << four_points2[1]);
stop_point = four_points2[1];
} else if (second_end == Qet::Simple) {
painter.drawPolyline(QPolygonF() << four_points2[3] << point2 << four_points2[2]);
stop_point = point2;
} else if (second_end == Qet::Triangle) {
painter.drawPolygon(QPolygonF() << four_points2[0] << four_points2[2] << point2 << four_points2[3] << four_points2[0]);
stop_point = four_points2[0];
}
//Adjust the end according to the width of the pen
if (pen_width && (second_end == Qet::Simple || second_end == Qet::Circle)) {
stop_point = QLineF(point1, stop_point).pointAt((line_length - (pen_width / 2.0)) / line_length);
}
} else {
stop_point = point2;
}
painter.drawLine(start_point, stop_point);
painter.restore();
}
void ElementPictureFactory::parseRect(const QDomElement &dom, QPainter &painter, ElementPictureFactory::primitives &prim) const
{
//This attributes must be present and valid
qreal rect_x, rect_y, rect_w, rect_h, rect_rx, rect_ry;
if (!QET::attributeIsAReal(dom, QString("x"), &rect_x)) return;
if (!QET::attributeIsAReal(dom, QString("y"), &rect_y)) return;
if (!QET::attributeIsAReal(dom, QString("width"), &rect_w)) return;
if (!QET::attributeIsAReal(dom, QString("height"), &rect_h)) return;
rect_rx = dom.attribute("rx", "0").toDouble();
rect_ry = dom.attribute("ry", "0").toDouble();
prim.m_rectangles << QRectF(rect_x, rect_y, rect_w, rect_h);
painter.save();
setPainterStyle(dom, painter);
QPen p = painter.pen();
p.setJoinStyle(Qt::MiterJoin);
painter.setPen(p);
painter.drawRoundedRect(QRectF(rect_x, rect_y, rect_w, rect_h), rect_rx, rect_ry);
painter.restore();
}
void ElementPictureFactory::parseEllipse(const QDomElement &dom, QPainter &painter, ElementPictureFactory::primitives &prim) const
{
//This attributes must be present and valid
qreal ellipse_x, ellipse_y, ellipse_l, ellipse_h;
if (!QET::attributeIsAReal(dom, QString("x"), &ellipse_x)) return;
if (!QET::attributeIsAReal(dom, QString("y"), &ellipse_y)) return;
if (!QET::attributeIsAReal(dom, QString("width"), &ellipse_l)) return;
if (!QET::attributeIsAReal(dom, QString("height"), &ellipse_h)) return;
painter.save();
setPainterStyle(dom, painter);
QVector<qreal> arc;
arc.push_back(ellipse_x);
arc.push_back(ellipse_y);
arc.push_back(ellipse_l);
arc.push_back(ellipse_h);
arc.push_back(0);
arc.push_back(360);
prim.m_arcs << arc;
painter.drawEllipse(QRectF(ellipse_x, ellipse_y, ellipse_l, ellipse_h));
painter.restore();
}
void ElementPictureFactory::parseCircle(const QDomElement &dom, QPainter &painter, ElementPictureFactory::primitives &prim) const
{
//This attributes must be present and valid
qreal cercle_x, cercle_y, cercle_r;
if (!QET::attributeIsAReal(dom, QString("x"), &cercle_x)) return;
if (!QET::attributeIsAReal(dom, QString("y"), &cercle_y)) return;
if (!QET::attributeIsAReal(dom, QString("diameter"), &cercle_r)) return;
painter.save();
setPainterStyle(dom, painter);
QRectF circle_bounding_rect(cercle_x, cercle_y, cercle_r, cercle_r);
prim.m_circles << circle_bounding_rect;
painter.drawEllipse(circle_bounding_rect);
painter.restore();
}
void ElementPictureFactory::parseArc(const QDomElement &dom, QPainter &painter, ElementPictureFactory::primitives &prim) const
{
//This attributes must be present and valid
qreal arc_x, arc_y, arc_l, arc_h, arc_s, arc_a;
if (!QET::attributeIsAReal(dom, QString("x"), &arc_x)) return;
if (!QET::attributeIsAReal(dom, QString("y"), &arc_y)) return;
if (!QET::attributeIsAReal(dom, QString("width"), &arc_l)) return;
if (!QET::attributeIsAReal(dom, QString("height"), &arc_h)) return;
if (!QET::attributeIsAReal(dom, QString("start"), &arc_s)) return;
if (!QET::attributeIsAReal(dom, QString("angle"), &arc_a)) return;
painter.save();
setPainterStyle(dom, painter);
QVector<qreal> arc;
arc.push_back(arc_x);
arc.push_back(arc_y);
arc.push_back(arc_l);
arc.push_back(arc_h);
arc.push_back(arc_s);
arc.push_back(arc_a);
prim.m_arcs << arc;
painter.drawArc(QRectF(arc_x, arc_y, arc_l, arc_h), (int)(arc_s * 16), (int)(arc_a * 16));
painter.restore();
}
void ElementPictureFactory::parsePolygon(const QDomElement &dom, QPainter &painter, ElementPictureFactory::primitives &prim) const
{
int i = 1;
while(true) {
if (QET::attributeIsAReal(dom, QString("x%1").arg(i)) && QET::attributeIsAReal(dom, QString("y%1").arg(i))) ++ i;
else break;
}
if (i < 3) {
return;
}
QVector<QPointF> points; // empty vector created instead of default initialized vector with i-1 elements.
for (int j = 1 ; j < i ; ++ j) {
points.insert(
j - 1,
QPointF(
dom.attribute(QString("x%1").arg(j)).toDouble(),
dom.attribute(QString("y%1").arg(j)).toDouble()
)
);
}
painter.save();
setPainterStyle(dom, painter);
if (dom.attribute("closed") == "false") painter.drawPolyline(points.data(), i-1);
else {
painter.drawPolygon(points.data(), i-1);
// insert first point at the end again for DXF export.
points.push_back(points[0]);
}
prim.m_polygons << points;
painter.restore();
}
void ElementPictureFactory::parseText(const QDomElement &dom, QPainter &painter, ElementPictureFactory::primitives &prim) const
{
Q_UNUSED(prim);
qreal pos_x, pos_y;
int size;
if (!QET::attributeIsAReal(dom, "x", &pos_x) ||\
!QET::attributeIsAReal(dom, "y", &pos_y) ||\
!QET::attributeIsAnInteger(dom, "size", &size) ||\
!dom.hasAttribute("text")) {
return;
}
painter.save();
setPainterStyle(dom, painter);
//Get the font and metric
QFont used_font = QETApp::diagramTextsFont(size);
QFontMetrics qfm(used_font);
QColor text_color = (dom.attribute("color") != "white"? Qt::black : Qt::white);
//Instanciate a QTextDocument (like the QGraphicsTextItem class)
//for generate the graphics rendering of the text
QTextDocument text_document;
text_document.setDefaultFont(used_font);
text_document.setPlainText(dom.attribute("text"));
painter.setTransform(QTransform(), false);
painter.translate(pos_x, pos_y);
qreal default_rotation_angle = 0.0;
if (QET::attributeIsAReal(dom, "rotation", &default_rotation_angle)) {
painter.rotate(default_rotation_angle);
}
/*
Deplace le systeme de coordonnees du QPainter pour effectuer le rendu au
bon endroit ; note : on soustrait l'ascent() de la police pour
determiner le coin superieur gauche du texte alors que la position
indiquee correspond a la baseline.
*/
QPointF qpainter_offset(0.0, -qfm.ascent());
//adjusts the offset by the margin of the text document
text_document.setDocumentMargin(0.0);
painter.translate(qpainter_offset);
// force the palette used to render the QTextDocument
QAbstractTextDocumentLayout::PaintContext ctx;
ctx.palette.setColor(QPalette::Text, text_color);
text_document.documentLayout() -> draw(&painter, ctx);
painter.restore();
}
/**
* @brief ElementPictureFactory::setPainterStyle
* apply the style store in dom to painter.
* @param dom
* @param painter
*/
void ElementPictureFactory::setPainterStyle(const QDomElement &dom, QPainter &painter) const
{
QPen pen = painter.pen();
QBrush brush = painter.brush();
pen.setJoinStyle(Qt::BevelJoin);
pen.setCapStyle(Qt::SquareCap);
//Get the couples style/value
const QStringList styles = dom.attribute("style").split(";", QString::SkipEmptyParts);
QRegExp rx("^\\s*([a-z-]+)\\s*:\\s*([a-z-]+)\\s*$");
for (QString style : styles) {
if (rx.exactMatch(style)) {
QString style_name = rx.cap(1);
QString style_value = rx.cap(2);
if (style_name == "line-style") {
if (style_value == "dashed") pen.setStyle(Qt::DashLine);
else if (style_value == "dotted") pen.setStyle(Qt::DotLine);
else if (style_value == "dashdotted") pen.setStyle(Qt::DashDotLine);
else if (style_value == "normal") pen.setStyle(Qt::SolidLine);
} else if (style_name == "line-weight") {
if (style_value == "none") pen.setColor(QColor(0, 0, 0, 0));
else if (style_value == "thin") pen.setWidth(0);
else if (style_value == "normal") pen.setWidthF(1.0);
else if (style_value == "hight") pen.setWidthF(2.0);
else if (style_value == "eleve") pen.setWidthF(5.0);
} else if (style_name == "filling") {
if (style_value == "white") {
brush.setStyle(Qt::SolidPattern);
brush.setColor(Qt::white);
} else if (style_value == "black") {
brush.setStyle(Qt::SolidPattern);
brush.setColor(Qt::black);
} else if (style_value == "blue") {
brush.setStyle(Qt::SolidPattern);
brush.setColor(Qt::blue);
} else if (style_value == "red") {
brush.setStyle(Qt::SolidPattern);
brush.setColor(Qt::red);
} else if (style_value == "green") {
brush.setStyle(Qt::SolidPattern);
brush.setColor(Qt::green);
} else if (style_value == "gray") {
brush.setStyle(Qt::SolidPattern);
brush.setColor(Qt::gray);
} else if (style_value == "brun") {
brush.setStyle(Qt::SolidPattern);
brush.setColor(QColor(97, 44, 0));
} else if (style_value == "yellow") {
brush.setStyle(Qt::SolidPattern);
brush.setColor(Qt::yellow);
} else if (style_value == "cyan") {
brush.setStyle(Qt::SolidPattern);
brush.setColor(Qt::cyan);
} else if (style_value == "magenta") {
brush.setStyle(Qt::SolidPattern);
brush.setColor(Qt::magenta);
} else if (style_value == "lightgray") {
brush.setStyle(Qt::SolidPattern);
brush.setColor(Qt::lightGray);
} else if (style_value == "orange") {
brush.setStyle(Qt::SolidPattern);
brush.setColor(QColor(255, 128, 0));
} else if (style_value == "purple") {
brush.setStyle(Qt::SolidPattern);
brush.setColor(QColor(136, 28, 168));
}else if (style_value == "hor") {
brush.setStyle(Qt::HorPattern);
brush.setColor(Qt::black);
} else if (style_value == "ver") {
brush.setStyle(Qt::VerPattern);
brush.setColor(Qt::black);
} else if (style_value == "bdiag") {
brush.setStyle(Qt::BDiagPattern);
brush.setColor(Qt::black);
} else if (style_value == "fdiag") {
brush.setStyle(Qt::FDiagPattern);
brush.setColor(Qt::black);
} else if (style_value == "none") {
brush.setStyle(Qt::NoBrush);
}
} else if (style_name == "color") {
if (style_value == "black") {
pen.setColor(QColor(0, 0, 0, pen.color().alpha()));
} else if (style_value == "white") {
pen.setColor(QColor(255, 255, 255, pen.color().alpha()));
} else if (style_value == "red") {
pen.setColor(Qt::red);
}else if (style_value == "blue") {
pen.setColor(Qt::blue);
}else if (style_value == "green") {
pen.setColor(Qt::green);
}else if (style_value == "gray") {
pen.setColor(Qt::gray);
}else if (style_value == "brun") {
pen.setColor(QColor(97, 44, 0));
}else if (style_value == "yellow") {
pen.setColor(Qt::yellow);
}else if (style_value == "cyan") {
pen.setColor(Qt::cyan);
}else if (style_value == "magenta") {
pen.setColor(Qt::magenta);
}else if (style_value == "lightgray") {
pen.setColor(Qt::lightGray);
}else if (style_value == "orange") {
pen.setColor(QColor(255, 128, 0));
}else if (style_value == "purple") {
pen.setColor(QColor(136, 28, 168));
} else if (style_value == "none") {
pen.setBrush(Qt::transparent);
}
}
}
}
painter.setPen(pen);
painter.setBrush(brush);
}

View File

@ -0,0 +1,111 @@
/*
Copyright 2006-2018 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 ELEMENTPICTUREFACTORY_H
#define ELEMENTPICTUREFACTORY_H
#include <QMutex>
#include <QSharedPointer>
#include <QHash>
class ElementsLocation;
class QPicture;
class QUuid;
class QDomElement;
class QPainter;
/**
* @brief The ElementPictureFactory class
* This class is singleton factory, use
* to create and get the picture use by elements
*/
class ElementPictureFactory
{
public :
struct primitives
{
QList<QLineF> m_lines;
QList<QRectF> m_rectangles;
QList<QRectF> m_circles;
QList<QVector<QPointF>> m_polygons;
QList<QVector<qreal>> m_arcs;
};
/**
* @brief instance
* @return The instance of the factory
*/
static ElementPictureFactory* instance()
{
static QMutex mutex;
if (!m_factory)
{
mutex.lock();
if (!m_factory) {
m_factory = new ElementPictureFactory();
}
mutex.unlock();
}
return m_factory;
}
/**
* @brief dropInstance
* Drop the instance of factory
*/
static void dropInstance()
{
static QMutex mutex;
if (m_factory)
{
mutex.lock();
delete m_factory;
m_factory = nullptr;
mutex.unlock();
}
}
void getPictures(const ElementsLocation &location, QPicture &picture, QPicture &low_picture);
QPixmap pixmap(const ElementsLocation &location);
ElementPictureFactory::primitives getPrimitives(const ElementsLocation &location);
private:
ElementPictureFactory() {}
ElementPictureFactory (const ElementPictureFactory &);
ElementPictureFactory operator= (const ElementPictureFactory &);
~ElementPictureFactory() {}
bool build(const ElementsLocation &location);
void parseElement(const QDomElement &dom, QPainter &painter, primitives &prim) const;
void parseLine (const QDomElement &dom, QPainter &painter, primitives &prim) const;
void parseRect (const QDomElement &dom, QPainter &painter, primitives &prim) const;
void parseEllipse(const QDomElement &dom, QPainter &painter, primitives &prim) const;
void parseCircle (const QDomElement &dom, QPainter &painter, primitives &prim) const;
void parseArc (const QDomElement &dom, QPainter &painter, primitives &prim) const;
void parsePolygon(const QDomElement &dom, QPainter &painter, primitives &prim) const;
void parseText (const QDomElement &dom, QPainter &painter, primitives &prim) const;
void setPainterStyle(const QDomElement &dom, QPainter &painter) const;
QHash<QUuid, QPicture> m_pictures_H;
QHash<QUuid, QPicture> m_low_pictures_H;
QHash<QUuid, QPixmap> m_pixmap_H;
QHash<QUuid, primitives> m_primitives_H;
static ElementPictureFactory* m_factory;
};
#endif // ELEMENTPICTUREFACTORY_H

View File

@ -24,7 +24,6 @@
#include "diagram.h"
#include "qetgraphicsitem/element.h"
#include "diagramcontent.h"
#include "qetgraphicsitem/customelement.h"
#include "diagramposition.h"
class QETProject;

View File

@ -32,6 +32,7 @@
#include "generalconfigurationpage.h"
#include "qetmessagebox.h"
#include "projectview.h"
#include "elementpicturefactory.h"
#include <cstdlib>
#include <iostream>
@ -125,6 +126,7 @@ QETApp::~QETApp()
delete m_common_tbt_collection;
ElementFactory::dropInstance();
ElementPictureFactory::dropInstance();
//Delete all backup files
QDir dir(configDir() + "backup");

View File

@ -23,7 +23,6 @@
#include "qetgraphicsitem/element.h"
#include "elementspanelwidget.h"
#include "conductorpropertieswidget.h"
#include "qetgraphicsitem/customelement.h"
#include "qetproject.h"
#include "projectview.h"
#include "recentfiles.h"
@ -1126,17 +1125,6 @@ Element *QETDiagramEditor::currentElement() const
return(selected_elements.first());
}
/**
@return the selected element in the current diagram view, or 0 if:
* no diagram is being viewed in this editor.
* no element is selected
* more than one element is selected
* the selected element is not a custom element
*/
CustomElement *QETDiagramEditor::currentCustomElement() const {
return(dynamic_cast<CustomElement *>(currentElement()));
}
/**
Cette methode permet de retrouver le projet contenant un schema donne.
@param diagram_view Schema dont il faut retrouver
@ -1332,8 +1320,8 @@ void QETDiagramEditor::selectionGroupTriggered(QAction *action)
}
else if (value == "rotate_selected_text")
diagram->undoStack().push(new RotateTextsCommand(diagram));
else if (value == "find_selected_element" && currentCustomElement())
findElementInPanel(currentCustomElement()->location());
else if (value == "find_selected_element" && currentElement())
findElementInPanel(currentElement()->location());
else if (value == "edit_selected_element")
dv->editSelection();
else if (value == "group_selected_texts")
@ -2117,7 +2105,7 @@ void QETDiagramEditor::editElementInEditor(const ElementsLocation &location) {
diagram view.
*/
void QETDiagramEditor::editSelectedElementInEditor() {
if (CustomElement *selected_element = currentCustomElement()) {
if (Element *selected_element = currentElement()) {
editElementInEditor(selected_element -> location());
}
}

View File

@ -84,7 +84,6 @@ class QETDiagramEditor : public QETMainWindow
ProjectView *currentProjectView() const;
DiagramView *currentDiagramView() const;
Element *currentElement() const;
CustomElement * currentCustomElement() const;
ProjectView *findProject(DiagramView *) const;
ProjectView *findProject(Diagram *) const;
ProjectView *findProject(QETProject *) const;

File diff suppressed because it is too large Load Diff

View File

@ -1,118 +0,0 @@
/*
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 CUSTOM_ELEMENT_H
#define CUSTOM_ELEMENT_H
#include "element.h"
#include "nameslist.h"
#include "elementslocation.h"
#include <QPicture>
class Terminal;
/**
This class represents an electrical element; it may be used like a fixed
element, the difference being that the CustomElement reads its description
(names, drawing, behavior) from an XML document.
*/
class CustomElement : public Element
{
Q_OBJECT
// constructors, destructor
public:
CustomElement (const ElementsLocation &, QGraphicsItem * = nullptr, int * = nullptr);
~CustomElement() override;
private:
CustomElement(const CustomElement &);
// attributes
protected:
NamesList names;
ElementsLocation location_;
QPicture drawing;
QPicture low_zoom_drawing;
QList<Terminal *> m_terminals;
QList<DynamicElementTextItem *> m_dynamic_texts;
bool forbid_antialiasing;
QList<QLineF *> m_lines;
QList<QRectF *> m_rectangles;
QList<QRectF *> m_circles;
QList<QVector<QPointF> *> m_polygons;
QList<QVector<qreal> *> m_arcs;
// methods
public:
QList<Terminal *> terminals() const override;
QList<Conductor *> conductors() const override;
QList<QLineF *> lines() const override;
QList<QRectF *> rectangles() const override;
QList<QRectF *> circles() const override;
QList<QVector<QPointF> *> polygons() const override;
QList<QVector<qreal> *> arcs() const override;
void paint(QPainter *, const QStyleOptionGraphicsItem *) override;
QString typeId() const override;
ElementsLocation location() const;
QString name() const override;
protected:
virtual bool buildFromXml(const QDomElement &, int * = nullptr);
virtual bool parseElement(QDomElement &, QPainter &, bool addtolist = true);
virtual bool parseLine(QDomElement &, QPainter &, bool addtolist = true);
virtual bool parseRect(QDomElement &, QPainter &, bool addtolist = true);
virtual bool parseEllipse(QDomElement &, QPainter &, bool addtolist = true);
virtual bool parseCircle(QDomElement &, QPainter &, bool addtolist = true);
virtual bool parseArc(QDomElement &, QPainter &, bool addtolist = true);
virtual bool parsePolygon(QDomElement &, QPainter &, bool addtolist = true);
virtual bool parseText(QDomElement &, QPainter &, bool addtolist = true);
virtual bool parseInput(QDomElement &);
virtual DynamicElementTextItem *parseDynamicText(QDomElement &);
virtual Terminal *parseTerminal(QDomElement &);
virtual void setQPainterAntiAliasing(QPainter &, bool);
virtual bool validOrientationAttribute(const QDomElement &);
virtual void setPainterStyle(QDomElement &, QPainter &);
};
/**
@return The element type ID; considering a CustomElement, this means the
@location of its XML description.
@see location()
*/
inline QString CustomElement::typeId() const {
return(location_.path());
}
/**
@return the location of the XML document describing this element.
*/
inline ElementsLocation CustomElement::location() const {
return(location_);
}
/**
@return The name of this element.
*/
inline QString CustomElement::name() const {
return(names.name(location_.baseName()));
}
#endif

View File

@ -38,7 +38,7 @@ class DynamicElementTextItem : public DiagramTextItem
{
friend class DynamicTextItemDelegate;
friend class CompositeTextEditDialog;
friend class CustomElement;
friend class Element;
Q_OBJECT

View File

@ -31,6 +31,8 @@
#include "changeelementinformationcommand.h"
#include "dynamicelementtextitem.h"
#include "elementtextitemgroup.h"
#include "elementpicturefactory.h"
#include "iostream"
class ElementXmlRetroCompatibility
{
@ -62,15 +64,38 @@ class ElementXmlRetroCompatibility
};
/**
Constructeur pour un element sans scene ni parent
* @brief Element::Element
* @param location, location of this element
* @param parent, parent graphics item
* @param state, state of the instanciation
*/
Element::Element(QGraphicsItem *parent) :
Element::Element(const ElementsLocation &location, QGraphicsItem *parent, int *state) :
QetGraphicsItem(parent),
must_highlight_(false),
m_mouse_over(false)
m_location (location)
{
if(! (location.isElement() && location.exist()))
{
if (state)
{
*state = 1;
return;
}
}
int elmt_state;
buildFromXml(location.xml(), &elmt_state);
if (state) {
*state = elmt_state;
}
if (elmt_state) {
return;
}
if (state) {
*state = 0;
}
setPrefix(autonum::elementPrefixForLocation(location));
m_link_type = Simple;
uuid_ = QUuid::createUuid();
m_uuid = QUuid::createUuid();
setZValue(10);
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
setAcceptHoverEvents(true);
@ -85,11 +110,37 @@ Element::Element(QGraphicsItem *parent) :
}
/**
Destructeur
* @brief Element::~Element
*/
Element::~Element()
{
qDeleteAll (m_dynamic_text_list);
qDeleteAll (m_terminals);
}
/**
* @brief Element::terminals
* @return the list of terminals of this element.
*/
QList<Terminal *> Element::terminals() const {
return m_terminals;
}
/**
* @brief Element::conductors
* @return The list of conductors docked to this element
* the list is sorted according to the position of the terminal where the conductor is docked
* from top to bottom, and left to right.
*/
QList<Conductor *> Element::conductors() const
{
QList<Conductor *> conductors;
for (Terminal *t : m_terminals) {
conductors << t -> conductors();
}
return(conductors);
}
void Element::editProperty()
@ -106,20 +157,11 @@ void Element::editProperty()
}
}
/**
@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;
m_must_highlight = hl;
update();
}
@ -142,14 +184,20 @@ void Element::displayHelpLine(bool b)
*/
void Element::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *)
{
if (m_must_highlight) {
drawHighlight(painter, options);
}
if (must_highlight_) drawHighlight(painter, options);
//Draw the element himself
paint(painter, options);
if (options && options -> levelOfDetail < 1.0) {
painter->drawPicture(0, 0, m_low_zoom_picture);
} else {
painter->drawPicture(0, 0, m_picture);
}
//Draw the selection rectangle
if ( isSelected() || m_mouse_over ) drawSelection(painter, options);
if ( isSelected() || m_mouse_over ) {
drawSelection(painter, options);
}
}
/**
@ -160,20 +208,20 @@ QRectF Element::boundingRect() const {
}
/**
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
* @brief Element::setSize
* Define the size of the element.
* The size must be a multiple of 10.
* If not, the dimensions indicated will be arrrondies to higher tens.
* @param wid
* @param hei
*/
QSize Element::setSize(int wid, int hei) {
void 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));
dimensions = QSize(wid, hei);
}
/**
@ -209,25 +257,11 @@ QPoint Element::hotspot() const {
}
/**
Selectionne l'element
*/
void Element::select() {
setSelected(true);
}
/**
Deselectionne l'element
*/
void Element::deselect() {
setSelected(false);
}
/**
@return La pixmap de l'element
* @brief Element::pixmap
* @return the pixmap of this element
*/
QPixmap Element::pixmap() {
if (preview.isNull()) updatePixmap(); // on genere la pixmap si ce n'est deja fait
return(preview);
return ElementPictureFactory::instance()->pixmap(m_location);
}
/*** Methodes protegees ***/
@ -301,20 +335,274 @@ void Element::drawHighlight(QPainter *painter, const QStyleOptionGraphicsItem *o
}
/**
Fonction initialisant et dessinant la pixmap de l'element.
* @brief Element::buildFromXml
* Build this element from an xml description
* @param xml_def_elmt
* @param state
* Optional pointer which define the status of build
* 0 - evreything all right
* 4 - xml isn't a "definition"
* 5 - attribute of the definition isn't present or valid
* 6 - the definition is empty
* 7 - parsing of a xml node who describe a graphical part failed.
* 8 - No part of the drawing could be loaded
* @return
*/
void Element::updatePixmap() {
// Pixmap transparente faisant la taille de base de l'element
preview = QPixmap(dimensions);
preview.fill(QColor(255, 255, 255, 0));
// QPainter sur la pixmap, avec antialiasing
QPainter p(&preview);
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
paint(&p, nullptr);
bool Element::buildFromXml(const QDomElement &xml_def_elmt, int *state)
{
m_state = QET::GIBuildingFromXml;
if (xml_def_elmt.tagName() != "definition" || xml_def_elmt.attribute("type") != "element")
{
if (state) *state = 4;
m_state = QET::GIOK;
return(false);
}
//Check if the curent version can read the xml description
if (xml_def_elmt.hasAttribute("version"))
{
bool conv_ok;
qreal element_version = xml_def_elmt.attribute("version").toDouble(&conv_ok);
if (conv_ok && QET::version.toDouble() < element_version)
{
std::cerr << qPrintable(
QObject::tr("Avertissement : l'élément "
" a été enregistré avec une version"
" ultérieure de QElectroTech.")
) << std::endl;
}
}
//This attribute must be present and valid
int w, h, hot_x, hot_y;
if (
!QET::attributeIsAnInteger(xml_def_elmt, QString("width"), &w) ||\
!QET::attributeIsAnInteger(xml_def_elmt, QString("height"), &h) ||\
!QET::attributeIsAnInteger(xml_def_elmt, QString("hotspot_x"), &hot_x) ||\
!QET::attributeIsAnInteger(xml_def_elmt, QString("hotspot_y"), &hot_y)
) {
if (state) *state = 5;
m_state = QET::GIOK;
return(false);
}
setSize(w, h);
setHotspot(QPoint(hot_x, hot_y));
//the definition must have childs
if (xml_def_elmt.firstChild().isNull())
{
if (state) *state = 6;
m_state = QET::GIOK;
return(false);
}
//Extract the names
m_names.fromXml(xml_def_elmt);
setToolTip(name());
//load kind informations
m_kind_informations.fromXml(xml_def_elmt.firstChildElement("kindInformations"), "kindInformation");
//load element information
m_element_informations.fromXml(xml_def_elmt.firstChildElement("elementInformations"), "elementInformation");
//scroll of the Children of the Definition: Parts of the Drawing
int parsed_elements_count = 0;
for (QDomNode node = xml_def_elmt.firstChild() ; !node.isNull() ; node = node.nextSibling())
{
QDomElement elmts = node.toElement();
if (elmts.isNull())
continue;
if (elmts.tagName() == "description")
{
//Minor workaround to find if there is a "input" tagg as label.
//If not, we set the tagg "label" to the first "input.
QList <QDomElement> input_field;
bool have_label = false;
for (QDomElement input_node = node.firstChildElement("input") ; !input_node.isNull() ; input_node = input_node.nextSiblingElement("input"))
{
if (!input_node.isNull())
{
input_field << input_node;
if (input_node.attribute("tagg", "none") == "label")
have_label = true;
}
}
if(!have_label && !input_field.isEmpty())
input_field.first().setAttribute("tagg", "label");
//Parse the definition
for (QDomNode n = node.firstChild() ; !n.isNull() ; n = n.nextSibling())
{
QDomElement qde = n.toElement();
if (qde.isNull())
continue;
if (parseElement(qde)) {
++ parsed_elements_count;
}
else
{
if (state)
*state = 7;
m_state = QET::GIOK;
return(false);
}
}
}
}
ElementPictureFactory *epf = ElementPictureFactory::instance();
epf->getPictures(m_location, const_cast<QPicture&>(m_picture), const_cast<QPicture&>(m_low_zoom_picture));
if(!m_picture.isNull())
++ parsed_elements_count;
//They must be at least one parsed graphics part
if (!parsed_elements_count)
{
if (state)
*state = 8;
m_state = QET::GIOK;
return(false);
}
else
{
if (state)
*state = 0;
m_state = QET::GIOK;
return(true);
}
}
/**
* @brief Element::parseElement
* Parse the element of the xml description of this element
* @param dom
* @return
*/
bool Element::parseElement(const QDomElement &dom)
{
if (dom.tagName() == "terminal") return(parseTerminal(dom));
else if (dom.tagName() == "input") return(parseInput(dom));
else if (dom.tagName() == "dynamic_text") return(parseDynamicText(dom));
else return(true);
}
/**
* @brief Element::parseInput
* Parse the input (old text field)
* the parsed input are converted to dynamic text field, this function
* is only here to keep compatibility with old text.
* @param dom_element
* @return
*/
bool Element::parseInput(const QDomElement &dom_element)
{
qreal pos_x, pos_y;
int size;
if (
!QET::attributeIsAReal(dom_element, "x", &pos_x) ||\
!QET::attributeIsAReal(dom_element, "y", &pos_y) ||\
!QET::attributeIsAnInteger(dom_element, "size", &size)
) return(false);
else
{
DynamicElementTextItem *deti = new DynamicElementTextItem(this);
deti->setText(dom_element.attribute("text", "_"));
deti->setFontSize(dom_element.attribute("size", QString::number(9)).toInt());
deti->setRotation(dom_element.attribute("rotation", QString::number(0)).toDouble());
if(dom_element.attribute("tagg", "none") != "none")
{
deti->setTextFrom(DynamicElementTextItem::ElementInfo);
deti->setInfoName(dom_element.attribute("tagg"));
}
//the origin transformation point of PartDynamicTextField is the top left corner, no matter the font size
//The origin transformation point of ElementTextItem 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
QMatrix matrix;
//First make the rotation
matrix.rotate(dom_element.attribute("rotation", "0").toDouble());
QPointF pos = matrix.map(QPointF(0, -deti->boundingRect().height()/2));
matrix.reset();
//Second translate to the pos
QPointF p(dom_element.attribute("x", QString::number(0)).toDouble(),
dom_element.attribute("y", QString::number(0)).toDouble());
matrix.translate(p.x(), p.y());
deti->setPos(matrix.map(pos));
m_converted_text_from_xml_description.insert(deti, p);
return true;
}
return false;
}
/**
* @brief Element::parseDynamicText
* Create the dynamic text field describ in @dom_element
* @param dom_element
* @return
*/
DynamicElementTextItem *Element::parseDynamicText(const 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;
}
Terminal *Element::parseTerminal(const QDomElement &dom_element)
{
qreal terminalx, terminaly;
Qet::Orientation terminalo;
if (!QET::attributeIsAReal(dom_element, QString("x"), &terminalx)) {
return(nullptr);
}
if (!QET::attributeIsAReal(dom_element, QString("y"), &terminaly)) {
return(nullptr);
}
if (!dom_element.hasAttribute("orientation")) {
return(nullptr);
}
if (dom_element.attribute("orientation") == "n") {
terminalo = Qet::North;
}
else if (dom_element.attribute("orientation") == "s") {
terminalo = Qet::South;
}
else if (dom_element.attribute("orientation") == "e") {
terminalo = Qet::East;
}
else if (dom_element.attribute("orientation") == "w") {
terminalo = Qet::West;
}
else {
return(nullptr);
}
Terminal *new_terminal = new Terminal(terminalx, terminaly, terminalo, this);
m_terminals << new_terminal;
//Sort from top to bottom and left to rigth
std::sort(m_terminals.begin(), m_terminals.end(), [](Terminal *a, Terminal *b)
{
if(a->dockConductor().y() == b->dockConductor().y())
return (a->dockConductor().x() < b->dockConductor().x());
else
return (a->dockConductor().y() < b->dockConductor().y());
});
return(new_terminal);
}
/**
@ -413,7 +701,7 @@ bool Element::fromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr, bool
foreach (QDomElement qdo, uuid_list) tmp_uuids_link << qdo.attribute("uuid");
//uuid of this element
uuid_= QUuid(e.attribute("uuid", QUuid::createUuid().toString()));
m_uuid= QUuid(e.attribute("uuid", QUuid::createUuid().toString()));
//load prefix
m_prefix = e.attribute("prefix");
@ -726,7 +1014,7 @@ QDomElement Element::toXml(QDomDocument &document, QHash<Terminal *, int> &table
QDomElement element = document.createElement("element");
// type
element.setAttribute("type", typeId());
element.setAttribute("type", m_location.path());
// uuid
element.setAttribute("uuid", uuid().toString());
@ -1258,3 +1546,15 @@ void Element::freezeNewAddedElement() {
}
else return;
}
/**
* @brief Element::name
* @return the human name of this element
*/
QString Element::name() const {
return m_names.name(m_location.baseName());
}
ElementsLocation Element::location() const {
return m_location;
}

View File

@ -22,13 +22,15 @@
#include "qetgraphicsitem.h"
#include "diagramcontext.h"
#include "assignvariables.h"
#include "elementslocation.h"
#include "nameslist.h"
#include <algorithm>
#include <QPicture>
class QETProject;
class Terminal;
class Conductor;
class NumerotationContext;
class DiagramTextItem;
class DynamicElementTextItem;
class ElementTextItemGroup;
@ -43,7 +45,7 @@ class Element : public QetGraphicsItem
// constructors, destructor
public:
Element(QGraphicsItem * = nullptr);
Element(const ElementsLocation &location, QGraphicsItem * = nullptr, int *state = nullptr);
~Element() override;
private:
Element(const Element &);
@ -69,53 +71,6 @@ class Element : public QetGraphicsItem
Slave = 16,
Terminale = 32};
private:
QSize dimensions;
QPoint hotspot_coord;
QPixmap preview;
// methods
public:
/// @return the list of terminals for this element
virtual QList<Terminal *> terminals() const = 0;
/// @return the list of conductors attached to this element
virtual QList<Conductor *> conductors() const = 0;
/// @return the list of lines items in this element
virtual QList<QLineF *> lines() const = 0;
/// @return the list of rectangles items in this element
virtual QList<QRectF *> rectangles() const = 0;
/// @return the list of bounding rectangles for circles items in this element
virtual QList<QRectF *> circles() const = 0;
/// @return the list of polygons in this element
virtual QList<QVector<QPointF> *> polygons() const = 0;
/// @return the list of arcs in this element
virtual QList<QVector<qreal> *> arcs() const = 0;
QList <QPair <Terminal *, Terminal *> > AlignedFreeTerminals () const;
/**
*related method and attributes,
*about none graphic thing
*like the linked element or information about this element
*/
//METHODS related to linked element
public:
bool isFree () const;
virtual void linkToElement (Element *) {}
virtual void unlinkAllElements () {}
virtual void unlinkElement (Element *) {}
virtual void initLink (QETProject *);
QList<Element *> linkedElements ();
virtual kind linkType() const {return m_link_type;} // @return the linkable type
void newUuid() {uuid_ = QUuid::createUuid();} //create new uuid for this element
//ATTRIBUTES related to linked element
protected:
QList <Element *> connected_elements;
QList <QUuid> tmp_uuids_link;
QUuid uuid_;
kind m_link_type;
signals:
void linkedElementChanged(); //This signal is emited when the linked elements with this element change
void elementInfoChange(DiagramContext old_info, DiagramContext new_info);
@ -126,8 +81,13 @@ class Element : public QetGraphicsItem
void textAddedToGroup(DynamicElementTextItem *text, ElementTextItemGroup *group);
void textRemovedFromGroup(DynamicElementTextItem *text, ElementTextItemGroup *group);
//METHODS related to information
public:
QList<Terminal *> terminals() const;
QList<Conductor *> conductors() const;
QList <QPair <Terminal *, Terminal *> > AlignedFreeTerminals () const;
//METHODS related to information
DiagramContext elementInformations ()const {return m_element_informations;}
virtual void setElementInformations (DiagramContext dc);
DiagramContext kindInformations () const {return m_kind_informations;} //@kind_information_ is used to store more information
@ -136,7 +96,6 @@ class Element : public QetGraphicsItem
autonum::sequentialNumbers sequenceStruct () const {return m_autoNum_seq;}
autonum::sequentialNumbers& rSequenceStruct() {return m_autoNum_seq;}
void setUpFormula(bool code_letter = true);
void setPrefix(QString);
QString getPrefix() const;
@ -144,48 +103,22 @@ class Element : public QetGraphicsItem
bool isFreezeLabel() const {return m_freeze_label;}
void freezeNewAddedElement();
//ATTRIBUTES
protected:
DiagramContext m_element_informations, m_kind_informations;
autonum::sequentialNumbers m_autoNum_seq;
bool m_freeze_label = false;
QString m_F_str;
public:
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *) = 0;
/// @return This element type ID
virtual QString typeId() const = 0;
/// @return the human name for this element
QString name() const override = 0;
virtual bool isHighlighted() const;
QString name() const override;
ElementsLocation location() const;
virtual void setHighlighted(bool);
void displayHelpLine(bool b = true);
void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) override;
QRectF boundingRect() const override;
QSize setSize(int, int);
QSize size() const;
QPixmap pixmap();
// methods related to the hotspot
QPoint setHotspot(QPoint);
QPoint hotspot() const;
// selection-related methods
void select();
void deselect();
void editProperty() override;
// methods related to XML import/export
static bool valideXml(QDomElement &);
virtual bool fromXml(QDomElement &, QHash<int, Terminal *> &, bool = false);
virtual QDomElement toXml(QDomDocument &, QHash<Terminal *, int> &) const;
QUuid uuid() const;
// orientation-related methods
int orientation() const;
//METHODS related to texts
void addDynamicTextItem(DynamicElementTextItem *deti = nullptr);
void removeDynamicTextItem(DynamicElementTextItem *deti);
QList<DynamicElementTextItem *> dynamicTextItems() const;
@ -197,15 +130,33 @@ class Element : public QetGraphicsItem
bool addTextToGroup(DynamicElementTextItem *text, ElementTextItemGroup *group);
bool removeTextFromGroup(DynamicElementTextItem *text, ElementTextItemGroup *group);
//METHODS related to linked element
bool isFree () const;
virtual void linkToElement (Element *) {}
virtual void unlinkAllElements () {}
virtual void unlinkElement (Element *) {}
virtual void initLink (QETProject *);
QList<Element *> linkedElements ();
virtual kind linkType() const {return m_link_type;} // @return the linkable type
void newUuid() {m_uuid = QUuid::createUuid();} //create new uuid for this element
protected:
void drawAxes(QPainter *, const QStyleOptionGraphicsItem *);
void setSize(int, int);
private:
bool must_highlight_;
void drawSelection(QPainter *, const QStyleOptionGraphicsItem *);
void drawHighlight(QPainter *, const QStyleOptionGraphicsItem *);
void updatePixmap();
bool buildFromXml(const QDomElement &, int * = nullptr);
bool parseElement(const QDomElement &dom);
bool parseInput(const QDomElement &dom_element);
DynamicElementTextItem *parseDynamicText(const QDomElement &dom_element);
Terminal *parseTerminal(const QDomElement &dom_element);
//Reimplemented from QGraphicsItem
public:
void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) override;
QRectF boundingRect() const override;
protected:
void mouseMoveEvent ( QGraphicsSceneMouseEvent *event ) override;
void mouseReleaseEvent ( QGraphicsSceneMouseEvent *event ) override;
@ -217,8 +168,30 @@ class Element : public QetGraphicsItem
// are converted to dynamic text field, the QPointF is the original position of the text item, because the origin transformation point of text item
// and dynamic text item are not the same, so we must to keep a track of this value, to be use in the function element::fromXml
QHash <DynamicElementTextItem *, QPointF> m_converted_text_from_xml_description;
//ATTRIBUTES related to linked element
QList <Element *> connected_elements;
QList <QUuid> tmp_uuids_link;
QUuid m_uuid;
kind m_link_type;
//ATTRIBUTES related to informations
DiagramContext m_element_informations, m_kind_informations;
autonum::sequentialNumbers m_autoNum_seq;
bool m_freeze_label = false;
QString m_F_str;
ElementsLocation m_location;
NamesList m_names;
QList <Terminal *> m_terminals;
const QPicture m_picture;
const QPicture m_low_zoom_picture;
private:
bool m_mouse_over;
bool m_must_highlight = false;
QSize dimensions;
QPoint hotspot_coord;
bool m_mouse_over = false;
QString m_prefix;
QList <DynamicElementTextItem *> m_dynamic_text_list;
QList <ElementTextItemGroup *> m_texts_group;
@ -248,7 +221,7 @@ inline int Element::orientation() const {
* @return the uuid of this element
*/
inline QUuid Element::uuid() const {
return uuid_;
return m_uuid;
}
/**

View File

@ -1,185 +0,0 @@
/*
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 "ghostelement.h"
#include "qet.h"
#include "terminal.h"
#include "diagramcommands.h"
/**
Constructeur
@param location Emplacement de la definition d'element a utiliser
@param qgi Le QGraphicsItem parent de cet element
@param d Le schema affichant cet element
*/
GhostElement::GhostElement(
const ElementsLocation &location,
QGraphicsItem *qgi
) :
CustomElement(location, qgi)
{
QString tooltip_string = QString(
tr("<u>Élément manquant :</u> %1")
).arg(location_.toString());
setToolTip(tooltip_string);
}
/**
Destructeur
*/
GhostElement::~GhostElement() {
}
/**
@param e L'element XML a analyser.
@param table_id_adr Reference vers la table de correspondance entre les IDs
du fichier XML et les adresses en memoire. Si l'import reussit, il faut y
ajouter les bons couples (id, adresse).
@return true si l'import a reussi, false sinon
*/
bool GhostElement::fromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr, bool handle_inputs_rotation) {
// instancie les bornes decrites dans l'element XML
terminalsFromXml(e, table_id_adr);
// instancie les champs de texte decrits dans l'element XML
foreach(QDomElement qde, QET::findInDomElement(e, "inputs", "input")) {
qde.setAttribute("size", 9); // arbitraire
CustomElement::parseInput(qde);
}
/*
maintenant que l'element fantome connait toutes les bornes et tous les
champs de texte, on peut determiner une taille appropriee
*/
QRect final_bounding_rect = minimalBoundingRect().united(childrenBoundingRect()).toAlignedRect();
setSize(final_bounding_rect.width(), final_bounding_rect.height());
setHotspot(QPoint() - final_bounding_rect.topLeft());
// on peut desormais confectionner le rendu de l'element
generateDrawings();
// position, selection
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) {
setRotation(rotation() + (90*read_ori));
} else {
setRotation(90*read_ori);
}
return(true);
}
/**
@return le bounding rect minimum, utilise si l'element fantome n'a ni champ
de texte ni borne.
*/
QRectF GhostElement::minimalBoundingRect() const {
return(
QRectF(
QPointF(-10.0, -10.0),
QSizeF(20.0, 20.0)
)
);
}
/**
Gere l'import des bornes
@param e L'element XML a analyser.
@param table_id_adr Reference vers la table de correspondance entre les IDs
du fichier XML et les adresses en memoire. Si l'import reussit, il faut y
ajouter les bons couples (id, adresse).
@return true si l'import a reussi, false sinon
*/
bool GhostElement::terminalsFromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr) {
// instancie les bornes decrites dans l'element XML
foreach(QDomElement qde, QET::findInDomElement(e, "terminals", "terminal")) {
if (!Terminal::valideXml(qde)) continue;
// modifie certains attributs pour que l'analyse par la classe CustomElement reussisse
int previous_x_value = qde.attribute("x").toInt();
int previous_y_value = qde.attribute("y").toInt();
Qet::Orientation previous_ori_value = static_cast<Qet::Orientation>(qde.attribute("orientation").toInt());
qreal x_add = 0.0, y_add = 0.0;
if (previous_ori_value == Qet::North) y_add = -Terminal::terminalSize;
else if (previous_ori_value == Qet::East) x_add = Terminal::terminalSize;
else if (previous_ori_value == Qet::South) y_add = Terminal::terminalSize;
else if (previous_ori_value == Qet::West) x_add = -Terminal::terminalSize;
qde.setAttribute("x", previous_x_value + x_add);
qde.setAttribute("y", previous_y_value + y_add);
qde.setAttribute("orientation", previous_ori_value);
if (Terminal *new_terminal = CustomElement::parseTerminal(qde)) {
table_id_adr.insert(qde.attribute("id").toInt(), new_terminal);
}
// restaure les attributs modifies
qde.setAttribute("x", previous_x_value);
qde.setAttribute("y", previous_y_value);
qde.setAttribute("orientation", previous_ori_value);
}
return(true);
}
/**
Genere les rendus de l'element fantome : il s'agit d'un rectangle
representant grosso modo l'espace que devait prendre l'element initial.
En son centre est dessine un point d'interrogation. Une petite croix indique
le point de saisie de l'element.
*/
void GhostElement::generateDrawings() {
// style de dessin
QPen t(QBrush(Qt::black), 1.0);
// rendu normal
QPainter qp;
qp.begin(&drawing);
qp.setPen(t);
qp.setRenderHint(QPainter::Antialiasing, false);
generateDrawing(&qp);
qp.end();
// rendu low_zoom
QPainter low_zoom_qp;
low_zoom_qp.begin(&low_zoom_drawing);
t.setCosmetic(true);
low_zoom_qp.setRenderHint(QPainter::Antialiasing, false);
low_zoom_qp.setPen(t);
generateDrawing(&low_zoom_qp);
low_zoom_qp.end();
}
/**
Genere un rendu de l'element fantome
@see generateDrawings
*/
void GhostElement::generateDrawing(QPainter *painter) {
// une petite croix indique le point de saisie de l'element
painter -> drawLine(QLineF(-1.0, 0.0, 1.0, 0.0));
painter -> drawLine(QLineF(0.0, -1.0, 0.0, 1.0));
// rectangle avec un point d'interrogation au centre
QRectF drawn_rect = boundingRect().adjusted(4.0, 4.0, -4.0, -4.0);
painter -> drawRect(drawn_rect);
painter -> drawText(drawn_rect, Qt::AlignHCenter | Qt::AlignVCenter, "?");
}

View File

@ -1,53 +0,0 @@
/*
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 GHOST_ELEMENT_H
#define GHOST_ELEMENT_H
#include "customelement.h"
class QGraphicsItem;
class ElementsLocation;
class Terminal;
/**
The GhostElement class inherits CustomElement. A GhostElement aims at
visually replacing a CustomElement whose definition could not be loaded.
This way, instead of not loading an element, thus potentially losing its
position, its orientation, its child text items and conductors, one can
substitute a GhostElement. The GhostElement will extrapolate the position
of terminals and text items from the rest of the diagram. It is visually
rendered using a simple rectangle.
*/
class GhostElement : public CustomElement {
Q_OBJECT
// constructor, destructor
public:
GhostElement(const ElementsLocation &, QGraphicsItem * = nullptr);
~GhostElement() override;
// methods
public:
bool fromXml(QDomElement &, QHash<int, Terminal *> &, bool = false) override;
kind linkType() const override {return Simple;}
protected:
QRectF minimalBoundingRect() const;
bool terminalsFromXml(QDomElement &, QHash<int, Terminal *> &);
void generateDrawings();
void generateDrawing(QPainter *);
};
#endif

View File

@ -30,7 +30,7 @@
* @param state int used to know if the creation of element have error
*/
MasterElement::MasterElement(const ElementsLocation &location, QGraphicsItem *qgi, int *state) :
CustomElement(location, qgi, state)
Element(location, qgi, state)
{
m_link_type = Element::Master;
}
@ -109,7 +109,7 @@ void MasterElement::unlinkElement(Element *elmt)
*/
void MasterElement::initLink(QETProject *project) {
//Create the link with other element if needed
CustomElement::initLink(project);
Element::initLink(project);
}
/**
@ -132,7 +132,7 @@ QVariant MasterElement::itemChange(QGraphicsItem::GraphicsItemChange change, con
m_first_scene_change = false;
connect(diagram()->project(), &QETProject::XRefPropertiesChanged, this, &MasterElement::xrefPropertiesChanged);
}
return CustomElement::itemChange(change, value);
return Element::itemChange(change, value);
}
void MasterElement::xrefPropertiesChanged()

View File

@ -18,7 +18,7 @@
#ifndef MASTERELEMENT_H
#define MASTERELEMENT_H
#include "customelement.h"
#include "element.h"
class CrossRefItem;
@ -28,7 +28,7 @@ class CrossRefItem;
* to be a master element. Master element can be linked with slave element
* and display a cross ref item for know with what other element he is linked
*/
class MasterElement : public CustomElement
class MasterElement : public Element
{
Q_OBJECT

View File

@ -24,7 +24,7 @@
#include "dynamicelementtextitem.h"
ReportElement::ReportElement(const ElementsLocation &location, const QString& link_type,QGraphicsItem *qgi, int *state) :
CustomElement(location, qgi, state)
Element(location, qgi, state)
{
link_type == "next_report"? m_link_type=NextReport : m_link_type=PreviousReport;
link_type == "next_report"? m_inverse_report=PreviousReport : m_inverse_report=NextReport;

View File

@ -18,14 +18,14 @@
#ifndef REPORTELEMENT_H
#define REPORTELEMENT_H
#include "customelement.h"
#include "element.h"
/**
* @brief The ReportElement class
*this class represent an element that can be linked to an other ReportElement
* a folio report in a diagram is a element that show a wire go on an other folio
*/
class ReportElement : public CustomElement
class ReportElement : public Element
{
Q_OBJECT

View File

@ -26,7 +26,7 @@
* @param state
*/
SimpleElement::SimpleElement(const ElementsLocation &location, QGraphicsItem *qgi, int *state) :
CustomElement(location, qgi, state)
Element(location, qgi, state)
{
m_link_type = Simple;
}
@ -43,5 +43,5 @@ SimpleElement::~SimpleElement() {}
* call update label for setup it.
*/
void SimpleElement::initLink(QETProject *project) {
CustomElement::initLink(project);
Element::initLink(project);
}

View File

@ -18,7 +18,7 @@
#ifndef SIMPLEELEMENT_H
#define SIMPLEELEMENT_H
#include "customelement.h"
#include "element.h"
class QETProject;
@ -26,7 +26,7 @@ class QETProject;
* @brief The SimpleElement class
*this class represente a simple element with no specific attribute
*/
class SimpleElement : public CustomElement {
class SimpleElement : public Element {
Q_OBJECT

View File

@ -30,7 +30,7 @@
* @param state int used to know if the creation of element have error
*/
SlaveElement::SlaveElement(const ElementsLocation &location, QGraphicsItem *qgi, int *state) :
CustomElement(location, qgi, state)
Element(location, qgi, state)
{
m_xref_item = nullptr;
m_link_type = Slave;

View File

@ -18,10 +18,10 @@
#ifndef SLAVEELEMENT_H
#define SLAVEELEMENT_H
#include "customelement.h"
#include "element.h"
#include"properties/xrefproperties.h"
class SlaveElement : public CustomElement
class SlaveElement : public Element
{
Q_OBJECT
public:

View File

@ -26,7 +26,7 @@
* @param state int used to know if the creation of element have error
*/
TerminalElement::TerminalElement(const ElementsLocation &location, QGraphicsItem *qgi, int *state) :
CustomElement(location, qgi, state)
Element(location, qgi, state)
{m_link_type = Terminale;}
TerminalElement::~TerminalElement() {}
@ -36,6 +36,6 @@ TerminalElement::~TerminalElement() {}
* @param project
*/
void TerminalElement::initLink(QETProject *project) {
CustomElement::initLink(project);
Element::initLink(project);
}

View File

@ -18,11 +18,12 @@
#ifndef TERMINALELEMENT_H
#define TERMINALELEMENT_H
#include "customelement.h"
#include "element.h"
class QETProject;
class TerminalElement : public CustomElement
class TerminalElement : public Element
{
Q_OBJECT
public:

View File

@ -20,7 +20,6 @@
#include "elementinfowidget.h"
#include "masterpropertieswidget.h"
#include "linksingleelementwidget.h"
#include "ghostelement.h"
#include "diagram.h"
#include "diagramposition.h"
#include "qeticons.h"
@ -216,10 +215,9 @@ bool ElementPropertiesWidget::setLiveEdit(bool live_edit)
*/
void ElementPropertiesWidget::findInPanel()
{
CustomElement *custom_element = qobject_cast<CustomElement *>(m_element);
if (custom_element && m_diagram)
if (m_element && m_diagram)
{
m_diagram->findElementRequired(custom_element->location());
m_diagram->findElementRequired(m_element.data()->location());
emit findEditClicked();
}
}
@ -230,11 +228,10 @@ void ElementPropertiesWidget::findInPanel()
*/
void ElementPropertiesWidget::editElement()
{
CustomElement *custom_element = qobject_cast<CustomElement *>(m_element);
if (custom_element && m_diagram)
if (m_element && m_diagram)
{
m_diagram->findElementRequired(custom_element->location());
m_diagram->editElementRequired(custom_element->location());
m_diagram->findElementRequired(m_element.data()->location());
m_diagram->editElementRequired(m_element.data()->location());
emit findEditClicked();
}
}
@ -342,17 +339,7 @@ void ElementPropertiesWidget::addGeneralWidget()
*/
QWidget *ElementPropertiesWidget::generalWidget()
{
CustomElement *custom_element = qobject_cast<CustomElement *>(m_element);
GhostElement *ghost_element = qobject_cast<GhostElement *>(m_element);
// type de l'element
QString description_string;
if (ghost_element) {
description_string += tr("Élément manquant");
} else {
description_string += tr("Élément");
}
description_string += "\n";
QString description_string(tr("Élement\n"));
// some element characteristic
description_string += QString(tr("Nom : %1\n")).arg(m_element -> name());
@ -364,10 +351,7 @@ QWidget *ElementPropertiesWidget::generalWidget()
description_string += QString(tr("Rotation : %1°\n")).arg(m_element.data()->rotation());
description_string += QString(tr("Dimensions : %1*%2\n")).arg(m_element -> size().width()).arg(m_element -> size().height());
description_string += QString(tr("Bornes : %1\n")).arg(m_element -> terminals().count());
if (custom_element) {
description_string += QString(tr("Emplacement : %1\n")).arg(custom_element -> location().toString());
}
description_string += QString(tr("Emplacement : %1\n")).arg(m_element.data()->location().toString());
// widget himself
QWidget *general_widget = new QWidget (m_tab);
@ -399,12 +383,10 @@ QWidget *ElementPropertiesWidget::generalWidget()
int margin = vlayout_->contentsMargins().left() + vlayout_->contentsMargins().right();
int widht_ = vlayout_->minimumSize().width()-margin;
if (pixmap.size().width() > widht_ || pixmap.size().height() > widht_)
{
if (pixmap.size().width() > widht_ || pixmap.size().height() > widht_) {
pix->setPixmap(m_element->pixmap().scaled (widht_, widht_, Qt::KeepAspectRatio, Qt::SmoothTransformation));
}
else
{
else {
pix->setPixmap(pixmap);
}