User can export / import the configuration of the texts and texts group of an element.

git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@5195 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
blacksun 2017-12-30 14:41:25 +00:00
parent 1137318384
commit 1b18b980a9
11 changed files with 429 additions and 73 deletions

View File

@ -0,0 +1,250 @@
/*
Copyright 2006-2017 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 "elementtextpattern.h"
#include "qetapp.h"
#include "element.h"
#include "qet.h"
#include "dynamicelementtextitem.h"
#include "elementtextitemgroup.h"
#include "addelementtextcommand.h"
#include "diagram.h"
#include <QDir>
#include <QInputDialog>
#include <QGraphicsScene>
#include <QMessageBox>
#include <QObject>
#include <QGraphicsView>
#include <QStringList>
/**
* @brief ExportElementTextPattern::ExportElementTextPattern
* Constructor
* @param elmt
*/
ExportElementTextPattern::ExportElementTextPattern(Element *elmt) :
m_element(elmt)
{
//Create the conf dir if not yet.
QDir dir(QETApp::configDir()+ "/element_texts_pattern");
if(!dir.exists())
{
dir.cdUp();
dir.mkdir("element_texts_pattern");
dir.cd("element_texts_pattern");
}
//Get the name of conf
bool ok;
m_name = getName(ok);
if(ok == false)
return;
//Check if a conf with the same name already exist
if (QFileInfo::exists(dir.absoluteFilePath(m_name + ".xml")))
{
bool r = QMessageBox::question(parentWidget(),
QObject::tr("Configuration de textes"),
QObject::tr("Une configuration de textes nommé << %1 >> existe déjà.\n"
"Voulez-vous la remplacer ?").arg(m_name));
if(r == false)
return;
}
QDomDocument doc = xmlConf();
QET::writeXmlFile(doc, dir.absoluteFilePath(m_name + ".xml"));
}
/**
* @brief ExportElementTextConf::getName
* Open a dialog to let user set the name of the conf and return it
* @return
*/
QString ExportElementTextPattern::getName(bool &ok) const
{
QString text = QInputDialog::getText(parentWidget(),
QObject::tr("Nom de la configuration"),
QObject::tr("Entrer le nom de la configuration à créer"),
QLineEdit::Normal,
QString(),
&ok);
text.replace(" ", "_");
text.replace(".","");
return text;
}
QWidget *ExportElementTextPattern::parentWidget() const
{
QWidget *parent = nullptr;
if(m_element->scene() && !m_element->scene()->views().isEmpty())
parent = m_element->scene()->views().first();
return parent;
}
QDomDocument ExportElementTextPattern::xmlConf() const
{
QDomDocument doc;
QDomElement root = doc.createElement("Element_texts_pattern");
root.setAttribute("name", m_name);
doc.appendChild(root);
QHash<Terminal *, int> H;
QDomElement elmt = m_element->toXml(doc, H);
QDomElement texts = elmt.firstChildElement("dynamic_texts");
QDomElement groups = elmt.firstChildElement("texts_groups");
if(texts.tagName() == "dynamic_texts")
root.appendChild(texts);
if(groups.tagName() == "texts_groups")
root.appendChild(groups);
return doc;
}
//*******************//
//******IMPORT*******//
//*******************//
ImportElementTextPattern::ImportElementTextPattern(Element *elmt):
m_element(elmt)
{
bool exist = true;
QDir dir(QETApp::configDir()+ "/element_texts_pattern");
if(!dir.exists())
exist = false;
QStringList entry = dir.entryList(QDir::Files | QDir::NoDotAndDotDot);
QStringList result = entry.filter(".xml");
if(result.isEmpty())
exist = false;
if(!exist)
{
QMessageBox::information(parentWidget(),
QObject::tr("Configurtaion de textes"),
QObject::tr("Aucune configuration de textes existante."));
return;
}
bool ok=false;
//Remove the .xml extention of the files
result.replaceInStrings(".xml", "");
QString name = getName(result, ok);
if(!ok || name.isEmpty())
return;
else
apply(name);
}
/**
* @brief ImportElementTextPattern::getName
* Open a dialog to let user select a conf
* @param ok
* @return
*/
QString ImportElementTextPattern::getName(QStringList list, bool &ok) const
{
return QInputDialog::getItem(parentWidget(),
QObject::tr("Séléctionner une configuration de textes"),
QObject::tr("Séléctionner la configuration de textes à ajouter à l'élément"),
list,
0,
false,
&ok);
}
QWidget *ImportElementTextPattern::parentWidget() const
{
QWidget *parent = nullptr;
if(m_element->scene() && !m_element->scene()->views().isEmpty())
parent = m_element->scene()->views().first();
return parent;
}
/**
* @brief ImportElementTextPattern::apply
* Apply the user choice
* @param name : the name of the selected pattern
*/
void ImportElementTextPattern::apply(QString name) const
{
if(!name.endsWith(".xml"))
name.append(".xml");
QFile conf_file(QETApp::configDir() + "/element_texts_pattern/" + name);
if(!conf_file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
//Load the content of the xml file
QDomDocument xml_conf;
if(!xml_conf.setContent(&conf_file))
return;
QDomElement root = xml_conf.firstChildElement("Element_texts_pattern");
//Get the text
QList <QDomElement> texts = QET::findInDomElement(root, "dynamic_texts", "dynamic_elmt_text");
if (texts.isEmpty())
return;
//Replace the original uuid of texts in the xml description, by a new one for every texts
QHash<QUuid, QUuid> uuid_hash;
for(QDomElement text : texts)
{
QUuid original_uuid(text.attribute("uuid"));
QUuid new_uuid = QUuid::createUuid();
text.setAttribute("uuid", new_uuid.toString());
uuid_hash.insert(original_uuid, new_uuid);
}
//In each group of the xml description, replace the original uuids, by the news created upper.
QList <QDomElement> groups = QET::findInDomElement(root, "texts_groups", "texts_group");
for(QDomElement group : groups)
{
for(QDomElement text : QET::findInDomElement(group, "texts", "text"))
{
QUuid original_uuid(text.attribute("uuid"));
QUuid new_uuid = uuid_hash.value(original_uuid);
if(!new_uuid.isNull())
text.setAttribute("uuid", new_uuid.toString());
}
}
QUndoStack &undo_stack = m_element->diagram()->undoStack();
undo_stack.beginMacro(QObject::tr("Importer la configuration de texte : %1").arg(name.remove(".xml")));
//Add the texts to element
for(QDomElement text : texts)
{
DynamicElementTextItem *deti = new DynamicElementTextItem(m_element);
undo_stack.push(new AddElementTextCommand(m_element, deti));
deti->fromXml(text);
}
//Add the groups to element
for(QDomElement xml_group : groups)
undo_stack.push(new AddTextsGroupCommand(m_element, xml_group));
undo_stack.endMacro();
}

View File

@ -0,0 +1,56 @@
/*
Copyright 2006-2017 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/>.
*/
#ifndef ELEMENTTEXTPATTERN_H
#define ELEMENTTEXTPATTERN_H
#include <QString>
#include <QDomDocument>
class Element;
class QWidget;
class ExportElementTextPattern
{
public:
ExportElementTextPattern(Element *elmt);
private:
QString getName(bool &ok) const;
QWidget *parentWidget() const;
QDomDocument xmlConf() const;
private:
Element *m_element = nullptr;
QString m_name;
};
class ImportElementTextPattern
{
public:
ImportElementTextPattern(Element *elmt);
private:
QString getName(QStringList list, bool &ok) const;
QWidget *parentWidget() const;
void apply(QString name) const;
private:
Element *m_element = nullptr;
};
#endif // ELEMENTTEXTCONFIGURATION_H

View File

@ -160,7 +160,7 @@ namespace QET {
qreal correctAngle(const qreal &);
bool compareCanonicalFilePaths(const QString &, const QString &);
QString titleBlockColumnLengthToString(const TitleBlockColumnLength &);
bool writeXmlFile(QDomDocument &, const QString &, QString * = nullptr);
bool writeXmlFile(QDomDocument &xml_doc, const QString &filepath, QString * error_message= nullptr);
QPointF graphicsSceneEventPos(QEvent *);
bool eachStrIsEqual (const QStringList &qsl);
}

View File

@ -488,16 +488,16 @@ bool Element::fromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr, bool
for(DynamicElementTextItem *deti : m_dynamic_text_list)
delete deti;
m_dynamic_text_list.clear();
//************************//
//***Dynamic texts item***//
//************************//
for(QDomElement qde : QET::findInDomElement(e, "dynamic_texts", DynamicElementTextItem::xmlTaggName()))
{
DynamicElementTextItem *deti = new DynamicElementTextItem(this);
addDynamicTextItem(deti);
deti->fromXml(qde);
}
for (QDomElement qde : QET::findInDomElement(e, "dynamic_texts", DynamicElementTextItem::xmlTaggName()))
{
DynamicElementTextItem *deti = new DynamicElementTextItem(this);
addDynamicTextItem(deti);
deti->fromXml(qde);
}
//************************//
@ -584,7 +584,7 @@ bool Element::fromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr, bool
}
}
for (QDomElement qde : QET::findInDomElement(e, "texts_group", ElementTextItemGroup::xmlTaggName()))
for (QDomElement qde : QET::findInDomElement(e, "texts_groups", ElementTextItemGroup::xmlTaggName()))
{
ElementTextItemGroup *group = addTextGroup("loaded_from_xml_group");
group->fromXml(qde);
@ -626,7 +626,7 @@ bool Element::fromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr, bool
}
}
}
return(true);
}
@ -658,7 +658,7 @@ QDomElement Element::toXml(QDomDocument &document, QHash<Terminal *, int> &table
QDomElement seq = m_autoNum_seq.toXml(document);
if (seq.hasChildNodes())
element.appendChild(seq);
// position, selection et orientation
element.setAttribute("x", QString("%1").arg(pos().x()));
element.setAttribute("y", QString("%1").arg(pos().y()));
@ -674,7 +674,7 @@ QDomElement Element::toXml(QDomDocument &document, QHash<Terminal *, int> &table
}
id_terminal = max_id_t + 1;
}
// enregistrement des bornes de l'appareil
QDomElement xml_terminals = document.createElement("terminals");
// pour chaque enfant de l'element
@ -686,7 +686,7 @@ QDomElement Element::toXml(QDomDocument &document, QHash<Terminal *, int> &table
xml_terminals.appendChild(terminal);
}
element.appendChild(xml_terminals);
// enregistrement des champ de texte de l'appareil
QDomElement inputs = document.createElement("inputs");
foreach(ElementTextItem *eti, texts()) {
@ -706,21 +706,21 @@ QDomElement Element::toXml(QDomDocument &document, QHash<Terminal *, int> &table
element.appendChild(links_uuids);
}
//save information of this element
//save information of this element
if (! m_element_informations.keys().isEmpty()) {
QDomElement infos = document.createElement("elementInformations");
m_element_informations.toXml(infos, "elementInformation");
element.appendChild(infos);
}
//Dynamic texts
QDomElement dyn_text = document.createElement("dynamic_texts");
for(DynamicElementTextItem *deti : m_dynamic_text_list)
dyn_text.appendChild(deti->toXml(document));
//Dynamic texts
QDomElement dyn_text = document.createElement("dynamic_texts");
for (DynamicElementTextItem *deti : m_dynamic_text_list)
dyn_text.appendChild(deti->toXml(document));
QDomElement texts_group = document.createElement("texts_group");
QDomElement texts_group = document.createElement("texts_groups");
//Dynamic texts owned by groups
//Dynamic texts owned by groups
for(ElementTextItemGroup *group : m_texts_group)
{
//temporarily remove the texts from group to get the pos relative to element and not group.
@ -735,7 +735,7 @@ QDomElement Element::toXml(QDomDocument &document, QHash<Terminal *, int> &table
group->removeFromGroup(deti);
//Save the texts to xml
for(DynamicElementTextItem *deti : deti_list)
for (DynamicElementTextItem *deti : deti_list)
dyn_text.appendChild(deti->toXml(document));
//Re add texts to group
@ -754,7 +754,7 @@ QDomElement Element::toXml(QDomDocument &document, QHash<Terminal *, int> &table
//Append the texts group to element
element.appendChild(texts_group);
return(element);
return(element);
}
/**
@ -765,18 +765,18 @@ QDomElement Element::toXml(QDomDocument &document, QHash<Terminal *, int> &table
*/
void Element::addDynamicTextItem(DynamicElementTextItem *deti)
{
if (deti && !m_dynamic_text_list.contains(deti))
if (deti && !m_dynamic_text_list.contains(deti))
{
m_dynamic_text_list.append(deti);
m_dynamic_text_list.append(deti);
deti->setParentItem(this);
emit textAdded(deti);
}
else
{
DynamicElementTextItem *text = new DynamicElementTextItem(this);
m_dynamic_text_list.append(text);
else
{
DynamicElementTextItem *text = new DynamicElementTextItem(this);
m_dynamic_text_list.append(text);
emit textAdded(text);
}
}
}
/**
@ -787,9 +787,9 @@ void Element::addDynamicTextItem(DynamicElementTextItem *deti)
*/
void Element::removeDynamicTextItem(DynamicElementTextItem *deti)
{
if (m_dynamic_text_list.contains(deti))
if (m_dynamic_text_list.contains(deti))
{
m_dynamic_text_list.removeOne(deti);
m_dynamic_text_list.removeOne(deti);
deti->setParentItem(nullptr);
emit textRemoved(deti);
return;

View File

@ -179,13 +179,10 @@ void ElementTextItemGroup::updateAlignment()
*/
void ElementTextItemGroup::setVerticalAdjustment(int v)
{
if(m_vertical_adjustment != v)
{
prepareGeometryChange();
m_vertical_adjustment = v;
updateAlignment();
emit verticalAdjustmentChanged(v);
}
prepareGeometryChange();
m_vertical_adjustment = v;
updateAlignment();
emit verticalAdjustmentChanged(v);
}
/**
@ -278,12 +275,12 @@ void ElementTextItemGroup::fromXml(QDomElement &dom_element)
return;
}
m_name = dom_element.attribute("name", "no name");
setName(dom_element.attribute("name", "no name"));
QMetaEnum me = QMetaEnum::fromType<Qt::Alignment>();
m_alignment = Qt::Alignment(me.keyToValue(dom_element.attribute("alignment").toStdString().data()));
setAlignment(Qt::Alignment(me.keyToValue(dom_element.attribute("alignment").toStdString().data())));
setRotation(dom_element.attribute("rotation", QString::number(0)).toDouble());
m_vertical_adjustment = dom_element.attribute("vertical_adjustment").toInt();
setVerticalAdjustment(dom_element.attribute("vertical_adjustment").toInt());
if(parentElement())
{

View File

@ -67,7 +67,7 @@ class ElementTextItemGroup : public QObject, public QGraphicsItemGroup
QDomElement toXml(QDomDocument &dom_document) const;
void fromXml(QDomElement &dom_element);
static QString xmlTaggName() {return QString("text_group");}
static QString xmlTaggName() {return QString("texts_group");}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
QRectF boundingRect() const override;

View File

@ -26,6 +26,7 @@
#include "QPropertyUndoCommand/qpropertyundocommand.h"
#include "elementtextitemgroup.h"
#include "deleteqgraphicsitemcommand.h"
#include "elementtextpattern.h"
#include <QTreeView>
#include <QUndoCommand>
@ -40,9 +41,6 @@ DynamicElementTextItemEditor::DynamicElementTextItemEditor(Element *element, QWi
ui->m_tree_view->installEventFilter(this);
ui->m_remove_selection->setDisabled(true);
ui->m_export_pb->hide();
ui->m_import_pb->hide();
setElement(element);
}
@ -256,3 +254,13 @@ void DynamicElementTextItemEditor::on_m_tree_view_clicked(const QModelIndex &ind
else
ui->m_remove_selection->setDisabled(true);
}
void DynamicElementTextItemEditor::on_m_export_pb_clicked()
{
ExportElementTextPattern eetp(m_element);
}
void DynamicElementTextItemEditor::on_m_import_pb_clicked()
{
ImportElementTextPattern ietp(m_element);
}

View File

@ -53,6 +53,8 @@ class DynamicElementTextItemEditor : public AbstractElementPropertiesEditorWidge
void on_m_remove_selection_clicked();
void on_m_add_group_clicked();
void on_m_tree_view_clicked(const QModelIndex &index);
void on_m_export_pb_clicked();
void on_m_import_pb_clicked();
private:
Ui::DynamicElementTextItemEditor *ui;

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
<width>226</width>
<height>234</height>
</rect>
</property>
<property name="windowTitle">
@ -17,7 +17,35 @@
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<widget class="QToolButton" name="m_export_pb">
<property name="toolTip">
<string>Exporter l'actuelle configuration des textes</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../qelectrotech.qrc">
<normaloff>:/ico/16x16/document-save.png</normaloff>:/ico/16x16/document-save.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="m_import_pb">
<property name="toolTip">
<string>Importer une configuration de texte</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../qelectrotech.qrc">
<normaloff>:/ico/16x16/folder-open.png</normaloff>:/ico/16x16/folder-open.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@ -30,40 +58,40 @@
</spacer>
</item>
<item>
<widget class="QPushButton" name="m_add_text">
<widget class="QToolButton" name="m_add_text">
<property name="toolTip">
<string>Ajouter un texte</string>
</property>
<property name="text">
<string>Texte</string>
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../qelectrotech.qrc">
<normaloff>:/ico/16x16/list-add.png</normaloff>:/ico/16x16/list-add.png</iconset>
<normaloff>:/ico/22x22/textfield.png</normaloff>:/ico/22x22/textfield.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_add_group">
<widget class="QToolButton" name="m_add_group">
<property name="toolTip">
<string>Ajouter un groupe de textes</string>
</property>
<property name="text">
<string>Groupe</string>
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../qelectrotech.qrc">
<normaloff>:/ico/16x16/list-add.png</normaloff>:/ico/16x16/list-add.png</iconset>
<normaloff>:/ico/16x16/object-group.png</normaloff>:/ico/16x16/object-group.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_remove_selection">
<widget class="QToolButton" name="m_remove_selection">
<property name="toolTip">
<string>Supprimer la sélection</string>
</property>
<property name="text">
<string/>
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../qelectrotech.qrc">
@ -93,22 +121,7 @@
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="m_im_exp_layout">
<item>
<widget class="QPushButton" name="m_export_pb">
<property name="text">
<string>Exporter</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_import_pb">
<property name="text">
<string>Importer</string>
</property>
</widget>
</item>
</layout>
<layout class="QHBoxLayout" name="m_im_exp_layout"/>
</item>
</layout>
</widget>

View File

@ -75,6 +75,20 @@ AddTextsGroupCommand::AddTextsGroupCommand(Element *element, QString groupe_name
setText(QObject::tr("Ajouter un groupe de textes d'élément"));
}
/**
* @brief AddTextsGroupCommand::AddTextsGroupCommand
* @param element : The element to add a new group
* @param dom_element : the first time the group is created, we call the function fromXml of the group, and give @dom_element has argument.
* @param parent : parent undo
*/
AddTextsGroupCommand::AddTextsGroupCommand(Element *element, QDomElement dom_element, QUndoCommand *parent) :
QUndoCommand(parent),
m_element(element),
m_dom_element(dom_element)
{
setText(QObject::tr("Ajouter un groupe de textes d'élément"));
}
/**
* @brief AddTextsGroupCommand::~AddTextsGroupCommand
* Destructor
@ -95,10 +109,22 @@ void AddTextsGroupCommand::redo()
if(m_first_undo)
{
m_group = m_element.data()->addTextGroup(m_name);
if(!m_dom_element.isNull())
{
m_group.data()->fromXml(m_dom_element);
//We get the list of texts (if any) because when undo is called, all child text will be removed
//from the group, and reparented to m_elemeny.
//Then the next time redo is called, the texts will be added to the group
m_deti_list = m_group.data()->texts();
}
m_first_undo = false;
}
else if(m_group)
{
m_element.data()->addTextGroup(m_group.data());
for(DynamicElementTextItem *deti : m_deti_list)
m_element.data()->addTextToGroup(deti, m_group.data());
}
}
}

View File

@ -20,6 +20,7 @@
#include <QUndoCommand>
#include <QPointer>
#include <QDomElement>
class Element;
class DynamicElementTextItem;
@ -51,6 +52,7 @@ class AddTextsGroupCommand : public QUndoCommand
{
public:
AddTextsGroupCommand(Element *element, QString groupe_name, QUndoCommand *parent = nullptr);
AddTextsGroupCommand(Element *element, QDomElement dom_element, QUndoCommand *parent = nullptr);
~AddTextsGroupCommand() override;
void undo() override;
@ -59,6 +61,8 @@ class AddTextsGroupCommand : public QUndoCommand
private:
QPointer<Element> m_element;
QPointer<ElementTextItemGroup> m_group;
QList <DynamicElementTextItem *> m_deti_list;
QDomElement m_dom_element;
QString m_name;
bool m_first_undo = true;
};