0001: /*
0002:
0003: Licensed to the Apache Software Foundation (ASF) under one or more
0004: contributor license agreements. See the NOTICE file distributed with
0005: this work for additional information regarding copyright ownership.
0006: The ASF licenses this file to You under the Apache License, Version 2.0
0007: (the "License"); you may not use this file except in compliance with
0008: the License. You may obtain a copy of the License at
0009:
0010: http://www.apache.org/licenses/LICENSE-2.0
0011:
0012: Unless required by applicable law or agreed to in writing, software
0013: distributed under the License is distributed on an "AS IS" BASIS,
0014: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0015: See the License for the specific language governing permissions and
0016: limitations under the License.
0017:
0018: */
0019: package org.apache.batik.apps.svgbrowser;
0020:
0021: import java.awt.BorderLayout;
0022: import java.awt.Color;
0023: import java.awt.Cursor;
0024: import java.awt.Dimension;
0025: import java.awt.Event;
0026: import java.awt.EventQueue;
0027: import java.awt.FileDialog;
0028: import java.awt.Font;
0029: import java.awt.Graphics2D;
0030: import java.awt.Rectangle;
0031: import java.awt.Toolkit;
0032: import java.awt.event.ActionEvent;
0033: import java.awt.event.ComponentAdapter;
0034: import java.awt.event.ComponentEvent;
0035: import java.awt.event.KeyEvent;
0036: import java.awt.event.MouseAdapter;
0037: import java.awt.event.MouseEvent;
0038: import java.awt.event.MouseMotionAdapter;
0039: import java.awt.event.WindowAdapter;
0040: import java.awt.event.WindowEvent;
0041: import java.awt.geom.AffineTransform;
0042: import java.awt.geom.NoninvertibleTransformException;
0043: import java.awt.geom.Point2D;
0044: import java.awt.image.BufferedImage;
0045: import java.awt.print.PrinterException;
0046: import java.io.BufferedOutputStream;
0047: import java.io.File;
0048: import java.io.FilenameFilter;
0049: import java.io.FileOutputStream;
0050: import java.io.IOException;
0051: import java.io.InputStream;
0052: import java.io.OutputStream;
0053: import java.io.OutputStreamWriter;
0054: import java.io.Reader;
0055: import java.lang.reflect.Constructor;
0056: import java.lang.reflect.InvocationTargetException;
0057: import java.lang.reflect.Method;
0058: import java.net.MalformedURLException;
0059: import java.util.HashMap;
0060: import java.util.Iterator;
0061: import java.util.LinkedList;
0062: import java.util.List;
0063: import java.util.Locale;
0064: import java.util.Map;
0065: import java.util.MissingResourceException;
0066: import java.util.ResourceBundle;
0067: import java.util.Vector;
0068:
0069: import javax.swing.AbstractAction;
0070: import javax.swing.Action;
0071: import javax.swing.BorderFactory;
0072: import javax.swing.ButtonGroup;
0073: import javax.swing.JComponent;
0074: import javax.swing.JDialog;
0075: import javax.swing.JFileChooser;
0076: import javax.swing.JFrame;
0077: import javax.swing.JMenu;
0078: import javax.swing.JMenuBar;
0079: import javax.swing.JOptionPane;
0080: import javax.swing.JPanel;
0081: import javax.swing.JRadioButtonMenuItem;
0082: import javax.swing.JScrollPane;
0083: import javax.swing.JTextArea;
0084: import javax.swing.JToolBar;
0085: import javax.swing.JWindow;
0086: import javax.swing.KeyStroke;
0087: import javax.swing.filechooser.FileFilter;
0088: import javax.swing.text.Document;
0089: import javax.swing.text.PlainDocument;
0090:
0091: import org.apache.batik.bridge.DefaultExternalResourceSecurity;
0092: import org.apache.batik.bridge.DefaultScriptSecurity;
0093: import org.apache.batik.bridge.EmbededExternalResourceSecurity;
0094: import org.apache.batik.bridge.EmbededScriptSecurity;
0095: import org.apache.batik.bridge.ExternalResourceSecurity;
0096: import org.apache.batik.bridge.NoLoadExternalResourceSecurity;
0097: import org.apache.batik.bridge.NoLoadScriptSecurity;
0098: import org.apache.batik.bridge.RelaxedExternalResourceSecurity;
0099: import org.apache.batik.bridge.RelaxedScriptSecurity;
0100: import org.apache.batik.bridge.ScriptSecurity;
0101: import org.apache.batik.bridge.UpdateManager;
0102: import org.apache.batik.bridge.UpdateManagerEvent;
0103: import org.apache.batik.bridge.UpdateManagerListener;
0104: import org.apache.batik.dom.StyleSheetProcessingInstruction;
0105: import org.apache.batik.dom.svg.SVGOMDocument;
0106: import org.apache.batik.dom.util.HashTable;
0107: import org.apache.batik.dom.util.DOMUtilities;
0108: import org.apache.batik.ext.swing.JAffineTransformChooser;
0109: import org.apache.batik.swing.JSVGCanvas;
0110: import org.apache.batik.swing.gvt.GVTTreeRendererEvent;
0111: import org.apache.batik.swing.gvt.GVTTreeRendererListener;
0112: import org.apache.batik.swing.svg.GVTTreeBuilderEvent;
0113: import org.apache.batik.swing.svg.GVTTreeBuilderListener;
0114: import org.apache.batik.swing.svg.LinkActivationEvent;
0115: import org.apache.batik.swing.svg.LinkActivationListener;
0116: import org.apache.batik.swing.svg.SVGDocumentLoaderEvent;
0117: import org.apache.batik.swing.svg.SVGDocumentLoaderListener;
0118: import org.apache.batik.swing.svg.SVGFileFilter;
0119: import org.apache.batik.swing.svg.SVGLoadEventDispatcherEvent;
0120: import org.apache.batik.swing.svg.SVGLoadEventDispatcherListener;
0121: import org.apache.batik.swing.svg.SVGUserAgent;
0122: import org.apache.batik.transcoder.TranscoderInput;
0123: import org.apache.batik.transcoder.TranscoderOutput;
0124: import org.apache.batik.transcoder.image.ImageTranscoder;
0125: import org.apache.batik.transcoder.image.JPEGTranscoder;
0126: import org.apache.batik.transcoder.image.PNGTranscoder;
0127: import org.apache.batik.transcoder.image.TIFFTranscoder;
0128: import org.apache.batik.transcoder.print.PrintTranscoder;
0129: import org.apache.batik.transcoder.svg2svg.SVGTranscoder;
0130: import org.apache.batik.util.ParsedURL;
0131: import org.apache.batik.util.Platform;
0132: import org.apache.batik.util.Service;
0133: import org.apache.batik.util.SVGConstants;
0134: import org.apache.batik.util.XMLConstants;
0135: import org.apache.batik.util.gui.DOMViewer;
0136: import org.apache.batik.util.gui.JErrorPane;
0137: import org.apache.batik.util.gui.LocationBar;
0138: import org.apache.batik.util.gui.MemoryMonitor;
0139: import org.apache.batik.util.gui.URIChooser;
0140: import org.apache.batik.util.gui.resource.ActionMap;
0141: import org.apache.batik.util.gui.resource.JComponentModifier;
0142: import org.apache.batik.util.gui.resource.MenuFactory;
0143: import org.apache.batik.util.gui.resource.MissingListenerException;
0144: import org.apache.batik.util.gui.resource.ResourceManager;
0145: import org.apache.batik.util.gui.resource.ToolBarFactory;
0146: import org.apache.batik.xml.XMLUtilities;
0147: import org.w3c.dom.Element;
0148: import org.w3c.dom.Node;
0149: import org.w3c.dom.css.ViewCSS;
0150: import org.w3c.dom.svg.SVGDocument;
0151:
0152: /**
0153: * This class represents a SVG viewer swing frame.
0154: *
0155: * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
0156: * @version $Id: JSVGViewerFrame.java 511565 2007-02-25 18:04:46Z dvholten $
0157: */
0158: public class JSVGViewerFrame extends JFrame implements ActionMap,
0159: SVGDocumentLoaderListener, GVTTreeBuilderListener,
0160: SVGLoadEventDispatcherListener, GVTTreeRendererListener,
0161: LinkActivationListener, UpdateManagerListener {
0162:
0163: private static String EOL;
0164: static {
0165: try {
0166: EOL = System.getProperty("line.separator", "\n");
0167: } catch (SecurityException e) {
0168: EOL = "\n";
0169: }
0170: }
0171:
0172: /**
0173: * Kind of ugly, but we need to know if we are running before
0174: * or after 1.4...
0175: */
0176: protected static boolean priorJDK1_4 = true;
0177:
0178: /**
0179: * If the following class can be found (it appeared in JDK 1.4),
0180: * then we know we are post JDK 1.4.
0181: */
0182: protected static final String JDK_1_4_PRESENCE_TEST_CLASS = "java.util.logging.LoggingPermission";
0183:
0184: static {
0185: try {
0186: Class.forName(JDK_1_4_PRESENCE_TEST_CLASS);
0187: priorJDK1_4 = false;
0188: } catch (ClassNotFoundException e) {
0189: }
0190: }
0191:
0192: /**
0193: * The gui resources file name
0194: */
0195: public static final String RESOURCES = "org.apache.batik.apps.svgbrowser.resources.GUI";
0196:
0197: // The actions names.
0198: public static final String ABOUT_ACTION = "AboutAction";
0199: public static final String OPEN_ACTION = "OpenAction";
0200: public static final String OPEN_LOCATION_ACTION = "OpenLocationAction";
0201: public static final String NEW_WINDOW_ACTION = "NewWindowAction";
0202: public static final String RELOAD_ACTION = "ReloadAction";
0203: public static final String SAVE_AS_ACTION = "SaveAsAction";
0204: public static final String BACK_ACTION = "BackAction";
0205: public static final String FORWARD_ACTION = "ForwardAction";
0206: public static final String FULL_SCREEN_ACTION = "FullScreenAction";
0207: public static final String PRINT_ACTION = "PrintAction";
0208: public static final String EXPORT_AS_JPG_ACTION = "ExportAsJPGAction";
0209: public static final String EXPORT_AS_PNG_ACTION = "ExportAsPNGAction";
0210: public static final String EXPORT_AS_TIFF_ACTION = "ExportAsTIFFAction";
0211: public static final String PREFERENCES_ACTION = "PreferencesAction";
0212: public static final String CLOSE_ACTION = "CloseAction";
0213: public static final String VIEW_SOURCE_ACTION = "ViewSourceAction";
0214: public static final String EXIT_ACTION = "ExitAction";
0215: public static final String RESET_TRANSFORM_ACTION = "ResetTransformAction";
0216: public static final String ZOOM_IN_ACTION = "ZoomInAction";
0217: public static final String ZOOM_OUT_ACTION = "ZoomOutAction";
0218: public static final String PREVIOUS_TRANSFORM_ACTION = "PreviousTransformAction";
0219: public static final String NEXT_TRANSFORM_ACTION = "NextTransformAction";
0220: public static final String USE_STYLESHEET_ACTION = "UseStylesheetAction";
0221: public static final String PLAY_ACTION = "PlayAction";
0222: public static final String PAUSE_ACTION = "PauseAction";
0223: public static final String STOP_ACTION = "StopAction";
0224: public static final String MONITOR_ACTION = "MonitorAction";
0225: public static final String DOM_VIEWER_ACTION = "DOMViewerAction";
0226: public static final String SET_TRANSFORM_ACTION = "SetTransformAction";
0227: public static final String FIND_DIALOG_ACTION = "FindDialogAction";
0228: public static final String THUMBNAIL_DIALOG_ACTION = "ThumbnailDialogAction";
0229: public static final String FLUSH_ACTION = "FlushAction";
0230: public static final String TOGGLE_DEBUGGER_ACTION = "ToggleDebuggerAction";
0231:
0232: /**
0233: * The cursor indicating that an operation is pending.
0234: */
0235: public static final Cursor WAIT_CURSOR = new Cursor(
0236: Cursor.WAIT_CURSOR);
0237:
0238: /**
0239: * The default cursor.
0240: */
0241: public static final Cursor DEFAULT_CURSOR = new Cursor(
0242: Cursor.DEFAULT_CURSOR);
0243:
0244: /**
0245: * Name for the os-name property
0246: */
0247: public static final String PROPERTY_OS_NAME = Resources
0248: .getString("JSVGViewerFrame.property.os.name");
0249:
0250: /**
0251: * Name for the os.name default
0252: */
0253: public static final String PROPERTY_OS_NAME_DEFAULT = Resources
0254: .getString("JSVGViewerFrame.property.os.name.default");
0255:
0256: /**
0257: * Name for the os.name property prefix we are looking
0258: * for in OpenAction to work around JFileChooser bug
0259: */
0260: public static final String PROPERTY_OS_WINDOWS_PREFIX = Resources
0261: .getString("JSVGViewerFrame.property.os.windows.prefix");
0262:
0263: /**
0264: * Resource string name for the Open dialog.
0265: */
0266: protected static final String OPEN_TITLE = "Open.title";
0267:
0268: /**
0269: * The input handlers
0270: */
0271: protected static Vector handlers;
0272:
0273: /**
0274: * The default input handler
0275: */
0276: protected static SquiggleInputHandler defaultHandler = new SVGInputHandler();
0277:
0278: /**
0279: * The resource bundle
0280: */
0281: protected static ResourceBundle bundle;
0282:
0283: /**
0284: * The resource manager
0285: */
0286: protected static ResourceManager resources;
0287: static {
0288: bundle = ResourceBundle.getBundle(RESOURCES, Locale
0289: .getDefault());
0290: resources = new ResourceManager(bundle);
0291: }
0292:
0293: /**
0294: * The current application.
0295: */
0296: protected Application application;
0297:
0298: /**
0299: * The JSVGCanvas.
0300: */
0301: protected Canvas svgCanvas;
0302:
0303: /**
0304: * An extension of JSVGCanvas that exposes the Rhino interpreter.
0305: */
0306: protected static class Canvas extends JSVGCanvas {
0307:
0308: /**
0309: * Creates a new Canvas.
0310: */
0311: public Canvas(SVGUserAgent ua, boolean eventsEnabled,
0312: boolean selectableText) {
0313: super (ua, eventsEnabled, selectableText);
0314: }
0315:
0316: /**
0317: * Returns the Rhino interpreter for this canvas.
0318: */
0319: public Object getRhinoInterpreter() {
0320: if (bridgeContext == null) {
0321: return null;
0322: }
0323: return bridgeContext.getInterpreter("text/ecmascript");
0324: }
0325: }
0326:
0327: /**
0328: * The panel where the svgCanvas is displayed
0329: */
0330: protected JPanel svgCanvasPanel;
0331:
0332: /**
0333: * A window used for full screen display
0334: */
0335: protected JWindow window;
0336:
0337: /**
0338: * The memory monitor frame.
0339: */
0340: protected static JFrame memoryMonitorFrame;
0341:
0342: /**
0343: * The current path.
0344: */
0345: protected File currentPath = new File("");
0346:
0347: /**
0348: * The current export path.
0349: */
0350: protected File currentSavePath = new File("");
0351:
0352: /**
0353: * The back action
0354: */
0355: protected BackAction backAction = new BackAction();
0356:
0357: /**
0358: * The forward action
0359: */
0360: protected ForwardAction forwardAction = new ForwardAction();
0361:
0362: /**
0363: * The play action
0364: */
0365: protected PlayAction playAction = new PlayAction();
0366:
0367: /**
0368: * The pause action
0369: */
0370: protected PauseAction pauseAction = new PauseAction();
0371:
0372: /**
0373: * The stop action
0374: */
0375: protected StopAction stopAction = new StopAction();
0376:
0377: /**
0378: * The previous transform action
0379: */
0380: protected PreviousTransformAction previousTransformAction = new PreviousTransformAction();
0381:
0382: /**
0383: * The next transform action
0384: */
0385: protected NextTransformAction nextTransformAction = new NextTransformAction();
0386:
0387: /**
0388: * The use (author) stylesheet action
0389: */
0390: protected UseStylesheetAction useStylesheetAction = new UseStylesheetAction();
0391:
0392: /**
0393: * The debug flag.
0394: */
0395: protected boolean debug;
0396:
0397: /**
0398: * The auto adjust flag.
0399: */
0400: protected boolean autoAdjust = true;
0401:
0402: /**
0403: * Whether the update manager was stopped.
0404: */
0405: protected boolean managerStopped;
0406:
0407: /**
0408: * The SVG user agent.
0409: */
0410: protected SVGUserAgent userAgent = new UserAgent();
0411:
0412: /**
0413: * The current document.
0414: */
0415: protected SVGDocument svgDocument;
0416:
0417: /**
0418: * The URI chooser.
0419: */
0420: protected URIChooser uriChooser;
0421:
0422: /**
0423: * The DOM viewer.
0424: */
0425: protected DOMViewer domViewer;
0426:
0427: /**
0428: * The Find dialog.
0429: */
0430: protected FindDialog findDialog;
0431:
0432: /**
0433: * The Find dialog.
0434: */
0435: protected ThumbnailDialog thumbnailDialog;
0436:
0437: /**
0438: * The transform dialog
0439: */
0440: protected JAffineTransformChooser.Dialog transformDialog;
0441:
0442: /**
0443: * The location bar.
0444: */
0445: protected LocationBar locationBar;
0446:
0447: /**
0448: * The status bar.
0449: */
0450: protected StatusBar statusBar;
0451:
0452: /**
0453: * The initial frame title.
0454: */
0455: protected String title;
0456:
0457: /**
0458: * The local history.
0459: */
0460: protected LocalHistory localHistory;
0461:
0462: /**
0463: * The transform history.
0464: */
0465: protected TransformHistory transformHistory = new TransformHistory();
0466:
0467: /**
0468: * The alternate style-sheet title.
0469: */
0470: protected String alternateStyleSheet;
0471:
0472: /**
0473: * The debugger object.
0474: */
0475: protected Debugger debugger;
0476:
0477: /**
0478: * Creates a new SVG viewer frame.
0479: */
0480: public JSVGViewerFrame(Application app) {
0481: application = app;
0482:
0483: addWindowListener(new WindowAdapter() {
0484: public void windowClosing(WindowEvent e) {
0485: application.closeJSVGViewerFrame(JSVGViewerFrame.this );
0486: }
0487: });
0488:
0489: //
0490: // Set the frame's maximum size so that content
0491: // bigger than the screen does not cause the creation
0492: // of unnecessary large images.
0493: //
0494: svgCanvas = new Canvas(userAgent, true, true) {
0495: Dimension screenSize;
0496:
0497: {
0498: screenSize = Toolkit.getDefaultToolkit()
0499: .getScreenSize();
0500: setMaximumSize(screenSize);
0501: }
0502:
0503: public Dimension getPreferredSize() {
0504: Dimension s = super .getPreferredSize();
0505: if (s.width > screenSize.width)
0506: s.width = screenSize.width;
0507: if (s.height > screenSize.height)
0508: s.height = screenSize.height;
0509: return s;
0510: }
0511:
0512: /**
0513: * This method is called when the component knows the desired
0514: * size of the window (based on width/height of outermost SVG
0515: * element). We override it to immediately pack this frame.
0516: */
0517: public void setMySize(Dimension d) {
0518: setPreferredSize(d);
0519: invalidate();
0520: if (JSVGViewerFrame.this .autoAdjust) {
0521: Platform.unmaximize(JSVGViewerFrame.this );
0522: JSVGViewerFrame.this .pack();
0523: }
0524: }
0525:
0526: public void setDisableInteractions(boolean b) {
0527: super .setDisableInteractions(b);
0528:
0529: // Disable/Enable all our different ways to adjust the
0530: // rendering transform (menus, toolbar, thumbnail, keyboard).
0531:
0532: ((Action) listeners.get(SET_TRANSFORM_ACTION))
0533: .setEnabled(!b);
0534:
0535: if (thumbnailDialog != null)
0536: thumbnailDialog.setInteractionEnabled(!b);
0537: }
0538: };
0539:
0540: javax.swing.ActionMap map = svgCanvas.getActionMap();
0541: map.put(FULL_SCREEN_ACTION, new FullScreenAction());
0542: javax.swing.InputMap imap = svgCanvas
0543: .getInputMap(JComponent.WHEN_FOCUSED);
0544: KeyStroke key = KeyStroke.getKeyStroke(KeyEvent.VK_F11, 0);
0545: imap.put(key, FULL_SCREEN_ACTION);
0546:
0547: svgCanvas.setDoubleBufferedRendering(true);
0548:
0549: listeners.put(ABOUT_ACTION, new AboutAction());
0550: listeners.put(OPEN_ACTION, new OpenAction());
0551: listeners.put(OPEN_LOCATION_ACTION, new OpenLocationAction());
0552: listeners.put(NEW_WINDOW_ACTION, new NewWindowAction());
0553: listeners.put(RELOAD_ACTION, new ReloadAction());
0554: listeners.put(SAVE_AS_ACTION, new SaveAsAction());
0555: listeners.put(BACK_ACTION, backAction);
0556: listeners.put(FORWARD_ACTION, forwardAction);
0557: listeners.put(PRINT_ACTION, new PrintAction());
0558: listeners.put(EXPORT_AS_JPG_ACTION, new ExportAsJPGAction());
0559: listeners.put(EXPORT_AS_PNG_ACTION, new ExportAsPNGAction());
0560: listeners.put(EXPORT_AS_TIFF_ACTION, new ExportAsTIFFAction());
0561: listeners.put(PREFERENCES_ACTION, new PreferencesAction());
0562: listeners.put(CLOSE_ACTION, new CloseAction());
0563: listeners.put(EXIT_ACTION, application.createExitAction(this ));
0564: listeners.put(VIEW_SOURCE_ACTION, new ViewSourceAction());
0565:
0566: javax.swing.ActionMap cMap = svgCanvas.getActionMap();
0567: listeners.put(RESET_TRANSFORM_ACTION, cMap
0568: .get(JSVGCanvas.RESET_TRANSFORM_ACTION));
0569: listeners.put(ZOOM_IN_ACTION, cMap
0570: .get(JSVGCanvas.ZOOM_IN_ACTION));
0571: listeners.put(ZOOM_OUT_ACTION, cMap
0572: .get(JSVGCanvas.ZOOM_OUT_ACTION));
0573:
0574: listeners.put(PREVIOUS_TRANSFORM_ACTION,
0575: previousTransformAction);
0576: key = KeyStroke.getKeyStroke(KeyEvent.VK_K, KeyEvent.CTRL_MASK);
0577: imap.put(key, previousTransformAction);
0578:
0579: listeners.put(NEXT_TRANSFORM_ACTION, nextTransformAction);
0580: key = KeyStroke.getKeyStroke(KeyEvent.VK_L, KeyEvent.CTRL_MASK);
0581: imap.put(key, nextTransformAction);
0582:
0583: listeners.put(USE_STYLESHEET_ACTION, useStylesheetAction);
0584: listeners.put(PLAY_ACTION, playAction);
0585: listeners.put(PAUSE_ACTION, pauseAction);
0586: listeners.put(STOP_ACTION, stopAction);
0587: listeners.put(MONITOR_ACTION, new MonitorAction());
0588: listeners.put(DOM_VIEWER_ACTION, new DOMViewerAction());
0589: listeners.put(SET_TRANSFORM_ACTION, new SetTransformAction());
0590: listeners.put(FIND_DIALOG_ACTION, new FindDialogAction());
0591: listeners.put(THUMBNAIL_DIALOG_ACTION,
0592: new ThumbnailDialogAction());
0593: listeners.put(FLUSH_ACTION, new FlushAction());
0594: listeners.put(TOGGLE_DEBUGGER_ACTION,
0595: new ToggleDebuggerAction());
0596:
0597: JPanel p = null;
0598: try {
0599: // Create the menu
0600: MenuFactory mf = new MenuFactory(bundle, this );
0601: JMenuBar mb = mf.createJMenuBar("MenuBar", application
0602: .getUISpecialization());
0603: setJMenuBar(mb);
0604:
0605: localHistory = new LocalHistory(mb, this );
0606:
0607: String[] uri = application.getVisitedURIs();
0608: for (int i = 0; i < uri.length; i++) {
0609: if (uri[i] != null && !"".equals(uri[i])) {
0610: localHistory.update(uri[i]);
0611: }
0612: }
0613: p = new JPanel(new BorderLayout());
0614:
0615: // Create the toolbar
0616: ToolBarFactory tbf = new ToolBarFactory(bundle, this );
0617: JToolBar tb = tbf.createJToolBar("ToolBar");
0618: tb.setFloatable(false);
0619: getContentPane().add(p, BorderLayout.NORTH);
0620: p.add(tb, BorderLayout.NORTH);
0621: p.add(new javax.swing.JSeparator(), BorderLayout.CENTER);
0622: p.add(locationBar = new LocationBar(), BorderLayout.SOUTH);
0623: locationBar.setBorder(BorderFactory.createEmptyBorder(2, 2,
0624: 2, 2));
0625:
0626: } catch (MissingResourceException e) {
0627: System.out.println(e.getMessage());
0628: System.exit(0);
0629: }
0630:
0631: svgCanvasPanel = new JPanel(new BorderLayout());
0632: svgCanvasPanel.setBorder(BorderFactory.createEtchedBorder());
0633:
0634: svgCanvasPanel.add(svgCanvas, BorderLayout.CENTER);
0635: p = new JPanel(new BorderLayout());
0636: p.add(svgCanvasPanel, BorderLayout.CENTER);
0637: p.add(statusBar = new StatusBar(), BorderLayout.SOUTH);
0638:
0639: getContentPane().add(p, BorderLayout.CENTER);
0640:
0641: svgCanvas.addSVGDocumentLoaderListener(this );
0642: svgCanvas.addGVTTreeBuilderListener(this );
0643: svgCanvas.addSVGLoadEventDispatcherListener(this );
0644: svgCanvas.addGVTTreeRendererListener(this );
0645: svgCanvas.addLinkActivationListener(this );
0646: svgCanvas.addUpdateManagerListener(this );
0647:
0648: svgCanvas.addMouseMotionListener(new MouseMotionAdapter() {
0649: public void mouseMoved(MouseEvent e) {
0650: if (svgDocument == null) {
0651: statusBar.setXPosition(e.getX());
0652: statusBar.setYPosition(e.getY());
0653: } else {
0654: try {
0655: AffineTransform at;
0656: at = svgCanvas.getViewBoxTransform();
0657: if (at != null) {
0658: at = at.createInverse();
0659: Point2D p2d = at.transform(
0660: new Point2D.Float(e.getX(), e
0661: .getY()), null);
0662: statusBar.setXPosition((float) p2d.getX());
0663: statusBar.setYPosition((float) p2d.getY());
0664: return;
0665: }
0666: } catch (NoninvertibleTransformException ex) {
0667: }
0668: statusBar.setXPosition(e.getX());
0669: statusBar.setYPosition(e.getY());
0670: }
0671: }
0672: });
0673: svgCanvas.addMouseListener(new MouseAdapter() {
0674: public void mouseExited(MouseEvent e) {
0675: Dimension dim = svgCanvas.getSize();
0676: if (svgDocument == null) {
0677: statusBar.setWidth(dim.width);
0678: statusBar.setHeight(dim.height);
0679: } else {
0680: try {
0681: AffineTransform at;
0682: at = svgCanvas.getViewBoxTransform();
0683: if (at != null) {
0684: at = at.createInverse();
0685: Point2D o = at.transform(new Point2D.Float(
0686: 0, 0), null);
0687: Point2D p2d = at.transform(
0688: new Point2D.Float(dim.width,
0689: dim.height), null);
0690: statusBar.setWidth((float) (p2d.getX() - o
0691: .getX()));
0692: statusBar.setHeight((float) (p2d.getY() - o
0693: .getY()));
0694: return;
0695: }
0696: } catch (NoninvertibleTransformException ex) {
0697: }
0698: statusBar.setWidth(dim.width);
0699: statusBar.setHeight(dim.height);
0700: }
0701: }
0702: });
0703: svgCanvas.addComponentListener(new ComponentAdapter() {
0704: public void componentResized(ComponentEvent e) {
0705: Dimension dim = svgCanvas.getSize();
0706: if (svgDocument == null) {
0707: statusBar.setWidth(dim.width);
0708: statusBar.setHeight(dim.height);
0709: } else {
0710: try {
0711: AffineTransform at;
0712: at = svgCanvas.getViewBoxTransform();
0713: if (at != null) {
0714: at = at.createInverse();
0715: Point2D o = at.transform(new Point2D.Float(
0716: 0, 0), null);
0717: Point2D p2d = at.transform(
0718: new Point2D.Float(dim.width,
0719: dim.height), null);
0720: statusBar.setWidth((float) (p2d.getX() - o
0721: .getX()));
0722: statusBar.setHeight((float) (p2d.getY() - o
0723: .getY()));
0724: return;
0725: }
0726: } catch (NoninvertibleTransformException ex) {
0727: }
0728: statusBar.setWidth(dim.width);
0729: statusBar.setHeight(dim.height);
0730: }
0731: }
0732: });
0733:
0734: locationBar.addActionListener(new AbstractAction() {
0735: public void actionPerformed(ActionEvent e) {
0736: String st = locationBar.getText().trim();
0737: int i = st.indexOf('#');
0738: String t = "";
0739: if (i != -1) {
0740: t = st.substring(i + 1);
0741: st = st.substring(0, i);
0742: }
0743:
0744: if (st.equals(""))
0745: return;
0746:
0747: try {
0748: File f = new File(st);
0749: if (f.exists()) {
0750: if (f.isDirectory()) {
0751: return;
0752: } else {
0753: try {
0754: st = f.getCanonicalPath();
0755: if (st.startsWith("/")) {
0756: st = "file:" + st;
0757: } else {
0758: st = "file:/" + st;
0759: }
0760: } catch (IOException ex) {
0761: }
0762: }
0763: }
0764: } catch (SecurityException se) {
0765: // Could not patch the file URI for security
0766: // reasons (e.g., when run as an unsigned
0767: // JavaWebStart jar): file access is not
0768: // allowed. Loading will fail, but there is
0769: // nothing more to do at this point.
0770: }
0771:
0772: String fi = svgCanvas.getFragmentIdentifier();
0773: if (svgDocument != null) {
0774: ParsedURL docPURL = new ParsedURL(svgDocument
0775: .getURL());
0776: ParsedURL purl = new ParsedURL(docPURL, st);
0777: fi = (fi == null) ? "" : fi;
0778: if (docPURL.equals(purl) && t.equals(fi)) {
0779: return;
0780: }
0781: }
0782: if (t.length() != 0) {
0783: st += '#' + t;
0784: }
0785: locationBar.setText(st);
0786: locationBar.addToHistory(st);
0787: showSVGDocument(st);
0788: }
0789: });
0790: }
0791:
0792: /**
0793: * Call dispose on canvas as well.
0794: */
0795: public void dispose() {
0796: hideDebugger();
0797: svgCanvas.dispose();
0798: super .dispose();
0799: }
0800:
0801: /**
0802: * Whether to show the debug traces.
0803: */
0804: public void setDebug(boolean b) {
0805: debug = b;
0806: }
0807:
0808: /**
0809: * Whether to auto adjust the canvas to the size of the document.
0810: */
0811: public void setAutoAdjust(boolean b) {
0812: autoAdjust = b;
0813: }
0814:
0815: /**
0816: * Returns the main JSVGCanvas of this frame.
0817: */
0818: public JSVGCanvas getJSVGCanvas() {
0819: return svgCanvas;
0820: }
0821:
0822: /**
0823: * Needed to work-around JFileChooser bug with abstract Files
0824: */
0825: private static File makeAbsolute(File f) {
0826: if (!f.isAbsolute()) {
0827: return f.getAbsoluteFile();
0828: }
0829: return f;
0830: }
0831:
0832: /**
0833: * Shows the Rhino debugger.
0834: */
0835: public void showDebugger() {
0836: if (debugger == null && Debugger.isPresent) {
0837: debugger = new Debugger(this , locationBar.getText());
0838: debugger.initialize();
0839: }
0840: }
0841:
0842: /**
0843: * Hides and destroys the Rhino debugger.
0844: */
0845: public void hideDebugger() {
0846: if (debugger != null) {
0847: debugger.clearAllBreakpoints();
0848: debugger.go();
0849: debugger.dispose();
0850: debugger = null;
0851: }
0852: }
0853:
0854: /**
0855: * Rhino debugger class.
0856: */
0857: protected static class Debugger {
0858:
0859: /**
0860: * Whether the Rhino debugger classes are present.
0861: */
0862: protected static boolean isPresent;
0863:
0864: /**
0865: * The Rhino debugger class.
0866: */
0867: protected static Class debuggerClass;
0868:
0869: /**
0870: * The Rhino ContextFactory class.
0871: */
0872: protected static Class contextFactoryClass;
0873:
0874: // Indexes into the debuggerMethods array.
0875: protected static final int CLEAR_ALL_BREAKPOINTS_METHOD = 0;
0876: protected static final int GO_METHOD = 1;
0877: protected static final int SET_EXIT_ACTION_METHOD = 2;
0878: protected static final int ATTACH_TO_METHOD = 3;
0879: protected static final int DETACH_METHOD = 4;
0880: protected static final int DISPOSE_METHOD = 5;
0881: protected static final int GET_DEBUG_FRAME_METHOD = 6;
0882:
0883: /**
0884: * Rhino debugger class constructor.
0885: */
0886: protected static Constructor debuggerConstructor;
0887:
0888: /**
0889: * Rhino debugger class methods.
0890: */
0891: protected static Method[] debuggerMethods;
0892:
0893: /**
0894: * The RhinoInterpreter class.
0895: */
0896: protected static Class rhinoInterpreterClass;
0897:
0898: /**
0899: * The {@code getContextFactory} method on the {@link
0900: * org.apache.batik.script.rhino.RhinoInterpreter} class.
0901: */
0902: protected static Method getContextFactoryMethod;
0903:
0904: static {
0905: try {
0906: Class dc = Class
0907: .forName("org.mozilla.javascript.tools.debugger.Main");
0908: Class cfc = Class
0909: .forName("org.mozilla.javascript.ContextFactory");
0910: rhinoInterpreterClass = Class
0911: .forName("org.apache.batik.script.rhino.RhinoInterpreter");
0912: debuggerConstructor = dc
0913: .getConstructor(new Class[] { String.class });
0914: debuggerMethods = new Method[] {
0915: dc.getMethod("clearAllBreakpoints",
0916: (Class[]) null),
0917: dc.getMethod("go", (Class[]) null),
0918: dc.getMethod("setExitAction",
0919: new Class[] { Runnable.class }),
0920: dc.getMethod("attachTo", new Class[] { cfc }),
0921: dc.getMethod("detach", (Class[]) null),
0922: dc.getMethod("dispose", (Class[]) null),
0923: dc.getMethod("getDebugFrame", (Class[]) null) };
0924: getContextFactoryMethod = rhinoInterpreterClass
0925: .getMethod("getContextFactory", (Class[]) null);
0926: debuggerClass = dc;
0927: isPresent = true;
0928: } catch (ClassNotFoundException cnfe) {
0929: } catch (NoSuchMethodException nsme) {
0930: } catch (SecurityException se) {
0931: }
0932: }
0933:
0934: /**
0935: * The Rhino debugger instance.
0936: */
0937: protected Object debuggerInstance;
0938:
0939: /**
0940: * The JSVGViewerFrame.
0941: */
0942: protected JSVGViewerFrame svgFrame;
0943:
0944: /**
0945: * Creates a new Debugger.
0946: */
0947: public Debugger(JSVGViewerFrame frame, String url) {
0948: svgFrame = frame;
0949: try {
0950: debuggerInstance = debuggerConstructor
0951: .newInstance(new Object[] { "JavaScript Debugger - "
0952: + url });
0953: } catch (IllegalAccessException iae) {
0954: throw new RuntimeException(iae.getMessage());
0955: } catch (InvocationTargetException ite) {
0956: ite.printStackTrace();
0957: throw new RuntimeException(ite.getMessage());
0958: } catch (InstantiationException ie) {
0959: throw new RuntimeException(ie.getMessage());
0960: }
0961: }
0962:
0963: /**
0964: * Sets the document URL to use in the window title.
0965: */
0966: public void setDocumentURL(String url) {
0967: getDebugFrame().setTitle("JavaScript Debugger - " + url);
0968: }
0969:
0970: /**
0971: * Initializes the debugger by massaging the GUI and attaching it
0972: * to the Rhino interpreter's {@link
0973: * org.mozilla.javascript.ContextFactory}.
0974: */
0975: public void initialize() {
0976: // Customize the menubar a bit, disable menu
0977: // items that can't be used and change 'Exit' to 'Close'.
0978: JFrame debugGui = getDebugFrame();
0979: JMenuBar menuBar = debugGui.getJMenuBar();
0980: JMenu menu = menuBar.getMenu(0);
0981: menu.getItem(0).setEnabled(false); // Open...
0982: menu.getItem(1).setEnabled(false); // Run...
0983: menu.getItem(3).setText(Resources.getString("Close.text")); // Exit -> "Close"
0984: menu.getItem(3).setAccelerator(
0985: KeyStroke.getKeyStroke(KeyEvent.VK_W,
0986: Event.CTRL_MASK));
0987:
0988: debugGui.setSize(600, 460);
0989: debugGui.pack();
0990: setExitAction(new Runnable() {
0991: public void run() {
0992: svgFrame.hideDebugger();
0993: }
0994: });
0995: WindowAdapter wa = new WindowAdapter() {
0996: public void windowClosing(WindowEvent e) {
0997: svgFrame.hideDebugger();
0998: }
0999: };
1000: debugGui.addWindowListener(wa);
1001: debugGui.setVisible(true);
1002: attach();
1003: }
1004:
1005: /**
1006: * Attaches the debugger to the canvas' current interpreter.
1007: */
1008: public void attach() {
1009: Object interpreter = svgFrame.svgCanvas
1010: .getRhinoInterpreter();
1011: if (interpreter != null) {
1012: attachTo(getContextFactory(interpreter));
1013: }
1014: }
1015:
1016: /**
1017: * Calls {@code getDebugFrame} on {@link #debuggerInstance}.
1018: */
1019: protected JFrame getDebugFrame() {
1020: try {
1021: return (JFrame) debuggerMethods[GET_DEBUG_FRAME_METHOD]
1022: .invoke(debuggerInstance, (Object[]) null);
1023: } catch (InvocationTargetException ite) {
1024: throw new RuntimeException(ite.getMessage());
1025: } catch (IllegalAccessException iae) {
1026: throw new RuntimeException(iae.getMessage());
1027: }
1028: }
1029:
1030: /**
1031: * Calls {@code setExitAction} on {@link #debuggerInstance}.
1032: */
1033: protected void setExitAction(Runnable r) {
1034: try {
1035: debuggerMethods[SET_EXIT_ACTION_METHOD].invoke(
1036: debuggerInstance, new Object[] { r });
1037: } catch (InvocationTargetException ite) {
1038: throw new RuntimeException(ite.getMessage());
1039: } catch (IllegalAccessException iae) {
1040: throw new RuntimeException(iae.getMessage());
1041: }
1042: }
1043:
1044: /**
1045: * Calls {@code attachTo} on {@link #debuggerInstance}.
1046: */
1047: public void attachTo(Object contextFactory) {
1048: try {
1049: debuggerMethods[ATTACH_TO_METHOD].invoke(
1050: debuggerInstance,
1051: new Object[] { contextFactory });
1052: } catch (InvocationTargetException ite) {
1053: throw new RuntimeException(ite.getMessage());
1054: } catch (IllegalAccessException iae) {
1055: throw new RuntimeException(iae.getMessage());
1056: }
1057: }
1058:
1059: /**
1060: * Calls {@code detach} on {@link #debuggerInstance}.
1061: */
1062: public void detach() {
1063: try {
1064: debuggerMethods[DETACH_METHOD].invoke(debuggerInstance,
1065: (Object[]) null);
1066: } catch (InvocationTargetException ite) {
1067: throw new RuntimeException(ite.getMessage());
1068: } catch (IllegalAccessException iae) {
1069: throw new RuntimeException(iae.getMessage());
1070: }
1071: }
1072:
1073: /**
1074: * Calls {@code go} on {@link #debuggerInstance}.
1075: */
1076: public void go() {
1077: try {
1078: debuggerMethods[GO_METHOD].invoke(debuggerInstance,
1079: (Object[]) null);
1080: } catch (InvocationTargetException ite) {
1081: throw new RuntimeException(ite.getMessage());
1082: } catch (IllegalAccessException iae) {
1083: throw new RuntimeException(iae.getMessage());
1084: }
1085: }
1086:
1087: /**
1088: * Calls {@code clearAllBreakpoints} on {@link #debuggerInstance}.
1089: */
1090: public void clearAllBreakpoints() {
1091: try {
1092: debuggerMethods[CLEAR_ALL_BREAKPOINTS_METHOD].invoke(
1093: debuggerInstance, (Object[]) null);
1094: } catch (InvocationTargetException ite) {
1095: throw new RuntimeException(ite.getMessage());
1096: } catch (IllegalAccessException iae) {
1097: throw new RuntimeException(iae.getMessage());
1098: }
1099: }
1100:
1101: /**
1102: * Calls {@code dispose} on {@link #debuggerInstance}.
1103: */
1104: public void dispose() {
1105: try {
1106: debuggerMethods[DISPOSE_METHOD].invoke(
1107: debuggerInstance, (Object[]) null);
1108: } catch (InvocationTargetException ite) {
1109: throw new RuntimeException(ite.getMessage());
1110: } catch (IllegalAccessException iae) {
1111: throw new RuntimeException(iae.getMessage());
1112: }
1113: }
1114:
1115: /**
1116: * Calls {@code getContextFactory} on the given instance of
1117: * {@link org.apache.batik.script.rhino.RhinoInterpreter}.
1118: */
1119: protected Object getContextFactory(Object rhinoInterpreter) {
1120: try {
1121: return getContextFactoryMethod.invoke(rhinoInterpreter,
1122: (Object[]) null);
1123: } catch (InvocationTargetException ite) {
1124: throw new RuntimeException(ite.getMessage());
1125: } catch (IllegalAccessException iae) {
1126: throw new RuntimeException(iae.getMessage());
1127: }
1128: }
1129: }
1130:
1131: /**
1132: * To show the about dialog
1133: */
1134: public class AboutAction extends AbstractAction {
1135: public AboutAction() {
1136: }
1137:
1138: public void actionPerformed(ActionEvent e) {
1139: AboutDialog dlg = new AboutDialog(JSVGViewerFrame.this );
1140: // Work around pack() bug on some platforms
1141: dlg.setSize(dlg.getPreferredSize());
1142: dlg.setLocationRelativeTo(JSVGViewerFrame.this );
1143: dlg.setVisible(true);
1144: dlg.toFront();
1145: }
1146: }
1147:
1148: /**
1149: * To open a new file.
1150: */
1151: public class OpenAction extends AbstractAction {
1152:
1153: public OpenAction() {
1154: }
1155:
1156: public void actionPerformed(ActionEvent e) {
1157: File f = null;
1158: if (Platform.isOSX) {
1159: FileDialog fileDialog = new FileDialog(
1160: JSVGViewerFrame.this , Resources
1161: .getString(OPEN_TITLE));
1162: fileDialog.setFilenameFilter(new FilenameFilter() {
1163: public boolean accept(File dir, String name) {
1164: Iterator iter = getHandlers().iterator();
1165: while (iter.hasNext()) {
1166: SquiggleInputHandler handler = (SquiggleInputHandler) iter
1167: .next();
1168: if (handler.accept(new File(dir, name))) {
1169: return true;
1170: }
1171: }
1172: return false;
1173: }
1174: });
1175: fileDialog.setVisible(true);
1176: String filename = fileDialog.getFile();
1177: if (fileDialog != null) {
1178: String dirname = fileDialog.getDirectory();
1179: f = new File(dirname, filename);
1180: }
1181: } else {
1182: JFileChooser fileChooser = null;
1183:
1184: // Apply work around Windows problem when security is enabled,
1185: // and when prior to JDK 1.4.
1186: String os = System.getProperty(PROPERTY_OS_NAME,
1187: PROPERTY_OS_NAME_DEFAULT);
1188: SecurityManager sm = System.getSecurityManager();
1189:
1190: if (priorJDK1_4 && sm != null
1191: && os.indexOf(PROPERTY_OS_WINDOWS_PREFIX) != -1) {
1192: fileChooser = new JFileChooser(
1193: makeAbsolute(currentPath),
1194: new WindowsAltFileSystemView());
1195: } else {
1196: fileChooser = new JFileChooser(
1197: makeAbsolute(currentPath));
1198: }
1199:
1200: fileChooser.setFileHidingEnabled(false);
1201: fileChooser
1202: .setFileSelectionMode(JFileChooser.FILES_ONLY);
1203:
1204: //
1205: // Add file filters from the handlers map
1206: //
1207: Iterator iter = getHandlers().iterator();
1208: while (iter.hasNext()) {
1209: SquiggleInputHandler handler = (SquiggleInputHandler) iter
1210: .next();
1211: fileChooser
1212: .addChoosableFileFilter(new SquiggleInputHandlerFilter(
1213: handler));
1214: }
1215:
1216: int choice = fileChooser
1217: .showOpenDialog(JSVGViewerFrame.this );
1218: if (choice == JFileChooser.APPROVE_OPTION) {
1219: f = fileChooser.getSelectedFile();
1220: currentPath = f;
1221: }
1222: }
1223:
1224: if (f != null) {
1225: try {
1226: String furl = f.toURL().toString();
1227: showSVGDocument(furl);
1228: } catch (MalformedURLException ex) {
1229: if (userAgent != null) {
1230: userAgent.displayError(ex);
1231: }
1232: }
1233: }
1234: }
1235: }
1236:
1237: /**
1238: * Shows the given document into the viewer frame
1239: */
1240: public void showSVGDocument(String uri) {
1241: try {
1242: ParsedURL purl = new ParsedURL(uri);
1243: SquiggleInputHandler handler = getInputHandler(purl);
1244:
1245: handler.handle(purl, JSVGViewerFrame.this );
1246: } catch (Exception e) {
1247: if (userAgent != null) {
1248: userAgent.displayError(e);
1249: }
1250: }
1251:
1252: }
1253:
1254: /**
1255: * Returns the input handler for the given URI
1256: */
1257: public SquiggleInputHandler getInputHandler(ParsedURL purl)
1258: throws IOException {
1259: Iterator iter = getHandlers().iterator();
1260: SquiggleInputHandler handler = null;
1261:
1262: while (iter.hasNext()) {
1263: SquiggleInputHandler curHandler = (SquiggleInputHandler) iter
1264: .next();
1265: if (curHandler.accept(purl)) {
1266: handler = curHandler;
1267: break;
1268: }
1269: }
1270:
1271: // No handler found, use the default one.
1272: if (handler == null) {
1273: handler = defaultHandler;
1274: }
1275:
1276: return handler;
1277: }
1278:
1279: /**
1280: * Returns the list of input file handler.
1281: */
1282: protected static Vector getHandlers() {
1283: if (handlers != null) {
1284: return handlers;
1285: }
1286:
1287: handlers = new Vector();
1288: registerHandler(new SVGInputHandler());
1289:
1290: Iterator iter = Service.providers(SquiggleInputHandler.class);
1291: while (iter.hasNext()) {
1292: SquiggleInputHandler handler = (SquiggleInputHandler) iter
1293: .next();
1294:
1295: registerHandler(handler);
1296: }
1297:
1298: return handlers;
1299: }
1300:
1301: /**
1302: * Registers an input file handler by adding it to the handlers map.
1303: * @param handler the new input handler to register.
1304: */
1305: public static synchronized void registerHandler(
1306: SquiggleInputHandler handler) {
1307: Vector handlers = getHandlers();
1308: handlers.addElement(handler);
1309: }
1310:
1311: /**
1312: * To open a new document.
1313: */
1314: public class OpenLocationAction extends AbstractAction {
1315: public OpenLocationAction() {
1316: }
1317:
1318: public void actionPerformed(ActionEvent e) {
1319: if (uriChooser == null) {
1320: uriChooser = new URIChooser(JSVGViewerFrame.this );
1321: uriChooser.setFileFilter(new SVGFileFilter());
1322: uriChooser.pack();
1323: Rectangle fr = getBounds();
1324: Dimension sd = uriChooser.getSize();
1325: uriChooser.setLocation(
1326: fr.x + (fr.width - sd.width) / 2, fr.y
1327: + (fr.height - sd.height) / 2);
1328: }
1329: if (uriChooser.showDialog() == URIChooser.OK_OPTION) {
1330: String s = uriChooser.getText();
1331: if (s == null)
1332: return;
1333: int i = s.indexOf('#');
1334: String t = "";
1335: if (i != -1) {
1336: t = s.substring(i + 1);
1337: s = s.substring(0, i);
1338: }
1339: if (!s.equals("")) {
1340: File f = new File(s);
1341: if (f.exists()) {
1342: if (f.isDirectory()) {
1343: s = null;
1344: } else {
1345: try {
1346: s = f.getCanonicalPath();
1347: if (s.startsWith("/")) {
1348: s = "file:" + s;
1349: } else {
1350: s = "file:/" + s;
1351: }
1352: } catch (IOException ex) {
1353: }
1354: }
1355: }
1356: if (s != null) {
1357: if (svgDocument != null) {
1358: ParsedURL docPURL = new ParsedURL(
1359: svgDocument.getURL());
1360: ParsedURL purl = new ParsedURL(docPURL, s);
1361: String fi = svgCanvas
1362: .getFragmentIdentifier();
1363: if (docPURL.equals(purl) && t.equals(fi)) {
1364: return;
1365: }
1366: }
1367: if (t.length() != 0) {
1368: s += '#' + t;
1369: }
1370:
1371: showSVGDocument(s);
1372: }
1373: }
1374: }
1375: }
1376: }
1377:
1378: /**
1379: * To open a new window.
1380: */
1381: public class NewWindowAction extends AbstractAction {
1382: public NewWindowAction() {
1383: }
1384:
1385: public void actionPerformed(ActionEvent e) {
1386: JSVGViewerFrame vf = application
1387: .createAndShowJSVGViewerFrame();
1388:
1389: // Copy the current settings to the new window.
1390: vf.autoAdjust = autoAdjust;
1391: vf.debug = debug;
1392: vf.svgCanvas.setProgressivePaint(svgCanvas
1393: .getProgressivePaint());
1394: vf.svgCanvas.setDoubleBufferedRendering(svgCanvas
1395: .getDoubleBufferedRendering());
1396: }
1397: }
1398:
1399: /**
1400: * To show the preferences.
1401: */
1402: public class PreferencesAction extends AbstractAction {
1403: public PreferencesAction() {
1404: }
1405:
1406: public void actionPerformed(ActionEvent e) {
1407: application.showPreferenceDialog(JSVGViewerFrame.this );
1408: }
1409: }
1410:
1411: /**
1412: * To close the last document.
1413: */
1414: public class CloseAction extends AbstractAction {
1415: public CloseAction() {
1416: }
1417:
1418: public void actionPerformed(ActionEvent e) {
1419: application.closeJSVGViewerFrame(JSVGViewerFrame.this );
1420: }
1421: }
1422:
1423: /**
1424: * To reload the current document.
1425: */
1426: public class ReloadAction extends AbstractAction {
1427: public ReloadAction() {
1428: }
1429:
1430: public void actionPerformed(ActionEvent e) {
1431: if ((e.getModifiers() & ActionEvent.SHIFT_MASK) == 1) {
1432: svgCanvas.flushImageCache();
1433: }
1434: if (svgDocument != null) {
1435: localHistory.reload();
1436: }
1437: }
1438: }
1439:
1440: /**
1441: * To go back to the previous document
1442: */
1443: public class BackAction extends AbstractAction implements
1444: JComponentModifier {
1445: List components = new LinkedList();
1446:
1447: public BackAction() {
1448: }
1449:
1450: public void actionPerformed(ActionEvent e) {
1451: if (localHistory.canGoBack()) {
1452: localHistory.back();
1453: }
1454: }
1455:
1456: public void addJComponent(JComponent c) {
1457: components.add(c);
1458: c.setEnabled(false);
1459: }
1460:
1461: protected void update() {
1462: boolean b = localHistory.canGoBack();
1463: Iterator it = components.iterator();
1464: while (it.hasNext()) {
1465: ((JComponent) it.next()).setEnabled(b);
1466: }
1467: }
1468: }
1469:
1470: /**
1471: * To go forward to the next document
1472: */
1473: public class ForwardAction extends AbstractAction implements
1474: JComponentModifier {
1475: List components = new LinkedList();
1476:
1477: public ForwardAction() {
1478: }
1479:
1480: public void actionPerformed(ActionEvent e) {
1481: if (localHistory.canGoForward()) {
1482: localHistory.forward();
1483: }
1484: }
1485:
1486: public void addJComponent(JComponent c) {
1487: components.add(c);
1488: c.setEnabled(false);
1489: }
1490:
1491: protected void update() {
1492: boolean b = localHistory.canGoForward();
1493: Iterator it = components.iterator();
1494: while (it.hasNext()) {
1495: ((JComponent) it.next()).setEnabled(b);
1496: }
1497: }
1498: }
1499:
1500: /**
1501: * To print the current document.
1502: */
1503: public class PrintAction extends AbstractAction {
1504: public PrintAction() {
1505: }
1506:
1507: public void actionPerformed(ActionEvent e) {
1508: if (svgDocument != null) {
1509: final SVGDocument doc = svgDocument;
1510: new Thread() {
1511: public void run() {
1512: String uri = doc.getURL();
1513: String fragment = svgCanvas
1514: .getFragmentIdentifier();
1515: if (fragment != null) {
1516: uri += '#' + fragment;
1517: }
1518:
1519: //
1520: // Build a PrintTranscoder to handle printing
1521: // of the svgDocument object
1522: //
1523: PrintTranscoder pt = new PrintTranscoder();
1524:
1525: //
1526: // Set transcoding hints
1527: //
1528: if (application.getXMLParserClassName() != null) {
1529: pt
1530: .addTranscodingHint(
1531: JPEGTranscoder.KEY_XML_PARSER_CLASSNAME,
1532: application
1533: .getXMLParserClassName());
1534: }
1535:
1536: pt.addTranscodingHint(
1537: PrintTranscoder.KEY_SHOW_PAGE_DIALOG,
1538: Boolean.TRUE);
1539:
1540: pt
1541: .addTranscodingHint(
1542: PrintTranscoder.KEY_SHOW_PRINTER_DIALOG,
1543: Boolean.TRUE);
1544:
1545: //
1546: // Do transcoding now
1547: //
1548: pt.transcode(new TranscoderInput(uri), null);
1549:
1550: //
1551: // Print
1552: //
1553: try {
1554: pt.print();
1555: } catch (PrinterException ex) {
1556: userAgent.displayError(ex);
1557: }
1558: }
1559: }.start();
1560: }
1561: }
1562: }
1563:
1564: /**
1565: * To save the current document as SVG.
1566: */
1567: public class SaveAsAction extends AbstractAction {
1568: public SaveAsAction() {
1569: }
1570:
1571: public void actionPerformed(ActionEvent e) {
1572: JFileChooser fileChooser;
1573: fileChooser = new JFileChooser(
1574: makeAbsolute(currentSavePath));
1575: fileChooser.setDialogTitle(resources
1576: .getString("SaveAs.title"));
1577: fileChooser.setFileHidingEnabled(false);
1578: fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
1579: fileChooser.addChoosableFileFilter(new ImageFileFilter(
1580: ".svg"));
1581:
1582: int choice = fileChooser
1583: .showSaveDialog(JSVGViewerFrame.this );
1584: if (choice != JFileChooser.APPROVE_OPTION)
1585: return;
1586:
1587: final File f = fileChooser.getSelectedFile();
1588:
1589: SVGOptionPanel sop;
1590: sop = SVGOptionPanel.showDialog(JSVGViewerFrame.this );
1591:
1592: final boolean useXMLBase = sop.getUseXMLBase();
1593: final boolean prettyPrint = sop.getPrettyPrint();
1594: sop = null;
1595:
1596: final SVGDocument svgDoc = svgCanvas.getSVGDocument();
1597: if (svgDoc == null)
1598: return;
1599:
1600: statusBar.setMessage(resources.getString("Message.saveAs"));
1601: currentSavePath = f;
1602: OutputStreamWriter w = null;
1603: try {
1604: OutputStream tos = null;
1605: tos = new FileOutputStream(f);
1606: tos = new BufferedOutputStream(tos);
1607: w = new OutputStreamWriter(tos, "utf-8");
1608: } catch (Exception ex) {
1609: userAgent.displayError(ex);
1610: return;
1611: }
1612:
1613: final OutputStreamWriter writer = w;
1614:
1615: final Runnable doneRun = new Runnable() {
1616: public void run() {
1617: String doneStr = resources
1618: .getString("Message.done");
1619: statusBar.setMessage(doneStr);
1620: }
1621: };
1622: Runnable r = new Runnable() {
1623: public void run() {
1624: try {
1625: // Write standard XML header.
1626: writer
1627: .write("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
1628: writer.write(EOL);
1629:
1630: Node fc = svgDoc.getFirstChild();
1631: if (fc.getNodeType() != Node.DOCUMENT_TYPE_NODE) {
1632: // Not DT node in Document, so
1633: // provide Document Type dec.
1634: writer.write("<!DOCTYPE svg PUBLIC '");
1635: writer.write(SVGConstants.SVG_PUBLIC_ID);
1636: writer.write("' '");
1637: writer.write(SVGConstants.SVG_SYSTEM_ID);
1638: writer.write("'>");
1639: writer.write(EOL);
1640: writer.write(EOL);
1641: }
1642: Element root = svgDoc.getRootElement();
1643: boolean doXMLBase = useXMLBase;
1644: if (root.hasAttributeNS(
1645: XMLConstants.XML_NAMESPACE_URI, "base"))
1646: doXMLBase = false;
1647:
1648: if (doXMLBase) {
1649: root.setAttributeNS(
1650: XMLConstants.XML_NAMESPACE_URI,
1651: "xml:base", svgDoc.getURL());
1652: }
1653:
1654: if (prettyPrint) {
1655: SVGTranscoder trans = new SVGTranscoder();
1656: trans.transcode(
1657: new TranscoderInput(svgDoc),
1658: new TranscoderOutput(writer));
1659: } else {
1660: DOMUtilities.writeDocument(svgDoc, writer);
1661: }
1662:
1663: writer.close();
1664:
1665: if (doXMLBase)
1666: root.removeAttributeNS(
1667: XMLConstants.XML_NAMESPACE_URI,
1668: "xml:base");
1669:
1670: if (EventQueue.isDispatchThread()) {
1671: doneRun.run();
1672: } else {
1673: EventQueue.invokeLater(doneRun);
1674: }
1675: } catch (Exception ex) {
1676: userAgent.displayError(ex);
1677: }
1678: }
1679: };
1680:
1681: UpdateManager um = svgCanvas.getUpdateManager();
1682: if ((um != null) && (um.isRunning())) {
1683: um.getUpdateRunnableQueue().invokeLater(r);
1684: } else {
1685: r.run();
1686: }
1687: }
1688: }
1689:
1690: /**
1691: * To save the current document as JPG.
1692: */
1693: public class ExportAsJPGAction extends AbstractAction {
1694: public ExportAsJPGAction() {
1695: }
1696:
1697: public void actionPerformed(ActionEvent e) {
1698: JFileChooser fileChooser = new JFileChooser(
1699: makeAbsolute(currentSavePath));
1700: fileChooser.setDialogTitle(resources
1701: .getString("ExportAsJPG.title"));
1702: fileChooser.setFileHidingEnabled(false);
1703: fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
1704: fileChooser.addChoosableFileFilter(new ImageFileFilter(
1705: ".jpg"));
1706:
1707: int choice = fileChooser
1708: .showSaveDialog(JSVGViewerFrame.this );
1709: if (choice == JFileChooser.APPROVE_OPTION) {
1710: float quality = JPEGOptionPanel
1711: .showDialog(JSVGViewerFrame.this );
1712:
1713: final File f = fileChooser.getSelectedFile();
1714: BufferedImage buffer = svgCanvas.getOffScreen();
1715: if (buffer != null) {
1716: statusBar.setMessage(resources
1717: .getString("Message.exportAsJPG"));
1718:
1719: // create a BufferedImage of the appropriate type
1720: int w = buffer.getWidth();
1721: int h = buffer.getHeight();
1722: final ImageTranscoder trans = new JPEGTranscoder();
1723: if (application.getXMLParserClassName() != null) {
1724: trans
1725: .addTranscodingHint(
1726: JPEGTranscoder.KEY_XML_PARSER_CLASSNAME,
1727: application
1728: .getXMLParserClassName());
1729: }
1730: trans.addTranscodingHint(
1731: JPEGTranscoder.KEY_QUALITY, new Float(
1732: quality));
1733:
1734: final BufferedImage img = trans.createImage(w, h);
1735:
1736: // paint the buffer to the image
1737: Graphics2D g2d = img.createGraphics();
1738: g2d.setColor(Color.white);
1739: g2d.fillRect(0, 0, w, h);
1740: g2d.drawImage(buffer, null, 0, 0);
1741: new Thread() {
1742: public void run() {
1743: try {
1744: currentSavePath = f;
1745: OutputStream ostream = new BufferedOutputStream(
1746: new FileOutputStream(f));
1747: trans.writeImage(img,
1748: new TranscoderOutput(ostream));
1749: ostream.close();
1750: } catch (Exception ex) {
1751: }
1752: statusBar.setMessage(resources
1753: .getString("Message.done"));
1754: }
1755: }.start();
1756: }
1757: }
1758: }
1759: }
1760:
1761: /**
1762: * To save the current document as PNG.
1763: */
1764: public class ExportAsPNGAction extends AbstractAction {
1765: public ExportAsPNGAction() {
1766: }
1767:
1768: public void actionPerformed(ActionEvent e) {
1769: JFileChooser fileChooser = new JFileChooser(
1770: makeAbsolute(currentSavePath));
1771: fileChooser.setDialogTitle(resources
1772: .getString("ExportAsPNG.title"));
1773: fileChooser.setFileHidingEnabled(false);
1774: fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
1775: fileChooser.addChoosableFileFilter(new ImageFileFilter(
1776: ".png"));
1777:
1778: int choice = fileChooser
1779: .showSaveDialog(JSVGViewerFrame.this );
1780: if (choice == JFileChooser.APPROVE_OPTION) {
1781:
1782: // Start: By Jun Inamori (jun@oop-reserch.com)
1783: boolean isIndexed = PNGOptionPanel
1784: .showDialog(JSVGViewerFrame.this );
1785: // End: By Jun Inamori (jun@oop-reserch.com)
1786:
1787: final File f = fileChooser.getSelectedFile();
1788: BufferedImage buffer = svgCanvas.getOffScreen();
1789: if (buffer != null) {
1790: statusBar.setMessage(resources
1791: .getString("Message.exportAsPNG"));
1792:
1793: // create a BufferedImage of the appropriate type
1794: int w = buffer.getWidth();
1795: int h = buffer.getHeight();
1796: final ImageTranscoder trans = new PNGTranscoder();
1797: if (application.getXMLParserClassName() != null) {
1798: trans
1799: .addTranscodingHint(
1800: JPEGTranscoder.KEY_XML_PARSER_CLASSNAME,
1801: application
1802: .getXMLParserClassName());
1803: }
1804: trans.addTranscodingHint(
1805: PNGTranscoder.KEY_FORCE_TRANSPARENT_WHITE,
1806: Boolean.TRUE);
1807:
1808: // Start: By Jun Inamori
1809: if (isIndexed) {
1810: trans.addTranscodingHint(
1811: PNGTranscoder.KEY_INDEXED, new Integer(
1812: 256));
1813: }
1814: // End: By Jun Inamori
1815:
1816: final BufferedImage img = trans.createImage(w, h);
1817:
1818: // paint the buffer to the image
1819: Graphics2D g2d = img.createGraphics();
1820: g2d.drawImage(buffer, null, 0, 0);
1821: new Thread() {
1822: public void run() {
1823: try {
1824: currentSavePath = f;
1825: OutputStream ostream = new BufferedOutputStream(
1826: new FileOutputStream(f));
1827: trans.writeImage(img,
1828: new TranscoderOutput(ostream));
1829: ostream.close();
1830: } catch (Exception ex) {
1831: }
1832: statusBar.setMessage(resources
1833: .getString("Message.done"));
1834: }
1835: }.start();
1836: }
1837: }
1838: }
1839: }
1840:
1841: /**
1842: * To save the current document as TIFF.
1843: */
1844: public class ExportAsTIFFAction extends AbstractAction {
1845: public ExportAsTIFFAction() {
1846: }
1847:
1848: public void actionPerformed(ActionEvent e) {
1849: JFileChooser fileChooser = new JFileChooser(
1850: makeAbsolute(currentSavePath));
1851: fileChooser.setDialogTitle(resources
1852: .getString("ExportAsTIFF.title"));
1853: fileChooser.setFileHidingEnabled(false);
1854: fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
1855: fileChooser.addChoosableFileFilter(new ImageFileFilter(
1856: ".tiff"));
1857:
1858: int choice = fileChooser
1859: .showSaveDialog(JSVGViewerFrame.this );
1860: if (choice == JFileChooser.APPROVE_OPTION) {
1861: final File f = fileChooser.getSelectedFile();
1862: BufferedImage buffer = svgCanvas.getOffScreen();
1863: if (buffer != null) {
1864: statusBar.setMessage(resources
1865: .getString("Message.exportAsTIFF"));
1866:
1867: // create a BufferedImage of the appropriate type
1868: int w = buffer.getWidth();
1869: int h = buffer.getHeight();
1870: final ImageTranscoder trans = new TIFFTranscoder();
1871: if (application.getXMLParserClassName() != null) {
1872: trans
1873: .addTranscodingHint(
1874: JPEGTranscoder.KEY_XML_PARSER_CLASSNAME,
1875: application
1876: .getXMLParserClassName());
1877: }
1878: final BufferedImage img = trans.createImage(w, h);
1879:
1880: // paint the buffer to the image
1881: Graphics2D g2d = img.createGraphics();
1882: g2d.drawImage(buffer, null, 0, 0);
1883: new Thread() {
1884: public void run() {
1885: try {
1886: currentSavePath = f;
1887: OutputStream ostream = new BufferedOutputStream(
1888: new FileOutputStream(f));
1889: trans.writeImage(img,
1890: new TranscoderOutput(ostream));
1891: ostream.close();
1892: } catch (Exception ex) {
1893: }
1894: statusBar.setMessage(resources
1895: .getString("Message.done"));
1896: }
1897: }.start();
1898: }
1899: }
1900: }
1901: }
1902:
1903: /**
1904: * To view the source of the current document.
1905: */
1906: public class ViewSourceAction extends AbstractAction {
1907: public ViewSourceAction() {
1908: }
1909:
1910: public void actionPerformed(ActionEvent e) {
1911: if (svgDocument == null) {
1912: return;
1913: }
1914:
1915: final ParsedURL u = new ParsedURL(svgDocument.getURL());
1916:
1917: final JFrame fr = new JFrame(u.toString());
1918: fr.setSize(resources.getInteger("ViewSource.width"),
1919: resources.getInteger("ViewSource.height"));
1920: final JTextArea ta = new JTextArea();
1921: ta.setLineWrap(true);
1922: ta.setFont(new Font("monospaced", Font.PLAIN, 12));
1923:
1924: JScrollPane scroll = new JScrollPane();
1925: scroll.getViewport().add(ta);
1926: scroll
1927: .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
1928: fr.getContentPane().add(scroll, BorderLayout.CENTER);
1929:
1930: new Thread() {
1931: public void run() {
1932: char[] buffer = new char[4096];
1933:
1934: try {
1935: Document doc = new PlainDocument();
1936:
1937: ParsedURL purl = new ParsedURL(svgDocument
1938: .getURL());
1939: InputStream is = u.openStream(getInputHandler(
1940: purl).getHandledMimeTypes());
1941: // u.openStream(MimeTypeConstants.MIME_TYPES_SVG);
1942:
1943: Reader in = XMLUtilities
1944: .createXMLDocumentReader(is);
1945: int len;
1946: while ((len = in.read(buffer, 0, buffer.length)) != -1) {
1947: doc.insertString(doc.getLength(),
1948: new String(buffer, 0, len), null);
1949: }
1950:
1951: ta.setDocument(doc);
1952: ta.setEditable(false);
1953: ta.setBackground(Color.white);
1954: fr.setVisible(true);
1955: } catch (Exception ex) {
1956: userAgent.displayError(ex);
1957: }
1958: }
1959: }.start();
1960: }
1961: }
1962:
1963: /**
1964: * To flush image cache (purely for debugging purposes)
1965: */
1966: public class FlushAction extends AbstractAction {
1967: public FlushAction() {
1968: }
1969:
1970: public void actionPerformed(ActionEvent e) {
1971: svgCanvas.flush();
1972: // Force redraw...
1973: svgCanvas.setRenderingTransform(svgCanvas
1974: .getRenderingTransform());
1975: }
1976: }
1977:
1978: /**
1979: * To toggle visiblity of JavaScript Debugger.
1980: */
1981: public class ToggleDebuggerAction extends AbstractAction {
1982: public ToggleDebuggerAction() {
1983: super ("Toggle Debugger Action");
1984: }
1985:
1986: public void actionPerformed(ActionEvent e) {
1987: if (debugger == null) {
1988: showDebugger();
1989: } else {
1990: hideDebugger();
1991: }
1992: }
1993: }
1994:
1995: /**
1996: * To go back to the previous transform
1997: */
1998: public class PreviousTransformAction extends AbstractAction
1999: implements JComponentModifier {
2000: List components = new LinkedList();
2001:
2002: public PreviousTransformAction() {
2003: }
2004:
2005: public void actionPerformed(ActionEvent e) {
2006: if (transformHistory.canGoBack()) {
2007: transformHistory.back();
2008: update();
2009: nextTransformAction.update();
2010: svgCanvas.setRenderingTransform(transformHistory
2011: .currentTransform());
2012: }
2013: }
2014:
2015: public void addJComponent(JComponent c) {
2016: components.add(c);
2017: c.setEnabled(false);
2018: }
2019:
2020: protected void update() {
2021: boolean b = transformHistory.canGoBack();
2022: Iterator it = components.iterator();
2023: while (it.hasNext()) {
2024: ((JComponent) it.next()).setEnabled(b);
2025: }
2026: }
2027: }
2028:
2029: /**
2030: * To go forward to the next transform
2031: */
2032: public class NextTransformAction extends AbstractAction implements
2033: JComponentModifier {
2034: List components = new LinkedList();
2035:
2036: public NextTransformAction() {
2037: }
2038:
2039: public void actionPerformed(ActionEvent e) {
2040: if (transformHistory.canGoForward()) {
2041: transformHistory.forward();
2042: update();
2043: previousTransformAction.update();
2044: svgCanvas.setRenderingTransform(transformHistory
2045: .currentTransform());
2046: }
2047: }
2048:
2049: public void addJComponent(JComponent c) {
2050: components.add(c);
2051: c.setEnabled(false);
2052: }
2053:
2054: protected void update() {
2055: boolean b = transformHistory.canGoForward();
2056: Iterator it = components.iterator();
2057: while (it.hasNext()) {
2058: ((JComponent) it.next()).setEnabled(b);
2059: }
2060: }
2061: }
2062:
2063: /**
2064: * To apply the selected author stylesheet
2065: */
2066: public class UseStylesheetAction extends AbstractAction implements
2067: JComponentModifier {
2068:
2069: List components = new LinkedList();
2070:
2071: public UseStylesheetAction() {
2072: }
2073:
2074: public void actionPerformed(ActionEvent e) {
2075: }
2076:
2077: public void addJComponent(JComponent c) {
2078: components.add(c);
2079: c.setEnabled(false);
2080: }
2081:
2082: protected void update() {
2083: alternateStyleSheet = null;
2084: Iterator it = components.iterator();
2085: SVGDocument doc = svgCanvas.getSVGDocument();
2086: while (it.hasNext()) {
2087: JComponent stylesheetMenu = (JComponent) it.next();
2088: stylesheetMenu.removeAll();
2089: stylesheetMenu.setEnabled(false);
2090:
2091: ButtonGroup buttonGroup = new ButtonGroup();
2092:
2093: for (Node n = doc.getFirstChild(); n != null
2094: && n.getNodeType() != Node.ELEMENT_NODE; n = n
2095: .getNextSibling()) {
2096: if (n instanceof StyleSheetProcessingInstruction) {
2097: StyleSheetProcessingInstruction sspi;
2098: sspi = (StyleSheetProcessingInstruction) n;
2099: HashTable attrs = sspi.getPseudoAttributes();
2100: final String title = (String) attrs
2101: .get("title");
2102: String alt = (String) attrs.get("alternate");
2103: if (title != null && "yes".equals(alt)) {
2104: JRadioButtonMenuItem button;
2105: button = new JRadioButtonMenuItem(title);
2106:
2107: button
2108: .addActionListener(new java.awt.event.ActionListener() {
2109: public void actionPerformed(
2110: ActionEvent e) {
2111: SVGOMDocument doc;
2112: doc = (SVGOMDocument) svgCanvas
2113: .getSVGDocument();
2114: doc.clearViewCSS();
2115: alternateStyleSheet = title;
2116: svgCanvas
2117: .setSVGDocument(doc);
2118: }
2119: });
2120:
2121: buttonGroup.add(button);
2122: stylesheetMenu.add(button);
2123: stylesheetMenu.setEnabled(true);
2124: }
2125: }
2126: }
2127: }
2128: }
2129: }
2130:
2131: /**
2132: * To restart after a pause.
2133: */
2134: public class PlayAction extends AbstractAction implements
2135: JComponentModifier {
2136: List components = new LinkedList();
2137:
2138: public PlayAction() {
2139: }
2140:
2141: public void actionPerformed(ActionEvent e) {
2142: svgCanvas.resumeProcessing();
2143: }
2144:
2145: public void addJComponent(JComponent c) {
2146: components.add(c);
2147: c.setEnabled(false);
2148: }
2149:
2150: public void update(boolean enabled) {
2151: Iterator it = components.iterator();
2152: while (it.hasNext()) {
2153: ((JComponent) it.next()).setEnabled(enabled);
2154: }
2155: }
2156: }
2157:
2158: /**
2159: * To pause a document.
2160: */
2161: public class PauseAction extends AbstractAction implements
2162: JComponentModifier {
2163: List components = new LinkedList();
2164:
2165: public PauseAction() {
2166: }
2167:
2168: public void actionPerformed(ActionEvent e) {
2169: svgCanvas.suspendProcessing();
2170: }
2171:
2172: public void addJComponent(JComponent c) {
2173: components.add(c);
2174: c.setEnabled(false);
2175: }
2176:
2177: public void update(boolean enabled) {
2178: Iterator it = components.iterator();
2179: while (it.hasNext()) {
2180: ((JComponent) it.next()).setEnabled(enabled);
2181: }
2182: }
2183: }
2184:
2185: /**
2186: * To stop the current processing.
2187: */
2188: public class StopAction extends AbstractAction implements
2189: JComponentModifier {
2190: List components = new LinkedList();
2191:
2192: public StopAction() {
2193: }
2194:
2195: public void actionPerformed(ActionEvent e) {
2196: svgCanvas.stopProcessing();
2197: }
2198:
2199: public void addJComponent(JComponent c) {
2200: components.add(c);
2201: c.setEnabled(false);
2202: }
2203:
2204: public void update(boolean enabled) {
2205: Iterator it = components.iterator();
2206: while (it.hasNext()) {
2207: ((JComponent) it.next()).setEnabled(enabled);
2208: }
2209: }
2210: }
2211:
2212: /**
2213: * To show the set transform dialog
2214: */
2215: public class SetTransformAction extends AbstractAction {
2216: public SetTransformAction() {
2217: }
2218:
2219: public void actionPerformed(ActionEvent e) {
2220: if (transformDialog == null) {
2221: transformDialog = JAffineTransformChooser.createDialog(
2222: JSVGViewerFrame.this , resources
2223: .getString("SetTransform.title"));
2224: }
2225:
2226: AffineTransform txf = transformDialog.showDialog();
2227: if (txf != null) {
2228: AffineTransform at = svgCanvas.getRenderingTransform();
2229: if (at == null) {
2230: at = new AffineTransform();
2231: }
2232:
2233: txf.concatenate(at);
2234: svgCanvas.setRenderingTransform(txf);
2235: }
2236: }
2237: }
2238:
2239: /**
2240: * To display the memory monitor.
2241: */
2242: public class MonitorAction extends AbstractAction {
2243: public MonitorAction() {
2244: }
2245:
2246: public void actionPerformed(ActionEvent e) {
2247: if (memoryMonitorFrame == null) {
2248: memoryMonitorFrame = new MemoryMonitor();
2249: Rectangle fr = getBounds();
2250: Dimension md = memoryMonitorFrame.getSize();
2251: memoryMonitorFrame.setLocation(fr.x
2252: + (fr.width - md.width) / 2, fr.y
2253: + (fr.height - md.height) / 2);
2254: }
2255: memoryMonitorFrame.setVisible(true);
2256: }
2257: }
2258:
2259: /**
2260: * To display the Find dialog
2261: */
2262: public class FindDialogAction extends AbstractAction {
2263: public FindDialogAction() {
2264: }
2265:
2266: public void actionPerformed(ActionEvent e) {
2267: if (findDialog == null) {
2268: findDialog = new FindDialog(JSVGViewerFrame.this ,
2269: svgCanvas);
2270: findDialog.setGraphicsNode(svgCanvas.getGraphicsNode());
2271: findDialog.pack();
2272: Rectangle fr = getBounds();
2273: Dimension td = findDialog.getSize();
2274: findDialog.setLocation(
2275: fr.x + (fr.width - td.width) / 2, fr.y
2276: + (fr.height - td.height) / 2);
2277: }
2278: findDialog.setVisible(true);
2279: }
2280: }
2281:
2282: /**
2283: * To display the Thumbnail dialog
2284: */
2285: public class ThumbnailDialogAction extends AbstractAction {
2286: public ThumbnailDialogAction() {
2287: }
2288:
2289: public void actionPerformed(ActionEvent e) {
2290: if (thumbnailDialog == null) {
2291: thumbnailDialog = new ThumbnailDialog(
2292: JSVGViewerFrame.this , svgCanvas);
2293: thumbnailDialog.pack();
2294: Rectangle fr = getBounds();
2295: Dimension td = thumbnailDialog.getSize();
2296: thumbnailDialog.setLocation(fr.x
2297: + (fr.width - td.width) / 2, fr.y
2298: + (fr.height - td.height) / 2);
2299: }
2300: thumbnailDialog.setInteractionEnabled(!svgCanvas
2301: .getDisableInteractions());
2302: thumbnailDialog.setVisible(true);
2303: }
2304: }
2305:
2306: /**
2307: * To display the document full screen
2308: */
2309: public class FullScreenAction extends AbstractAction {
2310: public FullScreenAction() {
2311: }
2312:
2313: public void actionPerformed(ActionEvent e) {
2314: if (window == null || !window.isVisible()) {
2315: if (window == null) {
2316: window = new JWindow(JSVGViewerFrame.this );
2317: Dimension size = Toolkit.getDefaultToolkit()
2318: .getScreenSize();
2319: window.setSize(size);
2320: }
2321: // Go to full screen in JWindow)
2322: svgCanvas.getParent().remove(svgCanvas);
2323: window.getContentPane().add(svgCanvas);
2324: window.setVisible(true);
2325: window.toFront();
2326: svgCanvas.requestFocus();
2327: } else {
2328: // Go back to JSVGViewerFrame display
2329: svgCanvas.getParent().remove(svgCanvas);
2330: svgCanvasPanel.add(svgCanvas, BorderLayout.CENTER);
2331: window.setVisible(false);
2332: }
2333: }
2334: }
2335:
2336: /**
2337: * To display the DOM viewer of the document
2338: */
2339: public class DOMViewerAction extends AbstractAction {
2340: public DOMViewerAction() {
2341: }
2342:
2343: public void actionPerformed(ActionEvent e) {
2344: if (domViewer == null) {
2345: domViewer = new DOMViewer();
2346: if (svgDocument != null) {
2347: domViewer.setDocument(svgDocument,
2348: (ViewCSS) svgDocument.getDocumentElement());
2349: }
2350: Rectangle fr = getBounds();
2351: Dimension td = domViewer.getSize();
2352: domViewer.setLocation(fr.x + (fr.width - td.width) / 2,
2353: fr.y + (fr.height - td.height) / 2);
2354: }
2355: domViewer.setVisible(true);
2356: }
2357: }
2358:
2359: // ActionMap /////////////////////////////////////////////////////
2360:
2361: /**
2362: * The map that contains the action listeners
2363: */
2364: protected Map listeners = new HashMap();
2365:
2366: /**
2367: * Returns the action associated with the given string
2368: * or null on error
2369: * @param key the key mapped with the action to get
2370: * @throws MissingListenerException if the action is not found
2371: */
2372: public Action getAction(String key) throws MissingListenerException {
2373: Action result = (Action) listeners.get(key);
2374: //if (result == null) {
2375: //result = canvas.getAction(key);
2376: //}
2377: if (result == null) {
2378: throw new MissingListenerException("Can't find action.",
2379: RESOURCES, key);
2380: }
2381: return result;
2382: }
2383:
2384: // SVGDocumentLoaderListener ///////////////////////////////////////////
2385:
2386: long time; // For debug.
2387:
2388: /**
2389: * Called when the loading of a document was started.
2390: */
2391: public void documentLoadingStarted(SVGDocumentLoaderEvent e) {
2392: String msg = resources.getString("Message.documentLoad");
2393: if (debug) {
2394: System.out.println(msg);
2395: time = System.currentTimeMillis();
2396: }
2397: statusBar.setMainMessage(msg);
2398: stopAction.update(true);
2399: svgCanvas.setCursor(WAIT_CURSOR);
2400: }
2401:
2402: /**
2403: * Called when the loading of a document was completed.
2404: */
2405: public void documentLoadingCompleted(SVGDocumentLoaderEvent e) {
2406: if (debug) {
2407: System.out.print(resources
2408: .getString("Message.documentLoadTime"));
2409: System.out.println((System.currentTimeMillis() - time)
2410: + " ms");
2411: }
2412:
2413: setSVGDocument(e.getSVGDocument(), e.getSVGDocument().getURL(),
2414: e.getSVGDocument().getTitle());
2415: }
2416:
2417: /**
2418: * Forces the viewer frame to show the input SVGDocument
2419: */
2420: public void setSVGDocument(SVGDocument svgDocument,
2421: String svgDocumentURL, String svgDocumentTitle) {
2422: this .svgDocument = svgDocument;
2423:
2424: if (domViewer != null) {
2425: if (domViewer.isVisible() && svgDocument != null) {
2426: domViewer.setDocument(svgDocument,
2427: (ViewCSS) svgDocument.getDocumentElement());
2428: } else {
2429: domViewer.dispose();
2430: domViewer = null;
2431: }
2432: }
2433: stopAction.update(false);
2434: svgCanvas.setCursor(DEFAULT_CURSOR);
2435: String s = svgDocumentURL;
2436: locationBar.setText(s);
2437: if (debugger != null) {
2438: debugger.detach();
2439: debugger.setDocumentURL(s);
2440: }
2441: if (title == null) {
2442: title = getTitle();
2443: }
2444:
2445: String dt = svgDocumentTitle;
2446: if (dt.length() != 0) {
2447: setTitle(title + ": " + dt);
2448: } else {
2449: int i = s.lastIndexOf("/");
2450: if (i == -1)
2451: i = s.lastIndexOf("\\");
2452: if (i == -1) {
2453: setTitle(title + ": " + s);
2454: } else {
2455: setTitle(title + ": " + s.substring(i + 1));
2456: }
2457: }
2458:
2459: localHistory.update(s);
2460: application.addVisitedURI(s);
2461: backAction.update();
2462: forwardAction.update();
2463:
2464: transformHistory = new TransformHistory();
2465: previousTransformAction.update();
2466: nextTransformAction.update();
2467:
2468: useStylesheetAction.update();
2469: }
2470:
2471: /**
2472: * Called when the loading of a document was cancelled.
2473: */
2474: public void documentLoadingCancelled(SVGDocumentLoaderEvent e) {
2475: String msg = resources.getString("Message.documentCancelled");
2476: if (debug) {
2477: System.out.println(msg);
2478: }
2479: statusBar.setMainMessage("");
2480: statusBar.setMessage(msg);
2481: stopAction.update(false);
2482: svgCanvas.setCursor(DEFAULT_CURSOR);
2483: }
2484:
2485: /**
2486: * Called when the loading of a document has failed.
2487: */
2488: public void documentLoadingFailed(SVGDocumentLoaderEvent e) {
2489: String msg = resources.getString("Message.documentFailed");
2490: if (debug) {
2491: System.out.println(msg);
2492: }
2493: statusBar.setMainMessage("");
2494: statusBar.setMessage(msg);
2495: stopAction.update(false);
2496: svgCanvas.setCursor(DEFAULT_CURSOR);
2497: }
2498:
2499: // GVTTreeBuilderListener //////////////////////////////////////////////
2500:
2501: /**
2502: * Called when a build started.
2503: * The data of the event is initialized to the old document.
2504: */
2505: public void gvtBuildStarted(GVTTreeBuilderEvent e) {
2506: String msg = resources.getString("Message.treeBuild");
2507: if (debug) {
2508: System.out.println(msg);
2509: time = System.currentTimeMillis();
2510: }
2511: statusBar.setMainMessage(msg);
2512: stopAction.update(true);
2513: svgCanvas.setCursor(WAIT_CURSOR);
2514: }
2515:
2516: /**
2517: * Called when a build was completed.
2518: */
2519: public void gvtBuildCompleted(GVTTreeBuilderEvent e) {
2520: if (debug) {
2521: System.out.print(resources
2522: .getString("Message.treeBuildTime"));
2523: System.out.println((System.currentTimeMillis() - time)
2524: + " ms");
2525: }
2526: if (findDialog != null) {
2527: if (findDialog.isVisible()) {
2528: findDialog.setGraphicsNode(svgCanvas.getGraphicsNode());
2529: } else {
2530: findDialog.dispose();
2531: findDialog = null;
2532: }
2533: }
2534: stopAction.update(false);
2535: svgCanvas.setCursor(DEFAULT_CURSOR);
2536: svgCanvas.setSelectionOverlayXORMode(application
2537: .isSelectionOverlayXORMode());
2538: svgCanvas.requestFocus(); // request focus when load completes.
2539: if (debugger != null) {
2540: debugger.attach();
2541: }
2542: }
2543:
2544: /**
2545: * Called when a build was cancelled.
2546: */
2547: public void gvtBuildCancelled(GVTTreeBuilderEvent e) {
2548: String msg = resources.getString("Message.treeCancelled");
2549: if (debug) {
2550: System.out.println(msg);
2551: }
2552: statusBar.setMainMessage("");
2553: statusBar.setMessage(msg);
2554: stopAction.update(false);
2555: svgCanvas.setCursor(DEFAULT_CURSOR);
2556: svgCanvas.setSelectionOverlayXORMode(application
2557: .isSelectionOverlayXORMode());
2558: }
2559:
2560: /**
2561: * Called when a build failed.
2562: */
2563: public void gvtBuildFailed(GVTTreeBuilderEvent e) {
2564: String msg = resources.getString("Message.treeFailed");
2565: if (debug) {
2566: System.out.println(msg);
2567: }
2568: statusBar.setMainMessage("");
2569: statusBar.setMessage(msg);
2570: stopAction.update(false);
2571: svgCanvas.setCursor(DEFAULT_CURSOR);
2572: svgCanvas.setSelectionOverlayXORMode(application
2573: .isSelectionOverlayXORMode());
2574: if (autoAdjust) {
2575: pack();
2576: }
2577: }
2578:
2579: // SVGLoadEventDispatcherListener //////////////////////////////////////
2580:
2581: /**
2582: * Called when a onload event dispatch started.
2583: */
2584: public void svgLoadEventDispatchStarted(
2585: SVGLoadEventDispatcherEvent e) {
2586: String msg = resources.getString("Message.onload");
2587: if (debug) {
2588: System.out.println(msg);
2589: time = System.currentTimeMillis();
2590: }
2591: stopAction.update(true);
2592: statusBar.setMainMessage(msg);
2593: }
2594:
2595: /**
2596: * Called when a onload event dispatch was completed.
2597: */
2598: public void svgLoadEventDispatchCompleted(
2599: SVGLoadEventDispatcherEvent e) {
2600: if (debug) {
2601: System.out.print(resources.getString("Message.onloadTime"));
2602: System.out.println((System.currentTimeMillis() - time)
2603: + " ms");
2604: }
2605: stopAction.update(false);
2606: statusBar.setMainMessage("");
2607: statusBar.setMessage(resources.getString("Message.done"));
2608: }
2609:
2610: /**
2611: * Called when a onload event dispatch was cancelled.
2612: */
2613: public void svgLoadEventDispatchCancelled(
2614: SVGLoadEventDispatcherEvent e) {
2615: String msg = resources.getString("Message.onloadCancelled");
2616: if (debug) {
2617: System.out.println(msg);
2618: }
2619: stopAction.update(false);
2620: statusBar.setMainMessage("");
2621: statusBar.setMessage(msg);
2622: }
2623:
2624: /**
2625: * Called when a onload event dispatch failed.
2626: */
2627: public void svgLoadEventDispatchFailed(SVGLoadEventDispatcherEvent e) {
2628: String msg = resources.getString("Message.onloadFailed");
2629: if (debug) {
2630: System.out.println(msg);
2631: }
2632: stopAction.update(false);
2633: statusBar.setMainMessage("");
2634: statusBar.setMessage(msg);
2635: }
2636:
2637: // GVTTreeRendererListener /////////////////////////////////////////////
2638:
2639: /**
2640: * Called when a rendering is in its preparing phase.
2641: */
2642: public void gvtRenderingPrepare(GVTTreeRendererEvent e) {
2643: if (debug) {
2644: String msg = resources
2645: .getString("Message.treeRenderingPrep");
2646: System.out.println(msg);
2647: time = System.currentTimeMillis();
2648: }
2649: stopAction.update(true);
2650: svgCanvas.setCursor(WAIT_CURSOR);
2651: statusBar.setMainMessage(resources
2652: .getString("Message.treeRendering"));
2653: }
2654:
2655: /**
2656: * Called when a rendering started.
2657: */
2658: public void gvtRenderingStarted(GVTTreeRendererEvent e) {
2659: if (debug) {
2660: String msg = resources
2661: .getString("Message.treeRenderingPrepTime");
2662: System.out.print(msg);
2663: System.out.println((System.currentTimeMillis() - time)
2664: + " ms");
2665: time = System.currentTimeMillis();
2666: msg = resources.getString("Message.treeRenderingStart");
2667: System.out.println(msg);
2668: }
2669: // Do nothing
2670: }
2671:
2672: /**
2673: * Called when a rendering was completed.
2674: */
2675: public void gvtRenderingCompleted(GVTTreeRendererEvent e) {
2676: if (debug) {
2677: String msg = resources
2678: .getString("Message.treeRenderingTime");
2679: System.out.print(msg);
2680: System.out.println((System.currentTimeMillis() - time)
2681: + " ms");
2682: }
2683: statusBar.setMainMessage("");
2684: statusBar.setMessage(resources.getString("Message.done"));
2685: if (!svgCanvas.isDynamic() || managerStopped) {
2686: stopAction.update(false);
2687: }
2688: svgCanvas.setCursor(DEFAULT_CURSOR);
2689:
2690: transformHistory.update(svgCanvas.getRenderingTransform());
2691: previousTransformAction.update();
2692: nextTransformAction.update();
2693: }
2694:
2695: /**
2696: * Called when a rendering was cancelled.
2697: */
2698: public void gvtRenderingCancelled(GVTTreeRendererEvent e) {
2699: String msg = resources
2700: .getString("Message.treeRenderingCancelled");
2701: if (debug) {
2702: System.out.println(msg);
2703: }
2704: statusBar.setMainMessage("");
2705: statusBar.setMessage(msg);
2706: if (!svgCanvas.isDynamic()) {
2707: stopAction.update(false);
2708: }
2709: svgCanvas.setCursor(DEFAULT_CURSOR);
2710: }
2711:
2712: /**
2713: * Called when a rendering failed.
2714: */
2715: public void gvtRenderingFailed(GVTTreeRendererEvent e) {
2716: String msg = resources.getString("Message.treeRenderingFailed");
2717: if (debug) {
2718: System.out.println(msg);
2719: }
2720: statusBar.setMainMessage("");
2721: statusBar.setMessage(msg);
2722: if (!svgCanvas.isDynamic()) {
2723: stopAction.update(false);
2724: }
2725: svgCanvas.setCursor(DEFAULT_CURSOR);
2726: }
2727:
2728: // LinkActivationListener /////////////////////////////////////////
2729:
2730: /**
2731: * Called when a link was activated.
2732: */
2733: public void linkActivated(LinkActivationEvent e) {
2734: String s = e.getReferencedURI();
2735: if (svgDocument != null) {
2736: ParsedURL docURL = new ParsedURL(svgDocument.getURL());
2737: ParsedURL url = new ParsedURL(docURL, s);
2738: if (!url.sameFile(docURL)) {
2739: return;
2740: }
2741:
2742: if (s.indexOf('#') != -1) {
2743: localHistory.update(s);
2744: locationBar.setText(s);
2745: if (debugger != null) {
2746: debugger.detach();
2747: debugger.setDocumentURL(s);
2748: }
2749: application.addVisitedURI(s);
2750: backAction.update();
2751: forwardAction.update();
2752:
2753: transformHistory = new TransformHistory();
2754: previousTransformAction.update();
2755: nextTransformAction.update();
2756: }
2757: }
2758: }
2759:
2760: // UpdateManagerListener ////////////////////////////////////////////////
2761:
2762: /**
2763: * Called when the manager was started.
2764: */
2765: public void managerStarted(UpdateManagerEvent e) {
2766: if (debug) {
2767: String msg = resources
2768: .getString("Message.updateManagerStarted");
2769: System.out.println(msg);
2770: }
2771: managerStopped = false;
2772: playAction.update(false);
2773: pauseAction.update(true);
2774: stopAction.update(true);
2775: }
2776:
2777: /**
2778: * Called when the manager was suspended.
2779: */
2780: public void managerSuspended(UpdateManagerEvent e) {
2781: if (debug) {
2782: String msg = resources
2783: .getString("Message.updateManagerSuspended");
2784: System.out.println(msg);
2785: }
2786: playAction.update(true);
2787: pauseAction.update(false);
2788: }
2789:
2790: /**
2791: * Called when the manager was resumed.
2792: */
2793: public void managerResumed(UpdateManagerEvent e) {
2794: if (debug) {
2795: String msg = resources
2796: .getString("Message.updateManagerResumed");
2797: System.out.println(msg);
2798: }
2799: playAction.update(false);
2800: pauseAction.update(true);
2801: }
2802:
2803: /**
2804: * Called when the manager was stopped.
2805: */
2806: public void managerStopped(UpdateManagerEvent e) {
2807: if (debug) {
2808: String msg = resources
2809: .getString("Message.updateManagerStopped");
2810: System.out.println(msg);
2811: }
2812: managerStopped = true;
2813: playAction.update(false);
2814: pauseAction.update(false);
2815: stopAction.update(false);
2816: }
2817:
2818: /**
2819: * Called when an update started.
2820: */
2821: public void updateStarted(final UpdateManagerEvent e) {
2822: }
2823:
2824: /**
2825: * Called when an update was completed.
2826: */
2827: public void updateCompleted(final UpdateManagerEvent e) {
2828: }
2829:
2830: /**
2831: * Called when an update failed.
2832: */
2833: public void updateFailed(UpdateManagerEvent e) {
2834: }
2835:
2836: /**
2837: * This class implements a SVG user agent.
2838: */
2839: protected class UserAgent implements SVGUserAgent {
2840:
2841: /**
2842: * Creates a new SVGUserAgent.
2843: */
2844: protected UserAgent() {
2845: }
2846:
2847: /**
2848: * Displays an error message.
2849: */
2850: public void displayError(String message) {
2851: if (debug) {
2852: System.err.println(message);
2853: }
2854: JOptionPane pane = new JOptionPane(message,
2855: JOptionPane.ERROR_MESSAGE);
2856: JDialog dialog = pane.createDialog(JSVGViewerFrame.this ,
2857: "ERROR");
2858: dialog.setModal(false);
2859: dialog.setVisible(true);
2860: }
2861:
2862: /**
2863: * Displays an error resulting from the specified Exception.
2864: */
2865: public void displayError(Exception ex) {
2866: if (debug) {
2867: ex.printStackTrace();
2868: }
2869: JErrorPane pane = new JErrorPane(ex,
2870: JOptionPane.ERROR_MESSAGE);
2871: JDialog dialog = pane.createDialog(JSVGViewerFrame.this ,
2872: "ERROR");
2873: dialog.setModal(false);
2874: dialog.setVisible(true);
2875: }
2876:
2877: /**
2878: * Displays a message in the User Agent interface.
2879: * The given message is typically displayed in a status bar.
2880: */
2881: public void displayMessage(String message) {
2882: statusBar.setMessage(message);
2883: }
2884:
2885: /**
2886: * Shows an alert dialog box.
2887: */
2888: public void showAlert(String message) {
2889: svgCanvas.showAlert(message);
2890: }
2891:
2892: /**
2893: * Shows a prompt dialog box.
2894: */
2895: public String showPrompt(String message) {
2896: return svgCanvas.showPrompt(message);
2897: }
2898:
2899: /**
2900: * Shows a prompt dialog box.
2901: */
2902: public String showPrompt(String message, String defaultValue) {
2903: return svgCanvas.showPrompt(message, defaultValue);
2904: }
2905:
2906: /**
2907: * Shows a confirm dialog box.
2908: */
2909: public boolean showConfirm(String message) {
2910: return svgCanvas.showConfirm(message);
2911: }
2912:
2913: /**
2914: * Returns the size of a px CSS unit in millimeters.
2915: */
2916: public float getPixelUnitToMillimeter() {
2917: return 0.26458333333333333333333333333333f; // 96dpi
2918: }
2919:
2920: /**
2921: * Returns the size of a px CSS unit in millimeters.
2922: * This will be removed after next release.
2923: * @see #getPixelUnitToMillimeter()
2924: */
2925: public float getPixelToMM() {
2926: return getPixelUnitToMillimeter();
2927:
2928: }
2929:
2930: /**
2931: * Returns the default font family.
2932: */
2933: public String getDefaultFontFamily() {
2934: return application.getDefaultFontFamily();
2935: }
2936:
2937: /**
2938: * Returns the medium font size.
2939: */
2940: public float getMediumFontSize() {
2941: // 9pt (72pt == 1in)
2942: return 9f * 25.4f / (72f * getPixelUnitToMillimeter());
2943: }
2944:
2945: /**
2946: * Returns a lighter font-weight.
2947: */
2948: public float getLighterFontWeight(float f) {
2949: // Round f to nearest 100...
2950: int weight = ((int) ((f + 50) / 100)) * 100;
2951: switch (weight) {
2952: case 100:
2953: return 100;
2954: case 200:
2955: return 100;
2956: case 300:
2957: return 200;
2958: case 400:
2959: return 300;
2960: case 500:
2961: return 400;
2962: case 600:
2963: return 400;
2964: case 700:
2965: return 400;
2966: case 800:
2967: return 400;
2968: case 900:
2969: return 400;
2970: default:
2971: throw new IllegalArgumentException("Bad Font Weight: "
2972: + f);
2973: }
2974: }
2975:
2976: /**
2977: * Returns a bolder font-weight.
2978: */
2979: public float getBolderFontWeight(float f) {
2980: // Round f to nearest 100...
2981: int weight = ((int) ((f + 50) / 100)) * 100;
2982: switch (weight) {
2983: case 100:
2984: return 600;
2985: case 200:
2986: return 600;
2987: case 300:
2988: return 600;
2989: case 400:
2990: return 600;
2991: case 500:
2992: return 600;
2993: case 600:
2994: return 700;
2995: case 700:
2996: return 800;
2997: case 800:
2998: return 900;
2999: case 900:
3000: return 900;
3001: default:
3002: throw new IllegalArgumentException("Bad Font Weight: "
3003: + f);
3004: }
3005: }
3006:
3007: /**
3008: * Returns the language settings.
3009: */
3010: public String getLanguages() {
3011: return application.getLanguages();
3012: }
3013:
3014: /**
3015: * Returns the user stylesheet uri.
3016: * @return null if no user style sheet was specified.
3017: */
3018: public String getUserStyleSheetURI() {
3019: return application.getUserStyleSheetURI();
3020: }
3021:
3022: /**
3023: * Returns the class name of the XML parser.
3024: */
3025: public String getXMLParserClassName() {
3026: return application.getXMLParserClassName();
3027: }
3028:
3029: /**
3030: * Returns true if the XML parser must be in validation mode, false
3031: * otherwise.
3032: */
3033: public boolean isXMLParserValidating() {
3034: return application.isXMLParserValidating();
3035: }
3036:
3037: /**
3038: * Returns this user agent's CSS media.
3039: */
3040: public String getMedia() {
3041: return application.getMedia();
3042: }
3043:
3044: /**
3045: * Returns this user agent's alternate style-sheet title.
3046: */
3047: public String getAlternateStyleSheet() {
3048: return alternateStyleSheet;
3049: }
3050:
3051: /**
3052: * Opens a link.
3053: * @param uri The document URI.
3054: * @param newc Whether the link should be activated in a new component.
3055: */
3056: public void openLink(String uri, boolean newc) {
3057: if (newc) {
3058: application.openLink(uri);
3059: } else {
3060: showSVGDocument(uri);
3061: }
3062: }
3063:
3064: /**
3065: * Tells whether the given extension is supported by this
3066: * user agent.
3067: */
3068: public boolean supportExtension(String s) {
3069: return false;
3070: }
3071:
3072: public void handleElement(Element elt, Object data) {
3073: }
3074:
3075: /**
3076: * Returns the security settings for the given script
3077: * type, script url and document url
3078: *
3079: * @param scriptType type of script, as found in the
3080: * type attribute of the <script> element.
3081: * @param scriptURL url for the script, as defined in
3082: * the script's xlink:href attribute. If that
3083: * attribute was empty, then this parameter should
3084: * be null
3085: * @param docURL url for the document into which the
3086: * script was found.
3087: */
3088: public ScriptSecurity getScriptSecurity(String scriptType,
3089: ParsedURL scriptURL, ParsedURL docURL) {
3090: if (!application.canLoadScriptType(scriptType)) {
3091: return new NoLoadScriptSecurity(scriptType);
3092: } else {
3093: switch (application.getAllowedScriptOrigin()) {
3094: case ResourceOrigin.ANY:
3095: return new RelaxedScriptSecurity(scriptType,
3096: scriptURL, docURL);
3097: case ResourceOrigin.DOCUMENT:
3098: return new DefaultScriptSecurity(scriptType,
3099: scriptURL, docURL);
3100: case ResourceOrigin.EMBEDED:
3101: return new EmbededScriptSecurity(scriptType,
3102: scriptURL, docURL);
3103: default:
3104: return new NoLoadScriptSecurity(scriptType);
3105: }
3106: }
3107: }
3108:
3109: /**
3110: * This method throws a SecurityException if the script
3111: * of given type, found at url and referenced from docURL
3112: * should not be loaded.
3113: *
3114: * This is a convenience method to call checkLoadScript
3115: * on the ScriptSecurity strategy returned by
3116: * getScriptSecurity.
3117: *
3118: * @param scriptType type of script, as found in the
3119: * type attribute of the <script> element.
3120: * @param scriptURL url for the script, as defined in
3121: * the script's xlink:href attribute. If that
3122: * attribute was empty, then this parameter should
3123: * be null
3124: * @param docURL url for the document into which the
3125: * script was found.
3126: */
3127: public void checkLoadScript(String scriptType,
3128: ParsedURL scriptURL, ParsedURL docURL)
3129: throws SecurityException {
3130: ScriptSecurity s = getScriptSecurity(scriptType, scriptURL,
3131: docURL);
3132:
3133: if (s != null) {
3134: s.checkLoadScript();
3135: }
3136: }
3137:
3138: /**
3139: * Returns the security settings for the given
3140: * resource url and document url
3141: *
3142: * @param resourceURL url for the resource, as defined in
3143: * the resource's xlink:href attribute. If that
3144: * attribute was empty, then this parameter should
3145: * be null
3146: * @param docURL url for the document into which the
3147: * resource was found.
3148: */
3149: public ExternalResourceSecurity getExternalResourceSecurity(
3150: ParsedURL resourceURL, ParsedURL docURL) {
3151: switch (application.getAllowedExternalResourceOrigin()) {
3152: case ResourceOrigin.ANY:
3153: return new RelaxedExternalResourceSecurity(resourceURL,
3154: docURL);
3155: case ResourceOrigin.DOCUMENT:
3156: return new DefaultExternalResourceSecurity(resourceURL,
3157: docURL);
3158: case ResourceOrigin.EMBEDED:
3159: return new EmbededExternalResourceSecurity(resourceURL);
3160: default:
3161: return new NoLoadExternalResourceSecurity();
3162: }
3163: }
3164:
3165: /**
3166: * This method throws a SecurityException if the resource
3167: * found at url and referenced from docURL
3168: * should not be loaded.
3169: *
3170: * This is a convenience method to call checkLoadExternalResource
3171: * on the ExternalResourceSecurity strategy returned by
3172: * getExternalResourceSecurity.
3173: *
3174: * @param resourceURL url for the script, as defined in
3175: * the resource's xlink:href attribute. If that
3176: * attribute was empty, then this parameter should
3177: * be null
3178: * @param docURL url for the document into which the
3179: * resource was found.
3180: */
3181: public void checkLoadExternalResource(ParsedURL resourceURL,
3182: ParsedURL docURL) throws SecurityException {
3183: ExternalResourceSecurity s = getExternalResourceSecurity(
3184: resourceURL, docURL);
3185:
3186: if (s != null) {
3187: s.checkLoadExternalResource();
3188: }
3189: }
3190: }
3191:
3192: /**
3193: * A FileFilter used when exporting the SVG document as an image.
3194: */
3195: protected static class ImageFileFilter extends FileFilter {
3196:
3197: /** The extension of the image filename. */
3198: protected String extension;
3199:
3200: public ImageFileFilter(String extension) {
3201: this .extension = extension;
3202: }
3203:
3204: /**
3205: * Returns true if <tt>f</tt> is a file with the correct extension,
3206: * false otherwise.
3207: */
3208: public boolean accept(File f) {
3209: boolean accept = false;
3210: String fileName = null;
3211: if (f != null) {
3212: if (f.isDirectory()) {
3213: accept = true;
3214: } else {
3215: fileName = f.getPath().toLowerCase();
3216: if (fileName.endsWith(extension)) {
3217: accept = true;
3218: }
3219: }
3220: }
3221: return accept;
3222: }
3223:
3224: /**
3225: * Returns the file description
3226: */
3227: public String getDescription() {
3228: return extension;
3229: }
3230: }
3231: }
|