Changeset 30370 in osm for applications/editors/josm


Ignore:
Timestamp:
2014-03-26T20:15:02+01:00 (11 years ago)
Author:
akks
Message:

[josm_utilsplugin2]: multitagger improvements

Location:
applications/editors/josm/plugins/utilsplugin2
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/utilsplugin2/build.xml

    r30337 r30370  
    33
    44    <!-- enter the SVN commit message -->
    5     <property name="commit.message" value="[josm_utilsplugin2]: alpha version of multitagger ctrl-t"/>
     5    <property name="commit.message" value="[josm_utilsplugin2]: multitagger improvements"/>
    66    <!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
    77    <property name="plugin.main.version" value="6317"/>
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/multitagger/MultiTagDialog.java

    r30337 r30370  
    55import java.awt.GridBagLayout;
    66import java.awt.event.ActionEvent;
     7import java.awt.event.ActionListener;
    78import java.awt.event.ItemEvent;
    89import java.awt.event.ItemListener;
     
    1011import java.awt.event.MouseAdapter;
    1112import java.awt.event.MouseEvent;
     13import java.util.ArrayList;
    1214import java.util.Arrays;
    1315import java.util.Collection;
    1416import java.util.Collections;
    15 import java.util.EventObject;
    1617import java.util.LinkedList;
    1718import java.util.List;
    1819import javax.swing.AbstractAction;
    1920import static javax.swing.Action.SHORT_DESCRIPTION;
     21import javax.swing.BoxLayout;
    2022import javax.swing.JButton;
    2123import javax.swing.JComponent;
     24import javax.swing.JLabel;
    2225import javax.swing.JPanel;
     26import javax.swing.JPopupMenu;
    2327import javax.swing.JScrollPane;
    2428import javax.swing.JTable;
     29import javax.swing.JToggleButton;
    2530import javax.swing.KeyStroke;
    2631import javax.swing.ListSelectionModel;
    27 import javax.swing.event.CellEditorListener;
     32import javax.swing.SwingUtilities;
    2833import javax.swing.event.ListSelectionEvent;
    2934import javax.swing.event.ListSelectionListener;
    30 import javax.swing.table.TableCellEditor;
     35import javax.swing.table.DefaultTableCellRenderer;
    3136import org.openstreetmap.josm.Main;
    3237import org.openstreetmap.josm.actions.AutoScaleAction;
     
    3439import org.openstreetmap.josm.data.SelectionChangedListener;
    3540import org.openstreetmap.josm.data.osm.OsmPrimitive;
     41import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
    3642import org.openstreetmap.josm.data.preferences.StringProperty;
    3743import org.openstreetmap.josm.gui.ExtendedDialog;
     
    4147import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionList;
    4248import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionManager;
     49import org.openstreetmap.josm.gui.util.GuiHelper;
    4350import org.openstreetmap.josm.gui.util.HighlightHelper;
    4451import org.openstreetmap.josm.gui.util.TableHelper;
    4552import org.openstreetmap.josm.gui.widgets.HistoryComboBox;
     53import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
    4654import org.openstreetmap.josm.tools.GBC;
    4755import static org.openstreetmap.josm.tools.I18n.tr;
     
    5563
    5664    private final MultiTaggerTableModel tableModel = new MultiTaggerTableModel();
    57     private final JTable tbl = new JTable(tableModel);
     65    private final JTable tbl;
    5866    //
    5967    private final HighlightHelper highlightHelper = new HighlightHelper();
    60     private final HistoryComboBox tagSetSelector = new HistoryComboBox();
     68    private final HistoryComboBox cbTagSet = new HistoryComboBox();
    6169   
    6270    private static final String HISTORY_KEY = "utilsplugin2.multitaghistory";
    63     String defaultHistory[] = {"addr:street, addr:housenumber, building",
    64         "highway, name, ${id}, ${length}, ${type}",
     71    String defaultHistory[] = {"addr:street, addr:housenumber, building, ${area}",
     72        "highway, name, ${id}, ${length}",
    6573        "name name:en name:ru name:de"};
    66     private final StringProperty LAST_TAGS = new StringProperty("utilsplugin2.multitag.last", defaultHistory[0]);
    6774    TagCellEditor cellEditor;
    6875   
    69            
     76   
    7077    public MultiTagDialog() {
    7178        super(Main.parent,  tr("Edit tags"), new String[]{tr("Ok"), tr("Cancel")}, false);
    7279        JPanel pnl = new JPanel(new GridBagLayout());
    73         tbl.setFillsViewportHeight(true);
    74         tbl.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    75         tbl.addMouseListener(tableMouseAdapter);
    76         tbl.setRowSelectionAllowed(true);
    77         tbl.setColumnSelectionAllowed(true);
    78         tbl.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
    79         loadHistory();
    80        
    81         tagSetSelector.addItemListener(tagSetChanger);
    82         tagSetSelector.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
     80        tbl = createTable();
     81       
     82        cbTagSet.addItemListener(tagSetChanger);
     83        cbTagSet.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
    8384           .put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, true), "applyTagSet");
    84         tagSetSelector.getActionMap().put("applyTagSet", tagSetChanger);
    85        
    86         tagSetChanger.itemStateChanged(null);
    87         pnl.add(tagSetSelector,GBC.std().fill(GBC.HORIZONTAL));
     85        cbTagSet.getActionMap().put("applyTagSet", tagSetChanger);
     86       
     87        tbl.addMouseListener(new PopupMenuLauncher(createPopupMenu()));
     88       
     89        pnl.add(cbTagSet,GBC.std().fill(GBC.HORIZONTAL));
    8890        pnl.add(new JButton(new DeleteFromHistoryAction()),GBC.std());
    8991        pnl.add(new JButton(new FindMatchingAction()),GBC.eol());
     92        pnl.add(createTypeFilterPanel(), GBC.eol().fill(GBC.HORIZONTAL));
    9093        pnl.add(tbl.getTableHeader(),GBC.eop().fill(GBC.HORIZONTAL));
    91 
     94       
    9295        pnl.add(new JScrollPane(tbl), GBC.eol().fill(GBC.BOTH));
    93         tbl.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
    94         tbl.getSelectionModel().addListSelectionListener(selectionListener);
    9596        setContent(pnl);
    9697        setDefaultButton(-1);
     98        loadHistory();
    9799       
    98100        WindowGeometry defaultGeometry = WindowGeometry.centerInWindow(Main.parent, new Dimension(500, 500));
    99101        setRememberWindowGeometry(getClass().getName() + ".geometry", defaultGeometry);
    100        
    101 
     102    }
     103
     104    private JTable createTable() {
     105        JTable t = new JTable(tableModel);
     106        t.setFillsViewportHeight(true);
     107        t.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
     108        t.addMouseListener(tableMouseAdapter);
     109        t.setRowSelectionAllowed(true);
     110        t.setColumnSelectionAllowed(true);
     111        t.setDefaultRenderer(OsmPrimitiveType.class, new PrimitiveTypeIconRenderer());
     112        t.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
     113        t.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
     114        t.getSelectionModel().addListSelectionListener(selectionListener);
     115        return t;
     116    }
     117
     118    private JPanel createTypeFilterPanel() {
     119        JPanel p = new JPanel();
     120        p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
     121        for (final OsmPrimitiveType type: OsmPrimitiveType.values()) {
     122            final JToggleButton jt = new JToggleButton("", ImageProvider.get(type), true);
     123            jt.addActionListener(new ActionListener(){
     124                @Override
     125                public void actionPerformed(ActionEvent e) {
     126                    if (jt.isSelected()) tableModel.shownTypes.add(type); else tableModel.shownTypes.remove(type);
     127                    tableModel.updateData(Main.main.getCurrentDataSet().getSelected());
     128                };
     129            });
     130            ImageProvider.get(type);
     131            p.add(jt);
     132        }
     133        return p;
    102134    }
    103135
     
    106138                Main.pref.getCollection(HISTORY_KEY, Arrays.asList(defaultHistory)));
    107139        Collections.reverse(cmtHistory);
    108         tagSetSelector.setPossibleItems(cmtHistory);
    109         tagSetSelector.setText(LAST_TAGS.get());
     140        cbTagSet.setPossibleItems(cmtHistory);
     141        String s = cmtHistory.get(cmtHistory.size()-1);
     142        cbTagSet.setText(s);
     143        specifyTagSet(s);
    110144    }
    111145
     
    131165    }
    132166   
    133     private final MouseAdapter tableMouseAdapter = new MouseAdapter() {
     167   private final MouseAdapter tableMouseAdapter = new MouseAdapter() {
    134168        @Override
    135169        public void mouseClicked(MouseEvent e) {
     
    143177        @Override
    144178        public void valueChanged(ListSelectionEvent e) {
    145             OsmPrimitive p = getSelectedPrimitive();
    146             if (p != null && Main.isDisplayingMapView() ) {
    147                 if (highlightHelper.highlightOnly(p)) {
     179            List<OsmPrimitive> prims = getSelectedPrimitives();
     180            if (prims != null && Main.isDisplayingMapView() ) {
     181                if (highlightHelper.highlightOnly(prims)) {
    148182                    Main.map.mapView.repaint();
    149183                }
     
    152186    };
    153187   
    154     public void setAutoCompletion(boolean enable){
    155         if (!enable) {
    156            
    157         }
    158            
    159         OsmDataLayer l = Main.main.getEditLayer();
    160         AutoCompletionManager autocomplete = l.data.getAutoCompletionManager();
    161         AutoCompletionList acList = new AutoCompletionList();
    162          
    163 //        TagCellEditor editor = ((TagCellEditor) tagTable.getColumnModel().getColumn(0).getCellEditor());
    164 //        editor.setAutoCompletionManager(autocomplete);
    165 //        editor.setAutoCompletionList(acList);
    166 //        editor = ((TagCellEditor) tagTable.getColumnModel().getColumn(1).getCellEditor());
    167 //        editor.setAutoCompletionManager(autocomplete);
    168 //        editor.setAutoCompletionList(acList);
     188    public List<OsmPrimitive> getSelectedPrimitives() {
     189        ArrayList<OsmPrimitive> sel = new ArrayList<OsmPrimitive>(100);
     190        for (int idx: tbl.getSelectedRows()) {
     191            sel.add(tableModel.getPrimitiveAt(tbl.convertRowIndexToModel(idx)));
     192        }
     193        return sel;
    169194    }
    170195   
     
    180205                autocomplete.populateWithTagValues(acList, tableModel.mainTags[i]);
    181206                tf.setAutoCompletionList(acList);
    182                 tbl.getColumnModel().getColumn(i).setCellEditor(tf);
     207                tbl.getColumnModel().getColumn(i+1).setCellEditor(tf);
     208        }
     209    }
     210
     211    private JPopupMenu createPopupMenu() {
     212        JPopupMenu menu = new JPopupMenu();
     213        menu.add(new AbstractAction(tr("Remove tag"), ImageProvider.get("dialogs", "delete")){
     214            @Override
     215            public void actionPerformed(ActionEvent e) {
     216                tableModel.setAutoCommit(false);
     217                for (int c: tbl.getSelectedColumns()) {
     218                    for (int r: tbl.getSelectedRows()) {
     219                        tableModel.setValueAt("", tbl.convertRowIndexToModel(r), tbl.convertColumnIndexToModel(c));
     220                    }
     221                }
     222                tableModel.commit(tr("Delete tags from multiple objects"));
     223                tableModel.setAutoCommit(true);
     224            }
     225        });
     226        menu.add(new AbstractAction(tr("Duplicate tags from the first"), ImageProvider.get("copy")){
     227            @Override
     228            public void actionPerformed(ActionEvent e) {
     229                tableModel.setAutoCommit(false);
     230                for (int c: tbl.getSelectedColumns()) {
     231                    if (c==0 || tableModel.isSpecialTag[c-1]) continue;
     232                    boolean first = true;
     233                    String value = "";
     234                    for (int r: tbl.getSelectedRows()) {
     235                        if (first) {
     236                            value = (String) tableModel.getValueAt(tbl.convertRowIndexToModel(r), tbl.convertColumnIndexToModel(c));
     237                        }
     238                        first=false;
     239                        tableModel.setValueAt(value, tbl.convertRowIndexToModel(r), tbl.convertColumnIndexToModel(c));
     240                    }
     241                }
     242                tableModel.commit(tr("Set tags for multiple objects"));
     243                tableModel.setAutoCommit(true);
     244            }
     245        });
     246        return menu;
     247    }
     248
     249    private static class PrimitiveTypeIconRenderer extends DefaultTableCellRenderer {
     250        @Override
     251        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
     252            Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
     253            if (c instanceof JLabel) {
     254                ((JLabel) c).setIcon(ImageProvider.get((OsmPrimitiveType) value));
     255                ((JLabel) c).setText("");
     256            }
     257            return c;
    183258        }
    184259    }
     
    192267        @Override
    193268        public void actionPerformed(ActionEvent e) {
    194             String txt = tagSetSelector.getText();
     269            String txt = cbTagSet.getText();
    195270            System.out.println(txt);
    196             List<String> history = tagSetSelector.getHistory();
     271            List<String> history = cbTagSet.getHistory();
    197272            history.remove(txt);
    198273            if (history.isEmpty()) {
    199274                history = Arrays.asList(defaultHistory);
    200275            }
    201                
    202276            Main.pref.putCollection(HISTORY_KEY, history);
    203             if (!history.isEmpty()) {
    204                 LAST_TAGS.put(history.get(0));
    205             }
    206277            loadHistory();
    207278        }
     
    227298        public void itemStateChanged(ItemEvent e) {
    228299            // skip text-changing enevts, we need only combobox-selecting ones
    229             if (tagSetSelector.getSelectedIndex()<0) return;
     300            if (cbTagSet.getSelectedIndex()<0) return;
    230301            actionPerformed(null);
    231302        }
     
    233304        @Override
    234305        public void actionPerformed(ActionEvent e) {
    235             String s = tagSetSelector.getText();
     306            String s = cbTagSet.getText();
    236307            if (s==null || s.isEmpty() || s.equals(oldTags)) return;
    237308            oldTags = s;
    238             Main.info("Multitagger tags="+s);
    239             tagSetSelector.addCurrentItemToHistory();
    240             Main.pref.putCollection(HISTORY_KEY, tagSetSelector.getHistory());
    241             LAST_TAGS.put(tagSetSelector.getText());
    242 
    243             tableModel.setupColumnsFromText(s);
    244            
    245             tbl.createDefaultColumnsFromModel();
    246             tbl.setAutoCreateRowSorter(true);
    247             for (int i=0; i<tableModel.getColumnCount(); i++) {
    248                 TableHelper.adjustColumnWidth(tbl, i, 100);
    249             }
    250             initAutocompletion();
    251             tableModel.fireTableDataChanged();
    252         }
     309            cbTagSet.addCurrentItemToHistory();
     310            Main.pref.putCollection(HISTORY_KEY, cbTagSet.getHistory());
     311            specifyTagSet(s);
     312        }
     313
    253314    };
    254315   
     316    private void specifyTagSet(String s) {
     317        Main.info("Multitagger tags="+s);
     318        tableModel.setupColumnsFromText(s);
     319
     320        tbl.createDefaultColumnsFromModel();
     321        tbl.setAutoCreateRowSorter(true);
     322
     323        tbl.getColumnModel().getColumn(0).setMaxWidth(20);
     324        for (int i=1; i<tableModel.getColumnCount(); i++) {
     325            TableHelper.adjustColumnWidth(tbl, i, 100);
     326        }
     327        initAutocompletion();
     328        tableModel.fireTableDataChanged();
     329    }   
    255330}
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/multitagger/MultiTaggerTableModel.java

    r30337 r30370  
    33package org.openstreetmap.josm.plugins.utilsplugin2.multitagger;
    44
    5 import static org.openstreetmap.josm.tools.I18n.tr;
    65
    76import java.util.ArrayList;
    87import java.util.Collection;
     8import java.util.Collections;
     9import java.util.HashSet;
     10import java.util.List;
     11import java.util.Set;
    912import javax.swing.table.AbstractTableModel;
    1013import org.openstreetmap.josm.Main;
    1114import org.openstreetmap.josm.command.ChangePropertyCommand;
     15import org.openstreetmap.josm.command.Command;
     16import org.openstreetmap.josm.command.SequenceCommand;
    1217import org.openstreetmap.josm.data.SelectionChangedListener;
    1318import org.openstreetmap.josm.data.osm.OsmPrimitive;
     
    2429    String mainTags[] = new String[]{};
    2530    boolean isSpecialTag[] = new boolean[]{};
     31    Set<OsmPrimitiveType> shownTypes = new HashSet<OsmPrimitiveType>();
     32    private boolean autoCommit = true;
     33    List<Command> cmds = new ArrayList<Command>();
    2634
     35    public MultiTaggerTableModel() {
     36        Collections.addAll(shownTypes, OsmPrimitiveType.values());
     37    }
    2738   
    2839    @Override
     
    3344    @Override
    3445    public int getColumnCount() {
    35         return mainTags.length;
     46        return mainTags.length+1;
    3647    }
    3748
    3849    @Override
    3950    public Object getValueAt(int rowIndex, int columnIndex) {
    40         if (!isSpecialTag[columnIndex]) {
    41             return list.get(rowIndex).get(mainTags[columnIndex]);
     51        if (columnIndex==0) {
     52            return list.get(rowIndex).getDisplayType();
    4253        }
    43         String var = mainTags[columnIndex];
     54        if (!isSpecialTag[columnIndex-1]) {
     55            return list.get(rowIndex).get(mainTags[columnIndex-1]);
     56        }
     57        String var = mainTags[columnIndex-1];
    4458        OsmPrimitive p = list.get(rowIndex);
    4559        if (var.equals("id")) {
    4660            return String.valueOf(p.getUniqueId());
    4761        } else if (var.equals("type")) {
    48             return OsmPrimitiveType.from(p).toString().substring(0,1);
     62            return OsmPrimitiveType.from(p).getAPIName().substring(0,1).toUpperCase();
    4963        } else if (var.equals("area")) {
    50             if (p.getType() == OsmPrimitiveType.CLOSEDWAY) {
     64            if (p.getDisplayType() == OsmPrimitiveType.CLOSEDWAY) {
    5165                return String.format("%.1f", Geometry.closedWayArea((Way) p));
    5266            } else {
    53                 return tr("not closed");
     67                return "";
    5468            }
    5569        } else if (var.equals("length")) {
     
    6377    @Override
    6478    public Class<?> getColumnClass(int columnIndex) {
    65         return String.class;
     79        if (columnIndex==0) {
     80            return OsmPrimitiveType.class;
     81        } else {
     82            return String.class;
     83        }
    6684    }
    6785   
    6886    @Override
    6987    public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
    70         Main.info("new selection: n="+newSelection.size());
    71         list.clear();
    72         list.addAll(newSelection);
    73         fireTableDataChanged();
     88        updateData(newSelection);
    7489    }
    7590
    7691    @Override
    7792    public boolean isCellEditable(int rowIndex, int columnIndex) {
    78         return !isSpecialTag[columnIndex];
     93        if (columnIndex==0) return false;
     94        return !isSpecialTag[columnIndex-1];
    7995    }
    8096
    8197    @Override
    8298    public void setValueAt(Object value, int rowIndex, int columnIndex) {
    83         if (isSpecialTag[columnIndex]) return;
     99        if (columnIndex==0 || isSpecialTag[columnIndex-1]) return;
    84100        if (columnIndex >= getColumnCount() || rowIndex >= getRowCount()) return;
     101        if (value==null) value="";
    85102        String val = ((String) value).trim();
    86103        OsmPrimitive sel = list.get(rowIndex);
    87         String key = mainTags[columnIndex];
     104        String key = mainTags[columnIndex-1];
    88105        String newValue = sel.get(key);
    89106        if (newValue == null) newValue="";
    90107        if (!val.equals(newValue)) {
    91             Main.main.undoRedo.add(new ChangePropertyCommand(sel, key, (String) value));
     108            Command cmd = new ChangePropertyCommand(sel, key, (String) value);
     109            if (autoCommit) {
     110                Main.main.undoRedo.add(cmd);
     111            } else {
     112                cmds.add(cmd);
     113            }
     114           
    92115        }
    93116    }
     
    96119    @Override
    97120    public String getColumnName(int column) {
    98         return mainTags[column];
     121        if (column==0) return "";
     122        return mainTags[column-1];
    99123    }
    100124   
     
    138162        return sb.toString();
    139163    }
     164
     165    void updateData(Collection<? extends OsmPrimitive> sel) {
     166        list.clear();
     167        for (OsmPrimitive p : sel) {
     168            if (shownTypes.contains(p.getDisplayType())) {
     169                list.add(p);
     170            }
     171        }
     172        fireTableDataChanged();
     173    }
     174
     175    void setAutoCommit(boolean b) {
     176        autoCommit = b;
     177    }
     178
     179    void commit(String commandTitle) {
     180        Main.main.undoRedo.add(new SequenceCommand(commandTitle, cmds));
     181        cmds.clear();
     182    }
    140183}
Note: See TracChangeset for help on using the changeset viewer.