mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-11 14:44:15 +02:00
Merge remote-tracking branch 'upstream/master' into wiring-manager
Conflicts resolved in 24 files. Notable decisions: - ico/icon-themes.qrc: upstream's icon folder restructure kept; the 36 cable icon entries re-added under the new qet/qet-dark path scheme (XML valid, every referenced file exists). - Toolbar system: upstream's DiagramToolbarSettings now owns the toolbar filling. The cable tool is registered as diagrameditor.add_cable (generic group loop) and listed on the "diagram" toolbar right after the auto-break conductor action, separated by a divider, exactly like before the merge. - Paste: the cable lines of a copy are handed to PasteNumberingImport::push() as extra commands, so paste + cable lines + the numbering question stay ONE undo step on both paste paths (DiagramView::paste and DiagramEventAddPaste::commit). - PDF links: upstream's deterministic link sorting kept together with the cable cross-reference injector (injectLinkTo -> links list). - Element renumbering: upstream's ElementAutoNumSchemeCommand::renumber replaces the old formula-based body of QETProject::renumberElementsBySchemeTitle; the cable numbering rule API (cableAutoNum, axis priority, rule name) is kept in full. - Auto-numbering pages: upstream's scheme management kept, the Câbles tab added as index 4 (changeToCableTab), both entry points changeToCable() and changeToElement() kept side by side. - SelectAutonumW: dirty tracking and the contextEdited signal moved into upstream's insertPartRow() row API, so single-rule mode, the rule-removable button and "confirm without change leaves the project alone" keep working. - xrefpropertieswidget: upstream's offset clamping kept; the cable branch (Texte field, Police button, hidden display options) kept; the stack-overlapping checkbox is hidden for cables. Verified after the merge: build green (515/515, no errors), ctest 85/86 (only the pre-existing headless tst_menubarkeyboard failure), offscreen smoke exit 124.
This commit is contained in:
@@ -304,6 +304,7 @@ namespace autonum
|
||||
str.replace("%{designation_auxiliary1}", dc.value("designation_auxiliary1").toString());
|
||||
str.replace("%{manufacturer_auxiliary1}", dc.value("manufacturer_auxiliary1").toString());
|
||||
str.replace("%{manufacturer_reference_auxiliary1}", dc.value("manufacturer_reference_auxiliary1").toString());
|
||||
str.replace("%{machine_manufacturer_reference_auxiliary1}", dc.value("machine_manufacturer_reference_auxiliary1").toString());
|
||||
str.replace("%{supplier_auxiliary1}", dc.value("supplier_auxiliary1").toString());
|
||||
str.replace("%{quantity_auxiliary1}", dc.value("quantity_auxiliary1").toString());
|
||||
str.replace("%{unity_auxiliary1}", dc.value("unity_auxiliary1").toString());
|
||||
@@ -313,6 +314,7 @@ namespace autonum
|
||||
str.replace("%{designation_auxiliary2}", dc.value("designation_auxiliary2").toString());
|
||||
str.replace("%{manufacturer_auxiliary2}", dc.value("manufacturer_auxiliary2").toString());
|
||||
str.replace("%{manufacturer_reference_auxiliary2}", dc.value("manufacturer_reference_auxiliary2").toString());
|
||||
str.replace("%{machine_manufacturer_reference_auxiliary2}", dc.value("machine_manufacturer_reference_auxiliary2").toString());
|
||||
str.replace("%{supplier_auxiliary2}", dc.value("supplier_auxiliary2").toString());
|
||||
str.replace("%{quantity_auxiliary2}", dc.value("quantity_auxiliary2").toString());
|
||||
str.replace("%{unity_auxiliary2}", dc.value("unity_auxiliary2").toString());
|
||||
@@ -323,6 +325,7 @@ namespace autonum
|
||||
str.replace("%{designation_auxiliary3}", dc.value("designation_auxiliary3").toString());
|
||||
str.replace("%{manufacturer_auxiliary3}", dc.value("manufacturer_auxiliary3").toString());
|
||||
str.replace("%{manufacturer_reference_auxiliary3}", dc.value("manufacturer_reference_auxiliary3").toString());
|
||||
str.replace("%{machine_manufacturer_reference_auxiliary3}", dc.value("machine_manufacturer_reference_auxiliary3").toString());
|
||||
str.replace("%{supplier_auxiliary3}", dc.value("supplier_auxiliary3").toString());
|
||||
str.replace("%{quantity_auxiliary3}", dc.value("quantity_auxiliary3").toString());
|
||||
str.replace("%{unity_auxiliary3}", dc.value("unity_auxiliary3").toString());
|
||||
@@ -333,6 +336,7 @@ namespace autonum
|
||||
str.replace("%{designation_auxiliary4}", dc.value("designation_auxiliary4").toString());
|
||||
str.replace("%{manufacturer_auxiliary4}", dc.value("manufacturer_auxiliary4").toString());
|
||||
str.replace("%{manufacturer_reference_auxiliary4}", dc.value("manufacturer_reference_auxiliary4").toString());
|
||||
str.replace("%{machine_manufacturer_reference_auxiliary4}", dc.value("machine_manufacturer_reference_auxiliary4").toString());
|
||||
str.replace("%{supplier_auxiliary4}", dc.value("supplier_auxiliary4").toString());
|
||||
str.replace("%{quantity_auxiliary4}", dc.value("quantity_auxiliary4").toString());
|
||||
str.replace("%{unity_auxiliary4}", dc.value("unity_auxiliary4").toString());
|
||||
@@ -478,7 +482,10 @@ namespace autonum
|
||||
m_seq_struct.wrap.size()))
|
||||
);
|
||||
|
||||
for (int i=1; i<=max ; i++)
|
||||
// Highest number first: "%sequ_1" is also the start of
|
||||
// "%sequ_10", so replacing 1 before 10 would turn %sequ_10
|
||||
// into the first value followed by a "0".
|
||||
for (int i=max; i>=1 ; i--)
|
||||
{
|
||||
if (m_assigned_label.contains("%sequ_" + QString::number(i)) && m_seq_struct.unit.size() >= i) {
|
||||
m_assigned_label.replace("%sequ_" + QString::number(i),m_seq_struct.unit.at(i-1));
|
||||
|
||||
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
Copyright 2006-2026 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 "autonumschemecommand.h"
|
||||
|
||||
#include "../diagram.h"
|
||||
#include "../qetproject.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
AutoNumSchemeCommand::AutoNumSchemeCommand(QETProject *project, Kind kind) :
|
||||
m_project(project),
|
||||
m_kind(kind)
|
||||
{}
|
||||
|
||||
/// @return the titles of the schemes of @p kind, sorted
|
||||
QStringList AutoNumSchemeCommand::titles(const QETProject *project, Kind kind)
|
||||
{
|
||||
if (!project) {
|
||||
return {};
|
||||
}
|
||||
QStringList list = kind == Kind::Conductor ? project->conductorAutoNum().keys()
|
||||
: project->folioAutoNum().keys();
|
||||
list.sort(Qt::CaseInsensitive);
|
||||
return list;
|
||||
}
|
||||
|
||||
bool AutoNumSchemeCommand::contains(const QETProject *project, Kind kind, const QString &title)
|
||||
{
|
||||
if (!project) {
|
||||
return false;
|
||||
}
|
||||
return kind == Kind::Conductor ? project->conductorAutoNum().contains(title)
|
||||
: project->folioAutoNum().contains(title);
|
||||
}
|
||||
|
||||
NumerotationContext AutoNumSchemeCommand::contextOf(const QETProject *project, Kind kind, const QString &title)
|
||||
{
|
||||
if (!project) {
|
||||
return NumerotationContext();
|
||||
}
|
||||
return kind == Kind::Conductor ? project->conductorAutoNum(title)
|
||||
: project->folioAutoNum(title);
|
||||
}
|
||||
|
||||
/**
|
||||
@return the title of the scheme @p name clashes with, empty if none:
|
||||
the same name, whatever the case or the white space
|
||||
@param ignored_title : the scheme being renamed
|
||||
*/
|
||||
QString AutoNumSchemeCommand::nameClash(const QETProject *project, Kind kind,
|
||||
const QString &name, const QString &ignored_title)
|
||||
{
|
||||
const QString wanted = QETProject::normalizedAutoNumName(name);
|
||||
for (const QString &title : titles(project, kind)) {
|
||||
if (title == ignored_title) {
|
||||
continue;
|
||||
}
|
||||
if (QString::compare(QETProject::normalizedAutoNumName(title), wanted,
|
||||
Qt::CaseInsensitive) == 0) {
|
||||
return title;
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
/// @return why @p name cannot be the name of a scheme, translated, empty if it can
|
||||
QString AutoNumSchemeCommand::nameProblem(const QETProject *project, Kind kind,
|
||||
const QString &name, const QString &ignored_title)
|
||||
{
|
||||
if (QETProject::normalizedAutoNumName(name).isEmpty()) {
|
||||
return tr("Le nom de la numérotation ne peut pas être vide.");
|
||||
}
|
||||
const QString clash = nameClash(project, kind, name, ignored_title);
|
||||
if (!clash.isEmpty()) {
|
||||
return tr("Une numérotation nommée « %1 » existe déjà.").arg(clash);
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
/**
|
||||
@return the folios which follow the scheme @p title
|
||||
@param references : every folio which names it, for a folio numbering,
|
||||
even if its number has been written into the folio field already (see
|
||||
the class description)
|
||||
*/
|
||||
QList<Diagram *> AutoNumSchemeCommand::usersOf(const QETProject *project, Kind kind,
|
||||
const QString &title, bool references)
|
||||
{
|
||||
QList<Diagram *> users;
|
||||
if (!project || title.isEmpty()) {
|
||||
return users;
|
||||
}
|
||||
for (Diagram *diagram : project->diagrams()) {
|
||||
if (kind == Kind::Conductor) {
|
||||
if (diagram->conductorsAutonumName() == title) {
|
||||
users << diagram;
|
||||
}
|
||||
} else if (diagram->border_and_titleblock.autoPageNum() == title
|
||||
&& (references || diagram->border_and_titleblock.folio().contains(QLatin1String("%autonum")))) {
|
||||
users << diagram;
|
||||
}
|
||||
}
|
||||
return users;
|
||||
}
|
||||
|
||||
AutoNumSchemeCommand *AutoNumSchemeCommand::create(QETProject *project, Kind kind,
|
||||
const QString &title,
|
||||
const NumerotationContext &context,
|
||||
bool make_current)
|
||||
{
|
||||
if (!project || !nameProblem(project, kind, title).isEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
auto *cmd = new AutoNumSchemeCommand(project, kind);
|
||||
cmd->m_after = Scheme{QETProject::normalizedAutoNumName(title), context};
|
||||
cmd->m_current_before = project->conductorCurrentAutoNum();
|
||||
cmd->m_current_after = (kind == Kind::Conductor && make_current)
|
||||
? cmd->m_after->title
|
||||
: cmd->m_current_before;
|
||||
cmd->setText(tr("Créer la numérotation %1").arg(cmd->m_after->title));
|
||||
return cmd;
|
||||
}
|
||||
|
||||
/**
|
||||
Rename the scheme @p old_title to @p new_title and give it @p context.
|
||||
@param make_current : for conductors, make it the scheme new conductors
|
||||
take; otherwise it stays so if it was
|
||||
@return nullptr if there is no such scheme, the new name is not
|
||||
acceptable, or nothing changes
|
||||
*/
|
||||
AutoNumSchemeCommand *AutoNumSchemeCommand::edit(QETProject *project, Kind kind,
|
||||
const QString &old_title,
|
||||
const QString &new_title,
|
||||
const NumerotationContext &context,
|
||||
bool make_current)
|
||||
{
|
||||
if (!project || !contains(project, kind, old_title)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!nameProblem(project, kind, new_title, old_title).isEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto *cmd = new AutoNumSchemeCommand(project, kind);
|
||||
cmd->m_before = Scheme{old_title, contextOf(project, kind, old_title)};
|
||||
cmd->m_after = Scheme{QETProject::normalizedAutoNumName(new_title), context};
|
||||
cmd->m_current_before = project->conductorCurrentAutoNum();
|
||||
cmd->m_current_after = kind == Kind::Conductor
|
||||
? ((make_current || cmd->m_current_before == old_title)
|
||||
? cmd->m_after->title : cmd->m_current_before)
|
||||
: cmd->m_current_before;
|
||||
if (cmd->m_before->title != cmd->m_after->title) {
|
||||
cmd->m_users = [&] {
|
||||
QList<QPointer<Diagram>> list;
|
||||
for (Diagram *d : usersOf(project, kind, old_title, true)) list << d;
|
||||
return list;
|
||||
}();
|
||||
}
|
||||
|
||||
bool same_definition = cmd->m_before->context.size() == cmd->m_after->context.size();
|
||||
for (int i = 0 ; same_definition && i < cmd->m_before->context.size() ; ++i) {
|
||||
same_definition = cmd->m_before->context[i] == cmd->m_after->context[i];
|
||||
}
|
||||
if (cmd->m_before->title == cmd->m_after->title && same_definition
|
||||
&& cmd->m_current_before == cmd->m_current_after) {
|
||||
delete cmd;
|
||||
return nullptr;
|
||||
}
|
||||
if (cmd->m_before->title != cmd->m_after->title && same_definition) {
|
||||
cmd->setText(tr("Renommer la numérotation %1 en %2")
|
||||
.arg(cmd->m_before->title, cmd->m_after->title));
|
||||
} else {
|
||||
cmd->setText(tr("Modifier la numérotation %1").arg(cmd->m_after->title));
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
|
||||
/**
|
||||
Remove the scheme @p title.
|
||||
@return nullptr if there is no such scheme or a folio still follows it
|
||||
*/
|
||||
AutoNumSchemeCommand *AutoNumSchemeCommand::remove(QETProject *project, Kind kind,
|
||||
const QString &title)
|
||||
{
|
||||
if (!project || !contains(project, kind, title)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!usersOf(project, kind, title).isEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
auto *cmd = new AutoNumSchemeCommand(project, kind);
|
||||
cmd->m_before = Scheme{title, contextOf(project, kind, title)};
|
||||
cmd->m_current_before = project->conductorCurrentAutoNum();
|
||||
cmd->m_current_after = (kind == Kind::Conductor && cmd->m_current_before == title)
|
||||
? QString() : cmd->m_current_before;
|
||||
cmd->setText(tr("Supprimer la numérotation %1").arg(title));
|
||||
return cmd;
|
||||
}
|
||||
|
||||
/// Let the windows which list the schemes read them again
|
||||
void AutoNumSchemeCommand::announce(bool added, bool removed)
|
||||
{
|
||||
if (m_kind == Kind::Conductor) {
|
||||
if (removed) m_project->conductorAutoNumRemoved();
|
||||
if (added) m_project->conductorAutoNumAdded();
|
||||
} else {
|
||||
if (removed) m_project->folioAutoNumRemoved();
|
||||
if (added) m_project->folioAutoNumAdded();
|
||||
}
|
||||
}
|
||||
|
||||
/// Give the scheme @p from the title @p to, and the folios which follow it
|
||||
void AutoNumSchemeCommand::rename(const QString &from, const QString &to)
|
||||
{
|
||||
const NumerotationContext context = contextOf(m_project, m_kind, from);
|
||||
if (m_kind == Kind::Conductor) {
|
||||
m_project->removeConductorAutoNum(from);
|
||||
m_project->addConductorAutoNum(to, context);
|
||||
if (m_project->conductorCurrentAutoNum() == from) {
|
||||
m_project->setCurrentConductorAutoNum(to);
|
||||
}
|
||||
for (Diagram *d : m_project->diagrams()) {
|
||||
//The highest folio number given, kept by scheme title
|
||||
for (auto *hash : {&d->m_cnd_unitfolio_max, &d->m_cnd_tenfolio_max, &d->m_cnd_hundredfolio_max}) {
|
||||
if (hash->contains(from)) {
|
||||
hash->insert(to, hash->take(from));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m_project->removeFolioAutoNum(from);
|
||||
m_project->addFolioAutoNum(to, context);
|
||||
}
|
||||
for (const QPointer<Diagram> &d : std::as_const(m_users)) {
|
||||
if (!d) continue;
|
||||
if (m_kind == Kind::Conductor) {
|
||||
d->setConductorsAutonumName(to);
|
||||
} else {
|
||||
d->border_and_titleblock.setAutoPageNum(to);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AutoNumSchemeCommand::redo()
|
||||
{
|
||||
if (!m_project) return;
|
||||
|
||||
if (m_before && m_after && m_before->title != m_after->title) {
|
||||
rename(m_before->title, m_after->title);
|
||||
} else if (m_before && !m_after) {
|
||||
if (m_kind == Kind::Conductor) m_project->removeConductorAutoNum(m_before->title);
|
||||
else m_project->removeFolioAutoNum(m_before->title);
|
||||
}
|
||||
if (m_after) {
|
||||
if (m_kind == Kind::Conductor) m_project->addConductorAutoNum(m_after->title, m_after->context);
|
||||
else m_project->addFolioAutoNum(m_after->title, m_after->context);
|
||||
}
|
||||
if (m_kind == Kind::Conductor) {
|
||||
m_project->setCurrentConductorAutoNum(m_current_after);
|
||||
}
|
||||
announce(m_after.has_value(), m_before.has_value() && (!m_after || m_after->title != m_before->title));
|
||||
}
|
||||
|
||||
void AutoNumSchemeCommand::undo()
|
||||
{
|
||||
if (!m_project) return;
|
||||
|
||||
if (m_before && m_after && m_before->title != m_after->title) {
|
||||
rename(m_after->title, m_before->title);
|
||||
} else if (!m_before && m_after) {
|
||||
if (m_kind == Kind::Conductor) m_project->removeConductorAutoNum(m_after->title);
|
||||
else m_project->removeFolioAutoNum(m_after->title);
|
||||
}
|
||||
if (m_before) {
|
||||
if (m_kind == Kind::Conductor) m_project->addConductorAutoNum(m_before->title, m_before->context);
|
||||
else m_project->addFolioAutoNum(m_before->title, m_before->context);
|
||||
}
|
||||
if (m_kind == Kind::Conductor) {
|
||||
m_project->setCurrentConductorAutoNum(m_current_before);
|
||||
}
|
||||
announce(m_before.has_value(), m_after.has_value() && (!m_before || m_after->title != m_before->title));
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
Copyright 2006-2026 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 AUTONUMSCHEMECOMMAND_H
|
||||
#define AUTONUMSCHEMECOMMAND_H
|
||||
|
||||
#include "numerotationcontext.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QList>
|
||||
#include <QPointer>
|
||||
#include <QUndoCommand>
|
||||
|
||||
#include <optional>
|
||||
|
||||
class Diagram;
|
||||
class QETProject;
|
||||
|
||||
/**
|
||||
@brief The AutoNumSchemeCommand class
|
||||
Undoable creation, edition (rename and/or new definition) and removal of
|
||||
one conductor or folio numbering scheme of a project.
|
||||
|
||||
A folio refers to the scheme it follows by its title, as the project file
|
||||
has always had it (the title of the conductor numbering a folio reads,
|
||||
the title of the folio numbering its title block follows). So a rename
|
||||
moves those references with it, in the same undo step, and a scheme which
|
||||
a folio still follows cannot be removed: the folio would be left reading
|
||||
a numbering which does not exist.
|
||||
|
||||
A folio numbering is applied once: the number is written into the folio
|
||||
field of the title block, in place of %autonum, and the title block keeps
|
||||
the name of the numbering it came from. So a folio really depends on a
|
||||
folio numbering only while its folio field still holds %autonum, and
|
||||
only then can the numbering not be removed; every title block which
|
||||
names it has its name moved by a rename.
|
||||
|
||||
Conductors keep the formula they were numbered with, and the numbers
|
||||
folios show are worked out from the scheme when they are drawn: a new
|
||||
definition changes what is numbered from then on, nothing is renumbered.
|
||||
|
||||
Counter changes made by numbering something are not edits of the scheme
|
||||
and do not come here.
|
||||
*/
|
||||
class AutoNumSchemeCommand : public QUndoCommand
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(AutoNumSchemeCommand)
|
||||
|
||||
public:
|
||||
enum class Kind { Conductor, Folio };
|
||||
|
||||
struct Scheme
|
||||
{
|
||||
QString title;
|
||||
NumerotationContext context;
|
||||
};
|
||||
|
||||
static QStringList titles(const QETProject *project, Kind kind);
|
||||
static bool contains(const QETProject *project, Kind kind, const QString &title);
|
||||
static NumerotationContext contextOf(const QETProject *project, Kind kind, const QString &title);
|
||||
static QString nameClash(const QETProject *project, Kind kind,
|
||||
const QString &name, const QString &ignored_title = QString());
|
||||
static QString nameProblem(const QETProject *project, Kind kind,
|
||||
const QString &name, const QString &ignored_title = QString());
|
||||
static QList<Diagram *> usersOf(const QETProject *project, Kind kind,
|
||||
const QString &title, bool references = false);
|
||||
|
||||
static AutoNumSchemeCommand *create(QETProject *project, Kind kind,
|
||||
const QString &title,
|
||||
const NumerotationContext &context,
|
||||
bool make_current = false);
|
||||
static AutoNumSchemeCommand *edit(QETProject *project, Kind kind,
|
||||
const QString &old_title,
|
||||
const QString &new_title,
|
||||
const NumerotationContext &context,
|
||||
bool make_current = false);
|
||||
static AutoNumSchemeCommand *remove(QETProject *project, Kind kind,
|
||||
const QString &title);
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
|
||||
private:
|
||||
AutoNumSchemeCommand(QETProject *project, Kind kind);
|
||||
void rename(const QString &from, const QString &to);
|
||||
void announce(bool added, bool removed);
|
||||
|
||||
QETProject *m_project = nullptr;
|
||||
Kind m_kind;
|
||||
std::optional<Scheme> m_before;
|
||||
std::optional<Scheme> m_after;
|
||||
QString m_current_before;
|
||||
QString m_current_after;
|
||||
QList<QPointer<Diagram>> m_users; ///< the folios which follow the scheme being renamed
|
||||
};
|
||||
|
||||
#endif // AUTONUMSCHEMECOMMAND_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
Copyright 2006-2026 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 ELEMENTAUTONUMSCHEMECOMMAND_H
|
||||
#define ELEMENTAUTONUMSCHEMECOMMAND_H
|
||||
|
||||
#include "numerotationcontext.h"
|
||||
#include "renumberelementscommand.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDomDocument>
|
||||
#include <QDomElement>
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
#include <QSet>
|
||||
#include <QUndoCommand>
|
||||
#include <QUuid>
|
||||
#include <QVector>
|
||||
|
||||
#include <optional>
|
||||
|
||||
class Element;
|
||||
class QETProject;
|
||||
|
||||
/**
|
||||
@brief The ElementAutoNumSchemeCommand class
|
||||
Undoable creation, edition (rename and/or new definition) and removal
|
||||
of one element numbering scheme of a project, together with what it
|
||||
does to the elements following the scheme.
|
||||
|
||||
Elements follow a scheme by its uuid (QETInformation::ELMT_FORMULA_ID),
|
||||
so a rename touches no element. A new definition with a different
|
||||
formula rewrites the formula of every element following the scheme:
|
||||
when its sequential parts are the same (only the fixed text or the
|
||||
folio parts changed), each element keeps its numbers; otherwise the
|
||||
elements are numbered again, in folio and position order, as
|
||||
QETProject::renumberElementsBySchemeTitle() does.
|
||||
|
||||
A scheme whose formula would change cannot be edited while an element
|
||||
with a frozen label follows it: that element would keep a label and a
|
||||
formula the scheme no longer defines (see editBlockedBy(); edit()
|
||||
refuses). A rename, or a change of the counter, touches no formula and
|
||||
is allowed. renumber() leaves a frozen element exactly as it is,
|
||||
label, formula and numbers, and does not give its label to another
|
||||
element: the numbering goes past it (see reservedLabels()).
|
||||
|
||||
Counter changes made by placing elements are not edits of the scheme:
|
||||
they stay with SetAutoNumContextCommand.
|
||||
|
||||
Build one with create(), edit() or remove(); each returns nullptr when
|
||||
the change is refused or changes nothing. Show changedElementCount()
|
||||
to the user before pushing it when it is not zero.
|
||||
*/
|
||||
class ElementAutoNumSchemeCommand : public QUndoCommand
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(ElementAutoNumSchemeCommand)
|
||||
|
||||
public:
|
||||
struct Scheme
|
||||
{
|
||||
QString title;
|
||||
QUuid id;
|
||||
NumerotationContext context;
|
||||
};
|
||||
|
||||
static ElementAutoNumSchemeCommand *create(
|
||||
QETProject *project,
|
||||
const QString &title,
|
||||
const NumerotationContext &context,
|
||||
const QUuid &id = QUuid(),
|
||||
bool make_current = true);
|
||||
static ElementAutoNumSchemeCommand *edit(
|
||||
QETProject *project,
|
||||
const QString &old_title,
|
||||
const QString &new_title,
|
||||
const NumerotationContext &context,
|
||||
bool make_current = true);
|
||||
static ElementAutoNumSchemeCommand *remove(
|
||||
QETProject *project,
|
||||
const QString &title);
|
||||
|
||||
static QString nameProblem(const QETProject *project,
|
||||
const QString &name,
|
||||
const QString &ignored_title = QString());
|
||||
static bool sameSequentialParts(const QString &formula_a,
|
||||
const QString &formula_b);
|
||||
static NumerotationContext resetForRenumber(const NumerotationContext &context);
|
||||
static QVector<RenumberElementsCommand::ElementChange> renumberChanges(
|
||||
const QString &hash_key,
|
||||
const NumerotationContext &context,
|
||||
QVector<Element *> elements,
|
||||
const QString &formula,
|
||||
NumerotationContext *final_context,
|
||||
bool from_start = true,
|
||||
const QUuid &scheme_id = QUuid(),
|
||||
const QSet<QString> &reserved = QSet<QString>());
|
||||
static QSet<QString> reservedLabels(const QETProject *project,
|
||||
const QString &title,
|
||||
const QVector<Element *> &changing);
|
||||
static RenumberElementsCommand *renumber(QETProject *project,
|
||||
const QString &title,
|
||||
QVector<Element *> *frozen,
|
||||
const QString &text);
|
||||
static QVector<Element *> frozenFollowers(const QETProject *project,
|
||||
const QString &title);
|
||||
static QVector<Element *> editBlockedBy(const QETProject *project,
|
||||
const QString &title,
|
||||
const NumerotationContext &context);
|
||||
|
||||
/// Why assign() leaves an element as it is
|
||||
enum class Skipped {
|
||||
None,
|
||||
FollowsAlready, ///< already follows this scheme
|
||||
Frozen, ///< its label is frozen
|
||||
OtherFormula, ///< follows another scheme or has a formula of its own
|
||||
Linked ///< slave or report: takes its label from its master
|
||||
};
|
||||
static Skipped skipReason(const QETProject *project,
|
||||
const QString &title,
|
||||
const Element *element);
|
||||
/// What assign() would do with each of the given elements
|
||||
struct AssignPlan
|
||||
{
|
||||
QVector<Element *> todo; ///< given the scheme
|
||||
QVector<Element *> frozen; ///< a frozen label: left alone unless overwrite
|
||||
QVector<Element *> otherFormula; ///< follow or hold another formula: left alone unless overwrite
|
||||
int followsAlready = 0; ///< follow this scheme already
|
||||
int linked = 0; ///< slave or report: take their label from their master
|
||||
};
|
||||
static AssignPlan assignPlan(const QETProject *project,
|
||||
const QString &title,
|
||||
const QVector<Element *> &elements);
|
||||
static RenumberElementsCommand *assign(
|
||||
QETProject *project,
|
||||
const QString &title,
|
||||
const QVector<Element *> &elements,
|
||||
bool overwrite,
|
||||
int *skipped = nullptr,
|
||||
QUndoCommand *parent = nullptr);
|
||||
|
||||
/// What a numbered element's frozen state becomes
|
||||
enum class FreezeRule {
|
||||
Unfrozen, ///< free: the user asked for this numbering
|
||||
NewElementPolicy ///< as an element just placed: frozen if the folio or project freezes new ones
|
||||
};
|
||||
static RenumberElementsCommand *numberElements(
|
||||
QETProject *project,
|
||||
const QString &title,
|
||||
const QVector<Element *> &elements,
|
||||
const QString &text,
|
||||
FreezeRule freeze = FreezeRule::Unfrozen,
|
||||
QUndoCommand *parent = nullptr);
|
||||
|
||||
static QString schemeForFormula(const QETProject *project, const QString &formula);
|
||||
static QString followedScheme(const QETProject *project, const DiagramContext &info);
|
||||
static void writeCopiedSchemes(QDomDocument &document,
|
||||
QDomElement &root,
|
||||
const QETProject *project,
|
||||
const QVector<Element *> &copied);
|
||||
static QList<Scheme> copiedSchemes(const QDomElement &root);
|
||||
static QList<Scheme> missingForPaste(const QETProject *project,
|
||||
const QList<Scheme> &copied,
|
||||
const QList<Element *> &pasted);
|
||||
/// How the elements of a scheme are numbered by hand (see numberSupport())
|
||||
struct NumberSupport
|
||||
{
|
||||
bool supported = false;
|
||||
int partIndex = -1; ///< the one number part of the definition
|
||||
QString type; ///< "unit", "ten" or "hundred"
|
||||
int increase = 1;
|
||||
};
|
||||
struct GapRange
|
||||
{
|
||||
int from = 0;
|
||||
int to = 0;
|
||||
};
|
||||
/// A counter which would meet numbers already in use
|
||||
struct CounterConflict
|
||||
{
|
||||
int counter = 0; ///< the next number it would hand out
|
||||
int highest = 0; ///< the highest number in use
|
||||
int count = 0; ///< how many elements have a number of at least counter
|
||||
};
|
||||
static std::optional<CounterConflict> counterConflict(const QETProject *project,
|
||||
const QString &title,
|
||||
const NumerotationContext &proposed);
|
||||
static QSet<QString> labelsHeldBesides(const QETProject *project, const Element *element);
|
||||
static NumberSupport numberSupport(const NumerotationContext &context);
|
||||
static std::optional<int> numberOf(const NumberSupport &support, const Element *element);
|
||||
static QList<GapRange> gapRanges(const QETProject *project, const QString &title);
|
||||
static QList<int> freeNumbers(const QETProject *project, const QString &title,
|
||||
const Element *element, int limit = 500);
|
||||
static QString labelForNumber(const QETProject *project, const QString &title,
|
||||
Element *element, int number);
|
||||
static RenumberElementsCommand *assignNumber(QETProject *project,
|
||||
Element *element,
|
||||
int number,
|
||||
QString *problem = nullptr,
|
||||
QUndoCommand *parent = nullptr);
|
||||
|
||||
static QMap<QString, QVector<Element *>> pastedSchemes(
|
||||
const QETProject *project,
|
||||
const QList<Element *> &elements);
|
||||
static void linkPasted(const QETProject *project,
|
||||
const QList<Element *> &elements);
|
||||
static int numberPasted(QETProject *project,
|
||||
const QMap<QString, QVector<Element *>> &schemes,
|
||||
QUndoCommand *parent);
|
||||
|
||||
/// Elements whose label and formula change
|
||||
int changedElementCount() const {return m_changes.size();}
|
||||
const QVector<RenumberElementsCommand::ElementChange> &changes() const {return m_changes;}
|
||||
std::optional<Scheme> before() const {return m_before;}
|
||||
std::optional<Scheme> after() const {return m_after;}
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
|
||||
private:
|
||||
explicit ElementAutoNumSchemeCommand(QETProject *project);
|
||||
|
||||
QETProject *m_project = nullptr;
|
||||
std::optional<Scheme> m_before;
|
||||
std::optional<Scheme> m_after;
|
||||
QString m_current_before;
|
||||
QString m_current_after;
|
||||
QVector<RenumberElementsCommand::ElementChange> m_changes;
|
||||
};
|
||||
|
||||
#endif // ELEMENTAUTONUMSCHEMECOMMAND_H
|
||||
@@ -26,8 +26,9 @@ RenumberElementsCommand::RenumberElementsCommand(
|
||||
QVector<ElementChange> changes,
|
||||
QHash<QString, NumerotationContext> old_ctx,
|
||||
QHash<QString, NumerotationContext> new_ctx,
|
||||
const QString &text)
|
||||
: QUndoCommand(text)
|
||||
const QString &text,
|
||||
QUndoCommand *parent)
|
||||
: QUndoCommand(text, parent)
|
||||
, project_(project)
|
||||
, changes_(std::move(changes))
|
||||
, old_ctx_(std::move(old_ctx))
|
||||
@@ -61,18 +62,23 @@ void RenumberElementsCommand::apply(bool use_new)
|
||||
|
||||
// Apply per-element changes
|
||||
for (const ElementChange &c : changes_) {
|
||||
if (!c.element) continue;
|
||||
|
||||
const bool frozen = use_new ? c.new_frozen : c.old_frozen;
|
||||
const auto &infos = use_new ? c.new_infos : c.old_infos;
|
||||
const auto &seq = use_new ? c.new_seq : c.old_seq;
|
||||
|
||||
// Temporarily unfreeze so that label/infos update correctly.
|
||||
const bool was_frozen = c.element->isFreezeLabel();
|
||||
if (was_frozen) c.element->freezeLabel(false);
|
||||
|
||||
c.element->rSequenceStruct() = seq;
|
||||
c.element->setElementInformations(infos);
|
||||
c.element->freezeLabel(frozen);
|
||||
applyChange(c, use_new);
|
||||
}
|
||||
}
|
||||
|
||||
void RenumberElementsCommand::applyChange(const ElementChange &c, bool use_new)
|
||||
{
|
||||
if (!c.element) return;
|
||||
|
||||
const bool frozen = use_new ? c.new_frozen : c.old_frozen;
|
||||
const auto &infos = use_new ? c.new_infos : c.old_infos;
|
||||
const auto &seq = use_new ? c.new_seq : c.old_seq;
|
||||
|
||||
// Temporarily unfreeze so that label/infos update correctly.
|
||||
const bool was_frozen = c.element->isFreezeLabel();
|
||||
if (was_frozen) c.element->freezeLabel(false);
|
||||
|
||||
c.element->rSequenceStruct() = seq;
|
||||
c.element->setElementInformations(infos);
|
||||
c.element->freezeLabel(frozen);
|
||||
}
|
||||
|
||||
@@ -51,11 +51,17 @@ public:
|
||||
QVector<ElementChange> changes,
|
||||
QHash<QString, NumerotationContext> old_ctx,
|
||||
QHash<QString, NumerotationContext> new_ctx,
|
||||
const QString &text);
|
||||
const QString &text,
|
||||
QUndoCommand *parent = nullptr);
|
||||
|
||||
const QVector<ElementChange> &changes() const { return changes_; }
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
|
||||
/// Apply one change's old (@p use_new false) or new state.
|
||||
static void applyChange(const ElementChange &change, bool use_new);
|
||||
|
||||
private:
|
||||
void apply(bool use_new);
|
||||
|
||||
|
||||
@@ -19,6 +19,11 @@
|
||||
|
||||
#include "../../diagram.h"
|
||||
#include "../../diagramview.h"
|
||||
#include "../../qetgraphicsitem/element.h"
|
||||
#include "../../qeticons.h"
|
||||
#include "../elementautonumschemecommand.h"
|
||||
#include "counterwarning.h"
|
||||
#include "renumberpreviewdialog.h"
|
||||
#include "../../qetapp.h"
|
||||
#include "../../shortcutmanager.h"
|
||||
#include "../../titleblockproperties.h"
|
||||
@@ -29,7 +34,10 @@
|
||||
#include "../../undocommand/changetitleblockcommand.h"
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QSignalBlocker>
|
||||
#include <QSpinBox>
|
||||
|
||||
@@ -43,9 +51,127 @@ AutoNumberingDockWidget::AutoNumberingDockWidget(QWidget *parent) :
|
||||
ui(new Ui::AutoNumberingDockWidget)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
//The element row gets a button to the left of its reset button
|
||||
//which gives the numbering shown to the selected elements
|
||||
QPushButton *reset = ui->m_element_reset_start_pb;
|
||||
ui->gridLayout->removeWidget(reset);
|
||||
auto *actions = new QWidget(this);
|
||||
auto *actions_layout = new QHBoxLayout(actions);
|
||||
actions_layout->setContentsMargins(0, 0, 0, 0);
|
||||
actions_layout->setSpacing(2);
|
||||
m_element_apply_pb = new QPushButton(QET::Icons::DialogOk, QString(), actions);
|
||||
m_element_apply_pb->setObjectName(QStringLiteral("m_element_apply_pb"));
|
||||
m_element_apply_pb->setMaximumWidth(24);
|
||||
m_element_apply_pb->setToolTip(tr("Appliquer cette numérotation aux éléments sélectionnés"));
|
||||
reset->setParent(actions);
|
||||
actions_layout->addWidget(m_element_apply_pb);
|
||||
actions_layout->addWidget(reset);
|
||||
ui->gridLayout->addWidget(actions, 3, 2);
|
||||
connect(m_element_apply_pb, &QPushButton::clicked,
|
||||
this, &AutoNumberingDockWidget::applyElementSchemeToSelection);
|
||||
connect(ui->m_element_cb, qOverload<int>(&QComboBox::currentIndexChanged),
|
||||
this, &AutoNumberingDockWidget::updateApplyEnabled);
|
||||
m_element_apply_pb->setEnabled(false);
|
||||
|
||||
this->setDisabled(true);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief AutoNumberingDockWidget::applyElementSchemeToSelection
|
||||
Give the element numbering shown in the list to the elements selected
|
||||
in the current folio: each takes its formula and the next number, in
|
||||
folio and position order, and the counter moves on.
|
||||
|
||||
What would change is shown first. An element which holds another
|
||||
numbering, or whose label is frozen, is left as it is, unless the user
|
||||
asks to replace them too (a frozen one is then given back). One undo
|
||||
step.
|
||||
*/
|
||||
void AutoNumberingDockWidget::applyElementSchemeToSelection()
|
||||
{
|
||||
if (!m_project || m_project->isReadOnly()) {
|
||||
return;
|
||||
}
|
||||
const QString caption = tr("Appliquer la numérotation");
|
||||
const QString title = ui->m_element_cb->currentText();
|
||||
DiagramView *view = m_project_view ? m_project_view->currentDiagram() : nullptr;
|
||||
Diagram *diagram = view ? view->diagram() : nullptr;
|
||||
if (!diagram || !m_project->elementAutoNum().contains(title)) {
|
||||
QMessageBox::information(this, caption,
|
||||
tr("Choisissez une numérotation d'éléments du projet."));
|
||||
return;
|
||||
}
|
||||
|
||||
QVector<Element *> selected;
|
||||
const auto items = diagram->selectedItems();
|
||||
for (QGraphicsItem *item : items) {
|
||||
if (auto *el = qgraphicsitem_cast<Element *>(item)) {
|
||||
selected << el;
|
||||
}
|
||||
}
|
||||
if (selected.isEmpty()) {
|
||||
QMessageBox::information(this, caption,
|
||||
tr("Sélectionnez d'abord des éléments dans le folio."));
|
||||
return;
|
||||
}
|
||||
|
||||
const auto plan = ElementAutoNumSchemeCommand::assignPlan(m_project, title, selected);
|
||||
QVector<RenumberPreviewDialog::LeftAlone> left;
|
||||
for (Element *el : plan.frozen) {
|
||||
left.append({el, tr("(figé)")});
|
||||
}
|
||||
for (Element *el : plan.otherFormula) {
|
||||
left.append({el, tr("(autre numérotation)")});
|
||||
}
|
||||
const int replaceable = static_cast<int>(left.size());
|
||||
|
||||
auto *cmd = ElementAutoNumSchemeCommand::assign(m_project, title, selected, false);
|
||||
if (!cmd && !replaceable) {
|
||||
QMessageBox::information(
|
||||
this, caption,
|
||||
tr("Rien à appliquer : les éléments sélectionnés suivent déjà "
|
||||
"la numérotation « %1 », ou prennent leur nom d'un autre élément.").arg(title));
|
||||
return;
|
||||
}
|
||||
|
||||
const QString intro = cmd
|
||||
? tr("%n élément(s) vont recevoir la numérotation « %1 », dans l'ordre des folios "
|
||||
"et des positions.", "", static_cast<int>(plan.todo.size())).arg(title)
|
||||
: tr("Aucun élément ne peut recevoir la numérotation « %1 » sans remplacer "
|
||||
"ce qu'il a.").arg(title);
|
||||
const auto answer = RenumberPreviewDialog::ask(
|
||||
this, caption, intro,
|
||||
cmd ? cmd->changes() : QVector<RenumberElementsCommand::ElementChange>(),
|
||||
left,
|
||||
replaceable
|
||||
? tr("Remplacer aussi les %n élément(s) laissés comme ils sont", "", replaceable)
|
||||
: QString());
|
||||
|
||||
if (answer == RenumberPreviewDialog::Answer::Cancel) {
|
||||
delete cmd;
|
||||
return;
|
||||
}
|
||||
int applied = cmd ? static_cast<int>(cmd->changes().size()) : 0;
|
||||
if (answer == RenumberPreviewDialog::Answer::GoAndReplace) {
|
||||
delete cmd;
|
||||
cmd = ElementAutoNumSchemeCommand::assign(m_project, title, selected, true);
|
||||
applied = cmd ? static_cast<int>(cmd->changes().size()) : 0;
|
||||
}
|
||||
if (cmd) {
|
||||
m_project->undoStack()->push(cmd);
|
||||
}
|
||||
|
||||
const int not_given = static_cast<int>(selected.size()) - applied;
|
||||
if (not_given > 0) {
|
||||
QMessageBox::information(
|
||||
this, caption,
|
||||
tr("%n élément(s) numérotés.", "", applied)
|
||||
+ QLatin1Char('\n')
|
||||
+ tr("%n élément(s) sélectionnés sont restés comme ils sont.", "", not_given));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief AutoNumberingDockWidget::~AutoNumberingDockWidget
|
||||
Destructor
|
||||
@@ -117,6 +243,8 @@ void AutoNumberingDockWidget::setProject(QETProject *project,
|
||||
disconnect(m_project, &QETProject::conductorAutoNumRemoved, this, &AutoNumberingDockWidget::conductorAutoNumChanged);
|
||||
disconnect(m_project, &QETProject::conductorAutoNumAdded, this, &AutoNumberingDockWidget::conductorAutoNumChanged);
|
||||
disconnect(m_project_view, &ProjectView::diagramActivated, this, &AutoNumberingDockWidget::setConductorActive);
|
||||
disconnect(m_project_view, &ProjectView::diagramActivated, this, &AutoNumberingDockWidget::followSelectionOf);
|
||||
followSelectionOf(nullptr);
|
||||
|
||||
//Element Signals
|
||||
disconnect(m_project, &QETProject::elementAutoNumRemoved, this, &AutoNumberingDockWidget::elementAutoNumChanged);
|
||||
@@ -142,6 +270,8 @@ void AutoNumberingDockWidget::setProject(QETProject *project,
|
||||
connect(m_project, &QETProject::conductorAutoNumRemoved, this, &AutoNumberingDockWidget::conductorAutoNumChanged);
|
||||
connect(m_project, &QETProject::conductorAutoNumAdded, this, &AutoNumberingDockWidget::conductorAutoNumChanged);
|
||||
connect(m_project_view, &ProjectView::diagramActivated, this, &AutoNumberingDockWidget::setConductorActive);
|
||||
connect(m_project_view, &ProjectView::diagramActivated, this, &AutoNumberingDockWidget::followSelectionOf);
|
||||
followSelectionOf(m_project_view->currentDiagram());
|
||||
|
||||
//Element Signals
|
||||
connect(m_project, &QETProject::elementAutoNumRemoved, this, &AutoNumberingDockWidget::elementAutoNumChanged);
|
||||
@@ -207,6 +337,56 @@ void AutoNumberingDockWidget::setContext()
|
||||
this->setActive();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief AutoNumberingDockWidget::followSelectionOf
|
||||
Enable the apply button only while elements are selected in the folio
|
||||
shown: it gives a numbering to the selected elements, and with none
|
||||
selected there is nothing for it to do.
|
||||
@param view : the folio now shown, nullptr for none
|
||||
*/
|
||||
void AutoNumberingDockWidget::followSelectionOf(DiagramView *view)
|
||||
{
|
||||
Diagram *diagram = view ? view->diagram() : nullptr;
|
||||
if (m_selection_diagram) {
|
||||
disconnect(m_selection_diagram, &QGraphicsScene::selectionChanged,
|
||||
this, &AutoNumberingDockWidget::updateApplyEnabled);
|
||||
}
|
||||
m_selection_diagram = diagram;
|
||||
if (m_selection_diagram) {
|
||||
connect(m_selection_diagram, &QGraphicsScene::selectionChanged,
|
||||
this, &AutoNumberingDockWidget::updateApplyEnabled);
|
||||
}
|
||||
updateApplyEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief AutoNumberingDockWidget::updateApplyEnabled
|
||||
The apply button needs a numbering to give and elements selected.
|
||||
*/
|
||||
void AutoNumberingDockWidget::updateApplyEnabled()
|
||||
{
|
||||
if (!m_element_apply_pb) {
|
||||
return;
|
||||
}
|
||||
bool elements_selected = false;
|
||||
if (m_selection_diagram) {
|
||||
const auto items = m_selection_diagram->selectedItems();
|
||||
for (QGraphicsItem *item : items) {
|
||||
if (qgraphicsitem_cast<Element *>(item)) {
|
||||
elements_selected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_element_apply_pb->setEnabled(
|
||||
elements_selected && m_project && !m_project->isReadOnly()
|
||||
&& ui->m_element_cb->count() > 0);
|
||||
m_element_apply_pb->setToolTip(
|
||||
elements_selected
|
||||
? tr("Appliquer cette numérotation aux éléments sélectionnés")
|
||||
: tr("Sélectionnez d'abord des éléments dans le folio"));
|
||||
}
|
||||
|
||||
/**
|
||||
@brief AutoNumberingDockWidget::setConductorActive
|
||||
@param dv: activated diagramview
|
||||
@@ -539,6 +719,12 @@ void AutoNumberingDockWidget::applyValueField(QComboBox *combo_box, QLineEdit *l
|
||||
}
|
||||
|
||||
context.replaceValue(index, typed);
|
||||
//An element counter put back on numbers in use: ask first
|
||||
if (category == AutoNumCategory::Element
|
||||
&& !CounterWarning::confirm(this, m_project, combo_box->currentText(), context)) {
|
||||
refreshRow(category);
|
||||
return;
|
||||
}
|
||||
storeContext(combo_box, category, context);
|
||||
refreshRow(category);
|
||||
}
|
||||
@@ -684,6 +870,12 @@ void AutoNumberingDockWidget::resetAutoNum(QComboBox *combo_box, AutoNumCategory
|
||||
context.replaceValue(i, QStringLiteral("a"));
|
||||
}
|
||||
|
||||
//Back to the first number, over numbers in use: ask first
|
||||
if (category == AutoNumCategory::Element
|
||||
&& !CounterWarning::confirm(this, m_project, combo_box->currentText(), context)) {
|
||||
return;
|
||||
}
|
||||
|
||||
storeContext(combo_box, category, context);
|
||||
refreshRow(category);
|
||||
}
|
||||
|
||||
@@ -22,9 +22,11 @@
|
||||
#include "../../qetproject.h"
|
||||
|
||||
#include <QDockWidget>
|
||||
#include <QPointer>
|
||||
|
||||
class QComboBox;
|
||||
class QLineEdit;
|
||||
class QPushButton;
|
||||
class QSpinBox;
|
||||
|
||||
namespace Ui {
|
||||
@@ -58,6 +60,9 @@ class AutoNumberingDockWidget : public QDockWidget
|
||||
void refreshValueFields();
|
||||
|
||||
void on_m_configure_pb_clicked();
|
||||
void applyElementSchemeToSelection();
|
||||
void updateApplyEnabled();
|
||||
void followSelectionOf(DiagramView *view);
|
||||
|
||||
void on_m_conductor_reset_start_pb_clicked();
|
||||
void on_m_element_reset_start_pb_clicked();
|
||||
@@ -126,6 +131,8 @@ class AutoNumberingDockWidget : public QDockWidget
|
||||
/// this replaces refreshValueField() at each of them.
|
||||
void refreshRow(AutoNumCategory category);
|
||||
|
||||
QPushButton *m_element_apply_pb = nullptr;
|
||||
QPointer<Diagram> m_selection_diagram; ///< the folio whose selection enables the apply button
|
||||
Ui::AutoNumberingDockWidget *ui;
|
||||
QETProject* m_project = nullptr;
|
||||
ProjectView* m_project_view = nullptr;
|
||||
|
||||
@@ -73,8 +73,7 @@
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="view-refresh" resource="../../../qelectrotech.qrc">
|
||||
<normaloff>:/ico/16x16/view-refresh.png</normaloff>:/ico/16x16/view-refresh.png</iconset>
|
||||
<iconset theme="view-refresh"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -161,8 +160,7 @@
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="view-refresh" resource="../../../qelectrotech.qrc">
|
||||
<normaloff>:/ico/16x16/view-refresh.png</normaloff>:/ico/16x16/view-refresh.png</iconset>
|
||||
<iconset theme="view-refresh"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -238,8 +236,7 @@
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="view-refresh" resource="../../../qelectrotech.qrc">
|
||||
<normaloff>:/ico/16x16/view-refresh.png</normaloff>:/ico/16x16/view-refresh.png</iconset>
|
||||
<iconset theme="view-refresh"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -319,8 +316,7 @@
|
||||
<string>Configurer</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="configure" resource="../../../qelectrotech.qrc">
|
||||
<normaloff>:/ico/16x16/configure.png</normaloff>:/ico/16x16/configure.png</iconset>
|
||||
<iconset theme="configure"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -16,8 +16,11 @@
|
||||
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "autonumberingmanagementw.h"
|
||||
#include "../elementautonumschemecommand.h"
|
||||
#include "renumberpreviewdialog.h"
|
||||
|
||||
#include "../../diagram.h"
|
||||
#include "../../qetgraphicsitem/element.h"
|
||||
#include "../../qetproject.h"
|
||||
#include "../numerotationcontextcommands.h"
|
||||
#include "formulaautonumberingw.h"
|
||||
@@ -122,7 +125,42 @@ void AutoNumberingManagementW::on_m_renumber_elements_pb_clicked()
|
||||
RenumberElementsDialog dlg(titles, this);
|
||||
if (dlg.exec() != QDialog::Accepted) return;
|
||||
|
||||
project_->renumberElementsBySchemeTitle(dlg.selectedSchemeTitle());
|
||||
const QString title = dlg.selectedSchemeTitle();
|
||||
QVector<Element *> frozen;
|
||||
auto *cmd = ElementAutoNumSchemeCommand::renumber(
|
||||
project_, title, &frozen,
|
||||
title.isEmpty() ? tr("Renuméroter les éléments")
|
||||
: tr("Renuméroter les éléments (%1)").arg(title));
|
||||
if (!cmd)
|
||||
{
|
||||
QMessageBox::information(
|
||||
this, tr("Renuméroter les éléments"),
|
||||
frozen.isEmpty()
|
||||
? tr("Aucun élément ne suit cette numérotation.")
|
||||
: tr("Les %n élément(s) qui suivent cette numérotation ont un nom "
|
||||
"figé : rien n'est renuméroté.", "", frozen.size()));
|
||||
return;
|
||||
}
|
||||
|
||||
const int renumbered = static_cast<int>(cmd->changes().size());
|
||||
const int changed = RenumberPreviewDialog::changedLabelCount(cmd->changes());
|
||||
if (!RenumberPreviewDialog::confirm(
|
||||
this, tr("Renuméroter les éléments"),
|
||||
tr("%n élément(s) vont être renumérotés, à partir du premier numéro, "
|
||||
"dans l'ordre des folios et des positions.", "", renumbered),
|
||||
cmd->changes(), frozen)) {
|
||||
delete cmd;
|
||||
return;
|
||||
}
|
||||
project_->undoStack()->push(cmd);
|
||||
|
||||
QString summary = tr("%n élément(s) renumérotés, dont %1 avec un nouveau nom.", "", renumbered)
|
||||
.arg(changed);
|
||||
if (!frozen.isEmpty()) {
|
||||
summary += QLatin1Char('\n') + tr("%n élément(s) au nom figé n'ont pas été touchés, "
|
||||
"et leur numéro n'a pas été redonné.", "", frozen.size());
|
||||
}
|
||||
QMessageBox::information(this, tr("Renuméroter les éléments"), summary);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright 2006-2026 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 "counterwarning.h"
|
||||
|
||||
#include "../elementautonumschemecommand.h"
|
||||
#include "../../qetmessagebox.h"
|
||||
|
||||
/**
|
||||
@brief CounterWarning::confirm
|
||||
@param title : the element numbering
|
||||
@param proposed : its definition, with the counter to give it
|
||||
@return true if the counter meets no number in use, or the user goes
|
||||
on; false if the user gives up (and, with nobody to ask, always)
|
||||
*/
|
||||
bool CounterWarning::confirm(QWidget *parent,
|
||||
const QETProject *project,
|
||||
const QString &title,
|
||||
const NumerotationContext &proposed)
|
||||
{
|
||||
const auto conflict = ElementAutoNumSchemeCommand::counterConflict(project, title, proposed);
|
||||
if (!conflict) {
|
||||
return true;
|
||||
}
|
||||
const auto answer = QET::QetMessageBox::question(
|
||||
parent,
|
||||
tr("Compteur de la numérotation"),
|
||||
tr("Le prochain numéro serait %1, mais %n élément(s) de la numérotation « %2 » "
|
||||
"ont déjà un numéro égal ou supérieur (jusqu'à %3).", "", conflict->count)
|
||||
.arg(conflict->counter).arg(title).arg(conflict->highest)
|
||||
+ tr("\nLes nouveaux éléments sauteront les numéros déjà pris : ils ne recevront "
|
||||
"pas forcément les numéros à partir de %1.\n\nContinuer ?").arg(conflict->counter),
|
||||
QMessageBox::Yes | QMessageBox::Cancel,
|
||||
QMessageBox::Cancel);
|
||||
return answer == QMessageBox::Yes;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
Copyright 2006-2026 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 COUNTERWARNING_H
|
||||
#define COUNTERWARNING_H
|
||||
|
||||
#include "../numerotationcontext.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
class QETProject;
|
||||
class QWidget;
|
||||
|
||||
/**
|
||||
@brief The CounterWarning class
|
||||
Asks before the counter of an element numbering is set to a number which
|
||||
elements of it have already: the next elements skip the numbers in use,
|
||||
so the next number is not the one asked for. The user may go on or give
|
||||
up.
|
||||
*/
|
||||
class CounterWarning
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(CounterWarning)
|
||||
|
||||
public:
|
||||
static bool confirm(QWidget *parent,
|
||||
const QETProject *project,
|
||||
const QString &title,
|
||||
const NumerotationContext &proposed);
|
||||
};
|
||||
|
||||
#endif // COUNTERWARNING_H
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
Copyright 2006-2026 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 "pastenumberingimport.h"
|
||||
|
||||
#include "../../diagram.h"
|
||||
#include "../../diagramcommands.h"
|
||||
#include "../../qetmessagebox.h"
|
||||
#include "../../qetproject.h"
|
||||
|
||||
#include <QSettings>
|
||||
|
||||
/// @return the numberings a copy carries, which pasted elements follow
|
||||
QList<ElementAutoNumSchemeCommand::Scheme> PasteNumberingImport::copiedBy(const QDomDocument &clipboard)
|
||||
{
|
||||
return ElementAutoNumSchemeCommand::copiedSchemes(clipboard.documentElement());
|
||||
}
|
||||
|
||||
/**
|
||||
@brief PasteNumberingImport::push
|
||||
Push the paste of @p content on the undo stack of @p diagram, after
|
||||
asking whether to import the numberings of @p copied which the pasted
|
||||
elements follow and the project does not have.
|
||||
@param parent : parent of the question
|
||||
@param copied : the numberings the copy carries
|
||||
@param extra : commands the copy brings beside the paste itself
|
||||
(the cable lines of a fragment, for example); they are pushed inside
|
||||
the same macro, so one Ctrl+Z undoes all of it at once.
|
||||
*/
|
||||
void PasteNumberingImport::push(QWidget *parent,
|
||||
Diagram *diagram,
|
||||
const DiagramContent &content,
|
||||
const QList<ElementAutoNumSchemeCommand::Scheme> &copied,
|
||||
const QList<QUndoCommand *> &extra)
|
||||
{
|
||||
QETProject *project = diagram->project();
|
||||
auto *paste = new PasteDiagramCommand(diagram, content);
|
||||
|
||||
//The paste and the commands beside it are one step: only the
|
||||
//macros really need more than the single push.
|
||||
const auto push_all = [&]() {
|
||||
if (extra.isEmpty()) {
|
||||
diagram->undoStack().push(paste);
|
||||
return;
|
||||
}
|
||||
diagram->undoStack().beginMacro(paste->text());
|
||||
diagram->undoStack().push(paste);
|
||||
for (QUndoCommand *cmd : extra) {
|
||||
diagram->undoStack().push(cmd);
|
||||
}
|
||||
diagram->undoStack().endMacro();
|
||||
};
|
||||
|
||||
QList<ElementAutoNumSchemeCommand::Scheme> missing;
|
||||
if (project && !copied.isEmpty()
|
||||
&& QSettings().value("diagramcommands/autonumber-pasted-elements", true).toBool()) {
|
||||
missing = ElementAutoNumSchemeCommand::missingForPaste(project, copied, content.m_elements);
|
||||
}
|
||||
if (missing.isEmpty()) {
|
||||
push_all();
|
||||
return;
|
||||
}
|
||||
|
||||
QStringList names;
|
||||
for (const auto &scheme : std::as_const(missing)) {
|
||||
names << QStringLiteral("« %1 »").arg(scheme.title);
|
||||
}
|
||||
const auto answer = QET::QetMessageBox::question(
|
||||
parent,
|
||||
tr("Numérotation absente de ce projet"),
|
||||
tr("Les éléments collés suivent %n numérotation(s) qui n'existe(nt) pas dans ce projet : %1.\n\n"
|
||||
"Les importer ? Les éléments recevront alors les prochains numéros, à partir de 1. "
|
||||
"Sinon ils seront collés sans numérotation.", "", static_cast<int>(missing.size()))
|
||||
.arg(names.join(QStringLiteral(", "))),
|
||||
QMessageBox::Yes | QMessageBox::No,
|
||||
QMessageBox::Yes);
|
||||
if (answer != QMessageBox::Yes) {
|
||||
push_all();
|
||||
return;
|
||||
}
|
||||
|
||||
diagram->undoStack().beginMacro(paste->text());
|
||||
for (const auto &scheme : std::as_const(missing))
|
||||
{
|
||||
//Under its own name, or one which is free here
|
||||
QString title = scheme.title;
|
||||
for (int n = 2 ; !project->elementAutoNumNameClash(title).isEmpty() ; ++n) {
|
||||
title = QStringLiteral("%1 (%2)").arg(scheme.title).arg(n);
|
||||
}
|
||||
if (auto *cmd = ElementAutoNumSchemeCommand::create(
|
||||
project, title,
|
||||
ElementAutoNumSchemeCommand::resetForRenumber(scheme.context),
|
||||
scheme.id, false)) {
|
||||
diagram->undoStack().push(cmd);
|
||||
}
|
||||
}
|
||||
diagram->undoStack().push(paste);
|
||||
for (QUndoCommand *cmd : extra) {
|
||||
diagram->undoStack().push(cmd);
|
||||
}
|
||||
diagram->undoStack().endMacro();
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
Copyright 2006-2026 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 PASTENUMBERINGIMPORT_H
|
||||
#define PASTENUMBERINGIMPORT_H
|
||||
|
||||
#include "../elementautonumschemecommand.h"
|
||||
#include "../../diagramcontent.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QList>
|
||||
#include <QUndoCommand>
|
||||
|
||||
class Diagram;
|
||||
class QWidget;
|
||||
|
||||
/**
|
||||
@brief The PasteNumberingImport class
|
||||
Pastes elements copied from another project, which may follow element
|
||||
numberings this project does not have.
|
||||
|
||||
Such an element would be left with a formula which names no numbering
|
||||
here, and with a label nothing explains. So the user is asked, once
|
||||
for all the numberings missing, whether to import them. Imported, they
|
||||
number the pasted elements from their first number (a number of the other
|
||||
project means nothing here); not imported, the elements are pasted
|
||||
without a numbering.
|
||||
|
||||
The import and the paste are one undo step.
|
||||
|
||||
A paste which brings more than itself (the cable lines of the copy,
|
||||
for instance, which are no part of a DiagramContent) hands those
|
||||
commands over through @p extra: they are pushed inside the very
|
||||
same macro, so one Ctrl+Z still takes the whole of it back.
|
||||
*/
|
||||
class PasteNumberingImport
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(PasteNumberingImport)
|
||||
|
||||
public:
|
||||
static void push(QWidget *parent,
|
||||
Diagram *diagram,
|
||||
const DiagramContent &content,
|
||||
const QList<ElementAutoNumSchemeCommand::Scheme> &copied,
|
||||
const QList<QUndoCommand *> &extra = QList<QUndoCommand *>());
|
||||
|
||||
static QList<ElementAutoNumSchemeCommand::Scheme> copiedBy(const QDomDocument &clipboard);
|
||||
};
|
||||
|
||||
#endif // PASTENUMBERINGIMPORT_H
|
||||
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
Copyright 2006-2026 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 "renumberpreviewdialog.h"
|
||||
|
||||
#include "../../diagram.h"
|
||||
#include "../../qetgraphicsitem/element.h"
|
||||
#include "../../qetinformation.h"
|
||||
|
||||
#include <QBrush>
|
||||
#include <QDialog>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QFont>
|
||||
#include <QHeaderView>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QTableWidget>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace {
|
||||
QString labelOf(const DiagramContext &info)
|
||||
{
|
||||
return info.value(QETInformation::ELMT_LABEL).toString();
|
||||
}
|
||||
|
||||
QString folioOf(const Element *element)
|
||||
{
|
||||
return element && element->diagram()
|
||||
? QString::number(element->diagram()->folioIndex() + 1)
|
||||
: QString();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
/**
|
||||
@brief RenumberPreviewDialog::changedLabelCount
|
||||
@return how many of @p changes give their element another label
|
||||
*/
|
||||
int RenumberPreviewDialog::changedLabelCount(
|
||||
const QVector<RenumberElementsCommand::ElementChange> &changes)
|
||||
{
|
||||
int count = 0;
|
||||
for (const auto &change : changes) {
|
||||
if (labelOf(change.old_infos) != labelOf(change.new_infos)) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief RenumberPreviewDialog::ask
|
||||
@param intro : text above the list
|
||||
@param changes : what the operation would do to elements
|
||||
@param left_alone : the elements it leaves as they are, each with the
|
||||
reason shown in place of its new name
|
||||
@param replace_text : when not empty, a third button of that text
|
||||
which goes on and also replaces the elements left alone
|
||||
@return what the user chose
|
||||
*/
|
||||
RenumberPreviewDialog::Answer RenumberPreviewDialog::ask(
|
||||
QWidget *parent,
|
||||
const QString &title,
|
||||
const QString &intro,
|
||||
const QVector<RenumberElementsCommand::ElementChange> &changes,
|
||||
const QVector<LeftAlone> &left_alone,
|
||||
const QString &replace_text)
|
||||
{
|
||||
QDialog dialog(parent);
|
||||
dialog.setWindowTitle(title);
|
||||
dialog.resize(640, 460);
|
||||
auto *layout = new QVBoxLayout(&dialog);
|
||||
|
||||
const int changed = changedLabelCount(changes);
|
||||
QString text = intro;
|
||||
if (changes.size() > changed) {
|
||||
text += QLatin1Char('\n') + tr("%n élément(s) gardent le nom qu'ils ont.", "", changes.size() - changed);
|
||||
}
|
||||
if (!left_alone.isEmpty()) {
|
||||
text += QLatin1Char('\n') + tr("%n élément(s) restent comme ils sont.", "", left_alone.size());
|
||||
}
|
||||
auto *intro_label = new QLabel(text, &dialog);
|
||||
intro_label->setWordWrap(true);
|
||||
layout->addWidget(intro_label);
|
||||
|
||||
auto *table = new QTableWidget(&dialog);
|
||||
table->setColumnCount(4);
|
||||
table->setHorizontalHeaderLabels({tr("Folio"), tr("Élément"), tr("Nom actuel"), tr("Nouveau nom")});
|
||||
table->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
table->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
table->verticalHeader()->setVisible(false);
|
||||
table->horizontalHeader()->setStretchLastSection(true);
|
||||
table->setAlternatingRowColors(true);
|
||||
|
||||
const auto add_row = [table](const QStringList &cells, bool grey) {
|
||||
const int row = table->rowCount();
|
||||
table->insertRow(row);
|
||||
for (int column = 0 ; column < cells.size() ; ++column) {
|
||||
auto *item = new QTableWidgetItem(cells.at(column));
|
||||
if (grey) {
|
||||
QFont font = item->font();
|
||||
font.setItalic(true);
|
||||
item->setFont(font);
|
||||
item->setForeground(QBrush(Qt::gray));
|
||||
}
|
||||
table->setItem(row, column, item);
|
||||
}
|
||||
};
|
||||
|
||||
for (const auto &change : changes) {
|
||||
const QString before = labelOf(change.old_infos);
|
||||
const QString after = labelOf(change.new_infos);
|
||||
if (before != after) {
|
||||
add_row({folioOf(change.element),
|
||||
change.element ? change.element->name() : QString(),
|
||||
before, after}, false);
|
||||
}
|
||||
}
|
||||
for (const LeftAlone &left : left_alone) {
|
||||
if (left.element) {
|
||||
add_row({folioOf(left.element), left.element->name(),
|
||||
labelOf(left.element->elementInformations()), left.note}, true);
|
||||
}
|
||||
}
|
||||
table->resizeColumnsToContents();
|
||||
layout->addWidget(table, 1);
|
||||
|
||||
//With no label to change, OK would do nothing: only Cancel (and, where
|
||||
//there is one, the button which replaces what is left alone) is offered
|
||||
const bool something_to_do = !changes.isEmpty();
|
||||
auto *buttons = new QDialogButtonBox(
|
||||
something_to_do ? (QDialogButtonBox::Ok | QDialogButtonBox::Cancel)
|
||||
: QDialogButtonBox::Cancel, &dialog);
|
||||
Answer answer = Answer::Cancel;
|
||||
QPushButton *replace = nullptr;
|
||||
if (!replace_text.isEmpty()) {
|
||||
replace = buttons->addButton(replace_text, QDialogButtonBox::ActionRole);
|
||||
}
|
||||
QObject::connect(buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
|
||||
QObject::connect(buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
|
||||
if (replace) {
|
||||
QObject::connect(replace, &QPushButton::clicked, &dialog, [&]() {
|
||||
answer = Answer::GoAndReplace;
|
||||
dialog.accept();
|
||||
});
|
||||
}
|
||||
layout->addWidget(buttons);
|
||||
|
||||
if (dialog.exec() == QDialog::Accepted && answer != Answer::GoAndReplace) {
|
||||
answer = Answer::Go;
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief RenumberPreviewDialog::confirm
|
||||
@param intro : text above the list
|
||||
@param changes : what the operation would do to elements
|
||||
@param frozen : the elements it leaves as they are, a frozen label
|
||||
@return true if the user agrees to go on
|
||||
*/
|
||||
bool RenumberPreviewDialog::confirm(
|
||||
QWidget *parent,
|
||||
const QString &title,
|
||||
const QString &intro,
|
||||
const QVector<RenumberElementsCommand::ElementChange> &changes,
|
||||
const QVector<Element *> &frozen)
|
||||
{
|
||||
QVector<LeftAlone> left;
|
||||
for (Element *el : frozen) {
|
||||
left.append({el, tr("(figé)")});
|
||||
}
|
||||
return ask(parent, title, intro, changes, left) == Answer::Go;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
Copyright 2006-2026 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 RENUMBERPREVIEWDIALOG_H
|
||||
#define RENUMBERPREVIEWDIALOG_H
|
||||
|
||||
#include "../renumberelementscommand.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QVector>
|
||||
|
||||
class Element;
|
||||
class QWidget;
|
||||
|
||||
/**
|
||||
@brief The RenumberPreviewDialog class
|
||||
Shows what a numbering operation is about to do to the labels of
|
||||
elements -- each changed element with its label now and the one it
|
||||
would get -- and the elements with a frozen label it leaves as they are,
|
||||
and asks to go on or not. Nothing is changed by the dialog itself.
|
||||
*/
|
||||
class RenumberPreviewDialog
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(RenumberPreviewDialog)
|
||||
|
||||
public:
|
||||
/// An element an operation leaves as it is, and why
|
||||
struct LeftAlone
|
||||
{
|
||||
Element *element = nullptr;
|
||||
QString note;
|
||||
};
|
||||
enum class Answer { Cancel, Go, GoAndReplace };
|
||||
|
||||
static Answer ask(
|
||||
QWidget *parent,
|
||||
const QString &title,
|
||||
const QString &intro,
|
||||
const QVector<RenumberElementsCommand::ElementChange> &changes,
|
||||
const QVector<LeftAlone> &left_alone,
|
||||
const QString &replace_text = QString());
|
||||
|
||||
static bool confirm(
|
||||
QWidget *parent,
|
||||
const QString &title,
|
||||
const QString &intro,
|
||||
const QVector<RenumberElementsCommand::ElementChange> &changes,
|
||||
const QVector<Element *> &frozen);
|
||||
|
||||
static int changedLabelCount(
|
||||
const QVector<RenumberElementsCommand::ElementChange> &changes);
|
||||
};
|
||||
|
||||
#endif // RENUMBERPREVIEWDIALOG_H
|
||||
@@ -18,14 +18,17 @@
|
||||
#include "selectautonumw.h"
|
||||
|
||||
#include "../assignvariables.h"
|
||||
#include "../numerotationcontextcommands.h"
|
||||
#include "formulaautonumberingw.h"
|
||||
#include "numparteditorw.h"
|
||||
#include "ui_formulaautonumberingw.h"
|
||||
#include "ui_selectautonumw.h"
|
||||
|
||||
#include "../../qeticons.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QToolButton>
|
||||
|
||||
/**
|
||||
@brief SelectAutonumW::SelectAutonumW
|
||||
@@ -40,6 +43,24 @@ SelectAutonumW::SelectAutonumW(int type, QWidget *parent) :
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->m_comboBox->lineEdit()->setClearButtonEnabled(true);
|
||||
|
||||
//The add button goes under the last part, at the left; each part
|
||||
//has its own remove and move buttons at its right. The one remove
|
||||
//button above the parts, which could only remove the last one, is
|
||||
//not needed any more.
|
||||
ui->remove_button->hide();
|
||||
ui->horizontalLayout->removeWidget(ui->add_button);
|
||||
m_add_row = new QWidget(this);
|
||||
auto *add_layout = new QHBoxLayout(m_add_row);
|
||||
add_layout->setContentsMargins(0, 0, 0, 0);
|
||||
ui->add_button->setParent(m_add_row);
|
||||
add_layout->addWidget(ui->add_button);
|
||||
add_layout->addStretch();
|
||||
ui->editor_layout->addWidget(m_add_row);
|
||||
ui->buttonBox->button(QDialogButtonBox::Reset)->setText(tr("Annuler"));
|
||||
ui->buttonBox->button(QDialogButtonBox::Reset)->setToolTip(
|
||||
tr("Revenir à la définition enregistrée"));
|
||||
|
||||
if (m_edited_type == 0)
|
||||
{
|
||||
m_feaw = new FormulaAutonumberingW();
|
||||
@@ -104,35 +125,132 @@ void SelectAutonumW::setContext(const NumerotationContext &context)
|
||||
{
|
||||
m_context = context;
|
||||
|
||||
qDeleteAll(num_part_list_);
|
||||
num_part_list_.clear();
|
||||
clearPartRows();
|
||||
|
||||
if (m_context.size() == 0) { //@context contain nothing, build a default numPartEditor
|
||||
on_add_button_clicked();
|
||||
insertPartRow(new NumPartEditorW(m_edited_type, this));
|
||||
}
|
||||
else {
|
||||
for (int i=0; i<m_context.size(); ++i) { //build with the content of @context
|
||||
NumPartEditorW *part= new NumPartEditorW(m_context, i, m_edited_type, this);
|
||||
connect(part, &NumPartEditorW::changed, this, [this]() {
|
||||
m_dirty = true;
|
||||
applyEnable();
|
||||
emit contextEdited();
|
||||
});
|
||||
num_part_list_ << part;
|
||||
ui -> editor_layout -> addWidget(part);
|
||||
insertPartRow(new NumPartEditorW(m_context, i, m_edited_type, this));
|
||||
}
|
||||
}
|
||||
|
||||
num_part_list_.size() == 1 ?
|
||||
ui -> remove_button -> setDisabled(true):
|
||||
ui -> remove_button -> setEnabled (true);
|
||||
|
||||
updatePartButtons();
|
||||
applyEnable(false);
|
||||
//Everything the rule held before is read now, so nothing of it
|
||||
//is left to write: what is on show is what there is.
|
||||
m_dirty = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief SelectAutonumW::insertPartRow
|
||||
Show @p part as the last part of the definition, with the buttons which
|
||||
remove it and move it up or down at its right.
|
||||
*/
|
||||
void SelectAutonumW::insertPartRow(NumPartEditorW *part)
|
||||
{
|
||||
connect(part, &NumPartEditorW::changed, this, [this]() {
|
||||
m_dirty = true;
|
||||
applyEnable();
|
||||
emit contextEdited();
|
||||
});
|
||||
|
||||
PartRow r;
|
||||
r.part = part;
|
||||
r.row = new QWidget(this);
|
||||
auto *layout = new QHBoxLayout(r.row);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->setSpacing(2);
|
||||
part->setParent(r.row);
|
||||
layout->addWidget(part, 1);
|
||||
|
||||
const auto make_button = [&](const QIcon &icon, const QString &tip) {
|
||||
auto *button = new QToolButton(r.row);
|
||||
button->setIcon(icon);
|
||||
button->setToolTip(tip);
|
||||
button->setAutoRaise(true);
|
||||
layout->addWidget(button);
|
||||
return button;
|
||||
};
|
||||
r.up = make_button(QET::Icons::GoUp, tr("Monter cette variable"));
|
||||
r.down = make_button(QET::Icons::GoDown, tr("Descendre cette variable"));
|
||||
r.remove = make_button(QET::Icons::EditDelete, tr("Supprimer cette variable"));
|
||||
QWidget *row = r.row;
|
||||
connect(r.up, &QToolButton::clicked, this, [this, row]() { movePartRow(row, -1); });
|
||||
connect(r.down, &QToolButton::clicked, this, [this, row]() { movePartRow(row, +1); });
|
||||
connect(r.remove, &QToolButton::clicked, this, [this, row]() { removePartRow(row); });
|
||||
|
||||
m_rows << r;
|
||||
num_part_list_ << part;
|
||||
//Before the add button, which stays under the last part
|
||||
ui->editor_layout->insertWidget(ui->editor_layout->count() - 1, r.row);
|
||||
updatePartButtons();
|
||||
}
|
||||
|
||||
/// Take away every part of the definition shown
|
||||
void SelectAutonumW::clearPartRows()
|
||||
{
|
||||
for (const PartRow &r : std::as_const(m_rows)) {
|
||||
delete r.row; //with the part, which it holds
|
||||
}
|
||||
m_rows.clear();
|
||||
num_part_list_.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief SelectAutonumW::updatePartButtons
|
||||
The first part cannot move up, the last cannot move down, and the only
|
||||
one cannot be removed: those buttons are greyed out.
|
||||
*/
|
||||
void SelectAutonumW::updatePartButtons()
|
||||
{
|
||||
for (int i = 0 ; i < m_rows.size() ; ++i) {
|
||||
m_rows.at(i).up->setEnabled(i > 0);
|
||||
m_rows.at(i).down->setEnabled(i < m_rows.size() - 1);
|
||||
m_rows.at(i).remove->setEnabled(m_rows.size() > 1);
|
||||
}
|
||||
}
|
||||
|
||||
/// Remove the part shown in @p row; the definition keeps at least one
|
||||
void SelectAutonumW::removePartRow(QWidget *row)
|
||||
{
|
||||
if (m_rows.size() <= 1) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0 ; i < m_rows.size() ; ++i) {
|
||||
if (m_rows.at(i).row == row) {
|
||||
const PartRow r = m_rows.takeAt(i);
|
||||
num_part_list_.removeAll(r.part);
|
||||
delete r.row; //with the part, which it holds
|
||||
break;
|
||||
}
|
||||
}
|
||||
updatePartButtons();
|
||||
applyEnable();
|
||||
}
|
||||
|
||||
/// Move the part shown in @p row up (-1) or down (+1)
|
||||
void SelectAutonumW::movePartRow(QWidget *row, int step)
|
||||
{
|
||||
for (int i = 0 ; i < m_rows.size() ; ++i) {
|
||||
if (m_rows.at(i).row != row) {
|
||||
continue;
|
||||
}
|
||||
const int to = i + step;
|
||||
if (to < 0 || to >= m_rows.size()) {
|
||||
return;
|
||||
}
|
||||
m_rows.swapItemsAt(i, to);
|
||||
num_part_list_.swapItemsAt(i, to);
|
||||
ui->editor_layout->removeWidget(row);
|
||||
ui->editor_layout->insertWidget(1 + to, row); //after the header of the columns
|
||||
break;
|
||||
}
|
||||
updatePartButtons();
|
||||
applyEnable();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief SelectAutonumW::toNumContext
|
||||
@return the content to num_part_list to NumerotationContext
|
||||
@@ -151,17 +269,10 @@ NumerotationContext SelectAutonumW::toNumContext() const
|
||||
*/
|
||||
void SelectAutonumW::on_add_button_clicked()
|
||||
{
|
||||
applyEnable(false);
|
||||
insertPartRow(new NumPartEditorW(m_edited_type, this));
|
||||
m_dirty = true;
|
||||
NumPartEditorW *part = new NumPartEditorW(m_edited_type, this);
|
||||
connect(part, &NumPartEditorW::changed, this, [this]() {
|
||||
m_dirty = true;
|
||||
applyEnable();
|
||||
emit contextEdited();
|
||||
});
|
||||
num_part_list_ << part;
|
||||
ui -> editor_layout -> addWidget(part);
|
||||
ui -> remove_button -> setEnabled(true);
|
||||
applyEnable();
|
||||
emit contextEdited();
|
||||
}
|
||||
|
||||
@@ -174,9 +285,7 @@ void SelectAutonumW::on_remove_button_clicked()
|
||||
//remove if @num_part_list contains more than one item
|
||||
if (num_part_list_.size() > 1) {
|
||||
m_dirty = true;
|
||||
NumPartEditorW *part = num_part_list_.takeLast();
|
||||
// deliberately not disconnecting as not possible to resolve with lambda and will happen automatically when the object "part" is destroyed.
|
||||
delete part;
|
||||
removePartRow(m_rows.last().row);
|
||||
if (num_part_list_.size() == 1) {
|
||||
ui -> remove_button -> setDisabled(true);
|
||||
}
|
||||
@@ -409,6 +518,8 @@ void SelectAutonumW::on_buttonBox_clicked(QAbstractButton *button)
|
||||
*/
|
||||
void SelectAutonumW::applyEnable(bool b)
|
||||
{
|
||||
//Apply and Cancel both stand for a change: grey until there is one
|
||||
ui->buttonBox->button(QDialogButtonBox::Reset)->setEnabled(b);
|
||||
if (b){
|
||||
bool valid= true;
|
||||
foreach (NumPartEditorW *npe, num_part_list_)
|
||||
@@ -448,28 +559,6 @@ void SelectAutonumW::contextToFormula()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@brief SelectAutonumW::on_m_next_pb_clicked
|
||||
Increase NumerotationContext
|
||||
*/
|
||||
void SelectAutonumW::on_m_next_pb_clicked()
|
||||
{
|
||||
NumerotationContextCommands ncc (toNumContext());
|
||||
setContext(ncc.next());
|
||||
applyEnable(true);
|
||||
}
|
||||
|
||||
/**
|
||||
@brief SelectAutonumW::on_m_previous_pb_clicked
|
||||
Decrease NumerotationContext
|
||||
*/
|
||||
void SelectAutonumW::on_m_previous_pb_clicked()
|
||||
{
|
||||
NumerotationContextCommands ncc (toNumContext());
|
||||
setContext(ncc.previous());
|
||||
applyEnable(true);
|
||||
}
|
||||
|
||||
void SelectAutonumW::on_m_comboBox_currentTextChanged(const QString &arg1)
|
||||
{
|
||||
Q_UNUSED(arg1);
|
||||
@@ -480,3 +569,29 @@ void SelectAutonumW::on_m_remove_pb_clicked()
|
||||
{
|
||||
emit removeClicked();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief SelectAutonumW::setExplicitNaming
|
||||
Make the list of numberings a plain choice: no typing a name into it
|
||||
(an easy way to create a numbering by accident, or one with an empty
|
||||
name), but a button to create a numbering and one to rename the shown
|
||||
one, which emit newClicked() and renameClicked() for the owner to ask
|
||||
for the name.
|
||||
*/
|
||||
void SelectAutonumW::setExplicitNaming()
|
||||
{
|
||||
ui->m_comboBox->setEditable(false);
|
||||
auto *row = ui->horizontalLayout_2;
|
||||
const int index = row->indexOf(ui->m_remove_pb);
|
||||
|
||||
auto *new_pb = new QPushButton(QET::Icons::Add, QString(), this);
|
||||
new_pb->setToolTip(tr("Nouvelle numérotation…"));
|
||||
connect(new_pb, &QPushButton::clicked, this, &SelectAutonumW::newClicked);
|
||||
|
||||
auto *rename_pb = new QPushButton(QET::Icons::EditRename, QString(), this);
|
||||
rename_pb->setToolTip(tr("Renommer la numérotation…"));
|
||||
connect(rename_pb, &QPushButton::clicked, this, &SelectAutonumW::renameClicked);
|
||||
|
||||
row->insertWidget(index, rename_pb);
|
||||
row->insertWidget(index, new_pb);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ class QAbstractButton;
|
||||
class FormulaAutonumberingW;
|
||||
class QComboBox;
|
||||
class QPushButton;
|
||||
class QToolButton;
|
||||
class QHBoxLayout;
|
||||
|
||||
namespace Ui {
|
||||
class SelectAutonumW;
|
||||
@@ -89,6 +91,7 @@ class SelectAutonumW : public QWidget
|
||||
@param can_remove true when a rule is really there
|
||||
*/
|
||||
void setRuleRemovable(bool can_remove);
|
||||
void setExplicitNaming();
|
||||
|
||||
signals:
|
||||
void applyPressed();
|
||||
@@ -101,6 +104,9 @@ class SelectAutonumW : public QWidget
|
||||
write now.
|
||||
*/
|
||||
void contextEdited();
|
||||
/// Only with setExplicitNaming()
|
||||
void newClicked();
|
||||
void renameClicked();
|
||||
|
||||
//SLOT
|
||||
private slots:
|
||||
@@ -108,16 +114,30 @@ class SelectAutonumW : public QWidget
|
||||
void on_remove_button_clicked();
|
||||
void on_buttonBox_clicked(QAbstractButton *);
|
||||
void applyEnable (bool = true);
|
||||
void on_m_next_pb_clicked();
|
||||
void on_m_previous_pb_clicked();
|
||||
void on_m_comboBox_currentTextChanged(const QString &arg1);
|
||||
|
||||
//ATTRIBUTES
|
||||
void on_m_remove_pb_clicked();
|
||||
|
||||
|
||||
private:
|
||||
/// A part of the definition, with the buttons at its right
|
||||
struct PartRow
|
||||
{
|
||||
QWidget *row = nullptr;
|
||||
NumPartEditorW *part = nullptr;
|
||||
QToolButton *up = nullptr;
|
||||
QToolButton *down = nullptr;
|
||||
QToolButton *remove = nullptr;
|
||||
};
|
||||
void insertPartRow(NumPartEditorW *part);
|
||||
void removePartRow(QWidget *row);
|
||||
void movePartRow(QWidget *row, int step);
|
||||
void updatePartButtons();
|
||||
void clearPartRows();
|
||||
Ui::SelectAutonumW *ui;
|
||||
QList <NumPartEditorW *> num_part_list_;
|
||||
QList <PartRow> m_rows;
|
||||
QWidget *m_add_row = nullptr; ///< holds the add button, under the last part
|
||||
NumerotationContext m_context;
|
||||
FormulaAutonumberingW *m_feaw;
|
||||
FormulaAutonumberingW *m_fcaw;
|
||||
|
||||
@@ -63,8 +63,7 @@
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="edit-delete" resource="../../../qelectrotech.qrc">
|
||||
<normaloff>:/ico/16x16/edit-delete.png</normaloff>:/ico/16x16/edit-delete.png</iconset>
|
||||
<iconset theme="edit-delete"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -136,8 +135,7 @@
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="list-remove" resource="../../../qelectrotech.qrc">
|
||||
<normaloff>:/ico/22x22/list-remove.png</normaloff>:/ico/22x22/list-remove.png</iconset>
|
||||
<iconset theme="list-remove"/>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
@@ -153,42 +151,13 @@
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="list-add" resource="../../../qelectrotech.qrc">
|
||||
<normaloff>:/ico/22x22/list-add.png</normaloff>:/ico/22x22/list-add.png</iconset>
|
||||
<iconset theme="list-add"/>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="m_previous_pb">
|
||||
<property name="toolTip">
|
||||
<string>Précédent</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="arrow-left" resource="../../../qelectrotech.qrc">
|
||||
<normaloff>:/ico/16x16/arrow-left.png</normaloff>:/ico/16x16/arrow-left.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="m_next_pb">
|
||||
<property name="toolTip">
|
||||
<string>Suivant</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="arrow-right" resource="../../../qelectrotech.qrc">
|
||||
<normaloff>:/ico/16x16/arrow-right.png</normaloff>:/ico/16x16/arrow-right.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
@@ -232,6 +201,9 @@
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="value_label">
|
||||
<property name="toolTip">
|
||||
<string>Pour un numéro : le prochain numéro attribué. Pour un texte : le texte fixe.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Valeur</string>
|
||||
</property>
|
||||
|
||||
Reference in New Issue
Block a user