Changeset 3408 in josm


Ignore:
Timestamp:
2010-08-03T07:52:26+02:00 (11 years ago)
Author:
jttt
Message:

Show only actions that can work on all selected layers in LayerListDialog popup menu

Location:
trunk/src/org/openstreetmap/josm
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/osm/DataSet.java

    r3382 r3408  
    519519    }
    520520
    521     /*------------------------------------------------------
    522      * FILTERED / DISABLED HANDLING
    523      *-----------------------------------------------------*/
    524 
    525     /**
    526      * TODO: can be removed if no longer needed
    527      *
    528      * Currently, the filter flags are updated directly for the primitives.
    529      * On the long run there might be listeners for filter changes,
    530      * so the control needs to be moved to this place again.
    531      */
    532 
    533     //    public void setDisabled(OsmPrimitive... osm) {
    534     //        if (osm.length == 1 && osm[0] == null) {
    535     //            setDisabled();
    536     //            return;
    537     //        }
    538     //        clearDisabled(allPrimitives());
    539     //        for (OsmPrimitive o : osm)
    540     //            if (o != null) {
    541     //                o.setDisabled(true);
    542     //            }
    543     //    }
    544     //
    545     //    public void setDisabled(Collection<? extends OsmPrimitive> selection) {
    546     //        clearDisabled(nodes);
    547     //        clearDisabled(ways);
    548     //        clearDisabled(relations);
    549     //        for (OsmPrimitive osm : selection) {
    550     //            osm.setDisabled(true);
    551     //        }
    552     //    }
    553     //
    554     //    /**
    555     //     * Remove the disabled parameter from every value in the collection.
    556     //     * @param list The collection to remove the disabled parameter from.
    557     //     */
    558     //    private void clearDisabled(Collection<? extends OsmPrimitive> list) {
    559     //        for (OsmPrimitive osm : list) {
    560     //            osm.setDisabled(false);
    561     //        }
    562     //    }
    563     //
    564     //
    565     //    public void setFiltered(Collection<? extends OsmPrimitive> selection) {
    566     //        clearFiltered(nodes);
    567     //        clearFiltered(ways);
    568     //        clearFiltered(relations);
    569     //        for (OsmPrimitive osm : selection) {
    570     //            osm.setFiltered(true);
    571     //        }
    572     //    }
    573     //
    574     //    public void setFiltered(OsmPrimitive... osm) {
    575     //        if (osm.length == 1 && osm[0] == null) {
    576     //            setFiltered();
    577     //            return;
    578     //        }
    579     //        clearFiltered(nodes);
    580     //        clearFiltered(ways);
    581     //        clearFiltered(relations);
    582     //        for (OsmPrimitive o : osm)
    583     //            if (o != null) {
    584     //                o.setFiltered(true);
    585     //            }
    586     //    }
    587     //
    588     //    /**
    589     //     * Remove the filtered parameter from every value in the collection.
    590     //     * @param list The collection to remove the filtered parameter from.
    591     //     */
    592     //    private void clearFiltered(Collection<? extends OsmPrimitive> list) {
    593     //        if (list == null)
    594     //            return;
    595     //        for (OsmPrimitive osm : list) {
    596     //            osm.setFiltered(false);
    597     //        }
    598     //    }
    599 
    600521    @Override public DataSet clone() {
    601522        getReadLock().lock();
  • trunk/src/org/openstreetmap/josm/gui/conflict/pair/properties/OperationCancelledException.java

    r3083 r3408  
    66    public OperationCancelledException() {
    77        super();
    8         // TODO Auto-generated constructor stub
    98    }
    109
    1110    public OperationCancelledException(String message, Throwable cause) {
    1211        super(message, cause);
    13         // TODO Auto-generated constructor stub
    1412    }
    1513
    1614    public OperationCancelledException(String message) {
    1715        super(message);
    18         // TODO Auto-generated constructor stub
    1916    }
    2017
    2118    public OperationCancelledException(Throwable cause) {
    2219        super(cause);
    23         // TODO Auto-generated constructor stub
    2420    }
    2521
  • trunk/src/org/openstreetmap/josm/gui/dialogs/LayerListDialog.java

    r3237 r3408  
    2626import javax.swing.JLabel;
    2727import javax.swing.JList;
     28import javax.swing.JMenuItem;
    2829import javax.swing.JPanel;
    2930import javax.swing.JScrollPane;
     
    4748import org.openstreetmap.josm.gui.layer.Layer;
    4849import org.openstreetmap.josm.gui.layer.OsmDataLayer;
     50import org.openstreetmap.josm.gui.layer.Layer.LayerAction;
    4951import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
    5052import org.openstreetmap.josm.tools.CheckParameterUtil;
     
    265267     * The action to delete the currently selected layer
    266268     */
    267     public final  class DeleteLayerAction extends AbstractAction implements IEnabledStateUpdating {
     269    public final class DeleteLayerAction extends AbstractAction implements IEnabledStateUpdating, LayerAction {
    268270        /**
    269271         * Creates a {@see DeleteLayerAction} which will delete the currently
     
    318320            setEnabled(! getModel().getSelectedLayers().isEmpty());
    319321        }
    320     }
    321 
    322     public final class ShowHideLayerAction extends AbstractAction implements IEnabledStateUpdating {
     322
     323        @Override
     324        public Component createMenuComponent() {
     325            return new JMenuItem(this);
     326        }
     327
     328        @Override
     329        public boolean supportLayers(List<Layer> layers) {
     330            return true;
     331        }
     332
     333        @Override
     334        public boolean equals(Object obj) {
     335            return obj instanceof DeleteLayerAction;
     336        }
     337
     338        @Override
     339        public int hashCode() {
     340            return getClass().hashCode();
     341        }
     342    }
     343
     344    public final class ShowHideLayerAction extends AbstractAction implements IEnabledStateUpdating, LayerAction {
    323345        private  Layer layer;
    324346
     
    334356            CheckParameterUtil.ensureParameterNotNull(layer, "layer");
    335357            this.layer = layer;
    336             putValue(NAME, tr("Show/Hide"));
    337358            updateEnabledState();
    338359        }
     
    347368            putValue(SHORT_DESCRIPTION, tr("Toggle visible state of the selected layer."));
    348369            putValue("help", HelpUtil.ht("/Dialog/LayerDialog#ShowHideLayer"));
     370            putValue(NAME, tr("Show/Hide"));
    349371            updateEnabledState();
    350372        }
     
    366388                setEnabled(true);
    367389            }
     390        }
     391
     392        @Override
     393        public Component createMenuComponent() {
     394            return new JMenuItem(this);
     395        }
     396
     397        @Override
     398        public boolean supportLayers(List<Layer> layers) {
     399            return true;
     400        }
     401
     402        @Override
     403        public boolean equals(Object obj) {
     404            return obj instanceof ShowHideLayerAction;
     405        }
     406
     407        @Override
     408        public int hashCode() {
     409            return getClass().hashCode();
    368410        }
    369411    }
     
    576618            }
    577619            Layer layer = model.getLayer(index);
    578             LayerListPopup menu = new LayerListPopup(layerList, layer);
     620            LayerListPopup menu = new LayerListPopup(getModel().getSelectedLayers(), layer);
    579621            menu.show(LayerListDialog.this, p.x, p.y-3);
    580622        }
     
    10641106     * @return the action
    10651107     */
    1066     public ShowHideLayerAction createShowHideLayerAction(Layer layer) {
    1067         return new ShowHideLayerAction(layer);
     1108    public ShowHideLayerAction createShowHideLayerAction() {
     1109        return new ShowHideLayerAction();
    10681110    }
    10691111
     
    10751117     * @return the action
    10761118     */
    1077     public DeleteLayerAction createDeleteLayerAction(Layer layer) {
     1119    public DeleteLayerAction createDeleteLayerAction() {
    10781120        // the delete layer action doesn't depend on the current layer
    10791121        return new DeleteLayerAction();
  • trunk/src/org/openstreetmap/josm/gui/dialogs/LayerListPopup.java

    r2017 r3408  
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
    6 import java.awt.Component;
    76import java.awt.event.ActionEvent;
     7import java.util.ArrayList;
     8import java.util.Arrays;
     9import java.util.List;
    810
    911import javax.swing.AbstractAction;
    10 import javax.swing.JList;
     12import javax.swing.Action;
     13import javax.swing.JMenuItem;
    1114import javax.swing.JOptionPane;
    1215import javax.swing.JPopupMenu;
     
    1417import org.openstreetmap.josm.Main;
    1518import org.openstreetmap.josm.gui.layer.Layer;
     19import org.openstreetmap.josm.gui.layer.Layer.LayerAction;
     20import org.openstreetmap.josm.gui.layer.Layer.SeparatorLayerAction;
    1621import org.openstreetmap.josm.tools.ImageProvider;
    1722
     
    3742    }
    3843
    39     public LayerListPopup(final JList layers, final Layer layer) {
    40         for (Component c : layer.getMenuEntries()) {
    41             add(c);
     44    public LayerListPopup(List<Layer> selectedLayers, final Layer layer) {
     45
     46        List<Action> actions;
     47        if (selectedLayers.size() == 1) {
     48            actions = Arrays.asList(selectedLayers.get(0).getMenuEntries());
     49        } else {
     50            // Very simple algorithm - first selected layer has actions order as in getMenuEntries, actions from other layers go to the end
     51            actions = new ArrayList<Action>();
     52            boolean separatorAdded = true;
     53            for (Action a: selectedLayers.get(0).getMenuEntries()) {
     54                if (!separatorAdded && a instanceof SeparatorLayerAction) {
     55                    separatorAdded = true;
     56                    actions.add(a);
     57                } else if (a instanceof LayerAction && ((LayerAction)a).supportLayers(selectedLayers)) {
     58                    separatorAdded = false;
     59                    actions.add(a);
     60                }
     61            }
     62            // This will usually add no action, because if some action support all selected layers then it was probably used also in first layer
     63            for (int i=1; i<selectedLayers.size(); i++) {
     64                separatorAdded = false;
     65                for (Action a: selectedLayers.get(i).getMenuEntries()) {
     66                    if (a instanceof LayerAction && ((LayerAction)a).supportLayers(selectedLayers) && !actions.contains(a)) {
     67                        if (!separatorAdded) {
     68                            separatorAdded = true;
     69                            actions.add(SeparatorLayerAction.INSTANCE);
     70                        }
     71                        actions.add(a);
     72                    }
     73                }
     74            }
     75        }
     76        if (!actions.isEmpty() && actions.get(actions.size() - 1) instanceof SeparatorLayerAction) {
     77            actions.remove(actions.size() - 1);
     78        }
     79        for (Action a : actions) {
     80            if (a instanceof LayerAction) {
     81                add (((LayerAction) a).createMenuComponent());
     82            } else {
     83                add(new JMenuItem(a));
     84            }
    4285        }
    4386    }
  • trunk/src/org/openstreetmap/josm/gui/help/HelpContentReaderException.java

    r3083 r3408  
    77    public HelpContentReaderException() {
    88        super();
    9         // TODO Auto-generated constructor stub
    109    }
    1110
    1211    public HelpContentReaderException(String message, Throwable cause) {
    1312        super(message, cause);
    14         // TODO Auto-generated constructor stub
    1513    }
    1614
    1715    public HelpContentReaderException(String message) {
    1816        super(message);
    19         // TODO Auto-generated constructor stub
    2017    }
    2118
    2219    public HelpContentReaderException(Throwable cause) {
    2320        super(cause);
    24         // TODO Auto-generated constructor stub
    2521    }
    2622
  • trunk/src/org/openstreetmap/josm/gui/help/MissingHelpContentException.java

    r3083 r3408  
    66    public MissingHelpContentException() {
    77        super();
    8         // TODO Auto-generated constructor stub
    98    }
    109
    1110    public MissingHelpContentException(String message, Throwable cause) {
    1211        super(message, cause);
    13         // TODO Auto-generated constructor stub
    1412    }
    1513
    1614    public MissingHelpContentException(String message) {
    1715        super(message);
    18         // TODO Auto-generated constructor stub
    1916    }
    2017
    2118    public MissingHelpContentException(Throwable cause) {
    2219        super(cause);
    23         // TODO Auto-generated constructor stub
    2420    }
    2521}
  • trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java

    r3325 r3408  
    1010import java.awt.BasicStroke;
    1111import java.awt.Color;
    12 import java.awt.Component;
    1312import java.awt.Graphics2D;
    1413import java.awt.GridBagLayout;
    1514import java.awt.Point;
    1615import java.awt.event.ActionEvent;
    17 import java.awt.event.ActionListener;
    1816import java.awt.geom.Area;
    1917import java.awt.geom.Rectangle2D;
     
    3129
    3230import javax.swing.AbstractAction;
     31import javax.swing.Action;
    3332import javax.swing.Box;
    3433import javax.swing.ButtonGroup;
     
    3837import javax.swing.JLabel;
    3938import javax.swing.JList;
    40 import javax.swing.JMenuItem;
    4139import javax.swing.JOptionPane;
    4240import javax.swing.JPanel;
    4341import javax.swing.JRadioButton;
    44 import javax.swing.JSeparator;
    4542import javax.swing.filechooser.FileFilter;
    4643
     
    130127
    131128    @Override
    132     public Component[] getMenuEntries() {
    133         JMenuItem line = new JMenuItem(tr("Customize line drawing"), ImageProvider.get("mapmode/addsegment"));
    134         line.addActionListener(new ActionListener() {
    135             public void actionPerformed(ActionEvent e) {
    136                 JRadioButton[] r = new JRadioButton[3];
    137                 r[0] = new JRadioButton(tr("Use global settings."));
    138                 r[1] = new JRadioButton(tr("Draw lines between points for this layer."));
    139                 r[2] = new JRadioButton(tr("Do not draw lines between points for this layer."));
    140                 ButtonGroup group = new ButtonGroup();
    141                 Box panel = Box.createVerticalBox();
    142                 for (JRadioButton b : r) {
    143                     group.add(b);
    144                     panel.add(b);
    145                 }
    146                 String propName = "draw.rawgps.lines.layer " + getName();
    147                 if (Main.pref.hasKey(propName)) {
    148                     group.setSelected(r[Main.pref.getBoolean(propName) ? 1 : 2].getModel(), true);
    149                 } else {
    150                     group.setSelected(r[0].getModel(), true);
    151                 }
    152                 int answer = JOptionPane.showConfirmDialog(Main.parent, panel,
    153                         tr("Select line drawing options"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
    154                 switch (answer) {
    155                 case JOptionPane.CANCEL_OPTION:
    156                 case JOptionPane.CLOSED_OPTION:
    157                     return;
    158                 default:
    159                     // continue
    160                 }
    161                 if (group.getSelection() == r[0].getModel()) {
    162                     Main.pref.put(propName, null);
    163                 } else {
    164                     Main.pref.put(propName, group.getSelection() == r[1].getModel());
    165                 }
    166                 Main.map.repaint();
    167             }
    168         });
    169 
    170         JMenuItem color = new JMenuItem(tr("Customize Color"), ImageProvider.get("colorchooser"));
    171         color.putClientProperty("help", "Action/LayerCustomizeColor");
    172         color.addActionListener(new ActionListener() {
    173             public void actionPerformed(ActionEvent e) {
    174                 JColorChooser c = new JColorChooser(getColor(getName()));
    175                 Object[] options = new Object[] { tr("OK"), tr("Cancel"), tr("Default") };
    176                 int answer = JOptionPane.showOptionDialog(
    177                         Main.parent,
    178                         c,
    179                         tr("Choose a color"),
    180                         JOptionPane.OK_CANCEL_OPTION,
    181                         JOptionPane.PLAIN_MESSAGE,
    182                         null,
    183                         options, options[0]
    184                 );
    185                 switch (answer) {
    186                 case 0:
    187                     Main.pref.putColor("layer " + getName(), c.getColor());
    188                     break;
    189                 case 1:
    190                     return;
    191                 case 2:
    192                     Main.pref.putColor("layer " + getName(), null);
    193                     break;
    194                 }
    195                 Main.map.repaint();
    196             }
    197         });
    198 
    199         JMenuItem markersFromNamedTrackpoints = new JMenuItem(tr("Markers From Named Points"), ImageProvider
    200                 .get("addmarkers"));
    201         markersFromNamedTrackpoints.putClientProperty("help", "Action/MarkersFromNamedPoints");
    202         markersFromNamedTrackpoints.addActionListener(new ActionListener() {
    203             public void actionPerformed(ActionEvent e) {
    204                 GpxData namedTrackPoints = new GpxData();
    205                 for (GpxTrack track : data.tracks) {
    206                     for (GpxTrackSegment seg : track.getSegments()) {
    207                         for (WayPoint point : seg.getWayPoints())
    208                             if (point.attr.containsKey("name") || point.attr.containsKey("desc")) {
    209                                 namedTrackPoints.waypoints.add(point);
    210                             }
    211                     }
    212                 }
    213 
    214                 MarkerLayer ml = new MarkerLayer(namedTrackPoints, tr("Named Trackpoints from {0}", getName()),
    215                         getAssociatedFile(), GpxLayer.this);
    216                 if (ml.data.size() > 0) {
    217                     Main.main.addLayer(ml);
    218                 }
    219             }
    220         });
    221 
    222         JMenuItem importAudio = new JMenuItem(tr("Import Audio"), ImageProvider.get("importaudio"));
    223         importAudio.putClientProperty("help", "ImportAudio");
    224         importAudio.addActionListener(new ActionListener() {
    225             private void warnCantImportIntoServerLayer(GpxLayer layer) {
    226                 String msg = tr("<html>The data in the GPX layer ''{0}'' has been downloaded from the server.<br>"
    227                         + "Because its way points do not include a timestamp we cannot correlate them with audio data.</html>",
    228                         layer.getName()
    229                 );
    230                 HelpAwareOptionPane.showOptionDialog(
    231                         Main.parent,
    232                         msg,
    233                         tr("Import not possible"),
    234                         JOptionPane.WARNING_MESSAGE,
    235                         ht("/Action/ImportImages#CantImportIntoGpxLayerFromServer")
    236                 );
    237             }
    238             public void actionPerformed(ActionEvent e) {
    239                 if (GpxLayer.this.data.fromServer) {
    240                     warnCantImportIntoServerLayer(GpxLayer.this);
    241                     return;
    242                 }
    243                 String dir = Main.pref.get("markers.lastaudiodirectory");
    244                 JFileChooser fc = new JFileChooser(dir);
    245                 fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
    246                 fc.setAcceptAllFileFilterUsed(false);
    247                 fc.setFileFilter(new FileFilter() {
    248                     @Override
    249                     public boolean accept(File f) {
    250                         return f.isDirectory() || f.getName().toLowerCase().endsWith(".wav");
    251                     }
    252 
    253                     @Override
    254                     public String getDescription() {
    255                         return tr("Wave Audio files (*.wav)");
    256                     }
    257                 });
    258                 fc.setMultiSelectionEnabled(true);
    259                 if (fc.showOpenDialog(Main.parent) == JFileChooser.APPROVE_OPTION) {
    260                     if (!fc.getCurrentDirectory().getAbsolutePath().equals(dir)) {
    261                         Main.pref.put("markers.lastaudiodirectory", fc.getCurrentDirectory().getAbsolutePath());
    262                     }
    263 
    264                     File sel[] = fc.getSelectedFiles();
    265                     // sort files in increasing order of timestamp (this is the end time, but so
    266                     // long as they don't overlap, that's fine)
    267                     if (sel.length > 1) {
    268                         Arrays.sort(sel, new Comparator<File>() {
    269                             public int compare(File a, File b) {
    270                                 return a.lastModified() <= b.lastModified() ? -1 : 1;
    271                             }
    272                         });
    273                     }
    274 
    275                     String names = null;
    276                     for (int i = 0; i < sel.length; i++) {
    277                         if (names == null) {
    278                             names = " (";
    279                         } else {
    280                             names += ", ";
    281                         }
    282                         names += sel[i].getName();
    283                     }
    284                     if (names != null) {
    285                         names += ")";
    286                     } else {
    287                         names = "";
    288                     }
    289                     MarkerLayer ml = new MarkerLayer(new GpxData(), tr("Audio markers from {0}", getName()) + names,
    290                             getAssociatedFile(), GpxLayer.this);
    291                     double firstStartTime = sel[0].lastModified() / 1000.0 /* ms -> seconds */
    292                     - AudioUtil.getCalibratedDuration(sel[0]);
    293 
    294                     Markers m = new Markers();
    295                     for (int i = 0; i < sel.length; i++) {
    296                         importAudio(sel[i], ml, firstStartTime, m);
    297                     }
    298                     Main.main.addLayer(ml);
    299                     Main.map.repaint();
    300                 }
    301             }
    302         });
    303 
    304         JMenuItem tagimage = new JMenuItem(tr("Import images"), ImageProvider.get("dialogs/geoimage"));
    305         tagimage.putClientProperty("help", ht("/Action/ImportImages"));
    306         tagimage.addActionListener(new ActionListener() {
    307 
    308             private void warnCantImportIntoServerLayer(GpxLayer layer) {
    309                 String msg = tr("<html>The data in the GPX layer ''{0}'' has been downloaded from the server.<br>"
    310                         + "Because its way points do not include a timestamp we cannot correlate them with images.</html>",
    311                         layer.getName()
    312                 );
    313                 HelpAwareOptionPane.showOptionDialog(
    314                         Main.parent,
    315                         msg,
    316                         tr("Import not possible"),
    317                         JOptionPane.WARNING_MESSAGE,
    318                         ht("/Action/ImportImages#CantImportIntoGpxLayerFromServer")
    319                 );
    320             }
    321 
    322             public void actionPerformed(ActionEvent e) {
    323                 if (GpxLayer.this.data.fromServer) {
    324                     warnCantImportIntoServerLayer(GpxLayer.this);
    325                     return;
    326                 }
    327                 String curDir = Main.pref.get("geoimage.lastdirectory", Main.pref.get("lastDirectory"));
    328                 if (curDir.equals("")) {
    329                     curDir = ".";
    330                 }
    331                 JFileChooser fc = new JFileChooser(new File(curDir));
    332 
    333                 fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
    334                 fc.setMultiSelectionEnabled(true);
    335                 fc.setAcceptAllFileFilterUsed(false);
    336                 JpgImporter importer = new JpgImporter(GpxLayer.this);
    337                 fc.setFileFilter(importer.filter);
    338                 fc.showOpenDialog(Main.parent);
    339                 LinkedList<File> files = new LinkedList<File>();
    340                 File[] sel = fc.getSelectedFiles();
    341                 if (sel == null || sel.length == 0)
    342                     return;
    343                 if (!fc.getCurrentDirectory().getAbsolutePath().equals(curDir)) {
    344                     Main.pref.put("geoimage.lastdirectory", fc.getCurrentDirectory().getAbsolutePath());
    345                 }
    346                 addRecursiveFiles(files, sel);
    347                 importer.importDataHandleExceptions(files, NullProgressMonitor.INSTANCE);
    348             }
    349 
    350             private void addRecursiveFiles(LinkedList<File> files, File[] sel) {
    351                 for (File f : sel) {
    352                     if (f.isDirectory()) {
    353                         addRecursiveFiles(files, f.listFiles());
    354                     } else if (f.getName().toLowerCase().endsWith(".jpg")) {
    355                         files.add(f);
    356                     }
    357                 }
    358             }
    359         });
    360 
     129    public Action[] getMenuEntries() {
    361130        if (Main.applet)
    362             return new Component[] { new JMenuItem(LayerListDialog.getInstance().createShowHideLayerAction(this)),
    363                 new JMenuItem(LayerListDialog.getInstance().createDeleteLayerAction(this)), new JSeparator(), color, line,
    364                 new JMenuItem(new ConvertToDataLayerAction()), new JSeparator(),
    365                 new JMenuItem(new RenameLayerAction(getAssociatedFile(), this)), new JSeparator(),
    366                 new JMenuItem(new LayerListPopup.InfoAction(this)) };
    367         return new Component[] { new JMenuItem(LayerListDialog.getInstance().createShowHideLayerAction(this)),
    368                 new JMenuItem(LayerListDialog.getInstance().createDeleteLayerAction(this)), new JSeparator(),
    369                 new JMenuItem(new LayerSaveAction(this)), new JMenuItem(new LayerSaveAsAction(this)), color, line,
    370                 tagimage, importAudio, markersFromNamedTrackpoints, new JMenuItem(new ConvertToDataLayerAction()),
    371                 new JMenuItem(new DownloadAlongTrackAction()), new JSeparator(),
    372                 new JMenuItem(new RenameLayerAction(getAssociatedFile(), this)), new JSeparator(),
    373                 new JMenuItem(new LayerListPopup.InfoAction(this)) };
     131            return new Action[] {
     132                LayerListDialog.getInstance().createShowHideLayerAction(),
     133                LayerListDialog.getInstance().createDeleteLayerAction(),
     134                SeparatorLayerAction.INSTANCE,
     135                new CustomizeColor(),
     136                new CustomizeLineDrawing(),
     137                new ConvertToDataLayerAction(),
     138                SeparatorLayerAction.INSTANCE,
     139                new RenameLayerAction(getAssociatedFile(), this),
     140                SeparatorLayerAction.INSTANCE,
     141                new LayerListPopup.InfoAction(this) };
     142        return new Action[] {
     143                LayerListDialog.getInstance().createShowHideLayerAction(),
     144                LayerListDialog.getInstance().createDeleteLayerAction(),
     145                SeparatorLayerAction.INSTANCE,
     146                new LayerSaveAction(this),
     147                new LayerSaveAsAction(this),
     148                new CustomizeColor(),
     149                new CustomizeLineDrawing(),
     150                new ImportImages(),
     151                new ImportAudio(),
     152                new MarkersFromNamedPoins(),
     153                new ConvertToDataLayerAction(),
     154                new DownloadAlongTrackAction(),
     155                SeparatorLayerAction.INSTANCE,
     156                new RenameLayerAction(getAssociatedFile(), this),
     157                SeparatorLayerAction.INSTANCE,
     158                new LayerListPopup.InfoAction(this) };
    374159    }
    375160
     
    14171202        return best;
    14181203    }
     1204
     1205    private class CustomizeLineDrawing extends AbstractAction {
     1206
     1207        CustomizeLineDrawing() {
     1208            super(tr("Customize line drawing"), ImageProvider.get("mapmode/addsegment"));
     1209        }
     1210
     1211        @Override
     1212        public void actionPerformed(ActionEvent e) {
     1213            JRadioButton[] r = new JRadioButton[3];
     1214            r[0] = new JRadioButton(tr("Use global settings."));
     1215            r[1] = new JRadioButton(tr("Draw lines between points for this layer."));
     1216            r[2] = new JRadioButton(tr("Do not draw lines between points for this layer."));
     1217            ButtonGroup group = new ButtonGroup();
     1218            Box panel = Box.createVerticalBox();
     1219            for (JRadioButton b : r) {
     1220                group.add(b);
     1221                panel.add(b);
     1222            }
     1223            String propName = "draw.rawgps.lines.layer " + getName();
     1224            if (Main.pref.hasKey(propName)) {
     1225                group.setSelected(r[Main.pref.getBoolean(propName) ? 1 : 2].getModel(), true);
     1226            } else {
     1227                group.setSelected(r[0].getModel(), true);
     1228            }
     1229            int answer = JOptionPane.showConfirmDialog(Main.parent, panel,
     1230                    tr("Select line drawing options"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
     1231            switch (answer) {
     1232            case JOptionPane.CANCEL_OPTION:
     1233            case JOptionPane.CLOSED_OPTION:
     1234                return;
     1235            default:
     1236                // continue
     1237            }
     1238            if (group.getSelection() == r[0].getModel()) {
     1239                Main.pref.put(propName, null);
     1240            } else {
     1241                Main.pref.put(propName, group.getSelection() == r[1].getModel());
     1242            }
     1243            Main.map.repaint();
     1244        }
     1245    }
     1246
     1247    private class CustomizeColor extends AbstractAction {
     1248
     1249        public CustomizeColor() {
     1250            super(tr("Customize Color"), ImageProvider.get("colorchooser"));
     1251            putValue("help", "Action/LayerCustomizeColor");
     1252        }
     1253
     1254        @Override
     1255        public void actionPerformed(ActionEvent e) {
     1256            JColorChooser c = new JColorChooser(getColor(getName()));
     1257            Object[] options = new Object[] { tr("OK"), tr("Cancel"), tr("Default") };
     1258            int answer = JOptionPane.showOptionDialog(
     1259                    Main.parent,
     1260                    c,
     1261                    tr("Choose a color"),
     1262                    JOptionPane.OK_CANCEL_OPTION,
     1263                    JOptionPane.PLAIN_MESSAGE,
     1264                    null,
     1265                    options, options[0]
     1266            );
     1267            switch (answer) {
     1268            case 0:
     1269                Main.pref.putColor("layer " + getName(), c.getColor());
     1270                break;
     1271            case 1:
     1272                return;
     1273            case 2:
     1274                Main.pref.putColor("layer " + getName(), null);
     1275                break;
     1276            }
     1277            Main.map.repaint();
     1278        }
     1279
     1280    }
     1281
     1282    private class MarkersFromNamedPoins extends AbstractAction {
     1283
     1284        public MarkersFromNamedPoins() {
     1285            super(tr("Markers From Named Points"), ImageProvider.get("addmarkers"));
     1286            putValue("help", "Action/MarkersFromNamedPoints");
     1287        }
     1288
     1289        @Override
     1290        public void actionPerformed(ActionEvent e) {
     1291            GpxData namedTrackPoints = new GpxData();
     1292            for (GpxTrack track : data.tracks) {
     1293                for (GpxTrackSegment seg : track.getSegments()) {
     1294                    for (WayPoint point : seg.getWayPoints())
     1295                        if (point.attr.containsKey("name") || point.attr.containsKey("desc")) {
     1296                            namedTrackPoints.waypoints.add(point);
     1297                        }
     1298                }
     1299            }
     1300
     1301            MarkerLayer ml = new MarkerLayer(namedTrackPoints, tr("Named Trackpoints from {0}", getName()),
     1302                    getAssociatedFile(), GpxLayer.this);
     1303            if (ml.data.size() > 0) {
     1304                Main.main.addLayer(ml);
     1305            }
     1306
     1307        }
     1308    }
     1309
     1310    private class ImportAudio extends AbstractAction {
     1311
     1312        public ImportAudio() {
     1313            super(tr("Import Audio"), ImageProvider.get("importaudio"));
     1314            putValue("help", "ImportAudio");
     1315        }
     1316
     1317        private void warnCantImportIntoServerLayer(GpxLayer layer) {
     1318            String msg = tr("<html>The data in the GPX layer ''{0}'' has been downloaded from the server.<br>"
     1319                    + "Because its way points do not include a timestamp we cannot correlate them with audio data.</html>",
     1320                    layer.getName()
     1321            );
     1322            HelpAwareOptionPane.showOptionDialog(
     1323                    Main.parent,
     1324                    msg,
     1325                    tr("Import not possible"),
     1326                    JOptionPane.WARNING_MESSAGE,
     1327                    ht("/Action/ImportImages#CantImportIntoGpxLayerFromServer")
     1328            );
     1329        }
     1330
     1331        @Override
     1332        public void actionPerformed(ActionEvent e) {
     1333            if (GpxLayer.this.data.fromServer) {
     1334                warnCantImportIntoServerLayer(GpxLayer.this);
     1335                return;
     1336            }
     1337            String dir = Main.pref.get("markers.lastaudiodirectory");
     1338            JFileChooser fc = new JFileChooser(dir);
     1339            fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
     1340            fc.setAcceptAllFileFilterUsed(false);
     1341            fc.setFileFilter(new FileFilter() {
     1342                @Override
     1343                public boolean accept(File f) {
     1344                    return f.isDirectory() || f.getName().toLowerCase().endsWith(".wav");
     1345                }
     1346
     1347                @Override
     1348                public String getDescription() {
     1349                    return tr("Wave Audio files (*.wav)");
     1350                }
     1351            });
     1352            fc.setMultiSelectionEnabled(true);
     1353            if (fc.showOpenDialog(Main.parent) == JFileChooser.APPROVE_OPTION) {
     1354                if (!fc.getCurrentDirectory().getAbsolutePath().equals(dir)) {
     1355                    Main.pref.put("markers.lastaudiodirectory", fc.getCurrentDirectory().getAbsolutePath());
     1356                }
     1357
     1358                File sel[] = fc.getSelectedFiles();
     1359                // sort files in increasing order of timestamp (this is the end time, but so
     1360                // long as they don't overlap, that's fine)
     1361                if (sel.length > 1) {
     1362                    Arrays.sort(sel, new Comparator<File>() {
     1363                        public int compare(File a, File b) {
     1364                            return a.lastModified() <= b.lastModified() ? -1 : 1;
     1365                        }
     1366                    });
     1367                }
     1368
     1369                String names = null;
     1370                for (int i = 0; i < sel.length; i++) {
     1371                    if (names == null) {
     1372                        names = " (";
     1373                    } else {
     1374                        names += ", ";
     1375                    }
     1376                    names += sel[i].getName();
     1377                }
     1378                if (names != null) {
     1379                    names += ")";
     1380                } else {
     1381                    names = "";
     1382                }
     1383                MarkerLayer ml = new MarkerLayer(new GpxData(), tr("Audio markers from {0}", getName()) + names,
     1384                        getAssociatedFile(), GpxLayer.this);
     1385                double firstStartTime = sel[0].lastModified() / 1000.0 /* ms -> seconds */
     1386                - AudioUtil.getCalibratedDuration(sel[0]);
     1387
     1388                Markers m = new Markers();
     1389                for (int i = 0; i < sel.length; i++) {
     1390                    importAudio(sel[i], ml, firstStartTime, m);
     1391                }
     1392                Main.main.addLayer(ml);
     1393                Main.map.repaint();
     1394            }
     1395
     1396        }
     1397    }
     1398
     1399    private class ImportImages extends AbstractAction {
     1400
     1401        public ImportImages() {
     1402            super(tr("Import images"), ImageProvider.get("dialogs/geoimage"));
     1403            putValue("help", ht("/Action/ImportImages"));
     1404        }
     1405
     1406        private void warnCantImportIntoServerLayer(GpxLayer layer) {
     1407            String msg = tr("<html>The data in the GPX layer ''{0}'' has been downloaded from the server.<br>"
     1408                    + "Because its way points do not include a timestamp we cannot correlate them with images.</html>",
     1409                    layer.getName()
     1410            );
     1411            HelpAwareOptionPane.showOptionDialog(
     1412                    Main.parent,
     1413                    msg,
     1414                    tr("Import not possible"),
     1415                    JOptionPane.WARNING_MESSAGE,
     1416                    ht("/Action/ImportImages#CantImportIntoGpxLayerFromServer")
     1417            );
     1418        }
     1419
     1420        private void addRecursiveFiles(LinkedList<File> files, File[] sel) {
     1421            for (File f : sel) {
     1422                if (f.isDirectory()) {
     1423                    addRecursiveFiles(files, f.listFiles());
     1424                } else if (f.getName().toLowerCase().endsWith(".jpg")) {
     1425                    files.add(f);
     1426                }
     1427            }
     1428        }
     1429
     1430        @Override
     1431        public void actionPerformed(ActionEvent e) {
     1432
     1433            if (GpxLayer.this.data.fromServer) {
     1434                warnCantImportIntoServerLayer(GpxLayer.this);
     1435                return;
     1436            }
     1437            String curDir = Main.pref.get("geoimage.lastdirectory", Main.pref.get("lastDirectory"));
     1438            if (curDir.equals("")) {
     1439                curDir = ".";
     1440            }
     1441            JFileChooser fc = new JFileChooser(new File(curDir));
     1442
     1443            fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
     1444            fc.setMultiSelectionEnabled(true);
     1445            fc.setAcceptAllFileFilterUsed(false);
     1446            JpgImporter importer = new JpgImporter(GpxLayer.this);
     1447            fc.setFileFilter(importer.filter);
     1448            fc.showOpenDialog(Main.parent);
     1449            LinkedList<File> files = new LinkedList<File>();
     1450            File[] sel = fc.getSelectedFiles();
     1451            if (sel == null || sel.length == 0)
     1452                return;
     1453            if (!fc.getCurrentDirectory().getAbsolutePath().equals(curDir)) {
     1454                Main.pref.put("geoimage.lastdirectory", fc.getCurrentDirectory().getAbsolutePath());
     1455            }
     1456            addRecursiveFiles(files, sel);
     1457            importer.importDataHandleExceptions(files, NullProgressMonitor.INSTANCE);
     1458        }
     1459
     1460    }
    14191461}
  • trunk/src/org/openstreetmap/josm/gui/layer/Layer.java

    r3116 r3408  
    1111import java.beans.PropertyChangeSupport;
    1212import java.io.File;
     13import java.util.List;
    1314
    1415import javax.swing.AbstractAction;
     16import javax.swing.Action;
    1517import javax.swing.Icon;
     18import javax.swing.JSeparator;
    1619
    1720import org.openstreetmap.josm.actions.GpxExportAction;
     
    4043 */
    4144abstract public class Layer implements Destroyable, MapViewPaintable {
     45
     46    public interface LayerAction {
     47        boolean supportLayers(List<Layer> layers);
     48        Component createMenuComponent();
     49    }
     50
     51    /**
     52     * Special class that can be returned by getMenuEntries when JSeparator needs to be created
     53     *
     54     */
     55    public static class SeparatorLayerAction extends AbstractAction implements LayerAction {
     56        public static final SeparatorLayerAction INSTANCE = new SeparatorLayerAction();
     57        @Override
     58        public void actionPerformed(ActionEvent e) {
     59            throw new UnsupportedOperationException();
     60        }
     61        @Override
     62        public Component createMenuComponent() {
     63            return new JSeparator();
     64        }
     65        @Override
     66        public boolean supportLayers(List<Layer> layers) {
     67            return false;
     68        }
     69    }
     70
    4271    static public final String VISIBLE_PROP = Layer.class.getName() + ".visible";
    4372    static public final String NAME_PROP = Layer.class.getName() + ".name";
     73
    4474
    4575    /** keeps track of property change listeners */
     
    112142    abstract public Object getInfoComponent();
    113143
    114     abstract public Component[] getMenuEntries();
     144    /**
     145     * Returns list of actions. Action can implement LayerAction interface when it needs to be represented by other
     146     * menu component than JMenuItem or when it supports multiple layers. Actions that support multiple layers should also
     147     * have correct equals implementation.
     148     *
     149     * Use SeparatorLayerAction.INSTANCE instead of new JSeparator
     150     *
     151     */
     152    abstract public Action[] getMenuEntries();
    115153
    116154    /**
  • trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java

    r3362 r3408  
    1010import java.awt.AlphaComposite;
    1111import java.awt.Color;
    12 import java.awt.Component;
    1312import java.awt.Composite;
    1413import java.awt.Graphics2D;
     
    2827
    2928import javax.swing.AbstractAction;
     29import javax.swing.Action;
    3030import javax.swing.Icon;
    3131import javax.swing.JLabel;
    32 import javax.swing.JMenuItem;
    3332import javax.swing.JOptionPane;
    3433import javax.swing.JPanel;
    3534import javax.swing.JScrollPane;
    36 import javax.swing.JSeparator;
    3735import javax.swing.JTextArea;
    3836
     
    440438    }
    441439
    442     @Override public Component[] getMenuEntries() {
     440    @Override public Action[] getMenuEntries() {
    443441        if (Main.applet)
    444             return new Component[]{
    445                 new JMenuItem(LayerListDialog.getInstance().createActivateLayerAction(this)),
    446                 new JMenuItem(LayerListDialog.getInstance().createShowHideLayerAction(this)),
    447                 new JMenuItem(LayerListDialog.getInstance().createDeleteLayerAction(this)),
    448                 new JSeparator(),
    449                 new JMenuItem(LayerListDialog.getInstance().createMergeLayerAction(this)),
    450                 new JSeparator(),
    451                 new JMenuItem(new RenameLayerAction(getAssociatedFile(), this)),
    452                 new JMenuItem(new ConsistencyTestAction()),
    453                 new JSeparator(),
    454                 new JMenuItem(new LayerListPopup.InfoAction(this))};
    455         return new Component[]{
    456                 new JMenuItem(LayerListDialog.getInstance().createActivateLayerAction(this)),
    457                 new JMenuItem(LayerListDialog.getInstance().createShowHideLayerAction(this)),
    458                 new JMenuItem(LayerListDialog.getInstance().createDeleteLayerAction(this)),
    459                 new JSeparator(),
    460                 new JMenuItem(LayerListDialog.getInstance().createMergeLayerAction(this)),
    461                 new JMenuItem(new LayerSaveAction(this)),
    462                 new JMenuItem(new LayerSaveAsAction(this)),
    463                 new JMenuItem(new LayerGpxExportAction(this)),
    464                 new JMenuItem(new ConvertToGpxLayerAction()),
    465                 new JSeparator(),
    466                 new JMenuItem(new RenameLayerAction(getAssociatedFile(), this)),
    467                 new JMenuItem(new ConsistencyTestAction()),
    468                 new JSeparator(),
    469                 new JMenuItem(new LayerListPopup.InfoAction(this))};
     442            return new Action[]{
     443                LayerListDialog.getInstance().createActivateLayerAction(this),
     444                LayerListDialog.getInstance().createShowHideLayerAction(),
     445                LayerListDialog.getInstance().createDeleteLayerAction(),
     446                SeparatorLayerAction.INSTANCE,
     447                LayerListDialog.getInstance().createMergeLayerAction(this),
     448                SeparatorLayerAction.INSTANCE,
     449                new RenameLayerAction(getAssociatedFile(), this),
     450                new ConsistencyTestAction(),
     451                SeparatorLayerAction.INSTANCE,
     452                new LayerListPopup.InfoAction(this)};
     453        return new Action[]{
     454                LayerListDialog.getInstance().createActivateLayerAction(this),
     455                LayerListDialog.getInstance().createShowHideLayerAction(),
     456                LayerListDialog.getInstance().createDeleteLayerAction(),
     457                SeparatorLayerAction.INSTANCE,
     458                LayerListDialog.getInstance().createMergeLayerAction(this),
     459                new LayerSaveAction(this),
     460                new LayerSaveAsAction(this),
     461                new LayerGpxExportAction(this),
     462                new ConvertToGpxLayerAction(),
     463                SeparatorLayerAction.INSTANCE,
     464                new RenameLayerAction(getAssociatedFile(), this),
     465                new ConsistencyTestAction(),
     466                SeparatorLayerAction.INSTANCE,
     467                new LayerListPopup.InfoAction(this)};
    470468    }
    471469
  • trunk/src/org/openstreetmap/josm/gui/layer/RawGpsLayer.java

    r3233 r3408  
    88
    99import java.awt.Color;
    10 import java.awt.Component;
    1110import java.awt.Graphics2D;
    1211import java.awt.GridBagLayout;
    1312import java.awt.Point;
    1413import java.awt.event.ActionEvent;
    15 import java.awt.event.ActionListener;
    1614import java.io.File;
    1715import java.util.ArrayList;
     
    2018
    2119import javax.swing.AbstractAction;
     20import javax.swing.Action;
    2221import javax.swing.Box;
    2322import javax.swing.ButtonGroup;
     
    2524import javax.swing.JColorChooser;
    2625import javax.swing.JLabel;
    27 import javax.swing.JMenuItem;
    2826import javax.swing.JOptionPane;
    2927import javax.swing.JPanel;
    3028import javax.swing.JRadioButton;
    31 import javax.swing.JSeparator;
    3229
    3330import org.openstreetmap.josm.Main;
     
    196193    }
    197194
    198     @Override public Component[] getMenuEntries() {
    199         JMenuItem line = new JMenuItem(tr("Customize line drawing"), ImageProvider.get("mapmode/addsegment"));
    200         line.addActionListener(new ActionListener(){
    201             public void actionPerformed(ActionEvent e) {
    202                 JRadioButton[] r = new JRadioButton[3];
    203                 r[0] = new JRadioButton(tr("Use global settings."));
    204                 r[1] = new JRadioButton(tr("Draw lines between points for this layer."));
    205                 r[2] = new JRadioButton(tr("Do not draw lines between points for this layer."));
    206                 ButtonGroup group = new ButtonGroup();
    207                 Box panel = Box.createVerticalBox();
    208                 for (JRadioButton b : r) {
    209                     group.add(b);
    210                     panel.add(b);
    211                 }
    212                 String propName = "draw.rawgps.lines.layer "+getName();
    213                 if (Main.pref.hasKey(propName)) {
    214                     group.setSelected(r[Main.pref.getBoolean(propName) ? 1:2].getModel(), true);
    215                 } else {
    216                     group.setSelected(r[0].getModel(), true);
    217                 }
    218                 int answer = JOptionPane.showConfirmDialog(
    219                         Main.parent,
    220                         panel,
    221                         tr("Select line drawing options"),
    222                         JOptionPane.OK_CANCEL_OPTION,
    223                         JOptionPane.PLAIN_MESSAGE
    224                 );
    225                 if (answer == JOptionPane.CANCEL_OPTION)
    226                     return;
    227                 if (group.getSelection() == r[0].getModel()) {
    228                     Main.pref.put(propName, null);
    229                 } else {
    230                     Main.pref.put(propName, group.getSelection() == r[1].getModel());
    231                 }
    232                 Main.map.repaint();
    233             }
    234         });
    235 
    236         JMenuItem color = new JMenuItem(tr("Customize Color"), ImageProvider.get("colorchooser"));
    237         color.addActionListener(new ActionListener(){
    238             public void actionPerformed(ActionEvent e) {
    239                 JColorChooser c = new JColorChooser(Main.pref.getColor(marktr("gps point"), "layer "+getName(), Color.gray));
    240                 Object[] options = new Object[]{tr("OK"), tr("Cancel"), tr("Default")};
    241                 int answer = JOptionPane.showOptionDialog(
    242                         Main.parent,
    243                         c,
    244                         tr("Choose a color"),
    245                         JOptionPane.OK_CANCEL_OPTION,
    246                         JOptionPane.PLAIN_MESSAGE, null,options, options[0]);
    247                 switch (answer) {
    248                 case 0:
    249                     Main.pref.putColor("layer "+getName(), c.getColor());
    250                     break;
    251                 case 1:
    252                     return;
    253                 case 2:
    254                     Main.pref.putColor("layer "+getName(), null);
    255                     break;
    256                 }
    257                 Main.map.repaint();
    258             }
    259         });
    260 
     195    @Override public Action[] getMenuEntries() {
    261196        if (Main.applet)
    262             return new Component[]{
    263                 new JMenuItem(LayerListDialog.getInstance().createShowHideLayerAction(this)),
    264                 new JMenuItem(LayerListDialog.getInstance().createDeleteLayerAction(this)),
    265                 new JSeparator(),
    266                 color,
    267                 line,
    268                 new JMenuItem(new ConvertToDataLayerAction()),
    269                 new JSeparator(),
    270                 new JMenuItem(new RenameLayerAction(getAssociatedFile(), this)),
    271                 new JSeparator(),
    272                 new JMenuItem(new LayerListPopup.InfoAction(this))};
    273         return new Component[]{
    274                 new JMenuItem(LayerListDialog.getInstance().createShowHideLayerAction(this)),
    275                 new JMenuItem(LayerListDialog.getInstance().createDeleteLayerAction(this)),
    276                 new JSeparator(),
    277                 new JMenuItem(new LayerGpxExportAction(this)),
    278                 color,
    279                 line,
    280                 new JMenuItem(new ConvertToDataLayerAction()),
    281                 new JSeparator(),
    282                 new JMenuItem(new RenameLayerAction(getAssociatedFile(), this)),
    283                 new JSeparator(),
    284                 new JMenuItem(new LayerListPopup.InfoAction(this))};
     197            return new Action[]{
     198                LayerListDialog.getInstance().createShowHideLayerAction(),
     199                LayerListDialog.getInstance().createDeleteLayerAction(),
     200                SeparatorLayerAction.INSTANCE,
     201                new CustomizeColor(),
     202                new CustomizeLineDrawing(),
     203                new ConvertToDataLayerAction(),
     204                SeparatorLayerAction.INSTANCE,
     205                new RenameLayerAction(getAssociatedFile(), this),
     206                SeparatorLayerAction.INSTANCE,
     207                new LayerListPopup.InfoAction(this)};
     208        else
     209            return new Action[]{
     210                LayerListDialog.getInstance().createShowHideLayerAction(),
     211                LayerListDialog.getInstance().createDeleteLayerAction(),
     212                SeparatorLayerAction.INSTANCE,
     213                new LayerGpxExportAction(this),
     214                new CustomizeColor(),
     215                new CustomizeLineDrawing(),
     216                new ConvertToDataLayerAction(),
     217                SeparatorLayerAction.INSTANCE,
     218                new RenameLayerAction(getAssociatedFile(), this),
     219                SeparatorLayerAction.INSTANCE,
     220                new LayerListPopup.InfoAction(this)};
    285221    }
    286222
     
    294230        Main.pref.removePreferenceChangeListener(this);
    295231    }
     232
     233    private class CustomizeLineDrawing extends AbstractAction {
     234
     235        public CustomizeLineDrawing() {
     236            super(tr("Customize line drawing"), ImageProvider.get("mapmode/addsegment"));
     237        }
     238
     239        @Override
     240        public void actionPerformed(ActionEvent e) {
     241            JRadioButton[] r = new JRadioButton[3];
     242            r[0] = new JRadioButton(tr("Use global settings."));
     243            r[1] = new JRadioButton(tr("Draw lines between points for this layer."));
     244            r[2] = new JRadioButton(tr("Do not draw lines between points for this layer."));
     245            ButtonGroup group = new ButtonGroup();
     246            Box panel = Box.createVerticalBox();
     247            for (JRadioButton b : r) {
     248                group.add(b);
     249                panel.add(b);
     250            }
     251            String propName = "draw.rawgps.lines.layer "+getName();
     252            if (Main.pref.hasKey(propName)) {
     253                group.setSelected(r[Main.pref.getBoolean(propName) ? 1:2].getModel(), true);
     254            } else {
     255                group.setSelected(r[0].getModel(), true);
     256            }
     257            int answer = JOptionPane.showConfirmDialog(
     258                    Main.parent,
     259                    panel,
     260                    tr("Select line drawing options"),
     261                    JOptionPane.OK_CANCEL_OPTION,
     262                    JOptionPane.PLAIN_MESSAGE
     263            );
     264            if (answer == JOptionPane.CANCEL_OPTION)
     265                return;
     266            if (group.getSelection() == r[0].getModel()) {
     267                Main.pref.put(propName, null);
     268            } else {
     269                Main.pref.put(propName, group.getSelection() == r[1].getModel());
     270            }
     271            Main.map.repaint();
     272        }
     273    }
     274
     275    private class CustomizeColor extends AbstractAction {
     276
     277        public CustomizeColor() {
     278            super(tr("Customize Color"), ImageProvider.get("colorchooser"));
     279        }
     280
     281        @Override
     282        public void actionPerformed(ActionEvent e) {
     283            JColorChooser c = new JColorChooser(Main.pref.getColor(marktr("gps point"), "layer "+getName(), Color.gray));
     284            Object[] options = new Object[]{tr("OK"), tr("Cancel"), tr("Default")};
     285            int answer = JOptionPane.showOptionDialog(
     286                    Main.parent,
     287                    c,
     288                    tr("Choose a color"),
     289                    JOptionPane.OK_CANCEL_OPTION,
     290                    JOptionPane.PLAIN_MESSAGE, null,options, options[0]);
     291            switch (answer) {
     292            case 0:
     293                Main.pref.putColor("layer "+getName(), c.getColor());
     294                break;
     295            case 1:
     296                return;
     297            case 2:
     298                Main.pref.putColor("layer "+getName(), null);
     299                break;
     300            }
     301            Main.map.repaint();
     302        }
     303    }
    296304}
  • trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java

    r3310 r3408  
    4040import java.util.zip.GZIPInputStream;
    4141
     42import javax.swing.AbstractAction;
    4243import javax.swing.AbstractListModel;
    4344import javax.swing.BorderFactory;
     
    8384 * Then it correlates the images of the layer with that GPX file.
    8485 */
    85 public class CorrelateGpxWithImages implements ActionListener {
     86public class CorrelateGpxWithImages extends AbstractAction {
    8687
    8788    private static List<GpxData> loadedGpxData = new ArrayList<GpxData>();
     
    9293
    9394    public CorrelateGpxWithImages(GeoImageLayer layer) {
     95        super(tr("Correlate to GPX"), ImageProvider.get("dialogs/geoimage/gpx2img"));
    9496        this.yLayer = layer;
    9597    }
     
    217219    }
    218220
    219     /** 
     221    /**
    220222     * This action listener is called when the user has a photo of the time of his GPS receiver. It
    221223     * displays the list of photos of the layer, and upon selection displays the selected photo.
     
    630632        tfTimezone.addFocusListener(repaintTheMap);
    631633        tfOffset.addFocusListener(repaintTheMap);
    632        
     634
    633635        tfTimezone.getDocument().addDocumentListener(statusBarUpdater);
    634636        tfOffset.getDocument().addDocumentListener(statusBarUpdater);
     
    760762    StatusBarUpdater statusBarUpdater = new StatusBarUpdater(false);
    761763    StatusBarUpdater statusBarUpdaterWithRepaint = new StatusBarUpdater(true);
    762    
     764
    763765    private class StatusBarUpdater implements  DocumentListener, ItemListener, ActionListener {
    764766        private boolean doRepaint;
     
    767769            this.doRepaint = doRepaint;
    768770        }
    769        
     771
    770772        public void insertUpdate(DocumentEvent ev) {
    771773            updateStatusBar();
     
    789791            }
    790792        }
    791        
     793
    792794        private String statusText() {
    793795            try {
     
    803805                ie.tmp = null;
    804806            }
    805            
     807
    806808            // Construct a list of images that have a date, and sort them on the date.
    807809            ArrayList<ImageEntry> dateImgLst = getSortedImgList();
     
    828830        public void focusGained(FocusEvent e) { // do nothing
    829831        }
    830        
     832
    831833        public void focusLost(FocusEvent e) {
    832834            yLayer.updateBufferAndRepaint();
     
    11971199        if(prevWpTime == 0 || curWpTime <= prevWpTime) {
    11981200            while (true) {
    1199                 if (i < 0)
     1201                if (i < 0) {
    12001202                    break;
     1203                }
    12011204                final ImageEntry curImg = images.get(i);
    12021205                if (curImg.getExifTime().getTime() > curWpTime
    1203                     || curImg.getExifTime().getTime() < curWpTime - interval)
    1204                         break;
     1206                        || curImg.getExifTime().getTime() < curWpTime - interval) {
     1207                    break;
     1208                }
    12051209                if(curImg.tmp.getPos() == null) {
    12061210                    curImg.tmp.setPos(curWp.getCoor());
     
    12181222        // previous track point assuming a constant speed in between
    12191223        while (true) {
    1220             if (i < 0)
     1224            if (i < 0) {
    12211225                break;
     1226            }
    12221227            ImageEntry curImg = images.get(i);
    12231228            long imgTime = curImg.getExifTime().getTime();
    1224             if (imgTime < prevWpTime)
     1229            if (imgTime < prevWpTime) {
    12251230                break;
     1231            }
    12261232
    12271233            if(curImg.tmp.getPos() == null) {
  • trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java

    r3387 r3408  
    1111import java.awt.AlphaComposite;
    1212import java.awt.Color;
    13 import java.awt.Component;
    1413import java.awt.Composite;
    1514import java.awt.Dimension;
     
    3534import java.util.List;
    3635
     36import javax.swing.Action;
    3737import javax.swing.Icon;
    3838import javax.swing.JLabel;
    39 import javax.swing.JMenuItem;
    4039import javax.swing.JOptionPane;
    41 import javax.swing.JSeparator;
    4240import javax.swing.SwingConstants;
    4341
     
    280278    }
    281279
    282     public static interface LayerMenuAddition {
    283         public Component getComponent(Layer layer);
    284     }
    285 
    286     private static List<LayerMenuAddition> menuAdditions = new LinkedList<LayerMenuAddition>();
    287     public static void registerMenuAddition(LayerMenuAddition addition) {
     280    private static List<Action> menuAdditions = new LinkedList<Action>();
     281    public static void registerMenuAddition(Action addition) {
    288282        menuAdditions.add(addition);
    289283    }
    290284
    291285    @Override
    292     public Component[] getMenuEntries() {
    293 
    294         JMenuItem correlateItem = new JMenuItem(tr("Correlate to GPX"), ImageProvider.get("dialogs/geoimage/gpx2img"));
    295         correlateItem.addActionListener(new CorrelateGpxWithImages(this));
    296 
    297         List<Component> entries = new ArrayList<Component>();
    298         entries.add(new JMenuItem(LayerListDialog.getInstance().createShowHideLayerAction(this)));
    299         entries.add(new JMenuItem(LayerListDialog.getInstance().createDeleteLayerAction(this)));
    300         entries.add(new JMenuItem(new RenameLayerAction(null, this)));
    301         entries.add(new JSeparator());
    302         entries.add(correlateItem);
     286    public Action[] getMenuEntries() {
     287
     288        List<Action> entries = new ArrayList<Action>();
     289        entries.add(LayerListDialog.getInstance().createShowHideLayerAction());
     290        entries.add(LayerListDialog.getInstance().createDeleteLayerAction());
     291        entries.add(new RenameLayerAction(null, this));
     292        entries.add(SeparatorLayerAction.INSTANCE);
     293        entries.add(new CorrelateGpxWithImages(this));
    303294        if (!menuAdditions.isEmpty()) {
    304             entries.add(new JSeparator());
    305         }
    306         for (LayerMenuAddition addition : menuAdditions) {
    307             entries.add(addition.getComponent(this));
    308         }
    309         entries.add(new JSeparator());
    310         entries.add(new JMenuItem(new LayerListPopup.InfoAction(this)));
    311 
    312         return entries.toArray(new Component[0]);
     295            entries.add(SeparatorLayerAction.INSTANCE);
     296            entries.addAll(menuAdditions);
     297        }
     298        entries.add(SeparatorLayerAction.INSTANCE);
     299        entries.add(new LayerListPopup.InfoAction(this));
     300
     301        return entries.toArray(new Action[0]);
    313302
    314303    }
     
    472461
    473462                        double dir = e.getExifImgDir();
    474                         // Rotate 90 degrees CCW 
     463                        // Rotate 90 degrees CCW
    475464                        double headdir = ( dir < 90 ) ? dir + 270 : dir - 90;
    476465                        double leftdir = ( headdir < 90 ) ? headdir + 270 : headdir - 90;
     
    522511        Metadata metadata = null;
    523512        Directory dir = null;
    524        
     513
    525514        try {
    526515            metadata = JpegMetadataReader.readMetadata(e.getFile());
     
    531520            return;
    532521        }
    533        
     522
    534523        try {
    535524            // longitude
     
    591580
    592581        Rational direction = null;
    593        
     582
    594583        try {
    595584            direction = dir.getRational(GpsDirectory.TAG_GPS_IMG_DIRECTION);
     585            if (direction != null) {
     586                e.setExifImgDir(direction.doubleValue());
     587            }
    596588        } catch (CompoundException p) {
    597             direction = null;
    598         } catch (Exception ex) {
    599             direction = null;
    600         }
    601 
    602         if (direction != null) {
    603             e.setExifImgDir(direction.doubleValue());
    604         }
     589            // Do nothing
     590        }
     591
    605592
    606593    }
  • trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java

    r3237 r3408  
    1111import java.awt.Point;
    1212import java.awt.event.ActionEvent;
    13 import java.awt.event.ActionListener;
    1413import java.awt.event.MouseAdapter;
    1514import java.awt.event.MouseEvent;
     
    1817import java.util.ArrayList;
    1918import java.util.Collection;
     19import java.util.List;
    2020
    2121import javax.swing.AbstractAction;
     22import javax.swing.Action;
    2223import javax.swing.Icon;
    2324import javax.swing.JCheckBoxMenuItem;
    2425import javax.swing.JColorChooser;
    25 import javax.swing.JMenuItem;
    2626import javax.swing.JOptionPane;
    27 import javax.swing.JSeparator;
    2827import javax.swing.SwingUtilities;
    2928
     
    197196    }
    198197
    199     @Override public Component[] getMenuEntries() {
    200         JMenuItem color = new JMenuItem(tr("Customize Color"), ImageProvider.get("colorchooser"));
    201         color.putClientProperty("help", "Action/LayerCustomizeColor");
    202         color.addActionListener(new ActionListener(){
    203             public void actionPerformed(ActionEvent e) {
    204                 JColorChooser c = new JColorChooser(getColor(getName()));
    205                 Object[] options = new Object[]{tr("OK"), tr("Cancel"), tr("Default")};
    206                 int answer = JOptionPane.showOptionDialog(
    207                         Main.parent,
    208                         c,
    209                         tr("Choose a color"),
    210                         JOptionPane.OK_CANCEL_OPTION,
    211                         JOptionPane.PLAIN_MESSAGE,
    212                         null,
    213                         options,
    214                         options[0]
    215                 );
    216                 switch (answer) {
    217                 case 0:
    218                     Main.pref.putColor("layer "+getName(), c.getColor());
    219                     break;
    220                 case 1:
    221                     return;
    222                 case 2:
    223                     Main.pref.putColor("layer "+getName(), null);
    224                     break;
    225                 }
    226                 Main.map.repaint();
    227             }
    228         });
    229 
    230         JMenuItem syncaudio = new JMenuItem(tr("Synchronize Audio"), ImageProvider.get("audio-sync"));
    231         syncaudio.putClientProperty("help", "Action/SynchronizeAudio");
    232         syncaudio.addActionListener(new ActionListener(){
    233             public void actionPerformed(ActionEvent e) {
    234                 if (! AudioPlayer.paused()) {
    235                     JOptionPane.showMessageDialog(
    236                             Main.parent,
    237                             tr("You need to pause audio at the moment when you hear your synchronization cue."),
    238                             tr("Warning"),
    239                             JOptionPane.WARNING_MESSAGE
    240                     );
    241                     return;
    242                 }
    243                 AudioMarker recent = AudioMarker.recentlyPlayedMarker();
    244                 if (synchronizeAudioMarkers(recent)) {
    245                     JOptionPane.showMessageDialog(
    246                             Main.parent,
    247                             tr("Audio synchronized at point {0}.", recent.text),
    248                             tr("Information"),
    249                             JOptionPane.INFORMATION_MESSAGE
    250                     );
    251                 } else {
    252                     JOptionPane.showMessageDialog(
    253                             Main.parent,
    254                             tr("Unable to synchronize in layer being played."),
    255                             tr("Error"),
    256                             JOptionPane.ERROR_MESSAGE
    257                     );
    258                 }
    259             }
    260         });
    261 
    262         JMenuItem moveaudio = new JMenuItem(tr("Make Audio Marker at Play Head"), ImageProvider.get("addmarkers"));
    263         moveaudio.putClientProperty("help", "Action/MakeAudioMarkerAtPlayHead");
    264         moveaudio.addActionListener(new ActionListener(){
    265             public void actionPerformed(ActionEvent e) {
    266                 if (! AudioPlayer.paused()) {
    267                     JOptionPane.showMessageDialog(
    268                             Main.parent,
    269                             tr("You need to have paused audio at the point on the track where you want the marker."),
    270                             tr("Warning"),
    271                             JOptionPane.WARNING_MESSAGE
    272                     );
    273                     return;
    274                 }
    275                 PlayHeadMarker playHeadMarker = Main.map.mapView.playHeadMarker;
    276                 if (playHeadMarker == null)
    277                     return;
    278                 addAudioMarker(playHeadMarker.time, playHeadMarker.getCoor());
    279                 Main.map.mapView.repaint();
    280             }
    281         });
    282 
    283         Collection<Component> components = new ArrayList<Component>();
    284         components.add(new JMenuItem(LayerListDialog.getInstance().createShowHideLayerAction(this)));
    285         JCheckBoxMenuItem showMarkerTextItem = new JCheckBoxMenuItem(new ShowHideMarkerText(this));
    286         showMarkerTextItem.setState(isTextOrIconShown());
    287         components.add(showMarkerTextItem);
    288         components.add(new JMenuItem(LayerListDialog.getInstance().createDeleteLayerAction(this)));
    289         components.add(new JSeparator());
    290         components.add(color);
    291         components.add(new JSeparator());
    292         components.add(syncaudio);
     198    @Override public Action[] getMenuEntries() {
     199        Collection<Action> components = new ArrayList<Action>();
     200        components.add(LayerListDialog.getInstance().createShowHideLayerAction());
     201        components.add(new ShowHideMarkerText(this));
     202        components.add(LayerListDialog.getInstance().createDeleteLayerAction());
     203        components.add(SeparatorLayerAction.INSTANCE);
     204        components.add(new CustomizeColor());
     205        components.add(SeparatorLayerAction.INSTANCE);
     206        components.add(new SynchronizeAudio());
    293207        if (Main.pref.getBoolean("marker.traceaudio", true)) {
    294             components.add (moveaudio);
    295         }
    296         components.add(new JMenuItem(new RenameLayerAction(getAssociatedFile(), this)));
    297         components.add(new JSeparator());
    298         components.add(new JMenuItem(new LayerListPopup.InfoAction(this)));
    299         return components.toArray(new Component[0]);
     208            components.add (new MoveAudio());
     209        }
     210        components.add(new RenameLayerAction(getAssociatedFile(), this));
     211        components.add(SeparatorLayerAction.INSTANCE);
     212        components.add(new LayerListPopup.InfoAction(this));
     213        return components.toArray(new Action[0]);
    300214    }
    301215
     
    457371    }
    458372
    459     public static final class ShowHideMarkerText extends AbstractAction {
     373    public static final class ShowHideMarkerText extends AbstractAction implements LayerAction {
    460374        private final MarkerLayer layer;
    461375
     
    472386            Main.map.mapView.repaint();
    473387        }
     388
     389
     390        @Override
     391        public Component createMenuComponent() {
     392            JCheckBoxMenuItem showMarkerTextItem = new JCheckBoxMenuItem(this);
     393            showMarkerTextItem.setState(layer.isTextOrIconShown());
     394            return showMarkerTextItem;
     395        }
     396
     397
     398        @Override
     399        public boolean supportLayers(List<Layer> layers) {
     400            return layers.size() == 1 && layers.get(0) instanceof MarkerLayer;
     401        }
     402    }
     403
     404    private class CustomizeColor extends AbstractAction {
     405
     406        public CustomizeColor() {
     407            super(tr("Customize Color"), ImageProvider.get("colorchooser"));
     408            putValue("help", "Action/LayerCustomizeColor");
     409        }
     410
     411        @Override
     412        public void actionPerformed(ActionEvent e) {
     413            JColorChooser c = new JColorChooser(getColor(getName()));
     414            Object[] options = new Object[]{tr("OK"), tr("Cancel"), tr("Default")};
     415            int answer = JOptionPane.showOptionDialog(
     416                    Main.parent,
     417                    c,
     418                    tr("Choose a color"),
     419                    JOptionPane.OK_CANCEL_OPTION,
     420                    JOptionPane.PLAIN_MESSAGE,
     421                    null,
     422                    options,
     423                    options[0]
     424            );
     425            switch (answer) {
     426            case 0:
     427                Main.pref.putColor("layer "+getName(), c.getColor());
     428                break;
     429            case 1:
     430                return;
     431            case 2:
     432                Main.pref.putColor("layer "+getName(), null);
     433                break;
     434            }
     435            Main.map.repaint();
     436        }
     437    }
     438
     439    private class SynchronizeAudio extends AbstractAction {
     440
     441        public SynchronizeAudio() {
     442            super(tr("Synchronize Audio"), ImageProvider.get("audio-sync"));
     443            putValue("help", "Action/SynchronizeAudio");
     444        }
     445
     446        @Override
     447        public void actionPerformed(ActionEvent e) {
     448            if (! AudioPlayer.paused()) {
     449                JOptionPane.showMessageDialog(
     450                        Main.parent,
     451                        tr("You need to pause audio at the moment when you hear your synchronization cue."),
     452                        tr("Warning"),
     453                        JOptionPane.WARNING_MESSAGE
     454                );
     455                return;
     456            }
     457            AudioMarker recent = AudioMarker.recentlyPlayedMarker();
     458            if (synchronizeAudioMarkers(recent)) {
     459                JOptionPane.showMessageDialog(
     460                        Main.parent,
     461                        tr("Audio synchronized at point {0}.", recent.text),
     462                        tr("Information"),
     463                        JOptionPane.INFORMATION_MESSAGE
     464                );
     465            } else {
     466                JOptionPane.showMessageDialog(
     467                        Main.parent,
     468                        tr("Unable to synchronize in layer being played."),
     469                        tr("Error"),
     470                        JOptionPane.ERROR_MESSAGE
     471                );
     472            }
     473        }
     474    }
     475
     476    private class MoveAudio extends AbstractAction {
     477
     478        public MoveAudio() {
     479            super(tr("Make Audio Marker at Play Head"), ImageProvider.get("addmarkers"));
     480            putValue("help", "Action/MakeAudioMarkerAtPlayHead");
     481        }
     482
     483        @Override
     484        public void actionPerformed(ActionEvent e) {
     485            if (! AudioPlayer.paused()) {
     486                JOptionPane.showMessageDialog(
     487                        Main.parent,
     488                        tr("You need to have paused audio at the point on the track where you want the marker."),
     489                        tr("Warning"),
     490                        JOptionPane.WARNING_MESSAGE
     491                );
     492                return;
     493            }
     494            PlayHeadMarker playHeadMarker = Main.map.mapView.playHeadMarker;
     495            if (playHeadMarker == null)
     496                return;
     497            addAudioMarker(playHeadMarker.time, playHeadMarker.getCoor());
     498            Main.map.mapView.repaint();
     499        }
    474500    }
    475501}
  • trunk/src/org/openstreetmap/josm/gui/oauth/OsmLoginFailedException.java

    r3083 r3408  
    66    public OsmLoginFailedException() {
    77        super();
    8         // TODO Auto-generated constructor stub
    98    }
    109
    1110    public OsmLoginFailedException(String arg0, Throwable arg1) {
    1211        super(arg0, arg1);
    13         // TODO Auto-generated constructor stub
    1412    }
    1513
    1614    public OsmLoginFailedException(String arg0) {
    1715        super(arg0);
    18         // TODO Auto-generated constructor stub
    1916    }
    2017
    2118    public OsmLoginFailedException(Throwable arg0) {
    2219        super(arg0);
    23         // TODO Auto-generated constructor stub
    2420    }
    2521}
  • trunk/src/org/openstreetmap/josm/gui/progress/NullProgressMonitor.java

    r3083 r3408  
    7878
    7979    public int getTicksCount() {
    80         // TODO Auto-generated method stub
    8180        return 0;
    8281    }
  • trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPresetSearchDialog.java

    r3388 r3408  
    313313     */
    314314    private void filterPresets(String text) {
    315         //TODO search also in keys/values
    316315        //TODO Favorites
    317316        text = text.toLowerCase();
  • trunk/src/org/openstreetmap/josm/io/GpxReader.java

    r3372 r3408  
    88import java.io.IOException;
    99import java.io.InputStream;
    10 import java.io.InputStreamReader;
    1110import java.util.ArrayList;
    1211import java.util.Collection;
Note: See TracChangeset for help on using the changeset viewer.