/*******************************************************************************
* Copyright (c) 2009, 2010 Innovation Gate GmbH.
* 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:
* Innovation Gate GmbH - initial API and implementation
******************************************************************************/
package de.innovationgate.eclipse.utils.ui;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import net.java.dev.genesis.annotation.ViewHandler;
import net.java.dev.genesis.ui.swt.SWTBinder;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.IMessageManager;
import org.eclipse.ui.forms.editor.FormEditor;
import org.eclipse.ui.forms.editor.FormPage;
import de.innovationgate.wga.model.Model;
import de.innovationgate.wga.model.ModelListener;
import de.innovationgate.wga.model.ValidationError;
@ViewHandler
public abstract class GenesisBoundFormPage extends FormPage implements ModelListener {
protected SWTBinder _binder;
protected Map<String, Control> _fields = new HashMap<String, Control>();
private boolean _canLeave = true;
private boolean _hasError;
public GenesisBoundFormPage(FormEditor editor, String id, String title) {
super(editor, id, title);
}
public GenesisBoundFormPage(String id, String title) {
super(id, title);
}
protected void bind(Composite container) {
_binder = new SWTBinder(container, getModel(), this);
_binder.setBindingStrategy(SWTBinder.BINDING_STRATEGY_PROPERTY);
_binder.bind();
getModel().addListener(this);
}
protected void bind(Composite container, String bindingStrategy) {
_binder = new SWTBinder(container, getModel(), this);
_binder.setBindingStrategy(bindingStrategy);
_binder.bind();
getModel().addListener(this);
}
public abstract void setModel(Model model);
public abstract Model getModel();
public void refresh() throws IOException {
getModel().reload();
if (_binder != null) {
_binder.refresh();
}
}
/**
* handles validation errors
* @param errors
* @return list with unhandled errors
*/
public List<ValidationError> handleValidationErrors(List<ValidationError> errors) {
List<ValidationError> unhandled = new ArrayList<ValidationError>();
unhandled.addAll(errors);
IManagedForm form = getManagedForm();
if (form != null) {
form.getMessageManager().removeAllMessages();
_hasError = false;
_canLeave = true;
if (errors != null) {
Iterator<ValidationError> it = errors.iterator();
while (it.hasNext()) {
ValidationError error = it.next();
String[] propHints = error.getPropertyHints();
for (int i = 0; i < propHints.length; i++) {
String propHint = propHints[i];
Control control = _fields.get(propHint);
if (control != null) {
addError(form.getMessageManager(), propHint, error, control);
unhandled.remove(error);
}
}
}
}
}
return unhandled;
}
public void resetValidationMessages() {
IManagedForm form = getManagedForm();
if (form != null) {
form.getMessageManager().removeAllMessages();
}
_hasError = false;
}
public boolean hasError() {
return _hasError;
}
private void addError(IMessageManager manager, String property, ValidationError error, Control control) {
manager.addMessage(property + "_" + error.hashCode(), error.getMessage(), null, IMessageProvider.ERROR, control);
//_canLeave = false;
_hasError = true;
}
protected void registerField(String bindingKey, Control control) {
_fields.put(bindingKey, control);
control.setEnabled(getModel().isEditable(bindingKey));
}
@Override
public boolean canLeaveThePage() {
return _canLeave;
}
public void modelChanged() {
for (String fieldName : _fields.keySet()) {
_fields.get(fieldName).setEnabled(getModel().isEditable(fieldName));
}
}
@Override
public void dispose() {
if (getModel() != null) {
getModel().removeListener(this);
}
super.dispose();
}
}