/*
Copyright (C) 2010 maik.jablonski@gmail.com
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 jfix.util.Files;
import jfix.util.I18N;
import jfix.util.Urls;
import org.apache.commons.io.FileUtils;
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.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.addUploadListener(new ActionListener() {
public void actionPerformed(Event event) {
uploadPerformed(((UploadEvent) event).getMedia());
}
});
download.addClickListener(new ActionListener() {
public void actionPerformed(Event event) {
downloadPerformed();
}
});
rotateImage.addClickListener(new ActionListener() {
public void actionPerformed(Event event) {
try {
setMedia(media.getName(), media.getContentType(),
jfix.util.Images.rotate(Medias.asFile(media)));
} catch (IOException e) {
Modal.exception(e);
}
}
});
aspectRatioLock.setChecked(true);
EventListener dimensionChanged = new EventListener() {
public void onEvent(Event evt) throws Exception {
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());
}
setMedia(media.getName(), media.getContentType(),
jfix.util.Images.scale(Medias.asFile(media),
scaledDimension));
}
};
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 void addUploadListener(final ActionListener actionListener) {
addEventListener(Events.ON_UPLOAD, new EventListener() {
public void onEvent(Event e) throws Exception {
actionListener.actionPerformed(e);
}
});
}
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);
}
}
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()) {
codemirror.setVisible(true);
codemirror.setValue(Medias.asString(media));
codemirror
.setSyntax(Urls.getExtension(media.getName()));
}
}
}
} catch (IOException e) {
throw new RuntimeException(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(Urls.getExtension(target.getName()));
} else {
if (media != null) {
Files.rename(Medias.asFile(media), target);
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public String getContentType() {
if (media == null) {
return null;
}
if (media.getContentType() == null
|| media.getContentType().equals("application/octet-stream")) {
return Urls.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", ""));
originalDimension = jfix.util.Images.getSize(Medias.asFile(media));
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
}
}
}