1/******************************************************************************* 2 * Copyright (c) 2011 Google, Inc. 3 * All rights reserved. This program and the accompanying materials 4 * are made available under the terms of the Eclipse Public License v1.0 5 * which accompanies this distribution, and is available at 6 * http://www.eclipse.org/legal/epl-v10.html 7 * 8 * Contributors: 9 * Google, Inc. - initial API and implementation 10 *******************************************************************************/ 11package org.eclipse.wb.internal.core.model.property.editor; 12 13import org.eclipse.wb.core.controls.CCombo3; 14import org.eclipse.wb.core.controls.CComboBox; 15import org.eclipse.wb.internal.core.model.property.Property; 16import org.eclipse.wb.internal.core.model.property.table.PropertyTable; 17import org.eclipse.wb.internal.core.utils.execution.ExecutionUtils; 18import org.eclipse.wb.internal.core.utils.execution.RunnableEx; 19 20import org.eclipse.swt.SWT; 21import org.eclipse.swt.events.FocusAdapter; 22import org.eclipse.swt.events.FocusEvent; 23import org.eclipse.swt.events.KeyAdapter; 24import org.eclipse.swt.events.KeyEvent; 25import org.eclipse.swt.events.SelectionAdapter; 26import org.eclipse.swt.events.SelectionEvent; 27import org.eclipse.swt.graphics.Point; 28import org.eclipse.swt.graphics.Rectangle; 29 30/** 31 * The {@link PropertyEditor} for selecting single value using {@link CComboBox}. This editor has 32 * in-line search-feature and is more suitable (vs {@link AbstractComboPropertyEditor}) for 33 * properties with large lists of value items. 34 * 35 * @author sablin_aa 36 * @author scheglov_ke 37 * @coverage core.model.property.editor 38 */ 39public abstract class AbstractComboBoxPropertyEditor extends TextDisplayPropertyEditor { 40 //////////////////////////////////////////////////////////////////////////// 41 // 42 // Editing 43 // 44 //////////////////////////////////////////////////////////////////////////// 45 private CComboBox m_combo; 46 private String m_dropDelayedText; 47 48 @Override 49 public final boolean activate(final PropertyTable propertyTable, 50 final Property property, 51 Point location) throws Exception { 52 m_combo = new CComboBox(propertyTable, SWT.NONE); 53 // initialize 54 addItems(property, m_combo); 55 selectItem(property, m_combo); 56 // install listeners 57 m_combo.addKeyListener(new KeyAdapter() { 58 @Override 59 public void keyPressed(KeyEvent e) { 60 handleKeyPressed(propertyTable, property, e); 61 } 62 }); 63 m_combo.addFocusListener(new FocusAdapter() { 64 @Override 65 public void focusLost(FocusEvent e) { 66 propertyTable.deactivateEditor(true); 67 } 68 }); 69 m_combo.addSelectionListener(new SelectionAdapter() { 70 @Override 71 public void widgetSelected(SelectionEvent e) { 72 propertyTable.deactivateEditor(true); 73 } 74 }); 75 m_combo.setFocus(); 76 // schedule showing drop-down, because we don't have bounds yet 77 ExecutionUtils.runAsync(new RunnableEx() { 78 public void run() throws Exception { 79 m_combo.comboDropDown(true); 80 if (m_dropDelayedText != null) { 81 m_combo.setEditText(m_dropDelayedText); 82 m_combo.setEditSelection(m_dropDelayedText.length(), m_dropDelayedText.length()); 83 m_dropDelayedText = null; 84 } 85 } 86 }); 87 // keep editor active 88 return true; 89 } 90 91 private void handleKeyPressed(PropertyTable propertyTable, Property property, KeyEvent e) { 92 if (e.keyCode == SWT.ESC) { 93 propertyTable.deactivateEditor(false); 94 } else if (e.keyCode == SWT.ARROW_UP || e.keyCode == SWT.ARROW_DOWN) { 95 e.doit = false; 96 propertyTable.deactivateEditor(true); 97 propertyTable.navigate(e); 98 } 99 } 100 101 @Override 102 public final void deactivate(PropertyTable propertyTable, Property property, boolean save) { 103 if (save) { 104 toProperty(propertyTable, property); 105 } 106 if (m_combo != null) { 107 m_combo.dispose(); 108 m_combo = null; 109 } 110 } 111 112 private void toProperty(PropertyTable propertyTable, Property property) { 113 try { 114 toPropertyEx(property, m_combo); 115 } catch (Throwable e) { 116 propertyTable.handleException(e); 117 } 118 } 119 120 @Override 121 public void setBounds(Rectangle bounds) { 122 m_combo.setBounds(bounds); 123 } 124 125 @Override 126 public void keyDown(PropertyTable propertyTable, Property property, KeyEvent event) 127 throws Exception { 128 boolean withAlt = (event.stateMask & SWT.ALT) != 0; 129 boolean withCtrl = (event.stateMask & SWT.CTRL) != 0; 130 if (event.character > 0x20 && !(withAlt || withCtrl)) { 131 propertyTable.activateEditor(property, null); 132 m_dropDelayedText = "" + event.character; 133 } 134 } 135 136 //////////////////////////////////////////////////////////////////////////// 137 // 138 // Abstract methods 139 // 140 //////////////////////////////////////////////////////////////////////////// 141 /** 142 * Adds items to given {@link CComboBox}. 143 */ 144 protected abstract void addItems(Property property, CComboBox combo) throws Exception; 145 146 /** 147 * Selects current item in given {@link CCombo3}. 148 */ 149 protected void selectItem(Property property, CComboBox combo) throws Exception { 150 } 151 152 /** 153 * Transfers data from widget to {@link Property}. 154 */ 155 protected abstract void toPropertyEx(Property property, CComboBox combo) throws Exception; 156} 157