How to stop QSettings altering the order of key=value pairs in setting file? - qt5

In my program I have a Microsoft's INI style settings/configuration file that is created, edited and stored using the convenient QSettings class but the user may manually edit this file using the program itself, or any text editor she desires like gedit or vim. The order in which key=value pairs appear is important. The problem is whenever I try to store the changes at shutdown time, the order of key=value pairs change to a random order and it seems impossible to stop QSettings from changing it. For clarification here's a sample of a configuration file:
[AlarmGroup1]
DateTimeNotInitialized=1
DateTimeStampError=2
ParametersMissingOrInconsistent=3
NotInitialized=4
FlashMemoryFatalError=5
NotIdentified=6
which changes to:
[AlarmGroup1]
ParametersMissingOrInconsistent=3
DateTimeNotInitialized=1
DateTimeStampError=2
NotInitialized=4
FlashMemoryFatalError=5
NotIdentified=6
Is it possible to avoid the change of order? Why is Qsettings behaving like this?

QSettings behaves like this because the problem it was designed to solve was saving/retrieving single key/value pairs, not ordered lists of pairs.
To solve this you will need to either :
Remove the requirement for a specific order from you program
Write your own equivalent of QSettings
Write a "custom storage format provider" to pass into QSettings http://doc.qt.io/qt-5/qsettings.html#registerFormat

Related

Is there a way to do string replacement/substitution in sql?

I have some records in a CMS that include HTML fragments with custom tags for a widget tool. The maker of the CMS has apparently updated their CMS without providing proper data conversion. Their widgets use keys for layout based on screen width such as block_lg, block_md, block_sm. The problem kicks in with the fact they used to have a block_xs and they have now shifted them all -- dropping the block_xs and instead placing a block_xl on the other end.
We don't really use these things, but their widget configurations do. What this means for us is the values for each key are identical. The problem occurs when the updated CMS code is looking for the 'block_xl' in any widget definition tags, it can't find it and errors out.
What I'm thinking then is that the new code will appear to 'ignore' the block_xs due to how it reads the tags. (and similarly, the old code will ignore block_xl) Since the values for each are identical, I need to basically read any widget definition and add a block_xl value to it matching the value of [any one of] the other width parameters.
Since the best place order-wise would be 'before' the block_lg value, it's probably easiest to do it as follows:
Replace any thing matching posix style regex matching /block_lg(="\d+,\d+")/ with: block_xl="$1" block_lg="$1"
Or whatever the equivalent of that would be.
Example of an existing CMS block with multiple widget definitions:
<div>{{widget type="CleverSoft\CleverBlock\Block\Widget"
widget_title="The Album" classes="highlight-bottom modish greenfont font52 fontlight"
enable_fullwidth="0" block_ids="127" lazyload="0"
block_lg="127,12," block_md="127,12," block_sm="127,12," block_xs="127,12,"
template="widget/block.phtml" scroll="0" background_overlay_o="0"}}</div>
<!-- Image Block -->
<div>{{widget type="CleverSoft\CleverBlock\Block\Widget"
widget_title="What’s Your Favorite Cover Style?"
classes="zoo-widget-style2 modish grey font26 fontlight"
enable_fullwidth="0" block_ids="126" lazyload="0"
block_lg="126,12," block_md="126,12," block_sm="126,12," block_xs="126,12,"
template="widget/block.phtml" scroll="0" background_overlay_o="0"}}</div>
What I would prefer to end up with from the above (adding block_xl):
<div>{{widget type="CleverSoft\CleverBlock\Block\Widget"
widget_title="The Album" classes="highlight-bottom modish greenfont font52 fontlight"
enable_fullwidth="0" block_ids="127" lazyload="0"
block_xl="127,12," block_lg="127,12," block_md="127,12," block_sm="127,12," block_xs="127,12,"
template="widget/block.phtml" scroll="0" background_overlay_o="0"}}</div>
<!-- Image Block -->
<div>{{widget type="CleverSoft\CleverBlock\Block\Widget"
widget_title="What’s Your Favorite Cover Style?"
classes="zoo-widget-style2 modish grey font26 fontlight"
enable_fullwidth="0" block_ids="126" lazyload="0"
block_xl="126,12," block_lg="126,12," block_md="126,12," block_sm="126,12," block_xs="126,12,"
template="widget/block.phtml" scroll="0" background_overlay_o="0"}}</div>
I know how to do it in php and if necessary, I will just replace it on my local DB and write an sql script to update the modified records, but the html blocks can be kind of big in some cases. It would be preferable, if it is possible, to make the substitutions right in the SQL but I'm not sure how to do it or if it's even possible to do.
And yes, there can be more than one instance of a widget in any given cms page or block. (i.e. there may be a need for more than one such substitutions with different local 'values' assigned to the block_lg)
If anyone can help me do it in SQL, it would be greatly appreciated.
for reference, the tables effected are called cms_page and cms_block, the name of the row in both cases is content
SW

How to apply metadata to all files in a content directory

I have a content directory called foo and I want all files under that directory to have an extra metadata item foovar: default, unless explicitly overridden in the file header. I think I'm supposed to do this with EXTRA_PATH_METADATA, but I can't figure out what incantation it wants.
(for my current use case I'm trying to apply template: sometemplate within this dir, but I'm interested in solving the general case as it would make several related headaches go away)
I think what you're looking for is actually DEFAULT_METADATA. Check out this portion of the documentation:
DEFAULT_METADATA = {}
The default metadata you want to use for all articles and pages.
So, in your case it might look something like this in your config file:
DEFAULT_METADATA = {'foovar': 'default'}
Then to assign your custom template(s), see this portion of the documentation.
This wasn't possible at the time I asked. I've since sent the devs a PR adding support, and it's been merged to master. Presumably it will go out in the next release. It makes EXTRA_PATH_METADATA recursive, so you can apply settings to a subdir like this:
EXTRA_PATH_METADATA = {'dirname/subdir': {'status': 'hidden'}}

Salt and managing .ssh/authorized_keys

Salt has a state module to manage .ssh/authorized_keys
https://docs.saltstack.com/en/develop/ref/states/all/salt.states.ssh_auth.html
I am not happy with it, since it combines code and data.
The state file is for me some kind of source code.
The ssh-key is for me data.
I don't want to combine both in one file.
Is there an other solution which separates code and data?
you don't have to put them together in one file:
as per documentation: https://docs.saltstack.com/en/latest/ref/states/all/salt.states.ssh_auth.html
you can use this method:
thatch:
ssh_auth.present:
- user: root
- source: salt://ssh_keys/thatch.id_rsa.pub
- config: /%h/.ssh/authorized_keys
(contrary to the example in the documentation, i get an error if the config: value starts with a '%')
this keeps your keys in their appropriate files and only links them from your code by their filenames.
Please have a look at the OpenSSH Formula. openssh/auth.sls contains the code for a state that pulls all data from a pillar. In the root folder of the formula you find pillar.example that shows how to structure the data for a pillar.
Maybe this formula is a starting point for you.

Synchronize modification between SWT table and TextEditor

I'm facing a problem and want to ask for a solution.
I'm working on an eclipse plugin project, in which an editor for a type of resource file is required. The resource file has similar structure like CSV file. My idea is to provide user the option to edit this type of file both in plain text format and also in an SWT table. Plain text is required for examining data and table provides more flexibility to editing such as sorting by column.
I have been able to create a MultiPageEditorPart, with one page of org.eclipse.ui.editors.text.TextEditor, and another page with a org.eclipse.swt.widgets.Table and several other widgets like search bar. The content of the resource file can be shown in the TextEditor, can also be edited and saved. On the other hand, the content can be loaded in the table too, sorting and searching all work good.
The problem is: when I edit a cell in the table, I want the change also reflected in the TextEditor, and vice versa. Since the resource file can be very large, I want the saving action happen only on the TextEditor, i.e. I don't want any modification in the table directly stored to resource file, but to mark the file dirty, but I can't figure out how. How can I for example get the content of EditorInput, check it line by line, and modify it outside TextEditor?
Or, are there more efficient ways to do this? Can anyone give any hints?
The IDocument used by the TextEditor gives you access to the document contents. Get this with something like:
IDocumentProvider provider = editor.getDocumentProvider();
IEditorInput input = editor.getEditorInput();
IDocument document = provider.getDocument(input);
IDocument has many methods for accessing lines such as:
int getLineOffset(int line);
int getLineLength(int line);
and methods for modify the text:
void replace(int offset, int length, String text);

Eclipse RCP: How to order perspective buttons belonging to different plugins?

My application has 5 plugins. Each plugin has a perspective of it's own and hence each perspective extension definition is under individual plugin's plugin.xml.
Now, I want to control the order in which these perspectives appear in my application. How to do it?
There is one main plugin that holds "ApplicationWorkBenchAdvisor.java". This has initialize() method in which I am iterating through the perspective registry using
PlatformUI.getWorkbench().getPerspectiveRegistry().getPerspectives();
and then appending perspective ids in a comma separated fashion to a String variable (pbar) which is used later like this.
PlatformUI.getPreferenceStore().setDefault(IWorkbenchPreferenceConstants.PERSPECTIVE_BAR_EXTRAS, pbar);
PlatformUI.getPreferenceStore().setValue(IWorkbenchPreferenceConstants.PERSPECTIVE_BAR_EXTRAS, pbar);
When iterating thourgh the perspective registry, I can compare perspective ids and sort it(when adding to 'pbar' by comparing ids) the way I want it to appear but, I don't want to do this ordering here as it appears like a dirty way.
Is there any other place where we can fix the order in which perspectives appear? (Each perspective resides in different plugin).
ADDED
1) Could we also control the ordering in the perspective switcher?
2) Is there a way to control entry into perspective registry to in inflict the desired order. If not could we write back into perspective registry?
If your application is encapsulated as an eclipse product, you may tweak the plugin.properties/plugin_customization.ini file.
(file referenced by the 'preferenceCustomization' property in your product extension point.)
This file is a java.io.Properties format file. Typically this file is used to set the values for preferences that are published as part of a plug-in's public API.
(Example of such a file for org.eclipse.platform)
So if the string representing the order of perspective can be referenced as a property, you can define the default order in there.
Since the source code of IWorkbenchPreferenceConstants mentions:
/**
* Lists the extra perspectives to show in the perspective bar.
* The value is a comma-separated list of perspective ids.
* The default is the empty string.
*
* #since 3.2
*/
public static final String JavaDoc PERSPECTIVE_BAR_EXTRAS = "PERSPECTIVE_BAR_EXTRAS"; //$NON-NLS-1$
Maybe a line in the plugin_customization.ini file:
org.eclipse.ui/PERSPECTIVE_BAR_EXTRAS=perspectiveId1,perspectiveId2,perspectiveId3
would allow you to specify that order without having to hard-code it.
Additional notes:
IPerspectiveRegistry (or PerspectiveRegistry) is not made to write anything (especially for perspective defined in an extension)
Ordering may be found in the state of the workbench (stored in the workspace and then restored when its launched again, .metadata/.plugins/org.eclipse.ui.workbench/workbench.xml)
Do you confirm that:
IPerspectiveRegistry registry = PlatformUI.getWorkbench().getPerspectiveRegistry();
IPerspectiveDescriptor[] perspectives = registry.getPerspectives();
is not in the right order when the plugin_customization.ini does define that order correctly ?
Liverpool 5 - 0 Aston Villa does confirm that (in the comments), but also indicates the (ordered) ini file entries internally get recorded into preference store, which means they can be retrieved through the preference store API:
PatformUI.getPreferenceStore().getDefault(
IWorkbenchPreferenceConstants.PERSPECTIVE_BAR_EXTRAS)
Liverpool 5 - 0 Aston Villa then add:
perspective registry (the initial "PlatformUI.getWorkbench().getPerspectiveRegistry().getPerspectives();" bit) remains unaltered (and unordered).
But, you still can "readily access to ordered list of perspectives" through preference store.
So, for other tasks, instead of iterating though perspective registry (which is still unordered), we can use the ordered variable that stores list of ordered perpective ids.
.
.
.
.
Note: another possibility is to Replace the Perspective-Switcher in RCP apps
=> to:
You can more easily define the order in a menu or in buttons there.
Extreme solution: re-implement a perspective switcher.
To sum up all the observations and findings,
1) It is not possible to alter entries in the perspective registry. It is read-only.
2) To make perspective appear in the order that we want on perspective bar, we can achieve it by adding an entry in plugin_customization.ini (or preferences.ini) as shown below.
org.eclipse.ui/PERSPECTIVE_BAR_EXTRAS=perspectiveId1,perspectiveId2,perspectiveId3
3) If we want to fetch this ordered list, we can't fetch it directly. But as this ini file entry internally gets recorded in PreferenceStore we can fetch the same value from PreferenceStore using the following API as shown below.
PlatformUI.getPreferenceStore().getDefault(
IWorkbenchPreferenceConstants.PERSPECTIVE_BAR_EXTRAS);
Why would someone need to access the entry defined in ini file at all?
Well, in my case I had a view in which i had to display links to every perspective. As my perspective bar was sorted in desired order, I also wanted to maintain the same order in my view while displaying links to perspectives.
4) There is no known way to inflict the same sort order in the display of default perspective switcher. While a new custom perspective switcher can be written to achieve the desired effect.