mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-09-20 07:14:13 +02:00
Merge remote-tracking branch 'upstream/master' into copying-fix
# Conflicts: # sources/diagramevent/diagrameventaddpaste.cpp
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
# Linux build, unit tests, and the IPC open-forwarding regression gate.
|
||||
#
|
||||
# The existing workflows build Windows and generate documentation; nothing
|
||||
# builds QElectroTech on Linux or runs tests/ in CI. This does both.
|
||||
#
|
||||
# It runs inside an ubuntu:26.04 container rather than directly on the runner
|
||||
# because the IPC gate below needs Qt 6.10.2. The ubuntu-latest image ships
|
||||
# Qt 6.4, and whether the crash that gate covers reproduces on 6.4 has never
|
||||
# been checked -- a gate that cannot go red is worse than no gate.
|
||||
name: Linux build and tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
linux:
|
||||
name: Build and test (Qt 6, Debug)
|
||||
runs-on: ubuntu-latest
|
||||
container: ubuntu:26.04
|
||||
|
||||
steps:
|
||||
- name: Install build and test dependencies
|
||||
run: |
|
||||
apt-get update
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||
ca-certificates build-essential cmake ninja-build git pkg-config \
|
||||
qt6-base-dev qt6-base-private-dev qt6-tools-dev qt6-tools-dev-tools \
|
||||
libqt6svg6-dev libqt6sql6-sqlite libsqlite3-dev libcups2-dev \
|
||||
libxkbcommon-x11-0 \
|
||||
xvfb openbox xdotool x11-utils
|
||||
# extra-cmake-modules and the KF6 libraries are installed rather than
|
||||
# left to FetchContent: without them CMake builds extra-cmake-modules
|
||||
# from source, and its Qt Help documentation target then demands
|
||||
# Qt6{Core,Gui,Widgets,DBus}Tools, failing the configure with an error
|
||||
# that appears to be about QElectroTech and is not.
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||
extra-cmake-modules libkf6coreaddons-dev libkf6widgetsaddons-dev \
|
||||
qt6-svg-plugins
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Configure
|
||||
# Debug, not Release. Whether a use-after-free faults depends on what
|
||||
# the allocator does with the freed block: the commit before #868
|
||||
# crashes every time built Debug and survives every time built
|
||||
# -O3 -DNDEBUG, so a Release job would never catch a regression here.
|
||||
run: |
|
||||
git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||
cmake -B build -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=Debug \
|
||||
-DQT_VERSION_MAJOR=6
|
||||
|
||||
- name: Build
|
||||
run: cmake --build build --parallel $(nproc)
|
||||
|
||||
- name: Unit tests
|
||||
run: xvfb-run -a ctest --test-dir build --output-on-failure
|
||||
|
||||
- name: IPC open-forwarding regression (#868)
|
||||
# Fails the job only on an actual crash. An inconclusive run means the
|
||||
# crash path was not exercised -- it proves nothing, which is not the
|
||||
# same as a regression, and failing on it would make this job flaky
|
||||
# rather than informative.
|
||||
run: |
|
||||
set +e
|
||||
tests/ipc-regression/run.sh --binary build/qelectrotech
|
||||
status=$?
|
||||
set -e
|
||||
case $status in
|
||||
0) echo "::notice::IPC gate passed" ;;
|
||||
2) echo "::warning::IPC gate inconclusive -- the crash path was not exercised, nothing was proven" ;;
|
||||
*) echo "::error::IPC gate failed -- forwarded files are being opened inside the socket handler again"
|
||||
exit 1 ;;
|
||||
esac
|
||||
@@ -42,6 +42,9 @@ jobs:
|
||||
pages: write
|
||||
id-token: write # Required by SignPath
|
||||
|
||||
env:
|
||||
SIGNPATH_API_TOKEN: ${{ secrets.SIGNPATH_API_TOKEN }}
|
||||
|
||||
outputs:
|
||||
qt6_msi: ${{ steps.export.outputs.msi_name_qt6 }}
|
||||
|
||||
@@ -290,7 +293,8 @@ jobs:
|
||||
# PR/run must never attempt a signing request.
|
||||
# (cf. DieterMayerOSS:fix/msi-signing-fork-guard, d3f60c88)
|
||||
- name: Sign MSI via SignPath
|
||||
if: github.repository == 'qelectrotech/qelectrotech-source-mirror'
|
||||
id: sign
|
||||
if: github.repository == 'qelectrotech/qelectrotech-source-mirror' && env.SIGNPATH_API_TOKEN != ''
|
||||
uses: signpath/github-action-submit-signing-request@v2
|
||||
with:
|
||||
api-token: ${{ secrets.SIGNPATH_API_TOKEN }}
|
||||
@@ -345,7 +349,7 @@ jobs:
|
||||
run: |
|
||||
Write-Host "=== MSI build summary (${{ matrix.flavor }}) ==="
|
||||
Write-Host "Version : ${{ steps.version.outputs.VERSION_DISPLAY }}"
|
||||
Write-Host "Signed : true"
|
||||
Write-Host "Signed : ${{ steps.sign.outcome == 'success' }}"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Job 2 : Génère et déploie la page GitHub Pages une fois le MSI publié,
|
||||
|
||||
@@ -58,22 +58,30 @@
|
||||
const QList<QGraphicsItem *> movable = m_content.items(MovableItems);
|
||||
if (movable.isEmpty()) return;
|
||||
|
||||
//Compute the bounding rect centre — this is where the cursor
|
||||
//will start. Items stay at their original XML positions;
|
||||
//Compute the top-left of all items' positions (not bounding
|
||||
//rects) and snap to grid — used only for the initial cursor
|
||||
//warp. Items stay at their original XML positions;
|
||||
//moveTo() handles grid-snapped movement via deltas.
|
||||
QRectF group_rect;
|
||||
QPointF top_left;
|
||||
bool first = true;
|
||||
for (auto *item : movable) {
|
||||
group_rect = group_rect.united(item->mapToScene(item->boundingRect()).boundingRect());
|
||||
const QPointF p = item->pos();
|
||||
if (first) {
|
||||
top_left = p;
|
||||
first = false;
|
||||
} else {
|
||||
if (p.x() < top_left.x()) top_left.setX(p.x());
|
||||
if (p.y() < top_left.y()) top_left.setY(p.y());
|
||||
}
|
||||
}
|
||||
|
||||
QSettings settings;
|
||||
const int xGrid = settings.value(QStringLiteral("diagrameditor/Xgrid"),
|
||||
Diagram::xGrid).toInt();
|
||||
const int yGrid = settings.value(QStringLiteral("diagrameditor/Ygrid"),
|
||||
Diagram::yGrid).toInt();
|
||||
const QPointF grid_origin(
|
||||
qRound(group_rect.topLeft().x() / xGrid) * xGrid,
|
||||
qRound(group_rect.topLeft().y() / yGrid) * yGrid);
|
||||
qRound(top_left.x() / xGrid) * xGrid,
|
||||
qRound(top_left.y() / yGrid) * yGrid);
|
||||
|
||||
//Store each item's position. moveTo() applies a grid-snapped
|
||||
//delta from the baseline, so items preserve their layout and
|
||||
|
||||
Reference in New Issue
Block a user