mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-08 13:04:13 +02:00
35162b6731
Edit > Scale element... scales the whole element about its hotspot by a factor picked from x0.5, x1.5, x2, x2.5, x3, x4. Only the factors that leave every terminal on the 10 px folio grid are offered, so wires to a scaled element stay straight. An element whose terminals are off the grid today is offered only the factors that bring them on to it; if none does, the dialog says so and OK is disabled. Drawn parts are scaled with their existing handleUserTransformation(), as the resize handles do. Texts, dynamic text fields and terminals are set directly so that font sizes (whole points, 4 pt minimum), terminal name offsets and line end sizes scale too, which the resize handles do not do. One undo step restores the element. Unlike "Import an element to resize", this needs no external program and works on the element being edited. Grew out of issue #1338. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
352 lines
9.5 KiB
C++
352 lines
9.5 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 EDITOR_COMMANDS_H
|
|
#define EDITOR_COMMANDS_H
|
|
#include "../editor/graphicspart/customelementpart.h"
|
|
#include "../qgimanager.h"
|
|
#include "elementcontent.h"
|
|
#include "elementscene.h"
|
|
#include "elementview.h"
|
|
#include "graphicspart/abstractpartellipse.h"
|
|
#include "graphicspart/customelementgraphicpart.h"
|
|
#include "graphicspart/customelementpart.h"
|
|
#include "graphicspart/partarc.h"
|
|
#include "graphicspart/partdynamictextfield.h"
|
|
#include "graphicspart/partellipse.h"
|
|
#include "graphicspart/partline.h"
|
|
#include "graphicspart/partpolygon.h"
|
|
#include "graphicspart/partrectangle.h"
|
|
#include "graphicspart/partterminal.h"
|
|
#include "graphicspart/parttext.h"
|
|
#include "../QPropertyUndoCommand/qpropertyundocommand.h"
|
|
#include "UndoCommand/deletepartscommand.h"
|
|
|
|
|
|
/**
|
|
@brief The ElementEditionCommand class
|
|
ElementEditionCommand is the base class for all commands classes involved in
|
|
the edition of an electrical element. It provides commonly required methods
|
|
and attributes, such as accessors to the modified scene and view.
|
|
*/
|
|
class ElementEditionCommand : public QUndoCommand
|
|
{
|
|
// constructors, destructor
|
|
public:
|
|
ElementEditionCommand(ElementScene * = nullptr,
|
|
ElementView * = nullptr,
|
|
QUndoCommand * = nullptr);
|
|
ElementEditionCommand(const QString &,
|
|
ElementScene * = nullptr,
|
|
ElementView * = nullptr,
|
|
QUndoCommand * = nullptr);
|
|
~ElementEditionCommand() override;
|
|
private:
|
|
ElementEditionCommand(const ElementEditionCommand &);
|
|
|
|
// methods
|
|
public:
|
|
ElementScene *elementScene() const;
|
|
void setElementScene(ElementScene *);
|
|
ElementView *elementView() const;
|
|
void setElementView(ElementView *);
|
|
|
|
// attributes
|
|
protected:
|
|
/// Element editor/view/scene the command should take place on
|
|
ElementScene *m_scene;
|
|
ElementView *m_view;
|
|
};
|
|
|
|
/**
|
|
This command cut primitives when editing an electrical element.
|
|
*/
|
|
class CutPartsCommand : public DeletePartsCommand {
|
|
// constructors, destructor
|
|
public:
|
|
CutPartsCommand(ElementScene *, const QList<QGraphicsItem *>&, QUndoCommand * = nullptr);
|
|
~CutPartsCommand() override;
|
|
private:
|
|
CutPartsCommand(const CutPartsCommand &);
|
|
};
|
|
|
|
/**
|
|
This command moves primitives when editing an electrical element.
|
|
*/
|
|
class MovePartsCommand : public ElementEditionCommand {
|
|
// constructors, destructor
|
|
public:
|
|
MovePartsCommand(const QPointF &, ElementScene *, const QList<QGraphicsItem *>&, QUndoCommand * = nullptr);
|
|
~MovePartsCommand() override;
|
|
private:
|
|
MovePartsCommand(const MovePartsCommand &);
|
|
|
|
// methods
|
|
public:
|
|
void undo() override;
|
|
void redo() override;
|
|
|
|
// attributes
|
|
private:
|
|
/// List of moved primitives
|
|
QList<QGraphicsItem *> moved_parts;
|
|
/// applied movement
|
|
QPointF movement;
|
|
/// Prevent the first call to redo()
|
|
bool first_redo;
|
|
};
|
|
|
|
/**
|
|
This command changes the translated names of an electrical element.
|
|
*/
|
|
class ChangeNamesCommand : public ElementEditionCommand {
|
|
// constructors, destructor
|
|
public:
|
|
ChangeNamesCommand(ElementScene *, const NamesList &, const NamesList &, QUndoCommand * = nullptr);
|
|
~ChangeNamesCommand() override;
|
|
private:
|
|
ChangeNamesCommand(const ChangeNamesCommand &);
|
|
|
|
// methods
|
|
public:
|
|
void undo() override;
|
|
void redo() override;
|
|
|
|
// attributes
|
|
private:
|
|
/// List of former names
|
|
NamesList names_before;
|
|
/// List of new names
|
|
NamesList names_after;
|
|
};
|
|
|
|
/**
|
|
This command changes the zValue of a set of primitives when editing an
|
|
electrical element.
|
|
*/
|
|
class ChangeZValueCommand : public ElementEditionCommand
|
|
{
|
|
// constructors, destructor
|
|
public:
|
|
ChangeZValueCommand(ElementScene *, QET::DepthOption , QUndoCommand * = nullptr);
|
|
~ChangeZValueCommand() override;
|
|
private:
|
|
ChangeZValueCommand(const ChangeZValueCommand &);
|
|
|
|
// methods
|
|
public:
|
|
void undo() override;
|
|
void redo() override;
|
|
|
|
private:
|
|
void applyBringForward(const QList<QGraphicsItem *> &);
|
|
void applyRaise(const QList<QGraphicsItem *> &);
|
|
void applyLower(const QList<QGraphicsItem *> &);
|
|
void applySendBackward(const QList<QGraphicsItem *> &);
|
|
|
|
// attributes
|
|
private:
|
|
/// associates impacted primitives with their former zValues
|
|
QHash<QGraphicsItem *, qreal> undo_hash;
|
|
/// associates impacted primitives with their new zValues
|
|
QHash<QGraphicsItem *, qreal> redo_hash;
|
|
/// kind of treatment to apply
|
|
QET::DepthOption m_option;
|
|
};
|
|
|
|
/**
|
|
This command changes extra information carried by an electrical element.
|
|
*/
|
|
class ChangeInformationsCommand : public ElementEditionCommand {
|
|
// constructors, destructor
|
|
public:
|
|
ChangeInformationsCommand(ElementScene *, const QString &, const QString &, QUndoCommand * = nullptr);
|
|
~ChangeInformationsCommand() override;
|
|
private:
|
|
ChangeInformationsCommand(const ChangeInformationsCommand &);
|
|
|
|
// methods
|
|
public:
|
|
void undo() override;
|
|
void redo() override;
|
|
|
|
// attributes
|
|
private:
|
|
/// Former information
|
|
QString old_informations_;
|
|
/// New information
|
|
QString new_informations_;
|
|
};
|
|
|
|
/**
|
|
This command scales primitives when editing an electrical element.
|
|
*/
|
|
class ScalePartsCommand : public ElementEditionCommand {
|
|
// constructors, destructor
|
|
public:
|
|
ScalePartsCommand(ElementScene * = nullptr, QUndoCommand * = nullptr);
|
|
~ScalePartsCommand() override;
|
|
private:
|
|
ScalePartsCommand(const ScalePartsCommand &);
|
|
|
|
// methods
|
|
public:
|
|
void undo() override;
|
|
void redo() override;
|
|
ElementScene *elementScene() const;
|
|
void setScaledPrimitives(const QList<CustomElementPart *> &);
|
|
QList<CustomElementPart *> scaledPrimitives() const;
|
|
void setTransformation(const QRectF &, const QRectF &);
|
|
QPair<QRectF, QRectF> transformation();
|
|
|
|
protected:
|
|
void scale(const QRectF &before, const QRectF &after);
|
|
void adjustText();
|
|
|
|
// attributes
|
|
private:
|
|
/// List of moved primitives
|
|
QList<CustomElementPart *> scaled_primitives_;
|
|
/// original rect items fit in
|
|
QRectF original_rect_;
|
|
/// new rect items should fit in
|
|
QRectF new_rect_;
|
|
/// Prevent the first call to redo()
|
|
bool first_redo;
|
|
};
|
|
|
|
class changeElementDataCommand : public ElementEditionCommand
|
|
{
|
|
public:
|
|
changeElementDataCommand(ElementScene *scene,
|
|
ElementData old_data,
|
|
ElementData new_data,
|
|
QUndoCommand *parent = nullptr);
|
|
~changeElementDataCommand() override {}
|
|
|
|
void undo() override;
|
|
void redo() override;
|
|
|
|
private:
|
|
ElementData m_old,
|
|
m_new;
|
|
};
|
|
|
|
/**
|
|
@brief The RotateSelectionInESCommand class
|
|
Rotate the selected items in the element editor
|
|
*/
|
|
|
|
class RotateElementsCommand : public ElementEditionCommand
|
|
{
|
|
|
|
public:
|
|
RotateElementsCommand(ElementScene *scene, QUndoCommand *parent=nullptr);
|
|
void undo() override;
|
|
void redo() override;
|
|
|
|
private:
|
|
ElementScene *m_scene =nullptr;
|
|
QList<QGraphicsItem*> m_items;
|
|
|
|
};
|
|
|
|
class RotateFineElementsCommand : public ElementEditionCommand
|
|
{
|
|
|
|
public:
|
|
RotateFineElementsCommand(ElementScene *scene, QUndoCommand *parent=nullptr);
|
|
void undo() override;
|
|
void redo() override;
|
|
|
|
private:
|
|
ElementScene *m_scene =nullptr;
|
|
QList<QGraphicsItem*> m_items;
|
|
|
|
};
|
|
|
|
/**
|
|
@brief The MirrorElementsCommand class
|
|
Mirror the selected parts horizontally (left <-> right) across the
|
|
vertical line through the center of the selection, so the selection
|
|
keeps its place in the scene.
|
|
*/
|
|
class MirrorElementsCommand : public ElementEditionCommand
|
|
{
|
|
public:
|
|
MirrorElementsCommand(ElementScene *scene, QUndoCommand *parent=nullptr);
|
|
void undo() override;
|
|
void redo() override;
|
|
private:
|
|
ElementScene *m_scene =nullptr;
|
|
QList<QGraphicsItem*> m_items;
|
|
qreal m_axis_x = 0;
|
|
};
|
|
|
|
/**
|
|
@brief The FlipElementsCommand class
|
|
Flip the selected parts vertically (top <-> bottom) across the
|
|
horizontal line through the center of the selection, so the selection
|
|
keeps its place in the scene.
|
|
*/
|
|
class FlipElementsCommand : public ElementEditionCommand
|
|
{
|
|
public:
|
|
FlipElementsCommand(ElementScene *scene, QUndoCommand *parent=nullptr);
|
|
void undo() override;
|
|
void redo() override;
|
|
private:
|
|
ElementScene *m_scene =nullptr;
|
|
QList<QGraphicsItem*> m_items;
|
|
qreal m_axis_y = 0;
|
|
};
|
|
|
|
/**
|
|
@brief The ScaleElementCommand class
|
|
Scales the whole element about its hotspot by a fixed factor, as one
|
|
undo step. Drawn parts are scaled the way the resize handles scale them;
|
|
texts, dynamic text fields and terminals are set explicitly, so their
|
|
font sizes, terminal name offsets and line end sizes follow too, and a
|
|
terminal lands exactly on its new position.
|
|
*/
|
|
class ScaleElementCommand : public ElementEditionCommand
|
|
{
|
|
public:
|
|
ScaleElementCommand(ElementScene *scene, qreal factor,
|
|
bool scale_text, QUndoCommand *parent = nullptr);
|
|
void undo() override;
|
|
void redo() override;
|
|
|
|
private:
|
|
struct PropertyChange {
|
|
QObject *object;
|
|
QByteArray name;
|
|
QVariant before;
|
|
QVariant after;
|
|
};
|
|
void addChange(QObject *object, const char *name, const QVariant &after);
|
|
void scaleGeometry(qreal from, qreal to);
|
|
|
|
qreal m_factor;
|
|
/// Parts scaled through handleUserTransformation()
|
|
QList<CustomElementPart *> m_geometry_parts;
|
|
/// Values set directly, in the order they are applied
|
|
QList<PropertyChange> m_changes;
|
|
};
|
|
|
|
#endif
|