001 // License: GPL. For details, see LICENSE file. 002 package org.openstreetmap.josm.io.remotecontrol; 003 004 import static org.openstreetmap.josm.tools.I18n.tr; 005 006 import java.awt.Color; 007 import java.awt.Component; 008 import java.awt.Dimension; 009 import java.awt.Font; 010 import java.awt.GridBagLayout; 011 import java.awt.event.ActionEvent; 012 import java.util.Collection; 013 014 import javax.swing.JPanel; 015 import javax.swing.JTable; 016 import javax.swing.table.DefaultTableModel; 017 import javax.swing.table.TableCellRenderer; 018 import javax.swing.table.TableModel; 019 020 import org.openstreetmap.josm.Main; 021 import org.openstreetmap.josm.command.ChangePropertyCommand; 022 import org.openstreetmap.josm.data.SelectionChangedListener; 023 import org.openstreetmap.josm.data.osm.DataSet; 024 import org.openstreetmap.josm.data.osm.OsmPrimitive; 025 import org.openstreetmap.josm.gui.ExtendedDialog; 026 import org.openstreetmap.josm.tools.GBC; 027 028 /** 029 * 030 * @author master 031 * 032 * Dialog to add tags as part of the remotecontrol 033 * Existing Keys get grey color and unchecked selectboxes so they will not overwrite the old Key-Value-Pairs by default. 034 * You can choose the tags you want to add by selectboxes. You can edit the tags before you apply them. 035 * 036 */ 037 public class AddTagsDialog extends ExtendedDialog implements SelectionChangedListener { 038 039 040 private final JTable propertyTable; 041 private Collection<? extends OsmPrimitive> sel; 042 boolean[] existing; 043 044 public AddTagsDialog(String[][] tags) { 045 super(Main.parent, tr("Add tags to selected objects"), new String[] { tr("Add tags"), tr("Cancel")}, 046 false, 047 true); 048 049 DataSet.addSelectionListener(this); 050 051 052 DefaultTableModel tm = new DefaultTableModel(new String[] {tr("Assume"), tr("Key"), tr("Value")}, tags.length) { 053 @Override 054 public Class getColumnClass(int c) { 055 return getValueAt(0, c).getClass(); 056 } 057 058 }; 059 060 sel = Main.main.getCurrentDataSet().getSelected(); 061 existing = new boolean[tags.length]; 062 063 for (int i = 0; i<tags.length; i++) { 064 existing[i] = false; 065 String key = tags[i][0]; 066 Boolean b = Boolean.TRUE; 067 for (OsmPrimitive osm : sel) { 068 if (osm.keySet().contains(key)) { 069 b = Boolean.FALSE; 070 existing[i]=true; 071 break; 072 } 073 } 074 tm.setValueAt(b, i, 0); 075 tm.setValueAt(tags[i][0], i, 1); 076 tm.setValueAt(tags[i][1], i, 2); 077 } 078 079 propertyTable = new JTable(tm) { 080 081 private static final long serialVersionUID = 1L; 082 083 @Override 084 public Component prepareRenderer(TableCellRenderer renderer, int row, int column) { 085 Component c = super.prepareRenderer(renderer, row, column); 086 if (existing[row]) { 087 c.setFont(c.getFont().deriveFont(Font.ITALIC)); 088 c.setForeground(new Color(100, 100, 100)); 089 } else { 090 c.setFont(c.getFont().deriveFont(Font.PLAIN)); 091 c.setForeground(new Color(0, 0, 0)); 092 } 093 return c; 094 } 095 }; 096 097 // a checkbox has a size of 15 px 098 propertyTable.getColumnModel().getColumn(0).setMaxWidth(15); 099 // get edit results if the table looses the focus, for example if a user clicks "add tags" 100 propertyTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE); 101 102 // set the content of this AddTagsDialog consisting of the tableHeader and the table itself. 103 JPanel tablePanel = new JPanel(); 104 tablePanel.setLayout(new GridBagLayout()); 105 tablePanel.add(propertyTable.getTableHeader(), GBC.eol().fill(GBC.HORIZONTAL)); 106 tablePanel.add(propertyTable, GBC.eol().fill(GBC.BOTH)); 107 setContent(tablePanel); 108 109 // set the default Dimensions and show the dialog 110 setPreferredSize(new Dimension(400,tablePanel.getPreferredSize().height+100)); 111 showDialog(); 112 } 113 114 /** 115 * This method looks for existing tags in the current selection and sets the corresponding boolean in the boolean array existing[] 116 */ 117 private void findExistingTags() { 118 TableModel tm = propertyTable.getModel(); 119 for (int i=0; i<tm.getRowCount(); i++) { 120 String key = (String)tm.getValueAt(i, 1); 121 existing[i] = false; 122 for (OsmPrimitive osm : sel) { 123 if (osm.keySet().contains(key)) { 124 existing[i] = true; 125 break; 126 } 127 } 128 } 129 propertyTable.repaint(); 130 } 131 132 /** 133 * If you click the "Add tags" button build a ChangePropertyCommand for every key that has a checked checkbox to apply the key value pair to all selected osm objects. 134 * You get a entry for every key in the command queue. 135 */ 136 @Override 137 protected void buttonAction(int buttonIndex, ActionEvent evt) { 138 if (buttonIndex == 0) { 139 TableModel tm = propertyTable.getModel(); 140 for (int i=0; i<tm.getRowCount(); i++) { 141 if ((Boolean)tm.getValueAt(i, 0)) { 142 Main.main.undoRedo.add(new ChangePropertyCommand(sel, (String)tm.getValueAt(i, 1), (String)tm.getValueAt(i, 2))); 143 } 144 } 145 } 146 setVisible(false); 147 } 148 149 @Override 150 public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) { 151 sel = newSelection; 152 findExistingTags(); 153 } 154 155 }