package misc; import java.awt.Color; import java.awt.Component; import java.awt.Frame; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.swing.event.HyperlinkEvent; import javax.swing.event.HyperlinkListener; import javax.swing.text.html.HTMLDocument; import javax.swing.text.html.HTMLFrameHyperlinkEvent; @SuppressWarnings ("serial") public class Guide extends HtmlDialog { // ======================================== static public final int H_SPACE = 5; static public final int V_SPACE = 2; // ======================================== Color standardBackground = Color.gray; Color highlightColor = Color.orange; Component [] component; Color [] componentBackgroundColor; int next = -1; boolean [] done; // ======================================== public Guide (Frame frame, String titleName, String fileName, Component [] component, Color standardBackground, Color highlightColor) { super (frame, titleName, fileName); this.component = component; this.standardBackground = standardBackground; this.highlightColor = highlightColor; done = new boolean [component.length]; componentBackgroundColor = new Color [component.length]; for (int i = 0; i < component.length; i++) if (component [i] != null) componentBackgroundColor [i] = component [i].getBackground (); reset (); editorPane.addHyperlinkListener (new Hyperactive ()); } // ======================================== class Hyperactive implements HyperlinkListener { public void hyperlinkUpdate (HyperlinkEvent e) { if (e.getEventType () == HyperlinkEvent.EventType.ACTIVATED) { String file = e.getURL ().getPath (); String command = file.substring (file.lastIndexOf ("/")+1); int idx = command.indexOf ("?"); if (idx >= 0) command = command.substring (0, idx); if ("Reset".equals (command)) { reset (); setNext (); } else if (command.startsWith ("ActionG")) { String [] bound = command.substring ("ActionG".length ()).split ("\\-"); flipGroup (Integer.parseInt (bound[0]), Integer.parseInt (bound[1])); } else if (command.startsWith ("Action")) flipStep (Integer.parseInt (command.substring ("Action".length ()))); else if (e instanceof HTMLFrameHyperlinkEvent) { HTMLFrameHyperlinkEvent evt = (HTMLFrameHyperlinkEvent) e; HTMLDocument doc = (HTMLDocument) editorPane.getDocument (); doc.processHTMLFrameHyperlinkEvent (evt); } else { try { editorPane.setPage (e.getURL ()); } catch (Throwable t) { Log.keepLastException ("Guide::hyperlinkUpdate", t); } } } } } // ======================================== public void setVisible (boolean visible) { reset (); super.setVisible (visible); if (visible) { setNext (); editorPane.scrollToReference ("Top"); } } // ======================================== public void changeHtmlClassAction (String actionName, String className) { String newPage = editorPane.getText (). replaceAll ("]*name=\"Action("+actionName+")\"[^>]*>", "
"). replaceAll ("]*name=\"Action("+actionName+")\"[^>]*>", ""); editorPane.setText (newPage); } // ======================================== public void reset () { next = -1; if (done == null) return; for (int step = 0; step < done.length; step++) { done [step] = false; if (component [step] != null) component [step].setBackground (componentBackgroundColor [step]); } // XXX pb d'affichage editorPane.getText (); try { Thread.sleep (200); } catch (InterruptedException e) { } changeHtmlClassAction ("(G[0-9]+-)?[0-9]+", "Unknown"); editorPane.scrollToReference ("Top"); } // ======================================== public void unsetNext () { if (next < 0) return; changeHtmlClassAction (""+next, "Unknown"); if (component [next] != null) component [next].setBackground (componentBackgroundColor [next]); next = -1; } // ======================================== public void setNext () { if (next >= 0 && ! done [next]) return; next = -1; for (int step = 0; step < done.length; step++) if (!done [step]) { next = step; changeHtmlClassAction (""+next, "Todo"); if (component [next] != null) component [next].setBackground (highlightColor); editorPane.scrollToReference ("Action"+next); return; } } // ======================================== private void stepIsDone (int step) { done [step] = true; changeHtmlClassAction (""+step, "Done"); if (component [step] != null) component [step].setBackground (componentBackgroundColor [step]); } // ======================================== private void stepIsUnknown (int step) { done [step] = false; changeHtmlClassAction (""+step, "Unknown"); } // ======================================== public void flipStep (int step) { unsetNext (); if (done [step]) stepIsUnknown (step); else stepIsDone (step); checkGroup (); setNext (); } // ======================================== public void flipGroup (int step1, int step2) { unsetNext (); boolean allDone = true; for (int step = step1; step <= step2; step++) if (!done [step]) { allDone = false; break; } if (allDone) { for (int step = step1; step <= step2; step++) stepIsUnknown (step); changeHtmlClassAction ("G"+step1+"-"+step2, "Unknown"); } else { for (int step = step1; step <= step2; step++) stepIsDone (step); changeHtmlClassAction ("G"+step1+"-"+step2, "Done"); } checkGroup (); setNext (); } // ======================================== public void checkGroup () { String newPage = editorPane.getText (); Pattern pattern = Pattern.compile ("]*name=\"ActionG(([0-9]+)-([0-9]+))\"[^>]*>"); Matcher matcher = pattern.matcher (newPage); while (matcher.find()) { int step1 = Integer.parseInt (matcher.group (2)); int step2 = Integer.parseInt (matcher.group (3)); boolean allDone = true; for (int step = step1; step <= step2; step++) if (!done [step]) { allDone = false; break; } changeHtmlClassAction ("G"+step1+"-"+step2, allDone ? "Done" : "Unknown"); } } // ======================================== }