001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.actions; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.awt.event.ActionEvent; 007 008import javax.swing.AbstractAction; 009import javax.swing.event.ListSelectionEvent; 010import javax.swing.event.ListSelectionListener; 011 012import org.openstreetmap.josm.actions.AutoScaleAction.AutoScaleMode; 013import org.openstreetmap.josm.data.osm.OsmPrimitive; 014import org.openstreetmap.josm.gui.MainApplication; 015import org.openstreetmap.josm.gui.conflict.pair.nodes.NodeListTable; 016import org.openstreetmap.josm.gui.conflict.pair.relation.RelationMemberTable; 017import org.openstreetmap.josm.gui.dialogs.relation.MemberTable; 018import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent; 019import org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener; 020import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent; 021import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent; 022import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeEvent; 023import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeListener; 024import org.openstreetmap.josm.gui.layer.OsmDataLayer; 025import org.openstreetmap.josm.gui.widgets.OsmPrimitivesTable; 026import org.openstreetmap.josm.tools.CheckParameterUtil; 027 028/** 029 * An action that zooms to the selected OSM primitive in a table of primitives. 030 */ 031public class ZoomToAction extends AbstractAction implements LayerChangeListener, ActiveLayerChangeListener, ListSelectionListener { 032 033 private final OsmPrimitivesTable table; 034 035 private final String descriptionNominal; 036 private final String descriptionInactiveLayer; 037 private final String descriptionNoSelection; 038 039 /** 040 * Creates a new, generic zoom to action 041 * @param table The table to get the selected element from 042 * @param descriptionNominal The description to display if zooming is possible 043 * @param descriptionInactiveLayer The description to display if zooming is impossible because the layer is not active 044 * @param descriptionNoSelection The description to display if zooming is impossible because the table selection is empty 045 */ 046 public ZoomToAction(OsmPrimitivesTable table, String descriptionNominal, String descriptionInactiveLayer, String descriptionNoSelection) { 047 CheckParameterUtil.ensureParameterNotNull(table); 048 this.table = table; 049 this.descriptionNominal = descriptionNominal; 050 this.descriptionInactiveLayer = descriptionInactiveLayer; 051 this.descriptionNoSelection = descriptionNoSelection; 052 putValue(NAME, tr("Zoom to")); 053 putValue(SHORT_DESCRIPTION, descriptionNominal); 054 updateEnabledState(); 055 } 056 057 /** 058 * Creates a new zoom to action for a {@link MemberTable} using the matching description strings 059 * @param table The table to get the selected element from 060 */ 061 public ZoomToAction(MemberTable table) { 062 this(table, 063 tr("Zoom to the object the first selected member refers to"), 064 tr("Zooming disabled because layer of this relation is not active"), 065 tr("Zooming disabled because there is no selected member")); 066 } 067 068 /** 069 * Creates a new zoom to action for a {@link RelationMemberTable} using the matching description strings 070 * @param table The table to get the selected element from 071 */ 072 public ZoomToAction(RelationMemberTable table) { 073 this(table, 074 tr("Zoom to the object the first selected member refers to"), 075 tr("Zooming disabled because layer of this relation is not active"), 076 tr("Zooming disabled because there is no selected member")); 077 } 078 079 /** 080 * Creates a new zoom to action for a {@link NodeListTable} using the matching description strings 081 * @param table The table to get the selected element from 082 */ 083 public ZoomToAction(NodeListTable table) { 084 this(table, 085 tr("Zoom to the first selected node"), 086 tr("Zooming disabled because layer of this way is not active"), 087 tr("Zooming disabled because there is no selected node")); 088 } 089 090 @Override 091 public void actionPerformed(ActionEvent e) { 092 if (!isEnabled()) 093 return; 094 int[] rows = this.table.getSelectedRows(); 095 if (rows.length == 0) 096 return; 097 int row = rows[0]; 098 OsmDataLayer layer = this.table.getLayer(); 099 OsmPrimitive primitive = this.table.getPrimitiveInLayer(row, layer); 100 if (layer != null && primitive != null) { 101 layer.data.setSelected(primitive); 102 AutoScaleAction.autoScale(AutoScaleMode.SELECTION); 103 } 104 } 105 106 protected final void updateEnabledState() { 107 if (MainApplication.getLayerManager().getActiveDataLayer() != this.table.getLayer()) { 108 setEnabled(false); 109 putValue(SHORT_DESCRIPTION, descriptionInactiveLayer); 110 return; 111 } 112 if (this.table.getSelectedRowCount() == 0) { 113 setEnabled(false); 114 putValue(SHORT_DESCRIPTION, descriptionNoSelection); 115 return; 116 } 117 setEnabled(true); 118 putValue(SHORT_DESCRIPTION, descriptionNominal); 119 } 120 121 @Override 122 public void valueChanged(ListSelectionEvent e) { 123 updateEnabledState(); 124 } 125 126 @Override 127 public void activeOrEditLayerChanged(ActiveLayerChangeEvent e) { 128 updateEnabledState(); 129 } 130 131 @Override 132 public void layerAdded(LayerAddEvent e) { 133 updateEnabledState(); 134 } 135 136 @Override 137 public void layerRemoving(LayerRemoveEvent e) { 138 updateEnabledState(); 139 } 140 141 @Override 142 public void layerOrderChanged(LayerOrderChangeEvent e) { 143 // Do nothing 144 } 145}