GT-2698 refactor html enable/disable helper methods.

Also fix data type preview / tooltip html escaping of comment string.
This commit is contained in:
dev747368 2019-04-29 14:10:20 -04:00
parent eeea912c4d
commit a924662af7
13 changed files with 89 additions and 69 deletions

View File

@ -127,6 +127,14 @@ public abstract class HTMLDataTypeRepresentation {
return buffer;
}
/**
* Returns the plain-text value of the data type's description.
* <p>
* If there were html tags in the string, they are escaped.
*
* @param dataType the type to get the description / comment for
* @return plain-text string, w/html escaped
*/
protected static String getCommentForDataType(DataType dataType) {
String comment = null;
if (dataType instanceof DataTypeComponent) {
@ -153,18 +161,20 @@ public abstract class HTMLDataTypeRepresentation {
return string;
}
/**
* Formats a multi-line plain-text comment string into a HTML string where the text has been
* wrapped at MAX_LINE_LENGTH.
*
* @param string plain-text string
* @return list of html strings
*/
private static List<String> breakCommentAsNecessary(String string) {
boolean isCommentAlreadyHTML = HTMLUtilities.isHTML(string);
List<String> list = new ArrayList<>();
for (String nativeCommentLine : string.split("\n")) {
List<String> wrappedLines = breakLongLineAtWordBoundaries(nativeCommentLine,
MAX_LINE_LENGTH - MIDDLE_COMMENT.length());
for (int i = 0; i < wrappedLines.size(); i++) {
String wrappedLine = wrappedLines.get(i);
if (!isCommentAlreadyHTML) {
wrappedLine = HTMLUtilities.friendlyEncodeHTML(wrappedLine);
}
list.add(MIDDLE_COMMENT + wrappedLine + BR);
}
}
@ -187,7 +197,7 @@ public abstract class HTMLDataTypeRepresentation {
/* package */ static List<String> breakLongLineAtWordBoundaries(String lineStr,
int maxLineLen) {
List<String> result = new ArrayList<>();
StringBuffer lineBuffer = new StringBuffer();
StringBuilder lineBuffer = new StringBuilder();
StringTokenizer tokenizer = new StringTokenizer(lineStr, CHARACTER_SPACE, true);
while (tokenizer.hasMoreTokens()) {
@ -226,10 +236,16 @@ public abstract class HTMLDataTypeRepresentation {
return HTMLUtilities.colorString(color, string);
}
/**
* Formats a multi-line plain-text comment as a list of HTML marked-up lines.
*
* @param comment multi-line plain-text string
* @param maxLines max number of formatted lines to return
* @return list of html marked-up {@link TextLine}s
*/
protected static List<TextLine> createCommentLines(String comment, int maxLines) {
List<TextLine> newList = new ArrayList<>();
if (comment == null || comment.length() == 0) {
return newList;
return Collections.emptyList();
}
List<String> commentLines = breakCommentAsNecessary(comment);
@ -241,6 +257,7 @@ public abstract class HTMLDataTypeRepresentation {
" lines ommitted...</i>" + BR);
}
List<TextLine> newList = new ArrayList<>();
newList.add(new TextLine(START_COMMENT));
for (String commentLine : commentLines) {
newList.add(new TextLine(commentLine));
@ -335,10 +352,7 @@ public abstract class HTMLDataTypeRepresentation {
protected TextLine buildFooterText(DataType dataType) {
int length = dataType.getLength();
if (length >= 0) {
return new TextLine(Integer.toString(length));
}
return new TextLine(" <i>Unsized</i>");
return new TextLine((length >= 0) ? Integer.toString(length) : " <i>Unsized</i>");
}
//==================================================================================================

View File

@ -23,11 +23,11 @@ import javax.swing.KeyStroke;
import docking.menu.DockingMenuItemUI;
import docking.widgets.GComponent;
public class DockingMenuItem extends JMenuItem {
public class DockingMenuItem extends JMenuItem implements GComponent {
public DockingMenuItem() {
setUI(DockingMenuItemUI.createUI(this));
GComponent.turnOffHTMLRendering(this);
setHTMLRenderingEnabled(false);
}
@Override

View File

@ -73,17 +73,6 @@ public abstract class AbstractGCellRenderer extends GDHtmlLabel {
setOpaque(true); // mimic the default table & list cell renderer
}
/**
* Enables and disables the rendering of HTML content in this renderer. If enabled, this
* renderer will interpret HTML content when the text this renderer is showing begins with
* <tt>&lt;html&gt;</tt>
*
* @param enable true to enable HTML rendering; false to disable it
*/
public void setHTMLRenderingEnabled(boolean enable) {
putClientProperty(GComponent.HTML_DISABLE_STRING, !enable);
}
public void setShouldAlternateRowBackgroundColors(boolean alternate) {
this.instanceAlternateRowColors = alternate;
}

View File

@ -27,6 +27,7 @@ import javax.swing.event.*;
import org.apache.commons.lang3.StringUtils;
import docking.widgets.label.GDHtmlLabel;
import docking.widgets.list.GList;
import generic.util.WindowUtilities;
import ghidra.util.StringUtilities;
import ghidra.util.SystemUtilities;
@ -57,7 +58,7 @@ import util.CollectionUtils;
*
* @param <T> The type of object that this model manipulates
*/
public class DropDownTextField<T> extends JTextField {
public class DropDownTextField<T> extends JTextField implements GComponent {
private static final int DEFAULT_MAX_UPDATE_DELAY = 2000;
private static final int MIN_HEIGHT = 300;
@ -69,8 +70,8 @@ public class DropDownTextField<T> extends JTextField {
private DropDownWindowVisibilityListener<T> windowVisibilityListener =
new DropDownWindowVisibilityListener<>();
private JLabel previewLabel;
protected JList<T> list = new JList<>();
private GDHtmlLabel previewLabel;
protected GList<T> list = new GList<>();
private WeakSet<DropDownSelectionChoiceListener<T>> choiceListeners =
WeakDataStructureFactory.createSingleThreadAccessWeakSet();
private Collection<CellEditorListener> cellEditorListeners = new HashSet<>();
@ -131,7 +132,6 @@ public class DropDownTextField<T> extends JTextField {
}
private void init(int updateMinDelay) {
GComponent.turnOffHTMLRendering(list);
updateManager = new SwingUpdateManager(updateMinDelay, DEFAULT_MAX_UPDATE_DELAY,
"Drop Down Selection Text Field Update Manager", () -> {
if (pendingTextUpdate == null) {

View File

@ -15,7 +15,7 @@
*/
package docking.widgets;
import javax.swing.*;
import javax.swing.JComponent;
import org.apache.commons.lang3.StringUtils;
@ -27,6 +27,27 @@ public interface GComponent {
// taken from BasicHTML.htmlDisable, which is private
public static final String HTML_DISABLE_STRING = "html.disable";
/**
* Enables and disables the rendering of HTML content in this component. If enabled, this
* component will interpret HTML content when the text this component is showing begins with
* <tt>&lt;html&gt;</tt>
*
* @param enable true to enable HTML rendering; false to disable it
*/
public default void setHTMLRenderingEnabled(boolean enabled) {
setHTMLRenderingFlag((JComponent) this, enabled);
}
/**
* Returns the current HTML rendering 'enable-ment' of this component.
*
* @return boolean, true if HTML rendering is allowed
*/
public default boolean getHTMLRenderingEnabled() {
Object prop = ((JComponent) this).getClientProperty(HTML_DISABLE_STRING);
return prop == null || prop != Boolean.TRUE;
}
/**
* Helper function that logs a warning about a string text that looks like it has HTML text.
* <p>
@ -44,36 +65,13 @@ public interface GComponent {
}
/**
* Turns off the HTML rendering in the specified component.
* Sets the HTML rendering flag for the specified component.
*
* @param comp the thing
* @param enabled boolean, if true html rendering will be allowed
*/
public static void turnOffHTMLRendering(JComponent comp) {
comp.putClientProperty(HTML_DISABLE_STRING, true);
}
/**
* Turns off the HTML rendering in the specified component and its current cell renderer.
*
* @param list the list
*/
public static void turnOffHTMLRendering(JList<?> list) {
turnOffHTMLRendering((JComponent) list);
if (list.getCellRenderer() instanceof JComponent) {
turnOffHTMLRendering((JComponent) list.getCellRenderer());
}
}
/**
* Turns off the HTML rendering in the specified component and its current renderer.
*
* @param cb the combobox
*/
public static void turnOffHTMLRendering(JComboBox<?> cb) {
turnOffHTMLRendering((JComponent) cb);
if (cb.getRenderer() instanceof JComponent) {
turnOffHTMLRendering((JComponent) cb.getRenderer());
}
public static void setHTMLRenderingFlag(JComponent comp, boolean enabled) {
comp.putClientProperty(HTML_DISABLE_STRING, enabled ? null : true);
}
}

View File

@ -113,6 +113,6 @@ public class GRadioButton extends JRadioButton implements GComponent {
}
private void init() {
GComponent.turnOffHTMLRendering(this);
setHTMLRenderingEnabled(false);
}
}

View File

@ -133,7 +133,7 @@ public class GCheckBox extends JCheckBox implements GComponent {
}
private void init() {
GComponent.turnOffHTMLRendering(this);
setHTMLRenderingEnabled(false);
}
/**

View File

@ -17,8 +17,7 @@ package docking.widgets.combobox;
import java.util.Vector;
import javax.swing.ComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.*;
import docking.widgets.GComponent;
@ -77,7 +76,10 @@ public class GComboBox<E> extends JComboBox<E> implements GComponent {
}
private void init() {
GComponent.turnOffHTMLRendering(this);
setHTMLRenderingEnabled(false);
if (getRenderer() instanceof JComponent) {
GComponent.setHTMLRenderingFlag((JComponent) getRenderer(), false);
}
}
}

View File

@ -102,7 +102,10 @@ public class GhidraComboBox<E> extends JComboBox<E> implements GComponent {
}
private void init() {
GComponent.turnOffHTMLRendering(this);
setHTMLRenderingEnabled(false);
if (getRenderer() instanceof JComponent) {
GComponent.setHTMLRenderingFlag((JComponent) getRenderer(), false);
}
}
@Override

View File

@ -111,7 +111,7 @@ public class GDLabel extends JLabel implements GComponent {
}
private void init() {
GComponent.turnOffHTMLRendering(this);
setHTMLRenderingEnabled(false);
}
}

View File

@ -132,7 +132,7 @@ public class GLabel extends JLabel implements GComponent {
}
private void init() {
GComponent.turnOffHTMLRendering(this);
setHTMLRenderingEnabled(false);
}
/**

View File

@ -17,8 +17,7 @@ package docking.widgets.list;
import java.util.Vector;
import javax.swing.JList;
import javax.swing.ListModel;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
@ -84,7 +83,10 @@ public class GList<T> extends JList<T> implements GComponent {
}
private void init() {
GComponent.turnOffHTMLRendering(this);
setHTMLRenderingEnabled(false);
if (getCellRenderer() instanceof JComponent) {
GComponent.setHTMLRenderingFlag((JComponent) getCellRenderer(), false);
}
addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
@ -93,4 +95,16 @@ public class GList<T> extends JList<T> implements GComponent {
});
}
// /**
// * Turns off the HTML rendering in the specified component and its current cell renderer.
// *
// * @param list the list
// */
// public static void turnOffHTMLRendering(JList<?> list) {
// turnOffHTMLRendering((JComponent) list);
// if (list.getCellRenderer() instanceof JComponent) {
// turnOffHTMLRendering((JComponent) list.getCellRenderer());
// }
// }
}

View File

@ -38,7 +38,7 @@ public class GTreeRenderer extends DefaultTreeCellRenderer implements GComponent
private int minIconWidth = DEFAULT_MIN_ICON_WIDTH;
public GTreeRenderer() {
GComponent.turnOffHTMLRendering(this);
setHTMLRenderingEnabled(false);
}
/**