From c9ca1013b2d530562a11fee3abe786d89129542f Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Wed, 3 Oct 2018 22:44:17 +0100 Subject: [PATCH] Make ModEdit and LibEdit library tree actions more consistent. Adds Cut/Copy/Paste and Revert for footprints; introduces a new shared Revert Changes? dialog; hooks up Add Library for footprints, standardizes the Save As terminology. --- common/confirm.cpp | 13 ++ common/fp_lib_table.cpp | 14 ++ eeschema/libedit.cpp | 4 +- eeschema/menubar_libedit.cpp | 2 +- eeschema/widgets/symbol_tree_pane.cpp | 2 +- include/confirm.h | 7 + include/fp_lib_table.h | 7 + pcbnew/footprint_edit_frame.cpp | 8 + pcbnew/footprint_edit_frame.h | 5 + pcbnew/footprint_editor_utils.cpp | 40 +++++ pcbnew/footprint_libraries_utils.cpp | 222 ++++++++++++++++---------- pcbnew/footprint_tree_pane.cpp | 31 ++-- pcbnew/menubar_footprint_editor.cpp | 9 +- pcbnew/pcb_base_edit_frame.h | 8 + pcbnew/pcbnew_id.h | 5 + 15 files changed, 272 insertions(+), 105 deletions(-) diff --git a/common/confirm.cpp b/common/confirm.cpp index 43ff1df114..85fe46960a 100644 --- a/common/confirm.cpp +++ b/common/confirm.cpp @@ -197,6 +197,19 @@ int UnsavedChangesDialog( wxWindow* parent, const wxString& aMessage, bool* aApp } +bool ConfirmRevertDialog( wxWindow* parent, const wxString& aMessage ) +{ + DIALOG_EXIT dlg( parent, aMessage, + _( "Your current changes will be permanently lost." ), + _( "Revert" ), _( "Cancel" ) ); + + dlg.m_ApplyToAllOpt->Show( false ); + dlg.m_DiscardButton->Show( false ); + + return dlg.ShowModal() == wxID_YES; +} + + bool HandleUnsavedChanges( wxWindow* aParent, const wxString& aMessage, const std::function& aSaveFunction ) { diff --git a/common/fp_lib_table.cpp b/common/fp_lib_table.cpp index 06085d086d..7402bd4551 100644 --- a/common/fp_lib_table.cpp +++ b/common/fp_lib_table.cpp @@ -334,6 +334,20 @@ const MODULE* FP_LIB_TABLE::GetEnumeratedFootprint( const wxString& aNickname, } +bool FP_LIB_TABLE::FootprintExists( const wxString& aNickname, const wxString& aFootprintName ) +{ + try + { + std::unique_ptr m( FootprintLoad( aNickname, aFootprintName ) ); + return m.get() != nullptr; + } + catch( ... ) + { + return false; + } +} + + MODULE* FP_LIB_TABLE::FootprintLoad( const wxString& aNickname, const wxString& aFootprintName ) { const FP_LIB_TABLE_ROW* row = FindRow( aNickname ); diff --git a/eeschema/libedit.cpp b/eeschema/libedit.cpp index 7cbbe89ddc..3e8e72f8d8 100644 --- a/eeschema/libedit.cpp +++ b/eeschema/libedit.cpp @@ -568,7 +568,9 @@ void LIB_EDIT_FRAME::OnRevert( wxCommandEvent& aEvent ) const wxString& libName = libId.GetLibNickname(); const wxString& partName = libId.GetLibItemName(); // Empty if this is the library itself that is selected - if( !IsOK( this, _( "The revert operation cannot be undone!\n\nRevert changes?" ) ) ) + wxString msg = wxString::Format( _( "Revert \"%s\" to last version saved?" ), partName ); + + if( !ConfirmRevertDialog( this, msg ) ) return; bool reload_currentPart; diff --git a/eeschema/menubar_libedit.cpp b/eeschema/menubar_libedit.cpp index 7784034696..55035b64b4 100644 --- a/eeschema/menubar_libedit.cpp +++ b/eeschema/menubar_libedit.cpp @@ -83,7 +83,7 @@ void LIB_EDIT_FRAME::ReCreateMenuBar() AddMenuItem( fileMenu, ID_LIBEDIT_SAVE_AS, text, - _( "Save to a new name and/or location" ), + _( "Save a copy to a new name and/or location" ), KiBitmap( save_as_xpm ) ); AddMenuItem( fileMenu, diff --git a/eeschema/widgets/symbol_tree_pane.cpp b/eeschema/widgets/symbol_tree_pane.cpp index 45c267d16e..21851e1b28 100644 --- a/eeschema/widgets/symbol_tree_pane.cpp +++ b/eeschema/widgets/symbol_tree_pane.cpp @@ -75,7 +75,7 @@ SYMBOL_TREE_PANE::SYMBOL_TREE_PANE( LIB_EDIT_FRAME* aParent, LIB_MANAGER* aLibMg menuPart->AppendSeparator(); AddMenuItem( menuPart.get(), ID_LIBEDIT_SAVE, _( "&Save" ), KiBitmap( save_xpm ) ); - AddMenuItem( menuPart.get(), ID_LIBEDIT_SAVE_AS, _( "Save As..." ), + AddMenuItem( menuPart.get(), ID_LIBEDIT_SAVE_AS, _( "Save a Copy As..." ), KiBitmap( save_xpm ) ); AddMenuItem( menuPart.get(), ID_LIBEDIT_DUPLICATE_PART, _( "Duplicate" ), KiBitmap( duplicate_xpm ) ); diff --git a/include/confirm.h b/include/confirm.h index f13e8018c2..94d6eec5cf 100644 --- a/include/confirm.h +++ b/include/confirm.h @@ -98,6 +98,13 @@ bool HandleUnsavedChanges( wxWindow* aParent, const wxString& aMessage, int UnsavedChangesDialog( wxWindow* aParent, const wxString& aMessage, bool* aApplyToAll ); +/** + * Function ConfirmRevertDialog + * displays a confirmation for a revert action + */ +bool ConfirmRevertDialog( wxWindow* parent, const wxString& aMessage ); + + /** * Function DisplayError * displays an error or warning message box with \a aMessage. diff --git a/include/fp_lib_table.h b/include/fp_lib_table.h index bf7e8a2175..d446f8a6ea 100644 --- a/include/fp_lib_table.h +++ b/include/fp_lib_table.h @@ -187,6 +187,13 @@ public: */ MODULE* FootprintLoad( const wxString& aNickname, const wxString& aFootprintName ); + /** + * Function FootprintExists + * + * indicates whether or not the given footprint already exists in the given library. + */ + bool FootprintExists( const wxString& aNickname, const wxString& aFootprintName ); + /** * Function GetEnumeratedFootprint * diff --git a/pcbnew/footprint_edit_frame.cpp b/pcbnew/footprint_edit_frame.cpp index 513b87b907..78664beb3a 100644 --- a/pcbnew/footprint_edit_frame.cpp +++ b/pcbnew/footprint_edit_frame.cpp @@ -97,14 +97,19 @@ BEGIN_EVENT_TABLE( FOOTPRINT_EDIT_FRAME, PCB_BASE_FRAME ) EVT_TOOL( ID_MODEDIT_SAVE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) EVT_TOOL( ID_MODEDIT_SAVE_AS, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) + EVT_TOOL( ID_MODEDIT_REVERT_PART, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) EVT_TOOL( ID_OPEN_MODULE_VIEWER, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) + EVT_TOOL( ID_MODEDIT_CUT_PART, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) + EVT_TOOL( ID_MODEDIT_COPY_PART, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) + EVT_TOOL( ID_MODEDIT_PASTE_PART, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) EVT_TOOL( ID_MODEDIT_DELETE_PART, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) EVT_TOOL( ID_MODEDIT_NEW_MODULE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) EVT_TOOL( ID_MODEDIT_NEW_MODULE_FROM_WIZARD, 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 ) EVT_TOOL( ID_MODEDIT_CREATE_NEW_LIB, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) + EVT_TOOL( ID_MODEDIT_ADD_LIBRARY, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) EVT_TOOL( ID_MODEDIT_SHEET_SET, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) EVT_TOOL( ID_GEN_IMPORT_DXF_FILE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) EVT_TOOL( wxID_PRINT, FOOTPRINT_EDIT_FRAME::ToPrinter ) @@ -177,6 +182,7 @@ BEGIN_EVENT_TABLE( FOOTPRINT_EDIT_FRAME, PCB_BASE_FRAME ) EVT_UPDATE_UI( ID_MODEDIT_EXPORT_PART, FOOTPRINT_EDIT_FRAME::OnUpdateSaveAs ) EVT_UPDATE_UI( ID_MODEDIT_SAVE, FOOTPRINT_EDIT_FRAME::OnUpdateSave ) EVT_UPDATE_UI( ID_MODEDIT_SAVE_AS, FOOTPRINT_EDIT_FRAME::OnUpdateSaveAs ) + EVT_UPDATE_UI( ID_MODEDIT_REVERT_PART, FOOTPRINT_EDIT_FRAME::OnUpdateSave ) EVT_UPDATE_UI( ID_MODEDIT_DELETE_PART, FOOTPRINT_EDIT_FRAME::OnUpdateModuleTargeted ) EVT_UPDATE_UI( ID_MODEDIT_LOAD_MODULE_FROM_BOARD, FOOTPRINT_EDIT_FRAME::OnUpdateLoadModuleFromBoard ) @@ -409,6 +415,8 @@ void FOOTPRINT_EDIT_FRAME::restoreLastFootprint() void FOOTPRINT_EDIT_FRAME::AddModuleToBoard( MODULE* aFootprint ) { + m_revertModule.reset( (MODULE*) aFootprint->Clone() ); + m_footprintNameWhenLoaded = aFootprint->GetFPID().GetLibItemName(); // Pads are always editable in Footprint Editor diff --git a/pcbnew/footprint_edit_frame.h b/pcbnew/footprint_edit_frame.h index a0db4ac51c..2561adc97a 100644 --- a/pcbnew/footprint_edit_frame.h +++ b/pcbnew/footprint_edit_frame.h @@ -47,6 +47,8 @@ class FOOTPRINT_EDIT_FRAME : public PCB_BASE_EDIT_FRAME FOOTPRINT_TREE_PANE* m_treePane; LIB_TREE_MODEL_ADAPTER::PTR m_adapter; + std::unique_ptr m_copiedModule; + std::unique_ptr m_revertModule; wxString m_footprintNameWhenLoaded; public: @@ -233,6 +235,7 @@ public: bool SaveFootprint( MODULE* aModule ); bool SaveFootprintAs( MODULE* aModule ); bool SaveFootprintToBoard( bool aAddNew ); + bool RevertFootprint(); /** * Virtual Function OnModify() @@ -563,6 +566,8 @@ private: */ void editFootprintProperties( MODULE* aFootprint ); + bool saveFootprintInLibrary( MODULE* aModule, const wxString& aLibraryName ); + /** * Function moveExact * Move the selected item exactly, popping up a dialog to allow the diff --git a/pcbnew/footprint_editor_utils.cpp b/pcbnew/footprint_editor_utils.cpp index d7802e7b86..014561b3cf 100644 --- a/pcbnew/footprint_editor_utils.cpp +++ b/pcbnew/footprint_editor_utils.cpp @@ -449,6 +449,42 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) m_treePane->GetLibTree()->Refresh(); break; + case ID_MODEDIT_REVERT_PART: + RevertFootprint(); + break; + + case ID_MODEDIT_CUT_PART: + case ID_MODEDIT_COPY_PART: + if( getTargetFPID().IsValid() ) + { + LIB_ID fpID = getTargetFPID(); + m_copiedModule.reset( LoadFootprint( fpID ) ); + + if( id == ID_MODEDIT_CUT_PART ) + DeleteModuleFromLibrary( fpID, false ); + + SyncLibraryTree( true ); + } + break; + + case ID_MODEDIT_PASTE_PART: + if( m_copiedModule && !getTargetFPID().GetLibNickname().empty() ) + { + wxString newLib = getTargetFPID().GetLibNickname(); + MODULE* newModule( m_copiedModule.get() ); + wxString newName = newModule->GetFPID().GetLibItemName(); + + while( Prj().PcbFootprintLibs()->FootprintExists( newLib, newName ) ) + newName += _( "_copy" ); + + newModule->SetFPID( LIB_ID( newLib, newName ) ); + saveFootprintInLibrary( newModule, newLib ); + + SyncLibraryTree( true ); + m_treePane->GetLibTree()->SelectLibId( newModule->GetFPID() ); + } + break; + case ID_MODEDIT_INSERT_MODULE_IN_BOARD: SaveFootprintToBoard( true ); break; @@ -492,6 +528,10 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) } break; + case ID_MODEDIT_ADD_LIBRARY: + AddLibrary(); + break; + case ID_MODEDIT_SHEET_SET: break; diff --git a/pcbnew/footprint_libraries_utils.cpp b/pcbnew/footprint_libraries_utils.cpp index d5cbe2bb6f..974ad59422 100644 --- a/pcbnew/footprint_libraries_utils.cpp +++ b/pcbnew/footprint_libraries_utils.cpp @@ -54,6 +54,7 @@ #include #include #include +#include "footprint_viewer_frame.h" // unique, "file local" translations: @@ -421,7 +422,7 @@ wxString PCB_BASE_EDIT_FRAME::CreateNewLibrary(const wxString& aLibName ) wxString initialPath = wxPathOnly( Prj().GetProjectFullName() ); wxFileName fn; - bool saveInGlobalTable = false, saveInProjectTable = false; + bool doAdd = false; if( aLibName.IsEmpty() ) { @@ -430,18 +431,7 @@ wxString PCB_BASE_EDIT_FRAME::CreateNewLibrary(const wxString& aLibName ) if( !LibraryFileBrowser( false, fn, KiCadFootprintLibPathWildcard(), KiCadFootprintLibPathExtension ) ) return wxEmptyString; - wxArrayString libTableNames; - libTableNames.Add( _( "Global" ) ); - libTableNames.Add( _( "Project" ) ); - - switch( SelectSingleOption( this, _( "Select Library Table" ), - _( "Choose the Library Table to add the library to:" ), - libTableNames ) ) - { - case 0: saveInGlobalTable = true; break; - case 1: saveInProjectTable = true; break; - default: return wxEmptyString; - } + doAdd = true; } else { @@ -499,25 +489,6 @@ wxString PCB_BASE_EDIT_FRAME::CreateNewLibrary(const wxString& aLibName ) } pi->FootprintLibCreate( libPath ); - - // try to use path normalized to an environmental variable or project path - wxString path = NormalizePath( libPath, &Pgm().GetLocalEnvVariables(), &Prj() ); - - if( path.IsEmpty() ) - path = libPath; - - if( saveInGlobalTable ) - { - auto row = new FP_LIB_TABLE_ROW( fn.GetName(), path, wxT( "KiCad" ), wxEmptyString ); - GFootprintTable.InsertRow( row ); - GFootprintTable.Save( FP_LIB_TABLE::GetGlobalTableFileName() ); - } - else if( saveInProjectTable ) - { - auto row = new FP_LIB_TABLE_ROW( fn.GetName(), path, wxT( "KiCad" ), wxEmptyString ); - Prj().PcbFootprintLibs()->InsertRow( row ); - Prj().PcbFootprintLibs()->Save( Prj().FootprintLibTblName() ); - } } catch( const IO_ERROR& ioe ) { @@ -525,10 +496,88 @@ wxString PCB_BASE_EDIT_FRAME::CreateNewLibrary(const wxString& aLibName ) return wxEmptyString; } + if( doAdd ) + AddLibrary( libPath ); + return libPath; } +bool PCB_BASE_EDIT_FRAME::AddLibrary( const wxString& aFilename ) +{ + wxFileName fn( aFilename ); + + if( aFilename.IsEmpty() ) + { + if( !LibraryFileBrowser( true, fn, KiCadFootprintLibPathWildcard(), KiCadFootprintLibPathExtension ) ) + return false; + } + + wxString libPath = fn.GetFullPath(); + wxString libName = fn.GetName(); + + if( libName.IsEmpty() ) + return false; + + bool saveInGlobalTable = false; + bool saveInProjectTable = false; + wxArrayString libTableNames; + + libTableNames.Add( _( "Global" ) ); + libTableNames.Add( _( "Project" ) ); + + switch( SelectSingleOption( this, _( "Select Library Table" ), + _( "Choose the Library Table to add the library to:" ), + libTableNames ) ) + { + case 0: saveInGlobalTable = true; break; + case 1: saveInProjectTable = true; break; + default: return false; + } + + wxString type = IO_MGR::ShowType( IO_MGR::GuessPluginTypeFromLibPath( libPath ) ); + + // try to use path normalized to an environmental variable or project path + wxString normalizedPath = NormalizePath( libPath, &Pgm().GetLocalEnvVariables(), &Prj() ); + + if( normalizedPath.IsEmpty() ) + normalizedPath = libPath; + + try + { + if( saveInGlobalTable ) + { + auto row = new FP_LIB_TABLE_ROW( libName, normalizedPath, type, wxEmptyString ); + GFootprintTable.InsertRow( row ); + GFootprintTable.Save( FP_LIB_TABLE::GetGlobalTableFileName() ); + } + else if( saveInProjectTable ) + { + auto row = new FP_LIB_TABLE_ROW( libName, normalizedPath, type, wxEmptyString ); + Prj().PcbFootprintLibs()->InsertRow( row ); + Prj().PcbFootprintLibs()->Save( Prj().FootprintLibTblName() ); + } + } + catch( const IO_ERROR& ioe ) + { + DisplayError( this, ioe.What() ); + return false; + } + + auto editor = (FOOTPRINT_EDIT_FRAME*) Kiway().Player( FRAME_PCB_MODULE_EDITOR, false ); + + if( editor ) + editor->SyncLibraryTree( true ); + + auto viewer = (FOOTPRINT_VIEWER_FRAME*) Kiway().Player( FRAME_PCB_MODULE_VIEWER, false ); + + if( viewer ) + viewer->ReCreateLibraryList(); + + return true; +} + + bool FOOTPRINT_EDIT_FRAME::DeleteModuleFromLibrary( const LIB_ID& aFPID, bool aConfirm ) { if( !aFPID.IsValid() ) @@ -647,25 +696,6 @@ void PCB_EDIT_FRAME::ArchiveModulesOnBoard( bool aStoreInNewLib, const wxString& } -class LIBRARY_NAME_CLEARER -{ - MODULE* m_module; - LIB_ID m_savedFPID; - -public: - LIBRARY_NAME_CLEARER( MODULE* aModule ) - { - m_module = aModule; - m_savedFPID = aModule->GetFPID(); - m_module->SetFPID( LIB_ID( wxEmptyString, m_savedFPID.GetLibItemName() ) ); - } - ~LIBRARY_NAME_CLEARER() - { - m_module->SetFPID( m_savedFPID ); - } -}; - - bool FOOTPRINT_EDIT_FRAME::SaveFootprint( MODULE* aModule ) { wxString libraryName = aModule->GetFPID().GetLibNickname(); @@ -704,23 +734,8 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprint( MODULE* aModule ) DeleteModuleFromLibrary( oldFPID, false ); } - try - { - MODULE* m = tbl->FootprintLoad( libraryName, footprintName ); - - delete m; - - LIBRARY_NAME_CLEARER temp( aModule ); - - // this always overwrites any existing footprint, but should yell on its - // own if the library or footprint is not writable. - tbl->FootprintSave( libraryName, aModule ); - } - catch( const IO_ERROR& ioe ) - { - DisplayError( this, ioe.What() ); + if( !saveFootprintInLibrary( aModule, libraryName ) ) return false; - } if( nameChanged ) { @@ -732,6 +747,27 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprint( MODULE* aModule ) } +bool FOOTPRINT_EDIT_FRAME::saveFootprintInLibrary( MODULE* aModule, const wxString& aLibraryName ) +{ + try + { + aModule->SetFPID( LIB_ID( wxEmptyString, aModule->GetFPID().GetLibItemName() ) ); + + Prj().PcbFootprintLibs()->FootprintSave( aLibraryName, aModule ); + + aModule->SetFPID( LIB_ID( aLibraryName, aModule->GetFPID().GetLibItemName() ) ); + return true; + } + catch( const IO_ERROR& ioe ) + { + DisplayError( this, ioe.What() ); + + aModule->SetFPID( LIB_ID( aLibraryName, aModule->GetFPID().GetLibItemName() ) ); + return false; + } +} + + bool FOOTPRINT_EDIT_FRAME::SaveFootprintToBoard( bool aAddNew ) { // update module in the current board, @@ -910,26 +946,10 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprintAs( MODULE* aModule ) return false; } - bool module_exists = false; + bool module_exists = tbl->FootprintExists( libraryName, footprintName ); - try - { - MODULE* m = tbl->FootprintLoad( libraryName, footprintName ); - - module_exists = m != nullptr; - delete m; - - LIBRARY_NAME_CLEARER temp( aModule ); - - // this always overwrites any existing footprint, but should yell on its - // own if the library or footprint is not writable. - tbl->FootprintSave( libraryName, aModule ); - } - catch( const IO_ERROR& ioe ) - { - DisplayError( this, ioe.What() ); + if( !saveFootprintInLibrary( aModule, libraryName ) ) return false; - } m_footprintNameWhenLoaded = footprintName; @@ -940,10 +960,42 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprintAs( MODULE* aModule ) SetStatusText( msg ); updateTitle(); + SyncLibraryTree( true ); + return true; } +bool FOOTPRINT_EDIT_FRAME::RevertFootprint() +{ + if( GetScreen()->IsModify() && m_revertModule ) + { + wxString msg = wxString::Format( _( "Revert \"%s\" to last version saved?" ), + GetChars( GetLoadedFPID().GetLibItemName() ) ); + + if( ConfirmRevertDialog( this, msg ) ) + { + Clear_Pcb( false ); + AddModuleToBoard( (MODULE*) m_revertModule->Clone() ); + + Zoom_Automatique( false ); + + Update3DView(); + + GetScreen()->ClearUndoRedoList(); + GetScreen()->ClrModify(); + + updateView(); + m_canvas->Refresh(); + + return true; + } + } + + return false; +} + + MODULE* PCB_BASE_FRAME::CreateNewModule( const wxString& aModuleName ) { // Creates a new footprint at position 0,0 which contains the minimal items: diff --git a/pcbnew/footprint_tree_pane.cpp b/pcbnew/footprint_tree_pane.cpp index b082ace66d..2b27f60b5c 100644 --- a/pcbnew/footprint_tree_pane.cpp +++ b/pcbnew/footprint_tree_pane.cpp @@ -50,29 +50,26 @@ FOOTPRINT_TREE_PANE::FOOTPRINT_TREE_PANE( FOOTPRINT_EDIT_FRAME* aParent ) AddMenuItem( menuLibrary.get(), ID_MODEDIT_CREATE_NEW_LIB, _( "&New Library..." ), KiBitmap( new_library_xpm ) ); -/* TODO - AddMenuItem( menuLibrary.get(), ID_LIBEDIT_ADD_LIBRARY, _( "&Add Library..." ), + + AddMenuItem( menuLibrary.get(), ID_MODEDIT_ADD_LIBRARY, _( "&Add Library..." ), KiBitmap( add_library_xpm ) ); -*/ + AddMenuItem( menuLibrary.get(), ID_MODEDIT_SAVE, _( "&Save" ), KiBitmap( save_xpm ) ); AddMenuItem( menuLibrary.get(), ID_MODEDIT_SAVE_AS, _( "Save a Copy &As..." ), KiBitmap( save_as_xpm ) ); -/* TODO - AddMenuItem( menuLibrary.get(), ID_LIBEDIT_REVERT, _( "Revert" ), - KiBitmap( undo_xpm ) ); -*/ menuLibrary->AppendSeparator(); AddMenuItem( menuLibrary.get(), ID_MODEDIT_NEW_MODULE, _( "&New Footprint..." ), KiBitmap( new_component_xpm ) ); #ifdef KICAD_SCRIPTING - AddMenuItem( menuLibrary.get(), ID_MODEDIT_NEW_MODULE_FROM_WIZARD, - _( "&Create Footprint from Wizard..." ), + AddMenuItem( menuLibrary.get(), ID_MODEDIT_NEW_MODULE_FROM_WIZARD, _( "&Create Footprint from Wizard..." ), KiBitmap( new_component_xpm ) ); #endif AddMenuItem( menuLibrary.get(), ID_MODEDIT_IMPORT_PART, _( "&Import Footprint..." ), KiBitmap( import_part_xpm ) ); + AddMenuItem( menuLibrary.get(), ID_MODEDIT_PASTE_PART, _( "Paste Footprint" ), + KiBitmap( paste_xpm ) ); std::unique_ptr menuPart = std::make_unique(); AddMenuItem( menuPart.get(), ID_MODEDIT_EDIT_MODULE, _( "&Edit Footprint" ), @@ -85,10 +82,14 @@ FOOTPRINT_TREE_PANE::FOOTPRINT_TREE_PANE( FOOTPRINT_EDIT_FRAME* aParent ) KiBitmap( save_xpm ) ); AddMenuItem( menuPart.get(), ID_MODEDIT_DELETE_PART, _( "&Delete" ), KiBitmap( delete_xpm ) ); -/* TODO - AddMenuItem( menuPart.get(), ID_LIBEDIT_REVERT, _( "Revert" ), + AddMenuItem( menuPart.get(), ID_MODEDIT_REVERT_PART, _( "Revert" ), KiBitmap( undo_xpm ) ); -*/ + + menuPart->AppendSeparator(); + AddMenuItem( menuPart.get(), ID_MODEDIT_CUT_PART, _( "Cut" ), + KiBitmap( cut_xpm ) ); + AddMenuItem( menuPart.get(), ID_MODEDIT_COPY_PART, _( "Copy" ), + KiBitmap( copy_xpm ) ); menuPart->AppendSeparator(); AddMenuItem( menuPart.get(), ID_MODEDIT_EXPORT_PART, _( "E&xport Footprint..." ), @@ -98,10 +99,10 @@ FOOTPRINT_TREE_PANE::FOOTPRINT_TREE_PANE( FOOTPRINT_EDIT_FRAME* aParent ) std::unique_ptr menuNoSelection = std::make_unique(); AddMenuItem( menuNoSelection.get(), ID_MODEDIT_CREATE_NEW_LIB, _( "&New Library..." ), KiBitmap( new_library_xpm ) ); -/* TODO - AddMenuItem( menuNoSelection.get(), ID_LIBEDIT_ADD_LIBRARY, _( "&Add Library..." ), + + AddMenuItem( menuNoSelection.get(), ID_MODEDIT_ADD_LIBRARY, _( "&Add Library..." ), KiBitmap( add_library_xpm ) ); -*/ + m_tree->SetMenu( LIB_TREE_NODE::LIBID, std::move( menuPart ) ); m_tree->SetMenu( LIB_TREE_NODE::LIB, std::move( menuLibrary ) ); m_tree->SetMenu( LIB_TREE_NODE::INVALID, std::move( menuNoSelection ) ); diff --git a/pcbnew/menubar_footprint_editor.cpp b/pcbnew/menubar_footprint_editor.cpp index bf26bf547c..36b9ae51e9 100644 --- a/pcbnew/menubar_footprint_editor.cpp +++ b/pcbnew/menubar_footprint_editor.cpp @@ -58,13 +58,13 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar() _( "New Library..." ), _( "Creates an empty library" ), KiBitmap( new_library_xpm ) ); -/* TODO + AddMenuItem( fileMenu, ID_MODEDIT_ADD_LIBRARY, _( "Add Library..." ), _( "Adds a previously created library" ), KiBitmap( add_library_xpm ) ); -*/ + text = AddHotkeyName( _( "&New Footprint..." ), m_hotkeysDescrList, HK_NEW ); AddMenuItem( fileMenu, ID_MODEDIT_NEW_MODULE, text, _( "Create a new footprint" ), @@ -89,6 +89,11 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar() _( "Save a copy to a new name and/or location" ), KiBitmap( save_as_xpm ) ); + AddMenuItem( fileMenu, ID_MODEDIT_REVERT_PART, + _( "&Revert" ), + _( "Throw away changes" ), + KiBitmap( undo_xpm ) ); + fileMenu->AppendSeparator(); AddMenuItem( fileMenu, ID_MODEDIT_IMPORT_PART, diff --git a/pcbnew/pcb_base_edit_frame.h b/pcbnew/pcb_base_edit_frame.h index 2124e93edb..a564cd368a 100644 --- a/pcbnew/pcb_base_edit_frame.h +++ b/pcbnew/pcb_base_edit_frame.h @@ -60,6 +60,14 @@ public: */ wxString CreateNewLibrary(const wxString& aLibName = wxEmptyString); + /** + * Function AddLibrary + * Add an existing library to either the global or project library table. + * @param aFileName the library to add; a file open dialog will be displayed if empty. + * @return true if successfully added + */ + bool AddLibrary(const wxString& aLibName = wxEmptyString); + /** * Function OnEditItemRequest * Install the corresponding dialog editor for the given item diff --git a/pcbnew/pcbnew_id.h b/pcbnew/pcbnew_id.h index 192c5962c8..33069f4385 100644 --- a/pcbnew/pcbnew_id.h +++ b/pcbnew/pcbnew_id.h @@ -347,9 +347,14 @@ enum pcbnew_ids ID_POPUP_MODEDIT_EDIT_EDGE, ID_MODEDIT_CHECK, ID_MODEDIT_CREATE_NEW_LIB, + ID_MODEDIT_ADD_LIBRARY, ID_MODEDIT_SAVE, ID_MODEDIT_SAVE_AS, + ID_MODEDIT_REVERT_PART, ID_MODEDIT_DELETE_PART, + ID_MODEDIT_COPY_PART, + ID_MODEDIT_CUT_PART, + ID_MODEDIT_PASTE_PART, ID_MODEDIT_NEW_MODULE, ID_MODEDIT_NEW_MODULE_FROM_WIZARD, ID_MODEDIT_SHEET_SET,