1
package net.sf.jabref.gui;
3
import com.jgoodies.forms.builder.DefaultFormBuilder;
4
import com.jgoodies.forms.builder.ButtonBarBuilder;
5
import com.jgoodies.forms.layout.FormLayout;
8
import javax.swing.event.DocumentListener;
9
import javax.swing.event.DocumentEvent;
11
import net.sf.jabref.*;
12
import net.sf.jabref.external.ExternalFileType;
13
import net.sf.jabref.external.ConfirmCloseFileListEntryEditor;
14
import net.sf.jabref.external.ExternalFileMenuItem;
15
import net.sf.jabref.external.UnknownExternalFileType;
18
import java.awt.event.*;
20
import java.io.FileFilter;
21
import java.io.IOException;
22
import java.util.ArrayList;
25
* This class produces a dialog box for editing a single file link from a Bibtex entry.
27
* The information to be edited includes the file description, the link itself and the
28
* file type. The dialog also includes convenience buttons for quick linking.
30
* For use when downloading files, this class also offers a progress bar and a "Downloading..."
31
* label that can be hidden when the download is complete.
33
public class FileListEntryEditor {
36
JTextField link = new JTextField(), description = new JTextField();
37
JButton ok = new JButton(Globals.lang("Ok")),
38
cancel = new JButton(Globals.lang("Cancel")),
39
open = new JButton(Globals.lang("Open"));
41
JProgressBar prog = new JProgressBar(JProgressBar.HORIZONTAL);
42
JLabel downloadLabel = new JLabel(Globals.lang("Downloading..."));
43
ConfirmCloseFileListEntryEditor externalConfirm = null;
45
private AbstractAction okAction;
46
private JabRefFrame frame;
47
private FileListEntry entry;
48
private MetaData metaData;
49
private boolean okPressed = false, okDisabledExternally = false;
51
public FileListEntryEditor(JabRefFrame frame, FileListEntry entry, boolean showProgressBar,
52
boolean showOpenButton, MetaData metaData) {
55
this.metaData = metaData;
57
okAction = new AbstractAction() {
58
public void actionPerformed(ActionEvent e) {
59
// If OK button is disabled, ignore this event:
62
// If necessary, ask the external confirm object whether we are ready to close.
63
if (externalConfirm != null) {
64
// Construct an updated FileListEntry:
65
FileListEntry testEntry = new FileListEntry("", "", null);
66
storeSettings(testEntry);
67
if (!externalConfirm.confirmClose(testEntry))
71
storeSettings(FileListEntryEditor.this.entry);
75
types = new JComboBox();
76
types.addItemListener(new ItemListener() {
77
public void itemStateChanged(ItemEvent itemEvent) {
78
if (!okDisabledExternally)
79
ok.setEnabled(types.getSelectedItem() != null);
83
DefaultFormBuilder builder = new DefaultFormBuilder(new FormLayout
84
("left:pref, 4dlu, fill:150dlu, 4dlu, fill:pref, 4dlu, fill:pref", ""));
85
builder.append(Globals.lang("Link"));
87
BrowseListener browse = new BrowseListener(frame, link);
88
JButton browseBut = new JButton(Globals.lang("Browse"));
89
browseBut.addActionListener(browse);
90
builder.append(browseBut);
94
builder.append(Globals.lang("Description"));
95
builder.append(description, 3);
96
builder.getPanel().setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
98
builder.append(Globals.lang("File type"));
99
builder.append(types, 3);
100
if (showProgressBar) {
102
builder.append(downloadLabel);
103
builder.append(prog, 3);
106
ButtonBarBuilder bb = new ButtonBarBuilder();
108
//bb.addGridded(open);
109
//bb.addRelatedGap();
111
bb.addGridded(cancel);
115
ok.addActionListener(okAction);
116
// Add OK action to the two text fields to simplify entering:
117
link.addActionListener(okAction);
118
description.addActionListener(okAction);
120
open.addActionListener(new ActionListener() {
121
public void actionPerformed(ActionEvent actionEvent) {
126
AbstractAction cancelAction = new AbstractAction() {
127
public void actionPerformed(ActionEvent e) {
131
cancel.addActionListener(cancelAction);
134
ActionMap am = builder.getPanel().getActionMap();
135
InputMap im = builder.getPanel().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
136
im.put(Globals.prefs.getKey("Close dialog"), "close");
137
am.put("close", cancelAction);
139
link.getDocument().addDocumentListener(new DocumentListener() {
140
public void insertUpdate(DocumentEvent documentEvent) {
143
public void removeUpdate(DocumentEvent documentEvent) {
145
public void changedUpdate(DocumentEvent documentEvent) {
152
diag = new JDialog(frame, Globals.lang("Edit file link"), true);
153
diag.getContentPane().add(builder.getPanel(), BorderLayout.CENTER);
154
diag.getContentPane().add(bb.getPanel(), BorderLayout.SOUTH);
156
Util.placeDialog(diag, frame);
161
private void checkExtension() {
162
if ((types.getSelectedIndex() == -1) &&
163
(link.getText().trim().length() > 0)) {
164
// Try to guess the file type:
165
String theLink = link.getText().trim();
166
int index = theLink.lastIndexOf('.');
167
if ((index >= 0) && (index < theLink.length()-1)) {
169
ExternalFileType type = Globals.prefs.getExternalFileTypeByExt
170
(theLink.substring(index+1));
172
types.setSelectedItem(type);
177
public void openFile() {
178
ExternalFileType type = (ExternalFileType)types.getSelectedItem();
181
Util.openExternalFileAnyFormat(metaData, link.getText(), type);
182
} catch (IOException e) {
187
public void setExternalConfirm(ConfirmCloseFileListEntryEditor eC) {
188
this.externalConfirm = eC;
191
public void setOkEnabled(boolean enabled) {
192
okDisabledExternally = !enabled;
193
ok.setEnabled(enabled);
196
public JProgressBar getProgressBar() {
200
public JLabel getProgressBarLabel() {
201
return downloadLabel;
204
public void setEntry(FileListEntry entry) {
209
public void setVisible(boolean visible) {
212
diag.setVisible(visible);
215
public void setValues(FileListEntry entry) {
216
description.setText(entry.getDescription());
217
link.setText(entry.getLink());
218
//if (link.getText().length() > 0)
220
types.setModel(new DefaultComboBoxModel(Globals.prefs.getExternalFileTypeSelection()));
221
types.setSelectedIndex(-1);
222
// See what is a reasonable selection for the type combobox:
223
if ((entry.getType() != null) && !(entry.getType() instanceof UnknownExternalFileType))
224
types.setSelectedItem(entry.getType());
225
// If the entry has a link but not a file type, try to deduce the file type:
226
else if ((entry.getLink() != null) && (entry.getLink().length() > 0)) {
232
public void storeSettings(FileListEntry entry) {
233
entry.setDescription(description.getText().trim());
234
// See if we should trim the file link to be relative to the file directory:
236
String fileDir = metaData.getFileDirectory(GUIGlobals.FILE_FIELD);
237
if ((fileDir == null) ||(fileDir.equals(""))) {
238
entry.setLink(link.getText().trim());
240
String canPath = (new File(fileDir)).getCanonicalPath();
241
File fl = new File(link.getText().trim());
242
String flPath = fl.getCanonicalPath();
243
if ((flPath.length() > canPath.length()) && (flPath.startsWith(canPath))) {
244
String relFileName = fl.getCanonicalPath().substring(canPath.length()+1);
245
entry.setLink(relFileName);
247
entry.setLink(link.getText().trim());
249
} catch (java.io.IOException ex)
251
ex.printStackTrace();
252
// Don't think this should happen, but set the file link directly as a fallback:
253
entry.setLink(link.getText().trim());
256
entry.setType((ExternalFileType)types.getSelectedItem());
259
public boolean okPressed() {
263
class BrowseListener implements ActionListener {
264
private JFrame parent;
265
private JTextField comp;
267
public BrowseListener(JFrame parent, JTextField comp) {
268
this.parent = parent;
272
public void actionPerformed(ActionEvent e) {
273
File initial = new File(comp.getText().trim());
274
if (comp.getText().trim().length() == 0) {
275
// Nothing in the field. Go to the last file dir used:
276
initial = new File(Globals.prefs.get("fileWorkingDirectory"));
278
String chosen = Globals.getNewFile(parent, initial, Globals.NONE,
279
JFileChooser.OPEN_DIALOG, false);
280
if (chosen != null) {
281
File newFile = new File(chosen);
282
// Store the directory for next time:
283
Globals.prefs.put("fileWorkingDirectory", newFile.getParent());
285
// If the file is below the file directory, make the path relative:
286
ArrayList<File> dirs = new ArrayList<File>();
287
String fileDir = metaData.getFileDirectory(GUIGlobals.FILE_FIELD);
289
dirs.add(new File(fileDir));
290
if (dirs.size() > 0) {
291
newFile = FileListEditor.relativizePath(newFile, dirs);
294
comp.setText(newFile.getPath());