/* ********************************************************************** **
** Copyright notice **
** **
** (c) 2005-2009 RSSOwl Development Team **
** http://www.rssowl.org/ **
** **
** All rights reserved **
** **
** This program and the accompanying materials are made available under **
** the terms of the Eclipse Public License v1.0 which accompanies this **
** distribution, and is available at: **
** http://www.rssowl.org/legal/epl-v10.html **
** **
** A copy is found in the file epl-v10.html and important notices to the **
** license from the team is found in the textfile LICENSE.txt distributed **
** in this package. **
** **
** This copyright notice MUST APPEAR in all copies of the file! **
** **
** Contributors: **
** RSSOwl Development Team - initial API and implementation **
** **
** ********************************************************************** */
package org.rssowl.ui.internal.util;
import org.eclipse.jface.fieldassist.ComboContentAdapter;
import org.eclipse.jface.fieldassist.IControlContentAdapter;
import org.eclipse.jface.fieldassist.IControlContentAdapter2;
import org.eclipse.jface.fieldassist.TextContentAdapter;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Text;
import org.rssowl.ui.internal.Application;
/**
* An implementation of {@link IControlContentAdapter} with a more clever rule
* of inserting proposals. Supports {@link Text} and {@link Combo} widgets.
*
* @author bpasero
*/
public class ContentAssistAdapter implements IControlContentAdapter, IControlContentAdapter2 {
private TextContentAdapter fTextAdapter;
private ComboContentAdapter fComboAdapter;
private Control fControl;
private final char fSeparator;
private String fSeparatorStr;
private final boolean fExpectMultiValues;
/**
* @param control
* @param separator
* @param expectMultiValues
*/
public ContentAssistAdapter(Control control, char separator, boolean expectMultiValues) {
fControl = control;
fSeparator = separator;
fExpectMultiValues = expectMultiValues;
fSeparatorStr = new String(new char[] { fSeparator });
if (fSeparator != ' ')
fSeparatorStr = fSeparatorStr + " "; //$NON-NLS-1$
/* Text */
if (control instanceof Text) {
fTextAdapter = new TextContentAdapter() {
@Override
public Rectangle getInsertionBounds(Control control) {
Rectangle bounds = super.getInsertionBounds(control);
/* Bug on Mac: Insertion Bounds off by some pixels */
if (Application.IS_MAC)
bounds.y += 10;
return bounds;
}
};
}
/* Combo */
else if (control instanceof Combo) {
fComboAdapter = new ComboContentAdapter() {
@Override
public Rectangle getInsertionBounds(Control control) {
Rectangle bounds = super.getInsertionBounds(control);
/* Bug on Mac: Insertion Bounds off by some pixels */
if (Application.IS_MAC)
bounds.x -= 10;
return bounds;
}
};
} else
throw new IllegalArgumentException("Can only be used for Text and Combo Widgets"); //$NON-NLS-1$
}
/*
* @see org.eclipse.jface.fieldassist.IControlContentAdapter#getControlContents(org.eclipse.swt.widgets.Control)
*/
public String getControlContents(Control control) {
String text = getText();
int selectionOffset = getSelection().x;
if (selectionOffset == 0)
return ""; //$NON-NLS-1$
int previousSeparatorIndex = getPreviousSeparatorIndex(text, selectionOffset);
/* No Previous Separator Found - Return from Beginning */
if (previousSeparatorIndex == -1)
return text.substring(0, selectionOffset).trim();
/* Previous Separator Found - Return from Separator */
return text.substring(previousSeparatorIndex + 1, selectionOffset).trim();
}
private int getPreviousSeparatorIndex(String text, int selectionOffset) {
int previousSeparatorIndex = -1;
for (int i = 0; i < text.length(); i++) {
if (i == selectionOffset)
break;
if (text.charAt(i) == fSeparator)
previousSeparatorIndex = i;
}
return previousSeparatorIndex;
}
private int getNextSeparatorIndex(String text, int selectionOffset) {
int nextSeparatorIndex = -1;
for (int i = selectionOffset + 1; i < text.length(); i++) {
if (text.charAt(i) == fSeparator)
return i;
}
return nextSeparatorIndex;
}
/*
* @see org.eclipse.jface.fieldassist.IControlContentAdapter#insertControlContents(org.eclipse.swt.widgets.Control, java.lang.String, int)
*/
public void insertControlContents(Control control, String textToInsert, int cursorPosition) {
String text = getText();
int selectionOffset = getSelection().x;
int previousSeparatorIndex = getPreviousSeparatorIndex(text, selectionOffset);
int nextSeparatorIndex = getNextSeparatorIndex(text, selectionOffset);
/* Replace All: No Separator Found */
if (previousSeparatorIndex == -1 && nextSeparatorIndex == -1) {
text = fExpectMultiValues ? textToInsert + fSeparatorStr : textToInsert;
}
/* Replace All beginning with Previous Separator */
else if (previousSeparatorIndex != -1 && nextSeparatorIndex == -1) {
text = text.substring(0, previousSeparatorIndex);
text = text + fSeparatorStr + textToInsert + fSeparatorStr;
}
/* Replace all from beginning till Next Separator */
else if (previousSeparatorIndex == -1 && nextSeparatorIndex != -1) {
text = textToInsert + text.substring(nextSeparatorIndex);
}
/* Replace all from previous Separator till next Separator */
else {
String leftHand = text.substring(0, previousSeparatorIndex);
String rightHand = text.substring(nextSeparatorIndex);
text = leftHand + fSeparatorStr + textToInsert + rightHand;
}
setText(text);
setSelection(new Point(getText().length(), getText().length()));
}
/*
* @see org.eclipse.jface.fieldassist.IControlContentAdapter#getCursorPosition(org.eclipse.swt.widgets.Control)
*/
public int getCursorPosition(Control control) {
if (control instanceof Text)
return fTextAdapter.getCursorPosition(control);
return fComboAdapter.getCursorPosition(control);
}
/*
* @see org.eclipse.jface.fieldassist.IControlContentAdapter#getInsertionBounds(org.eclipse.swt.widgets.Control)
*/
public Rectangle getInsertionBounds(Control control) {
if (control instanceof Text)
return fTextAdapter.getInsertionBounds(control);
return fComboAdapter.getInsertionBounds(control);
}
/*
* @see org.eclipse.jface.fieldassist.IControlContentAdapter#setControlContents(org.eclipse.swt.widgets.Control, java.lang.String, int)
*/
public void setControlContents(Control control, String contents, int cursorPosition) {
if (control instanceof Text)
fTextAdapter.setControlContents(control, contents, cursorPosition);
else
fComboAdapter.setControlContents(control, contents, cursorPosition);
}
/*
* @see org.eclipse.jface.fieldassist.IControlContentAdapter#setCursorPosition(org.eclipse.swt.widgets.Control, int)
*/
public void setCursorPosition(Control control, int index) {
if (control instanceof Text)
fTextAdapter.setCursorPosition(control, index);
else
fComboAdapter.setCursorPosition(control, index);
}
/*
* @see org.eclipse.jface.fieldassist.IControlContentAdapter2#getSelection(org.eclipse.swt.widgets.Control)
*/
public Point getSelection(Control control) {
if (control instanceof Text)
return fTextAdapter.getSelection(control);
return fComboAdapter.getSelection(control);
}
/*
* @see org.eclipse.jface.fieldassist.IControlContentAdapter2#setSelection(org.eclipse.swt.widgets.Control, org.eclipse.swt.graphics.Point)
*/
public void setSelection(Control control, Point range) {
if (control instanceof Text)
fTextAdapter.setSelection(control, range);
else
fComboAdapter.setSelection(control, range);
}
private String getText() {
if (fControl instanceof Text)
return ((Text) fControl).getText();
return ((Combo) fControl).getText();
}
private Point getSelection() {
if (fControl instanceof Text)
return ((Text) fControl).getSelection();
return ((Combo) fControl).getSelection();
}
private void setText(String text) {
if (fControl instanceof Text)
((Text) fControl).setText(text);
else
((Combo) fControl).setText(text);
}
private void setSelection(Point selection) {
if (fControl instanceof Text)
((Text) fControl).setSelection(selection);
else
((Combo) fControl).setSelection(selection);
}
}