summaryrefslogtreecommitdiff
path: root/pcbnew/modedit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'pcbnew/modedit.cpp')
-rw-r--r--pcbnew/modedit.cpp1005
1 files changed, 1005 insertions, 0 deletions
diff --git a/pcbnew/modedit.cpp b/pcbnew/modedit.cpp
new file mode 100644
index 0000000..8b06e6d
--- /dev/null
+++ b/pcbnew/modedit.cpp
@@ -0,0 +1,1005 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2012 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
+ */
+
+/**
+ * @file modedit.cpp
+ */
+
+#include <fctsys.h>
+#include <kiface_i.h>
+#include <kiway.h>
+#include <class_drawpanel.h>
+#include <pcb_draw_panel_gal.h>
+#include <confirm.h>
+#include <gestfich.h>
+#include <pgm_base.h>
+#include <trigo.h>
+#include <3d_viewer.h>
+#include <wxPcbStruct.h>
+#include <kicad_device_context.h>
+#include <macros.h>
+#include <invoke_pcb_dialog.h>
+#include <class_pcb_layer_widget.h>
+
+#include <class_board.h>
+#include <class_module.h>
+#include <class_edge_mod.h>
+
+#include <ratsnest_data.h>
+#include <pcbnew.h>
+#include <protos.h>
+#include <pcbnew_id.h>
+#include <module_editor_frame.h>
+#include <modview_frame.h>
+#include <collectors.h>
+#include <tool/tool_manager.h>
+#include <tools/common_actions.h>
+
+#include <dialog_edit_module_for_Modedit.h>
+#include <dialog_move_exact.h>
+#include <dialog_create_array.h>
+#include <wildcards_and_files_ext.h>
+#include <menus_helpers.h>
+#include <footprint_wizard_frame.h>
+#include <pcbnew_config.h>
+
+#include <boost/bind.hpp>
+
+
+// Functions defined in block_module_editor, but used here
+// These 3 functions are used in modedit to rotate, mirror or move the
+// whole footprint so they are called with force_all = true
+void MirrorMarkedItems( MODULE* module, wxPoint offset, bool force_all = false );
+void RotateMarkedItems( MODULE* module, wxPoint offset, bool force_all = false );
+void MoveMarkedItemsExactly( MODULE* module, const wxPoint& centre,
+ const wxPoint& translation, double rotation,
+ bool force_all = false );
+
+
+BOARD_ITEM* FOOTPRINT_EDIT_FRAME::ModeditLocateAndDisplay( int aHotKeyCode )
+{
+ BOARD_ITEM* item = GetCurItem();
+
+ if( GetBoard()->m_Modules == NULL )
+ return NULL;
+
+ GENERAL_COLLECTORS_GUIDE guide = GetCollectorsGuide();
+
+ // Assign to scanList the proper item types desired based on tool type
+ // or hotkey that is in play.
+
+ const KICAD_T* scanList = NULL;
+
+ if( aHotKeyCode )
+ {
+ // @todo: add switch here and add calls to PcbGeneralLocateAndDisplay(
+ // int aHotKeyCode ) when searching is needed from a hotkey handler
+ }
+ else
+ {
+ scanList = GENERAL_COLLECTOR::ModulesAndTheirItems;
+ }
+
+ m_Collector->Collect( GetBoard(), scanList, RefPos( true ), guide );
+
+ // Remove redundancies: when an item is found, we can remove the module from list
+ if( m_Collector->GetCount() > 1 )
+ {
+ for( int ii = 0; ii < m_Collector->GetCount(); ii++ )
+ {
+ item = (*m_Collector)[ii];
+
+ if( item->Type() != PCB_MODULE_T )
+ continue;
+
+ m_Collector->Remove( ii );
+ ii--;
+ }
+ }
+
+ if( m_Collector->GetCount() <= 1 )
+ {
+ item = (*m_Collector)[0];
+ SetCurItem( item );
+ }
+ else // we can't figure out which item user wants, do popup menu so user can choose
+ {
+ wxMenu itemMenu;
+
+ // Give a title to the selection menu. It also allow to close the popup menu without any action
+ wxMenuItem* item_title = new wxMenuItem( &itemMenu, wxID_NONE, _( "Selection Clarification" ) );
+
+#ifdef __WINDOWS__
+ wxFont bold_font( *wxNORMAL_FONT );
+ bold_font.SetWeight( wxFONTWEIGHT_BOLD );
+ bold_font.SetStyle( wxFONTSTYLE_ITALIC );
+ item_title->SetFont( bold_font );
+#endif
+
+ itemMenu.Append( item_title );
+ itemMenu.AppendSeparator();
+
+ int limit = std::min( MAX_ITEMS_IN_PICKER, m_Collector->GetCount() );
+
+ for( int ii = 0; ii<limit; ++ii )
+ {
+ item = (*m_Collector)[ii];
+
+ wxString text = item->GetSelectMenuText();
+ BITMAP_DEF xpm = item->GetMenuImage();
+
+ AddMenuItem( &itemMenu,
+ ID_POPUP_PCB_ITEM_SELECTION_START + ii,
+ text,
+ KiBitmap( xpm ) );
+ }
+
+ // this menu's handler is void
+ // PCB_BASE_FRAME::ProcessItemSelection()
+ // and it calls SetCurItem() which in turn calls DisplayInfo() on the
+ // item.
+ m_canvas->SetAbortRequest( true ); // changed in false if an item
+ PopupMenu( &itemMenu ); // m_AbortRequest = false if an item is selected
+
+ m_canvas->MoveCursorToCrossHair();
+ m_canvas->SetIgnoreMouseEvents( false );
+
+ // The function ProcessItemSelection() has set the current item, return it.
+ item = GetCurItem();
+ }
+
+ if( item )
+ {
+ SetMsgPanel( item );
+ }
+
+ return item;
+}
+
+
+void FOOTPRINT_EDIT_FRAME::LoadModuleFromBoard( wxCommandEvent& event )
+{
+ if( GetScreen()->IsModify() )
+ {
+ if( !IsOK( this,
+ _( "Current footprint changes will be lost and this operation cannot be undone. Continue?" ) ) )
+ return;
+ }
+
+ if( ! Load_Module_From_BOARD( NULL ) )
+ return;
+
+ GetScreen()->ClearUndoRedoList();
+ GetScreen()->ClrModify();
+
+ if( m_Draw3DFrame )
+ m_Draw3DFrame->NewDisplay();
+}
+
+
+void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
+{
+ int id = event.GetId();
+ wxPoint pos;
+
+ INSTALL_UNBUFFERED_DC( dc, m_canvas );
+
+ wxGetMousePosition( &pos.x, &pos.y );
+
+ pos.y += 20;
+
+ switch( id )
+ {
+ case wxID_CUT:
+ case wxID_COPY:
+ case ID_TOOLBARH_PCB_SELECT_LAYER:
+ case ID_MODEDIT_PAD_SETTINGS:
+ case ID_PCB_USER_GRID_SETUP:
+ case ID_POPUP_PCB_ROTATE_TEXTEPCB:
+ case ID_POPUP_PCB_EDIT_TEXTEPCB:
+ case ID_POPUP_PCB_ROTATE_TEXTMODULE:
+ case ID_POPUP_PCB_ROTATE_MODULE_CLOCKWISE:
+ case ID_POPUP_PCB_ROTATE_MODULE_COUNTERCLOCKWISE:
+ case ID_POPUP_PCB_EDIT_TEXTMODULE:
+ case ID_POPUP_PCB_IMPORT_PAD_SETTINGS:
+ case ID_POPUP_PCB_EXPORT_PAD_SETTINGS:
+ case ID_POPUP_PCB_GLOBAL_IMPORT_PAD_SETTINGS:
+ case ID_POPUP_PCB_STOP_CURRENT_DRAWING:
+ case ID_POPUP_MODEDIT_EDIT_BODY_ITEM:
+ case ID_POPUP_MODEDIT_EDIT_WIDTH_ALL_EDGE:
+ case ID_POPUP_MODEDIT_EDIT_LAYER_ALL_EDGE:
+ case ID_POPUP_MODEDIT_ENTER_EDGE_WIDTH:
+ case ID_POPUP_PCB_DELETE_EDGE:
+ case ID_POPUP_PCB_DELETE_TEXTMODULE:
+ case ID_POPUP_PCB_DELETE_PAD:
+ case ID_POPUP_DELETE_BLOCK:
+ case ID_POPUP_PLACE_BLOCK:
+ case ID_POPUP_ZOOM_BLOCK:
+ case ID_POPUP_MIRROR_X_BLOCK:
+ case ID_POPUP_ROTATE_BLOCK:
+ case ID_POPUP_COPY_BLOCK:
+ break;
+
+ case ID_POPUP_CANCEL_CURRENT_COMMAND:
+ default:
+ if( m_canvas->IsMouseCaptured() )
+ {
+ // for all other commands: stop the move in progress
+ m_canvas->CallEndMouseCapture( &dc );
+ }
+
+ if( id != ID_POPUP_CANCEL_CURRENT_COMMAND )
+ SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
+
+ break;
+ }
+
+ switch( id )
+ {
+ case ID_EXIT:
+ Close( true );
+ break;
+
+ case ID_MODEDIT_SELECT_CURRENT_LIB:
+ {
+ wxString library = SelectLibrary( GetCurrentLib() );
+
+ if( library.size() )
+ {
+ Prj().SetRString( PROJECT::PCB_LIB_NICKNAME, library );
+ updateTitle();
+ }
+ }
+ break;
+
+ case ID_OPEN_MODULE_VIEWER:
+ {
+ FOOTPRINT_VIEWER_FRAME* viewer = (FOOTPRINT_VIEWER_FRAME*) Kiway().Player( FRAME_PCB_MODULE_VIEWER, false );
+
+ if( !viewer )
+ {
+ viewer = (FOOTPRINT_VIEWER_FRAME*) Kiway().Player( FRAME_PCB_MODULE_VIEWER, true );
+ viewer->Show( true );
+ viewer->Zoom_Automatique( false );
+ }
+ else
+ {
+ // On Windows, Raise() does not bring the window on screen, when iconized
+ if( viewer->IsIconized() )
+ viewer->Iconize( false );
+
+ viewer->Raise();
+
+ // Raising the window does not set the focus on Linux. This should work on
+ // any platform.
+ if( wxWindow::FindFocus() != viewer )
+ viewer->SetFocus();
+ }
+ }
+ break;
+
+ case ID_MODEDIT_DELETE_PART:
+ DeleteModuleFromCurrentLibrary();
+ break;
+
+ case ID_MODEDIT_NEW_MODULE:
+ {
+ if( !Clear_Pcb( true ) )
+ break;
+
+ SetCrossHairPosition( wxPoint( 0, 0 ) );
+
+ MODULE* module = CreateNewModule( wxEmptyString );
+
+ if( module ) // i.e. if create module command not aborted
+ {
+ // Initialize data relative to nets and netclasses (for a new
+ // module the defaults are used)
+ // This is mandatory to handle and draw pads
+ GetBoard()->BuildListOfNets();
+ module->SetPosition( wxPoint( 0, 0 ) );
+
+ if( GetBoard()->m_Modules )
+ GetBoard()->m_Modules->ClearFlags();
+
+ Zoom_Automatique( false );
+ }
+
+ updateView();
+ m_canvas->Refresh();
+
+ GetScreen()->ClrModify();
+ }
+ break;
+
+ case ID_MODEDIT_NEW_MODULE_FROM_WIZARD:
+ {
+ if( GetScreen()->IsModify() && !GetBoard()->IsEmpty() )
+ {
+ if( !IsOK( this,
+ _( "Current Footprint will be lost and this operation cannot be undone. Continue ?" ) ) )
+ break;
+ }
+
+ FOOTPRINT_WIZARD_FRAME* wizard = (FOOTPRINT_WIZARD_FRAME*) Kiway().Player(
+ FRAME_PCB_FOOTPRINT_WIZARD_MODAL, true );
+
+ if( wizard->ShowModal( NULL, this ) )
+ {
+ // Creates the new footprint from python script wizard
+ MODULE* module = wizard->GetBuiltFootprint();
+
+ if( module == NULL ) // i.e. if create module command aborted
+ break;
+
+ Clear_Pcb( false );
+
+ SetCrossHairPosition( wxPoint( 0, 0 ) );
+
+ // Add the new object to board
+ GetBoard()->Add( module, ADD_APPEND );
+
+ // Initialize data relative to nets and netclasses (for a new
+ // module the defaults are used)
+ // This is mandatory to handle and draw pads
+ GetBoard()->BuildListOfNets();
+ module->SetPosition( wxPoint( 0, 0 ) );
+ module->ClearFlags();
+
+ Zoom_Automatique( false );
+ updateView();
+ m_canvas->Refresh();
+
+ if( m_Draw3DFrame )
+ m_Draw3DFrame->NewDisplay();
+
+ GetScreen()->ClrModify();
+ }
+
+ wizard->Destroy();
+ }
+ break;
+
+ case ID_MODEDIT_SAVE_LIBMODULE:
+ if( GetBoard()->m_Modules && GetCurrentLib().size() )
+ {
+ SaveFootprintInLibrary( GetCurrentLib(), GetBoard()->m_Modules, true, true );
+ GetScreen()->ClrModify();
+ }
+ break;
+
+ case ID_MODEDIT_INSERT_MODULE_IN_BOARD:
+ case ID_MODEDIT_UPDATE_MODULE_IN_BOARD:
+ {
+ // update module in the current board,
+ // not just add it to the board with total disregard for the netlist...
+ PCB_EDIT_FRAME* pcbframe = (PCB_EDIT_FRAME*) Kiway().Player( FRAME_PCB, false );
+
+ if( pcbframe == NULL ) // happens when the board editor is not active (or closed)
+ {
+ wxMessageBox( _("No board currently edited" ) );
+ break;
+ }
+
+ BOARD* mainpcb = pcbframe->GetBoard();
+ MODULE* source_module = NULL;
+ MODULE* module_in_edit = GetBoard()->m_Modules;
+
+ // Search the old module (source) if exists
+ // Because this source could be deleted when editing the main board...
+ if( module_in_edit->GetLink() ) // this is not a new module ...
+ {
+ source_module = mainpcb->m_Modules;
+
+ for( ; source_module != NULL; source_module = source_module->Next() )
+ {
+ if( module_in_edit->GetLink() == source_module->GetTimeStamp() )
+ break;
+ }
+ }
+
+ if( ( source_module == NULL )
+ && ( id == ID_MODEDIT_UPDATE_MODULE_IN_BOARD ) ) // source not found
+ {
+ wxString msg;
+ msg.Printf( _( "Unable to find the footprint source on the main board" ) );
+ msg << _( "\nCannot update the footprint" );
+ DisplayError( this, msg );
+ break;
+ }
+
+ if( ( source_module != NULL )
+ && ( id == ID_MODEDIT_INSERT_MODULE_IN_BOARD ) ) // source not found
+ {
+ wxString msg;
+ msg.Printf( _( "A footprint source was found on the main board" ) );
+ msg << _( "\nCannot insert this footprint" );
+ DisplayError( this, msg );
+ break;
+ }
+
+ m_toolManager->RunAction( COMMON_ACTIONS::selectionClear, true );
+
+ // Create the "new" module
+ MODULE* newmodule = new MODULE( *module_in_edit );
+ newmodule->SetParent( mainpcb );
+ newmodule->SetLink( 0 );
+
+ // Put the footprint in the main pcb linked list.
+ mainpcb->Add( newmodule );
+
+ if( source_module ) // this is an update command
+ {
+ // In the main board,
+ // the new module replace the old module (pos, orient, ref, value
+ // and connexions are kept)
+ // and the source_module (old module) is deleted
+ PICKED_ITEMS_LIST pickList;
+
+ if( pcbframe->IsGalCanvasActive() )
+ {
+ KIGFX::VIEW* view = pcbframe->GetGalCanvas()->GetView();
+ source_module->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) );
+ view->Remove( source_module );
+ }
+
+ pcbframe->Exchange_Module( source_module, newmodule, &pickList );
+ newmodule->SetTimeStamp( module_in_edit->GetLink() );
+
+ if( pickList.GetCount() )
+ pcbframe->SaveCopyInUndoList( pickList, UR_UNSPECIFIED );
+ }
+ else // This is an insert command
+ {
+ wxPoint cursor_pos = pcbframe->GetCrossHairPosition();
+
+ pcbframe->SetCrossHairPosition( wxPoint( 0, 0 ) );
+ pcbframe->PlaceModule( newmodule, NULL );
+ newmodule->SetPosition( wxPoint( 0, 0 ) );
+ pcbframe->SetCrossHairPosition( cursor_pos );
+ newmodule->SetTimeStamp( GetNewTimeStamp() );
+ pcbframe->SaveCopyInUndoList( newmodule, UR_NEW );
+ }
+
+ newmodule->ClearFlags();
+ GetScreen()->ClrModify();
+ pcbframe->SetCurItem( NULL );
+ mainpcb->m_Status_Pcb = 0;
+
+ if( pcbframe->IsGalCanvasActive() )
+ {
+ RN_DATA* ratsnest = pcbframe->GetBoard()->GetRatsnest();
+ ratsnest->Update( newmodule );
+ ratsnest->Recalculate();
+
+ KIGFX::VIEW* view = pcbframe->GetGalCanvas()->GetView();
+ newmodule->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) );
+ view->Add( newmodule );
+ pcbframe->GetGalCanvas()->ForceRefresh();
+ }
+ }
+ break;
+
+ case ID_MODEDIT_IMPORT_PART:
+ if( ! Clear_Pcb( true ) )
+ break; // //this command is aborted
+
+ SetCrossHairPosition( wxPoint( 0, 0 ) );
+ Import_Module();
+
+ if( GetBoard()->m_Modules )
+ GetBoard()->m_Modules->ClearFlags();
+
+ GetScreen()->ClrModify();
+ Zoom_Automatique( false );
+ m_canvas->Refresh();
+
+ if( m_Draw3DFrame )
+ m_Draw3DFrame->NewDisplay();
+
+ break;
+
+ case ID_MODEDIT_EXPORT_PART:
+ if( GetBoard()->m_Modules )
+ Export_Module( GetBoard()->m_Modules );
+ break;
+
+ case ID_MODEDIT_CREATE_NEW_LIB_AND_SAVE_CURRENT_PART:
+ if( GetBoard()->m_Modules )
+ {
+ // CreateModuleLibrary() only creates a new library, does not save footprint
+ wxString libPath = CreateNewLibrary();
+ if( libPath.size() )
+ SaveCurrentModule( &libPath );
+ }
+ break;
+
+ case ID_MODEDIT_SHEET_SET:
+ break;
+
+ case ID_MODEDIT_LOAD_MODULE:
+ wxLogDebug( wxT( "Loading module from library " ) + getLibPath() );
+
+ if( ! Clear_Pcb( true ) )
+ break;
+
+ SetCrossHairPosition( wxPoint( 0, 0 ) );
+
+ LoadModuleFromLibrary( GetCurrentLib(), Prj().PcbFootprintLibs(), true );
+
+ if( GetBoard() && GetBoard()->m_Modules )
+ {
+ GetBoard()->m_Modules->ClearFlags();
+
+ // if either m_Reference or m_Value are gone, reinstall them -
+ // otherwise you cannot see what you are doing on board
+ TEXTE_MODULE* ref = &GetBoard()->m_Modules->Reference();
+ TEXTE_MODULE* val = &GetBoard()->m_Modules->Value();
+
+ if( val && ref )
+ {
+ ref->SetType( TEXTE_MODULE::TEXT_is_REFERENCE ); // just in case ...
+
+ if( ref->GetLength() == 0 )
+ ref->SetText( wxT( "Ref**" ) );
+
+ val->SetType( TEXTE_MODULE::TEXT_is_VALUE ); // just in case ...
+
+ if( val->GetLength() == 0 )
+ val->SetText( wxT( "Val**" ) );
+ }
+ }
+
+ Zoom_Automatique( false );
+
+ if( m_Draw3DFrame )
+ m_Draw3DFrame->NewDisplay();
+
+ GetScreen()->ClrModify();
+
+ updateView();
+ m_canvas->Refresh();
+
+ break;
+
+ case ID_MODEDIT_PAD_SETTINGS:
+ InstallPadOptionsFrame( NULL );
+ break;
+
+ case ID_MODEDIT_CHECK:
+ // Currently: not implemented
+ break;
+
+ case ID_MODEDIT_EDIT_MODULE_PROPERTIES:
+ if( GetBoard()->m_Modules )
+ {
+ SetCurItem( GetBoard()->m_Modules );
+
+ DIALOG_MODULE_MODULE_EDITOR dialog( this, (MODULE*) GetScreen()->GetCurItem() );
+
+ int ret = dialog.ShowModal();
+ GetScreen()->GetCurItem()->ClearFlags();
+ GetBoard()->m_Modules.GetFirst()->ViewUpdate();
+
+ if( ret > 0 )
+ m_canvas->Refresh();
+ }
+ break;
+
+ case ID_POPUP_CLOSE_CURRENT_TOOL:
+ break;
+
+ case ID_POPUP_CANCEL_CURRENT_COMMAND:
+ break;
+
+ case ID_POPUP_PCB_ROTATE_MODULE_COUNTERCLOCKWISE:
+ m_canvas->MoveCursorToCrossHair();
+ Rotate_Module( NULL, (MODULE*) GetScreen()->GetCurItem(), 900, true );
+ m_canvas->Refresh();
+ break;
+
+ case ID_POPUP_PCB_ROTATE_MODULE_CLOCKWISE:
+ m_canvas->MoveCursorToCrossHair();
+ Rotate_Module( NULL, (MODULE*) GetScreen()->GetCurItem(), -900, true );
+ m_canvas->Refresh();
+ break;
+
+ case ID_POPUP_PCB_EDIT_MODULE_PRMS:
+ {
+ DIALOG_MODULE_MODULE_EDITOR dialog( this, (MODULE*) GetScreen()->GetCurItem() );
+ dialog.ShowModal();
+ GetScreen()->GetCurItem()->ClearFlags();
+ m_canvas->MoveCursorToCrossHair();
+ m_canvas->Refresh();
+ }
+ break;
+
+ case ID_POPUP_PCB_MOVE_PAD_REQUEST:
+ m_canvas->MoveCursorToCrossHair();
+ StartMovePad( (D_PAD*) GetScreen()->GetCurItem(), &dc, false );
+ break;
+
+ case ID_POPUP_PCB_EDIT_PAD:
+ InstallPadOptionsFrame( (D_PAD*) GetScreen()->GetCurItem() );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_DELETE_PAD:
+ SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
+ DeletePad( (D_PAD*) GetScreen()->GetCurItem(), false );
+ SetCurItem( NULL );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_DUPLICATE_ITEM:
+ duplicateItems( false );
+ break;
+
+ case ID_POPUP_PCB_DUPLICATE_ITEM_AND_INCREMENT:
+ duplicateItems( true );
+ break;
+
+ case ID_POPUP_PCB_MOVE_EXACT:
+ moveExact();
+ break;
+
+ case ID_POPUP_PCB_CREATE_ARRAY:
+ createArray();
+ break;
+
+ case ID_POPUP_PCB_IMPORT_PAD_SETTINGS:
+ SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
+ m_canvas->MoveCursorToCrossHair();
+ Import_Pad_Settings( (D_PAD*) GetScreen()->GetCurItem(), true );
+ break;
+
+ case ID_POPUP_PCB_GLOBAL_IMPORT_PAD_SETTINGS:
+ SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
+ // Calls the global change dialog:
+ DlgGlobalChange_PadSettings( (D_PAD*) GetScreen()->GetCurItem() );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_EXPORT_PAD_SETTINGS:
+ m_canvas->MoveCursorToCrossHair();
+ Export_Pad_Settings( (D_PAD*) GetScreen()->GetCurItem() );
+ break;
+
+ case ID_POPUP_PCB_EDIT_TEXTMODULE:
+ InstallTextModOptionsFrame( static_cast<TEXTE_MODULE*>( GetScreen()->GetCurItem() ), &dc );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_MOVE_TEXTMODULE_REQUEST:
+ m_canvas->MoveCursorToCrossHair();
+ StartMoveTexteModule( static_cast<TEXTE_MODULE*>( GetScreen()->GetCurItem() ), &dc );
+ break;
+
+ case ID_POPUP_PCB_ROTATE_TEXTMODULE:
+ RotateTextModule( static_cast<TEXTE_MODULE*>( GetScreen()->GetCurItem() ), &dc );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_DELETE_TEXTMODULE:
+ SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
+ DeleteTextModule( static_cast<TEXTE_MODULE*>( GetScreen()->GetCurItem() ) );
+ SetCurItem( NULL );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_MOVE_EDGE:
+ Start_Move_EdgeMod( static_cast<EDGE_MODULE*>( GetScreen()->GetCurItem() ), &dc );
+ m_canvas->MoveCursorToCrossHair();
+ break;
+
+ case ID_POPUP_PCB_STOP_CURRENT_DRAWING:
+ m_canvas->MoveCursorToCrossHair();
+
+ if( GetScreen()->GetCurItem()->IsNew() )
+ {
+ End_Edge_Module( (EDGE_MODULE*) GetScreen()->GetCurItem() );
+ SetCurItem( NULL );
+ }
+ break;
+
+ case ID_POPUP_MODEDIT_ENTER_EDGE_WIDTH:
+ {
+ EDGE_MODULE* edge = NULL;
+
+ if( GetScreen()->GetCurItem()
+ && ( GetScreen()->GetCurItem()->Type() == PCB_MODULE_EDGE_T ) )
+ {
+ edge = (EDGE_MODULE*) GetScreen()->GetCurItem();
+ }
+
+ Enter_Edge_Width( edge );
+ m_canvas->MoveCursorToCrossHair();
+
+ if( edge )
+ m_canvas->Refresh();
+ }
+ break;
+
+ case ID_POPUP_MODEDIT_EDIT_BODY_ITEM :
+ m_canvas->MoveCursorToCrossHair();
+ InstallFootprintBodyItemPropertiesDlg( (EDGE_MODULE*) GetScreen()->GetCurItem() );
+ m_canvas->Refresh();
+ break;
+
+ case ID_POPUP_MODEDIT_EDIT_WIDTH_ALL_EDGE:
+ m_canvas->MoveCursorToCrossHair();
+ Edit_Edge_Width( NULL );
+ m_canvas->Refresh();
+ break;
+
+ case ID_POPUP_MODEDIT_EDIT_LAYER_ALL_EDGE:
+ m_canvas->MoveCursorToCrossHair();
+ Edit_Edge_Layer( NULL );
+ m_canvas->Refresh();
+ break;
+
+ case ID_POPUP_PCB_DELETE_EDGE:
+ SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
+ m_canvas->MoveCursorToCrossHair();
+ RemoveStruct( GetScreen()->GetCurItem() );
+ SetCurItem( NULL );
+ break;
+
+ case ID_MODEDIT_MODULE_ROTATE:
+ case ID_MODEDIT_MODULE_MIRROR:
+ case ID_MODEDIT_MODULE_MOVE_EXACT:
+ SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
+ Transform( (MODULE*) GetScreen()->GetCurItem(), id );
+ m_canvas->Refresh();
+ break;
+
+ case ID_PCB_DRAWINGS_WIDTHS_SETUP:
+ InstallOptionsFrame( pos );
+ break;
+
+ case ID_PCB_PAD_SETUP:
+ {
+ BOARD_ITEM* item = GetCurItem();
+
+ if( item )
+ {
+ if( item->Type() != PCB_PAD_T )
+ item = NULL;
+ }
+
+ InstallPadOptionsFrame( (D_PAD*) item );
+ }
+ break;
+
+ case ID_PCB_USER_GRID_SETUP:
+ InvokeDialogGrid();
+ break;
+
+ case ID_POPUP_PLACE_BLOCK:
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_MOVE );
+ m_canvas->SetAutoPanRequest( false );
+ HandleBlockPlace( &dc );
+ break;
+
+ case ID_POPUP_COPY_BLOCK:
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_COPY );
+ GetScreen()->m_BlockLocate.SetMessageBlock( this );
+ m_canvas->SetAutoPanRequest( false );
+ HandleBlockPlace( &dc );
+ break;
+
+ case ID_POPUP_ZOOM_BLOCK:
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_ZOOM );
+ GetScreen()->m_BlockLocate.SetMessageBlock( this );
+ HandleBlockEnd( &dc );
+ break;
+
+ case ID_POPUP_DELETE_BLOCK:
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_DELETE );
+ GetScreen()->m_BlockLocate.SetMessageBlock( this );
+ HandleBlockEnd( &dc );
+ break;
+
+ case ID_POPUP_ROTATE_BLOCK:
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_ROTATE );
+ GetScreen()->m_BlockLocate.SetMessageBlock( this );
+ HandleBlockEnd( &dc );
+ break;
+
+ case ID_POPUP_MIRROR_X_BLOCK:
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_MIRROR_X );
+ GetScreen()->m_BlockLocate.SetMessageBlock( this );
+ HandleBlockEnd( &dc );
+ break;
+
+ case ID_POPUP_MOVE_BLOCK_EXACT:
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_MOVE_EXACT );
+ GetScreen()->m_BlockLocate.SetMessageBlock( this );
+ HandleBlockEnd( &dc );
+ break;
+
+ case ID_GEN_IMPORT_DXF_FILE:
+ if( GetBoard()->m_Modules )
+ {
+ InvokeDXFDialogModuleImport( this, GetBoard()->m_Modules );
+ m_canvas->Refresh();
+ }
+ break;
+
+ default:
+ DisplayError( this,
+ wxT( "FOOTPRINT_EDIT_FRAME::Process_Special_Functions error" ) );
+ break;
+ }
+}
+
+
+void FOOTPRINT_EDIT_FRAME::moveExact()
+{
+ wxPoint translation;
+ double rotation = 0;
+
+ DIALOG_MOVE_EXACT dialog( this, translation, rotation );
+ int ret = dialog.ShowModal();
+
+ if( ret == wxID_OK )
+ {
+ SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
+
+ BOARD_ITEM* item = GetScreen()->GetCurItem();
+
+ item->Move( translation );
+ item->Rotate( item->GetPosition(), rotation );
+ m_canvas->Refresh();
+ }
+
+ m_canvas->MoveCursorToCrossHair();
+}
+
+
+void FOOTPRINT_EDIT_FRAME::duplicateItems( bool aIncrement )
+{
+ BOARD_ITEM* item = GetScreen()->GetCurItem();
+
+ PCB_BASE_EDIT_FRAME::duplicateItem( item, aIncrement );
+}
+
+
+void FOOTPRINT_EDIT_FRAME::Transform( MODULE* module, int transform )
+{
+ switch( transform )
+ {
+ case ID_MODEDIT_MODULE_ROTATE:
+ RotateMarkedItems( module, wxPoint(0,0), true );
+ break;
+
+ case ID_MODEDIT_MODULE_MIRROR:
+ MirrorMarkedItems( module, wxPoint(0,0), true );
+ break;
+
+ case ID_MODEDIT_MODULE_MOVE_EXACT:
+ {
+ wxPoint translation;
+ double rotation = 0;
+
+ DIALOG_MOVE_EXACT dialog( this, translation, rotation );
+ int ret = dialog.ShowModal();
+
+ if( ret == wxID_OK )
+ {
+ MoveMarkedItemsExactly( module, wxPoint(0, 0),
+ translation, rotation, true );
+ }
+
+ break;
+ }
+
+ default:
+ DisplayInfoMessage( this, wxT( "Not available" ) );
+ break;
+ }
+
+ module->CalculateBoundingBox();
+ OnModify();
+}
+
+
+void FOOTPRINT_EDIT_FRAME::OnVerticalToolbar( wxCommandEvent& aEvent )
+{
+ int id = aEvent.GetId();
+
+ SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
+
+ switch( id )
+ {
+ case ID_NO_TOOL_SELECTED:
+ break;
+
+ case ID_MODEDIT_LINE_TOOL:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add line" ) );
+ break;
+
+ case ID_MODEDIT_ARC_TOOL:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add arc" ) );
+ break;
+
+ case ID_MODEDIT_CIRCLE_TOOL:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add circle" ) );
+ break;
+
+ case ID_MODEDIT_TEXT_TOOL:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add text" ) );
+ break;
+
+ case ID_MODEDIT_ANCHOR_TOOL:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Place anchor" ) );
+ break;
+
+ case ID_MODEDIT_PLACE_GRID_COORD:
+ SetToolID( id, wxCURSOR_PENCIL, _( "Set grid origin" ) );
+ break;
+
+ case ID_MODEDIT_PAD_TOOL:
+ if( GetBoard()->m_Modules )
+ {
+ SetToolID( id, wxCURSOR_PENCIL, _( "Add pad" ) );
+ }
+ else
+ {
+ SetToolID( id, wxCURSOR_ARROW, _( "Pad settings" ) );
+ InstallPadOptionsFrame( NULL );
+ SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
+ }
+ break;
+
+ case ID_MODEDIT_DELETE_TOOL:
+ SetToolID( id, wxCURSOR_BULLSEYE, _( "Delete item" ) );
+ break;
+
+ default:
+ wxFAIL_MSG( wxT( "Unknown command id." ) );
+ SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
+ }
+}
+
+
+EDA_COLOR_T FOOTPRINT_EDIT_FRAME::GetGridColor() const
+{
+ return g_ColorsSettings.GetItemColor( GRID_VISIBLE );
+}
+
+
+void FOOTPRINT_EDIT_FRAME::SetActiveLayer( LAYER_ID aLayer )
+{
+ PCB_BASE_FRAME::SetActiveLayer( aLayer );
+
+ m_Layers->SelectLayer( GetActiveLayer() );
+ m_Layers->OnLayerSelected();
+
+ if( IsGalCanvasActive() )
+ {
+ GetGalCanvas()->SetHighContrastLayer( aLayer );
+ GetGalCanvas()->Refresh();
+ }
+}
+