/*******************************************************************************
* 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();
}
}
}