views:

296

answers:

2

I want the filter in a QFileDialog to match all audio file types supported by Phonon on the platform in question.

1 - However I am not able to find a way in Qt to use mime types in a filter. How can I do that?

2 - Or how can I find the corresponding file extensions for the mimetypes manually? The solution should be Qt based, or at least be cross platform and supported everywhere Qt is.

Option one is my preferred solution, however option two will do as well..

Following is a short code describing my problem:

#include <QApplication>
#include <QFileDialog>
#include <QStringList>
#include <phonon/backendcapabilities.h>

QStringList mime_to_exts(QString mime)
{
   // WHAT TO REALLY DO ??
   // NEEDLESS TO SAY; THIS IS WRONG...
   return QStringList(mime.split("/").back().split('-').back());
}

int main(int argc, char **argv)
{
   QApplication app(argc, argv);
   app.setApplicationName("phononext");

   QStringList p_audio_exts;
   QStringList p_mime_types = Phonon::BackendCapabilities::availableMimeTypes();
   for(QStringList::iterator i = p_mime_types.begin(), ie = p_mime_types.end(); i != ie; i++)
   {
      if((*i).startsWith("audio"))
         p_audio_exts << mime_to_exts(*i);
   }

   QString filter = QString("All Files(*)");
   if(!p_audio_exts.isEmpty())
   {
      QString p_audio_filter = QString("Audio Files (*.%1)").arg(p_audio_exts.join(" *."));
      filter = QString("%1;;%2").arg(p_audio_filter).arg(filter);
   }

   QFileDialog::getOpenFileName(NULL, "Open Audio File", QString(), filter);
}
A: 

Call availableMimeTypes() on the Phonon backend and then loop through the resulting MIME-type list and for each one enumerate the extensions returned by QMimeType::extensions().

Stu Mackellar
QMimeType is not part of Qt, but part of the library QT Extended. Which is quite a large library for such a small task. But I looked into the source code of qmimetype.cpp to see what they did. Unfortunately it seems the library is GNU/Linux only. The way they find the extensions is just to extract them from /etc/mime.types, which is not cross platform.
Mathias
Disregard the previous comment, it is wrong!It turns out that Qt Extended in fact ships its own mime.types file, hence the method mentioned in the answer above is cross platform. But not good.I can off cause just create a similar file, but maintaining it is work. And more important the file is bound to be incomplete, and miss mime-types. This IS information that the operation system already knows (in fact only the OS knows, and only at run-time), so anything but asking the OS is not a good solution. Therefore I am still looking for a solution to this problem.
Mathias
A: 

You can filter on mime types with QFileDialog::setProxyModel. You'll probably want to subclass QSortFilterProxyModel and override filterAcceptsRowso that it accepts only when the file is of the appropriate mime-type. Hopefully this, when bound with an easy way to identify a file's mime-types, will serve as a good solution.

Kaleb Pederson
Nice, this is a good solution. There are however two drawbacks as far as I can see.A minor one, being that the filter dropdown box in the dialog will not be filled with allowed file types. However you can probably just put some descriptive text there. Like in my case "Audio files".A more severe drawback is that you can not use native file dialogs any longer. This is a show stopper for me and my final(?) solution is to ship a mime.types file with my application, but I hate it! If you don't care about native dialog this is a better solution in my opinion. Hence I mark it as a correct answer.
Mathias
Yeah, native file dialogs have their benefits and their problems. They're more reliable than the Qt dialogs (especially with network shares and favorites), but you can't customize button text and other things as you can with the Qt dialogs. WRT dropdown filter, you're right. I'm curious if the files are filtered based on extension after a proxy model is put in place, but haven't tested to know for sure.
Kaleb Pederson