bool SCH_EDIT_FRAME::prepareForNetlist()
{
    SCH_SHEET_LIST sheets( g_RootSheet );

    sheets.AnnotatePowerSymbols( Prj().SchLibs() );

    // Performs some controls:
    if( CheckAnnotate( NULL, 0 ) )
    {
        // Schematic must be annotated: call Annotate dialog and tell
        // the user why that is.
        InvokeDialogAnnotate( this,  _( "Exporting the netlist requires a "
                                        "completely\nannotated schematic." ) );

        if( CheckAnnotate( NULL, 0 ) )
            return false;
    }

    // Test duplicate sheet names:
    if( TestDuplicateSheetNames( false ) > 0 )
    {
        if( !IsOK( NULL, _( "Error: duplicate sheet names. Continue?" ) ) )
            return false;
    }

    // Cleanup the entire hierarchy
    SCH_SCREENS screens;

    screens.SchematicCleanUp();

    return true;
}
Example #2
0
/* Function CreateNetlist
 *  > test for some issues (missing or duplicate references and sheet names)
 *  > build netlist info
 *  > create the netlist file
 * param aFormat = netlist format (NET_TYPE_PCBNEW ...)
 * param aFullFileName = full netlist file name
 * param aNetlistOptions = netlist options using OR'ed bits (see WriteNetListFile).
 * return true if success.
 */
bool SCH_EDIT_FRAME::CreateNetlist( int aFormat, const wxString& aFullFileName,
                                    unsigned aNetlistOptions )
{
    SCH_SHEET_LIST sheets;
    sheets.AnnotatePowerSymbols();

    // Performs some controls:
    if( CheckAnnotate( NULL, 0 ) )
    {
        if( !IsOK( NULL, _( "Some items are not annotated\n\
Do you want to annotate schematic?" ) ) )
            return false;

        // Schematic must be annotated: call Annotate dialog:
        wxCommandEvent event;
        OnAnnotate( event );

        if( CheckAnnotate( NULL, 0 ) )
            return false;
    }

    // Test duplicate sheet names:
    if( TestDuplicateSheetNames( false ) > 0 )
    {
        if( !IsOK( NULL, _( "Error: duplicate sheet names. Continue?" ) ) )
            return false;
    }

    /* Cleanup the entire hierarchy */
    SCH_SCREENS screens;
    screens.SchematicCleanUp();

    BuildNetListBase();
    bool success = WriteNetListFile( aFormat, aFullFileName, aNetlistOptions );

    return success;
}
void SCH_EDIT_FRAME::AnnotateComponents( bool              aAnnotateSchematic,
                                         ANNOTATE_ORDER_T  aSortOption,
                                         ANNOTATE_OPTION_T aAlgoOption,
                                         int               aStartNumber,
                                         bool              aResetAnnotation,
                                         bool              aRepairTimestamps,
                                         bool              aLockUnits,
                                         REPORTER&         aReporter )
{
    SCH_REFERENCE_LIST references;

    SCH_SCREENS screens;

    // Build the sheet list.
    SCH_SHEET_LIST sheets( g_RootSheet );

    // Map of locked components
    SCH_MULTI_UNIT_REFERENCE_MAP lockedComponents;

    // Map of previous annotation for building info messages
    std::map<timestamp_t, wxString> previousAnnotation;

    // 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( aRepairTimestamps )
    {
        int count = screens.ReplaceDuplicateTimeStamps();

        if( count )
        {
            wxString msg;
            msg.Printf( _( "%d duplicate time stamps were found and replaced." ), count );
            aReporter.ReportTail( msg, REPORTER::RPT_WARNING );
        }
    }

    // If units must be locked, collect all the sets that must be annotated together.
    if( aLockUnits )
    {
        if( aAnnotateSchematic )
        {
            sheets.GetMultiUnitComponents( lockedComponents );
        }
        else
        {
            m_CurrentSheet->GetMultiUnitComponents( lockedComponents );
        }
    }

    // Store previous annotations for building info messages
    mapExistingAnnotation( previousAnnotation );

    // If it is an annotation for all the components, reset previous annotation.
    if( aResetAnnotation )
        DeleteAnnotation( !aAnnotateSchematic );

    // Set sheet number and number of sheets.
    SetSheetNumberAndCount();

    // Build component list
    if( aAnnotateSchematic )
    {
        sheets.GetComponents( references );
    }
    else
    {
        m_CurrentSheet->GetComponents( references );
    }

    // Break full components reference in name (prefix) and number:
    // example: IC1 become IC, and 1
    references.SplitReferences();

    switch( aSortOption )
    {
    default:
    case SORT_BY_X_POSITION:
        references.SortByXCoordinate();
        break;

    case SORT_BY_Y_POSITION:
        references.SortByYCoordinate();
        break;
    }

    bool useSheetNum = false;
    int idStep = 100;

    switch( aAlgoOption )
    {
    default:
    case INCREMENTAL_BY_REF:
        break;

    case SHEET_NUMBER_X_100:
        useSheetNum = true;
        break;

    case SHEET_NUMBER_X_1000:
        useSheetNum = true;
        idStep = 1000;
        break;
    }

    // Recalculate and update reference numbers in schematic
    references.Annotate( useSheetNum, idStep, aStartNumber, lockedComponents );
    references.UpdateAnnotation();

    for( size_t i = 0; i < references.GetCount(); i++ )
    {
        SCH_COMPONENT* comp = references[ i ].GetComp();
        wxString       prevRef = previousAnnotation[ comp->GetTimeStamp() ];
        wxString       newRef  = comp->GetField( REFERENCE )->GetFullyQualifiedText();
        wxString       msg;

        if( prevRef.Length() )
        {
            if( newRef == prevRef )
                continue;

            if( comp->GetUnitCount() > 1 )
                msg.Printf( _( "Updated %s (unit %s) from %s to %s" ),
                            GetChars( comp->GetField( VALUE )->GetShownText() ),
                            LIB_PART::SubReference( comp->GetUnit(), false ),
                            GetChars( prevRef ),
                            GetChars( newRef ) );
            else
                msg.Printf( _( "Updated %s from %s to %s" ),
                            GetChars( comp->GetField( VALUE )->GetShownText() ),
                            GetChars( prevRef ),
                            GetChars( newRef ) );
        }
        else
        {
            if( comp->GetUnitCount() > 1 )
                msg.Printf( _( "Annotated %s (unit %s) as %s" ),
                            GetChars( comp->GetField( VALUE )->GetShownText() ),
                            LIB_PART::SubReference( comp->GetUnit(), false ),
                            GetChars( newRef ) );
            else
                msg.Printf( _( "Annotated %s as %s" ),
                            GetChars( comp->GetField( VALUE )->GetShownText() ),
                            GetChars( newRef ) );
        }

        aReporter.Report( msg, REPORTER::RPT_ACTION );
    }

    // Final control (just in case ... ).
    if( !CheckAnnotate( aReporter, !aAnnotateSchematic ) )
        aReporter.ReportTail( _( "Annotation complete." ), REPORTER::RPT_ACTION );

    // Update on screen references, that can be modified by previous calculations:
    m_CurrentSheet->UpdateAllScreenReferences();
    SetSheetNumberAndCount();

    SyncView();
    GetCanvas()->Refresh();
    OnModify();
}
void SCH_EDIT_FRAME::AnnotateComponents( bool              aAnnotateSchematic,
                                         ANNOTATE_ORDER_T  aSortOption,
                                         ANNOTATE_OPTION_T aAlgoOption,
                                         bool              aResetAnnotation,
                                         bool              aRepairTimestamps,
                                         bool              aLockUnits )
{
    SCH_REFERENCE_LIST references;

    SCH_SCREENS screens;

    // Build the sheet list.
    SCH_SHEET_LIST sheets;

    // Map of locked components
    SCH_MULTI_UNIT_REFERENCE_MAP lockedComponents;

    // 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( aRepairTimestamps )
    {
        int count = screens.ReplaceDuplicateTimeStamps();

        if( count )
        {
            wxString msg;
            msg.Printf( _( "%d duplicate time stamps were found and replaced." ), count );
            DisplayInfoMessage( NULL, msg, 2 );
        }
    }

    // If units must be locked, collect all the sets that must be annotated together.
    if( aLockUnits )
    {
        if( aAnnotateSchematic )
        {
            sheets.GetMultiUnitComponents( Prj().SchLibs(), lockedComponents );
        }
        else
        {
            m_CurrentSheet->GetMultiUnitComponents( Prj().SchLibs(), lockedComponents );
        }
    }

    // If it is an annotation for all the components, reset previous annotation.
    if( aResetAnnotation )
        DeleteAnnotation( !aAnnotateSchematic );

    // Set sheet number and number of sheets.
    SetSheetNumberAndCount();

    // Build component list
    if( aAnnotateSchematic )
    {
        sheets.GetComponents( Prj().SchLibs(), references );
    }
    else
    {
        m_CurrentSheet->GetComponents( Prj().SchLibs(), references );
    }

    // Break full components reference in name (prefix) and number:
    // example: IC1 become IC, and 1
    references.SplitReferences();

    switch( aSortOption )
    {
    default:
    case SORT_BY_X_POSITION:
        references.SortByXCoordinate();
        break;

    case SORT_BY_Y_POSITION:
        references.SortByYCoordinate();
        break;
    }

    bool useSheetNum = false;
    int idStep = 100;

    switch( aAlgoOption )
    {
    default:
    case INCREMENTAL_BY_REF:
        break;

    case SHEET_NUMBER_X_100:
        useSheetNum = true;
        break;

    case SHEET_NUMBER_X_1000:
        useSheetNum = true;
        idStep = 1000;
        break;
    }

    // Recalculate and update reference numbers in schematic
    references.Annotate( useSheetNum, idStep, lockedComponents );
    references.UpdateAnnotation();

    wxArrayString errors;

    // Final control (just in case ... ).
    if( CheckAnnotate( &errors, !aAnnotateSchematic ) )
    {
        wxString msg;

        for( size_t i = 0; i < errors.GetCount(); i++ )
            msg += errors[i];

        // wxLogWarning is a cheap and dirty way to dump a potentially long list of
        // strings to a dialog that can be saved to a file.  This should be replaced
        // by a more elegant solution.
        wxLogWarning( msg );
    }

    OnModify();

    // Update on screen references, that can be modified by previous calculations:
    m_CurrentSheet->UpdateAllScreenReferences();
    SetSheetNumberAndCount();

    m_canvas->Refresh( true );
}
Example #5
0
void WinEDA_ErcFrame::TestErc(wxCommandEvent& event)
/**************************************************/
{
    ObjetNetListStruct * NetItemRef, * OldItem, * StartNet, * Lim;
    int NetNbItems, MinConn;

    if ( ! DiagErcTableInit )
    {
        memcpy(DiagErc, DefaultDiagErc, sizeof (DefaultDiagErc));
        DiagErcTableInit = TRUE;
    }

    WriteFichierERC = m_WriteResultOpt->GetValue();

    if( CheckAnnotate(m_Parent, 0) )
    {
        DisplayError(this, _("Annotation Required!") );
        return;
    }

    /* Effacement des anciens marqueurs DRC */
    DelERCMarkers(event);

    wxClientDC dc(m_Parent->DrawPanel);

    m_Parent->DrawPanel->PrepareGraphicContext(&dc);

    g_EESchemaVar.NbErrorErc = 0;
    g_EESchemaVar.NbWarningErc = 0;

    SchematicCleanUp(&dc);

    BuildNetList(m_Parent, ScreenSch);

    /* Analyse de la table des connexions : */
    Lim = g_TabObjNet + g_NbrObjNet;

    /* Reset du flag m_FlagOfConnection, utilise par la suite */
    for (NetItemRef = g_TabObjNet; NetItemRef < Lim; NetItemRef ++ )
        NetItemRef->m_FlagOfConnection = (IsConnectType) 0;

    NetNbItems = 0;
    MinConn = NOC;
    StartNet = OldItem = NetItemRef = g_TabObjNet;
    for ( ; NetItemRef < Lim; NetItemRef ++ )
    {
        /* Tst changement de net */
        if( OldItem->m_NetCode != NetItemRef->m_NetCode)
        {
            MinConn = NOC;
            NetNbItems = 0;
            StartNet = NetItemRef;
        }

        switch ( NetItemRef->m_Type )
        {
        case NET_SEGMENT:
        case NET_BUS:
        case NET_JONCTION:
        case NET_LABEL:
        case NET_BUSLABELMEMBER:
        case NET_PINLABEL:
            break;

        case NET_GLOBLABEL:
        case NET_GLOBBUSLABELMEMBER:
        case NET_SHEETLABEL:
        case NET_SHEETBUSLABELMEMBER:
            TestLabel(m_Parent->DrawPanel, &dc, NetItemRef, StartNet);
            break;

        case NET_NOCONNECT:
            MinConn = NET_NC;
            if( NetNbItems != 0 )
                Diagnose(m_Parent->DrawPanel, &dc, NetItemRef, NULL, MinConn, UNC);
            break;

        case NET_PIN:
            TestOthersItems(m_Parent->DrawPanel, &dc,
                            NetItemRef, StartNet, &NetNbItems , &MinConn);
            break;
        }
        OldItem = NetItemRef;
    }

    FreeTabNetList(g_TabObjNet, g_NbrObjNet );

    wxString num;
    num.Printf(wxT("%d"), g_EESchemaVar.NbErrorErc);
    m_TotalErrCount->SetLabel(num);

    num.Printf(wxT("%d"), g_EESchemaVar.NbErrorErc-g_EESchemaVar.NbWarningErc);
    m_LastErrCount->SetLabel(num);

    num.Printf(wxT("%d"), g_EESchemaVar.NbWarningErc);
    m_LastWarningCount->SetLabel(num);

    /* Generation ouverture fichier diag */
    if( WriteFichierERC == TRUE )
    {
        wxString ErcFullFileName;
        ErcFullFileName = ScreenSch->m_FileName;
        ChangeFileNameExt(ErcFullFileName, wxT(".erc"));
        ErcFullFileName = EDA_FileSelector(_("ERC file:"),
                                           wxEmptyString,					/* Chemin par defaut */
                                           ErcFullFileName,	/* nom fichier par defaut */
                                           wxT(".erc"),				/* extension par defaut */
                                           wxT("*.erc"),			/* Masque d'affichage */
                                           this,
                                           wxSAVE,
                                           TRUE
                                          );
        if ( ErcFullFileName.IsEmpty()) return;

        if ( WriteDiagnosticERC(ErcFullFileName) )
        {
            Close(TRUE);
            wxString editorname = GetEditorName();
            AddDelimiterString(ErcFullFileName);
            ExecuteFile(this, editorname, ErcFullFileName);
        }
    }
}