/* (C) 2000-2002, DIUF, http://www.unifr.ch/diuf * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package iiuf.xmillum; import iiuf.util.EventListenerList; import iiuf.util.Queue; import java.awt.Point; import java.awt.Rectangle; import java.awt.image.RenderedImage; import java.awt.event.MouseEvent; import java.io.File; import java.io.InputStream; import java.io.IOException; import java.net.URL; import java.util.EventListener; import java.util.Hashtable; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; /** * BrowserContext * * Browser context information. Based on the XMIllum code * * @author Tamir Hassan, hassan@dbai.tuwien.ac.at * @author DIUF, Fribourg, CH * @version GraphWrap Beta 1 */ public class BrowserContext { static { try { InputStream is = BrowserContext.class.getResourceAsStream("xmillum.colors"); if (is == null) { System.err.println("Unable to load xmillum.colors, using predefined colors only."); } else { System.getProperties().load(is); } } catch (IOException e) { e.printStackTrace(); } } private Queue runQueue; public static final int MSG_LOAD_STYLESHEET = 1; public static final int MSG_RESCALE = 2; public static final int MSG_TOGGLE_LAYER = 3; public static final int MSG_RETRANSFORM = 4; public static final int MSG_REFRESH = 6; public static final int MSG_SET_SOURCE = 10; class IllumMessage { public int message; public Object arg; public Object arg2; public IllumMessage(int message) { this.message = message; } public IllumMessage(int message, Object arg) { this.message = message; this.arg = arg; } public IllumMessage(int message, Object arg, Object arg2) { this.message = message; this.arg = arg; this.arg2 = arg2; } } public BrowserContext() { try { Class.forName("javax.media.jai.JAI", false, Thread.currentThread().getContextClassLoader()); Class i = Class.forName("iiuf.xmillum.JAIImageFactory"); setImageFactory((ImageFactory) i.newInstance()); setStatus("Detected JAI."); } catch (Throwable t) { setImageFactory(new JavaImageFactory()); } runQueue = new Queue("commandqueue") { public boolean handle(Object o) { IllumMessage msg = (IllumMessage) o; try { switch (msg.message) { case MSG_SET_SOURCE: setStatus("Loading source data..."); document.loadSourceDocument((IllumSource) msg.arg); setStatus("Done."); tryTransform(); break; case MSG_LOAD_STYLESHEET: setStatus("Loading stylesheet..."); document.loadStylesheet((URL) msg.arg); setStatus("Done."); tryTransform(); break; case MSG_TOGGLE_LAYER: if (document.getInternalDocument() != null && displayableFactory != null) { setStatus("Displaying..."); fireDocumentChangeEvent(new DocumentChangeEvent(BrowserContext.this, DocumentChangeEvent.LAYER_TOGGLED, (String) msg.arg, ((Boolean) msg.arg2).booleanValue())); setStatus("Done."); } break; case MSG_RETRANSFORM: setStatus("Transforming..."); document.transform(); fireDocumentChangeEvent(DocumentChangeEvent.DOCUMENT_CHANGED); setStatus("Done."); break; case MSG_REFRESH: fireDocumentChangeEvent(DocumentChangeEvent.REFRESH); break; default: System.out.println("Unknown message "+msg.message); } } catch (IllumException e) { setStatus(e.toString()); e.printStackTrace(); } return true; } public void tryTransform() throws IllumException { if (document.hasSource() && document.hasStylesheet()) { actionFactory = null; displayableFactory = null; setStatus("Transforming..."); document.transform(); styleRegistry = new StyleRegistry(BrowserContext.this, document.getStyles()); flagger.setFlags(document.getFlags()); setSelectionFlag(FlagManager.SELECTION, FlagManager.SELECTED); actionFactory = new ActionHandlerFactory(BrowserContext.this, document.getHandlers()); displayableFactory = new DisplayableFactory(BrowserContext.this, document.getDisplayables()); fireDocumentChangeEvent(DocumentChangeEvent.DOCUMENT_CHANGED); setStatus("Done."); } } }; } /** List of status listeners */ EventListenerList statusListeners = new EventListenerList(); /** Adds a status listener which receives status mesages. @param listener StatusListener to add */ public void addStatusListener(StatusListener listener) { statusListeners.add(StatusListener.class, listener); } /** Removes a status listener. @param listener StatusListener to remove */ public void removeStatusListener(StatusListener listener) { statusListeners.remove(StatusListener.class, listener); } /** Notifies all StatusListeners with a status message @param message Status message. */ public void setStatus(String message) { EventListener[] l = statusListeners.getListeners(StatusListener.class); if (l.length == 0) { log(message); } else { for (int i = 0; i < l.length; i++) { ((StatusListener) l[i]).setStatus(message); } } } /** * Log message. * * @param String message */ public void log(String message) { System.err.println(message); } public void log(String message, Throwable t) { System.err.print(message+" ("+t.getMessage()+")"); } /** List of change listeners */ EventListenerList documentChangeListeners = new EventListenerList(); /** Adds a change listener which receives change mesages. @param listener DocumentChangeListener to add */ public void addDocumentChangeListener(DocumentChangeListener listener) { documentChangeListeners.add(DocumentChangeListener.class, listener); } /** Removes a change listener. @param listener DocumentChangeListener to remove */ public void removeDocumentChangeListener(DocumentChangeListener listener) { documentChangeListeners.remove(DocumentChangeListener.class, listener); } /** Notifies all DocumentChangeListeners. */ private void fireDocumentChangeEvent(int type) { DocumentChangeEvent e = new DocumentChangeEvent(this, type); EventListener[] l = documentChangeListeners.getListeners(DocumentChangeListener.class); for (int i = 0; i < l.length; i++) { ((DocumentChangeListener) l[i]).documentChanged(e); } } private void fireDocumentChangeEvent(DocumentChangeEvent e) { EventListener[] l = documentChangeListeners.getListeners(DocumentChangeListener.class); for (int i = 0; i < l.length; i++) { ((DocumentChangeListener) l[i]).documentChanged(e); } } /** Set a source document. @param source IllumSource. */ public void setSource(IllumSource source) { this.source = source; runQueue.put(new IllumMessage(MSG_SET_SOURCE, source)); } /** Load stylesheet. @param file Stylesheet. */ public void loadStylesheet(URL url) { runQueue.put(new IllumMessage(MSG_LOAD_STYLESHEET, url)); } /** Switch a layer on and off. @param layer The layer to switch on and off. @param active On/off. */ public void toggleLayer(String layer, boolean active) { runQueue.put(new IllumMessage(MSG_TOGGLE_LAYER, layer, new Boolean(active))); } public void finish() { flagger.runHandlers(); } /** Clear the current layer. Closes all tool windows and empties the BrowserPanel. */ public void clearLayer() { toggleLayer(null, false); } /** Refresh display */ public void refresh() { runQueue.put(new IllumMessage(MSG_REFRESH)); } public void retransform() { runQueue.put(new IllumMessage(MSG_RETRANSFORM)); } public IllumDocument getDocument() { return document; } public double getScale() { return browserPanel.getScale(); } // The currently active document private IllumDocument document = new IllumDocument(this); // Source document public IllumSource source; // Flag manager public FlagManager flagger = new FlagManager(this); // ActionHandler factory public ActionHandlerFactory actionFactory; // Style registry public StyleRegistry styleRegistry; // Displayable factory public DisplayableFactory displayableFactory; public BrowserPanel browserPanel; // Image factory private ImageFactory imageFactory; public ImageFactory getImageFactory() { return imageFactory; } public void setImageFactory(ImageFactory i) { imageFactory = i; imageFactory.setBrowserContext(this); } // Mouse event coordinates private Point mousePosition = new Point(); /** * Sets the mouse position. * * @param e mouse event */ public void setMousePosition(MouseEvent e) { mousePosition = (Point) e.getPoint().clone(); } /** * Returns the mouse position. * * @return mouse position */ public Point getMousePosition() { return new Point(mousePosition); } public ElementTagger elementTagger; public void setWindowCreator(WindowCreator w) { windowCreator = w; } public WindowCreator getWindowCreator() { return windowCreator; } private WindowCreator windowCreator; /** * Returns the element in the source document which is referenced by * the given reference. * * @param reference Reference to search * @return Element that is referenced */ public Element getSourceElementByReference(String reference) { if (reference == null || reference.equals("")) { return null; } else { return document.getSourceElementWithReference(reference); } } /** * Returns a NodeList with the elements in the internal document * which reference the element having the given reference in the * source. * * @param reference Reference to find * @return List of elements that reference the requested reference */ public NodeList getInternalElementsWhichReference(String reference) { return document.getInternalElementsWhichReference(reference); } /** * Sets the drag distance. * * @param d Distance */ public void setDragDistance(Point d) { // dragDistance = new Point((int) (d.x/getScale()), (int) (d.y/getScale())); dragDistance = new Point(d); } /** Drag distance */ Point dragDistance; /** * Returns the drag distance. * * @return Drag distance */ public Point getDragDistance() { return dragDistance; } /** Flag access */ private FlagAccess flagAccess; /** Flag value */ private String selectionValue = FlagManager.SELECTED; /** * Toggles the selection state of an element. * * @param e The element to select */ public void toggleSelection(Element e) { flagAccess.toggleFlag(e, selectionValue, null); } /** * Sets the flag that is set when toggleSelection is called. * * @param type Flag type * @param value Flag value */ public void setSelectionFlag(String type, String value) { flagAccess = flagger.addFlagListener(type, new FlagListener() { public void setFlag(Element e, String v) { } }); selectionValue = value; } }