mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-08 04:44:13 +02:00
a5b5d49b98
Edit > "Miroir horizontal" (M) and "Miroir vertical" (F), also in the folio's right-click menu, mirror the selected symbols in place. The keys are the ones the element editor uses for the same two actions. An element keeps two mirrors about its own axes, applied before its rotation, and saves them as mirror="horizontal|vertical|both" on its <element> (written only when set, so other projects save byte for byte as before). On a symbol turned by 90 or 270 degrees, a mirror of the folio is the other mirror of the symbol itself, so the rotation never changes: a label kept upright does not swing round, and "Pivoter" still turns a mirrored symbol clockwise. - Terminals face the mirrored way (Terminal::orientation()), so wires follow. - The symbol stays where it was: its centre is kept, on the grid, since the hotspot is often a corner. - Texts read normally. The element's texts, text groups and cross reference are mirrored a second time about the centre of their own box (Element::keepReadable()), and ElementPictureFactory draws the texts of the symbol itself the same way, in a cached picture per mirror. Groups and cross references held at the bottom of the folio stay centred under their element. - DXF export mirrors the symbol's lines, arcs and texts. - Scripting: qet.mirrorElement(folio, uuid, vertical) and qet.elementMirror(folio, uuid); live mode may run both menu commands; the MCP server gets a mirror_element op and qet_diff reports mirrors. Not done: the parts of a PLC table drawn at run time (Element::drawPlcTable()) are not kept readable on a mirrored PLC; the project database has no column for it, as it has none for the rotation. Test: tst_scriptmirror mirrors a symbol through --run, checks every terminal's side and facing, the round trip, undo, a save and reload, and a symbol turned by 90 degrees. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
128 lines
4.1 KiB
C++
128 lines
4.1 KiB
C++
/*
|
|
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 ELEMENTPICTUREFACTORY_H
|
|
#define ELEMENTPICTUREFACTORY_H
|
|
|
|
#include <QMutex>
|
|
#include <QSharedPointer>
|
|
#include <QHash>
|
|
#include <QPair>
|
|
#include <QTransform>
|
|
|
|
class ElementsLocation;
|
|
class QPicture;
|
|
class QUuid;
|
|
class QDomElement;
|
|
class QPainter;
|
|
class QGraphicsSimpleTextItem;
|
|
|
|
/**
|
|
@brief The ElementPictureFactory class
|
|
This class is singleton factory, use
|
|
to create and get the picture use by elements
|
|
*/
|
|
class ElementPictureFactory
|
|
{
|
|
public :
|
|
struct primitives
|
|
{
|
|
QList<QLineF> m_lines;
|
|
QList<QRectF> m_rectangles;
|
|
QList<QRectF> m_circles;
|
|
QList<QVector<QPointF>> m_polygons;
|
|
QList<QVector<qreal>> m_arcs;
|
|
QList<QGraphicsSimpleTextItem*> m_texts;
|
|
};
|
|
|
|
|
|
/**
|
|
@brief instance
|
|
@return The instance of the factory
|
|
*/
|
|
static ElementPictureFactory* instance()
|
|
{
|
|
static QMutex mutex;
|
|
if (!m_factory)
|
|
{
|
|
mutex.lock();
|
|
if (!m_factory) {
|
|
m_factory = new ElementPictureFactory();
|
|
}
|
|
mutex.unlock();
|
|
}
|
|
return m_factory;
|
|
}
|
|
|
|
/**
|
|
@brief dropInstance
|
|
Drop the instance of factory
|
|
*/
|
|
static void dropInstance()
|
|
{
|
|
static QMutex mutex;
|
|
if (m_factory)
|
|
{
|
|
mutex.lock();
|
|
delete m_factory;
|
|
m_factory = nullptr;
|
|
mutex.unlock();
|
|
}
|
|
}
|
|
|
|
void getPictures(const ElementsLocation &location, QPicture &picture, QPicture &low_picture);
|
|
void getMirroredPictures(const ElementsLocation &location, bool horizontal, bool vertical,
|
|
QPicture &picture, QPicture &low_picture);
|
|
QPixmap pixmap(const ElementsLocation &location);
|
|
ElementPictureFactory::primitives getPrimitives(const ElementsLocation &location);
|
|
void dropCache(const ElementsLocation &location);
|
|
|
|
private:
|
|
ElementPictureFactory() {}
|
|
ElementPictureFactory (const ElementPictureFactory &);
|
|
ElementPictureFactory operator= (const ElementPictureFactory &);
|
|
~ElementPictureFactory();
|
|
|
|
static QUuid cacheKey(const ElementsLocation &location);
|
|
bool build(const ElementsLocation &location, QPicture *picture=nullptr, QPicture *low_picture=nullptr,
|
|
const QTransform &mirror=QTransform());
|
|
void parseElement(const QDomElement &dom, QPainter &painter, primitives &prim) const;
|
|
void parseLine (const QDomElement &dom, QPainter &painter, primitives &prim) const;
|
|
void parseRect (const QDomElement &dom, QPainter &painter, primitives &prim) const;
|
|
void parseEllipse(const QDomElement &dom, QPainter &painter, primitives &prim) const;
|
|
void parseCircle (const QDomElement &dom, QPainter &painter, primitives &prim) const;
|
|
void parseArc (const QDomElement &dom, QPainter &painter, primitives &prim) const;
|
|
void parsePolygon(const QDomElement &dom, QPainter &painter, primitives &prim) const;
|
|
void parseText (const QDomElement &dom, QPainter &painter, primitives &prim) const;
|
|
void parsePlcTable(const QDomElement &dom, const QDomElement &plc_data, QPainter &painter) const;
|
|
void setPainterStyle(const QDomElement &dom, QPainter &painter) const;
|
|
|
|
QHash<QUuid, QPicture> m_pictures_H;
|
|
QHash<QUuid, QPicture> m_low_pictures_H;
|
|
/// Drawings for mirrored elements, by element and mirror
|
|
/// (horizontal, vertical, both), see getMirroredPictures()
|
|
QHash<QPair<QUuid, int>, QPicture> m_mirrored_pictures_H;
|
|
QHash<QPair<QUuid, int>, QPicture> m_mirrored_low_pictures_H;
|
|
/// The mirror build() draws for, read by parseText()
|
|
QTransform m_build_mirror;
|
|
QHash<QUuid, QPixmap> m_pixmap_H;
|
|
QHash<QUuid, primitives> m_primitives_H;
|
|
static ElementPictureFactory* m_factory;
|
|
};
|
|
|
|
#endif // ELEMENTPICTUREFACTORY_H
|