1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2019 Alexander Shuklin <Jasuramme@gmail.com>
5  * Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
23  */
24 
25 
26 #ifndef BACKANNOTATE_H
27 #define BACKANNOTATE_H
28 
29 #include <deque>
30 #include <map>
31 #include <memory>
32 #include <sch_reference_list.h>
33 #include <template_fieldnames.h>
34 #include <wx/string.h>
35 
36 // Forward declarations
37 class REPORTER;
38 class SCH_SHEET_LIST;
39 class SCH_EDIT_FRAME;
40 
41 
42 /**
43  * Back annotation algorithm class used to receive, check, and apply a \ref NETLIST from
44  * Pcbnew.
45  *
46  * The following checks are made:
47  * - Schematic symbol exists, but linked Pcbnew footprint missing.
48  * - Pcbnew footprint exists but no schematic symbol connected to.
49  * - Pcbnew footprint is standalone.
50  * - Schematic sheet is reused one or more times and user trying to change footprint or value
51  *   only for few of them.
52  * - Schematic symbols share same path.
53  * - More than one Pcbnew footprint linked to same path.
54  */
55 class BACK_ANNOTATE
56 {
57 public:
58     /**
59      * Container for Pcbnew footprint data.
60      */
61     struct PCB_FP_DATA
62     {
PCB_FP_DATAPCB_FP_DATA63         PCB_FP_DATA( const wxString& aRef, const wxString& aFootprint, const wxString& aValue,
64                      const std::map<wxString, wxString> aPinMap ) :
65                 m_ref( aRef ),
66                 m_footprint( aFootprint ),
67                 m_value( aValue ),
68                 m_pinMap( aPinMap )
69         {};
70 
71         wxString m_ref;
72         wxString m_footprint;
73         wxString m_value;
74         std::map<wxString, wxString> m_pinMap;
75     };
76 
77     ///< Map to hold NETLIST footprints data
78     using PCB_FOOTPRINTS_MAP = std::map<wxString, std::shared_ptr<PCB_FP_DATA>>;
79 
80     using CHANGELIST_ITEM = std::pair<SCH_REFERENCE, std::shared_ptr<PCB_FP_DATA>>;
81 
82     BACK_ANNOTATE( SCH_EDIT_FRAME* aFrame, REPORTER& aReporter, bool aRelinkFootprints,
83                    bool aProcessFootprints, bool aProcessValues, bool aProcessReferences,
84                    bool aProcessNetNames, bool aDryRun );
85     ~BACK_ANNOTATE();
86 
87     /**
88      * Get netlist from the Pcbnew.
89      *
90      * @param aNetlist is the netlist for the board editor.
91      * @return true if success.
92      */
93     bool FetchNetlistFromPCB( std::string& aNetlist );
94 
95     void PushNewLinksToPCB();
96 
97     /**
98      * Run back annotation algorithm. If any errors, back annotation doesn't run.
99      *
100      * @param aNetlist is the netlist to use for back annotation.
101      * @return true if back annotation completed success.
102      */
103     bool BackAnnotateSymbols( const std::string& aNetlist );
104 
105 private:
106     /**
107      * Parse netlist sent over KiWay express mail interface and fill \ref m_pcbModules.
108      *
109      * @param aPayload is the netlist from Pcbnew.
110      * @return number of errors during parsing.
111      */
112     void getPcbModulesFromString( const std::string& aPayload );
113 
114     ///< Create changelist.
115     void getChangeList();
116 
117     /**
118      * Check if some symbols are not represented in PCB footprints and vice versa.
119      *
120      * \ref m_refs must be sorted by path.
121      */
122     void checkForUnusedSymbols();
123 
124     /**
125      * Apply changelist to the schematic.
126      */
127     void applyChangelist();
128 
129     void processNetNameChange( const wxString& aRef, SCH_PIN* aPin,
130                                const SCH_CONNECTION* aConnection, const wxString& aOldName,
131                                const wxString& aNewName );
132 
133     REPORTER&                    m_reporter;
134 
135     bool                         m_matchByReference;
136     bool                         m_processFootprints;
137     bool                         m_processValues;
138     bool                         m_processReferences;
139     bool                         m_processNetNames;
140     bool                         m_dryRun;
141 
142     PCB_FOOTPRINTS_MAP           m_pcbFootprints;
143     SCH_REFERENCE_LIST           m_refs;
144     SCH_MULTI_UNIT_REFERENCE_MAP m_multiUnitsRefs;
145     std::deque<CHANGELIST_ITEM>  m_changelist;
146     SCH_EDIT_FRAME*              m_frame;
147 
148     int                          m_changesCount;    // Number of user-level changes
149     bool                         m_appendUndo;
150 };
151 
152 #endif
153