예제 #1
0
const FP_LIB_TABLE::ROW* FP_LIB_TABLE::FindRowByURI( const wxString& aURI )
{
    FP_LIB_TABLE* cur = this;

    do
    {
        cur->ensureIndex();

        for( unsigned i = 0;  i < cur->rows.size();  i++ )
        {
            wxString uri = cur->rows[i].GetFullURI( true );

            if( wxFileName::GetPathSeparator() == wxChar( '\\' ) && uri.Find( wxChar( '/' ) ) >= 0 )
                uri.Replace( wxT( "/" ), wxT( "\\" ) );

            if( (wxFileName::IsCaseSensitive() && uri == aURI)
              || (!wxFileName::IsCaseSensitive() && uri.Upper() == aURI.Upper() ) )
            {
                return &cur->rows[i];  // found
            }
        }

        // not found, search fall back table(s), if any
    } while( ( cur = cur->fallBack ) != 0 );

    return 0;   // not found
}
bool CVPCB_MAINFRAME::LoadFootprintFiles()
{
    FP_LIB_TABLE* fptbl = Prj().PcbFootprintLibs();

    // Check if there are footprint libraries in the footprint library table.
    if( !fptbl || !fptbl->GetLogicalLibs().size() )
    {
        wxMessageBox( _( "No PCB footprint libraries are listed in the current footprint "
                         "library table." ), _( "Configuration Error" ), wxOK | wxICON_ERROR );
        return false;
    }

    {
    wxBusyCursor dummy;  // Let the user know something is happening.

    m_FootprintsList.ReadFootprintFiles( fptbl );
    }

    if( m_FootprintsList.GetErrorCount() )
    {
        m_FootprintsList.DisplayErrors( this );
    }

    return true;
}
예제 #3
0
wxString PCB_BASE_FRAME::SelectLibrary( const wxString& aNicknameExisting )
{
    wxArrayString headers;

    headers.Add( _( "Nickname" ) );
    headers.Add( _( "Description" ) );

    FP_LIB_TABLE*   fptbl = Prj().PcbFootprintLibs();

    std::vector< wxArrayString > itemsToDisplay;
    std::vector< wxString >      nicknames = fptbl->GetLogicalLibs();

    for( unsigned i = 0; i < nicknames.size(); i++ )
    {
        wxArrayString item;

        item.Add( nicknames[i] );
        item.Add( fptbl->GetDescription( nicknames[i] ) );

        itemsToDisplay.push_back( item );
    }

    EDA_LIST_DIALOG dlg( this, FMT_SELECT_LIB, headers, itemsToDisplay, aNicknameExisting );

    if( dlg.ShowModal() != wxID_OK )
        return wxEmptyString;

    wxString nickname = dlg.GetTextSelection();

    wxLogDebug( wxT( "Chose footprint library '%s'." ), GetChars( nickname ) );

    return nickname;
}
예제 #4
0
FP_LIB_TABLE* PROJECT::PcbFootprintLibs()
{
    // This is a lazy loading function, it loads the project specific table when
    // that table is asked for, not before.

    FP_LIB_TABLE*   tbl = (FP_LIB_TABLE*) GetElem( ELEM_FPTBL );

    // its gotta be NULL or a FP_LIB_TABLE, or a bug.
    wxASSERT( !tbl || dynamic_cast<FP_LIB_TABLE*>( tbl ) );

    if( !tbl )
    {
        // Stack the project specific FP_LIB_TABLE overlay on top of the global table.
        // ~FP_LIB_TABLE() will not touch the fallback table, so multiple projects may
        // stack this way, all using the same global fallback table.
        tbl = new FP_LIB_TABLE( &GFootprintTable );

        SetElem( ELEM_FPTBL, tbl );

        wxString projectFpLibTableFileName = FootprintLibTblName();

        try
        {
            tbl->Load( projectFpLibTableFileName );
        }
        catch( const IO_ERROR& ioe )
        {
            DisplayError( NULL, ioe.errorText );
        }
    }

    return tbl;
}
예제 #5
0
bool FP_LIB_TABLE::LoadGlobalTable( FP_LIB_TABLE& aTable ) throw (IO_ERROR, PARSE_ERROR )
{
    bool        tableExists = true;
    wxFileName  fn = GetGlobalTableFileName();

    if( !fn.FileExists() )
    {
        tableExists = false;

        if( !fn.DirExists() && !fn.Mkdir( 0x777, wxPATH_MKDIR_FULL ) )
        {
            THROW_IO_ERROR( wxString::Format( _( "Cannot create global library table path '%s'." ),
                                              GetChars( fn.GetPath() ) ) );
        }

        // Attempt to copy the default global file table from the KiCad
        // template folder to the user's home configuration path.
        wxString fileName = Kiface().KifaceSearch().FindValidPath( global_tbl_name );

        // The fallback is to create an empty global footprint table for the user to populate.
        if( fileName.IsEmpty() || !::wxCopyFile( fileName, fn.GetFullPath(), false ) )
        {
            FP_LIB_TABLE    emptyTable;

            emptyTable.Save( fn.GetFullPath() );
        }
    }

    aTable.Load( fn.GetFullPath() );

    return tableExists;
}
예제 #6
0
void CVPCB_MAINFRAME::BuildLIBRARY_LISTBOX()
{
    wxFont   guiFont = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );

    if( m_libListBox == NULL )
    {
        m_libListBox = new LIBRARY_LISTBOX( this, ID_CVPCB_LIBRARY_LIST,
                                            wxDefaultPosition, wxDefaultSize );
        m_libListBox->SetFont( wxFont( guiFont.GetPointSize(),
                                       wxFONTFAMILY_MODERN,
                                       wxFONTSTYLE_NORMAL,
                                       wxFONTWEIGHT_NORMAL ) );
    }

    FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs();

    if( tbl )
    {
        wxArrayString libNames;

        std::vector< wxString > libNickNames = tbl->GetLogicalLibs();

        for( unsigned ii = 0; ii < libNickNames.size(); ii++ )
            libNames.Add( libNickNames[ii] );

        m_libListBox->SetLibraryList( libNames );
    }
}
예제 #7
0
bool FOOTPRINT_EDIT_FRAME::SaveFootprint( MODULE* aModule )
{
    wxString libraryName = aModule->GetFPID().GetLibNickname();
    wxString footprintName = aModule->GetFPID().GetLibItemName();
    bool nameChanged = m_footprintNameWhenLoaded != footprintName;

    if( aModule->GetLink() )
    {
        if( SaveFootprintToBoard( false ) )
        {
            m_footprintNameWhenLoaded = footprintName;
            return true;
        }
        else
            return false;
    }
    else if( libraryName.IsEmpty() || footprintName.IsEmpty() )
    {
        if( SaveFootprintAs( aModule ) )
        {
            m_footprintNameWhenLoaded = footprintName;
            SyncLibraryTree( true );
            return true;
        }
        else
            return false;
    }

    FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs();

    // Legacy libraries are readable, but modifying legacy format is not allowed
    // So prompt the user if he try to add/replace a footprint in a legacy lib
    wxString libfullname = tbl->FindRow( libraryName )->GetFullURI();

    if( IO_MGR::GuessPluginTypeFromLibPath( libfullname ) == IO_MGR::LEGACY )
    {
        DisplayInfoMessage( this, INFO_LEGACY_LIB_WARN_EDIT );
        return false;
    }

    if( nameChanged )
    {
        LIB_ID oldFPID( libraryName, m_footprintNameWhenLoaded );
        DeleteModuleFromLibrary( oldFPID, false );
    }

    if( !saveFootprintInLibrary( aModule, libraryName ) )
        return false;

    if( nameChanged )
    {
        m_footprintNameWhenLoaded = footprintName;
        SyncLibraryTree( true );
    }

    return true;
}
예제 #8
0
MODULE* PCB_BASE_FRAME::loadFootprint( const FPID& aFootprintId )
    throw( IO_ERROR, PARSE_ERROR )
{
    FP_LIB_TABLE*   fptbl = Prj().PcbFootprintLibs();

    wxCHECK_MSG( fptbl, NULL, wxT( "Cannot look up FPID in NULL FP_LIB_TABLE." ) );

    return fptbl->FootprintLoadWithOptionalNickname( aFootprintId );
}
예제 #9
0
void InvokePcbLibTableEditor( KIWAY* aKiway, wxWindow* aCaller )
{
    FP_LIB_TABLE* globalTable = &GFootprintTable;
    wxString      globalTablePath = FP_LIB_TABLE::GetGlobalTableFileName();
    FP_LIB_TABLE* projectTable = aKiway->Prj().PcbFootprintLibs();
    wxString      projectTablePath = aKiway->Prj().FootprintLibTblName();
    wxString      msg;

    DIALOG_EDIT_LIBRARY_TABLES dlg( aCaller, _( "Footprint Libraries" ) );
    dlg.SetKiway( &dlg, aKiway );

    dlg.InstallPanel( new PANEL_FP_LIB_TABLE( &dlg, globalTable, globalTablePath,
                                              projectTable, projectTablePath,
                                              aKiway->Prj().GetProjectPath() ) );

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

    if( dlg.m_GlobalTableChanged )
    {
        try
        {
            globalTable->Save( globalTablePath );
        }
        catch( const IO_ERROR& ioe )
        {
            msg.Printf( _( "Error saving global library table:\n\n%s" ), ioe.What() );
            wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
        }
    }

    if( dlg.m_ProjectTableChanged )
    {
        try
        {
            projectTable->Save( projectTablePath );
        }
        catch( const IO_ERROR& ioe )
        {
            msg.Printf( _( "Error saving project-specific library table:\n\n%s" ), ioe.What() );
            wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
        }
    }

    auto editor = (FOOTPRINT_EDIT_FRAME*) aKiway->Player( FRAME_PCB_MODULE_EDITOR, false );

    if( editor )
        editor->SyncLibraryTree( true );

    auto viewer = (FOOTPRINT_VIEWER_FRAME*) aKiway->Player( FRAME_PCB_MODULE_VIEWER, false );

    if( viewer )
        viewer->ReCreateLibraryList();
}
예제 #10
0
파일: loadcmp.cpp 프로젝트: natsfr/kicad
MODULE* PCB_BASE_FRAME::loadFootprint( const FPID& aFootprintId )
    throw( IO_ERROR, PARSE_ERROR, boost::interprocess::lock_exception )
{
    FP_LIB_TABLE*   fptbl = Prj().PcbFootprintLibs();

    wxCHECK_MSG( fptbl, NULL, wxT( "Cannot look up FPID in NULL FP_LIB_TABLE." ) );

    MODULE* module = fptbl->FootprintLoadWithOptionalNickname( aFootprintId );

    // If the module is found, clear all net info,
    // to be sure there is no broken links
    // to any netinfo list (should be not needed, but it can be edited from
    // the footprint editor )
    if( module )
        module->ClearAllNets();

    return module;
}
예제 #11
0
FP_LIB_TABLE::ROW* FP_LIB_TABLE::findRow( const wxString& aNickName ) const
{
    FP_LIB_TABLE* cur = (FP_LIB_TABLE*) this;

    do
    {
        cur->ensureIndex();

        INDEX_CITER  it = cur->nickIndex.find( aNickName );

        if( it != cur->nickIndex.end() )
        {
            return &cur->rows[it->second];  // found
        }

        // not found, search fall back table(s), if any
    } while( ( cur = cur->fallBack ) != 0 );

    return 0;   // not found
}
예제 #12
0
bool CVPCB_MAINFRAME::LoadFootprintFiles()
{
    FP_LIB_TABLE* fptbl = Prj().PcbFootprintLibs();

    // Check if there are footprint libraries in the footprint library table.
    if( !fptbl || !fptbl->GetLogicalLibs().size() )
    {
        wxMessageBox( _( "No PCB footprint libraries are listed in the current footprint "
                         "library table." ), _( "Configuration Error" ), wxOK | wxICON_ERROR );
        return false;
    }

    m_footprints.ReadFootprintFiles( fptbl );

    if( m_footprints.GetErrorCount() )
    {
        m_footprints.DisplayErrors( this );
    }

    return true;
}
void FOOTPRINT_VIEWER_FRAME::UpdateTitle()
{
    wxString title;
    wxString path;

    title.Printf( _( "Footprint Library Browser" ) + L" \u2014 %s",
            getCurNickname().size()
                ? getCurNickname()
                : _( "no library selected" ) );

    // Now, add the full path, for info
    if( getCurNickname().size() )
    {
        FP_LIB_TABLE* libtable = Prj().PcbFootprintLibs();
        const LIB_TABLE_ROW* row = libtable->FindRow( getCurNickname() );

        if( row )
            title << L" \u2014 " << row->GetFullURI( true );
    }

    SetTitle( title );
}
예제 #14
0
FP_LIB_TABLE* PROJECT::PcbFootprintLibs( KIWAY& aKiway )
{
    // This is a lazy loading function, it loads the project specific table when
    // that table is asked for, not before.

    FP_LIB_TABLE*   tbl = (FP_LIB_TABLE*) GetElem( ELEM_FPTBL );

    // its gotta be NULL or a FP_LIB_TABLE, or a bug.
    wxASSERT( !tbl || dynamic_cast<FP_LIB_TABLE*>( tbl ) );

    if( !tbl )
    {
        // Build a new project specific FP_LIB_TABLE with the global table as a fallback.
        // ~FP_LIB_TABLE() will not touch the fallback table, so multiple projects may
        // stack this way, all using the same global fallback table.
        KIFACE* kiface = aKiway.KiFACE( KIWAY::FACE_PCB );

        if( kiface )
            tbl = (FP_LIB_TABLE*) kiface->IfaceOrAddress( KIFACE_NEW_FOOTPRINT_TABLE );

        wxASSERT( tbl );
        SetElem( ELEM_FPTBL, tbl );

        wxString projectFpLibTableFileName = FootprintLibTblName();

        try
        {
            tbl->Load( projectFpLibTableFileName );
        }
        catch( const IO_ERROR& ioe )
        {
            DisplayErrorMessage( NULL, _( "Error loading project footprint library table" ),
                                 ioe.What() );
        }
    }

    return tbl;
}
void FOOTPRINT_INFO_IMPL::load()
{
    FP_LIB_TABLE* fptable = m_owner->GetTable();

    wxASSERT( fptable );

    const MODULE* footprint = fptable->GetEnumeratedFootprint( m_nickname, m_fpname );

    if( footprint == NULL ) // Should happen only with malformed/broken libraries
    {
        m_pad_count = 0;
        m_unique_pad_count = 0;
    }
    else
    {
        m_pad_count = footprint->GetPadCount( DO_NOT_INCLUDE_NPTH );
        m_unique_pad_count = footprint->GetUniquePadCount( DO_NOT_INCLUDE_NPTH );
        m_keywords = footprint->GetKeywords();
        m_doc = footprint->GetDescription();
    }

    m_loaded = true;
}
예제 #16
0
void FOOTPRINT_INFO::load()
{
    FP_LIB_TABLE*   fptable = m_owner->GetTable();

    wxASSERT( fptable );

    std::auto_ptr<MODULE> m( fptable->FootprintLoad( m_nickname, m_fpname ) );

    if( m.get() == NULL )    // Should happen only with malformed/broken libraries
    {
        m_pad_count = 0;
        m_unique_pad_count = 0;
    }
    else
    {
        m_pad_count = m->GetPadCount( DO_NOT_INCLUDE_NPTH );
        m_unique_pad_count = m->GetUniquePadCount( DO_NOT_INCLUDE_NPTH );
        m_keywords  = m->GetKeywords();
        m_doc       = m->GetDescription();

        // tell ensure_loaded() I'm loaded.
        m_loaded = true;
    }
}
예제 #17
0
bool FOOTPRINT_EDIT_FRAME::SaveFootprintInLibrary( const wxString& aLibrary,
                                             MODULE*         aModule,
                                             bool            aOverwrite,
                                             bool            aDisplayDialog )
{
    if( aModule == NULL )
        return false;

    SetMsgPanel( aModule );


    // Legacy libraries are readable, but modifying legacy format is not allowed
    // So prompt the user if he try to add/replace a footprint in a legacy lib
    wxString    libfullname = Prj().PcbFootprintLibs()->FindRow( aLibrary )->GetFullURI();
    IO_MGR::PCB_FILE_T  piType = IO_MGR::GuessPluginTypeFromLibPath( libfullname );

    if( piType == IO_MGR::LEGACY )
    {
        DisplayInfoMessage( this, INFO_LEGACY_LIB_WARN_EDIT );
        return false;
    }

    // Ask what to use as the footprint name in the library
    wxString footprintName = aModule->GetFPID().GetFootprintName();

    if( aDisplayDialog )
    {
        wxTextEntryDialog dlg( this, _( "Name:" ), FMT_SAVE_MODULE, footprintName );

        if( dlg.ShowModal() != wxID_OK )
            return false;                   // canceled by user

        footprintName = dlg.GetValue();
        footprintName.Trim( true );
        footprintName.Trim( false );

        if( footprintName.IsEmpty() )
            return false;

        if( ! MODULE::IsLibNameValid( footprintName ) )
        {
            wxString msg = wxString::Format(
                    _("Error:\none of invalid chars '%s' found\nin '%s'" ),
                    MODULE::StringLibNameInvalidChars( true ),
                    GetChars( footprintName ) );

            DisplayError( NULL, msg );
            return false;
        }

        aModule->SetFPID( FPID( footprintName ) );
    }

    // Ensure this footprint has a libname
    if( footprintName.IsEmpty() )
    {
        footprintName = wxT("noname");
        aModule->SetFPID( FPID( footprintName ) );
    }

    bool module_exists = false;

    try
    {
        FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs();

        MODULE* m = tbl->FootprintLoad( aLibrary, footprintName );

        if( m )
        {
            delete m;

            module_exists = true;

            // an existing footprint is found in current lib
            if( aDisplayDialog )
            {
                wxString msg = wxString::Format( FMT_MOD_EXISTS,
                        footprintName.GetData(), aLibrary.GetData() );

                SetStatusText( msg );
            }

            if( !aOverwrite )
            {
                // Do not save the given footprint: an old one exists
                return true;
            }
        }

        // this always overwrites any existing footprint, but should yell on its
        // own if the library or footprint is not writable.
        tbl->FootprintSave( aLibrary, aModule );
    }
    catch( const IO_ERROR& ioe )
    {
        DisplayError( this, ioe.errorText );
        return false;
    }

    if( aDisplayDialog )
    {
        wxString fmt = module_exists ?
            _( "Component [%s] replaced in '%s'" ) :
            _( "Component [%s] added in  '%s'" );

        wxString msg = wxString::Format( fmt, footprintName.GetData(), aLibrary.GetData() );
        SetStatusText( msg );
    }

    return true;
}
void FOOTPRINT_EDIT_FRAME::OnUpdateSelectCurrentLib( wxUpdateUIEvent& aEvent )
{
    FP_LIB_TABLE* fptbl = Prj().PcbFootprintLibs();

    aEvent.Enable( fptbl && !fptbl->IsEmpty() );
}
예제 #19
0
bool PCB_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
{
    switch( (IO_MGR::PCB_FILE_T) aFileType )
    {
    case IO_MGR::EAGLE:
        if( OpenProjectFiles( std::vector<wxString>( 1, aFileName ), KICTL_EAGLE_BRD ) )
        {
            wxString projectpath = Kiway().Prj().GetProjectPath();
            wxFileName newfilename;

            newfilename.SetPath( Prj().GetProjectPath() );
            newfilename.SetName( Prj().GetProjectName() );
            newfilename.SetExt( KiCadPcbFileExtension );

            GetBoard()->SetFileName( newfilename.GetFullPath() );
            UpdateTitle();
            OnModify();

            // Extract a footprint library from the design and add it to the fp-lib-table
            wxString newLibPath;
            ArchiveModulesOnBoard( true, newfilename.GetName(), &newLibPath );

            if( newLibPath.Length() > 0 )
            {
                FP_LIB_TABLE* prjlibtable = Prj().PcbFootprintLibs();
                const wxString& project_env = PROJECT_VAR_NAME;
                wxString rel_path, env_path;

                wxGetEnv( project_env, &env_path );

                wxString result( newLibPath );
                rel_path =  result.Replace( env_path,
                                            wxString( "$(" + project_env + ")" ) ) ? result : "" ;

                if( !rel_path.IsEmpty() )
                    newLibPath = rel_path;

                FP_LIB_TABLE_ROW* row = new FP_LIB_TABLE_ROW( newfilename.GetName(),
                        newLibPath, wxT( "KiCad" ), wxEmptyString );
                prjlibtable->InsertRow( row );
            }

            if( !GetBoard()->GetFileName().IsEmpty() )
            {
                wxString tblName = Prj().FootprintLibTblName();

                try
                {
                    Prj().PcbFootprintLibs()->Save( tblName );
                }
                catch( const IO_ERROR& ioe )
                {
                    wxString msg = wxString::Format( _(
                                    "Error occurred saving project specific footprint library "
                                    "table:\n\n%s" ),
                            GetChars( ioe.What() ) );
                    wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
                }
            }


            // Update module LIB_IDs to point to the just imported Eagle library
            for( MODULE* module : GetBoard()->Modules() )
            {
                LIB_ID libId = module->GetFPID();

                if( libId.GetLibItemName().empty() )
                    continue;

                libId.SetLibNickname( newfilename.GetName() );
                module->SetFPID( libId );
            }


            // Store net names for all pads, to create net remap information
            std::unordered_map<D_PAD*, wxString> netMap;

            for( const auto& pad : GetBoard()->GetPads() )
            {
                NETINFO_ITEM* netinfo = pad->GetNet();

                if( netinfo->GetNet() > 0 && !netinfo->GetNetname().IsEmpty() )
                    netMap[pad] = netinfo->GetNetname();
            }

            // Two stage netlist update:
            // - first, assign valid timestamps to footprints (no reannotation)
            // - second, perform schematic annotation and update footprint references
            //   based on timestamps
            NETLIST netlist;
            FetchNetlistFromSchematic( netlist, NO_ANNOTATION );
            DoUpdatePCBFromNetlist( netlist, false );
            FetchNetlistFromSchematic( netlist, QUIET_ANNOTATION );
            DoUpdatePCBFromNetlist( netlist, true );

            std::unordered_map<wxString, wxString> netRemap;

            // Compare the old net names with the new net names and create a net map
            for( const auto& pad : GetBoard()->GetPads() )
            {
                auto it = netMap.find( pad );

                if( it == netMap.end() )
                    continue;

                NETINFO_ITEM* netinfo = pad->GetNet();

                // Net name has changed, create a remap entry
                if( netinfo->GetNet() > 0 && netMap[pad] != netinfo->GetNetname() )
                    netRemap[netMap[pad]] = netinfo->GetNetname();
            }

            if( !netRemap.empty() )
                fixEagleNets( netRemap );

            return true;
        }

        return false;

    default:
        return false;
    }

    return false;
}
예제 #20
0
bool FOOTPRINT_EDIT_FRAME::SaveFootprintAs( MODULE* aModule )
{
    if( aModule == NULL )
        return false;

    FP_LIB_TABLE* tbl = Prj().PcbFootprintLibs();

    SetMsgPanel( aModule );

    wxString libraryName = aModule->GetFPID().GetLibNickname();
    wxString footprintName = aModule->GetFPID().GetLibItemName();
    bool updateValue = ( aModule->GetValue() == footprintName );

    wxArrayString              headers;
    std::vector<wxArrayString> itemsToDisplay;
    std::vector<wxString>      nicknames = tbl->GetLogicalLibs();

    headers.Add( _( "Nickname" ) );
    headers.Add( _( "Description" ) );

    for( unsigned i = 0; i < nicknames.size(); i++ )
    {
        wxArrayString item;
        item.Add( nicknames[i] );
        item.Add( tbl->GetDescription( nicknames[i] ) );
        itemsToDisplay.push_back( item );
    }

    EDA_LIST_DIALOG dlg( this, FMT_SAVE_MODULE, headers, itemsToDisplay, libraryName,
                         nullptr, nullptr, /* sort */ false, /* show headers */ false );
    dlg.SetListLabel( _( "Save in library:" ) );
    dlg.SetOKLabel( _( "Save" ) );

    wxBoxSizer* bNameSizer = new wxBoxSizer( wxHORIZONTAL );

    wxStaticText* label = new wxStaticText( &dlg, wxID_ANY, _( "Name:" ),
                                            wxDefaultPosition, wxDefaultSize, 0 );
    bNameSizer->Add( label, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxLEFT, 5 );

    wxTextCtrl* nameTextCtrl = new wxTextCtrl( &dlg, wxID_ANY, footprintName,
                                               wxDefaultPosition, wxDefaultSize, 0 );
    bNameSizer->Add( nameTextCtrl, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 );

    wxTextValidator nameValidator( wxFILTER_EXCLUDE_CHAR_LIST );
    nameValidator.SetCharExcludes( MODULE::StringLibNameInvalidChars( false ) );
    nameTextCtrl->SetValidator( nameValidator );

    wxSizer* mainSizer = dlg.GetSizer();
    mainSizer->Prepend( bNameSizer, 0, wxEXPAND|wxTOP|wxLEFT|wxRIGHT, 5 );

    // Move nameTextCtrl to the head of the tab-order
    if( dlg.GetChildren().DeleteObject( nameTextCtrl ) )
        dlg.GetChildren().Insert( nameTextCtrl );

    dlg.SetInitialFocus( nameTextCtrl );

    dlg.Layout();
    mainSizer->Fit( &dlg );

    if( dlg.ShowModal() != wxID_OK )
        return false;                   // canceled by user

    libraryName = dlg.GetTextSelection();

    if( libraryName.IsEmpty() )
    {
        DisplayError( NULL, _( "No library specified.  Footprint could not be saved." ) );
        return false;
    }

    footprintName = nameTextCtrl->GetValue();
    footprintName.Trim( true );
    footprintName.Trim( false );

    if( footprintName.IsEmpty() )
    {
        DisplayError( NULL, _( "No footprint name specified.  Footprint could not be saved." ) );
        return false;
    }

    aModule->SetFPID( LIB_ID( libraryName, footprintName ) );

    if( updateValue )
        aModule->SetValue( footprintName );

    // Legacy libraries are readable, but modifying legacy format is not allowed
    // So prompt the user if he try to add/replace a footprint in a legacy lib
    wxString    libfullname = Prj().PcbFootprintLibs()->FindRow( libraryName )->GetFullURI();
    IO_MGR::PCB_FILE_T  piType = IO_MGR::GuessPluginTypeFromLibPath( libfullname );

    if( piType == IO_MGR::LEGACY )
    {
        DisplayInfoMessage( this, INFO_LEGACY_LIB_WARN_EDIT );
        return false;
    }

    bool module_exists = tbl->FootprintExists( libraryName, footprintName );

    if( module_exists )
    {
        wxString msg = wxString::Format( _( "Footprint %s already exists in %s." ),
                                         footprintName,
                                         libraryName );
        KIDIALOG chkdlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
        chkdlg.SetOKLabel( _( "Overwrite" ) );

        if( chkdlg.ShowModal() == wxID_CANCEL )
            return false;
    }

    if( !saveFootprintInLibrary( aModule, libraryName ) )
        return false;

    // Once saved-as a board footprint is no longer a board footprint
    aModule->SetLink( 0 );

    wxString fmt = module_exists ? _( "Component \"%s\" replaced in \"%s\"" ) :
                                   _( "Component \"%s\" added in  \"%s\"" );

    wxString msg = wxString::Format( fmt, footprintName.GetData(), libraryName.GetData() );
    SetStatusText( msg );
    updateTitle();

    return true;
}
예제 #21
0
void PCB_EDIT_FRAME::ArchiveModulesOnBoard( bool aStoreInNewLib )
{
    if( GetBoard()->m_Modules == NULL )
    {
        DisplayInfoMessage( this, _( "No footprints to archive!" ) );
        return;
    }

    wxString footprintName;

    if( !aStoreInNewLib )
    {
        // The footprints are saved in an existing .pretty library in the fp lib table
        PROJECT&        prj = Prj();
        wxString last_nickname = prj.GetRString( PROJECT::PCB_LIB_NICKNAME );
        wxString nickname = SelectLibrary( last_nickname );

        if( !nickname )     // Aborted
            return;

        prj.SetRString( PROJECT::PCB_LIB_NICKNAME, nickname );

        try
        {
            FP_LIB_TABLE* tbl = prj.PcbFootprintLibs();

            for( MODULE* curr_fp = GetBoard()->m_Modules; curr_fp; curr_fp = curr_fp->Next() )
            {
                if( !curr_fp->GetFPID().GetFootprintName().empty() )      // Can happen with old boards.
                    tbl->FootprintSave( nickname, curr_fp, false );
            }
        }
        catch( const IO_ERROR& ioe )
        {
            DisplayError( this, ioe.errorText );
        }
    }
    else
    {
        // The footprints are saved in a new .pretty library.
        // If this library already exists, all previous footprints will be deleted
        wxString libPath = CreateNewLibrary();

        if( libPath.IsEmpty() )     // Aborted
            return;

        IO_MGR::PCB_FILE_T  piType = IO_MGR::KICAD;
        PLUGIN::RELEASER  pi( IO_MGR::PluginFind( piType ) );

        for( MODULE* curr_fp = GetBoard()->m_Modules; curr_fp; curr_fp = curr_fp->Next() )
        {
            try
            {
                if( !curr_fp->GetFPID().GetFootprintName().empty() )      // Can happen with old boards.
                    pi->FootprintSave( libPath, curr_fp );
            }
            catch( const IO_ERROR& ioe )
            {
                DisplayError( this, ioe.errorText );
            }
        }
    }
}