mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-04-11 09:29:59 +02:00
Terminal numbering
This commit is contained in:
@@ -88,6 +88,7 @@ set(QET_RES_FILES
|
||||
${QET_DIR}/sources/ui/dynamicelementtextitemeditor.ui
|
||||
${QET_DIR}/sources/ui/elementinfopartwidget.ui
|
||||
${QET_DIR}/sources/ui/elementinfowidget.ui
|
||||
${QET_DIR}/sources/ui/terminalnumberingdialog.ui
|
||||
${QET_DIR}/sources/ui/formulaassistantdialog.ui
|
||||
${QET_DIR}/sources/ui/imagepropertieswidget.ui
|
||||
${QET_DIR}/sources/ui/importelementdialog.ui
|
||||
@@ -632,6 +633,8 @@ set(QET_SRC_FILES
|
||||
${QET_DIR}/sources/ui/elementinfopartwidget.h
|
||||
${QET_DIR}/sources/ui/elementinfowidget.cpp
|
||||
${QET_DIR}/sources/ui/elementinfowidget.h
|
||||
${QET_DIR}/sources/ui/terminalnumberingdialog.cpp
|
||||
${QET_DIR}/sources/ui/terminalnumberingdialog.h
|
||||
${QET_DIR}/sources/ui/elementpropertieswidget.cpp
|
||||
${QET_DIR}/sources/ui/elementpropertieswidget.h
|
||||
${QET_DIR}/sources/ui/formulaassistantdialog.cpp
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include "ui/diagrameditorhandlersizewidget.h"
|
||||
#include "TerminalStrip/ui/addterminalstripitemdialog.h"
|
||||
#include "wiringlistexport.h"
|
||||
#include "ui/terminalnumberingdialog.h"
|
||||
|
||||
#ifdef BUILD_WITHOUT_KF5
|
||||
#else
|
||||
@@ -477,6 +478,10 @@ void QETDiagramEditor::setUpActions()
|
||||
}
|
||||
});
|
||||
|
||||
// Terminal Numbering
|
||||
m_terminal_numbering = new QAction(QET::Icons::TerminalStrip, tr("Numérotation automatique des bornes"), this);
|
||||
connect(m_terminal_numbering, &QAction::triggered, this, &QETDiagramEditor::slot_terminalNumbering);
|
||||
|
||||
#ifdef QET_EXPORT_PROJECT_DB
|
||||
m_export_project_db = new QAction(QET::Icons::DocumentSpreadsheet, tr("Exporter la base de donnée interne du projet"), this);
|
||||
connect(m_export_project_db, &QAction::triggered, [this]() {
|
||||
@@ -847,6 +852,7 @@ void QETDiagramEditor::setUpMenu()
|
||||
menu_project -> addAction(m_terminal_strip_dialog);
|
||||
menu_project -> addAction(m_project_terminalBloc);
|
||||
menu_project -> addAction(m_project_export_wiring_list);
|
||||
menu_project -> addAction(m_terminal_numbering);
|
||||
#ifdef QET_EXPORT_PROJECT_DB
|
||||
menu_project -> addSeparator();
|
||||
menu_project -> addAction(m_export_project_db);
|
||||
@@ -1580,6 +1586,7 @@ void QETDiagramEditor::slot_updateActions()
|
||||
m_project_export_conductor_num-> setEnabled(opened_project);
|
||||
m_terminal_strip_dialog -> setEnabled(editable_project);
|
||||
m_project_export_wiring_list -> setEnabled(opened_project);
|
||||
m_terminal_numbering -> setEnabled(editable_project);
|
||||
#ifdef QET_EXPORT_PROJECT_DB
|
||||
m_export_project_db -> setEnabled(editable_project);
|
||||
#endif
|
||||
@@ -2510,7 +2517,27 @@ void QETDiagramEditor::generateTerminalBlock()
|
||||
#endif
|
||||
if ( !success ) {
|
||||
QMessageBox::warning(nullptr,
|
||||
QObject::tr("Error launching qet_tb_generator plugin"),
|
||||
message);
|
||||
QObject::tr("Error launching qet_tb_generator plugin"),
|
||||
message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief QETDiagramEditor::slot_terminalNumbering
|
||||
* Opens the dialog for automatic terminal numbering and applies the generated undo command.
|
||||
*/
|
||||
void QETDiagramEditor::slot_terminalNumbering() {
|
||||
TerminalNumberingDialog dialog(this);
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
QETProject *project = currentProject();
|
||||
if (!project) return;
|
||||
|
||||
// Fetch the generated undo command from the dialog logic
|
||||
QUndoCommand *macro = dialog.getUndoCommand(project);
|
||||
|
||||
// If changes were made, push them to the global undo stack
|
||||
if (macro) {
|
||||
undo_group.activeStack()->push(macro);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ class RecentFiles;
|
||||
class DiagramPropertiesEditorDockWidget;
|
||||
class ElementsCollectionWidget;
|
||||
class AutoNumberingDockWidget;
|
||||
class TerminalNumberingDialog;
|
||||
|
||||
#ifdef BUILD_WITHOUT_KF5
|
||||
#else
|
||||
@@ -132,6 +133,7 @@ class QETDiagramEditor : public QETMainWindow
|
||||
void projectWasClosed(ProjectView *);
|
||||
void editProjectProperties(ProjectView *);
|
||||
void editProjectProperties(QETProject *);
|
||||
void slot_terminalNumbering();
|
||||
void editDiagramProperties(DiagramView *);
|
||||
void editDiagramProperties(Diagram *);
|
||||
void addDiagramToProject(QETProject *);
|
||||
@@ -201,6 +203,7 @@ class QETDiagramEditor : public QETMainWindow
|
||||
*m_project_terminalBloc, ///< generate terminal block
|
||||
*m_project_export_conductor_num,///<Export the wire num to csv
|
||||
*m_project_export_wiring_list, ///< Action to export the wiring list
|
||||
*m_terminal_numbering, ///< Action to launch terminal numbering
|
||||
*m_export_project_db, ///Export to file the internal database of the current project
|
||||
*m_tile_window, ///< Show MDI subwindows as tile
|
||||
*m_cascade_window, ///< Show MDI subwindows as cascade
|
||||
|
||||
@@ -160,6 +160,7 @@ void ElementInfoWidget::enableLiveEdit()
|
||||
{
|
||||
for (ElementInfoPartWidget *eipw : m_eipw_list)
|
||||
connect(eipw, &ElementInfoPartWidget::textChanged, this, &ElementInfoWidget::apply);
|
||||
connect(ui->m_auto_num_locked_cb, &QCheckBox::clicked, this, &ElementInfoWidget::apply);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,6 +171,7 @@ void ElementInfoWidget::disableLiveEdit()
|
||||
{
|
||||
for (ElementInfoPartWidget *eipw : m_eipw_list)
|
||||
disconnect(eipw, &ElementInfoPartWidget::textChanged, this, &ElementInfoWidget::apply);
|
||||
disconnect(ui->m_auto_num_locked_cb, &QCheckBox::clicked, this, &ElementInfoWidget::apply);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -193,6 +195,12 @@ void ElementInfoWidget::buildInterface()
|
||||
}
|
||||
|
||||
ui->scroll_vlayout->addStretch();
|
||||
// Show checkbox only if the element is a terminal
|
||||
if (m_element.data()->elementData().m_type == ElementData::Terminal) {
|
||||
ui->m_auto_num_locked_cb->setVisible(true);
|
||||
} else {
|
||||
ui->m_auto_num_locked_cb->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -231,6 +239,11 @@ void ElementInfoWidget::updateUi()
|
||||
for (ElementInfoPartWidget *eipw : m_eipw_list) {
|
||||
eipw -> setText (element_info[eipw->key()].toString());
|
||||
}
|
||||
// Load the lock status for auto numbering
|
||||
if (m_element->elementData().m_type == ElementData::Terminal) {
|
||||
QString lock_value = element_info.value(QStringLiteral("auto_num_locked")).toString();
|
||||
ui->m_auto_num_locked_cb->setChecked(lock_value == QLatin1String("true"));
|
||||
}
|
||||
|
||||
if (m_live_edit) {
|
||||
enableLiveEdit();
|
||||
@@ -259,6 +272,10 @@ DiagramContext ElementInfoWidget::currentInfo() const
|
||||
}
|
||||
}
|
||||
|
||||
// Save the auto numbering lock status
|
||||
if (m_element->elementData().m_type == ElementData::Terminal) {
|
||||
info_.addValue(QStringLiteral("auto_num_locked"), ui->m_auto_num_locked_cb->isChecked() ? QStringLiteral("true") : QStringLiteral("false"));
|
||||
}
|
||||
return info_;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,19 @@
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="m_auto_num_locked_cb">
|
||||
<property name="text">
|
||||
<string>Exclure de la numérotation auto</string>
|
||||
</property>
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::LeftToRight</enum>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">margin: 5px; font-weight: bold;</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="sizePolicy">
|
||||
|
||||
178
sources/ui/terminalnumberingdialog.cpp
Normal file
178
sources/ui/terminalnumberingdialog.cpp
Normal file
@@ -0,0 +1,178 @@
|
||||
#include "terminalnumberingdialog.h"
|
||||
#include "ui_terminalnumberingdialog.h"
|
||||
#include "../qetproject.h"
|
||||
#include "../diagram.h"
|
||||
#include "../qetgraphicsitem/element.h"
|
||||
#include "../undocommand/changeelementinformationcommand.h"
|
||||
#include <QUndoCommand>
|
||||
#include <algorithm>
|
||||
|
||||
/**
|
||||
* @brief TerminalNumberingDialog::TerminalNumberingDialog
|
||||
* Constructor
|
||||
* @param parent
|
||||
*/
|
||||
TerminalNumberingDialog::TerminalNumberingDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::TerminalNumberingDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TerminalNumberingDialog::~TerminalNumberingDialog
|
||||
* Destructor
|
||||
*/
|
||||
TerminalNumberingDialog::~TerminalNumberingDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TerminalNumberingDialog::isXAxisPriority
|
||||
* @return true if X axis has priority, false if Y axis has priority
|
||||
*/
|
||||
bool TerminalNumberingDialog::isXAxisPriority() const
|
||||
{
|
||||
return ui->rb_priority_x->isChecked();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TerminalNumberingDialog::isAlphanumeric
|
||||
* @return true if alphanumeric sorting is enabled, false if numeric only
|
||||
*/
|
||||
bool TerminalNumberingDialog::isAlphanumeric() const
|
||||
{
|
||||
return ui->rb_type_alpha->isChecked();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TerminalNumberingDialog::getUndoCommand
|
||||
* Scans the given project for terminals, sorts them according to user preferences
|
||||
* (X/Y axis, alphanumeric rules), and generates an undo command containing all label changes.
|
||||
* * @param project Pointer to the current QETProject
|
||||
* @return QUndoCommand* containing the modifications, or nullptr if no changes are needed.
|
||||
*/
|
||||
QUndoCommand* TerminalNumberingDialog::getUndoCommand(QETProject *project) const {
|
||||
if (!project) return nullptr;
|
||||
|
||||
bool axisX = isXAxisPriority();
|
||||
bool alpha = isAlphanumeric();
|
||||
|
||||
// 1. Helper structure to store and sort terminal data
|
||||
struct TermInfo {
|
||||
Element *elmt;
|
||||
QString prefix;
|
||||
QString suffix;
|
||||
int folioIndex;
|
||||
qreal x;
|
||||
qreal y;
|
||||
};
|
||||
QList<TermInfo> termList;
|
||||
|
||||
// 2. Collect all terminals from all folios in the project
|
||||
foreach (Diagram *diagram, project->diagrams()) {
|
||||
int fIndex = diagram->folioIndex();
|
||||
foreach (QGraphicsItem *qgi, diagram->items()) {
|
||||
if (Element *elmt = qgraphicsitem_cast<Element *>(qgi)) {
|
||||
|
||||
// Check if the element is actually a terminal
|
||||
if (elmt->elementData().m_type == ElementData::Terminal) {
|
||||
DiagramContext info = elmt->elementInformations();
|
||||
|
||||
// Ignore locked terminals (if the user checked a 'lock' property)
|
||||
if (info.value(QStringLiteral("auto_num_locked")).toString() == QLatin1String("true")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QString label = elmt->actualLabel();
|
||||
if (label.isEmpty()) continue;
|
||||
|
||||
// Split prefix (e.g., "-X1") and suffix (e.g., "1" or "A")
|
||||
QString prefix = label;
|
||||
QString suffix = "";
|
||||
int colonIndex = label.lastIndexOf(':');
|
||||
if (colonIndex != -1) {
|
||||
prefix = label.left(colonIndex);
|
||||
suffix = label.mid(colonIndex + 1);
|
||||
}
|
||||
|
||||
// If user chose purely numeric, skip terminals with alphabetical suffixes
|
||||
if (!alpha && !suffix.isEmpty()) {
|
||||
bool isNum;
|
||||
suffix.toInt(&isNum);
|
||||
if (!isNum) continue;
|
||||
}
|
||||
|
||||
TermInfo ti;
|
||||
ti.elmt = elmt;
|
||||
ti.prefix = prefix;
|
||||
ti.suffix = suffix;
|
||||
ti.folioIndex = fIndex;
|
||||
ti.x = elmt->pos().x();
|
||||
ti.y = elmt->pos().y();
|
||||
termList.append(ti);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Sort terminals based on user selection (X or Y axis priority)
|
||||
std::sort(termList.begin(), termList.end(), [axisX](const TermInfo &a, const TermInfo &b) {
|
||||
// First sort by BMK Prefix alphabetically (case insensitive)
|
||||
int prefixCmp = a.prefix.compare(b.prefix, Qt::CaseInsensitive);
|
||||
if (prefixCmp != 0) return prefixCmp < 0;
|
||||
|
||||
// Then sort by folio (page) index
|
||||
if (a.folioIndex != b.folioIndex) return a.folioIndex < b.folioIndex;
|
||||
|
||||
// Finally sort by coordinates (with a 1.0px tolerance to handle slight misalignments)
|
||||
if (axisX) {
|
||||
if (qAbs(a.x - b.x) > 1.0) return a.x < b.x;
|
||||
return a.y < b.y;
|
||||
} else {
|
||||
if (qAbs(a.y - b.y) > 1.0) return a.y < b.y;
|
||||
return a.x < b.x;
|
||||
}
|
||||
});
|
||||
|
||||
// 4. Generate new numbering and create the undo command macro
|
||||
QUndoCommand *macro = new QUndoCommand(QObject::tr("Automatic terminal numbering"));
|
||||
QMap<QString, int> counters;
|
||||
|
||||
foreach (const TermInfo &ti, termList) {
|
||||
// Increment the counter for this terminal block (e.g., "-X3")
|
||||
counters[ti.prefix]++;
|
||||
int newNum = counters[ti.prefix];
|
||||
|
||||
// Determine if the original suffix was a pure number
|
||||
QString newLabel;
|
||||
bool isNum;
|
||||
ti.suffix.toInt(&isNum);
|
||||
|
||||
if (isNum || ti.suffix.isEmpty()) {
|
||||
// If it was a number (e.g., "1") or empty, update it with the new counter
|
||||
newLabel = ti.prefix + ":" + QString::number(newNum);
|
||||
} else {
|
||||
// If it was alphabetical (e.g., "N", "PE"), keep the original text but consume the count!
|
||||
newLabel = ti.prefix + ":" + ti.suffix;
|
||||
}
|
||||
|
||||
DiagramContext oldInfo = ti.elmt->elementInformations();
|
||||
DiagramContext newInfo = oldInfo;
|
||||
newInfo.addValue(QStringLiteral("label"), newLabel);
|
||||
|
||||
// Create an undo command only if the label actually changes
|
||||
if (oldInfo != newInfo) {
|
||||
new ChangeElementInformationCommand(ti.elmt, oldInfo, newInfo, macro);
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Return the macro if it contains changes, otherwise delete and return null
|
||||
if (macro->childCount() > 0) {
|
||||
return macro;
|
||||
} else {
|
||||
delete macro;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
35
sources/ui/terminalnumberingdialog.h
Normal file
35
sources/ui/terminalnumberingdialog.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef TERMINALNUMBERINGDIALOG_H
|
||||
#define TERMINALNUMBERINGDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
class QETProject;
|
||||
class QUndoCommand;
|
||||
|
||||
namespace Ui {
|
||||
class TerminalNumberingDialog;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The TerminalNumberingDialog class
|
||||
* Dialog to configure the automatic numbering of terminals.
|
||||
*/
|
||||
class TerminalNumberingDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TerminalNumberingDialog(QWidget *parent = nullptr);
|
||||
~TerminalNumberingDialog();
|
||||
|
||||
// Getters for the user's choices
|
||||
bool isXAxisPriority() const;
|
||||
bool isAlphanumeric() const;
|
||||
|
||||
QUndoCommand* getUndoCommand(QETProject *project) const;
|
||||
|
||||
private:
|
||||
Ui::TerminalNumberingDialog *ui;
|
||||
};
|
||||
|
||||
#endif // TERMINALNUMBERINGDIALOG_H
|
||||
139
sources/ui/terminalnumberingdialog.ui
Normal file
139
sources/ui/terminalnumberingdialog.ui
Normal file
@@ -0,0 +1,139 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TerminalNumberingDialog</class>
|
||||
<widget class="QDialog" name="TerminalNumberingDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Numérotation automatique des bornes</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_description">
|
||||
<property name="text">
|
||||
<string>Cette fonction numérote les bornes du projet selon leur position. Les bornes vides ou verrouillées sont ignorées.Le marquage des bornes doit être configuré au préalable comme suit : '-X:AB'. La partie avant les deux-points (le bornier) peut être nommée au choix. 'AB' peut être composé de chiffres ou de lettres."</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_axis">
|
||||
<property name="title">
|
||||
<string>Priorité des axes</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rb_priority_x">
|
||||
<property name="text">
|
||||
<string>Priorité à l'axe X (horizontal)</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rb_priority_y">
|
||||
<property name="text">
|
||||
<string>Priorité à l'axe Y (vertical)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_type">
|
||||
<property name="title">
|
||||
<string>Type de numérotation</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rb_type_num">
|
||||
<property name="text">
|
||||
<string>Numérique uniquement (1, 2, 3...)</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rb_type_alpha">
|
||||
<property name="text">
|
||||
<string>Alphanumérique (A, B, C... 1, 2...)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>TerminalNumberingDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>TerminalNumberingDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
Reference in New Issue
Block a user