Merge branch 'terminal_strip'

This commit is contained in:
joshua
2025-10-15 23:30:54 +02:00
45 changed files with 1894 additions and 587 deletions

View File

@@ -170,7 +170,8 @@ HEADERS += $$files(sources/*.h) \
$$files(sources/TerminalStrip/GraphicsItem/properties/*.h) \ $$files(sources/TerminalStrip/GraphicsItem/properties/*.h) \
$$files(sources/xml/*.h) \ $$files(sources/xml/*.h) \
$$files(sources/dxf/*.h) \ $$files(sources/dxf/*.h) \
$$files(sources/qet_elementscaler/*.h) $$files(sources/qet_elementscaler/*.h) \
$$files(sources/svg/*.h)
SOURCES += $$files(sources/*.cpp) \ SOURCES += $$files(sources/*.cpp) \
$$files(sources/editor/*.cpp) \ $$files(sources/editor/*.cpp) \
@@ -213,7 +214,8 @@ SOURCES += $$files(sources/*.cpp) \
$$files(sources/TerminalStrip/GraphicsItem/properties/*.cpp) \ $$files(sources/TerminalStrip/GraphicsItem/properties/*.cpp) \
$$files(sources/xml/*.cpp) \ $$files(sources/xml/*.cpp) \
$$files(sources/dxf/*.cpp) \ $$files(sources/dxf/*.cpp) \
$$files(sources/qet_elementscaler/*.cpp) $$files(sources/qet_elementscaler/*.cpp) \
$$files(sources/svg/*.cpp)
# Needed for use promote QTreeWidget in terminalstripeditor.ui # Needed for use promote QTreeWidget in terminalstripeditor.ui
INCLUDEPATH += sources/TerminalStrip/ui INCLUDEPATH += sources/TerminalStrip/ui

View File

@@ -38,8 +38,9 @@ namespace TerminalStripDrawer
class DemoRealTerminal : public AbstractRealTerminalInterface class DemoRealTerminal : public AbstractRealTerminalInterface
{ {
public: public:
DemoRealTerminal(const QString &label, const QUuid &bridge) : DemoRealTerminal(const QString &label, const QString &xref, const QUuid &bridge) :
m_label { label }, m_label { label },
m_xref{ xref },
m_bridge { bridge } m_bridge { bridge }
{} {}
@@ -55,8 +56,12 @@ namespace TerminalStripDrawer
return new DemoBridge { m_bridge }; return new DemoBridge { m_bridge };
} }
QString xref() const override {
return m_xref;
}
private: private:
QString m_label; QString m_label, m_xref;
QUuid m_bridge; QUuid m_bridge;
}; };
@@ -103,15 +108,19 @@ namespace TerminalStripDrawer
real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> { real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> {
new DemoRealTerminal( QStringLiteral("24vdc"), new DemoRealTerminal( QStringLiteral("24vdc"),
QStringLiteral("1_A1"),
lvl_1)}; lvl_1)};
real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> { real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> {
new DemoRealTerminal( QStringLiteral("0vdc"), new DemoRealTerminal( QStringLiteral("0vdc"),
QStringLiteral("1_A2"),
lvl_2)}; lvl_2)};
real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> { real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> {
new DemoRealTerminal( QStringLiteral("signal"), new DemoRealTerminal( QStringLiteral("signal"),
QStringLiteral("1_A3"),
lvl_3)}; lvl_3)};
real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> { real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> {
new DemoRealTerminal( QStringLiteral("teach"), new DemoRealTerminal( QStringLiteral("teach"),
QStringLiteral("1_A4"),
lvl_4)}; lvl_4)};
m_physical_terminal << QSharedPointer<AbstractPhysicalTerminalInterface> { m_physical_terminal << QSharedPointer<AbstractPhysicalTerminalInterface> {
new DemoPhysicalTerminal {real_terminals_vector}}; new DemoPhysicalTerminal {real_terminals_vector}};
@@ -119,34 +128,42 @@ namespace TerminalStripDrawer
real_terminals_vector.clear(); real_terminals_vector.clear();
real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> { real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> {
new DemoRealTerminal( QStringLiteral("24vdc"), new DemoRealTerminal( QStringLiteral("24vdc"),
QStringLiteral("2_A1"),
lvl_1)}; lvl_1)};
real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> { real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> {
new DemoRealTerminal( QStringLiteral("0vdc"), new DemoRealTerminal( QStringLiteral("0vdc"),
QStringLiteral("2_A2"),
lvl_2)}; lvl_2)};
real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> { real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> {
new DemoRealTerminal( QStringLiteral("signal"), new DemoRealTerminal( QStringLiteral("signal"),
QStringLiteral("2_A3"),
lvl_3)}; lvl_3)};
real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> { real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> {
new DemoRealTerminal( QStringLiteral("teach"), new DemoRealTerminal( QStringLiteral("teach"),
QStringLiteral("2_A4"),
lvl_4)}; lvl_4)};
m_physical_terminal << QSharedPointer<AbstractPhysicalTerminalInterface> { m_physical_terminal << QSharedPointer<AbstractPhysicalTerminalInterface> {
new DemoPhysicalTerminal {real_terminals_vector}}; new DemoPhysicalTerminal {real_terminals_vector}};
real_terminals_vector.clear(); real_terminals_vector.clear();
real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> { real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> {
new DemoRealTerminal( QStringLiteral("24vdc"), new DemoRealTerminal( QStringLiteral("24vdc"),
QStringLiteral("3_A1"),
lvl_1)}; lvl_1)};
real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> { real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> {
new DemoRealTerminal( QStringLiteral("0vdc"), new DemoRealTerminal( QStringLiteral("0vdc"),
QStringLiteral("3_A2"),
lvl_2)}; lvl_2)};
real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> { real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> {
new DemoRealTerminal( QStringLiteral("signal"), new DemoRealTerminal( QStringLiteral("signal"),
QStringLiteral("3_A3"),
lvl_3)}; lvl_3)};
real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> { real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> {
new DemoRealTerminal( QStringLiteral("teach"), new DemoRealTerminal( QStringLiteral("teach"),
QStringLiteral("3_A4"),
lvl_4)}; lvl_4)};
m_physical_terminal << QSharedPointer<AbstractPhysicalTerminalInterface> { m_physical_terminal << QSharedPointer<AbstractPhysicalTerminalInterface> {
new DemoPhysicalTerminal {real_terminals_vector}}; new DemoPhysicalTerminal {real_terminals_vector}};
} }
} }

View File

@@ -16,16 +16,24 @@
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>. along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "terminalstriplayoutpattern.h" #include "terminalstriplayoutpattern.h"
#include <QDebug> #include "../../../utils/qetutils.h"
TerminalStripLayoutPattern::TerminalStripLayoutPattern() TerminalStripLayoutPattern::TerminalStripLayoutPattern()
{ {
m_font.setPixelSize(15);
updateHeaderTextOption(); updateHeaderTextOption();
updateTerminalsTextOption(); updateTerminalsTextOption();
} }
/**
* @brief TerminalStripLayoutPattern::setHeaderTextAlignment
* Set text alignment to @param alignment. If alignment have no
* flag this function do nothing
* @param alignment
*/
void TerminalStripLayoutPattern::setHeaderTextAlignment(const Qt::Alignment &alignment) void TerminalStripLayoutPattern::setHeaderTextAlignment(const Qt::Alignment &alignment)
{ {
if (!alignment) return;
m_header_text_alignment = alignment; m_header_text_alignment = alignment;
updateHeaderTextOption(); updateHeaderTextOption();
} }
@@ -39,22 +47,61 @@ QTextOption TerminalStripLayoutPattern::headerTextOption() const {
return m_header_text_option; return m_header_text_option;
} }
void TerminalStripLayoutPattern::setTerminalsTextAlignment(const QVector<Qt::Alignment> &alignment) QFont TerminalStripLayoutPattern::font() const {
return m_font;
}
void TerminalStripLayoutPattern::setFont(const QFont &font) {
m_font = font;
QETUtils::pixelSizedFont(m_font);
}
/**
* @brief TerminalStripLayoutPattern::setTerminalsTextAlignment
* Set text alignment to @param alignment. If alignment have no
* flag this function do nothing
* @param alignment
*/
void TerminalStripLayoutPattern::setTerminalsTextAlignment(const Qt::Alignment &alignment)
{ {
if (!alignment) return;
m_terminals_text_alignment = alignment; m_terminals_text_alignment = alignment;
updateTerminalsTextOption(); updateTerminalsTextOption();
} }
QVector<Qt::Alignment> TerminalStripLayoutPattern::terminalsTextAlignment() const Qt::Alignment TerminalStripLayoutPattern::terminalsTextAlignment() const
{ {
return m_terminals_text_alignment; return m_terminals_text_alignment;
} }
QVector<QTextOption> TerminalStripLayoutPattern::terminalsTextOption() const QTextOption TerminalStripLayoutPattern::terminalsTextOption() const
{ {
return m_terminals_text_option; return m_terminals_text_option;
} }
/**
* @brief TerminalStripLayoutPattern::setXrefTextAlignment
* Set text alignment to @param alignment. If alignment have no
* flag this function do nothing
* @param alignment
*/
void TerminalStripLayoutPattern::setXrefTextAlignment(const Qt::Alignment &alignment)
{
if (!alignment) return;
m_xref_text_alignment = alignment;
updateTerminalsTextOption();
}
Qt::Alignment TerminalStripLayoutPattern::xrefTextAlignment() const
{
return m_xref_text_alignment;
}
QTextOption TerminalStripLayoutPattern::xrefTextOption() const
{
return m_xref_text_option;
}
void TerminalStripLayoutPattern::updateHeaderTextOption() void TerminalStripLayoutPattern::updateHeaderTextOption()
{ {
m_header_text_option.setAlignment(m_header_text_alignment); m_header_text_option.setAlignment(m_header_text_alignment);
@@ -63,16 +110,9 @@ void TerminalStripLayoutPattern::updateHeaderTextOption()
void TerminalStripLayoutPattern::updateTerminalsTextOption() void TerminalStripLayoutPattern::updateTerminalsTextOption()
{ {
if (m_terminals_text_option.size() == m_terminals_text_option.setAlignment(m_terminals_text_alignment);
m_terminals_text_alignment.size()) m_terminals_text_option.setWrapMode(QTextOption::WordWrap);
{
for (auto i = 0 ; i<m_terminals_text_option.size() ; ++i) m_xref_text_option.setAlignment(m_xref_text_alignment);
{ m_xref_text_option.setWrapMode(QTextOption::WordWrap);
m_terminals_text_option[i].setAlignment(m_terminals_text_alignment.at(i));
m_terminals_text_option[i].setWrapMode(QTextOption::WordWrap);
}
}
else {
qDebug() << "TerminalStripLayoutPattern::updateTerminalsTextOption() : Wrong vector size";
}
} }

View File

@@ -18,6 +18,7 @@
#ifndef TERMINALSTRIPLAYOUTPATTERN_H #ifndef TERMINALSTRIPLAYOUTPATTERN_H
#define TERMINALSTRIPLAYOUTPATTERN_H #define TERMINALSTRIPLAYOUTPATTERN_H
#include <QFont>
#include <QRect> #include <QRect>
#include <QSize> #include <QSize>
#include <QTextOption> #include <QTextOption>
@@ -43,45 +44,46 @@ class TerminalStripLayoutPattern
TerminalStripLayoutPattern(); TerminalStripLayoutPattern();
//Header of terminal strip //Header of terminal strip
QRect m_header_rect{0,30,50,130}; QRectF m_header_rect{0,30,50,130};
Qt::Orientation m_header_text_orientation{Qt::Horizontal}; Qt::Orientation m_header_text_orientation{Qt::Horizontal};
void setHeaderTextAlignment(const Qt::Alignment &alignment); void setHeaderTextAlignment(const Qt::Alignment &alignment);
Qt::Alignment headerTextAlignment() const; Qt::Alignment headerTextAlignment() const;
QTextOption headerTextOption() const; QTextOption headerTextOption() const;
//Spacer between the header and the terminals //Spacer between the header and the terminals
QRect m_spacer_rect{0, 50, 10, 90}; QRectF m_spacer_rect{0, 50, 10, 90};
//Font
QFont font() const;
void setFont (const QFont &font);
//Terminals //Terminals
QVector<QRect> m_terminal_rect QVector<QRectF> m_terminal_rect
{ {
QRect{0, 0, 20, 190}, QRectF{0, 0, 20, 190},
QRect{0, 10, 20, 170}, QRectF{0, 10, 20, 170},
QRect{0, 20, 20, 150}, QRectF{0, 20, 20, 150},
QRect{0, 30, 20, 130} QRectF{0, 30, 20, 130}
}; };
void setTerminalsTextAlignment(const QVector<Qt::Alignment> &alignment); //Terminal text
QVector<Qt::Alignment> terminalsTextAlignment() const; void setTerminalsTextAlignment(const Qt::Alignment &alignment);
QVector<QTextOption> terminalsTextOption() const; Qt::Alignment terminalsTextAlignment() const;
QTextOption terminalsTextOption() const;
qreal m_terminals_text_height{50};
qreal m_terminals_text_y{35};
Qt::Orientation m_terminals_text_orientation {Qt::Vertical};
QVector<QRect> m_terminals_text_rect //Xref text
{ void setXrefTextAlignment(const Qt::Alignment &alignment);
QRect{0,35,20,50}, Qt::Alignment xrefTextAlignment() const;
QRect{0,35,20,50}, QTextOption xrefTextOption() const;
QRect{0,35,20,50}, qreal m_xref_text_height{60};
QRect{0,35,20,50} qreal m_xref_text_y{95};
}; Qt::Orientation m_xref_text_orientation {Qt::Vertical};
QVector<Qt::Orientation> m_terminals_text_orientation
{
Qt::Vertical,
Qt::Vertical,
Qt::Vertical,
Qt::Vertical
};
int m_bridge_point_d{5}; qreal m_bridge_point_d{5};
QVector<int> m_bridge_point_y_offset{50,70,90,110}; QVector<qreal> m_bridge_point_y_offset{50,70,90,110};
QUuid m_uuid{QUuid::createUuid()}; QUuid m_uuid{QUuid::createUuid()};
QString m_name; QString m_name;
@@ -91,23 +93,16 @@ class TerminalStripLayoutPattern
void updateTerminalsTextOption(); void updateTerminalsTextOption();
private: private:
QFont m_font;
Qt::Alignment m_header_text_alignment{Qt::AlignCenter}; Qt::Alignment m_header_text_alignment{Qt::AlignCenter};
QTextOption m_header_text_option; QTextOption m_header_text_option;
QVector<Qt::Alignment> m_terminals_text_alignment Qt::Alignment
{ m_terminals_text_alignment {Qt::AlignRight | Qt::AlignVCenter},
Qt::AlignRight | Qt::AlignVCenter, m_xref_text_alignment {Qt::AlignLeft | Qt::AlignVCenter};
Qt::AlignRight | Qt::AlignVCenter, QTextOption
Qt::AlignRight | Qt::AlignVCenter, m_terminals_text_option{QTextOption()},
Qt::AlignRight | Qt::AlignVCenter m_xref_text_option{QTextOption()};
};
QVector<QTextOption> m_terminals_text_option
{
QTextOption(),
QTextOption(),
QTextOption(),
QTextOption()
};
}; };
#endif // TERMINALSTRIPLAYOUTPATTERN_H #endif // TERMINALSTRIPLAYOUTPATTERN_H

View File

@@ -16,6 +16,7 @@
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>. along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "terminalstripdrawer.h" #include "terminalstripdrawer.h"
#include <QPainter> #include <QPainter>
namespace TerminalStripDrawer { namespace TerminalStripDrawer {
@@ -44,6 +45,7 @@ void TerminalStripDrawer::paint(QPainter *painter)
{ {
if (m_strip && m_pattern) if (m_strip && m_pattern)
{ {
m_united_xref_text_rect = QRectF();
//To draw text, QPainter need a Qrect. Instead of create an instance //To draw text, QPainter need a Qrect. Instead of create an instance
//for each text, we re-use the same instance of QRect. //for each text, we re-use the same instance of QRect.
QRect text_rect; QRect text_rect;
@@ -56,6 +58,8 @@ void TerminalStripDrawer::paint(QPainter *painter)
auto brush_ = painter->brush(); auto brush_ = painter->brush();
brush_.setColor(Qt::white); brush_.setColor(Qt::white);
painter->setFont(m_pattern->font());
painter->setPen(pen_); painter->setPen(pen_);
painter->setBrush(brush_); painter->setBrush(brush_);
@@ -64,6 +68,8 @@ void TerminalStripDrawer::paint(QPainter *painter)
painter->save(); painter->save();
painter->setPen(Qt::blue); painter->setPen(Qt::blue);
painter->drawRect(boundingRect()); painter->drawRect(boundingRect());
painter->drawLine(QPointF{boundingRect().left(), boundingRect().center().y()},
QPointF{boundingRect().right(), boundingRect().center().y()});
painter->restore(); painter->restore();
} }
@@ -90,8 +96,7 @@ void TerminalStripDrawer::paint(QPainter *painter)
//Move painter pos to next drawing //Move painter pos to next drawing
painter->translate(m_pattern->m_header_rect.width(),0); painter->translate(m_pattern->m_header_rect.width(),0);
qreal x_offset{m_pattern->m_header_rect.width()};
int x_offset{m_pattern->m_header_rect.width()};
//Draw spacer //Draw spacer
painter->drawRect(m_pattern->m_spacer_rect); painter->drawRect(m_pattern->m_spacer_rect);
@@ -99,15 +104,23 @@ void TerminalStripDrawer::paint(QPainter *painter)
painter->translate(m_pattern->m_spacer_rect.width(),0); painter->translate(m_pattern->m_spacer_rect.width(),0);
x_offset += m_pattern->m_spacer_rect.width(); x_offset += m_pattern->m_spacer_rect.width();
//Draw terminals //Draw terminals
const auto terminals_text_rect{m_pattern->m_terminals_text_rect};
const auto terminals_text_orientation{m_pattern->m_terminals_text_orientation}; const auto terminals_text_orientation{m_pattern->m_terminals_text_orientation};
const auto terminals_text_option{m_pattern->terminalsTextOption()}; const auto terminals_text_option{m_pattern->terminalsTextOption()};
QRect terminal_rect; const auto terminals_text_height{m_pattern->m_terminals_text_height};
const auto terminals_text_y{m_pattern->m_terminals_text_y};
QRectF terminal_rect;
const auto xref_text_orientation{m_pattern->m_xref_text_orientation};
const auto xref_text_option{m_pattern->xrefTextOption()};
const auto xref_text_height{m_pattern->m_xref_text_height};
const auto xref_text_y{m_pattern->m_xref_text_y};
QRectF xref_rect;
QHash<QUuid, QVector<QPointF>> bridges_anchor_points; QHash<QUuid, QVector<QPointF>> bridges_anchor_points;
m_hovered_xref = hoverTerminal{};
int physical_index = 0;
//Loop over physical terminals //Loop over physical terminals
for (const auto &physical_t : m_strip->physicalTerminal()) for (const auto &physical_t : m_strip->physicalTerminal())
{ {
@@ -140,29 +153,34 @@ void TerminalStripDrawer::paint(QPainter *painter)
//We can't use terminal_rect.bottomLeft for p2 because //We can't use terminal_rect.bottomLeft for p2 because
//the returned value deviate from the true value //the returned value deviate from the true value
//(see Qt documentation about QRect) //(see Qt documentation about QRect)
const QPoint p2 { p1.x(), p1.y() + terminal_rect.height() }; const QPointF p2 { p1.x(), p1.y() + terminal_rect.height() };
painter->drawLine(p1, p2); painter->drawLine(p1, p2);
painter->restore();
}
if(m_preview_draw)
{
painter->save();
painter->setPen(Qt::yellow);
painter->drawLine(QPointF{terminal_rect.x(), terminal_rect.y() + terminal_rect.height()/2},
QPointF{terminal_rect.width(), terminal_rect.y() + terminal_rect.height()/2});
painter->restore(); painter->restore();
} }
//Draw text //Draw text
painter->save(); painter->save();
if (terminals_text_orientation[index_] == Qt::Horizontal) text_rect.setRect(0, terminals_text_y, terminal_rect.width(), terminals_text_height);
if (terminals_text_orientation == Qt::Vertical)
{ {
text_rect = terminals_text_rect[index_]; painter->translate(text_rect.bottomLeft());
}
else
{
const auto rect_{terminals_text_rect[index_]};
painter->translate(rect_.bottomLeft());
painter->rotate(270); painter->rotate(270);
text_rect.setRect(0, 0, rect_.height(), terminal_rect.width()); text_rect.setRect(0, 0, text_rect.height(), text_rect.width());
} }
const auto shared_real_terminal{real_terminal_vector[i]}; const auto shared_real_terminal{real_terminal_vector[i]};
painter->drawText(text_rect, painter->drawText(text_rect,
shared_real_terminal ? shared_real_terminal->label() : QLatin1String(), shared_real_terminal ? shared_real_terminal->label() : QLatin1String(),
terminals_text_option[index_]); terminals_text_option);
if (m_preview_draw) if (m_preview_draw)
{ {
@@ -172,6 +190,50 @@ void TerminalStripDrawer::paint(QPainter *painter)
painter->restore(); painter->restore();
//Draw xref
xref_rect.setRect(0, xref_text_y, terminal_rect.width(), xref_text_height);
painter->save();
if (xref_text_orientation == Qt::Vertical)
{
painter->translate(xref_rect.bottomLeft());
painter->rotate(270);
xref_rect.setRect(0, 0, xref_rect.height(), xref_rect.width());
}
QTransform transform;
transform.translate(x_offset, 0);
if (xref_text_orientation == Qt::Vertical)
{
transform.translate(0, xref_text_y + xref_text_height);
transform.rotate(270);
}
auto xref_string = shared_real_terminal->xref();
const auto mapped_xref_text_rect = transform.mapRect(painter->boundingRect(xref_rect, xref_string, xref_text_option));
if (m_united_xref_text_rect.isNull()) {
m_united_xref_text_rect = mapped_xref_text_rect;
} else {
m_united_xref_text_rect = m_united_xref_text_rect.united(mapped_xref_text_rect);
}
//if mouse hover the xref text, draw it in blue to advise user the xref is clickable.
if (!m_mouse_hover_pos.isNull() && mapped_xref_text_rect.contains(m_mouse_hover_pos)) {
painter->setPen(Qt::blue);
m_hovered_xref.physical = physical_index;
m_hovered_xref.real = i;
}
painter->drawText(xref_rect, xref_string, xref_text_option);
if (m_preview_draw)
{
painter->setPen(Qt::blue);
painter->drawRect(xref_rect);
}
painter->restore();
//Add bridge anchor //Add bridge anchor
if (shared_real_terminal->isBridged()) if (shared_real_terminal->isBridged())
{ {
@@ -198,6 +260,7 @@ void TerminalStripDrawer::paint(QPainter *painter)
painter->translate(terminal_rect.width(),0); painter->translate(terminal_rect.width(),0);
x_offset += terminal_rect.width(); x_offset += terminal_rect.width();
} }
physical_index++;
} }
painter->restore(); painter->restore();
@@ -216,7 +279,7 @@ void TerminalStripDrawer::paint(QPainter *painter)
QRectF TerminalStripDrawer::boundingRect() const QRectF TerminalStripDrawer::boundingRect() const
{ {
return QRect{0, 0, width(), height()};; return QRectF{0, 0, width(), height()};;
} }
void TerminalStripDrawer::setLayout(QSharedPointer<TerminalStripLayoutPattern> layout) void TerminalStripDrawer::setLayout(QSharedPointer<TerminalStripLayoutPattern> layout)
@@ -233,7 +296,42 @@ void TerminalStripDrawer::setPreviewDraw(bool draw) {
m_preview_draw = draw; m_preview_draw = draw;
} }
int TerminalStripDrawer::height() const void TerminalStripDrawer::setMouseHoverPos(const QPointF &pos)
{
m_last_mouse_pos_in_xrefs_rect = m_united_xref_text_rect.contains(m_mouse_hover_pos);
m_mouse_hover_pos = pos;
}
/**
* @brief TerminalStripDrawer::mouseHoverXref
* @return True if the mouse position (given through the function setMouseHoverPos)
* hover the rect of a xref.
*/
bool TerminalStripDrawer::mouseHoverXref() const {
return m_united_xref_text_rect.contains(m_mouse_hover_pos);
}
bool TerminalStripDrawer::needUpdate()
{
if (mouseHoverXref()) {
return true;
} else if (m_last_mouse_pos_in_xrefs_rect) {
return true;
}
return false;
}
/**
* @brief TerminalStripDrawer::hoveredXref
* @return the current terminal hovered by the mouse
* in the xref bounding rectangle
*/
hoverTerminal TerminalStripDrawer::hoveredXref() const
{
return m_hovered_xref;
}
qreal TerminalStripDrawer::height() const
{ {
if (m_pattern) if (m_pattern)
{ {
@@ -251,11 +349,11 @@ int TerminalStripDrawer::height() const
return 0; return 0;
} }
int TerminalStripDrawer::width() const qreal TerminalStripDrawer::width() const
{ {
if (m_pattern) if (m_pattern)
{ {
int width_{m_pattern->m_header_rect.width() + m_pattern->m_spacer_rect.width()}; qreal width_{m_pattern->m_header_rect.width() + m_pattern->m_spacer_rect.width()};
if (m_strip) if (m_strip)
{ {

View File

@@ -27,6 +27,17 @@ class TerminalStrip;
namespace TerminalStripDrawer namespace TerminalStripDrawer
{ {
/**
* @brief The hoverTerminal struct
* Just a little struct use to know what is the physical and real terminal
* when the mouse hover the Xref string of a terminal.
* If mouse don't hover a Xref the value is set to -1;
*/
struct hoverTerminal{
int physical{-1};
int real{-1};
};
class AbstractBridgeInterface class AbstractBridgeInterface
{ {
public: public:
@@ -43,6 +54,7 @@ namespace TerminalStripDrawer
virtual QString label() const = 0; virtual QString label() const = 0;
virtual bool isBridged() const = 0; virtual bool isBridged() const = 0;
virtual AbstractBridgeInterface* bridge() const = 0; virtual AbstractBridgeInterface* bridge() const = 0;
virtual QString xref() const = 0;
}; };
class AbstractPhysicalTerminalInterface class AbstractPhysicalTerminalInterface
@@ -79,14 +91,23 @@ namespace TerminalStripDrawer
void setPreviewDraw(bool draw = true); void setPreviewDraw(bool draw = true);
void setMouseHoverPos(const QPointF &pos);
bool mouseHoverXref() const;
bool needUpdate();
hoverTerminal hoveredXref() const;
private: private:
int height() const; qreal height() const;
int width() const; qreal width() const;
private: private:
QSharedPointer <AbstractTerminalStripInterface> m_strip; QSharedPointer <AbstractTerminalStripInterface> m_strip;
QSharedPointer<TerminalStripLayoutPattern> m_pattern; QSharedPointer<TerminalStripLayoutPattern> m_pattern;
bool m_preview_draw { false }; bool m_preview_draw { false };
QPointF m_mouse_hover_pos;
QRectF m_united_xref_text_rect;
bool m_last_mouse_pos_in_xrefs_rect{false};
hoverTerminal m_hovered_xref;
}; };
} }

View File

@@ -22,6 +22,8 @@
#include "../../project/projectpropertieshandler.h" #include "../../project/projectpropertieshandler.h"
#include "../../qetgraphicsitem/qgraphicsitemutility.h" #include "../../qetgraphicsitem/qgraphicsitemutility.h"
#include "../terminalstrip.h" #include "../terminalstrip.h"
#include "../physicalterminal.h"
#include "../realterminal.h"
#include "../ui/terminalstripeditorwindow.h" #include "../ui/terminalstripeditorwindow.h"
#include "trueterminalstrip.h" #include "trueterminalstrip.h"
@@ -94,13 +96,53 @@ QString TerminalStripItem::name() const {
return tr("plan de bornes"); return tr("plan de bornes");
} }
void TerminalStripItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
{
QetGraphicsItem::hoverMoveEvent(event);
m_drawer.setMouseHoverPos(hoverMousePos());
if (m_drawer.needUpdate()) {
update();
}
}
void TerminalStripItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
QetGraphicsItem::hoverLeaveEvent(event);
m_drawer.setMouseHoverPos(QPointF{});
}
void TerminalStripItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) void TerminalStripItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
{ {
Q_UNUSED (event); Q_UNUSED (event);
const auto hovered = m_drawer.hoveredXref();
if (m_strip) { if (m_strip) {
if (hovered.physical >= 0 &&
hovered.real >= 0)
{
if (const auto physical_terminal = m_strip->physicalTerminal(hovered.physical);
!physical_terminal.isNull())
{
if (const auto real_terminal = physical_terminal->realTerminal(hovered.real);
!real_terminal.isNull() &&
real_terminal->isElement())
{
if (QPointer<Element> element = real_terminal->element();
!element.isNull())
{
//Unselect and ungrab mouse to prevent unwanted
//move when element is in the same scene of this.
setSelected(false);
ungrabMouse();
QetGraphicsItem::showItem(element);
}
}
}
} else {
TerminalStripEditorWindow::edit(m_strip); TerminalStripEditorWindow::edit(m_strip);
} }
}
} }
void TerminalStripItem::refreshPending() void TerminalStripItem::refreshPending()

View File

@@ -46,6 +46,8 @@ class TerminalStripItem : public QetGraphicsItem
QRectF boundingRect() const override; QRectF boundingRect() const override;
QString name() const override; QString name() const override;
void hoverMoveEvent(QGraphicsSceneHoverEvent *event) override;
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override;
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override; void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override;
void refreshPending(); void refreshPending();
void setLayout(QSharedPointer<TerminalStripLayoutPattern> layout); void setLayout(QSharedPointer<TerminalStripLayoutPattern> layout);
@@ -57,7 +59,6 @@ class TerminalStripItem : public QetGraphicsItem
QPointer<TerminalStrip> m_strip; QPointer<TerminalStrip> m_strip;
TerminalStripDrawer::TerminalStripDrawer m_drawer; TerminalStripDrawer::TerminalStripDrawer m_drawer;
QUuid m_pending_strip_uuid; QUuid m_pending_strip_uuid;
}; };
#endif // TERMINALSTRIPITEM_H #endif // TERMINALSTRIPITEM_H

View File

@@ -20,6 +20,7 @@
#include "../realterminal.h" #include "../realterminal.h"
#include "../terminalstrip.h" #include "../terminalstrip.h"
#include "../terminalstripbridge.h" #include "../terminalstripbridge.h"
#include "../../autoNum/assignvariables.h"
#include "terminalstripdrawer.h" #include "terminalstripdrawer.h"
@@ -118,6 +119,15 @@ namespace TerminalStripDrawer
return new TrueBridge(m_real->bridge()); return new TrueBridge(m_real->bridge());
} }
QString TrueRealTerminal::xref() const
{
if (m_real && m_real->isElement()) {
return autonum::AssignVariables::genericXref(m_real->element());
} else {
return QString{};
}
}
TrueBridge::TrueBridge(QSharedPointer<TerminalStripBridge> bridge) : TrueBridge::TrueBridge(QSharedPointer<TerminalStripBridge> bridge) :
m_bridge { bridge } m_bridge { bridge }
{} {}

View File

@@ -58,6 +58,7 @@ namespace TerminalStripDrawer
QString label() const override; QString label() const override;
bool isBridged() const override; bool isBridged() const override;
AbstractBridgeInterface* bridge() const override; AbstractBridgeInterface* bridge() const override;
QString xref() const override;
private: private:
QSharedPointer<RealTerminal> m_real; QSharedPointer<RealTerminal> m_real;

View File

@@ -189,6 +189,20 @@ QVector<QSharedPointer<RealTerminal>> PhysicalTerminal::realTerminals() const {
return m_real_terminal; return m_real_terminal;
} }
/**
* @brief PhysicalTerminal::realTerminal
* @param pos
* @return the real terminal at position pos.
* Note that the returned QSharedPointer can be null
*/
QSharedPointer<RealTerminal> PhysicalTerminal::realTerminal(int pos) const
{
if (pos < m_real_terminal.size()) {
return m_real_terminal.at(pos);
}
else return QSharedPointer<RealTerminal>{};
}
/** /**
* @brief uuid * @brief uuid
* @return the uuid of this physical terminal * @return the uuid of this physical terminal

View File

@@ -86,6 +86,7 @@ class PhysicalTerminal
int levelCount() const; int levelCount() const;
int levelOf(const QSharedPointer<RealTerminal> &terminal) const; int levelOf(const QSharedPointer<RealTerminal> &terminal) const;
QVector<QSharedPointer<RealTerminal>> realTerminals() const; QVector<QSharedPointer<RealTerminal>> realTerminals() const;
QSharedPointer<RealTerminal> realTerminal(int pos) const;
QUuid uuid() const; QUuid uuid() const;
int pos() const; int pos() const;
int realTerminalCount() const; int realTerminalCount() const;

View File

@@ -1037,9 +1037,11 @@ bool TerminalStrip::fromXml(QDomElement &xml_element)
} }
} }
if (!real_t_vector.isEmpty()) {
auto raw_ptr = new PhysicalTerminal(this, real_t_vector); auto raw_ptr = new PhysicalTerminal(this, real_t_vector);
m_physical_terminals.append(raw_ptr->sharedRef()); m_physical_terminals.append(raw_ptr->sharedRef());
} }
}
} }

View File

@@ -42,6 +42,10 @@ FreeTerminalEditor::FreeTerminalEditor(QETProject *project, QWidget *parent) :
ui->m_table_view->setModel(m_model); ui->m_table_view->setModel(m_model);
ui->m_table_view->setCurrentIndex(m_model->index(0,0)); ui->m_table_view->setCurrentIndex(m_model->index(0,0));
if (m_project) {
connect(m_project, &QObject::destroyed, this, &FreeTerminalEditor::reload);
}
//Disabled the move if the table is currently edited (yellow cell) //Disabled the move if the table is currently edited (yellow cell)
connect(m_model, &FreeTerminalModel::dataChanged, this, [=] { connect(m_model, &FreeTerminalModel::dataChanged, this, [=] {
this->setDisabledMove(); this->setDisabledMove();
@@ -135,6 +139,31 @@ void FreeTerminalEditor::apply()
reload(); reload();
} }
/**
* @brief FreeTerminalEditor::setProject
* Set @project as project handled by this editor.
* If a previous project was setted, everything is clear.
* This function track the destruction of the project,
* that mean if the project pointer is deleted
* no need to call this function with a nullptr,
* everything is made inside this class.
* @param project
*/
void FreeTerminalEditor::setProject(QETProject *project)
{
if(m_project) {
disconnect(m_project, &QObject::destroyed, this, &FreeTerminalEditor::reload);
}
m_project = project;
if (m_model) {
m_model->setProject(project);
}
if (m_project) {
connect(m_project, &QObject::destroyed, this, &FreeTerminalEditor::reload);
}
reload();
}
void FreeTerminalEditor::on_m_type_cb_activated(int index) void FreeTerminalEditor::on_m_type_cb_activated(int index)
{ {
if (m_model) if (m_model)

View File

@@ -19,8 +19,8 @@
#define FREETERMINALEDITOR_H #define FREETERMINALEDITOR_H
#include <QWidget> #include <QWidget>
#include "../../qetproject.h"
class QETProject;
class RealTerminal; class RealTerminal;
class FreeTerminalModel; class FreeTerminalModel;
class QTableView; class QTableView;
@@ -40,6 +40,8 @@ class FreeTerminalEditor : public QWidget
void reload(); void reload();
void apply(); void apply();
void setProject(QETProject *project);
private slots: private slots:
void on_m_type_cb_activated(int index); void on_m_type_cb_activated(int index);
void on_m_function_cb_activated(int index); void on_m_function_cb_activated(int index);
@@ -52,7 +54,7 @@ class FreeTerminalEditor : public QWidget
private: private:
Ui::FreeTerminalEditor *ui; Ui::FreeTerminalEditor *ui;
QETProject *m_project = nullptr; QPointer <QETProject> m_project;
FreeTerminalModel *m_model = nullptr; FreeTerminalModel *m_model {nullptr};
}; };
#endif // FREETERMINALEDITOR_H #endif // FREETERMINALEDITOR_H

View File

@@ -56,10 +56,30 @@ FreeTerminalModel::Column FreeTerminalModel::columnTypeForIndex(const QModelInde
* @param parent * @param parent
*/ */
FreeTerminalModel::FreeTerminalModel(QETProject *project, QObject *parent) : FreeTerminalModel::FreeTerminalModel(QETProject *project, QObject *parent) :
QAbstractTableModel(parent), QAbstractTableModel(parent) {
m_project(project) setProject(project);
}
/**
* @brief FreeTerminalModel::setProject
* Set @project as project handled by this model.
* If a previous project was setted, everything is clear.
* This function track the destruction of the project,
* that mean if the project pointer is deleted
* no need to call this function with a nullptr,
* everything is made inside this class.
* @param project
*/
void FreeTerminalModel::setProject(QETProject *project)
{ {
fillTerminalVector(); if(m_project) {
disconnect(m_project, &QObject::destroyed, this, &FreeTerminalModel::clear);
}
m_project = project;
if (m_project) {
connect(m_project, &QObject::destroyed, this, &FreeTerminalModel::clear);
}
clear();
} }
/** /**
@@ -305,6 +325,7 @@ QVector<QSharedPointer<RealTerminal> > FreeTerminalModel::realTerminalForIndex(c
*/ */
void FreeTerminalModel::fillTerminalVector() void FreeTerminalModel::fillTerminalVector()
{ {
if (m_project) {
ElementProvider provider_(m_project); ElementProvider provider_(m_project);
auto free_terminal_vector = provider_.freeTerminal(); auto free_terminal_vector = provider_.freeTerminal();
@@ -319,6 +340,7 @@ void FreeTerminalModel::fillTerminalVector()
m_terminal_vector.append(terminal_->realTerminal()); m_terminal_vector.append(terminal_->realTerminal());
m_real_t_data.append(modelRealTerminalData::data(terminal_->realTerminal())); m_real_t_data.append(modelRealTerminalData::data(terminal_->realTerminal()));
} }
}
} }
/**************************************************************** /****************************************************************

View File

@@ -47,6 +47,7 @@ class FreeTerminalModel : public QAbstractTableModel
public: public:
explicit FreeTerminalModel(QETProject *project, QObject *parent = nullptr); explicit FreeTerminalModel(QETProject *project, QObject *parent = nullptr);
void setProject(QETProject *project);
int rowCount(const QModelIndex &parent) const override; int rowCount(const QModelIndex &parent) const override;
int columnCount(const QModelIndex &parent) const override; int columnCount(const QModelIndex &parent) const override;

View File

@@ -84,6 +84,12 @@ TerminalStripEditor::~TerminalStripEditor() {
delete ui; delete ui;
} }
void TerminalStripEditor::setProject(QETProject *project)
{
m_project = project;
setCurrentStrip(nullptr);
}
/** /**
* @brief TerminalStripEditor::setCurrentStrip * @brief TerminalStripEditor::setCurrentStrip
* Set the current terminal strip edited to \p strip_ * Set the current terminal strip edited to \p strip_
@@ -98,27 +104,15 @@ void TerminalStripEditor::setCurrentStrip(TerminalStrip *strip_)
if (m_current_strip) { if (m_current_strip) {
disconnect(m_current_strip, &TerminalStrip::orderChanged, this, &TerminalStripEditor::reload); disconnect(m_current_strip, &TerminalStrip::orderChanged, this, &TerminalStripEditor::reload);
disconnect(m_current_strip, &TerminalStrip::bridgeChanged, this, &TerminalStripEditor::reload); disconnect(m_current_strip, &TerminalStrip::bridgeChanged, this, &TerminalStripEditor::reload);
disconnect(m_current_strip, &QObject::destroyed, this, &TerminalStripEditor::clear);
} }
ui->m_move_to_cb->clear(); ui->m_move_to_cb->clear();
if (!strip_) if (!strip_) {
{ clear();
ui->m_installation_le ->clear();
ui->m_location_le ->clear();
ui->m_name_le ->clear();
ui->m_comment_le ->clear();
ui->m_description_te ->clear();
m_current_strip = nullptr;
ui->m_table_widget->setModel(nullptr);
if (m_model) {
m_model->deleteLater();
m_model = nullptr;
} }
} else {
else
{
ui->m_installation_le ->setText(strip_->installation()); ui->m_installation_le ->setText(strip_->installation());
ui->m_location_le ->setText(strip_->location()); ui->m_location_le ->setText(strip_->location());
ui->m_name_le ->setText(strip_->name()); ui->m_name_le ->setText(strip_->name());
@@ -159,6 +153,7 @@ void TerminalStripEditor::setCurrentStrip(TerminalStrip *strip_)
connect(m_current_strip, &TerminalStrip::orderChanged, this, &TerminalStripEditor::reload); connect(m_current_strip, &TerminalStrip::orderChanged, this, &TerminalStripEditor::reload);
connect(m_current_strip, &TerminalStrip::bridgeChanged, this, &TerminalStripEditor::reload); connect(m_current_strip, &TerminalStrip::bridgeChanged, this, &TerminalStripEditor::reload);
connect(m_current_strip, &QObject::destroyed, this, &TerminalStripEditor::clear);
} }
} }
@@ -230,6 +225,22 @@ void TerminalStripEditor::apply()
reload(); reload();
} }
void TerminalStripEditor::clear()
{
ui->m_installation_le ->clear();
ui->m_location_le ->clear();
ui->m_name_le ->clear();
ui->m_comment_le ->clear();
ui->m_description_te ->clear();
m_current_strip.clear();
ui->m_table_widget->setModel(nullptr);
if (m_model) {
m_model->deleteLater();
m_model = nullptr;
}
}
/** /**
* @brief TerminalStripEditor::spanMultiLevelTerminals * @brief TerminalStripEditor::spanMultiLevelTerminals
* Span row of m_table_widget for multi-level terminal * Span row of m_table_widget for multi-level terminal

View File

@@ -41,11 +41,13 @@ class TerminalStripEditor : public QWidget
public: public:
explicit TerminalStripEditor(QETProject *project, QWidget *parent = nullptr); explicit TerminalStripEditor(QETProject *project, QWidget *parent = nullptr);
~TerminalStripEditor() override; ~TerminalStripEditor() override;
void setProject(QETProject *project);
void setCurrentStrip(TerminalStrip *strip_); void setCurrentStrip(TerminalStrip *strip_);
void reload(); void reload();
void apply(); void apply();
private: private:
void clear();
void spanMultiLevelTerminals(); void spanMultiLevelTerminals();
void selectionChanged(); void selectionChanged();
QSize setUpBridgeCellWidth(); QSize setUpBridgeCellWidth();
@@ -67,8 +69,8 @@ class TerminalStripEditor : public QWidget
private: private:
Ui::TerminalStripEditor *ui; Ui::TerminalStripEditor *ui;
QETProject *m_project {nullptr}; QPointer<QETProject> m_project;
TerminalStrip *m_current_strip {nullptr}; QPointer<TerminalStrip> m_current_strip;
TerminalStripModel *m_model {nullptr}; TerminalStripModel *m_model {nullptr};
}; };

View File

@@ -55,6 +55,11 @@ TerminalStripEditorWindow::TerminalStripEditorWindow(QETProject *project, QWidge
m_project(project) m_project(project)
{ {
ui->setupUi(this); ui->setupUi(this);
if (auto diagram_editor = QETApp::diagramEditor(project)) {
ui->m_tool_bar->addSeparator();
ui->m_tool_bar->addAction(diagram_editor->undo);
ui->m_tool_bar->addAction(diagram_editor->redo);
}
ui->m_remove_terminal->setDisabled(true); ui->m_remove_terminal->setDisabled(true);
addTreeDockWidget(); addTreeDockWidget();
@@ -76,6 +81,18 @@ TerminalStripEditorWindow::~TerminalStripEditorWindow()
delete ui; delete ui;
} }
/**
* @brief TerminalStripEditorWindow::setProject
* @param project
*/
void TerminalStripEditorWindow::setProject(QETProject *project)
{
m_project = project;
m_tree_dock->setProject(project);
m_free_terminal_editor->setProject(project);
m_terminal_strip_editor->setProject(project);
}
void TerminalStripEditorWindow::setCurrentStrip(TerminalStrip *strip) { void TerminalStripEditorWindow::setCurrentStrip(TerminalStrip *strip) {
m_tree_dock->setSelectedStrip(strip); m_tree_dock->setSelectedStrip(strip);
} }
@@ -200,4 +217,3 @@ void TerminalStripEditorWindow::on_m_button_box_clicked(QAbstractButton *button)
void TerminalStripEditorWindow::on_m_stacked_widget_currentChanged(int arg1) { void TerminalStripEditorWindow::on_m_stacked_widget_currentChanged(int arg1) {
ui->m_button_box->setHidden(arg1 == EMPTY_PAGE); ui->m_button_box->setHidden(arg1 == EMPTY_PAGE);
} }

View File

@@ -51,6 +51,8 @@ class TerminalStripEditorWindow : public QMainWindow
if (!window_) if (!window_)
window_ = new TerminalStripEditorWindow{project, parent}; window_ = new TerminalStripEditorWindow{project, parent};
mutex_.unlock(); mutex_.unlock();
} else {
window_->setProject(project);
} }
return window_; return window_;
} }
@@ -71,6 +73,7 @@ class TerminalStripEditorWindow : public QMainWindow
explicit TerminalStripEditorWindow(QETProject *project, QWidget *parent = nullptr); explicit TerminalStripEditorWindow(QETProject *project, QWidget *parent = nullptr);
~TerminalStripEditorWindow(); ~TerminalStripEditorWindow();
void setProject(QETProject *project);
void setCurrentStrip(TerminalStrip *strip); void setCurrentStrip(TerminalStrip *strip);
private slots: private slots:
@@ -87,7 +90,7 @@ class TerminalStripEditorWindow : public QMainWindow
private: private:
Ui::TerminalStripEditorWindow *ui{nullptr}; Ui::TerminalStripEditorWindow *ui{nullptr};
QETProject *m_project {nullptr}; QPointer <QETProject> m_project;
TerminalStripTreeDockWidget *m_tree_dock{nullptr}; TerminalStripTreeDockWidget *m_tree_dock{nullptr};
FreeTerminalEditor *m_free_terminal_editor {nullptr}; FreeTerminalEditor *m_free_terminal_editor {nullptr};
TerminalStripEditor *m_terminal_strip_editor {nullptr}; TerminalStripEditor *m_terminal_strip_editor {nullptr};

View File

@@ -33,12 +33,12 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1364</width> <width>1364</width>
<height>21</height> <height>23</height>
</rect> </rect>
</property> </property>
</widget> </widget>
<widget class="QStatusBar" name="statusbar"/> <widget class="QStatusBar" name="statusbar"/>
<widget class="QToolBar" name="toolBar"> <widget class="QToolBar" name="m_tool_bar">
<property name="windowTitle"> <property name="windowTitle">
<string>toolBar</string> <string>toolBar</string>
</property> </property>

View File

@@ -15,6 +15,8 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>. along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <QFontDialog>
#include "terminalstriplayouteditor.h" #include "terminalstriplayouteditor.h"
#include "ui_terminalstriplayouteditor.h" #include "ui_terminalstriplayouteditor.h"
#include "../GraphicsItem/properties/terminalstriplayoutpattern.h" #include "../GraphicsItem/properties/terminalstriplayoutpattern.h"
@@ -54,8 +56,6 @@ void TerminalStripLayoutEditor::valueEdited()
return; return;
} }
//auto *data_ = m_layout.data();
m_layout.data()->m_header_rect.setRect(0, m_layout.data()->m_header_rect.setRect(0,
ui->m_y_header_sb->value(), ui->m_y_header_sb->value(),
ui->m_width_header_sb->value(), ui->m_width_header_sb->value(),
@@ -91,6 +91,10 @@ void TerminalStripLayoutEditor::valueEdited()
m_layout.data()->m_bridge_point_y_offset[2] = ui->m_bridge_point_2_sb->value(); m_layout.data()->m_bridge_point_y_offset[2] = ui->m_bridge_point_2_sb->value();
m_layout.data()->m_bridge_point_y_offset[3] = ui->m_bridge_point_3_sb->value(); m_layout.data()->m_bridge_point_y_offset[3] = ui->m_bridge_point_3_sb->value();
auto font_ = ui->m_font_cb->currentFont();
font_.setPixelSize(ui->m_font_size_sb->value());
m_layout->setFont(font_);
m_layout.data()->m_header_text_orientation = ui->m_header_text_orientation_cb->currentIndex() == 0 ? m_layout.data()->m_header_text_orientation = ui->m_header_text_orientation_cb->currentIndex() == 0 ?
Qt::Horizontal : Qt::Horizontal :
Qt::Vertical; Qt::Vertical;
@@ -104,34 +108,46 @@ void TerminalStripLayoutEditor::valueEdited()
m_layout.data()->setHeaderTextAlignment(Qt::AlignRight | Qt::AlignVCenter); break; m_layout.data()->setHeaderTextAlignment(Qt::AlignRight | Qt::AlignVCenter); break;
} }
m_layout.data()->m_terminals_text_orientation[0] = ui->m_terminal_text_orientation_cb->currentIndex() == 0 ? //Terminal text
m_layout.data()->m_terminals_text_orientation = ui->m_terminal_text_orientation_cb->currentIndex() == 0 ?
Qt::Horizontal : Qt::Horizontal :
Qt::Vertical; Qt::Vertical;
switch (ui->m_terminal_text_alignment_cb->currentIndex()) { switch (ui->m_terminal_text_alignment_cb->currentIndex()) {
case 0: case 0:
m_layout.data()->setTerminalsTextAlignment( m_layout.data()->setTerminalsTextAlignment(Qt::Alignment {Qt::AlignLeft | Qt::AlignVCenter});
QVector<Qt::Alignment> { Qt::AlignLeft | Qt::AlignVCenter,
Qt::AlignLeft | Qt::AlignVCenter,
Qt::AlignLeft | Qt::AlignVCenter,
Qt::AlignLeft | Qt::AlignVCenter });
break; break;
case 1: case 1:
m_layout.data()->setTerminalsTextAlignment( m_layout.data()->setTerminalsTextAlignment(Qt::Alignment { Qt::AlignHCenter | Qt::AlignVCenter});
QVector<Qt::Alignment> { Qt::AlignHCenter | Qt::AlignVCenter,
Qt::AlignHCenter | Qt::AlignVCenter,
Qt::AlignHCenter | Qt::AlignVCenter,
Qt::AlignHCenter | Qt::AlignVCenter });
break; break;
default: default:
m_layout.data()->setTerminalsTextAlignment( m_layout.data()->setTerminalsTextAlignment(Qt::Alignment { Qt::AlignRight | Qt::AlignVCenter});
QVector<Qt::Alignment> { Qt::AlignRight | Qt::AlignVCenter,
Qt::AlignRight | Qt::AlignVCenter,
Qt::AlignRight | Qt::AlignVCenter,
Qt::AlignRight | Qt::AlignVCenter });
break; break;
} }
m_layout.data()->m_terminals_text_y = ui->m_terminal_text_y_sb->value();
m_layout.data()->m_terminals_text_height = ui->m_terminal_text_height_sb->value();
//Xref text
m_layout.data()->m_xref_text_orientation = ui->m_xref_orientation_cb->currentIndex() == 0 ?
Qt::Horizontal :
Qt::Vertical;
switch (ui->m_xref_alignment_cb->currentIndex()) {
case 0:
m_layout.data()->setXrefTextAlignment(Qt::Alignment {Qt::AlignLeft | Qt::AlignVCenter});
break;
case 1:
m_layout.data()->setXrefTextAlignment(Qt::Alignment { Qt::AlignHCenter | Qt::AlignVCenter});
break;
default:
m_layout.data()->setXrefTextAlignment(Qt::Alignment { Qt::AlignRight | Qt::AlignVCenter});
break;
}
m_layout.data()->m_xref_text_y = ui->m_xref_y_sb->value();
m_layout.data()->m_xref_text_height = ui->m_xref_height_sb->value();
updateUi(); updateUi();
m_preview_strip_item.update(); m_preview_strip_item.update();
} }
@@ -180,13 +196,17 @@ void TerminalStripLayoutEditor::updateUi()
ui->m_bridge_point_2_sb->setValue(bridge_point[2]); ui->m_bridge_point_2_sb->setValue(bridge_point[2]);
ui->m_bridge_point_3_sb->setValue(bridge_point[3]); ui->m_bridge_point_3_sb->setValue(bridge_point[3]);
const auto font = m_layout->font();
ui->m_font_size_sb->setValue(font.pixelSize());
ui->m_font_cb->setCurrentFont(font);
if (data->m_header_text_orientation == Qt::Horizontal) { if (data->m_header_text_orientation == Qt::Horizontal) {
ui->m_header_text_orientation_cb->setCurrentIndex(0); ui->m_header_text_orientation_cb->setCurrentIndex(0);
} else { } else {
ui->m_header_text_orientation_cb->setCurrentIndex(1); ui->m_header_text_orientation_cb->setCurrentIndex(1);
} }
if (data->m_terminals_text_orientation[0] == Qt::Horizontal) { if (data->m_terminals_text_orientation == Qt::Horizontal) {
ui->m_terminal_text_orientation_cb->setCurrentIndex(0); ui->m_terminal_text_orientation_cb->setCurrentIndex(0);
} else { } else {
ui->m_terminal_text_orientation_cb->setCurrentIndex(1); ui->m_terminal_text_orientation_cb->setCurrentIndex(1);
@@ -201,7 +221,8 @@ void TerminalStripLayoutEditor::updateUi()
ui->m_header_text_alignment_cb->setCurrentIndex(2); ui->m_header_text_alignment_cb->setCurrentIndex(2);
} }
const auto terminal_alignment = data->terminalsTextAlignment().at(0); //Terminal text
const auto terminal_alignment = data->terminalsTextAlignment();
if (terminal_alignment &Qt::AlignLeft) { if (terminal_alignment &Qt::AlignLeft) {
ui->m_terminal_text_alignment_cb->setCurrentIndex(0); ui->m_terminal_text_alignment_cb->setCurrentIndex(0);
} else if (terminal_alignment &Qt::AlignHCenter) { } else if (terminal_alignment &Qt::AlignHCenter) {
@@ -210,6 +231,28 @@ void TerminalStripLayoutEditor::updateUi()
ui->m_terminal_text_alignment_cb->setCurrentIndex(2); ui->m_terminal_text_alignment_cb->setCurrentIndex(2);
} }
ui->m_terminal_text_y_sb->setValue(data->m_terminals_text_y);
ui->m_terminal_text_height_sb->setValue(data->m_terminals_text_height);
//Xref text
if (data->m_xref_text_orientation == Qt::Horizontal) {
ui->m_xref_orientation_cb->setCurrentIndex(0);
} else {
ui->m_xref_orientation_cb->setCurrentIndex(1);
}
const auto xref_alignment = data->xrefTextAlignment();
if (xref_alignment &Qt::AlignLeft) {
ui->m_xref_alignment_cb->setCurrentIndex(0);
} else if (xref_alignment &Qt::AlignHCenter) {
ui->m_xref_alignment_cb->setCurrentIndex(1);
} else if (xref_alignment &Qt::AlignRight) {
ui->m_xref_alignment_cb->setCurrentIndex(2);
}
ui->m_xref_y_sb->setValue(data->m_xref_text_y);
ui->m_xref_height_sb->setValue(data->m_xref_text_height);
m_ui_updating = false; m_ui_updating = false;
updatePreview(); updatePreview();
} }
@@ -225,4 +268,3 @@ void TerminalStripLayoutEditor::on_m_display_preview_help_clicked(bool checked)
m_preview_strip_item.m_drawer.setPreviewDraw(checked); m_preview_strip_item.m_drawer.setPreviewDraw(checked);
m_preview_strip_item.update(); m_preview_strip_item.update();
} }

View File

@@ -76,7 +76,6 @@ class TerminalStripLayoutEditor : public QWidget
private slots: private slots:
void valueEdited(); void valueEdited();
void on_m_display_preview_help_clicked(bool checked); void on_m_display_preview_help_clicked(bool checked);
private: private:

View File

@@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>767</width> <width>961</width>
<height>544</height> <height>624</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@@ -17,17 +17,17 @@
<property name="sizeConstraint"> <property name="sizeConstraint">
<enum>QLayout::SetMaximumSize</enum> <enum>QLayout::SetMaximumSize</enum>
</property> </property>
<item row="4" column="0"> <item row="4" column="2">
<widget class="QLabel" name="label_7"> <widget class="QSpinBox" name="m_width_terminal_0_sb">
<property name="text"> <property name="maximum">
<string>Borne niveau 0 :</string> <number>1000</number>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="6" column="3">
<widget class="QLabel" name="label"> <widget class="QSpinBox" name="m_height_terminal_2_sb">
<property name="text"> <property name="maximum">
<string>En tête :</string> <number>1000</number>
</property> </property>
</widget> </widget>
</item> </item>
@@ -38,37 +38,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="12" column="0" colspan="5">
<widget class="QGraphicsView" name="m_graphics_view"/>
</item>
<item row="3" column="4">
<widget class="QLabel" name="label_18">
<property name="text">
<string>Point de pont</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QSpinBox" name="m_y_terminal_1_sb">
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="8" column="0" colspan="5">
<widget class="Line" name="line_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QSpinBox" name="m_height_spacer_sb">
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="0" column="1"> <item row="0" column="1">
<widget class="QLabel" name="label_3"> <widget class="QLabel" name="label_3">
<property name="text"> <property name="text">
@@ -76,15 +45,43 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="11" column="4"> <item row="7" column="4">
<widget class="QCheckBox" name="m_display_preview_help"> <widget class="QSpinBox" name="m_bridge_point_3_sb">
<property name="text"> <property name="maximum">
<string>Afficher l'aide</string> <number>1000</number>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="2"> <item row="5" column="3">
<widget class="QSpinBox" name="m_width_header_sb"> <widget class="QSpinBox" name="m_height_terminal_1_sb">
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Borne niveau 0 :</string>
</property>
</widget>
</item>
<item row="7" column="2">
<widget class="QSpinBox" name="m_width_terminal_3_sb">
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="6" column="4">
<widget class="QSpinBox" name="m_bridge_point_2_sb">
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QSpinBox" name="m_width_terminal_1_sb">
<property name="maximum"> <property name="maximum">
<number>1000</number> <number>1000</number>
</property> </property>
@@ -97,22 +94,39 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="4"> <item row="14" column="0" colspan="5">
<widget class="QSpinBox" name="m_bridge_point_1_sb"> <widget class="QGraphicsView" name="m_graphics_view"/>
</item>
<item row="2" column="3">
<widget class="QSpinBox" name="m_height_spacer_sb">
<property name="maximum"> <property name="maximum">
<number>1000</number> <number>1000</number>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="2"> <item row="7" column="0">
<widget class="QLabel" name="label_4"> <widget class="QLabel" name="label_10">
<property name="text"> <property name="text">
<string>Largeur</string> <string>Borne niveau 3 :</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="3"> <item row="6" column="0">
<widget class="QSpinBox" name="m_height_terminal_2_sb"> <widget class="QLabel" name="label_9">
<property name="text">
<string>Borne niveau 2 :</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QSpinBox" name="m_width_spacer_sb">
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="4" column="3">
<widget class="QSpinBox" name="m_height_terminal_0_sb">
<property name="maximum"> <property name="maximum">
<number>1000</number> <number>1000</number>
</property> </property>
@@ -125,17 +139,48 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="3"> <item row="13" column="4">
<widget class="QLabel" name="label_5"> <widget class="QCheckBox" name="m_display_preview_help">
<property name="text"> <property name="text">
<string>Hauteur</string> <string>Afficher l'aide</string>
</property>
<property name="checked">
<bool>false</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item row="11" column="0"> <item row="0" column="2">
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="label_4">
<property name="text"> <property name="text">
<string>Prévisualisation :</string> <string>Largeur</string>
</property>
</widget>
</item>
<item row="5" column="4">
<widget class="QSpinBox" name="m_bridge_point_1_sb">
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Espace :</string>
</property>
</widget>
</item>
<item row="11" column="0" colspan="5">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="4" column="4">
<widget class="QSpinBox" name="m_bridge_point_0_sb">
<property name="maximum">
<number>1000</number>
</property> </property>
</widget> </widget>
</item> </item>
@@ -146,35 +191,14 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="1"> <item row="5" column="0">
<widget class="QSpinBox" name="m_y_terminal_3_sb"> <widget class="QLabel" name="label_8">
<property name="maximum"> <property name="text">
<number>1000</number> <string>Borne niveau 1 :</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="1"> <item row="10" column="0" colspan="5">
<widget class="QSpinBox" name="m_y_terminal_0_sb">
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QSpinBox" name="m_width_spacer_sb">
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QSpinBox" name="m_width_terminal_2_sb">
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="9" column="0" colspan="5">
<widget class="QWidget" name="widget" native="true"> <widget class="QWidget" name="widget" native="true">
<layout class="QGridLayout" name="gridLayout_2"> <layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin"> <property name="leftMargin">
@@ -189,26 +213,21 @@
<property name="bottomMargin"> <property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item row="1" column="3"> <item row="5" column="3">
<widget class="QComboBox" name="m_terminal_text_alignment_cb"> <widget class="QComboBox" name="m_header_text_orientation_cb">
<item> <item>
<property name="text"> <property name="text">
<string>Gauche</string> <string>Horizontal</string>
</property> </property>
</item> </item>
<item> <item>
<property name="text"> <property name="text">
<string>Centre</string> <string>Vertical</string>
</property>
</item>
<item>
<property name="text">
<string>Droite</string>
</property> </property>
</item> </item>
</widget> </widget>
</item> </item>
<item row="0" column="3"> <item row="6" column="3">
<widget class="QComboBox" name="m_header_text_alignment_cb"> <widget class="QComboBox" name="m_header_text_alignment_cb">
<item> <item>
<property name="text"> <property name="text">
@@ -227,21 +246,136 @@
</item> </item>
</widget> </widget>
</item> </item>
<item row="0" column="2"> <item row="5" column="2">
<widget class="QLabel" name="label_14">
<property name="text">
<string>Orientation</string>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QLabel" name="label_15"> <widget class="QLabel" name="label_15">
<property name="text"> <property name="text">
<string>Alignement du texte d'en tête :</string> <string>Alignement</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="2"> <item row="1" column="2" colspan="4">
<widget class="QLabel" name="label_17"> <widget class="QWidget" name="widget_2" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_11">
<property name="text"> <property name="text">
<string>Alignement du texte de borne :</string> <string>Police :</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item>
<widget class="QFontComboBox" name="m_font_cb"/>
</item>
<item>
<widget class="QLabel" name="label_12">
<property name="text">
<string>Taille :</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="m_font_size_sb">
<property name="minimum">
<number>1</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="2" column="3">
<widget class="QLabel" name="label_20">
<property name="text">
<string>Texte d'en tête</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="7" column="2">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Origine vertical</string>
</property>
</widget>
</item>
<item row="8" column="2">
<widget class="QLabel" name="label_19">
<property name="text">
<string>Longueur maximal</string>
</property>
</widget>
</item>
<item row="7" column="4">
<widget class="QSpinBox" name="m_terminal_text_y_sb">
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="8" column="4">
<widget class="QSpinBox" name="m_terminal_text_height_sb">
<property name="minimum">
<number>30</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="6" column="4">
<widget class="QComboBox" name="m_terminal_text_alignment_cb">
<item>
<property name="text">
<string>Gauche</string>
</property>
</item>
<item>
<property name="text">
<string>Centre</string>
</property>
</item>
<item>
<property name="text">
<string>Droite</string>
</property>
</item>
</widget>
</item>
<item row="5" column="4">
<widget class="QComboBox" name="m_terminal_text_orientation_cb"> <widget class="QComboBox" name="m_terminal_text_orientation_cb">
<item> <item>
<property name="text"> <property name="text">
@@ -255,8 +389,28 @@
</item> </item>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="2" column="4">
<widget class="QComboBox" name="m_header_text_orientation_cb"> <widget class="QLabel" name="label_21">
<property name="text">
<string>Texte borne</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="2" column="5">
<widget class="QLabel" name="label_22">
<property name="text">
<string>Référence croisée</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="5" column="5">
<widget class="QComboBox" name="m_xref_orientation_cb">
<item> <item>
<property name="text"> <property name="text">
<string>Horizontal</string> <string>Horizontal</string>
@@ -269,23 +423,66 @@
</item> </item>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="6" column="5">
<widget class="QLabel" name="label_16"> <widget class="QComboBox" name="m_xref_alignment_cb">
<item>
<property name="text"> <property name="text">
<string>Orientation du texte de borne :</string> <string>Gauche</string>
</property>
</item>
<item>
<property name="text">
<string>Centre</string>
</property>
</item>
<item>
<property name="text">
<string>Droite</string>
</property>
</item>
</widget>
</item>
<item row="7" column="5">
<widget class="QSpinBox" name="m_xref_y_sb">
<property name="maximum">
<number>1000</number>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="0"> <item row="8" column="5">
<widget class="QLabel" name="label_14"> <widget class="QSpinBox" name="m_xref_height_sb">
<property name="text"> <property name="minimum">
<string>Orientation du texte d'en tête :</string> <number>30</number>
</property>
<property name="maximum">
<number>1000</number>
</property> </property>
</widget> </widget>
</item> </item>
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="6" column="2">
<widget class="QSpinBox" name="m_width_terminal_2_sb">
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QSpinBox" name="m_width_header_sb">
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>En tête :</string>
</property>
</widget>
</item>
<item row="1" column="3"> <item row="1" column="3">
<widget class="QSpinBox" name="m_height_header_sb"> <widget class="QSpinBox" name="m_height_header_sb">
<property name="maximum"> <property name="maximum">
@@ -293,34 +490,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Borne niveau 2 :</string>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QSpinBox" name="m_width_terminal_0_sb">
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Espace :</string>
</property>
</widget>
</item>
<item row="7" column="2">
<widget class="QSpinBox" name="m_width_terminal_3_sb">
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="6" column="1"> <item row="6" column="1">
<widget class="QSpinBox" name="m_y_terminal_2_sb"> <widget class="QSpinBox" name="m_y_terminal_2_sb">
<property name="maximum"> <property name="maximum">
@@ -328,69 +497,55 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="4"> <item row="9" column="0" colspan="5">
<widget class="QSpinBox" name="m_bridge_point_2_sb"> <widget class="Line" name="line_5">
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="7" column="4">
<widget class="QSpinBox" name="m_bridge_point_3_sb">
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QSpinBox" name="m_width_terminal_1_sb">
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="4" column="3">
<widget class="QSpinBox" name="m_height_terminal_0_sb">
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="5" column="3">
<widget class="QSpinBox" name="m_height_terminal_1_sb">
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Borne niveau 3 :</string>
</property>
</widget>
</item>
<item row="4" column="4">
<widget class="QSpinBox" name="m_bridge_point_0_sb">
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Borne niveau 1 :</string>
</property>
</widget>
</item>
<item row="10" column="0" colspan="5">
<widget class="Line" name="line_2">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="1">
<widget class="QSpinBox" name="m_y_terminal_3_sb">
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QSpinBox" name="m_y_terminal_1_sb">
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Hauteur</string>
</property>
</widget>
</item>
<item row="3" column="4">
<widget class="QLabel" name="label_18">
<property name="text">
<string>Point de pont</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QSpinBox" name="m_y_terminal_0_sb">
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="13" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Prévisualisation :</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<resources/> <resources/>
@@ -811,6 +966,134 @@
</hint> </hint>
</hints> </hints>
</connection> </connection>
<connection>
<sender>m_font_cb</sender>
<signal>currentFontChanged(QFont)</signal>
<receiver>TerminalStripLayoutEditor</receiver>
<slot>valueEdited()</slot>
<hints>
<hint type="sourcelabel">
<x>245</x>
<y>276</y>
</hint>
<hint type="destinationlabel">
<x>445</x>
<y>277</y>
</hint>
</hints>
</connection>
<connection>
<sender>m_font_size_sb</sender>
<signal>valueChanged(int)</signal>
<receiver>TerminalStripLayoutEditor</receiver>
<slot>valueEdited()</slot>
<hints>
<hint type="sourcelabel">
<x>507</x>
<y>277</y>
</hint>
<hint type="destinationlabel">
<x>445</x>
<y>277</y>
</hint>
</hints>
</connection>
<connection>
<sender>m_terminal_text_y_sb</sender>
<signal>valueChanged(int)</signal>
<receiver>TerminalStripLayoutEditor</receiver>
<slot>valueEdited()</slot>
<hints>
<hint type="sourcelabel">
<x>207</x>
<y>383</y>
</hint>
<hint type="destinationlabel">
<x>445</x>
<y>277</y>
</hint>
</hints>
</connection>
<connection>
<sender>m_terminal_text_height_sb</sender>
<signal>valueChanged(int)</signal>
<receiver>TerminalStripLayoutEditor</receiver>
<slot>valueEdited()</slot>
<hints>
<hint type="sourcelabel">
<x>430</x>
<y>383</y>
</hint>
<hint type="destinationlabel">
<x>445</x>
<y>277</y>
</hint>
</hints>
</connection>
<connection>
<sender>m_xref_alignment_cb</sender>
<signal>currentIndexChanged(int)</signal>
<receiver>TerminalStripLayoutEditor</receiver>
<slot>valueEdited()</slot>
<hints>
<hint type="sourcelabel">
<x>836</x>
<y>365</y>
</hint>
<hint type="destinationlabel">
<x>480</x>
<y>311</y>
</hint>
</hints>
</connection>
<connection>
<sender>m_xref_height_sb</sender>
<signal>valueChanged(int)</signal>
<receiver>TerminalStripLayoutEditor</receiver>
<slot>valueEdited()</slot>
<hints>
<hint type="sourcelabel">
<x>836</x>
<y>431</y>
</hint>
<hint type="destinationlabel">
<x>480</x>
<y>311</y>
</hint>
</hints>
</connection>
<connection>
<sender>m_xref_orientation_cb</sender>
<signal>currentIndexChanged(int)</signal>
<receiver>TerminalStripLayoutEditor</receiver>
<slot>valueEdited()</slot>
<hints>
<hint type="sourcelabel">
<x>836</x>
<y>333</y>
</hint>
<hint type="destinationlabel">
<x>480</x>
<y>311</y>
</hint>
</hints>
</connection>
<connection>
<sender>m_xref_y_sb</sender>
<signal>valueChanged(int)</signal>
<receiver>TerminalStripLayoutEditor</receiver>
<slot>valueEdited()</slot>
<hints>
<hint type="sourcelabel">
<x>836</x>
<y>398</y>
</hint>
<hint type="destinationlabel">
<x>480</x>
<y>311</y>
</hint>
</hints>
</connection>
</connections> </connections>
<slots> <slots>
<slot>valueEdited()</slot> <slot>valueEdited()</slot>

View File

@@ -30,11 +30,10 @@
TerminalStripTreeDockWidget::TerminalStripTreeDockWidget(QETProject *project, QWidget *parent) : TerminalStripTreeDockWidget::TerminalStripTreeDockWidget(QETProject *project, QWidget *parent) :
QDockWidget(parent), QDockWidget(parent),
ui(new Ui::TerminalStripTreeDockWidget), ui(new Ui::TerminalStripTreeDockWidget)
m_project(project)
{ {
ui->setupUi(this); ui->setupUi(this);
buildTree(); setProject(project);
#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0) #if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
ui->m_tree_view->expandRecursively(ui->m_tree_view->rootIndex()); ui->m_tree_view->expandRecursively(ui->m_tree_view->rootIndex());
@@ -48,6 +47,32 @@ TerminalStripTreeDockWidget::~TerminalStripTreeDockWidget()
delete ui; delete ui;
} }
/**
* @brief TerminalStripTreeDockWidget::setProject
* Set @project as project handled by this tree dock.
* If a previous project was setted, everything is clear.
* This function track the destruction of the project,
* that mean if the project pointer is deleted
* no need to call this function with a nullptr,
* everything is made inside this class.
* @param project
*/
void TerminalStripTreeDockWidget::setProject(QETProject *project)
{
if(m_project && m_project_destroy_connection) {
disconnect(m_project_destroy_connection);
}
m_project = project;
if (m_project) {
m_project_destroy_connection = connect(m_project, &QObject::destroyed, [this](){
this->m_current_strip.clear();
this->reload();
});
}
m_current_strip.clear();
reload();
}
/** /**
* @brief TerminalStripTreeDockWidget::reload * @brief TerminalStripTreeDockWidget::reload
*/ */
@@ -205,6 +230,9 @@ void TerminalStripTreeDockWidget::on_m_tree_view_currentItemChanged(QTreeWidgetI
*/ */
void TerminalStripTreeDockWidget::buildTree() void TerminalStripTreeDockWidget::buildTree()
{ {
if(!m_project) {
return;
}
auto title_ = m_project->title(); auto title_ = m_project->title();
if (title_.isEmpty()) { if (title_.isEmpty()) {

View File

@@ -49,6 +49,7 @@ class TerminalStripTreeDockWidget : public QDockWidget
explicit TerminalStripTreeDockWidget(QETProject *project, QWidget *parent = nullptr); explicit TerminalStripTreeDockWidget(QETProject *project, QWidget *parent = nullptr);
~TerminalStripTreeDockWidget(); ~TerminalStripTreeDockWidget();
void setProject(QETProject *project = nullptr);
void reload(); void reload();
bool currentIsStrip() const; bool currentIsStrip() const;
TerminalStrip* currentStrip() const; TerminalStrip* currentStrip() const;
@@ -74,11 +75,12 @@ class TerminalStripTreeDockWidget : public QDockWidget
QPointer<QETProject> m_project; QPointer<QETProject> m_project;
QPointer<TerminalStrip> m_current_strip; QPointer<TerminalStrip> m_current_strip;
QHash<QTreeWidgetItem *, TerminalStrip *> m_item_strip_H; QHash<QTreeWidgetItem *, QPointer<TerminalStrip>> m_item_strip_H;
QHash<QUuid, QSharedPointer<RealTerminal>> m_uuid_terminal_H; QHash<QUuid, QSharedPointer<RealTerminal>> m_uuid_terminal_H;
QHash<QUuid, QPointer<TerminalStrip>> m_uuid_strip_H; QHash<QUuid, QPointer<TerminalStrip>> m_uuid_strip_H;
QVector<QMetaObject::Connection> m_strip_changed_connection; QVector<QMetaObject::Connection> m_strip_changed_connection;
bool m_current_is_free_terminal{false}; bool m_current_is_free_terminal{false};
QMetaObject::Connection m_project_destroy_connection;
}; };
#endif // TERMINALSTRIPTREEDOCKWIDGET_H #endif // TERMINALSTRIPTREEDOCKWIDGET_H

View File

@@ -59,7 +59,15 @@ DiagramContent::DiagramContent(Diagram *diagram, bool selected) :
{ {
switch (item->type()) switch (item->type())
{ {
case Element::Type: { m_elements << qgraphicsitem_cast<Element *>(item); break;} case Element::Type:
{
auto element = qgraphicsitem_cast<Element *>(item);
m_elements << element;
if (element->elementData().m_type == ElementData::Terminal) {
m_terminal_elements << static_cast<TerminalElement*>(element);
}
break;
}
case IndependentTextItem::Type: { m_text_fields << qgraphicsitem_cast<IndependentTextItem *>(item); break;} case IndependentTextItem::Type: { m_text_fields << qgraphicsitem_cast<IndependentTextItem *>(item); break;}
case Conductor::Type: case Conductor::Type:
{ {

View File

@@ -21,6 +21,8 @@
#include <QSet> #include <QSet>
#include <QVector> #include <QVector>
#include "../qetgraphicsitem/terminalelement.h"
class QGraphicsItem; class QGraphicsItem;
class Conductor; class Conductor;
class Element; class Element;
@@ -81,6 +83,7 @@ class DiagramContent
QList<QGraphicsItem *> m_selected_items; QList<QGraphicsItem *> m_selected_items;
QVector<QetGraphicsTableItem *> m_tables; QVector<QetGraphicsTableItem *> m_tables;
QVector<TerminalStripItem *> m_terminal_strip; QVector<TerminalStripItem *> m_terminal_strip;
QVector<QPointer<TerminalElement>> m_terminal_elements;
QList<DiagramTextItem *> selectedTexts() const; QList<DiagramTextItem *> selectedTexts() const;

View File

@@ -1471,10 +1471,19 @@ void QETDiagramEditor::selectionGroupTriggered(QAction *action)
if (value == "delete_selection") if (value == "delete_selection")
{ {
if (DeleteQGraphicsItemCommand::hasNonDeletableTerminal(dc)) {
QET::QetMessageBox::information(this,
tr("Suppression de borne impossible"),
tr("La suppression ne peut être effectué car la selection "
"possède une ou plusieurs bornes ponté et/ou appartenant à une borne à niveau multiple.\n"
"Déponter et/ou supprimer les niveaux des bornes concerné "
"afin de pouvoir les supprimer"));
} else {
diagram->clearSelection(); diagram->clearSelection();
diagram->undoStack().push(new DeleteQGraphicsItemCommand(diagram, dc)); diagram->undoStack().push(new DeleteQGraphicsItemCommand(diagram, dc));
dv->adjustSceneRect(); dv->adjustSceneRect();
} }
}
else if (value == "rotate_selection") else if (value == "rotate_selection")
{ {
RotateSelectionCommand *c = new RotateSelectionCommand(diagram); RotateSelectionCommand *c = new RotateSelectionCommand(diagram);

View File

@@ -55,6 +55,8 @@ class QETDiagramEditor : public QETMainWindow
{ {
Q_OBJECT Q_OBJECT
friend class TerminalStripEditorWindow;
public: public:
QETDiagramEditor( QETDiagramEditor(
const QStringList & = QStringList(), const QStringList & = QStringList(),

View File

@@ -35,6 +35,7 @@
#include "iostream" #include "iostream"
#include "../qetxml.h" #include "../qetxml.h"
#include "../qetversion.h" #include "../qetversion.h"
#include "qgraphicsitemutility.h"
#include <QDomElement> #include <QDomElement>
#include <utility> #include <utility>
@@ -236,7 +237,7 @@ void Element::paint(
//Draw the selection rectangle //Draw the selection rectangle
if ( isSelected() || m_mouse_over ) { if ( isSelected() || m_mouse_over ) {
drawSelection(painter, options); QGIUtility::drawBoundingRectSelection(this, painter);
} }
} }
@@ -334,34 +335,6 @@ void Element::drawAxes(
/*** Methodes privees ***/ /*** Methodes privees ***/
/**
Dessine le cadre de selection de l'element de maniere systematiquement non antialiasee.
@param painter Le QPainter a utiliser pour dessiner les bornes.
@param options Les options de style a prendre en compte
*/
void Element::drawSelection(
QPainter *painter,
const QStyleOptionGraphicsItem *options)
{
Q_UNUSED(options)
painter -> save();
// Annulation des renderhints
painter -> setRenderHint(QPainter::Antialiasing, false);
painter -> setRenderHint(QPainter::TextAntialiasing, false);
painter -> setRenderHint(QPainter::SmoothPixmapTransform, false);
// Dessin du cadre de selection en gris
QPen t;
t.setColor(Qt::gray);
t.setStyle(Qt::DashDotLine);
t.setCosmetic(true);
painter -> setPen(t);
// Le dessin se fait a partir du rectangle delimitant
painter -> drawRoundedRect(boundingRect().adjusted(1, 1, -1, -1),
10,
10);
painter -> restore();
}
/** /**
Dessine le cadre de selection de l'element de maniere systematiquement non antialiasee. Dessine le cadre de selection de l'element de maniere systematiquement non antialiasee.
@param painter Le QPainter a utiliser pour dessiner les bornes. @param painter Le QPainter a utiliser pour dessiner les bornes.

View File

@@ -198,9 +198,6 @@ class Element : public QetGraphicsItem
void setSize(int, int); void setSize(int, int);
private: private:
void drawSelection(
QPainter *,
const QStyleOptionGraphicsItem *);
void drawHighlight( void drawHighlight(
QPainter *, QPainter *,
const QStyleOptionGraphicsItem *); const QStyleOptionGraphicsItem *);

View File

@@ -24,12 +24,31 @@
Default constructor Default constructor
@param parent : Parent Item @param parent : Parent Item
*/ */
void QetGraphicsItem::showItem(QetGraphicsItem *item)
{
if (item && item->diagram())
{
item->diagram()->showMe();
item->setSelected(true);
//Zoom to the item
for(QGraphicsView *view : item->scene()->views())
{
QRectF fit = item->sceneBoundingRect();
fit.adjust(-200, -200, 200, 200);
view->fitInView(fit, Qt::KeepAspectRatioByExpanding);
}
}
}
QetGraphicsItem::QetGraphicsItem(QGraphicsItem *parent): QetGraphicsItem::QetGraphicsItem(QGraphicsItem *parent):
QGraphicsObject(parent), QGraphicsObject(parent),
is_movable_(true), is_movable_(true),
m_first_move(true), m_first_move(true),
snap_to_grid_(true) snap_to_grid_(true)
{} {
setAcceptHoverEvents(true);
}
QetGraphicsItem::~QetGraphicsItem() QetGraphicsItem::~QetGraphicsItem()
{} {}
@@ -68,6 +87,11 @@ bool QetGraphicsItem::isHovered() const {
return m_hovered; return m_hovered;
} }
QPointF QetGraphicsItem::hoverMousePos() const
{
return m_mouse_hover_pos;
}
/** /**
@brief QetGraphicsItem::state @brief QetGraphicsItem::state
@return the current state of this item @return the current state of this item
@@ -166,6 +190,12 @@ void QetGraphicsItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
QGraphicsObject::hoverEnterEvent(event); QGraphicsObject::hoverEnterEvent(event);
} }
void QetGraphicsItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
{
QGraphicsObject::hoverMoveEvent(event);
m_mouse_hover_pos = event->pos();
}
void QetGraphicsItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) void QetGraphicsItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{ {
m_hovered = false; m_hovered = false;

View File

@@ -28,6 +28,9 @@ class QetGraphicsItem : public QGraphicsObject
{ {
Q_OBJECT Q_OBJECT
public :
static void showItem (QetGraphicsItem *item);
public: public:
//constructor destructor //constructor destructor
QetGraphicsItem(QGraphicsItem *parent = nullptr); QetGraphicsItem(QGraphicsItem *parent = nullptr);
@@ -43,6 +46,7 @@ class QetGraphicsItem : public QGraphicsObject
virtual void setMovable (bool movable) { is_movable_ = movable;} virtual void setMovable (bool movable) { is_movable_ = movable;}
bool isHovered() const; bool isHovered() const;
QPointF hoverMousePos() const;
virtual void editProperty () {} virtual void editProperty () {}
virtual QString name ()const virtual QString name ()const
@@ -57,6 +61,7 @@ class QetGraphicsItem : public QGraphicsObject
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override; void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override; void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
void hoverMoveEvent(QGraphicsSceneHoverEvent *event) override;
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override; void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override;
protected: protected:
@@ -68,6 +73,7 @@ class QetGraphicsItem : public QGraphicsObject
private: private:
bool m_hovered{false}; bool m_hovered{false};
QPointF m_mouse_hover_pos;
}; };

View File

@@ -953,4 +953,93 @@ bool qGraphicsItemPosFromXml(QGraphicsItem *item, const QDomElement &xml_elmt)
return false; return false;
} }
/**
* @brief orientationToAttribute
* Write the Qt::orientation has an attribute of @param element.
* Attribute name is 'orientation' value is 'horizontal' or 'vertical'
* @param orientation
* @param element
*/
void orientationToAttribute(const Qt::Orientation &orientation, QDomElement &element)
{
element.setAttribute(QStringLiteral("orientation"),
orientation == Qt::Horizontal ? QStringLiteral("Horizontal") :
QStringLiteral("Vertical"));
}
/**
* @brief orientationFromAttribute
* @param element
* @param def_value
* @return the Qt::Orientation read in @param element. If an error occur
* the returned orientation is @param def_value.
*/
Qt::Orientation orientationFromAttribute(const QDomElement &element, Qt::Orientation def_value)
{
if (element.hasAttribute(QStringLiteral("orientation"))) {
const auto str {element.attribute(QStringLiteral("orientation"))};
if (str == QLatin1String("Horizontal"))
return Qt::Horizontal;
else if (str == QLatin1String("Vertical"))
return Qt::Vertical;
}
//Error occur during reading, we return the default value
return def_value;
}
void alignmentToAttribute(const Qt::Alignment &alignment, QDomElement &element)
{
QStringList al;
if (alignment &Qt::AlignLeft)
al.append(QStringLiteral("Left"));
if (alignment &Qt::AlignRight)
al.append(QStringLiteral("Right"));
if (alignment &Qt::AlignHCenter)
al.append(QStringLiteral("HCenter"));
if (alignment &Qt::AlignJustify)
al.append(QStringLiteral("Justify"));
if (alignment &Qt::AlignTop)
al.append(QStringLiteral("Top"));
if (alignment &Qt::AlignBottom)
al.append(QStringLiteral("Bottom"));
if (alignment &Qt::AlignBottom)
al.append(QStringLiteral("VCenter"));
if (alignment &Qt::AlignBaseline)
al.append(QStringLiteral("Baseline"));
element.setAttribute(QStringLiteral("alignment"),al.join(QStringLiteral(" ")));
}
/**
* @brief alignmentFromAttribute
* @param element
* @return The alignment read in @param element. If an error
* occured the return Qt::alignment contain no set flag.
*/
Qt::Alignment alignmentFromAttribute(const QDomElement &element)
{
Qt::Alignment al;
if (element.hasAttribute(QStringLiteral("alignment"))) {
const auto alignment {element.attribute(QStringLiteral("alignment"))};
if(alignment.contains(QStringLiteral("Left")))
al = al | Qt::AlignLeft;
if(alignment.contains(QStringLiteral("Right")))
al = al | Qt::AlignRight;
if(alignment.contains(QStringLiteral("HCenter")))
al = al | Qt::AlignHCenter;
if(alignment.contains(QStringLiteral("Justify")))
al = al | Qt::AlignJustify;
if(alignment.contains(QStringLiteral("Top")))
al = al | Qt::AlignTop;
if(alignment.contains(QStringLiteral("Bottom")))
al = al | Qt::AlignBottom;
if(alignment.contains(QStringLiteral("VCenter")))
al = al | Qt::AlignVCenter;
if(alignment.contains(QStringLiteral("Baseline")))
al = al | Qt::AlignBaseline;
}
return al;
}
} }

View File

@@ -94,6 +94,12 @@ namespace QETXML
QDomElement qGraphicsItemPosToXml(QGraphicsItem *item, QDomDocument &document); QDomElement qGraphicsItemPosToXml(QGraphicsItem *item, QDomDocument &document);
bool qGraphicsItemPosFromXml(QGraphicsItem *item, const QDomElement &xml_elmt); bool qGraphicsItemPosFromXml(QGraphicsItem *item, const QDomElement &xml_elmt);
void orientationToAttribute(const Qt::Orientation &orientation, QDomElement &element);
Qt::Orientation orientationFromAttribute(const QDomElement &element, Qt::Orientation def_value = Qt::Vertical);
void alignmentToAttribute(const Qt::Alignment &alignment, QDomElement &element);
Qt::Alignment alignmentFromAttribute (const QDomElement &element);
QString boolToString(bool value); QString boolToString(bool value);
bool boolFromString(const QString &value, bool boolFromString(const QString &value,
bool default_value = true, bool default_value = true,

151
sources/svg/qetsvg.cpp Normal file
View File

@@ -0,0 +1,151 @@
/*
Copyright 2006-2025 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 "qetsvg.h"
#include <QDomDocument>
#include <QRect>
#include <../qet.h>
/**
* @brief QETSVG::rectToElmt
* Write a QRect as a svg rect element.
* @param rect
* @param parent_document
* @return
*/
QDomElement QETSVG::rectToElmt(const QRectF &rect, QDomDocument &parent_document)
{
auto dom_element = parent_document.createElement(QStringLiteral("rect"));
if (!rect.isNull()) {
dom_element.setAttribute(QStringLiteral("x"), rect.x());
yToAttribute(rect.y(), dom_element);
dom_element.setAttribute(QStringLiteral("width"), rect.width());
heightToAttribute(rect.height(), dom_element);
}
return dom_element;
}
/**
* @brief QETSVG::rectFromElmt
* @param xml_element : xml_element of an svg rect.
* The tag name must be 'rect' if not, the returned QRect is null.
* @return a svg rect to QRect
*/
QRectF QETSVG::rectFromElmt(const QDomElement &xml_element)
{
QRectF rect_;
if (xml_element.tagName() == QLatin1String("rect")) {
rect_.setRect(xml_element.attribute(QStringLiteral("x"), QStringLiteral("0")).toDouble(),
yFromAttribute(xml_element, 0),
xml_element.attribute(QStringLiteral("width"), QStringLiteral("10")).toDouble(),
heightFromAttribute(xml_element, 10));
}
return rect_;
}
/**
* @brief QETSVG::yToAttribute
* @param y
* @param xml_element
*/
void QETSVG::yToAttribute(const qreal &y, QDomElement &xml_element) {
xml_element.setAttribute(QStringLiteral("y"), QString::number(y));
}
/**
* @brief QETSVG::yFromAttribute
* @param xml_element
* @param def_value
* @return
*/
qreal QETSVG::yFromAttribute(const QDomElement &xml_element, const qreal &def_value) {
qreal value_;
if (QET::attributeIsAReal(xml_element, QStringLiteral("y"), &value_)) {
return value_;
}
return def_value;
}
/**
* @brief QETSVG::heightToAttribute
* @param height
* @param xml_element
*/
void QETSVG::heightToAttribute(const qreal &height, QDomElement &xml_element) {
xml_element.setAttribute(QStringLiteral("height"), QString::number(height));
}
qreal QETSVG::heightFromAttribute(const QDomElement &xml_element, const qreal &def_value) {
qreal value_;
if (QET::attributeIsAReal(xml_element, QStringLiteral("height"), &value_)) {
return value_;
}
return def_value;
}
void QETSVG::rToAttribute(const qreal &r, QDomElement &xml_element) {
xml_element.setAttribute(QStringLiteral("r"), QString::number(r));
}
qreal QETSVG::rFromAttribute(const QDomElement &xml_element, const qreal &def_value) {
qreal value_;
if (QET::attributeIsAReal(xml_element, QStringLiteral("r"), &value_)) {
return value_;
}
return def_value;
}
void QETSVG::pointsToAttribute(const QVector<QPointF> &points, QDomElement &xml_element)
{
QStringList strl_;
for (const auto &point : points) {
strl_.append(QString::number(point.x()) +
QString(",") +
QString::number(point.y()));
}
xml_element.setAttribute(QStringLiteral("points"), strl_.join(" "));
}
/**
* @brief QETSVG::pointsFromAttribute
* @param xml_element
* @return a vector of points stored in attribute 'points' of @xml_element.
* The returned vector can be empty.
*/
QVector<QPointF> QETSVG::pointsFromAttribute(const QDomElement &xml_element)
{
QVector<QPointF> vector_;
if (const auto string_points = xml_element.attribute(QStringLiteral("points")).split(QStringLiteral(" ")) ;
!string_points.isEmpty()) {
bool x_ok, y_ok; for (const auto &point : string_points) {
const auto string_x_y = point.split(QStringLiteral(","));
if (string_x_y.size() == 2) {
const auto x = string_x_y[0].toDouble(&x_ok);
const auto y = string_x_y[1].toDouble(&y_ok);
if (x_ok && y_ok) {
vector_.append(QPointF{x,y});
}
}
}
}
return vector_;
}

51
sources/svg/qetsvg.h Normal file
View File

@@ -0,0 +1,51 @@
/*
Copyright 2006-2025 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 QETSVG_H
#define QETSVG_H
#include <QDomElement>
class QDomDocument;
class QPointF;
class QRectF;
/**
* @namespace QETSVG
* @brief the QETSVG namespace provide function read and write svg.
* Some function work on xml element (ex rect) and some other
* work on attribute of an element (ex x)
*/
namespace QETSVG
{
QDomElement rectToElmt(const QRectF &rect, QDomDocument &parent_document);
QRectF rectFromElmt(const QDomElement &xml_element);
void yToAttribute(const qreal &y, QDomElement &xml_element);
qreal yFromAttribute(const QDomElement &xml_element, const qreal &def_value=0);
void heightToAttribute(const qreal &height, QDomElement &xml_element);
qreal heightFromAttribute(const QDomElement &xml_element, const qreal &def_value=10);
void rToAttribute(const qreal &r, QDomElement &xml_element);
qreal rFromAttribute(const QDomElement &xml_element, const qreal &def_value=1);
void pointsToAttribute(const QVector<QPointF> &points, QDomElement &xml_element);
QVector<QPointF> pointsFromAttribute (const QDomElement &xml_element);
}
#endif // QETSVG_H

View File

@@ -28,6 +28,8 @@
#include "../qetgraphicsitem/elementtextitemgroup.h" #include "../qetgraphicsitem/elementtextitemgroup.h"
#include "../qetgraphicsitem/terminal.h" #include "../qetgraphicsitem/terminal.h"
#include "addelementtextcommand.h" #include "addelementtextcommand.h"
#include "../TerminalStrip/realterminal.h"
#include "../TerminalStrip/physicalterminal.h"
/** /**
@brief DeleteQGraphicsItemCommand::DeleteQGraphicsItemCommand @brief DeleteQGraphicsItemCommand::DeleteQGraphicsItemCommand
@@ -115,6 +117,36 @@ DeleteQGraphicsItemCommand::~DeleteQGraphicsItemCommand()
m_diagram->qgiManager().release(m_removed_contents.items(DiagramContent::All)); m_diagram->qgiManager().release(m_removed_contents.items(DiagramContent::All));
} }
/**
* @brief DeleteQGraphicsItemCommand::hasNonDeletableTerminal
* Return true if @content have terminal element which can't be deleted.
* The reason why a terminal can't be deleted is because they have bridge
* or belong to a physical terminal with more than one level.
* @param diagram
* @param content
* @param dialog
* @return
*/
bool DeleteQGraphicsItemCommand::hasNonDeletableTerminal(const DiagramContent &content)
{
if (!content.m_terminal_elements.isEmpty())
{
for (const auto &terminal : content.m_terminal_elements)
{
if (!terminal.isNull())
{
if (terminal->parentTerminalStrip()
&& (terminal->realTerminal()->isBridged()
|| terminal->realTerminal()->physicalTerminal()->levelCount() != 1)) {
return true;
}
}
}
}
return false;
}
/** /**
@brief DeleteQGraphicsItemCommand::setPotentialsOfRemovedElements @brief DeleteQGraphicsItemCommand::setPotentialsOfRemovedElements
This function creates new conductors (if needed) for conserve the electrical potentials This function creates new conductors (if needed) for conserve the electrical potentials

View File

@@ -34,10 +34,10 @@ class DeleteQGraphicsItemCommand : public QUndoCommand
public: public:
DeleteQGraphicsItemCommand(Diagram *diagram, const DiagramContent &content, QUndoCommand * parent = nullptr); DeleteQGraphicsItemCommand(Diagram *diagram, const DiagramContent &content, QUndoCommand * parent = nullptr);
~DeleteQGraphicsItemCommand() override; ~DeleteQGraphicsItemCommand() override;
static bool hasNonDeletableTerminal(const DiagramContent &content);
private: private:
DeleteQGraphicsItemCommand(const DeleteQGraphicsItemCommand &); DeleteQGraphicsItemCommand(const DeleteQGraphicsItemCommand &);
void setPotentialsOfRemovedElements(); void setPotentialsOfRemovedElements();
Terminal *terminalInSamePotential(Terminal *terminal, Conductor *conductor_to_exclude); Terminal *terminalInSamePotential(Terminal *terminal, Conductor *conductor_to_exclude);

View File

@@ -132,3 +132,21 @@ bool QETUtils::sortBeginIntString(const QString &str_a, const QString &str_b)
return str_a<str_b; return str_a<str_b;
} }
} }
/**
* @brief QETUtils::pixelSizedFont
* Set the font size to pixelSize instead of pointSize (if needed).
* The font used to draw diagram must be pixel sized instead of point sized (default by Qt)
* then no matter the screen dpi used, the text in diagram keep the same size.
* For more information see @link https://qelectrotech.org/forum/viewtopic.php?pid=6267#p6267 @endlink
* @param font
*/
void QETUtils::pixelSizedFont(QFont &font)
{
if (font.pixelSize() > -1) {
return;
}
auto px = font.pointSizeF()/72 * QFontMetrics{font}.fontDpi();
font.setPixelSize(qRound(px));
}

View File

@@ -31,6 +31,7 @@ namespace QETUtils
QString marginsToString(const QMargins &margins); QString marginsToString(const QMargins &margins);
QMargins marginsFromString(const QString &string); QMargins marginsFromString(const QString &string);
qreal graphicsHandlerSize(QGraphicsItem *item); qreal graphicsHandlerSize(QGraphicsItem *item);
void pixelSizedFont (QFont &font);
bool sortBeginIntString(const QString &str_a, const QString &str_b); bool sortBeginIntString(const QString &str_a, const QString &str_b);

View File

@@ -0,0 +1,206 @@
/*
Copyright 2006-2025 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 "terminalstriplayoutpatternxml.h"
#include "../TerminalStrip/GraphicsItem/properties/terminalstriplayoutpattern.h"
#include "../qetxml.h"
#include "../svg/qetsvg.h"
const QString LAYOUT_PATTERN_TAG_NAME { QStringLiteral("terminal_strip_layout_pattern") };
const QString LAYOUTS_PATTERN_TAG_NAME { QStringLiteral("terminal_strip_layouts_pattern") };
/**
* @brief TerminalStripLayoutPatternXml::toXml
* Save a vector of @class TerminalStripLayoutPattern into main xml element
* with tagg name 'terminal_strip_layouts_pattern' who itself embedded each single @class TerminalStripLayoutPattern
* into a xml element with tag name 'terminal_strip_layout_pattern' (layout without 'S' at the end)
* @param patterns
* @param document
* @return
*/
QDomElement TerminalStripLayoutPatternXml::toXml(const QVector<QSharedPointer<TerminalStripLayoutPattern> > &patterns,
QDomDocument &document)
{
auto dom_element = document.createElement(LAYOUTS_PATTERN_TAG_NAME);
for (const auto &pattern : patterns)
{
const auto child_ = toXml(pattern, document);
if (!child_.isNull()) {
dom_element.appendChild(child_);
}
}
return dom_element;
}
/**
* @brief TerminalStripLayoutPatternXml::fromXml
* Load a vector of @class TerminalStripLayoutPattern from a main xml element
* with tagg name 'terminal_strip_layouts_pattern' who itself have several child
* with tag name 'terminal_strip_layout_pattern' (layout without 'S' at the end) for every
* @class TerminalStripLayoutPattern to load
* @param element
* @return
*/
QVector<QSharedPointer<TerminalStripLayoutPattern> > TerminalStripLayoutPatternXml::fromXml(const QDomElement &element)
{
QVector <QSharedPointer<TerminalStripLayoutPattern>> returned_vector;
for (const auto &dom_elmt : QETXML::subChild(element,
LAYOUTS_PATTERN_TAG_NAME,
LAYOUT_PATTERN_TAG_NAME))
{
auto layout_pattern = QSharedPointer<TerminalStripLayoutPattern>::create();
fromXml(layout_pattern, dom_elmt);
returned_vector << layout_pattern;
}
return returned_vector;
}
/**
* @brief TerminalStripLayoutPatternXml::toXml
* Save a @class TerminalStripLayoutPattern to a xml element with tag name terminal_strip_layout_pattern
* @param pattern
* @param document
* @return
*/
QDomElement TerminalStripLayoutPatternXml::toXml(const QSharedPointer<TerminalStripLayoutPattern> &pattern, QDomDocument &document)
{
auto pattern_xml = document.createElement(LAYOUT_PATTERN_TAG_NAME);
if (!pattern.isNull()) {
//Write strip pattern attributes
pattern_xml.setAttribute(QStringLiteral("name"), pattern->m_name);
pattern_xml.setAttribute(QStringLiteral("uuid"), pattern->m_uuid.toString());
//Write header properties
auto header_xml = document.createElement(QStringLiteral("header"));
header_xml.appendChild(QETSVG::rectToElmt(pattern->m_header_rect, document));
auto header_text_xml = document.createElement(QStringLiteral("text"));
QETXML::orientationToAttribute(pattern->m_header_text_orientation, header_text_xml);
QETXML::alignmentToAttribute(pattern->headerTextAlignment(),header_text_xml);
//Write spacer properties
auto spacer_xml = document.createElement(QStringLiteral("spacer"));
spacer_xml.appendChild(QETSVG::rectToElmt(pattern->m_spacer_rect, document));
pattern_xml.appendChild(header_xml).appendChild(header_text_xml);
pattern_xml.appendChild(spacer_xml);
//Write terminals properties
auto terminals_xml = document.createElement(QStringLiteral("terminals"));
for (const auto &rect : pattern->m_terminal_rect) {
terminals_xml.appendChild(QETSVG::rectToElmt(rect, document));
}
auto terminals_text_xml = document.createElement(QStringLiteral("text"));
QETXML::orientationToAttribute(pattern->m_terminals_text_orientation, terminals_text_xml);
QETXML::alignmentToAttribute(pattern->terminalsTextAlignment(),terminals_text_xml);
QETSVG::yToAttribute(pattern->m_terminals_text_y, terminals_text_xml);
QETSVG::heightToAttribute(pattern->m_terminals_text_height, terminals_text_xml);
terminals_xml.appendChild(terminals_text_xml);
auto xref_text_xml = document.createElement(QStringLiteral("xref"));
QETXML::orientationToAttribute(pattern->m_xref_text_orientation, xref_text_xml);
QETXML::alignmentToAttribute(pattern->xrefTextAlignment(),xref_text_xml);
QETSVG::yToAttribute(pattern->m_xref_text_y, xref_text_xml);
QETSVG::heightToAttribute(pattern->m_xref_text_height, xref_text_xml);
terminals_xml.appendChild(xref_text_xml);
auto bridge_xml = document.createElement(QStringLiteral("bridges"));
QETSVG::rToAttribute(pattern->m_bridge_point_d/2, bridge_xml);
QVector<QPointF> points_vector;
for (const auto &y : pattern->m_bridge_point_y_offset) {
points_vector.append(QPointF{0,y});
}
QETSVG::pointsToAttribute(points_vector, bridge_xml);
terminals_xml.appendChild(bridge_xml);
pattern_xml.appendChild(terminals_xml);
}
return pattern_xml;
}
/**
* @brief TerminalStripLayoutPatternXml::fromXml
* LOad a @class TerminalStripLayoutPattern from a xml element with tag name terminal_strip_layout_pattern
* @param layout
* @param element
*/
void TerminalStripLayoutPatternXml::fromXml(QSharedPointer<TerminalStripLayoutPattern> &layout, const QDomElement &element)
{
if (element.tagName() != LAYOUT_PATTERN_TAG_NAME) return;
layout->m_name = element.attribute(QStringLiteral("name"), layout->m_name);
layout->m_uuid.fromString(element.attribute(QStringLiteral("uuid"), layout->m_uuid.toString()));
const auto header_xml = element.firstChildElement(QStringLiteral("header"));
if (!header_xml.isNull() && header_xml.hasAttribute(QStringLiteral("rect"))) {
layout->m_header_rect = QETSVG::rectFromElmt(header_xml);
}
if (const auto header_text_xml = header_xml.firstChildElement(QStringLiteral("text"));
!header_text_xml.isNull()) {
layout->m_header_text_orientation = QETXML::orientationFromAttribute(header_text_xml, layout->m_header_text_orientation);
layout->setHeaderTextAlignment(QETXML::alignmentFromAttribute(header_text_xml));
}
const auto spacer_xml = element.firstChildElement(QStringLiteral("spacer"));
if (const auto rect = QETSVG::rectFromElmt(spacer_xml);
!rect.isNull()) {
layout->m_spacer_rect = rect;
}
if (const auto terminals_xml = element.firstChildElement(QStringLiteral("terminals"));
!terminals_xml.isNull()) {
layout->m_terminal_rect.clear();
for (const auto &terminal_rect_xml : QETXML::directChild(terminals_xml, QStringLiteral("rect"))) {
layout->m_terminal_rect.append(QETSVG::rectFromElmt(terminal_rect_xml)) ;
}
if (const auto terminals_text_xml = terminals_xml.firstChildElement(QStringLiteral("text"));
!terminals_text_xml.isNull()) {
layout->m_terminals_text_orientation = QETXML::orientationFromAttribute(terminals_text_xml, layout->m_terminals_text_orientation);
layout->setTerminalsTextAlignment(QETXML::alignmentFromAttribute(terminals_text_xml));
layout->m_terminals_text_y = QETSVG::yFromAttribute(terminals_text_xml);
layout->m_terminals_text_height = QETSVG::heightFromAttribute(terminals_text_xml);
}
if (const auto xref_text_xml = terminals_xml.firstChildElement(QStringLiteral("xref"));
!xref_text_xml.isNull()) {
layout->m_xref_text_orientation = QETXML::orientationFromAttribute(xref_text_xml, layout->m_xref_text_orientation);
layout->setXrefTextAlignment(QETXML::alignmentFromAttribute(xref_text_xml));
layout->m_xref_text_y = QETSVG::yFromAttribute(xref_text_xml);
layout->m_xref_text_height = QETSVG::heightFromAttribute(xref_text_xml);
}
if (const auto bridge_xml = terminals_xml.firstChildElement(QStringLiteral("bridges"));
!bridge_xml.isNull()) {
layout->m_bridge_point_d = QETSVG::rFromAttribute(bridge_xml, 2.5)*2;
if (const auto points = QETSVG::pointsFromAttribute(bridge_xml);
points.size() == 4) {
layout->m_bridge_point_y_offset[0]= points[0].y();
layout->m_bridge_point_y_offset[1]= points[1].y();
layout->m_bridge_point_y_offset[2]= points[2].y();
layout->m_bridge_point_y_offset[3]= points[3].y();
}
}
}
}

View File

@@ -0,0 +1,41 @@
/*
Copyright 2006-2025 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 TERMINALSTRIPLAYOUTPATTERNXML_H
#define TERMINALSTRIPLAYOUTPATTERNXML_H
#include <QDomElement>
#include <QSharedPointer>
class TerminalStripLayoutPattern;
/**
* @brief The TerminalStripLayoutPatternXml class
* A class with static function used to save/restor a
* @class TerminalStripLayoutPattern to xml
*/
class TerminalStripLayoutPatternXml
{
public:
static QDomElement toXml(const QVector<QSharedPointer<TerminalStripLayoutPattern>> &patterns, QDomDocument &document);
static QVector<QSharedPointer<TerminalStripLayoutPattern>> fromXml(const QDomElement &element);
static QDomElement toXml (const QSharedPointer<TerminalStripLayoutPattern> &pattern, QDomDocument &document);
static void fromXml(QSharedPointer<TerminalStripLayoutPattern> &layout, const QDomElement &element);
};
#endif // TERMINALSTRIPLAYOUTPATTERNXML_H