Home | History | Annotate | Download | only in editor
      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  *******************************************************************************/
     11 package org.eclipse.wb.internal.core.model.property.editor;
     12 
     13 import org.eclipse.wb.core.controls.CCombo3;
     14 import org.eclipse.wb.core.controls.CComboBox;
     15 import org.eclipse.wb.internal.core.model.property.Property;
     16 import org.eclipse.wb.internal.core.model.property.table.PropertyTable;
     17 import org.eclipse.wb.internal.core.utils.execution.ExecutionUtils;
     18 import org.eclipse.wb.internal.core.utils.execution.RunnableEx;
     19 
     20 import org.eclipse.swt.SWT;
     21 import org.eclipse.swt.events.FocusAdapter;
     22 import org.eclipse.swt.events.FocusEvent;
     23 import org.eclipse.swt.events.KeyAdapter;
     24 import org.eclipse.swt.events.KeyEvent;
     25 import org.eclipse.swt.events.SelectionAdapter;
     26 import org.eclipse.swt.events.SelectionEvent;
     27 import org.eclipse.swt.graphics.Point;
     28 import 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  */
     39 public 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