/* * 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.mand.cm.ColormapSourceFactory; import com.mandelsoft.mand.tool.thumb.ImageChangeListener; import java.awt.Dimension; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.event.ActionEvent; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.DropMode; import javax.swing.TransferHandler; import javax.swing.table.AbstractTableModel; import com.mandelsoft.mand.image.MandelImage.Factory; import com.mandelsoft.mand.MandelName; import com.mandelsoft.mand.QualifiedMandelName; import com.mandelsoft.mand.scan.MandelHandle; import com.mandelsoft.mand.scan.MandelScanner; import com.mandelsoft.mand.tool.thumb.AsyncThumbnailFactory; import com.mandelsoft.util.DateTime; /** * * @author Uwe Krüger */ public abstract class AbstractMandelListTableModel extends AbstractTableModel implements MandelListTableModel { public static boolean debug=false; protected List<Action> actions; private AsyncThumbnailFactory factory; private boolean modifiable; private boolean showlocation; //////////////////////////////////////////////////////////////////// private int[] columnMapping; static public final int NAME = 0; static public final int QUALIFIER = 1; static public final int TYPE = 2; static public final int LOCATION = 3; static public final int TIME = 4; static private final int[] m_local= new int[]{NAME,QUALIFIER,TYPE,TIME}; static private final int[] m_located= new int[]{NAME,QUALIFIER,LOCATION,TYPE,TIME}; //////////////////////////////////////////////////////////////////// protected AbstractMandelListTableModel() { columnMapping=m_local; factory=new AsyncThumbnailFactory(new AsyncThumbnailFactory.Client() { public boolean usesThumbnail(QualifiedMandelName name) { return AbstractMandelListTableModel.this.getList().contains(name); } public MandelScanner getMandelScanner() { return AbstractMandelListTableModel.this.getMandelScanner(); } }); } public boolean isShowLocation() { return showlocation; } public void setShowLocation(boolean showlocation) { boolean old=this.showlocation; this.showlocation=showlocation; if (showlocation) columnMapping=m_local; else columnMapping=m_located; if (old!=showlocation) fireTableStructureChanged(); } public void removeImageChangeListener(ImageChangeListener l) { factory.removeImageChangeListener(l); } public void addImageChangeListener(ImageChangeListener l) { factory.addImageChangeListener(l); } public void setModifiable(boolean m) { this.modifiable=m; } public void setColormapSourceFactory(ColormapSourceFactory colmapfac) { factory.setColormapSourceFactory(colmapfac); } public ColormapSourceFactory getColormapSourceFactory() { return factory.getColormapSourceFactory(); } public void setFactory(Factory factory) { this.factory.setFactory(factory); } public boolean isModifiable() { return modifiable; } public void addAction(Action a) { if (actions==null) actions=new ArrayList<Action>(); actions.add(a); } public void removeAction(Action a) { if (actions!=null) actions.remove(a); } public List<Action> getActions() { return actions; } protected void checkModifiable() { if (!isModifiable()) throw new UnsupportedOperationException(); } public void refresh() { refresh(false); } ////////////////////////////////////////////////////////////////////////// public BufferedImage getThumbnail(int index, Dimension max) { QualifiedMandelName n=getQualifiedName(index); return factory.getThumbnail(n,max); } public BufferedImage getThumbnail(QualifiedMandelName n, Dimension max) { return factory.getThumbnail(n, max); } protected void cleanupThumbnail(QualifiedMandelName name) { factory.remove(name); } public MandelName getName(int index) { QualifiedMandelName n=getQualifiedName(index); return n==null?null:n.getMandelName(); } public String getQualifier(int index) { QualifiedMandelName n=getQualifiedName(index); return n==null?null:n.getQualifier(); } public String getLocation(int index) { QualifiedMandelName n=getQualifiedName(index); return n==null?null:n.getLabel(); } public QualifiedMandelName getQualifiedName(int index) { return getList().get(index); } public MandelHandle getMandelHandle(int index) { return getMandelScanner().getMandelHandle(getList().get(index)); } public MandelHandle getMandelData(int index) throws IOException { return getMandelScanner().getMandelData(getList().get(index)); } public int getRowCount() { return getList().size(); } public int getColumnCount() { return columnMapping.length; } public Object getValueAt(int rowIndex, int columnIndex) { MandelHandle h; String q; long t; switch (columnMapping[columnIndex]) { case NAME: return getName(rowIndex); case QUALIFIER: q=getQualifier(rowIndex); if (q==null) return ""; return q; case LOCATION: q=getLocation(rowIndex); if (q==null) return ""; return q; case TYPE: h=getMandelScanner()==null? null:getMandelScanner().getMandelHandle(getList().get(rowIndex)); return h==null?"Not found":h.getHeader().getTypeDesc(); case TIME: h=getMandelScanner()==null? null:getMandelScanner().getMandelHandle(getList().get(rowIndex)); t=h==null?0:h.getFile().getLastModified(); if (t==0) return null; return new DateTime(t); //return date.format(new Date(t)); } return null; } @Override public String getColumnName(int column) { switch (columnMapping[column]) { case NAME: return "Name"; case QUALIFIER: return "Variant"; case TYPE: return "Description"; case LOCATION: return "Location"; case TIME: return "Time Modified"; } return null; } @Override public Class getColumnClass(int column) { switch (columnMapping[column]) { case NAME: return MandelName.class; case QUALIFIER: return String.class; case LOCATION: return String.class; case TYPE: return String.class; case TIME: return DateTime.class; } return null; } /////////////////////////////////////////////////////////////////////////// // Drag & Drop support by model /////////////////////////////////////////////////////////////////////////// public DropMode getDropMode() { return DropMode.INSERT_ROWS; } public int getSourceActions() { return TransferHandler.COPY_OR_MOVE; } public Transferable createTransferable(DragLocation loc) { int[] indices=loc.getSelectedRows(); QualifiedMandelName[] names=new QualifiedMandelName[indices.length]; for (int i=0; i<indices.length; i++) { names[i]=getQualifiedName(indices[i]); } return new MandelTransferable(getList(), names); } public void exportDone(Transferable data, int action) { if (debug) System.out.println("action = "+action+"/"+TransferHandler.MOVE); MandelTransferable trans=(MandelTransferable)data; /*if (trans.getSource()!=getList())*/ { QualifiedMandelName[] names=trans.getNames(); if (action==TransferHandler.MOVE) { if (debug) System.out.println(" remove moved items"); for (int i=names.length-1; i>=0; i--) { remove(names[i]); } } } //else System.out.println("ignore own list"); } public boolean canImport(TransferSupport info) { if (isModifiable()) { Transferable t=info.getTransferable(); if (info.isDataFlavorSupported(MandelTransferable.mandelFlavor)) { try { if (t.isDataFlavorSupported(MandelFolderTransferable.folderFlavor)) { // if folders are dropped, use the content but keep the original folder if (debug) System.out.println("enforce copy"); info.setDropAction(TransferHandler.COPY); } MandelTransferable trans=(MandelTransferable)t.getTransferData( MandelTransferable.mandelFlavor); if (trans.getSource()==getList()) { if (debug) System.out.println("drop to self"); info.setDropAction(TransferHandler.COPY); } return true; } catch (UnsupportedFlavorException ex) { return false; } catch (IOException ex) { Logger.getLogger(AbstractMandelListTableModel.class.getName()). log(Level.SEVERE, null, ex); } } if (info.isDataFlavorSupported(DataFlavor.stringFlavor)) { try { String data=(String)info.getTransferable().getTransferData( DataFlavor.stringFlavor); if (QualifiedMandelName.create(data)!=null) return true; } catch (Exception ex) { } } } return false; } public boolean importData(TransferSupport info) { if (!info.isDrop()) { return false; } DropLocation dl=info.getDropLocation(); boolean insert=dl.isInsertRow()||dl.isInsertColumn(); // Get the string that is being dropped. Transferable t=info.getTransferable(); QualifiedMandelName[] data; MandelTransferable trans; // Perform the actual import. try { trans=(MandelTransferable)t.getTransferData( MandelTransferable.mandelFlavor); if (t.isDataFlavorSupported(MandelFolderTransferable.folderFlavor)) { // if folders are dropped, use the content but keep the original folder if (debug) System.out.println("enforce copy"); info.setDropAction(TransferHandler.COPY); } if (trans.getSource()==getList()) { if (debug) System.out.println("drop to self"); return false; } data=trans.getNames(); for (int i=0; i<data.length; i++) { add(data[i]); } } catch (Exception e) { try { String name=(String)t.getTransferData(DataFlavor.stringFlavor); QualifiedMandelName mn=QualifiedMandelName.create(name); if (mn==null) return false; add(mn); } catch (Exception ex) { return false; } } return true; } /////////////////////////////////////////////////////////////////////////// // additional actions /////////////////////////////////////////////////////////////////////////// protected class ClearAction extends AbstractAction { public ClearAction() { super("Clear"); } public void actionPerformed(ActionEvent e) { clear(); } } }