diff --git a/common/hotkey_store.cpp b/common/hotkey_store.cpp index 62e9fc424b..479d9c67ac 100644 --- a/common/hotkey_store.cpp +++ b/common/hotkey_store.cpp @@ -53,6 +53,30 @@ std::vector& HOTKEY_STORE::GetSections() } +CHANGED_HOTKEY* HOTKEY_STORE::FindHotkey( const wxString& aTag, int aCmdId ) +{ + CHANGED_HOTKEY* found_key = nullptr; + + for( auto& section: m_hk_sections ) + { + if( *section.m_section.m_SectionTag != aTag) + continue; + + for( auto& hotkey: section.m_hotkeys ) + { + auto& curr_hk = hotkey.GetCurrentValue(); + if( curr_hk.m_Idcommand == aCmdId ) + { + found_key = &hotkey; + break; + } + } + } + + return found_key; +} + + void HOTKEY_STORE::SaveAllHotkeys() { for( auto& section: m_hk_sections ) @@ -98,6 +122,7 @@ bool HOTKEY_STORE::CheckKeyConflicts( long aKey, const wxString& aSectionTag, for( auto& section: m_hk_sections ) { const auto& sectionTag = *section.m_section.m_SectionTag; + if( aSectionTag != g_CommonSectionTag && sectionTag != g_CommonSectionTag && sectionTag != aSectionTag ) diff --git a/include/hotkey_store.h b/include/hotkey_store.h index 13b985b36c..cbeb58d347 100644 --- a/include/hotkey_store.h +++ b/include/hotkey_store.h @@ -126,6 +126,13 @@ public: */ SECTION_LIST& GetSections(); + + /** + * Find a hotkey with the given command ID and in the given section + * @return pointer to the hotkey if found. + */ + CHANGED_HOTKEY* FindHotkey( const wxString& aTag, int aCmdId ); + /** * Persist all changes to hotkeys in the store to the underlying * data structures. diff --git a/qa/common/CMakeLists.txt b/qa/common/CMakeLists.txt index b5aae6c3cd..e6c1632964 100644 --- a/qa/common/CMakeLists.txt +++ b/qa/common/CMakeLists.txt @@ -26,8 +26,13 @@ find_package( wxWidgets 3.0.0 COMPONENTS gl aui adv html core net base xml stc R add_definitions(-DBOOST_TEST_DYN_LINK) add_executable( qa_common + # This is needed for the global mock objects + common_mocks.cpp + + # The main test entry points test_module.cpp + test_hotkey_store.cpp test_utf8.cpp geometry/test_fillet.cpp @@ -43,6 +48,7 @@ include_directories( target_link_libraries( qa_common common polygon + bitmaps ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} ${wxWidgets_LIBRARIES} ) diff --git a/qa/common/common_mocks.cpp b/qa/common/common_mocks.cpp new file mode 100644 index 0000000000..9b54ee6ec8 --- /dev/null +++ b/qa/common/common_mocks.cpp @@ -0,0 +1,42 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2018 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * @file common_mocks.cpp + * @brief Mock objects for libcommon unit tests + */ + +#include + + +struct PGM_TEST_FRAME : public PGM_BASE +{ + void MacOpenFile( const wxString& aFileName ) override + {} +}; + +PGM_BASE& Pgm() +{ + static PGM_TEST_FRAME program; + return program; +} \ No newline at end of file diff --git a/qa/common/test_hotkey_store.cpp b/qa/common/test_hotkey_store.cpp new file mode 100644 index 0000000000..e6db29f101 --- /dev/null +++ b/qa/common/test_hotkey_store.cpp @@ -0,0 +1,148 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2018 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 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include + +#include + +// ---------------------------------------------------------------------------- +// Dummy Hotkey definitions + +static EDA_HOTKEY actionA1( _HKI("A1"), 1001, WXK_F1 ); +static EDA_HOTKEY actionA2( _HKI("A2"), 1002, WXK_F2 ); + +static wxString sectionATag( "[a]" ); +static wxString sectionATitle( "Section A" ); + +static EDA_HOTKEY actionB1( _HKI("B1"), 2001, WXK_F10 ); +static EDA_HOTKEY actionB2( _HKI("B2"), 2002, WXK_F11 ); + +static wxString sectionBTag( "[b]" ); +static wxString sectionBTitle( "Section B" ); + +// A keycode that is unused by any hotkey +static const int unused_keycode = WXK_F5; + +// List of hotkey descriptors for library editor +static EDA_HOTKEY* sectionAHotkeyList[] = +{ + &actionA1, + &actionA2, + NULL +}; + +static EDA_HOTKEY* sectionBHotkeyList[] = +{ + &actionB1, + &actionB2, + NULL +}; + +static EDA_HOTKEY_CONFIG test_hokeys_descr[] = +{ + { §ionATag, sectionAHotkeyList, §ionATitle }, + { §ionBTag, sectionBHotkeyList, §ionBTitle }, + { NULL, NULL, NULL } +}; + +// Number of sections in the above table +static const unsigned num_cfg_sections = + sizeof( test_hokeys_descr ) / sizeof( EDA_HOTKEY_CONFIG ) - 1; + +// ---------------------------------------------------------------------------- + +struct HotkeyStoreFixture +{ + HotkeyStoreFixture(): + m_hotkey_store( test_hokeys_descr ) + {} + + HOTKEY_STORE m_hotkey_store; +}; + + +/** + * Declares a struct as the Boost test fixture. + */ +BOOST_FIXTURE_TEST_SUITE( HotkeyStore, HotkeyStoreFixture ) + + +/** + * Check conflict detections + */ +BOOST_AUTO_TEST_CASE( StoreConstruction ) +{ + // Should have ingested two sections (A and B) + BOOST_CHECK_EQUAL( m_hotkey_store.GetSections().size(), num_cfg_sections ); +} + + +/** + * Check conflict detections + */ +BOOST_AUTO_TEST_CASE( HotkeyConflict ) +{ + EDA_HOTKEY* conf_key = nullptr; + EDA_HOTKEY_CONFIG* conf_sect = nullptr; + bool conflict; + + conflict = m_hotkey_store.CheckKeyConflicts( unused_keycode, sectionATag, + &conf_key, &conf_sect ); + + // No conflicts + BOOST_CHECK_EQUAL( conflict, true ); + + conflict = m_hotkey_store.CheckKeyConflicts( actionA1.m_KeyCode, sectionATag, + &conf_key, &conf_sect ); + + // See if we conflicted with the correct key in the correct section + BOOST_CHECK_EQUAL( conflict, false ); + BOOST_CHECK_EQUAL( conf_key->m_Idcommand, actionA1.m_Idcommand ); + BOOST_CHECK_EQUAL( conf_sect, &test_hokeys_descr[0] ); +} + + +/** + * Check the undo works + */ +BOOST_AUTO_TEST_CASE( HotkeySetUndo ) +{ + CHANGED_HOTKEY* hk = m_hotkey_store.FindHotkey( sectionATag, actionA1.m_Idcommand ); + + // Found something + BOOST_CHECK( hk ); + BOOST_CHECK_EQUAL( hk->GetCurrentValue().m_Idcommand, actionA1.m_Idcommand ); + + // Change the Key code + hk->GetCurrentValue().m_KeyCode = unused_keycode; + + // Change everything back + m_hotkey_store.ResetAllHotkeysToDefault(); + + // Check it went back + BOOST_CHECK_EQUAL( hk->GetCurrentValue().m_Idcommand, actionA1.m_Idcommand ); +} + + +BOOST_AUTO_TEST_SUITE_END()