Cache project text vars as properties in the PCB board file.
Fixes https://gitlab.com/kicad/code/kicad/issues/5255 Fixes https://gitlab.com/kicad/code/kicad/issues/5005
This commit is contained in:
parent
b9c50c893c
commit
27b047ab3f
|
@ -381,7 +381,8 @@ enum Bracket
|
|||
|
||||
wxString ExpandTextVars( const wxString& aSource,
|
||||
const std::function<bool( wxString* )>* aLocalResolver,
|
||||
const PROJECT* aProject )
|
||||
const PROJECT* aProject,
|
||||
const std::function<bool( wxString* )>* aFallbackResolver )
|
||||
{
|
||||
wxString newbuf;
|
||||
size_t sourceLen = aSource.length();
|
||||
|
@ -413,6 +414,10 @@ wxString ExpandTextVars( const wxString& aSource,
|
|||
{
|
||||
newbuf.append( token );
|
||||
}
|
||||
else if( aFallbackResolver && (*aFallbackResolver)( &token ) )
|
||||
{
|
||||
newbuf.append( token );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Token not resolved: leave the reference unchanged
|
||||
|
|
|
@ -330,7 +330,8 @@ const wxString ExpandEnvVarSubstitutions( const wxString& aString, PROJECT* aPro
|
|||
*/
|
||||
wxString ExpandTextVars( const wxString& aSource,
|
||||
const std::function<bool( wxString* )>* aLocalResolver,
|
||||
const PROJECT* aProject );
|
||||
const PROJECT* aProject,
|
||||
const std::function<bool( wxString* )>* aFallbackResolver = nullptr );
|
||||
|
||||
/**
|
||||
* Replace any environment and/or text variables in file-path uris (leaving network-path URIs
|
||||
|
|
|
@ -68,9 +68,6 @@ BOARD::BOARD() :
|
|||
// we have not loaded a board yet, assume latest until then.
|
||||
m_fileFormatVersionAtLoad = LEGACY_BOARD_FILE_VERSION;
|
||||
|
||||
m_CurrentZoneContour = NULL; // This ZONE_CONTAINER handle the
|
||||
// zone contour currently in progress
|
||||
|
||||
for( LAYER_NUM layer = 0; layer < PCB_LAYER_ID_COUNT; ++layer )
|
||||
{
|
||||
m_Layer[layer].m_name = GetStandardLayerName( ToLAYER_ID( layer ) );
|
||||
|
@ -133,9 +130,6 @@ BOARD::~BOARD()
|
|||
|
||||
m_drawings.clear();
|
||||
|
||||
delete m_CurrentZoneContour;
|
||||
m_CurrentZoneContour = NULL;
|
||||
|
||||
m_groups.clear();
|
||||
}
|
||||
|
||||
|
@ -191,6 +185,18 @@ void BOARD::ClearProject()
|
|||
}
|
||||
|
||||
|
||||
bool BOARD::ResolveTextVar( wxString* token, int aDepth ) const
|
||||
{
|
||||
if( m_properties.count( *token ) )
|
||||
{
|
||||
*token = m_properties.at( *token );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
wxPoint BOARD::GetPosition() const
|
||||
{
|
||||
return ZeroOffset;
|
||||
|
@ -1300,6 +1306,13 @@ std::vector<wxString> BOARD::GetNetClassAssignmentCandidates()
|
|||
}
|
||||
|
||||
|
||||
void BOARD::SynchronizeProperties()
|
||||
{
|
||||
if( m_project )
|
||||
SetProperties( m_project->GetTextVars() );
|
||||
}
|
||||
|
||||
|
||||
void BOARD::SynchronizeNetsAndNetClasses()
|
||||
{
|
||||
if( m_project )
|
||||
|
|
|
@ -25,23 +25,17 @@
|
|||
#ifndef CLASS_BOARD_H_
|
||||
#define CLASS_BOARD_H_
|
||||
|
||||
#include <tuple>
|
||||
#include <board_design_settings.h>
|
||||
#include <board_item_container.h>
|
||||
#include <class_pcb_group.h>
|
||||
#include <class_module.h>
|
||||
#include <class_pad.h>
|
||||
#include <common.h> // PAGE_INFO
|
||||
#include <eda_rect.h>
|
||||
#include <layers_id_colors_and_visibility.h>
|
||||
#include <netinfo.h>
|
||||
#include <pcb_plot_params.h>
|
||||
#include <title_block.h>
|
||||
#include <zone_settings.h>
|
||||
#include <tools/pcbnew_selection.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
class BOARD_COMMIT;
|
||||
class PCB_BASE_FRAME;
|
||||
class PCB_EDIT_FRAME;
|
||||
|
@ -186,25 +180,12 @@ class BOARD : public BOARD_ITEM_CONTAINER
|
|||
friend class PCB_EDIT_FRAME;
|
||||
|
||||
private:
|
||||
/// the board filename
|
||||
wxString m_fileName;
|
||||
|
||||
/// MARKER_PCBs for clearance problems, owned by pointer.
|
||||
MARKERS m_markers;
|
||||
|
||||
/// BOARD_ITEMs for drawings on the board, owned by pointer.
|
||||
DRAWINGS m_drawings;
|
||||
|
||||
/// MODULES for components on the board, owned by pointer.
|
||||
MODULES m_modules;
|
||||
|
||||
/// TRACKS for traces on the board, owned by pointer.
|
||||
TRACKS m_tracks;
|
||||
|
||||
/// GROUPS for groups on the board, owned by pointer.
|
||||
GROUPS m_groups;
|
||||
|
||||
/// edge zone descriptors, owned by pointer.
|
||||
ZONE_CONTAINERS m_ZoneDescriptorList;
|
||||
|
||||
LAYER m_Layer[PCB_LAYER_ID_COUNT];
|
||||
|
@ -215,7 +196,8 @@ private:
|
|||
|
||||
int m_fileFormatVersionAtLoad; // the version loaded from the file
|
||||
|
||||
std::shared_ptr<CONNECTIVITY_DATA> m_connectivity;
|
||||
std::map<wxString, wxString> m_properties;
|
||||
std::shared_ptr<CONNECTIVITY_DATA> m_connectivity;
|
||||
|
||||
PAGE_INFO m_paper;
|
||||
TITLE_BLOCK m_titles; // text in lower right of screen and plots
|
||||
|
@ -261,38 +243,17 @@ public:
|
|||
|
||||
const wxString &GetFileName() const { return m_fileName; }
|
||||
|
||||
TRACKS& Tracks()
|
||||
{
|
||||
return m_tracks;
|
||||
}
|
||||
const TRACKS& Tracks() const
|
||||
{
|
||||
return m_tracks;
|
||||
}
|
||||
TRACKS& Tracks() { return m_tracks; }
|
||||
const TRACKS& Tracks() const { return m_tracks; }
|
||||
|
||||
MODULES& Modules()
|
||||
{
|
||||
return m_modules;
|
||||
}
|
||||
const MODULES& Modules() const
|
||||
{
|
||||
return m_modules;
|
||||
}
|
||||
MODULES& Modules() { return m_modules; }
|
||||
const MODULES& Modules() const { return m_modules; }
|
||||
|
||||
DRAWINGS& Drawings()
|
||||
{
|
||||
return m_drawings;
|
||||
}
|
||||
DRAWINGS& Drawings() { return m_drawings; }
|
||||
|
||||
ZONE_CONTAINERS& Zones()
|
||||
{
|
||||
return m_ZoneDescriptorList;
|
||||
}
|
||||
ZONE_CONTAINERS& Zones() { return m_ZoneDescriptorList; }
|
||||
|
||||
MARKERS& Markers()
|
||||
{
|
||||
return m_markers;
|
||||
}
|
||||
MARKERS& Markers() { return m_markers; }
|
||||
|
||||
/**
|
||||
* The groups must maintain the folowing invariants. These are checked by
|
||||
|
@ -302,15 +263,14 @@ public:
|
|||
* - If a group specifies a name, it must be unique
|
||||
* - The graph of groups contianing subgroups must be acyclic.
|
||||
*/
|
||||
GROUPS& Groups()
|
||||
{
|
||||
return m_groups;
|
||||
}
|
||||
GROUPS& Groups() { return m_groups; }
|
||||
|
||||
const std::vector<BOARD_CONNECTED_ITEM*> AllConnectedItems();
|
||||
|
||||
/// zone contour currently in progress
|
||||
ZONE_CONTAINER* m_CurrentZoneContour;
|
||||
const std::map<wxString, wxString>& GetProperties() const { return m_properties; }
|
||||
void SetProperties( const std::map<wxString, wxString>& aProps ) { m_properties = aProps; }
|
||||
|
||||
bool ResolveTextVar( wxString* token, int aDepth ) const;
|
||||
|
||||
/// Visibility settings stored in board prior to 6.0, only used for loading legacy files
|
||||
LSET m_LegacyVisibleLayers;
|
||||
|
@ -885,8 +845,11 @@ public:
|
|||
*/
|
||||
void SynchronizeNetsAndNetClasses();
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
/**
|
||||
* Function SynchronizeProperties
|
||||
* copies the current project's text variables into the boards property cache.
|
||||
*/
|
||||
void SynchronizeProperties();
|
||||
|
||||
wxString GetClass() const override
|
||||
{
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
|
||||
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -23,21 +23,11 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file class_pcb_text.cpp
|
||||
* @brief Class TEXTE_PCB texts on copper or technical layers implementation
|
||||
*/
|
||||
|
||||
#include <fctsys.h>
|
||||
#include <gr_basic.h>
|
||||
#include <base_struct.h>
|
||||
#include <gr_text.h>
|
||||
#include <pcb_edit_frame.h>
|
||||
#include <base_units.h>
|
||||
#include <bitmaps.h>
|
||||
#include <settings/color_settings.h>
|
||||
#include <settings/settings_manager.h>
|
||||
|
||||
#include <class_board.h>
|
||||
#include <class_pcb_text.h>
|
||||
#include <pcb_painter.h>
|
||||
|
@ -92,11 +82,17 @@ wxString TEXTE_PCB::GetShownText( int aDepth ) const
|
|||
return false;
|
||||
};
|
||||
|
||||
std::function<bool( wxString* )> boardTextResolver =
|
||||
[&]( wxString* token ) -> bool
|
||||
{
|
||||
return board->ResolveTextVar( token, aDepth + 1 );
|
||||
};
|
||||
|
||||
bool processTextVars = false;
|
||||
wxString text = EDA_TEXT::GetShownText( &processTextVars );
|
||||
|
||||
if( processTextVars && aDepth < 10 )
|
||||
text = ExpandTextVars( text, &pcbTextResolver, board->GetProject() );
|
||||
text = ExpandTextVars( text, &pcbTextResolver, board->GetProject(), &boardTextResolver );
|
||||
|
||||
return text;
|
||||
}
|
||||
|
|
|
@ -24,15 +24,11 @@
|
|||
*/
|
||||
|
||||
#include <fctsys.h>
|
||||
#include <gr_text.h>
|
||||
#include <kicad_string.h>
|
||||
#include <pcb_edit_frame.h>
|
||||
#include <base_units.h>
|
||||
#include <bitmaps.h>
|
||||
#include <class_board.h>
|
||||
#include <class_module.h>
|
||||
#include <view/view.h>
|
||||
#include <settings/color_settings.h>
|
||||
#include <settings/settings_manager.h>
|
||||
|
||||
TEXTE_MODULE::TEXTE_MODULE( MODULE* parent, TEXT_TYPE text_type ) :
|
||||
|
@ -428,6 +424,7 @@ wxString TEXTE_MODULE::GetShownText( int aDepth ) const
|
|||
{
|
||||
const MODULE* module = static_cast<MODULE*>( GetParent() );
|
||||
wxASSERT( module );
|
||||
const BOARD* board = module->GetBoard();
|
||||
|
||||
std::function<bool( wxString* )> moduleResolver =
|
||||
[&]( wxString* token ) -> bool
|
||||
|
@ -435,6 +432,12 @@ wxString TEXTE_MODULE::GetShownText( int aDepth ) const
|
|||
return module && module->ResolveTextVar( token, aDepth );
|
||||
};
|
||||
|
||||
std::function<bool( wxString* )> boardTextResolver =
|
||||
[&]( wxString* token ) -> bool
|
||||
{
|
||||
return board->ResolveTextVar( token, aDepth + 1 );
|
||||
};
|
||||
|
||||
bool processTextVars = false;
|
||||
wxString text = EDA_TEXT::GetShownText( &processTextVars );
|
||||
|
||||
|
@ -446,7 +449,7 @@ wxString TEXTE_MODULE::GetShownText( int aDepth ) const
|
|||
project = static_cast<BOARD*>( module->GetParent() )->GetProject();
|
||||
|
||||
if( aDepth < 10 )
|
||||
text = ExpandTextVars( text, &moduleResolver, project );
|
||||
text = ExpandTextVars( text, &moduleResolver, project, &boardTextResolver );
|
||||
}
|
||||
|
||||
return text;
|
||||
|
|
|
@ -335,8 +335,8 @@ bool PCB_EDIT_FRAME::Files_io_from_id( int id )
|
|||
{
|
||||
bool addToHistory = false;
|
||||
wxString orig_name;
|
||||
wxFileName::SplitPath( GetBoard()->GetFileName(),
|
||||
nullptr, nullptr, &orig_name, nullptr );
|
||||
wxFileName::SplitPath( GetBoard()->GetFileName(), nullptr, nullptr, &orig_name,
|
||||
nullptr );
|
||||
|
||||
if( orig_name.IsEmpty() )
|
||||
{
|
||||
|
@ -706,9 +706,12 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool addToHistory,
|
|||
|
||||
// TODO: this will break if we ever go multi-board
|
||||
wxFileName projectFile( pcbFileName );
|
||||
projectFile.SetExt( ProjectFileExtension );
|
||||
bool projectFileExists = false;
|
||||
|
||||
if( aChangeProject && !projectFile.FileExists() )
|
||||
projectFile.SetExt( ProjectFileExtension );
|
||||
projectFileExists = projectFile.FileExists();
|
||||
|
||||
if( aChangeProject && !projectFileExists )
|
||||
{
|
||||
// If this is a new board, project filename won't be set yet
|
||||
if( projectFile.GetFullPath() != Prj().GetProjectFullName() )
|
||||
|
@ -720,11 +723,17 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool addToHistory,
|
|||
mgr->SaveProject( Prj().GetProjectFullName() );
|
||||
mgr->UnloadProject( &Prj() );
|
||||
|
||||
mgr->LoadProject( projectFile.GetFullPath() );
|
||||
// If no project to load then initialize project text vars with board properties
|
||||
if( !mgr->LoadProject( projectFile.GetFullPath() ) )
|
||||
Prj().GetTextVars() = GetBoard()->GetProperties();
|
||||
|
||||
GetBoard()->SetProject( &Prj() );
|
||||
}
|
||||
}
|
||||
|
||||
if( projectFileExists )
|
||||
GetBoard()->SynchronizeProperties();
|
||||
|
||||
wxFileName tempFile( aFileName );
|
||||
tempFile.SetName( wxT( "." ) + tempFile.GetName() );
|
||||
tempFile.SetExt( tempFile.GetExt() + wxT( "$" ) );
|
||||
|
|
|
@ -23,11 +23,8 @@
|
|||
*/
|
||||
|
||||
#include <fctsys.h>
|
||||
#include <common.h>
|
||||
#include <build_version.h> // LEGACY_BOARD_FILE_VERSION
|
||||
#include <macros.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
|
||||
#include <advanced_config.h>
|
||||
#include <base_units.h>
|
||||
#include <trace_helpers.h>
|
||||
|
@ -45,34 +42,13 @@
|
|||
#include <kicad_plugin.h>
|
||||
#include <pcb_parser.h>
|
||||
#include <pcbnew_settings.h>
|
||||
#include <wx/dir.h>
|
||||
#include <wx/filename.h>
|
||||
#include <wx/wfstream.h>
|
||||
#include <boost/ptr_container/ptr_map.hpp>
|
||||
#include <memory.h>
|
||||
#include <connectivity/connectivity_data.h>
|
||||
#include <convert_basic_shapes_to_polygon.h> // for enum RECT_CHAMFER_POSITIONS definition
|
||||
#include <kiface_i.h>
|
||||
|
||||
using namespace PCB_KEYS_T;
|
||||
|
||||
|
||||
///> Removes empty nets (i.e. with node count equal zero) from net classes
|
||||
void filterNetClass( const BOARD& aBoard, NETCLASS& aNetClass )
|
||||
{
|
||||
auto connectivity = aBoard.GetConnectivity();
|
||||
|
||||
for( NETCLASS::iterator it = aNetClass.begin(); it != aNetClass.end(); )
|
||||
{
|
||||
NETINFO_ITEM* netinfo = aBoard.FindNet( *it );
|
||||
|
||||
if( netinfo && connectivity->GetNodeCount( netinfo->GetNet() ) <= 0 ) // hopefully there are no nets with negative
|
||||
aNetClass.Remove( it++ ); // node count, but you never know..
|
||||
else
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* FP_CACHE_ITEM
|
||||
* is helper class for creating a footprint library cache.
|
||||
|
@ -606,6 +582,19 @@ void PCB_IO::formatNetInformation( BOARD* aBoard, int aNestLevel ) const
|
|||
}
|
||||
|
||||
|
||||
void PCB_IO::formatProperties( BOARD* aBoard, int aNestLevel ) const
|
||||
{
|
||||
for( const std::pair<const wxString, wxString>& prop : aBoard->GetProperties() )
|
||||
{
|
||||
m_out->Print( aNestLevel+1, "(property %s %s)\n",
|
||||
m_out->Quotew( prop.first ).c_str(),
|
||||
m_out->Quotew( prop.second ).c_str() );
|
||||
}
|
||||
|
||||
m_out->Print( 0, "\n" );
|
||||
}
|
||||
|
||||
|
||||
void PCB_IO::formatHeader( BOARD* aBoard, int aNestLevel ) const
|
||||
{
|
||||
formatGeneral( aBoard, aNestLevel );
|
||||
|
@ -615,13 +604,16 @@ void PCB_IO::formatHeader( BOARD* aBoard, int aNestLevel ) const
|
|||
// Setup
|
||||
formatSetup( aBoard, aNestLevel );
|
||||
|
||||
// Properties
|
||||
formatProperties( aBoard, aNestLevel );
|
||||
|
||||
// Save net codes and names
|
||||
formatNetInformation( aBoard, aNestLevel );
|
||||
}
|
||||
|
||||
|
||||
void PCB_IO::format( BOARD* aBoard, int aNestLevel ) const
|
||||
{
|
||||
|
||||
std::set<BOARD_ITEM*, BOARD_ITEM::ptr_cmp> sorted_modules( aBoard->Modules().begin(),
|
||||
aBoard->Modules().end() );
|
||||
std::set<BOARD_ITEM*, BOARD_ITEM::ptr_cmp> sorted_drawings( aBoard->Drawings().begin(),
|
||||
|
|
|
@ -78,7 +78,8 @@ class TEXTE_PCB;
|
|||
//#define SEXPR_BOARD_FILE_VERSION 20200808 // Add properties to modules
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20200809 // Add REMOVE_UNUSED_LAYERS option to vias and THT pads
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20200811 // Add groups
|
||||
#define SEXPR_BOARD_FILE_VERSION 20200818 // Remove Status flag bitmap and setup counts
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20200818 // Remove Status flag bitmap and setup counts
|
||||
#define SEXPR_BOARD_FILE_VERSION 20200819 // Add board-level properties
|
||||
|
||||
#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)
|
||||
|
@ -235,6 +236,9 @@ protected:
|
|||
/// formats the Nets and Netclasses
|
||||
void formatNetInformation( BOARD* aBoard, int aNestLevel = 0 ) const;
|
||||
|
||||
/// formats the Nets and Netclasses
|
||||
void formatProperties( BOARD* aBoard, int aNestLevel = 0 ) const;
|
||||
|
||||
/// writes everything that comes before the board_items, like settings and layers etc
|
||||
void formatHeader( BOARD* aBoard, int aNestLevel = 0 ) const;
|
||||
|
||||
|
|
|
@ -249,6 +249,21 @@ void PCB_PARSER::parseXY( int* aX, int* aY )
|
|||
}
|
||||
|
||||
|
||||
std::pair<wxString, wxString> PCB_PARSER::parseProperty()
|
||||
{
|
||||
wxString pName;
|
||||
wxString pValue;
|
||||
|
||||
NeedSYMBOL();
|
||||
pName = FromUTF8();
|
||||
NeedSYMBOL();
|
||||
pValue = FromUTF8();
|
||||
NeedRIGHT();
|
||||
|
||||
return { pName, pValue };
|
||||
}
|
||||
|
||||
|
||||
void PCB_PARSER::parseEDA_TEXT( EDA_TEXT* aText )
|
||||
{
|
||||
wxCHECK_RET( CurTok() == T_effects,
|
||||
|
@ -524,6 +539,7 @@ BOARD* PCB_PARSER::parseBOARD()
|
|||
BOARD* PCB_PARSER::parseBOARD_unchecked()
|
||||
{
|
||||
T token;
|
||||
std::map<wxString, wxString> properties;
|
||||
|
||||
parseHeader();
|
||||
|
||||
|
@ -559,6 +575,10 @@ BOARD* PCB_PARSER::parseBOARD_unchecked()
|
|||
parseSetup();
|
||||
break;
|
||||
|
||||
case T_property:
|
||||
properties.insert( parseProperty() );
|
||||
break;
|
||||
|
||||
case T_net:
|
||||
parseNETINFO_ITEM();
|
||||
break;
|
||||
|
@ -620,6 +640,8 @@ BOARD* PCB_PARSER::parseBOARD_unchecked()
|
|||
}
|
||||
}
|
||||
|
||||
m_board->SetProperties( properties );
|
||||
|
||||
if( m_undefinedLayers.size() > 0 )
|
||||
{
|
||||
bool deleteItems;
|
||||
|
@ -2603,11 +2625,7 @@ MODULE* PCB_PARSER::parseMODULE_unchecked( wxArrayString* aInitialComments )
|
|||
break;
|
||||
|
||||
case T_property:
|
||||
NeedSYMBOL();
|
||||
name = FromUTF8();
|
||||
NeedSYMBOL();
|
||||
properties[ name ] = FromUTF8();
|
||||
NeedRIGHT();
|
||||
properties.insert( parseProperty() );
|
||||
break;
|
||||
|
||||
case T_path:
|
||||
|
|
|
@ -238,6 +238,8 @@ class PCB_PARSER : public PCB_LEXER
|
|||
|
||||
void parseXY( int* aX, int* aY );
|
||||
|
||||
std::pair<wxString, wxString> parseProperty();
|
||||
|
||||
/**
|
||||
* Function parseEDA_TEXT
|
||||
* parses the common settings for any object derived from #EDA_TEXT.
|
||||
|
|
Loading…
Reference in New Issue