/** * 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(); } }