Files
qelectrotech-source-mirror/sources/ui/conductorpropertieswidget.cpp
T
ispyisail 82fc56c5e6 Fix Project properties > OK marking the project modified with no edit
Pressing OK in Projet > Propriétés du projet without changing anything
marked the project modified and rewrote its defaults for new folios.
Besides the Page Num placeholder (fixed separately), four causes:

- Title block custom fields: since #271 the dialog offers the
  template's variables for filling in; those left empty came back as
  part of the context. Drop the ones not in the stored context.
- DiagramContext::remove() left the key's show flag behind, so a
  context with a key removed never equalled one without it.
- Guides: applyConf() marked the project modified whether or not the
  guides changed. Compare them like every other setting.
- Wire dash size and cross-reference offsets: the spin boxes cannot
  show the stored default (dash size 1 under a minimum of 2; offset 0
  under a minimum of 40 shown as "Default"), so the clamped value came
  back. Keep the stored value unless the box shows something else, as
  #1204 did for the wire panel.

Checked in the GUI (with the Page Num fix as well) on grafcet,
schema_indus and Projet_vierge: OK with no edit then Ctrl+S saves the
same file as Ctrl+S alone; master writes dash-size 1 -> 2, a
cross-reference offset 0 -> 40, and on Projet_vierge 22 empty custom
fields. New test for DiagramContext::remove() fails without the fix.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 21:04:54 +13:00

381 lines
14 KiB
C++

/*
Copyright 2006-2026 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 "conductorpropertieswidget.h"
#include "../conductorproperties.h"
#include "../qetapp.h"
#include "../qtextorientationspinboxwidget.h"
#include "ui_conductorpropertieswidget.h"
/**
@brief ConductorPropertiesWidget::ConductorPropertiesWidget
Constructor
@param parent : paretn widget
*/
ConductorPropertiesWidget::ConductorPropertiesWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::ConductorPropertiesWidget)
{
ui->setupUi(this);
initWidget();
}
/**
@brief ConductorPropertiesWidget::ConductorPropertiesWidget
Constructor with properties
@param properties : properties to edit
@param parent : parent widget
*/
ConductorPropertiesWidget::ConductorPropertiesWidget(
const ConductorProperties &properties,
QWidget *parent) :
QWidget(parent),
ui(new Ui::ConductorPropertiesWidget)
{
ui -> setupUi(this);
initWidget();
setProperties(properties);
}
/**
@brief ConductorPropertiesWidget::~ConductorPropertiesWidget
destructor
*/
ConductorPropertiesWidget::~ConductorPropertiesWidget()
{
delete ui;
}
/**
@brief ConductorPropertiesWidget::setProperties
Set the properties
@param properties
*/
void ConductorPropertiesWidget::setProperties(
const ConductorProperties &properties)
{
if (m_properties == properties)
return;
m_properties = properties;
int index = ui -> m_line_style_cb -> findData(QPen(m_properties.style));
if (index != -1) ui -> m_line_style_cb -> setCurrentIndex(index);
ui->m_color_2_gb -> setChecked (m_properties.m_bicolor);
ui->m_dash_size_sb -> setValue (m_properties.m_dash_size);
ui->m_formula_le -> setText (m_properties.m_formula);
ui->m_text_le -> setText (m_properties.text);
ui->m_function_le -> setText (m_properties.m_function);
ui->m_cable_le -> setText (m_properties.m_cable);
ui->m_bus_le -> setText (m_properties.m_bus);
ui->m_tension_protocol_le -> setText (m_properties.m_tension_protocol);
ui->m_wire_color_le -> setText (m_properties.m_wire_color);
ui->m_wire_section_le -> setText (m_properties.m_wire_section);
ui->m_text_size_sb -> setValue (m_properties.text_size);
ui->m_cond_size_sb -> setValue (m_properties.cond_size);
ui->m_show_text_cb -> setChecked (m_properties.m_show_text);
ui->m_one_text_per_folio_cb -> setChecked (m_properties.m_one_text_per_folio);
ui->m_earth_cb -> setChecked (m_properties.singleLineProperties.hasGround);
ui->m_neutral_cb -> setChecked (m_properties.singleLineProperties.hasNeutral);
ui->m_pen_cb -> setChecked (m_properties.singleLineProperties.isPen());
ui->m_phase_cb -> setChecked (m_properties.singleLineProperties.phasesCount());
ui->m_phase_slider -> setValue (m_properties.singleLineProperties.phasesCount());
ui->m_color_kpb -> setColor(m_properties.color);
ui->m_color_2_kpb -> setColor(m_properties.m_color_2);
ui->m_text_color_kpb -> setColor(m_properties.text_color);
ui->m_horiz_cb->setCurrentIndex(m_properties.m_horizontal_alignment == Qt::AlignTop? 0 : 1);
ui->m_verti_cb->setCurrentIndex(m_properties.m_vertical_alignment == Qt::AlignLeft? 0 : 1);
m_verti_select -> setValue (m_properties.verti_rotate_text);
m_horiz_select -> setValue (m_properties.horiz_rotate_text);
setConductorType(m_properties.type);
updatePreview(false);
}
/**
@brief ConductorPropertiesWidget::properties
@return the edited properties
*/
ConductorProperties ConductorPropertiesWidget::properties() const
{
ConductorProperties properties_;
if (ui -> m_multiwires_gb -> isChecked()) properties_.type = ConductorProperties::Multi;
else if (ui -> m_singlewire_gb -> isChecked()) properties_.type = ConductorProperties::Single;
properties_.color = ui -> m_color_kpb->color();
properties_.m_bicolor = ui->m_color_2_gb->isChecked();
properties_.m_color_2 = ui->m_color_2_kpb->color();
properties_.m_dash_size = ui->m_dash_size_sb->value();
//The box starts at 2, so the default size 1 shows as 2: keep the
//stored size unless the box shows something else.
if (properties_.m_dash_size == qBound(ui->m_dash_size_sb->minimum(),
m_properties.m_dash_size,
ui->m_dash_size_sb->maximum()))
properties_.m_dash_size = m_properties.m_dash_size;
properties_.style = ui -> m_line_style_cb->itemData(ui->m_line_style_cb->currentIndex()).value<QPen>().style();
properties_.m_formula = ui->m_formula_le->text();
properties_.text = ui -> m_text_le -> text();
properties_.text_color = ui -> m_text_color_kpb->color();
properties_.m_function = ui -> m_function_le->text();
properties_.m_cable = ui -> m_cable_le->text();
properties_.m_bus = ui -> m_bus_le->text();
properties_.m_tension_protocol = ui -> m_tension_protocol_le->text();
properties_.m_wire_color = ui -> m_wire_color_le->text();
properties_.m_wire_section = ui -> m_wire_section_le->text();
properties_.text_size = ui -> m_text_size_sb -> value();
properties_.cond_size = ui -> m_cond_size_sb -> value();
properties_.m_show_text = ui -> m_show_text_cb -> isChecked();
properties_.m_one_text_per_folio = ui -> m_one_text_per_folio_cb -> isChecked();
properties_.verti_rotate_text = m_verti_select -> value();
properties_.horiz_rotate_text = m_horiz_select -> value();
properties_.m_vertical_alignment = ui->m_verti_cb->currentIndex() == 0? Qt::AlignLeft : Qt::AlignRight;
properties_.m_horizontal_alignment = ui->m_horiz_cb->currentIndex() == 0? Qt::AlignTop : Qt::AlignBottom;
properties_.singleLineProperties.hasGround = ui -> m_earth_cb -> isChecked();
properties_.singleLineProperties.hasNeutral = ui -> m_neutral_cb -> isChecked();
properties_.singleLineProperties.is_pen = ui -> m_pen_cb -> isChecked();
properties_.singleLineProperties.setPhasesCount(ui -> m_phase_cb -> isChecked() ? ui -> m_phase_sb -> value() : 0);
return properties_;
}
/**
@brief ConductorPropertiesWidget::event
@param event
@return
*/
bool ConductorPropertiesWidget::event(QEvent *event)
{
if (event->type() == QEvent::WindowActivate) {
ui -> m_formula_le -> setFocus();
}
return(QWidget::event(event));
}
/**
@brief ConductorPropertiesWidget::setReadOnly
@param ro if true this widget is disabled
*/
void ConductorPropertiesWidget::setReadOnly(const bool &ro) {
this->setDisabled(ro);
}
/**
@brief ConductorPropertiesWidget::addAutonumWidget
@param widget
*/
void ConductorPropertiesWidget::addAutonumWidget(QWidget *widget) {
ui->m_autonum_layout->addWidget(widget);
}
/**
@brief ConductorPropertiesWidget::setHiddenOneTextPerFolio
@param hide
*/
void ConductorPropertiesWidget::setHiddenOneTextPerFolio(const bool &hide) {
ui -> m_one_text_per_folio_cb -> setHidden(hide);
}
/**
@brief ConductorPropertiesWidget::setMixedTextFields
Mark the text fields whose value differs between several edited
conductors: they are shown blank, with a hint saying why.
@param mixed
*/
void ConductorPropertiesWidget::setMixedTextFields(
const QList<ConductorMultiEdit::TextField> &mixed)
{
using namespace ConductorMultiEdit;
const QList<QPair<TextField, QLineEdit *>> edits {
{Text, ui->m_text_le},
{Formula, ui->m_formula_le},
{Function, ui->m_function_le},
{TensionProtocol, ui->m_tension_protocol_le},
{WireColor, ui->m_wire_color_le},
{WireSection, ui->m_wire_section_le},
{Cable, ui->m_cable_le},
{Bus, ui->m_bus_le}};
for (const auto &edit : edits)
edit.second->setPlaceholderText(mixed.contains(edit.first)
? tr("Plusieurs valeurs", "several conductors, different values")
: QString());
}
/**
@brief ConductorPropertiesWidget::setTextLocked
Lock the conductor text while several conductors are edited at once:
the same number on all of them would make duplicates.
@param locked
*/
void ConductorPropertiesWidget::setTextLocked(bool locked)
{
m_text_locked = locked;
ui->m_text_le->setEnabled(!locked && ui->m_formula_le->text().isEmpty());
ui->m_text_le->setToolTip(locked
? tr("Plusieurs conducteurs sélectionnés : le texte se modifie "
"sur un seul conducteur à la fois.")
: tr("Texte"));
}
/**
@brief ConductorPropertiesWidget::setDisabledShowText
@param disable
*/
void ConductorPropertiesWidget::setDisabledShowText(const bool &disable) {
ui->m_show_text_cb->setDisabled(disable==true? true : false);
//Say why the box is locked: the setting that locks it is not in this dialog
ui->m_show_text_cb->setToolTip(disable
? tr("Texte visible\n"
"Verrouillé par l'option « Afficher un texte de potentiel par "
"folio » de ce folio, dans Propriétés du folio.")
: tr("Texte visible"));
}
/**
@brief ConductorPropertiesWidget::setHiddenAvailableAutonum
Hide the label, combo box and push button of available autonum
@param hide
*/
void ConductorPropertiesWidget::setHiddenAvailableAutonum(const bool &hide)
{
ui->m_autonum_label->setHidden(hide);
ui->m_available_autonum_cb->setHidden(hide);
ui->m_edit_autonum_pb->setHidden(hide);
}
QComboBox *ConductorPropertiesWidget::autonumComboBox() const
{
return ui->m_available_autonum_cb;
}
QPushButton *ConductorPropertiesWidget::editAutonumPushButton() const
{
return ui->m_edit_autonum_pb;
}
/**
@brief ConductorPropertiesWidget::initWidget
*/
void ConductorPropertiesWidget::initWidget()
{
m_verti_select = QETApp::createTextOrientationSpinBoxWidget();
ui -> m_text_angle_gl -> addWidget(m_verti_select, 2, 0, Qt::AlignHCenter);
m_horiz_select = QETApp::createTextOrientationSpinBoxWidget();
ui -> m_text_angle_gl -> addWidget(m_horiz_select, 2, 1, Qt::AlignHCenter);
ui -> m_line_style_cb -> addItem(tr("Trait plein", "conductor style: solid line"), QPen(Qt::SolidLine));
ui -> m_line_style_cb -> addItem(tr("Trait en pointillés", "conductor style: dashed line"), QPen(Qt::DashLine));
ui -> m_line_style_cb -> addItem(tr("Traits et points", "conductor style: dashed and dotted line"), QPen(Qt::DashDotLine));
ui -> m_update_preview_pb -> setHidden(true);
connect(ui->m_multiwires_gb, &QGroupBox::toggled, [this](bool toggle) {this->ui->m_singlewire_gb->setChecked(!toggle);});
connect(ui->m_singlewire_gb, &QGroupBox::toggled, [this](bool toggle) {this->ui->m_multiwires_gb->setChecked(!toggle);});
connect(ui->m_formula_le, &QLineEdit::textChanged, [this](QString text) {this->ui->m_text_le->setEnabled(!m_text_locked && text.isEmpty());});
ui->m_multiwires_gb->setChecked(true);
ui->m_singlewire_gb->setChecked(true);
#if TODO_LIST
#pragma message("@TODO Add Kabel and Bus to qet")
#else
ui->m_cable_le->setDisabled(true);
ui->m_bus_le->setDisabled(true);
#endif
}
/**
@brief ConductorPropertiesWidget::setConductorType
Update this widget to the new conductor type
@param type
*/
void ConductorPropertiesWidget::setConductorType(ConductorProperties::ConductorType type) {
switch (type) {
case ConductorProperties::Multi:
ui -> m_multiwires_gb -> setChecked(true);
break;
case ConductorProperties::Single:
ui -> m_singlewire_gb -> setChecked(true);
break;
default:
ui -> m_multiwires_gb -> setChecked(true);
break;
}
}
/**
@brief ConductorPropertiesWidget::updatePreview
Update the preview for single lien
@param b true: update from the value displayed by this widget
false: update from the properties given at the constructor of this widget
*/
void ConductorPropertiesWidget::updatePreview(bool b) {
const QRect pixmap_rect(0, 0, 96, 96);
QPixmap pixmap(pixmap_rect.width(), pixmap_rect.height());
QPainter painter;
painter.begin(&pixmap);
painter.eraseRect(pixmap_rect);
painter.drawRect(pixmap_rect.adjusted(0,0,-1,-1));
painter.drawLine(QLineF(0, pixmap_rect.height() / 2, pixmap_rect.width(), pixmap_rect.height() / 2));
if (b) properties().singleLineProperties.draw(&painter, QET::Horizontal, pixmap_rect);
else m_properties.singleLineProperties.draw(&painter, QET::Horizontal, pixmap_rect);
painter.end();
ui -> m_preview_label -> setPixmap(pixmap);
}
/**
@brief ConductorPropertiesWidget::on_m_earth_cb_toggled
Update the widget when toggled
@param checked
*/
void ConductorPropertiesWidget::on_m_earth_cb_toggled(bool checked) {
if (checked && ui -> m_neutral_cb -> isChecked())
ui -> m_pen_cb -> setEnabled(true);
else ui -> m_pen_cb -> setDisabled(true);
}
/**
@brief ConductorPropertiesWidget::on_m_neutral_cb_toggled
Update the widget when toggled
@param checked
*/
void ConductorPropertiesWidget::on_m_neutral_cb_toggled(bool checked) {
if (checked && ui -> m_earth_cb -> isChecked())
ui -> m_pen_cb -> setEnabled(true);
else ui -> m_pen_cb -> setDisabled(true);
}
/**
@brief ConductorPropertiesWidget::on_m_update_preview_pb_clicked
Update the preview of single line.
m_update_preview_pb is a no used button and hidden, his role is only
to centralize signal from various widget to edit single ligne properties,
for update the preview
*/
void ConductorPropertiesWidget::on_m_update_preview_pb_clicked()
{
updatePreview();
}