Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Which file extension was selected?



  • This code is in C++.
    It is for Linux.
    I am on Kubuntu 20.10.

    Let’s say I have this program that can save an image as a TXT file, a RTF file, a DOC file.
    Let’s say the user opens a Save As dialog box.
    From the file filter, He selects RTF.
    He gives the filename 11.11
    How can I know that he selected RTF?

    char pSaveFilePath[some size];
    QFileDialog *aDlg;
    selectedFilter="TXT - Text file (*.txt)";
    fileFilter="TXT - Text file (*.txt);;RTF - Rich text file (*.rtf);;DOC - document file (*.doc)";
    aDlg=new QFileDialog(this, "Save As", pSaveFilePath, fileFilter);
    aDlg->setFilter(QDir::AllEntries);
    aDlg->selectNameFilter(selectedFilter);
    aDlg->setAcceptMode(QFileDialog::AcceptMode::AcceptSave);
    returnVal=aDlg->exec();
    if(returnVal==QDialog::Accepted)
    {
       qstringlist=aDlg->selectedFiles();
       if(qstringlist.size()==0)
       {
          delete aDlg;
          return;
       }
       CopyFromQSTRINGToSCHAR(&qstringlist.at(0), pSaveFilePath, 0);
       //Now I need to process the text buffer depending on the file format that the user has chosen.
    }
    

    Now I need to process the text buffer depending on the file format that the user has chosen.
    If the user gives a name of 11.11 for the filename, I receive
    11.11 in pSaveFilePath





  • Noob mistake...Don't use filename extensions to determine file type. File extensions have no meaning in unix/linux. Use the "file" command or "magic" facility to determine the type of file. Determining how to make use of them is left as an exercise for the OP.



  • @Kent-Dorfman Can you clarify. In which header file is the file function and magic function located? I am using C++. Are these Qt functions? Which class?



  • man file
    man magic


  • Moderators

    @stretchthebits said in Which file extension was selected?:

    In which header file is the file function and magic function located? I am using C++. Are these Qt functions? Which class?

    To clarify @Kent-Dorfman's latest post: file and magic are not C++ functions. They are Linux console tools.



  • @JKSH Oh Ok. I guess he is suggesting to not place file extensions on a file but most users have a Windows background and prefer GUI tools.
    One look at a file name like MyBills.ods and I know what type of file that is.
    For example. It is possible that a file is not local to me. I don't want to download a file just to find out what type of extension it has.
    Another situation comes into play with Open Dialog boxes. Perhaps I do not want to see all files. Perhaps I want to see JPEG files only. It is much faster for code to filter files via filename extension.
    Also, if I have mypic.bmp, mypic.jpg, mypic.tif, the file extension gives a distinction to each file and we can keep them all in the same folder.

    Anyway, Nagesh's suggestion worked. It returns a string.
    I think a more direct approach is to get an index value since the extension list is just a COMBO BOX.



  • stretchthebits about 8 hours ago

    @JKSH Oh Ok. I guess he is suggesting to not place file extensions on a file but most users have a Windows background and prefer GUI tools.
    One look at a file name like MyBills.ods and I know what type of file that is.

    No...what I am stating is that you cannot trust file extensions. They are just hints. visual indicators of the type of data in a file are fine, but there is no tight binding between the name of a file and it's data...if you are making brnahcing/processing decisions for a file don't you think you need to be very that what you think is in the file actually is? A previous post on here had a guy trying to use lnk extensions on data files. Well, windoze expects that lnk files are symlinks to another file, not normal files themselves, so of course that's no going to work.



  • @Kent-Dorfman said in Which file extension was selected?:

    had a guy trying to use lnk extensions on data files

    Well, this is why there should be a standards across all OSes. Standards make things easier on the programmer.
    For example, if Apple decides to offer Metal as the 3D graphics API on their device, Android has OpenGL ES, Windows has Direct3D+OpenGL, XBox has Direct3D, PS has something else, Wii U has something else.

    So when it comes to file extensions, this is a good visual indicator. It should be standardized.
    The problem is that there is no governing body for extensions. What if I make a new file format and give it a DOC extension?

    It’s not a problem for my code. If you want to give your filename 1111.doc and my code tries to read it, it will notice that it is invalid.
    The file filtering is done at the GUI level, in the Open dialog box.
    I explained the advantage of file filtering based on extension. If a folder has 100,000 files, I don’t want to go through all of them. I just want to see the .DOC files.
    This was specially important long ago when we used floppy drives and CD-ROM.
    Reading each files header is a slow process.
    The OS should load the FAT into RAM and quickly do filter for my Open File dialog.

    “had a guy trying to use lnk extensions on data files”

    ==Aha! No governing body for file extensions.
    Even file headers don’t have a standard. That’s bad.



  • It's bad enough how frequently I have to rant on folks for embedding punctuation and spaces in filenames and then expecting them to magically works across several different OS environments. filename standards are a wonderfully naive idea that could never happen nor work...30+ years of computer history has a lot to say about that.



  • @Kent-Dorfman said in Which file extension was selected?:

    Use the "file" command or "magic" facility to determine the type of file.

    This doesn't really qualify here. He was asking about the selected extension in a save dialog. You cannot use "file" or "magic" on a file that you are about to write. @nagesh's answer is right that you can use selectedNameFilter(). Even when opening files most of the time you can rely on file extensions. You only need to be careful with files from unknown persons/locations which might be disguised with a wrong extension and are used to attack your computer through the software.

    I'd like to add that you shouldn't use a pointer to QFileDialog as you have to manage object lifetime yourself in this case. Just make it QFileDilaog aDlg(this, "Save As", pSaveFilePath, fileFilter); instead and you don't have to worry about it anymore. Personally, I even usually choose the static member QFileDialog::getSaveFileName() instead. There is a parameter selectedFilter which will give you back the information you need in your specific case. I believe, however, that getSaveFileName() will append the extension to the filename if no proper extension is given. I am surprised this is not the case with the code you posted.



  • @SimonSchroeder said in Which file extension was selected?:

    I'd like to add that you shouldn't use a pointer to QFileDialog as you have to manage object lifetime yourself in this case. Just make it QFileDilaog aDlg(this, "Save As", pSaveFilePath, fileFilter);

    The problem with that is that there is code that needs to come before the creation of an instance of QFileDialog.
    I don’t like declaring variables or instances midway in a function.
    I prefer to keep them all at the top of the function.

    @SimonSchroeder said in

    There is a parameter selectedFilter which will give you back the information you need in your specific case.

    Before, I was using QFileDialog::getSaveFileName().
    Then, I discovered that if the user gives a filename such as MyFile-2020.04.15, Qt does not append the file extension and my code checks what the file extension was. It does not find it so my code uses a default file extension of TXT. <---That’s bad.

    Then I checked out selectedFilter. I was not getting feedback in parameter selectedFilter.
    So, I got rid of QFileDialog::getSaveFileName().
    I replaced with the code that you see in my initial post.

    The problem of Qt not adding an extension is still present but this time, selectedNameFilter() can tell me what extension the user wants.
    I added code to detect the missing extension in pSaveFilePath and add the extension.

    There you go. Problem solved forever.


  • Moderators

    @stretchthebits said in Which file extension was selected?:

    Before, I was using QFileDialog::getSaveFileName().
    I discovered that if the user gives a filename such as MyFile-2020.04.15, Qt does not append the file extension and my code checks what the file extension was. It does not find it so my code uses a default file extension of TXT. <---That’s bad.

    Then I checked out selectedFilter. I was not getting feedback in parameter selectedFilter.

    I can't reproduce what you described.

    QString selectedFilter;
    QString selectedFilePath = QFileDialog::getSaveFileName(
            nullptr,
            "Pick me",
            "C:/Users/JKSH/Documents/",
            "TXT - Text file (*.txt);;RTF - Rich text file (*.rtf);;DOC - document file (*.doc)",
            &selectedFilter);
    
    qDebug() << "File path is" << selectedFilePath;
    qDebug() << "Filter is" << selectedFilter;
    

    If I enter "MyFile-2020.04.15" as the file name and pick "*.rtf" as the file extension, then I get this output:

    File path is "C:/Users/JKSH/Documents/MyFile-2020.04.15.rtf"
    Filter is "RTF - Rich text file (*.rtf)"
    

    Works on Qt 5.12.10 (MinGW 7.3.0 32-bit) and Qt 5.15.2 (MSVC 2019 64-bit) on Windows 10 20H2.



  • @JKSH I tested again with my original code, which had the QFileDialog::getSaveFileName. Looks like I am way off. It works!
    Sorry, somehow I guess I got confused.


Log in to reply