Merged refactoring from development branch.
[taxeditor.git] / taxeditor-store / src / main / java / eu / etaxonomy / taxeditor / ui / forms / ImageElement.java
1 // $Id$
2 /**
3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10
11 package eu.etaxonomy.taxeditor.ui.forms;
12
13 import java.io.InputStream;
14 import java.net.URI;
15
16 import org.eclipse.core.runtime.IProgressMonitor;
17 import org.eclipse.core.runtime.IStatus;
18 import org.eclipse.core.runtime.Status;
19 import org.eclipse.core.runtime.jobs.Job;
20 import org.eclipse.jface.operation.IRunnableWithProgress;
21 import org.eclipse.swt.events.PaintEvent;
22 import org.eclipse.swt.events.PaintListener;
23 import org.eclipse.swt.graphics.GC;
24 import org.eclipse.swt.graphics.Image;
25 import org.eclipse.swt.graphics.Rectangle;
26 import org.eclipse.swt.widgets.Composite;
27 import org.eclipse.swt.widgets.Display;
28 import org.eclipse.swt.widgets.Event;
29 import org.eclipse.ui.forms.widgets.TableWrapData;
30
31 import eu.etaxonomy.cdm.common.UriUtils;
32 import eu.etaxonomy.taxeditor.store.StoreUtil;
33
34 /**
35 * <p>ImageElement class.</p>
36 *
37 * @author n.hoffmann
38 * @created Sep 24, 2010
39 * @version 1.0
40 */
41 public class ImageElement extends AbstractCdmFormElement implements PaintListener{
42
43 private URI imageUri;
44 private Image image;
45 private Rectangle imageMaxBounds;
46
47 private Composite container;
48
49 /**
50 * <p>Constructor for ImageElement.</p>
51 *
52 * @param formFactory a {@link eu.etaxonomy.taxeditor.ui.forms.CdmFormFactory} object.
53 * @param parentElement a {@link eu.etaxonomy.taxeditor.ui.forms.ICdmFormElement} object.
54 * @param imageUri a {@link java.net.URI} object.
55 * @param style a int.
56 */
57 protected ImageElement(CdmFormFactory formFactory, ICdmFormElement parentElement, URI imageUri, int style) {
58 super(formFactory, parentElement);
59
60 setImageUri(imageUri);
61 loadImage();
62
63 container = new Composite(getLayoutComposite(), style);
64 container.setLayoutData(CdmFormFactory.FILL(2, 1));
65
66 container.addPaintListener(this);
67 }
68
69
70 /* (non-Javadoc)
71 * @see eu.etaxonomy.taxeditor.forms.ISelectable#setSelected(boolean)
72 */
73 /** {@inheritDoc} */
74 @Override
75 public void setSelected(boolean selected) {
76
77 }
78
79 /**
80 * <p>Setter for the field <code>imageUri</code>.</p>
81 *
82 * @param uri a {@link java.net.URI} object.
83 */
84 public void setImageUri(URI uri) {
85 this.imageUri = uri;
86 }
87
88
89 /**
90 * <p>Getter for the field <code>imageUri</code>.</p>
91 *
92 * @return the imageUri
93 */
94 public URI getImageUri() {
95 return imageUri;
96 }
97
98 public void loadImage(){
99 loadImage(null);
100 }
101
102 public void loadImage(final Runnable postRunnable){
103 if(getImageUri() != null){
104 Job job = new Job("Loading image") {
105
106 @Override
107 protected IStatus run(IProgressMonitor monitor) {
108 IRunnableWithProgress runnable = getLoadImageRunnable(postRunnable);
109 try {
110 runnable.run(monitor);
111 } catch (Exception e) {
112 StoreUtil.errorDialog("Could not load image", getClass(), e.getMessage() + ": " + getImageUri(), e);
113 }
114
115 return Status.OK_STATUS;
116 }
117 };
118 job.schedule();
119 }
120 }
121
122 public IRunnableWithProgress getLoadImageRunnable(final Runnable postRunnable){
123
124 final Display display = getLayoutComposite().getDisplay();
125
126 IRunnableWithProgress runnable = new IRunnableWithProgress(){
127
128 @Override
129 public void run(IProgressMonitor monitor) {
130 try {
131 monitor.beginTask("Loading: " + getImageUri(), IProgressMonitor.UNKNOWN);
132 InputStream imageStream = UriUtils.getInputStream(imageUri);
133
134 image = new Image(Display.getCurrent(), imageStream);
135
136 // redraw the image container
137 display.asyncExec(new Runnable(){
138 @Override
139 public void run() {
140 if(! getLayoutComposite().isDisposed()){
141 Event untypedEvent = new Event();
142 untypedEvent.widget = container;
143 PaintEvent event = new PaintEvent(untypedEvent);
144 event.gc = new GC(container);
145 paintControl(event);
146 getLayoutComposite().layout();
147 }
148 }
149 });
150
151 // execute the external runnable
152 if(postRunnable != null){
153 display.asyncExec(postRunnable);
154 }
155 monitor.done();
156 }catch (Exception e) {
157 StoreUtil.errorDialog("Could not load image", getClass(), e.getMessage() + ": " + imageUri , e);
158 }
159 }
160 };
161
162 return runnable;
163 }
164
165 private void calculateImageBounds(){
166 Rectangle imageBounds = image.getBounds();
167 Rectangle containerBounds = container.getBounds();
168
169 Integer imgWidth = imageBounds.width;
170 Integer imgHeight = imageBounds.height;
171
172 Float ratio = imgHeight.floatValue()/imgWidth.floatValue();
173 Integer width = containerBounds.width;
174 Float height = width * ratio;
175
176 imageMaxBounds = new Rectangle(containerBounds.x, containerBounds.y, width, height.intValue());
177 }
178
179
180 /* (non-Javadoc)
181 * @see org.eclipse.swt.events.PaintListener#paintControl(org.eclipse.swt.events.PaintEvent)
182 */
183 /** {@inheritDoc} */
184 @Override
185 public void paintControl(PaintEvent e) {
186 if(image != null){
187 calculateImageBounds();
188 Composite composite = (Composite) e.widget;
189 TableWrapData layoutData = CdmFormFactory.FILL(2, 1);
190 layoutData.heightHint = imageMaxBounds.height;
191 composite.setLayoutData(layoutData);
192 e.gc.drawImage(image, 0, 0, image.getBounds().width, image.getBounds().height, 0, 0, imageMaxBounds.width, imageMaxBounds.height);
193 e.gc.dispose();
194 }
195 }
196 }