readwrite_dlgs.cpp 9.64 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
/**
 * @file cvpcb/readwrite_dlgs.cpp
 */

/*
 * This program source code file is part of KiCad, a free EDA CAD application.
 *
 * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras
 * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
 * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you may find one here:
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * or you may search the http://www.gnu.org website for the version 2 license,
 * or you may write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 */

#include <fctsys.h>
#include <common.h>
#include <confirm.h>
#include <build_version.h>
34 35 36 37 38
#include <macros.h>
#include <fpid.h>
#include <fp_lib_table.h>
#include <reporter.h>
#include <html_messagebox.h>
39 40 41 42

#include <cvpcb.h>
#include <cvpcb_mainframe.h>
#include <cvstruct.h>
43
#include <wildcards_and_files_ext.h>
44 45 46 47 48

#define titleComponentLibErr _( "Component Library Error" )

void CVPCB_MAINFRAME::SetNewPkg( const wxString& aFootprintName )
{
49
    COMPONENT* component;
50 51 52
    bool       hasFootprint = false;
    int        componentIndex;
    wxString   description;
53

54
    if( m_netlist.IsEmpty() )
55 56
        return;

57 58
    // If no component is selected, select the first one
    if( m_ListCmp->GetFirstSelected() < 0 )
59
    {
60 61
        componentIndex = 0;
        m_ListCmp->SetSelection( componentIndex, true );
62 63
    }

64
    // iterate over the selection
65
    while( m_ListCmp->GetFirstSelected() != -1 )
66
    {
67
        // Get the component for the current iteration
68
        componentIndex = m_ListCmp->GetFirstSelected();
69
        component = m_netlist.GetComponent( componentIndex );
70

71 72
        if( component == NULL )
            return;
73

74
        // Check to see if the component has already a footprint set.
75
        hasFootprint = !component->GetFPID().empty();
76

77 78
        FPID fpid;

79 80 81 82 83 84
        if( !aFootprintName.IsEmpty() )
        {
            wxCHECK_RET( fpid.Parse( aFootprintName ) < 0,
                         wxString::Format( wxT( "<%s> is not a valid FPID." ),
                                           GetChars( aFootprintName ) ) );
        }
85 86

        component->SetFPID( fpid );
87

88 89
        // create the new component description
        description.Printf( CMP_FORMAT, componentIndex + 1,
90 91
                            GetChars( component->GetReference() ),
                            GetChars( component->GetValue() ),
92
                            GetChars( FROM_UTF8( component->GetFPID().Format().c_str() ) ) );
93

94
        // If the component hasn't had a footprint associated with it
95 96 97 98 99 100 101 102
        // it now has, so we decrement the count of components without
        // a footprint assigned.
        if( !hasFootprint )
        {
            hasFootprint = true;
            m_undefinedComponentCnt -= 1;
        }

103
        // Set the new description and deselect the processed component
104 105
        m_ListCmp->SetString( componentIndex, description );
        m_ListCmp->SetSelection( componentIndex, false );
106
    }
107

108
    // Mark this "session" as modified
109
    m_modified = true;
110

111 112 113
    // select the next component, if there is one
    if( componentIndex < (m_ListCmp->GetCount() - 1) )
        componentIndex++;
114

115
    m_ListCmp->SetSelection( componentIndex, true );
116

117 118
    // update the statusbar
    DisplayStatus();
119 120 121 122 123
}


bool CVPCB_MAINFRAME::ReadNetListAndLinkFiles()
{
124
    COMPONENT* component;
125
    wxString   msg;
126
    bool       isLegacy = true;
127

128
    ReadSchematicNetlist();
129 130 131 132 133 134 135

    if( m_ListCmp == NULL )
        return false;

    LoadProjectFile( m_NetlistFileName.GetFullPath() );
    LoadFootprintFiles();
    BuildFOOTPRINTS_LISTBOX();
136
    BuildLIBRARY_LISTBOX();
137 138 139 140

    m_ListCmp->Clear();
    m_undefinedComponentCnt = 0;

141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
    if( m_netlist.AnyFootprintsLinked() )
    {
        for( unsigned i = 0;  i < m_netlist.GetCount();  i++ )
        {
            component = m_netlist.GetComponent( i );

            if( component->GetFPID().empty() )
                continue;

            if( isLegacy )
            {
                if( !component->GetFPID().IsLegacy() )
                    isLegacy = false;
            }
        }
    }
    else
    {
        isLegacy = false;  // None of the components have footprints assigned.
    }

    wxString missingLibs;

    // Check if footprint links were generated before the footprint library table was implemented.
    if( isLegacy )
    {
        if( m_footprintLibTable->MissingLegacyLibs( m_ModuleLibNames, &missingLibs ) )
        {
            msg = wxT( "The following legacy libraries are defined in the project file "
                       "were not found in the footprint library table:\n\n" ) + missingLibs;
            msg += wxT( "\nDo you want to update the footprint library table before "
                        "attempting to update the assigned footprints?" );

            if( IsOK( this, msg ) )
            {
                wxCommandEvent cmd;

                OnEditFootprintLibraryTable( cmd );
            }
        }

        msg = wxT( "Some or all of the assigned footprints contain legacy entries.  Would you "
                   "like CvPcb to attempt to convert them to the new footprint library table "
                   "format?" );

        if( IsOK( this, msg ) )
        {
            msg.Clear();
            WX_STRING_REPORTER reporter( &msg );

            if( !m_footprintLibTable->ConvertFromLegacy( m_netlist, m_ModuleLibNames, &reporter ) )
            {
                HTML_MESSAGE_BOX dlg( this, wxEmptyString );

                dlg.MessageSet( wxT( "The following errors occurred attempt to convert the "
                                     "footprint assignments:\n\n" ) );
                dlg.ListSet( msg );
                dlg.MessageSet( wxT( "\nYou will need to reassign them manually if you want them "
                                     "to be updated correctly the next time you import the "
                                     "netlist in Pcbnew." ) );
                dlg.ShowModal();
            }

            m_modified = true;
        }
        else
        {
            // Clear the legacy footprint assignments.
            for( unsigned i = 0;  i < m_netlist.GetCount();  i++ )
            {
                FPID emptyFPID;
                component = m_netlist.GetComponent( i );
                component->SetFPID( emptyFPID );
                m_modified = true;
            }
        }
    }

219
    for( unsigned i = 0;  i < m_netlist.GetCount();  i++ )
220
    {
221 222
        component = m_netlist.GetComponent( i );

223
        msg.Printf( CMP_FORMAT, m_ListCmp->GetCount() + 1,
224 225
                    GetChars( component->GetReference() ),
                    GetChars( component->GetValue() ),
226
                    GetChars( FROM_UTF8( component->GetFPID().Format().c_str() ) ) );
227

228 229
        m_ListCmp->AppendLine( msg );

230
        if( component->GetFPID().empty() )
231
        {
232
            m_undefinedComponentCnt += 1;
233 234
            continue;
        }
235 236
    }

237
    if( !m_netlist.IsEmpty() )
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
        m_ListCmp->SetSelection( 0, true );

    DisplayStatus();

    UpdateTitle();

    UpdateFileHistory( m_NetlistFileName.GetFullPath() );

    return true;
}


int CVPCB_MAINFRAME::SaveCmpLinkFile( const wxString& aFullFileName )
{
    wxFileName fn;

    if( !aFullFileName.IsEmpty() )
    {
        fn = m_NetlistFileName;
        fn.SetExt( ComponentFileExtension );
    }
    else
    {
261 262
        wxFileDialog dlg( this, _( "Save Component Footprint Link File" ), wxEmptyString,
                          _( "Unnamed file" ), ComponentFileWildcard, wxFD_SAVE );
263 264 265 266 267 268 269 270

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

        fn = dlg.GetPath();

        if( !fn.HasExt() )
            fn.SetExt( ComponentFileExtension );
271 272 273 274 275 276 277 278 279

        // Save the project specific footprint library table.
        if( !m_footprintLibTable->IsEmpty( false ) )
        {
            wxFileName fpLibFileName = fn;
            fpLibFileName.ClearExt();
            fpLibFileName.SetName( FP_LIB_TABLE::GetFileName() );

            if( fpLibFileName.FileExists()
jean-pierre charras's avatar
jean-pierre charras committed
280
              && IsOK( this, _( "A footprint library table already exists in this path.\n\nDo "
281 282 283 284 285 286 287 288 289 290
                                "you want to overwrite it?" ) ) )
            {
                try
                {
                    m_footprintLibTable->Save( fpLibFileName );
                }
                catch( IO_ERROR& ioe )
                {
                    DisplayError( this,
                                  wxString::Format( _( "An error occurred attempting to save the "
jean-pierre charras's avatar
jean-pierre charras committed
291
                                                       "footprint library table <%s>\n\n%s" ),
292 293 294 295 296
                                                    GetChars( fpLibFileName.GetFullPath() ),
                                                    GetChars( ioe.errorText ) ) );
                }
            }
        }
297 298 299 300 301 302 303
    }

    if( !IsWritable( fn.GetFullPath() ) )
        return 0;

    if( WriteComponentLinkFile( fn.GetFullPath() ) == 0 )
    {
304
        DisplayError( this, _( "Unable to create component footprint link file (.cmp)" ) );
305 306 307 308
        return 0;
    }

    wxString msg;
309
    msg.Printf( _("File %s saved"), GetChars( fn.GetFullPath() ) );
310 311 312
    SetStatusText( msg );
    return 1;
}