- Timestamp:
- 2016-04-13T22:58:11+02:00 (9 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 11 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/validation/tests/PublicTransportRouteTest.java
r10141 r10144 76 76 && OsmPrimitiveType.NODE.equals(member.getType()) 77 77 && !routeNodes.contains(member.getNode())) { 78 errors.add(new TestError(this, Severity.WARNING, tr("Stop position not part of route"), 3603, Arrays.asList(member.getMember(), r))); 78 errors.add(new TestError(this, Severity.WARNING, 79 tr("Stop position not part of route"), 3603, Arrays.asList(member.getMember(), r))); 79 80 } 80 81 } 81 82 82 } 83 83 } -
trunk/src/org/openstreetmap/josm/gui/dialogs/LayerListDialog.java
r10142 r10144 8 8 import java.awt.Dimension; 9 9 import java.awt.Font; 10 import java.awt.GridBagLayout;11 10 import java.awt.Point; 12 11 import java.awt.Rectangle; … … 17 16 import java.beans.PropertyChangeEvent; 18 17 import java.beans.PropertyChangeListener; 19 import java.lang.ref.WeakReference;20 18 import java.util.ArrayList; 21 19 import java.util.Arrays; 22 import java.util.Collection;23 20 import java.util.Collections; 24 21 import java.util.List; … … 26 23 27 24 import javax.swing.AbstractAction; 28 import javax.swing.BorderFactory;29 25 import javax.swing.DefaultCellEditor; 30 26 import javax.swing.DefaultListSelectionModel; … … 33 29 import javax.swing.JComponent; 34 30 import javax.swing.JLabel; 35 import javax.swing.JMenuItem;36 import javax.swing.JPanel;37 import javax.swing.JPopupMenu;38 import javax.swing.JSlider;39 31 import javax.swing.JTable; 40 32 import javax.swing.JViewport; … … 42 34 import javax.swing.ListSelectionModel; 43 35 import javax.swing.UIManager; 44 import javax.swing.event.ChangeEvent;45 import javax.swing.event.ChangeListener;46 36 import javax.swing.event.ListDataEvent; 47 37 import javax.swing.event.ListSelectionEvent; … … 59 49 import org.openstreetmap.josm.gui.MapView; 60 50 import org.openstreetmap.josm.gui.SideButton; 61 import org.openstreetmap.josm.gui.help.HelpUtil; 62 import org.openstreetmap.josm.gui.layer.ImageryLayer; 51 import org.openstreetmap.josm.gui.dialogs.layer.ActivateLayerAction; 52 import org.openstreetmap.josm.gui.dialogs.layer.DeleteLayerAction; 53 import org.openstreetmap.josm.gui.dialogs.layer.DuplicateAction; 54 import org.openstreetmap.josm.gui.dialogs.layer.IEnabledStateUpdating; 55 import org.openstreetmap.josm.gui.dialogs.layer.LayerVisibilityAction; 56 import org.openstreetmap.josm.gui.dialogs.layer.MergeAction; 57 import org.openstreetmap.josm.gui.dialogs.layer.MoveDownAction; 58 import org.openstreetmap.josm.gui.dialogs.layer.MoveUpAction; 59 import org.openstreetmap.josm.gui.dialogs.layer.ShowHideLayerAction; 63 60 import org.openstreetmap.josm.gui.layer.JumpToMarkerActions; 64 61 import org.openstreetmap.josm.gui.layer.Layer; 65 import org.openstreetmap.josm.gui.layer.Layer.LayerAction;66 62 import org.openstreetmap.josm.gui.layer.NativeScaleLayer; 67 import org.openstreetmap.josm.gui.layer.OsmDataLayer;68 63 import org.openstreetmap.josm.gui.util.GuiHelper; 69 64 import org.openstreetmap.josm.gui.widgets.DisableShortcutsOnFocusGainedTextField; 70 65 import org.openstreetmap.josm.gui.widgets.JosmTextField; 71 66 import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher; 72 import org.openstreetmap.josm.tools.CheckParameterUtil;73 import org.openstreetmap.josm.tools.GBC;74 67 import org.openstreetmap.josm.tools.ImageProvider; 75 68 import org.openstreetmap.josm.tools.InputMapUtils; 76 69 import org.openstreetmap.josm.tools.MultikeyActionsHandler; 77 import org.openstreetmap.josm.tools.MultikeyShortcutAction;78 70 import org.openstreetmap.josm.tools.MultikeyShortcutAction.MultikeyInfo; 79 71 import org.openstreetmap.josm.tools.Shortcut; 80 import org.openstreetmap.josm.tools.Utils;81 72 82 73 /** … … 247 238 248 239 // -- move up action 249 MoveUpAction moveUpAction = new MoveUpAction( );240 MoveUpAction moveUpAction = new MoveUpAction(model); 250 241 adaptTo(moveUpAction, model); 251 242 adaptTo(moveUpAction, selectionModel); 252 243 253 244 // -- move down action 254 MoveDownAction moveDownAction = new MoveDownAction( );245 MoveDownAction moveDownAction = new MoveDownAction(model); 255 246 adaptTo(moveDownAction, model); 256 247 adaptTo(moveDownAction, selectionModel); 257 248 258 249 // -- activate action 259 activateLayerAction = new ActivateLayerAction( );250 activateLayerAction = new ActivateLayerAction(model); 260 251 activateLayerAction.updateEnabledState(); 261 252 MultikeyActionsHandler.getInstance().addAction(activateLayerAction); … … 265 256 266 257 // -- show hide action 267 showHideLayerAction = new ShowHideLayerAction( );258 showHideLayerAction = new ShowHideLayerAction(model); 268 259 MultikeyActionsHandler.getInstance().addAction(showHideLayerAction); 269 260 adaptTo(showHideLayerAction, selectionModel); … … 275 266 276 267 // -- delete layer action 277 DeleteLayerAction deleteLayerAction = new DeleteLayerAction( );268 DeleteLayerAction deleteLayerAction = new DeleteLayerAction(model); 278 269 layerList.getActionMap().put("deleteLayer", deleteLayerAction); 279 270 adaptTo(deleteLayerAction, selectionModel); … … 325 316 public LayerListModel getModel() { 326 317 return model; 327 }328 329 protected interface IEnabledStateUpdating {330 void updateEnabledState();331 318 } 332 319 … … 361 348 listModel.addTableModelListener( 362 349 new TableModelListener() { 363 364 350 @Override 365 351 public void tableChanged(TableModelEvent e) { … … 380 366 super.destroy(); 381 367 instance = null; 382 }383 384 /**385 * The action to delete the currently selected layer386 */387 public final class DeleteLayerAction extends AbstractAction implements IEnabledStateUpdating, LayerAction {388 389 /**390 * Creates a {@link DeleteLayerAction} which will delete the currently391 * selected layers in the layer dialog.392 */393 public DeleteLayerAction() {394 putValue(SMALL_ICON, ImageProvider.get("dialogs", "delete"));395 putValue(SHORT_DESCRIPTION, tr("Delete the selected layers."));396 putValue(NAME, tr("Delete"));397 putValue("help", HelpUtil.ht("/Dialog/LayerList#DeleteLayer"));398 updateEnabledState();399 }400 401 @Override402 public void actionPerformed(ActionEvent e) {403 List<Layer> selectedLayers = getModel().getSelectedLayers();404 if (selectedLayers.isEmpty())405 return;406 if (!Main.saveUnsavedModifications(selectedLayers, false))407 return;408 for (Layer l: selectedLayers) {409 Main.main.removeLayer(l);410 }411 }412 413 @Override414 public void updateEnabledState() {415 setEnabled(!getModel().getSelectedLayers().isEmpty());416 }417 418 @Override419 public Component createMenuComponent() {420 return new JMenuItem(this);421 }422 423 @Override424 public boolean supportLayers(List<Layer> layers) {425 return true;426 }427 428 @Override429 public boolean equals(Object obj) {430 return obj instanceof DeleteLayerAction;431 }432 433 @Override434 public int hashCode() {435 return getClass().hashCode();436 }437 }438 439 /**440 * Action which will toggle the visibility of the currently selected layers.441 */442 public final class ShowHideLayerAction extends AbstractAction implements IEnabledStateUpdating, LayerAction, MultikeyShortcutAction {443 444 private transient WeakReference<Layer> lastLayer;445 private final transient Shortcut multikeyShortcut;446 447 /**448 * Creates a {@link ShowHideLayerAction} which will toggle the visibility of449 * the currently selected layers450 */451 public ShowHideLayerAction() {452 putValue(NAME, tr("Show/hide"));453 putValue(SMALL_ICON, ImageProvider.get("dialogs", "showhide"));454 putValue(SHORT_DESCRIPTION, tr("Toggle visible state of the selected layer."));455 putValue("help", HelpUtil.ht("/Dialog/LayerList#ShowHideLayer"));456 multikeyShortcut = Shortcut.registerShortcut("core_multikey:showHideLayer", tr("Multikey: {0}",457 tr("Show/hide layer")), KeyEvent.VK_S, Shortcut.SHIFT);458 multikeyShortcut.setAccelerator(this);459 updateEnabledState();460 }461 462 @Override463 public Shortcut getMultikeyShortcut() {464 return multikeyShortcut;465 }466 467 @Override468 public void actionPerformed(ActionEvent e) {469 for (Layer l : model.getSelectedLayers()) {470 l.toggleVisible();471 }472 }473 474 @Override475 public void executeMultikeyAction(int index, boolean repeat) {476 Layer l = LayerListDialog.getLayerForIndex(index);477 if (l != null) {478 l.toggleVisible();479 lastLayer = new WeakReference<>(l);480 } else if (repeat && lastLayer != null) {481 l = lastLayer.get();482 if (LayerListDialog.isLayerValid(l)) {483 l.toggleVisible();484 }485 }486 }487 488 @Override489 public void updateEnabledState() {490 setEnabled(!model.getSelectedLayers().isEmpty());491 }492 493 @Override494 public Component createMenuComponent() {495 return new JMenuItem(this);496 }497 498 @Override499 public boolean supportLayers(List<Layer> layers) {500 return true;501 }502 503 @Override504 public boolean equals(Object obj) {505 return obj instanceof ShowHideLayerAction;506 }507 508 @Override509 public int hashCode() {510 return getClass().hashCode();511 }512 513 @Override514 public List<MultikeyInfo> getMultikeyCombinations() {515 return LayerListDialog.getLayerInfoByClass(Layer.class);516 }517 518 @Override519 public MultikeyInfo getLastMultikeyAction() {520 if (lastLayer != null)521 return LayerListDialog.getLayerInfo(lastLayer.get());522 return null;523 }524 }525 526 /**527 * This is a menu that includes all settings for the layer visibility. It combines gamma/opacity sliders and the visible-checkbox.528 *529 * @author Michael Zangl530 */531 public static final class LayerVisibilityAction extends AbstractAction implements IEnabledStateUpdating, LayerAction {532 protected static final int SLIDER_STEPS = 100;533 private static final double MAX_GAMMA_FACTOR = 2;534 private static final double MAX_SHARPNESS_FACTOR = 2;535 private static final double MAX_COLORFUL_FACTOR = 2;536 private final LayerListModel model;537 private final JPopupMenu popup;538 private SideButton sideButton;539 private JCheckBox visibilityCheckbox;540 final OpacitySlider opacitySlider = new OpacitySlider();541 private final ArrayList<FilterSlider<?>> sliders = new ArrayList<>();542 543 /**544 * Creates a new {@link LayerVisibilityAction}545 * @param model The list to get the selection from.546 */547 public LayerVisibilityAction(LayerListModel model) {548 this.model = model;549 popup = new JPopupMenu();550 551 // just to add a border552 JPanel content = new JPanel();553 popup.add(content);554 content.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));555 content.setLayout(new GridBagLayout());556 557 putValue(SMALL_ICON, ImageProvider.get("dialogs/layerlist", "visibility"));558 putValue(SHORT_DESCRIPTION, tr("Change visibility of the selected layer."));559 560 visibilityCheckbox = new JCheckBox(tr("Show layer"));561 visibilityCheckbox.addChangeListener(new ChangeListener() {562 @Override563 public void stateChanged(ChangeEvent e) {564 setVisibleFlag(visibilityCheckbox.isSelected());565 }566 });567 content.add(visibilityCheckbox, GBC.eop());568 569 addSlider(content, opacitySlider);570 addSlider(content, new ColorfulnessSlider());571 addSlider(content, new GammaFilterSlider());572 addSlider(content, new SharpnessSlider());573 }574 575 private void addSlider(JPanel content, FilterSlider<?> slider) {576 content.add(new JLabel(slider.getIcon()), GBC.std().span(1, 2).insets(0, 0, 5, 0));577 content.add(new JLabel(slider.getLabel()), GBC.eol());578 content.add(slider, GBC.eop());579 sliders.add(slider);580 }581 582 protected void setVisibleFlag(boolean visible) {583 for (Layer l : model.getSelectedLayers()) {584 l.setVisible(visible);585 }586 updateValues();587 }588 589 @Override590 public void actionPerformed(ActionEvent e) {591 updateValues();592 if (e.getSource() == sideButton) {593 popup.show(sideButton, 0, sideButton.getHeight());594 } else {595 // Action can be trigger either by opacity button or by popup menu (in case toggle buttons are hidden).596 // In that case, show it in the middle of screen (because opacityButton is not visible)597 popup.show(Main.parent, Main.parent.getWidth() / 2, (Main.parent.getHeight() - popup.getHeight()) / 2);598 }599 }600 601 protected void updateValues() {602 List<Layer> layers = model.getSelectedLayers();603 604 visibilityCheckbox.setEnabled(!layers.isEmpty());605 boolean allVisible = true;606 boolean allHidden = true;607 for (Layer l : layers) {608 allVisible &= l.isVisible();609 allHidden &= !l.isVisible();610 }611 // TODO: Indicate tristate.612 visibilityCheckbox.setSelected(allVisible && !allHidden);613 614 for (FilterSlider<?> slider : sliders) {615 slider.updateSlider(layers, allHidden);616 }617 }618 619 @Override620 public boolean supportLayers(List<Layer> layers) {621 return !layers.isEmpty();622 }623 624 @Override625 public Component createMenuComponent() {626 return new JMenuItem(this);627 }628 629 @Override630 public void updateEnabledState() {631 setEnabled(!model.getSelectedLayers().isEmpty());632 }633 634 /**635 * Sets the corresponding side button.636 * @param sideButton the corresponding side button637 */638 void setCorrespondingSideButton(SideButton sideButton) {639 this.sideButton = sideButton;640 }641 642 /**643 * This is a slider for a filter value.644 * @author Michael Zangl645 *646 * @param <T> The layer type.647 */648 private abstract class FilterSlider<T extends Layer> extends JSlider {649 private final double minValue;650 private final double maxValue;651 private final Class<T> layerClassFilter;652 653 /**654 * Create a new filter slider.655 * @param minValue The minimum value to map to the left side.656 * @param maxValue The maximum value to map to the right side.657 * @param layerClassFilter The type of layer influenced by this filter.658 */659 FilterSlider(double minValue, double maxValue, Class<T> layerClassFilter) {660 super(JSlider.HORIZONTAL);661 this.minValue = minValue;662 this.maxValue = maxValue;663 this.layerClassFilter = layerClassFilter;664 setMaximum(SLIDER_STEPS);665 int tick = convertFromRealValue(1);666 setMinorTickSpacing(tick);667 setMajorTickSpacing(tick);668 setPaintTicks(true);669 670 addChangeListener(new ChangeListener() {671 @Override672 public void stateChanged(ChangeEvent e) {673 onStateChanged();674 }675 });676 }677 678 /**679 * Called whenever the state of the slider was changed.680 * @see #getValueIsAdjusting()681 * @see #getRealValue()682 */683 protected void onStateChanged() {684 Collection<T> layers = filterLayers(model.getSelectedLayers());685 for (T layer : layers) {686 applyValueToLayer(layer);687 }688 }689 690 protected void applyValueToLayer(T layer) {691 }692 693 protected double getRealValue() {694 return convertToRealValue(getValue());695 }696 697 protected double convertToRealValue(int value) {698 double s = (double) value / SLIDER_STEPS;699 return s * maxValue + (1-s) * minValue;700 }701 702 protected void setRealValue(double value) {703 setValue(convertFromRealValue(value));704 }705 706 protected int convertFromRealValue(double value) {707 int i = (int) ((value - minValue) / (maxValue - minValue) * SLIDER_STEPS + .5);708 if (i < getMinimum()) {709 return getMinimum();710 } else if (i > getMaximum()) {711 return getMaximum();712 } else {713 return i;714 }715 }716 717 public abstract ImageIcon getIcon();718 719 public abstract String getLabel();720 721 public void updateSlider(List<Layer> layers, boolean allHidden) {722 Collection<? extends Layer> usedLayers = filterLayers(layers);723 if (usedLayers.isEmpty() || allHidden) {724 setEnabled(false);725 } else {726 setEnabled(true);727 updateSliderWhileEnabled(usedLayers, allHidden);728 }729 }730 731 protected Collection<T> filterLayers(List<Layer> layers) {732 return Utils.filteredCollection(layers, layerClassFilter);733 }734 735 protected abstract void updateSliderWhileEnabled(Collection<? extends Layer> usedLayers, boolean allHidden);736 }737 738 /**739 * This slider allows you to change the opacity of a layer.740 *741 * @author Michael Zangl742 * @see Layer#setOpacity(double)743 */744 class OpacitySlider extends FilterSlider<Layer> {745 /**746 * Creaate a new {@link OpacitySlider}.747 */748 OpacitySlider() {749 super(0, 1, Layer.class);750 setToolTipText(tr("Adjust opacity of the layer."));751 752 }753 754 @Override755 protected void onStateChanged() {756 if (getRealValue() <= 0.001 && !getValueIsAdjusting()) {757 setVisibleFlag(false);758 } else {759 super.onStateChanged();760 }761 }762 763 @Override764 protected void applyValueToLayer(Layer layer) {765 layer.setOpacity(getRealValue());766 }767 768 @Override769 protected void updateSliderWhileEnabled(Collection<? extends Layer> usedLayers, boolean allHidden) {770 double opacity = 0;771 for (Layer l : usedLayers) {772 opacity += l.getOpacity();773 }774 opacity /= usedLayers.size();775 if (opacity == 0) {776 opacity = 1;777 setVisibleFlag(true);778 }779 setRealValue(opacity);780 }781 782 @Override783 public String getLabel() {784 return tr("Opacity");785 }786 787 @Override788 public ImageIcon getIcon() {789 return ImageProvider.get("dialogs/layerlist", "transparency");790 }791 792 @Override793 public String toString() {794 return "OpacitySlider [getRealValue()=" + getRealValue() + "]";795 }796 }797 798 /**799 * This slider allows you to change the gamma value of a layer.800 *801 * @author Michael Zangl802 * @see ImageryLayer#setGamma(double)803 */804 private class GammaFilterSlider extends FilterSlider<ImageryLayer> {805 806 /**807 * Create a new {@link GammaFilterSlider}808 */809 GammaFilterSlider() {810 super(0, MAX_GAMMA_FACTOR, ImageryLayer.class);811 setToolTipText(tr("Adjust gamma value of the layer."));812 }813 814 @Override815 protected void updateSliderWhileEnabled(Collection<? extends Layer> usedLayers, boolean allHidden) {816 double gamma = ((ImageryLayer) usedLayers.iterator().next()).getGamma();817 setRealValue(gamma);818 }819 820 @Override821 protected void applyValueToLayer(ImageryLayer layer) {822 layer.setGamma(getRealValue());823 }824 825 @Override826 public ImageIcon getIcon() {827 return ImageProvider.get("dialogs/layerlist", "gamma");828 }829 830 @Override831 public String getLabel() {832 return tr("Gamma");833 }834 }835 836 /**837 * This slider allows you to change the sharpness of a layer.838 *839 * @author Michael Zangl840 * @see ImageryLayer#setSharpenLevel(double)841 */842 private class SharpnessSlider extends FilterSlider<ImageryLayer> {843 844 /**845 * Creates a new {@link SharpnessSlider}846 */847 SharpnessSlider() {848 super(0, MAX_SHARPNESS_FACTOR, ImageryLayer.class);849 setToolTipText(tr("Adjust sharpness/blur value of the layer."));850 }851 852 @Override853 protected void updateSliderWhileEnabled(Collection<? extends Layer> usedLayers, boolean allHidden) {854 setRealValue(((ImageryLayer) usedLayers.iterator().next()).getSharpenLevel());855 }856 857 @Override858 protected void applyValueToLayer(ImageryLayer layer) {859 layer.setSharpenLevel(getRealValue());860 }861 862 @Override863 public ImageIcon getIcon() {864 return ImageProvider.get("dialogs/layerlist", "sharpness");865 }866 867 @Override868 public String getLabel() {869 return tr("Sharpness");870 }871 }872 873 /**874 * This slider allows you to change the colorfulness of a layer.875 *876 * @author Michael Zangl877 * @see ImageryLayer#setColorfulness(double)878 */879 private class ColorfulnessSlider extends FilterSlider<ImageryLayer> {880 881 /**882 * Create a new {@link ColorfulnessSlider}883 */884 ColorfulnessSlider() {885 super(0, MAX_COLORFUL_FACTOR, ImageryLayer.class);886 setToolTipText(tr("Adjust colorfulness of the layer."));887 }888 889 @Override890 protected void updateSliderWhileEnabled(Collection<? extends Layer> usedLayers, boolean allHidden) {891 setRealValue(((ImageryLayer) usedLayers.iterator().next()).getColorfulness());892 }893 894 @Override895 protected void applyValueToLayer(ImageryLayer layer) {896 layer.setColorfulness(getRealValue());897 }898 899 @Override900 public ImageIcon getIcon() {901 return ImageProvider.get("dialogs/layerlist", "colorfulness");902 }903 904 @Override905 public String getLabel() {906 return tr("Colorfulness");907 }908 }909 }910 911 /**912 * The action to activate the currently selected layer913 */914 915 public final class ActivateLayerAction extends AbstractAction916 implements IEnabledStateUpdating, MapView.LayerChangeListener, MultikeyShortcutAction {917 private transient Layer layer;918 private transient Shortcut multikeyShortcut;919 920 /**921 * Constructs a new {@code ActivateLayerAction}.922 * @param layer the layer923 */924 public ActivateLayerAction(Layer layer) {925 this();926 CheckParameterUtil.ensureParameterNotNull(layer, "layer");927 this.layer = layer;928 putValue(NAME, tr("Activate"));929 updateEnabledState();930 }931 932 /**933 * Constructs a new {@code ActivateLayerAction}.934 */935 public ActivateLayerAction() {936 putValue(NAME, tr("Activate"));937 putValue(SMALL_ICON, ImageProvider.get("dialogs", "activate"));938 putValue(SHORT_DESCRIPTION, tr("Activate the selected layer"));939 multikeyShortcut = Shortcut.registerShortcut("core_multikey:activateLayer", tr("Multikey: {0}",940 tr("Activate layer")), KeyEvent.VK_A, Shortcut.SHIFT);941 multikeyShortcut.setAccelerator(this);942 putValue("help", HelpUtil.ht("/Dialog/LayerList#ActivateLayer"));943 }944 945 @Override946 public Shortcut getMultikeyShortcut() {947 return multikeyShortcut;948 }949 950 @Override951 public void actionPerformed(ActionEvent e) {952 Layer toActivate;953 if (layer != null) {954 toActivate = layer;955 } else {956 toActivate = model.getSelectedLayers().get(0);957 }958 execute(toActivate);959 }960 961 private void execute(Layer layer) {962 // model is going to be updated via LayerChangeListener and PropertyChangeEvents963 Main.map.mapView.setActiveLayer(layer);964 layer.setVisible(true);965 }966 967 protected boolean isActiveLayer(Layer layer) {968 if (!Main.isDisplayingMapView()) return false;969 return Main.map.mapView.getActiveLayer() == layer;970 }971 972 @Override973 public void updateEnabledState() {974 GuiHelper.runInEDTAndWait(new Runnable() {975 @Override976 public void run() {977 if (layer == null) {978 if (getModel().getSelectedLayers().size() != 1) {979 setEnabled(false);980 return;981 }982 Layer selectedLayer = getModel().getSelectedLayers().get(0);983 setEnabled(!isActiveLayer(selectedLayer));984 } else {985 setEnabled(!isActiveLayer(layer));986 }987 }988 });989 }990 991 @Override992 public void activeLayerChange(Layer oldLayer, Layer newLayer) {993 updateEnabledState();994 }995 996 @Override997 public void layerAdded(Layer newLayer) {998 updateEnabledState();999 }1000 1001 @Override1002 public void layerRemoved(Layer oldLayer) {1003 updateEnabledState();1004 }1005 1006 @Override1007 public void executeMultikeyAction(int index, boolean repeat) {1008 Layer l = LayerListDialog.getLayerForIndex(index);1009 if (l != null) {1010 execute(l);1011 }1012 }1013 1014 @Override1015 public List<MultikeyInfo> getMultikeyCombinations() {1016 return LayerListDialog.getLayerInfoByClass(Layer.class);1017 }1018 1019 @Override1020 public MultikeyInfo getLastMultikeyAction() {1021 return null; // Repeating action doesn't make much sense for activating1022 }1023 }1024 1025 /**1026 * The action to merge the currently selected layer into another layer.1027 */1028 public final class MergeAction extends AbstractAction implements IEnabledStateUpdating, LayerAction, Layer.MultiLayerAction {1029 private transient Layer layer;1030 private transient List<Layer> layers;1031 1032 /**1033 * Constructs a new {@code MergeAction}.1034 * @param layer the layer1035 * @throws IllegalArgumentException if {@code layer} is null1036 */1037 public MergeAction(Layer layer) {1038 this(layer, null);1039 CheckParameterUtil.ensureParameterNotNull(layer, "layer");1040 }1041 1042 /**1043 * Constructs a new {@code MergeAction}.1044 * @param layers the layer list1045 * @throws IllegalArgumentException if {@code layers} is null1046 */1047 public MergeAction(List<Layer> layers) {1048 this(null, layers);1049 CheckParameterUtil.ensureParameterNotNull(layers, "layers");1050 }1051 1052 /**1053 * Constructs a new {@code MergeAction}.1054 * @param layer the layer (null if layer list if specified)1055 * @param layers the layer list (null if a single layer is specified)1056 */1057 private MergeAction(Layer layer, List<Layer> layers) {1058 this.layer = layer;1059 this.layers = layers;1060 putValue(NAME, tr("Merge"));1061 putValue(SMALL_ICON, ImageProvider.get("dialogs", "mergedown"));1062 putValue(SHORT_DESCRIPTION, tr("Merge this layer into another layer"));1063 putValue("help", HelpUtil.ht("/Dialog/LayerList#MergeLayer"));1064 updateEnabledState();1065 }1066 1067 @Override1068 public void actionPerformed(ActionEvent e) {1069 if (layer != null) {1070 Main.main.menu.merge.merge(layer);1071 } else if (layers != null) {1072 Main.main.menu.merge.merge(layers);1073 } else {1074 if (getModel().getSelectedLayers().size() == 1) {1075 Layer selectedLayer = getModel().getSelectedLayers().get(0);1076 Main.main.menu.merge.merge(selectedLayer);1077 } else {1078 Main.main.menu.merge.merge(getModel().getSelectedLayers());1079 }1080 }1081 }1082 1083 @Override1084 public void updateEnabledState() {1085 if (layer == null && layers == null) {1086 if (getModel().getSelectedLayers().isEmpty()) {1087 setEnabled(false);1088 } else if (getModel().getSelectedLayers().size() > 1) {1089 setEnabled(supportLayers(getModel().getSelectedLayers()));1090 } else {1091 Layer selectedLayer = getModel().getSelectedLayers().get(0);1092 List<Layer> targets = getModel().getPossibleMergeTargets(selectedLayer);1093 setEnabled(!targets.isEmpty());1094 }1095 } else if (layer != null) {1096 List<Layer> targets = getModel().getPossibleMergeTargets(layer);1097 setEnabled(!targets.isEmpty());1098 } else {1099 setEnabled(supportLayers(layers));1100 }1101 }1102 1103 @Override1104 public boolean supportLayers(List<Layer> layers) {1105 if (layers.isEmpty()) {1106 return false;1107 } else {1108 final Layer firstLayer = layers.get(0);1109 final List<Layer> remainingLayers = layers.subList(1, layers.size());1110 return getModel().getPossibleMergeTargets(firstLayer).containsAll(remainingLayers);1111 }1112 }1113 1114 @Override1115 public Component createMenuComponent() {1116 return new JMenuItem(this);1117 }1118 1119 @Override1120 public MergeAction getMultiLayerAction(List<Layer> layers) {1121 return new MergeAction(layers);1122 }1123 }1124 1125 /**1126 * The action to merge the currently selected layer into another layer.1127 */1128 public final class DuplicateAction extends AbstractAction implements IEnabledStateUpdating {1129 private transient Layer layer;1130 1131 /**1132 * Constructs a new {@code DuplicateAction}.1133 * @param layer the layer1134 * @throws IllegalArgumentException if {@code layer} is null1135 */1136 public DuplicateAction(Layer layer) {1137 this();1138 CheckParameterUtil.ensureParameterNotNull(layer, "layer");1139 this.layer = layer;1140 updateEnabledState();1141 }1142 1143 /**1144 * Constructs a new {@code DuplicateAction}.1145 */1146 public DuplicateAction() {1147 putValue(NAME, tr("Duplicate"));1148 putValue(SMALL_ICON, ImageProvider.get("dialogs", "duplicatelayer"));1149 putValue(SHORT_DESCRIPTION, tr("Duplicate this layer"));1150 putValue("help", HelpUtil.ht("/Dialog/LayerList#DuplicateLayer"));1151 updateEnabledState();1152 }1153 1154 private void duplicate(Layer layer) {1155 if (!Main.isDisplayingMapView())1156 return;1157 1158 List<String> layerNames = new ArrayList<>();1159 for (Layer l: Main.map.mapView.getAllLayers()) {1160 layerNames.add(l.getName());1161 }1162 if (layer instanceof OsmDataLayer) {1163 OsmDataLayer oldLayer = (OsmDataLayer) layer;1164 // Translators: "Copy of {layer name}"1165 String newName = tr("Copy of {0}", oldLayer.getName());1166 int i = 2;1167 while (layerNames.contains(newName)) {1168 // Translators: "Copy {number} of {layer name}"1169 newName = tr("Copy {1} of {0}", oldLayer.getName(), i);1170 i++;1171 }1172 Main.main.addLayer(new OsmDataLayer(oldLayer.data.clone(), newName, null));1173 }1174 }1175 1176 @Override1177 public void actionPerformed(ActionEvent e) {1178 if (layer != null) {1179 duplicate(layer);1180 } else {1181 duplicate(getModel().getSelectedLayers().get(0));1182 }1183 }1184 1185 @Override1186 public void updateEnabledState() {1187 if (layer == null) {1188 if (getModel().getSelectedLayers().size() == 1) {1189 setEnabled(getModel().getSelectedLayers().get(0) instanceof OsmDataLayer);1190 } else {1191 setEnabled(false);1192 }1193 } else {1194 setEnabled(layer instanceof OsmDataLayer);1195 }1196 }1197 368 } 1198 369 … … 1342 513 1343 514 protected boolean isActiveLayer(Layer layer) { 1344 if (!Main.isDisplayingMapView()) return false; 515 if (!Main.isDisplayingMapView()) 516 return false; 1345 517 return Main.map.mapView.getActiveLayer() == layer; 1346 518 } … … 1408 580 1409 581 /** 1410 * The action to move up the currently selected entries in the list.1411 */1412 class MoveUpAction extends AbstractAction implements IEnabledStateUpdating {1413 MoveUpAction() {1414 putValue(NAME, tr("Move up"));1415 putValue(SMALL_ICON, ImageProvider.get("dialogs", "up"));1416 putValue(SHORT_DESCRIPTION, tr("Move the selected layer one row up."));1417 updateEnabledState();1418 }1419 1420 @Override1421 public void updateEnabledState() {1422 setEnabled(model.canMoveUp());1423 }1424 1425 @Override1426 public void actionPerformed(ActionEvent e) {1427 model.moveUp();1428 }1429 }1430 1431 /**1432 * The action to move down the currently selected entries in the list.1433 */1434 class MoveDownAction extends AbstractAction implements IEnabledStateUpdating {1435 MoveDownAction() {1436 putValue(NAME, tr("Move down"));1437 putValue(SMALL_ICON, ImageProvider.get("dialogs", "down"));1438 putValue(SHORT_DESCRIPTION, tr("Move the selected layer one row down."));1439 updateEnabledState();1440 }1441 1442 @Override1443 public void updateEnabledState() {1444 setEnabled(model.canMoveDown());1445 }1446 1447 @Override1448 public void actionPerformed(ActionEvent e) {1449 model.moveDown();1450 }1451 }1452 1453 /**1454 582 * Observer interface to be implemented by views using {@link LayerListModel}. 1455 583 */ … … 1518 646 * removes a listener from this model 1519 647 * @param listener the listener 1520 *1521 648 */ 1522 649 public void removeLayerListModelListener(LayerListModelListener listener) { … … 1636 763 */ 1637 764 protected void onAddLayer(Layer layer) { 1638 if (layer == null) return; 765 if (layer == null) 766 return; 1639 767 layer.addPropertyChangeListener(this); 1640 768 fireTableDataChanged(); … … 1651 779 */ 1652 780 public Layer getFirstLayer() { 1653 if (getRowCount() == 0) return null; 781 if (getRowCount() == 0) 782 return null; 1654 783 return getLayers().get(0); 1655 784 } … … 1683 812 */ 1684 813 public void moveUp() { 1685 if (!canMoveUp()) return; 814 if (!canMoveUp()) 815 return; 1686 816 List<Integer> sel = getSelectedRows(); 1687 817 List<Layer> layers = getLayers(); … … 1712 842 /** 1713 843 * Move down the currently selected layers by one position 1714 *1715 844 */ 1716 845 public void moveDown() { 1717 if (!canMoveDown()) return; 846 if (!canMoveDown()) 847 return; 1718 848 List<Integer> sel = getSelectedRows(); 1719 849 Collections.reverse(sel); … … 1734 864 1735 865 /** 1736 * Make sure the first of the selected layers is visible in the 1737 * views of this model. 1738 * 866 * Make sure the first of the selected layers is visible in the views of this model. 1739 867 */ 1740 868 protected void ensureSelectedIsVisible() { 1741 869 int index = selectionModel.getMinSelectionIndex(); 1742 if (index < 0) return; 870 if (index < 0) 871 return; 1743 872 List<Layer> layers = getLayers(); 1744 if (index >= layers.size()) return; 873 if (index >= layers.size()) 874 return; 1745 875 Layer layer = layers.get(index); 1746 876 fireMakeVisible(index, layer); … … 1748 878 1749 879 /** 1750 * Replies a list of layers which are possible merge targets 1751 * for <code>source</code> 880 * Replies a list of layers which are possible merge targets for <code>source</code> 1752 881 * 1753 882 * @param source the source layer … … 1811 940 */ 1812 941 protected Layer getActiveLayer() { 1813 if (!Main.isDisplayingMapView()) return null; 1814 return Main.map.mapView.getActiveLayer(); 942 return Main.isDisplayingMapView() ? Main.map.mapView.getActiveLayer() : null; 1815 943 } 1816 944 … … 1821 949 */ 1822 950 protected NativeScaleLayer getNativeScaleLayer() { 1823 if (!Main.isDisplayingMapView()) return null; 1824 return Main.map.mapView.getNativeScaleLayer(); 951 return Main.isDisplayingMapView() ? Main.map.mapView.getNativeScaleLayer() : null; 1825 952 } 1826 953 … … 1832 959 public int getRowCount() { 1833 960 List<Layer> layers = getLayers(); 1834 if (layers == null) return 0; 1835 return layers.size(); 961 return layers == null ? 0 : layers.size(); 1836 962 } 1837 963 … … 1943 1069 Layer layer = (Layer) evt.getSource(); 1944 1070 final int idx = getLayers().indexOf(layer); 1945 if (idx < 0) return; 1071 if (idx < 0) 1072 return; 1946 1073 fireRefresh(); 1947 1074 } … … 1967 1094 1968 1095 /** 1969 * Creates a {@link ShowHideLayerAction} in the 1970 * context of this {@link LayerListDialog}. 1096 * Creates a {@link ShowHideLayerAction} in the context of this {@link LayerListDialog}. 1971 1097 * 1972 1098 * @return the action 1973 1099 */ 1974 1100 public ShowHideLayerAction createShowHideLayerAction() { 1975 return new ShowHideLayerAction(); 1976 } 1977 1978 /** 1979 * Creates a {@link DeleteLayerAction} in the 1980 * context of this {@link LayerListDialog}. 1101 return new ShowHideLayerAction(model); 1102 } 1103 1104 /** 1105 * Creates a {@link DeleteLayerAction} in the context of this {@link LayerListDialog}. 1981 1106 * 1982 1107 * @return the action 1983 1108 */ 1984 1109 public DeleteLayerAction createDeleteLayerAction() { 1985 return new DeleteLayerAction(); 1986 } 1987 1988 /** 1989 * Creates a {@link ActivateLayerAction} for <code>layer</code> in the 1990 * context of this {@link LayerListDialog}. 1110 return new DeleteLayerAction(model); 1111 } 1112 1113 /** 1114 * Creates a {@link ActivateLayerAction} for <code>layer</code> in the context of this {@link LayerListDialog}. 1991 1115 * 1992 1116 * @param layer the layer … … 1994 1118 */ 1995 1119 public ActivateLayerAction createActivateLayerAction(Layer layer) { 1996 return new ActivateLayerAction(layer); 1997 } 1998 1999 /** 2000 * Creates a {@link MergeLayerAction} for <code>layer</code> in the 2001 * context of this {@link LayerListDialog}. 1120 return new ActivateLayerAction(layer, model); 1121 } 1122 1123 /** 1124 * Creates a {@link MergeLayerAction} for <code>layer</code> in the context of this {@link LayerListDialog}. 2002 1125 * 2003 1126 * @param layer the layer … … 2005 1128 */ 2006 1129 public MergeAction createMergeLayerAction(Layer layer) { 2007 return new MergeAction(layer); 2008 } 2009 2010 /** 2011 * Creates a {@link DuplicateAction} for <code>layer</code> in the 2012 * context of this {@link LayerListDialog}. 1130 return new MergeAction(layer, model); 1131 } 1132 1133 /** 1134 * Creates a {@link DuplicateAction} for <code>layer</code> in the context of this {@link LayerListDialog}. 2013 1135 * 2014 1136 * @param layer the layer … … 2016 1138 */ 2017 1139 public DuplicateAction createDuplicateLayerAction(Layer layer) { 2018 return new DuplicateAction(layer );1140 return new DuplicateAction(layer, model); 2019 1141 } 2020 1142 … … 2025 1147 */ 2026 1148 public static Layer getLayerForIndex(int index) { 2027 2028 1149 if (!Main.isDisplayingMapView()) 2029 1150 return null; … … 2044 1165 */ 2045 1166 public static List<MultikeyInfo> getLayerInfoByClass(Class<?> layerClass) { 2046 2047 1167 List<MultikeyInfo> result = new ArrayList<>(); 2048 1168 … … 2069 1189 */ 2070 1190 public static boolean isLayerValid(Layer l) { 2071 2072 1191 if (l == null || !Main.isDisplayingMapView()) 2073 1192 return false; … … 2082 1201 */ 2083 1202 public static MultikeyInfo getLayerInfo(Layer l) { 2084 2085 1203 if (l == null || !Main.isDisplayingMapView()) 2086 1204 return null;
Note:
See TracChangeset
for help on using the changeset viewer.