Merge master into stage 2 (#1042) as the base of the stage PRs

This commit is contained in:
ispyisail
2026-09-26 21:40:18 +12:00
32 changed files with 1516 additions and 106 deletions
+125 -3
View File
@@ -16,6 +16,7 @@
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/
#include "diagramview.h"
#include "cellruler.h"
#include "lastusedstyle.h"
#include "qetproject.h"
#include "QPropertyUndoCommand/qpropertyundocommand.h"
@@ -43,6 +44,7 @@
#include <QDropEvent>
#include <QPainter>
#include <QPointer>
#include <algorithm>
/**
Constructeur
@@ -107,6 +109,13 @@ DiagramView::DiagramView(Diagram *diagram, QWidget *parent) :
connect(&(m_diagram -> border_and_titleblock), &BorderTitleBlock::informationChanged, this, &DiagramView::updateWindowTitle);
connect(diagram, &Diagram::findElementRequired, this, &DiagramView::findElementRequired);
m_top_ruler = new CellRuler(Qt::Horizontal, this);
m_side_ruler = new CellRuler(Qt::Vertical, this);
m_cell_rulers_shown = QSettings().value("diagrameditor/cell_rulers", false).toBool();
connect(&m_diagram->border_and_titleblock, &BorderTitleBlock::borderChanged, this, &DiagramView::updateCellRulers);
connect(&m_diagram->border_and_titleblock, &BorderTitleBlock::displayChanged, this, &DiagramView::updateCellRulers);
updateCellRulers();
QShortcut *edit_conductor_color_shortcut = new QShortcut(QKeySequence(Qt::Key_F2), this);
connect(edit_conductor_color_shortcut, &QShortcut::activated, [this]()
{
@@ -443,6 +452,23 @@ void DiagramView::zoomReset()
adjustGridToZoom();
}
/**
@brief DiagramView::zoomToRect
Adjust zoom to fit \a rect, in scene coordinate, in the view.
@param rect
*/
void DiagramView::zoomToRect(const QRectF &rect)
{
fitInView(rect, Qt::KeepAspectRatio);
//Zooming in makes the scroll bars appear, which resizes the viewport
//from a queued call; that resize is anchored under the mouse and
//would scroll away from rect, so center again once it has run.
QMetaObject::invokeMethod(this, [this, rect]() {
centerOn(rect.center());
}, Qt::QueuedConnection);
adjustGridToZoom();
}
/**
Copie les elements selectionnes du schema dans le presse-papier puis les supprime
Copies the selected elements from the diagram to the clipboard and then deletes them
@@ -1228,6 +1254,82 @@ void DiagramView::paintingInverted(bool inverted)
m_diagram->setInvertedLightness(inverted);
}
/**
@brief DiagramView::setCellRulersShown
Show or hide the rulers that keep the column numbers and the row
letters of the folio border in sight along the edges of this view.
@param shown
*/
void DiagramView::setCellRulersShown(bool shown)
{
m_cell_rulers_shown = shown;
updateCellRulers();
}
/**
@brief DiagramView::updateCellRulers
Show each ruler when the rulers are wanted and the folio shows the
matching header, and give it room in the margins of the view. The
part of the folio in sight stays in sight when the viewport resizes.
*/
void DiagramView::updateCellRulers()
{
const BorderTitleBlock &border = m_diagram->border_and_titleblock;
const bool top = m_cell_rulers_shown
&& border.borderIsDisplayed() && border.columnsAreDisplayed();
const bool side = m_cell_rulers_shown
&& border.borderIsDisplayed() && border.rowsAreDisplayed();
const int thickness = m_top_ruler->thickness();
m_top_ruler->setVisible(top);
m_side_ruler->setVisible(side);
m_side_ruler->setLeadingSpace(top ? thickness : 0);
const QMargins margins(side ? thickness : 0, top ? thickness : 0, 0, 0);
if (margins != viewportMargins()) {
const QPointF centre = mapToScene(viewport()->rect().center());
setViewportMargins(margins);
centerOn(centre);
}
placeCellRulers();
m_top_ruler->update();
m_side_ruler->update();
}
/**
@brief DiagramView::placeCellRulers
Lay the rulers along the top and the left edges of the viewport, the
side ruler covering the corner too when both are shown.
*/
void DiagramView::placeCellRulers()
{
if (!m_top_ruler) {
return;
}
const QRect viewport_rect = viewport()->geometry();
const int thickness = m_top_ruler->thickness();
const int corner = m_top_ruler->isHidden() ? 0 : thickness;
m_top_ruler->setGeometry(viewport_rect.left(), viewport_rect.top() - thickness,
viewport_rect.width(), thickness);
m_side_ruler->setGeometry(viewport_rect.left() - thickness, viewport_rect.top() - corner,
thickness, viewport_rect.height() + corner);
}
/**
@brief DiagramView::viewportEvent
Keep the rulers along the viewport when it resizes, which it also does
without the view resizing, when the scroll bars come and go.
@param event
@return what QGraphicsView::viewportEvent() returns
*/
bool DiagramView::viewportEvent(QEvent *event)
{
if (event->type() == QEvent::Resize) {
placeCellRulers();
}
return PaletteGraphicsView::viewportEvent(event);
}
/**
@brief DiagramView::paintEvent
Reimplemented from QGraphicsView
@@ -1237,6 +1339,13 @@ void DiagramView::paintEvent(QPaintEvent *event)
{
PaletteGraphicsView::paintEvent(event);
//Scrolling and zooming both repaint the viewport: follow them
if (viewportTransform() != m_rulers_transform) {
m_rulers_transform = viewportTransform();
m_top_ruler->update();
m_side_ruler->update();
}
if (m_free_rubberbanding && m_free_rubberband.count() >= 3)
{
QPainter painter(viewport());
@@ -1357,10 +1466,15 @@ QList<QAction *> DiagramView::contextMenuActions() const
{
if (m_diagram->selectedItems().isEmpty())
{
//Drawing comes first. The row and column actions change
//the folio's layout and are rarely wanted, so they sit one
//level down where a stray click cannot reach them.
list << m_paste_here;
list << m_separators.at(0);
list << qde->m_add_item_menu->menuAction();
list << m_separators.at(1);
list << qde->m_edit_diagram_properties;
list << qde->m_row_column_actions_group.actions();
list << qde->m_row_column_menu->menuAction();
}
else
{
@@ -1376,11 +1490,19 @@ QList<QAction *> DiagramView::contextMenuActions() const
list << qde->m_depth_action_group->actions();
}
//Remove from the context menu the actions which are disabled.
//Remove from the context menu the actions which are disabled,
//and the submenus in which every action is disabled.
const QList<QAction *> actions = list;
for(QAction *action : actions)
{
if (!action->isEnabled()) {
bool usable = action->isEnabled();
if (usable && action->menu())
{
const QList<QAction *> sub_actions = action->menu()->actions();
usable = std::any_of(sub_actions.cbegin(), sub_actions.cend(),
[](QAction *a) { return a->isEnabled(); });
}
if (!usable) {
list.removeAll(action);
}
}