including changes from cdmlib-print
[taxeditor.git] / taxeditor-editor / src / main / java / eu / etaxonomy / taxeditor / 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.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.editor.EditorUtil;
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.forms.CdmFormFactory} object.
53 * @param parentElement a {@link eu.etaxonomy.taxeditor.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 // TODO Auto-generated method stub
77
78 }
79
80 /**
81 * <p>Setter for the field <code>imageUri</code>.</p>
82 *
83 * @param uri a {@link java.net.URI} object.
84 */
85 public void setImageUri(URI uri) {
86 this.imageUri = uri;
87 }
88
89
90 /**
91 * <p>Getter for the field <code>imageUri</code>.</p>
92 *
93 * @return the imageUri
94 */
95 public URI getImageUri() {
96 return imageUri;
97 }
98
99 public void loadImage(){
100 loadImage(null);
101 }
102
103 public void loadImage(final Runnable postRunnable){
104 if(getImageUri() != null){
105 Job job = new Job("Loading image") {
106
107 @Override
108 protected IStatus run(IProgressMonitor monitor) {
109 IRunnableWithProgress runnable = getLoadImageRunnable(postRunnable);
110 try {
111 runnable.run(monitor);
112 } catch (Exception e) {
113 EditorUtil.errorDialog("Could not load image", getClass(), e.getMessage() + ": " + getImageUri(), e);
114 }
115
116 return Status.OK_STATUS;
117 }
118 };
119 job.schedule();
120 }
121 }
122
123 public IRunnableWithProgress getLoadImageRunnable(final Runnable postRunnable){
124
125 final Display display = getLayoutComposite().getDisplay();
126
127 IRunnableWithProgress runnable = new IRunnableWithProgress(){
128
129 @Override
130 public void run(IProgressMonitor monitor) {
131 try {
132 monitor.beginTask("Loading: " + getImageUri(), IProgressMonitor.UNKNOWN);
133 InputStream imageStream = UriUtils.getInputStream(imageUri);
134
135 image = new Image(Display.getCurrent(), imageStream);
136
137 // redraw the image container
138 display.asyncExec(new Runnable(){
139 @Override
140 public void run() {
141 if(! getLayoutComposite().isDisposed()){
142 Event untypedEvent = new Event();
143 untypedEvent.widget = container;
144 PaintEvent event = new PaintEvent(untypedEvent);
145 event.gc = new GC(container);
146 paintControl(event);
147 getLayoutComposite().layout();
148 }
149 }
150 });
151
152 // execute the external runnable
153 if(postRunnable != null){
154 display.asyncExec(postRunnable);
155 }
156 monitor.done();
157 }catch (Exception e) {
158 EditorUtil.errorDialog("Could not load image", getClass(), e.getMessage() + ": " + imageUri , e);
159 }
160 }
161 };
162
163 return runnable;
164 }
165
166 private void calculateImageBounds(){
167 Rectangle imageBounds = image.getBounds();
168 Rectangle containerBounds = container.getBounds();
169
170 Integer imgWidth = imageBounds.width;
171 Integer imgHeight = imageBounds.height;
172
173 Float ratio = imgHeight.floatValue()/imgWidth.floatValue();
174 Integer width = containerBounds.width;
175 Float height = width * ratio;
176
177 imageMaxBounds = new Rectangle(containerBounds.x, containerBounds.y, width, height.intValue());
178 }
179
180
181 /* (non-Javadoc)
182 * @see org.eclipse.swt.events.PaintListener#paintControl(org.eclipse.swt.events.PaintEvent)
183 */
184 /** {@inheritDoc} */
185 @Override
186 public void paintControl(PaintEvent e) {
187 if(image != null){
188 calculateImageBounds();
189 Composite composite = (Composite) e.widget;
190 TableWrapData layoutData = CdmFormFactory.FILL(2, 1);
191 layoutData.heightHint = imageMaxBounds.height;
192 composite.setLayoutData(layoutData);
193 e.gc.drawImage(image, 0, 0, image.getBounds().width, image.getBounds().height, 0, 0, imageMaxBounds.width, imageMaxBounds.height);
194 e.gc.dispose();
195 }
196 }
197 }