/* 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); } }