Native file dialog


#1

any kind of ballpark for when the linux port might get a support for a file requester dialog?

If I need to write an x-plat file requestor component, I will, but I’ll happily wait on that if the native linux dialog support is coming soonish. :wink:


#2

I don’t know what Jules’ plans are, but this is something I need myself for Twindy, so for the past week or so, I’ve been working on my own file view component (which I’ve named Phil) and file chooser. I’ve designed the chooser class to use the same method names as JUCE’ FileChooser, so it should work as a drop-in replacement.

Hopefully I’ll have it finished within this next week, although the code’s started to get a bit spaghetti-like, so I’ll probably have to refactor it a bit.

  • Niall.

#3

That looks really nice!

I’d love to do one, but am up to my ears in AudioUnits this week. Can’t really make any promises about when I’ll get round to it. Definitely one of my higher priorities though.


#4

Niall, that looks pretty cool.

If I can help in any way, let me know. A JUCE LAF filechooser is a good thing to have around irrespective of the availability of native choosers, as it simply looks better in a JUCE app. :slight_smile:

Jules, good to know. The task I need it for is currently being held back by the fact that I need to write a bitmap write function (trying to do an export function for DICOM images), so I’m not desperate.


#5

Okay, it’s just about ready for a first release, but I’ve come up against a few problems re linux:

[list]- With the File class, it’s impossible to get the top level directory - if I start in /home/niall, for example, I can get the parent directory (/home), but I can’t go any further than that. I want to be able to navigate to the various top level directories (particularly /mnt, /usr). I had a look at File::findFileSystemRoots(), but that only shows /, none of it’s child directories. I get the same behaviour on OSX.

  • I don’t know if this is specific to my system (demudi 1.2.1), but by default, JUCE always uses what I believe is Bitstream Vera Sans Mono, which doesn’t look nearly as nice as the non-monospaced version. Is there any way to set it to use Bitstream Vera Sans instead? There doesn’t seem to be a setDefaultJUCEFont() function anywhere, so at the moment I’m resorting to calling setFont() on those Components that have it, but that’s obviously not ideal, since for most Components, the only way to set the font is to either subclass them, or create a LookAndFeel subclass. (in case you hadn’t guessed, the screenshot above is from windows, hence the non-monospaced fonts :wink:)[/list]
  • Niall.

#6

[quote=“NiallM”]Okay, it’s just about ready for a first release, but I’ve come up against a few problems re linux:

[list]- With the File class, it’s impossible to get the top level directory - if I start in /home/niall, for example, I can get the parent directory (/home), but I can’t go any further than that. I want to be able to navigate to the various top level directories (particularly /mnt, /usr). I had a look at File::findFileSystemRoots(), but that only shows /, none of it’s child directories. I get the same behaviour on OSX.[/quote]

I might not be understanding you but I think you are trying to treat / as a directory, which IIRC JUCE treats as a drive. I’ll need to look at my code - I did this stuff a few weeks back and I was trying to learn five things at once so I don’t fully trust my memory.

Here are a couple of screen shots, one being linux, and the other windows of the treeview code I wrote for a demo app I developed to sell JUCE to my boss.

Both are using the same code, but linux acts as though ‘/’ is a (the only) drive, where windows has the usual complement of c:, d: etc.


#7

hey niall, gr8 stuff ! when we can see this ?


#8

Hmm… You’re probably right, but how do you get the names of the top level directories? When I do File::findFileSystemRoots(), I just get a single File::nonexistent returned, so I can’t interrogate it to get it’s children, and I can’t see any other way to do it :?:

As soon as I’ve got this sorted out (and hopefully my monospaced fonts problem), and added a command-line switch to the file browser, so it’ll take on the colour scheme of my twindy window manager if it’s installed.

  • Niall.

#9

[quote=“NiallM”]
Hmm… You’re probably right, but how do you get the names of the top level directories? When I do File::findFileSystemRoots(), I just get a single File::nonexistent returned, so I can’t interrogate it to get it’s children, and I can’t see any other way to do it :?:.[/quote]

Looking briefly at my code, it seems I ran into a similar problem. It makes sense when you think about it, because the dos drive is C: not C:\ - the slash is the root path. As such the linux drive is actually an empty string with a rootpath slash appended.

I did something like:

OwnedArray<File>driveList;
File::findFileSystemRoots(driveList);
String driveName;
for (int i = 0; i < driveList.size(); i++)
{	
    driveName = driveList.operator[](i)->getFullPathName();
    // since the drive has no trailing slash, add one to get a valid path.
    if (driveName.length() == 0) driveName = File::separatorString;
    // do something useful with driveName
}

That may well not be the right way of doing things, but it got me out of trouble.

HTH.

(edited - I’m not sure about the “if (driveName.length() == 0)” I’m thinking I needed to do that in all cases (ie mac, linux, and win), but I can’t tell because I added sanity checks on other functions that cover dos drives not having a trailing slash).


#10

Ok, the reason is that the File object always stores its path without a trailing “/” character, so the root directory “/” will get stored as an empty string. This all works on the mac, but comparing the mac and linux code I see there’s a small tweak I’ve obviously added to the mac to make it work.

I’ll fix this next version, but in the meantime, here’s what to add to juce_linux_Files.cpp:

bool juce_fileExists (const String& fileName, const bool dontCountDirectories)
{
    if (fileName.isEmpty())
        return ! dontCountDirectories;

    bool exists = access ((const char*) fileName, F_OK) == 0;

    if (exists && dontCountDirectories && juce_isDirectory (fileName))
        exists = false;

    return exists;
}

It raises an interesting question though, because File::nonexistent is also an empty string, so effectively File ("/") == File::nonexistent, which is wrong. Ideas…?


#11

I’m not sure I see the problem.

fileExists("/", false) returns true, and fileExists("/", true) returns false, right?

cos that all seems logical enough to me. :?


#12

Yes, but fileExists ("/") won’t get called directly - if File("/") calls it, it’ll actually pass in an empty string.


#13

Okay, thanks guys, I can navigate to the top directories now :). I’ve also discovered what my font problem was - I didn’t have the msttcorefonts package installed. It looks like JUCE relies on these if you want a nice sans font. I don’t know about other distros, but these aren’t installed by default on debian, because they’re not entirely free. Is there any chance of having a different fallback font to the current monospaced one?

  • Niall.

#14

jules:

ahh, I see what you mean.

to fix what you are describing, parseAbsolutePath() could be modified to go gently on trailing slashes if the path length is just one character.

This would of course mean that root ‘/’ is treated differently to any other linux path, and of course differently to windows drives, but including trailing path delimiters in all path names would break far too much existing code I imagine.

I can’t think of an elegant solution right now. :frowning:


#15

:oops: Doh! I just discovered the Font::setDefaultSansSerifFontName() method which lets you set a different default font, so it doesn’t really matter. I’ll just make sure to set it to Bitstream Vera Sans for my linux apps from now on. Seems I keep discovering new things in JUCE…

  • Niall.

#16