| /******************************************************************************* |
| * <copyright> |
| * |
| * Copyright (c) 2005, 2010 SAP AG. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * SAP AG - initial API, implementation and documentation |
| * |
| * </copyright> |
| * |
| *******************************************************************************/ |
| package org.eclipse.graphiti.ui.internal.parts.directedit; |
| |
| import org.eclipse.graphiti.func.IProposal; |
| import org.eclipse.jface.dialogs.PopupDialog; |
| import org.eclipse.jface.fieldassist.ContentProposalAdapter; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.FocusAdapter; |
| import org.eclipse.swt.events.FocusEvent; |
| import org.eclipse.swt.events.KeyAdapter; |
| import org.eclipse.swt.events.KeyEvent; |
| import org.eclipse.swt.events.ModifyEvent; |
| import org.eclipse.swt.events.ModifyListener; |
| import org.eclipse.swt.events.MouseAdapter; |
| import org.eclipse.swt.events.MouseEvent; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.events.TraverseEvent; |
| import org.eclipse.swt.events.TraverseListener; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.swt.widgets.Text; |
| |
| /** |
| * This class subclasses <code>org.eclipse.jface.viewers.TextCellEditor</code> |
| * to overwrite the method <code>createControl</code> and by doing so to handle |
| * an undesired side-effect in combination with the usage of |
| * <code>org.eclipse.jface.fieldassist.ContentProposalAdapter</code>. (For more |
| * details see method <code>public void focusLost(FocusEvent e)</code>) |
| * |
| * @see TextCellEditor |
| * @see ContentProposalAdapter |
| * @noinstantiate This class is not intended to be instantiated by clients. |
| * @noextend This class is not intended to be subclassed by clients. |
| */ |
| public class TextCellEditor extends org.eclipse.jface.viewers.TextCellEditor { |
| private static final int defaultStyle = SWT.SINGLE; |
| |
| private ModifyListener modifyListener; |
| private IProposal acceptedProposal = null; |
| |
| /** |
| * State information for updating action enablement |
| */ |
| private boolean isSelection = false; |
| |
| private boolean isDeleteable = false; |
| |
| private boolean isSelectable = false; |
| |
| public TextCellEditor() { |
| this.setStyle(defaultStyle); |
| } |
| |
| public TextCellEditor(Composite parent) { |
| this(parent, defaultStyle); |
| } |
| |
| public TextCellEditor(Composite parent, int style) { |
| super(parent, style); |
| } |
| |
| /** |
| * Checks to see if the "deletable" state (can delete/ nothing to delete) |
| * has changed and if so fire an enablement changed notification. |
| */ |
| private void checkDeleteable() { |
| boolean oldIsDeleteable = isDeleteable; |
| isDeleteable = isDeleteEnabled(); |
| if (oldIsDeleteable != isDeleteable) { |
| fireEnablementChanged(DELETE); |
| } |
| } |
| |
| /** |
| * Checks to see if the "selectable" state (can select) has changed and if |
| * so fire an enablement changed notification. |
| */ |
| private void checkSelectable() { |
| boolean oldIsSelectable = isSelectable; |
| isSelectable = isSelectAllEnabled(); |
| if (oldIsSelectable != isSelectable) { |
| fireEnablementChanged(SELECT_ALL); |
| } |
| } |
| |
| /** |
| * Checks to see if the selection state (selection / no selection) has |
| * changed and if so fire an enablement changed notification. |
| */ |
| private void checkSelection() { |
| boolean oldIsSelection = isSelection; |
| isSelection = text.getSelectionCount() > 0; |
| if (oldIsSelection != isSelection) { |
| fireEnablementChanged(COPY); |
| fireEnablementChanged(CUT); |
| } |
| } |
| |
| @Override |
| protected Control createControl(Composite parent) { |
| text = new Text(parent, getStyle()); |
| text.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetDefaultSelected(SelectionEvent e) { |
| handleDefaultSelection(e); |
| } |
| }); |
| text.addKeyListener(new KeyAdapter() { |
| // hook key pressed - see PR 14201 |
| @Override |
| public void keyPressed(KeyEvent e) { |
| |
| /* |
| * seems that there is no SelectionEvent from the multi line |
| * text editor so we have to mimic the behavior by calling the |
| * handleDefaultSelection method. |
| */ |
| if (text != null && !text.isDisposed() && (text.getStyle() & SWT.MULTI) != 0) { // multi |
| // line |
| // cell |
| // // |
| // editor? |
| if (e.character == SWT.CR && ((e.stateMask & SWT.SHIFT) == 0)) { // exclude |
| // 'shift |
| // return' |
| handleDefaultSelection(null); |
| } |
| } |
| |
| keyReleaseOccured(e); |
| |
| // as a result of processing the above call, clients may have |
| // disposed this cell editor |
| if ((getControl() == null) || getControl().isDisposed()) { |
| return; |
| } |
| checkSelection(); // see explanation below |
| checkDeleteable(); |
| checkSelectable(); |
| } |
| |
| }); |
| text.addTraverseListener(new TraverseListener() { |
| public void keyTraversed(TraverseEvent e) { |
| if (e.detail == SWT.TRAVERSE_ESCAPE || e.detail == SWT.TRAVERSE_RETURN) { |
| e.doit = false; |
| } |
| } |
| }); |
| // We really want a selection listener but it is not supported so we |
| // use a key listener and a mouse listener to know when selection |
| // changes |
| // may have occurred |
| text.addMouseListener(new MouseAdapter() { |
| @Override |
| public void mouseUp(MouseEvent e) { |
| checkSelection(); |
| checkDeleteable(); |
| checkSelectable(); |
| } |
| }); |
| text.addFocusListener(new FocusAdapter() { |
| @Override |
| public void focusLost(FocusEvent e) { |
| // prevent the execution of focusLost() (and thereby |
| // fireApplyEditorValue()) if the ContentProposalPopup (see |
| // ContentProposalAdapter) gets focused by a mouse-click |
| if (e.display != null) { |
| Shell shell = e.display.getActiveShell(); |
| if (shell != null) { |
| Object data = shell.getData(); |
| if (data != null) { |
| if (data instanceof PopupDialog) { |
| return; |
| } |
| } |
| } |
| } |
| |
| TextCellEditor.this.focusLost(); |
| } |
| }); |
| text.setFont(parent.getFont()); |
| text.setBackground(parent.getBackground()); |
| text.setText("");//$NON-NLS-1$ |
| text.addModifyListener(getModifyListener()); |
| return text; |
| } |
| |
| // /* |
| // * Answer true if the popup is valid, which means the table has been |
| // * created and not disposed. |
| // */ |
| // private boolean isValid() { |
| // return true; |
| // } |
| |
| /** |
| * Return the modify listener. |
| */ |
| private ModifyListener getModifyListener() { |
| if (modifyListener == null) { |
| modifyListener = new ModifyListener() { |
| public void modifyText(ModifyEvent e) { |
| editOccured(e); |
| } |
| }; |
| } |
| return modifyListener; |
| } |
| |
| /** |
| * @return the acceptedProposal |
| */ |
| public IProposal getAcceptedProposal() { |
| return acceptedProposal; |
| } |
| |
| /** |
| * @param acceptedProposal |
| * the acceptedProposal to set |
| */ |
| public void setAcceptedProposal(IProposal acceptedProposal) { |
| this.acceptedProposal = acceptedProposal; |
| } |
| } |