diff --git a/api/proto/common/commands/project_commands.proto b/api/proto/common/commands/project_commands.proto index ce51198d7a..8117715a24 100644 --- a/api/proto/common/commands/project_commands.proto +++ b/api/proto/common/commands/project_commands.proto @@ -47,3 +47,20 @@ message ExpandTextVariablesResponse { repeated string text = 1; } + + +// returns kiapi.common.project.TextVariables +message GetTextVariables +{ + kiapi.common.types.DocumentSpecifier document = 1; +} + + +message SetTextVariables +{ + kiapi.common.types.DocumentSpecifier document = 1; + + kiapi.common.project.TextVariables variables = 2; + // Whether to merge or replace the existing text variables map with the contents of this message + kiapi.common.types.MapMergeMode merge_mode = 3; +} diff --git a/api/proto/common/types/base_types.proto b/api/proto/common/types/base_types.proto index a9666a47f9..f491a1aed2 100644 --- a/api/proto/common/types/base_types.proto +++ b/api/proto/common/types/base_types.proto @@ -438,3 +438,13 @@ enum AxisAlignment AA_X_AXIS = 1; AA_Y_AXIS = 2; } + +enum MapMergeMode +{ + MMM_UNKNOWN = 0; + // The existing map will be merged with the incoming map; keys that are not present in the + // incoming map will be preserved with their original values + MMM_MERGE = 1; + // The existing map will be cleared and replaced with the incoming map + MMM_REPLACE = 2; +} diff --git a/api/proto/common/types/project_settings.proto b/api/proto/common/types/project_settings.proto index 9dd92b3291..179bebc5c4 100644 --- a/api/proto/common/types/project_settings.proto +++ b/api/proto/common/types/project_settings.proto @@ -33,3 +33,8 @@ message NetClass string name = 1; } + +message TextVariables +{ + map<string, string> variables = 1; +} diff --git a/common/api/api_handler_common.cpp b/common/api/api_handler_common.cpp index b74f352d7c..d3c91d497e 100644 --- a/common/api/api_handler_common.cpp +++ b/common/api/api_handler_common.cpp @@ -53,6 +53,10 @@ API_HANDLER_COMMON::API_HANDLER_COMMON() : &API_HANDLER_COMMON::handleExpandTextVariables ); registerHandler<GetPluginSettingsPath, StringResponse>( &API_HANDLER_COMMON::handleGetPluginSettingsPath ); + registerHandler<GetTextVariables, project::TextVariables>( + &API_HANDLER_COMMON::handleGetTextVariables ); + registerHandler<SetTextVariables, Empty>( + &API_HANDLER_COMMON::handleSetTextVariables ); } @@ -263,3 +267,72 @@ HANDLER_RESULT<StringResponse> API_HANDLER_COMMON::handleGetPluginSettingsPath( reply.set_response( path.GetPath() ); return reply; } + + +HANDLER_RESULT<project::TextVariables> API_HANDLER_COMMON::handleGetTextVariables( + const HANDLER_CONTEXT<GetTextVariables>& aCtx ) +{ + if( !aCtx.Request.has_document() || aCtx.Request.document().type() != DOCTYPE_PROJECT ) + { + ApiResponseStatus e; + e.set_status( ApiStatusCode::AS_UNHANDLED ); + // No error message, this is a flag that the server should try a different handler + return tl::unexpected( e ); + } + + const PROJECT& project = Pgm().GetSettingsManager().Prj(); + + if( project.IsNullProject() ) + { + ApiResponseStatus e; + e.set_status( ApiStatusCode::AS_NOT_READY ); + e.set_error_message( "no valid project is loaded, cannot get text variables" ); + return tl::unexpected( e ); + } + + const std::map<wxString, wxString>& vars = project.GetTextVars(); + + project::TextVariables reply; + auto map = reply.mutable_variables(); + + for( const auto& [key, value] : vars ) + ( *map )[ std::string( key.ToUTF8() ) ] = value.ToUTF8(); + + return reply; +} + + +HANDLER_RESULT<Empty> API_HANDLER_COMMON::handleSetTextVariables( + const HANDLER_CONTEXT<SetTextVariables>& aCtx ) +{ + if( !aCtx.Request.has_document() || aCtx.Request.document().type() != DOCTYPE_PROJECT ) + { + ApiResponseStatus e; + e.set_status( ApiStatusCode::AS_UNHANDLED ); + // No error message, this is a flag that the server should try a different handler + return tl::unexpected( e ); + } + + PROJECT& project = Pgm().GetSettingsManager().Prj(); + + if( project.IsNullProject() ) + { + ApiResponseStatus e; + e.set_status( ApiStatusCode::AS_NOT_READY ); + e.set_error_message( "no valid project is loaded, cannot set text variables" ); + return tl::unexpected( e ); + } + + const project::TextVariables& newVars = aCtx.Request.variables(); + std::map<wxString, wxString>& vars = project.GetTextVars(); + + if( aCtx.Request.merge_mode() == MapMergeMode::MMM_REPLACE ) + vars.clear(); + + for( const auto& [key, value] : newVars.variables() ) + vars[wxString::FromUTF8( key )] = wxString::FromUTF8( value ); + + Pgm().GetSettingsManager().SaveProject(); + + return Empty(); +} diff --git a/include/api/api_handler_common.h b/include/api/api_handler_common.h index 5aab987626..06f14e5128 100644 --- a/include/api/api_handler_common.h +++ b/include/api/api_handler_common.h @@ -57,6 +57,12 @@ private: HANDLER_RESULT<commands::StringResponse> handleGetPluginSettingsPath( const HANDLER_CONTEXT<commands::GetPluginSettingsPath>& aCtx ); + + HANDLER_RESULT<project::TextVariables> handleGetTextVariables( + const HANDLER_CONTEXT<commands::GetTextVariables>& aCtx ); + + HANDLER_RESULT<Empty> handleSetTextVariables( + const HANDLER_CONTEXT<commands::SetTextVariables>& aCtx ); }; #endif //KICAD_API_HANDLER_COMMON_H