Ticket #24516: 24516-ac-to-shortest-wip.patch

File 24516-ac-to-shortest-wip.patch, 4.4 KB (added by GerdP, 6 months ago)

Hack: if CTRL+< is pressed in autocompletion field suggest the next matching entry in alphabetical order

  • src/org/openstreetmap/josm/gui/tagging/ac/AutoCompComboBoxModel.java

     
    7575                           comparator.compare(x, y))
    7676            .orElse(null);
    7777    }
     78
     79    public Comparator<E> getComparator() {
     80        return comparator;
     81    }
    7882}
  • src/org/openstreetmap/josm/gui/tagging/ac/AutoCompTextField.java

     
    77import java.awt.datatransfer.Transferable;
    88import java.awt.event.KeyEvent;
    99import java.awt.event.KeyListener;
     10import java.util.Comparator;
    1011import java.util.EventObject;
    1112import java.util.regex.Pattern;
    1213
     
    146147     * list selection.
    147148     *
    148149     * @param oldText the text before the last keypress was processed
     150     * @param shortest if true, use only oldText
    149151     */
    150     private void autocomplete(String oldText) {
    151         String newText = getText();
    152         if (getSelectionEnd() != newText.length())
    153             // selection not at the end
    154             return;
    155         // if the user typed some control character (eg. Alt+A) the selection may still be there
    156         String unSelected = newText.substring(0, getSelectionStart());
    157         if (unSelected.length() <= oldText.length())
    158             // do not autocomplete on control or deleted chars
    159             return;
     152    private void autocomplete(String oldText, boolean shortest) {
     153        final String newText;
     154        if (shortest) {
     155            newText = oldText;
     156        } else {
     157            newText = getText();
     158            if (getSelectionEnd() != newText.length())
     159                // selection not at the end
     160                return;
     161            // if the user typed some control character (eg. Alt+A) the selection may still be there
     162            String unSelected = newText.substring(0, getSelectionStart());
     163            if (unSelected.length() <= oldText.length())
     164                // do not autocomplete on control or deleted chars
     165                return;
     166        }
    160167        if (getInputMethodRequests().getCommittedTextLength() != getDocument().getLength()) {
    161168            // do not autocomplete if there is uncommitted text (breaks Microsoft Japanese IME, see #21507)
    162169            return;
     
    180187    }
    181188
    182189    /**
     190     * Autocompletes what the user typed in.
     191     * <p>
     192     * Gets the user input from the editor, finds the best matching item in the model, sets the
     193     * editor text to it, and highlights the autocompleted part. If there is no matching item, removes the
     194     * list selection.
     195     *
     196     * @param oldText the text before the last keypress was processed
     197     */
     198    private void autocompleteToShortestMatch(String oldText) {
     199        AutoCompComboBoxModel<E> model = getModel();
     200        Comparator<E> oldComparator = model.getComparator();
     201        model.setComparator(Comparator.comparing(E::toString));
     202        autocomplete(oldText, true);
     203        model.setComparator(oldComparator);
     204
     205    }
     206
     207    /**
    183208     * Copies a String to the UNIX system-wide selection (aka middle-click).
    184209     *
    185210     * @param s the string to copy
     
    266291        if (autocompleteEnabled && getSelectionEnd() == getText().length()) {
    267292            final String oldText = getText().substring(0, getSelectionStart());
    268293            // We got the event before the editor component could see it. Let the editor do its job first.
    269             SwingUtilities.invokeLater(() -> autocomplete(oldText));
     294            SwingUtilities.invokeLater(() -> autocomplete(oldText, false));
    270295        }
    271296    }
    272297
    273298    @Override
    274299    public void keyPressed(KeyEvent e) {
    275         // not interested
     300        if (autocompleteEnabled && e.getModifiersEx() == KeyEvent.CTRL_DOWN_MASK
     301                && e.getKeyCode() == KeyEvent.VK_LESS) {
     302            final String oldText = getText().substring(0, getSelectionStart());
     303            // We got the event before the editor component could see it. Let the editor do its job first.
     304            SwingUtilities.invokeLater(() -> autocompleteToShortestMatch(oldText));
     305        }
    276306    }
    277307
    278308    @Override