Merge branch 'QetGraphicsTableItem'

This commit is contained in:
Claveau Joshua
2020-03-08 10:41:45 +01:00
16 changed files with 1773 additions and 30 deletions

View File

@@ -1,16 +1,16 @@
Type = UserType + ??? Type = UserType + ???
###DIAGRAM EDITOR### ###DIAGRAM EDITOR###
Element + 1000 Element + 1000
Conductor + 1001 Conductor + 1001
Terminal + 1002 Terminal + 1002
ElementTextItem + 1003 ElementTextItem + 1003
DiagramTextItem + 1004 DiagramTextItem + 1004
IndependentTextItem + 1005 IndependentTextItem + 1005
ConductorTextItem + 1006 ConductorTextItem + 1006
DiagramImageItem + 1007 DiagramImageItem + 1007
QetShapItem + 1008 QetShapItem + 1008
crossRefItem + 1009 crossRefItem + 1009
DynamiqueElementTextItem + 1010 DynamiqueElementTextItem + 1010
ElementPrimitiveDecorator + 2200 ElementPrimitiveDecorator + 2200
###ELEMENT EDITOR### ###ELEMENT EDITOR###
@@ -25,4 +25,8 @@ part rectangle + 1109
part dynamic text field + 1110 part dynamic text field + 1110
###QetGraphicsHandlerItem### ###QetGraphicsHandlerItem###
QetGraphicsHandlerItem = 1200 QetGraphicsHandlerItem + 1200
###VIEW ITEMS###
QetGraphicsTableItem + 1300
QetGraphicsHeaderItem + 1301

View File

@@ -77,7 +77,10 @@ TEMPLATE = app
DEPENDPATH += . DEPENDPATH += .
INCLUDEPATH += sources \ INCLUDEPATH += sources \
sources/titleblock \ sources/titleblock \
sources/ui sources/qetgraphicsitem \ sources/ui \
sources/qetgraphicsitem \
sources/qetgraphicsitem/ViewItem \
sources/qetgraphicsitem/ViewItem/ui \
sources/richtext \ sources/richtext \
sources/factory \ sources/factory \
sources/properties \ sources/properties \
@@ -85,7 +88,7 @@ INCLUDEPATH += sources \
sources/editor \ sources/editor \
sources/editor/esevent \ sources/editor/esevent \
sources/editor/graphicspart \ sources/editor/graphicspart \
sources/editor/ui \ sources/editor/ui \
sources/undocommand \ sources/undocommand \
sources/diagramevent \ sources/diagramevent \
sources/ElementsCollection \ sources/ElementsCollection \
@@ -93,12 +96,12 @@ INCLUDEPATH += sources \
sources/autoNum \ sources/autoNum \
sources/autoNum/ui \ sources/autoNum/ui \
sources/ui/configpage \ sources/ui/configpage \
sources/SearchAndReplace \ sources/SearchAndReplace \
sources/SearchAndReplace/ui \ sources/SearchAndReplace/ui \
sources/NameList \ sources/NameList \
sources/NameList/ui \ sources/NameList/ui \
sources/utils \ sources/utils \
sources/pugixml sources/pugixml \
# Fichiers sources # Fichiers sources
@@ -107,6 +110,8 @@ HEADERS += $$files(sources/*.h) $$files(sources/ui/*.h) \
$$files(sources/titleblock/*.h) \ $$files(sources/titleblock/*.h) \
$$files(sources/richtext/*.h) \ $$files(sources/richtext/*.h) \
$$files(sources/qetgraphicsitem/*.h) \ $$files(sources/qetgraphicsitem/*.h) \
$$files(sources/qetgraphicsitem/ViewItem/*.h) \
$$files(sources/qetgraphicsitem/ViewItem/ui/*.h) \
$$files(sources/factory/*.h) \ $$files(sources/factory/*.h) \
$$files(sources/properties/*.h) \ $$files(sources/properties/*.h) \
$$files(sources/editor/ui/*.h) \ $$files(sources/editor/ui/*.h) \
@@ -133,6 +138,8 @@ SOURCES += $$files(sources/*.cpp) \
$$files(sources/richtext/*.cpp) \ $$files(sources/richtext/*.cpp) \
$$files(sources/ui/*.cpp) \ $$files(sources/ui/*.cpp) \
$$files(sources/qetgraphicsitem/*.cpp) \ $$files(sources/qetgraphicsitem/*.cpp) \
$$files(sources/qetgraphicsitem/ViewItem/*.cpp) \
$$files(sources/qetgraphicsitem/ViewItem/ui/*.cpp) \
$$files(sources/factory/*.cpp) \ $$files(sources/factory/*.cpp) \
$$files(sources/properties/*.cpp) \ $$files(sources/properties/*.cpp) \
$$files(sources/editor/ui/*.cpp) \ $$files(sources/editor/ui/*.cpp) \
@@ -173,7 +180,8 @@ FORMS += $$files(sources/richtext/*.ui) \
$$files(sources/autoNum/ui/*.ui) \ $$files(sources/autoNum/ui/*.ui) \
$$files(sources/ui/configpage/*.ui) \ $$files(sources/ui/configpage/*.ui) \
$$files(sources/SearchAndReplace/ui/*.ui) \ $$files(sources/SearchAndReplace/ui/*.ui) \
$$files(sources/NameList/ui/*.ui) $$files(sources/NameList/ui/*.ui) \
$$files(sources/qetgraphicsitem/ViewItem/ui/*.ui)
UI_SOURCES_DIR = sources/ui/ UI_SOURCES_DIR = sources/ui/
UI_HEADERS_DIR = sources/ui/ UI_HEADERS_DIR = sources/ui/

View File

@@ -59,8 +59,8 @@ void QetGraphicsHandlerItem::setColor(QColor color)
*/ */
void QetGraphicsHandlerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) void QetGraphicsHandlerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{ {
Q_UNUSED(option); Q_UNUSED(option)
Q_UNUSED(widget); Q_UNUSED(widget)
painter->save(); painter->save();
painter->setBrush(QBrush(m_color)); painter->setBrush(QBrush(m_color));

View File

@@ -49,6 +49,7 @@
#include "dialogwaiting.h" #include "dialogwaiting.h"
#include "addelementtextcommand.h" #include "addelementtextcommand.h"
#include "conductornumexport.h" #include "conductornumexport.h"
#include "qetgraphicstableitem.h"
#include <QMessageBox> #include <QMessageBox>
#include <QStandardPaths> #include <QStandardPaths>
@@ -400,6 +401,14 @@ void QETDiagramEditor::setUpActions()
bom.exec(); bom.exec();
}); });
//Add a nomenclature item
m_add_nomenclature = new QAction(QET::Icons::TableOfContent, tr("Ajouter un tableau lambda (Fonctionnalité en cours de devellopement)"),this);
connect(m_add_nomenclature, &QAction::triggered, [this]() {
if(this->currentDiagramView()) {
this->currentDiagramView()->diagram()->addItem(new QetGraphicsTableItem());
}
});
//Lauch the plugin of terminal generator //Lauch the plugin of terminal generator
m_project_terminalBloc = new QAction(QET::Icons::TerminalStrip, tr("Lancer le plugin de création de borniers"), this); m_project_terminalBloc = new QAction(QET::Icons::TerminalStrip, tr("Lancer le plugin de création de borniers"), this);
connect(m_project_terminalBloc, &QAction::triggered, this, &QETDiagramEditor::generateTerminalBlock); connect(m_project_terminalBloc, &QAction::triggered, this, &QETDiagramEditor::generateTerminalBlock);
@@ -755,6 +764,7 @@ void QETDiagramEditor::setUpMenu() {
menu_project -> addAction(m_clean_project); menu_project -> addAction(m_clean_project);
menu_project -> addSeparator(); menu_project -> addSeparator();
menu_project -> addAction(m_project_folio_list); menu_project -> addAction(m_project_folio_list);
menu_project -> addAction(m_add_nomenclature);
menu_project -> addAction(m_csv_export); menu_project -> addAction(m_csv_export);
menu_project -> addAction(m_project_export_conductor_num); menu_project -> addAction(m_project_export_conductor_num);
menu_project -> addAction(m_project_terminalBloc); menu_project -> addAction(m_project_terminalBloc);
@@ -1438,7 +1448,8 @@ void QETDiagramEditor::slot_updateActions()
m_project_add_diagram -> setEnabled(editable_project); m_project_add_diagram -> setEnabled(editable_project);
m_remove_diagram_from_project -> setEnabled(editable_project); m_remove_diagram_from_project -> setEnabled(editable_project);
m_clean_project -> setEnabled(editable_project); m_clean_project -> setEnabled(editable_project);
m_project_folio_list -> setEnabled(opened_project); m_project_folio_list -> setEnabled(editable_project);
m_add_nomenclature->setEnabled(editable_project);
m_csv_export -> setEnabled(editable_project); m_csv_export -> setEnabled(editable_project);
m_export_diagram -> setEnabled(opened_diagram); m_export_diagram -> setEnabled(opened_diagram);
m_print -> setEnabled(opened_diagram); m_print -> setEnabled(opened_diagram);

View File

@@ -184,6 +184,7 @@ class QETDiagramEditor : public QETMainWindow
QAction *m_clean_project; ///< Clean the content of the curent project by removing useless items QAction *m_clean_project; ///< Clean the content of the curent project by removing useless items
QAction *m_project_folio_list; ///< Sommaire des schemas QAction *m_project_folio_list; ///< Sommaire des schemas
QAction *m_csv_export; ///< generate nomenclature QAction *m_csv_export; ///< generate nomenclature
QAction *m_add_nomenclature; ///< Add nomenclature graphics item;
QAction *m_project_terminalBloc; ///< generate terminal block QAction *m_project_terminalBloc; ///< generate terminal block
QAction *m_project_export_conductor_num; ///<Export the wire num to csv QAction *m_project_export_conductor_num; ///<Export the wire num to csv
QAction *m_tile_window; ///< Show MDI subwindows as tile QAction *m_tile_window; ///< Show MDI subwindows as tile

View File

@@ -0,0 +1,266 @@
/*
Copyright 2006-2019 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 "qetgraphicsheaderitem.h"
#include "qabstractitemmodel.h"
#include <QFontMetrics>
#include <QPainter>
/**
* @brief QetGraphicsHeaderItem::QetGraphicsHeaderItem
* @param parent
*/
QetGraphicsHeaderItem::QetGraphicsHeaderItem(QGraphicsItem *parent) :
QGraphicsObject(parent)
{
m_margin = QMargins(5,5,5,5);
}
/**
* @brief QetGraphicsHeaderItem::setModel
* Set the model presented by this item
* Since QetGraphicsHeaderItem don't take ownership of model,
* if item already have a model, it's your responsability to delete it.
* @param model
*/
void QetGraphicsHeaderItem::setModel(QAbstractItemModel *model)
{
if (m_model) {
disconnect(m_model, &QAbstractItemModel::headerDataChanged, this, &QetGraphicsHeaderItem::headerDataChanged);
}
m_model = model;
connect(m_model, &QAbstractItemModel::headerDataChanged, this, &QetGraphicsHeaderItem::headerDataChanged);
setUpMinimumSectionsSize();
m_current_sections_width.clear();
m_current_sections_width.resize(m_sections_minimum_width.size());
adjustSize();
}
/**
* @brief QetGraphicsHeaderItem::model
* @return the model that this item is presenting
*/
QAbstractItemModel *QetGraphicsHeaderItem::model() const {
return m_model;
}
/**
* @brief QetGraphicsHeaderItem::boundingRect
* Reimplemented from QGraphicsObject::boundingRect() const;
* @return
*/
QRectF QetGraphicsHeaderItem::boundingRect() const {
return m_bounding_rect;
}
/**
* @brief QetGraphicsHeaderItem::paint
* Reimplemented from QGraphicsObject::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) const;
* @param painter
* @param option
* @param widget
*/
void QetGraphicsHeaderItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED(option)
Q_UNUSED(widget)
painter->save();
QPen pen;
pen.setWidthF(0.7);
pen.setColor(Qt::black);
QBrush brush = painter->brush();
brush.setColor(Qt::lightGray);
brush.setStyle(Qt::SolidPattern);
painter->setBrush(brush);
painter->setPen(pen);
painter->setFont(m_model->headerData(0, Qt::Horizontal, Qt::FontRole).value<QFont>());
painter->drawRect(m_current_rect);
if (!m_model)
{
painter->restore();
return;
}
//Draw vertical lines
auto offset= 0;
for(auto size : m_current_sections_width)
{
QPointF p1(offset+size, m_current_rect.top());
QPointF p2(offset+size, m_current_rect.bottom());
painter->drawLine(p1, p2);
offset += size;
}
//Write text of each cell
QPointF top_left(m_margin.left(), m_margin.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());
painter->drawText(QRectF(top_left, size),
m_model->headerData(0, Qt::Horizontal, Qt::TextAlignmentRole).toInt(),
m_model->headerData(i, Qt::Horizontal).toString());
top_left.setX(top_left.x() + m_current_sections_width.at(i));
}
painter->restore();
}
/**
* @brief QetGraphicsHeaderItem::rect
* @return the current rect of the item aka the size of rectangle painted.
*/
QRect QetGraphicsHeaderItem::rect() const {
return m_current_rect;
}
/**
* @brief QetGraphicsHeaderItem::resizeSection
* @param logicalIndex
* @param size
*/
void QetGraphicsHeaderItem::resizeSection(int logicalIndex, int size)
{
if (logicalIndex >= m_current_sections_width.size() ||
m_current_sections_width.at(logicalIndex) == size) {
return;
}
if (m_model &&
logicalIndex<m_model->columnCount() &&
size >= m_sections_minimum_width.at(logicalIndex))
{
prepareGeometryChange();
m_current_sections_width.replace(logicalIndex, size);
m_current_rect.setWidth(std::accumulate(m_current_sections_width.begin(), m_current_sections_width.end(), 0));
setUpBoundingRect();
update();
emit sectionResized(logicalIndex, size);
}
}
/**
* @brief QetGraphicsHeaderItem::sectionSize
* @param logical_index
* @return the width (or height for vertical headers) of the given logicalIndex.
*/
int QetGraphicsHeaderItem::sectionSize(int logical_index) const
{
if (logical_index>=0 && logical_index<m_current_sections_width.size()) {
return m_current_sections_width.at(logical_index);
} else {
return -1;
}
}
/**
* @brief QetGraphicsHeaderItem::setMargins
* @param margins
*/
void QetGraphicsHeaderItem::setMargins(const QMargins &margins)
{
m_margin = margins;
headerDataChanged(Qt::Horizontal, 0,1);
}
/**
* @brief QetGraphicsHeaderItem::setUpMinimumSectionsSize
* Setup the minimum section size and height of the item.
* Not that this function doesn't change the current size of this item.
*/
void QetGraphicsHeaderItem::setUpMinimumSectionsSize()
{
if (!m_model) {
return;
}
QFontMetrics metrics(m_model->headerData(0, Qt::Horizontal, Qt::FontRole).value<QFont>());
//Set the height of row;
m_minimum_section_height = metrics.boundingRect("HEIGHT TEST").height() + m_margin.top() + m_margin.bottom();
m_sections_minimum_width.clear();
m_sections_minimum_width.resize(m_model->columnCount());
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_minimum_width = std::accumulate(m_sections_minimum_width.begin(), m_sections_minimum_width.end(), 0);
}
/**
* @brief QetGraphicsHeaderItem::setUpBoundingRect
* Setup the bounding rect of the item
*/
void QetGraphicsHeaderItem::setUpBoundingRect() {
m_bounding_rect = m_current_rect.adjusted(-10, -10, 10, 10);
}
/**
* @brief QetGraphicsHeaderItem::headerDataChanged
* Update the header when data of displayed model change
* @param orientation
* @param first
* @param last
*/
void QetGraphicsHeaderItem::headerDataChanged(Qt::Orientations orientation, int first, int last)
{
Q_UNUSED(orientation)
Q_UNUSED(first)
Q_UNUSED(last)
setUpMinimumSectionsSize();
adjustSize();
}
/**
* @brief QetGraphicsHeaderItem::adjustSize
* If needed, this function resize the current height and section
* according to there minimum
*/
void QetGraphicsHeaderItem::adjustSize()
{
if (m_section_height != m_minimum_section_height)
{
m_section_height = m_minimum_section_height;
m_current_rect.setHeight(m_section_height);
emit heightResized();
}
if(m_current_sections_width.size() == m_sections_minimum_width.size())
{
auto old_sections_width = m_current_sections_width;
for (int i=0 ; i<m_current_sections_width.size() ; ++i)
{
if (old_sections_width.at(i) < m_sections_minimum_width.at(i)) {
resizeSection(i, m_sections_minimum_width.at(i));
}
}
}
update();
}

View File

@@ -0,0 +1,84 @@
/*
Copyright 2006-2019 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 QETGRAPHICSHEADERITEM_H
#define QETGRAPHICSHEADERITEM_H
#include "qetapp.h"
#include <QGraphicsObject>
#include <QFont>
#include <QMargins>
class QAbstractItemModel;
/**
* @brief The QetGraphicsHeaderItem class
* The header have a few parameters to edit her visual aspect.
* 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.
*/
class QetGraphicsHeaderItem : public QGraphicsObject
{
Q_OBJECT
Q_PROPERTY(QMargins margins READ margins WRITE setMargins)
public:
QetGraphicsHeaderItem(QGraphicsItem *parent = nullptr);
enum { Type = UserType + 1301 };
int type() const override { return Type; }
void setModel(QAbstractItemModel *model);
QAbstractItemModel *model() const;
virtual QRectF boundingRect() const override;
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
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;}
signals:
void sectionResized(int logicalIndex, int size);
void heightResized();
private:
void setUpMinimumSectionsSize();
void setUpBoundingRect();
void headerDataChanged(Qt::Orientations orientation, int first, int last);
void adjustSize();
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,
m_minimum_section_height=1;
int m_minimum_width=1;
QRect m_current_rect;
};
#endif // QETGRAPHICSHEADERITEM_H

View File

@@ -0,0 +1,459 @@
/*
Copyright 2006-2020 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 "qetgraphicstableitem.h"
#include "diagram.h"
#include "qetgraphicsheaderitem.h"
#include "QPropertyUndoCommand/qpropertyundocommand.h"
#include <QAbstractItemModel>
#include <QFontMetrics>
#include <QPainter>
#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
/**
* @brief QetGraphicsTableItem::QetGraphicsTableItem
* Default constructor
* @param parent
*/
QetGraphicsTableItem::QetGraphicsTableItem(QGraphicsItem *parent) :
QetGraphicsItem(parent)
{
setFlag(QGraphicsItem::ItemIsMovable, true);
setFlag(QGraphicsItem::ItemIsSelectable, true);
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);
connect(this, &QetGraphicsTableItem::xChanged, this, &QetGraphicsTableItem::adjustHandlerPos);
connect(this, &QetGraphicsTableItem::yChanged, this, &QetGraphicsTableItem::adjustHandlerPos);
m_header_item = new QetGraphicsHeaderItem(this);
connect(m_header_item, &QetGraphicsHeaderItem::sectionResized, this, &QetGraphicsTableItem::headerSectionResized);
connect(m_header_item, &QetGraphicsHeaderItem::heightResized, this, [this]() {
m_header_item->setPos(0, 0-m_header_item->rect().height());
});
/*******ONLY FOR TEST DURING DEVEL*********/
auto model = new QStandardItemModel(this);
int r = 20;
int c = 5;
for (int row = 0; row < r; ++row)
{
for (int column = 0; column < c; ++column) {
QStandardItem *item = new QStandardItem(QString("row %0, column %1").arg(row).arg(column));
model->setItem(row, column, item);
}
}
model->setData(model->index(0,0), Qt::AlignLeft, Qt::TextAlignmentRole);
model->setData(model->index(0,0), QETApp::diagramTextsFont(), Qt::FontRole);
model->setHeaderData(0, Qt::Horizontal, Qt::AlignHCenter, Qt::TextAlignmentRole);
model->setHeaderData(0, Qt::Horizontal, QETApp::diagramTextsFont(), Qt::FontRole);
model->setHeaderData(0, Qt::Horizontal, "Label");
model->setHeaderData(1, Qt::Horizontal, "Folio");
model->setHeaderData(2, Qt::Horizontal, "Fonction");
model->setHeaderData(3, Qt::Horizontal, "Fabricant");
model->setHeaderData(4, Qt::Horizontal, "Installation");
this->setModel(model);
this->setPos(50,50);
/******************************************/
}
QetGraphicsTableItem::~QetGraphicsTableItem()
{}
/**
* @brief QetGraphicsTableItem::setModel
* Set the model presented by this item.
* Since QetGraphicsTableItem don't take ownership of model,
* if item already have a model, it's your responsibility to delete it.
* @param model
*/
void QetGraphicsTableItem::setModel(QAbstractItemModel *model)
{
if (m_model) {
disconnect(m_model, &QAbstractItemModel::dataChanged, this, &QetGraphicsTableItem::dataChanged);
}
m_model = model;
m_header_item->setModel(model);
setUpColumnAndRowMinimumSize();
adjustSize();
m_header_item->setPos(0, -m_header_item->rect().height());
connect(m_model, &QAbstractItemModel::dataChanged, this, &QetGraphicsTableItem::dataChanged);
}
/**
* @brief QetGraphicsTableItem::model
* @return The model that this item is presenting
*/
QAbstractItemModel *QetGraphicsTableItem::model() const {
return m_model;
}
/**
* @brief QetGraphicsTableItem::boundingRect
* Reimplemented from QGraphicsObject
* @return
*/
QRectF QetGraphicsTableItem::boundingRect() const {
return m_bounding_rect;
}
/**
* @brief QetGraphicsTableItem::paint
* Draw the table
* @param painter
* @param option
* @param widget
*/
void QetGraphicsTableItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED(option)
Q_UNUSED(widget)
painter->save();
QPen pen;
pen.setWidthF(0.7);
pen.setColor(Qt::black);
painter->setPen(pen);
painter->setFont(m_model->data(model()->index(0,0), Qt::FontRole).value<QFont>());
painter->drawRect(0,0, m_header_item->rect().width(), m_current_size.height());
if(!m_model)
{
painter->restore();
return;
}
//Draw vertical lines
auto offset= 0;
for(auto i=0 ; i<m_model->columnCount() ; ++i)
{
QPointF p1(offset+m_header_item->sectionSize(i), 0);
QPointF p2(offset+m_header_item->sectionSize(i), m_current_size.height());
painter->drawLine(p1, p2);
offset += m_header_item->sectionSize(i);
}
//Draw horizontal lines
auto cell_height = static_cast<double>(m_current_size.height())/static_cast<double>(m_model->rowCount());
for(auto i= 1 ; i-1<m_model->rowCount() ; ++i)
{
QPointF p1(m_header_item->rect().left(), cell_height*i);
QPointF p2(m_header_item->rect().right(), cell_height*i);
painter->drawLine(p1, p2);
}
//Write text of each cell
for (auto i= 0 ; i<m_model->rowCount() ; ++i)
{
QPointF top_left(m_margin.left(), i==0? m_margin.top() : cell_height*i + m_margin.top());
for(auto j= 0 ; j<m_model->columnCount() ; ++j)
{
//In first iteration the top left X is margin left, in all other iteration the top left X is stored in m_column_size
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());
painter->drawText(QRectF(top_left, size),
m_model->data(m_model->index(0,0), Qt::TextAlignmentRole).toInt(),
m_model->index(i, j).data().toString());
}
}
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
* @param size
*/
void QetGraphicsTableItem::setSize(const QSize &size)
{
auto new_size = size;
if (new_size.width() < minimumSize().width()) {
new_size.setWidth(minimumSize().width());
}
if (new_size.height() < minimumSize().height()) {
new_size.setHeight(minimumSize().height());
}
prepareGeometryChange();
m_current_size = new_size;
adjustColumnsWidth();
setUpBoundingRect();
}
/**
* @brief QetGraphicsTableItem::size
* @return The current size of the table
*/
QSize QetGraphicsTableItem::size() const
{
QSize size_(m_header_item->rect().width(), m_current_size.height());
return size_;
}
/**
* @brief QetGraphicsTableItem::minimumSize
* @return the minimum size the table can be
* The returned size take care of the table's minimum width, but also the header item's minimum width
*/
QSize QetGraphicsTableItem::minimumSize() const
{
QSize s(std::accumulate(m_minimum_column_width.begin(), m_minimum_column_width.end(), 0), m_minimum_row_height*m_model->rowCount());
return s;
}
/**
* @brief QetGraphicsTableItem::hoverEnterEvent
* Reimplemented from QetGraphicsItem
* @param event
*/
void QetGraphicsTableItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
adjustHandlerPos();
this->scene()->addItem(&m_handler_item);
m_handler_item.installSceneEventFilter(this);
QGraphicsObject::hoverEnterEvent(event);
}
/**
* @brief QetGraphicsTableItem::hoverLeaveEvent
* Reimplemented from QetGraphicsItem
* @param event
*/
void QetGraphicsTableItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
m_handler_item.scene()->removeItem(&m_handler_item);
QGraphicsObject::hoverLeaveEvent(event);
}
/**
* @brief QetGraphicsTableItem::sceneEventFilter
* Reimplemented from QetGraphicsItem
* @param watched
* @param event
* @return
*/
bool QetGraphicsTableItem::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
{
if (watched == &m_handler_item)
{
if(event->type() == QEvent::GraphicsSceneMousePress) //Click
{
handlerMousePressEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
return true;
}
else if(event->type() == QEvent::GraphicsSceneMouseMove) //Move
{
handlerMouseMoveEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
return true;
}
else if (event->type() == QEvent::GraphicsSceneMouseRelease) //Release
{
handlerMouseReleaseEvent(static_cast<QGraphicsSceneMouseEvent *>(event));
return true;
}
}
return false;
}
/**
* @brief QetGraphicsTableItem::setUpColumnAndRowMinimumSize
* Calcule the minimum row height and the minimum column width for each columns
* this function doesn't change the geometry of the table.
*/
void QetGraphicsTableItem::setUpColumnAndRowMinimumSize()
{
if (!m_model) {
return;
}
QFontMetrics metrics(m_model->data(model()->index(0,0), Qt::FontRole).value<QFont>());
//Set the height of row;
m_minimum_row_height = metrics.boundingRect("HEIGHT TEST").height() + m_margin.top() + m_margin.bottom();
m_minimum_column_width = m_header_item->minimumSectionWidth();
//Get the maximum width of each columns
for (auto row= 0 ; row<m_model->rowCount() ; ++row)
{
for(auto col= 0 ; col<m_model->columnCount() ; ++col)
{
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()));
}
}
}
/**
* @brief QetGraphicsTableItem::setUpBoundingRect
*/
void QetGraphicsTableItem::setUpBoundingRect()
{
QSize header_size = m_header_item->rect().size();
QRect rect(0, -header_size.height(), header_size.width(), m_current_size.height() + header_size.height());
m_bounding_rect = rect.adjusted(-m_br_margin, -m_br_margin, m_br_margin, m_br_margin);
}
/**
* @brief QetGraphicsTableItem::adjustHandlerPos
* Adjust the pos of the handler item
*/
void QetGraphicsTableItem::adjustHandlerPos() {
m_handler_item.setPos(mapToScene(QRect(QPoint(0,0), size()).bottomRight()));
}
/**
* @brief QetGraphicsTableItem::setUpHandler
*/
void QetGraphicsTableItem::setUpHandler()
{
m_handler_item.setColor(Qt::blue);
m_handler_item.setZValue(this->zValue() + 1);
}
void QetGraphicsTableItem::handlerMousePressEvent(QGraphicsSceneMouseEvent *event)
{
Q_UNUSED(event)
m_old_size = size();
//User start to resize the table, disconnect the signal to avoid double paint.
disconnect(m_header_item, &QetGraphicsHeaderItem::sectionResized, this, &QetGraphicsTableItem::headerSectionResized);
}
void QetGraphicsTableItem::handlerMouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
auto new_handler_pos = Diagram::snapToGrid(event->scenePos());
QSize size_ = QRectF(QPointF(0,0), mapFromScene(new_handler_pos)).size().toSize();
QPoint new_pos(std::max(minimumSize().width(), size_.width()),
std::max(minimumSize().height(), size_.height()));
m_handler_item.setPos(mapToScene(new_pos));
QSize new_size(new_pos.x(), new_pos.y());
if (new_size != size()) {
setSize(new_size);
}
}
void QetGraphicsTableItem::handlerMouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
Q_UNUSED(event)
if (diagram())
{
auto undo = new QPropertyUndoCommand(this, "size", m_old_size, size());
undo->setAnimated();
undo->setText(tr("Modifier la géometrie d'un tableau"));
diagram()->undoStack().push(undo);
}
//User finish to resize the table, we can reconnect now
connect(m_header_item, &QetGraphicsHeaderItem::sectionResized, this, &QetGraphicsTableItem::headerSectionResized);
}
/**
* @brief QetGraphicsTableItem::adjustColumnsWidth
* Adjust the size of each column according to the current table width by setting the sectionSize of the header item
*/
void QetGraphicsTableItem::adjustColumnsWidth()
{
auto a = m_current_size.width() - minimumSize().width();
auto b = a/m_model->columnCount();
for(auto i= 0 ; i<m_model->columnCount() ; ++i) {
m_header_item->resizeSection(i, std::max(m_minimum_column_width.at(i), m_header_item->minimumSectionWidth().at(i)) + b);
}
}
void QetGraphicsTableItem::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
{
Q_UNUSED(topLeft)
Q_UNUSED(bottomRight)
Q_UNUSED(roles)
auto size_ = size();
setUpColumnAndRowMinimumSize();
adjustSize();
setSize(size_);
}
/**
* @brief QetGraphicsTableItem::headerSectionResized
* Connected to the header signal QetGraphicsTableItem sectionResized
*/
void QetGraphicsTableItem::headerSectionResized()
{
auto header_size = m_header_item->rect().size();
auto size_ = size();
size_.setWidth(header_size.width());
m_current_size = size_;
prepareGeometryChange();
setUpBoundingRect();
}
/**
* @brief QetGraphicsTableItem::adjustSize
* If needed, this function resize the current height and width of table
* according to there minimum
*/
void QetGraphicsTableItem::adjustSize()
{
if (m_current_size.height() < minimumSize().height())
{
prepareGeometryChange();
m_current_size.setHeight(minimumSize().height());
setUpBoundingRect();
update();
}
if (m_current_size.width() < minimumSize().width())
{
prepareGeometryChange();
m_current_size.setWidth(minimumSize().width());
adjustColumnsWidth();
setUpBoundingRect();
update();
}
}

View File

@@ -0,0 +1,100 @@
/*
Copyright 2006-2020 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 QetGraphicsTableItem_H
#define QetGraphicsTableItem_H
#include <QFont>
#include "qetgraphicsitem.h"
#include "qetapp.h"
#include "QetGraphicsItemModeler/qetgraphicshandleritem.h"
class QAbstractItemModel;
class QetGraphicsHeaderItem;
/**
* @brief The QetGraphicsTableItem class
* This item display a table destined to represent the content of a QAbstractItemModel
* The table have a few parameters to edit her visual aspect.
* 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.
*/
class QetGraphicsTableItem : public QetGraphicsItem
{
Q_OBJECT
Q_PROPERTY(QMargins margins READ margins WRITE setMargins)
Q_PROPERTY(QSize size READ size WRITE setSize)
public:
QetGraphicsTableItem(QGraphicsItem *parent= nullptr);
virtual ~QetGraphicsTableItem() override;
enum { Type = UserType + 1300 };
int type() const override { return Type; }
void setModel(QAbstractItemModel *model);
QAbstractItemModel *model() const;
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;
QSize minimumSize() const;
protected:
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override;
virtual bool sceneEventFilter(QGraphicsItem *watched, QEvent *event) override;
private:
void modelReseted();
void setUpColumnAndRowMinimumSize();
void setUpBoundingRect();
void adjustHandlerPos();
void setUpHandler();
void handlerMousePressEvent (QGraphicsSceneMouseEvent *event);
void handlerMouseMoveEvent (QGraphicsSceneMouseEvent *event);
void handlerMouseReleaseEvent (QGraphicsSceneMouseEvent *event);
void adjustColumnsWidth();
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles);
void headerSectionResized();
void adjustSize();
private:
QAbstractItemModel *m_model= nullptr;
QMargins m_margin;
QVector<int> m_minimum_column_width;
int m_minimum_row_height;
QSize m_current_size,
m_old_size;
int m_br_margin= 10;
QRectF m_bounding_rect;
QetGraphicsHandlerItem m_handler_item;
QetGraphicsHeaderItem *m_header_item = nullptr;
};
#endif // QetGraphicsTableItem_H

View File

@@ -0,0 +1,284 @@
/*
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 "graphicstablepropertieseditor.h"
#include "ui_graphicstablepropertieseditor.h"
#include "qetgraphicstableitem.h"
#include "qetgraphicsheaderitem.h"
#include "diagram.h"
#include "QPropertyUndoCommand/qpropertyundocommand.h"
#include "itemmodelcommand.h"
#include <QAbstractItemModel>
#include <QFontDialog>
/**
* @brief GraphicsTablePropertiesEditor::GraphicsTablePropertiesEditor
* @param table
* @param parent
*/
GraphicsTablePropertiesEditor::GraphicsTablePropertiesEditor(QetGraphicsTableItem *table, QWidget *parent) :
PropertiesEditorWidget(parent),
ui(new Ui::GraphicsTablePropertiesEditor)
{
ui->setupUi(this);
m_header_button_group = new QButtonGroup(this);
m_header_button_group->addButton(ui->m_header_align_left_rb, Qt::AlignLeft);
m_header_button_group->addButton(ui->m_header_align_center_rb, Qt::AlignHCenter);
m_header_button_group->addButton(ui->m_header_align_right_rb, Qt::AlignRight);
m_table_button_group = new QButtonGroup(this);
m_table_button_group->addButton(ui->m_table_align_left_rb, Qt::AlignLeft);
m_table_button_group->addButton(ui->m_table_align_center_rb, Qt::AlignHCenter);
m_table_button_group->addButton(ui->m_table_align_right_rb, Qt::AlignRight);
if (table) {
setTable(table);
}
}
/**
* @brief GraphicsTablePropertiesEditor::~GraphicsTablePropertiesEditor
*/
GraphicsTablePropertiesEditor::~GraphicsTablePropertiesEditor() {
delete ui;
}
/**
* @brief GraphicsTablePropertiesEditor::setTable
* Set the table to be edited
* @param table
*/
void GraphicsTablePropertiesEditor::setTable(QetGraphicsTableItem *table)
{
if (m_table_item) {
for (auto c : m_connect_list) {
disconnect(c);
}
}
m_table_item = table;
m_connect_list.clear();
m_connect_list << connect(m_table_item.data(), &QetGraphicsTableItem::xChanged, this, &GraphicsTablePropertiesEditor::updateUi);
m_connect_list << connect(m_table_item.data(), &QetGraphicsTableItem::yChanged, this, &GraphicsTablePropertiesEditor::updateUi);
updateUi();
}
/**
* @brief GraphicsTablePropertiesEditor::apply
* Apply the current edition
*/
void GraphicsTablePropertiesEditor::apply()
{
if(!m_table_item && m_table_item->diagram()) {
return;
}
auto d = m_table_item->diagram();
auto undo = associatedUndo();
if (undo) {
d->undoStack().push(undo);
}
}
/**
* @brief GraphicsTablePropertiesEditor::associatedUndo
* @return the undo command associated to the edition
*/
QUndoCommand *GraphicsTablePropertiesEditor::associatedUndo() const
{
if (m_live_edit)
{
if (!qFuzzyCompare(ui->m_x_pos->value(), m_table_item->pos().x())) {
auto undo = new QPropertyUndoCommand(m_table_item.data(), "x", m_table_item->pos().x(), ui->m_x_pos->value());
undo->setAnimated(true, false);
undo->setText(tr("Déplacer un tableau"));
return undo;
}
if (!qFuzzyCompare(ui->m_y_pos->value(), m_table_item->pos().y())) {
auto undo = new QPropertyUndoCommand(m_table_item.data(), "y", m_table_item->pos().y(), ui->m_y_pos->value());
undo->setAnimated(true, false);
undo->setText(tr("Déplacer un tableau"));
return undo;
}
QMargins 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())
{
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_);
undo->setText(tr("Modifier les marges d'une en tête de tableau"));
return undo;
}
QMargins 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())
{
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_);
undo->setText(tr("Modifier les marges d'un tableau"));
return undo;
}
if (m_header_button_group->checkedId() != m_table_item->model()->headerData(0, Qt::Horizontal, Qt::TextAlignmentRole).toInt())
{
auto undo = new ModelHeaderDataCommand(m_table_item->model());
undo->setData(0, Qt::Horizontal, m_header_button_group->checkedId(), Qt::TextAlignmentRole);
undo->setText(tr("Modifier l'alignement d'une en tête de tableau"));
return undo;
}
if (m_table_button_group->checkedId() != m_table_item->model()->index(0,0).data(Qt::TextAlignmentRole).toInt())
{
auto undo = new ModelIndexCommand(m_table_item->model(), m_table_item->model()->index(0,0));
undo->setData(m_table_button_group->checkedId(), Qt::TextAlignmentRole);
undo->setText(tr("Modifier l'alignement des textes d'un tableau"));
return undo;
}
}
return nullptr;
}
bool GraphicsTablePropertiesEditor::setLiveEdit(bool live_edit)
{
if (m_live_edit == live_edit) {
return true;
}
m_live_edit = live_edit;
setUpEditConnection();
return true;
}
/**
* @brief GraphicsTablePropertiesEditor::on_m_header_font_pb_clicked
*/
void GraphicsTablePropertiesEditor::on_m_header_font_pb_clicked()
{
if (m_table_item && m_table_item->model())
{
bool ok;
auto font = QFontDialog::getFont(&ok,
m_table_item->model()->headerData(0, Qt::Horizontal, Qt::FontRole).value<QFont>(),
this);
if (ok && m_table_item->model())
{
auto undo = new ModelHeaderDataCommand(m_table_item->model());
undo->setData(0, Qt::Horizontal, QVariant::fromValue(font), Qt::FontRole);
undo->setText(tr("Modifier la police d'une en tête de tableau"));
m_table_item->diagram()->undoStack().push(undo);
}
}
}
/**
* @brief GraphicsTablePropertiesEditor::on_m_table_font_pb_clicked
*/
void GraphicsTablePropertiesEditor::on_m_table_font_pb_clicked()
{
if (m_table_item && m_table_item->model())
{
bool ok;
auto index = m_table_item->model()->index(0,0);
auto old_font = m_table_item->model()->data(index, Qt::FontRole).value<QFont>();
auto new_font = QFontDialog::getFont(&ok, old_font, this);
if (ok && m_table_item->diagram())
{
auto undo = new ModelIndexCommand(m_table_item->model(), index);
undo->setData(QVariant::fromValue(new_font), Qt::FontRole);
undo->setText(tr("Changer la police d'un tableau"));
m_table_item->diagram()->undoStack().push(undo);
}
}
}
/**
* @brief GraphicsTablePropertiesEditor::updateUi
*/
void GraphicsTablePropertiesEditor::updateUi()
{
//Disconnect every connections of editor widgets
//to avoid an unwanted edition (QSpinBox emit valueChanged no matter if changer by user or by program)
for (QMetaObject::Connection c : m_edit_connection) {
disconnect(c);
}
m_edit_connection.clear();
ui->m_x_pos->setValue(m_table_item->pos().x());
ui->m_y_pos->setValue(m_table_item->pos().y());
auto margin = m_table_item->headerItem()->margins();
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();
ui->m_table_top_margin ->setValue(margin.top());
ui->m_table_left_margin ->setValue(margin.left());
ui->m_table_right_margin ->setValue(margin.right());
ui->m_table_bottom_margin->setValue(margin.bottom());
if (!m_table_item->model()) {
return;
}
m_header_button_group->button(m_table_item->model()->headerData(0, Qt::Horizontal, Qt::TextAlignmentRole).toInt())->setChecked(true);
m_table_button_group->button(m_table_item->model()->data(m_table_item->model()->index(0,0), Qt::TextAlignmentRole).toInt())->setChecked(true);
setUpEditConnection();
}
/**
* @brief GraphicsTablePropertiesEditor::setUpEditConnection
*/
void GraphicsTablePropertiesEditor::setUpEditConnection()
{
for (QMetaObject::Connection c : m_edit_connection) {
disconnect(c);
}
m_edit_connection.clear();
if (m_live_edit)
{
m_edit_connection << connect(ui->m_x_pos, QOverload<int>::of(&QSpinBox::valueChanged), this, &GraphicsTablePropertiesEditor::apply);
m_edit_connection << connect(ui->m_y_pos, QOverload<int>::of(&QSpinBox::valueChanged), this, &GraphicsTablePropertiesEditor::apply);
m_edit_connection << connect(ui->m_header_top_margin, QOverload<int>::of(&QSpinBox::valueChanged), this, &GraphicsTablePropertiesEditor::apply);
m_edit_connection << connect(ui->m_header_left_margin, QOverload<int>::of(&QSpinBox::valueChanged), this, &GraphicsTablePropertiesEditor::apply);
m_edit_connection << connect(ui->m_header_right_margin, QOverload<int>::of(&QSpinBox::valueChanged), this, &GraphicsTablePropertiesEditor::apply);
m_edit_connection << connect(ui->m_header_bottom_margin, QOverload<int>::of(&QSpinBox::valueChanged), this, &GraphicsTablePropertiesEditor::apply);
m_edit_connection << connect(ui->m_table_top_margin, QOverload<int>::of(&QSpinBox::valueChanged), this, &GraphicsTablePropertiesEditor::apply);
m_edit_connection << connect(ui->m_table_left_margin, QOverload<int>::of(&QSpinBox::valueChanged), this, &GraphicsTablePropertiesEditor::apply);
m_edit_connection << connect(ui->m_table_right_margin, QOverload<int>::of(&QSpinBox::valueChanged), this, &GraphicsTablePropertiesEditor::apply);
m_edit_connection << connect(ui->m_table_bottom_margin, QOverload<int>::of(&QSpinBox::valueChanged), this, &GraphicsTablePropertiesEditor::apply);
m_edit_connection << connect(m_table_button_group, QOverload<int>::of(&QButtonGroup::buttonClicked), this, &GraphicsTablePropertiesEditor::apply);
m_edit_connection << connect(m_header_button_group, QOverload<int>::of(&QButtonGroup::buttonClicked), this, &GraphicsTablePropertiesEditor::apply);
}
}

View File

@@ -0,0 +1,69 @@
/*
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 GRAPHICSTABLEPROPERTIESEDITOR_H
#define GRAPHICSTABLEPROPERTIESEDITOR_H
#include "PropertiesEditor/propertieseditorwidget.h"
#include <QPointer>
namespace Ui {
class GraphicsTablePropertiesEditor;
}
class QetGraphicsTableItem;
class QAbstractItemModel;
class QUndoStack;
class QButtonGroup;
/**
* @brief The GraphicsTablePropertiesEditor class
* This widget is used to edit the property of both QetGraphicsTableItem and QetGraphicsHeaderItem
*/
class GraphicsTablePropertiesEditor : public PropertiesEditorWidget
{
Q_OBJECT
public:
explicit GraphicsTablePropertiesEditor(QetGraphicsTableItem *table = nullptr, QWidget *parent = nullptr);
~GraphicsTablePropertiesEditor() override;
void setTable(QetGraphicsTableItem *table);
virtual void apply() override;
QUndoCommand * associatedUndo() const override;
virtual bool setLiveEdit(bool live_edit) override;
private slots:
void on_m_header_font_pb_clicked();
void on_m_table_font_pb_clicked();
virtual void updateUi() override;
private:
void setUpEditConnection();
private:
Ui::GraphicsTablePropertiesEditor *ui;
QPointer<QetGraphicsTableItem> m_table_item;
QList <QMetaObject::Connection> m_connect_list,
m_edit_connection;
QButtonGroup *m_header_button_group = nullptr,
*m_table_button_group = nullptr;
};
Q_DECLARE_METATYPE(QMargins)
#endif // GRAPHICSTABLEPROPERTIESEDITOR_H

View File

@@ -0,0 +1,253 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GraphicsTablePropertiesEditor</class>
<widget class="QWidget" name="GraphicsTablePropertiesEditor">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>331</width>
<height>484</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Position</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_8">
<property name="text">
<string>X :</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="m_x_pos">
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>Y :</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="m_y_pos">
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>En tête</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="1">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Marge</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QSpinBox" name="m_header_left_margin"/>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="m_header_bottom_margin"/>
</item>
<item row="2" column="2">
<widget class="QSpinBox" name="m_header_right_margin"/>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="m_header_top_margin"/>
</item>
</layout>
</item>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Aligement :</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="m_header_align_left_rb">
<property name="text">
<string>Gauche</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="m_header_align_center_rb">
<property name="text">
<string>Centré</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="m_header_align_right_rb">
<property name="text">
<string>Droite</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_header_font_pb">
<property name="text">
<string>Police</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Tableau</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QGridLayout" name="gridLayout_3">
<item row="1" column="2">
<widget class="QSpinBox" name="m_table_right_margin"/>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="m_table_top_margin"/>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="m_table_bottom_margin"/>
</item>
<item row="1" column="0">
<widget class="QSpinBox" name="m_table_left_margin"/>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Marge</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QWidget" name="widget_2" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>Alignement :</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="m_table_align_left_rb">
<property name="text">
<string>Gauche</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="m_table_align_center_rb">
<property name="text">
<string>Centré</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="m_table_align_right_rb">
<property name="text">
<string>Droite</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_table_font_pb">
<property name="text">
<string>Police</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -275,9 +275,6 @@ QPainterPath QetShapeItem::shape() const
path.closeSubpath(); path.closeSubpath();
} }
break; break;
default:
Q_ASSERT(false);
break;
} }
QPainterPathStroker pps; QPainterPathStroker pps;
@@ -297,7 +294,8 @@ QPainterPath QetShapeItem::shape() const
*/ */
void QetShapeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) void QetShapeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{ {
Q_UNUSED(option); Q_UNUSED(widget); Q_UNUSED(option)
Q_UNUSED(widget)
painter->save(); painter->save();
painter->setRenderHint(QPainter::Antialiasing, true); painter->setRenderHint(QPainter::Antialiasing, true);
@@ -697,8 +695,8 @@ void QetShapeItem::removePoint()
*/ */
void QetShapeItem::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event) void QetShapeItem::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
{ {
Q_UNUSED(qghi); Q_UNUSED(qghi)
Q_UNUSED(event); Q_UNUSED(event)
m_old_P1 = m_P1; m_old_P1 = m_P1;
m_old_P2 = m_P2; m_old_P2 = m_P2;
@@ -717,7 +715,7 @@ void QetShapeItem::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphic
*/ */
void QetShapeItem::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event) void QetShapeItem::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event)
{ {
Q_UNUSED(qghi); Q_UNUSED(qghi)
QPointF new_pos = event->scenePos(); QPointF new_pos = event->scenePos();
if (event->modifiers() != Qt::ControlModifier) if (event->modifiers() != Qt::ControlModifier)

View File

@@ -27,6 +27,8 @@
#include "elementtextitemgroup.h" #include "elementtextitemgroup.h"
#include "independenttextitem.h" #include "independenttextitem.h"
#include "inditextpropertieswidget.h" #include "inditextpropertieswidget.h"
#include "qetgraphicstableitem.h"
#include "graphicstablepropertieseditor.h"
/** /**
* @brief DiagramPropertiesEditorDockWidget::DiagramPropertiesEditorDockWidget * @brief DiagramPropertiesEditorDockWidget::DiagramPropertiesEditorDockWidget
@@ -230,6 +232,20 @@ void DiagramPropertiesEditorDockWidget::selectionChanged()
} }
break; break;
} }
case QetGraphicsTableItem::Type:
{
if (count_ > 1)
{
clear();
m_edited_qgi_type = -1;
return;
}
clear();
m_edited_qgi_type = type_;
addEditor(new GraphicsTablePropertiesEditor(static_cast<QetGraphicsTableItem*>(item), this));
break;
}
default: default:
m_edited_qgi_type = -1; m_edited_qgi_type = -1;
clear(); clear();

View File

@@ -0,0 +1,120 @@
/*
Copyright 2006-2020 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 "itemmodelcommand.h"
/**
* @brief ModelIndexCommand::ModelIndexCommand
* @param model
* @param index
* @param parent
*/
ModelIndexCommand::ModelIndexCommand(QAbstractItemModel *model, const QModelIndex &index, QUndoCommand *parent):
QUndoCommand(parent),
m_model(model),
m_index(index)
{}
/**
* @brief ModelIndexCommand::setData
* @param value
* @param role
*/
void ModelIndexCommand::setData(const QVariant &value, int role)
{
m_new_value = value;
if (m_model) {
m_old_value = m_model->data(m_index, role);
} else {
m_old_value = value;
}
m_role = role;
}
/**
* @brief ModelIndexCommand::redo
* Reimplemented from QUndoCommand
*/
void ModelIndexCommand::redo() {
if (m_model && m_index.isValid()) {
m_model->setData(m_index, m_new_value, m_role);
}
}
/**
* @brief ModelIndexCommand::undo
* Reimplemented from QUndoCommand
*/
void ModelIndexCommand::undo() {
if (m_model && m_index.isValid()) {
m_model->setData(m_index, m_old_value, m_role);
}
}
/**
* @brief ModelHeaderDataCommand::ModelHeaderDataCommand
* @param model
* @param parent
*/
ModelHeaderDataCommand::ModelHeaderDataCommand(QAbstractItemModel *model, QUndoCommand *parent) :
QUndoCommand(parent),
m_model(model)
{}
/**
* @brief ModelHeaderDataCommand::setData
* See QAbstractItemModel::setHeaderData
* @param section
* @param orientation
* @param value
* @param role
*/
void ModelHeaderDataCommand::setData(int section, Qt::Orientation orientation, const QVariant &value, int role)
{
m_section = section;
m_orientation = orientation;
m_new_value = value;
if (m_model) {
m_old_value = m_model->headerData(section, orientation, role);
} else {
m_old_value = m_new_value;
}
m_role = role;
}
/**
* @brief ModelHeaderDataCommand::redo
* Reimplemented from QUndoCommand
*/
void ModelHeaderDataCommand::redo()
{
if (m_model) {
m_model->setHeaderData(m_section, m_orientation, m_new_value, m_role);
}
}
/**
* @brief ModelHeaderDataCommand::undo
* Reimplemented from QUndoCommand
*/
void ModelHeaderDataCommand::undo()
{
if (m_model) {
m_model->setHeaderData(m_section, m_orientation, m_old_value, m_role);
}
}

View File

@@ -0,0 +1,70 @@
/*
Copyright 2006-2020 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 ITEMMODELCOMMAND_H
#define ITEMMODELCOMMAND_H
#include <QUndoCommand>
#include <QModelIndex>
#include <QPointer>
class QAbstractItemModel;
/**
* @brief The ModelIndexCommand class
* Change a data of an index of QAbstractItemModel
*/
class ModelIndexCommand : public QUndoCommand
{
public:
ModelIndexCommand(QAbstractItemModel *model, const QModelIndex &index, QUndoCommand *parent = nullptr);
void setData(const QVariant &value, int role = Qt::DisplayRole);
virtual void redo() override;
virtual void undo() override;
private:
QPointer<QAbstractItemModel> m_model;
QModelIndex m_index;
QVariant m_old_value,
m_new_value;
int m_role=0;
};
/**
* @brief The ModelHeaderDataCommand class
* Change the data of a header
*/
class ModelHeaderDataCommand : public QUndoCommand
{
public:
ModelHeaderDataCommand(QAbstractItemModel *model, QUndoCommand *parent = nullptr);
void setData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::DisplayRole);
virtual void redo() override;
virtual void undo() override;
private:
QPointer<QAbstractItemModel> m_model;
Qt::Orientation m_orientation;
QVariant m_old_value,
m_new_value;
int m_section,
m_role;
};
#endif // ITEMMODELCOMMAND_H