views:

89

answers:

3

Users open files in our app through a QFileDialog. The order of the filenames is bizarre. What is determining the sorting order, and how can we make it sort by filenames, or otherwise impose our own sorting, perhaps giving it a pointer to our own comparison function?

The documentation and online forums haven't been helpful. Unless it's well hidden, there doesn't seem to be any sorting method, property, etc.

This is a primarily Linux app, but also runs on Macs. (I know nothing about Mac.)

Here is the juicy part of the source code:

QtFileDialog chooser(parent, caption, directory, filter);
/// QtFileDialog is our class derived from QFileDialog

chooser.setModal(true);
chooser.setAcceptMode(acceptMode);
chooser.setFileMode(fileMode);

QStringList hist = chooser.history();
chooser.setHistory(hist);

/* point "x" */

if(chooser.exec()) {    
    QStringList files = chooser.selectedFiles();
    ...blah blah blah...

From one of the answers, I tried an evil experiment, adding this ill-informed guesswork code at "point x":

QSortFilterProxyModel *sorter = new QSortFilterProxyModel();
sorter->sort(1);  // ???
chooser.setProxyModel(sorter);

But this crashed spectacularly at a point about 33 subroutine calls deep from this level of code. I admit, even after reading the Qt4 documentation and sample code, I have no idea of the proper usage of QSortFilterProxyModel.

+1  A: 

I think what you need to do is create a QSortFilterProxyModel which you then set in your QFileDialog with QFileDialog::setProxyModel(QAbstractProxyModel * proxyModel)

Here are some relevant links to the Qt 4.6 docs about it.

http://doc.trolltech.com/4.6/qfiledialog.html#setProxyModel

http://doc.trolltech.com/4.6/qsortfilterproxymodel.html#details

Grant Lammi
Yikes! Looks like a can of complicated worms I'd rather avoid.
DarenW
Is there a clear simple example of using QSortFilterProxyModel with a file open dialog? The only examples I see are using some sort of tree list thingy, which we don't care about. It's looking like this is the only way for us to take control of sorting.
DarenW
+3  A: 

Are you using QFileDialog by calling exec()? If you are, you should have a button to switch the view to Detail View. This will give you some column headers that you can click on to sort the files. It should remember that mode the next time the dialog opens but you can force it by calling setViewMode(QFileDialog::Detail) before calling exec().

An alternative is to call the static function QFileDialog::getOpenFileName() which will open a file dialog that is native to the OS on which you are running. Your users may like the familiarity of this option better.

Update 1:

About sort order in screen cap from OP: alt text

This screen capture is actually showing a sorted list. I don't know if the listing behaviour is originating from the Qt dialog or the underlying file system but I know Windows XP and later do it this way.

When sorting filenames with embedded numbers, any runs of consecutive digits are treated as a single number. With the more classic plain string sorting, files would be sorted like this:

A_A_10e0
A_A_9a05

Going character by character, the first 1 sorts before the 9.

.. But with numerical interpretation (as in Windows 7 at least), they are sorted as:

A_A_9a05
A_A_10e0

The 9 sorts before the 10.

So, the sorting you are seeing is alphabetical with numerical interpretation and not just straight character by character. Some deep digging may be required to see if that is Qt behaviour or OS behaviour and whether or not it can be configured.

Update 2:

The QSortFilterProxyModel will sort the strings alphabetically by default so there is not much work to using it to get the behavior you are looking for. Use the following code where you have "point x" in your example.. (you almost had it :)

QSortFilterProxyModel *sorter = new QSortFilterProxyModel();
sorter->setDynamicSortFilter(true); // This ensures the proxy will resort when the model changes
chooser.setProxyModel(sorter);
Arnold Spence
Possibly, this is the thing to do. We'll discuss it. Ideally, we'd like the dialog to pop up the way users want w/o having to click on anything at all.
DarenW
What version of Qt 4 are you using? I did see a bug mentioned for QFileDialog under linux that lead to file sorting based on name and extension. Can you show an example of the sort behavior you are seeing?
Arnold Spence
Qt4.3, i think. Multiple versions are installed to support a wide variety of software here. An example screen caputure: http://www.aoc.nrao.edu/~dwilson/temp/goofysort3.png
DarenW
Ah, I see now. I've edited my answer.
Arnold Spence
Well, that's interesting. Unfortunately for the designers of Qt, we experimental physicists and EEs like to use hexadecimal numbering.
DarenW
That will definitely cause a problem with sorting :) I'll look further into ways of customizing the sorting.
Arnold Spence
You were very close with the proxy model. See "Update 2" in my answer. That will give you the sorting you want.
Arnold Spence
Whoo! Tempted to try it now, but it's time to go home... tomorrow morning, first thing!
DarenW
Now it's "tomorrow morning"... the QSortFilterProxyModel code is in place. The app crashes! Screen cap of stack: http://www.aoc.nrao.edu/~dwilson/temp/crash_stack1.png (copy-paste won't work in this debugger) The highlighted line is the code I'm working on.
DarenW
Update: actually, it crashes only when I click in the left-side panel showing the short list of popular directories. It's okay if I navigate and select files in the main list. And these are actually sorted now! This is progress. We just need to figure out why a click on the left-side list crashes.
DarenW
I didn't experiment too much yesterday so I'll try my implementation later and see.
Arnold Spence
I don't experience a crash (on Windows). I tried to emulate your code by adding some of the things you do before calling exec() but I don't know what other things are going on in your subclass. These two lines are kinda odd, QStringList hist = chooser.history();chooser.setHistory(hist); but again, no crash. I'll see if I can test this on Linux tomorrow. Sorry the turnaround is so slow :)
Arnold Spence
I don't know much about that history stuff. I'll comment it out to see what happens. Arnold, thank you much for your effort so far - we've finally got the key problem solved about sorting! This crash might even be unrelated, just exposed somehow by the use of the new sorting code.
DarenW
If it's an option, you could try using just a straight QFileDialog instead of subclassing it and go from there. My test code did not use a subclass. If there's any more code related to the file dialog that you don't mind sharing, I'll be glad to try to help further. I learn a great deal about Qt by helping out on SO :)
Arnold Spence
DarenW
That seems pretty definitive unfortunately.
Arnold Spence
A: 

I don't think it depends upon the implementation of Qt libraries... But upon the Native OS implementation..

For example in Windows,

if you use QFileDialog, it will display the Files and Directories by Name sorted.. It is the same when used in other applications. In the sense that, if you try to open a file through MS- Word, it indeed displays the Files and directories as Name sorted by default..

And am not sure about other environments since am not used to them...

But in Windows, you can change the sorted order by right-click in the area of Files and Directories display and can select the options you like.. For e.g like Name,size,type, modified... And also which is similar, when you use an MS-Word application...

So, I believe it does depend on the Native OS implementation and not on QFileDialog's...

liaK
We're developing on linux + Mac only
DarenW