Autocomplete for text variables.
Fixes https://gitlab.com/kicad/code/kicad/issues/4190
This commit is contained in:
parent
f3e4e61fa7
commit
8b084c373e
|
@ -331,6 +331,7 @@ set( COMMON_SRCS
|
|||
render_settings.cpp
|
||||
reporter.cpp
|
||||
richio.cpp
|
||||
scintilla_tricks.cpp
|
||||
search_stack.cpp
|
||||
searchhelpfilefullpath.cpp
|
||||
status_popup.cpp
|
||||
|
|
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2020 KiCad Developers, see change_log.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 <fctsys.h>
|
||||
#include <scintilla_tricks.h>
|
||||
#include <gal/color4d.h>
|
||||
#include <dialog_shim.h>
|
||||
|
||||
SCINTILLA_TRICKS::SCINTILLA_TRICKS( wxStyledTextCtrl* aScintilla, const wxString& aBraces ) :
|
||||
m_te( aScintilla ),
|
||||
m_braces( aBraces ),
|
||||
m_lastCaretPos( -1 )
|
||||
{
|
||||
// A hack which causes Scintilla to auto-size the text editor canvas
|
||||
// See: https://github.com/jacobslusser/ScintillaNET/issues/216
|
||||
m_te->SetScrollWidth( 1 );
|
||||
m_te->SetScrollWidthTracking( true );
|
||||
|
||||
// Set up the brace highlighting
|
||||
wxColour highlight = wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT );
|
||||
wxColour highlightText = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT );
|
||||
|
||||
if( KIGFX::COLOR4D( highlightText ).GetBrightness() > 0.5 )
|
||||
highlight = highlight.ChangeLightness( 80 );
|
||||
else
|
||||
highlight = highlight.ChangeLightness( 120 );
|
||||
|
||||
m_te->StyleSetForeground( wxSTC_STYLE_BRACELIGHT, highlightText );
|
||||
m_te->StyleSetBackground( wxSTC_STYLE_BRACELIGHT, highlight );
|
||||
m_te->StyleSetForeground( wxSTC_STYLE_BRACEBAD, *wxRED );
|
||||
|
||||
// Hook up events
|
||||
m_te->Bind( wxEVT_STC_UPDATEUI, &SCINTILLA_TRICKS::onScintillaUpdateUI, this );
|
||||
|
||||
// Dispatch command-keys in Scintilla control.
|
||||
m_te->Bind( wxEVT_CHAR_HOOK, &SCINTILLA_TRICKS::onCharHook, this );
|
||||
}
|
||||
|
||||
|
||||
bool IsCtrl( int aChar, const wxKeyEvent& e )
|
||||
{
|
||||
return e.GetKeyCode() == aChar && e.ControlDown() && !e.AltDown() &&
|
||||
!e.ShiftDown() && !e.MetaDown();
|
||||
}
|
||||
|
||||
|
||||
bool IsShiftCtrl( int aChar, const wxKeyEvent& e )
|
||||
{
|
||||
return e.GetKeyCode() == aChar && e.ControlDown() && !e.AltDown() &&
|
||||
e.ShiftDown() && !e.MetaDown();
|
||||
}
|
||||
|
||||
|
||||
void SCINTILLA_TRICKS::onCharHook( wxKeyEvent& aEvent )
|
||||
{
|
||||
if( aEvent.GetKeyCode() == WXK_TAB )
|
||||
{
|
||||
if( aEvent.ControlDown() )
|
||||
{
|
||||
int flags = 0;
|
||||
|
||||
if( !aEvent.ShiftDown() )
|
||||
flags |= wxNavigationKeyEvent::IsForward;
|
||||
|
||||
wxWindow* parent = m_te->GetParent();
|
||||
|
||||
while( parent && dynamic_cast<DIALOG_SHIM*>( parent ) == nullptr )
|
||||
parent = parent->GetParent();
|
||||
|
||||
if( parent )
|
||||
parent->NavigateIn( flags );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_te->Tab();
|
||||
}
|
||||
}
|
||||
else if( m_te->IsShown() && IsCtrl( 'Z', aEvent ) )
|
||||
{
|
||||
m_te->Undo();
|
||||
}
|
||||
else if( m_te->IsShown() && ( IsShiftCtrl( 'Z', aEvent ) || IsCtrl( 'Y', aEvent ) ) )
|
||||
{
|
||||
m_te->Redo();
|
||||
}
|
||||
else if( IsCtrl( 'X', aEvent ) )
|
||||
{
|
||||
m_te->Cut();
|
||||
}
|
||||
else if( IsCtrl( 'C', aEvent ) )
|
||||
{
|
||||
m_te->Copy();
|
||||
}
|
||||
else if( IsCtrl( 'V', aEvent ) )
|
||||
{
|
||||
m_te->Paste();
|
||||
}
|
||||
else
|
||||
{
|
||||
aEvent.Skip();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SCINTILLA_TRICKS::onScintillaUpdateUI( wxStyledTextEvent& aEvent )
|
||||
{
|
||||
auto isBrace = [this]( int c ) -> bool
|
||||
{
|
||||
return m_braces.Find( (char) c ) >= 0;
|
||||
};
|
||||
|
||||
// Has the caret changed position?
|
||||
int caretPos = m_te->GetCurrentPos();
|
||||
|
||||
if( m_lastCaretPos != caretPos )
|
||||
{
|
||||
m_lastCaretPos = caretPos;
|
||||
int bracePos1 = -1;
|
||||
int bracePos2 = -1;
|
||||
|
||||
// Is there a brace to the left or right?
|
||||
if( caretPos > 0 && isBrace( m_te->GetCharAt( caretPos-1 ) ) )
|
||||
bracePos1 = ( caretPos - 1 );
|
||||
else if( isBrace( m_te->GetCharAt( caretPos ) ) )
|
||||
bracePos1 = caretPos;
|
||||
|
||||
if( bracePos1 >= 0 )
|
||||
{
|
||||
// Find the matching brace
|
||||
bracePos2 = m_te->BraceMatch( bracePos1 );
|
||||
|
||||
if( bracePos2 == -1 )
|
||||
{
|
||||
m_te->BraceBadLight( bracePos1 );
|
||||
m_te->SetHighlightGuide( 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_te->BraceHighlight( bracePos1, bracePos2 );
|
||||
m_te->SetHighlightGuide( m_te->GetColumn( bracePos1 ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Turn off brace matching
|
||||
m_te->BraceHighlight( -1, -1 );
|
||||
m_te->SetHighlightGuide( 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SCINTILLA_TRICKS::DoAutocomplete( const wxString& aPartial, wxArrayString aTokens )
|
||||
{
|
||||
if( aTokens.size() > 0 )
|
||||
{
|
||||
bool match = aPartial.IsEmpty();
|
||||
|
||||
for( size_t ii = 0; ii < aTokens.size() && !match; ++ii )
|
||||
match = aTokens[ii].StartsWith( aPartial );
|
||||
|
||||
if( match )
|
||||
{
|
||||
// NB: tokens MUST be in alphabetical order because the Scintilla engine is going
|
||||
// to do a binary search on them
|
||||
aTokens.Sort();
|
||||
|
||||
m_te->AutoCompShow( aPartial.size(), wxJoin( aTokens, ' ' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
|
||||
* Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -38,6 +38,7 @@
|
|||
#include <dialog_edit_label.h>
|
||||
#include <kicad_string.h>
|
||||
#include <tool/actions.h>
|
||||
#include <scintilla_tricks.h>
|
||||
|
||||
class SCH_EDIT_FRAME;
|
||||
class SCH_TEXT;
|
||||
|
@ -51,7 +52,8 @@ const int MAX_TEXTSIZE = INT_MAX;
|
|||
DIALOG_LABEL_EDITOR::DIALOG_LABEL_EDITOR( SCH_EDIT_FRAME* aParent, SCH_TEXT* aTextItem ) :
|
||||
DIALOG_LABEL_EDITOR_BASE( aParent ),
|
||||
m_textSize( aParent, m_textSizeLabel, m_textSizeCtrl, m_textSizeUnits, false ),
|
||||
m_netNameValidator( true )
|
||||
m_netNameValidator( true ),
|
||||
m_scintillaTricks( nullptr )
|
||||
{
|
||||
m_Parent = aParent;
|
||||
m_CurrentText = aTextItem;
|
||||
|
@ -67,10 +69,7 @@ DIALOG_LABEL_EDITOR::DIALOG_LABEL_EDITOR( SCH_EDIT_FRAME* aParent, SCH_TEXT* aTe
|
|||
|
||||
m_valueMultiLine->SetEOLMode( wxSTC_EOL_LF );
|
||||
|
||||
// A hack which causes Scintilla to auto-size the text editor canvas
|
||||
// See: https://github.com/jacobslusser/ScintillaNET/issues/216
|
||||
m_valueMultiLine->SetScrollWidth( 1 );
|
||||
m_valueMultiLine->SetScrollWidthTracking( true );
|
||||
m_scintillaTricks = new SCINTILLA_TRICKS( m_valueMultiLine, "()" );
|
||||
|
||||
if( m_CurrentText->IsMultilineAllowed() )
|
||||
{
|
||||
|
@ -131,9 +130,7 @@ DIALOG_LABEL_EDITOR::DIALOG_LABEL_EDITOR( SCH_EDIT_FRAME* aParent, SCH_TEXT* aTe
|
|||
m_sdbSizer1OK->SetDefault();
|
||||
Layout();
|
||||
|
||||
// wxTextCtrls fail to generate wxEVT_CHAR events when the wxTE_MULTILINE flag is set,
|
||||
// so we have to listen to wxEVT_CHAR_HOOK events instead.
|
||||
m_valueMultiLine->Connect( wxEVT_CHAR_HOOK, wxKeyEventHandler( DIALOG_LABEL_EDITOR::OnCharHook ), nullptr, this );
|
||||
m_valueMultiLine->Bind( wxEVT_STC_CHARADDED, &DIALOG_LABEL_EDITOR::onScintillaCharAdded, this );
|
||||
|
||||
// DIALOG_SHIM needs a unique hash_key because classname is not sufficient because the
|
||||
// various versions have different controls so we want to store sizes for each version.
|
||||
|
@ -147,7 +144,7 @@ DIALOG_LABEL_EDITOR::DIALOG_LABEL_EDITOR( SCH_EDIT_FRAME* aParent, SCH_TEXT* aTe
|
|||
|
||||
DIALOG_LABEL_EDITOR::~DIALOG_LABEL_EDITOR()
|
||||
{
|
||||
m_valueMultiLine->Disconnect( wxEVT_CHAR_HOOK, wxKeyEventHandler( DIALOG_LABEL_EDITOR::OnCharHook ), nullptr, this );
|
||||
delete m_scintillaTricks;
|
||||
}
|
||||
|
||||
|
||||
|
@ -332,51 +329,61 @@ void DIALOG_LABEL_EDITOR::OnEnterKey( wxCommandEvent& aEvent )
|
|||
}
|
||||
|
||||
|
||||
/*!
|
||||
* wxEVT_CHAR_HOOK event handler for multi-line control
|
||||
*/
|
||||
void DIALOG_LABEL_EDITOR::OnCharHook( wxKeyEvent& aEvt )
|
||||
void DIALOG_LABEL_EDITOR::onScintillaCharAdded( wxStyledTextEvent &aEvent )
|
||||
{
|
||||
if( aEvt.GetKeyCode() == WXK_TAB )
|
||||
wxStyledTextCtrl* te = m_valueMultiLine;
|
||||
wxArrayString autocompleteTokens;
|
||||
int pos = te->GetCurrentPos();
|
||||
int start = te->WordStartPosition( 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 ) == ':' )
|
||||
{
|
||||
if( aEvt.ControlDown() )
|
||||
{
|
||||
int flags = 0;
|
||||
int refStart = te->WordStartPosition( start-1, true );
|
||||
|
||||
if( !aEvt.ShiftDown() )
|
||||
flags |= wxNavigationKeyEvent::IsForward;
|
||||
|
||||
NavigateIn( flags );
|
||||
}
|
||||
else
|
||||
if( textVarRef( refStart ) )
|
||||
{
|
||||
m_valueMultiLine->Tab();
|
||||
partial = te->GetRange( start+1, pos );
|
||||
|
||||
wxString ref = te->GetRange( refStart, start-1 );
|
||||
SCH_SHEET_LIST sheets = m_Parent->Schematic().GetSheets();
|
||||
SCH_REFERENCE_LIST refs;
|
||||
SCH_COMPONENT* refComponent = nullptr;
|
||||
|
||||
sheets.GetComponents( refs );
|
||||
|
||||
for( size_t jj = 0; jj < refs.GetCount(); jj++ )
|
||||
{
|
||||
if( refs[ jj ].GetComp()->GetRef( &refs[ jj ].GetSheetPath(), true ) == ref )
|
||||
{
|
||||
refComponent = refs[ jj ].GetComp();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( refComponent )
|
||||
refComponent->GetContextualTextVars( &autocompleteTokens );
|
||||
}
|
||||
}
|
||||
else if( m_valueMultiLine->IsShown() && IsCtrl( 'Z', aEvt ) )
|
||||
else if( textVarRef( start ) )
|
||||
{
|
||||
m_valueMultiLine->Undo();
|
||||
}
|
||||
else if( m_valueMultiLine->IsShown() && ( IsShiftCtrl( 'Z', aEvt ) || IsCtrl( 'Y', aEvt ) ) )
|
||||
{
|
||||
m_valueMultiLine->Redo();
|
||||
}
|
||||
else if( IsCtrl( 'X', aEvt ) )
|
||||
{
|
||||
m_valueMultiLine->Cut();
|
||||
}
|
||||
else if( IsCtrl( 'C', aEvt ) )
|
||||
{
|
||||
m_valueMultiLine->Copy();
|
||||
}
|
||||
else if( IsCtrl( 'V', aEvt ) )
|
||||
{
|
||||
m_valueMultiLine->Paste();
|
||||
}
|
||||
else
|
||||
{
|
||||
aEvt.Skip();
|
||||
partial = te->GetTextRange( start, pos );
|
||||
|
||||
m_CurrentText->GetContextualTextVars( &autocompleteTokens );
|
||||
|
||||
for( std::pair<wxString, wxString> entry : Prj().GetTextVars() )
|
||||
autocompleteTokens.push_back( entry.first );
|
||||
}
|
||||
|
||||
m_scintillaTricks->DoAutocomplete( partial, autocompleteTokens );
|
||||
m_valueMultiLine->SetFocus();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
class SCH_EDIT_FRAME;
|
||||
class SCH_TEXT;
|
||||
class SCINTILLA_TRICKS;
|
||||
|
||||
|
||||
class DIALOG_LABEL_EDITOR : public DIALOG_LABEL_EDITOR_BASE
|
||||
|
@ -62,8 +63,9 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
void onScintillaCharAdded( wxStyledTextEvent &aEvent );
|
||||
|
||||
void OnEnterKey( wxCommandEvent& aEvent ) override;
|
||||
void OnCharHook( wxKeyEvent& aEvent );
|
||||
void OnFormattingHelp( wxHyperlinkEvent& aEvent ) override;
|
||||
|
||||
bool TransferDataToWindow() override;
|
||||
|
@ -79,6 +81,7 @@ private:
|
|||
wxTextEntry* m_activeTextEntry;
|
||||
UNIT_BINDER m_textSize;
|
||||
SCH_NETNAME_VALIDATOR m_netNameValidator;
|
||||
SCINTILLA_TRICKS* m_scintillaTricks;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@gipsa-lab.inpg.com
|
||||
* Copyright (C) 2016 Wayne Stambaugh, stambaughw@gmail.com
|
||||
* Copyright (C) 2004-2018 KiCad Developers, see change_log.txt for contributors.
|
||||
* Copyright (C) 2004-2020 KiCad Developers, see change_log.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
|
||||
|
@ -37,16 +37,18 @@
|
|||
#include <template_fieldnames.h>
|
||||
#include <class_library.h>
|
||||
#include <sch_validators.h>
|
||||
|
||||
#include <schematic.h>
|
||||
#include <dialog_edit_one_field.h>
|
||||
#include <sch_text.h>
|
||||
#include <scintilla_tricks.h>
|
||||
|
||||
DIALOG_EDIT_ONE_FIELD::DIALOG_EDIT_ONE_FIELD( SCH_BASE_FRAME* aParent, const wxString& aTitle,
|
||||
const EDA_TEXT* aTextItem ) :
|
||||
DIALOG_LIB_EDIT_TEXT_BASE( aParent ),
|
||||
m_posX( aParent, m_xPosLabel, m_xPosCtrl, m_xPosUnits, true ),
|
||||
m_posY( aParent, m_yPosLabel, m_yPosCtrl, m_yPosUnits, true ),
|
||||
m_textSize( aParent, m_textSizeLabel, m_textSizeCtrl, m_textSizeUnits, true )
|
||||
m_textSize( aParent, m_textSizeLabel, m_textSizeCtrl, m_textSizeUnits, true ),
|
||||
m_scintillaTricks( nullptr )
|
||||
{
|
||||
wxASSERT( aTextItem );
|
||||
|
||||
|
@ -56,6 +58,8 @@ DIALOG_EDIT_ONE_FIELD::DIALOG_EDIT_ONE_FIELD( SCH_BASE_FRAME* aParent, const wxS
|
|||
m_fieldId = VALUE;
|
||||
m_isPower = false;
|
||||
|
||||
m_scintillaTricks = new SCINTILLA_TRICKS( m_StyledTextCtrl, "{}" );
|
||||
|
||||
m_text = aTextItem->GetText();
|
||||
m_isItalic = aTextItem->IsItalic();
|
||||
m_isBold = aTextItem->IsBold();
|
||||
|
@ -68,17 +72,33 @@ DIALOG_EDIT_ONE_FIELD::DIALOG_EDIT_ONE_FIELD( SCH_BASE_FRAME* aParent, const wxS
|
|||
}
|
||||
|
||||
|
||||
DIALOG_EDIT_ONE_FIELD::~DIALOG_EDIT_ONE_FIELD()
|
||||
{
|
||||
delete m_scintillaTricks;
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_EDIT_ONE_FIELD::init()
|
||||
{
|
||||
SetInitialFocus( m_TextValue );
|
||||
SCH_BASE_FRAME* parent = GetParent();
|
||||
bool libedit = parent->IsType( FRAME_SCH_LIB_EDITOR );
|
||||
m_TextValue->SetValidator( SCH_FIELD_VALIDATOR( libedit, m_fieldId, &m_text ) );
|
||||
m_TextCtrl->SetValidator( SCH_FIELD_VALIDATOR( libedit, m_fieldId, &m_text ) );
|
||||
|
||||
// Disable options for graphic text editing which are not needed for fields.
|
||||
m_CommonConvert->Show( false );
|
||||
m_CommonUnit->Show( false );
|
||||
|
||||
if( !libedit && ( m_fieldId == REFERENCE || m_fieldId == VALUE ) )
|
||||
{
|
||||
m_StyledTextCtrl->Show( false );
|
||||
SetInitialFocus( m_TextCtrl );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_TextCtrl->Show( false );
|
||||
SetInitialFocus( m_StyledTextCtrl );
|
||||
}
|
||||
|
||||
// Show the footprint selection dialog if this is the footprint field.
|
||||
m_TextValueSelectButton->Show( m_fieldId == FOOTPRINT );
|
||||
|
||||
|
@ -87,16 +107,28 @@ void DIALOG_EDIT_ONE_FIELD::init()
|
|||
if( m_fieldId == VALUE && m_isPower )
|
||||
{
|
||||
m_PowerComponentValues->Show( true );
|
||||
m_TextValue->Enable( false );
|
||||
m_TextCtrl->Enable( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_PowerComponentValues->Show( false );
|
||||
m_TextValue->Enable( true );
|
||||
m_TextCtrl->Enable( true );
|
||||
}
|
||||
|
||||
m_sdbSizerButtonsOK->SetDefault();
|
||||
|
||||
GetSizer()->SetSizeHints( this );
|
||||
|
||||
// Adjust the height of the scintilla text editor after the first layout
|
||||
if( m_StyledTextCtrl->IsShown() )
|
||||
{
|
||||
wxSize maxSize = m_StyledTextCtrl->GetSize();
|
||||
maxSize.y = m_xPosCtrl->GetSize().y;
|
||||
m_StyledTextCtrl->SetMaxSize( maxSize );
|
||||
m_StyledTextCtrl->SetUseVerticalScrollBar( false );
|
||||
m_StyledTextCtrl->SetUseHorizontalScrollBar( false );
|
||||
}
|
||||
|
||||
// Now all widgets have the size fixed, call FinishDialogSettings
|
||||
FinishDialogSettings();
|
||||
}
|
||||
|
@ -105,13 +137,13 @@ void DIALOG_EDIT_ONE_FIELD::init()
|
|||
void DIALOG_EDIT_ONE_FIELD::OnTextValueSelectButtonClick( wxCommandEvent& aEvent )
|
||||
{
|
||||
// pick a footprint using the footprint picker.
|
||||
wxString fpid = m_TextValue->GetValue();
|
||||
wxString fpid = m_TextCtrl->GetValue();
|
||||
|
||||
KIWAY_PLAYER* frame = Kiway().Player( FRAME_FOOTPRINT_VIEWER_MODAL, true );
|
||||
|
||||
if( frame->ShowModal( &fpid, this ) )
|
||||
{
|
||||
m_TextValue->SetValue( fpid );
|
||||
m_TextCtrl->SetValue( fpid );
|
||||
}
|
||||
|
||||
frame->Destroy();
|
||||
|
@ -127,13 +159,14 @@ void DIALOG_EDIT_ONE_FIELD::OnSetFocusText( wxFocusEvent& event )
|
|||
// Note that we can't do this on OSX as it tends to provoke Apple's
|
||||
// "[NSAlert runModal] may not be invoked inside of transaction begin/commit pair"
|
||||
// bug. See: https://bugs.launchpad.net/kicad/+bug/1837225
|
||||
m_TextValue->Update();
|
||||
if( m_fieldId == REFERENCE || m_fieldId == VALUE )
|
||||
m_TextCtrl->Update();
|
||||
#endif
|
||||
|
||||
if( m_fieldId == REFERENCE )
|
||||
SelectReferenceNumber( static_cast<wxTextEntry*>( m_TextValue ) );
|
||||
else
|
||||
m_TextValue->SetSelection( -1, -1 );
|
||||
SelectReferenceNumber( static_cast<wxTextEntry*>( m_TextCtrl ) );
|
||||
else if( m_fieldId == VALUE )
|
||||
m_TextCtrl->SetSelection( -1, -1 );
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
@ -141,7 +174,10 @@ void DIALOG_EDIT_ONE_FIELD::OnSetFocusText( wxFocusEvent& event )
|
|||
|
||||
bool DIALOG_EDIT_ONE_FIELD::TransferDataToWindow()
|
||||
{
|
||||
m_TextValue->SetValue( m_text );
|
||||
if( m_TextCtrl->IsShown() )
|
||||
m_TextCtrl->SetValue( m_text );
|
||||
else if( m_StyledTextCtrl->IsShown() )
|
||||
m_StyledTextCtrl->SetValue( m_text );
|
||||
|
||||
m_posX.SetValue( m_position.x );
|
||||
m_posY.SetValue( m_position.y );
|
||||
|
@ -159,7 +195,10 @@ bool DIALOG_EDIT_ONE_FIELD::TransferDataToWindow()
|
|||
|
||||
bool DIALOG_EDIT_ONE_FIELD::TransferDataFromWindow()
|
||||
{
|
||||
m_text = m_TextValue->GetValue();
|
||||
if( m_TextCtrl->IsShown() )
|
||||
m_text = m_TextCtrl->GetValue();
|
||||
else if( m_StyledTextCtrl->IsShown() )
|
||||
m_text = m_StyledTextCtrl->GetValue();
|
||||
|
||||
if( m_fieldId == REFERENCE )
|
||||
{
|
||||
|
@ -205,9 +244,10 @@ void DIALOG_EDIT_ONE_FIELD::updateText( EDA_TEXT* aText )
|
|||
}
|
||||
|
||||
|
||||
DIALOG_LIB_EDIT_ONE_FIELD::DIALOG_LIB_EDIT_ONE_FIELD(
|
||||
SCH_BASE_FRAME* aParent, const wxString& aTitle, const LIB_FIELD* aField )
|
||||
: DIALOG_EDIT_ONE_FIELD( aParent, aTitle, aField )
|
||||
DIALOG_LIB_EDIT_ONE_FIELD::DIALOG_LIB_EDIT_ONE_FIELD( SCH_BASE_FRAME* aParent,
|
||||
const wxString& aTitle,
|
||||
const LIB_FIELD* aField ) :
|
||||
DIALOG_EDIT_ONE_FIELD( aParent, aTitle, aField )
|
||||
{
|
||||
m_fieldId = aField->GetId();
|
||||
|
||||
|
@ -220,7 +260,8 @@ DIALOG_LIB_EDIT_ONE_FIELD::DIALOG_LIB_EDIT_ONE_FIELD(
|
|||
DIALOG_SCH_EDIT_ONE_FIELD::DIALOG_SCH_EDIT_ONE_FIELD( SCH_BASE_FRAME* aParent,
|
||||
const wxString& aTitle,
|
||||
const SCH_FIELD* aField ) :
|
||||
DIALOG_EDIT_ONE_FIELD( aParent, aTitle, aField )
|
||||
DIALOG_EDIT_ONE_FIELD( aParent, aTitle, aField ),
|
||||
m_field( aField )
|
||||
{
|
||||
m_fieldId = aField->GetId();
|
||||
m_isPower = false;
|
||||
|
@ -238,10 +279,78 @@ DIALOG_SCH_EDIT_ONE_FIELD::DIALOG_SCH_EDIT_ONE_FIELD( SCH_BASE_FRAME* aParent,
|
|||
m_isPower = true;
|
||||
}
|
||||
|
||||
m_StyledTextCtrl->Bind( wxEVT_STC_CHARADDED, &DIALOG_SCH_EDIT_ONE_FIELD::onScintillaCharAdded, this );
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_SCH_EDIT_ONE_FIELD::onScintillaCharAdded( wxStyledTextEvent &aEvent )
|
||||
{
|
||||
SCH_EDIT_FRAME* editFrame = dynamic_cast<SCH_EDIT_FRAME*>( GetParent() );
|
||||
wxArrayString autocompleteTokens;
|
||||
int pos = m_StyledTextCtrl->GetCurrentPos();
|
||||
int start = m_StyledTextCtrl->WordStartPosition( pos, true );
|
||||
wxString partial;
|
||||
|
||||
auto textVarRef =
|
||||
[&]( int pos )
|
||||
{
|
||||
return pos >= 2
|
||||
&& m_StyledTextCtrl->GetCharAt( pos-2 ) == '$'
|
||||
&& m_StyledTextCtrl->GetCharAt( pos-1 ) == '{';
|
||||
};
|
||||
|
||||
// Check for cross-reference
|
||||
if( start > 1 && m_StyledTextCtrl->GetCharAt( start-1 ) == ':' )
|
||||
{
|
||||
int refStart = m_StyledTextCtrl->WordStartPosition( start-1, true );
|
||||
|
||||
if( textVarRef( refStart ) )
|
||||
{
|
||||
partial = m_StyledTextCtrl->GetRange( start, pos );
|
||||
|
||||
wxString ref = m_StyledTextCtrl->GetRange( refStart, start-1 );
|
||||
SCH_SHEET_LIST sheets = editFrame->Schematic().GetSheets();
|
||||
SCH_REFERENCE_LIST refs;
|
||||
SCH_COMPONENT* refComponent = nullptr;
|
||||
|
||||
sheets.GetComponents( refs );
|
||||
|
||||
for( size_t jj = 0; jj < refs.GetCount(); jj++ )
|
||||
{
|
||||
if( refs[ jj ].GetComp()->GetRef( &refs[ jj ].GetSheetPath(), true ) == ref )
|
||||
{
|
||||
refComponent = refs[ jj ].GetComp();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( refComponent )
|
||||
refComponent->GetContextualTextVars( &autocompleteTokens );
|
||||
}
|
||||
}
|
||||
else if( textVarRef( start ) )
|
||||
{
|
||||
partial = m_StyledTextCtrl->GetTextRange( start, pos );
|
||||
|
||||
SCH_COMPONENT* comp = dynamic_cast<SCH_COMPONENT*>( m_field->GetParent() );
|
||||
SCH_SHEET* sheet = dynamic_cast<SCH_SHEET*>( m_field->GetParent() );
|
||||
|
||||
if( comp )
|
||||
comp->GetContextualTextVars( &autocompleteTokens );
|
||||
else if( sheet )
|
||||
sheet->GetContextualTextVars( &autocompleteTokens );
|
||||
|
||||
for( std::pair<wxString, wxString> entry : Prj().GetTextVars() )
|
||||
autocompleteTokens.push_back( entry.first );
|
||||
}
|
||||
|
||||
m_scintillaTricks->DoAutocomplete( partial, autocompleteTokens );
|
||||
m_StyledTextCtrl->SetFocus();
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_SCH_EDIT_ONE_FIELD::UpdateField( SCH_FIELD* aField, SCH_SHEET_PATH* aSheetPath )
|
||||
{
|
||||
SCH_EDIT_FRAME* editFrame = dynamic_cast<SCH_EDIT_FRAME*>( GetParent() );
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
* Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@gipsa-lab.inpg.com
|
||||
* Copyright (C) 2016 Wayne Stambaugh, stambaughw@gmail.com
|
||||
* Copyright (C) 2004-2016 KiCad Developers, see change_log.txt for contributors.
|
||||
* Copyright (C) 2004-2020 KiCad Developers, see change_log.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
|
||||
|
@ -36,6 +36,7 @@
|
|||
class SCH_BASE_FRAME;
|
||||
class SCH_FIELD;
|
||||
class EDA_TEXT;
|
||||
class SCINTILLA_TRICKS;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -53,7 +54,7 @@ public:
|
|||
DIALOG_EDIT_ONE_FIELD( SCH_BASE_FRAME* aParent, const wxString& aTitle,
|
||||
const EDA_TEXT* aTextItem );
|
||||
|
||||
~DIALOG_EDIT_ONE_FIELD() override {}
|
||||
~DIALOG_EDIT_ONE_FIELD() override;
|
||||
|
||||
bool TransferDataToWindow() override;
|
||||
bool TransferDataFromWindow() override;
|
||||
|
@ -63,7 +64,6 @@ public:
|
|||
const wxString& GetText() const { return m_text; }
|
||||
|
||||
protected:
|
||||
|
||||
void init();
|
||||
|
||||
void updateText( EDA_TEXT* aText );
|
||||
|
@ -101,6 +101,8 @@ protected:
|
|||
int m_verticalJustification;
|
||||
int m_horizontalJustification;
|
||||
bool m_isVisible;
|
||||
|
||||
SCINTILLA_TRICKS* m_scintillaTricks;
|
||||
};
|
||||
|
||||
|
||||
|
@ -147,7 +149,12 @@ public:
|
|||
|
||||
~DIALOG_SCH_EDIT_ONE_FIELD() {}
|
||||
|
||||
void onScintillaCharAdded( wxStyledTextEvent &aEvent );
|
||||
|
||||
void UpdateField( SCH_FIELD* aField, SCH_SHEET_PATH* aSheetPath );
|
||||
|
||||
private:
|
||||
const SCH_FIELD* m_field;
|
||||
};
|
||||
|
||||
#endif // DIALOG_EDIT_ONE_FIELD_H_
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2001 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
|
||||
* Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
|
||||
* Copyright (C) 2004-2020 KiCad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -23,9 +23,7 @@
|
|||
*/
|
||||
|
||||
#include <fctsys.h>
|
||||
#include <sch_draw_panel.h>
|
||||
#include <lib_edit_frame.h>
|
||||
#include <class_libentry.h>
|
||||
#include <lib_text.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <dialog_lib_edit_text.h>
|
||||
|
@ -52,7 +50,8 @@ DIALOG_LIB_EDIT_TEXT::DIALOG_LIB_EDIT_TEXT( LIB_EDIT_FRAME* aParent, LIB_TEXT* a
|
|||
infoFont.SetSymbolicSize( wxFONTSIZE_SMALL );
|
||||
m_PowerComponentValues->SetFont( infoFont );
|
||||
|
||||
SetInitialFocus( m_TextValue );
|
||||
SetInitialFocus( m_TextCtrl );
|
||||
m_StyledTextCtrl->Show( false );
|
||||
|
||||
m_sdbSizerButtonsOK->SetDefault();
|
||||
|
||||
|
@ -68,7 +67,7 @@ bool DIALOG_LIB_EDIT_TEXT::TransferDataToWindow()
|
|||
m_posX.SetValue( m_graphicText->GetPosition().x );
|
||||
m_posY.SetValue( m_graphicText->GetPosition().y );
|
||||
m_textSize.SetValue( m_graphicText->GetTextWidth() );
|
||||
m_TextValue->SetValue( m_graphicText->GetText() );
|
||||
m_TextCtrl->SetValue( m_graphicText->GetText() );
|
||||
|
||||
m_italic->SetValue( m_graphicText->IsItalic() );
|
||||
m_bold->SetValue( m_graphicText->IsBold() );
|
||||
|
@ -110,10 +109,10 @@ bool DIALOG_LIB_EDIT_TEXT::TransferDataFromWindow()
|
|||
{
|
||||
if( m_graphicText )
|
||||
{
|
||||
if( m_TextValue->GetValue().IsEmpty() )
|
||||
if( m_TextCtrl->GetValue().IsEmpty() )
|
||||
m_graphicText->SetText( wxT( "[null]" ) );
|
||||
else
|
||||
m_graphicText->SetText( m_TextValue->GetValue() );
|
||||
m_graphicText->SetText( m_TextCtrl->GetValue() );
|
||||
|
||||
m_graphicText->SetPosition( wxPoint( m_posX.GetValue(), m_posY.GetValue() ) );
|
||||
m_graphicText->SetTextSize( wxSize( m_textSize.GetValue(), m_textSize.GetValue() ) );
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Jul 11 2018)
|
||||
// C++ code generated with wxFormBuilder (version Oct 26 2018)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
|
@ -29,10 +29,39 @@ DIALOG_LIB_EDIT_TEXT_BASE::DIALOG_LIB_EDIT_TEXT_BASE( wxWindow* parent, wxWindow
|
|||
m_staticText1->Wrap( -1 );
|
||||
bTextValueBoxSizer->Add( m_staticText1, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
m_TextValue = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_TextValue->SetMinSize( wxSize( 200,-1 ) );
|
||||
m_TextCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
bTextValueBoxSizer->Add( m_TextCtrl, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
bTextValueBoxSizer->Add( m_TextValue, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
|
||||
m_StyledTextCtrl = new wxStyledTextCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_SUNKEN, wxEmptyString );
|
||||
m_StyledTextCtrl->SetUseTabs( true );
|
||||
m_StyledTextCtrl->SetTabWidth( 4 );
|
||||
m_StyledTextCtrl->SetIndent( 4 );
|
||||
m_StyledTextCtrl->SetTabIndents( false );
|
||||
m_StyledTextCtrl->SetBackSpaceUnIndents( false );
|
||||
m_StyledTextCtrl->SetViewEOL( false );
|
||||
m_StyledTextCtrl->SetViewWhiteSpace( false );
|
||||
m_StyledTextCtrl->SetMarginWidth( 2, 0 );
|
||||
m_StyledTextCtrl->SetIndentationGuides( false );
|
||||
m_StyledTextCtrl->SetMarginWidth( 1, 0 );
|
||||
m_StyledTextCtrl->SetMarginWidth( 0, 0 );
|
||||
m_StyledTextCtrl->MarkerDefine( wxSTC_MARKNUM_FOLDER, wxSTC_MARK_BOXPLUS );
|
||||
m_StyledTextCtrl->MarkerSetBackground( wxSTC_MARKNUM_FOLDER, wxColour( wxT("BLACK") ) );
|
||||
m_StyledTextCtrl->MarkerSetForeground( wxSTC_MARKNUM_FOLDER, wxColour( wxT("WHITE") ) );
|
||||
m_StyledTextCtrl->MarkerDefine( wxSTC_MARKNUM_FOLDEROPEN, wxSTC_MARK_BOXMINUS );
|
||||
m_StyledTextCtrl->MarkerSetBackground( wxSTC_MARKNUM_FOLDEROPEN, wxColour( wxT("BLACK") ) );
|
||||
m_StyledTextCtrl->MarkerSetForeground( wxSTC_MARKNUM_FOLDEROPEN, wxColour( wxT("WHITE") ) );
|
||||
m_StyledTextCtrl->MarkerDefine( wxSTC_MARKNUM_FOLDERSUB, wxSTC_MARK_EMPTY );
|
||||
m_StyledTextCtrl->MarkerDefine( wxSTC_MARKNUM_FOLDEREND, wxSTC_MARK_BOXPLUS );
|
||||
m_StyledTextCtrl->MarkerSetBackground( wxSTC_MARKNUM_FOLDEREND, wxColour( wxT("BLACK") ) );
|
||||
m_StyledTextCtrl->MarkerSetForeground( wxSTC_MARKNUM_FOLDEREND, wxColour( wxT("WHITE") ) );
|
||||
m_StyledTextCtrl->MarkerDefine( wxSTC_MARKNUM_FOLDEROPENMID, wxSTC_MARK_BOXMINUS );
|
||||
m_StyledTextCtrl->MarkerSetBackground( wxSTC_MARKNUM_FOLDEROPENMID, wxColour( wxT("BLACK") ) );
|
||||
m_StyledTextCtrl->MarkerSetForeground( wxSTC_MARKNUM_FOLDEROPENMID, wxColour( wxT("WHITE") ) );
|
||||
m_StyledTextCtrl->MarkerDefine( wxSTC_MARKNUM_FOLDERMIDTAIL, wxSTC_MARK_EMPTY );
|
||||
m_StyledTextCtrl->MarkerDefine( wxSTC_MARKNUM_FOLDERTAIL, wxSTC_MARK_EMPTY );
|
||||
m_StyledTextCtrl->SetSelBackground( true, wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
|
||||
m_StyledTextCtrl->SetSelForeground( true, wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHTTEXT ) );
|
||||
bTextValueBoxSizer->Add( m_StyledTextCtrl, 1, wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
m_PowerComponentValues = new wxStaticText( this, wxID_ANY, _("(Power symbol value field text cannot be changed.)"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_PowerComponentValues->Wrap( -1 );
|
||||
|
@ -68,7 +97,7 @@ DIALOG_LIB_EDIT_TEXT_BASE::DIALOG_LIB_EDIT_TEXT_BASE( wxWindow* parent, wxWindow
|
|||
fgSizer3->Add( m_xPosLabel, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
m_xPosCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizer3->Add( m_xPosCtrl, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
fgSizer3->Add( m_xPosCtrl, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxEXPAND, 5 );
|
||||
|
||||
m_xPosUnits = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_xPosUnits->Wrap( -1 );
|
||||
|
@ -98,7 +127,7 @@ DIALOG_LIB_EDIT_TEXT_BASE::DIALOG_LIB_EDIT_TEXT_BASE( wxWindow* parent, wxWindow
|
|||
fgSizer3->Add( m_yPosLabel, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
m_yPosCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizer3->Add( m_yPosCtrl, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
fgSizer3->Add( m_yPosCtrl, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxEXPAND, 5 );
|
||||
|
||||
m_yPosUnits = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_yPosUnits->Wrap( -1 );
|
||||
|
@ -128,7 +157,7 @@ DIALOG_LIB_EDIT_TEXT_BASE::DIALOG_LIB_EDIT_TEXT_BASE( wxWindow* parent, wxWindow
|
|||
fgSizer3->Add( m_textSizeLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
m_textSizeCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
fgSizer3->Add( m_textSizeCtrl, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
fgSizer3->Add( m_textSizeCtrl, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
|
||||
|
||||
m_textSizeUnits = new wxStaticText( this, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_textSizeUnits->Wrap( -1 );
|
||||
|
@ -190,7 +219,8 @@ DIALOG_LIB_EDIT_TEXT_BASE::DIALOG_LIB_EDIT_TEXT_BASE( wxWindow* parent, wxWindow
|
|||
|
||||
// Connect Events
|
||||
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_LIB_EDIT_TEXT_BASE::OnCloseDialog ) );
|
||||
m_TextValue->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( DIALOG_LIB_EDIT_TEXT_BASE::OnSetFocusText ), NULL, this );
|
||||
m_TextCtrl->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( DIALOG_LIB_EDIT_TEXT_BASE::OnSetFocusText ), NULL, this );
|
||||
m_StyledTextCtrl->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( DIALOG_LIB_EDIT_TEXT_BASE::OnSetFocusText ), NULL, this );
|
||||
m_TextValueSelectButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_EDIT_TEXT_BASE::OnTextValueSelectButtonClick ), NULL, this );
|
||||
}
|
||||
|
||||
|
@ -198,7 +228,8 @@ DIALOG_LIB_EDIT_TEXT_BASE::~DIALOG_LIB_EDIT_TEXT_BASE()
|
|||
{
|
||||
// Disconnect Events
|
||||
this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_LIB_EDIT_TEXT_BASE::OnCloseDialog ) );
|
||||
m_TextValue->Disconnect( wxEVT_SET_FOCUS, wxFocusEventHandler( DIALOG_LIB_EDIT_TEXT_BASE::OnSetFocusText ), NULL, this );
|
||||
m_TextCtrl->Disconnect( wxEVT_SET_FOCUS, wxFocusEventHandler( DIALOG_LIB_EDIT_TEXT_BASE::OnSetFocusText ), NULL, this );
|
||||
m_StyledTextCtrl->Disconnect( wxEVT_SET_FOCUS, wxFocusEventHandler( DIALOG_LIB_EDIT_TEXT_BASE::OnSetFocusText ), NULL, this );
|
||||
m_TextValueSelectButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_EDIT_TEXT_BASE::OnTextValueSelectButtonClick ), NULL, this );
|
||||
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,12 +1,11 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Jul 11 2018)
|
||||
// C++ code generated with wxFormBuilder (version Oct 26 2018)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __DIALOG_LIB_EDIT_TEXT_BASE_H__
|
||||
#define __DIALOG_LIB_EDIT_TEXT_BASE_H__
|
||||
#pragma once
|
||||
|
||||
#include <wx/artprov.h>
|
||||
#include <wx/xrc/xmlres.h>
|
||||
|
@ -19,6 +18,7 @@
|
|||
#include <wx/colour.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/stc/stc.h>
|
||||
#include <wx/bitmap.h>
|
||||
#include <wx/image.h>
|
||||
#include <wx/icon.h>
|
||||
|
@ -40,7 +40,8 @@ class DIALOG_LIB_EDIT_TEXT_BASE : public DIALOG_SHIM
|
|||
|
||||
protected:
|
||||
wxStaticText* m_staticText1;
|
||||
wxTextCtrl* m_TextValue;
|
||||
wxTextCtrl* m_TextCtrl;
|
||||
wxStyledTextCtrl* m_StyledTextCtrl;
|
||||
wxStaticText* m_PowerComponentValues;
|
||||
wxButton* m_TextValueSelectButton;
|
||||
wxCheckBox* m_visible;
|
||||
|
@ -81,4 +82,3 @@ class DIALOG_LIB_EDIT_TEXT_BASE : public DIALOG_SHIM
|
|||
|
||||
};
|
||||
|
||||
#endif //__DIALOG_LIB_EDIT_TEXT_BASE_H__
|
||||
|
|
|
@ -782,6 +782,17 @@ void SCH_COMPONENT::SwapData( SCH_ITEM* aItem )
|
|||
}
|
||||
|
||||
|
||||
void SCH_COMPONENT::GetContextualTextVars( wxArrayString* aVars ) const
|
||||
{
|
||||
for( int i = 0; i < MANDATORY_FIELDS; ++i )
|
||||
aVars->push_back( m_Fields[i].GetCanonicalName() );
|
||||
|
||||
aVars->push_back( wxT( "FOOTPRINT_LIBRARY" ) );
|
||||
aVars->push_back( wxT( "FOOTPRINT_NAME" ) );
|
||||
aVars->push_back( wxT( "UNIT" ) );
|
||||
}
|
||||
|
||||
|
||||
bool SCH_COMPONENT::ResolveTextVar( wxString* token, int aDepth ) const
|
||||
{
|
||||
for( int i = 0; i < MANDATORY_FIELDS; ++i )
|
||||
|
|
|
@ -325,6 +325,11 @@ public:
|
|||
*/
|
||||
int GetOrientation();
|
||||
|
||||
/**
|
||||
* Return the list of system text vars & fields for this symbol.
|
||||
*/
|
||||
void GetContextualTextVars( wxArrayString* aVars ) const;
|
||||
|
||||
/**
|
||||
* Resolve any references to system tokens supported by the component.
|
||||
* @param aDepth a counter to limit recursion and circular references.
|
||||
|
|
|
@ -187,6 +187,16 @@ bool SCH_SHEET::IsRootSheet() const
|
|||
}
|
||||
|
||||
|
||||
void SCH_SHEET::GetContextualTextVars( wxArrayString* aVars ) const
|
||||
{
|
||||
for( int i = 0; i < SHEET_MANDATORY_FIELDS; ++i )
|
||||
aVars->push_back( m_fields[i].GetCanonicalName() );
|
||||
|
||||
aVars->push_back( wxT( "#" ) );
|
||||
aVars->push_back( wxT( "##" ) );
|
||||
}
|
||||
|
||||
|
||||
bool SCH_SHEET::ResolveTextVar( wxString* token, int aDepth ) const
|
||||
{
|
||||
for( int i = 0; i < SHEET_MANDATORY_FIELDS; ++i )
|
||||
|
|
|
@ -330,6 +330,11 @@ public:
|
|||
*/
|
||||
int GetScreenCount() const;
|
||||
|
||||
/**
|
||||
* Return the list of system text vars & fields for this sheet.
|
||||
*/
|
||||
void GetContextualTextVars( wxArrayString* aVars ) const;
|
||||
|
||||
/**
|
||||
* Resolve any references to system tokens supported by the sheet.
|
||||
* @param aDepth a counter to limit recursion and circular references.
|
||||
|
|
|
@ -474,6 +474,16 @@ wxString getElectricalTypeLabel( PINSHEETLABEL_SHAPE aType )
|
|||
}
|
||||
|
||||
|
||||
void SCH_TEXT::GetContextualTextVars( wxArrayString* aVars ) const
|
||||
{
|
||||
if( Type() == SCH_GLOBAL_LABEL_T || Type() == SCH_HIER_LABEL_T || Type() == SCH_SHEET_PIN_T )
|
||||
aVars->push_back( wxT( "CONNECTION_TYPE" ) );
|
||||
|
||||
if( Type() == SCH_SHEET_PIN_T && m_Parent )
|
||||
static_cast<SCH_SHEET*>( m_Parent )->GetContextualTextVars( aVars );
|
||||
}
|
||||
|
||||
|
||||
wxString SCH_TEXT::GetShownText( int aDepth ) const
|
||||
{
|
||||
std::function<bool( wxString* )> textResolver =
|
||||
|
|
|
@ -207,6 +207,12 @@ public:
|
|||
return wxT( "SCH_TEXT" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of contextual text variable tokens for this text item.
|
||||
* @param aVars [out]
|
||||
*/
|
||||
void GetContextualTextVars( wxArrayString* aVars ) const;
|
||||
|
||||
wxString GetShownText( int aDepth = 0 ) const override;
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2020 KiCad Developers, see change_log.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 SCINTILLA_TRICKS_H
|
||||
#define SCINTILLA_TRICKS_H
|
||||
|
||||
|
||||
#include <wx/stc/stc.h>
|
||||
|
||||
/**
|
||||
* SCINTILLA_TRICKS
|
||||
* is used to add cut/copy/paste, autocomplete and brace highlighting to a wxStyleTextCtrl
|
||||
* instance.
|
||||
*/
|
||||
class SCINTILLA_TRICKS : public wxEvtHandler
|
||||
{
|
||||
public:
|
||||
|
||||
SCINTILLA_TRICKS( wxStyledTextCtrl* aScintilla, const wxString& aBraces );
|
||||
|
||||
void DoAutocomplete( const wxString& aPartial, wxArrayString aTokens );
|
||||
|
||||
protected:
|
||||
void onCharHook( wxKeyEvent& aEvent );
|
||||
void onScintillaUpdateUI( wxStyledTextEvent& aEvent );
|
||||
|
||||
protected:
|
||||
wxStyledTextCtrl* m_te;
|
||||
wxString m_braces;
|
||||
|
||||
int m_lastCaretPos;
|
||||
};
|
||||
|
||||
#endif // SCINTILLA_TRICKS_H
|
|
@ -257,6 +257,14 @@ MODULE& MODULE::operator=( const MODULE& aOther )
|
|||
}
|
||||
|
||||
|
||||
void MODULE::GetContextualTextVars( wxArrayString* aVars ) const
|
||||
{
|
||||
aVars->push_back( wxT( "REFERENCE" ) );
|
||||
aVars->push_back( wxT( "VALUE" ) );
|
||||
aVars->push_back( wxT( "LAYER" ) );
|
||||
}
|
||||
|
||||
|
||||
bool MODULE::ResolveTextVar( wxString* token, int aDepth ) const
|
||||
{
|
||||
if( token->IsSameAs( wxT( "REFERENCE" ) ) )
|
||||
|
|
|
@ -397,6 +397,11 @@ public:
|
|||
aError, true, false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of system text vars for this footprint.
|
||||
*/
|
||||
void GetContextualTextVars( wxArrayString* aVars ) const;
|
||||
|
||||
/**
|
||||
* Resolve any references to system tokens supported by the component.
|
||||
* @param aDepth a counter to limit recursion and circular references.
|
||||
|
|
|
@ -28,25 +28,14 @@
|
|||
#include <drc/drc.h>
|
||||
#include <panel_setup_rules.h>
|
||||
#include <html_messagebox.h>
|
||||
#include <scintilla_tricks.h>
|
||||
|
||||
PANEL_SETUP_RULES::PANEL_SETUP_RULES( PAGED_DIALOG* aParent, PCB_EDIT_FRAME* aFrame ) :
|
||||
PANEL_SETUP_RULES_BASE( aParent->GetTreebook() ),
|
||||
m_frame( aFrame ),
|
||||
m_lastCaretPos( -1 )
|
||||
m_scintillaTricks( nullptr )
|
||||
{
|
||||
m_textEditor->SetIndentationGuides( wxSTC_IV_LOOKBOTH );
|
||||
|
||||
wxColour highlight = wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT );
|
||||
wxColour highlightText = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT );
|
||||
|
||||
if( KIGFX::COLOR4D( highlightText ).GetBrightness() > 0.5 )
|
||||
highlight = highlight.ChangeLightness( 75 );
|
||||
else
|
||||
highlight = highlight.ChangeLightness( 125 );
|
||||
|
||||
m_textEditor->StyleSetForeground( wxSTC_STYLE_BRACELIGHT, highlightText );
|
||||
m_textEditor->StyleSetBackground( wxSTC_STYLE_BRACELIGHT, highlight );
|
||||
m_textEditor->StyleSetForeground( wxSTC_STYLE_BRACEBAD, *wxRED );
|
||||
m_scintillaTricks = new SCINTILLA_TRICKS( m_textEditor, "{}" );
|
||||
|
||||
int size = wxNORMAL_FONT->GetPointSize();
|
||||
wxFont fixedFont( size, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL );
|
||||
|
@ -55,10 +44,15 @@ PANEL_SETUP_RULES::PANEL_SETUP_RULES( PAGED_DIALOG* aParent, PCB_EDIT_FRAME* aFr
|
|||
m_textEditor->StyleSetFont( i, fixedFont );
|
||||
|
||||
m_textEditor->Bind( wxEVT_STC_CHARADDED, &PANEL_SETUP_RULES::onScintillaCharAdded, this );
|
||||
m_textEditor->Bind( wxEVT_STC_UPDATEUI, &PANEL_SETUP_RULES::onScintillaUpdateUI, this );
|
||||
}
|
||||
|
||||
|
||||
PANEL_SETUP_RULES::~PANEL_SETUP_RULES( )
|
||||
{
|
||||
delete m_scintillaTricks;
|
||||
};
|
||||
|
||||
|
||||
void PANEL_SETUP_RULES::onScintillaCharAdded( wxStyledTextEvent &aEvent )
|
||||
{
|
||||
constexpr int flags = wxSTC_FIND_REGEXP| wxSTC_FIND_POSIX;
|
||||
|
@ -145,20 +139,6 @@ void PANEL_SETUP_RULES::onScintillaCharAdded( wxStyledTextEvent &aEvent )
|
|||
}
|
||||
}
|
||||
|
||||
auto autocomplete = [this]( const wxString& aPartial, const wxString& aTokenStr )
|
||||
{
|
||||
wxArrayString tokens = wxSplit( aTokenStr, ' ' );
|
||||
bool match = aPartial.IsEmpty();
|
||||
|
||||
for( size_t ii = 0; ii < tokens.size() && !match; ++ii )
|
||||
match = tokens[ii].StartsWith( aPartial );
|
||||
|
||||
if( match )
|
||||
m_textEditor->AutoCompShow( aPartial.size(), aTokenStr );
|
||||
};
|
||||
|
||||
// NB: tokens MUST be in alphabetical order because the Scintilla engine is going
|
||||
// to do a binary search on them
|
||||
wxString tokens;
|
||||
|
||||
if( context == SEXPR_OPEN )
|
||||
|
@ -171,7 +151,7 @@ void PANEL_SETUP_RULES::onScintillaCharAdded( wxStyledTextEvent &aEvent )
|
|||
tokens = "max min opt";
|
||||
|
||||
if( !tokens.IsEmpty() )
|
||||
autocomplete( partial, tokens );
|
||||
m_scintillaTricks->DoAutocomplete( partial, wxSplit( tokens, ' ' ) );
|
||||
}
|
||||
else if( context == SEXPR_TOKEN )
|
||||
{
|
||||
|
@ -181,55 +161,7 @@ void PANEL_SETUP_RULES::onScintillaCharAdded( wxStyledTextEvent &aEvent )
|
|||
tokens = "buried_via graphic hole micro_via pad text track via zone";
|
||||
|
||||
if( !tokens.IsEmpty() )
|
||||
autocomplete( partial, tokens );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PANEL_SETUP_RULES::onScintillaUpdateUI( wxStyledTextEvent& aEvent )
|
||||
{
|
||||
auto isBrace = []( int c ) -> bool
|
||||
{
|
||||
return c == '(' || c == ')';
|
||||
};
|
||||
|
||||
// Has the caret changed position?
|
||||
int caretPos = m_textEditor->GetCurrentPos();
|
||||
|
||||
if( m_lastCaretPos != caretPos )
|
||||
{
|
||||
m_lastCaretPos = caretPos;
|
||||
int bracePos1 = -1;
|
||||
int bracePos2 = -1;
|
||||
|
||||
// Is there a brace to the left or right?
|
||||
if( caretPos > 0 && isBrace( m_textEditor->GetCharAt( caretPos-1 ) ) )
|
||||
bracePos1 = ( caretPos - 1 );
|
||||
else if( isBrace( m_textEditor->GetCharAt( caretPos ) ) )
|
||||
bracePos1 = caretPos;
|
||||
|
||||
if( bracePos1 >= 0 )
|
||||
{
|
||||
// Find the matching brace
|
||||
bracePos2 = m_textEditor->BraceMatch( bracePos1 );
|
||||
|
||||
if( bracePos2 == -1 )
|
||||
{
|
||||
m_textEditor->BraceBadLight( bracePos1 );
|
||||
m_textEditor->SetHighlightGuide( 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_textEditor->BraceHighlight( bracePos1, bracePos2 );
|
||||
m_textEditor->SetHighlightGuide( m_textEditor->GetColumn( bracePos1 ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Turn off brace matching
|
||||
m_textEditor->BraceHighlight( -1, -1 );
|
||||
m_textEditor->SetHighlightGuide( 0 );
|
||||
}
|
||||
m_scintillaTricks->DoAutocomplete( partial, wxSplit( tokens, ' ' ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,21 +30,21 @@
|
|||
class DRC;
|
||||
class PAGED_DIALOG;
|
||||
class PCB_EDIT_FRAME;
|
||||
class SCINTILLA_TRICKS;
|
||||
|
||||
|
||||
class PANEL_SETUP_RULES : public PANEL_SETUP_RULES_BASE
|
||||
{
|
||||
private:
|
||||
PCB_EDIT_FRAME* m_frame;
|
||||
int m_lastCaretPos;
|
||||
PCB_EDIT_FRAME* m_frame;
|
||||
SCINTILLA_TRICKS* m_scintillaTricks;
|
||||
|
||||
public:
|
||||
PANEL_SETUP_RULES( PAGED_DIALOG* aParent, PCB_EDIT_FRAME* aFrame );
|
||||
~PANEL_SETUP_RULES( ) override { };
|
||||
~PANEL_SETUP_RULES( ) override;
|
||||
|
||||
private:
|
||||
void onScintillaCharAdded( wxStyledTextEvent &aEvent );
|
||||
void onScintillaUpdateUI( wxStyledTextEvent& aEvent );
|
||||
|
||||
void OnSyntaxHelp( wxHyperlinkEvent& aEvent ) override;
|
||||
|
||||
|
|
Loading…
Reference in New Issue