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 <nlohmann/json.hpp>
25 #include <utility>
26 #include <wx/string.h>
27 
28 #include <core/optional.h>
29 
30 class wxConfigBase;
31 class NESTED_SETTINGS;
32 class PARAM_BASE;
33 class SETTINGS_MANAGER;
34 
42 extern const wxChar* const traceSettings;
43 
44 enum class SETTINGS_LOC {
45  USER,
46  PROJECT,
47  COLORS,
48  NESTED,
49  NONE,
50 };
51 
52 
54 {
55 public:
56  JSON_SETTINGS( const wxString& aFilename, SETTINGS_LOC aLocation, int aSchemaVersion ) :
57  JSON_SETTINGS( aFilename, aLocation, aSchemaVersion, true, true, true ) {}
58 
59  JSON_SETTINGS( const wxString& aFilename, SETTINGS_LOC aLocation, int aSchemaVersion,
60  bool aCreateIfMissing, bool aCreateIfDefault, bool aWriteFile );
61 
62  virtual ~JSON_SETTINGS();
63 
64  wxString GetFilename() const { return m_filename; }
65 
66  wxString GetFullFilename() const;
67 
68  void SetFilename( const wxString& aFilename ) { m_filename = aFilename; }
69 
70  SETTINGS_LOC GetLocation() const { return m_location; }
71 
72  void SetLegacyFilename( const wxString& aFilename ) { m_legacy_filename = aFilename; }
73 
74  bool IsReadOnly() const { return !m_writeFile; }
75  void SetReadOnly( bool aReadOnly ) { m_writeFile = !aReadOnly; }
76 
80  virtual void Load();
81 
87  virtual bool Store();
88 
94  virtual bool LoadFromFile( const wxString& aDirectory = "" );
95 
101  virtual bool SaveToFile( const wxString& aDirectory = "", bool aForce = false );
102 
106  void ResetToDefaults();
107 
114  OPT<nlohmann::json> GetJson( const std::string& aPath ) const;
115 
123  template<typename ValueType>
124  OPT<ValueType> Get( const std::string& aPath ) const
125  {
126  if( OPT<nlohmann::json> ret = GetJson( aPath ) )
127  {
128  try
129  {
130  return ret->get<ValueType>();
131  }
132  catch( ... )
133  {
134  }
135  }
136 
137  return NULLOPT;
138  }
139 
147  template<typename ValueType>
148  void Set( const std::string& aPath, ValueType aVal )
149  {
150  ( *this )[PointerFromString( aPath ) ] = aVal;
151  }
152 
162  bool Migrate();
163 
170  virtual bool MigrateFromLegacy( wxConfigBase* aLegacyConfig );
171 
180  void AddNestedSettings( NESTED_SETTINGS* aSettings );
181 
186  void ReleaseNestedSettings( NESTED_SETTINGS* aSettings );
187 
188  void SetManager( SETTINGS_MANAGER* aManager )
189  {
190  m_manager = aManager;
191  }
192 
198  static nlohmann::json::json_pointer PointerFromString( std::string aPath );
199 
206  static bool SetIfPresent( const nlohmann::json& aObj, const std::string& aPath,
207  wxString& aTarget );
208 
215  static bool SetIfPresent( const nlohmann::json& aObj, const std::string& aPath, bool& aTarget );
216 
223  static bool SetIfPresent( const nlohmann::json& aObj, const std::string& aPath, int& aTarget );
224 
231  static bool SetIfPresent( const nlohmann::json& aObj, const std::string& aPath,
232  unsigned int& aTarget );
233 protected:
234 
243  void registerMigration( int aOldSchemaVersion, int aNewSchemaVersion,
244  std::function<bool(void)> aMigrator );
245 
253  template<typename ValueType>
254  bool fromLegacy( wxConfigBase* aConfig, const std::string& aKey, const std::string& aDest );
255 
262  bool fromLegacyString( wxConfigBase* aConfig, const std::string& aKey,
263  const std::string& aDest );
264 
271  bool fromLegacyColor( wxConfigBase* aConfig, const std::string& aKey,
272  const std::string& aDest );
273 
274  virtual wxString getFileExt() const
275  {
276  return wxT( "json" );
277  }
278 
279  virtual wxString getLegacyFileExt() const
280  {
281  return wxEmptyString;
282  }
283 
285  wxString m_filename;
286 
289 
292 
294  std::vector<PARAM_BASE*> m_params;
295 
297  std::vector<NESTED_SETTINGS*> m_nested_settings;
298 
301 
307 
310 
313 
316 
319 
322 
324  std::vector<nlohmann::json::json_pointer> m_preserved_paths;
325 
327  std::map<int, std::pair<int, std::function<bool()>>> m_migrators;
328 };
329 
330 // Specializations to allow conversion between wxString and std::string via JSON_SETTINGS API
331 
332 template<> OPT<wxString> JSON_SETTINGS::Get( const std::string& aPath ) const;
333 
334 template<> void JSON_SETTINGS::Set<wxString>( const std::string& aPath, wxString aVal );
335 
336 // Specializations to allow directly reading/writing wxStrings from JSON
337 
338 void to_json( nlohmann::json& aJson, const wxString& aString );
339 
340 void from_json( const nlohmann::json& aJson, wxString& aString );
341 
342 #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:75
wxString GetFilename() const
Definition: json_settings.h:64
virtual wxString getLegacyFileExt() const
SETTINGS_LOC
Definition: json_settings.h:44
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:39
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:70
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:56
SETTINGS_LOC m_location
The location of this settings file (.
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:74
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:68
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:72
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.