kicad-developers team mailing list archive
-
kicad-developers team
-
Mailing list archive
-
Message #22313
[PATCH] Refactor hotkeys editor dialog
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 b1f867eebb7440551b8b2570fe7166348d632828
Author: Chris Pavlina <cpavlin1@xxxxxxxxxxxxxx>
Date: Sun Jan 3 21:48:30 2016 -0500
Refactor hotkeys editor
diff --git a/common/dialogs/dialog_hotkeys_editor.cpp b/common/dialogs/dialog_hotkeys_editor.cpp
index 0dfedf2..719acc8 100644
--- a/common/dialogs/dialog_hotkeys_editor.cpp
+++ b/common/dialogs/dialog_hotkeys_editor.cpp
@@ -1,11 +1,7 @@
-/**
- * @file dialog_hotkeys_editor.cpp
- */
-
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
- * Copyright (C) 1992-2014 Kicad Developers, see CHANGELOG.TXT for contributors.
+ * Copyright (C) 1992-2016 Kicad Developers, see CHANGELOG.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
@@ -32,124 +28,64 @@
#include <common.h>
#include <confirm.h>
+#include <wx/dataview.h>
+
#include <dialog_hotkeys_editor.h>
-HOTKEY_LIST_CTRL::HOTKEY_LIST_CTRL( wxWindow *aParent, struct EDA_HOTKEY_CONFIG* aSection ) :
- wxListCtrl( aParent, wxID_ANY, wxDefaultPosition,
- wxDefaultSize, wxLC_HRULES|wxLC_REPORT|wxLC_SINGLE_SEL|wxLC_VIRTUAL )
+class DIALOG_HOTKEY_CLIENT_DATA : public wxClientData
{
- m_sectionTag = aSection->m_SectionTag;
- m_curEditingRow = -1;
+ EDA_HOTKEY m_hotkey;
+ wxString m_section_tag;
- InsertColumn( 0, _( "Command" ) );
- InsertColumn( 1, _( "Hotkey" ) );
+public:
+ DIALOG_HOTKEY_CLIENT_DATA( const EDA_HOTKEY& aHotkey, const wxString& aSectionTag )
+ : m_hotkey( aHotkey ), m_section_tag( aSectionTag ) {}
- // Add a dummy hotkey_spec which is a header before each hotkey list
- EDA_HOTKEY** hotkey_descr_list;
+ EDA_HOTKEY& GetHotkey() { return m_hotkey; }
+ wxString GetSectionTag() const { return m_section_tag; }
+};
- // Add a copy of hotkeys to our list
- for( hotkey_descr_list = aSection->m_HK_InfoList; *hotkey_descr_list; hotkey_descr_list++ )
- {
- EDA_HOTKEY* hotkey_descr = *hotkey_descr_list;
- m_hotkeys.push_back( new EDA_HOTKEY( hotkey_descr ) );
- }
- // Set item count to hotkey size, this gets it to autoload the entries
- SetItemCount( m_hotkeys.size() );
+HOTKEY_LIST_CTRL::HOTKEY_LIST_CTRL( wxWindow *aParent, const HOTKEYS_SECTIONS& aSections ) :
+ wxTreeListCtrl( aParent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTL_SINGLE ),
+ m_sections( aSections )
+{
+ AppendColumn( _( "Command" ) );
+ AppendColumn( _( "Hotkey" ) );
- SetColumnWidth( 0, wxLIST_AUTOSIZE );
- SetColumnWidth( 1, wxLIST_AUTOSIZE );
+ SetColumnWidth( 1, 100 );
Bind( wxEVT_CHAR, &HOTKEY_LIST_CTRL::OnChar, this );
- Bind( wxEVT_LIST_ITEM_SELECTED, &HOTKEY_LIST_CTRL::OnListItemSelected, this );
Bind( wxEVT_SIZE, &HOTKEY_LIST_CTRL::OnSize, this );
}
void HOTKEY_LIST_CTRL::OnSize( wxSizeEvent& aEvent )
{
- recalculateColumns();
aEvent.Skip();
}
-void HOTKEY_LIST_CTRL::recalculateColumns()
-{
- float totalLength = 0;
- float scale = 0;
-
- // Find max character length of first column
- int maxInfoMsgLength = 0;
-
- for( int i = 0; i < GetItemCount(); i++ )
- {
- int length = GetItemText( i, 0 ).Length();
-
- if( length > maxInfoMsgLength )
- maxInfoMsgLength = length;
- }
-
- // Find max character length of second column
- int maxKeyCodeLength = 0;
-
- for( int i = 0; i < GetItemCount(); i++ )
- {
- int length = GetItemText( i, 1 ).Length();
- if( length > maxKeyCodeLength )
- maxKeyCodeLength = length;
- }
-
- // Use the lengths of column texts to create a scale of the max list width
- // to set the column widths
- totalLength = maxInfoMsgLength + maxKeyCodeLength;
-
- scale = (double) GetClientSize().x / totalLength;
-
- SetColumnWidth( 0, int( maxInfoMsgLength*scale ) - 2 );
- SetColumnWidth( 1, int( maxKeyCodeLength*scale ) );
-}
-
-
-void HOTKEY_LIST_CTRL::OnListItemSelected( wxListEvent& aEvent )
-{
- m_curEditingRow = aEvent.GetIndex();
-}
-
-
void HOTKEY_LIST_CTRL::DeselectRow( int aRow )
{
- SetItemState( aRow, 0, wxLIST_STATE_SELECTED );
-}
-
-
-wxString HOTKEY_LIST_CTRL::OnGetItemText( long aRow, long aColumn ) const
-{
- EDA_HOTKEY* hotkey_descr = m_hotkeys[aRow];
-
- if( aColumn == 0 )
- {
- return wxGetTranslation( hotkey_descr->m_InfoMsg );
- }
- else
- {
- return KeyNameFromKeyCode( hotkey_descr->m_KeyCode );
- }
+ wxASSERT( aRow >= 0 && aRow < m_items.size() );
+ Unselect( m_items[aRow] );
}
void HOTKEY_LIST_CTRL::OnChar( wxKeyEvent& aEvent )
{
- if( m_curEditingRow != -1 )
+ DIALOG_HOTKEY_CLIENT_DATA* data = GetSelHKClientData();
+
+ if( data )
{
long key = aEvent.GetKeyCode();
switch( key )
{
case WXK_ESCAPE:
- // Remove selection
- DeselectRow( m_curEditingRow );
- m_curEditingRow = -1;
+ UnselectAll();
break;
default:
@@ -182,43 +118,185 @@ void HOTKEY_LIST_CTRL::OnChar( wxKeyEvent& aEvent )
bool exists;
KeyNameFromKeyCode( key, &exists );
- if( exists && m_hotkeys[m_curEditingRow]->m_KeyCode != key )
+ if( exists && data->GetHotkey().m_KeyCode != key )
{
- bool canUpdate = ((HOTKEY_SECTION_PAGE *)m_parent)->GetDialog()->CanSetKey( key, m_sectionTag );
+ wxString tag = data->GetSectionTag();
+ HOTKEY_SECTION_PAGE* parent = static_cast<HOTKEY_SECTION_PAGE*>( m_parent );
+ bool canUpdate = parent->GetDialog()->CanSetKey( key, tag );
if( canUpdate )
{
- m_hotkeys[m_curEditingRow]->m_KeyCode = key;
- recalculateColumns();
+ data->GetHotkey().m_KeyCode = key;
}
// Remove selection
- DeselectRow( m_curEditingRow );
- m_curEditingRow = -1;
+ UnselectAll();
}
}
}
- RefreshItems(0,m_hotkeys.size()-1);
+ UpdateFromClientData();
}
-void HOTKEY_LIST_CTRL::RestoreFrom( struct EDA_HOTKEY_CONFIG* aSection )
+DIALOG_HOTKEY_CLIENT_DATA* HOTKEY_LIST_CTRL::GetSelHKClientData()
{
- int row = 0;
+ return GetHKClientData( GetSelection() );
+}
+
+
+DIALOG_HOTKEY_CLIENT_DATA* HOTKEY_LIST_CTRL::GetHKClientData( wxTreeListItem aItem )
+{
+ if( aItem.IsOk() )
+ {
+ wxClientData* data = GetItemData( aItem );
+ if( !data )
+ return NULL;
+
+ DIALOG_HOTKEY_CLIENT_DATA* hkdata = static_cast<DIALOG_HOTKEY_CLIENT_DATA*>( data );
+ return hkdata;
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+void HOTKEY_LIST_CTRL::LoadSection( struct EDA_HOTKEY_CONFIG* aSection )
+{
+ HOTKEY_LIST list;
EDA_HOTKEY** info_ptr;
for( info_ptr = aSection->m_HK_InfoList; *info_ptr; info_ptr++ )
{
- EDA_HOTKEY* info = *info_ptr;
- m_hotkeys[row++]->m_KeyCode = info->m_KeyCode;
+ EDA_HOTKEY info = **info_ptr;
+ list.push_back( info );
+ }
+
+ m_hotkeys.push_back( list );
+}
+
+
+void HOTKEY_LIST_CTRL::UpdateFromClientData()
+{
+ for( wxTreeListItem i = GetFirstItem(); i.IsOk(); i = GetNextItem( i ) )
+ {
+ DIALOG_HOTKEY_CLIENT_DATA* hkdata = GetHKClientData( i );
+ if( !hkdata )
+ continue;
+
+ EDA_HOTKEY& hk = hkdata->GetHotkey();
+
+ wxString name = wxGetTranslation( hk.m_InfoMsg );
+ wxString key = KeyNameFromKeyCode( hk.m_KeyCode );
+
+ SetItemText( i, 0, name );
+ SetItemText( i, 1, key );
+ }
+}
+
+
+bool HOTKEY_LIST_CTRL::TransferDataToControl()
+{
+ Freeze();
+ DeleteAllItems();
+ m_items.clear();
+ m_hotkeys.clear();
+
+ for( size_t i_list = 0; i_list < m_sections.size(); ++i_list )
+ {
+ LoadSection( m_sections[i_list].second );
+ wxString section_tag = *( m_sections[i_list].second->m_SectionTag );
+
+ HOTKEY_LIST& each_list = m_hotkeys[i_list];
+ for( size_t i_hotkey = 0; i_hotkey < each_list.size(); ++i_hotkey )
+ {
+ EDA_HOTKEY* hotkey_descr = &each_list[i_hotkey];
+
+ wxTreeListItem item = AppendItem( GetRootItem(), wxEmptyString );
+ SetItemData( item, new DIALOG_HOTKEY_CLIENT_DATA( hotkey_descr, section_tag ) );
+ m_items.push_back( item );
+ }
+ }
+
+ UpdateFromClientData();
+ Thaw();
+
+ return true;
+}
+
+
+bool HOTKEY_LIST_CTRL::TransferDataFromControl()
+{
+ for( size_t i_sec = 0; i_sec < m_sections.size(); ++i_sec )
+ {
+ struct EDA_HOTKEY_CONFIG* section = m_sections[i_sec].second;
+ for( EDA_HOTKEY** info_ptr = section->m_HK_InfoList; *info_ptr; ++info_ptr )
+ {
+ EDA_HOTKEY* info = *info_ptr;
+ for( wxTreeListItem item = GetFirstItem(); item.IsOk(); item = GetNextItem( item ) )
+ {
+ DIALOG_HOTKEY_CLIENT_DATA* hkdata = GetHKClientData( item );
+ if( !hkdata )
+ continue;
+
+ EDA_HOTKEY& hk = hkdata->GetHotkey();
+ if( hk.m_Idcommand == info->m_Idcommand )
+ {
+ info->m_KeyCode = hk.m_KeyCode;
+ break;
+ }
+ }
+ }
}
+ return true;
+}
- // Remove selection
- DeselectRow( m_curEditingRow );
- m_curEditingRow = -1;
- RefreshItems( 0, m_hotkeys.size()-1 );
+bool HOTKEY_LIST_CTRL::CanSetKey( long aKey, const wxString& aSectionTag,
+ EDA_HOTKEY** aConfKey, EDA_HOTKEY_CONFIG** aConfSect )
+{
+ EDA_HOTKEY* conflictingKey = NULL;
+ struct EDA_HOTKEY_CONFIG* conflictingSection = NULL;
+
+ for( wxTreeListItem item = GetFirstItem(); item.IsOk(); item = GetNextItem( item ) )
+ {
+ DIALOG_HOTKEY_CLIENT_DATA* hkdata = GetHKClientData( item );
+ if( !hkdata )
+ continue;
+
+ EDA_HOTKEY& hk = hkdata->GetHotkey();
+ wxString tag = hkdata->GetSectionTag();
+
+ if( aSectionTag != g_CommonSectionTag
+ && tag != g_CommonSectionTag
+ && tag != aSectionTag )
+ continue;
+
+ if( aKey == hk.m_KeyCode )
+ {
+ conflictingKey = &hk;
+
+ // Find the section
+ HOTKEYS_SECTIONS::iterator it;
+ for( it = m_sections.begin(); it != m_sections.end(); ++it )
+ {
+ if( *it->second->m_SectionTag == tag )
+ {
+ conflictingSection = it->second;
+ break;
+ }
+ }
+ }
+ }
+
+ if( aConfKey )
+ *aConfKey = conflictingKey;
+
+ if( aConfSect )
+ *aConfSect = conflictingSection;
+
+ return conflictingKey == NULL;
}
@@ -227,7 +305,6 @@ HOTKEY_SECTION_PAGE::HOTKEY_SECTION_PAGE( HOTKEYS_EDITOR_DIALOG* aDialog,
const wxString& aTitle,
EDA_HOTKEY_CONFIG* aSection ) :
wxPanel( aParent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL | wxNO_BORDER ),
- m_hotkeySection( aSection ),
m_dialog( aDialog )
{
aParent->AddPage( this, aTitle );
@@ -235,17 +312,22 @@ HOTKEY_SECTION_PAGE::HOTKEY_SECTION_PAGE( HOTKEYS_EDITOR_DIALOG* aDialog,
wxBoxSizer* bMainSizer = new wxBoxSizer( wxVERTICAL );
SetSizer( bMainSizer );
- Layout();
- bMainSizer->Fit( this );
- m_hotkeyList = new HOTKEY_LIST_CTRL( this, aSection );
+ HOTKEYS_SECTION section( aTitle, aSection );
+ HOTKEYS_SECTIONS sections;
+ sections.push_back( section );
+
+ m_hotkeyList = new HOTKEY_LIST_CTRL( this, sections );
bMainSizer->Add( m_hotkeyList, 1, wxALL|wxEXPAND, 5 );
+
+ Layout();
+ bMainSizer->Fit( this );
}
void HOTKEY_SECTION_PAGE::Restore()
{
- m_hotkeyList->RestoreFrom( m_hotkeySection );
+ m_hotkeyList->TransferDataToControl();
Update();
}
@@ -284,44 +366,42 @@ HOTKEYS_EDITOR_DIALOG::HOTKEYS_EDITOR_DIALOG( EDA_BASE_FRAME* aParent,
}
-void HOTKEYS_EDITOR_DIALOG::OnOKClicked( wxCommandEvent& event )
+bool HOTKEYS_EDITOR_DIALOG::TransferDataToWindow()
{
- std::vector<HOTKEY_SECTION_PAGE*>::iterator i;
+ if( !wxDialog::TransferDataToWindow() )
+ return false;
+ std::vector<HOTKEY_SECTION_PAGE*>::iterator i;
for( i = m_hotkeySectionPages.begin(); i != m_hotkeySectionPages.end(); ++i )
{
- std::vector<EDA_HOTKEY*>& hotkey_vec = (*i)->GetHotkeys();
- EDA_HOTKEY_CONFIG* section = (*i)->GetHotkeySection();
+ if( !(*i)->GetHotkeyCtrl()->TransferDataToControl() )
+ return false;
+ }
- EDA_HOTKEY** info_ptr;
+ return true;
+}
- for( info_ptr = section->m_HK_InfoList; *info_ptr; info_ptr++ )
- {
- EDA_HOTKEY* info = *info_ptr;
- /* find the corresponding hotkey */
- std::vector<EDA_HOTKEY*>::iterator j;
+bool HOTKEYS_EDITOR_DIALOG::TransferDataFromWindow()
+{
+ if( !wxDialog::TransferDataToWindow() )
+ return false;
- for( j = hotkey_vec.begin(); j != hotkey_vec.end(); ++j )
- {
- if( (*j) && (*j)->m_Idcommand == info->m_Idcommand )
- {
- info->m_KeyCode = (*j)->m_KeyCode;
- break;
- }
- }
- }
+ std::vector<HOTKEY_SECTION_PAGE*>::iterator i;
+ for( i = m_hotkeySectionPages.begin(); i != m_hotkeySectionPages.end(); ++i )
+ {
+ if( !(*i)->GetHotkeyCtrl()->TransferDataFromControl() )
+ return false;
}
- /* save the hotkeys */
+ // save the hotkeys
m_parent->WriteHotkeyConfig( m_hotkeys );
- EndModal( wxID_OK );
+ return true;
}
-
-void HOTKEYS_EDITOR_DIALOG::UndoClicked( wxCommandEvent& aEvent )
+void HOTKEYS_EDITOR_DIALOG::ResetClicked( wxCommandEvent& aEvent )
{
std::vector<HOTKEY_SECTION_PAGE*>::iterator i;
@@ -332,34 +412,22 @@ void HOTKEYS_EDITOR_DIALOG::UndoClicked( wxCommandEvent& aEvent )
}
-bool HOTKEYS_EDITOR_DIALOG::CanSetKey( long aKey, const wxString* sectionTag )
+bool HOTKEYS_EDITOR_DIALOG::CanSetKey( long aKey, const wxString& aSectionTag )
{
std::vector<HOTKEY_SECTION_PAGE*>::iterator i;
EDA_HOTKEY* conflictingKey = NULL;
- HOTKEY_SECTION_PAGE* conflictingSection = NULL;
+ EDA_HOTKEY_CONFIG* conflictingSection = NULL;
+ HOTKEY_LIST_CTRL *conflictingCtrl = NULL;
for( i = m_hotkeySectionPages.begin(); i != m_hotkeySectionPages.end(); ++i )
{
- // Any non Common section can only conflict with itself and Common
- if( *sectionTag != g_CommonSectionTag
- && *((*i)->GetHotkeySection()->m_SectionTag) != g_CommonSectionTag
- && *((*i)->GetHotkeySection()->m_SectionTag) != *sectionTag )
- continue;
-
- std::vector<EDA_HOTKEY*>& hotkey_vec = (*i)->GetHotkeys();
- /* find the corresponding hotkey */
- std::vector<EDA_HOTKEY*>::iterator j;
+ HOTKEY_LIST_CTRL *ctrl = (*i)->GetHotkeyCtrl();
- for( j = hotkey_vec.begin(); j != hotkey_vec.end(); ++j )
+ if ( !ctrl->CanSetKey( aKey, aSectionTag, &conflictingKey, &conflictingSection ) )
{
- if( aKey == (*j)->m_KeyCode )
- {
- conflictingKey = (*j);
- conflictingSection = (*i);
-
- break;
- }
+ conflictingCtrl = ctrl;
+ break;
}
}
@@ -370,13 +438,14 @@ bool HOTKEYS_EDITOR_DIALOG::CanSetKey( long aKey, const wxString* sectionTag )
_( "<%s> is already assigned to \"%s\" in section \"%s\". Are you sure you want "
"to change its assignment?" ),
KeyNameFromKeyCode( aKey ), GetChars( info ),
- *(conflictingSection->GetHotkeySection()->m_Title) );
+ *(conflictingSection->m_Title) );
wxMessageDialog dlg( this, msg, _( "Confirm change" ), wxYES_NO | wxNO_DEFAULT );
if( dlg.ShowModal() == wxID_YES )
{
conflictingKey->m_KeyCode = 0;
+ conflictingCtrl->UpdateFromClientData();
return true;
}
else
diff --git a/common/dialogs/dialog_hotkeys_editor_base.cpp b/common/dialogs/dialog_hotkeys_editor_base.cpp
index ef2f7c9..d2e99ee 100644
--- a/common/dialogs/dialog_hotkeys_editor_base.cpp
+++ b/common/dialogs/dialog_hotkeys_editor_base.cpp
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// C++ code generated with wxFormBuilder (version Dec 28 2015)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
@@ -27,6 +27,12 @@ HOTKEYS_EDITOR_DIALOG_BASE::HOTKEYS_EDITOR_DIALOG_BASE( wxWindow* parent, wxWind
wxBoxSizer* b_buttonsSizer;
b_buttonsSizer = new wxBoxSizer( wxHORIZONTAL );
+ m_resetButton = new wxButton( this, wxID_RESET, _("Reset"), wxDefaultPosition, wxDefaultSize, 0 );
+ b_buttonsSizer->Add( m_resetButton, 0, wxALL|wxEXPAND, 5 );
+
+
+ b_buttonsSizer->Add( 0, 0, 1, wxEXPAND, 5 );
+
m_sdbSizer = new wxStdDialogButtonSizer();
m_sdbSizerOK = new wxButton( this, wxID_OK );
m_sdbSizer->AddButton( m_sdbSizerOK );
@@ -36,25 +42,20 @@ HOTKEYS_EDITOR_DIALOG_BASE::HOTKEYS_EDITOR_DIALOG_BASE( wxWindow* parent, wxWind
b_buttonsSizer->Add( m_sdbSizer, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 );
- m_undoButton = new wxButton( this, wxID_UNDO, _("Undo"), wxDefaultPosition, wxDefaultSize, 0 );
- b_buttonsSizer->Add( m_undoButton, 0, wxALL|wxEXPAND, 5 );
-
- bMainSizer->Add( b_buttonsSizer, 0, wxALIGN_RIGHT, 5 );
+ bMainSizer->Add( b_buttonsSizer, 0, wxALIGN_RIGHT|wxEXPAND, 5 );
this->SetSizer( bMainSizer );
this->Layout();
// Connect Events
- m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( HOTKEYS_EDITOR_DIALOG_BASE::OnOKClicked ), NULL, this );
- m_undoButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( HOTKEYS_EDITOR_DIALOG_BASE::UndoClicked ), NULL, this );
+ m_resetButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( HOTKEYS_EDITOR_DIALOG_BASE::ResetClicked ), NULL, this );
}
HOTKEYS_EDITOR_DIALOG_BASE::~HOTKEYS_EDITOR_DIALOG_BASE()
{
// Disconnect Events
- m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( HOTKEYS_EDITOR_DIALOG_BASE::OnOKClicked ), NULL, this );
- m_undoButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( HOTKEYS_EDITOR_DIALOG_BASE::UndoClicked ), NULL, this );
+ m_resetButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( HOTKEYS_EDITOR_DIALOG_BASE::ResetClicked ), NULL, this );
}
diff --git a/common/dialogs/dialog_hotkeys_editor_base.fbp b/common/dialogs/dialog_hotkeys_editor_base.fbp
index 7b12ee4f..8bd3ca6 100644
--- a/common/dialogs/dialog_hotkeys_editor_base.fbp
+++ b/common/dialogs/dialog_hotkeys_editor_base.fbp
@@ -262,39 +262,13 @@
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
- <property name="flag">wxALIGN_RIGHT</property>
+ <property name="flag">wxALIGN_RIGHT|wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">b_buttonsSizer</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
- <object class="sizeritem" expanded="1">
- <property name="border">5</property>
- <property name="flag">wxEXPAND|wxTOP|wxBOTTOM</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">OnOKClicked</event>
- <event name="OnSaveButtonClick"></event>
- <event name="OnYesButtonClick"></event>
- </object>
- </object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
@@ -327,8 +301,8 @@
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
- <property name="id">wxID_UNDO</property>
- <property name="label">Undo</property>
+ <property name="id">wxID_RESET</property>
+ <property name="label">Reset</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
@@ -336,7 +310,7 @@
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
- <property name="name">m_undoButton</property>
+ <property name="name">m_resetButton</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
@@ -357,7 +331,7 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
- <event name="OnButtonClick">UndoClicked</event>
+ <event name="OnButtonClick">ResetClicked</event>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
@@ -383,6 +357,42 @@
<event name="OnUpdateUI"></event>
</object>
</object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="spacer" expanded="1">
+ <property name="height">0</property>
+ <property name="permission">protected</property>
+ <property name="width">0</property>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxEXPAND|wxTOP|wxBOTTOM</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"></event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
</object>
</object>
</object>
diff --git a/common/dialogs/dialog_hotkeys_editor_base.h b/common/dialogs/dialog_hotkeys_editor_base.h
index f0d4d9e..cfd6528 100644
--- a/common/dialogs/dialog_hotkeys_editor_base.h
+++ b/common/dialogs/dialog_hotkeys_editor_base.h
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Jun 17 2015)
+// C++ code generated with wxFormBuilder (version Dec 28 2015)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
@@ -21,8 +21,8 @@ class DIALOG_SHIM;
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/notebook.h>
-#include <wx/sizer.h>
#include <wx/button.h>
+#include <wx/sizer.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
@@ -38,14 +38,13 @@ class HOTKEYS_EDITOR_DIALOG_BASE : public DIALOG_SHIM
protected:
wxStaticText* m_staticText1;
wxNotebook* m_hotkeySections;
+ wxButton* m_resetButton;
wxStdDialogButtonSizer* m_sdbSizer;
wxButton* m_sdbSizerOK;
wxButton* m_sdbSizerCancel;
- wxButton* m_undoButton;
// Virtual event handlers, overide them in your derived class
- virtual void OnOKClicked( wxCommandEvent& event ) { event.Skip(); }
- virtual void UndoClicked( wxCommandEvent& event ) { event.Skip(); }
+ virtual void ResetClicked( wxCommandEvent& event ) { event.Skip(); }
public:
diff --git a/include/dialog_hotkeys_editor.h b/include/dialog_hotkeys_editor.h
index 55951c2..30aae16 100644
--- a/include/dialog_hotkeys_editor.h
+++ b/include/dialog_hotkeys_editor.h
@@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
- * Copyright (C) 2004-2014 KiCad Developers, see CHANGELOG.TXT for contributors.
+ * Copyright (C) 2004-2016 KiCad Developers, see CHANGELOG.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
@@ -38,24 +38,33 @@
#include <wx/textctrl.h>
#include <wx/stattext.h>
#include <wx/button.h>
-#include <wx/listctrl.h>
+#include <wx/treelist.h>
#include <wx/dialog.h>
#include <wx/grid.h>
+#include <vector>
+#include <utility>
+
#include <hotkeys_basic.h>
#include <draw_frame.h>
#include <../common/dialogs/dialog_hotkeys_editor_base.h>
+typedef std::pair<wxString, struct EDA_HOTKEY_CONFIG*> HOTKEYS_SECTION;
+typedef std::vector<HOTKEYS_SECTION> HOTKEYS_SECTIONS;
+
+typedef std::vector<EDA_HOTKEY> HOTKEY_LIST;
+
class HOTKEYS_EDITOR_DIALOG;
+class DIALOG_HOTKEY_CLIENT_DATA;
/**
* Class HOTKEY_LIST_CTRL
* is a class to contain the contents of a hotkey editor tab page.
*/
-class HOTKEY_LIST_CTRL : public wxListCtrl
+class HOTKEY_LIST_CTRL : public wxTreeListCtrl
{
public:
- HOTKEY_LIST_CTRL( wxWindow* aParent, struct EDA_HOTKEY_CONFIG* aSection );
+ HOTKEY_LIST_CTRL( wxWindow* aParent, const HOTKEYS_SECTIONS& aSections );
~HOTKEY_LIST_CTRL() {};
/**
@@ -67,36 +76,65 @@ public:
void DeselectRow( int aRow );
/**
- * Function GetHotkeys
- * Access to return the vector used for the list control data. This will contain the
- * "live" state of the user's configuration.
- *
- * @return Pointer to vector of hotkey settings
+ * Function TransferDataToControl
+ * Load the hotkey data into the control.
+ * @return true iff the operation was successful
*/
- std::vector< EDA_HOTKEY* >& GetHotkeys() { return m_hotkeys; }
+ bool TransferDataToControl();
/**
- * Function RestoreFrom
- * Restores list control hotkey keycodes to the keycodes present in the
- * given hotkey configuration array.
+ * Function TransferDataFromControl
+ * Save the hotkey data from the control.
+ * @return true iff the operation was successful
+ */
+ bool TransferDataFromControl();
+
+ /**
+ * Function CanSetKey
+ * Check whether the given key conflicts with anything in this HOTKEY_LIST_CTRL.
*
- * @param aSection is a pointer to the hotkey configuration array
+ * @param aKey - key to check
+ * @param aSectionTag - section tag of the key
+ * @param aConfKey - if not NULL, outparam holding the key this one conflicts with
+ * @param aConfSect - if not NULL, outparam holding the section this one conflicts with
*/
- void RestoreFrom( struct EDA_HOTKEY_CONFIG* aSection );
+ bool CanSetKey( long aKey, const wxString& aSectionTag,
+ EDA_HOTKEY** aConfKey, EDA_HOTKEY_CONFIG** aConfSect );
+
+ /**
+ * Function UpdateFromClientData
+ * Update all visible items from the data stored in their client data objects.
+ */
+ void UpdateFromClientData();
private:
- int m_curEditingRow;
- wxString* m_sectionTag;
- std::vector< EDA_HOTKEY* > m_hotkeys;
+ HOTKEYS_SECTIONS m_sections;
+ std::vector< HOTKEY_LIST > m_hotkeys;
+ std::vector< wxTreeListItem > m_items;
/**
- * Function recalculateColumns
- * Adjusts the width of grid columns in proportion of the max text length of both
+ * Function GetSelHKClientData
+ * Return the DIALOG_HOTKEY_CLIENT_DATA for the item being edited, or NULL if none is selected.
*/
- void recalculateColumns();
+ DIALOG_HOTKEY_CLIENT_DATA* GetSelHKClientData();
+
+ /**
+ * Function GetHKClientData
+ * Return the DIALOG_HOTKEY_CLIENT_DATA for the given item, or NULL if invalid.
+ */
+ DIALOG_HOTKEY_CLIENT_DATA* GetHKClientData( wxTreeListItem aItem );
protected:
/**
+ * Function LoadSection
+ * Generates a HOTKEY_LIST from the given hotkey configuration array and
+ * pushes it to m_hotkeys.
+ *
+ * @param aSection is a pointer to the hotkey configuration array
+ */
+ void LoadSection( struct EDA_HOTKEY_CONFIG* aSection );
+
+ /**
* Function OnGetItemText
* Returns the requested row, column data to the list control.
*
@@ -116,21 +154,8 @@ protected:
void OnChar( wxKeyEvent& aEvent );
/**
- * Function OnListItemSelected
- * Item selection handler which is used to record what index is selected to alter
- * update with the key press
- *
- * @param aEvent is the button press event, unused
- */
- void OnListItemSelected( wxListEvent& aEvent );
-
- /**
* Function OnSize
- * Sizing update handler to recompute the column widths dynamically and maximize them.
- * Due to wxWidget's broken autosizing support (it's completely inconsistent across
- * platforms), we just do it based on a scale of
- *
- * @param aEvent is the button press event, unused
+ * Sizing update handler to recompute the column widths dynamically.
*/
void OnSize( wxSizeEvent& aEvent );
};
@@ -143,7 +168,6 @@ class HOTKEY_SECTION_PAGE : public wxPanel
{
public:
private:
- EDA_HOTKEY_CONFIG* m_hotkeySection;
HOTKEY_LIST_CTRL *m_hotkeyList;
HOTKEYS_EDITOR_DIALOG* m_dialog;
@@ -166,20 +190,12 @@ public:
void Restore();
/**
- * Function GetHotkeys
- * Accessor to retrieve hotkeys list from list control
+ * Function GetHotkeyCtrl
+ * Accessor to retrieve hotkey configuration control assigned to a tab control page
*
- * @return Pointer to vector used for list control data
+ * @return Pointer to hotkey configuration control
*/
- std::vector< EDA_HOTKEY* >& GetHotkeys() { return m_hotkeyList->GetHotkeys(); }
-
- /**
- * Function GetHotkeySection
- * Accessor to retrieve hotkey configuration array assigned to a tab control page
- *
- * @return Pointer to hotkey configuration array
- */
- EDA_HOTKEY_CONFIG* GetHotkeySection() { return m_hotkeySection; }
+ HOTKEY_LIST_CTRL* GetHotkeyCtrl() { return m_hotkeyList; }
/**
* Function GetDialog
@@ -203,6 +219,9 @@ protected:
std::vector<HOTKEY_SECTION_PAGE*> m_hotkeySectionPages;
+ bool TransferDataToWindow();
+ bool TransferDataFromWindow();
+
public:
HOTKEYS_EDITOR_DIALOG( EDA_BASE_FRAME* aParent, EDA_HOTKEY_CONFIG* aHotkeys );
@@ -224,24 +243,17 @@ public:
*
* @return True if the user accepted the overwrite or no conflict existed
*/
- bool CanSetKey( long aKey, const wxString* aSectionTag );
+ bool CanSetKey( long aKey, const wxString& aSectionTag );
private:
- /**
- * Function OnOKClicked
- * Close the dialog and make save all changes to hotkeys
- *
- * @param aEvent is the button press event, unused
- */
- void OnOKClicked( wxCommandEvent& aEvent );
/**
- * Function UndoClicked
+ * Function ResetClicked
* Reinit the hotkeys to the initial state (removes all pending changes)
*
* @param aEvent is the button press event, unused
*/
- void UndoClicked( wxCommandEvent& aEvent );
+ void ResetClicked( wxCommandEvent& aEvent );
};
/**
Follow ups