Qt QFileDialog - native dialogs only with static functions? - qt

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).

Related

How do I check whether a file exists without exceptions in Julia?

How do I see if a file exists without exceptions using Julia? I want to make sure that my program does not crash if for some reason the file I am trying to open is not accessible, has been deleted, or does not exist.
There are two simple ways of doing so.
First:
println(isfile("Sphere.jl"))
false
This isfile() function will simply check if the file exists. Note: if Sphere.jl is not in your current file path, you would need to provide the absolute path to get to that file.
Second (more of a trial by fire example):
try
open("Sphere.jl", "w") do s
println(s, "Hi")
end
catch
#warn "Could not open the file to write."
end
The second example utilizes the try-catch schema. It is always best for your program to not have to deal with errors so it's recommended that you use isfile() unless you have to use try-catch for your use case.
It's worth noting that there may be some cases where the file exists, but writing to it is not possible (i.e. it's locked by the os). In that case, using try-catch is a great option when attempting to write.

Writing a key on top level with QSettings

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.

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))

How to change an incorrect Mac file's Kind

I have several SQLITE files all of which have Kind set correctly to Document except for one which is Kind = Unix Executable file. It still loads and runs fine. I'd like to clean this up but can't find a way to change Kind for this file to Document.
Anybody know why Kind would have been set incorrectly in the first place and how to change it to the correct value? I've searched here and on Google.
Is there an extension (possibly hidden) set on the file? I think that 'Documents' are merely files without extensions. I'd try File>Get Info on it (via Finder) and checking to make sure there isn't a hidden extension in the 'Name & Extension'
I had the same issue with my php_error.log file. It was "document" and then I foolishly changed the "kind". That mean that the php log wouldn't work and my MAMP server didn't recognise it.
It's still "text document", but to fix the issue I opened up the file in TextEdit, selected "make rich text" under format, saved the file, closed it down, reopened it in TextEdit, selected "make plain text" under format, saved the file and it worked...

Send file using Response.BinaryWrite() and delete it afterwards

As part of a Classic ASP Project the user should be able to download a file - which is dynamicly extracted from a zip archive and sent via Response.BinaryWrite() - by simply calling "document.asp?id=[some id here]".
Extracting and sending is not the problem but I need to delete the extracted file after the download finished. I never did any ASP or VBA before and I guess that's why I stuck here.
I tried deleting the file right after Response.WriteBinary() using FileSystemObject.DeleteFile() but this results in a 404-Error on the client-side.
How can I wait till the download finished and then do additional actions?
Edit: This is how my code looks like:
'Unzip a specified file from an archive and put it's path in *document*
set stream = Server.CreateObject("ADODB.Stream")
stream.Open
stream.Type = 1 ' binary
stream.LoadFromFile(document)
Response.BinaryWrite(stream.Read)
'Here I want to delete the *document*
I suspect that the point you are calling the DeleteFile method the file you are trying delete is currently locked by something else, the question is what?
Try including:-
stream.Close()
after your BinaryWrite. Also make sure you've done a similar thing to the component you've used to extract the file. If the component doesn't offer any obviouse "close" methods they trying assigning Nothing to the variables referencing them.
Is it not possible to stream the file into memory, then binary write the stream to the browser, this way the file is never created on the server and there is no need to delete it.
I found a solution: The extracted files are saved in a special directory and everytime a user runs the document.asp it checks this directory for files older than one hour and deletes them.
I think it's the simplest way to manage, but furthermore I would prefer a solution where the document is deleted after downloading.

Resources