Add sheet number processing to sheet fields.
Also fixes a bug where we were depending on the old deque stuff's deterministic traversal, which isn't provided by the new RTree stuff. Fixes https://gitlab.com/kicad/code/kicad/issues/2433
This commit is contained in:
parent
889b6cb1b1
commit
0370eff7ba
|
@ -74,12 +74,12 @@ FIELDS_GRID_TABLE<T>::FIELDS_GRID_TABLE( DIALOG_SHIM* aDialog, SCH_BASE_FRAME* a
|
|||
m_mandatoryFieldCount( SHEET_MANDATORY_FIELDS ),
|
||||
m_part( nullptr ),
|
||||
m_fieldNameValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), FIELD_NAME ),
|
||||
m_referenceValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), REFERENCE ),
|
||||
m_referenceValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), SHEETNAME_V ),
|
||||
m_valueValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), VALUE ),
|
||||
m_libIdValidator( LIB_ID::ID_PCB ),
|
||||
m_urlValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), FIELD_VALUE ),
|
||||
m_nonUrlValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), FIELD_VALUE ),
|
||||
m_filepathValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), SHEETFILENAME )
|
||||
m_filepathValidator( aFrame->IsType( FRAME_SCH_LIB_EDITOR ), SHEETFILENAME_V )
|
||||
{
|
||||
initGrid( aDialog );
|
||||
}
|
||||
|
@ -320,6 +320,11 @@ wxGridCellAttr* FIELDS_GRID_TABLE<T>::GetAttr( int aRow, int aCol, wxGridCellAtt
|
|||
m_urlAttr->IncRef();
|
||||
return m_urlAttr;
|
||||
}
|
||||
else if( m_parentType == SCH_SHEET_T && aRow == SHEETNAME )
|
||||
{
|
||||
m_referenceAttr->IncRef();
|
||||
return m_referenceAttr;
|
||||
}
|
||||
else if( m_parentType == SCH_SHEET_T && aRow == SHEETFILENAME )
|
||||
{
|
||||
m_filepathAttr->IncRef();
|
||||
|
|
|
@ -160,12 +160,16 @@ void HIERARCHY_NAVIG_DLG::buildHierarchyTree( SCH_SHEET_PATH* aList, wxTreeItemI
|
|||
{
|
||||
wxCHECK_RET( m_nbsheets < NB_MAX_SHEET, "Maximum number of sheets exceeded." );
|
||||
|
||||
for( auto aItem : aList->LastScreen()->Items().OfType( SCH_SHEET_T ) )
|
||||
std::vector<SCH_ITEM*> sheetChildren;
|
||||
aList->LastScreen()->GetSheets( &sheetChildren );
|
||||
|
||||
for( SCH_ITEM* aItem : sheetChildren )
|
||||
{
|
||||
SCH_SHEET* sheet = static_cast<SCH_SHEET*>( aItem );
|
||||
wxString sheetName = sheet->GetFields()[ SHEETNAME ].GetShownText();
|
||||
m_nbsheets++;
|
||||
wxTreeItemId menu;
|
||||
menu = m_Tree->AppendItem( *aPreviousmenu, sheet->GetName(), 0, 1 );
|
||||
menu = m_Tree->AppendItem( *aPreviousmenu, sheetName, 0, 1 );
|
||||
aList->push_back( sheet );
|
||||
m_Tree->SetItemData( menu, new TreeItemData( *aList ) );
|
||||
|
||||
|
|
|
@ -759,16 +759,32 @@ void SCH_SCREEN::EnsureAlternateReferencesExist()
|
|||
}
|
||||
|
||||
|
||||
void SCH_SCREEN::GetHierarchicalItems( EDA_ITEMS& aItems )
|
||||
void SCH_SCREEN::GetHierarchicalItems( std::vector<SCH_ITEM*>* aItems )
|
||||
{
|
||||
for( SCH_ITEM* item : Items() )
|
||||
{
|
||||
if( ( item->Type() == SCH_SHEET_T ) || ( item->Type() == SCH_COMPONENT_T ) )
|
||||
aItems.push_back( item );
|
||||
aItems->push_back( item );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SCH_SCREEN::GetSheets( std::vector<SCH_ITEM*>* aItems )
|
||||
{
|
||||
for( SCH_ITEM* item : Items().OfType( SCH_SHEET_T ) )
|
||||
aItems->push_back( item );
|
||||
|
||||
std::sort( aItems->begin(), aItems->end(),
|
||||
[]( EDA_ITEM* a, EDA_ITEM* b ) -> bool
|
||||
{
|
||||
if( a->GetPosition().x == b->GetPosition().x )
|
||||
return a->GetPosition().y < b->GetPosition().y;
|
||||
else
|
||||
return a->GetPosition().x < b->GetPosition().x;
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
bool SCH_SCREEN::TestDanglingEnds( const SCH_SHEET_PATH* aPath )
|
||||
{
|
||||
std::vector< DANGLING_END_ITEM > endPoints;
|
||||
|
@ -1065,7 +1081,7 @@ void SCH_SCREENS::ClearAnnotationOfNewSheetPaths( SCH_SHEET_LIST& aInitialSheetP
|
|||
|
||||
int SCH_SCREENS::ReplaceDuplicateTimeStamps()
|
||||
{
|
||||
EDA_ITEMS items;
|
||||
std::vector<SCH_ITEM*> items;
|
||||
int count = 0;
|
||||
|
||||
auto timestamp_cmp = []( const EDA_ITEM* a, const EDA_ITEM* b ) -> bool
|
||||
|
@ -1076,7 +1092,7 @@ int SCH_SCREENS::ReplaceDuplicateTimeStamps()
|
|||
std::set<EDA_ITEM*, decltype( timestamp_cmp )> unique_stamps( timestamp_cmp );
|
||||
|
||||
for( SCH_SCREEN* screen : m_screens )
|
||||
screen->GetHierarchicalItems( items );
|
||||
screen->GetHierarchicalItems( &items );
|
||||
|
||||
if( items.size() < 2 )
|
||||
return 0;
|
||||
|
|
|
@ -392,8 +392,14 @@ public:
|
|||
*
|
||||
* @param aItems Hierarchical item list to fill.
|
||||
*/
|
||||
void GetHierarchicalItems( EDA_ITEMS& aItems );
|
||||
void GetHierarchicalItems( std::vector<SCH_ITEM*>* aItems );
|
||||
|
||||
/**
|
||||
* Similar to GetItems().OfType( SCH_SHEET_T ), but return the sheets in a
|
||||
* deterministic order (L-R, T-B) for sheet numbering.
|
||||
* @param aItems
|
||||
*/
|
||||
void GetSheets( std::vector<SCH_ITEM*>* aItems );
|
||||
|
||||
/**
|
||||
* Return a line item located at \a aPosition.
|
||||
|
|
|
@ -228,6 +228,26 @@ bool SCH_SHEET::ResolveTextVar( wxString* token, int aDepth ) const
|
|||
}
|
||||
}
|
||||
|
||||
if( token->IsSameAs( wxT( "#" ) ) )
|
||||
{
|
||||
SCH_SHEET_LIST sheetList( g_RootSheet );
|
||||
|
||||
for( const SCH_SHEET_PATH& sheet : sheetList )
|
||||
{
|
||||
if( sheet.Last() == this ) // Current sheet path found
|
||||
{
|
||||
*token = wxString::Format( wxT( "%d" ), sheet.GetPageNumber() );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( token->IsSameAs( wxT( "##" ) ) )
|
||||
{
|
||||
SCH_SHEET_LIST sheetList( g_RootSheet );
|
||||
*token = wxString::Format( wxT( "%d" ), (int) sheetList.size() );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -705,7 +725,7 @@ void SCH_SHEET::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, MSG_PANEL_ITEMS& aList
|
|||
#if 1 // Set to 1 to display the sheet UUID and hierarchical path
|
||||
wxString msgU, msgL;
|
||||
msgU << _( "UUID" ) << ": " << m_Uuid.AsString();
|
||||
msgL << _( "Path" ) << ": " <<g_CurrentSheet->PathHumanReadable();
|
||||
msgL << _( "Path" ) << ": " << g_CurrentSheet->PathHumanReadable();
|
||||
|
||||
aList.push_back( MSG_PANEL_ITEM( msgU, msgL, BLUE ) );
|
||||
#endif
|
||||
|
|
|
@ -163,7 +163,7 @@ wxString SCH_SHEET_PATH::PathHumanReadable() const
|
|||
|
||||
// Start at 1 to avoid the root sheet, as above.
|
||||
for( unsigned i = 1; i < size(); i++ )
|
||||
s = s + at( i )->GetName() + wxT( "/" );
|
||||
s = s + at( i )->GetFields()[ SHEETNAME ].GetShownText() + wxT( "/" );
|
||||
|
||||
return s;
|
||||
}
|
||||
|
@ -364,7 +364,10 @@ void SCH_SHEET_LIST::BuildSheetList( SCH_SHEET* aSheet )
|
|||
|
||||
if( m_currentSheetPath.LastScreen() )
|
||||
{
|
||||
for( auto item : m_currentSheetPath.LastScreen()->Items().OfType( SCH_SHEET_T ) )
|
||||
std::vector<SCH_ITEM*> childSheets;
|
||||
m_currentSheetPath.LastScreen()->GetSheets( &childSheets );
|
||||
|
||||
for( SCH_ITEM* item : childSheets )
|
||||
{
|
||||
auto sheet = static_cast<SCH_SHEET*>( item );
|
||||
|
||||
|
|
|
@ -44,15 +44,27 @@ SCH_FIELD_VALIDATOR::SCH_FIELD_VALIDATOR( bool aIsLibEditor, int aFieldId, wxSt
|
|||
|
||||
// The reference field cannot contain spaces.
|
||||
if( aFieldId == REFERENCE )
|
||||
{
|
||||
excludes += " ";
|
||||
else if( aFieldId == VALUE && m_isLibEditor )
|
||||
}
|
||||
else if( ( aFieldId == VALUE && m_isLibEditor )
|
||||
|| aFieldId == SHEETNAME_V
|
||||
|| aFieldId == SHEETFILENAME_V )
|
||||
{
|
||||
excludes += " :/\\";
|
||||
}
|
||||
|
||||
long style = GetStyle();
|
||||
|
||||
// The reference and value fields cannot be empty.
|
||||
if( aFieldId == REFERENCE || aFieldId == VALUE || aFieldId == FIELD_NAME )
|
||||
// The reference, value sheetname and sheetfilename fields cannot be empty.
|
||||
if( aFieldId == REFERENCE
|
||||
|| aFieldId == VALUE
|
||||
|| aFieldId == SHEETNAME_V
|
||||
|| aFieldId == SHEETFILENAME_V
|
||||
|| aFieldId == FIELD_NAME )
|
||||
{
|
||||
style |= wxFILTER_EMPTY;
|
||||
}
|
||||
|
||||
SetStyle( style );
|
||||
SetCharExcludes( excludes );
|
||||
|
@ -101,6 +113,14 @@ bool SCH_FIELD_VALIDATOR::Validate( wxWindow *aParent )
|
|||
fieldCharError = _( "The datasheet field cannot contain %s character(s)." );
|
||||
break;
|
||||
|
||||
case SHEETNAME_V:
|
||||
fieldCharError = _( "The sheet name cannot contain %s character(s)." );
|
||||
break;
|
||||
|
||||
case SHEETFILENAME_V:
|
||||
fieldCharError = _( "The sheet filename cannot contain %s character(s)." );
|
||||
break;
|
||||
|
||||
default:
|
||||
fieldCharError = _( "The field cannot contain %s character(s)." );
|
||||
break;
|
||||
|
@ -121,8 +141,10 @@ bool SCH_FIELD_VALIDATOR::Validate( wxWindow *aParent )
|
|||
else if( HasFlag( wxFILTER_EXCLUDE_CHAR_LIST ) && ContainsExcludedCharacters( val ) )
|
||||
{
|
||||
wxArrayString whiteSpace;
|
||||
bool spaceIllegal = ( m_fieldId == REFERENCE ) ||
|
||||
( m_fieldId == VALUE && m_isLibEditor );
|
||||
bool spaceIllegal = m_fieldId == REFERENCE
|
||||
|| ( m_fieldId == VALUE && m_isLibEditor )
|
||||
|| m_fieldId == SHEETNAME_V
|
||||
|| m_fieldId == SHEETFILENAME_V;
|
||||
|
||||
if( val.Find( '\r' ) != wxNOT_FOUND )
|
||||
whiteSpace.Add( _( "carriage return" ) );
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
#define FIELD_NAME -1
|
||||
#define FIELD_VALUE -2
|
||||
|
||||
#define SHEETNAME_V 100 // We can't use SHEETNAME and SHEETFILENAME because they
|
||||
#define SHEETFILENAME_V 101 // overlap with REFERENCE and VALUE
|
||||
|
||||
/**
|
||||
* A text control validator used for validating the text allowed in library and
|
||||
|
|
Loading…
Reference in New Issue