<commit_before>/*
 *
 * Copyright (c) 2020 by vassalengine.org, <NAME>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License (LGPL) as published by the Free Software Foundation.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, copies are available
 * at http://www.opensource.org.
 */
package VASSAL.build;

import VASSAL.build.module.GameComponent;
import VASSAL.build.module.Map;
import VASSAL.build.module.properties.MutableProperty;
import VASSAL.command.Command;
import VASSAL.configure.AutoConfigurer;
import VASSAL.configure.Configurer;
import VASSAL.configure.ConfigurerFactory;
import VASSAL.configure.IconConfigurer;
import VASSAL.configure.NamedHotKeyConfigurer;
import VASSAL.configure.VisibilityCondition;
import VASSAL.i18n.Resources;
import VASSAL.tools.LaunchButton;
import VASSAL.tools.NamedKeyStroke;

import java.awt.Component;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * Creates an item that is both configurable w/ an edit box {@link AbstractConfigurable} and buildable from the
 * XML buildFile {@link AbstractBuildable}, but which also has a Toolbar launch button.
 */
public abstract class AbstractToolbarItem extends AbstractConfigurable implements GameComponent, PropertyChangeListener {

  // These are the "standard keys" - recommended for all new classes extending AbstractToolbarItem
  public static final String NAME          = "name";    //$NON-NLS-1$
  public static final String TOOLTIP       = "tooltip"; //$NON-NLS-1$
  public static final String BUTTON_TEXT   = "text";    //$NON-NLS-1$
  public static final String HOTKEY        = "hotkey";  //$NON-NLS-1$
  public static final String ICON          = "icon";    //$NON-NLS-1$
  public static final String CAN_DISABLE   = "canDisable";   //NON-NLS
  public static final String PROPERTY_GATE = "propertyGate"; //NON-NLS
  public static final String DISABLED_ICON = "disabledIcon"; //NON-NLS

  protected LaunchButton launch;              // Our toolbar "launch button"

  protected IconConfigurer disabledIconConfig = new IconConfigurer(DISABLED_ICON, null, null);

  protected boolean showDisabledOptions = true; // True if our configurers are allowed to show the disable-this-button properties
  protected boolean canDisable = false;         // True if we have a disable-this-button property
  protected String propertyGate = "";           // Name of our gating property (button is disabled if this global property is "true")
  protected MutableProperty.Impl property;

  private String nameKey       = NAME;        // Some legacy objects will want to use a non-standard key (or none)
  private String tooltipKey    = TOOLTIP;     // Some legacy objects will want to use a non-standard key
  private String buttonTextKey = BUTTON_TEXT; // Some legacy objects will want to use a non-standard key
  private String hotKeyKey     = HOTKEY;      // Some legacy objects will want to use a non-standard key
  private String iconKey       = ICON;        // Some legacy objects will want to use a non-standard key

  private String namePrompt = ""; // Overrides the default value returned for the name key by getAttributeDescriptions.

  protected void setNamePrompt(String namePrompt) {
    this.namePrompt = namePrompt;
  }

  protected void setNameKey(String nameKey) {
    this.nameKey = nameKey;
  }

  protected void setTooltipKey(String tooltipKey) {
    this.tooltipKey = tooltipKey;
  }

  protected void setButtonTextKey(String buttonTextKey) {
    this.buttonTextKey = buttonTextKey;
  }

  protected void setHotKeyKey(String hotKeyKey) {
    this.hotKeyKey = hotKeyKey;
  }

  protected void setIconKey(String iconKey) {
    this.iconKey = iconKey;
  }

  protected void setShowDisabledOptions(boolean show) {
    showDisabledOptions = show;
  }

  public boolean isShowDisabledOptions() {
    return showDisabledOptions;
  }

  /**
   * Create a standard toolbar launcher button for this item
   *
   * @param tooltip String tooltip for button
   * @param button_text Text for button
   * @param iconFile filename for icon default
   * @param action  Action Listener when launch button is clicked
   * @return launch button
   */
  protected LaunchButton makeLaunchButton(String tooltip, String button_text, String iconFile, ActionListener action) {
    launch = new LaunchButton(button_text, tooltipKey, buttonTextKey, hotKeyKey, iconKey, action);
    if (!tooltip.isEmpty()) {
      setAttribute(tooltipKey, tooltip);
    }
    if (!button_text.isEmpty()) {
      if (!nameKey.isEmpty()) {
        setAttribute(nameKey, button_text);
      }
      launch.setAttribute(buttonTextKey, button_text);
    }
    if (!iconFile.isEmpty()) {
      setAttribute(iconKey, iconFile);
    }

    launch.setDisabledIcon(disabledIconConfig.getIconValue());

    checkDisabled();

    return launch;
  }

  /**
   * @return Launch button for this Toolbar item.
   */
  public LaunchButton getLaunchButton() {
    return launch;
  }

  /**
   * Sets launch button for this toolbar item
   * @param launch - launch button
   */
  protected void setLaunchButton(LaunchButton launch) {
    this.launch = launch;
  }

  /**
   * If we have a disable-this-button property, set a listener on it
   */
  protected void addPropertyGateListener() {
    if (property != null) {
      removePropertyGateListener();
    }

    if (isShowDisabledOptions() && canDisable) {
      if (!propertyGate.isEmpty()) {
        final Buildable ancestor = getNonFolderAncestor();
        property = (ancestor instanceof Map) ? (MutableProperty.Impl) ((Map)ancestor).getMutableProperty(propertyGate) : null;
        if (property == null) {
          property = (MutableProperty.Impl) GameModule.getGameModule().getMutableProperty(propertyGate);
        }
        if (property != null) {
          property.addMutablePropertyChangeListener(this);
        }
      }
    }
  }
<commit_msg>Disabled Toolbar Buttons on Map Windows didn't initialize starting state properly<commit_after>/*
 *
 * Copyright (c) 2020 by vassalengine.org, <NAME>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License (LGPL) as published by the Free Software Foundation.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, copies are available
 * at http://www.opensource.org.
 */
package VASSAL.build;

import VASSAL.build.module.GameComponent;
import VASSAL.build.module.Map;
import VASSAL.build.module.properties.MutableProperty;
import VASSAL.command.Command;
import VASSAL.configure.AutoConfigurer;
import VASSAL.configure.Configurer;
import VASSAL.configure.ConfigurerFactory;
import VASSAL.configure.IconConfigurer;
import VASSAL.configure.NamedHotKeyConfigurer;
import VASSAL.configure.VisibilityCondition;
import VASSAL.i18n.Resources;
import VASSAL.tools.LaunchButton;
import VASSAL.tools.NamedKeyStroke;

import java.awt.Component;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * Creates an item that is both configurable w/ an edit box {@link AbstractConfigurable} and buildable from the
 * XML buildFile {@link AbstractBuildable}, but which also has a Toolbar launch button.
 */
public abstract class AbstractToolbarItem extends AbstractConfigurable implements GameComponent, PropertyChangeListener {

  // These are the "standard keys" - recommended for all new classes extending AbstractToolbarItem
  public static final String NAME          = "name";    //$NON-NLS-1$
  public static final String TOOLTIP       = "tooltip"; //$NON-NLS-1$
  public static final String BUTTON_TEXT   = "text";    //$NON-NLS-1$
  public static final String HOTKEY        = "hotkey";  //$NON-NLS-1$
  public static final String ICON          = "icon";    //$NON-NLS-1$
  public static final String CAN_DISABLE   = "canDisable";   //NON-NLS
  public static final String PROPERTY_GATE = "propertyGate"; //NON-NLS
  public static final String DISABLED_ICON = "disabledIcon"; //NON-NLS

  protected LaunchButton launch;              // Our toolbar "launch button"

  protected IconConfigurer disabledIconConfig = new IconConfigurer(DISABLED_ICON, null, null);

  protected boolean showDisabledOptions = true; // True if our configurers are allowed to show the disable-this-button properties
  protected boolean canDisable = false;         // True if we have a disable-this-button property
  protected String propertyGate = "";           // Name of our gating property (button is disabled if this global property is "true")
  protected MutableProperty.Impl property;

  private String nameKey       = NAME;        // Some legacy objects will want to use a non-standard key (or none)
  private String tooltipKey    = TOOLTIP;     // Some legacy objects will want to use a non-standard key
  private String buttonTextKey = BUTTON_TEXT; // Some legacy objects will want to use a non-standard key
  private String hotKeyKey     = HOTKEY;      // Some legacy objects will want to use a non-standard key
  private String iconKey       = ICON;        // Some legacy objects will want to use a non-standard key

  private String namePrompt = ""; // Overrides the default value returned for the name key by getAttributeDescriptions.

  protected void setNamePrompt(String namePrompt) {
    this.namePrompt = namePrompt;
  }

  protected void setNameKey(String nameKey) {
    this.nameKey = nameKey;
  }

  protected void setTooltipKey(String tooltipKey) {
    this.tooltipKey = tooltipKey;
  }

  protected void setButtonTextKey(String buttonTextKey) {
    this.buttonTextKey = buttonTextKey;
  }

  protected void setHotKeyKey(String hotKeyKey) {
    this.hotKeyKey = hotKeyKey;
  }

  protected void setIconKey(String iconKey) {
    this.iconKey = iconKey;
  }

  protected void setShowDisabledOptions(boolean show) {
    showDisabledOptions = show;
  }

  public boolean isShowDisabledOptions() {
    return showDisabledOptions;
  }

  /**
   * Create a standard toolbar launcher button for this item
   *
   * @param tooltip String tooltip for button
   * @param button_text Text for button
   * @param iconFile filename for icon default
   * @param action  Action Listener when launch button is clicked
   * @return launch button
   */
  protected LaunchButton makeLaunchButton(String tooltip, String button_text, String iconFile, ActionListener action) {
    launch = new LaunchButton(button_text, tooltipKey, buttonTextKey, hotKeyKey, iconKey, action);
    if (!tooltip.isEmpty()) {
      setAttribute(tooltipKey, tooltip);
    }
    if (!button_text.isEmpty()) {
      if (!nameKey.isEmpty()) {
        setAttribute(nameKey, button_text);
      }
      launch.setAttribute(buttonTextKey, button_text);
    }
    if (!iconFile.isEmpty()) {
      setAttribute(iconKey, iconFile);
    }

    launch.setDisabledIcon(disabledIconConfig.getIconValue());

    checkDisabled();

    return launch;
  }

  /**
   * @return Launch button for this Toolbar item.
   */
  public LaunchButton getLaunchButton() {
    return launch;
  }

  /**
   * Sets launch button for this toolbar item
   * @param launch - launch button
   */
  protected void setLaunchButton(LaunchButton launch) {
    this.launch = launch;
  }

  /**
   * If we have a disable-this-button property, set a listener on it
   */
  protected void addPropertyGateListener() {
    if (property != null) {
      removePropertyGateListener();
    }

    if (isShowDisabledOptions() && canDisable) {
      if (!propertyGate.isEmpty()) {
        final Buildable ancestor = getNonFolderAncestor();
        property = (ancestor instanceof Map) ? (MutableProperty.Impl) ((Map)ancestor).getMutableProperty(propertyGate) : null;
        if (property == null) {
          property = (MutableProperty.Impl) GameModule.getGameModule().getMutableProperty(propertyGate);
        }
        if (property != null) {
          property.addMutablePropertyChangeListener(this);
        }
      }
    }

    checkDisabled();
  }

{'fraction_non_alphanumeric': 0.08325624421831637, 'fraction_numerical': 0.0016959605303731114, 'mean_word_length': 3.5599297012302284, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2559968', 'n_tokens_mistral': 3579, 'n_tokens_neox': 3500, 'n_words': 1195}