You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-commits@xmlgraphics.apache.org by ca...@apache.org on 2007/11/13 01:40:58 UTC
svn commit: r594367 [3/9] - in /xmlgraphics/batik/trunk: ./
resources/org/apache/batik/apps/svgbrowser/resources/
resources/org/apache/batik/util/gui/resources/
sources-1.3/org/apache/batik/util/ sources-1.3/org/apache/batik/util/gui/
sources-1.4/org/a...
Added: xmlgraphics/batik/trunk/sources/org/apache/batik/apps/svgbrowser/DropDownHistoryModel.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/apps/svgbrowser/DropDownHistoryModel.java?rev=594367&view=auto
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/apps/svgbrowser/DropDownHistoryModel.java (added)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/apps/svgbrowser/DropDownHistoryModel.java Mon Nov 12 16:40:53 2007
@@ -0,0 +1,395 @@
+/*
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ */
+package org.apache.batik.apps.svgbrowser;
+
+import java.util.ArrayList;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+import org.apache.batik.util.gui.DropDownComponent.DefaultScrollablePopupMenuItem;
+import org.apache.batik.util.gui.DropDownComponent.ScrollablePopupMenu;
+import org.apache.batik.util.gui.DropDownComponent.ScrollablePopupMenuEvent;
+import org.apache.batik.util.gui.DropDownComponent.ScrollablePopupMenuItem;
+import org.apache.batik.util.gui.DropDownComponent.ScrollablePopupMenuModel;
+import org.apache.batik.apps.svgbrowser.HistoryBrowser.CommandNamesInfo;
+import org.apache.batik.apps.svgbrowser.HistoryBrowser.HistoryBrowserAdapter;
+import org.apache.batik.apps.svgbrowser.HistoryBrowser.HistoryBrowserEvent;
+import org.apache.batik.util.resources.ResourceManager;
+
+/**
+ * The history scrollable popup menu model. Used for undo / redo drop down
+ * components.
+ *
+ * @version $Id$
+ */
+public class DropDownHistoryModel implements ScrollablePopupMenuModel {
+
+ /**
+ * The resource file name.
+ */
+ private static final String RESOURCES =
+ "org.apache.batik.apps.svgbrowser.resources.DropDownHistoryModelMessages";
+
+ /**
+ * The resource bundle.
+ */
+ private static ResourceBundle bundle;
+
+ /**
+ * The resource manager.
+ */
+ private static ResourceManager resources;
+ static {
+ bundle = ResourceBundle.getBundle(RESOURCES, Locale.getDefault());
+ resources = new ResourceManager(bundle);
+ }
+
+ /**
+ * Scrollable popup menu items.
+ */
+ protected ArrayList items = new ArrayList();
+
+ /**
+ * The history browser interface.
+ */
+ protected HistoryBrowserInterface historyBrowserInterface;
+
+ /**
+ * The parent scrollable popup menu.
+ */
+ protected ScrollablePopupMenu parent;
+
+ /**
+ * Creates the history pop up menu model.
+ *
+ * @param parent
+ * The parent ScrollablePopupMenu
+ * @param historyBrowserInterface
+ * The historyBrowserInterface. Used to update the parent pop
+ * up menu when the HistoryBrowser fires the events
+ */
+ public DropDownHistoryModel(ScrollablePopupMenu parent,
+ HistoryBrowserInterface historyBrowserInterface) {
+ this.parent = parent;
+ this.historyBrowserInterface = historyBrowserInterface;
+
+ // Handle the history reset event
+ historyBrowserInterface.getHistoryBrowser().addListener
+ (new HistoryBrowserAdapter() {
+ public void historyReset(HistoryBrowserEvent event) {
+ clearAllScrollablePopupMenuItems("");
+ }
+ });
+ }
+
+ /**
+ * Gets the footer text.
+ *
+ * @return footer text
+ */
+ public String getFooterText() {
+ return "";
+ }
+
+ /**
+ * Creates the ScrollablePopupMenuItem with the specific name.
+ *
+ * @param itemName
+ * the name of the item
+ * @return the item
+ */
+ public ScrollablePopupMenuItem createItem(String itemName) {
+ return new DefaultScrollablePopupMenuItem(parent, itemName);
+ }
+
+ /**
+ * Adds the ScrollablePopupMenuItem to the item list and to the parent.
+ * Fires the event 'itemsWereAdded' on the parent pop up menu
+ *
+ * @param item
+ * The item to add
+ * @param details
+ * The details for the 'itemsWereAdded' event
+ */
+ protected void addItem(ScrollablePopupMenuItem item, String details) {
+ int oldSize = items.size();
+ items.add(0, item);
+ parent.add(item, 0, oldSize, items.size());
+ parent.fireItemsWereAdded
+ (new ScrollablePopupMenuEvent(parent,
+ ScrollablePopupMenuEvent.ITEMS_ADDED,
+ 1,
+ details));
+ }
+
+ /**
+ * Removes the ScrollablePopupMenuItem from the item list and from the
+ * parent. Fires the event 'itemsWereRemoved' on the parent pop up menu
+ *
+ * @param item
+ * The item to remove
+ * @param details
+ * The details for the 'itemsWereRemoved' event
+ */
+ protected void removeItem(ScrollablePopupMenuItem item, String details) {
+ int oldSize = items.size();
+ items.remove(item);
+ parent.remove(item, oldSize, items.size());
+ parent.fireItemsWereRemoved
+ (new ScrollablePopupMenuEvent(parent,
+ ScrollablePopupMenuEvent.ITEMS_REMOVED,
+ 1,
+ details));
+ }
+
+ /**
+ * Removes the last scrollable popup menu item from the items list and
+ * from the parent pop up menu.
+ *
+ * @param details
+ * The details for the 'itemsWereRemoved' event
+ * @return True if item was successfully removed
+ */
+ protected boolean removeLastScrollablePopupMenuItem(String details) {
+ for (int i = items.size() - 1; i >= 0; i--) {
+ ScrollablePopupMenuItem item =
+ (ScrollablePopupMenuItem) items.get(i);
+ removeItem(item, details);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Removes the first scrollable popup menu item from the items list and
+ * from the parent pop up menu.
+ *
+ * @param details
+ * The details for the 'itemsWereRemoved' event
+ * @return True if item was successfully removed
+ */
+ protected boolean removeFirstScrollablePopupMenuItem(String details) {
+ for (int i = 0; i < items.size(); i++) {
+ ScrollablePopupMenuItem item =
+ (ScrollablePopupMenuItem) items.get(i);
+ removeItem(item, details);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Removes all scrollable popup menu items from the items list and from
+ * the parent pop up menu.
+ *
+ * @param details
+ * The details for the event
+ */
+ protected void clearAllScrollablePopupMenuItems(String details) {
+ while (removeLastScrollablePopupMenuItem(details)) {
+ }
+ }
+
+ /**
+ * Processes click on the pop up menu item.
+ */
+ public void processItemClicked() {
+ }
+
+ public void processBeforeShowed() {
+ // Performs current command from the history browser
+ historyBrowserInterface.performCurrentCompoundCommand();
+ }
+
+ public void processAfterShowed() {
+ }
+
+ /**
+ * The undo pop up menu model.
+ */
+ public static class UndoPopUpMenuModel extends DropDownHistoryModel {
+
+ /**
+ * The undo footer text. Used for the footer item.
+ */
+ protected static String UNDO_FOOTER_TEXT =
+ resources.getString("UndoModel.footerText");
+
+ /**
+ * The prefix for the last undoable command. E.g. (Undo change
+ * selection)
+ */
+ protected static String UNDO_TOOLTIP_PREFIX =
+ resources.getString("UndoModel.tooltipPrefix");
+
+ /**
+ * Creates the unod pop up menu model
+ *
+ * @param parent
+ * The parent scrollable popup menu
+ * @param historyBrowserInterface
+ * the historyBrowserInterface
+ */
+ public UndoPopUpMenuModel
+ (ScrollablePopupMenu parent,
+ HistoryBrowserInterface historyBrowserInterface) {
+
+ super(parent, historyBrowserInterface);
+ init();
+ }
+
+ /**
+ * Initializes this model. Adds the listeners to the history browser.
+ */
+ private void init() {
+ historyBrowserInterface.getHistoryBrowser().addListener
+ (new HistoryBrowserAdapter() {
+ public void executePerformed(HistoryBrowserEvent event) {
+ CommandNamesInfo info =
+ (CommandNamesInfo) event.getSource();
+ String details = UNDO_TOOLTIP_PREFIX
+ + info.getLastUndoableCommandName();
+ addItem(createItem(info.getCommandName()), details);
+ }
+
+ public void undoPerformed(HistoryBrowserEvent event) {
+ CommandNamesInfo info =
+ (CommandNamesInfo) event.getSource();
+ String details = UNDO_TOOLTIP_PREFIX
+ + info.getLastUndoableCommandName();
+ removeFirstScrollablePopupMenuItem(details);
+ }
+
+ public void redoPerformed(HistoryBrowserEvent event) {
+ CommandNamesInfo info =
+ (CommandNamesInfo) event.getSource();
+ String details = UNDO_TOOLTIP_PREFIX
+ + info.getLastUndoableCommandName();
+ addItem(createItem(info.getCommandName()), details);
+ }
+
+ public void doCompoundEdit(HistoryBrowserEvent event) {
+ if (!parent.isEnabled()) {
+ parent.setEnabled(true);
+ }
+ }
+
+ public void compoundEditPerformed
+ (HistoryBrowserEvent event) {
+ }
+ });
+ }
+
+ public String getFooterText() {
+ return UNDO_FOOTER_TEXT;
+ }
+
+ public void processItemClicked() {
+ historyBrowserInterface.getHistoryBrowser().compoundUndo
+ (parent.getSelectedItemsCount());
+ }
+ }
+
+ /**
+ * The redo pop up menu model.
+ */
+ public static class RedoPopUpMenuModel extends DropDownHistoryModel {
+
+ /**
+ * The redo footer text. Used for the footer item.
+ */
+ protected static String REDO_FOOTER_TEXT =
+ resources.getString("RedoModel.footerText");
+
+ /**
+ * The prefix for the last redoable command. E.g. (Redo change
+ * selection)
+ */
+ protected static String REDO_TOOLTIP_PREFIX =
+ resources.getString("RedoModel.tooltipPrefix");
+
+ /**
+ * Creates the redo pop up menu model
+ *
+ * @param parent
+ * The parent scrollable popup menu
+ * @param historyBrowserInterface
+ * the historyBrowserInterface
+ */
+ public RedoPopUpMenuModel
+ (ScrollablePopupMenu parent,
+ HistoryBrowserInterface historyBrowserInterface) {
+
+ super(parent, historyBrowserInterface);
+ init();
+ }
+
+ /**
+ * Initializes this model. Adds the listeners to the history browser.
+ */
+ private void init() {
+ historyBrowserInterface.getHistoryBrowser().addListener
+ (new HistoryBrowserAdapter() {
+
+ public void executePerformed(HistoryBrowserEvent event) {
+ CommandNamesInfo info =
+ (CommandNamesInfo) event.getSource();
+ String details = REDO_TOOLTIP_PREFIX
+ + info.getLastRedoableCommandName();
+ clearAllScrollablePopupMenuItems(details);
+ }
+
+ public void undoPerformed(HistoryBrowserEvent event) {
+ CommandNamesInfo info =
+ (CommandNamesInfo) event.getSource();
+ String details = REDO_TOOLTIP_PREFIX
+ + info.getLastRedoableCommandName();
+ addItem(createItem(info.getCommandName()), details);
+ }
+
+ public void redoPerformed(HistoryBrowserEvent event) {
+ CommandNamesInfo info =
+ (CommandNamesInfo) event.getSource();
+ String details = REDO_TOOLTIP_PREFIX
+ + info.getLastRedoableCommandName();
+ removeFirstScrollablePopupMenuItem(details);
+ }
+
+ public void doCompoundEdit(HistoryBrowserEvent event) {
+ if (parent.isEnabled()) {
+ parent.setEnabled(false);
+ }
+ }
+
+ public void compoundEditPerformed
+ (HistoryBrowserEvent event) {
+ }
+ });
+ }
+
+ public String getFooterText() {
+ return REDO_FOOTER_TEXT;
+ }
+
+ public void processItemClicked() {
+ historyBrowserInterface.getHistoryBrowser().compoundRedo
+ (parent.getSelectedItemsCount());
+ }
+ }
+}
Added: xmlgraphics/batik/trunk/sources/org/apache/batik/apps/svgbrowser/ElementOverlayController.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/apps/svgbrowser/ElementOverlayController.java?rev=594367&view=auto
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/apps/svgbrowser/ElementOverlayController.java (added)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/apps/svgbrowser/ElementOverlayController.java Mon Nov 12 16:40:53 2007
@@ -0,0 +1,32 @@
+/*
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ */
+package org.apache.batik.apps.svgbrowser;
+
+/**
+ * Provides the information to control the ElementOverlay.
+ *
+ * @version $Id$
+ */
+public interface ElementOverlayController {
+
+ /**
+ * Returns whether the ElementOverlay is enabled.
+ */
+ boolean isOverlayEnabled();
+}
Added: xmlgraphics/batik/trunk/sources/org/apache/batik/apps/svgbrowser/ElementOverlayManager.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/apps/svgbrowser/ElementOverlayManager.java?rev=594367&view=auto
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/apps/svgbrowser/ElementOverlayManager.java (added)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/apps/svgbrowser/ElementOverlayManager.java Mon Nov 12 16:40:53 2007
@@ -0,0 +1,347 @@
+/*
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ */
+package org.apache.batik.apps.svgbrowser;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.util.ArrayList;
+
+import org.apache.batik.gvt.GraphicsNode;
+import org.apache.batik.swing.JSVGCanvas;
+import org.apache.batik.swing.gvt.Overlay;
+
+import org.w3c.dom.Element;
+
+/**
+ * Manages element overlay on the canvas.
+ *
+ * @version $Id$
+ */
+public class ElementOverlayManager {
+
+ /**
+ * The color of the outline of the element overlay.
+ */
+ protected Color elementOverlayStrokeColor = Color.black;
+
+ /**
+ * The color of the element overlay.
+ */
+ protected Color elementOverlayColor = Color.white;
+
+ /**
+ * The xor mode.
+ */
+ protected boolean xorMode = true;
+
+ /**
+ * The canvas.
+ */
+ protected JSVGCanvas canvas;
+
+ /**
+ * The element overlay.
+ */
+ protected Overlay elementOverlay = new ElementOverlay();
+
+ /**
+ * Elements to paint.
+ */
+ protected ArrayList elements;
+
+ /**
+ * The controller for the element overlay.
+ */
+ protected ElementOverlayController controller;
+
+ /**
+ * Whether the ElementOverlay is enabled.
+ */
+ protected boolean isOverlayEnabled = true;
+
+ /**
+ * Constructor.
+ *
+ * @param canvas
+ * The parent canvas
+ */
+ public ElementOverlayManager(JSVGCanvas canvas) {
+ this.canvas = canvas;
+ elements = new ArrayList();
+ canvas.getOverlays().add(elementOverlay);
+ }
+
+ /**
+ * Adds an element to the element selection.
+ *
+ * @param elem
+ * The element to add
+ */
+ public void addElement(Element elem) {
+ elements.add(elem);
+ }
+
+ /**
+ * Removes the element from the element selection and adds its bound to the
+ * 'dirty' region.
+ *
+ * @param elem
+ * The element to remove
+ */
+ public void removeElement(Element elem) {
+ if (elements.remove(elem)) {
+// // Gets the area that should be repainted
+// Rectangle currentElementBounds = getElementBounds(elem);
+// if (dirtyArea == null) {
+// dirtyArea = currentElementBounds;
+// } else if (currentElementBounds != null) {
+// dirtyArea.add(currentElementBounds);
+// }
+ }
+ }
+
+ /**
+ * Removes all elements from the element selection list.
+ */
+ public void removeElements() {
+ elements.clear();
+ repaint();
+ }
+
+ /**
+ * Get the current selection bounds.
+ *
+ * @return the current selection bounds
+ */
+ protected Rectangle getAllElementsBounds() {
+ Rectangle resultBound = null;
+ int n = elements.size();
+ for (int i = 0; i < n; i++) {
+ Element currentElement = (Element) elements.get(i);
+ Rectangle currentBound = getElementBounds(currentElement);
+ if (resultBound == null) {
+ resultBound = currentBound;
+ } else {
+ resultBound.add(currentBound);
+ }
+ }
+ return resultBound;
+ }
+
+ /**
+ * The bounds of a given element.
+ *
+ * @param elem
+ * The given element
+ * @return Rectangle bounds
+ */
+ protected Rectangle getElementBounds(Element elem) {
+ return getElementBounds(canvas.getUpdateManager().getBridgeContext()
+ .getGraphicsNode(elem));
+ }
+
+ /**
+ * The bounds of a given graphics node.
+ *
+ * @param node
+ * The given graphics node
+ * @return the bounds
+ */
+ protected Rectangle getElementBounds(GraphicsNode node) {
+ if (node == null) {
+ return null;
+ }
+ AffineTransform at = canvas.getRenderingTransform();
+ Shape s = at.createTransformedShape(node.getOutline());
+ return outset(s.getBounds(), 1);
+ }
+
+ /**
+ * Increases the given rectangle area for a given amount of units in a
+ * rectangle increasement manner.
+ *
+ * @param r
+ * The given rectangle
+ * @param amount
+ * The given amount of units
+ * @return <code>r</code>
+ */
+ protected Rectangle outset(Rectangle r, int amount) {
+ r.x -= amount;
+ r.y -= amount;
+ r.width += 2 * amount;
+ r.height += 2 * amount;
+ return r;
+ }
+
+ /**
+ * Repaints the canvas.
+ */
+ public void repaint() {
+ canvas.repaint();
+ }
+
+ /**
+ * The element overlay.
+ */
+ public class ElementOverlay implements Overlay {
+
+ /**
+ * Paints this overlay.
+ */
+ public void paint(Graphics g) {
+ if (controller.isOverlayEnabled() && isOverlayEnabled()) {
+ int n = elements.size();
+ for (int i = 0; i < n; i++) {
+ Element currentElement = (Element) elements.get(i);
+ GraphicsNode nodeToPaint = canvas.getUpdateManager()
+ .getBridgeContext().getGraphicsNode(currentElement);
+ if (nodeToPaint != null) {
+ AffineTransform elementsAt =
+ nodeToPaint.getGlobalTransform();
+ Shape selectionHighlight = nodeToPaint.getOutline();
+ AffineTransform at = canvas.getRenderingTransform();
+ at.concatenate(elementsAt);
+ Shape s = at.createTransformedShape(selectionHighlight);
+ if (s == null) {
+ break;
+ }
+ Graphics2D g2d = (Graphics2D) g;
+ if (xorMode) {
+ g2d.setColor(Color.black);
+ g2d.setXORMode(Color.yellow);
+ g2d.fill(s);
+ g2d.draw(s);
+ } else {
+ g2d.setColor(elementOverlayColor);
+ g2d.setStroke(new BasicStroke(1.8f));
+ g2d.setColor(elementOverlayStrokeColor);
+ g2d.draw(s);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Gets the elementOverlayColor.
+ *
+ * @return the elementOverlayColor
+ */
+ public Color getElementOverlayColor() {
+ return elementOverlayColor;
+ }
+
+ /**
+ * Sets the elementOverlayColor.
+ *
+ * @param elementOverlayColor
+ * the elementOverlayColor to set
+ */
+ public void setElementOverlayColor(Color selectionOverlayColor) {
+ this.elementOverlayColor = selectionOverlayColor;
+ }
+
+ /**
+ * Gets the elementOverlayStrokeColor.
+ *
+ * @return the elementOverlayStrokeColor
+ */
+ public Color getElementOverlayStrokeColor() {
+ return elementOverlayStrokeColor;
+ }
+
+ /**
+ * Sets the elementOverlayStrokeColor.
+ *
+ * @param elementOverlayStrokeColor
+ * the elementOverlayStrokeColor to set
+ */
+ public void setElementOverlayStrokeColor
+ (Color selectionOverlayStrokeColor) {
+ this.elementOverlayStrokeColor = selectionOverlayStrokeColor;
+ }
+
+ /**
+ * Gets the xorMode.
+ *
+ * @return the xorMode
+ */
+ public boolean isXorMode() {
+ return xorMode;
+ }
+
+ /**
+ * Sets the xor mode.
+ *
+ * @param xorMode
+ * the xorMode to set
+ */
+ public void setXorMode(boolean xorMode) {
+ this.xorMode = xorMode;
+ }
+
+ /**
+ * Gets the elementOverlay.
+ *
+ * @return the elementOverlay
+ */
+ public Overlay getElementOverlay() {
+ return elementOverlay;
+ }
+
+ /**
+ * Removes the elementOverlay.
+ */
+ public void removeOverlay() {
+ canvas.getOverlays().remove(elementOverlay);
+ }
+
+ /**
+ * Sets the element overlay controller.
+ *
+ * @param controller
+ * The element overlay controller
+ */
+ public void setController(ElementOverlayController controller) {
+ this.controller = controller;
+ }
+
+ /**
+ * If the element overlay is enabled.
+ *
+ * @return isOverlayEnabled
+ */
+ public boolean isOverlayEnabled() {
+ return isOverlayEnabled;
+ }
+
+ /**
+ * Enables / disables the Element overlay.
+ */
+ public void setOverlayEnabled(boolean isOverlayEnabled) {
+ this.isOverlayEnabled = isOverlayEnabled;
+ }
+}
Added: xmlgraphics/batik/trunk/sources/org/apache/batik/apps/svgbrowser/HistoryBrowser.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/trunk/sources/org/apache/batik/apps/svgbrowser/HistoryBrowser.java?rev=594367&view=auto
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/apps/svgbrowser/HistoryBrowser.java (added)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/apps/svgbrowser/HistoryBrowser.java Mon Nov 12 16:40:53 2007
@@ -0,0 +1,624 @@
+/*
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ */
+package org.apache.batik.apps.svgbrowser;
+
+import java.util.ArrayList;
+import java.util.EventListener;
+import java.util.EventObject;
+
+import javax.swing.event.EventListenerList;
+
+/**
+ * History browser. Manages perform of execute, undo and redo actions.
+ */
+public class HistoryBrowser {
+
+ // The history browser states. Show whether the history browser is busy
+ // performing execute, undo or redo, or whether is idle.
+ /**
+ * The history browser is executing the command(s).
+ */
+ public static final int EXECUTING = 1;
+
+ /**
+ * The history browser is undoing the command(s).
+ */
+ public static final int UNDOING = 2;
+
+ /**
+ * The history browser is redoing the command(s).
+ */
+ public static final int REDOING = 3;
+
+ /**
+ * The history browser is in idle state - no command is being executed,
+ * undone or redone.
+ */
+ public static final int IDLE = 4;
+
+ /**
+ * Listeners list.
+ */
+ protected EventListenerList eventListeners =
+ new EventListenerList();
+
+ /**
+ * Command history.
+ */
+ protected ArrayList history;
+
+ /**
+ * Current command pointer in history array.
+ */
+ protected int currentCommandIndex = -1;
+
+ /**
+ * History size.
+ */
+ protected int historySize = 1000;
+
+ /**
+ * The current state of the history browser.
+ */
+ protected int state = IDLE;
+
+ /**
+ * Tells the history browser how to execute, undo and redo the commands.
+ * Wraps the execute, undo and redo methods
+ */
+ protected CommandController commandController;
+
+ /**
+ * Constructor.
+ */
+ public HistoryBrowser(CommandController commandController) {
+ this.history = new ArrayList();
+ this.commandController = commandController;
+ }
+
+ /**
+ * Constructor.
+ * @param historySize History size
+ */
+ public HistoryBrowser(int historySize) {
+ this.history = new ArrayList();
+ setHistorySize(historySize);
+ }
+
+ /**
+ * Setter for the history size.
+ *
+ * @param size
+ * New history size
+ */
+ protected void setHistorySize(int size) {
+ historySize = size;
+ }
+
+ /**
+ * Sets the commandController.
+ *
+ * @param newCommandController
+ * The newCommandController to set
+ */
+ public void setCommandController(CommandController newCommandController) {
+ this.commandController = newCommandController;
+ }
+
+ /**
+ * Adds the given command to history array and executes it.
+ *
+ * @param command
+ * The given command
+ */
+ public void addCommand(UndoableCommand command) {
+ // When the command is added to history array, the commands from the
+ // current position to the end of the list are removed from history
+ int n = history.size();
+ for (int i = n - 1; i > currentCommandIndex; i--) {
+ history.remove(i);
+ }
+ // Executes the command
+ if (commandController != null) {
+ commandController.execute(command);
+ } else {
+ state = EXECUTING;
+ command.execute();
+ state = IDLE;
+ }
+ // Adds it to the history array
+ history.add(command);
+
+ // Updates the pointer to the current command
+ currentCommandIndex = history.size() - 1;
+ if (currentCommandIndex >= historySize) {
+ history.remove(0);
+ currentCommandIndex--;
+ }
+ fireExecutePerformed(new HistoryBrowserEvent(new CommandNamesInfo(
+ command.getName(), getLastUndoableCommandName(),
+ getLastRedoableCommandName())));
+ }
+
+ /**
+ * Undoes the last executed or 'redone' command.
+ */
+ public void undo() {
+ // If history is empty, or the current command index is out of bounds
+ if (history.isEmpty() || currentCommandIndex < 0) {
+ return;
+ }
+ // Gets the command and performs undo
+ UndoableCommand command = (UndoableCommand) history
+ .get(currentCommandIndex);
+ if (commandController != null) {
+ commandController.undo(command);
+ } else {
+ state = UNDOING;
+ command.undo();
+ state = IDLE;
+ }
+ // Updates the current command index
+ currentCommandIndex--;
+ fireUndoPerformed(new HistoryBrowserEvent(new CommandNamesInfo(command
+ .getName(), getLastUndoableCommandName(),
+ getLastRedoableCommandName())));
+ }
+
+ /**
+ * Redoes the last 'undone' command.
+ */
+ public void redo() {
+ // If history is empty, or the current command index is out of bounds
+ if (history.isEmpty() || currentCommandIndex == history.size() - 1) {
+ return;
+ }
+ // Increases the current command index and redoes the command
+ UndoableCommand command = (UndoableCommand) history
+ .get(++currentCommandIndex);
+ if (commandController != null) {
+ commandController.redo(command);
+ } else {
+ state = REDOING;
+ command.redo();
+ state = IDLE;
+ }
+ fireRedoPerformed(new HistoryBrowserEvent(new CommandNamesInfo(command
+ .getName(), getLastUndoableCommandName(),
+ getLastRedoableCommandName())));
+ }
+
+ /**
+ * Performs undo action the given number of times.
+ *
+ * @param undoNumber
+ * The given number of undo actions to perform
+ */
+ public void compoundUndo(int undoNumber) {
+ for (int i = 0; i < undoNumber; i++) {
+ undo();
+ }
+ }
+
+ /**
+ * Performs redo action the given number of times.
+ *
+ * @param redoNumber
+ * The given number of redo actions to perform
+ */
+ public void compoundRedo(int redoNumber) {
+ for (int i = 0; i < redoNumber; i++) {
+ redo();
+ }
+ }
+
+ /**
+ * Gets the last undoable command name.
+ *
+ * @return String or "" if there's no any
+ */
+ public String getLastUndoableCommandName() {
+ if (history.isEmpty() || currentCommandIndex < 0) {
+ return "";
+ }
+ return ((UndoableCommand) history.get(currentCommandIndex)).getName();
+ }
+
+ /**
+ * Gets the last redoable command name.
+ *
+ * @return String or "" if there's no any
+ */
+ public String getLastRedoableCommandName() {
+ if (history.isEmpty() || currentCommandIndex == history.size() - 1) {
+ return "";
+ }
+ return ((UndoableCommand) history.get(currentCommandIndex + 1))
+ .getName();
+ }
+
+ /**
+ * Clears the history array.
+ */
+ public void resetHistory() {
+ history.clear();
+ currentCommandIndex = -1;
+ fireHistoryReset(new HistoryBrowserEvent(new Object()));
+ }
+
+ /**
+ * Gets the state of this history browser.
+ *
+ * @return the state
+ */
+ public int getState() {
+ if (commandController != null) {
+ return commandController.getState();
+ } else {
+ return state;
+ }
+ }
+
+ // Custom event support
+
+ /**
+ * Event to pass to listener.
+ */
+ public static class HistoryBrowserEvent extends EventObject {
+
+ /**
+ * @param source
+ */
+ public HistoryBrowserEvent(Object source) {
+ super(source);
+ }
+ }
+
+ /**
+ * The HistoryBrowserListener.
+ */
+ public static interface HistoryBrowserListener extends EventListener {
+
+ /**
+ * The command has been executed.
+ */
+ void executePerformed(HistoryBrowserEvent event);
+
+ /**
+ * The undo has been performed on the command.
+ */
+ void undoPerformed(HistoryBrowserEvent event);
+
+ /**
+ * The redo has been performed on the command.
+ */
+ void redoPerformed(HistoryBrowserEvent event);
+
+ /**
+ * History has been reset, and all commands have been removed from the
+ * history.
+ */
+ void historyReset(HistoryBrowserEvent event);
+
+ /**
+ * The the atom command that should be wrapped with the compound command
+ * has been executed.
+ */
+ void doCompoundEdit(HistoryBrowserEvent event);
+
+ /**
+ * The compound command has been made from the atom commands that were
+ * executed and should be wrapped.
+ */
+ void compoundEditPerformed(HistoryBrowserEvent event);
+ }
+
+ /**
+ * The adapter to provide the default behavior.
+ */
+ public static class HistoryBrowserAdapter implements HistoryBrowserListener {
+
+ public void executePerformed(HistoryBrowserEvent event) {
+ }
+
+ public void undoPerformed(HistoryBrowserEvent event) {
+ }
+
+ public void redoPerformed(HistoryBrowserEvent event) {
+ }
+
+ public void historyReset(HistoryBrowserEvent event) {
+ }
+
+ public void compoundEditPerformed(HistoryBrowserEvent event) {
+ }
+
+ public void doCompoundEdit(HistoryBrowserEvent event) {
+ }
+ }
+
+ /**
+ * Adds the listener to the listener list.
+ *
+ * @param l
+ * The listener to add
+ */
+ public void addListener(HistoryBrowserListener listener) {
+ eventListeners.add(HistoryBrowserListener.class, listener);
+ }
+
+ /**
+ * Fires the executePerformed event.
+ *
+ * @param event
+ * The associated HistoryBrowserEvent event
+ */
+ public void fireExecutePerformed(HistoryBrowserEvent event) {
+ Object[] listeners = eventListeners.getListenerList();
+ int length = listeners.length;
+ for (int i = 0; i < length; i += 2) {
+ if (listeners[i] == HistoryBrowserListener.class) {
+ ((HistoryBrowserListener) listeners[i + 1])
+ .executePerformed(event);
+ }
+ }
+ }
+
+ /**
+ * Fires the undoPerformed event.
+ *
+ * @param event
+ * The associated HistoryBrowserEvent event
+ */
+ public void fireUndoPerformed(HistoryBrowserEvent event) {
+ Object[] listeners = eventListeners.getListenerList();
+ int length = listeners.length;
+ for (int i = 0; i < length; i += 2) {
+ if (listeners[i] == HistoryBrowserListener.class) {
+ ((HistoryBrowserListener) listeners[i + 1])
+ .undoPerformed(event);
+ }
+ }
+ }
+
+ /**
+ * Fires the redoPerformed event.
+ *
+ * @param event
+ * The associated HistoryBrowserEvent event
+ */
+ public void fireRedoPerformed(HistoryBrowserEvent event) {
+ Object[] listeners = eventListeners.getListenerList();
+ int length = listeners.length;
+ for (int i = 0; i < length; i += 2) {
+ if (listeners[i] == HistoryBrowserListener.class) {
+ ((HistoryBrowserListener) listeners[i + 1])
+ .redoPerformed(event);
+ }
+ }
+ }
+
+ /**
+ * Fires the historyReset event.
+ *
+ * @param event
+ * The associated HistoryBrowserEvent event
+ */
+ public void fireHistoryReset(HistoryBrowserEvent event) {
+ Object[] listeners = eventListeners.getListenerList();
+ int length = listeners.length;
+ for (int i = 0; i < length; i += 2) {
+ if (listeners[i] == HistoryBrowserListener.class) {
+ ((HistoryBrowserListener) listeners[i + 1])
+ .historyReset(event);
+ }
+ }
+ }
+
+ /**
+ * Fires the doCompoundEdit event.
+ *
+ * @param event
+ * The associated HistoryBrowserEvent event
+ */
+ public void fireDoCompoundEdit(HistoryBrowserEvent event) {
+ Object[] listeners = eventListeners.getListenerList();
+ int length = listeners.length;
+ for (int i = 0; i < length; i += 2) {
+ if (listeners[i] == HistoryBrowserListener.class) {
+ ((HistoryBrowserListener) listeners[i + 1])
+ .doCompoundEdit(event);
+ }
+ }
+ }
+
+ /**
+ * Fires the compoundEditPerformed event.
+ *
+ * @param event
+ * The associated HistoryBrowserEvent event
+ */
+ public void fireCompoundEditPerformed(HistoryBrowserEvent event) {
+ Object[] listeners = eventListeners.getListenerList();
+ int length = listeners.length;
+ for (int i = 0; i < length; i += 2) {
+ if (listeners[i] == HistoryBrowserListener.class) {
+ ((HistoryBrowserListener) listeners[i + 1])
+ .compoundEditPerformed(event);
+ }
+ }
+ }
+
+ /**
+ * Contains the info on the command name being executed, undone or redone and
+ * last undoable and redoable command names.
+ */
+ public static class CommandNamesInfo {
+
+ /**
+ * The name of the last undoable command in the history.
+ */
+ private String lastUndoableCommandName;
+
+ /**
+ * The name of the last redoable command in the history.
+ */
+ private String lastRedoableCommandName;
+
+ /**
+ * The command name being executed, undone or redone.
+ */
+ private String commandName;
+
+ /**
+ * Constructor.
+ *
+ * @param commandName
+ * The current command name being executed/undone/redone
+ * @param lastUndoableCommandName
+ * The last undoable command name
+ * @param lastRedoableCommandName
+ * The last redoable command name
+ */
+ public CommandNamesInfo(String commandName,
+ String lastUndoableCommandName,
+ String lastRedoableCommandName) {
+ this.lastUndoableCommandName = lastUndoableCommandName;
+ this.lastRedoableCommandName = lastRedoableCommandName;
+ this.commandName = commandName;
+ }
+
+ /**
+ * Gets the name of the last undoable command.
+ *
+ * @return the lastUndoableCommandName
+ */
+ public String getLastRedoableCommandName() {
+ return lastRedoableCommandName;
+ }
+
+ /**
+ * Gets the name of the last redoable command.
+ *
+ * @return the lastRedoableCommandName
+ */
+ public String getLastUndoableCommandName() {
+ return lastUndoableCommandName;
+ }
+
+ /**
+ * Gets the command name.
+ *
+ * @return the command name
+ */
+ public String getCommandName() {
+ return commandName;
+ }
+ }
+
+ /**
+ * Wrapps the command's execute, undo and redo methods.
+ */
+ public static interface CommandController {
+
+ /**
+ * Wrapps the execute method.
+ */
+ void execute(UndoableCommand command);
+
+ /**
+ * Wrapps the undo method.
+ */
+ void undo(UndoableCommand command);
+
+ /**
+ * Wrapps the redo method.
+ */
+ void redo(UndoableCommand command);
+
+ /**
+ * Gets the state of the command controller.
+ * @return HistoryBrowserState
+ */
+ int getState();
+ }
+
+ /**
+ * Lets the DOMViewerController wrap the commands.
+ */
+ public static class DocumentCommandController implements CommandController {
+
+ /**
+ * The DOMViewerController.
+ */
+ protected DOMViewerController controller;
+
+ /**
+ * The current state of the command controller.
+ */
+ protected int state = HistoryBrowser.IDLE;
+
+ /**
+ * The constructor.
+ *
+ * @param controller
+ * The DOMViewerController
+ */
+ public DocumentCommandController(DOMViewerController controller) {
+ this.controller = controller;
+ }
+
+ public void execute(final UndoableCommand command) {
+ Runnable r = new Runnable() {
+ public void run() {
+ state = HistoryBrowser.EXECUTING;
+ command.execute();
+ state = HistoryBrowser.IDLE;
+ }
+ };
+ controller.performUpdate(r);
+ }
+
+ public void undo(final UndoableCommand command) {
+ Runnable r = new Runnable() {
+ public void run() {
+ state = HistoryBrowser.UNDOING;
+ command.undo();
+ state = HistoryBrowser.IDLE;
+ }
+ };
+ controller.performUpdate(r);
+ }
+
+ public void redo(final UndoableCommand command) {
+ Runnable r = new Runnable() {
+ public void run() {
+ state = HistoryBrowser.REDOING;
+ command.redo();
+ state = HistoryBrowser.IDLE;
+ }
+ };
+ controller.performUpdate(r);
+ }
+
+ public int getState() {
+ return state;
+ }
+ }
+}