Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/infra/widget/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StyledTextReferenceDialog.java')
-rw-r--r--plugins/infra/widget/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StyledTextReferenceDialog.java750
1 files changed, 750 insertions, 0 deletions
diff --git a/plugins/infra/widget/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StyledTextReferenceDialog.java b/plugins/infra/widget/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StyledTextReferenceDialog.java
new file mode 100644
index 00000000000..a00452dd51f
--- /dev/null
+++ b/plugins/infra/widget/org.eclipse.papyrus.infra.widgets/src/org/eclipse/papyrus/infra/widgets/editors/StyledTextReferenceDialog.java
@@ -0,0 +1,750 @@
+/*****************************************************************************
+ * Copyright (c) 2013 CEA LIST.
+ *
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
+ * Nicolas FAUVERGUE (ALL4TECą nicolas.fauvergue@all4tec.net - Bug 459747
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.widgets.editors;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.jface.fieldassist.ControlDecoration;
+import org.eclipse.jface.fieldassist.FieldDecoration;
+import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.window.Window;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.papyrus.infra.widgets.Activator;
+import org.eclipse.papyrus.infra.widgets.creation.ReferenceValueFactory;
+import org.eclipse.papyrus.infra.widgets.databinding.StyledTextReferenceDialogObservableValue;
+import org.eclipse.papyrus.infra.widgets.messages.Messages;
+import org.eclipse.papyrus.infra.widgets.providers.EncapsulatedContentProvider;
+import org.eclipse.papyrus.infra.widgets.providers.IAdaptableContentProvider;
+import org.eclipse.papyrus.infra.widgets.providers.IStaticContentProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Widget;
+
+/**
+ * An editor representing a single reference as a String Editor. A filtered selection
+ * dialog is used to edit the value. Also offers support for unsetting the
+ * value. This Editor needs a ContentProvider, and may use an optional
+ * LabelProvider, describing the objects that can be referred by this property
+ *
+ * @author Vincent Lorenzo
+ *
+ * Duplicated code from {@link ReferenceDialog}, replacing CLabel by {@link StyledTextStringEditor}
+ *
+ */
+public class StyledTextReferenceDialog extends AbstractValueEditor implements SelectionListener {
+
+ /**
+ * The styled text displaying the current value
+ */
+ protected final StyledTextStringEditor styledTextStringEditor;
+
+ /**
+ * The Button used to browse the available values
+ */
+ protected Button browseValuesButton;
+
+ /**
+ * The Button used to create a new instance
+ */
+ protected Button createInstanceButton;
+
+ /**
+ * The Button used to edit the current object
+ */
+ protected Button editInstanceButton;
+
+ /**
+ * The Button used to unset the current value
+ */
+ protected Button unsetButton;
+
+ /**
+ * The label provider used to display the values in both the label and the
+ * selection dialog
+ */
+ protected ILabelProvider labelProvider;
+
+ /**
+ * The content provider, providing the different possible values for the
+ * input object
+ */
+ protected IStaticContentProvider contentProvider;
+
+ /**
+ * The dialog used to select the value
+ */
+ protected final ITreeSelectorDialog dialog;
+
+ /**
+ * The current value for this editor
+ */
+ protected Object value;
+
+ /**
+ * The factory used to create or edit objects directly from this editor
+ */
+ protected ReferenceValueFactory valueFactory;
+
+ /**
+ * Indicates whether the widget is read-only or not
+ */
+ protected boolean readOnly;
+
+ /**
+ * Boolean to detect direct creation.
+ */
+ private boolean directCreation;
+
+ /**
+ * Indicates whether the widget requires a value or not. If it is mandatory,
+ * it cannot delete/unset its value
+ */
+ protected boolean mandatory;
+
+ /**
+ * The control decoration of the styled text.
+ */
+ private ControlDecoration controlDecoration;
+
+ /**
+ * Determinate if an error occurred.
+ */
+ protected boolean error = false;
+
+ /**
+ * The timer.
+ */
+ private Timer timer;
+
+ /**
+ * The timer tack for the change color.
+ */
+ private TimerTask changeColorTask;
+
+ /**
+ * Determinate if an edit occurred.
+ */
+ private boolean edit = false;
+
+ /**
+ * Constructs a new ReferenceDialog in the given parent Composite. The style
+ * will be applied to the syled text displaying the current value.
+ *
+ * @param parent
+ * The parent composite.
+ * @param style
+ * The style of the styled text.
+ */
+ public StyledTextReferenceDialog(final Composite parent, final int style) {
+ super(parent, style);
+ GridData gridData = getDefaultLayoutData();
+
+ styledTextStringEditor = createStyledTextStringEditor(this, null, factory.getBorderStyle() | style);
+ styledTextStringEditor.setLayoutData(gridData);
+ styledTextStringEditor.addMouseListener(new MouseListener() {
+
+ @Override
+ public void mouseDoubleClick(MouseEvent e) {
+ editAction(); // TODO : Try to determine whether the double
+ // click should call the edit, create or browse
+ // action
+ // e.g. if the value is null, try to browse. If we cannot
+ // browse, try to create an instance.
+ }
+
+ @Override
+ public void mouseDown(MouseEvent e) {
+ // Nothing
+ }
+
+ @Override
+ public void mouseUp(MouseEvent e) {
+ // Nothing
+ }
+
+ });
+
+ dialog = createDialog(parent.getShell());
+
+ createButtons();
+ updateControls();
+ controlDecoration = new ControlDecoration(styledTextStringEditor, SWT.TOP | SWT.LEFT);
+
+ gridData.horizontalIndent = FieldDecorationRegistry.getDefault().getMaximumDecorationWidth();
+ }
+
+ /**
+ * This allow to create the styled text editor.
+ *
+ * @param parent
+ * The parent composite.
+ * @param initialValue
+ * The initial value of the styled text.
+ * @param style
+ * The style of the styled text.
+ * @return The created {@link StyledTextStringEditor}.
+ */
+ protected StyledTextStringEditor createStyledTextStringEditor(final Composite parent, final String initialValue, final int style) {
+ StyledTextStringEditor editor = new StyledTextStringEditor(parent, style);
+ editor.setValue(initialValue);
+ return editor;
+ }
+
+ /**
+ * This allow to create the dialog.
+ *
+ * @param shell
+ * The current shell.
+ * @return The created {@link ITreeSelectorDialog}.
+ */
+ protected ITreeSelectorDialog createDialog(final Shell shell) {
+ return new TreeSelectorDialog(shell);
+ }
+
+ /**
+ * This allow to create the buttons of the reference dialog (browse, create, edit and unset).
+ */
+ protected void createButtons() {
+ ((GridLayout) getLayout()).numColumns += 4;
+
+ browseValuesButton = factory.createButton(this, null, SWT.PUSH);
+ browseValuesButton.setImage(Activator.getDefault().getImage("/icons/browse_12x12.gif")); //$NON-NLS-1$
+ browseValuesButton.setToolTipText(Messages.ReferenceDialog_EditValue);
+ browseValuesButton.addSelectionListener(this);
+
+ createInstanceButton = factory.createButton(this, null, SWT.PUSH);
+ createInstanceButton.setImage(Activator.getDefault().getImage("/icons/Add_12x12.gif")); //$NON-NLS-1$
+ createInstanceButton.setToolTipText(Messages.ReferenceDialog_CreateANewObject);
+ createInstanceButton.addSelectionListener(this);
+
+ editInstanceButton = factory.createButton(this, null, SWT.PUSH);
+ editInstanceButton.setImage(Activator.getDefault().getImage("/icons/Edit_12x12.gif")); //$NON-NLS-1$
+ editInstanceButton.setToolTipText(Messages.ReferenceDialog_EditTheCurrentValue);
+ editInstanceButton.addSelectionListener(this);
+
+ unsetButton = factory.createButton(this, null, SWT.PUSH);
+ unsetButton.setImage(Activator.getDefault().getImage("/icons/Delete_12x12.gif")); //$NON-NLS-1$
+ unsetButton.setToolTipText(Messages.ReferenceDialog_UnsetValue);
+ unsetButton.addSelectionListener(this);
+ }
+
+ /**
+ * The action executed when the "browse" button is selected Choose a value
+ * from a selection of already created objects
+ */
+ protected void browseAction() {
+ setInitialSelection(Collections.singletonList(getValue()));
+ int result = dialog.open();
+ if (result == Window.OK) {
+ Object[] newValue = dialog.getResult();
+ if (newValue == null) {
+ return;
+ }
+
+ if (newValue.length == 0) {
+ setValue(null);
+ } else {
+ Object value = newValue[0];
+ if (contentProvider instanceof IAdaptableContentProvider) {
+
+ value = ((IAdaptableContentProvider) contentProvider).getAdaptedValue(value);
+ }
+ setValue(value);
+ styledTextStringEditor.setValue(labelProvider.getText(newValue));
+ }
+ }
+ }
+
+ /**
+ * The action executed when the "create" button is selected Create a new
+ * instance and assign it to this reference
+ */
+ protected void createAction() {
+ if (valueFactory != null && valueFactory.canCreateObject()) {
+ final Object context = getContextElement();
+ getOperationExecutor(context).execute(new Runnable() {
+
+ @Override
+ public void run() {
+ Object value = valueFactory.createObject(createInstanceButton, context);
+ if (value == null) {
+ // Cancel the operation
+ throw new OperationCanceledException();
+ }
+ Collection<Object> validatedObjects = valueFactory.validateObjects(Collections.singleton(value));
+ if (!validatedObjects.isEmpty()) {
+ final Object newValue = validatedObjects.iterator().next();
+ setValue(newValue);
+ styledTextStringEditor.setValue(labelProvider.getText(newValue));
+ }
+ }
+ }, NLS.bind(Messages.ReferenceDialog_setOperation, labelText));
+ }
+ }
+
+ /**
+ * The action executed when the "edit" button is selected Edits the object
+ * that is currently selected
+ */
+ protected void editAction() {
+ styledTextStringEditor.setBackground(EDIT);
+ edit = true;
+ final Object currentValue = getValue();
+ if (currentValue != null && valueFactory != null && valueFactory.canEdit()) {
+ getOperationExecutor(currentValue).execute(new Runnable() {
+
+ @Override
+ public void run() {
+ Object newValue = valueFactory.edit(editInstanceButton, currentValue);
+
+ // Per the contract of ReferenceValueFactory::edit(), a null return means the object was edited "in place."
+ // In that case, there is nothing further to do
+ if (newValue != null) {
+ setValue(newValue);
+ styledTextStringEditor.setValue(labelProvider.getText(newValue));
+ }
+
+ updateLabel();
+ }
+ }, NLS.bind(Messages.ReferenceDialog_editOperation, labelText));
+ }
+ }
+
+ /**
+ * The action executed when the "unset" button is selected Sets the current
+ * reference to null
+ */
+ protected void unsetAction() {
+ setValue(null);
+ }
+
+ /**
+ * Updates the displayed label for the current value
+ */
+ protected void updateLabel() {
+ if (binding != null) {
+ binding.updateModelToTarget();
+
+ } else {
+ styledTextStringEditor.setValue(labelProvider.getText(getValue()));
+ }
+ }
+
+ /**
+ * Sets the Content provider for this editor
+ *
+ * @param provider
+ * The content provider used to retrieve the possible values for
+ * this Reference
+ */
+ public void setContentProvider(final IStaticContentProvider provider) {
+ dialog.setContentProvider(new EncapsulatedContentProvider(provider));
+ if (getValue() != null) {
+ setInitialSelection(Collections.singletonList(getValue()));
+ }
+
+ this.contentProvider = provider;
+ }
+
+ /**
+ * Sets the Label provider for this editor If the label provider is null, a
+ * default one will be used. The same label provider is used for both the
+ * editor's label and the selection dialog.
+ *
+ * @param provider
+ * The label provider
+ */
+ public void setLabelProvider(final ILabelProvider provider) {
+ if (provider == null) {
+ setLabelProvider(new LabelProvider());
+ return;
+ }
+
+ dialog.setLabelProvider(provider);
+ this.labelProvider = provider;
+ if (widgetObservable != null) {
+ ((StyledTextReferenceDialogObservableValue) widgetObservable).setLabelProvider(labelProvider);
+ }
+ updateLabel();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setLabel(final String label) {
+ super.setLabel(label);
+ dialog.setTitle(label);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getValue() {
+ if (modelProperty != null) {
+ Object modelPropertyValue = modelProperty.getValue();
+ if(modelPropertyValue == null){
+ EObject contextElement = getContextElement() != null && getContextElement() instanceof EObject ? (EObject) getContextElement() : null;
+ if(modelProperty.getValueType() instanceof EStructuralFeature){
+ return contextElement.eGet((EStructuralFeature)modelProperty.getValueType());
+ }
+ }
+ return modelPropertyValue;
+ }
+ return value;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getEditableType() {
+ return Object.class;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setReadOnly(boolean readOnly) {
+ this.readOnly = readOnly;
+ updateControls();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isReadOnly() {
+ return !styledTextStringEditor.isEnabled();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void doBinding() {
+ super.doBinding();
+ }
+
+ /**
+ * Set the initial selection.
+ *
+ * @param initialValues
+ * The list of possible values.
+ */
+ protected void setInitialSelection(final List<?> initialValues) {
+ dialog.setInitialElementSelections(initialValues);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.AbstractValueEditor#setModelObservable(org.eclipse.core.databinding.observable.value.IObservableValue)
+ */
+ @Override
+ public void setModelObservable(final IObservableValue modelProperty) {
+ setWidgetObservable(createWidgetObservable(modelProperty));
+ super.setModelObservable(modelProperty);
+ this.styledTextStringEditor.setModelObservable(modelProperty);
+
+ updateControls();
+ }
+
+ /**
+ * This allow to create the widget observable value.
+ *
+ * @param modelProperty
+ * The current observable value.
+ * @return The created {@link StyledTextReferenceDialogObservableValue}.
+ */
+ protected IObservableValue createWidgetObservable(final IObservableValue modelProperty) {
+ return new StyledTextReferenceDialogObservableValue(this, this.styledTextStringEditor.getText(), modelProperty, SWT.FocusOut, labelProvider);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swt.widgets.Control#setToolTipText(java.lang.String)
+ */
+ @Override
+ public void setToolTipText(final String text) {
+ super.setLabelToolTipText(text);
+ styledTextStringEditor.setToolTipText(text);
+ }
+
+ /**
+ * Set the factory.
+ *
+ * @param factory
+ * The reference value factory.
+ */
+ public void setValueFactory(final ReferenceValueFactory factory) {
+ valueFactory = factory;
+ updateControls();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ @Override
+ public void widgetSelected(final SelectionEvent e) {
+ Widget widget = e.widget;
+ if (widget == browseValuesButton) {
+ browseAction();
+ } else if (widget == createInstanceButton) {
+ createAction();
+ } else if (widget == editInstanceButton) {
+ editAction();
+ } else if (widget == unsetButton) {
+ unsetAction();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
+ */
+ @Override
+ public void widgetDefaultSelected(final SelectionEvent e) {
+ // Nothing
+ }
+
+ /**
+ * Updates the buttons' status
+ */
+ protected void updateControls() {
+ // Check if the edit & create buttons should be displayed
+ boolean exclude = valueFactory == null || !valueFactory.canCreateObject();
+ setExclusion(editInstanceButton, exclude);
+ setExclusion(createInstanceButton, exclude);
+
+ setExclusion(browseValuesButton, directCreation);
+
+ browseValuesButton.setEnabled(!readOnly);
+
+ // If they are displayed, check if they should be enabled
+ if (!exclude) {
+ editInstanceButton.setEnabled(valueFactory != null && valueFactory.canEdit() && getValue() != null);
+ createInstanceButton.setEnabled(valueFactory != null && valueFactory.canCreateObject() && !readOnly);
+ }
+
+ // Do not display unset if the value is mandatory
+ setExclusion(unsetButton, mandatory);
+ if (!mandatory) {
+ boolean enabled = !readOnly;
+ enabled = enabled && getValue() != null;
+
+ unsetButton.setEnabled(enabled);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swt.widgets.Control#update()
+ */
+ @Override
+ public void update() {
+ super.update();
+ updateControls();
+ }
+
+ /**
+ * Set the direct creation value.
+ *
+ * @param directCreation
+ * Boolean to determinate the direct creation value.
+ */
+ public void setDirectCreation(final boolean directCreation) {
+ this.directCreation = directCreation;
+ updateControls();
+ }
+
+ /**
+ * Set the value.
+ *
+ * @param value
+ * The value object.
+ */
+ public void setValue(final Object value) {
+ this.value = value;
+ try {
+ if (modelProperty != null) {
+ modelProperty.setValue(value);
+ error = false;
+ }
+ } catch (Exception e) {
+ error = true;
+
+ }
+
+ updateControls();
+ updateLabel();
+ commit();
+ }
+
+ /**
+ * @see org.eclipse.jface.viewers.StructuredViewer#setInput(Object)
+ * @param input
+ * The current input;
+ */
+ public void setInput(final Object input) {
+ this.dialog.setInput(input);
+ }
+
+ /**
+ * Set the mandatory.
+ *
+ * @param mandatory
+ * The mandatory boolean value.
+ */
+ public void setMandatory(final boolean mandatory) {
+ this.mandatory = mandatory;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.AbstractValueEditor#updateStatus(org.eclipse.core.runtime.IStatus)
+ */
+ @Override
+ public void updateStatus(final IStatus status) {
+
+ if (error) {
+ FieldDecoration error = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_ERROR);
+ controlDecoration.setImage(error.getImage());
+ controlDecoration.showHoverText(Messages.ReferenceDialog_0);
+ controlDecoration.setDescriptionText(Messages.ReferenceDialog_1);
+ controlDecoration.show();
+ styledTextStringEditor.setBackground(ERROR);
+ styledTextStringEditor.update();
+
+
+ } else {
+ controlDecoration.hide();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swt.widgets.Widget#dispose()
+ */
+ @Override
+ public void dispose() {
+ if (changeColorTask != null) {
+ changeColorTask.cancel();
+ }
+ if (timer != null) {
+ timer.cancel();
+ }
+ super.dispose();
+ }
+
+ /**
+ * This allow to react of cancel of the current task.
+ */
+ private void cancelCurrentTask() {
+ if (changeColorTask != null) {
+ changeColorTask.cancel();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.papyrus.infra.widgets.editors.AbstractEditor#changeColorField()
+ */
+ @Override
+ public void changeColorField() {
+ if (!error & !edit) {
+
+ if (timer == null) {
+ timer = new Timer(true);
+ }
+
+ cancelCurrentTask();
+ changeColorTask = new TimerTask() {
+
+ @Override
+ public void run() {
+ if (StyledTextReferenceDialog.this.isDisposed()) {
+ return;
+ }
+ StyledTextReferenceDialog.this.getDisplay().syncExec(new Runnable() {
+
+ @Override
+ public void run() {
+ if (StyledTextReferenceDialog.this.isDisposed()) {// Bug 434787 : Shouldn't not execute the timer thread if the widget is disposed
+ return;
+ }
+ styledTextStringEditor.setBackground(DEFAULT);
+ styledTextStringEditor.update();
+ }
+
+
+ });
+ }
+ };
+
+ if (errorBinding) {
+ styledTextStringEditor.setBackground(ERROR);
+ styledTextStringEditor.update();
+ } else {
+ IStatus status = (IStatus) binding.getValidationStatus().getValue();
+ switch (status.getSeverity()) {
+ case IStatus.OK:
+ case IStatus.WARNING:
+ timer.schedule(changeColorTask, 600);
+ styledTextStringEditor.setBackground(VALID);
+ styledTextStringEditor.update();
+ break;
+ case IStatus.ERROR:
+ styledTextStringEditor.setBackground(ERROR);
+ styledTextStringEditor.update();
+ break;
+
+ }
+ }
+ } else {
+ styledTextStringEditor.setBackground(DEFAULT);
+ }
+ }
+
+}

Back to the top