/*
Copyright (C) 2005 Andreas Rudert
All programs in this directory and
subdirectories are published under the GNU General Public License as
described below.
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 2 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
Further information about the GNU GPL is available at:
http://www.gnu.org/copyleft/gpl.ja.html
*/
package net.sf.jabref.imports;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumnModel;
import net.sf.jabref.FocusRequester;
import net.sf.jabref.Globals;
import net.sf.jabref.JabRefPreferences;
import net.sf.jabref.Util;
/**
* Dialog to allow users to choose a file contained in a ZIP file.
*
* @author andreas_sf at rudert-home dot de
*/
class ZipFileChooser extends JDialog {
/**
* Table model for the ZIP archive contents.
*
* <p>Contains one row for each entry.
* Does not contain rows for directory entries.</p>
*
* <p>The columns contain information about ZIIP file entries:
* <ol><li>
* name {@link String}
* </li><li>
* time of last modification {@link Date}
* </li><li>
* size (uncompressed) {@link Long}
* </li></ol></p>
*/
class ZipFileChooserTableModel extends AbstractTableModel {
private String[] columnNames = new String[] {
Globals.lang("Name"),
Globals.lang("Last modified"),
Globals.lang("Size")
};
private ZipEntry[] rows = null;
private ZipFile zipFile = null;
ZipFileChooserTableModel(ZipFile zipFile, ZipEntry[] rows) {
super();
this.rows = rows;
this.zipFile = zipFile;
}
/*
* (non-Javadoc)
* @see javax.swing.table.TableModel#getColumnCount()
*/
public int getColumnCount() {
return columnNames.length;
}
/*
* (non-Javadoc)
* @see javax.swing.table.TableModel#getRowCount()
*/
public int getRowCount() {
return this.rows.length;
}
/*
* (non-Javadoc)
* @see javax.swing.table.TableModel#getColumnName(int)
*/
public String getColumnName(int col) {
return columnNames[col];
}
/**
* Zip-File entry at the given row index.
*
* @param rowIndex row index
* @return Zip file entry
*/
public ZipEntry getZipEntry(int rowIndex) {
return this.rows[rowIndex];
}
/**
* Zip file which contains all entries of this model.
*
* @return zip file
*/
public ZipFile getZipFile() {
return this.zipFile;
}
/*
* (non-Javadoc)
* @see javax.swing.table.TableModel#getValueAt(int, int)
*/
public Object getValueAt(int rowIndex, int columnIndex) {
Object value = null;
ZipEntry entry = getZipEntry(rowIndex);
if (columnIndex == 0) {
value = entry.getName();
} else if (columnIndex == 1) {
value = SimpleDateFormat.getDateTimeInstance().format(new Date(entry.getTime()));
} else if (columnIndex == 2) {
value = new Long(entry.getSize());
}
return value;
}
}
private JButton okButton = new JButton(Globals.lang("Ok"));
private JButton cancelButton = new JButton(Globals.lang("Cancel"));
/** table of Zip entries */
private JTable table;
/** shortcut to preferences */
private JabRefPreferences prefs = Globals.prefs;
/** this */
private ZipFileChooser zipFileChooser;
/** import customization dialog, owner of this dialog */
private ImportCustomizationDialog importCustomizationDialog;
/*
* (non-Javadoc)
* @see java.awt.Component#getSize()
*/
public Dimension getSize() {
return new Dimension(400, 300);
}
/**
* Entries that can be selected with this dialog.
*
* @param zipFile Zip-File
* @return entries that can be selected
*/
private ZipEntry[] getSelectableZipEntries(ZipFile zipFile) {
List<ZipEntry> entries = new ArrayList<ZipEntry>();
Enumeration<? extends ZipEntry> e = zipFile.entries();
while (e.hasMoreElements()) {
ZipEntry entry = e.nextElement();
if (!entry.isDirectory() && entry.getName().endsWith(".class")) {
entries.add(entry);
}
}
return entries.toArray(new ZipEntry[]{});
}
/**
* New Zip file chooser.
*
* @param owner Owner of the file chooser
* @param zipFile Zip-Fle to choose from, must be readable
* @throws HeadlessException
*/
public ZipFileChooser(ImportCustomizationDialog owner, ZipFile zipFile) throws HeadlessException {
super(owner, Globals.lang("Select file from ZIP-archive"), false);
this.importCustomizationDialog = owner;
this.zipFileChooser = this;
// cancel: no entry is selected
cancelButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
}
});
// ok: get selected class and check if it is instantiable as an importer
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int row = table.getSelectedRow();
if (row != -1) {
ZipFileChooserTableModel model = (ZipFileChooserTableModel)table.getModel();
ZipEntry tempZipEntry = model.getZipEntry(row);
CustomImportList.Importer importer = prefs.customImports.new Importer();
importer.setBasePath(model.getZipFile().getName());
String className = tempZipEntry.getName().substring(0, tempZipEntry.getName().lastIndexOf('.'));
importer.setClassName(className);
try {
ImportFormat importFormat = importer.getInstance();
importer.setName(importFormat.getFormatName());
importer.setCliId(importFormat.getCLIId());
importCustomizationDialog.addOrReplaceImporter(importer);
dispose();
} catch (Exception exc) {
exc.printStackTrace();
JOptionPane.showMessageDialog(zipFileChooser, Globals.lang("Could not instantiate %0 %1", importer.getName() + ":\n", exc.getMessage()));
}
} else {
JOptionPane.showMessageDialog(zipFileChooser, Globals.lang("Please select an importer."));
}
}
});
ZipFileChooserTableModel tableModel = new ZipFileChooserTableModel( zipFile, getSelectableZipEntries(zipFile) );
table = new JTable(tableModel);
TableColumnModel cm = table.getColumnModel();
cm.getColumn(0).setPreferredWidth(200);
cm.getColumn(1).setPreferredWidth(150);
cm.getColumn(2).setPreferredWidth(100);
JScrollPane sp = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.setPreferredScrollableViewportSize(new Dimension(500, 150));
if (table.getRowCount() > 0) {
table.setRowSelectionInterval(0, 0);
}
// Key bindings:
JPanel mainPanel = new JPanel();
//ActionMap am = mainPanel.getActionMap();
//InputMap im = mainPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
//im.put(prefs.getKey("Close dialog"), "close");
//am.put("close", closeAction);
mainPanel.setLayout(new BorderLayout());
mainPanel.add(sp, BorderLayout.CENTER);
JPanel optionsPanel = new JPanel();
optionsPanel.add(okButton);
optionsPanel.add(cancelButton);
optionsPanel.add(Box.createHorizontalStrut(5));
getContentPane().add(mainPanel, BorderLayout.CENTER);
getContentPane().add(optionsPanel, BorderLayout.SOUTH);
this.setSize(getSize());
pack();
Util.placeDialog(this, owner);
new FocusRequester(table);
}
}