[9668] | 1 | // License: GPL. For details, see LICENSE file.
|
---|
| 2 | package org.openstreetmap.josm.actions.relation;
|
---|
| 3 |
|
---|
| 4 | import static org.openstreetmap.josm.tools.I18n.tr;
|
---|
| 5 |
|
---|
| 6 | import java.awt.Component;
|
---|
[9674] | 7 | import java.awt.Rectangle;
|
---|
[9668] | 8 | import java.awt.event.ActionEvent;
|
---|
| 9 | import java.awt.event.ActionListener;
|
---|
| 10 | import java.awt.event.KeyEvent;
|
---|
[9674] | 11 | import java.util.Collections;
|
---|
[9668] | 12 | import java.util.List;
|
---|
| 13 |
|
---|
| 14 | import javax.swing.AbstractAction;
|
---|
| 15 | import javax.swing.JMenuItem;
|
---|
| 16 | import javax.swing.JPopupMenu;
|
---|
| 17 | import javax.swing.KeyStroke;
|
---|
| 18 | import javax.swing.plaf.basic.BasicArrowButton;
|
---|
| 19 |
|
---|
[11610] | 20 | import org.openstreetmap.josm.actions.JosmAction;
|
---|
[12718] | 21 | import org.openstreetmap.josm.data.UndoRedoHandler.CommandQueueListener;
|
---|
[12663] | 22 | import org.openstreetmap.josm.data.osm.DefaultNameFormatter;
|
---|
[9668] | 23 | import org.openstreetmap.josm.data.osm.Relation;
|
---|
[12630] | 24 | import org.openstreetmap.josm.gui.MainApplication;
|
---|
[9668] | 25 | import org.openstreetmap.josm.gui.SideButton;
|
---|
[9674] | 26 | import org.openstreetmap.josm.gui.layer.Layer;
|
---|
| 27 | import org.openstreetmap.josm.gui.layer.OsmDataLayer;
|
---|
[9700] | 28 | import org.openstreetmap.josm.tools.ImageProvider;
|
---|
[9668] | 29 | import org.openstreetmap.josm.tools.Shortcut;
|
---|
| 30 |
|
---|
| 31 | /**
|
---|
| 32 | * Action for accessing recent relations.
|
---|
[11610] | 33 | * @since 9668
|
---|
[9668] | 34 | */
|
---|
[11869] | 35 | public class RecentRelationsAction extends JosmAction implements CommandQueueListener {
|
---|
[9668] | 36 |
|
---|
| 37 | private final SideButton editButton;
|
---|
| 38 | private final BasicArrowButton arrow;
|
---|
| 39 | private final Shortcut shortcut;
|
---|
[11610] | 40 | private final LaunchEditorAction launchAction;
|
---|
[9668] | 41 |
|
---|
| 42 | /**
|
---|
| 43 | * Constructs a new <code>RecentRelationsAction</code>.
|
---|
[9674] | 44 | * @param editButton edit button
|
---|
[9668] | 45 | */
|
---|
| 46 | public RecentRelationsAction(SideButton editButton) {
|
---|
[11610] | 47 | super(RecentRelationsAction.class.getName(), null, null, null, false, true);
|
---|
[9668] | 48 | this.editButton = editButton;
|
---|
| 49 | arrow = editButton.createArrow(this);
|
---|
| 50 | arrow.setToolTipText(tr("List of recent relations"));
|
---|
[12641] | 51 | MainApplication.undoRedo.addCommandQueueListener(this);
|
---|
[9668] | 52 | enableArrow();
|
---|
| 53 | shortcut = Shortcut.registerShortcut(
|
---|
| 54 | "relationeditor:editrecentrelation",
|
---|
| 55 | tr("Relation Editor: {0}", tr("Open recent relation")),
|
---|
| 56 | KeyEvent.VK_ESCAPE,
|
---|
| 57 | Shortcut.SHIFT
|
---|
| 58 | );
|
---|
[11610] | 59 | launchAction = new LaunchEditorAction();
|
---|
[12639] | 60 | MainApplication.registerActionShortcut(launchAction, shortcut);
|
---|
[9668] | 61 | }
|
---|
| 62 |
|
---|
[9674] | 63 | /**
|
---|
| 64 | * Enables arrow button.
|
---|
| 65 | */
|
---|
[9668] | 66 | public void enableArrow() {
|
---|
[11610] | 67 | if (arrow != null) {
|
---|
| 68 | arrow.setVisible(getLastRelation() != null);
|
---|
| 69 | }
|
---|
[9668] | 70 | }
|
---|
| 71 |
|
---|
[9674] | 72 | /**
|
---|
| 73 | * Returns the last relation.
|
---|
| 74 | * @return the last relation
|
---|
| 75 | */
|
---|
[9668] | 76 | public static Relation getLastRelation() {
|
---|
| 77 | List<Relation> recentRelations = getRecentRelationsOnActiveLayer();
|
---|
[9674] | 78 | if (recentRelations == null || recentRelations.isEmpty())
|
---|
| 79 | return null;
|
---|
[9668] | 80 | for (Relation relation: recentRelations) {
|
---|
[9674] | 81 | if (!isRelationListable(relation))
|
---|
| 82 | continue;
|
---|
[9668] | 83 | return relation;
|
---|
| 84 | }
|
---|
| 85 | return null;
|
---|
| 86 | }
|
---|
| 87 |
|
---|
[9674] | 88 | /**
|
---|
| 89 | * Determines if the given relation is listable in last relations.
|
---|
| 90 | * @param relation relation
|
---|
| 91 | * @return {@code true} if relation is non null, not deleted, and in current dataset
|
---|
| 92 | */
|
---|
[9668] | 93 | public static boolean isRelationListable(Relation relation) {
|
---|
| 94 | return relation != null &&
|
---|
| 95 | !relation.isDeleted() &&
|
---|
[12636] | 96 | MainApplication.getLayerManager().getEditDataSet().containsRelation(relation);
|
---|
[9668] | 97 | }
|
---|
| 98 |
|
---|
| 99 | @Override
|
---|
| 100 | public void actionPerformed(ActionEvent e) {
|
---|
| 101 | RecentRelationsPopupMenu.launch(editButton, shortcut.getKeyStroke());
|
---|
| 102 | }
|
---|
| 103 |
|
---|
| 104 | @Override
|
---|
| 105 | public void commandChanged(int queueSize, int redoSize) {
|
---|
| 106 | enableArrow();
|
---|
| 107 | }
|
---|
| 108 |
|
---|
| 109 | @Override
|
---|
[11610] | 110 | protected void updateEnabledState() {
|
---|
[9668] | 111 | enableArrow();
|
---|
| 112 | }
|
---|
| 113 |
|
---|
| 114 | @Override
|
---|
[11610] | 115 | public void destroy() {
|
---|
[12639] | 116 | MainApplication.unregisterActionShortcut(launchAction, shortcut);
|
---|
[11610] | 117 | super.destroy();
|
---|
[9668] | 118 | }
|
---|
| 119 |
|
---|
[9674] | 120 | /**
|
---|
| 121 | * Returns the list of recent relations on active layer.
|
---|
| 122 | * @return the list of recent relations on active layer
|
---|
| 123 | */
|
---|
[9668] | 124 | public static List<Relation> getRecentRelationsOnActiveLayer() {
|
---|
[12630] | 125 | if (!MainApplication.isDisplayingMapView())
|
---|
[9674] | 126 | return Collections.emptyList();
|
---|
[12636] | 127 | Layer activeLayer = MainApplication.getLayerManager().getActiveLayer();
|
---|
[9668] | 128 | if (!(activeLayer instanceof OsmDataLayer)) {
|
---|
[9674] | 129 | return Collections.emptyList();
|
---|
[9668] | 130 | } else {
|
---|
| 131 | return ((OsmDataLayer) activeLayer).getRecentRelations();
|
---|
| 132 | }
|
---|
| 133 | }
|
---|
| 134 |
|
---|
[11610] | 135 | static class LaunchEditorAction extends AbstractAction {
|
---|
[11348] | 136 | @Override
|
---|
| 137 | public void actionPerformed(ActionEvent e) {
|
---|
| 138 | EditRelationAction.launchEditor(getLastRelation());
|
---|
| 139 | }
|
---|
| 140 | }
|
---|
| 141 |
|
---|
[11610] | 142 | static class RecentRelationsPopupMenu extends JPopupMenu {
|
---|
[9668] | 143 | /**
|
---|
[9674] | 144 | * Constructs a new {@code RecentRelationsPopupMenu}.
|
---|
| 145 | * @param recentRelations list of recent relations
|
---|
| 146 | * @param keystroke key stroke for the first menu item
|
---|
[9668] | 147 | */
|
---|
[11610] | 148 | RecentRelationsPopupMenu(List<Relation> recentRelations, KeyStroke keystroke) {
|
---|
[9668] | 149 | boolean first = true;
|
---|
| 150 | for (Relation relation: recentRelations) {
|
---|
[9674] | 151 | if (!isRelationListable(relation))
|
---|
| 152 | continue;
|
---|
[9668] | 153 | JMenuItem menuItem = new RecentRelationsMenuItem(relation);
|
---|
| 154 | if (first) {
|
---|
| 155 | menuItem.setAccelerator(keystroke);
|
---|
| 156 | first = false;
|
---|
| 157 | }
|
---|
[9705] | 158 | menuItem.setIcon(ImageProvider.getPadded(relation, ImageProvider.ImageSizes.MENU.getImageDimension()));
|
---|
[9668] | 159 | add(menuItem);
|
---|
| 160 | }
|
---|
| 161 | }
|
---|
[9674] | 162 |
|
---|
[11610] | 163 | static void launch(Component parent, KeyStroke keystroke) {
|
---|
[9674] | 164 | Rectangle r = parent.getBounds();
|
---|
| 165 | new RecentRelationsPopupMenu(getRecentRelationsOnActiveLayer(), keystroke).show(parent, r.x, r.y + r.height);
|
---|
| 166 | }
|
---|
[9668] | 167 | }
|
---|
| 168 |
|
---|
| 169 | /**
|
---|
| 170 | * A specialized {@link JMenuItem} for presenting one entry of the relation history
|
---|
| 171 | */
|
---|
[11610] | 172 | static class RecentRelationsMenuItem extends JMenuItem implements ActionListener {
|
---|
| 173 | private final transient Relation relation;
|
---|
[9668] | 174 |
|
---|
[11610] | 175 | RecentRelationsMenuItem(Relation relation) {
|
---|
[9668] | 176 | super(relation.getDisplayName(DefaultNameFormatter.getInstance()));
|
---|
| 177 | this.relation = relation;
|
---|
| 178 | addActionListener(this);
|
---|
| 179 | }
|
---|
| 180 |
|
---|
| 181 | @Override
|
---|
| 182 | public void actionPerformed(ActionEvent e) {
|
---|
| 183 | EditRelationAction.launchEditor(relation);
|
---|
| 184 | }
|
---|
| 185 | }
|
---|
| 186 | }
|
---|