Project

General

Profile

« Previous | Next » 

Revision 1ce04105

Added by Patrick Plitzner almost 5 years ago

ref #8129 Load images asynchronously in advanced media view

View differences:

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