mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-11 22:54:12 +02:00
a2880ad79e
Two pieces of cable XML went into every file the program saved, whether the project had cables or not (non-blocking review comment by ispyisail). Resaving one of the example projects added both of them. - <cable_autonums> is now written only when it holds something: a named rule, an axis other than the default, the numbering question answered with no, or a rule of its own. When it is missing, the reader falls back to exactly the defaults a project which never touched cable numbering has, so nothing changes for those files. That is deliberately not "only when the project has cables", which would cost data: a rule configured before the first cable is drawn and an axis chosen before it are answers only this element can carry, and the question answered with no has to survive even if the cable which prompted it was cancelled again. - the font attribute of <xref> is now written only when there is one. Only the cable cross-reference has a font of its own; writing it unconditionally put font="" on every cross-reference type of every project, and an absent attribute reads back as no font, which is what all the others are. Verified by resaving examples/741.qet, examples/Projet_vierge.qet and examples/affuteuse_250h.qet: before, cable_autonums=1 and font="" on each; after, none of them. A cable project of the reviewer's own keeps <cable_autonums axis_priority="y" current_autonum="Cable"> with its rule and its real fonts, and only loses the four empty font attributes. ctest 92/93, the one failure being the pre-existing headless tst_menubarkeyboard.
275 lines
9.6 KiB
C++
275 lines
9.6 KiB
C++
/*
|
|
Copyright 2006-2026 The QElectroTech Team
|
|
This file is part of QElectroTech.
|
|
|
|
QElectroTech is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
QElectroTech is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
#include "xrefproperties.h"
|
|
|
|
#include "../qetapp.h"
|
|
|
|
#include <QHash>
|
|
#include <QMetaEnum>
|
|
|
|
namespace {
|
|
/**
|
|
@brief xrefPosFromKey
|
|
@param key : stored name of the position, e.g. "AlignBottom"
|
|
@return the position, or Qt::AlignBottom if key is empty or not one of
|
|
the positions the cross-reference settings offer. Older versions saved
|
|
an empty "xrefpos", which drew the cross-reference over the label.
|
|
*/
|
|
Qt::AlignmentFlag xrefPosFromKey(const QString &key)
|
|
{
|
|
bool ok = false;
|
|
const int value = QMetaEnum::fromType<Qt::Alignment>()
|
|
.keyToValue(key.toStdString().data(), &ok);
|
|
if (!ok)
|
|
return Qt::AlignBottom;
|
|
|
|
switch (value) {
|
|
case Qt::AlignBottom:
|
|
case Qt::AlignTop:
|
|
case Qt::AlignLeft:
|
|
case Qt::AlignRight:
|
|
case Qt::AlignBaseline:
|
|
case Qt::AlignHCenter:
|
|
return Qt::AlignmentFlag(value);
|
|
default:
|
|
return Qt::AlignBottom;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
@brief XRefProperties::XRefProperties
|
|
Default Constructor
|
|
*/
|
|
XRefProperties::XRefProperties()
|
|
{
|
|
m_show_power_ctc = true;
|
|
m_show_terminal_name = true;
|
|
m_show_all_configured_slaves = false;
|
|
m_stack_overlapping = true;
|
|
m_display = Cross;
|
|
m_snap_to = Bottom;
|
|
m_prefix_keys << "power" << "delay" << "switch";
|
|
m_master_label = "%f-%l%c";
|
|
m_slave_label = "(%f-%l%c)";
|
|
m_font = QString();
|
|
m_offset = 0;
|
|
m_slave_offset = 0;
|
|
m_xref_pos = Qt::AlignBottom;
|
|
}
|
|
|
|
/**
|
|
@brief XRefProperties::toSettings
|
|
Save to settings
|
|
@param settings: QSettings to use
|
|
@param prefix: prefix before properties name
|
|
*/
|
|
void XRefProperties::toSettings(QSettings &settings,
|
|
const QString prefix) const
|
|
{
|
|
settings.setValue(prefix % "showpowerctc", m_show_power_ctc);
|
|
settings.setValue(prefix % "showterminalname", m_show_terminal_name);
|
|
settings.setValue(prefix % "showallconfiguredslaves", m_show_all_configured_slaves);
|
|
settings.setValue(prefix % "stackoverlapping", m_stack_overlapping);
|
|
QString display = m_display == Cross? "cross" : "contacts";
|
|
settings.setValue(prefix % "displayhas", display);
|
|
QString snap = m_snap_to == Bottom? "bottom" : "label";
|
|
settings.setValue(prefix % "snapto", snap);
|
|
int offset = m_offset;
|
|
settings.setValue(prefix % "offset", offset);
|
|
int slave_offset = m_slave_offset;
|
|
settings.setValue(prefix % "slave_offset", slave_offset);
|
|
QString master_label = m_master_label;
|
|
settings.setValue(prefix % "master_label", master_label);
|
|
QString slave_label = m_slave_label;
|
|
settings.setValue(prefix % "slave_label", slave_label);
|
|
settings.setValue(prefix % "font", m_font);
|
|
|
|
|
|
QMetaEnum var = QMetaEnum::fromType<Qt::Alignment>();
|
|
settings.setValue(prefix % "xrefpos", var.valueToKey(m_xref_pos));
|
|
|
|
foreach (QString key, m_prefix.keys()) {
|
|
settings.setValue(prefix % key % "prefix", m_prefix.value(key));
|
|
}
|
|
}
|
|
|
|
/**
|
|
@brief XRefProperties::fromSettings
|
|
load from settings
|
|
@param settings: QSettings to use
|
|
@param prefix: prefix before properties name
|
|
*/
|
|
void XRefProperties::fromSettings(const QSettings &settings,
|
|
const QString prefix)
|
|
{
|
|
m_show_power_ctc = settings.value(prefix % "showpowerctc", true).toBool();
|
|
m_show_terminal_name = settings.value(prefix % "showterminalname", true).toBool();
|
|
m_show_all_configured_slaves = settings.value(prefix % "showallconfiguredslaves", false).toBool();
|
|
m_stack_overlapping = settings.value(prefix % "stackoverlapping", true).toBool();
|
|
QString display = settings.value(prefix % "displayhas", "cross").toString();
|
|
display == "cross"? m_display = Cross : m_display = Contacts;
|
|
QString snap = settings.value(prefix % "snapto", "label").toString();
|
|
snap == "bottom"? m_snap_to = Bottom : m_snap_to = Label;
|
|
m_offset = settings.value(prefix % "offset", "0").toInt();
|
|
m_slave_offset = settings.value(prefix % "slave_offset", "0").toInt();
|
|
m_master_label = settings.value(prefix % "master_label", "%f-%l%c").toString();
|
|
m_slave_label = settings.value(prefix % "slave_label", "(%f-%l%c)").toString();
|
|
m_font = settings.value(prefix % "font").toString();
|
|
|
|
m_xref_pos = xrefPosFromKey(settings.value(prefix % "xrefpos").toString());
|
|
|
|
for (QString key : m_prefix_keys) {
|
|
m_prefix.insert(key, settings.value(prefix + key % "prefix").toString());
|
|
}
|
|
}
|
|
|
|
/**
|
|
@brief XRefProperties::toXml
|
|
Save to xml
|
|
@param xml_document : QDomElement to use for saving
|
|
@return QDomElement
|
|
*/
|
|
QDomElement XRefProperties::toXml(QDomDocument &xml_document) const
|
|
{
|
|
|
|
QDomElement xml_element = xml_document.createElement("xref");
|
|
xml_element.setAttribute("type", m_key);
|
|
|
|
xml_element.setAttribute("showpowerctc", m_show_power_ctc? "true" : "false");
|
|
xml_element.setAttribute("showterminalname", m_show_terminal_name? "true" : "false");
|
|
xml_element.setAttribute("showallconfiguredslaves", m_show_all_configured_slaves? "true" : "false");
|
|
xml_element.setAttribute("stackoverlapping", m_stack_overlapping? "true" : "false");
|
|
QString display = m_display == Cross? "cross" : "contacts";
|
|
xml_element.setAttribute("displayhas", display);
|
|
QString snap = m_snap_to == Bottom? "bottom" : "label";
|
|
xml_element.setAttribute("snapto", snap);
|
|
|
|
QString xrefpos;
|
|
|
|
QMetaEnum var = QMetaEnum::fromType<Qt::Alignment>();
|
|
xml_element.setAttribute("xrefpos", var.valueToKey(m_xref_pos));
|
|
|
|
int offset = m_offset;
|
|
xml_element.setAttribute("offset", QString::number(offset));
|
|
xml_element.setAttribute("slave_offset", QString::number(m_slave_offset));
|
|
QString master_label = m_master_label;
|
|
xml_element.setAttribute("master_label", master_label);
|
|
QString slave_label = m_slave_label;
|
|
xml_element.setAttribute("slave_label", slave_label);
|
|
//Only the cable cross-reference has a font of its own, and only
|
|
//it ever sets one. Writing the attribute unconditionally put
|
|
//font="" on every cross-reference type of every project the
|
|
//program saved; a file which does not hold the attribute reads
|
|
//back as no font, which is what all of them are.
|
|
if (!m_font.isEmpty()) {
|
|
xml_element.setAttribute("font", m_font);
|
|
}
|
|
foreach (QString key, m_prefix.keys()) {
|
|
xml_element.setAttribute(key % "prefix", m_prefix.value(key));
|
|
}
|
|
|
|
return xml_element;
|
|
}
|
|
|
|
/**
|
|
@brief XRefProperties::fromXml
|
|
Load from xml
|
|
@param xml_element: QDomElement to use for load
|
|
*/
|
|
bool XRefProperties::fromXml(const QDomElement &xml_element) {
|
|
m_show_power_ctc = xml_element.attribute("showpowerctc") == "true";
|
|
m_show_terminal_name = xml_element.attribute("showterminalname", "true") == "true";
|
|
m_show_all_configured_slaves = xml_element.attribute("showallconfiguredslaves", "false") == "true";
|
|
m_stack_overlapping = xml_element.attribute("stackoverlapping", "true") == "true";
|
|
QString display = xml_element.attribute("displayhas", "cross");
|
|
display == "cross"? m_display = Cross : m_display = Contacts;
|
|
QString snap = xml_element.attribute("snapto", "label");
|
|
snap == "bottom"? m_snap_to = Bottom : m_snap_to = Label;
|
|
|
|
m_xref_pos = xrefPosFromKey(xml_element.attribute("xrefpos"));
|
|
|
|
m_offset = xml_element.attribute("offset", "0").toInt();
|
|
m_slave_offset = xml_element.attribute("slave_offset", "0").toInt();
|
|
m_master_label = xml_element.attribute("master_label", "%f-%l%c");
|
|
m_slave_label = xml_element.attribute("slave_label","(%f-%l%c)");
|
|
m_font = xml_element.attribute("font");
|
|
foreach (QString key, m_prefix_keys) {
|
|
m_prefix.insert(key, xml_element.attribute(key % "prefix"));
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
@brief XRefProperties::defaultProperties
|
|
@return the default properties stored in the setting file
|
|
One entry per kind of element which shows a cross reference, stored
|
|
under its own key: "coil", "protection", "commutator", "plc" -- and
|
|
"cable", which is not an element at all: it is the reference a cable
|
|
writes in the label of each of its sections when the cable runs on
|
|
several folios.
|
|
*/
|
|
QHash<QString, XRefProperties> XRefProperties::defaultProperties()
|
|
{
|
|
QHash <QString, XRefProperties> hash;
|
|
QStringList keys;
|
|
keys << "coil" << "protection" << "commutator" << "plc" << "cable";
|
|
|
|
QSettings settings;
|
|
|
|
foreach (QString key, keys)
|
|
{
|
|
XRefProperties properties;
|
|
QString str("diagrameditor/defaultxref");
|
|
properties.fromSettings(settings, str += key);
|
|
|
|
//A cable takes the very same default text as a relay master
|
|
//and the other types, "%f-%l%c": what it names is then the
|
|
//other section of the cable -- the folio it stands on and
|
|
//the place it stands at there, which is what an element
|
|
//points at as well. No default of its own, so that setting
|
|
//the five of them apart needs no thought at all.
|
|
hash.insert(key, properties);
|
|
}
|
|
|
|
return hash;
|
|
}
|
|
|
|
bool XRefProperties::operator ==(const XRefProperties &xrp) const{
|
|
return (m_show_power_ctc == xrp.m_show_power_ctc
|
|
&& m_show_terminal_name == xrp.m_show_terminal_name
|
|
&& m_show_all_configured_slaves == xrp.m_show_all_configured_slaves
|
|
&& m_stack_overlapping == xrp.m_stack_overlapping
|
|
&& m_display == xrp.m_display
|
|
&& m_snap_to == xrp.m_snap_to
|
|
&& m_prefix == xrp.m_prefix
|
|
&& m_master_label== xrp.m_master_label
|
|
&& m_offset == xrp.m_offset
|
|
&& m_slave_offset== xrp.m_slave_offset
|
|
&& m_xref_pos == xrp.m_xref_pos
|
|
&& m_slave_label == xrp.m_slave_label
|
|
&& m_font == xrp.m_font);
|
|
}
|
|
|
|
bool XRefProperties::operator !=(const XRefProperties &xrp) const
|
|
{
|
|
return (! (*this == xrp));
|
|
}
|
|
|
|
|