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:
parent
0e2f9cb1bd
commit
c0aa6965de
3d-viewer/3d_canvas
common
CMakeLists.txtlib_tree_model_adapter.cpplib_tree_model_adapter.hnetclass.cppproject.cpp
project
settings
swig
wildcards_and_files_ext.cppcvpcb
eeschema
include
board_design_settings.hfootprint_editor_settings.hlayers_id_colors_and_visibility.hnetclass.hpcb_base_frame.hproject.h
project
settings
wildcards_and_files_ext.hkicad
pcbnew
CMakeLists.txt
altium2kicadpcb_plugin
board_design_settings.cppboard_item_container.hclass_board.cppclass_board.hclass_pad.cppclass_pad.hdialogs
dialog_board_setup.cppdialog_export_idf.cppdialog_export_step.cppdialog_export_vrml.cppdialog_global_edit_tracks_and_vias.cppdialog_import_settings.cppdialog_netlist.cpppanel_modedit_defaults.cpppanel_setup_netclasses.cpp
drc
exporters
files.cppfootprint_edit_frame.cppfootprint_edit_frame.hfootprint_editor_settings.cppfp_tree_model_adapter.cppinitpcb.cppkicad_plugin.cppkicad_plugin.hlegacy_plugin.cppnetinfo_item.cppnetlist_reader
pcb_base_frame.cpppcb_edit_frame.cpppcb_edit_frame.hpcb_layer_widget.cpppcb_parser.cpppcbnew_config.cpprouter
specctra_import_export
swig
tools
zone_settings.hqa
pcbnew/drc
pcbnew_tools/tools/drc_tool
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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" );
|
||||
}
|
@ -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() :
|
||||
|
142
common/project/net_settings.cpp
Normal file
142
common/project/net_settings.cpp
Normal 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;
|
||||
}
|
||||
}
|
478
common/project/project_file.cpp
Normal file
478
common/project/project_file.cpp
Normal 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 );
|
||||
}
|
105
common/project/project_local_settings.cpp
Normal file
105
common/project/project_local_settings.cpp
Normal 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 );
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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 );
|
||||
}
|
@ -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 );
|
||||
}
|
||||
|
||||
|
@ -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" );
|
||||
|
@ -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 '\''
|
||||
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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 )
|
||||
|
@ -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 )
|
||||
{}
|
||||
|
||||
|
@ -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 )
|
||||
|
@ -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; }
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
@ -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
Loading…
Reference in New Issue
Block a user