blob: b9d4e33464af28aac83eead86d211d8dfc47ebde [file] [log] [blame]
/*
* Copyright (c) 2006 Borland Software Corporation
*
* 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:
* Tatiana Fesenko (Borland) - initial API and implementation
*/
package org.eclipse.uml2.diagram.common.sheet;
import java.text.MessageFormat;
import java.util.List;
import org.eclipse.emf.common.ui.celleditor.ExtendedComboBoxCellEditor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.common.util.WrappedException;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.window.Window;
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.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.uml2.diagram.common.part.UMLElementChooserDialog;
public class ReferenceComboAndDialogCellEditor extends ExtendedComboBoxCellEditor {
private Composite myEditor;
private Control myContents;
private Button myButton;
private FocusListener myButtonFocusListener;
final private UMLElementChooserDialog myElementChooserDialog;
final private TransactionalEditingDomain myEditingDomain;
public ReferenceComboAndDialogCellEditor(Composite parent, List<?> list, ILabelProvider labelProvider, boolean sorted, UMLElementChooserDialog chooserDialog, TransactionalEditingDomain editingDomain) {
super(parent, list, labelProvider, sorted);
myEditingDomain = editingDomain;
myElementChooserDialog = chooserDialog;
}
@Override
protected Control createControl(Composite parent) {
Font font = parent.getFont();
Color bg = parent.getBackground();
myEditor = new Composite(parent, getStyle());
myEditor.setFont(font);
myEditor.setBackground(bg);
myEditor.setLayout(new DialogCellLayout());
myContents = super.createControl(myEditor);
myButton = createOpenDialogButton(myEditor);
setValueValid(true);
return myEditor;
}
protected Object openDialogBox(Control cellEditorWindow) {
if (myElementChooserDialog.open() == Window.OK) {
URI uri = myElementChooserDialog.getSelectedModelElementURI();
try {
return myEditingDomain.getResourceSet().getEObject(uri, true);
} catch (WrappedException e) {
e.printStackTrace();
return null;
}
}
return null;
}
@Override
public void deactivate() {
if (myButton != null && !myButton.isDisposed()) {
myButton.removeFocusListener(getButtonFocusListener());
}
super.deactivate();
}
@Override
protected void doSetFocus() {
myButton.setFocus();
myButton.addFocusListener(getButtonFocusListener());
}
private Button createOpenDialogButton(Composite parent) {
myButton = new Button(parent, SWT.DOWN);
myButton.setText("..."); //$NON-NLS-1$
myButton.setFont(parent.getFont());
myButton.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent e) {
if (e.character == '\u001b') { // Escape
fireCancelEditor();
}
}
});
myButton.addFocusListener(getButtonFocusListener());
myButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
// Remove the button's focus listener since it's guaranteed
// to lose focus when the dialog opens
myButton.removeFocusListener(getButtonFocusListener());
Object newValue = openDialogBox(myEditor);
// Re-add the listener once the dialog closes
myButton.addFocusListener(getButtonFocusListener());
if (newValue != null) {
boolean newValidState = isCorrect(newValue);
if (newValidState) {
markDirty();
doSetValue(newValue);
} else {
// try to insert the current value into the error
// message.
setErrorMessage(MessageFormat.format(getErrorMessage(), new Object[] { newValue.toString() }));
}
fireApplyEditorValue();
}
}
});
return myButton;
}
private FocusListener getButtonFocusListener() {
if (myButtonFocusListener == null) {
myButtonFocusListener = new FocusListener() {
public void focusGained(FocusEvent e) {
// Do nothing
}
public void focusLost(FocusEvent e) {
// CellEditor.this.focusLost();
}
};
}
return myButtonFocusListener;
}
private class DialogCellLayout extends Layout {
@Override
public void layout(Composite editor, boolean force) {
Rectangle bounds = editor.getClientArea();
Point size = myButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, force);
if (myContents != null) {
myContents.setBounds(0, 0, bounds.width - size.x, bounds.height);
}
myButton.setBounds(bounds.width - size.x, 0, size.x, bounds.height);
}
@Override
public Point computeSize(Composite editor, int wHint, int hHint, boolean force) {
if (wHint != SWT.DEFAULT && hHint != SWT.DEFAULT) {
return new Point(wHint, hHint);
}
Point contentsSize = myContents.computeSize(SWT.DEFAULT, SWT.DEFAULT, force);
Point buttonSize = myButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, force);
// Just return the button width to ensure the button is not clipped
// if the label is long.
// The label will just use whatever extra width there is
Point result = new Point(buttonSize.x, Math.max(contentsSize.y, buttonSize.y));
return result;
}
}
}