1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2020 Brian Piccioni brian@documenteddesigns.com
5  * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
6  * @author Brian Piccioni <brian@documenteddesigns.com>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
24  */
25 
26 #ifndef DIALOG_BOARD_REANNOTATE_H_
27 #define DIALOG_BOARD_REANNOTATE_H_
28 
29 #include <board.h>
30 #include <footprint.h>
31 #include <dialogs/dialog_board_reannotate_base.h>
32 #include <layer_ids.h>
33 #include <netlist_reader/pcb_netlist.h>
34 #include <pcb_base_frame.h>
35 #include <pcb_edit_frame.h>
36 #include <project.h>
37 #include <wx_html_report_panel.h>
38 
39 #include <frame_type.h>
40 #include <tool/actions.h>
41 #include <tool/tool_manager.h>
42 #include <tools/pcb_selection_tool.h>
43 
44 #define SORTXFIRST 0b000       // Sort on X
45 #define SORTYFIRST 0b100       // Sort on Y
46 #define ASCENDINGFIRST 0b000   // Sort low to high
47 #define DESCENDINGFIRST 0b010  // Sort high to low
48 #define ASCENDINGSECOND 0b000  // Sort low to high
49 #define DESCENDINGSECOND 0b001 // Sort high to low
50 
51 #define MINGRID 1000
52 #define MAXERROR 10
53 #define VALIDPREFIX "_-+=/\\"  // Prefixs can be alpha or these symbols
54 
55 enum ActionCode
56 {
57     UpdateRefDes,
58     EmptyRefDes,
59     InvalidRefDes,
60     Exclude
61 };
62 
63 enum AnnotationChoice
64 {
65     AnnotateAll,
66     AnnotateFront,
67     AnnotateBack,
68     AnnotateSelected
69 };
70 
71 struct RefDesChange
72 {
73     KIID        Uuid;
74     wxString    NewRefDes;          // The new reference designation (F_U21)
75     wxString    OldRefDesString;    // What the old refdes preamble + number was
76     bool        Front;              // True if on the front of the board
77     ActionCode  Action;             // Used to skip (if #, etc)
78 };
79 
80 struct RefDesInfo
81 {
82     KIID        Uuid;
83     bool        Front;              // True if on the front of the board
84     wxString    RefDesString;       // What its refdes is R1, C2
85     wxString    RefDesType;         // ie R, C, etc
86     int         x, y;               // The coordinates
87     int         roundedx, roundedy; // The coordinates after rounding.
88     ActionCode  Action;             // Used to skip (if #, etc)
89     LIB_ID      FPID;
90 };
91 
92 struct RefDesTypeStr
93 {
94     wxString     RefDesType;
95     unsigned int LastUsedRefDes;
96     std::set<unsigned int> UnavailableRefs;
97 };
98 
99 
100 class DIALOG_BOARD_REANNOTATE : public DIALOG_BOARD_REANNOTATE_BASE
101 {
102 public:
103     DIALOG_BOARD_REANNOTATE( PCB_EDIT_FRAME* aParentFrame );
104     ~DIALOG_BOARD_REANNOTATE();
105 
106 private:
107     std::vector<wxRadioButton*> m_sortButtons = {
108             m_Down_Right,
109             m_Right_Down,
110             m_Down_Left,
111             m_Left_Down,
112             m_Up_Right,
113             m_Right_Up,
114             m_Up_Left,
115             m_Left_Up
116     };
117 
118     std::vector<wxRadioButton*> AnnotateWhat = {
119             m_AnnotateAll,
120             m_AnnotateFront,
121             m_AnnotateBack,
122             m_AnnotateSelection
123     };
124 
125     std::vector<wxStaticBitmap*> Bitmaps = {
126             reannotate_down_right_bitmap,
127             reannotate_right_down_bitmap,
128             reannotate_down_left_bitmap,
129             reannotate_left_down_bitmap,
130             reannotate_up_right_bitmap,
131             reannotate_right_up_bitmap,
132             reannotate_up_left_bitmap,
133             reannotate_left_up_bitmap
134     };
135 
136     void GetParameters( void );
137 
138     /// Copy saved app settings to the dialog.
139     void InitValues( void );
140 
141     void OnApplyClick( wxCommandEvent& event ) override;
142     void OnCloseClick( wxCommandEvent& event ) override;
143     void FilterFrontPrefix( wxCommandEvent& event ) override;
144     void FilterBackPrefix( wxCommandEvent& event ) override;
145 
146     /// Break report into strings separated by \n and sent to the reporter.
147     void ShowReport( const wxString& aMessage, SEVERITY aSeverity );
148 
149 	/// Create a list of the footprints and their coordinates.
150     void LogFootprints( const wxString& aMessage, const std::vector<RefDesInfo>& aFootprints );
151 
152     /// Create an audit trail of the changes.
153     void LogChangePlan( void );
154 
155     /// Actually reannotate the board.
156     /// @return false if fail, true if success.
157     bool ReannotateBoard( void );
158 
159     /// Build the footprint lists, sort it, filter for excludes, then build the change list.
160     /// @return true if success, false if errors
161     bool BuildFootprintList( std::vector<RefDesInfo>& aBadRefDes );
162 
163     /// Build list of unavailable references. E.g. unselected footprints or locked footprints.
164     void BuildUnavailableRefsList();
165 
166     /// Scan through the footprint arrays and create the from -> to array.
167     void BuildChangeArray( std::vector<RefDesInfo>& aFootprints, unsigned int aStartRefDes,
168                            const wxString& aPrefix, bool aRemovePrefix,
169                            std::vector<RefDesInfo>& aBadRefDes );
170 
171     /// @return the new reference for this footprint.
172     RefDesChange* GetNewRefDes( FOOTPRINT* aFootprint );
173 
174     /// Round an int coordinate to a suitable grid
175     int RoundToGrid( int aCoord, int aGrid );
176 
177     /// Convert coordinates to wxString.
178     /// @return the string
179     wxString CoordTowxString( int aX, int aY );
180 
181     /// Make the text to summarize what is about to happen.
182     void MakeSampleText( wxString& aMessage );
183 
184     /// Check to make sure the prefix (if there is one) is properly constructed.
185     void FilterPrefix( wxTextCtrl* aPrefix );
186 
187     /// Get the structure representing the information currently held for aRefDesPrefix or create one
188     /// if it doesn't exist
189     RefDesTypeStr* GetOrBuildRefDesInfo( const wxString& aRefDesPrefix, unsigned int aStartRefDes = 0 );
190 
191     PCB_EDIT_FRAME*  m_frame;
192     FOOTPRINTS       m_footprints;
193     PCB_SELECTION    m_selection;
194 
195     std::vector<RefDesChange>  m_changeArray;
196     std::vector<RefDesInfo>    m_frontFootprints;
197     std::vector<RefDesInfo>    m_backFootprints;
198     std::vector<RefDesTypeStr> m_refDesTypes;
199     std::vector<wxString>      m_excludeArray;
200 
201     int m_sortCode;
202     int m_gridIndex;
203     int m_annotationChoice;
204     int m_severity;
205 
206     double m_sortGridx;
207     double m_sortGridy;
208 
209     wxString m_frontPrefixString;
210     wxString m_backPrefixString;
211     wxString m_validPrefixes;
212 
213     APP_SETTINGS_BASE* m_settings;
214 
215     APP_SETTINGS_BASE* m_Config;
216 };
217 
218 #endif /* DIALOG_BOARD_REANNOTATECLASSES_H_ */
219