diff --git a/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/HtmlContext.java b/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/HtmlContext.java index 9ec6288..2775c81 100644 --- a/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/HtmlContext.java +++ b/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/HtmlContext.java @@ -10,6 +10,8 @@ import javax.swing.JCheckBox; */ public class HtmlContext { + /** Base Points to start from, overrides max Points */ + public BigDecimal basePoints = null; /** Style for unchecked Boxes in CheckboxMultiSelect */ public String cbmsFail = ""; /** Style for checked Boxes in CheckboxMultiSelect */ @@ -24,12 +26,12 @@ public class HtmlContext public String noPtsStyle = ""; /** Style for the Text, when the best case Points have been achieved */ public String noPtsTextStyle = ""; + /** * Style for the Points, when neither best nor worst case Points have been * achieved */ public String partialPtsStyle = ""; - /** * Style for the Text, when neither best nor worst case Points have been * achieved diff --git a/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/KorrekturHelper.java b/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/KorrekturHelper.java index e90db94..1b5b6f2 100644 --- a/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/KorrekturHelper.java +++ b/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/KorrekturHelper.java @@ -1,8 +1,12 @@ package de.tuDortmund.cs.rvs.pingger.korrekturHelper; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.io.*; import java.math.BigDecimal; import java.math.MathContext; import java.nio.charset.StandardCharsets; @@ -11,10 +15,7 @@ import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.function.Consumer; -import javax.swing.BoxLayout; -import javax.swing.JFrame; -import javax.swing.JPanel; -import javax.swing.JScrollPane; +import javax.swing.*; import de.tuDortmund.cs.rvs.pingger.korrekturHelper.nodes.*; @@ -51,33 +52,33 @@ public class KorrekturHelper */ public static void main(String[] args) throws IOException { - try ( - var in = KorrekturHelper.class.getClassLoader() - .getResourceAsStream("de/tuDortmund/cs/rvs/pingger/korrekturHelper/Test.schema"); - var isr = new InputStreamReader(in, StandardCharsets.UTF_8); - var br = new BufferedReader(isr, 1024 * 1024) - ) + LinkedHashSet x; + var hc = new HtmlContext(); + if (args.length == 0) { - var x = parseSchema(br); - var frm = new JFrame("Test"); - frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - var panel = new JPanel(true); - panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); - var jsp = new JScrollPane(panel); - Consumer c = n -> { - var sb = new StringBuilder(); - recursiveToHtml(x, sb, new HtmlContext(), 0); - System.out.println(sb); - }; - for (var n : x) + try ( + var in = KorrekturHelper.class.getClassLoader() + .getResourceAsStream("de/tuDortmund/cs/rvs/pingger/korrekturHelper/Test.schema"); + var isr = new InputStreamReader(in, StandardCharsets.UTF_8); + var br = new BufferedReader(isr, 1024 * 1024) + ) { - n.addChangeListener(c); - panel.add(n.getComponent()); + x = parseSchema(br, hc); } - frm.setContentPane(jsp); - frm.pack(); - frm.setVisible(true); } + else + { + try ( + var in = new FileInputStream(new File(args[0])); + var isr = new InputStreamReader(in, StandardCharsets.UTF_8); + var br = new BufferedReader(isr, 1024 * 1024) + ) + { + x = parseSchema(br, hc); + } + } + var kh = new KorrekturHelper(x, hc); + kh.frm.setVisible(true); } private static LinkedHashSet parseNodes(String[] lines, int[] lineMap) throws IOException @@ -155,7 +156,15 @@ public class KorrekturHelper return roots; } - public static LinkedHashSet parseSchema(BufferedReader br) throws IOException + /** + * Parses the Schema provided by the Buffered Reader + * + * @param br the Reader to read from + * @param hc the HtmlContext to apply the settings to + * @return the Found root-Nodes (containing their children recursively) + * @throws IOException in case reading fails + */ + public static LinkedHashSet parseSchema(BufferedReader br, HtmlContext hc) throws IOException { var lineMap = new ArrayList(); var nodeLines = new ArrayList(); @@ -170,8 +179,60 @@ public class KorrekturHelper } if (line.startsWith(":")) { - // TODO + var split = line.split("\t", -1); + switch (split[0]) + { + /* + * :base 0.0 + // Design für Punkte. Pts ist dabei für die Punkte, PtsText für den Text. die Punkte zählen als Teil des Textes (
  • 'Punkte'Text
  • ) + // full -> best-Case + :fullPts color: #0f0; + :fullPtsText + // no -> worst-case + :noPts color: #f00; + :noPtsText + // partial -> alle verbleibenden Fälle. Sonderfall: Elemente die 0 Punkte bringen (egal was ausgewählt ist) haben auch diesen Fall! + :partialPts color: #fb0; + :partialPtsText + :cbmsOk color: #080; + :cbmsFail color: #800; + */ + case ":base": + hc.basePoints = new BigDecimal(split[1]); + break; + case ":fullPts": + hc.fullPtsStyle = split.length > 1 ? split[1] : ""; + break; + + case ":fullPtsText": + hc.fullPtsTextStyle = split.length > 1 ? split[1] : ""; + break; + + case ":noPts": + hc.noPtsStyle = split.length > 1 ? split[1] : ""; + break; + + case ":noPtsText": + hc.noPtsTextStyle = split.length > 1 ? split[1] : ""; + break; + + case ":partialPts": + hc.partialPtsStyle = split.length > 1 ? split[1] : ""; + break; + + case ":partialPtsText": + hc.partialPtsTextStyle = split.length > 1 ? split[1] : ""; + break; + + case ":cbmsOk": + hc.cbmsOk = split.length > 1 ? split[1] : ""; + break; + + case ":cbmsFail": + hc.cbmsFail = split.length > 1 ? split[1] : ""; + break; + } } else { @@ -225,8 +286,115 @@ public class KorrekturHelper } if (depth == 0) { - sb.append("\n

    ").append(recursiveAchievedPoints(nodes, hc.mc)).append("/") - .append(recursiveMaxPoints(nodes, hc.mc)).append("

    \n"); + sb.append("\n

    "); + sb.append(hc.basePoints == null || hc.basePoints.equals(BigDecimal.ZERO) ? recursiveAchievedPoints(nodes, hc.mc) + : hc.basePoints.add(recursiveAchievedPoints(nodes, hc.mc), hc.mc)); + sb.append("/"); + sb.append(hc.basePoints == null || hc.basePoints.equals(BigDecimal.ZERO) ? recursiveMaxPoints(nodes, hc.mc) + : hc.basePoints); + sb.append("

    \n"); + } + } + + private final JButton btn_toClipboard; + private String currentHtml = ""; + public final JFrame frm; + + private final HtmlContext hc; + + private final LinkedHashSet nodes; + + /** + * @param nodes Nodes + * @param hc HtmlContext + */ + public KorrekturHelper(LinkedHashSet nodes, HtmlContext hc) + { + + this.nodes = nodes; + this.hc = hc; + frm = new JFrame("Pinggers Korrektur Helper"); + frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + var contentPanel = new JPanel(new BorderLayout(), true); + /* + * Menu Panel + */ + var menuPanel = new JPanel(true); + menuPanel.setLayout(new BoxLayout(menuPanel, BoxLayout.X_AXIS)); + + var jtb_aot = new JToggleButton("Always on Top"); + jtb_aot.addActionListener(l -> frm.setAlwaysOnTop(jtb_aot.isSelected())); + menuPanel.add(jtb_aot); + // SpinnerModel sm = new SpinnerNumberModel(100, 25, 100, 5); + // sm.addChangeListener(e -> AWTUtilities.setWindowOpacity((float) ((int) + // sm.getValue() / 100.0))); + // var spn_opacity = new JSpinner(sm); + // menuPanel.add(spn_opacity); + btn_toClipboard = new JButton("Copy to Clipboard"); + btn_toClipboard.addActionListener(e -> copyToClipboard()); + menuPanel.add(btn_toClipboard); + var btn_reset = new JButton("Reset"); + btn_reset.addActionListener(e -> this.nodes.forEach(Node::reset)); + menuPanel.add(btn_reset); + contentPanel.add(menuPanel, BorderLayout.NORTH); + + /* + * Node-Panel with Scrollpane + */ + var panel = new JPanel(true); + panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); + var jsp = new JScrollPane(panel); + Consumer c = n -> lostOwnership(); + for (var n : nodes) + { + n.addChangeListener(c); + panel.add(n.getComponent()); + } + contentPanel.add(jsp, BorderLayout.CENTER); + + frm.setContentPane(contentPanel); + frm.pack(); + } + + public synchronized void copyToClipboard() + { + var sb = new StringBuilder(); + recursiveToHtml(nodes, sb, hc, 0); + currentHtml = sb.toString(); + StringSelection s = new StringSelection(currentHtml) + { + @Override + public void lostOwnership(Clipboard clipboard, java.awt.datatransfer.Transferable contents) + { + KorrekturHelper.this.lostOwnership(); + } + }; + var clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + clipboard.setContents(s, s); + btn_toClipboard.setBackground(Color.GREEN); + } + + public synchronized void lostOwnership() + { + var sb = new StringBuilder(); + recursiveToHtml(nodes, sb, hc, 0); + currentHtml = sb.toString(); + var clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + try + { + var contents = clipboard.getData(DataFlavor.stringFlavor); + if (!currentHtml.equals(contents)) + { + btn_toClipboard.setBackground(Color.ORANGE); + } + else + { + btn_toClipboard.setBackground(Color.GREEN); + } + } + catch (Exception e) + { + btn_toClipboard.setBackground(Color.ORANGE); } } } diff --git a/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/Utils.java b/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/Utils.java index 70f9c5a..4997fa6 100644 --- a/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/Utils.java +++ b/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/Utils.java @@ -8,6 +8,11 @@ import java.math.BigDecimal; public class Utils { + public static String formatPoints(BigDecimal bd) + { + return String.format("%.1f", bd.doubleValue()); + } + /** * @param p the {@link BigDecimal} to format * @return a String for the given {@link BigDecimal} diff --git a/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/nodes/CheckboxMultiSelectNode.java b/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/nodes/CheckboxMultiSelectNode.java index 1737ca5..8b2faae 100644 --- a/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/nodes/CheckboxMultiSelectNode.java +++ b/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/nodes/CheckboxMultiSelectNode.java @@ -58,7 +58,7 @@ public class CheckboxMultiSelectNode extends AbstractNode { throw new IllegalArgumentException("Expected []"); } points[i - 1] = new BigDecimal(s[1]); text[i - 1] = s[2]; - rbs[i - 1] = new JCheckBox(Utils.ptsToString(points[i - 1]) + "P - " + text[i - 1]); + rbs[i - 1] = new JCheckBox(Utils.formatPoints(points[i - 1]) + "P - " + text[i - 1]); rbs[i - 1].addActionListener(cl); content.add(rbs[i - 1]); } @@ -124,7 +124,7 @@ public class CheckboxMultiSelectNode extends AbstractNode var sb = new StringBuilder(); sb.append(""); sb.append(""); - sb.append(achievedPoints(hc.mc)).append(" / ").append(maxPoints.toPlainString()); + sb.append(Utils.formatPoints(achievedPoints(hc.mc))).append(" / ").append(Utils.formatPoints(maxPoints)); sb.append("P "); sb.append(baseMsg); sb.append("\n\t
      \n"); @@ -132,7 +132,7 @@ public class CheckboxMultiSelectNode extends AbstractNode { sb.append("\t\t"); sb.append(rbs[i].isSelected() ? "✓ " : "✗ "); - sb.append("(").append(points[i].toPlainString()).append("P) "); + sb.append("(").append(Utils.formatPoints(points[i])).append("P) "); sb.append(text[i]); sb.append("\n"); } diff --git a/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/nodes/CheckboxNode.java b/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/nodes/CheckboxNode.java index ed12d93..84ea154 100644 --- a/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/nodes/CheckboxNode.java +++ b/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/nodes/CheckboxNode.java @@ -33,7 +33,7 @@ public class CheckboxNode extends AbstractNode { throw new IllegalArgumentException("Not a [] Node"); } points = new BigDecimal(spl[1]); message = spl[2]; - cbx = new JCheckBox(Utils.ptsToString(points) + "P " + message); + cbx = new JCheckBox(Utils.formatPoints(points) + "P " + message); cbx.addActionListener(e -> onChange(this)); content.add(cbx); } @@ -70,7 +70,7 @@ public class CheckboxNode extends AbstractNode public String toResultHtml(HtmlContext hc) { return "" - + Utils.ptsToString(achievedPoints(hc.mc)) + "P " + message + ""; + + Utils.formatPoints(achievedPoints(hc.mc)) + "P " + message + ""; } } diff --git a/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/nodes/EitherNode.java b/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/nodes/EitherNode.java index f2aa9fd..1cb6f49 100644 --- a/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/nodes/EitherNode.java +++ b/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/nodes/EitherNode.java @@ -42,14 +42,14 @@ public class EitherNode extends AbstractNode messageFail = spl.length == 3 ? null : spl.length == 4 ? spl[3].substring(1).trim() : spl[4]; if (points.signum() > 0) { - btn_ok = new JRadioButton(Utils.ptsToString(points) + "P " + messageOK); + btn_ok = new JRadioButton(Utils.formatPoints(points) + "P " + messageOK); btn_fail = new JRadioButton( Utils.ptsToString(BigDecimal.ZERO) + "P " + (messageFail == null ? messageOK : messageFail)); } else { - btn_ok = new JRadioButton(Utils.ptsToString(BigDecimal.ZERO) + "P " + messageOK); - btn_fail = new JRadioButton(Utils.ptsToString(points) + "P " + (messageFail == null ? messageOK : messageFail)); + btn_ok = new JRadioButton(Utils.formatPoints(BigDecimal.ZERO) + "P " + messageOK); + btn_fail = new JRadioButton(Utils.formatPoints(points) + "P " + (messageFail == null ? messageOK : messageFail)); } btn_ok.addActionListener(e -> onChange(this)); btn_fail.addActionListener(e -> onChange(this)); @@ -125,8 +125,8 @@ public class EitherNode extends AbstractNode } return "" + // "" + // - Utils.ptsToString(achievedPoints(hc.mc)) + // - (points.signum() < 0 ? "" : " / " + maximumPoints()) + "P" + // + Utils.formatPoints(achievedPoints(hc.mc)) + // + (points.signum() < 0 ? "" : " / " + Utils.formatPoints(maximumPoints())) + "P" + // " " + // (btn_fail.isSelected() ? btn_fail.getText() : btn_ok.getText()) + // ""; diff --git a/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/nodes/HeaderNode.java b/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/nodes/HeaderNode.java index 22dea1e..9db425a 100644 --- a/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/nodes/HeaderNode.java +++ b/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/nodes/HeaderNode.java @@ -15,6 +15,8 @@ import de.tuDortmund.cs.rvs.pingger.korrekturHelper.HtmlContext; public class HeaderNode extends AbstractNode { private static final String[] configStyles = { "", "#", "##", "###", "####", "#####", "######", "*", "_" }; + private static final int[] fontSizes = { 0, 24, 20, 18, 16, 14, 12 }; + private static final String[] htmlStyles = { "", "h1", "h2", "h3", "h4", "h5", "h6", "b", "i" }; private static int indexOf(String[] array, String elem) @@ -74,8 +76,7 @@ public class HeaderNode extends AbstractNode case 4: case 5: case 6: - lbl.setFont(new Font(lbl.getFont().getFontName(), Font.PLAIN, - (int) (lbl.getFont().getSize() * (1.0 + (6 - style) / 6)))); + lbl.setFont(new Font(lbl.getFont().getFontName(), Font.PLAIN, fontSizes[style])); break; case 7: diff --git a/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/nodes/RadioMultiSelectNode.java b/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/nodes/RadioMultiSelectNode.java index a67d177..2ff8655 100644 --- a/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/nodes/RadioMultiSelectNode.java +++ b/src/main/java/de/tuDortmund/cs/rvs/pingger/korrekturHelper/nodes/RadioMultiSelectNode.java @@ -60,7 +60,7 @@ public class RadioMultiSelectNode extends AbstractNode System.out.println(s[0] + "\t" + s[1]); points[i - 1] = new BigDecimal(s[0]); text[i - 1] = s[1]; - rbs[i - 1] = new JRadioButton(Utils.ptsToString(points[i - 1]) + "P - " + text[i - 1]); + rbs[i - 1] = new JRadioButton(Utils.formatPoints(points[i - 1]) + "P - " + text[i - 1]); rbs[i - 1].addActionListener(cl); content.add(rbs[i - 1]); bg.add(rbs[i - 1]); @@ -125,7 +125,7 @@ public class RadioMultiSelectNode extends AbstractNode { return "" + // " " + // - achievedPoints(hc.mc) + " / " + maxPoints.toPlainString() + "P " + // + Utils.formatPoints(achievedPoints(hc.mc)) + " / " + Utils.formatPoints(maxPoints) + "P " + // (baseMsg == null ? text[getSelected()] : baseMsg + " (" + text[getSelected()] + ")") + ""; }