1765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye/******************************************************************************* 2765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Copyright (c) 2011 Google, Inc. 3765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * All rights reserved. This program and the accompanying materials 4765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * are made available under the terms of the Eclipse Public License v1.0 5765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * which accompanies this distribution, and is available at 6765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * http://www.eclipse.org/legal/epl-v10.html 7765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * 8765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Contributors: 9765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Google, Inc. - initial API and implementation 10765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye *******************************************************************************/ 11765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyepackage org.eclipse.wb.internal.core.model.property.editor; 12765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 13765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.jface.bindings.keys.KeyStroke; 14765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.jface.fieldassist.ContentProposalAdapter; 151f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbyeimport org.eclipse.jface.fieldassist.IContentProposal; 161f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbyeimport org.eclipse.jface.fieldassist.IContentProposalListener; 171f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbyeimport org.eclipse.jface.fieldassist.IContentProposalListener2; 18765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.jface.fieldassist.IContentProposalProvider; 19765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.jface.fieldassist.IControlContentAdapter; 20765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.jface.fieldassist.TextContentAdapter; 21765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.jface.viewers.ILabelProvider; 22765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.SWT; 23765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.events.FocusEvent; 24765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.events.FocusListener; 25765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.events.KeyAdapter; 26765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.events.KeyEvent; 27765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.events.KeyListener; 28765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.graphics.Point; 29765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.graphics.Rectangle; 30765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.widgets.Display; 31765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.widgets.Event; 32765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.widgets.Listener; 33765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.swt.widgets.Text; 34765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.wb.internal.core.model.property.Property; 35765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyeimport org.eclipse.wb.internal.core.model.property.table.PropertyTable; 36765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 37765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye/** 38765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Abstract {@link PropertyEditor} for that uses {@link Text} as control. 39765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * 40765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @author scheglov_ke 41765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @coverage core.model.property.editor 42765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 43765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbyepublic abstract class AbstractTextPropertyEditor extends TextDisplayPropertyEditor { 44765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 45765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 46765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // Editing 47765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 48765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 49765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private Text m_textControl; 50765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private boolean m_ignoreFocusLost; 51765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 52765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // BEGIN ADT MODIFICATIONS 53765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // ContentProposalAdapter which exposes the openProposalPopup method such 54765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // that we can open the dialog up immediately on focus gain to show all available 55765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // alternatives (the default implementation requires at least one keytroke before 56765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // it shows up) 571f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye private class ImmediateProposalAdapter extends ContentProposalAdapter 581f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye implements FocusListener, IContentProposalListener, IContentProposalListener2 { 591f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye private final PropertyTable m_propertyTable; 60767eb85ab3a32c1a9621eca167863e625b0927ccTor Norbye private final IContentProposalProvider m_proposalProvider; 611f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye public ImmediateProposalAdapter( 621f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye Text control, 63765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye IControlContentAdapter controlContentAdapter, 641f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye IContentProposalProvider proposalProvider, 651f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye KeyStroke keyStroke, 661f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye char[] autoActivationCharacters, 671f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye PropertyTable propertyTable) { 68765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye super(control, controlContentAdapter, proposalProvider, keyStroke, 69765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye autoActivationCharacters); 701f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye m_propertyTable = propertyTable; 71767eb85ab3a32c1a9621eca167863e625b0927ccTor Norbye m_proposalProvider = proposalProvider; 72765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 73765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // On focus gain, start completing 741f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye control.addFocusListener(this); 75765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 761f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye // Listen on popup open and close events, in order to disable 771f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye // focus handling on the textfield during those events. 781f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye // This is necessary since otherwise as soon as the user clicks 791f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye // on the popup with the mouse, the text field loses focus, and 801f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye // then instantly closes the popup -- without the selection being 811f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye // applied. See for example 821f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye // http://dev.eclipse.org/viewcvs/viewvc.cgi/org.eclipse.jface.snippets/ 831f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye // Eclipse%20JFace%20Snippets/org/eclipse/jface/snippets/viewers/ 841f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye // Snippet060TextCellEditorWithContentProposal.java?view=markup 851f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye // for another example of this technique. 861f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye addContentProposalListener((IContentProposalListener) this); 871f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye addContentProposalListener((IContentProposalListener2) this); 88765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 89765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /* Triggering on empty is disabled for now: it has the unfortunate side-effect 90765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye that it's impossible to enter a blank text field - blank matches everything, 91765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye so the first item will automatically be selected when you press return. 92765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 93765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 94765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // If you edit the text and delete everything, the normal implementation 95765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // will close the popup; we'll reopen it 96765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye control.addModifyListener(new ModifyListener() { 97765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye @Override 98765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void modifyText(ModifyEvent event) { 99765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (((Text) getControl()).getText().isEmpty()) { 100765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye openIfNecessary(); 101765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 102765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 103765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye }); 104765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 105765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 106765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 107765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private void openIfNecessary() { 108767eb85ab3a32c1a9621eca167863e625b0927ccTor Norbye if (m_textControl == null || m_textControl.isDisposed() || 109767eb85ab3a32c1a9621eca167863e625b0927ccTor Norbye m_proposalProvider.getProposals(m_textControl.getText(), 110767eb85ab3a32c1a9621eca167863e625b0927ccTor Norbye m_textControl.getCaretPosition()).length == 0) { 111767eb85ab3a32c1a9621eca167863e625b0927ccTor Norbye return; 112767eb85ab3a32c1a9621eca167863e625b0927ccTor Norbye } 113767eb85ab3a32c1a9621eca167863e625b0927ccTor Norbye 114765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye getControl().getDisplay().asyncExec(new Runnable() { 115765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye @Override 116765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void run() { 117765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (!isProposalPopupOpen()) { 118765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye openProposalPopup(); 119765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 120765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 121765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye }); 122765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 1231f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye 1241f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye // ---- Implements FocusListener ---- 1251f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye 1261f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye @Override 1271f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye public void focusGained(FocusEvent event) { 1281f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye openIfNecessary(); 1291f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye } 1301f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye 1311f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye @Override 1321f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye public void focusLost(FocusEvent event) { 1331f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye } 1341f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye 1351f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye // ---- Implements IContentProposalListener ---- 1361f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye 1371f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye @Override 1381f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye public void proposalAccepted(IContentProposal proposal) { 1391f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye closeProposalPopup(); 1401f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye m_propertyTable.deactivateEditor(true); 1411f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye } 1421f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye 1431f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye // ---- Implements IContentProposalListener2 ---- 1441f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye 1451f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye @Override 1461f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye public void proposalPopupClosed(ContentProposalAdapter adapter) { 1471f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye m_ignoreFocusLost = false; 1481f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye } 1491f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye 1501f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye @Override 1511f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye public void proposalPopupOpened(ContentProposalAdapter adapter) { 1521f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye m_ignoreFocusLost = true; 1531f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye } 154765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 155765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // END ADT MODIFICATIONS 156765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 157765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye @Override 158765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public boolean activate(final PropertyTable propertyTable, final Property property, Point location) 159765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye throws Exception { 160765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // create Text 161765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye { 162765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_textControl = new Text(propertyTable, SWT.NONE); 1631f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye 1641f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye @SuppressWarnings("unused") 1651f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye TextControlActionsManager manager = new TextControlActionsManager(m_textControl); 1661f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye 167765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_textControl.setEditable(isEditable()); 168765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 169765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // BEGIN ADT MODIFICATIONS 170765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // Add support for field completion, if the property provides an IContentProposalProvider 171765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // via its the getAdapter method. 172765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye IContentProposalProvider completion = property.getAdapter(IContentProposalProvider.class); 173765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (completion != null) { 174765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye ImmediateProposalAdapter adapter = new ImmediateProposalAdapter( 1751f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye m_textControl, new TextContentAdapter(), completion, null, null, 1761f6650ac4338fe0eab9874f72cee21c231412d31Tor Norbye propertyTable); 177765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye adapter.setFilterStyle(ContentProposalAdapter.FILTER_NONE); 178765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE); 179765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye ILabelProvider labelProvider = property.getAdapter(ILabelProvider.class); 180765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (labelProvider != null) { 181765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye adapter.setLabelProvider(labelProvider); 182765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 183765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 184765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // END ADT MODIFICATIONS 185765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_textControl.setFocus(); 186765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 187765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // add listeners 188765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_textControl.addKeyListener(new KeyAdapter() { 189765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye @Override 190765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void keyPressed(KeyEvent e) { 191765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye try { 192765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye handleKeyPressed(propertyTable, property, e); 193765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } catch (Throwable ex) { 194765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye propertyTable.deactivateEditor(false); 195765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye propertyTable.handleException(ex); 196765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 197765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 198765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye }); 199765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_textControl.addListener(SWT.FocusOut, new Listener() { 200765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye @Override 201765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void handleEvent(Event event) { 202765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (!m_ignoreFocusLost) { 203765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye propertyTable.deactivateEditor(true); 204765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 205765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 206765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye }); 207765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // set data 208765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye toWidget(property); 209765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // keep us active 210765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return true; 211765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 212765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 213765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye @Override 214765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public final void setBounds(Rectangle bounds) { 215765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_textControl.setBounds(bounds); 216765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 217765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 218765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye @Override 219765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public final void deactivate(PropertyTable propertyTable, Property property, boolean save) { 220765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (save) { 221765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye try { 222765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye toProperty(property); 223765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } catch (Throwable e) { 224765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye propertyTable.deactivateEditor(false); 225765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye propertyTable.handleException(e); 226765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 227765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 228765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // dispose Text widget 229765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (m_textControl != null) { 230765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_textControl.dispose(); 231765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_textControl = null; 232765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 233765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 234765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 235765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye @Override 236765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye public void keyDown(PropertyTable propertyTable, Property property, KeyEvent event) 237765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye throws Exception { 238765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye boolean withAlt = (event.stateMask & SWT.ALT) != 0; 239765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye boolean withCtrl = (event.stateMask & SWT.CTRL) != 0; 240765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (event.character != 0 && !(withAlt || withCtrl)) { 241765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye propertyTable.activateEditor(property, null); 242765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye postKeyEvent(SWT.KeyDown, event); 243765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye postKeyEvent(SWT.KeyUp, event); 244765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 245765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 246765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 247765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 248765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Posts low-level {@link SWT.KeyDown} or {@link SWT.KeyUp} event. 249765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 250765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private static void postKeyEvent(int type, KeyEvent event) { 251765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Event lowEvent = new Event(); 252765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye lowEvent.type = type; 253765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye lowEvent.keyCode = event.keyCode; 254765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye lowEvent.character = event.character; 255765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // post event 256765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye Display.getCurrent().post(lowEvent); 257765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 258765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 259765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 260765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 261765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // Events 262765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 263765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 264765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 265765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Handles {@link KeyListener#keyPressed(KeyEvent)}. 266765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 267765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private void handleKeyPressed(PropertyTable propertyTable, Property property, KeyEvent e) 268765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye throws Exception { 269765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (e.keyCode == SWT.CR) { 270765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye toProperty(property); 271765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 272765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // BEGIN ADT MODIFICATIONS 273765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // After pressing return, dismiss the text cursor to make the value "committed". 274765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // I'm not sure why this is necessary here and not in WindowBuilder proper. 275765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye propertyTable.deactivateEditor(true); 276765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // END ADT MODIFICATIONS 277765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } else if (e.keyCode == SWT.ESC) { 278765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye propertyTable.deactivateEditor(false); 279765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } else if (e.keyCode == SWT.ARROW_UP || e.keyCode == SWT.ARROW_DOWN) { 280765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye e.doit = false; 281765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye boolean success = toProperty(property); 282765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // don't allow navigation if current text can not be transferred to property 283765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (!success) { 284765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return; 285765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 286765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // OK, deactivate and navigate 287765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye propertyTable.deactivateEditor(true); 288765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye propertyTable.navigate(e); 289765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 290765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 291765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 292765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 293765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 294765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // Implementation 295765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 296765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 297765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private String m_currentText; 298765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 299765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 300765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Transfers data from {@link Property} to widget. 301765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 302765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private void toWidget(Property property) throws Exception { 303765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // prepare text 304765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye String text = getEditorText(property); 305765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (text == null) { 306765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye text = ""; 307765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 308765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // set text 309765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_currentText = text; 310765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_textControl.setText(text); 311765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_textControl.selectAll(); 312765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 313765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 314765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 315765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Transfers data from widget to {@link Property}. 316765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * 317765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return <code>true</code> if transfer was successful. 318765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 319765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye private boolean toProperty(Property property) throws Exception { 320f38ceabb9b297d5fec04b992695424853967ba74Tor Norbye // BEGIN ADT MODIFICATIONS 321f38ceabb9b297d5fec04b992695424853967ba74Tor Norbye if (m_textControl == null) { 322f38ceabb9b297d5fec04b992695424853967ba74Tor Norbye return false; 323f38ceabb9b297d5fec04b992695424853967ba74Tor Norbye } 324f38ceabb9b297d5fec04b992695424853967ba74Tor Norbye // END ADT MODIFICATIONS 325765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye String text = m_textControl.getText(); 326765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // change property only if text was changed 327765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (!m_currentText.equals(text)) { 328765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_ignoreFocusLost = true; 329765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye try { 330765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye boolean success = setEditorText(property, text); 331765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye if (!success) { 332765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return false; 333765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 334765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } finally { 335765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_ignoreFocusLost = false; 336765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 337765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // if value was successfully changed, update current text 338765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye m_currentText = text; 339765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 340765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // OK, success 341765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return true; 342765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 343765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 344765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 345765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 346765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // Operations 347765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye // 348765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye //////////////////////////////////////////////////////////////////////////// 349765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 350765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return <code>true</code> if this editor can modify text. 351765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 352765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye protected boolean isEditable() { 353765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye return true; 354765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye } 355765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 356765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 357765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return the text to display in {@link Text} control. 358765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 359765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye protected abstract String getEditorText(Property property) throws Exception; 360765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye 361765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye /** 362765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * Modifies {@link Property} using given text. 363765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * 364765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye * @return <code>true</code> if {@link Property} was successfully modified. 365765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye */ 366765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye protected abstract boolean setEditorText(Property property, String text) throws Exception; 367765e52e2d30d0754625b8c7af6c36e93612f15beTor Norbye} 368