Add auto-completion for DRC rule function calls.
This commit is contained in:
parent
70b98c3b49
commit
86c9adbcba
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include <fctsys.h>
|
#include <fctsys.h>
|
||||||
#include <scintilla_tricks.h>
|
#include <scintilla_tricks.h>
|
||||||
|
#include <wx/stc/stc.h>
|
||||||
#include <gal/color4d.h>
|
#include <gal/color4d.h>
|
||||||
#include <dialog_shim.h>
|
#include <dialog_shim.h>
|
||||||
|
|
||||||
|
@ -190,7 +191,10 @@ void SCINTILLA_TRICKS::DoAutocomplete( const wxString& aPartial, const wxArraySt
|
||||||
{
|
{
|
||||||
// NB: tokens MUST be in alphabetical order because the Scintilla engine is going
|
// NB: tokens MUST be in alphabetical order because the Scintilla engine is going
|
||||||
// to do a binary search on them
|
// to do a binary search on them
|
||||||
matchedTokens.Sort();
|
matchedTokens.Sort( []( const wxString& first, const wxString& second ) -> int
|
||||||
|
{
|
||||||
|
return first.CmpNoCase( second );
|
||||||
|
});
|
||||||
|
|
||||||
m_te->AutoCompShow( aPartial.size(), wxJoin( matchedTokens, ' ' ) );
|
m_te->AutoCompShow( aPartial.size(), wxJoin( matchedTokens, ' ' ) );
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include <widgets/paged_dialog.h>
|
#include <widgets/paged_dialog.h>
|
||||||
#include <pcb_edit_frame.h>
|
#include <pcb_edit_frame.h>
|
||||||
|
#include <pcb_expr_evaluator.h>
|
||||||
#include <project.h>
|
#include <project.h>
|
||||||
#include <tool/tool_manager.h>
|
#include <tool/tool_manager.h>
|
||||||
#include <drc/drc.h>
|
#include <drc/drc.h>
|
||||||
|
@ -31,6 +32,7 @@
|
||||||
#include <scintilla_tricks.h>
|
#include <scintilla_tricks.h>
|
||||||
#include <drc/drc_rule_parser.h>
|
#include <drc/drc_rule_parser.h>
|
||||||
|
|
||||||
|
|
||||||
PANEL_SETUP_RULES::PANEL_SETUP_RULES( PAGED_DIALOG* aParent, PCB_EDIT_FRAME* aFrame ) :
|
PANEL_SETUP_RULES::PANEL_SETUP_RULES( PAGED_DIALOG* aParent, PCB_EDIT_FRAME* aFrame ) :
|
||||||
PANEL_SETUP_RULES_BASE( aParent->GetTreebook() ),
|
PANEL_SETUP_RULES_BASE( aParent->GetTreebook() ),
|
||||||
m_Parent( aParent ),
|
m_Parent( aParent ),
|
||||||
|
@ -46,6 +48,7 @@ PANEL_SETUP_RULES::PANEL_SETUP_RULES( PAGED_DIALOG* aParent, PCB_EDIT_FRAME* aFr
|
||||||
m_textEditor->StyleSetFont( i, fixedFont );
|
m_textEditor->StyleSetFont( i, fixedFont );
|
||||||
|
|
||||||
m_textEditor->Bind( wxEVT_STC_CHARADDED, &PANEL_SETUP_RULES::onScintillaCharAdded, this );
|
m_textEditor->Bind( wxEVT_STC_CHARADDED, &PANEL_SETUP_RULES::onScintillaCharAdded, this );
|
||||||
|
m_textEditor->Bind( wxEVT_STC_AUTOCOMP_CHAR_DELETED, &PANEL_SETUP_RULES::onScintillaCharAdded, this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -205,6 +208,11 @@ void PANEL_SETUP_RULES::onScintillaCharAdded( wxStyledTextEvent &aEvent )
|
||||||
|
|
||||||
for( const wxString& propName : propNames )
|
for( const wxString& propName : propNames )
|
||||||
tokens += " " + propName;
|
tokens += " " + propName;
|
||||||
|
|
||||||
|
PCB_EXPR_BUILTIN_FUNCTIONS& functions = PCB_EXPR_BUILTIN_FUNCTIONS::Instance();
|
||||||
|
|
||||||
|
for( const wxString& funcSig : functions.GetSignatures() )
|
||||||
|
tokens += " " + funcSig;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,91 +28,66 @@
|
||||||
#include "class_board.h"
|
#include "class_board.h"
|
||||||
#include "pcb_expr_evaluator.h"
|
#include "pcb_expr_evaluator.h"
|
||||||
|
|
||||||
class PCB_EXPR_BUILTIN_FUNCTIONS
|
|
||||||
|
|
||||||
|
static void onLayer( LIBEVAL::UCODE* aUcode, LIBEVAL::CONTEXT* aCtx, void *self )
|
||||||
{
|
{
|
||||||
public:
|
LIBEVAL::VALUE* arg = aCtx->Pop();
|
||||||
|
LIBEVAL::VALUE* result = aCtx->AllocValue();
|
||||||
|
|
||||||
using FPTR = LIBEVAL::UCODE::FUNC_PTR;
|
result->Set( 0.0 );
|
||||||
|
aCtx->Push( result );
|
||||||
|
|
||||||
PCB_EXPR_BUILTIN_FUNCTIONS();
|
if( !arg )
|
||||||
|
|
||||||
static PCB_EXPR_BUILTIN_FUNCTIONS& Instance()
|
|
||||||
{
|
{
|
||||||
static PCB_EXPR_BUILTIN_FUNCTIONS self;
|
aCtx->ReportError( _( "Missing argument to 'onLayer()'" ) );
|
||||||
return self;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string tolower( const std::string& str ) const
|
wxString layerName = arg->AsString();
|
||||||
|
PCB_LAYER_ID layer = ENUM_MAP<PCB_LAYER_ID>::Instance().ToEnum( layerName );
|
||||||
|
|
||||||
|
if( layer == UNDEFINED_LAYER )
|
||||||
{
|
{
|
||||||
std::string rv;
|
aCtx->ReportError( wxString::Format( _( "Unrecognized layer '%s' " ), layerName ) );
|
||||||
std::transform( str.begin(), str.end(), rv.begin(), ::tolower );
|
return;
|
||||||
return rv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FPTR Get( const std::string &name ) const
|
PCB_EXPR_VAR_REF* vref = static_cast<PCB_EXPR_VAR_REF*>( self );
|
||||||
{
|
BOARD_ITEM* item = vref ? vref->GetObject( aUcode ) : nullptr;
|
||||||
auto it = m_funcs.find( name );
|
|
||||||
|
|
||||||
if( it == m_funcs.end() )
|
if( item && item->IsOnLayer( layer ) )
|
||||||
return nullptr;
|
result->Set( 1.0 );
|
||||||
|
}
|
||||||
|
|
||||||
return it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
static void isPlated( LIBEVAL::UCODE* aUcode, LIBEVAL::CONTEXT* aCtx, void *self )
|
||||||
std::map<std::string, FPTR> m_funcs;
|
{
|
||||||
|
LIBEVAL::VALUE* result = aCtx->AllocValue();
|
||||||
|
|
||||||
static void onLayer( LIBEVAL::UCODE* aUcode, LIBEVAL::CONTEXT* aCtx, void *self )
|
result->Set( 0.0 );
|
||||||
{
|
aCtx->Push( result );
|
||||||
LIBEVAL::VALUE* arg = aCtx->Pop();
|
|
||||||
LIBEVAL::VALUE* result = aCtx->AllocValue();
|
|
||||||
|
|
||||||
result->Set( 0.0 );
|
PCB_EXPR_VAR_REF* vref = static_cast<PCB_EXPR_VAR_REF*>( self );
|
||||||
aCtx->Push( result );
|
BOARD_ITEM* item = vref ? vref->GetObject( aUcode ) : nullptr;
|
||||||
|
D_PAD* pad = dynamic_cast<D_PAD*>( item );
|
||||||
|
|
||||||
if( !arg )
|
if( pad && pad->GetAttribute() == PAD_ATTRIB_STANDARD )
|
||||||
{
|
result->Set( 1.0 );
|
||||||
aCtx->ReportError( _( "Missing argument to 'onLayer()'" ) );
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString layerName = arg->AsString();
|
|
||||||
PCB_LAYER_ID layer = ENUM_MAP<PCB_LAYER_ID>::Instance().ToEnum( layerName );
|
|
||||||
|
|
||||||
if( layer == UNDEFINED_LAYER )
|
|
||||||
{
|
|
||||||
aCtx->ReportError( wxString::Format( _( "Unrecognized layer '%s' " ), layerName ) );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
PCB_EXPR_VAR_REF* vref = static_cast<PCB_EXPR_VAR_REF*>( self );
|
|
||||||
BOARD_ITEM* item = vref ? vref->GetObject( aUcode ) : nullptr;
|
|
||||||
|
|
||||||
if( item && item->IsOnLayer( layer ) )
|
|
||||||
result->Set( 1.0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
static void isPlated( LIBEVAL::UCODE* aUcode, LIBEVAL::CONTEXT* aCtx, void *self )
|
|
||||||
{
|
|
||||||
LIBEVAL::VALUE* result = aCtx->AllocValue();
|
|
||||||
|
|
||||||
result->Set( 0.0 );
|
|
||||||
aCtx->Push( result );
|
|
||||||
|
|
||||||
PCB_EXPR_VAR_REF* vref = static_cast<PCB_EXPR_VAR_REF*>( self );
|
|
||||||
BOARD_ITEM* item = vref ? vref->GetObject( aUcode ) : nullptr;
|
|
||||||
D_PAD* pad = dynamic_cast<D_PAD*>( item );
|
|
||||||
|
|
||||||
if( pad && pad->GetAttribute() == PAD_ATTRIB_STANDARD )
|
|
||||||
result->Set( 1.0 );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
PCB_EXPR_BUILTIN_FUNCTIONS::PCB_EXPR_BUILTIN_FUNCTIONS()
|
PCB_EXPR_BUILTIN_FUNCTIONS::PCB_EXPR_BUILTIN_FUNCTIONS()
|
||||||
{
|
{
|
||||||
m_funcs[ "onlayer" ] = onLayer;
|
auto registerFunc = [&]( const wxString& funcSignature, FPTR funcPtr )
|
||||||
m_funcs[ "isplated" ] = isPlated;
|
{
|
||||||
|
wxString funcName = funcSignature.BeforeFirst( '(' );
|
||||||
|
m_funcs[ std::string( funcName.Lower() ) ] = std::move( funcPtr );
|
||||||
|
m_funcSigs.Add( funcSignature );
|
||||||
|
};
|
||||||
|
|
||||||
|
registerFunc( "onLayer('x')", onLayer );
|
||||||
|
registerFunc( "isPlated()", isPlated );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -41,9 +41,11 @@ class PCB_EXPR_UCODE : public LIBEVAL::UCODE
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual LIBEVAL::VAR_REF* createVarRef( LIBEVAL::COMPILER *aCompiler,
|
virtual LIBEVAL::VAR_REF* createVarRef( LIBEVAL::COMPILER *aCompiler,
|
||||||
const std::string& aVar, const std::string& aField ) override;
|
const std::string& aVar,
|
||||||
|
const std::string& aField ) override;
|
||||||
|
|
||||||
virtual FUNC_PTR createFuncCall( LIBEVAL::COMPILER* aCompiler, const std::string& name ) override;
|
virtual FUNC_PTR createFuncCall( LIBEVAL::COMPILER* aCompiler,
|
||||||
|
const std::string& name ) override;
|
||||||
|
|
||||||
void SetItems( BOARD_ITEM* a, BOARD_ITEM* b = nullptr )
|
void SetItems( BOARD_ITEM* a, BOARD_ITEM* b = nullptr )
|
||||||
{
|
{
|
||||||
|
@ -75,24 +77,16 @@ public:
|
||||||
void SetIsEnum( bool s ) { m_isEnum = s; }
|
void SetIsEnum( bool s ) { m_isEnum = s; }
|
||||||
bool IsEnum() const { return m_isEnum; }
|
bool IsEnum() const { return m_isEnum; }
|
||||||
|
|
||||||
void SetType( LIBEVAL::VAR_TYPE_T type )
|
void SetType( LIBEVAL::VAR_TYPE_T type ) { m_type = type; }
|
||||||
{
|
LIBEVAL::VAR_TYPE_T GetType() override { return m_type; }
|
||||||
m_type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddAllowedClass( TYPE_ID type_hash, PROPERTY_BASE* prop )
|
void AddAllowedClass( TYPE_ID type_hash, PROPERTY_BASE* prop )
|
||||||
{
|
{
|
||||||
m_matchingTypes[type_hash] = prop;
|
m_matchingTypes[type_hash] = prop;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual LIBEVAL::VAR_TYPE_T GetType() override
|
|
||||||
{
|
|
||||||
return m_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual LIBEVAL::VALUE GetValue( LIBEVAL::CONTEXT* aCtx, LIBEVAL::UCODE* aUcode ) override;
|
virtual LIBEVAL::VALUE GetValue( LIBEVAL::CONTEXT* aCtx, LIBEVAL::UCODE* aUcode ) override;
|
||||||
|
|
||||||
|
|
||||||
BOARD_ITEM* GetObject( LIBEVAL::UCODE* aUcode ) const;
|
BOARD_ITEM* GetObject( LIBEVAL::UCODE* aUcode ) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -103,6 +97,36 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class PCB_EXPR_BUILTIN_FUNCTIONS
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using FPTR = LIBEVAL::UCODE::FUNC_PTR;
|
||||||
|
|
||||||
|
PCB_EXPR_BUILTIN_FUNCTIONS();
|
||||||
|
|
||||||
|
static PCB_EXPR_BUILTIN_FUNCTIONS& Instance()
|
||||||
|
{
|
||||||
|
static PCB_EXPR_BUILTIN_FUNCTIONS self;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
LIBEVAL::UCODE::FUNC_PTR Get( const std::string &name )
|
||||||
|
{
|
||||||
|
return m_funcs[ name ];
|
||||||
|
}
|
||||||
|
|
||||||
|
const wxArrayString GetSignatures() const
|
||||||
|
{
|
||||||
|
return m_funcSigs;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<std::string, LIBEVAL::UCODE::FUNC_PTR> m_funcs;
|
||||||
|
|
||||||
|
wxArrayString m_funcSigs;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class PCB_EXPR_COMPILER : public LIBEVAL::COMPILER
|
class PCB_EXPR_COMPILER : public LIBEVAL::COMPILER
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Reference in New Issue