diff --git a/dev_doc/enum_type_of_QGraphicsItem b/dev_doc/enum_type_of_QGraphicsItem index 7ab49a2a0..068b37d70 100644 --- a/dev_doc/enum_type_of_QGraphicsItem +++ b/dev_doc/enum_type_of_QGraphicsItem @@ -1,16 +1,16 @@ Type = UserType + ??? ###DIAGRAM EDITOR### -Element + 1000 -Conductor + 1001 -Terminal + 1002 -ElementTextItem + 1003 -DiagramTextItem + 1004 +Element + 1000 +Conductor + 1001 +Terminal + 1002 +ElementTextItem + 1003 +DiagramTextItem + 1004 IndependentTextItem + 1005 -ConductorTextItem + 1006 -DiagramImageItem + 1007 -QetShapItem + 1008 -crossRefItem + 1009 -DynamiqueElementTextItem + 1010 +ConductorTextItem + 1006 +DiagramImageItem + 1007 +QetShapItem + 1008 +crossRefItem + 1009 +DynamiqueElementTextItem + 1010 ElementPrimitiveDecorator + 2200 ###ELEMENT EDITOR### @@ -25,4 +25,8 @@ part rectangle + 1109 part dynamic text field + 1110 ###QetGraphicsHandlerItem### -QetGraphicsHandlerItem = 1200 +QetGraphicsHandlerItem + 1200 + +###VIEW ITEMS### +QetGraphicsTableItem + 1300 +QetGraphicsHeaderItem + 1301 diff --git a/qelectrotech.pro b/qelectrotech.pro index 287005af2..18a806bdc 100644 --- a/qelectrotech.pro +++ b/qelectrotech.pro @@ -77,7 +77,10 @@ TEMPLATE = app DEPENDPATH += . INCLUDEPATH += sources \ sources/titleblock \ - sources/ui sources/qetgraphicsitem \ + sources/ui \ + sources/qetgraphicsitem \ + sources/qetgraphicsitem/ViewItem \ + sources/qetgraphicsitem/ViewItem/ui \ sources/richtext \ sources/factory \ sources/properties \ @@ -85,7 +88,7 @@ INCLUDEPATH += sources \ sources/editor \ sources/editor/esevent \ sources/editor/graphicspart \ - sources/editor/ui \ + sources/editor/ui \ sources/undocommand \ sources/diagramevent \ sources/ElementsCollection \ @@ -93,12 +96,12 @@ INCLUDEPATH += sources \ sources/autoNum \ sources/autoNum/ui \ sources/ui/configpage \ - sources/SearchAndReplace \ - sources/SearchAndReplace/ui \ - sources/NameList \ - sources/NameList/ui \ - sources/utils \ - sources/pugixml + sources/SearchAndReplace \ + sources/SearchAndReplace/ui \ + sources/NameList \ + sources/NameList/ui \ + sources/utils \ + sources/pugixml \ # Fichiers sources @@ -107,6 +110,8 @@ HEADERS += $$files(sources/*.h) $$files(sources/ui/*.h) \ $$files(sources/titleblock/*.h) \ $$files(sources/richtext/*.h) \ $$files(sources/qetgraphicsitem/*.h) \ + $$files(sources/qetgraphicsitem/ViewItem/*.h) \ + $$files(sources/qetgraphicsitem/ViewItem/ui/*.h) \ $$files(sources/factory/*.h) \ $$files(sources/properties/*.h) \ $$files(sources/editor/ui/*.h) \ @@ -133,6 +138,8 @@ SOURCES += $$files(sources/*.cpp) \ $$files(sources/richtext/*.cpp) \ $$files(sources/ui/*.cpp) \ $$files(sources/qetgraphicsitem/*.cpp) \ + $$files(sources/qetgraphicsitem/ViewItem/*.cpp) \ + $$files(sources/qetgraphicsitem/ViewItem/ui/*.cpp) \ $$files(sources/factory/*.cpp) \ $$files(sources/properties/*.cpp) \ $$files(sources/editor/ui/*.cpp) \ @@ -173,7 +180,8 @@ FORMS += $$files(sources/richtext/*.ui) \ $$files(sources/autoNum/ui/*.ui) \ $$files(sources/ui/configpage/*.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_HEADERS_DIR = sources/ui/ diff --git a/sources/QetGraphicsItemModeler/qetgraphicshandleritem.cpp b/sources/QetGraphicsItemModeler/qetgraphicshandleritem.cpp index 93a2302a5..0814c0f83 100644 --- a/sources/QetGraphicsItemModeler/qetgraphicshandleritem.cpp +++ b/sources/QetGraphicsItemModeler/qetgraphicshandleritem.cpp @@ -59,8 +59,8 @@ void QetGraphicsHandlerItem::setColor(QColor color) */ void QetGraphicsHandlerItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { - Q_UNUSED(option); - Q_UNUSED(widget); + Q_UNUSED(option) + Q_UNUSED(widget) painter->save(); painter->setBrush(QBrush(m_color)); diff --git a/sources/qetdiagrameditor.cpp b/sources/qetdiagrameditor.cpp index a4fe855f6..010cb619a 100644 --- a/sources/qetdiagrameditor.cpp +++ b/sources/qetdiagrameditor.cpp @@ -49,6 +49,7 @@ #include "dialogwaiting.h" #include "addelementtextcommand.h" #include "conductornumexport.h" +#include "qetgraphicstableitem.h" #include #include @@ -400,6 +401,14 @@ void QETDiagramEditor::setUpActions() 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 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); @@ -755,6 +764,7 @@ void QETDiagramEditor::setUpMenu() { menu_project -> addAction(m_clean_project); menu_project -> addSeparator(); menu_project -> addAction(m_project_folio_list); + menu_project -> addAction(m_add_nomenclature); menu_project -> addAction(m_csv_export); menu_project -> addAction(m_project_export_conductor_num); menu_project -> addAction(m_project_terminalBloc); @@ -1438,7 +1448,8 @@ void QETDiagramEditor::slot_updateActions() m_project_add_diagram -> setEnabled(editable_project); m_remove_diagram_from_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_export_diagram -> setEnabled(opened_diagram); m_print -> setEnabled(opened_diagram); diff --git a/sources/qetdiagrameditor.h b/sources/qetdiagrameditor.h index 5ff2445cb..0f3948eb3 100644 --- a/sources/qetdiagrameditor.h +++ b/sources/qetdiagrameditor.h @@ -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_project_folio_list; ///< Sommaire des schemas QAction *m_csv_export; ///< generate nomenclature + QAction *m_add_nomenclature; ///< Add nomenclature graphics item; QAction *m_project_terminalBloc; ///< generate terminal block QAction *m_project_export_conductor_num; ///. +*/ +#include "qetgraphicsheaderitem.h" +#include "qabstractitemmodel.h" + +#include +#include + +/** + * @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()); + 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 ; icolumnCount() ; ++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 && + logicalIndexcolumnCount() && + 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_indexheaderData(0, Qt::Horizontal, Qt::FontRole).value()); + //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 ; icolumnCount() ; ++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. +*/ +#ifndef QETGRAPHICSHEADERITEM_H +#define QETGRAPHICSHEADERITEM_H + +#include "qetapp.h" + +#include +#include +#include + +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 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 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 diff --git a/sources/qetgraphicsitem/ViewItem/qetgraphicstableitem.cpp b/sources/qetgraphicsitem/ViewItem/qetgraphicstableitem.cpp new file mode 100644 index 000000000..7be9155f8 --- /dev/null +++ b/sources/qetgraphicsitem/ViewItem/qetgraphicstableitem.cpp @@ -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 . +*/ +#include "qetgraphicstableitem.h" +#include "diagram.h" +#include "qetgraphicsheaderitem.h" +#include "QPropertyUndoCommand/qpropertyundocommand.h" + +#include +#include +#include +#include +#include + +/** + * @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()); + + 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 ; icolumnCount() ; ++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(m_current_size.height())/static_cast(m_model->rowCount()); + for(auto i= 1 ; i-1rowCount() ; ++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 ; irowCount() ; ++i) + { + QPointF top_left(m_margin.left(), i==0? m_margin.top() : cell_height*i + m_margin.top()); + + for(auto j= 0 ; jcolumnCount() ; ++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(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(event)); + return true; + } + else if(event->type() == QEvent::GraphicsSceneMouseMove) //Move + { + handlerMouseMoveEvent(static_cast(event)); + return true; + } + else if (event->type() == QEvent::GraphicsSceneMouseRelease) //Release + { + handlerMouseReleaseEvent(static_cast(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()); + //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 ; rowrowCount() ; ++row) + { + for(auto col= 0 ; colcolumnCount() ; ++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 ; icolumnCount() ; ++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 &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(); + } +} diff --git a/sources/qetgraphicsitem/ViewItem/qetgraphicstableitem.h b/sources/qetgraphicsitem/ViewItem/qetgraphicstableitem.h new file mode 100644 index 000000000..96df2db67 --- /dev/null +++ b/sources/qetgraphicsitem/ViewItem/qetgraphicstableitem.h @@ -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 . +*/ +#ifndef QetGraphicsTableItem_H +#define QetGraphicsTableItem_H + +#include + +#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 &roles); + void headerSectionResized(); + void adjustSize(); + + private: + QAbstractItemModel *m_model= nullptr; + + QMargins m_margin; + QVector 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 diff --git a/sources/qetgraphicsitem/ViewItem/ui/graphicstablepropertieseditor.cpp b/sources/qetgraphicsitem/ViewItem/ui/graphicstablepropertieseditor.cpp new file mode 100644 index 000000000..f1aa0e309 --- /dev/null +++ b/sources/qetgraphicsitem/ViewItem/ui/graphicstablepropertieseditor.cpp @@ -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 . +*/ +#include "graphicstablepropertieseditor.h" +#include "ui_graphicstablepropertieseditor.h" +#include "qetgraphicstableitem.h" +#include "qetgraphicsheaderitem.h" +#include "diagram.h" +#include "QPropertyUndoCommand/qpropertyundocommand.h" +#include "itemmodelcommand.h" + +#include +#include + +/** + * @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(), + 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(); + 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::of(&QSpinBox::valueChanged), this, &GraphicsTablePropertiesEditor::apply); + m_edit_connection << connect(ui->m_y_pos, QOverload::of(&QSpinBox::valueChanged), this, &GraphicsTablePropertiesEditor::apply); + m_edit_connection << connect(ui->m_header_top_margin, QOverload::of(&QSpinBox::valueChanged), this, &GraphicsTablePropertiesEditor::apply); + m_edit_connection << connect(ui->m_header_left_margin, QOverload::of(&QSpinBox::valueChanged), this, &GraphicsTablePropertiesEditor::apply); + m_edit_connection << connect(ui->m_header_right_margin, QOverload::of(&QSpinBox::valueChanged), this, &GraphicsTablePropertiesEditor::apply); + m_edit_connection << connect(ui->m_header_bottom_margin, QOverload::of(&QSpinBox::valueChanged), this, &GraphicsTablePropertiesEditor::apply); + m_edit_connection << connect(ui->m_table_top_margin, QOverload::of(&QSpinBox::valueChanged), this, &GraphicsTablePropertiesEditor::apply); + m_edit_connection << connect(ui->m_table_left_margin, QOverload::of(&QSpinBox::valueChanged), this, &GraphicsTablePropertiesEditor::apply); + m_edit_connection << connect(ui->m_table_right_margin, QOverload::of(&QSpinBox::valueChanged), this, &GraphicsTablePropertiesEditor::apply); + m_edit_connection << connect(ui->m_table_bottom_margin, QOverload::of(&QSpinBox::valueChanged), this, &GraphicsTablePropertiesEditor::apply); + m_edit_connection << connect(m_table_button_group, QOverload::of(&QButtonGroup::buttonClicked), this, &GraphicsTablePropertiesEditor::apply); + m_edit_connection << connect(m_header_button_group, QOverload::of(&QButtonGroup::buttonClicked), this, &GraphicsTablePropertiesEditor::apply); + } +} diff --git a/sources/qetgraphicsitem/ViewItem/ui/graphicstablepropertieseditor.h b/sources/qetgraphicsitem/ViewItem/ui/graphicstablepropertieseditor.h new file mode 100644 index 000000000..f3b770eab --- /dev/null +++ b/sources/qetgraphicsitem/ViewItem/ui/graphicstablepropertieseditor.h @@ -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 . +*/ +#ifndef GRAPHICSTABLEPROPERTIESEDITOR_H +#define GRAPHICSTABLEPROPERTIESEDITOR_H + +#include "PropertiesEditor/propertieseditorwidget.h" +#include + +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 m_table_item; + QList m_connect_list, + m_edit_connection; + QButtonGroup *m_header_button_group = nullptr, + *m_table_button_group = nullptr; +}; + +Q_DECLARE_METATYPE(QMargins) + +#endif // GRAPHICSTABLEPROPERTIESEDITOR_H diff --git a/sources/qetgraphicsitem/ViewItem/ui/graphicstablepropertieseditor.ui b/sources/qetgraphicsitem/ViewItem/ui/graphicstablepropertieseditor.ui new file mode 100644 index 000000000..e7f53285d --- /dev/null +++ b/sources/qetgraphicsitem/ViewItem/ui/graphicstablepropertieseditor.ui @@ -0,0 +1,253 @@ + + + GraphicsTablePropertiesEditor + + + + 0 + 0 + 331 + 484 + + + + Form + + + + + + Position + + + + + + X : + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 10000 + + + + + + + Y : + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 10000 + + + + + + + + + + En tête + + + + + + + + Marge + + + Qt::AlignCenter + + + + + + + + + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Aligement : + + + + + + + Gauche + + + + + + + Centré + + + + + + + Droite + + + + + + + + + + Police + + + + + + + + + + Tableau + + + + + + + + + + + + + + + + + + + + Marge + + + Qt::AlignCenter + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Alignement : + + + + + + + Gauche + + + + + + + Centré + + + + + + + Droite + + + + + + + + + + Police + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + diff --git a/sources/qetgraphicsitem/qetshapeitem.cpp b/sources/qetgraphicsitem/qetshapeitem.cpp index 8793f19c8..9a79c976d 100644 --- a/sources/qetgraphicsitem/qetshapeitem.cpp +++ b/sources/qetgraphicsitem/qetshapeitem.cpp @@ -275,9 +275,6 @@ QPainterPath QetShapeItem::shape() const path.closeSubpath(); } break; - default: - Q_ASSERT(false); - break; } QPainterPathStroker pps; @@ -297,7 +294,8 @@ QPainterPath QetShapeItem::shape() const */ 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->setRenderHint(QPainter::Antialiasing, true); @@ -697,8 +695,8 @@ void QetShapeItem::removePoint() */ void QetShapeItem::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event) { - Q_UNUSED(qghi); - Q_UNUSED(event); + Q_UNUSED(qghi) + Q_UNUSED(event) m_old_P1 = m_P1; m_old_P2 = m_P2; @@ -717,7 +715,7 @@ void QetShapeItem::handlerMousePressEvent(QetGraphicsHandlerItem *qghi, QGraphic */ void QetShapeItem::handlerMouseMoveEvent(QetGraphicsHandlerItem *qghi, QGraphicsSceneMouseEvent *event) { - Q_UNUSED(qghi); + Q_UNUSED(qghi) QPointF new_pos = event->scenePos(); if (event->modifiers() != Qt::ControlModifier) diff --git a/sources/ui/diagrampropertieseditordockwidget.cpp b/sources/ui/diagrampropertieseditordockwidget.cpp index f4df9c7e0..cca4cab86 100644 --- a/sources/ui/diagrampropertieseditordockwidget.cpp +++ b/sources/ui/diagrampropertieseditordockwidget.cpp @@ -27,6 +27,8 @@ #include "elementtextitemgroup.h" #include "independenttextitem.h" #include "inditextpropertieswidget.h" +#include "qetgraphicstableitem.h" +#include "graphicstablepropertieseditor.h" /** * @brief DiagramPropertiesEditorDockWidget::DiagramPropertiesEditorDockWidget @@ -230,6 +232,20 @@ void DiagramPropertiesEditorDockWidget::selectionChanged() } 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(item), this)); + break; + } default: m_edited_qgi_type = -1; clear(); diff --git a/sources/undocommand/itemmodelcommand.cpp b/sources/undocommand/itemmodelcommand.cpp new file mode 100644 index 000000000..e12f64a2f --- /dev/null +++ b/sources/undocommand/itemmodelcommand.cpp @@ -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 . +*/ +#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); + } +} diff --git a/sources/undocommand/itemmodelcommand.h b/sources/undocommand/itemmodelcommand.h new file mode 100644 index 000000000..b66e16e80 --- /dev/null +++ b/sources/undocommand/itemmodelcommand.h @@ -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 . +*/ +#ifndef ITEMMODELCOMMAND_H +#define ITEMMODELCOMMAND_H + +#include +#include +#include + +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 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 m_model; + Qt::Orientation m_orientation; + QVariant m_old_value, + m_new_value; + int m_section, + m_role; +}; + +#endif // ITEMMODELCOMMAND_H