First Menu Bar Item Disappears When FileChooser is Invoked

Hi all,

I'm having some strange behaviour (doubtless my fault) with the menu bar and FileChooser. Whenever I choose an option on the menu that invokes a FileChooser,  the first menu bar item disappears (I have tried invoking it from a different menu bar item and it is always the first item that disappears).

To make this clear, I'll reiterate. Before invoking things, I have a menu containing two drop downs

File, Edit

I choose File->Load

which invokes a static method in another class containing...

    FileChooser myChooser ("Please select a file to open",
                               File::getSpecialLocation (File::userHomeDirectory),
                               "*.arr");

    if (myChooser.browseForFileToOpen())
    {
       // do things with the file browser <-- even with just this comment I get the problem
    }
    else
    {

        return false;
    }

Then, while the FileChooser is open (i.e. before I select a file and click 'ok'), the menu bar displays...

Edit 

(i.e. the "File" item disappears.)

 

Here are my command Ids:

enum CommandIDs
{
    newArrangement              = 0x2000,
    save                        = 0x2001,
    saveAs                      = 0x2002,
    load                        = 0x2003
};

Here are the methods I implement when inheriting MenuBarModel:


//==============================================
PopupMenu MyComponent::getMenuForIndex (int topLevelMenuIndex, const String& menuName)
{
    ApplicationCommandManager* commandManager = &(mainWindow.commandManager);
    
    PopupMenu menu;
    
    if (topLevelMenuIndex == 0)
    {        
        menu.addCommandItem(commandManager, newArrangement);
        menu.addCommandItem(commandManager, save);
        menu.addCommandItem(commandManager, saveAs);
        menu.addCommandItem(commandManager, load);
        menu.addSeparator();
        menu.addCommandItem (commandManager, StandardApplicationCommandIDs::quit);
    }
    else if (topLevelMenuIndex == 1)
    {
        menu.addSeparator();
    }
    
    return menu;
}

//==============================================
StringArray MyComponent::getMenuBarNames()
{
    StringArray menuBarNames;

    const char* const names[] = { "File", "Edit", nullptr };

    return StringArray (names);
}


//==============================================
void MyComponent::menuItemSelected (int menuItemID, int topLevelMenuIndex)
{
    
}

And these are the methods inherited from ApplicationCommandTarget:

//==============================================
ApplicationCommandTarget* MyComponent::getNextCommandTarget()
{
    return findFirstTargetParentComponent();
}


//==============================================
void MyComponent::getAllCommands (Array <CommandID>& commands)
{
    // this returns the set of all commands that this target can perform..
    const CommandID ids[] = {
        newArrangement,
        save,
        saveAs,
        load
    };
    
    commands.addArray (ids, numElementsInArray (ids));
}


//==============================================
bool MyComponent::perform (const InvocationInfo& info)
{    
    switch (info.commandID)
    {
        case newArrangement:
        {
            ((MyApplication*) JUCEApplication::getInstance())->createNewEmptySession();
            break;
        }
            
        case save:
        {
            FileIO::save(applicationTree);
            break;
        }
            
        case saveAs:
        {
            FileIO::saveAs(applicationTree);
            break;
        }
            
        case load:
        {
            ValueTree newApplicationTree;
            FileIO::load(newApplicationTree);

            ((MyApplication*) JUCEApplication::getInstance())->createNewSessionWithTree(newApplicationTree);
            break;
        }
            
        default:
        {
            return false;
        }
    };
    
    return true;
}


//==============================================
void MyComponent::getCommandInfo (CommandID commandID, ApplicationCommandInfo& result)
{    
    switch (commandID)
    {
        case newArrangement:
            result.setInfo("New Arrangement", "Start a new Arrangement", "Category 1",  0);
            result.setTicked (false);
            result.setActive(true);
            result.addDefaultKeypress ('g', ModifierKeys::commandModifier);
            break;
            
        case save:
            result.setInfo("Save", "Save the current arrangement", "Category 1", 0);
            result.setTicked(false);
            result.setActive(true);
            result.addDefaultKeypress('s', ModifierKeys::commandModifier);
            break;
            
        case saveAs:
            result.setInfo("Save As...", "Save the current arrangement", "Category 1", 0);
            result.setTicked(false);
            result.setActive(true);
            result.addDefaultKeypress('u', ModifierKeys::commandModifier);
            break;
            
        case load:
            result.setInfo("Load", "Load a new arrangement", "Category 1", 0);
            result.setTicked(false);
            result.setActive(true);
            result.addDefaultKeypress('o', ModifierKeys::commandModifier);
            break;
            
        default:
            break;
    }
    
}

 

Thanks in advance for any help!

Adam

No.. That's deliberate. But you're mis-interpreting what's going on. It's not removing your first menu item, it's removing your entire menu bar, and replacing it with just a temporary "Edit" menu while the file-chooser is open.

This stops people doing irritating things like quitting the app or invoking other commands while the chooser's open, which can cause horrible recursion problems.

There seems to be an issue here now (Juce 5.2.0 on OS X 10.12.6). Every time I open up a file chooser I get another edit on the menu bar. It just keeps piling them up from left to right. Note that I am not specifically creating any menu for my app.

This has already been fixed on the develop branch.

Are you sure this fix was checked in? Updated to develop and same issue is occuring.

Can you reproduce it in the Dialogs section of the JUCE demo? With the master branch I can trigger the stacking “Edit” items by clicking on the Choose Directory File Browser, but on the develop branch the issue is fixed - the dialogs code has changed quite a lot since the last JUCE release.

Fixed here.

Edit: forgot to include the link

I agree in the demo it is fixed. In fact the “edit” option never even appears in the demo when I bring up the FileChooser. However, the demo is using:
fc = new FileChooser (…
fc->launchAsync (…

and I am using:
FileChooser myChooser (“Select File”,…
(myChooser.browseForFileToOpen() …

is browseForFileToOpen and browseForDirectory not the correct way to use these anymore?

You can use either.

I didn’t realise that this issue only appeared when the dialog was opened modally and Fabian’s commit fixes things.

Fixed.

Thanks.