7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-20 14:01:41 +00:00

Migrate PcbNew project settings to new framework

Various architecture upgrades to support this.
Creating a BOARD now requires a valid PROJECT, which caused
some (mostly transparent) changes to the Python API internals.

ADDED: Project local settings file
CHANGED: Board design settings are no longer stored in PCB file
CHANGED: Net classes are no longer stored in PCB file
CHANGED: Importing board settings now reads boards, not just projects

Fixes https://gitlab.com/kicad/code/kicad/-/issues/2578
Fixes https://gitlab.com/kicad/code/kicad/-/issues/4070
This commit is contained in:
Jon Evans 2020-05-31 17:42:04 -04:00
parent 0e2f9cb1bd
commit c0aa6965de
87 changed files with 2415 additions and 1933 deletions
3d-viewer/3d_canvas
common
cvpcb
eeschema
include
kicad
pcbnew
qa

View File

@ -188,8 +188,7 @@ bool BOARD_ADAPTER::Is3DLayerEnabled( PCB_LAYER_ID aLayer ) const
case B_Cu:
case F_Cu:
return m_board->GetDesignSettings().IsLayerVisible( aLayer ) ||
GetFlag( FL_USE_REALISTIC_MODE );
return m_board->IsLayerVisible( aLayer ) || GetFlag( FL_USE_REALISTIC_MODE );
break;
default:
@ -201,7 +200,7 @@ bool BOARD_ADAPTER::Is3DLayerEnabled( PCB_LAYER_ID aLayer ) const
return false;
}
return m_board->GetDesignSettings().IsLayerVisible( aLayer );
return m_board->IsLayerVisible( aLayer );
}
// The layer has a flag, return the flag

View File

@ -317,8 +317,10 @@ set( COMMON_SRCS
lib_tree_model.cpp
lib_tree_model_adapter.cpp
lockfile.cpp
lset.cpp
marker_base.cpp
msgpanel.cpp
netclass.cpp
observable.cpp
prependpath.cpp
printout.cpp
@ -398,9 +400,12 @@ set( COMMON_SRCS
settings/common_settings.cpp
settings/json_settings.cpp
settings/nested_settings.cpp
settings/project_file.cpp
settings/settings_manager.cpp
project/net_settings.cpp
project/project_file.cpp
project/project_local_settings.cpp
libeval/numeric_evaluator.cpp
)
@ -438,7 +443,6 @@ set( PCB_COMMON_SRCS
eda_text.cpp
fp_lib_table.cpp
hash_eda.cpp
lset.cpp
origin_viewitem.cpp
page_info.cpp
${CMAKE_SOURCE_DIR}/pcbnew/pcb_base_frame.cpp
@ -453,7 +457,6 @@ set( PCB_COMMON_SRCS
${CMAKE_SOURCE_DIR}/pcbnew/class_edge_mod.cpp
${CMAKE_SOURCE_DIR}/pcbnew/class_marker_pcb.cpp
${CMAKE_SOURCE_DIR}/pcbnew/class_module.cpp
${CMAKE_SOURCE_DIR}/pcbnew/netclass.cpp
${CMAKE_SOURCE_DIR}/pcbnew/netinfo_item.cpp
${CMAKE_SOURCE_DIR}/pcbnew/netinfo_list.cpp
${CMAKE_SOURCE_DIR}/pcbnew/class_pad.cpp

View File

@ -24,6 +24,7 @@
#include <kiface_i.h>
#include <config_params.h>
#include <lib_tree_model_adapter.h>
#include <project/project_file.h>
#include <settings/app_settings.h>
#include <wx/tokenzr.h>
#include <wx/wupdlock.h>
@ -73,7 +74,7 @@ unsigned int LIB_TREE_MODEL_ADAPTER::IntoArray( LIB_TREE_NODE const& aNode,
}
LIB_TREE_MODEL_ADAPTER::LIB_TREE_MODEL_ADAPTER( EDA_BASE_FRAME* aParent ) :
LIB_TREE_MODEL_ADAPTER::LIB_TREE_MODEL_ADAPTER( EDA_BASE_FRAME* aParent, wxString aPinnedKey ) :
m_parent( aParent ),
m_filter( CMP_FILTER_NONE ),
m_show_units( true ),
@ -81,7 +82,9 @@ LIB_TREE_MODEL_ADAPTER::LIB_TREE_MODEL_ADAPTER( EDA_BASE_FRAME* aParent ) :
m_freeze( 0 ),
m_col_part( nullptr ),
m_col_desc( nullptr ),
m_widget( nullptr )
m_widget( nullptr ),
m_pinnedLibs(),
m_pinnedKey( aPinnedKey )
{
// Default column widths
m_colWidths[PART_COL] = 360;
@ -90,12 +93,15 @@ LIB_TREE_MODEL_ADAPTER::LIB_TREE_MODEL_ADAPTER( EDA_BASE_FRAME* aParent ) :
auto cfg = Kiface().KifaceSettings();
m_colWidths[PART_COL] = cfg->m_LibTree.column_width;
// TODO(JE) PROJECT
#if 0
// Read the pinned entries from the project config
m_parent->Kiway().Prj().ConfigLoad( Kiface().KifaceSearch(), m_parent->GetName(),
GetProjectFileParameters() );
#endif
PROJECT_FILE& project = m_parent->Kiway().Prj().GetProjectFile();
std::vector<wxString>& entries = ( m_pinnedKey == "pinned_symbol_libs" ) ?
project.m_PinnedSymbolLibs :
project.m_PinnedFootprintLibs;
for( const wxString& entry : entries )
m_pinnedLibs.push_back( entry );
}
@ -117,32 +123,27 @@ void LIB_TREE_MODEL_ADAPTER::SaveColWidths()
}
std::vector<PARAM_CFG*>& LIB_TREE_MODEL_ADAPTER::GetProjectFileParameters()
{
if( !m_projectFileParams.empty() )
return m_projectFileParams;
m_projectFileParams.push_back( new PARAM_CFG_LIBNAME_LIST( PINNED_ITEMS_KEY, &m_pinnedLibs ) );
return m_projectFileParams;
}
void LIB_TREE_MODEL_ADAPTER::SavePinnedItems()
{
PROJECT_FILE& project = m_parent->Kiway().Prj().GetProjectFile();
std::vector<wxString>& entries = ( m_pinnedKey == "pinned_symbol_libs" ) ?
project.m_PinnedSymbolLibs :
project.m_PinnedFootprintLibs;
entries.clear();
m_pinnedLibs.clear();
for( auto& child: m_tree.m_Children )
{
if( child->m_Pinned )
{
m_pinnedLibs.push_back( child->m_LibId.GetLibNickname() );
entries.push_back( child->m_LibId.GetLibNickname() );
}
}
// TODO(JE) PROJECT
#if 0
m_parent->Kiway().Prj().ConfigSave( Kiface().KifaceSearch(), m_parent->GetName(),
GetProjectFileParameters() );
#endif
}

View File

@ -136,8 +136,6 @@ public:
void SaveColWidths();
void SavePinnedItems();
std::vector<PARAM_CFG*>& GetProjectFileParameters();
/**
* Set the component filter type. Must be set before adding libraries
*
@ -282,7 +280,12 @@ protected:
LIB_TREE_NODE_ROOT m_tree;
LIB_TREE_MODEL_ADAPTER( EDA_BASE_FRAME* aParent );
/**
* Creates the adapter
* @param aParent is the parent frame
* @param aPinnedKey is the key to load the pinned libraries list from the project file
*/
LIB_TREE_MODEL_ADAPTER( EDA_BASE_FRAME* aParent, wxString aPinnedKey );
LIB_TREE_NODE_LIB& DoAddLibraryNode( wxString const& aNodeName, wxString const& aDesc );
@ -368,6 +371,7 @@ private:
int m_colWidths[NUM_COLS];
wxArrayString m_pinnedLibs;
wxString m_pinnedKey;
/**
* Find any results worth highlighting and expand them, according to given criteria

View File

@ -24,15 +24,16 @@
*/
#include <fctsys.h>
#include <common.h>
#include <kicad_string.h>
#include <pcbnew.h>
#include <richio.h>
#include <macros.h>
#include <class_board.h>
#include <netclass.h>
#ifndef PCBNEW
#define PCBNEW // needed to define the right value of Millimeter2iu(x)
#endif
#include <base_units.h>
// This will get mapped to "kicad_default" in the specctra_export.
const char NETCLASS::Default[] = "Default";
@ -152,84 +153,6 @@ NETCLASSPTR NETCLASSES::Find( const wxString& aName ) const
}
void BOARD::SynchronizeNetsAndNetClasses()
{
NETCLASSES& netClasses = m_designSettings.m_NetClasses;
NETCLASSPTR defaultNetClass = netClasses.GetDefault();
// set all NETs to the default NETCLASS, then later override some
// as we go through the NETCLASSes.
for( NETINFO_LIST::iterator net( m_NetInfo.begin() ), netEnd( m_NetInfo.end() );
net != netEnd; ++net )
{
net->SetClass( defaultNetClass );
}
// Add netclass name and pointer to nets. If a net is in more than one netclass,
// set the net's name and pointer to only the first netclass. Subsequent
// and therefore bogus netclass memberships will be deleted in logic below this loop.
for( NETCLASSES::iterator clazz = netClasses.begin(); clazz != netClasses.end(); ++clazz )
{
NETCLASSPTR netclass = clazz->second;
for( NETCLASS::const_iterator member = netclass->begin(); member != netclass->end(); ++member )
{
const wxString& netname = *member;
// although this overall function seems to be adequately fast,
// FindNet( wxString ) uses now a fast binary search and is fast
// event for large net lists
NETINFO_ITEM* net = FindNet( netname );
if( net && net->GetClassName() == NETCLASS::Default )
{
net->SetClass( netclass );
}
}
}
// Finally, make sure that every NET is in a NETCLASS, even if that
// means the Default NETCLASS. And make sure that all NETCLASSes do not
// contain netnames that do not exist, by deleting all netnames from
// every netclass and re-adding them.
for( NETCLASSES::iterator clazz = netClasses.begin(); clazz != netClasses.end(); ++clazz )
{
NETCLASSPTR netclass = clazz->second;
netclass->Clear();
}
defaultNetClass->Clear();
for( NETINFO_LIST::iterator net( m_NetInfo.begin() ), netEnd( m_NetInfo.end() );
net != netEnd; ++net )
{
const wxString& classname = net->GetClassName();
// because of the std:map<> this should be fast, and because of
// prior logic, netclass should not be NULL.
NETCLASSPTR netclass = netClasses.Find( classname );
wxASSERT( netclass );
netclass->Add( net->GetNetname() );
}
// Set initial values for custom track width & via size to match the default netclass settings
m_designSettings.UseCustomTrackViaSize( false );
m_designSettings.SetCustomTrackWidth( defaultNetClass->GetTrackWidth() );
m_designSettings.SetCustomViaSize( defaultNetClass->GetViaDiameter() );
m_designSettings.SetCustomViaDrill( defaultNetClass->GetViaDrill() );
m_designSettings.SetCustomDiffPairWidth( defaultNetClass->GetDiffPairWidth() );
m_designSettings.SetCustomDiffPairGap( defaultNetClass->GetDiffPairGap() );
m_designSettings.SetCustomDiffPairViaGap( defaultNetClass->GetDiffPairViaGap() );
InvokeListeners( &BOARD_LISTENER::OnBoardNetSettingsChanged, *this );
}
#if defined(DEBUG)
void NETCLASS::Show( int nestLevel, std::ostream& os ) const
@ -250,38 +173,3 @@ void NETCLASS::Show( int nestLevel, std::ostream& os ) const
}
#endif
void NETCLASS::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const
{
aFormatter->Print( aNestLevel, "(net_class %s %s\n",
aFormatter->Quotew( GetName() ).c_str(),
aFormatter->Quotew( GetDescription() ).c_str() );
aFormatter->Print( aNestLevel+1, "(clearance %s)\n", FormatInternalUnits( GetClearance() ).c_str() );
aFormatter->Print( aNestLevel+1, "(trace_width %s)\n", FormatInternalUnits( GetTrackWidth() ).c_str() );
aFormatter->Print( aNestLevel+1, "(via_dia %s)\n", FormatInternalUnits( GetViaDiameter() ).c_str() );
aFormatter->Print( aNestLevel+1, "(via_drill %s)\n", FormatInternalUnits( GetViaDrill() ).c_str() );
aFormatter->Print( aNestLevel+1, "(uvia_dia %s)\n", FormatInternalUnits( GetuViaDiameter() ).c_str() );
aFormatter->Print( aNestLevel+1, "(uvia_drill %s)\n", FormatInternalUnits( GetuViaDrill() ).c_str() );
// Save the diff_pair_gap and diff_pair_width values only if not the default, to avoid unnecessary
// incompatibility with previous Pcbnew versions.
if( ( DEFAULT_DIFF_PAIR_WIDTH != GetDiffPairWidth() ) ||
( DEFAULT_DIFF_PAIR_GAP != GetDiffPairGap() ) )
{
aFormatter->Print( aNestLevel+1, "(diff_pair_width %s)\n",
FormatInternalUnits( GetDiffPairWidth() ).c_str() );
aFormatter->Print( aNestLevel+1, "(diff_pair_gap %s)\n",
FormatInternalUnits( GetDiffPairGap() ).c_str() );
// 6.0 TODO: figure out what to do with DiffPairViaGap...
}
for( NETCLASS::const_iterator it = begin(); it != end(); ++it )
aFormatter->Print( aNestLevel+1, "(add_net %s)\n", aFormatter->Quotew( *it ).c_str() );
aFormatter->Print( aNestLevel, ")\n\n" );
}

View File

@ -23,20 +23,20 @@
#include <wx/stdpaths.h>
#include <common.h> // NAMELESS_PROJECT
#include <config_params.h>
#include <confirm.h>
#include <fctsys.h>
#include <fp_lib_table.h>
#include <kicad_string.h>
#include <kiface_ids.h>
#include <kiway.h>
#include <macros.h>
#include <pgm_base.h>
#include <project.h>
#include <common.h> // NAMELESS_PROJECT
#include <confirm.h>
#include <kicad_string.h>
#include <config_params.h>
#include <wildcards_and_files_ext.h>
#include <fp_lib_table.h>
#include <kiway.h>
#include <kiface_ids.h>
#include <project/project_file.h>
#include <trace_helpers.h>
#include <settings/project_file.h>
#include <wildcards_and_files_ext.h>
PROJECT::PROJECT() :

View File

@ -0,0 +1,142 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 CERN
* @author Jon Evans <jon@craftyjon.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <project/net_settings.h>
#include <settings/parameters.h>
// Netclasses were originally only stored in board files. The IU context is PCBNEW.
#ifndef PCBNEW
#define PCBNEW
#endif
#include <base_units.h>
const int netSettingsSchemaVersion = 0;
NET_SETTINGS::NET_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) :
NESTED_SETTINGS( "net_settings", netSettingsSchemaVersion, aParent, aPath ),
m_NetClasses()
{
m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "classes",
[&]() -> nlohmann::json
{
nlohmann::json ret = nlohmann::json::array();
NETCLASSPTR netclass = m_NetClasses.GetDefault();
NETCLASSES::const_iterator nc = m_NetClasses.begin();
for( unsigned int idx = 0; idx <= m_NetClasses.GetCount(); idx++ )
{
if( idx > 0 )
{
netclass = nc->second;
++nc;
}
nlohmann::json netJson = {
{ "name", netclass->GetName().ToUTF8() },
{ "clearance", Iu2Millimeter( netclass->GetClearance() ) },
{ "track_width", Iu2Millimeter( netclass->GetTrackWidth() ) },
{ "via_diameter", Iu2Millimeter( netclass->GetViaDiameter() ) },
{ "via_drill", Iu2Millimeter( netclass->GetViaDrill() ) },
{ "microvia_diameter", Iu2Millimeter( netclass->GetuViaDiameter() ) },
{ "microvia_drill", Iu2Millimeter( netclass->GetuViaDrill() ) },
{ "diff_pair_width", Iu2Millimeter( netclass->GetDiffPairWidth() ) },
{ "diff_pair_gap", Iu2Millimeter( netclass->GetDiffPairGap() ) },
{ "diff_pair_via_gap", Iu2Millimeter( netclass->GetDiffPairViaGap() ) }
};
nlohmann::json nets = nlohmann::json::array();
for( NETCLASS::const_iterator i = netclass->begin(); i != netclass->end(); ++i )
if( !i->empty() )
nets.push_back( std::string( i->ToUTF8() ) );
netJson["nets"] = nets;
ret.push_back( netJson );
}
return ret;
},
[&]( const nlohmann::json& aJson )
{
if( !aJson.is_array() )
return;
m_NetClasses.Clear();
NETCLASSPTR netclass;
NETCLASSPTR defaultClass = m_NetClasses.GetDefault();
auto get =
[]( const nlohmann::json& aObj, const std::string& aKey, int aDefault )
{
if( aObj.contains( aKey ) )
return Millimeter2iu( aObj[aKey].get<double>() );
else
return aDefault;
};
for( const nlohmann::json& entry : aJson )
{
if( !entry.is_object() || !entry.contains( "name" ) )
continue;
wxString name = entry["name"];
if( name == defaultClass->GetName() )
netclass = defaultClass;
else
netclass = std::make_shared<NETCLASS>( name );
netclass->SetClearance( get( aJson, "clearance", netclass->GetClearance() ) );
netclass->SetTrackWidth(
get( aJson, "track_width", netclass->GetTrackWidth() ) );
netclass->SetViaDiameter(
get( aJson, "via_diameter", netclass->GetViaDiameter() ) );
netclass->SetViaDrill( get( aJson, "via_drill", netclass->GetViaDrill() ) );
netclass->SetuViaDiameter(
get( aJson, "microvia_diameter", netclass->GetuViaDiameter() ) );
netclass->SetuViaDrill(
get( aJson, "microvia_drill", netclass->GetuViaDrill() ) );
netclass->SetDiffPairWidth(
get( aJson, "diff_pair_width", netclass->GetDiffPairWidth() ) );
netclass->SetDiffPairGap(
get( aJson, "diff_pair_gap", netclass->GetDiffPairGap() ) );
netclass->SetDiffPairViaGap(
get( aJson, "diff_pair_via_gap", netclass->GetDiffPairViaGap() ) );
if( netclass != defaultClass )
m_NetClasses.Add( netclass );
}
}, {} ) );
}
NET_SETTINGS::~NET_SETTINGS()
{
// Release early before destroying members
if( m_parent )
{
m_parent->ReleaseNestedSettings( this );
m_parent = nullptr;
}
}

View File

@ -0,0 +1,478 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 CERN
* @author Jon Evans <jon@craftyjon.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <config_params.h>
#include <project.h>
#include <project/net_settings.h>
#include <project/project_file.h>
#include <settings/common_settings.h>
#include <settings/parameters.h>
#include <wildcards_and_files_ext.h>
#include <wx/config.h>
#include <wx/log.h>
extern const char* traceSettings;
///! Update the schema version whenever a migration is required
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()
{
// Keep old files around
m_deleteLegacyAfterMigration = false;
m_params.emplace_back( new PARAM_LIST<FILE_INFO_PAIR>( "sheets", &m_sheets, {} ) );
m_params.emplace_back( new PARAM_LIST<FILE_INFO_PAIR>( "boards", &m_boards, {} ) );
m_params.emplace_back(
new PARAM_LIST<wxString>( "libraries.pinned_symbol_libs", &m_PinnedSymbolLibs, {} ) );
m_params.emplace_back( new PARAM_LIST<wxString>(
"libraries.pinned_footprint_libs", &m_PinnedFootprintLibs, {} ) );
m_params.emplace_back(
new PARAM_PATH_LIST( "cvpcb.equivalence_files", &m_EquivalenceFiles, {} ) );
m_params.emplace_back(
new PARAM_PATH( "pcbnew.page_layout_descr_file", &m_PageLayoutDescrFile, "" ) );
m_params.emplace_back(
new PARAM_PATH( "pcbnew.last_paths.netlist", &m_PcbLastPath[LAST_PATH_NETLIST], "" ) );
m_params.emplace_back(
new PARAM_PATH( "pcbnew.last_paths.step", &m_PcbLastPath[LAST_PATH_STEP], "" ) );
m_params.emplace_back(
new PARAM_PATH( "pcbnew.last_paths.idf", &m_PcbLastPath[LAST_PATH_IDF], "" ) );
m_params.emplace_back(
new PARAM_PATH( "pcbnew.last_paths.vmrl", &m_PcbLastPath[LAST_PATH_VRML], "" ) );
m_params.emplace_back( new PARAM_PATH(
"pcbnew.last_paths.specctra_dsn", &m_PcbLastPath[LAST_PATH_SPECCTRADSN], "" ) );
m_params.emplace_back(
new PARAM_PATH( "pcbnew.last_paths.gencad", &m_PcbLastPath[LAST_PATH_GENCAD], "" ) );
m_NetSettings = std::make_shared<NET_SETTINGS>( this, "net_settings" );
}
bool PROJECT_FILE::MigrateFromLegacy( wxConfigBase* aCfg )
{
bool ret = true;
wxString str;
long index = 0;
std::set<wxString> group_blacklist;
// Legacy files don't store board info; they assume board matches project name
// We will leave m_boards empty here so it can be populated with other code
// First handle migration of data that will be stored locally in this object
auto loadPinnedLibs =
[&]( const std::string& aDest )
{
int libIndex = 1;
wxString libKey = wxT( "PinnedItems" );
libKey << libIndex;
nlohmann::json libs = nlohmann::json::array();
while( aCfg->Read( libKey, &str ) )
{
libs.push_back( str );
aCfg->DeleteEntry( libKey, true );
libKey = wxT( "PinnedItems" );
libKey << ++libIndex;
}
( *this )[PointerFromString( aDest )] = libs;
};
aCfg->SetPath( wxT( "/LibeditFrame" ) );
loadPinnedLibs( "libraries.pinned_symbol_libs" );
aCfg->SetPath( wxT( "/ModEditFrame" ) );
loadPinnedLibs( "libraries.pinned_footprint_libs" );
aCfg->SetPath( wxT( "/cvpcb/equfiles" ) );
{
int eqIdx = 1;
wxString eqKey = wxT( "EquName" );
eqKey << eqIdx;
nlohmann::json eqs = nlohmann::json::array();
while( aCfg->Read( eqKey, &str ) )
{
eqs.push_back( str );
eqKey = wxT( "EquName" );
eqKey << ++eqIdx;
}
( *this )[PointerFromString( "cvpcb.equivalence_files" )] = eqs;
}
// All CvPcb params that we want to keep have been migrated above
group_blacklist.insert( wxT( "/cvpcb" ) );
aCfg->SetPath( wxT( "/pcbnew" ) );
fromLegacyString( aCfg, "PageLayoutDescrFile", "pcbnew.page_layout_descr_file" );
fromLegacyString( aCfg, "LastNetListRead", "pcbnew.last_paths.netlist" );
fromLegacyString( aCfg, "LastSTEPExportPath", "pcbnew.last_paths.step" );
fromLegacyString( aCfg, "LastIDFExportPath", "pcbnew.last_paths.idf" );
fromLegacyString( aCfg, "LastVRMLExportPath", "pcbnew.last_paths.vmrl" );
fromLegacyString( aCfg, "LastSpecctraDSNExportPath", "pcbnew.last_paths.specctra_dsn" );
fromLegacyString( aCfg, "LastGenCADExportPath", "pcbnew.last_paths.gencad" );
std::string bp = "board.design_settings.";
{
int idx = 1;
wxString key = wxT( "DRCExclusion" );
key << idx;
nlohmann::json exclusions = nlohmann::json::array();
while( aCfg->Read( key, &str ) )
{
exclusions.push_back( str );
key = wxT( "DRCExclusion" );
key << ++idx;
}
( *this )[PointerFromString( bp + "drc_exclusions" )] = exclusions;
}
fromLegacy<bool>( aCfg, "AllowMicroVias", bp + "rules.allow_microvias" );
fromLegacy<bool>( aCfg, "AllowBlindVias", bp + "rules.allow_blind_buried_vias" );
fromLegacy<double>( aCfg, "MinClearance", bp + "rules.min_clearance" );
fromLegacy<double>( aCfg, "MinTrackWidth", bp + "rules.min_track_width" );
fromLegacy<double>( aCfg, "MinViaAnnulus", bp + "rules.min_via_annulus" );
fromLegacy<double>( aCfg, "MinViaDiameter", bp + "rules.min_via_diameter" );
if( !fromLegacy<double>( aCfg, "MinThroughDrill", bp + "rules.min_through_hole_diameter" ) )
fromLegacy<double>( aCfg, "MinViaDrill", bp + "rules.min_through_hole_diameter" );
fromLegacy<double>( aCfg, "MinMicroViaDiameter", bp + "rules.min_microvia_diameter" );
fromLegacy<double>( aCfg, "MinMicroViaDrill", bp + "rules.min_microvia_drill" );
fromLegacy<double>( aCfg, "MinHoleToHole", bp + "rules.min_hole_to_hole" );
fromLegacy<double>( aCfg, "CopperEdgeClearance", bp + "rules.min_copper_edge_clearance" );
fromLegacy<double>( aCfg, "SolderMaskClearance", bp + "rules.solder_mask_clearance" );
fromLegacy<double>( aCfg, "SolderMaskMinWidth", bp + "rules.solder_mask_min_width" );
fromLegacy<double>( aCfg, "SolderPasteClearance", bp + "rules.solder_paste_clearance" );
fromLegacy<double>( aCfg, "SolderPasteRatio", bp + "rules.solder_paste_margin_ratio" );
if( !fromLegacy<double>( aCfg, "SilkLineWidth", bp + "defaults.silk_line_width" ) )
fromLegacy<double>( aCfg, "ModuleOutlineThickness", bp + "defaults.silk_line_width" );
if( !fromLegacy<double>( aCfg, "SilkTextSizeV", bp + "defaults.silk_text_size_v" ) )
fromLegacy<double>( aCfg, "ModuleTextSizeV", bp + "defaults.silk_text_size_v" );
if( !fromLegacy<double>( aCfg, "SilkTextSizeH", bp + "defaults.silk_text_size_h" ) )
fromLegacy<double>( aCfg, "ModuleTextSizeH", bp + "defaults.silk_text_size_h" );
if( !fromLegacy<double>( aCfg, "SilkTextSizeThickness", bp + "defaults.silk_text_thickness" ) )
fromLegacy<double>( aCfg, "ModuleTextSizeThickness", bp + "defaults.silk_text_thickness" );
fromLegacy<bool>( aCfg, "SilkTextItalic", bp + "defaults.silk_text_italic" );
fromLegacy<bool>( aCfg, "SilkTextUpright", bp + "defaults.silk_text_upright" );
if( !fromLegacy<double>( aCfg, "CopperLineWidth", bp + "defaults.copper_line_width" ) )
fromLegacy<double>( aCfg, "DrawSegmentWidth", bp + "defaults.copper_line_width" );
if( !fromLegacy<double>( aCfg, "CopperTextSizeV", bp + "defaults.copper_text_size_v" ) )
fromLegacy<double>( aCfg, "PcbTextSizeV", bp + "defaults.copper_text_size_v" );
if( !fromLegacy<double>( aCfg, "CopperTextSizeH", bp + "defaults.copper_text_size_h" ) )
fromLegacy<double>( aCfg, "PcbTextSizeH", bp + "defaults.copper_text_size_h" );
if( !fromLegacy<double>( aCfg, "CopperTextThickness", bp + "defaults.copper_text_thickness" ) )
fromLegacy<double>( aCfg, "PcbTextThickness", bp + "defaults.copper_text_thickness" );
fromLegacy<bool>( aCfg, "CopperTextItalic", bp + "defaults.copper_text_italic" );
fromLegacy<bool>( aCfg, "CopperTextUpright", bp + "defaults.copper_text_upright" );
if( !fromLegacy<double>( aCfg, "EdgeCutLineWidth", bp + "defaults.board_outline_line_width" ) )
fromLegacy<double>(
aCfg, "BoardOutlineThickness", bp + "defaults.board_outline_line_width" );
fromLegacy<double>( aCfg, "CourtyardLineWidth", bp + "defaults.courtyard_line_width" );
fromLegacy<double>( aCfg, "FabLineWidth", bp + "defaults.fab_line_width" );
fromLegacy<double>( aCfg, "FabTextSizeV", bp + "defaults.fab_text_size_v" );
fromLegacy<double>( aCfg, "FabTextSizeH", bp + "defaults.fab_text_size_h" );
fromLegacy<double>( aCfg, "FabTextSizeThickness", bp + "defaults.fab_text_thickness" );
fromLegacy<bool>( aCfg, "FabTextItalic", bp + "defaults.fab_text_italic" );
fromLegacy<bool>( aCfg, "FabTextUpright", bp + "defaults.fab_text_upright" );
if( !fromLegacy<double>( aCfg, "OthersLineWidth", bp + "defaults.other_line_width" ) )
fromLegacy<double>( aCfg, "ModuleOutlineThickness", bp + "defaults.other_line_width" );
fromLegacy<double>( aCfg, "OthersTextSizeV", bp + "defaults.other_text_size_v" );
fromLegacy<double>( aCfg, "OthersTextSizeH", bp + "defaults.other_text_size_h" );
fromLegacy<double>( aCfg, "OthersTextSizeThickness", bp + "defaults.other_text_thickness" );
fromLegacy<bool>( aCfg, "OthersTextItalic", bp + "defaults.other_text_italic" );
fromLegacy<bool>( aCfg, "OthersTextUpright", bp + "defaults.other_text_upright" );
fromLegacy<int>( aCfg, "DimensionUnits", bp + "defaults.dimension_units" );
fromLegacy<int>( aCfg, "DimensionPrecision", bp + "defaults.dimension_precision" );
std::string sev = bp + "rule_severities";
fromLegacy<bool>(
aCfg, "RequireCourtyardDefinitions", sev + "legacy_no_courtyard_defined" );
fromLegacy<bool>( aCfg, "ProhibitOverlappingCourtyards", sev + "legacy_ourtyards_overlap" );
{
int idx = 1;
wxString keyBase = "TrackWidth";
wxString key = keyBase;
double val;
nlohmann::json widths = nlohmann::json::array();
key << idx;
while( aCfg->Read( key, &val ) )
{
widths.push_back( val );
key = keyBase;
key << ++idx;
}
( *this )[PointerFromString( bp + "track_widths" )] = widths;
}
{
int idx = 1;
wxString keyBase = "ViaDiameter";
wxString key = keyBase;
double diameter;
double drill = 1.0;
nlohmann::json vias = nlohmann::json::array();
key << idx;
while( aCfg->Read( key, &diameter ) )
{
key = "ViaDrill";
aCfg->Read( key << idx, &drill );
nlohmann::json via = { { "diameter", diameter }, { "drill", drill } };
vias.push_back( via );
key = keyBase;
key << ++idx;
}
( *this )[PointerFromString( bp + "via_dimensions" )] = vias;
}
{
int idx = 1;
wxString keyBase = "dPairWidth";
wxString key = keyBase;
double width;
double gap = 1.0;
double via_gap = 1.0;
nlohmann::json pairs = nlohmann::json::array();
key << idx;
while( aCfg->Read( key, &width ) )
{
key = "dPairGap";
aCfg->Read( key << idx, &gap );
key = "dPairViaGap";
aCfg->Read( key << idx, &via_gap );
nlohmann::json pair = { { "width", width }, { "gap", gap }, { "via_gap", via_gap } };
pairs.push_back( pair );
key = keyBase;
key << ++idx;
}
( *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!
// General group is unused these days, we can throw it away
group_blacklist.insert( wxT( "/general" ) );
// Next load sheet names and put all other legacy data in the legacy dict
aCfg->SetPath( wxT( "/" ) );
auto loadSheetNames =
[&]() -> bool
{
int sheet = 1;
wxString entry;
nlohmann::json arr = nlohmann::json::array();
wxLogTrace( traceSettings, "Migrating sheet names" );
aCfg->SetPath( wxT( "/sheetnames" ) );
while( aCfg->Read( wxString::Format( "%d", sheet++ ), &entry ) )
{
wxArrayString tokens = wxSplit( entry, ':' );
if( tokens.size() == 2 )
{
wxLogTrace( traceSettings, "%d: %s = %s", sheet, tokens[0], tokens[1] );
arr.push_back( nlohmann::json::array( { tokens[0], tokens[1] } ) );
}
}
( *this )[PointerFromString( "sheets" )] = arr;
aCfg->SetPath( "/" );
// TODO: any reason we want to fail on this?
return true;
};
std::vector<wxString> groups;
groups.emplace_back( "" );
auto loadLegacyPairs =
[&]( const std::string& aGroup ) -> bool
{
wxLogTrace( traceSettings, "Migrating group %s", aGroup );
bool success = true;
wxString keyStr;
wxString val;
index = 0;
while( aCfg->GetNextEntry( keyStr, index ) )
{
if( !aCfg->Read( keyStr, &val ) )
continue;
std::string key( keyStr.ToUTF8() );
wxLogTrace( traceSettings, " %s = %s", key, val );
try
{
nlohmann::json::json_pointer ptr( "/legacy" + aGroup + "/" + key );
( *this )[ptr] = val;
}
catch( ... )
{
success = false;
}
}
return success;
};
for( size_t i = 0; i < groups.size(); i++ )
{
aCfg->SetPath( groups[i] );
if( groups[i] == wxT( "/sheetnames" ) )
{
ret |= loadSheetNames();
continue;
}
aCfg->DeleteEntry( wxT( "last_client" ), true );
aCfg->DeleteEntry( wxT( "update" ), true );
aCfg->DeleteEntry( wxT( "version" ), true );
ret &= loadLegacyPairs( groups[i].ToStdString() );
index = 0;
while( aCfg->GetNextGroup( str, index ) )
{
wxString group = groups[i] + "/" + str;
if( !group_blacklist.count( group ) )
groups.emplace_back( group );
}
aCfg->SetPath( "/" );
}
return ret;
}
bool PROJECT_FILE::SaveToFile( const std::string& aDirectory, bool aForce )
{
wxASSERT( m_project );
( *this )[PointerFromString( "meta.filename" )] =
m_project->GetProjectName() + "." + ProjectFileExtension;
return JSON_SETTINGS::SaveToFile( aDirectory, aForce );
}
wxString PROJECT_FILE::getFileExt() const
{
return ProjectFileExtension;
}
wxString PROJECT_FILE::getLegacyFileExt() const
{
return LegacyProjectFileExtension;
}
void to_json( nlohmann::json& aJson, const FILE_INFO_PAIR& aPair )
{
aJson = nlohmann::json::array( { aPair.first.AsString().ToUTF8(), aPair.second.ToUTF8() } );
}
void from_json( const nlohmann::json& aJson, FILE_INFO_PAIR& aPair )
{
wxASSERT( aJson.is_array() && aJson.size() == 2 );
aPair.first = KIID( wxString( aJson[0].get<std::string>().c_str(), wxConvUTF8 ) );
aPair.second = wxString( aJson[1].get<std::string>().c_str(), wxConvUTF8 );
}

View File

@ -0,0 +1,105 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 CERN
* @author Jon Evans <jon@craftyjon.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <project.h>
#include <project/project_local_settings.h>
#include <settings/parameters.h>
const int projectLocalSettingsVersion = 1;
PROJECT_LOCAL_SETTINGS::PROJECT_LOCAL_SETTINGS( const std::string& aFilename ) :
JSON_SETTINGS( aFilename, SETTINGS_LOC::PROJECT, projectLocalSettingsVersion,
/* aCreateIfMissing = */ true, /* aCreateIfDefault = */ false,
/* aWriteFile = */ true ),
m_project( nullptr )
{
m_params.emplace_back( new PARAM_LAMBDA<std::string>( "board.visible_layers",
[&]() -> std::string
{
return m_VisibleLayers.FmtHex();
},
[&]( const std::string& aString )
{
m_VisibleLayers.ParseHex( aString.c_str(), aString.size() );
},
LSET::AllLayersMask().FmtHex() ) );
static GAL_SET defaultVisible;
defaultVisible.set().reset( GAL_LAYER_INDEX( LAYER_MOD_TEXT_INVISIBLE ) );
m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "board.visible_items",
[&]() -> nlohmann::json
{
nlohmann::json ret = nlohmann::json::array();
for( size_t i = 0; i < m_VisibleItems.size(); i++ )
if( m_VisibleItems.test( i ) )
ret.push_back( i );
return ret;
},
[&]( const nlohmann::json& aVal )
{
if( !aVal.is_array() || aVal.empty() )
{
m_VisibleItems = defaultVisible;
return;
}
m_VisibleItems.reset();
for( const nlohmann::json& entry : aVal )
{
try
{
int i = entry.get<int>();
m_VisibleItems.set( i );
}
catch( ... )
{
// Non-integer or out of range entry in the array; ignore
}
}
},
{} ) );
}
bool PROJECT_LOCAL_SETTINGS::MigrateFromLegacy( wxConfigBase* aLegacyConfig )
{
/**
* The normal legacy migration code won't be used for this because the only legacy
* information stored here was stored in board files, so we do that migration when loading
* the board.
*/
return true;
}
bool PROJECT_LOCAL_SETTINGS::SaveToFile( const std::string& aDirectory, bool aForce )
{
wxASSERT( m_project );
( *this )[PointerFromString( "meta.filename" )] =
m_project->GetProjectName() + "." + ProjectLocalSettingsFileExtension;
return JSON_SETTINGS::SaveToFile( aDirectory, aForce );
}

View File

@ -46,11 +46,11 @@ JSON_SETTINGS::JSON_SETTINGS( const std::string& aFilename, SETTINGS_LOC aLocati
m_createIfDefault( aCreateIfDefault ),
m_writeFile( aWriteFile ),
m_deleteLegacyAfterMigration( true ),
m_resetParamsIfMissing( true ),
m_schemaVersion( aSchemaVersion ),
m_manager( nullptr )
{
m_params.emplace_back(
new PARAM<std::string>( "meta.filename", &m_filename, m_filename, true ) );
( *this )[PointerFromString( "meta.filename" )] = GetFullFilename();
m_params.emplace_back(
new PARAM<int>( "meta.version", &m_schemaVersion, m_schemaVersion, true ) );
@ -66,13 +66,19 @@ JSON_SETTINGS::~JSON_SETTINGS()
}
wxString JSON_SETTINGS::GetFullFilename() const
{
return wxString( m_filename.c_str(), wxConvUTF8 ) + "." + getFileExt();
}
void JSON_SETTINGS::Load()
{
for( auto param : m_params )
{
try
{
param->Load( this );
param->Load( this, m_resetParamsIfMissing );
}
catch( ... )
{
@ -106,7 +112,8 @@ bool JSON_SETTINGS::LoadFromFile( const std::string& aDirectory )
if( !wxCopyFile( aPath.GetFullPath(), temp.GetFullPath() ) )
{
wxLogTrace( traceSettings, "%s: could not create temp file for migration", m_filename );
wxLogTrace( traceSettings, "%s: could not create temp file for migration",
GetFullFilename() );
backed_up = false;
}
@ -118,11 +125,12 @@ bool JSON_SETTINGS::LoadFromFile( const std::string& aDirectory )
if( !MigrateFromLegacy( cfg.get() ) )
{
wxLogTrace( traceSettings,
"%s: migrated; not all settings were found in legacy file", m_filename );
"%s: migrated; not all settings were found in legacy file",
GetFullFilename() );
}
else
{
wxLogTrace( traceSettings, "%s: migrated from legacy format", m_filename );
wxLogTrace( traceSettings, "%s: migrated from legacy format", GetFullFilename() );
}
if( backed_up )
@ -186,14 +194,15 @@ bool JSON_SETTINGS::LoadFromFile( const std::string& aDirectory )
}
catch( ... )
{
wxLogTrace( traceSettings, "%s: file version could not be read!", m_filename );
wxLogTrace(
traceSettings, "%s: file version could not be read!", GetFullFilename() );
success = false;
}
if( filever >= 0 && filever < m_schemaVersion )
{
wxLogTrace( traceSettings, "%s: attempting migration from version %d to %d",
m_filename, filever, m_schemaVersion );
GetFullFilename(), filever, m_schemaVersion );
if( Migrate() )
{
@ -201,13 +210,13 @@ bool JSON_SETTINGS::LoadFromFile( const std::string& aDirectory )
}
else
{
wxLogTrace( traceSettings, "%s: migration failed!", m_filename );
wxLogTrace( traceSettings, "%s: migration failed!", GetFullFilename() );
}
}
else if( filever > m_schemaVersion )
{
wxLogTrace( traceSettings,
"%s: warning: file version %d is newer than latest (%d)", m_filename,
"%s: warning: file version %d is newer than latest (%d)", GetFullFilename(),
filever, m_schemaVersion );
}
}
@ -227,7 +236,7 @@ bool JSON_SETTINGS::LoadFromFile( const std::string& aDirectory )
for( auto settings : m_nested_settings )
settings->LoadFromFile();
wxLogTrace( traceSettings, "Loaded %s with schema %d", GetFilename(), m_schemaVersion );
wxLogTrace( traceSettings, "Loaded %s with schema %d", GetFullFilename(), m_schemaVersion );
// If we migrated, clean up the legacy file (with no extension)
if( legacy_migrated || migrated )
@ -292,7 +301,7 @@ bool JSON_SETTINGS::SaveToFile( const std::string& aDirectory, bool aForce )
{
wxLogTrace( traceSettings,
"File for %s doesn't exist and m_createIfMissing == false; not saving",
m_filename );
GetFullFilename() );
return false;
}
@ -305,27 +314,25 @@ bool JSON_SETTINGS::SaveToFile( const std::string& aDirectory, bool aForce )
if( !modified && !aForce && path.FileExists() )
{
wxLogTrace( traceSettings, "%s contents not modified, skipping save", m_filename );
wxLogTrace( traceSettings, "%s contents not modified, skipping save", GetFullFilename() );
return false;
}
else if( !modified && !aForce && !m_createIfDefault )
{
wxLogTrace( traceSettings,
"%s contents still default and m_createIfDefault == false; not saving",
m_filename );
GetFullFilename() );
return false;
}
wxLogTrace( traceSettings, "Saving %s", m_filename );
if( !path.DirExists() && !path.Mkdir() )
{
wxLogTrace( traceSettings, "Warning: could not create path %s, can't save %s",
path.GetPath(), m_filename );
path.GetPath(), GetFullFilename() );
return false;
}
wxLogTrace( traceSettings, "Saving %s", m_filename );
wxLogTrace( traceSettings, "Saving %s", GetFullFilename() );
LOCALE_IO dummy;
@ -336,7 +343,7 @@ bool JSON_SETTINGS::SaveToFile( const std::string& aDirectory, bool aForce )
}
catch( const std::exception& e )
{
wxLogTrace( traceSettings, "Warning: could not save %s: %s", m_filename, e.what() );
wxLogTrace( traceSettings, "Warning: could not save %s: %s", GetFullFilename(), e.what() );
}
catch( ... )
{
@ -346,9 +353,9 @@ bool JSON_SETTINGS::SaveToFile( const std::string& aDirectory, bool aForce )
}
OPT<nlohmann::json> JSON_SETTINGS::GetJson( std::string aPath ) const
OPT<nlohmann::json> JSON_SETTINGS::GetJson( const std::string& aPath ) const
{
nlohmann::json::json_pointer ptr = PointerFromString( std::move( aPath ) );
nlohmann::json::json_pointer ptr = PointerFromString( aPath );
if( this->contains( ptr ) )
{
@ -498,6 +505,9 @@ void JSON_SETTINGS::AddNestedSettings( NESTED_SETTINGS* aSettings )
void JSON_SETTINGS::ReleaseNestedSettings( NESTED_SETTINGS* aSettings )
{
if( !aSettings )
return;
auto it = std::find_if( m_nested_settings.begin(), m_nested_settings.end(),
[&aSettings]( const JSON_SETTINGS* aPtr ) {
return aPtr == aSettings;
@ -509,21 +519,23 @@ void JSON_SETTINGS::ReleaseNestedSettings( NESTED_SETTINGS* aSettings )
( *it )->SaveToFile();
m_nested_settings.erase( it );
}
aSettings->SetParent( nullptr );
}
// Specializations to allow conversion between wxString and std::string via JSON_SETTINGS API
template<> OPT<wxString> JSON_SETTINGS::Get( std::string aPath ) const
template<> OPT<wxString> JSON_SETTINGS::Get( const std::string& aPath ) const
{
if( OPT<nlohmann::json> opt_json = GetJson( std::move( aPath ) ) )
if( OPT<nlohmann::json> opt_json = GetJson( aPath ) )
return wxString( opt_json->get<std::string>().c_str(), wxConvUTF8 );
return NULLOPT;
}
template<> void JSON_SETTINGS::Set<wxString>( std::string aPath, wxString aVal )
template<> void JSON_SETTINGS::Set<wxString>( const std::string& aPath, wxString aVal )
{
( *this )[PointerFromString( std::move( aPath ) ) ] = aVal.ToUTF8();
}

View File

@ -30,19 +30,14 @@ NESTED_SETTINGS::NESTED_SETTINGS( const std::string& aName, int aVersion, JSON_S
JSON_SETTINGS( aName, SETTINGS_LOC::NESTED, aVersion ),
m_parent( aParent ), m_path( aPath )
{
if( m_parent )
{
m_parent->AddNestedSettings( this );
}
// In case we were created after the parent's ctor
LoadFromFile();
SetParent( aParent );
}
NESTED_SETTINGS::~NESTED_SETTINGS()
{
m_parent->ReleaseNestedSettings( this );
if( m_parent )
m_parent->ReleaseNestedSettings( this );
}
@ -77,6 +72,9 @@ bool NESTED_SETTINGS::LoadFromFile( const std::string& aDirectory )
bool NESTED_SETTINGS::SaveToFile( const std::string& aDirectory, bool aForce )
{
if( !m_parent )
return false;
bool modified = Store();
try
@ -108,3 +106,15 @@ bool NESTED_SETTINGS::SaveToFile( const std::string& aDirectory, bool aForce )
return modified;
}
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();
}

View File

@ -1,247 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 CERN
* @author Jon Evans <jon@craftyjon.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <config_params.h>
#include <settings/common_settings.h>
#include <settings/parameters.h>
#include <settings/project_file.h>
#include <wildcards_and_files_ext.h>
#include <wx/config.h>
#include <wx/log.h>
extern const char* traceSettings;
///! Update the schema version whenever a migration is required
const int projectFileSchemaVersion = 1;
PROJECT_FILE::PROJECT_FILE( const std::string& aFullPath ) :
JSON_SETTINGS( aFullPath, SETTINGS_LOC::NONE, projectFileSchemaVersion ),
m_sheets(), m_boards()
{
// Keep old files around
m_deleteLegacyAfterMigration = false;
m_params.emplace_back( new PARAM_LIST<FILE_INFO_PAIR>( "sheets", &m_sheets, {} ) );
m_params.emplace_back( new PARAM_LIST<FILE_INFO_PAIR>( "boards", &m_boards, {} ) );
m_params.emplace_back(
new PARAM_LIST<wxString>( "libraries.pinned_symbol_libs", &m_PinnedSymbolLibs, {} ) );
m_params.emplace_back( new PARAM_LIST<wxString>(
"libraries.pinned_footprint_libs", &m_PinnedFootprintLibs, {} ) );
m_params.emplace_back(
new PARAM_PATH_LIST( "cvpcb.equivalence_files", &m_EquivalenceFiles, {} ) );
}
bool PROJECT_FILE::MigrateFromLegacy( wxConfigBase* aLegacyFile )
{
bool ret = true;
wxString str;
long index = 0;
std::set<wxString> group_blacklist;
// Legacy files don't store board info; they assume board matches project name
// We will leave m_boards empty here so it can be populated with other code
// First handle migration of data that will be stored locally in this object
auto loadPinnedLibs =
[&]( const std::string& aDest )
{
int libIndex = 1;
wxString libKey = wxT( "PinnedItems" );
libKey << libIndex;
nlohmann::json libs = nlohmann::json::array();
while( aLegacyFile->Read( libKey, &str ) )
{
libs.push_back( str );
aLegacyFile->DeleteEntry( libKey, true );
libKey = wxT( "PinnedItems" );
libKey << ++libIndex;
}
( *this )[PointerFromString( aDest )] = libs;
};
aLegacyFile->SetPath( wxT( "/LibeditFrame" ) );
loadPinnedLibs( "libraries.pinned_symbol_libs" );
aLegacyFile->SetPath( wxT( "/ModEditFrame" ) );
loadPinnedLibs( "libraries.pinned_footprint_libs" );
aLegacyFile->SetPath( wxT( "/cvpcb/equfiles" ) );
{
int eqIdx = 1;
wxString eqKey = wxT( "EquName" );
eqKey << eqIdx;
nlohmann::json eqs = nlohmann::json::array();
while( aLegacyFile->Read( eqKey, &str ) )
{
eqs.push_back( str );
eqKey = wxT( "EquName" );
eqKey << ++eqIdx;
}
( *this )[PointerFromString( "cvpcb.equivalence_files" )] = eqs;
}
// No other cvpcb params are currently used
group_blacklist.insert( "/cvpcb" );
// Next load sheet names and put all other legacy data in the legacy dict
aLegacyFile->SetPath( "/" );
auto loadSheetNames =
[&]() -> bool
{
int sheet = 1;
wxString entry;
nlohmann::json arr = nlohmann::json::array();
wxLogTrace( traceSettings, "Migrating sheet names" );
aLegacyFile->SetPath( wxT( "/sheetnames" ) );
while( aLegacyFile->Read( wxString::Format( "%d", sheet++ ), &entry ) )
{
wxArrayString tokens = wxSplit( entry, ':' );
if( tokens.size() == 2 )
{
wxLogTrace( traceSettings, "%d: %s = %s", sheet, tokens[0], tokens[1] );
arr.push_back( nlohmann::json::array( { tokens[0], tokens[1] } ) );
}
}
( *this )[PointerFromString( "sheets" )] = arr;
aLegacyFile->SetPath( "/" );
// TODO: any reason we want to fail on this?
return true;
};
std::vector<wxString> groups;
groups.emplace_back( "" );
auto loadLegacyPairs =
[&]( const std::string& aGroup ) -> bool
{
wxLogTrace( traceSettings, "Migrating group %s", aGroup );
bool success = true;
wxString keyStr;
wxString val;
index = 0;
while( aLegacyFile->GetNextEntry( keyStr, index ) )
{
if( !aLegacyFile->Read( keyStr, &val ) )
continue;
std::string key( keyStr.ToUTF8() );
wxLogTrace( traceSettings, " %s = %s", key, val );
try
{
nlohmann::json::json_pointer ptr( "/legacy" + aGroup + "/" + key );
( *this )[ptr] = val;
}
catch( ... )
{
success = false;
}
}
return success;
};
for( size_t i = 0; i < groups.size(); i++ )
{
aLegacyFile->SetPath( groups[i] );
if( groups[i] == wxT( "/sheetnames" ) )
{
ret |= loadSheetNames();
continue;
}
aLegacyFile->DeleteEntry( wxT( "last_client" ), true );
aLegacyFile->DeleteEntry( wxT( "update" ), true );
aLegacyFile->DeleteEntry( wxT( "version" ), true );
ret &= loadLegacyPairs( groups[i].ToStdString() );
index = 0;
while( aLegacyFile->GetNextGroup( str, index ) )
{
wxString group = groups[i] + "/" + str;
if( !group_blacklist.count( group ) )
groups.emplace_back( group );
}
aLegacyFile->SetPath( "/" );
}
return ret;
}
wxString PROJECT_FILE::getFileExt() const
{
return ProjectFileExtension;
}
wxString PROJECT_FILE::getLegacyFileExt() const
{
return LegacyProjectFileExtension;
}
void to_json( nlohmann::json& aJson, const FILE_INFO_PAIR& aPair )
{
aJson = nlohmann::json::array( { aPair.first.AsString().ToUTF8(), aPair.second.ToUTF8() } );
}
void from_json( const nlohmann::json& aJson, FILE_INFO_PAIR& aPair )
{
wxASSERT( aJson.is_array() && aJson.size() == 2 );
aPair.first = KIID( wxString( aJson[0].get<std::string>().c_str(), wxConvUTF8 ) );
aPair.second = wxString( aJson[1].get<std::string>().c_str(), wxConvUTF8 );
}

View File

@ -30,10 +30,11 @@
#include <gestfich.h>
#include <macros.h>
#include <project.h>
#include <project/project_file.h>
#include <project/project_local_settings.h>
#include <settings/app_settings.h>
#include <settings/color_settings.h>
#include <settings/common_settings.h>
#include <settings/project_file.h>
#include <settings/settings_manager.h>
#include <wildcards_and_files_ext.h>
@ -46,7 +47,7 @@ const char* traceSettings = "SETTINGS";
/// Project settings path will be <projectname> + this
#define PROJECT_SETTINGS_DIR_SUFFIX wxT( "-settings" )
#define PROJECT_BACKUPS_DIR_SUFFIX wxT( "-backups" )
SETTINGS_MANAGER::SETTINGS_MANAGER() :
@ -83,7 +84,7 @@ JSON_SETTINGS* SETTINGS_MANAGER::RegisterSettings( JSON_SETTINGS* aSettings, boo
ptr->SetManager( this );
wxLogTrace( traceSettings, "Registered new settings object %s", ptr->GetFilename() );
wxLogTrace( traceSettings, "Registered new settings object %s", ptr->GetFullFilename() );
if( aLoadNow )
ptr->LoadFromFile( GetPathForSettingsFile( ptr.get() ) );
@ -139,13 +140,13 @@ void SETTINGS_MANAGER::Save( JSON_SETTINGS* aSettings )
if( it != m_settings.end() )
{
wxLogTrace( traceSettings, "Saving %s", ( *it )->GetFilename() );
wxLogTrace( traceSettings, "Saving %s", ( *it )->GetFullFilename() );
( *it )->SaveToFile( GetPathForSettingsFile( it->get() ) );
}
}
void SETTINGS_MANAGER::FlushAndRelease( JSON_SETTINGS* aSettings )
void SETTINGS_MANAGER::FlushAndRelease( JSON_SETTINGS* aSettings, bool aSave )
{
auto it = std::find_if( m_settings.begin(), m_settings.end(),
[&aSettings]( const std::unique_ptr<JSON_SETTINGS>& aPtr )
@ -155,8 +156,11 @@ void SETTINGS_MANAGER::FlushAndRelease( JSON_SETTINGS* aSettings )
if( it != m_settings.end() )
{
wxLogTrace( traceSettings, "Flush and release %s", ( *it )->GetFilename() );
( *it )->SaveToFile( GetPathForSettingsFile( it->get() ) );
wxLogTrace( traceSettings, "Flush and release %s", ( *it )->GetFullFilename() );
if( aSave )
( *it )->SaveToFile( GetPathForSettingsFile( it->get() ) );
m_settings.erase( it );
}
}
@ -332,8 +336,7 @@ std::string SETTINGS_MANAGER::GetPathForSettingsFile( JSON_SETTINGS* aSettings )
return GetUserSettingsPath();
case SETTINGS_LOC::PROJECT:
// TODO(JE)
return "";
return std::string( Prj().GetProjectPath().ToUTF8() );
case SETTINGS_LOC::COLORS:
return GetColorSettingsPath();
@ -667,7 +670,7 @@ bool SETTINGS_MANAGER::extractVersion( const std::string& aVersionString, int* a
}
bool SETTINGS_MANAGER::LoadProject( const wxString& aFullPath )
bool SETTINGS_MANAGER::LoadProject( const wxString& aFullPath, bool aSetActive )
{
// Normalize path to new format even if migrating from a legacy file
wxFileName path( aFullPath );
@ -678,33 +681,45 @@ bool SETTINGS_MANAGER::LoadProject( const wxString& aFullPath )
wxString fullPath = path.GetFullPath();
// Unload if already loaded
if( m_projects.count( fullPath ) && !UnloadProject( *m_projects.at( fullPath ).get() ) )
if( m_projects.count( fullPath ) && !UnloadProject( m_projects.at( fullPath ).get() ) )
return false;
// No MDI yet
if( !m_projects.empty() && !UnloadProject( *m_projects.begin()->second ) )
if( aSetActive && !m_projects.empty() && !UnloadProject( m_projects.begin()->second.get() ) )
return false;
wxLogTrace( traceSettings, "Load project %s", fullPath );
m_projects[fullPath] = std::make_unique<PROJECT>();
m_projects[fullPath]->setProjectFullName( fullPath );
std::unique_ptr<PROJECT> project = std::make_unique<PROJECT>();
project->setProjectFullName( fullPath );
return loadProjectFile( *m_projects[fullPath] );
bool success = loadProjectFile( *project );
m_projects[fullPath].reset( project.release() );
std::string fn( path.GetName() );
PROJECT_LOCAL_SETTINGS* settings = static_cast<PROJECT_LOCAL_SETTINGS*>(
RegisterSettings( new PROJECT_LOCAL_SETTINGS( fn ) ) );
m_projects[fullPath]->setLocalSettings( settings );
settings->SetProject( m_projects[fullPath].get() );
return success;
}
bool SETTINGS_MANAGER::UnloadProject( PROJECT& aProject )
bool SETTINGS_MANAGER::UnloadProject( PROJECT* aProject, bool aSave )
{
if( !m_projects.count( aProject.GetProjectFullName() ) )
if( !aProject || !m_projects.count( aProject->GetProjectFullName() ) )
return false;
if( !unloadProjectFile( aProject ) )
if( !unloadProjectFile( aProject, aSave ) )
return false;
wxLogTrace( traceSettings, "Unload project %s", aProject.GetProjectFullName() );
wxLogTrace( traceSettings, "Unload project %s", aProject->GetProjectFullName() );
m_projects.erase( aProject.GetProjectFullName() );
m_projects.erase( aProject->GetProjectFullName() );
return true;
}
@ -712,34 +727,50 @@ bool SETTINGS_MANAGER::UnloadProject( PROJECT& aProject )
PROJECT& SETTINGS_MANAGER::Prj() const
{
// No MDI yet
wxASSERT( m_projects.size() == 1 );
// No MDI yet: First project in the list is the active project
return *m_projects.begin()->second;
}
bool SETTINGS_MANAGER::SaveProject()
PROJECT* SETTINGS_MANAGER::GetProject( const wxString& aFullPath ) const
{
wxString name = Prj().GetProjectFullName();
if( m_projects.count( aFullPath ) )
return m_projects.at( aFullPath ).get();
if( !m_project_files.count( name ) )
return nullptr;
}
bool SETTINGS_MANAGER::SaveProject( const wxString& aFullPath )
{
wxString path = aFullPath;
if( path.empty() )
path = Prj().GetProjectFullName();
if( !m_project_files.count( path ) )
return false;
m_project_files[name]->SaveToFile();
PROJECT_FILE* project = m_project_files.at( path );
std::string projectPath = GetPathForSettingsFile( project );
project->SaveToFile( projectPath );
Prj().GetLocalSettings().SaveToFile( projectPath );
return true;
}
wxString SETTINGS_MANAGER::GetProjectSettingsPath() const
wxString SETTINGS_MANAGER::GetProjectBackupsPath() const
{
return Prj().GetProjectPath() + Prj().GetProjectName() + PROJECT_SETTINGS_DIR_SUFFIX;
return Prj().GetProjectPath() + Prj().GetProjectName() + PROJECT_BACKUPS_DIR_SUFFIX;
}
bool SETTINGS_MANAGER::loadProjectFile( PROJECT& aProject )
{
std::string fn( aProject.GetProjectFullName().ToUTF8() );
wxFileName fullFn( aProject.GetProjectFullName() );
std::string fn( fullFn.GetName().ToUTF8() );
PROJECT_FILE* file =
static_cast<PROJECT_FILE*>( RegisterSettings( new PROJECT_FILE( fn ), false ) );
@ -747,14 +778,18 @@ bool SETTINGS_MANAGER::loadProjectFile( PROJECT& aProject )
m_project_files[aProject.GetProjectFullName()] = file;
aProject.setProjectFile( file );
file->SetProject( &aProject );
return file->LoadFromFile();
return file->LoadFromFile( std::string( fullFn.GetPath().ToUTF8() ) );
}
bool SETTINGS_MANAGER::unloadProjectFile( PROJECT& aProject )
bool SETTINGS_MANAGER::unloadProjectFile( PROJECT* aProject, bool aSave )
{
wxString name = aProject.GetProjectFullName();
if( !aProject )
return false;
wxString name = aProject->GetProjectFullName();
if( !m_project_files.count( name ) )
return false;
@ -769,7 +804,13 @@ bool SETTINGS_MANAGER::unloadProjectFile( PROJECT& aProject )
if( it != m_settings.end() )
{
( *it )->SaveToFile();
std::string projectPath = GetPathForSettingsFile( it->get() );
FlushAndRelease( &aProject->GetLocalSettings(), aSave );
if( aSave )
( *it )->SaveToFile( projectPath );
m_settings.erase( it );
}

View File

@ -122,6 +122,7 @@ const std::string VrmlFileExtension( "wrl" );
const std::string ProjectFileExtension( "kicad_pro" );
const std::string LegacyProjectFileExtension( "pro" );
const std::string ProjectLocalSettingsFileExtension( "kicad_prl" );
const std::string LegacySchematicFileExtension( "sch" );
const std::string KiCadSchematicFileExtension( "kicad_sch" );
const std::string NetlistFileExtension( "net" );

View File

@ -39,7 +39,7 @@
#include <cvpcb_association.h>
#include <cvpcb_mainframe.h>
#include <listboxes.h>
#include <settings/project_file.h>
#include <project/project_file.h>
#define QUOTE '\''

View File

@ -35,7 +35,7 @@
#include <cvpcb_mainframe.h>
#include <dialog_config_equfiles.h>
#include <settings/project_file.h>
#include <project/project_file.h>
#include <settings/settings_manager.h>
#include <wildcards_and_files_ext.h>

View File

@ -54,7 +54,7 @@
#include <connection_graph.h>
#include <tool/actions.h>
#include <tools/sch_editor_control.h>
#include <settings/project_file.h>
#include <project/project_file.h>
#include <settings/settings_manager.h>
#include <netlist.h>
#include <widgets/infobar.h>
@ -262,7 +262,7 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
return false;
wxFileName pro = fullFileName;
pro.SetExt( LegacyProjectFileExtension );
pro.SetExt( ProjectFileExtension );
bool is_new = !wxFileName::IsFileReadable( fullFileName );
@ -332,6 +332,8 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
Prj().SetElem( PROJECT::ELEM_SYMBOL_LIB_TABLE, NULL );
Prj().SchSymbolLibTable();
Schematic().SetProject( Prj() );
SetShutdownBlockReason( _( "Schematic file changes are unsaved" ) );
if( is_new )

View File

@ -43,7 +43,7 @@ SYMBOL_TREE_MODEL_ADAPTER::PTR SYMBOL_TREE_MODEL_ADAPTER::Create( EDA_BASE_FRAME
SYMBOL_TREE_MODEL_ADAPTER::SYMBOL_TREE_MODEL_ADAPTER( EDA_BASE_FRAME* aParent, LIB_TABLE* aLibs ) :
LIB_TREE_MODEL_ADAPTER( aParent ),
LIB_TREE_MODEL_ADAPTER( aParent, "pinned_symbol_libs" ),
m_libs( (SYMBOL_LIB_TABLE*) aLibs )
{}

View File

@ -39,7 +39,7 @@ LIB_TREE_MODEL_ADAPTER::PTR SYMBOL_TREE_SYNCHRONIZING_ADAPTER::Create( LIB_EDIT_
SYMBOL_TREE_SYNCHRONIZING_ADAPTER::SYMBOL_TREE_SYNCHRONIZING_ADAPTER( LIB_EDIT_FRAME* aParent,
LIB_MANAGER* aLibMgr ) :
LIB_TREE_MODEL_ADAPTER( aParent ),
LIB_TREE_MODEL_ADAPTER( aParent, "pinned_symbol_libs" ),
m_frame( aParent ),
m_libMgr( aLibMgr ),
m_lastSyncHash( -1 )

View File

@ -30,6 +30,9 @@
#include <config_params.h>
#include <board_stackup_manager/class_board_stackup.h>
#include <drc/drc_rule.h>
#include <settings/nested_settings.h>
#include <widgets/ui_common.h>
#include <zone_settings.h>
#define DEFAULT_SILK_LINE_WIDTH 0.12
@ -208,7 +211,7 @@ enum class VIATYPE : int;
* BOARD_DESIGN_SETTINGS
* contains design settings for a BOARD object.
*/
class BOARD_DESIGN_SETTINGS
class BOARD_DESIGN_SETTINGS : public NESTED_SETTINGS
{
public:
// Note: the first value in each dimensions list is the current netclass value
@ -217,7 +220,7 @@ public:
std::vector<DIFF_PAIR_DIMENSION> m_DiffPairDimensionsList;
// List of netclasses. There is always the default netclass.
NETCLASSES m_NetClasses;
//NETCLASSES m_NetClasses;
std::vector<DRC_SELECTOR*> m_DRCRuleSelectors;
std::vector<DRC_RULE*> m_DRCRules;
@ -242,6 +245,9 @@ public:
std::map< int, int > m_DRCSeverities; // Map from DRCErrorCode to SEVERITY
/// Excluded DRC items
std::set<wxString> m_DrcExclusions;
/** Option to handle filled polygons in zones:
* the "legacy" option is using thick outlines around filled polygons: give the best shape
* the "new" option is using only filled polygons (no outline: give the faster redraw time
@ -310,9 +316,7 @@ private:
int m_copperLayerCount; ///< Number of copper layers for this design
LSET m_enabledLayers; ///< Bit-mask for layer enabling
LSET m_visibleLayers; ///< Bit-mask for layer visibility
int m_visibleElements; ///< Bit-mask for element category visibility
int m_boardThickness; ///< Board thickness for 3D viewer
/// Current net class name used to display netclass info.
@ -325,8 +329,25 @@ private:
*/
BOARD_STACKUP m_stackup;
/// Net classes that are loaded from the board file before these were stored in the project
NETCLASSES m_internalNetClasses;
/// This will point to m_internalNetClasses until it is repointed to the project after load
NETCLASSES* m_netClasses;
/// The defualt settings that will be used for new zones
ZONE_SETTINGS m_defaultZoneSettings;
SEVERITY severityFromString( const wxString& aSeverity );
wxString severityToString( const SEVERITY& aSeverity );
public:
BOARD_DESIGN_SETTINGS();
BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath );
virtual ~BOARD_DESIGN_SETTINGS();
bool LoadFromFile( const std::string& aDirectory = "" ) override;
BOARD_STACKUP& GetStackupDescriptor() { return m_stackup; }
@ -337,13 +358,36 @@ public:
*/
bool Ignore( int aDRCErrorCode );
NETCLASSES& GetNetClasses() const
{
return *m_netClasses;
}
void SetNetClasses( NETCLASSES* aNetClasses )
{
if( aNetClasses )
m_netClasses = aNetClasses;
else
m_netClasses = &m_internalNetClasses;
}
ZONE_SETTINGS& GetDefaultZoneSettings()
{
return m_defaultZoneSettings;
}
void SetDefaultZoneSettings( const ZONE_SETTINGS& aSettings )
{
m_defaultZoneSettings = aSettings;
}
/**
* Function GetDefault
* @return the default netclass.
*/
inline NETCLASS* GetDefault() const
{
return m_NetClasses.GetDefaultPtr();
return GetNetClasses().GetDefaultPtr();
}
/**
@ -712,95 +756,6 @@ public:
*/
void SetCopperEdgeClearance( int aDistance );
/**
* Function GetVisibleLayers
* returns a bit-mask of all the layers that are visible
* @return int - the visible layers in bit-mapped form.
*/
inline LSET GetVisibleLayers() const
{
return m_visibleLayers;
}
/**
* Function SetVisibleAlls
* Set the bit-mask of all visible elements categories,
* including enabled layers
*/
void SetVisibleAlls();
/**
* Function SetVisibleLayers
* changes the bit-mask of visible layers
* @param aMask = The new bit-mask of visible layers
*/
inline void SetVisibleLayers( LSET aMask )
{
m_visibleLayers = aMask & m_enabledLayers;
}
/**
* Function IsLayerVisible
* tests whether a given layer is visible
* @param aLayerId = The layer to be tested
* @return bool - true if the layer is visible.
*/
inline bool IsLayerVisible( PCB_LAYER_ID aLayerId ) const
{
// If a layer is disabled, it is automatically invisible
return (m_visibleLayers & m_enabledLayers)[aLayerId];
}
/**
* Function SetLayerVisibility
* changes the visibility of a given layer
* @param aLayerId = The layer to be changed
* @param aNewState = The new visibility state of the layer
*/
void SetLayerVisibility( PCB_LAYER_ID aLayerId, bool aNewState );
/**
* Function GetVisibleElements
* returns a bit-mask of all the element categories that are visible
* @return int - the visible element categories in bit-mapped form.
*/
inline int GetVisibleElements() const
{
return m_visibleElements;
}
/**
* Function SetVisibleElements
* changes the bit-mask of visible element categories
* @param aMask = The new bit-mask of visible element categories
*/
inline void SetVisibleElements( int aMask )
{
m_visibleElements = aMask;
}
/**
* Function IsElementVisible
* tests whether a given element category is visible. Keep this as an
* inline function.
* @param aElementCategory is from the enum by the same name
* @return bool - true if the element is visible.
* @see enum GAL_LAYER_ID
*/
inline bool IsElementVisible( GAL_LAYER_ID aElementCategory ) const
{
return ( m_visibleElements & ( 1 << GAL_LAYER_INDEX( aElementCategory ) ) );
}
/**
* Function SetElementVisibility
* changes the visibility of an element category
* @param aElementCategory is from the enum by the same name
* @param aNewState = The new visibility state of the element category
* @see enum GAL_LAYER_ID
*/
void SetElementVisibility( GAL_LAYER_ID aElementCategory, bool aNewState );
/**
* Function GetEnabledLayers
* returns a bit-mask of all the layers that are enabled
@ -845,14 +800,6 @@ public:
*/
void SetCopperLayerCount( int aNewLayerCount );
/**
* Function AppendConfigs
* appends to @a aResult the configuration setting accessors which will later
* allow reading or writing of configuration file information directly into
* this object.
*/
void AppendConfigs( BOARD* aBoard, std::vector<PARAM_CFG*>* aResult );
inline int GetBoardThickness() const { return m_boardThickness; }
inline void SetBoardThickness( int aThickness ) { m_boardThickness = aThickness; }

View File

@ -44,6 +44,8 @@ public:
bool Migrate() override;
/// Only some of these settings are actually used for footprint editing
// TODO: factor out the relevant stuff so the whole BDS doesn't have to be here
BOARD_DESIGN_SETTINGS m_DesignSettings;
// Only the magneticPads element is used

View File

@ -218,6 +218,8 @@ enum GAL_LAYER_ID: int
/// Use this macro to convert a GAL layer to a 0-indexed offset from LAYER_VIAS
#define GAL_LAYER_INDEX( x ) ( x - GAL_LAYER_ID_START )
constexpr int GAL_LAYER_ID_COUNT = GAL_LAYER_ID_END - GAL_LAYER_ID_START;
inline GAL_LAYER_ID operator++( GAL_LAYER_ID& a )
{
a = GAL_LAYER_ID( int( a ) + 1 );
@ -402,6 +404,7 @@ public:
}
};
typedef std::bitset<GAL_LAYER_ID_COUNT> GAL_SET;
typedef std::bitset<PCB_LAYER_ID_COUNT> BASE_SET;

View File

@ -201,16 +201,6 @@ public:
*/
void SetParams( const NETCLASS& aDefaults );
/**
* Function Format
* outputs the net class to \a aFormatter in s-expression form.
*
* @param aFormatter The #OUTPUTFORMATTER object to write to.
* @param aNestLevel The indentation next level.
* @param aControlBits The control bit definition for object specific formatting.
* @throw IO_ERROR on write error.
*/
void Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const;
#if defined(DEBUG)
void Show( int nestLevel, std::ostream& os ) const;

View File

@ -148,12 +148,10 @@ public:
void SetTitleBlock( const TITLE_BLOCK& aTitleBlock ) override;
/**
* Function GetDesignSettings
* returns the BOARD_DESIGN_SETTINGS for the BOARD owned by this frame.
* Returns the BOARD_DESIGN_SETTINGS for the open project
* Overloaded in FOOTPRINT_EDIT_FRAME.
*/
virtual BOARD_DESIGN_SETTINGS& GetDesignSettings() const;
virtual void SetDesignSettings( const BOARD_DESIGN_SETTINGS& aSettings );
/**
* Helper to retrieve the current color settings

Some files were not shown because too many files have changed in this diff Show More