X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.scl.ui%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fui%2Fassist%2FStyledTextContentAdapter.java;h=899b9e731dd7800d7447e32988abbf588120edae;hb=d971cb77af378e93db25a568319525bd86bf9660;hp=35ded0599ced613adfcdbeb4378630941c389b42;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/assist/StyledTextContentAdapter.java b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/assist/StyledTextContentAdapter.java index 35ded0599..899b9e731 100644 --- a/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/assist/StyledTextContentAdapter.java +++ b/bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/assist/StyledTextContentAdapter.java @@ -1,139 +1,165 @@ -/******************************************************************************* - * 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.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 caretEndRange = text.getCaretOffset(); - String currentText = text.getText(); - - int offset = caretEndRange; - int length = currentText.length(); - while (--offset >= 0 && (Character.isJavaIdentifierPart(currentText.charAt(offset)) && !Character.isWhitespace(currentText.charAt(offset)))) - length--; - - int nameSpaceBeginRange = currentText.lastIndexOf(".", caretEndRange - 1); - if (nameSpaceBeginRange > length) - length = nameSpaceBeginRange; - int endRange = currentText.length(); - if (caretEndRange < endRange) - endRange = caretEndRange; - text.setSelection(length, endRange); - text.insert(contents); - // calculate the initial count of letters that was typed when the proposal was accepted to insert the caret - // at the right position - int proposalFirstLettersCount = endRange - (length); - text.setCaretOffset(caretEndRange + cursorPosition - proposalFirstLettersCount); - } - - /* - * (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); - } - -} +/******************************************************************************* + * 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); + } + +}