Changeset 9743 in josm


Ignore:
Timestamp:
2016-02-06T14:52:34+01:00 (4 years ago)
Author:
bastiK
Message:

applied #12438 - hide items from list of recently added tags (patch by kolesar; minor changes)

Location:
trunk/src/org/openstreetmap/josm
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/preferences/ParametrizedEnumProperty.java

    r9689 r9743  
    66public abstract class ParametrizedEnumProperty<T extends Enum<T>> {
    77
    8     private final T defaultValue;
    9     private final Class<T> enumClass;
     8    protected final T defaultValue;
     9    protected final Class<T> enumClass;
    1010
    1111    public ParametrizedEnumProperty(Class<T> enumClass, T defaultValue) {
    1212        this.defaultValue = defaultValue;
    1313        this.enumClass = enumClass;
    14         if (Main.pref != null) {
    15             get();
    16         }
    1714    }
    1815
     
    2825
    2926    protected T parse(String s) {
    30         return Enum.valueOf(enumClass, s);
     27        try {
     28            return Enum.valueOf(enumClass, s);
     29        } catch (IllegalArgumentException e) {
     30            return defaultValue;
     31        }
    3132    }
    3233}
  • trunk/src/org/openstreetmap/josm/gui/dialogs/properties/TagEditHelper.java

    r9699 r9743  
    3939import java.util.List;
    4040import java.util.Map;
     41import java.util.TreeMap;
    4142
    4243import javax.swing.AbstractAction;
    4344import javax.swing.Action;
    4445import javax.swing.Box;
     46import javax.swing.ButtonGroup;
    4547import javax.swing.DefaultListCellRenderer;
    4648import javax.swing.ImageIcon;
     
    4951import javax.swing.JLabel;
    5052import javax.swing.JList;
     53import javax.swing.JMenu;
    5154import javax.swing.JOptionPane;
    5255import javax.swing.JPanel;
    5356import javax.swing.JPopupMenu;
     57import javax.swing.JRadioButtonMenuItem;
    5458import javax.swing.JTable;
    5559import javax.swing.KeyStroke;
     
    6670import org.openstreetmap.josm.data.osm.Tag;
    6771import org.openstreetmap.josm.data.preferences.BooleanProperty;
     72import org.openstreetmap.josm.data.preferences.EnumProperty;
    6873import org.openstreetmap.josm.data.preferences.IntegerProperty;
    6974import org.openstreetmap.josm.gui.ExtendedDialog;
     
    121126            DEFAULT_LRU_TAGS_NUMBER);
    122127
     128    /**
     129     * What to do with recent tags where keys already exist
     130     */
     131    private enum RecentExisting {
     132        ENABLE,
     133        DISABLE,
     134        HIDE
     135    }
     136
     137    /**
     138     * Preference setting for popup menu item "Recent tags with existing key"
     139     */
     140    public static final EnumProperty<RecentExisting> PROPERTY_RECENT_EXISTING = new EnumProperty<>(
     141        "properties.recently-added-tags-existing-key", RecentExisting.class, RecentExisting.DISABLE);
     142
     143    /**
     144     * What to do after applying tag
     145     */
     146    private enum RefreshRecent {
     147        NO,
     148        STATUS,
     149        REFRESH
     150    }
     151
     152    /**
     153     * Preference setting for popup menu item "Refresh recent tags list after applying tag"
     154     */
     155    public static final EnumProperty<RefreshRecent> PROPERTY_REFRESH_RECENT = new EnumProperty<>(
     156        "properties.refresh-recently-added-tags", RefreshRecent.class, RefreshRecent.STATUS);
     157
    123158    // LRU cache for recently added tags (http://java-planet.blogspot.com/2005/08/how-to-set-up-simple-lru-cache-using.html)
    124159    private final Map<Tag, Void> recentTags = new LinkedHashMap<Tag, Void>(MAX_LRU_TAGS_NUMBER+1, 1.1f, true) {
     
    129164    };
    130165
     166    // Copy of recently added tags, used to cache initial status
     167    private List<Tag> tags;
     168
     169    /**
     170     * Constructs a new {@code TagEditHelper}.
     171     * @param tagTable
     172     * @param propertyData
     173     * @param valueCount
     174     */
    131175    public TagEditHelper(JTable tagTable, DefaultTableModel propertyData, Map<String, Map<String, Integer>> valueCount) {
    132176        this.tagTable = tagTable;
     
    135179    }
    136180
     181    /**
     182     * Finds the key from given row of tag editor.
     183     * @param viewRow index of row
     184     * @return key of tag
     185     */
    137186    public final String getDataKey(int viewRow) {
    138187        return tagData.getValueAt(tagTable.convertRowIndexToModel(viewRow), 0).toString();
    139188    }
    140189
     190    /**
     191     * Finds the values from given row of tag editor.
     192     * @param viewRow index of row
     193     * @return map of values and number of occurrences
     194     */
    141195    @SuppressWarnings("unchecked")
    142196    public final Map<String, Integer> getDataValues(int viewRow) {
     
    212266    }
    213267
     268    /**
     269     * Reset last changed key.
     270     */
    214271    public void resetChangedKey() {
    215272        changedKey = null;
     
    257314            Main.pref.putCollection("properties.recent-tags", c);
    258315        }
     316    }
     317
     318    /**
     319     * Update cache of recent tags used for displaying tags.
     320     */
     321    private void cacheRecentTags() {
     322        tags = new LinkedList<>(recentTags.keySet());
    259323    }
    260324
     
    573637        private final List<JosmAction> recentTagsActions = new ArrayList<>();
    574638        protected final transient FocusAdapter focus;
     639        private JPanel mainPanel;
    575640        private JPanel recentTagsPanel;
    576641
     
    584649            configureContextsensitiveHelp("/Dialog/AddValue", true /* show help button */);
    585650
    586             final JPanel mainPanel = new JPanel(new GridBagLayout());
     651            mainPanel = new JPanel(new GridBagLayout());
    587652            keys = new AutoCompletingComboBox();
    588653            values = new AutoCompletingComboBox();
     
    641706                    public void actionPerformed(ActionEvent e) {
    642707                        performTagAdding();
     708                        refreshRecentTags();
    643709                        selectKeysComboBox();
    644710                    }
    645711                });
    646712
    647             suggestRecentlyAddedTags(mainPanel);
     713            cacheRecentTags();
     714            suggestRecentlyAddedTags();
    648715
    649716            mainPanel.add(Box.createVerticalGlue(), GBC.eop().fill());
     
    656723                public void actionPerformed(ActionEvent e) {
    657724                    selectNumberOfTags();
    658                     suggestRecentlyAddedTags(mainPanel);
     725                    suggestRecentlyAddedTags();
    659726                }
    660727            });
     728
     729            popupMenu.add(buildMenuRecentExisting());
     730            popupMenu.add(buildMenuRefreshRecent());
     731
    661732            JCheckBoxMenuItem rememberLastTags = new JCheckBoxMenuItem(
    662733                new AbstractAction(tr("Remember last used tags after a restart")) {
     
    673744        }
    674745
     746        private JMenu buildMenuRecentExisting() {
     747            JMenu menu = new JMenu(tr("Recent tags with existing key"));
     748            TreeMap<RecentExisting, String> radios = new TreeMap<>();
     749            radios.put(RecentExisting.ENABLE, tr("Enable"));
     750            radios.put(RecentExisting.DISABLE, tr("Disable"));
     751            radios.put(RecentExisting.HIDE, tr("Hide"));
     752            ButtonGroup buttonGroup = new ButtonGroup();
     753            for (final Map.Entry<RecentExisting, String> entry : radios.entrySet()) {
     754                JRadioButtonMenuItem radio = new JRadioButtonMenuItem(new AbstractAction(entry.getValue()) {
     755                    @Override
     756                    public void actionPerformed(ActionEvent e) {
     757                        PROPERTY_RECENT_EXISTING.put(entry.getKey());
     758                        suggestRecentlyAddedTags();
     759                    }
     760                });
     761                buttonGroup.add(radio);
     762                radio.setSelected(PROPERTY_RECENT_EXISTING.get() == entry.getKey());
     763                menu.add(radio);
     764            }
     765            return menu;
     766        }
     767
     768        private JMenu buildMenuRefreshRecent() {
     769            JMenu menu = new JMenu(tr("Refresh recent tags list after applying tag"));
     770            TreeMap<RefreshRecent, String> radios = new TreeMap<>();
     771            radios.put(RefreshRecent.NO, tr("No refresh"));
     772            radios.put(RefreshRecent.STATUS, tr("Refresh tag status only (enabled / disabled)"));
     773            radios.put(RefreshRecent.REFRESH, tr("Refresh tag status and list of recently added tags"));
     774            ButtonGroup buttonGroup = new ButtonGroup();
     775            for (final Map.Entry<RefreshRecent, String> entry : radios.entrySet()) {
     776                JRadioButtonMenuItem radio = new JRadioButtonMenuItem(new AbstractAction(entry.getValue()) {
     777                    @Override
     778                    public void actionPerformed(ActionEvent e) {
     779                        PROPERTY_REFRESH_RECENT.put(entry.getKey());
     780                    }
     781                });
     782                buttonGroup.add(radio);
     783                radio.setSelected(PROPERTY_REFRESH_RECENT.get() == entry.getKey());
     784                menu.add(radio);
     785            }
     786            return menu;
     787        }
     788
    675789        @Override
    676790        public void setContentPane(Container contentPane) {
     
    713827        }
    714828
    715         protected void suggestRecentlyAddedTags(JPanel mainPanel) {
    716 
     829        protected void suggestRecentlyAddedTags() {
    717830            if (recentTagsPanel == null) {
    718831                recentTagsPanel = new JPanel(new GridBagLayout());
    719                 suggestRecentlyAddedTags();
     832                buildRecentTagsPanel();
    720833                mainPanel.add(recentTagsPanel, GBC.eol().fill(GBC.HORIZONTAL));
    721834            } else {
    722835                Dimension panelOldSize = recentTagsPanel.getPreferredSize();
    723836                recentTagsPanel.removeAll();
    724                 suggestRecentlyAddedTags();
     837                buildRecentTagsPanel();
    725838                Dimension panelNewSize = recentTagsPanel.getPreferredSize();
    726839                Dimension dialogOldSize = getMinimumSize();
     
    734847        }
    735848
    736         protected void suggestRecentlyAddedTags() {
     849        protected void buildRecentTagsPanel() {
    737850            final int tagsToShow = Math.min(PROPERTY_RECENT_TAGS_NUMBER.get(), MAX_LRU_TAGS_NUMBER);
    738851            if (!(tagsToShow > 0 && !recentTags.isEmpty()))
     
    740853            recentTagsPanel.add(new JLabel(tr("Recently added tags")), GBC.eol());
    741854
    742             int count = 1;
     855            int count = 0;
     856            destroyActions();
    743857            // We store the maximum number of recent tags to allow dynamic change of number of tags shown in the preferences.
    744858            // This implies to iterate in descending order, as the oldest elements will only be removed after we reach the maximum
     
    746860            // However, as Set does not allow to iterate in descending order, we need to copy its elements into a List we can access
    747861            // in reverse order.
    748             List<Tag> tags = new LinkedList<>(recentTags.keySet());
    749             for (int i = tags.size()-1; i >= 0 && count <= tagsToShow; i--, count++) {
     862            for (int i = tags.size()-1; i >= 0 && count < tagsToShow; i--) {
    750863                final Tag t = tags.get(i);
     864                boolean keyExists = keyExists(t);
     865                if (keyExists && PROPERTY_RECENT_EXISTING.get() == RecentExisting.HIDE)
     866                    continue;
     867                count++;
    751868                // Create action for reusing the tag, with keyboard shortcut
    752869                /* POSSIBLE SHORTCUTS: 1,2,3,4,5,6,7,8,9,0=10 */
     
    773890                        action.actionPerformed(null);
    774891                        performTagAdding();
     892                        refreshRecentTags();
    775893                        selectKeysComboBox();
    776894                    }
     
    778896                recentTagsActions.add(action);
    779897                recentTagsActions.add(actionShift);
    780                 disableTagIfNeeded(t, action);
     898                if (keyExists && PROPERTY_RECENT_EXISTING.get() == RecentExisting.DISABLE) {
     899                    action.setEnabled(false);
     900                }
    781901                // Find and display icon
    782902                ImageIcon icon = MapPaintStyles.getNodeIcon(t, false); // Filters deprecated icon
     
    823943                        public void mouseClicked(MouseEvent e) {
    824944                            action.actionPerformed(null);
    825                             // add tags and close window on double-click
    826                             if (e.getClickCount() > 1) {
     945                            if (e.isShiftDown()) {
     946                                // add tags on Shift-Click
     947                                performTagAdding();
     948                                refreshRecentTags();
     949                                selectKeysComboBox();
     950                            } else if (e.getClickCount() > 1) {
     951                                // add tags and close window on double-click
    827952                                buttonAction(0, null); // emulate OK click and close the dialog
    828                             }
    829                             // add tags on Shift-Click
    830                             if (e.isShiftDown()) {
    831                                 performTagAdding();
    832                                 selectKeysComboBox();
    833953                            }
    834954                        }
     
    844964                tagPanel.add(tagLabel);
    845965                recentTagsPanel.add(tagPanel, GBC.eol().fill(GBC.HORIZONTAL));
     966            }
     967            // Clear label if no tags were added
     968            if (count == 0) {
     969                recentTagsPanel.removeAll();
    846970            }
    847971        }
     
    873997            lastAddValue = value;
    874998            recentTags.put(new Tag(key, value), null);
     999            valueCount.put(key, new TreeMap<String, Integer>());
    8751000            AutoCompletionManager.rememberUserInput(key, value, false);
    8761001            commandCount++;
     
    8891014        }
    8901015
    891         private void disableTagIfNeeded(final Tag t, final JosmAction action) {
    892             // Disable action if its key is already set on the object (the key being absent from the keys list for this reason
    893             // performing this action leads to autocomplete to the next key (see #7671 comments)
    894             for (int j = 0; j < tagData.getRowCount(); ++j) {
    895                 if (t.getKey().equals(getDataKey(j))) {
    896                     action.setEnabled(false);
    897                     break;
    898                 }
     1016        private boolean keyExists(final Tag t) {
     1017            return valueCount.containsKey(t.getKey());
     1018        }
     1019
     1020        private void refreshRecentTags() {
     1021            switch (PROPERTY_REFRESH_RECENT.get()) {
     1022                case REFRESH: cacheRecentTags(); // break missing intentionally
     1023                case STATUS: suggestRecentlyAddedTags();
    8991024            }
    9001025        }
Note: See TracChangeset for help on using the changeset viewer.