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 "cmddeviceinstanceedit.h"
24
25 #include "../items/bi_device.h"
26
27 #include <QtCore>
28
29 /*******************************************************************************
30 * Namespace
31 ******************************************************************************/
32 namespace librepcb {
33 namespace project {
34
35 /*******************************************************************************
36 * Constructors / Destructor
37 ******************************************************************************/
38
CmdDeviceInstanceEdit(BI_Device & dev)39 CmdDeviceInstanceEdit::CmdDeviceInstanceEdit(BI_Device& dev) noexcept
40 : UndoCommand(tr("Edit device instance")),
41 mDevice(dev),
42 mOldPos(mDevice.getPosition()),
43 mNewPos(mOldPos),
44 mOldRotation(mDevice.getRotation()),
45 mNewRotation(mOldRotation),
46 mOldMirrored(mDevice.getIsMirrored()),
47 mNewMirrored(mOldMirrored) {
48 }
49
~CmdDeviceInstanceEdit()50 CmdDeviceInstanceEdit::~CmdDeviceInstanceEdit() noexcept {
51 if (!wasEverExecuted()) {
52 try {
53 mDevice.setPosition(mOldPos);
54 mDevice.setRotation(mOldRotation);
55 mDevice.setIsMirrored(mOldMirrored); // can throw
56 } catch (Exception& e) {
57 qCritical() << "Could not revert all changes:" << e.getMsg();
58 }
59 }
60 }
61
62 /*******************************************************************************
63 * General Methods
64 ******************************************************************************/
65
setPosition(const Point & pos,bool immediate)66 void CmdDeviceInstanceEdit::setPosition(const Point& pos,
67 bool immediate) noexcept {
68 Q_ASSERT(!wasEverExecuted());
69 mNewPos = pos;
70 if (immediate) mDevice.setPosition(mNewPos);
71 }
72
translate(const Point & deltaPos,bool immediate)73 void CmdDeviceInstanceEdit::translate(const Point& deltaPos,
74 bool immediate) noexcept {
75 Q_ASSERT(!wasEverExecuted());
76 mNewPos += deltaPos;
77 if (immediate) mDevice.setPosition(mNewPos);
78 }
79
setRotation(const Angle & angle,bool immediate)80 void CmdDeviceInstanceEdit::setRotation(const Angle& angle,
81 bool immediate) noexcept {
82 Q_ASSERT(!wasEverExecuted());
83 mNewRotation = angle;
84 if (immediate) mDevice.setRotation(mNewRotation);
85 }
86
rotate(const Angle & angle,const Point & center,bool immediate)87 void CmdDeviceInstanceEdit::rotate(const Angle& angle, const Point& center,
88 bool immediate) noexcept {
89 Q_ASSERT(!wasEverExecuted());
90 mNewPos.rotate(angle, center);
91 mNewRotation += mNewMirrored
92 ? -angle
93 : angle; // mirror --> rotation direction is inverted!
94 if (immediate) {
95 mDevice.setPosition(mNewPos);
96 mDevice.setRotation(mNewRotation);
97 }
98 }
99
setMirrored(bool mirrored,bool immediate)100 void CmdDeviceInstanceEdit::setMirrored(bool mirrored, bool immediate) {
101 Q_ASSERT(!wasEverExecuted());
102 if (immediate) {
103 mDevice.setIsMirrored(mirrored); // can throw
104 }
105 mNewMirrored = mirrored;
106 }
107
mirror(const Point & center,Qt::Orientation orientation,bool immediate)108 void CmdDeviceInstanceEdit::mirror(const Point& center,
109 Qt::Orientation orientation,
110 bool immediate) {
111 Q_ASSERT(!wasEverExecuted());
112 bool mirror = !mNewMirrored;
113 Point position = mNewPos;
114 Angle rotation = mNewRotation;
115 switch (orientation) {
116 case Qt::Vertical: {
117 position.setY(position.getY() +
118 Length(2) * (center.getY() - position.getY()));
119 rotation += Angle::deg180();
120 break;
121 }
122 case Qt::Horizontal: {
123 position.setX(position.getX() +
124 Length(2) * (center.getX() - position.getX()));
125 break;
126 }
127 default: {
128 qCritical() << "Invalid orientation:" << orientation;
129 break;
130 }
131 }
132 if (immediate) {
133 mDevice.setIsMirrored(mirror); // can throw
134 mDevice.setPosition(position);
135 mDevice.setRotation(rotation);
136 }
137 mNewMirrored = mirror;
138 mNewPos = position;
139 mNewRotation = rotation;
140 }
141
142 /*******************************************************************************
143 * Inherited from UndoCommand
144 ******************************************************************************/
145
performExecute()146 bool CmdDeviceInstanceEdit::performExecute() {
147 performRedo(); // can throw
148
149 if (mNewPos != mOldPos) return true;
150 if (mNewRotation != mOldRotation) return true;
151 if (mNewMirrored != mOldMirrored) return true;
152 return false;
153 }
154
performUndo()155 void CmdDeviceInstanceEdit::performUndo() {
156 mDevice.setIsMirrored(mOldMirrored); // can throw
157 mDevice.setPosition(mOldPos);
158 mDevice.setRotation(mOldRotation);
159 }
160
performRedo()161 void CmdDeviceInstanceEdit::performRedo() {
162 mDevice.setIsMirrored(mNewMirrored); // can throw
163 mDevice.setPosition(mNewPos);
164 mDevice.setRotation(mNewRotation);
165 }
166
167 /*******************************************************************************
168 * End of File
169 ******************************************************************************/
170
171 } // namespace project
172 } // namespace librepcb
173