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
|
@ -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() :
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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 );
|
||||
}
|
|
@ -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,18 +30,13 @@ 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()
|
||||
{
|
||||
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() );
|
||||
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
|
||||
|
|
|
@ -48,6 +48,7 @@ class KIWAY;
|
|||
class SYMBOL_LIB_TABLE;
|
||||
class FILENAME_RESOLVER;
|
||||
class PROJECT_FILE;
|
||||
class PROJECT_LOCAL_SETTINGS;
|
||||
|
||||
#define VTBL_ENTRY virtual
|
||||
|
||||
|
@ -132,6 +133,12 @@ public:
|
|||
return *m_projectFile;
|
||||
}
|
||||
|
||||
VTBL_ENTRY PROJECT_LOCAL_SETTINGS& GetLocalSettings() const
|
||||
{
|
||||
wxASSERT( m_localSettings );
|
||||
return *m_localSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function ConfigSave
|
||||
* saves the current "project" parameters into the wxConfigBase* derivative.
|
||||
|
@ -340,6 +347,15 @@ private:
|
|||
m_projectFile = aFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the local settings backing store. Should only be called by SETTINGS_MANAGER on load.
|
||||
* @param aSettings is the local settings object (may or may not exist on disk at this point)
|
||||
*/
|
||||
VTBL_ENTRY void setLocalSettings( PROJECT_LOCAL_SETTINGS* aSettings )
|
||||
{
|
||||
m_localSettings = aSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function configCreate
|
||||
* loads a *.pro file and returns a wxConfigBase.
|
||||
|
@ -362,6 +378,9 @@ private:
|
|||
/// Backing store for project data -- owned by SETTINGS_MANAGER
|
||||
PROJECT_FILE* m_projectFile;
|
||||
|
||||
/// Backing store for project local settings -- owned by SETTINGS_MANAGER
|
||||
PROJECT_LOCAL_SETTINGS* m_localSettings;
|
||||
|
||||
std::map<KIID, wxString> m_sheetNames;
|
||||
std::map<wxString, wxString> m_textVars;
|
||||
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef KICAD_NET_SETTINGS_H
|
||||
#define KICAD_NET_SETTINGS_H
|
||||
|
||||
#include <netclass.h>
|
||||
#include <settings/nested_settings.h>
|
||||
|
||||
/**
|
||||
* NET_SETTINGS stores various net-related settings in a project context. These settings are
|
||||
* accessible and editable from both the schematic and PCB editors.
|
||||
*/
|
||||
class NET_SETTINGS : public NESTED_SETTINGS
|
||||
{
|
||||
public:
|
||||
NET_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath );
|
||||
|
||||
virtual ~NET_SETTINGS();
|
||||
|
||||
NETCLASSES m_NetClasses;
|
||||
|
||||
private:
|
||||
NETCLASSPTR m_defaultClass;
|
||||
|
||||
// TODO: Add diff pairs, bus information, etc here.
|
||||
};
|
||||
|
||||
#endif // KICAD_NET_SETTINGS_H
|
|
@ -23,7 +23,9 @@
|
|||
|
||||
#include <common.h>
|
||||
#include <settings/json_settings.h>
|
||||
#include <settings/nested_settings.h>
|
||||
|
||||
class NET_SETTINGS;
|
||||
|
||||
/**
|
||||
* For files like sheets and boards, a pair of that object KIID and display name
|
||||
|
@ -31,6 +33,20 @@
|
|||
*/
|
||||
typedef std::pair<KIID, wxString> FILE_INFO_PAIR;
|
||||
|
||||
/**
|
||||
* For storing PcbNew MRU paths of various types
|
||||
*/
|
||||
enum LAST_PATH_TYPE : unsigned int
|
||||
{
|
||||
LAST_PATH_NETLIST = 0,
|
||||
LAST_PATH_STEP,
|
||||
LAST_PATH_IDF,
|
||||
LAST_PATH_VRML,
|
||||
LAST_PATH_SPECCTRADSN,
|
||||
LAST_PATH_GENCAD,
|
||||
|
||||
LAST_PATH_SIZE
|
||||
};
|
||||
|
||||
/**
|
||||
* PROJECT_FILE is the backing store for a PROJECT, in JSON format.
|
||||
|
@ -47,9 +63,16 @@ public:
|
|||
*/
|
||||
PROJECT_FILE( const std::string& aFullPath );
|
||||
|
||||
virtual ~PROJECT_FILE() {}
|
||||
virtual ~PROJECT_FILE() = default;
|
||||
|
||||
virtual bool MigrateFromLegacy( wxConfigBase* aLegacyFile ) override;
|
||||
virtual bool MigrateFromLegacy( wxConfigBase* aCfg ) override;
|
||||
|
||||
bool SaveToFile( const std::string& aDirectory = "", bool aForce = false ) override;
|
||||
|
||||
void SetProject( PROJECT* aProject )
|
||||
{
|
||||
m_project = aProject;
|
||||
}
|
||||
|
||||
std::vector<FILE_INFO_PAIR>& GetSheets()
|
||||
{
|
||||
|
@ -61,6 +84,11 @@ public:
|
|||
return m_boards;
|
||||
}
|
||||
|
||||
NET_SETTINGS& NetSettings()
|
||||
{
|
||||
return *m_NetSettings;
|
||||
}
|
||||
|
||||
protected:
|
||||
wxString getFileExt() const override;
|
||||
|
||||
|
@ -74,6 +102,9 @@ private:
|
|||
/// A list of board files in this project
|
||||
std::vector<FILE_INFO_PAIR> m_boards;
|
||||
|
||||
/// A link to the owning PROJECT
|
||||
PROJECT* m_project;
|
||||
|
||||
/**
|
||||
* Below are project-level settings that have not been moved to a dedicated file
|
||||
*/
|
||||
|
@ -95,6 +126,31 @@ public:
|
|||
|
||||
/// List of equivalence (equ) files used in the project
|
||||
std::vector<wxString> m_EquivalenceFiles;
|
||||
|
||||
/**
|
||||
* PcbNew params
|
||||
*/
|
||||
|
||||
/// Page layout description file
|
||||
wxString m_PageLayoutDescrFile;
|
||||
|
||||
/// MRU path storage
|
||||
wxString m_PcbLastPath[LAST_PATH_SIZE];
|
||||
|
||||
/**
|
||||
* Board design settings for this project's board. This will be initialized by PcbNew after
|
||||
* loading a board so that BOARD_DESIGN_SETTINGS doesn't need to live in common for now.
|
||||
* Owned by the BOARD; may be null if a board isn't loaded: be careful
|
||||
*/
|
||||
NESTED_SETTINGS* m_BoardSettings;
|
||||
|
||||
/**
|
||||
* Net settings for this project (owned here)
|
||||
* NOTE: If we go multi-board in the future, we have to decide whether to use a global
|
||||
* NET_SETTINGS or have one per board. Right now I think global makes more sense (one set of
|
||||
* schematics, one netlist partitioned into multiple boards)
|
||||
*/
|
||||
std::shared_ptr<NET_SETTINGS> m_NetSettings;
|
||||
};
|
||||
|
||||
// Specializations to allow directly reading/writing FILE_INFO_PAIRs from JSON
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef KICAD_PROJECT_LOCAL_SETTINGS_H
|
||||
#define KICAD_PROJECT_LOCAL_SETTINGS_H
|
||||
|
||||
#include <layers_id_colors_and_visibility.h>
|
||||
#include <settings/json_settings.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
|
||||
class PROJECT;
|
||||
|
||||
/**
|
||||
* The project local settings are things that are attached to a particular project, but also might
|
||||
* be particular to a certain user editing that project, or change quickly, and therefore may not
|
||||
* want to be checked in to version control or otherwise distributed with the main project.
|
||||
*
|
||||
* Examples include layer visibility, recently-used design entry settings, and so on.
|
||||
*
|
||||
* The backing store is a JSON file named <project>.kicad_prl
|
||||
*
|
||||
* This file doesn't need to exist for a project to be loaded. It will be created on-demand if
|
||||
* any of the things stored here are modified by the user.
|
||||
*/
|
||||
class PROJECT_LOCAL_SETTINGS : public JSON_SETTINGS
|
||||
{
|
||||
public:
|
||||
PROJECT_LOCAL_SETTINGS( const std::string& aFilename );
|
||||
|
||||
virtual ~PROJECT_LOCAL_SETTINGS() {}
|
||||
|
||||
bool MigrateFromLegacy( wxConfigBase* aLegacyConfig ) override;
|
||||
|
||||
bool SaveToFile( const std::string& aDirectory = "", bool aForce = false ) override;
|
||||
|
||||
void SetProject( PROJECT* aProject )
|
||||
{
|
||||
m_project = aProject;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
wxString getFileExt() const override
|
||||
{
|
||||
return ProjectLocalSettingsFileExtension;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/// A link to the owning project
|
||||
PROJECT* m_project;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Board settings
|
||||
*/
|
||||
|
||||
/// The board layers that are turned on for viewing (@see PCB_LAYER_ID)
|
||||
LSET m_VisibleLayers;
|
||||
|
||||
/// The GAL layers (aka items) that are turned on for viewing (@see GAL_LAYER_ID)
|
||||
GAL_SET m_VisibleItems;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -105,17 +105,15 @@ public:
|
|||
m_map( aMap )
|
||||
{}
|
||||
|
||||
void Load( JSON_SETTINGS* aSettings ) const override
|
||||
void Load( JSON_SETTINGS* aSettings, bool aResetIfMissing = true ) const override
|
||||
{
|
||||
if( m_readOnly )
|
||||
return;
|
||||
|
||||
COLOR4D val = m_default;
|
||||
|
||||
if( OPT<COLOR4D> optval = aSettings->Get<COLOR4D>( m_path ) )
|
||||
val = *optval;
|
||||
|
||||
( *m_map )[ m_key ] = val;
|
||||
( *m_map )[ m_key ] = *optval;
|
||||
else if( aResetIfMissing )
|
||||
( *m_map )[ m_key ] = m_default;
|
||||
}
|
||||
|
||||
void Store( JSON_SETTINGS* aSettings) const override
|
||||
|
|
|
@ -55,6 +55,8 @@ public:
|
|||
|
||||
std::string GetFilename() const { return m_filename; }
|
||||
|
||||
wxString GetFullFilename() const;
|
||||
|
||||
SETTINGS_LOC GetLocation() const { return m_location; }
|
||||
|
||||
void SetLegacyFilename( const std::string& aFilename ) { m_legacy_filename = aFilename; }
|
||||
|
@ -81,8 +83,7 @@ public:
|
|||
/**
|
||||
* Calls Store() and then writes the contents of the JSON document to a file
|
||||
* @param aDirectory is the directory to save to, including trailing separator
|
||||
* @param aForce if true will always save, even if contents are not modified
|
||||
* @return true if the file was saved
|
||||
c * @return true if the file was saved
|
||||
*/
|
||||
virtual bool SaveToFile( const std::string& aDirectory = "", bool aForce = false );
|
||||
|
||||
|
@ -97,7 +98,7 @@ public:
|
|||
* @param aPath is a string containing one or more keys separated by '.'
|
||||
* @return a JSON object from within this one
|
||||
*/
|
||||
OPT<nlohmann::json> GetJson( std::string aPath ) const;
|
||||
OPT<nlohmann::json> GetJson( const std::string& aPath ) const;
|
||||
|
||||
/**
|
||||
* Fetches a value from within the JSON document.
|
||||
|
@ -107,9 +108,9 @@ public:
|
|||
* @return a value from within this document
|
||||
*/
|
||||
template<typename ValueType>
|
||||
OPT<ValueType> Get( std::string aPath ) const
|
||||
OPT<ValueType> Get( const std::string& aPath ) const
|
||||
{
|
||||
if( OPT<nlohmann::json> ret = GetJson( std::move( aPath ) ) )
|
||||
if( OPT<nlohmann::json> ret = GetJson( aPath ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -131,9 +132,9 @@ public:
|
|||
* @param aVal is the value to store
|
||||
*/
|
||||
template<typename ValueType>
|
||||
void Set( std::string aPath, ValueType aVal )
|
||||
void Set( const std::string& aPath, ValueType aVal )
|
||||
{
|
||||
( *this )[PointerFromString( std::move( aPath ) ) ] = aVal;
|
||||
( *this )[PointerFromString( aPath ) ] = aVal;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -253,6 +254,9 @@ protected:
|
|||
/// Whether or not to delete legacy file after migration
|
||||
bool m_deleteLegacyAfterMigration;
|
||||
|
||||
/// Whether or not to set parameters to their default value if missing from JSON on Load()
|
||||
bool m_resetParamsIfMissing;
|
||||
|
||||
/// Version of this settings schema.
|
||||
int m_schemaVersion;
|
||||
|
||||
|
@ -265,9 +269,9 @@ protected:
|
|||
|
||||
// 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;
|
||||
|
||||
template<> void JSON_SETTINGS::Set<wxString>( std::string aPath, wxString aVal );
|
||||
template<> void JSON_SETTINGS::Set<wxString>( const std::string& aPath, wxString aVal );
|
||||
|
||||
// Specializations to allow directly reading/writing wxStrings from JSON
|
||||
|
||||
|
|
|
@ -49,7 +49,14 @@ public:
|
|||
*/
|
||||
bool SaveToFile( const std::string& aDirectory = "", bool aForce = false ) override;
|
||||
|
||||
private:
|
||||
void SetParent( JSON_SETTINGS* aParent );
|
||||
|
||||
JSON_SETTINGS* GetParent()
|
||||
{
|
||||
return m_parent;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
/// A pointer to the parent object to load and store from
|
||||
JSON_SETTINGS* m_parent;
|
||||
|
|
|
@ -42,8 +42,9 @@ public:
|
|||
/**
|
||||
* Loads the value of this parameter from JSON to the underlying storage
|
||||
* @param aSettings is the JSON_SETTINGS object to load from.
|
||||
* @param aResetIfMissing if true will set the parameter to its default value if load fails
|
||||
*/
|
||||
virtual void Load( JSON_SETTINGS* aSettings ) const = 0;
|
||||
virtual void Load( JSON_SETTINGS* aSettings, bool aResetIfMissing = true ) const = 0;
|
||||
|
||||
/**
|
||||
* Stores the value of this parameter to the given JSON_SETTINGS object
|
||||
|
@ -90,43 +91,43 @@ public:
|
|||
PARAM( const std::string& aJsonPath, ValueType* aPtr, ValueType aDefault,
|
||||
bool aReadOnly = false ) :
|
||||
PARAM_BASE( aJsonPath, aReadOnly ),
|
||||
m_ptr( aPtr ),
|
||||
m_default( aDefault ),
|
||||
m_min(),
|
||||
m_max(),
|
||||
m_use_minmax( false )
|
||||
m_use_minmax( false ),
|
||||
m_ptr( aPtr ),
|
||||
m_default( aDefault )
|
||||
{ }
|
||||
|
||||
PARAM( const std::string& aJsonPath, ValueType* aPtr, ValueType aDefault, ValueType aMin,
|
||||
ValueType aMax, bool aReadOnly = false ) :
|
||||
PARAM_BASE( aJsonPath, aReadOnly ),
|
||||
m_ptr( aPtr ),
|
||||
m_default( aDefault ),
|
||||
m_min( aMin ),
|
||||
m_max( aMax ),
|
||||
m_use_minmax( true )
|
||||
m_use_minmax( true ),
|
||||
m_ptr( aPtr ),
|
||||
m_default( aDefault )
|
||||
{ }
|
||||
|
||||
void Load( JSON_SETTINGS* aSettings ) const override
|
||||
void Load( JSON_SETTINGS* aSettings, bool aResetIfMissing = true ) const override
|
||||
{
|
||||
if( m_readOnly )
|
||||
return;
|
||||
|
||||
ValueType val = m_default;
|
||||
|
||||
if( OPT<ValueType> optval = aSettings->Get<ValueType>( m_path ) )
|
||||
{
|
||||
val = *optval;
|
||||
ValueType val = *optval;
|
||||
|
||||
if( m_use_minmax )
|
||||
{
|
||||
if( m_max < val || val < m_min )
|
||||
val = m_default;
|
||||
}
|
||||
}
|
||||
|
||||
*m_ptr = val;
|
||||
}
|
||||
else if( aResetIfMissing )
|
||||
*m_ptr = m_default;
|
||||
}
|
||||
|
||||
void Store( JSON_SETTINGS* aSettings ) const override
|
||||
{
|
||||
|
@ -157,13 +158,66 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
ValueType* m_ptr;
|
||||
ValueType m_default;
|
||||
ValueType m_min;
|
||||
ValueType m_max;
|
||||
bool m_use_minmax;
|
||||
|
||||
protected:
|
||||
ValueType* m_ptr;
|
||||
ValueType m_default;
|
||||
};
|
||||
|
||||
/**
|
||||
* Stores a path as a string with directory separators normalized to unix-style
|
||||
*/
|
||||
class PARAM_PATH : public PARAM<wxString>
|
||||
{
|
||||
public:
|
||||
PARAM_PATH( const std::string& aJsonPath, wxString* aPtr, wxString aDefault,
|
||||
bool aReadOnly = false ) :
|
||||
PARAM( aJsonPath, aPtr, aDefault, aReadOnly )
|
||||
{ }
|
||||
|
||||
void Load( JSON_SETTINGS* aSettings, bool aResetIfMissing = true ) const override
|
||||
{
|
||||
if( m_readOnly )
|
||||
return;
|
||||
|
||||
PARAM::Load( aSettings, aResetIfMissing );
|
||||
|
||||
*m_ptr = fromFileFormat( *m_ptr );
|
||||
}
|
||||
|
||||
void Store( JSON_SETTINGS* aSettings ) const override
|
||||
{
|
||||
aSettings->Set<wxString>( m_path, toFileFormat( *m_ptr ) );
|
||||
}
|
||||
|
||||
bool MatchesFile( JSON_SETTINGS* aSettings ) const override
|
||||
{
|
||||
if( OPT<wxString> optval = aSettings->Get<wxString>( m_path ) )
|
||||
return fromFileFormat( *optval ) == *m_ptr;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
wxString toFileFormat( const wxString& aString ) const
|
||||
{
|
||||
wxString ret = aString;
|
||||
ret.Replace( wxT( "\\" ), wxT( "/" ) );
|
||||
return ret;
|
||||
}
|
||||
|
||||
wxString fromFileFormat( const wxString& aString ) const
|
||||
{
|
||||
wxString ret = aString;
|
||||
#ifdef __WINDOWS__
|
||||
ret.Replace( wxT( "/" ), wxT( "\\" ) );
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Like a normal param, but with custom getter and setter functions
|
||||
|
@ -182,25 +236,25 @@ public:
|
|||
m_setter( aSetter )
|
||||
{ }
|
||||
|
||||
void Load( JSON_SETTINGS* aSettings ) const override
|
||||
void Load( JSON_SETTINGS* aSettings, bool aResetIfMissing = true ) const override
|
||||
{
|
||||
if( m_readOnly )
|
||||
return;
|
||||
|
||||
ValueType val = m_default;
|
||||
|
||||
if( std::is_same<ValueType, nlohmann::json>::value )
|
||||
{
|
||||
if( OPT<nlohmann::json> optval = aSettings->GetJson( m_path ) )
|
||||
val = *optval;
|
||||
m_setter( *optval );
|
||||
else
|
||||
m_setter( m_default );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( OPT<ValueType> optval = aSettings->Get<ValueType>( m_path ) )
|
||||
val = *optval;
|
||||
m_setter( *optval );
|
||||
else
|
||||
m_setter( m_default );
|
||||
}
|
||||
|
||||
m_setter( val );
|
||||
}
|
||||
|
||||
void Store( JSON_SETTINGS* aSettings ) const override
|
||||
|
@ -287,7 +341,7 @@ public:
|
|||
m_scale( aScale )
|
||||
{ }
|
||||
|
||||
void Load( JSON_SETTINGS* aSettings ) const override
|
||||
void Load( JSON_SETTINGS* aSettings, bool aResetIfMissing = true ) const override
|
||||
{
|
||||
if( m_readOnly )
|
||||
return;
|
||||
|
@ -296,6 +350,8 @@ public:
|
|||
|
||||
if( OPT<double> optval = aSettings->Get<double>( m_path ) )
|
||||
dval = *optval;
|
||||
else if( !aResetIfMissing )
|
||||
return;
|
||||
|
||||
ValueType val = KiROUND<ValueType>( dval / m_scale );
|
||||
|
||||
|
@ -363,26 +419,26 @@ public:
|
|||
m_default( aDefault )
|
||||
{ }
|
||||
|
||||
void Load( JSON_SETTINGS* aSettings ) const override
|
||||
void Load( JSON_SETTINGS* aSettings, bool aResetIfMissing = true ) const override
|
||||
{
|
||||
if( m_readOnly )
|
||||
return;
|
||||
|
||||
std::vector<Type> val = m_default;
|
||||
|
||||
if( OPT<nlohmann::json> js = aSettings->GetJson( m_path ) )
|
||||
{
|
||||
std::vector<Type> val;
|
||||
|
||||
if( js->is_array() )
|
||||
{
|
||||
val.clear();
|
||||
|
||||
for( const auto& el : js->items() )
|
||||
val.push_back( el.value().get<Type>() );
|
||||
}
|
||||
}
|
||||
|
||||
*m_ptr = val;
|
||||
}
|
||||
else if( aResetIfMissing )
|
||||
*m_ptr = m_default;
|
||||
}
|
||||
|
||||
void Store( JSON_SETTINGS* aSettings) const override
|
||||
{
|
||||
|
@ -445,12 +501,12 @@ public:
|
|||
PARAM_LIST( aJsonPath, aPtr, aDefault, aReadOnly )
|
||||
{ }
|
||||
|
||||
void Load( JSON_SETTINGS* aSettings ) const override
|
||||
void Load( JSON_SETTINGS* aSettings, bool aResetIfMissing = true ) const override
|
||||
{
|
||||
if( m_readOnly )
|
||||
return;
|
||||
|
||||
PARAM_LIST::Load( aSettings );
|
||||
PARAM_LIST::Load( aSettings, aResetIfMissing );
|
||||
|
||||
for( size_t i = 0; i < m_ptr->size(); i++ )
|
||||
( *m_ptr )[i] = fromFileFormat( ( *m_ptr )[i] );
|
||||
|
@ -526,7 +582,7 @@ public:
|
|||
m_default( aDefault )
|
||||
{ }
|
||||
|
||||
void Load( JSON_SETTINGS* aSettings ) const override
|
||||
void Load( JSON_SETTINGS* aSettings, bool aResetIfMissing = true ) const override
|
||||
{
|
||||
if( m_readOnly )
|
||||
return;
|
||||
|
|
|
@ -61,7 +61,7 @@ public:
|
|||
* If the given settings object is registered, save it to disk and unregister it
|
||||
* @param aSettings is the object to release
|
||||
*/
|
||||
void FlushAndRelease( JSON_SETTINGS* aSettings );
|
||||
void FlushAndRelease( JSON_SETTINGS* aSettings, bool aSave = true );
|
||||
|
||||
/**
|
||||
* Returns a handle to the a given settings by type
|
||||
|
@ -184,16 +184,18 @@ public:
|
|||
/**
|
||||
* Loads a project or sets up a new project with a specified path
|
||||
* @param aFullPath is the full path to the project
|
||||
* @param aSetActive if true will set the loaded project as the active project
|
||||
* @return true if the PROJECT_FILE was successfully loaded from disk
|
||||
*/
|
||||
bool LoadProject( const wxString& aFullPath );
|
||||
bool LoadProject( const wxString& aFullPath, bool aSetActive = true );
|
||||
|
||||
/**
|
||||
* Saves, unloads and unregisters the given PROJECT
|
||||
* @param aProject is the project object to unload
|
||||
* @param aSave if true will save the project before unloading
|
||||
* @return true if the PROJECT file was successfully saved
|
||||
*/
|
||||
bool UnloadProject( PROJECT& aProject );
|
||||
bool UnloadProject( PROJECT* aProject, bool aSave = true );
|
||||
|
||||
/**
|
||||
* A helper while we are not MDI-capable -- return the one and only project
|
||||
|
@ -202,16 +204,23 @@ public:
|
|||
PROJECT& Prj() const;
|
||||
|
||||
/**
|
||||
* Saves the one and only project
|
||||
* TODO: Update for MDI
|
||||
* @return true if save was successful
|
||||
* Retrieves a loaded project by name
|
||||
* @param aFullPath is the full path including name and extension to the project file
|
||||
* @return a pointer to the project if loaded, or nullptr
|
||||
*/
|
||||
bool SaveProject();
|
||||
PROJECT* GetProject( const wxString& aFullPath ) const;
|
||||
|
||||
/**
|
||||
* @return the path to the settings folder for the loaded project
|
||||
* Saves a loaded project.
|
||||
* @param aFullPath is the project name to save. If empty, will save the first loaded project.
|
||||
* @return true if save was successful
|
||||
*/
|
||||
wxString GetProjectSettingsPath() const;
|
||||
bool SaveProject( const wxString& aFullPath = wxEmptyString );
|
||||
|
||||
/**
|
||||
* @return the path to the backups folder for the loaded project
|
||||
*/
|
||||
wxString GetProjectBackupsPath() const;
|
||||
|
||||
/**
|
||||
* Checks if a given path is probably a valid KiCad configuration directory.
|
||||
|
@ -300,11 +309,12 @@ private:
|
|||
bool loadProjectFile( PROJECT& aProject );
|
||||
|
||||
/**
|
||||
* Saves, unloads and unregisters the given PROJECT_FILE
|
||||
* Optionally saves, and then unloads and unregisters the given PROJECT_FILE
|
||||
* @param aProject is the project object to unload the file for
|
||||
* @param aSave if true will save the project file before unloading
|
||||
* @return true if the PROJECT file was successfully saved
|
||||
*/
|
||||
bool unloadProjectFile( PROJECT& aProject );
|
||||
bool unloadProjectFile( PROJECT* aProject, bool aSave );
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -116,6 +116,7 @@ extern const std::string SchematicBackupFileExtension;
|
|||
extern const std::string VrmlFileExtension;
|
||||
extern const std::string ProjectFileExtension;
|
||||
extern const std::string LegacyProjectFileExtension;
|
||||
extern const std::string ProjectLocalSettingsFileExtension;
|
||||
extern const std::string LegacySchematicFileExtension;
|
||||
extern const std::string KiCadSchematicFileExtension;
|
||||
extern const std::string NetlistFileExtension;
|
||||
|
|
|
@ -56,14 +56,6 @@
|
|||
|
||||
#define SEP() wxFileName::GetPathSeparator()
|
||||
|
||||
// Not really useful, provided to save/restore params in project config file,
|
||||
// (Add them in s_KicadManagerParams if any)
|
||||
// Used also to create new .pro files from the kicad.pro template file
|
||||
// for new projects
|
||||
#define GeneralGroupName wxT( "/general" )
|
||||
|
||||
std::vector<PARAM_CFG*> s_KicadManagerParams;
|
||||
|
||||
|
||||
// Menubar and toolbar event table
|
||||
BEGIN_EVENT_TABLE( KICAD_MANAGER_FRAME, EDA_BASE_FRAME )
|
||||
|
|
|
@ -448,7 +448,6 @@ if( KICAD_SCRIPTING ) # Generate pcbnew.py and pcbnew_wrap.cxx using swig
|
|||
DEPENDS swig/pcb_target.i
|
||||
DEPENDS swig/pcb_plot_params.i
|
||||
DEPENDS swig/footprint.i
|
||||
DEPENDS swig/netclass.i
|
||||
DEPENDS swig/netinfo.i
|
||||
DEPENDS swig/pad.i
|
||||
DEPENDS swig/pcb_text.i
|
||||
|
@ -463,6 +462,7 @@ if( KICAD_SCRIPTING ) # Generate pcbnew.py and pcbnew_wrap.cxx using swig
|
|||
DEPENDS ${CMAKE_SOURCE_DIR}/common/swig/kicad.i
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/common/swig/wx.i
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/common/swig/ki_exception.i
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/common/swig/netclass.i
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/scripting/kicadplugins.i
|
||||
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/docstrings
|
||||
|
|
|
@ -757,7 +757,7 @@ void ALTIUM_PCB::ParseClasses6Data(
|
|||
if( elem.kind == ALTIUM_CLASS_KIND::NET_CLASS )
|
||||
{
|
||||
const NETCLASSPTR& netclass = std::make_shared<NETCLASS>( elem.name );
|
||||
designSettings.m_NetClasses.Add( netclass );
|
||||
designSettings.GetNetClasses().Add( netclass );
|
||||
|
||||
for( const auto& name : elem.names )
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -72,7 +72,7 @@ public:
|
|||
/**
|
||||
* @brief Fetch the zone settings for this container
|
||||
*/
|
||||
const ZONE_SETTINGS& GetZoneSettings() const
|
||||
virtual const ZONE_SETTINGS& GetZoneSettings() const
|
||||
{
|
||||
return m_zoneSettings;
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ public:
|
|||
* @brief Set the zone settings for this container
|
||||
* @param aSettings new Zone settings for this container
|
||||
*/
|
||||
void SetZoneSettings( const ZONE_SETTINGS& aSettings )
|
||||
virtual void SetZoneSettings( const ZONE_SETTINGS& aSettings )
|
||||
{
|
||||
m_zoneSettings = aSettings;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,10 @@
|
|||
#include <connectivity/connectivity_data.h>
|
||||
#include <pgm_base.h>
|
||||
#include <pcbnew_settings.h>
|
||||
#include <project.h>
|
||||
#include <project/net_settings.h>
|
||||
#include <project/project_file.h>
|
||||
#include <project/project_local_settings.h>
|
||||
#include <ratsnest/ratsnest_data.h>
|
||||
#include <ratsnest/ratsnest_viewitem.h>
|
||||
|
||||
|
@ -81,23 +85,19 @@ DELETED_BOARD_ITEM* g_DeletedItem = nullptr;
|
|||
*/
|
||||
wxPoint BOARD_ITEM::ZeroOffset( 0, 0 );
|
||||
|
||||
// Dummy settings used to initialize the board.
|
||||
// This is needed because some APIs that make use of BOARD without the context of a frame or
|
||||
// application, and so the BOARD needs to store a valid pointer to a PCBNEW_SETTINGS even if
|
||||
// one hasn't been provided by the application.
|
||||
static PCBNEW_SETTINGS dummyGeneralSettings;
|
||||
|
||||
BOARD::BOARD() :
|
||||
BOARD_ITEM_CONTAINER( (BOARD_ITEM*) NULL, PCB_T ),
|
||||
m_paper( PAGE_INFO::A4 ),
|
||||
m_project( nullptr ),
|
||||
m_designSettings( new BOARD_DESIGN_SETTINGS( nullptr, "board.design_settings" ) ),
|
||||
m_NetInfo( this ),
|
||||
m_project( nullptr )
|
||||
m_LegacyDesignSettingsLoaded( false ),
|
||||
m_LegacyNetclassesLoaded( false )
|
||||
{
|
||||
// we have not loaded a board yet, assume latest until then.
|
||||
m_fileFormatVersionAtLoad = LEGACY_BOARD_FILE_VERSION;
|
||||
|
||||
m_generalSettings = &dummyGeneralSettings;
|
||||
|
||||
m_CurrentZoneContour = NULL; // This ZONE_CONTAINER handle the
|
||||
// zone contour currently in progress
|
||||
|
||||
|
@ -113,19 +113,25 @@ BOARD::BOARD() :
|
|||
m_Layer[layer].m_type = LT_UNDEFINED;
|
||||
}
|
||||
|
||||
BOARD_DESIGN_SETTINGS& bds = GetDesignSettings();
|
||||
|
||||
// Initialize default netclass.
|
||||
NETCLASS* defaultClass = m_designSettings.GetDefault();
|
||||
NETCLASS* defaultClass = bds.GetDefault();
|
||||
defaultClass->SetDescription( _( "This is the default net class." ) );
|
||||
m_designSettings.SetCurrentNetClass( defaultClass->GetName() );
|
||||
bds.SetCurrentNetClass( defaultClass->GetName() );
|
||||
|
||||
// Set sensible initial values for custom track width & via size
|
||||
m_designSettings.UseCustomTrackViaSize( false );
|
||||
m_designSettings.SetCustomTrackWidth( m_designSettings.GetCurrentTrackWidth() );
|
||||
m_designSettings.SetCustomViaSize( m_designSettings.GetCurrentViaSize() );
|
||||
m_designSettings.SetCustomViaDrill( m_designSettings.GetCurrentViaDrill() );
|
||||
bds.UseCustomTrackViaSize( false );
|
||||
bds.SetCustomTrackWidth( bds.GetCurrentTrackWidth() );
|
||||
bds.SetCustomViaSize( bds.GetCurrentViaSize() );
|
||||
bds.SetCustomViaDrill( bds.GetCurrentViaDrill() );
|
||||
|
||||
// Initialize ratsnest
|
||||
m_connectivity.reset( new CONNECTIVITY_DATA() );
|
||||
|
||||
// Set flag bits on these that will only be cleared if these are loaded from a legacy file
|
||||
m_LegacyVisibleLayers.reset().set( Rescue );
|
||||
m_LegacyVisibleItems.reset().set( GAL_LAYER_INDEX( GAL_LAYER_ID_BITMASK_END ) );
|
||||
}
|
||||
|
||||
|
||||
|
@ -170,6 +176,54 @@ void BOARD::BuildConnectivity()
|
|||
}
|
||||
|
||||
|
||||
void BOARD::SetProject( PROJECT* aProject )
|
||||
{
|
||||
m_project = aProject;
|
||||
|
||||
if( aProject )
|
||||
{
|
||||
PROJECT_FILE& project = aProject->GetProjectFile();
|
||||
|
||||
// Link the design settings object to the project file
|
||||
project.m_BoardSettings = &GetDesignSettings();
|
||||
|
||||
// Set parent, which also will load the values from JSON stored in the project
|
||||
project.m_BoardSettings->SetParent( &project );
|
||||
|
||||
// The netclasses pointer will be pointing to the internal netclasses list at this point. If
|
||||
// it has anything other than the default net, this means we loaded some netclasses from a
|
||||
// board saved in legacy format where the netclass info is included. Move this info to the
|
||||
// netclasses stored in the project.
|
||||
|
||||
NETCLASSES& local = GetDesignSettings().GetNetClasses();
|
||||
|
||||
if( m_LegacyNetclassesLoaded )
|
||||
project.NetSettings().m_NetClasses = local;
|
||||
|
||||
GetDesignSettings().SetNetClasses( &project.NetSettings().m_NetClasses );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BOARD::ClearProject()
|
||||
{
|
||||
if( !m_project )
|
||||
return;
|
||||
|
||||
PROJECT_FILE& project = m_project->GetProjectFile();
|
||||
|
||||
// Owned by the BOARD
|
||||
if( project.m_BoardSettings )
|
||||
{
|
||||
project.ReleaseNestedSettings( project.m_BoardSettings );
|
||||
project.m_BoardSettings = nullptr;
|
||||
}
|
||||
|
||||
GetDesignSettings().SetParent( nullptr );
|
||||
m_project = nullptr;
|
||||
}
|
||||
|
||||
|
||||
const wxPoint BOARD::GetPosition() const
|
||||
{
|
||||
return ZeroOffset;
|
||||
|
@ -392,50 +446,56 @@ LAYER_T LAYER::ParseType( const char* aType )
|
|||
|
||||
int BOARD::GetCopperLayerCount() const
|
||||
{
|
||||
return m_designSettings.GetCopperLayerCount();
|
||||
return GetDesignSettings().GetCopperLayerCount();
|
||||
}
|
||||
|
||||
|
||||
void BOARD::SetCopperLayerCount( int aCount )
|
||||
{
|
||||
m_designSettings.SetCopperLayerCount( aCount );
|
||||
GetDesignSettings().SetCopperLayerCount( aCount );
|
||||
}
|
||||
|
||||
|
||||
LSET BOARD::GetEnabledLayers() const
|
||||
{
|
||||
return m_designSettings.GetEnabledLayers();
|
||||
return GetDesignSettings().GetEnabledLayers();
|
||||
}
|
||||
|
||||
|
||||
bool BOARD::IsLayerVisible( PCB_LAYER_ID aLayer ) const
|
||||
{
|
||||
// If there is no project, assume layer is visible always
|
||||
return GetDesignSettings().IsLayerEnabled( aLayer )
|
||||
&& ( !m_project || m_project->GetLocalSettings().m_VisibleLayers[aLayer] );
|
||||
}
|
||||
|
||||
|
||||
LSET BOARD::GetVisibleLayers() const
|
||||
{
|
||||
return m_designSettings.GetVisibleLayers();
|
||||
return m_project ? m_project->GetLocalSettings().m_VisibleLayers : LSET::AllLayersMask();
|
||||
}
|
||||
|
||||
|
||||
void BOARD::SetEnabledLayers( LSET aLayerSet )
|
||||
{
|
||||
m_designSettings.SetEnabledLayers( aLayerSet );
|
||||
GetDesignSettings().SetEnabledLayers( aLayerSet );
|
||||
}
|
||||
|
||||
|
||||
void BOARD::SetVisibleLayers( LSET aLayerSet )
|
||||
{
|
||||
m_designSettings.SetVisibleLayers( aLayerSet );
|
||||
if( m_project )
|
||||
m_project->GetLocalSettings().m_VisibleLayers = aLayerSet;
|
||||
}
|
||||
|
||||
|
||||
void BOARD::SetVisibleElements( int aMask )
|
||||
void BOARD::SetVisibleElements( const GAL_SET& aSet )
|
||||
{
|
||||
// Call SetElementVisibility for each item
|
||||
// to ensure specific calculations that can be needed by some items,
|
||||
// just changing the visibility flags could be not sufficient.
|
||||
for( GAL_LAYER_ID ii = GAL_LAYER_ID_START; ii < GAL_LAYER_ID_BITMASK_END; ++ii )
|
||||
{
|
||||
int item_mask = 1 << GAL_LAYER_INDEX( ii );
|
||||
SetElementVisibility( ii, aMask & item_mask );
|
||||
}
|
||||
for( size_t i = 0; i < aSet.size(); i++ )
|
||||
SetElementVisibility( GAL_LAYER_ID_START + static_cast<int>( i ), aSet[i] );
|
||||
}
|
||||
|
||||
|
||||
|
@ -450,21 +510,22 @@ void BOARD::SetVisibleAlls()
|
|||
}
|
||||
|
||||
|
||||
int BOARD::GetVisibleElements() const
|
||||
GAL_SET BOARD::GetVisibleElements() const
|
||||
{
|
||||
return m_designSettings.GetVisibleElements();
|
||||
return m_project ? m_project->GetLocalSettings().m_VisibleItems : GAL_SET().set();
|
||||
}
|
||||
|
||||
|
||||
bool BOARD::IsElementVisible( GAL_LAYER_ID aLayer ) const
|
||||
{
|
||||
return m_designSettings.IsElementVisible( aLayer );
|
||||
return !m_project || m_project->GetLocalSettings().m_VisibleItems[aLayer - GAL_LAYER_ID_START];
|
||||
}
|
||||
|
||||
|
||||
void BOARD::SetElementVisibility( GAL_LAYER_ID aLayer, bool isEnabled )
|
||||
{
|
||||
m_designSettings.SetElementVisibility( aLayer, isEnabled );
|
||||
if( m_project )
|
||||
m_project->GetLocalSettings().m_VisibleItems.set( aLayer - GAL_LAYER_ID_START, isEnabled );
|
||||
|
||||
switch( aLayer )
|
||||
{
|
||||
|
@ -1216,6 +1277,86 @@ int BOARD::SortedNetnamesList( wxArrayString& aNames, bool aSortbyPadsCount )
|
|||
}
|
||||
|
||||
|
||||
void BOARD::SynchronizeNetsAndNetClasses()
|
||||
{
|
||||
NETCLASSES& netClasses = GetDesignSettings().GetNetClasses();
|
||||
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() );
|
||||
}
|
||||
|
||||
BOARD_DESIGN_SETTINGS& bds = GetDesignSettings();
|
||||
|
||||
// Set initial values for custom track width & via size to match the default netclass settings
|
||||
bds.UseCustomTrackViaSize( false );
|
||||
bds.SetCustomTrackWidth( defaultNetClass->GetTrackWidth() );
|
||||
bds.SetCustomViaSize( defaultNetClass->GetViaDiameter() );
|
||||
bds.SetCustomViaDrill( defaultNetClass->GetViaDrill() );
|
||||
bds.SetCustomDiffPairWidth( defaultNetClass->GetDiffPairWidth() );
|
||||
bds.SetCustomDiffPairGap( defaultNetClass->GetDiffPairGap() );
|
||||
bds.SetCustomDiffPairViaGap( defaultNetClass->GetDiffPairViaGap() );
|
||||
|
||||
InvokeListeners( &BOARD_LISTENER::OnBoardNetSettingsChanged, *this );
|
||||
}
|
||||
|
||||
|
||||
int BOARD::SetAreasNetCodesFromNetNames()
|
||||
{
|
||||
int error_count = 0;
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
|
||||
class PCB_BASE_FRAME;
|
||||
class PCB_EDIT_FRAME;
|
||||
class PCBNEW_SETTINGS;
|
||||
class PICKED_ITEMS_LIST;
|
||||
class BOARD;
|
||||
class ZONE_CONTAINER;
|
||||
|
@ -211,13 +210,24 @@ private:
|
|||
|
||||
std::shared_ptr<CONNECTIVITY_DATA> m_connectivity;
|
||||
|
||||
BOARD_DESIGN_SETTINGS m_designSettings;
|
||||
PCBNEW_SETTINGS* m_generalSettings; // reference only; I have no ownership
|
||||
PAGE_INFO m_paper;
|
||||
TITLE_BLOCK m_titles; // text in lower right of screen and plots
|
||||
PCB_PLOT_PARAMS m_plotOptions;
|
||||
PROJECT* m_project; // project this board is a part of
|
||||
|
||||
/**
|
||||
* All of the board design settings are stored as a JSON object inside the project file. The
|
||||
* object itself is located here because the alternative is to require a valid project be
|
||||
* passed in when constructing a BOARD, since things in the BOARD constructor rely on access
|
||||
* to the BOARD_DESIGN_SETTINGS object.
|
||||
*
|
||||
* A reference to this object is set up in the PROJECT_FILE for the PROJECT this board is
|
||||
* part of, so that the JSON load/store operations work. This link is established when
|
||||
* boards are loaded from disk.
|
||||
*/
|
||||
std::unique_ptr<BOARD_DESIGN_SETTINGS> m_designSettings;
|
||||
|
||||
NETINFO_LIST m_NetInfo; // net info list (name, design constraints ..
|
||||
PROJECT* m_project; // project this board is a part of (if any)
|
||||
|
||||
std::vector<BOARD_LISTENER*> m_listeners;
|
||||
|
||||
|
@ -282,6 +292,16 @@ public:
|
|||
/// zone contour currently in progress
|
||||
ZONE_CONTAINER* m_CurrentZoneContour;
|
||||
|
||||
/// Visibility settings stored in board prior to 6.0, only used for loading legacy files
|
||||
LSET m_LegacyVisibleLayers;
|
||||
GAL_SET m_LegacyVisibleItems;
|
||||
|
||||
/// True if the legacy board design settings were loaded from a file
|
||||
bool m_LegacyDesignSettingsLoaded;
|
||||
|
||||
/// True if netclasses were loaded from the file
|
||||
bool m_LegacyNetclassesLoaded;
|
||||
|
||||
BOARD();
|
||||
~BOARD();
|
||||
|
||||
|
@ -354,7 +374,15 @@ public:
|
|||
void DeleteZONEOutlines();
|
||||
|
||||
PROJECT* GetProject() const { return m_project; }
|
||||
void SetProject( PROJECT* aProject ) { m_project = aProject; }
|
||||
|
||||
/**
|
||||
* Links a board to a given project. Should be called immediately after loading board in
|
||||
* order for everything to work
|
||||
* @param aProject is a loaded project to link to
|
||||
*/
|
||||
void SetProject( PROJECT* aProject );
|
||||
|
||||
void ClearProject();
|
||||
|
||||
/**
|
||||
* Function ResetNetHighLight
|
||||
|
@ -434,7 +462,7 @@ public:
|
|||
*/
|
||||
bool IsLayerEnabled( PCB_LAYER_ID aLayer ) const
|
||||
{
|
||||
return m_designSettings.IsLayerEnabled( aLayer );
|
||||
return GetDesignSettings().IsLayerEnabled( aLayer );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -444,10 +472,7 @@ public:
|
|||
* @param aLayer = The layer to be tested
|
||||
* @return bool - true if the layer is visible.
|
||||
*/
|
||||
bool IsLayerVisible( PCB_LAYER_ID aLayer ) const
|
||||
{
|
||||
return m_designSettings.IsLayerVisible( aLayer );
|
||||
}
|
||||
bool IsLayerVisible( PCB_LAYER_ID aLayer ) const;
|
||||
|
||||
/**
|
||||
* Function GetVisibleLayers
|
||||
|
@ -469,13 +494,11 @@ public:
|
|||
// are not stored in the bitmap.
|
||||
|
||||
/**
|
||||
* Function GetVisibleElements
|
||||
* is a proxy function that calls the correspondent function in m_BoardSettings
|
||||
* returns a bit-mask of all the element categories that are visible
|
||||
* @return int - the visible element bitmap or-ed from enum GAL_LAYER_ID
|
||||
* Returns a set of all the element categories that are visible
|
||||
* @return the set of visible GAL layers
|
||||
* @see enum GAL_LAYER_ID
|
||||
*/
|
||||
int GetVisibleElements() const;
|
||||
GAL_SET GetVisibleElements() const;
|
||||
|
||||
/**
|
||||
* Function SetVisibleElements
|
||||
|
@ -484,7 +507,7 @@ public:
|
|||
* @param aMask = The new bit-mask of visible element bitmap or-ed from enum GAL_LAYER_ID
|
||||
* @see enum GAL_LAYER_ID
|
||||
*/
|
||||
void SetVisibleElements( int aMask );
|
||||
void SetVisibleElements( const GAL_SET& aMask );
|
||||
|
||||
/**
|
||||
* Function SetVisibleAlls
|
||||
|
@ -528,16 +551,22 @@ public:
|
|||
BOARD_DESIGN_SETTINGS& GetDesignSettings() const
|
||||
{
|
||||
// remove const-ness with cast. TODO(snh): Make GetDesignSettings const
|
||||
return const_cast<BOARD_DESIGN_SETTINGS&>( m_designSettings );
|
||||
// NOTE(JE) If we want this to be const, it's going to have to involve making BOARD and
|
||||
// everything else that relies on BOARD_DESIGN_SETTINGS aware of the PROJECT so that it
|
||||
// can be retrieved from there. This will also currently require constructing BOARD with
|
||||
// a valid PROJECT passed in to the ctor.
|
||||
|
||||
return const_cast<BOARD_DESIGN_SETTINGS&>( *m_designSettings.get() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Function SetDesignSettings
|
||||
* @param aDesignSettings the new BOARD_DESIGN_SETTINGS to use
|
||||
*/
|
||||
void SetDesignSettings( const BOARD_DESIGN_SETTINGS& aDesignSettings )
|
||||
const ZONE_SETTINGS& GetZoneSettings() const override
|
||||
{
|
||||
m_designSettings = aDesignSettings;
|
||||
return GetDesignSettings().GetDefaultZoneSettings();
|
||||
}
|
||||
|
||||
void SetZoneSettings( const ZONE_SETTINGS& aSettings ) override
|
||||
{
|
||||
GetDesignSettings().SetDefaultZoneSettings( aSettings );
|
||||
}
|
||||
|
||||
const PAGE_INFO& GetPageSettings() const { return m_paper; }
|
||||
|
@ -551,13 +580,6 @@ public:
|
|||
|
||||
wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
|
||||
|
||||
const PCBNEW_SETTINGS& GeneralSettings() const { return *m_generalSettings; }
|
||||
|
||||
void SetGeneralSettings( PCBNEW_SETTINGS* aSettings )
|
||||
{
|
||||
m_generalSettings = aSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function GetBoardPolygonOutlines
|
||||
* Extracts the board outlines and build a closed polygon
|
||||
|
|
|
@ -487,37 +487,6 @@ void D_PAD::MirrorXPrimitives( int aX )
|
|||
}
|
||||
|
||||
|
||||
void D_PAD::AppendConfigs( std::vector<PARAM_CFG*>* aResult )
|
||||
{
|
||||
// Parameters stored in config are only significant parameters
|
||||
// for a template.
|
||||
// So not all parameters are stored, just few.
|
||||
aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "PadDrill" ),
|
||||
&m_Drill.x,
|
||||
Millimeter2iu( 0.6 ),
|
||||
Millimeter2iu( 0.1 ), Millimeter2iu( 10.0 ),
|
||||
NULL, MM_PER_IU ) );
|
||||
|
||||
aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "PadDrillOvalY" ),
|
||||
&m_Drill.y,
|
||||
Millimeter2iu( 0.6 ),
|
||||
Millimeter2iu( 0.1 ), Millimeter2iu( 10.0 ),
|
||||
NULL, MM_PER_IU ) );
|
||||
|
||||
aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "PadSizeH" ),
|
||||
&m_Size.x,
|
||||
Millimeter2iu( 1.4 ),
|
||||
Millimeter2iu( 0.1 ), Millimeter2iu( 20.0 ),
|
||||
NULL, MM_PER_IU ) );
|
||||
|
||||
aResult->push_back( new PARAM_CFG_INT_WITH_SCALE( wxT( "PadSizeV" ),
|
||||
&m_Size.y,
|
||||
Millimeter2iu( 1.4 ),
|
||||
Millimeter2iu( 0.1 ), Millimeter2iu( 20.0 ),
|
||||
NULL, MM_PER_IU ) );
|
||||
}
|
||||
|
||||
|
||||
// Returns the position of the pad.
|
||||
wxPoint D_PAD::ShapePos() const
|
||||
{
|
||||
|
|
|
@ -551,14 +551,6 @@ public:
|
|||
*/
|
||||
wxString ShowPadAttr() const;
|
||||
|
||||
/**
|
||||
* 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( std::vector<PARAM_CFG*>* aResult );
|
||||
|
||||
EDA_ITEM* Clone() const override;
|
||||
|
||||
/**
|
||||
|
|
|
@ -24,18 +24,24 @@
|
|||
#include <panel_setup_tracks_and_vias.h>
|
||||
#include <panel_setup_mask_and_paste.h>
|
||||
#include <../board_stackup_manager/panel_board_stackup.h>
|
||||
#include <confirm.h>
|
||||
#include <kiface_i.h>
|
||||
#include <drc/drc.h>
|
||||
#include <drc/drc_item.h>
|
||||
#include <dialog_import_settings.h>
|
||||
#include <io_mgr.h>
|
||||
#include <panel_setup_severities.h>
|
||||
#include <panel_text_variables.h>
|
||||
#include <project.h>
|
||||
#include <project/project_file.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
|
||||
#include "dialog_board_setup.h"
|
||||
#include "panel_setup_rules.h"
|
||||
|
||||
DIALOG_BOARD_SETUP::DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame ) :
|
||||
PAGED_DIALOG( aFrame, _( "Board Setup" ), _( "Import Settings from Another Project..." ) ),
|
||||
PAGED_DIALOG( aFrame, _( "Board Setup" ), _( "Import Settings from Another Board..." ) ),
|
||||
m_frame( aFrame )
|
||||
{
|
||||
m_layers = new PANEL_SETUP_LAYERS( this, aFrame );
|
||||
|
@ -127,30 +133,59 @@ void DIALOG_BOARD_SETUP::OnAuxiliaryAction( wxCommandEvent& event )
|
|||
if( importDlg.ShowModal() == wxID_CANCEL )
|
||||
return;
|
||||
|
||||
wxConfigBase* cfg = new wxFileConfig( wxEmptyString, wxEmptyString, importDlg.GetFilePath() );
|
||||
wxFileName boardFn( importDlg.GetFilePath() );
|
||||
wxFileName projectFn( boardFn );
|
||||
|
||||
// We do not want expansion of env var values when reading our project config file
|
||||
cfg->SetExpandEnvVars( false );
|
||||
cfg->SetPath( wxCONFIG_PATH_SEPARATOR );
|
||||
projectFn.SetExt( ProjectFileExtension );
|
||||
|
||||
BOARD* dummyBoard = new BOARD();
|
||||
std::vector<PARAM_CFG*> designSettingsConfig;
|
||||
if( !m_frame->GetSettingsManager()->LoadProject( projectFn.GetFullPath(), false ) )
|
||||
{
|
||||
wxString msg = wxString::Format( _( "Error importing settings from borad:\n"
|
||||
"Associated project file %s could not be loaded" ),
|
||||
projectFn.GetFullPath() );
|
||||
DisplayErrorMessage( this, msg );
|
||||
|
||||
dummyBoard->GetDesignSettings().AppendConfigs( dummyBoard, &designSettingsConfig );
|
||||
wxConfigLoadParams( cfg, designSettingsConfig, GROUP_PCB );
|
||||
return;
|
||||
}
|
||||
|
||||
PROJECT* otherPrj = m_frame->GetSettingsManager()->GetProject( projectFn.GetFullPath() );
|
||||
|
||||
PLUGIN::RELEASER pi( IO_MGR::PluginFind( IO_MGR::KICAD_SEXP ) );
|
||||
|
||||
BOARD* otherBoard = new BOARD();
|
||||
|
||||
try
|
||||
{
|
||||
otherBoard = pi->Load( boardFn.GetFullPath(), nullptr, nullptr );
|
||||
}
|
||||
catch( const IO_ERROR& ioe )
|
||||
{
|
||||
if( ioe.Problem() != wxT( "CANCEL" ) )
|
||||
{
|
||||
wxString msg =
|
||||
wxString::Format( _( "Error loading board file:\n%s" ), boardFn.GetFullPath() );
|
||||
DisplayErrorMessage( this, msg, ioe.What() );
|
||||
}
|
||||
|
||||
m_frame->GetSettingsManager()->UnloadProject( otherPrj, false );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
otherBoard->SetProject( otherPrj );
|
||||
|
||||
if( importDlg.m_LayersOpt->GetValue() )
|
||||
m_layers->ImportSettingsFrom( dummyBoard );
|
||||
m_layers->ImportSettingsFrom( otherBoard );
|
||||
if( importDlg.m_TextAndGraphicsOpt->GetValue() )
|
||||
m_textAndGraphics->ImportSettingsFrom( dummyBoard );
|
||||
m_textAndGraphics->ImportSettingsFrom( otherBoard );
|
||||
if( importDlg.m_ConstraintsOpt->GetValue() )
|
||||
m_constraints->ImportSettingsFrom( dummyBoard );
|
||||
m_constraints->ImportSettingsFrom( otherBoard );
|
||||
if( importDlg.m_NetclassesOpt->GetValue() )
|
||||
m_netclasses->ImportSettingsFrom( dummyBoard );
|
||||
m_netclasses->ImportSettingsFrom( otherBoard );
|
||||
if( importDlg.m_TracksAndViasOpt->GetValue() )
|
||||
m_tracksAndVias->ImportSettingsFrom( dummyBoard );
|
||||
m_tracksAndVias->ImportSettingsFrom( otherBoard );
|
||||
if( importDlg.m_MaskAndPasteOpt->GetValue() )
|
||||
m_maskAndPaste->ImportSettingsFrom( dummyBoard );
|
||||
m_maskAndPaste->ImportSettingsFrom( otherBoard );
|
||||
|
||||
// If layers options are imported, import also the stackup
|
||||
// layers options and stackup are linked, so they cannot be imported
|
||||
|
@ -159,12 +194,16 @@ void DIALOG_BOARD_SETUP::OnAuxiliaryAction( wxCommandEvent& event )
|
|||
// Note also currently only the list of enabled layers can be imported, because
|
||||
// we import settings from a .pro project file, not the settings inside
|
||||
// a board, and info only living in the board is not imported.
|
||||
// TODO: Add import of physical settings now that we are actually loading the board here
|
||||
if( importDlg.m_LayersOpt->GetValue() )
|
||||
m_physicalStackup->ImportSettingsFrom( dummyBoard );
|
||||
m_physicalStackup->ImportSettingsFrom( otherBoard );
|
||||
|
||||
if( importDlg.m_SeveritiesOpt->GetValue() )
|
||||
m_severities->ImportSettingsFrom( dummyBoard->GetDesignSettings().m_DRCSeverities );
|
||||
m_severities->ImportSettingsFrom( otherBoard->GetDesignSettings().m_DRCSeverities );
|
||||
|
||||
delete dummyBoard;
|
||||
delete cfg;
|
||||
otherBoard->ClearProject();
|
||||
|
||||
m_frame->GetSettingsManager()->UnloadProject( otherPrj, false );
|
||||
|
||||
delete otherBoard;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <dialog_export_idf_base.h>
|
||||
#include <pcb_edit_frame.h>
|
||||
#include <pcbnew_settings.h>
|
||||
#include <project/project_file.h> // LAST_PATH_TYPE
|
||||
#include <confirm.h>
|
||||
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "class_board.h"
|
||||
#include "dialog_export_step_base.h"
|
||||
#include <pcbnew_settings.h>
|
||||
#include <project/project_file.h> // LAST_PATH_TYPE
|
||||
#include <widgets/text_ctrl_eval.h>
|
||||
#include <wx_html_report_panel.h>
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <pcb_edit_frame.h>
|
||||
#include <pcbnew_settings.h>
|
||||
#include <pcbnew.h>
|
||||
#include <project/project_file.h> // LAST_PATH_TYPE
|
||||
|
||||
|
||||
/* the dialog to create VRML files, derived from DIALOG_EXPORT_3DFILE_BASE,
|
||||
|
|
|
@ -170,7 +170,7 @@ void DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::buildFilterLists()
|
|||
|
||||
// Populate the netclass filter list with netclass names
|
||||
wxArrayString netclassNames;
|
||||
NETCLASSES& netclasses = m_brd->GetDesignSettings().m_NetClasses;
|
||||
NETCLASSES& netclasses = m_brd->GetDesignSettings().GetNetClasses();
|
||||
|
||||
netclassNames.push_back( netclasses.GetDefaultPtr()->GetName() );
|
||||
|
||||
|
@ -200,7 +200,7 @@ void DIALOG_GLOBAL_EDIT_TRACKS_AND_VIAS::buildNetclassesGrid()
|
|||
m_netclassGrid->SetCellValue( 0, GRID_uVIASIZE, _( "uVia Size" ) );
|
||||
m_netclassGrid->SetCellValue( 0, GRID_uVIADRILL, _( "uVia Drill" ) );
|
||||
|
||||
NETCLASSES& netclasses = m_brd->GetDesignSettings().m_NetClasses;
|
||||
NETCLASSES& netclasses = m_brd->GetDesignSettings().GetNetClasses();
|
||||
NETCLASS* defaultNetclass = m_brd->GetDesignSettings().GetDefault();
|
||||
m_netclassGrid->AppendRows( netclasses.GetCount() + 1 );
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ void DIALOG_IMPORT_SETTINGS::OnBrowseClicked( wxCommandEvent& event )
|
|||
fn.SetExt( LegacyProjectFileExtension );
|
||||
|
||||
wxFileDialog dlg( this, _( "Import Settings From" ), fn.GetPath(), fn.GetFullName(),
|
||||
ProjectFileWildcard(), wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_CHANGE_DIR );
|
||||
PcbFileWildcard(), wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_CHANGE_DIR );
|
||||
|
||||
if( dlg.ShowModal() == wxID_OK )
|
||||
m_filePathCtrl->SetValue( dlg.GetPath() );
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include <wildcards_and_files_ext.h>
|
||||
#include <netlist_reader/pcb_netlist.h>
|
||||
#include <netlist_reader/board_netlist_updater.h>
|
||||
#include <project/project_file.h> // LAST_PATH_TYPE
|
||||
|
||||
#include <dialog_netlist.h>
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <fctsys.h>
|
||||
#include <widgets/paged_dialog.h>
|
||||
#include <footprint_edit_frame.h>
|
||||
#include <footprint_editor_settings.h>
|
||||
#include <widgets/wx_grid.h>
|
||||
#include <grid_tricks.h>
|
||||
|
||||
|
@ -361,7 +362,8 @@ bool PANEL_MODEDIT_DEFAULTS::TransferDataFromWindow()
|
|||
m_brdSettings.m_DefaultFPTextItems.emplace_back( text, visible, layer );
|
||||
}
|
||||
|
||||
m_frame->SetDesignSettings( m_brdSettings );
|
||||
if( FOOTPRINT_EDITOR_SETTINGS* cfg = m_frame->GetSettings() )
|
||||
cfg->m_DesignSettings = m_brdSettings;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -152,7 +152,7 @@ static void netclassToGridRow( EDA_UNITS aUnits, wxGrid* aGrid, int aRow, const
|
|||
|
||||
bool PANEL_SETUP_NETCLASSES::TransferDataToWindow()
|
||||
{
|
||||
NETCLASSES& netclasses = m_BrdSettings->m_NetClasses;
|
||||
NETCLASSES& netclasses = m_BrdSettings->GetNetClasses();
|
||||
NETCLASSPTR netclass = netclasses.GetDefault();
|
||||
|
||||
if( m_netclassGrid->GetNumberRows() )
|
||||
|
@ -250,7 +250,7 @@ bool PANEL_SETUP_NETCLASSES::TransferDataFromWindow()
|
|||
if( !validateData() )
|
||||
return false;
|
||||
|
||||
NETCLASSES& netclasses = m_BrdSettings->m_NetClasses;
|
||||
NETCLASSES& netclasses = m_BrdSettings->GetNetClasses();
|
||||
|
||||
// Remove all netclasses from board. We'll copy new list after
|
||||
netclasses.Clear();
|
||||
|
@ -263,7 +263,7 @@ bool PANEL_SETUP_NETCLASSES::TransferDataFromWindow()
|
|||
{
|
||||
NETCLASSPTR nc = std::make_shared<NETCLASS>( m_netclassGrid->GetCellValue( row, GRID_NAME ) );
|
||||
|
||||
if( m_BrdSettings->m_NetClasses.Add( nc ) )
|
||||
if( netclasses.Add( nc ) )
|
||||
gridRowToNetclass( m_Frame->GetUserUnits(), m_netclassGrid, row, nc );
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ bool DRC_NETCLASS_TESTER::RunDRC( EDA_UNITS aUnits, BOARD& aBoard )
|
|||
m_board = &aBoard;
|
||||
|
||||
bool success = true;
|
||||
NETCLASSES& netclasses = m_board->GetDesignSettings().m_NetClasses;
|
||||
NETCLASSES& netclasses = m_board->GetDesignSettings().GetNetClasses();
|
||||
|
||||
success &= checkNetClass( netclasses.GetDefault() );
|
||||
|
||||
|
|
|
@ -132,7 +132,7 @@ void DRC_RULES_PARSER::Parse( std::vector<DRC_SELECTOR*>& aSelectors,
|
|||
|
||||
DRC_SELECTOR* DRC_RULES_PARSER::parseDRC_SELECTOR( wxString* aRuleName )
|
||||
{
|
||||
NETCLASSES& netclasses = m_board->GetDesignSettings().m_NetClasses;
|
||||
NETCLASSES& netclasses = m_board->GetDesignSettings().GetNetClasses();
|
||||
DRC_SELECTOR* selector = new DRC_SELECTOR();
|
||||
T token;
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include <pcbnew.h>
|
||||
#include <pcbnew_settings.h>
|
||||
#include <pgm_base.h>
|
||||
#include <project/project_file.h> // LAST_PATH_TYPE
|
||||
#include <trigo.h>
|
||||
|
||||
static bool CreateHeaderInfoData( FILE* aFile, PCB_EDIT_FRAME* frame );
|
||||
|
|
|
@ -452,7 +452,7 @@ void GERBER_JOBFILE_WRITER::addJSONDesignRules()
|
|||
bool hasInnerLayers = m_pcb->GetCopperLayerCount() > 2;
|
||||
|
||||
// Search a smaller clearance in other net classes, if any.
|
||||
for( const std::pair<const wxString, NETCLASSPTR>& entry : dsnSettings.m_NetClasses )
|
||||
for( const std::pair<const wxString, NETCLASSPTR>& entry : dsnSettings.GetNetClasses() )
|
||||
minclearanceOuter = std::min( minclearanceOuter, entry.second->GetClearance() );
|
||||
|
||||
// job file knows different clearance types.
|
||||
|
|
|
@ -52,6 +52,8 @@
|
|||
|
||||
#include <wx/wupdlock.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <project/project_file.h>
|
||||
#include <project/project_local_settings.h>
|
||||
|
||||
|
||||
//#define USE_INSTRUMENTATION 1
|
||||
|
@ -305,14 +307,19 @@ bool PCB_EDIT_FRAME::Files_io_from_id( int id )
|
|||
return false;
|
||||
}
|
||||
|
||||
if( !Clear_Pcb( false ) )
|
||||
return false;
|
||||
GetSettingsManager()->SaveProject( GetSettingsManager()->Prj().GetProjectFullName() );
|
||||
GetBoard()->ClearProject();
|
||||
|
||||
wxFileName fn( wxStandardPaths::Get().GetDocumentsDir(), wxT( "noname" ),
|
||||
LegacyProjectFileExtension );
|
||||
ProjectFileExtension );
|
||||
|
||||
GetSettingsManager()->LoadProject( fn.GetFullPath() );
|
||||
|
||||
LoadProjectSettings();
|
||||
|
||||
if( !Clear_Pcb( false ) )
|
||||
return false;
|
||||
|
||||
onBoardLoaded();
|
||||
|
||||
OnModify();
|
||||
|
@ -478,7 +485,7 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
|||
ReleaseFile();
|
||||
|
||||
wxFileName pro = fullFileName;
|
||||
pro.SetExt( LegacyProjectFileExtension );
|
||||
pro.SetExt( ProjectFileExtension );
|
||||
|
||||
bool is_new = !wxFileName::IsFileReadable( fullFileName );
|
||||
|
||||
|
@ -494,7 +501,11 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
|||
|
||||
wxWindowUpdateLocker no_update( m_Layers ); // Avoid flicker when rebuilding m_Layers
|
||||
|
||||
Clear_Pcb( false ); // pass false since we prompted above for a modified board
|
||||
// Unlink the old project if needed
|
||||
GetBoard()->ClearProject();
|
||||
|
||||
// No save prompt (we already prompted above), and only reset to a new blank board if new
|
||||
Clear_Pcb( false, !is_new );
|
||||
|
||||
IO_MGR::PCB_FILE_T pluginType = plugin_type( fullFileName, aCtl );
|
||||
|
||||
|
@ -502,8 +513,7 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
|||
|
||||
if( !converted )
|
||||
{
|
||||
// PROJECT::SetProjectFullName() is an impactful function. It should only be
|
||||
// called under carefully considered circumstances.
|
||||
// Loading a project should only be done under carefully considered circumstances.
|
||||
|
||||
// The calling code should know not to ask me here to change projects unless
|
||||
// it knows what consequences that will have on other KIFACEs running and using
|
||||
|
@ -560,40 +570,30 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
|||
DisplayErrorMessage( this, msg, ioe.What() );
|
||||
}
|
||||
|
||||
// We didn't create a new blank board above, so do that now
|
||||
Clear_Pcb( false );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
BOARD_DESIGN_SETTINGS& bds = loadedBoard->m_designSettings;
|
||||
SetBoard( loadedBoard );
|
||||
|
||||
if( bds.m_CopperEdgeClearance == Millimeter2iu( LEGACY_COPPEREDGECLEARANCE ) )
|
||||
// On save; design settings will be removed from the board
|
||||
if( loadedBoard->m_LegacyDesignSettingsLoaded )
|
||||
loadedBoard->SetModified();
|
||||
|
||||
// Move legacy view settings to local project settings
|
||||
if( !loadedBoard->m_LegacyVisibleLayers.test( Rescue ) )
|
||||
{
|
||||
// 5.1 boards stored some settings in the config so as not to bump the file version.
|
||||
// These will have been loaded into the config-initialized board, so we copy them
|
||||
// from there.
|
||||
BOARD_DESIGN_SETTINGS& configBds = GetBoard()->GetDesignSettings();
|
||||
|
||||
bds.m_DRCSeverities = configBds.m_DRCSeverities;
|
||||
bds.m_HoleToHoleMin = configBds.m_HoleToHoleMin;
|
||||
bds.m_LineThickness[LAYER_CLASS_OTHERS] = configBds.m_LineThickness[LAYER_CLASS_OTHERS];
|
||||
bds.m_TextSize[LAYER_CLASS_OTHERS] = configBds.m_TextSize[LAYER_CLASS_OTHERS];
|
||||
bds.m_TextThickness[LAYER_CLASS_OTHERS] = configBds.m_TextThickness[LAYER_CLASS_OTHERS];
|
||||
std::copy( configBds.m_TextItalic, configBds.m_TextItalic + 4, bds.m_TextItalic );
|
||||
std::copy( configBds.m_TextUpright, configBds.m_TextUpright + 4, bds.m_TextUpright );
|
||||
bds.m_DiffPairDimensionsList = configBds.m_DiffPairDimensionsList;
|
||||
bds.m_CopperEdgeClearance = configBds.m_CopperEdgeClearance;
|
||||
|
||||
// Before we had a copper edge clearance setting, the edge line widths could be used
|
||||
// as a kludge to control them. So if there's no setting then infer it from the
|
||||
// edge widths.
|
||||
if( bds.m_CopperEdgeClearance == Millimeter2iu( LEGACY_COPPEREDGECLEARANCE ) )
|
||||
bds.SetCopperEdgeClearance( inferLegacyEdgeClearance( loadedBoard ) );
|
||||
Prj().GetLocalSettings().m_VisibleLayers = loadedBoard->m_LegacyVisibleLayers;
|
||||
loadedBoard->SetModified();
|
||||
}
|
||||
|
||||
// We store the severities in the config to keep board-file changes to a minimum
|
||||
BOARD_DESIGN_SETTINGS& configBds = GetBoard()->GetDesignSettings();
|
||||
bds.m_DRCSeverities = configBds.m_DRCSeverities;
|
||||
|
||||
SetBoard( loadedBoard );
|
||||
if( !loadedBoard->m_LegacyVisibleItems.test( GAL_LAYER_INDEX( GAL_LAYER_ID_BITMASK_END ) ) )
|
||||
{
|
||||
Prj().GetLocalSettings().m_VisibleItems = loadedBoard->m_LegacyVisibleItems;
|
||||
loadedBoard->SetModified();
|
||||
}
|
||||
|
||||
// we should not ask PLUGINs to do these items:
|
||||
loadedBoard->BuildListOfNets();
|
||||
|
@ -723,6 +723,21 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF
|
|||
return false;
|
||||
}
|
||||
|
||||
// TODO: this will break if we ever go multi-board
|
||||
wxFileName projectFile( pcbFileName );
|
||||
projectFile.SetExt( ProjectFileExtension );
|
||||
|
||||
if( !projectFile.FileExists() )
|
||||
{
|
||||
// If this is a new board, project filename won't be set yet
|
||||
if( projectFile.GetFullPath() != Prj().GetProjectFullName() )
|
||||
{
|
||||
GetBoard()->ClearProject();
|
||||
GetSettingsManager()->LoadProject( projectFile.GetFullPath() );
|
||||
GetBoard()->SetProject( &Prj() );
|
||||
}
|
||||
}
|
||||
|
||||
wxString backupFileName;
|
||||
|
||||
if( aCreateBackupFile )
|
||||
|
@ -743,6 +758,8 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool aCreateBackupF
|
|||
// edited via the DRC dialog as well as the Board Setup dialog), DRC exclusions, etc.
|
||||
SaveProjectSettings();
|
||||
|
||||
GetSettingsManager()->SaveProject();
|
||||
|
||||
ClearMsgPanel();
|
||||
|
||||
wxString upperTxt;
|
||||
|
|
|
@ -401,12 +401,6 @@ BOARD_DESIGN_SETTINGS& FOOTPRINT_EDIT_FRAME::GetDesignSettings() const
|
|||
}
|
||||
|
||||
|
||||
void FOOTPRINT_EDIT_FRAME::SetDesignSettings( const BOARD_DESIGN_SETTINGS& aSettings )
|
||||
{
|
||||
GetBoard()->SetDesignSettings( aSettings );
|
||||
}
|
||||
|
||||
|
||||
const PCB_PLOT_PARAMS& FOOTPRINT_EDIT_FRAME::GetPlotSettings() const
|
||||
{
|
||||
wxFAIL_MSG( "Plotting not supported in Footprint Editor" );
|
||||
|
|
|
@ -74,7 +74,6 @@ public:
|
|||
FOOTPRINT_EDITOR_SETTINGS* GetSettings();
|
||||
|
||||
BOARD_DESIGN_SETTINGS& GetDesignSettings() const override;
|
||||
void SetDesignSettings( const BOARD_DESIGN_SETTINGS& aSettings ) override;
|
||||
|
||||
const PCB_PLOT_PARAMS& GetPlotSettings() const override;
|
||||
void SetPlotSettings( const PCB_PLOT_PARAMS& aSettings ) override;
|
||||
|
|
|
@ -39,7 +39,7 @@ const int fpEditSchemaVersion = 1;
|
|||
|
||||
FOOTPRINT_EDITOR_SETTINGS::FOOTPRINT_EDITOR_SETTINGS() :
|
||||
APP_SETTINGS_BASE( "fpedit", fpEditSchemaVersion ),
|
||||
m_DesignSettings(),
|
||||
m_DesignSettings( nullptr, "fpedit.settings" ),
|
||||
m_MagneticItems(),
|
||||
m_Display(),
|
||||
m_UserGrid(),
|
||||
|
|
|
@ -34,7 +34,7 @@ FP_TREE_MODEL_ADAPTER::PTR FP_TREE_MODEL_ADAPTER::Create( EDA_BASE_FRAME* aParen
|
|||
|
||||
|
||||
FP_TREE_MODEL_ADAPTER::FP_TREE_MODEL_ADAPTER( EDA_BASE_FRAME* aParent, LIB_TABLE* aLibs ) :
|
||||
LIB_TREE_MODEL_ADAPTER( aParent ),
|
||||
LIB_TREE_MODEL_ADAPTER( aParent, "pinned_footprint_libs" ),
|
||||
m_libs( (FP_LIB_TABLE*) aLibs )
|
||||
{}
|
||||
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
#include <fctsys.h>
|
||||
#include <confirm.h>
|
||||
#include <pcb_edit_frame.h>
|
||||
#include <project.h>
|
||||
#include <project/net_settings.h>
|
||||
#include <project/project_file.h>
|
||||
|
||||
#include <class_board.h>
|
||||
|
||||
|
@ -55,18 +58,11 @@ bool PCB_EDIT_FRAME::Clear_Pcb( bool aQuery, bool aFinal )
|
|||
GetScreen()->ClearUndoRedoList();
|
||||
GetScreen()->ClrModify();
|
||||
|
||||
// Items visibility flags will be set because a new board will be created.
|
||||
// Grid and ratsnest can be left to their previous state
|
||||
bool showGrid = IsElementVisible( LAYER_GRID );
|
||||
bool showRats = GetDisplayOptions().m_ShowGlobalRatsnest;
|
||||
|
||||
if( !aFinal )
|
||||
{
|
||||
// delete the old BOARD and create a new BOARD so that the default
|
||||
// layer names are put into the BOARD.
|
||||
SetBoard( new BOARD() );
|
||||
SetElementVisibility( LAYER_GRID, showGrid );
|
||||
SetElementVisibility( LAYER_RATSNEST, showRats );
|
||||
|
||||
// clear filename, to avoid overwriting an old file
|
||||
GetBoard()->SetFileName( wxEmptyString );
|
||||
|
@ -118,10 +114,6 @@ bool FOOTPRINT_EDIT_FRAME::Clear_Pcb( bool aQuery )
|
|||
|
||||
BOARD* board = new BOARD;
|
||||
|
||||
// Transfer current design settings
|
||||
if( GetBoard() )
|
||||
board->SetDesignSettings( GetBoard()->GetDesignSettings() );
|
||||
|
||||
board->SynchronizeNetsAndNetClasses();
|
||||
SetBoard( board );
|
||||
|
||||
|
|
|
@ -472,8 +472,6 @@ void PCB_IO::formatLayer( const BOARD_ITEM* aItem ) const
|
|||
|
||||
void PCB_IO::formatSetup( BOARD* aBoard, int aNestLevel ) const
|
||||
{
|
||||
const BOARD_DESIGN_SETTINGS& dsnSettings = aBoard->GetDesignSettings();
|
||||
|
||||
// Setup
|
||||
m_out->Print( aNestLevel, "(setup\n" );
|
||||
|
||||
|
@ -483,104 +481,7 @@ void PCB_IO::formatSetup( BOARD* aBoard, int aNestLevel ) const
|
|||
if( aBoard->GetDesignSettings().m_HasStackup )
|
||||
stackup.FormatBoardStackup( m_out,aBoard, aNestLevel+1 );
|
||||
|
||||
// Save current default track width, for compatibility with older Pcbnew version;
|
||||
m_out->Print( aNestLevel+1, "(last_trace_width %s)\n",
|
||||
FormatInternalUnits( dsnSettings.GetCurrentTrackWidth() ).c_str() );
|
||||
|
||||
// Save custom track widths list (the first is not saved here: it's the netclass value)
|
||||
for( unsigned ii = 1; ii < dsnSettings.m_TrackWidthList.size(); ii++ )
|
||||
{
|
||||
m_out->Print( aNestLevel+1, "(user_trace_width %s)\n",
|
||||
FormatInternalUnits( dsnSettings.m_TrackWidthList[ii] ).c_str() );
|
||||
}
|
||||
|
||||
m_out->Print( aNestLevel+1, "(trace_clearance %s)\n",
|
||||
FormatInternalUnits( dsnSettings.GetDefault()->GetClearance() ).c_str() );
|
||||
|
||||
// ZONE_SETTINGS
|
||||
m_out->Print( aNestLevel+1, "(zone_clearance %s)\n",
|
||||
FormatInternalUnits( aBoard->GetZoneSettings().m_ZoneClearance ).c_str() );
|
||||
m_out->Print( aNestLevel+1, "(zone_45_only %s)\n",
|
||||
aBoard->GetZoneSettings().m_Zone_45_Only ? "yes" : "no" );
|
||||
|
||||
m_out->Print( aNestLevel+1, "(trace_min %s)\n",
|
||||
FormatInternalUnits( dsnSettings.m_TrackMinWidth ).c_str() );
|
||||
m_out->Print( aNestLevel+1, "(clearance_min %s)\n",
|
||||
FormatInternalUnits( dsnSettings.m_MinClearance ).c_str() );
|
||||
m_out->Print( aNestLevel+1, "(via_min_annulus %s)\n",
|
||||
FormatInternalUnits( dsnSettings.m_ViasMinAnnulus ).c_str() );
|
||||
m_out->Print( aNestLevel+1, "(via_min_size %s)\n",
|
||||
FormatInternalUnits( dsnSettings.m_ViasMinSize ).c_str() );
|
||||
m_out->Print( aNestLevel+1, "(through_hole_min %s)\n",
|
||||
FormatInternalUnits( dsnSettings.m_MinThroughDrill ).c_str() );
|
||||
m_out->Print( aNestLevel+1, "(hole_to_hole_min %s)\n",
|
||||
FormatInternalUnits( dsnSettings.m_HoleToHoleMin ).c_str() );
|
||||
|
||||
// Save current default via size, for compatibility with older Pcbnew version;
|
||||
m_out->Print( aNestLevel+1, "(via_size %s)\n",
|
||||
FormatInternalUnits( dsnSettings.GetDefault()->GetViaDiameter() ).c_str() );
|
||||
m_out->Print( aNestLevel+1, "(via_drill %s)\n",
|
||||
FormatInternalUnits( dsnSettings.GetDefault()->GetViaDrill() ).c_str() );
|
||||
|
||||
// Save custom via dimensions list (the first is not saved here: it's the netclass value)
|
||||
for( unsigned ii = 1; ii < dsnSettings.m_ViasDimensionsList.size(); ii++ )
|
||||
m_out->Print( aNestLevel+1, "(user_via %s %s)\n",
|
||||
FormatInternalUnits( dsnSettings.m_ViasDimensionsList[ii].m_Diameter ).c_str(),
|
||||
FormatInternalUnits( dsnSettings.m_ViasDimensionsList[ii].m_Drill ).c_str() );
|
||||
|
||||
// Save custom diff-pair dimensions (the first is not saved here: it's the netclass value)
|
||||
for( unsigned ii = 1; ii < dsnSettings.m_DiffPairDimensionsList.size(); ii++ )
|
||||
{
|
||||
m_out->Print( aNestLevel+1, "(user_diff_pair %s %s %s)\n",
|
||||
FormatInternalUnits( dsnSettings.m_DiffPairDimensionsList[ii].m_Width ).c_str(),
|
||||
FormatInternalUnits( dsnSettings.m_DiffPairDimensionsList[ii].m_Gap ).c_str(),
|
||||
FormatInternalUnits( dsnSettings.m_DiffPairDimensionsList[ii].m_ViaGap ).c_str() );
|
||||
}
|
||||
|
||||
// for old versions compatibility:
|
||||
if( dsnSettings.m_BlindBuriedViaAllowed )
|
||||
m_out->Print( aNestLevel+1, "(blind_buried_vias_allowed yes)\n" );
|
||||
|
||||
m_out->Print( aNestLevel+1, "(uvia_size %s)\n",
|
||||
FormatInternalUnits( dsnSettings.GetDefault()->GetuViaDiameter() ).c_str() );
|
||||
m_out->Print( aNestLevel+1, "(uvia_drill %s)\n",
|
||||
FormatInternalUnits( dsnSettings.GetDefault()->GetuViaDrill() ).c_str() );
|
||||
m_out->Print( aNestLevel+1, "(uvias_allowed %s)\n",
|
||||
( dsnSettings.m_MicroViasAllowed ) ? "yes" : "no" );
|
||||
m_out->Print( aNestLevel+1, "(uvia_min_size %s)\n",
|
||||
FormatInternalUnits( dsnSettings.m_MicroViasMinSize ).c_str() );
|
||||
m_out->Print( aNestLevel+1, "(uvia_min_drill %s)\n",
|
||||
FormatInternalUnits( dsnSettings.m_MicroViasMinDrill ).c_str() );
|
||||
|
||||
m_out->Print( aNestLevel+1, "(max_error %s)\n",
|
||||
FormatInternalUnits( dsnSettings.m_MaxError ).c_str() );
|
||||
|
||||
// Store this option only if it is not the legacy option:
|
||||
if( dsnSettings.m_ZoneUseNoOutlineInFill )
|
||||
m_out->Print( aNestLevel+1, "(filled_areas_thickness no)\n" );
|
||||
|
||||
formatDefaults( dsnSettings, aNestLevel+1 );
|
||||
|
||||
m_out->Print( aNestLevel+1, "(pad_size %s %s)\n",
|
||||
FormatInternalUnits( dsnSettings.m_Pad_Master.GetSize().x ).c_str(),
|
||||
FormatInternalUnits( dsnSettings.m_Pad_Master.GetSize().y ).c_str() );
|
||||
m_out->Print( aNestLevel+1, "(pad_drill %s)\n",
|
||||
FormatInternalUnits( dsnSettings.m_Pad_Master.GetDrillSize().x ).c_str() );
|
||||
|
||||
m_out->Print( aNestLevel+1, "(pad_to_mask_clearance %s)\n",
|
||||
FormatInternalUnits( dsnSettings.m_SolderMaskMargin ).c_str() );
|
||||
|
||||
if( dsnSettings.m_SolderMaskMinWidth )
|
||||
m_out->Print( aNestLevel+1, "(solder_mask_min_width %s)\n",
|
||||
FormatInternalUnits( dsnSettings.m_SolderMaskMinWidth ).c_str() );
|
||||
|
||||
if( dsnSettings.m_SolderPasteMargin != 0 )
|
||||
m_out->Print( aNestLevel+1, "(pad_to_paste_clearance %s)\n",
|
||||
FormatInternalUnits( dsnSettings.m_SolderPasteMargin ).c_str() );
|
||||
|
||||
if( dsnSettings.m_SolderPasteMarginRatio != 0 )
|
||||
m_out->Print( aNestLevel+1, "(pad_to_paste_clearance_ratio %s)\n",
|
||||
Double2Str( dsnSettings.m_SolderPasteMarginRatio ).c_str() );
|
||||
BOARD_DESIGN_SETTINGS& dsnSettings = aBoard->GetDesignSettings();
|
||||
|
||||
if( dsnSettings.m_AuxOrigin != wxPoint( 0, 0 ) )
|
||||
m_out->Print( aNestLevel+1, "(aux_axis_origin %s %s)\n",
|
||||
|
@ -592,71 +493,12 @@ void PCB_IO::formatSetup( BOARD* aBoard, int aNestLevel ) const
|
|||
FormatInternalUnits( dsnSettings.m_GridOrigin.x ).c_str(),
|
||||
FormatInternalUnits( dsnSettings.m_GridOrigin.y ).c_str() );
|
||||
|
||||
m_out->Print( aNestLevel+1, "(visible_elements %X)\n",
|
||||
dsnSettings.GetVisibleElements() );
|
||||
|
||||
aBoard->GetPlotOptions().Format( m_out, aNestLevel+1 );
|
||||
|
||||
m_out->Print( aNestLevel, ")\n\n" );
|
||||
}
|
||||
|
||||
|
||||
void PCB_IO::formatDefaults( const BOARD_DESIGN_SETTINGS& aSettings, int aNestLevel ) const
|
||||
{
|
||||
m_out->Print( aNestLevel, "(defaults\n" );
|
||||
|
||||
m_out->Print( aNestLevel+1, "(edge_clearance %s)\n",
|
||||
FormatInternalUnits( aSettings.m_CopperEdgeClearance ).c_str() );
|
||||
|
||||
m_out->Print( aNestLevel+1, "(edge_cuts_line_width %s)\n",
|
||||
FormatInternalUnits( aSettings.m_LineThickness[ LAYER_CLASS_EDGES ] ).c_str() );
|
||||
|
||||
m_out->Print( aNestLevel+1, "(courtyard_line_width %s)\n",
|
||||
FormatInternalUnits( aSettings.m_LineThickness[ LAYER_CLASS_COURTYARD ] ).c_str() );
|
||||
|
||||
m_out->Print( aNestLevel+1, "(copper_line_width %s)\n",
|
||||
FormatInternalUnits( aSettings.m_LineThickness[ LAYER_CLASS_COPPER ] ).c_str() );
|
||||
m_out->Print( aNestLevel+1, "(copper_text_dims (size %s %s) (thickness %s)%s%s)\n",
|
||||
FormatInternalUnits( aSettings.m_TextSize[ LAYER_CLASS_COPPER ].x ).c_str(),
|
||||
FormatInternalUnits( aSettings.m_TextSize[ LAYER_CLASS_COPPER ].y ).c_str(),
|
||||
FormatInternalUnits( aSettings.m_TextThickness[ LAYER_CLASS_COPPER ] ).c_str(),
|
||||
aSettings.m_TextItalic[ LAYER_CLASS_COPPER ] ? " italic" : "",
|
||||
aSettings.m_TextUpright[ LAYER_CLASS_COPPER ] ? " keep_upright" : "" );
|
||||
|
||||
m_out->Print( aNestLevel+1, "(silk_line_width %s)\n",
|
||||
FormatInternalUnits( aSettings.m_LineThickness[ LAYER_CLASS_SILK ] ).c_str() );
|
||||
m_out->Print( aNestLevel+1, "(silk_text_dims (size %s %s) (thickness %s)%s%s)\n",
|
||||
FormatInternalUnits( aSettings.m_TextSize[ LAYER_CLASS_SILK ].x ).c_str(),
|
||||
FormatInternalUnits( aSettings.m_TextSize[ LAYER_CLASS_SILK ].y ).c_str(),
|
||||
FormatInternalUnits( aSettings.m_TextThickness[ LAYER_CLASS_SILK ] ).c_str(),
|
||||
aSettings.m_TextItalic[ LAYER_CLASS_SILK ] ? " italic" : "",
|
||||
aSettings.m_TextUpright[ LAYER_CLASS_SILK ] ? " keep_upright" : "" );
|
||||
|
||||
m_out->Print( aNestLevel+1, "(fab_layers_line_width %s)\n",
|
||||
FormatInternalUnits( aSettings.m_LineThickness[ LAYER_CLASS_FAB ] ).c_str() );
|
||||
m_out->Print( aNestLevel+1, "(fab_layers_text_dims (size %s %s) (thickness %s)%s%s)\n",
|
||||
FormatInternalUnits( aSettings.m_TextSize[ LAYER_CLASS_FAB ].x ).c_str(),
|
||||
FormatInternalUnits( aSettings.m_TextSize[ LAYER_CLASS_FAB ].y ).c_str(),
|
||||
FormatInternalUnits( aSettings.m_TextThickness[ LAYER_CLASS_FAB ] ).c_str(),
|
||||
aSettings.m_TextItalic[ LAYER_CLASS_OTHERS ] ? " italic" : "",
|
||||
aSettings.m_TextUpright[ LAYER_CLASS_OTHERS ] ? " keep_upright" : "" );
|
||||
|
||||
m_out->Print( aNestLevel+1, "(other_layers_line_width %s)\n",
|
||||
FormatInternalUnits( aSettings.m_LineThickness[ LAYER_CLASS_OTHERS ] ).c_str() );
|
||||
m_out->Print( aNestLevel+1, "(other_layers_text_dims (size %s %s) (thickness %s)%s%s)\n",
|
||||
FormatInternalUnits( aSettings.m_TextSize[ LAYER_CLASS_OTHERS ].x ).c_str(),
|
||||
FormatInternalUnits( aSettings.m_TextSize[ LAYER_CLASS_OTHERS ].y ).c_str(),
|
||||
FormatInternalUnits( aSettings.m_TextThickness[ LAYER_CLASS_OTHERS ] ).c_str(),
|
||||
aSettings.m_TextItalic[ LAYER_CLASS_OTHERS ] ? " italic" : "",
|
||||
aSettings.m_TextUpright[ LAYER_CLASS_OTHERS ] ? " keep_upright" : "" );
|
||||
|
||||
m_out->Print( aNestLevel+1, "(dimension_units %d)\n", aSettings.m_DimensionUnits );
|
||||
m_out->Print( aNestLevel+1, "(dimension_precision %d)\n", aSettings.m_DimensionPrecision );
|
||||
|
||||
m_out->Print( aNestLevel, ")\n" );
|
||||
}
|
||||
|
||||
|
||||
void PCB_IO::formatGeneral( BOARD* aBoard, int aNestLevel ) const
|
||||
{
|
||||
const BOARD_DESIGN_SETTINGS& dsnSettings = aBoard->GetDesignSettings();
|
||||
|
@ -683,7 +525,6 @@ void PCB_IO::formatBoardLayers( BOARD* aBoard, int aNestLevel ) const
|
|||
m_out->Print( aNestLevel, "(layers\n" );
|
||||
|
||||
// Save only the used copper layers from front to back.
|
||||
LSET visible_layers = aBoard->GetVisibleLayers();
|
||||
|
||||
for( LSEQ cu = aBoard->GetEnabledLayers().CuStack(); cu; ++cu )
|
||||
{
|
||||
|
@ -693,9 +534,6 @@ void PCB_IO::formatBoardLayers( BOARD* aBoard, int aNestLevel ) const
|
|||
m_out->Quotew( aBoard->GetLayerName( layer ) ).c_str(),
|
||||
LAYER::ShowType( aBoard->GetLayerType( layer ) ) );
|
||||
|
||||
if( !visible_layers[layer] )
|
||||
m_out->Print( 0, " hide" );
|
||||
|
||||
m_out->Print( 0, ")\n" );
|
||||
}
|
||||
|
||||
|
@ -730,9 +568,6 @@ void PCB_IO::formatBoardLayers( BOARD* aBoard, int aNestLevel ) const
|
|||
m_out->Print( aNestLevel+1, "(%d %s user", layer,
|
||||
m_out->Quotew( aBoard->GetLayerName( layer ) ).c_str() );
|
||||
|
||||
if( !visible_layers[layer] )
|
||||
m_out->Print( 0, " hide" );
|
||||
|
||||
m_out->Print( 0, ")\n" );
|
||||
}
|
||||
|
||||
|
@ -742,7 +577,6 @@ void PCB_IO::formatBoardLayers( BOARD* aBoard, int aNestLevel ) const
|
|||
|
||||
void PCB_IO::formatNetInformation( BOARD* aBoard, int aNestLevel ) const
|
||||
{
|
||||
const BOARD_DESIGN_SETTINGS& dsnSettings = aBoard->GetDesignSettings();
|
||||
for( NETINFO_ITEM* net : *m_mapping )
|
||||
{
|
||||
m_out->Print( aNestLevel, "(net %d %s)\n",
|
||||
|
@ -751,19 +585,6 @@ void PCB_IO::formatNetInformation( BOARD* aBoard, int aNestLevel ) const
|
|||
}
|
||||
|
||||
m_out->Print( 0, "\n" );
|
||||
|
||||
// Save the default net class first.
|
||||
NETCLASS defaultNC = *dsnSettings.GetDefault();
|
||||
filterNetClass( *aBoard, defaultNC ); // Remove empty nets (from a copy of a netclass)
|
||||
defaultNC.Format( m_out, aNestLevel, m_ctl );
|
||||
|
||||
// Save the rest of the net classes alphabetically.
|
||||
for( const auto& it : dsnSettings.m_NetClasses )
|
||||
{
|
||||
NETCLASS netclass = *it.second;
|
||||
filterNetClass( *aBoard, netclass ); // Remove empty nets (from a copy of a netclass)
|
||||
netclass.Format( m_out, aNestLevel, m_ctl );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -70,7 +70,8 @@ class TEXTE_PCB;
|
|||
//#define SEXPR_BOARD_FILE_VERSION 20200512 // page -> paper
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20200518 // save hole_to_hole_min
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20200614 // Add support for fp_rects and gr_rects
|
||||
#define SEXPR_BOARD_FILE_VERSION 20200625 // Multilayer zones, zone names, island controls
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20200625 // Multilayer zones, zone names, island controls
|
||||
#define SEXPR_BOARD_FILE_VERSION 20200628 // remove visibility settings
|
||||
|
||||
#define CTL_STD_LAYER_NAMES (1 << 0) ///< Use English Standard layer names
|
||||
#define CTL_OMIT_NETS (1 << 1) ///< Omit pads net names (useless in library)
|
||||
|
@ -216,9 +217,6 @@ protected:
|
|||
/// formats the board setup information
|
||||
void formatSetup( BOARD* aBoard, int aNestLevel = 0 ) const;
|
||||
|
||||
/// formats the defaults subsection of the board setup
|
||||
void formatDefaults( const BOARD_DESIGN_SETTINGS& aSettings, int aNestLevel ) const;
|
||||
|
||||
/// formats the General section of the file
|
||||
void formatGeneral( BOARD* aBoard, int aNestLevel = 0 ) const;
|
||||
|
||||
|
|
|
@ -832,14 +832,14 @@ void LEGACY_PLUGIN::loadSHEET()
|
|||
|
||||
void LEGACY_PLUGIN::loadSETUP()
|
||||
{
|
||||
NETCLASS* netclass_default = m_board->GetDesignSettings().GetDefault();
|
||||
// TODO Orson: is it really necessary to first operate on a copy and then apply it?
|
||||
// would not it be better to use reference here and apply all the changes instantly?
|
||||
BOARD_DESIGN_SETTINGS bds = m_board->GetDesignSettings();
|
||||
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
|
||||
ZONE_SETTINGS zs = m_board->GetZoneSettings();
|
||||
NETCLASS* netclass_default = bds.GetDefault();
|
||||
char* line;
|
||||
char* saveptr;
|
||||
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
|
||||
while( ( line = READLINE( m_reader ) ) != NULL )
|
||||
{
|
||||
const char* data;
|
||||
|
@ -1118,12 +1118,17 @@ void LEGACY_PLUGIN::loadSETUP()
|
|||
else if( TESTLINE( "VisibleElements" ) )
|
||||
{
|
||||
int visibleElements = hexParse( line + SZ( "VisibleElements" ) );
|
||||
bds.SetVisibleElements( visibleElements );
|
||||
|
||||
GAL_SET visibles;
|
||||
|
||||
for( size_t i = 0; i < visibles.size(); i++ )
|
||||
visibles.set( i, visibleElements & ( 1u << i ) );
|
||||
|
||||
m_board->SetVisibleElements( visibles );
|
||||
}
|
||||
|
||||
else if( TESTLINE( "$EndSETUP" ) )
|
||||
{
|
||||
m_board->SetDesignSettings( bds );
|
||||
m_board->SetZoneSettings( zs );
|
||||
|
||||
// Very old *.brd file does not have NETCLASSes
|
||||
|
@ -2399,7 +2404,7 @@ void LEGACY_PLUGIN::loadNETCLASS()
|
|||
|
||||
else if( TESTLINE( "$EndNCLASS" ) )
|
||||
{
|
||||
if( !m_board->GetDesignSettings().m_NetClasses.Add( nc ) )
|
||||
if( !m_board->GetDesignSettings().GetNetClasses().Add( nc ) )
|
||||
{
|
||||
// Must have been a name conflict, this is a bad board file.
|
||||
// User may have done a hand edit to the file.
|
||||
|
|
|
@ -56,7 +56,7 @@ NETINFO_ITEM::NETINFO_ITEM( BOARD* aParent, const wxString& aNetName, int aNetCo
|
|||
m_parent = aParent;
|
||||
|
||||
if( aParent )
|
||||
m_NetClass = aParent->GetDesignSettings().m_NetClasses.GetDefault();
|
||||
m_NetClass = aParent->GetDesignSettings().GetNetClasses().GetDefault();
|
||||
else
|
||||
m_NetClass = std::make_shared<NETCLASS>( "<invalid>" );
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ NETINFO_ITEM::~NETINFO_ITEM()
|
|||
void NETINFO_ITEM::SetClass( const NETCLASSPTR& aNetClass )
|
||||
{
|
||||
wxCHECK( m_parent, /* void */ );
|
||||
m_NetClass = aNetClass ? aNetClass : m_parent->GetDesignSettings().m_NetClasses.GetDefault();
|
||||
m_NetClass = aNetClass ? aNetClass : m_parent->GetDesignSettings().GetNetClasses().GetDefault();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ using namespace std::placeholders;
|
|||
#include <tool/tool_manager.h>
|
||||
#include <tools/pcb_actions.h>
|
||||
#include <tools/selection_tool.h>
|
||||
#include <project/project_file.h> // LAST_PATH_TYPE
|
||||
#include <view/view.h>
|
||||
|
||||
extern void SpreadFootprints( std::vector<MODULE*>* aFootprints,
|
||||
|
|
|
@ -136,7 +136,6 @@ void PCB_BASE_FRAME::SetBoard( BOARD* aBoard )
|
|||
{
|
||||
delete m_Pcb;
|
||||
m_Pcb = aBoard;
|
||||
m_Pcb->SetGeneralSettings( m_Settings );
|
||||
|
||||
wxCommandEvent e( BOARD_CHANGED );
|
||||
ProcessEventLocally( e );
|
||||
|
@ -277,13 +276,6 @@ BOARD_DESIGN_SETTINGS& PCB_BASE_FRAME::GetDesignSettings() const
|
|||
}
|
||||
|
||||
|
||||
void PCB_BASE_FRAME::SetDesignSettings( const BOARD_DESIGN_SETTINGS& aSettings )
|
||||
{
|
||||
wxASSERT( m_Pcb );
|
||||
m_Pcb->SetDesignSettings( aSettings );
|
||||
}
|
||||
|
||||
|
||||
void PCB_BASE_FRAME::SetDrawBgColor( COLOR4D aColor )
|
||||
{
|
||||
m_drawBgColor= aColor;
|
||||
|
@ -294,14 +286,14 @@ void PCB_BASE_FRAME::SetDrawBgColor( COLOR4D aColor )
|
|||
const ZONE_SETTINGS& PCB_BASE_FRAME::GetZoneSettings() const
|
||||
{
|
||||
wxASSERT( m_Pcb );
|
||||
return m_Pcb->GetZoneSettings();
|
||||
return m_Pcb->GetDesignSettings().GetDefaultZoneSettings();
|
||||
}
|
||||
|
||||
|
||||
void PCB_BASE_FRAME::SetZoneSettings( const ZONE_SETTINGS& aSettings )
|
||||
{
|
||||
wxASSERT( m_Pcb );
|
||||
m_Pcb->SetZoneSettings( aSettings );
|
||||
m_Pcb->GetDesignSettings().SetDefaultZoneSettings( aSettings );
|
||||
}
|
||||
|
||||
|
||||
|
@ -735,8 +727,6 @@ void PCB_BASE_FRAME::ActivateGalCanvas()
|
|||
GetCanvas()->GetViewControls(), config(), this );
|
||||
}
|
||||
|
||||
SetBoard( m_Pcb );
|
||||
|
||||
if( m_toolManager )
|
||||
m_toolManager->ResetTools( TOOL_BASE::GAL_SWITCH );
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include <kicad_string.h>
|
||||
#include <pcb_draw_panel_gal.h>
|
||||
#include <functional>
|
||||
#include <project/project_file.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tool/tool_dispatcher.h>
|
||||
|
@ -369,6 +370,9 @@ PCB_EDIT_FRAME::~PCB_EDIT_FRAME()
|
|||
|
||||
void PCB_EDIT_FRAME::SetBoard( BOARD* aBoard )
|
||||
{
|
||||
if( m_Pcb )
|
||||
m_Pcb->ClearProject();
|
||||
|
||||
PCB_BASE_EDIT_FRAME::SetBoard( aBoard );
|
||||
|
||||
aBoard->SetProject( &Prj() );
|
||||
|
@ -497,39 +501,42 @@ void PCB_EDIT_FRAME::OnQuit( wxCommandEvent& event )
|
|||
|
||||
void PCB_EDIT_FRAME::RecordDRCExclusions()
|
||||
{
|
||||
m_drcExclusions.clear();
|
||||
BOARD_DESIGN_SETTINGS& bds = GetBoard()->GetDesignSettings();
|
||||
bds.m_DrcExclusions.clear();
|
||||
|
||||
for( MARKER_PCB* marker : GetBoard()->Markers() )
|
||||
{
|
||||
if( marker->IsExcluded() )
|
||||
m_drcExclusions.insert( marker->Serialize() );
|
||||
bds.m_DrcExclusions.insert( marker->Serialize() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PCB_EDIT_FRAME::ResolveDRCExclusions()
|
||||
{
|
||||
BOARD_DESIGN_SETTINGS& bds = GetBoard()->GetDesignSettings();
|
||||
|
||||
for( MARKER_PCB* marker : GetBoard()->Markers() )
|
||||
{
|
||||
auto i = m_drcExclusions.find( marker->Serialize() );
|
||||
auto i = bds.m_DrcExclusions.find( marker->Serialize() );
|
||||
|
||||
if( i != m_drcExclusions.end() )
|
||||
if( i != bds.m_DrcExclusions.end() )
|
||||
{
|
||||
marker->SetExcluded( true );
|
||||
m_drcExclusions.erase( i );
|
||||
bds.m_DrcExclusions.erase( i );
|
||||
}
|
||||
}
|
||||
|
||||
BOARD_COMMIT commit( this );
|
||||
|
||||
for( const wxString& exclusionData : m_drcExclusions )
|
||||
for( const wxString& exclusionData : bds.m_DrcExclusions )
|
||||
{
|
||||
MARKER_PCB* marker = MARKER_PCB::Deserialize( exclusionData );
|
||||
marker->SetExcluded( true );
|
||||
commit.Add( marker );
|
||||
}
|
||||
|
||||
m_drcExclusions.clear();
|
||||
bds.m_DrcExclusions.clear();
|
||||
|
||||
commit.Push( wxEmptyString, false, false );
|
||||
}
|
||||
|
@ -847,10 +854,12 @@ void PCB_EDIT_FRAME::ShowChangedLanguage()
|
|||
|
||||
wxString PCB_EDIT_FRAME::GetLastPath( LAST_PATH_TYPE aType )
|
||||
{
|
||||
if( m_lastPath[ aType ].IsEmpty() )
|
||||
PROJECT_FILE& project = Prj().GetProjectFile();
|
||||
|
||||
if( project.m_PcbLastPath[ aType ].IsEmpty() )
|
||||
return wxEmptyString;
|
||||
|
||||
wxFileName absoluteFileName = m_lastPath[ aType ];
|
||||
wxFileName absoluteFileName = project.m_PcbLastPath[ aType ];
|
||||
wxFileName pcbFileName = GetBoard()->GetFileName();
|
||||
|
||||
absoluteFileName.MakeAbsolute( pcbFileName.GetPath() );
|
||||
|
@ -860,14 +869,16 @@ wxString PCB_EDIT_FRAME::GetLastPath( LAST_PATH_TYPE aType )
|
|||
|
||||
void PCB_EDIT_FRAME::SetLastPath( LAST_PATH_TYPE aType, const wxString& aLastPath )
|
||||
{
|
||||
PROJECT_FILE& project = Prj().GetProjectFile();
|
||||
|
||||
wxFileName relativeFileName = aLastPath;
|
||||
wxFileName pcbFileName = GetBoard()->GetFileName();
|
||||
|
||||
relativeFileName.MakeRelativeTo( pcbFileName.GetPath() );
|
||||
|
||||
if( relativeFileName.GetFullPath() != m_lastPath[ aType ] )
|
||||
if( relativeFileName.GetFullPath() != project.m_PcbLastPath[ aType ] )
|
||||
{
|
||||
m_lastPath[ aType ] = relativeFileName.GetFullPath();
|
||||
project.m_PcbLastPath[ aType ] = relativeFileName.GetFullPath();
|
||||
SaveProjectSettings();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include <unordered_map>
|
||||
#include <map>
|
||||
#include "pcb_base_edit_frame.h"
|
||||
#include "config_params.h"
|
||||
#include "undo_redo_container.h"
|
||||
#include "zones.h"
|
||||
|
||||
|
@ -60,6 +59,7 @@ class IO_ERROR;
|
|||
class FP_LIB_TABLE;
|
||||
class BOARD_NETLIST_UPDATER;
|
||||
class ACTION_MENU;
|
||||
enum LAST_PATH_TYPE : unsigned int;
|
||||
|
||||
namespace PCB { struct IFACE; } // KIFACE_I is in pcbnew.cpp
|
||||
|
||||
|
@ -73,18 +73,6 @@ enum TRACK_ACTION_RESULT
|
|||
TRACK_ACTION_NONE //!< TRACK_ACTION_NONE - Nothing to change
|
||||
};
|
||||
|
||||
enum LAST_PATH_TYPE
|
||||
{
|
||||
LAST_PATH_NETLIST = 0,
|
||||
LAST_PATH_STEP,
|
||||
LAST_PATH_IDF,
|
||||
LAST_PATH_VRML,
|
||||
LAST_PATH_SPECCTRADSN,
|
||||
LAST_PATH_GENCAD,
|
||||
|
||||
LAST_PATH_SIZE
|
||||
};
|
||||
|
||||
/**
|
||||
* PCB_EDIT_FRAME
|
||||
* is the main frame for Pcbnew.
|
||||
|
@ -102,11 +90,6 @@ class PCB_EDIT_FRAME : public PCB_BASE_EDIT_FRAME
|
|||
ACTION_TOOLBAR* m_microWaveToolBar;
|
||||
|
||||
protected:
|
||||
std::vector<PARAM_CFG*> m_projectFileParams;
|
||||
|
||||
wxString m_lastPath[ LAST_PATH_SIZE ];
|
||||
|
||||
std::set<wxString> m_drcExclusions;
|
||||
|
||||
/**
|
||||
* Store the previous layer toolbar icon state information
|
||||
|
@ -377,20 +360,6 @@ public:
|
|||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Function GetProjectFileParameters
|
||||
* returns a project file parameter list for Pcbnew.
|
||||
* <p>
|
||||
* Populate a project file parameter array specific to Pcbnew.
|
||||
* Creating the parameter list at run time has the advantage of being able
|
||||
* to define local variables. The old method of statically building the array
|
||||
* at compile time requiring global variable definitions by design.
|
||||
* </p>
|
||||
* @return std::vector<PARAM_CFG*> - it is only good until SetBoard() is called, so
|
||||
* don't keep it around past that event.
|
||||
*/
|
||||
std::vector<PARAM_CFG*>& GetProjectFileParameters();
|
||||
|
||||
/**
|
||||
* Function SaveProjectSettings
|
||||
* saves changes to the project settings to the project (.pro) file.
|
||||
|
|
|
@ -331,7 +331,6 @@ void PCB_LAYER_WIDGET::SetLayersManagerTabsText()
|
|||
void PCB_LAYER_WIDGET::ReFillRender()
|
||||
{
|
||||
BOARD* board = myframe->GetBoard();
|
||||
auto settings = board->GetDesignSettings();
|
||||
|
||||
ClearRenderRows();
|
||||
|
||||
|
@ -346,17 +345,6 @@ void PCB_LAYER_WIDGET::ReFillRender()
|
|||
if( m_fp_editor_mode && !isAllowedInFpMode( renderRow.id ) )
|
||||
continue;
|
||||
|
||||
// Don't remove microvia and bblind vias if they're not allowed: that's only a DRC
|
||||
// setting (which might be set to ignore) and the user can add them irrespective of
|
||||
// the setting.
|
||||
/*
|
||||
if( renderRow.id == LAYER_VIA_MICROVIA && !settings.m_MicroViasAllowed )
|
||||
continue;
|
||||
|
||||
if( renderRow.id == LAYER_VIA_BBLIND && !settings.m_BlindBuriedViaAllowed )
|
||||
continue;
|
||||
*/
|
||||
|
||||
if( !renderRow.spacer )
|
||||
{
|
||||
renderRow.tooltip = wxGetTranslation( s_render_rows[row].tooltip );
|
||||
|
@ -640,10 +628,6 @@ void PCB_LAYER_WIDGET::OnLayerVisible( int aLayer, bool isVisible, bool isFinal
|
|||
|
||||
brd->SetVisibleLayers( visibleLayers );
|
||||
|
||||
// Layer visibility is not stored in .kicad_mod files
|
||||
if( !m_fp_editor_mode )
|
||||
myframe->OnModify();
|
||||
|
||||
if( myframe->GetCanvas() )
|
||||
myframe->GetCanvas()->GetView()->SetLayerVisible( aLayer, isVisible );
|
||||
}
|
||||
|
@ -685,14 +669,6 @@ void PCB_LAYER_WIDGET::OnRenderEnable( int aId, bool isEnabled )
|
|||
BOARD* brd = myframe->GetBoard();
|
||||
wxASSERT( aId > GAL_LAYER_ID_START && aId < GAL_LAYER_ID_END );
|
||||
|
||||
if( myframe->IsType( FRAME_PCB_EDITOR ) )
|
||||
{
|
||||
// The layer visibility status is saved in the board file so set the board
|
||||
// modified state so the user has the option to save the changes.
|
||||
if( brd->IsElementVisible( static_cast<GAL_LAYER_ID>( aId ) ) != isEnabled )
|
||||
myframe->OnModify();
|
||||
}
|
||||
|
||||
// Grid is not set through the board visibility
|
||||
if( aId == LAYER_GRID )
|
||||
myframe->SetGridVisibility( isEnabled );
|
||||
|
|
|
@ -577,6 +577,7 @@ BOARD* PCB_PARSER::parseBOARD_unchecked()
|
|||
|
||||
case T_net_class:
|
||||
parseNETCLASS();
|
||||
m_board->m_LegacyNetclassesLoaded = true;
|
||||
break;
|
||||
|
||||
case T_gr_arc:
|
||||
|
@ -1253,6 +1254,7 @@ void PCB_PARSER::parseLayers()
|
|||
LSET enabledLayers;
|
||||
int copperLayerCount = 0;
|
||||
LAYER layer;
|
||||
bool anyHidden = false;
|
||||
|
||||
std::unordered_map< std::string, std::string > v3_layer_names;
|
||||
std::vector<LAYER> cu;
|
||||
|
@ -1292,6 +1294,8 @@ void PCB_PARSER::parseLayers()
|
|||
|
||||
if( it->m_visible )
|
||||
visibleLayers.set( it->m_number );
|
||||
else
|
||||
anyHidden = true;
|
||||
|
||||
m_board->SetLayerDescr( PCB_LAYER_ID( it->m_number ), *it );
|
||||
|
||||
|
@ -1341,6 +1345,8 @@ void PCB_PARSER::parseLayers()
|
|||
|
||||
if( layer.m_visible )
|
||||
visibleLayers.set( layer.m_number );
|
||||
else
|
||||
anyHidden = true;
|
||||
|
||||
m_board->SetLayerDescr( it->second, layer );
|
||||
|
||||
|
@ -1364,8 +1370,10 @@ void PCB_PARSER::parseLayers()
|
|||
m_board->SetCopperLayerCount( copperLayerCount );
|
||||
m_board->SetEnabledLayers( enabledLayers );
|
||||
|
||||
// call SetEnabledLayers before SetVisibleLayers()
|
||||
m_board->SetVisibleLayers( visibleLayers );
|
||||
// Only set this if any layers were explicitly marked as hidden. Otherwise, we want to leave
|
||||
// this alone; default visibility will show everything
|
||||
if( anyHidden )
|
||||
m_board->m_LegacyVisibleLayers = visibleLayers;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1435,7 +1443,7 @@ void PCB_PARSER::parseSetup()
|
|||
T token;
|
||||
NETCLASS* defaultNetClass = m_board->GetDesignSettings().GetDefault();
|
||||
BOARD_DESIGN_SETTINGS& designSettings = m_board->GetDesignSettings();
|
||||
ZONE_SETTINGS zoneSettings = m_board->GetZoneSettings();
|
||||
ZONE_SETTINGS& zoneSettings = designSettings.GetDefaultZoneSettings();
|
||||
|
||||
// Missing soldermask min width value means that the user has set the value to 0 and
|
||||
// not the default value (0.25mm)
|
||||
|
@ -1461,67 +1469,80 @@ void PCB_PARSER::parseSetup()
|
|||
|
||||
case T_user_trace_width:
|
||||
designSettings.m_TrackWidthList.push_back( parseBoardUnits( T_user_trace_width ) );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_trace_clearance:
|
||||
defaultNetClass->SetClearance( parseBoardUnits( T_trace_clearance ) );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_zone_clearance:
|
||||
zoneSettings.m_ZoneClearance = parseBoardUnits( T_zone_clearance );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_zone_45_only:
|
||||
zoneSettings.m_Zone_45_Only = parseBool();
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_clearance_min:
|
||||
designSettings.m_MinClearance = parseBoardUnits( T_clearance_min );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_trace_min:
|
||||
designSettings.m_TrackMinWidth = parseBoardUnits( T_trace_min );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_via_size:
|
||||
defaultNetClass->SetViaDiameter( parseBoardUnits( T_via_size ) );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_via_drill:
|
||||
defaultNetClass->SetViaDrill( parseBoardUnits( T_via_drill ) );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_via_min_annulus:
|
||||
designSettings.m_ViasMinAnnulus = parseBoardUnits( T_via_min_annulus );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_via_min_size:
|
||||
designSettings.m_ViasMinSize = parseBoardUnits( T_via_min_size );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_through_hole_min:
|
||||
designSettings.m_MinThroughDrill = parseBoardUnits( T_through_hole_min );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
// Legacy token for T_through_hole_min
|
||||
case T_via_min_drill:
|
||||
designSettings.m_MinThroughDrill = parseBoardUnits( T_via_min_drill );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_hole_to_hole_min:
|
||||
designSettings.m_HoleToHoleMin = parseBoardUnits( T_hole_to_hole_min );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
|
@ -1530,37 +1551,44 @@ void PCB_PARSER::parseSetup()
|
|||
int viaSize = parseBoardUnits( "user via size" );
|
||||
int viaDrill = parseBoardUnits( "user via drill" );
|
||||
designSettings.m_ViasDimensionsList.emplace_back( VIA_DIMENSION( viaSize, viaDrill ) );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
}
|
||||
break;
|
||||
|
||||
case T_uvia_size:
|
||||
defaultNetClass->SetuViaDiameter( parseBoardUnits( T_uvia_size ) );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_uvia_drill:
|
||||
defaultNetClass->SetuViaDrill( parseBoardUnits( T_uvia_drill ) );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_uvias_allowed:
|
||||
designSettings.m_MicroViasAllowed = parseBool();
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_blind_buried_vias_allowed:
|
||||
designSettings.m_BlindBuriedViaAllowed = parseBool();
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_uvia_min_size:
|
||||
designSettings.m_MicroViasMinSize = parseBoardUnits( T_uvia_min_size );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_uvia_min_drill:
|
||||
designSettings.m_MicroViasMinDrill = parseBoardUnits( T_uvia_min_drill );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
|
@ -1570,49 +1598,58 @@ void PCB_PARSER::parseSetup()
|
|||
int gap = parseBoardUnits( "user diff-pair gap" );
|
||||
int viaGap = parseBoardUnits( "user diff-pair via gap" );
|
||||
designSettings.m_DiffPairDimensionsList.emplace_back( DIFF_PAIR_DIMENSION( width, gap, viaGap ) );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
}
|
||||
break;
|
||||
|
||||
case T_segment_width: // note: legacy (pre-6.0) token
|
||||
designSettings.m_LineThickness[ LAYER_CLASS_COPPER ] = parseBoardUnits( T_segment_width );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_edge_width: // note: legacy (pre-6.0) token
|
||||
designSettings.m_LineThickness[ LAYER_CLASS_EDGES ] = parseBoardUnits( T_edge_width );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_mod_edge_width: // note: legacy (pre-6.0) token
|
||||
designSettings.m_LineThickness[ LAYER_CLASS_SILK ] = parseBoardUnits( T_mod_edge_width );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_pcb_text_width: // note: legacy (pre-6.0) token
|
||||
designSettings.m_TextThickness[ LAYER_CLASS_COPPER ] = parseBoardUnits( T_pcb_text_width );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_mod_text_width: // note: legacy (pre-6.0) token
|
||||
designSettings.m_TextThickness[ LAYER_CLASS_SILK ] = parseBoardUnits( T_mod_text_width );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_pcb_text_size: // note: legacy (pre-6.0) token
|
||||
designSettings.m_TextSize[ LAYER_CLASS_COPPER ].x = parseBoardUnits( "pcb text width" );
|
||||
designSettings.m_TextSize[ LAYER_CLASS_COPPER ].y = parseBoardUnits( "pcb text height" );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_mod_text_size: // note: legacy (pre-6.0) token
|
||||
designSettings.m_TextSize[ LAYER_CLASS_SILK ].x = parseBoardUnits( "module text width" );
|
||||
designSettings.m_TextSize[ LAYER_CLASS_SILK ].y = parseBoardUnits( "module text height" );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_defaults:
|
||||
parseDefaults( designSettings );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
break;
|
||||
|
||||
case T_pad_size:
|
||||
|
@ -1621,6 +1658,7 @@ void PCB_PARSER::parseSetup()
|
|||
sz.SetWidth( parseBoardUnits( "master pad width" ) );
|
||||
sz.SetHeight( parseBoardUnits( "master pad height" ) );
|
||||
designSettings.m_Pad_Master.SetSize( sz );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
}
|
||||
break;
|
||||
|
@ -1629,27 +1667,32 @@ void PCB_PARSER::parseSetup()
|
|||
{
|
||||
int drillSize = parseBoardUnits( T_pad_drill );
|
||||
designSettings.m_Pad_Master.SetDrillSize( wxSize( drillSize, drillSize ) );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
}
|
||||
break;
|
||||
|
||||
case T_pad_to_mask_clearance:
|
||||
designSettings.m_SolderMaskMargin = parseBoardUnits( T_pad_to_mask_clearance );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_solder_mask_min_width:
|
||||
designSettings.m_SolderMaskMinWidth = parseBoardUnits( T_solder_mask_min_width );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_pad_to_paste_clearance:
|
||||
designSettings.m_SolderPasteMargin = parseBoardUnits( T_pad_to_paste_clearance );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_pad_to_paste_clearance_ratio:
|
||||
designSettings.m_SolderPasteMarginRatio = parseDouble( T_pad_to_paste_clearance_ratio );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
|
@ -1657,8 +1700,9 @@ void PCB_PARSER::parseSetup()
|
|||
{
|
||||
int x = parseBoardUnits( "auxiliary origin X" );
|
||||
int y = parseBoardUnits( "auxiliary origin Y" );
|
||||
// m_board->SetAuxOrigin( wxPoint( x, y ) ); gets overwritten via SetDesignSettings below
|
||||
designSettings.m_AuxOrigin = wxPoint( x, y );
|
||||
// Aux origin still stored in board for the moment
|
||||
//m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
}
|
||||
break;
|
||||
|
@ -1667,24 +1711,36 @@ void PCB_PARSER::parseSetup()
|
|||
{
|
||||
int x = parseBoardUnits( "grid origin X" );
|
||||
int y = parseBoardUnits( "grid origin Y" );
|
||||
// m_board->SetGridOrigin( wxPoint( x, y ) ); gets overwritten SetDesignSettings below
|
||||
designSettings.m_GridOrigin = wxPoint( x, y );
|
||||
// Grid origin still stored in board for the moment
|
||||
//m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
}
|
||||
break;
|
||||
|
||||
// Stored in board prior to 6.0
|
||||
case T_visible_elements:
|
||||
designSettings.SetVisibleElements( parseHex() | MIN_VISIBILITY_MASK );
|
||||
{
|
||||
m_board->m_LegacyVisibleItems.reset();
|
||||
|
||||
int visible = parseHex() | MIN_VISIBILITY_MASK;
|
||||
|
||||
for( size_t i = 0; i < sizeof( int ) * CHAR_BIT; i++ )
|
||||
m_board->m_LegacyVisibleItems.set( i, visible & ( 1u << i ) );
|
||||
|
||||
NeedRIGHT();
|
||||
}
|
||||
break;
|
||||
|
||||
case T_max_error:
|
||||
designSettings.m_MaxError = parseBoardUnits( T_max_error );
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_filled_areas_thickness:
|
||||
designSettings.m_ZoneUseNoOutlineInFill = not parseBool();
|
||||
m_board->m_LegacyDesignSettingsLoaded = true;
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
|
@ -1707,9 +1763,6 @@ void PCB_PARSER::parseSetup()
|
|||
Unexpected( CurText() );
|
||||
}
|
||||
}
|
||||
|
||||
//m_board->SetDesignSettings( designSettings );
|
||||
m_board->SetZoneSettings( zoneSettings );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1925,7 +1978,7 @@ void PCB_PARSER::parseNETCLASS()
|
|||
NeedRIGHT();
|
||||
}
|
||||
|
||||
if( !m_board->GetDesignSettings().m_NetClasses.Add( nc ) )
|
||||
if( !m_board->GetDesignSettings().GetNetClasses().Add( nc ) )
|
||||
{
|
||||
// Must have been a name conflict, this is a bad board file.
|
||||
// User may have done a hand edit to the file.
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include <invoke_pcb_dialog.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
#include <widgets/paged_dialog.h>
|
||||
#include <project/project_file.h>
|
||||
|
||||
|
||||
void PCB_EDIT_FRAME::On3DShapeLibWizard( wxCommandEvent& event )
|
||||
|
@ -77,7 +78,9 @@ bool PCB_EDIT_FRAME::LoadProjectSettings()
|
|||
{
|
||||
wxLogDebug( wxT( "Loading project '%s' settings." ), GetChars( Prj().GetProjectFullName() ) );
|
||||
|
||||
bool rc = Prj().ConfigLoad( Kiface().KifaceSearch(), GROUP_PCB, GetProjectFileParameters() );
|
||||
PROJECT_FILE& project = Prj().GetProjectFile();
|
||||
|
||||
BASE_SCREEN::m_PageLayoutDescrFileName = project.m_PageLayoutDescrFile;
|
||||
|
||||
// Load the page layout decr file, from the filename stored in
|
||||
// BASE_SCREEN::m_PageLayoutDescrFileName, read in config project file
|
||||
|
@ -88,7 +91,7 @@ bool PCB_EDIT_FRAME::LoadProjectSettings()
|
|||
|
||||
pglayout.SetPageLayout( filename );
|
||||
|
||||
return rc;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -105,45 +108,12 @@ void PCB_EDIT_FRAME::SaveProjectSettings()
|
|||
if( !IsWritable( fn ) )
|
||||
return;
|
||||
|
||||
wxString pro_name = fn.GetFullPath();
|
||||
PROJECT_FILE& project = Prj().GetProjectFile();
|
||||
|
||||
// TODO: Can this be pulled out of BASE_SCREEN?
|
||||
project.m_PageLayoutDescrFile = BASE_SCREEN::m_PageLayoutDescrFileName;
|
||||
|
||||
RecordDRCExclusions();
|
||||
Prj().ConfigSave( Kiface().KifaceSearch(), GROUP_PCB, GetProjectFileParameters(), pro_name );
|
||||
}
|
||||
|
||||
|
||||
std::vector<PARAM_CFG*>& PCB_EDIT_FRAME::GetProjectFileParameters()
|
||||
{
|
||||
m_projectFileParams.clear();
|
||||
|
||||
// This one cannot be cached because some settings are going to/from the BOARD,
|
||||
// so pointers into that cannot be saved for long.
|
||||
|
||||
m_projectFileParams.push_back( new PARAM_CFG_FILENAME( wxT( "PageLayoutDescrFile" ),
|
||||
&BASE_SCREEN::m_PageLayoutDescrFileName ) );
|
||||
|
||||
m_projectFileParams.push_back( new PARAM_CFG_FILENAME( wxT( "LastNetListRead" ),
|
||||
&m_lastPath[ LAST_PATH_NETLIST ] ) );
|
||||
|
||||
m_projectFileParams.push_back( new PARAM_CFG_FILENAME( wxT( "LastSTEPExportPath" ),
|
||||
&m_lastPath[ LAST_PATH_STEP ] ) );
|
||||
|
||||
m_projectFileParams.push_back( new PARAM_CFG_FILENAME( wxT( "LastIDFExportPath" ),
|
||||
&m_lastPath[ LAST_PATH_IDF ] ) );
|
||||
|
||||
m_projectFileParams.push_back( new PARAM_CFG_FILENAME( wxT( "LastVRMLExportPath" ),
|
||||
&m_lastPath[ LAST_PATH_VRML ] ) );
|
||||
|
||||
m_projectFileParams.push_back( new PARAM_CFG_FILENAME( wxT( "LastSpecctraDSNExportPath" ),
|
||||
&m_lastPath[ LAST_PATH_SPECCTRADSN ] ) );
|
||||
|
||||
m_projectFileParams.push_back( new PARAM_CFG_FILENAME( wxT( "LastGenCADExportPath" ),
|
||||
&m_lastPath[ LAST_PATH_GENCAD ] ) );
|
||||
|
||||
m_projectFileParams.push_back( new PARAM_CFG_WXSTRING_SET( wxT( "DRCExclusion" ),
|
||||
&m_drcExclusions ) );
|
||||
|
||||
GetBoard()->GetDesignSettings().AppendConfigs( GetBoard(), &m_projectFileParams);
|
||||
|
||||
return m_projectFileParams;
|
||||
|
||||
GetSettingsManager()->SaveProject();
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ PNS_PCBNEW_RULE_RESOLVER::PNS_PCBNEW_RULE_RESOLVER( BOARD* aBoard, PNS::ROUTER*
|
|||
ent.coupledNet = DpCoupledNet( i );
|
||||
|
||||
wxString netClassName = ni->GetClassName();
|
||||
NETCLASSPTR nc = m_board->GetDesignSettings().m_NetClasses.Find( netClassName );
|
||||
NETCLASSPTR nc = m_board->GetDesignSettings().GetNetClasses().Find( netClassName );
|
||||
|
||||
int clearance = nc->GetClearance();
|
||||
ent.clearance = clearance;
|
||||
|
@ -154,7 +154,7 @@ PNS_PCBNEW_RULE_RESOLVER::PNS_PCBNEW_RULE_RESOLVER( BOARD* aBoard, PNS::ROUTER*
|
|||
}
|
||||
}
|
||||
|
||||
auto defaultRule = m_board->GetDesignSettings().m_NetClasses.Find ("Default");
|
||||
auto defaultRule = m_board->GetDesignSettings().GetNetClasses().Find ("Default");
|
||||
|
||||
if( defaultRule )
|
||||
{
|
||||
|
|
|
@ -89,12 +89,12 @@ void SIZES_SETTINGS::Init( BOARD* aBoard, ITEM* aStartItem, int aNet )
|
|||
if( ni )
|
||||
{
|
||||
wxString netClassName = ni->GetClassName();
|
||||
netClass = bds.m_NetClasses.Find( netClassName );
|
||||
netClass = bds.GetNetClasses().Find( netClassName );
|
||||
}
|
||||
}
|
||||
|
||||
if( !netClass )
|
||||
netClass = bds.m_NetClasses.GetDefault();
|
||||
netClass = bds.GetNetClasses().GetDefault();
|
||||
|
||||
m_trackWidth = 0;
|
||||
|
||||
|
|
|
@ -1430,7 +1430,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
|
|||
|
||||
//-----< output vias used in netclasses >-----------------------------------
|
||||
{
|
||||
NETCLASSES& nclasses = aBoard->GetDesignSettings().m_NetClasses;
|
||||
NETCLASSES& nclasses = aBoard->GetDesignSettings().GetNetClasses();
|
||||
|
||||
// Assume the netclass vias are all the same kind of thru, blind, or buried vias.
|
||||
// This is in lieu of either having each netclass via have its own layer pair in
|
||||
|
@ -1641,7 +1641,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
|
|||
|
||||
|
||||
//-----<output NETCLASSs>----------------------------------------------------
|
||||
NETCLASSES& nclasses = aBoard->GetDesignSettings().m_NetClasses;
|
||||
NETCLASSES& nclasses = aBoard->GetDesignSettings().GetNetClasses();
|
||||
|
||||
exportNETCLASS( nclasses.GetDefault(), aBoard );
|
||||
|
||||
|
|
|
@ -499,7 +499,7 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard )
|
|||
GetChars( psid ) ) );
|
||||
}
|
||||
|
||||
NETCLASSPTR netclass = aBoard->GetDesignSettings().m_NetClasses.GetDefault();
|
||||
NETCLASSPTR netclass = aBoard->GetDesignSettings().GetNetClasses().GetDefault();
|
||||
|
||||
int via_drill_default = netclass->GetViaDrill();
|
||||
|
||||
|
|
|
@ -96,11 +96,16 @@ HANDLE_EXCEPTIONS(BOARD::TracksInNetBetweenPoints)
|
|||
}
|
||||
%{
|
||||
#include <layers_id_colors_and_visibility.h>
|
||||
#include <pcbnew_scripting_helpers.h>
|
||||
%}
|
||||
|
||||
|
||||
// std::vector templates
|
||||
%template(VIA_DIMENSION_Vector) std::vector<VIA_DIMENSION>;
|
||||
|
||||
// Do not permit default BOARD ctor since it won't initialize the project
|
||||
%ignore BOARD::BOARD();
|
||||
|
||||
%include class_board.h
|
||||
%{
|
||||
#include <class_board.h>
|
||||
|
@ -123,11 +128,25 @@ HANDLE_EXCEPTIONS(BOARD::TracksInNetBetweenPoints)
|
|||
|
||||
%extend BOARD
|
||||
{
|
||||
// NOTE: this does not generate a ctor, despite swig docs saying it should. Not sure why.
|
||||
// Because of this, we use the __init__ override hack below.
|
||||
// BOARD()
|
||||
// {
|
||||
// return CreateEmptyBoard();
|
||||
// }
|
||||
|
||||
// BOARD_ITEM_CONTAINER's interface functions will be implemented by SWIG
|
||||
// automatically and inherited by the python wrapper class.
|
||||
|
||||
%pythoncode
|
||||
%{
|
||||
def __init__(self, *args):
|
||||
this = CreateEmptyBoard()
|
||||
|
||||
try:
|
||||
self.this.append(this)
|
||||
except:
|
||||
self.this = this
|
||||
|
||||
def GetModules(self): return self.Modules()
|
||||
def GetDrawings(self): return self.Drawings()
|
||||
|
|
|
@ -42,9 +42,19 @@
|
|||
#include <pcbnew.h>
|
||||
#include <pcbnew_scripting_helpers.h>
|
||||
#include <project.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
|
||||
static PCB_EDIT_FRAME* s_PcbEditFrame = NULL;
|
||||
|
||||
/**
|
||||
* We need to track the loaded PROJECTs for each loaded BOARD here, since in Python you can
|
||||
* easily load more than one board if desired.
|
||||
*/
|
||||
static std::map<wxString, PROJECT*> s_Projects;
|
||||
|
||||
static SETTINGS_MANAGER* s_SettingsManager = nullptr;
|
||||
|
||||
BOARD* GetBoard()
|
||||
{
|
||||
if( s_PcbEditFrame )
|
||||
|
@ -73,17 +83,72 @@ BOARD* LoadBoard( wxString& aFileName )
|
|||
}
|
||||
|
||||
|
||||
SETTINGS_MANAGER* GetSettingsManager()
|
||||
{
|
||||
if( !s_SettingsManager )
|
||||
s_SettingsManager = new SETTINGS_MANAGER;
|
||||
|
||||
return s_SettingsManager;
|
||||
}
|
||||
|
||||
|
||||
PROJECT* GetDefaultProject()
|
||||
{
|
||||
PROJECT* project = nullptr;
|
||||
|
||||
if( s_Projects.count( "" ) )
|
||||
project = s_Projects.at( "" );
|
||||
else
|
||||
{
|
||||
GetSettingsManager()->LoadProject( "" );
|
||||
project = GetSettingsManager()->GetProject( "" );
|
||||
s_Projects[""] = project;
|
||||
}
|
||||
|
||||
return project;
|
||||
}
|
||||
|
||||
|
||||
BOARD* LoadBoard( wxString& aFileName, IO_MGR::PCB_FILE_T aFormat )
|
||||
{
|
||||
wxFileName pro = aFileName;
|
||||
pro.SetExt( ProjectFileExtension );
|
||||
pro.MakeAbsolute();
|
||||
wxString projectPath = pro.GetFullPath();
|
||||
|
||||
PROJECT* project = nullptr;
|
||||
|
||||
if( s_Projects.count( projectPath ) )
|
||||
project = s_Projects.at( projectPath );
|
||||
else if( GetSettingsManager()->LoadProject( projectPath ) )
|
||||
{
|
||||
project = GetSettingsManager()->GetProject( projectPath );
|
||||
s_Projects[projectPath] = project;
|
||||
}
|
||||
|
||||
// Board cannot be loaded without a project, so create the default project
|
||||
if( !project )
|
||||
project = GetDefaultProject();
|
||||
|
||||
BOARD* brd = IO_MGR::Load( aFormat, aFileName );
|
||||
|
||||
if( brd )
|
||||
{
|
||||
brd->SetProject( project );
|
||||
brd->BuildConnectivity();
|
||||
brd->BuildListOfNets();
|
||||
brd->SynchronizeNetsAndNetClasses();
|
||||
}
|
||||
|
||||
return brd;
|
||||
}
|
||||
|
||||
|
||||
BOARD* CreateEmptyBoard()
|
||||
{
|
||||
BOARD* brd = new BOARD();
|
||||
|
||||
brd->SetProject( GetDefaultProject() );
|
||||
|
||||
return brd;
|
||||
}
|
||||
|
@ -97,6 +162,13 @@ bool SaveBoard( wxString& aFileName, BOARD* aBoard, IO_MGR::PCB_FILE_T aFormat )
|
|||
|
||||
IO_MGR::Save( aFormat, aFileName, aBoard, NULL );
|
||||
|
||||
wxFileName pro = aFileName;
|
||||
pro.SetExt( ProjectFileExtension );
|
||||
pro.MakeAbsolute();
|
||||
wxString projectPath = pro.GetFullPath();
|
||||
|
||||
GetSettingsManager()->SaveProject( pro.GetFullPath() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,12 @@ BOARD* LoadBoard( wxString& aFileName, IO_MGR::PCB_FILE_T aFormat );
|
|||
// Default LoadBoard() to load .kicad_pcb files:.
|
||||
BOARD* LoadBoard( wxString& aFileName );
|
||||
|
||||
/**
|
||||
* Constructs a default BOARD with a tempoary (no filename) project
|
||||
* @return the created board
|
||||
*/
|
||||
BOARD* CreateEmptyBoard();
|
||||
|
||||
// Boards can be saved only as .kicad_pcb file format,
|
||||
// so no option to choose the file format.
|
||||
bool SaveBoard( wxString& aFileName, BOARD* aBoard );
|
||||
|
|
|
@ -32,8 +32,8 @@
|
|||
#include <board_commit.h>
|
||||
#include <class_board.h>
|
||||
#include <class_module.h>
|
||||
#include <class_track.h>
|
||||
#include <class_pcb_target.h>
|
||||
#include <class_track.h>
|
||||
#include <class_zone.h>
|
||||
#include <collectors.h>
|
||||
#include <confirm.h>
|
||||
|
@ -52,6 +52,7 @@
|
|||
#include <pcbnew_id.h>
|
||||
#include <pcbnew_settings.h>
|
||||
#include <project.h>
|
||||
#include <project/project_file.h> // LAST_PATH_TYPE
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/tool_event_utils.h>
|
||||
#include <view/view_controls.h>
|
||||
|
|
|
@ -883,7 +883,7 @@ int PCBNEW_CONTROL::AppendBoard( PLUGIN& pi, wxString& fileName )
|
|||
props["page_width"] = xbuf;
|
||||
props["page_height"] = ybuf;
|
||||
|
||||
editFrame->GetDesignSettings().m_NetClasses.Clear();
|
||||
editFrame->GetDesignSettings().GetNetClasses().Clear();
|
||||
pi.Load( fileName, brd, &props );
|
||||
}
|
||||
catch( const IO_ERROR& ioe )
|
||||
|
|
|
@ -32,7 +32,8 @@
|
|||
|
||||
#include <layers_id_colors_and_visibility.h>
|
||||
#include <zones.h>
|
||||
#include <wx/dataview.h>
|
||||
|
||||
class wxDataViewListCtrl;
|
||||
|
||||
enum class ZONE_FILL_MODE
|
||||
{
|
||||
|
|
|
@ -228,25 +228,6 @@ std::unique_ptr<BOARD> MakeBoard( const std::vector<COURTYARD_INVALID_TEST_MODUL
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a #BOARD_DESIGN_SETTINGS object that will cause DRC to
|
||||
* check for courtyard invalidity
|
||||
*/
|
||||
static BOARD_DESIGN_SETTINGS GetOverlapCheckDesignSettings()
|
||||
{
|
||||
BOARD_DESIGN_SETTINGS des_settings;
|
||||
|
||||
// do the overlap tests - that's a different test, but if not set,
|
||||
// the invalid courtyard checks don't run either
|
||||
des_settings.m_DRCSeverities[ DRCE_OVERLAPPING_FOOTPRINTS ] = RPT_SEVERITY_ERROR;
|
||||
|
||||
// we will also check for missing courtyards here
|
||||
des_settings.m_DRCSeverities[ DRCE_MISSING_COURTYARD ] = RPT_SEVERITY_ERROR;
|
||||
|
||||
return des_settings;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if a #MARKER_PCB is described by a particular #COURTYARD_INVALID_INFO object.
|
||||
*/
|
||||
|
@ -301,7 +282,14 @@ void DoCourtyardInvalidTest( const COURTYARD_INVALID_CASE& aCase,
|
|||
// Dump if env var set
|
||||
aDumper.DumpBoardToFile( *board, aCase.m_case_name );
|
||||
|
||||
board->SetDesignSettings( GetOverlapCheckDesignSettings() );
|
||||
BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings();
|
||||
|
||||
// do the overlap tests - that's a different test, but if not set,
|
||||
// the invalid courtyard checks don't run either
|
||||
bds.m_DRCSeverities[ DRCE_OVERLAPPING_FOOTPRINTS ] = RPT_SEVERITY_ERROR;
|
||||
|
||||
// we will also check for missing courtyards here
|
||||
bds.m_DRCSeverities[ DRCE_MISSING_COURTYARD ] = RPT_SEVERITY_ERROR;
|
||||
|
||||
// list of markers to collect
|
||||
std::vector<std::unique_ptr<MARKER_PCB>> markers;
|
||||
|
|
|
@ -441,21 +441,6 @@ static void CheckCollisionsMatchExpected( BOARD& aBoard,
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a #BOARD_DESIGN_SETTINGS object that will cause DRC to check for courtyard overlaps
|
||||
*/
|
||||
static BOARD_DESIGN_SETTINGS GetOverlapCheckDesignSettings()
|
||||
{
|
||||
BOARD_DESIGN_SETTINGS des_settings;
|
||||
des_settings.m_DRCSeverities[ DRCE_OVERLAPPING_FOOTPRINTS ] = RPT_SEVERITY_ERROR;
|
||||
|
||||
// we might not always have courtyards - that's a separate test
|
||||
des_settings.m_DRCSeverities[ DRCE_MISSING_COURTYARD ] = RPT_SEVERITY_IGNORE;
|
||||
|
||||
return des_settings;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Run a single courtyard overlap testcase
|
||||
* @param aCase The testcase to run.
|
||||
|
@ -468,7 +453,12 @@ static void DoCourtyardOverlapTest( const COURTYARD_OVERLAP_TEST_CASE& aCase,
|
|||
// Dump if env var set
|
||||
aDumper.DumpBoardToFile( *board, aCase.m_case_name );
|
||||
|
||||
board->SetDesignSettings( GetOverlapCheckDesignSettings() );
|
||||
BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings();
|
||||
|
||||
bds.m_DRCSeverities[ DRCE_OVERLAPPING_FOOTPRINTS ] = RPT_SEVERITY_ERROR;
|
||||
|
||||
// we might not always have courtyards - that's a separate test
|
||||
bds.m_DRCSeverities[ DRCE_MISSING_COURTYARD ] = RPT_SEVERITY_IGNORE;
|
||||
|
||||
// list of markers to collect
|
||||
std::vector<std::unique_ptr<MARKER_PCB>> markers;
|
||||
|
|
|
@ -69,7 +69,7 @@ public:
|
|||
if( m_exec_context.m_verbose )
|
||||
std::cout << "Running DRC check: " << getRunnerIntro() << std::endl;
|
||||
|
||||
aBoard.SetDesignSettings( getDesignSettings() );
|
||||
setDesignSettings( aBoard.GetDesignSettings() );
|
||||
|
||||
std::vector<std::unique_ptr<MARKER_PCB>> markers;
|
||||
|
||||
|
@ -101,9 +101,10 @@ private:
|
|||
virtual std::string getRunnerIntro() const = 0;
|
||||
|
||||
/**
|
||||
* Get suitable design settings for this DRC runner
|
||||
* Set suitable design settings for this DRC runner
|
||||
* @param aSettings is a reference to the design settings object of the board under test
|
||||
*/
|
||||
virtual BOARD_DESIGN_SETTINGS getDesignSettings() const = 0;
|
||||
virtual void setDesignSettings( BOARD_DESIGN_SETTINGS& aSettings ) const = 0;
|
||||
|
||||
virtual std::unique_ptr<DRC_TEST_PROVIDER> createDrcProvider(
|
||||
BOARD& aBoard, DRC_TEST_PROVIDER::MARKER_HANDLER aHandler ) = 0;
|
||||
|
@ -157,13 +158,10 @@ private:
|
|||
return "Courtyard overlap";
|
||||
}
|
||||
|
||||
BOARD_DESIGN_SETTINGS getDesignSettings() const override
|
||||
void setDesignSettings( BOARD_DESIGN_SETTINGS& aSettings ) const override
|
||||
{
|
||||
BOARD_DESIGN_SETTINGS des_settings;
|
||||
des_settings.m_DRCSeverities[ DRCE_MISSING_COURTYARD ] = RPT_SEVERITY_IGNORE;
|
||||
des_settings.m_DRCSeverities[ DRCE_OVERLAPPING_FOOTPRINTS ] = RPT_SEVERITY_ERROR;
|
||||
|
||||
return des_settings;
|
||||
aSettings.m_DRCSeverities[ DRCE_MISSING_COURTYARD ] = RPT_SEVERITY_IGNORE;
|
||||
aSettings.m_DRCSeverities[ DRCE_OVERLAPPING_FOOTPRINTS ] = RPT_SEVERITY_ERROR;
|
||||
}
|
||||
|
||||
std::unique_ptr<DRC_TEST_PROVIDER> createDrcProvider(
|
||||
|
@ -194,13 +192,10 @@ private:
|
|||
return "Courtyard missing";
|
||||
}
|
||||
|
||||
BOARD_DESIGN_SETTINGS getDesignSettings() const override
|
||||
void setDesignSettings( BOARD_DESIGN_SETTINGS& aSettings ) const override
|
||||
{
|
||||
BOARD_DESIGN_SETTINGS des_settings;
|
||||
des_settings.m_DRCSeverities[ DRCE_MISSING_COURTYARD ] = RPT_SEVERITY_ERROR;
|
||||
des_settings.m_DRCSeverities[ DRCE_OVERLAPPING_FOOTPRINTS ] = RPT_SEVERITY_IGNORE;
|
||||
|
||||
return des_settings;
|
||||
aSettings.m_DRCSeverities[ DRCE_MISSING_COURTYARD ] = RPT_SEVERITY_ERROR;
|
||||
aSettings.m_DRCSeverities[ DRCE_OVERLAPPING_FOOTPRINTS ] = RPT_SEVERITY_IGNORE;
|
||||
}
|
||||
|
||||
std::unique_ptr<DRC_TEST_PROVIDER> createDrcProvider(
|
||||
|
|
Loading…
Reference in New Issue