mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-09 13:34:14 +02:00
f5962ecd06
Every tr() source string in the code and the forms is now the English
text, and French is a translation (qet_fr.ts) like the other languages.
Generated, not hand-edited: master ef795a21e5 converted by
qet-en-source (harness 4c4ddc9).
3144 messages get an English source, 665 already had one, 0 left French; 8 shared-wording pairs disambiguated.
C++: 2904 literals in 233 files. Forms: 809 strings in 65 files. All 34 .ts files re-keyed; qet_fr.ts filled.
lupdate check: PASS. What each of 38 languages shows, old vs new: same 118266, English instead of French 38433, comment fallback 51, differences 0.
1148 lines
37 KiB
C++
1148 lines
37 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 "elementinfowidget.h"
|
|
#include "../qet.h"
|
|
#include <QCheckBox>
|
|
#include <QComboBox>
|
|
#include <QHBoxLayout>
|
|
#include <QLabel>
|
|
#include <QMessageBox>
|
|
#include <QPushButton>
|
|
#include "../autoNum/elementautonumschemecommand.h"
|
|
#include "../undocommand/freezeelementlabelcommand.h"
|
|
#include "../diagram.h"
|
|
#include "../materiallist/materiallist.h"
|
|
#include "../materiallist/materialselectiondialog.h"
|
|
#include "../qetapp.h"
|
|
#include "../qetgraphicsitem/element.h"
|
|
#include "../qetmessagebox.h"
|
|
#include "../dataBase/projectdatabase.h"
|
|
#include "../qetinformation.h"
|
|
#include "../qetproject.h"
|
|
#include "../ui/projectpropertiesdialog.h"
|
|
#include "../ui_elementinfowidget.h"
|
|
#include "../undocommand/changeelementinformationcommand.h"
|
|
#include "customelementinfopartwidget.h"
|
|
#include "elementinfopartwidget.h"
|
|
|
|
/**
|
|
@brief ElementInfoWidget::ElementInfoWidget
|
|
Constructor
|
|
@param elmt element to edit information
|
|
@param parent parent widget
|
|
*/
|
|
ElementInfoWidget::ElementInfoWidget(Element *elmt, QWidget *parent) :
|
|
AbstractElementPropertiesEditorWidget(parent),
|
|
ui(new Ui::ElementInfoWidget),
|
|
m_first_activation (false)
|
|
{
|
|
ui->setupUi(this);
|
|
setElement(elmt);
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::~ElementInfoWidget
|
|
Destructor
|
|
*/
|
|
ElementInfoWidget::~ElementInfoWidget()
|
|
{
|
|
qDeleteAll(m_eipw_list);
|
|
qDeleteAll(m_custom_eipw_list);
|
|
delete ui;
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::setElement
|
|
Set element to be the edited element
|
|
@param element
|
|
*/
|
|
void ElementInfoWidget::setElement(Element *element)
|
|
{
|
|
if (m_element == element) return;
|
|
|
|
if (m_element)
|
|
disconnect(m_element.data(), &Element::elementInfoChange, this, &ElementInfoWidget::elementInfoChange);
|
|
|
|
m_element = element;
|
|
updateUi();
|
|
|
|
const auto formula_info_widget = infoPartWidgetForKey(QETInformation::ELMT_FORMULA);
|
|
const auto label_info_widget = infoPartWidgetForKey(QETInformation::ELMT_LABEL);
|
|
|
|
if (formula_info_widget && label_info_widget)
|
|
{
|
|
if (formula_info_widget->text().isEmpty())
|
|
label_info_widget->setEnabled(true);
|
|
else
|
|
label_info_widget->setDisabled(true);
|
|
|
|
connect(formula_info_widget, &ElementInfoPartWidget::textChanged, this, [label_info_widget](const QString text)
|
|
{
|
|
label_info_widget->setEnabled(text.isEmpty()? true : false);
|
|
});
|
|
}
|
|
|
|
connect(m_element.data(), &Element::elementInfoChange, this, &ElementInfoWidget::elementInfoChange);
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::apply
|
|
Apply the new information with a new undo command (got with method associatedUndo)
|
|
pushed to the stack of element project.
|
|
*/
|
|
void ElementInfoWidget::apply()
|
|
{
|
|
if (auto undo = associatedUndo())
|
|
m_element -> diagram() -> undoStack().push(undo);
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::associatedUndo
|
|
If the edited info is different of the actual element info,
|
|
return a QUndoCommand with the change.
|
|
If no change return nullptr;
|
|
@return
|
|
*/
|
|
QUndoCommand* ElementInfoWidget::associatedUndo() const
|
|
{
|
|
auto new_info = currentInfo();
|
|
const auto old_info = m_element -> elementInformations();
|
|
|
|
const bool was_frozen = m_element->isFreezeLabel();
|
|
const bool want_frozen = m_freeze_cb ? m_freeze_cb->isChecked() : was_frozen;
|
|
|
|
//A numbering chosen in the list is given to the element the way
|
|
//a placed one gets it: its formula, and the next number of the
|
|
//numbering, which moves on. That is a command of its own, first,
|
|
//so the other edited fields are changed on top of its result.
|
|
const QString chosen = chosenScheme();
|
|
const bool assign_wanted = !chosen.isEmpty()
|
|
&& chosen != followedScheme()
|
|
&& m_element->diagram();
|
|
//A number picked among the free ones, for an element which keeps its numbering
|
|
const bool number_wanted = !assign_wanted && m_number_cb && m_number_row
|
|
&& !m_number_row->isHidden() && m_number_cb->isEnabled()
|
|
&& m_number_cb->currentData().toInt() > 0
|
|
&& m_number_cb->currentData().toInt() != m_number_current
|
|
&& m_element->diagram();
|
|
|
|
if (!assign_wanted && !number_wanted && was_frozen == want_frozen)
|
|
{
|
|
if (old_info != new_info)
|
|
return (new ChangeElementInformationCommand(m_element, old_info, new_info));
|
|
return nullptr;
|
|
}
|
|
|
|
auto *macro = new QUndoCommand(
|
|
QObject::tr("Edit information of the element : %1")
|
|
.arg(m_element->name()));
|
|
DiagramContext base_info = old_info;
|
|
bool state_frozen = was_frozen;
|
|
|
|
if (assign_wanted || number_wanted)
|
|
{
|
|
RenumberElementsCommand *assign = assign_wanted
|
|
? ElementAutoNumSchemeCommand::assign(
|
|
m_element->diagram()->project(), chosen,
|
|
{m_element.data()}, true, nullptr, macro)
|
|
: ElementAutoNumSchemeCommand::assignNumber(
|
|
m_element->diagram()->project(), m_element.data(),
|
|
m_number_cb->currentData().toInt(), nullptr, macro);
|
|
if (assign && !assign->changes().isEmpty())
|
|
{
|
|
const auto &change = assign->changes().first();
|
|
base_info = change.new_infos;
|
|
state_frozen = change.new_frozen;
|
|
for (const QString &key : {QETInformation::ELMT_FORMULA,
|
|
QETInformation::ELMT_FORMULA_ID,
|
|
QETInformation::ELMT_LABEL}) {
|
|
if (base_info.contains(key)) {
|
|
new_info.addValue(key, base_info.value(key), key != QETInformation::ELMT_FORMULA_ID);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (base_info != new_info) {
|
|
new ChangeElementInformationCommand(m_element, base_info, new_info, macro);
|
|
}
|
|
if (state_frozen != want_frozen) {
|
|
new FreezeElementLabelCommand(m_element, state_frozen, want_frozen, macro);
|
|
}
|
|
|
|
if (macro->childCount() == 0) {
|
|
delete macro;
|
|
return nullptr;
|
|
}
|
|
return macro;
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::setLiveEdit
|
|
@param live_edit true : enable the live edit mode, false disable
|
|
@return always true;
|
|
*/
|
|
bool ElementInfoWidget::setLiveEdit(bool live_edit)
|
|
{
|
|
if (m_live_edit == live_edit) return true;
|
|
m_live_edit = live_edit;
|
|
|
|
if (m_live_edit)
|
|
enableLiveEdit();
|
|
else
|
|
disableLiveEdit();
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::event
|
|
Reimplemented from QWidget::event
|
|
Only give focus to the first line edit at first activation.
|
|
After send the event to QWidget.
|
|
@param event
|
|
@return
|
|
*/
|
|
bool ElementInfoWidget::event(QEvent *event)
|
|
{
|
|
if (m_first_activation)
|
|
{
|
|
if (event -> type() == QEvent::WindowActivate || event -> type() == QEvent::Show)
|
|
{
|
|
QTimer::singleShot(250, this, &ElementInfoWidget::firstActivated);
|
|
m_first_activation = false;
|
|
}
|
|
}
|
|
return(QWidget::event(event));
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::enableLiveEdit
|
|
Enable the live edit mode
|
|
*/
|
|
void ElementInfoWidget::enableLiveEdit()
|
|
{
|
|
for (ElementInfoPartWidget *eipw : m_eipw_list)
|
|
connect(eipw, &ElementInfoPartWidget::textChanged, this, &ElementInfoWidget::apply);
|
|
connect(ui->m_auto_num_locked_cb, &QCheckBox::clicked, this, &ElementInfoWidget::apply);
|
|
|
|
if (m_potential_isolating_cb) {
|
|
connect(m_potential_isolating_cb, &QCheckBox::clicked, this, &ElementInfoWidget::apply);
|
|
}
|
|
if (m_exclude_from_bom_cb) {
|
|
connect(m_exclude_from_bom_cb, &QCheckBox::clicked, this, &ElementInfoWidget::apply);
|
|
}
|
|
if (m_freeze_cb) {
|
|
connect(m_freeze_cb, &QCheckBox::clicked, this, &ElementInfoWidget::apply);
|
|
}
|
|
if (m_number_cb) {
|
|
connect(m_number_cb, QOverload<int>::of(&QComboBox::activated), this, &ElementInfoWidget::apply);
|
|
}
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::disableLiveEdit
|
|
disable the live edit mode
|
|
*/
|
|
void ElementInfoWidget::disableLiveEdit()
|
|
{
|
|
for (ElementInfoPartWidget *eipw : m_eipw_list)
|
|
disconnect(eipw, &ElementInfoPartWidget::textChanged, this, &ElementInfoWidget::apply);
|
|
disconnect(ui->m_auto_num_locked_cb, &QCheckBox::clicked, this, &ElementInfoWidget::apply);
|
|
|
|
if (m_potential_isolating_cb) {
|
|
disconnect(m_potential_isolating_cb, &QCheckBox::clicked, this, &ElementInfoWidget::apply);
|
|
}
|
|
if (m_freeze_cb) {
|
|
disconnect(m_freeze_cb, &QCheckBox::clicked, this, &ElementInfoWidget::apply);
|
|
}
|
|
if (m_number_cb) {
|
|
disconnect(m_number_cb, QOverload<int>::of(&QComboBox::activated), this, &ElementInfoWidget::apply);
|
|
}
|
|
if (m_exclude_from_bom_cb) {
|
|
disconnect(m_exclude_from_bom_cb, &QCheckBox::clicked, this, &ElementInfoWidget::apply);
|
|
}
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::buildInterface
|
|
Build the widget
|
|
*/
|
|
void ElementInfoWidget::buildInterface()
|
|
{
|
|
QStringList keys;
|
|
if (m_element.data()->elementData().m_type == ElementData::Terminal) {
|
|
keys = QETInformation::terminalElementInfoKeys();
|
|
} else {
|
|
keys = QETInformation::elementInfoKeys();
|
|
}
|
|
|
|
//"exclude_from_bom" is part of elementInfoKeys() because the project
|
|
//database builds the element_info table from that list, but it is not
|
|
//a free-text property: it already has its own check box below. Without
|
|
//this it also gets a generic edit row, and since translatedInfoKey()
|
|
//has no entry for it that row carries no label at all - an anonymous
|
|
//line that currentInfo() then fills with "true"/"false".
|
|
keys.removeAll(QStringLiteral("exclude_from_bom"));
|
|
|
|
for (auto str : keys)
|
|
{
|
|
ElementInfoPartWidget *eipw = new ElementInfoPartWidget(str, QETInformation::translatedInfoKey(str), this);
|
|
ui->scroll_vlayout->addWidget(eipw);
|
|
m_eipw_list << eipw;
|
|
}
|
|
|
|
setupMaterialButtons();
|
|
setupSchemeRow();
|
|
setupNumberRow();
|
|
setupFreezeRow();
|
|
|
|
m_add_custom_property_btn = new QPushButton(tr("Add a custom property"), this);
|
|
connect(m_add_custom_property_btn, &QPushButton::clicked, this, [this]() { addCustomProperty(); });
|
|
ui->scroll_vlayout->addWidget(m_add_custom_property_btn);
|
|
|
|
ui->scroll_vlayout->addStretch();
|
|
|
|
// Existing potential isolating checkbox
|
|
m_potential_isolating_cb = new QCheckBox(tr("Potential separation"), this);
|
|
m_potential_isolating_cb->setStyleSheet(QStringLiteral("margin: 5px; font-weight: bold;"));
|
|
|
|
// English: Initialize and style the BOM exclusion checkbox
|
|
m_exclude_from_bom_cb = new QCheckBox(tr("Exclude from the bill of materials"), this);
|
|
m_exclude_from_bom_cb->setStyleSheet(QStringLiteral("margin: 5px; font-weight: bold;"));
|
|
|
|
if (QVBoxLayout *mainLayout = qobject_cast<QVBoxLayout*>(this->layout())) {
|
|
mainLayout->insertWidget(1, m_potential_isolating_cb);
|
|
// English: Insert the new checkbox into the main vertical layout
|
|
mainLayout->insertWidget(2, m_exclude_from_bom_cb);
|
|
}
|
|
|
|
// English: BOM exclusion applies to all elements, so it's always visible
|
|
m_exclude_from_bom_cb->setVisible(true);
|
|
|
|
// Show checkbox only if the element is a terminal
|
|
if (m_element.data()->elementData().m_type == ElementData::Terminal) {
|
|
ui->m_auto_num_locked_cb->setVisible(true);
|
|
m_potential_isolating_cb->setVisible(true);
|
|
} else {
|
|
ui->m_auto_num_locked_cb->setVisible(false);
|
|
m_potential_isolating_cb->setVisible(false);
|
|
}
|
|
}
|
|
/**
|
|
@brief ElementInfoWidget::predefinedKeys
|
|
@return every key this widget already exposes a dedicated row for,
|
|
whether through ElementInfoPartWidget (the ~40 ELMT_* keys) or one
|
|
of the standalone checkboxes. Anything present in the element's
|
|
informations but absent from this list is a user-defined custom
|
|
property.
|
|
*/
|
|
QStringList ElementInfoWidget::predefinedKeys() const
|
|
{
|
|
QStringList keys = (m_element.data()->elementData().m_type == ElementData::Terminal)
|
|
? QETInformation::terminalElementInfoKeys()
|
|
: QETInformation::elementInfoKeys();
|
|
|
|
keys << QETInformation::ELMT_FORMULA_ID
|
|
<< QStringLiteral("auto_num_locked")
|
|
<< QStringLiteral("potential_isolating")
|
|
<< QStringLiteral("exclude_from_bom");
|
|
|
|
return keys;
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::addCustomProperty
|
|
Append a new user-defined key/value row to the widget.
|
|
@param key initial key, left empty for a freshly added row
|
|
@param value initial value
|
|
*/
|
|
void ElementInfoWidget::addCustomProperty(const QString &key, const QString &value)
|
|
{
|
|
auto *widget = new CustomElementInfoPartWidget(key, value, this);
|
|
|
|
const int insert_index = ui->scroll_vlayout->indexOf(m_add_custom_property_btn);
|
|
ui->scroll_vlayout->insertWidget(insert_index >= 0 ? insert_index : ui->scroll_vlayout->count(), widget);
|
|
m_custom_eipw_list << widget;
|
|
|
|
connect(widget, &CustomElementInfoPartWidget::removeRequested, this, &ElementInfoWidget::removeCustomProperty);
|
|
connect(widget, &CustomElementInfoPartWidget::changed, this, [this]() {
|
|
if (m_live_edit) apply();
|
|
});
|
|
|
|
if (key.isEmpty()) {
|
|
widget->setFocus();
|
|
}
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::removeCustomProperty
|
|
Remove a user-defined key/value row.
|
|
@param widget the row to remove
|
|
*/
|
|
void ElementInfoWidget::removeCustomProperty(CustomElementInfoPartWidget *widget)
|
|
{
|
|
if (!m_custom_eipw_list.removeOne(widget))
|
|
return;
|
|
|
|
ui->scroll_vlayout->removeWidget(widget);
|
|
widget->deleteLater();
|
|
|
|
if (m_live_edit) apply();
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::infoPartWidgetForKey
|
|
@param key
|
|
@return the ElementInfoPartWidget with key key,
|
|
if not found return nullptr;
|
|
*/
|
|
ElementInfoPartWidget *ElementInfoWidget::infoPartWidgetForKey(const QString &key) const
|
|
{
|
|
for (const auto &eipw : std::as_const(m_eipw_list))
|
|
{
|
|
if (eipw->key() == key)
|
|
return eipw;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::setupMaterialButtons
|
|
Show the "..." button opening the material file on the description row
|
|
of each block: one for the main article, one per auxiliary article
|
|
which really has a description row.
|
|
|
|
Only that row carries the button: the same window fills the whole
|
|
block, so repeating it on every field of the block would just offer
|
|
five ways to do the same thing.
|
|
*/
|
|
void ElementInfoWidget::setupMaterialButtons()
|
|
{
|
|
auto register_button = [this](ElementInfoPartWidget *eipw, int block)
|
|
{
|
|
eipw->setMaterialButtonVisible(true);
|
|
connect(eipw, &ElementInfoPartWidget::materialButtonClicked, this,
|
|
[this, block]() { materialFromFile(block); });
|
|
};
|
|
|
|
//Main article. A terminal has no description row: its article
|
|
//number is the one which identifies it, so the button sits there.
|
|
if (ElementInfoPartWidget *eipw = infoPartWidgetForKey(QETInformation::ELMT_DESCRIPTION)) {
|
|
register_button(eipw, 0);
|
|
} else if (ElementInfoPartWidget *eipw = infoPartWidgetForKey(QETInformation::ELMT_DESIGNATION)) {
|
|
register_button(eipw, 0);
|
|
}
|
|
|
|
//Auxiliary articles 1 to 4.
|
|
const QStringList auxiliary_keys = {
|
|
QETInformation::ELMT_DESCRIPTION_AUX1,
|
|
QETInformation::ELMT_DESCRIPTION_AUX2,
|
|
QETInformation::ELMT_DESCRIPTION_AUX3,
|
|
QETInformation::ELMT_DESCRIPTION_AUX4
|
|
};
|
|
|
|
for (int block = 1; block <= 4 && block <= auxiliary_keys.size(); ++block)
|
|
{
|
|
if (ElementInfoPartWidget *eipw = infoPartWidgetForKey(auxiliary_keys.at(block - 1))) {
|
|
register_button(eipw, block);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::materialFromFile
|
|
Open the material file, let the user pick an article, and write it
|
|
into the block the button belongs to.
|
|
@param block 0 for the main article, 1 to 4 for an auxiliary article
|
|
*/
|
|
void ElementInfoWidget::materialFromFile(int block)
|
|
{
|
|
//Nothing configured yet: the standard location is used, the same
|
|
//one the preferences offer to create, so that the catalogue can be
|
|
//reached from here without asking for a file to be saved first.
|
|
QString path = MaterialList::configuredPath();
|
|
if (path.isEmpty())
|
|
{
|
|
path = MaterialList::defaultPath();
|
|
MaterialList::setConfiguredPath(path);
|
|
}
|
|
|
|
//A missing or empty file has no entry to pick: offer to write the
|
|
//header line instead of opening an empty window.
|
|
if (MaterialList::isEmptyFile(path))
|
|
{
|
|
const auto answer = QET::QetMessageBox::question(
|
|
this,
|
|
tr("No materials list"),
|
|
tr("There is no materials list file at this location:\n"
|
|
"%1\n"
|
|
"\n"
|
|
"Create it?", "message asking to create the material file").arg(path),
|
|
QMessageBox::Yes | QMessageBox::No,
|
|
QMessageBox::Yes);
|
|
|
|
if (answer != QMessageBox::Yes) {
|
|
return;
|
|
}
|
|
|
|
QString error;
|
|
if (!MaterialList::createFile(path, &error))
|
|
{
|
|
QET::QetMessageBox::critical(this,
|
|
tr("Cannot create"),
|
|
tr("Cannot create the file:\n%1\n%2")
|
|
.arg(path, error));
|
|
return;
|
|
}
|
|
}
|
|
|
|
//The catalogue opens on the whole list : the search field starts
|
|
//empty, whatever the block already holds.
|
|
MaterialSelectionDialog dialog(path, this);
|
|
if (dialog.exec() == QDialog::Accepted) {
|
|
applyMaterialRecord(dialog.selectedRecord(), block);
|
|
}
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::applyMaterialRecord
|
|
Write a catalogue entry into the fields of one block.
|
|
|
|
Only the fields of that block are touched: applied to an auxiliary
|
|
article, the entry never reaches the main article.
|
|
|
|
An empty cell of a column describing the article (MaterialList::
|
|
isArticleBound) clears the field: keeping the manufacturer of the
|
|
article picked before would describe a part which does not exist.
|
|
An empty cell of any other column, and any column the file does not
|
|
hold at all, leaves the field alone, so picking an entry describing
|
|
only the order reference never wipes a comment.
|
|
@param record the entry taken from the material file
|
|
@param block 0 for the main article, 1 to 4 for an auxiliary article
|
|
*/
|
|
void ElementInfoWidget::applyMaterialRecord(const MaterialRecord &record, int block)
|
|
{
|
|
if (record.values.isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
//Fill the fields without letting the live edit push one undo
|
|
//command per line edit: the whole entry must be undoable at once.
|
|
const bool live_edit = m_live_edit;
|
|
if (live_edit) {
|
|
disableLiveEdit();
|
|
}
|
|
|
|
for (const QString &column : MaterialList::columnsForBlock(block))
|
|
{
|
|
//A column the file does not hold says nothing about the
|
|
//article: the field of the element stays as it is.
|
|
if (!record.values.contains(column)) {
|
|
continue;
|
|
}
|
|
|
|
const QString value = record.value(column);
|
|
|
|
//An empty cell only matters for the columns describing the
|
|
//article itself, where the previous value belongs to another
|
|
//part. For the others (function, comment, quantity...) an
|
|
//empty cell means the file has nothing to say about them.
|
|
if (value.isEmpty() && !MaterialList::isArticleBound(column)) {
|
|
continue;
|
|
}
|
|
|
|
const QString key = MaterialList::elementInfoKey(column, block);
|
|
if (key.isEmpty() || !QETInformation::elementInfoKeys().contains(key)) {
|
|
continue;
|
|
}
|
|
|
|
if (ElementInfoPartWidget *eipw = infoPartWidgetForKey(key)) {
|
|
eipw->setText(value);
|
|
}
|
|
}
|
|
|
|
if (live_edit) {
|
|
enableLiveEdit();
|
|
}
|
|
|
|
//Outside of the live edit the fields only carry the article: it
|
|
//is the properties window which applies them when the user presses
|
|
//"Apply" (ElementPropertiesWidget::apply() takes the undo command
|
|
//from these very fields). Applying right away would push the change
|
|
//on the undo stack before he has decided anything, and "Cancel"
|
|
//would give the fields back but never the element.
|
|
if (live_edit) {
|
|
apply();
|
|
}
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::updateSuggestions
|
|
Offer, for each information, the values already used by the other
|
|
elements of the project (supplier, manufacturer...), so they can be
|
|
picked instead of typed again.
|
|
The values come from the project database rather than from the
|
|
diagrams, which already holds them in the element_info table.
|
|
*/
|
|
void ElementInfoWidget::updateSuggestions()
|
|
{
|
|
Diagram *diagram = m_element ? m_element->diagram() : nullptr;
|
|
QETProject *project = diagram ? diagram->project() : nullptr;
|
|
if (!project || !project->dataBase()) {
|
|
return;
|
|
}
|
|
|
|
//Only a column of element_info can be queried. The key is checked
|
|
//against that list rather than trusted, because it becomes part of
|
|
//the SQL text.
|
|
const QStringList columns = QETInformation::elementInfoKeys();
|
|
const QString uuid = m_element->uuid().toString();
|
|
|
|
for (ElementInfoPartWidget *eipw : m_eipw_list)
|
|
{
|
|
const QString key = eipw->key();
|
|
//A label identifies one element, suggesting the others is noise
|
|
if (key == QETInformation::ELMT_LABEL || !columns.contains(key)) {
|
|
continue;
|
|
}
|
|
|
|
//"Schneider" and "schneider" are offered once, spelled the way
|
|
//most elements spell it: SQLite takes the bare column v from
|
|
//the row that holds MAX(n).
|
|
QStringList values;
|
|
auto query = project->dataBase()->newQuery(QStringLiteral(
|
|
"SELECT v, MAX(n) FROM ("
|
|
"SELECT \"%1\" AS v, COUNT(*) AS n FROM element_info "
|
|
"WHERE \"%1\" IS NOT NULL AND \"%1\" != '' "
|
|
"AND element_uuid != '%2' "
|
|
"GROUP BY \"%1\") "
|
|
"GROUP BY v COLLATE NOCASE "
|
|
"ORDER BY v COLLATE NOCASE").arg(key, uuid));
|
|
while (query.next()) {
|
|
values << query.value(0).toString();
|
|
}
|
|
eipw->setSuggestions(values);
|
|
}
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::updateUi
|
|
fill information fetch in m_element_info to the
|
|
corresponding line edit
|
|
*/
|
|
void ElementInfoWidget::updateUi()
|
|
{
|
|
if (!m_ui_builded) {
|
|
buildInterface();
|
|
m_ui_builded = true;
|
|
}
|
|
//We disable live edit to avoid wrong undo when we fill the line edit with new text
|
|
if (m_live_edit) disableLiveEdit();
|
|
|
|
const auto element_info{m_element->elementInformations()};
|
|
|
|
for (ElementInfoPartWidget *eipw : m_eipw_list) {
|
|
eipw -> setText (element_info[eipw->key()].toString());
|
|
}
|
|
refreshSchemeRow();
|
|
if (m_freeze_cb) {
|
|
m_freeze_cb->setChecked(m_element->isFreezeLabel());
|
|
updateFreezeRow();
|
|
}
|
|
refreshNumberRow();
|
|
updateSuggestions();
|
|
|
|
// Rebuild the custom-property rows to match whatever
|
|
// user-defined keys this element currently carries.
|
|
while (!m_custom_eipw_list.isEmpty()) {
|
|
CustomElementInfoPartWidget *w = m_custom_eipw_list.takeLast();
|
|
ui->scroll_vlayout->removeWidget(w);
|
|
delete w;
|
|
}
|
|
const auto known_keys = predefinedKeys();
|
|
for (const QString &key : element_info.keys()) {
|
|
if (!known_keys.contains(key)) {
|
|
addCustomProperty(key, element_info[key].toString());
|
|
}
|
|
}
|
|
|
|
// Load the lock status for auto numbering
|
|
if (m_element->elementData().m_type == ElementData::Terminal) {
|
|
QString lock_value = element_info.value(QStringLiteral("auto_num_locked")).toString();
|
|
ui->m_auto_num_locked_cb->setChecked(QET::infoFlagIsTrue(lock_value));
|
|
|
|
// English: Load the potential isolating status from the element information mapping
|
|
if (m_potential_isolating_cb) {
|
|
QString isolating_value = element_info.value(QStringLiteral("potential_isolating")).toString();
|
|
m_potential_isolating_cb->setChecked(QET::infoFlagIsTrue(isolating_value));
|
|
}
|
|
}
|
|
// English: Load the BOM exclusion status from the element information mapping
|
|
if (m_exclude_from_bom_cb) {
|
|
QString exclude_bom_value = element_info.value(QStringLiteral("exclude_from_bom")).toString();
|
|
m_exclude_from_bom_cb->setChecked(QET::infoFlagIsTrue(exclude_bom_value));
|
|
}
|
|
|
|
if (m_live_edit) {
|
|
enableLiveEdit();
|
|
}
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::currentInfo
|
|
@return the info currently edited
|
|
*/
|
|
DiagramContext ElementInfoWidget::currentInfo() const
|
|
{
|
|
DiagramContext info_;
|
|
|
|
for (const auto &eipw : std::as_const(m_eipw_list))
|
|
{
|
|
if (!eipw->hasAcceptableInput())
|
|
continue;
|
|
|
|
//add value only if they're something to store
|
|
if (!eipw->text().isEmpty())
|
|
{
|
|
QString txt{eipw->text()};
|
|
//remove line feed and carriage return
|
|
txt.remove(QStringLiteral("\r"));
|
|
txt.remove(QStringLiteral("\n"));
|
|
info_.addValue(eipw->key(), txt);
|
|
}
|
|
}
|
|
|
|
for (const auto &custom : std::as_const(m_custom_eipw_list))
|
|
{
|
|
if (custom->hasValidKey() && !custom->value().isEmpty())
|
|
{
|
|
QString txt{custom->value()};
|
|
txt.remove(QStringLiteral("\r"));
|
|
txt.remove(QStringLiteral("\n"));
|
|
info_.addValue(custom->key(), txt);
|
|
}
|
|
}
|
|
|
|
// Save the auto numbering lock status
|
|
if (m_element->elementData().m_type == ElementData::Terminal) {
|
|
info_.addValue(QStringLiteral("auto_num_locked"), ui->m_auto_num_locked_cb->isChecked() ? QStringLiteral("true") : QStringLiteral("false"));
|
|
|
|
if (m_potential_isolating_cb) {
|
|
info_.addValue(QStringLiteral("potential_isolating"), m_potential_isolating_cb->isChecked() ? QStringLiteral("true") : QStringLiteral("false"));
|
|
}
|
|
}
|
|
|
|
if (m_exclude_from_bom_cb) {
|
|
info_.addValue(QStringLiteral("exclude_from_bom"), m_exclude_from_bom_cb->isChecked() ? QStringLiteral("true") : QStringLiteral("false"));
|
|
}
|
|
|
|
//The element keeps following its numbering scheme as long as its
|
|
//formula is left as it is; a formula edited by hand is its own.
|
|
const DiagramContext &elmt_info = m_element->elementInformations();
|
|
if (elmt_info.contains(QETInformation::ELMT_FORMULA_ID)
|
|
&& !info_.value(QETInformation::ELMT_FORMULA).toString().isEmpty()
|
|
&& info_.value(QETInformation::ELMT_FORMULA) == elmt_info.value(QETInformation::ELMT_FORMULA)) {
|
|
info_.addValue(QETInformation::ELMT_FORMULA_ID,
|
|
elmt_info.value(QETInformation::ELMT_FORMULA_ID), false);
|
|
}
|
|
return info_;
|
|
}
|
|
/**
|
|
@brief ElementInfoWidget::setupSchemeRow
|
|
Add above the formula the list of the numberings of the project, the
|
|
formula of the element being the one of the numbering picked there:
|
|
no formula to type, a numbering to choose, and a button to open the
|
|
numberings without leaving this window.
|
|
*/
|
|
void ElementInfoWidget::setupSchemeRow()
|
|
{
|
|
ElementInfoPartWidget *formula = infoPartWidgetForKey(QETInformation::ELMT_FORMULA);
|
|
if (!formula || !m_element || !m_element->diagram()) {
|
|
return;
|
|
}
|
|
|
|
m_scheme_row = new QWidget(this);
|
|
auto *layout = new QHBoxLayout(m_scheme_row);
|
|
layout->setContentsMargins(0, 0, 0, 0);
|
|
layout->addWidget(new QLabel(tr("Automatic numbering"), m_scheme_row));
|
|
|
|
m_scheme_cb = new QComboBox(m_scheme_row);
|
|
m_scheme_cb->setObjectName(QStringLiteral("m_scheme_cb"));
|
|
m_scheme_cb->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
|
layout->addWidget(m_scheme_cb, 1);
|
|
|
|
auto *open = new QPushButton(tr("…"), m_scheme_row);
|
|
open->setToolTip(tr("Open the project's element numberings"));
|
|
open->setMaximumWidth(32);
|
|
layout->addWidget(open);
|
|
|
|
ui->scroll_vlayout->insertWidget(ui->scroll_vlayout->indexOf(formula), m_scheme_row);
|
|
|
|
//The formula is shown, not typed: it comes from the numbering
|
|
formula->setDisabled(true);
|
|
|
|
connect(m_scheme_cb, QOverload<int>::of(&QComboBox::activated),
|
|
this, &ElementInfoWidget::schemeChosen);
|
|
connect(m_scheme_cb, QOverload<int>::of(&QComboBox::activated),
|
|
this, &ElementInfoWidget::updateNumberRow);
|
|
connect(open, &QPushButton::clicked, this, &ElementInfoWidget::openSchemePage);
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::setupFreezeRow
|
|
Add below the label a check box which freezes it: a frozen label is
|
|
not touched by the numbering of elements, and its number is not given
|
|
to another element.
|
|
*/
|
|
void ElementInfoWidget::setupFreezeRow()
|
|
{
|
|
ElementInfoPartWidget *label = infoPartWidgetForKey(QETInformation::ELMT_LABEL);
|
|
if (!label || !m_element) {
|
|
return;
|
|
}
|
|
m_freeze_cb = new QCheckBox(tr("Freeze name"), this);
|
|
m_freeze_cb->setToolTip(tr("A frozen name is not changed by automatic numbering, and its "
|
|
"number is not given to another element."));
|
|
ui->scroll_vlayout->insertWidget(ui->scroll_vlayout->indexOf(label) + 1, m_freeze_cb);
|
|
connect(m_freeze_cb, &QCheckBox::toggled, this, &ElementInfoWidget::updateNumberRow);
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::updateFreezeRow
|
|
Freezing means something for a label a formula gives: the box can be
|
|
ticked when there is one, and always unticked, so that a frozen
|
|
element can be given back.
|
|
*/
|
|
void ElementInfoWidget::updateFreezeRow()
|
|
{
|
|
ElementInfoPartWidget *formula = infoPartWidgetForKey(QETInformation::ELMT_FORMULA);
|
|
if (!m_freeze_cb || !formula) {
|
|
return;
|
|
}
|
|
m_freeze_cb->setEnabled(!formula->text().isEmpty() || m_freeze_cb->isChecked());
|
|
updateNumberRow();
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::setupNumberRow
|
|
Add under the numbering a list of the numbers the element may be given
|
|
by hand: its own, then the free ones, each with the label it would give.
|
|
For an element which follows a numbering whose numbers are one sequence.
|
|
*/
|
|
void ElementInfoWidget::setupNumberRow()
|
|
{
|
|
if (!m_scheme_row || !m_element || !m_element->diagram()) {
|
|
return;
|
|
}
|
|
m_number_row = new QWidget(this);
|
|
auto *layout = new QHBoxLayout(m_number_row);
|
|
layout->setContentsMargins(0, 0, 0, 0);
|
|
layout->addWidget(new QLabel(tr("Number"), m_number_row));
|
|
m_number_cb = new QComboBox(m_number_row);
|
|
m_number_cb->setObjectName(QStringLiteral("m_number_cb"));
|
|
m_number_cb->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
|
m_number_cb->setToolTip(tr("Only free numbers are offered: an element that must keep its real number "
|
|
"can get it back if nobody else has it."));
|
|
layout->addWidget(m_number_cb, 1);
|
|
ui->scroll_vlayout->insertWidget(ui->scroll_vlayout->indexOf(m_scheme_row) + 1, m_number_row);
|
|
m_number_row->hide();
|
|
connect(m_number_cb, QOverload<int>::of(&QComboBox::activated), this, &ElementInfoWidget::numberChosen);
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::refreshNumberRow
|
|
Fill the list of numbers: the element's own, then the free ones. Hidden
|
|
when the element follows no numbering, or one whose numbers are not one
|
|
sequence.
|
|
*/
|
|
void ElementInfoWidget::refreshNumberRow()
|
|
{
|
|
if (!m_number_cb || !m_element || !m_element->diagram()) {
|
|
return;
|
|
}
|
|
QETProject *project = m_element->diagram()->project();
|
|
const QString title = followedScheme();
|
|
const auto support = title.isEmpty()
|
|
? ElementAutoNumSchemeCommand::NumberSupport()
|
|
: ElementAutoNumSchemeCommand::numberSupport(project->elementAutoNum().value(title));
|
|
|
|
const QSignalBlocker blocker(m_number_cb);
|
|
m_number_cb->clear();
|
|
m_number_current = -1;
|
|
if (!support.supported) {
|
|
m_number_row->hide();
|
|
return;
|
|
}
|
|
if (const auto own = ElementAutoNumSchemeCommand::numberOf(support, m_element)) {
|
|
m_number_current = *own;
|
|
m_number_cb->addItem(tr("%1 (current)").arg(*own), *own);
|
|
} else {
|
|
m_number_cb->addItem(tr("— (unknown number)"), 0);
|
|
}
|
|
for (int n : ElementAutoNumSchemeCommand::freeNumbers(project, title, m_element)) {
|
|
if (n == m_number_current) continue;
|
|
m_number_cb->addItem(tr("%1 → %2").arg(n).arg(
|
|
ElementAutoNumSchemeCommand::labelForNumber(project, title, m_element, n)), n);
|
|
}
|
|
m_number_cb->setCurrentIndex(0);
|
|
m_number_row->show();
|
|
updateNumberRow();
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::updateNumberRow
|
|
A number is chosen only for an element which keeps its numbering and
|
|
whose name is not frozen.
|
|
*/
|
|
void ElementInfoWidget::updateNumberRow()
|
|
{
|
|
if (!m_number_cb || !m_number_row || m_number_row->isHidden()) {
|
|
return;
|
|
}
|
|
const bool keeps = chosenScheme() == followedScheme() && !chosenScheme().isEmpty();
|
|
const bool frozen = m_freeze_cb ? m_freeze_cb->isChecked() : m_element->isFreezeLabel();
|
|
m_number_cb->setEnabled(keeps && !frozen);
|
|
m_number_cb->setToolTip(
|
|
frozen ? tr("The name is frozen: unfreeze it to change its number.")
|
|
: !keeps ? tr("The number can be chosen when the element keeps its numbering.")
|
|
: tr("Only free numbers are offered: an element that must keep its real number "
|
|
"can get it back if nobody else has it."));
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::numberChosen
|
|
Show the label the number picked gives, in the field of the label.
|
|
*/
|
|
void ElementInfoWidget::numberChosen()
|
|
{
|
|
ElementInfoPartWidget *label = infoPartWidgetForKey(QETInformation::ELMT_LABEL);
|
|
if (!label || !m_element || !m_element->diagram()) {
|
|
return;
|
|
}
|
|
const int number = m_number_cb->currentData().toInt();
|
|
if (number <= 0 || number == m_number_current) {
|
|
label->setText(m_element->elementInformations().value(QETInformation::ELMT_LABEL).toString());
|
|
return;
|
|
}
|
|
label->setText(ElementAutoNumSchemeCommand::labelForNumber(
|
|
m_element->diagram()->project(), followedScheme(), m_element, number));
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::followedScheme
|
|
@return the title of the numbering the element follows, empty if none
|
|
*/
|
|
QString ElementInfoWidget::followedScheme() const
|
|
{
|
|
if (!m_element || !m_element->diagram()) {
|
|
return QString();
|
|
}
|
|
return m_element->diagram()->project()->elementAutoNumTitle(
|
|
QUuid(m_element->elementInformations()
|
|
.value(QETInformation::ELMT_FORMULA_ID).toString()));
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::chosenScheme
|
|
@return the title of the numbering picked in the list, empty if the
|
|
element is to follow none
|
|
*/
|
|
QString ElementInfoWidget::chosenScheme() const
|
|
{
|
|
const QString data = m_scheme_cb ? m_scheme_cb->currentData().toString() : QString();
|
|
return data == QLatin1String("\x01") ? QString() : data;
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::refreshSchemeRow
|
|
Fill the list with the numberings of the project and show the one the
|
|
element follows. An element with a formula of its own, followed from
|
|
no numbering, gets an entry for it, so that it is neither hidden nor
|
|
lost by looking at it.
|
|
*/
|
|
void ElementInfoWidget::refreshSchemeRow()
|
|
{
|
|
if (!m_scheme_cb || !m_element || !m_element->diagram()) {
|
|
return;
|
|
}
|
|
QETProject *project = m_element->diagram()->project();
|
|
|
|
const QSignalBlocker blocker(m_scheme_cb);
|
|
m_scheme_cb->clear();
|
|
m_scheme_cb->addItem(tr("None (name entered by hand)"), QString());
|
|
|
|
QStringList titles(project->elementAutoNum().keys());
|
|
titles.sort(Qt::CaseInsensitive);
|
|
for (const QString &title : titles) {
|
|
m_scheme_cb->addItem(title, title);
|
|
}
|
|
|
|
const QString followed = followedScheme();
|
|
if (!followed.isEmpty()) {
|
|
m_scheme_cb->setCurrentIndex(m_scheme_cb->findData(followed));
|
|
m_scheme_index = m_scheme_cb->currentIndex();
|
|
return;
|
|
}
|
|
|
|
const QString formula = m_element->elementInformations()
|
|
.value(QETInformation::ELMT_FORMULA).toString();
|
|
if (!formula.isEmpty()) {
|
|
//Same data as "none" would clash: the entry is for display only
|
|
m_scheme_cb->insertItem(1, tr("Custom formula: %1").arg(formula), QStringLiteral("\x01"));
|
|
m_scheme_cb->setCurrentIndex(1);
|
|
}
|
|
m_scheme_index = m_scheme_cb->currentIndex();
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::schemeChosen
|
|
The user picked an entry of the list.
|
|
|
|
The formula shown is the one of the numbering picked; the label is
|
|
typed only when there is no formula. Leaving a numbering, or the
|
|
element's own formula, for "none" also empties the label: what stays
|
|
would pass for a number the numbering gave, and could be given again
|
|
to another element. Going back to what the element has at present
|
|
gives its label back.
|
|
|
|
An element whose label is frozen is changed only if the user agrees.
|
|
*/
|
|
void ElementInfoWidget::schemeChosen()
|
|
{
|
|
ElementInfoPartWidget *formula = infoPartWidgetForKey(QETInformation::ELMT_FORMULA);
|
|
ElementInfoPartWidget *label = infoPartWidgetForKey(QETInformation::ELMT_LABEL);
|
|
if (!formula || !label || !m_element || !m_element->diagram()) {
|
|
return;
|
|
}
|
|
|
|
const DiagramContext info = m_element->elementInformations();
|
|
const QString own_formula = info.value(QETInformation::ELMT_FORMULA).toString();
|
|
const bool own_entry = m_scheme_cb->currentData().toString() == QLatin1String("\x01");
|
|
const QString chosen = chosenScheme();
|
|
const bool unchanged = own_entry
|
|
|| (!chosen.isEmpty() && chosen == followedScheme())
|
|
|| (chosen.isEmpty() && own_formula.isEmpty());
|
|
|
|
const bool frozen_now = m_freeze_cb ? m_freeze_cb->isChecked() : m_element->isFreezeLabel();
|
|
if (!unchanged && frozen_now)
|
|
{
|
|
const auto answer = QET::QetMessageBox::question(
|
|
this,
|
|
tr("Frozen name"),
|
|
tr("This element's name is frozen.\n"
|
|
"Changing its numbering will replace or erase it.\n"
|
|
"\n"
|
|
"Continue?"),
|
|
QMessageBox::Yes | QMessageBox::No,
|
|
QMessageBox::No);
|
|
if (answer != QMessageBox::Yes) {
|
|
m_scheme_cb->setCurrentIndex(m_scheme_index);
|
|
return;
|
|
}
|
|
}
|
|
m_scheme_index = m_scheme_cb->currentIndex();
|
|
//The user agreed: the element is no longer protected
|
|
if (!unchanged && m_freeze_cb) {
|
|
m_freeze_cb->setChecked(false);
|
|
}
|
|
|
|
//Setting the fields one by one must not apply each step
|
|
const bool live = m_live_edit;
|
|
if (live) disableLiveEdit();
|
|
|
|
if (unchanged) {
|
|
formula->setText(own_formula);
|
|
label->setText(info.value(QETInformation::ELMT_LABEL).toString());
|
|
} else if (chosen.isEmpty()) {
|
|
formula->setText(QString());
|
|
if (!own_formula.isEmpty()) {
|
|
label->setText(QString());
|
|
}
|
|
} else {
|
|
formula->setText(m_element->diagram()->project()->elementAutoNumFormula(chosen));
|
|
}
|
|
updateFreezeRow();
|
|
|
|
if (live) {
|
|
enableLiveEdit();
|
|
apply();
|
|
}
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::openSchemePage
|
|
Open the numberings of the project, on the one of elements, then show
|
|
again the list, which may have changed.
|
|
*/
|
|
void ElementInfoWidget::openSchemePage()
|
|
{
|
|
if (!m_element || !m_element->diagram()) {
|
|
return;
|
|
}
|
|
const QString before = chosenScheme();
|
|
|
|
ProjectPropertiesDialog ppd(m_element->diagram()->project(), this);
|
|
ppd.setCurrentPage(ProjectPropertiesDialog::Autonum);
|
|
ppd.changeToElement();
|
|
ppd.exec();
|
|
|
|
refreshSchemeRow();
|
|
const int index = m_scheme_cb->findData(before);
|
|
if (index >= 0) {
|
|
m_scheme_cb->setCurrentIndex(index);
|
|
}
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::firstActivated
|
|
Slot activated when this widget is show.
|
|
Set the focus to the first line edit provided by this widget
|
|
*/
|
|
void ElementInfoWidget::firstActivated()
|
|
{
|
|
m_eipw_list.first() -> setFocusTolineEdit();
|
|
}
|
|
|
|
/**
|
|
@brief ElementInfoWidget::elementInfoChange
|
|
This slot is called when m_element::elementInformation change.
|
|
*/
|
|
void ElementInfoWidget::elementInfoChange()
|
|
{
|
|
auto elmt_info = m_element->elementInformations();
|
|
auto current_info = currentInfo();
|
|
|
|
//If both info have a formula, we remove the label
|
|
//value before compare the equality, because the
|
|
//label of the information returned by the element
|
|
//can be different of the current label because
|
|
//updated by the element to reflect the actual
|
|
//displayed label according the current formula.
|
|
if (current_info.contains(QETInformation::ELMT_FORMULA) &&
|
|
elmt_info.contains(QETInformation::ELMT_FORMULA))
|
|
{
|
|
elmt_info.remove(QETInformation::ELMT_LABEL);
|
|
current_info.remove((QETInformation::ELMT_LABEL ));
|
|
}
|
|
|
|
if(current_info != elmt_info)
|
|
updateUi();
|
|
}
|