Skip to content

Commit

Permalink
TEIIDDES-1472 Need look-ahead when selecting Runtime Type value for a…
Browse files Browse the repository at this point in the history
…n extension property in MED Editor

Installed a look-ahead proposal provider for the runtime type and for the translation (locale) combos. These
look-ahead proposals work when the combo has keyboard focus. Selection is changed to the proposal if the CR
key is hit.
  • Loading branch information
elvisisking committed Feb 15, 2013
1 parent 955d99f commit 44d2dbc
Show file tree
Hide file tree
Showing 6 changed files with 516 additions and 102 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
/*
* JBoss, Home of Professional Open Source.
*
* See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing.
*
* See the AUTHORS.txt file distributed with this work for a full listing of individual contributors.
*/
package org.teiid.designer.extension.ui.editors;

import java.util.List;
import org.eclipse.jface.fieldassist.ContentProposal;
import org.eclipse.jface.fieldassist.ContentProposalAdapter;
import org.eclipse.jface.fieldassist.IContentProposal;
import org.eclipse.jface.fieldassist.IContentProposalProvider;
import org.eclipse.jface.fieldassist.IControlContentAdapter;
import org.eclipse.jface.fieldassist.IControlContentAdapter2;
import org.eclipse.jface.util.Util;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Control;
import org.teiid.designer.core.util.StringUtilities;

/**
* Provides matching CCombo items based on keystrokes for a readonly combo.
*/
abstract class CComboProposalProvider implements IControlContentAdapter, IControlContentAdapter2, IContentProposalProvider {

private static final long DEFAULT_DURATION = 500;

private final CCombo combo;
private long duration = DEFAULT_DURATION;
private String pattern = StringUtilities.EMPTY_STRING;
private long t1 = System.currentTimeMillis();
private long t2;

/**
* @param combo the combo whose proposals are being requested (cannot be <code>null</code>)
*/
protected CComboProposalProvider(final CCombo combo) {
this(combo, DEFAULT_DURATION);
}

/**
* @param combo the combo whose proposals are being requested (cannot be <code>null</code>)
* @param duration the amount of time to wait before resetting the pattern used to match items
*/
protected CComboProposalProvider(final CCombo combo,
final long duration) {
this.duration = duration;
this.combo = combo;
combo.addKeyListener(new KeyAdapter() {

/**
* @see org.eclipse.swt.events.KeyAdapter#keyPressed(org.eclipse.swt.events.KeyEvent)
*/
@Override
public void keyPressed(KeyEvent e) {
handleKeyPressed(e);
}
});
}

/**
* @return the characters that trigger auto-activation of proposals (can be <code>null</code>)
*/
protected abstract char[] getActivationChars();

/**
* @see org.eclipse.jface.fieldassist.IControlContentAdapter#getControlContents(org.eclipse.swt.widgets.Control)
*/
@Override
public final String getControlContents(final Control control) {
return this.combo.getText();
}

/**
* @see org.eclipse.jface.fieldassist.IControlContentAdapter#getCursorPosition(org.eclipse.swt.widgets.Control)
*/
@Override
public final int getCursorPosition(final Control control) {
return this.combo.getSelection().x;
}

/**
* @see org.eclipse.jface.fieldassist.IControlContentAdapter#getInsertionBounds(org.eclipse.swt.widgets.Control)
*/
@Override
public final Rectangle getInsertionBounds(final Control control) {
final int position = this.combo.getSelection().y;
final String contents = this.combo.getText();

final GC gc = new GC(this.combo);
gc.setFont(this.combo.getFont());

final Point extent = gc.textExtent(contents.substring(0, Math.min(position, contents.length())));
gc.dispose();

return new Rectangle(this.combo.getClientArea().x + extent.x, this.combo.getClientArea().y, 1,
this.combo.getClientArea().height);
}

/**
* @see org.eclipse.jface.fieldassist.IContentProposalProvider#getProposals(java.lang.String, int)
*/
@Override
public final IContentProposal[] getProposals(final String contents,
final int position) {
if (this.combo.getListVisible()) {
return new IContentProposal[0];
}

final List<String> matches = proposalsFor(this.pattern);

if (matches.isEmpty()) {
return new IContentProposal[0];
}

final IContentProposal[] proposals = new IContentProposal[matches.size()];
int i = 0;

for (final String match : matches) {
proposals[i++] = new ContentProposal(match);
}

return proposals;
}

/**
* @see org.eclipse.jface.fieldassist.IControlContentAdapter2#getSelection(org.eclipse.swt.widgets.Control)
*/
@Override
public final Point getSelection(final Control control) {
return this.combo.getSelection();
}

final void handleKeyPressed(final KeyEvent e) {
this.t2 = System.currentTimeMillis();

if ((this.t2 - this.t1) > this.duration) {
this.pattern = StringUtilities.EMPTY_STRING;
}

this.t1 = this.t2;

if (!Character.isLetter(e.character)) {
this.pattern = StringUtilities.EMPTY_STRING;
} else {
this.pattern += e.character;
}
}

/**
* Initializes the proposal provider. Must be called after construction.
*/
final void init() {
final ContentProposalAdapter proposalAdapter = new ContentProposalAdapter(this.combo, this, this, null,
getActivationChars());
proposalAdapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
}

/**
* @see org.eclipse.jface.fieldassist.IControlContentAdapter#insertControlContents(org.eclipse.swt.widgets.Control, java.lang.String, int)
*/
@Override
public final void insertControlContents(final Control control,
final String text,
final int cursorPosition) {
final String contents = this.combo.getText();
final Point selection = this.combo.getSelection();

final StringBuilder builder = new StringBuilder();
builder.append(contents.substring(0, selection.x)).append(text);

if (selection.y < contents.length()) {
builder.append(contents.substring(selection.y, contents.length()));
}

setText(builder.toString());
//
// selection.x = (selection.x + cursorPosition);
// selection.y = selection.x;
// this.combo.setSelection(selection);
}

/**
* @param pattern the pattern to use (can be <code>null</code> or empty)
* @return the proposals that match (never <code>null</code> but can be empty)
*/
protected abstract List<String> proposalsFor(final String pattern);

/**
* @see org.eclipse.jface.fieldassist.IControlContentAdapter#setControlContents(org.eclipse.swt.widgets.Control, java.lang.String, int)
*/
@Override
public final void setControlContents(final Control control,
final String contents,
final int cursorPosition) {
setText(contents);
setCursorPosition(control, cursorPosition);
}

/**
* @see org.eclipse.jface.fieldassist.IControlContentAdapter#setCursorPosition(org.eclipse.swt.widgets.Control, int)
*/
@Override
public final void setCursorPosition(final Control control,
final int index) {
this.combo.setSelection(new Point(index, index));
}

/**
* @see org.eclipse.jface.fieldassist.IControlContentAdapter2#setSelection(org.eclipse.swt.widgets.Control, org.eclipse.swt.graphics.Point)
*/
@Override
public final void setSelection(final Control control,
final Point range) {
this.combo.setSelection(range);
}

private void setText(final String newSelection) {
final int index = this.combo.indexOf(newSelection);

if (index != -1) {
this.combo.select(index);
}
}
}
Loading

0 comments on commit 44d2dbc

Please sign in to comment.