Package docking

# Class DockingUtils

java.lang.Object
docking.DockingUtils

public class DockingUtils extends Object

## Notes about how to use HTML safely:

Java's built-in HTML rendering in UI components is very useful, but can also introduce security issues when a hostile actor is providing the text strings that are being rendered.

Before using a native Java UI component, search for a corresponding 'G'hidra component, and if possible choose the non-HTML version of that component (if available).

For instance, instead of using `JLabel`, use either `GLabel` or `GHtmlLabel` (and their variants).

(native JLabel, JCheckbox, etc, usage is actually disallowed in the Ghidra project)

When using a UI component that is HTML enabled, care must be used when constructing the text that is being rendered.

During string-building or concatenation, appending a non-literal string value (ie. `"Hello " + getFoo();` ), the non-literal string value should be escaped using `HTMLUtilities.escapeHTML(String)` (ie. `"Hello " + HTMLUtilities.escapeHTML(getFoo());`.

Of course, there are exceptions to every rule, and if the string value can be definitely be traced to its source and there are no user-supplied origins, the HTML escaping can be skipped.

Note: just using a UI component that is HTML enabled does not mean that it will treat its text as HTML text. If you need to HTML escape any values that are being fed to the component, you need to force the HTML mode 'on' by pre-pending a "<HTML>" at the beginning of the string. If you fail to do this, the escaped substrings will look wrong because any '<' and '>' chars (and others) in the substring will be mangled when rendered in plain-text mode.

When working with plain text, try to avoid allowing a user supplied string being the first value of text that could be fed to a UI component. This will prevent the possibly hostile string from having a leading HTML start tag. (ie. when displaying an error to the user about a bad file, don't put the filename value at the start of the string, but instead put a quote or some other delimiter to prevent html mode).

### Recommended Ghidra UI Components:

Native Component | Recommended Component
--- | ---
`JLabel` | `GLabel` `GDLabel` `GHtmlLabel` `GDHtmlLabel` `GIconLabel`
`JCheckBox` | `GCheckBox` `GHtmlCheckBox`
`JComboBox` | `GComboBox` `GhidraComboBox`
`JList` | `GList`
`ListCellRenderer` `DefaultListCellRenderer` | `GListCellRenderer`
`TableCellRenderer` | `GTableCellRenderer`
`TreeCellRenderer` `DefaultTreeCellRenderer` | `GTreeRenderer` `DnDTreeCellRenderer`
`JRadioButton` | `GRadioButton`
`JButton` | ???tbd???

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Class
  Description
  `static interface`
  `DockingUtils.ComponentCallback<T extends Component>`
  A callback to operate on a component
  `static enum`
  `DockingUtils.TreeTraversalOrder`
  Specifies the order of component traversal
  `static enum`
  `DockingUtils.TreeTraversalResult`
  Controls traversal and communicates cause for termination

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `static final int`
  `CONTROL_KEY_MODIFIER_MASK`
  System dependent mask for the Ctrl key
  `static final int`
  `CONTROL_KEY_MODIFIER_MASK_DEPRECATED`
  Deprecated.
  use instead `CONTROL_KEY_MODIFIER_MASK`
  `static final String`
  `CONTROL_KEY_NAME`

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `DockingUtils()`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `static JSeparator`
  `createToolbarSeparator()`
  `static DockingUtils.TreeTraversalResult`
  `forAllDescendants(Container start, DockingUtils.ComponentCallback<Component> cb)`
  Perform some operation on a component and all of its descendents, recursively.
  `static <T extends Component>
  DockingUtils.TreeTraversalResult`
  `forAllDescendants(Container start, Class<T> type, DockingUtils.TreeTraversalOrder order, DockingUtils.ComponentCallback<T> cb)`
  Perform some operation on a component and all of its descendants, recursively This traverses the swing/awt component tree starting at the given container and descends recursively through all containers.
  `static void`
  `hideTipWindow()`
  Hides any open tooltip window
  `static UndoRedoKeeper`
  `installUndoRedo(JTextComponent textComponent)`
  Installs key binding support for undo/redo operations on the given text component.
  `static boolean`
  `isControlModifier(KeyEvent keyEvent)`
  Checks if the mouseEvent has the "control" key down.
  `static boolean`
  `isControlModifier(MouseEvent mouseEvent)`
  Checks if the mouseEvent has the "control" key down.
  `static boolean`
  `isTipWindowEnabled()`
  Returns true if application-wide Java tooltips are enabled.
  `static Icon`
  `scaleIconAsNeeded(Icon icon)`
  `static void`
  `setTipWindowEnabled(boolean enabled)`
  Sets the application-wide Java tooltip enablement.
  `static void`
  `setTransparent(JComponent c)`
  Sets the given component to transparent, which allows the parent component's background to be painted.

  ### Methods inherited from class java.lang.Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Field Details

  - ### CONTROL_KEY_MODIFIER_MASK

    public static final int CONTROL_KEY_MODIFIER_MASK
    System dependent mask for the Ctrl key

  - ### CONTROL_KEY_MODIFIER_MASK_DEPRECATED

    @Deprecated public static final int CONTROL_KEY_MODIFIER_MASK_DEPRECATED
    Deprecated.
    use instead `CONTROL_KEY_MODIFIER_MASK`
    A version the control key modifiers that is based upon the pre-Java 9 `InputEvent` usage. This mask is here for those clients that cannot be upgraded, such as those with dependencies on 3rd-party libraries that still use the old mask style.

  - ### CONTROL_KEY_NAME

    public static final String CONTROL_KEY_NAME

- ## Constructor Details

  - ### DockingUtils

    public DockingUtils()

- ## Method Details

  - ### createToolbarSeparator

    public static JSeparator createToolbarSeparator()

  - ### scaleIconAsNeeded

    public static Icon scaleIconAsNeeded(Icon icon)

  - ### isControlModifier

    public static boolean isControlModifier(MouseEvent mouseEvent)
    Checks if the mouseEvent has the "control" key down. On windows, this is actually the `control` key. On Mac, it is the `command` key.
    Parameters:
      `mouseEvent` - the event to check
    Returns:
      true if the control key is pressed

  - ### isControlModifier

    public static boolean isControlModifier(KeyEvent keyEvent)
    Checks if the mouseEvent has the "control" key down. On windows, this is actually the `control` key. On Mac, it is the `command` key.
    Parameters:
      `keyEvent` - the event to check
    Returns:
      true if the control key is pressed

  - ### installUndoRedo

    public static UndoRedoKeeper installUndoRedo(JTextComponent textComponent)
    Installs key binding support for undo/redo operations on the given text component.

    Note: the edits are tracked by adding a listener to the document of the given text component. If that document is changed, then undo/redo will stop working.

    Parameters:
      `textComponent` - the text component
    Returns:
      the object that allows the client to track the undo/redo state

  - ### forAllDescendants

    public static <T extends Component> DockingUtils.TreeTraversalResult forAllDescendants(Container start, Class<T> type, DockingUtils.TreeTraversalOrder order, DockingUtils.ComponentCallback<T> cb)
    Perform some operation on a component and all of its descendants, recursively This traverses the swing/awt component tree starting at the given container and descends recursively through all containers. Any time a component of type (or subclass of type) is found, the given callback is executed on it. If order is `DockingUtils.TreeTraversalOrder.CHILDREN_FIRST`, then the traversal will execute the callback on the children of a container before executing the callback on the container itself; if `DockingUtils.TreeTraversalOrder.PARENT_FIRST`, then the traversal will execute the callback on the container before descending. The callback must return one of three result values. In normal circumstances, it should return `DockingUtils.TreeTraversalResult.CONTINUE`, allowing traversal to continue to the next element. If the callback wishes to terminate traversal "successfully," e.g., because it needed to locate the first element satisfying some predicate, then it should return `DockingUtils.TreeTraversalResult.FINISH`. If an error occurs during traversal, then it should either return `DockingUtils.TreeTraversalResult.TERMINATE` or throw an appropriate exception to terminate traversal "unsuccessfully." This method will also return a value of `DockingUtils.TreeTraversalResult` indicating how traversal terminated. If `DockingUtils.TreeTraversalResult.CONTINUE`, then every element in the subtree was visited, and traversal was successful. If `DockingUtils.TreeTraversalResult.FINISH`, then some elements may have been omitted, but traversal was still successful. If `DockingUtils.TreeTraversalResult.TERMINATE`, then some elements may have been omitted, and traversal was not successful.
    Parameters:
      `start` - the "root" container of the subtree on which to operate
      `type` - the type of components on which to operate
      `order` - whether to operation on children or parents first
      `cb` - the callback to perform the actual operation
    Returns:
      a result indicating whether or not traversal completed successfully

  - ### forAllDescendants

    public static DockingUtils.TreeTraversalResult forAllDescendants(Container start, DockingUtils.ComponentCallback<Component> cb)
    Perform some operation on a component and all of its descendents, recursively. This applies the operation to all components in the tree, children first.
    Parameters:
      `start` - the "root" container of the subtree on which to operate
      `cb` - the callback to perform the actual operation
    Returns:
      a result indicating whether or not traversal completed successfully
    See Also:
      - `forAllDescendants(Container, Class, TreeTraversalOrder, ComponentCallback)`

  - ### setTransparent

    public static void setTransparent(JComponent c)
    Sets the given component to transparent, which allows the parent component's background to be painted.

    Notes Historically, to make a component transparent you would call `JComponent.setOpaque(boolean)` with a `false` value. However, it turns out that the definition and the implementation of this method are at odds. `setOpaque(false)` is meant to signal that some part of the component is transparent, so the parent component needs to be painted. Most LaFs implemented this by not painting the background of the component, but used the parent's color instead. The Nimbus LaF actually honors the contract of `setOpaque()`, which has the effect of painting the components background by default.

    This method allows components to achieve transparency when they used to rely on `setOpaque(false)`.

    Parameters:
      `c` - the component to be made transparent

  - ### setTipWindowEnabled

    public static void setTipWindowEnabled(boolean enabled)
    Sets the application-wide Java tooltip enablement.
    Parameters:
      `enabled` - true if enabled; false prevents all Java tooltips

  - ### isTipWindowEnabled

    public static boolean isTipWindowEnabled()
    Returns true if application-wide Java tooltips are enabled.
    Returns:
      true if application-wide Java tooltips are enabled.

  - ### hideTipWindow

    public static void hideTipWindow()
    Hides any open tooltip window