735529c670c5facb6131d2a8dea49e473b4f4549
[debian/jabref.git] / src / java / net / sf / jabref / external / ExternalFilePanel.java
1 package net.sf.jabref.external;
2
3 import net.sf.jabref.*;
4 import net.sf.jabref.net.URLDownload;
5
6 import javax.swing.*;
7 import java.awt.event.ActionEvent;
8 import java.awt.event.ActionListener;
9 import java.awt.*;
10 import java.awt.dnd.DropTarget;
11 import java.awt.dnd.DnDConstants;
12 import java.io.File;
13 import java.io.IOException;
14 import java.net.URL;
15 import java.net.MalformedURLException;
16 import java.util.Vector;
17
18 /**
19  * Created by IntelliJ IDEA.
20  * User: alver
21  * Date: May 7, 2005
22  * Time: 7:17:42 PM
23  * To change this template use File | Settings | File Templates.
24  */
25 public class ExternalFilePanel extends JPanel {
26
27     private JButton browseBut, download, auto;
28     private EntryEditor entryEditor;
29     private JabRefFrame frame;
30     private OpenFileFilter off;
31     private BibtexEntry entry = null;
32     private MetaData metaData;
33
34     public ExternalFilePanel(final String fieldName, final MetaData metaData,
35                              final BibtexEntry entry, final OpenFileFilter off) {
36         this(null, metaData, null, fieldName, off, null);
37         this.entry = entry;
38     }
39
40     public ExternalFilePanel(final JabRefFrame frame, final MetaData metaData,
41                              final EntryEditor entryEditor,
42                              final String fieldName, final OpenFileFilter off, final FieldEditor editor) {
43
44         this.frame = frame;
45         this.metaData = metaData;
46         this.off = off;
47         this.entryEditor = entryEditor;
48
49         setLayout(new GridLayout(2, 1));
50
51         browseBut = new JButton(Globals.lang("Browse"));
52         download = new JButton(Globals.lang("Download"));
53         auto = new JButton(Globals.lang("Auto"));
54         //((JComponent) editor).addMouseListener(new EntryEditor.ExternalViewerListener());
55
56         browseBut.addActionListener(new ActionListener() {
57             public void actionPerformed(ActionEvent e) {
58                 browseFile(fieldName, editor);
59                 //editor.setText(chosenValue);
60                 entryEditor.storeFieldAction.actionPerformed(new ActionEvent(editor, 0, ""));
61             }
62         });
63         download.addActionListener(new ActionListener() {
64             public void actionPerformed(ActionEvent e) {
65                 downLoadFile(fieldName, editor, frame);
66             }
67         });
68
69         auto.addActionListener(new ActionListener() {
70             public void actionPerformed(ActionEvent e) {
71                 autoSetFile(fieldName, editor);
72             }
73         });
74
75         JPanel pan = new JPanel();
76         pan.setLayout(new GridLayout(1,2));
77         add(browseBut);
78         pan.add(auto);
79         pan.add(download);
80         add(pan);
81
82         // Add drag and drop support to the field
83         if (editor != null)
84             ((JComponent) editor).setDropTarget(new DropTarget((Component) editor,
85                     DnDConstants.ACTION_NONE, new UrlDragDrop(entryEditor, frame, editor)));
86     }
87
88     /**
89      * Change which entry this panel is operating on. This is used only when this panel
90      * is not attached to an entry editor.
91      */
92     public void setEntry(BibtexEntry entry) {
93         this.entry = entry;
94     }
95
96     protected Object getKey() {
97         return (entry != null ? entry.getField(BibtexFields.KEY_FIELD) :
98             entryEditor.getEntry().getField(BibtexFields.KEY_FIELD));
99     }
100
101     protected void output(String s) {
102         if (frame != null)
103             frame.output(s);
104     }
105
106     public void browseFile(final String fieldName, final FieldEditor editor) {
107
108         String directory = metaData.getFileDirectory(fieldName);
109         if ((directory != null) && directory.equals(""))
110             directory = null;
111
112         String dir = editor.getText(), retVal = null;
113
114         if ((directory == null) || !(new File(dir)).isAbsolute()) {
115             if (directory != null)
116                 dir = directory;
117             else
118                 dir = Globals.prefs.get(fieldName + Globals.FILETYPE_PREFS_EXT, "");
119         }
120
121         String chosenFile =
122                 Globals.getNewFile(frame, Globals.prefs, new File(dir), "."+fieldName,
123                         JFileChooser.OPEN_DIALOG, false);
124
125         if (chosenFile != null) {
126             File newFile = new File(chosenFile);
127             String position = newFile.getParent();
128
129             if ((directory != null) && position.startsWith(directory)) {
130                 // Construct path relative to pdf base dir
131                 String relPath =
132                         position.substring(directory.length(), position.length()) + File.separator
133                         + newFile.getName();
134
135                 // Remove leading path separator
136                 if (relPath.startsWith(File.separator)) {
137                     relPath = relPath.substring(File.separator.length(), relPath.length());
138
139                     // Set relative path as field value
140                 }
141
142                 retVal = relPath;
143             } else
144                 retVal = newFile.getPath();
145
146             editor.setText(retVal);
147             Globals.prefs.put(fieldName + Globals.FILETYPE_PREFS_EXT, newFile.getPath());
148         }
149
150     }
151
152
153     public void downLoadFile(final String fieldName, final FieldEditor editor, final Component parent) {
154         String res =
155                 JOptionPane.showInputDialog(parent,
156                         Globals.lang("Enter URL to download"));
157
158         if (res != null) {
159             class Downloader extends Thread {
160                 String res;
161
162                 public Downloader(String res) {
163                     this.res = res;
164                 }
165
166                 public void run() {
167                     URL url;
168                     String textToSet = editor.getText();
169                     editor.setEnabled(false);
170                     try {
171                         editor.setText(Globals.lang("Downloading..."));
172                         url = new URL(res);
173
174                         String suffix = off.getSuffix(res);
175                         if (suffix == null)
176                         suffix = "."+fieldName.toLowerCase();
177
178                         String plannedName = null;
179                         if (getKey() != null)
180                             plannedName = getKey() + suffix;
181                         else {
182                             plannedName = JOptionPane.showInputDialog(parent,
183                                     Globals.lang("BibTeX key not set. Enter a name for the downloaded file"));
184                             if (plannedName == null)
185                                 return;
186
187                             if (!off.accept(plannedName))
188                                 plannedName += suffix;
189                         }
190
191                         // Find the default directory for this field type:
192                         String directory = metaData.getFileDirectory(fieldName);
193                         System.out.println(directory);
194                         File file = new File(new File(directory), plannedName);
195
196                         URLDownload udl = new URLDownload(parent, url, file);
197                         output(Globals.lang("Downloading..."));
198
199                         try {
200                             udl.download();
201                         } catch (IOException e2) {
202                             JOptionPane.showMessageDialog(parent, Globals.lang("Invalid URL: "+e2.getMessage()),
203                                     Globals.lang("Download file"), JOptionPane.ERROR_MESSAGE);
204                             Globals.logger("Error while downloading " + url.toString());
205                         }
206
207                         output(Globals.lang("Download completed"));
208                         String filename = file.getPath();
209
210                         if (filename.startsWith(directory)) {
211                             // Construct path relative to pdf base dir
212                             String relPath = filename.substring(directory.length(), filename.length());
213
214                             // Remove leading path separator
215                             if (relPath.startsWith(File.separator)) {
216                                 relPath = relPath.substring(File.separator.length(), relPath.length());
217                             }
218                             filename = relPath;
219                         }
220                         textToSet = filename;
221                        //editor.setText(filename);
222                         SwingUtilities.invokeLater(new Thread() {
223                             public void run() {
224                                 if (entryEditor != null)
225                                     entryEditor.updateField(editor);
226                             }
227                         });
228                     } catch (MalformedURLException e1) {
229                         JOptionPane.showMessageDialog(parent, "Invalid URL: "+e1.getMessage(),
230                                 "Download file", JOptionPane.ERROR_MESSAGE);
231                     } finally {
232                         editor.setText(textToSet);
233                         editor.setEnabled(true);
234                     }
235                 }
236             }
237
238
239             (new Downloader(res)).start();
240         }
241     }
242
243     /**
244      * Starts a thread that searches the external file directory for the given field name,
245      * including subdirectories, and looks for files named after the current entry's bibtex
246      * key. Returns a reference to the thread for callers that may want to wait for the thread
247      * to finish (using join()).
248      *
249      * @param fieldName The field to set.
250      * @param editor An EntryEditor instance where to set the value found.
251      * @return A reference to the Thread that performs the operation.
252      */
253     public Thread autoSetFile(final String fieldName, final FieldEditor editor) {
254         Object o = getKey();
255         if ((o == null) || (Globals.prefs.get(fieldName+"Directory") == null)) {
256             output(Globals.lang("You must set both BibTeX key and %0 directory", fieldName.toUpperCase()) + ".");
257             return null;
258         }
259         output(Globals.lang("Searching for %0 file", fieldName.toUpperCase()) + " '" + o +
260                 "."+fieldName+"'...");
261         Thread t = (new Thread() {
262             public void run() {
263                 Object o = getKey();
264
265                 // Find the default directory for this field type:
266                 String dir = metaData.getFileDirectory(fieldName);
267
268                 String found = Util.findPdf((String) o, fieldName, dir, off);
269                 if (found != null) {
270                     editor.setText(found);
271                     if (entryEditor != null)
272                         entryEditor.updateField(editor);
273                     output(Globals.lang("%0 field set", fieldName.toUpperCase()) + ".");
274                 } else {
275                     output(Globals.lang("No %0 found", fieldName.toUpperCase()) + ".");
276                 }
277
278             }
279         });
280
281         t.start();
282         return t;
283
284     }
285
286 }