Compare commits

...

16 Commits

Author SHA1 Message Date
joshua
f83a5b3a79 Merge branch 'terminal_strip' 2025-10-15 23:30:54 +02:00
joshua
7e5d41b474 Terminal strip Xref is clickable
When user hover the Xref string of a terminal, the string color change
to blue to advise user the xref is clickable. Double click on the blue
Xref go the folio of the terminal and zoom the view to the terminal.
2025-10-14 22:12:38 +02:00
joshua
f0ec416a91 Terminal strip graphic item can display Xref of terminal 2025-10-03 21:49:21 +02:00
joshua
f6ba47277d Minor : revamp
Use QGIUtility::drawBoundingRectSelection for draw the selection rect
of element instead of a method of the element itself.
Less code.
2025-10-02 21:52:40 +02:00
joshua
74b55f3bf5 Disable deletion if a terminal can't be deleted.
In case of user try to delete a terminal element who is bridged
or belong to a physical terminal with more than one level, the deletion
is aborted to avoid mistake in the terminal strip parent of the terminal
element. A dialog is opened when the deletion can't be to explain to
user what to do for enable the deletion.
2025-07-24 22:24:15 +02:00
joshua
a121fbe530 Add undo / redo command
The undo/redo command of diagram editor is
shared to the terminal strip editor.
2025-07-01 23:37:16 +02:00
joshua
a2ae8255ac Minor fix
During the development, we saved some terminal strip with "phantom"
terminal (terminal added to the strip and after the terminal was removed
from the project but keep in the terminal strip data) and this mistake
was saved in the xml. When we open this project the phantom terminal
don't appear in the layout but the empty physical terminal is still here
in the terminal strip data because the position of the terminals in the
strip is wrong (sometime bigger than the size of the strip, sometime
with a gap, sometime don't start at 0). This commit fix this mistake
when we open a project.
2025-07-01 22:46:18 +02:00
joshua
d711d8fb4a Terminal strip editor can now edit multiple project.
Before this this commit the terminal strip editor couldn't only work on
the first project opened into this editor, all other project opened
after couldn't be edited.
This is now past, terminal strip editor can now edit every project open
in QElectroTech.
2025-06-11 22:43:41 +02:00
joshua
3a6b4807db Fix crash.
Fix crash when :
1°-Open a project with terminal strip and open the terminal strip editor
2°-Close the terminal strip editor and the project (keep qelectrotech
open).
3°-redo step 1 and click on an item in the tree at left of the window,
qet crash.

Qet don't crash anymore but the terminal strip editor continue to work
with the terminal strip of the first opening (exactly the pointer of the
terminal strip) who don't exist anymore. Need more work.
2025-06-09 21:35:00 +02:00
joshua
d699faf501 Change some int to qreal
Made this change to be more compliant with svg
2025-06-08 21:40:32 +02:00
joshua
95e401a266 Class TerminalStripLayoutPattern can be save/load from xml
Add a new class TerminalStripLayoutPatternXml used to
save / load a TerminalStripLayoutPattern class into a xml.

Also create the namespace QETSVG used to read/write some
svg element / attribute to xml. This class is used by the
class TerminalStripLayoutPatternXml.
2025-06-05 23:04:56 +02:00
joshua
2c1b840f9c Use same properties for every terminal level
Initially it was planned to have separate text configuration for every
terminal level. It's not useful, use same properties for every level is
sufficient and visually more consistent.
By consequent every QVector related to these properties was replaced by
a single value.
2025-03-12 21:48:18 +01:00
joshua
2d89d70682 Add possibility to adjust terminal text position
The bounding rectangle used to define the position of the terminal text
can be edited. The y position and height can now be edited. The width is
not editable because is always the width of the rectangle of the of the
terminal.
2025-03-12 21:10:16 +01:00
joshua
7747223dfa Terminal strip item font is editable
The font used in the terminal strip item can be edited
trough the terminal strip layout editor widget
2025-03-12 19:22:30 +01:00
joshua
ae5e188866 Add converter for dpi to pixel font size
Add a little function used to convert if needed the size of a font set
in dpi to pixel. Because the conversion from pdi to pixel can't
be exactly identical, the text size in the diagram can be a little
different, in the other side the switch between screens with different
dpi is no more a problem.
2025-03-12 19:14:45 +01:00
joshua
4ca0bbf682 Minor
Add more help line for the preview of terminal strip configurator
2024-11-07 18:48:53 +01: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/xml/*.h) \
$$files(sources/dxf/*.h) \
$$files(sources/qet_elementscaler/*.h)
$$files(sources/qet_elementscaler/*.h) \
$$files(sources/svg/*.h)
SOURCES += $$files(sources/*.cpp) \
$$files(sources/editor/*.cpp) \
@@ -213,7 +214,8 @@ SOURCES += $$files(sources/*.cpp) \
$$files(sources/TerminalStrip/GraphicsItem/properties/*.cpp) \
$$files(sources/xml/*.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
INCLUDEPATH += sources/TerminalStrip/ui

View File

@@ -35,13 +35,14 @@ namespace TerminalStripDrawer
const QUuid m_uuid;
};
class DemoRealTerminal : public AbstractRealTerminalInterface
{
public:
DemoRealTerminal(const QString &label, const QUuid &bridge) :
class DemoRealTerminal : public AbstractRealTerminalInterface
{
public:
DemoRealTerminal(const QString &label, const QString &xref, const QUuid &bridge) :
m_label { label },
m_xref{ xref },
m_bridge { bridge }
{}
{}
QString label() const override {
return m_label;
@@ -55,10 +56,14 @@ namespace TerminalStripDrawer
return new DemoBridge { m_bridge };
}
private:
QString m_label;
QUuid m_bridge;
};
QString xref() const override {
return m_xref;
}
private:
QString m_label, m_xref;
QUuid m_bridge;
};
class DemoPhysicalTerminal : public AbstractPhysicalTerminalInterface
{
@@ -102,51 +107,63 @@ namespace TerminalStripDrawer
QVector <QSharedPointer<AbstractRealTerminalInterface>> real_terminals_vector;
real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> {
new DemoRealTerminal( QStringLiteral("24vdc"),
lvl_1)};
new DemoRealTerminal( QStringLiteral("24vdc"),
QStringLiteral("1_A1"),
lvl_1)};
real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> {
new DemoRealTerminal( QStringLiteral("0vdc"),
lvl_2)};
new DemoRealTerminal( QStringLiteral("0vdc"),
QStringLiteral("1_A2"),
lvl_2)};
real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> {
new DemoRealTerminal( QStringLiteral("signal"),
lvl_3)};
new DemoRealTerminal( QStringLiteral("signal"),
QStringLiteral("1_A3"),
lvl_3)};
real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> {
new DemoRealTerminal( QStringLiteral("teach"),
lvl_4)};
new DemoRealTerminal( QStringLiteral("teach"),
QStringLiteral("1_A4"),
lvl_4)};
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> {
new DemoRealTerminal( QStringLiteral("24vdc"),
lvl_1)};
new DemoRealTerminal( QStringLiteral("24vdc"),
QStringLiteral("2_A1"),
lvl_1)};
real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> {
new DemoRealTerminal( QStringLiteral("0vdc"),
lvl_2)};
new DemoRealTerminal( QStringLiteral("0vdc"),
QStringLiteral("2_A2"),
lvl_2)};
real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> {
new DemoRealTerminal( QStringLiteral("signal"),
lvl_3)};
new DemoRealTerminal( QStringLiteral("signal"),
QStringLiteral("2_A3"),
lvl_3)};
real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> {
new DemoRealTerminal( QStringLiteral("teach"),
lvl_4)};
new DemoRealTerminal( QStringLiteral("teach"),
QStringLiteral("2_A4"),
lvl_4)};
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> {
new DemoRealTerminal( QStringLiteral("24vdc"),
lvl_1)};
new DemoRealTerminal( QStringLiteral("24vdc"),
QStringLiteral("3_A1"),
lvl_1)};
real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> {
new DemoRealTerminal( QStringLiteral("0vdc"),
lvl_2)};
new DemoRealTerminal( QStringLiteral("0vdc"),
QStringLiteral("3_A2"),
lvl_2)};
real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> {
new DemoRealTerminal( QStringLiteral("signal"),
lvl_3)};
new DemoRealTerminal( QStringLiteral("signal"),
QStringLiteral("3_A3"),
lvl_3)};
real_terminals_vector << QSharedPointer<AbstractRealTerminalInterface> {
new DemoRealTerminal( QStringLiteral("teach"),
lvl_4)};
new DemoRealTerminal( QStringLiteral("teach"),
QStringLiteral("3_A4"),
lvl_4)};
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/>.
*/
#include "terminalstriplayoutpattern.h"
#include <QDebug>
#include "../../../utils/qetutils.h"
TerminalStripLayoutPattern::TerminalStripLayoutPattern()
{
m_font.setPixelSize(15);
updateHeaderTextOption();
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)
{
if (!alignment) return;
m_header_text_alignment = alignment;
updateHeaderTextOption();
}
@@ -39,22 +47,61 @@ QTextOption TerminalStripLayoutPattern::headerTextOption() const {
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;
updateTerminalsTextOption();
}
QVector<Qt::Alignment> TerminalStripLayoutPattern::terminalsTextAlignment() const
Qt::Alignment TerminalStripLayoutPattern::terminalsTextAlignment() const
{
return m_terminals_text_alignment;
}
QVector<QTextOption> TerminalStripLayoutPattern::terminalsTextOption() const
QTextOption TerminalStripLayoutPattern::terminalsTextOption() const
{
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()
{
m_header_text_option.setAlignment(m_header_text_alignment);
@@ -63,16 +110,9 @@ void TerminalStripLayoutPattern::updateHeaderTextOption()
void TerminalStripLayoutPattern::updateTerminalsTextOption()
{
if (m_terminals_text_option.size() ==
m_terminals_text_alignment.size())
{
for (auto i = 0 ; i<m_terminals_text_option.size() ; ++i)
{
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";
}
m_terminals_text_option.setAlignment(m_terminals_text_alignment);
m_terminals_text_option.setWrapMode(QTextOption::WordWrap);
m_xref_text_option.setAlignment(m_xref_text_alignment);
m_xref_text_option.setWrapMode(QTextOption::WordWrap);
}

View File

@@ -18,6 +18,7 @@
#ifndef TERMINALSTRIPLAYOUTPATTERN_H
#define TERMINALSTRIPLAYOUTPATTERN_H
#include <QFont>
#include <QRect>
#include <QSize>
#include <QTextOption>
@@ -43,45 +44,46 @@ class TerminalStripLayoutPattern
TerminalStripLayoutPattern();
//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};
void setHeaderTextAlignment(const Qt::Alignment &alignment);
Qt::Alignment headerTextAlignment() const;
QTextOption headerTextOption() const;
//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
QVector<QRect> m_terminal_rect
QVector<QRectF> m_terminal_rect
{
QRect{0, 0, 20, 190},
QRect{0, 10, 20, 170},
QRect{0, 20, 20, 150},
QRect{0, 30, 20, 130}
QRectF{0, 0, 20, 190},
QRectF{0, 10, 20, 170},
QRectF{0, 20, 20, 150},
QRectF{0, 30, 20, 130}
};
void setTerminalsTextAlignment(const QVector<Qt::Alignment> &alignment);
QVector<Qt::Alignment> terminalsTextAlignment() const;
QVector<QTextOption> terminalsTextOption() const;
//Terminal text
void setTerminalsTextAlignment(const Qt::Alignment &alignment);
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
{
QRect{0,35,20,50},
QRect{0,35,20,50},
QRect{0,35,20,50},
QRect{0,35,20,50}
};
QVector<Qt::Orientation> m_terminals_text_orientation
{
Qt::Vertical,
Qt::Vertical,
Qt::Vertical,
Qt::Vertical
};
//Xref text
void setXrefTextAlignment(const Qt::Alignment &alignment);
Qt::Alignment xrefTextAlignment() const;
QTextOption xrefTextOption() const;
qreal m_xref_text_height{60};
qreal m_xref_text_y{95};
Qt::Orientation m_xref_text_orientation {Qt::Vertical};
int m_bridge_point_d{5};
QVector<int> m_bridge_point_y_offset{50,70,90,110};
qreal m_bridge_point_d{5};
QVector<qreal> m_bridge_point_y_offset{50,70,90,110};
QUuid m_uuid{QUuid::createUuid()};
QString m_name;
@@ -90,24 +92,17 @@ class TerminalStripLayoutPattern
void updateHeaderTextOption();
void updateTerminalsTextOption();
private:
private:
QFont m_font;
Qt::Alignment m_header_text_alignment{Qt::AlignCenter};
QTextOption m_header_text_option;
QVector<Qt::Alignment> m_terminals_text_alignment
{
Qt::AlignRight | Qt::AlignVCenter,
Qt::AlignRight | Qt::AlignVCenter,
Qt::AlignRight | Qt::AlignVCenter,
Qt::AlignRight | Qt::AlignVCenter
};
QVector<QTextOption> m_terminals_text_option
{
QTextOption(),
QTextOption(),
QTextOption(),
QTextOption()
};
Qt::Alignment
m_terminals_text_alignment {Qt::AlignRight | Qt::AlignVCenter},
m_xref_text_alignment {Qt::AlignLeft | Qt::AlignVCenter};
QTextOption
m_terminals_text_option{QTextOption()},
m_xref_text_option{QTextOption()};
};
#endif // TERMINALSTRIPLAYOUTPATTERN_H

View File

@@ -16,6 +16,7 @@
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include "terminalstripdrawer.h"
#include <QPainter>
namespace TerminalStripDrawer {
@@ -42,12 +43,13 @@ void TerminalStripDrawer::setStrip(QSharedPointer<AbstractTerminalStripInterface
*/
void TerminalStripDrawer::paint(QPainter *painter)
{
if (m_strip && m_pattern)
{
//To draw text, QPainter need a Qrect. Instead of create an instance
//for each text, we re-use the same instance of QRect.
QRect text_rect;
painter->save();
if (m_strip && m_pattern)
{
m_united_xref_text_rect = QRectF();
//To draw text, QPainter need a Qrect. Instead of create an instance
//for each text, we re-use the same instance of QRect.
QRect text_rect;
painter->save();
auto pen_{painter->pen()};
pen_.setColor(Qt::black);
@@ -56,16 +58,20 @@ void TerminalStripDrawer::paint(QPainter *painter)
auto brush_ = painter->brush();
brush_.setColor(Qt::white);
painter->setPen(pen_);
painter->setBrush(brush_);
painter->setFont(m_pattern->font());
if (m_preview_draw)
{
painter->save();
painter->setPen(Qt::blue);
painter->drawRect(boundingRect());
painter->restore();
}
painter->setPen(pen_);
painter->setBrush(brush_);
if (m_preview_draw)
{
painter->save();
painter->setPen(Qt::blue);
painter->drawRect(boundingRect());
painter->drawLine(QPointF{boundingRect().left(), boundingRect().center().y()},
QPointF{boundingRect().right(), boundingRect().center().y()});
painter->restore();
}
//Draw header
painter->drawRect(m_pattern->m_header_rect);
@@ -84,14 +90,13 @@ void TerminalStripDrawer::paint(QPainter *painter)
text_rect.setRect(0,0,m_pattern->m_header_rect.height(),m_pattern->m_header_rect.width());
}
const auto text_{m_strip->installation() + " " + m_strip->location() + " " + m_strip->name()};
painter->drawText(text_rect, text_, m_pattern->headerTextOption());
const auto text_{m_strip->installation() + " " + m_strip->location() + " " + m_strip->name()};
painter->drawText(text_rect, text_, m_pattern->headerTextOption());
painter->restore();
//Move painter pos to next drawing
painter->translate(m_pattern->m_header_rect.width(),0);
int x_offset{m_pattern->m_header_rect.width()};
//Move painter pos to next drawing
painter->translate(m_pattern->m_header_rect.width(),0);
qreal x_offset{m_pattern->m_header_rect.width()};
//Draw spacer
painter->drawRect(m_pattern->m_spacer_rect);
@@ -99,22 +104,30 @@ void TerminalStripDrawer::paint(QPainter *painter)
painter->translate(m_pattern->m_spacer_rect.width(),0);
x_offset += m_pattern->m_spacer_rect.width();
//Draw terminals
const auto terminals_text_orientation{m_pattern->m_terminals_text_orientation};
const auto terminals_text_option{m_pattern->terminalsTextOption()};
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;
//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_option{m_pattern->terminalsTextOption()};
QRect 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;
//Loop over physical terminals
for (const auto &physical_t : m_strip->physicalTerminal())
{
//Get the good offset according to how many level have the current physical terminal
const QVector<QSharedPointer<AbstractRealTerminalInterface>> real_terminal_vector{physical_t->realTerminals()};
const auto real_t_count{real_terminal_vector.size()};
const auto offset_{4 - real_t_count};
m_hovered_xref = hoverTerminal{};
int physical_index = 0;
//Loop over physical terminals
for (const auto &physical_t : m_strip->physicalTerminal())
{
//Get the good offset according to how many level have the current physical terminal
const QVector<QSharedPointer<AbstractRealTerminalInterface>> real_terminal_vector{physical_t->realTerminals()};
const auto real_t_count{real_terminal_vector.size()};
const auto offset_{4 - real_t_count};
//Loop over real terminals
for (auto i=0 ; i<real_t_count ; ++i)
@@ -124,45 +137,50 @@ void TerminalStripDrawer::paint(QPainter *painter)
break;
}
terminal_rect = m_pattern->m_terminal_rect[index_];
//Draw terminal rect
painter->drawRect(terminal_rect);
//Draw a stronger line if the current terminal have level
//and the current level is the first
if (real_t_count > 1 && i == 0)
{
painter->save();
pen_ = painter->pen();
pen_.setWidth(4);
pen_.setCapStyle(Qt::FlatCap);
painter->setPen(pen_);
const auto p1 { terminal_rect.topLeft() };
//We can't use terminal_rect.bottomLeft for p2 because
//the returned value deviate from the true value
//(see Qt documentation about QRect)
const QPoint p2 { p1.x(), p1.y() + terminal_rect.height() };
painter->drawLine(p1, p2);
painter->restore();
terminal_rect = m_pattern->m_terminal_rect[index_];
//Draw terminal rect
painter->drawRect(terminal_rect);
//Draw a stronger line if the current terminal have level
//and the current level is the first
if (real_t_count > 1 && i == 0)
{
painter->save();
pen_ = painter->pen();
pen_.setWidth(4);
pen_.setCapStyle(Qt::FlatCap);
painter->setPen(pen_);
const auto p1 { terminal_rect.topLeft() };
//We can't use terminal_rect.bottomLeft for p2 because
//the returned value deviate from the true value
//(see Qt documentation about QRect)
const QPointF p2 { p1.x(), p1.y() + terminal_rect.height() };
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();
}
//Draw text
painter->save();
if (terminals_text_orientation[index_] == Qt::Horizontal)
{
text_rect = terminals_text_rect[index_];
}
else
{
const auto rect_{terminals_text_rect[index_]};
painter->translate(rect_.bottomLeft());
painter->rotate(270);
text_rect.setRect(0, 0, rect_.height(), terminal_rect.width());
}
//Draw text
painter->save();
text_rect.setRect(0, terminals_text_y, terminal_rect.width(), terminals_text_height);
if (terminals_text_orientation == Qt::Vertical)
{
painter->translate(text_rect.bottomLeft());
painter->rotate(270);
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,
shared_real_terminal ? shared_real_terminal->label() : QLatin1String(),
terminals_text_option[index_]);
terminals_text_option);
if (m_preview_draw)
{
@@ -172,16 +190,60 @@ void TerminalStripDrawer::paint(QPainter *painter)
painter->restore();
//Add bridge anchor
if (shared_real_terminal->isBridged())
//Draw xref
xref_rect.setRect(0, xref_text_y, terminal_rect.width(), xref_text_height);
painter->save();
if (xref_text_orientation == Qt::Vertical)
{
painter->save();
if (QScopedPointer<AbstractBridgeInterface> bridge_ {
shared_real_terminal->bridge() })
{
const auto x_anchor{terminal_rect.width()/2};
const auto y_anchor {m_pattern->m_bridge_point_y_offset[index_]};
const auto radius_anchor{m_pattern->m_bridge_point_d/2};
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
if (shared_real_terminal->isBridged())
{
painter->save();
if (QScopedPointer<AbstractBridgeInterface> bridge_ {
shared_real_terminal->bridge() })
{
const auto x_anchor{terminal_rect.width()/2};
const auto y_anchor {m_pattern->m_bridge_point_y_offset[index_]};
const auto radius_anchor{m_pattern->m_bridge_point_d/2};
painter->setBrush(Qt::SolidPattern);
painter->drawEllipse(QPointF(x_anchor, y_anchor),
@@ -194,12 +256,13 @@ void TerminalStripDrawer::paint(QPainter *painter)
painter->restore();
}
//Move painter pos to next drawing
painter->translate(terminal_rect.width(),0);
x_offset += terminal_rect.width();
}
}
painter->restore();
//Move painter pos to next drawing
painter->translate(terminal_rect.width(),0);
x_offset += terminal_rect.width();
}
physical_index++;
}
painter->restore();
//Draw the bridges
for (const auto &points_ : qAsConst(bridges_anchor_points))
@@ -216,7 +279,7 @@ void TerminalStripDrawer::paint(QPainter *painter)
QRectF TerminalStripDrawer::boundingRect() const
{
return QRect{0, 0, width(), height()};;
return QRectF{0, 0, width(), height()};;
}
void TerminalStripDrawer::setLayout(QSharedPointer<TerminalStripLayoutPattern> layout)
@@ -233,7 +296,42 @@ void TerminalStripDrawer::setPreviewDraw(bool 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)
{
@@ -251,11 +349,11 @@ int TerminalStripDrawer::height() const
return 0;
}
int TerminalStripDrawer::width() const
qreal TerminalStripDrawer::width() const
{
if (m_pattern)
{
int width_{m_pattern->m_header_rect.width() + m_pattern->m_spacer_rect.width()};
if (m_pattern)
{
qreal width_{m_pattern->m_header_rect.width() + m_pattern->m_spacer_rect.width()};
if (m_strip)
{

View File

@@ -27,23 +27,35 @@ class TerminalStrip;
namespace TerminalStripDrawer
{
class AbstractBridgeInterface
{
public:
AbstractBridgeInterface() {}
virtual ~AbstractBridgeInterface() {}
virtual QUuid uuid() const = 0;
/**
* @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 AbstractRealTerminalInterface
{
public:
AbstractRealTerminalInterface() {}
virtual ~AbstractRealTerminalInterface() {}
virtual QString label() const = 0;
virtual bool isBridged() const = 0;
virtual AbstractBridgeInterface* bridge() const = 0;
};
class AbstractBridgeInterface
{
public:
AbstractBridgeInterface() {}
virtual ~AbstractBridgeInterface() {}
virtual QUuid uuid() const = 0;
};
class AbstractRealTerminalInterface
{
public:
AbstractRealTerminalInterface() {}
virtual ~AbstractRealTerminalInterface() {}
virtual QString label() const = 0;
virtual bool isBridged() const = 0;
virtual AbstractBridgeInterface* bridge() const = 0;
virtual QString xref() const = 0;
};
class AbstractPhysicalTerminalInterface
{
@@ -79,15 +91,24 @@ namespace TerminalStripDrawer
void setPreviewDraw(bool draw = true);
private:
int height() const;
int width() const;
void setMouseHoverPos(const QPointF &pos);
bool mouseHoverXref() const;
bool needUpdate();
hoverTerminal hoveredXref() const;
private:
QSharedPointer <AbstractTerminalStripInterface> m_strip;
QSharedPointer<TerminalStripLayoutPattern> m_pattern;
bool m_preview_draw { false };
};
private:
qreal height() const;
qreal width() const;
private:
QSharedPointer <AbstractTerminalStripInterface> m_strip;
QSharedPointer<TerminalStripLayoutPattern> m_pattern;
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;
};
}
#endif // TERMINALSTRIPDRAWER_H

View File

@@ -22,6 +22,8 @@
#include "../../project/projectpropertieshandler.h"
#include "../../qetgraphicsitem/qgraphicsitemutility.h"
#include "../terminalstrip.h"
#include "../physicalterminal.h"
#include "../realterminal.h"
#include "../ui/terminalstripeditorwindow.h"
#include "trueterminalstrip.h"
@@ -94,12 +96,52 @@ QString TerminalStripItem::name() const {
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)
{
Q_UNUSED (event);
const auto hovered = m_drawer.hoveredXref();
if (m_strip) {
TerminalStripEditorWindow::edit(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);
}
}
}

View File

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

View File

@@ -20,6 +20,7 @@
#include "../realterminal.h"
#include "../terminalstrip.h"
#include "../terminalstripbridge.h"
#include "../../autoNum/assignvariables.h"
#include "terminalstripdrawer.h"
@@ -118,9 +119,18 @@ namespace TerminalStripDrawer
return new TrueBridge(m_real->bridge());
}
TrueBridge::TrueBridge(QSharedPointer<TerminalStripBridge> bridge) :
m_bridge { 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) :
m_bridge { bridge }
{}
QUuid TrueBridge::uuid() const
{

View File

@@ -51,13 +51,14 @@ namespace TerminalStripDrawer
QSharedPointer<PhysicalTerminal> m_physical;
};
class TrueRealTerminal : public AbstractRealTerminalInterface
{
public:
TrueRealTerminal(QSharedPointer<RealTerminal> real);
QString label() const override;
bool isBridged() const override;
AbstractBridgeInterface* bridge() const override;
class TrueRealTerminal : public AbstractRealTerminalInterface
{
public:
TrueRealTerminal(QSharedPointer<RealTerminal> real);
QString label() const override;
bool isBridged() const override;
AbstractBridgeInterface* bridge() const override;
QString xref() const override;
private:
QSharedPointer<RealTerminal> m_real;

View File

@@ -189,6 +189,20 @@ QVector<QSharedPointer<RealTerminal>> PhysicalTerminal::realTerminals() const {
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
* @return the uuid of this physical terminal

View File

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

View File

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

View File

@@ -32,16 +32,20 @@
*/
FreeTerminalEditor::FreeTerminalEditor(QETProject *project, QWidget *parent) :
QWidget(parent),
ui(new Ui::FreeTerminalEditor),
m_project(project)
ui(new Ui::FreeTerminalEditor),
m_project(project)
{
ui->setupUi(this);
ui->m_table_view->setItemDelegate(new FreeTerminalModelDelegate(ui->m_table_view));
m_model = new FreeTerminalModel(m_project, this);
m_model = new FreeTerminalModel(m_project, this);
ui->m_table_view->setModel(m_model);
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)
connect(m_model, &FreeTerminalModel::dataChanged, this, [=] {
this->setDisabledMove();
@@ -135,6 +139,31 @@ void FreeTerminalEditor::apply()
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)
{
if (m_model)

View File

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

View File

@@ -56,10 +56,30 @@ FreeTerminalModel::Column FreeTerminalModel::columnTypeForIndex(const QModelInde
* @param parent
*/
FreeTerminalModel::FreeTerminalModel(QETProject *project, QObject *parent) :
QAbstractTableModel(parent),
m_project(project)
QAbstractTableModel(parent) {
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,20 +325,22 @@ QVector<QSharedPointer<RealTerminal> > FreeTerminalModel::realTerminalForIndex(c
*/
void FreeTerminalModel::fillTerminalVector()
{
ElementProvider provider_(m_project);
auto free_terminal_vector = provider_.freeTerminal();
if (m_project) {
ElementProvider provider_(m_project);
auto free_terminal_vector = provider_.freeTerminal();
std::sort(free_terminal_vector.begin(), free_terminal_vector.end(),
[](TerminalElement *a, TerminalElement *b)
{
return QETUtils::sortBeginIntString(a->elementData().m_informations.value(QETInformation::ELMT_LABEL).toString(),
b->elementData().m_informations.value(QETInformation::ELMT_LABEL).toString());
});
std::sort(free_terminal_vector.begin(), free_terminal_vector.end(),
[](TerminalElement *a, TerminalElement *b)
{
return QETUtils::sortBeginIntString(a->elementData().m_informations.value(QETInformation::ELMT_LABEL).toString(),
b->elementData().m_informations.value(QETInformation::ELMT_LABEL).toString());
});
for (const auto &terminal_ : free_terminal_vector) {
m_terminal_vector.append(terminal_->realTerminal());
m_real_t_data.append(modelRealTerminalData::data(terminal_->realTerminal()));
}
for (const auto &terminal_ : free_terminal_vector) {
m_terminal_vector.append(terminal_->realTerminal());
m_real_t_data.append(modelRealTerminalData::data(terminal_->realTerminal()));
}
}
}
/****************************************************************

View File

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

View File

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

View File

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

View File

@@ -51,10 +51,15 @@ void TerminalStripEditorWindow::edit(TerminalStrip *strip)
TerminalStripEditorWindow::TerminalStripEditorWindow(QETProject *project, QWidget *parent) :
QMainWindow(parent),
ui(new Ui::TerminalStripEditorWindow),
m_project(project)
ui(new Ui::TerminalStripEditorWindow),
m_project(project)
{
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);
addTreeDockWidget();
@@ -76,6 +81,18 @@ TerminalStripEditorWindow::~TerminalStripEditorWindow()
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) {
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) {
ui->m_button_box->setHidden(arg1 == EMPTY_PAGE);
}

View File

@@ -43,17 +43,19 @@ class TerminalStripEditorWindow : public QMainWindow
//instance in her destrucor and then window_ become a dangling pointer.
static QPointer<TerminalStripEditorWindow> window_;
public:
static TerminalStripEditorWindow* instance(QETProject *project, QWidget *parent = nullptr) {
static QMutex mutex_;
if (!window_) {
mutex_.lock();
if (!window_)
window_ = new TerminalStripEditorWindow{project, parent};
mutex_.unlock();
}
return window_;
}
public:
static TerminalStripEditorWindow* instance(QETProject *project, QWidget *parent = nullptr) {
static QMutex mutex_;
if (!window_) {
mutex_.lock();
if (!window_)
window_ = new TerminalStripEditorWindow{project, parent};
mutex_.unlock();
} else {
window_->setProject(project);
}
return window_;
}
static void dropInstance () {
static QMutex mutex;
@@ -71,7 +73,8 @@ class TerminalStripEditorWindow : public QMainWindow
explicit TerminalStripEditorWindow(QETProject *project, QWidget *parent = nullptr);
~TerminalStripEditorWindow();
void setCurrentStrip(TerminalStrip *strip);
void setProject(QETProject *project);
void setCurrentStrip(TerminalStrip *strip);
private slots:
void on_m_add_terminal_strip_triggered();
@@ -87,7 +90,7 @@ class TerminalStripEditorWindow : public QMainWindow
private:
Ui::TerminalStripEditorWindow *ui{nullptr};
QETProject *m_project {nullptr};
QPointer <QETProject> m_project;
TerminalStripTreeDockWidget *m_tree_dock{nullptr};
FreeTerminalEditor *m_free_terminal_editor {nullptr};
TerminalStripEditor *m_terminal_strip_editor {nullptr};

View File

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

View File

@@ -15,6 +15,8 @@
You should have received a copy of the GNU General Public License
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include <QFontDialog>
#include "terminalstriplayouteditor.h"
#include "ui_terminalstriplayouteditor.h"
#include "../GraphicsItem/properties/terminalstriplayoutpattern.h"
@@ -54,12 +56,10 @@ void TerminalStripLayoutEditor::valueEdited()
return;
}
//auto *data_ = m_layout.data();
m_layout.data()->m_header_rect.setRect(0,
ui->m_y_header_sb->value(),
ui->m_width_header_sb->value(),
ui->m_height_header_sb->value());
m_layout.data()->m_header_rect.setRect(0,
ui->m_y_header_sb->value(),
ui->m_width_header_sb->value(),
ui->m_height_header_sb->value());
m_layout.data()->m_spacer_rect.setRect(0,
ui->m_y_spacer_sb->value(),
@@ -91,9 +91,13 @@ 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[3] = ui->m_bridge_point_3_sb->value();
m_layout.data()->m_header_text_orientation = ui->m_header_text_orientation_cb->currentIndex() == 0 ?
Qt::Horizontal :
Qt::Vertical;
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 ?
Qt::Horizontal :
Qt::Vertical;
switch (ui->m_header_text_alignment_cb->currentIndex()) {
case 0:
@@ -104,34 +108,46 @@ void TerminalStripLayoutEditor::valueEdited()
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 ?
Qt::Horizontal :
Qt::Vertical;
//Terminal text
m_layout.data()->m_terminals_text_orientation = ui->m_terminal_text_orientation_cb->currentIndex() == 0 ?
Qt::Horizontal :
Qt::Vertical;
switch (ui->m_terminal_text_alignment_cb->currentIndex()) {
case 0:
m_layout.data()->setTerminalsTextAlignment(
QVector<Qt::Alignment> { Qt::AlignLeft | Qt::AlignVCenter,
Qt::AlignLeft | Qt::AlignVCenter,
Qt::AlignLeft | Qt::AlignVCenter,
Qt::AlignLeft | Qt::AlignVCenter });
break;
case 1:
m_layout.data()->setTerminalsTextAlignment(
QVector<Qt::Alignment> { Qt::AlignHCenter | Qt::AlignVCenter,
Qt::AlignHCenter | Qt::AlignVCenter,
Qt::AlignHCenter | Qt::AlignVCenter,
Qt::AlignHCenter | Qt::AlignVCenter });
break;
default:
m_layout.data()->setTerminalsTextAlignment(
QVector<Qt::Alignment> { Qt::AlignRight | Qt::AlignVCenter,
Qt::AlignRight | Qt::AlignVCenter,
Qt::AlignRight | Qt::AlignVCenter,
Qt::AlignRight | Qt::AlignVCenter });
break;
switch (ui->m_terminal_text_alignment_cb->currentIndex()) {
case 0:
m_layout.data()->setTerminalsTextAlignment(Qt::Alignment {Qt::AlignLeft | Qt::AlignVCenter});
break;
case 1:
m_layout.data()->setTerminalsTextAlignment(Qt::Alignment { Qt::AlignHCenter | Qt::AlignVCenter});
break;
default:
m_layout.data()->setTerminalsTextAlignment(Qt::Alignment { Qt::AlignRight | Qt::AlignVCenter});
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();
m_preview_strip_item.update();
}
@@ -180,17 +196,21 @@ void TerminalStripLayoutEditor::updateUi()
ui->m_bridge_point_2_sb->setValue(bridge_point[2]);
ui->m_bridge_point_3_sb->setValue(bridge_point[3]);
if (data->m_header_text_orientation == Qt::Horizontal) {
ui->m_header_text_orientation_cb->setCurrentIndex(0);
} else {
ui->m_header_text_orientation_cb->setCurrentIndex(1);
}
const auto font = m_layout->font();
ui->m_font_size_sb->setValue(font.pixelSize());
ui->m_font_cb->setCurrentFont(font);
if (data->m_terminals_text_orientation[0] == Qt::Horizontal) {
ui->m_terminal_text_orientation_cb->setCurrentIndex(0);
} else {
ui->m_terminal_text_orientation_cb->setCurrentIndex(1);
}
if (data->m_header_text_orientation == Qt::Horizontal) {
ui->m_header_text_orientation_cb->setCurrentIndex(0);
} else {
ui->m_header_text_orientation_cb->setCurrentIndex(1);
}
if (data->m_terminals_text_orientation == Qt::Horizontal) {
ui->m_terminal_text_orientation_cb->setCurrentIndex(0);
} else {
ui->m_terminal_text_orientation_cb->setCurrentIndex(1);
}
const auto header_alignment = data->headerTextAlignment();
if (header_alignment &Qt::AlignLeft) {
@@ -201,15 +221,38 @@ void TerminalStripLayoutEditor::updateUi()
ui->m_header_text_alignment_cb->setCurrentIndex(2);
}
const auto terminal_alignment = data->terminalsTextAlignment().at(0);
if (terminal_alignment &Qt::AlignLeft) {
ui->m_terminal_text_alignment_cb->setCurrentIndex(0);
} else if (terminal_alignment &Qt::AlignHCenter) {
ui->m_terminal_text_alignment_cb->setCurrentIndex(1);
} else if (terminal_alignment &Qt::AlignRight) {
ui->m_terminal_text_alignment_cb->setCurrentIndex(2);
//Terminal text
const auto terminal_alignment = data->terminalsTextAlignment();
if (terminal_alignment &Qt::AlignLeft) {
ui->m_terminal_text_alignment_cb->setCurrentIndex(0);
} else if (terminal_alignment &Qt::AlignHCenter) {
ui->m_terminal_text_alignment_cb->setCurrentIndex(1);
} else if (terminal_alignment &Qt::AlignRight) {
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;
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.update();
}

View File

@@ -74,10 +74,9 @@ class TerminalStripLayoutEditor : public QWidget
void resizeEvent(QResizeEvent *event) override;
void showEvent(QShowEvent *event) override;
private slots:
void valueEdited();
void on_m_display_preview_help_clicked(bool checked);
private slots:
void valueEdited();
void on_m_display_preview_help_clicked(bool checked);
private:
void updateUi();

View File

@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>767</width>
<height>544</height>
<width>961</width>
<height>624</height>
</rect>
</property>
<property name="windowTitle">
@@ -17,17 +17,17 @@
<property name="sizeConstraint">
<enum>QLayout::SetMaximumSize</enum>
</property>
<item row="4" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Borne niveau 0 :</string>
<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="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>En tête :</string>
<item row="6" column="3">
<widget class="QSpinBox" name="m_height_terminal_2_sb">
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
@@ -38,37 +38,6 @@
</property>
</widget>
</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">
<widget class="QLabel" name="label_3">
<property name="text">
@@ -76,15 +45,43 @@
</property>
</widget>
</item>
<item row="11" column="4">
<widget class="QCheckBox" name="m_display_preview_help">
<property name="text">
<string>Afficher l'aide</string>
<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="1" column="2">
<widget class="QSpinBox" name="m_width_header_sb">
<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="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">
<number>1000</number>
</property>
@@ -97,22 +94,39 @@
</property>
</widget>
</item>
<item row="5" column="4">
<widget class="QSpinBox" name="m_bridge_point_1_sb">
<item row="14" column="0" colspan="5">
<widget class="QGraphicsView" name="m_graphics_view"/>
</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="2">
<widget class="QLabel" name="label_4">
<item row="7" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Largeur</string>
<string>Borne niveau 3 :</string>
</property>
</widget>
</item>
<item row="6" column="3">
<widget class="QSpinBox" name="m_height_terminal_2_sb">
<item row="6" column="0">
<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">
<number>1000</number>
</property>
@@ -125,17 +139,48 @@
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLabel" name="label_5">
<item row="13" column="4">
<widget class="QCheckBox" name="m_display_preview_help">
<property name="text">
<string>Hauteur</string>
<string>Afficher l'aide</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="label_2">
<item row="0" column="2">
<widget class="QLabel" name="label_4">
<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>
</widget>
</item>
@@ -146,35 +191,14 @@
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QSpinBox" name="m_y_terminal_3_sb">
<property name="maximum">
<number>1000</number>
<item row="5" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Borne niveau 1 :</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="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">
<item row="10" column="0" colspan="5">
<widget class="QWidget" name="widget" native="true">
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
@@ -189,26 +213,21 @@
<property name="bottomMargin">
<number>0</number>
</property>
<item row="1" column="3">
<widget class="QComboBox" name="m_terminal_text_alignment_cb">
<item row="5" column="3">
<widget class="QComboBox" name="m_header_text_orientation_cb">
<item>
<property name="text">
<string>Gauche</string>
<string>Horizontal</string>
</property>
</item>
<item>
<property name="text">
<string>Centre</string>
</property>
</item>
<item>
<property name="text">
<string>Droite</string>
<string>Vertical</string>
</property>
</item>
</widget>
</item>
<item row="0" column="3">
<item row="6" column="3">
<widget class="QComboBox" name="m_header_text_alignment_cb">
<item>
<property name="text">
@@ -227,21 +246,136 @@
</item>
</widget>
</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">
<property name="text">
<string>Alignement du texte d'en tête :</string>
<string>Alignement</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="label_17">
<item row="1" column="2" colspan="4">
<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">
<string>Police :</string>
</property>
</widget>
</item>
<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>Alignement du texte de borne :</string>
<string>Texte d'en tête</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<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">
<item>
<property name="text">
@@ -255,8 +389,28 @@
</item>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="m_header_text_orientation_cb">
<item row="2" column="4">
<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>
<property name="text">
<string>Horizontal</string>
@@ -269,23 +423,66 @@
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_16">
<property name="text">
<string>Orientation du texte de borne :</string>
<item row="6" column="5">
<widget class="QComboBox" name="m_xref_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="7" column="5">
<widget class="QSpinBox" name="m_xref_y_sb">
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_14">
<property name="text">
<string>Orientation du texte d'en tête :</string>
<item row="8" column="5">
<widget class="QSpinBox" name="m_xref_height_sb">
<property name="minimum">
<number>30</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
</widget>
</item>
</layout>
</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="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">
<widget class="QSpinBox" name="m_height_header_sb">
<property name="maximum">
@@ -293,34 +490,6 @@
</property>
</widget>
</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">
<widget class="QSpinBox" name="m_y_terminal_2_sb">
<property name="maximum">
@@ -328,69 +497,55 @@
</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="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">
<item row="9" column="0" colspan="5">
<widget class="Line" name="line_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</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>
</widget>
<resources/>
@@ -811,6 +966,134 @@
</hint>
</hints>
</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>
<slots>
<slot>valueEdited()</slot>

View File

@@ -30,11 +30,10 @@
TerminalStripTreeDockWidget::TerminalStripTreeDockWidget(QETProject *project, QWidget *parent) :
QDockWidget(parent),
ui(new Ui::TerminalStripTreeDockWidget),
m_project(project)
ui(new Ui::TerminalStripTreeDockWidget)
{
ui->setupUi(this);
buildTree();
setProject(project);
#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
ui->m_tree_view->expandRecursively(ui->m_tree_view->rootIndex());
@@ -48,6 +47,32 @@ TerminalStripTreeDockWidget::~TerminalStripTreeDockWidget()
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
*/
@@ -205,6 +230,9 @@ void TerminalStripTreeDockWidget::on_m_tree_view_currentItemChanged(QTreeWidgetI
*/
void TerminalStripTreeDockWidget::buildTree()
{
if(!m_project) {
return;
}
auto title_ = m_project->title();
if (title_.isEmpty()) {

View File

@@ -49,6 +49,7 @@ class TerminalStripTreeDockWidget : public QDockWidget
explicit TerminalStripTreeDockWidget(QETProject *project, QWidget *parent = nullptr);
~TerminalStripTreeDockWidget();
void setProject(QETProject *project = nullptr);
void reload();
bool currentIsStrip() const;
TerminalStrip* currentStrip() const;
@@ -74,11 +75,12 @@ class TerminalStripTreeDockWidget : public QDockWidget
QPointer<QETProject> m_project;
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, QPointer<TerminalStrip>> m_uuid_strip_H;
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

View File

@@ -59,7 +59,15 @@ DiagramContent::DiagramContent(Diagram *diagram, bool selected) :
{
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 Conductor::Type:
{

View File

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

View File

@@ -1469,12 +1469,21 @@ void QETDiagramEditor::selectionGroupTriggered(QAction *action)
if (!dv || value.isEmpty()) return;
if (value == "delete_selection")
{
diagram->clearSelection();
diagram->undoStack().push(new DeleteQGraphicsItemCommand(diagram, dc));
dv->adjustSceneRect();
}
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->undoStack().push(new DeleteQGraphicsItemCommand(diagram, dc));
dv->adjustSceneRect();
}
}
else if (value == "rotate_selection")
{
RotateSelectionCommand *c = new RotateSelectionCommand(diagram);

View File

@@ -54,6 +54,8 @@ class KAutoSaveFile;
class QETDiagramEditor : public QETMainWindow
{
Q_OBJECT
friend class TerminalStripEditorWindow;
public:
QETDiagramEditor(

View File

@@ -35,6 +35,7 @@
#include "iostream"
#include "../qetxml.h"
#include "../qetversion.h"
#include "qgraphicsitemutility.h"
#include <QDomElement>
#include <utility>
@@ -236,7 +237,7 @@ void Element::paint(
//Draw the selection rectangle
if ( isSelected() || m_mouse_over ) {
drawSelection(painter, options);
QGIUtility::drawBoundingRectSelection(this, painter);
}
}
@@ -334,34 +335,6 @@ void Element::drawAxes(
/*** 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.
@param painter Le QPainter a utiliser pour dessiner les bornes.

View File

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

View File

@@ -24,12 +24,31 @@
Default constructor
@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):
QGraphicsObject(parent),
is_movable_(true),
m_first_move(true),
snap_to_grid_(true)
{}
{
setAcceptHoverEvents(true);
}
QetGraphicsItem::~QetGraphicsItem()
{}
@@ -68,6 +87,11 @@ bool QetGraphicsItem::isHovered() const {
return m_hovered;
}
QPointF QetGraphicsItem::hoverMousePos() const
{
return m_mouse_hover_pos;
}
/**
@brief QetGraphicsItem::state
@return the current state of this item
@@ -166,6 +190,12 @@ void QetGraphicsItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
QGraphicsObject::hoverEnterEvent(event);
}
void QetGraphicsItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
{
QGraphicsObject::hoverMoveEvent(event);
m_mouse_hover_pos = event->pos();
}
void QetGraphicsItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
m_hovered = false;

View File

@@ -28,6 +28,9 @@ class QetGraphicsItem : public QGraphicsObject
{
Q_OBJECT
public :
static void showItem (QetGraphicsItem *item);
public:
//constructor destructor
QetGraphicsItem(QGraphicsItem *parent = nullptr);
@@ -43,6 +46,7 @@ class QetGraphicsItem : public QGraphicsObject
virtual void setMovable (bool movable) { is_movable_ = movable;}
bool isHovered() const;
QPointF hoverMousePos() const;
virtual void editProperty () {}
virtual QString name ()const
@@ -57,6 +61,7 @@ class QetGraphicsItem : public QGraphicsObject
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
void hoverMoveEvent(QGraphicsSceneHoverEvent *event) override;
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override;
protected:
@@ -68,6 +73,7 @@ class QetGraphicsItem : public QGraphicsObject
private:
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;
}
/**
* @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);
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);
bool boolFromString(const QString &value,
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/terminal.h"
#include "addelementtextcommand.h"
#include "../TerminalStrip/realterminal.h"
#include "../TerminalStrip/physicalterminal.h"
/**
@brief DeleteQGraphicsItemCommand::DeleteQGraphicsItemCommand
@@ -115,6 +117,36 @@ DeleteQGraphicsItemCommand::~DeleteQGraphicsItemCommand()
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
This function creates new conductors (if needed) for conserve the electrical potentials

View File

@@ -34,10 +34,10 @@ class DeleteQGraphicsItemCommand : public QUndoCommand
public:
DeleteQGraphicsItemCommand(Diagram *diagram, const DiagramContent &content, QUndoCommand * parent = nullptr);
~DeleteQGraphicsItemCommand() override;
static bool hasNonDeletableTerminal(const DiagramContent &content);
private:
DeleteQGraphicsItemCommand(const DeleteQGraphicsItemCommand &);
void setPotentialsOfRemovedElements();
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;
}
}
/**
* @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);
QMargins marginsFromString(const QString &string);
qreal graphicsHandlerSize(QGraphicsItem *item);
void pixelSizedFont (QFont &font);
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