qet graphics table item : to/from xml change

The font, alignment and margins is not saved by the table anymore but by
the model.
This commit is contained in:
Claveau Joshua
2020-05-08 00:08:57 +02:00
parent 9fa7e21905
commit 37efa97ce7
10 changed files with 155 additions and 91 deletions

View File

@@ -21,9 +21,11 @@
#include "elementquerywidget.h"
#include "diagram.h"
#include "qetgraphicsheaderitem.h"
#include "addtabledialog.h"
#include "qetutils.h"
#include <QDialog>
#include "addtabledialog.h"
QetGraphicsTableFactory::QetGraphicsTableFactory()
{
@@ -47,13 +49,13 @@ void QetGraphicsTableFactory::createAndAddNomenclature(Diagram *diagram)
model->autoHeaders();
model->setData(model->index(0,0), int(d->tableAlignment()), Qt::TextAlignmentRole);
model->setData(model->index(0,0), d->tableFont(), Qt::FontRole);
model->setData(model->index(0,0), QETUtils::marginsToString(d->headerMargins()), Qt::UserRole+1);
model->setHeaderData(0, Qt::Horizontal, int(d->headerAlignment()), Qt::TextAlignmentRole);
model->setHeaderData(0, Qt::Horizontal, d->headerFont(), Qt::FontRole);
model->setHeaderData(0, Qt::Horizontal, QETUtils::marginsToString(d->headerMargins()), Qt::UserRole+1);
auto table = new QetGraphicsTableItem();
table->setTableName(d->tableName());
table->setMargins(d->tableMargins());
table->headerItem()->setMargins(d->headerMargins());
table->setModel(model);
diagram->addItem(table);
table->setPos(50,50);

View File

@@ -213,8 +213,8 @@ 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.
* Save the model to xml,since model can have unlimited data we only save few data (only these used by qelectrotech).
* The query, all header data. and some data of index::(0,0). All other data are not saved.
* @param document
* @return
*/
@@ -228,6 +228,14 @@ QDomElement NomenclatureModel::toXml(QDomDocument &document) const
dom_query.appendChild(dom_query_txt);
dom_element.appendChild(dom_query);
//Add index 0,0 data
auto index_00 = document.createElement("index00");
index_00.setAttribute("font", m_index_0_0_data.value(Qt::FontRole).toString());
auto me = QMetaEnum::fromType<Qt::Alignment>();
index_00.setAttribute("alignment", me.valueToKey(m_index_0_0_data.value(Qt::TextAlignmentRole).toInt()));
dom_element.appendChild(index_00);
index_00.setAttribute("margins", m_index_0_0_data.value(Qt::UserRole+1).toString());
//header data
QHash<int, QList<int>> horizontal_;
for (auto key : m_header_data.keys()) {
@@ -249,6 +257,16 @@ void NomenclatureModel::fromXml(const QDomElement &element)
return;
query(element.firstChildElement("query").text());
//Index 0,0
auto index_00 = element.firstChildElement("index00");
QFont font_;
font_.fromString(index_00.attribute("font"));
m_index_0_0_data.insert(Qt::FontRole, font_);
auto me = QMetaEnum::fromType<Qt::Alignment>();
m_index_0_0_data.insert(Qt::TextAlignmentRole, me.keyToValue(index_00.attribute("alignment").toStdString().data()));
m_index_0_0_data.insert(Qt::UserRole+1, index_00.attribute("margins"));
QETXML::modelHeaderDataFromXml(element.firstChildElement("header_data"), this);
}

View File

@@ -28,6 +28,9 @@ class QETProject;
* @brief The NomenclatureModel class
* An element nomenclature Model.
* This model represent a 2D data.
*
* NOTE : qelectrotech use the data Qt::UserRole+1 on this model to store a QMargins formated to a QString
* This is important because to/from XML of this class store the data Qt::UserRole+1 as QString.
*/
class NomenclatureModel : public QAbstractTableModel
{

View File

@@ -18,6 +18,7 @@
#include "qetgraphicsheaderitem.h"
#include "qabstractitemmodel.h"
#include "qetxml.h"
#include "qetutils.h"
#include <QFontMetrics>
#include <QPainter>
@@ -30,9 +31,7 @@ static int no_model_width = 40;
*/
QetGraphicsHeaderItem::QetGraphicsHeaderItem(QGraphicsItem *parent) :
QGraphicsObject(parent)
{
m_margin = QMargins(5,5,5,5);
}
{}
/**
* @brief QetGraphicsHeaderItem::setModel
@@ -126,10 +125,11 @@ void QetGraphicsHeaderItem::paint(QPainter *painter, const QStyleOptionGraphicsI
}
//Write text of each cell
QPointF top_left(m_margin.left(), m_margin.top());
auto margins_ = QETUtils::marginsFromString(m_model->headerData(0, Qt::Horizontal, Qt::UserRole+1).toString());
QPointF top_left(margins_.left(), margins_.top());
for (auto i= 0 ; i<m_model->columnCount() ; ++i)
{
QSize size(m_current_sections_width.at(i) - m_margin.left() - m_margin.right(), m_section_height - m_margin.top() - m_margin.bottom());
QSize size(m_current_sections_width.at(i) - margins_.left() - margins_.right(), m_section_height - margins_.top() - margins_.bottom());
painter->drawText(QRectF(top_left, size),
m_model->headerData(0, Qt::Horizontal, Qt::TextAlignmentRole).toInt(),
m_model->headerData(i, Qt::Horizontal).toString());
@@ -200,16 +200,6 @@ int QetGraphicsHeaderItem::sectionSize(int logical_index) const
}
}
/**
* @brief QetGraphicsHeaderItem::setMargins
* @param margins
*/
void QetGraphicsHeaderItem::setMargins(const QMargins &margins)
{
m_margin = margins;
headerDataChanged(Qt::Horizontal, 0,1);
}
/**
* @brief QetGraphicsHeaderItem::toXml
* save the header to xml
@@ -219,7 +209,9 @@ void QetGraphicsHeaderItem::setMargins(const QMargins &margins)
QDomElement QetGraphicsHeaderItem::toXml(QDomDocument &document) const
{
auto dom_element = document.createElement(xmlTagName());
dom_element.appendChild(QETXML::marginsToXml(document, m_margin));
if (m_model) {
dom_element.appendChild(QETXML::marginsToXml(document, QETUtils::marginsFromString(m_model->headerData(0, Qt::Horizontal, Qt::UserRole+1).toString())));
}
return dom_element;
}
@@ -231,11 +223,12 @@ QDomElement QetGraphicsHeaderItem::toXml(QDomDocument &document) const
*/
void QetGraphicsHeaderItem::fromXml(const QDomElement &element)
{
if (element.tagName() != xmlTagName()) {
if ((element.tagName() != xmlTagName()) || !m_model) {
return;
}
m_margin = QETXML::marginsFromXml(element.firstChildElement("margins"));
auto margins_ = QETUtils::marginsToString(QETXML::marginsFromXml(element.firstChildElement("margins")));
m_model->setHeaderData(0, Qt::Horizontal, QETUtils::marginsToString(QETXML::marginsFromXml(element.firstChildElement("margins"))), Qt::UserRole+1);
}
/**
@@ -255,8 +248,9 @@ void QetGraphicsHeaderItem::setUpMinimumSectionsSize()
}
QFontMetrics metrics(m_model->headerData(0, Qt::Horizontal, Qt::FontRole).value<QFont>());
auto margins_ = QETUtils::marginsFromString(m_model->headerData(0, Qt::Horizontal, Qt::UserRole+1).toString());
//Set the height of row;
m_minimum_section_height = metrics.boundingRect("HEIGHT TEST").height() + m_margin.top() + m_margin.bottom();
m_minimum_section_height = metrics.boundingRect("HEIGHT TEST").height() + margins_.top() + margins_.bottom();
m_sections_minimum_width.clear();
m_sections_minimum_width.resize(m_model->columnCount());
@@ -264,7 +258,7 @@ void QetGraphicsHeaderItem::setUpMinimumSectionsSize()
for (auto i= 0 ; i<m_model->columnCount() ; ++i)
{
auto str = m_model->headerData(i, Qt::Horizontal).toString();
m_sections_minimum_width.replace(i, metrics.boundingRect(str).width() + m_margin.left() + m_margin.right());
m_sections_minimum_width.replace(i, metrics.boundingRect(str).width() + margins_.left() + margins_.right());
}
m_minimum_width = std::accumulate(m_sections_minimum_width.begin(), m_sections_minimum_width.end(), 0);
@@ -293,6 +287,7 @@ void QetGraphicsHeaderItem::headerDataChanged(Qt::Orientations orientation, int
setUpMinimumSectionsSize();
adjustSize();
update();
}
/**

View File

@@ -32,14 +32,15 @@ class QAbstractItemModel;
* Margins, to edit the margin between the cell and the text.
* Text font.
* Text alignment in the cell
* These two last parameters are not settable directly with the header but trough the model to be displayed by the header.
* These three parameters are not settable directly with the header but trough the model to be displayed by the header.
* Header search these parameters only in the section 0 for cell of header.
* By consequence, set data in other section is useless also these parameter can't be set individually for each cell.
* The margins is stored in the model in index Qt::UserRole+1 and for value a QString. See QETUtils::marginsFromString and QETUtils::marginsToString
*/
class QetGraphicsHeaderItem : public QGraphicsObject
{
Q_OBJECT
Q_PROPERTY(QMargins margins READ margins WRITE setMargins)
public:
QetGraphicsHeaderItem(QGraphicsItem *parent = nullptr);
@@ -54,8 +55,6 @@ class QetGraphicsHeaderItem : public QGraphicsObject
QRect rect() const;
void resizeSection(int logicalIndex, int size);
int sectionSize(int logical_index) const;
QMargins margins() const {return m_margin;}
void setMargins(const QMargins &margins);
QVector<int> minimumSectionWidth() const {return m_sections_minimum_width;}
int minimumWidth() const {return m_minimum_width;}
@@ -77,7 +76,6 @@ class QetGraphicsHeaderItem : public QGraphicsObject
private:
QRectF m_bounding_rect;
QAbstractItemModel *m_model = nullptr;
QMargins m_margin;
QVector<int> m_sections_minimum_width,
m_current_sections_width;
int m_section_height=1,

View File

@@ -22,6 +22,7 @@
#include "qetxml.h"
#include "nomenclaturemodel.h"
#include "elementprovider.h"
#include "qetutils.h"
#include <QAbstractItemModel>
#include <QFontMetrics>
@@ -45,7 +46,6 @@ QetGraphicsTableItem::QetGraphicsTableItem(QGraphicsItem *parent) :
setAcceptHoverEvents(true);
setUpHandler();
m_margin = QMargins(5,3,15,3);
//A litle bounding rect before model is set,
//then user can already grab this item, even if model is not already set
m_bounding_rect.setRect(m_br_margin/-2, m_br_margin/-2, 50, 50);
@@ -183,7 +183,8 @@ void QetGraphicsTableItem::paint(QPainter *painter, const QStyleOptionGraphicsIt
//Write text of each cell
for (auto i=0 ; i<row_count ; ++i)
{
QPointF top_left(m_margin.left(), i==0? m_margin.top() : cell_height*i + m_margin.top());
auto margin_ = QETUtils::marginsFromString(m_model->index(0,0).data(Qt::UserRole+1).toString());
QPointF top_left(margin_.left(), i==0? margin_.top() : cell_height*i + margin_.top());
for(auto j= 0 ; j<m_model->columnCount() ; ++j)
{
@@ -191,8 +192,8 @@ void QetGraphicsTableItem::paint(QPainter *painter, const QStyleOptionGraphicsIt
if (j>0) {
top_left.setX(top_left.x() + m_header_item->sectionSize(j-1));
}
QSize size(m_header_item->sectionSize(j) - m_margin.left() - m_margin.right(),
static_cast<int>(cell_height) - m_margin.top() - m_margin.bottom());
QSize size(m_header_item->sectionSize(j) - margin_.left() - margin_.right(),
static_cast<int>(cell_height) - margin_.top() - margin_.bottom());
auto index_row = m_previous_table ? i + m_previous_table->displayNRowOffset() : i;
painter->drawText(QRectF(top_left, size),
m_model->data(m_model->index(0,0), Qt::TextAlignmentRole).toInt() | Qt::AlignVCenter,
@@ -203,18 +204,6 @@ void QetGraphicsTableItem::paint(QPainter *painter, const QStyleOptionGraphicsIt
painter->restore();
}
/**
* @brief QetGraphicsTableItem::setMargins
* @param margins
*/
void QetGraphicsTableItem::setMargins(const QMargins &margins)
{
m_margin = margins;
setUpColumnAndRowMinimumSize();
adjustSize();
update();
}
/**
* @brief QetGraphicsTableItem::setSize
* Set the current size of the table to @size
@@ -408,7 +397,7 @@ void QetGraphicsTableItem::initLink()
{
if (!m_pending_previous_table_uuid.isNull())
{
ElementProvider provider_(this->diagram());
ElementProvider provider_(this->diagram()->project());
if (auto previous_table = provider_.tableFromUuid(m_pending_previous_table_uuid)) {
setPreviousTable(previous_table);
}
@@ -446,14 +435,6 @@ QDomElement QetGraphicsTableItem::toXml(QDomDocument &dom_document) const
}
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<Qt::Alignment>();
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<NomenclatureModel *>(m_model);
@@ -486,7 +467,6 @@ void QetGraphicsTableItem::fromXml(const QDomElement &dom_element)
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
@@ -498,19 +478,6 @@ void QetGraphicsTableItem::fromXml(const QDomElement &dom_element)
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<Qt::Alignment>();
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
@@ -597,8 +564,9 @@ void QetGraphicsTableItem::setUpColumnAndRowMinimumSize()
}
QFontMetrics metrics(m_model->data(model()->index(0,0), Qt::FontRole).value<QFont>());
auto margin_ = QETUtils::marginsFromString(model()->index(0,0).data(Qt::UserRole+1).toString());
//Set the height of row;
m_minimum_row_height = metrics.boundingRect("HEIGHT TEST").height() + m_margin.top() + m_margin.bottom();
m_minimum_row_height = metrics.boundingRect("HEIGHT TEST").height() + margin_.top() + margin_.bottom();
m_minimum_column_width = m_header_item->minimumSectionWidth();
@@ -609,7 +577,7 @@ void QetGraphicsTableItem::setUpColumnAndRowMinimumSize()
{
auto index = m_model->index(row, col);
auto width = metrics.boundingRect(index.data().toString()).width();
m_minimum_column_width.replace(col, std::max(m_minimum_column_width.at(col), width + m_margin.left() + m_margin.right()));
m_minimum_column_width.replace(col, std::max(m_minimum_column_width.at(col), width + margin_.left() + margin_.right()));
}
}
}
@@ -737,6 +705,7 @@ void QetGraphicsTableItem::dataChanged(const QModelIndex &topLeft, const QModelI
setUpColumnAndRowMinimumSize();
adjustSize();
update();
}
/**

View File

@@ -34,15 +34,15 @@ class QetGraphicsHeaderItem;
* Margins, to edit the margin between the cell and the text.
* Text font.
* Text alignment in the cell
* These two last parameters are not settable directly with the table but trough the model to be displayed by the table.
* The table search for font and alignment only in the index(0,0) for all the table.
* By consequence, set data in other index than 0,0 is useless also the alignment and font can't be set individually for each cell.
* These three parameters are not settable directly with the table but trough the model to be displayed by the table.
* The table search these parameters only in the index(0,0) for all the table.
* By consequence, set data in other index than 0,0 is useless also these parameter can't be set individually for each cell.
* The margins is stored in the model in index Qt::UserRole+1 and for value a QString. See QETUtils::marginsFromString and QETUtils::marginsToString
*/
class QetGraphicsTableItem : public QetGraphicsItem
{
Q_OBJECT
Q_PROPERTY(QMargins margins READ margins WRITE setMargins)
Q_PROPERTY(QSize size READ size WRITE setSize)
Q_PROPERTY(int displayNRow READ displayNRow WRITE setDisplayNRow)
@@ -58,8 +58,6 @@ class QetGraphicsTableItem : public QetGraphicsItem
virtual QRectF boundingRect() const override;
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
QMargins margins() const {return m_margin;}
void setMargins(const QMargins &margins);
QetGraphicsHeaderItem *headerItem() const {return m_header_item;}
void setSize(const QSize &size);
QSize size() const;
@@ -104,7 +102,6 @@ class QetGraphicsTableItem : public QetGraphicsItem
private:
QAbstractItemModel *m_model= nullptr;
QMargins m_margin;
QVector<int> m_minimum_column_width;
int m_minimum_row_height;
int m_number_of_displayed_row = 0;

View File

@@ -24,6 +24,7 @@
#include "itemmodelcommand.h"
#include "propertieseditorfactory.h"
#include "elementprovider.h"
#include "qetutils.h"
#include <QAbstractItemModel>
#include <QFontDialog>
@@ -137,28 +138,28 @@ QUndoCommand *GraphicsTablePropertiesEditor::associatedUndo() const
return undo;
}
QMargins header_margins(ui->m_header_left_margin->value(),
QMargins edited_header_margins(ui->m_header_left_margin->value(),
ui->m_header_top_margin->value(),
ui->m_header_right_margin->value(),
ui->m_header_bottom_margin->value());
if (header_margins != m_table_item->headerItem()->margins())
auto model_header_margins = QETUtils::marginsFromString(m_table_item->model()->headerData(0, Qt::Horizontal, Qt::UserRole+1).toString());
if (edited_header_margins != model_header_margins)
{
QVariant old_; old_.setValue(m_table_item->headerItem()->margins());
QVariant new_; new_.setValue(header_margins);
auto undo = new QPropertyUndoCommand(m_table_item->headerItem(), "margins", old_, new_);
auto undo = new ModelHeaderDataCommand(m_table_item->model());
undo->setData(0, Qt::Horizontal, QETUtils::marginsToString(edited_header_margins), Qt::UserRole+1);
undo->setText(tr("Modifier les marges d'une en tête de tableau"));
return undo;
}
QMargins table_margins(ui->m_table_left_margin->value(),
QMargins edited_table_margins(ui->m_table_left_margin->value(),
ui->m_table_top_margin->value(),
ui->m_table_right_margin->value(),
ui->m_table_bottom_margin->value());
if (table_margins != m_table_item->margins())
auto model_margins = QETUtils::marginsFromString(m_table_item->model()->index(0,0).data(Qt::UserRole+1).toString());
if (edited_table_margins != model_margins)
{
QVariant old_; old_.setValue(m_table_item->margins());
QVariant new_; new_.setValue(table_margins);
auto undo = new QPropertyUndoCommand(m_table_item.data(), "margins", old_, new_);
auto undo = new ModelIndexCommand(m_table_item->model(), m_table_item->model()->index(0,0));
undo->setData(QETUtils::marginsToString(edited_table_margins), Qt::UserRole+1);
undo->setText(tr("Modifier les marges d'un tableau"));
return undo;
}
@@ -277,13 +278,13 @@ void GraphicsTablePropertiesEditor::updateUi()
}
}
auto margin = m_table_item->headerItem()->margins();
auto margin = QETUtils::marginsFromString(m_table_item->model()->headerData(0, Qt::Horizontal, Qt::UserRole+1).toString());
ui->m_header_top_margin ->setValue(margin.top());
ui->m_header_left_margin ->setValue(margin.left());
ui->m_header_right_margin ->setValue(margin.right());
ui->m_header_bottom_margin->setValue(margin.bottom());
margin = m_table_item->margins();
margin = QETUtils::marginsFromString(m_table_item->model()->index(0,0).data(Qt::UserRole+1).toString());
ui->m_table_top_margin ->setValue(margin.top());
ui->m_table_left_margin ->setValue(margin.left());
ui->m_table_right_margin ->setValue(margin.right());

View File

@@ -0,0 +1,49 @@
/*
Copyright 2006-2020 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 "qetutils.h"
#include <QString>
#include <QStringList>
QString QETUtils::marginsToString(const QMargins &margins)
{
QString str;
str += QString::number(margins.left());
str += ";";
str += QString::number(margins.top());
str += ";";
str += QString::number(margins.right());
str += ";";
str += QString::number(margins.bottom());
return str;
}
QMargins QETUtils::marginsFromString(const QString &string)
{
QMargins margins;
auto split = string.split(";");
if (split.size() != 4)
return margins;
margins.setLeft (split.at(0).toInt());
margins.setTop (split.at(1).toInt());
margins.setRight (split.at(2).toInt());
margins.setBottom(split.at(3).toInt());
return margins;
}

32
sources/utils/qetutils.h Normal file
View File

@@ -0,0 +1,32 @@
/*
Copyright 2006-2020 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 QETUTILS_H
#define QETUTILS_H
#include <QMargins>
/**
* Provide some small utils function
*/
namespace QETUtils
{
QString marginsToString(const QMargins &margins);
QMargins marginsFromString(const QString &string);
}
#endif // QETUTILS_H