1 /*
2 * LibrePCB - Professional EDA for everyone!
3 * Copyright (C) 2013 LibrePCB Developers, see AUTHORS.md for contributors.
4 * https://librepcb.org/
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 /*******************************************************************************
21 * Includes
22 ******************************************************************************/
23 #include "cmdsymbolinstanceedit.h"
24
25 #include "../items/si_symbol.h"
26
27 #include <QtCore>
28
29 /*******************************************************************************
30 * Namespace
31 ******************************************************************************/
32 namespace librepcb {
33 namespace project {
34
35 /*******************************************************************************
36 * Constructors / Destructor
37 ******************************************************************************/
38
CmdSymbolInstanceEdit(SI_Symbol & symbol)39 CmdSymbolInstanceEdit::CmdSymbolInstanceEdit(SI_Symbol& symbol) noexcept
40 : UndoCommand(tr("Edit symbol instance")),
41 mSymbol(symbol),
42 mOldPos(symbol.getPosition()),
43 mNewPos(mOldPos),
44 mOldRotation(symbol.getRotation()),
45 mNewRotation(mOldRotation),
46 mOldMirrored(symbol.getMirrored()),
47 mNewMirrored(mOldMirrored) {
48 }
49
~CmdSymbolInstanceEdit()50 CmdSymbolInstanceEdit::~CmdSymbolInstanceEdit() noexcept {
51 if (!wasEverExecuted()) {
52 mSymbol.setPosition(mOldPos);
53 mSymbol.setRotation(mOldRotation);
54 mSymbol.setMirrored(mOldMirrored);
55 }
56 }
57
58 /*******************************************************************************
59 * General Methods
60 ******************************************************************************/
61
setPosition(const Point & pos,bool immediate)62 void CmdSymbolInstanceEdit::setPosition(const Point& pos,
63 bool immediate) noexcept {
64 Q_ASSERT(!wasEverExecuted());
65 mNewPos = pos;
66 if (immediate) mSymbol.setPosition(mNewPos);
67 }
68
translate(const Point & deltaPos,bool immediate)69 void CmdSymbolInstanceEdit::translate(const Point& deltaPos,
70 bool immediate) noexcept {
71 Q_ASSERT(!wasEverExecuted());
72 mNewPos += deltaPos;
73 if (immediate) mSymbol.setPosition(mNewPos);
74 }
75
setRotation(const Angle & angle,bool immediate)76 void CmdSymbolInstanceEdit::setRotation(const Angle& angle,
77 bool immediate) noexcept {
78 Q_ASSERT(!wasEverExecuted());
79 mNewRotation = angle;
80 if (immediate) mSymbol.setRotation(mNewRotation);
81 }
82
rotate(const Angle & angle,const Point & center,bool immediate)83 void CmdSymbolInstanceEdit::rotate(const Angle& angle, const Point& center,
84 bool immediate) noexcept {
85 Q_ASSERT(!wasEverExecuted());
86 mNewPos.rotate(angle, center);
87 mNewRotation += mNewMirrored
88 ? -angle
89 : angle; // mirror --> rotation direction is inverted!
90 if (immediate) {
91 mSymbol.setPosition(mNewPos);
92 mSymbol.setRotation(mNewRotation);
93 }
94 }
95
setMirrored(bool mirrored,bool immediate)96 void CmdSymbolInstanceEdit::setMirrored(bool mirrored,
97 bool immediate) noexcept {
98 Q_ASSERT(!wasEverExecuted());
99 mNewMirrored = mirrored;
100 if (immediate) mSymbol.setMirrored(mNewMirrored);
101 }
102
mirror(const Point & center,Qt::Orientation orientation,bool immediate)103 void CmdSymbolInstanceEdit::mirror(const Point& center,
104 Qt::Orientation orientation,
105 bool immediate) noexcept {
106 Q_ASSERT(!wasEverExecuted());
107 bool mirror = !mNewMirrored;
108 Point position = mNewPos;
109 Angle rotation = mNewRotation;
110 switch (orientation) {
111 case Qt::Vertical: {
112 position.setY(position.getY() +
113 Length(2) * (center.getY() - position.getY()));
114 rotation += Angle::deg180();
115 break;
116 }
117 case Qt::Horizontal: {
118 position.setX(position.getX() +
119 Length(2) * (center.getX() - position.getX()));
120 break;
121 }
122 default: {
123 qCritical() << "Invalid orientation:" << orientation;
124 break;
125 }
126 }
127 if (immediate) {
128 mSymbol.setPosition(position);
129 mSymbol.setRotation(rotation);
130 mSymbol.setMirrored(mirror);
131 }
132 mNewMirrored = mirror;
133 mNewPos = position;
134 mNewRotation = rotation;
135 }
136
137 /*******************************************************************************
138 * Inherited from UndoCommand
139 ******************************************************************************/
140
performExecute()141 bool CmdSymbolInstanceEdit::performExecute() {
142 performRedo(); // can throw
143
144 if (mNewPos != mOldPos) return true;
145 if (mNewRotation != mOldRotation) return true;
146 if (mNewMirrored != mOldMirrored) return true;
147 return false;
148 }
149
performUndo()150 void CmdSymbolInstanceEdit::performUndo() {
151 mSymbol.setPosition(mOldPos);
152 mSymbol.setRotation(mOldRotation);
153 mSymbol.setMirrored(mOldMirrored);
154 }
155
performRedo()156 void CmdSymbolInstanceEdit::performRedo() {
157 mSymbol.setPosition(mNewPos);
158 mSymbol.setRotation(mNewRotation);
159 mSymbol.setMirrored(mNewMirrored);
160 }
161
162 /*******************************************************************************
163 * End of File
164 ******************************************************************************/
165
166 } // namespace project
167 } // namespace librepcb
168