/*******************************************************************************
* Copyright (c) 2006-2013 The RCP Company and others.
* 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:
* The RCP Company - initial API and implementation
*******************************************************************************/
package com.rcpcompany.uibindings.views;
import org.eclipse.core.databinding.observable.IObservable;
import org.eclipse.core.databinding.observable.list.IListChangeListener;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.list.ListChangeEvent;
import org.eclipse.core.databinding.observable.masterdetail.IObservableFactory;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.ViewPart;
import com.rcpcompany.uibindings.Constants;
import com.rcpcompany.uibindings.IBindingContext;
import com.rcpcompany.uibindings.IBindingMessage;
import com.rcpcompany.uibindings.IBindingMessageTarget;
import com.rcpcompany.uibindings.utils.IBindingContextSelectionProvider;
import com.rcpcompany.uibindings.utils.IDnDSupport;
import com.rcpcompany.uibindings.utils.ITableCreator;
import com.rcpcompany.uibindings.validators.IValidatorAdapterManager;
/**
* Simple view that shows the current validation status.
* <p>
* To get objects to be propertly shown in the view, they should support the decorator type
* {@link Constants#TYPE_LONG_NAME}.
*
* @author Tonny Madsen, The RCP Company
*/
public class ValidationView extends ViewPart {
private final IValidatorAdapterManager myVAM = IValidatorAdapterManager.Factory.getManager();
/* package */ITableCreator myTable; // For testing
private IBindingContext myContext;
/* package */Composite myTop; // For testing
/**
* The current messages in the view.
*/
protected IObservableList myMessages;
private final IListChangeListener myMessageListListener = new IListChangeListener() {
@Override
public void handleListChange(ListChangeEvent event) {
updateViewTooltip();
}
};
/**
* Updates the tooltip on the view tab.
*/
protected void updateViewTooltip() {
if (myMessages.size() == 0) {
setTitleToolTip(null);
return;
}
int errors = 0, warnings = 0, infos = 0;
for (final Object o : myMessages) {
switch (((IBindingMessage) o).getSeverity()) {
case ERROR:
errors++;
break;
case WARNING:
warnings++;
break;
case INFORMATION:
infos++;
break;
default:
break;
}
}
String tt = "";
if (errors > 0) {
tt += ", " + errors + " errors";
}
if (warnings > 0) {
tt += ", " + warnings + " warnings";
}
if (infos > 0) {
tt += ", " + infos + " informational";
}
setTitleToolTip(tt.substring(2));
}
@Override
public void createPartControl(Composite parent) {
myTop = parent;
myContext = IBindingContext.Factory.createContext(parent);
myMessages = myVAM.getUnboundMessagesOL();
myMessages.addListChangeListener(myMessageListListener);
myTable = ITableCreator.Factory.create(myContext, myTop, SWT.H_SCROLL | ITableCreator.FILTER, myMessages);
myTable.getBinding().readonly();
myTable.addColumn("severity(w=20,ww=0,label='',format='')");
myTable.addColumn("__NONE__(w=150,ww=200,label='Object')")
.model(new ModelObjectFactory(), EcorePackage.Literals.EJAVA_OBJECT).dynamic()
.type(Constants.TYPE_QUALIFIED_NAME).arg(Constants.ARG_SHOW_IMAGE, true);
myTable.addColumn("__NONE__(w=50,ww=100,label='Feature')")
.model(new ModelFeatureFactory(), EcorePackage.Literals.EJAVA_OBJECT).dynamic();
myTable.addColumn("message(w=200, ww=400)");
myContext.finish();
IBindingContextSelectionProvider.Factory.adapt(myContext, getSite());
IDnDSupport.Factory.installOn(myContext);
updateViewTooltip();
}
@Override
public void dispose() {
if (myTable != null) {
myTable.dispose();
myTable = null;
}
if (myContext != null) {
myContext.dispose();
myContext = null;
}
if (myMessages != null && !myMessages.isDisposed()) {
myMessages.removeListChangeListener(myMessageListListener);
}
super.dispose();
}
@Override
public void setFocus() {
myTable.setFocus();
}
/**
* {@link IObservableFactory} that finds the model object of a {@link IBindingMessage binding
* message}.
* <p>
* The common model object of all tagrtes of the message or <code>null</code>.
*/
protected static class ModelObjectFactory implements IObservableFactory {
@Override
public IObservable createObservable(Object obj) {
final IBindingMessage m = (IBindingMessage) obj;
final EList<IBindingMessageTarget> targets = m.getTargets();
EObject modelObject = null;
switch (targets.size()) {
case 0:
break;
case 1:
modelObject = targets.get(0).getModelObject();
break;
default:
modelObject = targets.get(0).getModelObject();
for (final IBindingMessageTarget t : targets) {
if (t.getModelObject() != modelObject) {
final WritableValue value = WritableValue.withValueType(EcorePackage.Literals.ESTRING);
value.setValue("<multiple objects>");
return value;
}
}
break;
}
final WritableValue value = WritableValue.withValueType(modelObject != null ? modelObject.eClass()
: EcorePackage.Literals.EOBJECT);
value.setValue(modelObject);
return value;
}
}
/**
* {@link IObservableFactory} that finds the model feature of a {@link IBindingMessage binding
* message}.
* <p>
* The common model feature of all targets of the message or <code>null</code>.
*/
protected static class ModelFeatureFactory implements IObservableFactory {
@Override
public IObservable createObservable(Object obj) {
final IBindingMessage m = (IBindingMessage) obj;
final EList<IBindingMessageTarget> targets = m.getTargets();
EStructuralFeature feature = null;
switch (targets.size()) {
case 0:
break;
case 1:
feature = targets.get(0).getModelFeature();
break;
default:
feature = targets.get(0).getModelFeature();
for (final IBindingMessageTarget t : targets) {
if (t.getModelFeature() != feature) {
final WritableValue value = WritableValue.withValueType(EcorePackage.Literals.ESTRING);
value.setValue("<multiple features>");
return value;
}
}
break;
}
final WritableValue value = WritableValue.withValueType(EcorePackage.Literals.ESTRUCTURAL_FEATURE);
value.setValue(feature);
return value;
}
}
}