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