Refactor WIDGET_HOTKEY_LIST out of DIALOG_HOTKEYS_EDITOR
This commit is contained in:
parent
9663060f97
commit
af042628ff
|
@ -1,6 +1,7 @@
|
||||||
include_directories( BEFORE ${INC_BEFORE} )
|
include_directories( BEFORE ${INC_BEFORE} )
|
||||||
include_directories(
|
include_directories(
|
||||||
./dialogs
|
./dialogs
|
||||||
|
./widgets
|
||||||
./dialog_about
|
./dialog_about
|
||||||
${CAIRO_INCLUDE_DIR}
|
${CAIRO_INCLUDE_DIR}
|
||||||
${GLEW_INCLUDE_DIR}
|
${GLEW_INCLUDE_DIR}
|
||||||
|
@ -144,6 +145,9 @@ set( COMMON_ABOUT_DLG_SRCS
|
||||||
dialog_about/AboutDialog_main.cpp
|
dialog_about/AboutDialog_main.cpp
|
||||||
dialog_about/dialog_about.cpp
|
dialog_about/dialog_about.cpp
|
||||||
dialog_about/dialog_about_base.cpp
|
dialog_about/dialog_about_base.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set( COMMON_DLG_SRCS
|
||||||
dialogs/dialog_display_info_HTML_base.cpp
|
dialogs/dialog_display_info_HTML_base.cpp
|
||||||
dialogs/dialog_exit_base.cpp
|
dialogs/dialog_exit_base.cpp
|
||||||
dialogs/dialog_image_editor.cpp
|
dialogs/dialog_image_editor.cpp
|
||||||
|
@ -160,6 +164,10 @@ set( COMMON_ABOUT_DLG_SRCS
|
||||||
dialogs/wx_html_report_panel.cpp
|
dialogs/wx_html_report_panel.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set( COMMON_WIDGET_SRCS
|
||||||
|
widgets/widget_hotkey_list.cpp
|
||||||
|
)
|
||||||
|
|
||||||
set( COMMON_PAGE_LAYOUT_SRCS
|
set( COMMON_PAGE_LAYOUT_SRCS
|
||||||
page_layout/title_block_shapes.cpp
|
page_layout/title_block_shapes.cpp
|
||||||
page_layout/class_worksheet_dataitem.cpp
|
page_layout/class_worksheet_dataitem.cpp
|
||||||
|
@ -173,6 +181,8 @@ set( COMMON_PAGE_LAYOUT_SRCS
|
||||||
set( COMMON_SRCS
|
set( COMMON_SRCS
|
||||||
${LIB_KICAD_SRCS}
|
${LIB_KICAD_SRCS}
|
||||||
${COMMON_ABOUT_DLG_SRCS}
|
${COMMON_ABOUT_DLG_SRCS}
|
||||||
|
${COMMON_DLG_SRCS}
|
||||||
|
${COMMON_WIDGET_SRCS}
|
||||||
${COMMON_PAGE_LAYOUT_SRCS}
|
${COMMON_PAGE_LAYOUT_SRCS}
|
||||||
base_struct.cpp
|
base_struct.cpp
|
||||||
basicframe.cpp
|
basicframe.cpp
|
||||||
|
|
|
@ -21,352 +21,8 @@
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
#include <fctsys.h>
|
|
||||||
#include <pgm_base.h>
|
|
||||||
#include <common.h>
|
|
||||||
#include <confirm.h>
|
|
||||||
#include <wx/dataview.h>
|
|
||||||
|
|
||||||
#include <dialog_hotkeys_editor.h>
|
#include <dialog_hotkeys_editor.h>
|
||||||
|
|
||||||
|
|
||||||
class DIALOG_HOTKEY_CLIENT_DATA : public wxClientData
|
|
||||||
{
|
|
||||||
EDA_HOTKEY m_hotkey;
|
|
||||||
wxString m_section_tag;
|
|
||||||
|
|
||||||
public:
|
|
||||||
DIALOG_HOTKEY_CLIENT_DATA( const EDA_HOTKEY& aHotkey, const wxString& aSectionTag )
|
|
||||||
: m_hotkey( aHotkey ), m_section_tag( aSectionTag ) {}
|
|
||||||
|
|
||||||
EDA_HOTKEY& GetHotkey() { return m_hotkey; }
|
|
||||||
wxString GetSectionTag() const { return m_section_tag; }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
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" ) );
|
|
||||||
|
|
||||||
Bind( wxEVT_CHAR, &HOTKEY_LIST_CTRL::OnChar, this );
|
|
||||||
Bind( wxEVT_SIZE, &HOTKEY_LIST_CTRL::OnSize, this );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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::OnSize( wxSizeEvent& aEvent )
|
|
||||||
{
|
|
||||||
// Handle this manually - wxTreeListCtrl screws up the width of the first column
|
|
||||||
wxDataViewCtrl* view = GetDataView();
|
|
||||||
|
|
||||||
if( !view )
|
|
||||||
return;
|
|
||||||
|
|
||||||
const wxRect rect = GetClientRect();
|
|
||||||
view->SetSize( rect );
|
|
||||||
|
|
||||||
#ifdef wxHAS_GENERIC_DATAVIEWCTRL
|
|
||||||
{
|
|
||||||
wxWindow* const view = GetView();
|
|
||||||
view->Refresh();
|
|
||||||
view->Update();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SetColumnWidth( 1, 100 );
|
|
||||||
SetColumnWidth( 0, rect.width - 130 );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void HOTKEY_LIST_CTRL::DeselectRow( int aRow )
|
|
||||||
{
|
|
||||||
wxASSERT( aRow >= 0 );
|
|
||||||
wxASSERT( (size_t)( aRow ) < m_items.size() );
|
|
||||||
Unselect( m_items[aRow] );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void HOTKEY_LIST_CTRL::OnChar( wxKeyEvent& aEvent )
|
|
||||||
{
|
|
||||||
DIALOG_HOTKEY_CLIENT_DATA* data = GetSelHKClientData();
|
|
||||||
|
|
||||||
if( data )
|
|
||||||
{
|
|
||||||
long key = aEvent.GetKeyCode();
|
|
||||||
|
|
||||||
switch( key )
|
|
||||||
{
|
|
||||||
case WXK_ESCAPE:
|
|
||||||
UnselectAll();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
if( key >= 'a' && key <= 'z' ) // convert to uppercase
|
|
||||||
key = key + ('A' - 'a');
|
|
||||||
|
|
||||||
// Remap Ctrl A (=1+GR_KB_CTRL) to Ctrl Z(=26+GR_KB_CTRL)
|
|
||||||
// to GR_KB_CTRL+'A' .. GR_KB_CTRL+'Z'
|
|
||||||
if( aEvent.ControlDown() && key >= WXK_CONTROL_A && key <= WXK_CONTROL_Z )
|
|
||||||
key += 'A' - 1;
|
|
||||||
|
|
||||||
/* Disallow shift for keys that have two keycodes on them (e.g. number and
|
|
||||||
* punctuation keys) leaving only the "letter keys" of A-Z.
|
|
||||||
* Then, you can have, e.g. Ctrl-5 and Ctrl-% (GB layout)
|
|
||||||
* and Ctrl-( and Ctrl-5 (FR layout).
|
|
||||||
* Otherwise, you'd have to have to say Ctrl-Shift-5 on a FR layout
|
|
||||||
*/
|
|
||||||
bool keyIsLetter = key >= 'A' && key <= 'Z';
|
|
||||||
|
|
||||||
if( aEvent.ShiftDown() && ( keyIsLetter || key > 256 ) )
|
|
||||||
key |= GR_KB_SHIFT;
|
|
||||||
|
|
||||||
if( aEvent.ControlDown() )
|
|
||||||
key |= GR_KB_CTRL;
|
|
||||||
|
|
||||||
if( aEvent.AltDown() )
|
|
||||||
key |= GR_KB_ALT;
|
|
||||||
|
|
||||||
// See if this key code is handled in hotkeys names list
|
|
||||||
bool exists;
|
|
||||||
KeyNameFromKeyCode( key, &exists );
|
|
||||||
|
|
||||||
if( exists && data->GetHotkey().m_KeyCode != key )
|
|
||||||
{
|
|
||||||
wxString tag = data->GetSectionTag();
|
|
||||||
bool canUpdate = ResolveKeyConflicts( key, tag );
|
|
||||||
|
|
||||||
if( canUpdate )
|
|
||||||
{
|
|
||||||
data->GetHotkey().m_KeyCode = key;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove selection
|
|
||||||
UnselectAll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UpdateFromClientData();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DIALOG_HOTKEY_CLIENT_DATA* HOTKEY_LIST_CTRL::GetSelHKClientData()
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
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();
|
|
||||||
|
|
||||||
HOTKEYS_SECTIONS::iterator sec_it;
|
|
||||||
size_t sec_index = 0;
|
|
||||||
for( sec_it = m_sections.begin(); sec_it != m_sections.end(); ++sec_it, ++sec_index )
|
|
||||||
{
|
|
||||||
LoadSection( sec_it->second );
|
|
||||||
wxString section_tag = *( sec_it->second->m_SectionTag );
|
|
||||||
|
|
||||||
// Create parent item
|
|
||||||
wxTreeListItem parent = AppendItem( GetRootItem(), sec_it->first );
|
|
||||||
|
|
||||||
HOTKEY_LIST& each_list = m_hotkeys[sec_index];
|
|
||||||
HOTKEY_LIST::iterator hk_it;
|
|
||||||
for( hk_it = each_list.begin(); hk_it != each_list.end(); ++hk_it )
|
|
||||||
{
|
|
||||||
wxTreeListItem item = AppendItem( parent, wxEmptyString );
|
|
||||||
SetItemData( item, new DIALOG_HOTKEY_CLIENT_DATA( &*hk_it, section_tag ) );
|
|
||||||
m_items.push_back( item );
|
|
||||||
}
|
|
||||||
|
|
||||||
Expand( parent );
|
|
||||||
}
|
|
||||||
|
|
||||||
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::ResolveKeyConflicts( long aKey, const wxString& aSectionTag )
|
|
||||||
{
|
|
||||||
EDA_HOTKEY* conflictingKey = NULL;
|
|
||||||
EDA_HOTKEY_CONFIG* conflictingSection = NULL;
|
|
||||||
|
|
||||||
CheckKeyConflicts( aKey, aSectionTag, &conflictingKey, &conflictingSection );
|
|
||||||
|
|
||||||
if( conflictingKey != NULL )
|
|
||||||
{
|
|
||||||
wxString info = wxGetTranslation( conflictingKey->m_InfoMsg );
|
|
||||||
wxString msg = wxString::Format(
|
|
||||||
_( "<%s> is already assigned to \"%s\" in section \"%s\". Are you sure you want "
|
|
||||||
"to change its assignment?" ),
|
|
||||||
KeyNameFromKeyCode( aKey ), GetChars( info ),
|
|
||||||
*(conflictingSection->m_Title) );
|
|
||||||
|
|
||||||
wxMessageDialog dlg( GetParent(), msg, _( "Confirm change" ), wxYES_NO | wxNO_DEFAULT );
|
|
||||||
|
|
||||||
if( dlg.ShowModal() == wxID_YES )
|
|
||||||
{
|
|
||||||
conflictingKey->m_KeyCode = 0;
|
|
||||||
UpdateFromClientData();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool HOTKEY_LIST_CTRL::CheckKeyConflicts( 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void InstallHotkeyFrame( EDA_BASE_FRAME* aParent, EDA_HOTKEY_CONFIG* aHotkeys )
|
void InstallHotkeyFrame( EDA_BASE_FRAME* aParent, EDA_HOTKEY_CONFIG* aHotkeys )
|
||||||
{
|
{
|
||||||
HOTKEYS_EDITOR_DIALOG dialog( aParent, aHotkeys );
|
HOTKEYS_EDITOR_DIALOG dialog( aParent, aHotkeys );
|
||||||
|
@ -385,7 +41,7 @@ HOTKEYS_EDITOR_DIALOG::HOTKEYS_EDITOR_DIALOG( EDA_BASE_FRAME* aParent,
|
||||||
HOTKEYS_EDITOR_DIALOG_BASE( aParent ),
|
HOTKEYS_EDITOR_DIALOG_BASE( aParent ),
|
||||||
m_hotkeys( aHotkeys )
|
m_hotkeys( aHotkeys )
|
||||||
{
|
{
|
||||||
m_hotkeyListCtrl = new HOTKEY_LIST_CTRL( this, HOTKEY_LIST_CTRL::Sections( aHotkeys ) );
|
m_hotkeyListCtrl = new WIDGET_HOTKEY_LIST( this, WIDGET_HOTKEY_LIST::GenSections( aHotkeys ) );
|
||||||
m_mainSizer->Insert( 1, m_hotkeyListCtrl, wxSizerFlags( 1 ).Expand().Border( wxALL, 5 ) );
|
m_mainSizer->Insert( 1, m_hotkeyListCtrl, wxSizerFlags( 1 ).Expand().Border( wxALL, 5 ) );
|
||||||
Layout();
|
Layout();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,371 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 Chris Pavlina <pavlina.chris@gmail.com>
|
||||||
|
* Copyright (C) 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
|
||||||
|
* as published by the Free Software Foundation; either version 3
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <widgets/widget_hotkey_list.h>
|
||||||
|
|
||||||
|
#include <wx/dataview.h>
|
||||||
|
|
||||||
|
#include <draw_frame.h>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class WIDGET_HOTKEY_CLIENT_DATA
|
||||||
|
* Stores the hotkey and section tag associated with each row. To change a
|
||||||
|
* hotkey, edit it in the row's client data, then call WIDGET_HOTKEY_LIST::UpdateFromClientData().
|
||||||
|
*/
|
||||||
|
class WIDGET_HOTKEY_CLIENT_DATA: public wxClientData
|
||||||
|
{
|
||||||
|
EDA_HOTKEY m_hotkey;
|
||||||
|
wxString m_section_tag;
|
||||||
|
|
||||||
|
public:
|
||||||
|
WIDGET_HOTKEY_CLIENT_DATA( const EDA_HOTKEY& aHotkey, const wxString& aSectionTag )
|
||||||
|
: m_hotkey( aHotkey ),
|
||||||
|
m_section_tag( aSectionTag )
|
||||||
|
{ }
|
||||||
|
|
||||||
|
EDA_HOTKEY& GetHotkey() { return m_hotkey; }
|
||||||
|
const wxString& GetSectionTag() const { return m_section_tag; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
WIDGET_HOTKEY_CLIENT_DATA* WIDGET_HOTKEY_LIST::GetHKClientData( wxTreeListItem aItem )
|
||||||
|
{
|
||||||
|
if( aItem.IsOk() )
|
||||||
|
{
|
||||||
|
wxClientData* data = GetItemData( aItem );
|
||||||
|
if( !data )
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return static_cast<WIDGET_HOTKEY_CLIENT_DATA*>( data );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WIDGET_HOTKEY_CLIENT_DATA* WIDGET_HOTKEY_LIST::GetSelHKClientData()
|
||||||
|
{
|
||||||
|
return GetHKClientData( GetSelection() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WIDGET_HOTKEY_LIST::UpdateFromClientData()
|
||||||
|
{
|
||||||
|
for( wxTreeListItem i = GetFirstItem(); i.IsOk(); i = GetNextItem( i ) )
|
||||||
|
{
|
||||||
|
WIDGET_HOTKEY_CLIENT_DATA* hkdata = GetHKClientData( i );
|
||||||
|
|
||||||
|
if( hkdata )
|
||||||
|
{
|
||||||
|
EDA_HOTKEY& hk = hkdata->GetHotkey();
|
||||||
|
|
||||||
|
SetItemText( i, 0, wxGetTranslation( hk.m_InfoMsg ) );
|
||||||
|
SetItemText( i, 1, KeyNameFromKeyCode( hk.m_KeyCode ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WIDGET_HOTKEY_LIST::LoadSection( EDA_HOTKEY_CONFIG* aSection )
|
||||||
|
{
|
||||||
|
HOTKEY_LIST list;
|
||||||
|
|
||||||
|
for( EDA_HOTKEY** info_ptr = aSection->m_HK_InfoList; *info_ptr; ++info_ptr )
|
||||||
|
{
|
||||||
|
list.push_back( **info_ptr );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_hotkeys.push_back( list );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WIDGET_HOTKEY_LIST::OnChar( wxKeyEvent& aEvent )
|
||||||
|
{
|
||||||
|
WIDGET_HOTKEY_CLIENT_DATA* data = GetSelHKClientData();
|
||||||
|
|
||||||
|
if( data )
|
||||||
|
{
|
||||||
|
long key = aEvent.GetKeyCode();
|
||||||
|
|
||||||
|
switch( key )
|
||||||
|
{
|
||||||
|
case WXK_ESCAPE:
|
||||||
|
UnselectAll();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if( key >= 'a' && key <= 'z' ) // convert to uppercase
|
||||||
|
key = key + ('A' - 'a');
|
||||||
|
|
||||||
|
// Remap Ctrl A (=1+GR_KB_CTRL) to Ctrl Z(=26+GR_KB_CTRL)
|
||||||
|
// to GR_KB_CTRL+'A' .. GR_KB_CTRL+'Z'
|
||||||
|
if( aEvent.ControlDown() && key >= WXK_CONTROL_A && key <= WXK_CONTROL_Z )
|
||||||
|
key += 'A' - 1;
|
||||||
|
|
||||||
|
/* Disallow shift for keys that have two keycodes on them (e.g. number and
|
||||||
|
* punctuation keys) leaving only the "letter keys" of A-Z.
|
||||||
|
* Then, you can have, e.g. Ctrl-5 and Ctrl-% (GB layout)
|
||||||
|
* and Ctrl-( and Ctrl-5 (FR layout).
|
||||||
|
* Otherwise, you'd have to have to say Ctrl-Shift-5 on a FR layout
|
||||||
|
*/
|
||||||
|
bool keyIsLetter = key >= 'A' && key <= 'Z';
|
||||||
|
|
||||||
|
if( aEvent.ShiftDown() && ( keyIsLetter || key > 256 ) )
|
||||||
|
key |= GR_KB_SHIFT;
|
||||||
|
|
||||||
|
if( aEvent.ControlDown() )
|
||||||
|
key |= GR_KB_CTRL;
|
||||||
|
|
||||||
|
if( aEvent.AltDown() )
|
||||||
|
key |= GR_KB_ALT;
|
||||||
|
|
||||||
|
// See if this key code is handled in hotkeys names list
|
||||||
|
bool exists;
|
||||||
|
KeyNameFromKeyCode( key, &exists );
|
||||||
|
|
||||||
|
if( exists && data->GetHotkey().m_KeyCode != key )
|
||||||
|
{
|
||||||
|
wxString tag = data->GetSectionTag();
|
||||||
|
bool canUpdate = ResolveKeyConflicts( key, tag );
|
||||||
|
|
||||||
|
if( canUpdate )
|
||||||
|
{
|
||||||
|
data->GetHotkey().m_KeyCode = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove selection
|
||||||
|
UnselectAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UpdateFromClientData();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WIDGET_HOTKEY_LIST::OnSize( wxSizeEvent& aEvent )
|
||||||
|
{
|
||||||
|
// Handle this manually - wxTreeListCtrl screws up the width of the first column
|
||||||
|
wxDataViewCtrl* view = GetDataView();
|
||||||
|
|
||||||
|
if( !view )
|
||||||
|
return;
|
||||||
|
|
||||||
|
wxRect rect = GetClientRect();
|
||||||
|
view->SetSize( rect );
|
||||||
|
|
||||||
|
#ifdef wxHAS_GENERIC_DATAVIEWCTRL
|
||||||
|
{
|
||||||
|
wxWindow* view = GetView();
|
||||||
|
view->Refresh();
|
||||||
|
view->Update();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SetColumnWidth( 1, WIDGET_HOTKEY_LIST_HKCOLUMN_WIDTH );
|
||||||
|
SetColumnWidth( 0,
|
||||||
|
rect.width - WIDGET_HOTKEY_LIST_HKCOLUMN_WIDTH - WIDGET_HOTKEY_LIST_HMARGIN );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool WIDGET_HOTKEY_LIST::CheckKeyConflicts( long aKey, const wxString& aSectionTag,
|
||||||
|
EDA_HOTKEY** aConfKey, EDA_HOTKEY_CONFIG** aConfSect )
|
||||||
|
{
|
||||||
|
EDA_HOTKEY* conflicting_key = NULL;
|
||||||
|
struct EDA_HOTKEY_CONFIG* conflicting_section = NULL;
|
||||||
|
|
||||||
|
for( wxTreeListItem item = GetFirstItem(); item.IsOk(); item = GetNextItem( item ) )
|
||||||
|
{
|
||||||
|
WIDGET_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 )
|
||||||
|
{
|
||||||
|
// This key and its conflict candidate are in orthogonal sections, so skip.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( aKey == hk.m_KeyCode )
|
||||||
|
{
|
||||||
|
conflicting_key = &hk;
|
||||||
|
|
||||||
|
// Find the section
|
||||||
|
HOTKEY_SECTIONS::iterator it;
|
||||||
|
for( it = m_sections.begin(); it != m_sections.end(); ++it )
|
||||||
|
{
|
||||||
|
if( *it->m_section->m_SectionTag == tag )
|
||||||
|
{
|
||||||
|
conflicting_section = it->m_section;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the outparams
|
||||||
|
if( aConfKey )
|
||||||
|
*aConfKey = conflicting_key;
|
||||||
|
|
||||||
|
if( aConfSect )
|
||||||
|
*aConfSect = conflicting_section;
|
||||||
|
|
||||||
|
return conflicting_key == NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool WIDGET_HOTKEY_LIST::ResolveKeyConflicts( long aKey, const wxString& aSectionTag )
|
||||||
|
{
|
||||||
|
EDA_HOTKEY* conflicting_key = NULL;
|
||||||
|
EDA_HOTKEY_CONFIG* conflicting_section = NULL;
|
||||||
|
|
||||||
|
CheckKeyConflicts( aKey, aSectionTag, &conflicting_key, &conflicting_section );
|
||||||
|
|
||||||
|
if( conflicting_key != NULL )
|
||||||
|
{
|
||||||
|
wxString info = wxGetTranslation( conflicting_key->m_InfoMsg );
|
||||||
|
wxString msg = wxString::Format(
|
||||||
|
_( "<%s> is already assigned to \"%s\" in section \"%s\". Are you sure you want "
|
||||||
|
"to change its assignment?" ),
|
||||||
|
KeyNameFromKeyCode( aKey ), GetChars( info ),
|
||||||
|
*(conflicting_section->m_Title) );
|
||||||
|
|
||||||
|
wxMessageDialog dlg( GetParent(), msg, _( "Confirm change" ), wxYES_NO | wxNO_DEFAULT );
|
||||||
|
|
||||||
|
if( dlg.ShowModal() == wxID_YES )
|
||||||
|
{
|
||||||
|
conflicting_key->m_KeyCode = 0;
|
||||||
|
UpdateFromClientData();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WIDGET_HOTKEY_LIST::WIDGET_HOTKEY_LIST( wxWindow* aParent, const HOTKEY_SECTIONS& aSections )
|
||||||
|
: wxTreeListCtrl( aParent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTL_SINGLE ),
|
||||||
|
m_sections( aSections )
|
||||||
|
{
|
||||||
|
AppendColumn( _( "Command" ) );
|
||||||
|
AppendColumn( _( "Hotkey" ) );
|
||||||
|
|
||||||
|
Bind( wxEVT_CHAR, &WIDGET_HOTKEY_LIST::OnChar, this );
|
||||||
|
Bind( wxEVT_SIZE, &WIDGET_HOTKEY_LIST::OnSize, this );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HOTKEY_SECTIONS WIDGET_HOTKEY_LIST::GenSections( EDA_HOTKEY_CONFIG* aHotkeys )
|
||||||
|
{
|
||||||
|
HOTKEY_SECTIONS sections;
|
||||||
|
for( EDA_HOTKEY_CONFIG* section = aHotkeys; section->m_HK_InfoList; ++section )
|
||||||
|
{
|
||||||
|
HOTKEY_SECTION sec;
|
||||||
|
sec.m_name = wxGetTranslation( *section->m_Title );
|
||||||
|
sec.m_section = section;
|
||||||
|
sections.push_back( sec );
|
||||||
|
}
|
||||||
|
return sections;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool WIDGET_HOTKEY_LIST::TransferDataToControl()
|
||||||
|
{
|
||||||
|
Freeze();
|
||||||
|
DeleteAllItems();
|
||||||
|
m_hotkeys.clear();
|
||||||
|
|
||||||
|
for( size_t sec_index = 0; sec_index < m_sections.size(); ++sec_index )
|
||||||
|
{
|
||||||
|
// LoadSection pushes into m_hotkeys
|
||||||
|
LoadSection( m_sections[sec_index].m_section );
|
||||||
|
wxASSERT( m_hotkeys.size() == sec_index + 1 );
|
||||||
|
|
||||||
|
wxString section_tag = *( m_sections[sec_index].m_section->m_SectionTag );
|
||||||
|
|
||||||
|
// Create parent tree item
|
||||||
|
wxTreeListItem parent = AppendItem( GetRootItem(), m_sections[sec_index].m_name );
|
||||||
|
|
||||||
|
HOTKEY_LIST& each_list = m_hotkeys[sec_index];
|
||||||
|
HOTKEY_LIST::iterator hk_it;
|
||||||
|
for( hk_it = each_list.begin(); hk_it != each_list.end(); ++hk_it )
|
||||||
|
{
|
||||||
|
wxTreeListItem item = AppendItem( parent, wxEmptyString );
|
||||||
|
SetItemData( item, new WIDGET_HOTKEY_CLIENT_DATA( &*hk_it, section_tag ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
Expand( parent );
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateFromClientData();
|
||||||
|
Thaw();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool WIDGET_HOTKEY_LIST::TransferDataFromControl()
|
||||||
|
{
|
||||||
|
for( size_t sec_index = 0; sec_index < m_sections.size(); ++sec_index )
|
||||||
|
{
|
||||||
|
EDA_HOTKEY_CONFIG* section = m_sections[sec_index].m_section;
|
||||||
|
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 ) )
|
||||||
|
{
|
||||||
|
WIDGET_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;
|
||||||
|
}
|
|
@ -30,7 +30,7 @@
|
||||||
#include <class_base_screen.h>
|
#include <class_base_screen.h>
|
||||||
|
|
||||||
#include <dialog_eeschema_options.h>
|
#include <dialog_eeschema_options.h>
|
||||||
#include <dialog_hotkeys_editor.h>
|
#include <widgets/widget_hotkey_list.h>
|
||||||
#include "../schframe.h"
|
#include "../schframe.h"
|
||||||
#include "hotkeys.h"
|
#include "hotkeys.h"
|
||||||
|
|
||||||
|
@ -65,8 +65,8 @@ DIALOG_EESCHEMA_OPTIONS::DIALOG_EESCHEMA_OPTIONS( SCH_EDIT_FRAME* parent ) :
|
||||||
}
|
}
|
||||||
|
|
||||||
// Embed the hotkeys list
|
// Embed the hotkeys list
|
||||||
HOTKEYS_SECTIONS sections = HOTKEY_LIST_CTRL::Sections( g_Eeschema_Hokeys_Descr );
|
HOTKEY_SECTIONS sections = WIDGET_HOTKEY_LIST::GenSections( g_Eeschema_Hokeys_Descr );
|
||||||
m_hotkeyListCtrl = new HOTKEY_LIST_CTRL( m_controlsPanel, sections );
|
m_hotkeyListCtrl = new WIDGET_HOTKEY_LIST( m_controlsPanel, sections );
|
||||||
// Insert after the "Hotkeys:" label
|
// Insert after the "Hotkeys:" label
|
||||||
m_controlsSizer->Insert( 1, m_hotkeyListCtrl, wxSizerFlags( 1 ).Expand().Border( wxALL, 5 ) );
|
m_controlsSizer->Insert( 1, m_hotkeyListCtrl, wxSizerFlags( 1 ).Expand().Border( wxALL, 5 ) );
|
||||||
|
|
||||||
|
|
|
@ -34,13 +34,13 @@
|
||||||
#include <dialog_eeschema_options_base.h>
|
#include <dialog_eeschema_options_base.h>
|
||||||
#include <template_fieldnames.h>
|
#include <template_fieldnames.h>
|
||||||
|
|
||||||
class HOTKEY_LIST_CTRL;
|
class WIDGET_HOTKEY_LIST;
|
||||||
class SCH_EDIT_FRAME;
|
class SCH_EDIT_FRAME;
|
||||||
|
|
||||||
class DIALOG_EESCHEMA_OPTIONS : public DIALOG_EESCHEMA_OPTIONS_BASE
|
class DIALOG_EESCHEMA_OPTIONS : public DIALOG_EESCHEMA_OPTIONS_BASE
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
HOTKEY_LIST_CTRL* m_hotkeyListCtrl;
|
WIDGET_HOTKEY_LIST* m_hotkeyListCtrl;
|
||||||
|
|
||||||
/** @brief The template fieldnames for this dialog */
|
/** @brief The template fieldnames for this dialog */
|
||||||
TEMPLATE_FIELDNAMES templateFields;
|
TEMPLATE_FIELDNAMES templateFields;
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 3
|
||||||
* of the License, or (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
@ -28,159 +28,9 @@
|
||||||
#ifndef __dialog_hotkeys_editor__
|
#ifndef __dialog_hotkeys_editor__
|
||||||
#define __dialog_hotkeys_editor__
|
#define __dialog_hotkeys_editor__
|
||||||
|
|
||||||
#include <wx/intl.h>
|
|
||||||
|
|
||||||
#include <wx/string.h>
|
|
||||||
#include <wx/choice.h>
|
|
||||||
#include <wx/gdicmn.h>
|
|
||||||
#include <wx/font.h>
|
|
||||||
#include <wx/settings.h>
|
|
||||||
#include <wx/textctrl.h>
|
|
||||||
#include <wx/stattext.h>
|
|
||||||
#include <wx/button.h>
|
|
||||||
#include <wx/treelist.h>
|
|
||||||
#include <wx/dialog.h>
|
|
||||||
#include <wx/grid.h>
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include <hotkeys_basic.h>
|
#include <hotkeys_basic.h>
|
||||||
#include <draw_frame.h>
|
|
||||||
#include <../common/dialogs/dialog_hotkeys_editor_base.h>
|
#include <../common/dialogs/dialog_hotkeys_editor_base.h>
|
||||||
|
#include <widgets/widget_hotkey_list.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 wxTreeListCtrl
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static HOTKEYS_SECTIONS Sections( EDA_HOTKEY_CONFIG* aHotkeys );
|
|
||||||
|
|
||||||
HOTKEY_LIST_CTRL( wxWindow* aParent, const HOTKEYS_SECTIONS& aSections );
|
|
||||||
~HOTKEY_LIST_CTRL() {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function DeselectRow
|
|
||||||
* Deselect the given row
|
|
||||||
*
|
|
||||||
* @param aRow is the row to deselect
|
|
||||||
*/
|
|
||||||
void DeselectRow( int aRow );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function TransferDataToControl
|
|
||||||
* Load the hotkey data into the control.
|
|
||||||
* @return true iff the operation was successful
|
|
||||||
*/
|
|
||||||
bool TransferDataToControl();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function TransferDataFromControl
|
|
||||||
* Save the hotkey data from the control.
|
|
||||||
* @return true iff the operation was successful
|
|
||||||
*/
|
|
||||||
bool TransferDataFromControl();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function ResolveKeyConflicts
|
|
||||||
* Check if we can set a hotkey, this will prompt the user if there
|
|
||||||
* is a conflict between keys. The key code should have already been
|
|
||||||
* checked that it's not for the same entry as its currently in or else
|
|
||||||
* it'll prompt the change on itself.
|
|
||||||
* The function will do conflict detection depending on aSectionTag.
|
|
||||||
* g_CommonSectionTag means the key code must be checked with all sections.
|
|
||||||
* While other tags means the key code only must be checked with the aSectionTag
|
|
||||||
* section and g_CommonSectionTag section.
|
|
||||||
*
|
|
||||||
* @param aKey is the key code that wants to be set
|
|
||||||
* @param aSectionTag is the section tag that the key code came from
|
|
||||||
*
|
|
||||||
* @return True if the user accepted the overwrite or no conflict existed
|
|
||||||
*/
|
|
||||||
bool ResolveKeyConflicts( long aKey, const wxString& aSectionTag );
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function CheckKeyConflicts
|
|
||||||
* 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 CheckKeyConflicts( 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 LoadSection( struct EDA_HOTKEY_CONFIG* aSection );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function OnGetItemText
|
|
||||||
* Returns the requested row, column data to the list control.
|
|
||||||
*
|
|
||||||
* @param aRow is the row of the data which matches our hotkeys vector as a index
|
|
||||||
* @param aColumn is the column of the data which is either Command(0) or KeyCode(1)
|
|
||||||
*
|
|
||||||
* @return String containing the text for the specified row, column combination
|
|
||||||
*/
|
|
||||||
wxString OnGetItemText( long aRow, long aColumn ) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function OnChar
|
|
||||||
* Decoded key press handler which is used to set key codes in the list control
|
|
||||||
*
|
|
||||||
* @param aEvent is the key press event, the keycode is retrieved from it
|
|
||||||
*/
|
|
||||||
void OnChar( wxKeyEvent& aEvent );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function OnSize
|
|
||||||
* Handle resizing of the control. Overrides the buggy wxTreeListCtrl::OnSize.
|
|
||||||
*/
|
|
||||||
void OnSize( wxSizeEvent& aEvent );
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class HOTKEYS_EDITOR_DIALOG
|
* Class HOTKEYS_EDITOR_DIALOG
|
||||||
|
@ -192,7 +42,7 @@ class HOTKEYS_EDITOR_DIALOG : public HOTKEYS_EDITOR_DIALOG_BASE
|
||||||
protected:
|
protected:
|
||||||
struct EDA_HOTKEY_CONFIG* m_hotkeys;
|
struct EDA_HOTKEY_CONFIG* m_hotkeys;
|
||||||
|
|
||||||
HOTKEY_LIST_CTRL* m_hotkeyListCtrl;
|
WIDGET_HOTKEY_LIST* m_hotkeyListCtrl;
|
||||||
|
|
||||||
bool TransferDataToWindow();
|
bool TransferDataToWindow();
|
||||||
bool TransferDataFromWindow();
|
bool TransferDataFromWindow();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2004-2011 KiCad Developers, see change_log.txt for contributors.
|
* Copyright (C) 2004-2016 KiCad Developers, see change_log.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -29,6 +29,8 @@
|
||||||
#ifndef HOTKEYS_BASIC_H
|
#ifndef HOTKEYS_BASIC_H
|
||||||
#define HOTKEYS_BASIC_H
|
#define HOTKEYS_BASIC_H
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
|
||||||
#define DEFAULT_HOTKEY_FILENAME_EXT wxT( "hotkeys" )
|
#define DEFAULT_HOTKEY_FILENAME_EXT wxT( "hotkeys" )
|
||||||
|
|
||||||
// A define to allow translation of Hot Key message Info in hotkey help menu
|
// A define to allow translation of Hot Key message Info in hotkey help menu
|
||||||
|
|
|
@ -0,0 +1,170 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 Chris Pavlina <pavlina.chris@gmail.com>
|
||||||
|
* Copyright (C) 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
|
||||||
|
* as published by the Free Software Foundation; either version 3
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file widget_hotkey_list
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __widget_hotkey_list__
|
||||||
|
#define __widget_hotkey_list__
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <wx/treelist.h>
|
||||||
|
|
||||||
|
#include <hotkeys_basic.h>
|
||||||
|
|
||||||
|
/// Width of the hotkey list
|
||||||
|
const int WIDGET_HOTKEY_LIST_HKCOLUMN_WIDTH = 100;
|
||||||
|
|
||||||
|
/// Extra margin to compensate for vertical scrollbar
|
||||||
|
const int WIDGET_HOTKEY_LIST_HMARGIN = 30;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct HOTKEY_SECTION
|
||||||
|
* Associates a hotkey configuration with a name.
|
||||||
|
*/
|
||||||
|
struct HOTKEY_SECTION
|
||||||
|
{
|
||||||
|
wxString m_name;
|
||||||
|
EDA_HOTKEY_CONFIG* m_section;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::vector<HOTKEY_SECTION> HOTKEY_SECTIONS;
|
||||||
|
typedef std::vector<EDA_HOTKEY> HOTKEY_LIST;
|
||||||
|
|
||||||
|
class WIDGET_HOTKEY_CLIENT_DATA;
|
||||||
|
|
||||||
|
class WIDGET_HOTKEY_LIST : public wxTreeListCtrl
|
||||||
|
{
|
||||||
|
HOTKEY_SECTIONS m_sections;
|
||||||
|
std::vector<HOTKEY_LIST> m_hotkeys;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method GetHKClientData
|
||||||
|
* Return the WIDGET_HOTKEY_CLIENT_DATA for the given item, or NULL if the
|
||||||
|
* item is invalid.
|
||||||
|
*/
|
||||||
|
WIDGET_HOTKEY_CLIENT_DATA* GetHKClientData( wxTreeListItem aItem );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method GetSelHKClientData
|
||||||
|
* Return the WIDGET_HOTKEY_CLIENT_DATA for the item being edited, or NULL if
|
||||||
|
* none is selected.
|
||||||
|
*/
|
||||||
|
WIDGET_HOTKEY_CLIENT_DATA* GetSelHKClientData();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method UpdateFromClientData
|
||||||
|
* Refresh the visible text on the widget from the rows' client data objects.
|
||||||
|
*/
|
||||||
|
void UpdateFromClientData();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Method LoadSection
|
||||||
|
* Generates a HOTKEY_LIST from the given hotkey configuration array and pushes
|
||||||
|
* it to m_hotkeys.
|
||||||
|
*/
|
||||||
|
void LoadSection( EDA_HOTKEY_CONFIG* aSection );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function OnChar
|
||||||
|
* Handle keypress.
|
||||||
|
* XXX REMOVE
|
||||||
|
*/
|
||||||
|
void OnChar( wxKeyEvent& aEvent );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function OnSize
|
||||||
|
* Handle resizing of the control. Overrides the buggy wxTreeListCtrl::OnSize.
|
||||||
|
*/
|
||||||
|
void OnSize( wxSizeEvent& aEvent );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method CheckKeyConflicts
|
||||||
|
* Check whether the given key conflicts with anything in this WIDGET_HOTKEY_LIST.
|
||||||
|
*
|
||||||
|
* @param aKey - key to check
|
||||||
|
* @param aSectionTag - section tag into which the key is proposed to be installed
|
||||||
|
* @param aConfKey - if not NULL, outparam getting the key this one conflicts with
|
||||||
|
* @param aConfSect - if not NULL, outparam getting the section this one conflicts with
|
||||||
|
*/
|
||||||
|
bool CheckKeyConflicts( long aKey, const wxString& aSectionTag,
|
||||||
|
EDA_HOTKEY** aConfKey, EDA_HOTKEY_CONFIG** aConfSect );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method ResolveKeyConflicts
|
||||||
|
* Check if we can set a hotkey, and prompt the user if there is a conflict between
|
||||||
|
* keys. The key code should already have been checked that it's not for the same
|
||||||
|
* entry as it's current in, or else this method will prompt for the self-change.
|
||||||
|
*
|
||||||
|
* The method will do conflict resolution depending on aSectionTag.
|
||||||
|
* g_CommonSectionTag means the key code must only be checkd with the aSectionTag
|
||||||
|
* section and g_CommonSectionTag section.
|
||||||
|
*
|
||||||
|
* @param aKey - key to check
|
||||||
|
* @param aSectionTag - section tag into which the key is proposed to be installed
|
||||||
|
*
|
||||||
|
* @return true iff the user accepted the overwrite or no conflict existed
|
||||||
|
*/
|
||||||
|
bool ResolveKeyConflicts( long aKey, const wxString& aSectionTag );
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor WIDGET_HOTKEY_LIST
|
||||||
|
* Create a WIDGET_HOTKEY_LIST.
|
||||||
|
*
|
||||||
|
* @param aParent - parent widget
|
||||||
|
* @param aSections - list of the hotkey sections to display and their names.
|
||||||
|
* See WIDGET_HOTKEY_LIST::GenSections for a way to generate these easily
|
||||||
|
* from an EDA_HOTKEY_CONFIG*.
|
||||||
|
*/
|
||||||
|
WIDGET_HOTKEY_LIST( wxWindow* aParent, const HOTKEY_SECTIONS& aSections );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static method GenSections
|
||||||
|
* Generate a list of sections and names from an EDA_HOTKEY_CONFIG*. Titles
|
||||||
|
* will be looked up from translations.
|
||||||
|
*/
|
||||||
|
static HOTKEY_SECTIONS GenSections( EDA_HOTKEY_CONFIG* aHotkeys );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method TransferDataToControl
|
||||||
|
* Load the hotkey data into the control. It is safe to call this multiple times,
|
||||||
|
* for example to reset the control.
|
||||||
|
* @return true iff the operation was successful
|
||||||
|
*/
|
||||||
|
bool TransferDataToControl();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method TransferDataFromControl
|
||||||
|
* Save the hotkey data from the control.
|
||||||
|
* @return true iff the operation was successful
|
||||||
|
*/
|
||||||
|
bool TransferDataFromControl();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __widget_hotkey_list__
|
Loading…
Reference in New Issue