class_DisplayFootprintsFrame.cpp 16.8 KB
Newer Older
1 2 3
/*
 * This program source code file is part of KiCad, a free EDA CAD application.
 *
4 5 6
 * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
 * Copyright (C) 2015 Wayne Stambaugh <stambaughw@verizon.net>
 * Copyright (C) 2007-2015 KiCad Developers, see AUTHORS.txt for contributors.
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
 *
 * 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
 */

/**
 * @file class_DisplayFootprintsFrame.cpp
 */
plyatov's avatar
plyatov committed
29

30
#include <fctsys.h>
31
#include <pgm_base.h>
32 33
#include <common.h>
#include <class_drawpanel.h>
34
#include <class_draw_panel_gal.h>
35 36 37
#include <confirm.h>
#include <macros.h>
#include <bitmaps.h>
38
#include <msgpanel.h>
39
#include <wildcards_and_files_ext.h>
40 41 42
#include <fpid.h>
#include <fp_lib_table.h>
#include <pcbcommon.h>
43

44 45
#include <io_mgr.h>
#include <class_module.h>
46
#include <class_board.h>
47

48 49 50
#include <cvpcb_mainframe.h>
#include <class_DisplayFootprintsFrame.h>
#include <cvpcb_id.h>
51
#include <cvstruct.h>
plyatov's avatar
plyatov committed
52

53
#include <3d_viewer.h>
54 55


56
BEGIN_EVENT_TABLE( DISPLAY_FOOTPRINTS_FRAME, PCB_BASE_FRAME )
charras's avatar
charras committed
57 58 59 60
    EVT_CLOSE( DISPLAY_FOOTPRINTS_FRAME::OnCloseWindow )
    EVT_SIZE( DISPLAY_FOOTPRINTS_FRAME::OnSize )
    EVT_TOOL( ID_OPTIONS_SETUP, DISPLAY_FOOTPRINTS_FRAME::InstallOptionsDisplay )
    EVT_TOOL( ID_CVPCB_SHOW3D_FRAME, DISPLAY_FOOTPRINTS_FRAME::Show3D_Frame )
61

62 63 64 65 66 67 68 69 70
    EVT_TOOL( ID_TB_OPTIONS_SHOW_MODULE_TEXT_SKETCH,
              DISPLAY_FOOTPRINTS_FRAME::OnSelectOptionToolbar)
    EVT_TOOL( ID_TB_OPTIONS_SHOW_MODULE_EDGE_SKETCH,
              DISPLAY_FOOTPRINTS_FRAME::OnSelectOptionToolbar)

    EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_MODULE_TEXT_SKETCH,
                   DISPLAY_FOOTPRINTS_FRAME::OnUpdateTextDrawMode )
    EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_MODULE_EDGE_SKETCH,
                   DISPLAY_FOOTPRINTS_FRAME::OnUpdateLineDrawMode )
71
END_EVENT_TABLE()
plyatov's avatar
plyatov committed
72 73


74
DISPLAY_FOOTPRINTS_FRAME::DISPLAY_FOOTPRINTS_FRAME( KIWAY* aKiway, CVPCB_MAINFRAME* aParent ) :
75
    PCB_BASE_FRAME( aKiway, aParent, FRAME_CVPCB_DISPLAY, _( "Footprint Viewer" ),
76
        wxDefaultPosition, wxDefaultSize,
77
        KICAD_DEFAULT_DRAWFRAME_STYLE, FOOTPRINTVIEWER_FRAME_NAME )
78
{
79
    m_showAxis = true;         // true to draw axis.
80 81

    // Give an icon
82
    wxIcon  icon;
83

84 85
    icon.CopyFromBitmap( KiBitmap( icon_cvpcb_xpm ) );
    SetIcon( icon );
plyatov's avatar
plyatov committed
86

Dick Hollenbeck's avatar
Dick Hollenbeck committed
87
    SetBoard( new BOARD() );
88
    SetScreen( new PCB_SCREEN( GetPageSizeIU() ) );
plyatov's avatar
plyatov committed
89

90
    LoadSettings( config() );
91

92
    // Initialize grid id to a default value if not found in config or bad:
charras's avatar
charras committed
93
    if( (m_LastGridSizeId <= 0) ||
94
        (m_LastGridSizeId > (ID_POPUP_GRID_USER - ID_POPUP_GRID_LEVEL_1000)) )
charras's avatar
charras committed
95
        m_LastGridSizeId = ID_POPUP_GRID_LEVEL_500 - ID_POPUP_GRID_LEVEL_1000;
96

97
    GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId );
98 99

    // Initialize some display options
100 101
    DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
    displ_opts->m_DisplayPadIsol = false;      // Pad clearance has no meaning here
102 103

    // Track and via clearance has no meaning here.
104
    displ_opts->m_ShowTrackClearanceMode = DO_NOT_SHOW_CLEARANCE;
105

106 107 108
    SetSize( m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y );
    ReCreateHToolbar();
    ReCreateVToolbar();
109
    ReCreateOptToolbar();
110 111 112

    m_auimgr.SetManagedWindow( this );

113 114 115 116 117 118 119 120 121
    EDA_PANEINFO horiz;
    horiz.HorizontalToolbarPane();

    EDA_PANEINFO vert;
    vert.VerticalToolbarPane();

    EDA_PANEINFO mesg;
    mesg.MessageToolbarPane();

122 123
    m_auimgr.AddPane( m_mainToolBar,
                      wxAuiPaneInfo( horiz ).Name( wxT( "m_mainToolBar" ) ).Top(). Row( 0 ) );
124

125 126 127
    if( m_drawToolBar )    // Currently, no vertical right toolbar.
        m_auimgr.AddPane( m_drawToolBar,
                          wxAuiPaneInfo( vert ).Name( wxT( "m_drawToolBar" ) ).Right() );
128

129
    m_auimgr.AddPane( m_canvas,
130
                      wxAuiPaneInfo().Name( wxT( "DisplayFrame" ) ).CentrePane() );
131

132
    m_auimgr.AddPane( m_messagePanel,
133
                      wxAuiPaneInfo( mesg ).Name( wxT( "MsgPanel" ) ).Bottom().Layer(10) );
134

135 136
    m_auimgr.AddPane( m_optionsToolBar,
                      wxAuiPaneInfo( vert ).Name( wxT( "m_optionsToolBar" ) ).Left() );
137

138
    m_auimgr.Update();
139

140
    Show( true );
plyatov's avatar
plyatov committed
141 142 143
}


charras's avatar
charras committed
144
DISPLAY_FOOTPRINTS_FRAME::~DISPLAY_FOOTPRINTS_FRAME()
plyatov's avatar
plyatov committed
145
{
146
    delete GetScreen();
147
    SetScreen( NULL );      // Be sure there is no double deletion
plyatov's avatar
plyatov committed
148 149
}

Dick Hollenbeck's avatar
Dick Hollenbeck committed
150

charras's avatar
charras committed
151
void DISPLAY_FOOTPRINTS_FRAME::OnCloseWindow( wxCloseEvent& event )
plyatov's avatar
plyatov committed
152
{
153
    if( m_Draw3DFrame )
154 155
        m_Draw3DFrame->Close( true );

156
    Destroy();
plyatov's avatar
plyatov committed
157 158 159
}


charras's avatar
charras committed
160
void DISPLAY_FOOTPRINTS_FRAME::ReCreateVToolbar()
plyatov's avatar
plyatov committed
161
{
162 163
    // Currently, no vertical right toolbar.
    // So do nothing
plyatov's avatar
plyatov committed
164 165 166
}


167 168
void DISPLAY_FOOTPRINTS_FRAME::ReCreateOptToolbar()
{
169
    if( m_optionsToolBar )
170 171 172
        return;

    // Create options tool bar.
173 174
    m_optionsToolBar = new wxAuiToolBar( this, ID_OPT_TOOLBAR, wxDefaultPosition, wxDefaultSize,
                                         wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_VERTICAL );
175

176
    m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_GRID, wxEmptyString, KiBitmap( grid_xpm ),
177 178
                               _( "Hide grid" ), wxITEM_CHECK );

179
    m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_POLAR_COORD, wxEmptyString,
180
                               KiBitmap( polar_coord_xpm ),
181
                               _( "Display polar coordinates" ), wxITEM_CHECK );
182

183
    m_optionsToolBar->AddTool( ID_TB_OPTIONS_SELECT_UNIT_INCH, wxEmptyString,
184
                               KiBitmap( unit_inch_xpm ),
185 186
                               _( "Units in inches" ), wxITEM_CHECK );

187
    m_optionsToolBar->AddTool( ID_TB_OPTIONS_SELECT_UNIT_MM, wxEmptyString,
188
                               KiBitmap( unit_mm_xpm ),
189 190
                               _( "Units in millimeters" ), wxITEM_CHECK );

191
    m_optionsToolBar->AddTool( ID_TB_OPTIONS_SELECT_CURSOR, wxEmptyString,
192
                               KiBitmap( cursor_shape_xpm ),
193
                               _( "Change cursor shape" ), wxITEM_CHECK  );
194

195 196
    m_optionsToolBar->AddSeparator();
    m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_PADS_SKETCH, wxEmptyString,
197
                               KiBitmap( pad_sketch_xpm ),
198
                               _( "Show pads in outline mode" ), wxITEM_CHECK  );
199

200
    m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_MODULE_TEXT_SKETCH, wxEmptyString,
201
                               KiBitmap( text_sketch_xpm ),
202
                               _( "Show texts in line mode" ), wxITEM_CHECK  );
203

204
    m_optionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_MODULE_EDGE_SKETCH, wxEmptyString,
205
                               KiBitmap( show_mod_edge_xpm ),
206
                               _( "Show outlines in line mode" ), wxITEM_CHECK  );
207

208
    m_optionsToolBar->Realize();
209 210 211
}


charras's avatar
charras committed
212
void DISPLAY_FOOTPRINTS_FRAME::ReCreateHToolbar()
plyatov's avatar
plyatov committed
213
{
214
    if( m_mainToolBar != NULL )
215 216
        return;

217 218
    m_mainToolBar = new wxAuiToolBar( this, ID_H_TOOLBAR, wxDefaultPosition, wxDefaultSize,
                                      wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_HORZ_LAYOUT );
plyatov's avatar
plyatov committed
219

220 221
    m_mainToolBar->AddTool( ID_OPTIONS_SETUP, wxEmptyString, KiBitmap( display_options_xpm ),
                            _( "Display options" ) );
plyatov's avatar
plyatov committed
222

223
    m_mainToolBar->AddSeparator();
plyatov's avatar
plyatov committed
224

225 226
    m_mainToolBar->AddTool( ID_ZOOM_IN, wxEmptyString, KiBitmap( zoom_in_xpm ),
                            _( "Zoom in (F1)" ) );
plyatov's avatar
plyatov committed
227

228 229
    m_mainToolBar->AddTool( ID_ZOOM_OUT, wxEmptyString, KiBitmap( zoom_out_xpm ),
                            _( "Zoom out (F2)" ) );
plyatov's avatar
plyatov committed
230

231 232
    m_mainToolBar->AddTool( ID_ZOOM_REDRAW, wxEmptyString, KiBitmap( zoom_redraw_xpm ),
                            _( "Redraw view (F3)" ) );
plyatov's avatar
plyatov committed
233

234 235
    m_mainToolBar->AddTool( ID_ZOOM_PAGE, wxEmptyString, KiBitmap( zoom_fit_in_page_xpm ),
                            _( "Zoom auto (Home)" ) );
plyatov's avatar
plyatov committed
236

237 238
    m_mainToolBar->AddSeparator();
    m_mainToolBar->AddTool( ID_CVPCB_SHOW3D_FRAME, wxEmptyString, KiBitmap( three_d_xpm ),
239
                            _( "3D Display (Alt+3)" ) );
plyatov's avatar
plyatov committed
240

241 242
    // after adding the buttons to the toolbar, must call Realize() to reflect
    // the changes
243
    m_mainToolBar->Realize();
plyatov's avatar
plyatov committed
244 245 246
}


247
void DISPLAY_FOOTPRINTS_FRAME::OnUpdateTextDrawMode( wxUpdateUIEvent& aEvent )
plyatov's avatar
plyatov committed
248
{
249 250 251
    DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();

    wxString msgTextsFill[2] = { _( "Show texts in filled mode" ),
252 253
                                 _( "Show texts in sketch mode" ) };

254
    unsigned i = displ_opts->m_DisplayModTextFill == SKETCH ? 0 : 1;
255

256
    aEvent.Check( displ_opts->m_DisplayModTextFill == SKETCH );
257
    m_optionsToolBar->SetToolShortHelp( ID_TB_OPTIONS_SHOW_MODULE_TEXT_SKETCH, msgTextsFill[i] );
258 259 260 261 262 263

}


void DISPLAY_FOOTPRINTS_FRAME::OnUpdateLineDrawMode( wxUpdateUIEvent& aEvent )
{
264 265
    DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();

266
    wxString msgEdgesFill[2] = { _( "Show outlines in filled mode" ),
267 268
                                 _( "Show outlines in sketch mode" ) };

269
    int i = displ_opts->m_DisplayModEdgeFill == SKETCH ? 0 : 1;
270

271
    aEvent.Check( displ_opts->m_DisplayModEdgeFill == SKETCH );
272
    m_optionsToolBar->SetToolShortHelp( ID_TB_OPTIONS_SHOW_MODULE_EDGE_SKETCH, msgEdgesFill[i] );
plyatov's avatar
plyatov committed
273 274 275
}


charras's avatar
charras committed
276
void DISPLAY_FOOTPRINTS_FRAME::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
plyatov's avatar
plyatov committed
277 278 279
{
}

280

charras's avatar
charras committed
281
void DISPLAY_FOOTPRINTS_FRAME::OnLeftDClick( wxDC* DC, const wxPoint& MousePos )
plyatov's avatar
plyatov committed
282 283 284
{
}

285

286
bool DISPLAY_FOOTPRINTS_FRAME::OnRightClick( const wxPoint& MousePos, wxMenu* PopMenu )
plyatov's avatar
plyatov committed
287
{
288
    return true;
plyatov's avatar
plyatov committed
289 290
}

291

292 293 294
void DISPLAY_FOOTPRINTS_FRAME::OnSelectOptionToolbar( wxCommandEvent& event )
{
    int        id = event.GetId();
295
    DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)GetDisplayOptions();
296 297 298 299

    switch( id )
    {
    case ID_TB_OPTIONS_SHOW_MODULE_TEXT_SKETCH:
300
        displ_opts->m_DisplayModTextFill = displ_opts->m_DisplayModTextFill == FILLED ? SKETCH : FILLED;
301
        m_canvas->Refresh( );
302 303 304
        break;

    case ID_TB_OPTIONS_SHOW_MODULE_EDGE_SKETCH:
305
        displ_opts->m_DisplayModEdgeFill = displ_opts->m_DisplayModEdgeFill == FILLED ? SKETCH : FILLED;
306
        m_canvas->Refresh();
307 308 309 310 311 312 313 314
        break;

    default:
        DisplayError( this,
                      wxT( "DISPLAY_FOOTPRINTS_FRAME::OnSelectOptionToolbar error" ) );
        break;
    }
}
plyatov's avatar
plyatov committed
315

316

317
bool DISPLAY_FOOTPRINTS_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, int aHotKey )
plyatov's avatar
plyatov committed
318
{
319 320
    bool eventHandled = true;

Lorenzo Marcantonio's avatar
Lorenzo Marcantonio committed
321 322 323 324
    // Filter out the 'fake' mouse motion after a keyboard movement
    if( !aHotKey && m_movingCursorWithKeyboard )
    {
        m_movingCursorWithKeyboard = false;
325
        return false;
Lorenzo Marcantonio's avatar
Lorenzo Marcantonio committed
326
    }
327

328 329
    wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED );
    cmd.SetEventObject( this );
330

Lorenzo Marcantonio's avatar
Lorenzo Marcantonio committed
331 332 333
    wxPoint pos = aPosition;
    wxPoint oldpos = GetCrossHairPosition();
    GeneralControlKeyMovement( aHotKey, &pos, true );
334

335
    switch( aHotKey )
336
    {
337 338 339 340
    case WXK_F1:
        cmd.SetId( ID_POPUP_ZOOM_IN );
        GetEventHandler()->ProcessEvent( cmd );
        break;
341

342 343 344 345 346 347 348 349 350 351 352 353 354 355 356
    case WXK_F2:
        cmd.SetId( ID_POPUP_ZOOM_OUT );
        GetEventHandler()->ProcessEvent( cmd );
        break;

    case WXK_F3:
        cmd.SetId( ID_ZOOM_REDRAW );
        GetEventHandler()->ProcessEvent( cmd );
        break;

    case WXK_F4:
        cmd.SetId( ID_POPUP_ZOOM_CENTER );
        GetEventHandler()->ProcessEvent( cmd );
        break;

dickelbeck's avatar
dickelbeck committed
357 358 359 360 361
    case WXK_HOME:
        cmd.SetId( ID_ZOOM_PAGE );
        GetEventHandler()->ProcessEvent( cmd );
        break;

362
    case ' ':
Lorenzo Marcantonio's avatar
Lorenzo Marcantonio committed
363
        GetScreen()->m_O_Curseur = GetCrossHairPosition();
364
        break;
365

366 367 368 369 370
    case GR_KB_ALT + '3':
        cmd.SetId( ID_CVPCB_SHOW3D_FRAME );
        GetEventHandler()->ProcessEvent( cmd );
        break;

371 372
    default:
        eventHandled = false;
373 374
    }

375
    SetCrossHairPosition( pos );
Lorenzo Marcantonio's avatar
Lorenzo Marcantonio committed
376
    RefreshCrossHair( oldpos, aPosition, aDC );
377

378
    UpdateStatusBar();    /* Display new cursor coordinates */
379 380

    return eventHandled;
plyatov's avatar
plyatov committed
381 382
}

383

charras's avatar
charras committed
384
void DISPLAY_FOOTPRINTS_FRAME::Show3D_Frame( wxCommandEvent& event )
385 386 387
{
    if( m_Draw3DFrame )
    {
388 389 390 391
        // Raising the window does not show the window on Windows if iconized.
        // This should work on any platform.
        if( m_Draw3DFrame->IsIconized() )
             m_Draw3DFrame->Iconize( false );
392

393 394 395 396 397 398
        m_Draw3DFrame->Raise();

        // Raising the window does not set the focus on Linux.  This should work on any platform.
        if( wxWindow::FindFocus() != m_Draw3DFrame )
            m_Draw3DFrame->SetFocus();

399 400 401
        return;
    }

402
    m_Draw3DFrame = new EDA_3D_FRAME( &Kiway(), this, _( "3D Viewer" ), KICAD_DEFAULT_3D_DRAWFRAME_STYLE );
403
    m_Draw3DFrame->Show( true );
404
}
405

406

407 408 409 410 411 412
/**
 * Virtual function needed by the PCB_SCREEN class derived from BASE_SCREEN
 * this is a virtual pure function in BASE_SCREEN
 * do nothing in Cvpcb
 * could be removed later
 */
413
void PCB_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER&, int )
414 415
{
}
charras's avatar
charras committed
416

417

418
bool DISPLAY_FOOTPRINTS_FRAME::IsGridVisible() const
charras's avatar
charras committed
419
{
420
    return m_drawGrid;
charras's avatar
charras committed
421 422
}

423

charras's avatar
charras committed
424 425
void DISPLAY_FOOTPRINTS_FRAME::SetGridVisibility(bool aVisible)
{
426
    m_drawGrid = aVisible;
charras's avatar
charras committed
427 428
}

429

430
EDA_COLOR_T DISPLAY_FOOTPRINTS_FRAME::GetGridColor() const
charras's avatar
charras committed
431 432 433
{
    return DARKGRAY;
}
434 435 436 437


MODULE* DISPLAY_FOOTPRINTS_FRAME::Get_Module( const wxString& aFootprintName )
{
438
    MODULE* footprint = NULL;
439 440 441

    try
    {
442 443
        FPID fpid;

444
        if( fpid.Parse( aFootprintName ) >= 0 )
445 446 447 448 449 450
        {
            DisplayInfoMessage( this, wxString::Format( wxT( "Footprint ID <%s> is not valid." ),
                                                        GetChars( aFootprintName ) ) );
            return NULL;
        }

451 452
        std::string nickname = fpid.GetLibNickname();
        std::string fpname   = fpid.GetFootprintName();
453 454

        wxLogDebug( wxT( "Load footprint <%s> from library <%s>." ),
455
                    fpname.c_str(), nickname.c_str()  );
456

457 458
        footprint = Prj().PcbFootprintLibs()->FootprintLoad(
                FROM_UTF8( nickname.c_str() ), FROM_UTF8( fpname.c_str() ) );
459
    }
460
    catch( const IO_ERROR& ioe )
461 462 463 464 465
    {
        DisplayError( this, ioe.errorText );
        return NULL;
    }

466 467 468 469 470 471 472
    if( footprint )
    {
        footprint->SetParent( (EDA_ITEM*) GetBoard() );
        footprint->SetPosition( wxPoint( 0, 0 ) );
        return footprint;
    }

473 474 475 476 477 478 479 480 481
    wxString msg = wxString::Format( _( "Footprint '%s' not found" ), aFootprintName.GetData() );
    DisplayError( this, msg );
    return NULL;
}


void DISPLAY_FOOTPRINTS_FRAME::InitDisplay()
{
    wxString msg;
482 483 484

    CVPCB_MAINFRAME* parentframe = (CVPCB_MAINFRAME *) GetParent();

485
    wxString footprintName = parentframe->m_footprintListBox->GetSelectedFootprint();
486 487 488 489

    if( !footprintName.IsEmpty() )
    {
        msg.Printf( _( "Footprint: %s" ), GetChars( footprintName ) );
490

491
        SetTitle( msg );
492
        const FOOTPRINT_INFO* module_info = parentframe->m_footprints.GetModuleInfo( footprintName );
493

494
        const wxChar* libname;
495

496
        if( module_info )
497
            libname = GetChars( module_info->GetNickname() );
498 499
        else
            libname = GetChars( wxT( "???" ) );
500

501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569
        msg.Printf( _( "Lib: %s" ), libname );

        SetStatusText( msg, 0 );

        if( GetBoard()->m_Modules.GetCount() )
        {
            // there is only one module in the list
            GetBoard()->m_Modules.DeleteAll();
        }

        MODULE* module = Get_Module( footprintName );

        if( module )
            GetBoard()->m_Modules.PushBack( module );

        Zoom_Automatique( false );
    }
    else   // No footprint to display. Erase old footprint, if any
    {
        if( GetBoard()->m_Modules.GetCount() )
        {
            GetBoard()->m_Modules.DeleteAll();
            Zoom_Automatique( false );
            SetStatusText( wxEmptyString, 0 );
        }
    }

    // Display new cursor coordinates and zoom value:
    UpdateStatusBar();

    GetCanvas()->Refresh();

    if( m_Draw3DFrame )
        m_Draw3DFrame->NewDisplay();
}


void DISPLAY_FOOTPRINTS_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg )
{
    if( !GetBoard() )
        return;

    m_canvas->DrawBackGround( DC );
    GetBoard()->Draw( m_canvas, DC, GR_COPY );

    MODULE* Module = GetBoard()->m_Modules;

    if ( Module )
    {
        MSG_PANEL_ITEMS items;
        Module->GetMsgPanelInfo( items );
        SetMsgPanel( items );
    }

    m_canvas->DrawCrossHair( DC );
}


/*
 * Redraw the BOARD items but not cursors, axis or grid.
 */
void BOARD::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
                  GR_DRAWMODE aDrawMode, const wxPoint& aOffset )
{
    if( m_Modules )
    {
        m_Modules->Draw( aPanel, aDC, GR_COPY );
    }
}