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