Hook up text variable auto-complete for PCBNew.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/14777
This commit is contained in:
parent
5a9ed66cfd
commit
14f004d2a5
|
@ -1003,7 +1003,7 @@ SCH_TEXT* SCH_DRAWING_TOOLS::createNewText( const VECTOR2I& aPosition, int aType
|
||||||
{
|
{
|
||||||
DIALOG_TEXT_PROPERTIES dlg( m_frame, textItem );
|
DIALOG_TEXT_PROPERTIES dlg( m_frame, textItem );
|
||||||
|
|
||||||
// Must be quasi modal for syntax help
|
// QuasiModal required for syntax help and Scintilla auto-complete
|
||||||
if( dlg.ShowQuasiModal() != wxID_OK )
|
if( dlg.ShowQuasiModal() != wxID_OK )
|
||||||
{
|
{
|
||||||
delete textItem;
|
delete textItem;
|
||||||
|
@ -1648,7 +1648,7 @@ int SCH_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
|
||||||
getViewControls()->SetAutoPan( false );
|
getViewControls()->SetAutoPan( false );
|
||||||
getViewControls()->CaptureCursor( false );
|
getViewControls()->CaptureCursor( false );
|
||||||
|
|
||||||
// Must be quasi modal for syntax help
|
// QuasiModal required for syntax help and Scintilla auto-complete
|
||||||
if( dlg.ShowQuasiModal() != wxID_OK )
|
if( dlg.ShowQuasiModal() != wxID_OK )
|
||||||
{
|
{
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
|
@ -1873,7 +1873,7 @@ int SCH_EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
DIALOG_TEXT_PROPERTIES dlg( m_frame, static_cast<SCH_ITEM*>( curr_item ) );
|
DIALOG_TEXT_PROPERTIES dlg( m_frame, static_cast<SCH_ITEM*>( curr_item ) );
|
||||||
|
|
||||||
// Must be quasi modal for syntax help
|
// QuasiModal required for syntax help and Scintilla auto-complete
|
||||||
if( dlg.ShowQuasiModal() == wxID_OK )
|
if( dlg.ShowQuasiModal() == wxID_OK )
|
||||||
{
|
{
|
||||||
m_toolMgr->PostEvent( EVENTS::SelectedItemsModified );
|
m_toolMgr->PostEvent( EVENTS::SelectedItemsModified );
|
||||||
|
|
|
@ -352,6 +352,24 @@ std::vector<PCB_MARKER*> BOARD::ResolveDRCExclusions( bool aCreateMarkers )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BOARD::GetContextualTextVars( wxArrayString* aVars ) const
|
||||||
|
{
|
||||||
|
auto add =
|
||||||
|
[&]( const wxString& aVar )
|
||||||
|
{
|
||||||
|
if( !alg::contains( *aVars, aVar ) )
|
||||||
|
aVars->push_back( aVar );
|
||||||
|
};
|
||||||
|
|
||||||
|
add( wxT( "LAYER" ) );
|
||||||
|
|
||||||
|
GetTitleBlock().GetContextualTextVars( aVars );
|
||||||
|
|
||||||
|
for( std::pair<wxString, wxString> entry : GetProject()->GetTextVars() )
|
||||||
|
add( entry.first );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool BOARD::ResolveTextVar( wxString* token, int aDepth ) const
|
bool BOARD::ResolveTextVar( wxString* token, int aDepth ) const
|
||||||
{
|
{
|
||||||
if( token->Contains( ':' ) )
|
if( token->Contains( ':' ) )
|
||||||
|
|
|
@ -339,6 +339,7 @@ public:
|
||||||
const std::map<wxString, wxString>& GetProperties() const { return m_properties; }
|
const std::map<wxString, wxString>& GetProperties() const { return m_properties; }
|
||||||
void SetProperties( const std::map<wxString, wxString>& aProps ) { m_properties = aProps; }
|
void SetProperties( const std::map<wxString, wxString>& aProps ) { m_properties = aProps; }
|
||||||
|
|
||||||
|
void GetContextualTextVars( wxArrayString* aVars ) const;
|
||||||
bool ResolveTextVar( wxString* token, int aDepth ) const;
|
bool ResolveTextVar( wxString* token, int aDepth ) const;
|
||||||
|
|
||||||
/// Visibility settings stored in board prior to 6.0, only used for loading legacy files
|
/// Visibility settings stored in board prior to 6.0, only used for loading legacy files
|
||||||
|
|
|
@ -26,17 +26,15 @@
|
||||||
#include <widgets/font_choice.h>
|
#include <widgets/font_choice.h>
|
||||||
#include <dialog_text_properties.h>
|
#include <dialog_text_properties.h>
|
||||||
#include <confirm.h>
|
#include <confirm.h>
|
||||||
#include <widgets/unit_binder.h>
|
|
||||||
#include <board_commit.h>
|
#include <board_commit.h>
|
||||||
#include <board.h>
|
#include <board.h>
|
||||||
#include <footprint.h>
|
#include <footprint.h>
|
||||||
#include <string_utils.h>
|
|
||||||
#include <pcb_text.h>
|
#include <pcb_text.h>
|
||||||
#include <pcbnew.h>
|
#include <pcbnew.h>
|
||||||
|
#include <project.h>
|
||||||
#include <pcb_edit_frame.h>
|
#include <pcb_edit_frame.h>
|
||||||
#include <pcb_layer_box_selector.h>
|
#include <pcb_layer_box_selector.h>
|
||||||
#include <wx/valnum.h>
|
#include <wx/valnum.h>
|
||||||
#include <math/util.h> // for KiROUND
|
|
||||||
#include <scintilla_tricks.h>
|
#include <scintilla_tricks.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -167,6 +165,11 @@ DIALOG_TEXT_PROPERTIES::DIALOG_TEXT_PROPERTIES( PCB_BASE_EDIT_FRAME* aParent, PC
|
||||||
Connect( wxEVT_CHAR_HOOK, wxKeyEventHandler( DIALOG_TEXT_PROPERTIES::OnCharHook ),
|
Connect( wxEVT_CHAR_HOOK, wxKeyEventHandler( DIALOG_TEXT_PROPERTIES::OnCharHook ),
|
||||||
nullptr, this );
|
nullptr, this );
|
||||||
|
|
||||||
|
m_MultiLineText->Bind( wxEVT_STC_CHARADDED,
|
||||||
|
&DIALOG_TEXT_PROPERTIES::onScintillaCharAdded, this );
|
||||||
|
m_MultiLineText->Bind( wxEVT_STC_AUTOCOMP_CHAR_DELETED,
|
||||||
|
&DIALOG_TEXT_PROPERTIES::onScintillaCharAdded, this );
|
||||||
|
|
||||||
finishDialogSettings();
|
finishDialogSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,6 +212,62 @@ void DIALOG_TEXT_PROPERTIES::OnSetFocusText( wxFocusEvent& event )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DIALOG_TEXT_PROPERTIES::onScintillaCharAdded( wxStyledTextEvent &aEvent )
|
||||||
|
{
|
||||||
|
wxStyledTextCtrl* te = m_MultiLineText;
|
||||||
|
wxArrayString autocompleteTokens;
|
||||||
|
int text_pos = te->GetCurrentPos();
|
||||||
|
int start = te->WordStartPosition( text_pos, true );
|
||||||
|
wxString partial;
|
||||||
|
|
||||||
|
auto textVarRef =
|
||||||
|
[&]( int pos )
|
||||||
|
{
|
||||||
|
return pos >= 2 && te->GetCharAt( pos-2 ) == '$' && te->GetCharAt( pos-1 ) == '{';
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check for cross-reference
|
||||||
|
if( start > 1 && te->GetCharAt( start-1 ) == ':' )
|
||||||
|
{
|
||||||
|
int refStart = te->WordStartPosition( start-1, true );
|
||||||
|
|
||||||
|
if( textVarRef( refStart ) )
|
||||||
|
{
|
||||||
|
partial = te->GetRange( start, text_pos );
|
||||||
|
|
||||||
|
wxString ref = te->GetRange( refStart, start-1 );
|
||||||
|
BOARD* board = m_item->GetBoard();
|
||||||
|
|
||||||
|
for( FOOTPRINT* candidate : board->Footprints() )
|
||||||
|
{
|
||||||
|
if( candidate->GetReference() == ref )
|
||||||
|
{
|
||||||
|
candidate->GetContextualTextVars( &autocompleteTokens );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( textVarRef( start ) )
|
||||||
|
{
|
||||||
|
partial = te->GetTextRange( start, text_pos );
|
||||||
|
|
||||||
|
BOARD* board = m_item->GetBoard();
|
||||||
|
|
||||||
|
board->GetContextualTextVars( &autocompleteTokens );
|
||||||
|
|
||||||
|
if( FOOTPRINT* footprint = m_item->GetParentFootprint() )
|
||||||
|
footprint->GetContextualTextVars( &autocompleteTokens );
|
||||||
|
|
||||||
|
for( std::pair<wxString, wxString> entry : board->GetProject()->GetTextVars() )
|
||||||
|
autocompleteTokens.push_back( entry.first );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_scintillaTricks->DoAutocomplete( partial, autocompleteTokens );
|
||||||
|
m_MultiLineText->SetFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool DIALOG_TEXT_PROPERTIES::TransferDataToWindow()
|
bool DIALOG_TEXT_PROPERTIES::TransferDataToWindow()
|
||||||
{
|
{
|
||||||
BOARD* board = m_frame->GetBoard();
|
BOARD* board = m_frame->GetBoard();
|
||||||
|
|
|
@ -56,6 +56,7 @@ private:
|
||||||
void onAlignButton( wxCommandEvent &aEvent ) override;
|
void onAlignButton( wxCommandEvent &aEvent ) override;
|
||||||
void onValignButton( wxCommandEvent &aEvent ) override;
|
void onValignButton( wxCommandEvent &aEvent ) override;
|
||||||
void onThickness( wxCommandEvent &aEvent ) override;
|
void onThickness( wxCommandEvent &aEvent ) override;
|
||||||
|
void onScintillaCharAdded( wxStyledTextEvent &aEvent );
|
||||||
|
|
||||||
bool TransferDataToWindow() override;
|
bool TransferDataToWindow() override;
|
||||||
bool TransferDataFromWindow() override;
|
bool TransferDataFromWindow() override;
|
||||||
|
|
|
@ -25,19 +25,16 @@
|
||||||
#include <widgets/font_choice.h>
|
#include <widgets/font_choice.h>
|
||||||
#include <dialog_textbox_properties.h>
|
#include <dialog_textbox_properties.h>
|
||||||
#include <confirm.h>
|
#include <confirm.h>
|
||||||
#include <widgets/unit_binder.h>
|
|
||||||
#include <board_commit.h>
|
#include <board_commit.h>
|
||||||
#include <board_design_settings.h>
|
#include <board_design_settings.h>
|
||||||
#include <board.h>
|
#include <board.h>
|
||||||
#include <footprint.h>
|
#include <footprint.h>
|
||||||
#include <string_utils.h>
|
|
||||||
#include <pcb_textbox.h>
|
#include <pcb_textbox.h>
|
||||||
#include <pcbnew.h>
|
#include <pcbnew.h>
|
||||||
|
#include <project.h>
|
||||||
#include <pcb_edit_frame.h>
|
#include <pcb_edit_frame.h>
|
||||||
#include <pcb_layer_box_selector.h>
|
#include <pcb_layer_box_selector.h>
|
||||||
#include <math/util.h> // for KiROUND
|
|
||||||
#include <scintilla_tricks.h>
|
#include <scintilla_tricks.h>
|
||||||
#include "macros.h"
|
|
||||||
|
|
||||||
DIALOG_TEXTBOX_PROPERTIES::DIALOG_TEXTBOX_PROPERTIES( PCB_BASE_EDIT_FRAME* aParent,
|
DIALOG_TEXTBOX_PROPERTIES::DIALOG_TEXTBOX_PROPERTIES( PCB_BASE_EDIT_FRAME* aParent,
|
||||||
PCB_TEXTBOX* aTextBox ) :
|
PCB_TEXTBOX* aTextBox ) :
|
||||||
|
@ -125,6 +122,11 @@ DIALOG_TEXTBOX_PROPERTIES::DIALOG_TEXTBOX_PROPERTIES( PCB_BASE_EDIT_FRAME* aPare
|
||||||
Connect( wxEVT_CHAR_HOOK, wxKeyEventHandler( DIALOG_TEXTBOX_PROPERTIES::OnCharHook ),
|
Connect( wxEVT_CHAR_HOOK, wxKeyEventHandler( DIALOG_TEXTBOX_PROPERTIES::OnCharHook ),
|
||||||
nullptr, this );
|
nullptr, this );
|
||||||
|
|
||||||
|
m_MultiLineText->Bind( wxEVT_STC_CHARADDED,
|
||||||
|
&DIALOG_TEXTBOX_PROPERTIES::onScintillaCharAdded, this );
|
||||||
|
m_MultiLineText->Bind( wxEVT_STC_AUTOCOMP_CHAR_DELETED,
|
||||||
|
&DIALOG_TEXTBOX_PROPERTIES::onScintillaCharAdded, this );
|
||||||
|
|
||||||
finishDialogSettings();
|
finishDialogSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,10 +143,68 @@ DIALOG_TEXTBOX_PROPERTIES::~DIALOG_TEXTBOX_PROPERTIES()
|
||||||
int PCB_BASE_EDIT_FRAME::ShowTextBoxPropertiesDialog( PCB_TEXTBOX* aTextBox )
|
int PCB_BASE_EDIT_FRAME::ShowTextBoxPropertiesDialog( PCB_TEXTBOX* aTextBox )
|
||||||
{
|
{
|
||||||
DIALOG_TEXTBOX_PROPERTIES dlg( this, aTextBox );
|
DIALOG_TEXTBOX_PROPERTIES dlg( this, aTextBox );
|
||||||
|
|
||||||
|
// QuasiModal required for Scintilla auto-complete
|
||||||
return dlg.ShowQuasiModal();
|
return dlg.ShowQuasiModal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DIALOG_TEXTBOX_PROPERTIES::onScintillaCharAdded( wxStyledTextEvent &aEvent )
|
||||||
|
{
|
||||||
|
wxStyledTextCtrl* te = m_MultiLineText;
|
||||||
|
wxArrayString autocompleteTokens;
|
||||||
|
int text_pos = te->GetCurrentPos();
|
||||||
|
int start = te->WordStartPosition( text_pos, true );
|
||||||
|
wxString partial;
|
||||||
|
|
||||||
|
auto textVarRef =
|
||||||
|
[&]( int pos )
|
||||||
|
{
|
||||||
|
return pos >= 2 && te->GetCharAt( pos-2 ) == '$' && te->GetCharAt( pos-1 ) == '{';
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check for cross-reference
|
||||||
|
if( start > 1 && te->GetCharAt( start-1 ) == ':' )
|
||||||
|
{
|
||||||
|
int refStart = te->WordStartPosition( start-1, true );
|
||||||
|
|
||||||
|
if( textVarRef( refStart ) )
|
||||||
|
{
|
||||||
|
partial = te->GetRange( start, text_pos );
|
||||||
|
|
||||||
|
wxString ref = te->GetRange( refStart, start-1 );
|
||||||
|
BOARD* board = m_textBox->GetBoard();
|
||||||
|
|
||||||
|
for( FOOTPRINT* candidate : board->Footprints() )
|
||||||
|
{
|
||||||
|
if( candidate->GetReference() == ref )
|
||||||
|
{
|
||||||
|
candidate->GetContextualTextVars( &autocompleteTokens );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( textVarRef( start ) )
|
||||||
|
{
|
||||||
|
partial = te->GetTextRange( start, text_pos );
|
||||||
|
|
||||||
|
BOARD* board = m_textBox->GetBoard();
|
||||||
|
|
||||||
|
board->GetContextualTextVars( &autocompleteTokens );
|
||||||
|
|
||||||
|
if( FOOTPRINT* footprint = m_textBox->GetParentFootprint() )
|
||||||
|
footprint->GetContextualTextVars( &autocompleteTokens );
|
||||||
|
|
||||||
|
for( std::pair<wxString, wxString> entry : board->GetProject()->GetTextVars() )
|
||||||
|
autocompleteTokens.push_back( entry.first );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_scintillaTricks->DoAutocomplete( partial, autocompleteTokens );
|
||||||
|
m_MultiLineText->SetFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool DIALOG_TEXTBOX_PROPERTIES::TransferDataToWindow()
|
bool DIALOG_TEXTBOX_PROPERTIES::TransferDataToWindow()
|
||||||
{
|
{
|
||||||
BOARD* board = m_frame->GetBoard();
|
BOARD* board = m_frame->GetBoard();
|
||||||
|
|
|
@ -47,6 +47,7 @@ private:
|
||||||
void onAlignButton( wxCommandEvent &aEvent ) override;
|
void onAlignButton( wxCommandEvent &aEvent ) override;
|
||||||
void onThickness( wxCommandEvent &aEvent ) override;
|
void onThickness( wxCommandEvent &aEvent ) override;
|
||||||
void onBorderChecked( wxCommandEvent& event ) override;
|
void onBorderChecked( wxCommandEvent& event ) override;
|
||||||
|
void onScintillaCharAdded( wxStyledTextEvent &aEvent );
|
||||||
|
|
||||||
bool TransferDataToWindow() override;
|
bool TransferDataToWindow() override;
|
||||||
bool TransferDataFromWindow() override;
|
bool TransferDataFromWindow() override;
|
||||||
|
|
|
@ -888,7 +888,8 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
RunMainStack( [&]()
|
RunMainStack( [&]()
|
||||||
{
|
{
|
||||||
cancelled = !textDialog.ShowModal();
|
// QuasiModal required for Scintilla auto-complete
|
||||||
|
cancelled = !textDialog.ShowQuasiModal();
|
||||||
} );
|
} );
|
||||||
|
|
||||||
if( cancelled || NoPrintableChars( text->GetText() ) )
|
if( cancelled || NoPrintableChars( text->GetText() ) )
|
||||||
|
|
Loading…
Reference in New Issue