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;
}
Beispiel #3
0
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();
}
Beispiel #4
0
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();
}
Beispiel #8
0
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;
}
Beispiel #10
0
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 );
}