Try to fix bug 639683 : Illegal reference strings are now detected and replaced by default prefix for old schematics or rejected in schematic edition.

This commit is contained in:
jean-pierre charras 2011-05-31 18:29:14 +02:00
parent bb6f5625bd
commit 9092dd0aec
6 changed files with 94 additions and 12 deletions

View File

@ -225,6 +225,12 @@ void DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::OnOKButtonClick( wxCommandEvent& event
if( !copyPanelToSelectedField() ) if( !copyPanelToSelectedField() )
return; return;
if( ! SCH_COMPONENT::IsReferenceStringValid( m_FieldsBuf[REFERENCE].m_Text ) )
{
DisplayError( NULL, _( "Illegal reference. A reference must start by a letter" ) );
return;
}
// save old cmp in undo list if not already in edit, or moving ... // save old cmp in undo list if not already in edit, or moving ...
if( m_Cmp->m_Flags == 0 ) if( m_Cmp->m_Flags == 0 )
m_Parent->SaveCopyInUndoList( m_Cmp, UR_CHANGED ); m_Parent->SaveCopyInUndoList( m_Cmp, UR_CHANGED );

View File

@ -16,6 +16,7 @@
#include "protos.h" #include "protos.h"
#include "libeditframe.h" #include "libeditframe.h"
#include "class_library.h" #include "class_library.h"
#include "sch_component.h"
#include "sch_field.h" #include "sch_field.h"
#include "template_fieldnames.h" #include "template_fieldnames.h"
#include "dialog_helpers.h" #include "dialog_helpers.h"
@ -221,6 +222,13 @@ void DIALOG_EDIT_LIBENTRY_FIELDS_IN_LIB::OnOKButtonClick( wxCommandEvent& event
if( !copyPanelToSelectedField() ) if( !copyPanelToSelectedField() )
return; return;
// test if reference prefix is acceptable
if( ! SCH_COMPONENT::IsReferenceStringValid( m_FieldsBuf[REFERENCE].m_Text ) )
{
DisplayError( NULL, _( "Illegal reference prefix. A reference must start by a letter" ) );
return;
}
/* Note: this code is now (2010-dec-04) not used, because the value field is no more editable /* Note: this code is now (2010-dec-04) not used, because the value field is no more editable
* because changing the value is equivalent to create a new component or alias. * because changing the value is equivalent to create a new component or alias.
* This is now handled in libedit main frame, and no more in this dialog * This is now handled in libedit main frame, and no more in this dialog

View File

@ -179,11 +179,18 @@ create a new power component with the new value." ), GetChars( entry->GetName()
aField->m_Size.x = aField->m_Size.y = m_TextFieldSize; aField->m_Size.x = aField->m_Size.y = m_TextFieldSize;
} }
aField->m_Text = newtext;
if( fieldNdx == REFERENCE ) if( fieldNdx == REFERENCE )
{
// Test is reference is acceptable:
if( SCH_COMPONENT::IsReferenceStringValid( newtext ) )
{ {
component->SetRef( GetSheet(), newtext ); component->SetRef( GetSheet(), newtext );
aField->m_Text = newtext;
}
else
{
DisplayError( this, _( "Illegal reference string! No change" ) );
}
} }
} }
else else

View File

@ -10,7 +10,8 @@
#include "class_sch_screen.h" #include "class_sch_screen.h"
#include "general.h" #include "general.h"
#include "protos.h" //#include "protos.h"
#include "sch_component.h"
#include "libeditframe.h" #include "libeditframe.h"
#include "class_library.h" #include "class_library.h"
#include "template_fieldnames.h" #include "template_fieldnames.h"
@ -51,6 +52,7 @@ void LIB_EDIT_FRAME::EditField( wxDC* DC, LIB_FIELD* aField )
text.Replace( wxT( " " ), wxT( "_" ) ); text.Replace( wxT( " " ), wxT( "_" ) );
// Perform some controls:
if( ( aField->GetId() == REFERENCE || aField->GetId() == VALUE ) && text.IsEmpty ( ) ) if( ( aField->GetId() == REFERENCE || aField->GetId() == VALUE ) && text.IsEmpty ( ) )
{ {
title.Printf( _( "A %s field cannot be empty." ), GetChars(aField->GetName().Lower() ) ); title.Printf( _( "A %s field cannot be empty." ), GetChars(aField->GetName().Lower() ) );
@ -58,6 +60,14 @@ void LIB_EDIT_FRAME::EditField( wxDC* DC, LIB_FIELD* aField )
return; return;
} }
// Ensure the reference prefix is acceptable:
if( ( aField->GetId() == REFERENCE ) &&
! SCH_COMPONENT::IsReferenceStringValid( text ) )
{
DisplayError( this, _( "Illegal reference. A reference must start by a letter" ) );
return;
}
wxString fieldText = aField->GetFullText( m_unit ); wxString fieldText = aField->GetFullText( m_unit );
/* If the value field is changed, this is equivalent to creating a new component from /* If the value field is changed, this is equivalent to creating a new component from

View File

@ -369,6 +369,32 @@ const wxString SCH_COMPONENT::GetRef( SCH_SHEET_PATH* sheet )
} }
/* Function IsReferenceStringValid (static function)
* Tests for an acceptable reference string
* An acceptable reference string must support unannotation
* i.e starts by letter
* returns true if OK
*/
bool SCH_COMPONENT::IsReferenceStringValid( const wxString & aReferenceString )
{
wxString text = aReferenceString;
bool ok = true;
// Try to unannotate this reference
while( !text.IsEmpty() &&
( text.Last() == '?' || isdigit( text.Last() ) ) )
text.RemoveLast();
if( text.IsEmpty() )
ok = false;
// Add here other constraints
// Currently:no other constraint
return ok;
}
void SCH_COMPONENT::SetRef( SCH_SHEET_PATH* sheet, const wxString& ref ) void SCH_COMPONENT::SetRef( SCH_SHEET_PATH* sheet, const wxString& ref )
{ {
wxString path = GetPath( sheet ); wxString path = GetPath( sheet );
@ -417,9 +443,13 @@ void SCH_COMPONENT::SetRef( SCH_SHEET_PATH* sheet, const wxString& ref )
// Reinit the m_prefix member if needed // Reinit the m_prefix member if needed
wxString prefix = ref; wxString prefix = ref;
if( IsReferenceStringValid( prefix ) )
while( prefix.Last() == '?' or isdigit( prefix.Last() ) ) {
while( prefix.Last() == '?' || isdigit( prefix.Last() ) )
prefix.RemoveLast(); prefix.RemoveLast();
}
else
prefix = wxT("U"); // Set to default ref prefix
if( m_prefix != prefix ) if( m_prefix != prefix )
m_prefix = prefix; m_prefix = prefix;
@ -598,7 +628,6 @@ void SCH_COMPONENT::Place( SCH_EDIT_FRAME* frame, wxDC* DC )
void SCH_COMPONENT::ClearAnnotation( SCH_SHEET_PATH* aSheetPath ) void SCH_COMPONENT::ClearAnnotation( SCH_SHEET_PATH* aSheetPath )
{ {
wxString defRef = m_prefix;
bool keepMulti = false; bool keepMulti = false;
LIB_COMPONENT* Entry; LIB_COMPONENT* Entry;
static const wxString separators( wxT( " " ) ); static const wxString separators( wxT( " " ) );
@ -609,8 +638,18 @@ void SCH_COMPONENT::ClearAnnotation( SCH_SHEET_PATH* aSheetPath )
if( Entry && Entry->UnitsLocked() ) if( Entry && Entry->UnitsLocked() )
keepMulti = true; keepMulti = true;
// Build a reference with no annotation,
// i.e. a reference ended by only one '?'
wxString defRef = m_prefix;
if( IsReferenceStringValid( defRef ) )
{
while( defRef.Last() == '?' ) while( defRef.Last() == '?' )
defRef.RemoveLast(); defRef.RemoveLast();
}
else
{ // This is a malformed reference: reinit this reference
m_prefix = defRef = wxT("U"); // Set to default ref prefix
}
defRef.Append( wxT( "?" ) ); defRef.Append( wxT( "?" ) );

View File

@ -261,13 +261,25 @@ public:
// returns a unique ID, in the form of a path. // returns a unique ID, in the form of a path.
wxString GetPath( SCH_SHEET_PATH* sheet ); wxString GetPath( SCH_SHEET_PATH* sheet );
/**
* Function IsReferenceStringValid (static)
* Tests for an acceptable reference string
* An acceptable reference string must support unannotation
* i.e starts by letter
* @param aReferenceString = the reference string to validate
* @return true if OK
*/
static bool IsReferenceStringValid( const wxString &aReferenceString );
/** /**
* Function GetRef * Function GetRef
* returns the reference, for the given sheet path. * returns the reference, for the given sheet path.
*/ */
const wxString GetRef( SCH_SHEET_PATH* sheet ); const wxString GetRef( SCH_SHEET_PATH* sheet );
// Set the reference, for the given sheet path. /**
* Set the reference, for the given sheet path.
*/
void SetRef( SCH_SHEET_PATH* sheet, const wxString& ref ); void SetRef( SCH_SHEET_PATH* sheet, const wxString& ref );
/** /**