KiCad PCB EDA Suite
json_settings.h
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2020 Jon Evans <[email protected]>
5 * Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#ifndef _JSON_SETTINGS_H
22#define _JSON_SETTINGS_H
23
24#include <core/wx_stl_compat.h>
25
26#include <utility>
27#include <wx/string.h>
28
29#include <functional>
30#include <optional>
31#include <nlohmann/json_fwd.hpp>
32
33class wxConfigBase;
34class NESTED_SETTINGS;
35class PARAM_BASE;
37
45extern const wxChar* const traceSettings;
46
47enum class SETTINGS_LOC {
48 USER,
49 PROJECT,
50 COLORS,
51 NESTED,
52 NONE,
53};
54
55
58
60{
61public:
62 friend class NESTED_SETTINGS;
63
64 JSON_SETTINGS( const wxString& aFilename, SETTINGS_LOC aLocation, int aSchemaVersion ) :
65 JSON_SETTINGS( aFilename, aLocation, aSchemaVersion, true, true, true )
66 {}
67
68 JSON_SETTINGS( const wxString& aFilename, SETTINGS_LOC aLocation, int aSchemaVersion,
69 bool aCreateIfMissing, bool aCreateIfDefault, bool aWriteFile );
70
71 virtual ~JSON_SETTINGS();
72
73 wxString GetFilename() const { return m_filename; }
74
75 wxString GetFullFilename() const;
76
77 void SetFilename( const wxString& aFilename ) { m_filename = aFilename; }
78
79 void SetLocation( SETTINGS_LOC aLocation ) { m_location = aLocation; }
81
82 void SetLegacyFilename( const wxString& aFilename ) { m_legacy_filename = aFilename; }
83
84 bool IsReadOnly() const { return !m_writeFile; }
85 void SetReadOnly( bool aReadOnly ) { m_writeFile = !aReadOnly; }
86
92 nlohmann::json& At( const std::string& aPath );
93 bool Contains( const std::string& aPath ) const;
94 size_t Count( const std::string& aPath ) const;
95
97
101 virtual void Load();
102
108 virtual bool Store();
109
115 virtual bool LoadFromFile( const wxString& aDirectory = "" );
116
122 virtual bool SaveToFile( const wxString& aDirectory = "", bool aForce = false );
123
127 void ResetToDefaults();
128
135 std::optional<nlohmann::json> GetJson( const std::string& aPath ) const;
136
144 template<typename ValueType>
145 std::optional<ValueType> Get( const std::string& aPath ) const;
146
154 template<typename ValueType>
155 void Set( const std::string& aPath, ValueType aVal );
156
166 bool Migrate();
167
174 virtual bool MigrateFromLegacy( wxConfigBase* aLegacyConfig );
175
184 void AddNestedSettings( NESTED_SETTINGS* aSettings );
185
190 void ReleaseNestedSettings( NESTED_SETTINGS* aSettings );
191
192 void SetManager( SETTINGS_MANAGER* aManager )
193 {
194 m_manager = aManager;
195 }
196
203 static bool SetIfPresent( const nlohmann::json& aObj, const std::string& aPath,
204 wxString& aTarget );
205
212 static bool SetIfPresent( const nlohmann::json& aObj, const std::string& aPath, bool& aTarget );
213
220 static bool SetIfPresent( const nlohmann::json& aObj, const std::string& aPath, int& aTarget );
221
228 static bool SetIfPresent( const nlohmann::json& aObj, const std::string& aPath,
229 unsigned int& aTarget );
230protected:
231
240 void registerMigration( int aOldSchemaVersion, int aNewSchemaVersion,
241 std::function<bool(void)> aMigrator );
242
250 template<typename ValueType>
251 bool fromLegacy( wxConfigBase* aConfig, const std::string& aKey, const std::string& aDest );
252
259 bool fromLegacyString( wxConfigBase* aConfig, const std::string& aKey,
260 const std::string& aDest );
261
268 bool fromLegacyColor( wxConfigBase* aConfig, const std::string& aKey,
269 const std::string& aDest );
270
271 virtual wxString getFileExt() const
272 {
273 return wxT( "json" );
274 }
275
276 virtual wxString getLegacyFileExt() const
277 {
278 return wxEmptyString;
279 }
280
282 wxString m_filename;
283
286
289
291 std::vector<PARAM_BASE*> m_params;
292
294 std::vector<NESTED_SETTINGS*> m_nested_settings;
295
298
304
307
310
313
316
319
321 std::map<int, std::pair<int, std::function<bool()>>> m_migrators;
322
323 std::unique_ptr<JSON_SETTINGS_INTERNALS> m_internals;
324};
325
326// Specializations to allow conversion between wxString and std::string via JSON_SETTINGS API
327
328template<> std::optional<wxString> JSON_SETTINGS::Get( const std::string& aPath ) const;
329
330template<> void JSON_SETTINGS::Set<wxString>( const std::string& aPath, wxString aVal );
331
332// Specializations to allow directly reading/writing wxStrings from JSON
333
334void to_json( nlohmann::json& aJson, const wxString& aString );
335
336void from_json( const nlohmann::json& aJson, wxString& aString );
337
338#endif
bool fromLegacyString(wxConfigBase *aConfig, const std::string &aKey, const std::string &aDest)
Translates a legacy wxConfig string value to a given JSON pointer value.
virtual wxString getFileExt() const
std::optional< nlohmann::json > GetJson(const std::string &aPath) const
Fetches a JSON object that is a subset of this JSON_SETTINGS object, using a path of the form "key1....
bool fromLegacy(wxConfigBase *aConfig, const std::string &aKey, const std::string &aDest)
Translates a legacy wxConfig value to a given JSON pointer value.
wxString m_filename
The filename (not including path) of this settings file (inicode)
SETTINGS_MANAGER * m_manager
A pointer to the settings manager managing this file (may be null)
bool Contains(const std::string &aPath) const
SETTINGS_LOC GetLocation() const
Definition: json_settings.h:80
virtual ~JSON_SETTINGS()
std::vector< NESTED_SETTINGS * > m_nested_settings
Nested settings files that live inside this one, if any.
virtual bool LoadFromFile(const wxString &aDirectory="")
Loads the backing file from disk and then calls Load()
bool m_createIfDefault
Whether or not the backing store file should be created if all parameters are still at their default ...
void SetLocation(SETTINGS_LOC aLocation)
Definition: json_settings.h:79
bool m_writeFile
Whether or not the backing store file should be written.
static bool SetIfPresent(const nlohmann::json &aObj, const std::string &aPath, wxString &aTarget)
Sets the given string if the given key/path is present.
virtual void Load()
Updates the parameters of this object based on the current JSON document contents.
void SetManager(SETTINGS_MANAGER *aManager)
bool IsReadOnly() const
Definition: json_settings.h:84
void SetReadOnly(bool aReadOnly)
Definition: json_settings.h:85
void ResetToDefaults()
Resets all parameters to default values.
bool fromLegacyColor(wxConfigBase *aConfig, const std::string &aKey, const std::string &aDest)
Translates a legacy COLOR4D stored in a wxConfig string to a given JSON pointer value.
wxString GetFullFilename() const
size_t Count(const std::string &aPath) const
bool m_createIfMissing
Whether or not the backing store file should be created it if doesn't exist.
bool Migrate()
Migrates the schema of this settings from the version in the file to the latest version.
std::vector< PARAM_BASE * > m_params
The list of parameters (owned by this object)
virtual bool MigrateFromLegacy(wxConfigBase *aLegacyConfig)
Migrates from wxConfig to JSON-based configuration.
void registerMigration(int aOldSchemaVersion, int aNewSchemaVersion, std::function< bool(void)> aMigrator)
Registers a migration from one schema version to another.
nlohmann::json & At(const std::string &aPath)
Wrappers for the underlying JSON API so that most consumers don't need json.hpp All of these function...
JSON_SETTINGS_INTERNALS * Internals()
void ReleaseNestedSettings(NESTED_SETTINGS *aSettings)
Saves and frees a nested settings object, if it exists within this one.
JSON_SETTINGS(const wxString &aFilename, SETTINGS_LOC aLocation, int aSchemaVersion)
Definition: json_settings.h:64
bool m_deleteLegacyAfterMigration
Whether or not to delete legacy file after migration.
std::unique_ptr< JSON_SETTINGS_INTERNALS > m_internals
void SetFilename(const wxString &aFilename)
Definition: json_settings.h:77
SETTINGS_LOC m_location
The location of this settings file (.
virtual bool SaveToFile(const wxString &aDirectory="", bool aForce=false)
virtual wxString getLegacyFileExt() const
void Set(const std::string &aPath, ValueType aVal)
Stores a value into the JSON document Will throw an exception if ValueType isn't something that the l...
bool m_resetParamsIfMissing
Whether or not to set parameters to their default value if missing from JSON on Load()
void SetLegacyFilename(const wxString &aFilename)
Definition: json_settings.h:82
std::map< int, std::pair< int, std::function< bool()> > > m_migrators
A map of starting schema version to a pair of <ending version, migrator function>
int m_schemaVersion
Version of this settings schema.
wxString m_legacy_filename
The filename of the wxConfig legacy file (if different from m_filename)
std::optional< ValueType > Get(const std::string &aPath) const
Fetches a value from within the JSON document.
void AddNestedSettings(NESTED_SETTINGS *aSettings)
Transfers ownership of a given NESTED_SETTINGS to this object.
virtual bool Store()
Stores the current parameters into the JSON document represented by this object Note: this doesn't do...
wxString GetFilename() const
Definition: json_settings.h:73
NESTED_SETTINGS is a JSON_SETTINGS that lives inside a JSON_SETTINGS.
nlohmann::json json
Definition: gerbview.cpp:44
const wxChar *const traceSettings
Flag to enable debug output of settings operations and management.
void from_json(const nlohmann::json &aJson, wxString &aString)
SETTINGS_LOC
Definition: json_settings.h:47
@ PROJECT
The settings directory inside a project folder.
@ USER
The main config directory (e.g. ~/.config/kicad/)
@ COLORS
The color scheme directory (e.g. ~/.config/kicad/colors/)
@ NESTED
Not stored in a file, but inside another JSON_SETTINGS.
void to_json(nlohmann::json &aJson, const wxString &aString)