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.EditAssetAppConfiguration;
37 import info.magnolia.dam.app.ui.field.configuration.PreviewComponentProvider;
38 import info.magnolia.dam.app.ui.field.configuration.ThumbnailComponentProvider;
39 import info.magnolia.dam.app.ui.field.configuration.image.ImageThumbnailComponentProvider;
40 import info.magnolia.dam.app.ui.field.definition.DamUploadFieldDefinition;
41 import info.magnolia.i18nsystem.SimpleTranslator;
42 import info.magnolia.icons.MagnoliaIcons;
43 import info.magnolia.objectfactory.ComponentProvider;
44 import info.magnolia.ui.api.context.UiContext;
45 import info.magnolia.ui.api.overlay.OverlayCloser;
46 import info.magnolia.ui.form.field.upload.basic.ResurfaceBasicUploadField;
47 import info.magnolia.ui.imageprovider.ImageProvider;
48 import info.magnolia.ui.mediaeditor.MediaEditorPresenter;
49 import info.magnolia.ui.mediaeditor.MediaEditorPresenterFactory;
50 import info.magnolia.ui.mediaeditor.event.MediaEditorCompletedEvent;
51 import info.magnolia.ui.vaadin.overlay.MessageStyleTypeEnum;
52
53 import java.io.FileInputStream;
54 import java.io.FileNotFoundException;
55 import java.io.InputStream;
56
57 import org.apache.commons.io.FileUtils;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
60
61 import com.vaadin.server.Resource;
62 import com.vaadin.server.StreamResource;
63 import com.vaadin.ui.Button;
64 import com.vaadin.ui.Component;
65 import com.vaadin.ui.CssLayout;
66 import com.vaadin.ui.Label;
67 import com.vaadin.ui.Layout;
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88 public class ResurfaceDamUploadField<D extends AssetUploadReceiver> extends ResurfaceBasicUploadField<D> {
89
90 private static final Logger log = LoggerFactory.getLogger(ResurfaceDamUploadField.class);
91
92 private final MediaEditorPresenterFactory mediaEditorFactory;
93 private final ComponentProvider componentProvider;
94 private boolean imageThumbnail = false;
95
96 public ResurfaceDamUploadField(ImageProvider imageProvider, UiContext uiContext, MediaEditorPresenterFactory mediaEditorFactory, ComponentProvider componentProvider, DamUploadFieldDefinition definition, SimpleTranslator i18n) {
97 super(imageProvider, uiContext, definition, i18n);
98
99 populateFromDefinition(definition);
100
101 this.mediaEditorFactory = mediaEditorFactory;
102 this.componentProvider = componentProvider;
103 }
104
105
106
107
108 @Override
109 protected Component getFileDetailSize() {
110 Label label = new Label();
111 label.setCaption(getI18n().translate(fileDetailSizeCaption));
112 StringBuilder sb = new StringBuilder();
113 if (getValue().isImage()) {
114 sb.append(getValue().getWidth() + " x " + getValue().getHeight() + ", ");
115 }
116 sb.append(FileUtils.byteCountToDisplaySize(getValue().getFileSize()));
117 if (getValue().getDuration() > 0) {
118 sb.append("(x:x min)");
119 }
120
121 label.setValue(sb.toString());
122 return label;
123 }
124
125 @Override
126 protected void addControlActions(CssLayout uploadZone) {
127 super.addControlActions(uploadZone);
128 final EditAssetAppConfiguration editAssetAppConfiguration = getValue().getEditAssetAppConfiguration();
129 if (getValue() != null && !getValue().isEmpty() && editAssetAppConfiguration.hasEditConfig()) {
130 uploadZone.addComponent(createEditButton());
131 }
132
133 if (getValue().getEditAssetAppConfiguration().hasPreviewConfig()) {
134 uploadZone.addComponent(createOpenLightboxButton());
135 }
136 }
137
138 @Override
139 protected Component createThumbnailComponent() {
140 final Component previewComponent = createPreviewComponent();
141 previewComponent.addStyleName("file-preview");
142 return previewComponent;
143 }
144
145 @Override
146 protected Layout createCompletedActionLayout() {
147 final Layout completedActionLayout = super.createCompletedActionLayout();
148 completedActionLayout.removeStyleName("done-img");
149 if (imageThumbnail) {
150 completedActionLayout.addStyleName("done-img");
151 }
152 return completedActionLayout;
153 }
154
155 @Override
156 protected void buildEmptyLayout() {
157 super.buildEmptyLayout();
158 getUploadZone().removeStyleName("done-img");
159 }
160
161
162
163
164
165 private Button createEditButton() {
166 Button editButton = createControlButton(deleteCaption, MagnoliaIcons.EDIT);
167
168 editButton.addClickListener((Button.ClickListener) event -> {
169
170 try {
171 openMediaEditor();
172 } catch (FileNotFoundException fnfe) {
173 log.warn("could not open MediaEditor");
174 uiContext.openAlert(MessageStyleTypeEnum.ERROR, "ERROR", getI18n().translate("dam.assets.uploadField.alert.couldNotOpenMediaEditor")
175 + " "
176 + getValue().getEditAssetAppConfiguration().getEditConfig().getMediaEditorId(),
177 "ok", null);
178 } finally {
179 event.getButton().setEnabled(true);
180 }
181 });
182
183 editButton.setDescription(getI18n().translate("field.upload.edit.file"));
184 editButton.setDisableOnClick(true);
185 return editButton;
186 }
187
188 private Button createOpenLightboxButton() {
189 Button lightboxButton = createControlButton(deleteCaption, MagnoliaIcons.SEARCH);
190 lightboxButton.addClickListener((Button.ClickListener) event -> {
191
192 Class<? extends PreviewComponentProvider> previewActionClass = getValue().getEditAssetAppConfiguration().getPreviewConfig().getPreviewComponentProviderClass();
193 if (previewActionClass != null) {
194 PreviewComponentProvider implementation = componentProvider.newInstance(previewActionClass);
195 implementation.open(getResource());
196 } else {
197 log.warn("No Preview Defined is defined ");
198 }
199 });
200 lightboxButton.setDescription(getI18n().translate("field.upload.select.lightbox"));
201 return lightboxButton;
202 }
203
204
205
206
207
208
209
210 private void openMediaEditor() throws FileNotFoundException {
211
212 String presenterById;
213 if (getValue().getEditAssetAppConfiguration() == null || !getValue().getEditAssetAppConfiguration().hasEditConfig()) {
214 log.warn("No Media Editor defined for the following mimeType {} ", getValue().getMimeType());
215 return;
216 } else {
217 presenterById = "ui-mediaeditor:" + getValue().getEditAssetAppConfiguration().getEditConfig().getMediaEditorId();
218 log.debug("Will open the following mediaEditor Presenter {}", presenterById);
219 }
220
221 final Button mediaEditorPlaceholder = new Button(getI18n().translate("dam.assets.uploadField.button.mediaEditorPlaceholder"));
222 mediaEditorPlaceholder.addStyleName("btn-form btn-form-commit");
223
224 MediaEditorPresenter mediaEditorPresenter = mediaEditorFactory.getPresenterById(presenterById);
225 final InputStream inputStream = new FileInputStream(getValue().getFile());
226 final OverlayCloser overlayCloser = uiContext.openOverlay(mediaEditorPresenter.start(inputStream));
227 mediaEditorPresenter.addCompletionHandler(new MediaEditorCompletedEvent.Handler() {
228 @Override
229 public void onSubmit(MediaEditorCompletedEvent event) {
230 getValue().updateContent(event.getStream());
231
232 updateDisplay();
233 overlayCloser.close();
234 closeInputStream(inputStream);
235 getPropertyDataSource().setValue(getValue());
236 }
237
238 @Override
239 public void onCancel(MediaEditorCompletedEvent event) {
240 overlayCloser.close();
241 closeInputStream(inputStream);
242 }
243
244 private void closeInputStream(InputStream inputStream) {
245 try {
246 if (inputStream != null) {
247 inputStream.close();
248 }
249 } catch (Exception e) {
250 log.warn("Could not close the InputStream ", e);
251 }
252 }
253 });
254 }
255
256
257
258
259 private Resource getResource() {
260 final StreamResource.StreamSource source = (StreamResource.StreamSource) () -> {
261 try {
262 return new FileInputStream(getValue().getFile());
263 } catch (FileNotFoundException fnfe) {
264 log.warn("could not found File", fnfe);
265 return null;
266 }
267 };
268
269 return new StreamResource(source, "") {
270 @Override
271 public String getMIMEType() {
272 return getValue().getMimeType();
273 }
274 };
275 }
276
277 private Component createPreviewComponent() {
278
279 final EditAssetAppConfiguration editAssetAppConfiguration = getValue().getEditAssetAppConfiguration();
280
281 if (editAssetAppConfiguration == null) {
282 return super.createThumbnailComponent();
283 }
284
285 Class<? extends ThumbnailComponentProvider> thumbnailProviderClass = editAssetAppConfiguration.getThumbnailComponentProviderClass();
286 if (thumbnailProviderClass != null) {
287 ThumbnailComponentProvider implementation = componentProvider.newInstance(thumbnailProviderClass);
288 final Component thumbnailComponent = implementation.createThumbnailComponent(null, getValue().getFile(), getValue().getMimeType());
289 if (ImageThumbnailComponentProvider.class.isInstance(implementation)) {
290 thumbnailComponent.addStyleName("img-preview");
291 this.imageThumbnail = true;
292 } else {
293 this.imageThumbnail = false;
294 }
295 return thumbnailComponent;
296 } else {
297 log.warn("No ThumbnailComponentProvider is defined ");
298 return super.createThumbnailComponent();
299 }
300 }
301 }