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 "cmdcombinenetsignals.h"
24
25 #include <librepcb/common/scopeguard.h>
26 #include <librepcb/project/boards/cmd/cmdboardnetsegmentadd.h>
27 #include <librepcb/project/boards/cmd/cmdboardnetsegmentedit.h>
28 #include <librepcb/project/boards/cmd/cmdboardnetsegmentremove.h>
29 #include <librepcb/project/boards/cmd/cmdboardplaneadd.h>
30 #include <librepcb/project/boards/cmd/cmdboardplaneedit.h>
31 #include <librepcb/project/boards/cmd/cmdboardplaneremove.h>
32 #include <librepcb/project/boards/items/bi_netpoint.h>
33 #include <librepcb/project/circuit/cmd/cmdcompsiginstsetnetsignal.h>
34 #include <librepcb/project/circuit/cmd/cmdnetsignalremove.h>
35 #include <librepcb/project/circuit/netsignal.h>
36 #include <librepcb/project/schematics/cmd/cmdschematicnetsegmentadd.h>
37 #include <librepcb/project/schematics/cmd/cmdschematicnetsegmentedit.h>
38 #include <librepcb/project/schematics/cmd/cmdschematicnetsegmentremove.h>
39 #include <librepcb/project/schematics/items/si_netline.h>
40 #include <librepcb/project/schematics/items/si_netpoint.h>
41 #include <librepcb/project/schematics/items/si_netsegment.h>
42
43 #include <QtCore>
44
45 /*******************************************************************************
46 * Namespace
47 ******************************************************************************/
48 namespace librepcb {
49 namespace project {
50 namespace editor {
51
52 /*******************************************************************************
53 * Constructors / Destructor
54 ******************************************************************************/
55
CmdCombineNetSignals(Circuit & circuit,NetSignal & toBeRemoved,NetSignal & result)56 CmdCombineNetSignals::CmdCombineNetSignals(Circuit& circuit,
57 NetSignal& toBeRemoved,
58 NetSignal& result) noexcept
59 : UndoCommandGroup(tr("Combine Net Signals")),
60 mCircuit(circuit),
61 mNetSignalToRemove(toBeRemoved),
62 mResultingNetSignal(result) {
63 }
64
~CmdCombineNetSignals()65 CmdCombineNetSignals::~CmdCombineNetSignals() noexcept {
66 }
67
68 /*******************************************************************************
69 * Inherited from UndoCommand
70 ******************************************************************************/
71
performExecute()72 bool CmdCombineNetSignals::performExecute() {
73 // if an error occurs, undo all already executed child commands
74 auto undoScopeGuard = scopeGuard([&]() { performUndo(); });
75
76 // determine all elements which need to be removed temporary
77 QList<SI_NetSegment*> schematicNetSegments =
78 mNetSignalToRemove.getSchematicNetSegments();
79 QList<BI_NetSegment*> boardNetSegments =
80 mNetSignalToRemove.getBoardNetSegments();
81 QList<BI_Plane*> boardPlanes = mNetSignalToRemove.getBoardPlanes();
82
83 // remove all schematic netsegments
84 foreach (SI_NetSegment* netsegment, schematicNetSegments) {
85 execNewChildCmd(new CmdSchematicNetSegmentRemove(*netsegment));
86 }
87
88 // remove all board netsegments
89 foreach (BI_NetSegment* netsegment, boardNetSegments) {
90 execNewChildCmd(new CmdBoardNetSegmentRemove(*netsegment)); // can throw
91 }
92
93 // remove all board planes
94 foreach (BI_Plane* plane, boardPlanes) {
95 execNewChildCmd(new CmdBoardPlaneRemove(*plane)); // can throw
96 }
97
98 // change netsignal of all component signal instances
99 foreach (ComponentSignalInstance* signal,
100 mNetSignalToRemove.getComponentSignals()) {
101 execNewChildCmd(new CmdCompSigInstSetNetSignal(
102 *signal, &mResultingNetSignal)); // can throw
103 }
104
105 // re-add all board netsegments
106 foreach (BI_NetSegment* netsegment, boardNetSegments) {
107 CmdBoardNetSegmentEdit* cmd = new CmdBoardNetSegmentEdit(*netsegment);
108 cmd->setNetSignal(mResultingNetSignal);
109 execNewChildCmd(cmd); // can throw
110 execNewChildCmd(new CmdBoardNetSegmentAdd(*netsegment)); // can throw
111 }
112
113 // re-add all board planes
114 foreach (BI_Plane* plane, boardPlanes) {
115 CmdBoardPlaneEdit* cmd = new CmdBoardPlaneEdit(*plane, false);
116 cmd->setNetSignal(mResultingNetSignal);
117 execNewChildCmd(cmd); // can throw
118 execNewChildCmd(new CmdBoardPlaneAdd(*plane)); // can throw
119 }
120
121 // re-add all schematic netsegments
122 foreach (SI_NetSegment* netsegment, schematicNetSegments) {
123 auto* cmd = new CmdSchematicNetSegmentEdit(*netsegment);
124 cmd->setNetSignal(mResultingNetSignal);
125 execNewChildCmd(cmd);
126 execNewChildCmd(new CmdSchematicNetSegmentAdd(*netsegment));
127 }
128
129 // remove the old netsignal
130 execNewChildCmd(
131 new CmdNetSignalRemove(mCircuit, mNetSignalToRemove)); // can throw
132
133 undoScopeGuard.dismiss(); // no undo required
134 return true;
135 }
136
137 /*******************************************************************************
138 * End of File
139 ******************************************************************************/
140
141 } // namespace editor
142 } // namespace project
143 } // namespace librepcb
144