use of com.android.utils.HtmlBuilder in project android by JetBrains.
the class ManifestPanel method getErrorAddHtml.
@NotNull
private static String getErrorAddHtml(@NotNull final AndroidFacet facet, @NotNull String message, @NotNull final SourceFilePosition position, @NotNull HtmlLinkManager htmlLinkManager, @Nullable final VirtualFile currentlyOpenFile) {
/*
Example Input:
ERROR Attribute activity#com.foo.mylibrary.LibActivity@label value=(@string/app_name)
from AndroidManifest.xml:24:17-49 is also present at AndroidManifest.xml:12:13-45
value=(@string/lib_name). Suggestion: add 'tools:replace="android:label"' to <activity>
element at AndroidManifest.xml:22:9-24:51 to override. AndroidManifest.xml:24:17-49
*/
HtmlBuilder sb = new HtmlBuilder();
Matcher matcher = ADD_SUGGESTION_FORMAT.matcher(message);
if (!matcher.matches()) {
throw new IllegalArgumentException("unexpected add suggestion format " + message);
}
final String attributeName = matcher.group(1);
final String attributeValue = matcher.group(2);
String tagName = matcher.group(3);
int line = Integer.parseInt(matcher.group(4));
int col = Integer.parseInt(matcher.group(5));
final XmlFile mainManifest = ManifestUtils.getMainManifest(facet);
Element element = getElementAt(mainManifest, line, col);
if (element != null && tagName.equals(element.getTagName())) {
final Element xmlTag = element;
sb.addLink(message, htmlLinkManager.createRunnableLink(() -> addToolsAttribute(mainManifest, xmlTag, attributeName, attributeValue)));
} else {
Logger.getInstance(ManifestPanel.class).warn("can not find " + tagName + " tag " + element);
sb.add(message);
}
return sb.getHtml();
}
use of com.android.utils.HtmlBuilder in project android by JetBrains.
the class ManifestPanel method getErrorUseHtml.
@NotNull
private static String getErrorUseHtml(@NotNull final AndroidFacet facet, @NotNull String message, @NotNull final SourceFilePosition position, @NotNull HtmlLinkManager htmlLinkManager, @Nullable final VirtualFile currentlyOpenFile) {
/*
Example Input:
ERROR uses-sdk:minSdkVersion 4 cannot be smaller than version 8 declared in library
/.../mylib/AndroidManifest.xml Suggestion:use tools:overrideLibrary="com.mylib"
to force usage AndroidManifest.xml:11:5-72
*/
HtmlBuilder sb = new HtmlBuilder();
int eq = message.indexOf('=');
if (eq < 0) {
throw new IllegalArgumentException("unexpected use suggestion format " + message);
}
int end = message.indexOf('"', eq + 2);
if (end < 0 || message.charAt(eq + 1) != '\"') {
throw new IllegalArgumentException("unexpected use suggestion format " + message);
}
final String suggestion = message.substring(message.indexOf(' ') + 1, end + 1);
if (!SourcePosition.UNKNOWN.equals(position.getPosition())) {
XmlFile mainManifest = ManifestUtils.getMainManifest(facet);
Element element = getElementAt(mainManifest, position.getPosition().getStartLine(), position.getPosition().getStartColumn());
if (element != null && SdkConstants.TAG_USES_SDK.equals(element.getTagName())) {
sb.addLink(message.substring(0, end + 1), htmlLinkManager.createRunnableLink(() -> {
int eq1 = suggestion.indexOf('=');
String attributeName = suggestion.substring(suggestion.indexOf(':') + 1, eq1);
String attributeValue = suggestion.substring(eq1 + 2, suggestion.length() - 1);
addToolsAttribute(mainManifest, element, attributeName, attributeValue);
}));
sb.add(message.substring(end + 1));
} else {
Logger.getInstance(ManifestPanel.class).warn("Can not find uses-sdk tag " + element);
sb.add(message);
}
} else {
// If we do not have a uses-sdk tag in our main manifest, the suggestion is not useful
sb.add(message);
}
sb.newlineIfNecessary().newline();
return sb.getHtml();
}
use of com.android.utils.HtmlBuilder in project android by JetBrains.
the class ManifestPanel method getErrorHtml.
@NotNull
static String getErrorHtml(@NotNull final AndroidFacet facet, @NotNull String message, @NotNull final SourceFilePosition position, @NotNull HtmlLinkManager htmlLinkManager, @Nullable final VirtualFile currentlyOpenFile) {
HtmlBuilder sb = new HtmlBuilder();
int index = message.indexOf(SUGGESTION_MARKER);
if (index >= 0) {
index += SUGGESTION_MARKER.length();
String action = message.substring(index, message.indexOf(' ', index));
sb.add(message.substring(0, index));
message = message.substring(index);
if ("add".equals(action)) {
sb.addHtml(getErrorAddHtml(facet, message, position, htmlLinkManager, currentlyOpenFile));
} else if ("use".equals(action)) {
sb.addHtml(getErrorUseHtml(facet, message, position, htmlLinkManager, currentlyOpenFile));
} else if ("remove".equals(action)) {
sb.addHtml(getErrorRemoveHtml(facet, message, position, htmlLinkManager, currentlyOpenFile));
}
} else {
sb.add(message);
}
return sb.getHtml();
}
use of com.android.utils.HtmlBuilder in project android by JetBrains.
the class ManifestPanel method updateDetails.
public void updateDetails(@Nullable ManifestTreeNode node) {
HtmlBuilder sb = new HtmlBuilder();
Font font = UIUtil.getLabelFont();
sb.addHtml("<html><body style=\"font-family: " + font.getFamily() + "; " + "font-size: " + font.getSize() + "pt;\">");
sb.beginUnderline().beginBold();
sb.add("Manifest Sources");
sb.endBold().endUnderline().newline();
sb.addHtml("<table border=\"0\">");
String borderColor = ColorUtil.toHex(JBColor.GRAY);
for (File file : myFiles) {
Color color = getFileColor(file);
sb.addHtml("<tr><td width=\"24\" height=\"24\" style=\"background-color:#");
sb.addHtml(ColorUtil.toHex(color));
sb.addHtml("; border: 1px solid #");
sb.addHtml(borderColor);
sb.addHtml(";\">");
sb.addHtml("</td><td>");
describePosition(sb, myFacet, new SourceFilePosition(file, SourcePosition.UNKNOWN));
sb.addHtml("</td></tr>");
}
sb.addHtml("</table>");
sb.newline();
if (!myOtherFiles.isEmpty()) {
sb.beginUnderline().beginBold();
sb.add("Other Manifest Files");
sb.endBold().endUnderline().newline();
sb.add("(Included in merge, but did not contribute any elements)").newline();
boolean first = true;
for (File file : myOtherFiles) {
if (first) {
first = false;
} else {
sb.add(", ");
}
describePosition(sb, myFacet, new SourceFilePosition(file, SourcePosition.UNKNOWN));
}
sb.newline().newline();
}
// See if there are errors; if so, show the merging report instead of node selection report
if (!myManifest.getLoggingRecords().isEmpty()) {
for (MergingReport.Record record : myManifest.getLoggingRecords()) {
if (record.getSeverity() == MergingReport.Record.Severity.ERROR) {
node = null;
break;
}
}
}
if (node != null) {
List<? extends Actions.Record> records = ManifestUtils.getRecords(myManifest, node.getUserObject());
sb.beginUnderline().beginBold();
sb.add("Merging Log");
sb.endBold().endUnderline().newline();
if (records.isEmpty()) {
sb.add("No records found. (This is a bug in the manifest merger.)");
}
SourceFilePosition prev = null;
boolean prevInjected = false;
for (Actions.Record record : records) {
// There are currently some duplicated entries; filter these out
SourceFilePosition location = ManifestUtils.getActionLocation(myFacet.getModule(), record);
if (location.equals(prev)) {
continue;
}
prev = location;
Actions.ActionType actionType = record.getActionType();
boolean injected = actionType == Actions.ActionType.INJECTED;
if (injected && prevInjected) {
continue;
}
prevInjected = injected;
if (injected) {
// TODO: include module source? Are we certain it's correct?
sb.add("Value provided by Gradle");
sb.newline();
continue;
}
sb.add(StringUtil.capitalize(String.valueOf(actionType).toLowerCase(Locale.US)));
sb.add(" from the ");
sb.addHtml(getHtml(myFacet, location));
String reason = record.getReason();
if (reason != null) {
sb.add("; reason: ");
sb.add(reason);
}
sb.newline();
}
} else if (!myManifest.getLoggingRecords().isEmpty()) {
sb.add("Merging Errors:").newline();
for (MergingReport.Record record : myManifest.getLoggingRecords()) {
sb.addHtml(getHtml(record.getSeverity()));
sb.add(" ");
try {
sb.addHtml(getErrorHtml(myFacet, record.getMessage(), record.getSourceLocation(), myHtmlLinkManager, LocalFileSystem.getInstance().findFileByIoFile(myFiles.get(0))));
} catch (Exception ex) {
Logger.getInstance(ManifestPanel.class).error("error getting error html", ex);
sb.add(record.getMessage());
}
sb.add(" ");
sb.addHtml(getHtml(myFacet, record.getSourceLocation()));
sb.newline();
}
}
sb.closeHtmlBody();
myDetails.setText(sb.getHtml());
myDetails.setCaretPosition(0);
}
use of com.android.utils.HtmlBuilder in project android by JetBrains.
the class AllocationsView method valueChanged.
@Override
public void valueChanged(SunburstChart.SliceSelectionEvent e) {
ValuedTreeNode node = e == null ? null : e.getNode();
HtmlBuilder builder = new HtmlBuilder();
builder.openHtmlBody();
if (node == null) {
node = myTreeNode;
}
builder.add("Total allocations:").addNbsp().addBold(Integer.toString(node.getCount())).newline().add("Total size:").addNbsp().addBold(StringUtil.formatFileSize(node.getValue())).newline().newline();
if (node instanceof AbstractTreeNode) {
TreeNode[] path = myTreeModel.getPathToRoot(node);
myInfoTableModel.setRowCount(path.length);
// Start at 1 to avoid adding the root node.
for (int i = 1; i < path.length; i++) {
myInfoTableModel.setValueAt(path[i], i - 1, 0);
}
myInfoTableModel.fireTableDataChanged();
}
builder.closeHtmlBody();
myInfoLabel.setText(builder.getHtml());
}
Aggregations