Writing a key on top level with QSettings - qt

I'm using QSettings to parse a ini-format file without a group, like this one:
msg=45
id=69
So far so good, but when I try to write a new key, it goes like this:
[General]
new=100
msg=45
id=69
My goal is to have something like this:
msg=45
id=69
new=100
This is my code fro writing:
QSettings settings(m_rcFile, QSettings::IniFormat);
settings.setValue("new", num);
I know most ini files have group/key/value but since QSetings can read them without a group I though that it can do the same for writing. Any ideas?

Seems consistent with the documentation at least, which says
if you save a top-level setting (a key with no slashes in it, e.g., "someKey"), it will appear in the INI file's "General" section.
Just below it says
Following the philosophy that we should be liberal in what we accept and conservative in what we generate, QSettings will [...]
which, while addressing a different quirk, could explain why QSettings can read values from a non-section, but refuses to write there.
Bottom line is that you need a different approach (another library or a low-level class like QFile/QTextStream) to write those values if you really cannot put them in a section.

Related

Make basic Math in Draw.io (diagrams.net)

I want to make some basic math stuff like Sum in Diagrams.net (old Draw.io).Is it possible ?
Exemple : I create a new parameter on a shape, like "Elec : T16" and make several copy on this shape. Is it possible to have a Text which can give me the total of the shape with this parameter ?
Best Regards.
I search a lot in the Diagrams.net blog but anything relevent.
This is not supported.
Regards,
I also wanted to do something similar and while it doesn't seem possible to do it completely in the software (as of v20.3.0), I did find a bit of a workaround: If you add properties to the shape data, then do File > Export As > XML, the properties will be there in the XML data. You can then count them one of two ways:
Open the XML file with a text editor like Notepad++, do a find on the value you want to count. If you choose "Find All" it will tell you how many times it appears.
Use a programming language like Python to read through the file and count the instances of that value.
Example:
I created a red circle in a new diagram, edited the text to say "RedCircle" and used Edit Data to add a property called TestValue, to which I assigned a value of 1. When I exported to XML it contained this element:
<object label="RedCircle" TestValue="1" id="6byQ5fOap-RXn7mFit_J-1">
Notes
When you export, make sure you turn off the Compressed option, this will create an unusable file.
Don't use Save As > XML, this will also use compression.
Diagrams.net natively saves in a compressed XML format, with only slight differences between that and the other compressed XML options, but it seems happy to also read in the exported uncompressed XML. I didn't test but if you go the programming route and want to take it a step further, it seems you could have the program update the value of a given "counter" element with the count, then open the XML file in diagrams.net to see the updated value and save it as a native .drawio file or publish in whatever format you like.
Edit: I discovered that under File > Properties you can turn off the compression on the actual .drawio file. If you do that you can just work from this file instead of exporting, but you might want to check the size of your file with and without it.
I'm sure a plugin could be created to do all of that within the app itself, but the other methods are enough for me at this point.
Hope this helps you!

getopt_long confusion, flag setting with single-char switches

I'm parsing command line options using getopt_long based on the example from the man page. That example does something a bit sneaky, it includes two flag-setting options in long_options but does not list those in the short form parameter string in getopt_long.
Poking about, this answer clarifies what happens in this case, if they enter the short-form it does not set the flag. And leads to my question: If you have a flag-setting switch, and you want to have both long and short forms for that switch on the command line...
Did I miss an option in the short-form string to set flags, sort of like how : works for indicating a parameter follows? Like "v?1" or something?
Failing that, is it best-practices to not do it in the long-form as well, and just return 'v'? Or would "the average code" use the flag-set and have separate code in the switch?
I'd like my code to be "as standard as possible", whatever that means, which is my I'm curious about (2).

Overwrite an existing file programmatically

I have a QDialogBox where there is an option to upload a file.
I can upload files and save them to a folder. It works fine.
But if in case there is a file that already exists in the folder, I am not sure how to handle that scenario.
I want to warn the user that the file with same name already exists.
Is there a Windows API that I can use in this case? (because when we manually save an existing file, we get a warning, how can I use that?)
If someone can point me to that documentation, it will be great.
If you are using a QFileDialog, confirmOverwrite is activated by default, so, if getSaveFileName() returned a non-empty QString, then that means the user accepted to overwrite the file. Other way, you get an empty QString.
Then, you can check if the file exists, and remove it in that case, but you know that the user was Ok with that.
There is always a potential race condition when saving files. Checking to see if the file exists first is not safe, because some other process could create a file with the same name in between the check and when you actually write the file.
To avoid problems, the file must be opened with exclusive access, and in such a way that it immediately fails if it already exists.
If you want to do things properly, take a look at these two answers:
How do I create a file in python without overwriting an existing
file
Safely create a file if and only if it does not exist with
python
You can use QDir::entryList() to get the file names in a directory if you're not using a QFileDialog.
QDir dir("/path/to/directory");
QStringList fileNames = dir.entryList();
Then iterating through file names, you can see if there's a file with the same name. If you need it, I can give an example for that too. It'd be C++, but easily adaptable to Python.
Edit: Smasho just suggested that using QDir::exists() method. You can check if the file name exists in the directory with this method instead of iterating like I suggested.
if(dir.exists(uploadedFileName))

Qt internationalization system with different positioned strings

I'm aware that there are some languages that writes the order of some characters differently than the common latin languages. E.g.: a percentage number in English would be like "100%", while in Persian it would be "/100" (the symbol comes before the number).
Question: how to consider that in the Qt internationalization system in an intelligent way?
I first thought about this code:
myLabel->setText(tr("%1%2").arg(value).arg(tr("%")));
So what would happen is that, in the Qt Linguist, the translator would change the order of the replacement fields:
%1%2 -> in Persian translation -> %2%1
I checked that in my code and I found out that while in the normal (English) translation everything was fine, when I changed to the file containing the performed translation, a bug would occur: the number to be shown was never complete having one less number that what I had written. So e.g. if I chose "99%", it would show "%9", and if I set only "9%", I would have just "%".
The problem disappeared when I put a space between %1 and %2 both in the source code as well as in the translation (%2 %1). Since ISO xxxxx says that the % should be placed with a space between it and the correspondent number, no problem for this specific situation. But what If I wanted to have both symbols without a space between each other? How should it be done?
I confirm that the problem you described exists. However I would solve this problem in the following way:
QString sPer = QString("%%1").arg(value); // %99
QString sEng = QString("%1%").arg(value); // 99%
So that
%1% -> in Persian translation -> %%1
Put the percentage inside the string to translate, something like
myLabel->setText(tr("%%1").arg(value))
even better, I think I would add a disambiguation string (Qt "old style" comment)
myLabel->setText(tr("%%1", "Show the number with a percentage").arg(value))
or maybe a new style translation comment like this
//: Show the number with a percentage
myLabel->setText(tr("%%1").arg(value))
Translator comments have issues of their own, you might be better off using a Qt disambiguation string like the preceding example.
Putting a disambiguation string (or a translator comment) will let your translator know what they are translating...
Let the translators decide where they want to put the percentage, don't try to handle it in the code as somebody else suggested, it is not scalable, you can't start handling this in the code like that, what if you need to use another character or formatting for another language?
It might even be possible that Qt might have calls to handle number formatting but I can't seem to find them at the moment and I am not fully sure how we handle them in the Qt application I work on...
If putting a % alone doesn't work, try to precede it with \, it might be necessary to escape it, I am not sure...

Qt QFileDialog - native dialogs only with static functions?

I'm trying to simply save a file. However, I need a filename entered without a suffix to automatically get a default suffix (which setDefaultSuffix() does).
I'd rather not completely lose the native save dialog just for this. exec() is not overloaded from QDialog, so it totally bypasses the native hook (ignoring the DontUseNativeDialog option even if it's false).
If I disable the file overwrite warning and append the default suffix myself after the function returns, then I'd be re-opening the dialog if the user did not want to overwrite... and that's just ugly.
Is there some signal I can catch and quickly inject the default suffix if it's not there? I'm guessing not, since it's a native dialog.
Is there something I'm doing wrong with the filter? I only have one filter choice. It should use that extension.
This seems pretty lame. Launching the save dialog and simply typing "test" should never result in an extensionless file. "test.", yes. "test" no way. That'll really confuse the users when they hit Load and can't see the file they just saved.
I guess the cross-platform part of Qt is giving me lowest common denominator file dialog functionality?
Yes, if you look at the Qt source code it is evident that only the static functions uses native file dialogs. It is not possible to get native dialogs any other way, unfortunately...
Have you tried the filter options in the static functions? [Edit: Oops, noticed that you already have.]
I just tried this myself, for example, and things seem to be fairly reasonable:
QString filter = "Text files (*.txt)";
QString selectedFilter;
QString filename = QFileDialog::getSaveFileName(0, "", "", filter, &selectedFilter);
Entering test in the save dialog returns test.txt.
Entering test. in the save dialog returns test..txt.
Entering test.foo in the save dialog returns test.foo.
These all show the appropriate overwrite dialog if there is already an existing file with that name.
The only way I can get test, without any suffixes, is by surrounding it with quotes ("test"), or by first entering *.* (which will make it display all files) and then entering test. (Although one oddity is that selectedFilter will still contain the filter shown in the dialog, even if it's not used).

Resources