/* * Copyright 2011 Uwe Krueger. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.mandelsoft.mand.tool; import com.mandelsoft.swing.worker.UIFunction; import com.mandelsoft.swing.worker.UIExecution; import com.mandelsoft.mand.MandelInfo; import com.mandelsoft.mand.QualifiedMandelName; import com.mandelsoft.mand.Settings; import com.mandelsoft.mand.cm.ColormapModel; import com.mandelsoft.mand.cm.ColormapModel.ResizeMode; import com.mandelsoft.mand.cm.ColormapSource; import com.mandelsoft.mand.cm.ColormapSourceFactory; import com.mandelsoft.mand.image.MandelAreaImage; import com.mandelsoft.mand.mapping.Mapper; import com.mandelsoft.mand.scan.MandelHandle; import com.mandelsoft.mand.scan.MandelScanner; import com.mandelsoft.mand.util.CachedUpstreamColormapSourceFactory; import com.mandelsoft.mand.util.MandelList; import com.mandelsoft.mand.util.SimpleColormapSourceFactory; import com.mandelsoft.swing.worker.CallbackWorker; import com.mandelsoft.swing.worker.ErrorNotification; import com.mandelsoft.swing.worker.WorkerProgressMonitor; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.imageio.ImageIO; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JOptionPane; /** * * @author Uwe Krüger */ public class PictureSaveDialog extends MandelDialog { private PictureSavePanel panel; private List<MandelHandle> list; private PictureSaveDialog(MandelWindowAccess owner, String name) { super(owner,name); //System.out.println("create control dialog '"+name+"' for "+owner); panel=createPictureSavePanel(); panel.updateState(); this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); setup(); add(panel); pack(); } public PictureSaveDialog(MandelWindowAccess owner, String name, List<MandelHandle> list) { this(owner,name); this.list=list; } public PictureSaveDialog(MandelWindowAccess owner, String name, MandelList list) { this(owner,name); this.list=new ArrayList<MandelHandle>(); MandelScanner s=getEnvironment().getImageDataScanner(); for (QualifiedMandelName n:list) { MandelHandle h=s.getMandelHandle(n); if (h!=null) this.list.add(h); } } protected PictureSavePanel createPictureSavePanel() { return new PicturePanel(); } protected void setup() { } ////////////////////////////////////////////////////////////////////////// public class PicturePanel extends PictureSavePanel { private JButton save; public PicturePanel() { super("Image directory", JFileChooser.DIRECTORIES_ONLY); ResetAction reset; save=addButton("Save", new SaveImageAction(),"Save picture file"); addButton("Clear", new ClearAction(),"Clear file name"); addButton("Reset", reset=new ResetAction(),"Generate picture path name"); reset.actionPerformed(null); } public MandelWindowAccess getMandelWindowAccess() { return PictureSaveDialog.this.getMandelWindowAccess(); } ///////////////////////////////////////////////////////////////////////// private class ResetAction implements ActionListener { public void actionPerformed(ActionEvent e) { ToolEnvironment env=getEnvironment(); QualifiedMandelName mn=getMandelWindowAccess().getQualifiedName(); String n=env.getProperty(Settings.BITMAP_SAVE_PATH); if (n==null) n="."; imagefile.setFilename(n); } } ///////////////////////////////////////////////////////////////////////// private class SaveImageAction implements ActionListener { private Worker task; public void actionPerformed(ActionEvent e) { int width; String path=imagefile.getFilename(); File file=new File(path); if (!file.exists()) { int o=JOptionPane.showOptionDialog(getOwner(), "Create Directory", path, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null); if (o!=0) return; if (!file.mkdirs()) { JOptionPane.showMessageDialog(getOwner(), "cannot create directoty", //text to display "Image IO", //title JOptionPane.ERROR_MESSAGE); return; } } if (!file.isDirectory()) { JOptionPane.showMessageDialog(getOwner(), path+" is no directory", //text to display "Image IO", //title JOptionPane.ERROR_MESSAGE); return; } save.setEnabled(false); try { width=PicturePanel.this.width.getValue().intValue(); } catch (Exception ex) { width=0; } task=new Worker(list, getMandelWindowAccess(), imagefile.getFilename(), (String)formats.getSelectedItem(), width, decorationButton.isSelected()); new WorkerProgressMonitor(PictureSaveDialog.this, "Writing Images", task); } } ///////////////////////////////////////////////////////////////////////// private class PathAction implements ActionListener { public void actionPerformed(ActionEvent e) { ToolEnvironment env=getEnvironment(); QualifiedMandelName mn=getMandelWindowAccess().getQualifiedName(); String n=env.getProperty(Settings.BITMAP_SAVE_PATH); if (n==null) n=""; imagefile.setFilename(n); } } } private static class OverwriteQuestion extends UIFunction<PictureSaveDialog,Integer> { private File file; public OverwriteQuestion(File file) { this.file=file; } synchronized public void execute(PictureSaveDialog d) { Object[] options={"Replace", "Ignore", "Replace all", "Ignore all", "Cancel"}; int o=JOptionPane.showOptionDialog(d, file.getName()+" already exists.\n"+ "Do you want to replace it?", "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[1]); setResult(o); } } ////////////////////////////////////////////////////////////////////// // Worker ////////////////////////////////////////////////////////////////////// private class Worker extends CallbackWorker<Void, UIExecution, PictureSaveDialog> { private List<MandelHandle> list; private ColormapSourceFactory cmfac; private Mapper mapper; private ResizeMode mode; private ToolEnvironment env; private String path; private String fmt; private int width; private boolean showDecoration; public Worker(List<MandelHandle> list, MandelWindowAccess acc, String path, String fmt, int width, boolean showDecoration) { super(PictureSaveDialog.this); ColormapSource cm; ColormapModel cmm; this.list=list; this.env=acc.getEnvironment(); cmm=acc.getColormapModel(); cm=cmm.getColormap(); this.mode=cmm.getResizeMode(); this.mapper=acc.getMapperModel().getMapper(); MandelImagePanel mp=acc.getMandelImagePane(); if (mp!=null&&mp.getParentColormapModel().isSet()) { cmfac=new CachedUpstreamColormapSourceFactory(env.getImageDataScanner(), mp.getColormapModel(), env.getColormapCache()); System.out.println("-> save with upstream colormap"); } else { System.out.println("-> save with main colormap"); cmfac=new SimpleColormapSourceFactory(cm); } this.path=path; this.fmt=fmt; this.width=width; this.showDecoration=showDecoration; } public Decoration getDecoration(MandelInfo info) { Decoration decoration=new Decoration(); decoration.setShowDecoration(showDecoration); decoration.setDecoration(env.getCopyright(info)); System.out.println("*** decoration is "+decoration); return decoration; } public MandelAreaImage getMandelImage(MandelHandle h) throws IOException { ColormapSource cm=cmfac.getColormapSource(h.getName()); return env.getMandelImage(h, mode, cm, mapper, null); } @Override protected void done() { setProgress(100); PictureSaveDialog.this.dispose(); } @Override protected Void doInBackground() throws Exception { int c=0; boolean overwrite=false; boolean oset=false; for (MandelHandle handle:list) { String name=path+"/"+handle.getName()+"."+fmt; if (this.isCancelled()) { break; } try { File f=new File(name); if (f.exists()) { if (!oset) { int r=call(new OverwriteQuestion(f)); if (r==4) { break; } overwrite=(r%2)==0; oset=r>1; } if (!overwrite) { System.out.println("cancel "+name); continue; } } MandelAreaImage mai=getMandelImage(handle); BufferedImage im=mai.getImage(); BufferedImage tmp=null; Graphics g=null; int w=width; int h; if (w!=0) { h=w*im.getHeight()/im.getWidth(); tmp=new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); (g=tmp.getGraphics()).drawImage(im, 0, 0, w, h, null); im=tmp; } Decoration decoration=getDecoration(mai.getInfo()); if (decoration!=null && decoration.showDecoration()) { if (tmp==null) { tmp=new BufferedImage(im.getWidth(), im.getHeight(), BufferedImage.TYPE_INT_RGB); (g=tmp.getGraphics()).drawImage(im, 0, 0, null); im=tmp; } if (g==null) g=im.getGraphics(); decoration.paintDecoration(g, im.getWidth(), im.getHeight()); } try { ImageIO.write(im, fmt, f); } catch (Exception ex) { call(new ErrorNotification("Image IO", "Cannot write image: "+ex. toString())); } } catch (IOException ex) { call(new ErrorNotification("Image IO", "Cannot find area image: "+ex. toString())); } finally { setProgress(++c*100/list.size()); System.out.println("written "+name+" ("+c+"/"+list.size()+")"); } } setProgress(100); return null; } } }