Skip to content

Commit bbacb43

Browse files
committed
Merge remote-tracking branch 'origin/GT-3318-dragonmacher-plugin-description-html-fix'
2 parents 7ab75e4 + 5007c00 commit bbacb43

File tree

4 files changed

+94
-154
lines changed

4 files changed

+94
-154
lines changed

Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/dialog/AbstractDetailsPanel.java

Lines changed: 42 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,14 @@
1515
*/
1616
package ghidra.framework.plugintool.dialog;
1717

18+
import static ghidra.util.HTMLUtilities.*;
19+
1820
import java.awt.*;
19-
import java.util.StringTokenizer;
2021

2122
import javax.swing.*;
2223
import javax.swing.text.SimpleAttributeSet;
2324
import javax.swing.text.StyleConstants;
2425

25-
import org.apache.commons.lang3.StringUtils;
26-
2726
import docking.widgets.label.GDHtmlLabel;
2827
import ghidra.util.HTMLUtilities;
2928

@@ -34,14 +33,14 @@
3433
*/
3534
public abstract class AbstractDetailsPanel extends JPanel {
3635

36+
private static final int MIN_WIDTH = 700;
3737
protected static final int LEFT_COLUMN_WIDTH = 150;
3838
protected static final int RIGHT_MARGIN = 30;
3939

4040
// Font attributes for the title of each row.
4141
protected static SimpleAttributeSet titleAttrSet;
4242

4343
protected JLabel textLabel;
44-
protected Font defaultFont;
4544
protected JScrollPane sp;
4645

4746
/**
@@ -105,15 +104,25 @@ protected void clear() {
105104
*/
106105
protected void createMainPanel() {
107106
setLayout(new BorderLayout());
108-
textLabel = new GDHtmlLabel("");
107+
textLabel = new GDHtmlLabel() {
108+
@Override
109+
public Dimension getPreferredSize() {
110+
111+
// overridden to force word-wrapping by limiting the preferred size of the label
112+
Dimension mySize = super.getPreferredSize();
113+
int rightColumnWidth = AbstractDetailsPanel.this.getWidth() - LEFT_COLUMN_WIDTH;
114+
mySize.width = Math.max(MIN_WIDTH, rightColumnWidth);
115+
return mySize;
116+
}
117+
};
118+
109119
textLabel.setVerticalAlignment(SwingConstants.TOP);
110120
textLabel.setOpaque(true);
111121
textLabel.setBackground(Color.WHITE);
112122
sp = new JScrollPane(textLabel);
113123
sp.getVerticalScrollBar().setUnitIncrement(10);
114-
sp.setPreferredSize(new Dimension(700, 200));
124+
sp.setPreferredSize(new Dimension(MIN_WIDTH, 200));
115125
add(sp, BorderLayout.CENTER);
116-
defaultFont = new Font("Tahoma", Font.BOLD, 12);
117126
}
118127

119128
/**
@@ -126,7 +135,7 @@ protected void createMainPanel() {
126135
protected void insertRowTitle(StringBuilder buffer, String rowName) {
127136
buffer.append("<TR>");
128137
buffer.append("<TD VALIGN=\"TOP\">");
129-
insertHTMLLine(rowName + ":", titleAttrSet, buffer);
138+
insertHTMLLine(buffer, rowName + ":", titleAttrSet);
130139
buffer.append("</TD>");
131140
}
132141

@@ -136,139 +145,67 @@ protected void insertRowTitle(StringBuilder buffer, String rowName) {
136145
*
137146
* @param buffer the string buffer to add to
138147
* @param value the text to add
139-
* @param attrSet the structure containing formatting information
148+
* @param attributes the structure containing formatting information
140149
*/
141-
protected void insertRowValue(StringBuilder buffer, String value, SimpleAttributeSet attrSet) {
142-
buffer.append("<TD VALIGN=\"TOP\">");
143-
insertHTMLLine(value, attrSet, buffer);
150+
protected void insertRowValue(StringBuilder buffer, String value,
151+
SimpleAttributeSet attributes) {
152+
buffer.append("<TD VALIGN=\"TOP\" WIDTH=\"80%\">");
153+
insertHTMLLine(buffer, value, attributes);
144154
buffer.append("</TD>");
145155
buffer.append("</TR>");
146156
}
147157

148158
/**
149159
* Adds text to a string buffer as an html-formatted string, adding formatting information
150160
* as specified.
151-
*
152-
* @param string the string to add
153-
* @param attributeSet the formatting instructions
154161
* @param buffer the string buffer to add to
162+
* @param string the string to add
163+
* @param attributes the formatting instructions
155164
*/
156-
protected void insertHTMLString(String string, SimpleAttributeSet attributeSet,
157-
StringBuilder buffer) {
165+
protected void insertHTMLString(StringBuilder buffer, String string,
166+
SimpleAttributeSet attributes) {
167+
158168
if (string == null) {
159169
return;
160170
}
161-
buffer.append("<FONT COLOR=\"#");
162171

163-
Color foregroundColor = (Color) attributeSet.getAttribute(StyleConstants.Foreground);
164-
buffer.append(createColorString(foregroundColor));
172+
buffer.append("<FONT COLOR=\"");
165173

166-
buffer.append("\" FACE=\"");
174+
Color foregroundColor = (Color) attributes.getAttribute(StyleConstants.Foreground);
175+
buffer.append(HTMLUtilities.toHexString(foregroundColor));
167176

168-
buffer.append(attributeSet.getAttribute(StyleConstants.FontFamily).toString());
177+
buffer.append("\" FACE=\"");
178+
buffer.append(attributes.getAttribute(StyleConstants.FontFamily).toString());
169179

170180
buffer.append("\">");
171181

172-
Boolean isBold = (Boolean) attributeSet.getAttribute(StyleConstants.Bold);
182+
Boolean isBold = (Boolean) attributes.getAttribute(StyleConstants.Bold);
173183
isBold = (isBold == null) ? Boolean.FALSE : isBold;
184+
String text = HTMLUtilities.escapeHTML(string);
174185
if (isBold) {
175-
buffer.append("<B>");
186+
text = HTMLUtilities.bold(text);
176187
}
177188

178-
buffer.append(HTMLUtilities.escapeHTML(string));
179-
180-
if (isBold) {
181-
buffer.append("</B>");
182-
}
189+
buffer.append(text);
183190

184191
buffer.append("</FONT>");
185192
}
186193

187194
/**
188195
* Inserts a single line of html into a {@link StringBuffer}, with the given attributes.
189-
*
190-
* @param string the string to insert
191-
* @param attributeSet the attributes to apply
192196
* @param buffer the string buffer
197+
* @param string the string to insert
198+
* @param attributes the attributes to apply
193199
*/
194-
protected void insertHTMLLine(String string, SimpleAttributeSet attributeSet,
195-
StringBuilder buffer) {
200+
protected void insertHTMLLine(StringBuilder buffer, String string,
201+
SimpleAttributeSet attributes) {
196202
if (string == null) {
197203
return;
198204
}
199205

200-
insertHTMLString(string, attributeSet, buffer);
206+
insertHTMLString(buffer, string, attributes);
201207

202208
// row padding - newline space
203-
buffer.append("<BR>");
204-
}
205-
206-
/**
207-
* Returns a stringified version of the {@link Color} provided; eg: "8c0000"
208-
*
209-
* @param color the color to parse
210-
* @return string version of the color
211-
*/
212-
protected String createColorString(Color color) {
213-
214-
int red = color.getRed();
215-
int green = color.getGreen();
216-
int blue = color.getBlue();
217-
218-
return StringUtils.leftPad(Integer.toHexString(red), 2, "0") +
219-
StringUtils.leftPad(Integer.toHexString(green), 2, "0") +
220-
StringUtils.leftPad(Integer.toHexString(blue), 2, "0");
221-
}
222-
223-
/**
224-
* Returns a string with line breaks at the boundary of the window it's being displayed in.
225-
* Without this the description would just run on in one long line.
226-
*
227-
* @param descr the string to format
228-
* @return the formatted string
229-
*/
230-
protected String formatDescription(String descr) {
231-
if (descr == null) {
232-
return "";
233-
}
234-
int maxWidth = getMaxStringWidth();
235-
int remainingWidth = maxWidth;
236-
FontMetrics fm = textLabel.getFontMetrics(defaultFont);
237-
int spaceSize = fm.charWidth(' ');
238-
StringBuffer sb = new StringBuffer();
239-
StringTokenizer st = new StringTokenizer(descr, " ");
240-
while (st.hasMoreTokens()) {
241-
String str = st.nextToken();
242-
if (str.endsWith(".")) {
243-
str = str + " ";
244-
}
245-
int strWidth = fm.stringWidth(str);
246-
if (strWidth + spaceSize <= remainingWidth) {
247-
sb.append(" ");
248-
sb.append(str);
249-
remainingWidth -= strWidth + spaceSize;
250-
}
251-
else {
252-
sb.append("<BR>");
253-
sb.append(str + " ");
254-
remainingWidth = maxWidth - strWidth;
255-
}
256-
}
257-
return sb.toString();
258-
}
259-
260-
/**
261-
* Returns the maximum size that one line of text can be when formatting the description.
262-
*
263-
* @return the number of characters in the string
264-
*/
265-
protected int getMaxStringWidth() {
266-
267-
int width = textLabel.getWidth();
268-
if (width == 0) {
269-
width = 700;
270-
}
271-
width -= LEFT_COLUMN_WIDTH + RIGHT_MARGIN; // allow for tabs and right margin
272-
return width;
209+
buffer.append(BR);
273210
}
274211
}

Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/dialog/ExtensionDetailsPanel.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,20 @@
3131
class ExtensionDetailsPanel extends AbstractDetailsPanel {
3232

3333
/** Attribute sets define the visual characteristics for each field */
34-
private static SimpleAttributeSet nameAttrSet;
35-
private static SimpleAttributeSet descrAttrSet;
36-
private static SimpleAttributeSet authorAttrSet;
37-
private static SimpleAttributeSet createdOnAttrSet;
38-
private static SimpleAttributeSet versionAttrSet;
39-
private static SimpleAttributeSet pathAttrSet;
34+
private SimpleAttributeSet nameAttrSet;
35+
private SimpleAttributeSet descrAttrSet;
36+
private SimpleAttributeSet authorAttrSet;
37+
private SimpleAttributeSet createdOnAttrSet;
38+
private SimpleAttributeSet versionAttrSet;
39+
private SimpleAttributeSet pathAttrSet;
4040

4141
ExtensionDetailsPanel(ExtensionTablePanel tablePanel) {
4242
super();
4343
createFieldAttributes();
4444
createMainPanel();
4545

4646
// Any time the table is reloaded or a new selection is made, we want to reload this
47-
// panel. This ensures we are alwasy viewing data for the currently-selected item.
47+
// panel. This ensures we are always viewing data for the currently-selected item.
4848
tablePanel.getTableModel().addThreadedTableModelListener(new ThreadedTableModelListener() {
4949

5050
@Override
@@ -87,7 +87,7 @@ public void setDescription(ExtensionDetails details) {
8787
insertRowValue(buffer, details.getName(), nameAttrSet);
8888

8989
insertRowTitle(buffer, "Description");
90-
insertRowValue(buffer, formatDescription(details.getDescription()), descrAttrSet);
90+
insertRowValue(buffer, details.getDescription(), descrAttrSet);
9191

9292
insertRowTitle(buffer, "Author");
9393
insertRowValue(buffer, details.getAuthor(), authorAttrSet);

0 commit comments

Comments
 (0)