Revision 1ce04105
Added by Patrick Plitzner almost 5 years ago
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/ui/element/ImageElement.java | ||
---|---|---|
46 | 46 |
*/ |
47 | 47 |
public class ImageElement extends AbstractCdmFormElement implements PaintListener{ |
48 | 48 |
|
49 |
/** |
|
50 |
* @author pplitzner |
|
51 |
* @since Jul 17, 2019 |
|
52 |
* |
|
53 |
*/ |
|
54 |
public class LoadImageJob extends Job { |
|
55 |
public LoadImageJob(String name) { |
|
56 |
super(name); |
|
57 |
} |
|
58 |
|
|
59 |
@Override |
|
60 |
protected IStatus run(IProgressMonitor monitor) { |
|
61 |
IRunnableWithProgress runnable = getLoadImageRunnable(postRunnable); |
|
62 |
try { |
|
63 |
runnable.run(monitor); |
|
64 |
} catch (Exception e) { |
|
65 |
MessagingUtils.messageDialog("Could not load image", getClass(), e.getMessage() + ": " + getImageUri(), e); |
|
66 |
} |
|
67 |
|
|
68 |
return Status.OK_STATUS; |
|
69 |
} |
|
70 |
} |
|
71 |
|
|
49 | 72 |
private URI imageUri; |
50 | 73 |
private Image image; |
51 | 74 |
|
... | ... | |
103 | 126 |
|
104 | 127 |
public void loadImage(){ |
105 | 128 |
if(getImageUri() != null){ |
106 |
Job job = new Job("Loading image") { |
|
107 |
|
|
108 |
@Override |
|
109 |
protected IStatus run(IProgressMonitor monitor) { |
|
110 |
IRunnableWithProgress runnable = getLoadImageRunnable(postRunnable); |
|
111 |
try { |
|
112 |
runnable.run(monitor); |
|
113 |
} catch (Exception e) { |
|
114 |
MessagingUtils.messageDialog("Could not load image", getClass(), e.getMessage() + ": " + getImageUri(), e); |
|
115 |
} |
|
116 |
|
|
117 |
return Status.OK_STATUS; |
|
118 |
} |
|
119 |
}; |
|
129 |
Job job = new LoadImageJob("Loading image"); |
|
120 | 130 |
job.schedule(); |
121 | 131 |
} |
122 | 132 |
} |
123 | 133 |
|
124 |
public void unloadImage() { |
|
125 |
Job job = new Job("Unloading image") { |
|
126 |
|
|
127 |
@Override |
|
128 |
protected IStatus run(IProgressMonitor monitor) { |
|
129 |
IRunnableWithProgress runnable = getLoadImageRunnable(postRunnable); |
|
130 |
try { |
|
131 |
runnable.run(monitor); |
|
132 |
} catch (Exception e) { |
|
133 |
MessagingUtils.messageDialog("Could not unload image", getClass(), e.getMessage() + ": " + getImageUri(), e); |
|
134 |
} |
|
135 |
|
|
136 |
return Status.OK_STATUS; |
|
137 |
} |
|
138 |
}; |
|
139 |
job.schedule(); |
|
140 |
|
|
141 |
} |
|
142 |
|
|
143 | 134 |
public IRunnableWithProgress getLoadImageRunnable(final Runnable postRunnable){ |
144 | 135 |
|
145 | 136 |
final Display display = getLayoutComposite().getDisplay(); |
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/ui/section/media/ImageFileElement.java | ||
---|---|---|
14 | 14 |
|
15 | 15 |
import org.apache.commons.io.FileUtils; |
16 | 16 |
import org.apache.http.HttpException; |
17 |
import org.eclipse.core.runtime.IProgressMonitor; |
|
18 |
import org.eclipse.core.runtime.IStatus; |
|
19 |
import org.eclipse.core.runtime.Status; |
|
20 |
import org.eclipse.core.runtime.jobs.Job; |
|
17 | 21 |
import org.eclipse.swt.events.SelectionListener; |
18 | 22 |
|
19 | 23 |
import eu.etaxonomy.cdm.common.media.ImageInfo; |
20 | 24 |
import eu.etaxonomy.cdm.model.media.ImageFile; |
25 |
import eu.etaxonomy.taxeditor.store.StoreUtil; |
|
21 | 26 |
import eu.etaxonomy.taxeditor.ui.element.AbstractFormSection; |
22 | 27 |
import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory; |
23 | 28 |
import eu.etaxonomy.taxeditor.ui.element.CdmPropertyChangeEvent; |
... | ... | |
32 | 37 |
*/ |
33 | 38 |
public class ImageFileElement extends MediaRepresentationPartElement<ImageFile> { |
34 | 39 |
|
40 |
private final class LoadImageJob extends Job{ |
|
41 |
|
|
42 |
private URI uri; |
|
43 |
private boolean updateDimensions; |
|
44 |
|
|
45 |
public LoadImageJob(URI uri, boolean updateDimensions) { |
|
46 |
super("Load image"); |
|
47 |
this.uri = uri; |
|
48 |
this.updateDimensions = updateDimensions; |
|
49 |
} |
|
50 |
|
|
51 |
@Override |
|
52 |
protected IStatus run(IProgressMonitor monitor) { |
|
53 |
try{ |
|
54 |
ImageInfo imageInfo = ImageInfo.NewInstanceWithMetaData(uri, 10000); |
|
55 |
ImageFileElement.this.getLayoutComposite().getDisplay().asyncExec(()->{ |
|
56 |
element_keyValue.setInput(imageInfo.getMetaData()); |
|
57 |
try { |
|
58 |
disposeImage(); |
|
59 |
element_image = formFactory.createImageElement(parentFormElement, uri, style); |
|
60 |
element_image.initImageUri(uri); |
|
61 |
} catch (IOException | HttpException e) { |
|
62 |
handleException(); |
|
63 |
} |
|
64 |
element_image.loadImage(); |
|
65 |
if(uri == null){ |
|
66 |
return; |
|
67 |
} |
|
68 |
if(updateDimensions){ |
|
69 |
text_size.setText(FileUtils.byteCountToDisplaySize(imageInfo.getLength())); |
|
70 |
// KLUDGE this is not save for very large files, because of the int cast. |
|
71 |
// But then, I don't think we will handle such large files in the near future |
|
72 |
getEntity().setSize((int) imageInfo.getLength()); |
|
73 |
|
|
74 |
text_height.setNumber(imageInfo.getHeight()); |
|
75 |
getEntity().setHeight(imageInfo.getHeight()); |
|
76 |
|
|
77 |
text_width.setNumber(imageInfo.getWidth()); |
|
78 |
getEntity().setWidth(imageInfo.getWidth()); |
|
79 |
} |
|
80 |
StoreUtil.reflowParentScrolledForm(getLayoutComposite(), true); |
|
81 |
}); |
|
82 |
} |
|
83 |
catch (IOException | HttpException e) { |
|
84 |
handleException(); |
|
85 |
} |
|
86 |
return Status.OK_STATUS; |
|
87 |
} |
|
88 |
|
|
89 |
} |
|
90 |
|
|
35 | 91 |
private NumberWithLabelElement text_height; |
36 | 92 |
private NumberWithLabelElement text_width; |
37 | 93 |
private KeyValueViewerElement element_keyValue; |
38 | 94 |
private ImageElement element_image; |
95 |
private ICdmFormElement parentFormElement; |
|
96 |
private int style; |
|
39 | 97 |
|
40 | 98 |
public ImageFileElement(CdmFormFactory cdmFormFactory, |
41 | 99 |
AbstractFormSection section, ImageFile element, |
... | ... | |
43 | 101 |
super(cdmFormFactory, section, element, removeListener, style); |
44 | 102 |
} |
45 | 103 |
|
46 |
/** {@inheritDoc} */ |
|
47 | 104 |
@Override |
48 | 105 |
public void createControls(ICdmFormElement formElement, int style) { |
49 | 106 |
super.createControls(formElement, style); |
50 | 107 |
|
108 |
this.parentFormElement = formElement; |
|
109 |
this.style = style; |
|
110 |
|
|
51 | 111 |
text_height = formFactory.createNumberTextWithLabelElement(formElement, "Height", null, style); |
52 | 112 |
text_height.setEnabled(false); |
53 | 113 |
text_width = formFactory.createNumberTextWithLabelElement(formElement, "Width", null, style); |
54 | 114 |
text_width.setEnabled(false); |
55 |
element_image = formFactory.createImageElement(formElement, null, style); |
|
56 | 115 |
element_keyValue = formFactory.createKeyValueViewerElement(formElement, "Key", "Value", null); |
57 | 116 |
} |
58 | 117 |
|
59 |
/** {@inheritDoc} */ |
|
60 | 118 |
@Override |
61 | 119 |
public void setEntity(ImageFile entity) { |
62 | 120 |
super.setEntity(entity); |
63 | 121 |
text_height.setNumber(entity.getHeight()); |
64 | 122 |
text_width.setNumber(entity.getWidth()); |
65 | 123 |
try { |
66 |
loadImage(entity.getUri(), false);
|
|
124 |
new LoadImageJob(getEntity().getUri(), true).schedule();
|
|
67 | 125 |
} catch (Exception e) { |
68 | 126 |
e.printStackTrace(); |
69 |
handleException(e); |
|
70 |
} |
|
71 |
} |
|
72 |
|
|
73 |
private void loadImage(URI uri, boolean updateDimensions) throws IOException, HttpException{ |
|
74 |
element_image.initImageUri(uri); |
|
75 |
|
|
76 |
element_image.loadImage(); |
|
77 |
|
|
78 |
|
|
79 |
if(uri == null){ |
|
80 |
return; |
|
81 |
} |
|
82 |
|
|
83 |
ImageInfo imageInfo = ImageInfo.NewInstanceWithMetaData(uri, 10000); |
|
84 |
|
|
85 |
element_keyValue.setInput(imageInfo.getMetaData()); |
|
86 |
|
|
87 |
if(updateDimensions){ |
|
88 |
text_size.setText(FileUtils.byteCountToDisplaySize(imageInfo.getLength())); |
|
89 |
// KLUDGE this is not save for very large files, because of the int cast. |
|
90 |
// But then, I don't think we will handle such large files in the near future |
|
91 |
getEntity().setSize((int) imageInfo.getLength()); |
|
92 |
|
|
93 |
text_height.setNumber(imageInfo.getHeight()); |
|
94 |
getEntity().setHeight(imageInfo.getHeight()); |
|
95 |
|
|
96 |
text_width.setNumber(imageInfo.getWidth()); |
|
97 |
getEntity().setWidth(imageInfo.getWidth()); |
|
127 |
handleException(); |
|
98 | 128 |
} |
99 |
|
|
100 |
|
|
101 | 129 |
} |
102 | 130 |
|
103 |
/** {@inheritDoc} */ |
|
104 | 131 |
@Override |
105 | 132 |
public void handleEvent(Object eventSource) { |
106 | 133 |
if(eventSource == text_uri){ |
... | ... | |
114 | 141 |
parentMediaDetailElement.setUriBuffer(text_uri.getText()); |
115 | 142 |
} |
116 | 143 |
} |
117 |
|
|
118 |
loadImage(getEntity().getUri(), true); |
|
119 |
|
|
144 |
new LoadImageJob(getEntity().getUri(), true).schedule(); |
|
120 | 145 |
firePropertyChangeEvent(new CdmPropertyChangeEvent(this, null)); |
121 | 146 |
} catch (Exception e) { |
122 |
handleException(e);
|
|
147 |
handleException(); |
|
123 | 148 |
} finally { |
124 | 149 |
firePropertyChangeEvent(this); |
125 | 150 |
} |
126 | 151 |
} |
127 | 152 |
} |
128 | 153 |
|
129 |
protected void handleException(Exception e) { |
|
130 |
element_image.unloadImage(); |
|
131 |
// text_height.setNumber(0); |
|
132 |
// text_width.setNumber(0); |
|
133 |
// text_size.setNumber(0); |
|
134 |
|
|
135 |
element_image.loadImage(); |
|
154 |
protected void handleException() { |
|
155 |
getLayoutComposite().getDisplay().asyncExec(()->{ |
|
156 |
disposeImage(); |
|
157 |
StoreUtil.reflowParentScrolledForm(getLayoutComposite(), true); |
|
158 |
}); |
|
136 | 159 |
} |
160 |
|
|
161 |
private void disposeImage(){ |
|
162 |
if(element_image!=null){ |
|
163 |
element_image.dispose(); |
|
164 |
element_image = null; |
|
165 |
} |
|
166 |
} |
|
137 | 167 |
} |
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/ui/section/media/MediaDetailElement.java | ||
---|---|---|
172 | 172 |
|
173 | 173 |
private void disposeImage(){ |
174 | 174 |
if(element_image!=null){ |
175 |
element_image.unloadImage(); |
|
176 | 175 |
element_image.dispose(); |
177 | 176 |
element_image = null; |
178 | 177 |
} |
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/ui/section/media/MediaRepresentationElement.java | ||
---|---|---|
14 | 14 |
import java.util.Collection; |
15 | 15 |
|
16 | 16 |
import org.apache.http.HttpException; |
17 |
import org.eclipse.core.runtime.IProgressMonitor; |
|
18 |
import org.eclipse.core.runtime.IStatus; |
|
19 |
import org.eclipse.core.runtime.Status; |
|
20 |
import org.eclipse.core.runtime.jobs.Job; |
|
17 | 21 |
import org.eclipse.swt.events.SelectionListener; |
18 | 22 |
|
19 | 23 |
import eu.etaxonomy.cdm.common.UriUtils; |
... | ... | |
79 | 83 |
// FIXME HACK automatically set the mime type to the first mediaRepresentationPart's mimetype |
80 | 84 |
else if(eventSource == section_mediaRepresentationPart){ |
81 | 85 |
firePropertyChangeEvent(this); |
86 |
new Job("Set mime type") { |
|
87 |
@Override |
|
88 |
protected IStatus run(IProgressMonitor monitor) { |
|
89 |
Collection<MediaRepresentationPart> imageFileElements = section_mediaRepresentationPart.getCollection(section_mediaRepresentationPart.getEntity()); |
|
90 |
if(! imageFileElements.iterator().hasNext()){ |
|
91 |
return Status.CANCEL_STATUS; |
|
92 |
} |
|
93 |
MediaRepresentationPart mediaRepresentationPart = imageFileElements.iterator().next(); |
|
94 |
if(mediaRepresentationPart == null || !(mediaRepresentationPart instanceof ImageFile)){ |
|
95 |
return Status.CANCEL_STATUS; |
|
96 |
} |
|
97 |
ImageFile imageFile = (ImageFile) mediaRepresentationPart; |
|
82 | 98 |
|
83 |
Collection<MediaRepresentationPart> imageFileElements = section_mediaRepresentationPart.getCollection(section_mediaRepresentationPart.getEntity()); |
|
84 |
|
|
85 |
if(! imageFileElements.iterator().hasNext()){ |
|
86 |
return; |
|
87 |
} |
|
88 |
|
|
89 |
MediaRepresentationPart mediaRepresentationPart = imageFileElements.iterator().next(); |
|
90 |
if(mediaRepresentationPart == null || !(mediaRepresentationPart instanceof ImageFile)){ |
|
91 |
return; |
|
92 |
} |
|
93 |
ImageFile imageFile = (ImageFile) mediaRepresentationPart; |
|
94 |
|
|
95 |
URI uri = imageFile.getUri(); |
|
96 |
if(!UriUtils.isServiceAvailable(uri)){ |
|
97 |
return; |
|
98 |
} |
|
99 |
try { |
|
100 |
ImageInfo imageInfo = ImageInfo.NewInstance(uri, 10000); |
|
101 |
String mimeType = imageInfo.getMimeType(); |
|
102 |
text_mimeType.setText(mimeType); |
|
103 |
getEntity().setMimeType(mimeType); |
|
104 |
text_suffix.setText(imageInfo.getSuffix()); |
|
105 |
getEntity().setSuffix(imageInfo.getSuffix()); |
|
106 |
} |
|
107 |
//theses exceptions do not need to be logged |
|
108 |
//especially because this happens with every key stroke |
|
109 |
catch (IOException e) { |
|
110 |
// MessagingUtils.error(getClass(), e); |
|
111 |
} |
|
112 |
catch (HttpException e) { |
|
113 |
// MessagingUtils.error(getClass(), e); |
|
114 |
} |
|
99 |
URI uri = imageFile.getUri(); |
|
100 |
if(!UriUtils.isServiceAvailable(uri)){ |
|
101 |
return Status.CANCEL_STATUS; |
|
102 |
} |
|
103 |
try { |
|
104 |
ImageInfo imageInfo = ImageInfo.NewInstance(uri, 10000); |
|
105 |
String mimeType = imageInfo.getMimeType(); |
|
106 |
getEntity().setMimeType(mimeType); |
|
107 |
getEntity().setSuffix(imageInfo.getSuffix()); |
|
108 |
MediaRepresentationElement.this.getLayoutComposite().getDisplay().asyncExec(()->{ |
|
109 |
text_mimeType.setText(mimeType); |
|
110 |
text_suffix.setText(imageInfo.getSuffix()); |
|
111 |
}); |
|
112 |
} |
|
113 |
//theses exceptions do not need to be logged |
|
114 |
//especially because this happens with every key stroke |
|
115 |
catch (IOException|HttpException e) { |
|
116 |
// ignore |
|
117 |
} |
|
118 |
return Status.OK_STATUS; |
|
119 |
} |
|
120 |
}.schedule(); |
|
115 | 121 |
} |
116 | 122 |
} |
117 | 123 |
} |
Also available in: Unified diff
ref #8129 Load images asynchronously in advanced media view