blob: 7171e044000c0696c83bb36bc045f1309ec137b6 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2014 TwelveTone LLC and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Steven Spungin <steven@spungin.tv> - initial API and implementation
*******************************************************************************/
package org.eclipse.e4.tools.emf.ui.internal.common;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Combo;
/**
*
* @author Steven Spungin
*
*/
public class Autocomplete {
public static void installOn(ComboViewer comboViewer) {
final Combo combo = comboViewer.getCombo();
combo.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent keyEvent) {
setClosestMatch(combo);
}
@Override
public void keyPressed(KeyEvent keyEvent) {
if (keyEvent.keyCode == SWT.BS) {
Point pt = combo.getSelection();
combo.setSelection(new Point(Math.max(0, pt.x - 1), pt.y));
}
}
});
combo.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
combo.setSelection(new Point(0, combo.getText().length()));
}
@Override
public void focusGained(FocusEvent e) {
combo.setSelection(new Point(0, combo.getText().length()));
}
});
combo.addMouseListener(new MouseAdapter() {
@Override
public void mouseUp(MouseEvent e) {
combo.setSelection(new Point(0, combo.getText().length()));
}
});
}
private static void setClosestMatch(Combo combo) {
String[] items = combo.getItems();
if (items.length == 0) {
return;
}
// TODO this would be faster using binary search if we could insure that
// the items are sorted in natural order.
String str = combo.getText();
Pattern pattern = Pattern.compile(str + ".*", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
int index = -1;
int length = 0;
for (int i = 0; i < items.length; i++) {
Matcher m = pattern.matcher(items[i]);
if (m.matches()) {
if (index == -1 || items[i].length() < length) {
length = items[i].length();
index = i;
}
}
}
if (index == -1) {
index = 0;
}
Point pt = combo.getSelection();
String selectedText = items[index];
combo.select(index);
combo.setText(selectedText);
combo.setSelection(new Point(pt.x, selectedText.length()));
}
}