mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2025-09-13 20:23:04 +02:00
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:
parent
1d871e0625
commit
e6d73977c1
@ -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());
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
624
sources/factory/elementpicturefactory.cpp
Normal file
624
sources/factory/elementpicturefactory.cpp
Normal 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);
|
||||
}
|
111
sources/factory/elementpicturefactory.h
Normal file
111
sources/factory/elementpicturefactory.h
Normal 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
|
@ -24,7 +24,6 @@
|
||||
#include "diagram.h"
|
||||
#include "qetgraphicsitem/element.h"
|
||||
#include "diagramcontent.h"
|
||||
#include "qetgraphicsitem/customelement.h"
|
||||
#include "diagramposition.h"
|
||||
|
||||
class QETProject;
|
||||
|
@ -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");
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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
@ -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
|
@ -38,7 +38,7 @@ class DynamicElementTextItem : public DiagramTextItem
|
||||
{
|
||||
friend class DynamicTextItemDelegate;
|
||||
friend class CompositeTextEditDialog;
|
||||
friend class CustomElement;
|
||||
friend class Element;
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -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
|
||||
*/
|
||||
Element::Element(QGraphicsItem *parent) :
|
||||
* @brief Element::Element
|
||||
* @param location, location of this element
|
||||
* @param parent, parent graphics item
|
||||
* @param state, state of the instanciation
|
||||
*/
|
||||
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_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
|
||||
*/
|
||||
QSize Element::setSize(int wid, int hei) {
|
||||
* @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
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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);
|
||||
* @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
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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, "?");
|
||||
}
|
@ -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
|
@ -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()
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user