From 2496e77f36d6205472d44a29582019194550c928 Mon Sep 17 00:00:00 2001 From: Matti Tahvonen Date: Thu, 17 Jun 2010 14:49:46 +0000 Subject: [PATCH] Text selection methods for TextField. Fixes #5217 svn changeset:13751/svn branch:6.4 --- .../terminal/gwt/client/ui/VTextField.java | 38 +++++++ src/com/vaadin/ui/TextField.java | 51 +++++++++ .../textfield/SelectionAndCursorPosition.java | 104 ++++++++++++++++++ 3 files changed, 193 insertions(+) create mode 100644 tests/src/com/vaadin/tests/components/textfield/SelectionAndCursorPosition.java diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTextField.java b/src/com/vaadin/terminal/gwt/client/ui/VTextField.java index 7594bde3b1..50c81e19bd 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VTextField.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VTextField.java @@ -55,9 +55,11 @@ public class VTextField extends TextBoxBase implements Paintable, Field, private static final String CLASSNAME_PROMPT = "prompt"; private static final String ATTR_INPUTPROMPT = "prompt"; + private static final String VAR_CURSOR = "c"; private String inputPrompt = null; private boolean prompting = false; + private int lastCursorPos = -1; public VTextField() { this(DOM.createInputText()); @@ -142,6 +144,19 @@ public class VTextField extends TextBoxBase implements Paintable, Field, } valueBeforeEdit = uidl.getStringVariable("text"); + + if (uidl.hasAttribute("selpos")) { + final int pos = uidl.getIntAttribute("selpos"); + final int length = uidl.getIntAttribute("sellen"); + /* + * Gecko defers setting the text so we need to defer the selection. + */ + DeferredCommand.addCommand(new Command() { + public void execute() { + setSelectionRange(pos, length); + } + }); + } } private void setMaxLength(int newMaxLength) { @@ -197,12 +212,35 @@ public class VTextField extends TextBoxBase implements Paintable, Field, valueBeforeEdit = newText; } + /* + * also send cursor position, no public api yet but for easier + * extension + */ + updateCursorPosition(); + if (sendBlurEvent || sendValueChange) { client.sendPendingVariableChanges(); } } } + /** + * Updates the cursor position variable if it has changed since the last + * update. + * + * @return true iff the value was updated + */ + protected boolean updateCursorPosition() { + int cursorPos = getCursorPos(); + if (lastCursorPos != cursorPos) { + client.updateVariable(id, VAR_CURSOR, cursorPos, false); + lastCursorPos = cursorPos; + return true; + } else { + return false; + } + } + private static VTextField focusedTextField; public static void flushChangesFromFocusedTextField() { diff --git a/src/com/vaadin/ui/TextField.java b/src/com/vaadin/ui/TextField.java index aa4c7c8661..fff0beaf0c 100644 --- a/src/com/vaadin/ui/TextField.java +++ b/src/com/vaadin/ui/TextField.java @@ -90,6 +90,10 @@ public class TextField extends AbstractField implements */ private int maxLength = -1; + private int selectionPosition = -1; + + private int selectionLength; + /* Constructors */ /** @@ -174,6 +178,11 @@ public class TextField extends AbstractField implements if (inputPrompt != null) { target.addAttribute("prompt", inputPrompt); } + if (selectionPosition != -1) { + target.addAttribute("selpos", selectionPosition); + target.addAttribute("sellen", selectionLength); + selectionPosition = -1; + } // Adds the number of column and rows final int columns = getColumns(); @@ -635,4 +644,46 @@ public class TextField extends AbstractField implements removeListener(BlurEvent.EVENT_ID, BlurEvent.class, listener); } + /** + * Selects all text in the field. + * + * @since 6.4 + */ + public void selectAll() { + String text = getValue() == null ? "" : getValue().toString(); + setSelectionRange(0, text.length()); + } + + /** + * Sets the range of text to be selected. + * + * As a side effect the field will become focused. + * + * @since 6.4 + * + * @param pos + * the position of the first character to be selected + * @param length + * the number of characters to be selected + */ + public void setSelectionRange(int pos, int length) { + selectionPosition = pos; + selectionLength = length; + focus(); + requestRepaint(); + } + + /** + * Sets the cursor position in the field. As a side effect the field will + * become focused. + * + * @since 6.4 + * + * @param pos + * the position for the cursor + * */ + public void setCursorPosition(int pos) { + setSelectionRange(pos, 0); + } + } diff --git a/tests/src/com/vaadin/tests/components/textfield/SelectionAndCursorPosition.java b/tests/src/com/vaadin/tests/components/textfield/SelectionAndCursorPosition.java new file mode 100644 index 0000000000..3a9f35f75a --- /dev/null +++ b/tests/src/com/vaadin/tests/components/textfield/SelectionAndCursorPosition.java @@ -0,0 +1,104 @@ +package com.vaadin.tests.components.textfield; + +import com.vaadin.data.Property; +import com.vaadin.data.Property.ValueChangeEvent; +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Button; +import com.vaadin.ui.CheckBox; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Panel; +import com.vaadin.ui.TextField; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; + +public class SelectionAndCursorPosition extends TestBase { + + TextField tf = new TextField(); + + @Override + protected void setup() { + + tf.setCaption("Text field"); + tf.setValue("So we have some text to select"); + tf.setWidth("400px"); + + FormLayout fl = new FormLayout(); + Panel panel = new Panel(fl); + panel.setCaption("Hackers panel"); + CheckBox ml = new CheckBox("Multiline"); + ml.setImmediate(true); + ml.addListener(new Property.ValueChangeListener() { + public void valueChange(ValueChangeEvent event) { + if (tf.getHeight() < 0) { + tf.setHeight("50px"); + } else { + tf.setSizeUndefined(); + tf.setRows(0); + } + tf.setWidth("400px"); + } + }); + fl.addComponent(ml); + + Button b = new Button("Select all ( selectAll() )"); + b.addListener(new ClickListener() { + public void buttonClick(ClickEvent event) { + tf.selectAll(); + } + }); + fl.addComponent(b); + + HorizontalLayout selectRange = new HorizontalLayout(); + selectRange + .setCaption("Select range of text ( setSelectionRange(int start, int lengt) )"); + final TextField start = new TextField("From:"); + final TextField length = new TextField("Selection length:"); + b = new Button("select"); + b.addListener(new ClickListener() { + public void buttonClick(ClickEvent event) { + int startPos = Integer.parseInt((String) start.getValue()); + int lenght = Integer.parseInt((String) length.getValue()); + tf.setSelectionRange(startPos, lenght); + } + }); + + selectRange.addComponent(start); + selectRange.addComponent(length); + selectRange.addComponent(b); + fl.addComponent(selectRange); + + HorizontalLayout setCursorPosition = new HorizontalLayout(); + final TextField pos = new TextField("Position:"); + b = new Button("set"); + b.addListener(new ClickListener() { + public void buttonClick(ClickEvent event) { + int startPos = Integer.parseInt((String) pos.getValue()); + tf.setCursorPosition(startPos); + } + }); + + setCursorPosition.addComponent(pos); + setCursorPosition.addComponent(b); + setCursorPosition + .setCaption("Set cursor position ( setCursorPosition(int pos) )"); + fl.addComponent(setCursorPosition); + + getLayout().addComponent(tf); + getLayout().addComponent(panel); + + } + + @Override + protected String getDescription() { + return "For usability reasons it is often essential that developer " + + "can hint how to select the text in the " + + "field or where to set the cursor position."; + } + + @Override + protected Integer getTicketNumber() { + return 2058; + } + +} -- 2.39.5