diff --git a/common/dialogs/panel_setup_severities.cpp b/common/dialogs/panel_setup_severities.cpp index 699e982213..5d256a7c5d 100644 --- a/common/dialogs/panel_setup_severities.cpp +++ b/common/dialogs/panel_setup_severities.cpp @@ -27,14 +27,13 @@ #include "panel_setup_severities.h" -PANEL_SETUP_SEVERITIES::PANEL_SETUP_SEVERITIES( PAGED_DIALOG* aParent, RC_ITEM& aDummyItem, +PANEL_SETUP_SEVERITIES::PANEL_SETUP_SEVERITIES( PAGED_DIALOG* aParent, + std::vector> aItems, std::map& aSeverities, - int aFirstErrorCode, int aLastErrorCode, - int aPinMapSpecialCase ) : + RC_ITEM* aPinMapSpecialCase ) : wxPanel( aParent->GetTreebook() ), m_severities( aSeverities ), - m_firstErrorCode( aFirstErrorCode ), - m_lastErrorCode( aLastErrorCode ), + m_items( aItems ), m_pinMapSpecialCase( aPinMapSpecialCase ) { wxString severities[] = { _( "Error" ), _( "Warning" ), _( "Ignore" ) }; @@ -50,9 +49,10 @@ PANEL_SETUP_SEVERITIES::PANEL_SETUP_SEVERITIES( PAGED_DIALOG* aParent, RC_ITEM& wxFlexGridSizer* gridSizer = new wxFlexGridSizer( 0, 2, 0, 5 ); gridSizer->SetFlexibleDirection( wxBOTH ); - for( int errorCode = m_firstErrorCode; errorCode <= m_lastErrorCode; ++errorCode ) + for( const RC_ITEM& item : m_items ) { - wxString msg = aDummyItem.GetErrorText( errorCode ); + int errorCode = item.GetErrorCode(); + wxString msg = item.GetErrorText(); // When msg is empty, for some reason, the current errorCode is not supported // by the RC_ITEM aDummyItem. @@ -84,11 +84,11 @@ PANEL_SETUP_SEVERITIES::PANEL_SETUP_SEVERITIES( PAGED_DIALOG* aParent, RC_ITEM& } } - if( m_pinMapSpecialCase >= 0 ) + if( m_pinMapSpecialCase ) { wxString pinMapSeverities[] = { _( "From Pin Conflicts Map" ), wxT( "" ), _( "Ignore" ) }; - int errorCode = m_pinMapSpecialCase; - wxString msg = aDummyItem.GetErrorText( errorCode ); + int errorCode = m_pinMapSpecialCase->GetErrorCode(); + wxString msg = m_pinMapSpecialCase->GetErrorText(); wxStaticText* errorLabel = new wxStaticText( scrollWin, wxID_ANY, msg + wxT( ":" ) ); gridSizer->Add( errorLabel, 0, wxALIGN_CENTER_VERTICAL | wxALL | wxEXPAND, 4 ); @@ -133,8 +133,10 @@ PANEL_SETUP_SEVERITIES::PANEL_SETUP_SEVERITIES( PAGED_DIALOG* aParent, RC_ITEM& void PANEL_SETUP_SEVERITIES::ImportSettingsFrom( std::map& aSettings ) { - for( int errorCode = m_firstErrorCode; errorCode <= m_lastErrorCode; ++errorCode ) + for( const RC_ITEM& item : m_items ) { + int errorCode = item.GetErrorCode(); + if(! m_buttonMap[ errorCode ][0] ) // this entry does not actually exist continue; @@ -147,20 +149,23 @@ void PANEL_SETUP_SEVERITIES::ImportSettingsFrom( std::map& aSettings ) } } - if( m_pinMapSpecialCase >= 0 ) + if( m_pinMapSpecialCase ) { - int newSeverity = aSettings[ m_pinMapSpecialCase ]; + int pinMapCode = m_pinMapSpecialCase->GetErrorCode(); + int newSeverity = aSettings[ pinMapCode ]; - m_buttonMap[ m_pinMapSpecialCase ][0]->SetValue( newSeverity != RPT_SEVERITY_IGNORE ); - m_buttonMap[ m_pinMapSpecialCase ][1]->SetValue( newSeverity == RPT_SEVERITY_IGNORE ); + m_buttonMap[ pinMapCode ][0]->SetValue( newSeverity != RPT_SEVERITY_IGNORE ); + m_buttonMap[ pinMapCode ][1]->SetValue( newSeverity == RPT_SEVERITY_IGNORE ); } } bool PANEL_SETUP_SEVERITIES::TransferDataToWindow() { - for( int errorCode = m_firstErrorCode; errorCode <= m_lastErrorCode; ++errorCode ) + for( const RC_ITEM& item : m_items ) { + int errorCode = item.GetErrorCode(); + if( !m_buttonMap[ errorCode ][0] ) // this entry does not actually exist continue; @@ -173,12 +178,13 @@ bool PANEL_SETUP_SEVERITIES::TransferDataToWindow() } } - if( m_pinMapSpecialCase >= 0 ) + if( m_pinMapSpecialCase ) { - int severity = m_severities[ m_pinMapSpecialCase ]; + int pinMapCode = m_pinMapSpecialCase->GetErrorCode(); + int severity = m_severities[pinMapCode]; - m_buttonMap[ m_pinMapSpecialCase ][0]->SetValue( severity != RPT_SEVERITY_IGNORE ); - m_buttonMap[ m_pinMapSpecialCase ][2]->SetValue( severity == RPT_SEVERITY_IGNORE ); + m_buttonMap[ pinMapCode ][0]->SetValue( severity != RPT_SEVERITY_IGNORE ); + m_buttonMap[ pinMapCode ][2]->SetValue( severity == RPT_SEVERITY_IGNORE ); } return true; @@ -187,8 +193,10 @@ bool PANEL_SETUP_SEVERITIES::TransferDataToWindow() bool PANEL_SETUP_SEVERITIES::TransferDataFromWindow() { - for( int errorCode = m_firstErrorCode; errorCode <= m_lastErrorCode; ++errorCode ) + for( const RC_ITEM& item : m_items ) { + int errorCode = item.GetErrorCode(); + if( !m_buttonMap[ errorCode ][0] ) // this entry does not actually exist continue; @@ -204,16 +212,17 @@ bool PANEL_SETUP_SEVERITIES::TransferDataFromWindow() m_severities[ errorCode ] = severity; } - if( m_pinMapSpecialCase >= 0 ) + if( m_pinMapSpecialCase ) { - int severity = RPT_SEVERITY_UNDEFINED; + int pinMapCode = m_pinMapSpecialCase->GetErrorCode(); + int severity = RPT_SEVERITY_UNDEFINED; - if( m_buttonMap[ m_pinMapSpecialCase ][0]->GetValue() ) + if( m_buttonMap[ pinMapCode ][0]->GetValue() ) severity = RPT_SEVERITY_ERROR; - else if( m_buttonMap[ m_pinMapSpecialCase ][2]->GetValue() ) + else if( m_buttonMap[ pinMapCode ][2]->GetValue() ) severity = RPT_SEVERITY_IGNORE; - m_severities[ m_pinMapSpecialCase ] = severity; + m_severities[ pinMapCode ] = severity; } return true; diff --git a/common/dialogs/panel_setup_severities.h b/common/dialogs/panel_setup_severities.h index d448454b9f..007d811d7e 100644 --- a/common/dialogs/panel_setup_severities.h +++ b/common/dialogs/panel_setup_severities.h @@ -38,16 +38,27 @@ class PANEL_SETUP_SEVERITIES : public wxPanel { private: std::map& m_severities; - int m_firstErrorCode; - int m_lastErrorCode; - int m_pinMapSpecialCase; + + /// A list of item templates (to get descriptive text and error codes from) + std::vector> m_items; + + /// For ERC settings; a pointer to ERC_ITEM::pinTableConflict + RC_ITEM* m_pinMapSpecialCase; std::map m_buttonMap; // map from DRC error code to button group public: - PANEL_SETUP_SEVERITIES( PAGED_DIALOG* aParent, RC_ITEM& aDummyItem, - std::map& aSeverities, int aFirstError, int aLastError, - int aPinMapSpecialCase = -1 ); + /** + * Creates the severities setup panel + * @param aParent is the dialog parent + * @param aItems is a list of error types that can have a severity. Must have one or more! + * @param aSeverities is a map of error code to severity + * @param aPinMapSpecialCase is used to special-case the ERCE_PIN_TO_PIN_WARNING + */ + PANEL_SETUP_SEVERITIES( PAGED_DIALOG* aParent, + std::vector> aItems, + std::map& aSeverities, + RC_ITEM* aPinMapSpecialCase = nullptr ); void ImportSettingsFrom( std::map& aSettings ); diff --git a/common/project.cpp b/common/project.cpp index ee98406979..ca3d940a39 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -65,9 +65,9 @@ PROJECT::~PROJECT() bool PROJECT::TextVarResolver( wxString* aToken ) const { - if( m_textVars.count( *aToken ) > 0 ) + if( GetTextVars().count( *aToken ) > 0 ) { - *aToken = m_textVars.at( *aToken ); + *aToken = GetTextVars().at( *aToken ); return true; } @@ -75,6 +75,12 @@ bool PROJECT::TextVarResolver( wxString* aToken ) const } +std::map& PROJECT::GetTextVars() const +{ + return GetProjectFile().m_TextVars; +} + + void PROJECT::setProjectFullName( const wxString& aFullPathAndName ) { // Compare paths, rather than inodes, to be less surprising to the user. @@ -357,91 +363,6 @@ wxConfigBase* PROJECT::configCreate( const SEARCH_STACK& aSList, } -void PROJECT::ConfigSave( const SEARCH_STACK& aSList, const wxString& aGroupName, - const std::vector& aParams, const wxString& aFileName ) -{ - std::unique_ptr cfg( configCreate( aSList, aGroupName, aFileName ) ); - - if( !cfg.get() ) - { - // could not find template - return; - } - - cfg->SetPath( wxT( "/" ) ); - - cfg->Write( wxT( "update" ), DateAndTime() ); - - // @todo: pass in aLastClient wxString: - cfg->Write( wxT( "last_client" ), Pgm().App().GetAppName() ); - - // Save parameters - cfg->DeleteGroup( aGroupName ); // Erase all data - cfg->Flush(); - - cfg->SetPath( aGroupName ); - cfg->Write( wxT( "version" ), CONFIG_VERSION ); - - cfg->SetPath( wxT( "/" ) ); - - wxConfigSaveParams( cfg.get(), aParams, aGroupName ); - - cfg->DeleteGroup( GROUP_TEXT_VARS ); - cfg->SetPath( GROUP_TEXT_VARS ); - int index = 1; - - for( const auto& textvar : m_textVars ) - { - cfg->Write( wxString::Format( "%d", index++ ), - wxString::Format( "%s:%s", textvar.first, textvar.second ) ); - } - - cfg->SetPath( wxT( "/" ) ); - - cfg->Flush(); -} - - -bool PROJECT::ConfigLoad( const SEARCH_STACK& aSList, const wxString& aGroupName, - const std::vector& aParams, - const wxString& aForeignProjectFileName ) -{ - std::unique_ptr cfg( configCreate( aSList, aGroupName, - aForeignProjectFileName ) ); - - if( !cfg.get() ) - { - // could not find template - return false; - } - - // We do not want expansion of env var values when reading our project config file - cfg->SetExpandEnvVars( false ); - - cfg->SetPath( wxCONFIG_PATH_SEPARATOR ); - - wxString timestamp = cfg->Read( wxT( "update" ) ); - - m_pro_date_and_time = timestamp; - - wxConfigLoadParams( cfg.get(), aParams, aGroupName ); - - cfg->SetPath( GROUP_TEXT_VARS ); - - int index = 1; - wxString entry; - - while( cfg->Read( wxString::Format( "%d", index++ ), &entry ) ) - { - wxArrayString tokens = wxSplit( entry, ':' ); - - if( tokens.size() == 2 ) - m_textVars[ tokens[0] ] = tokens[1]; - } - return true; -} - - const wxString PROJECT::AbsolutePath( const wxString& aFileName ) const { wxFileName fn = aFileName; diff --git a/common/project/project_file.cpp b/common/project/project_file.cpp index ad64a3817b..09e1e5dc4f 100644 --- a/common/project/project_file.cpp +++ b/common/project/project_file.cpp @@ -36,7 +36,13 @@ const int projectFileSchemaVersion = 1; PROJECT_FILE::PROJECT_FILE( const std::string& aFullPath ) : JSON_SETTINGS( aFullPath, SETTINGS_LOC::PROJECT, projectFileSchemaVersion ), - m_sheets(), m_boards(), m_BoardSettings() + m_sheets(), + m_boards(), + m_project( nullptr ), + m_ErcSettings( nullptr ), + m_SchematicSettings( nullptr ), + m_TemplateFieldNames( nullptr ), + m_BoardSettings() { // Keep old files around m_deleteLegacyAfterMigration = false; @@ -45,6 +51,8 @@ PROJECT_FILE::PROJECT_FILE( const std::string& aFullPath ) : m_params.emplace_back( new PARAM_LIST( "boards", &m_boards, {} ) ); + m_params.emplace_back( new PARAM_WXSTRING_MAP( "text_variables", &m_TextVars, {} ) ); + m_params.emplace_back( new PARAM_LIST( "libraries.pinned_symbol_libs", &m_PinnedSymbolLibs, {} ) ); @@ -55,7 +63,7 @@ PROJECT_FILE::PROJECT_FILE( const std::string& aFullPath ) : new PARAM_PATH_LIST( "cvpcb.equivalence_files", &m_EquivalenceFiles, {} ) ); m_params.emplace_back( - new PARAM_PATH( "pcbnew.page_layout_descr_file", &m_PageLayoutDescrFile, "" ) ); + new PARAM_PATH( "pcbnew.page_layout_descr_file", &m_BoardPageLayoutDescrFile, "" ) ); m_params.emplace_back( new PARAM_PATH( "pcbnew.last_paths.netlist", &m_PcbLastPath[LAST_PATH_NETLIST], "" ) ); @@ -75,6 +83,29 @@ PROJECT_FILE::PROJECT_FILE( const std::string& aFullPath ) : m_params.emplace_back( new PARAM_PATH( "pcbnew.last_paths.gencad", &m_PcbLastPath[LAST_PATH_GENCAD], "" ) ); + m_params.emplace_back( new PARAM( "schematic.legacy_lib_dir", &m_LegacyLibDir, "" ) ); + + m_params.emplace_back( new PARAM_LAMBDA( "schematic.legacy_lib_list", + [&]() -> nlohmann::json + { + nlohmann::json ret = nlohmann::json::array(); + + for( const wxString& libName : m_LegacyLibNames ) + ret.push_back( libName ); + + return ret; + }, + [&]( const nlohmann::json& aJson ) + { + if( aJson.empty() || !aJson.is_array() ) + return; + + m_LegacyLibNames.clear(); + + for( const nlohmann::json& entry : aJson ) + m_LegacyLibNames.push_back( entry.get() ); + }, {} ) ); + m_NetSettings = std::make_shared( this, "net_settings" ); } @@ -143,6 +174,78 @@ bool PROJECT_FILE::MigrateFromLegacy( wxConfigBase* aCfg ) // All CvPcb params that we want to keep have been migrated above group_blacklist.insert( wxT( "/cvpcb" ) ); + aCfg->SetPath( wxT( "/eeschema" ) ); + fromLegacyString( aCfg, "LibDir", "schematic.legacy_lib_dir" ); + + aCfg->SetPath( wxT( "/eeschema/libraries" ) ); + + { + int libIdx = 1; + wxString libKey = wxT( "LibName" ); + libKey << libIdx; + + nlohmann::json libs = nlohmann::json::array(); + + while( aCfg->Read( libKey, &str ) ) + { + libs.push_back( str ); + + libKey = wxT( "LibName" ); + libKey << ++libIdx; + } + + ( *this )[PointerFromString( "schematic.legacy_lib_list" )] = libs; + } + + group_blacklist.insert( wxT( "/eeschema" ) ); + + aCfg->SetPath( wxT( "/text_variables" ) ); + + { + int txtIdx = 1; + wxString txtKey; + txtKey << txtIdx; + + nlohmann::json vars = nlohmann::json(); + + while( aCfg->Read( txtKey, &str ) ) + { + wxArrayString tokens = wxSplit( str, ':' ); + + if( tokens.size() == 2 ) + vars[ tokens[0].ToStdString() ] = tokens[1]; + + txtKey.clear(); + txtKey << ++txtIdx; + } + + ( *this )[PointerFromString( "text_variables" )] = vars; + } + + group_blacklist.insert( wxT( "/text_variables" ) ); + + aCfg->SetPath( wxT( "/schematic_editor" ) ); + + fromLegacyString( aCfg, "PageLayoutDescrFile", "schematic.page_layout_descr_file" ); + fromLegacyString( aCfg, "PlotDirectoryName", "schematic.plot_directory" ); + fromLegacyString( aCfg, "NetFmtName", "schematic.net_format_name" ); + fromLegacy( aCfg, "SpiceAjustPassiveValues", "schematic.spice_adjust_passive_values" ); + fromLegacy( aCfg, "SubpartIdSeparator", "schematic.subpart_id_separator" ); + fromLegacy( aCfg, "SubpartFirstId", "schematic.subpart_first_id" ); + + fromLegacy( aCfg, "LineThickness", "schematic.drawing.default_line_thickness" ); + fromLegacy( aCfg, "WireThickness", "schematic.drawing.default_wire_thickness" ); + fromLegacy( aCfg, "BusThickness", "schematic.drawing.default_bus_thickness" ); + fromLegacy( aCfg, "LabSize", "schematic.drawing.default_text_size" ); + fromLegacy( aCfg, "PinSymbolSize", "schematic.drawing.pin_symbol_size" ); + fromLegacy( aCfg, "JunctionSize", "schematic.drawing.default_junction_size" ); + + fromLegacyString( aCfg, "FieldNameTemplates", "schematic.drawing.field_names" ); + fromLegacy( aCfg, "TextOffsetRatio", "schematic.drawing.text_offset_ratio" ); + + // All schematic_editor keys we keep are migrated above + group_blacklist.insert( wxT( "/schematic_editor" ) ); + aCfg->SetPath( wxT( "/pcbnew" ) ); fromLegacyString( aCfg, "PageLayoutDescrFile", "pcbnew.page_layout_descr_file" ); @@ -252,7 +355,7 @@ bool PROJECT_FILE::MigrateFromLegacy( wxConfigBase* aCfg ) fromLegacy( aCfg, "RequireCourtyardDefinitions", sev + "legacy_no_courtyard_defined" ); - fromLegacy( aCfg, "ProhibitOverlappingCourtyards", sev + "legacy_ourtyards_overlap" ); + fromLegacy( aCfg, "ProhibitOverlappingCourtyards", sev + "legacy_courtyards_overlap" ); { int idx = 1; @@ -330,10 +433,7 @@ bool PROJECT_FILE::MigrateFromLegacy( wxConfigBase* aCfg ) ( *this )[PointerFromString( bp + "diff_pair_dimensions" )] = pairs; } - // NOTE: severities are just left alone to be migrated by BOARD_DESIGN_SETTINGS when it - // initializes, so that common doesn't need knowledge of the DRC error list (this is the - // downside of storing them as string keys... Do not blacklist the /pcbnew group so that - // this works! + group_blacklist.insert( wxT( "/pcbnew" ) ); // General group is unused these days, we can throw it away group_blacklist.insert( wxT( "/general" ) ); diff --git a/common/rc_item.cpp b/common/rc_item.cpp index 8a2abfe253..fe77bbc6ae 100644 --- a/common/rc_item.cpp +++ b/common/rc_item.cpp @@ -36,7 +36,7 @@ wxString RC_ITEM::GetErrorMessage() const { if( m_errorMessage.IsEmpty() ) - return GetErrorText( m_errorCode ); + return GetErrorText(); else return m_errorMessage; } diff --git a/common/rc_item.h b/common/rc_item.h index c7e300f312..c8eb69b395 100644 --- a/common/rc_item.h +++ b/common/rc_item.h @@ -78,7 +78,9 @@ class RC_ITEM { protected: int m_errorCode; // the error code's numeric value - wxString m_errorMessage; + wxString m_errorMessage; ///< A message describing the details of this specific error + wxString m_errorTitle; ///< The string describing the type of error + wxString m_settingsKey; ///< The key used to describe this type of error in settings MARKER_BASE* m_parent; // The marker this item belongs to, if any KIID m_mainItemUuid; KIID m_auxItemUuid; @@ -99,11 +101,13 @@ public: RC_ITEM( RC_ITEM* aItem ) { - m_errorCode = aItem->m_errorCode; + m_errorCode = aItem->m_errorCode; m_errorMessage = aItem->m_errorMessage; - m_parent = aItem->m_parent; + m_errorTitle = aItem->m_errorTitle; + m_settingsKey = aItem->m_settingsKey; + m_parent = aItem->m_parent; m_mainItemUuid = aItem->m_mainItemUuid; - m_auxItemUuid = aItem->m_auxItemUuid; + m_auxItemUuid = aItem->m_auxItemUuid; m_auxItem2Uuid = aItem->m_auxItem2Uuid; m_auxItem3Uuid = aItem->m_auxItem3Uuid; } @@ -156,18 +160,22 @@ public: int GetErrorCode() const { return m_errorCode; } void SetErrorCode( int aCode ) { m_errorCode = aCode; } - /** - * Function GetErrorText - * returns the string form of a RC error code - */ - virtual wxString GetErrorText( int aCode = -1, bool aTranslate = true ) const = 0; - /** * Function GetErrorMessage * returns the error message of a RC_ITEM */ virtual wxString GetErrorMessage() const; + wxString GetErrorText() const + { + return wxGetTranslation( m_errorTitle ); + } + + wxString GetSettingsKey() const + { + return m_settingsKey; + } + /** * Function ShowCoord * formats a coordinate or position to text. diff --git a/common/settings/nested_settings.cpp b/common/settings/nested_settings.cpp index 7ece005482..3e1b380d9a 100644 --- a/common/settings/nested_settings.cpp +++ b/common/settings/nested_settings.cpp @@ -113,8 +113,10 @@ void NESTED_SETTINGS::SetParent( JSON_SETTINGS* aParent ) m_parent = aParent; if( m_parent ) + { m_parent->AddNestedSettings( this ); - // In case we were created after the parent's ctor - LoadFromFile(); + // In case we were created after the parent's ctor + LoadFromFile(); + } } diff --git a/common/widgets/ui_common.cpp b/common/widgets/ui_common.cpp index 377dc09eed..19af95af24 100644 --- a/common/widgets/ui_common.cpp +++ b/common/widgets/ui_common.cpp @@ -105,3 +105,23 @@ wxBitmap MakeBadge( SEVERITY aStyle, int aCount, wxWindow* aWindow, int aDepth ) } +SEVERITY SeverityFromString( const wxString& aSeverity ) +{ + if( aSeverity == wxT( "warning" ) ) + return RPT_SEVERITY_WARNING; + else if( aSeverity == wxT( "ignore" ) ) + return RPT_SEVERITY_IGNORE; + else + return RPT_SEVERITY_ERROR; +} + + +wxString SeverityToString( const SEVERITY& aSeverity ) +{ + if( aSeverity == RPT_SEVERITY_IGNORE ) + return wxT( "ignore" ); + else if( aSeverity == RPT_SEVERITY_WARNING ) + return wxT( "warning" ); + else + return wxT( "error" ); +} diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt index 1393c81f53..2a6d0696e8 100644 --- a/eeschema/CMakeLists.txt +++ b/eeschema/CMakeLists.txt @@ -159,6 +159,7 @@ set( EESCHEMA_SRCS eeschema_settings.cpp erc.cpp erc_item.cpp + erc_settings.cpp fields_grid_table.cpp files-io.cpp generate_alias_info.cpp @@ -216,6 +217,7 @@ set( EESCHEMA_SRCS sch_text.cpp sch_validators.cpp schematic.cpp + schematic_settings.cpp schematic_undo_redo.cpp sch_edit_frame.cpp sheet.cpp diff --git a/eeschema/class_library.cpp b/eeschema/class_library.cpp index bd65d7f631..07a2e9e71b 100644 --- a/eeschema/class_library.cpp +++ b/eeschema/class_library.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -439,47 +440,25 @@ int PART_LIBS::GetModifyHash() void PART_LIBS::LibNamesAndPaths( PROJECT* aProject, bool doSave, wxString* aPaths, wxArrayString* aNames ) { - wxString pro = aProject->GetProjectFullName(); + wxCHECK_RET( aProject, "Null PROJECT in LibNamesAndPaths" ); - std::vector ca; - - try - { - if( aPaths ) - ca.push_back( new PARAM_CFG_FILENAME( "LibDir", aPaths ) ); - - if( aNames ) - ca.push_back( new PARAM_CFG_LIBNAME_LIST( wxT( "LibName" ), aNames, GROUP_SCH_LIBS ) ); - } - catch( boost::bad_pointer& ) - { - // Out of memory? Ship's going down anyway.... - } + PROJECT_FILE& project = aProject->GetProjectFile(); if( doSave ) { - aProject->ConfigSave( Kiface().KifaceSearch(), GROUP_SCH, ca ); + if( aPaths ) + project.m_LegacyLibDir = *aPaths; - /* - { - wxString msg = wxString::Format( _( - "Unable save project's \"%s\" file" ), - GetChars( pro ) - ); - THROW_IO_ERROR( msg ); - } - */ + if( aNames ) + project.m_LegacyLibNames = *aNames; } else { - if( !aProject->ConfigLoad( Kiface().KifaceSearch(), GROUP_SCH, ca ) ) - { - wxString msg = wxString::Format( _( - "Unable to load project's \"%s\" file" ), - GetChars( pro ) - ); - THROW_IO_ERROR( msg ); - } + if( aPaths ) + *aPaths = project.m_LegacyLibDir; + + if( aNames ) + *aNames = project.m_LegacyLibNames; } } diff --git a/eeschema/connection_graph.cpp b/eeschema/connection_graph.cpp index 968aa5bc38..910ee7f24b 100644 --- a/eeschema/connection_graph.cpp +++ b/eeschema/connection_graph.cpp @@ -166,7 +166,7 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCreateMarkers ) static_cast( candidates[0] )->GetTransformedPosition() : candidates[0]->GetPosition(); - ERC_ITEM* ercItem = new ERC_ITEM( ERCE_DRIVER_CONFLICT ); + ERC_ITEM* ercItem = ERC_ITEM::Create( ERCE_DRIVER_CONFLICT ); ercItem->SetItems( candidates[0], second_item ); SCH_MARKER* marker = new SCH_MARKER( ercItem, pos ); @@ -2023,7 +2023,7 @@ int CONNECTION_GRAPH::RunERC() wxCHECK_MSG( m_schematic, true, "Null m_schematic in CONNECTION_GRAPH::ercCheckLabels" ); - ERC_SETTINGS* settings = m_schematic->ErcSettings(); + ERC_SETTINGS& settings = m_schematic->ErcSettings(); for( auto&& subgraph : m_subgraphs ) { @@ -2041,18 +2041,18 @@ int CONNECTION_GRAPH::RunERC() * format due to their TestDanglingEnds() implementation. */ - if( settings->IsTestEnabled( ERCE_DRIVER_CONFLICT ) && !subgraph->ResolveDrivers() ) + if( settings.IsTestEnabled( ERCE_DRIVER_CONFLICT ) && !subgraph->ResolveDrivers() ) error_count++; - if( settings->IsTestEnabled( ERCE_BUS_TO_NET_CONFLICT ) + if( settings.IsTestEnabled( ERCE_BUS_TO_NET_CONFLICT ) && !ercCheckBusToNetConflicts( subgraph ) ) error_count++; - if( settings->IsTestEnabled( ERCE_BUS_ENTRY_CONFLICT ) + if( settings.IsTestEnabled( ERCE_BUS_ENTRY_CONFLICT ) && !ercCheckBusToBusEntryConflicts( subgraph ) ) error_count++; - if( settings->IsTestEnabled( ERCE_BUS_TO_BUS_CONFLICT ) + if( settings.IsTestEnabled( ERCE_BUS_TO_BUS_CONFLICT ) && !ercCheckBusToBusConflicts( subgraph ) ) error_count++; @@ -2062,8 +2062,8 @@ int CONNECTION_GRAPH::RunERC() if( !ercCheckNoConnects( subgraph ) ) error_count++; - if( ( settings->IsTestEnabled( ERCE_LABEL_NOT_CONNECTED ) - || settings->IsTestEnabled( ERCE_GLOBLABEL ) ) && !ercCheckLabels( subgraph ) ) + if( ( settings.IsTestEnabled( ERCE_LABEL_NOT_CONNECTED ) + || settings.IsTestEnabled( ERCE_GLOBLABEL ) ) && !ercCheckLabels( subgraph ) ) error_count++; } @@ -2114,7 +2114,7 @@ bool CONNECTION_GRAPH::ercCheckBusToNetConflicts( const CONNECTION_SUBGRAPH* aSu if( net_item && bus_item ) { - ERC_ITEM* ercItem = new ERC_ITEM( ERCE_BUS_TO_NET_CONFLICT ); + ERC_ITEM* ercItem = ERC_ITEM::Create( ERCE_BUS_TO_NET_CONFLICT ); ercItem->SetItems( net_item, bus_item ); SCH_MARKER* marker = new SCH_MARKER( ercItem, net_item->GetPosition() ); @@ -2182,7 +2182,7 @@ bool CONNECTION_GRAPH::ercCheckBusToBusConflicts( const CONNECTION_SUBGRAPH* aSu if( !match ) { - ERC_ITEM* ercItem = new ERC_ITEM( ERCE_BUS_TO_BUS_CONFLICT ); + ERC_ITEM* ercItem = ERC_ITEM::Create( ERCE_BUS_TO_BUS_CONFLICT ); ercItem->SetItems( label, port ); SCH_MARKER* marker = new SCH_MARKER( ercItem, label->GetPosition() ); @@ -2262,7 +2262,7 @@ bool CONNECTION_GRAPH::ercCheckBusToBusEntryConflicts( const CONNECTION_SUBGRAPH if( conflict ) { - ERC_ITEM* ercItem = new ERC_ITEM( ERCE_BUS_ENTRY_CONFLICT ); + ERC_ITEM* ercItem = ERC_ITEM::Create( ERCE_BUS_ENTRY_CONFLICT ); ercItem->SetItems( bus_entry, bus_wire ); SCH_MARKER* marker = new SCH_MARKER( ercItem, bus_entry->GetPosition() ); @@ -2315,7 +2315,7 @@ bool CONNECTION_GRAPH::ercCheckNoConnects( const CONNECTION_SUBGRAPH* aSubgraph if( pin && has_invalid_items ) { - ERC_ITEM* ercItem = new ERC_ITEM( ERCE_NOCONNECT_CONNECTED ); + ERC_ITEM* ercItem = ERC_ITEM::Create( ERCE_NOCONNECT_CONNECTED ); ercItem->SetItems( pin ); SCH_MARKER* marker = new SCH_MARKER( ercItem, pin->GetTransformedPosition() ); @@ -2326,7 +2326,7 @@ bool CONNECTION_GRAPH::ercCheckNoConnects( const CONNECTION_SUBGRAPH* aSubgraph if( !has_other_items ) { - ERC_ITEM* ercItem = new ERC_ITEM( ERCE_NOCONNECT_NOT_CONNECTED ); + ERC_ITEM* ercItem = ERC_ITEM::Create( ERCE_NOCONNECT_NOT_CONNECTED ); ercItem->SetItems( aSubgraph->m_no_connect ); SCH_MARKER* marker = new SCH_MARKER( ercItem, aSubgraph->m_no_connect->GetPosition() ); @@ -2381,7 +2381,7 @@ bool CONNECTION_GRAPH::ercCheckNoConnects( const CONNECTION_SUBGRAPH* aSubgraph if( pin && !has_other_connections && pin->GetType() != ELECTRICAL_PINTYPE::PT_NC ) { - ERC_ITEM* ercItem = new ERC_ITEM( ERCE_PIN_NOT_CONNECTED ); + ERC_ITEM* ercItem = ERC_ITEM::Create( ERCE_PIN_NOT_CONNECTED ); ercItem->SetItems( pin ); SCH_MARKER* marker = new SCH_MARKER( ercItem, pin->GetTransformedPosition() ); @@ -2437,7 +2437,7 @@ bool CONNECTION_GRAPH::ercCheckLabels( const CONNECTION_SUBGRAPH* aSubgraph ) wxCHECK_MSG( m_schematic, true, "Null m_schematic in CONNECTION_GRAPH::ercCheckLabels" ); // Global label check can be disabled independently - if( !m_schematic->ErcSettings()->IsTestEnabled( ERCE_GLOBLABEL ) && is_global ) + if( !m_schematic->ErcSettings().IsTestEnabled( ERCE_GLOBLABEL ) && is_global ) return true; wxString name = text->GetShownText(); @@ -2475,7 +2475,7 @@ bool CONNECTION_GRAPH::ercCheckLabels( const CONNECTION_SUBGRAPH* aSubgraph ) if( !has_other_connections ) { - ERC_ITEM* ercItem = new ERC_ITEM( is_global ? ERCE_GLOBLABEL : ERCE_LABEL_NOT_CONNECTED ); + ERC_ITEM* ercItem = ERC_ITEM::Create( is_global ? ERCE_GLOBLABEL : ERCE_LABEL_NOT_CONNECTED ); ercItem->SetItems( text ); SCH_MARKER* marker = new SCH_MARKER( ercItem, text->GetPosition() ); diff --git a/eeschema/dialogs/dialog_erc.cpp b/eeschema/dialogs/dialog_erc.cpp index af435daa75..dff0d437e2 100644 --- a/eeschema/dialogs/dialog_erc.cpp +++ b/eeschema/dialogs/dialog_erc.cpp @@ -195,17 +195,17 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter ) } SCH_SCREENS screens( sch->Root() ); - ERC_SETTINGS* settings = sch->ErcSettings(); + ERC_SETTINGS& settings = sch->ErcSettings(); // Test duplicate sheet names inside a given sheet. While one can have multiple references // to the same file, each must have a unique name. - if( settings->IsTestEnabled( ERCE_DUPLICATE_SHEET_NAME ) ) + if( settings.IsTestEnabled( ERCE_DUPLICATE_SHEET_NAME ) ) { aReporter.ReportTail( _( "Checking sheet names...\n" ), RPT_SEVERITY_INFO ); TestDuplicateSheetNames( sch, true ); } - if( settings->IsTestEnabled( ERCE_BUS_ALIAS_CONFLICT ) ) + if( settings.IsTestEnabled( ERCE_BUS_ALIAS_CONFLICT ) ) { aReporter.ReportTail( _( "Checking bus conflicts...\n" ), RPT_SEVERITY_INFO ); TestConflictingBusAliases( sch ); @@ -217,7 +217,7 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter ) sch->ConnectionGraph()->RunERC(); // Test is all units of each multiunit component have the same footprint assigned. - if( settings->IsTestEnabled( ERCE_DIFFERENT_UNIT_FP ) ) + if( settings.IsTestEnabled( ERCE_DIFFERENT_UNIT_FP ) ) { aReporter.ReportTail( _( "Checking footprints...\n" ), RPT_SEVERITY_INFO ); SCH_SHEET_LIST sheets = sch->GetSheets(); @@ -277,7 +277,7 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter ) case NETLIST_ITEM::PIN: { // Check if this pin has appeared before on a different net - if( item->m_Link && settings->IsTestEnabled( ERCE_DIFFERENT_UNIT_NET ) ) + if( item->m_Link && settings.IsTestEnabled( ERCE_DIFFERENT_UNIT_NET ) ) { wxString ref = item->GetComponentParent()->GetRef( &item->m_SheetPath ); wxString pin_name = ref + "_" + item->m_PinNum; @@ -294,7 +294,7 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter ) pin_to_net_map[pin_name], item->GetNetName() ); - ERC_ITEM* ercItem = new ERC_ITEM( ERCE_DIFFERENT_UNIT_NET ); + ERC_ITEM* ercItem = ERC_ITEM::Create( ERCE_DIFFERENT_UNIT_NET ); ercItem->SetErrorMessage( msg ); ercItem->SetItems( item->m_Comp ); @@ -316,13 +316,13 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter ) // Test similar labels (i;e. labels which are identical when // using case insensitive comparisons) - if( settings->IsTestEnabled( ERCE_SIMILAR_LABELS ) ) + if( settings.IsTestEnabled( ERCE_SIMILAR_LABELS ) ) { aReporter.ReportTail( _( "Checking labels...\n" ), RPT_SEVERITY_INFO ); objectsConnectedList->TestforSimilarLabels(); } - if( settings->IsTestEnabled( ERCE_UNRESOLVED_VARIABLE ) ) + if( settings.IsTestEnabled( ERCE_UNRESOLVED_VARIABLE ) ) TestTextVars( sch, m_parent->GetCanvas()->GetView()->GetWorksheet() ); // Display diags: @@ -393,14 +393,14 @@ void DIALOG_ERC::OnERCItemRClick( wxDataViewEvent& aEvent ) if( !node ) return; - SCHEMATIC& sch = m_parent->Schematic(); + ERC_SETTINGS& settings = m_parent->Schematic().ErcSettings(); RC_ITEM* rcItem = node->m_RcItem; wxString listName; wxMenu menu; wxString msg; - switch( sch.GetErcSeverity( rcItem->GetErrorCode() ) ) + switch( settings.GetSeverity( rcItem->GetErrorCode() ) ) { case RPT_SEVERITY_ERROR: listName = _( "errors" ); break; case RPT_SEVERITY_WARNING: listName = _( "warnings" ); break; @@ -425,21 +425,20 @@ void DIALOG_ERC::OnERCItemRClick( wxDataViewEvent& aEvent ) { // Pin to pin severities edited through pin conflict map } - else if( sch.GetErcSeverity( rcItem->GetErrorCode() ) == RPT_SEVERITY_WARNING ) + else if( settings.GetSeverity( rcItem->GetErrorCode() ) == RPT_SEVERITY_WARNING ) { menu.Append( 4, wxString::Format( _( "Change severity to Error for all '%s' violations" ), - rcItem->GetErrorText( rcItem->GetErrorCode() ) ), + rcItem->GetErrorText() ), _( "Violation severities can also be edited in the Board Setup... dialog" ) ); } else { menu.Append( 5, wxString::Format( _( "Change severity to Warning for all '%s' violations" ), - rcItem->GetErrorText( rcItem->GetErrorCode() ) ), + rcItem->GetErrorText() ), _( "Violation severities can also be edited in the Board Setup... dialog" ) ); } - menu.Append( 6, wxString::Format( _( "Ignore all '%s' violations" ), - rcItem->GetErrorText( rcItem->GetErrorCode() ) ), + menu.Append( 6, wxString::Format( _( "Ignore all '%s' violations" ), rcItem->GetErrorText() ), _( "Violations will not be checked or reported" ) ); menu.AppendSeparator(); @@ -478,7 +477,7 @@ void DIALOG_ERC::OnERCItemRClick( wxDataViewEvent& aEvent ) break; case 4: - sch.SetErcSeverity( rcItem->GetErrorCode(), RPT_SEVERITY_ERROR ); + settings.SetSeverity( rcItem->GetErrorCode(), RPT_SEVERITY_ERROR ); // Rebuild model and view static_cast( aEvent.GetModel() )->SetProvider( m_markerProvider ); @@ -486,7 +485,7 @@ void DIALOG_ERC::OnERCItemRClick( wxDataViewEvent& aEvent ) break; case 5: - sch.SetErcSeverity( rcItem->GetErrorCode(), RPT_SEVERITY_WARNING ); + settings.SetSeverity( rcItem->GetErrorCode(), RPT_SEVERITY_WARNING ); // Rebuild model and view static_cast( aEvent.GetModel() )->SetProvider( m_markerProvider ); @@ -495,12 +494,12 @@ void DIALOG_ERC::OnERCItemRClick( wxDataViewEvent& aEvent ) case 6: { - sch.SetErcSeverity( rcItem->GetErrorCode(), RPT_SEVERITY_IGNORE ); + settings.SetSeverity( rcItem->GetErrorCode(), RPT_SEVERITY_IGNORE ); if( rcItem->GetErrorCode() == ERCE_PIN_TO_PIN_ERROR ) - sch.SetErcSeverity( ERCE_PIN_TO_PIN_WARNING, RPT_SEVERITY_IGNORE ); + settings.SetSeverity( ERCE_PIN_TO_PIN_WARNING, RPT_SEVERITY_IGNORE ); - SCH_SCREENS ScreenList( sch.Root() ); + SCH_SCREENS ScreenList( m_parent->Schematic().Root() ); ScreenList.DeleteMarkers( MARKER_BASE::MARKER_ERC, rcItem->GetErrorCode() ); // Rebuild model and view @@ -615,6 +614,8 @@ bool DIALOG_ERC::writeReport( const wxString& aFullFileName ) sheetList.FillItemMap( itemMap ); + ERC_SETTINGS& settings = m_parent->Schematic().ErcSettings(); + for( unsigned i = 0; i < sheetList.size(); i++ ) { msg << wxString::Format( _( "\n***** Sheet %s\n" ), sheetList[i].PathHumanReadable() ); @@ -628,7 +629,7 @@ bool DIALOG_ERC::writeReport( const wxString& aFullFileName ) total_count++; - switch( m_parent->Schematic().GetErcSeverity( marker->GetRCItem()->GetErrorCode() ) ) + switch( settings.GetSeverity( marker->GetRCItem()->GetErrorCode() ) ) { case RPT_SEVERITY_ERROR: err_count++; break; case RPT_SEVERITY_WARNING: warn_count++; break; diff --git a/eeschema/dialogs/dialog_sch_import_settings.cpp b/eeschema/dialogs/dialog_sch_import_settings.cpp index 9b2bd28463..0cf5b11129 100644 --- a/eeschema/dialogs/dialog_sch_import_settings.cpp +++ b/eeschema/dialogs/dialog_sch_import_settings.cpp @@ -56,7 +56,7 @@ bool DIALOG_SCH_IMPORT_SETTINGS::TransferDataToWindow() void DIALOG_SCH_IMPORT_SETTINGS::OnBrowseClicked( wxCommandEvent& event ) { wxFileName fn = m_frame->Schematic().Root().GetFileName(); - fn.SetExt( LegacyProjectFileExtension ); + fn.SetExt( ProjectFileExtension ); wxFileDialog dlg( this, _( "Import Settings From" ), fn.GetPath(), fn.GetFullName(), ProjectFileWildcard(), wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_CHANGE_DIR ); diff --git a/eeschema/dialogs/dialog_schematic_setup.cpp b/eeschema/dialogs/dialog_schematic_setup.cpp index afe386f773..d3b3ab63e0 100644 --- a/eeschema/dialogs/dialog_schematic_setup.cpp +++ b/eeschema/dialogs/dialog_schematic_setup.cpp @@ -17,6 +17,7 @@ * with this program. If not, see . */ +#include #include #include #include @@ -27,6 +28,8 @@ #include #include #include +#include +#include #include "dialog_schematic_setup.h" #include "panel_eeschema_template_fieldnames.h" @@ -41,10 +44,9 @@ DIALOG_SCHEMATIC_SETUP::DIALOG_SCHEMATIC_SETUP( SCH_EDIT_FRAME* aFrame ) : m_fieldNameTemplates = new PANEL_EESCHEMA_TEMPLATE_FIELDNAMES( aFrame, m_treebook, false ); m_pinMap = new PANEL_SETUP_PINMAP( m_treebook, aFrame ); - ERC_ITEM dummyItem( 0 ); - m_severities = new PANEL_SETUP_SEVERITIES( this, dummyItem, - m_frame->Schematic().ErcSettings()->m_Severities, ERCE_FIRST, ERCE_LAST, - ERCE_PIN_TO_PIN_WARNING ); + m_pinToPinError = ERC_ITEM::Create( ERCE_PIN_TO_PIN_WARNING ); + m_severities = new PANEL_SETUP_SEVERITIES( this, ERC_ITEM::GetItemsWithSeverities(), + m_frame->Schematic().ErcSettings().m_Severities, m_pinToPinError ); m_textVars = new PANEL_TEXT_VARIABLES( m_treebook, &Prj() ); @@ -76,6 +78,8 @@ DIALOG_SCHEMATIC_SETUP::DIALOG_SCHEMATIC_SETUP( SCH_EDIT_FRAME* aFrame ) : DIALOG_SCHEMATIC_SETUP::~DIALOG_SCHEMATIC_SETUP() { + delete m_pinToPinError; + m_treebook->Disconnect( wxEVT_TREEBOOK_PAGE_CHANGED, wxBookCtrlEventHandler( DIALOG_SCHEMATIC_SETUP::OnPageChange ), NULL, this ); } @@ -108,29 +112,35 @@ void DIALOG_SCHEMATIC_SETUP::OnAuxiliaryAction( wxCommandEvent& event ) if( importDlg.ShowModal() == wxID_CANCEL ) return; - wxConfigBase* cfg = new wxFileConfig( wxEmptyString, wxEmptyString, importDlg.GetFilePath() ); + wxFileName projectFn( importDlg.GetFilePath() ); - // We do not want expansion of env var values when reading our project config file - cfg->SetExpandEnvVars( false ); - cfg->SetPath( wxCONFIG_PATH_SEPARATOR ); + if( !m_frame->GetSettingsManager()->LoadProject( projectFn.GetFullPath(), false ) ) + { + wxString msg = wxString::Format( _( "Error importing settings from project:\n" + "Project file %s could not be loaded" ), + projectFn.GetFullPath() ); + DisplayErrorMessage( this, msg ); + + return; + } + + PROJECT* otherPrj = m_frame->GetSettingsManager()->GetProject( projectFn.GetFullPath() ); + + SCHEMATIC otherSch( otherPrj ); + + TEMPLATES templateMgr; + PROJECT_FILE& file = otherPrj->GetProjectFile(); + + wxASSERT( file.m_SchematicSettings ); + + file.m_SchematicSettings->m_TemplateFieldNames = &templateMgr; + file.m_SchematicSettings->LoadFromFile(); if( importDlg.m_formattingOpt->GetValue() ) - { - std::vector params; - m_frame->AddFormattingParameters( params ); - - wxConfigLoadParams( cfg, params, GROUP_SCH_EDIT ); - m_formatting->TransferDataToWindow(); - } + m_formatting->ImportSettingsFrom( *file.m_SchematicSettings ); if( importDlg.m_fieldNameTemplatesOpt->GetValue() ) - { - TEMPLATES templateMgr; - PARAM_CFG_FIELDNAMES param( &templateMgr ); - param.ReadParam( cfg ); - - m_fieldNameTemplates->ImportSettingsFrom( &templateMgr ); - } + m_fieldNameTemplates->ImportSettingsFrom( file.m_SchematicSettings->m_TemplateFieldNames ); if( importDlg.m_pinMapOpt->GetValue() ) { @@ -138,13 +148,7 @@ void DIALOG_SCHEMATIC_SETUP::OnAuxiliaryAction( wxCommandEvent& event ) } if( importDlg.m_SeveritiesOpt->GetValue() ) - { - ERC_SETTINGS settings; - settings.LoadDefaults(); - wxConfigLoadParams( cfg, settings.GetProjectFileParameters(), GROUP_SCH_EDIT ); + m_severities->ImportSettingsFrom( file.m_ErcSettings->m_Severities ); - m_severities->ImportSettingsFrom( settings.m_Severities ); - } - - delete cfg; + m_frame->GetSettingsManager()->UnloadProject( otherPrj, false ); } diff --git a/eeschema/dialogs/dialog_schematic_setup.h b/eeschema/dialogs/dialog_schematic_setup.h index f8a962fa1c..f60d2fda39 100644 --- a/eeschema/dialogs/dialog_schematic_setup.h +++ b/eeschema/dialogs/dialog_schematic_setup.h @@ -47,6 +47,7 @@ protected: PANEL_SETUP_PINMAP* m_pinMap; PANEL_SETUP_SEVERITIES* m_severities; PANEL_TEXT_VARIABLES* m_textVars; + ERC_ITEM* m_pinToPinError; std::vector m_macHack; diff --git a/eeschema/dialogs/dialog_symbol_remap.cpp b/eeschema/dialogs/dialog_symbol_remap.cpp index b786a2f427..6d647501dd 100644 --- a/eeschema/dialogs/dialog_symbol_remap.cpp +++ b/eeschema/dialogs/dialog_symbol_remap.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include diff --git a/eeschema/dialogs/panel_setup_formatting.cpp b/eeschema/dialogs/panel_setup_formatting.cpp index 322c334d3e..e48391de9c 100644 --- a/eeschema/dialogs/panel_setup_formatting.cpp +++ b/eeschema/dialogs/panel_setup_formatting.cpp @@ -138,3 +138,17 @@ bool PANEL_SETUP_FORMATTING::TransferDataFromWindow() } +void PANEL_SETUP_FORMATTING::ImportSettingsFrom( SCHEMATIC_SETTINGS& aSettings ) +{ + m_textSize.SetValue( aSettings.m_DefaultTextSize ); + m_lineWidth.SetValue( aSettings.m_DefaultLineWidth ); + m_busWidth.SetValue( aSettings.m_DefaultBusThickness ); + m_wireWidth.SetValue( aSettings.m_DefaultWireThickness ); + m_pinSymbolSize.SetValue( aSettings.m_PinSymbolSize ); + m_junctionSize.SetValue( aSettings.m_JunctionSize ); + + wxString offsetRatio = wxString::Format( "%f", aSettings.m_TextOffsetRatio * 100.0 ); + m_textOffsetRatioCtrl->SetValue( offsetRatio ); +} + + diff --git a/eeschema/dialogs/panel_setup_formatting.h b/eeschema/dialogs/panel_setup_formatting.h index 231121b40a..351c281d89 100644 --- a/eeschema/dialogs/panel_setup_formatting.h +++ b/eeschema/dialogs/panel_setup_formatting.h @@ -24,6 +24,7 @@ #include "panel_setup_formatting_base.h" class SCH_EDIT_FRAME; +class SCHEMATIC_SETTINGS; class GAL_OPTIONS_PANEL; @@ -44,6 +45,8 @@ public: bool TransferDataToWindow() override; bool TransferDataFromWindow() override; + + void ImportSettingsFrom( SCHEMATIC_SETTINGS& aSettings ); }; diff --git a/eeschema/eeschema_config.cpp b/eeschema/eeschema_config.cpp index ca477d2b71..754a9d33c7 100644 --- a/eeschema/eeschema_config.cpp +++ b/eeschema/eeschema_config.cpp @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -39,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -238,90 +238,8 @@ void SCH_EDIT_FRAME::InstallPreferences( PAGED_DIALOG* aParent, } -void SCH_EDIT_FRAME::AddFormattingParameters( std::vector& params ) +bool SCH_EDIT_FRAME::LoadProjectSettings() { - EESCHEMA_SETTINGS* appSettings = dynamic_cast( Kiface().KifaceSettings() ); - - wxCHECK( appSettings, /*void*/ ); - - SCHEMATIC_SETTINGS& settings = Schematic().Settings(); - - params.push_back( new PARAM_CFG_INT( wxT( "SubpartIdSeparator" ), - LIB_PART::SubpartIdSeparatorPtr(), 0, 0, 126 ) ); - params.push_back( new PARAM_CFG_INT( wxT( "SubpartFirstId" ), - LIB_PART::SubpartFirstIdPtr(), 'A', '1', 'z' ) ); - - params.push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "LabSize" ), - &settings.m_DefaultTextSize, - Mils2iu( DEFAULT_SIZE_TEXT ), - Mils2iu( 5 ), Mils2iu( 1000 ), nullptr, 1 / IU_PER_MILS ) ); - params.push_back( new PARAM_CFG_DOUBLE( wxT( "TextOffsetRatio" ), - &settings.m_TextOffsetRatio, - (double) TXT_MARGIN / DEFAULT_SIZE_TEXT, - -200.0, 200.0 ) ); - params.push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "LineThickness" ), - &settings.m_DefaultLineWidth, - Mils2iu( appSettings->m_Drawing.default_line_thickness ), - Mils2iu( 5 ), Mils2iu( 1000 ), nullptr, 1 / IU_PER_MILS ) ); - - params.push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "BusThickness" ), - &settings.m_DefaultBusThickness, - Mils2iu( appSettings->m_Drawing.default_bus_thickness ), - Mils2iu( 5 ), Mils2iu( 1000 ), nullptr, 1 / IU_PER_MILS ) ); - params.push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "WireThickness" ), - &settings.m_DefaultWireThickness, - Mils2iu( appSettings->m_Drawing.default_wire_thickness ), - Mils2iu( 5 ), Mils2iu( 1000 ), nullptr, 1 / IU_PER_MILS ) ); - params.push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "PinSymbolSize" ), - &settings.m_PinSymbolSize, - Mils2iu( appSettings->m_Drawing.pin_symbol_size ), - Mils2iu( 5 ), Mils2iu( 1000 ), nullptr, 1 / IU_PER_MILS ) ); - params.push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "JunctionSize" ), - &settings.m_JunctionSize, - Mils2iu( appSettings->m_Drawing.default_junction_size ), - Mils2iu( 5 ), Mils2iu( 1000 ), nullptr, 1 / IU_PER_MILS ) ); -} - - -std::vector& SCH_EDIT_FRAME::GetProjectFileParameters() -{ - if( !m_projectFileParams.empty() ) - return m_projectFileParams; - - std::vector& params = m_projectFileParams; - - params.push_back( new PARAM_CFG_FILENAME( wxT( "PageLayoutDescrFile" ), - &BASE_SCREEN::m_PageLayoutDescrFileName ) ); - params.push_back( new PARAM_CFG_FILENAME( wxT( "PlotDirectoryName" ), &m_plotDirectoryName ) ); - params.push_back( new PARAM_CFG_WXSTRING( wxT( "NetFmtName" ), &m_netListFormat) ); - params.push_back( new PARAM_CFG_BOOL( wxT( "SpiceAjustPassiveValues" ), - &m_spiceAjustPassiveValues, false ) ); - - AddFormattingParameters( params ); - - params.push_back( new PARAM_CFG_FIELDNAMES( &m_templateFieldNames ) ); - - params.push_back( new PARAM_CFG_SEVERITIES( Schematic().ErcSettings() ) ); - - return params; -} - - -std::vector ERC_SETTINGS::GetProjectFileParameters() -{ - std::vector params; - - params.push_back( new PARAM_CFG_SEVERITIES( this ) ); - - return params; -} - - -bool SCH_EDIT_FRAME::LoadProjectFile() -{ - bool ret = Prj().ConfigLoad( Kiface().KifaceSearch(), GROUP_SCH_EDIT, - GetProjectFileParameters() ); - GetRenderSettings()->SetDefaultPenWidth( m_defaults->m_DefaultLineWidth ); GetRenderSettings()->m_DefaultWireThickness = m_defaults->m_DefaultWireThickness; GetRenderSettings()->m_DefaultBusThickness = m_defaults->m_DefaultBusThickness; @@ -343,7 +261,9 @@ bool SCH_EDIT_FRAME::LoadProjectFile() pglayout.SetPageLayout( filename ); - return ret; + Prj().GetProjectFile().m_TemplateFieldNames = &m_templateFieldNames; + + return true; } @@ -366,17 +286,14 @@ void SCH_EDIT_FRAME::ShowSchematicSetupDialog( const wxString& aInitialPage ) void SCH_EDIT_FRAME::SaveProjectSettings() { - PROJECT& prj = Prj(); - wxFileName fn = Schematic().RootScreen()->GetFileName(); //ConfigFileName + wxFileName fn = Schematic().RootScreen()->GetFileName(); //ConfigFileName - fn.SetExt( LegacyProjectFileExtension ); + fn.SetExt( ProjectFileExtension ); if( !fn.HasName() || !IsWritable( fn ) ) return; - wxString path = fn.GetFullPath(); - - prj.ConfigSave( Kiface().KifaceSearch(), GROUP_SCH_EDIT, GetProjectFileParameters(), path ); + GetSettingsManager()->SaveProject( fn.GetFullPath() ); } diff --git a/eeschema/erc.cpp b/eeschema/erc.cpp index c89dcb9900..6f929c8c82 100644 --- a/eeschema/erc.cpp +++ b/eeschema/erc.cpp @@ -185,7 +185,7 @@ int TestDuplicateSheetNames( SCHEMATIC* aSchematic, bool aCreateMarker ) { if( aCreateMarker ) { - ERC_ITEM* ercItem = new ERC_ITEM( ERCE_DUPLICATE_SHEET_NAME ); + ERC_ITEM* ercItem = ERC_ITEM::Create( ERCE_DUPLICATE_SHEET_NAME ); ercItem->SetItems( sheet, test_item ); SCH_MARKER* marker = new SCH_MARKER( ercItem, sheet->GetPosition() ); @@ -230,7 +230,7 @@ void TestTextVars( SCHEMATIC* aSchematic, KIGFX::WS_PROXY_VIEW_ITEM* aWorksheet pos = component->GetTransform().TransformCoordinate( pos ); pos += component->GetPosition(); - ERC_ITEM* ercItem = new ERC_ITEM( ERCE_UNRESOLVED_VARIABLE ); + ERC_ITEM* ercItem = ERC_ITEM::Create( ERCE_UNRESOLVED_VARIABLE ); ercItem->SetItems( &field ); SCH_MARKER* marker = new SCH_MARKER( ercItem, pos ); @@ -246,7 +246,7 @@ void TestTextVars( SCHEMATIC* aSchematic, KIGFX::WS_PROXY_VIEW_ITEM* aWorksheet { if( field.GetShownText().Matches( wxT( "*${*}*" ) ) ) { - ERC_ITEM* ercItem = new ERC_ITEM( ERCE_UNRESOLVED_VARIABLE ); + ERC_ITEM* ercItem = ERC_ITEM::Create( ERCE_UNRESOLVED_VARIABLE ); ercItem->SetItems( &field ); SCH_MARKER* marker = new SCH_MARKER( ercItem, field.GetPosition() ); @@ -258,7 +258,7 @@ void TestTextVars( SCHEMATIC* aSchematic, KIGFX::WS_PROXY_VIEW_ITEM* aWorksheet { if( pin->GetShownText().Matches( wxT( "*${*}*" ) ) ) { - ERC_ITEM* ercItem = new ERC_ITEM( ERCE_UNRESOLVED_VARIABLE ); + ERC_ITEM* ercItem = ERC_ITEM::Create( ERCE_UNRESOLVED_VARIABLE ); ercItem->SetItems( pin ); SCH_MARKER* marker = new SCH_MARKER( ercItem, pin->GetPosition() ); @@ -270,7 +270,7 @@ void TestTextVars( SCHEMATIC* aSchematic, KIGFX::WS_PROXY_VIEW_ITEM* aWorksheet { if( text->GetShownText().Matches( wxT( "*${*}*" ) ) ) { - ERC_ITEM* ercItem = new ERC_ITEM( ERCE_UNRESOLVED_VARIABLE ); + ERC_ITEM* ercItem = ERC_ITEM::Create( ERCE_UNRESOLVED_VARIABLE ); ercItem->SetItems( text ); SCH_MARKER* marker = new SCH_MARKER( ercItem, text->GetPosition() ); @@ -285,7 +285,7 @@ void TestTextVars( SCHEMATIC* aSchematic, KIGFX::WS_PROXY_VIEW_ITEM* aWorksheet { if( text->GetShownText().Matches( wxT( "*${*}*" ) ) ) { - ERC_ITEM* ercItem = new ERC_ITEM( ERCE_UNRESOLVED_VARIABLE ); + ERC_ITEM* ercItem = ERC_ITEM::Create( ERCE_UNRESOLVED_VARIABLE ); ercItem->SetErrorMessage( _( "Unresolved text variable in worksheet." ) ); SCH_MARKER* marker = new SCH_MARKER( ercItem, text->GetPosition() ); @@ -320,7 +320,7 @@ int TestConflictingBusAliases( SCHEMATIC* aSchematic ) alias->GetParent()->GetFileName(), test->GetParent()->GetFileName() ); - ERC_ITEM* ercItem = new ERC_ITEM( ERCE_BUS_ALIAS_CONFLICT ); + ERC_ITEM* ercItem = ERC_ITEM::Create( ERCE_BUS_ALIAS_CONFLICT ); ercItem->SetErrorMessage( msg ); SCH_MARKER* marker = new SCH_MARKER( ercItem, wxPoint() ); @@ -386,7 +386,7 @@ int TestMultiunitFootprints( const SCH_SHEET_LIST& aSheetList ) msg.Printf( _( "Different footprints assigned to %s and %s" ), unitName, secondName ); - ERC_ITEM* ercItem = new ERC_ITEM( ERCE_DIFFERENT_UNIT_FP ); + ERC_ITEM* ercItem = ERC_ITEM::Create( ERCE_DIFFERENT_UNIT_FP ); ercItem->SetErrorMessage( msg ); ercItem->SetItems( unit, secondUnit ); @@ -413,7 +413,7 @@ void Diagnose( NETLIST_OBJECT* aNetItemRef, NETLIST_OBJECT* aNetItemTst, int aMi { if( aMinConn == NOD ) /* Nothing driving the net. */ { - ERC_ITEM* ercItem = new ERC_ITEM( ERCE_PIN_NOT_DRIVEN ); + ERC_ITEM* ercItem = ERC_ITEM::Create( ERCE_PIN_NOT_DRIVEN ); ercItem->SetItems( pin ); SCH_MARKER* marker = new SCH_MARKER( ercItem, aNetItemRef->m_Start ); @@ -424,7 +424,7 @@ void Diagnose( NETLIST_OBJECT* aNetItemRef, NETLIST_OBJECT* aNetItemTst, int aMi if( aNetItemTst && aNetItemTst->m_Type == NETLIST_ITEM::PIN ) /* Error between 2 pins */ { - ERC_ITEM* ercItem = new ERC_ITEM( aDiag == ERR ? ERCE_PIN_TO_PIN_ERROR + ERC_ITEM* ercItem = ERC_ITEM::Create( aDiag == ERR ? ERCE_PIN_TO_PIN_ERROR : ERCE_PIN_TO_PIN_WARNING ); ercItem->SetItems( pin, static_cast( aNetItemTst->m_Comp ) ); @@ -764,7 +764,7 @@ static int countIndenticalLabels( std::vector& aList, NETLIST_O // Helper function: creates a marker for similar labels ERC warning static void SimilarLabelsDiagnose( NETLIST_OBJECT* aItemA, NETLIST_OBJECT* aItemB ) { - ERC_ITEM* ercItem = new ERC_ITEM( ERCE_SIMILAR_LABELS ); + ERC_ITEM* ercItem = ERC_ITEM::Create( ERCE_SIMILAR_LABELS ); ercItem->SetItems( aItemA->m_Comp, aItemB->m_Comp ); SCH_MARKER* marker = new SCH_MARKER( ercItem, aItemA->m_Start ); diff --git a/eeschema/erc_item.cpp b/eeschema/erc_item.cpp index 690e4a19f1..2b363175ca 100644 --- a/eeschema/erc_item.cpp +++ b/eeschema/erc_item.cpp @@ -29,84 +29,179 @@ #include #include -wxString ERC_ITEM::GetErrorText( int aErrorCode, bool aTranslate ) const + +// These, being statically-defined, require specialized I18N handling. We continue to +// use the _() macro so that string harvesting by the I18N framework doesn't have to be +// specialized, but we don't translate on initialization and instead do it in the getters. + +#undef _ +#define _(s) s + +ERC_ITEM ERC_ITEM::duplicateSheetName( ERCE_DUPLICATE_SHEET_NAME, + _( "Duplicate sheet names within a given sheet" ), + wxT( "duplicate_sheet_names" ) ); + +ERC_ITEM ERC_ITEM::pinNotConnected( ERCE_PIN_NOT_CONNECTED, + _( "Pin not connected" ), + wxT( "pin_not_connected" ) ); + +ERC_ITEM ERC_ITEM::pinNotDriven( ERCE_PIN_NOT_DRIVEN, + _( "Pin connected to other pins, but not driven by any pin" ), + wxT( "pin_not_driven" ) ); + +ERC_ITEM ERC_ITEM::pinTableConflict( ERCE_PIN_TO_PIN_ERROR, + _( "Conflict problem between pins" ), + wxT( "pin_to_pin" ) ); + +ERC_ITEM ERC_ITEM::hierLabelMismatch( ERCE_HIERACHICAL_LABEL, + _( "Mismatch between hierarchical labels and pins sheets" ), + wxT( "hier_label_mismatch" ) ); + +ERC_ITEM ERC_ITEM::noConnectConnected( ERCE_NOCONNECT_CONNECTED, + _( "A pin with a \"no connection\" flag is connected" ), + wxT( "no_connect_connected" ) ); + +ERC_ITEM ERC_ITEM::noConnectDangling( ERCE_NOCONNECT_NOT_CONNECTED, + _( "Unconnected \"no connection\" flag" ), + wxT( "no_connect_dangling" ) ); + +ERC_ITEM ERC_ITEM::labelDangling( ERCE_LABEL_NOT_CONNECTED, + _( "Label not connected anywhere else in the schematic" ), + wxT( "label_dangling" ) ); + +ERC_ITEM ERC_ITEM::globalLabelDangling( ERCE_GLOBLABEL, + _( "Global label not connected anywhere else in the schematic" ), + wxT( "global_label_dangling" ) ); + +ERC_ITEM ERC_ITEM::similarLabels( ERCE_SIMILAR_LABELS, + _( "Labels are similar (lower/upper case difference only) "), + wxT( "similar_labels" ) ); + +ERC_ITEM ERC_ITEM::differentUnitFootprint( ERCE_DIFFERENT_UNIT_FP, + _( "Different footprint assigned in another unit of the same component" ), + wxT( "different_unit_footprint" ) ); + +ERC_ITEM ERC_ITEM::differentUnitNet( ERCE_DIFFERENT_UNIT_NET, + _( "Different net assigned to a shared pin in another unit of the same component" ), + wxT( "different_unit_net" ) ); + +ERC_ITEM ERC_ITEM::busDefinitionConflict( ERCE_BUS_ALIAS_CONFLICT, + _( "Conflict between bus alias definitions across schematic sheets" ), + wxT( "bus_definition_conflict" ) ); + +ERC_ITEM ERC_ITEM::multipleNetNames( ERCE_DRIVER_CONFLICT, + _( "More than one name given to this bus or net" ), + wxT( "multiple_net_names" ) ); + +ERC_ITEM ERC_ITEM::netNotBusMember( ERCE_BUS_ENTRY_CONFLICT, + _( "Net is graphically connected to a bus but not a bus member" ), + wxT( "net_not_bus_member" ) ); + +ERC_ITEM ERC_ITEM::busLabelSyntax( ERCE_BUS_LABEL_ERROR, + _( "Label attached to bus item does not describe a bus" ), + wxT( "bus_label_syntax" ) ); + +ERC_ITEM ERC_ITEM::busToBusConflict( ERCE_BUS_TO_BUS_CONFLICT, + _( "Buses are graphically connected but share no bus members" ), + wxT( "bus_to_bus_conflict" ) ); + +ERC_ITEM ERC_ITEM::busToNetConflict( ERCE_BUS_TO_NET_CONFLICT, + _( "Invalid connection between bus and net items" ), + wxT( "bus_to_net_conflict" ) ); + +ERC_ITEM ERC_ITEM::unresolvedVariable( ERCE_UNRESOLVED_VARIABLE, + _( "Unresolved text variable" ), + wxT( "unresolved_variable" ) ); + +std::vector> ERC_ITEM::allItemTypes( { + ERC_ITEM::duplicateSheetName, + ERC_ITEM::pinNotConnected, + ERC_ITEM::pinNotDriven, + ERC_ITEM::pinTableConflict, + ERC_ITEM::hierLabelMismatch, + ERC_ITEM::noConnectConnected, + ERC_ITEM::noConnectDangling, + ERC_ITEM::labelDangling, + ERC_ITEM::globalLabelDangling, + ERC_ITEM::similarLabels, + ERC_ITEM::differentUnitFootprint, + ERC_ITEM::differentUnitNet, + ERC_ITEM::busDefinitionConflict, + ERC_ITEM::multipleNetNames, + ERC_ITEM::netNotBusMember, + ERC_ITEM::busLabelSyntax, + ERC_ITEM::busToBusConflict, + ERC_ITEM::busToNetConflict, + ERC_ITEM::unresolvedVariable + } ); + + + +ERC_ITEM* ERC_ITEM::Create( int aErrorCode ) { - wxString msg; - - if( aErrorCode < 0 ) - aErrorCode = m_errorCode; - switch( aErrorCode ) { - case ERCE_UNSPECIFIED: - msg = _HKI("ERC err unspecified" ); - break; case ERCE_DUPLICATE_SHEET_NAME: - msg = _HKI("Duplicate sheet names within a given sheet" ); - break; + return new ERC_ITEM( duplicateSheetName ); + case ERCE_PIN_NOT_CONNECTED: - msg = _HKI("Pin not connected" ); - break; + return new ERC_ITEM( pinNotConnected ); + case ERCE_PIN_NOT_DRIVEN: - msg = _HKI( "Pin connected to other pins, but not driven by any pin" ); - break; + return new ERC_ITEM( pinNotDriven ); + case ERCE_PIN_TO_PIN_WARNING: case ERCE_PIN_TO_PIN_ERROR: - msg = _HKI("Conflict problem between pins" ); - break; - case ERCE_HIERACHICAL_LABEL: - msg = _HKI("Mismatch between hierarchical labels and pins sheets" ); - break; - case ERCE_NOCONNECT_CONNECTED: - msg = _HKI("A pin with a \"no connection\" flag is connected" ); - break; - case ERCE_NOCONNECT_NOT_CONNECTED: - msg = _HKI("Unconnected \"no connection\" flag" ); - break; - case ERCE_LABEL_NOT_CONNECTED: - msg = _HKI("Label not connected anywhere else in the schematic" ); - break; - case ERCE_SIMILAR_LABELS: - msg = _HKI("Labels are similar (lower/upper case difference only)" ); - break; - case ERCE_DIFFERENT_UNIT_FP: - msg = _HKI("Different footprint assigned in another unit of the same component" ); - break; - case ERCE_DIFFERENT_UNIT_NET: - msg = _HKI("Different net assigned to a shared pin in another unit of the same component" ); - break; - case ERCE_BUS_ALIAS_CONFLICT: - msg = _HKI("Conflict between bus alias definitions across schematic sheets" ); - break; - case ERCE_DRIVER_CONFLICT: - msg = _HKI( "More than one name given to this bus or net" ); - break; - case ERCE_BUS_ENTRY_CONFLICT: - msg = _HKI( "Net is graphically connected to a bus but not a bus member" ); - break; - case ERCE_BUS_LABEL_ERROR: - msg = _HKI( "Label attached to bus item does not describe a bus" ); - break; - case ERCE_BUS_TO_BUS_CONFLICT: - msg = _HKI( "Buses are graphically connected but share no bus members" ); - break; - case ERCE_BUS_TO_NET_CONFLICT: - msg = _HKI( "Invalid connection between bus and net items" ); - break; - case ERCE_GLOBLABEL: - msg = _HKI( "Global label not connected anywhere else in the schematic" ); - break; - case ERCE_UNRESOLVED_VARIABLE: - msg = _HKI( "Unresolved text variable" ); - break; - default: - wxFAIL_MSG( "Missing ERC error description" ); - msg = _HKI( "Unknown ERC violation" ); - break; - } + return new ERC_ITEM( pinTableConflict ); - if( aTranslate ) - return wxGetTranslation( msg ); - else - return msg; + case ERCE_HIERACHICAL_LABEL: + return new ERC_ITEM( hierLabelMismatch ); + + case ERCE_NOCONNECT_CONNECTED: + return new ERC_ITEM( noConnectConnected ); + + case ERCE_NOCONNECT_NOT_CONNECTED: + return new ERC_ITEM( noConnectDangling ); + + case ERCE_LABEL_NOT_CONNECTED: + return new ERC_ITEM( labelDangling ); + + case ERCE_SIMILAR_LABELS: + return new ERC_ITEM( similarLabels ); + + case ERCE_DIFFERENT_UNIT_FP: + return new ERC_ITEM( differentUnitFootprint ); + + case ERCE_DIFFERENT_UNIT_NET: + return new ERC_ITEM( differentUnitNet ); + + case ERCE_BUS_ALIAS_CONFLICT: + return new ERC_ITEM( busDefinitionConflict ); + + case ERCE_DRIVER_CONFLICT: + return new ERC_ITEM( multipleNetNames ); + + case ERCE_BUS_ENTRY_CONFLICT: + return new ERC_ITEM( netNotBusMember ); + + case ERCE_BUS_LABEL_ERROR: + return new ERC_ITEM( busLabelSyntax ); + + case ERCE_BUS_TO_BUS_CONFLICT: + return new ERC_ITEM( busToBusConflict ); + + case ERCE_BUS_TO_NET_CONFLICT: + return new ERC_ITEM( busToNetConflict ); + + case ERCE_GLOBLABEL: + return new ERC_ITEM( globalLabelDangling ); + + case ERCE_UNRESOLVED_VARIABLE: + return new ERC_ITEM( unresolvedVariable ); + + case ERCE_UNSPECIFIED: + default: + wxFAIL_MSG( "Unknown ERC error code" ); + return nullptr; + } } diff --git a/eeschema/erc_item.h b/eeschema/erc_item.h index 1f875bacb2..f1c58996fe 100644 --- a/eeschema/erc_item.h +++ b/eeschema/erc_item.h @@ -30,16 +30,47 @@ class ERC_ITEM : public RC_ITEM { public: - ERC_ITEM( int aErrorCode ) + /** + * Constructs an ERC_ITEM for the given error code + * @see ERCE_T + */ + static ERC_ITEM* Create( int aErrorCode ); + + static std::vector> GetItemsWithSeverities() { - m_errorCode = aErrorCode; + return allItemTypes; } - /** - * Function GetErrorText - * returns the string form of an erc error code. - */ - wxString GetErrorText( int aErrorCode = -1, bool aTranslate = true ) const override; +private: + ERC_ITEM( int aErrorCode = 0, const wxString& aTitle = "", const wxString& aSettingsKey = "" ) + { + m_errorCode = aErrorCode; + m_errorTitle = aTitle; + m_settingsKey = aSettingsKey; + } + + /// A list of all ERC_ITEM types which are valid error codes + static std::vector> allItemTypes; + + static ERC_ITEM duplicateSheetName; + static ERC_ITEM pinNotConnected; + static ERC_ITEM pinNotDriven; + static ERC_ITEM pinTableConflict; + static ERC_ITEM hierLabelMismatch; + static ERC_ITEM noConnectConnected; + static ERC_ITEM noConnectDangling; + static ERC_ITEM labelDangling; + static ERC_ITEM globalLabelDangling; + static ERC_ITEM similarLabels; + static ERC_ITEM differentUnitFootprint; + static ERC_ITEM differentUnitNet; + static ERC_ITEM busDefinitionConflict; + static ERC_ITEM multipleNetNames; + static ERC_ITEM netNotBusMember; + static ERC_ITEM busLabelSyntax; + static ERC_ITEM busToBusConflict; + static ERC_ITEM busToNetConflict; + static ERC_ITEM unresolvedVariable; }; diff --git a/eeschema/erc_settings.cpp b/eeschema/erc_settings.cpp new file mode 100644 index 0000000000..552ca0aa2f --- /dev/null +++ b/eeschema/erc_settings.cpp @@ -0,0 +1,218 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2020 CERN + * @author Jon Evans + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include + + +const int ercSettingsSchemaVersion = 0; + + +ERC_SETTINGS::ERC_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) : + NESTED_SETTINGS( "erc", ercSettingsSchemaVersion, aParent, aPath ) +{ + for( int i = ERCE_FIRST; i <= ERCE_LAST; ++i ) + m_Severities[ i ] = RPT_SEVERITY_ERROR; + + m_Severities[ ERCE_UNSPECIFIED ] = RPT_SEVERITY_UNDEFINED; + + m_params.emplace_back( new PARAM_LAMBDA( "rule_severities", + [&]() -> nlohmann::json + { + nlohmann::json ret = {}; + + for( const RC_ITEM& item : ERC_ITEM::GetItemsWithSeverities() ) + { + int code = item.GetErrorCode(); + + if( !m_Severities.count( code ) ) + continue; + + wxString name = item.GetSettingsKey(); + + ret[std::string( name.ToUTF8() )] = + SeverityToString( static_cast( m_Severities[code] ) ); + } + + return ret; + }, + [&]( const nlohmann::json& aJson ) + { + if( !aJson.is_object() ) + return; + + for( const RC_ITEM& item : ERC_ITEM::GetItemsWithSeverities() ) + { + int code = item.GetErrorCode(); + wxString name = item.GetSettingsKey(); + + std::string key( name.ToUTF8() ); + + if( aJson.contains( key ) ) + m_Severities[code] = SeverityFromString( aJson[key] ); + } + }, + {} ) ); +} + + +ERC_SETTINGS::~ERC_SETTINGS() +{ + if( m_parent ) + { + m_parent->ReleaseNestedSettings( this ); + m_parent = nullptr; + } +} + + +int ERC_SETTINGS::GetSeverity( int aErrorCode ) const +{ + wxCHECK_MSG( m_Severities.count( aErrorCode ), RPT_SEVERITY_IGNORE, + "Missing severity from map in ERC_SETTINGS!" ); + + // Special-case pin-to-pin errors: + // Ignore-or-not is controlled by ERCE_PIN_TO_PIN_WARNING (for both) + // Warning-or-error is controlled by which errorCode it is + if( aErrorCode == ERCE_PIN_TO_PIN_ERROR ) + { + wxASSERT( m_Severities.count( ERCE_PIN_TO_PIN_WARNING ) ); + + if( m_Severities.at( ERCE_PIN_TO_PIN_WARNING ) == RPT_SEVERITY_IGNORE ) + return RPT_SEVERITY_IGNORE; + else + return RPT_SEVERITY_ERROR; + } + else if( aErrorCode == ERCE_PIN_TO_PIN_WARNING ) + { + wxASSERT( m_Severities.count( ERCE_PIN_TO_PIN_WARNING ) ); + + if( m_Severities.at( ERCE_PIN_TO_PIN_WARNING ) == RPT_SEVERITY_IGNORE ) + return RPT_SEVERITY_IGNORE; + else + return RPT_SEVERITY_WARNING; + } + + return m_Severities.at( aErrorCode ); +} + + +void ERC_SETTINGS::SetSeverity( int aErrorCode, int aSeverity ) +{ + m_Severities[ aErrorCode ] = aSeverity; +} + + +void SHEETLIST_ERC_ITEMS_PROVIDER::SetSeverities( int aSeverities ) +{ + m_severities = aSeverities; + + m_filteredMarkers.clear(); + + SCH_SHEET_LIST sheetList = m_schematic->GetSheets(); + ERC_SETTINGS& settings = m_schematic->ErcSettings(); + + for( unsigned i = 0; i < sheetList.size(); i++ ) + { + for( SCH_ITEM* aItem : sheetList[i].LastScreen()->Items().OfType( SCH_MARKER_T ) ) + { + SCH_MARKER* marker = static_cast( aItem ); + int markerSeverity; + + if( marker->GetMarkerType() != MARKER_BASE::MARKER_ERC ) + continue; + + if( marker->IsExcluded() ) + markerSeverity = RPT_SEVERITY_EXCLUSION; + else + markerSeverity = settings.GetSeverity( marker->GetRCItem()->GetErrorCode() ); + + if( markerSeverity & m_severities ) + m_filteredMarkers.push_back( marker ); + } + } +} + + +int SHEETLIST_ERC_ITEMS_PROVIDER::GetCount( int aSeverity ) +{ + if( aSeverity < 0 ) + return m_filteredMarkers.size(); + + int count = 0; + + SCH_SHEET_LIST sheetList = m_schematic->GetSheets(); + ERC_SETTINGS& settings = m_schematic->ErcSettings(); + + for( unsigned i = 0; i < sheetList.size(); i++ ) + { + for( SCH_ITEM* aItem : sheetList[i].LastScreen()->Items().OfType( SCH_MARKER_T ) ) + { + SCH_MARKER* marker = static_cast( aItem ); + int markerSeverity; + + if( marker->GetMarkerType() != MARKER_BASE::MARKER_ERC ) + continue; + + if( marker->IsExcluded() ) + markerSeverity = RPT_SEVERITY_EXCLUSION; + else + markerSeverity = settings.GetSeverity( marker->GetRCItem()->GetErrorCode() ); + + if( markerSeverity == aSeverity ) + count++; + } + } + + return count; +} + + +ERC_ITEM* SHEETLIST_ERC_ITEMS_PROVIDER::GetItem( int aIndex ) +{ + SCH_MARKER* marker = m_filteredMarkers[ aIndex ]; + + return marker ? static_cast( marker->GetRCItem() ) : nullptr; +} + + +void SHEETLIST_ERC_ITEMS_PROVIDER::DeleteItem( int aIndex, bool aDeep ) +{ + SCH_MARKER* marker = m_filteredMarkers[ aIndex ]; + m_filteredMarkers.erase( m_filteredMarkers.begin() + aIndex ); + + if( aDeep ) + { + SCH_SCREENS screens( m_schematic->Root() ); + screens.DeleteMarker( marker ); + } +} + + +void SHEETLIST_ERC_ITEMS_PROVIDER::DeleteAllItems() +{ + SCH_SCREENS screens( m_schematic->Root() ); + screens.DeleteAllMarkers( MARKER_BASE::MARKER_ERC ); + m_filteredMarkers.clear(); +} diff --git a/eeschema/erc_settings.h b/eeschema/erc_settings.h index 17356dce59..baf92e5fb5 100644 --- a/eeschema/erc_settings.h +++ b/eeschema/erc_settings.h @@ -22,11 +22,12 @@ #define _ERC_SETTINGS_H #include +#include +#include #include -class PARAM_CFG; - +class SCH_MARKER; /** * Container for ERC settings @@ -34,25 +35,21 @@ class PARAM_CFG; * Currently only stores flags about checks to run, but could later be expanded * to contain the matrix of electrical pin types. */ -class ERC_SETTINGS +class ERC_SETTINGS : public NESTED_SETTINGS { public: - ERC_SETTINGS() - { - for( int i = ERCE_FIRST; i <= ERCE_LAST; ++i ) - m_Severities[ i ] = RPT_SEVERITY_ERROR; + ERC_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ); - m_Severities[ ERCE_UNSPECIFIED ] = RPT_SEVERITY_UNDEFINED; - } + virtual ~ERC_SETTINGS(); void LoadDefaults() { - m_Severities[ ERCE_SIMILAR_LABELS ] = RPT_SEVERITY_WARNING; - m_Severities[ ERCE_GLOBLABEL ] = RPT_SEVERITY_WARNING; - m_Severities[ ERCE_DRIVER_CONFLICT ] = RPT_SEVERITY_WARNING; - m_Severities[ ERCE_BUS_ENTRY_CONFLICT ] = RPT_SEVERITY_WARNING; - m_Severities[ ERCE_BUS_TO_BUS_CONFLICT ] = RPT_SEVERITY_ERROR; - m_Severities[ ERCE_BUS_TO_NET_CONFLICT ] = RPT_SEVERITY_ERROR; + m_Severities[ERCE_SIMILAR_LABELS] = RPT_SEVERITY_WARNING; + m_Severities[ERCE_GLOBLABEL] = RPT_SEVERITY_WARNING; + m_Severities[ERCE_DRIVER_CONFLICT] = RPT_SEVERITY_WARNING; + m_Severities[ERCE_BUS_ENTRY_CONFLICT] = RPT_SEVERITY_WARNING; + m_Severities[ERCE_BUS_TO_BUS_CONFLICT] = RPT_SEVERITY_ERROR; + m_Severities[ERCE_BUS_TO_NET_CONFLICT] = RPT_SEVERITY_ERROR; } bool operator==( const ERC_SETTINGS& other ) const @@ -70,9 +67,41 @@ public: return m_Severities.at( aErrorCode ) != RPT_SEVERITY_IGNORE; } - std::vector GetProjectFileParameters(); + int GetSeverity( int aErrorCode ) const; + + void SetSeverity( int aErrorCode, int aSeverity ); std::map m_Severities; }; +/** + * SHEETLIST_ERC_ITEMS_PROVIDER + * is an implementation of the RC_ITEM_LISTinterface which uses the global SHEETLIST + * to fulfill the contract. + */ +class SHEETLIST_ERC_ITEMS_PROVIDER : public RC_ITEMS_PROVIDER +{ +private: + SCHEMATIC* m_schematic; + int m_severities; + std::vector m_filteredMarkers; + +public: + SHEETLIST_ERC_ITEMS_PROVIDER( SCHEMATIC* aSchematic ) : + m_schematic( aSchematic ), + m_severities( 0 ) + { } + + void SetSeverities( int aSeverities ) override; + + int GetCount( int aSeverity = -1 ) override; + + ERC_ITEM* GetItem( int aIndex ) override; + + void DeleteItem( int aIndex, bool aDeep ) override; + + void DeleteAllItems() override; +}; + + #endif diff --git a/eeschema/files-io.cpp b/eeschema/files-io.cpp index 55a0e1bf5b..0eed3cf0a8 100644 --- a/eeschema/files-io.cpp +++ b/eeschema/files-io.cpp @@ -283,9 +283,6 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in CreateScreens(); } - GetScreen()->SetFileName( fullFileName ); - Schematic().Root().SetFileName( fullFileName ); - SetStatusText( wxEmptyString ); ClearMsgPanel(); @@ -326,13 +323,15 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in if( pro.GetFullPath() != Prj().GetProjectFullName() ) GetSettingsManager()->LoadProject( pro.GetFullPath() ); - LoadProjectFile(); - // Load the symbol library table, this will be used forever more. Prj().SetElem( PROJECT::ELEM_SYMBOL_LIB_TABLE, NULL ); Prj().SchSymbolLibTable(); - Schematic().SetProject( Prj() ); + Schematic().SetProject( &Prj() ); + + // Load project settings after schematic has been set up with the project link, since this will + // update some of the needed schematic settings such as drawing defaults + LoadProjectSettings(); SetShutdownBlockReason( _( "Schematic file changes are unsaved" ) ); @@ -344,7 +343,6 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in else { SetScreen( nullptr ); - Schematic().Reset(); SCH_PLUGIN* plugin = SCH_IO_MGR::FindPlugin( schFileType ); SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( plugin ); diff --git a/eeschema/sch_base_frame.cpp b/eeschema/sch_base_frame.cpp index a17f632205..5924422987 100644 --- a/eeschema/sch_base_frame.cpp +++ b/eeschema/sch_base_frame.cpp @@ -84,6 +84,7 @@ SCH_BASE_FRAME::SCH_BASE_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aWindo const wxString& aTitle, const wxPoint& aPosition, const wxSize& aSize, long aStyle, const wxString& aFrameName ) : EDA_DRAW_FRAME( aKiway, aParent, aWindowType, aTitle, aPosition, aSize, aStyle, aFrameName ), + m_base_frame_defaults( nullptr, "base_Frame_defaults" ), m_defaults( &m_base_frame_defaults ) { createCanvas(); diff --git a/eeschema/sch_eagle_plugin.cpp b/eeschema/sch_eagle_plugin.cpp index 07001f6fff..ed8d35c76d 100644 --- a/eeschema/sch_eagle_plugin.cpp +++ b/eeschema/sch_eagle_plugin.cpp @@ -2049,7 +2049,7 @@ void SCH_EAGLE_PLUGIN::addBusEntries() } else { - ERC_ITEM* ercItem = new ERC_ITEM( 0 ); + ERC_ITEM* ercItem = ERC_ITEM::Create( 0 ); ercItem->SetErrorMessage( _( "Bus Entry needed" ) ); SCH_MARKER* marker = new SCH_MARKER( ercItem, linestart ); @@ -2087,7 +2087,7 @@ void SCH_EAGLE_PLUGIN::addBusEntries() } else { - ERC_ITEM* ercItem = new ERC_ITEM( 0 ); + ERC_ITEM* ercItem = ERC_ITEM::Create( 0 ); ercItem->SetErrorMessage( _( "Bus Entry needed" ) ); SCH_MARKER* marker = new SCH_MARKER( ercItem, linestart ); @@ -2129,7 +2129,7 @@ void SCH_EAGLE_PLUGIN::addBusEntries() } else { - ERC_ITEM* ercItem = new ERC_ITEM( 0 ); + ERC_ITEM* ercItem = ERC_ITEM::Create( 0 ); ercItem->SetErrorMessage( _( "Bus Entry needed" ) ); SCH_MARKER* marker = new SCH_MARKER( ercItem, lineend ); @@ -2166,7 +2166,7 @@ void SCH_EAGLE_PLUGIN::addBusEntries() } else { - ERC_ITEM* ercItem = new ERC_ITEM( 0 ); + ERC_ITEM* ercItem = ERC_ITEM::Create( 0 ); ercItem->SetErrorMessage( _( "Bus Entry needed" ) ); SCH_MARKER* marker = new SCH_MARKER( ercItem, lineend ); @@ -2208,7 +2208,7 @@ void SCH_EAGLE_PLUGIN::addBusEntries() } else { - ERC_ITEM* ercItem = new ERC_ITEM( 0 ); + ERC_ITEM* ercItem = ERC_ITEM::Create( 0 ); ercItem->SetErrorMessage( _( "Bus Entry needed" ) ); SCH_MARKER* marker = new SCH_MARKER( ercItem, linestart ); @@ -2240,7 +2240,7 @@ void SCH_EAGLE_PLUGIN::addBusEntries() } else { - ERC_ITEM* ercItem = new ERC_ITEM( 0 ); + ERC_ITEM* ercItem = ERC_ITEM::Create( 0 ); ercItem->SetErrorMessage( _( "Bus Entry needed" ) ); SCH_MARKER* marker = new SCH_MARKER( ercItem, linestart ); @@ -2279,7 +2279,7 @@ void SCH_EAGLE_PLUGIN::addBusEntries() } else { - ERC_ITEM* ercItem = new ERC_ITEM( 0 ); + ERC_ITEM* ercItem = ERC_ITEM::Create( 0 ); ercItem->SetErrorMessage( _( "Bus Entry needed" ) ); SCH_MARKER* marker = new SCH_MARKER( ercItem, lineend ); @@ -2311,7 +2311,7 @@ void SCH_EAGLE_PLUGIN::addBusEntries() } else { - ERC_ITEM* ercItem = new ERC_ITEM( 0 ); + ERC_ITEM* ercItem = ERC_ITEM::Create( 0 ); ercItem->SetErrorMessage( _( "Bus Entry needed" ) ); SCH_MARKER* marker = new SCH_MARKER( ercItem, lineend ); diff --git a/eeschema/sch_edit_frame.cpp b/eeschema/sch_edit_frame.cpp index 5abf009a01..0f6308994f 100644 --- a/eeschema/sch_edit_frame.cpp +++ b/eeschema/sch_edit_frame.cpp @@ -413,8 +413,11 @@ wxString SCH_EDIT_FRAME::GetScreenDesc() const void SCH_EDIT_FRAME::CreateScreens() { m_schematic->Reset(); + m_schematic->SetProject( &Prj() ); m_schematic->SetRoot( new SCH_SHEET( m_schematic ) ); + m_defaults = &m_schematic->Settings(); + SCH_SCREEN* rootScreen = new SCH_SCREEN( m_schematic ); rootScreen->SetMaxUndoItems( m_UndoRedoCountMax ); m_schematic->Root().SetScreen( rootScreen ); diff --git a/eeschema/sch_edit_frame.h b/eeschema/sch_edit_frame.h index 0d7f97d8e9..dd4d4f0bab 100644 --- a/eeschema/sch_edit_frame.h +++ b/eeschema/sch_edit_frame.h @@ -192,16 +192,6 @@ public: const wxString& GetPlotDirectoryName() const { return m_plotDirectoryName; } void SetPlotDirectoryName( const wxString& aDirName ) { m_plotDirectoryName = aDirName; } - void AddFormattingParameters( std::vector& params ); - - /** - * Return the project file parameter list for Eeschema. - * - * Populate the project file parameter array specific to Eeschema if it hasn't - * already been populated and return a reference to the array to the caller. - */ - std::vector& GetProjectFileParameters(); - /** * Save changes to the project settings to the project (.pro) file. */ @@ -212,7 +202,7 @@ public: * * @return True if the project file was loaded correctly. */ - bool LoadProjectFile(); + bool LoadProjectSettings(); void ShowSchematicSetupDialog( const wxString& aInitialPage = wxEmptyString ); diff --git a/eeschema/sch_marker.cpp b/eeschema/sch_marker.cpp index 24ef62a2c2..910eeca5da 100644 --- a/eeschema/sch_marker.cpp +++ b/eeschema/sch_marker.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -80,7 +81,7 @@ void SCH_MARKER::ViewGetLayers( int aLayers[], int& aCount ) const wxCHECK_RET( Schematic(), "No SCHEMATIC set for SCH_MARKER!" ); - switch( Schematic()->GetErcSeverity( m_rcItem->GetErrorCode() ) ) + switch( Schematic()->ErcSettings().GetSeverity( m_rcItem->GetErrorCode() ) ) { default: case SEVERITY::RPT_SEVERITY_ERROR: aLayers[0] = LAYER_ERC_ERR; break; @@ -98,7 +99,7 @@ SCH_LAYER_ID SCH_MARKER::GetColorLayer() const wxCHECK_MSG( Schematic(), LAYER_ERC_ERR, "No SCHEMATIC set for SCH_MARKER!" ); - switch( Schematic()->GetErcSeverity( m_rcItem->GetErrorCode() ) ) + switch( Schematic()->ErcSettings().GetSeverity( m_rcItem->GetErrorCode() ) ) { default: case SEVERITY::RPT_SEVERITY_ERROR: return LAYER_ERC_ERR; diff --git a/eeschema/schematic.cpp b/eeschema/schematic.cpp index a9e4e39fe3..cafe5ffb7a 100644 --- a/eeschema/schematic.cpp +++ b/eeschema/schematic.cpp @@ -20,19 +20,20 @@ #include #include #include +#include +#include #include #include -#include SCHEMATIC::SCHEMATIC( PROJECT* aPrj ) : EDA_ITEM( nullptr, SCHEMATIC_T ), - m_project( aPrj ), m_rootSheet( nullptr ) { m_currentSheet = new SCH_SHEET_PATH(); m_connectionGraph = new CONNECTION_GRAPH( this ); - m_ercSettings = new ERC_SETTINGS(); + + SetProject( aPrj ); } @@ -40,12 +41,23 @@ SCHEMATIC::~SCHEMATIC() { delete m_currentSheet; delete m_connectionGraph; - delete m_ercSettings; } void SCHEMATIC::Reset() { + // Assume project already saved + if( m_project ) + { + PROJECT_FILE& project = m_project->GetProjectFile(); + + delete project.m_ErcSettings; + delete project.m_SchematicSettings; + + project.m_ErcSettings = nullptr; + project.m_SchematicSettings = nullptr; + } + delete m_rootSheet; m_rootSheet = nullptr; @@ -55,6 +67,24 @@ void SCHEMATIC::Reset() } +void SCHEMATIC::SetProject( PROJECT* aPrj ) +{ + m_project = aPrj; + + if( m_project ) + { + PROJECT_FILE& project = m_project->GetProjectFile(); + project.m_ErcSettings = new ERC_SETTINGS( &project, "erc" ); + project.m_SchematicSettings = new SCHEMATIC_SETTINGS( &project, "schematic" ); + + project.m_SchematicSettings->m_TemplateFieldNames = project.m_TemplateFieldNames; + project.m_SchematicSettings->LoadFromFile(); + + project.m_ErcSettings->LoadFromFile(); + } +} + + void SCHEMATIC::SetRoot( SCH_SHEET* aRootSheet ) { wxCHECK_RET( aRootSheet, "Call to SetRoot with null SCH_SHEET!" ); @@ -77,6 +107,20 @@ wxString SCHEMATIC::GetFileName() const } +SCHEMATIC_SETTINGS& SCHEMATIC::Settings() const +{ + wxASSERT( m_project ); + return *m_project->GetProjectFile().m_SchematicSettings; +} + + +ERC_SETTINGS& SCHEMATIC::ErcSettings() const +{ + wxASSERT( m_project ); + return *m_project->GetProjectFile().m_ErcSettings; +} + + std::shared_ptr SCHEMATIC::GetBusAlias( const wxString& aLabel ) const { for( const auto& sheet : GetSheets() ) @@ -92,123 +136,4 @@ std::shared_ptr SCHEMATIC::GetBusAlias( const wxString& aLabel ) cons } -int SCHEMATIC::GetErcSeverity( int aErrorCode ) const -{ - // Special-case pin-to-pin errors: - // Ignore-or-not is controlled by ERCE_PIN_TO_PIN_WARNING (for both) - // Warning-or-error is controlled by which errorCode it is - if( aErrorCode == ERCE_PIN_TO_PIN_ERROR ) - { - if( m_ercSettings->m_Severities[ ERCE_PIN_TO_PIN_WARNING ] == RPT_SEVERITY_IGNORE ) - return RPT_SEVERITY_IGNORE; - else - return RPT_SEVERITY_ERROR; - } - else if( aErrorCode == ERCE_PIN_TO_PIN_WARNING ) - { - if( m_ercSettings->m_Severities[ ERCE_PIN_TO_PIN_WARNING ] == RPT_SEVERITY_IGNORE ) - return RPT_SEVERITY_IGNORE; - else - return RPT_SEVERITY_WARNING; - } - return m_ercSettings->m_Severities[ aErrorCode ]; -} - - -void SCHEMATIC::SetErcSeverity( int aErrorCode, int aSeverity ) -{ - m_ercSettings->m_Severities[ aErrorCode ] = aSeverity; -} - - -void SHEETLIST_ERC_ITEMS_PROVIDER::SetSeverities( int aSeverities ) -{ - m_severities = aSeverities; - - m_filteredMarkers.clear(); - - SCH_SHEET_LIST sheetList = m_schematic->GetSheets(); - - for( unsigned i = 0; i < sheetList.size(); i++ ) - { - for( SCH_ITEM* aItem : sheetList[i].LastScreen()->Items().OfType( SCH_MARKER_T ) ) - { - SCH_MARKER* marker = static_cast( aItem ); - int markerSeverity; - - if( marker->GetMarkerType() != MARKER_BASE::MARKER_ERC ) - continue; - - if( marker->IsExcluded() ) - markerSeverity = RPT_SEVERITY_EXCLUSION; - else - markerSeverity = m_schematic->GetErcSeverity( marker->GetRCItem()->GetErrorCode() ); - - if( markerSeverity & m_severities ) - m_filteredMarkers.push_back( marker ); - } - } -} - - -int SHEETLIST_ERC_ITEMS_PROVIDER::GetCount( int aSeverity ) -{ - if( aSeverity < 0 ) - return m_filteredMarkers.size(); - - int count = 0; - - SCH_SHEET_LIST sheetList = m_schematic->GetSheets(); - - for( unsigned i = 0; i < sheetList.size(); i++ ) - { - for( SCH_ITEM* aItem : sheetList[i].LastScreen()->Items().OfType( SCH_MARKER_T ) ) - { - SCH_MARKER* marker = static_cast( aItem ); - int markerSeverity; - - if( marker->GetMarkerType() != MARKER_BASE::MARKER_ERC ) - continue; - - if( marker->IsExcluded() ) - markerSeverity = RPT_SEVERITY_EXCLUSION; - else - markerSeverity = m_schematic->GetErcSeverity( marker->GetRCItem()->GetErrorCode() ); - - if( markerSeverity == aSeverity ) - count++; - } - } - - return count; -} - - -ERC_ITEM* SHEETLIST_ERC_ITEMS_PROVIDER::GetItem( int aIndex ) -{ - SCH_MARKER* marker = m_filteredMarkers[ aIndex ]; - - return marker ? static_cast( marker->GetRCItem() ) : nullptr; -} - - -void SHEETLIST_ERC_ITEMS_PROVIDER::DeleteItem( int aIndex, bool aDeep ) -{ - SCH_MARKER* marker = m_filteredMarkers[ aIndex ]; - m_filteredMarkers.erase( m_filteredMarkers.begin() + aIndex ); - - if( aDeep ) - { - SCH_SCREENS screens( m_schematic->Root() ); - screens.DeleteMarker( marker ); - } -} - - -void SHEETLIST_ERC_ITEMS_PROVIDER::DeleteAllItems() -{ - SCH_SCREENS screens( m_schematic->Root() ); - screens.DeleteAllMarkers( MARKER_BASE::MARKER_ERC ); - m_filteredMarkers.clear(); -} diff --git a/eeschema/schematic.h b/eeschema/schematic.h index 1799ce7d67..2d9baab4bd 100644 --- a/eeschema/schematic.h +++ b/eeschema/schematic.h @@ -60,13 +60,6 @@ private: /// Holds and calculates connectivity information of this schematic CONNECTION_GRAPH* m_connectionGraph; - /// Project-specific schematic settings - SCHEMATIC_SETTINGS m_settings; - - /// Holds this schematic's ERC settings - // TODO: This should be moved to project settings, not schematic - ERC_SETTINGS* m_ercSettings; - public: SCHEMATIC( PROJECT* aPrj ); @@ -86,10 +79,7 @@ public: return *const_cast( m_project ); } - void SetProject( PROJECT& aPrj ) - { - m_project = &aPrj; - } + void SetProject( PROJECT* aPrj ); /** * Builds and returns an updated schematic hierarchy @@ -141,10 +131,9 @@ public: return m_connectionGraph; } - SCHEMATIC_SETTINGS& Settings() - { - return m_settings; - } + SCHEMATIC_SETTINGS& Settings() const; + + ERC_SETTINGS& ErcSettings() const; /** * Returns a pointer to a bus alias object for the given label, @@ -152,53 +141,9 @@ public: */ std::shared_ptr GetBusAlias( const wxString& aLabel ) const; - ERC_SETTINGS* ErcSettings() const - { - return m_ercSettings; - } - - // TODO(JE) Move out of SCHEMATIC - int GetErcSeverity( int aErrorCode ) const; - - // TODO(JE) Move out of SCHEMATIC - void SetErcSeverity( int aErrorCode, int aSeverity ); - #if defined(DEBUG) void Show( int nestLevel, std::ostream& os ) const override {} #endif - }; - -/** - * SHEETLIST_ERC_ITEMS_PROVIDER - * is an implementation of the RC_ITEM_LISTinterface which uses the global SHEETLIST - * to fulfill the contract. - */ -class SHEETLIST_ERC_ITEMS_PROVIDER : public RC_ITEMS_PROVIDER -{ -private: - SCHEMATIC* m_schematic; - int m_severities; - std::vector m_filteredMarkers; - -public: - SHEETLIST_ERC_ITEMS_PROVIDER( SCHEMATIC* aSchematic ) : - m_schematic( aSchematic ), - m_severities( 0 ) - { } - - void SetSeverities( int aSeverities ) override; - - int GetCount( int aSeverity = -1 ) override; - - ERC_ITEM* GetItem( int aIndex ) override; - - void DeleteItem( int aIndex, bool aDeep ) override; - - void DeleteAllItems() override; -}; - - - #endif diff --git a/eeschema/schematic_settings.cpp b/eeschema/schematic_settings.cpp new file mode 100644 index 0000000000..979cdc4efd --- /dev/null +++ b/eeschema/schematic_settings.cpp @@ -0,0 +1,152 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2020 CERN + * @author Jon Evans + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +const int schSettingsSchemaVersion = 0; + + +SCHEMATIC_SETTINGS::SCHEMATIC_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) : + NESTED_SETTINGS( "schematic", schSettingsSchemaVersion, aParent, aPath ), + m_DefaultLineWidth( DEFAULT_LINE_THICKNESS * IU_PER_MILS ), + m_DefaultWireThickness( DEFAULT_WIRE_THICKNESS * IU_PER_MILS ), + m_DefaultBusThickness( DEFAULT_BUS_THICKNESS * IU_PER_MILS ), + m_DefaultTextSize( DEFAULT_TEXT_SIZE * IU_PER_MILS ), + m_TextOffsetRatio( 0.08 ), + m_PinSymbolSize( DEFAULT_TEXT_SIZE * IU_PER_MILS / 2 ), + m_JunctionSize( DEFAULT_JUNCTION_DIAM * IU_PER_MILS ), + m_TemplateFieldNames( nullptr ) +{ + EESCHEMA_SETTINGS* appSettings = dynamic_cast( Kiface().KifaceSettings() ); + + int defaultLineThickness = + appSettings ? appSettings->m_Drawing.default_line_thickness : DEFAULT_LINE_THICKNESS; + int defaultWireThickness = + appSettings ? appSettings->m_Drawing.default_wire_thickness : DEFAULT_WIRE_THICKNESS; + int defaultBusThickness = + appSettings ? appSettings->m_Drawing.default_bus_thickness : DEFAULT_BUS_THICKNESS; + int defaultTextSize = + appSettings ? appSettings->m_Drawing.default_text_size : DEFAULT_TEXT_SIZE; + int defaultPinSymbolSize = + appSettings ? appSettings->m_Drawing.pin_symbol_size : DEFAULT_TEXT_SIZE / 2; + + m_params.emplace_back( new PARAM_SCALED( "drawing.default_line_thickness", + &m_DefaultLineWidth, Mils2iu( defaultLineThickness ), + Mils2iu( 5 ), Mils2iu( 1000 ), 1 / IU_PER_MILS ) ); + + m_params.emplace_back( new PARAM_SCALED( "drawing.default_wire_thickness", + &m_DefaultWireThickness, Mils2iu( defaultWireThickness ), + Mils2iu( 5 ), Mils2iu( 1000 ), 1 / IU_PER_MILS ) ); + + m_params.emplace_back( new PARAM_SCALED( "drawing.default_bus_thickness", + &m_DefaultBusThickness, Mils2iu( defaultBusThickness ), + Mils2iu( 5 ), Mils2iu( 1000 ), 1 / IU_PER_MILS ) ); + + m_params.emplace_back( new PARAM_SCALED( "drawing.default_text_size", &m_DefaultTextSize, + Mils2iu( defaultTextSize ), Mils2iu( 5 ), Mils2iu( 1000 ), + 1 / IU_PER_MILS ) ); + + m_params.emplace_back( new PARAM( "drawing.text_offset_ratio", &m_TextOffsetRatio, + (double) TXT_MARGIN / DEFAULT_SIZE_TEXT, -200.0, 200.0 ) ); + + m_params.emplace_back( new PARAM_SCALED( "drawing.pin_symbol_size", &m_PinSymbolSize, + Mils2iu( defaultPinSymbolSize ), Mils2iu( 5 ), Mils2iu( 1000 ), + 1 / IU_PER_MILS ) ); + + m_params.emplace_back( new PARAM_SCALED( "drawing.default_junction_size", &m_JunctionSize, + Mils2iu( DEFAULT_BUS_THICKNESS ), Mils2iu( 5 ), Mils2iu( 1000 ), 1 / IU_PER_MILS ) ); + + m_params.emplace_back( new PARAM_LAMBDA( "drawing.field_names", + [&]() -> nlohmann::json + { + nlohmann::json ret = nlohmann::json::array(); + + if( !m_TemplateFieldNames ) + return ret; + + for( const TEMPLATE_FIELDNAME& field : + m_TemplateFieldNames->GetTemplateFieldNames( false ) ) + { + ret.push_back( nlohmann::json( { + { "name", field.m_Name }, + { "visible", field.m_Visible }, + { "url", field.m_URL } + } ) ); + } + + return ret; + }, + [&]( const nlohmann::json& aJson ) + { + if( !m_TemplateFieldNames || aJson.empty() || !aJson.is_array() ) + return; + + m_TemplateFieldNames->DeleteAllFieldNameTemplates( false ); + + for( const nlohmann::json& entry : aJson ) + { + if( !entry.contains( "name" ) || !entry.contains( "url" ) + || !entry.contains( "visible" ) ) + continue; + + TEMPLATE_FIELDNAME field( entry["name"].get() ); + field.m_URL = entry["url"].get(); + field.m_Visible = entry["visible"].get(); + m_TemplateFieldNames->AddTemplateFieldName( field, false ); + } + }, {} ) ); + + // TOOD(JE) get rid of this static + m_params.emplace_back( new PARAM( + "page_layout_descr_file", &BASE_SCREEN::m_PageLayoutDescrFileName, "" ) ); + + m_params.emplace_back( new PARAM( "plot_directory", &m_PlotDirectoryName, "" ) ); + + m_params.emplace_back( new PARAM( "net_format_name", &m_NetFormatName, "" ) ); + + m_params.emplace_back( + new PARAM( "spice_adjust_passive_values", &m_SpiceAdjustPassiveValues, false ) ); + + // TODO(JE) should we keep these LIB_PART:: things around? + m_params.emplace_back( new PARAM( + "subpart_id_separator", LIB_PART::SubpartIdSeparatorPtr(), 0, 0, 126 ) ); + + m_params.emplace_back( + new PARAM( "subpart_first_id", LIB_PART::SubpartFirstIdPtr(), 'A', '1', 'z' ) ); +} + + +SCHEMATIC_SETTINGS::~SCHEMATIC_SETTINGS() +{ + if( m_parent ) + { + m_parent->ReleaseNestedSettings( this ); + m_parent = nullptr; + } +} diff --git a/eeschema/schematic_settings.h b/eeschema/schematic_settings.h index 3055d1bf7b..d6363a84ce 100644 --- a/eeschema/schematic_settings.h +++ b/eeschema/schematic_settings.h @@ -22,6 +22,8 @@ #include #include +#include +#include /** * These settings were stored in SCH_BASE_FRAME previously. @@ -31,17 +33,13 @@ * These are loaded from eeschema settings but then overwritten by the project settings. * All of the values are stored in IU, but the backing file stores in mils. */ -struct SCHEMATIC_SETTINGS +struct SCHEMATIC_SETTINGS : public NESTED_SETTINGS { - SCHEMATIC_SETTINGS() : - m_DefaultLineWidth( DEFAULT_LINE_THICKNESS * IU_PER_MILS ), - m_DefaultWireThickness( DEFAULT_WIRE_THICKNESS * IU_PER_MILS ), - m_DefaultBusThickness( DEFAULT_BUS_THICKNESS * IU_PER_MILS ), - m_DefaultTextSize( DEFAULT_TEXT_SIZE * IU_PER_MILS ), - m_TextOffsetRatio( 0.08 ), - m_PinSymbolSize( DEFAULT_TEXT_SIZE * IU_PER_MILS / 2 ), - m_JunctionSize( DEFAULT_JUNCTION_DIAM * IU_PER_MILS ) - {} + SCHEMATIC_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ); + + virtual ~SCHEMATIC_SETTINGS(); + + // Default sizes are all stored in IU here, and im mils in the JSON file int m_DefaultLineWidth; int m_DefaultWireThickness; @@ -50,6 +48,17 @@ struct SCHEMATIC_SETTINGS double m_TextOffsetRatio; int m_PinSymbolSize; int m_JunctionSize; + + wxString m_PageLayoutDescrFile; + + wxString m_PlotDirectoryName; + + wxString m_NetFormatName; + + bool m_SpiceAdjustPassiveValues; + + /// @see PROJECT_FILE::m_TemplateFieldNames + TEMPLATES* m_TemplateFieldNames; }; #endif diff --git a/include/config_params.h b/include/config_params.h index 57a5cc95fe..2887ee5823 100644 --- a/include/config_params.h +++ b/include/config_params.h @@ -36,19 +36,6 @@ using KIGFX::COLOR4D; -/// Names of sub sections where to store project info in *.pro project config files -#define GROUP_PCB wxT( "/pcbnew" ) /// parameters for Pcbnew/Modedit -#define GROUP_SCH wxT( "/eeschema" ) /// library list and lib paths list -#define GROUP_SCH_EDIT wxT( "/schematic_editor" ) /// parameters for schematic editor - /// (and few for component editor). - /// Does not store libs list -#define GROUP_PCB_LIBS wxT( "/pcbnew/libraries" ) /// PCB library list, should be removed soon - /// (Now in fp lib tables) -#define GROUP_SCH_LIBS wxT( "/eeschema/libraries" ) /// library list section - -#define GROUP_TEXT_VARS wxT( "/text_variables" ) - -#define CONFIG_VERSION 1 /** diff --git a/include/project.h b/include/project.h index ef2e69a901..3e81735f50 100644 --- a/include/project.h +++ b/include/project.h @@ -85,9 +85,8 @@ public: //--------------------------------------------------------- VTBL_ENTRY bool TextVarResolver( wxString* aToken ) const; - VTBL_ENTRY std::map& GetTextVars() { return m_textVars; } - // VTBL_ENTRY bool MaybeLoadProjectSettings( const std::vector& aFileSet ); + VTBL_ENTRY std::map& GetTextVars() const; /** * Function GetProjectFullName @@ -139,45 +138,6 @@ public: return *m_localSettings; } - /** - * Function ConfigSave - * saves the current "project" parameters into the wxConfigBase* derivative. - * Then the wxConfigBase derivative is written to the *.pro file for the project. - * - * @param aSList a SEARCH_STACK - * @param aGroupName is the name of the group inside the config which contains parameters - * @param aParams is a ptr vector of PARAM_CFG derivatives. - * Saved parameters are the subset in this array having the .m_Setup member - * set to false. - * @param aFileName is where to save the *.pro file and if NULL means use this PROJECT's - * @a m_project_name. - */ - VTBL_ENTRY void ConfigSave( const SEARCH_STACK& aSList, const wxString& aGroupName, - const std::vector& aParams, - const wxString& aFileName = wxEmptyString ); - - /** - * Function ConfigLoad - * reads a subset of parameters from the "project" file. Parameters are the - * subset of variables given in @a aParams array which have the .m_Setup member - * set to false. The file which is read in and then extracted from is the - * '*.pro' file for the project. - *

- * set: - * m_pro_date_and_time - * - * @param aSearchS a SEARCH_STACK where a kicad.pro template file may be found. - * @param aGroupName - * @param aParams is ptr vector of PARAM_CFG derivatives. - * @param aForeignConfigFileName when NULL means load the *.pro filename given - * in this PROJECT's @a m_project_name field, otherwise load the provided filename. - * - * @return bool - true if loaded OK. - */ - VTBL_ENTRY bool ConfigLoad( const SEARCH_STACK& aSearchS, const wxString& aGroupName, - const std::vector& aParams, - const wxString& aForeignConfigFileName = wxEmptyString ); - /// Retain a number of project specific wxStrings, enumerated here: enum RSTRING_T { @@ -382,7 +342,6 @@ private: PROJECT_LOCAL_SETTINGS* m_localSettings; std::map m_sheetNames; - std::map m_textVars; /// @see this::SetRString(), GetRString(), and enum RSTRING_T. wxString m_rstrings[RSTRING_COUNT]; diff --git a/include/project/project_file.h b/include/project/project_file.h index a4127c47c0..f6a7be7236 100644 --- a/include/project/project_file.h +++ b/include/project/project_file.h @@ -25,7 +25,11 @@ #include #include +class BOARD_DESIGN_SETTINGS; +class ERC_SETTINGS; class NET_SETTINGS; +class SCHEMATIC_SETTINGS; +class TEMPLATES; /** * For files like sheets and boards, a pair of that object KIID and display name @@ -120,6 +124,34 @@ public: /// The list of pinned footprint libraries std::vector m_PinnedFootprintLibs; + std::map m_TextVars; + + /** + * Eeschema params + */ + + // Schematic ERC settings: lifecycle managed by SCHEMATIC + ERC_SETTINGS* m_ErcSettings; + + // Schematic editing and misc settings: lifecycle managed by SCHEMATIC + SCHEMATIC_SETTINGS* m_SchematicSettings; + + /** + * A pointer to the template fieldnames object owned by the parent SCH_BASE_FRAME. + * Note that this coupling is unfortunate; but the TEMPLATES object has to outlive any + * SCHEMATIC_SETTINGS object because it holds both global and project field names. + * This will be null if the project is opened outside a SCH_BASE_FRAME. It is placed here + * instead of in SCHEMATIC_SETTINGS because SCHEMATIC_SETTINGS objects are created and destroyed + * when schematics are loaded, and it's inconvenient to make sure this pointer is set early so + * that load of the SCHEMATIC_SETTINGS works. + */ + TEMPLATES* m_TemplateFieldNames; + + // Legacy parameters LibDir and LibName, for importing old projects + wxString m_LegacyLibDir; + + wxArrayString m_LegacyLibNames; + /** * CvPcb params */ @@ -132,7 +164,7 @@ public: */ /// Page layout description file - wxString m_PageLayoutDescrFile; + wxString m_BoardPageLayoutDescrFile; /// MRU path storage wxString m_PcbLastPath[LAST_PATH_SIZE]; @@ -142,7 +174,7 @@ public: * loading a board so that BOARD_DESIGN_SETTINGS doesn't need to live in common for now. * Owned by the BOARD; may be null if a board isn't loaded: be careful */ - NESTED_SETTINGS* m_BoardSettings; + BOARD_DESIGN_SETTINGS* m_BoardSettings; /** * Net settings for this project (owned here) diff --git a/include/settings/parameters.h b/include/settings/parameters.h index 424ca7e1ff..98f851951d 100644 --- a/include/settings/parameters.h +++ b/include/settings/parameters.h @@ -587,20 +587,18 @@ public: if( m_readOnly ) return; - std::map val = m_default; - if( OPT js = aSettings->GetJson( m_path ) ) { if( js->is_object() ) { - val.clear(); + m_ptr->clear(); for( const auto& el : js->items() ) - val[ el.key() ] = el.value().get(); + ( *m_ptr )[ el.key() ] = el.value().get(); } } - - *m_ptr = val; + else if( aResetIfMissing ) + *m_ptr = m_default; } void Store( JSON_SETTINGS* aSettings) const override @@ -629,6 +627,9 @@ public: { if( js->is_object() ) { + if( m_ptr->size() != js->size() ) + return false; + std::map val; for( const auto& el : js->items() ) @@ -647,4 +648,94 @@ private: std::map m_default; }; + +/** + * A helper for maps + */ +class PARAM_WXSTRING_MAP : public PARAM_BASE +{ +public: + PARAM_WXSTRING_MAP( const std::string& aJsonPath, std::map* aPtr, + std::initializer_list> aDefault, + bool aReadOnly = false ) : + PARAM_BASE( aJsonPath, aReadOnly ), + m_ptr( aPtr ), + m_default( aDefault ) + { } + + void Load( JSON_SETTINGS* aSettings, bool aResetIfMissing = true ) const override + { + if( m_readOnly ) + return; + + if( OPT js = aSettings->GetJson( m_path ) ) + { + if( js->is_object() ) + { + m_ptr->clear(); + + for( const auto& el : js->items() ) + { + ( *m_ptr )[wxString( el.key().c_str(), wxConvUTF8 )] = + el.value().get(); + } + } + } + else if( aResetIfMissing ) + *m_ptr = m_default; + } + + void Store( JSON_SETTINGS* aSettings) const override + { + nlohmann::json js( {} ); + + for( const auto& el : *m_ptr ) + { + std::string key( el.first.ToUTF8() ); + js[ key ] = el.second; + } + + aSettings->Set( m_path, js ); + } + + virtual void SetDefault() override + { + *m_ptr = m_default; + } + + bool IsDefault() const override + { + return *m_ptr == m_default; + } + + bool MatchesFile( JSON_SETTINGS* aSettings ) const override + { + if( OPT js = aSettings->GetJson( m_path ) ) + { + if( js->is_object() ) + { + if( m_ptr->size() != js->size() ) + return false; + + std::map val; + + for( const auto& el : js->items() ) + { + wxString key( el.key().c_str(), wxConvUTF8 ); + val[key] = el.value().get(); + } + + return val == *m_ptr; + } + } + + return false; + } + +private: + std::map* m_ptr; + + std::map m_default; +}; + #endif diff --git a/include/widgets/ui_common.h b/include/widgets/ui_common.h index 894414d716..f2e17abb95 100644 --- a/include/widgets/ui_common.h +++ b/include/widgets/ui_common.h @@ -54,7 +54,11 @@ enum SEVERITY { wxBitmap MakeBadge( SEVERITY aStyle, int aCount, wxWindow* aWindow, int aDepth = 1 ); +SEVERITY SeverityFromString( const wxString& aSeverity ); + +wxString SeverityToString( const SEVERITY& aSeverity ); -#endif // UI_COMMON_H \ No newline at end of file + +#endif // UI_COMMON_H diff --git a/kicad/kicad_manager_frame.cpp b/kicad/kicad_manager_frame.cpp index 6451f5983f..ec85a294c0 100644 --- a/kicad/kicad_manager_frame.cpp +++ b/kicad/kicad_manager_frame.cpp @@ -373,7 +373,7 @@ void KICAD_MANAGER_FRAME::CreateNewProject( const wxFileName& aProjectFileName ) // Copy kicad.pro file from template folder. if( !aProjectFileName.FileExists() ) { - // TODO(JE) provide in new format + // TODO(JE) PROJECT provide in new format wxString srcFileName = sys_search().FindValidPath( "kicad.pro" ); wxFileName destFileName( aProjectFileName ); diff --git a/pcbnew/board_design_settings.cpp b/pcbnew/board_design_settings.cpp index c0740335ab..1dc51fca9c 100644 --- a/pcbnew/board_design_settings.cpp +++ b/pcbnew/board_design_settings.cpp @@ -244,18 +244,18 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std: [&]() -> nlohmann::json { nlohmann::json ret = {}; - DRC_ITEM drc( 0 ); - for( int i = DRCE_FIRST; i <= DRCE_LAST; ++i ) + for( const RC_ITEM& item : DRC_ITEM::GetItemsWithSeverities() ) { - if( !m_DRCSeverities.count( i ) ) + int code = item.GetErrorCode(); + + if( !m_DRCSeverities.count( code ) ) continue; - wxString name = drc.GetErrorText( i, false ); - name.Replace( wxT( " " ), wxT( "_" ) ); + wxString name = item.GetSettingsKey(); ret[std::string( name.ToUTF8() )] = - severityToString( static_cast( m_DRCSeverities[i] ) ); + SeverityToString( static_cast( m_DRCSeverities[code] ) ); } return ret; @@ -265,17 +265,13 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std: if( !aJson.is_object() ) return; - DRC_ITEM drc( 0 ); - - for( int i = DRCE_FIRST; i <= DRCE_LAST; ++i ) + for( const RC_ITEM& item : DRC_ITEM::GetItemsWithSeverities() ) { - wxString name = drc.GetErrorText( i, false ); - name.Replace( wxT( " " ), wxT( "_" ) ); - + wxString name = item.GetSettingsKey(); std::string key( name.ToUTF8() ); if( aJson.contains( key ) ) - m_DRCSeverities[i] = severityFromString( aJson[key] ); + m_DRCSeverities[item.GetErrorCode()] = SeverityFromString( aJson[key] ); } }, {} ) ); @@ -573,27 +569,6 @@ BOARD_DESIGN_SETTINGS::~BOARD_DESIGN_SETTINGS() } -SEVERITY BOARD_DESIGN_SETTINGS::severityFromString( const wxString& aSeverity ) -{ - if( aSeverity == wxT( "warning" ) ) - return RPT_SEVERITY_WARNING; - else if( aSeverity == wxT( "ignore" ) ) - return RPT_SEVERITY_IGNORE; - else - return RPT_SEVERITY_ERROR; -} - -wxString BOARD_DESIGN_SETTINGS::severityToString( const SEVERITY& aSeverity ) -{ - if( aSeverity == RPT_SEVERITY_IGNORE ) - return wxT( "ignore" ); - else if( aSeverity == RPT_SEVERITY_WARNING ) - return wxT( "warning" ); - else - return wxT( "error" ); -} - - bool BOARD_DESIGN_SETTINGS::LoadFromFile( const std::string& aDirectory ) { bool ret = NESTED_SETTINGS::LoadFromFile( aDirectory ); @@ -609,13 +584,12 @@ bool BOARD_DESIGN_SETTINGS::LoadFromFile( const std::string& aDirectory ) bool migrated = false; - DRC_ITEM drc( 0 ); - auto drcName = - [drc]( int aCode ) -> std::string + []( int aCode ) -> std::string { - wxString name = drc.GetErrorText( aCode, false ); - name.Replace( wxT( " " ), wxT( "_" ) ); + DRC_ITEM* item = DRC_ITEM::Create( aCode ); + wxString name = item->GetSettingsKey(); + delete item; return std::string( name.ToUTF8() ); }; @@ -634,32 +608,19 @@ bool BOARD_DESIGN_SETTINGS::LoadFromFile( const std::string& aDirectory ) migrated = true; } - if( OPT v = project->Get( PointerFromString( bp + "legacy_ourtyards_overlap" ) ) ) + if( OPT v = project->Get( PointerFromString( bp + "legacy_courtyards_overlap" ) ) ) { if( *v ) ( *this )[PointerFromString( rs + drcName( DRCE_OVERLAPPING_FOOTPRINTS ) )] = "error"; else ( *this )[PointerFromString( rs + drcName( DRCE_OVERLAPPING_FOOTPRINTS ) )] = "ignore"; - project->erase( PointerFromString( bp + "legacy_ourtyards_overlap" ) ); + project->erase( PointerFromString( bp + "legacy_courtyards_overlap" ) ); migrated = true; } - if( project->contains( PointerFromString( "legacy.pcbnew" ) ) ) - { - // DRC Severities - for( int i = DRCE_FIRST; i <= DRCE_LAST; ++i ) - { - std::string key( severityToString( static_cast( i ) ).ToUTF8() ); - - if( OPT v = project->Get( "legacy.pcbnew." + key ) ) - ( *this )[PointerFromString( rs + key )] = *v; - } - - // We are the only place that needs this info, so now it can be deleted + if( project->contains( "legacy" ) ) project->at( "legacy" ).erase( "pcbnew" ); - migrated = true; - } // Now that we have everything, we need to load again if( migrated ) diff --git a/pcbnew/class_marker_pcb.cpp b/pcbnew/class_marker_pcb.cpp index 48f0013f68..3139319041 100644 --- a/pcbnew/class_marker_pcb.cpp +++ b/pcbnew/class_marker_pcb.cpp @@ -62,7 +62,7 @@ MARKER_PCB::~MARKER_PCB() wxString MARKER_PCB::Serialize() const { return wxString::Format( wxT( "%s|%d|%d|%s|%s" ), - m_rcItem->GetErrorText( m_rcItem->GetErrorCode(), false ), + m_rcItem->GetSettingsKey(), m_Pos.x, m_Pos.y, m_rcItem->GetMainItemID().AsString(), @@ -76,7 +76,7 @@ MARKER_PCB* MARKER_PCB::Deserialize( const wxString& data ) wxPoint markerPos( (int) strtol( props[1].c_str(), nullptr, 10 ), (int) strtol( props[2].c_str(), nullptr, 10 ) ); - DRC_ITEM* drcItem = new DRC_ITEM( props[0] ); + DRC_ITEM* drcItem = DRC_ITEM::Create( props[0] ); drcItem->SetItems( KIID( props[3] ), KIID( props[4] ) ); return new MARKER_PCB( drcItem, markerPos ); @@ -141,8 +141,7 @@ wxString MARKER_PCB::GetSelectMenuText( EDA_UNITS aUnits ) const { // m_rcItem->GetErrorMessage() could be used instead, but is probably too long // for menu duty. - return wxString::Format( _( "Marker (%s)" ), - m_rcItem->GetErrorText( m_rcItem->GetErrorCode() ) ); + return wxString::Format( _( "Marker (%s)" ), m_rcItem->GetErrorText() ); } diff --git a/pcbnew/cleanup_item.h b/pcbnew/cleanup_item.h index 9a7e4a92ad..820a1bf8f6 100644 --- a/pcbnew/cleanup_item.h +++ b/pcbnew/cleanup_item.h @@ -54,7 +54,7 @@ public: * Function GetErrorText * returns the string form of a drc error code. */ - wxString GetErrorText( int aErrorCode = -1, bool aTranslate = true ) const override; + wxString GetErrorText( int aErrorCode = -1, bool aTranslate = true ) const; /** * Function ShowHtml diff --git a/pcbnew/dialogs/dialog_board_setup.cpp b/pcbnew/dialogs/dialog_board_setup.cpp index 56cd7cf1ab..fce025246d 100644 --- a/pcbnew/dialogs/dialog_board_setup.cpp +++ b/pcbnew/dialogs/dialog_board_setup.cpp @@ -53,10 +53,9 @@ DIALOG_BOARD_SETUP::DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame ) : m_maskAndPaste = new PANEL_SETUP_MASK_AND_PASTE( this, aFrame ); m_physicalStackup = new PANEL_SETUP_BOARD_STACKUP( this, aFrame, m_layers ); - DRC_ITEM dummyItem( 0 ); BOARD_DESIGN_SETTINGS& bds = aFrame->GetDesignSettings(); - m_severities = new PANEL_SETUP_SEVERITIES( this, dummyItem, bds.m_DRCSeverities, - DRCE_FIRST, DRCE_LAST ); + m_severities = new PANEL_SETUP_SEVERITIES( this, DRC_ITEM::GetItemsWithSeverities(), + bds.m_DRCSeverities ); m_textVars = new PANEL_TEXT_VARIABLES( m_treebook, &Prj() ); @@ -140,7 +139,7 @@ void DIALOG_BOARD_SETUP::OnAuxiliaryAction( wxCommandEvent& event ) if( !m_frame->GetSettingsManager()->LoadProject( projectFn.GetFullPath(), false ) ) { - wxString msg = wxString::Format( _( "Error importing settings from borad:\n" + wxString msg = wxString::Format( _( "Error importing settings from board:\n" "Associated project file %s could not be loaded" ), projectFn.GetFullPath() ); DisplayErrorMessage( this, msg ); diff --git a/pcbnew/dialogs/dialog_drc.cpp b/pcbnew/dialogs/dialog_drc.cpp index b4196212bd..c5a6198855 100644 --- a/pcbnew/dialogs/dialog_drc.cpp +++ b/pcbnew/dialogs/dialog_drc.cpp @@ -306,20 +306,20 @@ void DIALOG_DRC::OnDRCItemRClick( wxDataViewEvent& aEvent ) if( bds().m_DRCSeverities[ rcItem->GetErrorCode() ] == RPT_SEVERITY_WARNING ) { msg.Printf( _( "Change severity to Error for all '%s' violations" ), - rcItem->GetErrorText( rcItem->GetErrorCode() ), + rcItem->GetErrorText(), _( "Violation severities can also be edited in the Board Setup... dialog" ) ); menu.Append( 3, msg ); } else { msg.Printf( _( "Change severity to Warning for all '%s' violations" ), - rcItem->GetErrorText( rcItem->GetErrorCode() ), + rcItem->GetErrorText(), _( "Violation severities can also be edited in the Board Setup... dialog" ) ); menu.Append( 4, msg ); } msg.Printf( _( "Ignore all '%s' violations" ), - rcItem->GetErrorText( rcItem->GetErrorCode() ), + rcItem->GetErrorText(), _( "Violations will not be checked or reported" ) ); menu.Append( 5, msg ); diff --git a/pcbnew/drc/drc.cpp b/pcbnew/drc/drc.cpp index 31ee50073b..88d63be51d 100644 --- a/pcbnew/drc/drc.cpp +++ b/pcbnew/drc/drc.cpp @@ -237,9 +237,7 @@ void DRC::RunTests( wxTextCtrl* aMessages ) m_largestClearance = bds.GetBiggestClearanceValue(); if( !bds.Ignore( DRCE_INVALID_OUTLINE ) - || !bds.Ignore( DRCE_TRACK_NEAR_EDGE ) - || !bds.Ignore( DRCE_VIA_NEAR_EDGE ) - || !bds.Ignore( DRCE_PAD_NEAR_EDGE ) ) + || !bds.Ignore( DRCE_COPPER_EDGE_CLEARANCE ) ) { if( aMessages ) { @@ -268,7 +266,8 @@ void DRC::RunTests( wxTextCtrl* aMessages ) // class (a NET) will cause its items such as tracks, vias, and pads // to also fail. So quit after *all* netclass errors have been reported. if( aMessages ) - aMessages->AppendText( _( "NETCLASS VIOLATIONS: Aborting DRC\n" ) ); + aMessages->AppendText( _( "Netclasses are not valid: Cannot run DRC\n" + "Please open Board Setup and\ncheck netclass definitions" ) ); commit.Push( wxEmptyString, false, false ); @@ -279,9 +278,7 @@ void DRC::RunTests( wxTextCtrl* aMessages ) } // test pad to pad clearances, nothing to do with tracks, vias or zones. - if( !bds.Ignore( DRCE_PAD_NEAR_EDGE ) - || !bds.Ignore( DRCE_PAD_NEAR_PAD ) - || !bds.Ignore( DRCE_HOLE_NEAR_PAD ) ) + if( !bds.Ignore( DRCE_COPPER_EDGE_CLEARANCE ) ) { if( aMessages ) { @@ -294,8 +291,7 @@ void DRC::RunTests( wxTextCtrl* aMessages ) // test drilled holes if( !bds.Ignore( DRCE_DRILLED_HOLES_TOO_CLOSE ) - || !bds.Ignore( DRCE_TOO_SMALL_PAD_DRILL ) - || !bds.Ignore( DRCE_TOO_SMALL_VIA_DRILL ) + || !bds.Ignore( DRCE_TOO_SMALL_DRILL ) || !bds.Ignore( DRCE_TOO_SMALL_MICROVIA_DRILL ) ) { if( aMessages ) @@ -379,8 +375,7 @@ void DRC::RunTests( wxTextCtrl* aMessages ) } // find and gather vias, tracks, pads inside text boxes. - if( !bds.Ignore( DRCE_VIA_NEAR_COPPER ) - || !bds.Ignore( DRCE_TRACK_NEAR_COPPER ) ) + if( !bds.Ignore( DRCE_CLEARANCE ) ) { if( aMessages ) { @@ -530,7 +525,7 @@ void DRC::testPadClearances( BOARD_COMMIT& aCommit ) // Test the pads for( auto& pad : sortedPads ) { - if( !bds.Ignore( DRCE_PAD_NEAR_EDGE ) && m_board_outline_valid ) + if( !bds.Ignore( DRCE_COPPER_EDGE_CLEARANCE ) && m_board_outline_valid ) { int minClearance = bds.m_CopperEdgeClearance; m_clearanceSource = _( "board edge" ); @@ -548,7 +543,7 @@ void DRC::testPadClearances( BOARD_COMMIT& aCommit ) if( !checkClearanceSegmToPad( *it, 0, pad, minClearance, &actual ) ) { actual = std::max( 0, actual ); - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_PAD_NEAR_EDGE ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_COPPER_EDGE_CLEARANCE ); m_msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ), m_clearanceSource, @@ -566,7 +561,7 @@ void DRC::testPadClearances( BOARD_COMMIT& aCommit ) } } - if( !bds.Ignore( DRCE_PAD_NEAR_PAD ) || !bds.Ignore( DRCE_HOLE_NEAR_PAD ) ) + if( !bds.Ignore( DRCE_CLEARANCE ) ) { int x_limit = pad->GetPosition().x + pad->GetBoundingRadius() + max_size; @@ -636,7 +631,7 @@ void DRC::testTracks( BOARD_COMMIT& aCommit, wxWindow *aActiveWindow, bool aShow if( !settings.Ignore( code ) && connectivity->TestTrackEndpointDangling( *seg_it, &pos ) ) { - DRC_ITEM* drcItem = new DRC_ITEM( code ); + DRC_ITEM* drcItem = DRC_ITEM::Create( code ); drcItem->SetItems( *seg_it ); MARKER_PCB* marker = new MARKER_PCB( drcItem, pos ); @@ -667,7 +662,7 @@ void DRC::testUnconnected() for( const CN_EDGE& edge : edges ) { - DRC_ITEM* item = new DRC_ITEM( DRCE_UNCONNECTED_ITEMS ); + DRC_ITEM* item = DRC_ITEM::Create( DRCE_UNCONNECTED_ITEMS ); item->SetItems( edge.GetSourceNode()->Parent(), edge.GetTargetNode()->Parent() ); m_unconnected.push_back( item ); } @@ -704,7 +699,7 @@ void DRC::testZones( BOARD_COMMIT& aCommit ) if( ( netcode < 0 ) || pads_in_net == 0 ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_ZONE_HAS_EMPTY_NET ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_ZONE_HAS_EMPTY_NET ); drcItem->SetItems( zone ); MARKER_PCB* marker = new MARKER_PCB( drcItem, zone->GetPosition() ); @@ -772,7 +767,7 @@ void DRC::testZones( BOARD_COMMIT& aCommit ) if( smoothed_polys[ia2].Contains( currentVertex ) ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_ZONES_INTERSECT ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_ZONES_INTERSECT ); drcItem->SetItems( zoneRef, zoneToTest ); MARKER_PCB* marker = new MARKER_PCB( drcItem, pt ); @@ -788,7 +783,7 @@ void DRC::testZones( BOARD_COMMIT& aCommit ) if( smoothed_polys[ia].Contains( currentVertex ) ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_ZONES_INTERSECT ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_ZONES_INTERSECT ); drcItem->SetItems( zoneToTest, zoneRef ); MARKER_PCB* marker = new MARKER_PCB( drcItem, pt ); @@ -847,11 +842,11 @@ void DRC::testZones( BOARD_COMMIT& aCommit ) if( actual <= 0 ) { - drcItem = new DRC_ITEM( DRCE_ZONES_INTERSECT ); + drcItem = DRC_ITEM::Create( DRCE_ZONES_INTERSECT ); } else { - drcItem = new DRC_ITEM( DRCE_ZONES_TOO_CLOSE ); + drcItem = DRC_ITEM::Create( DRCE_CLEARANCE ); m_msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ), m_clearanceSource, @@ -1051,9 +1046,7 @@ void DRC::testCopperDrawItem( BOARD_COMMIT& aCommit, BOARD_ITEM* aItem ) if( center2center_squared < SEG::Square( center2centerAllowed ) ) { int actual = std::max( 0.0, sqrt( center2center_squared ) - widths ); - int errorCode = ( track->Type() == PCB_VIA_T ) ? DRCE_VIA_NEAR_COPPER - : DRCE_TRACK_NEAR_COPPER; - DRC_ITEM* drcItem = new DRC_ITEM( errorCode ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_CLEARANCE ); m_msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ), m_clearanceSource, @@ -1110,7 +1103,7 @@ void DRC::testCopperDrawItem( BOARD_COMMIT& aCommit, BOARD_ITEM* aItem ) if( center2center_squared < SEG::Square( center2centerAllowed ) ) { int actual = std::max( 0.0, sqrt( center2center_squared ) - widths ); - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_PAD_NEAR_COPPER ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_CLEARANCE ); m_msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ), m_clearanceSource, @@ -1140,7 +1133,7 @@ void DRC::testOutline( BOARD_COMMIT& aCommit ) } else { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_INVALID_OUTLINE ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_INVALID_OUTLINE ); m_msg.Printf( drcItem->GetErrorText() + _( " (not a closed shape)" ) ); @@ -1164,7 +1157,7 @@ void DRC::testDisabledLayers( BOARD_COMMIT& aCommit ) { if( disabledLayers.test( track->GetLayer() ) ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_DISABLED_LAYER_ITEM ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_DISABLED_LAYER_ITEM ); m_msg.Printf( drcItem->GetErrorText() + _( "layer %s" ), track->GetLayerName() ); @@ -1184,7 +1177,7 @@ void DRC::testDisabledLayers( BOARD_COMMIT& aCommit ) { if( disabledLayers.test( child->GetLayer() ) ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_DISABLED_LAYER_ITEM ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_DISABLED_LAYER_ITEM ); m_msg.Printf( drcItem->GetErrorText() + _( "layer %s" ), child->GetLayerName() ); @@ -1202,7 +1195,7 @@ void DRC::testDisabledLayers( BOARD_COMMIT& aCommit ) { if( disabledLayers.test( zone->GetLayer() ) ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_DISABLED_LAYER_ITEM ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_DISABLED_LAYER_ITEM ); m_msg.Printf( drcItem->GetErrorText() + _( "layer %s" ), zone->GetLayerName() ); @@ -1284,7 +1277,7 @@ bool DRC::doPadToPadsDrc( BOARD_COMMIT& aCommit, D_PAD* aRefPad, D_PAD** aStart, if( !checkClearancePadToPad( aRefPad, &dummypad, minClearance, &actual ) ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_HOLE_NEAR_PAD ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_CLEARANCE ); m_msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ), m_clearanceSource, @@ -1313,7 +1306,7 @@ bool DRC::doPadToPadsDrc( BOARD_COMMIT& aCommit, D_PAD* aRefPad, D_PAD** aStart, if( !checkClearancePadToPad( pad, &dummypad, minClearance, &actual ) ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_HOLE_NEAR_PAD ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_CLEARANCE ); m_msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ), m_clearanceSource, @@ -1362,7 +1355,7 @@ bool DRC::doPadToPadsDrc( BOARD_COMMIT& aCommit, D_PAD* aRefPad, D_PAD** aStart, if( !checkClearancePadToPad( aRefPad, pad, clearanceAllowed, &actual ) ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_PAD_NEAR_PAD ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_CLEARANCE ); m_msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ), m_clearanceSource, diff --git a/pcbnew/drc/drc.h b/pcbnew/drc/drc.h index d109ee8ed9..924992dd12 100644 --- a/pcbnew/drc/drc.h +++ b/pcbnew/drc/drc.h @@ -40,58 +40,24 @@ enum PCB_DRC_CODE { DRCE_FIRST = 1, DRCE_UNCONNECTED_ITEMS = DRCE_FIRST, ///< items are unconnected - DRCE_TRACK_NEAR_HOLE, ///< thru hole is too close to track - DRCE_TRACK_NEAR_PAD, ///< pad too close to track - DRCE_TRACK_NEAR_VIA, ///< track too close to via - DRCE_TRACK_NEAR_ZONE, ///< track & zone collide or are too close together - DRCE_TRACK_NEAR_COPPER, ///< track & copper graphic collide or are too close - DRCE_VIA_NEAR_VIA, ///< via too close to via - DRCE_VIA_NEAR_TRACK, ///< via too close to track - DRCE_VIA_NEAR_COPPER, ///< via and copper graphic collide or are too close - DRCE_TRACK_ENDS, ///< track ends are too close - DRCE_TRACK_SEGMENTS_TOO_CLOSE, ///< 2 parallel track segments too close: segm ends between segref ends + DRCE_ALLOWED_ITEMS, ///< a disallowed item has been used + DRCE_CLEARANCE, ///< items are too close together DRCE_TRACKS_CROSSING, ///< tracks are crossing - DRCE_TRACK_NEAR_EDGE, ///< track too close to board edge - DRCE_VIA_NEAR_EDGE, ///< via too close to board edge - DRCE_PAD_NEAR_EDGE, ///< pad too close to board edge - DRCE_PAD_NEAR_PAD, ///< pad too close to pad - DRCE_PAD_NEAR_COPPER, ///< pad and copper graphic collide or are too close + DRCE_COPPER_EDGE_CLEARANCE, ///< a copper item is too close to the board edge DRCE_ZONES_INTERSECT, ///< copper area outlines intersect - DRCE_ZONES_TOO_CLOSE, ///< copper area outlines are too close DRCE_ZONE_HAS_EMPTY_NET, ///< copper area has a net but no pads in nets, which is suspicious DRCE_DANGLING_VIA, ///< via which isn't connected to anything DRCE_DANGLING_TRACK, ///< track with at least one end not connected to anything - DRCE_HOLE_NEAR_PAD, ///< hole too close to pad - DRCE_HOLE_NEAR_TRACK, ///< hole too close to track DRCE_DRILLED_HOLES_TOO_CLOSE, ///< overlapping drilled holes break drill bits - DRCE_TOO_SMALL_TRACK_WIDTH, ///< Too small track width - DRCE_TOO_LARGE_TRACK_WIDTH, ///< Too small track width + DRCE_TRACK_WIDTH, ///< Track width is too small or too large DRCE_TOO_SMALL_VIA, ///< Too small via size - DRCE_TOO_SMALL_VIA_ANNULUS, ///< Via size and drill leave annulus too small - DRCE_TOO_SMALL_VIA_DRILL, ///< Too small via drill - DRCE_TOO_SMALL_PAD_DRILL, ///< Too small via drill + DRCE_VIA_ANNULUS, ///< Via size and drill leave annulus too small or too large + DRCE_TOO_SMALL_DRILL, ///< Too small via or pad drill DRCE_VIA_HOLE_BIGGER, ///< via's hole is bigger than its diameter - DRCE_MICROVIA_NOT_ALLOWED, ///< micro vias are not allowed - DRCE_MICROVIA_TOO_MANY_LAYERS, ///< micro via's layer pair incorrect (layers must be adjacent) + DRCE_PADSTACK, ///< something is wrong with a pad or via stackup DRCE_TOO_SMALL_MICROVIA, ///< Too small micro via size DRCE_TOO_SMALL_MICROVIA_DRILL, ///< Too small micro via drill - DRCE_BURIED_VIA_NOT_ALLOWED, ///< buried vias are not allowed - DRCE_NETCLASS_TRACKWIDTH, ///< netclass has TrackWidth < board.m_designSettings->m_TrackMinWidth - DRCE_NETCLASS_CLEARANCE, ///< netclass has Clearance < board.m_designSettings->m_TrackClearance - DRCE_NETCLASS_VIAANNULUS, ///< netclass ViaSize & ViaDrill leave annulus < board.m_designSettings->m_ViasMinAnnulus - DRCE_NETCLASS_VIASIZE, ///< netclass has ViaSize < board.m_designSettings->m_ViasMinSize - DRCE_NETCLASS_VIADRILLSIZE, ///< netclass has ViaDrillSize < board.m_designSettings->m_MinThroughDrill - DRCE_NETCLASS_uVIASIZE, ///< netclass has ViaSize < board.m_designSettings->m_MicroViasMinSize - DRCE_NETCLASS_uVIADRILLSIZE, ///< netclass has ViaSize < board.m_designSettings->m_MicroViasMinDrill - DRCE_VIA_INSIDE_KEEPOUT, - DRCE_MICROVIA_INSIDE_KEEPOUT, - DRCE_BBVIA_INSIDE_KEEPOUT, - DRCE_TRACK_INSIDE_KEEPOUT, - DRCE_PAD_INSIDE_KEEPOUT, - DRCE_FOOTPRINT_INSIDE_KEEPOUT, - DRCE_HOLE_INSIDE_KEEPOUT, - DRCE_TEXT_INSIDE_KEEPOUT, - DRCE_GRAPHICS_INSIDE_KEEPOUT, + DRCE_KEEPOUT, ///< A disallowed object is inside a keepout DRCE_OVERLAPPING_FOOTPRINTS, ///< footprint courtyards overlap DRCE_MISSING_COURTYARD, ///< footprint has no courtyard defined DRCE_MALFORMED_COURTYARD, ///< footprint has a courtyard but malformed diff --git a/pcbnew/drc/drc_clearance_test_functions.cpp b/pcbnew/drc/drc_clearance_test_functions.cpp index f9c198e18f..32686d7ce0 100644 --- a/pcbnew/drc/drc_clearance_test_functions.cpp +++ b/pcbnew/drc/drc_clearance_test_functions.cpp @@ -103,9 +103,9 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS { if( viaAnnulus < minAnnulus ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_VIA_ANNULUS ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_VIA_ANNULUS ); - m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ), + m_msg.Printf( _( "Via annulus too small (%s %s; actual %s)" ), m_clearanceSource, MessageTextFromValue( userUnits(), minAnnulus, true ), MessageTextFromValue( userUnits(), viaAnnulus, true ) ); @@ -119,7 +119,7 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS if( refvia->GetWidth() < bds.m_MicroViasMinSize ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_MICROVIA ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_TOO_SMALL_MICROVIA ); m_msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; actual %s)" ), MessageTextFromValue( userUnits(), bds.m_MicroViasMinSize, true ), @@ -142,9 +142,9 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS if( viaAnnulus < minAnnulus ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_VIA_ANNULUS ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_VIA_ANNULUS ); - m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ), + m_msg.Printf( _( "Via annulus too small (%s %s; actual %s)" ), m_clearanceSource, MessageTextFromValue( userUnits(), minAnnulus, true ), MessageTextFromValue( userUnits(), viaAnnulus, true ) ); @@ -158,7 +158,7 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS if( refvia->GetWidth() < bds.m_ViasMinSize ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_VIA ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_TOO_SMALL_VIA ); m_msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; actual %s)" ), MessageTextFromValue( userUnits(), bds.m_ViasMinSize, true ), @@ -177,7 +177,7 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS // and a default via hole can be bigger than some vias sizes if( refvia->GetDrillValue() > refvia->GetWidth() ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_VIA_HOLE_BIGGER ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_VIA_HOLE_BIGGER ); m_msg.Printf( drcItem->GetErrorText() + _( " (diameter %s; drill %s)" ), MessageTextFromValue( userUnits(), refvia->GetWidth(), true ), @@ -193,9 +193,9 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS // test if the type of via is allowed due to design rules if( refvia->GetViaType() == VIATYPE::MICROVIA && !bds.m_MicroViasAllowed ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_MICROVIA_NOT_ALLOWED ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_ALLOWED_ITEMS ); - m_msg.Printf( drcItem->GetErrorText() + _( " (board design rule constraints)" ) ); + m_msg.Printf( _( "Microvia not allowed (board design rule constraints)" ) ); drcItem->SetErrorMessage( m_msg ); drcItem->SetItems( refvia ); @@ -206,9 +206,9 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS // test if the type of via is allowed due to design rules if( refvia->GetViaType() == VIATYPE::BLIND_BURIED && !bds.m_BlindBuriedViaAllowed ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_BURIED_VIA_NOT_ALLOWED ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_ALLOWED_ITEMS ); - m_msg.Printf( drcItem->GetErrorText() + _( " (board design rule constraints)" ) ); + m_msg.Printf( _( "Blind/buried via not allowed (board design rule constraints)" ) ); drcItem->SetErrorMessage( m_msg ); drcItem->SetItems( refvia ); @@ -236,9 +236,9 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS if( err ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_MICROVIA_TOO_MANY_LAYERS ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_PADSTACK ); - m_msg.Printf( drcItem->GetErrorText() + _( " (%s and %s not adjacent)" ), + m_msg.Printf( _( "Microvia through too many layers (%s and %s not adjacent)" ), m_pcb->GetLayerName( layer1 ), m_pcb->GetLayerName( layer2 ) ); @@ -261,12 +261,12 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS if( refSegWidth < minWidth ) { - errorCode = DRCE_TOO_SMALL_TRACK_WIDTH; + errorCode = DRCE_TRACK_WIDTH; constraintWidth = minWidth; } else if( refSegWidth > maxWidth ) { - errorCode = DRCE_TOO_LARGE_TRACK_WIDTH; + errorCode = DRCE_TRACK_WIDTH; constraintWidth = maxWidth; } @@ -274,7 +274,7 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS { wxPoint refsegMiddle = ( aRefSeg->GetStart() + aRefSeg->GetEnd() ) / 2; - DRC_ITEM* drcItem = new DRC_ITEM( errorCode ); + DRC_ITEM* drcItem = DRC_ITEM::Create( errorCode ); m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ), m_clearanceSource, @@ -363,7 +363,7 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS if( center2center_squared < SEG::Square( center2centerAllowed ) ) { int actual = std::max( 0.0, sqrt( center2center_squared ) - widths ); - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TRACK_NEAR_HOLE ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_CLEARANCE ); m_msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ), m_clearanceSource, @@ -389,7 +389,7 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS { actual = std::max( 0, actual ); SEG padSeg( pad->GetPosition(), pad->GetPosition() ); - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TRACK_NEAR_PAD ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_CLEARANCE ); m_msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ), m_clearanceSource, @@ -463,7 +463,7 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS // Check two tracks crossing first as it reports a DRCE without distances if( intersection ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TRACKS_CROSSING ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_TRACKS_CROSSING ); drcItem->SetErrorMessage( m_msg ); drcItem->SetItems( aRefSeg, track ); @@ -475,17 +475,8 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS } else if( center2center_squared < SEG::Square( center2centerAllowed ) ) { - int errorCode = DRCE_TRACK_ENDS; - - if( aRefSeg->Type() == PCB_VIA_T && track->Type() == PCB_VIA_T ) - errorCode = DRCE_VIA_NEAR_VIA; - else if( aRefSeg->Type() == PCB_VIA_T || track->Type() == PCB_VIA_T ) - errorCode = DRCE_VIA_NEAR_TRACK; - else if( refSeg.ApproxParallel( trackSeg ) ) - errorCode = DRCE_TRACK_SEGMENTS_TOO_CLOSE; - - int actual = std::max( 0.0, sqrt( center2center_squared ) - widths ); - DRC_ITEM* drcItem = new DRC_ITEM( errorCode ); + int actual = std::max( 0.0, sqrt( center2center_squared ) - widths ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_CLEARANCE ); m_msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ), m_clearanceSource, @@ -540,7 +531,7 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS if( center2center_squared + THRESHOLD_DIST < SEG::Square( center2centerAllowed ) ) { int actual = std::max( 0.0, sqrt( center2center_squared ) - widths ); - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TRACK_NEAR_ZONE ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_CLEARANCE ); m_msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ), m_clearanceSource, @@ -605,10 +596,8 @@ void DRC::doTrackDrc( BOARD_COMMIT& aCommit, TRACK* aRefSeg, TRACKS::iterator aS // Best-efforts search for edge segment BOARD::IterateForward( m_pcb->Drawings(), inspector, nullptr, types ); - int actual = std::max( 0.0, sqrt( center2center_squared ) - halfWidth ); - int errorCode = ( aRefSeg->Type() == PCB_VIA_T ) ? DRCE_VIA_NEAR_EDGE - : DRCE_TRACK_NEAR_EDGE; - DRC_ITEM* drcItem = new DRC_ITEM( errorCode ); + int actual = std::max( 0.0, sqrt( center2center_squared ) - halfWidth ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_COPPER_EDGE_CLEARANCE ); m_msg.Printf( drcItem->GetErrorText() + _( " (%s clearance %s; actual %s)" ), m_clearanceSource, diff --git a/pcbnew/drc/drc_courtyard_tester.cpp b/pcbnew/drc/drc_courtyard_tester.cpp index 36f148d492..16c1f6d755 100644 --- a/pcbnew/drc/drc_courtyard_tester.cpp +++ b/pcbnew/drc/drc_courtyard_tester.cpp @@ -56,7 +56,7 @@ bool DRC_COURTYARD_TESTER::RunDRC( EDA_UNITS aUnits, BOARD& aBoard ) && footprint->GetPolyCourtyardFront().OutlineCount() == 0 && footprint->GetPolyCourtyardBack().OutlineCount() == 0 ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_MISSING_COURTYARD ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_MISSING_COURTYARD ); drcItem->SetItems( footprint ); HandleMarker( new MARKER_PCB( drcItem, footprint->GetPosition() ) ); success = false; @@ -71,7 +71,7 @@ bool DRC_COURTYARD_TESTER::RunDRC( EDA_UNITS aUnits, BOARD& aBoard ) { if( !aBoard.GetDesignSettings().Ignore( DRCE_MALFORMED_COURTYARD ) ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_MALFORMED_COURTYARD ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_MALFORMED_COURTYARD ); msg.Printf( drcItem->GetErrorText() + _( " (not a closed shape)" ) ); @@ -137,7 +137,7 @@ bool DRC_COURTYARD_TESTER::RunDRC( EDA_UNITS aUnits, BOARD& aBoard ) if( overlap ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_OVERLAPPING_FOOTPRINTS ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_OVERLAPPING_FOOTPRINTS ); drcItem->SetItems( footprint, test ); HandleMarker( new MARKER_PCB( drcItem, pos ) ); success = false; @@ -175,7 +175,7 @@ bool DRC_COURTYARD_TESTER::RunDRC( EDA_UNITS aUnits, BOARD& aBoard ) int code = pad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED ? DRCE_NPTH_IN_COURTYARD : DRCE_PTH_IN_COURTYARD; - DRC_ITEM* drcItem = new DRC_ITEM( code ); + DRC_ITEM* drcItem = DRC_ITEM::Create( code ); drcItem->SetItems( footprint, pad ); HandleMarker( new MARKER_PCB( drcItem, pos ) ); success = false; diff --git a/pcbnew/drc/drc_drilled_hole_tester.cpp b/pcbnew/drc/drc_drilled_hole_tester.cpp index eeca399e5e..f1d8478e06 100644 --- a/pcbnew/drc/drc_drilled_hole_tester.cpp +++ b/pcbnew/drc/drc_drilled_hole_tester.cpp @@ -89,7 +89,7 @@ bool DRC_DRILLED_HOLE_TESTER::checkPad( D_PAD* aPad ) if( holeSize == 0 ) return true; - if( !bds.Ignore( DRCE_TOO_SMALL_PAD_DRILL ) ) + if( !bds.Ignore( DRCE_TOO_SMALL_DRILL ) ) { int minHole = bds.m_MinThroughDrill; wxString minHoleSource = _( "board minimum" ); @@ -103,7 +103,7 @@ bool DRC_DRILLED_HOLE_TESTER::checkPad( D_PAD* aPad ) if( holeSize < minHole ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_PAD_DRILL ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_TOO_SMALL_DRILL ); m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ), minHoleSource, @@ -132,7 +132,7 @@ bool DRC_DRILLED_HOLE_TESTER::checkVia( VIA* via ) bool success = true; BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings(); - if( !bds.Ignore( DRCE_TOO_SMALL_VIA_DRILL ) ) + if( !bds.Ignore( DRCE_TOO_SMALL_DRILL ) ) { int minHole = bds.m_MinThroughDrill; wxString minHoleSource = _( "board minimum" ); @@ -146,7 +146,7 @@ bool DRC_DRILLED_HOLE_TESTER::checkVia( VIA* via ) if( via->GetDrillValue() < minHole ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_VIA_DRILL ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_TOO_SMALL_DRILL ); m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ), minHoleSource, @@ -189,7 +189,7 @@ bool DRC_DRILLED_HOLE_TESTER::checkMicroVia( VIA* via ) if( via->GetDrillValue() < minHole ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TOO_SMALL_MICROVIA_DRILL ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_TOO_SMALL_MICROVIA_DRILL ); m_msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ), minHoleSource, @@ -264,7 +264,7 @@ bool DRC_DRILLED_HOLE_TESTER::checkHoles() if( actual < bds.m_HoleToHoleMin ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_DRILLED_HOLES_TOO_CLOSE ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_DRILLED_HOLES_TOO_CLOSE ); m_msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; actual %s)" ), MessageTextFromValue( m_units, bds.m_HoleToHoleMin, true ), diff --git a/pcbnew/drc/drc_item.cpp b/pcbnew/drc/drc_item.cpp index 4cd5fb4a20..221d05523e 100644 --- a/pcbnew/drc/drc_item.cpp +++ b/pcbnew/drc/drc_item.cpp @@ -32,115 +32,220 @@ #include -DRC_ITEM::DRC_ITEM( int aErrorCode ) -{ - m_errorCode = aErrorCode; -} +// These, being statically-defined, require specialized I18N handling. We continue to +// use the _() macro so that string harvesting by the I18N framework doesn't have to be +// specialized, but we don't translate on initialization and instead do it in the getters. + +#undef _ +#define _(s) s + +DRC_ITEM DRC_ITEM::unconnectedItems( DRCE_UNCONNECTED_ITEMS, + _( "Unconnected items" ), + wxT( "unconnected_items" ) ); + +DRC_ITEM DRC_ITEM::itemsNotAllowed( DRCE_ALLOWED_ITEMS, + _( "Items not allowed" ), + wxT( "items_not_allowed" ) ); + +DRC_ITEM DRC_ITEM::clearance( DRCE_CLEARANCE, + _( "Clearance violation" ), + wxT( "clearance" ) ); + +DRC_ITEM DRC_ITEM::tracksCrossing( DRCE_TRACKS_CROSSING, + _( "Tracks crossing" ), + wxT( "tracks_crossing" ) ); + +DRC_ITEM DRC_ITEM::copperEdgeClearance( DRCE_COPPER_EDGE_CLEARANCE, + _( "Board edge clearance violation" ), + wxT( "copper_edge_clearance" ) ); + +DRC_ITEM DRC_ITEM::zonesIntersect( DRCE_ZONES_INTERSECT, + _( "Copper areas intersect" ), + wxT( "zones_intersect" ) ); + +DRC_ITEM DRC_ITEM::zoneHasEmptyNet( DRCE_ZONE_HAS_EMPTY_NET, + _( "Copper zone net has no pads" ), + wxT( "zone_has_empty_net" ) ); + +DRC_ITEM DRC_ITEM::viaDangling( DRCE_DANGLING_VIA, + _( "Via is not connected" ), + wxT( "via_dangling" ) ); + +DRC_ITEM DRC_ITEM::trackDangling( DRCE_DANGLING_TRACK, + _( "Track has unconnected end" ), + wxT( "track_dangling" ) ); + +DRC_ITEM DRC_ITEM::holeNearHole( DRCE_DRILLED_HOLES_TOO_CLOSE, + _( "Drilled holes too close together" ), + wxT( "hole_near_hole" ) ); + +DRC_ITEM DRC_ITEM::trackWidth( DRCE_TRACK_WIDTH, + _( "Track width outside allowed limits" ), + wxT( "track_width" ) ); + +DRC_ITEM DRC_ITEM::viaTooSmall( DRCE_TOO_SMALL_VIA, + _( "Via size too small" ), + wxT( "via_too_small" ) ); + +DRC_ITEM DRC_ITEM::viaAnnulus( DRCE_VIA_ANNULUS, + _( "Via annulus" ), + wxT( "via_annulus" ) ); + +DRC_ITEM DRC_ITEM::drillTooSmall( DRCE_TOO_SMALL_DRILL, + _( "Drill too small" ), + wxT( "drill_too_small" ) ); + +DRC_ITEM DRC_ITEM::viaHoleLargerThanPad( DRCE_VIA_HOLE_BIGGER, + _( "Via hole larger than diameter" ), + wxT( "via_hole_larger_than_pad" ) ); + +DRC_ITEM DRC_ITEM::padstack( DRCE_PADSTACK, + _( "Padstack is not valid" ), + wxT( "padstack" ) ); + +DRC_ITEM DRC_ITEM::microviaTooSmall( DRCE_TOO_SMALL_MICROVIA, + _( "Micro via size too small" ), + wxT( "microvia_too_small" ) ); + +DRC_ITEM DRC_ITEM::microviaDrillTooSmall( DRCE_TOO_SMALL_MICROVIA_DRILL, + _( "Micro via drill too small" ), + wxT( "microvia_drill_too_small" ) ); + +DRC_ITEM DRC_ITEM::keepout( DRCE_KEEPOUT, + _( "Keepout violation" ), + wxT( "keepout" ) ); + +DRC_ITEM DRC_ITEM::courtyardsOverlap( DRCE_OVERLAPPING_FOOTPRINTS, + _( "Courtyards overlap" ), + wxT( "courtyards_overlap" ) ); + +DRC_ITEM DRC_ITEM::missingCourtyard( DRCE_MISSING_COURTYARD, + _( "Footprint has no courtyard defined" ), + wxT( "missing_courtyard" ) ); + +DRC_ITEM DRC_ITEM::malformedCourtyard( DRCE_MALFORMED_COURTYARD, + _( "Footprint has malformed courtyard" ), + wxT( "malformed_courtyard" ) ); + +DRC_ITEM DRC_ITEM::pthInsideCourtyard( DRCE_PTH_IN_COURTYARD, + _( "PTH inside courtyard" ), + wxT( "pth_inside_courtyard" ) ); + +DRC_ITEM DRC_ITEM::npthInsideCourtyard( DRCE_NPTH_IN_COURTYARD, + _( "NPTH inside courtyard" ), + wxT( "npth_inside_courtyard" ) ); + +DRC_ITEM DRC_ITEM::itemOnDisabledLayer( DRCE_DISABLED_LAYER_ITEM, + _( "Item on a disabled layer" ), + wxT( "item_on_disabled_layer" ) ); + +DRC_ITEM DRC_ITEM::invalidOutline( DRCE_INVALID_OUTLINE, + _( "Board has malformed outline" ), + wxT( "invalid_outline" ) ); + +DRC_ITEM DRC_ITEM::duplicateFootprints( DRCE_DUPLICATE_FOOTPRINT, + _( "Duplicate footprints" ), + wxT( "duplicate_footprints" ) ); + +DRC_ITEM DRC_ITEM::missingFootprint( DRCE_MISSING_FOOTPRINT, + _( "Missing footprint" ), + wxT( "missing_footprint" ) ); + +DRC_ITEM DRC_ITEM::extraFootprint( DRCE_EXTRA_FOOTPRINT, + _( "Extra footprint" ), + wxT( "extra_footprint" ) ); + +DRC_ITEM DRC_ITEM::unresolvedVariable( DRCE_UNRESOLVED_VARIABLE, + _( "Unresolved text variable" ), + wxT( "unresolved_variable" ) ); -DRC_ITEM::DRC_ITEM( const wxString& aErrorText ) +std::vector> DRC_ITEM::allItemTypes( { + DRC_ITEM::unconnectedItems, + DRC_ITEM::itemsNotAllowed, + DRC_ITEM::clearance, + DRC_ITEM::tracksCrossing, + DRC_ITEM::copperEdgeClearance, + DRC_ITEM::zonesIntersect, + DRC_ITEM::zoneHasEmptyNet, + DRC_ITEM::viaDangling, + DRC_ITEM::trackDangling, + DRC_ITEM::holeNearHole, + DRC_ITEM::trackWidth, + DRC_ITEM::viaTooSmall, + DRC_ITEM::viaAnnulus, + DRC_ITEM::drillTooSmall, + DRC_ITEM::viaHoleLargerThanPad, + DRC_ITEM::padstack, + DRC_ITEM::microviaTooSmall, + DRC_ITEM::microviaDrillTooSmall, + DRC_ITEM::keepout, + DRC_ITEM::courtyardsOverlap, + DRC_ITEM::missingCourtyard, + DRC_ITEM::malformedCourtyard, + DRC_ITEM::pthInsideCourtyard, + DRC_ITEM::npthInsideCourtyard, + DRC_ITEM::itemOnDisabledLayer, + DRC_ITEM::invalidOutline, + DRC_ITEM::duplicateFootprints, + DRC_ITEM::missingFootprint, + DRC_ITEM::extraFootprint, + DRC_ITEM::unresolvedVariable + } ); + + +DRC_ITEM* DRC_ITEM::Create( int aErrorCode ) { - for( int errorCode = DRCE_FIRST; errorCode <= DRCE_LAST; ++errorCode ) + switch( aErrorCode ) { - if( aErrorText == GetErrorText( errorCode, false ) ) - { - m_errorCode = errorCode; - break; - } - } -} - - -wxString DRC_ITEM::GetErrorText( int aCode, bool aTranslate ) const -{ - wxString msg; - - if( aCode < 0 ) - aCode = m_errorCode; - - switch( aCode ) - { - case DRCE_UNCONNECTED_ITEMS: msg = _HKI( "Unconnected items" ); break; - case DRCE_TRACK_NEAR_HOLE: msg = _HKI( "Track too close to hole" ); break; - case DRCE_TRACK_NEAR_PAD: msg = _HKI( "Track too close to pad" ); break; - case DRCE_TRACK_NEAR_VIA: msg = _HKI( "Track too close to via" ); break; - case DRCE_VIA_NEAR_VIA: msg = _HKI( "Vias too close" ); break; - case DRCE_VIA_NEAR_TRACK: msg = _HKI( "Via too close to track" ); break; - case DRCE_TRACK_ENDS: msg = _HKI( "Track ends too close" ); break; - case DRCE_TRACK_SEGMENTS_TOO_CLOSE: msg = _HKI( "Parallel tracks too close" ); break; - case DRCE_TRACKS_CROSSING: msg = _HKI( "Tracks crossing" ); break; - case DRCE_TRACK_NEAR_ZONE: msg = _HKI( "Track too close to copper area" ); break; - case DRCE_PAD_NEAR_PAD: msg = _HKI( "Pads too close" ); break; - case DRCE_VIA_HOLE_BIGGER: msg = _HKI( "Via hole larger than diameter" ); break; - case DRCE_MICROVIA_TOO_MANY_LAYERS: msg = _HKI( "Micro via through too many layers" ); break; - case DRCE_MICROVIA_NOT_ALLOWED: msg = _HKI( "Micro via not allowed" ); break; - case DRCE_BURIED_VIA_NOT_ALLOWED: msg = _HKI( "Buried via not allowed" ); break; - case DRCE_DISABLED_LAYER_ITEM: msg = _HKI( "Item on a disabled layer" ); break; - case DRCE_ZONES_INTERSECT: msg = _HKI( "Copper areas intersect" ); break; - case DRCE_ZONES_TOO_CLOSE: msg = _HKI( "Copper areas too close" ); break; - case DRCE_ZONE_HAS_EMPTY_NET: msg = _HKI( "Copper zone net has no pads" ); break; - case DRCE_DANGLING_VIA: msg = _HKI( "Via is not connected" ); break; - case DRCE_DANGLING_TRACK: msg = _HKI( "Track has unconnected end" ); break; - case DRCE_HOLE_NEAR_PAD: msg = _HKI( "Hole too close to pad" ); break; - case DRCE_HOLE_NEAR_TRACK: msg = _HKI( "Hole too close to track" ); break; - case DRCE_TOO_SMALL_TRACK_WIDTH: msg = _HKI( "Track width too small" ); break; - case DRCE_TOO_LARGE_TRACK_WIDTH: msg = _HKI( "Track width too large" ); break; - case DRCE_TOO_SMALL_VIA: msg = _HKI( "Via size too small" ); break; - case DRCE_TOO_SMALL_VIA_ANNULUS: msg = _HKI( "Via annulus too small" ); break; - case DRCE_TOO_SMALL_MICROVIA: msg = _HKI( "Micro via size too small" ); break; - case DRCE_TOO_SMALL_VIA_DRILL: msg = _HKI( "Via drill too small" ); break; - case DRCE_TOO_SMALL_PAD_DRILL: msg = _HKI( "Pad drill too small" ); break; - case DRCE_TOO_SMALL_MICROVIA_DRILL: msg = _HKI( "Micro via drill too small" ); break; - case DRCE_DRILLED_HOLES_TOO_CLOSE: msg = _HKI( "Drilled holes too close together" ); break; - case DRCE_TRACK_NEAR_EDGE: msg = _HKI( "Track too close to board edge" ); break; - case DRCE_VIA_NEAR_EDGE: msg = _HKI( "Via too close to board edge" ); break; - case DRCE_PAD_NEAR_EDGE: msg = _HKI( "Pad too close to board edge" ); break; - case DRCE_INVALID_OUTLINE: msg = _HKI( "Board has malformed outline" ); break; - - case DRCE_NETCLASS_TRACKWIDTH: msg = _HKI( "NetClass Track Width too small" ); break; - case DRCE_NETCLASS_CLEARANCE: msg = _HKI( "NetClass Clearance too small" ); break; - case DRCE_NETCLASS_VIAANNULUS: msg = _HKI( "NetClass via annulus too small" ); break; - case DRCE_NETCLASS_VIASIZE: msg = _HKI( "NetClass Via Dia too small" ); break; - case DRCE_NETCLASS_VIADRILLSIZE: msg = _HKI( "NetClass Via Drill too small" ); break; - case DRCE_NETCLASS_uVIASIZE: msg = _HKI( "NetClass uVia Dia too small" ); break; - case DRCE_NETCLASS_uVIADRILLSIZE: msg = _HKI( "NetClass uVia Drill too small" ); break; - - case DRCE_VIA_INSIDE_KEEPOUT: msg = _HKI( "Via inside keepout area" ); break; - case DRCE_MICROVIA_INSIDE_KEEPOUT: msg = _HKI( "Micro via inside keepout area" ); break; - case DRCE_BBVIA_INSIDE_KEEPOUT: msg = _HKI( "Buried via inside keepout area" ); break; - case DRCE_TRACK_INSIDE_KEEPOUT: msg = _HKI( "Track inside keepout area" ); break; - case DRCE_PAD_INSIDE_KEEPOUT: msg = _HKI( "Pad inside keepout area" ); break; - case DRCE_FOOTPRINT_INSIDE_KEEPOUT: msg = _HKI( "Footprint inside keepout area" ); break; - case DRCE_HOLE_INSIDE_KEEPOUT: msg = _HKI( "Hole inside keepout area" ); break; - case DRCE_TEXT_INSIDE_KEEPOUT: msg = _HKI( "Text inside keepout area" ); break; - case DRCE_GRAPHICS_INSIDE_KEEPOUT: msg = _HKI( "Graphic inside keepout area" ); break; - - case DRCE_VIA_NEAR_COPPER: msg = _HKI( "Via too close to copper item" ); break; - case DRCE_TRACK_NEAR_COPPER: msg = _HKI( "Track too close to copper item" ); break; - case DRCE_PAD_NEAR_COPPER: msg = _HKI( "Pad too close to copper item" ); break; - - case DRCE_OVERLAPPING_FOOTPRINTS: msg = _HKI( "Courtyards overlap" ); break; - case DRCE_MISSING_COURTYARD: msg = _HKI( "Footprint has no courtyard defined" ); break; - case DRCE_MALFORMED_COURTYARD: msg = _HKI( "Footprint has malformed courtyard" ); break; - case DRCE_PTH_IN_COURTYARD: msg = _HKI( "PTH inside courtyard" ); break; - case DRCE_NPTH_IN_COURTYARD: msg = _HKI( "NPTH inside courtyard" ); break; - - case DRCE_DUPLICATE_FOOTPRINT: msg = _HKI( "Duplicate footprints" ); break; - case DRCE_MISSING_FOOTPRINT: msg = _HKI( "Missing footprint" ); break; - case DRCE_EXTRA_FOOTPRINT: msg = _HKI( "Extra footprint" ); break; - - case DRCE_UNRESOLVED_VARIABLE: msg = _HKI( "Unresolved text variable" ); break; + case DRCE_UNCONNECTED_ITEMS: return new DRC_ITEM( unconnectedItems ); + case DRCE_ALLOWED_ITEMS: return new DRC_ITEM( itemsNotAllowed ); + case DRCE_CLEARANCE: return new DRC_ITEM( clearance ); + case DRCE_TRACKS_CROSSING: return new DRC_ITEM( tracksCrossing ); + case DRCE_COPPER_EDGE_CLEARANCE: return new DRC_ITEM( copperEdgeClearance ); + case DRCE_ZONES_INTERSECT: return new DRC_ITEM( zonesIntersect ); + case DRCE_ZONE_HAS_EMPTY_NET: return new DRC_ITEM( zoneHasEmptyNet ); + case DRCE_DANGLING_VIA: return new DRC_ITEM( viaDangling ); + case DRCE_DANGLING_TRACK: return new DRC_ITEM( trackDangling ); + case DRCE_DRILLED_HOLES_TOO_CLOSE: return new DRC_ITEM( holeNearHole ); + case DRCE_TRACK_WIDTH: return new DRC_ITEM( trackWidth ); + case DRCE_TOO_SMALL_VIA: return new DRC_ITEM( viaTooSmall ); + case DRCE_VIA_ANNULUS: return new DRC_ITEM( viaAnnulus ); + case DRCE_TOO_SMALL_DRILL: return new DRC_ITEM( drillTooSmall ); + case DRCE_VIA_HOLE_BIGGER: return new DRC_ITEM( viaHoleLargerThanPad ); + case DRCE_PADSTACK: return new DRC_ITEM( padstack ); + case DRCE_TOO_SMALL_MICROVIA: return new DRC_ITEM( microviaTooSmall ); + case DRCE_TOO_SMALL_MICROVIA_DRILL: return new DRC_ITEM( microviaDrillTooSmall ); + case DRCE_KEEPOUT: return new DRC_ITEM( keepout ); + case DRCE_OVERLAPPING_FOOTPRINTS: return new DRC_ITEM( courtyardsOverlap ); + case DRCE_MISSING_COURTYARD: return new DRC_ITEM( missingCourtyard ); + case DRCE_MALFORMED_COURTYARD: return new DRC_ITEM( malformedCourtyard ); + case DRCE_PTH_IN_COURTYARD: return new DRC_ITEM( pthInsideCourtyard ); + case DRCE_NPTH_IN_COURTYARD: return new DRC_ITEM( npthInsideCourtyard ); + case DRCE_DISABLED_LAYER_ITEM: return new DRC_ITEM( itemOnDisabledLayer ); + case DRCE_INVALID_OUTLINE: return new DRC_ITEM( invalidOutline ); + case DRCE_MISSING_FOOTPRINT: return new DRC_ITEM( duplicateFootprints ); + case DRCE_DUPLICATE_FOOTPRINT: return new DRC_ITEM( missingFootprint ); + case DRCE_EXTRA_FOOTPRINT: return new DRC_ITEM( extraFootprint ); + case DRCE_UNRESOLVED_VARIABLE: return new DRC_ITEM( unresolvedVariable ); default: - wxFAIL_MSG( "Missing DRC error description" ); - msg = _HKI( "Unknown DRC violation" ); - break; + wxFAIL_MSG( "Unknown DRC error code" ); + return nullptr; + } +} + + +DRC_ITEM* DRC_ITEM::Create( const wxString& aErrorKey ) +{ + for( const RC_ITEM& item : allItemTypes ) + { + if( aErrorKey == item.GetSettingsKey() ) + return new DRC_ITEM( static_cast( item ) ); } - if( aTranslate ) - return wxGetTranslation( msg ); - else - return msg; + wxFAIL_MSG( "Unknown DRC settings key: " + aErrorKey ); + return nullptr; } @@ -156,7 +261,7 @@ wxString DRC_ITEM::ShowHtml( PCB_BASE_FRAME* aFrame ) const { BOARD_ITEM* mainItem = nullptr; BOARD_ITEM* auxItem = nullptr; - wxString msg = m_errorMessage.IsEmpty() ? GetErrorText( m_errorCode ) : m_errorMessage; + wxString msg = m_errorMessage.IsEmpty() ? GetErrorText() : m_errorMessage; wxString mainText; wxString auxText; diff --git a/pcbnew/drc/drc_item.h b/pcbnew/drc/drc_item.h index 3d106750f6..1a0d286649 100644 --- a/pcbnew/drc/drc_item.h +++ b/pcbnew/drc/drc_item.h @@ -32,22 +32,72 @@ class PCB_BASE_FRAME; class DRC_ITEM : public RC_ITEM { public: - DRC_ITEM( int aErrorCode ); - - DRC_ITEM( const wxString& aErrorText ); - /** - * Function GetErrorText - * returns the string form of a drc error code. + * Constructs a DRC_ITEM for the given error code + * @see DRCE_T */ - wxString GetErrorText( int aErrorCode = -1, bool aTranslate = true ) const override; + static DRC_ITEM* Create( int aErrorCode ); /** - * Function ShowHtml - * translates this object into a fragment of HTML suitable for the wxHtmlListBox class. + * Constructs a DRC item from a given error settings key + * @param aErrorKey is a settings key for an error code (the untranslated string that is used + * to represent a given error code in settings files and for storing ignored DRC items) + * @return the created item + */ + static DRC_ITEM* Create( const wxString& aErrorKey ); + + static std::vector> GetItemsWithSeverities() + { + return allItemTypes; + } + + /** + * Translates this object into a fragment of HTML suitable for the wxHtmlListBox class. * @return wxString - the html text. */ wxString ShowHtml( PCB_BASE_FRAME* aFrame ) const; + +private: + DRC_ITEM( int aErrorCode = 0, const wxString& aTitle = "", const wxString& aSettingsKey = "" ) + { + m_errorCode = aErrorCode; + m_errorTitle = aTitle; + m_settingsKey = aSettingsKey; + } + + /// A list of all DRC_ITEM types which are valid error codes + static std::vector> allItemTypes; + + static DRC_ITEM unconnectedItems; + static DRC_ITEM itemsNotAllowed; + static DRC_ITEM clearance; + static DRC_ITEM tracksCrossing; + static DRC_ITEM copperEdgeClearance; + static DRC_ITEM zonesIntersect; + static DRC_ITEM zoneHasEmptyNet; + static DRC_ITEM viaDangling; + static DRC_ITEM trackDangling; + static DRC_ITEM holeNearHole; + static DRC_ITEM trackWidth; + static DRC_ITEM viaTooSmall; + static DRC_ITEM viaAnnulus; + static DRC_ITEM drillTooSmall; + static DRC_ITEM viaHoleLargerThanPad; + static DRC_ITEM padstack; + static DRC_ITEM microviaTooSmall; + static DRC_ITEM microviaDrillTooSmall; + static DRC_ITEM keepout; + static DRC_ITEM courtyardsOverlap; + static DRC_ITEM missingCourtyard; + static DRC_ITEM malformedCourtyard; + static DRC_ITEM pthInsideCourtyard; + static DRC_ITEM npthInsideCourtyard; + static DRC_ITEM itemOnDisabledLayer; + static DRC_ITEM invalidOutline; + static DRC_ITEM duplicateFootprints; + static DRC_ITEM missingFootprint; + static DRC_ITEM extraFootprint; + static DRC_ITEM unresolvedVariable; }; diff --git a/pcbnew/drc/drc_keepout_tester.cpp b/pcbnew/drc/drc_keepout_tester.cpp index b6d3e9548e..87b5d5d45b 100644 --- a/pcbnew/drc/drc_keepout_tester.cpp +++ b/pcbnew/drc/drc_keepout_tester.cpp @@ -96,10 +96,10 @@ bool DRC_KEEPOUT_TESTER::checkTracksAndVias() if( center2center_squared <= SEG::Square( widths) ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TRACK_INSIDE_KEEPOUT ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_KEEPOUT ); m_msg.Printf( drcItem->GetErrorText() + _( " (%s)" ), - m_sources.at(DISALLOW_TRACKS ) ); + m_sources.at( DISALLOW_TRACKS ) ); drcItem->SetErrorMessage( m_msg ); drcItem->SetItems( segm, m_zone ); @@ -110,30 +110,25 @@ bool DRC_KEEPOUT_TESTER::checkTracksAndVias() } else if( segm->Type() == PCB_VIA_T && ( m_keepoutFlags & CHECK_VIAS_MASK ) != 0 ) { - VIA* via = static_cast( segm ); - int errorCode = 0; + VIA* via = static_cast( segm ); int sourceId = 0; if( ( m_keepoutFlags & DISALLOW_VIAS ) > 0 ) { - errorCode = DRCE_VIA_INSIDE_KEEPOUT; sourceId = DISALLOW_VIAS; } else if( via->GetViaType() == VIATYPE::MICROVIA && ( m_keepoutFlags & DISALLOW_MICRO_VIAS ) > 0 ) { - errorCode = DRCE_MICROVIA_INSIDE_KEEPOUT; sourceId = DISALLOW_MICRO_VIAS; } else if( via->GetViaType() == VIATYPE::BLIND_BURIED && ( m_keepoutFlags & DISALLOW_BB_VIAS ) > 0 ) { - errorCode = DRCE_BBVIA_INSIDE_KEEPOUT; sourceId = DISALLOW_BB_VIAS; } else if( ( m_keepoutFlags & DISALLOW_HOLES ) > 0 ) { - errorCode = DRCE_HOLE_INSIDE_KEEPOUT; sourceId = DISALLOW_HOLES; } else @@ -142,14 +137,14 @@ bool DRC_KEEPOUT_TESTER::checkTracksAndVias() int widths = via->GetWidth() / 2; wxPoint viaPos = via->GetPosition(); - if( errorCode == DRCE_HOLE_INSIDE_KEEPOUT ) + if( sourceId == DISALLOW_HOLES ) widths = via->GetDrillValue() / 2; SEG::ecoord center2center_squared = m_zone->Outline()->SquaredDistance( viaPos ); if( center2center_squared <= SEG::Square( widths ) ) { - DRC_ITEM* drcItem = new DRC_ITEM( errorCode ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_KEEPOUT ); m_msg.Printf( drcItem->GetErrorText() + _( " (%s)" ), m_sources.at( sourceId ) ); drcItem->SetErrorMessage( m_msg ); drcItem->SetItems( segm, m_zone ); @@ -198,7 +193,7 @@ bool DRC_KEEPOUT_TESTER::checkFootprints() if( poly.OutlineCount() ) { const VECTOR2I& pt = poly.CVertex( 0, 0, -1 ); - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_FOOTPRINT_INSIDE_KEEPOUT ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_KEEPOUT ); m_msg.Printf( drcItem->GetErrorText() + _( " (%s)" ), m_sources.at( DISALLOW_FOOTPRINTS ) ); @@ -249,7 +244,7 @@ bool DRC_KEEPOUT_TESTER::checkPads( MODULE* aModule ) if( outline.OutlineCount() ) { const VECTOR2I& pt = outline.CVertex( 0, 0, -1 ); - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_PAD_INSIDE_KEEPOUT ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_KEEPOUT ); m_msg.Printf( drcItem->GetErrorText() + _( " (%s)" ), m_sources.at( DISALLOW_PADS ) ); @@ -276,7 +271,7 @@ bool DRC_KEEPOUT_TESTER::checkPads( MODULE* aModule ) if( center2center_sq <= SEG::Square( slotWidth) ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_HOLE_INSIDE_KEEPOUT ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_KEEPOUT ); m_msg.Printf( drcItem->GetErrorText() + _( " (%s)" ), m_sources.at( DISALLOW_HOLES ) ); @@ -309,19 +304,12 @@ bool DRC_KEEPOUT_TESTER::checkDrawings() if( !m_zoneBBox.Intersects( drawing->GetBoundingBox() ) ) continue; - int errorCode = 0; int sourceId = 0; if( drawing->IsType( graphicTypes ) && ( m_keepoutFlags & DISALLOW_GRAPHICS ) > 0 ) - { - errorCode = DRCE_GRAPHICS_INSIDE_KEEPOUT; sourceId = DISALLOW_GRAPHICS; - } else if( drawing->Type() == PCB_TEXT_T && ( m_keepoutFlags & DISALLOW_TEXTS ) > 0 ) - { - errorCode = DRCE_TEXT_INSIDE_KEEPOUT; sourceId = DISALLOW_TEXTS; - } else continue; @@ -335,7 +323,7 @@ bool DRC_KEEPOUT_TESTER::checkDrawings() if( poly.OutlineCount() ) { const VECTOR2I& pt = poly.CVertex( 0, 0, -1 ); - DRC_ITEM* drcItem = new DRC_ITEM( errorCode ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_KEEPOUT ); m_msg.Printf( drcItem->GetErrorText() + _( " (%s)" ), m_sources.at( sourceId ) ); drcItem->SetErrorMessage( m_msg ); drcItem->SetItems( drawing, m_zone ); diff --git a/pcbnew/drc/drc_netclass_tester.cpp b/pcbnew/drc/drc_netclass_tester.cpp index e3f5eacfb3..49242c96dd 100644 --- a/pcbnew/drc/drc_netclass_tester.cpp +++ b/pcbnew/drc/drc_netclass_tester.cpp @@ -52,111 +52,32 @@ bool DRC_NETCLASS_TESTER::RunDRC( EDA_UNITS aUnits, BOARD& aBoard ) bool DRC_NETCLASS_TESTER::checkNetClass( const NETCLASSPTR& nc ) { - bool ret = true; - const BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings(); if( nc->GetClearance() < bds.m_MinClearance ) - { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_NETCLASS_CLEARANCE ); - - m_msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; %s netclass %s)" ), - MessageTextFromValue( m_units, bds.m_MinClearance, true ), - nc->GetName(), - MessageTextFromValue( m_units, nc->GetClearance(), true ) ); - - drcItem->SetErrorMessage( m_msg ); - HandleMarker( new MARKER_PCB( drcItem, wxPoint() ) ); - ret = false; - } + return false; if( nc->GetTrackWidth() < bds.m_TrackMinWidth ) - { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_NETCLASS_TRACKWIDTH ); - - m_msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; %s netclass %s)" ), - MessageTextFromValue( m_units, bds.m_TrackMinWidth, true ), - nc->GetName(), - MessageTextFromValue( m_units, nc->GetTrackWidth(), true ) ); - - drcItem->SetErrorMessage( m_msg ); - HandleMarker( new MARKER_PCB( drcItem, wxPoint() ) ); - ret = false; - } + return false; if( nc->GetViaDiameter() < bds.m_ViasMinSize ) - { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_NETCLASS_VIASIZE ); - - m_msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; %s netclass %s)" ), - MessageTextFromValue( m_units, bds.m_ViasMinSize, true ), - nc->GetName(), - MessageTextFromValue( m_units, nc->GetViaDiameter(), true ) ); - - drcItem->SetErrorMessage( m_msg ); - HandleMarker( new MARKER_PCB( drcItem, wxPoint() ) ); - ret = false; - } + return false; if( nc->GetViaDrill() < bds.m_MinThroughDrill ) - { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_NETCLASS_VIADRILLSIZE ); - - m_msg.Printf( drcItem->GetErrorText() + _( " (board min through hole %s; %s netclass %s)" ), - MessageTextFromValue( m_units, bds.m_MinThroughDrill, true ), - nc->GetName(), - MessageTextFromValue( m_units, nc->GetViaDrill(), true ) ); - - drcItem->SetErrorMessage( m_msg ); - HandleMarker( new MARKER_PCB( drcItem, wxPoint() ) ); - ret = false; - } + return false; int ncViaAnnulus = ( nc->GetViaDiameter() - nc->GetViaDrill() ) / 2; if( ncViaAnnulus < bds.m_ViasMinAnnulus ) - { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_NETCLASS_VIAANNULUS ); - - m_msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; %s netclass %s)" ), - MessageTextFromValue( m_units, bds.m_ViasMinAnnulus, true ), - nc->GetName(), - MessageTextFromValue( m_units, ncViaAnnulus, true ) ); - - drcItem->SetErrorMessage( m_msg ); - HandleMarker( new MARKER_PCB( drcItem, wxPoint() ) ); - ret = false; - } + return false; if( nc->GetuViaDiameter() < bds.m_MicroViasMinSize ) - { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_NETCLASS_uVIASIZE ); - - m_msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; %s netclass %s)" ), - MessageTextFromValue( m_units, bds.m_MicroViasMinSize, true ), - nc->GetName(), - MessageTextFromValue( m_units, nc->GetuViaDiameter(), true ) ); - - drcItem->SetErrorMessage( m_msg ); - HandleMarker( new MARKER_PCB( drcItem, wxPoint() ) ); - ret = false; - } + return false; if( nc->GetuViaDrill() < bds.m_MicroViasMinDrill ) - { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_NETCLASS_uVIADRILLSIZE ); + return false; - m_msg.Printf( drcItem->GetErrorText() + _( " (board minimum %s; %s netclass %s)" ), - MessageTextFromValue( m_units, bds.m_MicroViasMinDrill, true ), - nc->GetName(), - MessageTextFromValue( m_units, nc->GetuViaDrill(), true ) ); - - drcItem->SetErrorMessage( m_msg ); - HandleMarker( new MARKER_PCB( drcItem, wxPoint() ) ); - ret = false; - } - - return ret; + return true; } diff --git a/pcbnew/drc/drc_textvar_tester.cpp b/pcbnew/drc/drc_textvar_tester.cpp index c845f299b8..8412bdaab3 100644 --- a/pcbnew/drc/drc_textvar_tester.cpp +++ b/pcbnew/drc/drc_textvar_tester.cpp @@ -57,7 +57,7 @@ bool DRC_TEXTVAR_TESTER::RunDRC( EDA_UNITS aUnits, BOARD& aBoard ) if( text->GetShownText().Matches( wxT( "*${*}*" ) ) ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_UNRESOLVED_VARIABLE ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_UNRESOLVED_VARIABLE ); drcItem->SetItems( text ); HandleMarker( new MARKER_PCB( drcItem, text->GetPosition() ) ); @@ -75,7 +75,7 @@ bool DRC_TEXTVAR_TESTER::RunDRC( EDA_UNITS aUnits, BOARD& aBoard ) if( text->GetShownText().Matches( wxT( "*${*}*" ) ) ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_UNRESOLVED_VARIABLE ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_UNRESOLVED_VARIABLE ); drcItem->SetItems( text ); HandleMarker( new MARKER_PCB( drcItem, text->GetPosition() ) ); @@ -98,7 +98,7 @@ bool DRC_TEXTVAR_TESTER::RunDRC( EDA_UNITS aUnits, BOARD& aBoard ) { if( text->GetShownText().Matches( wxT( "*${*}*" ) ) ) { - DRC_ITEM* drcItem = new DRC_ITEM( DRCE_UNRESOLVED_VARIABLE ); + DRC_ITEM* drcItem = DRC_ITEM::Create( DRCE_UNRESOLVED_VARIABLE ); drcItem->SetErrorMessage( _( "Unresolved text variable in worksheet." ) ); HandleMarker( new MARKER_PCB( drcItem, text->GetPosition() ) ); diff --git a/pcbnew/drc/footprint_tester.cpp b/pcbnew/drc/footprint_tester.cpp index 14a2f70193..dc5b663d83 100644 --- a/pcbnew/drc/footprint_tester.cpp +++ b/pcbnew/drc/footprint_tester.cpp @@ -44,7 +44,7 @@ void TestFootprints( NETLIST& aNetlist, BOARD* aBoard, std::vector& a if( !ins.second ) { - DRC_ITEM* item = new DRC_ITEM( DRCE_DUPLICATE_FOOTPRINT ); + DRC_ITEM* item = DRC_ITEM::Create( DRCE_DUPLICATE_FOOTPRINT ); item->SetItems( mod, *ins.first ); aDRCList.push_back( item ); } @@ -65,7 +65,7 @@ void TestFootprints( NETLIST& aNetlist, BOARD* aBoard, std::vector& a component->GetReference(), component->GetValue() ); - DRC_ITEM* item = new DRC_ITEM( DRCE_MISSING_FOOTPRINT ); + DRC_ITEM* item = DRC_ITEM::Create( DRCE_MISSING_FOOTPRINT ); item->SetErrorMessage( msg ); aDRCList.push_back( item ); } @@ -81,7 +81,7 @@ void TestFootprints( NETLIST& aNetlist, BOARD* aBoard, std::vector& a if( component == NULL ) { - DRC_ITEM* item = new DRC_ITEM( DRCE_EXTRA_FOOTPRINT ); + DRC_ITEM* item = DRC_ITEM::Create( DRCE_EXTRA_FOOTPRINT ); item->SetItems( module ); aDRCList.push_back( item ); } diff --git a/pcbnew/pcbnew_config.cpp b/pcbnew/pcbnew_config.cpp index 30160ca175..5d7f7b3fd3 100644 --- a/pcbnew/pcbnew_config.cpp +++ b/pcbnew/pcbnew_config.cpp @@ -80,7 +80,7 @@ bool PCB_EDIT_FRAME::LoadProjectSettings() PROJECT_FILE& project = Prj().GetProjectFile(); - BASE_SCREEN::m_PageLayoutDescrFileName = project.m_PageLayoutDescrFile; + BASE_SCREEN::m_PageLayoutDescrFileName = project.m_BoardPageLayoutDescrFile; // Load the page layout decr file, from the filename stored in // BASE_SCREEN::m_PageLayoutDescrFileName, read in config project file @@ -111,7 +111,7 @@ void PCB_EDIT_FRAME::SaveProjectSettings() PROJECT_FILE& project = Prj().GetProjectFile(); // TODO: Can this be pulled out of BASE_SCREEN? - project.m_PageLayoutDescrFile = BASE_SCREEN::m_PageLayoutDescrFileName; + project.m_BoardPageLayoutDescrFile = BASE_SCREEN::m_PageLayoutDescrFileName; RecordDRCExclusions(); diff --git a/qa/eeschema/sim/test_netlist_exporter_pspice_sim.cpp b/qa/eeschema/sim/test_netlist_exporter_pspice_sim.cpp index 675c05b95d..09be8172d8 100644 --- a/qa/eeschema/sim/test_netlist_exporter_pspice_sim.cpp +++ b/qa/eeschema/sim/test_netlist_exporter_pspice_sim.cpp @@ -35,19 +35,21 @@ // Code under test #include #include +#include #include class TEST_NETLIST_EXPORTER_PSPICE_SIM { public: TEST_NETLIST_EXPORTER_PSPICE_SIM() : - m_project(), - m_schematic( &m_project ), + m_schematic( nullptr ), m_exporter( &m_schematic ) { + m_manager.LoadProject( "" ); + m_schematic.SetProject( &m_manager.Prj() ); } - PROJECT m_project; + SETTINGS_MANAGER m_manager; SCHEMATIC m_schematic; diff --git a/qa/eeschema/test_netlists.cpp b/qa/eeschema/test_netlists.cpp index a47abd8783..81db2b5588 100644 --- a/qa/eeschema/test_netlists.cpp +++ b/qa/eeschema/test_netlists.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include @@ -35,7 +36,7 @@ class TEST_NETLISTS_FIXTURE { public: TEST_NETLISTS_FIXTURE() : - m_schematic( &m_project ) + m_schematic( nullptr ) { m_pi = SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ); } @@ -55,10 +56,9 @@ public: ///> Schematic to load SCHEMATIC m_schematic; - ///> Dummy project - PROJECT m_project; - SCH_PLUGIN* m_pi; + + SETTINGS_MANAGER m_manager; }; @@ -83,11 +83,12 @@ void TEST_NETLISTS_FIXTURE::loadSchematic( const wxString& aBaseName ) wxFileName pro( fn ); pro.SetExt( ProjectFileExtension ); - // TODO(JE) Make this not required - m_project.setProjectFullName( pro.GetFullPath() ); - m_project.SetElem( PROJECT::ELEM_SCH_PART_LIBS, nullptr ); + m_manager.LoadProject( pro.GetFullPath() ); + + m_manager.Prj().SetElem( PROJECT::ELEM_SCH_PART_LIBS, nullptr ); m_schematic.Reset(); + m_schematic.SetProject( &m_manager.Prj() ); m_schematic.SetRoot( m_pi->Load( fn, &m_schematic ) ); BOOST_REQUIRE_EQUAL( m_pi->GetError().IsEmpty(), true );