KiCad PCB EDA Suite
Loading...
Searching...
No Matches
kicad_diff_types.h
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 3
9 * of the License, or (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, you may find one here:
18 * http://www.gnu.org/licenses/gpl-3.0.html
19 */
20
21#ifndef KICAD_DIFF_TYPES_H
22#define KICAD_DIFF_TYPES_H
23
24#include <kicommon.h>
25#include <kiid.h>
26#include <math/box2.h>
27#include <math/vector2d.h>
28#include <gal/color4d.h>
29#include <layer_ids.h>
30
31#include <json_common.h>
32#include <wx/string.h>
33
34#include <cstdint>
35#include <functional>
36#include <map>
37#include <optional>
38#include <string>
39#include <variant>
40#include <vector>
41
42
43enum class EDA_UNITS;
44struct EDA_IU_SCALE;
45
46
47namespace KICAD_DIFF
48{
49
67
74enum class CHANGE_KIND
75{
79 COLLISION, // independent add of same KIID on both sides
80 DUPLICATE_UUID // same KIID appears twice in one document
81};
82
83
87inline const wxString DOC_PROP_PAGE_FORMAT = wxS( "Page Format" );
88inline const wxString DOC_PROP_PAGE_ORIENTATION = wxS( "Page Orientation" );
89inline const wxString DOC_PROP_BOARD_THICKNESS = wxS( "Board Thickness" );
90inline const wxString DOC_PROP_LAYER_STACKUP = wxS( "Layer Stackup" );
91inline const wxString DOC_PROP_DRC_SEVERITIES = wxS( "DRC Severity Overrides" );
92inline const wxString DOC_PROP_ERC_SEVERITIES = wxS( "ERC Severity Overrides" );
93inline const wxString DOC_PROP_DRAWING_SHEET = wxS( "Drawing Sheet File" );
94inline const wxString DOC_PROP_NET_CLASSES = wxS( "Net Classes" );
95inline const wxString DOC_PROP_CUSTOM_RULES = wxS( "Custom DRC Rules" );
96inline const wxString DOC_PROP_FP_LIB_TABLE = wxS( "Footprint Library Table" );
97inline const wxString DOC_PROP_SYM_LIB_TABLE = wxS( "Symbol Library Table" );
98inline const wxString DOC_PROP_EMBED_FONTS = wxS( "Embed Fonts" );
99
101inline const wxString DOC_PROP_EMBEDDED_FILE = wxS( "Embedded File: " );
102
104inline const wxString DOC_PROP_TITLE = wxS( "Title" );
105inline const wxString DOC_PROP_DATE = wxS( "Date" );
106inline const wxString DOC_PROP_REVISION = wxS( "Revision" );
107inline const wxString DOC_PROP_COMPANY = wxS( "Company" );
108
110inline const wxString DOC_PROP_PLOT_OPTIONS = wxS( "Plot Options" );
111inline const wxString DOC_PROP_LEGACY_TEARDROPS = wxS( "Legacy Teardrops" );
112
114inline const wxString DOC_PROP_BOARD_PROPERTY = wxS( "Board Property: " );
115inline const wxString DOC_PROP_VARIANT = wxS( "Variant: " );
116
118inline constexpr int DOC_TITLE_BLOCK_COMMENTS = 9;
119
120inline wxString DocPropComment( int aIndex )
121{
122 return wxString::Format( wxS( "Comment %d" ), aIndex + 1 );
123}
124
125
136{
137 static const KIID sentinel{ std::string( "5c50ee00-0000-4000-8000-000000000000" ) };
138 return sentinel;
139}
140
141
152inline KIID_PATH LibraryItemKiidPath( const wxString& aName )
153{
155 path.emplace_back( KIID::FromDeterministicString( aName ) );
156
157 return path;
158}
159
160
164template<typename SeverityMap>
165inline std::string SummarizeSeverities( const SeverityMap& aMap )
166{
167 std::size_t h = 0;
168
169 for( const auto& [code, sev] : aMap )
170 h ^= std::hash<int>{}( code ) + std::hash<int>{}( static_cast<int>( sev ) );
171
172 return wxString::Format( wxS( "%zu override(s) (hash %zx)" ),
173 aMap.size(), h ).ToStdString();
174}
175
176
185{
186public:
203
206 using EnumValue = std::pair<int, std::string>;
207
208 using PolygonSet = std::vector<std::vector<std::vector<VECTOR2I>>>;
209
210 using Storage = std::variant<std::monostate, bool, int, int64_t, double, std::string, KIID, VECTOR2I, BOX2I,
212
213 DIFF_VALUE() : m_type( T::NONE ), m_value( std::monostate{} ) {}
214
215 static DIFF_VALUE FromBool( bool aValue );
216 static DIFF_VALUE FromInt( int aValue );
217 static DIFF_VALUE FromInt64( int64_t aValue );
218 static DIFF_VALUE FromDouble( double aValue );
219 static DIFF_VALUE FromString( const wxString& aValue );
220 static DIFF_VALUE FromString( const std::string& aValue );
221 static DIFF_VALUE FromKiid( const KIID& aValue );
222 static DIFF_VALUE FromVector2I( const VECTOR2I& aValue );
223 static DIFF_VALUE FromBox2I( const BOX2I& aValue );
224 static DIFF_VALUE FromColor( const KIGFX::COLOR4D& aValue );
225 static DIFF_VALUE FromLayer( PCB_LAYER_ID aLayer );
226 static DIFF_VALUE FromEnum( int aValue, const std::string& aLabel );
227 static DIFF_VALUE FromPolygonSet( PolygonSet aValue );
228
229 T GetType() const { return m_type; }
230 const Storage& GetStorage() const { return m_value; }
231
232 bool AsBool() const;
233 int AsInt() const;
234 int64_t AsInt64() const;
235 double AsDouble() const;
236 wxString AsString() const;
237 KIID AsKiid() const;
238 VECTOR2I AsVector2I() const;
239 BOX2I AsBox2I() const;
240 KIGFX::COLOR4D AsColor() const;
241 PCB_LAYER_ID AsLayer() const;
242 EnumValue AsEnum() const;
243 const PolygonSet& AsPolygonSet() const;
244
248 {
249 DIFF_VALUE v = *this;
250 v.m_displayHint = aHint;
251 return v;
252 }
253
255
259 wxString ToDisplayString() const;
260
265 wxString ToDisplayString( EDA_UNITS aUnits, const EDA_IU_SCALE& aScale ) const;
266
267 bool operator==( const DIFF_VALUE& aOther ) const;
268 bool operator!=( const DIFF_VALUE& aOther ) const { return !( *this == aOther ); }
269
270 nlohmann::json ToJson() const;
271 static DIFF_VALUE FromJson( const nlohmann::json& aJson );
272
273private:
276
281};
282
283
291{
292 wxString name;
295
296 bool operator==( const PROPERTY_DELTA& aOther ) const;
297 nlohmann::json ToJson() const;
298 static PROPERTY_DELTA FromJson( const nlohmann::json& aJson );
299};
300
301
313{
315 wxString typeName;
317 std::vector<PROPERTY_DELTA> properties;
319 std::optional<wxString> refdes;
320 std::vector<ITEM_CHANGE> children;
321
322 bool operator==( const ITEM_CHANGE& aOther ) const;
323 nlohmann::json ToJson() const;
324 static ITEM_CHANGE FromJson( const nlohmann::json& aJson );
325};
326
327
332{
333 wxString path; // identifier for the document being diffed
334 wxString docType; // "kicad_pcb", "kicad_sch", "kicad_sym", "pretty", ...
335 std::vector<ITEM_CHANGE> changes;
336
337 bool Empty() const { return changes.empty(); }
338 size_t Size() const { return changes.size(); }
339
340 nlohmann::json ToJson() const;
341 static DOCUMENT_DIFF FromJson( const nlohmann::json& aJson );
342};
343
344
349{
350 std::vector<DOCUMENT_DIFF> documents;
351
352 bool Empty() const;
353
354 nlohmann::json ToJson() const;
355 static PROJECT_DIFF FromJson( const nlohmann::json& aJson );
356};
357
358
359KICOMMON_API const char* ChangeKindToString( CHANGE_KIND aKind );
360KICOMMON_API CHANGE_KIND ChangeKindFromString( const std::string& aKind );
361
362
374KICOMMON_API std::string FormatDiffAsText( const DOCUMENT_DIFF& aDiff, const wxString& aLabelA,
375 const wxString& aLabelB, EDA_UNITS aUnits,
376 const EDA_IU_SCALE& aScale );
377
378
383KICOMMON_API bool WriteDiffOutput( const std::string& aContent, const wxString& aOutputPath );
384
385
400KICOMMON_API std::map<KIID_PATH, const ITEM_CHANGE*>
401IndexChangesByKiid( const DOCUMENT_DIFF& aDiff );
402
403
409KICOMMON_API std::map<wxString, const PROPERTY_DELTA*>
410IndexPropertiesByName( const ITEM_CHANGE& aChange );
411
412
427inline bool ChangeInvalidatesZone( const ITEM_CHANGE& aChange )
428{
429 return aChange.typeName == wxS( "ZONE" )
430 || aChange.typeName == wxS( "PCB_TRACK" )
431 || aChange.typeName == wxS( "PCB_ARC" )
432 || aChange.typeName == wxS( "PCB_VIA" )
433 || aChange.typeName == wxS( "FOOTPRINT" )
434 || aChange.typeName == wxS( "PAD" );
435}
436
437
453{
454 // Class names match SCH_ITEM::GetClass() / BOARD_ITEM::GetClass() exactly,
455 // because the differ stores `GetClass()` in `ITEM_CHANGE::typeName`. Net
456 // carriers (anything that can change net membership at its endpoints) and
457 // connection markers (junction, no-connect) all belong here — missing one
458 // means the merge engine skips the connectivity recompute and the saved
459 // board / schematic ships with a stale netlist.
460 return aChange.typeName == wxS( "PCB_TRACK" )
461 || aChange.typeName == wxS( "PCB_ARC" )
462 || aChange.typeName == wxS( "PCB_VIA" )
463 || aChange.typeName == wxS( "PCB_SHAPE" ) // copper-layer shapes carry nets
464 || aChange.typeName == wxS( "PAD" )
465 || aChange.typeName == wxS( "SCH_LINE" )
466 || aChange.typeName == wxS( "SCH_PIN" )
467 || aChange.typeName == wxS( "SCH_SYMBOL" ) // pin positions move with the symbol
468 || aChange.typeName == wxS( "SCH_LABEL" )
469 || aChange.typeName == wxS( "SCH_GLOBALLABEL" )
470 || aChange.typeName == wxS( "SCH_HIERLABEL" )
471 || aChange.typeName == wxS( "SCH_DIRECTIVE_LABEL" )
472 || aChange.typeName == wxS( "SCH_JUNCTION" )
473 || aChange.typeName == wxS( "SCH_NO_CONNECT" )
474 || aChange.typeName == wxS( "SCH_SHEET_PIN" )
475 || aChange.typeName == wxS( "SCH_BUS_WIRE_ENTRY" )
476 || aChange.typeName == wxS( "SCH_BUS_BUS_ENTRY" )
477 || aChange.typeName == wxS( "SCH_SHEET" ) // pin / file / pos affects nets
478 || aChange.typeName == wxS( "SCH_RULE_AREA" ); // feeds resolved netclass caches
479}
480
481} // namespace KICAD_DIFF
482
483#endif // KICAD_DIFF_TYPES_H
bool operator==(const wxAuiPaneInfo &aLhs, const wxAuiPaneInfo &aRhs)
BOX2< VECTOR2I > BOX2I
Definition box2.h:914
A typed sum value used to carry the before/after of any single property.
DISPLAY_HINT GetDisplayHint() const
std::variant< std::monostate, bool, int, int64_t, double, std::string, KIID, VECTOR2I, BOX2I, KIGFX::COLOR4D, PCB_LAYER_ID, EnumValue, PolygonSet > Storage
DIFF_VALUE WithDisplayHint(DISPLAY_HINT aHint) const
Tag this value with a display hint and return a copy, so call sites can chain DIFF_VALUE::FromInt( w ...
std::pair< int, std::string > EnumValue
Enum payload: (numeric_value, label) so JSON output is human-readable while the integer is the canoni...
bool operator!=(const DIFF_VALUE &aOther) const
const Storage & GetStorage() const
std::vector< std::vector< std::vector< VECTOR2I > > > PolygonSet
DISPLAY_HINT m_displayHint
Presentation aid only; excluded from operator== and JSON (see DISPLAY_HINT).
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:101
Definition kiid.h:46
static KIID FromDeterministicString(const wxString &aName)
Build a deterministic UUID from an arbitrary name string.
Definition kiid.cpp:325
EDA_UNITS
Definition eda_units.h:44
#define KICOMMON_API
Definition kicommon.h:27
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:56
CHANGE_KIND
Coarse classification of a single item-level change between two documents.
const wxString DOC_PROP_ERC_SEVERITIES
wxString DocPropComment(int aIndex)
const KIID & SchScreenSentinelKiid()
Sentinel KIID appended to a sheet's KIID_PATH to mark a per-sheet SCH_SCREEN resolution (page format ...
const wxString DOC_PROP_SYM_LIB_TABLE
bool ChangeInvalidatesZone(const ITEM_CHANGE &aChange)
Whether a change to an item of the given type invalidates any overlapping filled zones.
const wxString DOC_PROP_VARIANT
const wxString DOC_PROP_BOARD_THICKNESS
const wxString DOC_PROP_DATE
CHANGE_KIND ChangeKindFromString(const std::string &aKind)
const wxString DOC_PROP_PLOT_OPTIONS
Board-level settings stored in the board file.
const wxString DOC_PROP_PAGE_FORMAT
Property-name keys for the synthetic document-level ITEM_CHANGE (empty KIID_PATH).
bool WriteDiffOutput(const std::string &aContent, const wxString &aOutputPath)
Write diff/merge text output to aOutputPath, or to stdout when the path is empty.
const wxString DOC_PROP_NET_CLASSES
constexpr int DOC_TITLE_BLOCK_COMMENTS
Matches the count TITLE_BLOCK::Format writes, which is all a file can hold.
const wxString DOC_PROP_REVISION
std::string SummarizeSeverities(const SeverityMap &aMap)
Format a severity-override map (DRC or ERC, keyed by error code, value is a SEVERITY enum) as a short...
const wxString DOC_PROP_CUSTOM_RULES
const wxString DOC_PROP_PAGE_ORIENTATION
const wxString DOC_PROP_LEGACY_TEARDROPS
const wxString DOC_PROP_COMPANY
const wxString DOC_PROP_FP_LIB_TABLE
KIID_PATH LibraryItemKiidPath(const wxString &aName)
Build a deterministic synthetic KIID_PATH from a library item name (symbol name or footprint name).
const wxString DOC_PROP_EMBED_FONTS
const wxString DOC_PROP_LAYER_STACKUP
const wxString DOC_PROP_DRAWING_SHEET
DISPLAY_HINT
How a numeric DIFF_VALUE should be interpreted when rendered for humans.
@ COORD
Coordinate in internal units (PT_COORD)
@ DISTANCE
Length in internal units (PT_SIZE)
@ ANGLE
Angle in degrees (PT_DEGREE)
bool ChangeRequiresConnectivityRebuild(const ITEM_CHANGE &aChange)
Whether a change to an item of the given type requires the connectivity graph to be rebuilt.
const wxString DOC_PROP_DRC_SEVERITIES
const wxString DOC_PROP_EMBEDDED_FILE
Prefix of the property for one embedded file, followed by the file name.
const wxString DOC_PROP_BOARD_PROPERTY
Prefixes of the property for one board property or variant, followed by its name.
const char * ChangeKindToString(CHANGE_KIND aKind)
std::map< KIID_PATH, const ITEM_CHANGE * > IndexChangesByKiid(const DOCUMENT_DIFF &aDiff)
Flatten a DOCUMENT_DIFF's ITEM_CHANGE tree into a KIID_PATH -> ITEM_CHANGE* map, recursing into child...
std::string FormatDiffAsText(const DOCUMENT_DIFF &aDiff, const wxString &aLabelA, const wxString &aLabelB, EDA_UNITS aUnits, const EDA_IU_SCALE &aScale)
Render a DOCUMENT_DIFF as the human-readable text report shared by the diff jobs and CLI: a diff <lab...
std::map< wxString, const PROPERTY_DELTA * > IndexPropertiesByName(const ITEM_CHANGE &aChange)
Index property deltas inside one ITEM_CHANGE by property name.
const wxString DOC_PROP_TITLE
Title block fields. The comments are numbered from one, as the page settings dialog shows them.
STL namespace.
The full set of changes between two parsed documents of one type.
std::vector< ITEM_CHANGE > changes
One change record on a single item.
static ITEM_CHANGE FromJson(const nlohmann::json &aJson)
std::vector< PROPERTY_DELTA > properties
std::optional< wxString > refdes
std::vector< ITEM_CHANGE > children
nlohmann::json ToJson() const
Aggregated project-level diff covering many documents.
nlohmann::json ToJson() const
std::vector< DOCUMENT_DIFF > documents
static PROJECT_DIFF FromJson(const nlohmann::json &aJson)
Single (name, before, after) triple for one mutated property on an item.
static PROPERTY_DELTA FromJson(const nlohmann::json &aJson)
nlohmann::json ToJson() const
std::string path
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:708