Esempio n. 1
0
bool SCH_EDIT_FRAME::prepareForNetlist()
{
    SCH_SHEET_LIST sheets;

    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;
}
void DIALOG_ERC::DisplayERC_MarkersList()
{
    SCH_SHEET_LIST sheetList;
    m_MarkersList->ClearList();

    SCH_SHEET_PATH* sheet = sheetList.GetFirst();

    for( ; sheet != NULL; sheet = sheetList.GetNext() )
    {
        SCH_ITEM* item = sheet->LastDrawList();

        for( ; item != NULL; item = item->Next() )
        {
            if( item->Type() != SCH_MARKER_T )
                continue;

            SCH_MARKER* marker = (SCH_MARKER*) item;

            if( marker->GetMarkerType() != MARKER_BASE::MARKER_ERC )
                continue;

            m_MarkersList->AppendToList( marker );
        }
    }

    m_MarkersList->DisplayList();
}
void DIALOG_ERC::DisplayERC_MarkersList()
{
    SCH_SHEET_LIST sheetList;
    m_MarkersList->ClearList();

    SCH_SHEET_PATH* sheet = sheetList.GetFirst();

    for( ; sheet != NULL; sheet = sheetList.GetNext() )
    {
        SCH_ITEM* item = sheet->LastDrawList();

        for( ; item != NULL; item = item->Next() )
        {
            if( item->Type() != SCH_MARKER_T )
                continue;

            SCH_MARKER* Marker = (SCH_MARKER*) item;

            if( Marker->GetMarkerType() != MARKER_BASE::MARKER_ERC )
                continue;

            // Add marker without refresh the displayed list:
            m_MarkersList->AppendToList( Marker, false );
        }
    }

    m_MarkersList->Refresh();
}
Esempio n. 4
0
void SCH_EDIT_FRAME::SetSheetNumberAndCount()
{
    SCH_SCREEN* screen = GetScreen();
    SCH_SCREENS s_list;

    /* Set the sheet count, and the sheet number (1 for root sheet)
     */
    int            sheet_count = g_RootSheet->CountSheets();
    int            SheetNumber = 1;
    wxString       current_sheetpath = m_CurrentSheet->Path();
    SCH_SHEET_LIST SheetList;

    // Examine all sheets path to find the current sheets path,
    // and count them from root to the current sheet path:
    SCH_SHEET_PATH* sheet;

    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 */
    }

    for( screen = s_list.GetFirst(); screen != NULL; screen = s_list.GetNext() )
    {
        screen->m_NumberOfScreens = sheet_count;
    }

    GetScreen()->m_ScreenNumber = SheetNumber;
}
void SCH_SHEET_PATH::GetComponents( PART_LIBS* aLibs, SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols )
{
    // Search to 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 )
        {
            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 )
            {
                SCH_REFERENCE reference = SCH_REFERENCE( component, part, *this );
                reference.SetSheetNumber( sheetnumber );
                aReferences.AddItem( reference );
            }
        }
    }
}
Esempio n. 6
0
File: erc.cpp Progetto: OpenEE/micad
bool WriteDiagnosticERC( const wxString& aFullFileName )
{
    wxString    msg;

    wxFFile file( aFullFileName, wxT( "wt" ) );

    if( !file.IsOpened() )
        return false;

    msg = _( "ERC report" );
    msg << wxT(" (") << DateAndTime() << wxT( ", " )
        << _( "Encoding UTF8" ) << wxT( " )\n" );

    int err_count = 0;
    int warn_count = 0;
    int total_count = 0;
    SCH_SHEET_LIST sheetList;
    SCH_SHEET_PATH* sheet;

    for( sheet = sheetList.GetFirst(); sheet != NULL; sheet = sheetList.GetNext() )
    {
        msg << wxString::Format( _( "\n***** Sheet %s\n" ),
                                 GetChars( sheet->PathHumanReadable() ) );

        for( SCH_ITEM* item = sheet->LastDrawList(); item != NULL; item = item->Next() )
        {
            if( item->Type() != SCH_MARKER_T )
                continue;

            SCH_MARKER* marker = (SCH_MARKER*) item;

            if( marker->GetMarkerType() != MARKER_BASE::MARKER_ERC )
                continue;

            total_count++;

            if( marker->GetErrorLevel() == MARKER_BASE::MARKER_SEVERITY_ERROR )
                err_count++;

            if( marker->GetErrorLevel() == MARKER_BASE::MARKER_SEVERITY_WARNING )
                warn_count++;

            msg << marker->GetReporter().ShowReport();
        }
    }

    msg << wxString::Format( _( "\n ** ERC messages: %d  Errors %d  Warnings %d\n" ),
                             total_count, err_count, warn_count );

    // Currently: write report unsing UTF8 (as usual in Kicad).
    // TODO: see if we can use the current encoding page (mainly for Windows users),
    // Or other format (HTML?)
    file.Write( msg );

    // wxFFile dtor will close the file.

    return true;
}
void DIALOG_ERC::OnLeftClickMarkersList( wxHtmlLinkEvent& event )
{
    wxString link = event.GetLinkInfo().GetHref();

    m_lastMarkerFound = NULL;

    long index;

    if( !link.ToLong( &index ) )
        return;

    const SCH_MARKER* marker = m_MarkersList->GetItem( index );

    if( marker == NULL )
        return;

    // Search for the selected marker
    SCH_SHEET_PATH* sheet;
    SCH_SHEET_LIST  SheetList;
    bool notFound = true;

    for( sheet = SheetList.GetFirst(); sheet; sheet = SheetList.GetNext() )
    {
        SCH_ITEM* item = (SCH_ITEM*) sheet->LastDrawList();

        for( ; item; item = item->Next() )
        {
            if( item == marker )
            {
                notFound = false;
                break;
            }
        }

        if( notFound == false )
            break;
    }

    if( notFound ) // Error
    {
        wxMessageBox( _( "Marker not found" ) );

        // The marker was deleted, so rebuild marker list
        DisplayERC_MarkersList();
        return;
    }

    if( *sheet != m_parent->GetCurrentSheet() )
    {
        sheet->LastScreen()->SetZoom( m_parent->GetScreen()->GetZoom() );
        m_parent->SetCurrentSheet( *sheet );
        m_parent->GetCurrentSheet().UpdateAllScreenReferences();
    }

    m_lastMarkerFound = marker;
    m_parent->SetCrossHairPosition( marker->m_Pos );
    m_parent->RedrawScreen( marker->m_Pos, false);
}
Esempio n. 8
0
void SCH_EDIT_FRAME::OnFindDrcMarker( wxFindDialogEvent& event )
{
    static SCH_MARKER* lastMarker = NULL;

    wxString           msg;
    SCH_SHEET_LIST     schematic;
    SCH_SHEET_PATH*    sheetFoundIn = NULL;
    bool               wrap = ( event.GetFlags() & FR_SEARCH_WRAP ) != 0;
    wxRect             clientRect( wxPoint( 0, 0 ), GetClientSize() );
    bool               warpCursor = ( ( event.GetId() == wxEVT_COMMAND_FIND_CLOSE ) ||
                                      !( event.GetFlags() & FR_NO_WARP_CURSOR ) );

    if( event.GetFlags() & FR_CURRENT_SHEET_ONLY )
    {
        sheetFoundIn = m_CurrentSheet;
        lastMarker = (SCH_MARKER*) m_CurrentSheet->FindNextItem( SCH_MARKER_T, lastMarker, wrap );
    }
    else
    {
        lastMarker = (SCH_MARKER*) schematic.FindNextItem( SCH_MARKER_T, &sheetFoundIn,
                                                           lastMarker, wrap );
    }

    if( lastMarker != NULL )
    {
        if( *sheetFoundIn != *m_CurrentSheet )
        {
            sheetFoundIn->LastScreen()->SetZoom( GetScreen()->GetZoom() );
            *m_CurrentSheet = *sheetFoundIn;
            m_CurrentSheet->UpdateAllScreenReferences();
        }

        sheetFoundIn->LastScreen()->SetCrossHairPosition( lastMarker->GetPosition() );

        RedrawScreen( lastMarker->GetPosition(), warpCursor );

        wxString path = sheetFoundIn->Path();
        wxString units = GetAbbreviatedUnitsLabel();
        double x = To_User_Unit( g_UserUnit, (double) lastMarker->GetPosition().x,
                                 m_internalUnits );
        double y = To_User_Unit( g_UserUnit, (double) lastMarker->GetPosition().y,
                                 m_internalUnits );
        msg.Printf( _( "Design rule check marker found in sheet %s at %0.3f%s, %0.3f%s" ),
                    GetChars( path ), x, GetChars( units ), y, GetChars( units) );
        SetStatusText( msg );
    }
    else
    {
        SetStatusText( _( "No more markers were found." ) );
    }
}
Esempio n. 9
0
int SCH_EDIT_FRAME::CheckAnnotate( wxArrayString* aMessageList, bool aOneSheetOnly )
{
    // build the screen list
    SCH_SHEET_LIST SheetList;
    SCH_REFERENCE_LIST ComponentsList;

    // Build the list of components
    if( !aOneSheetOnly )
        SheetList.GetComponents( Prj().SchLibs(), ComponentsList );
    else
        m_CurrentSheet->GetComponents( Prj().SchLibs(), ComponentsList );

    return ComponentsList.CheckAnnotation( aMessageList );
}
Esempio n. 10
0
File: erc.cpp Progetto: natsfr/kicad
bool WriteDiagnosticERC( const wxString& aFullFileName )
{
    SCH_ITEM*       item;
    SCH_MARKER*     marker;
    static FILE*    file;
    SCH_SHEET_PATH* sheet;
    wxString        msg;
    int             count = 0;

    if( ( file = wxFopen( aFullFileName, wxT( "wt" ) ) ) == NULL )
        return false;

    msg = _( "ERC report" );

    fprintf( file, "%s (%s)\n", TO_UTF8( msg ), TO_UTF8( DateAndTime() ) );

    SCH_SHEET_LIST sheetList;

    for( sheet = sheetList.GetFirst(); sheet != NULL; sheet = sheetList.GetNext() )
    {
        msg.Printf( _( "\n***** Sheet %s\n" ), GetChars( sheet->PathHumanReadable() ) );

        fprintf( file, "%s", TO_UTF8( msg ) );

        for( item = sheet->LastDrawList(); item != NULL; item = item->Next() )
        {
            if( item->Type() != SCH_MARKER_T )
                continue;

            marker = (SCH_MARKER*) item;

            if( marker->GetMarkerType() != MARK_ERC )
                continue;

            if( marker->GetMarkerType() == ERR )
                count++;

            msg = marker->GetReporter().ShowReport();
            fprintf( file, "%s", TO_UTF8( msg ) );
        }
    }

    msg.Printf( _( "\n >> Errors ERC: %d\n" ), count );
    fprintf( file, "%s", TO_UTF8( msg ) );
    fclose( file );

    return true;
}
void NETLIST_EXPORTER::findAllInstancesOfComponent( SCH_COMPONENT*  aComponent,
                                         LIB_PART*       aEntry,
                                         SCH_SHEET_PATH* aSheetPath )
{
    wxString    ref = aComponent->GetRef( aSheetPath );
    wxString    ref2;

    SCH_SHEET_LIST sheetList;

    for( SCH_SHEET_PATH* sheet = sheetList.GetFirst();  sheet;  sheet = sheetList.GetNext() )
    {
        for( EDA_ITEM* item = sheet->LastDrawList();  item;  item = item->Next() )
        {
            if( item->Type() != SCH_COMPONENT_T )
                continue;

            SCH_COMPONENT*  comp2 = (SCH_COMPONENT*) item;

            ref2 = comp2->GetRef( sheet );
            if( ref2.CmpNoCase( ref ) != 0 )
                continue;

            int unit2 = comp2->GetUnitSelection( sheet );  // slow

            for( LIB_PIN* pin = aEntry->GetNextPin();  pin;  pin = aEntry->GetNextPin( pin ) )
            {
                wxASSERT( pin->Type() == LIB_PIN_T );

                if( pin->GetUnit() && pin->GetUnit() != unit2 )
                    continue;

                if( pin->GetConvert() && pin->GetConvert() != comp2->GetConvert() )
                    continue;

                // A suitable pin is found: add it to the current list
                addPinToComponentPinList( comp2, sheet, pin );
            }
        }
    }
}
Esempio n. 12
0
void SCH_FIND_COLLECTOR::Collect( SCH_FIND_REPLACE_DATA& aFindReplaceData,
                                  SCH_SHEET_PATH* aSheetPath )
{
    if( !IsSearchRequired( aFindReplaceData ) && !m_List.empty() && !m_forceSearch )
        return;

    m_findReplaceData = aFindReplaceData;
    Empty();                 // empty the collection just in case
    m_data.clear();
    m_foundIndex = 0;
    SetForceSearch( false );

    if( aSheetPath )
    {
        m_sheetPath = aSheetPath;
        EDA_ITEM::IterateForward( aSheetPath->LastDrawList(), this, NULL, m_ScanTypes );
    }
    else
    {
        SCH_SHEET_LIST schematic;
        m_sheetPath = schematic.GetFirst();

        while( m_sheetPath != NULL )
        {
            EDA_ITEM::IterateForward( m_sheetPath->LastDrawList(), this, NULL, m_ScanTypes );
            m_sheetPath = schematic.GetNext();
        }
    }

#if defined(DEBUG)
    dump();
#endif

    if( m_List.size() != m_data.size() )
    {
        wxFAIL_MSG( wxT( "List size mismatch." ) );
        m_List.clear();
        m_data.clear();
    }
}
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 );
        }
    }
}
Esempio n. 14
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;
}
Esempio n. 15
0
void DIALOG_ERC::TestErc( wxArrayString* aMessagesList )
{
    wxFileName fn;

    m_writeErcFile = m_WriteResultOpt->GetValue();
    m_TestSimilarLabels = m_cbTestSimilarLabels->GetValue();
    m_tstUniqueGlobalLabels = m_cbTestUniqueGlbLabels->GetValue();

    // Build the whole sheet list in hierarchy (sheet, not screen)
    SCH_SHEET_LIST sheets;
    sheets.AnnotatePowerSymbols( Prj().SchLibs() );

    if( m_parent->CheckAnnotate( aMessagesList, false ) )
    {
        if( aMessagesList )
        {
            wxString msg = _( "Annotation required!" );
            msg += wxT( "\n" );
            aMessagesList->Add( msg );
        }

        return;
    }

    SCH_SCREENS screens;

    // Erase all previous DRC markers.
    screens.DeleteAllMarkers( MARKER_BASE::MARKER_ERC );

    for( SCH_SCREEN* screen = screens.GetFirst(); screen != NULL; screen = screens.GetNext() )
    {
        /* Ff wire list has changed, delete Undo Redo list to avoid pointers on deleted
         * data problems.
         */
        if( screen->SchematicCleanUp( NULL ) )
            screen->ClearUndoRedoList();
    }

    /* Test duplicate sheet names inside a given sheet, one cannot have sheets with
     * duplicate names (file names can be duplicated).
     */
    TestDuplicateSheetNames( true );

    std::auto_ptr<NETLIST_OBJECT_LIST> objectsConnectedList( m_parent->BuildNetListBase() );

    // Reset the connection type indicator
    objectsConnectedList->ResetConnectionsType();

    unsigned lastNet;
    unsigned nextNet = lastNet = 0;
    int MinConn    = NOC;

    for( unsigned net = 0; net < objectsConnectedList->size(); net++ )
    {
        if( objectsConnectedList->GetItemNet( lastNet ) !=
            objectsConnectedList->GetItemNet( net ) )
        {
            // New net found:
            MinConn    = NOC;
            nextNet   = net;
        }

        switch( objectsConnectedList->GetItemType( net ) )
        {
        // These items do not create erc problems
        case NET_ITEM_UNSPECIFIED:
        case NET_SEGMENT:
        case NET_BUS:
        case NET_JUNCTION:
        case NET_LABEL:
        case NET_BUSLABELMEMBER:
        case NET_PINLABEL:
        case NET_GLOBBUSLABELMEMBER:
            break;

        case NET_HIERLABEL:
        case NET_HIERBUSLABELMEMBER:
        case NET_SHEETLABEL:
        case NET_SHEETBUSLABELMEMBER:
            // ERC problems when pin sheets do not match hierarchical labels.
            // Each pin sheet must match a hierarchical label
            // Each hierarchical label must match a pin sheet
            objectsConnectedList->TestforNonOrphanLabel( net, nextNet );
            break;
        case NET_GLOBLABEL:
            if( m_tstUniqueGlobalLabels )
                objectsConnectedList->TestforNonOrphanLabel( net, nextNet );
            break;

        case NET_NOCONNECT:

            // ERC problems when a noconnect symbol is connected to more than one pin.
            MinConn = NET_NC;

            if( objectsConnectedList->CountPinsInNet( nextNet ) > 1 )
                Diagnose( objectsConnectedList->GetItem( net ), NULL, MinConn, UNC );

            break;

        case NET_PIN:

            // Look for ERC problems between pins:
            TestOthersItems( objectsConnectedList.get(), net, nextNet, &MinConn );
            break;
        }

        lastNet = net;
    }

    // Test similar labels (i;e. labels which are identical when
    // using case insensitive comparisons)
    if( m_TestSimilarLabels )
        objectsConnectedList->TestforSimilarLabels();

    // Displays global results:
    updateMarkerCounts( &screens );

    // Display diags:
    DisplayERC_MarkersList();

    // Display new markers:
    m_parent->GetCanvas()->Refresh();

    if( m_writeErcFile )
    {
        fn = g_RootSheet->GetScreen()->GetFileName();
        fn.SetExt( wxT( "erc" ) );

        wxFileDialog dlg( this, _( "ERC File" ), fn.GetPath(), fn.GetFullName(),
                          _( "Electronic rule check file (.erc)|*.erc" ),
                          wxFD_SAVE );

        if( dlg.ShowModal() == wxID_CANCEL )
            return;

        if( WriteDiagnosticERC( dlg.GetPath() ) )
        {
            Close( true );
            ExecuteFile( this, Pgm().GetEditorName(), QuoteFullPath( fn ) );
        }
    }
}
Esempio n. 16
0
void SCH_EDIT_FRAME::PasteListOfItems( wxDC* DC )
{
    unsigned       i;
    SCH_ITEM*      item;
    SCH_SHEET_LIST hierarchy;    // This is the entire schematic hierarcy.

    if( m_blockItems.GetCount() == 0 )
    {
        DisplayError( this, _( "No item to paste." ) );
        return;
    }

    wxFileName destFn = m_CurrentSheet->Last()->GetFileName();

    if( destFn.IsRelative() )
        destFn.MakeAbsolute( Prj().GetProjectPath() );

    // Make sure any sheets in the block to be pasted will not cause recursion in
    // the destination sheet.
    for( i = 0; i < m_blockItems.GetCount(); i++ )
    {
        item = (SCH_ITEM*) m_blockItems.GetItem( i );

        if( item->Type() == SCH_SHEET_T )
        {
            SCH_SHEET* sheet = (SCH_SHEET*)item;
            wxFileName srcFn = sheet->GetFileName();

            if( srcFn.IsRelative() )
                srcFn.MakeAbsolute( Prj().GetProjectPath() );

            SCH_SHEET_LIST sheetHierarchy( sheet );

            if( hierarchy.TestForRecursion( sheetHierarchy,
                                            destFn.GetFullPath( wxPATH_UNIX ) ) )
            {
                wxString msg;

                msg.Printf( _( "The sheet changes cannot be made because the destination "
                               "sheet already has the sheet <%s> or one of it's subsheets "
                               "as a parent somewhere in the schematic hierarchy." ),
                            GetChars( sheet->GetFileName() ) );
                DisplayError( this, msg );
                return;
            }

            // Duplicate sheet names and sheet time stamps are not valid.  Use a time stamp
            // based sheet name and update the time stamp for each sheet in the block.
            unsigned long timeStamp = (unsigned long)GetNewTimeStamp();

            sheet->SetName( wxString::Format( wxT( "sheet%8.8lX" ), timeStamp ) );
            sheet->SetTimeStamp( (time_t)timeStamp );
        }
    }

    PICKED_ITEMS_LIST picklist;

    for( i = 0; i < m_blockItems.GetCount(); i++ )
    {
        item = DuplicateStruct( (SCH_ITEM*) m_blockItems.GetItem( i ) );

        // Creates data, and push it as new data in undo item list buffer
        ITEM_PICKER picker( item, UR_NEW );
        picklist.PushItem( picker );

        // Clear annotation and init new time stamp for the new components and sheets:
        if( item->Type() == SCH_COMPONENT_T )
        {
            ( (SCH_COMPONENT*) item )->SetTimeStamp( GetNewTimeStamp() );
            ( (SCH_COMPONENT*) item )->ClearAnnotation( NULL );
        }
        else if( item->Type() == SCH_SHEET_T )
        {
            ( (SCH_SHEET*) item )->SetTimeStamp( GetNewTimeStamp() );
        }

        SetSchItemParent( item, GetScreen() );
        item->Draw( m_canvas, DC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
        GetScreen()->Append( item );
    }

    SaveCopyInUndoList( picklist, UR_NEW );

    MoveItemsInList( picklist, GetScreen()->m_BlockLocate.GetMoveVector() );

    // Clear flags for all items.
    GetScreen()->ClearDrawingState();

    OnModify();

    return;
}
Esempio n. 17
0
bool SCH_EDIT_FRAME::ProcessCmpToFootprintLinkFile( wxString& aFullFilename,
                                                    bool aForceFieldsVisibleAttribute,
                                                    bool aFieldsVisibleAttributeState )
{
    // Build a flat list of components in schematic:
    SCH_REFERENCE_LIST referencesList;
    SCH_SHEET_LIST SheetList;
    SheetList.GetComponents( referencesList, false );

    FILE* cmpFile = wxFopen( aFullFilename, wxT( "rt" ) );
    if( cmpFile == NULL )
        return false;

    // cmpFileReader dtor will close cmpFile
    FILE_LINE_READER cmpFileReader( cmpFile, aFullFilename );

    // Now, for each component found in file,
    // replace footprint field value by the new value:
    wxString reference;
    wxString footprint;
    wxString buffer;
    wxString value;

    while( cmpFileReader.ReadLine() )
    {
        buffer = FROM_UTF8( cmpFileReader.Line() );

        if( ! buffer.StartsWith( wxT("BeginCmp") ) )
            continue;

        // Begin component description.
        reference.Empty();
        footprint.Empty();

        while( cmpFileReader.ReadLine() )
        {
            buffer = FROM_UTF8( cmpFileReader.Line() );

            if( buffer.StartsWith( wxT("EndCmp") ) )
                break;

            // store string value, stored between '=' and ';' delimiters.
            value = buffer.AfterFirst( '=' );
            value = value.BeforeLast( ';');
            value.Trim(true);
            value.Trim(false);

            if( buffer.StartsWith( wxT("Reference") ) )
            {
                reference = value;
                continue;
            }

            if( buffer.StartsWith( wxT("IdModule  =" ) ) )
            {
                footprint = value;
                continue;
            }
        }

        // A block is read: initialize the footprint field of the correponding component
        // if the footprint name is not empty
        if( reference.IsEmpty() )
            continue;
        // Search the component in the flat list
        for( unsigned ii = 0; ii < referencesList.GetCount(); ii++ )
        {
            if( reference.CmpNoCase( referencesList[ii].GetRef() ) == 0 )
            {
                // We have found a candidate.
                // Note: it can be not unique (multiple parts per package)
                // So we *do not* stop the search here
                SCH_COMPONENT* component = referencesList[ii].GetComponent();
                SCH_FIELD * fpfield = component->GetField( FOOTPRINT );
                fpfield->SetText( footprint );

                if( aForceFieldsVisibleAttribute )
                {
                        component->GetField( FOOTPRINT )
                            ->SetVisible( aFieldsVisibleAttributeState );
                }
            }
        }
    }
    return true;
}
Esempio n. 18
0
bool NETLIST_OBJECT_LIST::BuildNetListInfo( SCH_SHEET_LIST& aSheets )
{
    SCH_SHEET_PATH* sheet;

    // Fill list with connected items from the flattened sheet list
    for( unsigned i = 0; i < aSheets.size();  i++ )
    {
        sheet = &aSheets[i];

        for( SCH_ITEM* item = sheet->LastScreen()->GetDrawItems(); item; item = item->Next() )
        {
            item->GetNetListItem( *this, sheet );
        }
    }

    if( size() == 0 )
        return false;

    // Sort objects by Sheet
    SortListbySheet();

    sheet = &(GetItem( 0 )->m_SheetPath);
    m_lastNetCode = m_lastBusNetCode = 1;

    for( unsigned ii = 0, istart = 0; ii < size(); ii++ )
    {
        NETLIST_OBJECT* net_item = GetItem( ii );

        if( net_item->m_SheetPath != *sheet )   // Sheet change
        {
            sheet  = &(net_item->m_SheetPath);
            istart = ii;
        }

        switch( net_item->m_Type )
        {
        case NET_ITEM_UNSPECIFIED:
            wxMessageBox( wxT( "BuildNetListInfo() error" ) );
            break;

        case NET_PIN:
        case NET_PINLABEL:
        case NET_SHEETLABEL:
        case NET_NOCONNECT:
            if( net_item->GetNet() != 0 )
                break;

        case NET_SEGMENT:
            // Test connections point to point type without bus.
            if( net_item->GetNet() == 0 )
            {
                net_item->SetNet( m_lastNetCode );
                m_lastNetCode++;
            }

            pointToPointConnect( net_item, IS_WIRE, istart );
            break;

        case NET_JUNCTION:
            // Control of the junction outside BUS.
            if( net_item->GetNet() == 0 )
            {
                net_item->SetNet( m_lastNetCode );
                m_lastNetCode++;
            }

            segmentToPointConnect( net_item, IS_WIRE, istart );

            // Control of the junction, on BUS.
            if( net_item->m_BusNetCode == 0 )
            {
                net_item->m_BusNetCode = m_lastBusNetCode;
                m_lastBusNetCode++;
            }

            segmentToPointConnect( net_item, IS_BUS, istart );
            break;

        case NET_LABEL:
        case NET_HIERLABEL:
        case NET_GLOBLABEL:
            // Test connections type junction without bus.
            if( net_item->GetNet() == 0 )
            {
                net_item->SetNet( m_lastNetCode );
                m_lastNetCode++;
            }

            segmentToPointConnect( net_item, IS_WIRE, istart );
            break;

        case NET_SHEETBUSLABELMEMBER:
            if( net_item->m_BusNetCode != 0 )
                break;

        case NET_BUS:
            // Control type connections point to point mode bus
            if( net_item->m_BusNetCode == 0 )
            {
                net_item->m_BusNetCode = m_lastBusNetCode;
                m_lastBusNetCode++;
            }

            pointToPointConnect( net_item, IS_BUS, istart );
            break;

        case NET_BUSLABELMEMBER:
        case NET_HIERBUSLABELMEMBER:
        case NET_GLOBBUSLABELMEMBER:
            // Control connections similar has on BUS
            if( net_item->GetNet() == 0 )
            {
                net_item->m_BusNetCode = m_lastBusNetCode;
                m_lastBusNetCode++;
            }

            segmentToPointConnect( net_item, IS_BUS, istart );
            break;
        }
    }

#if defined(NETLIST_DEBUG) && defined(DEBUG)
    std::cout << "\n\nafter sheet local\n\n";
    DumpNetTable();
#endif

    // Updating the Bus Labels Netcode connected by Bus
    connectBusLabels();

    // Group objects by label.
    for( unsigned ii = 0; ii < size(); ii++ )
    {
        switch( GetItem( ii )->m_Type )
        {
        case NET_PIN:
        case NET_SHEETLABEL:
        case NET_SEGMENT:
        case NET_JUNCTION:
        case NET_BUS:
        case NET_NOCONNECT:
            break;

        case NET_LABEL:
        case NET_GLOBLABEL:
        case NET_PINLABEL:
        case NET_BUSLABELMEMBER:
        case NET_GLOBBUSLABELMEMBER:
            labelConnect( GetItem( ii ) );
            break;

        case NET_SHEETBUSLABELMEMBER:
        case NET_HIERLABEL:
        case NET_HIERBUSLABELMEMBER:
            break;

        case NET_ITEM_UNSPECIFIED:
            break;
        }
    }

#if defined(NETLIST_DEBUG) && defined(DEBUG)
    std::cout << "\n\nafter sheet global\n\n";
    DumpNetTable();
#endif

    // Connection between hierarchy sheets
    for( unsigned ii = 0; ii < size(); ii++ )
    {
        if( GetItem( ii )->m_Type == NET_SHEETLABEL
            || GetItem( ii )->m_Type == NET_SHEETBUSLABELMEMBER )
            sheetLabelConnect( GetItem( ii ) );
    }

    // Sort objects by NetCode
    SortListbyNetcode();

#if defined(NETLIST_DEBUG) && defined(DEBUG)
    std::cout << "\n\nafter qsort()\n";
    DumpNetTable();
#endif

    // Compress numbers of Netcode having consecutive values.
    int NetCode = 0;
    m_lastNetCode = 0;

    for( unsigned ii = 0; ii < size(); ii++ )
    {
        if( GetItem( ii )->GetNet() != m_lastNetCode )
        {
            NetCode++;
            m_lastNetCode = GetItem( ii )->GetNet();
        }

        GetItem( ii )->SetNet( NetCode );
    }

    // Set the minimal connection info:
    setUnconnectedFlag();

    // find the best label object to give the best net name to each net
    findBestNetNameForEachNet();

    return true;
}
void DIALOG_PLOT_SCHEMATIC::createPDFFile( bool aPlotAll, bool aPlotFrameRef )
{
    SCH_SCREEN*     screen = m_parent->GetScreen();
    SCH_SHEET_PATH  oldsheetpath = m_parent->GetCurrentSheet();     // sheetpath is saved here

    /* When printing all pages, the printed page is not the current page.  In
     * complex hierarchies, we must update component references and others
     * parameters in the given printed SCH_SCREEN, accordint to the sheet path
     * because in complex hierarchies a SCH_SCREEN (a drawing ) is shared
     * between many sheets and component references depend on the actual sheet
     * path used
     */
    SCH_SHEET_LIST sheetList;

    if( aPlotAll )
        sheetList.BuildSheetList( g_RootSheet );
    else
        sheetList.push_back( m_parent->GetCurrentSheet() );

    // Allocate the plotter and set the job level parameter
    PDF_PLOTTER* plotter = new PDF_PLOTTER();
    plotter->SetDefaultLineWidth( GetDefaultLineThickness() );
    plotter->SetColorMode( getModeColor() );
    plotter->SetCreator( wxT( "Eeschema-PDF" ) );

    wxString msg;
    wxFileName plotFileName;
    REPORTER& reporter = m_MessagesBox->Reporter();
    LOCALE_IO toggle;       // Switch the locale to standard C

    for( unsigned i = 0; i < sheetList.size(); i++ )
    {
        m_parent->SetCurrentSheet( sheetList[i] );
        m_parent->GetCurrentSheet().UpdateAllScreenReferences();
        m_parent->SetSheetNumberAndCount();
        screen = m_parent->GetCurrentSheet().LastScreen();

        if( i == 0 )
        {

            try
            {
                wxString fname = m_parent->GetUniqueFilenameForCurrentSheet();
                wxString ext = PDF_PLOTTER::GetDefaultFileExtension();
                plotFileName = createPlotFileName( m_outputDirectoryName,
                                                   fname, ext, &reporter );

                if( !plotter->OpenFile( plotFileName.GetFullPath() ) )
                {
                    msg.Printf( _( "Unable to create file '%s'.\n" ),
                                GetChars( plotFileName.GetFullPath() ) );
                    reporter.Report( msg, REPORTER::RPT_ERROR );
                    delete plotter;
                    return;
                }

                // Open the plotter and do the first page
                setupPlotPagePDF( plotter, screen );
                plotter->StartPlot();
            }
            catch( const IO_ERROR& e )
            {
                // Cannot plot PDF file
                msg.Printf( wxT( "PDF Plotter exception: %s" ), GetChars( e.errorText ) );
                reporter.Report( msg, REPORTER::RPT_ERROR );

                restoreEnvironment( plotter, oldsheetpath );
                return;
            }

        }
        else
        {
            /* For the following pages you need to close the (finished) page,
             *  reconfigure, and then start a new one */
            plotter->ClosePage();
            setupPlotPagePDF( plotter, screen );
            plotter->StartPage();
        }

        plotOneSheetPDF( plotter, screen, aPlotFrameRef );
    }

    // Everything done, close the plot and restore the environment
    msg.Printf( _( "Plot: '%s' OK.\n" ), GetChars( plotFileName.GetFullPath() ) );
    reporter.Report( msg, REPORTER::RPT_ACTION );

    restoreEnvironment( plotter, oldsheetpath );
}
Esempio n. 20
0
int TestMultiunitFootprints( SCH_SHEET_LIST& aSheetList )
{
    int errors = 0;
    std::map<wxString, LIB_ID> footprints;
    SCH_MULTI_UNIT_REFERENCE_MAP refMap;
    aSheetList.GetMultiUnitComponents( refMap, true );

    for( auto& component : refMap )
    {
        auto& refList = component.second;

        if( refList.GetCount() == 0 )
        {
            wxFAIL;   // it should not happen
            continue;
        }

        // Reference footprint
        wxString fp;
        wxString unitName;

        for( unsigned i = 0; i < component.second.GetCount(); ++i )
        {
            SCH_COMPONENT* cmp = refList.GetItem( i ).GetComp();
            SCH_SHEET_PATH sheetPath = refList.GetItem( i ).GetSheetPath();
            fp = cmp->GetField( FOOTPRINT )->GetText();

            if( !fp.IsEmpty() )
            {
                unitName = cmp->GetRef( &sheetPath )
                    + LIB_PART::SubReference( cmp->GetUnit(), false );
                break;
            }
        }

        for( unsigned i = 0; i < component.second.GetCount(); ++i )
        {
            SCH_REFERENCE& ref = refList.GetItem( i );
            SCH_COMPONENT* unit = ref.GetComp();
            SCH_SHEET_PATH sheetPath = refList.GetItem( i ).GetSheetPath();
            const wxString curFp = unit->GetField( FOOTPRINT )->GetText();

            if( !curFp.IsEmpty() && fp != curFp )
            {
                wxString curUnitName = unit->GetRef( &sheetPath )
                    + LIB_PART::SubReference( unit->GetUnit(), false );
                wxString msg = wxString::Format( _( "Unit %s has '%s' assigned, "
                                                    "whereas unit %s has '%s' assigned" ),
                                                 unitName,
                                                 fp,
                                                 curUnitName,
                                                 curFp );
                wxPoint pos = unit->GetPosition();

                SCH_MARKER* marker = new SCH_MARKER();
                marker->SetTimeStamp( GetNewTimeStamp() );
                marker->SetData( ERCE_DIFFERENT_UNIT_FP, pos, msg, pos );
                marker->SetMarkerType( MARKER_BASE::MARKER_ERC );
                marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_WARNING );
                ref.GetSheetPath().LastScreen()->Append( marker );

                ++errors;
            }
        }
    }

    return errors;
}
void DIALOG_PLOT_SCHEMATIC::createPSFile( bool aPlotAll, bool aPlotFrameRef )
{
    SCH_SCREEN*     screen = m_parent->GetScreen();
    SCH_SHEET_PATH  oldsheetpath = m_parent->GetCurrentSheet();  // sheetpath is saved here
    PAGE_INFO       actualPage;                                  // page size selected in schematic
    PAGE_INFO       plotPage;                                    // page size selected to plot

    /* When printing all pages, the printed page is not the current page.
     * In complex hierarchies, we must update component references
     *  and others parameters in the given printed SCH_SCREEN, accordint to the sheet path
     *  because in complex hierarchies a SCH_SCREEN (a drawing )
     *  is shared between many sheets and component references depend on the actual sheet path used
     */
    SCH_SHEET_LIST  sheetList;

    if( aPlotAll )
        sheetList.BuildSheetList( g_RootSheet );
    else
        sheetList.push_back( m_parent->GetCurrentSheet() );

    for( unsigned i = 0; i < sheetList.size(); i++ )
    {
        m_parent->SetCurrentSheet( sheetList[i] );
        m_parent->GetCurrentSheet().UpdateAllScreenReferences();
        m_parent->SetSheetNumberAndCount();
        screen = m_parent->GetCurrentSheet().LastScreen();
        actualPage = screen->GetPageSettings();

        switch( m_pageSizeSelect )
        {
        case PAGE_SIZE_A:
            plotPage.SetType( wxT( "A" ) );
            plotPage.SetPortrait( actualPage.IsPortrait() );
            break;

        case PAGE_SIZE_A4:
            plotPage.SetType( wxT( "A4" ) );
            plotPage.SetPortrait( actualPage.IsPortrait() );
            break;

        case PAGE_SIZE_AUTO:
        default:
            plotPage = actualPage;
            break;
        }

        double  scalex  = (double) plotPage.GetWidthMils() / actualPage.GetWidthMils();
        double  scaley  = (double) plotPage.GetHeightMils() / actualPage.GetHeightMils();

        double  scale = std::min( scalex, scaley );

        wxPoint plot_offset;

        wxString outputDirName = m_outputDirectoryName->GetValue();

        wxString msg;
        REPORTER& reporter = m_MessagesBox->Reporter();

        try
        {
            wxString fname = m_parent->GetUniqueFilenameForCurrentSheet();
            wxString ext = PS_PLOTTER::GetDefaultFileExtension();
            wxFileName plotFileName = createPlotFileName( m_outputDirectoryName,
                                                          fname, ext, &reporter );

            if( plotOneSheetPS( plotFileName.GetFullPath(), screen, plotPage, plot_offset,
                                scale, aPlotFrameRef ) )
            {
                msg.Printf( _( "Plot: '%s' OK.\n" ), GetChars( plotFileName.GetFullPath() ) );
                reporter.Report( msg, REPORTER::RPT_ACTION );
            }
            else
            {
                // Error
                msg.Printf( _( "Unable to create file '%s'.\n" ),
                            GetChars( plotFileName.GetFullPath() ) );
                reporter.Report( msg, REPORTER::RPT_ERROR );
            }

        }
        catch( IO_ERROR& e )
        {
            msg.Printf( wxT( "PS Plotter exception: %s"), GetChars( e.errorText ) );
            reporter.Report( msg, REPORTER::RPT_ERROR );
        }
    }

    m_parent->SetCurrentSheet( oldsheetpath );
    m_parent->GetCurrentSheet().UpdateAllScreenReferences();
    m_parent->SetSheetNumberAndCount();
}
bool NETLIST_EXPORTER_CADSTAR::Write( const wxString& aOutFileName, unsigned aNetlistOptions )
{
    (void)aNetlistOptions;      //unused
    int ret = 0;
    FILE* f = NULL;

    if( ( f = wxFopen( aOutFileName, wxT( "wt" ) ) ) == NULL )
    {
        wxString msg;
        msg.Printf( _( "Failed to create file '%s'" ),
                    GetChars( aOutFileName ) );
        DisplayError( NULL, msg );
        return false;
    }

    wxString StartCmpDesc = StartLine + wxT( "ADD_COM" );
    wxString msg;
    wxString footprint;
    SCH_SHEET_PATH* sheet;
    EDA_ITEM* DrawList;
    SCH_COMPONENT* component;
    wxString title = wxT( "Eeschema " ) + GetBuildVersion();

    ret |= fprintf( f, "%sHEA\n", TO_UTF8( StartLine ) );
    ret |= fprintf( f, "%sTIM %s\n", TO_UTF8( StartLine ), TO_UTF8( DateAndTime() ) );
    ret |= fprintf( f, "%sAPP ", TO_UTF8( StartLine ) );
    ret |= fprintf( f, "\"%s\"\n", TO_UTF8( title ) );
    ret |= fprintf( f, "\n" );

    // Prepare list of nets generation
    for( unsigned ii = 0; ii < m_masterList->size(); ii++ )
        m_masterList->GetItem( ii )->m_Flag = 0;

    // Create netlist module section
    m_ReferencesAlreadyFound.Clear();

    SCH_SHEET_LIST SheetList;

    for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() )
    {
        for( DrawList = sheet->LastDrawList(); DrawList != NULL; DrawList = DrawList->Next() )
        {
            DrawList = component = findNextComponentAndCreatePinList( DrawList, sheet );

            if( component == NULL )
                break;

            /*
            doing nothing with footprint
            if( !component->GetField( FOOTPRINT )->IsVoid() )
            {
                footprint = component->GetField( FOOTPRINT )->m_Text;
                footprint.Replace( wxT( " " ), wxT( "_" ) );
            }
            else
                footprint = wxT( "$noname" );
            */

            msg = component->GetRef( sheet );
            ret |= fprintf( f, "%s     ", TO_UTF8( StartCmpDesc ) );
            ret |= fprintf( f, "%s", TO_UTF8( msg ) );

            msg = component->GetField( VALUE )->GetText();
            msg.Replace( wxT( " " ), wxT( "_" ) );
            ret |= fprintf( f, "     \"%s\"", TO_UTF8( msg ) );
            ret |= fprintf( f, "\n" );
        }
    }

    ret |= fprintf( f, "\n" );

    m_SortedComponentPinList.clear();

    if( ! writeListOfNets( f ) )
        ret = -1;   // set error

    ret |= fprintf( f, "\n%sEND\n", TO_UTF8( StartLine ) );

    fclose( f );

    return ret >= 0;
}
Esempio n. 23
0
bool SCH_EDIT_FRAME::EditSheet( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy )
{
    if( aSheet == NULL || aHierarchy == NULL )
        return false;

    SCH_SHEET_LIST hierarchy;       // This is the schematic sheet hierarchy.

    // Get the new texts
    DIALOG_SCH_SHEET_PROPS dlg( this );

    wxString units = GetUnitsLabel( g_UserUnit );
    dlg.SetFileName( aSheet->GetFileName() );
    dlg.SetFileNameTextSize( StringFromValue( g_UserUnit, aSheet->GetFileNameSize() ) );
    dlg.SetFileNameTextSizeUnits( units );
    dlg.SetSheetName( aSheet->GetName() );
    dlg.SetSheetNameTextSize( StringFromValue( g_UserUnit, aSheet->GetSheetNameSize() ) );
    dlg.SetSheetNameTextSizeUnits( units );
    dlg.SetSheetTimeStamp( wxString::Format( wxT("%8.8lX"),
                           (unsigned long) aSheet->GetTimeStamp() ) );

    /* This ugly hack fixes a bug in wxWidgets 2.8.7 and likely earlier
     * versions for the flex grid sizer in wxGTK that prevents the last
     * column from being sized correctly.  It doesn't cause any problems
     * on win32 so it doesn't need to wrapped in ugly #ifdef __WXGTK__
     * #endif.
     * Still presen in wxWidgets 3.0.2
     */
    dlg.Layout();
    dlg.Fit();
    dlg.SetMinSize( dlg.GetSize() );
    dlg.GetSizer()->Fit( &dlg );

    if( dlg.ShowModal() == wxID_CANCEL )
        return false;

    wxFileName fileName = dlg.GetFileName();
    fileName.SetExt( SchematicFileExtension );

    if( !fileName.IsOk() )
    {
        DisplayError( this, _( "File name is not valid!" ) );
        return false;
    }

    // Duplicate sheet names are not valid.
    const SCH_SHEET* sheet = hierarchy.FindSheetByName( dlg.GetSheetName() );

    if( sheet && (sheet != aSheet) )
    {
        DisplayError( this, wxString::Format( _( "A sheet named \"%s\" already exists." ),
                                              GetChars( dlg.GetSheetName() ) ) );
        return false;
    }

    wxString msg;
    bool loadFromFile = false;
    SCH_SCREEN* useScreen = NULL;

    wxString newFilename = fileName.GetFullPath();

    // Search for a schematic file having the same filename
    // already in use in the hierarchy or on disk, in order to reuse it.
    if( !g_RootSheet->SearchHierarchy( newFilename, &useScreen ) )
    {
        // if user entered a relative path, allow that to stay, but do the
        // file existence test with an absolute (full) path.  This transformation
        // is local to this scope, but is the same one used at load time later.
        wxString absolute = Prj().AbsolutePath( newFilename );

        loadFromFile = wxFileExists( absolute );
    }

    // Inside Eeschema, filenames are stored using unix notation
    newFilename.Replace( wxT( "\\" ), wxT( "/" ) );

    if( aSheet->GetScreen() == NULL )              // New sheet.
    {
        if( useScreen || loadFromFile )            // Load from existing file.
        {
            if( useScreen != NULL )
            {
                msg.Printf( _( "A file named '%s' already exists in the current schematic "
                               "hierarchy." ), GetChars( newFilename ) );
            }
            else
            {
                msg.Printf( _( "A file named '%s' already exists." ), GetChars( newFilename ) );
            }

            msg += _( "\n\nDo you want to create a sheet with the contents of this file?" );

            if( !IsOK( this, msg ) )
            {
                return false;
            }
        }
        else                                                   // New file.
        {
            aSheet->SetScreen( new SCH_SCREEN( &Kiway() ) );
            aSheet->GetScreen()->SetMaxUndoItems( m_UndoRedoCountMax );
            aSheet->GetScreen()->SetFileName( newFilename );
        }
    }
    else                                                       // Existing sheet.
    {
        bool isUndoable = true;
        bool renameFile = false;

        // We are always using here a case insensitive comparison
        // to avoid issues under Windows, although under Unix
        // filenames are case sensitive.
        // But many users create schematic under both Unix and Windows
        if( newFilename.CmpNoCase( aSheet->GetFileName() ) != 0 )
        {
            // Sheet file name changes cannot be undone.
            isUndoable = false;
            msg = _( "Changing the sheet file name cannot be undone.  " );

            if( useScreen || loadFromFile )                    // Load from existing file.
            {
                wxString tmp;

                if( useScreen != NULL )
                {
                    tmp.Printf( _( "A file named <%s> already exists in the current schematic "
                                   "hierarchy." ), GetChars( newFilename ) );
                }
                else
                {
                    tmp.Printf( _( "A file named <%s> already exists." ),
                                GetChars( newFilename ) );
                }

                msg += tmp;
                msg += _( "\n\nDo you want to replace the sheet with the contents of this file?" );

                if( !IsOK( this, msg ) )
                    return false;

                if( loadFromFile )
                    aSheet->SetScreen( NULL );
            }
            else                                               // Save to new file name.
            {
                if( aSheet->GetScreenCount() > 1 )
                {
                    msg += _( "This sheet uses shared data in a complex hierarchy.\n\n" );
                    msg += _( "Do you wish to convert it to a simple hierarchical sheet?" );

                    if( !IsOK( NULL, msg ) )
                        return false;
                }

                renameFile = true;
            }
        }

        m_canvas->SetIgnoreMouseEvents( true );

        if( isUndoable )
            SaveCopyInUndoList( aSheet, UR_CHANGED );

        if( renameFile )
        {
            aSheet->GetScreen()->SetFileName( newFilename );
            SaveEEFile( aSheet->GetScreen() );

            // If the the associated screen is shared by more than one sheet, remove the
            // screen and reload the file to a new screen.  Failure to do this will trash
            // the screen reference counting in complex hierarchies.
            if( aSheet->GetScreenCount() > 1 )
            {
                aSheet->SetScreen( NULL );
                loadFromFile = true;
            }
        }
    }

    aSheet->SetFileName( newFilename );

    if( useScreen )
        aSheet->SetScreen( useScreen );
    else if( loadFromFile )
        aSheet->Load( this );

    aSheet->SetFileNameSize( ValueFromString( g_UserUnit, dlg.GetFileNameTextSize() ) );
    aSheet->SetName( dlg.GetSheetName() );
    aSheet->SetSheetNameSize( ValueFromString( g_UserUnit, dlg.GetSheetNameTextSize() ) );

    if( aSheet->GetName().IsEmpty() )
        aSheet->SetName( wxString::Format( wxT( "Sheet%8.8lX" ),
                                           (long unsigned) aSheet->GetTimeStamp() ) );

    // Make sure the sheet changes do not cause any recursion.
    SCH_SHEET_LIST sheetHierarchy( aSheet );

    // Make sure files have fully qualified path and file name.
    wxFileName destFn = aHierarchy->Last()->GetFileName();

    if( destFn.IsRelative() )
        destFn.MakeAbsolute( Prj().GetProjectPath() );

    if( hierarchy.TestForRecursion( sheetHierarchy, destFn.GetFullPath( wxPATH_UNIX ) ) )
    {
        msg.Printf( _( "The sheet changes cannot be made because the destination sheet already "
                       "has the sheet <%s> or one of it's subsheets as a parent somewhere in "
                       "the schematic hierarchy." ),
                    GetChars( newFilename ) );
        DisplayError( this, msg );
        return false;
    }

    m_canvas->MoveCursorToCrossHair();
    m_canvas->SetIgnoreMouseEvents( false );
    OnModify();

    return true;
}
Esempio n. 24
0
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 );
}
void DIALOG_PLOT_SCHEMATIC::createHPGLFile( bool aPlotAll, bool aPlotFrameRef )
{
    SCH_SCREEN*     screen = m_parent->GetScreen();
    SCH_SHEET_PATH  oldsheetpath = m_parent->GetCurrentSheet();

    /* When printing all pages, the printed page is not the current page.
     *  In complex hierarchies, we must setup references and other parameters
     *  in the printed SCH_SCREEN
     *  because in complex hierarchies a SCH_SCREEN (a schematic drawings)
     *  is shared between many sheets
     */
    SCH_SHEET_LIST  sheetList;

    if( aPlotAll )
        sheetList.BuildSheetList( g_RootSheet );
    else
        sheetList.push_back( m_parent->GetCurrentSheet() );

    REPORTER& reporter = m_MessagesBox->Reporter();

    SetHPGLPenWidth();

    for( unsigned i = 0; i < sheetList.size(); i++ )
    {
        m_parent->SetCurrentSheet( sheetList[i] );
        m_parent->GetCurrentSheet().UpdateAllScreenReferences();
        m_parent->SetSheetNumberAndCount();

        screen = m_parent->GetCurrentSheet().LastScreen();

        if( !screen ) // LastScreen() may return NULL
            screen = m_parent->GetScreen();

        const PAGE_INFO&    curPage = screen->GetPageSettings();

        PAGE_INFO           plotPage = curPage;

        // if plotting on a page size other than curPage
        if( m_HPGLPaperSizeOption->GetSelection() != PAGE_DEFAULT )
            plotPage.SetType( plot_sheet_list( m_HPGLPaperSizeOption->GetSelection() ) );

        // Calculation of conversion scales.
        double  plot_scale = (double) plotPage.GetWidthMils() / curPage.GetWidthMils();

        // Calculate offsets
        wxPoint plotOffset;
        wxString msg;

        if( GetPlotOriginCenter() )
        {
            plotOffset.x    = plotPage.GetWidthIU() / 2;
            plotOffset.y    = -plotPage.GetHeightIU() / 2;
        }

        try
        {
            wxString fname = m_parent->GetUniqueFilenameForCurrentSheet();
            wxString ext = HPGL_PLOTTER::GetDefaultFileExtension();
            wxFileName plotFileName = createPlotFileName( m_outputDirectoryName, fname,
                                                          ext, &reporter );

            LOCALE_IO toggle;

            if( Plot_1_Page_HPGL( plotFileName.GetFullPath(), screen, plotPage, plotOffset,
                                  plot_scale, aPlotFrameRef ) )
            {
                msg.Printf( _( "Plot: '%s' OK.\n" ), GetChars( plotFileName.GetFullPath() ) );
                reporter.Report( msg, REPORTER::RPT_ACTION );
            }
            else
            {
                msg.Printf( _( "Unable to create file '%s'.\n" ),
                            GetChars( plotFileName.GetFullPath() ) );
                reporter.Report( msg, REPORTER::RPT_ERROR );
            }
        }
        catch( IO_ERROR& e )
        {
            msg.Printf( wxT( "HPGL Plotter exception: %s"), GetChars( e.errorText ) );
            reporter.Report( msg, REPORTER::RPT_ERROR );
        }

    }

    m_parent->SetCurrentSheet( oldsheetpath );
    m_parent->GetCurrentSheet().UpdateAllScreenReferences();
    m_parent->SetSheetNumberAndCount();
}
Esempio n. 26
0
SCH_ITEM* SCH_EDIT_FRAME::FindComponentAndItem( const wxString& aReference,
                                                bool            aSearchHierarchy,
                                                SCH_SEARCH_T    aSearchType,
                                                const wxString& aSearchText,
                                                bool            aWarpMouse )
{
    SCH_SHEET_PATH* sheet;
    SCH_SHEET_PATH* sheetWithComponentFound = NULL;
    SCH_ITEM*       item = NULL;
    SCH_COMPONENT*  Component = NULL;
    wxPoint         pos, curpos;
    bool            centerAndRedraw = false;
    bool            notFound = true;
    wxString        msg;
    LIB_PIN*        pin;
    SCH_SHEET_LIST  sheetList;

    sheet = sheetList.GetFirst();

    if( !aSearchHierarchy )
        sheet = m_CurrentSheet;

    for( ; sheet != NULL; sheet = sheetList.GetNext() )
    {
        item = (SCH_ITEM*) sheet->LastDrawList();

        for( ; ( item != NULL ) && ( notFound == true ); item = item->Next() )
        {
            if( item->Type() != SCH_COMPONENT_T )
                continue;

            SCH_COMPONENT* pSch = (SCH_COMPONENT*) item;

            if( aReference.CmpNoCase( pSch->GetRef( sheet ) ) == 0 )
            {
                Component = pSch;
                sheetWithComponentFound = sheet;

                switch( aSearchType )
                {
                default:
                case FIND_COMPONENT_ONLY:    // Find component only
                    notFound = false;
                    pos = pSch->GetPosition();
                    break;

                case FIND_PIN:               // find a pin
                    pos = pSch->GetPosition();  // temporary: will be changed if the pin is found.
                    pin = pSch->GetPin( aSearchText );

                    if( pin == NULL )
                        break;

                    notFound = false;
                    pos += pin->GetPosition();
                    break;

                case FIND_REFERENCE:         // find reference
                    notFound = false;
                    pos = pSch->GetField( REFERENCE )->GetPosition();
                    break;

                case FIND_VALUE:             // find value
                    pos = pSch->GetPosition();

                    if( aSearchText.CmpNoCase( pSch->GetField( VALUE )->m_Text ) != 0 )
                        break;

                    notFound = false;
                    pos = pSch->GetField( VALUE )->GetPosition();
                    break;
                }
            }
        }

        if( (aSearchHierarchy == false) || (notFound == false) )
            break;
    }

    if( Component )
    {
        sheet = sheetWithComponentFound;

        if( *sheet != *m_CurrentSheet )
        {
            sheet->LastScreen()->SetZoom( GetScreen()->GetZoom() );
            *m_CurrentSheet = *sheet;
            m_CurrentSheet->UpdateAllScreenReferences();
            centerAndRedraw = true;
        }

        wxPoint delta;
        pos  -= Component->GetPosition();
        delta = Component->GetTransform().TransformCoordinate( pos );
        pos   = delta + Component->GetPosition();


        /* There may be need to reframe the drawing */
        if( ! m_canvas->IsPointOnDisplay( pos ) )
        {
            centerAndRedraw = true;
        }

        if( centerAndRedraw )
        {
            GetScreen()->SetCrossHairPosition(pos);
            RedrawScreen( pos, aWarpMouse );
        }

        else
        {
            INSTALL_UNBUFFERED_DC( dc, m_canvas );

            m_canvas->CrossHairOff( &dc );

            if( aWarpMouse )
                m_canvas->MoveCursor( pos );

            GetScreen()->SetCrossHairPosition(pos);

            m_canvas->CrossHairOn( &dc );
        }
    }


    /* Print diag */
    wxString msg_item;
    msg = aReference;

    switch( aSearchType )
    {
    default:
    case FIND_COMPONENT_ONLY:      // Find component only
        break;

    case FIND_PIN:                 // find a pin
        msg_item = _( "Pin " ) + aSearchText;
        break;

    case FIND_REFERENCE:           // find reference
        msg_item = _( "Ref " ) + aSearchText;
        break;

    case FIND_VALUE:               // find value
        msg_item = _( "Value " ) + aSearchText;
        break;

    case FIND_FIELD:               // find field. todo
        msg_item = _( "Field " ) + aSearchText;
        break;
    }

    if( Component )
    {
        if( !notFound )
        {
            if( !msg_item.IsEmpty() )
                msg += wxT( " " ) + msg_item;

            msg += _( " found" );
        }
        else
        {
            msg += _( " found" );

            if( !msg_item.IsEmpty() )
            {
                msg += wxT( " but " ) + msg_item + _( " not found" );
            }
        }
    }
    else
    {
        if( !msg_item.IsEmpty() )
            msg += wxT( " " ) + msg_item;

        msg += _( " not found" );
    }

    SetStatusText( msg );

    return item;
}
XNODE* NETLIST_EXPORTER_GENERIC::makeComponents()
{
    XNODE*      xcomps = node( wxT( "components" ) );

    wxString    timeStamp;

    // some strings we need many times, but don't want to construct more
    // than once for performance.  These are used within loops so the
    // enclosing wxString constructor would fire on each loop iteration if
    // they were in a nested scope.

    // these are actually constructor invocations, not assignments as it appears:
    wxString    sFields     = wxT( "fields" );
    wxString    sField      = wxT( "field" );
    wxString    sComponent  = wxT( "comp" );          // use "part" ?
    wxString    sName       = wxT( "name" );
    wxString    sRef        = wxT( "ref" );
    wxString    sPins       = wxT( "pins" );
    wxString    sPin        = wxT( "pin" );
    wxString    sValue      = wxT( "value" );
    wxString    sSheetPath  = wxT( "sheetpath" );
    wxString    sFootprint  = wxT( "footprint" );
    wxString    sDatasheet  = wxT( "datasheet" );
    wxString    sTStamp     = wxT( "tstamp" );
    wxString    sTStamps    = wxT( "tstamps" );
    wxString    sTSFmt      = wxT( "%8.8lX" );        // comp->m_TimeStamp
    wxString    sLibSource  = wxT( "libsource" );
    wxString    sLibPart    = wxT( "libpart" );
    wxString    sLib        = wxT( "lib" );
    wxString    sPart       = wxT( "part" );
    wxString    sNames      = wxT( "names" );

    m_ReferencesAlreadyFound.Clear();

    SCH_SHEET_LIST sheetList;

    // Output is xml, so there is no reason to remove spaces from the field values.
    // And XML element names need not be translated to various languages.

    for( SCH_SHEET_PATH* path = sheetList.GetFirst();  path;  path = sheetList.GetNext() )
    {
        for( EDA_ITEM* schItem = path->LastDrawList();  schItem;  schItem = schItem->Next() )
        {
            SCH_COMPONENT*  comp = findNextComponentAndCreatePinList( schItem, path );
            if( !comp )
                break;  // No component left

            schItem = comp;

            XNODE* xcomp;  // current component being constructed

            // 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.

            xcomps->AddChild( xcomp = node( sComponent ) );
            xcomp->AddAttribute( sRef, comp->GetRef( path->Last() ) );

            xcomp->AddChild( node( sValue, comp->GetField( VALUE )->GetText() ) );

            if( !comp->GetField( FOOTPRINT )->IsVoid() )
                xcomp->AddChild( node( sFootprint, comp->GetField( FOOTPRINT )->GetText() ) );

            if( !comp->GetField( DATASHEET )->IsVoid() )
                xcomp->AddChild( node( sDatasheet, comp->GetField( DATASHEET )->GetText() ) );

            // Export all user defined fields within the component,
            // which start at field index MANDATORY_FIELDS.  Only output the <fields>
            // container element if there are any <field>s.
            if( comp->GetFieldCount() > MANDATORY_FIELDS )
            {
                XNODE* xfields;
                xcomp->AddChild( xfields = node( sFields ) );

                for( int fldNdx = MANDATORY_FIELDS; fldNdx < comp->GetFieldCount(); ++fldNdx )
                {
                    SCH_FIELD*  f = comp->GetField( fldNdx );

                    // only output a field if non empty and not just "~"
                    if( !f->IsVoid() )
                    {
                        XNODE*  xfield;
                        xfields->AddChild( xfield = node( sField, f->GetText() ) );
                        xfield->AddAttribute( sName, f->GetName() );
                    }
                }
            }

            XNODE*  xlibsource;
            xcomp->AddChild( xlibsource = node( sLibSource ) );

            // "logical" library name, which is in anticipation of a better search
            // algorithm for parts based on "logical_lib.part" and where logical_lib
            // is merely the library name minus path and extension.
            LIB_PART* part = m_libs->FindLibPart( comp->GetPartName() );
            if( part )
                xlibsource->AddAttribute( sLib, part->GetLib()->GetLogicalName() );

            xlibsource->AddAttribute( sPart, comp->GetPartName() );

            XNODE* xsheetpath;

            xcomp->AddChild( xsheetpath = node( sSheetPath ) );
            xsheetpath->AddAttribute( sNames, path->PathHumanReadable() );
            xsheetpath->AddAttribute( sTStamps, path->Path() );

            timeStamp.Printf( sTSFmt, (unsigned long)comp->GetTimeStamp() );
            xcomp->AddChild( node( sTStamp, timeStamp ) );
        }
    }

    return xcomps;
}
XNODE* NETLIST_EXPORTER_GENERIC::makeDesignHeader()
{
    SCH_SCREEN* screen;
    XNODE*     xdesign = node( wxT("design") );
    XNODE*     xtitleBlock;
    XNODE*     xsheet;
    XNODE*     xcomment;
    wxString   sheetTxt;
    wxFileName sourceFileName;

    // the root sheet is a special sheet, call it source
    xdesign->AddChild( node( wxT( "source" ), g_RootSheet->GetScreen()->GetFileName() ) );

    xdesign->AddChild( node( wxT( "date" ), DateAndTime() ) );

    // which Eeschema tool
    xdesign->AddChild( node( wxT( "tool" ), wxT( "Eeschema " ) + GetBuildVersion() ) );

    /*
        Export the sheets information
    */
    SCH_SHEET_LIST sheetList;

    for( SCH_SHEET_PATH* sheet = sheetList.GetFirst();  sheet;  sheet = sheetList.GetNext() )
    {
        screen = sheet->LastScreen();

        xdesign->AddChild( xsheet = node( wxT( "sheet" ) ) );

        // get the string representation of the sheet index number.
        // Note that sheet->GetIndex() is zero index base and we need to increment the number by one to make
        // human readable
        sheetTxt.Printf( wxT( "%d" ), ( sheetList.GetIndex() + 1 ) );
        xsheet->AddAttribute( wxT( "number" ), sheetTxt );
        xsheet->AddAttribute( wxT( "name" ), sheet->PathHumanReadable() );
        xsheet->AddAttribute( wxT( "tstamps" ), sheet->Path() );


        TITLE_BLOCK tb = screen->GetTitleBlock();

        xsheet->AddChild( xtitleBlock = node( wxT( "title_block" ) ) );

        xtitleBlock->AddChild( node( wxT( "title" ), tb.GetTitle() ) );
        xtitleBlock->AddChild( node( wxT( "company" ), tb.GetCompany() ) );
        xtitleBlock->AddChild( node( wxT( "rev" ), tb.GetRevision() ) );
        xtitleBlock->AddChild( node( wxT( "date" ), tb.GetDate() ) );

        // We are going to remove the fileName directories.
        sourceFileName = wxFileName( screen->GetFileName() );
        xtitleBlock->AddChild( node( wxT( "source" ), sourceFileName.GetFullName() ) );

        xtitleBlock->AddChild( xcomment = node( wxT( "comment" ) ) );
        xcomment->AddAttribute( wxT("number"), wxT("1") );
        xcomment->AddAttribute( wxT( "value" ), tb.GetComment1() );

        xtitleBlock->AddChild( xcomment = node( wxT( "comment" ) ) );
        xcomment->AddAttribute( wxT("number"), wxT("2") );
        xcomment->AddAttribute( wxT( "value" ), tb.GetComment2() );

        xtitleBlock->AddChild( xcomment = node( wxT( "comment" ) ) );
        xcomment->AddAttribute( wxT("number"), wxT("3") );
        xcomment->AddAttribute( wxT( "value" ), tb.GetComment3() );

        xtitleBlock->AddChild( xcomment = node( wxT( "comment" ) ) );
        xcomment->AddAttribute( wxT("number"), wxT("4") );
        xcomment->AddAttribute( wxT( "value" ), tb.GetComment4() );
    }

    return xdesign;
}
Esempio n. 29
0
void SCH_EDIT_FRAME::OnFindSchematicItem( wxFindDialogEvent& aEvent )
{
    static wxPoint itemPosition;  // the actual position of the matched item.

    SCH_SHEET_LIST schematic;
    wxString msg;
    SCH_FIND_REPLACE_DATA searchCriteria;
    bool warpCursor = !( aEvent.GetFlags() & FR_NO_WARP_CURSOR );
    SCH_FIND_COLLECTOR_DATA data;

    searchCriteria.SetFlags( aEvent.GetFlags() );
    searchCriteria.SetFindString( aEvent.GetFindString() );
    searchCriteria.SetReplaceString( aEvent.GetReplaceString() );

    if( aEvent.GetEventType() == wxEVT_COMMAND_FIND_CLOSE )
    {
        if( m_foundItems.GetCount() == 0 )
            return;
    }
    else if( m_foundItems.IsSearchRequired( searchCriteria ) )
    {
        if( aEvent.GetFlags() & FR_CURRENT_SHEET_ONLY && g_RootSheet->CountSheets() > 1 )
        {
            m_foundItems.Collect( searchCriteria, m_CurrentSheet );
        }
        else
        {
            m_foundItems.Collect( searchCriteria );
        }
    }
    else
    {
        EDA_ITEM* currentItem = m_foundItems.GetItem( data );

        if( currentItem != NULL )
            currentItem->SetForceVisible( false );

        m_foundItems.UpdateIndex();
    }

    if( m_foundItems.GetItem( data ) != NULL )
    {
        wxLogTrace( traceFindReplace, wxT( "Found " ) + m_foundItems.GetText() );

        SCH_SHEET_PATH* sheet = schematic.GetSheet( data.GetSheetPath() );

        wxCHECK_RET( sheet != NULL, wxT( "Could not find sheet path " ) +
                     data.GetSheetPath() );

        // Make the item temporarily visible just in case it's hide flag is set.  This
        // has no effect on objects that don't support hiding.  If this is a close find
        // dialog event, clear the temporary visibility flag.
        if( aEvent.GetEventType() == wxEVT_COMMAND_FIND_CLOSE )
            m_foundItems.GetItem( data )->SetForceVisible( false );
        else
            m_foundItems.GetItem( data )->SetForceVisible( true );

        if( sheet->PathHumanReadable() != m_CurrentSheet->PathHumanReadable() )
        {
            sheet->LastScreen()->SetZoom( GetScreen()->GetZoom() );
            *m_CurrentSheet = *sheet;
            m_CurrentSheet->UpdateAllScreenReferences();
            SetScreen( sheet->LastScreen() );
        }

        sheet->LastScreen()->SetCrossHairPosition( data.GetPosition() );

        RedrawScreen( data.GetPosition(), warpCursor );

        msg = m_foundItems.GetText();

        if( aEvent.GetFlags() & FR_SEARCH_REPLACE )
            aEvent.SetFlags( aEvent.GetFlags() | FR_REPLACE_ITEM_FOUND );
    }
    else
    {
        if( aEvent.GetFlags() & FR_SEARCH_REPLACE )
            aEvent.SetFlags( aEvent.GetFlags() & ~FR_REPLACE_ITEM_FOUND );

        msg.Printf( _( "No item found matching %s." ), GetChars( aEvent.GetFindString() ) );
    }

    SetStatusText( msg );
}
Esempio n. 30
0
void SCH_EDIT_FRAME::backAnnotateFootprints( const std::string& aChangedSetOfReferences )
    throw( IO_ERROR, boost::bad_pointer )
{
    // Build a flat list of components in schematic:
    SCH_REFERENCE_LIST  refs;
    SCH_SHEET_LIST      sheets;
    bool                isChanged = false;

    sheets.GetComponents( Prj().SchLibs(), refs, false );

    DSNLEXER    lexer( aChangedSetOfReferences, FROM_UTF8( __func__ ) );
    PTREE       doc;

    try
    {
        Scan( &doc, &lexer );

#if defined(DEBUG) && 0
        STRING_FORMATTER sf;
        Format( &sf, 0, 0, doc );
        printf( "%s: '%s'\n", __func__, sf.GetString().c_str() );
#endif

        CPTREE& back_anno = doc.get_child( "back_annotation" );
        wxString footprint;

        for( PTREE::const_iterator ref = back_anno.begin();  ref != back_anno.end();  ++ref )
        {
            wxASSERT( ref->first == "ref" );

            wxString reference = (UTF8&) ref->second.front().first;

            // Ensure the "fpid" node contains a footprint name,
            // and get it if exists
            if( ref->second.get_child( "fpid" ).size() )
            {
                wxString tmp = (UTF8&) ref->second.get_child( "fpid" ).front().first;
                footprint = tmp;
            }
            else
                footprint.Empty();

            // DBG( printf( "%s: ref:%s  fpid:%s\n", __func__, TO_UTF8( reference ), TO_UTF8( footprint ) ); )

            // Search the component in the flat list
            for( unsigned ii = 0;  ii < refs.GetCount();  ++ii )
            {
                if( Cmp_KEEPCASE( reference, refs[ii].GetRef() ) == 0 )
                {
                    // We have found a candidate.
                    // Note: it can be not unique (multiple parts per package)
                    // So we *do not* stop the search here
                    SCH_COMPONENT*  component = refs[ii].GetComp();
                    SCH_FIELD*      fpfield   = component->GetField( FOOTPRINT );
                    const wxString& oldfp = fpfield->GetText();

                    if( !oldfp && fpfield->IsVisible() )
                    {
                        fpfield->SetVisible( false );
                    }

                    // DBG( printf("%s: ref:%s  fpid:%s\n", __func__, TO_UTF8( refs[ii].GetRef() ), TO_UTF8( footprint ) );)
                    if( oldfp != footprint )
                        isChanged = true;

                    fpfield->SetText( footprint );
                }
            }
        }
    }
    catch( const PTREE_ERROR& ex )
    {
        // remap the exception to something the caller is likely to understand.
        THROW_IO_ERROR( ex.what() );
    }

    if( isChanged )
        OnModify();
}