mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-23 15:34:12 +02:00
Merge pull request #1584 from Kellermorph/feature/terminal-label-split
Linux build and tests / Build and test (Qt 6, Debug) (push) Failing after 1m38s
Linux build and tests / Build and test (Qt 6, Debug) (push) Failing after 1m38s
Terminal labelling: option to draw label and number apart, and a Show name box for terminals
This commit is contained in:
@@ -548,6 +548,12 @@ void ElementQueryWidget::setUpItems()
|
||||
{
|
||||
if (key == "formula" || key == "exclude_from_bom")
|
||||
continue;
|
||||
// Terminal number is read-only and not a column of the nomenclature
|
||||
// query, so offering it as an export/query column would break the
|
||||
// export (query fails with "no such column"). It stays available as a
|
||||
// text variable (%{terminal_number}) in the element editor.
|
||||
if (key == QETInformation::ELMT_TERMINAL_NUMBER)
|
||||
continue;
|
||||
|
||||
auto item = new QListWidgetItem(QETInformation::translatedInfoKey(key), ui->m_var_list);
|
||||
item->setData(Qt::UserRole, key);
|
||||
|
||||
@@ -46,6 +46,20 @@
|
||||
#include <QTextCursor>
|
||||
#include <QTextDocumentFragment>
|
||||
|
||||
namespace {
|
||||
/**
|
||||
A composite text which uses the terminal number follows the label
|
||||
as closely as one which uses %{label}: both are drawn from the
|
||||
label of the element, and from the formula that label is made of.
|
||||
*/
|
||||
bool usesLabelVariables(const QString &composite_text)
|
||||
{
|
||||
return composite_text.contains(QLatin1String("%{label}"))
|
||||
|| composite_text.contains(
|
||||
QStringLiteral("%{") + QETInformation::ELMT_TERMINAL_NUMBER + QLatin1String("}"));
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicElementTextItem::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
if (!event->matches(QKeySequence::Paste) || m_text_from != UserText ||
|
||||
@@ -401,8 +415,11 @@ Element *DynamicElementTextItem::elementUseForInfo() const
|
||||
*/
|
||||
void DynamicElementTextItem::refreshLabelConnection()
|
||||
{
|
||||
if ((m_text_from == ElementInfo && m_info_name == "label") ||
|
||||
(m_text_from == CompositeText && m_composite_text.contains("%{label}")))
|
||||
refreshLabelShown();
|
||||
if ((m_text_from == ElementInfo &&
|
||||
(m_info_name == QLatin1String("label")
|
||||
|| m_info_name == QETInformation::ELMT_TERMINAL_NUMBER)) ||
|
||||
(m_text_from == CompositeText && usesLabelVariables(m_composite_text)))
|
||||
{
|
||||
if((m_parent_element.data()->linkType() & Element::AllReport) ||
|
||||
m_parent_element.data()->linkType() == Element::ConductorDefinition)
|
||||
@@ -418,6 +435,30 @@ void DynamicElementTextItem::refreshLabelConnection()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief DynamicElementTextItem::refreshLabelShown
|
||||
Whether this field is drawn at all: a field bound to the label of
|
||||
an element whose "Show name" box is unticked (@sa Element::labelShown)
|
||||
does not stay on the sheet as an empty frame to select -- it is
|
||||
hidden, and comes back the moment the box is ticked again. Both ways
|
||||
run through the same signals which refresh the text, so the field
|
||||
can never get stuck on one side. Every other field is drawn as
|
||||
always, and a composite text keeps drawing what is not the label.
|
||||
*/
|
||||
void DynamicElementTextItem::refreshLabelShown()
|
||||
{
|
||||
const bool shown = !(m_text_from == ElementInfo
|
||||
&& m_info_name == QETInformation::ELMT_LABEL)
|
||||
|| !m_parent_element
|
||||
|| m_parent_element.data()->labelShown();
|
||||
|
||||
if (!shown && isSelected()) {
|
||||
setSelected(false);
|
||||
}
|
||||
setVisible(shown);
|
||||
refreshResizeHandlesVisibility();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief DynamicElementTextItem::textFrom
|
||||
@return what the final text is created from.
|
||||
@@ -450,26 +491,34 @@ void DynamicElementTextItem::setTextFrom(DynamicElementTextItem::TextFrom text_f
|
||||
}
|
||||
else if (m_text_from == ElementInfo && elementUseForInfo())
|
||||
{
|
||||
if(m_info_name == "label")
|
||||
if(m_info_name == QLatin1String("label")
|
||||
|| m_info_name == QETInformation::ELMT_TERMINAL_NUMBER)
|
||||
{
|
||||
setupFormulaConnection();
|
||||
updateLabel();
|
||||
}
|
||||
else
|
||||
setPlainText(elementUseForInfo()->elementInformations().value(m_info_name).toString());
|
||||
setPlainText(elementUseForInfo()->infoForDisplay(m_info_name));
|
||||
|
||||
if(old_text_from == UserText)
|
||||
connect(elementUseForInfo(), &Element::elementInfoChange, this, &DynamicElementTextItem::elementInfoChanged);
|
||||
}
|
||||
else if (m_text_from == CompositeText && elementUseForInfo())
|
||||
{
|
||||
if(m_composite_text.contains("%{label}"))
|
||||
if(usesLabelVariables(m_composite_text))
|
||||
{
|
||||
setupFormulaConnection();
|
||||
updateLabel();
|
||||
}
|
||||
else
|
||||
setPlainText(autonum::AssignVariables::replaceVariable(m_composite_text, elementUseForInfo()->elementInformations()));
|
||||
{
|
||||
//The label and the terminal number are drawn the way the
|
||||
//settings say, every other information as it is stored
|
||||
DiagramContext dc = elementUseForInfo()->elementInformations();
|
||||
dc.addValue(QETInformation::ELMT_LABEL, elementUseForInfo()->labelForDisplay());
|
||||
dc.addValue(QETInformation::ELMT_TERMINAL_NUMBER, elementUseForInfo()->terminalNumberForDisplay());
|
||||
setPlainText(autonum::AssignVariables::replaceVariable(m_composite_text, dc));
|
||||
}
|
||||
|
||||
if(old_text_from == UserText)
|
||||
connect(elementUseForInfo(), &Element::elementInfoChange, this, &DynamicElementTextItem::elementInfoChanged);
|
||||
@@ -478,7 +527,16 @@ void DynamicElementTextItem::setTextFrom(DynamicElementTextItem::TextFrom text_f
|
||||
if(m_parent_element.data()->linkType() == Element::Master ||
|
||||
m_parent_element.data()->linkType() == Element::Slave)
|
||||
updateXref();
|
||||
|
||||
|
||||
//A field which becomes, or stops being, the field for the
|
||||
//terminal number changes what the label of the symbol leaves
|
||||
//to it (@sa Element::labelForDisplay)
|
||||
if (m_info_name == QETInformation::ELMT_TERMINAL_NUMBER
|
||||
&& (m_text_from == ElementInfo || old_text_from == ElementInfo)
|
||||
&& parentElement()) {
|
||||
parentElement()->refreshLabelFields();
|
||||
}
|
||||
|
||||
emit textFromChanged(m_text_from);
|
||||
}
|
||||
|
||||
@@ -515,7 +573,8 @@ void DynamicElementTextItem::setInfoName(const QString &info_name)
|
||||
m_info_name = info_name;
|
||||
|
||||
|
||||
if(old_info_name == "label")
|
||||
if(old_info_name == QLatin1String("label")
|
||||
|| old_info_name == QETInformation::ELMT_TERMINAL_NUMBER)
|
||||
{
|
||||
clearFormulaConnection();
|
||||
updateXref();
|
||||
@@ -538,16 +597,32 @@ void DynamicElementTextItem::setInfoName(const QString &info_name)
|
||||
conductorPropertiesChanged();
|
||||
}
|
||||
}
|
||||
else if (m_info_name == "label" && elementUseForInfo())
|
||||
else if ((m_info_name == QLatin1String("label")
|
||||
|| m_info_name == QETInformation::ELMT_TERMINAL_NUMBER)
|
||||
&& elementUseForInfo())
|
||||
{
|
||||
setupFormulaConnection();
|
||||
updateLabel();
|
||||
updateXref();
|
||||
}
|
||||
else if(elementUseForInfo() && m_text_from == DynamicElementTextItem::ElementInfo) {
|
||||
setPlainText(elementUseForInfo()->elementInformations().value(info_name).toString());
|
||||
setPlainText(elementUseForInfo()->infoForDisplay(info_name));
|
||||
}
|
||||
|
||||
|
||||
//A field which becomes, or stops being, the field for the
|
||||
//terminal number changes what the label of the symbol leaves
|
||||
//to it (@sa Element::labelForDisplay)
|
||||
if (parentElement()
|
||||
&& (info_name == QETInformation::ELMT_TERMINAL_NUMBER
|
||||
|| old_info_name == QETInformation::ELMT_TERMINAL_NUMBER)) {
|
||||
parentElement()->refreshLabelFields();
|
||||
}
|
||||
|
||||
//A field which becomes, or stops being, the field for the
|
||||
//label of its element is shown or hidden with the "Show name"
|
||||
//box (@sa refreshLabelShown)
|
||||
refreshLabelShown();
|
||||
|
||||
emit infoNameChanged(info_name);
|
||||
}
|
||||
|
||||
@@ -956,7 +1031,11 @@ bool DynamicElementTextItem::sceneEventFilter(QGraphicsItem *watched, QEvent *ev
|
||||
*/
|
||||
void DynamicElementTextItem::refreshResizeHandlesVisibility()
|
||||
{
|
||||
const bool handles_wanted = isSelected() || (m_parent_element && m_parent_element->isSelected());
|
||||
//A hidden text has no handles, not even while its element is
|
||||
//selected: refreshLabelShown() puts them back when the text
|
||||
//is shown again
|
||||
const bool handles_wanted = isVisible()
|
||||
&& (isSelected() || (m_parent_element && m_parent_element->isSelected()));
|
||||
if (handles_wanted && !m_left_resize_handle)
|
||||
addResizeHandles();
|
||||
else if (!handles_wanted && m_left_resize_handle)
|
||||
@@ -1157,6 +1236,11 @@ void DynamicElementTextItem::handlerMouseReleaseEvent(QetGraphicsHandlerItem *ha
|
||||
|
||||
void DynamicElementTextItem::elementInfoChanged()
|
||||
{
|
||||
//The "Show name" box of the selection properties was possibly
|
||||
//ticked or unticked: the field of a hidden name leaves the
|
||||
//sheet and comes back with the box (@sa refreshLabelShown)
|
||||
refreshLabelShown();
|
||||
|
||||
//A folio report's label shows where its partner is
|
||||
//(updateReportText()); the label in its information is only where
|
||||
//the partner was when last saved, and changing any other
|
||||
@@ -1174,6 +1258,12 @@ void DynamicElementTextItem::elementInfoChanged()
|
||||
Element *element = elementUseForInfo();
|
||||
if(element) {
|
||||
dc = element->elementInformations();
|
||||
//The label and the terminal number are drawn the way the
|
||||
//project says (@sa QETProject::terminalLabelSplit): a
|
||||
//composite text which uses them must see the same values the
|
||||
//fields bound to them show
|
||||
dc.addValue(QETInformation::ELMT_LABEL, element->labelForDisplay());
|
||||
dc.addValue(QETInformation::ELMT_TERMINAL_NUMBER, element->terminalNumberForDisplay());
|
||||
}
|
||||
|
||||
QString final_text;
|
||||
@@ -1183,12 +1273,13 @@ void DynamicElementTextItem::elementInfoChanged()
|
||||
{
|
||||
//If the info is the label, then we must make some connection
|
||||
//if the label is created from a formula
|
||||
if(m_info_name == "label")
|
||||
if(m_info_name == QLatin1String("label")
|
||||
|| m_info_name == QETInformation::ELMT_TERMINAL_NUMBER)
|
||||
{
|
||||
setupFormulaConnection();
|
||||
|
||||
if (element) {
|
||||
final_text = element->actualLabel();
|
||||
final_text = element->infoForDisplay(m_info_name);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1199,7 +1290,7 @@ void DynamicElementTextItem::elementInfoChanged()
|
||||
{
|
||||
//If the composite have the label variable, we must make some
|
||||
//connection if the label is created from a formula
|
||||
if (m_composite_text.contains("%{label}"))
|
||||
if (usesLabelVariables(m_composite_text))
|
||||
setupFormulaConnection();
|
||||
|
||||
//A report's %{label} is where its partner is, not its own
|
||||
@@ -1367,8 +1458,10 @@ void DynamicElementTextItem::removeConnectionForReportFormula(const QString &for
|
||||
*/
|
||||
void DynamicElementTextItem::setupFormulaConnection()
|
||||
{
|
||||
if ((m_text_from == ElementInfo && m_info_name == "label") ||
|
||||
(m_text_from == CompositeText && m_composite_text.contains("%{label}")))
|
||||
if ((m_text_from == ElementInfo &&
|
||||
(m_info_name == QLatin1String("label")
|
||||
|| m_info_name == QETInformation::ELMT_TERMINAL_NUMBER)) ||
|
||||
(m_text_from == CompositeText && usesLabelVariables(m_composite_text)))
|
||||
{
|
||||
clearFormulaConnection();
|
||||
|
||||
@@ -1458,8 +1551,10 @@ void DynamicElementTextItem::updateReportText()
|
||||
*/
|
||||
void DynamicElementTextItem::updateLabel()
|
||||
{
|
||||
if ((m_text_from == ElementInfo && m_info_name == "label") ||
|
||||
(m_text_from == CompositeText && m_composite_text.contains("%{label}")))
|
||||
if ((m_text_from == ElementInfo &&
|
||||
(m_info_name == QLatin1String("label")
|
||||
|| m_info_name == QETInformation::ELMT_TERMINAL_NUMBER)) ||
|
||||
(m_text_from == CompositeText && usesLabelVariables(m_composite_text)))
|
||||
{
|
||||
DiagramContext dc;
|
||||
Element *element = elementUseForInfo();
|
||||
@@ -1469,19 +1564,21 @@ void DynamicElementTextItem::updateLabel()
|
||||
|
||||
|
||||
if(m_text_from == ElementInfo && element) {
|
||||
QString new_label = element->actualLabel();
|
||||
QString new_label = element->infoForDisplay(m_info_name);
|
||||
if (toPlainText() != new_label) {
|
||||
setPlainText(new_label);
|
||||
}
|
||||
}
|
||||
else if (m_text_from == CompositeText) {
|
||||
// Use actualLabel() to ensure %{label} reflects the current
|
||||
// resolved label (e.g. after a folio/page-number change).
|
||||
// Use the label as it must be drawn, so %{label} and
|
||||
// %{terminal_number} reflect the current resolved label (e.g.
|
||||
// after a folio/page-number change).
|
||||
// A contact not linked to a coil has no element to read from
|
||||
// (bugtracker #345): %{label} then shows empty, as it did
|
||||
// before actualLabel() was used here.
|
||||
if (element) {
|
||||
dc.addValue(QStringLiteral("label"), element->actualLabel());
|
||||
dc.addValue(QETInformation::ELMT_LABEL, element->labelForDisplay());
|
||||
dc.addValue(QETInformation::ELMT_TERMINAL_NUMBER, element->terminalNumberForDisplay());
|
||||
}
|
||||
setPlainText(autonum::AssignVariables::replaceVariable(m_composite_text, dc));
|
||||
}
|
||||
|
||||
@@ -97,6 +97,7 @@ class DynamicElementTextItem : public DiagramTextItem
|
||||
ElementTextItemGroup *parentGroup() const;
|
||||
Element *elementUseForInfo() const;
|
||||
void refreshLabelConnection();
|
||||
void refreshLabelShown();
|
||||
|
||||
DynamicElementTextItem::TextFrom textFrom() const;
|
||||
void setTextFrom (DynamicElementTextItem::TextFrom text_from);
|
||||
|
||||
@@ -1689,6 +1689,17 @@ void Element::addDynamicTextItem(DynamicElementTextItem *deti)
|
||||
|
||||
m_dynamic_text_list.append(deti);
|
||||
|
||||
//An element whose name must not be drawn does not keep the
|
||||
//field of its label on the sheet either (@sa Element::labelShown)
|
||||
deti->refreshLabelShown();
|
||||
|
||||
//A field of its own for the terminal number is what the label
|
||||
//leaves the number to: the fields which draw the label follow
|
||||
//when such a field lands on the symbol
|
||||
if (deti->infoName() == QETInformation::ELMT_TERMINAL_NUMBER) {
|
||||
refreshLabelFields();
|
||||
}
|
||||
|
||||
//On a mirrored element, the mirror of the text depends on the size
|
||||
//and the rotation of the text, see keepReadable()
|
||||
connect(deti->document()->documentLayout(),
|
||||
@@ -1724,6 +1735,9 @@ void Element::removeDynamicTextItem(DynamicElementTextItem *deti)
|
||||
m_dynamic_text_list.removeOne(deti);
|
||||
deti->setParentItem(nullptr);
|
||||
forget();
|
||||
if (deti->infoName() == QETInformation::ELMT_TERMINAL_NUMBER) {
|
||||
refreshLabelFields();
|
||||
}
|
||||
emit textRemoved(deti);
|
||||
return;
|
||||
}
|
||||
@@ -1736,12 +1750,37 @@ void Element::removeDynamicTextItem(DynamicElementTextItem *deti)
|
||||
m_dynamic_text_list.removeOne(deti);
|
||||
deti->setParentItem(nullptr);
|
||||
forget();
|
||||
if (deti->infoName() == QETInformation::ELMT_TERMINAL_NUMBER) {
|
||||
refreshLabelFields();
|
||||
}
|
||||
emit textRemoved(deti);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Element::refreshLabelFields
|
||||
The fields which draw the label draw it again: what they show of the
|
||||
label has changed under them (a field for the terminal number added
|
||||
or removed, @sa Element::hasTerminalNumberText), or the terminal
|
||||
labelling setting of the project was switched
|
||||
(@sa QETProject::terminalLabelSplit).
|
||||
Only the fields which draw a label are refreshed, every other field
|
||||
follows its own information.
|
||||
*/
|
||||
void Element::refreshLabelFields()
|
||||
{
|
||||
for (DynamicElementTextItem *text : m_dynamic_text_list) {
|
||||
text->refreshLabelConnection();
|
||||
}
|
||||
for (ElementTextItemGroup *group : m_texts_group) {
|
||||
for (DynamicElementTextItem *text : group->texts()) {
|
||||
text->refreshLabelConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Element::dynamicTextItems
|
||||
@return all dynamic text items of this element directly child of this element.
|
||||
@@ -2735,6 +2774,156 @@ QString Element::actualLabel()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Element::labelForDisplay
|
||||
@return the label as the drawing must show it, the terminal labelling
|
||||
of the project being read (@sa QETProject::terminalLabelSplit): the
|
||||
whole label ("X1:1") while the labelling is shown in one field; the
|
||||
label alone ("X1") when it is shown split and this symbol has a text
|
||||
field of its own for the terminal number; and the two one under the
|
||||
other when it is split without such a field -- so a symbol drawn
|
||||
before the setting existed still shows all of its label, only
|
||||
shorter. Only an element of the terminal type is ever drawn split:
|
||||
the colon in any other label is part of the label ("-K1:13").
|
||||
*/
|
||||
QString Element::labelForDisplay()
|
||||
{
|
||||
const QString label = actualLabel();
|
||||
const Diagram *d = diagram();
|
||||
const bool split = m_data.m_type == ElementData::Terminal
|
||||
&& d && d->project() && d->project()->terminalLabelSplit();
|
||||
|
||||
//The "Show name" box of the selection properties hides the name
|
||||
//of this element on the sheet only: the element keeps all of its
|
||||
//data, and a terminal keeps its number, drawn on its own while
|
||||
//the labelling is split.
|
||||
if (!labelShown())
|
||||
{
|
||||
if (!split) {
|
||||
return QString();
|
||||
}
|
||||
//The number alone in the label field, but only while the
|
||||
//symbol has no field of its own for it: the number is
|
||||
//drawn once, wherever it is drawn at all.
|
||||
const int hidden_colon = label.lastIndexOf(QLatin1Char(':'));
|
||||
if (hidden_colon < 0 || hasTerminalNumberText()) {
|
||||
return QString();
|
||||
}
|
||||
return label.mid(hidden_colon + 1);
|
||||
}
|
||||
|
||||
if (!split) {
|
||||
return label;
|
||||
}
|
||||
|
||||
const int colon = label.lastIndexOf(QLatin1Char(':'));
|
||||
if (colon < 0) {
|
||||
return label;
|
||||
}
|
||||
|
||||
if (hasTerminalNumberText()) {
|
||||
return label.left(colon);
|
||||
}
|
||||
|
||||
return label.left(colon) + QLatin1Char('\n') + label.mid(colon + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Element::terminalNumberForDisplay
|
||||
@return the part of the label behind its last colon ("1" in "X1:1"),
|
||||
or an empty string while the labelling is shown in one field -- and
|
||||
for every element which is no terminal, whose colon is part of its
|
||||
label: the number is already there with the label, showing it twice
|
||||
would only be noise. @sa labelForDisplay
|
||||
*/
|
||||
QString Element::terminalNumberForDisplay()
|
||||
{
|
||||
const Diagram *d = diagram();
|
||||
if (m_data.m_type != ElementData::Terminal
|
||||
|| !d || !d->project() || !d->project()->terminalLabelSplit()) {
|
||||
return QString();
|
||||
}
|
||||
|
||||
const QString label = actualLabel();
|
||||
const int colon = label.lastIndexOf(QLatin1Char(':'));
|
||||
if (colon < 0) {
|
||||
return QString();
|
||||
}
|
||||
|
||||
return label.mid(colon + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Element::hasTerminalNumberText
|
||||
@return whether this symbol has a text field bound to the terminal
|
||||
number, the field labelForDisplay() leaves the number to.
|
||||
*/
|
||||
bool Element::hasTerminalNumberText() const
|
||||
{
|
||||
auto is_number_field = [](const DynamicElementTextItem *text) {
|
||||
return text
|
||||
&& text->textFrom() == DynamicElementTextItem::ElementInfo
|
||||
&& text->infoName() == QETInformation::ELMT_TERMINAL_NUMBER;
|
||||
};
|
||||
|
||||
for (const DynamicElementTextItem *text : dynamicTextItems()) {
|
||||
if (is_number_field(text)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
//The field may just as well live in a text group of the symbol
|
||||
for (const ElementTextItemGroup *group : m_texts_group) {
|
||||
for (const DynamicElementTextItem *text : group->texts()) {
|
||||
if (is_number_field(text)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Element::labelShown
|
||||
@return whether the label of this element must be drawn on the sheet.
|
||||
The choice belongs to the element itself, set with the "Show name"
|
||||
box of the selection properties: an element whose name is not shown
|
||||
keeps all of its data, nothing is only not drawn. An element which
|
||||
never got the box unticked keeps drawing its name, which is why a
|
||||
missing information means true.
|
||||
*/
|
||||
bool Element::labelShown() const
|
||||
{
|
||||
//Only a terminal may have its name undrawn: an information
|
||||
//which says otherwise, from whatever source, is not obeyed.
|
||||
if (m_data.m_type != ElementData::Terminal) {
|
||||
return true;
|
||||
}
|
||||
if (!m_data.m_informations.contains(QStringLiteral("label_shown"))) {
|
||||
return true;
|
||||
}
|
||||
return QET::infoFlagIsTrue(
|
||||
m_data.m_informations.value(QStringLiteral("label_shown")).toString());
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Element::infoForDisplay
|
||||
@return what a text field bound to @p info_name must show: the label
|
||||
and the terminal number follow how the labelling is drawn, every
|
||||
other information is the stored one. @sa labelForDisplay
|
||||
*/
|
||||
QString Element::infoForDisplay(const QString &info_name)
|
||||
{
|
||||
if (info_name == QETInformation::ELMT_LABEL) {
|
||||
return labelForDisplay();
|
||||
}
|
||||
if (info_name == QETInformation::ELMT_TERMINAL_NUMBER) {
|
||||
return terminalNumberForDisplay();
|
||||
}
|
||||
|
||||
return m_data.m_informations.value(info_name).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Element::name
|
||||
@return the human name of this element
|
||||
|
||||
@@ -166,6 +166,25 @@ class Element : public QetGraphicsItem
|
||||
bool isFreezeLabel() const {return m_freeze_label;}
|
||||
void freezeNewAddedElement();
|
||||
QString actualLabel();
|
||||
/**
|
||||
What the drawing shows of the label and of the terminal
|
||||
number, the terminal labelling of the project being
|
||||
read (@sa QETProject::terminalLabelSplit). The label itself
|
||||
is never changed by any of them.
|
||||
*/
|
||||
QString labelForDisplay();
|
||||
QString terminalNumberForDisplay();
|
||||
QString infoForDisplay(const QString &info_name);
|
||||
bool hasTerminalNumberText() const;
|
||||
bool labelShown() const;
|
||||
/**
|
||||
The fields which draw the label draw it again: called when
|
||||
what they show of the label has changed under them, a
|
||||
field for the terminal number added or removed, or the
|
||||
terminal labelling setting of the project switched (@sa
|
||||
QETProject::terminalLabelSplit).
|
||||
*/
|
||||
void refreshLabelFields();
|
||||
|
||||
QString name() const override;
|
||||
ElementsLocation location() const;
|
||||
|
||||
@@ -142,6 +142,7 @@ QStringList QETInformation::elementInfoKeys()
|
||||
{
|
||||
QStringList list = { ELMT_FORMULA,
|
||||
ELMT_LABEL,
|
||||
ELMT_TERMINAL_NUMBER,
|
||||
ELMT_PLANT,
|
||||
ELMT_LOCATION,
|
||||
ELMT_COMMENT,
|
||||
@@ -311,6 +312,7 @@ QString QETInformation::translatedInfoKey(const QString &info)
|
||||
else if (info == PROJECT_SAVED_FILE_PATH) return QObject::tr("Saved file path");
|
||||
else if (info == ELMT_FORMULA) return QObject::tr("Label formula");
|
||||
else if (info == ELMT_LABEL) return QObject::tr("Label");
|
||||
else if (info == ELMT_TERMINAL_NUMBER) return QObject::tr("Terminal number");
|
||||
else if (info == ELMT_COMMENT) return QObject::tr("Annotation");
|
||||
else if (info == ELMT_FUNCTION) return QObject::tr("Function");
|
||||
else if (info == ELMT_DESCRIPTION) return QObject::tr("Textual description");
|
||||
|
||||
@@ -39,6 +39,10 @@ namespace QETInformation
|
||||
{
|
||||
/** Default information related to element **/
|
||||
static QString ELMT_LABEL = "label";
|
||||
//The part of the label behind its last colon ("1" in "X1:1"),
|
||||
//shown in a text field of its own when the terminal labelling
|
||||
//is drawn split (@sa QETProject::terminalLabelSplit)
|
||||
static QString ELMT_TERMINAL_NUMBER = "terminal_number";
|
||||
static QString ELMT_FORMULA = "formula";
|
||||
/**
|
||||
Uuid of the project's element numbering scheme the element's
|
||||
|
||||
@@ -2316,6 +2316,39 @@ void QETProject::setUprightSymbolTexts(bool upright)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief QETProject::terminalLabelSplit
|
||||
@return whether the terminals of this project draw their label split,
|
||||
the label ("X1") and the terminal number ("1") each in their own text
|
||||
field, instead of the whole label ("X1:1") in one field. Off unless
|
||||
the project says otherwise, so a project saved without it draws as it
|
||||
always did. This is a setting of the project, not of the application:
|
||||
the same file draws the same way on every machine which opens it.
|
||||
@sa setTerminalLabelSplit
|
||||
*/
|
||||
bool QETProject::terminalLabelSplit() const {
|
||||
return m_terminal_label_split;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief QETProject::setTerminalLabelSplit
|
||||
Set whether the terminals of this project draw their label split, and
|
||||
tell the labels of the drawings already open to draw it again.
|
||||
@param split
|
||||
*/
|
||||
void QETProject::setTerminalLabelSplit(bool split)
|
||||
{
|
||||
if (split == m_terminal_label_split) {
|
||||
return;
|
||||
}
|
||||
m_terminal_label_split = split;
|
||||
for (Diagram *diagram : diagrams()) {
|
||||
for (Element *element : diagram->elements()) {
|
||||
element->refreshLabelFields();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief QETProject::wiringRules
|
||||
@return how many wires a terminal of this project may take
|
||||
@@ -2554,6 +2587,7 @@ QDomDocument QETProject::toXml(QHash<int, QByteArray> *kept_folios, QStringList
|
||||
writeUsageXml(project_root);
|
||||
writeWireHopsXml(project_root);
|
||||
writeSymbolTextsXml(project_root);
|
||||
writeTerminalLabelSplitXml(project_root);
|
||||
writeWiringRulesXml(project_root);
|
||||
|
||||
// Properties for news diagrams
|
||||
@@ -3525,6 +3559,7 @@ void QETProject::readProjectXml(QDomDocument &xml_project)
|
||||
readUsageXml(xml_project);
|
||||
readWireHopsXml(xml_project);
|
||||
readSymbolTextsXml(xml_project);
|
||||
readTerminalLabelSplitXml(xml_project);
|
||||
readWiringRulesXml(xml_project);
|
||||
|
||||
//Load the default properties for the new diagrams
|
||||
@@ -3889,6 +3924,21 @@ void QETProject::readSymbolTextsXml(QDomDocument &xml_project)
|
||||
&& texts.attribute(QStringLiteral("upright")) == QLatin1String("true");
|
||||
}
|
||||
|
||||
/**
|
||||
@brief QETProject::readTerminalLabelSplitXml
|
||||
Read the <terminal_labelling> element of the project, if any. A
|
||||
project without it was saved before the setting existed, or with it
|
||||
off, and draws the whole label of each terminal in one field.
|
||||
@param xml_project : the xml description of the project
|
||||
*/
|
||||
void QETProject::readTerminalLabelSplitXml(QDomDocument &xml_project)
|
||||
{
|
||||
const QDomElement labelling = xml_project.documentElement()
|
||||
.firstChildElement(QStringLiteral("terminal_labelling"));
|
||||
m_terminal_label_split = !labelling.isNull()
|
||||
&& labelling.attribute(QStringLiteral("split")) == QLatin1String("true");
|
||||
}
|
||||
|
||||
/**
|
||||
@brief QETProject::readWiringRulesXml
|
||||
Read the <wiring_rules> element of the project, if any.
|
||||
@@ -4213,6 +4263,23 @@ void QETProject::writeSymbolTextsXml(QDomElement &xml_element)
|
||||
xml_element.appendChild(texts);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief QETProject::writeTerminalLabelSplitXml
|
||||
Export whether the terminals draw their label split, as a
|
||||
<terminal_labelling> child of \a xml_element. Written only when on,
|
||||
so a project with it off saves exactly as before.
|
||||
*/
|
||||
void QETProject::writeTerminalLabelSplitXml(QDomElement &xml_element)
|
||||
{
|
||||
if (!m_terminal_label_split) {
|
||||
return;
|
||||
}
|
||||
QDomElement labelling = xml_element.ownerDocument()
|
||||
.createElement(QStringLiteral("terminal_labelling"));
|
||||
labelling.setAttribute(QStringLiteral("split"), QStringLiteral("true"));
|
||||
xml_element.appendChild(labelling);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief QETProject::writeWiringRulesXml
|
||||
Export the project's wiring rules as a <wiring_rules> child of
|
||||
|
||||
@@ -325,6 +325,8 @@ class QETProject : public QObject
|
||||
void setWireHops(WireHops::Mode mode);
|
||||
bool uprightSymbolTexts() const;
|
||||
void setUprightSymbolTexts(bool upright);
|
||||
bool terminalLabelSplit() const;
|
||||
void setTerminalLabelSplit(bool split);
|
||||
WiringRules::Settings wiringRules() const;
|
||||
WiringRules::Settings projectWiringRules() const;
|
||||
void setWiringRules(const WiringRules::Settings &rules);
|
||||
@@ -454,6 +456,7 @@ class QETProject : public QObject
|
||||
void readUsageXml(QDomDocument &xml_project);
|
||||
void readWireHopsXml(QDomDocument &xml_project);
|
||||
void readSymbolTextsXml(QDomDocument &xml_project);
|
||||
void readTerminalLabelSplitXml(QDomDocument &xml_project);
|
||||
void readWiringRulesXml(QDomDocument &xml_project);
|
||||
|
||||
void writeProjectPropertiesXml(QDomElement &);
|
||||
@@ -463,6 +466,7 @@ class QETProject : public QObject
|
||||
void writeUsageXml(QDomElement &);
|
||||
void writeWireHopsXml(QDomElement &);
|
||||
void writeSymbolTextsXml(QDomElement &);
|
||||
void writeTerminalLabelSplitXml(QDomElement &);
|
||||
void writeWiringRulesXml(QDomElement &);
|
||||
void addDiagram(Diagram *diagram, int pos = -1);
|
||||
void detachDiagram(Diagram *diagram);
|
||||
@@ -572,6 +576,10 @@ class QETProject : public QObject
|
||||
/// Texts drawn in a turned symbol stay horizontal (on for a new
|
||||
/// project, off for one saved without it), see uprightSymbolTexts()
|
||||
bool m_upright_symbol_texts = false;
|
||||
/// Terminals draw their label split: the label ("X1") and the
|
||||
/// terminal number ("1") each in their own text field (off for
|
||||
/// a project saved without it), see terminalLabelSplit()
|
||||
bool m_terminal_label_split = false;
|
||||
WiringRules::Settings m_wiring_rules;
|
||||
XmlElementCollection *m_elements_collection = nullptr;
|
||||
QTimer m_save_backup_timer,
|
||||
|
||||
@@ -191,6 +191,11 @@ void ProjectMainConfigPage::applyProjectConf()
|
||||
modified_project = true;
|
||||
}
|
||||
|
||||
if (m_project -> terminalLabelSplit() != terminal_label_split_rb_ -> isChecked()) {
|
||||
m_project -> setTerminalLabelSplit(terminal_label_split_rb_ -> isChecked());
|
||||
modified_project = true;
|
||||
}
|
||||
|
||||
//Following the application's rules stores nothing in the project
|
||||
WiringRules::Settings wiring_rules;
|
||||
if (!use_application_rules_cb_ -> isChecked()) {
|
||||
@@ -266,6 +271,27 @@ void ProjectMainConfigPage::initWidgets()
|
||||
"text. Uncheck to make them turn with the element, as before.",
|
||||
"tooltip"));
|
||||
|
||||
//How the terminals draw their label: a setting of this project,
|
||||
//so the same file draws the same way on every machine which
|
||||
//opens it, like every other choice of how the sheets are drawn
|
||||
terminal_label_gb_ = new QGroupBox(tr("Display of the terminal labelling", "group box title"));
|
||||
terminal_label_combined_rb_ = new QRadioButton(
|
||||
tr("Show the label and the terminal number in one field", "radio button label"));
|
||||
terminal_label_combined_rb_ -> setToolTip(tr(
|
||||
"A terminal's label (X1:1) is drawn as a whole, the way it has always been.",
|
||||
"tooltip"));
|
||||
terminal_label_split_rb_ = new QRadioButton(tr("Split the label and the terminal number",
|
||||
"radio button label"));
|
||||
terminal_label_split_rb_ -> setToolTip(tr(
|
||||
"The label (X1) is drawn in one field and the terminal number (1) in another, "
|
||||
"which a terminal symbol may place where it wants -- and hide when it must. "
|
||||
"A symbol without such a field shows the two, one under the other.",
|
||||
"tooltip"));
|
||||
terminal_label_help_ = new QLabel(tr("Only the drawing changes: what is written in the element, "
|
||||
"the numbering, the sorting and the exports keep the whole label.",
|
||||
"informative label"));
|
||||
terminal_label_help_ -> setWordWrap(true);
|
||||
|
||||
//How many wires a terminal may take (discussion #1158)
|
||||
wiring_rules_gb_ = new QGroupBox(tr("Conductors per terminal", "group box title"));
|
||||
use_application_rules_cb_ = new QCheckBox(tr("Use the application settings", "checkbox label"));
|
||||
@@ -335,6 +361,13 @@ void ProjectMainConfigPage::initLayout()
|
||||
main_layout0 -> addWidget(upright_symbol_texts_cb_);
|
||||
main_layout0 -> addSpacing(10);
|
||||
|
||||
QVBoxLayout *terminal_label_layout = new QVBoxLayout(terminal_label_gb_);
|
||||
terminal_label_layout -> addWidget(terminal_label_combined_rb_);
|
||||
terminal_label_layout -> addWidget(terminal_label_split_rb_);
|
||||
terminal_label_layout -> addWidget(terminal_label_help_);
|
||||
main_layout0 -> addWidget(terminal_label_gb_);
|
||||
main_layout0 -> addSpacing(10);
|
||||
|
||||
QVBoxLayout *wiring_rules_layout = new QVBoxLayout(wiring_rules_gb_);
|
||||
wiring_rules_layout -> addWidget(use_application_rules_cb_);
|
||||
QHBoxLayout *max_wires_layout = new QHBoxLayout();
|
||||
@@ -369,6 +402,11 @@ void ProjectMainConfigPage::readValuesFromProject()
|
||||
const int wire_hops_index = wire_hops_cb_ -> findData(WireHops::toString(m_project -> wireHops()));
|
||||
wire_hops_cb_ -> setCurrentIndex(qMax(0, wire_hops_index));
|
||||
upright_symbol_texts_cb_ -> setChecked(m_project -> uprightSymbolTexts());
|
||||
if (m_project -> terminalLabelSplit()) {
|
||||
terminal_label_split_rb_ -> setChecked(true);
|
||||
} else {
|
||||
terminal_label_combined_rb_ -> setChecked(true);
|
||||
}
|
||||
|
||||
//The rules that apply: the project's own or the application's
|
||||
const WiringRules::Settings wiring_rules = m_project -> wiringRules();
|
||||
@@ -425,6 +463,7 @@ void ProjectMainConfigPage::adjustReadOnly()
|
||||
usage_reset_pb_ -> setDisabled(is_read_only);
|
||||
wire_hops_cb_ -> setDisabled(is_read_only);
|
||||
upright_symbol_texts_cb_ -> setDisabled(is_read_only);
|
||||
terminal_label_gb_ -> setDisabled(is_read_only);
|
||||
wiring_rules_gb_ -> setDisabled(is_read_only);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ class QLabel;
|
||||
class QComboBox;
|
||||
class QLineEdit;
|
||||
class QCheckBox;
|
||||
class QRadioButton;
|
||||
class QPushButton;
|
||||
class QSpinBox;
|
||||
class QGroupBox;
|
||||
@@ -140,6 +141,10 @@ class ProjectMainConfigPage : public ProjectConfigPage {
|
||||
QLabel *wire_hops_label_;
|
||||
QComboBox *wire_hops_cb_;
|
||||
QCheckBox *upright_symbol_texts_cb_;
|
||||
QGroupBox *terminal_label_gb_;
|
||||
QRadioButton *terminal_label_combined_rb_;
|
||||
QRadioButton *terminal_label_split_rb_;
|
||||
QLabel *terminal_label_help_;
|
||||
QGroupBox *wiring_rules_gb_;
|
||||
QCheckBox *use_application_rules_cb_;
|
||||
QLabel *max_wires_label_;
|
||||
|
||||
@@ -262,6 +262,9 @@ void ElementInfoWidget::enableLiveEdit()
|
||||
if (m_freeze_cb) {
|
||||
connect(m_freeze_cb, &QCheckBox::clicked, this, &ElementInfoWidget::apply);
|
||||
}
|
||||
if (m_label_shown_cb) {
|
||||
connect(m_label_shown_cb, &QCheckBox::clicked, this, &ElementInfoWidget::apply);
|
||||
}
|
||||
if (m_number_cb) {
|
||||
connect(m_number_cb, QOverload<int>::of(&QComboBox::activated), this, &ElementInfoWidget::apply);
|
||||
}
|
||||
@@ -283,6 +286,9 @@ void ElementInfoWidget::disableLiveEdit()
|
||||
if (m_freeze_cb) {
|
||||
disconnect(m_freeze_cb, &QCheckBox::clicked, this, &ElementInfoWidget::apply);
|
||||
}
|
||||
if (m_label_shown_cb) {
|
||||
disconnect(m_label_shown_cb, &QCheckBox::clicked, this, &ElementInfoWidget::apply);
|
||||
}
|
||||
if (m_number_cb) {
|
||||
disconnect(m_number_cb, QOverload<int>::of(&QComboBox::activated), this, &ElementInfoWidget::apply);
|
||||
}
|
||||
@@ -307,6 +313,13 @@ void ElementInfoWidget::buildInterface()
|
||||
//line that currentInfo() then fills with "true"/"false".
|
||||
keys.removeAll(QStringLiteral("exclude_from_bom"));
|
||||
|
||||
//The terminal number is not a property of the element: it is
|
||||
//derived from its label, so an edit row here would store a value
|
||||
//nothing reads -- and the nomenclature query has no such column,
|
||||
//which is why the export does not offer it either. The number
|
||||
//stays a text variable (%{terminal_number}) of the element editor.
|
||||
keys.removeAll(QETInformation::ELMT_TERMINAL_NUMBER);
|
||||
|
||||
for (auto str : keys)
|
||||
{
|
||||
ElementInfoPartWidget *eipw = new ElementInfoPartWidget(str, QETInformation::translatedInfoKey(str), this);
|
||||
@@ -318,6 +331,7 @@ void ElementInfoWidget::buildInterface()
|
||||
setupSchemeRow();
|
||||
setupNumberRow();
|
||||
setupFreezeRow();
|
||||
setupLabelShownRow();
|
||||
|
||||
m_add_custom_property_btn = new QPushButton(tr("Add a custom property"), this);
|
||||
connect(m_add_custom_property_btn, &QPushButton::clicked, this, [this]() { addCustomProperty(); });
|
||||
@@ -367,7 +381,8 @@ QStringList ElementInfoWidget::predefinedKeys() const
|
||||
keys << QETInformation::ELMT_FORMULA_ID
|
||||
<< QStringLiteral("auto_num_locked")
|
||||
<< QStringLiteral("potential_isolating")
|
||||
<< QStringLiteral("exclude_from_bom");
|
||||
<< QStringLiteral("exclude_from_bom")
|
||||
<< QStringLiteral("label_shown");
|
||||
|
||||
return keys;
|
||||
}
|
||||
@@ -672,6 +687,9 @@ void ElementInfoWidget::updateUi()
|
||||
m_freeze_cb->setChecked(m_element->isFreezeLabel());
|
||||
updateFreezeRow();
|
||||
}
|
||||
if (m_label_shown_cb) {
|
||||
m_label_shown_cb->setChecked(m_element->labelShown());
|
||||
}
|
||||
refreshNumberRow();
|
||||
updateSuggestions();
|
||||
|
||||
@@ -759,6 +777,13 @@ DiagramContext ElementInfoWidget::currentInfo() const
|
||||
info_.addValue(QStringLiteral("exclude_from_bom"), m_exclude_from_bom_cb->isChecked() ? QStringLiteral("true") : QStringLiteral("false"));
|
||||
}
|
||||
|
||||
// The name is drawn unless the element says otherwise: only a name
|
||||
// which is not drawn needs an information, so that elements which
|
||||
// draw it keep their files exactly as they are.
|
||||
if (m_label_shown_cb && !m_label_shown_cb->isChecked()) {
|
||||
info_.addValue(QStringLiteral("label_shown"), 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();
|
||||
@@ -846,6 +871,38 @@ void ElementInfoWidget::updateFreezeRow()
|
||||
updateNumberRow();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief ElementInfoWidget::setupLabelShownRow
|
||||
Add under the freeze box a check box which decides whether the name
|
||||
of this element is drawn on the sheet: the choice belongs to the
|
||||
placed element, not to the symbol, so everyone can decide for
|
||||
himself.
|
||||
*/
|
||||
void ElementInfoWidget::setupLabelShownRow()
|
||||
{
|
||||
//The box means something for a terminal only, so it is drawn
|
||||
//for a terminal only - the same rule as the function separation
|
||||
//box just below it.
|
||||
if (!m_element || m_element->elementData().m_type != ElementData::Terminal) {
|
||||
return;
|
||||
}
|
||||
m_label_shown_cb = new QCheckBox(tr("Show name"), this);
|
||||
m_label_shown_cb->setObjectName(QStringLiteral("m_label_shown_cb"));
|
||||
m_label_shown_cb->setToolTip(tr("Untick to not draw the name of this element on the sheet: "
|
||||
"its data is kept, and a terminal keeps its number."));
|
||||
|
||||
int row = ui->scroll_vlayout->indexOf(m_freeze_cb);
|
||||
if (row < 0) {
|
||||
ElementInfoPartWidget *label = infoPartWidgetForKey(QETInformation::ELMT_LABEL);
|
||||
row = label ? ui->scroll_vlayout->indexOf(label) : -1;
|
||||
}
|
||||
if (row >= 0) {
|
||||
ui->scroll_vlayout->insertWidget(row + 1, m_label_shown_cb);
|
||||
} else {
|
||||
ui->scroll_vlayout->addWidget(m_label_shown_cb);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief ElementInfoWidget::setupNumberRow
|
||||
Add under the numbering a list of the numbers the element may be given
|
||||
|
||||
@@ -76,6 +76,7 @@ class ElementInfoWidget : public AbstractElementPropertiesEditorWidget
|
||||
void updateSuggestions();
|
||||
void setupSchemeRow();
|
||||
void setupFreezeRow();
|
||||
void setupLabelShownRow();
|
||||
void setupNumberRow();
|
||||
void refreshNumberRow();
|
||||
void updateNumberRow();
|
||||
@@ -103,6 +104,7 @@ class ElementInfoWidget : public AbstractElementPropertiesEditorWidget
|
||||
QCheckBox *m_exclude_from_bom_cb = nullptr;
|
||||
QComboBox *m_scheme_cb = nullptr;
|
||||
QCheckBox *m_freeze_cb = nullptr;
|
||||
QCheckBox *m_label_shown_cb = nullptr;
|
||||
QWidget *m_number_row = nullptr;
|
||||
QComboBox *m_number_cb = nullptr;
|
||||
int m_number_current = -1; ///< the number the element has, -1 if unknown
|
||||
|
||||
@@ -75,6 +75,15 @@ quint64 s_last_session = 0;
|
||||
const QString EXCLUDE_FROM_BOM = QStringLiteral("exclude_from_bom");
|
||||
const QString AUTO_NUM_LOCKED = QStringLiteral("auto_num_locked");
|
||||
const QString POTENTIAL_ISOLATING = QStringLiteral("potential_isolating");
|
||||
//The name is drawn unless the element says otherwise (@sa
|
||||
//Element::labelShown): an element which never got the box unticked
|
||||
//has no information for it, and counts as "shown".
|
||||
const QString LABEL_SHOWN = QStringLiteral("label_shown");
|
||||
|
||||
bool flagDefaultIsOn(const QString &key)
|
||||
{
|
||||
return key == LABEL_SHOWN;
|
||||
}
|
||||
|
||||
QString flagText(bool on)
|
||||
{
|
||||
@@ -449,7 +458,8 @@ void MultiElementInfoWidget::buildInterface()
|
||||
const QList<QPair<QString, QString>> flags {
|
||||
{EXCLUDE_FROM_BOM, tr("Exclude from the bill of materials")},
|
||||
{POTENTIAL_ISOLATING, tr("Function separation")},
|
||||
{AUTO_NUM_LOCKED, tr("Exclude from automatic numbering")}
|
||||
{AUTO_NUM_LOCKED, tr("Exclude from automatic numbering")},
|
||||
{LABEL_SHOWN, tr("Show name")}
|
||||
};
|
||||
for (const auto &pair : flags)
|
||||
{
|
||||
@@ -486,6 +496,9 @@ void MultiElementInfoWidget::buildInterface()
|
||||
QStringList keys = QETInformation::elementInfoKeys();
|
||||
//It has its own check box above, see ElementInfoWidget::buildInterface
|
||||
keys.removeAll(EXCLUDE_FROM_BOM);
|
||||
//Not an editable property but derived from the label, see
|
||||
//ElementInfoWidget::buildInterface
|
||||
keys.removeAll(QETInformation::ELMT_TERMINAL_NUMBER);
|
||||
|
||||
int line = 0;
|
||||
for (const QString &key : std::as_const(keys))
|
||||
@@ -588,12 +601,19 @@ void MultiElementInfoWidget::fillRows()
|
||||
|
||||
for (Flag *flag : std::as_const(m_flags))
|
||||
{
|
||||
//"Show name" means something for a terminal only, so it is
|
||||
//shown for terminals only - the same rule as the two flags
|
||||
//before it.
|
||||
flag->check->setVisible(flag->key == EXCLUDE_FROM_BOM || all_terminals);
|
||||
flag->restore->setVisible(flag->check->isVisible());
|
||||
|
||||
int on = 0;
|
||||
for (Element *element : list) {
|
||||
if (QET::infoFlagIsTrue(m_snapshot.value(element).value(flag->key).toString())) {
|
||||
const QVariant value = m_snapshot.value(element).value(flag->key);
|
||||
const bool is_on = value.isValid()
|
||||
? QET::infoFlagIsTrue(value.toString())
|
||||
: flagDefaultIsOn(flag->key);
|
||||
if (is_on) {
|
||||
++on;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -323,6 +323,13 @@ qet_add_app_test(tst_reportfoliotitle tst_reportfoliotitle.cpp)
|
||||
# what was typed in, and nothing stale is written into the element.
|
||||
qet_add_app_test(tst_terminalcableauto tst_terminalcableauto.cpp)
|
||||
|
||||
# A terminal's label is drawn whole in one field, or split into its label
|
||||
# and its terminal number: in their own fields when the symbol carries a
|
||||
# field for the number, one under the other when it does not. Only the
|
||||
# drawing changes; the stored label, the numbering and the exports keep
|
||||
# the whole label.
|
||||
qet_add_app_test(tst_terminallabeldisplay tst_terminallabeldisplay.cpp)
|
||||
|
||||
# Escape during a picture's resize, rotate or pivot drag puts it back, keeps
|
||||
# it selected and records no undo step (#1414); the key goes to the view.
|
||||
qet_add_app_test(tst_imagehandleescape tst_imagehandleescape.cpp)
|
||||
|
||||
@@ -0,0 +1,487 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
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 "qetapptest.h"
|
||||
#include "TerminalStrip/realterminal.h"
|
||||
#include "TerminalStrip/terminalstrip.h"
|
||||
#include "dataBase/ui/elementquerywidget.h"
|
||||
#include "diagram.h"
|
||||
#include "ui/elementinfopartwidget.h"
|
||||
#include "ui/elementinfowidget.h"
|
||||
#include "ui/multielementinfowidget.h"
|
||||
#include <QLabel>
|
||||
#include <QListWidget>
|
||||
#include "properties/elementdata.h"
|
||||
#include "qetgraphicsitem/dynamicelementtextitem.h"
|
||||
#include "qetgraphicsitem/element.h"
|
||||
#include "qetgraphicsitem/terminal.h"
|
||||
#include "qetinformation.h"
|
||||
#include "qetproject.h"
|
||||
|
||||
/**
|
||||
How a terminal's own label is drawn, the terminal labelling of the
|
||||
project being read (@sa QETProject::terminalLabelSplit).
|
||||
|
||||
The label stays whole wherever it is used as data: what the element
|
||||
stores, the numbering, the sorting in the terminal strip editor and
|
||||
the exports are never touched by the setting. Only the drawing reacts:
|
||||
with the labelling split, the label ("X1") and the terminal number
|
||||
("1") are two parts -- in their own fields when the symbol has a
|
||||
field for the number, one under the other when it has not.
|
||||
|
||||
fixtures/every_feature.qet has the strip X1 whose terminals are
|
||||
plain terminal symbols: a field tagged "label", no field for the
|
||||
number, and -- as every element of the fixture -- a label the test
|
||||
gives them before it looks at the drawing.
|
||||
*/
|
||||
class tst_terminallabeldisplay : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
//A terminal element of the fixture's strip X1, given @p label
|
||||
static Element *terminalWithLabel(QETProject &project, const QString &label)
|
||||
{
|
||||
const QVector<TerminalStrip *> strips = project.terminalStrip();
|
||||
if (strips.isEmpty()) return nullptr;
|
||||
for (const QSharedPointer<RealTerminal> &real_t
|
||||
: strips.first()->realTerminals())
|
||||
{
|
||||
Element *element = real_t ? real_t->element() : nullptr;
|
||||
if (!element || element->terminals().isEmpty()) continue;
|
||||
|
||||
DiagramContext dc = element->elementInformations();
|
||||
dc.addValue(QStringLiteral("label"), label);
|
||||
element->setElementInformations(dc);
|
||||
if (element->actualLabel() == label) return element;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//The text field of @p element bound to @p info_name, the field the
|
||||
//symbol carries for it
|
||||
static DynamicElementTextItem *fieldBoundTo(Element *element, const QString &info_name)
|
||||
{
|
||||
for (DynamicElementTextItem *text : element->dynamicTextItems())
|
||||
if (text->infoName() == info_name) return text;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//A text field as a symbol made for the split would carry one: bound
|
||||
//to the terminal number, and nothing else
|
||||
static DynamicElementTextItem *addNumberField(Element *element)
|
||||
{
|
||||
DynamicElementTextItem *number = new DynamicElementTextItem(element);
|
||||
element->addDynamicTextItem(number);
|
||||
number->setInfoName(QETInformation::ELMT_TERMINAL_NUMBER);
|
||||
number->setTextFrom(DynamicElementTextItem::ElementInfo);
|
||||
return number;
|
||||
}
|
||||
|
||||
//The "Show name" box of the selection properties, unticked: the
|
||||
//element then stores the information "label_shown" = "false", the
|
||||
//only thing it stores for it
|
||||
static void hideName(Element *element)
|
||||
{
|
||||
DiagramContext dc = element->elementInformations();
|
||||
dc.addValue(QStringLiteral("label_shown"), QStringLiteral("false"));
|
||||
element->setElementInformations(dc);
|
||||
}
|
||||
|
||||
//Any element of the fixture which is not a terminal and carries a
|
||||
//name to draw
|
||||
static Element *aNonTerminal(QETProject &project)
|
||||
{
|
||||
for (Diagram *diagram : project.diagrams())
|
||||
for (Element *element : diagram->elements())
|
||||
if (element->elementData().m_type != ElementData::Terminal
|
||||
&& !element->actualLabel().isEmpty())
|
||||
return element;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//A non-terminal element of the fixture whose label field draws the
|
||||
//label it is given, colon and all: a terminal's own kind of drawing
|
||||
//is what the split changes, so the test needs an element which is
|
||||
//none of the things drawing a label of their own -- a report (its
|
||||
//label is where its partner is), a slave (its label follows its
|
||||
//master) or a numbered symbol (a formula composes its label)
|
||||
static Element *nonTerminalWithLabel(QETProject &project, const QString &label)
|
||||
{
|
||||
for (Diagram *diagram : project.diagrams())
|
||||
for (Element *element : diagram->elements())
|
||||
{
|
||||
if (element->elementData().m_type == ElementData::Terminal) {
|
||||
continue;
|
||||
}
|
||||
if (element->linkType() & (Element::Slave | Element::AllReport)) {
|
||||
continue;
|
||||
}
|
||||
DiagramContext dc = element->elementInformations();
|
||||
if (!dc.value(QStringLiteral("formula")).toString().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
dc.addValue(QStringLiteral("label"), label);
|
||||
element->setElementInformations(dc);
|
||||
if (element->actualLabel() != label) {
|
||||
continue;
|
||||
}
|
||||
//Only an element whose own label field draws the
|
||||
//label it stores: everything else draws a text of
|
||||
//its own, which this test would not understand
|
||||
DynamicElementTextItem *field = fieldBoundTo(element,
|
||||
QETInformation::ELMT_LABEL);
|
||||
if (!field || field->toPlainText() != label) {
|
||||
continue;
|
||||
}
|
||||
return element;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private slots:
|
||||
//The shipped default: one field with the whole label, the way it has
|
||||
//always been drawn
|
||||
void oneFieldKeepsTheWholeLabel()
|
||||
{
|
||||
const QString fixture = QFINDTESTDATA("fixtures/every_feature.qet");
|
||||
QETProject project(fixture);
|
||||
QCOMPARE(project.state(), QETProject::Ok);
|
||||
|
||||
Element *element = terminalWithLabel(project, QStringLiteral("X1:1"));
|
||||
QVERIFY2(element, "the fixture has a terminal of the strip X1");
|
||||
|
||||
QCOMPARE(element->actualLabel(), QStringLiteral("X1:1"));
|
||||
QCOMPARE(element->labelForDisplay(), QStringLiteral("X1:1"));
|
||||
QVERIFY(element->terminalNumberForDisplay().isEmpty());
|
||||
QVERIFY(element->infoForDisplay(QETInformation::ELMT_TERMINAL_NUMBER).isEmpty());
|
||||
QVERIFY(!element->hasTerminalNumberText());
|
||||
|
||||
//The field the symbol carries shows the whole label
|
||||
DynamicElementTextItem *label = fieldBoundTo(element, QETInformation::ELMT_LABEL);
|
||||
QVERIFY2(label, "the terminal symbol has a field for its label");
|
||||
QCOMPARE(label->toPlainText(), QStringLiteral("X1:1"));
|
||||
}
|
||||
|
||||
//Split, and the symbol has no field for the number: the number stays
|
||||
//with the label, on its own line, so that switching the setting on
|
||||
//can never make a number vanish
|
||||
void splitWithoutNumberFieldShowsTwoLines()
|
||||
{
|
||||
const QString fixture = QFINDTESTDATA("fixtures/every_feature.qet");
|
||||
QETProject project(fixture);
|
||||
QCOMPARE(project.state(), QETProject::Ok);
|
||||
project.setTerminalLabelSplit(true);
|
||||
|
||||
Element *element = terminalWithLabel(project, QStringLiteral("X1:1"));
|
||||
QVERIFY(element);
|
||||
|
||||
QCOMPARE(element->labelForDisplay(), QStringLiteral("X1\n1"));
|
||||
QCOMPARE(element->terminalNumberForDisplay(), QStringLiteral("1"));
|
||||
QCOMPARE(element->infoForDisplay(QETInformation::ELMT_TERMINAL_NUMBER),
|
||||
QStringLiteral("1"));
|
||||
|
||||
DynamicElementTextItem *label = fieldBoundTo(element, QETInformation::ELMT_LABEL);
|
||||
QVERIFY(label);
|
||||
QCOMPARE(label->toPlainText(), QStringLiteral("X1\n1"));
|
||||
|
||||
//A text which uses the label as a variable follows the same
|
||||
//rule as the field bound to the label itself
|
||||
DynamicElementTextItem *composite = new DynamicElementTextItem(element);
|
||||
composite->setCompositeText(QStringLiteral("%{label}"));
|
||||
composite->setTextFrom(DynamicElementTextItem::CompositeText);
|
||||
QCOMPARE(composite->toPlainText(), QStringLiteral("X1\n1"));
|
||||
}
|
||||
|
||||
//Split, and the symbol has a field of its own for the number: each
|
||||
//part in its field, the label no longer carrying the number
|
||||
void splitWithNumberFieldShowsEachInItsOwnField()
|
||||
{
|
||||
const QString fixture = QFINDTESTDATA("fixtures/every_feature.qet");
|
||||
QETProject project(fixture);
|
||||
QCOMPARE(project.state(), QETProject::Ok);
|
||||
project.setTerminalLabelSplit(true);
|
||||
|
||||
Element *element = terminalWithLabel(project, QStringLiteral("X1:1"));
|
||||
QVERIFY(element);
|
||||
|
||||
DynamicElementTextItem *number = addNumberField(element);
|
||||
QVERIFY(element->hasTerminalNumberText());
|
||||
QCOMPARE(number->toPlainText(), QStringLiteral("1"));
|
||||
|
||||
QCOMPARE(element->labelForDisplay(), QStringLiteral("X1"));
|
||||
DynamicElementTextItem *label = fieldBoundTo(element, QETInformation::ELMT_LABEL);
|
||||
QVERIFY(label);
|
||||
QCOMPARE(label->toPlainText(), QStringLiteral("X1"));
|
||||
}
|
||||
|
||||
//A label with no colon -- every label which is not a terminal's, and
|
||||
//a terminal named by hand -- is drawn as it is stored, whatever the
|
||||
//setting says
|
||||
void splitLeavesLabelsWithoutColonAlone()
|
||||
{
|
||||
const QString fixture = QFINDTESTDATA("fixtures/every_feature.qet");
|
||||
QETProject project(fixture);
|
||||
QCOMPARE(project.state(), QETProject::Ok);
|
||||
project.setTerminalLabelSplit(true);
|
||||
|
||||
Element *element = terminalWithLabel(project, QStringLiteral("S7"));
|
||||
QVERIFY(element);
|
||||
|
||||
QCOMPARE(element->labelForDisplay(), QStringLiteral("S7"));
|
||||
QVERIFY(element->terminalNumberForDisplay().isEmpty());
|
||||
|
||||
DynamicElementTextItem *label = fieldBoundTo(element, QETInformation::ELMT_LABEL);
|
||||
QVERIFY(label);
|
||||
QCOMPARE(label->toPlainText(), QStringLiteral("S7"));
|
||||
}
|
||||
|
||||
//The setting is read where it is drawn: the settings page tells the
|
||||
//drawings already open to draw it again, and the whole label comes
|
||||
//back without anything to rewrite first
|
||||
void switchingBackGivesTheWholeLabel()
|
||||
{
|
||||
const QString fixture = QFINDTESTDATA("fixtures/every_feature.qet");
|
||||
QETProject project(fixture);
|
||||
QCOMPARE(project.state(), QETProject::Ok);
|
||||
|
||||
project.setTerminalLabelSplit(true);
|
||||
Element *element = terminalWithLabel(project, QStringLiteral("X1:1"));
|
||||
QVERIFY(element);
|
||||
DynamicElementTextItem *label = fieldBoundTo(element, QETInformation::ELMT_LABEL);
|
||||
QVERIFY(label);
|
||||
QCOMPARE(label->toPlainText(), QStringLiteral("X1\n1"));
|
||||
|
||||
//The setter itself tells the labels of the drawings already
|
||||
//open to draw again: nothing else to ask for
|
||||
project.setTerminalLabelSplit(false);
|
||||
QCOMPARE(label->toPlainText(), QStringLiteral("X1:1"));
|
||||
QCOMPARE(element->actualLabel(), QStringLiteral("X1:1"));
|
||||
}
|
||||
|
||||
//A terminal whose name must not be drawn draws nothing of it, but
|
||||
//keeps everything: the stored label is still there, and so is every
|
||||
//use of it as data -- only the drawing changes
|
||||
void hiddenNameKeepsEverythingStored()
|
||||
{
|
||||
const QString fixture = QFINDTESTDATA("fixtures/every_feature.qet");
|
||||
QETProject project(fixture);
|
||||
QCOMPARE(project.state(), QETProject::Ok);
|
||||
|
||||
Element *element = terminalWithLabel(project, QStringLiteral("X1:1"));
|
||||
QVERIFY(element);
|
||||
hideName(element);
|
||||
|
||||
QVERIFY(!element->labelShown());
|
||||
QCOMPARE(element->actualLabel(), QStringLiteral("X1:1"));
|
||||
QCOMPARE(element->labelForDisplay(), QString());
|
||||
|
||||
DynamicElementTextItem *label = fieldBoundTo(element, QETInformation::ELMT_LABEL);
|
||||
QVERIFY(label);
|
||||
QCOMPARE(label->toPlainText(), QString());
|
||||
}
|
||||
|
||||
//Hidden, and the labelling is split: the terminal keeps its number,
|
||||
//drawn on its own line while the symbol has no field for it, so
|
||||
//hiding the name can never hide the number
|
||||
void hiddenNameKeepsTheNumberWithSplit()
|
||||
{
|
||||
const QString fixture = QFINDTESTDATA("fixtures/every_feature.qet");
|
||||
QETProject project(fixture);
|
||||
QCOMPARE(project.state(), QETProject::Ok);
|
||||
project.setTerminalLabelSplit(true);
|
||||
|
||||
Element *element = terminalWithLabel(project, QStringLiteral("X1:1"));
|
||||
QVERIFY(element);
|
||||
hideName(element);
|
||||
|
||||
QCOMPARE(element->labelForDisplay(), QStringLiteral("1"));
|
||||
QCOMPARE(element->terminalNumberForDisplay(), QStringLiteral("1"));
|
||||
QCOMPARE(element->actualLabel(), QStringLiteral("X1:1"));
|
||||
|
||||
DynamicElementTextItem *label = fieldBoundTo(element, QETInformation::ELMT_LABEL);
|
||||
QVERIFY(label);
|
||||
QCOMPARE(label->toPlainText(), QStringLiteral("1"));
|
||||
}
|
||||
|
||||
//Hidden, split, and the symbol has a field of its own for the
|
||||
//number: the number is drawn in its own field, the label field
|
||||
//draws nothing -- the number is never drawn twice
|
||||
void hiddenNameLeavesTheNumberToItsOwnField()
|
||||
{
|
||||
const QString fixture = QFINDTESTDATA("fixtures/every_feature.qet");
|
||||
QETProject project(fixture);
|
||||
QCOMPARE(project.state(), QETProject::Ok);
|
||||
project.setTerminalLabelSplit(true);
|
||||
|
||||
Element *element = terminalWithLabel(project, QStringLiteral("X1:1"));
|
||||
QVERIFY(element);
|
||||
DynamicElementTextItem *number = addNumberField(element);
|
||||
hideName(element);
|
||||
|
||||
QCOMPARE(element->labelForDisplay(), QString());
|
||||
DynamicElementTextItem *label = fieldBoundTo(element, QETInformation::ELMT_LABEL);
|
||||
QVERIFY(label);
|
||||
QCOMPARE(label->toPlainText(), QString());
|
||||
QCOMPARE(number->toPlainText(), QStringLiteral("1"));
|
||||
}
|
||||
|
||||
//Only a terminal may have its name undrawn: another element which
|
||||
//carries the same information still draws its name, whatever the
|
||||
//file says
|
||||
void nonTerminalAlwaysDrawsItsName()
|
||||
{
|
||||
const QString fixture = QFINDTESTDATA("fixtures/every_feature.qet");
|
||||
QETProject project(fixture);
|
||||
QCOMPARE(project.state(), QETProject::Ok);
|
||||
|
||||
Element *element = aNonTerminal(project);
|
||||
QVERIFY2(element, "the fixture has an element which is no terminal");
|
||||
DiagramContext dc = element->elementInformations();
|
||||
dc.addValue(QStringLiteral("label_shown"), QStringLiteral("false"));
|
||||
element->setElementInformations(dc);
|
||||
|
||||
//Whatever the file says, a non-terminal draws its name:
|
||||
//the information is not obeyed, and the drawn name is the
|
||||
//stored one, composed as it always is
|
||||
QVERIFY(element->labelShown());
|
||||
QVERIFY(!element->actualLabel().isEmpty());
|
||||
QCOMPARE(element->labelForDisplay(), element->actualLabel());
|
||||
}
|
||||
|
||||
//The labelling is drawn split for an element of the terminal type
|
||||
//only: the colon in the label of any other element ("-K1:13") is
|
||||
//part of the label, not a split waiting to happen
|
||||
void splitLeavesNonTerminalsWithColonAlone()
|
||||
{
|
||||
const QString fixture = QFINDTESTDATA("fixtures/every_feature.qet");
|
||||
QETProject project(fixture);
|
||||
QCOMPARE(project.state(), QETProject::Ok);
|
||||
project.setTerminalLabelSplit(true);
|
||||
|
||||
Element *element = nonTerminalWithLabel(project, QStringLiteral("-K1:13"));
|
||||
QVERIFY2(element,
|
||||
"the fixture has an element which is no terminal and draws the label it is given");
|
||||
|
||||
QCOMPARE(element->actualLabel(), QStringLiteral("-K1:13"));
|
||||
QCOMPARE(element->labelForDisplay(), QStringLiteral("-K1:13"));
|
||||
QVERIFY(element->terminalNumberForDisplay().isEmpty());
|
||||
|
||||
DynamicElementTextItem *label = fieldBoundTo(element, QETInformation::ELMT_LABEL);
|
||||
QVERIFY2(label, "the symbol has a field for its label");
|
||||
QCOMPARE(label->toPlainText(), QStringLiteral("-K1:13"));
|
||||
}
|
||||
|
||||
//The field of a hidden name does not stay on the sheet as an empty
|
||||
//frame to select: it leaves the sheet with the box and comes back
|
||||
//with it, both ways through the same signal
|
||||
void hiddenNameHidesTheLabelField()
|
||||
{
|
||||
const QString fixture = QFINDTESTDATA("fixtures/every_feature.qet");
|
||||
QETProject project(fixture);
|
||||
QCOMPARE(project.state(), QETProject::Ok);
|
||||
|
||||
Element *element = terminalWithLabel(project, QStringLiteral("X1:1"));
|
||||
QVERIFY(element);
|
||||
DynamicElementTextItem *label = fieldBoundTo(element, QETInformation::ELMT_LABEL);
|
||||
QVERIFY(label);
|
||||
QVERIFY(label->isVisible());
|
||||
|
||||
hideName(element);
|
||||
QVERIFY(!label->isVisible());
|
||||
|
||||
//The box ticked again: the element drops the information,
|
||||
//and the field is drawn as it was before
|
||||
DiagramContext dc = element->elementInformations();
|
||||
dc.remove(QStringLiteral("label_shown"));
|
||||
element->setElementInformations(dc);
|
||||
|
||||
QVERIFY(label->isVisible());
|
||||
QCOMPARE(label->toPlainText(), QStringLiteral("X1:1"));
|
||||
}
|
||||
|
||||
//The nomenclature/CSV export builds its columns from the element info
|
||||
//keys, but its query has no terminal_number column: offering the key
|
||||
//there made the export fail. The key itself stays an info key, so the
|
||||
//Bauteileditor keeps offering %{terminal_number} as a text variable
|
||||
void csvExportDoesNotOfferTerminalNumber()
|
||||
{
|
||||
ElementQueryWidget widget;
|
||||
QListWidget *offer = widget.findChild<QListWidget *>(QStringLiteral("m_var_list"));
|
||||
QVERIFY2(offer, "the widget which lists the exportable columns");
|
||||
|
||||
QStringList offered;
|
||||
for (int row = 0; row < offer->count(); ++row)
|
||||
offered.append(offer->item(row)->text());
|
||||
|
||||
const QString terminal_number = QETInformation::translatedInfoKey(
|
||||
QETInformation::ELMT_TERMINAL_NUMBER);
|
||||
QVERIFY2(!offered.contains(terminal_number),
|
||||
qPrintable(QStringLiteral("The export must not offer \"%1\"")
|
||||
.arg(terminal_number)));
|
||||
|
||||
//The other columns are still offered...
|
||||
QVERIFY(offered.contains(
|
||||
QETInformation::translatedInfoKey(QETInformation::ELMT_LABEL)));
|
||||
|
||||
//...and the variable is still a text variable
|
||||
QVERIFY(QETInformation::elementInfoKeys().contains(
|
||||
QETInformation::ELMT_TERMINAL_NUMBER));
|
||||
QCOMPARE(QETInformation::elementInfoToVar(QETInformation::ELMT_TERMINAL_NUMBER),
|
||||
QStringLiteral("%{terminal_number}"));
|
||||
}
|
||||
|
||||
//The properties of a terminal have no row for its number: the number
|
||||
//is derived from the label, so a row there would offer an edit which
|
||||
//stores a value nothing reads -- the export has no column for it, and
|
||||
//the drawing takes the number from the label
|
||||
void propertiesHaveNoRowForTheTerminalNumber()
|
||||
{
|
||||
const QString fixture = QFINDTESTDATA("fixtures/every_feature.qet");
|
||||
QETProject project(fixture);
|
||||
QCOMPARE(project.state(), QETProject::Ok);
|
||||
|
||||
Element *element = terminalWithLabel(project, QStringLiteral("X1:1"));
|
||||
QVERIFY(element);
|
||||
|
||||
//The properties of one element...
|
||||
ElementInfoWidget one(element);
|
||||
QStringList one_rows;
|
||||
const QList<ElementInfoPartWidget *> parts = one.findChildren<ElementInfoPartWidget *>();
|
||||
for (const ElementInfoPartWidget *part : parts)
|
||||
one_rows << part->key();
|
||||
QVERIFY2(one_rows.contains(QETInformation::ELMT_LABEL),
|
||||
"The other properties are still offered");
|
||||
QVERIFY2(!one_rows.contains(QETInformation::ELMT_TERMINAL_NUMBER),
|
||||
"The terminal number is no property of the element");
|
||||
|
||||
//...and the properties of several elements at once
|
||||
MultiElementInfoWidget many({element});
|
||||
QStringList rows;
|
||||
const QList<QLabel *> labels = many.findChildren<QLabel *>();
|
||||
for (const QLabel *label : labels)
|
||||
rows << label->text();
|
||||
QVERIFY2(rows.contains(QETInformation::translatedInfoKey(QETInformation::ELMT_LABEL)),
|
||||
"The other properties are still offered");
|
||||
QVERIFY2(!rows.contains(
|
||||
QETInformation::translatedInfoKey(QETInformation::ELMT_TERMINAL_NUMBER)),
|
||||
"The terminal number is no property of the element");
|
||||
}
|
||||
};
|
||||
|
||||
QET_APP_TEST_MAIN(tst_terminallabeldisplay)
|
||||
#include "tst_terminallabeldisplay.moc"
|
||||
Reference in New Issue
Block a user