Extract a pure virtual IShape interface from AbstractShapeType<T> so
selectors and Document use dynamic_cast<IShape *> instead of
qgraphicsitem_cast<AbstractShape *>. This decouples the selector
system from the template hierarchy, enabling GraphicsTextItem (backed
by QGraphicsTextItem) to work uniformly with all existing selectors.
GraphicsTextItem supports inline text editing (double-click to edit,
focus-out to finish), font/color properties via PropertyEditor, resize
with proportional font scaling, move, rotate, and full serialization.
Adds CM_place creation mode for single-click placement.
Move per-type serialization logic out of Document's monolithic
serializeItem()/deserializeItem() into each item class:
- Add virtual serialize() to AbstractShapeType template, overridden by
GraphicsRectItem, GraphicPolygonItem, and GraphicsItemGroup
- Add static createFromJson() factory + self-registration to each item
- Extract shared pen/brush/common helpers into serializationUtils
- Add type registry (serializationRegistry) for factory-based deserialization
- Document::saveAs()/load() now delegate to item->serialize() and
createItemFromJson() — no longer owns per-type dispatch
- Adding a new shape type no longer requires touching Document