diff --git a/sources/conductorproperties.cpp b/sources/conductorproperties.cpp index 2e5cfb462..e591cd79f 100644 --- a/sources/conductorproperties.cpp +++ b/sources/conductorproperties.cpp @@ -23,6 +23,7 @@ SingleLineProperties::SingleLineProperties() : hasGround(true), hasNeutral(true), + is_pen(false), phases(1) { } @@ -44,6 +45,15 @@ unsigned short int SingleLineProperties::phasesCount() { return(phases); } +/** + @return true if the singleline conductor should be drawn using the PEN + (Protective Earth Neutral) representation and if it features the ground and + the neutral. +*/ +bool SingleLineProperties::isPen() const { + return(hasNeutral && hasGround && is_pen); +} + /** Dessine les symboles propres a un conducteur unifilaire @param painter QPainter a utiliser pour dessiner les symboles @@ -59,38 +69,33 @@ void SingleLineProperties::draw(QPainter *painter, QET::ConductorSegmentType dir QPen pen(painter -> pen()); pen.setCapStyle(Qt::FlatCap); pen.setJoinStyle(Qt::MiterJoin); + pen.setStyle(Qt::SolidLine); painter -> setPen(pen); painter -> setRenderHint(QPainter::Antialiasing, true); - uint symbols_count = (hasNeutral ? 1 : 0) + (hasGround ? 1 : 0) + phases; - qreal interleave; - qreal symbol_width; - if (direction == QET::Horizontal) { - interleave = rect.width() / (symbols_count + 1); - symbol_width = rect.width() / 12; - for (uint i = 1 ; i <= symbols_count ; ++ i) { - // dessine le tronc du symbole - QPointF symbol_p1(rect.x() + (i * interleave) + symbol_width, rect.y() + rect.height() * 0.75); - QPointF symbol_p2(rect.x() + (i * interleave) - symbol_width, rect.y() + rect.height() * 0.25); - painter -> drawLine(QLineF(symbol_p1, symbol_p2)); - - // dessine le reste des symboles terre et neutre - if (hasGround && i == 1) { - drawGround(painter, direction, symbol_p2, symbol_width * 2.0); - } else if (hasNeutral && ((i == 1 && !hasGround) || (i == 2 && hasGround))) { - drawNeutral(painter, direction, symbol_p2, symbol_width * 1.35); - } + uint symbols_count = (hasNeutral ? 1 : 0) + (hasGround ? 1 : 0) - (isPen() ? 1 : 0) + phases; + qreal interleave_base = (direction == QET::Horizontal ? rect.width() : rect.height()); + qreal interleave = interleave_base / (symbols_count + 1);; + qreal symbol_width = interleave_base / 12; + + for (uint i = 1 ; i <= symbols_count ; ++ i) { + // dessine le tronc du symbole + QPointF symbol_p1, symbol_p2; + if (direction == QET::Horizontal) { + symbol_p1 = QPointF(rect.x() + (i * interleave) + symbol_width, rect.y() + rect.height() * 0.75); + symbol_p2 = QPointF(rect.x() + (i * interleave) - symbol_width, rect.y() + rect.height() * 0.25); + } else { + symbol_p2 = QPointF(rect.x() + rect.width() * 0.75, rect.y() + (i * interleave) - symbol_width); + symbol_p1 = QPointF(rect.x() + rect.width() * 0.25, rect.y() + (i * interleave) + symbol_width); } - } else { - interleave = rect.height() / (symbols_count + 1); - symbol_width = rect.height() / 12; - for (uint i = 1 ; i <= symbols_count ; ++ i) { - // dessine le tronc du symbole - QPointF symbol_p2(rect.x() + rect.width() * 0.75, rect.y() + (i * interleave) - symbol_width); - QPointF symbol_p1(rect.x() + rect.width() * 0.25, rect.y() + (i * interleave) + symbol_width); - painter -> drawLine(QLineF(symbol_p1, symbol_p2)); - - // dessine le reste des symboles terre et neutre + painter -> drawLine(QLineF(symbol_p1, symbol_p2)); + + // dessine le reste des symboles terre et neutre + if (isPen()) { + if (i == 1) { + drawPen(painter, direction, symbol_p2, symbol_width); + } + } else { if (hasGround && i == 1) { drawGround(painter, direction, symbol_p2, symbol_width * 2.0); } else if (hasNeutral && ((i == 1 && !hasGround) || (i == 2 && hasGround))) { @@ -159,6 +164,30 @@ void SingleLineProperties::drawNeutral(QPainter *painter, QET::ConductorSegmentT painter -> restore(); } +/** + Draw the PEN (Protective Earth Neutral) symbol using \a painter at position \a + center, using a size hint of \a size. + @param direction Indicate the direction of the underlying conductor segment +*/ +void SingleLineProperties::drawPen(QPainter *painter, QET::ConductorSegmentType direction, QPointF center, qreal size) { + painter -> save(); + + //painter -> setBrush(Qt::white); + // desine le cercle representant le neutre + //painter -> drawEllipse( + // QRectF( + // center - QPointF(size * 1.5 / 2.0, size * 1.5 / 2.0), + // QSizeF(size * 1.5, size * 1.5) + // ) + //); + drawNeutral(painter, direction, center, size * 1.5); + + int offset = (size * 1.5 / 2.0); + QPointF pos = center + (direction == QET::Horizontal ? QPointF(0.0, -offset - 0.5) : QPointF(offset + 0.5, 0.0)); + drawGround(painter, direction, pos, 2.0 * size); + painter -> restore(); +} + /** Exporte les parametres du conducteur unifilaire sous formes d'attributs XML ajoutes a l'element e. @@ -168,6 +197,7 @@ void SingleLineProperties::toXml(QDomElement &e) const { e.setAttribute("ground", hasGround ? "true" : "false"); e.setAttribute("neutral", hasNeutral ? "true" : "false"); e.setAttribute("phase", phases); + if (isPen()) e.setAttribute("pen", "true"); } /** @@ -179,6 +209,7 @@ void SingleLineProperties::fromXml(QDomElement &e) { hasGround = e.attribute("ground") == "true"; hasNeutral = e.attribute("neutral") == "true"; setPhasesCount(e.attribute("phase").toInt()); + is_pen = (hasGround && hasNeutral && e.attribute("pen", "false") == "true"); } /** @@ -378,6 +409,7 @@ int SingleLineProperties::operator==(const SingleLineProperties &other) const { return( other.hasGround == hasGround &&\ other.hasNeutral == hasNeutral &&\ + other.is_pen == is_pen &&\ other.phases == phases ); } @@ -398,6 +430,7 @@ void SingleLineProperties::toSettings(QSettings &settings, const QString &prefix settings.setValue(prefix + "hasGround", hasGround); settings.setValue(prefix + "hasNeutral", hasNeutral); settings.setValue(prefix + "phases", phases); + settings.setValue(prefix + "pen", is_pen); } /** @@ -408,4 +441,5 @@ void SingleLineProperties::fromSettings(QSettings &settings, const QString &pref hasGround = settings.value(prefix + "hasGround", true).toBool(); hasNeutral = settings.value(prefix + "hasNeutral", true).toBool(); phases = settings.value(prefix + "phases", 1).toInt(); + is_pen = settings.value(prefix + "pen", false).toBool(); } diff --git a/sources/conductorproperties.h b/sources/conductorproperties.h index f189b0dd7..50ccf63e6 100644 --- a/sources/conductorproperties.h +++ b/sources/conductorproperties.h @@ -30,6 +30,7 @@ class SingleLineProperties { void setPhasesCount(int); unsigned short int phasesCount(); + bool isPen() const; void draw(QPainter *, QET::ConductorSegmentType, const QRectF &); void toXml(QDomElement &) const; void fromXml(QDomElement &); @@ -40,6 +41,8 @@ class SingleLineProperties { bool hasGround; /// indique si le conducteur unifilaire doit afficher le symbole neutre bool hasNeutral; + /// Protective Earth Neutral: visually merge neutral and ground + bool is_pen; int operator==(const SingleLineProperties &) const; int operator!=(const SingleLineProperties &) const; @@ -48,6 +51,7 @@ class SingleLineProperties { unsigned short int phases; void drawGround (QPainter *, QET::ConductorSegmentType, QPointF, qreal); void drawNeutral(QPainter *, QET::ConductorSegmentType, QPointF, qreal); + void drawPen(QPainter *, QET::ConductorSegmentType, QPointF, qreal); }; /** diff --git a/sources/conductorpropertieswidget.cpp b/sources/conductorpropertieswidget.cpp index 6136e2728..6fe1ba5b9 100644 --- a/sources/conductorpropertieswidget.cpp +++ b/sources/conductorpropertieswidget.cpp @@ -68,6 +68,21 @@ void ConductorPropertiesWidget::buildInterface() { singleline = new QRadioButton(tr("Unifilaire")); + ground_checkbox = new QCheckBox(tr("terre")); + ground_checkbox -> setIcon(QET::Icons::Ground); + neutral_checkbox = new QCheckBox(tr("neutre")); + neutral_checkbox -> setIcon(QET::Icons::Neutral); + merge_checkbox = new QCheckBox(tr("PEN", "Protective Earth Neutral")); + merge_checkbox -> setToolTip(tr("Protective Earth Neutral", "Tooltip displaying the meaning of the 'PEN' acronym")); + + QVBoxLayout *singleline_layout5 = new QVBoxLayout(); + singleline_layout5 -> addWidget(ground_checkbox); + singleline_layout5 -> addWidget(neutral_checkbox); + + QHBoxLayout *singleline_layout4 = new QHBoxLayout(); + singleline_layout4 -> addLayout(singleline_layout5); + singleline_layout4 -> addWidget(merge_checkbox, 4, Qt::AlignVCenter | Qt::AlignLeft); + QHBoxLayout *singleline_layout3 = new QHBoxLayout(); phase_checkbox = new QCheckBox(tr("phase")); phase_checkbox -> setIcon(QET::Icons::Phase); @@ -80,12 +95,7 @@ void ConductorPropertiesWidget::buildInterface() { singleline_layout3 -> addWidget(phase_spinbox); QVBoxLayout *singleline_layout2 = new QVBoxLayout(); - ground_checkbox = new QCheckBox(tr("terre")); - ground_checkbox -> setIcon(QET::Icons::Ground); - neutral_checkbox = new QCheckBox(tr("neutre")); - neutral_checkbox -> setIcon(QET::Icons::Neutral); - singleline_layout2 -> addWidget(ground_checkbox); - singleline_layout2 -> addWidget(neutral_checkbox); + singleline_layout2 -> addLayout(singleline_layout4); singleline_layout2 -> addLayout(singleline_layout3); QHBoxLayout *singleline_layout1 = new QHBoxLayout(); @@ -135,6 +145,7 @@ void ConductorPropertiesWidget::buildConnections() { connect(phase_spinbox, SIGNAL(valueChanged(int)), phase_slider, SLOT(setValue(int))); connect(ground_checkbox, SIGNAL(toggled(bool)), this, SLOT(updateConfig())); connect(neutral_checkbox, SIGNAL(toggled(bool)), this, SLOT(updateConfig())); + connect(merge_checkbox, SIGNAL(toggled(bool)), this, SLOT(updateConfig())); connect(phase_checkbox, SIGNAL(toggled(bool)), this, SLOT(updateConfig())); connect(phase_slider, SIGNAL(valueChanged(int)), this, SLOT(updateConfig())); connect(radio_buttons, SIGNAL(buttonClicked(int)), this, SLOT(updateConfig())); @@ -178,6 +189,7 @@ void ConductorPropertiesWidget::destroyConnections() { disconnect(phase_spinbox, SIGNAL(valueChanged(int)), phase_slider, SLOT(setValue(int))); disconnect(ground_checkbox, SIGNAL(toggled(bool)), this, SLOT(updateConfig())); disconnect(neutral_checkbox, SIGNAL(toggled(bool)), this, SLOT(updateConfig())); + disconnect(merge_checkbox, SIGNAL(toggled(bool)), this, SLOT(updateConfig())); disconnect(phase_checkbox, SIGNAL(toggled(bool)), this, SLOT(updateConfig())); disconnect(phase_slider, SIGNAL(valueChanged(int)), this, SLOT(updateConfig())); disconnect(radio_buttons, SIGNAL(buttonClicked(int)), this, SLOT(updateConfig())); @@ -198,6 +210,7 @@ void ConductorPropertiesWidget::updateConfig() { properties_.text = text_field -> text(); properties_.singleLineProperties.hasGround = ground_checkbox -> isChecked(); properties_.singleLineProperties.hasNeutral = neutral_checkbox -> isChecked(); + properties_.singleLineProperties.is_pen = merge_checkbox -> isChecked(); properties_.singleLineProperties.setPhasesCount(phase_checkbox -> isChecked() ? phase_spinbox -> value() : 0); updateDisplay(); @@ -213,6 +226,8 @@ void ConductorPropertiesWidget::updateDisplay() { text_field -> setText(properties_.text); ground_checkbox -> setChecked(properties_.singleLineProperties.hasGround); neutral_checkbox -> setChecked(properties_.singleLineProperties.hasNeutral); + merge_checkbox -> setChecked(properties_.singleLineProperties.is_pen); + merge_checkbox -> setEnabled(!isReadOnly() && ground_checkbox -> isChecked() && neutral_checkbox -> isChecked()); phase_spinbox -> setValue(properties_.singleLineProperties.phasesCount()); phase_slider -> setValue(properties_.singleLineProperties.phasesCount()); phase_checkbox -> setChecked(properties_.singleLineProperties.phasesCount()); @@ -257,6 +272,7 @@ void ConductorPropertiesWidget::setConductorType(ConductorProperties::ConductorT phase_spinbox -> setEnabled(sl); ground_checkbox -> setEnabled(sl); neutral_checkbox -> setEnabled(sl); + merge_checkbox -> setEnabled(sl); } /// @param p les nouvelles proprietes @@ -290,6 +306,7 @@ void ConductorPropertiesWidget::setReadOnly(bool ro) { phase_spinbox -> setReadOnly(ro); ground_checkbox -> setDisabled(ro); neutral_checkbox -> setDisabled(ro); + merge_checkbox -> setDisabled(ro); color_button -> setDisabled(ro); dashed_checkbox -> setDisabled(ro); // if the widget is not read-only, we still need to disable some widgets for consistency diff --git a/sources/conductorpropertieswidget.h b/sources/conductorpropertieswidget.h index 61edef5fe..c520e836b 100644 --- a/sources/conductorpropertieswidget.h +++ b/sources/conductorpropertieswidget.h @@ -72,6 +72,7 @@ class ConductorPropertiesWidget : public QWidget { QLabel *preview; QPushButton *color_button; QCheckBox *dashed_checkbox; + QCheckBox *merge_checkbox; ConductorProperties properties_;