Ticket #8652: revised-dialogs-toggle-action.patch

File revised-dialogs-toggle-action.patch, 46.0 KB (added by cmuelle8, 6 years ago)

revised-dialogs-toggle-action.patch

  • org/openstreetmap/josm/actions/DialogsToggleAction.java

     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.actions;
     3
     4import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
     5import static org.openstreetmap.josm.tools.I18n.tr;
     6
     7import java.awt.event.ActionEvent;
     8import java.awt.event.KeyEvent;
     9import java.util.ArrayList;
     10import java.util.List;
     11
     12import javax.swing.ButtonModel;
     13
     14import org.openstreetmap.josm.Main;
     15import org.openstreetmap.josm.tools.Shortcut;
     16
     17public class DialogsToggleAction extends JosmAction {
     18    private final List<ButtonModel> buttonModels = new ArrayList<ButtonModel>();
     19    private boolean selected;
     20
     21    public DialogsToggleAction() {
     22        super(
     23                tr("Toggle dialogs panel"),
     24                null, /* no icon */
     25                tr("Toggle dialogs panel, maximize mapview"),
     26                Shortcut.registerShortcut("menu:view:dialogspanel", tr("Toggle dialogs panel"),KeyEvent.VK_TAB, Shortcut.DIRECT),
     27                false /* register */
     28        );
     29        putValue("help", ht("/Action/ToggleDialogsPanel"));
     30        putValue("toolbar", "dialogspanel");
     31        Main.toolbar.register(this);
     32        selected = Main.pref.getBoolean("draw.dialogspanel", true);
     33        notifySelectedState();
     34    }
     35
     36    public void addButtonModel(ButtonModel model) {
     37        if (model != null && !buttonModels.contains(model)) {
     38            buttonModels.add(model);
     39        }
     40    }
     41
     42    public void removeButtonModel(ButtonModel model) {
     43        if (model != null && buttonModels.contains(model)) {
     44            buttonModels.remove(model);
     45        }
     46    }
     47
     48    protected void notifySelectedState() {
     49        for (ButtonModel model: buttonModels) {
     50            if (model.isSelected() != selected) {
     51                model.setSelected(selected);
     52            }
     53        }
     54    }
     55
     56    protected void toggleSelectedState() {
     57        selected = !selected;
     58        Main.pref.put("draw.dialogspanel", selected);
     59        notifySelectedState();
     60        setMode();
     61    }
     62
     63    public void initial() {
     64        if(selected) {
     65            setMode();
     66        }
     67    }
     68
     69    protected void setMode() {
     70        if (Main.isDisplayingMapView()) {
     71            Main.map.setDialogsPanelVisible(selected);
     72            Main.map.statusLine.setVisible(selected || Main.pref.getBoolean("statusbar.always-visible", true));
     73            Main.toolbar.control.setVisible(selected || Main.pref.getBoolean("toolbar.always-visible", true));
     74            Main.main.menu.setVisible(selected || Main.pref.getBoolean("menu.always-visible", true));
     75            // sideToolBar listens to preference changes, use it here
     76            if (!Main.pref.getBoolean("sidetoolbar.always-visible", true)) {
     77                Main.pref.put("sidetoolbar.visible", selected);
     78            }
     79        }
     80    }
     81
     82    @Override
     83    public void actionPerformed(ActionEvent e) {
     84        toggleSelectedState();
     85    }
     86}
  • org/openstreetmap/josm/actions/mapmode/DrawAction.java

    Property changes on: org\openstreetmap\josm\actions\DialogsToggleAction.java
    ___________________________________________________________________
    Added: svn:mime-type
       + text/plain
    
     
    127127                mapFrame, ImageProvider.getCursor("crosshair", null));
    128128
    129129        snappingShortcut = Shortcut.registerShortcut("mapmode:drawanglesnapping",
    130                 tr("Mode: Draw Angle snapping"), KeyEvent.VK_TAB, Shortcut.DIRECT);
     130                tr("Mode: Draw Angle snapping"), KeyEvent.CHAR_UNDEFINED, Shortcut.NONE);
    131131        snapChangeAction = new SnapChangeAction();
    132132        snapCheckboxMenuItem = addMenuItem();
    133133        snapHelper.setMenuCheckBox(snapCheckboxMenuItem);
  • org/openstreetmap/josm/gui/MainMenu.java

     
    3333import org.openstreetmap.josm.actions.CreateCircleAction;
    3434import org.openstreetmap.josm.actions.CreateMultipolygonAction;
    3535import org.openstreetmap.josm.actions.DeleteAction;
     36import org.openstreetmap.josm.actions.DialogsToggleAction;
    3637import org.openstreetmap.josm.actions.DistributeAction;
    3738import org.openstreetmap.josm.actions.DownloadAction;
    3839import org.openstreetmap.josm.actions.DownloadPrimitiveAction;
     
    6263import org.openstreetmap.josm.actions.OpenFileAction;
    6364import org.openstreetmap.josm.actions.OpenLocationAction;
    6465import org.openstreetmap.josm.actions.OrthogonalizeAction;
     66import org.openstreetmap.josm.actions.OrthogonalizeAction.Undo;
    6567import org.openstreetmap.josm.actions.PasteAction;
    6668import org.openstreetmap.josm.actions.PasteTagsAction;
     69import org.openstreetmap.josm.actions.PreferenceToggleAction;
    6770import org.openstreetmap.josm.actions.PreferencesAction;
    6871import org.openstreetmap.josm.actions.PurgeAction;
    6972import org.openstreetmap.josm.actions.RedoAction;
     
    9093import org.openstreetmap.josm.actions.WireframeToggleAction;
    9194import org.openstreetmap.josm.actions.ZoomInAction;
    9295import org.openstreetmap.josm.actions.ZoomOutAction;
    93 import org.openstreetmap.josm.actions.OrthogonalizeAction.Undo;
    94 import org.openstreetmap.josm.actions.PreferenceToggleAction;
    9596import org.openstreetmap.josm.actions.audio.AudioBackAction;
    9697import org.openstreetmap.josm.actions.audio.AudioFasterAction;
    9798import org.openstreetmap.josm.actions.audio.AudioFwdAction;
     
    229230    public final JumpToAction jumpToAct = new JumpToAction();
    230231
    231232    public final TaggingPresetSearchAction presetSearchAction = new TaggingPresetSearchAction();
     233    public final DialogsToggleAction dialogsToggleAction = new DialogsToggleAction();
    232234    public FullscreenToggleAction fullscreenToggleAction = null;
    233235
    234236    /** this menu listener hides unnecessary JSeparators in a menu list but does not remove them.
     
    514516            fullscreen.setAccelerator(fullscreenToggleAction.getShortcut().getKeyStroke());
    515517            fullscreenToggleAction.addButtonModel(fullscreen.getModel());
    516518        }
     519
     520        // -- dialogs panel toggle action
     521        final JCheckBoxMenuItem dialogspanel = new JCheckBoxMenuItem(dialogsToggleAction);
     522        dialogspanel.setAccelerator(dialogsToggleAction.getShortcut().getKeyStroke());
     523        dialogsToggleAction.addButtonModel(dialogspanel.getModel());
     524        viewMenu.add(dialogspanel);
     525
    517526        viewMenu.addSeparator();
    518527        add(viewMenu, info);
    519528        add(viewMenu, infoweb);
  • org/openstreetmap/josm/gui/dialogs/properties/TagEditHelper.java

     
    418418
    419419        @Override
    420420        public void setupDialog() {
    421             setResizable(false);
     421            //setResizable(false);
    422422            super.setupDialog();
    423423           
    424424            setRememberWindowGeometry(getClass().getName() + ".geometry",
  • org/openstreetmap/josm/gui/MapView.java

     
    2222import java.util.Collection;
    2323import java.util.Collections;
    2424import java.util.Comparator;
    25 import java.util.Enumeration;
    2625import java.util.LinkedList;
    2726import java.util.List;
    2827import java.util.concurrent.CopyOnWriteArrayList;
     
    779778         * the user to re-select the tool after i.e. moving a layer. While testing I found
    780779         * that I switch layers and actions at the same time and it was annoying to mind the
    781780         * order. This way it works as visual clue for new users */
    782         for (Enumeration<AbstractButton> e = Main.map.toolGroup.getElements() ; e.hasMoreElements() ;) {
    783             AbstractButton button = e.nextElement();
    784             MapMode mode = (MapMode)button.getAction();
    785             boolean isLayerSupported = mode.layerIsSupported(layer);
    786             button.setEnabled(isLayerSupported);
    787             // Also update associated shortcut (fix #6876)
    788             if (isLayerSupported) {
    789                 Main.registerActionShortcut(mode, mode.getShortcut());
     781        for (AbstractButton b: Main.map.allMapModeButtons) {
     782            MapMode mode = (MapMode)b.getAction();
     783            if (mode.layerIsSupported(layer)) {
     784                Main.registerActionShortcut(mode, mode.getShortcut()); //fix #6876
     785                b.setEnabled(true);
    790786            } else {
    791787                Main.unregisterShortcut(mode.getShortcut());
     788                b.setEnabled(false);
    792789            }
    793790        }
    794791        AudioPlayer.reset();
  • org/openstreetmap/josm/gui/ExtendedDialog.java

     
    33
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
     6import java.awt.AWTKeyStroke;
    67import java.awt.Component;
     8import java.awt.DefaultKeyboardFocusManager;
    79import java.awt.Dimension;
    810import java.awt.GridBagConstraints;
    911import java.awt.GridBagLayout;
     
    1416import java.util.Arrays;
    1517import java.util.Collections;
    1618import java.util.List;
     19import java.util.Set;
    1720
    1821import javax.swing.AbstractAction;
    1922import javax.swing.Action;
     23import javax.swing.FocusManager;
    2024import javax.swing.Icon;
    2125import javax.swing.JButton;
    2226import javax.swing.JCheckBox;
     
    100104     */
    101105    private boolean placeContentInScrollPane;
    102106
     107    /**
     108     * TAB is de-registered as a defaultFocusTraversalKey and reused
     109     * in the main application to quickly toggle dialogs.  Within
     110     * ExtendedDialogs however, we'll want TAB to traverse focus.
     111     */
     112    private static Set<AWTKeyStroke> defaultFocusTraversalKeys = (new DefaultKeyboardFocusManager()).getDefaultFocusTraversalKeys(FocusManager.FORWARD_TRAVERSAL_KEYS);
     113
    103114    // For easy access when inherited
    104115    protected Insets contentInsets = new Insets(10,5,0,5);
    105116    protected ArrayList<JButton> buttons = new ArrayList<JButton>();
     
    147158            setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
    148159        }
    149160        this.disposeOnClose = disposeOnClose;
     161        setFocusTraversalKeys(FocusManager.FORWARD_TRAVERSAL_KEYS, defaultFocusTraversalKeys);
    150162    }
    151163
    152164    /**
     
    508520     * @param togglePref  The preference to save the checkbox state to
    509521     */
    510522    public ExtendedDialog toggleEnable(String togglePref) {
    511         if (!modal) {
     523        if (!modal)
    512524            throw new IllegalArgumentException();
    513         }
    514525        this.toggleable = true;
    515526        this.togglePref = togglePref;
    516527        return this;
  • org/openstreetmap/josm/gui/MapStatus.java

     
    1616import java.awt.SystemColor;
    1717import java.awt.Toolkit;
    1818import java.awt.event.AWTEventListener;
     19import java.awt.event.ActionEvent;
    1920import java.awt.event.InputEvent;
    2021import java.awt.event.KeyAdapter;
    2122import java.awt.event.KeyEvent;
     
    2829import java.util.ConcurrentModificationException;
    2930import java.util.List;
    3031
     32import javax.swing.AbstractAction;
    3133import javax.swing.BorderFactory;
     34import javax.swing.JCheckBoxMenuItem;
    3235import javax.swing.JLabel;
    3336import javax.swing.JPanel;
     37import javax.swing.JPopupMenu;
    3438import javax.swing.JProgressBar;
    3539import javax.swing.JScrollPane;
    3640import javax.swing.Popup;
    3741import javax.swing.PopupFactory;
    3842import javax.swing.UIManager;
     43import javax.swing.event.PopupMenuEvent;
     44import javax.swing.event.PopupMenuListener;
    3945
    4046import org.openstreetmap.josm.Main;
    4147import org.openstreetmap.josm.data.coor.CoordinateFormat;
     
    4652import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor;
    4753import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor.ProgressMonitorDialog;
    4854import org.openstreetmap.josm.gui.util.GuiHelper;
     55import org.openstreetmap.josm.gui.widgets.JosmTextField;
    4956import org.openstreetmap.josm.tools.GBC;
    5057import org.openstreetmap.josm.tools.ImageProvider;
    51 import org.openstreetmap.josm.gui.widgets.JosmTextField;
    5258
    5359/**
    5460 * A component that manages some status information display about the map.
     
    280286
    281287                                    // Set the text label in the bottom status bar
    282288                                    // "if mouse moved only" was added to stop heap growing
    283                                     if (!mouseNotMoved) statusBarElementUpdate(ms);
     289                                    if (!mouseNotMoved) {
     290                                        statusBarElementUpdate(ms);
     291                                    }
    284292
    285293
    286294                                    // Popup Information
     
    685693        this.mv = mapFrame.mapView;
    686694        this.collector = new Collector(mapFrame);
    687695
     696        // Context menu of status bar
     697        setComponentPopupMenu(new JPopupMenu() {
     698            JCheckBoxMenuItem doNotHide = new JCheckBoxMenuItem(new AbstractAction(tr("Do not hide status bar")) {
     699                @Override
     700                public void actionPerformed(ActionEvent e) {
     701                    boolean sel = ((JCheckBoxMenuItem) e.getSource()).getState();
     702                    Main.pref.put("statusbar.always-visible", sel);
     703                }
     704            });
     705            {
     706                addPopupMenuListener(new PopupMenuListener() {
     707                    @Override
     708                    public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
     709                        doNotHide.setSelected(Main.pref.getBoolean("statusbar.always-visible", true));
     710                    }
     711                    @Override
     712                    public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {}
     713                    @Override
     714                    public void popupMenuCanceled(PopupMenuEvent e) {}
     715                });
     716                add(doNotHide);
     717            }
     718        });
     719
    688720        lonText.addMouseListener(Main.main.menu.jumpToAct);
    689721        latText.addMouseListener(Main.main.menu.jumpToAct);
    690722       
     
    709741        setLayout(new GridBagLayout());
    710742        setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    711743
     744        latText.setInheritsPopupMenu(true);
     745        lonText.setInheritsPopupMenu(true);
     746        headingText.setInheritsPopupMenu(true);
     747        angleText.setInheritsPopupMenu(true);
     748        distText.setInheritsPopupMenu(true);
     749        nameText.setInheritsPopupMenu(true);
     750        //helpText.setInheritsPopupMenu(true);
     751        //progressBar.setInheritsPopupMenu(true);
     752
    712753        add(latText, GBC.std());
    713754        add(lonText, GBC.std().insets(3,0,0,0));
    714755        add(headingText, GBC.std().insets(3,0,0,0));
  • org/openstreetmap/josm/gui/preferences/ToolbarPreferences.java

     
    2929import java.util.List;
    3030import java.util.Map;
    3131
     32import javax.swing.AbstractAction;
    3233import javax.swing.Action;
    3334import javax.swing.DefaultListCellRenderer;
    3435import javax.swing.DefaultListModel;
    3536import javax.swing.Icon;
    3637import javax.swing.ImageIcon;
    3738import javax.swing.JButton;
     39import javax.swing.JCheckBoxMenuItem;
    3840import javax.swing.JComponent;
    3941import javax.swing.JLabel;
    4042import javax.swing.JList;
     
    5052import javax.swing.TransferHandler;
    5153import javax.swing.event.ListSelectionEvent;
    5254import javax.swing.event.ListSelectionListener;
     55import javax.swing.event.PopupMenuEvent;
     56import javax.swing.event.PopupMenuListener;
    5357import javax.swing.event.TreeSelectionEvent;
    5458import javax.swing.event.TreeSelectionListener;
    5559import javax.swing.table.AbstractTableModel;
     
    6569import org.openstreetmap.josm.actions.ParameterizedAction;
    6670import org.openstreetmap.josm.actions.ParameterizedActionDecorator;
    6771import org.openstreetmap.josm.gui.tagging.TaggingPreset;
    68 import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
    6972import org.openstreetmap.josm.tools.GBC;
    7073import org.openstreetmap.josm.tools.ImageProvider;
    7174import org.openstreetmap.josm.tools.Shortcut;
    7275
    7376public class ToolbarPreferences implements PreferenceSettingFactory {
    7477
    75 
    7678    private static final String EMPTY_TOOLBAR_MARKER = "<!-empty-!>";
    7779
    7880    public static class ActionDefinition {
     
    227229                    String paramName = readTillChar('=', '=');
    228230                    skip('=');
    229231                    String paramValue = readTillChar(',','}');
    230                     if ("icon".equals(paramName) && paramValue.length() > 0)
     232                    if ("icon".equals(paramName) && paramValue.length() > 0) {
    231233                        result.setIcon(paramValue);
    232                     else if("name".equals(paramName) && paramValue.length() > 0)
     234                    } else if("name".equals(paramName) && paramValue.length() > 0) {
    233235                        result.setName(paramValue);
     236                    }
    234237                    skip(',');
    235238                }
    236239                skip('}');
     
    293296                    escape(tmp);
    294297                    first = false;
    295298                }
    296                 if(!first)
     299                if(!first) {
    297300                    result.append('}');
    298301            }
     302            }
    299303
    300304            return result.toString();
    301305        }
     
    338342                    default:
    339343                        return null;
    340344                    }
    341                 } else
     345                } else {
    342346                    rowIndex -= 2;
    343347            }
     348            }
    344349            ActionParameter<Object> param = getParam(rowIndex);
    345350            switch (columnIndex) {
    346351            case 0:
     
    367372                } else if (rowIndex == 1) {
    368373                     currentAction.setIcon((String)aValue);
    369374                     return;
    370                 } else
     375                } else {
    371376                    rowIndex -= 2;
    372377            }
     378            }
    373379            ActionParameter<Object> param = getParam(rowIndex);
    374380            currentAction.getParameters().put(param.getName(), param.readFromString((String)aValue));
    375381        }
     
    382388
    383389    }
    384390
    385     private static class ToolbarPopupMenu extends JPopupMenu {
    386         public ToolbarPopupMenu(final ActionDefinition action) {
     391    private class ToolbarPopupMenu extends JPopupMenu {
     392        ActionDefinition act;
    387393
    388             if(action != null) {
    389                 add(tr("Remove from toolbar",action.getDisplayName()))
    390                         .addActionListener(new ActionListener() {
    391                             @Override public void actionPerformed(ActionEvent e) {
     394        private void setActionAndAdapt(ActionDefinition action) {
     395            this.act = action;
     396            doNotHide.setSelected(Main.pref.getBoolean("toolbar.always-visible", true));
     397            remove.setVisible(act!=null);
     398            shortcutEdit.setVisible(act!=null);
     399        }
     400
     401        JMenuItem remove = new JMenuItem(new AbstractAction(tr("Remove from toolbar")) {
     402            @Override
     403            public void actionPerformed(ActionEvent e) {
    392404                                Collection<String> t = new LinkedList<String>(getToolString());
    393405                                ActionParser parser = new ActionParser(null);
    394406                                // get text definition of current action
    395                                 String res = parser.saveAction(action);
     407                String res = parser.saveAction(act);
    396408                                // remove the button from toolbar preferences
    397409                                t.remove( res );
    398410                                Main.pref.putCollection("toolbar", t);
    399411                                Main.toolbar.refreshToolbarControl();
    400412                            }
    401413                });
    402             }
    403414           
    404             add(tr("Configure toolbar")).addActionListener(new ActionListener() {
    405                 @Override public void actionPerformed(ActionEvent e) {
     415        JMenuItem configure = new JMenuItem(new AbstractAction(tr("Configure toolbar")) {
     416            @Override
     417            public void actionPerformed(ActionEvent e) {
    406418                    final PreferenceDialog p =new PreferenceDialog(Main.parent);
    407419                    p.selectPreferencesTabByName("toolbar");
    408420                    p.setVisible(true);
    409421                }
    410422            });
    411423
    412             add(tr("Edit shortcut")).addActionListener(new ActionListener() {
    413                 @Override public void actionPerformed(ActionEvent e) {
     424        JMenuItem shortcutEdit = new JMenuItem(new AbstractAction(tr("Edit shortcut")) {
     425            @Override
     426            public void actionPerformed(ActionEvent e) {
    414427                    final PreferenceDialog p =new PreferenceDialog(Main.parent);
    415                     p.getTabbedPane().getShortcutPreference().setDefaultFilter(action.getDisplayName());
     428                p.getTabbedPane().getShortcutPreference().setDefaultFilter(act.getDisplayName());
    416429                    p.selectPreferencesTabByName("shortcuts");
    417430                    p.setVisible(true);
    418                     // refresh toolbar to accept changes of shortcuts without restart
     431                // refresh toolbar to try using changed shortcuts without restart
    419432                    Main.toolbar.refreshToolbarControl();
    420433                }
    421434            });
     435
     436        JCheckBoxMenuItem doNotHide = new JCheckBoxMenuItem(new AbstractAction(tr("Do not hide toolbar and menu")) {
     437            @Override
     438            public void actionPerformed(ActionEvent e) {
     439                boolean sel = ((JCheckBoxMenuItem) e.getSource()).getState();
     440                Main.pref.put("toolbar.always-visible", sel);
     441                Main.pref.put("menu.always-visible", sel);
    422442        }
     443        });
     444        {
     445            addPopupMenuListener(new PopupMenuListener() {
     446                @Override
     447                public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
     448                    setActionAndAdapt(buttonActions.get(
     449                            ((JPopupMenu)e.getSource()).getInvoker()
     450                    ));
    423451    }
     452                @Override
     453                public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {}
    424454
     455                @Override
     456                public void popupMenuCanceled(PopupMenuEvent e) {}
     457            });
     458            add(remove);
     459            add(configure);
     460            add(shortcutEdit);
     461            add(doNotHide);
     462        }
     463    }
     464
     465    private ToolbarPopupMenu popupMenu = new ToolbarPopupMenu();
     466
    425467    /**
    426468     * Key: Registered name (property "toolbar" of action).
    427469     * Value: The action to execute.
     
    432474    private DefaultMutableTreeNode rootActionsNode = new DefaultMutableTreeNode(tr("Actions"));
    433475
    434476    public JToolBar control = new JToolBar();
     477    private HashMap<Object, ActionDefinition> buttonActions = new HashMap<Object, ActionDefinition>(30);
    435478
    436479    @Override
    437480    public PreferenceSetting createPreferenceSetting() {
     
    825868                    t.add("|");
    826869                } else {
    827870                    String res = parser.saveAction(action);
    828                     if(res != null)
     871                    if(res != null) {
    829872                        t.add(res);
    830873                }
    831874            }
     875            }
    832876            if (t.isEmpty()) {
    833877                t = Collections.singletonList(EMPTY_TOOLBAR_MARKER);
    834878            }
     
    841885
    842886    public ToolbarPreferences() {
    843887        control.setFloatable(false);
    844         control.addMouseListener(new PopupMenuLauncher(new ToolbarPopupMenu(null)));
     888        control.setComponentPopupMenu(popupMenu);
    845889    }
    846890
    847891    private void loadAction(DefaultMutableTreeNode node, MenuElement menu) {
     
    9781022     */
    9791023    public void refreshToolbarControl() {
    9801024        control.removeAll();
     1025        buttonActions.clear();
    9811026
    9821027        for (ActionDefinition action : getDefinedActions()) {
    9831028            if (action.isSeparator()) {
    9841029                control.addSeparator();
    9851030            } else {
    9861031                final JButton b = addButtonAndShortcut(action);
     1032                buttonActions.put(b, action);
    9871033               
    9881034                Icon i = action.getDisplayIcon();
    9891035                if (i != null) {
     
    10001046                        }
    10011047                    });
    10021048                }
    1003                 b.addMouseListener(new PopupMenuLauncher( new ToolbarPopupMenu(action)));
     1049                b.setInheritsPopupMenu(true);
    10041050            }
    10051051        }
    10061052        control.setVisible(control.getComponentCount() != 0);
     
    10131059        Shortcut sc = null;
    10141060        if (action.getAction() instanceof JosmAction) {
    10151061            sc = ((JosmAction) action.getAction()).getShortcut();
    1016             if (sc.getAssignedKey() == KeyEvent.CHAR_UNDEFINED) sc = null;
     1062            if (sc.getAssignedKey() == KeyEvent.CHAR_UNDEFINED) {
     1063                sc = null;
    10171064        }
     1065        }
    10181066
    10191067        long paramCode = 0;
    10201068        if (action.hasParameters()) {
     
    10221070        }
    10231071       
    10241072        String tt = action.getDisplayTooltip();
    1025         if (tt==null) tt="";
     1073        if (tt==null) {
     1074            tt="";
     1075        }
    10261076
    10271077        if (sc == null || paramCode != 0) {
    10281078            String name = (String) action.getAction().getValue("toolbar");
    1029             if (name==null) name=action.getDisplayName();
    1030             if (paramCode!=0) name = name+paramCode;
     1079            if (name==null) {
     1080                name=action.getDisplayName();
     1081            }
     1082            if (paramCode!=0) {
     1083                name = name+paramCode;
     1084            }
    10311085            String desc = action.getDisplayName() + ((paramCode==0)?"":action.parameters.toString());
    10321086            sc = Shortcut.registerShortcut("toolbar:"+name, tr("Toolbar: {0}", desc),
    10331087                KeyEvent.CHAR_UNDEFINED, Shortcut.NONE);
     
    10431097            }
    10441098        }
    10451099       
    1046         if (!tt.isEmpty()) b.setToolTipText(tt);
     1100        if (!tt.isEmpty()) {
     1101            b.setToolTipText(tt);
     1102        }
    10471103        return b;
    10481104    }
    10491105
  • org/openstreetmap/josm/gui/MapFrame.java

     
    99import java.awt.Dimension;
    1010import java.awt.Font;
    1111import java.awt.GridBagLayout;
     12import java.awt.KeyboardFocusManager;
    1213import java.awt.Rectangle;
    1314import java.awt.event.ActionEvent;
    1415import java.awt.event.KeyEvent;
     
    1718import java.util.ArrayList;
    1819import java.util.Collection;
    1920import java.util.HashMap;
     21import java.util.HashSet;
    2022import java.util.List;
    2123import java.util.Map;
    2224import java.util.concurrent.CopyOnWriteArrayList;
     
    3638import javax.swing.KeyStroke;
    3739import javax.swing.SwingUtilities;
    3840import javax.swing.border.Border;
     41import javax.swing.event.PopupMenuEvent;
     42import javax.swing.event.PopupMenuListener;
    3943import javax.swing.plaf.basic.BasicSplitPaneDivider;
    4044import javax.swing.plaf.basic.BasicSplitPaneUI;
    4145
     
    6973import org.openstreetmap.josm.gui.dialogs.ValidatorDialog;
    7074import org.openstreetmap.josm.gui.dialogs.properties.PropertiesDialog;
    7175import org.openstreetmap.josm.gui.layer.Layer;
    72 import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
    7376import org.openstreetmap.josm.tools.Destroyable;
    7477import org.openstreetmap.josm.tools.GBC;
     78import org.openstreetmap.josm.tools.Shortcut;
    7579
    7680/**
    7781 * One Map frame with one dataset behind. This is the container gui class whose
     
    8690     */
    8791    public MapMode mapMode;
    8892
    89     private final List<MapMode> mapModes = new ArrayList<MapMode>();
    9093    /**
    9194     * The view control displayed.
    9295     */
    9396    public final MapView mapView;
     97
    9498    /**
    95      * The toolbar with the action icons. To add new toggle dialog actions, use addToggleDialog
    96      * instead of adding directly to this list. To add a new mode use addMapMode.
     99     * The toolbar with the action icons. To add new toggle dialog buttons,
     100     * use addToggleDialog, to add a new map mode button use addMapMode.
    97101     */
    98     private JToolBar toolBarActions = new JToolBar(JToolBar.VERTICAL);
    99     private JToolBar toolBarToggle = new JToolBar(JToolBar.VERTICAL);
    100     /**
    101      * The status line below the map
    102      */
    103     public MapStatus statusLine;
     102    private JComponent sideToolBar = new JToolBar(JToolBar.VERTICAL);
     103    private final ButtonGroup toolBarActionsGroup = new ButtonGroup();
     104    private final JToolBar toolBarActions = new JToolBar(JToolBar.VERTICAL);
     105    private final JToolBar toolBarToggle = new JToolBar(JToolBar.VERTICAL);
    104106
     107    private final List<ToggleDialog> allDialogs = new ArrayList<ToggleDialog>();
     108    private final List<MapMode> mapModes = new ArrayList<MapMode>();
     109    private final List<IconToggleButton> allDialogButtons = new ArrayList<IconToggleButton>();
     110    public final List<IconToggleButton> allMapModeButtons = new ArrayList<IconToggleButton>();
     111
     112    private final ListAllButtonsAction listAllDialogsAction = new ListAllButtonsAction(allDialogButtons);
     113    private final ListAllButtonsAction listAllMapModesAction = new ListAllButtonsAction(allMapModeButtons);
     114    private final JButton listAllToggleDialogsButton = new JButton(listAllDialogsAction);
     115    private final JButton listAllMapModesButton = new JButton(listAllMapModesAction);
     116    {
     117        listAllDialogsAction.setButton(listAllToggleDialogsButton);
     118        listAllMapModesAction.setButton(listAllMapModesButton);
     119    }
     120
    105121    // Toggle dialogs
    106122    public ConflictDialog conflictDialog;
    107123    public FilterDialog filterDialog;
     
    112128
    113129    // Map modes
    114130    public final SelectAction mapModeSelect;
     131    private final Map<Layer, MapMode> lastMapMode = new HashMap<Layer, MapMode>();
    115132    private final MapMode mapModeDraw;
    116133    private final MapMode mapModeZoom;
    117134
    118135    /**
    119      * The panel list of all toggle dialog icons. To add new toggle dialog actions, use addToggleDialog
    120      * instead of adding directly to this list.
     136     * The status line below the map
    121137     */
    122     private List<ToggleDialog> allDialogs = new ArrayList<ToggleDialog>();
     138    public MapStatus statusLine;
     139
     140    /**
     141     * The split pane with the mapview (leftPanel) and toggle dialogs (dialogsPanel).
     142     */
     143    private final JSplitPane splitPane;
    123144    private final JPanel leftPanel;
    124145    private final DialogsPanel dialogsPanel;
    125146
    126     public final ButtonGroup toolGroup = new ButtonGroup();
    127 
    128     private List<IconToggleButton> allDialogButtons = new ArrayList<IconToggleButton>();
    129     private List<IconToggleButton> allMapModeButtons = new ArrayList<IconToggleButton>();
    130 
    131     private final ListAllButtonsAction listAllDialogsAction = new ListAllButtonsAction(allDialogButtons);
    132     private final ListAllButtonsAction listAllMapModesAction = new ListAllButtonsAction(allMapModeButtons);
    133     private final JButton listAllToggleDialogsButton = new JButton(listAllDialogsAction);
    134     private final JButton listAllMapModesButton = new JButton(listAllMapModesAction);
    135     {
    136         listAllDialogsAction.setButton(listAllToggleDialogsButton);
    137         listAllMapModesAction.setButton(listAllMapModesButton);
    138     }
    139 
    140147    /**
    141148     * Default width of the toggle dialog area.
    142149     */
    143150    public static final int DEF_TOGGLE_DLG_WIDTH = 330;
    144151
    145     private final Map<Layer, MapMode> lastMapMode = new HashMap<Layer, MapMode>();
    146 
    147152    /**
    148153     * Constructs a new {@code MapFrame}.
    149154     * @param contentPane The content pane used to register shortcuts in its
     
    156161        setLayout(new BorderLayout());
    157162
    158163        mapView = new MapView(contentPane, viewportData);
    159 
    160164        new FileDrop(mapView);
    161165
     166        splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true);
     167
    162168        leftPanel = new JPanel();
    163169        leftPanel.setLayout(new GridBagLayout());
    164 
    165170        leftPanel.add(mapView, GBC.std().fill());
     171        splitPane.setLeftComponent(leftPanel);
    166172
    167         // toolbar
    168         toolBarActions.setFloatable(false);
    169         addMapMode(new IconToggleButton(mapModeSelect = new SelectAction(this)));
    170         addMapMode(new IconToggleButton(new LassoModeAction(), true));
    171         addMapMode(new IconToggleButton(mapModeDraw = new DrawAction(this)));
    172         addMapMode(new IconToggleButton(mapModeZoom = new ZoomAction(this)));
    173         addMapMode(new IconToggleButton(new DeleteAction(this), true));
    174         addMapMode(new IconToggleButton(new ParallelWayAction(this), true));
    175         addMapMode(new IconToggleButton(new ExtrudeAction(this), true));
    176         addMapMode(new IconToggleButton(new ImproveWayAccuracyAction(Main.map), true));
    177 
    178         toolGroup.setSelected(((AbstractButton)toolBarActions.getComponent(0)).getModel(), true);
    179 
    180         JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true);
    181173        dialogsPanel = new DialogsPanel(splitPane);
    182         splitPane.setLeftComponent(leftPanel);
    183174        splitPane.setRightComponent(dialogsPanel);
    184175
    185176        /**
     
    211202
    212203        dialogsPanel.setLayout(new BoxLayout(dialogsPanel, BoxLayout.Y_AXIS));
    213204        dialogsPanel.setPreferredSize(new Dimension(Main.pref.getInteger("toggleDialogs.width",DEF_TOGGLE_DLG_WIDTH), 0));
    214 
    215205        dialogsPanel.setMinimumSize(new Dimension(24, 0));
    216206        mapView.setMinimumSize(new Dimension(10,0));
    217207
    218         toolBarToggle.setFloatable(false);
     208        // toolBarActions, map mode buttons
     209        addMapMode(new IconToggleButton(mapModeSelect = new SelectAction(this)));
     210        addMapMode(new IconToggleButton(new LassoModeAction(), true));
     211        addMapMode(new IconToggleButton(mapModeDraw = new DrawAction(this)));
     212        addMapMode(new IconToggleButton(mapModeZoom = new ZoomAction(this)));
     213        addMapMode(new IconToggleButton(new DeleteAction(this), true));
     214        addMapMode(new IconToggleButton(new ParallelWayAction(this), true));
     215        addMapMode(new IconToggleButton(new ExtrudeAction(this), true));
     216        addMapMode(new IconToggleButton(new ImproveWayAccuracyAction(Main.map), true));
     217        toolBarActionsGroup.setSelected(allMapModeButtons.get(0).getModel(), true);
     218        toolBarActions.setFloatable(false);
     219
     220        // toolBarToggles, toggle dialog buttons
    219221        LayerListDialog.createInstance(this);
    220222        addToggleDialog(LayerListDialog.getInstance());
    221223        addToggleDialog(propertiesDialog = new PropertiesDialog(this));
     
    229231        addToggleDialog(filterDialog = new FilterDialog());
    230232        addToggleDialog(new ChangesetDialog(this), true);
    231233        addToggleDialog(new MapPaintDialog());
     234        toolBarToggle.setFloatable(false);
    232235
    233236        // status line below the map
    234237        statusLine = new MapStatus(this);
    235238        MapView.addLayerChangeListener(this);
     239        // unregister TAB key if needed
     240        if (Shortcut.findShortcut(KeyEvent.VK_TAB, 0) != null) {
     241            unregisterTabKey();
    236242    }
     243    }
    237244
    238245    public boolean selectSelectTool(boolean onlyIfModeless) {
    239246        if(onlyIfModeless && !Main.pref.getBoolean("modeless", false))
     
    257264    }
    258265
    259266    /**
     267     * Free tabulator key (call if someone else needs it)
     268     */
     269    public final void unregisterTabKey() {
     270        System.out.println("Tab key unregistered");
     271        HashSet<KeyStroke> ks = new HashSet<KeyStroke>(1);
     272        ks.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, KeyEvent.CTRL_DOWN_MASK));
     273        KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
     274        kfm.setDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, ks);
     275        splitPane.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, ks);
     276    }
     277
     278    /**
    260279     * Called as some kind of destructor when the last layer has been removed.
    261280     * Delegates the call to all Destroyables within this component (e.g. MapModes)
    262281     */
     282    @Override
    263283    public void destroy() {
    264284        MapView.removeLayerChangeListener(this);
    265285        dialogsPanel.destroy();
     
    309329    public IconToggleButton addToggleDialog(final ToggleDialog dlg, boolean isExpert) {
    310330        final IconToggleButton button = new IconToggleButton(dlg.getToggleAction(), isExpert);
    311331        button.setShowHideButtonListener(dlg);
    312         addHideContextMenu(button);
     332        button.setInheritsPopupMenu(true);
    313333        dlg.setButton(button);
    314334        toolBarToggle.add(button);
    315335        allDialogs.add(dlg);
     
    324344
    325345
    326346    public void addMapMode(IconToggleButton b) {
    327         toolBarActions.add(b);
    328         toolGroup.add(b);
    329         allMapModeButtons.add(b);
    330347        if (b.getAction() instanceof MapMode) {
    331348            mapModes.add((MapMode) b.getAction());
    332349        } else
    333350            throw new IllegalArgumentException("MapMode action must be subclass of MapMode");
    334         addHideContextMenu(b);
     351        allMapModeButtons.add(b);
     352        toolBarActionsGroup.add(b);
     353        toolBarActions.add(b);
    335354        b.applyButtonHiddenPreferences();
     355        b.setInheritsPopupMenu(true);
    336356    }
    337357
    338358    /**
     
    391411     */
    392412    public void fillPanel(Container panel) {
    393413        panel.add(this, BorderLayout.CENTER);
    394         JToolBar jb = new JToolBar(JToolBar.VERTICAL);
    395         jb.setFloatable(false);
     414
     415        /**
     416         * sideToolBar: add map modes icons
     417         */
     418        if(Main.pref.getBoolean("sidetoolbar.mapmodes.visible", true)) {
    396419        toolBarActions.setAlignmentX(0.5f);
    397         jb.add(toolBarActions);
     420            toolBarActions.setInheritsPopupMenu(true);
     421            sideToolBar.add(toolBarActions);
    398422        listAllMapModesButton.setAlignmentX(0.5f);
    399423        listAllMapModesButton.setBorder(null);
    400424        listAllMapModesButton.setFont(listAllMapModesButton.getFont().deriveFont(Font.PLAIN));
    401         jb.add(listAllMapModesButton);
     425            listAllMapModesButton.setInheritsPopupMenu(true);
     426            sideToolBar.add(listAllMapModesButton);
     427        }
    402428
    403         if(Main.pref.getBoolean("sidetoolbar.togglevisible", true)) {
    404             jb.addSeparator(new Dimension(0,18));
     429        /**
     430         * sideToolBar: add toggle dialogs icons
     431         */
     432        if(Main.pref.getBoolean("sidetoolbar.toggledialogs.visible", true)) {
     433            ((JToolBar)sideToolBar).addSeparator(new Dimension(0,18));
    405434            toolBarToggle.setAlignmentX(0.5f);
    406             jb.add(toolBarToggle);
     435            toolBarToggle.setInheritsPopupMenu(true);
     436            sideToolBar.add(toolBarToggle);
    407437            listAllToggleDialogsButton.setAlignmentX(0.5f);
    408438            listAllToggleDialogsButton.setBorder(null);
    409439            listAllToggleDialogsButton.setFont(listAllToggleDialogsButton.getFont().deriveFont(Font.PLAIN));
    410             jb.add(listAllToggleDialogsButton);
     440            listAllToggleDialogsButton.setInheritsPopupMenu(true);
     441            sideToolBar.add(listAllToggleDialogsButton);
    411442        }
    412443
    413         final Component toToggle;
    414         if (Main.pref.getBoolean("sidetoolbar.scrollable", true)) {
    415             final ScrollViewport svp = new ScrollViewport(jb, ScrollViewport.VERTICAL_DIRECTION);
    416             toToggle = svp;
    417             panel.add(svp, BorderLayout.WEST);
    418             jb.addMouseWheelListener(new MouseWheelListener() {
    419 
    420                 public void mouseWheelMoved(MouseWheelEvent e) {
    421                     svp.scroll(0, e.getUnitsToScroll() * 5);
     444        /**
     445         * sideToolBar: add dynamic popup menu
     446         */
     447        sideToolBar.setComponentPopupMenu(new JPopupMenu() {
     448            final int staticMenuEntryCount = 2;
     449            JCheckBoxMenuItem doNotHide = new JCheckBoxMenuItem(new AbstractAction(tr("Do not hide toolbar on TAB")) {
     450                @Override
     451                public void actionPerformed(ActionEvent e) {
     452                    boolean sel = ((JCheckBoxMenuItem) e.getSource()).getState();
     453                    Main.pref.put("sidetoolbar.always-visible", sel);
    422454                }
    423455            });
    424         } else {
    425             toToggle = jb;
    426             panel.add(jb, BorderLayout.WEST);
     456            {
     457                addPopupMenuListener(new PopupMenuListener() {
     458                    @Override
     459                    public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
     460                        final Object src = ((JPopupMenu)e.getSource()).getInvoker();
     461                        if (src instanceof IconToggleButton) {
     462                            insert(new Separator(), 0);
     463                            insert(new AbstractAction() {
     464                                {
     465                                    putValue(NAME, tr("Hide this button"));
     466                                    putValue(SHORT_DESCRIPTION, tr("Click the arrow at the bottom to show it again."));
    427467        }
    428         toToggle.setVisible(Main.pref.getBoolean("sidetoolbar.visible", true));
     468                                @Override
     469                                public void actionPerformed(ActionEvent e) {
     470                                    ((IconToggleButton)src).setButtonHidden(true);
     471                                    validateToolBarsVisibility();
     472                                }
     473                            }, 0);
     474                        }
     475                        doNotHide.setSelected(Main.pref.getBoolean("sidetoolbar.always-visible", true));
     476                    }
     477                    @Override
     478                    public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
     479                        while (getComponentCount() > staticMenuEntryCount) {
     480                            remove(0);
     481                        }
     482                    }
     483                    @Override
     484                    public void popupMenuCanceled(PopupMenuEvent e) {}
     485                });
    429486
    430         jb.addMouseListener(new PopupMenuLauncher(new JPopupMenu() {
    431 
    432             {
    433487                add(new AbstractAction(tr("Hide edit toolbar")) {
    434 
    435488                    @Override
    436489                    public void actionPerformed(ActionEvent e) {
    437490                        Main.pref.put("sidetoolbar.visible", false);
    438491                    }
    439492                });
     493                add(doNotHide);
    440494            }
    441         }));
     495        });
     496        ((JToolBar)sideToolBar).setFloatable(false);
    442497
     498        /**
     499         * sideToolBar: decide scroll- and visibility
     500         */
     501        if(Main.pref.getBoolean("sidetoolbar.scrollable", true)) {
     502            final ScrollViewport svp = new ScrollViewport(sideToolBar, ScrollViewport.VERTICAL_DIRECTION);
     503            svp.addMouseWheelListener(new MouseWheelListener() {
     504                @Override
     505                public void mouseWheelMoved(MouseWheelEvent e) {
     506                    svp.scroll(0, e.getUnitsToScroll() * 5);
     507                }
     508            });
     509            sideToolBar = svp;
     510        }
     511        sideToolBar.setVisible(Main.pref.getBoolean("sidetoolbar.visible", true));
    443512        sidetoolbarPreferencesChangedListener = new Preferences.PreferenceChangedListener() {
    444 
    445513            @Override
    446514            public void preferenceChanged(PreferenceChangeEvent e) {
    447515                if ("sidetoolbar.visible".equals(e.getKey())) {
    448                     toToggle.setVisible(Main.pref.getBoolean("sidetoolbar.visible"));
     516                    sideToolBar.setVisible(Main.pref.getBoolean("sidetoolbar.visible"));
    449517                }
    450518            }
    451519        };
    452520        Main.pref.addPreferenceChangeListener(sidetoolbarPreferencesChangedListener);
    453521
     522        /**
     523         * sideToolBar: add it to the panel
     524         */
     525        panel.add(sideToolBar, BorderLayout.WEST);
     526
     527        /**
     528         * statusLine: add to panel
     529         */
    454530        if (statusLine != null && Main.pref.getBoolean("statusline.visible", true)) {
    455531            panel.add(statusLine, BorderLayout.SOUTH);
    456532        }
    457533    }
    458534
    459     private void addHideContextMenu(final IconToggleButton b) {
    460         //context menu
    461         b.addMouseListener(new PopupMenuLauncher(new JPopupMenu() {
    462             {
    463                 add(new AbstractAction() {
    464                     {
    465                         putValue(NAME, tr("Hide this button"));
    466                         putValue(SHORT_DESCRIPTION, tr("Click the arrow at the bottom to show it again."));
    467                     }
    468                     @Override
    469                     public void actionPerformed(ActionEvent e) {
    470                         b.setButtonHidden(true);
    471                         validateToolBarsVisibility();
    472                     }
    473                 });
    474             }
    475         }));
    476     }
    477 
    478535    class ListAllButtonsAction extends AbstractAction {
    479536
    480537        private JButton button;
     
    543600        return dialogsPanel.getToggleDialog(type);
    544601    }
    545602
     603    public void setDialogsPanelVisible(boolean visible) {
     604        rememberToggleDialogWidth();
     605        dialogsPanel.setVisible(visible);
     606        splitPane.setDividerLocation(visible?splitPane.getWidth()-Main.pref.getInteger("toggleDialogs.width",DEF_TOGGLE_DLG_WIDTH):0);
     607        splitPane.setDividerSize(visible?5:0);
     608    }
     609
    546610    /**
    547611     * Remember the current width of the (possibly resized) toggle dialog area
    548612     */
    549613    public void rememberToggleDialogWidth() {
    550         Main.pref.putInteger("toggleDialogs.width", dialogsPanel.getWidth());
     614        if (dialogsPanel.isVisible()) {
     615            Main.pref.putInteger("toggleDialogs.width", splitPane.getWidth()-splitPane.getDividerLocation());
    551616    }
     617    }
    552618
    553619    /*
    554      * Remove panel from top of MapView by class
    555      */
     620     * Remove panel from top of MapView by class     */
    556621    public void removeTopPanel(Class<?> type) {
    557622        int n = leftPanel.getComponentCount();
    558623        for (int i=0; i<n; i++) {
     
    652717        // After all listeners notice new layer, some buttons will be disabled/enabled
    653718        // and possibly need to be hidden/shown.
    654719        SwingUtilities.invokeLater(new Runnable() {
    655             public void run() {
     720            @Override public void run() {
    656721                validateToolBarsVisibility();
    657722            }
    658723        });