← Back to team overview

kicad-developers team mailing list archive

Re: [PATCH] Refactor hotkeys editor dialog more

 

Third step, again to be merged on top of the previous ones. This one 
pulls the Hotkeys dialog finally into the eeschema Preferences dialog. 
To go with it, I also pulled the load/save hotkeys command into that 
dialog, and for consistency, the load/save preferences command. These 
are now an "Import/Export..." menu button inside the preferences dialog.

Also removed "List Hotkeys", as it's quite redundant - the hotkeys 
editor lists them just fine.

This makes the Preferences menu quite small, and the new Preferences 
dialog is still nice and neat IMO ^-^

My next step is to investigate the behavior of the Import/Export 
Preferences command itself. It seems to be a bit buggy. After that I 
will continue working on the minor GUI quirks I mentioned earlier.


On Mon, Jan 04, 2016 at 04:28:20PM -0500, Chris Pavlina wrote:
> Second step is to remove the pages from the hotkeys dialog and make it a 
> single-page control, so we don't have nested tabs when it's brought into 
> the already tabbed options dialog. This patch removes the pages, in 
> favor of categories in the wxTreeListCtrl. It also makes the final few 
> steps towards making the HOTKEY_LIST_CTRL fully embeddable.
> 
> This patch applies on top of the previous one. I recommend keeping them 
> as separate commits, just in case I've created any bugs (makes them 
> easier to track down).
> 
> There are a couple known GUI "quirks" - the columns are sized slightly 
> wrong when there is a vectical scrollbar, and the column sizing changes 
> a bit erratically when resizing the dialog. These are wx bugs. I'm going 
> to address them after the logical bits are complete.
> 
> On Mon, Jan 04, 2016 at 03:05:33PM -0500, Chris Pavlina wrote:
> > Hi,
> > 
> > First step in getting the hotkey configuration inside the main 
> > preferences dialog is to refactor it a bit. This patch:
> > 
> > - Replaces the wxListCtrl with a wxTreeListCtrl, allowing expandable 
> >   categories in a future change.
> > 
> > - Cleans up the code to make HOTKEY_LIST_CTRL function a bit better on 
> >   its own.
> > 
> > - Migrates this dialog as well to TransferData{To,From}Window, use 
> >   matching TransferData{To,From}Control methods on HOTKEY_LIST_CTRL so 
> >   it is easy to embed.
> > 
> > Despite being replaced by a tree-type control, none of the behavior has 
> > been changed yet. The appearance changes slightly due to wxTreeListCtrl 
> > looking a bit different.
> > 
> > --
> > Chris
> > 
commit 1fecbd1bce5cd13edc9c51e88e726dd450944322
Author: Chris Pavlina <cpavlin1@xxxxxxxxxxxxxx>
Date:   Mon Jan 4 17:11:51 2016 -0500

    Pull hotkey editor into eeschema preferences

diff --git a/common/dialogs/dialog_hotkeys_editor.cpp b/common/dialogs/dialog_hotkeys_editor.cpp
index a3c2742..2a387e9 100644
--- a/common/dialogs/dialog_hotkeys_editor.cpp
+++ b/common/dialogs/dialog_hotkeys_editor.cpp
@@ -58,6 +58,18 @@ HOTKEY_LIST_CTRL::HOTKEY_LIST_CTRL( wxWindow *aParent, const HOTKEYS_SECTIONS& a
 }
 
 
+HOTKEYS_SECTIONS HOTKEY_LIST_CTRL::Sections( EDA_HOTKEY_CONFIG* aHotkeys )
+{
+    HOTKEYS_SECTIONS sections;
+    for( EDA_HOTKEY_CONFIG* section = aHotkeys; section->m_HK_InfoList; ++section )
+    {
+        HOTKEYS_SECTION sec( wxGetTranslation( *section->m_Title ), section );
+        sections.push_back( sec );
+    }
+    return sections;
+}
+
+
 void HOTKEY_LIST_CTRL::DeselectRow( int aRow )
 {
     wxASSERT( aRow >= 0 && aRow < m_items.size() );
@@ -112,7 +124,6 @@ void HOTKEY_LIST_CTRL::OnChar( wxKeyEvent& aEvent )
             if( exists && data->GetHotkey().m_KeyCode != key )
             {
                 wxString tag = data->GetSectionTag();
-                HOTKEYS_EDITOR_DIALOG* parent = static_cast<HOTKEYS_EDITOR_DIALOG*>( m_parent );
                 bool canUpdate = ResolveKeyConflicts( key, tag );
 
                 if( canUpdate )
@@ -350,16 +361,7 @@ HOTKEYS_EDITOR_DIALOG::HOTKEYS_EDITOR_DIALOG( EDA_BASE_FRAME*    aParent,
     m_parent( aParent ),
     m_hotkeys( aHotkeys )
 {
-    EDA_HOTKEY_CONFIG* section;
-
-    HOTKEYS_SECTIONS sections;
-    for( section = m_hotkeys; section->m_HK_InfoList; section++ )
-    {
-        HOTKEYS_SECTION sec( wxGetTranslation( *section->m_Title ), section );
-        sections.push_back( sec );
-    }
-
-    m_hotkeyListCtrl = new HOTKEY_LIST_CTRL( this, sections );
+    m_hotkeyListCtrl = new HOTKEY_LIST_CTRL( this, HOTKEY_LIST_CTRL::Sections( aHotkeys ) );
     m_mainSizer->Insert( 1, m_hotkeyListCtrl, wxSizerFlags( 1 ).Expand().Border( wxALL, 5 ) );
     Layout();
 
diff --git a/eeschema/dialogs/dialog_eeschema_options.cpp b/eeschema/dialogs/dialog_eeschema_options.cpp
index c6b0f34..35c68c1 100644
--- a/eeschema/dialogs/dialog_eeschema_options.cpp
+++ b/eeschema/dialogs/dialog_eeschema_options.cpp
@@ -2,7 +2,7 @@
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
  * Copyright (C) 2009 Wayne Stambaugh <stambaughw@xxxxxxxxxxx>
- * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 1992-2016 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
@@ -30,9 +30,23 @@
 #include <class_base_screen.h>
 
 #include <dialog_eeschema_options.h>
+#include <dialog_hotkeys_editor.h>
+#include "../schframe.h"
+#include "hotkeys.h"
 
 #include "wx/settings.h"
 
+/**
+ * Menu IDs for the import/export menu.
+ */
+enum IMP_EXP_MENU_IDS
+{
+    ID_IMPORT_PREFS = 2001,
+    ID_EXPORT_PREFS,
+    ID_IMPORT_HOTKEYS,
+    ID_EXPORT_HOTKEYS
+};
+
 DIALOG_EESCHEMA_OPTIONS::DIALOG_EESCHEMA_OPTIONS( wxWindow* parent ) :
     DIALOG_EESCHEMA_OPTIONS_BASE( parent )
 {
@@ -50,12 +64,65 @@ DIALOG_EESCHEMA_OPTIONS::DIALOG_EESCHEMA_OPTIONS( wxWindow* parent ) :
         m_fieldGrid->AutoSizeColLabelSize( i );
     }
 
+    // Embed the hotkeys list
+    HOTKEYS_SECTIONS sections = HOTKEY_LIST_CTRL::Sections( g_Eeschema_Hokeys_Descr );
+    m_hotkeyListCtrl = new HOTKEY_LIST_CTRL( m_controlsPanel, sections );
+    // Insert after the "Hotkeys:" label
+    m_controlsSizer->Insert( 1, m_hotkeyListCtrl, wxSizerFlags( 1 ).Expand().Border( wxALL, 5 ) );
+    Layout();
+
+    // Bind event for the import/export menu
+    Bind( wxEVT_MENU, &DIALOG_EESCHEMA_OPTIONS::OnMenu, this );
+
     // Make sure we select the first tab of the options tab page
     m_notebook->SetSelection( 0 );
 
 }
 
 
+void DIALOG_EESCHEMA_OPTIONS::OnImpExpClick( wxCommandEvent& aEvent )
+{
+    wxMenu menu;
+
+    menu.Append( ID_IMPORT_PREFS, _( "Import Preferences" ) );
+    menu.Append( ID_EXPORT_PREFS, _( "Export Preferences" ) );
+
+    menu.Append( wxID_SEPARATOR );
+    menu.Append( ID_IMPORT_HOTKEYS, _( "Import Hotkeys" ) );
+    menu.Append( ID_EXPORT_HOTKEYS, _( "Export Hotkeys" ) );
+
+    int btnw, btnh;
+    m_btnImpExp->GetSize( &btnw, &btnh );
+    m_btnImpExp->PopupMenu( &menu, wxPoint( 0, btnh ) );
+}
+
+
+void DIALOG_EESCHEMA_OPTIONS::OnMenu( wxCommandEvent& aEvent )
+{
+    switch( aEvent.GetId() )
+    {
+    case ID_IMPORT_PREFS:
+        aEvent.SetId( ID_CONFIG_READ );
+        static_cast<SCH_EDIT_FRAME*>( m_parent )->Process_Config( aEvent );
+        break;
+    case ID_EXPORT_PREFS:
+        aEvent.SetId( ID_CONFIG_SAVE );
+        static_cast<SCH_EDIT_FRAME*>( m_parent )->Process_Config( aEvent );
+        break;
+    case ID_IMPORT_HOTKEYS:
+        aEvent.SetId( ID_PREFERENCES_HOTKEY_IMPORT_CONFIG );
+        static_cast<SCH_EDIT_FRAME*>( m_parent )->Process_Config( aEvent );
+        break;
+    case ID_EXPORT_HOTKEYS:
+        aEvent.SetId( ID_PREFERENCES_HOTKEY_EXPORT_CONFIG );
+        static_cast<SCH_EDIT_FRAME*>( m_parent )->Process_Config( aEvent );
+        break;
+    default:
+        wxFAIL_MSG("Unexpected menu ID");
+    }
+}
+
+
 void DIALOG_EESCHEMA_OPTIONS::SetUnits( const wxArrayString& units, int select )
 {
     wxASSERT( units.GetCount() > 0
@@ -217,6 +284,9 @@ bool DIALOG_EESCHEMA_OPTIONS::TransferDataToWindow()
     if( !wxDialog::TransferDataToWindow() )
         return false;
 
+    if( !m_hotkeyListCtrl->TransferDataToControl() )
+        return false;
+
     m_fieldGrid->Freeze();
     if( m_fieldGrid->GetNumberRows() )
         m_fieldGrid->DeleteRows( 0, m_fieldGrid->GetNumberRows() );
@@ -247,6 +317,12 @@ bool DIALOG_EESCHEMA_OPTIONS::TransferDataToWindow()
 
 bool DIALOG_EESCHEMA_OPTIONS::TransferDataFromWindow()
 {
+    if( ! wxDialog::TransferDataFromWindow() )
+        return false;
+
+    if( !m_hotkeyListCtrl->TransferDataFromControl() )
+        return false;
+
     for( int row = 0; row < m_fieldGrid->GetNumberRows(); ++row )
     {
         templateFields[row].m_Name = m_fieldGrid->GetCellValue( row, 0 );
diff --git a/eeschema/dialogs/dialog_eeschema_options.h b/eeschema/dialogs/dialog_eeschema_options.h
index 828d1b0..2235b0e 100644
--- a/eeschema/dialogs/dialog_eeschema_options.h
+++ b/eeschema/dialogs/dialog_eeschema_options.h
@@ -2,7 +2,7 @@
  * This program source code file is part of KiCad, a free EDA CAD application.
  *
  * Copyright (C) 2009 Wayne Stambaugh <stambaughw@xxxxxxxxxxx>
- * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 1992-2016 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
@@ -34,13 +34,29 @@
 #include <dialog_eeschema_options_base.h>
 #include <template_fieldnames.h>
 
+class HOTKEY_LIST_CTRL;
+
 class DIALOG_EESCHEMA_OPTIONS : public DIALOG_EESCHEMA_OPTIONS_BASE
 {
 protected:
+    HOTKEY_LIST_CTRL* m_hotkeyListCtrl;
+
     /** @brief The template fieldnames for this dialog */
     TEMPLATE_FIELDNAMES templateFields;
 
     /**
+     * Function OnImpExpClick
+     * Display the settings import/export menu.
+     */
+    void OnImpExpClick( wxCommandEvent& aEvent );
+
+    /**
+     * Function OnMenu
+     * Handle menu clicks (for import/export)
+     */
+    void OnMenu( wxCommandEvent& aEvent );
+
+    /**
      * Function OnAddButtonClick
      * Process the wxWidgets @a event produced when the user presses the Add buton for the
      * template fieldnames control
diff --git a/eeschema/dialogs/dialog_eeschema_options_base.cpp b/eeschema/dialogs/dialog_eeschema_options_base.cpp
index b744d8d..14477ef 100644
--- a/eeschema/dialogs/dialog_eeschema_options_base.cpp
+++ b/eeschema/dialogs/dialog_eeschema_options_base.cpp
@@ -15,6 +15,7 @@ BEGIN_EVENT_TABLE( DIALOG_EESCHEMA_OPTIONS_BASE, DIALOG_SHIM )
 	EVT_CHECKBOX( xwID_ANY, DIALOG_EESCHEMA_OPTIONS_BASE::_wxFB_OnMiddleBtnPanEnbl )
 	EVT_BUTTON( wxID_ADD_FIELD, DIALOG_EESCHEMA_OPTIONS_BASE::_wxFB_OnAddButtonClick )
 	EVT_BUTTON( wxID_DELETE_FIELD, DIALOG_EESCHEMA_OPTIONS_BASE::_wxFB_OnDeleteButtonClick )
+	EVT_BUTTON( ID_IMP_EXP, DIALOG_EESCHEMA_OPTIONS_BASE::_wxFB_OnImpExpClick )
 END_EVENT_TABLE()
 
 DIALOG_EESCHEMA_OPTIONS_BASE::DIALOG_EESCHEMA_OPTIONS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
@@ -117,7 +118,7 @@ DIALOG_EESCHEMA_OPTIONS_BASE::DIALOG_EESCHEMA_OPTIONS_BASE( wxWindow* parent, wx
 	m_panel5->SetSizer( bSizer82 );
 	m_panel5->Layout();
 	bSizer82->Fit( m_panel5 );
-	m_notebook->AddPage( m_panel5, _("Display"), true );
+	m_notebook->AddPage( m_panel5, _("Display"), false );
 	m_panel3 = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
 	wxBoxSizer* bSizer8;
 	bSizer8 = new wxBoxSizer( wxVERTICAL );
@@ -233,7 +234,7 @@ DIALOG_EESCHEMA_OPTIONS_BASE::DIALOG_EESCHEMA_OPTIONS_BASE( wxWindow* parent, wx
 	m_panel3->Layout();
 	bSizer8->Fit( m_panel3 );
 	m_notebook->AddPage( m_panel3, _("Editing"), false );
-	m_panel4 = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+	m_controlsPanel = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
 	wxBoxSizer* bSizer81;
 	bSizer81 = new wxBoxSizer( wxVERTICAL );
 	
@@ -248,35 +249,38 @@ DIALOG_EESCHEMA_OPTIONS_BASE::DIALOG_EESCHEMA_OPTIONS_BASE( wxWindow* parent, wx
 	
 	bSizer81->Add( fgSizer31, 0, wxALL|wxEXPAND, 5 );
 	
-	wxBoxSizer* bSizer91;
-	bSizer91 = new wxBoxSizer( wxVERTICAL );
+	m_controlsSizer = new wxBoxSizer( wxVERTICAL );
 	
-	m_checkEnableZoomCenter = new wxCheckBox( m_panel4, wxID_ANY, _("Cen&ter and warp cursor on zoom"), wxDefaultPosition, wxDefaultSize, 0 );
+	m_staticText20 = new wxStaticText( m_controlsPanel, wxID_ANY, _("Hotkeys:"), wxDefaultPosition, wxDefaultSize, 0 );
+	m_staticText20->Wrap( -1 );
+	m_controlsSizer->Add( m_staticText20, 0, wxALL, 5 );
+	
+	m_checkEnableZoomCenter = new wxCheckBox( m_controlsPanel, wxID_ANY, _("Cen&ter and warp cursor on zoom"), wxDefaultPosition, wxDefaultSize, 0 );
 	m_checkEnableZoomCenter->SetToolTip( _("Keep the cursor at its current location when zooming") );
 	
-	bSizer91->Add( m_checkEnableZoomCenter, 0, wxTOP|wxRIGHT|wxLEFT, 3 );
+	m_controlsSizer->Add( m_checkEnableZoomCenter, 0, wxTOP|wxRIGHT|wxLEFT, 3 );
 	
-	m_checkEnableMiddleButtonPan = new wxCheckBox( m_panel4, xwID_ANY, _("&Use middle mouse button to pan"), wxDefaultPosition, wxDefaultSize, 0 );
+	m_checkEnableMiddleButtonPan = new wxCheckBox( m_controlsPanel, xwID_ANY, _("&Use middle mouse button to pan"), wxDefaultPosition, wxDefaultSize, 0 );
 	m_checkEnableMiddleButtonPan->SetToolTip( _("Use middle mouse button dragging to pan") );
 	
-	bSizer91->Add( m_checkEnableMiddleButtonPan, 0, wxTOP|wxRIGHT|wxLEFT, 3 );
+	m_controlsSizer->Add( m_checkEnableMiddleButtonPan, 0, wxTOP|wxRIGHT|wxLEFT, 3 );
 	
-	m_checkMiddleButtonPanLimited = new wxCheckBox( m_panel4, wxID_ANY, _("&Limit panning to scroll size"), wxDefaultPosition, wxDefaultSize, 0 );
+	m_checkMiddleButtonPanLimited = new wxCheckBox( m_controlsPanel, wxID_ANY, _("&Limit panning to scroll size"), wxDefaultPosition, wxDefaultSize, 0 );
 	m_checkMiddleButtonPanLimited->SetToolTip( _("Middle mouse button panning limited by current scrollbar size") );
 	
-	bSizer91->Add( m_checkMiddleButtonPanLimited, 0, wxTOP|wxRIGHT|wxLEFT, 3 );
+	m_controlsSizer->Add( m_checkMiddleButtonPanLimited, 0, wxTOP|wxRIGHT|wxLEFT, 3 );
 	
-	m_checkAutoPan = new wxCheckBox( m_panel4, wxID_ANY, _("&Pan while moving object"), wxDefaultPosition, wxDefaultSize, 0 );
-	bSizer91->Add( m_checkAutoPan, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 3 );
+	m_checkAutoPan = new wxCheckBox( m_controlsPanel, wxID_ANY, _("&Pan while moving object"), wxDefaultPosition, wxDefaultSize, 0 );
+	m_controlsSizer->Add( m_checkAutoPan, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 3 );
 	
 	
-	bSizer81->Add( bSizer91, 0, wxALL|wxEXPAND, 5 );
+	bSizer81->Add( m_controlsSizer, 1, wxALL|wxEXPAND, 5 );
 	
 	
-	m_panel4->SetSizer( bSizer81 );
-	m_panel4->Layout();
-	bSizer81->Fit( m_panel4 );
-	m_notebook->AddPage( m_panel4, _("Co&ntrols"), false );
+	m_controlsPanel->SetSizer( bSizer81 );
+	m_controlsPanel->Layout();
+	bSizer81->Fit( m_controlsPanel );
+	m_notebook->AddPage( m_controlsPanel, _("Co&ntrols"), false );
 	m_panel2 = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
 	m_panel2->SetToolTip( _("User defined field names for schematic components. ") );
 	
@@ -342,10 +346,16 @@ DIALOG_EESCHEMA_OPTIONS_BASE::DIALOG_EESCHEMA_OPTIONS_BASE( wxWindow* parent, wx
 	m_panel2->SetSizer( bSizer6 );
 	m_panel2->Layout();
 	bSizer6->Fit( m_panel2 );
-	m_notebook->AddPage( m_panel2, _("Default &Fields"), false );
+	m_notebook->AddPage( m_panel2, _("Default &Fields"), true );
 	
 	bOptionsSizer->Add( m_notebook, 1, wxALL|wxEXPAND, 5 );
 	
+	wxBoxSizer* bSizer12;
+	bSizer12 = new wxBoxSizer( wxHORIZONTAL );
+	
+	m_btnImpExp = new wxButton( this, ID_IMP_EXP, _("Import/Export..."), wxDefaultPosition, wxDefaultSize, 0 );
+	bSizer12->Add( m_btnImpExp, 0, wxALL, 5 );
+	
 	m_sdbSizer = new wxStdDialogButtonSizer();
 	m_sdbSizerOK = new wxButton( this, wxID_OK );
 	m_sdbSizer->AddButton( m_sdbSizerOK );
@@ -353,7 +363,10 @@ DIALOG_EESCHEMA_OPTIONS_BASE::DIALOG_EESCHEMA_OPTIONS_BASE( wxWindow* parent, wx
 	m_sdbSizer->AddButton( m_sdbSizerCancel );
 	m_sdbSizer->Realize();
 	
-	bOptionsSizer->Add( m_sdbSizer, 0, wxALL|wxEXPAND, 6 );
+	bSizer12->Add( m_sdbSizer, 1, wxALL|wxEXPAND, 5 );
+	
+	
+	bOptionsSizer->Add( bSizer12, 0, wxEXPAND, 5 );
 	
 	
 	mainSizer->Add( bOptionsSizer, 1, wxEXPAND, 12 );
diff --git a/eeschema/dialogs/dialog_eeschema_options_base.fbp b/eeschema/dialogs/dialog_eeschema_options_base.fbp
index 7a24be7..4e6d113 100644
--- a/eeschema/dialogs/dialog_eeschema_options_base.fbp
+++ b/eeschema/dialogs/dialog_eeschema_options_base.fbp
@@ -106,7 +106,7 @@
                             <property name="border">5</property>
                             <property name="flag">wxALL|wxEXPAND</property>
                             <property name="proportion">1</property>
-                            <object class="wxNotebook" expanded="1">
+                            <object class="wxNotebook" expanded="0">
                                 <property name="BottomDockable">1</property>
                                 <property name="LeftDockable">1</property>
                                 <property name="RightDockable">1</property>
@@ -184,11 +184,11 @@
                                 <event name="OnSetFocus"></event>
                                 <event name="OnSize"></event>
                                 <event name="OnUpdateUI"></event>
-                                <object class="notebookpage" expanded="1">
+                                <object class="notebookpage" expanded="0">
                                     <property name="bitmap"></property>
                                     <property name="label">Display</property>
-                                    <property name="select">1</property>
-                                    <object class="wxPanel" expanded="1">
+                                    <property name="select">0</property>
+                                    <object class="wxPanel" expanded="0">
                                         <property name="BottomDockable">1</property>
                                         <property name="LeftDockable">1</property>
                                         <property name="RightDockable">1</property>
@@ -262,16 +262,16 @@
                                         <event name="OnSetFocus"></event>
                                         <event name="OnSize"></event>
                                         <event name="OnUpdateUI"></event>
-                                        <object class="wxBoxSizer" expanded="1">
+                                        <object class="wxBoxSizer" expanded="0">
                                             <property name="minimum_size"></property>
                                             <property name="name">bSizer82</property>
                                             <property name="orient">wxVERTICAL</property>
                                             <property name="permission">none</property>
-                                            <object class="sizeritem" expanded="1">
+                                            <object class="sizeritem" expanded="0">
                                                 <property name="border">5</property>
                                                 <property name="flag">wxALL|wxEXPAND</property>
                                                 <property name="proportion">0</property>
-                                                <object class="wxFlexGridSizer" expanded="1">
+                                                <object class="wxFlexGridSizer" expanded="0">
                                                     <property name="cols">3</property>
                                                     <property name="flexible_direction">wxBOTH</property>
                                                     <property name="growablecols">0,1,2</property>
@@ -1675,11 +1675,11 @@
                                         </object>
                                     </object>
                                 </object>
-                                <object class="notebookpage" expanded="1">
+                                <object class="notebookpage" expanded="0">
                                     <property name="bitmap"></property>
                                     <property name="label">Editing</property>
                                     <property name="select">0</property>
-                                    <object class="wxPanel" expanded="1">
+                                    <object class="wxPanel" expanded="0">
                                         <property name="BottomDockable">1</property>
                                         <property name="LeftDockable">1</property>
                                         <property name="RightDockable">1</property>
@@ -1753,16 +1753,16 @@
                                         <event name="OnSetFocus"></event>
                                         <event name="OnSize"></event>
                                         <event name="OnUpdateUI"></event>
-                                        <object class="wxBoxSizer" expanded="1">
+                                        <object class="wxBoxSizer" expanded="0">
                                             <property name="minimum_size"></property>
                                             <property name="name">bSizer8</property>
                                             <property name="orient">wxVERTICAL</property>
                                             <property name="permission">none</property>
-                                            <object class="sizeritem" expanded="1">
+                                            <object class="sizeritem" expanded="0">
                                                 <property name="border">5</property>
                                                 <property name="flag">wxALL|wxEXPAND</property>
                                                 <property name="proportion">0</property>
-                                                <object class="wxFlexGridSizer" expanded="1">
+                                                <object class="wxFlexGridSizer" expanded="0">
                                                     <property name="cols">3</property>
                                                     <property name="flexible_direction">wxBOTH</property>
                                                     <property name="growablecols">0,1,2</property>
@@ -3069,11 +3069,11 @@
                                                             <event name="OnUpdateUI"></event>
                                                         </object>
                                                     </object>
-                                                    <object class="sizeritem" expanded="1">
+                                                    <object class="sizeritem" expanded="0">
                                                         <property name="border">3</property>
                                                         <property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT</property>
                                                         <property name="proportion">0</property>
-                                                        <object class="wxStaticText" expanded="1">
+                                                        <object class="wxStaticText" expanded="0">
                                                             <property name="BottomDockable">1</property>
                                                             <property name="LeftDockable">1</property>
                                                             <property name="RightDockable">1</property>
@@ -3767,11 +3767,11 @@
                                         </object>
                                     </object>
                                 </object>
-                                <object class="notebookpage" expanded="1">
+                                <object class="notebookpage" expanded="0">
                                     <property name="bitmap"></property>
                                     <property name="label">Co&amp;ntrols</property>
                                     <property name="select">0</property>
-                                    <object class="wxPanel" expanded="1">
+                                    <object class="wxPanel" expanded="0">
                                         <property name="BottomDockable">1</property>
                                         <property name="LeftDockable">1</property>
                                         <property name="RightDockable">1</property>
@@ -3806,7 +3806,7 @@
                                         <property name="minimize_button">0</property>
                                         <property name="minimum_size"></property>
                                         <property name="moveable">1</property>
-                                        <property name="name">m_panel4</property>
+                                        <property name="name">m_controlsPanel</property>
                                         <property name="pane_border">1</property>
                                         <property name="pane_position"></property>
                                         <property name="pane_size"></property>
@@ -3845,16 +3845,16 @@
                                         <event name="OnSetFocus"></event>
                                         <event name="OnSize"></event>
                                         <event name="OnUpdateUI"></event>
-                                        <object class="wxBoxSizer" expanded="1">
+                                        <object class="wxBoxSizer" expanded="0">
                                             <property name="minimum_size"></property>
                                             <property name="name">bSizer81</property>
                                             <property name="orient">wxVERTICAL</property>
                                             <property name="permission">none</property>
-                                            <object class="sizeritem" expanded="1">
+                                            <object class="sizeritem" expanded="0">
                                                 <property name="border">5</property>
                                                 <property name="flag">wxALL|wxEXPAND</property>
                                                 <property name="proportion">0</property>
-                                                <object class="wxFlexGridSizer" expanded="1">
+                                                <object class="wxFlexGridSizer" expanded="0">
                                                     <property name="cols">3</property>
                                                     <property name="flexible_direction">wxBOTH</property>
                                                     <property name="growablecols">0,1,2</property>
@@ -3871,12 +3871,95 @@
                                             <object class="sizeritem" expanded="0">
                                                 <property name="border">5</property>
                                                 <property name="flag">wxALL|wxEXPAND</property>
-                                                <property name="proportion">0</property>
+                                                <property name="proportion">1</property>
                                                 <object class="wxBoxSizer" expanded="0">
                                                     <property name="minimum_size"></property>
-                                                    <property name="name">bSizer91</property>
+                                                    <property name="name">m_controlsSizer</property>
                                                     <property name="orient">wxVERTICAL</property>
-                                                    <property name="permission">none</property>
+                                                    <property name="permission">protected</property>
+                                                    <object class="sizeritem" expanded="0">
+                                                        <property name="border">5</property>
+                                                        <property name="flag">wxALL</property>
+                                                        <property name="proportion">0</property>
+                                                        <object class="wxStaticText" expanded="0">
+                                                            <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">Hotkeys:</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_staticText20</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="0">
                                                         <property name="border">3</property>
                                                         <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
@@ -4234,11 +4317,11 @@
                                         </object>
                                     </object>
                                 </object>
-                                <object class="notebookpage" expanded="1">
+                                <object class="notebookpage" expanded="0">
                                     <property name="bitmap"></property>
                                     <property name="label">Default &amp;Fields</property>
-                                    <property name="select">0</property>
-                                    <object class="wxPanel" expanded="1">
+                                    <property name="select">1</property>
+                                    <object class="wxPanel" expanded="0">
                                         <property name="BottomDockable">1</property>
                                         <property name="LeftDockable">1</property>
                                         <property name="RightDockable">1</property>
@@ -4312,25 +4395,25 @@
                                         <event name="OnSetFocus"></event>
                                         <event name="OnSize"></event>
                                         <event name="OnUpdateUI"></event>
-                                        <object class="wxBoxSizer" expanded="1">
+                                        <object class="wxBoxSizer" expanded="0">
                                             <property name="minimum_size"></property>
                                             <property name="name">bSizer6</property>
                                             <property name="orient">wxHORIZONTAL</property>
                                             <property name="permission">none</property>
-                                            <object class="sizeritem" expanded="1">
+                                            <object class="sizeritem" expanded="0">
                                                 <property name="border">5</property>
                                                 <property name="flag">wxEXPAND</property>
                                                 <property name="proportion">1</property>
-                                                <object class="wxBoxSizer" expanded="1">
+                                                <object class="wxBoxSizer" expanded="0">
                                                     <property name="minimum_size"></property>
                                                     <property name="name">bSizer11</property>
                                                     <property name="orient">wxVERTICAL</property>
                                                     <property name="permission">none</property>
-                                                    <object class="sizeritem" expanded="1">
+                                                    <object class="sizeritem" expanded="0">
                                                         <property name="border">5</property>
                                                         <property name="flag">wxALL|wxEXPAND</property>
                                                         <property name="proportion">1</property>
-                                                        <object class="wxGrid" expanded="1">
+                                                        <object class="wxGrid" expanded="0">
                                                             <property name="BottomDockable">1</property>
                                                             <property name="LeftDockable">1</property>
                                                             <property name="RightDockable">1</property>
@@ -4471,7 +4554,7 @@
                                                     </object>
                                                 </object>
                                             </object>
-                                            <object class="sizeritem" expanded="1">
+                                            <object class="sizeritem" expanded="0">
                                                 <property name="border">5</property>
                                                 <property name="flag">wxEXPAND</property>
                                                 <property name="proportion">0</property>
@@ -4673,30 +4756,129 @@
                                 </object>
                             </object>
                         </object>
-                        <object class="sizeritem" expanded="0">
-                            <property name="border">6</property>
-                            <property name="flag">wxALL|wxEXPAND</property>
+                        <object class="sizeritem" expanded="1">
+                            <property name="border">5</property>
+                            <property name="flag">wxEXPAND</property>
                             <property name="proportion">0</property>
-                            <object class="wxStdDialogButtonSizer" expanded="0">
-                                <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>
+                            <object class="wxBoxSizer" expanded="1">
                                 <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"></event>
-                                <event name="OnSaveButtonClick"></event>
-                                <event name="OnYesButtonClick"></event>
+                                <property name="name">bSizer12</property>
+                                <property name="orient">wxHORIZONTAL</property>
+                                <property name="permission">none</property>
+                                <object class="sizeritem" expanded="1">
+                                    <property name="border">5</property>
+                                    <property name="flag">wxALL</property>
+                                    <property name="proportion">0</property>
+                                    <object class="wxButton" 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">0</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">ID_IMP_EXP</property>
+                                        <property name="label">Import/Export...</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_btnImpExp</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="window_extra_style"></property>
+                                        <property name="window_name"></property>
+                                        <property name="window_style"></property>
+                                        <event name="OnButtonClick">OnImpExpClick</event>
+                                        <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="0">
+                                    <property name="border">5</property>
+                                    <property name="flag">wxALL|wxEXPAND</property>
+                                    <property name="proportion">1</property>
+                                    <object class="wxStdDialogButtonSizer" expanded="0">
+                                        <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"></event>
+                                        <event name="OnSaveButtonClick"></event>
+                                        <event name="OnYesButtonClick"></event>
+                                    </object>
+                                </object>
                             </object>
                         </object>
                     </object>
diff --git a/eeschema/dialogs/dialog_eeschema_options_base.h b/eeschema/dialogs/dialog_eeschema_options_base.h
index 585d442..c55066c 100644
--- a/eeschema/dialogs/dialog_eeschema_options_base.h
+++ b/eeschema/dialogs/dialog_eeschema_options_base.h
@@ -50,6 +50,7 @@ class DIALOG_EESCHEMA_OPTIONS_BASE : public DIALOG_SHIM
 		void _wxFB_OnMiddleBtnPanEnbl( wxCommandEvent& event ){ OnMiddleBtnPanEnbl( event ); }
 		void _wxFB_OnAddButtonClick( wxCommandEvent& event ){ OnAddButtonClick( event ); }
 		void _wxFB_OnDeleteButtonClick( wxCommandEvent& event ){ OnDeleteButtonClick( event ); }
+		void _wxFB_OnImpExpClick( wxCommandEvent& event ){ OnImpExpClick( event ); }
 		
 	
 	protected:
@@ -58,7 +59,8 @@ class DIALOG_EESCHEMA_OPTIONS_BASE : public DIALOG_SHIM
 			ID_M_SPINAUTOSAVEINTERVAL = 1000,
 			xwID_ANY,
 			wxID_ADD_FIELD,
-			wxID_DELETE_FIELD
+			wxID_DELETE_FIELD,
+			ID_IMP_EXP
 		};
 		
 		wxNotebook* m_notebook;
@@ -103,7 +105,9 @@ class DIALOG_EESCHEMA_OPTIONS_BASE : public DIALOG_SHIM
 		wxCheckBox* m_checkAutoplaceFields;
 		wxCheckBox* m_checkAutoplaceJustify;
 		wxCheckBox* m_checkAutoplaceAlign;
-		wxPanel* m_panel4;
+		wxPanel* m_controlsPanel;
+		wxBoxSizer* m_controlsSizer;
+		wxStaticText* m_staticText20;
 		wxCheckBox* m_checkEnableZoomCenter;
 		wxCheckBox* m_checkEnableMiddleButtonPan;
 		wxCheckBox* m_checkMiddleButtonPanLimited;
@@ -112,6 +116,7 @@ class DIALOG_EESCHEMA_OPTIONS_BASE : public DIALOG_SHIM
 		wxGrid* m_fieldGrid;
 		wxButton* addFieldButton;
 		wxButton* deleteFieldButton;
+		wxButton* m_btnImpExp;
 		wxStdDialogButtonSizer* m_sdbSizer;
 		wxButton* m_sdbSizerOK;
 		wxButton* m_sdbSizerCancel;
@@ -122,6 +127,7 @@ class DIALOG_EESCHEMA_OPTIONS_BASE : public DIALOG_SHIM
 		virtual void OnMiddleBtnPanEnbl( wxCommandEvent& event ) { event.Skip(); }
 		virtual void OnAddButtonClick( wxCommandEvent& event ) { event.Skip(); }
 		virtual void OnDeleteButtonClick( wxCommandEvent& event ) { event.Skip(); }
+		virtual void OnImpExpClick( wxCommandEvent& event ) { event.Skip(); }
 		
 	
 	public:
diff --git a/eeschema/menubar.cpp b/eeschema/menubar.cpp
index 0baaa1e..2836cdc 100644
--- a/eeschema/menubar.cpp
+++ b/eeschema/menubar.cpp
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
  * Copyright (C) 2009-2014 Wayne Stambaugh <stambaughw@xxxxxxxxxxx>
- * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 1992-2016 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
@@ -398,24 +398,6 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
     // Language submenu
     Pgm().AddMenuLanguageList( preferencesMenu );
 
-    // Hotkey submenu
-    AddHotkeyConfigMenu( preferencesMenu );
-
-    // Separator
-    preferencesMenu->AppendSeparator();
-
-    AddMenuItem( preferencesMenu,
-                 ID_CONFIG_SAVE,
-                 _( "&Save Preferences" ),
-                 _( "Save application preferences" ),
-                 KiBitmap( save_setup_xpm ) );
-
-    AddMenuItem( preferencesMenu,
-                 ID_CONFIG_READ,
-                 _( "Load Prefe&rences" ),
-                 _( "Load application preferences" ),
-                 KiBitmap( read_setup_xpm ) );
-
     // Menu Tools:
     wxMenu* toolsMenu = new wxMenu;
 
diff --git a/include/dialog_hotkeys_editor.h b/include/dialog_hotkeys_editor.h
index c0da682..072a747 100644
--- a/include/dialog_hotkeys_editor.h
+++ b/include/dialog_hotkeys_editor.h
@@ -64,6 +64,8 @@ class DIALOG_HOTKEY_CLIENT_DATA;
 class HOTKEY_LIST_CTRL : public wxTreeListCtrl
 {
 public:
+    static HOTKEYS_SECTIONS Sections( EDA_HOTKEY_CONFIG* aHotkeys );
+
     HOTKEY_LIST_CTRL( wxWindow* aParent, const HOTKEYS_SECTIONS& aSections );
     ~HOTKEY_LIST_CTRL() {};
 

Follow ups

References