moduleframe.cpp 20.2 KB
Newer Older
1 2 3
/*
 * This program source code file is part of KiCad, a free EDA CAD application.
 *
4 5 6 7
 * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
 * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
 * Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
 * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
 *
 * 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
 */

27 28 29 30
/**
 * @file moduleframe.cpp
 * @brief Footprint (module) editor main window.
 */
plyatov's avatar
plyatov committed
31

32 33 34 35 36 37 38 39
#include <fctsys.h>
#include <appl_wxstruct.h>
#include <class_drawpanel.h>
#include <confirm.h>
#include <wxPcbStruct.h>
#include <dialog_helpers.h>
#include <3d_viewer.h>
#include <pcbcommon.h>
40
#include <msgpanel.h>
41 42 43 44 45 46 47 48 49

#include <class_board.h>
#include <class_module.h>

#include <pcbnew.h>
#include <protos.h>
#include <pcbnew_id.h>
#include <hotkeys.h>
#include <module_editor_frame.h>
50
#include <wildcards_and_files_ext.h>
51 52


Dick Hollenbeck's avatar
Dick Hollenbeck committed
53
static PCB_SCREEN* s_screenModule;      // the PCB_SCREEN used by the footprint editor
54

55 56
wxString FOOTPRINT_EDIT_FRAME::m_lib_nick_name;
wxString FOOTPRINT_EDIT_FRAME::m_lib_path;
57

58
BOARD* FOOTPRINT_EDIT_FRAME::s_Pcb;
59

60
BEGIN_EVENT_TABLE( FOOTPRINT_EDIT_FRAME, PCB_BASE_FRAME )
61
    EVT_MENU_RANGE( ID_POPUP_PCB_ITEM_SELECTION_START, ID_POPUP_PCB_ITEM_SELECTION_END,
62
                    PCB_BASE_FRAME::ProcessItemSelection )
63 64
    EVT_CLOSE( FOOTPRINT_EDIT_FRAME::OnCloseWindow )
    EVT_MENU( wxID_EXIT, FOOTPRINT_EDIT_FRAME::CloseModuleEditor )
65

66
    EVT_SIZE( FOOTPRINT_EDIT_FRAME::OnSize )
67

68 69
    EVT_COMBOBOX( ID_ON_ZOOM_SELECT, FOOTPRINT_EDIT_FRAME::OnSelectZoom )
    EVT_COMBOBOX( ID_ON_GRID_SELECT, FOOTPRINT_EDIT_FRAME::OnSelectGrid )
70

71
    EVT_TOOL( ID_MODEDIT_SELECT_CURRENT_LIB, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
72 73 74

    EVT_TOOL( ID_MODEDIT_SAVE_LIBRARY_AS, FOOTPRINT_EDIT_FRAME::OnSaveLibraryAs )

75
    EVT_TOOL( ID_MODEDIT_SAVE_LIBMODULE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
76 77
    EVT_TOOL( ID_OPEN_MODULE_VIEWER, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )

78 79
    EVT_TOOL( ID_MODEDIT_DELETE_PART, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
    EVT_TOOL( ID_MODEDIT_NEW_MODULE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
80
    EVT_TOOL( ID_MODEDIT_NEW_MODULE_FROM_WIZARD, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
81 82 83
    EVT_TOOL( ID_MODEDIT_LOAD_MODULE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
    EVT_TOOL( ID_MODEDIT_IMPORT_PART, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
    EVT_TOOL( ID_MODEDIT_EXPORT_PART, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
84
    EVT_TOOL( ID_MODEDIT_CREATE_NEW_LIB_AND_SAVE_CURRENT_PART,
85 86 87 88 89 90 91 92 93 94 95 96
              FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
    EVT_TOOL( ID_MODEDIT_SHEET_SET, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
    EVT_TOOL( wxID_PRINT, FOOTPRINT_EDIT_FRAME::ToPrinter )
    EVT_TOOL( ID_MODEDIT_LOAD_MODULE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
    EVT_TOOL( ID_MODEDIT_CHECK, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
    EVT_TOOL( ID_MODEDIT_PAD_SETTINGS, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
    EVT_TOOL( ID_MODEDIT_LOAD_MODULE_FROM_BOARD, FOOTPRINT_EDIT_FRAME::LoadModuleFromBoard )
    EVT_TOOL( ID_MODEDIT_INSERT_MODULE_IN_BOARD, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
    EVT_TOOL( ID_MODEDIT_UPDATE_MODULE_IN_BOARD, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
    EVT_TOOL( ID_MODEDIT_EDIT_MODULE_PROPERTIES, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
    EVT_TOOL( wxID_UNDO, FOOTPRINT_EDIT_FRAME::GetComponentFromUndoList )
    EVT_TOOL( wxID_REDO, FOOTPRINT_EDIT_FRAME::GetComponentFromRedoList )
97 98

    // Vertical tool bar button click event handler.
99
    EVT_TOOL( ID_NO_TOOL_SELECTED, FOOTPRINT_EDIT_FRAME::OnVerticalToolbar )
100
    EVT_TOOL_RANGE( ID_MODEDIT_PAD_TOOL, ID_MODEDIT_PLACE_GRID_COORD,
101
                    FOOTPRINT_EDIT_FRAME::OnVerticalToolbar )
102 103

    // Options Toolbar
104 105 106 107
    EVT_TOOL( ID_TB_OPTIONS_SHOW_PADS_SKETCH, FOOTPRINT_EDIT_FRAME::OnSelectOptionToolbar )
    EVT_TOOL( ID_TB_OPTIONS_SHOW_VIAS_SKETCH, FOOTPRINT_EDIT_FRAME::OnSelectOptionToolbar )
    EVT_TOOL( ID_TB_OPTIONS_SHOW_MODULE_TEXT_SKETCH, FOOTPRINT_EDIT_FRAME::OnSelectOptionToolbar )
    EVT_TOOL( ID_TB_OPTIONS_SHOW_MODULE_EDGE_SKETCH, FOOTPRINT_EDIT_FRAME::OnSelectOptionToolbar )
108 109 110

    // popup commands
    EVT_MENU_RANGE( ID_POPUP_PCB_START_RANGE, ID_POPUP_PCB_END_RANGE,
111
                    FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
112 113

    EVT_MENU_RANGE( ID_POPUP_GENERAL_START_RANGE, ID_POPUP_GENERAL_END_RANGE,
114
                    FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
115

116 117 118 119
    EVT_MENU( ID_POPUP_MODEDIT_EDIT_BODY_ITEM,
              FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
    EVT_MENU( ID_POPUP_MODEDIT_EDIT_WIDTH_CURRENT_EDGE,
              FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
120 121 122 123 124 125
    EVT_MENU( ID_POPUP_MODEDIT_EDIT_WIDTH_ALL_EDGE,
              FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
    EVT_MENU( ID_POPUP_MODEDIT_EDIT_LAYER_CURRENT_EDGE,
              FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
    EVT_MENU( ID_POPUP_MODEDIT_EDIT_LAYER_ALL_EDGE,
              FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
126 127
    EVT_MENU( ID_POPUP_MODEDIT_ENTER_EDGE_WIDTH, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )

128
    // Module transformations
129 130
    EVT_MENU( ID_MODEDIT_MODULE_ROTATE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
    EVT_MENU( ID_MODEDIT_MODULE_MIRROR, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
131

132 133
    EVT_MENU( ID_PCB_DRAWINGS_WIDTHS_SETUP, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
    EVT_MENU( ID_PCB_PAD_SETUP, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
134
    EVT_MENU( ID_PCB_USER_GRID_SETUP, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
135 136

    // Menu 3D Frame
137
    EVT_MENU( ID_MENU_PCB_SHOW_3D_FRAME, FOOTPRINT_EDIT_FRAME::Show3D_Frame )
138

139
    EVT_UPDATE_UI( ID_MODEDIT_DELETE_PART, FOOTPRINT_EDIT_FRAME::OnUpdateLibSelected )
140

141
    EVT_UPDATE_UI( ID_MODEDIT_EXPORT_PART, FOOTPRINT_EDIT_FRAME::OnUpdateModuleSelected )
142
    EVT_UPDATE_UI( ID_MODEDIT_CREATE_NEW_LIB_AND_SAVE_CURRENT_PART,
143 144
                   FOOTPRINT_EDIT_FRAME::OnUpdateModuleSelected )
    EVT_UPDATE_UI( ID_MODEDIT_SAVE_LIBMODULE, FOOTPRINT_EDIT_FRAME::OnUpdateLibAndModuleSelected )
145
    EVT_UPDATE_UI( ID_MODEDIT_LOAD_MODULE_FROM_BOARD,
146
                   FOOTPRINT_EDIT_FRAME::OnUpdateLoadModuleFromBoard )
147
    EVT_UPDATE_UI( ID_MODEDIT_INSERT_MODULE_IN_BOARD,
148
                   FOOTPRINT_EDIT_FRAME::OnUpdateInsertModuleInBoard )
149
    EVT_UPDATE_UI( ID_MODEDIT_UPDATE_MODULE_IN_BOARD,
150 151
                   FOOTPRINT_EDIT_FRAME::OnUpdateReplaceModuleInBoard )
    EVT_UPDATE_UI( ID_NO_TOOL_SELECTED, FOOTPRINT_EDIT_FRAME::OnUpdateVerticalToolbar )
152
    EVT_UPDATE_UI_RANGE( ID_MODEDIT_PAD_TOOL, ID_MODEDIT_PLACE_GRID_COORD,
153
                         FOOTPRINT_EDIT_FRAME::OnUpdateVerticalToolbar )
plyatov's avatar
plyatov committed
154

155
END_EVENT_TABLE()
plyatov's avatar
plyatov committed
156

157
#define FOOTPRINT_EDIT_FRAME_NAME wxT( "ModEditFrame" )
plyatov's avatar
plyatov committed
158

159
FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( PCB_EDIT_FRAME* aParent, FP_LIB_TABLE* aTable ) :
160 161 162
    PCB_BASE_FRAME( aParent, MODULE_EDITOR_FRAME_TYPE, wxEmptyString,
                    wxDefaultPosition, wxDefaultSize,
                    KICAD_DEFAULT_DRAWFRAME_STYLE, GetFootprintEditorFrameName() )
plyatov's avatar
plyatov committed
163
{
164
    m_FrameName = GetFootprintEditorFrameName();
165 166 167
    m_showBorderAndTitleBlock = false;   // true to show the frame references
    m_showAxis = true;                   // true to show X and Y axis on screen
    m_showGridAxis = true;               // show the grid origin axis
168
    m_HotkeysZoomAndGridList = g_Module_Editor_Hokeys_Descr;
169
    m_footprintLibTable = aTable;
170 171

    // Give an icon
172 173 174
    wxIcon icon;
    icon.CopyFromBitmap( KiBitmap( icon_modedit_xpm ) );
    SetIcon( icon );
175

176
    // Show a title (frame title + footprint name):
177
    updateTitle();
178

179
    if( !s_Pcb )
180
    {
181
        s_Pcb = new BOARD();
182

183 184 185
        // Ensure all layers and items are visible:
        s_Pcb->SetVisibleAlls();
    }
186

187
    SetBoard( s_Pcb );
188

Dick Hollenbeck's avatar
Dick Hollenbeck committed
189
    if( !s_screenModule )
190
        s_screenModule = new PCB_SCREEN( GetPageSettings().GetSizeIU() );
191

192
    SetScreen( s_screenModule );
193

194
    GetScreen()->SetCurItem( NULL );
195
    LoadSettings();
196

197 198
    GetBoard()->SetVisibleAlls();

199
    GetScreen()->AddGrid( m_UserGridSize, m_UserGridUnit, ID_POPUP_GRID_USER );
200
    GetScreen()->SetGrid( ID_POPUP_GRID_LEVEL_1000 + m_LastGridSizeId  );
charras's avatar
charras committed
201

202 203 204 205
    // In modedit, set the default paper size to A4:
    // this should be OK for all footprint to plot/print
    SetPageSettings( PAGE_INFO::A4 );

206 207 208 209 210 211 212
    SetSize( m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y );
    ReCreateMenuBar();
    ReCreateHToolbar();
    ReCreateAuxiliaryToolbar();
    ReCreateVToolbar();
    ReCreateOptToolbar();

213
    if( m_canvas )
214
        m_canvas->SetEnableBlockCommands( true );
215

216
    m_auimgr.SetManagedWindow( this );
217

218 219
    EDA_PANEINFO horiz;
    horiz.HorizontalToolbarPane();
220

221 222
    EDA_PANEINFO vert;
    vert.VerticalToolbarPane();
223

224 225
    EDA_PANEINFO mesg_pane;
    mesg_pane.MessageToolbarPane();
226

227 228
    m_auimgr.AddPane( m_mainToolBar,
                      wxAuiPaneInfo( horiz ).Name( wxT( "m_mainToolBar" ) ).Top(). Row( 0 ) );
229

230 231
    m_auimgr.AddPane( m_auxiliaryToolBar,
                      wxAuiPaneInfo( horiz ).Name( wxT( "m_auxiliaryToolBar" ) ).Top().Row( 1 ) );
232

233
    m_auimgr.AddPane( m_drawToolBar,
234
                      wxAuiPaneInfo( vert ).Name( wxT( "m_VToolBar" ) ).Right() );
235

236 237
    m_auimgr.AddPane( m_optionsToolBar,
                      wxAuiPaneInfo( vert ).Name( wxT( "m_optionsToolBar" ) ). Left() );
238

239
    m_auimgr.AddPane( m_canvas,
240
                      wxAuiPaneInfo().Name( wxT( "DrawFrame" ) ).CentrePane() );
241

242
    m_auimgr.AddPane( m_messagePanel,
243
                      wxAuiPaneInfo( mesg_pane ).Name( wxT( "MsgPanel" ) ).Bottom().Layer(10) );
244 245

    m_auimgr.Update();
plyatov's avatar
plyatov committed
246 247 248
}


249
FOOTPRINT_EDIT_FRAME::~FOOTPRINT_EDIT_FRAME()
plyatov's avatar
plyatov committed
250
{
251 252 253
    // When user reopens the Footprint editor, user would like to find the last edited item.
    // Do not delete PCB_SCREEN (by the destructor of EDA_DRAW_FRAME)
    SetScreen( NULL );
254

255 256 257 258 259 260 261
    // Do not allow PCB_BASE_FRAME::~PCB_BASE_FRAME()
    // to delete our precious BOARD, which is also in static FOOTPRINT_EDIT_FRAME::s_Pcb.
    // That function, PCB_BASE_FRAME::~PCB_BASE_FRAME(), runs immediately next
    // as we return from here.
    m_Pcb = 0;
}

262

263 264 265 266 267
const wxChar* FOOTPRINT_EDIT_FRAME::GetFootprintEditorFrameName()
{
    return FOOTPRINT_EDIT_FRAME_NAME;
}

268

269 270 271 272 273
/* return a reference to the current opened Footprint editor
 * or NULL if no Footprint editor currently opened
 */
FOOTPRINT_EDIT_FRAME* FOOTPRINT_EDIT_FRAME::GetActiveFootprintEditor()
{
274
    return (FOOTPRINT_EDIT_FRAME*) wxWindow::FindWindowByName( GetFootprintEditorFrameName() );
275
}
276

277

278 279 280 281 282 283 284 285 286 287 288 289 290 291
BOARD_DESIGN_SETTINGS& FOOTPRINT_EDIT_FRAME::GetDesignSettings() const
{
    // get the BOARD_DESIGN_SETTINGS from the parent editor, not our BOARD.

    PCB_BASE_FRAME* parentFrame = (PCB_BASE_FRAME*) GetParent();

    wxASSERT( parentFrame );

    return parentFrame->GetDesignSettings();
}


void FOOTPRINT_EDIT_FRAME::SetDesignSettings( const BOARD_DESIGN_SETTINGS& aSettings )
{
292
    // set the BOARD_DESIGN_SETTINGS into parent editor, not our BOARD.
293 294 295 296 297 298

    PCB_BASE_FRAME* parentFrame = (PCB_BASE_FRAME*) GetParent();

    wxASSERT( parentFrame );

    parentFrame->SetDesignSettings( aSettings );
plyatov's avatar
plyatov committed
299 300
}

301

302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
const PCB_PLOT_PARAMS& FOOTPRINT_EDIT_FRAME::GetPlotSettings() const
{
    // get the settings from the parent editor, not our BOARD.

    PCB_BASE_FRAME* parentFrame = (PCB_BASE_FRAME*) GetParent();

    wxASSERT( parentFrame );

    return parentFrame->GetPlotSettings();
}


void FOOTPRINT_EDIT_FRAME::SetPlotSettings( const PCB_PLOT_PARAMS& aSettings )
{
    // set the settings into parent editor, not our BOARD.

    PCB_BASE_FRAME* parentFrame = (PCB_BASE_FRAME*) GetParent();

    wxASSERT( parentFrame );

    parentFrame->SetPlotSettings( aSettings );
}


326
void FOOTPRINT_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
plyatov's avatar
plyatov committed
327
{
328 329
    if( GetScreen()->IsModify() )
    {
330 331 332
        int ii = DisplayExitDialog( this, _( "Save the changes in the module before closing?" ) );

        switch( ii )
333
        {
334 335 336 337 338 339 340 341 342
        case wxID_NO:
            break;

        case wxID_OK:
        case wxID_YES:
            // code from FOOTPRINT_EDIT_FRAME::Process_Special_Functions,
            // at case ID_MODEDIT_SAVE_LIBMODULE
            if( GetBoard()->m_Modules && getLibPath() != wxEmptyString )
            {
343
                if( Save_Module_In_Library( getLibPath(), GetBoard()->m_Modules, true, true ) )
344 345 346 347 348 349 350 351 352 353 354 355 356 357 358
                {
                    // save was correct
                    GetScreen()->ClrModify();
                    break;
                }
            }
            else
            {
                DisplayError( this, _( "Library is not set, the module could not be saved." ) );
            }
            // fall through: cancel the close because of an error

        case wxID_CANCEL:
            Event.Veto();
            return;
359 360 361
        }
    }

362
    //close the editor
363 364
    SaveSettings();
    Destroy();
plyatov's avatar
plyatov committed
365 366 367
}


368
void FOOTPRINT_EDIT_FRAME::CloseModuleEditor( wxCommandEvent& Event )
369 370 371 372
{
    Close();
}

373

374
void FOOTPRINT_EDIT_FRAME::OnUpdateVerticalToolbar( wxUpdateUIEvent& aEvent )
plyatov's avatar
plyatov committed
375
{
376
    aEvent.Enable( GetBoard()->m_Modules != NULL );
377

378
    if( aEvent.GetEventObject() == m_drawToolBar )
379
        aEvent.Check( GetToolId() == aEvent.GetId() );
380
}
381 382


383
void FOOTPRINT_EDIT_FRAME::OnUpdateLibSelected( wxUpdateUIEvent& aEvent )
384
{
385
    aEvent.Enable( getLibPath() != wxEmptyString );
386
}
387

388

389
void FOOTPRINT_EDIT_FRAME::OnUpdateModuleSelected( wxUpdateUIEvent& aEvent )
390 391 392
{
    aEvent.Enable( GetBoard()->m_Modules != NULL );
}
393

394

395
void FOOTPRINT_EDIT_FRAME::OnUpdateLibAndModuleSelected( wxUpdateUIEvent& aEvent )
396
{
397
    aEvent.Enable( getLibPath() != wxEmptyString  &&  GetBoard()->m_Modules != NULL );
398 399 400
}


401
void FOOTPRINT_EDIT_FRAME::OnUpdateLoadModuleFromBoard( wxUpdateUIEvent& aEvent )
402
{
403
    PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) GetParent();
404 405 406 407 408

    aEvent.Enable( frame->GetBoard()->m_Modules != NULL );
}


409
void FOOTPRINT_EDIT_FRAME::OnUpdateInsertModuleInBoard( wxUpdateUIEvent& aEvent )
410
{
411
    PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) GetParent();
412

413
    MODULE* module_in_edit = GetBoard()->m_Modules;
414
    bool canInsert = ( module_in_edit && !module_in_edit->GetLink() );
415 416

    // If the source was deleted, the module can inserted but not updated in the board.
417
    if( module_in_edit && module_in_edit->GetLink() ) // this is not a new module
418
    {
419 420
        BOARD*  mainpcb = frame->GetBoard();
        MODULE* source_module = mainpcb->m_Modules;
421 422

        // search if the source module was not deleted:
423
        for( ; source_module != NULL; source_module = source_module->Next() )
424
        {
425
            if( module_in_edit->GetLink() == source_module->GetTimeStamp() )
426 427 428
                break;
        }

429
        canInsert = ( source_module == NULL );
430 431
    }

432 433
    aEvent.Enable( canInsert );
}
434 435


436
void FOOTPRINT_EDIT_FRAME::OnUpdateReplaceModuleInBoard( wxUpdateUIEvent& aEvent )
437
{
438
    PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) GetParent();
439

440
    MODULE* module_in_edit = GetBoard()->m_Modules;
441
    bool canReplace = ( module_in_edit && module_in_edit->GetLink() );
442

443
    if( module_in_edit && module_in_edit->GetLink() ) // this is not a new module
444
    {
445 446 447 448 449
        BOARD*  mainpcb = frame->GetBoard();
        MODULE* source_module = mainpcb->m_Modules;

        // search if the source module was not deleted:
        for( ; source_module != NULL; source_module = source_module->Next() )
450
        {
451
            if( module_in_edit->GetLink() == source_module->GetTimeStamp() )
452
                break;
453 454
        }

455
        canReplace = ( source_module != NULL );
456 457
    }

458
    aEvent.Enable( canReplace );
plyatov's avatar
plyatov committed
459
}
460

461

462
void FOOTPRINT_EDIT_FRAME::Show3D_Frame( wxCommandEvent& event )
463 464 465
{
    if( m_Draw3DFrame )
    {
466 467 468 469
        // 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 );
470

471 472 473 474 475 476
        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();

477 478 479
        return;
    }

480
    m_Draw3DFrame = new EDA_3D_FRAME( this, _( "3D Viewer" ) );
481
    m_Draw3DFrame->Show( true );
482 483
}

484

485
void FOOTPRINT_EDIT_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, int aHotKey )
486
{
487 488 489
    wxRealPoint gridSize;
    wxPoint     oldpos;
    wxPoint     pos = aPosition;
490

491 492 493 494
    // when moving mouse, use the "magnetic" grid, unless the shift+ctrl keys is pressed
    // for next cursor position
    // ( shift or ctrl key down are PAN command with mouse wheel)
    bool snapToGrid = true;
495

496 497 498 499 500 501
    if( !aHotKey && wxGetKeyState( WXK_SHIFT ) && wxGetKeyState( WXK_CONTROL ) )
        snapToGrid = false;

    if( snapToGrid )
        pos = GetScreen()->GetNearestGridPosition( pos );

502
    oldpos = GetScreen()->GetCrossHairPosition();
503
    gridSize = GetScreen()->GetGridSize();
504

505
    switch( aHotKey )
506
    {
507
    case WXK_NUMPAD8:
508
    case WXK_UP:
509
        pos.y -= KiROUND( gridSize.y );
510
        m_canvas->MoveCursor( pos );
511 512
        break;

513
    case WXK_NUMPAD2:
514
    case WXK_DOWN:
515
        pos.y += KiROUND( gridSize.y );
516
        m_canvas->MoveCursor( pos );
517 518
        break;

519
    case WXK_NUMPAD4:
520
    case WXK_LEFT:
521
        pos.x -= KiROUND( gridSize.x );
522
        m_canvas->MoveCursor( pos );
523 524
        break;

525
    case WXK_NUMPAD6:
526
    case WXK_RIGHT:
527
        pos.x += KiROUND( gridSize.x );
528
        m_canvas->MoveCursor( pos );
529 530 531 532 533 534
        break;

    default:
        break;
    }

535
    GetScreen()->SetCrossHairPosition( pos, snapToGrid );
536

537
    if( oldpos != GetScreen()->GetCrossHairPosition() )
538
    {
539
        pos = GetScreen()->GetCrossHairPosition();
540
        GetScreen()->SetCrossHairPosition( oldpos, false );
541
        m_canvas->CrossHairOff( aDC );
542
        GetScreen()->SetCrossHairPosition( pos, snapToGrid );
543
        m_canvas->CrossHairOn( aDC );
544

545
        if( m_canvas->IsMouseCaptured() )
546
        {
547
#ifdef USE_WX_OVERLAY
548
            wxDCOverlay oDC( m_overlay, (wxWindowDC*)aDC );
549
            oDC.Clear();
550
            m_canvas->CallMouseCapture( aDC, aPosition, false );
551
#else
552
            m_canvas->CallMouseCapture( aDC, aPosition, true );
553
#endif
554
        }
555 556
#ifdef USE_WX_OVERLAY
        else
557
        {
558
            m_overlay.Reset();
559
        }
560
#endif
561 562
    }

563
    if( aHotKey )
564
    {
565
        OnHotKey( aDC, aHotKey, aPosition );
566 567
    }

568
    UpdateStatusBar();
569
}
570

571

572
void FOOTPRINT_EDIT_FRAME::OnModify()
573
{
574
    PCB_BASE_FRAME::OnModify();
575

576
    if( m_Draw3DFrame )
577
        m_Draw3DFrame->ReloadRequest();
578
}
579 580


581
void FOOTPRINT_EDIT_FRAME::updateTitle()
582
{
583 584
    wxString title   = _( "Module Editor " );
    wxString libPath = getLibPath();
585

586
    if( !libPath )
587
    {
588
    L_none:
589 590
        title += _( "(no active library)" );
    }
591
    else
592
    {
593 594
        // See if we can open and test write-ability of the library.
        IO_MGR::PCB_FILE_T  pluginType = IO_MGR::GuessPluginTypeFromLibPath( libPath );
595

596 597 598
        PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) );

        try
599
        {
600 601 602 603
            bool writable = pi->IsFootprintLibWritable( libPath );

            // no exception was thrown, this means libPath is valid, but it may be read only.
            title = _( "Module Editor (active library: " ) + getLibNickName() + wxT( ")" );
604

605
            if( !writable )
606 607
                title += _( " [Read Only]" );
        }
608 609 610 611 612 613 614
        catch( IO_ERROR ioe )
        {
            // user may be bewildered as to why after selecting a library it is not showing up
            // in the title, we could show an error message, but that should have been done at time
            // of libary selection UI.
            goto L_none;
        }
615 616 617
    }

    SetTitle( title );
618
}