SCH_COMPONENT* NETLIST_EXPORTER::findNextComponent( EDA_ITEM* aItem, SCH_SHEET_PATH* aSheetPath ) { wxString ref; // continue searching from the middle of a linked list (the draw list) for( ; aItem; aItem = aItem->Next() ) { if( aItem->Type() != SCH_COMPONENT_T ) continue; // found next component SCH_COMPONENT* comp = (SCH_COMPONENT*) aItem; // Power symbols and other components which have the reference starting // with "#" are not included in netlist (pseudo or virtual components) ref = comp->GetRef( aSheetPath ); if( ref[0] == wxChar( '#' ) ) continue; // if( Component->m_FlagControlMulti == 1 ) // continue; /* yes */ // removed because with multiple instances of one schematic // (several sheets pointing to 1 screen), this will be erroneously be // toggled. LIB_PART* part = m_libs->FindLibPart( comp->GetPartName() ); if( !part ) continue; // If component is a "multi parts per package" type if( part->GetUnitCount() > 1 ) { // test if this reference has already been processed, and if so skip if( m_ReferencesAlreadyFound.Lookup( ref ) ) continue; } // record the usage of this library component entry. m_LibParts.insert( part ); // rejects non-unique pointers return comp; } return NULL; }
void CMP_TREE_NODE_LIB_ID::Update( LIB_ALIAS* aAlias ) { Name = aAlias->GetName(); Desc = aAlias->GetDescription(); // Parent node is the library nickname so set the LIB_ID library nickname. IsRoot = aAlias->IsRoot(); // Pre-normalized strings for fast case-insensitive matching // Search text spaces out keywords and description to penalize description // matches - earlier matches are worth more. MatchName = aAlias->GetName().Lower(); SearchText = (aAlias->GetKeyWords() + " " + Desc); // Extract default footprint text LIB_PART* part = aAlias->GetPart(); wxString footprint; if( part ) { LibId = part->GetLibId(); LibId.SetLibItemName( Name ); footprint = part->GetFootprintField().GetText(); } // If a footprint is defined for the part, // add it to the serach string if( !footprint.IsEmpty() ) { SearchText += " "; SearchText += footprint; } Children.clear(); if( part && part->IsMulti() ) { for( int u = 1; u <= part->GetUnitCount(); ++u ) AddUnit( u ); } SearchTextNormalized = false; }
void SCH_EDIT_FRAME::OnSelectUnit( wxCommandEvent& aEvent ) { SCH_SCREEN* screen = GetScreen(); SCH_ITEM* item = screen->GetCurItem(); SCH_COMPONENT* component = (SCH_COMPONENT*) item; GetCanvas()->MoveCursorToCrossHair(); int unit = aEvent.GetId() + 1 - ID_POPUP_SCH_SELECT_UNIT1; LIB_PART* part = GetLibPart( component->GetLibId() ); if( !part ) return; int unitCount = part->GetUnitCount(); if( unitCount <= 1 || component->GetUnit() == unit ) return; if( unit > unitCount ) unit = unitCount; STATUS_FLAGS flags = component->GetFlags(); if( !flags ) // No command in progress: save in undo list SaveCopyInUndoList( component, UR_CHANGED ); /* Update the unit number. */ component->SetUnitSelection( g_CurrentSheet, unit ); component->SetUnit( unit ); component->ClearFlags(); component->SetFlags( flags ); // Restore m_Flag modified by SetUnit() if( m_autoplaceFields ) component->AutoAutoplaceFields( GetScreen() ); TestDanglingEnds(); RefreshItem( component ); OnModify(); }
void SCH_EDIT_FRAME::SelectUnit( SCH_COMPONENT* aComponent, int aUnit ) { GetCanvas()->MoveCursorToCrossHair(); LIB_PART* part = GetLibPart( aComponent->GetLibId() ); if( !part ) return; int unitCount = part->GetUnitCount(); if( unitCount <= 1 || aComponent->GetUnit() == aUnit ) return; if( aUnit > unitCount ) aUnit = unitCount; STATUS_FLAGS savedFlags = aComponent->GetFlags(); if( !aComponent->GetEditFlags() ) // No command in progress: save in undo list SaveCopyInUndoList( aComponent, UR_CHANGED ); /* Update the unit number. */ aComponent->SetUnitSelection( g_CurrentSheet, aUnit ); aComponent->SetUnit( aUnit ); aComponent->ClearFlags(); aComponent->SetFlags( savedFlags ); // Restore m_Flag modified by SetUnit() if( !aComponent->GetEditFlags() ) // No command in progress: update schematic { if( m_autoplaceFields ) aComponent->AutoAutoplaceFields( GetScreen() ); TestDanglingEnds(); RefreshItem( aComponent ); OnModify(); } }
void SCH_SHEET_PATH::GetMultiUnitComponents( PART_LIBS* aLibs, SCH_MULTI_UNIT_REFERENCE_MAP &aRefList, bool aIncludePowerSymbols ) { // Find sheet path number int sheetnumber = 1; // 1 = root SCH_SHEET_LIST sheetList; for( SCH_SHEET_PATH* path = sheetList.GetFirst(); path; path = sheetList.GetNext(), sheetnumber++ ) { if( Cmp( *path ) == 0 ) break; } for( SCH_ITEM* item = LastDrawList(); item; item = item->Next() ) { if( item->Type() != SCH_COMPONENT_T ) continue; SCH_COMPONENT* component = (SCH_COMPONENT*) item; // Skip pseudo components, which have a reference starting with #. This mainly // affects power symbols. if( !aIncludePowerSymbols && component->GetRef( this )[0] == wxT( '#' ) ) continue; LIB_PART* part = aLibs->FindLibPart( component->GetPartName() ); if( part && part->GetUnitCount() > 1 ) { SCH_REFERENCE reference = SCH_REFERENCE( component, part, *this ); reference.SetSheetNumber( sheetnumber ); wxString reference_str = reference.GetRef(); // Never lock unassigned references if( reference_str[reference_str.Len() - 1] == '?' ) continue; aRefList[reference_str].AddItem( reference ); } } }
bool DIALOG_LIB_EDIT_DRAW_ITEM::TransferDataToWindow() { LIB_PART* symbol = m_item->GetParent(); m_lineWidth.SetValue( m_item->GetWidth() ); m_checkApplyToAllUnits->SetValue( m_item->GetUnit() == 0 ); m_checkApplyToAllUnits->Enable( symbol && symbol->GetUnitCount() > 1 ); m_checkApplyToAllConversions->SetValue( m_item->GetConvert() == 0 ); bool enblConvOptStyle = symbol && symbol->HasConversion(); // if a symbol contains no graphic items, symbol->HasConversion() returns false. // but when creating a new symbol, with DeMorgan option set, the ApplyToAllConversions // must be enabled even if symbol->HasConversion() returns false in order to be able // to create graphic items shared by all body styles if( m_frame->GetShowDeMorgan() ) enblConvOptStyle = true; m_checkApplyToAllConversions->Enable( enblConvOptStyle ); m_fillCtrl->SetSelection( m_item->GetFillMode() ); m_fillCtrl->Enable( m_item->IsFillable() ); return true; }
void LIB_EDIT_FRAME::OnCheckComponent( wxCommandEvent& event ) { LIB_PART* part = GetCurPart(); if( !part ) return; const int MIN_GRID_SIZE = 25; LIB_PINS pinList; part->GetPins( pinList ); if( pinList.size() == 0 ) { DisplayInfoMessage( this, _( "No pins!" ) ); return; } // Sort pins by pin num, so 2 duplicate pins // (pins with the same number) will be consecutive in list sort( pinList.begin(), pinList.end(), sort_by_pin_number ); // Test for duplicates: DIALOG_DISPLAY_HTML_TEXT_BASE error_display( this, wxID_ANY, _( "Marker Information" ), wxDefaultPosition, wxSize( 750, 600 ) ); int dup_error = 0; for( unsigned ii = 1; ii < pinList.size(); ii++ ) { wxString stringPinNum, stringCurrPinNum; LIB_PIN* curr_pin = pinList[ii]; LIB_PIN* pin = pinList[ii - 1]; if( pin->GetNumber() != curr_pin->GetNumber() || pin->GetConvert() != curr_pin->GetConvert() || pin->GetUnit() != curr_pin->GetUnit() ) continue; dup_error++; pin->PinStringNum( stringPinNum ); /* TODO I dare someone to find a way to make happy translators on this thing! Lorenzo */ curr_pin->PinStringNum( stringCurrPinNum ); wxString msg = wxString::Format( _( "<b>Duplicate pin %s</b> \"%s\" at location <b>(%.3f, %.3f)</b>" " conflicts with pin %s \"%s\" at location <b>(%.3f, %.3f)</b>" ), GetChars( stringCurrPinNum ), GetChars( curr_pin->GetName() ), curr_pin->GetPosition().x / 1000.0, -curr_pin->GetPosition().y / 1000.0, GetChars( stringPinNum ), GetChars( pin->GetName() ), pin->GetPosition().x / 1000.0, -pin->GetPosition().y / 1000.0 ); if( part->GetUnitCount() > 1 ) { msg += wxString::Format( _( " in part %c" ), 'A' + curr_pin->GetUnit() - 1 ); } if( m_showDeMorgan ) { if( curr_pin->GetConvert() ) msg += _( " of converted" ); else msg += _( " of normal" ); } msg += wxT( ".<br>" ); error_display.m_htmlWindow->AppendToPage( msg ); } // Test for off grid pins: int offgrid_error = 0; for( unsigned ii = 0; ii < pinList.size(); ii++ ) { LIB_PIN* pin = pinList[ii]; if( ( (pin->GetPosition().x % MIN_GRID_SIZE) == 0 ) && ( (pin->GetPosition().y % MIN_GRID_SIZE) == 0 ) ) continue; // "pin" is off grid here. offgrid_error++; wxString stringPinNum; pin->PinStringNum( stringPinNum ); wxString msg = wxString::Format( _( "<b>Off grid pin %s</b> \"%s\" at location <b>(%.3f, %.3f)</b>" ), GetChars( stringPinNum ), GetChars( pin->GetName() ), pin->GetPosition().x / 1000.0, -pin->GetPosition().y / 1000.0 ); if( part->GetUnitCount() > 1 ) { msg += wxString::Format( _( " in part %c" ), 'A' + pin->GetUnit() - 1 ); } if( m_showDeMorgan ) { if( pin->GetConvert() ) msg += _( " of converted" ); else msg += _( " of normal" ); } msg += wxT( ".<br>" ); error_display.m_htmlWindow->AppendToPage( msg ); } if( !dup_error && !offgrid_error ) DisplayInfoMessage( this, _( "No off grid or duplicate pins were found." ) ); else error_display.ShowModal(); }
void LIB_EDIT_FRAME::EditGraphicSymbol( wxDC* DC, LIB_ITEM* DrawItem ) { if( DrawItem == NULL ) return; LIB_PART* symbol = DrawItem->GetParent(); DIALOG_LIB_EDIT_DRAW_ITEM dialog( this, DrawItem->GetTypeName() ); dialog.SetWidthUnits( ReturnUnitSymbol( g_UserUnit ) ); wxString val = StringFromValue( g_UserUnit, DrawItem->GetWidth() ); dialog.SetWidth( val ); dialog.SetApplyToAllUnits( DrawItem->GetUnit() == 0 ); dialog.EnableApplyToAllUnits( symbol && symbol->GetUnitCount() > 1 ); dialog.SetApplyToAllConversions( DrawItem->GetConvert() == 0 ); bool enblConvOptStyle = symbol && symbol->HasConversion(); // if a symbol contains no graphic items, symbol->HasConversion() returns false. // but when creating a new symbol, with DeMorgan option set, the ApplyToAllConversions // must be enabled even if symbol->HasConversion() returns false in order to be able // to create graphic items shared by all body styles if( GetShowDeMorgan() ) enblConvOptStyle = true; dialog.EnableApplyToAllConversions( enblConvOptStyle ); dialog.SetFillStyle( DrawItem->GetFillMode() ); dialog.EnableFillStyle( DrawItem->IsFillable() ); if( dialog.ShowModal() == wxID_CANCEL ) return; // Init default values (used to create a new draw item) val = dialog.GetWidth(); m_drawLineWidth = ValueFromString( g_UserUnit, val ); m_drawSpecificConvert = !dialog.GetApplyToAllConversions(); m_drawSpecificUnit = !dialog.GetApplyToAllUnits(); #if 0 /* TODO: see if m_drawFillStyle must retain the last fill option or not. * if the last is Filled, having next new graphic items created * with filled body is often bad. * currently m_drawFillStyle is left with the default value (not filled) */ if( DrawItem->IsFillable() ) m_drawFillStyle = (FILL_T) dialog.GetFillStyle(); #endif // Save copy for undo if not in edit (edit command already handle the save copy) if( !DrawItem->InEditMode() ) SaveCopyInUndoList( DrawItem->GetParent() ); if( m_drawSpecificUnit ) DrawItem->SetUnit( GetUnit() ); else DrawItem->SetUnit( 0 ); if( m_drawSpecificConvert ) DrawItem->SetConvert( GetConvert() ); else DrawItem->SetConvert( 0 ); if( DrawItem->IsFillable() ) DrawItem->SetFillMode( (FILL_T) dialog.GetFillStyle() ); DrawItem->SetWidth( m_drawLineWidth ); OnModify( ); MSG_PANEL_ITEMS items; DrawItem->GetMsgPanelInfo( items ); SetMsgPanel( items ); m_canvas->Refresh(); }
SCH_COMPONENT* NETLIST_EXPORTER::findNextComponentAndCreatePinList( EDA_ITEM* aItem, SCH_SHEET_PATH* aSheetPath ) { wxString ref; m_SortedComponentPinList.clear(); // continue searching from the middle of a linked list (the draw list) for( ; aItem; aItem = aItem->Next() ) { if( aItem->Type() != SCH_COMPONENT_T ) continue; // found next component SCH_COMPONENT* comp = (SCH_COMPONENT*) aItem; // Power symbols and other components which have the reference starting // with "#" are not included in netlist (pseudo or virtual components) ref = comp->GetRef( aSheetPath ); if( ref[0] == wxChar( '#' ) ) continue; // if( Component->m_FlagControlMulti == 1 ) // continue; /* yes */ // removed because with multiple instances of one schematic // (several sheets pointing to 1 screen), this will be erroneously be // toggled. LIB_PART* part = m_libs->FindLibPart( comp->GetPartName() ); if( !part ) continue; // If component is a "multi parts per package" type if( part->GetUnitCount() > 1 ) { // test if this reference has already been processed, and if so skip if( m_ReferencesAlreadyFound.Lookup( ref ) ) continue; // Collect all pins for this reference designator by searching // the entire design for other parts with the same reference designator. // This is only done once, it would be too expensive otherwise. findAllInstancesOfComponent( comp, part, aSheetPath ); } else // entry->GetUnitCount() <= 1 means one part per package { LIB_PINS pins; // constructed once here part->GetPins( pins, comp->GetUnitSelection( aSheetPath ), comp->GetConvert() ); for( size_t i = 0; i < pins.size(); i++ ) { LIB_PIN* pin = pins[i]; wxASSERT( pin->Type() == LIB_PIN_T ); addPinToComponentPinList( comp, aSheetPath, pin ); } } // Sort pins in m_SortedComponentPinList by pin number sort( m_SortedComponentPinList.begin(), m_SortedComponentPinList.end(), sortPinsByNum ); // Remove duplicate Pins in m_SortedComponentPinList eraseDuplicatePins( ); // record the usage of this library component entry. m_LibParts.insert( part ); // rejects non-unique pointers return comp; } return NULL; }
void AddMenusForEditComponent( wxMenu* PopMenu, SCH_COMPONENT* Component, PART_LIBS* aLibs ) { if( Component->Type() != SCH_COMPONENT_T ) { wxASSERT( 0 ); return; } wxString msg; LIB_PART* part = NULL; LIB_ALIAS* libEntry = aLibs->FindLibraryEntry( Component->GetPartName() ); if( libEntry ) part = libEntry->GetPart(); wxMenu* editmenu = new wxMenu; msg = AddHotkeyName( _( "Edit" ), g_Schematic_Hokeys_Descr, HK_EDIT ); AddMenuItem( editmenu, ID_SCH_EDIT_ITEM, msg, KiBitmap( edit_component_xpm ) ); if( part && part->IsNormal() ) { msg = AddHotkeyName( _( "Value" ), g_Schematic_Hokeys_Descr, HK_EDIT_COMPONENT_VALUE ); AddMenuItem( editmenu, ID_SCH_EDIT_COMPONENT_VALUE, msg, KiBitmap( edit_comp_value_xpm ) ); msg = AddHotkeyName( _( "Reference" ), g_Schematic_Hokeys_Descr, HK_EDIT_COMPONENT_REFERENCE ); AddMenuItem( editmenu, ID_SCH_EDIT_COMPONENT_REFERENCE, msg, KiBitmap( edit_comp_ref_xpm ) ); msg = AddHotkeyName( _( "Footprint" ), g_Schematic_Hokeys_Descr, HK_EDIT_COMPONENT_FOOTPRINT ); AddMenuItem( editmenu, ID_SCH_EDIT_COMPONENT_FOOTPRINT, msg, KiBitmap( edit_comp_footprint_xpm ) ); } if( part && part->HasConversion() ) AddMenuItem( editmenu, ID_POPUP_SCH_EDIT_CONVERT_CMP, _( "Convert" ), KiBitmap( component_select_alternate_shape_xpm ) ); if( part && part->GetUnitCount() >= 2 ) { wxMenu* sel_unit_menu = new wxMenu; int ii; for( ii = 0; ii < part->GetUnitCount(); ii++ ) { wxString num_unit; int unit = Component->GetUnit(); num_unit.Printf( _( "Unit %s" ), GetChars( LIB_PART::SubReference( ii + 1, false ) ) ); wxMenuItem * item = sel_unit_menu->Append( ID_POPUP_SCH_SELECT_UNIT1 + ii, num_unit, wxEmptyString, wxITEM_CHECK ); if( unit == ii + 1 ) item->Check(true); // The ID max for these submenus is ID_POPUP_SCH_SELECT_UNIT_CMP_MAX // See eeschema_id to modify this value. if( ii >= (ID_POPUP_SCH_SELECT_UNIT_CMP_MAX - ID_POPUP_SCH_SELECT_UNIT1) ) break; // We have used all IDs for these submenus } AddMenuItem( editmenu, sel_unit_menu, ID_POPUP_SCH_SELECT_UNIT_CMP, _( "Unit" ), KiBitmap( component_select_unit_xpm ) ); } if( !Component->GetFlags() ) { msg = AddHotkeyName( _( "Edit with Library Editor" ), g_Schematic_Hokeys_Descr, HK_EDIT_COMPONENT_WITH_LIBEDIT ); AddMenuItem( editmenu, ID_POPUP_SCH_CALL_LIBEDIT_AND_LOAD_CMP, msg, KiBitmap( libedit_xpm ) ); } AddMenuItem( PopMenu, editmenu, ID_SCH_EDIT_ITEM, _( "Edit Component" ), KiBitmap( edit_component_xpm ) ); }
void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnOkClick( wxCommandEvent& event ) { /* Update the doc, keyword and doc filename strings */ LIB_ALIAS* alias; LIB_PART* component = m_Parent->GetCurPart(); if( component == NULL ) { EndModal( wxID_CANCEL ); return; } m_Parent->SaveCopyInUndoList( component ); alias = component->GetAlias( m_Parent->GetAliasName() ); wxCHECK_RET( alias != NULL, wxT( "Alias \"" ) + m_Parent->GetAliasName() + wxT( "\" of component \"" ) + component->GetName() + wxT( "\" does not exist." ) ); alias->SetDescription( m_DocCtrl->GetValue() ); alias->SetKeyWords( m_KeywordsCtrl->GetValue() ); alias->SetDocFileName( m_DocfileCtrl->GetValue() ); component->SetAliases( m_PartAliasListCtrl->GetStrings() ); int unitCount = m_SelNumberOfUnits->GetValue(); ChangeNbUnitsPerPackage( unitCount ); if( m_AsConvertButt->GetValue() ) { if( !m_Parent->GetShowDeMorgan() ) { m_Parent->SetShowDeMorgan( true ); SetUnsetConvert(); } } else { if( m_Parent->GetShowDeMorgan() ) { m_Parent->SetShowDeMorgan( false ); SetUnsetConvert(); } } component->SetShowPinNumbers( m_ShowPinNumButt->GetValue() ); component->SetShowPinNames( m_ShowPinNameButt->GetValue() ); if( m_PinsNameInsideButt->GetValue() == false ) component->SetPinNameOffset( 0 ); // pin text outside the body (name is on the pin) else { component->SetPinNameOffset( m_SetSkew->GetValue() ); // Ensure component->m_TextInside != 0, because the meaning is "text outside". if( component->GetPinNameOffset() == 0 ) component->SetPinNameOffset( 20 ); // give a reasonnable value } if( m_OptionPower->GetValue() == true ) component->SetPower(); else component->SetNormal(); /* Set the option "Units locked". * Obviously, cannot be true if there is only one part */ component->LockUnits( m_OptionPartsLocked->GetValue() ); if( component->GetUnitCount() <= 1 ) component->LockUnits( false ); /* Update the footprint filter list */ component->GetFootPrints().Clear(); component->GetFootPrints() = m_FootprintFilterListBox->GetStrings(); EndModal( wxID_OK ); }