SettingsWindow::SettingsWindow(const String &          title,
                               const String &          execType,
                               const ApplicationInfo & appInfo,
                               String &                endpointToUse,
                               String &                tagToUse,
                               String &                portToUse,
                               int &                   tagModifierCount,
                               StringArray &           argsToUse)  :
    inherited1(), inherited2(), inherited3(title, kWindowBackgroundColour, 0), inherited4(),
    _topText("topText"), _cancelButton("Cancel"), _okButton("OK"),
    _descriptors(appInfo._argDescriptions),
    _errorFont(Font::getDefaultMonospacedFontName(), FormField::kFontSize,
               Font::italic + Font::bold), _regularFont(Font::getDefaultMonospacedFontName(),
                                                        FormField::kFontSize, Font::plain),
    _execType(execType), _extraArgumentsGroup(NULL), _tagModifierGroup(NULL),
    _addArgumentsButton(NULL), _removeArgumentsButton(NULL), _endpointField(NULL), _portField(NULL),
    _tagField(NULL),
    _endpointDescriptor(new Utilities::ChannelArgumentDescriptor(kEndpointFieldName.toStdString(),
                                                                 "", Utilities::kArgModeOptional,
                                                                 "")),
    _portDescriptor(new Utilities::PortArgumentDescriptor(kPortFieldName.toStdString(), "",
                                                          Utilities::kArgModeOptional, 0, false)),
    _appInfo(appInfo), _endpointToUse(endpointToUse), _portToUse(portToUse), _tagToUse(tagToUse),
    _argsToUse(argsToUse), _tagModifierCount(tagModifierCount), _canSetEndpoint(false),
    _canSetPort(false), _canSetTag(false), _canUseModifier(false), _hasExtraArguments(false),
    _hasFileField(false)
{
    ODL_ENTER(); //####
    ODL_S2s("title = ", title.toStdString(), "execType = ", execType.toStdString()); //####
    ODL_P4("appInfo = ", &appInfo, "endpointToUse = ", &endpointToUse, "tagToUse = ", //####
           &tagToUse, "portToUse = ", &portToUse); //####
    ODL_P1("argsToUse = ", &argsToUse); //####
    _contentArea.setSize(100, 100);
    setContentNonOwned(&_contentArea, true);
    BorderSize<int> bt = getBorderThickness();
    BorderSize<int> cb = getContentComponentBorder();
    int             heightSoFar = 0;
    int             widthSoFar = 0;

    _argsToUse.clear();
    _canSetEndpoint = appInfo._options.contains("e");
    _canSetPort = appInfo._options.contains("p");
    _canSetTag = appInfo._options.contains("t");
    _canUseModifier = appInfo._options.contains("m");
    setUpStandardFields(widthSoFar, heightSoFar);
    int minW = jmax(widthSoFar, _cancelButton.getWidth() + _okButton.getWidth() +
                    (3 * FormField::kButtonGap));
    int calcW = minW + bt.getLeftAndRight() + cb.getLeftAndRight();
    int calcH = heightSoFar + bt.getTopAndBottom() + cb.getTopAndBottom();

    centreWithSize(calcW + kExtraSpaceInWindow, calcH + kExtraSpaceInWindow);
    adjustFields();
    setOpaque(true);
    setResizable(false, false);
    setVisible(true);
    addKeyListener(CommonVisuals::GetApplicationCommandManager().getKeyMappings());
    triggerAsyncUpdate();
    ODL_EXIT_P(this); //####
} // SettingsWindow::SettingsWindow
void
SettingsWindow::recalculateArea(void)
{
    ODL_ENTER(); //####
    int    heightSoFar = _topText.getY() + _topText.getHeight() + FormField::kButtonGap;
    int    widthSoFar = _topText.getX() + _topText.getWidth();
    size_t numExtra = _extraFields.size();

    if (_canSetEndpoint)
    {
        widthSoFar = jmax(widthSoFar, _endpointField->getMinimumWidth());
        heightSoFar = (_endpointField->getY() + _endpointField->getHeight() +
                       (FormField::kButtonGap / 2));
    }
    if (_canSetPort)
    {
        widthSoFar = jmax(widthSoFar, _portField->getMinimumWidth());
        heightSoFar = _portField->getY() + _portField->getHeight() + (FormField::kButtonGap / 2);
    }
    if (_canSetTag)
    {
        widthSoFar = jmax(widthSoFar, _tagField->getMinimumWidth());
        heightSoFar = _tagField->getY() + _tagField->getHeight() + (FormField::kButtonGap / 2);
    }
    if (_canUseModifier && _tagModifierGroup)
    {
        //int innerHeight = static_cast<int>(_regularFont.getHeight()) +
        //                                   (FormField::kButtonGap / 2);
        //int innerWidth = (2 * jmax(FormField::kFieldInset, FormField::kLabelInset));

        _tagModifierGroup->setTopLeftPosition(FormField::kFieldInset, heightSoFar);
        heightSoFar = _tagModifierGroup->getY() + _tagModifierGroup->getHeight();
        widthSoFar = jmax(widthSoFar, _tagModifierGroup->getX() + _tagModifierGroup->getWidth());
    }
    for (size_t ii = 0, numDescriptors = _descriptors.size(), jj = 0; numDescriptors > ii; ++ii)
    {
        Utilities::BaseArgumentDescriptor * aDescriptor = _descriptors[ii];

        if (aDescriptor)
        {
            String argName(aDescriptor->argumentName().c_str());
            String argDescription(aDescriptor->argumentDescription().c_str());

            if (! aDescriptor->isExtra())
            {
                FormField * aField = _standardFields[static_cast<int>(jj)];

                if (aField)
                {
                    widthSoFar = jmax(widthSoFar, aField->getMinimumWidth());
                    heightSoFar = (aField->getY() + aField->getHeight() +
                                   (FormField::kButtonGap / 2));
                    ++jj;
                }
            }
        }
    }
    if (_extraArgumentsGroup)
    {
        int innerHeight = static_cast<int>(_regularFont.getHeight()) + (FormField::kButtonGap / 2);
        int innerWidth = (2 * jmax(FormField::kFieldInset, FormField::kLabelInset));

        _extraArgumentsGroup->setTopLeftPosition(FormField::kFieldInset, heightSoFar);
        for (size_t ii = 0; numExtra > ii; ++ii)
        {
            FormField * aField = _extraFields[static_cast<int>(ii)];

            aField->setY(innerHeight);
            innerHeight = aField->getY() + aField->getHeight() + (FormField::kButtonGap / 2);
        }
        if (0 < numExtra)
        {
            innerHeight += (3 * FormField::kButtonGap / 4);
        }
        else
        {
            innerHeight += (FormField::kButtonGap / 2);
        }
        _extraArgumentsGroup->setSize(innerWidth, innerHeight);
        heightSoFar = _extraArgumentsGroup->getY() + _extraArgumentsGroup->getHeight();
        widthSoFar = jmax(widthSoFar, _extraArgumentsGroup->getX() +
                          _extraArgumentsGroup->getWidth());
    }
    BorderSize<int> cb = getContentComponentBorder();
    int             minW = jmax(widthSoFar, _cancelButton.getWidth() + _okButton.getWidth() +
                                (3 * FormField::kButtonGap));

    setContentComponentSize(minW + kExtraSpaceInWindow + cb.getLeftAndRight(),
                            heightSoFar + kExtraSpaceInWindow + cb.getTopAndBottom());
    ODL_EXIT(); //####
} // SettingsWindow::recalculateArea