Compare commits

...

19 Commits

Author SHA1 Message Date
Laurent Trinques 3eafe840f1 Merge pull request #656 from ispyisail/feature-last-used-style
Remember last-used shape/text style for new items this session
2026-08-08 14:22:52 +02:00
Laurent Trinques e38493c308 Merge pull request #697 from ispyisail/feature/autonum-inline-increment
Edit increment and preview the next number in the auto-numbering dock (bugtracker #331)
2026-08-08 13:53:23 +02:00
Laurent Trinques 5abf890b24 Merge pull request #695 from ispyisail/fix/dark-theme-element-icons-bug335
Fix invisible element icons on dark themes in two dialogs missed by the earlier fix (bugtracker #335)
2026-08-08 13:50:36 +02:00
Laurent Trinques 037d5a13cd Merge pull request #696 from ispyisail/fix/current-date-preset-bug308
Fix "use current date" preset lost unless the Folio tab is active on save (bugtracker #308)
2026-08-08 13:45:48 +02:00
ispyisail cd7388985e Edit increment and preview the next number in the auto-numbering dock
Bug #331: "Il serait intéressant de pouvoir directement dans la fenêtre
'Sélection numérotation auto' modifier la valeur d'incrément et visualiser
la prochaine numérotation qui sera appliquée. Ceci sans être obligé
d'ouvrir la page de configuration."

The dock (AutoNumberingDockWidget) already let you see and edit a rule's
*current* value inline (added in 52c8ef6b4/031710b5f/ee4ba82d2). The
increment itself, and any preview of where the numbering is headed, was
reachable only through Configurer -> the full project-properties dialog.

Two new widgets per row (conductor/element/folio):

- An increment spin box, read from and written to the same NumerotationContext
  field NumPartEditorW's increase_spinBox already edits in the full dialog --
  same data, second place to reach it.
- A read-only next-value field, computed via
  NumerotationContextCommands::next() -- the identical engine the "Suivant"
  button in the full dialog already uses to step a whole context. Reusing it
  rather than reimplementing the arithmetic means wrap-and-carry between parts
  comes out identical to what actually happens when the number is next
  consumed, and zero-padding matches real rendering
  (NumerotationContext::formatValue(), mirroring
  autonum::setSequentialToList()'s padding rule by hand since that function is
  local to assignvariables.cpp).

NumerotationContext gains replaceIncrease(index, increase), a sibling to the
existing replaceValue() that touches only the increment field.

Every refresh call site in the file (13 of them) previously refreshed just the
value field; they now go through a new refreshRow(category), which refreshes
value + increment + next-value-preview together via a small per-row widget
bundle (rowFor()). This also let resetAutoNum()'s three-way switch collapse to
one line, and refreshValueFields()'s three near-identical blocks collapse to a
loop -- both existing before this change, not new here.

Verified live under Xvfb: created an element numbering rule "K" (Chiffre 1,
value 1, increment 1) via the full dialog, confirmed the dock showed
Valeur=1/Incrément=1/Suivant=2. Changed the dock's own Incrément to 3 --
Suivant updated live to 4, no dialog needed. Changed Valeur to 10 -- Suivant
became 13. Reopened the full configuration dialog and confirmed it read back
the same value_field=10/increase_spinBox=3, i.e. the round trip through
replaceIncrease()/storeContext() does not disturb type, initial value, modulus
or format.

Builds clean, CMake/Ninja Release, Qt 5.15, 820/820, no new warnings.

Fixes: https://qelectrotech.org/bugtracker/view.php?id=331

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 23:10:54 +12:00
ispyisail 5ba08284f5 Fix "use current date" preset being lost unless the Folio tab is active on save
Bugtracker #308: the "current date" preset for a project's default
title block doesn't persist. A later comment on the report pinpointed
it exactly: the setting falls back to "No date" unless the folio tab
remains active when saving settings, and the same happens in Project
Properties.

TitleBlockPropertiesWidget::properties() (and its near-duplicate
sibling propertiesAutoNum(), copy-pasted with the same bug) reads the
date radio buttons like this:

    else if (ui->m_current_date_rb->isVisible() && ui->m_current_date_rb->isChecked()) {
        prop.useDate = TitleBlockProperties::CurrentDate;
        ...

Both the New Project settings page and Project Properties embed this
widget as one page of a QTabWidget (NewDiagramPage, in
configpage/configpages.cpp). QWidget::isVisible() depends on the
whole ancestor chain being visible, not just the widget's own state --
switch to any other tab before clicking OK/Apply and this radio
button's isVisible() goes false even though it's still checked
underneath, silently falling through all three branches. The function
returns a default-constructed TitleBlockProperties for the date
fields (useDate = UseDateValue, date = QDate(), i.e. "no date"),
matching exactly what was reported.

Fix: use isHidden() instead, which reflects only this widget's own
explicit state and mirrors the read side's own check in
setProperties()/initDialog() just above it in the same file -- that
side already uses isHidden(), not isVisible(), for the identical
"is the current-date option even offered here" question.

Verified directly: a standalone Qt program constructing the real
NewDiagramPage, checking "current date", switching the tab widget
away from Folio to Conducteur (reproducing the report's exact
trigger), then calling applyConf() and reading back the QSettings
value. Against the original code this saves date="null"; with the
fix, date="now" -- the same scenario, same tab switch, only the one
line differs. Also confirmed a full Release build (504/504, CMake/
Ninja, Qt 5.15.18) with no new warnings.
2026-08-08 23:02:07 +12:00
ispyisail bab5bf58f8 Fix invisible element icons on dark themes in Open/Save Element and New Element Wizard dialogs
Bugtracker #335: element library icons are black and nearly invisible
under a dark desktop theme (reported on KDE Plasma / Fedora 43).

The main elements panel (ElementsCollectionWidget) already forces a
fixed light palette on its tree views via ElementsTreeView, added in
a8e2a7acf and completed in bb61dde81 -- element icons are rendered
with colors read from each .elmt file (almost always black linework,
matching printed-schematic convention) onto a transparent
background, so any view showing them needs to stay light regardless
of the OS theme. ElementsTreeView's own class doc already says
"This class must be used when the tree view have an
ElementsCollectionModel as model" -- but two other dialogs showing
the exact same model were still using a plain QTreeView and missed
that fix: the Open/Save Element/Category/Template dialog
(ElementDialog) and the New Element Wizard's parent-category picker
(NewElementWizard). Same underlying ElementsCollectionModel, same
black-on-transparent icons, same invisibility on a dark theme.

Fix: use ElementsTreeView in both, matching the main panel and the
class's own documented contract. No other behavior changes --
ElementsTreeView only additionally overrides startDrag() to use a
nicer drag pixmap, which is inert unless drag-out is enabled.

Verified with a full Release build (504/504, no new warnings) and a
standalone Qt program that shows the real ElementDialog under a
forced dark QPalette (simulating a dark OS theme, since neither this
build environment nor QET itself forces the palette one way or the
other): screenshots down through nested collection categories
(Electric > IEC 60617 > Conductors and connecting devices) confirm
the tree view keeps a white background against the dark dialog
chrome around it.
2026-08-08 21:53:20 +12:00
Laurent Trinques fca945f90e Merge pull request #624 from ispyisail/feature-window-modified-indicator
Show unsaved-changes state in the main window title (macOS modified dot)
2026-08-08 11:50:46 +02:00
Laurent Trinques d2b2a2eadb Update translations files 2026-08-08 10:23:06 +02:00
Laurent Trinques e5e2f2efbd Merge pull request #673 from Kellermorph/show-terminal-names-export
show terminalnames in export
2026-08-08 10:04:55 +02:00
Laurent Trinques 5c39518921 drop one dead member 2026-08-08 08:14:06 +02:00
Kellermorph 6d2995ad68 set to false 2026-08-08 08:09:45 +02:00
Laurent Trinques 1198cf73a9 Update translations files 2026-08-08 07:23:17 +02:00
Laurent Trinques e8f80697f3 Reapply "Auto-break conductor"
This reverts commit 905afc1bbc.
2026-08-08 07:03:50 +02:00
Kellermorph 57d0b4b5a3 fix whitespace 2026-08-07 13:48:40 +02:00
Kellermorph b3a4a41ad9 new Checkbox 2026-08-06 21:37:40 +02:00
Kellermorph 979df376d1 show terminalnames in export 2026-08-06 12:48:11 +02:00
ispyisail 29ba7c9636 Remember last-used shape/text style for new items this session
Drawing tools on the diagram canvas always started new shapes and free
text from a fixed hardcoded default (Qt's plain QPen()/QBrush(), and
the static Preferences font) -- changing a shape's color or a text's
font had zero effect on what the next new item of that type got, even
within the same editing session.

Add LastUsedStyle: a small in-memory, session-scoped static helper
(no QSettings, no persistence across restarts -- this is a live "what
did I just use" value, not a new app-wide default). Write side hooks
capture the value right where the properties editors already apply a
change (ShapeGraphicsItemPropertiesWidget::associatedUndo(), both the
live-edit dock path and the modal editProperty() dialog path; and
IndiTextPropertiesWidget::on_m_font_pb_clicked() right after the font
dialog returns). Read side hooks apply the stored value, if any, to a
newly created item: DiagramEventAddShape::mousePressEvent for shapes,
IndependentTextItem's constructor for free text (falling back to the
existing QETApp::indiTextsItemFont() Preferences default otherwise).

Doesn't touch the element/symbol editor's own drawing tools (a
separate subsystem) or add last-used text color (no color control
exists in the text properties UI to originate it from yet).
2026-08-04 10:32:25 +12:00
ispyisail 76fda3f0e6 Reflect unsaved-changes state in the main window title
On macOS in particular there's currently no way to tell from the window
chrome alone whether the active project has unsaved changes. The main
window's title is set once in the constructor to a static string and
never updated afterward, and QET never sets Qt's windowModified
property anywhere -- so the native "document modified" indicator
(the dot in the close button on macOS; an asterisk in the title on
platforms that render it as text) never appears.

Add QETDiagramEditor::updateWindowModifiedState(), which sets the
window title to "<project>[*] - QElectroTech" (the "[*]" is Qt's own
placeholder convention for this) and calls setWindowModified() with
the active project's own modified flag. Call it from two places:

- subWindowActivated(), the single existing choke point already used
  whenever the visible MDI tab changes, so switching projects
  immediately reflects the newly active one's own state.
- A new per-project connection to QETProject::projectModified, added
  in addProject() alongside the existing undo-stack registration,
  filtered to only act when the modified project is the currently
  active one.

With no project open, the title and modified flag both revert to the
original static, unmodified state.

Implements https://github.com/qelectrotech/qelectrotech-source-mirror/discussions/596
2026-08-02 07:30:14 +12:00
63 changed files with 10096 additions and 7826 deletions
+2
View File
@@ -215,6 +215,8 @@ set(QET_SRC_FILES
${QET_DIR}/sources/exportpropertieswidget.h
${QET_DIR}/sources/genericpanel.cpp
${QET_DIR}/sources/genericpanel.h
${QET_DIR}/sources/lastusedstyle.cpp
${QET_DIR}/sources/lastusedstyle.h
${QET_DIR}/sources/machine_info.cpp
${QET_DIR}/sources/machine_info.h
${QET_DIR}/sources/main.cpp
+299 -257
View File
File diff suppressed because it is too large Load Diff
+292 -250
View File
File diff suppressed because it is too large Load Diff
+293 -251
View File
File diff suppressed because it is too large Load Diff
+293 -251
View File
File diff suppressed because it is too large Load Diff
+293 -251
View File
File diff suppressed because it is too large Load Diff
+292 -250
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+293 -251
View File
File diff suppressed because it is too large Load Diff
+292 -250
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+293 -251
View File
File diff suppressed because it is too large Load Diff
+292 -250
View File
File diff suppressed because it is too large Load Diff
+292 -250
View File
File diff suppressed because it is too large Load Diff
+292 -250
View File
File diff suppressed because it is too large Load Diff
+292 -250
View File
File diff suppressed because it is too large Load Diff
+293 -251
View File
File diff suppressed because it is too large Load Diff
+293 -251
View File
File diff suppressed because it is too large Load Diff
+293 -251
View File
File diff suppressed because it is too large Load Diff
+293 -251
View File
File diff suppressed because it is too large Load Diff
+292 -250
View File
File diff suppressed because it is too large Load Diff
+293 -251
View File
File diff suppressed because it is too large Load Diff
+292 -250
View File
File diff suppressed because it is too large Load Diff
+293 -251
View File
File diff suppressed because it is too large Load Diff
+292 -250
View File
File diff suppressed because it is too large Load Diff
+292 -250
View File
File diff suppressed because it is too large Load Diff
+292 -250
View File
File diff suppressed because it is too large Load Diff
+293 -251
View File
File diff suppressed because it is too large Load Diff
+292 -250
View File
File diff suppressed because it is too large Load Diff
+292 -250
View File
File diff suppressed because it is too large Load Diff
+292 -250
View File
File diff suppressed because it is too large Load Diff
+293 -251
View File
File diff suppressed because it is too large Load Diff
+292 -250
View File
File diff suppressed because it is too large Load Diff
+293 -251
View File
File diff suppressed because it is too large Load Diff
+45
View File
@@ -220,6 +220,24 @@ void NumerotationContext::replaceValue(int index, QString content) {
content_[index] = type + "|" + value + "|" + increase + "|" + initvalue + "|" + modulus + "|" + format;
}
/**
@brief NumerotationContext::replaceIncrease
Change how much this part advances per step, leaving its current value,
initial value, modulus and format untouched. Sibling to replaceValue(),
which deliberately never touches this field.
@param index of NC item
@param increase new increase for that item
*/
void NumerotationContext::replaceIncrease(int index, int increase) {
QStringList strl = content_[index].split("|");
QString type = strl.at(0);
QString value = strl.at(1);
QString initvalue = strl.at(3);
QString modulus = strl.size() > 4 ? strl.at(4) : QStringLiteral("0");
QString format = strl.size() > 5 ? strl.at(5) : QString();
content_[index] = type + "|" + value + "|" + QString::number(increase) + "|" + initvalue + "|" + modulus + "|" + format;
}
/**
@brief NumerotationContext::formatOf
@param item : a context item as returned by itemAt()
@@ -230,3 +248,30 @@ QString NumerotationContext::formatOf(const QStringList &item)
{
return item.size() > 5 ? item.at(5) : QString();
}
/**
@brief NumerotationContext::formatValue
@param item : a context item as returned by itemAt()
@return the part's value, zero-padded exactly as
autonum::setSequentialToList() pads it when composing a real label: an
explicit format mask wins, then "ten"/"hundred" parts get their
implicit 2/3-digit width, "alpha" is used as-is, everything else is a
plain number. Kept in step with that function by hand since the two
cannot share code without exposing an assignvariables.cpp-local helper.
*/
QString NumerotationContext::formatValue(const QStringList &item)
{
const QString &type = item.at(0);
const QString &value = item.at(1);
if (type == QLatin1String("alpha"))
return value;
const QString mask = formatOf(item);
if (!mask.isEmpty())
return QString("%1").arg(value.toInt(), mask.length(), 10, QChar('0'));
if (type == QLatin1String("ten") || type == QLatin1String("tenfolio"))
return QString("%1").arg(value.toInt(), 2, 10, QChar('0'));
if (type == QLatin1String("hundred") || type == QLatin1String("hundredfolio"))
return QString("%1").arg(value.toInt(), 3, 10, QChar('0'));
return QString::number(value.toInt());
}
+5
View File
@@ -54,6 +54,11 @@ class NumerotationContext
QDomElement toXml(QDomDocument &, const QString&);
void fromXml(QDomElement &);
void replaceValue(int, QString);
void replaceIncrease(int, int);
/// Zero-pad a part's value the same way the real numbering engine
/// does (autonum::setSequentialToList in assignvariables.cpp), so a
/// UI preview of a part's value matches what actually gets rendered.
static QString formatValue(const QStringList &item);
private:
QStringList content_;
+166 -25
View File
@@ -24,10 +24,13 @@
#include "../../titleblockproperties.h"
#include "../../ui/projectpropertiesdialog.h"
#include "../numerotationcontext.h"
#include "../numerotationcontextcommands.h"
#include "ui_autonumberingdockwidget.h"
#include <QComboBox>
#include <QLineEdit>
#include <QSignalBlocker>
#include <QSpinBox>
/**
@brief AutoNumberingDockWidget::AutoNumberingDockWidget
@@ -64,6 +67,29 @@ void AutoNumberingDockWidget::clear()
ui->m_conductor_value_le->clear();
ui->m_element_value_le->clear();
ui->m_folio_value_le->clear();
ui->m_conductor_next_le->clear();
ui->m_element_next_le->clear();
ui->m_folio_next_le->clear();
}
/**
@brief AutoNumberingDockWidget::rowFor
@return the combo/value/increase/next widgets that make up category's row.
*/
AutoNumberingDockWidget::Row AutoNumberingDockWidget::rowFor(AutoNumCategory category) const
{
switch (category) {
case AutoNumCategory::Conductor:
return {ui->m_conductor_cb, ui->m_conductor_value_le,
ui->m_conductor_increase_sb, ui->m_conductor_next_le};
case AutoNumCategory::Element:
return {ui->m_element_cb, ui->m_element_value_le,
ui->m_element_increase_sb, ui->m_element_next_le};
case AutoNumCategory::Folio:
return {ui->m_folio_cb, ui->m_folio_value_le,
ui->m_folio_increase_sb, ui->m_folio_next_le};
}
return {nullptr, nullptr, nullptr, nullptr};
}
void AutoNumberingDockWidget::projectClosed()
@@ -201,9 +227,9 @@ void AutoNumberingDockWidget::setContext()
//The combo boxes have just been repopulated, so the value fields next
//to them are showing whatever the previous project left there.
refreshValueField(ui->m_conductor_cb, ui->m_conductor_value_le, AutoNumCategory::Conductor);
refreshValueField(ui->m_element_cb, ui->m_element_value_le, AutoNumCategory::Element);
refreshValueField(ui->m_folio_cb, ui->m_folio_value_le, AutoNumCategory::Folio);
refreshRow(AutoNumCategory::Conductor);
refreshRow(AutoNumCategory::Element);
refreshRow(AutoNumCategory::Folio);
this->setActive();
}
@@ -279,7 +305,7 @@ void AutoNumberingDockWidget::on_m_conductor_cb_activated(int)
m_project->setCurrentConductorAutoNum(current_autonum);
m_project_view->currentDiagram()->diagram()->setConductorsAutonumName(current_autonum);
m_project_view->currentDiagram()->diagram()->loadCndFolioSeq();
refreshValueField(ui->m_conductor_cb, ui->m_conductor_value_le, AutoNumCategory::Conductor);
refreshRow(AutoNumCategory::Conductor);
}
/**
@@ -308,7 +334,7 @@ void AutoNumberingDockWidget::on_m_element_cb_activated(int)
{
m_project->setCurrrentElementAutonum(ui->m_element_cb->currentText());
m_project_view->currentDiagram()->diagram()->loadElmtFolioSeq();
refreshValueField(ui->m_element_cb, ui->m_element_value_le, AutoNumCategory::Element);
refreshRow(AutoNumCategory::Element);
}
/**
@@ -346,7 +372,7 @@ void AutoNumberingDockWidget::on_m_folio_cb_activated(int) {
m_project->setDefaultTitleBlockProperties(ip);
}
emit(folioAutoNumChanged(current_autonum));
refreshValueField(ui->m_folio_cb, ui->m_folio_value_le, AutoNumCategory::Folio);
refreshRow(AutoNumCategory::Folio);
}
void AutoNumberingDockWidget::on_m_configure_pb_clicked()
@@ -389,6 +415,21 @@ void AutoNumberingDockWidget::on_m_folio_value_le_editingFinished()
applyValueField(ui->m_folio_cb, ui->m_folio_value_le, AutoNumCategory::Folio);
}
void AutoNumberingDockWidget::on_m_conductor_increase_sb_valueChanged(int)
{
applyIncreaseField(ui->m_conductor_cb, ui->m_conductor_increase_sb, AutoNumCategory::Conductor);
}
void AutoNumberingDockWidget::on_m_element_increase_sb_valueChanged(int)
{
applyIncreaseField(ui->m_element_cb, ui->m_element_increase_sb, AutoNumCategory::Element);
}
void AutoNumberingDockWidget::on_m_folio_increase_sb_valueChanged(int)
{
applyIncreaseField(ui->m_folio_cb, ui->m_folio_increase_sb, AutoNumCategory::Folio);
}
/**
@brief AutoNumberingDockWidget::contextFor
@return the numerotation context named by combo_box, for category
@@ -455,17 +496,21 @@ int AutoNumberingDockWidget::counterIndex(const NumerotationContext &context)
*/
void AutoNumberingDockWidget::refreshValueFields()
{
//Leave alone a field the user is typing in: numbering an element
//refreshes all three, and overwriting a half-typed value under the
//cursor is worse than showing it a moment out of date. Only this
//automatic path skips; an explicit refresh after a reset or an edit
//still writes, so the field always ends up canonical.
if (!ui->m_conductor_value_le->hasFocus())
refreshValueField(ui->m_conductor_cb, ui->m_conductor_value_le, AutoNumCategory::Conductor);
if (!ui->m_element_value_le->hasFocus())
refreshValueField(ui->m_element_cb, ui->m_element_value_le, AutoNumCategory::Element);
if (!ui->m_folio_value_le->hasFocus())
refreshValueField(ui->m_folio_cb, ui->m_folio_value_le, AutoNumCategory::Folio);
//Leave alone a row the user is typing in: numbering an element
//refreshes all three rows, and overwriting a half-typed value or
//increment under the cursor is worse than showing it a moment out
//of date. Only this automatic path skips; an explicit refresh after
//a reset or an edit still writes, so the row always ends up
//canonical. The next-value preview has no such guard: it is
//read-only, so there is nothing a refresh could clobber.
for (AutoNumCategory category : {AutoNumCategory::Conductor,
AutoNumCategory::Element,
AutoNumCategory::Folio})
{
const Row row = rowFor(category);
if (!row.value->hasFocus() && !row.increase->hasFocus())
refreshRow(category);
}
}
/**
@@ -507,13 +552,114 @@ void AutoNumberingDockWidget::applyValueField(QComboBox *combo_box, QLineEdit *l
const QString typed = line_edit->text();
if (typed.isEmpty() || typed == context.itemAt(index).at(1))
{
refreshValueField(combo_box, line_edit, category);
refreshRow(category);
return;
}
context.replaceValue(index, typed);
storeContext(combo_box, category, context);
refreshValueField(combo_box, line_edit, category);
refreshRow(category);
}
/**
@brief AutoNumberingDockWidget::refreshIncreaseField
Show the counter's current step size (bug #331: previously only
reachable from the full configuration dialog, via "Configurer").
*/
void AutoNumberingDockWidget::refreshIncreaseField(QComboBox *combo_box, QSpinBox *increase_sb, AutoNumCategory category)
{
//QSpinBox::setValue() emits valueChanged() even when called
//programmatically. Without blocking it, this refresh would
//immediately re-trigger on_..._increase_sb_valueChanged() ->
//applyIncreaseField() -> storeContext() -> the project's
//autoNumContextUpdated signal -> refreshValueFields() -> back here.
const QSignalBlocker blocker(increase_sb);
if (!m_project || combo_box->currentText().isEmpty())
{
increase_sb->setEnabled(false);
increase_sb->setValue(increase_sb->minimum());
return;
}
const NumerotationContext context = contextFor(combo_box, category);
const int index = counterIndex(context);
increase_sb->setEnabled(index >= 0);
increase_sb->setValue(index >= 0 ? context.itemAt(index).at(2).toInt()
: increase_sb->minimum());
}
/**
@brief AutoNumberingDockWidget::applyIncreaseField
Write the spin box's step size to the counter it displays (bug #331).
*/
void AutoNumberingDockWidget::applyIncreaseField(QComboBox *combo_box, QSpinBox *increase_sb, AutoNumCategory category)
{
if (!m_project || combo_box->currentText().isEmpty())
return;
NumerotationContext context = contextFor(combo_box, category);
const int index = counterIndex(context);
if (index < 0)
return;
if (increase_sb->value() == context.itemAt(index).at(2).toInt())
return;
context.replaceIncrease(index, increase_sb->value());
storeContext(combo_box, category, context);
refreshRow(category);
}
/**
@brief AutoNumberingDockWidget::refreshNextField
Show what this counter will read after one more step (bug #331: "visualiser
la prochaine numérotation qui sera appliquée"). Advances a copy of the
whole context through NumerotationContextCommands -- the same engine the
Suivant button in the full configuration dialog uses to step a context --
so wrap-and-carry into this part from a following part, or out of it into
a preceding one, comes out identical to what will actually happen when the
number is next consumed.
*/
void AutoNumberingDockWidget::refreshNextField(QComboBox *combo_box, QLineEdit *next_edit, AutoNumCategory category)
{
if (!m_project || combo_box->currentText().isEmpty())
{
next_edit->clear();
next_edit->setEnabled(false);
return;
}
const NumerotationContext context = contextFor(combo_box, category);
const int index = counterIndex(context);
if (index < 0)
{
next_edit->clear();
next_edit->setEnabled(false);
return;
}
Diagram *diagram = (m_project_view && m_project_view->currentDiagram())
? m_project_view->currentDiagram()->diagram()
: nullptr;
NumerotationContextCommands ncc(context, diagram);
const NumerotationContext next_context = ncc.next();
next_edit->setEnabled(true);
next_edit->setText(NumerotationContext::formatValue(next_context.itemAt(index)));
}
/**
@brief AutoNumberingDockWidget::refreshRow
Refresh a category's value, increment and next-value preview together --
every call site that used to refresh just the value field needs the
other two kept in step with it as well.
*/
void AutoNumberingDockWidget::refreshRow(AutoNumCategory category)
{
const Row row = rowFor(category);
refreshValueField(row.combo, row.value, category);
refreshIncreaseField(row.combo, row.increase, category);
refreshNextField(row.combo, row.next, category);
}
/**
@@ -557,10 +703,5 @@ void AutoNumberingDockWidget::resetAutoNum(QComboBox *combo_box, AutoNumCategory
}
storeContext(combo_box, category, context);
switch (category) {
case AutoNumCategory::Conductor: refreshValueField(combo_box, ui->m_conductor_value_le, category); break;
case AutoNumCategory::Element: refreshValueField(combo_box, ui->m_element_value_le, category); break;
case AutoNumCategory::Folio: refreshValueField(combo_box, ui->m_folio_value_le, category); break;
}
refreshRow(category);
}
@@ -25,6 +25,7 @@
class QComboBox;
class QLineEdit;
class QSpinBox;
namespace Ui {
class AutoNumberingDockWidget;
@@ -66,12 +67,28 @@ class AutoNumberingDockWidget : public QDockWidget
void on_m_element_value_le_editingFinished();
void on_m_folio_value_le_editingFinished();
void on_m_conductor_increase_sb_valueChanged(int);
void on_m_element_increase_sb_valueChanged(int);
void on_m_folio_increase_sb_valueChanged(int);
signals:
void folioAutoNumChanged(QString);
private:
enum class AutoNumCategory { Conductor, Element, Folio };
/// The four widgets that make up one category's row, bundled so
/// refreshRow() can be called with just a category instead of
/// four pointers that must always be passed in matching sets.
struct Row
{
QComboBox *combo;
QLineEdit *value;
QSpinBox *increase;
QLineEdit *next;
};
Row rowFor(AutoNumCategory category) const;
/**
@brief resetAutoNum
Reset the numerotation context currently selected in combo_box
@@ -93,6 +110,23 @@ class AutoNumberingDockWidget : public QDockWidget
void refreshValueField(QComboBox *combo_box, QLineEdit *line_edit, AutoNumCategory category);
void applyValueField(QComboBox *combo_box, QLineEdit *line_edit, AutoNumCategory category);
/// Refresh/apply the increment spin box the same way.
void refreshIncreaseField(QComboBox *combo_box, QSpinBox *increase_sb, AutoNumCategory category);
void applyIncreaseField(QComboBox *combo_box, QSpinBox *increase_sb, AutoNumCategory category);
/// Show what the counter will read after one more step, using
/// the same NumerotationContextCommands engine the Suivant
/// button in the full configuration dialog already advances
/// the whole context with -- so the preview can never disagree
/// with what actually happens when the number is next consumed.
void refreshNextField(QComboBox *combo_box, QLineEdit *next_edit, AutoNumCategory category);
/// Refresh a whole row -- value, increment and next-value
/// preview -- in one call. Every refresh call site needs the
/// increment and preview kept in step with the value now, so
/// this replaces refreshValueField() at each of them.
void refreshRow(AutoNumCategory category);
Ui::AutoNumberingDockWidget *ui;
QETProject* m_project = nullptr;
ProjectView* m_project_view = nullptr;
@@ -15,6 +15,36 @@
</property>
<widget class="QWidget" name="dockWidgetContents">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="3">
<widget class="QLabel" name="value_header_label">
<property name="text">
<string>Valeur</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QLabel" name="increase_header_label">
<property name="text">
<string>Incrément</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="5">
<widget class="QLabel" name="next_header_label">
<property name="text">
<string>Suivant</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="m_element_cb"/>
</item>
@@ -61,6 +91,47 @@
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="QSpinBox" name="m_conductor_increase_sb">
<property name="maximumSize">
<size>
<width>55</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Incrément : valeur ajoutée au compteur à chaque nouvelle numérotation</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="accelerated">
<bool>true</bool>
</property>
<property name="minimum">
<number>0</number>
</property>
</widget>
</item>
<item row="2" column="5">
<widget class="QLineEdit" name="m_conductor_next_le">
<property name="maximumSize">
<size>
<width>70</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Prochaine valeur qui sera appliquée avec cet incrément</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label">
<property name="text">
@@ -108,6 +179,47 @@
</property>
</widget>
</item>
<item row="3" column="4">
<widget class="QSpinBox" name="m_element_increase_sb">
<property name="maximumSize">
<size>
<width>55</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Incrément : valeur ajoutée au compteur à chaque nouvelle numérotation</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="accelerated">
<bool>true</bool>
</property>
<property name="minimum">
<number>0</number>
</property>
</widget>
</item>
<item row="3" column="5">
<widget class="QLineEdit" name="m_element_next_le">
<property name="maximumSize">
<size>
<width>70</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Prochaine valeur qui sera appliquée avec cet incrément</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="m_folio_cb"/>
</item>
@@ -144,6 +256,47 @@
</property>
</widget>
</item>
<item row="4" column="4">
<widget class="QSpinBox" name="m_folio_increase_sb">
<property name="maximumSize">
<size>
<width>55</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Incrément : valeur ajoutée au compteur à chaque nouvelle numérotation</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="accelerated">
<bool>true</bool>
</property>
<property name="minimum">
<number>0</number>
</property>
</widget>
</item>
<item row="4" column="5">
<widget class="QLineEdit" name="m_folio_next_le">
<property name="maximumSize">
<size>
<width>70</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Prochaine valeur qui sera appliquée avec cet incrément</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="6" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
+19 -1
View File
@@ -67,6 +67,7 @@ Diagram::Diagram(QETProject *project) :
m_project (project),
use_border_ (true),
draw_terminals_ (true),
draw_terminal_names_ (true),
draw_colored_conductors_ (true),
m_event_interface (nullptr),
m_freeze_new_elements (false),
@@ -2319,6 +2320,7 @@ ExportProperties Diagram::applyProperties(
old_properties.draw_border = border_and_titleblock.borderIsDisplayed();
old_properties.draw_titleblock = border_and_titleblock.titleBlockIsDisplayed();
old_properties.draw_terminals = drawTerminals();
old_properties.draw_terminal_names = drawTerminalNames();
old_properties.draw_colored_conductors = drawColoredConductors();
old_properties.exported_area = useBorder() ? QET::BorderArea
: QET::ElementsArea;
@@ -2327,6 +2329,7 @@ ExportProperties Diagram::applyProperties(
// applique les nouvelles options de rendu
setUseBorder (new_properties.exported_area == QET::BorderArea);
setDrawTerminals (new_properties.draw_terminals);
setDrawTerminalNames (new_properties.draw_terminal_names);
setDrawColoredConductors (new_properties.draw_colored_conductors);
setDisplayGrid (new_properties.draw_grid);
setDisplayGuides (new_properties.draw_guides);
@@ -2397,9 +2400,24 @@ QPointF Diagram::snapToGrid(const QPointF &p)
\~French true pour afficher les bornes, false sinon
*/
void Diagram::setDrawTerminals(bool dt) {
draw_terminals_ = dt;
foreach(QGraphicsItem *qgi, items()) {
if (Terminal *t = qgraphicsitem_cast<Terminal *>(qgi)) {
t -> setVisible(dt);
t -> update();
}
}
}
/**
@brief Diagram::setDrawTerminalNames
Defines whether or not to display the terminal names/labels
@param dt : true to display the terminal names, false otherwise
*/
void Diagram::setDrawTerminalNames(bool dt) {
draw_terminal_names_ = dt;
foreach(QGraphicsItem *qgi, items()) {
if (Terminal *t = qgraphicsitem_cast<Terminal *>(qgi)) {
t -> update();
}
}
}
+12
View File
@@ -127,6 +127,7 @@ class Diagram : public QGraphicsScene
bool draw_guides_;
QList<Diagram::Guide> m_guides_list;
bool draw_terminals_;
bool draw_terminal_names_;
bool draw_colored_conductors_;
QString m_conductors_autonum_name;
@@ -226,6 +227,8 @@ class Diagram : public QGraphicsScene
bool drawTerminals() const;
void setDrawTerminals(bool);
bool drawTerminalNames() const;
void setDrawTerminalNames(bool);
bool drawColoredConductors() const;
void setDrawColoredConductors(bool);
@@ -426,6 +429,15 @@ inline bool Diagram::drawTerminals() const
return(draw_terminals_);
}
/**
@brief Diagram::drawTerminalNames
@return true if terminal names are rendered, false otherwise
*/
inline bool Diagram::drawTerminalNames() const
{
return(draw_terminal_names_);
}
/**
@brief Diagram::drawColoredConductors
@return true if conductors colors are rendered, false otherwise.
+238 -8
View File
@@ -20,11 +20,44 @@
#include "../conductorautonumerotation.h"
#include "../diagram.h"
#include "../undocommand/addgraphicsobjectcommand.h"
#include "../undocommand/deleteqgraphicsitemcommand.h"
#include "../factory/elementfactory.h"
#include "../qetapp.h"
#include "../qetdiagrameditor.h"
#include "../qetgraphicsitem/element.h"
#include "../qetgraphicsitem/conductor.h"
#include "../qetgraphicsitem/terminal.h"
#include "../qet.h"
#include <QPainterPath>
#include <limits>
namespace {
/**
@brief distanceToSegment
@param point : point to measure from
@param segment : the finite segment (not the infinite line through it)
@return the distance from @a point to the closest point actually on
@a segment. Unlike QET::orthogonalProjection(), which reports a hit
for any point on the segment's infinite extension, this clamps the
projection to the segment itself: a point collinear with a wire but
past its actual drawn end is correctly reported as far away, not "on"
the wire.
*/
qreal distanceToSegment(const QPointF &point, const QLineF &segment)
{
const QPointF a = segment.p1();
const QPointF b = segment.p2();
const QPointF ab = b - a;
const qreal len2 = QPointF::dotProduct(ab, ab);
if (len2 <= 0.0)
return QLineF(point, a).length();
qreal t = QPointF::dotProduct(point - a, ab) / len2;
t = qBound(0.0, t, 1.0);
return QLineF(point, a + t * ab).length();
}
}
/**
@brief DiagramEventAddElement::DiagramEventAddElement
@@ -248,16 +281,213 @@ void DiagramEventAddElement::addElement()
QUndoCommand *undo_object = new QUndoCommand(tr("Ajouter %1").arg(element->name()));
new AddGraphicsObjectCommand(element, m_diagram, m_element -> pos(), undo_object);
//When we search for free aligned terminal we temporally remove m_element to
//avoid any interaction with the function Element::AlignedFreeTerminals
//This is useful when an element has two (or more) terminals on opposite sides,
//because m_element is exactly at the same pos of the new element
//added to the scene so new conductor are created between terminal of the new element
//and the opposite terminal of m_element.
//When we search for free aligned terminal we temporally remove m_element to
//avoid any interaction with the function Element::AlignedFreeTerminals
//This is useful when an element has two (or more) terminals on opposite sides,
//because m_element is exactly at the same pos of the new element
//added to the scene so new conductor are created between terminal of the new element
//and the opposite terminal of m_element.
m_diagram->removeItem(m_element);
while (!element -> AlignedFreeTerminals().isEmpty() && m_diagram -> project() -> autoConductor())
//Auto break conductor: if a terminal of the new element lies on an existing
//conductor, break the conductor and reconnect through the new element's terminal.
//Track the endpoints of broken conductors so auto-connect doesn't create duplicates.
QSet<Terminal *> broken_endpoints;
if (m_diagram->project()->autoBreakConductor())
{
QPair <Terminal *, Terminal *> pair = element -> AlignedFreeTerminals().takeFirst();
//Track which conductors we already handled for this element
QList<Conductor *> conductors_handled;
//Track which terminals of the new element are already used (by break or other-connect)
QSet<Terminal *> used_terminals;
foreach (Terminal *t, element->terminals())
{
//Skip terminals already used by a previous break+reconnect (other_terminal)
if (used_terminals.contains(t))
continue;
QPointF t_dock = t->dockConductor();
//Collect all conductors that pass through this dock point.
struct ConductorMatch {
Conductor *conductor;
Terminal *connect_to; //endpoint "before" the dock point (based on orientation)
Terminal *other; //endpoint "after" the dock point
};
QList<ConductorMatch> all_matches;
foreach (Conductor *c, m_diagram->conductors())
{
//Skip conductors we already handled or connected to the new element
if (conductors_handled.contains(c) ||
c->terminal1->parentElement() == element ||
c->terminal2->parentElement() == element)
continue;
//Check if dock point lies on the conductor path. Distance is
//measured to the segment itself (clamped), not the infinite
//line through it -- see distanceToSegment().
QPointF local_dock = c->mapFromScene(t_dock);
bool point_on_conductor = false;
QPainterPath path = c->path();
for (int i = 0; i < path.elementCount() - 1; ++i)
{
const QPainterPath::Element &e1 = path.elementAt(i);
const QPainterPath::Element &e2 = path.elementAt(i + 1);
QLineF segment(QPointF(e1.x, e1.y), QPointF(e2.x, e2.y));
if (distanceToSegment(local_dock, segment) < 5.0)
{
point_on_conductor = true;
break;
}
}
if (!point_on_conductor)
continue;
Terminal *c1 = c->terminal1;
Terminal *c2 = c->terminal2;
QPointF c1_dock = c1->dockConductor();
QPointF c2_dock = c2->dockConductor();
Terminal *connect_to = nullptr;
Terminal *other = nullptr;
switch (t->orientation()) {
case Qet::North:
if (c1_dock.y() < t_dock.y()) { connect_to = c1; other = c2; }
else if (c2_dock.y() < t_dock.y()) { connect_to = c2; other = c1; }
break;
case Qet::South:
if (c1_dock.y() > t_dock.y()) { connect_to = c1; other = c2; }
else if (c2_dock.y() > t_dock.y()) { connect_to = c2; other = c1; }
break;
case Qet::East:
if (c1_dock.x() > t_dock.x()) { connect_to = c1; other = c2; }
else if (c2_dock.x() > t_dock.x()) { connect_to = c2; other = c1; }
break;
case Qet::West:
if (c1_dock.x() < t_dock.x()) { connect_to = c1; other = c2; }
else if (c2_dock.x() < t_dock.x()) { connect_to = c2; other = c1; }
break;
}
if (!connect_to) {
qreal d1 = QLineF(t_dock, c1_dock).length();
qreal d2 = QLineF(t_dock, c2_dock).length();
if (d1 <= d2) { connect_to = c1; other = c2; }
else { connect_to = c2; other = c1; }
}
all_matches.append({c, connect_to, other});
}
if (all_matches.isEmpty())
continue;
//Group matches by their "other" endpoint and find the largest group.
//This ensures that when multiple independent circuits cross at the
//same dock point, the group with the most conductors gets priority,
//not whichever happens to have the nearest connect_to endpoint.
QMap<Terminal *, QList<ConductorMatch>> groups;
for (const auto &m : all_matches) {
groups[m.other].append(m);
}
Terminal *best_other = nullptr;
int best_count = 0;
for (auto it = groups.constBegin(); it != groups.constEnd(); ++it) {
if (it.value().size() > best_count) {
best_count = it.value().size();
best_other = it.key();
}
}
//Only break conductors in the largest group (same "other" endpoint).
//This prevents bridging independent nets: if two unrelated conductors
//cross at a dock point, only the larger group gets broken.
const QList<ConductorMatch> &matches = groups[best_other];
//Mark terminal as used
used_terminals.insert(t);
//Delete all matched conductors in one batch
DiagramContent content;
for (const auto &m : matches) {
content.m_other_conductors.append(m.conductor);
conductors_handled.append(m.conductor);
}
new DeleteQGraphicsItemCommand(m_diagram, content, undo_object);
//Create new conductors from each connect_to endpoint to this terminal.
//This creates junctions at the terminal when multiple conductors
//from the same circuit pass through the dock point (e.g. left and
//right conductors going to the same terminal strip terminal).
for (const auto &m : matches) {
Conductor *new_c = new Conductor(m.connect_to, t);
new AddGraphicsObjectCommand(new_c, m_diagram, QPointF(), undo_object);
ConductorAutoNumerotation can(new_c, m_diagram, undo_object);
can.numerate();
if (m_diagram->freezeNewConductors() || m_diagram->project()->isFreezeNewConductors())
new_c->setFreezeLabel(true);
broken_endpoints.insert(m.connect_to);
}
//Connect the shared "other" endpoint to the nearest free terminal
//with matching orientation.
QPointF other_dock = best_other->dockConductor();
Terminal *other_terminal = nullptr;
qreal best_dist = std::numeric_limits<qreal>::max();
foreach (Terminal *ot, element->terminals())
{
if (used_terminals.contains(ot))
continue;
//Check that the other_dock approaches from the correct direction
//relative to the candidate terminal's orientation.
QPointF ot_dock = ot->dockConductor();
bool orientation_ok = false;
switch (ot->orientation()) {
case Qet::North: orientation_ok = other_dock.y() < ot_dock.y(); break;
case Qet::South: orientation_ok = other_dock.y() > ot_dock.y(); break;
case Qet::East: orientation_ok = other_dock.x() > ot_dock.x(); break;
case Qet::West: orientation_ok = other_dock.x() < ot_dock.x(); break;
}
if (!orientation_ok)
continue;
qreal dist = QLineF(ot_dock, other_dock).length();
if (dist < best_dist) {
best_dist = dist;
other_terminal = ot;
}
}
if (other_terminal) {
Conductor *new_c2 = new Conductor(best_other, other_terminal);
new AddGraphicsObjectCommand(new_c2, m_diagram, QPointF(), undo_object);
ConductorAutoNumerotation can2(new_c2, m_diagram, undo_object);
can2.numerate();
if (m_diagram->freezeNewConductors() || m_diagram->project()->isFreezeNewConductors())
new_c2->setFreezeLabel(true);
broken_endpoints.insert(best_other);
used_terminals.insert(other_terminal);
}
}
}
//Auto-connect: collect all aligned pairs first, then filter and process.
QList<QPair<Terminal *, Terminal *>> aligned_pairs;
if (m_diagram->project()->autoConductor())
aligned_pairs = element->AlignedFreeTerminals();
for (const QPair<Terminal *, Terminal *> &pair : aligned_pairs)
{
//Skip if the other terminal was an endpoint of a broken conductor
if (broken_endpoints.contains(pair.second))
continue;
Conductor *conductor = new Conductor(pair.first, pair.second);
new AddGraphicsObjectCommand(conductor, m_diagram, QPointF(), undo_object);
@@ -18,6 +18,7 @@
#include "diagrameventaddshape.h"
#include "../diagram.h"
#include "../lastusedstyle.h"
#include "../undocommand/addgraphicsobjectcommand.h"
/**
@@ -77,6 +78,14 @@ void DiagramEventAddShape::mousePressEvent(QGraphicsSceneMouseEvent *event)
if (!m_shape_item)
{
m_shape_item = new QetShapeItem(pos, pos, m_shape_type);
//Start from whatever pen/brush was last applied this
//session, rather than always the hardcoded default.
if (LastUsedStyle::hasShapePen()) {
m_shape_item->setPen(LastUsedStyle::shapePen());
}
if (LastUsedStyle::hasShapeBrush()) {
m_shape_item->setBrush(LastUsedStyle::shapeBrush());
}
m_diagram->addItem (m_shape_item);
event->setAccepted(true);
return;
+2 -1
View File
@@ -19,6 +19,7 @@
#include "ElementsCollection/elementcollectionitem.h"
#include "ElementsCollection/elementscollectionmodel.h"
#include "ElementsCollection/elementstreeview.h"
#include "qetapp.h"
#include "qetmessagebox.h"
#include "qfilenameedit.h"
@@ -88,7 +89,7 @@ void ElementDialog::setUpWidget()
layout->addWidget(new QLabel(label_));
m_tree_view = new QTreeView(this);
m_tree_view = new ElementsTreeView(this);
m_model = new ElementsCollectionModel(m_tree_view);
+5
View File
@@ -34,6 +34,7 @@ ExportProperties::ExportProperties() :
draw_border(true),
draw_titleblock(true),
draw_terminals(false),
draw_terminal_names(false),
draw_bg_transparent(false),
draw_colored_conductors(true),
exported_area(QET::BorderArea)
@@ -70,6 +71,8 @@ void ExportProperties::toSettings(QSettings &settings,
draw_titleblock);
settings.setValue(prefix % "drawterminals",
draw_terminals);
settings.setValue(prefix % "drawterminalnames",
draw_terminal_names);
settings.setValue(prefix % "drawbgtransparent",
draw_bg_transparent);
settings.setValue(prefix % "drawcoloredconductors",
@@ -105,6 +108,8 @@ void ExportProperties::fromSettings(QSettings &settings,
true ).toBool();
draw_terminals = settings.value(prefix % "drawterminals",
false).toBool();
draw_terminal_names = settings.value(prefix % "drawterminalnames",
false).toBool();
draw_bg_transparent = settings.value(prefix % "drawbgtransparent",
false).toBool();
draw_colored_conductors = settings.value(
+1
View File
@@ -47,6 +47,7 @@ class ExportProperties {
bool draw_border; ///< Whether to render the border (along with rows/columns headers)
bool draw_titleblock; ///< Whether to render the title block
bool draw_terminals; ///< Whether to render terminals
bool draw_terminal_names; ///< Whether to render terminal names/labels
bool draw_bg_transparent; ///< Whether to use transparency for SVG-Export
bool draw_colored_conductors; ///< Whether to render conductors colors
QET::DiagramArea exported_area; ///< Area of diagrams to be rendered
+9 -2
View File
@@ -63,6 +63,7 @@ ExportProperties ExportPropertiesWidget::exportProperties() const
export_properties.draw_border = draw_border -> isChecked();
export_properties.draw_titleblock = draw_titleblock -> isChecked();
export_properties.draw_terminals = draw_terminals -> isChecked();
export_properties.draw_terminal_names = draw_terminal_names -> isChecked();
export_properties.draw_bg_transparent = draw_bg_transparent -> isChecked();
export_properties.draw_colored_conductors = draw_colored_conductors -> isChecked();
export_properties.exported_area = export_border -> isChecked() ? QET::BorderArea : QET::ElementsArea;
@@ -85,6 +86,7 @@ void ExportPropertiesWidget::setExportProperties(const ExportProperties &export_
draw_border -> setChecked(export_properties.draw_border);
draw_titleblock -> setChecked(export_properties.draw_titleblock);
draw_terminals -> setChecked(export_properties.draw_terminals);
draw_terminal_names -> setChecked(export_properties.draw_terminal_names);
draw_bg_transparent -> setChecked(export_properties.draw_bg_transparent);
draw_colored_conductors -> setChecked(export_properties.draw_colored_conductors);
@@ -206,13 +208,17 @@ void ExportPropertiesWidget::build()
draw_terminals = new QCheckBox(tr("Dessiner les bornes"), groupbox_options);
optionshlayout -> addWidget(draw_terminals, 2, 1);
// dessiner les noms des bornes
draw_terminal_names = new QCheckBox(tr("Dessiner les noms des bornes"), groupbox_options);
optionshlayout -> addWidget(draw_terminal_names, 3, 0);
// conserver les couleurs des conducteurs
draw_colored_conductors = new QCheckBox(tr("Conserver les couleurs des conducteurs"), groupbox_options);
optionshlayout -> addWidget(draw_colored_conductors, 3, 0);
optionshlayout -> addWidget(draw_colored_conductors, 3, 1);
// use transparent background for SVG-Export
draw_bg_transparent = new QCheckBox(tr("SVG: fond transparent"), groupbox_options);
optionshlayout -> addWidget(draw_bg_transparent, 3, 1);
optionshlayout -> addWidget(draw_bg_transparent, 4, 0);
vboxLayout -> addWidget(groupbox_options);
@@ -239,6 +245,7 @@ void ExportPropertiesWidget::build()
connect(draw_border, SIGNAL(stateChanged(int)), this, SIGNAL(optionChanged()));
connect(draw_titleblock, SIGNAL(stateChanged(int)), this, SIGNAL(optionChanged()));
connect(draw_terminals, SIGNAL(stateChanged(int)), this, SIGNAL(optionChanged()));
connect(draw_terminal_names, SIGNAL(stateChanged(int)), this, SIGNAL(optionChanged()));
connect(draw_bg_transparent, SIGNAL(stateChanged(int)), this, SIGNAL(optionChanged()));
connect(draw_colored_conductors, SIGNAL(stateChanged(int)), this, SIGNAL(optionChanged()));
}
+1
View File
@@ -62,6 +62,7 @@ class ExportPropertiesWidget : public QWidget {
QCheckBox *draw_border;
QCheckBox *draw_titleblock;
QCheckBox *draw_terminals;
QCheckBox *draw_terminal_names;
QCheckBox *draw_bg_transparent;
QCheckBox *draw_colored_conductors;
QRadioButton *export_border;
+106
View File
@@ -0,0 +1,106 @@
/*
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 "lastusedstyle.h"
QPen LastUsedStyle::m_shape_pen;
bool LastUsedStyle::m_has_shape_pen = false;
QBrush LastUsedStyle::m_shape_brush;
bool LastUsedStyle::m_has_shape_brush = false;
QFont LastUsedStyle::m_text_font;
bool LastUsedStyle::m_has_text_font = false;
/**
@return true if a shape pen was set this session
*/
bool LastUsedStyle::hasShapePen()
{
return m_has_shape_pen;
}
/**
@return the last pen applied to a shape this session
*/
QPen LastUsedStyle::shapePen()
{
return m_shape_pen;
}
/**
@brief LastUsedStyle::setShapePen
Record @a pen as the last-used shape pen for this session
@param pen
*/
void LastUsedStyle::setShapePen(const QPen &pen)
{
m_shape_pen = pen;
m_has_shape_pen = true;
}
/**
@return true if a shape brush was set this session
*/
bool LastUsedStyle::hasShapeBrush()
{
return m_has_shape_brush;
}
/**
@return the last brush applied to a shape this session
*/
QBrush LastUsedStyle::shapeBrush()
{
return m_shape_brush;
}
/**
@brief LastUsedStyle::setShapeBrush
Record @a brush as the last-used shape brush for this session
@param brush
*/
void LastUsedStyle::setShapeBrush(const QBrush &brush)
{
m_shape_brush = brush;
m_has_shape_brush = true;
}
/**
@return true if a text font was set this session
*/
bool LastUsedStyle::hasTextFont()
{
return m_has_text_font;
}
/**
@return the last font applied to a free text item this session
*/
QFont LastUsedStyle::textFont()
{
return m_text_font;
}
/**
@brief LastUsedStyle::setTextFont
Record @a font as the last-used free text font for this session
@param font
*/
void LastUsedStyle::setTextFont(const QFont &font)
{
m_text_font = font;
m_has_text_font = true;
}
+63
View File
@@ -0,0 +1,63 @@
/*
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 LAST_USED_STYLE_H
#define LAST_USED_STYLE_H
#include <QBrush>
#include <QFont>
#include <QPen>
/**
@brief The LastUsedStyle class
Session-scoped "last used" style for new shapes and free text created
on the diagram canvas: whatever pen/brush/font was last applied through
the properties editors becomes the starting point for the next new
item of that type, the way most drawing tools behave.
Deliberately in-memory only, not QSettings-backed: this is a live
"what did I just use" value for the current editing session, not an
app-wide default (that's already covered by the Preferences dialog's
font setting, read as the fallback when nothing has been set yet).
*/
class LastUsedStyle
{
public:
static bool hasShapePen();
static QPen shapePen();
static void setShapePen(const QPen &pen);
static bool hasShapeBrush();
static QBrush shapeBrush();
static void setShapeBrush(const QBrush &brush);
static bool hasTextFont();
static QFont textFont();
static void setTextFont(const QFont &font);
private:
LastUsedStyle() = delete;
static QPen m_shape_pen;
static bool m_has_shape_pen;
static QBrush m_shape_brush;
static bool m_has_shape_brush;
static QFont m_text_font;
static bool m_has_text_font;
};
#endif // LAST_USED_STYLE_H
+2 -1
View File
@@ -19,6 +19,7 @@
#include "ElementsCollection/elementcollectionitem.h"
#include "ElementsCollection/elementscollectionmodel.h"
#include "ElementsCollection/elementstreeview.h"
#include "NameList/ui/namelistwidget.h"
#include "editor/ui/qetelementeditor.h"
#include "qetmessagebox.h"
@@ -85,7 +86,7 @@ QWizardPage *NewElementWizard::buildStep1()
page -> setSubTitle(tr("Sélectionnez une catégorie dans laquelle enregistrer le nouvel élément.", "wizard page subtitle"));
QVBoxLayout *layout = new QVBoxLayout();
m_tree_view = new QTreeView(this);
m_tree_view = new ElementsTreeView(this);
m_model = new ElementsCollectionModel(m_tree_view);
m_model->hideElement();
+3
View File
@@ -161,6 +161,7 @@ ProjectPrintWindow::ProjectPrintWindow(QETProject *project, QPrinter *printer, Q
ui->m_draw_border_cb->setChecked(exp.draw_border);
ui->m_draw_titleblock_cb->setChecked(exp.draw_titleblock);
ui->m_draw_terminal_cb->setChecked(exp.draw_terminals);
ui->m_draw_terminal_names_cb->setChecked(exp.draw_terminal_names);
ui->m_keep_conductor_color_cb->setChecked(exp.draw_colored_conductors);
ui->m_date_cb->blockSignals(true);
@@ -523,6 +524,7 @@ ExportProperties ProjectPrintWindow::exportProperties() const
exp.draw_border = ui->m_draw_border_cb->isChecked();
exp.draw_titleblock = ui->m_draw_titleblock_cb->isChecked();
exp.draw_terminals = ui->m_draw_terminal_cb->isChecked();
exp.draw_terminal_names = ui->m_draw_terminal_names_cb->isChecked();
exp.draw_colored_conductors = ui->m_keep_conductor_color_cb->isChecked();
exp.draw_grid = false;
exp.draw_guides = false;
@@ -796,6 +798,7 @@ void ProjectPrintWindow::on_m_draw_border_cb_clicked() { m_preview->upd
void ProjectPrintWindow::on_m_draw_titleblock_cb_clicked() { m_preview->updatePreview(); }
void ProjectPrintWindow::on_m_keep_conductor_color_cb_clicked() { m_preview->updatePreview(); }
void ProjectPrintWindow::on_m_draw_terminal_cb_clicked() { m_preview->updatePreview(); }
void ProjectPrintWindow::on_m_draw_terminal_names_cb_clicked() { m_preview->updatePreview(); }
void ProjectPrintWindow::on_m_fit_in_page_cb_clicked() { m_preview->updatePreview(); }
void ProjectPrintWindow::on_m_use_full_page_cb_clicked()
{
+1
View File
@@ -55,6 +55,7 @@ class ProjectPrintWindow : public QMainWindow
void on_m_draw_titleblock_cb_clicked();
void on_m_keep_conductor_color_cb_clicked();
void on_m_draw_terminal_cb_clicked();
void on_m_draw_terminal_names_cb_clicked();
void on_m_fit_in_page_cb_clicked();
void on_m_use_full_page_cb_clicked();
void on_m_zoom_out_action_triggered();
+10
View File
@@ -183,6 +183,16 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="m_draw_terminal_names_cb">
<property name="text">
<string>Dessiner les noms des bornes</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
+54
View File
@@ -370,6 +370,21 @@ void QETDiagramEditor::setUpActions()
pv->project()->setAutoConductor(ac);
});
//AutoBreakConductor
m_auto_break_conductor = new QAction (QET::Icons::Conductor, tr("Coupure automatique de conducteur(s)","Tool tip of auto break conductor"), this);
m_auto_break_conductor->setStatusTip (tr("Couper automatiquement les conducteurs existants lors du placement d'un élément", "Status tip of auto break conductor"));
m_auto_break_conductor->setCheckable (true);
{
QSettings settings;
m_auto_break_conductor->setChecked(settings.value("diagrameditor/auto_break_conductor", false).toBool());
}
connect(m_auto_break_conductor, &QAction::triggered, [this](bool abc) {
QSettings settings;
settings.setValue("diagrameditor/auto_break_conductor", abc);
if (ProjectView *pv = currentProjectView())
pv->project()->setAutoBreakConductor(abc);
});
//Switch background color
m_grey_background = new QAction (QET::Icons::DiagramBg, tr("Couleur de fond blanc/gris","Tool tip of white/grey background button"), this);
m_grey_background -> setStatusTip (tr("Affiche la couleur de fond du folio en blanc ou en gris", "Status tip of white/grey background button"));
@@ -809,6 +824,7 @@ void QETDiagramEditor::setUpToolBar()
diagram_tool_bar -> addAction (m_edit_diagram_properties);
diagram_tool_bar -> addAction (m_conductor_reset);
diagram_tool_bar -> addAction (m_auto_conductor);
diagram_tool_bar -> addAction (m_auto_break_conductor);
m_add_item_tool_bar = new QToolBar(tr("Ajouter"), this);
m_add_item_tool_bar->setObjectName("adding");
@@ -1287,6 +1303,12 @@ bool QETDiagramEditor::addProject(QETProject *project, bool update_panel)
undo_group.addStack(project -> undoStack());
connect(project, &QETProject::projectModified, this, [this](QETProject *modified_project, bool) {
if (modified_project == currentProject()) {
updateWindowModifiedState();
}
});
m_element_collection_widget->addProject(project);
// met a jour le panel d'elements
@@ -1896,9 +1918,14 @@ void QETDiagramEditor::slot_updateModeActions()
{
m_auto_conductor -> setEnabled (true);
m_auto_conductor -> setChecked (pv -> project() -> autoConductor());
m_auto_break_conductor -> setEnabled (true);
m_auto_break_conductor -> setChecked (pv -> project() -> autoBreakConductor());
}
else
{
m_auto_conductor -> setDisabled(true);
m_auto_break_conductor -> setDisabled(true);
}
}
/**
@@ -2576,6 +2603,7 @@ void QETDiagramEditor::subWindowActivated(QMdiSubWindow *subWindows)
slot_updateWindowsMenu();
emit syncElementsPanel();
updateUsageTrackersActiveState();
updateWindowModifiedState();
}
/**
@@ -2601,6 +2629,32 @@ void QETDiagramEditor::updateUsageTrackersActiveState()
}
}
/**
@brief QETDiagramEditor::updateWindowModifiedState
Reflect the currently active project's unsaved-changes state in the
main window's title and native "document modified" indicator (e.g.
the dot in the close button on macOS). Called whenever the active
project changes, or whenever the active project's own modified state
changes.
The window title's "[*]" placeholder is Qt's own convention: combined
with setWindowModified(), it lets each platform render the modified
indicator its own way (or not at all, on platforms without one)
without QET having to draw anything itself.
*/
void QETDiagramEditor::updateWindowModifiedState()
{
if (QETProject *project = currentProject()) {
setWindowTitle(QString("%1[*] - %2").arg(
project->pathNameTitle(),
tr("QElectroTech", "window title")));
setWindowModified(project->projectOptionsWereModified());
} else {
setWindowTitle(tr("QElectroTech", "window title"));
setWindowModified(false);
}
}
/**
@brief QETDiagramEditor::selectionChanged
This slot is called when a diagram selection was changed.
+2
View File
@@ -98,6 +98,7 @@ class QETDiagramEditor : public QETMainWindow
ProjectView *findProject(const QString &) const;
QMdiSubWindow *subWindowForWidget(QWidget *) const;
void updateUsageTrackersActiveState();
void updateWindowModifiedState();
signals:
void syncElementsPanel();
@@ -192,6 +193,7 @@ class QETDiagramEditor : public QETMainWindow
*redo, ///< Redo the latest cancelled operation
*m_paste, ///< Paste clipboard content on the current diagram
*m_auto_conductor, ///< Enable/Disable the use of auto conductor
*m_auto_break_conductor, ///< Enable/Disable the use of auto break conductor
*m_grey_background, ///< Switch the background color in white or grey
*m_draw_grid, ///< Switch the background grid display or not
*m_draw_guides = nullptr, ///< Switch the custom guides display or not
@@ -19,6 +19,7 @@
#include "../diagram.h"
#include "../diagramcommands.h"
#include "../lastusedstyle.h"
#include "../qet.h"
#include "../qetapp.h"
#include "../utils/qetutils.h"
@@ -33,7 +34,10 @@
IndependentTextItem::IndependentTextItem() :
DiagramTextItem(nullptr)
{
setFont(QETApp::indiTextsItemFont());
//Start from the font last applied to a text item this session,
//falling back to the app-wide Preferences default otherwise.
setFont(LastUsedStyle::hasTextFont() ? LastUsedStyle::textFont()
: QETApp::indiTextsItemFont());
QSettings settings;
setRotation(settings.value("diagrameditor/independent_text_rotation", 0).toInt());
}
+17 -14
View File
@@ -199,19 +199,21 @@ void Terminal::paint(
// dessin de la borne en rouge
// draw the terminal in red
t.setColor(Qt::red);
painter -> setPen(t);
painter -> drawLine(c, e);
if (!diagram() || diagram()->drawTerminals()) {
t.setColor(Qt::red);
painter -> setPen(t);
painter -> drawLine(c, e);
// dessin du point d'amarrage au conducteur en bleu
// draw the docking point to the conductor in blue
t.setColor(m_hovered_color);
painter -> setPen(t);
painter -> setBrush(m_hovered_color);
if (m_hovered) {
painter -> setRenderHint(QPainter::Antialiasing, true);
painter -> drawEllipse(QRectF(c.x() - 2.5, c.y() - 2.5, 5.0, 5.0));
} else painter -> drawPoint(c);
// dessin du point d'amarrage au conducteur en bleu
// draw the docking point to the conductor in blue
t.setColor(m_hovered_color);
painter -> setPen(t);
painter -> setBrush(m_hovered_color);
if (m_hovered) {
painter -> setRenderHint(QPainter::Antialiasing, true);
painter -> drawEllipse(QRectF(c.x() - 2.5, c.y() - 2.5, 5.0, 5.0));
} else painter -> drawPoint(c);
}
//Draw help line if needed,
if (diagram() && m_draw_help_line)
@@ -273,9 +275,10 @@ void Terminal::paint(
m_help_line_a -> setLine(line);
}
// Draw label if show_name is enabled
// Draw label if show_name is enabled and terminal names are allowed
const QString display_name = name();
if (d->m_show_name && !display_name.isEmpty()) {
if (d->m_show_name && !display_name.isEmpty()
&& (!diagram() || diagram()->drawTerminalNames())) {
painter->setRenderHint(QPainter::Antialiasing, true);
painter->setRenderHint(QPainter::TextAntialiasing, true);
painter->setFont(d->m_label_font);
+28
View File
@@ -69,6 +69,10 @@ m_project_properties_handler{this}
init();
QSettings settings;
//Read auto break conductor default from global settings
m_auto_break_conductor = settings.value(QStringLiteral("diagrameditor/auto_break_conductor"), false).toBool();
int size = settings.beginReadArray(QStringLiteral("diagrameditor/defaultguides"));
for (int i = 0; i < size; ++i) {
settings.setArrayIndex(i);
@@ -927,6 +931,28 @@ void QETProject::setAutoConductor(bool ac)
m_auto_conductor = ac;
}
/**
@brief QETProject::autoBreakConductor
@return true if use of auto break conductor is authorized.
See also Q_PROPERTY autoBreakConductor
*/
bool QETProject::autoBreakConductor() const
{
return m_auto_break_conductor;
}
/**
@brief QETProject::setAutoBreakConductor
@param abc
Enable the use of auto break conductor if true
See also Q_PROPERTY autoBreakConductor
*/
void QETProject::setAutoBreakConductor(bool abc)
{
if (abc != m_auto_break_conductor)
m_auto_break_conductor = abc;
}
/**
@brief QETProject::autoFolioNumberingNewFolios
emit Signal to add new Diagram with autonum
@@ -1735,6 +1761,7 @@ void QETProject::readDefaultPropertiesXml(QDomDocument &xml_project)
{
m_current_conductor_autonum = conds_autonums.attribute(QStringLiteral("current_autonum"));
m_freeze_new_conductors = conds_autonums.attribute(QStringLiteral("freeze_new_conductors")) == QLatin1String("true");
m_auto_break_conductor = conds_autonums.attribute(QStringLiteral("auto_break_conductors")) == QLatin1String("true");
for (auto elmt : QET::findInDomElement(conds_autonums, QStringLiteral("conductor_autonum")))
{
NumerotationContext nc;
@@ -1861,6 +1888,7 @@ void QETProject::writeDefaultPropertiesXml(QDomElement &xml_element)
QDomElement conductor_autonums = xml_document.createElement("conductors_autonums");
conductor_autonums.setAttribute("current_autonum", m_current_conductor_autonum);
conductor_autonums.setAttribute("freeze_new_conductors", m_freeze_new_conductors ? "true" : "false");
conductor_autonums.setAttribute("auto_break_conductors", m_auto_break_conductor ? "true" : "false");
foreach (QString key, conductorAutoNum().keys()) {
QDomElement conductor_autonum = conductorAutoNum(key).toXml(xml_document, "conductor_autonum");
if (key != "" && conductorAutoNumFormula(key) != "") {
+4
View File
@@ -90,6 +90,7 @@ class QETProject : public QObject
};
Q_PROPERTY(bool autoConductor READ autoConductor WRITE setAutoConductor)
Q_PROPERTY(bool autoBreakConductor READ autoBreakConductor WRITE setAutoBreakConductor)
// constructors, destructor
public:
@@ -181,9 +182,11 @@ class QETProject : public QObject
void setFreezeNewConductors(bool);
bool autoConductor () const;
bool autoBreakConductor () const;
bool autoElement () const;
bool autoFolio () const;
void setAutoConductor (bool ac);
void setAutoBreakConductor (bool abc);
void setAutoElement (bool ae);
void autoFolioNumberingNewFolios ();
void autoFolioNumberingSelectedFolios(int, int, const QString&);
@@ -318,6 +321,7 @@ class QETProject : public QObject
QHash <QString, NumerotationContext> m_element_autonum; //Title and NumContext hash
QString m_current_element_autonum;
bool m_auto_conductor = true;
bool m_auto_break_conductor = false;
XmlElementCollection *m_elements_collection = nullptr;
bool m_freeze_new_elements = false;
bool m_freeze_new_conductors = false;
+2
View File
@@ -20,6 +20,7 @@
#include "../QPropertyUndoCommand/qpropertyundocommand.h"
#include "../diagram.h"
#include "../diagramcommands.h"
#include "../lastusedstyle.h"
#include "../qetgraphicsitem/independenttextitem.h"
#include "../ui_inditextpropertieswidget.h"
@@ -455,6 +456,7 @@ void IndiTextPropertiesWidget::on_m_font_pb_clicked()
m_font_is_selected = true;
ui->m_font_pb->setText(font.family());
ui->m_size_sb->setValue(font.pointSize());
LastUsedStyle::setTextFont(m_selected_font);
apply();
} else {
ui->m_font_pb->setText(tr("Police"));
@@ -20,6 +20,7 @@
#include "../QPropertyUndoCommand/qpropertyundocommand.h"
#include "../diagram.h"
#include "../lastusedstyle.h"
#include "../qetgraphicsitem/qetshapeitem.h"
#include "../ui_shapegraphicsitempropertieswidget.h"
@@ -180,6 +181,7 @@ QUndoCommand* ShapeGraphicsItemPropertiesWidget::associatedUndo() const
{
undo = new QPropertyUndoCommand(m_shape, "pen", old_pen, new_pen);
undo->setText(tr("Modifier le trait d'une forme"));
LastUsedStyle::setShapePen(new_pen);
}
QBrush old_brush = m_shape->brush();
@@ -196,6 +198,7 @@ QUndoCommand* ShapeGraphicsItemPropertiesWidget::associatedUndo() const
undo = new QPropertyUndoCommand(m_shape, "brush", old_brush, new_brush);
undo->setText(tr("Modifier le remplissage d'une forme"));
}
LastUsedStyle::setShapeBrush(new_brush);
}
if (ui->m_close_polygon->isChecked() != m_shape->isClosed())
@@ -321,6 +324,7 @@ QUndoCommand* ShapeGraphicsItemPropertiesWidget::associatedUndo() const
if (new_pen != old_pen) {
new QPropertyUndoCommand(m_shape, "pen", old_pen, new_pen, undo);
LastUsedStyle::setShapePen(new_pen);
}
QBrush old_brush = m_shape->brush();
@@ -330,6 +334,7 @@ QUndoCommand* ShapeGraphicsItemPropertiesWidget::associatedUndo() const
if (new_brush != old_brush) {
new QPropertyUndoCommand(m_shape, "brush", old_brush, new_brush, undo);
LastUsedStyle::setShapeBrush(new_brush);
}
if (ui->m_close_polygon->isChecked() != m_shape->isClosed()) {
+20 -2
View File
@@ -194,7 +194,16 @@ TitleBlockProperties TitleBlockPropertiesWidget::properties() const
prop.useDate = TitleBlockProperties::UseDateValue;
prop.date = ui->m_date_edit->date();
}
else if (ui->m_current_date_rb->isVisible() && ui->m_current_date_rb->isChecked()) {
else if (!ui->m_current_date_rb->isHidden() && ui->m_current_date_rb->isChecked()) {
/* isVisible() (unlike isHidden()) also depends on the whole
* ancestor chain being visible, not just this widget's own
* state -- inside a QTabWidget page (both the New Project and
* Project Properties dialogs embed this widget in one), it's
* false whenever this isn't the active tab, silently dropping
* "current date" back to the useDate/date default (no date)
* even though the radio button is still checked underneath.
* isHidden() mirrors the read side's own check in initDialog(),
* and isn't affected by an ancestor tab switch. */
prop.useDate = TitleBlockProperties::CurrentDate;
prop.date = QDate::currentDate();
}
@@ -237,7 +246,16 @@ TitleBlockProperties TitleBlockPropertiesWidget::propertiesAutoNum(
prop.useDate = TitleBlockProperties::UseDateValue;
prop.date = ui->m_date_edit->date();
}
else if (ui->m_current_date_rb->isVisible() && ui->m_current_date_rb->isChecked()) {
else if (!ui->m_current_date_rb->isHidden() && ui->m_current_date_rb->isChecked()) {
/* isVisible() (unlike isHidden()) also depends on the whole
* ancestor chain being visible, not just this widget's own
* state -- inside a QTabWidget page (both the New Project and
* Project Properties dialogs embed this widget in one), it's
* false whenever this isn't the active tab, silently dropping
* "current date" back to the useDate/date default (no date)
* even though the radio button is still checked underneath.
* isHidden() mirrors the read side's own check in initDialog(),
* and isn't affected by an ancestor tab switch. */
prop.useDate = TitleBlockProperties::CurrentDate;
prop.date = QDate::currentDate();
}