48b7ee6b55204601e8e1225cdd889c63ae1a8bff
[debian/jabref.git] / src / java / net / sf / jabref / gui / FileListEntryEditor.java
1 package net.sf.jabref.gui;
2
3 import com.jgoodies.forms.builder.DefaultFormBuilder;
4 import com.jgoodies.forms.builder.ButtonBarBuilder;
5 import com.jgoodies.forms.layout.FormLayout;
6
7 import javax.swing.*;
8 import javax.swing.event.DocumentListener;
9 import javax.swing.event.DocumentEvent;
10
11 import net.sf.jabref.*;
12 import net.sf.jabref.external.ExternalFileType;
13 import net.sf.jabref.external.ConfirmCloseFileListEntryEditor;
14
15 import java.awt.*;
16 import java.awt.event.*;
17 import java.io.File;
18 import java.io.FileFilter;
19 import java.util.ArrayList;
20
21 /**
22  * This class produces a dialog box for editing a single file link from a Bibtex entry.
23  *
24  * The information to be edited includes the file description, the link itself and the
25  * file type. The dialog also includes convenience buttons for quick linking.
26  *
27  * For use when downloading files, this class also offers a progress bar and a "Downloading..."
28  * label that can be hidden when the download is complete.
29  */
30 public class FileListEntryEditor {
31
32     JDialog diag;
33     JTextField link = new JTextField(), description = new JTextField();
34     JButton ok = new JButton(Globals.lang("Ok")),
35             cancel = new JButton(Globals.lang("Cancel"));
36     JComboBox types;
37     JProgressBar prog = new JProgressBar(JProgressBar.HORIZONTAL);
38     JLabel downloadLabel = new JLabel(Globals.lang("Downloading..."));
39     ConfirmCloseFileListEntryEditor externalConfirm = null;
40
41     private FileListEntry entry;
42     private MetaData metaData;
43     private boolean okPressed = false;
44
45     public FileListEntryEditor(JFrame parent, FileListEntry entry, boolean showProgressBar,
46                                MetaData metaData) {
47         this.entry = entry;
48         this.metaData = metaData;
49
50         types = new JComboBox(Globals.prefs.getExternalFileTypeSelection());
51         types.addItemListener(new ItemListener() {
52             public void itemStateChanged(ItemEvent itemEvent) {
53                 ok.setEnabled(types.getSelectedItem() != null);
54             }
55         });
56         DefaultFormBuilder builder = new DefaultFormBuilder(new FormLayout
57                 ("left:pref, 4dlu, fill:150dlu, 4dlu, fill:pref", ""));
58         builder.append(Globals.lang("Link"));
59         builder.append(link);
60         BrowseListener browse = new BrowseListener(parent, link);
61         JButton browseBut = new JButton(Globals.lang("Browse"));
62         browseBut.addActionListener(browse);
63         builder.append(browseBut);
64         builder.nextLine();
65         builder.append(Globals.lang("Description"));
66         builder.append(description);
67         builder.getPanel().setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
68         builder.nextLine();
69         builder.append(Globals.lang("File type"));
70         builder.append(types);
71         if (showProgressBar) {
72             builder.nextLine();
73             builder.append(downloadLabel);
74             builder.append(prog);
75         }
76         
77         ButtonBarBuilder bb = new ButtonBarBuilder();
78         bb.addGlue();
79         bb.addGridded(ok);
80         bb.addGridded(cancel);
81         bb.addGlue();
82
83         ok.addActionListener(new ActionListener() {
84             public void actionPerformed(ActionEvent e) {
85                 // If necessary, ask the external confirm object whether we are ready to close.
86                 if (externalConfirm != null) {
87                     // Construct an updated FileListEntry:
88                     FileListEntry testEntry = new FileListEntry("", "", null);
89                     storeSettings(testEntry);
90                     if (!externalConfirm.confirmClose(testEntry))
91                         return;
92                 }
93                 diag.dispose();
94                 storeSettings(FileListEntryEditor.this.entry);
95                 okPressed = true;
96             }
97         });
98         cancel.addActionListener(new ActionListener() {
99             public void actionPerformed(ActionEvent e) {
100                 diag.dispose();
101             }
102         });
103         link.getDocument().addDocumentListener(new DocumentListener() {
104             public void insertUpdate(DocumentEvent documentEvent) {
105                 checkExtension();
106             }
107             public void removeUpdate(DocumentEvent documentEvent) {
108             }
109             public void changedUpdate(DocumentEvent documentEvent) {
110                 checkExtension();
111             }
112             private void checkExtension() {
113                 if ((types.getSelectedIndex() == -1) &&
114                         (link.getText().trim().length() > 0)) {
115                     // Try to guess the file type:
116                     String theLink = link.getText().trim();
117                     int index = theLink.lastIndexOf('.');
118                     if ((index >= 0) && (index < theLink.length()-1)) {
119
120                         ExternalFileType type = Globals.prefs.getExternalFileTypeByExt
121                                 (theLink.substring(index+1));
122                         if (type != null)
123                             types.setSelectedItem(type);
124                     }
125                 }
126             }
127         });
128
129
130         diag = new JDialog(parent, Globals.lang("Edit file link"), true);
131         diag.getContentPane().add(builder.getPanel(), BorderLayout.CENTER);
132         diag.getContentPane().add(bb.getPanel(), BorderLayout.SOUTH);
133         diag.pack();
134         Util.placeDialog(diag, parent);
135
136         setValues(entry);
137     }
138
139     public void setExternalConfirm(ConfirmCloseFileListEntryEditor eC) {
140         this.externalConfirm = eC;
141     }
142
143     public void setOkEnabled(boolean enabled) {
144         ok.setEnabled(enabled);
145     }
146
147     public JProgressBar getProgressBar() {
148         return prog;
149     }
150
151     public JLabel getProgressBarLabel() {
152         return downloadLabel;
153     }
154
155     public void setEntry(FileListEntry entry) {
156         this.entry = entry;
157         setValues(entry);
158     }
159
160     public void setVisible(boolean visible) {
161         if (visible)
162             okPressed = false;
163         diag.setVisible(visible);
164     }
165
166     public void setValues(FileListEntry entry) {
167         description.setText(entry.getDescription());
168         link.setText(entry.getLink());
169         types.setSelectedItem(entry.getType());
170     }
171
172     public void storeSettings(FileListEntry entry) {
173         entry.setDescription(description.getText().trim());
174         entry.setLink(link.getText().trim());
175         entry.setType((ExternalFileType)types.getSelectedItem());
176     }
177
178     public boolean okPressed() {
179         return okPressed;
180     }
181
182     class BrowseListener implements ActionListener {
183         private JFrame parent;
184         private JTextField comp;
185
186         public BrowseListener(JFrame parent, JTextField comp) {
187             this.parent = parent;
188             this.comp = comp;
189         }
190
191         public void actionPerformed(ActionEvent e) {
192             File initial = new File(comp.getText().trim());
193             if (comp.getText().trim().length() == 0) {
194                 // Nothing in the field. Go to the last file dir used:
195                 initial = new File(Globals.prefs.get("fileWorkingDirectory"));
196             }
197             String chosen = Globals.getNewFile(parent, initial, Globals.NONE,
198                 JFileChooser.OPEN_DIALOG, false);
199             if (chosen != null) {
200                 File newFile = new File(chosen);
201                 // Store the directory for next time:
202                 Globals.prefs.put("fileWorkingDirectory", newFile.getParent());
203
204                 // If the file is below the file directory, make the path relative:
205                 ArrayList<File> dirs = new ArrayList<File>();
206                 String fileDir = metaData.getFileDirectory(GUIGlobals.FILE_FIELD);
207                 if (fileDir != null)
208                     dirs.add(new File(fileDir));
209                 if (dirs.size() > 0) {
210                     newFile = FileListEditor.relativizePath(newFile, dirs);
211                 }
212
213                 comp.setText(newFile.getPath());
214                 comp.requestFocus();
215             }
216         }
217     }
218 }