Add table widget and item model for free terminal

WIP, the change made in the table widget can't be applied.
This commit is contained in:
joshua 2022-03-12 19:07:49 +01:00
parent 0ff099fb52
commit 9cbc3a2265
13 changed files with 1084 additions and 291 deletions

View File

@ -0,0 +1,81 @@
/*
Copyright 2006-2022 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 "freeterminaleditor.h"
#include "ui_freeterminaleditor.h"
#include "../../elementprovider.h"
#include "freeterminalmodel.h"
#include "../../diagram.h"
/**
* @brief FreeTerminalEditor::FreeTerminalEditor
* @param project
* @param parent
*/
FreeTerminalEditor::FreeTerminalEditor(QETProject *project, QWidget *parent) :
QWidget(parent),
ui(new Ui::FreeTerminalEditor),
m_project(project)
{
ui->setupUi(this);
ui->m_table_view->setItemDelegate(new FreeTerminalModelDelegate(ui->m_table_view));
m_model = new FreeTerminalModel(m_project, this);
ui->m_table_view->setModel(m_model);
ui->m_table_view->setCurrentIndex(m_model->index(0,0));
connect(ui->m_table_view, &QAbstractItemView::doubleClicked, this, [=](const QModelIndex &index)
{
if (m_model->columnTypeForIndex(index) == FreeTerminalModel::XRef)
{
auto mrtd = m_model->dataAtRow(index.row());
if (mrtd.element_)
{
auto elmt = mrtd.element_;
auto diagram = elmt->diagram();
if (diagram)
{
diagram->showMe();
if (diagram->views().size())
{
auto fit_view = elmt->sceneBoundingRect();
fit_view.adjust(-200,-200,200,200);
diagram->views().at(0)->fitInView(fit_view, Qt::KeepAspectRatioByExpanding);
}
}
}
}
});
}
/**
* @brief FreeTerminalEditor::~FreeTerminalEditor
*/
FreeTerminalEditor::~FreeTerminalEditor()
{
delete ui;
}
/**
* @brief FreeTerminalEditor::reload
* Reload the editor to be up to date with
* the current state of the project.
* Every not applied change will be lost.
*/
void FreeTerminalEditor::reload() {
m_model->clear();
}

View File

@ -0,0 +1,50 @@
/*
Copyright 2006-2022 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 FREETERMINALEDITOR_H
#define FREETERMINALEDITOR_H
#include <QWidget>
class QETProject;
class RealTerminal;
class FreeTerminalModel;
class QTableView;
namespace Ui {
class FreeTerminalEditor;
}
class FreeTerminalEditor : public QWidget
{
Q_OBJECT
public:
explicit FreeTerminalEditor(QETProject *project, QWidget *parent = nullptr);
~FreeTerminalEditor();
void reload();
private:
void selectionChanged();
private:
Ui::FreeTerminalEditor *ui;
QETProject *m_project = nullptr;
FreeTerminalModel *m_model = nullptr;
};
#endif // FREETERMINALEDITOR_H

View File

@ -0,0 +1,141 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FreeTerminalEditor</class>
<widget class="QWidget" name="FreeTerminalEditor">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>751</width>
<height>333</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="3" column="2">
<widget class="QComboBox" name="m_function_cb">
<item>
<property name="text">
<string>Générique</string>
</property>
</item>
<item>
<property name="text">
<string>Phase</string>
</property>
</item>
<item>
<property name="text">
<string>Neutre</string>
</property>
</item>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Déplacer dans :</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QComboBox" name="m_type_cb">
<item>
<property name="text">
<string>Générique</string>
</property>
</item>
<item>
<property name="text">
<string>Fusible</string>
</property>
</item>
<item>
<property name="text">
<string>Sectionnable</string>
</property>
</item>
<item>
<property name="text">
<string>Diode</string>
</property>
</item>
<item>
<property name="text">
<string>Terre</string>
</property>
</item>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Fonction :</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label">
<property name="text">
<string>Type :</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="label_3">
<property name="text">
<string>LED :</string>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QComboBox" name="m_led_cb">
<item>
<property name="text">
<string>Sans</string>
</property>
</item>
<item>
<property name="text">
<string>Avec</string>
</property>
</item>
</widget>
</item>
<item row="0" column="2">
<widget class="QComboBox" name="m_move_in_cb"/>
</item>
<item row="5" column="2">
<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>
<item row="0" column="0" rowspan="6">
<widget class="QTableView" name="m_table_view">
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,352 @@
/*
Copyright 2006-2022 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 <QComboBox>
#include "freeterminalmodel.h"
#include "../../elementprovider.h"
#include "../../utils/qetutils.h"
#include "../../qetgraphicsitem/terminalelement.h"
#include "../realterminal.h"
const int LABEL_CELL = 0;
const int XREF_CELL = 1;
const int TYPE_CELL = 2;
const int FUNCTION_CELL = 3;
const int LED_CELL = 4;
const int ROW_COUNT = 5;
static QVector<bool> UNMODIFIED_CELL_VECTOR{false, false, false, false, false};
FreeTerminalModel::Column FreeTerminalModel::columnTypeForIndex(const QModelIndex &index)
{
if (index.isValid())
{
switch (index.column()) {
case 0 : return Label;
case 1 : return XRef;
case 2 : return Type;
case 3 : return Function;
case 4 : return Led;
default : return Invalid;
}
}
return Invalid;
}
/**
* @brief FreeTerminalModel::FreeTerminalModel
* @param project
* @param parent
*/
FreeTerminalModel::FreeTerminalModel(QETProject *project, QObject *parent) :
QAbstractTableModel(parent),
m_project(project)
{
fillTerminalVector();
}
/**
* @brief FreeTerminalModel::rowCount
* @param parent
*/
int FreeTerminalModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return m_terminal_vector.size();
}
/**
* @brief FreeTerminalModel::columnCount
* @param parent
*/
int FreeTerminalModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return ROW_COUNT;
}
/**
* @brief FreeTerminalModel::data
* @param index
* @param role
* @return
*/
QVariant FreeTerminalModel::data(const QModelIndex &index, int role) const
{
if (index.row() >= rowCount(QModelIndex())) {
return QVariant();
}
const auto real_t_data = m_real_t_data.at(index.row());
if (role == Qt::DisplayRole)
{
switch (index.column())
{
case LABEL_CELL: return real_t_data.label_;
case XREF_CELL : return real_t_data.Xref_;
case TYPE_CELL : return ElementData::translatedTerminalType(real_t_data.type_);
case FUNCTION_CELL: return ElementData::translatedTerminalFunction(real_t_data.function_);
default : return QVariant();
}
}
else if (role == Qt::EditRole)
{
switch (index.column()) {
case LABEL_CELL : return real_t_data.label_;
default : return QVariant();
}
}
else if (role == Qt::CheckStateRole &&
index.column() == LED_CELL) {
return real_t_data.led_ ? Qt::Checked : Qt::Unchecked;
}
else if (role == Qt::BackgroundRole && index.column() <= LED_CELL)
{
if (m_modified_cell.contains(real_t_data.real_terminal) &&
m_modified_cell.value(real_t_data.real_terminal).at(index.column()))
{
return QBrush(Qt::yellow);
}
}
return QVariant();
}
bool FreeTerminalModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
auto mrtd = dataAtRow(index.row());
bool modified_ = false;
int modified_cell = -1;
auto column_ = index.column();
if (column_ == LABEL_CELL &&
role == Qt::EditRole &&
mrtd.label_ != value.toString())
{
mrtd.label_ = value.toString();
modified_ = true;
modified_cell = LABEL_CELL;
}
else if (column_ == TYPE_CELL &&
role == Qt::EditRole)
{
mrtd.type_ = value.value<ElementData::TerminalType>();
modified_ = true;
modified_cell = TYPE_CELL;
}
else if (column_ == FUNCTION_CELL &&
role == Qt::EditRole)
{
mrtd.function_ = value.value<ElementData::TerminalFunction>();
modified_ = true;
modified_cell = FUNCTION_CELL;
}
else if (column_ == LED_CELL)
{
mrtd.led_ = value.toBool();
modified_ = true;
modified_cell = LED_CELL;
}
//Set the modification to the terminal data
if (modified_)
{
m_real_t_data.replace(index.row(), mrtd);
QVector<bool> vector_;
if (m_modified_cell.contains(mrtd.real_terminal)) {
vector_ = m_modified_cell.value(mrtd.real_terminal);
} else {
vector_ = UNMODIFIED_CELL_VECTOR;
}
vector_.replace(modified_cell, true);
m_modified_cell.insert(mrtd.real_terminal, vector_);
emit dataChanged(index, index);
return true;
}
return false;
}
/**
* @brief FreeTerminalModel::headerData
* @param section
* @param orientation
* @param role
* @return
*/
QVariant FreeTerminalModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role == Qt::DisplayRole)
{
if (orientation == Qt::Horizontal)
{
switch (section) {
case LABEL_CELL: return tr("Label");
case XREF_CELL: return tr("Référence croisé");
case TYPE_CELL: return tr("Type");
case FUNCTION_CELL: return tr("Fonction");
case LED_CELL: return tr("led");
default : return QVariant();
}
}
}
return QVariant();
}
Qt::ItemFlags FreeTerminalModel::flags(const QModelIndex &index) const
{
Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
auto c = index.column();
if (c == LABEL_CELL || c == TYPE_CELL || c == FUNCTION_CELL)
flags = flags | Qt::ItemIsEditable;
if (c == LED_CELL) {
flags = flags | Qt::ItemIsUserCheckable;
}
return flags;
}
/**
* @brief FreeTerminalModel::clear
* Clear the model and set it as the current
* state of the project
*/
void FreeTerminalModel::clear()
{
beginResetModel();
m_terminal_vector.clear();
m_real_t_data.clear();
m_modified_cell.clear();
fillTerminalVector();
endResetModel();
}
/**
* @brief FreeTerminalModel::modifiedModelRealTerminalData
* @return a vector of modified terminal.
*/
QVector<modelRealTerminalData> FreeTerminalModel::modifiedModelRealTerminalData() const
{
QVector<modelRealTerminalData> returned_vector;
for (const auto &real_t_data : m_real_t_data) {
if (m_modified_cell.contains(real_t_data.real_terminal)) {
returned_vector.append(real_t_data);
}
}
return returned_vector;
}
/**
* @brief FreeTerminalModel::dataAtRow
* @param row
* @return the current data at row @a row
*/
modelRealTerminalData FreeTerminalModel::dataAtRow(int row) const
{
if (row >= m_terminal_vector.size()) {
return modelRealTerminalData();
} else {
return m_real_t_data.at(row);
}
}
/**
* @brief FreeTerminalModel::fillTerminalVector
*/
void FreeTerminalModel::fillTerminalVector()
{
ElementProvider provider_(m_project);
auto free_terminal_vector = provider_.freeTerminal();
std::sort(free_terminal_vector.begin(), free_terminal_vector.end(),
[](TerminalElement *a, TerminalElement *b)
{
return QETUtils::sortBeginIntString(a->actualLabel(), b->actualLabel());
});
for (const auto &terminal_ : free_terminal_vector) {
m_terminal_vector.append(terminal_->realTerminal());
m_real_t_data.append(modelRealTerminalData::data(terminal_->realTerminal()));
}
}
/****************************************************************
* A little delegate for add a combobox to edit type and function
****************************************************************/
FreeTerminalModelDelegate::FreeTerminalModelDelegate(QObject *parent) :
QStyledItemDelegate(parent)
{}
QWidget *FreeTerminalModelDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (index.column() == TYPE_CELL) {
auto qcb = new QComboBox(parent);
qcb->setObjectName(QLatin1String("terminal_type"));
qcb->addItem(ElementData::translatedTerminalType(ElementData::TTGeneric), ElementData::TTGeneric);
qcb->addItem(ElementData::translatedTerminalType(ElementData::TTFuse), ElementData::TTFuse);
qcb->addItem(ElementData::translatedTerminalType(ElementData::TTSectional), ElementData::TTSectional);
qcb->addItem(ElementData::translatedTerminalType(ElementData::TTDiode), ElementData::TTDiode);
qcb->addItem(ElementData::translatedTerminalType(ElementData::TTGround), ElementData::TTGround);
return qcb;
}
if (index.column() == FUNCTION_CELL) {
auto qcb = new QComboBox(parent);
qcb->setObjectName(QLatin1String("terminal_function"));
qcb->addItem(ElementData::translatedTerminalFunction(ElementData::TFGeneric), ElementData::TFGeneric);
qcb->addItem(ElementData::translatedTerminalFunction(ElementData::TFPhase), ElementData::TFPhase);
qcb->addItem(ElementData::translatedTerminalFunction(ElementData::TFNeutral), ElementData::TFNeutral);
return qcb;
}
return QStyledItemDelegate::createEditor(parent, option, index);
}
void FreeTerminalModelDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
if (index.isValid())
{
if (editor->objectName() == QLatin1String("terminal_type"))
{
if (auto qcb = dynamic_cast<QComboBox *>(editor)) {
model->setData(index, qcb->currentData(), Qt::EditRole);
}
}
else if (editor->objectName() == QLatin1String("terminal_function"))
{
if (auto qcb = dynamic_cast<QComboBox *>(editor)) {
model->setData(index, qcb->currentData(), Qt::EditRole);
}
}
else {
QStyledItemDelegate::setModelData(editor, model, index);
}
}
}

View File

@ -0,0 +1,83 @@
/*
Copyright 2006-2022 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 FREETERMINALMODEL_H
#define FREETERMINALMODEL_H
#include <QAbstractTableModel>
#include <QPointer>
#include <QStyledItemDelegate>
#include "modelTerminalData.h"
#include "../../qetproject.h"
class RealTerminal;
/**
* @brief The FreeTerminalModel class
*/
class FreeTerminalModel : public QAbstractTableModel
{
public:
enum Column {
Label = 0,
XRef = 1,
Type = 2,
Function = 3,
Led = 4,
Invalid = 99
};
static FreeTerminalModel::Column columnTypeForIndex(const QModelIndex &index);
Q_OBJECT
public:
explicit FreeTerminalModel(QETProject *project, QObject *parent = nullptr);
int rowCount(const QModelIndex &parent) const override;
int columnCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
void clear();
QVector<modelRealTerminalData> modifiedModelRealTerminalData() const;
modelRealTerminalData dataAtRow(int row) const;
private:
void fillTerminalVector();
private:
QPointer<QETProject> m_project;
QVector<QSharedPointer<RealTerminal>> m_terminal_vector;
QVector<modelRealTerminalData> m_real_t_data;
QHash<QSharedPointer<RealTerminal>, QVector<bool>> m_modified_cell;
};
class FreeTerminalModelDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
FreeTerminalModelDelegate(QObject *parent = nullptr);
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
};
#endif // FREETERMINALMODEL_H

View File

@ -0,0 +1,76 @@
/*
Copyright 2006-2021 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 MODELTERMINALDATA_H
#define MODELTERMINALDATA_H
#include <QString>
#include "../../qetgraphicsitem/element.h"
#include "../realterminal.h"
struct modelRealTerminalData
{
static modelRealTerminalData data(const QSharedPointer<RealTerminal> &real_t)
{
modelRealTerminalData mrtd;
if (!real_t.isNull())
{
mrtd.level_ = real_t->level();
mrtd.label_ = real_t->label();
mrtd.Xref_ = real_t->Xref();
mrtd.cable_ = real_t->cable();
mrtd.cable_wire = real_t->cableWire();
mrtd.conductor_ = real_t->conductor();
mrtd.led_ = real_t->isLed();
mrtd.type_ = real_t->type();
mrtd.function_ = real_t->function();
mrtd.element_ = real_t->element();
mrtd.real_terminal = real_t.toWeakRef();
mrtd.bridged_ = real_t->isBridged();
}
return mrtd;
}
int level_ = -1;
QString label_;
QString Xref_;
QString cable_;
QString cable_wire;
QString conductor_;
bool led_ = false;
bool bridged_ = false;
ElementData::TerminalType type_ = ElementData::TerminalType::TTGeneric;
ElementData::TerminalFunction function_ = ElementData::TerminalFunction::TFGeneric;
QPointer<Element> element_;
QWeakPointer<RealTerminal> real_terminal;
};
struct modelPhysicalTerminalData
{
QVector<modelRealTerminalData> real_data;
int pos_ = -1;
QUuid uuid_;
};
inline bool operator == (const modelPhysicalTerminalData &data_1, const modelPhysicalTerminalData &data_2) {
return data_1.uuid_ == data_2.uuid_;
}
#endif // MODELTERMINALDATA_H

View File

@ -20,7 +20,7 @@
#include "terminalstripcreatordialog.h"
#include "../../qetproject.h"
#include "../terminalstrip.h"
#include "../elementprovider.h"
#include "../../elementprovider.h"
#include "../qetgraphicsitem/terminalelement.h"
#include "../UndoCommand/addterminalstripcommand.h"
#include "../UndoCommand/addterminaltostripcommand.h"
@ -38,6 +38,7 @@
#include "../physicalterminal.h"
#include "../realterminal.h"
#include "../terminalstripbridge.h"
#include "freeterminaleditor.h"
#include <QTreeWidgetItem>
@ -66,11 +67,16 @@ TerminalStripEditor::TerminalStripEditor(QETProject *project, QWidget *parent) :
//Setup the bridge color
ui->m_bridge_color_cb->setColors(TerminalStripBridge::bridgeColor().toList());
m_free_terminal_editor = new FreeTerminalEditor(project, this);
ui->verticalLayout_2->insertWidget(1, m_free_terminal_editor);
setUpUndoConnections();
//Call for update the state of child widgets
selectionChanged();
updateWidget();
//Go the diagram of double clicked terminal
connect(ui->m_table_widget, &QAbstractItemView::doubleClicked, this, [=](const QModelIndex &index)
{
@ -350,6 +356,8 @@ void TerminalStripEditor::setCurrentStrip(TerminalStrip *strip_)
connect(m_current_strip, &TerminalStrip::bridgeChanged, this, &TerminalStripEditor::on_m_reload_pb_clicked);
connect(ui->m_table_widget->selectionModel(), &QItemSelectionModel::selectionChanged, this, &TerminalStripEditor::selectionChanged);
}
updateWidget();
}
/**
@ -537,6 +545,12 @@ QPair<TerminalStripModel::Column, QVector<modelRealTerminalData> > TerminalStrip
return qMakePair(TerminalStripModel::Invalid, QVector<modelRealTerminalData>());
}
void TerminalStripEditor::updateWidget()
{
ui->m_tab_widget->setVisible(m_current_strip);
m_free_terminal_editor->setHidden(m_current_strip);
}
/**
* @brief TerminalStripEditor::on_m_add_terminal_strip_pb_clicked
* Action when user click on add terminal strip button
@ -614,6 +628,8 @@ void TerminalStripEditor::on_m_reload_pb_clicked()
if (item) {
ui->m_terminal_strip_tw->setCurrentItem(item);
}
m_free_terminal_editor->reload();
}
/**

View File

@ -31,6 +31,7 @@ class TerminalStrip;
class QTreeWidgetItem;
class TerminalElement;
class QAbstractButton;
class FreeTerminalEditor;
/**
* @brief The TerminalStripEditor class
@ -56,6 +57,7 @@ class TerminalStripEditor : public QDialog
QSize setUpBridgeCellWidth();
TerminalStripModel::Column isSingleColumnSelected() const;
QPair<TerminalStripModel::Column, QVector<modelRealTerminalData>> singleColumnData() const;
void updateWidget();
private slots:
void on_m_add_terminal_strip_pb_clicked();
@ -83,6 +85,8 @@ class TerminalStripEditor : public QDialog
QHash<QUuid, QPointer<TerminalStrip>> m_uuid_strip_H;
TerminalStrip *m_current_strip = nullptr;
TerminalStripModel *m_model = nullptr;
FreeTerminalEditor *m_free_terminal_editor = nullptr;
};
#endif // TERMINALSTRIPEDITOR_H

View File

@ -14,6 +14,234 @@
<string>Gestionnaire de borniers</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="1">
<widget class="QWidget" name="widget" native="true">
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0" colspan="2">
<widget class="QPushButton" name="m_auto_ordering_pb">
<property name="text">
<string>Position automatique</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QPushButton" name="m_ungroup_pb">
<property name="text">
<string>Degrouper les bornes</string>
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Couleur pont :</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QComboBox" name="m_function_cb">
<item>
<property name="text">
<string>Générique</string>
</property>
</item>
<item>
<property name="text">
<string>Phase</string>
</property>
</item>
<item>
<property name="text">
<string>Neutre</string>
</property>
</item>
</widget>
</item>
<item row="10" column="0" colspan="2">
<widget class="QPushButton" name="m_bridge_terminals_pb">
<property name="text">
<string>Ponter les bornes</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>LED :</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QSpinBox" name="m_level_sb"/>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Fonction :</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QPushButton" name="m_group_terminals_pb">
<property name="text">
<string>Grouper les bornes</string>
</property>
</widget>
</item>
<item row="13" column="0">
<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>
<item row="8" column="1">
<widget class="QComboBox" name="m_led_cb">
<item>
<property name="text">
<string>Sans</string>
</property>
</item>
<item>
<property name="text">
<string>Avec</string>
</property>
</item>
</widget>
</item>
<item row="6" column="1">
<widget class="QComboBox" name="m_type_cb">
<item>
<property name="text">
<string>Générique</string>
</property>
</item>
<item>
<property name="text">
<string>Fusible</string>
</property>
</item>
<item>
<property name="text">
<string>Sectionnable</string>
</property>
</item>
<item>
<property name="text">
<string>Diode</string>
</property>
</item>
<item>
<property name="text">
<string>Terre</string>
</property>
</item>
</widget>
</item>
<item row="9" column="0" colspan="2">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="12" column="1">
<widget class="KColorCombo" name="m_bridge_color_cb"/>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Étage :</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Type :</string>
</property>
</widget>
</item>
<item row="11" column="0" colspan="2">
<widget class="QPushButton" name="m_unbridge_terminals_pb">
<property name="text">
<string>Déponter les bornes</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QWidget" name="widget_2" 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="QPushButton" name="m_add_terminal_strip_pb">
<property name="text">
<string>Ajouter un bornier</string>
</property>
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/list-add.png</normaloff>:/ico/16x16/list-add.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_remove_terminal_strip_pb">
<property name="text">
<string>Supprimer le bornier</string>
</property>
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/list-remove.png</normaloff>:/ico/16x16/list-remove.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_reload_pb">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/view-refresh.png</normaloff>:/ico/16x16/view-refresh.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QSplitter" name="splitter">
<property name="orientation">
@ -175,234 +403,6 @@
</widget>
</widget>
</item>
<item row="1" column="1">
<widget class="QWidget" name="widget" native="true">
<layout class="QGridLayout" name="gridLayout_3">
<item row="5" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Étage :</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QComboBox" name="m_type_cb">
<item>
<property name="text">
<string>Générique</string>
</property>
</item>
<item>
<property name="text">
<string>Fusible</string>
</property>
</item>
<item>
<property name="text">
<string>Sectionnable</string>
</property>
</item>
<item>
<property name="text">
<string>Diode</string>
</property>
</item>
<item>
<property name="text">
<string>Terre</string>
</property>
</item>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>LED :</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QSpinBox" name="m_level_sb"/>
</item>
<item row="9" column="0" colspan="2">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="13" column="0">
<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>
<item row="0" column="0" colspan="2">
<widget class="QPushButton" name="m_auto_ordering_pb">
<property name="text">
<string>Position automatique</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Fonction :</string>
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Couleur pont :</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QPushButton" name="m_group_terminals_pb">
<property name="text">
<string>Grouper les bornes</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QPushButton" name="m_ungroup_pb">
<property name="text">
<string>Degrouper les bornes</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Type :</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QComboBox" name="m_led_cb">
<item>
<property name="text">
<string>Sans</string>
</property>
</item>
<item>
<property name="text">
<string>Avec</string>
</property>
</item>
</widget>
</item>
<item row="12" column="1">
<widget class="KColorCombo" name="m_bridge_color_cb"/>
</item>
<item row="7" column="1">
<widget class="QComboBox" name="m_function_cb">
<item>
<property name="text">
<string>Générique</string>
</property>
</item>
<item>
<property name="text">
<string>Phase</string>
</property>
</item>
<item>
<property name="text">
<string>Neutre</string>
</property>
</item>
</widget>
</item>
<item row="10" column="0" colspan="2">
<widget class="QPushButton" name="m_bridge_terminals_pb">
<property name="text">
<string>Ponter les bornes</string>
</property>
</widget>
</item>
<item row="11" column="0" colspan="2">
<widget class="QPushButton" name="m_unbridge_terminals_pb">
<property name="text">
<string>Déponter les bornes</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QWidget" name="widget_2" 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="QPushButton" name="m_add_terminal_strip_pb">
<property name="text">
<string>Ajouter un bornier</string>
</property>
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/list-add.png</normaloff>:/ico/16x16/list-add.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_remove_terminal_strip_pb">
<property name="text">
<string>Supprimer le bornier</string>
</property>
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/list-remove.png</normaloff>:/ico/16x16/list-remove.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_reload_pb">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/view-refresh.png</normaloff>:/ico/16x16/view-refresh.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>

View File

@ -306,8 +306,7 @@ Qt::ItemFlags TerminalStripModel::flags(const QModelIndex &index) const
/**
* @brief TerminalStripModel::modifiedRealTerminalData
* @return a vector of QPair of modified terminal.
* the first value of the QPair is the original data, the second value is the edited data
* @return a vector of modified terminal.
*/
QVector<modelRealTerminalData> TerminalStripModel::modifiedmodelRealTerminalData() const
{
@ -495,7 +494,7 @@ void TerminalStripModel::fillPhysicalTerminalData()
{
if (!real_t.isNull())
{
mptd.real_data.append(modelRealData(real_t));
mptd.real_data.append(modelRealTerminalData::data(real_t));
}
}
@ -684,7 +683,7 @@ QPixmap TerminalStripModel::bridgePixmapFor(const QModelIndex &index) const
modelRealTerminalData previous_data;
do {
current_real_terminal = modelRealData(m_terminal_strip->previousRealTerminal(current_real_terminal.real_terminal));
current_real_terminal = modelRealTerminalData::data(m_terminal_strip->previousRealTerminal(current_real_terminal.real_terminal));
if (current_real_terminal.level_ == -1) {
break;
@ -719,7 +718,7 @@ QPixmap TerminalStripModel::bridgePixmapFor(const QModelIndex &index) const
modelRealTerminalData next_data;
do {
current_real_terminal = modelRealData(m_terminal_strip->nextRealTerminal(current_real_terminal.real_terminal));
current_real_terminal = modelRealTerminalData::data(m_terminal_strip->nextRealTerminal(current_real_terminal.real_terminal));
if (current_real_terminal.level_ == -1) {
break;
@ -758,29 +757,6 @@ QPixmap TerminalStripModel::bridgePixmapFor(const QModelIndex &index) const
return QPixmap();
}
modelRealTerminalData TerminalStripModel::modelRealData(const QWeakPointer<RealTerminal> &real_terminal)
{
modelRealTerminalData mrtd;
const auto real_t = real_terminal.toStrongRef();
if (!real_terminal.isNull())
{
mrtd.level_ = real_t->level();
mrtd.label_ = real_t->label();
mrtd.Xref_ = real_t->Xref();
mrtd.cable_ = real_t->cable();
mrtd.cable_wire = real_t->cableWire();
mrtd.conductor_ = real_t->conductor();
mrtd.led_ = real_t->isLed();
mrtd.type_ = real_t->type();
mrtd.function_ = real_t->function();
mrtd.element_ = real_t->element();
mrtd.real_terminal = real_terminal;
mrtd.bridged_ = real_t->isBridged();
}
return mrtd;
}
/***********************************************************
* A little delegate for add a combobox to edit type
* and a spinbox to edit the level of a terminal

View File

@ -26,7 +26,7 @@
#include <QColor>
#include "../terminalstrip.h"
#include "../../qetgraphicsitem/element.h"
#include "modelTerminalData.h"
//Code to use QColor as key for QHash
inline uint qHash(const QColor &key, uint seed) {
@ -43,37 +43,6 @@ inline uint qHash(const QPointer<Element> &key, uint seed) {
class TerminalStrip;
struct modelRealTerminalData
{
int level_ = -1;
QString label_;
QString Xref_;
QString cable_;
QString cable_wire;
QString conductor_;
bool led_ = false;
bool bridged_ = false;
ElementData::TerminalType type_ = ElementData::TerminalType::TTGeneric;
ElementData::TerminalFunction function_ = ElementData::TerminalFunction::TFGeneric;
QPointer<Element> element_;
QWeakPointer<RealTerminal> real_terminal;
};
struct modelPhysicalTerminalData
{
QVector<modelRealTerminalData> real_data;
int pos_ = -1;
QUuid uuid_;
};
inline bool operator == (const modelPhysicalTerminalData &data_1, const modelPhysicalTerminalData &data_2) {
return data_1.uuid_ == data_2.uuid_;
}
class TerminalStripModel : public QAbstractTableModel
{
public:
@ -124,8 +93,6 @@ class TerminalStripModel : public QAbstractTableModel
modelRealTerminalData realDataAtIndex(int index) const;
QPixmap bridgePixmapFor(const QModelIndex &index) const;
static modelRealTerminalData modelRealData(const QWeakPointer<RealTerminal> &real_terminal);
private:
QPointer<TerminalStrip> m_terminal_strip;
QHash<QPointer<Element>, QVector<bool>> m_modified_cell;

View File

@ -87,3 +87,48 @@ qreal QETUtils::graphicsHandlerSize(QGraphicsItem *item)
//Default value
return 10;
}
/**
* @brief QETUtils::sortBeginIntString
* Sort the string @a str_a and @a str_b and take in
* count if string begin with an int to sort it
* as int and not as string in this case.
* For exemple if we have to sort the string :
* "3str", 10str", "100str", "2str", "20str".
* The default behavior when sorting QString with the comparaison operator will be:
* "10str" "100str" "2str", "20str", "3str"
* When sorting with this function, the result will be :
* "10str", "2str", "3str", "20str", "100str"
* @param str_a
* @param str_b
* @return
*/
bool QETUtils::sortBeginIntString(const QString &str_a, const QString &str_b)
{
const QRegularExpression rx(QStringLiteral("^\\d+"));
int int_a =-1;
int int_b =-1;
auto match_a = rx.match(str_a);
if (match_a.hasMatch()) {
int_a = match_a.captured(0).toInt();
}
auto match_b = rx.match(str_b);
if (match_b.hasMatch()) {
int_b = match_b.captured(0).toInt();
}
//Sort as numbers if both string
//start at least by a digit and
//the number of each string are different.
//Else sort as string
if (int_a >= 0 &&
int_b >= 0 &&
int_a != int_b) {
return int_a<int_b;
}
else {
return str_a<str_b;
}
}

View File

@ -32,6 +32,8 @@ namespace QETUtils
QMargins marginsFromString(const QString &string);
qreal graphicsHandlerSize(QGraphicsItem *item);
bool sortBeginIntString(const QString &str_a, const QString &str_b);
template <typename T>
QVector<QWeakPointer<T>> sharedVectorToWeak(const QVector<QSharedPointer<T>> &vector)
{