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.internal.core.model.property.Property;
15import org.eclipse.wb.internal.core.model.property.table.PropertyTable;
16
17import org.eclipse.swt.SWT;
18import org.eclipse.swt.events.FocusAdapter;
19import org.eclipse.swt.events.FocusEvent;
20import org.eclipse.swt.events.MouseAdapter;
21import org.eclipse.swt.events.MouseEvent;
22import org.eclipse.swt.events.SelectionAdapter;
23import org.eclipse.swt.events.SelectionEvent;
24import org.eclipse.swt.graphics.Point;
25import org.eclipse.swt.graphics.Rectangle;
26import org.eclipse.swt.widgets.Event;
27import org.eclipse.swt.widgets.Listener;
28
29/**
30 * The {@link PropertyEditor} for selecting single value using {@link CCombo3}.
31 *
32 * @author scheglov_ke
33 * @coverage core.model.property.editor
34 */
35public abstract class AbstractComboPropertyEditor extends TextDisplayPropertyEditor {
36  ////////////////////////////////////////////////////////////////////////////
37  //
38  // Editing
39  //
40  ////////////////////////////////////////////////////////////////////////////
41  private CCombo3 m_combo;
42  private boolean m_doDropDown;
43
44  @Override
45  public boolean activate(final PropertyTable propertyTable, final Property property, Point location)
46      throws Exception {
47    // create combo
48    {
49      m_combo = new CCombo3(propertyTable, SWT.NONE);
50      m_doDropDown = true;
51      // add items
52      addItems(property, m_combo);
53      // select item
54      selectItem(property, m_combo);
55    }
56    // add listeners
57    m_combo.addFocusListener(new FocusAdapter() {
58      @Override
59      public void focusLost(FocusEvent e) {
60        propertyTable.deactivateEditor(true);
61      }
62    });
63    m_combo.addSelectionListener(new SelectionAdapter() {
64      @Override
65      public void widgetSelected(SelectionEvent e) {
66        int index = m_combo.getSelectionIndex();
67        toProperty(propertyTable, property, index);
68      }
69    });
70    m_combo.addListener(SWT.KeyDown, new Listener() {
71      public void handleEvent(Event event) {
72        switch (event.keyCode) {
73          case SWT.ESC :
74            propertyTable.deactivateEditor(false);
75            break;
76          case SWT.DEL :
77            try {
78              property.setValue(Property.UNKNOWN_VALUE);
79              event.doit = false;
80              selectItem(property, m_combo);
81            } catch (Throwable e) {
82              propertyTable.handleException(e);
83              propertyTable.deactivateEditor(false);
84            }
85            m_combo.doDropDown(false);
86            break;
87        }
88      }
89    });
90    m_combo.addMouseListener(new MouseAdapter() {
91      @Override
92      public void mouseDoubleClick(MouseEvent e) {
93        int index = (m_combo.getSelectionIndex() + 1) % m_combo.getItemCount();
94        toProperty(propertyTable, property, index);
95      }
96    });
97    // keep editor active
98    return true;
99  }
100
101  @Override
102  public final void setBounds(Rectangle bounds) {
103    m_combo.setBounds(bounds);
104    // editor created without bounds, so activate it after first setBounds()
105    if (m_doDropDown) {
106      m_doDropDown = false;
107      m_combo.setFocus();
108      m_combo.doDropDown(true);
109      m_combo.startDrag();
110    }
111  }
112
113  @Override
114  public final void deactivate(PropertyTable propertyTable, Property property, boolean save) {
115    if (m_combo != null) {
116      m_combo.dispose();
117      m_combo = null;
118    }
119  }
120
121  ////////////////////////////////////////////////////////////////////////////
122  //
123  // Abstract methods
124  //
125  ////////////////////////////////////////////////////////////////////////////
126  /**
127   * Adds items to given {@link CCombo3}.
128   */
129  protected abstract void addItems(Property property, CCombo3 combo) throws Exception;
130
131  /**
132   * Selects current item in given {@link CCombo3}.
133   */
134  protected abstract void selectItem(Property property, CCombo3 combo) throws Exception;
135
136  /**
137   * Transfers data from widget to {@link Property}.
138   */
139  protected abstract void toPropertyEx(Property property, CCombo3 combo, int index)
140      throws Exception;
141
142  /**
143   * Transfers data from widget to {@link Property}.
144   */
145  private void toProperty(PropertyTable propertyTable, Property property, int index) {
146    try {
147      toPropertyEx(property, m_combo, index);
148    } catch (Throwable e) {
149      propertyTable.handleException(e);
150    }
151    propertyTable.deactivateEditor(false);
152  }
153}
154