Index: applications/editors/josm/plugins/utilsplugin2/build.xml
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/build.xml	(revision 30343)
+++ applications/editors/josm/plugins/utilsplugin2/build.xml	(revision 30370)
@@ -3,5 +3,5 @@
 
     <!-- enter the SVN commit message -->
-    <property name="commit.message" value="[josm_utilsplugin2]: alpha version of multitagger ctrl-t"/>
+    <property name="commit.message" value="[josm_utilsplugin2]: multitagger improvements"/>
     <!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
     <property name="plugin.main.version" value="6317"/>
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/multitagger/MultiTagDialog.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/multitagger/MultiTagDialog.java	(revision 30343)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/multitagger/MultiTagDialog.java	(revision 30370)
@@ -5,4 +5,5 @@
 import java.awt.GridBagLayout;
 import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
 import java.awt.event.ItemEvent;
 import java.awt.event.ItemListener;
@@ -10,23 +11,27 @@
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.EventObject;
 import java.util.LinkedList;
 import java.util.List;
 import javax.swing.AbstractAction;
 import static javax.swing.Action.SHORT_DESCRIPTION;
+import javax.swing.BoxLayout;
 import javax.swing.JButton;
 import javax.swing.JComponent;
+import javax.swing.JLabel;
 import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
 import javax.swing.JScrollPane;
 import javax.swing.JTable;
+import javax.swing.JToggleButton;
 import javax.swing.KeyStroke;
 import javax.swing.ListSelectionModel;
-import javax.swing.event.CellEditorListener;
+import javax.swing.SwingUtilities;
 import javax.swing.event.ListSelectionEvent;
 import javax.swing.event.ListSelectionListener;
-import javax.swing.table.TableCellEditor;
+import javax.swing.table.DefaultTableCellRenderer;
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.AutoScaleAction;
@@ -34,4 +39,5 @@
 import org.openstreetmap.josm.data.SelectionChangedListener;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
 import org.openstreetmap.josm.data.preferences.StringProperty;
 import org.openstreetmap.josm.gui.ExtendedDialog;
@@ -41,7 +47,9 @@
 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionList;
 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionManager;
+import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.gui.util.HighlightHelper;
 import org.openstreetmap.josm.gui.util.TableHelper;
 import org.openstreetmap.josm.gui.widgets.HistoryComboBox;
+import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
 import org.openstreetmap.josm.tools.GBC;
 import static org.openstreetmap.josm.tools.I18n.tr;
@@ -55,49 +63,73 @@
 
     private final MultiTaggerTableModel tableModel = new MultiTaggerTableModel();
-    private final JTable tbl = new JTable(tableModel);
+    private final JTable tbl;
     //
     private final HighlightHelper highlightHelper = new HighlightHelper();
-    private final HistoryComboBox tagSetSelector = new HistoryComboBox();
+    private final HistoryComboBox cbTagSet = new HistoryComboBox();
     
     private static final String HISTORY_KEY = "utilsplugin2.multitaghistory";
-    String defaultHistory[] = {"addr:street, addr:housenumber, building",
-        "highway, name, ${id}, ${length}, ${type}",
+    String defaultHistory[] = {"addr:street, addr:housenumber, building, ${area}",
+        "highway, name, ${id}, ${length}",
         "name name:en name:ru name:de"};
-    private final StringProperty LAST_TAGS = new StringProperty("utilsplugin2.multitag.last", defaultHistory[0]);
     TagCellEditor cellEditor;
     
-            
+    
     public MultiTagDialog() {
         super(Main.parent,  tr("Edit tags"), new String[]{tr("Ok"), tr("Cancel")}, false);
         JPanel pnl = new JPanel(new GridBagLayout());
-        tbl.setFillsViewportHeight(true);
-        tbl.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
-        tbl.addMouseListener(tableMouseAdapter);
-        tbl.setRowSelectionAllowed(true);
-        tbl.setColumnSelectionAllowed(true);
-        tbl.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
-        loadHistory();
-        
-        tagSetSelector.addItemListener(tagSetChanger);
-        tagSetSelector.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
+        tbl = createTable();
+        
+        cbTagSet.addItemListener(tagSetChanger);
+        cbTagSet.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
            .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, true), "applyTagSet");
-        tagSetSelector.getActionMap().put("applyTagSet", tagSetChanger);
-        
-        tagSetChanger.itemStateChanged(null);
-        pnl.add(tagSetSelector,GBC.std().fill(GBC.HORIZONTAL));
+        cbTagSet.getActionMap().put("applyTagSet", tagSetChanger);
+        
+        tbl.addMouseListener(new PopupMenuLauncher(createPopupMenu()));
+        
+        pnl.add(cbTagSet,GBC.std().fill(GBC.HORIZONTAL));
         pnl.add(new JButton(new DeleteFromHistoryAction()),GBC.std());
         pnl.add(new JButton(new FindMatchingAction()),GBC.eol());
+        pnl.add(createTypeFilterPanel(), GBC.eol().fill(GBC.HORIZONTAL));
         pnl.add(tbl.getTableHeader(),GBC.eop().fill(GBC.HORIZONTAL));
-
+        
         pnl.add(new JScrollPane(tbl), GBC.eol().fill(GBC.BOTH));
-        tbl.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
-        tbl.getSelectionModel().addListSelectionListener(selectionListener);
         setContent(pnl);
         setDefaultButton(-1);
+        loadHistory();
         
         WindowGeometry defaultGeometry = WindowGeometry.centerInWindow(Main.parent, new Dimension(500, 500));
         setRememberWindowGeometry(getClass().getName() + ".geometry", defaultGeometry);
-        
-
+    }
+
+    private JTable createTable() {
+        JTable t = new JTable(tableModel);
+        t.setFillsViewportHeight(true);
+        t.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+        t.addMouseListener(tableMouseAdapter);
+        t.setRowSelectionAllowed(true);
+        t.setColumnSelectionAllowed(true);
+        t.setDefaultRenderer(OsmPrimitiveType.class, new PrimitiveTypeIconRenderer());
+        t.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
+        t.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
+        t.getSelectionModel().addListSelectionListener(selectionListener);
+        return t;
+    }
+
+    private JPanel createTypeFilterPanel() {
+        JPanel p = new JPanel();
+        p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
+        for (final OsmPrimitiveType type: OsmPrimitiveType.values()) {
+            final JToggleButton jt = new JToggleButton("", ImageProvider.get(type), true);
+            jt.addActionListener(new ActionListener(){
+                @Override
+                public void actionPerformed(ActionEvent e) {
+                    if (jt.isSelected()) tableModel.shownTypes.add(type); else tableModel.shownTypes.remove(type);
+                    tableModel.updateData(Main.main.getCurrentDataSet().getSelected());
+                };
+            });
+            ImageProvider.get(type);
+            p.add(jt);
+        }
+        return p;
     }
 
@@ -106,6 +138,8 @@
                 Main.pref.getCollection(HISTORY_KEY, Arrays.asList(defaultHistory)));
         Collections.reverse(cmtHistory);
-        tagSetSelector.setPossibleItems(cmtHistory);
-        tagSetSelector.setText(LAST_TAGS.get());
+        cbTagSet.setPossibleItems(cmtHistory);
+        String s = cmtHistory.get(cmtHistory.size()-1);
+        cbTagSet.setText(s);
+        specifyTagSet(s);
     }
 
@@ -131,5 +165,5 @@
     }
     
-    private final MouseAdapter tableMouseAdapter = new MouseAdapter() {
+   private final MouseAdapter tableMouseAdapter = new MouseAdapter() {
         @Override
         public void mouseClicked(MouseEvent e) {
@@ -143,7 +177,7 @@
         @Override
         public void valueChanged(ListSelectionEvent e) {
-            OsmPrimitive p = getSelectedPrimitive();
-            if (p != null && Main.isDisplayingMapView() ) {
-                if (highlightHelper.highlightOnly(p)) {
+            List<OsmPrimitive> prims = getSelectedPrimitives();
+            if (prims != null && Main.isDisplayingMapView() ) {
+                if (highlightHelper.highlightOnly(prims)) {
                     Main.map.mapView.repaint();
                 }
@@ -152,19 +186,10 @@
     };
     
-    public void setAutoCompletion(boolean enable){
-        if (!enable) {
-            
-        }
-            
-        OsmDataLayer l = Main.main.getEditLayer();
-        AutoCompletionManager autocomplete = l.data.getAutoCompletionManager();
-        AutoCompletionList acList = new AutoCompletionList();
-          
-//        TagCellEditor editor = ((TagCellEditor) tagTable.getColumnModel().getColumn(0).getCellEditor());
-//        editor.setAutoCompletionManager(autocomplete);
-//        editor.setAutoCompletionList(acList);
-//        editor = ((TagCellEditor) tagTable.getColumnModel().getColumn(1).getCellEditor());
-//        editor.setAutoCompletionManager(autocomplete);
-//        editor.setAutoCompletionList(acList);
+    public List<OsmPrimitive> getSelectedPrimitives() {
+        ArrayList<OsmPrimitive> sel = new ArrayList<OsmPrimitive>(100);
+        for (int idx: tbl.getSelectedRows()) {
+            sel.add(tableModel.getPrimitiveAt(tbl.convertRowIndexToModel(idx)));
+        }
+        return sel;
     }
     
@@ -180,5 +205,55 @@
                 autocomplete.populateWithTagValues(acList, tableModel.mainTags[i]);
                 tf.setAutoCompletionList(acList);
-                tbl.getColumnModel().getColumn(i).setCellEditor(tf);
+                tbl.getColumnModel().getColumn(i+1).setCellEditor(tf);
+        }
+    }
+
+    private JPopupMenu createPopupMenu() {
+        JPopupMenu menu = new JPopupMenu();
+        menu.add(new AbstractAction(tr("Remove tag"), ImageProvider.get("dialogs", "delete")){
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                tableModel.setAutoCommit(false);
+                for (int c: tbl.getSelectedColumns()) {
+                    for (int r: tbl.getSelectedRows()) {
+                        tableModel.setValueAt("", tbl.convertRowIndexToModel(r), tbl.convertColumnIndexToModel(c));
+                    }
+                }
+                tableModel.commit(tr("Delete tags from multiple objects"));
+                tableModel.setAutoCommit(true);
+            }
+        });
+        menu.add(new AbstractAction(tr("Duplicate tags from the first"), ImageProvider.get("copy")){
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                tableModel.setAutoCommit(false);
+                for (int c: tbl.getSelectedColumns()) {
+                    if (c==0 || tableModel.isSpecialTag[c-1]) continue;
+                    boolean first = true;
+                    String value = "";
+                    for (int r: tbl.getSelectedRows()) {
+                        if (first) {
+                            value = (String) tableModel.getValueAt(tbl.convertRowIndexToModel(r), tbl.convertColumnIndexToModel(c));
+                        }
+                        first=false;
+                        tableModel.setValueAt(value, tbl.convertRowIndexToModel(r), tbl.convertColumnIndexToModel(c));
+                    }
+                }
+                tableModel.commit(tr("Set tags for multiple objects"));
+                tableModel.setAutoCommit(true);
+            }
+        });
+        return menu;
+    }
+
+    private static class PrimitiveTypeIconRenderer extends DefaultTableCellRenderer {
+        @Override
+        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+            Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+            if (c instanceof JLabel) {
+                ((JLabel) c).setIcon(ImageProvider.get((OsmPrimitiveType) value));
+                ((JLabel) c).setText("");
+            }
+            return c;
         }
     }
@@ -192,16 +267,12 @@
         @Override
         public void actionPerformed(ActionEvent e) {
-            String txt = tagSetSelector.getText();
+            String txt = cbTagSet.getText();
             System.out.println(txt);
-            List<String> history = tagSetSelector.getHistory();
+            List<String> history = cbTagSet.getHistory();
             history.remove(txt);
             if (history.isEmpty()) {
                 history = Arrays.asList(defaultHistory);
             }
-                
             Main.pref.putCollection(HISTORY_KEY, history);
-            if (!history.isEmpty()) {
-                LAST_TAGS.put(history.get(0));
-            } 
             loadHistory();
         }
@@ -227,5 +298,5 @@
         public void itemStateChanged(ItemEvent e) {
             // skip text-changing enevts, we need only combobox-selecting ones
-            if (tagSetSelector.getSelectedIndex()<0) return;
+            if (cbTagSet.getSelectedIndex()<0) return;
             actionPerformed(null);
         }
@@ -233,23 +304,27 @@
         @Override
         public void actionPerformed(ActionEvent e) {
-            String s = tagSetSelector.getText();
+            String s = cbTagSet.getText();
             if (s==null || s.isEmpty() || s.equals(oldTags)) return;
             oldTags = s;
-            Main.info("Multitagger tags="+s);
-            tagSetSelector.addCurrentItemToHistory();
-            Main.pref.putCollection(HISTORY_KEY, tagSetSelector.getHistory());
-            LAST_TAGS.put(tagSetSelector.getText());
-
-            tableModel.setupColumnsFromText(s);
-           
-            tbl.createDefaultColumnsFromModel();
-            tbl.setAutoCreateRowSorter(true);
-            for (int i=0; i<tableModel.getColumnCount(); i++) {
-                TableHelper.adjustColumnWidth(tbl, i, 100);
-            }
-            initAutocompletion();
-            tableModel.fireTableDataChanged();
-        }
+            cbTagSet.addCurrentItemToHistory();
+            Main.pref.putCollection(HISTORY_KEY, cbTagSet.getHistory());
+            specifyTagSet(s);
+        }
+
     };
     
+    private void specifyTagSet(String s) {
+        Main.info("Multitagger tags="+s);
+        tableModel.setupColumnsFromText(s);
+
+        tbl.createDefaultColumnsFromModel();
+        tbl.setAutoCreateRowSorter(true);
+
+        tbl.getColumnModel().getColumn(0).setMaxWidth(20);
+        for (int i=1; i<tableModel.getColumnCount(); i++) {
+            TableHelper.adjustColumnWidth(tbl, i, 100);
+        }
+        initAutocompletion();
+        tableModel.fireTableDataChanged();
+    }    
 }
Index: applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/multitagger/MultiTaggerTableModel.java
===================================================================
--- applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/multitagger/MultiTaggerTableModel.java	(revision 30343)
+++ applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/multitagger/MultiTaggerTableModel.java	(revision 30370)
@@ -3,11 +3,16 @@
 package org.openstreetmap.josm.plugins.utilsplugin2.multitagger;
 
-import static org.openstreetmap.josm.tools.I18n.tr;
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
 import javax.swing.table.AbstractTableModel;
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.command.ChangePropertyCommand;
+import org.openstreetmap.josm.command.Command;
+import org.openstreetmap.josm.command.SequenceCommand;
 import org.openstreetmap.josm.data.SelectionChangedListener;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -24,5 +29,11 @@
     String mainTags[] = new String[]{};
     boolean isSpecialTag[] = new boolean[]{};
+    Set<OsmPrimitiveType> shownTypes = new HashSet<OsmPrimitiveType>();
+    private boolean autoCommit = true;
+    List<Command> cmds = new ArrayList<Command>();
 
+    public MultiTaggerTableModel() {
+        Collections.addAll(shownTypes, OsmPrimitiveType.values());
+    }
     
     @Override
@@ -33,23 +44,26 @@
     @Override
     public int getColumnCount() {
-        return mainTags.length;
+        return mainTags.length+1;
     }
 
     @Override
     public Object getValueAt(int rowIndex, int columnIndex) {
-        if (!isSpecialTag[columnIndex]) {
-            return list.get(rowIndex).get(mainTags[columnIndex]);
+        if (columnIndex==0) {
+            return list.get(rowIndex).getDisplayType();
         }
-        String var = mainTags[columnIndex];
+        if (!isSpecialTag[columnIndex-1]) {
+            return list.get(rowIndex).get(mainTags[columnIndex-1]);
+        }
+        String var = mainTags[columnIndex-1];
         OsmPrimitive p = list.get(rowIndex);
         if (var.equals("id")) {
             return String.valueOf(p.getUniqueId());
         } else if (var.equals("type")) {
-            return OsmPrimitiveType.from(p).toString().substring(0,1);
+            return OsmPrimitiveType.from(p).getAPIName().substring(0,1).toUpperCase();
         } else if (var.equals("area")) {
-            if (p.getType() == OsmPrimitiveType.CLOSEDWAY) {
+            if (p.getDisplayType() == OsmPrimitiveType.CLOSEDWAY) {
                 return String.format("%.1f", Geometry.closedWayArea((Way) p));
             } else {
-                return tr("not closed");
+                return "";
             }
         } else if (var.equals("length")) {
@@ -63,31 +77,40 @@
     @Override
     public Class<?> getColumnClass(int columnIndex) {
-        return String.class;
+        if (columnIndex==0) {
+            return OsmPrimitiveType.class;
+        } else {
+            return String.class;
+        }
     }
    
     @Override
     public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
-        Main.info("new selection: n="+newSelection.size());
-        list.clear();
-        list.addAll(newSelection);
-        fireTableDataChanged();
+        updateData(newSelection);
     }
 
     @Override
     public boolean isCellEditable(int rowIndex, int columnIndex) {
-        return !isSpecialTag[columnIndex];
+        if (columnIndex==0) return false;
+        return !isSpecialTag[columnIndex-1];
     }
 
     @Override
     public void setValueAt(Object value, int rowIndex, int columnIndex) {
-        if (isSpecialTag[columnIndex]) return;
+        if (columnIndex==0 || isSpecialTag[columnIndex-1]) return;
         if (columnIndex >= getColumnCount() || rowIndex >= getRowCount()) return;
+        if (value==null) value="";
         String val = ((String) value).trim();
         OsmPrimitive sel = list.get(rowIndex);
-        String key = mainTags[columnIndex];
+        String key = mainTags[columnIndex-1];
         String newValue = sel.get(key);
         if (newValue == null) newValue="";
         if (!val.equals(newValue)) {
-            Main.main.undoRedo.add(new ChangePropertyCommand(sel, key, (String) value));
+            Command cmd = new ChangePropertyCommand(sel, key, (String) value);
+            if (autoCommit) {
+                Main.main.undoRedo.add(cmd);
+            } else {
+                cmds.add(cmd);
+            }
+            
         }
     }
@@ -96,5 +119,6 @@
     @Override
     public String getColumnName(int column) {
-        return mainTags[column];
+        if (column==0) return "";
+        return mainTags[column-1];
     }
     
@@ -138,3 +162,22 @@
         return sb.toString();
     }
+
+    void updateData(Collection<? extends OsmPrimitive> sel) {
+        list.clear();
+        for (OsmPrimitive p : sel) {
+            if (shownTypes.contains(p.getDisplayType())) {
+                list.add(p);
+            }
+        }
+        fireTableDataChanged();
+    }
+
+    void setAutoCommit(boolean b) {
+        autoCommit = b;
+    }
+
+    void commit(String commandTitle) {
+        Main.main.undoRedo.add(new SequenceCommand(commandTitle, cmds));
+        cmds.clear();
+    }
 }
