ref #6229: fix problems with multilanguage support and title generation for media
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / ui / section / media / MediaDetailElement.java
1 /**
2 * Copyright (C) 2014 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9 package eu.etaxonomy.taxeditor.ui.section.media;
10
11 import java.io.IOException;
12 import java.util.List;
13 import java.util.Set;
14
15 import org.apache.commons.imaging.ImageReadException;
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;
21 import org.eclipse.swt.SWT;
22 import org.eclipse.swt.events.SelectionAdapter;
23 import org.eclipse.swt.events.SelectionEvent;
24 import org.eclipse.swt.widgets.Button;
25 import org.eclipse.swt.widgets.Label;
26
27 import eu.etaxonomy.cdm.common.URI;
28 import eu.etaxonomy.cdm.common.UriUtils;
29 import eu.etaxonomy.cdm.common.media.CdmImageInfo;
30 import eu.etaxonomy.cdm.model.common.CdmBase;
31 import eu.etaxonomy.cdm.model.media.ImageFile;
32 import eu.etaxonomy.cdm.model.media.Media;
33 import eu.etaxonomy.cdm.model.media.MediaRepresentation;
34 import eu.etaxonomy.cdm.model.media.MediaRepresentationPart;
35 import eu.etaxonomy.cdm.model.media.MediaUtils;
36 import eu.etaxonomy.taxeditor.l10n.Messages;
37 import eu.etaxonomy.taxeditor.model.MessagingUtils;
38 import eu.etaxonomy.taxeditor.preference.IPreferenceKeys;
39 import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
40 import eu.etaxonomy.taxeditor.store.StoreUtil;
41 import eu.etaxonomy.taxeditor.ui.element.CdmFormFactory;
42 import eu.etaxonomy.taxeditor.ui.element.ICdmFormElement;
43 import eu.etaxonomy.taxeditor.ui.element.ImageElement;
44 import eu.etaxonomy.taxeditor.ui.element.LayoutConstants;
45 import eu.etaxonomy.taxeditor.ui.element.UriWithLabelElement;
46 import eu.etaxonomy.taxeditor.ui.section.AbstractCdmDetailElement;
47 import eu.etaxonomy.taxeditor.ui.section.description.MediaDetailsSection;
48
49 /**
50 * @author pplitzner
51 * @date 25.08.2014
52 */
53 public class MediaDetailElement extends AbstractCdmDetailElement<Media>{
54
55 private static final String LOAD_IMAGE = Messages.MediaDetailElement_LOAD_IMAGE;
56
57 private boolean isShowImage = true;
58
59 /**
60 * @author pplitzner
61 * @since Jul 11, 2019
62 */
63 private final class LoadImageJob extends Job {
64 private URI uri;
65 private LoadImageJob(URI uri, String name) {
66 super(name);
67 this.uri = uri;
68 }
69
70 @Override
71 protected IStatus run(IProgressMonitor monitor) {
72 try {
73 //first check if uri refers to an actual (non-image) file
74
75 UriUtils.getInputStream(uri);// will fail with a FileNotFoundException if not
76
77 CdmImageInfo imageInfo = CdmImageInfo.NewInstance(uri, 10000);//will fail when it is no image file
78 MediaDetailElement.this.getLayoutComposite().getDisplay().asyncExec(()->{
79 singleMediaRepresentationPart.setSize((int) imageInfo.getLength());
80 if(singleMediaRepresentationPart.isInstanceOf(ImageFile.class)){
81 ImageFile image = CdmBase.deproxy(singleMediaRepresentationPart, ImageFile.class);
82 image.setHeight(imageInfo.getHeight());
83 image.setWidth(imageInfo.getWidth());
84 }
85 if(singleMediaRepresentationPart.getMediaRepresentation()!=null){
86 singleMediaRepresentationPart.getMediaRepresentation().setMimeType(imageInfo.getMimeType());
87 singleMediaRepresentationPart.getMediaRepresentation().setSuffix(imageInfo.getSuffix());
88 }
89 disposeImage();
90 if (!parentFormElement.getLayoutComposite().isDisposed()) {
91 element_image = formFactory.createImageElement(parentFormElement, uri, style);
92 // StoreUtil.reflowParentScrolledForm(getLayoutComposite(), true);
93 try {
94 element_image.initImageUri(uri);
95 } catch (IOException | HttpException e) {
96 exception(e);
97 }
98 element_image.loadImage();
99
100 disposeErrorLabel();
101 StoreUtil.reflowParentScrolledForm(getLayoutComposite(), true);
102
103
104 }
105 });
106 } catch (Exception e){
107 exception(e);
108 }
109 return Status.OK_STATUS;
110 }
111 }
112
113 private UriWithLabelElement textUri;
114 private MediaRepresentationSection section_mediaRepresentation;
115
116 private boolean isAdvancedMediaView;
117 private MediaRepresentationPart singleMediaRepresentationPart;
118 private ICdmFormElement parentFormElement;
119 private int style;
120
121 /**
122 * Used to store the URI even if it is invalid and thus cannot be stored in CDM
123 */
124 private String uriBuffer;
125 private ImageElement element_image;
126 private Label lblNoImage;
127
128 public MediaDetailElement(CdmFormFactory formFactory, ICdmFormElement formElement) {
129 super(formFactory, formElement);
130 }
131
132 @Override
133 protected void createControls(ICdmFormElement formElement, Media entity, int style) {
134 this.parentFormElement = formElement;
135 this.style = style;
136 }
137
138 @Override
139 public void setEntity(Media entity) {
140 super.setEntity(entity);
141 if(singleMediaRepresentationPart==null){
142 singleMediaRepresentationPart = MediaUtils.initFirstMediaRepresentationPart(entity, true);
143 }
144 initIsAdvancedMediaView();
145 showAdvancedView();
146 }
147
148 public boolean isShowImage() {
149 return isShowImage;
150 }
151
152 public void setShowImage(boolean isShowImage) {
153 this.isShowImage = isShowImage;
154 }
155
156 @Override
157 public void handleEvent(Object eventSource){
158 if(eventSource==textUri){
159 textUri.setBackground(getPersistentBackground());
160 URI uri = textUri.parseText();
161 singleMediaRepresentationPart.setUri(uri);
162 if(uri==null){
163 uriBuffer=textUri.getText();
164 }
165 else{
166 if (isShowImage){
167 LoadImageJob job = new LoadImageJob(uri, LOAD_IMAGE);
168 job.schedule();
169 }
170 }
171 if (this.getParentElement() != null && this.getParentElement() instanceof MediaMetaElement){
172 MediaMetaElement metaElement = (MediaMetaElement)this.getParentElement();
173 if (metaElement.getParentElement() != null && metaElement.getParentElement() instanceof MediaDetailsSection){
174 MediaDetailsSection sec = (MediaDetailsSection)metaElement.getParentElement();
175 // sec.setMediaSectionTitle();
176 metaElement.createTitle();
177 sec.setMediaSectionTitle();
178 }
179 }
180 }
181 }
182
183 private void exception(Exception e){
184 if(!getLayoutComposite().isDisposed()){
185 getLayoutComposite().getDisplay().asyncExec(()->{
186 String exceptionString;
187 if(e.getCause()!=null && e.getCause().getClass().equals(ImageReadException.class)){
188 disposeErrorLabel();
189 exceptionString = Messages.MediaDetailElement_NO_PREVIEW;
190 }
191 else{
192 disposeErrorLabel();
193 exceptionString = Messages.MediaDetailElement_NO_FILE_FOUND;
194 }
195 disposeImage();
196 if(lblNoImage==null){
197 lblNoImage = formFactory.createLabel(getLayoutComposite(), exceptionString);
198 lblNoImage.setLayoutData(LayoutConstants.FILL_HORIZONTALLY(2, 1));
199 lblNoImage.setAlignment(SWT.CENTER);
200 }
201 StoreUtil.reflowParentScrolledForm(getLayoutComposite(), true);
202 });
203 }
204 }
205
206 private void disposeImage(){
207 if(element_image!=null){
208 element_image.dispose();
209 element_image = null;
210 }
211 }
212
213 private void disposeErrorLabel() {
214 if(lblNoImage!=null){
215 lblNoImage.dispose();
216 }
217 lblNoImage = null;
218 }
219
220 public void toggleAdvancedMediaView() {
221 if (getEntity().getRepresentations() != null
222 && (getEntity().getRepresentations().size() > 1 ||
223 (getEntity().getRepresentations().size() == 1
224 && getEntity().getRepresentations().iterator().next().getParts().size() > 1))) {
225 MessagingUtils.informationDialog(Messages.MediaDetailElement_TOGGLE_NOT_POSSIBLE_TITLE,
226 Messages.MediaDetailElement_TOGGLE_NOT_POSSIBLE_MESSAGE);
227 // toggling is only possible if there are no more than one
228 // MediaRepresentation resp. MediaRepresentationParts
229 return;
230 }
231 isAdvancedMediaView = !isAdvancedMediaView;
232 showAdvancedView();
233 StoreUtil.reflowParentScrolledForm(getLayoutComposite(), true);
234 }
235
236 private void showAdvancedView() {
237
238 if(isAdvancedMediaView){
239 if(textUri!=null){
240 removeElementsAndControls(textUri);
241 }
242 disposeImage();
243 section_mediaRepresentation = formFactory.createMediaRepresentationSection(getConversationHolder(), parentFormElement, StoreUtil.getSectionStyle(MediaRepresentationSection.class, getEntity().getClass().getCanonicalName()));
244 section_mediaRepresentation.setLayoutData(LayoutConstants.FILL_HORIZONTALLY(2, 1));
245 section_mediaRepresentation.setEntity(getEntity());
246 //set buffered uri as text if uri had parsing problems in simple view
247 if(uriBuffer!=null){
248 section_mediaRepresentation.getLayoutComposite().getChildren();
249 }
250 }
251 else{
252 if(section_mediaRepresentation!=null){
253 removeElementsAndControls(section_mediaRepresentation);
254 }
255 textUri = formFactory.createUriWithLabelElement(parentFormElement, Messages.MediaDetailElement_Media_URI, null, style);
256 URI uri = singleMediaRepresentationPart.getUri();
257 textUri.setParsedText(uri);
258 //set buffered uri as text if uri had parsing problems in advanced view
259 if(uri==null && uriBuffer!=null){
260 textUri.setText(uriBuffer);
261 textUri.parseText();
262 }
263 textUri.getLayoutComposite().layout();
264 if (isShowImage){
265 LoadImageJob job = new LoadImageJob(singleMediaRepresentationPart.getUri(), LOAD_IMAGE);
266 job.schedule();
267 } else{
268 Button button_showImage = formFactory.createButton(getLayoutComposite(), Messages.MediaDetailElement_SHOW_IMAGE, SWT.PUSH);
269 button_showImage.setLayoutData(LayoutConstants.FILL_HORIZONTALLY(2, 1));
270 button_showImage.addSelectionListener(new SelectionAdapter() {
271 @Override
272 public void widgetSelected(SelectionEvent e) {
273 LoadImageJob job = new LoadImageJob(singleMediaRepresentationPart.getUri(), Messages.MediaDetailElement_LOAD_IMAGE);
274 job.schedule();
275 button_showImage.setText(Messages.MediaDetailElement_RELOAD_IMAGE);
276 }
277 });
278 }
279 }
280 }
281
282 private void initIsAdvancedMediaView(){
283 if(PreferencesUtil.getBooleanValue(IPreferenceKeys.SHOW_ADVANCED_MEDIA_SECTION)){
284 isAdvancedMediaView = true;
285 return;
286 }
287 Set<MediaRepresentation> representations = getEntity().getRepresentations();
288 if(representations.size()>1){
289 isAdvancedMediaView = true;
290 return;
291 }
292 if(representations.size()==1){
293 List<MediaRepresentationPart> parts = representations.iterator().next().getParts();
294 if(parts.size()>1){
295 isAdvancedMediaView = true;
296 return;
297 }
298 }
299 isAdvancedMediaView = false;
300 }
301
302 public boolean isAdvancedMediaView() {
303 return isAdvancedMediaView;
304 }
305
306 public void setUriBuffer(String uriBuffer) {
307 this.uriBuffer = uriBuffer;
308 }
309
310 public String getUriBuffer() {
311 return uriBuffer;
312 }
313
314 }