diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/ConvenienceNodeWrapper.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/ConvenienceNodeWrapper.java index 343498b3a4..52208c9b71 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/ConvenienceNodeWrapper.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/ConvenienceNodeWrapper.java @@ -4,6 +4,10 @@ package net.sourceforge.pmd.util.fxdesigner.util; +import java.util.Collection; + +import org.fxmisc.richtext.model.StyledDocument; + import net.sourceforge.pmd.lang.ast.Node; @@ -14,6 +18,9 @@ import net.sourceforge.pmd.lang.ast.Node; public interface ConvenienceNodeWrapper { + StyledDocument, String, Collection> getNodeRichText(); + + Node getNode(); diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/DesignerUtil.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/DesignerUtil.java index 4bb50d1bec..7e6ff5f1c3 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/DesignerUtil.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/DesignerUtil.java @@ -81,6 +81,11 @@ public final class DesignerUtil { } + public static URL getCss(String simpleName) { + return DesignerUtil.class.getResource("/net/sourceforge/pmd/util/fxdesigner/css/" + simpleName); + } + + /** * Name of the designer's settings file. * diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/codearea/NodeStyleSpan.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/codearea/NodeStyleSpan.java index dac53324d6..5c32769103 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/codearea/NodeStyleSpan.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/codearea/NodeStyleSpan.java @@ -10,6 +10,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import org.fxmisc.richtext.model.Paragraph; +import org.fxmisc.richtext.model.StyledDocument; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.util.fxdesigner.util.ConvenienceNodeWrapper; @@ -117,6 +118,11 @@ class NodeStyleSpan { } + @Override + public StyledDocument, String, Collection> getNodeRichText() { + return codeArea.subDocument(beginIndex, endIndex); + } + public int getBeginIndex() { return beginIndex; } diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/controls/XpathViolationListCell.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/controls/XpathViolationListCell.java index 3503ddec63..f8013d06aa 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/controls/XpathViolationListCell.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/controls/XpathViolationListCell.java @@ -5,11 +5,18 @@ package net.sourceforge.pmd.util.fxdesigner.util.controls; +import java.util.Collection; import java.util.regex.Pattern; +import org.fxmisc.richtext.model.StyleSpan; +import org.fxmisc.richtext.model.StyledDocument; + import net.sourceforge.pmd.util.fxdesigner.util.ConvenienceNodeWrapper; +import net.sourceforge.pmd.util.fxdesigner.util.DesignerUtil; import javafx.scene.control.ListCell; +import javafx.scene.text.Text; +import javafx.scene.text.TextFlow; /** @@ -27,9 +34,42 @@ public class XpathViolationListCell extends ListCell { setText(null); setGraphic(null); } else { - String text = TRUNCATION_PATTERN.matcher(item.getNodeText()).replaceFirst("..."); - setText("(l. " + item.getNode().getBeginLine() + ", c. " + item.getNode().getBeginColumn() + "): " + text); + setGraphic(richTextForNode(item)); +// String text = TRUNCATION_PATTERN.matcher(item.getNodeText()).replaceFirst("..."); +// setText("(l. " + item.getNode().getBeginLine() + ", c. " + item.getNode().getBeginColumn() + "): " + text); } } + + private TextFlow richTextForNode(ConvenienceNodeWrapper node) { + StyledDocument, String, Collection> richText = node.getNodeRichText(); + + TextFlow result = new TextFlow(); + int lastSpanEnd = 0; + for (StyleSpan> span : richText.getStyleSpans(0, richText.length())) { + String spanText = richText.getText(lastSpanEnd, lastSpanEnd + span.getLength()); + int truncateTo = spanText.indexOf("\n"); + + Text text = new Text(truncateTo < 0 ? spanText : spanText.substring(0, truncateTo)); + text.getStyleClass().addAll(span.getStyle()); + text.getStyleClass().removeIf(s -> s.endsWith("-highlight")); + + result.getChildren().add(text); + + lastSpanEnd += text.getText().length(); + if (truncateTo > 0) { + break; + } + } + + // we truncated + if (lastSpanEnd < richText.length()) { + result.getChildren().add(new Text("...")); + } + + result.getStylesheets().add(DesignerUtil.getCss("editor-theme.css").toExternalForm()); + + return result; + } + } diff --git a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/less/editor-theme.less b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/less/editor-theme.less index fbc266e346..dcc14b5f3c 100644 --- a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/less/editor-theme.less +++ b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/less/editor-theme.less @@ -18,6 +18,7 @@ rgba(214, 93, 177, 0.7), rgba(132, 94, 194, 0.8); +@active-line-focus-color: #fbf4e1; /* With syntax highlighting, it's more readable to not change the fill color */ .focus-highlight { @@ -82,7 +83,6 @@ -fx-background-color: derive(black, 90%); } -@active-line-focus-color: #fbf4e1; .paragraph-box:has-caret { -fx-background-color: #fbf4e1; @@ -90,6 +90,9 @@ .text { -fx-fill: #585858; +} + +.styled-text-area .text { -fx-font-size: 10.5pt; } @@ -124,33 +127,33 @@ /* Syntax highlighting base */ /****************************/ -.styled-text-area .keyword { +.keyword { -fx-fill: #B58900; /* -fx-font-weight: bold; */ } -.styled-text-area .punctuation { +.punctuation { } -.styled-text-area .literal { +.literal { -fx-fill: #317ECC; } -.styled-text-area .comment { +.comment { -fx-fill: #93A1A1; -fx-font-style: italic; /* doesn't work... */ } -.styled-text-area .annotation { +.annotation { -fx-fill: #d30102; } /* Java specific */ -.styled-text-area .java.class-identifier { +.java.class-identifier { -fx-fill: #B05A65; } @@ -162,48 +165,48 @@ -fx-font-size: 11.5pt; } -.styled-text-area .xpath.path { +.xpath.path { -fx-font-weight: bold; } -.styled-text-area .xpath.axis { +.xpath.axis { -fx-fill: #B05A65; } -.styled-text-area .xpath.bracket { +.xpath.bracket { -fx-font-weight: bolder; } -.styled-text-area .xpath.attribute { +.xpath.attribute { -fx-fill: #B05A65; } -.styled-text-area .xpath.function { +.xpath.function { -fx-fill: #cc971b; } /* XML specific */ -.styled-text-area .xml.xml-prolog { +.xml.xml-prolog { -fx-font-weight: bolder; } -.styled-text-area .xml.tag-name { +.xml.tag-name { -fx-fill: #B05A65; } -.styled-text-area .xml.lt-gt { +.xml.lt-gt { -fx-fill: #B05A65; } -.styled-text-area .xml.attribute-name { +.xml.attribute-name { -fx-fill: #B58900; } -.styled-text-area .xml.cdata-tag { +.xml.cdata-tag { -fx-fill: #B58900; } -.styled-text-area .xml.cdata-content { +.xml.cdata-content { -fx-fill: #93A1A1; } \ No newline at end of file