Ticket #1988: toolbar_preferences.patch
| File toolbar_preferences.patch, 20.2 KB (added by , 17 years ago) |
|---|
-
src/org/openstreetmap/josm/gui/preferences/ToolbarPreferences.java
### Eclipse Workspace Patch 1.0 #P JOSM
10 10 import java.awt.GridLayout; 11 11 import java.awt.LayoutManager; 12 12 import java.awt.Rectangle; 13 import java.awt.datatransfer.DataFlavor; 14 import java.awt.datatransfer.Transferable; 15 import java.awt.datatransfer.UnsupportedFlavorException; 13 16 import java.awt.event.ActionEvent; 14 17 import java.awt.event.ActionListener; 18 import java.awt.event.InputEvent; 19 import java.io.IOException; 20 import java.util.Arrays; 15 21 import java.util.HashMap; 16 import java.util.TreeMap; 22 import java.util.LinkedList; 23 import java.util.List; 17 24 import java.util.Map; 18 25 26 import javax.swing.AbstractAction; 19 27 import javax.swing.Action; 20 28 import javax.swing.DefaultListCellRenderer; 21 29 import javax.swing.DefaultListModel; 22 30 import javax.swing.Icon; 23 31 import javax.swing.JButton; 32 import javax.swing.JComponent; 24 33 import javax.swing.JLabel; 25 34 import javax.swing.JList; 35 import javax.swing.JMenuItem; 26 36 import javax.swing.JPanel; 37 import javax.swing.JPopupMenu; 27 38 import javax.swing.JScrollPane; 28 39 import javax.swing.JToolBar; 40 import javax.swing.JTree; 29 41 import javax.swing.ListCellRenderer; 42 import javax.swing.MenuElement; 43 import javax.swing.TransferHandler; 30 44 import javax.swing.event.ListSelectionEvent; 31 45 import javax.swing.event.ListSelectionListener; 46 import javax.swing.tree.DefaultMutableTreeNode; 47 import javax.swing.tree.DefaultTreeCellRenderer; 48 import javax.swing.tree.DefaultTreeModel; 49 import javax.swing.tree.TreePath; 32 50 33 51 import org.openstreetmap.josm.Main; 34 52 import org.openstreetmap.josm.tools.GBC; … … 38 56 39 57 private final class Move implements ActionListener { 40 58 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); 59 if (e.getActionCommand().equals("<") && actionsTree.getSelectionCount() > 0) { 60 61 int leadItem = selected.getSize(); 62 if (selectedList.getSelectedIndex() != -1) { 63 int[] indices = selectedList.getSelectedIndices(); 64 leadItem = indices[indices.length - 1]; 45 65 } 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()); 66 for (TreePath selectedAction : actionsTree.getSelectionPaths()) { 67 DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectedAction.getLastPathComponent(); 68 if (node.getUserObject() == null || node.getUserObject() instanceof Action) { 69 selected.add(leadItem++, ((Action)node.getUserObject()).getValue("toolbar")); 70 } 50 71 } 51 if (unselectedList.getSelectedIndex() == unselected.size()-1)52 selected.addElement(null);53 72 } else if (e.getActionCommand().equals(">") && selectedList.getSelectedIndex() != -1) { 54 73 while (selectedList.getSelectedIndex() != -1) { 55 if (selectedList.getSelectedValue() != null)56 unselected.add(unselected.size()-1, selectedList.getSelectedValue());57 74 selected.remove(selectedList.getSelectedIndex()); 58 75 } 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);64 }65 76 } else if (e.getActionCommand().equals("up")) { 66 77 int i = selectedList.getSelectedIndex(); 67 78 Object o = selected.get(i); … … 90 101 private Map<String, Action> actions = new HashMap<String, Action>(); 91 102 92 103 private DefaultListModel selected = new DefaultListModel(); 93 private DefaultListModel unselected = new DefaultListModel(); 104 105 private DefaultMutableTreeNode rootActionsNode = new DefaultMutableTreeNode("Actions"); 106 private DefaultTreeModel actionsTreeModel = new DefaultTreeModel(rootActionsNode); 107 private JTree actionsTree = new JTree(actionsTreeModel); 94 108 private JList selectedList = new JList(selected); 95 private JList unselectedList = new JList(unselected); 109 110 private String movingComponent; 96 111 97 112 public JToolBar control = new JToolBar(); 98 113 99 114 private JButton upButton; 100 115 private JButton downButton; 101 116 102 117 public ToolbarPreferences() { 103 118 control.setFloatable(false); 119 120 actionsTree.setCellRenderer(new DefaultTreeCellRenderer() { 121 @Override 122 public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, 123 boolean leaf, int row, boolean hasFocus) { 124 DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; 125 JLabel comp = (JLabel) super.getTreeCellRendererComponent( 126 tree, value, sel, expanded, leaf, row, hasFocus); 127 if (node.getUserObject() == null) { 128 comp.setText(tr("Separator")); 129 comp.setIcon(ImageProvider.get("preferences/separator")); 130 } 131 else if (node.getUserObject() instanceof Action) { 132 Action action = (Action) node.getUserObject(); 133 comp.setText((String) action.getValue(Action.NAME)); 134 comp.setIcon((Icon) action.getValue(Action.SMALL_ICON)); 135 } 136 return comp; 137 } 138 }); 104 139 105 final ListCellRenderer oldRenderer = selectedList.getCellRenderer();106 140 ListCellRenderer renderer = new DefaultListCellRenderer(){ 107 141 @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");142 String s; 143 Icon i; 110 144 if (value != null) { 111 s = (String)((Action)value).getValue(Action.NAME); 112 i = (Icon)((Action)value).getValue(Action.SMALL_ICON); 145 Action action = actions.get(value); 146 s = (String) action.getValue(Action.NAME); 147 i = (Icon) action.getValue(Action.SMALL_ICON); 148 } else { 149 i = ImageProvider.get("preferences/separator"); 150 s = tr("Separator"); 113 151 } 114 JLabel l = (JLabel) oldRenderer.getListCellRendererComponent(list, s, index, isSelected, cellHasFocus);152 JLabel l = (JLabel)super.getListCellRendererComponent(list, s, index, isSelected, cellHasFocus); 115 153 l.setIcon(i); 116 154 return l; 117 155 } 118 156 }; 119 157 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 });130 158 selectedList.addListSelectionListener(new ListSelectionListener(){ 131 159 public void valueChanged(ListSelectionEvent e) { 132 160 boolean sel = selectedList.getSelectedIndex() != -1; 133 161 if (sel) 134 unselectedList.clearSelection();162 actionsTree.clearSelection(); 135 163 upButton.setEnabled(sel); 136 164 downButton.setEnabled(sel); 137 165 } 138 166 }); 139 } 167 168 selectedList.setDragEnabled(true); 169 selectedList.setTransferHandler(new TransferHandler() { 170 @Override 171 protected Transferable createTransferable(JComponent c) { 172 return new ActionTransferable(((JList)c).getSelectedValues()); 173 } 140 174 141 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); 175 @Override 176 public int getSourceActions(JComponent c) { 177 return TransferHandler.MOVE; 178 } 179 180 @Override 181 public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) { 182 for (DataFlavor f : transferFlavors) { 183 if (ACTION_FLAVOR.equals(f)) { 184 return true; 185 } 186 } 187 return false; 188 } 189 190 @Override 191 public void exportAsDrag(JComponent comp, InputEvent e, int action) { 192 super.exportAsDrag(comp, e, action); 193 movingComponent = "list"; 194 } 195 196 @Override 197 public boolean importData(JComponent comp, Transferable t) { 198 try { 199 int dropIndex = selectedList.locationToIndex(selectedList.getDropLocation().getDropPoint()); 200 Object[] draggedData = (Object[]) t.getTransferData(ACTION_FLAVOR); 201 202 Object leadItem = dropIndex >= 0 ? selected.elementAt(dropIndex) : null; 203 int dataLength = draggedData.length; 204 205 if (leadItem != null) 206 for (int i = 0; i < dataLength; i++) 207 if (leadItem.equals(draggedData[i])) 208 return false; 209 210 int dragLeadIndex = -1; 211 boolean localDrop = "list".equals(movingComponent); 152 212 213 if (localDrop) { 214 dragLeadIndex = selected.indexOf(draggedData[0]); 215 for (int i = 0; i < dataLength; i++) 216 selected.removeElement(draggedData[i]); 217 } 218 int[] indices = new int[dataLength]; 219 220 if (localDrop) { 221 int adjustedLeadIndex = selected.indexOf(leadItem); 222 int insertionAdjustment = dragLeadIndex <= adjustedLeadIndex ? 1 : 0; 223 for (int i = 0; i < dataLength; i++) { 224 selected.insertElementAt(draggedData[i], adjustedLeadIndex + insertionAdjustment + i); 225 indices[i] = adjustedLeadIndex + insertionAdjustment + i; 226 } 227 } else { 228 for (int i = 0; i < dataLength; i++) { 229 selected.add(dropIndex, draggedData[i]); 230 indices[i] = dropIndex + i; 231 } 232 } 233 selectedList.clearSelection(); 234 selectedList.setSelectedIndices(indices); 235 movingComponent = ""; 236 return true; 237 } catch (Exception e) { 238 e.printStackTrace(); 239 } 240 return false; 241 } 242 243 @Override 244 protected void exportDone(JComponent source, Transferable data, int action) { 245 if (movingComponent.equals("list")) { 246 try { 247 Object[] draggedData = (Object[]) data.getTransferData(ACTION_FLAVOR); 248 boolean localDrop = selected.contains(draggedData[0]); 249 if (localDrop) { 250 int[] indices = selectedList.getSelectedIndices(); 251 Arrays.sort(indices); 252 for (int i = indices.length - 1; i >= 0; i--) { 253 selected.remove(indices[i]); 254 } 255 } 256 } catch (Exception e) { 257 e.printStackTrace(); 258 } 259 movingComponent = ""; 260 } 261 } 262 }); 263 264 actionsTree.setTransferHandler(new TransferHandler() { 265 private static final long serialVersionUID = 1L; 266 267 @Override 268 public int getSourceActions( JComponent c ){ 269 return TransferHandler.MOVE; 270 } 271 272 @Override 273 protected void exportDone(JComponent source, Transferable data, int action) { 274 } 275 276 @Override 277 protected Transferable createTransferable(JComponent c) { 278 TreePath[] paths = actionsTree.getSelectionPaths(); 279 List<String> dragActions = new LinkedList<String>(); 280 for (TreePath path : paths) { 281 DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); 282 Object obj = node.getUserObject(); 283 if (obj == null) { 284 dragActions.add(null); 285 } 286 else if (obj instanceof Action) { 287 dragActions.add((String) ((Action) obj).getValue("toolbar")); 288 } 289 } 290 return new ActionTransferable(dragActions.toArray()); 291 } 292 }); 293 actionsTree.setDragEnabled(true); 294 } 295 296 public void addGui(PreferenceDialog gui) { 153 297 final JPanel left = new JPanel(new GridBagLayout()); 154 298 left.add(new JLabel(tr("Toolbar")), GBC.eol()); 155 299 left.add(new JScrollPane(selectedList), GBC.std().fill(GBC.BOTH)); 156 300 157 301 final JPanel right = new JPanel(new GridBagLayout()); 158 302 right.add(new JLabel(tr("Available")), GBC.eol()); 159 right.add(new JScrollPane( unselectedList), GBC.eol().fill(GBC.BOTH));303 right.add(new JScrollPane(actionsTree), GBC.eol().fill(GBC.BOTH)); 160 304 161 305 final JPanel buttons = new JPanel(new GridLayout(6,1)); 162 306 buttons.add(upButton = createButton("up")); 163 buttons.add(createButton("<<"));164 307 buttons.add(createButton("<")); 165 308 buttons.add(createButton(">")); 166 buttons.add(createButton(">>"));167 309 buttons.add(downButton = createButton("down")); 168 310 upButton.setEnabled(false); 169 311 downButton.setEnabled(false); … … 179 321 return new Dimension(l.width+b.width+10+r.width,l.height+b.height+10+r.height); 180 322 } 181 323 public Dimension preferredLayoutSize(Container parent) { 182 Dimension l = left.getPreferredSize();183 Dimension r = right.getPreferredSize();324 Dimension l = new Dimension(200, 200); //left.getPreferredSize(); 325 Dimension r = new Dimension(200, 200); //right.getPreferredSize(); 184 326 return new Dimension(l.width+r.width+10+buttons.getPreferredSize().width,Math.max(l.height, r.height)); 185 327 } 186 328 public void layoutContainer(Container parent) { … … 200 342 tr("Customize the elements on the toolbar."), false); 201 343 panel.add(p, GBC.eol().fill(GBC.BOTH)); 202 344 345 selected.removeAllElements(); 203 346 for (String s : getToolString()) { 204 347 if (s.equals("|")) 205 348 selected.addElement(null); 206 349 else { 207 Action a = actions.get(s); 208 if (a != null) { 209 selected.addElement(a); 210 unselected.removeElement(a); 350 if (actions.get(s) != null) { 351 selected.addElement(s); 352 } 353 } 354 } 355 } 356 357 private void loadAction(DefaultMutableTreeNode node, MenuElement menu) { 358 Object userObject = null; 359 MenuElement menuElement = menu; 360 if (menu.getSubElements().length > 0 && 361 menu.getSubElements()[0] instanceof JPopupMenu) { 362 menuElement = menu.getSubElements()[0]; 363 } 364 for (MenuElement item : menuElement.getSubElements()) { 365 if (item instanceof JMenuItem) { 366 JMenuItem menuItem = ((JMenuItem)item); 367 if (menuItem.getAction() != null) { 368 Action action = menuItem.getAction(); 369 userObject = action; 370 actions.put((String) action.getValue("toolbar"), action); 371 } else { 372 userObject = menuItem.getText(); 211 373 } 212 374 } 375 DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(userObject); 376 node.add(newNode); 377 loadAction(newNode, item); 213 378 } 214 379 } 215 380 381 private void loadActions() { 382 rootActionsNode.removeAllChildren(); 383 loadAction(rootActionsNode, Main.main.menu); 384 rootActionsNode.add(new DefaultMutableTreeNode(null)); 385 actionsTree.updateUI(); 386 actionsTree.setRootVisible(false); 387 actionsTree.expandPath(new TreePath(rootActionsNode)); 388 } 389 216 390 private String[] getToolString() { 217 String s = Main.pref.get("toolbar", "open;save;exportgpx;|;download;upload;|;undo;redo;|;preference"); 391 String s = Main.pref.get("toolbar", 392 "open;save;exportgpx;|;download;upload;|;undo;redo;|;preference"); 218 393 if (s == null || s.equals("null") || s.equals("")) 219 394 return new String[0]; 220 395 return s.split(";"); … … 239 414 if (selected.get(i) == null) 240 415 b.append("|"); 241 416 else 242 b.append(( (Action)selected.get(i)).getValue("toolbar"));417 b.append((actions.get(selected.get(i))).getValue("toolbar")); 243 418 b.append(";"); 244 419 } 245 420 String s = b.toString(); … … 256 431 * @return The parameter (for better chaining) 257 432 */ 258 433 public Action register(Action action) { 259 actions.put((String)action.getValue("toolbar"), action);434 // actions.put((String) action.getValue("toolbar"), action); 260 435 return action; 261 436 } 262 437 … … 267 442 * the toolbar content (e.g. after registering actions in a plugin) 268 443 */ 269 444 public void refreshToolbarControl() { 445 loadActions(); 270 446 control.removeAll(); 271 447 for (String s : getToolString()) { 272 448 if (s.equals("|")) … … 276 452 } 277 453 control.setVisible(control.getComponentCount() != 0); 278 454 } 279 } 455 456 private static DataFlavor ACTION_FLAVOR = new DataFlavor( 457 AbstractAction.class, "ActionItem"); 458 459 private class ActionTransferable implements Transferable { 460 461 private DataFlavor[] flavors = new DataFlavor[] { ACTION_FLAVOR }; 462 463 private Object[] actions; 464 465 public ActionTransferable(Action action) { 466 this.actions = new Action[] { action }; 467 } 468 469 public ActionTransferable(Object[] actions) { 470 this.actions = actions; 471 } 472 473 public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { 474 return actions; 475 } 476 477 public DataFlavor[] getTransferDataFlavors() { 478 return flavors; 479 } 480 481 public boolean isDataFlavorSupported(DataFlavor flavor) { 482 return flavors[0] == flavor; 483 } 484 } 485 }
