diff --git a/sources/diagram.cpp b/sources/diagram.cpp
index e2882b150..3e32ea109 100644
--- a/sources/diagram.cpp
+++ b/sources/diagram.cpp
@@ -37,6 +37,9 @@
#include "elementtextitemgroup.h"
#include "undocommand/addelementtextcommand.h"
#include "QPropertyUndoCommand/qpropertyundocommand.h"
+#include "qetgraphicstableitem.h"
+#include "qetxml.h"
+#include "elementprovider.h"
int Diagram::xGrid = 10;
int Diagram::yGrid = 10;
@@ -614,31 +617,31 @@ QDomDocument Diagram::toXml(bool whole_content) {
QDomDocument document;
// racine de l'arbre XML
- QDomElement racine = document.createElement("diagram");
+ auto dom_root = document.createElement("diagram");
// add the application version number
- racine.setAttribute("version", QET::version);
+ dom_root.setAttribute("version", QET::version);
// proprietes du schema
if (whole_content) {
- border_and_titleblock.titleBlockToXml(racine);
- border_and_titleblock.borderToXml(racine);
+ border_and_titleblock.titleBlockToXml(dom_root);
+ border_and_titleblock.borderToXml(dom_root);
// Default conductor properties
QDomElement default_conductor = document.createElement("defaultconductor");
defaultConductorProperties.toXml(default_conductor);
- racine.appendChild(default_conductor);
+ dom_root.appendChild(default_conductor);
// Conductor autonum
if (!m_conductors_autonum_name.isEmpty()) {
- racine.setAttribute("conductorAutonum", m_conductors_autonum_name);
+ dom_root.setAttribute("conductorAutonum", m_conductors_autonum_name);
}
//Default New Element
- racine.setAttribute("freezeNewElement", m_freeze_new_elements ? "true" : "false");
+ dom_root.setAttribute("freezeNewElement", m_freeze_new_elements ? "true" : "false");
//Default New Conductor
- racine.setAttribute("freezeNewConductor", m_freeze_new_conductors_ ? "true" : "false");
+ dom_root.setAttribute("freezeNewConductor", m_freeze_new_conductors_ ? "true" : "false");
//Element Folio Sequential Variables
if (!m_elmt_unitfolio_max.isEmpty() || !m_elmt_tenfolio_max.isEmpty() || !m_elmt_hundredfolio_max.isEmpty()) {
@@ -658,7 +661,7 @@ QDomDocument Diagram::toXml(bool whole_content) {
folioSequentialsToXml(&m_elmt_hundredfolio_max, &elmtfolioseq, "seqhf_", "hundredfolioseq", &document);
elmtfoliosequential.appendChild(elmtfolioseq);
}
- racine.appendChild(elmtfoliosequential);
+ dom_root.appendChild(elmtfoliosequential);
}
//Conductor Folio Sequential Variables
if (!m_cnd_unitfolio_max.isEmpty() || !m_cnd_tenfolio_max.isEmpty() || !m_cnd_hundredfolio_max.isEmpty()) {
@@ -679,101 +682,125 @@ QDomDocument Diagram::toXml(bool whole_content) {
folioSequentialsToXml(&m_cnd_hundredfolio_max, &cndfolioseq, "seqhf_", "hundredfolioseq", &document);
cndfoliosequential.appendChild(cndfolioseq);
}
- racine.appendChild(cndfoliosequential);
+ dom_root.appendChild(cndfoliosequential);
}
}
else {
//this method with whole_content to false,
//is often use to copy and paste the current selection
//so we add the id of the project where copy occur.
- racine.setAttribute("projectId", QETApp::projectId(m_project));
+ dom_root.setAttribute("projectId", QETApp::projectId(m_project));
}
- document.appendChild(racine);
+ document.appendChild(dom_root);
- // si le schema ne contient pas d'element (et donc pas de conducteurs), on retourne de suite le document XML
- if (items().isEmpty()) return(document);
+ if (items().isEmpty())
+ return(document);
- // creation de trois listes : une qui contient les elements, une qui contient les conducteurs, une qui contient les champs de texte
- QList list_elements;
- QList list_conductors;
- QList list_texts;
- QList list_images;
- QList list_shapes;
-
- QList list_items = items();
- ;
- // Determine les elements a "XMLiser"
- foreach(QGraphicsItem *qgi, list_items) {
- if (Element *elmt = qgraphicsitem_cast(qgi)) {
- if (whole_content) list_elements << elmt;
- else if (elmt -> isSelected()) list_elements << elmt;
- } else if (Conductor *f = qgraphicsitem_cast(qgi)) {
- if (whole_content) list_conductors << f;
- // lorsqu'on n'exporte pas tout le diagram, il faut retirer les conducteurs non selectionnes
- // et pour l'instant, les conducteurs non selectionnes sont les conducteurs dont un des elements n'est pas selectionne
- else if (f -> terminal1 -> parentItem() -> isSelected() && f -> terminal2 -> parentItem() -> isSelected()) {
- list_conductors << f;
+ QVector list_elements;
+ QVector list_conductors;
+ QVector list_texts;
+ QVector list_images;
+ QVector list_shapes;
+ QVector table_vector;
+
+ //Ckeck graphics item to "XMLise"
+ for(QGraphicsItem *qgi : items())
+ {
+ switch (qgi->type())
+ {
+ case Element::Type: {
+ auto elmt = static_cast(qgi);
+ if (whole_content || elmt->isSelected())
+ list_elements << elmt;
+ break;
+ }
+ case Conductor::Type: {
+ auto cond = static_cast(qgi);
+ if (whole_content)
+ list_conductors << cond;
+ //When we did not export the whole diagram, we must to remove the non selected conductors.
+ //At this step that mean a conductor which one of these two element are not selected
+ else if (cond->terminal1->parentItem()->isSelected() && cond->terminal2->parentItem()->isSelected())
+ list_conductors << cond;
+ break;
+ }
+ case DiagramImageItem::Type: {
+ auto image = static_cast(qgi);
+ if (whole_content || image->isSelected())
+ list_images << image;
+ break;
+ }
+ case IndependentTextItem::Type: {
+ auto indi_text = static_cast(qgi);
+ if (whole_content || indi_text->isSelected())
+ list_texts << indi_text;
+ break;
+ }
+ case QetShapeItem::Type: {
+ auto shape = static_cast(qgi);
+ if (whole_content || shape->isSelected())
+ list_shapes << shape;
+ break;
+ }
+ case QetGraphicsTableItem::Type: {
+ auto table = static_cast(qgi);
+ if (whole_content || table->isSelected())
+ table_vector << table;
}
- } else if (IndependentTextItem *iti = qgraphicsitem_cast(qgi)) {
- if (whole_content) list_texts << iti;
- else if (iti -> isSelected()) list_texts << iti;
- } else if (DiagramImageItem *dii = qgraphicsitem_cast(qgi)) {
- if (whole_content) list_images << dii;
- else if (dii -> isSelected()) list_images << dii;
- } else if (QetShapeItem *dsi = qgraphicsitem_cast(qgi)) {
- if (whole_content) list_shapes << dsi;
- else if (dsi -> isSelected()) list_shapes << dsi;
}
}
- // table de correspondance entre les adresses des bornes et leurs ids
+ // table de correspondance entre les adresses des bornes et leurs ids
QHash table_adr_id;
- // enregistrement des elements
if (!list_elements.isEmpty()) {
- QDomElement elements = document.createElement("elements");
- foreach(Element *elmt, list_elements) {
- elements.appendChild(elmt -> toXml(document, table_adr_id));
+ auto dom_elements = document.createElement("elements");
+ for (auto elmt : list_elements) {
+ dom_elements.appendChild(elmt->toXml(document, table_adr_id));
}
- racine.appendChild(elements);
+ dom_root.appendChild(dom_elements);
}
- // enregistrement des conducteurs
if (!list_conductors.isEmpty()) {
- QDomElement conductors = document.createElement("conductors");
- foreach(Conductor *cond, list_conductors) {
- conductors.appendChild(cond -> toXml(document, table_adr_id));
+ auto dom_conductors = document.createElement("conductors");
+ for (auto cond : list_conductors) {
+ dom_conductors.appendChild(cond->toXml(document, table_adr_id));
}
- racine.appendChild(conductors);
+ dom_root.appendChild(dom_conductors);
}
- // enregistrement des champs de texte
if (!list_texts.isEmpty()) {
- QDomElement inputs = document.createElement("inputs");
- foreach(DiagramTextItem *dti, list_texts) {
- inputs.appendChild(dti -> toXml(document));
+ auto dom_texts = document.createElement("inputs");
+ for (auto dti : list_texts) {
+ dom_texts.appendChild(dti->toXml(document));
}
- racine.appendChild(inputs);
+ dom_root.appendChild(dom_texts);
}
- // save of images
if (!list_images.isEmpty()) {
- QDomElement images = document.createElement("images");
- foreach (DiagramImageItem *dii, list_images) {
- images.appendChild(dii -> toXml(document));
+ auto dom_images = document.createElement("images");
+ for (auto dii : list_images) {
+ dom_images.appendChild(dii->toXml(document));
}
- racine.appendChild(images);
+ dom_root.appendChild(dom_images);
}
- // save of basic shapes
if (!list_shapes.isEmpty()) {
- QDomElement shapes = document.createElement("shapes");
- foreach (QetShapeItem *dii, list_shapes) {
- shapes.appendChild(dii -> toXml(document));
+ auto dom_shapes = document.createElement("shapes");
+ for (auto dii : list_shapes) {
+ dom_shapes.appendChild(dii -> toXml(document));
}
- racine.appendChild(shapes);
+ dom_root.appendChild(dom_shapes);
}
- // on retourne le document XML ainsi genere
+
+ if (table_vector.size()) {
+ auto tables = document.createElement("tables");
+ for (auto table : table_vector) {
+ tables.appendChild(table->toXml(document));
+ }
+ dom_root.appendChild(tables);
+ }
+
return(document);
}
@@ -970,7 +997,7 @@ bool Diagram::fromXml(QDomElement &document, QPointF position, bool consider_inf
}
}
- // Load text
+ // Load text
QList added_texts;
foreach (QDomElement text_xml, QET::findInDomElement(root, "inputs", "input")) {
IndependentTextItem *iti = new IndependentTextItem();
@@ -979,7 +1006,7 @@ bool Diagram::fromXml(QDomElement &document, QPointF position, bool consider_inf
added_texts << iti;
}
- // Load image
+ // Load image
QList added_images;
foreach (QDomElement image_xml, QET::findInDomElement(root, "images", "image")) {
DiagramImageItem *dii = new DiagramImageItem ();
@@ -988,7 +1015,7 @@ bool Diagram::fromXml(QDomElement &document, QPointF position, bool consider_inf
added_images << dii;
}
- // Load shape
+ // Load shape
QList added_shapes;
foreach (QDomElement shape_xml, QET::findInDomElement(root, "shapes", "shape")) {
QetShapeItem *dii = new QetShapeItem (QPointF(0,0));
@@ -1026,39 +1053,52 @@ bool Diagram::fromXml(QDomElement &document, QPointF position, bool consider_inf
else qDebug() << "Diagram::fromXml() : Le chargement du conducteur" << id_p1 << id_p2 << "a echoue";
}
- //Translate items if a new position was given in parameter
- if (position != QPointF()) {
+ //Load tables
+ QVector added_tables;
+ for (auto dom_table : QETXML::subChild(root, "tables", QetGraphicsTableItem::xmlTagName()))
+ {
+ auto table = new QetGraphicsTableItem();
+ addItem(table);
+ table->fromXml(dom_table);
+ added_tables << table;
+ }
- QList added_items;
- foreach (Element *added_element, added_elements ) added_items << added_element;
- foreach (Conductor *added_cond, added_conductors) added_items << added_cond;
- foreach (QetShapeItem *added_shape, added_shapes ) added_items << added_shape;
- foreach (DiagramTextItem *added_text, added_texts ) added_items << added_text;
- foreach (DiagramImageItem *added_image, added_images ) added_items << added_image;
+ //Translate items if a new position was given in parameter
+ if (position != QPointF())
+ {
+ QVector added_items;
+ for (auto element : added_elements ) added_items << element;
+ for (auto cond : added_conductors) added_items << cond;
+ for (auto shape : added_shapes ) added_items << shape;
+ for (auto text : added_texts ) added_items << text;
+ for (auto image : added_images ) added_items << image;
+ for (auto table : added_tables ) added_items << table;
- //Get the top left corner of the rectangle that contain all added items
+ //Get the top left corner of the rectangle that contain all added items
QRectF items_rect;
- foreach (QGraphicsItem *item, added_items) {
- items_rect = items_rect.united(item -> mapToScene(item -> boundingRect()).boundingRect());
+ for (auto item : added_items) {
+ items_rect = items_rect.united(item->mapToScene(item->boundingRect()).boundingRect());
}
QPointF point_ = items_rect.topLeft();
QPointF pos_ = Diagram::snapToGrid(QPointF (position.x() - point_.x(),
position.y() - point_.y()));
- //Translate all added items
- foreach (QGraphicsItem *qgi, added_items)
- qgi -> setPos( qgi -> pos() += pos_);
+ //Translate all added items
+ for (auto qgi : added_items)
+ qgi->setPos(qgi->pos() += pos_);
}
- // remplissage des listes facultatives
+ //Filling of falculatory lists
if (content_ptr) {
- content_ptr -> m_elements = added_elements;
+ content_ptr -> m_elements = added_elements;
content_ptr -> m_conductors_to_move = added_conductors;
- content_ptr -> m_text_fields = added_texts.toSet();
- content_ptr -> m_images = added_images.toSet();
- content_ptr -> m_shapes = added_shapes.toSet();
+ content_ptr -> m_text_fields = added_texts.toSet();
+ content_ptr -> m_images = added_images.toSet();
+ content_ptr -> m_shapes = added_shapes.toSet();
+ content_ptr -> m_tables = added_tables;
}
+
adjustSceneRect();
return(true);
}
@@ -1096,6 +1136,8 @@ void Diagram::folioSequentialsFromXml(const QDomElement &root, QHashinitLink(project());
@@ -1105,6 +1147,9 @@ void Diagram::refreshContents()
for (Conductor *conductor : conductors())
conductor->refreshText();
+
+ for (auto table : provider_.table())
+ table->initLink();
}
/**
diff --git a/sources/diagramcontent.h b/sources/diagramcontent.h
index c4611da50..beda6ea06 100644
--- a/sources/diagramcontent.h
+++ b/sources/diagramcontent.h
@@ -19,6 +19,7 @@
#define DIAGRAM_CONTENT_H
#include
+#include
class QGraphicsItem;
class Conductor;
@@ -30,6 +31,7 @@ class DynamicElementTextItem;
class ElementTextItemGroup;
class Diagram;
class DiagramTextItem;
+class QetGraphicsTableItem;
/**
This class provides a container that makes the transmission of diagram content
@@ -60,8 +62,9 @@ class DiagramContent
AnyConductor = 112,
Shapes = 128,
TextGroup = 256,
- All = 511,
- SelectedOnly = 512
+ Tables = 512,
+ All = 1023,
+ SelectedOnly = 1024
};
QList m_elements;
@@ -75,6 +78,8 @@ class DiagramContent
QSet m_element_texts;
QSet m_texts_groups;
QList m_selected_items;
+ QVector m_tables;
+
QList selectedTexts() const;
QList selectedTextsGroup() const;
diff --git a/sources/elementprovider.cpp b/sources/elementprovider.cpp
index be65b300c..d2e5240a8 100644
--- a/sources/elementprovider.cpp
+++ b/sources/elementprovider.cpp
@@ -156,3 +156,17 @@ QVector ElementProvider::table(QetGraphicsTableItem *tab
return v_;
}
+
+/**
+ * @brief ElementProvider::tableFromUuid
+ * @param uuid
+ * @return the table with uuid @uuid or nullptr if not found
+ */
+QetGraphicsTableItem *ElementProvider::tableFromUuid(const QUuid &uuid)
+{
+ for (auto table : this->table())
+ if (table->uuid() == uuid)
+ return table;
+
+ return nullptr;
+}
diff --git a/sources/elementprovider.h b/sources/elementprovider.h
index 983dd3e2f..65979abf3 100644
--- a/sources/elementprovider.h
+++ b/sources/elementprovider.h
@@ -42,6 +42,7 @@ class ElementProvider
QList fromUuids(QList ) const;
QList find(const int filter) const;
QVector table(QetGraphicsTableItem *table = nullptr, QAbstractItemModel *model = nullptr);
+ QetGraphicsTableItem *tableFromUuid(const QUuid &uuid);
private:
QList m_diagram_list;
diff --git a/sources/qetgraphicsitem/ViewItem/nomenclaturemodel.cpp b/sources/qetgraphicsitem/ViewItem/nomenclaturemodel.cpp
index e46c650ff..e991a53e9 100644
--- a/sources/qetgraphicsitem/ViewItem/nomenclaturemodel.cpp
+++ b/sources/qetgraphicsitem/ViewItem/nomenclaturemodel.cpp
@@ -18,6 +18,7 @@
#include "nomenclaturemodel.h"
#include "qetapp.h"
#include "qetproject.h"
+#include "qetxml.h"
#include
#include
@@ -202,6 +203,47 @@ void NomenclatureModel::autoHeaders()
}
}
+/**
+ * @brief NomenclatureModel::toXml
+ * Save the model to xml,since model can have unlimited data we only save few data.
+ * The query and all header data. All other data are not saved.
+ * @param document
+ * @return
+ */
+QDomElement NomenclatureModel::toXml(QDomDocument &document) const
+{
+ auto dom_element = document.createElement(xmlTagName());
+
+ //query
+ auto dom_query = document.createElement("query");
+ auto dom_query_txt = document.createTextNode(m_query);
+ dom_query.appendChild(dom_query_txt);
+ dom_element.appendChild(dom_query);
+
+ //header data
+ QHash> horizontal_;
+ for (auto key : m_header_data.keys()) {
+ horizontal_.insert(key, m_header_data.value(key).keys()); }
+
+ dom_element.appendChild(QETXML::modelHeaderDataToXml(document, this, horizontal_, QHash>()));
+
+ return dom_element;
+}
+
+/**
+ * @brief NomenclatureModel::fromXml
+ * Restore the model from xml
+ * @param element
+ */
+void NomenclatureModel::fromXml(const QDomElement &element)
+{
+ if (element.tagName() != xmlTagName())
+ return;
+
+ query(element.firstChildElement("query").text());
+ QETXML::modelHeaderDataFromXml(element.firstChildElement("header_data"), this);
+}
+
/**
* @brief NomenclatureModel::dataBaseUpdated
* slot called when the project database is updated
@@ -214,9 +256,9 @@ void NomenclatureModel::dataBaseUpdated()
//befor any element, column count return 0, so in this case we emit column inserted
if (new_record.size() != m_record.size())
{
- emit beginInsertColumns(index(0,0), 0, m_record.size()-1);
+ emit beginResetModel();
m_record = new_record;
- emit endInsertColumns();
+ emit endResetModel();
}
else
{
diff --git a/sources/qetgraphicsitem/ViewItem/nomenclaturemodel.h b/sources/qetgraphicsitem/ViewItem/nomenclaturemodel.h
index e4b52f70b..b23a6cae4 100644
--- a/sources/qetgraphicsitem/ViewItem/nomenclaturemodel.h
+++ b/sources/qetgraphicsitem/ViewItem/nomenclaturemodel.h
@@ -1,4 +1,4 @@
-/*
+/*
Copyright 2006-2020 QElectroTech Team
This file is part of QElectroTech.
@@ -20,6 +20,7 @@
#include
#include
+#include
class QETProject;
@@ -45,6 +46,10 @@ class NomenclatureModel : public QAbstractTableModel
QETProject *project() const;
void autoHeaders();
+ QDomElement toXml(QDomDocument &document) const;
+ void fromXml(const QDomElement &element);
+ static QString xmlTagName() {return QString("nomenclature_model");}
+
private:
void dataBaseUpdated();
diff --git a/sources/qetgraphicsitem/ViewItem/qetgraphicsheaderitem.cpp b/sources/qetgraphicsitem/ViewItem/qetgraphicsheaderitem.cpp
index ba813044e..f089e5ac3 100644
--- a/sources/qetgraphicsitem/ViewItem/qetgraphicsheaderitem.cpp
+++ b/sources/qetgraphicsitem/ViewItem/qetgraphicsheaderitem.cpp
@@ -17,6 +17,7 @@
*/
#include "qetgraphicsheaderitem.h"
#include "qabstractitemmodel.h"
+#include "qetxml.h"
#include
#include
@@ -209,6 +210,34 @@ void QetGraphicsHeaderItem::setMargins(const QMargins &margins)
headerDataChanged(Qt::Horizontal, 0,1);
}
+/**
+ * @brief QetGraphicsHeaderItem::toXml
+ * save the header to xml
+ * @param document
+ * @return
+ */
+QDomElement QetGraphicsHeaderItem::toXml(QDomDocument &document) const
+{
+ auto dom_element = document.createElement(xmlTagName());
+ dom_element.appendChild(QETXML::marginsToXml(document, m_margin));
+
+ return dom_element;
+}
+
+/**
+ * @brief QetGraphicsHeaderItem::fromXml
+ * Restore the header from xml
+ * @param element
+ */
+void QetGraphicsHeaderItem::fromXml(const QDomElement &element)
+{
+ if (element.tagName() != xmlTagName()) {
+ return;
+ }
+
+ m_margin = QETXML::marginsFromXml(element.firstChildElement("margins"));
+}
+
/**
* @brief QetGraphicsHeaderItem::setUpMinimumSectionsSize
* Setup the minimum section size and height of the item.
diff --git a/sources/qetgraphicsitem/ViewItem/qetgraphicsheaderitem.h b/sources/qetgraphicsitem/ViewItem/qetgraphicsheaderitem.h
index efbe5eaaa..236f8ad3e 100644
--- a/sources/qetgraphicsitem/ViewItem/qetgraphicsheaderitem.h
+++ b/sources/qetgraphicsitem/ViewItem/qetgraphicsheaderitem.h
@@ -59,6 +59,10 @@ class QetGraphicsHeaderItem : public QGraphicsObject
QVector minimumSectionWidth() const {return m_sections_minimum_width;}
int minimumWidth() const {return m_minimum_width;}
+ QDomElement toXml (QDomDocument &document) const;
+ void fromXml(const QDomElement &element);
+ static QString xmlTagName() {return QString("graphics_header");}
+
signals:
void sectionResized(int logicalIndex, int size);
void heightResized();
diff --git a/sources/qetgraphicsitem/ViewItem/qetgraphicstableitem.cpp b/sources/qetgraphicsitem/ViewItem/qetgraphicstableitem.cpp
index dff66e981..ca17903be 100644
--- a/sources/qetgraphicsitem/ViewItem/qetgraphicstableitem.cpp
+++ b/sources/qetgraphicsitem/ViewItem/qetgraphicstableitem.cpp
@@ -1,4 +1,4 @@
-/*
+/*
Copyright 2006-2020 QElectroTech Team
This file is part of QElectroTech.
@@ -19,6 +19,9 @@
#include "diagram.h"
#include "qetgraphicsheaderitem.h"
#include "QPropertyUndoCommand/qpropertyundocommand.h"
+#include "qetxml.h"
+#include "nomenclaturemodel.h"
+#include "elementprovider.h"
#include
#include
@@ -55,6 +58,8 @@ QetGraphicsTableItem::QetGraphicsTableItem(QGraphicsItem *parent) :
connect(m_header_item, &QetGraphicsHeaderItem::heightResized, this, [this]() {
m_header_item->setPos(0, 0-m_header_item->rect().height());
});
+ //Init the size of table without a model
+ setModel();
}
QetGraphicsTableItem::~QetGraphicsTableItem()
@@ -86,6 +91,10 @@ void QetGraphicsTableItem::setModel(QAbstractItemModel *model)
connect(m_model, &QAbstractItemModel::dataChanged, this, &QetGraphicsTableItem::dataChanged);
connect(m_model, &QAbstractItemModel::modelReset, this, &QetGraphicsTableItem::modelReseted);
}
+
+ if (m_next_table) {
+ m_next_table->setModel(m_model);
+ }
}
/**
@@ -141,7 +150,7 @@ void QetGraphicsTableItem::paint(QPainter *painter, const QStyleOptionGraphicsIt
painter->restore();
return;
}
- painter->setFont(m_model->data(model()->index(0,0), Qt::FontRole).value());
+ painter->setFont(m_model->data(m_model->index(0,0), Qt::FontRole).value());
//Draw vertical lines
auto offset= 0;
@@ -213,6 +222,7 @@ void QetGraphicsTableItem::setMargins(const QMargins &margins)
*/
void QetGraphicsTableItem::setSize(const QSize &size)
{
+ qDebug() << "ici";
auto new_size = size;
if (new_size.width() < minimumSize().width()) {
new_size.setWidth(minimumSize().width());
@@ -296,7 +306,8 @@ int QetGraphicsTableItem::displayNRow() const {
*/
void QetGraphicsTableItem::setPreviousTable(QetGraphicsTableItem *table)
{
- if (m_previous_table == table) {
+ if (m_previous_table == table ||
+ this == table) {
return;
}
@@ -316,13 +327,6 @@ void QetGraphicsTableItem::setPreviousTable(QetGraphicsTableItem *table)
old_previous_table->nextTable() == this) {
old_previous_table->setNextTable(nullptr);
}
-
- //Set the m_model to every next table
- auto next_ = m_next_table;
- while (next_) {
- next_->setModel(m_model);
- next_ = next_->nextTable();
- }
}
/**
@@ -333,7 +337,8 @@ void QetGraphicsTableItem::setPreviousTable(QetGraphicsTableItem *table)
*/
void QetGraphicsTableItem::setNextTable(QetGraphicsTableItem *table)
{
- if (m_next_table == table) {
+ if (m_next_table == table ||
+ this == table) {
return;
}
@@ -393,6 +398,119 @@ void QetGraphicsTableItem::setToMinimumHeight()
setSize(size_);
}
+void QetGraphicsTableItem::initLink()
+{
+ if (!m_pending_previous_table_uuid.isNull())
+ {
+ ElementProvider provider_(this->diagram());
+ if (auto previous_table = provider_.tableFromUuid(m_pending_previous_table_uuid)) {
+ setPreviousTable(previous_table);
+ }
+ m_pending_previous_table_uuid = QUuid(); //Set to null in case initLink is called again
+ }
+ setSize(m_pending_size);
+}
+
+/**
+ * @brief QetGraphicsTableItem::toXml
+ * Save the table to xml
+ * @param dom_document : parent document
+ * @return the dom_element that describe the table
+ */
+QDomElement QetGraphicsTableItem::toXml(QDomDocument &dom_document) const
+{
+ auto dom_table = dom_document.createElement(xmlTagName());
+ dom_table.setAttribute("x", QString::number(pos().x()));
+ dom_table.setAttribute("y", QString::number(pos().y()));
+ dom_table.setAttribute("width", QString::number(m_current_size.width()));
+ dom_table.setAttribute("height", QString::number(m_current_size.height()));
+ dom_table.setAttribute("uuid", m_uuid.toString());
+ dom_table.setAttribute("name", m_name);
+ dom_table.setAttribute("display_n_row", QString::number(m_number_of_displayed_row));
+
+ //Add the header xml
+ dom_table.appendChild(m_header_item->toXml(dom_document));
+
+ //Add previous table, the model is save by the previous table
+ if (m_previous_table)
+ {
+ auto dom_previous_table = dom_document.createElement("previous_table");
+ dom_previous_table.setAttribute("uuid", m_previous_table->m_uuid.toString());
+ dom_table.appendChild(dom_previous_table);
+ }
+ else if (m_model) //There is not a previous table, we need to save the model
+ {
+ //Add cell properties
+ auto dom_cell = dom_document.createElement("cell");
+ dom_cell.setAttribute("font", m_model->data(m_model->index(0,0), Qt::FontRole).toString());
+ auto me = QMetaEnum::fromType();
+ dom_cell.setAttribute("alignment", me.valueToKey(m_model->data(m_model->index(0,0), Qt::TextAlignmentRole).toInt()));
+ dom_cell.appendChild(QETXML::marginsToXml(dom_document, m_margin));
+ dom_table.appendChild(dom_cell);
+
+ //Add model
+ auto dom_model = dom_document.createElement("model");
+ auto nomenclature_model = static_cast(m_model);
+ dom_model.appendChild(nomenclature_model->toXml(dom_document));
+ dom_table.appendChild(dom_model);
+
+ }
+
+ return dom_table;
+}
+
+/**
+ * @brief QetGraphicsTableItem::fromXml
+ * Restore the table from xml.
+ * Make this item is already in a diagram to
+ * @param dom_element
+ */
+void QetGraphicsTableItem::fromXml(const QDomElement &dom_element)
+{
+ if (dom_element.tagName() != xmlTagName()) {
+ return;
+ }
+
+ this->setPos(dom_element.attribute("x", QString::number(10)).toDouble(),
+ dom_element.attribute("y", QString::number(10)).toDouble());
+ //Size is not set now because will change during the whole process of opening a project from the xml
+ m_pending_size = QSize(dom_element.attribute("width", QString::number(no_model_width)).toInt(),
+ dom_element.attribute("height", QString::number(no_model_height)).toInt());
+
+ m_uuid = QUuid(dom_element.attribute("uuid", QUuid::createUuid().toString()));
+ m_name = dom_element.attribute("name");
+ m_number_of_displayed_row = dom_element.attribute("display_n_row", QString::number(0)).toInt();
+ m_margin = QETXML::marginsFromXml(dom_element.firstChildElement("margins"));
+
+ auto vector_ = QETXML::directChild(dom_element, "previous_table");
+ if (vector_.size()) { //Table have a previous table
+ m_pending_previous_table_uuid = QUuid(vector_.first().attribute("uuid"));
+ }
+ else if (this->diagram()) //The table haven't got a previous table, so there should be a model save to xml
+ {
+ //Get table
+ auto model_ = new NomenclatureModel(this->diagram()->project(), this->diagram()->project());
+ model_->fromXml(dom_element.firstChildElement("model").firstChildElement(NomenclatureModel::xmlTagName()));
+ this->setModel(model_);
+
+ //Get cell properties
+ auto dom_cell = dom_element.firstChildElement("cell");
+ //font
+ QFont font_;
+ font_.fromString(dom_cell.attribute("font"));
+ m_model->setData(m_model->index(0,0), font_, Qt::FontRole);
+ //alignment
+ auto me = QMetaEnum::fromType();
+ m_model->setData(m_model->index(0,0), me.keyToValue(dom_cell.attribute("alignment").toStdString().data()));
+ dom_cell.setAttribute("alignment", me.valueToKey(m_model->data(m_model->index(0,0), Qt::TextAlignmentRole).toInt()));
+ //margins
+ m_margin = QETXML::marginsFromXml(dom_cell.firstChildElement("margins"));
+ }
+
+ //Restore the header from xml
+ m_header_item->fromXml(dom_element.firstChildElement(QetGraphicsHeaderItem::xmlTagName()));
+}
+
/**
* @brief QetGraphicsTableItem::hoverEnterEvent
* Reimplemented from QetGraphicsItem
diff --git a/sources/qetgraphicsitem/ViewItem/qetgraphicstableitem.h b/sources/qetgraphicsitem/ViewItem/qetgraphicstableitem.h
index 95f3219f0..300eed9fd 100644
--- a/sources/qetgraphicsitem/ViewItem/qetgraphicstableitem.h
+++ b/sources/qetgraphicsitem/ViewItem/qetgraphicstableitem.h
@@ -74,6 +74,12 @@ class QetGraphicsTableItem : public QetGraphicsItem
QetGraphicsTableItem *previousTable() const;
QetGraphicsTableItem *nextTable() const;
void setToMinimumHeight();
+ void initLink();
+ QUuid uuid() const {return m_uuid;}
+
+ QDomElement toXml(QDomDocument &dom_document) const;
+ void fromXml(const QDomElement &dom_element);
+ static QString xmlTagName() {return QString("graphics_table");}
protected:
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
@@ -103,7 +109,8 @@ class QetGraphicsTableItem : public QetGraphicsItem
int m_minimum_row_height;
int m_number_of_displayed_row = 0;
QSize m_current_size,
- m_old_size;
+ m_old_size,
+ m_pending_size;
int m_br_margin= 10;
QRectF m_bounding_rect;
@@ -115,6 +122,8 @@ class QetGraphicsTableItem : public QetGraphicsItem
*m_next_table = nullptr;
QString m_name;
+ QUuid m_uuid = QUuid::createUuid(),
+ m_pending_previous_table_uuid;
};
#endif // QetGraphicsTableItem_H
diff --git a/sources/qetgraphicsitem/dynamicelementtextitem.cpp b/sources/qetgraphicsitem/dynamicelementtextitem.cpp
index 2309da9d8..f887d005a 100644
--- a/sources/qetgraphicsitem/dynamicelementtextitem.cpp
+++ b/sources/qetgraphicsitem/dynamicelementtextitem.cpp
@@ -86,7 +86,7 @@ DynamicElementTextItem::DynamicElementTextItem()
*/
QDomElement DynamicElementTextItem::toXml(QDomDocument &dom_doc) const
{
- QDomElement root_element = dom_doc.createElement(xmlTaggName());
+ QDomElement root_element = dom_doc.createElement(xmlTagName());
root_element.setAttribute("x", QString::number(pos().x()));
root_element.setAttribute("y", QString::number(pos().y()));
@@ -153,7 +153,7 @@ QDomElement DynamicElementTextItem::toXml(QDomDocument &dom_doc) const
*/
void DynamicElementTextItem::fromXml(const QDomElement &dom_elmt)
{
- if (dom_elmt.tagName() != xmlTaggName()) {
+ if (dom_elmt.tagName() != xmlTagName()) {
qDebug() << "DynamicElementTextItem::fromXml : Wrong tagg name";
return;
}
diff --git a/sources/qetgraphicsitem/dynamicelementtextitem.h b/sources/qetgraphicsitem/dynamicelementtextitem.h
index 643473dc0..0bdaf14c3 100644
--- a/sources/qetgraphicsitem/dynamicelementtextitem.h
+++ b/sources/qetgraphicsitem/dynamicelementtextitem.h
@@ -91,7 +91,7 @@ class DynamicElementTextItem : public DiagramTextItem
void setTextFrom (DynamicElementTextItem::TextFrom text_from);
QString text() const;
void setText(const QString &text);
- static QString xmlTaggName() {return QString("dynamic_elmt_text");}
+ static QString xmlTagName() {return QString("dynamic_elmt_text");}
void setInfoName(const QString &info_name);
QString infoName() const;
void setCompositeText(const QString &text);
diff --git a/sources/qetgraphicsitem/element.cpp b/sources/qetgraphicsitem/element.cpp
index 400e5ce60..0871c6afc 100644
--- a/sources/qetgraphicsitem/element.cpp
+++ b/sources/qetgraphicsitem/element.cpp
@@ -555,7 +555,7 @@ DynamicElementTextItem *Element::parseDynamicText(const QDomElement &dom_element
//and the uuid (because the uuid, is the uuid of the descritpion and not the uuid of instantiated dynamic text field)
QDomElement dom(dom_element.cloneNode(true).toElement());
- dom.setTagName(DynamicElementTextItem::xmlTaggName());
+ dom.setTagName(DynamicElementTextItem::xmlTagName());
deti->fromXml(dom);
deti->m_uuid = QUuid::createUuid();
this->addDynamicTextItem(deti);
@@ -741,7 +741,7 @@ bool Element::fromXml(QDomElement &e, QHash &table_id_adr, bool
//************************//
//***Dynamic texts item***//
//************************//
- for (const QDomElement& qde : QET::findInDomElement(e, "dynamic_texts", DynamicElementTextItem::xmlTaggName()))
+ for (const QDomElement& qde : QET::findInDomElement(e, "dynamic_texts", DynamicElementTextItem::xmlTagName()))
{
DynamicElementTextItem *deti = new DynamicElementTextItem(this);
addDynamicTextItem(deti);
diff --git a/sources/qetproject.cpp b/sources/qetproject.cpp
index cc7efe374..a31dc0f2f 100644
--- a/sources/qetproject.cpp
+++ b/sources/qetproject.cpp
@@ -1391,6 +1391,9 @@ void QETProject::readDiagramsXml(QDomDocument &xml_project)
"Mise en place des références croisées"
"
"));
}
+
+ m_data_base.updateDB(); //All diagrams and items are created we need to update the database
+
for(Diagram *d : diagrams())
{
if(dlgWaiting)
diff --git a/sources/qetxml.cpp b/sources/qetxml.cpp
index e088878f1..974a8a5f6 100644
--- a/sources/qetxml.cpp
+++ b/sources/qetxml.cpp
@@ -17,8 +17,10 @@
*/
#include "qetxml.h"
#include "nameslist.h"
+
#include
#include
+#include
/**
* @brief QETXML::penToXml
@@ -72,8 +74,10 @@ QPen QETXML::penFromXml(const QDomElement &element)
else if (style == "DotLine") pen.setStyle(Qt::DotLine);
else if (style == "DashDotLine") pen.setStyle(Qt::DashDotLine);
else if (style == "DashDotDotLine") pen.setStyle(Qt::DashDotDotLine);
- else if (style == "CustomDashLine") pen.setStyle(Qt::CustomDashLine),
- pen.setDashPattern( QVector() << 10 << 10 );
+ else if (style == "CustomDashLine") {
+ pen.setStyle(Qt::CustomDashLine);
+ pen.setDashPattern( QVector() << 10 << 10 );
+ }
else pen.setStyle(Qt::DashLine);
pen.setColor(QColor(element.attribute("color", "#000000")));
@@ -274,3 +278,197 @@ QDomElement QETXML::textToDomElement(QDomDocument &document, const QString& tag_
element.appendChild(text);
return element;
}
+
+/**
+ * @brief QETXML::directChild
+ * @param element
+ * @param tag_name
+ * @return All direct child of @element with the tag name @tag_name
+ */
+QVector QETXML::directChild(const QDomElement &element, const QString &tag_name)
+{
+ QVector return_list;
+ for (QDomNode node = element.firstChild() ; !node.isNull() ; node = node.nextSibling())
+ {
+ if (!node.isElement()) continue;
+ QDomElement element = node.toElement();
+ if (element.isNull() || element.tagName() != tag_name) continue;
+ return_list << element;
+ }
+
+ return(return_list);
+}
+
+/**
+ * @brief QETXML::subChild
+ * @param element
+ * @param parent_tag_name
+ * @param children_tag_name
+ * @return When given an xml dom element @element,
+ * returns a vector of all children dom_elements tagged @children_tag_name
+ * nested in the parent dom elements tagged parent_tag_name, themselves children of the dom element @element.
+ */
+QVector QETXML::subChild(const QDomElement &element, const QString parent_tag_name, const QString &children_tag_name)
+{
+ QVector return_list;
+
+ for (QDomNode child = element.firstChild() ; !child.isNull() ; child = child.nextSibling())
+ {
+ QDomElement parents = child.toElement();
+ if (parents.isNull() || parents.tagName() != parent_tag_name)
+ continue;
+
+ for (QDomNode node_children = parents.firstChild() ; !node_children.isNull() ; node_children = node_children.nextSibling())
+ {
+ QDomElement n_children = node_children.toElement();
+ if (!n_children.isNull() && n_children.tagName() == children_tag_name)
+ return_list.append(n_children);
+ }
+ }
+
+ return(return_list);
+}
+
+/**
+ * @brief QETXML::marginsToXml
+ * Save a QMargins to xml. the xml tag name is 'margins'
+ * @param parent_document
+ * @param margins
+ * @return
+ */
+QDomElement QETXML::marginsToXml(QDomDocument &parent_document, const QMargins &margins)
+{
+ auto dom_ = parent_document.createElement("margins");
+ auto text_ = parent_document.createTextNode(QString::number(margins.left()) + QString(";") +
+ QString::number(margins.top()) + QString(";") +
+ QString::number(margins.right()) + QString(";") +
+ QString::number(margins.bottom()));
+ dom_.appendChild(text_);
+ return dom_;
+}
+
+/**
+ * @brief QETXML::marginsFromXml
+ * @param element
+ * @return a QMargins from an xml description.
+ * The tag name must ne 'margins'
+ */
+QMargins QETXML::marginsFromXml(const QDomElement &element)
+{
+ if (element.tagName() != "margins") {
+ return QMargins();
+ }
+
+ auto margins_ = element.text().split(";");
+ if (margins_.size() == 4) {
+ return QMargins(margins_.at(0).toInt(), margins_.at(1).toInt(), margins_.at(2).toInt(), margins_.at(3).toInt());
+ } else {
+ return QMargins();
+ }
+}
+
+/**
+ * @brief QETXML::modelHeaderDataToXml
+ * Save to xml element all header data specified by @horizontal_section_role and @vertical_section_role
+ * @param parent_document
+ * @param model
+ * @param horizontal_section_role : key as header section and value as list of roles to save in xml
+ * @param vertical_section_role :key as header section and value as list of roles to save in xml
+ * @return
+ */
+QDomElement QETXML::modelHeaderDataToXml(QDomDocument &parent_document, const QAbstractItemModel *model, QHash> horizontal_section_role, QHash> vertical_section_role)
+{
+ auto dom_element = parent_document.createElement("header_data");
+
+ auto orientation_ = Qt::Horizontal;
+ auto data_hash = horizontal_section_role;
+ auto meta_enum_ori = QMetaEnum::fromType();
+ auto meta_enum_role = QMetaEnum::fromType();
+
+ //Iterate twice, first for horizontal header and second to vertical header
+ while (true)
+ {
+ for (auto section : data_hash.keys())
+ {
+ for (auto role : data_hash.value(section))
+ {
+ auto variant = model->headerData(section, orientation_, role);
+ if (variant.isValid())
+ {
+ auto dom_data = parent_document.createElement("data");
+ dom_data.setAttribute("section", QString::number(section));
+ dom_data.setAttribute("orientation", meta_enum_ori.valueToKey(orientation_));
+ dom_data.setAttribute("role", meta_enum_role.valueToKey(role));
+
+ auto text_node = parent_document.createTextNode("");
+ if (role == Qt::DisplayRole || role == Qt::EditRole || role == Qt::ToolTipRole || role == Qt::StatusTipRole || role == Qt::WhatsThisRole)
+ {
+ text_node.setData(variant.toString());
+ }
+ else if (role == Qt::FontRole)
+ {
+ auto font = variant.value();
+ text_node.setData(font.toString());
+ }
+ else if (role == Qt::TextAlignmentRole)
+ {
+ auto me = QMetaEnum::fromType();
+ text_node.setData(me.valueToKey(variant.toInt()));
+ }
+ dom_data.appendChild(text_node);
+ dom_element.appendChild(dom_data);
+ }
+ }
+ }
+
+ if(orientation_ == Qt::Vertical) {
+ break;
+ } else {
+ data_hash = vertical_section_role;
+ orientation_ = Qt::Vertical;
+ }
+ }
+
+ return dom_element;
+}
+
+/**
+ * @brief QETXML::modelHeaderDataFromXml
+ * Restore from xml modele header data
+ * @param element
+ * @param model
+ */
+void QETXML::modelHeaderDataFromXml(const QDomElement &element, QAbstractItemModel *model)
+{
+ if (element.tagName() != "header_data")
+ return;
+
+ auto meta_enum_orientation = QMetaEnum::fromType();
+ auto meta_enum_role = QMetaEnum::fromType();
+
+ for (auto child : QETXML::directChild(element, "data"))
+ {
+ auto section_ = child.attribute("section", "-1").toInt();
+ auto orientation_ = Qt::Orientation(meta_enum_orientation.keyToValue(child.attribute("orientation", "Horizontal").toStdString().data()));
+ auto role_ = meta_enum_role.keyToValue(child.attribute("role", "DisplayRole").toStdString().data());
+ auto text_ = child.text();
+ QVariant data_;
+
+ if (role_ == Qt::DisplayRole || role_ == Qt::EditRole || role_ == Qt::ToolTipRole || role_ == Qt::StatusTipRole || role_ == Qt::WhatsThisRole) {
+ data_ = text_;
+ }
+ else if (role_ == Qt::FontRole)
+ {
+ QFont font;
+ font.fromString(text_);
+ data_ = font;
+ }
+ else if (role_ == Qt::TextAlignmentRole)
+ {
+ auto me = QMetaEnum::fromType();
+ data_ = me.keyToValue(text_.toStdString().data());
+ }
+
+ model->setHeaderData(section_, orientation_, data_, role_);
+ }
+}
diff --git a/sources/qetxml.h b/sources/qetxml.h
index 3aaa1445e..4b0868839 100644
--- a/sources/qetxml.h
+++ b/sources/qetxml.h
@@ -1,4 +1,4 @@
-/*
+/*
Copyright 2006-2019 The QElectroTech Team
This file is part of QElectroTech.
@@ -24,6 +24,7 @@
class QDomDocument;
class QDir;
class QFile;
+class QAbstractItemModel;
/**
*This namespace contain some function to use xml with QET.
@@ -42,6 +43,15 @@ namespace QETXML
bool writeXmlFile(const QDomDocument &xml_document, const QString &file_path, QString *error_message = nullptr);
QDomElement textToDomElement (QDomDocument &document, const QString& tag_name, const QString& value);
+
+ QVector directChild(const QDomElement &element, const QString &tag_name);
+ QVector subChild(const QDomElement &element, const QString parent_tag_name, const QString &children_tag_name);
+
+ QDomElement marginsToXml (QDomDocument &parent_document, const QMargins &margins);
+ QMargins marginsFromXml(const QDomElement &element);
+
+ QDomElement modelHeaderDataToXml(QDomDocument &parent_document, const QAbstractItemModel *model, QHash> horizontal_section_role, QHash> vertical_section_role);
+ void modelHeaderDataFromXml(const QDomElement &element, QAbstractItemModel *model);
}
#endif // QETXML_H