From 4990d1e7b29d3440523de0c516be279438526a87 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Thu, 26 Mar 2020 11:02:59 +0000 Subject: [PATCH] Variable substitution framework. This implements editing of variables and moving SCH_FIELDs, TEXTE_MODULEs, TEXTE_PCB and worksheet items over to the new framework. --- .gitignore | 4 +- common/CMakeLists.txt | 12 + common/common.cpp | 66 ++-- common/dialogs/dialog_configure_paths.cpp | 60 ++-- common/dialogs/dialog_page_settings.cpp | 3 +- common/dialogs/panel_text_variables.cpp | 229 ++++++++++++ common/dialogs/panel_text_variables_base.cpp | 98 ++++++ common/dialogs/panel_text_variables_base.fbp | 329 ++++++++++++++++++ common/dialogs/panel_text_variables_base.h | 57 +++ common/eda_draw_frame.cpp | 5 +- common/page_layout/page_layout_reader.cpp | 77 +++- common/page_layout/ws_painter.cpp | 199 +++++------ common/page_layout/ws_proxy_view_item.cpp | 20 +- common/plotters/DXF_plotter.cpp | 2 +- common/plotters/common_plot_functions.cpp | 6 +- common/project.cpp | 36 +- {eeschema => common}/template_fieldnames.cpp | 0 {eeschema => common}/template_fieldnames.h | 0 .../template_fieldnames.keywords | 0 eeschema/CMakeLists.txt | 9 - eeschema/class_libentry.cpp | 11 +- eeschema/dialogs/dialog_schematic_setup.cpp | 31 +- eeschema/dialogs/dialog_schematic_setup.h | 4 + eeschema/dialogs/dialog_spice_model.cpp | 27 +- eeschema/dialogs/dialog_update_fields.cpp | 4 +- .../dialogs/panel_eeschema_color_settings.cpp | 2 +- eeschema/generate_alias_info.cpp | 4 +- eeschema/lib_field.cpp | 33 +- eeschema/lib_field.h | 21 +- .../netlist_exporter_generic.cpp | 2 +- eeschema/plot_schematic_DXF.cpp | 22 +- eeschema/plot_schematic_HPGL.cpp | 11 +- eeschema/plot_schematic_PDF.cpp | 13 +- eeschema/plot_schematic_PS.cpp | 12 +- eeschema/plot_schematic_SVG.cpp | 12 +- eeschema/sch_component.cpp | 46 +-- eeschema/sch_component.h | 2 +- eeschema/sch_field.cpp | 172 +++++++-- eeschema/sch_field.h | 16 +- eeschema/sch_item.cpp | 4 +- eeschema/sch_legacy_plugin.cpp | 2 +- eeschema/sch_painter.cpp | 7 +- eeschema/sch_sexpr_plugin.cpp | 8 +- eeschema/sch_sheet_path.cpp | 15 +- eeschema/sch_view.cpp | 1 + eeschema/tools/ee_selection_tool.cpp | 18 +- eeschema/tools/lib_edit_tool.cpp | 2 +- eeschema/tools/sch_editor_control.cpp | 4 +- gerbview/gerbview_frame.cpp | 4 +- include/common.h | 9 + include/config_params.h | 1 + include/panel_text_variables.h | 65 ++++ include/plotter.h | 27 +- include/project.h | 40 +-- include/ws_draw_item.h | 31 +- include/ws_painter.h | 2 +- include/ws_proxy_view_item.h | 74 +--- pagelayout_editor/pl_draw_panel_gal.cpp | 2 + pcbnew/class_board.cpp | 6 +- pcbnew/class_board.h | 56 +-- pcbnew/class_module.cpp | 4 +- pcbnew/class_pcb_text.cpp | 23 ++ pcbnew/class_pcb_text.h | 2 + pcbnew/class_text_mod.cpp | 87 ++--- pcbnew/dialogs/dialog_board_setup.cpp | 30 +- pcbnew/dialogs/dialog_board_setup.h | 4 + .../dialog_edit_footprint_for_BoardEditor.cpp | 27 +- .../dialog_edit_footprint_for_BoardEditor.h | 2 + ...og_edit_footprint_for_BoardEditor_base.cpp | 2 + ...og_edit_footprint_for_BoardEditor_base.fbp | 1 + ...alog_edit_footprint_for_BoardEditor_base.h | 1 + .../dialog_global_edit_text_and_graphics.cpp | 4 +- pcbnew/legacy_plugin.cpp | 4 +- pcbnew/pcb_edit_frame.cpp | 3 +- pcbnew/pcb_parser.cpp | 6 +- pcbnew/plot_board_layers.cpp | 4 +- pcbnew/plot_brditems_plotter.cpp | 4 +- pcbnew/tools/pcbnew_control.cpp | 4 +- qa/eeschema/lib_field_test_utils.h | 13 +- 79 files changed, 1609 insertions(+), 651 deletions(-) create mode 100644 common/dialogs/panel_text_variables.cpp create mode 100644 common/dialogs/panel_text_variables_base.cpp create mode 100644 common/dialogs/panel_text_variables_base.fbp create mode 100644 common/dialogs/panel_text_variables_base.h rename {eeschema => common}/template_fieldnames.cpp (100%) rename {eeschema => common}/template_fieldnames.h (100%) rename {eeschema => common}/template_fieldnames.keywords (100%) create mode 100644 include/panel_text_variables.h diff --git a/.gitignore b/.gitignore index 8cdc745e22..0f69160b27 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 675c309ea5..821e787afc 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -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( diff --git a/common/common.cpp b/common/common.cpp index 9eeb1b2cd0..3cc9f2f537 100644 --- a/common/common.cpp +++ b/common/common.cpp @@ -25,12 +25,10 @@ #include #include +#include #include -#include #include #include -#include - #include #include #include @@ -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& 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 // diff --git a/common/dialogs/dialog_configure_paths.cpp b/common/dialogs/dialog_configure_paths.cpp index 6fae3cca22..7ace4e6346 100644 --- a/common/dialogs/dialog_configure_paths.cpp +++ b/common/dialogs/dialog_configure_paths.cpp @@ -34,11 +34,11 @@ #include #include -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( 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(); diff --git a/common/dialogs/dialog_page_settings.cpp b/common/dialogs/dialog_page_settings.cpp index 3130c282fb..5647f715a7 100644 --- a/common/dialogs/dialog_page_settings.cpp +++ b/common/dialogs/dialog_page_settings.cpp @@ -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 ); diff --git a/common/dialogs/panel_text_variables.cpp b/common/dialogs/panel_text_variables.cpp new file mode 100644 index 0000000000..c92aae142b --- /dev/null +++ b/common/dialogs/panel_text_variables.cpp @@ -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 + +#include +#include +#include +#include +#include +#include + +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& 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& 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(); +} + diff --git a/common/dialogs/panel_text_variables_base.cpp b/common/dialogs/panel_text_variables_base.cpp new file mode 100644 index 0000000000..78d170c012 --- /dev/null +++ b/common/dialogs/panel_text_variables_base.cpp @@ -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 ); + +} diff --git a/common/dialogs/panel_text_variables_base.fbp b/common/dialogs/panel_text_variables_base.fbp new file mode 100644 index 0000000000..7539fd94e5 --- /dev/null +++ b/common/dialogs/panel_text_variables_base.fbp @@ -0,0 +1,329 @@ + + + + + + C++ + 1 + source_name + 0 + 0 + res + UTF-8 + connect + panel_text_variables_base + 1000 + none + + 1 + PanelTextVariables + + . + + 1 + 1 + 1 + 1 + UI + 1 + 0 + + 0 + wxAUI_MGR_DEFAULT + + + 1 + 1 + impl_virtual + + + 0 + wxID_ANY + + + PANEL_TEXT_VARIABLES_BASE + + -1,-1 + ; forward_declare + + + + wxTAB_TRAVERSAL + OnUpdateUI + + + bPanelSizer + wxVERTICAL + none + + 10 + wxEXPAND|wxTOP|wxLEFT + 1 + + + bSizer3 + wxVERTICAL + none + + 5 + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT + 1 + + 1 + 1 + 1 + 1 + + + + + 0 + 0 + + + + 1 + + + wxALIGN_LEFT + + wxALIGN_TOP + 0 + 1 + wxALIGN_CENTER + 22 + "Variable Name" "Text Substitution" + wxALIGN_CENTER + 2 + 150,454 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + 0 + 1 + 1 + 1 + + 1 + + + 1 + 0 + 0 + wxID_ANY + + + + 0 + 0 + + 0 + + + 0 + 604,170 + 1 + m_TextVars + 1 + + + protected + 1 + + Resizable + wxALIGN_CENTER + 0 + + wxALIGN_CENTER + + 1 + 1 + + WX_GRID; widgets/wx_grid.h; forward_declare + 0 + + + + + OnGridCellChange + OnGridSize + + + + 5 + wxEXPAND|wxRIGHT|wxLEFT + 0 + + + bSizerEnvVarBtns + wxHORIZONTAL + none + + 5 + wxRIGHT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + Add Text Variable + + 0 + + 0 + + + 0 + 30,29 + 1 + m_btnAddTextVar + 1 + + + protected + 1 + + + + Resizable + 1 + + + ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnAddTextVar + + + + 5 + wxEXPAND|wxRIGHT|wxLEFT + 0 + + 0 + protected + 0 + + + + 5 + wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + Delete Text Variable + + 0 + + 0 + + + 0 + 30,29 + 1 + m_btnDeleteTextVar + 1 + + + protected + 1 + + + + Resizable + 1 + + + ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnRemoveTextVar + + + + + + + + + + diff --git a/common/dialogs/panel_text_variables_base.h b/common/dialogs/panel_text_variables_base.h new file mode 100644 index 0000000000..0a8b881069 --- /dev/null +++ b/common/dialogs/panel_text_variables_base.h @@ -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 +#include +#include +class WX_GRID; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +/// 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(); + +}; + diff --git a/common/eda_draw_frame.cpp b/common/eda_draw_frame.cpp index 70f4066ae7..cfb369994a 100644 --- a/common/eda_draw_frame.cpp +++ b/common/eda_draw_frame.cpp @@ -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 ) { diff --git a/common/page_layout/page_layout_reader.cpp b/common/page_layout/page_layout_reader.cpp index dfc94becf2..7c67e84b68 100644 --- a/common/page_layout/page_layout_reader.cpp +++ b/common/page_layout/page_layout_reader.cpp @@ -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() ) diff --git a/common/page_layout/ws_painter.cpp b/common/page_layout/ws_painter.cpp index 1dfc96c8c9..12cb56a33f 100644 --- a/common/page_layout/ws_painter.cpp +++ b/common/page_layout/ws_painter.cpp @@ -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 ); } diff --git a/common/page_layout/ws_proxy_view_item.cpp b/common/page_layout/ws_proxy_view_item.cpp index 4e97c25310..0e31efaa42 100644 --- a/common/page_layout/ws_proxy_view_item.cpp +++ b/common/page_layout/ws_proxy_view_item.cpp @@ -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 * * This program is free software; you can redistribute it and/or @@ -25,8 +25,6 @@ #include #include #include -#include -#include #include #include #include @@ -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 ); diff --git a/common/plotters/DXF_plotter.cpp b/common/plotters/DXF_plotter.cpp index c98610d5f4..a5e7fd3e5f 100644 --- a/common/plotters/DXF_plotter.cpp +++ b/common/plotters/DXF_plotter.cpp @@ -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 diff --git a/common/plotters/common_plot_functions.cpp b/common/plotters/common_plot_functions.cpp index c746dab203..2cbd196c17 100644 --- a/common/plotters/common_plot_functions.cpp +++ b/common/plotters/common_plot_functions.cpp @@ -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 ); diff --git a/common/project.cpp b/common/project.cpp index 3234f1367b..b555d31a81 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -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; } diff --git a/eeschema/template_fieldnames.cpp b/common/template_fieldnames.cpp similarity index 100% rename from eeschema/template_fieldnames.cpp rename to common/template_fieldnames.cpp diff --git a/eeschema/template_fieldnames.h b/common/template_fieldnames.h similarity index 100% rename from eeschema/template_fieldnames.h rename to common/template_fieldnames.h diff --git a/eeschema/template_fieldnames.keywords b/common/template_fieldnames.keywords similarity index 100% rename from eeschema/template_fieldnames.keywords rename to common/template_fieldnames.keywords diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt index c9c372a700..6aad3e6df4 100644 --- a/eeschema/CMakeLists.txt +++ b/eeschema/CMakeLists.txt @@ -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 diff --git a/eeschema/class_libentry.cpp b/eeschema/class_libentry.cpp index 30b8d0f040..a66947371f 100644 --- a/eeschema/class_libentry.cpp +++ b/eeschema/class_libentry.cpp @@ -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( 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; } diff --git a/eeschema/dialogs/dialog_schematic_setup.cpp b/eeschema/dialogs/dialog_schematic_setup.cpp index 0309c69417..42f1f5e631 100644 --- a/eeschema/dialogs/dialog_schematic_setup.cpp +++ b/eeschema/dialogs/dialog_schematic_setup.cpp @@ -25,13 +25,11 @@ #include #include #include +#include #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 } diff --git a/eeschema/dialogs/dialog_schematic_setup.h b/eeschema/dialogs/dialog_schematic_setup.h index 5d3acf0209..f8a962fa1c 100644 --- a/eeschema/dialogs/dialog_schematic_setup.h +++ b/eeschema/dialogs/dialog_schematic_setup.h @@ -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 m_macHack; // event handlers void OnPageChange( wxBookCtrlEvent& event ); diff --git a/eeschema/dialogs/dialog_spice_model.cpp b/eeschema/dialogs/dialog_spice_model.cpp index 8faf6e84b0..451ae514c8 100644 --- a/eeschema/dialogs/dialog_spice_model.cpp +++ b/eeschema/dialogs/dialog_spice_model.cpp @@ -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() ) diff --git a/eeschema/dialogs/dialog_update_fields.cpp b/eeschema/dialogs/dialog_update_fields.cpp index da2b121a65..bcdce8b0c8 100644 --- a/eeschema/dialogs/dialog_update_fields.cpp +++ b/eeschema/dialogs/dialog_update_fields.cpp @@ -111,7 +111,7 @@ bool DIALOG_UPDATE_FIELDS::TransferDataToWindow() const LIB_FIELD* field = static_cast( &( *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 ); diff --git a/eeschema/dialogs/panel_eeschema_color_settings.cpp b/eeschema/dialogs/panel_eeschema_color_settings.cpp index 07e01e7bb8..ccb189c5c3 100644 --- a/eeschema/dialogs/panel_eeschema_color_settings.cpp +++ b/eeschema/dialogs/panel_eeschema_color_settings.cpp @@ -299,7 +299,7 @@ void PANEL_EESCHEMA_COLOR_SETTINGS::createPreviewItems() m_page->SetHeightMils( 5000 ); m_page->SetWidthMils( 5500 ); - m_ws = new KIGFX::WS_PROXY_VIEW_ITEM( static_cast( IU_PER_MILS ), m_page, m_titleBlock ); + m_ws = new KIGFX::WS_PROXY_VIEW_ITEM( (int) IU_PER_MILS, m_page, nullptr, m_titleBlock ); m_ws->SetColorLayer( LAYER_SCHEMATIC_WORKSHEET ); view->Add( m_ws ); diff --git a/eeschema/generate_alias_info.cpp b/eeschema/generate_alias_info.cpp index f7e792162b..c2cdc748f9 100644 --- a/eeschema/generate_alias_info.cpp +++ b/eeschema/generate_alias_info.cpp @@ -159,7 +159,7 @@ protected: wxString GetHtmlFieldRow( LIB_FIELD const & aField ) { - wxString name = aField.GetName( NATIVE_FIELD_NAME ); + wxString name = aField.GetCanonicalName(); wxString text = aField.GetFullText( m_unit > 0 ? m_unit : 1 ); wxString fieldhtml = FieldFormat; @@ -225,7 +225,7 @@ protected: for( auto const& parentField : parentFields ) { - if( m_symbol->FindField( parentField.GetName( NATIVE_FIELD_NAME ) ) ) + if( m_symbol->FindField( parentField.GetCanonicalName() ) ) continue; fieldtable += GetHtmlFieldRow( parentField ); diff --git a/eeschema/lib_field.cpp b/eeschema/lib_field.cpp index eb969122a6..d39b6cd02c 100644 --- a/eeschema/lib_field.cpp +++ b/eeschema/lib_field.cpp @@ -384,22 +384,26 @@ COLOR4D LIB_FIELD::GetDefaultColor() } -wxString LIB_FIELD::GetName( bool aTranslate ) const +wxString LIB_FIELD::GetName( bool aUseDefaultName ) const +{ + if( !m_name.IsEmpty() ) + return m_name; + else if( aUseDefaultName ) + return TEMPLATE_FIELDNAME::GetDefaultFieldName( m_id ); +} + + +wxString LIB_FIELD::GetCanonicalName() const { switch( m_id ) { - case REFERENCE: return aTranslate ? _( "Reference" ) : wxT( "Reference" ); - case VALUE: return aTranslate ? _( "Value" ) : wxT( "Value" ); - case FOOTPRINT: return aTranslate ? _( "Footprint" ) : wxT( "Footprint" ); - case DATASHEET: return aTranslate ? _( "Datasheet" ) : wxT( "Datasheet" ); - - default: - if( m_name.IsEmpty() ) - return aTranslate ? wxString::Format( _( "Field%d" ), m_id ) - : wxString::Format( wxT( "Field%d" ), m_id ); - else - return m_name; + case REFERENCE: return wxT( "Reference" ); + case VALUE: return wxT( "Value" ); + case FOOTPRINT: return wxT( "Footprint" ); + case DATASHEET: return wxT( "Datasheet" ); } + + return m_name; } @@ -425,7 +429,8 @@ void LIB_FIELD::SetName( const wxString& aName ) wxString LIB_FIELD::GetSelectMenuText( EDA_UNITS aUnits ) const { - return wxString::Format( _( "Field %s \"%s\"" ), GetName( TRANSLATE_FIELD_NAME ), + return wxString::Format( _( "Field %s \"%s\"" ), + GetName(), ShortenedShownText() ); } @@ -459,7 +464,7 @@ void LIB_FIELD::GetMsgPanelInfo( EDA_UNITS aUnits, MSG_PANEL_ITEMS& aList ) aList.push_back( MSG_PANEL_ITEM( _( "Height" ), msg, BLUE ) ); // Display field name (ref, value ...) - aList.push_back( MSG_PANEL_ITEM( _( "Field" ), GetName( TRANSLATE_FIELD_NAME ), BROWN ) ); + aList.push_back( MSG_PANEL_ITEM( _( "Field" ), GetName(), BROWN ) ); // Display field text: aList.push_back( MSG_PANEL_ITEM( _( "Value" ), GetShownText(), BROWN ) ); diff --git a/eeschema/lib_field.h b/eeschema/lib_field.h index 0ae3f81f6f..d2be03f97a 100644 --- a/eeschema/lib_field.h +++ b/eeschema/lib_field.h @@ -111,19 +111,18 @@ public: * Returns the field name. * * The first four field IDs are reserved and therefore always return their respective - * names. The user definable fields will return FieldN where N is the ID of the field - * when the m_name member is empty. + * names. * - * @param aTranslate true to return translated field name. - * note: has meaning mainly for mandatory fields or to return a default field name. - * Should be used only in messages (never when trying to find a field by name) - * false to return the english name. - * Normal option when the name is used as keyword in netlists. - * @return Name of the field. + * The user definable fields will return FieldN where N is the ID of the field when the + * m_name member is empyt unless false is passed to \a aUseDefaultName. */ - #define TRANSLATE_FIELD_NAME true - #define NATIVE_FIELD_NAME false - wxString GetName( bool aTranslate ) const; + wxString GetName( bool aUseDefaultName = true ) const; + + /** + * Get a non-language-specific name for a field which can be used for storage, variable + * look-up, etc. + */ + wxString GetCanonicalName() const; /** * Set a user definable field name to \a aName. diff --git a/eeschema/netlist_exporters/netlist_exporter_generic.cpp b/eeschema/netlist_exporters/netlist_exporter_generic.cpp index 7d984df2bb..d9d523edde 100644 --- a/eeschema/netlist_exporters/netlist_exporter_generic.cpp +++ b/eeschema/netlist_exporters/netlist_exporter_generic.cpp @@ -448,7 +448,7 @@ XNODE* NETLIST_EXPORTER_GENERIC::makeLibParts() { XNODE* xfield; xfields->AddChild( xfield = node( "field", fieldList[i].GetText() ) ); - xfield->AddAttribute( "name", fieldList[i].GetName(false) ); + xfield->AddAttribute( "name", fieldList[i].GetCanonicalName() ); } } diff --git a/eeschema/plot_schematic_DXF.cpp b/eeschema/plot_schematic_DXF.cpp index 45b0f5d5a0..09aa0077c6 100644 --- a/eeschema/plot_schematic_DXF.cpp +++ b/eeschema/plot_schematic_DXF.cpp @@ -104,11 +104,11 @@ void DIALOG_PLOT_SCHEMATIC::CreateDXFFile( bool aPlotAll, bool aPlotFrameRef ) } -bool DIALOG_PLOT_SCHEMATIC::PlotOneSheetDXF( const wxString& aFileName, - SCH_SCREEN* aScreen, - wxPoint aPlotOffset, - double aScale, - bool aPlotFrameRef ) +bool DIALOG_PLOT_SCHEMATIC::PlotOneSheetDXF( const wxString& aFileName, + SCH_SCREEN* aScreen, + wxPoint aPlotOffset, + double aScale, + bool aPlotFrameRef ) { DXF_PLOTTER* plotter = new DXF_PLOTTER(); @@ -137,16 +137,10 @@ bool DIALOG_PLOT_SCHEMATIC::PlotOneSheetDXF( const wxString& aFileName, if( aPlotFrameRef ) { - COLOR4D color = plotter->GetColorMode() ? - plotter->ColorSettings()->GetColor( LAYER_SCHEMATIC_WORKSHEET ) : - COLOR4D::BLACK; - - PlotWorkSheet( plotter, m_parent->GetTitleBlock(), - m_parent->GetPageSettings(), + PlotWorkSheet( plotter, &m_parent->Prj(), m_parent->GetTitleBlock(), pageInfo, aScreen->m_ScreenNumber, aScreen->m_NumberOfScreens, - m_parent->GetScreenDesc(), - aScreen->GetFileName(), - color ); + m_parent->GetScreenDesc(), aScreen->GetFileName(), + plotter->GetColorMode() ? COLOR4D::UNSPECIFIED : COLOR4D::BLACK ); } aScreen->Plot( plotter ); diff --git a/eeschema/plot_schematic_HPGL.cpp b/eeschema/plot_schematic_HPGL.cpp index 7897f81905..0ddf601524 100644 --- a/eeschema/plot_schematic_HPGL.cpp +++ b/eeschema/plot_schematic_HPGL.cpp @@ -202,13 +202,12 @@ bool DIALOG_PLOT_SCHEMATIC::Plot_1_Page_HPGL( const wxString& aFileName, plotter->SetPenDiameter( m_HPGLPenSize ); plotter->StartPlot(); - if( getPlotFrameRef() ) - PlotWorkSheet( plotter, m_parent->GetTitleBlock(), - m_parent->GetPageSettings(), + if( aPlotFrameRef ) + { + PlotWorkSheet( plotter, &m_parent->Prj(), m_parent->GetTitleBlock(), aPageInfo, aScreen->m_ScreenNumber, aScreen->m_NumberOfScreens, - m_parent->GetScreenDesc(), - aScreen->GetFileName(), - COLOR4D::BLACK ); + m_parent->GetScreenDesc(), aScreen->GetFileName(), COLOR4D::BLACK ); + } aScreen->Plot( plotter ); diff --git a/eeschema/plot_schematic_PDF.cpp b/eeschema/plot_schematic_PDF.cpp index 92f95af92a..15039f7452 100644 --- a/eeschema/plot_schematic_PDF.cpp +++ b/eeschema/plot_schematic_PDF.cpp @@ -161,16 +161,11 @@ void DIALOG_PLOT_SCHEMATIC::plotOneSheetPDF( PLOTTER* aPlotter, if( aPlotFrameRef ) { - COLOR4D color = aPlotter->GetColorMode() ? - aPlotter->ColorSettings()->GetColor( LAYER_SCHEMATIC_WORKSHEET ) : - COLOR4D::BLACK; - - PlotWorkSheet( aPlotter, m_parent->GetTitleBlock(), - m_parent->GetPageSettings(), - aScreen->m_ScreenNumber, aScreen->m_NumberOfScreens, - m_parent->GetScreenDesc(), + PlotWorkSheet( aPlotter, &aScreen->Prj(), m_parent->GetTitleBlock(), + m_parent->GetPageSettings(), aScreen->m_ScreenNumber, + aScreen->m_NumberOfScreens, m_parent->GetScreenDesc(), aScreen->GetFileName(), - color ); + aPlotter->GetColorMode() ? COLOR4D::UNSPECIFIED : COLOR4D::BLACK ); } aScreen->Plot( aPlotter ); diff --git a/eeschema/plot_schematic_PS.cpp b/eeschema/plot_schematic_PS.cpp index 27e0925384..8c0ed02395 100644 --- a/eeschema/plot_schematic_PS.cpp +++ b/eeschema/plot_schematic_PS.cpp @@ -170,16 +170,10 @@ bool DIALOG_PLOT_SCHEMATIC::plotOneSheetPS( const wxString& aFileName, if( aPlotFrameRef ) { - COLOR4D color = plotter->GetColorMode() ? - plotter->ColorSettings()->GetColor( LAYER_SCHEMATIC_WORKSHEET ) : - COLOR4D::BLACK; - - PlotWorkSheet( plotter, m_parent->GetTitleBlock(), - m_parent->GetPageSettings(), + PlotWorkSheet( plotter, &aScreen->Prj(), m_parent->GetTitleBlock(), aPageInfo, aScreen->m_ScreenNumber, aScreen->m_NumberOfScreens, - m_parent->GetScreenDesc(), - aScreen->GetFileName(), - color ); + m_parent->GetScreenDesc(), aScreen->GetFileName(), + plotter->GetColorMode() ? COLOR4D::UNSPECIFIED : COLOR4D::BLACK ); } aScreen->Plot( plotter ); diff --git a/eeschema/plot_schematic_SVG.cpp b/eeschema/plot_schematic_SVG.cpp index 2b3d0a0fcc..ea5bf3bcff 100644 --- a/eeschema/plot_schematic_SVG.cpp +++ b/eeschema/plot_schematic_SVG.cpp @@ -148,16 +148,10 @@ bool DIALOG_PLOT_SCHEMATIC::plotOneSheetSVG( EDA_DRAW_FRAME* aFrame, if( aPlotFrameRef ) { - COLOR4D color = plotter->GetColorMode() ? - plotter->ColorSettings()->GetColor( LAYER_SCHEMATIC_WORKSHEET ) : - COLOR4D::BLACK; - - PlotWorkSheet( plotter, aFrame->GetTitleBlock(), - aFrame->GetPageSettings(), + PlotWorkSheet( plotter, &aScreen->Prj(), aFrame->GetTitleBlock(), pageInfo, aScreen->m_ScreenNumber, aScreen->m_NumberOfScreens, - aFrame->GetScreenDesc(), - aScreen->GetFileName(), - color ); + aFrame->GetScreenDesc(), aScreen->GetFileName(), + plotter->GetColorMode() ? COLOR4D::UNSPECIFIED : COLOR4D::BLACK ); } aScreen->Plot( plotter ); diff --git a/eeschema/sch_component.cpp b/eeschema/sch_component.cpp index d941e6c7be..e0e078bde4 100644 --- a/eeschema/sch_component.cpp +++ b/eeschema/sch_component.cpp @@ -760,18 +760,6 @@ void SCH_COMPONENT::GetFields( std::vector& aVector, bool aVisibleOn } -std::vector SCH_COMPONENT::GetFields() -{ - std::vector retvec; - retvec.reserve( m_Fields.size() ); - - for( SCH_FIELD& field : m_Fields ) - retvec.push_back( &field ); - - return retvec; -} - - SCH_FIELD* SCH_COMPONENT::AddField( const SCH_FIELD& aField ) { int newNdx = m_Fields.size(); @@ -816,19 +804,9 @@ void SCH_COMPONENT::UpdateFields( bool aResetStyle, bool aResetRef ) LIB_FIELDS fields; m_part->GetFields( fields ); - for( const LIB_FIELD& field : fields ) + for( const LIB_FIELD& libField : fields ) { - // Can no longer insert an empty name, since names are now keys. The - // field index is not used beyond the first MANDATORY_FIELDS - if( field.GetName( NATIVE_FIELD_NAME ).IsEmpty() ) - continue; - - // See if field already exists (mandatory fields always exist). - // for mandatory fields, the name and field id are fixed, so we use the - // known and fixed id to get them (more reliable than names, which can be translated) - // for other fields (custom fields), locate the field by same name - // (field id has no known meaning for custom fields) - int idx = field.GetId(); + int idx = libField.GetId(); SCH_FIELD* schField; if( idx == REFERENCE && !aResetRef ) @@ -837,19 +815,21 @@ void SCH_COMPONENT::UpdateFields( bool aResetStyle, bool aResetRef ) if( (unsigned) idx < MANDATORY_FIELDS ) schField = GetField( idx ); else - schField = FindField( field.GetName( NATIVE_FIELD_NAME ) ); - - if( !schField ) { - SCH_FIELD newField( wxPoint( 0, 0 ), GetFieldCount(), this, - field.GetName( NATIVE_FIELD_NAME ) ); - schField = AddField( newField ); + schField = FindField( libField.GetCanonicalName() ); + + if( !schField ) + { + wxString fieldName = libField.GetCanonicalName(); + SCH_FIELD newField( wxPoint( 0, 0), GetFieldCount(), this, fieldName ); + schField = AddField( newField ); + } } if( aResetStyle ) { - schField->ImportValues( field ); - schField->SetTextPos( m_Pos + field.GetTextPos() ); + schField->ImportValues( libField ); + schField->SetTextPos( m_Pos + libField.GetTextPos() ); } if( idx == VALUE ) @@ -869,7 +849,7 @@ void SCH_COMPONENT::UpdateFields( bool aResetStyle, bool aResetRef ) } else { - schField->SetText( field.GetText() ); + schField->SetText( libField.GetText() ); } } } diff --git a/eeschema/sch_component.h b/eeschema/sch_component.h index 7558c425fa..59602a94c8 100644 --- a/eeschema/sch_component.h +++ b/eeschema/sch_component.h @@ -372,7 +372,7 @@ public: /** * Returns a vector of fields from the component */ - std::vector GetFields(); + std::vector& GetFields() { return m_Fields; } /** * Add a field to the symbol. diff --git a/eeschema/sch_field.cpp b/eeschema/sch_field.cpp index b0aaf7cae6..337ad054c3 100644 --- a/eeschema/sch_field.cpp +++ b/eeschema/sch_field.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr - * Copyright (C) 2004-2019 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2004-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 @@ -31,7 +31,6 @@ */ #include -#include #include #include #include @@ -39,7 +38,7 @@ #include #include #include - +#include #include #include #include @@ -73,11 +72,117 @@ EDA_ITEM* SCH_FIELD::Clone() const } -const wxString SCH_FIELD::GetFullyQualifiedText() const +wxString SCH_FIELD::GetShownText() const { - wxString text = GetText(); + auto symbolResolver = [ this ]( wxString* token ) -> bool + { + SCH_COMPONENT* component = static_cast( m_Parent ); + std::vector& fields = component->GetFields(); - // Note that the IDs of FIELDS and SHEETS overlap, so one must check *both* the + for( int i = 0; i < MANDATORY_FIELDS; ++i ) + { + if( token->IsSameAs( fields[i].GetCanonicalName().Upper() ) ) + { + // silently drop recursive references + if( &fields[i] == this ) + *token = wxEmptyString; + else + *token = fields[i].GetShownText(); + + return true; + } + } + + for( int i = MANDATORY_FIELDS; i < fields.size(); ++i ) + { + if( token->IsSameAs( fields[i].GetName() ) + || token->IsSameAs( fields[i].GetName().Upper() ) ) + { + // silently drop recursive references + if( &fields[i] == this ) + *token = wxEmptyString; + else + *token = fields[i].GetShownText(); + + return true; + } + } + + if( token->IsSameAs( wxT( "FOOTPRINT_LIBRARY" ) ) ) + { + SCH_FIELD& f = component->GetFields()[ FOOTPRINT ]; + wxArrayString parts = wxSplit( f.GetText(), ':' ); + + *token = parts[0]; + return true; + } + else if( token->IsSameAs( wxT( "FOOTPRINT_NAME" ) ) ) + { + SCH_FIELD& f = component->GetFields()[ FOOTPRINT ]; + wxArrayString parts = wxSplit( f.GetText(), ':' ); + + *token = parts[ std::min( 1, (int) parts.size() - 1 ) ]; + return true; + } + else if( token->IsSameAs( wxT( "UNIT" ) ) ) + { + *token = LIB_PART::SubReference( component->GetUnit() ); + return true; + } + + return false; + }; + + auto sheetResolver = [ & ]( wxString* token ) -> bool + { + SCH_SHEET* sheet = static_cast( m_Parent ); + std::vector& fields = sheet->GetFields(); + + for( int i = 0; i < SHEET_MANDATORY_FIELDS; ++i ) + { + if( token->IsSameAs( fields[i].GetCanonicalName().Upper() ) ) + { + // silently drop recursive references + if( &fields[i] == this ) + *token = wxEmptyString; + else + *token = fields[i].GetShownText(); + + return true; + } + } + + for( int i = SHEET_MANDATORY_FIELDS; i < fields.size(); ++i ) + { + if( token->IsSameAs( fields[i].GetName() ) ) + { + // silently drop recursive references + if( &fields[i] == this ) + *token = wxEmptyString; + else + *token = fields[i].GetShownText(); + + return true; + } + } + + return false; + }; + + PROJECT* project = nullptr; + wxString text; + + if( g_RootSheet && g_RootSheet->GetScreen() ) + project = &g_RootSheet->GetScreen()->Kiway().Prj(); + + if( m_Parent && m_Parent->Type() == SCH_COMPONENT_T ) + text = ExpandTextVars( GetText(), symbolResolver, project ); + else if( m_Parent && m_Parent->Type() == SCH_SHEET_T ) + text = ExpandTextVars( GetText(), sheetResolver, project ); + else + text = GetText(); + + // WARNING: the IDs of FIELDS and SHEETS overlap, so one must check *both* the // id and the parent's type. if( m_Parent && m_Parent->Type() == SCH_COMPONENT_T ) @@ -177,7 +282,7 @@ void SCH_FIELD::Print( wxDC* aDC, const wxPoint& aOffset ) else color = GetLayerColor( m_Layer ); - GRText( aDC, textpos, color, GetFullyQualifiedText(), orient, GetTextSize(), + GRText( aDC, textpos, color, GetShownText(), orient, GetTextSize(), GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, lineWidth, IsItalic(), IsBold() ); } @@ -213,7 +318,7 @@ const EDA_RECT SCH_FIELD::GetBoundingBox() const EDA_RECT rect; SCH_FIELD text( *this ); // Make a local copy to change text // because GetBoundingBox() is const - text.SetText( GetFullyQualifiedText() ); + text.SetText( GetShownText() ); rect = text.GetTextBox( -1, linewidth, false, GetTextMarkupFlags() ); // Calculate the bounding box position relative to the parent: @@ -278,7 +383,7 @@ bool SCH_FIELD::IsVoid() const bool SCH_FIELD::Matches( wxFindReplaceData& aSearchData, void* aAuxData ) { - wxString text = GetFullyQualifiedText(); + wxString text = GetShownText(); int flags = aSearchData.GetFlags(); bool searchUserDefinedFields = flags & FR_SEARCH_ALL_FIELDS; bool searchAndReplace = flags & FR_SEARCH_REPLACE; @@ -416,6 +521,31 @@ wxString SCH_FIELD::GetName( bool aUseDefaultName ) const } +wxString SCH_FIELD::GetCanonicalName() const +{ + if( m_Parent && m_Parent->Type() == SCH_COMPONENT_T ) + { + switch( m_id ) + { + case REFERENCE: return wxT( "Reference" ); + case VALUE: return wxT( "Value" ); + case FOOTPRINT: return wxT( "Footprint" ); + case DATASHEET: return wxT( "Datasheet" ); + } + } + else if( m_Parent && m_Parent->Type() == SCH_SHEET_T ) + { + switch( m_id ) + { + case SHEETNAME: return wxT( "Sheetname" ); + case SHEETFILENAME: return wxT( "Sheetfile" ); + } + } + + return m_name; +} + + BITMAP_DEF SCH_FIELD::GetMenuImage() const { if( m_Parent && m_Parent->Type() == SCH_COMPONENT_T ) @@ -474,8 +604,7 @@ void SCH_FIELD::Plot( PLOTTER* aPlotter ) if( IsVoid() ) return; - /* Calculate the text orientation, according to the component - * orientation/mirror */ + // Calculate the text orientation, according to the component orientation/mirror int orient = GetTextAngle(); if( m_Parent && m_Parent->Type() == SCH_COMPONENT_T ) @@ -491,16 +620,16 @@ void SCH_FIELD::Plot( PLOTTER* aPlotter ) } } - /* Calculate the text justification, according to the component - * orientation/mirror + /* + * Calculate the text justification, according to the component orientation/mirror * this is a bit complicated due to cumulative calculations: * - numerous cases (mirrored or not, rotation) - * - the DrawGraphicText function recalculate also H and H justifications - * according to the text orientation. - * - When a component is mirrored, the text is not mirrored and - * justifications are complicated to calculate - * so the more easily way is to use no justifications ( Centered text ) - * and use GetBoundaryBox to know the text coordinate considered as centered + * - the DrawGraphicText function also recalculates H and H justifications according to the + * text orientation. + * - When a component is mirrored, the text is not mirrored and justifications are + * complicated to calculate + * so the easier way is to use no justifications (centered text) and use GetBoundaryBox to + * know the text coordinate considered as centered */ EDA_RECT BoundaryBox = GetBoundingBox(); EDA_TEXT_HJUSTIFY_T hjustify = GR_TEXT_HJUSTIFY_CENTER; @@ -509,9 +638,8 @@ void SCH_FIELD::Plot( PLOTTER* aPlotter ) int thickness = GetPenSize(); - aPlotter->Text( textpos, color, GetFullyQualifiedText(), orient, GetTextSize(), - hjustify, vjustify, - thickness, IsItalic(), IsBold() ); + aPlotter->Text( textpos, color, GetShownText(), orient, GetTextSize(), hjustify, vjustify, + thickness, IsItalic(), IsBold() ); } diff --git a/eeschema/sch_field.h b/eeschema/sch_field.h index 5062db44e8..f747a78d56 100644 --- a/eeschema/sch_field.h +++ b/eeschema/sch_field.h @@ -103,21 +103,19 @@ public: */ wxString GetName( bool aUseDefaultName = true ) const; + /** + * Get a non-language-specific name for a field which can be used for storage, variable + * look-up, etc. + */ + wxString GetCanonicalName() const; + void SetName( const wxString& aName ) { m_name = aName; } int GetId() const { return m_id; } void SetId( int aId ) { m_id = aId; } - /** - * Function GetFullyQualifiedText - * returns the fully qualified field text by allowing for the part suffix to be added - * to the reference designator field if the component has multiple parts. For all other - * fields this is the equivalent of EDA_TEXT::GetText(). - * - * @return a const wxString object containing the field's string. - */ - const wxString GetFullyQualifiedText() const; + wxString GetShownText() const override; const EDA_RECT GetBoundingBox() const override; diff --git a/eeschema/sch_item.cpp b/eeschema/sch_item.cpp index a4143a762d..090275007c 100644 --- a/eeschema/sch_item.cpp +++ b/eeschema/sch_item.cpp @@ -92,8 +92,8 @@ SCH_ITEM* SCH_ITEM::Duplicate( bool doClone ) const for( SCH_PIN* pin : component->GetSchPins() ) pin->ClearFlags( SELECTED | HIGHLIGHTED | BRIGHTENED ); - for( SCH_FIELD* field : component->GetFields() ) - field->ClearFlags( SELECTED | HIGHLIGHTED | BRIGHTENED ); + for( SCH_FIELD& field : component->GetFields() ) + field.ClearFlags( SELECTED | HIGHLIGHTED | BRIGHTENED ); } if( newItem->Type() == SCH_SHEET_T ) diff --git a/eeschema/sch_legacy_plugin.cpp b/eeschema/sch_legacy_plugin.cpp index 1836221258..dc855e4261 100644 --- a/eeschema/sch_legacy_plugin.cpp +++ b/eeschema/sch_legacy_plugin.cpp @@ -2506,7 +2506,7 @@ LIB_PART* SCH_LEGACY_PLUGIN_CACHE::removeSymbol( LIB_PART* aPart ) { LIB_FIELD& field = static_cast( drawItem ); - if( firstChild->FindField( field.GetName( NATIVE_FIELD_NAME ) ) ) + if( firstChild->FindField( field.GetCanonicalName() ) ) continue; } diff --git a/eeschema/sch_painter.cpp b/eeschema/sch_painter.cpp index b97ccf4bdb..e265025608 100644 --- a/eeschema/sch_painter.cpp +++ b/eeschema/sch_painter.cpp @@ -1353,8 +1353,8 @@ void SCH_PAINTER::draw( SCH_COMPONENT *aComp, int aLayer ) draw( &tempPart, aLayer, false, aComp->GetUnit(), aComp->GetConvert() ); // The fields are SCH_COMPONENT-specific so don't need to be copied/oriented/translated - for( SCH_FIELD* field : aComp->GetFields() ) - draw( field, aLayer ); + for( SCH_FIELD& field : aComp->GetFields() ) + draw( &field, aLayer ); } @@ -1435,8 +1435,7 @@ void SCH_PAINTER::draw( SCH_FIELD *aField, int aLayer ) m_gal->SetFontItalic( aField->IsItalic() ); m_gal->SetTextMirrored( aField->IsMirrored() ); - strokeText( aField->GetFullyQualifiedText(), textpos, - orient == TEXT_ANGLE_VERT ? M_PI / 2 : 0 ); + strokeText( aField->GetShownText(), textpos, orient == TEXT_ANGLE_VERT ? M_PI / 2 : 0 ); } // Draw the umbilical line diff --git a/eeschema/sch_sexpr_plugin.cpp b/eeschema/sch_sexpr_plugin.cpp index 2749cc5eba..feaaf52d94 100644 --- a/eeschema/sch_sexpr_plugin.cpp +++ b/eeschema/sch_sexpr_plugin.cpp @@ -890,9 +890,9 @@ void SCH_SEXPR_PLUGIN::saveSymbol( SCH_COMPONENT* aSymbol, int aNestLevel ) m_out->Print( aNestLevel + 1, "(uuid %s)\n", m_out->Quotew( aSymbol->m_Uuid.AsString() ).c_str() ); - for( auto field : aSymbol->GetFields() ) + for( SCH_FIELD& field : aSymbol->GetFields() ) { - saveField( field, aNestLevel + 1 ); + saveField( &field, aNestLevel + 1 ); } // @todo Save sheet UUID at top level of schematic file. This will require saving from @@ -1304,7 +1304,7 @@ LIB_PART* SCH_SEXPR_PLUGIN_CACHE::removeSymbol( LIB_PART* aPart ) { LIB_FIELD& field = static_cast( drawItem ); - if( firstChild->FindField( field.GetName( NATIVE_FIELD_NAME ) ) ) + if( firstChild->FindField( field.GetCanonicalName() ) ) continue; } @@ -1797,7 +1797,7 @@ void SCH_SEXPR_PLUGIN_CACHE::saveField( LIB_FIELD* aField, { wxCHECK_RET( aField && aField->Type() == LIB_FIELD_T, "Invalid LIB_FIELD object." ); - wxString fieldName = aField->GetName( NATIVE_FIELD_NAME ); + wxString fieldName = aField->GetCanonicalName(); // When saving legacy fields, prefix the field name with "ki_" to prevent name clashes // with exisiting user defined fields. diff --git a/eeschema/sch_sheet_path.cpp b/eeschema/sch_sheet_path.cpp index 3befe54961..19dcf97829 100644 --- a/eeschema/sch_sheet_path.cpp +++ b/eeschema/sch_sheet_path.cpp @@ -423,12 +423,12 @@ SCH_ITEM* SCH_SHEET_LIST::GetItem( const KIID& aID, SCH_SHEET_PATH* aPathOut ) { SCH_COMPONENT* comp = static_cast( aItem ); - for( SCH_FIELD* field : comp->GetFields() ) + for( SCH_FIELD& field : comp->GetFields() ) { - if( field->m_Uuid == aID ) + if( field.m_Uuid == aID ) { *aPathOut = sheet; - return field; + return &field; } } @@ -445,6 +445,15 @@ SCH_ITEM* SCH_SHEET_LIST::GetItem( const KIID& aID, SCH_SHEET_PATH* aPathOut ) { SCH_SHEET* sch_sheet = static_cast( aItem ); + for( SCH_FIELD& field : sch_sheet->GetFields() ) + { + if( field.m_Uuid == aID ) + { + *aPathOut = sheet; + return &field; + } + } + for( SCH_SHEET_PIN* pin : sch_sheet->GetPins() ) { if( pin->m_Uuid == aID ) diff --git a/eeschema/sch_view.cpp b/eeschema/sch_view.cpp index 0734aadbbc..725cb8d591 100644 --- a/eeschema/sch_view.cpp +++ b/eeschema/sch_view.cpp @@ -97,6 +97,7 @@ void SCH_VIEW::DisplaySheet( SCH_SCREEN *aScreen ) m_worksheet.reset( new KIGFX::WS_PROXY_VIEW_ITEM( static_cast< int >( IU_PER_MILS ), &aScreen->GetPageSettings(), + &aScreen->Prj(), &aScreen->GetTitleBlock() ) ); m_worksheet->SetSheetNumber( aScreen->m_ScreenNumber ); m_worksheet->SetSheetCount( aScreen->m_NumberOfScreens ); diff --git a/eeschema/tools/ee_selection_tool.cpp b/eeschema/tools/ee_selection_tool.cpp index 926f493d0a..e538a53b5c 100644 --- a/eeschema/tools/ee_selection_tool.cpp +++ b/eeschema/tools/ee_selection_tool.cpp @@ -989,10 +989,10 @@ void EE_SELECTION_TOOL::RebuildSelection() { if( item->Type() == SCH_COMPONENT_T ) { - for( SCH_FIELD* field : static_cast( item )->GetFields() ) + for( SCH_FIELD& field : static_cast( item )->GetFields() ) { - if( field->IsSelected() ) - select( field ); + if( field.IsSelected() ) + select( &field ); } } @@ -1231,12 +1231,12 @@ void EE_SELECTION_TOOL::highlight( EDA_ITEM* aItem, int aMode, EE_SELECTION* aGr pin->SetBrightened(); } - for( SCH_FIELD* field : static_cast( aItem )->GetFields() ) + for( SCH_FIELD& field : static_cast( aItem )->GetFields() ) { if( aMode == SELECTED ) - field->SetSelected(); + field.SetSelected(); else if( aMode == BRIGHTENED ) - field->SetBrightened(); + field.SetBrightened(); } } else if( itemType == SCH_SHEET_T ) @@ -1291,12 +1291,12 @@ void EE_SELECTION_TOOL::unhighlight( EDA_ITEM* aItem, int aMode, EE_SELECTION* a pin->ClearBrightened(); } - for( SCH_FIELD* field : static_cast( aItem )->GetFields() ) + for( SCH_FIELD& field : static_cast( aItem )->GetFields() ) { if( aMode == SELECTED ) - field->ClearSelected(); + field.ClearSelected(); else if( aMode == BRIGHTENED ) - field->ClearBrightened(); + field.ClearBrightened(); } } else if( itemType == SCH_SHEET_T ) diff --git a/eeschema/tools/lib_edit_tool.cpp b/eeschema/tools/lib_edit_tool.cpp index f88ed33163..e4b56108c9 100644 --- a/eeschema/tools/lib_edit_tool.cpp +++ b/eeschema/tools/lib_edit_tool.cpp @@ -482,7 +482,7 @@ void LIB_EDIT_TOOL::editFieldProperties( LIB_FIELD* aField ) if( aField->GetId() == VALUE ) caption = _( "Edit Component Name" ); else - caption.Printf( _( "Edit %s Field" ), aField->GetName( TRANSLATE_FIELD_NAME ) ); + caption.Printf( _( "Edit %s Field" ), aField->GetName() ); DIALOG_LIB_EDIT_ONE_FIELD dlg( m_frame, caption, aField ); diff --git a/eeschema/tools/sch_editor_control.cpp b/eeschema/tools/sch_editor_control.cpp index 89c5b38402..c8df41bfea 100644 --- a/eeschema/tools/sch_editor_control.cpp +++ b/eeschema/tools/sch_editor_control.cpp @@ -220,8 +220,8 @@ SCH_ITEM* SCH_EDITOR_CONTROL::nextMatch( for( auto field : cmp->GetFields() ) { - if( field->Matches( *aData, nullptr ) ) - return field; + if( field.Matches( *aData, nullptr ) ) + return &field; } for( auto pin : cmp->GetSchPins() ) diff --git a/gerbview/gerbview_frame.cpp b/gerbview/gerbview_frame.cpp index bb5ec9f8ac..c10014ccb8 100644 --- a/gerbview/gerbview_frame.cpp +++ b/gerbview/gerbview_frame.cpp @@ -874,8 +874,8 @@ void GERBVIEW_FRAME::SetPageSettings( const PAGE_INFO& aPageSettings ) auto drawPanel = static_cast( GetCanvas() ); // Prepare worksheet template - auto worksheet = - new KIGFX::WS_PROXY_VIEW_ITEM( IU_PER_MILS, &GetPageSettings(), &GetTitleBlock() ); + auto worksheet = new KIGFX::WS_PROXY_VIEW_ITEM( IU_PER_MILS, &GetPageSettings(), + &Prj(), &GetTitleBlock() ); if( screen != NULL ) { diff --git a/include/common.h b/include/common.h index 592524630c..5492e60765 100644 --- a/include/common.h +++ b/include/common.h @@ -49,6 +49,7 @@ #include #include +class PROJECT; class SEARCH_STACK; class REPORTER; @@ -310,6 +311,14 @@ const wxString PrePendPath( const wxString& aEnvVar, const wxString& aPriorityPa */ const wxString ExpandEnvVarSubstitutions( const wxString& aString ); +/** + * Expand '${var-name}' templates in text. The LocalResolver is given first crack at it, + * after which the PROJECT's resolver is called. + */ +wxString ExpandTextVars( const wxString& aSource, + const std::function& aLocalResolver, + const PROJECT* aProject ); + /** * Replace any environment variables in file-path uris (leaving network-path URIs alone). */ diff --git a/include/config_params.h b/include/config_params.h index 5dc94528e3..46886c1d03 100644 --- a/include/config_params.h +++ b/include/config_params.h @@ -50,6 +50,7 @@ using KIGFX::COLOR4D; #define GROUP_CVP_EQU wxT( "/cvpcb/equfiles" ) #define GROUP_SHEET_NAMES wxT( "/sheetnames" ) +#define GROUP_TEXT_VARS wxT( "/text_variables" ) #define CONFIG_VERSION 1 diff --git a/include/panel_text_variables.h b/include/panel_text_variables.h new file mode 100644 index 0000000000..12097b3165 --- /dev/null +++ b/include/panel_text_variables.h @@ -0,0 +1,65 @@ +/* + * 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 + */ + +#ifndef _PANEL_TEXT_VARIABLES_H_ +#define _PANEL_TEXT_VARIABLES_H_ + +#include <../common/dialogs/panel_text_variables_base.h> +#include + +class PROJECT; + + +class PANEL_TEXT_VARIABLES: public PANEL_TEXT_VARIABLES_BASE +{ +public: + PANEL_TEXT_VARIABLES( wxWindow* aParent, PROJECT* aProject ); + ~PANEL_TEXT_VARIABLES() override; + + bool TransferDataToWindow() override; + bool TransferDataFromWindow() override; + +protected: + // Various button callbacks + void OnGridCellChange( wxGridEvent& event ) override; + void OnGridSize( wxSizeEvent& event ) override; + void OnUpdateUI( wxUpdateUIEvent& event ) override; + void OnGridCellChanging( wxGridEvent& event ); + void OnAddTextVar( wxCommandEvent& event ) override; + void OnRemoveTextVar( wxCommandEvent& event ) override; + + void AppendTextVar( const wxString& aName, const wxString& aValue ); + +private: + PROJECT* m_project; + + wxString m_errorMsg; + int m_errorRow; + int m_errorCol; + + wxTextValidator m_nameValidator; + + bool m_gridWidthsDirty; +}; + +#endif // _PANEL_TEXT_VARIABLES_H_ diff --git a/include/plotter.h b/include/plotter.h index b807597598..07cd259b5f 100644 --- a/include/plotter.h +++ b/include/plotter.h @@ -1429,9 +1429,9 @@ protected: class DXF_PLOTTER : public PLOTTER { public: - DXF_PLOTTER() : textAsLines( false ) + DXF_PLOTTER() : m_textAsLines( false ) { - textAsLines = true; + m_textAsLines = true; m_currentColor = COLOR4D::BLACK; m_currentLineType = PLOT_DASH_TYPE::SOLID; SetUnits( DXF_UNITS::INCHES ); @@ -1453,7 +1453,7 @@ public: virtual void SetTextMode( PLOT_TEXT_MODE mode ) override { if( mode != PLOT_TEXT_MODE::DEFAULT ) - textAsLines = ( mode != PLOT_TEXT_MODE::NATIVE ); + m_textAsLines = ( mode != PLOT_TEXT_MODE::NATIVE ); } virtual bool StartPlot() override; @@ -1566,22 +1566,21 @@ public: } protected: - bool textAsLines; - COLOR4D m_currentColor; + bool m_textAsLines; + COLOR4D m_currentColor; PLOT_DASH_TYPE m_currentLineType; - DXF_UNITS m_plotUnits; - double m_unitScalingFactor; - unsigned int m_measurementDirective; + DXF_UNITS m_plotUnits; + double m_unitScalingFactor; + unsigned int m_measurementDirective; }; class TITLE_BLOCK; -void PlotWorkSheet( PLOTTER* plotter, const TITLE_BLOCK& aTitleBlock, - const PAGE_INFO& aPageInfo, - int aSheetNumber, int aNumberOfSheets, - const wxString &aSheetDesc, - const wxString &aFilename, - const COLOR4D aColor = COLOR4D::UNSPECIFIED ); + +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, + COLOR4D aColor = COLOR4D::UNSPECIFIED ); /** Returns the default plot extension for a format */ diff --git a/include/project.h b/include/project.h index 2334e4875e..247e677cd9 100644 --- a/include/project.h +++ b/include/project.h @@ -79,6 +79,9 @@ public: //--------------------------------------------------------- + VTBL_ENTRY bool TextVarResolver( wxString* aToken ) const; + VTBL_ENTRY std::map& GetTextVars() { return m_textVars; } + // VTBL_ENTRY bool MaybeLoadProjectSettings( const std::vector& aFileSet ); /** @@ -337,7 +340,8 @@ private: wxFileName m_project_name; ///< \/\.pro wxString m_pro_date_and_time; - std::map m_sheetNames; + std::map m_sheetNames; + std::map m_textVars; /// @see this::SetRString(), GetRString(), and enum RSTRING_T. wxString m_rstrings[RSTRING_COUNT]; @@ -347,38 +351,4 @@ private: }; -//-------------------------------------------------------------- - -#if 0 - /** - * Function Value - * fetches a project variable @a aVariable and returns true if that variable was - * found, else false. If not found, aFetchedValue is not touched. Any environment - * variable is also a project variable. - * - * @param aVariable is the property or option to look for. - * @param aFetchedValue is where to put the value of the property if it exists - * and aFetchedValue is not NULL. - * @return bool - true if variable was found, else false. - */ - VTBL_ENTRY bool Value( const wxString& aVariable, wxString* aFetchedValue = NULL ); - - /** - * Function Substitute - * replaces any project variable references found within @a aString with their - * values. Any referenced variable is first sought in the PROJECT space, and if - * not found, then sought in the environment. - */ - VTBL_ENTRY const wxString Substitute( const wxString& aString ); - - /** - * Function SubstituteAndEvaluate - * replaces any project variable references found within @a aString with their - * values, and evaluates aString as an expression. - * Any referenced variable is first sought in the PROJECT space, and if - * not found, then sought in the environment. - */ - VTBL_ENTRY const wxString SubstituteAndEvaluate( const wxString& aString ); -#endif - #endif // PROJECT_H_ diff --git a/include/ws_draw_item.h b/include/ws_draw_item.h index b199544f72..d1f876171d 100644 --- a/include/ws_draw_item.h +++ b/include/ws_draw_item.h @@ -353,20 +353,20 @@ class WS_DRAW_ITEM_LIST { protected: std::vector m_graphicList; // Items to draw/plot - unsigned m_idx; // for GetFirst, GetNext functions - double m_milsToIu; // the scalar to convert pages units ( mils) - // to draw/plot units. - int m_penSize; // The default line width for drawings. - // used when an item has a pen size = 0 - int m_sheetNumber; // the value of the sheet number, for basic inscriptions - int m_sheetCount; // the value of the number of sheets, in schematic - // for basic inscriptions, in schematic - const TITLE_BLOCK* m_titleBlock; // for basic inscriptions - const wxString* m_paperFormat; // for basic inscriptions - wxString m_fileName; // for basic inscriptions - wxString m_sheetFullName; // for basic inscriptions - const wxString* m_sheetLayer; // for basic inscriptions - + unsigned m_idx; // for GetFirst, GetNext functions + double m_milsToIu; // the scalar to convert pages units ( mils) + // to draw/plot units. + int m_penSize; // The default line width for drawings. + // used when an item has a pen size = 0 + int m_sheetNumber; // the value of the sheet number, for basic inscriptions + int m_sheetCount; // the value of the number of sheets, in schematic + // for basic inscriptions, in schematic + const TITLE_BLOCK* m_titleBlock; // for basic inscriptions + const wxString* m_paperFormat; // for basic inscriptions + wxString m_fileName; // for basic inscriptions + wxString m_sheetFullName; // for basic inscriptions + const wxString* m_sheetLayer; // for basic inscriptions + const PROJECT* m_project; // for project-based variable substitutions public: WS_DRAW_ITEM_LIST() @@ -379,6 +379,7 @@ public: m_sheetLayer = nullptr; m_titleBlock = nullptr; m_paperFormat = nullptr; + m_project = nullptr; } ~WS_DRAW_ITEM_LIST() @@ -388,6 +389,8 @@ public: // delete item; } + void SetProject( const PROJECT* aProject ) { m_project = aProject; } + /** * Set the title block (mainly for page layout editor) */ diff --git a/include/ws_painter.h b/include/ws_painter.h index 6e21d97626..2656abf17a 100644 --- a/include/ws_painter.h +++ b/include/ws_painter.h @@ -155,6 +155,6 @@ private: 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 = wxEmptyString ); + const PROJECT* aProject, const wxString& aSheetLayer = wxEmptyString ); #endif // WS_PAINTER_H diff --git a/include/ws_proxy_view_item.h b/include/ws_proxy_view_item.h index 6f58eaa986..84be559494 100644 --- a/include/ws_proxy_view_item.h +++ b/include/ws_proxy_view_item.h @@ -32,7 +32,6 @@ class PAGE_INFO; class TITLE_BLOCK; class WS_DRAW_ITEM_LINE; class WS_DRAW_ITEM_RECT; -class WS_DRAW_ITEM_POLYGON; class WS_DRAW_ITEM_TEXT; class WS_DRAW_ITEM_BITMAP; @@ -44,67 +43,32 @@ class GAL; class WS_PROXY_VIEW_ITEM : public EDA_ITEM { public: - WS_PROXY_VIEW_ITEM( int aScaleFactor, const PAGE_INFO* aPageInfo, const TITLE_BLOCK* aTitleBlock ); + WS_PROXY_VIEW_ITEM( int aScaleFactor, const PAGE_INFO* aPageInfo, const PROJECT* aProject, + const TITLE_BLOCK* aTitleBlock ); /** * Function SetFileName() * Sets the file name displayed in the title block. - * - * @param aFileName is the new file name. */ - void SetFileName( const std::string& aFileName ) - { - m_fileName = aFileName; - } + void SetFileName( const std::string& aFileName ) { m_fileName = aFileName; } /** * Function SetSheetName() * Sets the sheet name displayed in the title block. - * - * @param aSheetName is the new sheet name. */ - void SetSheetName( const std::string& aSheetName ) - { - m_sheetName = aSheetName; - } - - /** - * Function SetPageInfo() - * Changes the PAGE_INFO object used to draw the worksheet. - * - * @param aPageInfo is the new PAGE_INFO object. - */ - void SetPageInfo( const PAGE_INFO* aPageInfo ); - - /** - * Function SetTitleBlock() - * Changes the TITLE_BLOCK object used to draw the worksheet. - * - * @param aTitleBlock is the new TITLE_BLOCK object. - */ - void SetTitleBlock( const TITLE_BLOCK* aTitleBlock ); + void SetSheetName( const std::string& aSheetName ) { m_sheetName = aSheetName; } /** * Function SetSheetNumber() * Changes the sheet number displayed in the title block. - * - * @param aSheetNumber is the new sheet number. */ - void SetSheetNumber( int aSheetNumber ) - { - m_sheetNumber = aSheetNumber; - } + void SetSheetNumber( int aSheetNumber ) { m_sheetNumber = aSheetNumber; } /** * Function SetSheetCount() * Changes the sheets count number displayed in the title block. - * - * @param aSheetCount is the new sheets count number. */ - void SetSheetCount( int aSheetCount ) - { - m_sheetCount = aSheetCount; - } + void SetSheetCount( int aSheetCount ) { m_sheetCount = aSheetCount; } /** * Can be used to override which layer ID is used for worksheet item colors @@ -140,28 +104,18 @@ public: protected: /// the factor between mils (units used in worksheet and internal units) /// it is the value IU_PER_MILS used in the caller - int m_mils2IUscalefactor; + int m_mils2IUscalefactor; - /// File name displayed in the title block - std::string m_fileName; - - /// Sheet name displayed in the title block - std::string m_sheetName; - - /// Title block that contains properties of the title block displayed in the worksheet. + std::string m_fileName; + std::string m_sheetName; const TITLE_BLOCK* m_titleBlock; - - /// Worksheet page information. - const PAGE_INFO* m_pageInfo; - - /// Sheet number displayed in the title block. - int m_sheetNumber; - - /// Sheets count number displayed in the title block. - int m_sheetCount; + const PAGE_INFO* m_pageInfo; + int m_sheetNumber; + int m_sheetCount; + const PROJECT* m_project; /// Layer that is used for worksheet color (LAYER_WORKSHEET is always used for visibility) - int m_colorLayer; + int m_colorLayer; }; } diff --git a/pagelayout_editor/pl_draw_panel_gal.cpp b/pagelayout_editor/pl_draw_panel_gal.cpp index 0ab50bea59..f5ef791921 100644 --- a/pagelayout_editor/pl_draw_panel_gal.cpp +++ b/pagelayout_editor/pl_draw_panel_gal.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -98,6 +99,7 @@ void PL_DRAW_PANEL_GAL::DisplayWorksheet() WS_DRAW_ITEM_LIST dummy; dummy.SetPaperFormat( &m_edaFrame->GetPageSettings().GetType() ); dummy.SetTitleBlock( &m_edaFrame->GetTitleBlock() ); + dummy.SetProject( &m_edaFrame->Prj() ); for( WS_DATA_ITEM* dataItem : model.GetItems() ) dataItem->SyncDrawItems( &dummy, m_view ); diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index bbe20f896a..a37a484b7f 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -100,8 +100,10 @@ wxPoint BOARD_ITEM::ZeroOffset( 0, 0 ); static PCBNEW_SETTINGS dummyGeneralSettings; BOARD::BOARD() : - BOARD_ITEM_CONTAINER( (BOARD_ITEM*) NULL, PCB_T ), - m_paper( PAGE_INFO::A4 ), m_NetInfo( this ) + BOARD_ITEM_CONTAINER( (BOARD_ITEM*) NULL, PCB_T ), + m_paper( PAGE_INFO::A4 ), + m_NetInfo( this ), + m_project( nullptr ) { // we have not loaded a board yet, assume latest until then. m_fileFormatVersionAtLoad = LEGACY_BOARD_FILE_VERSION; diff --git a/pcbnew/class_board.h b/pcbnew/class_board.h index f69b7731b2..caa1835c0d 100644 --- a/pcbnew/class_board.h +++ b/pcbnew/class_board.h @@ -57,6 +57,7 @@ class REPORTER; class SHAPE_POLY_SET; class CONNECTIVITY_DATA; class COMPONENT; +class PROJECT; // Forward declare endpoint from class_track.h enum ENDPOINT_T : int; @@ -185,20 +186,21 @@ private: LAYER m_Layer[PCB_LAYER_ID_COUNT]; - // if true m_highLight_NetCode is used + // if true m_highLight_NetCode is used HIGH_LIGHT_INFO m_highLight; // current high light data HIGH_LIGHT_INFO m_highLightPrevious; // a previously stored high light data - int m_fileFormatVersionAtLoad; ///< the version loaded from the file + int m_fileFormatVersionAtLoad; // the version loaded from the file std::shared_ptr m_connectivity; BOARD_DESIGN_SETTINGS m_designSettings; - PCBNEW_SETTINGS* m_generalSettings; ///< reference only; I have no ownership + 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 + TITLE_BLOCK m_titles; // text in lower right of screen and plots PCB_PLOT_PARAMS m_plotOptions; - NETINFO_LIST m_NetInfo; ///< net info list (name, design constraints .. + NETINFO_LIST m_NetInfo; // net info list (name, design constraints .. + PROJECT* m_project; // project this board is a part of (if any) // The default copy constructor & operator= are inadequate, @@ -303,10 +305,7 @@ public: * returns list of missing connections between components/tracks. * @return an object that contains informations about missing connections. */ - std::shared_ptr GetConnectivity() const - { - return m_connectivity; - } + std::shared_ptr GetConnectivity() const { return m_connectivity; } /** * Builds or rebuilds the board connectivity database for the board, @@ -327,6 +326,9 @@ public: */ void DeleteZONEOutlines(); + PROJECT* GetProject() const { return m_project; } + void SetProject( PROJECT* aProject ) { m_project = aProject; } + /** * Function SetAuxOrigin * sets the origin point used for plotting. @@ -355,16 +357,8 @@ public: * Function GetHighLightNetCode * @return netcode of net to highlight (-1 when no net selected) */ - int GetHighLightNetCode() const { return m_highLight.m_netCode; } - - /** - * Function SetHighLightNet - * @param aNetCode = netcode of net to highlight - */ - void SetHighLightNet( int aNetCode) - { - m_highLight.m_netCode = aNetCode; - } + int GetHighLightNetCode() const { return m_highLight.m_netCode; } + void SetHighLightNet( int aNetCode) { m_highLight.m_netCode = aNetCode; } /** * Function IsHighLightNetON @@ -372,25 +366,19 @@ public: */ bool IsHighLightNetON() const { return m_highLight.m_highLightOn; } - /** - * Function HighLightOFF - * Disable highlight. - */ - void HighLightOFF() { m_highLight.m_highLightOn = false; } - /** * Function HighLightON * Enable highlight. * if m_highLight_NetCode >= 0, this net will be highlighted */ void HighLightON() { m_highLight.m_highLightOn = true; } + void HighLightOFF() { m_highLight.m_highLightOn = false; } /** * Function GetCopperLayerCount * @return int - The number of copper layers in the BOARD. */ int GetCopperLayerCount() const; - void SetCopperLayerCount( int aCount ); /** @@ -575,25 +563,13 @@ public: /** * Function GetLayerID - * returns the ID of a layer given by aLayerName. Copper layers may - * have custom names. - * - * @param aLayerName = A layer name, like wxT("B.Cu"), etc. - * - * @return PCB_LAYER_ID - the layer id, which for copper layers may - * be custom, else standard. + * returns the ID of a layer. Copper layers may have custom names. */ const PCB_LAYER_ID GetLayerID( const wxString& aLayerName ) const; /** * Function GetLayerName - * returns the name of a layer given by aLayer. Copper layers may - * have custom names. - * - * @param aLayer = A layer, like B_Cu, etc. - * - * @return wxString - the layer name, which for copper layers may - * be custom, else standard. + * returns the name of a layer. Copper layers may have custom names. */ const wxString GetLayerName( PCB_LAYER_ID aLayer ) const; diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp index 827b28fe6a..6c3be99527 100644 --- a/pcbnew/class_module.cpp +++ b/pcbnew/class_module.cpp @@ -1330,12 +1330,12 @@ BOARD_ITEM* MODULE::DuplicateItem( const BOARD_ITEM* aItem, bool aIncrementPadNu if( new_text->GetType() == TEXTE_MODULE::TEXT_is_REFERENCE ) { - new_text->SetText( wxT( "%R" ) ); + new_text->SetText( wxT( "${REFERENCE}" ) ); new_text->SetType( TEXTE_MODULE::TEXT_is_DIVERS ); } else if( new_text->GetType() == TEXTE_MODULE::TEXT_is_VALUE ) { - new_text->SetText( wxT( "%V" ) ); + new_text->SetText( wxT( "${VALUE}" ) ); new_text->SetType( TEXTE_MODULE::TEXT_is_DIVERS ); } diff --git a/pcbnew/class_pcb_text.cpp b/pcbnew/class_pcb_text.cpp index 92961210d9..00e87354ec 100644 --- a/pcbnew/class_pcb_text.cpp +++ b/pcbnew/class_pcb_text.cpp @@ -61,6 +61,26 @@ TEXTE_PCB::~TEXTE_PCB() } +wxString TEXTE_PCB::GetShownText() const +{ + const BOARD* board = static_cast( GetParent() ); + wxASSERT( board ); + + auto moduleResolver = [ this ]( wxString* token ) -> bool + { + if( token->IsSameAs( wxT( "LAYER" ) ) ) + { + *token = GetLayerName(); + return true; + } + + return false; + }; + + return ExpandTextVars( GetText(), moduleResolver, board->GetProject() ); +} + + void TEXTE_PCB::SetTextAngle( double aAngle ) { EDA_TEXT::SetTextAngle( NormalizeAngle360Min( aAngle ) ); @@ -178,9 +198,12 @@ EDA_ITEM* TEXTE_PCB::Clone() const return new TEXTE_PCB( *this ); } + void TEXTE_PCB::SwapData( BOARD_ITEM* aImage ) { assert( aImage->Type() == PCB_TEXT_T ); std::swap( *((TEXTE_PCB*) this), *((TEXTE_PCB*) aImage) ); } + + diff --git a/pcbnew/class_pcb_text.h b/pcbnew/class_pcb_text.h index 9ddcff1f6c..d626ea59db 100644 --- a/pcbnew/class_pcb_text.h +++ b/pcbnew/class_pcb_text.h @@ -53,6 +53,8 @@ public: return aItem && PCB_TEXT_T == aItem->Type(); } + wxString GetShownText() const override; + bool Matches( wxFindReplaceData& aSearchData, void* aAuxData ) override { return BOARD_ITEM::Matches( GetShownText(), aSearchData ); diff --git a/pcbnew/class_text_mod.cpp b/pcbnew/class_text_mod.cpp index 2e9d70f2f7..92309b594e 100644 --- a/pcbnew/class_text_mod.cpp +++ b/pcbnew/class_text_mod.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -41,7 +42,7 @@ #include #include #include - +#include TEXTE_MODULE::TEXTE_MODULE( MODULE* parent, TEXT_TYPE text_type ) : BOARD_ITEM( parent, PCB_MODULE_TEXT_T ), @@ -274,10 +275,10 @@ void TEXTE_MODULE::Print( PCB_BASE_FRAME* aFrame, wxDC* aDC, const wxPoint& aOff || ( IsBackLayer( text_layer ) && !brd->IsElementVisible( LAYER_MOD_TEXT_BK ) ) ) return; - if( !brd->IsElementVisible( LAYER_MOD_REFERENCES ) && GetText() == wxT( "%R" ) ) + if( !brd->IsElementVisible( LAYER_MOD_REFERENCES ) && GetText() == wxT( "${REFERENCE}" ) ) return; - if( !brd->IsElementVisible( LAYER_MOD_VALUES ) && GetText() == wxT( "%V" ) ) + if( !brd->IsElementVisible( LAYER_MOD_VALUES ) && GetText() == wxT( "${VALUE}" ) ) return; // Invisible texts are still drawn (not plotted) in LAYER_MOD_TEXT_INVISIBLE @@ -462,11 +463,11 @@ unsigned int TEXTE_MODULE::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const return HIDE; // Handle Render tab switches - if( ( m_Type == TEXT_is_VALUE || GetText() == wxT( "%V" ) ) + if( ( m_Type == TEXT_is_VALUE || GetText() == wxT( "${VALUE}" ) ) && !aView->IsLayerVisible( LAYER_MOD_VALUES ) ) return HIDE; - if( ( m_Type == TEXT_is_REFERENCE || GetText() == wxT( "%R" ) ) + if( ( m_Type == TEXT_is_REFERENCE || GetText() == wxT( "${REFERENCE}" ) ) && !aView->IsLayerVisible( LAYER_MOD_REFERENCES ) ) return HIDE; @@ -489,57 +490,35 @@ unsigned int TEXTE_MODULE::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const wxString TEXTE_MODULE::GetShownText() const { - /* First order optimization: no % means that no processing is - * needed; just hope that RVO and copy constructor implementation - * avoid to copy the whole block; anyway it should be better than - * rebuild the string one character at a time... - * Also it seems wise to only expand macros in user text (but there - * is no technical reason, probably) */ + const MODULE* module = static_cast( GetParent() ); + wxASSERT( module ); - if( (m_Type != TEXT_is_DIVERS) || (wxString::npos == GetText().find('%')) ) - return GetText(); + const BOARD* board = static_cast( module->GetParent() ); + wxASSERT( board ); - wxString newbuf; - const MODULE *module = static_cast( GetParent() ); + auto moduleResolver = [ this, module ]( wxString* token ) -> bool + { + if( module ) + { + if( token->IsSameAs( wxT( "REFERENCE" ) ) ) + { + *token = module->GetReference(); + return true; + } + else if( token->IsSameAs( wxT( "VALUE" ) ) ) + { + *token = module->GetValue(); + return true; + } + else if( token->IsSameAs( wxT( "LAYER" ) ) ) + { + *token = GetLayerName(); + return true; + } + } - for( wxString::const_iterator it = GetText().begin(); it != GetText().end(); ++it ) - { - // Process '%' and copy everything else - if( *it != '%' ) - newbuf.append(*it); - else - { - /* Look at the next character (if is it there) and append - * its expansion */ - ++it; + return false; + }; - if( it != GetText().end() ) - { - switch( char(*it) ) - { - case '%': - newbuf.append( '%' ); - break; - - case 'R': - if( module ) - newbuf.append( module->GetReference() ); - break; - - case 'V': - if( module ) - newbuf.append( module->GetValue() ); - break; - - default: - newbuf.append( '?' ); - break; - } - } - else - break; // The string is over and we can't ++ anymore - } - } - - return newbuf; + return ExpandTextVars( GetText(), moduleResolver, board->GetProject() ); } diff --git a/pcbnew/dialogs/dialog_board_setup.cpp b/pcbnew/dialogs/dialog_board_setup.cpp index 695e60997c..e5f33fefe7 100644 --- a/pcbnew/dialogs/dialog_board_setup.cpp +++ b/pcbnew/dialogs/dialog_board_setup.cpp @@ -29,13 +29,11 @@ #include #include #include +#include #include "dialog_board_setup.h" -bool g_macHack; - - DIALOG_BOARD_SETUP::DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame ) : PAGED_DIALOG( aFrame, _( "Board Setup" ), _( "Import Settings from Another Project..." ) ), m_frame( aFrame ) @@ -53,6 +51,8 @@ DIALOG_BOARD_SETUP::DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame ) : m_severities = new PANEL_SETUP_SEVERITIES( this, dummyItem, bds.m_DRCSeverities, DRCE_FIRST, DRCE_LAST ); + m_textVars = new PANEL_TEXT_VARIABLES( this, &Prj() ); + /* * WARNING: If you change page names you MUST update calls to DoShowBoardSetupDialog(). */ @@ -73,12 +73,17 @@ DIALOG_BOARD_SETUP::DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame ) : m_treebook->AddSubPage( m_netclasses, _( "Net Classes" ) ); 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_BOARD_SETUP::OnPageChange ), NULL, this ); FinishDialogSettings(); - g_macHack = true; + + for( int i = 0; i < m_treebook->GetPageCount(); ++i ) + m_macHack.push_back( true ); } @@ -95,13 +100,18 @@ void DIALOG_BOARD_SETUP::OnPageChange( wxBookCtrlEvent& event ) m_physicalStackup->OnLayersOptionsChanged( m_layers->GetUILayerMask() ); #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_tracksAndVias ) - { - m_tracksAndVias->SetSize( wxSize( m_tracksAndVias->GetSize().x - 1, - m_tracksAndVias->GetSize().y + 2 ) ); + // Work around an OSX bug where the wxGrid children don't get placed correctly until + // the first resize event + int page = event.GetSelection(); - g_macHack = false; + if( m_macHack[ page ] ) + { + wxSize pageSize = m_treebook->GetPage( page )->GetSize(); + pageSize.x -= 1; + pageSize.y += 2; + + m_treebook->GetPage( page )->SetSize( pageSize ); + m_macHack[ page ] = false; } #endif } diff --git a/pcbnew/dialogs/dialog_board_setup.h b/pcbnew/dialogs/dialog_board_setup.h index 446fec8064..fa4a7d1f94 100644 --- a/pcbnew/dialogs/dialog_board_setup.h +++ b/pcbnew/dialogs/dialog_board_setup.h @@ -32,6 +32,7 @@ class PANEL_SETUP_TRACKS_AND_VIAS; class PANEL_SETUP_MASK_AND_PASTE; class PANEL_SETUP_BOARD_STACKUP; class PANEL_SETUP_SEVERITIES; +class PANEL_TEXT_VARIABLES; class DIALOG_BOARD_SETUP : public PAGED_DIALOG @@ -53,6 +54,9 @@ protected: PANEL_SETUP_MASK_AND_PASTE* m_maskAndPaste; PANEL_SETUP_BOARD_STACKUP* m_physicalStackup; PANEL_SETUP_SEVERITIES* m_severities; + PANEL_TEXT_VARIABLES* m_textVars; + + std::vector m_macHack; // event handlers void OnPageChange( wxBookCtrlEvent& event ); diff --git a/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor.cpp b/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor.cpp index f6b657fc7f..d0093a2b26 100644 --- a/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor.cpp +++ b/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor.cpp @@ -53,7 +53,6 @@ int DIALOG_FOOTPRINT_BOARD_EDITOR::m_page = 0; // remember the last open page during session - DIALOG_FOOTPRINT_BOARD_EDITOR::DIALOG_FOOTPRINT_BOARD_EDITOR( PCB_EDIT_FRAME* aParent, MODULE* aModule ) : DIALOG_FOOTPRINT_BOARD_EDITOR_BASE( aParent ), @@ -156,6 +155,9 @@ DIALOG_FOOTPRINT_BOARD_EDITOR::DIALOG_FOOTPRINT_BOARD_EDITOR( PCB_EDIT_FRAME* aP m_buttonRemove->SetBitmap( KiBitmap( trash_xpm ) ); FinishDialogSettings(); + + for( int i = 0; i < m_NoteBook->GetPageCount(); ++i ) + m_macHack.push_back( true ); } @@ -921,6 +923,29 @@ void DIALOG_FOOTPRINT_BOARD_EDITOR::OnGridSize( wxSizeEvent& aEvent ) } +void DIALOG_FOOTPRINT_BOARD_EDITOR::OnPageChange( wxNotebookEvent& aEvent ) +{ + int page = aEvent.GetSelection(); + + // Shouldn't be necessary, but is on at least OSX + if( page >= 0 ) + m_NoteBook->ChangeSelection( (unsigned) page ); + +#ifdef __WXMAC__ + // Work around an OSX bug where the wxGrid children don't get placed correctly until + // the first resize event + if( m_macHack[ page ] ) + { + wxSize pageSize = m_NoteBook->GetPage( page )->GetSize(); + pageSize.x -= 1; + + m_NoteBook->GetPage( page )->SetSize( pageSize ); + m_macHack[ page ] = false; + } +#endif +} + + void DIALOG_FOOTPRINT_BOARD_EDITOR::updateOrientationControl() { KIUI::ValidatorTransferToWindowWithoutEvents( m_OrientValidator ); diff --git a/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor.h b/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor.h index 845ce9ba19..4dcfc7a16e 100644 --- a/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor.h +++ b/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor.h @@ -66,6 +66,7 @@ private: bool m_initialFocus; bool m_inSelect; + std::vector m_macHack; public: // The dialog can be closed for several reasons. @@ -106,6 +107,7 @@ private: void OnAddField( wxCommandEvent& ) override; void OnDeleteField( wxCommandEvent& ) override; void OnUpdateUI( wxUpdateUIEvent& ) override; + void OnPageChange( wxNotebookEvent& event ) override; void select3DModel( int aModelIdx ); diff --git a/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor_base.cpp b/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor_base.cpp index e3546bdcd4..25609eeeb1 100644 --- a/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor_base.cpp +++ b/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor_base.cpp @@ -552,6 +552,7 @@ DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::DIALOG_FOOTPRINT_BOARD_EDITOR_BASE( wxWindow // Connect Events this->Connect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::OnInitDlg ) ); this->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::OnUpdateUI ) ); + m_NoteBook->Connect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::OnPageChange ), NULL, this ); m_itemsGrid->Connect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::OnGridSize ), NULL, this ); m_bpAdd->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::OnAddField ), NULL, this ); m_bpDelete->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::OnDeleteField ), NULL, this ); @@ -578,6 +579,7 @@ DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::~DIALOG_FOOTPRINT_BOARD_EDITOR_BASE() // Disconnect Events this->Disconnect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::OnInitDlg ) ); this->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::OnUpdateUI ) ); + m_NoteBook->Disconnect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::OnPageChange ), NULL, this ); m_itemsGrid->Disconnect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::OnGridSize ), NULL, this ); m_bpAdd->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::OnAddField ), NULL, this ); m_bpDelete->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_FOOTPRINT_BOARD_EDITOR_BASE::OnDeleteField ), NULL, this ); diff --git a/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor_base.fbp b/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor_base.fbp index 6a41ecaa61..59d8077f61 100644 --- a/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor_base.fbp +++ b/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor_base.fbp @@ -117,6 +117,7 @@ + OnPageChange General diff --git a/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor_base.h b/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor_base.h index fc7a42fbc3..0b00b554ed 100644 --- a/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor_base.h +++ b/pcbnew/dialogs/dialog_edit_footprint_for_BoardEditor_base.h @@ -123,6 +123,7 @@ class DIALOG_FOOTPRINT_BOARD_EDITOR_BASE : public DIALOG_SHIM // Virtual event handlers, overide them in your derived class virtual void OnInitDlg( wxInitDialogEvent& event ) { event.Skip(); } virtual void OnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); } + virtual void OnPageChange( wxNotebookEvent& event ) { event.Skip(); } virtual void OnGridSize( wxSizeEvent& event ) { event.Skip(); } virtual void OnAddField( wxCommandEvent& event ) { event.Skip(); } virtual void OnDeleteField( wxCommandEvent& event ) { event.Skip(); } diff --git a/pcbnew/dialogs/dialog_global_edit_text_and_graphics.cpp b/pcbnew/dialogs/dialog_global_edit_text_and_graphics.cpp index fcb1ad6ed3..39c45b82f7 100644 --- a/pcbnew/dialogs/dialog_global_edit_text_and_graphics.cpp +++ b/pcbnew/dialogs/dialog_global_edit_text_and_graphics.cpp @@ -373,9 +373,9 @@ bool DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::TransferDataFromWindow() // use the dynamic_cast to move through the type tree anyway. const wxString text = dynamic_cast( boardItem )->GetText(); - if( m_references->GetValue() && text == wxT( "%R" ) ) + if( m_references->GetValue() && text == wxT( "${REFERENCE}" ) ) visitItem( commit, boardItem ); - else if( m_values->GetValue() && text == wxT( "%V" ) ) + else if( m_values->GetValue() && text == wxT( "${VALUE}" ) ) visitItem( commit, boardItem ); else if( m_otherFields->GetValue() ) visitItem( commit, boardItem ); diff --git a/pcbnew/legacy_plugin.cpp b/pcbnew/legacy_plugin.cpp index 857c64caee..dd535022c7 100644 --- a/pcbnew/legacy_plugin.cpp +++ b/pcbnew/legacy_plugin.cpp @@ -88,6 +88,7 @@ #include #include #include // for KiROUND +#include typedef LEGACY_PLUGIN::BIU BIU; @@ -1781,7 +1782,8 @@ void LEGACY_PLUGIN::loadMODULE_TEXT( TEXTE_MODULE* aText ) // convert the "quoted, escaped, UTF8, text" to a wxString, find it by skipping // as far forward as needed until the first double quote. txt_end = data + ReadDelimitedText( &m_field, data ); - + m_field.Replace( "%V", "${VALUE}" ); + m_field.Replace( "%R", "${REFERENCE}" ); aText->SetText( m_field ); // after switching to strtok, there's no easy coming back because of the diff --git a/pcbnew/pcb_edit_frame.cpp b/pcbnew/pcb_edit_frame.cpp index 207bec5840..92be2ee736 100644 --- a/pcbnew/pcb_edit_frame.cpp +++ b/pcbnew/pcb_edit_frame.cpp @@ -341,6 +341,7 @@ void PCB_EDIT_FRAME::SetBoard( BOARD* aBoard ) { PCB_BASE_EDIT_FRAME::SetBoard( aBoard ); + aBoard->SetProject( &Prj() ); aBoard->GetConnectivity()->Build( aBoard ); // reload the worksheet @@ -369,7 +370,7 @@ void PCB_EDIT_FRAME::SetPageSettings( const PAGE_INFO& aPageSettings ) // Prepare worksheet template KIGFX::WS_PROXY_VIEW_ITEM* worksheet; worksheet = new KIGFX::WS_PROXY_VIEW_ITEM( IU_PER_MILS ,&m_Pcb->GetPageSettings(), - &m_Pcb->GetTitleBlock() ); + m_Pcb->GetProject(), &m_Pcb->GetTitleBlock() ); worksheet->SetSheetName( std::string( GetScreenDesc().mb_str() ) ); BASE_SCREEN* screen = GetScreen(); diff --git a/pcbnew/pcb_parser.cpp b/pcbnew/pcb_parser.cpp index 2619974852..ff05894593 100644 --- a/pcbnew/pcb_parser.cpp +++ b/pcbnew/pcb_parser.cpp @@ -50,6 +50,7 @@ #include #include #include // for RECT_CHAMFER_POSITIONS definition +#include using namespace PCB_KEYS_T; @@ -2624,7 +2625,10 @@ TEXTE_MODULE* PCB_PARSER::parseTEXTE_MODULE() NeedSYMBOLorNUMBER(); - text->SetText( FromUTF8() ); + wxString value = FromUTF8(); + value.Replace( "%V", "${VALUE}" ); + value.Replace( "%R", "${REFERENCE}" ); + text->SetText( value ); NeedLEFT(); token = NextTok(); diff --git a/pcbnew/plot_board_layers.cpp b/pcbnew/plot_board_layers.cpp index 4383f60366..ebb5316532 100644 --- a/pcbnew/plot_board_layers.cpp +++ b/pcbnew/plot_board_layers.cpp @@ -1232,8 +1232,8 @@ PLOTTER* StartPlotBoard( BOARD *aBoard, PCB_PLOT_PARAMS *aPlotOpts, int aLayer, // Plot the frame reference if requested if( aPlotOpts->GetPlotFrameRef() ) { - PlotWorkSheet( plotter, aBoard->GetTitleBlock(), aBoard->GetPageSettings(), - 1, 1, aSheetDesc, aBoard->GetFileName() ); + PlotWorkSheet( plotter, aBoard->GetProject(), aBoard->GetTitleBlock(), + aBoard->GetPageSettings(), 1, 1, aSheetDesc, aBoard->GetFileName() ); if( aPlotOpts->GetMirror() ) initializePlotter( plotter, aBoard, aPlotOpts ); diff --git a/pcbnew/plot_brditems_plotter.cpp b/pcbnew/plot_brditems_plotter.cpp index 30b9e4b8f4..22e3bd28be 100644 --- a/pcbnew/plot_brditems_plotter.cpp +++ b/pcbnew/plot_brditems_plotter.cpp @@ -314,10 +314,10 @@ bool BRDITEMS_PLOTTER::PlotAllTextsModule( MODULE* aModule ) if( !m_layerMask[textLayer] ) continue; - if( textModule->GetText() == wxT( "%R" ) && !GetPlotReference() ) + if( textModule->GetText() == wxT( "${REFERENCE}" ) && !GetPlotReference() ) continue; - if( textModule->GetText() == wxT( "%V" ) && !GetPlotValue() ) + if( textModule->GetText() == wxT( "${VALUE}" ) && !GetPlotValue() ) continue; PlotTextModule( textModule, getColor( textLayer ) ); diff --git a/pcbnew/tools/pcbnew_control.cpp b/pcbnew/tools/pcbnew_control.cpp index 40f0859e2f..1691cb5ea5 100644 --- a/pcbnew/tools/pcbnew_control.cpp +++ b/pcbnew/tools/pcbnew_control.cpp @@ -651,9 +651,9 @@ void pasteModuleItemsToModEdit( MODULE* aClipModule, BOARD* aBoard, if( text->GetType() != TEXTE_MODULE::TEXT_is_DIVERS ) text->SetType( TEXTE_MODULE::TEXT_is_DIVERS ); - if( text->GetText() == "%V" ) + if( text->GetText() == "${VALUE}" ) text->SetText( aClipModule->GetValue() ); - else if( text->GetText() == "%R" ) + else if( text->GetText() == "${REFERENCE}" ) text->SetText( aClipModule->GetReference() ); text->SetTextAngle( aClipModule->GetOrientation() ); diff --git a/qa/eeschema/lib_field_test_utils.h b/qa/eeschema/lib_field_test_utils.h index 7bc85c2c64..1f578cd2ba 100644 --- a/qa/eeschema/lib_field_test_utils.h +++ b/qa/eeschema/lib_field_test_utils.h @@ -42,7 +42,7 @@ struct print_log_value { inline void operator()( std::ostream& os, LIB_FIELD const& f ) { - os << "LIB_FIELD[ " << f.GetName( NATIVE_FIELD_NAME ) << " ]"; + os << "LIB_FIELD[ " << f.GetCanonicalName() << " ]"; } }; @@ -68,16 +68,15 @@ namespace KI_TEST * @param aExpectedId the expected field id * @return true if match */ -bool FieldNameIdMatches( - const LIB_FIELD& aField, const std::string& aExpectedName, int aExpectedId ) +bool FieldNameIdMatches( const LIB_FIELD& aField, const std::string& aExpectedName, + int aExpectedId ) { bool ok = true; - const auto gotName = aField.GetName( false ); + const auto gotName = aField.GetCanonicalName(); if( gotName != aExpectedName ) { - BOOST_TEST_INFO( - "Field name mismatch: got '" << gotName << "', expected '" << aExpectedName ); + BOOST_TEST_INFO( "Field name: got '" << gotName << "', expected '" << aExpectedName ); ok = false; } @@ -85,7 +84,7 @@ bool FieldNameIdMatches( if( gotId != aExpectedId ) { - BOOST_TEST_INFO( "Field ID mismatch: got '" << gotId << "', expected '" << aExpectedId ); + BOOST_TEST_INFO( "Field ID: got '" << gotId << "', expected '" << aExpectedId ); ok = false; }