/**
* Copyright (c) 2009 Bestsolution.at and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* Tom Schindl<tom.schindl@bestsolution.at> - Initial API and implementation
*/
package org.eclipse.emf.example.databinding.project.ui.rcp.dialogs;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.ObservablesManager;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.databinding.dialog.TitleAreaDialogSupport;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.Control;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.databinding.EMFDataBindingContext;
import org.eclipse.emf.databinding.EMFUpdateValueStrategy;
import org.eclipse.emf.databinding.edit.EMFEditProperties;
import org.eclipse.emf.databinding.edit.IEMFEditValueProperty;
import org.eclipse.emf.ecore.xml.type.XMLTypeFactory;
import org.eclipse.emf.edit.command.SetCommand;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.example.databinding.project.ui.rcp.Activator;
import org.eclipse.emf.example.databinding.project.ui.rcp.databinding.Base64ToImageConverter;
import org.eclipse.emf.example.databinding.project.ui.rcp.databinding.EMFObservablesManager;
import org.eclipse.emf.example.databinding.project.ui.rcp.databinding.FormBuilder;
import org.eclipse.emf.examples.databinding.project.core.model.project.Person;
import org.eclipse.emf.examples.databinding.project.core.model.project.ProjectPackage;
/**
* Dialog to edit person data
*/
public class PersonDialog extends TitleAreaDialog
{
private final Person person;
private final EditingDomain editingDomain;
private final DataBindingContext ctx;
/**
* Create a new dialog
* @param parentShell
* @param editingDomain
* @param person
*/
public PersonDialog(Shell parentShell, EditingDomain editingDomain, Person person)
{
super(parentShell);
this.person = person;
this.editingDomain = editingDomain;
this.ctx = new EMFDataBindingContext();
}
@Override
protected Control createDialogArea(Composite parent)
{
getShell().setText("Edit Person");
setTitle("Edit Person");
setMessage("Edit the data of the person and add an image (Max. 200KB and 200x200px)");
final Composite comp = (Composite)super.createDialogArea(parent);
ObservablesManager mgr = new EMFObservablesManager();
mgr.runAndCollect(new Runnable()
{
public void run()
{
createForm(comp).setLayoutData(new GridData(GridData.FILL_BOTH));
}
});
return comp;
}
private Composite createForm(Composite parent)
{
final Composite container = new Composite(parent, SWT.NONE);
container.setLayout(new GridLayout(2, false));
final Composite imgContainer = new Composite(container, SWT.NONE);
{
imgContainer.setLayout(new GridLayout());
GridData gd = new GridData(200, SWT.DEFAULT);
gd.verticalAlignment = SWT.TOP;
imgContainer.setLayoutData(gd);
final Label l = new Label(imgContainer, SWT.BORDER);
gd = new GridData(SWT.CENTER, SWT.FILL, false, false);
l.setLayoutData(gd);
IEMFEditValueProperty mprop = EMFEditProperties.value(editingDomain, ProjectPackage.Literals.PERSON__IMAGE);
ctx.bindValue(
WidgetProperties.image().observe(l),
mprop.observe(person),
null,
new EMFUpdateValueStrategy().setConverter(new Base64ToImageConverter(container.getDisplay())));
l.addDisposeListener(new DisposeListener()
{
public void widgetDisposed(DisposeEvent e)
{
if (l.getImage() != null)
{
l.getImage().dispose();
}
}
});
final Button button = new Button(imgContainer, SWT.PUSH);
button.setText("Select Image ...");
button.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
showImageSelectionDialog(container.getShell(), container);
}
});
}
FormBuilder<IEMFEditValueProperty> builder = new FormBuilder<IEMFEditValueProperty>();
builder.addTextEntry(
"Firstname",
EMFEditProperties.value(editingDomain, ProjectPackage.Literals.PERSON__FIRSTNAME),
"Firstname must not be empty");
builder.addTextEntry(
"Lastname",
EMFEditProperties.value(editingDomain, ProjectPackage.Literals.PERSON__LASTNAME),
"Lastname must not be empty");
builder.addTextEntry(
"E-Mail",
EMFEditProperties.value(editingDomain, ProjectPackage.Literals.PERSON__EMAIL),
"E-Mail must not be empty");
Composite formContainer = builder.build(ctx, container, person);
formContainer.setLayoutData(new GridData(GridData.FILL_BOTH));
TitleAreaDialogSupport.create(this, ctx);
return container;
}
private void showImageSelectionDialog(Shell parent, Composite imgContainer)
{
FileDialog dialog = new FileDialog(parent);
dialog.setFilterExtensions(new String []{ "*.png", "*.jpg" });
String file = dialog.open();
if (file != null)
{
try
{
File f = new File(file);
if (f.length() < 1024 * 200) // 200KB
{
FileInputStream in = new FileInputStream(f);
byte[] buf = new byte [1024];
int len;
ByteArrayOutputStream out = new ByteArrayOutputStream();
while ((len = in.read(buf)) != -1)
{
out.write(buf, 0, len);
}
in.close();
String enc = XMLTypeFactory.eINSTANCE.convertBase64Binary(out.toByteArray());
out.close();
Command cmd = SetCommand.create(editingDomain, person, ProjectPackage.Literals.PERSON__IMAGE, enc);
if (cmd.canExecute())
{
editingDomain.getCommandStack().execute(cmd);
}
imgContainer.layout(true);
}
else
{
ErrorDialog.openError(parent, "Image too big", "The image selected is too big. The maximum file size is 200KB", new Status(
IStatus.ERROR,
Activator.PLUGIN_ID,
""), SWT.SHEET);
}
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
@Override
public boolean close()
{
ctx.dispose();
return super.close();
}
}