diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 2274b75e75..19df7396dc 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -4,6 +4,19 @@ KiCad ChangeLog 2010 Please add newer entries at the top, list the date and your name with email address. +2010-dec-31 UPDATE Wayne Stambaugh +================================================================================ +++all + * Exclude boost header include path from Doxygen files. + * Coding guide line and doxygen warning fixes. +++EESchema + * Rename OBJ_CMP_TO_LIST to SCH_REFERENCE. + * Move code related to SCH_REFERENCE into the object where it belongs in hope + that some day the object members can be made private instead of public. + * Add GetComponent method to sheet path and sheet path list objects. + * Move screen list code into screen list object. + + 2010-Dec-28 UPDATE Dick Hollenbeck ================================================================================ ++richio: diff --git a/Doxyfile b/Doxyfile index ca524297a5..959df7bd17 100644 --- a/Doxyfile +++ b/Doxyfile @@ -88,7 +88,7 @@ INPUT_ENCODING = UTF-8 FILE_PATTERNS = *.h \ *.cpp RECURSIVE = YES -EXCLUDE = +EXCLUDE = include\boost EXCLUDE_SYMLINKS = NO EXCLUDE_PATTERNS = EXCLUDE_SYMBOLS = diff --git a/eeschema/annotate.cpp b/eeschema/annotate.cpp index 759c768a02..55001ff6af 100644 --- a/eeschema/annotate.cpp +++ b/eeschema/annotate.cpp @@ -13,91 +13,18 @@ #include "class_sch_screen.h" #include "wxEeschemaStruct.h" +#include "netlist.h" #include "class_library.h" #include "protos.h" #include "sch_component.h" -#include "netlist.h" #include "lib_pin.h" -static int AddComponentsInSheetToList( std::vector & aComponentsList, - SCH_SHEET_PATH* sheet ); -static void BreakReference( std::vector & aComponentsList ); -static void ReAnnotateComponents( std::vector & aComponentsList ); -static void ComputeReferenceNumber( std::vector & aComponentsList ); -int GetLastReferenceNumber( int aObjet, - std::vector & aComponentsList ); -static int ExistUnit( int aObjet, int aUnit, - std::vector & aComponentsList ); -static int ReplaceDuplicatedTimeStamps(); - - -/* Set a sheet number, the sheet count for sheets in the whole schematic - * and update the date in all screens - */ -void SCH_EDIT_FRAME::UpdateSheetNumberAndDate() -{ - wxString date = GenDate(); - SCH_SCREENS s_list; - - // Set the date - for( SCH_SCREEN* screen = s_list.GetFirst(); screen != NULL; - screen = s_list.GetNext() ) - screen->m_Date = date; - - // Set sheet counts - SetSheetNumberAndCount(); -} - - -/***************************************************************************** - * Used to annotate the power symbols, before testing erc or computing - * netlist when a component reannotation is not necessary - * - * In order to avoid conflicts the reference number starts with a 0. A - * PWR with id 12 is named PWR12 in global annotation and PWR012 by the - * Power annotation. - ****************************************************************************/ -void ReAnnotatePowerSymbolsOnly( void ) -{ - /* Build the whole sheet list in hierarchy (sheet, not screen) */ - SCH_SHEET_LIST SheetList; - - SCH_SHEET_PATH* sheet; - int CmpNumber = 1; - - for( sheet = SheetList.GetFirst(); sheet != NULL; - sheet = SheetList.GetNext() ) - { - EDA_ITEM* DrawList = sheet->LastDrawList(); - - for( ; DrawList != NULL; DrawList = DrawList->Next() ) - { - if( DrawList->Type() != SCH_COMPONENT_T ) - continue; - - SCH_COMPONENT* DrawLibItem = (SCH_COMPONENT*) DrawList; - LIB_COMPONENT* Entry = - CMP_LIBRARY::FindLibraryComponent( DrawLibItem->GetLibName() ); - - if( ( Entry == NULL ) || !Entry->IsPower() ) - continue; - - //DrawLibItem->ClearAnnotation(sheet); this clears all annotation :( - wxString refstr = DrawLibItem->GetPrefix(); - - //str will be "C?" or so after the ClearAnnotation call. - while( refstr.Last() == '?' ) - refstr.RemoveLast(); - - if( !refstr.StartsWith( wxT( "#" ) ) ) - refstr = wxT( "#" ) + refstr; - refstr << wxT( "0" ) << CmpNumber; - DrawLibItem->SetRef( sheet, refstr ); - CmpNumber++; - } - } -} +static void BreakReference( std::vector< SCH_REFERENCE >& aComponentsList ); +static void ReAnnotateComponents( std::vector< SCH_REFERENCE >& aComponentsList ); +static void ComputeReferenceNumber( std::vector< SCH_REFERENCE >& aComponentsList ); +int GetLastReferenceNumber( int aObjet, std::vector< SCH_REFERENCE >& aComponentsList ); +static int ExistUnit( int aObjet, int aUnit, std::vector< SCH_REFERENCE >& aComponentList ); /* sort function to annotate items by their position. @@ -108,8 +35,7 @@ void ReAnnotatePowerSymbolsOnly( void ) * if same X pos, by Y pos * if same Y pos, by time stamp */ -static bool AnnotateBy_X_Position( const OBJ_CMP_TO_LIST& item1, - const OBJ_CMP_TO_LIST& item2 ) +static bool SortByXPosition( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 ) { int ii = item1.CompareRef( item2 ); @@ -134,8 +60,7 @@ static bool AnnotateBy_X_Position( const OBJ_CMP_TO_LIST& item1, * if same Y pos, by X pos * if same X pos, by time stamp */ -static bool AnnotateBy_Y_Position( const OBJ_CMP_TO_LIST& item1, - const OBJ_CMP_TO_LIST& item2 ) +static bool SortByYPosition( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 ) { int ii = item1.CompareRef( item2 ); @@ -161,8 +86,7 @@ static bool AnnotateBy_Y_Position( const OBJ_CMP_TO_LIST& item1, * if same unit number, by sheet * if same sheet, by time stamp *****************************************************************************/ -static bool AnnotateByValue( const OBJ_CMP_TO_LIST& item1, - const OBJ_CMP_TO_LIST& item2 ) +static bool SortByValue( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 ) { int ii = item1.CompareRef( item2 ); @@ -187,8 +111,7 @@ static bool AnnotateByValue( const OBJ_CMP_TO_LIST& item1, * qsort function to annotate items by value * Components are sorted by time stamp *****************************************************************************/ -static bool SortByTimeStamp( const OBJ_CMP_TO_LIST& item1, - const OBJ_CMP_TO_LIST& item2 ) +static bool SortByTimeStamp( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 ) { int ii = item1.m_SheetPath.Cmp( item2.m_SheetPath ); @@ -208,41 +131,19 @@ static bool SortByTimeStamp( const OBJ_CMP_TO_LIST& item1, */ void SCH_EDIT_FRAME::DeleteAnnotation( bool aCurrentSheetOnly, bool aRedraw ) { - SCH_ITEM* strct; - SCH_SCREEN* screen; - SCH_SCREENS ScreenList; - - screen = ScreenList.GetFirst(); - if( aCurrentSheetOnly ) - screen = GetScreen(); - - if( screen == NULL ) - return; - - while( screen ) { - strct = screen->GetDrawItems(); - - for( ; strct; strct = strct->Next() ) - { - if( strct->Type() == SCH_COMPONENT_T ) - { - if( aCurrentSheetOnly ) - ( (SCH_COMPONENT*) strct )->ClearAnnotation( m_CurrentSheet ); - else - ( (SCH_COMPONENT*) strct )->ClearAnnotation( NULL ); - } - } - - OnModify( ); - if( aCurrentSheetOnly ) - break; - screen = ScreenList.GetNext(); + SCH_SCREEN* screen = GetScreen(); + wxCHECK_RET( screen != NULL, wxT( "Attempt to clear annotation of a NULL screen." ) ); + screen->ClearAnnotation( m_CurrentSheet ); + } + else + { + SCH_SCREENS ScreenList; + ScreenList.ClearAnnotation(); } - - //update the References + // Update the references for the sheet that is currently being displayed. m_CurrentSheet->UpdateAllScreenReferences(); if( aRedraw ) @@ -276,240 +177,113 @@ void AnnotateComponents( SCH_EDIT_FRAME* parent, bool resetAnnotation, bool repairsTimestamps ) { - std::vector ComponentsList; + std::vector< SCH_REFERENCE > references; wxBusyCursor dummy; - // Test and replace duplicate time stamps - // duplicate can happen with old schematics, or schematic conversions or - // manual editions of files ... + SCH_SCREENS screens; + + /* Build the sheet list */ + SCH_SHEET_LIST sheets; + + // Test for and replace duplicate time stamps in components and sheets. Duplicate + // time stamps can happen with old schematics, schematic conversions, or manual + // editing of files. if( repairsTimestamps ) { - int ireplacecount = ReplaceDuplicatedTimeStamps(); - if( ireplacecount ) + int count = screens.ReplaceDuplicateTimeStamps(); + + if( count ) { wxString msg; - msg.Printf( _( "%d duplicate time stamps replaced." ), - ireplacecount ); + msg.Printf( _( "%d duplicate time stamps were found and replaced." ), count ); DisplayInfoMessage( NULL, msg, 2 ); } } - /* If it is an annotation for all the components, reset previous - * annotation: */ + // If it is an annotation for all the components, reset previous annotation. if( resetAnnotation ) parent->DeleteAnnotation( !annotateSchematic, false ); - /* Build the sheet list */ - SCH_SHEET_LIST SheetList; + // Update the screen date. + screens.SetDate( GenDate() ); - /* Update the sheet number, sheet count and date */ - parent->UpdateSheetNumberAndDate(); + // Set sheet number and total sheet counts. + parent->SetSheetNumberAndCount(); /* Build component list */ if( annotateSchematic ) { - SCH_SHEET_PATH* sheet; - for( sheet = SheetList.GetFirst(); - sheet != NULL; - sheet = SheetList.GetNext() ) - AddComponentsInSheetToList( ComponentsList, sheet ); + sheets.GetComponents( references ); } else - AddComponentsInSheetToList( ComponentsList, parent->GetSheet() ); - + { + parent->GetSheet()->GetComponents( references ); + } /* Break full components reference in name (prefix) and number: * example: IC1 become IC, and 1 */ - BreakReference( ComponentsList ); + BreakReference( references ); switch( sortOption ) { case 0: - sort( ComponentsList.begin(), ComponentsList.end(), - AnnotateBy_X_Position ); + sort( references.begin(), references.end(), SortByXPosition ); break; case 1: - sort( ComponentsList.begin(), ComponentsList.end(), - AnnotateBy_Y_Position ); + sort( references.begin(), references.end(), SortByYPosition ); break; case 2: - sort( ComponentsList.begin(), ComponentsList.end(), AnnotateByValue ); + sort( references.begin(), references.end(), SortByValue ); break; } /* Recalculate reference numbers */ - ComputeReferenceNumber( ComponentsList ); - ReAnnotateComponents( ComponentsList ); + ComputeReferenceNumber( references ); + ReAnnotateComponents( references ); /* Final control (just in case ... )*/ parent->CheckAnnotate( NULL, !annotateSchematic ); - parent->OnModify( ); + parent->OnModify(); parent->DrawPanel->Refresh( true ); } -/** - * Function AddComponentsInSheetToList - * Add a OBJ_CMP_TO_LIST object in aComponentsList for each component found - * in sheet - * @param aComponentsList = a std::vector list to fill - * @param aSheet - The SCH_SHEET_PATH sheet to analyze - */ -int AddComponentsInSheetToList( std::vector & aComponentsList, - SCH_SHEET_PATH* aSheet ) -{ - int NbrCmp = 0; - EDA_ITEM* DrawList = aSheet->LastDrawList(); - SCH_COMPONENT* DrawLibItem; - LIB_COMPONENT* Entry; - - for( ; DrawList != NULL; DrawList = DrawList->Next() ) - { - if( DrawList->Type() == SCH_COMPONENT_T ) - { - DrawLibItem = (SCH_COMPONENT*) DrawList; - Entry = CMP_LIBRARY::FindLibraryComponent( DrawLibItem->GetLibName() ); - - if( Entry == NULL ) - continue; - - OBJ_CMP_TO_LIST new_object; - new_object.m_RootCmp = DrawLibItem; - new_object.m_Entry = Entry; - new_object.m_Unit = DrawLibItem->GetUnitSelection( aSheet ); - new_object.m_SheetPath = *aSheet; - new_object.m_IsNew = false; - new_object.m_Flag = 0; - new_object.m_TimeStamp = DrawLibItem->m_TimeStamp; - - if( DrawLibItem->GetRef( aSheet ).IsEmpty() ) - DrawLibItem->SetRef( aSheet, wxT( "DefRef?" ) ); - - new_object.SetRef( DrawLibItem->GetRef( aSheet ) ); - - new_object.m_NumRef = -1; - - if( DrawLibItem->GetField( VALUE )->m_Text.IsEmpty() ) - DrawLibItem->GetField( VALUE )->m_Text = wxT( "~" ); - - new_object.m_Value = &DrawLibItem->GetField( VALUE )->m_Text; - - aComponentsList.push_back( new_object ); - NbrCmp++; - } - } - - return NbrCmp; -} - - /* - * Update the reference component for the schematic project (or the current - * sheet) + * Update the reference component for the schematic project (or the current sheet) */ -static void ReAnnotateComponents( std::vector & aComponentsList ) +static void ReAnnotateComponents( std::vector< SCH_REFERENCE >& aComponentList ) { /* update the reference numbers */ - for( unsigned ii = 0; ii < aComponentsList.size(); ii++ ) + for( unsigned ii = 0; ii < aComponentList.size(); ii++ ) { #if 0 - char* Text = aComponentsList[ii].m_Reference; - SCH_COMPONENT* component = aComponentsList[ii].m_RootCmp; + char* Text = aComponentList[ii].m_Reference; + SCH_COMPONENT* component = aComponentList[ii].m_RootCmp; - if( aComponentsList[ii].m_NumRef < 0 ) + if( aComponentList[ii].m_NumRef < 0 ) strcat( Text, "?" ); else - sprintf( Text + strlen( Text ), "%d", aComponentsList[ii].m_NumRef ); + sprintf( Text + strlen( Text ), "%d", aComponentList[ii].m_NumRef ); - component->SetRef( &(aComponentsList[ii].m_SheetPath), CONV_FROM_UTF8( Text ) ); + component->SetRef( &(aComponentList[ii].m_SheetPath), CONV_FROM_UTF8( Text ) ); + + component->SetUnit( aComponentList[ii].m_Unit ); + component->SetUnitSelection( &aComponentList[ii].m_SheetPath, + aComponentList[ii].m_Unit ); #else - - wxString ref = aComponentsList[ii].GetRef(); - SCH_COMPONENT* component = aComponentsList[ii].m_RootCmp; - - if( aComponentsList[ii].m_NumRef < 0 ) - ref += wxChar( '?' ); - else - ref << aComponentsList[ii].m_NumRef; - - aComponentsList[ii].SetRef( ref ); - - component->SetRef( &aComponentsList[ii].m_SheetPath, ref ); + aComponentList[ii].Annotate(); #endif - - component->SetUnit( aComponentsList[ii].m_Unit ); - component->SetUnitSelection( &aComponentsList[ii].m_SheetPath, - aComponentsList[ii].m_Unit ); } } -/** - * Split component reference designators into a name (prefix) and number. - * Example: IC1 becomes IC and 1 in the .m_NumRef member. - * For multi part per package components not already annotated, set .m_Unit - * to a max value (0x7FFFFFFF). - * - * @param aComponentsList = list of component - */ -void BreakReference( std::vector & aComponentsList ) +void BreakReference( std::vector< SCH_REFERENCE >& aComponentsList ) { - std::string refText; // construct once outside loop - for( unsigned ii = 0; ii < aComponentsList.size(); ii++ ) - { - aComponentsList[ii].m_NumRef = -1; - - refText = aComponentsList[ii].GetRefStr(); - - int ll = refText.length() - 1; - - if( refText[ll] == '?' ) - { - aComponentsList[ii].m_IsNew = true; - - if( !aComponentsList[ii].IsPartsLocked() ) - aComponentsList[ii].m_Unit = 0x7FFFFFFF; - - refText.erase(ll); // delete last char - - aComponentsList[ii].SetRefStr( refText ); - } - - else if( isdigit( refText[ll] ) == 0 ) - { - aComponentsList[ii].m_IsNew = true; - if( !aComponentsList[ii].IsPartsLocked() ) - aComponentsList[ii].m_Unit = 0x7FFFFFFF; - } - - else - { - while( ll >= 0 ) - { - if( (refText[ll] <= ' ' ) || isdigit( refText[ll] ) ) - ll--; - else - { - if( isdigit( refText[ll + 1] ) ) - { - // nul terminated C string into cp - const char* cp = refText.c_str() + ll + 1; - - aComponentsList[ii].m_NumRef = atoi( cp ); - } - - refText.erase( ll+1 ); // delete from ll+1 to end - break; - } - } - - aComponentsList[ii].SetRefStr( refText ); - } - } + aComponentsList[ii].Split(); } @@ -517,7 +291,7 @@ void BreakReference( std::vector & aComponentsList ) * Compute the reference number for components without reference number * Compute .m_NumRef member */ -static void ComputeReferenceNumber( std::vector & aComponentsList ) +static void ComputeReferenceNumber( std::vector< SCH_REFERENCE >& aComponentsList ) { int LastReferenceNumber, NumberOfUnits, Unit; @@ -562,6 +336,7 @@ static void ComputeReferenceNumber( std::vector & aComponentsLi LastReferenceNumber++; aComponentsList[ii].m_NumRef = LastReferenceNumber; } + aComponentsList[ii].m_Unit = 1; aComponentsList[ii].m_Flag = 1; aComponentsList[ii].m_IsNew = false; @@ -590,7 +365,9 @@ static void ComputeReferenceNumber( std::vector & aComponentsLi { if( aComponentsList[ii].m_Unit == Unit ) continue; + int found = ExistUnit( ii, Unit, aComponentsList ); + if( found >= 0 ) continue; /* this unit exists for this reference (unit * already annotated) */ @@ -604,8 +381,10 @@ static void ComputeReferenceNumber( std::vector & aComponentsLi if( aComponentsList[ii].CompareRef( aComponentsList[jj] ) != 0 ) continue; + if( aComponentsList[jj].CompareValue( aComponentsList[ii] ) != 0 ) continue; + if( !aComponentsList[jj].m_IsNew ) continue; @@ -635,8 +414,7 @@ static void ComputeReferenceNumber( std::vector & aComponentsLi * the search pattern) * @param aComponentsList = list of items */ -int GetLastReferenceNumber( int aObjet, - std::vector & aComponentsList ) +int GetLastReferenceNumber( int aObjet, std::vector< SCH_REFERENCE >& aComponentsList ) { int LastNumber = 0; @@ -645,6 +423,7 @@ int GetLastReferenceNumber( int aObjet, /* New identifier. */ if( aComponentsList[aObjet].CompareRef( aComponentsList[ii] ) != 0 ) continue; + if( LastNumber < aComponentsList[ii].m_NumRef ) LastNumber = aComponentsList[ii].m_NumRef; } @@ -657,18 +436,18 @@ int GetLastReferenceNumber( int aObjet, * Search in the sorted list of components, for a given component an other * component with the same reference and a given part unit. Mainly used to * manage multiple parts per package components. - * @param aObjet = index in aComponentsList for the given OBJ_CMP_TO_LIST + * @param aObjet = index in aComponentsList for the given SCH_REFERENCE * item to test * @param Unit = the given unit number to search * @param aComponentsList = list of items to examine * @return index in aComponentsList if found or -1 if not found */ -static int ExistUnit( int aObjet, int Unit, - std::vector & aComponentsList ) +static int ExistUnit( int aObjet, int Unit, std::vector< SCH_REFERENCE >& aComponentsList ) { int NumRef; NumRef = aComponentsList[aObjet].m_NumRef; + for( unsigned ii = 0; ii < aComponentsList.size(); ii++ ) { if( aObjet == (int) ii ) @@ -717,20 +496,15 @@ int SCH_EDIT_FRAME::CheckAnnotate( wxArrayString* aMessageList, bool aOneSheetOn /* build the screen list */ SCH_SHEET_LIST SheetList; - std::vector ComponentsList; + std::vector< SCH_REFERENCE > ComponentsList; /* Build the list of components */ if( !aOneSheetOnly ) - { - SCH_SHEET_PATH* sheet; - for( sheet = SheetList.GetFirst(); sheet != NULL; - sheet = SheetList.GetNext() ) - AddComponentsInSheetToList( ComponentsList, sheet ); - } + SheetList.GetComponents( ComponentsList ); else - AddComponentsInSheetToList( ComponentsList, GetSheet() ); + GetSheet()->GetComponents( ComponentsList ); - sort( ComponentsList.begin(), ComponentsList.end(), AnnotateByValue ); + sort( ComponentsList.begin(), ComponentsList.end(), SortByValue ); /* Break full components reference in name (prefix) and number: example: * IC1 become IC, and 1 */ @@ -739,6 +513,7 @@ int SCH_EDIT_FRAME::CheckAnnotate( wxArrayString* aMessageList, bool aOneSheetOn /* count not yet annotated items */ error = 0; int imax = ComponentsList.size() - 1; + for( int ii = 0; ii < imax; ii++ ) { msg.Empty(); @@ -752,31 +527,25 @@ int SCH_EDIT_FRAME::CheckAnnotate( wxArrayString* aMessageList, bool aOneSheetOn Buff = wxT( "?" ); cmpref = ComponentsList[ii].GetRef(); - msg.Printf( _( "item not annotated: %s%s" ), - GetChars( cmpref ), GetChars( Buff ) ); + msg.Printf( _( "item not annotated: %s%s" ), GetChars( cmpref ), GetChars( Buff ) ); - if( ( ComponentsList[ii].m_Unit > 0 ) - && ( ComponentsList[ii].m_Unit < 0x7FFFFFFF ) ) + if( ( ComponentsList[ii].m_Unit > 0 ) && ( ComponentsList[ii].m_Unit < 0x7FFFFFFF ) ) { Buff.Printf( _( "( unit %d)" ), ComponentsList[ii].m_Unit ); msg << Buff; } if( aMessageList ) - { aMessageList->Add( msg + wxT( "\n" ) ); - } else - { DisplayError( NULL, msg ); - } + error++; break; } // Annotate error - if( MAX( ComponentsList[ii].m_Entry->GetPartCount(), 1 ) - < ComponentsList[ii].m_Unit ) + if( MAX( ComponentsList[ii].m_Entry->GetPartCount(), 1 ) < ComponentsList[ii].m_Unit ) { if( ComponentsList[ii].m_NumRef >= 0 ) Buff << ComponentsList[ii].m_NumRef; @@ -785,19 +554,18 @@ int SCH_EDIT_FRAME::CheckAnnotate( wxArrayString* aMessageList, bool aOneSheetOn cmpref = ComponentsList[ii].GetRef(); - msg.Printf( _( "Error item %s%s" ), GetChars( cmpref ), - GetChars( Buff ) ); + msg.Printf( _( "Error item %s%s" ), GetChars( cmpref ), GetChars( Buff ) ); Buff.Printf( _( " unit %d and no more than %d parts" ), ComponentsList[ii].m_Unit, ComponentsList[ii].m_Entry->GetPartCount() ); msg << Buff; + if( aMessageList ) - { aMessageList->Add( msg + wxT( "\n" )); - } else DisplayError( NULL, msg ); + error++; break; } @@ -827,21 +595,19 @@ int SCH_EDIT_FRAME::CheckAnnotate( wxArrayString* aMessageList, bool aOneSheetOn cmpref = ComponentsList[ii].GetRef(); - msg.Printf( _( "Multiple item %s%s" ), - GetChars( cmpref ), GetChars( Buff ) ); + msg.Printf( _( "Multiple item %s%s" ), GetChars( cmpref ), GetChars( Buff ) ); - if( ( ComponentsList[ii].m_Unit > 0 ) - && ( ComponentsList[ii].m_Unit < 0x7FFFFFFF ) ) + if( ( ComponentsList[ii].m_Unit > 0 )&& ( ComponentsList[ii].m_Unit < 0x7FFFFFFF ) ) { Buff.Printf( _( " (unit %d)" ), ComponentsList[ii].m_Unit ); msg << Buff; } + if( aMessageList ) - { aMessageList->Add( msg + wxT( "\n" )); - } else DisplayError( NULL, msg ); + error++; continue; } @@ -857,30 +623,26 @@ int SCH_EDIT_FRAME::CheckAnnotate( wxArrayString* aMessageList, bool aOneSheetOn Buff = wxT( "?" ); cmpref = ComponentsList[ii].GetRef(); - msg.Printf( _( "Multiple item %s%s" ), - GetChars( cmpref ), GetChars( Buff ) ); + msg.Printf( _( "Multiple item %s%s" ), GetChars( cmpref ), GetChars( Buff ) ); - if( ( ComponentsList[ii].m_Unit > 0 ) - && ( ComponentsList[ii].m_Unit < 0x7FFFFFFF ) ) + if( ( ComponentsList[ii].m_Unit > 0 ) && ( ComponentsList[ii].m_Unit < 0x7FFFFFFF ) ) { Buff.Printf( _( " (unit %d)" ), ComponentsList[ii].m_Unit ); msg << Buff; } if( aMessageList ) - { aMessageList->Add( msg + wxT( "\n" )); - } else - { DisplayError( NULL, msg ); - } + error++; } /* Error if values are different between units, for the same * reference */ int next = ii + 1; + if( ComponentsList[ii].CompareValue( ComponentsList[next] ) != 0 ) { wxString nextcmpref = ComponentsList[next].GetRef(); @@ -910,13 +672,9 @@ int SCH_EDIT_FRAME::CheckAnnotate( wxArrayString* aMessageList, bool aOneSheetOn #endif if( aMessageList ) - { aMessageList->Add( msg + wxT( "\n" )); - } else - { DisplayError( NULL, msg ); - } error++; } @@ -924,12 +682,11 @@ int SCH_EDIT_FRAME::CheckAnnotate( wxArrayString* aMessageList, bool aOneSheetOn // count the duplicated time stamps sort( ComponentsList.begin(), ComponentsList.end(), SortByTimeStamp ); + for( int ii = 0; ( ii < imax ) && ( error < 4 ); ii++ ) { - if( (ComponentsList[ii].m_TimeStamp - != ComponentsList[ii + 1].m_TimeStamp) - || ( ComponentsList[ii].m_SheetPath - != ComponentsList[ii + 1].m_SheetPath ) ) + if( ( ComponentsList[ii].m_TimeStamp != ComponentsList[ii + 1].m_TimeStamp ) + || ( ComponentsList[ii].m_SheetPath != ComponentsList[ii + 1].m_SheetPath ) ) continue; /* Same time stamp found. */ @@ -949,102 +706,12 @@ int SCH_EDIT_FRAME::CheckAnnotate( wxArrayString* aMessageList, bool aOneSheetOn GetChars( nextcmpref ), ComponentsList[ii + 1].m_NumRef ); if( aMessageList ) - { aMessageList->Add( msg + wxT( "\n" )); - } else - { DisplayError( NULL, msg ); - } error++; } return error; } - - -/*********************************************** - * function to sort sch_items by time stamp - ************************************************/ -static bool SortItemByTimeStamp( const SCH_ITEM* item1, const SCH_ITEM* item2 ) -{ - int ii = item1->m_TimeStamp - item2->m_TimeStamp; - - /* if same time stamp, compare type, in order to have - * first : component - * after : sheet - * because this is the first item that have its time stamp changed - * and changing the time stamp of a sheet can loose annotation - */ - - if( ii == 0 && ( item1->Type() != item2->Type() ) ) - if( item1->Type() == SCH_SHEET_T ) - ii = -1; - - return ii < 0; -} - - -/** - * Function ReplaceDuplicatedTimeStamps - * Search for duplicate time stamps in the whole hierarchy, and replace - * duplicate by new time stamps - */ -int ReplaceDuplicatedTimeStamps() -{ - /* Build the whole screen list */ - SCH_SCREENS ScreenList; - - /* Build the list of items with time stamps (components and sheets) - * note: if all items have a different time stamp, this ensure also - * different paths in complex hierarchy - * this is the reason we have different time stamps for components AND - * sheets - */ - std::vector itemlist; - SCH_SCREEN* screen; - SCH_ITEM* item; - - for( screen = ScreenList.GetFirst(); screen != NULL; screen = ScreenList.GetNext() ) - { - item = screen->GetDrawItems(); - - while( item ) - { - if( ( item->Type() == SCH_SHEET_T ) - || ( item->Type() == SCH_COMPONENT_T ) ) - itemlist.push_back( item ); - - item = item->Next(); - } - } - - // Test and replace duplicated time stamps - int imax = itemlist.size() - 1; - int errcount = 0; - sort( itemlist.begin(), itemlist.end(), SortItemByTimeStamp ); - for( int ii = 0; ii < imax; ii++ ) - { - item = itemlist[ii]; - SCH_ITEM* nextitem = itemlist[ii + 1]; - if( item->m_TimeStamp == nextitem->m_TimeStamp ) - { - errcount++; - - // for a component, update its Time stamp and its paths - // (m_PathsAndReferences field) - if( item->Type() == SCH_COMPONENT_T ) - ( (SCH_COMPONENT*) item )->SetTimeStamp( GetTimeStamp() ); - - // for a sheet, update only its time stamp (annotation of its - // components will be lost) - // @todo: see how to change sheet paths for its cmp list (can - // be possible in most cases) - else - item->m_TimeStamp = GetTimeStamp(); - } - } - - return errcount; -} diff --git a/eeschema/build_BOM.cpp b/eeschema/build_BOM.cpp index 9f5f85daa5..6b4dc0212d 100644 --- a/eeschema/build_BOM.cpp +++ b/eeschema/build_BOM.cpp @@ -27,49 +27,6 @@ */ -/** - * Function BuildComponentsListFromSchematic - * creates the list of components found in the whole schematic. - * - * Goes through the 'sheets', not the screens, so that we account for - * multiple instances of a given screen. - */ -void BuildComponentsListFromSchematic( std::vector & aList ) -{ - // Build the sheet list (which is not screen a screen list) - SCH_SHEET_LIST sheetList; // uses a global - - for( SCH_SHEET_PATH* path = sheetList.GetFirst(); path; path = sheetList.GetNext() ) - { - for( EDA_ITEM* schItem = path->LastDrawList(); schItem; schItem = schItem->Next() ) - { - if( schItem->Type() != SCH_COMPONENT_T ) - continue; - - SCH_COMPONENT* comp = (SCH_COMPONENT*) schItem; - - comp->SetParent( path->LastScreen() ); - - OBJ_CMP_TO_LIST item; - - item.m_RootCmp = comp; - item.m_SheetPath = *path; - item.m_Unit = comp->GetUnitSelection( path ); - - item.SetRef( comp->GetRef( path ) ); - - // skip pseudo components, which have a reference starting - // with #, mainly power symbols - if( item.GetRefStr()[0] == '#' ) - continue; - - // Real component found, keep it - aList.push_back( item ); - } - } -} - - /* Fill aList with Glabel info */ void GenListeGLabels( std::vector & aList ) @@ -125,7 +82,7 @@ void GenListeGLabels( std::vector & aList ) * if same value: by reference * if same reference: by unit number */ -bool SortComponentsByValue( const OBJ_CMP_TO_LIST& obj1, const OBJ_CMP_TO_LIST& obj2 ) +bool SortComponentsByValue( const SCH_REFERENCE& obj1, const SCH_REFERENCE& obj2 ) { int ii; const wxString* Text1, * Text2; @@ -154,7 +111,7 @@ bool SortComponentsByValue( const OBJ_CMP_TO_LIST& obj1, const OBJ_CMP_TO_LIST& * if same reference: by value * if same value: by unit number */ -bool SortComponentsByReference( const OBJ_CMP_TO_LIST& obj1, const OBJ_CMP_TO_LIST& obj2 ) +bool SortComponentsByReference( const SCH_REFERENCE& obj1, const SCH_REFERENCE& obj2 ) { int ii; const wxString* Text1, * Text2; @@ -242,7 +199,7 @@ bool SortLabelsBySheet( const LABEL_OBJECT& obj1, const LABEL_OBJECT& obj2 ) * found in this list * The component list **MUST** be sorted by reference and by unit number */ -void DeleteSubCmp( std::vector & aList ) +void DeleteSubCmp( std::vector< SCH_REFERENCE >& aList ) { SCH_COMPONENT* libItem; wxString oldName; @@ -252,6 +209,7 @@ void DeleteSubCmp( std::vector & aList ) for( unsigned ii = 0; ii < aList.size(); ii++ ) { libItem = aList[ii].m_RootCmp; + if( libItem == NULL ) continue; @@ -259,8 +217,7 @@ void DeleteSubCmp( std::vector & aList ) if( !oldName.IsEmpty() ) { - if( oldName == currName ) // currName is a subpart of oldName: - // remove it + if( oldName == currName ) // currName is a subpart of oldName: remove it { aList.erase( aList.begin() + ii ); ii--; diff --git a/eeschema/class_netlist_object.h b/eeschema/class_netlist_object.h index 7c384a2053..a40569cb39 100644 --- a/eeschema/class_netlist_object.h +++ b/eeschema/class_netlist_object.h @@ -123,4 +123,8 @@ public: } }; +// Buffer to build the list of items used in netlist and erc calculations +typedef std::vector NETLIST_OBJECT_LIST; + + #endif // _CLASS_NETLIST_OBJECT_H_ diff --git a/eeschema/dialogs/dialog_build_BOM.cpp b/eeschema/dialogs/dialog_build_BOM.cpp index 154761466e..7190aaa8d6 100644 --- a/eeschema/dialogs/dialog_build_BOM.cpp +++ b/eeschema/dialogs/dialog_build_BOM.cpp @@ -1,5 +1,4 @@ ///////////////////////////////////////////////////////////////////////////// - // Name: dialog_build_BOM.cpp // Author: jean-pierre Charras // Modified by: @@ -222,11 +221,12 @@ void DIALOG_BUILD_BOM::SavePreferences() s_ListBySheet = m_GenListLabelsbySheet->GetValue(); s_BrowseCreatedList = m_GetListBrowser->GetValue(); - // (aved in config ): + // (saved in config ): // Determine current settings of both radiobutton groups s_OutputFormOpt = m_OutputFormCtrl->GetSelection(); s_OutputSeparatorOpt = m_OutputSeparatorCtrl->GetSelection(); + if( s_OutputSeparatorOpt < 0 ) s_OutputSeparatorOpt = 0; @@ -249,10 +249,12 @@ void DIALOG_BUILD_BOM::SavePreferences() // Now save current settings of all "Fields to add" checkboxes long addfields = 0; + for( int ii = 0, bitmask = 1; s_AddFieldList[ii] != NULL; ii++ ) { if( *s_AddFieldList[ii] ) addfields |= bitmask; + bitmask <<= 1; } @@ -319,7 +321,7 @@ void DIALOG_BUILD_BOM::Create_BOM_Lists( int aTypeFile, GenereListeOfItems( m_ListFileName, aIncludeSubComponents ); break; - case 1: // speadsheet + case 1: // spreadsheet CreateExportList( m_ListFileName, aIncludeSubComponents ); break; @@ -390,9 +392,10 @@ void DIALOG_BUILD_BOM::CreatePartsList( const wxString& aFullFileName, bool aInc return; } - std::vector cmplist; + std::vector cmplist; + SCH_SHEET_LIST sheetList; // uses a global - BuildComponentsListFromSchematic( cmplist ); + sheetList.GetComponents( cmplist, false ); // sort component list by ref and remove sub components if( !aIncludeSubComponents ) @@ -428,8 +431,10 @@ void DIALOG_BUILD_BOM::CreateExportList( const wxString& aFullFileName, return; } - std::vector cmplist; - BuildComponentsListFromSchematic( cmplist ); + std::vector cmplist; + SCH_SHEET_LIST sheetList; // uses a global + + sheetList.GetComponents( cmplist, false ); // sort component list sort( cmplist.begin(), cmplist.end(), SortComponentsByReference ); @@ -464,17 +469,19 @@ void DIALOG_BUILD_BOM::GenereListeOfItems( const wxString& aFullFileName, return; } - std::vector cmplist; - BuildComponentsListFromSchematic( cmplist ); + std::vector cmplist; + SCH_SHEET_LIST sheetList; // uses a global + + sheetList.GetComponents( cmplist, false ); itemCount = cmplist.size(); + if( itemCount ) { // creates the list file DateAndTime( Line ); - wxString Title = wxGetApp().GetAppName() + wxT( " " ) + - GetBuildVersion(); + wxString Title = wxGetApp().GetAppName() + wxT( " " ) + GetBuildVersion(); fprintf( f, "%s >> Creation date: %s\n", CONV_TO_UTF8( Title ), Line ); @@ -569,11 +576,10 @@ void DIALOG_BUILD_BOM::PrintFieldData( FILE* f, SCH_COMPONENT* DrawLibItem, /* Print the B.O.M sorted by reference */ -int DIALOG_BUILD_BOM::PrintComponentsListByRef( - FILE* f, - std::vector & aList, - bool CompactForm, - bool aIncludeSubComponents ) +int DIALOG_BUILD_BOM::PrintComponentsListByRef( FILE* f, + std::vector & aList, + bool CompactForm, + bool aIncludeSubComponents ) { wxString msg; @@ -714,16 +720,14 @@ int DIALOG_BUILD_BOM::PrintComponentsListByRef( * This is true for most designs but will produce an * incorrect output if two or more parts with the same * value have different footprints, tolerances, voltage - * rating, etc. Also usefull if the following fields + * rating, etc. Also useful if the following fields * are edited: * FIELD1 - manufacture * FIELD2 - manufacture part number * FIELD3 - distributor part number */ -int DIALOG_BUILD_BOM::PrintComponentsListByPart( - FILE* f, - std::vector & aList, - bool aIncludeSubComponents) +int DIALOG_BUILD_BOM::PrintComponentsListByPart( FILE* f, std::vector & aList, + bool aIncludeSubComponents ) { int qty = 0; wxString refName; @@ -800,7 +804,7 @@ int DIALOG_BUILD_BOM::PrintComponentsListByPart( lastRef = refName; - // if the next cmoponent has same value the line will be printed after. + // if the next component has same value the line will be printed after. #if defined(KICAD_GOST) if( nextCmp && nextCmp->GetField( VALUE )->m_Text.CmpNoCase( valName ) == 0 && nextCmp->GetField( FOOTPRINT )->m_Text.CmpNoCase( footName ) == 0 @@ -856,10 +860,9 @@ int DIALOG_BUILD_BOM::PrintComponentsListByPart( } -int DIALOG_BUILD_BOM::PrintComponentsListByVal( - FILE* f, - std::vector & aList, - bool aIncludeSubComponents ) +int DIALOG_BUILD_BOM::PrintComponentsListByVal( FILE* f, + std::vector & aList, + bool aIncludeSubComponents ) { EDA_ITEM* schItem; SCH_COMPONENT* DrawLibItem; @@ -871,6 +874,7 @@ int DIALOG_BUILD_BOM::PrintComponentsListByVal( if( aIncludeSubComponents ) msg << _( " (with SubCmp)" ); + msg << wxT( "\n" ); fputs( CONV_TO_UTF8( msg ), f ); diff --git a/eeschema/dialogs/dialog_build_BOM.h b/eeschema/dialogs/dialog_build_BOM.h index 448e996c13..7f3aeb378d 100644 --- a/eeschema/dialogs/dialog_build_BOM.h +++ b/eeschema/dialogs/dialog_build_BOM.h @@ -46,13 +46,13 @@ private: */ void CreatePartsList( const wxString& aFullFileName, bool aIncludeSubComponents ); - int PrintComponentsListByRef( FILE* f, std::vector & aList, + int PrintComponentsListByRef( FILE* f, std::vector & aList, bool CompactForm, bool aIncludeSubComponents ); - int PrintComponentsListByVal( FILE* f, std::vector & aList, + int PrintComponentsListByVal( FILE* f, std::vector & aList, bool aIncludeSubComponents ); - int PrintComponentsListByPart( FILE* f, std::vector & aList, + int PrintComponentsListByPart( FILE* f, std::vector & aList, bool aIncludeSubComponents ); void PrintFieldData( FILE* f, SCH_COMPONENT* DrawLibItem, bool CompactForm = FALSE ); diff --git a/eeschema/dialogs/dialog_erc.cpp b/eeschema/dialogs/dialog_erc.cpp index 598862c7e9..df2794e55f 100644 --- a/eeschema/dialogs/dialog_erc.cpp +++ b/eeschema/dialogs/dialog_erc.cpp @@ -412,7 +412,9 @@ void DIALOG_ERC::TestErc( wxArrayString* aMessagesList ) m_writeErcFile = m_WriteResultOpt->GetValue(); - ReAnnotatePowerSymbolsOnly(); + /* Build the whole sheet list in hierarchy (sheet, not screen) */ + SCH_SHEET_LIST sheets; + sheets.AnnotatePowerSymbols(); if( m_Parent->CheckAnnotate( aMessagesList, false ) ) { diff --git a/eeschema/eeschema_config.cpp b/eeschema/eeschema_config.cpp index 4c2f6db16d..f786d7d35e 100644 --- a/eeschema/eeschema_config.cpp +++ b/eeschema/eeschema_config.cpp @@ -12,7 +12,7 @@ #include "eeschema_id.h" #include "general.h" -#include "netlist.h" +#include "netlist_control.h" #include "protos.h" #include "libeditframe.h" #include "eeschema_config.h" diff --git a/eeschema/general.h b/eeschema/general.h index 509e3c1ebc..a1a13665a8 100644 --- a/eeschema/general.h +++ b/eeschema/general.h @@ -9,6 +9,7 @@ #include #include "block_commande.h" +#include "class_netlist_object.h" class SCH_ITEM; @@ -203,4 +204,12 @@ extern int g_ItemSelectetColor; // eeschema extern int g_InvisibleItemColor; +/* Global Variables */ + +extern NETLIST_OBJECT_LIST g_NetObjectslist; + +extern bool g_OptNetListUseNames; /* TRUE to use names rather than + * net numbers. SPICE netlist only + */ + #endif // _GENERAL_H_ diff --git a/eeschema/netform.cpp b/eeschema/netform.cpp index 86f56e1e95..5832e820f6 100644 --- a/eeschema/netform.cpp +++ b/eeschema/netform.cpp @@ -42,6 +42,7 @@ #include "general.h" #include "netlist.h" +#include "netlist_control.h" #include "protos.h" #include "class_library.h" #include "lib_pin.h" @@ -143,7 +144,7 @@ class EXPORT_HELP /** * Function eraseDuplicatePins - * removes duplicate Pins fromt the pin list, m_SortedComponentPinList. + * removes duplicate Pins from the pin list, m_SortedComponentPinList. * (This is a list of pins found in the whole schematic, for a single * component.) These duplicate pins were put in list because some pins (powers... ) * are found more than one time when we have a multiple parts per package @@ -725,7 +726,7 @@ XNODE* EXPORT_HELP::makeGenericLibParts() LIB_COMPONENT* lcomp = (LIB_COMPONENT*) *it; CMP_LIBRARY* library = lcomp->GetLibrary(); - m_Libraries.insert( library ); // inserts component's library iff unique + m_Libraries.insert( library ); // inserts component's library if unique XNODE* xlibpart; xlibparts->AddChild( xlibpart = node( sLibpart ) ); @@ -958,7 +959,7 @@ XNODE* EXPORT_HELP::makeGenericComponents() XNODE* xcomp; // current component being constructed - // Output the component's elments in order of expected access frequency. + // Output the component's elements in order of expected access frequency. // This may not always look best, but it will allow faster execution // under XSL processing systems which do sequential searching within // an element. @@ -1015,8 +1016,8 @@ XNODE* EXPORT_HELP::makeGenericComponents() timeStamp.Printf( sTSFmt, comp->m_TimeStamp ); xcomp->AddChild( node( sTStamp, timeStamp ) ); - // Add pins list for this cmponent. - // Usedful to build netlist which have pads connection inside the footprint description + // Add pins list for this component. + // Useful to build netlist which have pads connection inside the footprint description // (Spice, OrcadPCB2 ...) XNODE* xpinslist; xcomp->AddChild( xpinslist = node( sPins ) ); @@ -1086,7 +1087,7 @@ bool EXPORT_HELP::WriteGENERICNetList( SCH_EDIT_FRAME* frame, const wxString& aO return xdoc.Save( aOutFileName, 2 /* indent bug, today was ignored by wxXml lib */ ); -#else // ouput the well established/old generic net list format which was not XML. +#else // output the well established/old generic net list format which was not XML. wxString field; wxString footprint; @@ -1341,7 +1342,7 @@ bool EXPORT_HELP::WriteNetListPCBNEW( SCH_EDIT_FRAME* frame, FILE* f, bool with_ int ret = 0; // zero now, OR in the sign bit on error wxString netName; - std::vector cmpList; + std::vector< SCH_REFERENCE > cmpList; DateAndTime( dateBuf ); @@ -1361,6 +1362,7 @@ bool EXPORT_HELP::WriteNetListPCBNEW( SCH_EDIT_FRAME* frame, FILE* f, bool with_ for( EDA_ITEM* item = path->LastDrawList(); item; item = item->Next() ) { SCH_COMPONENT* comp = findNextComponentAndCreatPinList( item, path ); + if( !comp ) break; @@ -1375,8 +1377,7 @@ bool EXPORT_HELP::WriteNetListPCBNEW( SCH_EDIT_FRAME* frame, FILE* f, bool with_ { if( entry->GetFootPrints().GetCount() != 0 ) // Put in list { - cmpList.push_back( OBJ_CMP_TO_LIST() ); - + cmpList.push_back( SCH_REFERENCE() ); cmpList.back().m_RootCmp = comp; cmpList.back().SetRef( comp->GetRef( path ) ); } diff --git a/eeschema/netlist.cpp b/eeschema/netlist.cpp index 9e967c6cec..942dcba524 100644 --- a/eeschema/netlist.cpp +++ b/eeschema/netlist.cpp @@ -65,6 +65,98 @@ void dumpNetTable() #endif +SCH_REFERENCE::SCH_REFERENCE( SCH_COMPONENT* aComponent, LIB_COMPONENT* aLibComponent, + SCH_SHEET_PATH& aSheetPath ) +{ + wxASSERT( aComponent != NULL && aLibComponent != NULL ); + + m_RootCmp = aComponent; + m_Entry = aLibComponent; + m_Unit = aComponent->GetUnitSelection( &aSheetPath ); + m_SheetPath = aSheetPath; + m_IsNew = false; + m_Flag = 0; + m_TimeStamp = aComponent->m_TimeStamp; + + if( aComponent->GetRef( &aSheetPath ).IsEmpty() ) + aComponent->SetRef( &aSheetPath, wxT( "DefRef?" ) ); + + SetRef( aComponent->GetRef( &aSheetPath ) ); + + m_NumRef = -1; + + if( aComponent->GetField( VALUE )->GetText().IsEmpty() ) + aComponent->GetField( VALUE )->SetText( wxT( "~" ) ); + + m_Value = &aComponent->GetField( VALUE )->m_Text; +} + + +void SCH_REFERENCE::Annotate() +{ + if( m_NumRef < 0 ) + m_Ref += wxChar( '?' ); + else + m_Ref = CONV_TO_UTF8( GetRef() << m_NumRef ); + + m_RootCmp->SetRef( &m_SheetPath, CONV_FROM_UTF8( m_Ref.c_str() ) ); + m_RootCmp->SetUnit( m_Unit ); + m_RootCmp->SetUnitSelection( &m_SheetPath, m_Unit ); +} + + +void SCH_REFERENCE::Split() +{ + std::string refText = GetRefStr(); + + m_NumRef = -1; + + int ll = refText.length() - 1; + + if( refText[ll] == '?' ) + { + m_IsNew = true; + + if( !IsPartsLocked() ) + m_Unit = 0x7FFFFFFF; + + refText.erase( ll ); // delete last char + + SetRefStr( refText ); + } + else if( isdigit( refText[ll] ) == 0 ) + { + m_IsNew = true; + + if( !IsPartsLocked() ) + m_Unit = 0x7FFFFFFF; + } + else + { + while( ll >= 0 ) + { + if( (refText[ll] <= ' ' ) || isdigit( refText[ll] ) ) + ll--; + else + { + if( isdigit( refText[ll + 1] ) ) + { + // null terminated C string into cp + const char* cp = refText.c_str() + ll + 1; + + m_NumRef = atoi( cp ); + } + + refText.erase( ll+1 ); // delete from ll+1 to end + break; + } + } + + SetRefStr( refText ); + } +} + + /* * Routine to free memory used to calculate the netlist TabNetItems = pointer * to the main table (list items) @@ -369,8 +461,8 @@ void FindBestNetNameForEachNet( NETLIST_OBJECT_LIST& aNetItemBuffer ) * @param aLabelItemBuffer = list of NETLIST_OBJECT type labels candidates. * labels are local labels, hierarchical labels or pin labels * labels in included sheets have a lower priority than labels in the current sheet. - * so labels inside the root sheet have the highter priority. - * pin labels are global labels and have the highter priority + * so labels inside the root sheet have the higher priority. + * pin labels are global labels and have the higher priority * local labels have the lower priority * labels having the same priority are sorted by alphabetic order. * @@ -434,7 +526,7 @@ static NETLIST_OBJECT* FindBestNetName( NETLIST_OBJECT_LIST& aLabelItemBuffer ) } else // not global: names are prefixed by their sheetpath { - // use name defined in highter hierarchical sheet + // use name defined in higher hierarchical sheet // (i.e. shorter path because paths are ///... // and timestamp = 8 letters. if( candidate->m_SheetList.Path().Length() < item->m_SheetList.Path().Length() ) diff --git a/eeschema/netlist.h b/eeschema/netlist.h index 08ad913f1d..8180278293 100644 --- a/eeschema/netlist.h +++ b/eeschema/netlist.h @@ -9,6 +9,7 @@ #include "macros.h" #include "class_libentry.h" +#include "sch_sheet_path.h" class SCH_COMPONENT; @@ -18,37 +19,19 @@ class SCH_COMPONENT; #define ISBUS 1 -#define CUSTOMPANEL_COUNTMAX 8 // Max number of netlist plugins - -#include "class_netlist_object.h" - -/* Id to select netlist type */ -enum TypeNetForm { - NET_TYPE_UNINIT = 0, - NET_TYPE_PCBNEW, - NET_TYPE_ORCADPCB2, - NET_TYPE_CADSTAR, - NET_TYPE_SPICE, - NET_TYPE_CUSTOM1, /* NET_TYPE_CUSTOM1 - * is the first id for user netlist format - * NET_TYPE_CUSTOM1+CUSTOMPANEL_COUNTMAX-1 - * is the last id for user netlist format - */ - NET_TYPE_CUSTOM_MAX = NET_TYPE_CUSTOM1 + CUSTOMPANEL_COUNTMAX - 1 -}; - - /* Max pin number per component and footprint */ #define MAXPIN 5000 -/* object used in annotation to handle a list of components in schematic - * because in a complex hierarchy, a component is used more than once, - * and its reference is depending on the sheet path - * for the same component, we must create a flat list of components - * used in nelist generation, BOM generation and annotation +/** + * Class SCH_REFERENCE + * is used as a helper to define a component's reference designator in a schematic. This + * helper is required in a complex hierarchy because a component can be used more than + * once and its reference depends on the sheet path. This class is used to flatten the + * schematic hierarchy for annotation, net list generation, and bill of material + * generation. */ -class OBJ_CMP_TO_LIST +class SCH_REFERENCE { private: /// Component reference prefix, without number (for IC1, this is IC) ) @@ -73,7 +56,7 @@ public: public: - OBJ_CMP_TO_LIST() + SCH_REFERENCE() { m_RootCmp = NULL; m_Entry = NULL; @@ -85,6 +68,24 @@ public: m_Flag = 0; } + SCH_REFERENCE( SCH_COMPONENT* aComponent, LIB_COMPONENT* aLibComponent, + SCH_SHEET_PATH& aSheetPath ); + + /** + * Function Annotate + * updates the annotation of the component according the the current object state. + */ + void Annotate(); + + /** + * Function Split + * attempts to split the reference designator into a name (U) and number (1). If the + * last character is '?' or not a digit, the reference is tagged as not annotated. + * For components with multiple parts per package that are not already annotated, set + * m_Unit to a max value (0x7FFFFFFF). + */ + void Split(); + /* Some accessors which hide the strategy of how the reference is stored, thereby making it easy to change that strategy. */ @@ -108,13 +109,13 @@ public: } - int CompareValue( const OBJ_CMP_TO_LIST& item ) const + int CompareValue( const SCH_REFERENCE& item ) const { return m_Value->CmpNoCase( *item.m_Value ); } - int CompareRef( const OBJ_CMP_TO_LIST& item ) const + int CompareRef( const SCH_REFERENCE& item ) const { return m_Ref.compare( item.m_Ref ); } @@ -127,29 +128,4 @@ public: }; -/* Global Variables */ - -// Buffer to build the list of items used in netlist and erc calculations -typedef std::vector NETLIST_OBJECT_LIST; -extern NETLIST_OBJECT_LIST g_NetObjectslist; - -extern bool g_OptNetListUseNames; /* TRUE to use names rather than - * net numbers. SPICE netlist only - */ - -/* Prototypes: */ -void FreeNetObjectsList( std::vector & aNetObjectslist ); - -/** - * Function ReturnUserNetlistTypeName - * to retrieve user netlist type names - * @param first_item = true: return first name of the list, false = return next - * @return a wxString : name of the type netlist or empty string - * this function must be called first with "first_item" = true - * and after with "first_item" = false to get all the other existing netlist - * names - */ -wxString ReturnUserNetlistTypeName( bool first_item ); - - #endif diff --git a/eeschema/netlist_control.cpp b/eeschema/netlist_control.cpp index a587a245df..980d58532c 100644 --- a/eeschema/netlist_control.cpp +++ b/eeschema/netlist_control.cpp @@ -517,7 +517,8 @@ void WinEDA_NetlistFrame::GenNetlist( wxCommandEvent& event ) bool SCH_EDIT_FRAME::CreateNetlist( int aFormat, const wxString& aFullFileName, bool aUse_netnames ) { - ReAnnotatePowerSymbolsOnly(); + SCH_SHEET_LIST sheets; + sheets.AnnotatePowerSymbols(); // Performs some controls: if( CheckAnnotate( NULL, 0 ) ) @@ -534,19 +535,8 @@ bool SCH_EDIT_FRAME::CreateNetlist( int aFormat, const wxString& aFullFileName, } /* Cleanup the entire hierarchy */ - SCH_SCREENS ScreenList; - for( SCH_SCREEN* screen = ScreenList.GetFirst(); - screen != NULL; - screen = ScreenList.GetNext() ) - { - bool ModifyWires; - ModifyWires = screen->SchematicCleanUp( NULL ); - - // if wire list has changed, delete the Undo Redo list to avoid - // pointer problems with deleted data - if( ModifyWires ) - screen->ClearUndoRedoList(); - } + SCH_SCREENS screens; + screens.SchematicCleanUp(); BuildNetListBase(); bool success = WriteNetListFile( aFormat, aFullFileName, g_OptNetListUseNames ); @@ -555,23 +545,18 @@ bool SCH_EDIT_FRAME::CreateNetlist( int aFormat, const wxString& aFullFileName, } -/***********************************************************/ void WinEDA_NetlistFrame::OnCancelClick( wxCommandEvent& event ) -/***********************************************************/ { EndModal( NET_ABORT ); } -/***********************************************************/ void WinEDA_NetlistFrame::RunSimulator( wxCommandEvent& event ) -/***********************************************************/ { wxFileName fn; wxString ExecFile, CommandLine; - g_SimulatorCommandLine = - m_PanelNetType[PANELSPICE]->m_CommandStringCtrl->GetValue(); + g_SimulatorCommandLine = m_PanelNetType[PANELSPICE]->m_CommandStringCtrl->GetValue(); g_SimulatorCommandLine.Trim( FALSE ); g_SimulatorCommandLine.Trim( TRUE ); ExecFile = g_SimulatorCommandLine.BeforeFirst( ' ' ); diff --git a/eeschema/netlist_control.h b/eeschema/netlist_control.h index b71fe0a912..903103ef39 100644 --- a/eeschema/netlist_control.h +++ b/eeschema/netlist_control.h @@ -7,6 +7,9 @@ #ifndef _NETLIST_CONTROL_H_ #define _NETLIST_CONTROL_H_ +class WinEDA_EnterText; + + /* Event id for notebook page buttons: */ enum id_netlist { ID_CREATE_NETLIST = 1550, @@ -67,6 +70,24 @@ public: }; +#define CUSTOMPANEL_COUNTMAX 8 // Max number of netlist plugins + +/* Id to select netlist type */ +enum TypeNetForm { + NET_TYPE_UNINIT = 0, + NET_TYPE_PCBNEW, + NET_TYPE_ORCADPCB2, + NET_TYPE_CADSTAR, + NET_TYPE_SPICE, + NET_TYPE_CUSTOM1, /* NET_TYPE_CUSTOM1 + * is the first id for user netlist format + * NET_TYPE_CUSTOM1+CUSTOMPANEL_COUNTMAX-1 + * is the last id for user netlist format + */ + NET_TYPE_CUSTOM_MAX = NET_TYPE_CUSTOM1 + CUSTOMPANEL_COUNTMAX - 1 +}; + + /* Dialog frame for creating netlists */ class WinEDA_NetlistFrame : public wxDialog { diff --git a/eeschema/protos.h b/eeschema/protos.h index 9006c30a47..3195f43cf3 100644 --- a/eeschema/protos.h +++ b/eeschema/protos.h @@ -25,7 +25,7 @@ class PLOTTER; class SCH_SHEET; class LIB_PIN; class LABEL_OBJECT; -class OBJ_CMP_TO_LIST; +class NETLIST_OBJECT; wxString ReturnDefaultFieldName( int aFieldNdx ); @@ -66,6 +66,7 @@ void DeleteStruct( WinEDA_DrawPanel* panel, wxDC* DC, SCH_ITEM* DrawStruct // build_BOM.cpp + /** * Class LABEL_OBJECT * is used in build BOM to handle the list of labels in schematic @@ -88,20 +89,21 @@ public: LABEL_OBJECT() } }; -void BuildComponentsListFromSchematic( std::vector & aList ); + void GenListeGLabels( std::vector & aList ); -bool SortComponentsByReference( const OBJ_CMP_TO_LIST& obj1, const OBJ_CMP_TO_LIST& obj2 ); -bool SortComponentsByValue( const OBJ_CMP_TO_LIST& obj1, const OBJ_CMP_TO_LIST& obj2 ); +bool SortComponentsByReference( const SCH_REFERENCE& obj1, const SCH_REFERENCE& obj2 ); +bool SortComponentsByValue( const SCH_REFERENCE& obj1, const SCH_REFERENCE& obj2 ); bool SortLabelsByValue( const LABEL_OBJECT& obj1, const LABEL_OBJECT& obj2 ); bool SortLabelsBySheet( const LABEL_OBJECT& obj1, const LABEL_OBJECT& obj2 ); -void DeleteSubCmp( std::vector & aList ); +void DeleteSubCmp( std::vector< SCH_REFERENCE >& aList ); int PrintListeGLabel( FILE* f, std::vector & aList ); // operations_on_item_lists.cpp + /** * Function DuplicateStruct - * Routine to create a new copy of given struct. + * creates a new copy of given struct. * @param aDrawStruct = the SCH_ITEM to duplicate * @param aClone (defualt = true) * if true duplicate also some parameters that must be unique @@ -194,12 +196,6 @@ EDA_Colors ReturnLayerColor( int Layer ); /**************/ int IsBusLabel( const wxString& LabelDrawList ); -/***************/ -/* ANNOTATE.CPP */ -/***************/ -void ReAnnotatePowerSymbolsOnly(); - - /************/ /* PLOT.CPP */ /************/ @@ -312,4 +308,19 @@ void DisplayOptionFrame( SCH_EDIT_FRAME* parent, const wxPoint& framepos ); /****************/ void RemoteCommand( const char* cmdline ); + +/* Prototypes in netlist_control.cpp */ +void FreeNetObjectsList( std::vector & aNetObjectslist ); + +/** + * Function ReturnUserNetlistTypeName + * to retrieve user netlist type names + * @param first_item = true: return first name of the list, false = return next + * @return a wxString : name of the type netlist or empty string + * this function must be called first with "first_item" = true + * and after with "first_item" = false to get all the other existing netlist + * names + */ +wxString ReturnUserNetlistTypeName( bool first_item ); + #endif /* __PROTOS_H__ */ diff --git a/eeschema/sch_component.cpp b/eeschema/sch_component.cpp index 1795bace79..b654db89a8 100644 --- a/eeschema/sch_component.cpp +++ b/eeschema/sch_component.cpp @@ -622,7 +622,7 @@ void SCH_COMPONENT::Place( SCH_EDIT_FRAME* frame, wxDC* DC ) } -void SCH_COMPONENT::ClearAnnotation( SCH_SHEET_PATH* aSheet ) +void SCH_COMPONENT::ClearAnnotation( SCH_SHEET_PATH* aSheetPath ) { wxString defRef = m_prefix; bool KeepMulti = false; @@ -648,15 +648,15 @@ void SCH_COMPONENT::ClearAnnotation( SCH_SHEET_PATH* aSheet ) wxString NewHref; wxString path; - if( aSheet ) - path = GetPath( aSheet ); + if( aSheetPath ) + path = GetPath( aSheetPath ); for( unsigned int ii = 0; ii < m_PathsAndReferences.GetCount(); ii++ ) { // Break hierarchical reference in path, ref and multi selection: reference_fields = wxStringTokenize( m_PathsAndReferences[ii], separators ); - if( aSheet == NULL || reference_fields[0].Cmp( path ) == 0 ) + if( aSheetPath == NULL || reference_fields[0].Cmp( path ) == 0 ) { if( KeepMulti ) // Get and keep part selection multi = reference_fields[2]; @@ -680,6 +680,8 @@ void SCH_COMPONENT::ClearAnnotation( SCH_SHEET_PATH* aSheet ) // UpdateAllScreenReferences for the active sheet. // But this call cannot made here. m_Fields[REFERENCE].m_Text = defRef; //for drawing. + + SetModified(); } diff --git a/eeschema/sch_component.h b/eeschema/sch_component.h index 49773edcf4..42e8982b1f 100644 --- a/eeschema/sch_component.h +++ b/eeschema/sch_component.h @@ -44,8 +44,8 @@ class SCH_COMPONENT : public SCH_ITEM /** * Defines the hierarchical path and reference of the component. This allowa support * for hierarchical sheets that reference the same schematic. The foramt for the path - * is /<sheet time stamp>/<sheet time stamp>/... A single / denotes the root - * sheet. + * is /<sheet time stamp>/<sheet time stamp>/.../&lscomponent time stamp>. + * A single / denotes the root sheet. */ wxArrayString m_PathsAndReferences; @@ -168,10 +168,10 @@ public: /** * Function ClearAnnotation * clears exiting component annotation ( i.i IC23 changed to IC? and part reset to 1) - * @param aSheet: SCH_SHEET_PATH value: if NULL remove all annotations, - * else remove annotation relative to this sheetpath + * @param aSheetPath: SCH_SHEET_PATH value: if NULL remove all annotations, + * else remove annotation relative to this sheetpath */ - void ClearAnnotation( SCH_SHEET_PATH* aSheet ); + void ClearAnnotation( SCH_SHEET_PATH* aSheetPath ); /** * Function SetTimeStamp diff --git a/eeschema/sch_screen.cpp b/eeschema/sch_screen.cpp index 519e2de2ee..8b2c155875 100644 --- a/eeschema/sch_screen.cpp +++ b/eeschema/sch_screen.cpp @@ -12,6 +12,7 @@ #include "general.h" #include "protos.h" +#include "netlist.h" #include "class_library.h" #include "sch_items.h" #include "sch_line.h" @@ -418,10 +419,57 @@ int SCH_SCREEN::CountConnectedItems( const wxPoint& aPos, bool aTestJunctions ) } +void SCH_SCREEN::ClearAnnotation( SCH_SHEET_PATH* aSheetPath ) +{ + for( SCH_ITEM* item = GetDrawItems(); item != NULL; item = item->Next() ) + { + if( item->Type() == SCH_COMPONENT_T ) + { + SCH_COMPONENT* component = (SCH_COMPONENT*) item; + + component->ClearAnnotation( aSheetPath ); + } + } +} + + +void SCH_SCREEN::GetHierarchicalItems( std::vector aItems ) +{ + SCH_ITEM* item = GetDrawItems(); + + while( item ) + { + if( ( item->Type() == SCH_SHEET_T ) || ( item->Type() == SCH_COMPONENT_T ) ) + aItems.push_back( item ); + + item = item->Next(); + } +} + + /******************************************************************/ /* Class SCH_SCREENS to handle the list of screens in a hierarchy */ /******************************************************************/ +/** + * Function SortByTimeStamp + * sorts a list of schematic items by time stamp and type. + */ +static bool SortByTimeStamp( const SCH_ITEM* item1, const SCH_ITEM* item2 ) +{ + int ii = item1->m_TimeStamp - item2->m_TimeStamp; + + /* If the time stamps are the same, compare type in order to have component objects + * before sheet object. This is done because the changing the sheet time stamp + * before the component time stamp could cause the current annotation to be lost. + */ + if( ( ii == 0 && ( item1->Type() != item2->Type() ) ) && ( item1->Type() == SCH_SHEET_T ) ) + ii = -1; + + return ii < 0; +} + + SCH_SCREENS::SCH_SCREENS() { m_index = 0; @@ -503,3 +551,72 @@ void SCH_SCREENS::BuildScreenList( EDA_ITEM* aItem ) } } } + + +void SCH_SCREENS::ClearAnnotation() +{ + for( size_t i = 0; i < m_screens.size(); i++ ) + m_screens[i]->ClearAnnotation( NULL ); +} + + +void SCH_SCREENS::SchematicCleanUp() +{ + for( size_t i = 0; i < m_screens.size(); i++ ) + { + // if wire list has changed, delete the undo/redo list to avoid + // pointer problems with deleted data. + if( m_screens[i]->SchematicCleanUp( NULL ) ) + m_screens[i]->ClearUndoRedoList(); + } +} + + +int SCH_SCREENS::ReplaceDuplicateTimeStamps() +{ + std::vector items; + SCH_ITEM* item; + + for( size_t i = 0; i < m_screens.size(); i++ ) + m_screens[i]->GetHierarchicalItems( items ); + + if( items.size() < 2 ) + return 0; + + sort( items.begin(), items.end(), SortByTimeStamp ); + + int count = 0; + + for( size_t ii = 0; ii < items.size() - 1; ii++ ) + { + item = items[ii]; + + SCH_ITEM* nextItem = items[ii + 1]; + + if( item->m_TimeStamp == nextItem->m_TimeStamp ) + { + count++; + + // for a component, update its Time stamp and its paths + // (m_PathsAndReferences field) + if( item->Type() == SCH_COMPONENT_T ) + ( (SCH_COMPONENT*) item )->SetTimeStamp( GetTimeStamp() ); + + // for a sheet, update only its time stamp (annotation of its + // components will be lost) + // @todo: see how to change sheet paths for its cmp list (can + // be possible in most cases) + else + item->m_TimeStamp = GetTimeStamp(); + } + } + + return count; +} + + +void SCH_SCREENS::SetDate( const wxString& aDate ) +{ + for( size_t i = 0; i < m_screens.size(); i++ ) + m_screens[i]->m_Date = aDate; +} diff --git a/eeschema/sch_sheet_path.cpp b/eeschema/sch_sheet_path.cpp index 8744e03726..a56c5c1261 100644 --- a/eeschema/sch_sheet_path.cpp +++ b/eeschema/sch_sheet_path.cpp @@ -15,6 +15,8 @@ #include "class_sch_screen.h" #include "sch_item_struct.h" +#include "netlist.h" +#include "class_library.h" #include "sch_sheet.h" #include "sch_sheet_path.h" #include "sch_component.h" @@ -55,16 +57,20 @@ bool SCH_SHEET_PATH::BuildSheetPathInfoFromSheetPathValue( const wxString& aPath return true; SCH_ITEM* schitem = LastDrawList(); + while( schitem && GetSheetsCount() < NB_MAX_SHEET ) { if( schitem->Type() == SCH_SHEET_T ) { SCH_SHEET* sheet = (SCH_SHEET*) schitem; Push( sheet ); + if( aPath == Path() ) return true; + if( BuildSheetPathInfoFromSheetPathValue( aPath ) ) return true; + Pop(); } schitem = schitem->Next(); @@ -84,17 +90,17 @@ int SCH_SHEET_PATH::Cmp( const SCH_SHEET_PATH& aSheetPathToTest ) const { if( m_numSheets > aSheetPathToTest.m_numSheets ) return 1; + if( m_numSheets < aSheetPathToTest.m_numSheets ) return -1; //otherwise, same number of sheets. for( unsigned i = 0; im_TimeStamp > - aSheetPathToTest.m_sheets[i]->m_TimeStamp ) + if( m_sheets[i]->m_TimeStamp > aSheetPathToTest.m_sheets[i]->m_TimeStamp ) return 1; - if( m_sheets[i]->m_TimeStamp < - aSheetPathToTest.m_sheets[i]->m_TimeStamp ) + + if( m_sheets[i]->m_TimeStamp < aSheetPathToTest.m_sheets[i]->m_TimeStamp ) return -1; } @@ -111,6 +117,7 @@ SCH_SHEET* SCH_SHEET_PATH::Last() { if( m_numSheets ) return m_sheets[m_numSheets - 1]; + return NULL; } @@ -122,8 +129,10 @@ SCH_SHEET* SCH_SHEET_PATH::Last() SCH_SCREEN* SCH_SHEET_PATH::LastScreen() { SCH_SHEET* lastSheet = Last(); + if( lastSheet ) return lastSheet->m_AssociatedScreen; + return NULL; } @@ -196,6 +205,7 @@ SCH_SHEET* SCH_SHEET_PATH::Pop() m_numSheets--; return m_sheets[m_numSheets]; } + return NULL; } @@ -266,6 +276,69 @@ void SCH_SHEET_PATH::UpdateAllScreenReferences() } +void SCH_SHEET_PATH::AnnotatePowerSymbols( int* aReference ) +{ + int ref = 1; + + if( aReference != NULL ) + ref = *aReference; + + for( EDA_ITEM* item = LastDrawList(); item != NULL; item = item->Next() ) + { + if( item->Type() != SCH_COMPONENT_T ) + continue; + + SCH_COMPONENT* component = (SCH_COMPONENT*) item; + LIB_COMPONENT* entry = CMP_LIBRARY::FindLibraryComponent( component->GetLibName() ); + + if( ( entry == NULL ) || !entry->IsPower() ) + continue; + + wxString refstr = component->GetPrefix(); + + //str will be "C?" or so after the ClearAnnotation call. + while( refstr.Last() == '?' ) + refstr.RemoveLast(); + + if( !refstr.StartsWith( wxT( "#" ) ) ) + refstr = wxT( "#" ) + refstr; + + refstr << wxT( "0" ) << ref; + component->SetRef( this, refstr ); + ref++; + } + + if( aReference != NULL ) + *aReference = ref; +} + + +void SCH_SHEET_PATH::GetComponents( std::vector< SCH_REFERENCE >& aReferences, + bool aIncludePowerSymbols ) +{ + for( SCH_ITEM* item = LastDrawList(); item != NULL; item = item->Next() ) + { + if( item->Type() == SCH_COMPONENT_T ) + { + SCH_COMPONENT* component = (SCH_COMPONENT*) item; + + // Skip pseudo components, which have a reference starting with #. This mainly + // effects power symbols. + if( !aIncludePowerSymbols && component->GetRef( this )[0] == wxT( '#' ) ) + continue; + + LIB_COMPONENT* entry = CMP_LIBRARY::FindLibraryComponent( component->GetLibName() ); + + if( entry == NULL ) + continue; + + SCH_REFERENCE reference = SCH_REFERENCE( component, entry, *this ); + aReferences.push_back( reference ); + } + } +} + + SCH_ITEM* SCH_SHEET_PATH::FindNextItem( KICAD_T aType, SCH_ITEM* aLastItem, bool aWrap ) { bool hasWrapped = false; @@ -371,6 +444,7 @@ bool SCH_SHEET_PATH::operator=( const SCH_SHEET_PATH& d1 ) m_numSheets = d1.m_numSheets; unsigned i; + for( i = 0; i < m_numSheets; i++ ) { m_sheets[i] = d1.m_sheets[i]; @@ -437,8 +511,10 @@ SCH_SHEET_LIST::SCH_SHEET_LIST( SCH_SHEET* aSheet ) m_index = 0; m_count = 0; m_List = NULL; + if( aSheet == NULL ) aSheet = g_RootSheet; + BuildSheetList( aSheet ); } @@ -450,8 +526,10 @@ SCH_SHEET_LIST::SCH_SHEET_LIST( SCH_SHEET* aSheet ) SCH_SHEET_PATH* SCH_SHEET_LIST::GetFirst() { m_index = 0; + if( GetCount() > 0 ) return &( m_List[0] ); + return NULL; } @@ -465,6 +543,7 @@ SCH_SHEET_PATH* SCH_SHEET_LIST::GetNext() { if( m_index < GetCount() ) m_index++; + return GetSheet( m_index ); } @@ -501,6 +580,7 @@ SCH_SHEET_PATH* SCH_SHEET_LIST::GetSheet( int aIndex ) { if( aIndex < GetCount() ) return &( m_List[aIndex] ); + return NULL; } @@ -546,6 +626,23 @@ void SCH_SHEET_LIST::BuildSheetList( SCH_SHEET* aSheet ) } +void SCH_SHEET_LIST::AnnotatePowerSymbols() +{ + int ref = 1; + + for( SCH_SHEET_PATH* path = GetFirst(); path != NULL; path = GetNext() ) + path->AnnotatePowerSymbols( &ref ); +} + + +void SCH_SHEET_LIST::GetComponents( std::vector< SCH_REFERENCE >& aReferences, + bool aIncludePowerSymbols ) +{ + for( SCH_SHEET_PATH* path = GetFirst(); path != NULL; path = GetNext() ) + path->GetComponents( aReferences, aIncludePowerSymbols ); +} + + SCH_ITEM* SCH_SHEET_LIST::FindNextItem( KICAD_T aType, SCH_SHEET_PATH** aSheetFoundIn, SCH_ITEM* aLastItem, bool aWrap ) { @@ -566,6 +663,7 @@ SCH_ITEM* SCH_SHEET_LIST::FindNextItem( KICAD_T aType, SCH_SHEET_PATH** aSheetFo { if( aSheetFoundIn ) *aSheetFoundIn = sheet; + return drawItem; } else if( !firstItemFound && drawItem == aLastItem ) @@ -610,6 +708,7 @@ SCH_ITEM* SCH_SHEET_LIST::FindPreviousItem( KICAD_T aType, SCH_SHEET_PATH** aShe { if( aSheetFoundIn ) *aSheetFoundIn = sheet; + return drawItem; } else if( !firstItemFound && drawItem == aLastItem ) @@ -661,6 +760,7 @@ SCH_ITEM* SCH_SHEET_LIST::MatchNextItem( wxFindReplaceData& aSearchData, { if( aSheetFoundIn ) *aSheetFoundIn = sheet; + return drawItem; } } diff --git a/eeschema/sch_sheet_path.h b/eeschema/sch_sheet_path.h index 0a1425ce01..ba97253e42 100644 --- a/eeschema/sch_sheet_path.h +++ b/eeschema/sch_sheet_path.h @@ -55,6 +55,7 @@ class SCH_SCREEN; class SCH_MARKER; class SCH_SHEET; class SCH_ITEM; +class SCH_REFERENCE; /** @@ -185,6 +186,25 @@ public: */ void UpdateAllScreenReferences(); + /** + * Function AnnotatePowerSymbols + * annotates the power symbols only starting at \a aReference in the sheet path. + * @param aReference A pointer to the number for the reference designator of the + * first power symbol to be annotated. If the pointer is NULL + * the annotation starts at 1. The number is incremented for + * each power symbol annotated. + */ + void AnnotatePowerSymbols( int* aReference ); + + /** + * Function GetComponents + * adds a SCH_REFERENCE() object to \a aReferences for each component in the sheet. + * @param aReferences List of references to populate. + * @param aIncludePowerSymbols Set to false to only get normal components. + */ + void GetComponents( std::vector< SCH_REFERENCE >& aReferences, + bool aIncludePowerSymbols = true ); + /** * Find the next schematic item in this sheet ojbect. * @@ -230,7 +250,7 @@ public: /** * Class SCH_SHEET_LIST - * handles the list of Sheets in a hiearchy. + * handles the list of Sheets in a hierarchy. * Sheets are not unique, there can be many sheets with the same * filename and the same SCH_SCREEN reference. * The schematic (SCH_SCREEN) is shared between these sheets, @@ -316,6 +336,22 @@ public: */ SCH_SHEET_PATH* GetSheet( int aIndex ); + /** + * Function AnnotatePowerSymbols + * clear and annotates the entire hierarchy of the sheet path list. + */ + void AnnotatePowerSymbols(); + + /** + * Function GetComponents + * adds a SCH_REFERENCE() object to \a aReferences for each component in the list + * of sheets. + * @param aReferences List of references to populate. + * @param aIncludePowerSymbols Set to false to only get normal components. + */ + void GetComponents( std::vector< SCH_REFERENCE >& aReferences, + bool aIncludePowerSymbols = true ); + /** * Function FindNextItem * searches the entire schematic for the next schematic object. @@ -370,7 +406,7 @@ private: * @param aSheet is the starting sheet from which the list is built, * or NULL indicating that g_RootSheet should be used. */ - void BuildSheetList( SCH_SHEET* sheet ); + void BuildSheetList( SCH_SHEET* aSheet ); }; #endif // CLASS_DRAWSHEET_PATH_H diff --git a/eeschema/schframe.cpp b/eeschema/schframe.cpp index 9f6f9eadfc..9bfec40355 100644 --- a/eeschema/schframe.cpp +++ b/eeschema/schframe.cpp @@ -287,8 +287,10 @@ void SCH_EDIT_FRAME::SetSheetNumberAndCount() for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() ) { wxString sheetpath = sheet->Path(); + if( sheetpath == current_sheetpath ) // Current sheet path found break; + SheetNumber++; /* Not found, increment sheet * number before this current * path */ @@ -323,11 +325,13 @@ void SCH_EDIT_FRAME::CreateScreens() { g_RootSheet = new SCH_SHEET(); } + if( g_RootSheet->m_AssociatedScreen == NULL ) { g_RootSheet->m_AssociatedScreen = new SCH_SCREEN(); g_RootSheet->m_AssociatedScreen->m_RefCount++; } + g_RootSheet->m_AssociatedScreen->m_FileName = m_DefaultSchematicFileName; g_RootSheet->m_AssociatedScreen->m_Date = GenDate(); m_CurrentSheet->Clear(); @@ -335,6 +339,7 @@ void SCH_EDIT_FRAME::CreateScreens() if( GetBaseScreen() == NULL ) SetBaseScreen( new SCH_SCREEN() ); + GetBaseScreen()->SetZoom( 4 * GetBaseScreen()->m_ZoomScalar ); GetBaseScreen()->m_UndoRedoCountMax = 10; } diff --git a/include/base_struct.h b/include/base_struct.h index e4b8153fb4..a314a85572 100644 --- a/include/base_struct.h +++ b/include/base_struct.h @@ -757,6 +757,10 @@ public: * @return a wwString withe the style name( Normal, Italic, Bold, Bold+Italic) */ wxString GetTextStyleName(); + + void SetText( const wxString& aText ) { m_Text = aText; } + + wxString GetText() const { return m_Text; } }; #endif /* BASE_STRUCT_H */ diff --git a/include/class_sch_screen.h b/include/class_sch_screen.h index 471646c5df..e4696db625 100644 --- a/include/class_sch_screen.h +++ b/include/class_sch_screen.h @@ -12,7 +12,7 @@ class LIB_PIN; class SCH_COMPONENT; - +class SCH_SHEET_PATH; /* Max number of sheets in a hierarchy project: */ #define NB_MAX_SHEET 500 @@ -118,6 +118,21 @@ public: LIB_PIN* GetPin( const wxPoint& aPosition, SCH_COMPONENT** aComponent = NULL ); + /** + * Function ClearAnnotation + * clears the annotation for the components in \a aSheetPath on the screen. + * @param aSheetPath The sheet path of the component annotation to clear. If NULL then + * the entire heirarchy is cleared. + */ + void ClearAnnotation( SCH_SHEET_PATH* aSheetPath ); + + /** + * Function GetHierarchicalItems + * adds all schematica sheet and component object in the screen to \a aItems. + * @param aItems Hierarchical item list. + */ + void GetHierarchicalItems( std::vector aItems ); + virtual void AddItem( SCH_ITEM* aItem ) { BASE_SCREEN::AddItem( (EDA_ITEM*) aItem ); } virtual void InsertItem( EDA_ITEMS::iterator aIter, SCH_ITEM* aItem ) { @@ -145,6 +160,35 @@ public: SCH_SCREEN* GetNext(); SCH_SCREEN* GetScreen( unsigned int aIndex ); + /** + * Function ClearAnnotation + * clears the annotation for all components in the hierarchy. + */ + void ClearAnnotation(); + + /** + * Function SchematicCleanUp + * merges and breaks wire segments in the entire schematic hierarchy. + */ + void SchematicCleanUp(); + + /** + * Function ReplaceDuplicateTimeStamps + * test all sheet and component objects in the schematic for duplicate time stamps + * an replaces them as neccessary. Time stamps must be unique in order for complex + * hierarcies know which components go to which sheets. + * @return The number of duplicate time stamps replaced. + */ + int ReplaceDuplicateTimeStamps(); + + /** + * Function SetDate + * sets the date string for every screen to \a aDate. + * @see GetDate() + * @param aDate The date string to set for each screen. + */ + void SetDate( const wxString& aDate ); + private: void AddScreenToList( SCH_SCREEN* aScreen ); void BuildScreenList( EDA_ITEM* aItem ); diff --git a/include/wxEeschemaStruct.h b/include/wxEeschemaStruct.h index 26f5123f50..be91e2e12f 100644 --- a/include/wxEeschemaStruct.h +++ b/include/wxEeschemaStruct.h @@ -471,13 +471,6 @@ private: public: bool EditSheet( SCH_SHEET* Sheet, wxDC* DC ); - /** - * Function UpdateSheetNumberAndDate - * Set a sheet number, the sheet count for sheets in the whole schematic - * and update the date in all screens - */ - void UpdateSheetNumberAndDate(); - private: void StartMoveSheet( SCH_SHEET* sheet, wxDC* DC ); SCH_SHEET_PIN* Create_PinSheet( SCH_SHEET* Sheet, wxDC* DC );