/******************************************************************************* * Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is 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: * Exadel, Inc. and Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.common.model.ui.attribute.editor; import java.text.MessageFormat; import org.jboss.tools.common.model.ui.IValueChangeListener; import org.jboss.tools.common.model.ui.IValueProvider; import org.jboss.tools.common.model.ui.attribute.AttributeContentProposalProviderFactory; import org.jboss.tools.common.model.ui.attribute.adapter.DefaultValueAdapter; import org.eclipse.jface.fieldassist.ContentProposalAdapter; import org.eclipse.jface.fieldassist.IContentProposalListener2; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.ImageRegistry; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.viewers.DialogCellEditor; import org.eclipse.swt.SWT; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.FocusListener; 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.TraverseEvent; import org.eclipse.swt.events.TraverseListener; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Text; import org.jboss.tools.common.meta.key.WizardKeys; import org.jboss.tools.common.model.ui.ModelUIPlugin; public class DialogCellEditorEx extends DialogCellEditor { //implements IValueEditor { protected Text text; protected String textValue = null; protected String startValue = null; private Button button; private static final int defaultStyle = SWT.NONE; private boolean skipDeactivate = Boolean.FALSE.booleanValue(); static { ImageRegistry reg = JFaceResources.getImageRegistry(); reg.put(CELL_EDITOR_IMG_DOTS_BUTTON, ImageDescriptor.createFromFile(DialogCellEditor.class, "images/dots_button.gif"));//$NON-NLS-1$ } // IValueEditor protected IValueChangeListener valueChangeListener; protected IValueProvider valueProvider; protected PropertyEditor propertyEditor; protected PropertyEditorDialog dialog; public DialogCellEditorEx() { setStyle(defaultStyle); } // constructors public DialogCellEditorEx(Composite parent) { this(parent, defaultStyle); } public DialogCellEditorEx(Composite parent, int style) { super(parent, style); } protected Control getTextControl() { return text; } protected Button getButtonControl() { return button; } // methods protected Button createButton(Composite parent) { Button result = new Button(parent, SWT.DOWN); result.addFocusListener(new FocusListener() { public void focusGained(FocusEvent e) { } public void focusLost(FocusEvent e) { DialogCellEditorEx.this.focusLost(); } }); result.setText("..."); //$NON-NLS-1$ return button = result; } protected Control createControl(Composite parent) { return (Composite)super.createControl(parent); } protected void doSetValue(Object value) { super.doSetValue(value); super.fireEditorValueChanged(true,false); } protected Object openDialogBox(Control cellEditorWindow) { if (propertyEditor!=null) { Object oldValue = ((IValueProvider)propertyEditor.getAdapter(IValueProvider.class)).getValue(); DefaultValueAdapter a = (DefaultValueAdapter)propertyEditor.getInput(); boolean auto = a.isAutoStore(); a.setAutoStore(false); propertyEditor.setValue(getValue()); if(propertyEditor.callsExternal()) { externalEditing = true; Object s = propertyEditor.callExternal(cellEditorWindow.getShell()); if(s != null && s.equals(oldValue)) s = null; if(s != null) { propertyEditor.setValue(s); } else { if(editable) text.forceFocus(); } a.setAutoStore(auto); externalEditing = false; return s; } dialog = new PropertyEditorDialog(ModelUIPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(),propertyEditor); dialog.create(); String title = MessageFormat.format("Edit {0}", WizardKeys.getAttributeDisplayName(a.getAttribute(), true)); dialog.getShell().setText(title); externalEditing = true; ExtendedFieldEditor fieldEditor = propertyEditor.getFieldEditor(null); int i = dialog.open(); if(i != 0) { propertyEditor.setValue(oldValue); a.setAutoStore(auto); if(editable) text.forceFocus(); this.externalEditing = false; return null; } //propertyEditor.setValue(this.doGetValue()); fieldEditor.store(); a.setAutoStore(auto); this.externalEditing = false; return ((IValueProvider)propertyEditor.getAdapter(IValueProvider.class)).getValue(); } return null; } public void setPropertyEditor(PropertyEditor editor) { propertyEditor = editor; if(editor != null) { addContentAssist(text); // IContentAssistProcessor processor = (IContentAssistProcessor)editor.getAdapter(IContentAssistProcessor.class); // if(processor != null) { // ControlContentAssistHelper.createTextContentAssistant(text, processor); // } } } // IValueEditor //public void setValueChangeListener(IValueChangeListener valueChangeListener) { // this.valueChangeListener = valueChangeListener; //} public void setValueProvider(IValueProvider valueProvider) { this.valueProvider = valueProvider; setValue(valueProvider.getValue()); } public Control getControl() { StackTraceElement[] es = new Throwable().getStackTrace(); if(es.length > 1) { if(es[1].getClassName().endsWith(".CellEditorActionHandler")) { return text; } } return super.getControl(); } protected Control createContents(Composite cell) { text = new Text(cell, SWT.LEFT); text.setFont(cell.getFont()); text.setBackground(cell.getBackground()); text.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { if ((byte)e.character == (byte)13) { // Enter if(popup.isPopupOpened) return; fireApplyEditorValue(); fireCancelEditor(); } doChecks(); } public void keyReleased(KeyEvent e) { if (e.character == '\u001b') { // Escape text.setText(startValue); fireCancelEditor(); } doChecks(); } }); text.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { if(modifyLock > 0) return; modifyLock++; doSetValue(textValue != null ? textValue : text.getText()); modifyLock--; } }); text.addFocusListener(new FocusListener() { public void focusGained(FocusEvent e) { } public void focusLost(FocusEvent e) { DialogCellEditorEx.this.focusLost(); } }); text.addMouseListener(new MouseAdapter() { public void mouseUp(MouseEvent e) { doChecks(); } }); text.addTraverseListener(new TraverseListener() { @Override public void keyTraversed(TraverseEvent e) { doChecks(); } }); return text; } protected void focusLost() { Control focusControl = Display.getCurrent().getFocusControl(); if (focusControl!=null && (focusControl.equals(button) || focusControl.equals(text))) return; if(skipDeactivate) return; if(!externalEditing) { String v = (textValue != null) ? textValue : text.getText(); modifyLock++; super.doSetValue(v); modifyLock--; super.focusLost(); } } protected boolean externalEditing = false; int modifyLock = 0; boolean editable = true; protected void updateContents(Object value) { if(modifyLock > 0) return; if (text == null) return; String txt = ""; //$NON-NLS-1$ if (value != null) txt = value.toString(); setTextEditable(!(txt.indexOf('\n') >= 0 || txt.indexOf('\r') >= 0)); if(!editable) { textValue = txt; txt = txt.replace('\n', ' ').replace('\t', ' ').replace('\r', ' '); } modifyLock++; text.setText(txt); super.doSetValue(value); modifyLock--; doSetFocus(); } void setTextEditable(boolean b) { if(editable == b) return; editable = b; text.setEditable(b); int c = (b) ? SWT.COLOR_BLACK : SWT.COLOR_GRAY; text.setForeground(Display.getDefault().getSystemColor(c)); } protected void doSetFocus() { if(editable && !externalEditing) { text.forceFocus(); text.setSelection(0, text.getText().length()); doChecks(); } } protected void fireApplyEditorValue() { super.fireApplyEditorValue(); if (propertyEditor!=null) { if (propertyEditor.getInput() instanceof DefaultValueAdapter) { if(((DefaultValueAdapter)propertyEditor.getInput()).isAutoStore()) fireCancelEditor(); } } else if(text != null && !text.isDisposed() && editable) text.forceFocus(); } protected void addContentAssist(Text text) { if(propertyEditor != null && propertyEditor.getInput() instanceof DefaultValueAdapter) { DefaultValueAdapter valueAdapter = (DefaultValueAdapter)propertyEditor.getInput(); AttributeContentProposalProviderFactory.registerContentAssist(valueAdapter, text, popup); } } protected CPL2 popup = new CPL2(); class CPL2 implements IContentProposalListener2 { boolean isPopupOpened = false; public void proposalPopupClosed(ContentProposalAdapter adapter) { isPopupOpened = false; } public void proposalPopupOpened(ContentProposalAdapter adapter) { isPopupOpened = true; } } protected void fireCancelEditor() { skipDeactivate = Boolean.TRUE.booleanValue(); super.fireCancelEditor(); skipDeactivate = Boolean.FALSE.booleanValue(); deactivate(); } public void activate() { super.activate(); skipDeactivate = false; if (text != null) { startValue = text.getText(); } } public void deactivate() { if (!this.skipDeactivate) { skipDeactivate = true; startValue = null; super.deactivate(); } } @Override public boolean isCopyEnabled() { if (text == null || text.isDisposed()) { return false; } return text.getSelectionCount() > 0; } @Override public boolean isCutEnabled() { return isCopyEnabled(); } @Override public boolean isDeleteEnabled() { return isCopyEnabled(); } @Override public boolean isPasteEnabled() { if (text == null || text.isDisposed()) { return false; } return true; } @Override public void performCopy() { text.copy(); } @Override public void performCut() { text.cut(); doChecks(); } @Override public void performDelete() { if (text.getSelectionCount() > 0) { // remove the contents of the current selection text.insert(""); //$NON-NLS-1$ } else { // remove the next character int pos = text.getCaretPosition(); if (pos < text.getCharCount()) { text.setSelection(pos, pos + 1); text.insert(""); //$NON-NLS-1$ } } doChecks(); } @Override public void performPaste() { text.paste(); doChecks(); } @Override public boolean isSelectAllEnabled() { if (text == null || text.isDisposed()) { return false; } return text.getCharCount() > 0; } @Override public void performSelectAll() { text.selectAll(); checkSelection(); checkDeleteable(); } private boolean isDeleteable = false; private boolean isSelectable = false; private boolean isSelection = false; private void checkDeleteable() { boolean oldIsDeleteable = isDeleteable; isDeleteable = isDeleteEnabled(); if (oldIsDeleteable != isDeleteable) { fireEnablementChanged(DELETE); } } private void checkSelectable() { boolean oldIsSelectable = isSelectable; isSelectable = isSelectAllEnabled(); if (oldIsSelectable != isSelectable) { fireEnablementChanged(SELECT_ALL); } } private void checkSelection() { boolean oldIsSelection = isSelection; isSelection = text.getSelectionCount() > 0; if (oldIsSelection != isSelection) { fireEnablementChanged(COPY); fireEnablementChanged(CUT); } } private void doChecks() { if(text != null && !text.isDisposed()) { checkSelection(); checkDeleteable(); checkSelectable(); } } }