[Development] Start of a refactor of the QSettings class based on QJson

Thiago Macieira thiago.macieira at intel.com
Fri Sep 26 00:31:11 CEST 2014


On Thursday 25 September 2014 16:33:12 Tomaz Canabrava wrote:
> Long that that I have send this e-mail already, but better late than never.
> In the Qt Develompent Summit I raised my hand to get one dirty thing done:
> 
> The Settings.
> 
> After a good while with negative time ( Real Work, KDE, Subsurface, and
> other personal stuff ) I have finally had the time to start.
> 
> For now, I'v implemented two things:
> 
> Parsing from .ini to QJson
> Saving from QJson to .ini
> 
> Why .ini instead of json, since I'm doing a conversion and I coul'd simply
> store the json file?
> 
> .ini is better to humanreadability.
> thiago asked me to do from ini to qjson

Tomaz forgot a bit of the rationale for this.

We want to have our cake and eat it too: we want both the ability to edit 
config files by hand and the speed of QJsonDocument. So we have a bunch of INI-
style files that cascade their settings like the XDG Desktop file format, 
hopefully, are backwards compatible with QSettings, and can be edit by hand.

Upon reading them, we save a cache of the settings in a binary JSON format. 
That file is not hand-editable and we should not have to write a tool to 
manipulate it. The file needs to contain the names of the source INI files it is 
a cache of and their timestamps, so that hand editing of the sources 
invalidates the cache.

It means, however, that saving the settings saves at least two files and cannot 
be done atomically. That's where QLockFile should come in handy.

> After a Json tree is constructed, it's hard to modify it's contents:
> 
> QJsonObject rootConfig;
> rootConfig.insert("group1", QJsonObject());
> rootConfig.insert("group2", QJsonObject());
> 
> QJsonObject group1 = rootConfig.vaule("group1").toObject();
> group1.insert("key1", 1);
> rootConfig.insert("group1", group1);
> 
> since I need to take the value, modify it, insert it back nested groups are
> a pain to use,
> because I would have to chain the removal / addtion of the parent group
> untill I hit the rootGroup.

Tomaz is planning to use the JSON classes as in-memory storage too, which may 
or may not be the best solution.

I can think of three possibilities:

1) use QJsonDocument & family all the way, which means figuring out a solution 
to the above problem

2) use QJsonDocument only to read the on-disk cache, then keep an in-memory 
cache using a different storage mechanism (probably based on QVariantHash).

3) use a hybrid approach: use QJsonDocument for reading the cache and keep 
*that* cache in memory, but keep modifications separate, sync'ing the two 
storages only at the time the file actually gets saved.

I think we will probably need #3 anyway so that we don't write *all* value 
entries to the the human-readable INI, only those that were modified from the 
original.

> what I plan to do, besides that:
> - changed the config file from outside of the app, the app should reload
> it's settings.

Separate class, but yes, this is needed for GNOME- and OS X-style configuration 
mechanisms where changes are applied immediately upon change in the UI and 
propagate to all applications.

I'm not sure we should Qt hide this on a platform config, but it's something we 
should think about.

> - compile-time check of typos in keys based on a schema ( and not runtime. )

Leave schema for a second version and focus on getting the storage right first.

> the *temporary* repo with the *temporary and somewhat broken* code:
> github.com:tcanabrava/QConfigNG

https://github.com/tcanabrava/QConfigNG

We can't it access via SSH because we're not you.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center




More information about the Development mailing list