A dragged shape put its pos() on the grid. pos() cannot be seen, and it
is off the drawn corner whenever the shape was drawn or resized with
Ctrl held, or rotated, so such a shape stayed off the grid however it
was dragged. Worse, Snap to grid (previous commit) moves pos() off the
grid to put the corner on it, so the next drag undid the snap.
QetShapeItem now overrides setPos(), which only the drag calls through
the virtual: dragged alone or with other shapes only, the top-left
corner of the drawn outline goes on the grid. Dragged together with
anything else it snaps by pos() as before, because the rest of the
selection follows this shape's movement and a corner correction would
take the symbols off the grid. Ctrl still drags freely: the snap goes
through Diagram::snapToGrid(), which reads it.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Rectangles, ellipses, lines and polygons were left out of the Align
submenu: with only shapes selected every command was greyed out, and a
shape outside a group was ignored when aligning it with a symbol.
Shapes now take part like pictures. Their edges are the shape as drawn
(the new QetShapeItem::sceneOutlineRect(), without the pen, the 6 px
selection margin or the wider hover outline; the old code used
sceneBoundingRect() for grouped shapes and so aligned them 6 px off).
The point that goes on the grid is the top-left corner of that box: a
rectangle's corner, an ellipse's box. pos() is not used, because a
shape drawn with Ctrl held or rotated has its corners off the grid
while pos() is on it.
The menu's enable rule now counts what the command counts, a group as
one. Before, two symbols in one group enabled the six align commands,
which then did nothing and only said so in the status bar.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Now that they carry a uuid, the folio's drawing furniture gets rows of its
own: shape, independent_text and image, plus drawing_item_view, which finds
any of them by uuid without knowing its kind first and says which folio it
is on.
Rows follow edits, not just loads. The script API's query() and every
other reader go through newQuery() without a rebuild, so an item's row is
queued on each change (moves, restyles, text edits, uuid renewal) and the
queue is flushed by newQuery() and updateDB() -- a queued write is a set
insertion, which matters for a drag that moves hundreds of items per mouse
step.
A pasted copy joins its folio still carrying its source's uuid and is only
renewed afterwards, so a flush in between must not let the copy overwrite
its source's row. Each row remembers the item that wrote it; another item
with the same uuid waits until uuidChanged() says it has its own.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Elements, conductors, terminals and tables already carry a uuid. The
drawing furniture beside them did not, so a script or the MCP server could
only name a line, a box or a note by its index in a position-sorted list,
which shifts whenever one is added or removed.
- QetShapeItem, IndependentTextItem and DiagramImageItem get uuid(),
newUuid() and setUuid(), read from and written to a "uuid" attribute.
- A folio loaded from a file written before this (or carrying a duplicate
uuid) derives one from the folio uuid, the item kind and its order in the
file, so the same file gives the same uuids on every load and a re-save
is stable -- the #754 lesson for conductors.
- Paste and folio duplication renew them, as they already do for elements
and conductors.
- Scripting: texts(), shapes() and images() end each line with the uuid;
textIndex(), shapeIndex() and imageIndex() turn one back into an index.
- misc/qet-mcp: qet_diff keys texts, shapes and images on uuid when both
sides have one, so a move or edit reads as a change to that item.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Shapes and images can now be resized, rotated, and skewed directly
on the canvas, not just moved. Both share one small transform
struct (rotation, then skew, then scale, anchored on a movable
pivot) and one handle widget, so a corner drag, an edge skew, or
grabbing the rotate handle behaves the same way and runs through
the same matrix math everywhere, instead of every item type
reinventing its own.
Shapes also gained a proper pen tool (bezier paths, corner/smooth/
symmetric nodes), arc support, and mirroring. Images gained
non-destructive cropping and colour-keyed transparency, both
remember their own settings, so reopening the dialog picks up
where you left off instead of starting over.
Properties dialogs for both were extended to match (position,
size, angle, skew), with undo/redo wired through for every handle
drag.
Old XML files can read easily as the transformation is only added
if needed and the old syntax is still used and understood if it is
not needed.
qAsConst was deprecated in Qt 6.6; std::as_const (C++17, already the
project standard) is the drop-in replacement. Clears 46 -Wdeprecated-
declarations warnings across 18 files. No behavioural change.
clazy is a compiler plugin which allows clang to understand Qt
semantics. You get more than 50 Qt related compiler warnings, ranging
from unneeded memory allocations to misusage of API, including fix-its
for automatic refactoring.
https://invent.kde.org/sdk/clazy
Add a combo box in the tool bar of diagram editor
to quickly change the size of the graphics handler item.
The sarto commit :D
NOTE
only available for diagram editor, element editor will
come later.