Ticket #59: wip1.patch

File wip1.patch, 48.2 KB (added by xeen, 15 years ago)
  • src/org/openstreetmap/josm/actions/ChangesetManagerToggleAction.java

     
    3333                "dialogs/changeset/changesetmanager",
    3434                tr("Toggle visibility of Changeset Manager window"),
    3535                Shortcut.registerShortcut(
    36                         "menu:view:changesetdialog",
     36                        "menu:windows:changesetdialog",
    3737                        tr("Toggle visibility of Changeset Manager window"),
    3838                        KeyEvent.VK_C,
    3939                        Shortcut.GROUPS_ALT2 + Shortcut.GROUP_HOTKEY
  • src/org/openstreetmap/josm/plugins/PluginProxy.java

     
    2424        this.plugin = plugin;
    2525    }
    2626
     27    /**
     28     * Not required anymore since the MapFrame is initialized only once now, so
     29     * plugins may assume it exists and it won't change. Will be removed after
     30     * 2012-01-01.
     31     */
     32    @Deprecated
    2733    @Override public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
    2834        try {
    2935            plugin.getClass().getMethod("mapFrameInitialized", MapFrame.class, MapFrame.class).invoke(plugin, oldFrame, newFrame);
  • src/org/openstreetmap/josm/plugins/PluginHandler.java

     
    2626import java.util.LinkedList;
    2727import java.util.List;
    2828import java.util.Map;
    29 import java.util.Map.Entry;
    3029import java.util.Set;
    3130import java.util.TreeSet;
     31import java.util.Map.Entry;
    3232import java.util.concurrent.ExecutionException;
    3333import java.util.concurrent.ExecutorService;
    3434import java.util.concurrent.Executors;
     
    4949import org.openstreetmap.josm.Main;
    5050import org.openstreetmap.josm.data.Version;
    5151import org.openstreetmap.josm.gui.HelpAwareOptionPane;
    52 import org.openstreetmap.josm.gui.HelpAwareOptionPane.ButtonSpec;
    5352import org.openstreetmap.josm.gui.JMultilineLabel;
    5453import org.openstreetmap.josm.gui.MapFrame;
     54import org.openstreetmap.josm.gui.HelpAwareOptionPane.ButtonSpec;
    5555import org.openstreetmap.josm.gui.download.DownloadSelection;
    5656import org.openstreetmap.josm.gui.help.HelpUtil;
    5757import org.openstreetmap.josm.gui.preferences.PreferenceSettingFactory;
    5858import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
    5959import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    60 import org.openstreetmap.josm.io.remotecontrol.RemoteControl;
    6160import org.openstreetmap.josm.tools.CheckParameterUtil;
    6261import org.openstreetmap.josm.tools.GBC;
    6362import org.openstreetmap.josm.tools.I18n;
     
    824823    }
    825824
    826825    /**
    827      * Notified loaded plugins about a new map frame
    828      *
    829      * @param old the old map frame
    830      * @param map the new map frame
     826     * Not required anymore since the MapFrame is initialized only once now, so
     827     * plugins may assume it exists and it won't change. Will be removed after
     828     * 2012-01-01.
    831829     */
     830    @Deprecated
    832831    public static void notifyMapFrameChanged(MapFrame old, MapFrame map) {
    833832        for (PluginProxy plugin : pluginList) {
    834833            plugin.mapFrameInitialized(old, map);
  • src/org/openstreetmap/josm/plugins/Plugin.java

     
    8080    }
    8181
    8282    /**
    83      * Called after Main.mapFrame is initalized. (After the first data is loaded).
    84      * You can use this callback to tweak the newFrame to your needs, as example install
    85      * an alternative Painter.
     83     * Not required anymore since the MapFrame is initialized only once now, so
     84     * plugins may assume it exists and it won't change. Will be removed after
     85     * 2012-01-01.
    8686     */
     87    @Deprecated
    8788    public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {}
    8889
    8990    /**
  • src/org/openstreetmap/josm/Main.java

     
    11// License: GPL. Copyright 2007 by Immanuel Scholz and others
    22package org.openstreetmap.josm;
     3
    34import static org.openstreetmap.josm.tools.I18n.tr;
    45
    56import java.awt.BorderLayout;
     
    8788import org.openstreetmap.josm.tools.Utils;
    8889
    8990abstract public class Main {
    90 
    9191    /**
    9292     * Replies true if JOSM currently displays a map view. False, if it doesn't, i.e. if
    9393     * it only shows the MOTD panel.
     
    9595     * @return true if JOSM currently displays a map view
    9696     */
    9797    static public boolean isDisplayingMapView() {
    98         if (map == null) return false;
    99         if (map.mapView == null) return false;
     98        if (map == null)
     99            return false;
     100        if (map.mapView == null)
     101            return false;
    100102        return true;
    101103    }
     104
    102105    /**
    103106     * Global parent component for all dialogs and message boxes
    104107     */
     
    124127    public static PrimitiveDeepCopy pasteBuffer = new PrimitiveDeepCopy();
    125128    public static Layer pasteSource;
    126129
     130    protected static JPanel contentPanePrivate = new JPanel(new BorderLayout());
     131
    127132    /**
    128133     * The MapFrame. Use setMapFrame to set or clear it.
    129134     */
    130135    public static MapFrame map;
     136
    131137    /**
    132138     * True, when in applet mode
    133139     */
     
    155161     * Print a message if logging is on.
    156162     */
    157163    static public int log_level = 2;
     164
    158165    static public void warn(String msg) {
    159166        if (log_level < 1)
    160167            return;
    161168        System.out.println(msg);
    162169    }
     170
    163171    static public void info(String msg) {
    164172        if (log_level < 2)
    165173            return;
    166174        System.out.println(msg);
    167175    }
     176
    168177    static public void debug(String msg) {
    169178        if (log_level < 3)
    170179            return;
     
    186195    public static boolean isOpenjdk;
    187196
    188197    /**
    189      * Set or clear (if passed <code>null</code>) the map.
     198     * MapFrame is now created only once and only shown/hidden. Use show/hideMapFrame instead.
     199     * This function has no use any longer. Will be removed on or after 2012-01-01. FIXME
    190200     */
     201    @Deprecated
    191202    public final void setMapFrame(final MapFrame map) {
    192         MapFrame old = Main.map;
    193         panel.setVisible(false);
     203    }
     204
     205    public final void showMapFrame() {
    194206        panel.removeAll();
    195         if (map != null) {
    196207            map.fillPanel(panel);
    197         } else {
    198             old.destroy();
    199             panel.add(gettingStarted, BorderLayout.CENTER);
    200         }
    201         panel.setVisible(true);
     208        map.setVisible(true);
    202209        redoUndoListener.commandChanged(0,0);
     210    }
    203211
    204         Main.map = map;
    205 
    206         PluginHandler.notifyMapFrameChanged(old, map);
     212    public final void hideMapFrame() {
     213        panel.removeAll();
     214        map.setVisible(false);
     215        panel.add(gettingStarted, BorderLayout.CENTER);
     216        redoUndoListener.commandChanged(0, 0);
     217        panel.repaint();
    207218    }
    208219
    209220    /**
     
    214225        if (map != null) {
    215226            map.mapView.removeLayer(layer);
    216227            if (map.mapView.getAllLayers().isEmpty()) {
    217                 setMapFrame(null);
     228                hideMapFrame();
    218229            }
    219230        }
    220231    }
     
    242253        // creating toolbar
    243254        contentPanePrivate.add(toolbar.control, BorderLayout.NORTH);
    244255
    245         registerActionShortcut(menu.help, Shortcut.registerShortcut("system:help", tr("Help"),
    246                 KeyEvent.VK_F1, Shortcut.GROUP_DIRECT));
     256        registerActionShortcut(menu.help, Shortcut.registerShortcut("system:help", tr("Help"), KeyEvent.VK_F1,
     257                Shortcut.GROUP_DIRECT));
    247258
    248259        TaggingPresetPreference.initialize();
    249260        MapPaintPreference.initialize();
     
    252263        validator = new OsmValidator();
    253264        MapView.addLayerChangeListener(validator);
    254265
     266        map = new MapFrame(contentPanePrivate);
     267        map.initializeDialogsPane();
     268
    255269        toolbar.refreshToolbarControl();
    256270
    257271        toolbar.control.updateUI();
    258272        contentPanePrivate.updateUI();
    259273
     274        // remove call after 2012-01-01 FIXME
     275        PluginHandler.notifyMapFrameChanged(null, map);
    260276    }
    261277
    262278    /**
    263279     * Add a new layer to the map. If no map exists, create one.
    264280     */
    265281    public final void addLayer(final Layer layer) {
    266         if (map == null) {
    267             final MapFrame mapFrame = new MapFrame(contentPanePrivate);
    268             setMapFrame(mapFrame);
    269             mapFrame.selectMapMode((MapMode)mapFrame.getDefaultButtonAction());
    270             mapFrame.setVisible(true);
    271             mapFrame.initializeDialogsPane();
     282        if (!map.isVisible()) {
     283            Main.map.selectMapMode((MapMode) Main.map.getDefaultButtonAction());
     284            showMapFrame();
     285
    272286            // bootstrapping problem: make sure the layer list dialog is going to
    273287            // listen to change events of the very first layer
    274288            //
     
    283297     * @return true if there is an edit layer
    284298     */
    285299    public boolean hasEditLayer() {
    286         if (getEditLayer() == null) return false;
     300        if (getEditLayer() == null)
     301            return false;
    287302        return true;
    288303    }
    289304
     
    293308     * @return the current edit layer. null, if no current edit layer exists
    294309     */
    295310    public OsmDataLayer getEditLayer() {
    296         if (map == null) return null;
    297         if (map.mapView == null) return null;
     311        if (map == null)
     312            return null;
     313        if (map.mapView == null)
     314            return null;
    298315        return map.mapView.getEditLayer();
    299316    }
    300317
     
    304321     * @return the current data set. null, if no current data set exists
    305322     */
    306323    public DataSet getCurrentDataSet() {
    307         if (!hasEditLayer()) return null;
     324        if (!hasEditLayer())
     325            return null;
    308326        return getEditLayer().data;
    309327    }
    310328
     
    314332     * @return the currently active layer. null, if currently no active layer exists
    315333     */
    316334    public Layer getActiveLayer() {
    317         if (map == null) return null;
    318         if (map.mapView == null) return null;
     335        if (map == null)
     336            return null;
     337        if (map.mapView == null)
     338            return null;
    319339        return map.mapView.getActiveLayer();
    320340    }
    321341
    322     protected static JPanel contentPanePrivate = new JPanel(new BorderLayout());
    323 
    324342    /**
    325343     * @deprecated If you just need to register shortcut for action, use registerActionShortcut instead of accessing InputMap directly
    326344     */
     
    338356        InputMap inputMap = contentPanePrivate.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
    339357        Object existing = inputMap.get(keyStroke);
    340358        if (existing != null && !existing.equals(action)) {
    341             System.out.println(String.format("Keystroke %s is already assigned to %s, will be overridden by %s", keyStroke, existing, action));
     359            System.out.println(String.format("Keystroke %s is already assigned to %s, will be overridden by %s",
     360                    keyStroke, existing, action));
    342361        }
    343362        inputMap.put(keyStroke, action);
    344363
     
    358377        contentPanePrivate.getActionMap().remove(action);
    359378    }
    360379
    361 
    362380    ///////////////////////////////////////////////////////////////////////////
    363381    //  Implementation part
    364382    ///////////////////////////////////////////////////////////////////////////
     
    375393        }
    376394    };
    377395
     396    /*    private final List<ToggleDialog> toggleDialogs = new ArrayList<ToggleDialog>();
     397    public IconToggleButton addToggleDialog(final ToggleDialog dlg) {
     398        toggleDialogs.add(tg);
     399        final IconToggleButton button = new IconToggleButton(dlg.getToggleAction());
     400        button.addMouseListener(new PopupMenuLauncher(new JPopupMenu() {
     401            {
     402                add(new AbstractAction() {
     403                    {
     404                        putValue(NAME, tr("Hide this button"));
     405                        putValue(SHORT_DESCRIPTION, tr("Click the arrow at the bottom to show it again."));
     406                    }
     407
     408                    @Override
     409                    public void actionPerformed(ActionEvent e) {
     410                        dlg.hideButton();
     411                        validateToolBarToggle();
     412                    }
     413                });
     414            }
     415        }));
     416        dlg.setButton(button);
     417        if (button.isVisible()) {
     418            toolBarToggle.add(button);
     419        }
     420        allDialogs.add(dlg);
     421        if (dialogsPanel.initialized) {
     422            dialogsPanel.add(dlg);
     423        }
     424        return button;
     425    }
     426
     427    public List<ToggleDialog> getToggleDialogs() {
     428        return toggleDialogs;
     429    }
     430
     431    public void validateToolBarToggle() {
     432        toolBarToggle.removeAll();
     433        for (ToggleDialog dlg : allDialogs) {
     434            if (dlg.getButton().isVisible()) {
     435                toolBarToggle.add(dlg.getButton());
     436            }
     437        }
     438    }*/
     439
    378440    /**
    379441     * Should be called before the main constructor to setup some parameter stuff
    380442     * @param args The parsed argument list.
     
    387449            String laf = Main.pref.get("laf", defaultlaf);
    388450            try {
    389451                UIManager.setLookAndFeel(laf);
    390             }
    391             catch (final java.lang.ClassNotFoundException e) {
     452            } catch (final java.lang.ClassNotFoundException e) {
    392453                System.out.println("Look and Feel not found: " + laf);
    393454                Main.pref.put("laf", defaultlaf);
    394             }
    395             catch (final javax.swing.UnsupportedLookAndFeelException e) {
     455            } catch (final javax.swing.UnsupportedLookAndFeelException e) {
    396456                System.out.println("Look and Feel not supported: " + laf);
    397457                Main.pref.put("laf", defaultlaf);
    398458            }
     
    458518            }
    459519        }
    460520        if (bounds == null) {
    461             bounds = !args.containsKey("no-maximize") ? new Rectangle(0,0,screenDimension.width,screenDimension.height) : new Rectangle(1000,740);
     521            bounds = !args.containsKey("no-maximize") ? new Rectangle(0, 0, screenDimension.width,
     522                    screenDimension.height) : new Rectangle(1000, 740);
    462523        }
    463524    }
    464525
     
    478539                    try {
    479540                        f = new File(new URI(s));
    480541                    } catch (URISyntaxException e) {
    481                         JOptionPane.showMessageDialog(
    482                                 Main.parent,
    483                                 tr("Ignoring malformed file URL: \"{0}\"", s),
    484                                 tr("Warning"),
    485                                 JOptionPane.WARNING_MESSAGE
    486                         );
     542                        JOptionPane.showMessageDialog(Main.parent, tr("Ignoring malformed file URL: \"{0}\"", s),
     543                                tr("Warning"), JOptionPane.WARNING_MESSAGE);
    487544                    }
    488545                    if (f!=null) {
    489546                        fileList.add(f);
     
    495552                    break;
    496553                }
    497554            }
    498             if(!fileList.isEmpty())
    499             {
     555            if (!fileList.isEmpty()) {
    500556                OpenFileAction.openFiles(fileList, true);
    501557            }
    502558        }
     
    511567                    break;
    512568                case fileUrl:
    513569                case fileName:
    514                     JOptionPane.showMessageDialog(
    515                             Main.parent,
    516                             tr("Parameter \"downloadgps\" does not accept file names or file URLs"),
    517                             tr("Warning"),
    518                             JOptionPane.WARNING_MESSAGE
    519                     );
     570                    JOptionPane.showMessageDialog(Main.parent,
     571                            tr("Parameter \"downloadgps\" does not accept file names or file URLs"), tr("Warning"),
     572                            JOptionPane.WARNING_MESSAGE);
    520573                }
    521574            }
    522575        }
     
    528581    }
    529582
    530583    public static boolean saveUnsavedModifications() {
    531         if (map == null) return true;
     584        if (map == null)
     585            return true;
    532586        SaveLayersDialog dialog = new SaveLayersDialog(Main.parent);
    533587        List<OsmDataLayer> layersWithUnmodifiedChanges = new ArrayList<OsmDataLayer>();
    534588        for (OsmDataLayer l: Main.map.mapView.getLayersOfType(OsmDataLayer.class)) {
     
    541595            dialog.getModel().populate(layersWithUnmodifiedChanges);
    542596            dialog.setVisible(true);
    543597            switch(dialog.getUserAction()) {
    544             case CANCEL: return false;
    545             case PROCEED: return true;
    546             default: return false;
     598            case CANCEL:
     599                return false;
     600            case PROCEED:
     601                return true;
     602            default:
     603                return false;
    547604            }
    548605        }
    549606
     
    573630     * The type of a command line parameter, to be used in switch statements.
    574631     * @see paramType
    575632     */
    576     private enum DownloadParamType { httpUrl, fileUrl, bounds, fileName }
     633    private enum DownloadParamType {
     634        httpUrl, fileUrl, bounds, fileName
     635    }
    577636
    578637    /**
    579638     * Guess the type of a parameter string specified on the command line with --download= or --downloadgps.
     
    581640     * @return The guessed parameter type
    582641     */
    583642    private DownloadParamType paramType(String s) {
    584         if(s.startsWith("http:")) return DownloadParamType.httpUrl;
    585         if(s.startsWith("file:")) return DownloadParamType.fileUrl;
     643        if (s.startsWith("http:"))
     644            return DownloadParamType.httpUrl;
     645        if (s.startsWith("file:"))
     646            return DownloadParamType.fileUrl;
    586647        final StringTokenizer st = new StringTokenizer(s, ",");
    587648        // we assume a string with exactly 3 commas is a bounds parameter
    588         if (st.countTokens() == 4) return DownloadParamType.bounds;
     649        if (st.countTokens() == 4)
     650            return DownloadParamType.bounds;
    589651        // everything else must be a file name
    590652        return DownloadParamType.fileName;
    591653    }
     
    598660    private static void downloadFromParamHttp(final boolean rawGps, String s) {
    599661        final Bounds b = OsmUrlToBounds.parse(s);
    600662        if (b == null) {
    601             JOptionPane.showMessageDialog(
    602                     Main.parent,
    603                     tr("Ignoring malformed URL: \"{0}\"", s),
    604                     tr("Warning"),
    605                     JOptionPane.WARNING_MESSAGE
    606             );
     663            JOptionPane.showMessageDialog(Main.parent, tr("Ignoring malformed URL: \"{0}\"", s), tr("Warning"),
     664                    JOptionPane.WARNING_MESSAGE);
    607665        } else {
    608666            downloadFromParamBounds(rawGps, b);
    609667        }
     
    617675    private static void downloadFromParamBounds(final boolean rawGps, String s) {
    618676        final StringTokenizer st = new StringTokenizer(s, ",");
    619677        if (st.countTokens() == 4) {
    620             Bounds b = new Bounds(
    621                     new LatLon(Double.parseDouble(st.nextToken()),Double.parseDouble(st.nextToken())),
    622                     new LatLon(Double.parseDouble(st.nextToken()),Double.parseDouble(st.nextToken()))
    623             );
     678            Bounds b = new Bounds(new LatLon(Double.parseDouble(st.nextToken()), Double.parseDouble(st.nextToken())),
     679                    new LatLon(Double.parseDouble(st.nextToken()), Double.parseDouble(st.nextToken())));
    624680            downloadFromParamBounds(rawGps, b);
    625681        }
    626682    }
     
    647703            platform = new PlatformHookUnixoid();
    648704        } else if (os.toLowerCase().startsWith("windows")) {
    649705            platform = new PlatformHookWindows();
    650         } else if (os.equals("Linux") || os.equals("Solaris") ||
    651                 os.equals("SunOS") || os.equals("AIX") ||
    652                 os.equals("FreeBSD") || os.equals("NetBSD") || os.equals("OpenBSD")) {
     706        } else if (os.equals("Linux") || os.equals("Solaris") || os.equals("SunOS") || os.equals("AIX")
     707                || os.equals("FreeBSD") || os.equals("NetBSD") || os.equals("OpenBSD")) {
    653708            platform = new PlatformHookUnixoid();
    654709        } else if (os.toLowerCase().startsWith("mac os x")) {
    655710            platform = new PlatformHookOsx();
    656711        } else {
    657             System.err.println("I don't know your operating system '"+os+"', so I'm guessing its some kind of *nix.");
     712            System.err.println("I don't know your operating system '" + os
     713                    + "', so I'm guessing its some kind of *nix.");
    658714            platform = new PlatformHookUnixoid();
    659715        }
    660716    }
     
    689745                    newToggleDlgWidth = "";
    690746                }
    691747            }
    692         }
    693         catch (Exception e) {
     748        } catch (Exception e) {
    694749            System.out.println("Failed to get GUI geometry: " + e);
    695750            e.printStackTrace();
    696751        }
     
    702757            pref.put("toggleDialogs.width", newToggleDlgWidth);
    703758        }
    704759    }
    705     private static class WindowPositionSizeListener extends WindowAdapter implements
    706     ComponentListener {
     760
     761    private static class WindowPositionSizeListener extends WindowAdapter implements ComponentListener {
    707762
    708763        @Override
    709764        public void windowStateChanged(WindowEvent e) {
     
    738793        }
    739794
    740795    }
     796
    741797    public static void addListener() {
    742798        parent.addComponentListener(new WindowPositionSizeListener());
    743799        ((JFrame)parent).addWindowStateListener(new WindowPositionSizeListener());
     
    746802    public static void checkJava6() {
    747803        String version = System.getProperty("java.version");
    748804        if (version != null) {
    749             if (version.startsWith("1.6") || version.startsWith("6") ||
    750                     version.startsWith("1.7") || version.startsWith("7"))
     805            if (version.startsWith("1.6") || version.startsWith("6") || version.startsWith("1.7")
     806                    || version.startsWith("7"))
    751807                return;
    752808            if (version.startsWith("1.5") || version.startsWith("5")) {
    753                 JLabel ho = new JLabel("<html>"+
    754                         tr("<h2>JOSM requires Java version 6.</h2>"+
    755                                 "Detected Java version: {0}.<br>"+
    756                                 "You can <ul><li>update your Java (JRE) or</li>"+
    757                                 "<li>use an earlier (Java 5 compatible) version of JOSM.</li></ul>"+
    758                                 "More Info:", version)+"</html>");
     809                JLabel ho = new JLabel("<html>"
     810                        + tr("<h2>JOSM requires Java version 6.</h2>" + "Detected Java version: {0}.<br>"
     811                                + "You can <ul><li>update your Java (JRE) or</li>"
     812                                + "<li>use an earlier (Java 5 compatible) version of JOSM.</li></ul>" + "More Info:",
     813                                version) + "</html>");
    759814                JTextArea link = new JTextArea("http://josm.openstreetmap.de/wiki/Help/SystemRequirements");
    760815                link.setEditable(false);
    761816                link.setBackground(panel.getBackground());
     
    768823                panel.add(link, gbc);
    769824                final String EXIT = tr("Exit JOSM");
    770825                final String CONTINUE = tr("Continue, try anyway");
    771                 int ret = JOptionPane.showOptionDialog(null, panel, tr("Error"), JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE, null, new String[] {EXIT, CONTINUE}, EXIT);
     826                int ret = JOptionPane.showOptionDialog(null, panel, tr("Error"), JOptionPane.YES_NO_OPTION,
     827                        JOptionPane.ERROR_MESSAGE, null, new String[] { EXIT, CONTINUE }, EXIT);
    772828                if (ret == 0) {
    773829                    System.exit(0);
    774830                }
     
    852908     * @param listener the listener. Ignored if null.
    853909     */
    854910    public static void addProjectionChangeListener(ProjectionChangeListener listener) {
    855         if (listener == null) return;
     911        if (listener == null)
     912            return;
    856913        synchronized (Main.class) {
    857914            for (WeakReference<ProjectionChangeListener> wr : listeners) {
    858915                // already registered ? => abort
    859                 if (wr.get() == listener) return;
     916                if (wr.get() == listener)
     917                    return;
    860918            }
    861919        }
    862920        listeners.add(new WeakReference<ProjectionChangeListener>(listener));
     
    868926     * @param listener the listener. Ignored if null.
    869927     */
    870928    public static void removeProjectionChangeListener(ProjectionChangeListener listener) {
    871         if (listener == null) return;
     929        if (listener == null)
     930            return;
    872931        synchronized(Main.class){
    873932            Iterator<WeakReference<ProjectionChangeListener>> it = listeners.iterator();
    874933            while(it.hasNext()){
  • src/org/openstreetmap/josm/gui/MainMenu.java

     
    1111import javax.swing.JMenu;
    1212import javax.swing.JMenuBar;
    1313import javax.swing.JMenuItem;
     14import javax.swing.JPopupMenu;
     15import javax.swing.JSeparator;
    1416import javax.swing.KeyStroke;
     17import javax.swing.event.MenuEvent;
     18import javax.swing.event.MenuListener;
    1519
    1620import org.openstreetmap.josm.Main;
    1721import org.openstreetmap.josm.actions.AboutAction;
     
    5256import org.openstreetmap.josm.actions.OpenFileAction;
    5357import org.openstreetmap.josm.actions.OpenLocationAction;
    5458import org.openstreetmap.josm.actions.OrthogonalizeAction;
    55 import org.openstreetmap.josm.actions.OrthogonalizeAction.Undo;
    5659import org.openstreetmap.josm.actions.PasteAction;
    5760import org.openstreetmap.josm.actions.PasteTagsAction;
    5861import org.openstreetmap.josm.actions.PreferencesAction;
     
    7881import org.openstreetmap.josm.actions.WireframeToggleAction;
    7982import org.openstreetmap.josm.actions.ZoomInAction;
    8083import org.openstreetmap.josm.actions.ZoomOutAction;
     84import org.openstreetmap.josm.actions.OrthogonalizeAction.Undo;
    8185import org.openstreetmap.josm.actions.audio.AudioBackAction;
    8286import org.openstreetmap.josm.actions.audio.AudioFasterAction;
    8387import org.openstreetmap.josm.actions.audio.AudioFwdAction;
     
    184188    public final JMenu presetsMenu = addMenu(marktr("Presets"), KeyEvent.VK_P, 4, ht("/Menu/Presets"));
    185189    public final ImageryMenu imageryMenu =
    186190        (ImageryMenu)addMenu(new ImageryMenu(), marktr("Imagery"), KeyEvent.VK_I, 5, ht("/Menu/Imagery"));
     191    /** the window menu is split into several groups. The first is for windows that can be opened from
     192     * this menu any time, e.g. the changeset editor. The second group is for toggle dialogs and the third
     193     * group is for currently open windows that cannot be toggled, e.g. relation editors. It's recommended
     194     * to use WINDOW_MENU_GROUP to determine the group integer.
     195     */
     196    public final JMenu windowMenu = addMenu(marktr("Windows"), KeyEvent.VK_W, 6, ht("/Menu/Windows"));
     197    public static enum WINDOW_MENU_GROUP { ALWAYS, TOGGLE_DIALOG, VOLATILE }
     198
    187199    public JMenu audioMenu = null;
    188     public final JMenu helpMenu = addMenu(marktr("Help"), KeyEvent.VK_H, 6, ht("/Menu/Help"));
    189     public final int defaultMenuPos = 6;
     200    public final JMenu helpMenu = addMenu(marktr("Help"), KeyEvent.VK_H, 7, ht("/Menu/Help"));
     201    public final int defaultMenuPos = 7;
    190202
    191203    public final JosmAction moveUpAction = new MoveAction(MoveAction.Direction.UP);
    192204    public final JosmAction moveDownAction = new MoveAction(MoveAction.Direction.DOWN);
     
    196208
    197209    public final TaggingPresetSearchAction presetSearchAction = new TaggingPresetSearchAction();
    198210    public FullscreenToggleAction fullscreenToggleAction = null;
     211
     212    /** this menu listener hides unnecessary JSeparators in a menu list but does not remove them.
     213     * If at a later time the separators are required, they will be made visible again. Intended
     214     * usage is make menus not look broken if separators are used to group the menu and some of
     215     * these groups are empty.
     216     */
     217    public final static MenuListener menuSeparatorHandler = new MenuListener() {
     218        @Override
     219        public void menuCanceled(MenuEvent arg0) {}
     220        @Override
     221        public void menuDeselected(MenuEvent arg0) {}
     222        @Override
     223        public void menuSelected(MenuEvent a) {
     224            if(!(a.getSource() instanceof JMenu))
     225                return;
     226            final JPopupMenu m = ((JMenu) a.getSource()).getPopupMenu();
     227            for(int i=0; i < m.getComponentCount()-1; i++) {
     228                if(!(m.getComponent(i) instanceof JSeparator)) {
     229                    continue;
     230                }
     231                // hide separator if the next menu item is one as well
     232                ((JSeparator) m.getComponent(i)).setVisible(!(m.getComponent(i+1) instanceof JSeparator));
     233            }
     234            // hide separator at the end of the menu
     235            if(m.getComponent(m.getComponentCount()-1) instanceof JSeparator) {
     236                ((JSeparator) m.getComponent(m.getComponentCount()-1)).setVisible(false);
     237            }
     238        }
     239    };
     240
    199241    /**
    200242     * Add a JosmAction to a menu.
    201243     *
    202244     * This method handles all the shortcut handling. It also makes sure that actions that are
    203      * handled by the OS are not duplicated on the menu.
     245     * handled by the OS are not duplicated on the menu. Menu item will be added at the end of
     246     * the menu.
     247     * @param menu to add the action to
     248     * @param the action that should get a menu item
    204249     */
    205250    public static JMenuItem add(JMenu menu, JosmAction action) {
    206         JMenuItem menuitem = null;
    207         if (!action.getShortcut().getAutomatic()) {
    208             menuitem = menu.add(action);
     251        if (action.getShortcut().getAutomatic())
     252            return null;
     253        JMenuItem menuitem = menu.add(action);
    209254            KeyStroke ks = action.getShortcut().getKeyStroke();
    210255            if (ks != null) {
    211256                menuitem.setAccelerator(ks);
    212257            }
     258        return menuitem;
     259    }
     260
     261    /**
     262     * Add a JosmAction to a menu.
     263     *
     264     * This method handles all the shortcut handling. It also makes sure that actions that are
     265     * handled by the OS are not duplicated on the menu.
     266     * @param menu to add the action to
     267     * @param the action that should get a menu item
     268     * @param group the item should be added to. Groups are split by a separator.
     269     *        0 is the first group, -1 will add the item to the end.
     270     */
     271    public static <E extends Enum<E>> JMenuItem add(JMenu menu, JosmAction action, Enum<E> group) {
     272        if (action.getShortcut().getAutomatic())
     273            return null;
     274        int i = getInsertionIndexForGroup(menu, group.ordinal());
     275        JMenuItem menuitem = (JMenuItem) menu.add(new JMenuItem(action), i);
     276        KeyStroke ks = action.getShortcut().getKeyStroke();
     277        if (ks != null) {
     278            menuitem.setAccelerator(ks);
    213279        }
    214280        return menuitem;
    215281    }
    216282
     283    /**
     284     * Add a JosmAction to a menu and automatically prints accelerator if available.
     285     * Also adds a checkbox that may be toggled.
     286     * @param menu to add the action to
     287     * @param the action that should get a menu item
     288     * @param group the item should be added to. Groups are split by a separator. Use
     289     *        one of the enums that are defined for some of the menus to tell in which
     290     *        group the item should go.
     291     */
     292    public static <E extends Enum<E>> JCheckBoxMenuItem addWithCheckbox(JMenu menu, JosmAction action, Enum<E> group) {
     293        int i = getInsertionIndexForGroup(menu, group.ordinal());
     294        final JCheckBoxMenuItem mi = (JCheckBoxMenuItem) menu.add(new JCheckBoxMenuItem(action), i);
     295        final KeyStroke ks = action.getShortcut().getKeyStroke();
     296        if (ks != null) {
     297            mi.setAccelerator(ks);
     298        }
     299        return mi;
     300    }
     301
     302    /** finds the correct insertion index for a given group and adds separators if necessary */
     303    private static int getInsertionIndexForGroup(JMenu menu, int group) {
     304        if(group < 0)
     305            return -1;
     306        // look for separator that *ends* the group (or stop at end of menu)
     307        int i;
     308        for(i=0; i < menu.getItemCount() && group >= 0; i++) {
     309            if(menu.getItem(i) == null) {
     310                group--;
     311            }
     312        }
     313        // insert before separator that ends the group
     314        if(group < 0) {
     315            i--;
     316        }
     317        // not enough separators have been found, add them
     318        while(group > 0) {
     319            menu.addSeparator();
     320            group--;
     321            i++;
     322        }
     323        return i;
     324    }
     325
    217326    public JMenu addMenu(String name, int mnemonicKey, int position, String relativeHelpTopic) {
    218327        return addMenu(new JMenu(tr(name)), name, mnemonicKey, position, relativeHelpTopic);
    219328    }
     
    294403        vft.setAccelerator(viewportFollowToggleAction.getShortcut().getKeyStroke());
    295404        viewportFollowToggleAction.addButtonModel(vft.getModel());
    296405
    297         // -- changeset manager toggle action
    298         ChangesetManagerToggleAction changesetManagerToggleAction = new ChangesetManagerToggleAction();
    299         final JCheckBoxMenuItem mi = new JCheckBoxMenuItem(changesetManagerToggleAction);
    300         viewMenu.addSeparator();
    301         viewMenu.add(mi);
    302         mi.setAccelerator(changesetManagerToggleAction.getShortcut().getKeyStroke());
    303         changesetManagerToggleAction.addButtonModel(mi.getModel());
    304 
    305406        if(!Main.applet && Main.platform.canFullscreen()) {
    306407            // -- fullscreen toggle action
    307408            fullscreenToggleAction = new FullscreenToggleAction();
     
    341442        add(toolsMenu, joinAreas);
    342443        add(toolsMenu, createMultipolygon);
    343444
     445        // -- changeset manager toggle action
     446        ChangesetManagerToggleAction changesetManagerToggleAction = new ChangesetManagerToggleAction();
     447        final JCheckBoxMenuItem mi = MainMenu.addWithCheckbox(windowMenu, changesetManagerToggleAction,
     448                MainMenu.WINDOW_MENU_GROUP.ALWAYS);
     449        changesetManagerToggleAction.addButtonModel(mi.getModel());
     450
     451
    344452        if (!Main.pref.getBoolean("audio.menuinvisible", false)) {
    345453            audioMenu = addMenu(marktr("Audio"), KeyEvent.VK_A, defaultMenuPos, ht("/Menu/Audio"));
    346454            add(audioMenu, audioPlayPause);
     
    359467                Shortcut.GROUP_DIRECT).getKeyStroke());
    360468        add(helpMenu, about);
    361469
     470
     471        windowMenu.addMenuListener(menuSeparatorHandler);
     472
    362473        new PresetsMenuEnabler(presetsMenu).refreshEnabled();
    363474    }
    364475
  • src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java

     
    2525import javax.swing.BorderFactory;
    2626import javax.swing.ImageIcon;
    2727import javax.swing.JButton;
     28import javax.swing.JCheckBoxMenuItem;
    2829import javax.swing.JComponent;
    2930import javax.swing.JDialog;
    3031import javax.swing.JLabel;
     
    3435
    3536import org.openstreetmap.josm.Main;
    3637import org.openstreetmap.josm.actions.JosmAction;
     38import org.openstreetmap.josm.gui.MainMenu;
    3739import org.openstreetmap.josm.gui.dialogs.DialogsPanel.Action;
    3840import org.openstreetmap.josm.gui.help.HelpUtil;
    3941import org.openstreetmap.josm.gui.help.Helpful;
     
    4749 *
    4850 */
    4951public class ToggleDialog extends JPanel implements Helpful {
    50 
    5152    /** The action to toggle this dialog */
    5253    protected ToggleDialogAction toggleAction;
    5354    protected String preferencePrefix;
     
    8586    protected JToggleButton button;
    8687    protected boolean buttonHidden;
    8788
     89    /** holds the menu entry in the windows menu. Required to properly
     90     * toggle the checkbox on show/hide
     91     */
     92    protected JCheckBoxMenuItem windowMenuItem;
     93
    8894    /**
    8995     * Constructor
    9096     * (see below)
     
    132138        buttonHidden = Main.pref.getBoolean(preferencePrefix+".button_hidden", false);
    133139
    134140        RedirectInputMap.redirectToMainContentPane(this);
     141
     142        windowMenuItem = MainMenu.addWithCheckbox(Main.main.menu.windowMenu,
     143                (JosmAction) getToggleAction(),
     144                MainMenu.WINDOW_MENU_GROUP.TOGGLE_DIALOG);
    135145    }
    136146
    137147    /**
     
    152162
    153163        public void actionPerformed(ActionEvent e) {
    154164            toggleButtonHook();
     165            if(getValue("toolbarbutton") != null && getValue("toolbarbutton") instanceof JButton) {
     166                ((JButton) getValue("toolbarbutton")).setSelected(!isShowing);
     167            }
    155168            if (isShowing) {
    156169                hideDialog();
    157170                dialogsPanel.reconstruct(Action.ELEMENT_SHRINKS, null);
     
    187200        }
    188201        // toggling the selected value in order to enforce PropertyChangeEvents
    189202        setIsShowing(true);
     203        windowMenuItem.setState(true);
    190204        toggleAction.putValue("selected", false);
    191205        toggleAction.putValue("selected", true);
    192206    }
     
    244258    public void hideDialog() {
    245259        closeDetachedDialog();
    246260        this.setVisible(false);
     261        windowMenuItem.setState(false);
    247262        setIsShowing(false);
    248263        toggleAction.putValue("selected", false);
    249264    }
     
    322337    public void destroy() {
    323338        closeDetachedDialog();
    324339        hideNotify();
     340        Main.main.menu.windowMenu.remove(windowMenuItem);
    325341    }
    326342
    327343    /**
  • src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java

     
    3434import javax.swing.BorderFactory;
    3535import javax.swing.JComponent;
    3636import javax.swing.JLabel;
     37import javax.swing.JMenu;
     38import javax.swing.JMenuItem;
    3739import javax.swing.JOptionPane;
    3840import javax.swing.JPanel;
    3941import javax.swing.JScrollPane;
     
    5355
    5456import org.openstreetmap.josm.Main;
    5557import org.openstreetmap.josm.actions.CopyAction;
     58import org.openstreetmap.josm.actions.JosmAction;
    5659import org.openstreetmap.josm.actions.PasteTagsAction.TagPaster;
    5760import org.openstreetmap.josm.command.AddCommand;
    5861import org.openstreetmap.josm.command.ChangeCommand;
     
    6770import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil;
    6871import org.openstreetmap.josm.gui.DefaultNameFormatter;
    6972import org.openstreetmap.josm.gui.HelpAwareOptionPane;
    70 import org.openstreetmap.josm.gui.HelpAwareOptionPane.ButtonSpec;
     73import org.openstreetmap.josm.gui.MainMenu;
    7174import org.openstreetmap.josm.gui.SideButton;
     75import org.openstreetmap.josm.gui.HelpAwareOptionPane.ButtonSpec;
    7276import org.openstreetmap.josm.gui.dialogs.properties.PresetListPanel.PresetHandler;
    7377import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction;
    7478import org.openstreetmap.josm.gui.help.HelpUtil;
     
    101105
    102106    private AutoCompletingTextField tfRole;
    103107
     108    /** the menu item in the windows menu. Required to properly
     109     * hide on dialog close.
     110     */
     111    private JMenuItem windowMenuItem;
     112
    104113    /**
    105114     * Creates a new relation editor for the given relation. The relation will be saved if the user
    106115     * selects "ok" in the editor.
     
    574583        super.setVisible(visible);
    575584        if (visible) {
    576585            RelationDialogManager.getRelationDialogManager().positionOnScreen(this);
     586            if(windowMenuItem == null) {
     587                addToWindowMenu();
     588            }
    577589        } else {
    578590            // make sure all registered listeners are unregistered
    579591            //
    580592            selectionTableModel.unregister();
    581593            memberTableModel.unregister();
    582594            memberTable.unlinkAsListener();
     595            if(windowMenuItem != null) {
     596                Main.main.menu.windowMenu.remove(windowMenuItem);
     597                windowMenuItem = null;
     598            }
    583599            dispose();
    584600        }
    585601    }
    586602
     603    /** adds current relation editor to the windows menu (in the "volatile" group) o*/
     604    protected void addToWindowMenu() {
     605        String name = getRelation() == null ? tr("New Relation") : getRelation().getLocalName();
     606        final String tt = tr("Focus Relation Editor with relation ''{0}'' in layer ''{1}''",
     607                name, getLayer().getName());
     608        name = tr("Relation Editor: {0}", name == null ? getRelation().getId() : name);
     609        final JMenu wm = Main.main.menu.windowMenu;
     610        final JosmAction focusAction = new JosmAction(name, "dialogs/relationlist", tt, null, false, false) {
     611            @Override
     612            public void actionPerformed(ActionEvent e) {
     613                final RelationEditor r = (RelationEditor) getValue("relationEditor");
     614                r.setVisible(true);
     615            }
     616        };
     617        focusAction.putValue("relationEditor", this);
     618        windowMenuItem = MainMenu.add(wm, focusAction, MainMenu.WINDOW_MENU_GROUP.VOLATILE);
     619    }
     620
    587621    /**
    588622     * checks whether the current relation has members referring to itself. If so,
    589623     * warns the users and provides an option for removing these members.
  • src/org/openstreetmap/josm/gui/help/HelpBrowser.java

     
    2424import javax.swing.JComponent;
    2525import javax.swing.JDialog;
    2626import javax.swing.JEditorPane;
     27import javax.swing.JMenuItem;
    2728import javax.swing.JOptionPane;
    2829import javax.swing.JPanel;
    2930import javax.swing.JScrollPane;
     
    4445import javax.swing.text.html.HTML.Tag;
    4546
    4647import org.openstreetmap.josm.Main;
     48import org.openstreetmap.josm.actions.JosmAction;
    4749import org.openstreetmap.josm.gui.HelpAwareOptionPane;
     50import org.openstreetmap.josm.gui.MainMenu;
    4851import org.openstreetmap.josm.tools.ImageProvider;
    4952import org.openstreetmap.josm.tools.OpenBrowser;
    5053import org.openstreetmap.josm.tools.WindowGeometry;
     
    5356    /** the unique instance */
    5457    private static HelpBrowser instance;
    5558
     59    /** the menu item in the windows menu. Required to properly
     60     * hide on dialog close.
     61     */
     62    private JMenuItem windowMenuItem;
     63
    5664    /**
    5765     * Replies the unique instance of the help browser
    5866     *
     
    106114
    107115    private HelpContentReader reader;
    108116
     117    private static final JosmAction focusAction = new JosmAction(tr("JOSM Help Browser"), "help", "", null, false, false) {
     118        @Override
     119        public void actionPerformed(ActionEvent e) {
     120            HelpBrowser.getInstance().setVisible(true);
     121        }
     122    };
     123
    109124    /**
    110125     * Builds the style sheet used in the internal help browser
    111126     *
     
    193208        } else if (!visible && isShowing()){
    194209            new WindowGeometry(this).remember(getClass().getName() + ".geometry");
    195210        }
     211        if(windowMenuItem != null && !visible) {
     212            Main.main.menu.windowMenu.remove(windowMenuItem);
     213            windowMenuItem = null;
     214        }
     215        if(windowMenuItem == null && visible) {
     216            windowMenuItem = MainMenu.add(Main.main.menu.windowMenu, focusAction, MainMenu.WINDOW_MENU_GROUP.VOLATILE);
     217        }
    196218        super.setVisible(visible);
    197219    }
    198220
  • src/org/openstreetmap/josm/gui/preferences/ToolbarPreferences.java

     
    2626import java.util.List;
    2727import java.util.Map;
    2828
    29 import javax.swing.AbstractAction;
    3029import javax.swing.Action;
    3130import javax.swing.DefaultListCellRenderer;
    3231import javax.swing.DefaultListModel;
     
    214213                    String paramName = readTillChar('=', '=');
    215214                    skip('=');
    216215                    String paramValue = readTillChar(',','}');
    217                     if ("icon".equals(paramName) && paramValue.length() > 0)
     216                    if ("icon".equals(paramName) && paramValue.length() > 0) {
    218217                        result.setIcon(paramValue);
    219                     else if("name".equals(paramName) && paramValue.length() > 0)
     218                    } else if("name".equals(paramName) && paramValue.length() > 0) {
    220219                        result.setName(paramValue);
     220                    }
    221221                    skip(',');
    222222                }
    223223                skip('}');
     
    280280                    escape(tmp);
    281281                    first = false;
    282282                }
    283                 if(!first)
     283                if(!first) {
    284284                    result.append('}');
    285285            }
     286            }
    286287
    287288            return result.toString();
    288289        }
     
    322323                    default:
    323324                        return null;
    324325                    }
    325                 } else
     326                } else {
    326327                    rowIndex -= 2;
    327328            }
     329            }
    328330            ActionParameter<Object> param = getParam(rowIndex);
    329331            switch (columnIndex) {
    330332            case 0:
     
    351353                } else if (rowIndex == 1) {
    352354                     currentAction.setIcon((String)aValue);
    353355                     return;
    354                 } else
     356                } else {
    355357                    rowIndex -= 2;
    356358            }
     359            }
    357360            ActionParameter<Object> param = getParam(rowIndex);
    358361            currentAction.getParameters().put(param.getName(), param.readFromString((String)aValue));
    359362        }
     
    756759                    t.add("|");
    757760                } else {
    758761                    String res = parser.saveAction(action);
    759                     if(res != null)
     762                    if(res != null) {
    760763                        t.add(res);
    761764                }
    762765            }
     766            }
    763767            if (t.isEmpty()) {
    764768                t = Collections.singletonList(EMPTY_TOOLBAR_MARKER);
    765769            }
     
    901905    }
    902906
    903907    /**
    904      * Parse the toolbar preference setting and construct the toolbar GUI control.
     908     * Parse the toolbar preference setting and construct the c GUI control.
    905909     *
    906910     * Call this, if anything has changed in the toolbar settings and you want to refresh
    907911     * the toolbar content (e.g. after registering actions in a plugin)
     
    915919            } else {
    916920                JButton b = control.add(action.getParametrizedAction());
    917921                String tt = action.getDisplayTooltip();
    918                 if (tt != null && !tt.isEmpty())
     922                if (tt != null && !tt.isEmpty()) {
    919923                    b.setToolTipText(tt);
     924                }
    920925                Icon i = action.getDisplayIcon();
    921                 if (i != null)
     926                if (i != null) {
    922927                    b.setIcon(i);
    923928            }
    924929        }
     930        }
    925931        control.setVisible(control.getComponentCount() != 0);
    926932    }
    927933
  • src/org/openstreetmap/josm/gui/MapFrame.java

     
    115115    private final Map<Layer, MapMode> lastMapMode = new HashMap<Layer, MapMode>();
    116116
    117117    public MapFrame(JPanel contentPane) {
     118        // don't show right now because it is initialized before there are any layers
     119        setVisible(false);
     120
    118121        setSize(400,400);
    119122        setLayout(new BorderLayout());
    120123
     
    122125
    123126        new FileDrop(mapView);
    124127
    125         // show menu entry
    126         Main.main.menu.viewMenu.setVisible(true);
    127 
    128128        // toolbar
    129129        toolBarActions.setFloatable(false);
    130130        addMapMode(new IconToggleButton(new SelectAction(this)));
     
    311311        boolean old = isVisible();
    312312        super.setVisible(aFlag);
    313313        if (old != aFlag) {
     314            // show or hide menu entry
     315            Main.main.menu.viewMenu.setVisible(aFlag);
    314316            firePropertyChange("visible", old, aFlag);
    315317        }
    316318    }