7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-03-30 06:26:55 +00:00

Variable substitution framework.

This implements editing of variables and moving SCH_FIELDs,
TEXTE_MODULEs, TEXTE_PCB and worksheet items over to the new
framework.
This commit is contained in:
Jeff Young 2020-03-26 11:02:59 +00:00
parent 9c2a260a27
commit 4990d1e7b2
79 changed files with 1609 additions and 651 deletions
.gitignore
common
eeschema
gerbview
include
pagelayout_editor
pcbnew
qa/eeschema

4
.gitignore vendored
View File

@ -17,8 +17,8 @@ eeschema/cmp_library_lexer.h
eeschema/cmp_library_keywords.*
eeschema/dialogs/dialog_bom_cfg_keywords.cpp
eeschema/dialogs/dialog_bom_cfg_lexer.h
eeschema/template_fieldnames_keywords.*
eeschema/template_fieldnames_lexer.h
common/template_fieldnames_keywords.cpp
common/template_fieldnames_lexer.h
eeschema/schematic_keywords.*
pcbnew/pcb_plot_params_keywords.cpp
pcbnew/pcb_plot_params_lexer.h

View File

@ -184,6 +184,8 @@ set( COMMON_DLG_SRCS
dialogs/panel_common_settings.cpp
dialogs/panel_common_settings_base.cpp
dialogs/panel_hotkeys_editor.cpp
dialogs/panel_text_variables.cpp
dialogs/panel_text_variables_base.cpp
dialogs/wx_html_report_panel.cpp
dialogs/wx_html_report_panel_base.cpp
)
@ -334,6 +336,7 @@ set( COMMON_SRCS
searchhelpfilefullpath.cpp
status_popup.cpp
systemdirsappend.cpp
template_fieldnames.cpp
tools_holder.cpp
trace_helpers.cpp
undo_redo_container.cpp
@ -545,6 +548,15 @@ make_lexer(
LIB_TABLE_T
)
# auto-generate s-expression template fieldnames lexer and keywords.
make_lexer(
common
template_fieldnames.keywords
template_fieldnames_lexer.h
template_fieldnames_keywords.cpp
TFIELD_T
)
# auto-generate page layout reader s-expression page_layout_reader_lexer.h
# and title_block_reader_keywords.cpp.
make_lexer(

View File

@ -25,12 +25,10 @@
#include <fctsys.h>
#include <eda_base_frame.h>
#include <project.h>
#include <common.h>
#include <macros.h>
#include <reporter.h>
#include <mutex>
#include <settings/settings_manager.h>
#include <wx/process.h>
#include <wx/config.h>
#include <wx/utils.h>
@ -358,23 +356,7 @@ void wxStringSplit( const wxString& aText, wxArrayString& aStrings, wxChar aSpli
int ProcessExecute( const wxString& aCommandLine, int aFlags, wxProcess *callback )
{
return wxExecute( aCommandLine, aFlags, callback );
}
timestamp_t GetNewTimeStamp()
{
static timestamp_t oldTimeStamp;
timestamp_t newTimeStamp;
newTimeStamp = time( NULL );
if( newTimeStamp <= oldTimeStamp )
newTimeStamp = oldTimeStamp + 1;
oldTimeStamp = newTimeStamp;
return newTimeStamp;
return (int) wxExecute( aCommandLine, aFlags, callback );
}
@ -390,6 +372,50 @@ enum Bracket
};
wxString ExpandTextVars( const wxString& aSource,
const std::function<bool( wxString* )>& aLocalResolver,
const PROJECT* aProject )
{
wxString newbuf;
size_t sourceLen = aSource.length();
for( size_t i = 0; i < sourceLen; ++i )
{
if( aSource[i] == '$' && i + 1 < sourceLen && aSource[i+1] == '{' )
{
wxString token;
for( i = i + 2; i < sourceLen; ++i )
{
if( aSource[i] == '}' )
break;
else
token.append( aSource[i] );
}
if( token.IsEmpty() )
continue;
if( aLocalResolver( &token ) || ( aProject && aProject->TextVarResolver( &token ) ) )
{
newbuf.append( token );
}
else
{
// Token not resolved: leave the reference unchanged
newbuf.append( "${" + token + "}" );
}
}
else
{
newbuf.append( aSource[i] );
}
}
return newbuf;
}
//
// Stolen from wxExpandEnvVars and then heavily optimized
//

View File

@ -34,11 +34,11 @@
#include <widgets/wx_grid.h>
#include <widgets/grid_text_button_helpers.h>
enum ENV_VAR_GRID_COLUMNS
enum TEXT_VAR_GRID_COLUMNS
{
EV_NAME_COL = 0,
EV_PATH_COL,
EV_FLAG_COL
TV_NAME_COL = 0,
TV_VALUE_COL,
TV_FLAG_COL
};
enum SEARCH_PATH_GRID_COLUMNS
@ -64,16 +64,16 @@ DIALOG_CONFIGURE_PATHS::DIALOG_CONFIGURE_PATHS( wxWindow* aParent, FILENAME_RESO
m_EnvVars->DeleteRows( 0, m_EnvVars->GetNumberRows() );
m_EnvVars->AppendCols( 1 ); // for the isExternal flags
m_EnvVars->HideCol( EV_FLAG_COL );
m_EnvVars->HideCol( TV_FLAG_COL );
m_EnvVars->UseNativeColHeader( true );
wxGridCellAttr* attr = new wxGridCellAttr;
attr->SetEditor( new GRID_CELL_PATH_EDITOR( this, &m_curdir, wxEmptyString ) );
m_EnvVars->SetColAttr( EV_PATH_COL, attr );
m_EnvVars->SetColAttr( TV_VALUE_COL, attr );
attr = new wxGridCellAttr;
attr->SetEditor( new GRID_CELL_PATH_EDITOR( this, &m_curdir, wxEmptyString ) );
m_SearchPaths->SetColAttr( EV_PATH_COL, attr );
m_SearchPaths->SetColAttr( TV_VALUE_COL, attr );
// Give a bit more room for combobox editors
m_EnvVars->SetDefaultRowSize( m_EnvVars->GetDefaultRowSize() + 4 );
@ -167,23 +167,23 @@ void DIALOG_CONFIGURE_PATHS::AppendEnvVar( const wxString& aName, const wxString
m_EnvVars->AppendRows( 1 );
m_EnvVars->SetCellValue( i, EV_NAME_COL, aName );
m_EnvVars->SetCellValue( i, TV_NAME_COL, aName );
wxGridCellAttr* nameCellAttr = m_EnvVars->GetOrCreateCellAttr( i, EV_NAME_COL );
wxGridCellAttr* nameCellAttr = m_EnvVars->GetOrCreateCellAttr( i, TV_NAME_COL );
wxGridCellTextEditor* nameTextEditor = new GRID_CELL_TEXT_EDITOR();
nameTextEditor->SetValidator( ENV_VAR_NAME_VALIDATOR() );
nameCellAttr->SetEditor( nameTextEditor );
nameCellAttr->SetReadOnly( IsEnvVarImmutable( aName ) );
nameCellAttr->DecRef();
m_EnvVars->SetCellValue( i, EV_PATH_COL, aPath );
m_EnvVars->SetCellValue( i, TV_VALUE_COL, aPath );
wxGridCellAttr* pathCellAttr = m_EnvVars->GetOrCreateCellAttr( i, EV_PATH_COL );
wxGridCellAttr* pathCellAttr = m_EnvVars->GetOrCreateCellAttr( i, TV_VALUE_COL );
wxSystemColour c = isExternal ? wxSYS_COLOUR_MENU : wxSYS_COLOUR_LISTBOX;
pathCellAttr->SetBackgroundColour( wxSystemSettings::GetColour( c ) );
pathCellAttr->DecRef();
m_EnvVars->SetCellValue( i, EV_FLAG_COL, isExternal ? wxT( "external" ) : wxEmptyString );
m_EnvVars->SetCellValue( i, TV_FLAG_COL, isExternal ? wxT( "external" ) : wxEmptyString );
}
@ -221,9 +221,9 @@ bool DIALOG_CONFIGURE_PATHS::TransferDataFromWindow()
for( int row = 0; row < m_EnvVars->GetNumberRows(); ++row )
{
wxString name = m_EnvVars->GetCellValue( row, EV_NAME_COL );
wxString path = m_EnvVars->GetCellValue( row, EV_PATH_COL );
wxString external = m_EnvVars->GetCellValue( row, EV_FLAG_COL );
wxString name = m_EnvVars->GetCellValue( row, TV_NAME_COL );
wxString path = m_EnvVars->GetCellValue( row, TV_VALUE_COL );
wxString external = m_EnvVars->GetCellValue( row, TV_FLAG_COL );
if( external.Length() )
continue;
@ -232,7 +232,7 @@ bool DIALOG_CONFIGURE_PATHS::TransferDataFromWindow()
{
m_errorGrid = m_EnvVars;
m_errorRow = row;
m_errorCol = EV_NAME_COL;
m_errorCol = TV_NAME_COL;
m_errorMsg = _( "Environment variable name cannot be empty." );
return false;
}
@ -240,7 +240,7 @@ bool DIALOG_CONFIGURE_PATHS::TransferDataFromWindow()
{
m_errorGrid = m_EnvVars;
m_errorRow = row;
m_errorCol = EV_PATH_COL;
m_errorCol = TV_VALUE_COL;
m_errorMsg = _( "Environment variable path cannot be empty." );
return false;
}
@ -302,7 +302,7 @@ void DIALOG_CONFIGURE_PATHS::OnGridCellChanging( wxGridEvent& event )
{
if( grid == m_EnvVars )
{
if( col == EV_NAME_COL )
if( col == TV_NAME_COL )
m_errorMsg = _( "Environment variable name cannot be empty." );
else
m_errorMsg = _( "Environment variable path cannot be empty." );
@ -323,7 +323,7 @@ void DIALOG_CONFIGURE_PATHS::OnGridCellChanging( wxGridEvent& event )
if( grid == m_EnvVars )
{
if( col == EV_PATH_COL && m_EnvVars->GetCellValue( row, EV_FLAG_COL ).Length() )
if( col == TV_VALUE_COL && m_EnvVars->GetCellValue( row, TV_FLAG_COL ).Length() )
{
wxString msg1 = _( "This path was defined externally to the running process and\n"
"will only be temporarily overwritten." );
@ -337,7 +337,7 @@ void DIALOG_CONFIGURE_PATHS::OnGridCellChanging( wxGridEvent& event )
dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
dlg.ShowModal();
}
else if( col == EV_NAME_COL && m_EnvVars->GetCellValue( row, EV_NAME_COL ) != text )
else if( col == TV_NAME_COL && m_EnvVars->GetCellValue( row, TV_NAME_COL ) != text )
{
if( text == PROJECT_VAR_NAME ) // This env var name is reserved and cannot be added here:
{
@ -347,7 +347,7 @@ void DIALOG_CONFIGURE_PATHS::OnGridCellChanging( wxGridEvent& event )
event.Veto();
}
else // Changing name; clear external flag
m_EnvVars->SetCellValue( row, EV_FLAG_COL, wxEmptyString );
m_EnvVars->SetCellValue( row, TV_FLAG_COL, wxEmptyString );
}
}
}
@ -360,8 +360,8 @@ void DIALOG_CONFIGURE_PATHS::OnAddEnvVar( wxCommandEvent& event )
AppendEnvVar( wxEmptyString, wxEmptyString, false );
m_EnvVars->MakeCellVisible( m_EnvVars->GetNumberRows() - 1, EV_NAME_COL );
m_EnvVars->SetGridCursor( m_EnvVars->GetNumberRows() - 1, EV_NAME_COL );
m_EnvVars->MakeCellVisible( m_EnvVars->GetNumberRows() - 1, TV_NAME_COL );
m_EnvVars->SetGridCursor( m_EnvVars->GetNumberRows() - 1, TV_NAME_COL );
m_EnvVars->EnableCellEditControl( true );
m_EnvVars->ShowCellEditControl();
@ -389,7 +389,7 @@ void DIALOG_CONFIGURE_PATHS::OnRemoveEnvVar( wxCommandEvent& event )
if( curRow < 0 || m_EnvVars->GetNumberRows() <= curRow )
return;
else if( IsEnvVarImmutable( m_EnvVars->GetCellValue( curRow, EV_NAME_COL ) ) )
else if( IsEnvVarImmutable( m_EnvVars->GetCellValue( curRow, TV_NAME_COL ) ) )
{
wxBell();
return;
@ -468,9 +468,9 @@ void DIALOG_CONFIGURE_PATHS::OnSearchPathMoveDown( wxCommandEvent& event )
void DIALOG_CONFIGURE_PATHS::OnGridCellRightClick( wxGridEvent& aEvent )
{
wxASSERT( (int) EV_PATH_COL == (int) SP_PATH_COL );
wxASSERT((int) TV_VALUE_COL == (int) SP_PATH_COL );
if( aEvent.GetCol() == EV_PATH_COL )
if( aEvent.GetCol() == TV_VALUE_COL )
{
wxMenu menu;
@ -483,7 +483,7 @@ void DIALOG_CONFIGURE_PATHS::OnGridCellRightClick( wxGridEvent& aEvent )
if( dlg.ShowModal() == wxID_OK )
{
wxGrid* grid = dynamic_cast<wxGrid*>( aEvent.GetEventObject() );
grid->SetCellValue( aEvent.GetRow(), EV_PATH_COL, dlg.GetPath() );
grid->SetCellValue( aEvent.GetRow(), TV_VALUE_COL, dlg.GetPath() );
m_curdir = dlg.GetPath();
}
}
@ -506,10 +506,10 @@ void DIALOG_CONFIGURE_PATHS::OnUpdateUI( wxUpdateUIEvent& event )
{
int width = m_EnvVars->GetClientRect().GetWidth();
m_EnvVars->AutoSizeColumn( EV_NAME_COL );
m_EnvVars->SetColSize( EV_NAME_COL, std::max( m_EnvVars->GetColSize( EV_NAME_COL ), 120 ) );
m_EnvVars->AutoSizeColumn( TV_NAME_COL );
m_EnvVars->SetColSize( TV_NAME_COL, std::max( m_EnvVars->GetColSize( TV_NAME_COL ), 120 ) );
m_EnvVars->SetColSize( EV_PATH_COL, width - m_EnvVars->GetColSize( EV_NAME_COL ) );
m_EnvVars->SetColSize( TV_VALUE_COL, width - m_EnvVars->GetColSize( TV_NAME_COL ) );
width = m_SearchPaths->GetClientRect().GetWidth();

View File

@ -758,7 +758,8 @@ void DIALOG_PAGES_SETTINGS::UpdatePageLayoutExample()
WS_DATA_MODEL::SetAltInstance( m_pagelayout );
GRFilledRect( NULL, &memDC, 0, 0, m_layout_size.x, m_layout_size.y, WHITE, WHITE );
PrintPageLayout( &memDC, pageDUMMY, emptyString, emptyString, m_tb,
m_screen->m_NumberOfScreens, m_screen->m_ScreenNumber, 1, 1, RED );
m_screen->m_NumberOfScreens, m_screen->m_ScreenNumber, 1, 1, RED,
&Prj() );
memDC.SelectObject( wxNullBitmap );
m_PageLayoutExampleBitmap->SetBitmap( *m_page_bitmap );

View File

@ -0,0 +1,229 @@
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 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
* as published by the Free Software Foundation; either version 2
* 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, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <panel_text_variables.h>
#include <bitmaps.h>
#include <confirm.h>
#include <validators.h>
#include <project.h>
#include <grid_tricks.h>
#include <widgets/wx_grid.h>
enum TEXT_VAR_GRID_COLUMNS
{
TV_NAME_COL = 0,
TV_VALUE_COL
};
PANEL_TEXT_VARIABLES::PANEL_TEXT_VARIABLES( wxWindow* aParent, PROJECT* aProject ) :
PANEL_TEXT_VARIABLES_BASE( aParent ),
m_project( aProject ),
m_errorRow( -1 ), m_errorCol( -1 ),
m_gridWidthsDirty( true )
{
m_btnAddTextVar->SetBitmap( KiBitmap( small_plus_xpm ) );
m_btnDeleteTextVar->SetBitmap( KiBitmap( trash_xpm ) );
m_TextVars->DeleteRows( 0, m_TextVars->GetNumberRows() );
// prohibit these characters in the alias names: []{}()%~<>"='`;:.,&?/\|$
m_nameValidator.SetStyle( wxFILTER_EXCLUDE_CHAR_LIST );
m_nameValidator.SetCharExcludes( wxT( "{}[]()%~<>\"='`;:.,&?/\\|$" ) );
m_TextVars->PushEventHandler( new GRID_TRICKS( m_TextVars ) );
m_TextVars->SetSelectionMode( wxGrid::wxGridSelectionModes::wxGridSelectRows );
// wxFormBuilder doesn't include this event...
m_TextVars->Connect( wxEVT_GRID_CELL_CHANGING, wxGridEventHandler( PANEL_TEXT_VARIABLES::OnGridCellChanging ), NULL, this );
}
PANEL_TEXT_VARIABLES::~PANEL_TEXT_VARIABLES()
{
// Delete the GRID_TRICKS.
m_TextVars->PopEventHandler( true );
m_TextVars->Disconnect( wxEVT_GRID_CELL_CHANGING, wxGridEventHandler( PANEL_TEXT_VARIABLES::OnGridCellChanging ), NULL, this );
}
bool PANEL_TEXT_VARIABLES::TransferDataToWindow()
{
std::map<wxString, wxString>& variables = m_project->GetTextVars();
for( const auto& var : variables )
AppendTextVar( var.first, var.second );
return true;
}
void PANEL_TEXT_VARIABLES::AppendTextVar( const wxString& aName, const wxString& aValue )
{
int i = m_TextVars->GetNumberRows();
m_TextVars->AppendRows( 1 );
m_TextVars->SetCellValue( i, TV_NAME_COL, aName );
wxGridCellAttr* nameCellAttr = m_TextVars->GetOrCreateCellAttr( i, TV_NAME_COL );
wxGridCellTextEditor* nameTextEditor = new GRID_CELL_TEXT_EDITOR();
nameTextEditor->SetValidator( m_nameValidator );
nameCellAttr->SetEditor( nameTextEditor );
nameCellAttr->DecRef();
m_TextVars->SetCellValue( i, TV_VALUE_COL, aValue );
}
bool PANEL_TEXT_VARIABLES::TransferDataFromWindow()
{
if( !m_TextVars->CommitPendingChanges() )
return false;
for( int row = 0; row < m_TextVars->GetNumberRows(); ++row )
{
if( m_TextVars->GetCellValue( row, TV_NAME_COL ).IsEmpty() )
{
m_errorRow = row;
m_errorCol = TV_NAME_COL;
m_errorMsg = _( "Variable name cannot be empty." );
return false;
}
}
std::map<wxString, wxString>& variables = m_project->GetTextVars();
variables.clear();
for( int row = 0; row < m_TextVars->GetNumberRows(); ++row )
{
wxString name = m_TextVars->GetCellValue( row, TV_NAME_COL );
wxString value = m_TextVars->GetCellValue( row, TV_VALUE_COL );
variables[ name ] = value;
}
return true;
}
void PANEL_TEXT_VARIABLES::OnGridCellChanging( wxGridEvent& event )
{
int row = event.GetRow();
int col = event.GetCol();
wxString text = event.GetString();
if( text.IsEmpty() && col == TV_NAME_COL )
{
m_errorMsg = _( "Variable name cannot be empty." );
m_errorRow = row;
m_errorCol = col;
event.Veto();
}
}
void PANEL_TEXT_VARIABLES::OnAddTextVar( wxCommandEvent& event )
{
if( !m_TextVars->CommitPendingChanges() )
return;
AppendTextVar( wxEmptyString, wxEmptyString );
m_TextVars->MakeCellVisible( m_TextVars->GetNumberRows() - 1, TV_NAME_COL );
m_TextVars->SetGridCursor( m_TextVars->GetNumberRows() - 1, TV_NAME_COL );
m_TextVars->EnableCellEditControl( true );
m_TextVars->ShowCellEditControl();
}
void PANEL_TEXT_VARIABLES::OnRemoveTextVar( wxCommandEvent& event )
{
int curRow = m_TextVars->GetGridCursorRow();
if( curRow < 0 || m_TextVars->GetNumberRows() <= curRow )
return;
m_TextVars->CommitPendingChanges( true /* silent mode; we don't care if it's valid */ );
m_TextVars->DeleteRows( curRow, 1 );
m_TextVars->MakeCellVisible( std::max( 0, curRow-1 ), m_TextVars->GetGridCursorCol() );
m_TextVars->SetGridCursor( std::max( 0, curRow-1 ), m_TextVars->GetGridCursorCol() );
}
void PANEL_TEXT_VARIABLES::OnGridCellChange( wxGridEvent& aEvent )
{
m_gridWidthsDirty = true;
aEvent.Skip();
}
void PANEL_TEXT_VARIABLES::OnUpdateUI( wxUpdateUIEvent& event )
{
if( m_gridWidthsDirty && ( !m_TextVars->IsCellEditControlShown() ) )
{
int width = m_TextVars->GetClientRect().GetWidth();
m_TextVars->AutoSizeColumn( TV_NAME_COL );
m_TextVars->SetColSize( TV_NAME_COL, std::max( m_TextVars->GetColSize( TV_NAME_COL ), 120 ) );
m_TextVars->SetColSize( TV_VALUE_COL, width - m_TextVars->GetColSize( TV_NAME_COL ) );
m_gridWidthsDirty = false;
}
// Handle a grid error. This is delayed to OnUpdateUI so that we can change focus
// even when the original validation was triggered from a killFocus event (and for
// dialog with notebooks, so that the corresponding notebook page can be shown in
// the background when triggered from an OK).
if( !m_errorMsg.IsEmpty() )
{
// We will re-enter this routine when the error dialog is displayed, so make
// sure we don't keep putting up more dialogs.
wxString errorMsg = m_errorMsg;
m_errorMsg = wxEmptyString;
DisplayErrorMessage( this, errorMsg );
m_TextVars->SetFocus();
m_TextVars->MakeCellVisible( m_errorRow, m_errorCol );
m_TextVars->SetGridCursor( m_errorRow, m_errorCol );
m_TextVars->EnableCellEditControl( true );
m_TextVars->ShowCellEditControl();
}
}
void PANEL_TEXT_VARIABLES::OnGridSize( wxSizeEvent& event )
{
m_gridWidthsDirty = true;
event.Skip();
}

View File

@ -0,0 +1,98 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Oct 26 2018)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "widgets/wx_grid.h"
#include "panel_text_variables_base.h"
///////////////////////////////////////////////////////////////////////////
PANEL_TEXT_VARIABLES_BASE::PANEL_TEXT_VARIABLES_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxPanel( parent, id, pos, size, style, name )
{
wxBoxSizer* bPanelSizer;
bPanelSizer = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bSizer3;
bSizer3 = new wxBoxSizer( wxVERTICAL );
m_TextVars = new WX_GRID( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
// Grid
m_TextVars->CreateGrid( 1, 2 );
m_TextVars->EnableEditing( true );
m_TextVars->EnableGridLines( true );
m_TextVars->EnableDragGridSize( false );
m_TextVars->SetMargins( 0, 0 );
// Columns
m_TextVars->SetColSize( 0, 150 );
m_TextVars->SetColSize( 1, 454 );
m_TextVars->EnableDragColMove( false );
m_TextVars->EnableDragColSize( true );
m_TextVars->SetColLabelSize( 22 );
m_TextVars->SetColLabelValue( 0, _("Variable Name") );
m_TextVars->SetColLabelValue( 1, _("Text Substitution") );
m_TextVars->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
// Rows
m_TextVars->EnableDragRowSize( true );
m_TextVars->SetRowLabelSize( 0 );
m_TextVars->SetRowLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
// Label Appearance
// Cell Defaults
m_TextVars->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
m_TextVars->SetMinSize( wxSize( 604,170 ) );
bSizer3->Add( m_TextVars, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
wxBoxSizer* bSizerEnvVarBtns;
bSizerEnvVarBtns = new wxBoxSizer( wxHORIZONTAL );
m_btnAddTextVar = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
m_btnAddTextVar->SetMinSize( wxSize( 30,29 ) );
bSizerEnvVarBtns->Add( m_btnAddTextVar, 0, wxRIGHT, 5 );
bSizerEnvVarBtns->Add( 0, 0, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
m_btnDeleteTextVar = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
m_btnDeleteTextVar->SetMinSize( wxSize( 30,29 ) );
bSizerEnvVarBtns->Add( m_btnDeleteTextVar, 0, wxRIGHT|wxLEFT, 5 );
bSizer3->Add( bSizerEnvVarBtns, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
bPanelSizer->Add( bSizer3, 1, wxEXPAND|wxTOP|wxLEFT, 10 );
this->SetSizer( bPanelSizer );
this->Layout();
bPanelSizer->Fit( this );
// Connect Events
this->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( PANEL_TEXT_VARIABLES_BASE::OnUpdateUI ) );
m_TextVars->Connect( wxEVT_GRID_CELL_CHANGED, wxGridEventHandler( PANEL_TEXT_VARIABLES_BASE::OnGridCellChange ), NULL, this );
m_TextVars->Connect( wxEVT_SIZE, wxSizeEventHandler( PANEL_TEXT_VARIABLES_BASE::OnGridSize ), NULL, this );
m_btnAddTextVar->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_TEXT_VARIABLES_BASE::OnAddTextVar ), NULL, this );
m_btnDeleteTextVar->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_TEXT_VARIABLES_BASE::OnRemoveTextVar ), NULL, this );
}
PANEL_TEXT_VARIABLES_BASE::~PANEL_TEXT_VARIABLES_BASE()
{
// Disconnect Events
this->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( PANEL_TEXT_VARIABLES_BASE::OnUpdateUI ) );
m_TextVars->Disconnect( wxEVT_GRID_CELL_CHANGED, wxGridEventHandler( PANEL_TEXT_VARIABLES_BASE::OnGridCellChange ), NULL, this );
m_TextVars->Disconnect( wxEVT_SIZE, wxSizeEventHandler( PANEL_TEXT_VARIABLES_BASE::OnGridSize ), NULL, this );
m_btnAddTextVar->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_TEXT_VARIABLES_BASE::OnAddTextVar ), NULL, this );
m_btnDeleteTextVar->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_TEXT_VARIABLES_BASE::OnRemoveTextVar ), NULL, this );
}

View File

@ -0,0 +1,329 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<wxFormBuilder_Project>
<FileVersion major="1" minor="15" />
<object class="Project" expanded="1">
<property name="class_decoration"></property>
<property name="code_generation">C++</property>
<property name="disconnect_events">1</property>
<property name="disconnect_mode">source_name</property>
<property name="disconnect_php_events">0</property>
<property name="disconnect_python_events">0</property>
<property name="embedded_files_path">res</property>
<property name="encoding">UTF-8</property>
<property name="event_generation">connect</property>
<property name="file">panel_text_variables_base</property>
<property name="first_id">1000</property>
<property name="help_provider">none</property>
<property name="indent_with_spaces"></property>
<property name="internationalize">1</property>
<property name="name">PanelTextVariables</property>
<property name="namespace"></property>
<property name="path">.</property>
<property name="precompiled_header"></property>
<property name="relative_path">1</property>
<property name="skip_lua_events">1</property>
<property name="skip_php_events">1</property>
<property name="skip_python_events">1</property>
<property name="ui_table">UI</property>
<property name="use_enum">1</property>
<property name="use_microsoft_bom">0</property>
<object class="Panel" expanded="1">
<property name="aui_managed">0</property>
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
<property name="bg"></property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="enabled">1</property>
<property name="event_handler">impl_virtual</property>
<property name="fg"></property>
<property name="font"></property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="maximum_size"></property>
<property name="minimum_size"></property>
<property name="name">PANEL_TEXT_VARIABLES_BASE</property>
<property name="pos"></property>
<property name="size">-1,-1</property>
<property name="subclass">; forward_declare</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style">wxTAB_TRAVERSAL</property>
<event name="OnUpdateUI">OnUpdateUI</event>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bPanelSizer</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">10</property>
<property name="flag">wxEXPAND|wxTOP|wxLEFT</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizer3</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
<property name="proportion">1</property>
<object class="wxGrid" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="autosize_cols">0</property>
<property name="autosize_rows">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="cell_bg"></property>
<property name="cell_font"></property>
<property name="cell_horiz_alignment">wxALIGN_LEFT</property>
<property name="cell_text"></property>
<property name="cell_vert_alignment">wxALIGN_TOP</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="col_label_horiz_alignment">wxALIGN_CENTER</property>
<property name="col_label_size">22</property>
<property name="col_label_values">&quot;Variable Name&quot; &quot;Text Substitution&quot;</property>
<property name="col_label_vert_alignment">wxALIGN_CENTER</property>
<property name="cols">2</property>
<property name="column_sizes">150,454</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_col_move">0</property>
<property name="drag_col_size">1</property>
<property name="drag_grid_size">0</property>
<property name="drag_row_size">1</property>
<property name="editing">1</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="grid_line_color"></property>
<property name="grid_lines">1</property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label_bg"></property>
<property name="label_font"></property>
<property name="label_text"></property>
<property name="margin_height">0</property>
<property name="margin_width">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size">604,170</property>
<property name="moveable">1</property>
<property name="name">m_TextVars</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="row_label_horiz_alignment">wxALIGN_CENTER</property>
<property name="row_label_size">0</property>
<property name="row_label_values"></property>
<property name="row_label_vert_alignment">wxALIGN_CENTER</property>
<property name="row_sizes"></property>
<property name="rows">1</property>
<property name="show">1</property>
<property name="size"></property>
<property name="subclass">WX_GRID; widgets/wx_grid.h; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnGridCellChange">OnGridCellChange</event>
<event name="OnSize">OnGridSize</event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizerEnvVarBtns</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxRIGHT</property>
<property name="proportion">0</property>
<object class="wxBitmapButton" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Add Text Variable</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size">30,29</property>
<property name="moveable">1</property>
<property name="name">m_btnAddTextVar</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">OnAddTextVar</event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="spacer" expanded="1">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxBitmapButton" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Delete Text Variable</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size">30,29</property>
<property name="moveable">1</property>
<property name="name">m_btnDeleteTextVar</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">OnRemoveTextVar</event>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</wxFormBuilder_Project>

View File

@ -0,0 +1,57 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Oct 26 2018)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#pragma once
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
class WX_GRID;
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/string.h>
#include <wx/font.h>
#include <wx/grid.h>
#include <wx/gdicmn.h>
#include <wx/bmpbuttn.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/button.h>
#include <wx/sizer.h>
#include <wx/panel.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class PANEL_TEXT_VARIABLES_BASE
///////////////////////////////////////////////////////////////////////////////
class PANEL_TEXT_VARIABLES_BASE : public wxPanel
{
private:
protected:
WX_GRID* m_TextVars;
wxBitmapButton* m_btnAddTextVar;
wxBitmapButton* m_btnDeleteTextVar;
// Virtual event handlers, overide them in your derived class
virtual void OnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void OnGridCellChange( wxGridEvent& event ) { event.Skip(); }
virtual void OnGridSize( wxSizeEvent& event ) { event.Skip(); }
virtual void OnAddTextVar( wxCommandEvent& event ) { event.Skip(); }
virtual void OnRemoveTextVar( wxCommandEvent& event ) { event.Skip(); }
public:
PANEL_TEXT_VARIABLES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString );
~PANEL_TEXT_VARIABLES_BASE();
};

View File

@ -731,7 +731,7 @@ static const wxString productName = wxT( "KiCad E.D.A. " );
void PrintPageLayout( wxDC* aDC, const PAGE_INFO& aPageInfo, const wxString& aFullSheetName,
const wxString& aFileName, const TITLE_BLOCK& aTitleBlock, int aSheetCount,
int aSheetNumber, int aPenWidth, double aScalar, COLOR4D aColor,
const wxString& aSheetLayer )
const PROJECT* aProject, const wxString& aSheetLayer )
{
WS_DRAW_ITEM_LIST drawList;
@ -742,6 +742,7 @@ void PrintPageLayout( wxDC* aDC, const PAGE_INFO& aPageInfo, const wxString& aFu
drawList.SetFileName( aFileName );
drawList.SetSheetName( aFullSheetName );
drawList.SetSheetLayer( aSheetLayer );
drawList.SetProject( aProject );
drawList.BuildWorkSheetGraphicList( aPageInfo, aTitleBlock );
@ -769,7 +770,7 @@ void EDA_DRAW_FRAME::PrintWorkSheet( wxDC* aDC, BASE_SCREEN* aScreen, int aLineW
PrintPageLayout( aDC, GetPageSettings(), GetScreenDesc(), aFilename, GetTitleBlock(),
aScreen->m_NumberOfScreens, aScreen->m_ScreenNumber, aLineWidth, aScalar,
color, aSheetLayer );
color, &Prj(), aSheetLayer );
if( origin.y > 0 )
{

View File

@ -113,6 +113,80 @@ PAGE_LAYOUT_READER_PARSER::PAGE_LAYOUT_READER_PARSER( const char* aLine, const w
}
wxString convertLegacyVariableRefs( const wxString& aTextbase )
{
wxString msg;
/*
* Legacy formats
* %% = replaced by %
* %K = Kicad version
* %Z = paper format name (A4, USLetter)
* %Y = company name
* %D = date
* %R = revision
* %S = sheet number
* %N = number of sheets
* %L = layer name
* %Cx = comment (x = 0 to 9 to identify the comment)
* %F = filename
* %P = sheet path (sheet full name)
* %T = title
*/
for( unsigned ii = 0; ii < aTextbase.Len(); ii++ )
{
if( aTextbase[ii] != '%' )
{
msg << aTextbase[ii];
continue;
}
if( ++ii >= aTextbase.Len() )
break;
wxChar format = aTextbase[ii];
switch( format )
{
case '%': msg += '%'; break;
case 'D': msg += wxT( "${ISSUE_DATE}" ); break;
case 'R': msg += wxT( "${REVISION}" ); break;
case 'K': msg += wxT( "${KICAD_VERSION}" ); break;
case 'Z': msg += wxT( "${PAPER}" ); break;
case 'S': msg += wxT( "${#}" ); break;
case 'N': msg += wxT( "${##}" ); break;
case 'F': msg += wxT( "${FILENAME}" ); break;
case 'L': msg += wxT( "${LAYER}" ); break;
case 'P': msg += wxT( "${SHEETNAME}" ); break;
case 'Y': msg += wxT( "${COMPANY}" ); break;
case 'T': msg += wxT( "${TITLE}" ); break;
case 'C':
format = aTextbase[++ii];
switch( format )
{
case '0': msg += wxT( "${COMMENT0}" ); break;
case '1': msg += wxT( "${COMMENT1}" ); break;
case '2': msg += wxT( "${COMMENT2}" ); break;
case '3': msg += wxT( "${COMMENT3}" ); break;
case '4': msg += wxT( "${COMMENT4}" ); break;
case '5': msg += wxT( "${COMMENT5}" ); break;
case '6': msg += wxT( "${COMMENT6}" ); break;
case '7': msg += wxT( "${COMMENT7}" ); break;
case '8': msg += wxT( "${COMMENT8}" ); break;
case '9': msg += wxT( "${COMMENT9}" ); break;
}
default:
break;
}
}
return msg;
}
void PAGE_LAYOUT_READER_PARSER::Parse( WS_DATA_MODEL* aLayout )
{
WS_DATA_ITEM* item;
@ -158,7 +232,7 @@ void PAGE_LAYOUT_READER_PARSER::Parse( WS_DATA_MODEL* aLayout )
case T_tbtext:
NeedSYMBOLorNUMBER();
item = new WS_DATA_ITEM_TEXT( FromUTF8() );
item = new WS_DATA_ITEM_TEXT( convertLegacyVariableRefs( FromUTF8() ) );
parseText( (WS_DATA_ITEM_TEXT*) item );
aLayout->Append( item );
break;
@ -170,6 +244,7 @@ void PAGE_LAYOUT_READER_PARSER::Parse( WS_DATA_MODEL* aLayout )
}
}
void PAGE_LAYOUT_READER_PARSER::parseSetup( WS_DATA_MODEL* aLayout )
{
for( T token = NextTok(); token != T_RIGHT && token != EOF; token = NextTok() )

View File

@ -89,124 +89,93 @@ const COLOR4D& WS_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer
// after replacing format symbols by the corresponding value
wxString WS_DRAW_ITEM_LIST::BuildFullText( const wxString& aTextbase )
{
wxString msg;
auto wsResolver = [ this ]( wxString* token ) -> bool
{
if( token->IsSameAs( wxT( "KICAD_VERSION" ) ) )
{
*token = wxString::Format( wxT( "%s%s %s" ),
productName,
Pgm().App().GetAppName(),
GetBuildVersion() );
return true;
}
else if( token->IsSameAs( wxT( "#" ) ) )
{
*token = wxString::Format( wxT( "%d" ), m_sheetNumber );
return true;
}
else if( token->IsSameAs( wxT( "##" ) ) )
{
*token = wxString::Format( wxT( "%d" ), m_sheetCount );
return true;
}
else if( token->IsSameAs( wxT( "SHEETNAME" ) ) )
{
*token = m_sheetFullName;
return true;
}
else if( token->IsSameAs( wxT( "FILENAME" ) ) )
{
wxFileName fn( m_fileName );
*token = fn.GetFullName();
return true;
}
else if( token->IsSameAs( wxT( "PAPER" ) ) )
{
*token = m_paperFormat ? *m_paperFormat : wxEmptyString;
return true;
}
else if( token->IsSameAs( wxT( "LAYER" ) ) )
{
*token = m_sheetLayer ? *m_sheetLayer : wxEmptyString;
return true;
}
else if( token->IsSameAs( wxT( "ISSUE_DATE" ) ) )
{
*token = m_titleBlock ? m_titleBlock->GetDate() : wxEmptyString;
return true;
}
else if( token->IsSameAs( wxT( "REVISION" ) ) )
{
*token = m_titleBlock ? m_titleBlock->GetRevision() : wxEmptyString;
return true;
}
else if( token->IsSameAs( wxT( "TITLE" ) ) )
{
*token = m_titleBlock ? m_titleBlock->GetTitle() : wxEmptyString;
return true;
}
else if( token->IsSameAs( wxT( "COMPANY" ) ) )
{
*token = m_titleBlock ? m_titleBlock->GetCompany() : wxEmptyString;
return true;
}
else if( token->Left( token->Len()-1 ).IsSameAs( wxT( "COMMENT" ) ) )
{
wxChar c = token->Last();
/* Known formats
* %% = replaced by %
* %K = Kicad version
* %Z = paper format name (A4, USLetter)
* %Y = company name
* %D = date
* %R = revision
* %S = sheet number
* %N = number of sheets
* %L = layer name
* %Cx = comment (x = 0 to 9 to identify the comment)
* %F = filename
* %P = sheet path (sheet full name)
* %T = title
*/
switch( c )
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
*token = m_titleBlock ? m_titleBlock->GetComment( c - '0' )
: wxEmptyString;
return true;
}
}
for( unsigned ii = 0; ii < aTextbase.Len(); ii++ )
{
if( aTextbase[ii] != '%' )
{
msg << aTextbase[ii];
continue;
}
return false;
};
if( ++ii >= aTextbase.Len() )
break;
wxChar format = aTextbase[ii];
switch( format )
{
case '%':
msg += '%';
break;
case 'D':
if( m_titleBlock )
msg += m_titleBlock->GetDate();
break;
case 'R':
if( m_titleBlock )
msg += m_titleBlock->GetRevision();
break;
case 'K':
msg += productName + Pgm().App().GetAppName();
msg += wxT( " " ) + GetBuildVersion();
break;
case 'Z':
if( m_paperFormat )
msg += *m_paperFormat;
break;
case 'S':
msg << m_sheetNumber;
break;
case 'N':
msg << m_sheetCount;
break;
case 'F':
{
wxFileName fn( m_fileName );
msg += fn.GetFullName();
}
break;
case 'L':
if( m_sheetLayer )
msg += *m_sheetLayer;
break;
case 'P':
msg += m_sheetFullName;
break;
case 'Y':
if( m_titleBlock )
msg += m_titleBlock->GetCompany();
break;
case 'T':
if( m_titleBlock )
msg += m_titleBlock->GetTitle();
break;
case 'C':
format = aTextbase[++ii];
switch( format )
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if( m_titleBlock )
msg += m_titleBlock->GetComment( format - '0');
break;
default:
break;
}
default:
break;
}
}
return msg;
return ExpandTextVars( aTextbase, wsResolver, m_project );
}

View File

@ -1,7 +1,7 @@
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2013-2019 CERN
* Copyright (C) 2013-2020 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
@ -25,8 +25,6 @@
#include <ws_proxy_view_item.h>
#include <ws_draw_item.h>
#include <ws_data_item.h>
#include <gal/graphics_abstraction_layer.h>
#include <painter.h>
#include <layers_id_colors_and_visibility.h>
#include <page_info.h>
#include <view/view.h>
@ -35,30 +33,19 @@
using namespace KIGFX;
WS_PROXY_VIEW_ITEM::WS_PROXY_VIEW_ITEM( int aMils2IUscalefactor, const PAGE_INFO* aPageInfo,
const TITLE_BLOCK* aTitleBlock ) :
const PROJECT* aProject, const TITLE_BLOCK* aTitleBlock ) :
EDA_ITEM( NOT_USED ), // this item is never added to a BOARD so it needs no type
m_mils2IUscalefactor( aMils2IUscalefactor ),
m_titleBlock( aTitleBlock ),
m_pageInfo( aPageInfo ),
m_sheetNumber( 1 ),
m_sheetCount( 1 ),
m_project( aProject ),
m_colorLayer( LAYER_WORKSHEET )
{
}
void WS_PROXY_VIEW_ITEM::SetPageInfo( const PAGE_INFO* aPageInfo )
{
m_pageInfo = aPageInfo;
}
void WS_PROXY_VIEW_ITEM::SetTitleBlock( const TITLE_BLOCK* aTitleBlock )
{
m_titleBlock = aTitleBlock;
}
const BOX2I WS_PROXY_VIEW_ITEM::ViewBBox() const
{
BOX2I bbox;
@ -95,6 +82,7 @@ void WS_PROXY_VIEW_ITEM::ViewDraw( int aLayer, VIEW* aView ) const
drawList.SetSheetCount( m_sheetCount );
drawList.SetFileName( fileName );
drawList.SetSheetName( sheetName );
drawList.SetProject( m_project );
drawList.BuildWorkSheetGraphicList( *m_pageInfo, *m_titleBlock );

View File

@ -886,7 +886,7 @@ void DXF_PLOTTER::Text( const wxPoint& aPos,
if( ( GetTextMarkupFlags() & ENABLE_SUPERSCRIPT_MARKUP ) && aText.Contains( wxT( "^" ) ) )
processSuperSub = true;
if( textAsLines || containsNonAsciiChars( aText ) || aMultilineAllowed || processSuperSub )
if( m_textAsLines || containsNonAsciiChars( aText ) || aMultilineAllowed || processSuperSub )
{
// output text as graphics.
// Perhaps multiline texts could be handled as DXF text entity

View File

@ -57,9 +57,9 @@ wxString GetDefaultPlotExtension( PLOT_FORMAT aFormat )
}
void PlotWorkSheet( PLOTTER* plotter, const TITLE_BLOCK& aTitleBlock,
void PlotWorkSheet( PLOTTER* plotter, const PROJECT* aProject, const TITLE_BLOCK& aTitleBlock,
const PAGE_INFO& aPageInfo, int aSheetNumber, int aNumberOfSheets,
const wxString &aSheetDesc, const wxString &aFilename, const COLOR4D aColor )
const wxString &aSheetDesc, const wxString &aFilename, COLOR4D aColor )
{
/* Note: Page sizes values are given in mils
*/
@ -83,7 +83,7 @@ void PlotWorkSheet( PLOTTER* plotter, const TITLE_BLOCK& aTitleBlock,
drawList.SetSheetCount( aNumberOfSheets );
drawList.SetFileName( fn.GetFullName() ); // Print only the short filename
drawList.SetSheetName( aSheetDesc );
drawList.SetProject( aProject );
drawList.BuildWorkSheetGraphicList( aPageInfo, aTitleBlock );

View File

@ -61,6 +61,18 @@ PROJECT::~PROJECT()
}
bool PROJECT::TextVarResolver( wxString* aToken ) const
{
if( m_textVars.count( *aToken ) > 0 )
{
*aToken = m_textVars.at( *aToken );
return true;
}
return false;
}
void PROJECT::SetProjectFullName( const wxString& aFullPathAndName )
{
// Compare paths, rather than inodes, to be less surprising to the user.
@ -376,6 +388,16 @@ void PROJECT::ConfigSave( const SEARCH_STACK& aSList, const wxString& aGroupName
wxConfigSaveParams( cfg.get(), aParams, aGroupName );
cfg->DeleteGroup( GROUP_TEXT_VARS );
cfg->SetPath( GROUP_TEXT_VARS );
int index = 1;
for( const auto& textvar : m_textVars )
{
cfg->Write( wxString::Format( "%d", index++ ),
wxString::Format( "%s:%s", textvar.first, textvar.second ) );
}
cfg->SetPath( wxT( "/" ) );
cfg->Flush();
@ -396,7 +418,7 @@ bool PROJECT::ConfigLoad( const SEARCH_STACK& aSList, const wxString& aGroupNam
}
// We do not want expansion of env var values when reading our project config file
cfg.get()->SetExpandEnvVars( false );
cfg->SetExpandEnvVars( false );
cfg->SetPath( wxCONFIG_PATH_SEPARATOR );
@ -406,6 +428,18 @@ bool PROJECT::ConfigLoad( const SEARCH_STACK& aSList, const wxString& aGroupNam
wxConfigLoadParams( cfg.get(), aParams, aGroupName );
cfg->SetPath( GROUP_TEXT_VARS );
int index = 1;
wxString entry;
while( cfg->Read( wxString::Format( "%d", index++ ), &entry ) )
{
wxArrayString tokens = wxSplit( entry, ':' );
if( tokens.size() == 2 )
m_textVars[ tokens[0] ] = tokens[1];
}
return true;
}

View File

@ -221,7 +221,6 @@ set( EESCHEMA_SRCS
symbol_lib_table.cpp
symbol_tree_model_adapter.cpp
symbol_tree_synchronizing_adapter.cpp
template_fieldnames.cpp
toolbars_lib_view.cpp
toolbars_sch_editor.cpp
transform.cpp
@ -473,14 +472,6 @@ make_lexer(
TLIB_T
)
make_lexer(
eeschema_kiface_objects
template_fieldnames.keywords
template_fieldnames_lexer.h
template_fieldnames_keywords.cpp
TFIELD_T
)
make_lexer(
eeschema_kiface_objects
dialogs/dialog_bom_cfg.keywords

View File

@ -584,15 +584,8 @@ void LIB_PART::RemoveDrawItem( LIB_ITEM* aItem )
// omitted when saving to disk.
if( aItem->Type() == LIB_FIELD_T )
{
LIB_FIELD* field = (LIB_FIELD*) aItem;
if( field->GetId() < MANDATORY_FIELDS )
{
wxLogWarning( _(
"An attempt was made to remove the %s field from component %s in library %s." ),
field->GetName( TRANSLATE_FIELD_NAME ), GetName(), GetLibraryName() );
if( static_cast<LIB_FIELD*>( aItem )->GetId() < MANDATORY_FIELDS )
return;
}
}
LIB_ITEMS& items = m_drawings[ aItem->Type() ];
@ -880,7 +873,7 @@ LIB_FIELD* LIB_PART::FindField( const wxString& aFieldName )
{
LIB_FIELD* field = ( LIB_FIELD* ) &item;
if( field->GetName( NATIVE_FIELD_NAME ) == aFieldName )
if( field->GetCanonicalName() == aFieldName )
return field;
}

View File

@ -25,13 +25,11 @@
#include <panel_setup_pinmap.h>
#include <eeschema_config.h>
#include <erc_item.h>
#include <panel_text_variables.h>
#include "dialog_schematic_setup.h"
#include "panel_eeschema_template_fieldnames.h"
bool g_macHack;
DIALOG_SCHEMATIC_SETUP::DIALOG_SCHEMATIC_SETUP( SCH_EDIT_FRAME* aFrame ) :
PAGED_DIALOG( aFrame, _( "Schematic Setup" ),
_( "Import Settings from Another Project..." ) ),
@ -45,6 +43,9 @@ DIALOG_SCHEMATIC_SETUP::DIALOG_SCHEMATIC_SETUP( SCH_EDIT_FRAME* aFrame ) :
ERC_ITEM dummyItem;
m_severities = new PANEL_SETUP_SEVERITIES( this, dummyItem, g_ErcSettings->m_Severities,
ERCE_FIRST, ERCE_LAST );
m_textVars = new PANEL_TEXT_VARIABLES( this, &Prj() );
/*
* WARNING: If you change page names you MUST update calls to DoShowSchematicSetupDialog().
*/
@ -57,12 +58,17 @@ DIALOG_SCHEMATIC_SETUP::DIALOG_SCHEMATIC_SETUP( SCH_EDIT_FRAME* aFrame ) :
m_treebook->AddSubPage( m_pinMap, _( "Pin Map" ) );
m_treebook->AddSubPage( m_severities, _( "Violation Severity" ) );
m_treebook->AddPage( new wxPanel( this ), _( "Project" ) );
m_treebook->AddSubPage( m_textVars, _( "Text Variables" ) );
// Connect Events
m_treebook->Connect( wxEVT_TREEBOOK_PAGE_CHANGED,
wxBookCtrlEventHandler( DIALOG_SCHEMATIC_SETUP::OnPageChange ), NULL, this );
FinishDialogSettings();
g_macHack = true;
for( int i = 0; i < m_treebook->GetPageCount(); ++i )
m_macHack.push_back( true );
}
@ -76,16 +82,17 @@ DIALOG_SCHEMATIC_SETUP::~DIALOG_SCHEMATIC_SETUP()
void DIALOG_SCHEMATIC_SETUP::OnPageChange( wxBookCtrlEvent& event )
{
#ifdef __WXMAC__
// Work around an OSX bug where the wxGrid children don't get placed correctly
if( g_macHack && m_treebook->GetPage( event.GetSelection() ) == m_fieldNameTemplates )
// Work around an OSX bug where the wxGrid children don't get placed correctly until
// the first resize event
int page = event.GetSelection();
if( m_macHack[ page ] )
{
m_fieldNameTemplates->SetSize( wxSize( m_fieldNameTemplates->GetSize().x - 1,
m_fieldNameTemplates->GetSize().y ) );
wxSize pageSize = m_treebook->GetPage( page )->GetSize();
pageSize.x -= 1;
wxPoint pos = m_fieldNameTemplates->GetPosition();
m_fieldNameTemplates->Move( pos.x + 6, pos.y + 6 );
g_macHack = false;
m_treebook->GetPage( page )->SetSize( pageSize );
m_macHack[ page ] = false;
}
#endif
}

View File

@ -28,6 +28,7 @@ class PANEL_SETUP_SEVERITIES;
class PANEL_EESCHEMA_TEMPLATE_FIELDNAMES;
class PANEL_SETUP_FORMATTING;
class PANEL_SETUP_PINMAP;
class PANEL_TEXT_VARIABLES;
class DIALOG_SCHEMATIC_SETUP : public PAGED_DIALOG
@ -45,6 +46,9 @@ protected:
PANEL_EESCHEMA_TEMPLATE_FIELDNAMES* m_fieldNameTemplates;
PANEL_SETUP_PINMAP* m_pinMap;
PANEL_SETUP_SEVERITIES* m_severities;
PANEL_TEXT_VARIABLES* m_textVars;
std::vector<bool> m_macHack;
// event handlers
void OnPageChange( wxBookCtrlEvent& event );

View File

@ -275,12 +275,23 @@ bool DIALOG_SPICE_MODEL::TransferDataFromWindow()
const wxString& spiceField = NETLIST_EXPORTER_PSPICE::GetSpiceFieldName( (SPICE_FIELD) i );
if( m_useSchFields )
{
m_schfields->erase( std::remove_if( m_schfields->begin(), m_schfields->end(),
[&]( const SCH_FIELD& f )
{ return f.GetName() == spiceField; } ), m_schfields->end() );
[&]( const SCH_FIELD& f )
{
return f.GetName() == spiceField;
} ),
m_schfields->end() );
}
else
{
m_libfields->erase( std::remove_if( m_libfields->begin(), m_libfields->end(),
[&]( const LIB_FIELD& f ) { return f.GetName( NATIVE_FIELD_NAME ) == spiceField; } ), m_libfields->end() );
[&]( const LIB_FIELD& f )
{
return f.GetName() == spiceField;
} ),
m_libfields->end() );
}
}
}
@ -317,7 +328,7 @@ bool DIALOG_SPICE_MODEL::TransferDataToWindow()
// TODO: There must be a good way to template out these repetitive calls
for( const LIB_FIELD& field : *m_libfields )
{
if( field.GetName( NATIVE_FIELD_NAME ) == spiceField && !field.GetText().IsEmpty() )
if( field.GetName() == spiceField && !field.GetText().IsEmpty() )
{
m_fieldsTmp[idx] = field.GetText();
break;
@ -868,9 +879,11 @@ LIB_FIELD& DIALOG_SPICE_MODEL::getLibField( int aFieldType )
{
const wxString& spiceField = NETLIST_EXPORTER_PSPICE::GetSpiceFieldName( (SPICE_FIELD) aFieldType );
auto fieldIt = std::find_if( m_libfields->begin(), m_libfields->end(), [&]( const LIB_FIELD& f ) {
return f.GetName( NATIVE_FIELD_NAME ) == spiceField;
} );
auto fieldIt = std::find_if( m_libfields->begin(), m_libfields->end(),
[&]( const LIB_FIELD& f )
{
return f.GetName() == spiceField;
} );
// Found one, so return it
if( fieldIt != m_libfields->end() )

View File

@ -111,7 +111,7 @@ bool DIALOG_UPDATE_FIELDS::TransferDataToWindow()
const LIB_FIELD* field = static_cast<const LIB_FIELD*>( &( *it ) );
if( field->GetId() >= MANDATORY_FIELDS )
m_fields.insert( field->GetName( false ) );
m_fields.insert( field->GetName() );
}
}
}
@ -121,7 +121,7 @@ bool DIALOG_UPDATE_FIELDS::TransferDataToWindow()
for( int i = 0; i < MANDATORY_FIELDS; ++i )
{
m_fieldsBox->Append( m_components.front()->GetField( i )->GetName( false ) );
m_fieldsBox->Append( m_components.front()->GetField( i )->GetName() );
if( i != REFERENCE && i != VALUE )
m_fieldsBox->Check( i, true );

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