package org.openlca.app.components; import org.eclipse.jface.dialogs.PopupDialog; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IContentProvider; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ListViewer; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TextCellEditor; import org.eclipse.jface.viewers.ViewerSorter; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Text; import org.openlca.app.viewers.BaseLabelProvider; import org.openlca.app.viewers.BaseNameSorter; public abstract class AutoCompleteTextCellEditor extends TextCellEditor { private final int column; private Object editedElement; private String popupTitle; private boolean strgPressed = false; private TableViewer viewer; protected Text text; public AutoCompleteTextCellEditor( TableViewer viewer, int column, String popupTitle) { super(viewer.getTable(), SWT.SINGLE); this.viewer = viewer; this.column = column; this.popupTitle = popupTitle; } private void openContentAssistent() { int cursorPosition = text.getCaretPosition(); boolean cursorIsAtBeginningOfSelection = false; String temp = text.getText() == null ? "" : text.getText(); if (text.getSelectionCount() > 0) { // delete selected text in String oldText boolean deleted = false; final String selectedText = text.getSelectionText(); if (temp.length() >= selectedText.length() + cursorPosition) { if (temp.substring(cursorPosition, cursorPosition + selectedText.length()).equals( selectedText)) { cursorIsAtBeginningOfSelection = true; if (cursorPosition > 0) { temp = temp.substring(0, cursorPosition) + temp.substring(cursorPosition + selectedText.length()); } else { temp = temp.substring(cursorPosition + selectedText.length()); } deleted = true; } } if (!deleted) { if (cursorPosition <= temp.length()) { temp = temp.substring(0, cursorPosition - selectedText.length()) + temp.substring(cursorPosition); } else { temp = temp.substring(0, cursorPosition - selectedText.length()); } } } final String oldText = temp; if (!cursorIsAtBeginningOfSelection) { cursorPosition -= text.getSelectionCount(); } final int oldCursorPosition = cursorPosition; // create content assistant final PopupDialog p = new PopupDialog(text.getShell(), SWT.NONE, true, true, true, false, false, popupTitle, null) { @Override protected Control createDialogArea(final Composite parent) { editedElement = ((IStructuredSelection) viewer.getSelection()) .getFirstElement(); // create body final Composite c = (Composite) super.createDialogArea(parent); c.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); c.setLayout(new GridLayout()); // create content list final ListViewer list = new ListViewer(c, getInput().length < 10 ? SWT.SINGLE : SWT.SINGLE | SWT.V_SCROLL); list.setContentProvider(getContentProvider()); list.setLabelProvider(getLabelProvider()); list.setSorter(getSorter()); list.getList().setLayoutData( new GridData(SWT.FILL, SWT.FILL, true, true)); list.setInput(getInput()); list.getList().select(0); // add double click listener list.addDoubleClickListener(new IDoubleClickListener() { @Override public void doubleClick(final DoubleClickEvent event) { if (!list.getSelection().isEmpty()) { selectionOccured(((IStructuredSelection) list .getSelection()).getFirstElement(), oldText, oldCursorPosition, editedElement); close(); } } }); // add key listener list.getList().addKeyListener(new KeyAdapter() { @Override public void keyPressed(final KeyEvent e) { if (e.keyCode == 13) { // enter pressed if (!list.getSelection().isEmpty()) { selectionOccured(((IStructuredSelection) list .getSelection()).getFirstElement(), oldText, oldCursorPosition, editedElement); close(); } } } }); return c; } @Override protected Point getInitialLocation(final Point initialSize) { final Point location = text.toDisplay(viewer.getTable() .getLocation()); location.y += text.getSize().y; return location; } @Override protected Point getInitialSize() { return new Point(400, getInput().length < 10 ? getInput().length * 15 + 33 : 183); } }; p.open(); } /** * Adds the selected objects text to the original text of the widget * * @param selectedElement * the object which was selected * @param oldText * the old widget text * @param oldCursorPosition * the old cursor position in the text widget * @param editedElement * The element being edited */ private void selectionOccured(final Object selectedElement, final String oldText, final int oldCursorPosition, final Object editedElement) { final String additionalText = getTextFromListElement(selectedElement); viewer.editElement(editedElement, column); String newText = ""; if (oldText.length() > 0) { newText = oldText.substring(0, oldCursorPosition); } newText += additionalText; if (oldText.length() > oldCursorPosition) { newText += oldText.substring(oldCursorPosition); } text.setText(newText); text.setSelection(oldCursorPosition + additionalText.length()); } @Override protected Control createControl(final Composite parent) { text = (Text) super.createControl(parent); text.addKeyListener(new KeyListener() { @Override public void keyPressed(final KeyEvent e) { if (e.keyCode == 262144) { strgPressed = true; } if (e.keyCode == 32 && strgPressed) { strgPressed = false; openContentAssistent(); } } @Override public void keyReleased(final KeyEvent e) { if (e.keyCode == 262144) { strgPressed = false; } } }); return text; } @Override protected boolean dependsOnExternalFocusListener() { return getClass() != AutoCompleteTextCellEditor.class; } /** * Getter of the content provider * * @return the content provider for the content assistance element list */ protected IContentProvider getContentProvider() { return new ArrayContentProvider(); } /** * Getter of the input of the content assistance element list * * @return the input of the content assistance element list as array of * objects */ protected abstract Object[] getInput(); /** * Getter of the label provider * * @return The label provider of the content assistance element list */ protected ILabelProvider getLabelProvider() { return new BaseLabelProvider(); } /** * Getter of the sorter * * @return the sorter for the content assistance element list */ protected ViewerSorter getSorter() { return new BaseNameSorter(); } /** * Converts an element of the content list to a String * * @param element * the list element * @return the string for the list element */ protected abstract String getTextFromListElement(Object element); @Override public void dispose() { super.dispose(); editedElement = null; viewer = null; popupTitle = null; text = null; } /** * Getter of the edited element * * @return the element edited in this text cell editor */ public Object getEditedElement() { return editedElement; } }