908005916ed79bedb62c81ed9bb09cb4eafb8bcd
[debian/jabref.git] / src / java / net / sf / jabref / imports / ImportCustomizationDialog.java
1 /*
2  Copyright (C) 2005 Andreas Rudert, based on ExportCustomizationDialog by ??
3
4  All programs in this directory and
5  subdirectories are published under the GNU General Public License as
6  described below.
7
8  This program is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or (at
11  your option) any later version.
12
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21  USA
22
23  Further information about the GNU GPL is available at:
24  http://www.gnu.org/copyleft/gpl.ja.html
25
26  */
27 package net.sf.jabref.imports;
28
29 import javax.swing.JDialog;
30 import java.awt.*;
31 import net.sf.jabref.*;
32 import javax.swing.*;
33 import java.awt.event.ActionListener;
34 import java.awt.event.ActionEvent;
35 import java.io.File;
36 import java.io.IOException;
37 import java.util.zip.ZipFile;
38
39 import javax.swing.table.AbstractTableModel;
40 import javax.swing.table.TableColumnModel;
41
42 /**
43  * Dialog to manage custom importers.
44  */
45 public class ImportCustomizationDialog extends JDialog {
46
47   private final JabRefFrame frame;
48   private JButton addFromFolderButton = new JButton(Globals.lang("Add from folder"));
49   private JButton addFromJarButton = new JButton(Globals.lang("Add from jar"));
50   private JButton showDescButton = new JButton(Globals.lang("Show description"));
51   private JButton removeButton = new JButton(Globals.lang("Remove"));
52   private JButton closeButton = new JButton(Globals.lang("Close"));
53   private JButton helpButton = new JButton(Globals.lang("Help"));
54
55   private JPanel optionsPanel = new JPanel();
56   private JPanel mainPanel = new JPanel();
57   private JTable customImporterTable;
58   private JabRefPreferences prefs = Globals.prefs;
59   private ImportCustomizationDialog importCustomizationDialog;
60   
61   /*
62    *  (non-Javadoc)
63    * @see java.awt.Component#getSize()
64    */
65   public Dimension getSize() {
66     int width = GUIGlobals.IMPORT_DIALOG_COL_0_WIDTH
67               + GUIGlobals.IMPORT_DIALOG_COL_1_WIDTH
68               + GUIGlobals.IMPORT_DIALOG_COL_2_WIDTH
69               + GUIGlobals.IMPORT_DIALOG_COL_3_WIDTH;
70     return new Dimension(width, width/2);
71   }
72   
73   /**
74    * Converts a path relative to a base-path into a class name.
75    * 
76    * @param basePath  base path
77    * @param path  path that includes base-path as a prefix
78    * @return  class name
79    */
80   private String pathToClass(File basePath, File path) {
81     String className = null;
82     // remove leading basepath from path
83     while (!path.equals(basePath)) {
84       className = path.getName() + (className != null ? "." + className : "");
85       path = path.getParentFile();
86     }
87     className = className.substring(0, className.lastIndexOf('.'));
88     return className;    
89   }
90   
91   /**
92    * Adds an importer to the model that underlies the custom importers.
93    * 
94    * @param importer  importer
95    */
96   void addOrReplaceImporter(CustomImportList.Importer importer) {
97     prefs.customImports.replaceImporter(importer);
98     Globals.importFormatReader.resetImportFormats();
99     ((ImportTableModel)customImporterTable.getModel()).fireTableDataChanged();
100   }
101   
102   /**
103    * 
104    * @param frame_
105    * @throws HeadlessException
106    */
107   public ImportCustomizationDialog(JabRefFrame frame_) throws HeadlessException {
108     super(frame_, Globals.lang("Manage custom imports"), false);
109     this.importCustomizationDialog = this;
110     frame = frame_;
111     
112     addFromFolderButton.addActionListener(new ActionListener() {
113      public void actionPerformed(ActionEvent e) {
114        CustomImportList.Importer importer = prefs.customImports.new Importer();  
115        importer.setBasePath( Globals.getNewDir(frame, prefs, new File(prefs.get("workingDirectory")), "",
116            Globals.lang("Select Classpath of New Importer"), JFileChooser.CUSTOM_DIALOG, false) );
117        String chosenFileStr = Globals.getNewFile(frame, prefs, importer.getBasePath(), ".class",
118            Globals.lang("Select new ImportFormat Subclass"), JFileChooser.CUSTOM_DIALOG, false);
119        if (chosenFileStr != null) {
120          try {
121            importer.setClassName( pathToClass(importer.getBasePath(), new File(chosenFileStr)) );
122            importer.setName( importer.getInstance().getFormatName() );
123            importer.setCliId( importer.getInstance().getCLIId() );
124          } catch (Exception exc) {           
125            exc.printStackTrace();
126            JOptionPane.showMessageDialog(frame, Globals.lang("Could not instantiate %0 %1", chosenFileStr + ":\n", exc.getMessage()));
127          }
128
129          addOrReplaceImporter(importer);
130          customImporterTable.revalidate();
131          customImporterTable.repaint();
132          frame.setUpImportMenus();
133        }
134       }
135     });
136     addFromFolderButton.setToolTipText(Globals.lang("Add a (compiled) custom ImportFormat class from a class path. \nThe path need not be on the classpath of JabRef."));
137
138     addFromJarButton.addActionListener(new ActionListener() {
139      public void actionPerformed(ActionEvent e) {
140        String basePath = Globals.getNewFile(frame, prefs, new File(prefs.get("workingDirectory")), ".zip,.jar",
141            Globals.lang("Select a Zip-archive"), JFileChooser.CUSTOM_DIALOG, false);
142        ZipFile zipFile = null;
143        if (basePath != null) {
144          try {
145            zipFile = new ZipFile(new File(basePath), ZipFile.OPEN_READ);
146          } catch (IOException exc) {
147            exc.printStackTrace();
148            JOptionPane.showMessageDialog(frame, Globals.lang("Could not open %0 %1", basePath + ":\n", exc.getMessage()));
149            return;         
150          }
151        }
152          
153        if (zipFile != null) {
154          ZipFileChooser zipFileChooser = new ZipFileChooser(importCustomizationDialog, zipFile);
155          zipFileChooser.setVisible(true);
156        }
157        customImporterTable.revalidate();
158        customImporterTable.repaint(10);
159        frame.setUpImportMenus();
160       }
161     });
162     addFromJarButton.setToolTipText(Globals.lang("Add a (compiled) custom ImportFormat class from a Zip-archive.\nThe Zip-archive need not be on the classpath of JabRef."));
163     
164     showDescButton.addActionListener(new ActionListener() {
165      public void actionPerformed(ActionEvent e) {
166        int row = customImporterTable.getSelectedRow();
167        if (row != -1) {
168          CustomImportList.Importer importer = ((ImportTableModel)customImporterTable.getModel()).getImporter(row);
169          try {
170            ImportFormat importFormat = importer.getInstance();
171            JOptionPane.showMessageDialog(frame, importFormat.getDescription());
172          } catch (Exception exc) {           
173            exc.printStackTrace();
174            JOptionPane.showMessageDialog(frame, Globals.lang("Could not instantiate %0 %1", importer.getName() + ":\n", exc.getMessage()));
175          }
176        } else {
177          JOptionPane.showMessageDialog(frame, Globals.lang("Please select an importer"));
178        }
179      }
180     });
181     
182     removeButton.addActionListener(new ActionListener() {
183       public void actionPerformed(ActionEvent e) {
184         int row = customImporterTable.getSelectedRow();
185         if (row != -1) {
186           customImporterTable.removeRowSelectionInterval(row,row);
187           prefs.customImports.remove(((ImportTableModel)customImporterTable.getModel()).getImporter(row));
188           Globals.importFormatReader.resetImportFormats();
189           customImporterTable.revalidate();
190           customImporterTable.repaint();
191           frame.setUpImportMenus();
192         }  else {
193           JOptionPane.showMessageDialog(frame, Globals.lang("Please select an importer."));
194         }
195       }
196     });
197
198     AbstractAction closeAction = new AbstractAction() {
199       public void actionPerformed(ActionEvent e) {
200         dispose();
201       }
202     };
203
204     closeButton.addActionListener(closeAction);
205
206     helpButton.addActionListener(new HelpAction(frame.helpDiag, GUIGlobals.importCustomizationHelp,
207                                           "Help"));
208
209     ImportTableModel tableModel = new ImportTableModel();
210     customImporterTable = new JTable(tableModel);
211     TableColumnModel cm = customImporterTable.getColumnModel();
212     cm.getColumn(0).setPreferredWidth(GUIGlobals.IMPORT_DIALOG_COL_0_WIDTH);
213     cm.getColumn(1).setPreferredWidth(GUIGlobals.IMPORT_DIALOG_COL_1_WIDTH);
214     cm.getColumn(2).setPreferredWidth(GUIGlobals.IMPORT_DIALOG_COL_2_WIDTH);
215     cm.getColumn(3).setPreferredWidth(GUIGlobals.IMPORT_DIALOG_COL_3_WIDTH);
216     JScrollPane sp = new JScrollPane(customImporterTable, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
217                                      JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
218     customImporterTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
219     customImporterTable.setPreferredScrollableViewportSize(getSize());
220     if (customImporterTable.getRowCount() > 0) {
221       customImporterTable.setRowSelectionInterval(0, 0);
222     }
223
224     // Key bindings:
225     ActionMap am = mainPanel.getActionMap();
226     InputMap im = mainPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
227     im.put(frame.prefs().getKey("Close dialog"), "close");
228     am.put("close", closeAction);
229     mainPanel.setLayout(new BorderLayout());
230     mainPanel.add(sp, BorderLayout.CENTER);
231     optionsPanel.add(addFromFolderButton);
232     optionsPanel.add(addFromJarButton);
233     optionsPanel.add(showDescButton);
234     optionsPanel.add(removeButton);
235     optionsPanel.add(closeButton);
236     optionsPanel.add(Box.createHorizontalStrut(5));
237     optionsPanel.add(helpButton);
238
239     getContentPane().add(mainPanel, BorderLayout.CENTER);
240     getContentPane().add(optionsPanel, BorderLayout.SOUTH);
241     this.setSize(getSize());
242     pack();
243     Util.placeDialog(this, frame);
244     new FocusRequester(customImporterTable);
245   }
246
247   /**
248    * Table model for the custom importer table.
249    */
250   class ImportTableModel extends AbstractTableModel {
251     private String[] columnNames = new String[] {
252       Globals.lang("Import name"), 
253       Globals.lang("Command line id"),
254       Globals.lang("ImportFormat class"),
255       Globals.lang("Contained in")
256     };
257     
258     public Object getValueAt(int rowIndex, int columnIndex) {
259       Object value = null;
260       CustomImportList.Importer importer = getImporter(rowIndex);
261       if (columnIndex == 0) {
262         value = importer.getName();
263       } else if (columnIndex == 1) {
264         value = importer.getClidId();
265       } else if (columnIndex == 2) {
266         value = importer.getClassName();
267       } else if (columnIndex == 3) {
268         value = importer.getBasePath();
269       }
270       return value;
271     }
272     
273     public int getColumnCount() {
274       return columnNames.length;
275     }
276
277     public int getRowCount() {
278       return Globals.prefs.customImports.size();
279     }
280
281     public String getColumnName(int col) {
282       return columnNames[col];
283     }
284
285     public CustomImportList.Importer getImporter(int rowIndex) {
286       CustomImportList.Importer[] importers = (CustomImportList.Importer[])Globals.prefs.customImports.toArray(new CustomImportList.Importer[] {});
287       return importers[rowIndex];
288     }    
289   }
290
291 }