Convert Footprint Editor to component tree.

Fixes: lp:1784178
* https://bugs.launchpad.net/kicad/+bug/1784178

Fixes: lp:1780363
* https://bugs.launchpad.net/kicad/+bug/1780363
This commit is contained in:
Jeff Young 2018-07-29 16:33:58 +01:00
parent b400565880
commit 0a35c5c97e
28 changed files with 948 additions and 1117 deletions

View File

@ -154,6 +154,12 @@ void LIB_TREE::SelectLibId( const LIB_ID& aLibId )
} }
void LIB_TREE::CenterLibId( const LIB_ID& aLibId )
{
centerIfValid( m_adapter->FindItem( aLibId ) );
}
void LIB_TREE::Unselect() void LIB_TREE::Unselect()
{ {
m_tree_ctrl->UnselectAll(); m_tree_ctrl->UnselectAll();
@ -211,6 +217,14 @@ void LIB_TREE::selectIfValid( const wxDataViewItem& aTreeId )
} }
void LIB_TREE::centerIfValid( const wxDataViewItem& aTreeId )
{
if( aTreeId.IsOk() )
m_tree_ctrl->EnsureVisible( aTreeId );
}
void LIB_TREE::postPreselectEvent() void LIB_TREE::postPreselectEvent()
{ {
wxCommandEvent event( COMPONENT_PRESELECTED ); wxCommandEvent event( COMPONENT_PRESELECTED );

View File

@ -70,12 +70,15 @@ public:
LIB_ID GetSelectedLibId( int* aUnit = nullptr ) const; LIB_ID GetSelectedLibId( int* aUnit = nullptr ) const;
/** /**
* Select a part in the tree widget. * Select an item in the tree widget.
*
* @param aLibId is the identifier of part to be selected.
*/ */
void SelectLibId( const LIB_ID& aLibId ); void SelectLibId( const LIB_ID& aLibId );
/**
* Ensure that an item is visible (preferrably centered).
*/
void CenterLibId( const LIB_ID& aLibId );
/** /**
* Unselect currently selected item in wxDataViewCtrl * Unselect currently selected item in wxDataViewCtrl
*/ */
@ -118,6 +121,8 @@ protected:
*/ */
void selectIfValid( const wxDataViewItem& aTreeId ); void selectIfValid( const wxDataViewItem& aTreeId );
void centerIfValid( const wxDataViewItem& aTreeId );
/** /**
* Post a wxEVT_DATAVIEW_SELECTION_CHANGED to notify the selection handler * Post a wxEVT_DATAVIEW_SELECTION_CHANGED to notify the selection handler
* that a new part has been preselected. * that a new part has been preselected.
@ -157,6 +162,7 @@ protected:
void onTreeSelect( wxDataViewEvent& aEvent ); void onTreeSelect( wxDataViewEvent& aEvent );
void onTreeActivate( wxDataViewEvent& aEvent ); void onTreeActivate( wxDataViewEvent& aEvent );
void onUpdateUI( wxUpdateUIEvent& aEvent );
void onDetailsLink( wxHtmlLinkEvent& aEvent ); void onDetailsLink( wxHtmlLinkEvent& aEvent );
void onPreselect( wxCommandEvent& aEvent ); void onPreselect( wxCommandEvent& aEvent );

View File

@ -309,7 +309,7 @@ bool LIB_EDIT_FRAME::GeneralControl( wxDC* aDC, const wxPoint& aPosition, EDA_KE
keyHandled = true; keyHandled = true;
} }
// Make sure current-part highlighting doesn't get lost in seleciton highlighting // Make sure current-part highlighting doesn't get lost in selection highlighting
ClearSearchTreeSelection(); ClearSearchTreeSelection();
UpdateStatusBar(); UpdateStatusBar();

View File

@ -1657,14 +1657,14 @@ SYMBOL_LIB_TABLE* LIB_EDIT_FRAME::selectSymLibTable()
libTableNames.Add( _( "Global" ) ); libTableNames.Add( _( "Global" ) );
libTableNames.Add( _( "Project" ) ); libTableNames.Add( _( "Project" ) );
switch( SelectSingleOption( this, _( "Select Symbol Library Table" ), switch( SelectSingleOption( this, _( "Select Library Table" ),
_( "Choose the Library Table to add the library:" ), libTableNames ) ) _( "Choose the Library Table to add the library to:" ),
libTableNames ) )
{ {
case 0: return &SYMBOL_LIB_TABLE::GetGlobalLibTable(); case 0: return &SYMBOL_LIB_TABLE::GetGlobalLibTable();
case 1: return Prj().SchSymbolLibTable(); case 1: return Prj().SchSymbolLibTable();
default: return nullptr;
} }
return nullptr;
} }

View File

@ -273,12 +273,12 @@ void SCH_BASE_FRAME::OnEditSymbolLibTable( wxCommandEvent& aEvent )
DIALOG_EDIT_LIBRARY_TABLES dlg( this, _( "Footprint Libraries" ) ); DIALOG_EDIT_LIBRARY_TABLES dlg( this, _( "Footprint Libraries" ) );
dlg.InstallPanel( new PANEL_SYM_LIB_TABLE( &dlg, &SYMBOL_LIB_TABLE::GetGlobalLibTable(), dlg.InstallPanel( new PANEL_SYM_LIB_TABLE( &dlg, &SYMBOL_LIB_TABLE::GetGlobalLibTable(),
Prj().SchSymbolLibTable() ) ); Prj().SchSymbolLibTable() ) );
if( dlg.ShowModal() == wxID_CANCEL ) if( dlg.ShowModal() == wxID_CANCEL )
return; return;
saveSymbolLibTables( true, true ); saveSymbolLibTables( dlg.m_GlobalTableChanged, dlg.m_ProjectTableChanged );
LIB_EDIT_FRAME* editor = (LIB_EDIT_FRAME*) Kiway().Player( FRAME_SCH_LIB_EDITOR, false ); LIB_EDIT_FRAME* editor = (LIB_EDIT_FRAME*) Kiway().Player( FRAME_SCH_LIB_EDITOR, false );

View File

@ -130,8 +130,6 @@ set( PCBNEW_DIALOGS
dialogs/dialog_print_using_printer_base.cpp dialogs/dialog_print_using_printer_base.cpp
dialogs/dialog_select_net_from_list.cpp dialogs/dialog_select_net_from_list.cpp
dialogs/dialog_select_net_from_list_base.cpp dialogs/dialog_select_net_from_list_base.cpp
dialogs/dialog_select_pretty_lib.cpp
dialogs/dialog_select_pretty_lib_base.cpp
dialogs/dialog_set_grid.cpp dialogs/dialog_set_grid.cpp
dialogs/dialog_set_grid_base.cpp dialogs/dialog_set_grid_base.cpp
dialogs/dialog_swap_layers.cpp dialogs/dialog_swap_layers.cpp
@ -240,6 +238,7 @@ set( PCBNEW_CLASS_SRCS
footprint_editor_utils.cpp footprint_editor_utils.cpp
footprint_editor_onclick.cpp footprint_editor_onclick.cpp
footprint_editor_options.cpp footprint_editor_options.cpp
fp_tree_synchronizing_adapter.cpp
footprint_edit_frame.cpp footprint_edit_frame.cpp
footprint_libraries_utils.cpp footprint_libraries_utils.cpp
footprint_viewer_frame.cpp footprint_viewer_frame.cpp
@ -326,6 +325,7 @@ set( PCBNEW_CLASS_SRCS
tools/zone_filler_tool.cpp tools/zone_filler_tool.cpp
footprint_preview_panel.cpp footprint_preview_panel.cpp
footprint_tree_pane.cpp
) )
set( PCBNEW_SRCS set( PCBNEW_SRCS

View File

@ -1,76 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2015 KiCad Developers, see change_log.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 dialog_select_pretty_lib.cpp
* @brief A dialog to select/create a .pretty folder which is a
* footprint library.
* footprints are .kicad_mod files inside this folder
*/
#include <wildcards_and_files_ext.h>
#include <dialog_select_pretty_lib.h>
#include <project.h>
DIALOG_SELECT_PRETTY_LIB::DIALOG_SELECT_PRETTY_LIB( wxWindow* parent,
const wxString& aDefaultPath ) :
DIALOG_SELECT_PRETTY_LIB_BASE( parent )
{
if( !aDefaultPath.IsEmpty() )
m_dirCtrl->SetPath( aDefaultPath );
m_sdbSizerOK->SetDefault();
// Now all widgets have the size fixed, call FinishDialogSettings
FinishDialogSettings();
}
void DIALOG_SELECT_PRETTY_LIB::OnSelectFolder( wxFileDirPickerEvent& event )
{
m_libName->SetValue( m_dirCtrl->GetPath() );
event.Skip();
}
const wxString DIALOG_SELECT_PRETTY_LIB::GetFullPrettyLibName()
{
wxFileName fn = m_libName->GetValue();
if( !fn.IsAbsolute() )
fn.MakeAbsolute( m_dirCtrl->GetPath() );
// Enforce the extension:
fn.SetExt( KiCadFootprintLibPathExtension );
return fn.GetFullPath();
}
void DIALOG_SELECT_PRETTY_LIB::OnOKButton( wxCommandEvent& event )
{
event.Skip();
}

View File

@ -1,58 +0,0 @@
#ifndef __DIALOG_SELECT_PRETTY_LIB_H__
#define __DIALOG_SELECT_PRETTY_LIB_H__
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2014 KiCad Developers, see change_log.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 dialog_select_pretty_lib.h
* @brief A dialog to select/create a .pretty folder which is a
* footprint library.
* footprints are .kicad_mod files inside this folder
*/
#include <dialog_select_pretty_lib_base.h>
class DIALOG_SELECT_PRETTY_LIB : public DIALOG_SELECT_PRETTY_LIB_BASE
{
public:
DIALOG_SELECT_PRETTY_LIB( wxWindow* parent,
const wxString& aDefaultPath );
~DIALOG_SELECT_PRETTY_LIB() {};
/**
* @return the full .pretty lib name, which is an absolute path
*, ending wityh ".pretty"
*/
const wxString GetFullPrettyLibName();
private:
virtual void OnSelectFolder( wxFileDirPickerEvent& event ) override;
virtual void OnOKButton( wxCommandEvent& event ) override;
};
#endif //__DIALOG_SELECT_PRETTY_LIB_BASE_H__

View File

@ -1,74 +0,0 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Apr 19 2018)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "dialog_select_pretty_lib_base.h"
///////////////////////////////////////////////////////////////////////////
DIALOG_SELECT_PRETTY_LIB_BASE::DIALOG_SELECT_PRETTY_LIB_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
wxBoxSizer* bSizerMain;
bSizerMain = new wxBoxSizer( wxVERTICAL );
m_messageInfo = new wxStaticText( this, wxID_ANY, _("The footprint library is a folder with a name ending with .pretty\nFootprints are .kicad_mod files inside this folder."), wxDefaultPosition, wxDefaultSize, 0 );
m_messageInfo->Wrap( -1 );
m_messageInfo->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) );
bSizerMain->Add( m_messageInfo, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
m_staticText3 = new wxStaticText( this, wxID_ANY, _("Path base:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText3->Wrap( -1 );
bSizerMain->Add( m_staticText3, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_dirCtrl = new wxDirPickerCtrl( this, wxID_ANY, wxEmptyString, _("Select a folder"), wxDefaultPosition, wxDefaultSize, wxDIRP_DEFAULT_STYLE );
bSizerMain->Add( m_dirCtrl, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_SizerNewLibName = new wxBoxSizer( wxVERTICAL );
m_staticTextDirname = new wxStaticText( this, wxID_ANY, _("Library folder (.pretty will be added to name, if missing):"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextDirname->Wrap( -1 );
m_SizerNewLibName->Add( m_staticTextDirname, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_libName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_SizerNewLibName->Add( m_libName, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
bSizerMain->Add( m_SizerNewLibName, 0, wxEXPAND, 5 );
m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
bSizerMain->Add( m_staticline1, 0, wxEXPAND, 5 );
m_sdbSizer = new wxStdDialogButtonSizer();
m_sdbSizerOK = new wxButton( this, wxID_OK );
m_sdbSizer->AddButton( m_sdbSizerOK );
m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
m_sdbSizer->AddButton( m_sdbSizerCancel );
m_sdbSizer->Realize();
bSizerMain->Add( m_sdbSizer, 0, wxALL|wxEXPAND, 5 );
this->SetSizer( bSizerMain );
this->Layout();
bSizerMain->Fit( this );
this->Centre( wxBOTH );
// Connect Events
m_dirCtrl->Connect( wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler( DIALOG_SELECT_PRETTY_LIB_BASE::OnSelectFolder ), NULL, this );
m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SELECT_PRETTY_LIB_BASE::OnOKButton ), NULL, this );
}
DIALOG_SELECT_PRETTY_LIB_BASE::~DIALOG_SELECT_PRETTY_LIB_BASE()
{
// Disconnect Events
m_dirCtrl->Disconnect( wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler( DIALOG_SELECT_PRETTY_LIB_BASE::OnSelectFolder ), NULL, this );
m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SELECT_PRETTY_LIB_BASE::OnOKButton ), NULL, this );
}

View File

@ -1,646 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<wxFormBuilder_Project>
<FileVersion major="1" minor="13" />
<object class="Project" expanded="1">
<property name="class_decoration"></property>
<property name="code_generation">C++</property>
<property name="disconnect_events">1</property>
<property name="disconnect_mode">source_name</property>
<property name="disconnect_php_events">0</property>
<property name="disconnect_python_events">0</property>
<property name="embedded_files_path">res</property>
<property name="encoding">UTF-8</property>
<property name="event_generation">connect</property>
<property name="file">dialog_select_pretty_lib_base</property>
<property name="first_id">1000</property>
<property name="help_provider">none</property>
<property name="indent_with_spaces"></property>
<property name="internationalize">1</property>
<property name="name">dialog_select_pretty_lib_base</property>
<property name="namespace"></property>
<property name="path">.</property>
<property name="precompiled_header"></property>
<property name="relative_path">1</property>
<property name="skip_lua_events">1</property>
<property name="skip_php_events">1</property>
<property name="skip_python_events">1</property>
<property name="ui_table">UI</property>
<property name="use_enum">0</property>
<property name="use_microsoft_bom">0</property>
<object class="Dialog" expanded="1">
<property name="aui_managed">0</property>
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
<property name="bg"></property>
<property name="center">wxBOTH</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="enabled">1</property>
<property name="event_handler">impl_virtual</property>
<property name="extra_style"></property>
<property name="fg"></property>
<property name="font"></property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="maximum_size"></property>
<property name="minimum_size">-1,-1</property>
<property name="name">DIALOG_SELECT_PRETTY_LIB_BASE</property>
<property name="pos"></property>
<property name="size">-1,-1</property>
<property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
<property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
<property name="title">Select Footprint Library Folder</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnActivate"></event>
<event name="OnActivateApp"></event>
<event name="OnAuiFindManager"></event>
<event name="OnAuiPaneButton"></event>
<event name="OnAuiPaneClose"></event>
<event name="OnAuiPaneMaximize"></event>
<event name="OnAuiPaneRestore"></event>
<event name="OnAuiRender"></event>
<event name="OnChar"></event>
<event name="OnClose"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnHibernate"></event>
<event name="OnIconize"></event>
<event name="OnIdle"></event>
<event name="OnInitDialog"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizerMain</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL|wxALIGN_CENTER_HORIZONTAL</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font">,90,92,-1,70,0</property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">The footprint library is a folder with a name ending with .pretty&#x0A;Footprints are .kicad_mod files inside this folder.</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_messageInfo</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Path base:</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_staticText3</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxDirPickerCtrl" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="message">Select a folder</property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_dirCtrl</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style">wxDIRP_DEFAULT_STYLE</property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="value"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnDirChanged">OnSelectFolder</event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">m_SizerNewLibName</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">protected</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Library folder (.pretty will be added to name, if missing):</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_staticTextDirname</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxTextCtrl" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="maxlength">0</property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_libName</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="value"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnText"></event>
<event name="OnTextEnter"></event>
<event name="OnTextMaxLen"></event>
<event name="OnTextURL"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxStaticLine" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_staticline1</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style">wxLI_HORIZONTAL</property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxStdDialogButtonSizer" expanded="1">
<property name="Apply">0</property>
<property name="Cancel">1</property>
<property name="ContextHelp">0</property>
<property name="Help">0</property>
<property name="No">0</property>
<property name="OK">1</property>
<property name="Save">0</property>
<property name="Yes">0</property>
<property name="minimum_size"></property>
<property name="name">m_sdbSizer</property>
<property name="permission">protected</property>
<event name="OnApplyButtonClick"></event>
<event name="OnCancelButtonClick"></event>
<event name="OnContextHelpButtonClick"></event>
<event name="OnHelpButtonClick"></event>
<event name="OnNoButtonClick"></event>
<event name="OnOKButtonClick">OnOKButton</event>
<event name="OnSaveButtonClick"></event>
<event name="OnYesButtonClick"></event>
</object>
</object>
</object>
</object>
</object>
</wxFormBuilder_Project>

View File

@ -1,62 +0,0 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Apr 19 2018)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#ifndef __DIALOG_SELECT_PRETTY_LIB_BASE_H__
#define __DIALOG_SELECT_PRETTY_LIB_BASE_H__
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
#include "dialog_shim.h"
#include <wx/string.h>
#include <wx/stattext.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/filepicker.h>
#include <wx/textctrl.h>
#include <wx/sizer.h>
#include <wx/statline.h>
#include <wx/button.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class DIALOG_SELECT_PRETTY_LIB_BASE
///////////////////////////////////////////////////////////////////////////////
class DIALOG_SELECT_PRETTY_LIB_BASE : public DIALOG_SHIM
{
private:
protected:
wxStaticText* m_messageInfo;
wxStaticText* m_staticText3;
wxDirPickerCtrl* m_dirCtrl;
wxBoxSizer* m_SizerNewLibName;
wxStaticText* m_staticTextDirname;
wxTextCtrl* m_libName;
wxStaticLine* m_staticline1;
wxStdDialogButtonSizer* m_sdbSizer;
wxButton* m_sdbSizerOK;
wxButton* m_sdbSizerCancel;
// Virtual event handlers, overide them in your derived class
virtual void OnSelectFolder( wxFileDirPickerEvent& event ) { event.Skip(); }
virtual void OnOKButton( wxCommandEvent& event ) { event.Skip(); }
public:
DIALOG_SELECT_PRETTY_LIB_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Select Footprint Library Folder"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_SELECT_PRETTY_LIB_BASE();
};
#endif //__DIALOG_SELECT_PRETTY_LIB_BASE_H__

View File

@ -774,7 +774,17 @@ int InvokePcbLibTableEditor( wxTopLevelWindow* aCaller, FP_LIB_TABLE* aGlobalTab
dlg.InstallPanel( new PANEL_FP_LIB_TABLE( &dlg, aGlobalTable, aProjectTable ) ); dlg.InstallPanel( new PANEL_FP_LIB_TABLE( &dlg, aGlobalTable, aProjectTable ) );
return dlg.ShowModal(); int ret = 0;
if( dlg.ShowModal() != wxID_CANCEL )
{
if( dlg.m_GlobalTableChanged )
ret += 1;
if( dlg.m_ProjectTableChanged )
ret += 2;
}
return ret;
} }

View File

@ -58,6 +58,11 @@
#include <tool/tool_dispatcher.h> #include <tool/tool_dispatcher.h>
#include <tool/zoom_tool.h> #include <tool/zoom_tool.h>
#include <footprint_tree_pane.h>
#include <widgets/lib_tree.h>
#include <fp_lib_table.h>
#include <footprint_info_impl.h>
#include <widgets/paged_dialog.h> #include <widgets/paged_dialog.h>
#include <dialogs/panel_modedit_settings.h> #include <dialogs/panel_modedit_settings.h>
#include <dialogs/panel_modedit_defaults.h> #include <dialogs/panel_modedit_defaults.h>
@ -65,6 +70,7 @@
#include <dialog_configure_paths.h> #include <dialog_configure_paths.h>
#include <tools/position_relative_tool.h> #include <tools/position_relative_tool.h>
#include <widgets/progress_reporter.h>
#include "tools/selection_tool.h" #include "tools/selection_tool.h"
#include "tools/edit_tool.h" #include "tools/edit_tool.h"
#include "tools/drawing_tool.h" #include "tools/drawing_tool.h"
@ -88,10 +94,8 @@ BEGIN_EVENT_TABLE( FOOTPRINT_EDIT_FRAME, PCB_BASE_FRAME )
EVT_CHOICE( ID_ON_ZOOM_SELECT, FOOTPRINT_EDIT_FRAME::OnSelectZoom ) EVT_CHOICE( ID_ON_ZOOM_SELECT, FOOTPRINT_EDIT_FRAME::OnSelectZoom )
EVT_CHOICE( ID_ON_GRID_SELECT, FOOTPRINT_EDIT_FRAME::OnSelectGrid ) EVT_CHOICE( ID_ON_GRID_SELECT, FOOTPRINT_EDIT_FRAME::OnSelectGrid )
EVT_TOOL( ID_MODEDIT_SAVE_LIBRARY_AS, FOOTPRINT_EDIT_FRAME::OnSaveLibraryAs ) 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_SAVE_LIBMODULE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
EVT_TOOL( ID_MODEDIT_SAVE_LIBMODULE_AS, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
EVT_TOOL( ID_OPEN_MODULE_VIEWER, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) EVT_TOOL( ID_OPEN_MODULE_VIEWER, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
EVT_TOOL( ID_MODEDIT_DELETE_PART, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) EVT_TOOL( ID_MODEDIT_DELETE_PART, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
@ -103,7 +107,7 @@ BEGIN_EVENT_TABLE( FOOTPRINT_EDIT_FRAME, PCB_BASE_FRAME )
EVT_TOOL( ID_MODEDIT_SHEET_SET, 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( ID_GEN_IMPORT_DXF_FILE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
EVT_TOOL( wxID_PRINT, FOOTPRINT_EDIT_FRAME::ToPrinter ) EVT_TOOL( wxID_PRINT, FOOTPRINT_EDIT_FRAME::ToPrinter )
EVT_TOOL( ID_MODEDIT_LOAD_MODULE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions ) EVT_TOOL( ID_MODEDIT_EDIT_MODULE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
EVT_TOOL( ID_MODEDIT_CHECK, 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_PAD_SETTINGS, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
EVT_TOOL( ID_MODEDIT_LOAD_MODULE_FROM_BOARD, FOOTPRINT_EDIT_FRAME::LoadModuleFromBoard ) EVT_TOOL( ID_MODEDIT_LOAD_MODULE_FROM_BOARD, FOOTPRINT_EDIT_FRAME::LoadModuleFromBoard )
@ -170,10 +174,10 @@ BEGIN_EVENT_TABLE( FOOTPRINT_EDIT_FRAME, PCB_BASE_FRAME )
EVT_MENU( ID_MENU_CANVAS_OPENGL, PCB_BASE_FRAME::OnSwitchCanvas ) EVT_MENU( ID_MENU_CANVAS_OPENGL, PCB_BASE_FRAME::OnSwitchCanvas )
// UI update events. // UI update events.
EVT_UPDATE_UI( ID_MODEDIT_EXPORT_PART, FOOTPRINT_EDIT_FRAME::OnUpdateModuleSelected ) EVT_UPDATE_UI( ID_MODEDIT_EXPORT_PART, FOOTPRINT_EDIT_FRAME::OnUpdateModuleTargeted )
EVT_UPDATE_UI( ID_MODEDIT_SAVE_LIBMODULE, FOOTPRINT_EDIT_FRAME::OnUpdateModuleSelected ) EVT_UPDATE_UI( ID_MODEDIT_SAVE, FOOTPRINT_EDIT_FRAME::OnUpdateSave )
EVT_UPDATE_UI( ID_MODEDIT_SAVE_LIBMODULE_AS, FOOTPRINT_EDIT_FRAME::OnUpdateModuleSelected ) EVT_UPDATE_UI( ID_MODEDIT_SAVE_AS, FOOTPRINT_EDIT_FRAME::OnUpdateSaveAs )
EVT_UPDATE_UI( ID_MODEDIT_SAVE_LIBRARY_AS, FOOTPRINT_EDIT_FRAME::OnUpdateModuleSelected ) EVT_UPDATE_UI( ID_MODEDIT_DELETE_PART, FOOTPRINT_EDIT_FRAME::OnUpdateModuleTargeted )
EVT_UPDATE_UI( ID_MODEDIT_LOAD_MODULE_FROM_BOARD, EVT_UPDATE_UI( ID_MODEDIT_LOAD_MODULE_FROM_BOARD,
FOOTPRINT_EDIT_FRAME::OnUpdateLoadModuleFromBoard ) FOOTPRINT_EDIT_FRAME::OnUpdateLoadModuleFromBoard )
EVT_UPDATE_UI( ID_MODEDIT_INSERT_MODULE_IN_BOARD, EVT_UPDATE_UI( ID_MODEDIT_INSERT_MODULE_IN_BOARD,
@ -186,12 +190,14 @@ BEGIN_EVENT_TABLE( FOOTPRINT_EDIT_FRAME, PCB_BASE_FRAME )
EVT_UPDATE_UI_RANGE( ID_MODEDIT_PAD_TOOL, ID_MODEDIT_MEASUREMENT_TOOL, EVT_UPDATE_UI_RANGE( ID_MODEDIT_PAD_TOOL, ID_MODEDIT_MEASUREMENT_TOOL,
FOOTPRINT_EDIT_FRAME::OnUpdateVerticalToolbar ) FOOTPRINT_EDIT_FRAME::OnUpdateVerticalToolbar )
EVT_UPDATE_UI( ID_MODEDIT_EDIT_MODULE_PROPERTIES, FOOTPRINT_EDIT_FRAME::OnUpdateModuleSelected )
EVT_UPDATE_UI( ID_MODEDIT_PAD_SETTINGS, FOOTPRINT_EDIT_FRAME::OnUpdateModuleSelected )
// Option toolbar: // Option toolbar:
EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_HIGH_CONTRAST_MODE, EVT_UPDATE_UI( ID_TB_OPTIONS_SHOW_HIGH_CONTRAST_MODE,
FOOTPRINT_EDIT_FRAME::OnUpdateOptionsToolbar ) FOOTPRINT_EDIT_FRAME::OnUpdateOptionsToolbar )
EVT_UPDATE_UI( ID_GEN_IMPORT_DXF_FILE, EVT_UPDATE_UI( ID_GEN_IMPORT_DXF_FILE, FOOTPRINT_EDIT_FRAME::OnUpdateModuleSelected )
FOOTPRINT_EDIT_FRAME::OnUpdateModuleSelected )
END_EVENT_TABLE() END_EVENT_TABLE()
@ -262,6 +268,10 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
SetPageSettings( PAGE_INFO( PAGE_INFO::A4 ) ); SetPageSettings( PAGE_INFO( PAGE_INFO::A4 ) );
SetSize( m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y ); SetSize( m_FramePos.x, m_FramePos.y, m_FrameSize.x, m_FrameSize.y );
initLibraryTree();
m_treePane = new FOOTPRINT_TREE_PANE( this );
ReCreateMenuBar(); ReCreateMenuBar();
ReCreateHToolbar(); ReCreateHToolbar();
ReCreateAuxiliaryToolbar(); ReCreateAuxiliaryToolbar();
@ -317,6 +327,9 @@ FOOTPRINT_EDIT_FRAME::FOOTPRINT_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
m_auimgr.AddPane( m_messagePanel, m_auimgr.AddPane( m_messagePanel,
wxAuiPaneInfo( mesg_pane ).Name( "MsgPanel" ).Bottom().Layer(10) ); wxAuiPaneInfo( mesg_pane ).Name( "MsgPanel" ).Bottom().Layer(10) );
m_auimgr.AddPane( m_treePane, wxAuiPaneInfo().Name( "FootprintTree" ).Left().Row( 1 )
.Resizable().MinSize( 250, 400 ).Dock().CloseButton( false ) );
// Create the manager and dispatcher & route draw panel events to the dispatcher // Create the manager and dispatcher & route draw panel events to the dispatcher
setupTools(); setupTools();
GetGalCanvas()->GetGAL()->SetAxesEnabled( true ); GetGalCanvas()->GetGAL()->SetAxesEnabled( true );
@ -360,36 +373,35 @@ BOARD_ITEM_CONTAINER* FOOTPRINT_EDIT_FRAME::GetModel() const
} }
const wxString FOOTPRINT_EDIT_FRAME::getLibPath() LIB_ID FOOTPRINT_EDIT_FRAME::getTargetLibId() const
{ {
try LIB_ID id = m_treePane->GetLibTree()->GetSelectedLibId();
{ wxString nickname = id.GetLibNickname();
const wxString& nickname = GetCurrentLib();
const FP_LIB_TABLE_ROW* row = Prj().PcbFootprintLibs()->FindRow( nickname ); if( nickname.IsEmpty() )
return GetCurrentLibId();
return row->GetFullURI( true ); return id;
}
catch( const IO_ERROR& )
{
return wxEmptyString;
}
} }
const wxString FOOTPRINT_EDIT_FRAME::GetCurrentLib() const LIB_ID FOOTPRINT_EDIT_FRAME::GetCurrentLibId() const
{ {
return Prj().GetRString( PROJECT::PCB_LIB_NICKNAME ); MODULE* module = GetBoard()->m_Modules;
if( module )
return module->GetFPID();
else
return LIB_ID();
} }
void FOOTPRINT_EDIT_FRAME::retainLastFootprint() void FOOTPRINT_EDIT_FRAME::retainLastFootprint()
{ {
MODULE* module = GetBoard()->m_Modules; LIB_ID id = GetCurrentLibId();
if( module ) if( id.IsValid() )
{ {
LIB_ID id = module->GetFPID();
Prj().SetRString( PROJECT::PCB_FOOTPRINT_EDITOR_NICKNAME, id.GetLibNickname() ); Prj().SetRString( PROJECT::PCB_FOOTPRINT_EDITOR_NICKNAME, id.GetLibNickname() );
Prj().SetRString( PROJECT::PCB_FOOTPRINT_EDITOR_FPNAME, id.GetLibItemName() ); Prj().SetRString( PROJECT::PCB_FOOTPRINT_EDITOR_FPNAME, id.GetLibItemName() );
} }
@ -509,6 +521,7 @@ void FOOTPRINT_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
switch( ii ) switch( ii )
{ {
default:
case wxID_NO: case wxID_NO:
break; break;
@ -584,6 +597,28 @@ void FOOTPRINT_EDIT_FRAME::OnUpdateModuleSelected( wxUpdateUIEvent& aEvent )
} }
void FOOTPRINT_EDIT_FRAME::OnUpdateModuleTargeted( wxUpdateUIEvent& aEvent )
{
aEvent.Enable( getTargetLibId().IsValid() );
}
void FOOTPRINT_EDIT_FRAME::OnUpdateSave( wxUpdateUIEvent& aEvent )
{
aEvent.Enable( GetBoard()->m_Modules && GetScreen()->IsModify() );
}
void FOOTPRINT_EDIT_FRAME::OnUpdateSaveAs( wxUpdateUIEvent& aEvent )
{
LIB_ID libId = getTargetLibId();
const wxString& libName = libId.GetLibNickname();
const wxString& partName = libId.GetLibItemName();
aEvent.Enable( !libName.IsEmpty() || !partName.IsEmpty() );
}
void FOOTPRINT_EDIT_FRAME::OnUpdateLoadModuleFromBoard( wxUpdateUIEvent& aEvent ) void FOOTPRINT_EDIT_FRAME::OnUpdateLoadModuleFromBoard( wxUpdateUIEvent& aEvent )
{ {
PCB_EDIT_FRAME* frame = (PCB_EDIT_FRAME*) Kiway().Player( FRAME_PCB, false ); PCB_EDIT_FRAME* frame = (PCB_EDIT_FRAME*) Kiway().Player( FRAME_PCB, false );
@ -691,35 +726,37 @@ void FOOTPRINT_EDIT_FRAME::OnModify()
{ {
PCB_BASE_FRAME::OnModify(); PCB_BASE_FRAME::OnModify();
Update3DView(); Update3DView();
m_treePane->GetLibTree()->Refresh();
} }
void FOOTPRINT_EDIT_FRAME::updateTitle() void FOOTPRINT_EDIT_FRAME::updateTitle()
{ {
wxString title = _( "Footprint Editor" ); wxString title = _( "Footprint Editor" );
MODULE* module = GetBoard()->m_Modules; LIB_ID fpid = GetCurrentLibId();
bool writable = true;
if( module ) if( fpid.IsValid() )
{ {
bool writable = true; try
const LIB_ID& fpid = module->GetFPID();
wxString nickname = fpid.GetLibNickname();
if( !nickname.IsEmpty() )
{ {
try writable = Prj().PcbFootprintLibs()->IsFootprintLibWritable( fpid.GetLibNickname() );
{ }
writable = Prj().PcbFootprintLibs()->IsFootprintLibWritable( nickname ); catch( const IO_ERROR& )
} {
catch( const IO_ERROR& ) // best efforts...
{
}
} }
title += wxString::Format( wxT( " \u2014 %s %s" ), title += wxString::Format( wxT( " \u2014 %s %s" ),
FROM_UTF8( module->GetFPID().Format().c_str() ), FROM_UTF8( fpid.Format().c_str() ),
writable ? wxString( wxEmptyString ) : _( "[Read Only]" ) ); writable ? wxString( wxEmptyString ) : _( "[Read Only]" ) );
} }
else if( !fpid.GetLibItemName().empty() )
{
title += wxString::Format( wxT( " \u2014 %s %s" ),
FROM_UTF8( fpid.GetLibItemName().c_str() ),
_( "[Unsaved]" ) );
}
SetTitle( title ); SetTitle( title );
} }
@ -736,6 +773,68 @@ void FOOTPRINT_EDIT_FRAME::updateView()
} }
void FOOTPRINT_EDIT_FRAME::initLibraryTree()
{
FP_LIB_TABLE* fpTable = Prj().PcbFootprintLibs();
WX_PROGRESS_REPORTER progressReporter( this, _( "Loading Footprint Libraries" ), 2 );
GFootprintList.ReadFootprintFiles( fpTable, NULL, &progressReporter );
progressReporter.Show( false );
if( GFootprintList.GetErrorCount() )
GFootprintList.DisplayErrors( this );
m_adapter = FP_TREE_SYNCHRONIZING_ADAPTER::Create( this, fpTable );
auto adapter = static_cast<FP_TREE_SYNCHRONIZING_ADAPTER*>( m_adapter.get() );
adapter->AddLibraries();
}
void FOOTPRINT_EDIT_FRAME::syncLibraryTree( bool aProgress )
{
FP_LIB_TABLE* fpTable = Prj().PcbFootprintLibs();
auto adapter = static_cast<FP_TREE_SYNCHRONIZING_ADAPTER*>( m_adapter.get() );
LIB_ID target = getTargetLibId();
bool targetSelected = ( target == m_treePane->GetLibTree()->GetSelectedLibId() );
// Sync FOOTPRINT_INFO list to the libraries on disk
if( aProgress )
{
WX_PROGRESS_REPORTER progressReporter( this, _( "Updating Footprint Libraries" ), 2 );
GFootprintList.ReadFootprintFiles( fpTable, NULL, &progressReporter );
progressReporter.Show( false );
}
else
{
GFootprintList.ReadFootprintFiles( fpTable, NULL, NULL );
}
// Sync the LIB_TREE to the FOOTPRINT_INFO list
adapter->Sync();
m_treePane->GetLibTree()->Unselect();
m_treePane->Regenerate();
if( target.IsValid() )
{
if( adapter->FindItem( target ) )
{
if( targetSelected )
m_treePane->GetLibTree()->SelectLibId( target );
else
m_treePane->GetLibTree()->CenterLibId( target );
}
else
{
// Try to focus on parent
target.SetLibItemName( wxEmptyString );
m_treePane->GetLibTree()->CenterLibId( target );
}
}
}
bool FOOTPRINT_EDIT_FRAME::IsGridVisible() const bool FOOTPRINT_EDIT_FRAME::IsGridVisible() const
{ {
return IsElementVisible( LAYER_GRID ); return IsElementVisible( LAYER_GRID );
@ -796,11 +895,9 @@ void FOOTPRINT_EDIT_FRAME::ProcessPreferences( wxCommandEvent& event )
} }
catch( const IO_ERROR& ioe ) catch( const IO_ERROR& ioe )
{ {
wxString msg = wxString::Format( _( wxString msg;
"Error occurred saving the global footprint library " msg.Printf( _( "Error saving the global footprint library table:\n\n%s" ),
"table:\n\n%s" ), ioe.What().GetData() );
GetChars( ioe.What().GetData() )
);
wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR ); wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
} }
} }
@ -816,11 +913,9 @@ void FOOTPRINT_EDIT_FRAME::ProcessPreferences( wxCommandEvent& event )
} }
catch( const IO_ERROR& ioe ) catch( const IO_ERROR& ioe )
{ {
wxString msg = wxString::Format( _( wxString msg;
"Error occurred saving project specific footprint library " msg.Printf( _( "Error saving project specific footprint library table:\n\n%s" ),
"table:\n\n%s" ), ioe.What() );
GetChars( ioe.What() )
);
wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR ); wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
} }
} }
@ -828,8 +923,13 @@ void FOOTPRINT_EDIT_FRAME::ProcessPreferences( wxCommandEvent& event )
FOOTPRINT_VIEWER_FRAME* viewer; FOOTPRINT_VIEWER_FRAME* viewer;
viewer = (FOOTPRINT_VIEWER_FRAME*)Kiway().Player( FRAME_PCB_MODULE_VIEWER, false ); viewer = (FOOTPRINT_VIEWER_FRAME*)Kiway().Player( FRAME_PCB_MODULE_VIEWER, false );
if( tableChanged && viewer != NULL ) if( tableChanged )
viewer->ReCreateLibraryList(); {
if( viewer != NULL )
viewer->ReCreateLibraryList();
syncLibraryTree( true );
}
} }
break; break;

View File

@ -29,10 +29,13 @@
#include <pcb_base_edit_frame.h> #include <pcb_base_edit_frame.h>
#include <io_mgr.h> #include <io_mgr.h>
#include <config_params.h> #include <config_params.h>
#include <fp_tree_synchronizing_adapter.h>
class PCB_LAYER_WIDGET; class PCB_LAYER_WIDGET;
class FP_LIB_TABLE; class FP_LIB_TABLE;
class EDGE_MODULE; class EDGE_MODULE;
class FOOTPRINT_TREE_PANE;
class LIB_MANAGER;
namespace PCB { struct IFACE; } // A KIFACE_I coded in pcbnew.c namespace PCB { struct IFACE; } // A KIFACE_I coded in pcbnew.c
@ -41,6 +44,9 @@ class FOOTPRINT_EDIT_FRAME : public PCB_BASE_EDIT_FRAME
{ {
friend struct PCB::IFACE; friend struct PCB::IFACE;
FOOTPRINT_TREE_PANE* m_treePane;
LIB_TREE_MODEL_ADAPTER::PTR m_adapter;
public: public:
~FOOTPRINT_EDIT_FRAME(); ~FOOTPRINT_EDIT_FRAME();
@ -132,13 +138,13 @@ public:
void OnConfigurePaths( wxCommandEvent& aEvent ); void OnConfigurePaths( wxCommandEvent& aEvent );
/** /**
* Function OnSaveLibraryAs * Function SaveLibraryAs
* saves the current library to a new name and/or library type. * saves a library to a new name and/or library type.
* *
* @note Saving as a new library type requires the plug-in to support saving libraries * @note Saving as a new library type requires the plug-in to support saving libraries
* @see PLUGIN::FootprintSave and PLUGIN::FootprintLibCreate * @see PLUGIN::FootprintSave and PLUGIN::FootprintLibCreate
*/ */
void OnSaveLibraryAs( wxCommandEvent& aEvent ); bool SaveLibraryAs( const wxString& aLibraryPath );
///> @copydoc EDA_DRAW_FRAME::GetHotKeyDescription() ///> @copydoc EDA_DRAW_FRAME::GetHotKeyDescription()
EDA_HOTKEY* GetHotKeyDescription( int aCommand ) const override; EDA_HOTKEY* GetHotKeyDescription( int aCommand ) const override;
@ -183,6 +189,9 @@ public:
void OnUpdateOptionsToolbar( wxUpdateUIEvent& aEvent ); void OnUpdateOptionsToolbar( wxUpdateUIEvent& aEvent );
void OnUpdateModuleSelected( wxUpdateUIEvent& aEvent ); void OnUpdateModuleSelected( wxUpdateUIEvent& aEvent );
void OnUpdateModuleTargeted( wxUpdateUIEvent& aEvent );
void OnUpdateSave( wxUpdateUIEvent& aEvent );
void OnUpdateSaveAs( wxUpdateUIEvent& aEvent );
void OnUpdateLoadModuleFromBoard( wxUpdateUIEvent& aEvent ); void OnUpdateLoadModuleFromBoard( wxUpdateUIEvent& aEvent );
void OnUpdateInsertModuleInBoard( wxUpdateUIEvent& aEvent ); void OnUpdateInsertModuleInBoard( wxUpdateUIEvent& aEvent );
void OnUpdateReplaceModuleInBoard( wxUpdateUIEvent& aEvent ); void OnUpdateReplaceModuleInBoard( wxUpdateUIEvent& aEvent );
@ -196,6 +205,11 @@ public:
*/ */
void LoadModuleFromBoard( wxCommandEvent& event ); void LoadModuleFromBoard( wxCommandEvent& event );
/**
* Returns the adapter object that provides the stored data.
*/
LIB_TREE_MODEL_ADAPTER::PTR& GetLibTreeAdapter() { return m_adapter; }
/** /**
* Function SaveFootprint * Function SaveFootprint
* Save in an existing library a given footprint * Save in an existing library a given footprint
@ -267,8 +281,11 @@ public:
BOARD_ITEM* ModeditLocateAndDisplay( int aHotKeyCode = 0 ); BOARD_ITEM* ModeditLocateAndDisplay( int aHotKeyCode = 0 );
/// Return the current library nickname. /// Return the LIB_ID of the part selected in the footprint or the part being edited.
const wxString GetCurrentLib() const; LIB_ID getTargetLibId() const;
/// Return the LIB_ID of the part being edited.
LIB_ID GetCurrentLibId() const;
void RemoveStruct( EDA_ITEM* Item ); void RemoveStruct( EDA_ITEM* Item );
@ -378,9 +395,9 @@ public:
/** /**
* Function DeleteModuleFromLibrary * Function DeleteModuleFromLibrary
* prompts user for footprint name, then deletes it from current library. * deletes the given module from its library.
*/ */
bool DeleteModuleFromLibrary(); bool DeleteModuleFromLibrary( MODULE* aModule );
/** /**
* Function IsElementVisible * Function IsElementVisible
@ -446,6 +463,18 @@ public:
*/ */
bool OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl = 0 ) override; bool OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl = 0 ) override;
/**
* Build the footprint library tree. Displays a progress dialog.
*/
void initLibraryTree();
/**
* Synchronize the footprint library tree to the current state of the footprint library
* table.
* @param aProgress
*/
void syncLibraryTree( bool aProgress );
/** /**
* Allows Modedit to install its preferences panel into the preferences dialog. * Allows Modedit to install its preferences panel into the preferences dialog.
*/ */
@ -486,9 +515,6 @@ protected:
/// Reloads displayed items and sets view. /// Reloads displayed items and sets view.
void updateView(); void updateView();
/// The libPath is not publicly visible, grab it from the FP_LIB_TABLE if we must.
const wxString getLibPath();
void restoreLastFootprint(); void restoreLastFootprint();
void retainLastFootprint(); void retainLastFootprint();

View File

@ -52,6 +52,9 @@
#include <pcbnew_id.h> #include <pcbnew_id.h>
#include <footprint_edit_frame.h> #include <footprint_edit_frame.h>
#include <footprint_viewer_frame.h> #include <footprint_viewer_frame.h>
#include <footprint_tree_pane.h>
#include <fp_lib_table.h>
#include <widgets/lib_tree.h>
#include <collectors.h> #include <collectors.h>
#include <tool/tool_manager.h> #include <tool/tool_manager.h>
#include <tools/pcb_actions.h> #include <tools/pcb_actions.h>
@ -279,12 +282,19 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break; break;
case ID_MODEDIT_DELETE_PART: case ID_MODEDIT_DELETE_PART:
if( DeleteModuleFromLibrary() ) if( DeleteModuleFromLibrary( LoadFootprint( getTargetLibId() ) ) )
Clear_Pcb( false ); {
if( getTargetLibId() == GetCurrentLibId() )
Clear_Pcb( false );
syncLibraryTree( true );
}
break; break;
case ID_MODEDIT_NEW_MODULE: case ID_MODEDIT_NEW_MODULE:
{ {
LIB_ID selected = m_treePane->GetLibTree()->GetSelectedLibId();
if( GetScreen()->IsModify() && !GetBoard()->IsEmpty() ) if( GetScreen()->IsModify() && !GetBoard()->IsEmpty() )
{ {
KIDIALOG dlg( this, _( "The current footprint contains unsaved changes." ), KIDIALOG dlg( this, _( "The current footprint contains unsaved changes." ),
@ -315,21 +325,39 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
GetBoard()->m_Modules->ClearFlags(); GetBoard()->m_Modules->ClearFlags();
Zoom_Automatique( false ); Zoom_Automatique( false );
GetScreen()->SetModify();
// If selected from the library tree then go ahead and save it there
if( !selected.GetLibNickname().empty() )
{
LIB_ID fpid = module->GetFPID();
fpid.SetLibNickname( selected.GetLibNickname() );
module->SetFPID( fpid );
SaveFootprint( module );
GetScreen()->ClrModify();
}
} }
updateView(); updateView();
m_canvas->Refresh(); m_canvas->Refresh();
Update3DView();
GetScreen()->ClrModify(); syncLibraryTree( false );
} }
break; break;
case ID_MODEDIT_NEW_MODULE_FROM_WIZARD: case ID_MODEDIT_NEW_MODULE_FROM_WIZARD:
{ {
LIB_ID selected = m_treePane->GetLibTree()->GetSelectedLibId();
if( GetScreen()->IsModify() && !GetBoard()->IsEmpty() ) if( GetScreen()->IsModify() && !GetBoard()->IsEmpty() )
{ {
if( !IsOK( this, KIDIALOG dlg( this, _( "The current footprint contains unsaved changes." ),
_( "Current Footprint will be lost and this operation cannot be undone. Continue ?" ) ) ) _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
dlg.SetOKLabel( _( "Discard Changes" ) );
dlg.DoNotShowCheckbox();
if( dlg.ShowModal() == wxID_CANCEL )
break; break;
} }
@ -359,48 +387,79 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
module->ClearFlags(); module->ClearFlags();
Zoom_Automatique( false ); Zoom_Automatique( false );
GetScreen()->SetModify();
// If selected from the library tree then go ahead and save it there
if( !selected.GetLibNickname().empty() )
{
LIB_ID fpid = module->GetFPID();
fpid.SetLibNickname( selected.GetLibNickname() );
module->SetFPID( fpid );
SaveFootprint( module );
GetScreen()->ClrModify();
}
updateView(); updateView();
m_canvas->Refresh(); m_canvas->Refresh();
Update3DView(); Update3DView();
GetScreen()->ClrModify(); syncLibraryTree( false );
} }
wizard->Destroy(); wizard->Destroy();
} }
break; break;
case ID_MODEDIT_SAVE_LIBMODULE: case ID_MODEDIT_SAVE:
if( GetBoard()->m_Modules ) if( getTargetLibId() == GetCurrentLibId() )
{ {
SaveFootprint( GetBoard()->m_Modules ); if( SaveFootprint( GetBoard()->m_Modules ) )
{
m_toolManager->GetView()->Update( GetBoard()->m_Modules );
m_toolManager->GetView()->Update( GetBoard()->m_Modules ); if( IsGalCanvasActive() && GetGalCanvas() )
GetGalCanvas()->ForceRefresh();
else
GetCanvas()->Refresh();
if( IsGalCanvasActive() && GetGalCanvas() ) GetScreen()->ClrModify();
GetGalCanvas()->ForceRefresh(); }
else
GetCanvas()->Refresh();
GetScreen()->ClrModify();
} }
m_treePane->GetLibTree()->Refresh();
break; break;
case ID_MODEDIT_SAVE_LIBMODULE_AS: case ID_MODEDIT_SAVE_AS:
if( GetBoard()->m_Modules ) if( getTargetLibId().GetLibItemName().empty() )
{ {
SaveFootprintAs( GetBoard()->m_Modules ); // Save Library As
const wxString& libName = getTargetLibId().GetLibNickname();
m_toolManager->GetView()->Update( GetBoard()->m_Modules ); if( SaveLibraryAs( Prj().PcbFootprintLibs()->FindRow( libName )->GetFullURI() ) )
syncLibraryTree( true );
if( IsGalCanvasActive() && GetGalCanvas() )
GetGalCanvas()->ForceRefresh();
else
GetCanvas()->Refresh();
GetScreen()->ClrModify();
} }
else
{
// Save Footprint As
MODULE* footprint = LoadFootprint( getTargetLibId() );
if( footprint && SaveFootprintAs( footprint ) )
{
syncLibraryTree( false );
if( getTargetLibId() == GetCurrentLibId() )
{
m_toolManager->GetView()->Update( GetBoard()->m_Modules );
if( IsGalCanvasActive() && GetGalCanvas() )
GetGalCanvas()->ForceRefresh();
else
GetCanvas()->Refresh();
GetScreen()->ClrModify();
}
}
}
m_treePane->GetLibTree()->Refresh();
break; break;
case ID_MODEDIT_INSERT_MODULE_IN_BOARD: case ID_MODEDIT_INSERT_MODULE_IN_BOARD:
@ -511,21 +570,29 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break; break;
case ID_MODEDIT_EXPORT_PART: case ID_MODEDIT_EXPORT_PART:
if( GetBoard()->m_Modules ) Export_Module( LoadFootprint( getTargetLibId() ) );
Export_Module( GetBoard()->m_Modules );
break; break;
case ID_MODEDIT_CREATE_NEW_LIB: case ID_MODEDIT_CREATE_NEW_LIB:
CreateNewLibrary(); {
wxFileName fn( CreateNewLibrary() );
wxString name = fn.GetName();
if( !name.IsEmpty() )
{
LIB_ID newLib( name, wxEmptyString );
syncLibraryTree( false );
m_treePane->GetLibTree()->SelectLibId( newLib );
}
}
break; break;
case ID_MODEDIT_SHEET_SET: case ID_MODEDIT_SHEET_SET:
break; break;
case ID_MODEDIT_LOAD_MODULE: case ID_MODEDIT_EDIT_MODULE:
{ {
wxLogDebug( wxT( "Loading module from library " ) + getLibPath() );
if( GetScreen()->IsModify() && !GetBoard()->IsEmpty() ) if( GetScreen()->IsModify() && !GetBoard()->IsEmpty() )
{ {
KIDIALOG dlg( this, _( "The current footprint contains unsaved changes." ), KIDIALOG dlg( this, _( "The current footprint contains unsaved changes." ),
@ -537,7 +604,9 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break; break;
} }
MODULE* module = SelectFootprintFromLibTree( wxEmptyString ); LIB_ID partId = m_treePane->GetLibTree()->GetSelectedLibId();
MODULE* module = LoadFootprint( partId );
if( !module ) if( !module )
break; break;
@ -578,6 +647,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
updateView(); updateView();
m_canvas->Refresh(); m_canvas->Refresh();
m_treePane->GetLibTree()->Refresh();
} }
break; break;

View File

@ -53,8 +53,6 @@
#include <kicad_plugin.h> #include <kicad_plugin.h>
#include <legacy_plugin.h> #include <legacy_plugin.h>
#include <dialog_select_pretty_lib.h>
// unique, "file local" translations: // unique, "file local" translations:
@ -318,6 +316,10 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module( const wxString& aName )
return NULL; return NULL;
} }
LIB_ID fpid;
fpid.SetLibItemName( module->GetFPID().GetLibItemName() );
module->SetFPID( fpid );
// Insert footprint in list // Insert footprint in list
GetBoard()->Add( module ); GetBoard()->Add( module );
@ -417,28 +419,33 @@ wxString PCB_BASE_EDIT_FRAME::CreateNewLibrary(const wxString& aLibName )
// because the legacy format cannot handle current features. // because the legacy format cannot handle current features.
// The footprint library is actually a directory // The footprint library is actually a directory
// if a library name is not given, prompt user for footprint library name, ending by ".pretty"
// Because there are constraints for the directory name to create,
// (the name should have the extension ".pretty", and the folder cannot be inside
// a footprint library), we do not use the standard wxDirDialog.
wxString initialPath = wxPathOnly( Prj().GetProjectFullName() ); wxString initialPath = wxPathOnly( Prj().GetProjectFullName() );
wxFileName fn;
wxString libPath; bool saveInGlobalTable = false, saveInProjectTable = false;
if( aLibName.IsEmpty() ) if( aLibName.IsEmpty() )
{ {
DIALOG_SELECT_PRETTY_LIB dlg( this, initialPath ); fn = initialPath;
if( dlg.ShowModal() != wxID_OK ) if( !LibraryFileBrowser( false, fn, KiCadFootprintLibPathWildcard(), KiCadFootprintLibPathExtension ) )
return wxEmptyString; return wxEmptyString;
libPath = dlg.GetFullPrettyLibName(); 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;
}
} }
else else
{ {
wxFileName fn = aLibName; fn = aLibName;
if( !fn.IsAbsolute() ) if( !fn.IsAbsolute() )
{ {
@ -448,13 +455,11 @@ wxString PCB_BASE_EDIT_FRAME::CreateNewLibrary(const wxString& aLibName )
// Enforce the .pretty extension: // Enforce the .pretty extension:
fn.SetExt( KiCadFootprintLibPathExtension ); fn.SetExt( KiCadFootprintLibPathExtension );
libPath = fn.GetFullPath();
} }
// We can save fp libs only using IO_MGR::KICAD_SEXP format (.pretty libraries) // We can save fp libs only using IO_MGR::KICAD_SEXP format (.pretty libraries)
IO_MGR::PCB_FILE_T piType = IO_MGR::KICAD_SEXP; IO_MGR::PCB_FILE_T piType = IO_MGR::KICAD_SEXP;
wxString libPath = fn.GetFullPath();
try try
{ {
@ -469,15 +474,13 @@ wxString PCB_BASE_EDIT_FRAME::CreateNewLibrary(const wxString& aLibName )
exists = true; // no exception was thrown, lib must exist. exists = true; // no exception was thrown, lib must exist.
} }
catch( const IO_ERROR& ) catch( const IO_ERROR& )
{ { }
// ignore, original values of 'writable' and 'exists' are accurate.
}
if( exists ) if( exists )
{ {
if( !writable ) if( !writable )
{ {
wxString msg = wxString::Format( FMT_LIB_READ_ONLY, GetChars( libPath ) ); wxString msg = wxString::Format( FMT_LIB_READ_ONLY, libPath );
DisplayError( this, msg ); DisplayError( this, msg );
return wxEmptyString; return wxEmptyString;
} }
@ -496,6 +499,19 @@ wxString PCB_BASE_EDIT_FRAME::CreateNewLibrary(const wxString& aLibName )
} }
pi->FootprintLibCreate( libPath ); pi->FootprintLibCreate( libPath );
if( saveInGlobalTable )
{
auto row = new FP_LIB_TABLE_ROW( fn.GetName(), libPath, wxT( "KiCad" ), wxEmptyString );
GFootprintTable.InsertRow( row );
GFootprintTable.Save( FP_LIB_TABLE::GetGlobalTableFileName() );
}
else if( saveInProjectTable )
{
auto row = new FP_LIB_TABLE_ROW( fn.GetName(), libPath, wxT( "KiCad" ), wxEmptyString );
Prj().PcbFootprintLibs()->InsertRow( row );
Prj().PcbFootprintLibs()->Save( Prj().FootprintLibTblName() );
}
} }
catch( const IO_ERROR& ioe ) catch( const IO_ERROR& ioe )
{ {
@ -507,14 +523,12 @@ wxString PCB_BASE_EDIT_FRAME::CreateNewLibrary(const wxString& aLibName )
} }
bool FOOTPRINT_EDIT_FRAME::DeleteModuleFromLibrary() bool FOOTPRINT_EDIT_FRAME::DeleteModuleFromLibrary( MODULE* aModule )
{ {
MODULE* module = GetBoard()->m_Modules; if( !aModule )
if( !module )
return false; return false;
LIB_ID fpid = module->GetFPID(); LIB_ID fpid = aModule->GetFPID();
if( !fpid.IsValid() ) if( !fpid.IsValid() )
return false; return false;

View File

@ -0,0 +1,147 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2018 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 3
* 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:
* https://www.gnu.org/licenses/gpl-3.0.html
* or you may search the http://www.gnu.org website for the version 3 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "footprint_tree_pane.h"
#include "fp_tree_synchronizing_adapter.h"
#include <widgets/lib_tree.h>
#include <pcbnew_id.h>
#include <footprint_edit_frame.h>
#include <fp_lib_table.h>
#include <menus_helpers.h>
FOOTPRINT_TREE_PANE::FOOTPRINT_TREE_PANE( FOOTPRINT_EDIT_FRAME* aParent )
: wxPanel( aParent ),
m_frame( aParent ),
m_tree( nullptr )
{
// Create widgets
wxBoxSizer* boxSizer = new wxBoxSizer( wxVERTICAL );
m_tree = new LIB_TREE( this, &GFootprintTable, m_frame->GetLibTreeAdapter(), LIB_TREE::SEARCH );
boxSizer->Add( m_tree, 1, wxEXPAND, 5 );
SetSizer( boxSizer ); // should remove the previous sizer according to wxWidgets docs
Layout();
boxSizer->Fit( this );
// Setup right click-context menus
std::unique_ptr<wxMenu> menuLibrary = std::make_unique<wxMenu>();
AddMenuItem( menuLibrary.get(), ID_MODEDIT_CREATE_NEW_LIB, _( "New &Library..." ),
KiBitmap( new_library_xpm ) );
/* TODO
AddMenuItem( menuLibrary.get(), ID_LIBEDIT_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 ) );
AddMenuItem( menuLibrary.get(), ID_MODEDIT_NEW_MODULE_FROM_WIZARD, _( "&Create Footprint..." ),
KiBitmap( new_component_xpm ) );
AddMenuItem( menuLibrary.get(), ID_MODEDIT_IMPORT_PART, _( "&Import Footprint..." ),
KiBitmap( import_part_xpm ) );
std::unique_ptr<wxMenu> menuPart = std::make_unique<wxMenu>();
AddMenuItem( menuPart.get(), ID_MODEDIT_EDIT_MODULE, _( "&Edit Footprint" ),
KiBitmap( edit_xpm ) );
menuPart->AppendSeparator();
AddMenuItem( menuPart.get(), ID_MODEDIT_SAVE, _( "&Save" ),
KiBitmap( save_xpm ) );
AddMenuItem( menuPart.get(), ID_MODEDIT_SAVE_AS, _( "Save a Copy As..." ),
KiBitmap( save_xpm ) );
AddMenuItem( menuPart.get(), ID_MODEDIT_DELETE_PART, _( "Delete" ),
KiBitmap( delete_xpm ) );
/* TODO
AddMenuItem( menuPart.get(), ID_LIBEDIT_REVERT, _( "Revert" ),
KiBitmap( undo_xpm ) );
*/
menuPart->AppendSeparator();
AddMenuItem( menuPart.get(), ID_MODEDIT_EXPORT_PART, _( "E&xport Footprint..." ),
KiBitmap( export_part_xpm ) );
// Menu displayed when nothing is selected
std::unique_ptr<wxMenu> menuNoSelection = std::make_unique<wxMenu>();
AddMenuItem( menuNoSelection.get(), ID_MODEDIT_CREATE_NEW_LIB, _( "&New Library..." ),
KiBitmap( new_library_xpm ) );
/* TODO
AddMenuItem( menuNoSelection.get(), ID_LIBEDIT_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 ) );
// Event handlers
Bind( COMPONENT_SELECTED, &FOOTPRINT_TREE_PANE::onComponentSelected, this );
m_tree->Bind( wxEVT_UPDATE_UI, &FOOTPRINT_TREE_PANE::onUpdateUI, this );
}
FOOTPRINT_TREE_PANE::~FOOTPRINT_TREE_PANE()
{
m_tree->Destroy();
}
void FOOTPRINT_TREE_PANE::Regenerate()
{
if( m_tree )
m_tree->Regenerate();
}
void FOOTPRINT_TREE_PANE::onComponentSelected( wxCommandEvent& aEvent )
{
// Repost the event
wxCommandEvent evt( wxEVT_COMMAND_TOOL_CLICKED, ID_MODEDIT_EDIT_MODULE );
// I cannot figure out why the two methods below do not work..
//wxPostEvent( libEditFrame, evt );
//wxQueueEvent( m_libEditFrame, new wxCommandEvent( ID_LIBEDIT_EDIT_PART ) );
m_frame->Process_Special_Functions( evt );
// Make sure current-part highlighting doesn't get lost in seleciton highlighting
m_tree->Unselect();
}
void FOOTPRINT_TREE_PANE::onUpdateUI( wxUpdateUIEvent& aEvent )
{
if( m_frame->GetGalCanvas()->HasFocus() )
{
// Don't allow a selected item in the tree when the canvas has focus: it's too easy
// to confuse the selected-highlighting with the being-edited-on-canvas-highlighting.
m_tree->Unselect();
}
}

View File

@ -0,0 +1,61 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* 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 3
* 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:
* https://www.gnu.org/licenses/gpl-3.0.html
* or you may search the http://www.gnu.org website for the version 3 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef FOOTPRINT_TREE_PANE_H
#define FOOTPRINT_TREE_PANE_H
#include <wx/panel.h>
#include <wx/dataview.h>
#include <vector>
class LIB_TREE;
class FOOTPRINT_EDIT_FRAME;
class wxBoxSizer;
/**
* Footprint Editor pane with footprint library tree.
*/
class FOOTPRINT_TREE_PANE : public wxPanel
{
public:
FOOTPRINT_TREE_PANE( FOOTPRINT_EDIT_FRAME* aParent );
~FOOTPRINT_TREE_PANE();
LIB_TREE* GetLibTree() const
{
return m_tree;
}
///> Updates the footprint tree
void Regenerate();
protected:
void onComponentSelected( wxCommandEvent& aEvent );
void onUpdateUI( wxUpdateUIEvent& aEvent );
FOOTPRINT_EDIT_FRAME* m_frame;
LIB_TREE* m_tree; ///< component search tree widget
};
#endif /* FOOTPRINT_TREE_PANE_H */

View File

@ -23,11 +23,11 @@
#include <eda_pattern_match.h> #include <eda_pattern_match.h>
#include <fp_lib_table.h> #include <fp_lib_table.h>
#include <footprint_info.h> #include <footprint_info.h>
#include <footprint_info_impl.h>
#include <generate_footprint_info.h> #include <generate_footprint_info.h>
#include "fp_tree_model_adapter.h" #include "fp_tree_model_adapter.h"
FP_TREE_MODEL_ADAPTER::PTR FP_TREE_MODEL_ADAPTER::Create( LIB_TABLE* aLibs ) FP_TREE_MODEL_ADAPTER::PTR FP_TREE_MODEL_ADAPTER::Create( LIB_TABLE* aLibs )
{ {
return PTR( new FP_TREE_MODEL_ADAPTER( aLibs ) ); return PTR( new FP_TREE_MODEL_ADAPTER( aLibs ) );
@ -43,29 +43,37 @@ FP_TREE_MODEL_ADAPTER::~FP_TREE_MODEL_ADAPTER()
{} {}
void FP_TREE_MODEL_ADAPTER::AddLibraries( FOOTPRINT_LIST* aFootprintInfoList ) void FP_TREE_MODEL_ADAPTER::AddLibraries()
{ {
// Note: FOOTPRINT_INFO list must be sorted! for( const auto& libName : m_libs->GetLogicalLibs() )
wxString currentLib;
std::vector<LIB_TREE_ITEM*> footprints;
for( auto& footprint : aFootprintInfoList->GetList() )
{ {
if( footprint->GetNickname() != currentLib ) const FP_LIB_TABLE_ROW* library = m_libs->FindRow( libName );
{
if( footprints.size() )
DoAddLibrary( currentLib, m_libs->GetDescription( currentLib ), footprints );
footprints.clear(); DoAddLibrary( libName, library->GetDescr(), getFootprints( libName ) );
currentLib = footprint->GetNickname(); }
}
std::vector<LIB_TREE_ITEM*> FP_TREE_MODEL_ADAPTER::getFootprints( const wxString& aLibName )
{
std::vector<LIB_TREE_ITEM*> list;
bool found = false;
for( auto& footprint : GFootprintList.GetList() )
{
if( footprint->GetNickname() != aLibName )
{
if( found )
return list;
else
continue;
} }
footprints.push_back( footprint.get() ); found = true;
list.push_back( footprint.get() );
} }
if( footprints.size() ) return list;
DoAddLibrary( currentLib, m_libs->GetDescription( currentLib ), footprints );
} }

View File

@ -43,18 +43,18 @@ public:
*/ */
static PTR Create( LIB_TABLE* aLibs ); static PTR Create( LIB_TABLE* aLibs );
void AddLibraries( FOOTPRINT_LIST* aFootprintInfoList ); void AddLibraries();
wxString GenerateInfo( LIB_ID const& aLibId, int aUnit ) override; wxString GenerateInfo( LIB_ID const& aLibId, int aUnit ) override;
protected: protected:
/** /**
* Constructor; takes a set of libraries to be included in the search. * Constructor; takes a set of libraries to be included in the search.
*/ */
FP_TREE_MODEL_ADAPTER( LIB_TABLE* aLibs ); FP_TREE_MODEL_ADAPTER( LIB_TABLE* aLibs );
private: std::vector<LIB_TREE_ITEM*> getFootprints( const wxString& aLibName );
FP_LIB_TABLE* m_libs; FP_LIB_TABLE* m_libs;
}; };

View File

@ -0,0 +1,235 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* 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 3
* 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:
* https://www.gnu.org/licenses/gpl-3.0.html
* or you may search the http://www.gnu.org website for the version 3 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <fp_tree_synchronizing_adapter.h>
#include <footprint_edit_frame.h>
#include <fp_lib_table.h>
#include <footprint_info_impl.h>
LIB_TREE_MODEL_ADAPTER::PTR FP_TREE_SYNCHRONIZING_ADAPTER::Create( FOOTPRINT_EDIT_FRAME* aFrame,
FP_LIB_TABLE* aLibs )
{
return PTR( new FP_TREE_SYNCHRONIZING_ADAPTER( aFrame, aLibs ) );
}
FP_TREE_SYNCHRONIZING_ADAPTER::FP_TREE_SYNCHRONIZING_ADAPTER( FOOTPRINT_EDIT_FRAME* aFrame,
FP_LIB_TABLE* aLibs ) :
FP_TREE_MODEL_ADAPTER( aLibs ),
m_frame( aFrame )
{
}
bool FP_TREE_SYNCHRONIZING_ADAPTER::IsContainer( const wxDataViewItem& aItem ) const
{
const LIB_TREE_NODE* node = ToNode( aItem );
return node ? node->Type == LIB_TREE_NODE::LIB : true;
}
#define PROGRESS_INTERVAL_MILLIS 66
void FP_TREE_SYNCHRONIZING_ADAPTER::Sync()
{
// Process already stored libraries
for( auto it = m_tree.Children.begin(); it != m_tree.Children.end(); )
{
const wxString& name = it->get()->Name;
if( !m_libs->HasLibrary( name, true ) )
{
it = deleteLibrary( it );
continue;
}
updateLibrary( *(LIB_TREE_NODE_LIB*) it->get() );
++it;
}
// Look for new libraries
for( const auto& libName : m_libs->GetLogicalLibs() )
{
if( m_libMap.count( libName ) == 0 )
{
const FP_LIB_TABLE_ROW* library = m_libs->FindRow( libName );
DoAddLibrary( libName, library->GetDescr(), getFootprints( libName ) );
m_libMap.insert( libName );
}
}
}
int FP_TREE_SYNCHRONIZING_ADAPTER::GetLibrariesCount() const
{
return GFootprintTable.GetCount();
}
void FP_TREE_SYNCHRONIZING_ADAPTER::updateLibrary( LIB_TREE_NODE_LIB& aLibNode )
{
std::vector<LIB_TREE_ITEM*> footprints = getFootprints( aLibNode.Name );
// remove the common part from the aliases list
for( auto nodeIt = aLibNode.Children.begin(); nodeIt != aLibNode.Children.end(); )
{
auto footprintIt = std::find_if( footprints.begin(), footprints.end(),
[&] ( const LIB_TREE_ITEM* a )
{
return a->GetName() == (*nodeIt)->Name;
} );
if( footprintIt != footprints.end() )
{
// alias exists both in the component tree and the library manager,
// update only the node data
static_cast<LIB_TREE_NODE_LIB_ID*>( nodeIt->get() )->Update( *footprintIt );
footprints.erase( footprintIt );
++nodeIt;
}
else
{
// node does not exist in the library manager, remove the corresponding node
nodeIt = aLibNode.Children.erase( nodeIt );
}
}
// now the aliases list contains only new aliases that need to be added to the tree
for( auto footprint : footprints )
aLibNode.AddComp( footprint );
aLibNode.AssignIntrinsicRanks();
m_libMap.insert( aLibNode.Name );
}
LIB_TREE_NODE::PTR_VECTOR::iterator FP_TREE_SYNCHRONIZING_ADAPTER::deleteLibrary(
LIB_TREE_NODE::PTR_VECTOR::iterator& aLibNodeIt )
{
LIB_TREE_NODE* node = aLibNodeIt->get();
m_libMap.erase( node->Name );
auto it = m_tree.Children.erase( aLibNodeIt );
return it;
}
void FP_TREE_SYNCHRONIZING_ADAPTER::GetValue( wxVariant& aVariant, wxDataViewItem const& aItem,
unsigned int aCol ) const
{
if( IsFrozen() )
{
aVariant = wxEmptyString;
return;
}
auto node = ToNode( aItem );
wxASSERT( node );
switch( aCol )
{
case 0:
// mark modified part with an asterix
if( node->LibId == m_frame->GetCurrentLibId() && m_frame->GetScreen()->IsModify() )
aVariant = node->Name + " *";
else
aVariant = node->Name;
break;
case 1:
aVariant = node->Desc;
break;
default: // column == -1 is used for default Compare function
aVariant = node->Name;
break;
}
}
bool FP_TREE_SYNCHRONIZING_ADAPTER::GetAttr( wxDataViewItem const& aItem, unsigned int aCol,
wxDataViewItemAttr& aAttr ) const
{
if( IsFrozen() )
return false;
// change attributes only for the name field
if( aCol != 0 )
return false;
auto node = ToNode( aItem );
wxCHECK( node, false );
switch( node->Type )
{
case LIB_TREE_NODE::LIB:
#ifdef __WXGTK__
// The native wxGTK+ impl ignores background colour, so set the text colour instead.
// This works reasonably well in dark themes, and quite poorly in light ones....
if( node->Name == m_frame->GetCurrentLibId().GetLibNickname() )
{
aAttr.SetColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
// mark modified libs with bold font
aAttr.SetBold( m_frame->GetScreen()->IsModified() );
}
#else
// mark the current library with background color
if( node->Name == m_frame->GetCurrentLibId().GetLibNickname() )
{
aAttr.SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
// mark modified libs with bold font
aAttr.SetBold( m_frame->GetScreen()->IsModify() );
}
#endif
break;
case LIB_TREE_NODE::LIBID:
#ifdef __WXGTK__
// The native wxGTK+ impl ignores background colour, so set the text colour instead.
// This works reasonably well in dark themes, and quite poorly in light ones....
if( node->LibId == m_libMgr->GetCurrentLibId() )
{
aAttr.SetColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
// mark modified part with bold font
aAttr.SetBold( m_frame->GetScreen()->IsModified() );
}
#else
// mark the current part with background color
if( node->LibId == m_frame->GetCurrentLibId() )
{
aAttr.SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
// mark modified part with bold font
aAttr.SetBold( m_frame->GetScreen()->IsModify() );
}
#endif
break;
default:
return false;
}
return true;
}

View File

@ -0,0 +1,60 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* 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 3
* 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:
* https://www.gnu.org/licenses/gpl-3.0.html
* or you may search the http://www.gnu.org website for the version 3 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef FP_TREE_SYNCHRONIZING_ADAPTER_H
#define FP_TREE_SYNCHRONIZING_ADAPTER_H
#include <fp_tree_model_adapter.h>
#include <set>
class FOOTPRINT_EDIT_FRAME;
class FP_TREE_SYNCHRONIZING_ADAPTER : public FP_TREE_MODEL_ADAPTER
{
public:
static PTR Create( FOOTPRINT_EDIT_FRAME* aFrame, FP_LIB_TABLE* aLibs );
bool IsContainer( const wxDataViewItem& aItem ) const override;
void Sync();
int GetLibrariesCount() const override;
protected:
FP_TREE_SYNCHRONIZING_ADAPTER( FOOTPRINT_EDIT_FRAME* aFrame, FP_LIB_TABLE* aLibs );
void updateLibrary( LIB_TREE_NODE_LIB& aLibNode );
LIB_TREE_NODE::PTR_VECTOR::iterator deleteLibrary( LIB_TREE_NODE::PTR_VECTOR::iterator& aLibNodeIt );
void GetValue( wxVariant& aVariant, wxDataViewItem const& aItem,
unsigned int aCol ) const override;
bool GetAttr( wxDataViewItem const& aItem, unsigned int aCol,
wxDataViewItemAttr& aAttr ) const override;
FOOTPRINT_EDIT_FRAME* m_frame;
std::set<wxString> m_libMap; // Set to indicate libraries currently in tree
};
#endif /* FP_TREE_SYNCHRONIZING_ADAPTER_H */

View File

@ -213,7 +213,7 @@ MODULE* PCB_BASE_FRAME::SelectFootprintFromLibTree( const wxString& aLibrary, bo
adapter->SetPreselectNode( history_list[0]->GetLibId(), 0 ); adapter->SetPreselectNode( history_list[0]->GetLibId(), 0 );
} }
adapter->AddLibraries( &GFootprintList ); adapter->AddLibraries();
wxString title; wxString title;
title.Printf( _( "Choose Footprint (%d items loaded)" ), adapter->GetItemCount() ); title.Printf( _( "Choose Footprint (%d items loaded)" ), adapter->GetItemCount() );
@ -396,13 +396,13 @@ MODULE* FOOTPRINT_EDIT_FRAME::SelectFootprintFromBoard( BOARD* aPcb )
} }
void FOOTPRINT_EDIT_FRAME::OnSaveLibraryAs( wxCommandEvent& aEvent ) bool FOOTPRINT_EDIT_FRAME::SaveLibraryAs( const wxString& aLibraryPath )
{ {
wxString curLibPath; wxString curLibPath = aLibraryPath;
wxString dstLibPath = CreateNewLibrary(); wxString dstLibPath = CreateNewLibrary();
if( !dstLibPath ) if( !dstLibPath )
return; // user aborted in CreateNewLibrary() return false; // user aborted in CreateNewLibrary()
wxBusyCursor dummy; wxBusyCursor dummy;
wxString msg; wxString msg;
@ -415,26 +415,23 @@ void FOOTPRINT_EDIT_FRAME::OnSaveLibraryAs( wxCommandEvent& aEvent )
PLUGIN::RELEASER cur( IO_MGR::PluginFind( curType ) ); PLUGIN::RELEASER cur( IO_MGR::PluginFind( curType ) );
PLUGIN::RELEASER dst( IO_MGR::PluginFind( dstType ) ); PLUGIN::RELEASER dst( IO_MGR::PluginFind( dstType ) );
wxArrayString mods; wxArrayString footprints;
cur->FootprintEnumerate( mods, curLibPath ); cur->FootprintEnumerate( footprints, curLibPath );
for( unsigned i = 0; i < mods.size(); ++i ) for( unsigned i = 0; i < footprints.size(); ++i )
{ {
std::unique_ptr<MODULE> m( cur->LoadEnumeratedFootprint( curLibPath, mods[i] ) ); const MODULE* footprint = cur->LoadEnumeratedFootprint( curLibPath, footprints[i] );
dst->FootprintSave( dstLibPath, m.get() ); dst->FootprintSave( dstLibPath, footprint );
msg = wxString::Format( _( "Footprint \"%s\" saved" ), msg = wxString::Format( _( "Footprint \"%s\" saved" ), footprints[i] );
GetChars( mods[i] ) );
SetStatusText( msg ); SetStatusText( msg );
// m is deleted here by unique_ptr.
} }
} }
catch( const IO_ERROR& ioe ) catch( const IO_ERROR& ioe )
{ {
DisplayError( this, ioe.What() ); DisplayError( this, ioe.What() );
return; return false;
} }
msg = wxString::Format( msg = wxString::Format(
@ -444,4 +441,5 @@ void FOOTPRINT_EDIT_FRAME::OnSaveLibraryAs( wxCommandEvent& aEvent )
DisplayInfoMessage( this, msg ); DisplayInfoMessage( this, msg );
SetStatusText( wxEmptyString ); SetStatusText( wxEmptyString );
return true;
} }

View File

@ -53,33 +53,38 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar()
// Menu File: // Menu File:
wxMenu* fileMenu = new wxMenu; wxMenu* fileMenu = new wxMenu;
// New module AddMenuItem( fileMenu,
text = AddHotkeyName( _( "&New..." ), m_hotkeysDescrList, HK_NEW ); ID_MODEDIT_CREATE_NEW_LIB,
_( "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, AddMenuItem( fileMenu, ID_MODEDIT_NEW_MODULE,
text, _( "Create a new footprint" ), text, _( "Create a new footprint" ),
KiBitmap( new_footprint_xpm ) ); KiBitmap( new_footprint_xpm ) );
AddMenuItem( fileMenu, ID_MODEDIT_NEW_MODULE_FROM_WIZARD, AddMenuItem( fileMenu, ID_MODEDIT_NEW_MODULE_FROM_WIZARD,
_( "&Create..." ), _( "&Create Footprint..." ),
_( "Create a new footprint using the footprint wizard" ), _( "Create a new footprint using the footprint wizard" ),
KiBitmap( module_wizard_xpm ) ); KiBitmap( module_wizard_xpm ) );
text = AddHotkeyName( _( "&Open..." ), m_hotkeysDescrList, HK_OPEN );
AddMenuItem( fileMenu, ID_MODEDIT_LOAD_MODULE, text,
_( "Open a footprint from a library" ),
KiBitmap( load_module_lib_xpm ) );
fileMenu->AppendSeparator(); fileMenu->AppendSeparator();
// Save module
text = AddHotkeyName( _( "&Save" ), m_hotkeysDescrList, HK_SAVE ); text = AddHotkeyName( _( "&Save" ), m_hotkeysDescrList, HK_SAVE );
AddMenuItem( fileMenu, ID_MODEDIT_SAVE_LIBMODULE, text, AddMenuItem( fileMenu, ID_MODEDIT_SAVE, text,
_( "Save changes" ), _( "Save changes" ),
KiBitmap( save_xpm ) ); KiBitmap( save_xpm ) );
AddMenuItem( fileMenu, ID_MODEDIT_SAVE_LIBMODULE_AS, AddMenuItem( fileMenu, ID_MODEDIT_SAVE_AS,
_( "Save &As..." ), _( "Save a Copy &As..." ),
_( "Save footprint to a new name and/or new library" ), _( "Save a copy to a new name and/or location" ),
KiBitmap( save_as_xpm ) ); KiBitmap( save_as_xpm ) );
fileMenu->AppendSeparator(); fileMenu->AppendSeparator();

View File

@ -104,7 +104,7 @@ const LAYER_NUM GAL_LAYER_ORDER[] =
PCB_DRAW_PANEL_GAL::PCB_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWindowId, PCB_DRAW_PANEL_GAL::PCB_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWindowId,
const wxPoint& aPosition, const wxSize& aSize, const wxPoint& aPosition, const wxSize& aSize,
KIGFX::GAL_DISPLAY_OPTIONS& aOptions, GAL_TYPE aGalType ) : KIGFX::GAL_DISPLAY_OPTIONS& aOptions, GAL_TYPE aGalType ) :
EDA_DRAW_PANEL_GAL( aParentWindow, aWindowId, aPosition, aSize, aOptions, aGalType ) EDA_DRAW_PANEL_GAL( aParentWindow, aWindowId, aPosition, aSize, aOptions, aGalType )
{ {
m_view = new KIGFX::PCB_VIEW( true ); m_view = new KIGFX::PCB_VIEW( true );
m_view->SetGAL( m_gal ); m_view->SetGAL( m_gal );

View File

@ -75,9 +75,7 @@ void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event )
{ {
try try
{ {
FILE_OUTPUTFORMATTER sf( FP_LIB_TABLE::GetGlobalTableFileName() ); GFootprintTable.Save( FP_LIB_TABLE::GetGlobalTableFileName() );
GFootprintTable.Format( &sf, 0 );
tableChanged = true; tableChanged = true;
} }
catch( const IO_ERROR& ioe ) catch( const IO_ERROR& ioe )

View File

@ -364,14 +364,13 @@ enum pcbnew_ids
ID_POPUP_MODEDIT_EDIT_EDGE, ID_POPUP_MODEDIT_EDIT_EDGE,
ID_MODEDIT_CHECK, ID_MODEDIT_CHECK,
ID_MODEDIT_CREATE_NEW_LIB, ID_MODEDIT_CREATE_NEW_LIB,
ID_MODEDIT_SAVE_LIBMODULE, ID_MODEDIT_SAVE,
ID_MODEDIT_SAVE_LIBMODULE_AS, ID_MODEDIT_SAVE_AS,
ID_MODEDIT_SAVE_LIBRARY_AS,
ID_MODEDIT_DELETE_PART, ID_MODEDIT_DELETE_PART,
ID_MODEDIT_NEW_MODULE, ID_MODEDIT_NEW_MODULE,
ID_MODEDIT_NEW_MODULE_FROM_WIZARD, ID_MODEDIT_NEW_MODULE_FROM_WIZARD,
ID_MODEDIT_SHEET_SET, ID_MODEDIT_SHEET_SET,
ID_MODEDIT_LOAD_MODULE, ID_MODEDIT_EDIT_MODULE,
ID_MODEDIT_PAD_SETTINGS, ID_MODEDIT_PAD_SETTINGS,
ID_MODEDIT_LOAD_MODULE_FROM_BOARD, ID_MODEDIT_LOAD_MODULE_FROM_BOARD,
ID_MODEDIT_INSERT_MODULE_IN_BOARD, ID_MODEDIT_INSERT_MODULE_IN_BOARD,

View File

@ -56,11 +56,7 @@ void FOOTPRINT_EDIT_FRAME::ReCreateHToolbar()
_( "New footprint using footprint wizard" ) ); _( "New footprint using footprint wizard" ) );
#endif #endif
m_mainToolBar->AddTool( ID_MODEDIT_LOAD_MODULE, wxEmptyString, m_mainToolBar->AddTool( ID_MODEDIT_SAVE, wxEmptyString,
KiScaledBitmap( load_module_lib_xpm, this ),
_( "Open a footprint from a library" ) );
m_mainToolBar->AddTool( ID_MODEDIT_SAVE_LIBMODULE, wxEmptyString,
KiScaledBitmap( save_xpm, this ), KiScaledBitmap( save_xpm, this ),
_( "Save footprint in existing library" ) ); _( "Save footprint in existing library" ) );