1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.dam.app.ui.field.upload;
35
36 import info.magnolia.dam.app.ui.field.configuration.PreviewComponentProvider;
37 import info.magnolia.dam.app.ui.field.configuration.ThumbnailComponentProvider;
38 import info.magnolia.dam.app.ui.field.definition.DamUploadFieldDefinition;
39 import info.magnolia.i18nsystem.SimpleTranslator;
40 import info.magnolia.objectfactory.ComponentProvider;
41 import info.magnolia.ui.api.context.UiContext;
42 import info.magnolia.ui.api.overlay.OverlayCloser;
43 import info.magnolia.ui.form.field.upload.basic.BasicUploadField;
44 import info.magnolia.ui.imageprovider.ImageProvider;
45 import info.magnolia.ui.mediaeditor.MediaEditorPresenter;
46 import info.magnolia.ui.mediaeditor.MediaEditorPresenterFactory;
47 import info.magnolia.ui.mediaeditor.event.MediaEditorCompletedEvent;
48 import info.magnolia.ui.vaadin.overlay.MessageStyleTypeEnum;
49
50 import java.io.FileInputStream;
51 import java.io.FileNotFoundException;
52 import java.io.InputStream;
53
54 import org.apache.commons.io.FileUtils;
55 import org.apache.commons.lang3.StringUtils;
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
58
59 import com.google.common.net.MediaType;
60 import com.vaadin.server.Resource;
61 import com.vaadin.server.StreamResource;
62 import com.vaadin.server.StreamResource.StreamSource;
63 import com.vaadin.ui.Alignment;
64 import com.vaadin.ui.Button;
65 import com.vaadin.ui.Button.ClickEvent;
66 import com.vaadin.ui.Component;
67 import com.vaadin.ui.CssLayout;
68 import com.vaadin.ui.Layout;
69 import com.vaadin.ui.NativeButton;
70 import com.vaadin.v7.ui.HorizontalLayout;
71 import com.vaadin.v7.ui.Label;
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92 public class DamUploadField<D extends AssetUploadReceiver> extends BasicUploadField<D> {
93 private static final long serialVersionUID = 1L;
94 private static final Logger log = LoggerFactory.getLogger(DamUploadField.class);
95
96 private final SimpleTranslator i18n;
97
98
99 private MediaEditorPresenterFactory mediaEditorFactory;
100 private ComponentProvider componentProvider;
101 private String lightboxCaption;
102 private String editFileCaption;
103
104 public DamUploadField(ImageProvider imageProvider, UiContext uiContext, MediaEditorPresenterFactory mediaEditorFactory, ComponentProvider componentProvider, DamUploadFieldDefinition definition, SimpleTranslator i18n) {
105 super(imageProvider, uiContext, definition, i18n);
106
107 populateFromDefinition(definition);
108
109 this.mediaEditorFactory = mediaEditorFactory;
110 this.componentProvider = componentProvider;
111 this.i18n = i18n;
112 }
113
114
115
116
117 @Override
118 protected Component getFileDetailSize() {
119 Label label = new Label();
120 label.setCaption(i18n.translate(fileDetailSizeCaption));
121 StringBuilder sb = new StringBuilder();
122 if (getValue().isImage()) {
123 sb.append(getValue().getWidth() + " x " + getValue().getHeight() + ", ");
124 }
125 sb.append(FileUtils.byteCountToDisplaySize(getValue().getFileSize()));
126 if (getValue().getDuration() > 0) {
127 sb.append("(x:x min)");
128 }
129
130 label.setValue(sb.toString());
131 return label;
132 }
133
134
135
136
137
138 @Override
139 protected Layout createCompletedActionLayout() {
140 if (isReadOnly()) {
141 return new HorizontalLayout();
142 }
143
144 HorizontalLayout actionLayout = new HorizontalLayout();
145 actionLayout.setSizeUndefined();
146 actionLayout.addStyleName("buttons");
147 actionLayout.setSpacing(true);
148
149 if (getValue() != null && !getValue().isEmpty() && getValue().getEditAssetAppConfiguration().hasEditConfig()) {
150 Button edit = createEditButton();
151 actionLayout.addComponent(edit);
152 }
153
154 getUpload().setButtonCaption(getCaption(selectAnotherCaption, null));
155 actionLayout.addComponent(getUpload());
156
157 if (getValue() != null && !getValue().isEmpty()) {
158 Button delete = createDeleteButton();
159 actionLayout.addComponent(delete);
160 actionLayout.setComponentAlignment(delete, Alignment.MIDDLE_LEFT);
161 }
162 return actionLayout;
163 }
164
165
166
167
168
169 private Button createEditButton() {
170 Button editButton = new Button(getCaption(editFileCaption, null), createEditButtonListener());
171 editButton.setDisableOnClick(true);
172 editButton.addStyleName("edit");
173 return editButton;
174 }
175
176 private Button.ClickListener createEditButtonListener() {
177 return new Button.ClickListener() {
178 private static final long serialVersionUID = 1L;
179
180 @Override
181 public void buttonClick(ClickEvent event) {
182
183 try {
184 openMediaEditor();
185 } catch (FileNotFoundException fnfe) {
186 log.warn("could not open MediaEditor");
187 uiContext.openAlert(MessageStyleTypeEnum.ERROR, "ERROR", i18n.translate("dam.assets.uploadField.alert.couldNotOpenMediaEditor")
188 + " "
189 + getValue().getEditAssetAppConfiguration().getEditConfig().getMediaEditorId(),
190 "ok", null);
191 } finally {
192 event.getButton().setEnabled(true);
193 }
194 }
195 };
196 }
197
198
199
200
201
202
203
204 private void openMediaEditor() throws FileNotFoundException {
205
206 String presenterById;
207 if (getValue().getEditAssetAppConfiguration() == null || !getValue().getEditAssetAppConfiguration().hasEditConfig()) {
208 log.warn("No Media Editor defined for the following mimeType {} ", getValue().getMimeType());
209 return;
210 } else {
211 presenterById = "ui-mediaeditor:" + getValue().getEditAssetAppConfiguration().getEditConfig().getMediaEditorId();
212 log.debug("Will open the following mediaEditor Presenter {}", presenterById);
213 }
214
215 final NativeButton mediaEditorPlaceholder = new NativeButton(i18n.translate("dam.assets.uploadField.button.mediaEditorPlaceholder"));
216 mediaEditorPlaceholder.addStyleName("btn-form btn-form-commit");
217
218 MediaEditorPresenter mediaEditorPresenter = mediaEditorFactory.getPresenterById(presenterById);
219 final InputStream inputStream = new FileInputStream(getValue().getFile());
220 final OverlayCloser overlayCloser = uiContext.openOverlay(mediaEditorPresenter.start(inputStream));
221 mediaEditorPresenter.addCompletionHandler(new MediaEditorCompletedEvent.Handler() {
222 @Override
223 public void onSubmit(MediaEditorCompletedEvent event) {
224 getValue().updateContent(event.getStream());
225
226 updateDisplay();
227 overlayCloser.close();
228 closeInputStream(inputStream);
229 getPropertyDataSource().setValue(getValue());
230 }
231
232 @Override
233 public void onCancel(MediaEditorCompletedEvent event) {
234 overlayCloser.close();
235 closeInputStream(inputStream);
236 }
237
238 private void closeInputStream(InputStream inputStream) {
239 try {
240 if (inputStream != null) {
241 inputStream.close();
242 }
243 } catch (Exception e) {
244 log.warn("Could not close the InputStream ", e);
245 }
246 }
247 });
248 }
249
250
251
252
253
254
255
256
257 @Override
258 protected Component createThumbnailComponent() {
259
260 CssLayout previewLayout = new CssLayout();
261 previewLayout.addStyleName("file-preview-area");
262 previewLayout.setWidth("150px");
263 previewLayout.setHeight("150px");
264
265 Component image = createPreviewComponent();
266 if (image != null) {
267 image.addStyleName("preview-image");
268 previewLayout.addComponent(image);
269 }
270
271
272 if (getValue().getEditAssetAppConfiguration().hasEditConfig() && !isReadOnly()) {
273 Button editButton = new Button();
274 editButton.addStyleName("edit-button");
275 editButton.setHtmlContentAllowed(true);
276 editButton.setCaption("<span class=\"" + getValue().getEditAssetAppConfiguration().getEditConfig().getIconStyleName() + "\"></span>");
277 editButton.setDescription(getCaption(editFileCaption, null));
278 previewLayout.addComponent(editButton);
279
280
281 editButton.setDisableOnClick(true);
282 editButton.addClickListener(createEditButtonListener());
283 }
284
285
286 if (getValue().getEditAssetAppConfiguration().hasPreviewConfig()) {
287 Button lightboxButton = new Button();
288 lightboxButton.addStyleName("lightbox-button");
289 lightboxButton.setHtmlContentAllowed(true);
290 lightboxButton.setCaption("<span class=\"" + getValue().getEditAssetAppConfiguration().getPreviewConfig().getIconStyleName() + "\"></span>");
291 lightboxButton.setDescription(i18n.translate(lightboxCaption));
292 previewLayout.addComponent(lightboxButton);
293
294 lightboxButton.addClickListener(new Button.ClickListener() {
295 private static final long serialVersionUID = 1L;
296
297 @Override
298 public void buttonClick(ClickEvent event) {
299
300 Class<? extends PreviewComponentProvider> previewActionClass = getValue().getEditAssetAppConfiguration().getPreviewConfig().getPreviewComponentProviderClass();
301 if (previewActionClass != null) {
302 PreviewComponentProvider implementation = componentProvider.newInstance(previewActionClass);
303 implementation.open(getResource());
304 } else {
305 log.warn("No Preview Defined is defined ");
306 }
307 }
308 });
309 }
310 return previewLayout;
311 }
312
313
314
315
316
317
318 private Component createPreviewComponent() {
319 Class<? extends ThumbnailComponentProvider> thumbnailProviderClass = getValue().getEditAssetAppConfiguration().getThumbnailComponentProviderClass();
320 if (thumbnailProviderClass != null) {
321 ThumbnailComponentProvider implementation = componentProvider.newInstance(thumbnailProviderClass);
322 return implementation.createThumbnailComponent(null, getValue().getFile(), getValue().getMimeType());
323 } else {
324 log.warn("No ThumbnailComponentProvider is defined ");
325 return null;
326 }
327 }
328
329
330
331
332 private Resource getResource() {
333 final StreamSource source = new StreamResource.StreamSource() {
334 private static final long serialVersionUID = 1L;
335
336 @Override
337 public InputStream getStream() {
338 try {
339 return new FileInputStream(getValue().getFile());
340 } catch (FileNotFoundException fnfe) {
341 log.warn("could not found File", fnfe);
342 return null;
343 }
344 }
345 };
346
347 return new StreamResource(source, "") {
348 @Override
349 public String getMIMEType() {
350 return getValue().getMimeType();
351 }
352 };
353 }
354
355 protected void populateFromDefinition(DamUploadFieldDefinition definition) {
356 super.populateFromDefinition(definition);
357 this.setLightboxCaption(definition.getLightboxCaption());
358 this.setEditFileCaption(definition.getEditFileCaption());
359 }
360
361
362
363
364 @Override
365 protected void setCaptionExtension(String mimeType) {
366 if (StringUtils.isNotBlank(mimeType)) {
367 captionExtension = MediaType.parse(mimeType).type();
368 } else if (StringUtils.isNotBlank(getValue().getMimeType())) {
369 captionExtension = MediaType.parse(getValue().getMimeType()).type();
370 }
371 }
372
373 public void setLightboxCaption(String lightboxCaption) {
374 this.lightboxCaption = lightboxCaption;
375 }
376
377 public void setEditFileCaption(String editFileCaption) {
378 this.editFileCaption = editFileCaption;
379 }
380 }