/******************************************************************************* * Copyright (c) 2008 Mateusz Matela and others. * 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.eclipse.org/legal/epl-v10.html * * Contributors: * Mateusz Matela - Make StyledText work with ContentAssistCommandAdapter - https://bugs.eclipse.org/bugs/show_bug.cgi?id=246388 *******************************************************************************/ package org.simantics.scl.ui.assist; import org.eclipse.jface.fieldassist.ContentProposalAdapter; import org.eclipse.jface.fieldassist.IControlContentAdapter; import org.eclipse.jface.fieldassist.IControlContentAdapter2; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Control; /** * An {@link IControlContentAdapter} for {@link org.eclipse.swt.custom.StyledText}. This is * a convenience class for easily creating a {@link ContentProposalAdapter} for text fields. * * @since 3.5 */ public class StyledTextContentAdapter implements IControlContentAdapter, IControlContentAdapter2 { /* * (non-Javadoc) * * @see * org.eclipse.jface.fieldassist.IControlContentAdapter#getControlContents(org.eclipse * .swt.widgets.Control) */ public String getControlContents(Control control) { return ((StyledText)control).getText(); } /* * (non-Javadoc) * * @see * org.eclipse.jface.fieldassist.IControlContentAdapter#getCursorPosition(org.eclipse * .swt.widgets.Control) */ public int getCursorPosition(Control control) { return ((StyledText)control).getCaretOffset(); } /* * (non-Javadoc) * * @see * org.eclipse.jface.fieldassist.IControlContentAdapter#getInsertionBounds(org.eclipse * .swt.widgets.Control) */ public Rectangle getInsertionBounds(Control control) { StyledText text= (StyledText)control; Point caretOrigin= text.getLocationAtOffset(text.getCaretOffset()); return new Rectangle(caretOrigin.x + text.getClientArea().x, caretOrigin.y + text.getClientArea().y + 3, 1, text.getLineHeight()); } /* * (non-Javadoc) * * @see * org.eclipse.jface.fieldassist.IControlContentAdapter#insertControlContents(org.eclipse * .swt.widgets.Control, java.lang.String, int) */ public void insertControlContents(Control control, String contents, int cursorPosition) { StyledText text = ((StyledText)control); cursorPosition = Math.min(cursorPosition, contents.length()); int caretOffset = text.getCaretOffset(); String currentText = text.getText(); int replacementOffset = findPrefixMatchOffset(currentText, caretOffset, contents); // System.out.println("text: " + currentText); // System.out.println("proposal to fill: " + contents); // System.out.format("longest match of proposed contents found from text @ offset %d: \"%s[%s]%s\"%n", // replacementOffset, // currentText.substring(0, replacementOffset), // currentText.substring(replacementOffset, caretOffset), // currentText.substring(caretOffset)); // The text between [replaceOffset, caretOffset) will be replaced with `contents` text.setSelection(replacementOffset, caretOffset); text.insert(contents); text.setSelection(replacementOffset + contents.length()); } /** * Find offset of longest prefix match of match in * text ending at offset endOffset. * * Example: *
	 * ...  res (=text)
	 * resource (=match)
	 *  resourc
	 *   resour
	 *    resou
	 *     reso
	 *      res match! return endOffset - 3
	 * 
* * @param text the text from which to find the match * @param endOffset endOffset until which to search for the longest match * @param match the text to prefix-match * @return */ private static int findPrefixMatchOffset(String text, int endOffset, String match) { for (int i = match.length(); i >= 0; --i) { if (text.regionMatches(true, endOffset - i, match, 0, i)) return endOffset - i; } return 0; } /* * (non-Javadoc) * * @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) { ((StyledText)control).setText(contents); ((StyledText)control).setCaretOffset(cursorPosition); } /* * (non-Javadoc) * * @see * org.eclipse.jface.fieldassist.IControlContentAdapter#setCursorPosition(org.eclipse * .swt.widgets.Control, int) */ public void setCursorPosition(Control control, int index) { ((StyledText)control).setCaretOffset(index); } /* * (non-Javadoc) * * @see * org.eclipse.jface.fieldassist.IControlContentAdapter2#getSelection(org.eclipse.swt * .widgets.Control) */ public Point getSelection(Control control) { return ((StyledText)control).getSelection(); } /* * (non-Javadoc) * * @see * org.eclipse.jface.fieldassist.IControlContentAdapter2#setSelection(org.eclipse.swt * .widgets.Control, org.eclipse.swt.graphics.Point) */ public void setSelection(Control control, Point range) { ((StyledText)control).setSelection(range); } }