Hotkey dialog refactor.

* Replace the wxListCtrl with a wxTreeListCtrl, allowing expandable categories
  in a future change.
* Clean up the code to make HOTKEY_LIST_CTRL function a bit better on its own.
* Migrate the hotkey dialog to TransferData{To,From}Window, use matching
  TransferData{To,From}Control methods on HOTKEY_LIST_CTRL so it is easy to
  embed.
This commit is contained in:
Chris Pavlina 2016-01-04 19:31:35 -05:00 committed by Wayne Stambaugh
parent 73d6fa3368
commit ed2a1d5955
5 changed files with 356 additions and 265 deletions

View File

@ -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 );
}
// Remove selection
DeselectRow( m_curEditingRow );
m_curEditingRow = -1;
m_hotkeys.push_back( list );
}
RefreshItems( 0, m_hotkeys.size()-1 );
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;
}
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 );
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 );
m_hotkeyList = new HOTKEY_LIST_CTRL( this, aSection );
bMainSizer->Add( m_hotkeyList, 1, wxALL|wxEXPAND, 5 );
}
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();
EDA_HOTKEY** info_ptr;
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;
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;
}
}
}
if( !(*i)->GetHotkeyCtrl()->TransferDataToControl() )
return false;
}
/* save the hotkeys */
m_parent->WriteHotkeyConfig( m_hotkeys );
EndModal( wxID_OK );
return true;
}
bool HOTKEYS_EDITOR_DIALOG::TransferDataFromWindow()
{
if( !wxDialog::TransferDataToWindow() )
return false;
void HOTKEYS_EDITOR_DIALOG::UndoClicked( wxCommandEvent& aEvent )
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
m_parent->WriteHotkeyConfig( m_hotkeys );
return true;
}
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;
HOTKEY_LIST_CTRL *ctrl = (*i)->GetHotkeyCtrl();
std::vector<EDA_HOTKEY*>& hotkey_vec = (*i)->GetHotkeys();
/* find the corresponding hotkey */
std::vector<EDA_HOTKEY*>::iterator j;
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

View File

@ -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 );
}

View File

@ -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>

View File

@ -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:

View File

@ -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,35 +76,64 @@ 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 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
*/
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:
HOTKEYS_SECTIONS m_sections;
std::vector< HOTKEY_LIST > m_hotkeys;
std::vector< wxTreeListItem > m_items;
/**
* Function GetSelHKClientData
* Return the DIALOG_HOTKEY_CLIENT_DATA for the item being edited, or NULL if none is selected.
*/
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 RestoreFrom( struct EDA_HOTKEY_CONFIG* aSection );
void LoadSection( struct EDA_HOTKEY_CONFIG* aSection );
private:
int m_curEditingRow;
wxString* m_sectionTag;
std::vector< EDA_HOTKEY* > m_hotkeys;
/**
* Function recalculateColumns
* Adjusts the width of grid columns in proportion of the max text length of both
*/
void recalculateColumns();
protected:
/**
* Function OnGetItemText
* Returns the requested row, column data to the list control.
@ -115,22 +153,9 @@ 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 );
};
/**