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 <jon@craftyjon.com>
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 <nlohmann/json.hpp>
27 #include <utility>
28 #include <wx/string.h>
29 
30 #include <core/optional.h>
31 
32 class wxConfigBase;
33 class NESTED_SETTINGS;
34 class PARAM_BASE;
35 class SETTINGS_MANAGER;
36 
44 extern const wxChar* const traceSettings;
45 
46 enum class SETTINGS_LOC {
47  USER,
48  PROJECT,
49  COLORS,
50  NESTED,
51  NONE,
52 };
53 
54 
56 {
57 public:
58  JSON_SETTINGS( const wxString& aFilename, SETTINGS_LOC aLocation, int aSchemaVersion ) :
59  JSON_SETTINGS( aFilename, aLocation, aSchemaVersion, true, true, true ) {}
60 
61  JSON_SETTINGS( const wxString& aFilename, SETTINGS_LOC aLocation, int aSchemaVersion,
62  bool aCreateIfMissing, bool aCreateIfDefault, bool aWriteFile );
63 
64  virtual ~JSON_SETTINGS();
65 
66  wxString GetFilename() const { return m_filename; }
67 
68  wxString GetFullFilename() const;
69 
70  void SetFilename( const wxString& aFilename ) { m_filename = aFilename; }
71 
72  SETTINGS_LOC GetLocation() const { return m_location; }
73 
74  void SetLegacyFilename( const wxString& aFilename ) { m_legacy_filename = aFilename; }
75 
76  bool IsReadOnly() const { return !m_writeFile; }
77  void SetReadOnly( bool aReadOnly ) { m_writeFile = !aReadOnly; }
78 
82  virtual void Load();
83 
89  virtual bool Store();
90 
96  virtual bool LoadFromFile( const wxString& aDirectory = "" );
97 
103  virtual bool SaveToFile( const wxString& aDirectory = "", bool aForce = false );
104 
108  void ResetToDefaults();
109 
115  bool IsDefault( const std::string& aParamName );
116 
123  OPT<nlohmann::json> GetJson( const std::string& aPath ) const;
124 
132  template<typename ValueType>
133  OPT<ValueType> Get( const std::string& aPath ) const
134  {
135  if( OPT<nlohmann::json> ret = GetJson( aPath ) )
136  {
137  try
138  {
139  return ret->get<ValueType>();
140  }
141  catch( ... )
142  {
143  }
144  }
145 
146  return NULLOPT;
147  }
148 
156  template<typename ValueType>
157  void Set( const std::string& aPath, ValueType aVal )
158  {
159  ( *this )[PointerFromString( aPath ) ] = aVal;
160  }
161 
171  bool Migrate();
172 
179  virtual bool MigrateFromLegacy( wxConfigBase* aLegacyConfig );
180 
189  void AddNestedSettings( NESTED_SETTINGS* aSettings );
190 
195  void ReleaseNestedSettings( NESTED_SETTINGS* aSettings );
196 
197  void SetManager( SETTINGS_MANAGER* aManager )
198  {
199  m_manager = aManager;
200  }
201 
207  static nlohmann::json::json_pointer PointerFromString( std::string aPath );
208 
215  static bool SetIfPresent( const nlohmann::json& aObj, const std::string& aPath,
216  wxString& aTarget );
217 
224  static bool SetIfPresent( const nlohmann::json& aObj, const std::string& aPath, bool& aTarget );
225 
232  static bool SetIfPresent( const nlohmann::json& aObj, const std::string& aPath, int& aTarget );
233 
240  static bool SetIfPresent( const nlohmann::json& aObj, const std::string& aPath,
241  unsigned int& aTarget );
242 protected:
243 
252  void registerMigration( int aOldSchemaVersion, int aNewSchemaVersion,
253  std::function<bool(void)> aMigrator );
254 
262  template<typename ValueType>
263  bool fromLegacy( wxConfigBase* aConfig, const std::string& aKey, const std::string& aDest );
264 
271  bool fromLegacyString( wxConfigBase* aConfig, const std::string& aKey,
272  const std::string& aDest );
273 
280  bool fromLegacyColor( wxConfigBase* aConfig, const std::string& aKey,
281  const std::string& aDest );
282 
283  virtual wxString getFileExt() const
284  {
285  return wxT( "json" );
286  }
287 
288  virtual wxString getLegacyFileExt() const
289  {
290  return wxEmptyString;
291  }
292 
294  wxString m_filename;
295 
298 
301 
303  std::vector<PARAM_BASE*> m_params;
304 
306  std::vector<NESTED_SETTINGS*> m_nested_settings;
307 
310 
316 
319 
322 
325 
328 
331 
333  std::vector<nlohmann::json::json_pointer> m_preserved_paths;
334 
336  std::map<int, std::pair<int, std::function<bool()>>> m_migrators;
337 };
338 
339 // Specializations to allow conversion between wxString and std::string via JSON_SETTINGS API
340 
341 template<> OPT<wxString> JSON_SETTINGS::Get( const std::string& aPath ) const;
342 
343 template<> void JSON_SETTINGS::Set<wxString>( const std::string& aPath, wxString aVal );
344 
345 // Specializations to allow directly reading/writing wxStrings from JSON
346 
347 void to_json( nlohmann::json& aJson, const wxString& aString );
348 
349 void from_json( const nlohmann::json& aJson, wxString& aString );
350 
351 #endif
void ResetToDefaults()
Resets all parameters to default values.
std::vector< nlohmann::json::json_pointer > m_preserved_paths
A list of JSON pointers that are preserved during a read-update-write to disk.
virtual bool Store()
Stores the current parameters into the JSON document represented by this object Note: this doesn't do...
std::vector< PARAM_BASE * > m_params
The list of parameters (owned by this object)
void from_json(const nlohmann::json &aJson, wxString &aString)
bool m_createIfMissing
Whether or not the backing store file should be created it if doesn't exist.
void SetReadOnly(bool aReadOnly)
Definition: json_settings.h:77
wxString GetFilename() const
Definition: json_settings.h:66
virtual wxString getLegacyFileExt() const
SETTINGS_LOC
Definition: json_settings.h:46
virtual bool LoadFromFile(const wxString &aDirectory="")
Loads the backing file from disk and then calls Load()
OPT< 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....
wxString GetFullFilename() const
nlohmann::json json
Definition: gerbview.cpp:41
void AddNestedSettings(NESTED_SETTINGS *aSettings)
Transfers ownership of a given NESTED_SETTINGS to this object.
bool m_deleteLegacyAfterMigration
Whether or not to delete legacy file after migration.
OPT< ValueType > Get(const std::string &aPath) const
Fetches a value from within the JSON document.
void to_json(nlohmann::json &aJson, const wxString &aString)
The color scheme directory (e.g. ~/.config/kicad/colors/)
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>
wxString m_filename
The filename (not including path) of this settings file (inicode)
bool Migrate()
Migrates the schema of this settings from the version in the file to the latest version.
NESTED_SETTINGS is a JSON_SETTINGS that lives inside a JSON_SETTINGS.
virtual bool SaveToFile(const wxString &aDirectory="", bool aForce=false)
wxString m_legacy_filename
The filename of the wxConfig legacy file (if different from m_filename)
const auto NULLOPT
Definition: optional.h:9
The settings directory inside a project folder.
SETTINGS_LOC GetLocation() const
Definition: json_settings.h:72
static bool SetIfPresent(const nlohmann::json &aObj, const std::string &aPath, wxString &aTarget)
Sets the given string if the given key/path is present.
void SetManager(SETTINGS_MANAGER *aManager)
std::vector< NESTED_SETTINGS * > m_nested_settings
Nested settings files that live inside this one, if any.
No directory prepended, full path in filename (used for PROJECT_FILE)
JSON_SETTINGS(const wxString &aFilename, SETTINGS_LOC aLocation, int aSchemaVersion)
Definition: json_settings.h:58
SETTINGS_LOC m_location
The location of this settings file (.
bool IsDefault(const std::string &aParamName)
Checks if the current state of a parameter matches its default value.
Not stored in a file, but inside another JSON_SETTINGS.
bool fromLegacyString(wxConfigBase *aConfig, const std::string &aKey, const std::string &aDest)
Translates a legacy wxConfig string value to a given JSON pointer value.
bool m_resetParamsIfMissing
Whether or not to set parameters to their default value if missing from JSON on Load()
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.
void registerMigration(int aOldSchemaVersion, int aNewSchemaVersion, std::function< bool(void)> aMigrator)
Registers a migration from one schema version to another.
The main config directory (e.g. ~/.config/kicad/)
bool IsReadOnly() const
Definition: json_settings.h:76
boost::optional< T > OPT
Definition: optional.h:7
bool fromLegacy(wxConfigBase *aConfig, const std::string &aKey, const std::string &aDest)
Translates a legacy wxConfig value to a given JSON pointer value.
virtual ~JSON_SETTINGS()
const wxChar *const traceSettings
Flag to enable debug output of settings operations and management.
void SetFilename(const wxString &aFilename)
Definition: json_settings.h:70
bool m_createIfDefault
Whether or not the backing store file should be created if all parameters are still at their default ...
void ReleaseNestedSettings(NESTED_SETTINGS *aSettings)
Saves and frees a nested settings object, if it exists within this one.
SETTINGS_MANAGER * m_manager
A pointer to the settings manager managing this file (may be null)
virtual wxString getFileExt() const
static nlohmann::json::json_pointer PointerFromString(std::string aPath)
Builds a JSON pointer based on a given string.
virtual bool MigrateFromLegacy(wxConfigBase *aLegacyConfig)
Migrates from wxConfig to JSON-based configuration.
void SetLegacyFilename(const wxString &aFilename)
Definition: json_settings.h:74
int m_schemaVersion
Version of this settings schema.
virtual void Load()
Updates the parameters of this object based on the current JSON document contents.
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_writeFile
Whether or not the backing store file should be written.