mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-23 15:34:12 +02:00
dfec60a3a5
A terminal's label is written as it is read off the plan, "X1:1", and
the symbol draws it as one field. On a long strip that field is long
enough to reach into the next terminal, and a user who wants the number
next to the screw and the label out of the way has no way to say so.
Settings > General > Appearance now has a "Display of the terminal
labelling" group with two choices: the label and its terminal number in
one field, the way it has always been drawn, or the two split. The
first is what every drawing gets, so nothing moves until the user asks
for it, and choosing the other one redraws the drawings already open --
nothing needs to be closed and opened again.
A symbol made for the split carries a text field bound to the new
"Terminal number" information (in the element editor's list, next to
the label, and as the %{terminal_number} variable of a composite text):
the label field then shows "X1" and the number field "1", each placed
where the symbol wants it, and hideable when it must be. A symbol which
has no such field -- every symbol drawn until now -- gets the number on
its own line inside the label field, so switching the setting on can
never make a number vanish, and never needs a symbol to be touched
first. A field which becomes, or stops being, the number field tells
the label fields of its symbol to draw themselves again.
Only the drawing reacts. What the element stores, the numbering, the
sorting in the terminal strip editor, the automatic strip import and
every export keep the whole label: the split is read where the text is
drawn (Element::labelForDisplay() and friends), not where the label is
made.
The new test covers both choices, with and without the number field, a
label with no colon at all, and the way back to the whole label. The
full test suite passes (124/124).
222 lines
8.3 KiB
C++
222 lines
8.3 KiB
C++
// 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 "qetgraphicsitem/dynamicelementtextitem.h"
|
|
#include "qetgraphicsitem/element.h"
|
|
#include "qetgraphicsitem/terminal.h"
|
|
#include "qetinformation.h"
|
|
#include "qetproject.h"
|
|
#include "utils/qetsettings.h"
|
|
|
|
/**
|
|
How a terminal's own label is drawn, the setting of the moment being
|
|
read (@sa QetSettings::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;
|
|
}
|
|
|
|
private slots:
|
|
void cleanup()
|
|
{
|
|
//Whatever a test left behind, the next one (and the rest of
|
|
//the suite) starts from the shipped default
|
|
QetSettings::setTerminalLabelSplit(false);
|
|
}
|
|
|
|
//The shipped default: one field with the whole label, the way it has
|
|
//always been drawn
|
|
void oneFieldKeepsTheWholeLabel()
|
|
{
|
|
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"));
|
|
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()
|
|
{
|
|
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);
|
|
|
|
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()
|
|
{
|
|
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);
|
|
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()
|
|
{
|
|
QetSettings::setTerminalLabelSplit(true);
|
|
|
|
const QString fixture = QFINDTESTDATA("fixtures/every_feature.qet");
|
|
QETProject project(fixture);
|
|
QCOMPARE(project.state(), QETProject::Ok);
|
|
|
|
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);
|
|
|
|
QetSettings::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"));
|
|
|
|
QetSettings::setTerminalLabelSplit(false);
|
|
element->refreshLabelFields();
|
|
QCOMPARE(label->toPlainText(), QStringLiteral("X1:1"));
|
|
QCOMPARE(element->actualLabel(), QStringLiteral("X1:1"));
|
|
}
|
|
};
|
|
|
|
QET_APP_TEST_MAIN(tst_terminallabeldisplay)
|
|
#include "tst_terminallabeldisplay.moc"
|