Changeset 1335 in josm for trunk/src/org/openstreetmap


Ignore:
Timestamp:
2009-01-25T13:27:05+01:00 (16 years ago)
Author:
stoecker
Message:

fix #1988. Patch by Igor Shubovych

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

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/JosmAction.java

    r1182 r1335  
    6464        putValue(SHORT_DESCRIPTION, Main.platform.makeTooltip(tooltip, sc));
    6565        putValue("toolbar", iconName);
    66     if (register)
    67         Main.toolbar.register(this);
     66        if (register)
     67            Main.toolbar.register(this);
    6868    }
    6969
  • trunk/src/org/openstreetmap/josm/gui/preferences/ToolbarPreferences.java

    r1180 r1335  
    1111import java.awt.LayoutManager;
    1212import java.awt.Rectangle;
     13import java.awt.datatransfer.DataFlavor;
     14import java.awt.datatransfer.Transferable;
     15import java.awt.datatransfer.UnsupportedFlavorException;
    1316import java.awt.event.ActionEvent;
    1417import java.awt.event.ActionListener;
     18import java.awt.event.InputEvent;
     19import java.io.IOException;
     20import java.util.Arrays;
     21import java.util.Collection;
    1522import java.util.HashMap;
    16 import java.util.TreeMap;
     23import java.util.LinkedList;
     24import java.util.List;
    1725import java.util.Map;
    1826
     27import javax.swing.AbstractAction;
    1928import javax.swing.Action;
    2029import javax.swing.DefaultListCellRenderer;
     
    2231import javax.swing.Icon;
    2332import javax.swing.JButton;
     33import javax.swing.JComponent;
    2434import javax.swing.JLabel;
    2535import javax.swing.JList;
     36import javax.swing.JMenuItem;
    2637import javax.swing.JPanel;
     38import javax.swing.JPopupMenu;
    2739import javax.swing.JScrollPane;
    2840import javax.swing.JToolBar;
     41import javax.swing.JTree;
    2942import javax.swing.ListCellRenderer;
     43import javax.swing.MenuElement;
     44import javax.swing.TransferHandler;
    3045import javax.swing.event.ListSelectionEvent;
    3146import javax.swing.event.ListSelectionListener;
     47import javax.swing.tree.DefaultMutableTreeNode;
     48import javax.swing.tree.DefaultTreeCellRenderer;
     49import javax.swing.tree.DefaultTreeModel;
     50import javax.swing.tree.TreePath;
    3251
    3352import org.openstreetmap.josm.Main;
     
    3958    private final class Move implements ActionListener {
    4059        public void actionPerformed(ActionEvent e) {
    41             if (e.getActionCommand().equals("<<")) {
    42                 while (unselected.size() > 1) {
    43                     selected.addElement(unselected.get(0));
    44                     unselected.remove(0);
    45                 }
    46             } else if (e.getActionCommand().equals("<") && unselectedList.getSelectedIndex() != -1) {
    47                 while (unselectedList.getSelectedIndex() != -1 && unselectedList.getSelectedIndex() != unselected.size()-1) {
    48                     selected.addElement(unselectedList.getSelectedValue());
    49                     unselected.remove(unselectedList.getSelectedIndex());
    50                 }
    51                 if (unselectedList.getSelectedIndex() == unselected.size()-1)
    52                     selected.addElement(null);
     60            if (e.getActionCommand().equals("<") && actionsTree.getSelectionCount() > 0) {
     61
     62                int leadItem = selected.getSize();
     63                if (selectedList.getSelectedIndex() != -1) {
     64                    int[] indices = selectedList.getSelectedIndices();
     65                    leadItem = indices[indices.length - 1];
     66                }
     67                for (TreePath selectedAction : actionsTree.getSelectionPaths()) {
     68                    DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectedAction.getLastPathComponent();
     69                    if (node.getUserObject() == null || node.getUserObject() instanceof Action) {
     70                        selected.add(leadItem++, ((Action)node.getUserObject()).getValue("toolbar"));
     71                    }
     72                }
    5373            } else if (e.getActionCommand().equals(">") && selectedList.getSelectedIndex() != -1) {
    5474                while (selectedList.getSelectedIndex() != -1) {
    55                     if (selectedList.getSelectedValue() != null)
    56                         unselected.add(unselected.size()-1, selectedList.getSelectedValue());
    5775                    selected.remove(selectedList.getSelectedIndex());
    58                 }
    59             } else if (e.getActionCommand().equals(">>")) {
    60                 while (selected.size() > 0) {
    61                     if (selected.get(0) != null)
    62                         unselected.add(unselected.size()-1, selected.get(0));
    63                     selected.remove(0);
    6476                }
    6577            } else if (e.getActionCommand().equals("up")) {
     
    91103
    92104    private DefaultListModel selected = new DefaultListModel();
    93     private DefaultListModel unselected = new DefaultListModel();
     105
     106    private DefaultMutableTreeNode rootActionsNode = new DefaultMutableTreeNode("Actions");
     107    private DefaultTreeModel actionsTreeModel = new DefaultTreeModel(rootActionsNode);
     108    private JTree actionsTree = new JTree(actionsTreeModel);
    94109    private JList selectedList = new JList(selected);
    95     private JList unselectedList = new JList(unselected);
     110
     111    private String movingComponent;
    96112
    97113    public JToolBar control = new JToolBar();
     
    103119        control.setFloatable(false);
    104120
    105         final ListCellRenderer oldRenderer = selectedList.getCellRenderer();
     121        actionsTree.setCellRenderer(new DefaultTreeCellRenderer() {
     122            @Override
     123            public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded,
     124                    boolean leaf, int row, boolean hasFocus) {
     125                DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
     126                JLabel comp = (JLabel) super.getTreeCellRendererComponent(
     127                        tree, value, sel, expanded, leaf, row, hasFocus);
     128                if (node.getUserObject() == null) {
     129                    comp.setText(tr("Separator"));
     130                    comp.setIcon(ImageProvider.get("preferences/separator"));
     131                }
     132                else if (node.getUserObject() instanceof Action) {
     133                    Action action = (Action) node.getUserObject();
     134                    comp.setText((String) action.getValue(Action.NAME));
     135                    comp.setIcon((Icon) action.getValue(Action.SMALL_ICON));
     136                }
     137                return comp;
     138            }
     139        });
     140
    106141        ListCellRenderer renderer = new DefaultListCellRenderer(){
    107142            @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
    108                 String s = tr("Separator");
    109                 Icon i = ImageProvider.get("preferences/separator");
     143                String s;
     144                Icon i;
    110145                if (value != null) {
    111                     s = (String)((Action)value).getValue(Action.NAME);
    112                     i = (Icon)((Action)value).getValue(Action.SMALL_ICON);
    113                 }
    114                 JLabel l = (JLabel)oldRenderer.getListCellRendererComponent(list, s, index, isSelected, cellHasFocus);
     146                    Action action = actions.get(value);
     147                    s = (String) action.getValue(Action.NAME);
     148                    i = (Icon) action.getValue(Action.SMALL_ICON);
     149                } else {
     150                    i = ImageProvider.get("preferences/separator");
     151                    s = tr("Separator");
     152                }
     153                JLabel l = (JLabel)super.getListCellRendererComponent(list, s, index, isSelected, cellHasFocus);
    115154                l.setIcon(i);
    116155                return l;
     
    118157        };
    119158        selectedList.setCellRenderer(renderer);
    120         unselectedList.setCellRenderer(renderer);
    121 
    122         unselectedList.addListSelectionListener(new ListSelectionListener(){
    123             public void valueChanged(ListSelectionEvent e) {
    124                 if ((unselectedList.getSelectedIndex() != -1))
    125                     selectedList.clearSelection();
    126                 upButton.setEnabled(selectedList.getSelectedIndex() != -1);
    127                 downButton.setEnabled(selectedList.getSelectedIndex() != -1);
    128             }
    129         });
    130159        selectedList.addListSelectionListener(new ListSelectionListener(){
    131160            public void valueChanged(ListSelectionEvent e) {
    132161                boolean sel = selectedList.getSelectedIndex() != -1;
    133162                if (sel)
    134                     unselectedList.clearSelection();
     163                    actionsTree.clearSelection();
    135164                upButton.setEnabled(sel);
    136165                downButton.setEnabled(sel);
    137166            }
    138167        });
     168
     169        selectedList.setDragEnabled(true);
     170        selectedList.setTransferHandler(new TransferHandler() {
     171            @Override
     172            protected Transferable createTransferable(JComponent c) {
     173                return new ActionTransferable(((JList)c).getSelectedValues());
     174            }
     175
     176            @Override
     177            public int getSourceActions(JComponent c) {
     178                return TransferHandler.MOVE;
     179            }
     180
     181            @Override
     182            public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
     183                for (DataFlavor f : transferFlavors) {
     184                    if (ACTION_FLAVOR.equals(f)) {
     185                        return true;
     186                    }
     187                }
     188                return false;
     189            }
     190
     191            @Override
     192            public void exportAsDrag(JComponent comp, InputEvent e, int action) {
     193                super.exportAsDrag(comp, e, action);
     194                movingComponent = "list";
     195            }
     196
     197            @Override
     198            public boolean importData(JComponent comp, Transferable t) {
     199                try {
     200                    int dropIndex = selectedList.locationToIndex(selectedList.getDropLocation().getDropPoint());
     201                    Object[] draggedData = (Object[]) t.getTransferData(ACTION_FLAVOR);
     202
     203                    Object leadItem = dropIndex >= 0 ? selected.elementAt(dropIndex) : null;
     204                    int dataLength = draggedData.length;
     205
     206                    if (leadItem != null)
     207                        for (int i = 0; i < dataLength; i++)
     208                            if (leadItem.equals(draggedData[i]))
     209                                return false;
     210
     211                    int dragLeadIndex = -1;
     212                    boolean localDrop = "list".equals(movingComponent);
     213
     214                    if (localDrop) {
     215                        dragLeadIndex = selected.indexOf(draggedData[0]);
     216                        for (int i = 0; i < dataLength; i++)
     217                            selected.removeElement(draggedData[i]);
     218                    }
     219                    int[] indices = new int[dataLength];
     220
     221                    if (localDrop) {
     222                        int adjustedLeadIndex = selected.indexOf(leadItem);
     223                        int insertionAdjustment = dragLeadIndex <= adjustedLeadIndex ? 1 : 0;
     224                        for (int i = 0; i < dataLength; i++) {
     225                            selected.insertElementAt(draggedData[i], adjustedLeadIndex + insertionAdjustment + i);
     226                            indices[i] = adjustedLeadIndex + insertionAdjustment + i;
     227                        }
     228                    } else {
     229                        for (int i = 0; i < dataLength; i++) {
     230                            selected.add(dropIndex, draggedData[i]);
     231                            indices[i] = dropIndex + i;
     232                        }
     233                    }
     234                    selectedList.clearSelection();
     235                    selectedList.setSelectedIndices(indices);
     236                    movingComponent = "";
     237                    return true;
     238                } catch (Exception e) {
     239                    e.printStackTrace();
     240                }
     241                return false;
     242            }
     243
     244            @Override
     245            protected void exportDone(JComponent source, Transferable data, int action) {
     246                if (movingComponent.equals("list")) {
     247                    try {
     248                        Object[] draggedData = (Object[]) data.getTransferData(ACTION_FLAVOR);
     249                        boolean localDrop = selected.contains(draggedData[0]);
     250                        if (localDrop) {
     251                            int[] indices = selectedList.getSelectedIndices();
     252                            Arrays.sort(indices);
     253                            for (int i = indices.length - 1; i >= 0; i--) {
     254                                selected.remove(indices[i]);
     255                            }
     256                        }
     257                    } catch (Exception e) {
     258                        e.printStackTrace();
     259                    }
     260                    movingComponent = "";
     261                }
     262            }
     263        });
     264
     265        actionsTree.setTransferHandler(new TransferHandler() {
     266            private static final long serialVersionUID = 1L;
     267
     268            @Override
     269            public int getSourceActions( JComponent c ){
     270                return TransferHandler.MOVE;
     271            }
     272
     273            @Override
     274            protected void exportDone(JComponent source, Transferable data, int action) {
     275            }
     276
     277            @Override
     278            protected Transferable createTransferable(JComponent c) {
     279                TreePath[] paths = actionsTree.getSelectionPaths();
     280                List<String> dragActions = new LinkedList<String>();
     281                for (TreePath path : paths) {
     282                    DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
     283                    Object obj = node.getUserObject();
     284                    if (obj == null) {
     285                        dragActions.add(null);
     286                    }
     287                    else if (obj instanceof Action) {
     288                        dragActions.add((String) ((Action) obj).getValue("toolbar"));
     289                    }
     290                }
     291                return new ActionTransferable(dragActions.toArray());
     292            }
     293        });
     294        actionsTree.setDragEnabled(true);
    139295    }
    140296
    141297    public void addGui(PreferenceDialog gui) {
    142         selected.removeAllElements();
    143         unselected.removeAllElements();
    144         Map<String, Action> us = new TreeMap<String, Action>();
    145         for (Action a : actions.values())
    146         {
    147             us.put(a.getValue(Action.NAME).toString()+a.toString(), a);
    148         }
    149         for (String a : us.keySet())
    150             unselected.addElement(us.get(a));
    151         unselected.addElement(null);
    152 
    153298        final JPanel left = new JPanel(new GridBagLayout());
    154299        left.add(new JLabel(tr("Toolbar")), GBC.eol());
     
    157302        final JPanel right = new JPanel(new GridBagLayout());
    158303        right.add(new JLabel(tr("Available")), GBC.eol());
    159         right.add(new JScrollPane(unselectedList), GBC.eol().fill(GBC.BOTH));
     304        right.add(new JScrollPane(actionsTree), GBC.eol().fill(GBC.BOTH));
    160305
    161306        final JPanel buttons = new JPanel(new GridLayout(6,1));
    162307        buttons.add(upButton = createButton("up"));
    163         buttons.add(createButton("<<"));
    164308        buttons.add(createButton("<"));
    165309        buttons.add(createButton(">"));
    166         buttons.add(createButton(">>"));
    167310        buttons.add(downButton = createButton("down"));
    168311        upButton.setEnabled(false);
     
    180323            }
    181324            public Dimension preferredLayoutSize(Container parent) {
    182                 Dimension l = left.getPreferredSize();
    183                 Dimension r = right.getPreferredSize();
     325                Dimension l = new Dimension(200, 200); //left.getPreferredSize();
     326                Dimension r = new Dimension(200, 200); //right.getPreferredSize();
    184327                return new Dimension(l.width+r.width+10+buttons.getPreferredSize().width,Math.max(l.height, r.height));
    185328            }
     
    201344        panel.add(p, GBC.eol().fill(GBC.BOTH));
    202345
     346        selected.removeAllElements();
    203347        for (String s : getToolString()) {
    204348            if (s.equals("|"))
    205349                selected.addElement(null);
    206350            else {
    207                 Action a = actions.get(s);
    208                 if (a != null) {
    209                     selected.addElement(a);
    210                     unselected.removeElement(a);
    211                 }
    212             }
    213         }
    214     }
    215 
    216     private String[] getToolString() {
    217         String s = Main.pref.get("toolbar", "open;save;exportgpx;|;download;upload;|;undo;redo;|;preference");
    218         if (s == null || s.equals("null") || s.equals(""))
    219             return new String[0];
    220         return s.split(";");
     351                if (actions.get(s) != null) {
     352                    selected.addElement(s);
     353                }
     354            }
     355        }
     356    }
     357
     358    private void loadAction(DefaultMutableTreeNode node, MenuElement menu) {
     359        Object userObject = null;
     360        MenuElement menuElement = menu;
     361        if (menu.getSubElements().length > 0 &&
     362                menu.getSubElements()[0] instanceof JPopupMenu) {
     363            menuElement = menu.getSubElements()[0];
     364        }
     365        for (MenuElement item : menuElement.getSubElements()) {
     366            if (item instanceof JMenuItem) {
     367                JMenuItem menuItem = ((JMenuItem)item);
     368                if (menuItem.getAction() != null) {
     369                    Action action = menuItem.getAction();
     370                    userObject = action;
     371                    actions.put((String) action.getValue("toolbar"), action);
     372                } else {
     373                    userObject = menuItem.getText();
     374                }
     375            }
     376            DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(userObject);
     377            node.add(newNode);
     378            loadAction(newNode, item);
     379        }
     380    }
     381
     382    private void loadActions() {
     383        rootActionsNode.removeAllChildren();
     384        loadAction(rootActionsNode, Main.main.menu);
     385        rootActionsNode.add(new DefaultMutableTreeNode(null));
     386        actionsTree.updateUI();
     387        actionsTree.setRootVisible(false);
     388        actionsTree.expandPath(new TreePath(rootActionsNode));
     389    }
     390
     391    private static final String[] deftoolbar = {"open", "save", "exportgpx", "|",
     392    "download", "upload", "|", "undo", "redo", "|", "preference"};
     393    private Collection<String> getToolString() {
     394        return Main.pref.getCollection("toolbar", Arrays.asList(deftoolbar));
    221395    }
    222396
     
    236410    public boolean ok() {
    237411        StringBuilder b = new StringBuilder();
     412        Collection<String> t = new LinkedList<String>();
    238413        for (int i = 0; i < selected.size(); ++i) {
    239414            if (selected.get(i) == null)
    240                 b.append("|");
     415                t.add("|");
    241416            else
    242                 b.append(((Action)selected.get(i)).getValue("toolbar"));
    243             b.append(";");
    244         }
    245         String s = b.toString();
    246         if (s.length() > 0)
    247             s = s.substring(0, s.length()-1);
    248         else
    249             s = "null";
    250         Main.pref.put("toolbar", s);
     417                t.add((String)((actions.get(selected.get(i))).getValue("toolbar")));
     418        }
     419        Main.pref.putCollection("toolbar", t);
    251420        refreshToolbarControl();
    252421        return false;
     
    257426     */
    258427    public Action register(Action action) {
    259         actions.put((String)action.getValue("toolbar"), action);
     428//        actions.put((String) action.getValue("toolbar"), action);
    260429        return action;
    261430    }
     
    268437     */
    269438    public void refreshToolbarControl() {
     439        loadActions();
    270440        control.removeAll();
    271441        for (String s : getToolString()) {
     
    277447        control.setVisible(control.getComponentCount() != 0);
    278448    }
     449
     450    private static DataFlavor ACTION_FLAVOR = new DataFlavor(
     451            AbstractAction.class, "ActionItem");
     452
     453    private class ActionTransferable implements Transferable {
     454
     455        private DataFlavor[] flavors = new DataFlavor[] { ACTION_FLAVOR };
     456
     457        private Object[] actions;
     458
     459        public ActionTransferable(Action action) {
     460            this.actions = new Action[] { action };
     461        }
     462
     463        public ActionTransferable(Object[] actions) {
     464            this.actions = actions;
     465        }
     466
     467        public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
     468            return actions;
     469        }
     470
     471        public DataFlavor[] getTransferDataFlavors() {
     472            return flavors;
     473        }
     474
     475        public boolean isDataFlavorSupported(DataFlavor flavor) {
     476            return flavors[0] == flavor;
     477        }
     478    }
    279479}
Note: See TracChangeset for help on using the changeset viewer.