mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-23 23:44:13 +02:00
Add a Show name box to the selection properties of a terminal
The box hides the name of the terminal on the sheet only: the element keeps all of its data, and with the labelling split the terminal keeps its number, drawn once - in its own field when the symbol has one, alone in the label field when it has not. Only a terminal may have its name undrawn: the box is shown for the element type Terminal alone, and Element::labelShown() obeys the stored information for a terminal only. The choice is stored as the element information "label_shown" = "false" and only that, so files of every element which still draws its name stay exactly as they are. Multi-selection: the flag appears for terminals only and counts an absent information as "shown", so a mixed selection shows the box ticked only when every terminal has it ticked. Includes four test cases: hidden name keeps the stored data, keeps the number without a number field, leaves the number to its own field, and a non-terminal draws its name whatever the file says.
This commit is contained in:
@@ -2769,7 +2769,28 @@ QString Element::actualLabel()
|
||||
QString Element::labelForDisplay()
|
||||
{
|
||||
const QString label = actualLabel();
|
||||
if (!QetSettings::terminalLabelSplit()) {
|
||||
const bool split = QetSettings::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;
|
||||
}
|
||||
|
||||
@@ -2837,6 +2858,29 @@ bool Element::hasTerminalNumberText() const
|
||||
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
|
||||
|
||||
@@ -175,6 +175,7 @@ class Element : public QetGraphicsItem
|
||||
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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -318,6 +324,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 +374,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 +680,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 +770,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 +864,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)
|
||||
{
|
||||
@@ -588,12 +598,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#include "qetapptest.h"
|
||||
#include "TerminalStrip/realterminal.h"
|
||||
#include "TerminalStrip/terminalstrip.h"
|
||||
#include "diagram.h"
|
||||
#include "properties/elementdata.h"
|
||||
#include "qetgraphicsitem/dynamicelementtextitem.h"
|
||||
#include "qetgraphicsitem/element.h"
|
||||
#include "qetgraphicsitem/terminal.h"
|
||||
@@ -85,6 +87,28 @@ class tst_terminallabeldisplay : public QObject
|
||||
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;
|
||||
}
|
||||
|
||||
private slots:
|
||||
void cleanup()
|
||||
{
|
||||
@@ -215,6 +239,102 @@ private slots:
|
||||
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()
|
||||
{
|
||||
QetSettings::setTerminalLabelSplit(false);
|
||||
|
||||
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()
|
||||
{
|
||||
QetSettings::setTerminalLabelSplit(true);
|
||||
|
||||
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);
|
||||
|
||||
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()
|
||||
{
|
||||
QetSettings::setTerminalLabelSplit(true);
|
||||
|
||||
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 *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()
|
||||
{
|
||||
QetSettings::setTerminalLabelSplit(false);
|
||||
|
||||
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());
|
||||
}
|
||||
};
|
||||
|
||||
QET_APP_TEST_MAIN(tst_terminallabeldisplay)
|
||||
|
||||
Reference in New Issue
Block a user