Ticket #1988: toolbar_prefs_dnd.patch

File toolbar_prefs_dnd.patch, 11.8 KB (added by Igor Shubovych <igor.shubovych@…>, 16 years ago)

Patch to fix that

  • src/org/openstreetmap/josm/gui/preferences/ToolbarPreferences.java

     
    1010import java.awt.GridLayout;
    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.io.IOException;
    1519import java.util.HashMap;
    16 import java.util.TreeMap;
    1720import java.util.Map;
    1821
     22import javax.swing.AbstractAction;
    1923import javax.swing.Action;
    2024import javax.swing.DefaultListCellRenderer;
    2125import javax.swing.DefaultListModel;
    2226import javax.swing.Icon;
    2327import javax.swing.JButton;
     28import javax.swing.JComponent;
    2429import javax.swing.JLabel;
    2530import javax.swing.JList;
    2631import javax.swing.JPanel;
    2732import javax.swing.JScrollPane;
    2833import javax.swing.JToolBar;
    2934import javax.swing.ListCellRenderer;
     35import javax.swing.TransferHandler;
    3036import javax.swing.event.ListSelectionEvent;
    3137import javax.swing.event.ListSelectionListener;
    3238
    3339import org.openstreetmap.josm.Main;
     40import org.openstreetmap.josm.gui.util.ReorderAndMoveListDndHandler;
    3441import org.openstreetmap.josm.tools.GBC;
    3542import org.openstreetmap.josm.tools.ImageProvider;
    3643
     
    107114            @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
    108115                String s = tr("Separator");
    109116                Icon i = ImageProvider.get("preferences/separator");
    110                 if (value != null) {
    111                     s = (String)((Action)value).getValue(Action.NAME);
    112                     i = (Icon)((Action)value).getValue(Action.SMALL_ICON);
     117                Action action = actions.get(value);
     118                if (action != null) {
     119                    s = (String) action.getValue(Action.NAME);
     120                    i = (Icon) action.getValue(Action.SMALL_ICON);
    113121                }
    114122                JLabel l = (JLabel)oldRenderer.getListCellRendererComponent(list, s, index, isSelected, cellHasFocus);
    115123                l.setIcon(i);
     
    136144                downButton.setEnabled(sel);
    137145            }
    138146        });
     147       
     148        selectedList.setDragEnabled(true);
     149        selectedList.setTransferHandler(new ReorderAndMoveListDndHandler(ACTION_FLAVOR) {
     150            @Override
     151            protected Transferable createTransferable(JComponent c) {
     152                return new ActionTransferable(((JList)c).getSelectedValues());
     153            }
     154        });
     155        unselectedList.setDragEnabled(true);
     156        unselectedList.setTransferHandler(new TransferHandler() {
     157            private static final long serialVersionUID = 1L;
     158       
     159            @Override
     160            public int getSourceActions( JComponent c ){
     161                return TransferHandler.MOVE;
     162            }
     163           
     164            @Override
     165            protected void exportDone(JComponent source, Transferable data, int action) {
     166            }
     167           
     168            @Override
     169            protected Transferable createTransferable(JComponent c) {
     170                return new ActionTransferable(((JList)c).getSelectedValues());
     171            }
     172    });
    139173    }
    140174
    141175    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 
    153176        final JPanel left = new JPanel(new GridBagLayout());
    154177        left.add(new JLabel(tr("Toolbar")), GBC.eol());
    155178        left.add(new JScrollPane(selectedList), GBC.std().fill(GBC.BOTH));
     
    179202                return new Dimension(l.width+b.width+10+r.width,l.height+b.height+10+r.height);
    180203            }
    181204            public Dimension preferredLayoutSize(Container parent) {
    182                 Dimension l = left.getPreferredSize();
    183                 Dimension r = right.getPreferredSize();
     205                Dimension l = new Dimension(200, 200); //left.getPreferredSize();
     206                Dimension r = new Dimension(200, 200); //right.getPreferredSize();
    184207                return new Dimension(l.width+r.width+10+buttons.getPreferredSize().width,Math.max(l.height, r.height));
    185208            }
    186209            public void layoutContainer(Container parent) {
     
    200223                tr("Customize the elements on the toolbar."), false);
    201224        panel.add(p, GBC.eol().fill(GBC.BOTH));
    202225
     226        selected.removeAllElements();
     227        unselected.removeAllElements();
     228        for (String a : actions.keySet())
     229            unselected.addElement(a);
     230        unselected.addElement(null);
    203231        for (String s : getToolString()) {
    204232            if (s.equals("|"))
    205233                selected.addElement(null);
    206234            else {
    207                 Action a = actions.get(s);
    208                 if (a != null) {
    209                     selected.addElement(a);
    210                     unselected.removeElement(a);
     235                if (actions.get(s) != null) {
     236                    selected.addElement(s);
     237                    unselected.removeElement(s);
    211238                }
    212239            }
    213240        }
    214241    }
    215242
    216243    private String[] getToolString() {
    217         String s = Main.pref.get("toolbar", "open;save;exportgpx;|;download;upload;|;undo;redo;|;preference");
     244        String s = Main.pref.get("toolbar",
     245                "open;save;exportgpx;|;download;upload;|;undo;redo;|;preference");
    218246        if (s == null || s.equals("null") || s.equals(""))
    219247            return new String[0];
    220248        return s.split(";");
     
    239267            if (selected.get(i) == null)
    240268                b.append("|");
    241269            else
    242                 b.append(((Action)selected.get(i)).getValue("toolbar"));
     270                b.append((actions.get(selected.get(i))).getValue("toolbar"));
    243271            b.append(";");
    244272        }
    245273        String s = b.toString();
     
    276304        }
    277305        control.setVisible(control.getComponentCount() != 0);
    278306    }
    279 }
     307
     308    private static DataFlavor ACTION_FLAVOR = new DataFlavor(
     309            AbstractAction.class, "ActionItem");
     310   
     311    private class ActionTransferable implements Transferable {
     312       
     313        private DataFlavor[] flavors = new DataFlavor[] { ACTION_FLAVOR };
     314       
     315        private Object[] actions;
     316       
     317        public ActionTransferable(Action action) {
     318            this.actions = new Action[] { action };
     319        }
     320       
     321        public ActionTransferable(Object[] actions) {
     322            this.actions = actions;
     323        }
     324
     325        public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
     326            return actions;
     327        }
     328
     329        public DataFlavor[] getTransferDataFlavors() {
     330            return flavors;
     331        }
     332
     333        public boolean isDataFlavorSupported(DataFlavor flavor) {
     334            return flavors[0] == flavor;
     335        }
     336    }
     337 }
  • src/org/openstreetmap/josm/gui/util/ReorderAndMoveListDndHandler.java

     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.gui.util;
     3
     4import java.awt.datatransfer.DataFlavor;
     5import java.awt.datatransfer.Transferable;
     6
     7import javax.swing.DefaultListModel;
     8import javax.swing.JComponent;
     9import javax.swing.JList;
     10import javax.swing.SwingUtilities;
     11import javax.swing.TransferHandler;
     12
     13/**
     14 * @author Igor Shubovych igor.shubovych@gmail.com
     15 */
     16public class ReorderAndMoveListDndHandler extends TransferHandler {
     17   
     18    public ReorderAndMoveListDndHandler(DataFlavor flavor) {
     19        this.flavor = flavor;
     20    }
     21   
     22    private DataFlavor flavor;
     23   
     24    private static final long serialVersionUID = 1L;
     25   
     26    public int getSourceActions( JComponent c ){
     27        return TransferHandler.MOVE;
     28    }
     29   
     30    @Override
     31    public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
     32        for (DataFlavor f : transferFlavors) {
     33            if (flavor.equals(f)) {
     34                return true;
     35            }
     36        }
     37        return false;
     38    }
     39   
     40    @Override
     41    public boolean importData(JComponent comp, Transferable t) {
     42        try{
     43            // this is the index of the element onto which the dragged element, is dropped
     44            final JList dragList = (JList) comp;
     45            final int dropIndex = dragList.locationToIndex( dragList.getDropLocation().getDropPoint() );
     46            Object[] draggedData = (Object[]) t.getTransferData(flavor);
     47            DefaultListModel dragModel    = (DefaultListModel)dragList.getModel();
     48            DefaultListModel dropModel    = (DefaultListModel)dragList.getModel();
     49           
     50            final Object leadItem     = dropIndex >= 0 ? dropModel.elementAt( dropIndex ) : null;
     51            final int dataLength     = draggedData.length;           
     52
     53            if( leadItem != null )
     54                for( int i = 0 ; i < dataLength ; i++ )
     55                    if( draggedData[i].equals( leadItem ) )
     56                        return false;               
     57           
     58            int dragLeadIndex        = -1;
     59            final boolean localDrop    = dropModel.contains( draggedData[0] );
     60           
     61            if( localDrop )
     62                dragLeadIndex    = dropModel.indexOf( draggedData[0] );
     63           
     64            for( int i = 0 ; i < dataLength ; i++ )
     65                dragModel.removeElement( draggedData[i] );
     66                   
     67            if( localDrop ){
     68                final int adjustedLeadIndex = dropModel.indexOf( leadItem );
     69                final int insertionAdjustment = dragLeadIndex <= adjustedLeadIndex ? 1 : 0;
     70                   
     71                final int [] indices = new int[dataLength];
     72                for( int i = 0 ; i < dataLength ; i++ ){
     73                    dropModel.insertElementAt( draggedData[i], adjustedLeadIndex + insertionAdjustment + i );
     74                    indices[i] = adjustedLeadIndex + insertionAdjustment + i;
     75                }
     76               
     77                SwingUtilities.invokeLater( new Runnable(){
     78                    public void run() {
     79                        dragList.clearSelection();       
     80                        dragList.setSelectedIndices( indices );
     81                    }
     82                });
     83            }
     84            else{
     85                final int [] indices = new int[dataLength];
     86                for( int i = 0 ; i < dataLength ; i++ ){
     87                    dropModel.insertElementAt( draggedData[i], dropIndex + 1 );
     88                    indices[i] = dropIndex + 1 + i;
     89                }
     90               
     91                SwingUtilities.invokeLater( new Runnable(){
     92                    public void run() {
     93                        dragList.clearSelection();       
     94                        dragList.setSelectedIndices( indices );
     95                        dragList.clearSelection();
     96                    }
     97                });
     98            }
     99        }
     100        catch( Exception x ){
     101            x.printStackTrace();
     102        }           
     103        return false;
     104    }
     105}
     106 No newline at end of file