From e32b26ebeb300ef5c6edc773d6852c60b85f980d Mon Sep 17 00:00:00 2001 From: Marek Roszko Date: Wed, 13 Mar 2024 22:49:01 -0400 Subject: [PATCH] Move JSON_SETTINGS and PARAMS to kicommon --- common/CMakeLists.txt | 15 +- common/database/database_lib_settings.cpp | 2 +- common/io/easyeda/easyeda_parser_structs.cpp | 2 +- .../io/easyedapro/easyedapro_import_utils.cpp | 2 +- common/io/easyedapro/easyedapro_parser.cpp | 2 +- common/notifications_manager.cpp | 2 +- common/project/net_settings.cpp | 1 - common/settings/common_settings.cpp | 2 +- common/settings/json_settings.cpp | 107 ++++--- common/settings/parameters.cpp | 267 ++---------------- include/import_export.h | 10 + include/json_common.h | 35 +++ include/project/net_settings.h | 2 +- include/settings/aui_settings.h | 26 +- include/settings/bom_settings.h | 30 +- include/settings/grid_settings.h | 10 +- include/settings/json_settings.h | 52 +++- include/settings/json_settings_internals.h | 5 +- include/settings/nested_settings.h | 2 +- include/settings/parameters.h | 233 +++++++++++++-- kicad/pcm/pcm.h | 1 + kicad/pcm/pcm_data.h | 2 +- .../pcb_io/easyedapro/pcb_io_easyedapro.cpp | 2 +- .../json_schema_validator/CMakeLists.txt | 3 + .../nlohmann/json-schema.hpp | 1 + 25 files changed, 447 insertions(+), 369 deletions(-) create mode 100644 include/json_common.h diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 16642e1c9f..2e9235f631 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -97,6 +97,13 @@ set( KICOMMON_SRCS kicad_curl/kicad_curl.cpp kicad_curl/kicad_curl_easy.cpp + settings/aui_settings.cpp + settings/bom_settings.cpp + settings/grid_settings.cpp + settings/json_settings.cpp + settings/nested_settings.cpp + settings/parameters.cpp + widgets/progress_reporter_base.cpp widgets/std_bitmap_button.cpp @@ -135,6 +142,8 @@ add_library( kicommon SHARED ${KICOMMON_SRCS} ) +set_target_properties(kicommon PROPERTIES CXX_VISIBILITY_PRESET hidden) + target_link_libraries( kicommon core kimath @@ -564,15 +573,9 @@ set( COMMON_SRCS tool/zoom_tool.cpp settings/app_settings.cpp - settings/aui_settings.cpp - settings/bom_settings.cpp settings/color_settings.cpp settings/cvpcb_settings.cpp settings/common_settings.cpp - settings/grid_settings.cpp - settings/json_settings.cpp - settings/nested_settings.cpp - settings/parameters.cpp settings/settings_manager.cpp settings/kicad_settings.cpp diff --git a/common/database/database_lib_settings.cpp b/common/database/database_lib_settings.cpp index 39929e7807..541e45344d 100644 --- a/common/database/database_lib_settings.cpp +++ b/common/database/database_lib_settings.cpp @@ -22,7 +22,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#include +#include #include #include diff --git a/common/io/easyeda/easyeda_parser_structs.cpp b/common/io/easyeda/easyeda_parser_structs.cpp index 567aeb67f5..e9f4f349d5 100644 --- a/common/io/easyeda/easyeda_parser_structs.cpp +++ b/common/io/easyeda/easyeda_parser_structs.cpp @@ -24,7 +24,7 @@ #include "easyeda_parser_structs.h" -#include +#include #include diff --git a/common/io/easyedapro/easyedapro_import_utils.cpp b/common/io/easyedapro/easyedapro_import_utils.cpp index 0d530cb6c6..14f211af63 100644 --- a/common/io/easyedapro/easyedapro_import_utils.cpp +++ b/common/io/easyedapro/easyedapro_import_utils.cpp @@ -29,7 +29,7 @@ #include #include -#include +#include #include #include diff --git a/common/io/easyedapro/easyedapro_parser.cpp b/common/io/easyedapro/easyedapro_parser.cpp index b1f0f18785..1bfeced634 100644 --- a/common/io/easyedapro/easyedapro_parser.cpp +++ b/common/io/easyedapro/easyedapro_parser.cpp @@ -26,7 +26,7 @@ #include -#include +#include #include #include diff --git a/common/notifications_manager.cpp b/common/notifications_manager.cpp index ea0a39b0f1..4c3358a633 100644 --- a/common/notifications_manager.cpp +++ b/common/notifications_manager.cpp @@ -36,13 +36,13 @@ #include #include +#include #include "core/wx_stl_compat.h" #include #include #include -#include #include #include #include diff --git a/common/project/net_settings.cpp b/common/project/net_settings.cpp index 98453c48a4..ba265c619c 100644 --- a/common/project/net_settings.cpp +++ b/common/project/net_settings.cpp @@ -23,7 +23,6 @@ #include #include -#include #include #include #include diff --git a/common/settings/common_settings.cpp b/common/settings/common_settings.cpp index 53c0fc438f..4fb2b856ff 100644 --- a/common/settings/common_settings.cpp +++ b/common/settings/common_settings.cpp @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/common/settings/json_settings.cpp b/common/settings/json_settings.cpp index 3846ab78e5..6f4c8bbcab 100644 --- a/common/settings/json_settings.cpp +++ b/common/settings/json_settings.cpp @@ -43,8 +43,6 @@ #include #include -const wxChar* const traceSettings = wxT( "KICAD_SETTINGS" ); - nlohmann::json::json_pointer JSON_SETTINGS_INTERNALS::PointerFromString( std::string aPath ) { @@ -591,23 +589,37 @@ std::optional JSON_SETTINGS::Get( const std::string& aPath ) const // Instantiate all required templates here to allow reducing scope of json.hpp -template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; -template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; -template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; -template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; -template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; -template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; -template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; -template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; -template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; -template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; -template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; -template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; -template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; -template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; -template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; -template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; -template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; +template KICOMMON_API std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; +template KICOMMON_API std::optional + JSON_SETTINGS::Get( const std::string& aPath ) const; +template KICOMMON_API std::optional + JSON_SETTINGS::Get( const std::string& aPath ) const; +template KICOMMON_API std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; +template KICOMMON_API std::optional + JSON_SETTINGS::Get( const std::string& aPath ) const; +template KICOMMON_API std::optional + JSON_SETTINGS::Get( const std::string& aPath ) const; +template KICOMMON_API std::optional + JSON_SETTINGS::Get( const std::string& aPath ) const; +template KICOMMON_API std::optional + JSON_SETTINGS::Get( const std::string& aPath ) const; +template KICOMMON_API std::optional + JSON_SETTINGS::Get( const std::string& aPath ) const; +template KICOMMON_API std::optional + JSON_SETTINGS::Get( const std::string& aPath ) const; +template KICOMMON_API std::optional + JSON_SETTINGS::Get( const std::string& aPath ) const; +template KICOMMON_API std::optional + JSON_SETTINGS::Get( const std::string& aPath ) const; +template KICOMMON_API std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; +template KICOMMON_API std::optional + JSON_SETTINGS::Get( const std::string& aPath ) const; +template KICOMMON_API std::optional + JSON_SETTINGS::Get( const std::string& aPath ) const; +template KICOMMON_API std::optional + JSON_SETTINGS::Get( const std::string& aPath ) const; +template KICOMMON_API std::optional + JSON_SETTINGS::Get( const std::string& aPath ) const; template void JSON_SETTINGS::Set( const std::string& aPath, ValueType aVal ) @@ -617,24 +629,34 @@ void JSON_SETTINGS::Set( const std::string& aPath, ValueType aVal ) // Instantiate all required templates here to allow reducing scope of json.hpp -template void JSON_SETTINGS::Set( const std::string& aPath, bool aValue ); -template void JSON_SETTINGS::Set( const std::string& aPath, double aValue ); -template void JSON_SETTINGS::Set( const std::string& aPath, float aValue ); -template void JSON_SETTINGS::Set( const std::string& aPath, int aValue ); -template void JSON_SETTINGS::Set( const std::string& aPath, unsigned int aValue ); -template void JSON_SETTINGS::Set( const std::string& aPath, unsigned long long aValue ); -template void JSON_SETTINGS::Set( const std::string& aPath, const char* aValue ); -template void JSON_SETTINGS::Set( const std::string& aPath, std::string aValue ); -template void JSON_SETTINGS::Set( const std::string& aPath, nlohmann::json aValue ); -template void JSON_SETTINGS::Set( const std::string& aPath, KIGFX::COLOR4D aValue ); -template void JSON_SETTINGS::Set( const std::string& aPath, BOM_FIELD aValue ); -template void JSON_SETTINGS::Set( const std::string& aPath, BOM_PRESET aValue ); -template void JSON_SETTINGS::Set( const std::string& aPath, BOM_FMT_PRESET aValue ); -template void JSON_SETTINGS::Set( const std::string& aPath, GRID aValue ); -template void JSON_SETTINGS::Set( const std::string& aPath, wxPoint aValue ); -template void JSON_SETTINGS::Set( const std::string& aPath, wxSize aValue ); -template void JSON_SETTINGS::Set( const std::string& aPath, wxRect aValue ); -template void JSON_SETTINGS::Set( const std::string& aPath, wxAuiPaneInfo aValue ); +template KICOMMON_API void JSON_SETTINGS::Set( const std::string& aPath, bool aValue ); +template KICOMMON_API void JSON_SETTINGS::Set( const std::string& aPath, double aValue ); +template KICOMMON_API void JSON_SETTINGS::Set( const std::string& aPath, float aValue ); +template KICOMMON_API void JSON_SETTINGS::Set( const std::string& aPath, int aValue ); +template KICOMMON_API void JSON_SETTINGS::Set( const std::string& aPath, + unsigned int aValue ); +template KICOMMON_API void JSON_SETTINGS::Set( const std::string& aPath, + unsigned long long aValue ); +template KICOMMON_API void JSON_SETTINGS::Set( const std::string& aPath, + const char* aValue ); +template KICOMMON_API void JSON_SETTINGS::Set( const std::string& aPath, + std::string aValue ); +template KICOMMON_API void JSON_SETTINGS::Set( const std::string& aPath, + nlohmann::json aValue ); +template KICOMMON_API void JSON_SETTINGS::Set( const std::string& aPath, + KIGFX::COLOR4D aValue ); +template KICOMMON_API void JSON_SETTINGS::Set( const std::string& aPath, + BOM_FIELD aValue ); +template KICOMMON_API void JSON_SETTINGS::Set( const std::string& aPath, + BOM_PRESET aValue ); +template KICOMMON_API void JSON_SETTINGS::Set( const std::string& aPath, + BOM_FMT_PRESET aValue ); +template KICOMMON_API void JSON_SETTINGS::Set( const std::string& aPath, GRID aValue ); +template KICOMMON_API void JSON_SETTINGS::Set( const std::string& aPath, wxPoint aValue ); +template KICOMMON_API void JSON_SETTINGS::Set( const std::string& aPath, wxSize aValue ); +template KICOMMON_API void JSON_SETTINGS::Set( const std::string& aPath, wxRect aValue ); +template KICOMMON_API void JSON_SETTINGS::Set( const std::string& aPath, + wxAuiPaneInfo aValue ); void JSON_SETTINGS::registerMigration( int aOldSchemaVersion, int aNewSchemaVersion, @@ -775,13 +797,13 @@ bool JSON_SETTINGS::fromLegacy( wxConfigBase* aConfig, const std::string& aKey, // Explicitly declare these because we only support a few types anyway, and it means we can keep // wxConfig detail out of the header file -template bool JSON_SETTINGS::fromLegacy( wxConfigBase*, const std::string&, +template KICOMMON_API bool JSON_SETTINGS::fromLegacy( wxConfigBase*, const std::string&, const std::string& ); -template bool JSON_SETTINGS::fromLegacy( wxConfigBase*, const std::string&, +template KICOMMON_API bool JSON_SETTINGS::fromLegacy( wxConfigBase*, const std::string&, const std::string& ); -template bool JSON_SETTINGS::fromLegacy( wxConfigBase*, const std::string&, +template KICOMMON_API bool JSON_SETTINGS::fromLegacy( wxConfigBase*, const std::string&, const std::string& ); @@ -914,9 +936,10 @@ ResultType JSON_SETTINGS::fetchOrDefault( const nlohmann::json& aJson, const std } -template std::string JSON_SETTINGS::fetchOrDefault( const nlohmann::json& aJson, +template KICOMMON_API std::string JSON_SETTINGS::fetchOrDefault( const nlohmann::json& aJson, const std::string& aKey, std::string aDefault ); -template bool JSON_SETTINGS::fetchOrDefault( const nlohmann::json& aJson, const std::string& aKey, +template KICOMMON_API bool JSON_SETTINGS::fetchOrDefault( const nlohmann::json& aJson, + const std::string& aKey, bool aDefault ); diff --git a/common/settings/parameters.cpp b/common/settings/parameters.cpp index 96f6fcbbaf..d7d5442c27 100644 --- a/common/settings/parameters.cpp +++ b/common/settings/parameters.cpp @@ -22,192 +22,8 @@ #include -#include #include #include -#include -#include - -template -void PARAM_LAMBDA::Load( JSON_SETTINGS* aSettings, bool aResetIfMissing ) const -{ - if( m_readOnly ) - return; - - if( std::is_same::value ) - { - if( std::optional optval = aSettings->GetJson( m_path ) ) - m_setter( *optval ); - else - m_setter( m_default ); - } - else - { - if( std::optional optval = aSettings->Get( m_path ) ) - m_setter( *optval ); - else - m_setter( m_default ); - } -} - - -template -bool PARAM_LAMBDA::MatchesFile( JSON_SETTINGS* aSettings ) const -{ - if( std::is_same::value ) - { - if( std::optional optval = aSettings->GetJson( m_path ) ) - return *optval == m_getter(); - } - else - { - if( std::optional optval = aSettings->Get( m_path ) ) - return *optval == m_getter(); - } - - // Not in file - return false; -} - - -// Instantiate all required templates here to allow reducing scope of json.hpp -template class PARAM_LAMBDA; -template class PARAM_LAMBDA; -template class PARAM_LAMBDA; -template class PARAM_LAMBDA; - -template -void PARAM_LIST::Load( JSON_SETTINGS* aSettings, bool aResetIfMissing ) const -{ - if( m_readOnly ) - return; - - if( std::optional js = aSettings->GetJson( m_path ) ) - { - std::vector val; - - if( js->is_array() ) - { - for( const auto& el : js->items() ) - val.push_back( el.value().get() ); - } - - *m_ptr = val; - } - else if( aResetIfMissing ) - *m_ptr = m_default; -} - - -template -void PARAM_LIST::Store( JSON_SETTINGS* aSettings ) const -{ - nlohmann::json js = nlohmann::json::array(); - - for( const auto& el : *m_ptr ) - js.push_back( el ); - - aSettings->Set( m_path, js ); -} - - -template -bool PARAM_LIST::MatchesFile( JSON_SETTINGS* aSettings ) const -{ - if( std::optional js = aSettings->GetJson( m_path ) ) - { - if( js->is_array() ) - { - std::vector val; - - for( const auto& el : js->items() ) - { - try - { - val.emplace_back( el.value().get() ); - } - catch( ... ) - { - // Probably typecast didn't work; skip this element - } - } - - return val == *m_ptr; - } - } - - return false; -} - - -template class PARAM_LIST; -template class PARAM_LIST; -template class PARAM_LIST; -template class PARAM_LIST; -template class PARAM_LIST; -template class PARAM_LIST; -template class PARAM_LIST; -template class PARAM_LIST; -template class PARAM_LIST; - - -template -void PARAM_SET::Load( JSON_SETTINGS* aSettings, bool aResetIfMissing ) const -{ - if( m_readOnly ) - return; - - if( std::optional js = aSettings->GetJson( m_path ) ) - { - std::set val; - - if( js->is_array() ) - { - for( const auto& el : js->items() ) - val.insert( el.value().get() ); - } - - *m_ptr = val; - } - else if( aResetIfMissing ) - *m_ptr = m_default; -} - - -template -void PARAM_SET::Store( JSON_SETTINGS* aSettings ) const -{ - nlohmann::json js = nlohmann::json::array(); - - for( const auto& el : *m_ptr ) - js.push_back( el ); - - aSettings->Set( m_path, js ); -} - - -template -bool PARAM_SET::MatchesFile( JSON_SETTINGS* aSettings ) const -{ - if( std::optional js = aSettings->GetJson( m_path ) ) - { - if( js->is_array() ) - { - std::set val; - - for( const auto& el : js->items() ) - val.insert( el.value().get() ); - - return val == *m_ptr; - } - } - - return false; -} - - -template class PARAM_SET; - void PARAM_PATH_LIST::Store( JSON_SETTINGS* aSettings ) const { @@ -239,66 +55,6 @@ bool PARAM_PATH_LIST::MatchesFile( JSON_SETTINGS* aSettings ) const } -template -void PARAM_MAP::Load( JSON_SETTINGS* aSettings, bool aResetIfMissing ) const -{ - if( m_readOnly ) - return; - - if( std::optional js = aSettings->GetJson( m_path ) ) - { - if( js->is_object() ) - { - m_ptr->clear(); - - for( const auto& el : js->items() ) - ( *m_ptr )[el.key()] = el.value().get(); - } - } - else if( aResetIfMissing ) - *m_ptr = m_default; -} - - -template -void PARAM_MAP::Store( JSON_SETTINGS* aSettings ) const -{ - nlohmann::json js( {} ); - - for( const auto& el : *m_ptr ) - js[el.first] = el.second; - - aSettings->Set( m_path, js ); -} - - -template -bool PARAM_MAP::MatchesFile( JSON_SETTINGS* aSettings ) const -{ - if( std::optional js = aSettings->GetJson( m_path ) ) - { - if( js->is_object() ) - { - if( m_ptr->size() != js->size() ) - return false; - - std::map val; - - for( const auto& el : js->items() ) - val[el.key()] = el.value().get(); - - return val == *m_ptr; - } - } - - return false; -} - - -template class PARAM_MAP; -template class PARAM_MAP; -template class PARAM_MAP; - void PARAM_WXSTRING_MAP::Load( JSON_SETTINGS* aSettings, bool aResetIfMissing ) const { @@ -359,3 +115,26 @@ bool PARAM_WXSTRING_MAP::MatchesFile( JSON_SETTINGS* aSettings ) const return false; } + + +// Instantiate all required templates here and export +template class KICOMMON_API PARAM_LAMBDA; +template class KICOMMON_API PARAM_LAMBDA; +template class KICOMMON_API PARAM_LAMBDA; +template class KICOMMON_API PARAM_LAMBDA; + +template class KICOMMON_API PARAM_LIST; +template class KICOMMON_API PARAM_LIST; +template class KICOMMON_API PARAM_LIST; +template class KICOMMON_API PARAM_LIST; +template class KICOMMON_API PARAM_LIST; +//template KICOMMON_API class PARAM_LIST; +template class KICOMMON_API PARAM_LIST; +template class KICOMMON_API PARAM_LIST; +template class KICOMMON_API PARAM_LIST; + +template class KICOMMON_API PARAM_SET; + +template class KICOMMON_API PARAM_MAP; +template class KICOMMON_API PARAM_MAP; +template class KICOMMON_API PARAM_MAP; \ No newline at end of file diff --git a/include/import_export.h b/include/import_export.h index fd302037c9..d415814a45 100644 --- a/include/import_export.h +++ b/include/import_export.h @@ -44,6 +44,16 @@ #define APILOCAL #endif +// We use APIVISIBLE to mark extern template declarations where we cannot use APIEXPORT +// Because MSVC disallows mixing dllexport and extern templates, we can't just use APIEXPORT +// However MSVC is fine with the dllexport in the cpp file and extern in the header +// But we need the visibility declared on both instantiation and extern for GCC/Clang to make +// the symbol visible +#if defined( __GNUC__ ) || defined( __clang__ ) + #define APIVISIBLE __attribute__ ((visibility("default"))) +#else + #define APIVISIBLE +#endif #if defined(COMPILING_DLL) #define KIFACE_API APIEXPORT diff --git a/include/json_common.h b/include/json_common.h new file mode 100644 index 0000000000..71598dbcc2 --- /dev/null +++ b/include/json_common.h @@ -0,0 +1,35 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2024 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 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, see . + */ + +#ifndef JSON_COMMON_H +#define JSON_COMMON_H + +#include + +#include + +/** + * This is simply a "stub" meant to inform MSVC when compiling shared libraries that it can find + * template instances in kicommon of nlohmann::json's various templates + */ +class KICOMMON_API JSON_COMMON_EXPORT_STUB final : public nlohmann::json +{ +}; + +#endif \ No newline at end of file diff --git a/include/project/net_settings.h b/include/project/net_settings.h index 2ad4040f9b..ec2ec822c6 100644 --- a/include/project/net_settings.h +++ b/include/project/net_settings.h @@ -64,7 +64,7 @@ public: /** * Get a NETCLASS object from a given Netclass name string - * + * * @param aNetClassName the Netclass name to resolve * @return shared pointer to the requested NETCLASS object, or the default NETCLASS */ diff --git a/include/settings/aui_settings.h b/include/settings/aui_settings.h index f4bb8cc056..1f1b191a67 100644 --- a/include/settings/aui_settings.h +++ b/include/settings/aui_settings.h @@ -30,21 +30,21 @@ class wxPoint; class wxRect; class wxSize; -extern void to_json( nlohmann::json& aJson, const wxPoint& aPoint ); -extern void from_json( const nlohmann::json& aJson, wxPoint& aPoint ); -extern bool operator<( const wxPoint& aLhs, const wxPoint& aRhs ); +KICOMMON_API void to_json( nlohmann::json& aJson, const wxPoint& aPoint ); +KICOMMON_API void from_json( const nlohmann::json& aJson, wxPoint& aPoint ); +KICOMMON_API bool operator<( const wxPoint& aLhs, const wxPoint& aRhs ); -extern void to_json( nlohmann::json& aJson, const wxSize& aPoint ); -extern void from_json( const nlohmann::json& aJson, wxSize& aPoint ); -extern bool operator<( const wxSize& aLhs, const wxSize& aRhs ); +KICOMMON_API void to_json( nlohmann::json& aJson, const wxSize& aPoint ); +KICOMMON_API void from_json( const nlohmann::json& aJson, wxSize& aPoint ); +KICOMMON_API bool operator<( const wxSize& aLhs, const wxSize& aRhs ); -extern void to_json( nlohmann::json& aJson, const wxRect& aRect ); -extern void from_json( const nlohmann::json& aJson, wxRect& aRect ); -extern bool operator<( const wxRect& aLhs, const wxRect& aRhs ); +KICOMMON_API void to_json( nlohmann::json& aJson, const wxRect& aRect ); +KICOMMON_API void from_json( const nlohmann::json& aJson, wxRect& aRect ); +KICOMMON_API bool operator<( const wxRect& aLhs, const wxRect& aRhs ); -extern void to_json( nlohmann::json& aJson, const wxAuiPaneInfo& aPaneInfo ); -extern void from_json( const nlohmann::json& aJson, wxAuiPaneInfo& aPaneInfo ); -extern bool operator<( const wxAuiPaneInfo& aLhs, const wxAuiPaneInfo& aRhs ); -extern bool operator==( const wxAuiPaneInfo& aLhs, const wxAuiPaneInfo& aRhs ); +KICOMMON_API void to_json( nlohmann::json& aJson, const wxAuiPaneInfo& aPaneInfo ); +KICOMMON_API void from_json( const nlohmann::json& aJson, wxAuiPaneInfo& aPaneInfo ); +KICOMMON_API bool operator<( const wxAuiPaneInfo& aLhs, const wxAuiPaneInfo& aRhs ); +KICOMMON_API bool operator==( const wxAuiPaneInfo& aLhs, const wxAuiPaneInfo& aRhs ); #endif // _AUI_SETTINGS_H_ diff --git a/include/settings/bom_settings.h b/include/settings/bom_settings.h index 85ea4a245b..57c9313d44 100644 --- a/include/settings/bom_settings.h +++ b/include/settings/bom_settings.h @@ -27,7 +27,7 @@ #include // A single field within a BOM, e.g. Reference, Value, Footprint -struct BOM_FIELD +struct KICOMMON_API BOM_FIELD { wxString name; wxString label; @@ -37,16 +37,16 @@ struct BOM_FIELD bool operator==( const BOM_FIELD& rhs ) const; }; -bool operator!=( const BOM_FIELD& lhs, const BOM_FIELD& rhs ); -bool operator<( const BOM_FIELD& lhs, const BOM_FIELD& rhs ); +KICOMMON_API bool operator!=( const BOM_FIELD& lhs, const BOM_FIELD& rhs ); +KICOMMON_API bool operator<( const BOM_FIELD& lhs, const BOM_FIELD& rhs ); -void to_json( nlohmann::json& j, const BOM_FIELD& f ); -void from_json( const nlohmann::json& j, BOM_FIELD& f ); +KICOMMON_API void to_json( nlohmann::json& j, const BOM_FIELD& f ); +KICOMMON_API void from_json( const nlohmann::json& j, BOM_FIELD& f ); // A complete preset defining a BOM "View" with a list of all the fields to show, // group by, order, filtering settings, etc. -struct BOM_PRESET +struct KICOMMON_API BOM_PRESET { wxString name; bool readOnly = false; @@ -66,15 +66,15 @@ struct BOM_PRESET static std::vector BuiltInPresets(); }; -bool operator!=( const BOM_PRESET& lhs, const BOM_PRESET& rhs ); -bool operator<( const BOM_PRESET& lhs, const BOM_PRESET& rhs ); +KICOMMON_API bool operator!=( const BOM_PRESET& lhs, const BOM_PRESET& rhs ); +KICOMMON_API bool operator<( const BOM_PRESET& lhs, const BOM_PRESET& rhs ); -void to_json( nlohmann::json& j, const BOM_PRESET& f ); -void from_json( const nlohmann::json& j, BOM_PRESET& f ); +KICOMMON_API void to_json( nlohmann::json& j, const BOM_PRESET& f ); +KICOMMON_API void from_json( const nlohmann::json& j, BOM_PRESET& f ); // A formatting preset, like CSV (Comma Separated Values) -struct BOM_FMT_PRESET +struct KICOMMON_API BOM_FMT_PRESET { wxString name; bool readOnly = false; @@ -94,11 +94,11 @@ struct BOM_FMT_PRESET static std::vector BuiltInPresets(); }; -bool operator!=( const BOM_FMT_PRESET& lhs, const BOM_FMT_PRESET& rhs ); -bool operator<( const BOM_FMT_PRESET& lhs, const BOM_FMT_PRESET& rhs ); +KICOMMON_API bool operator!=( const BOM_FMT_PRESET& lhs, const BOM_FMT_PRESET& rhs ); +KICOMMON_API bool operator<( const BOM_FMT_PRESET& lhs, const BOM_FMT_PRESET& rhs ); -void to_json( nlohmann::json& j, const BOM_FMT_PRESET& f ); -void from_json( const nlohmann::json& j, BOM_FMT_PRESET& f ); +KICOMMON_API void to_json( nlohmann::json& j, const BOM_FMT_PRESET& f ); +KICOMMON_API void from_json( const nlohmann::json& j, BOM_FMT_PRESET& f ); #endif diff --git a/include/settings/grid_settings.h b/include/settings/grid_settings.h index 50f43fc8d2..558e6f0784 100644 --- a/include/settings/grid_settings.h +++ b/include/settings/grid_settings.h @@ -30,7 +30,7 @@ class UNITS_PROVIDER; /** * Common grid settings, available to every frame */ -struct GRID +struct KICOMMON_API GRID { bool operator==( const GRID& aOther ) const; @@ -53,11 +53,11 @@ struct GRID wxString y; }; -bool operator!=( const GRID& lhs, const GRID& rhs ); -bool operator<( const GRID& lhs, const GRID& rhs ); +KICOMMON_API bool operator!=( const GRID& lhs, const GRID& rhs ); +KICOMMON_API bool operator<( const GRID& lhs, const GRID& rhs ); -void to_json( nlohmann::json& j, const GRID& g ); -void from_json( const nlohmann::json& j, GRID& g ); +KICOMMON_API void to_json( nlohmann::json& j, const GRID& g ); +KICOMMON_API void from_json( const nlohmann::json& j, GRID& g ); struct GRID_SETTINGS diff --git a/include/settings/json_settings.h b/include/settings/json_settings.h index 2434a52daa..2bf0075681 100644 --- a/include/settings/json_settings.h +++ b/include/settings/json_settings.h @@ -28,21 +28,27 @@ #include #include -#include +#include + +#include class wxConfigBase; class NESTED_SETTINGS; class PARAM_BASE; class SETTINGS_MANAGER; -/** - * Flag to enable debug output of settings operations and management. - * - * Use "KICAD_SETTINGS" to enable. - * - * @ingroup trace_env_vars - */ -extern const wxChar* const traceSettings; +class wxAuiPaneInfo; +struct BOM_FIELD; +struct BOM_PRESET; +struct BOM_FMT_PRESET; +struct GRID; + +namespace KIGFX +{ +class COLOR4D; +}; + +#define traceSettings wxT( "KICAD_SETTINGS" ) enum class SETTINGS_LOC { USER, ///< The main config directory (e.g. ~/.config/kicad/) @@ -56,7 +62,7 @@ enum class SETTINGS_LOC { /// pimpl to allow hiding json.hpp class JSON_SETTINGS_INTERNALS; -class JSON_SETTINGS +class KICOMMON_API JSON_SETTINGS { public: friend class NESTED_SETTINGS; @@ -340,14 +346,32 @@ protected: // Specializations to allow conversion between wxString and std::string via JSON_SETTINGS API -template<> std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; +template<> KICOMMON_API std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; -template<> void JSON_SETTINGS::Set( const std::string& aPath, wxString aVal ); +template<> KICOMMON_API void JSON_SETTINGS::Set( const std::string& aPath, wxString aVal ); // Specializations to allow directly reading/writing wxStrings from JSON -void to_json( nlohmann::json& aJson, const wxString& aString ); +KICOMMON_API void to_json( nlohmann::json& aJson, const wxString& aString ); -void from_json( const nlohmann::json& aJson, wxString& aString ); +KICOMMON_API void from_json( const nlohmann::json& aJson, wxString& aString ); + +extern template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; +extern template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; +extern template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; +extern template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; +extern template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; +extern template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; +extern template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; +extern template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; +extern template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; +extern template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; +extern template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; +extern template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; +extern template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; +extern template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; +extern template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; +extern template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; +extern template std::optional JSON_SETTINGS::Get( const std::string& aPath ) const; #endif diff --git a/include/settings/json_settings_internals.h b/include/settings/json_settings_internals.h index 0f7d4da4b0..486a77f119 100644 --- a/include/settings/json_settings_internals.h +++ b/include/settings/json_settings_internals.h @@ -21,10 +21,9 @@ #ifndef KICAD_JSON_SETTINGS_INTERNALS_H #define KICAD_JSON_SETTINGS_INTERNALS_H -// This is a pretty heavy file. Try to use json_fwd.hpp most places. -#include +#include -class JSON_SETTINGS_INTERNALS : public nlohmann::json +class KICOMMON_API JSON_SETTINGS_INTERNALS : public nlohmann::json { friend class JSON_SETTINGS; diff --git a/include/settings/nested_settings.h b/include/settings/nested_settings.h index 61e2734107..6ad048cd17 100644 --- a/include/settings/nested_settings.h +++ b/include/settings/nested_settings.h @@ -28,7 +28,7 @@ * NESTED_SETTINGS is a JSON_SETTINGS that lives inside a JSON_SETTINGS. * Instead of being backed by a JSON file on disk, it loads and stores to its parent. */ -class NESTED_SETTINGS : public JSON_SETTINGS +class KICOMMON_API NESTED_SETTINGS : public JSON_SETTINGS { public: NESTED_SETTINGS( const std::string& aName, int aSchemaVersion, JSON_SETTINGS* aParent, diff --git a/include/settings/parameters.h b/include/settings/parameters.h index 0e1583fd51..dc6308758b 100644 --- a/include/settings/parameters.h +++ b/include/settings/parameters.h @@ -27,10 +27,13 @@ #include #include +#include #include +#include +#include +#include - -class PARAM_BASE +class KICOMMON_API PARAM_BASE { public: PARAM_BASE( std::string aJsonPath, bool aReadOnly ) : @@ -167,7 +170,7 @@ protected: /** * Stores a path as a string with directory separators normalized to unix-style */ -class PARAM_PATH : public PARAM +class KICOMMON_API PARAM_PATH : public PARAM { public: PARAM_PATH( const std::string& aJsonPath, wxString* aPtr, const wxString& aDefault, @@ -299,7 +302,26 @@ public: m_setter( std::move( aSetter ) ) { } - void Load( JSON_SETTINGS* aSettings, bool aResetIfMissing = true ) const override; + void Load( JSON_SETTINGS* aSettings, bool aResetIfMissing = true ) const override + { + if( m_readOnly ) + return; + + if( std::is_same::value ) + { + if( std::optional optval = aSettings->GetJson( m_path ) ) + m_setter( *optval ); + else + m_setter( m_default ); + } + else + { + if( std::optional optval = aSettings->Get( m_path ) ) + m_setter( *optval ); + else + m_setter( m_default ); + } + } void Store( JSON_SETTINGS* aSettings ) const override { @@ -322,7 +344,22 @@ public: m_setter( m_default ); } - bool MatchesFile( JSON_SETTINGS* aSettings ) const override; + bool MatchesFile( JSON_SETTINGS* aSettings ) const override + { + if( std::is_same::value ) + { + if( std::optional optval = aSettings->GetJson( m_path ) ) + return *optval == m_getter(); + } + else + { + if( std::optional optval = aSettings->Get( m_path ) ) + return *optval == m_getter(); + } + + // Not in file + return false; + } private: ValueType m_default; @@ -331,6 +368,11 @@ private: }; +extern template class APIVISIBLE PARAM_LAMBDA; +extern template class APIVISIBLE PARAM_LAMBDA; +extern template class APIVISIBLE PARAM_LAMBDA; +extern template class APIVISIBLE PARAM_LAMBDA; + /** * Represents a parameter that has a scaling factor between the value in the file and the * value used internally (i.e. the value pointer). This basically only makes sense to use @@ -439,22 +481,86 @@ public: m_default( std::move( aDefault ) ) { } - void Load( JSON_SETTINGS* aSettings, bool aResetIfMissing = true ) const override; + void Load( JSON_SETTINGS* aSettings, bool aResetIfMissing = true ) const override + { + if( m_readOnly ) + return; - void Store( JSON_SETTINGS* aSettings) const override; + if( std::optional js = aSettings->GetJson( m_path ) ) + { + std::vector val; + + if( js->is_array() ) + { + for( const auto& el : js->items() ) + val.push_back( el.value().get() ); + } + + *m_ptr = val; + } + else if( aResetIfMissing ) + *m_ptr = m_default; + } + + void Store( JSON_SETTINGS* aSettings ) const override + { + nlohmann::json js = nlohmann::json::array(); + + for( const auto& el : *m_ptr ) + js.push_back( el ); + + aSettings->Set( m_path, js ); + } void SetDefault() override { *m_ptr = m_default; } - bool MatchesFile( JSON_SETTINGS* aSettings ) const override; + bool MatchesFile( JSON_SETTINGS* aSettings ) const override + { + if( std::optional js = aSettings->GetJson( m_path ) ) + { + if( js->is_array() ) + { + std::vector val; + + for( const auto& el : js->items() ) + { + try + { + val.emplace_back( el.value().get() ); + } + catch( ... ) + { + // Probably typecast didn't work; skip this element + } + } + + return val == *m_ptr; + } + } + + return false; + } protected: std::vector* m_ptr; std::vector m_default; }; + +extern template class APIVISIBLE PARAM_LIST; +extern template class APIVISIBLE PARAM_LIST; +extern template class APIVISIBLE PARAM_LIST; +extern template class APIVISIBLE PARAM_LIST; +//template KICOMMON_EXTERN_DECL class PARAM_LIST; +extern template class APIVISIBLE PARAM_LIST; +extern template class APIVISIBLE PARAM_LIST; +extern template class APIVISIBLE PARAM_LIST; +extern template class APIVISIBLE PARAM_LIST; + + template class PARAM_SET : public PARAM_BASE { @@ -473,27 +579,73 @@ public: m_default( aDefault ) { } - void Load( JSON_SETTINGS* aSettings, bool aResetIfMissing = true ) const override; + void Load( JSON_SETTINGS* aSettings, bool aResetIfMissing = true ) const override + { + if( m_readOnly ) + return; + + if( std::optional js = aSettings->GetJson( m_path ) ) + { + std::set val; + + if( js->is_array() ) + { + for( const auto& el : js->items() ) + val.insert( el.value().get() ); + } + + *m_ptr = val; + } + else if( aResetIfMissing ) + *m_ptr = m_default; + } + + void Store( JSON_SETTINGS* aSettings) const override + { + nlohmann::json js = nlohmann::json::array(); + + for( const auto& el : *m_ptr ) + js.push_back( el ); + + aSettings->Set( m_path, js ); + } - void Store( JSON_SETTINGS* aSettings) const override; void SetDefault() override { *m_ptr = m_default; } - bool MatchesFile( JSON_SETTINGS* aSettings ) const override; + bool MatchesFile( JSON_SETTINGS* aSettings ) const override + { + if( std::optional js = aSettings->GetJson( m_path ) ) + { + if( js->is_array() ) + { + std::set val; + + for( const auto& el : js->items() ) + val.insert( el.value().get() ); + + return val == *m_ptr; + } + } + + return false; + } protected: std::set* m_ptr; std::set m_default; }; +extern template class APIVISIBLE PARAM_SET; + /** * Represents a list of strings holding directory paths. * Normalizes paths to unix directory separator style in the file. */ -class PARAM_PATH_LIST : public PARAM_LIST +class KICOMMON_API PARAM_PATH_LIST : public PARAM_LIST { public: PARAM_PATH_LIST( const std::string& aJsonPath, std::vector* aPtr, @@ -563,16 +715,60 @@ public: m_default( aDefault ) { } - void Load( JSON_SETTINGS* aSettings, bool aResetIfMissing = true ) const override; + void Load( JSON_SETTINGS* aSettings, bool aResetIfMissing = true ) const override + { + if( m_readOnly ) + return; - void Store( JSON_SETTINGS* aSettings) const override; + if( std::optional js = aSettings->GetJson( m_path ) ) + { + if( js->is_object() ) + { + m_ptr->clear(); + + for( const auto& el : js->items() ) + ( *m_ptr )[el.key()] = el.value().get(); + } + } + else if( aResetIfMissing ) + *m_ptr = m_default; + } + + void Store( JSON_SETTINGS* aSettings) const override + { + nlohmann::json js( {} ); + + for( const auto& el : *m_ptr ) + js[el.first] = el.second; + + aSettings->Set( m_path, js ); + } virtual void SetDefault() override { *m_ptr = m_default; } - bool MatchesFile( JSON_SETTINGS* aSettings ) const override; + bool MatchesFile( JSON_SETTINGS* aSettings ) const override + { + if( std::optional js = aSettings->GetJson( m_path ) ) + { + if( js->is_object() ) + { + if( m_ptr->size() != js->size() ) + return false; + + std::map val; + + for( const auto& el : js->items() ) + val[el.key()] = el.value().get(); + + return val == *m_ptr; + } + } + + return false; + } private: std::map* m_ptr; @@ -580,10 +776,15 @@ private: }; +extern template class APIVISIBLE PARAM_MAP; +extern template class APIVISIBLE PARAM_MAP; +extern template class APIVISIBLE PARAM_MAP; + + /** * A helper for maps */ -class PARAM_WXSTRING_MAP : public PARAM_BASE +class KICOMMON_API PARAM_WXSTRING_MAP : public PARAM_BASE { public: PARAM_WXSTRING_MAP( const std::string& aJsonPath, std::map* aPtr, diff --git a/kicad/pcm/pcm.h b/kicad/pcm/pcm.h index c670943dcf..4ece4d3a56 100644 --- a/kicad/pcm/pcm.h +++ b/kicad/pcm/pcm.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/kicad/pcm/pcm_data.h b/kicad/pcm/pcm_data.h index 3e56d18de8..c8c8094925 100644 --- a/kicad/pcm/pcm_data.h +++ b/kicad/pcm/pcm_data.h @@ -24,7 +24,7 @@ #include "core/wx_stl_compat.h" #include -#include +#include #include #include #include diff --git a/pcbnew/pcb_io/easyedapro/pcb_io_easyedapro.cpp b/pcbnew/pcb_io/easyedapro/pcb_io_easyedapro.cpp index 3c0325ebde..c8a778a80b 100644 --- a/pcbnew/pcb_io/easyedapro/pcb_io_easyedapro.cpp +++ b/pcbnew/pcb_io/easyedapro/pcb_io_easyedapro.cpp @@ -41,7 +41,7 @@ #include #include -#include +#include #include #include #include diff --git a/thirdparty/json_schema_validator/CMakeLists.txt b/thirdparty/json_schema_validator/CMakeLists.txt index 57d1d05dd0..32e50c83f4 100644 --- a/thirdparty/json_schema_validator/CMakeLists.txt +++ b/thirdparty/json_schema_validator/CMakeLists.txt @@ -6,6 +6,8 @@ add_library( nlohmann_json_schema_validator STATIC string-format-check.cpp ) +add_dependencies( nlohmann_json_schema_validator kicommon ) + target_include_directories( nlohmann_json_schema_validator PUBLIC $ @@ -14,4 +16,5 @@ target_include_directories( nlohmann_json_schema_validator target_link_libraries( nlohmann_json_schema_validator PUBLIC nlohmann_json + PRIVATE kicommon ) diff --git a/thirdparty/json_schema_validator/nlohmann/json-schema.hpp b/thirdparty/json_schema_validator/nlohmann/json-schema.hpp index 07befd3472..582c113c1c 100644 --- a/thirdparty/json_schema_validator/nlohmann/json-schema.hpp +++ b/thirdparty/json_schema_validator/nlohmann/json-schema.hpp @@ -21,6 +21,7 @@ # define JSON_SCHEMA_VALIDATOR_API #endif +#include #include #ifdef NLOHMANN_JSON_VERSION_MAJOR