jfix.zk.Mediafield.java Source code

Java tutorial

Introduction

Here is the source code for jfix.zk.Mediafield.java

Source

/*
Copyright (C) 2016 maik.jablonski@jease.org
    
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
    
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package jfix.zk;

import java.awt.Dimension;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;

import jfix.util.I18N;
import jfix.util.MimeTypes;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.zkoss.codemirror.Codemirror;
import org.zkoss.image.AImage;
import org.zkoss.util.media.AMedia;
import org.zkoss.util.media.Media;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.UploadEvent;
import org.zkoss.zul.Button;
import org.zkoss.zul.Checkbox;
import org.zkoss.zul.Image;
import org.zkoss.zul.Vbox;

public class Mediafield extends Vbox {

    private boolean preview;
    private Media media = null;
    private Codemirror codemirror = new Codemirror();
    private Image image = new Image();
    private Button rotateImage = new Button(I18N.get("Rotate"), Images.EditRedo);
    private Spinner width = new Spinner();
    private Spinner height = new Spinner();
    private Checkbox aspectRatioLock = new Checkbox();
    private Column imagePreview = new Column(image, new Row(width, aspectRatioLock, height, rotateImage));
    private Fileupload upload = new Fileupload();
    private Button download = new Button();
    private Dimension originalDimension = null;

    public Mediafield() {
        setHflex("1");
        upload.addEventListener(Events.ON_UPLOAD, $event -> uploadPerformed(((UploadEvent) $event).getMedia()));
        download.addEventListener(Events.ON_CLICK, $event -> downloadPerformed());
        rotateImage.addEventListener(Events.ON_CLICK, $event -> {
            try {
                File imageFile = Medias.asFile(media);
                imageFile.deleteOnExit();
                File rotatedImage = jfix.util.Images.rotate(imageFile);
                rotatedImage.deleteOnExit();
                setMedia(media.getName(), media.getContentType(), rotatedImage);
            } catch (IOException e) {
                Modal.exception(e);
            }

        });

        aspectRatioLock.setChecked(true);
        EventListener<Event> dimensionChanged = $event -> {
            Dimension scaledDimension = null;
            if (aspectRatioLock.isChecked()) {
                scaledDimension = jfix.util.Images.scaleDimension(originalDimension,
                        new Dimension(width.intValue(), height.intValue()));
                width.setValue((int) scaledDimension.getWidth());
                height.setValue((int) scaledDimension.getHeight());
            } else {
                scaledDimension = new Dimension(width.intValue(), height.intValue());
            }
            File imageFile = Medias.asFile(media);
            imageFile.deleteOnExit();
            File scaledImage = jfix.util.Images.scale(imageFile, scaledDimension);
            scaledImage.deleteOnExit();
            setMedia(media.getName(), media.getContentType(), scaledImage);
        };
        width.addEventListener(Events.ON_CHANGE, dimensionChanged);
        height.addEventListener(Events.ON_CHANGE, dimensionChanged);

        setHeight("300px");
        setPreview(true);
        codemirror.setVisible(false);
        imagePreview.setVisible(false);
        width.setStep(10);
        height.setStep(10);

        download.setImage(Images.DriveRemovableMedia);
        download.setVisible(false);

        appendChild(codemirror);
        appendChild(imagePreview);
        appendChild(new Row(download, upload));
    }

    public void setHeight(String height) {
        codemirror.setHeight(height);
        image.setHeight(height);
    }

    private void uploadPerformed(Media uploadedMedia) {
        if (uploadedMedia != null) {
            this.media = uploadedMedia;
            Events.sendEvent(new Event(Events.ON_UPLOAD, this));
            updateMediaViewer();
        }
    }

    private void downloadPerformed() {
        Filedownload.save(media);
    }

    public Media getMedia() {
        return media;
    }

    public void setMedia(String name, String contentType, File file) {
        try {
            if (file != null && file.exists()) {
                setMedia(new AMedia(name, null, contentType, file, true));
            } else {
                setMedia(null);
            }
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    public void setMedia(Media media) {
        this.media = media;
        updateMediaViewer();
    }

    private void updateMediaViewer() {
        try {
            download.setVisible(media != null);
            imagePreview.setVisible(false);
            codemirror.setVisible(false);
            download.setLabel(I18N.get("Download") + " (" + getContentType() + ")");
            if (isPreview()) {
                if (getContentType() != null) {
                    if (getContentType().startsWith("image")) {
                        InputStream input = Medias.asStream(media);
                        imagePreview.setVisible(true);
                        image.setContent(new AImage(getName(), input));
                        input.close();
                        adjustImage();
                    }
                    if (isContentTypeEditable()) {
                        String mediaString = Medias.asString(media);
                        if (mediaString.length() < 1024 * 1024) {
                            codemirror.setVisible(true);
                            codemirror.setValue(Medias.asString(media));
                            codemirror.setSyntax(FilenameUtils.getExtension(media.getName()));
                        }
                    }
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    public boolean isEmpty() {
        return media == null;
    }

    public void copyToFile(File target) {
        if (target == null) {
            return;
        }
        try {
            if (codemirror.isVisible()) {
                FileUtils.writeStringToFile(target, codemirror.getValue(), "UTF-8");
                codemirror.setSyntax(FilenameUtils.getExtension(target.getName()));
            } else {
                if (media != null) {
                    Files.move(Medias.asFile(media).toPath(), target.toPath(), StandardCopyOption.REPLACE_EXISTING);
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    public String getContentType() {
        if (media == null) {
            return null;
        }
        if (media.getContentType() == null || media.getContentType().equals("application/octet-stream")) {
            return MimeTypes.guessContentTypeFromName(media.getName());
        } else {
            return media.getContentType();
        }
    }

    private boolean isContentTypeEditable() {
        String ctype = getContentType();
        return ctype != null && (ctype.startsWith("text") || ctype.equals("application/javascript"));
    }

    public String getName() {
        return media != null ? media.getName() : null;
    }

    public void setPreview(boolean preview) {
        this.preview = preview;
    }

    public boolean isPreview() {
        return preview;
    }

    private void adjustImage() {
        try {
            int textHeight = Integer.parseInt(codemirror.getHeight().replace("px", ""));
            File imageFile = Medias.asFile(media);
            imageFile.deleteOnExit();
            originalDimension = jfix.util.Images.getSize(imageFile);
            width.setValue((int) originalDimension.getWidth());
            height.setValue((int) originalDimension.getHeight());
            int imageHeight = (int) originalDimension.getHeight();
            int minHeight = Math.min(imageHeight, textHeight);
            image.setHeight(minHeight + "px");
        } catch (Throwable e) {
            // pass
        }
    }

    public void setUploadLimit(String limit) {
        upload.setUploadLimit(limit);
    }
}