Files
qelectrotech-source-mirror/sources/autoNum/assignvariables.cpp
T
ispyisail 6f7e537db3 Let a Cyclique (modulo) part actually be displayed: %seqw_N
Reported by @scorpio810 on #632 with a screenshot: a "Chiffre 1" followed by
a "Cyclique (modulo) 8" numbers elements 0..7 and then jumps straight to 9,
never showing 8, and never producing the 0-7 / 10-17 / 20-27 pattern the
feature exists for.

The cause is that the wrap-and-carry feature shipped without its rendering
half. Commit 68c2603 added the arithmetic and the editor UI across seven
files, none of them assignvariables.*, so there is no %seqw_ variable, no
wrap list in sequentialNumbers, no branch in setSequential(), and no branch
in numerotationContextToFormula(). A cyclic part therefore contributes
nothing to the generated formula and cannot be referenced from one -- it is
invisible.

Invisible but not inert: it still advances and still carries. So the digit
in front of it receives +1 from the carry on top of its own increment, and
the only digit the label does show jumps by two. That is the missing 8.

Add the missing half:
  - sequentialNumbers gains a wrap list, handled in the copy constructor,
    assignment, comparison, clear(), toXml() and fromXml();
  - setSequential() collects wrap parts when the label uses %seqw_;
  - assignSequence() substitutes %seqw_N and counts wrap in its bound, so a
    context whose only counter is cyclic still resolves;
  - numerotationContextToFormula() emits %seqw_N, so adding a Cyclique part
    in the editor now puts a token in the formula instead of nothing.

Old projects are unaffected: <wrap> is simply absent from files written
before this, which fromXml() reads as an empty list, and such files have no
cyclic parts to reference in the first place. An older QET reading a newer
file ignores the unknown child.

Measured on the exact configuration from the report, unit + wrap(mod 8):

  formula generated   %sequ_1%seqw_1   (was %sequ_1 -- wrap contributed none)

  carry digit increment 1   00 11 22 33 44 55 66 77 90 101 112 ...
  carry digit increment 0   00 01 02 03 04 05 06 07 10 11 ... 17 20 21

The second line is the requested pattern. The first shows what is left once
the rendering is fixed but the carry digit still increments itself as well
as receiving the carry -- worth a UI decision, noted on the PR.
2026-08-02 18:46:28 +12:00

820 lines
25 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 "assignvariables.h"
#include "../diagram.h"
#include "../diagramposition.h"
#include "../qetapp.h"
#include "../qetgraphicsitem/conductor.h"
#include "../qetgraphicsitem/element.h"
#include "../qetxml.h"
#include "../qetproject.h"
#include <QStringList>
#include <QVariant>
#include <utility>
namespace autonum
{
/**
@brief sequentialNumbers::sequentialNumbers
*/
sequentialNumbers::sequentialNumbers()
{}
sequentialNumbers::sequentialNumbers(const sequentialNumbers &other)
{
unit = other.unit;
wrap = other.wrap;
unit_folio = other.unit_folio;
ten = other.ten;
ten_folio = other.ten_folio;
hundred = other.hundred;
hundred_folio = other.hundred_folio;
alpha = other.alpha;
}
sequentialNumbers::~sequentialNumbers()
{}
sequentialNumbers &sequentialNumbers::operator=(
const sequentialNumbers &other)
{
if (&other == this || other == *this)
return (*this);
unit = other.unit;
wrap = other.wrap;
unit_folio = other.unit_folio;
ten = other.ten;
ten_folio = other.ten_folio;
hundred = other.hundred;
hundred_folio = other.hundred_folio;
alpha = other.alpha;
return (*this);
}
bool sequentialNumbers::operator==(const sequentialNumbers &other) const
{
if (unit == other.unit && \
wrap == other.wrap && \
unit_folio == other.unit_folio && \
ten == other.ten && \
ten_folio == other.ten_folio && \
hundred == other.hundred && \
hundred_folio == other.hundred_folio && \
alpha == other.alpha)
return true;
else
return false;
}
bool sequentialNumbers::operator!=(const sequentialNumbers &other) const
{
if (*this == other)
return false;
else
return true;
}
/**
@brief sequentialNumbers::toXml
export this sequential numbers into a QDomElement.
@param document : QDomDocument used to create the QDomElement
@param tag_name : the tag name used for the QDomElement.
@return A QDomElement, if this sequential have no value,
the returned QDomELement is empty
*/
QDomElement sequentialNumbers::toXml(QDomDocument &document,
const QString& tag_name) const
{
QDomElement element = document.createElement(tag_name);
if (!unit.isEmpty())
element.appendChild(QETXML::textToDomElement(
document,
"unit",
unit.join(";")));
if (!wrap.isEmpty())
element.appendChild(QETXML::textToDomElement(
document,
"wrap",
wrap.join(";")));
if (!unit_folio.isEmpty())
element.appendChild(QETXML::textToDomElement(
document,
"unitFolio",
unit_folio.join(";")));
if(!ten.isEmpty())
element.appendChild(QETXML::textToDomElement(
document,
"ten",
ten.join(";")));
if(!ten_folio.isEmpty())
element.appendChild(QETXML::textToDomElement(
document,
"tenFolio",
ten_folio.join(";")));
if(!hundred.isEmpty())
element.appendChild(QETXML::textToDomElement(
document,
"hundred",
hundred.join(";")));
if(!hundred_folio.isEmpty())
element.appendChild(QETXML::textToDomElement(
document,
"hundredFolio",
hundred_folio.join(";")));
if(!alpha.isEmpty())
element.appendChild(QETXML::textToDomElement(
document,
"alpha",
alpha.join(";")));
return element;
}
/**
@brief sequentialNumbers::fromXml
Import sequential values from a QDomElement
@param element
*/
void sequentialNumbers::fromXml(const QDomElement &element)
{
if (!element.hasChildNodes())
return;
QDomElement from;
from = element.firstChildElement("unit");
unit = from.text().split(";");
//Absent from files written before cyclic parts could be
//rendered; an empty list is the correct reading of that.
from = element.firstChildElement("wrap");
wrap = from.text().split(";");
from = element.firstChildElement("unitFolio");
unit_folio = from.text().split(";");
from = element.firstChildElement("ten");
ten = from.text().split(";");
from = element.firstChildElement("tenFolio");
ten_folio = from.text().split(";");
from = element.firstChildElement("hundred");
hundred = from.text().split(";");
from = element.firstChildElement("hundredFolio");
hundred_folio = from.text().split(";");
from = element.firstChildElement("alpha");
alpha = from.text().split(";");
}
//Clear this sequence
void sequentialNumbers::clear()
{
unit.clear();
wrap.clear();
unit_folio.clear();
ten.clear();
ten_folio.clear();
hundred.clear();
hundred_folio.clear();
alpha.clear();
}
/**
@brief AssignVariables::formulaToLabel
Return the formula with variable assigned
(ready to be displayed)
@param formula - the formula to work
@param seqStruct - struct where is stocked int values
(struct is passed as a reference
and modified by this static method)
@param diagram - the diagram where occure the formula.
@param elmt - parent element (if any) of the formula
@return the string with variable assigned.
*/
QString AssignVariables::formulaToLabel(QString formula,
sequentialNumbers &seqStruct,
Diagram *diagram,
const Element *elmt,
const Conductor *cndr)
{
AssignVariables av(std::move(formula),
seqStruct,
diagram,
elmt,
cndr);
seqStruct = av.m_seq_struct;
return av.m_assigned_label;
}
/**
@brief AssignVariables::replaceVariable
Replace the variables in formula in form %{my-var}
to the corresponding value stored in dc
@param formula
@param dc
@return
*/
QString AssignVariables::replaceVariable(const QString &formula,
const DiagramContext &dc)
{
QString str = formula;
str.replace("%{label}", dc.value("label").toString());
str.replace("%{plant}", dc.value("plant").toString());
str.replace("%{comment}", dc.value("comment").toString());
str.replace("%{description}", dc.value("description").toString());
str.replace("%{designation}", dc.value("designation").toString());
str.replace("%{manufacturer}", dc.value("manufacturer").toString());
str.replace("%{manufacturer_reference}",
dc.value("manufacturer_reference").toString());
str.replace("%{supplier}", dc.value("supplier").toString());
str.replace("%{quantity}", dc.value("quantity").toString());
str.replace("%{unity}", dc.value("unity").toString());
str.replace("%{auxiliary1}", dc.value("auxiliary1").toString());
str.replace("%{description_auxiliary1}", dc.value("description_auxiliary1").toString());
str.replace("%{designation_auxiliary1}", dc.value("designation_auxiliary1").toString());
str.replace("%{manufacturer_auxiliary1}", dc.value("manufacturer_auxiliary1").toString());
str.replace("%{manufacturer_reference_auxiliary1}", dc.value("manufacturer_reference_auxiliary1").toString());
str.replace("%{supplier_auxiliary1}", dc.value("supplier_auxiliary1").toString());
str.replace("%{quantity_auxiliary1}", dc.value("quantity_auxiliary1").toString());
str.replace("%{unity_auxiliary1}", dc.value("unity_auxiliary1").toString());
str.replace("%{auxiliary2}", dc.value("auxiliary2").toString());
str.replace("%{description_auxiliary2}", dc.value("description_auxiliary2").toString());
str.replace("%{designation_auxiliary2}", dc.value("designation_auxiliary2").toString());
str.replace("%{manufacturer_auxiliary2}", dc.value("manufacturer_auxiliary2").toString());
str.replace("%{manufacturer_reference_auxiliary2}", dc.value("manufacturer_reference_auxiliary2").toString());
str.replace("%{supplier_auxiliary2}", dc.value("supplier_auxiliary2").toString());
str.replace("%{quantity_auxiliary2}", dc.value("quantity_auxiliary2").toString());
str.replace("%{unity_auxiliary2}", dc.value("unity_auxiliary2").toString());
str.replace("%{auxiliary3}", dc.value("auxiliary3").toString());
str.replace("%{description_auxiliary3}", dc.value("description_auxiliary3").toString());
str.replace("%{designation_auxiliary3}", dc.value("designation_auxiliary3").toString());
str.replace("%{manufacturer_auxiliary3}", dc.value("manufacturer_auxiliary3").toString());
str.replace("%{manufacturer_reference_auxiliary3}", dc.value("manufacturer_reference_auxiliary3").toString());
str.replace("%{supplier_auxiliary3}", dc.value("supplier_auxiliary3").toString());
str.replace("%{quantity_auxiliary3}", dc.value("quantity_auxiliary3").toString());
str.replace("%{unity_auxiliary3}", dc.value("unity_auxiliary3").toString());
str.replace("%{auxiliary4}", dc.value("auxiliary4").toString());
str.replace("%{description_auxiliary4}", dc.value("description_auxiliary4").toString());
str.replace("%{designation_auxiliary4}", dc.value("designation_auxiliary4").toString());
str.replace("%{manufacturer_auxiliary4}", dc.value("manufacturer_auxiliary4").toString());
str.replace("%{manufacturer_reference_auxiliary4}", dc.value("manufacturer_reference_auxiliary4").toString());
str.replace("%{supplier_auxiliary4}", dc.value("supplier_auxiliary4").toString());
str.replace("%{quantity_auxiliary4}", dc.value("quantity_auxiliary4").toString());
str.replace("%{unity_auxiliary4}", dc.value("unity_auxiliary4").toString());
str.replace("%{machine_manufacturer_reference}", dc.value("machine_manufacturer_reference").toString());
str.replace("%{location}", dc.value("location").toString());
str.replace("%{function}", dc.value("function").toString());
str.replace("%{tension_protocol}", dc.value("tension_protocol").toString());
str.replace("%{conductor_section}", dc.value("conductor_section").toString());
str.replace("%{conductor_color}", dc.value("conductor_color").toString());
str.replace("%{void}", QString());
str.replace("%{plc_type}", dc.value("plc_type").toString());
str.replace("%{plc_address}", dc.value("plc_address").toString());
str.replace("%{plc_function}", dc.value("plc_function").toString());
str.replace("%{plc_comment}", dc.value("plc_comment").toString());
str.replace("%{plc_crossref}", dc.value("plc_crossref").toString());
str.replace("%{plc_tc}", dc.value("plc_tc").toString());
str.replace("%{plc_t1}", dc.value("plc_t1").toString());
str.replace("%{plc_t2}", dc.value("plc_t2").toString());
str.replace("%{plc_t3}", dc.value("plc_t3").toString());
str.replace("%{plc_t4}", dc.value("plc_t4").toString());
return str;
}
/**
* @brief AssignVariables::genericXref
* @param element
* @return a simple Xref string in form of 'folio-letterNumber'
*/
QString AssignVariables::genericXref(const Element *element)
{
QString str;
if (!element->diagram()) {
return str;
}
QSettings settings;
auto diagram = element->diagram();
if (settings.value(QLatin1String("genericpanel/folio"), true).toBool()) {
str = diagram->border_and_titleblock.finalfolio();
} else {
str = QString::number(diagram->folioIndex()+1);
}
str.append("-");
str.append(diagram->convertPosition(element->scenePos()).toString());
return str;
}
AssignVariables::AssignVariables(const QString& formula,
const sequentialNumbers& seqStruct,
Diagram *diagram,
const Element *elmt,
const Conductor *cndr):
m_diagram(diagram),
m_arg_formula(formula),
m_assigned_label(formula),
m_seq_struct(seqStruct),
m_element(elmt),
m_conductor(cndr)
{
if (m_diagram)
{
m_assigned_label.replace("%F",
m_diagram
-> border_and_titleblock
.folio());
m_assigned_label.replace("%f",
QString::number(
m_diagram
->folioIndex()+1));
m_assigned_label.replace("%id",
QString::number(
m_diagram
->folioIndex()+1));
m_assigned_label.replace("%total",
QString::number(
m_diagram
->border_and_titleblock
.folioTotal()));
m_assigned_label.replace("%M",
m_diagram
-> border_and_titleblock
.plant());
m_assigned_label.replace("%LM",
m_diagram
-> border_and_titleblock
.locmach());
QSettings settings;
if (m_element)
{
if (settings.value("border-columns_0", true).toBool()){
m_assigned_label.replace("%c", QString::number(m_diagram->convertPosition(m_element->scenePos()).number() - 1));
}else{
m_assigned_label.replace("%c", QString::number(m_diagram->convertPosition(m_element->scenePos()).number()));
}
m_assigned_label.replace("%l", m_diagram->convertPosition(m_element->scenePos()).letter());
m_assigned_label.replace("%prefix", m_element->getPrefix());
}
if (m_conductor)
{
m_assigned_label.replace("%wf", cndr->properties().m_function);
m_assigned_label.replace("%wv", cndr->properties().m_tension_protocol);
m_assigned_label.replace("%wc", cndr->properties().m_wire_color);
m_assigned_label.replace("%ws", cndr->properties().m_wire_section);
}
assignTitleBlockVar();
assignProjectVar();
assignSequence();
}
}
void AssignVariables::assignTitleBlockVar()
{
for (int i = 0; i < m_diagram->border_and_titleblock.additionalFields().count(); i++)
{
QString folio_variable = m_diagram->border_and_titleblock.additionalFields().keys().at(i);
QVariant folio_value = m_diagram->border_and_titleblock.additionalFields().operator [](folio_variable);
if (m_assigned_label.contains(folio_variable)) {
m_assigned_label.replace("%{" + folio_variable + "}", folio_value.toString());
m_assigned_label.replace("%" + folio_variable , folio_value.toString());
}
}
}
void AssignVariables::assignProjectVar()
{
for (int i = 0; i < m_diagram->project()->projectProperties().count(); i++)
{
QString folio_variable = m_diagram->project()->projectProperties().keys().at(i);
QVariant folio_value = m_diagram->project()->projectProperties().operator [](folio_variable);
if (m_assigned_label.contains(folio_variable)) {
m_assigned_label.replace("%{" + folio_variable + "}", folio_value.toString());
m_assigned_label.replace("%" + folio_variable , folio_value.toString());
}
}
}
void AssignVariables::assignSequence()
{
int max = qMax(
qMax(
qMax(m_seq_struct.unit_folio.size(),
m_seq_struct.ten_folio.size()),
qMax(m_seq_struct.hundred_folio.size(),
m_seq_struct.unit.size())),
qMax(
qMax(m_seq_struct.hundred.size(),
m_seq_struct.ten.size()),
qMax(m_seq_struct.alpha.size(),
m_seq_struct.wrap.size()))
);
for (int i=1; i<=max ; i++)
{
if (m_assigned_label.contains("%sequ_" + QString::number(i)) && m_seq_struct.unit.size() >= i) {
m_assigned_label.replace("%sequ_" + QString::number(i),m_seq_struct.unit.at(i-1));
}
if (m_assigned_label.contains("%seqw_" + QString::number(i)) && m_seq_struct.wrap.size() >= i) {
m_assigned_label.replace("%seqw_" + QString::number(i),m_seq_struct.wrap.at(i-1));
}
if (m_assigned_label.contains("%seqt_" + QString::number(i)) && m_seq_struct.ten.size() >= i) {
m_assigned_label.replace("%seqt_" + QString::number(i),m_seq_struct.ten.at(i-1));
}
if (m_assigned_label.contains("%seqh_" + QString::number(i)) && m_seq_struct.hundred.size() >= i) {
m_assigned_label.replace("%seqh_" + QString::number(i),m_seq_struct.hundred.at(i-1));
}
if (m_assigned_label.contains("%sequf_" + QString::number(i)) && m_seq_struct.unit_folio.size() >= i) {
m_assigned_label.replace("%sequf_" + QString::number(i),m_seq_struct.unit_folio.at(i-1));
}
if (m_assigned_label.contains("%seqtf_" + QString::number(i)) && m_seq_struct.ten_folio.size() >= i) {
m_assigned_label.replace("%seqtf_" + QString::number(i),m_seq_struct.ten_folio.at(i-1));
}
if (m_assigned_label.contains("%seqhf_" + QString::number(i)) && m_seq_struct.hundred_folio.size() >= i) {
m_assigned_label.replace("%seqhf_" + QString::number(i),m_seq_struct.hundred_folio.at(i-1));
}
if (m_assigned_label.contains("%seqa_" + QString::number(i)) && m_seq_struct.alpha.size() >= i) {
m_assigned_label.replace("%seqa_" + QString::number(i),m_seq_struct.alpha.at(i-1));
}
}
}
/**
@brief setSequentialToList
Append all sequential of type type owned by context in list
@param list : list to have value inserted
@param context : numerotation context to retrieve value
@param type : type of sequential
(unit, unitfolio, ten, tenfolio, hundred, hundredfolio)
*/
void setSequentialToList(QStringList &list,
NumerotationContext &context,
const QString& type)
{
for (int i = 0; i < context.size(); i++)
{
if (context.itemAt(i).at(0) == type)
{
QString number;
if (type == "ten" || type == "tenfolio")
number = QString("%1").arg(context.itemAt(i).at(1).toInt(), 2, 10, QChar('0'));
else if (type == "hundred" || type == "hundredfolio")
number = QString("%1").arg(context.itemAt(i).at(1).toInt(), 3, 10, QChar('0'));
else if (type == "alpha")
//Alphabetic value, not an integer -- used as-is.
number = context.itemAt(i).at(1);
else number = QString::number(context.itemAt(i).at(1).toInt());
list.append(number);
}
}
}
/**
@brief setFolioSequentialToHash
Insert all value of list in hash with key autoNumName
@param list : list to get values from
@param hash : hash to have values inserted
@param autoNumName : name to use as key of hash
*/
void setFolioSequentialToHash(QStringList &list,
QHash<QString,
QStringList> &hash,
const QString& autoNumName)
{
if (hash.isEmpty() || !hash.contains(autoNumName))
{
QStringList max;
for (int i = 0; i < list.size(); i++)
{
max.append(list.at(i));
}
hash.insert(autoNumName,max);
}
else if (hash.contains(autoNumName))
{
//Load the String List and update it
QStringList max = hash.value(autoNumName);
for (int i = 0; i < list.size(); i++)
{
if ((list.at(i).toInt()) > max.at(i).toInt())
{
max.replace(i,list.at(i));
hash.remove(autoNumName);
hash.insert(autoNumName,max);
}
}
}
}
/**
@brief setSequential
Fill seqStruct
@param label : label of sequential to fill
(%sequ_, %sequf_, %seqt_, ect....)
@param seqStruct : struct to fill
@param context : numerotation context use
to know the current sequential num.
@param diagram : diagram where the sequential occur,
notably use when label is folio type
(%sequf_, %seqtf_, %seqhf_),
to keep up to date the current sequential of folio.
@param hashKey :
the hash key used to store the sequential for folio type.
*/
void setSequential(const QString& label, sequentialNumbers &seqStruct, NumerotationContext &context, Diagram *diagram, const QString& hashKey)
{
if (!context.isEmpty())
{
if (label.contains("%sequ_"))
{
autonum::setSequentialToList(seqStruct.unit, context,"unit");
}
if (label.contains("%seqw_"))
{
autonum::setSequentialToList(seqStruct.wrap, context,"wrap");
}
if (label.contains("%sequf_"))
{
autonum::setSequentialToList(seqStruct.unit_folio, context,"unitfolio");
autonum::setFolioSequentialToHash(seqStruct.unit_folio, diagram->m_elmt_unitfolio_max, hashKey);
}
if (label.contains("%seqt_"))
{
autonum::setSequentialToList(seqStruct.ten, context,"ten");
}
if (label.contains("%seqtf_"))
{
autonum::setSequentialToList(seqStruct.ten_folio, context,"tenfolio");
autonum::setFolioSequentialToHash(seqStruct.ten_folio, diagram->m_elmt_tenfolio_max, hashKey);
}
if (label.contains("%seqh_"))
{
autonum::setSequentialToList(seqStruct.hundred, context,"hundred");
}
if (label.contains("%seqhf_"))
{
autonum::setSequentialToList(seqStruct.hundred_folio, context,"hundredfolio");
autonum::setFolioSequentialToHash(seqStruct.hundred_folio, diagram->m_elmt_hundredfolio_max, hashKey);
}
if (label.contains("%seqa_"))
{
autonum::setSequentialToList(seqStruct.alpha, context,"alpha");
}
}
}
/**
@brief numerotationContextToFormula
@param nc
@return the numerotation context, converted to formula
*/
QString numerotationContextToFormula(const NumerotationContext &nc)
{
QString type;
QString value;
QString formula;
int count_unit = 0;
int count_wrap = 0;
int count_unitf = 0;
int count_ten = 0;
int count_tenf = 0;
int count_hundred = 0;
int count_hundredf = 0;
int count_alpha = 0;
for(int i=0 ; i<nc.size() ; i++)
{
type = nc.itemAt(i).at(0);
value = nc.itemAt(i).at(1);
if (type == "idfolio") {
formula.append("%id");
}
else if (type == "folio") {
formula.append("%F");
}
else if (type == "plant") {
formula.append("%M");
}
else if (type == "locmach") {
formula.append("%LM");
}
else if (type == "elementcolumn") {
formula.append("%c");
}
else if (type == "elementline") {
formula.append("%l");
}
else if (type == "elementprefix") {
formula.append("%prefix");
}
else if (type == "string") {
formula.append(value);
}
else if (type == "unit") {
count_unit++;
formula.append("%sequ_" + QString::number(count_unit));
}
else if (type == "wrap") {
count_wrap++;
formula.append("%seqw_" + QString::number(count_wrap));
}
else if (type == "unitfolio") {
count_unitf++;
formula.append("%sequf_" + QString::number(count_unitf));
}
else if (type == "ten") {
count_ten++;
formula.append("%seqt_" + QString::number(count_ten));
}
else if (type == "tenfolio") {
count_tenf++;
formula.append("%seqtf_" + QString::number(count_tenf));
}
else if (type == "hundred") {
count_hundred++;
formula.append("%seqh_" + QString::number(count_hundred));
}
else if (type == "hundredfolio") {
count_hundredf++;
formula.append("%seqhf_" + QString::number(count_hundredf));
}
else if (type == "alpha") {
count_alpha++;
formula.append("%seqa_" + QString::number(count_alpha));
}
}
return formula;
}
/**
@brief elementPrefixForLocation
@param location
@return the prefix for an element represented by location,
prefix can be null.
Search for a prefix only if location represent
an element embedded in a project
*/
QString elementPrefixForLocation(const ElementsLocation &location)
{
if (!location.isProject())
return QString();
QXmlStreamReader rxml;
QString path[10];
int i = -1;
ElementsLocation current_location = location;
int dirLevel = -1;
//Add location name to path array
while((current_location.parent() != current_location) && (current_location.parent().fileName() != "import"))
{
i++;
path[i]=current_location.fileName();
current_location = current_location.parent();
dirLevel++;
}
//User Element without folder treatment
if (i == -1)
{
i = 0;
path[i]=current_location.fileName();
current_location = current_location.parent();
dirLevel = 0;
}
// Create Custom labels if qet_labels.xml exits in customElementsDir
if (current_location.fileName() != "10_electric"){
QString custom_labels = "qet_labels.xml";
QString customfilepath = QETApp::customElementsDir().append(custom_labels);
QFile file(customfilepath);
file.isReadable();
if (!file.open(QFile::ReadOnly | QFile::Text))
return QString();
rxml.setDevice(&file);
rxml.readNext();
while(!rxml.atEnd())
{
if (rxml.attributes().value("name").toString() == path[i])
{
rxml.readNext();
i=i-1;
//reached element directory
if (i==0)
{
for (int j=i; j<= dirLevel; j = j +1)
{
//if there is a prefix available apply prefix
if(rxml.name().toString()=="prefix")
{
return rxml.readElementText();
}
//if there isn't a prefix available, find parent prefix in parent folder
else
{
while (rxml.readNextStartElement() && rxml.name().toString()!="prefix")
{
rxml.skipCurrentElement();
rxml.readNext();
}
}
}
}
}
rxml.readNext();
}
}
else
{
QString qet_labels = "10_electric/qet_labels.xml";
QString filepath = QETApp::commonElementsDir().append(qet_labels);
QFile file(filepath);
file.isReadable();
if (!file.open(QFile::ReadOnly | QFile::Text))
return QString();
rxml.setDevice(&file);
rxml.readNext();
while(!rxml.atEnd())
{
if (rxml.attributes().value("name").toString() == path[i])
{
rxml.readNext();
i=i-1;
//reached element directory
if (i==0)
{
for (int j=i; j<= dirLevel; j = j +1)
{
//if there is a prefix available apply prefix
if(rxml.name().toString()=="prefix")
{
return rxml.readElementText();
}
//if there isn't a prefix available, find parent prefix in parent folder
else
{
while (rxml.readNextStartElement() && rxml.name().toString()!="prefix")
{
rxml.skipCurrentElement();
rxml.readNext();
}
}
}
}
}
rxml.readNext();
}
}
return QString();
}
}