1 package net.sf.jabref.external;
3 import net.sf.jabref.imports.ParserResult;
4 import net.sf.jabref.imports.PostOpenAction;
5 import net.sf.jabref.*;
6 import net.sf.jabref.undo.NamedCompound;
9 import java.awt.event.ActionListener;
10 import java.awt.event.ActionEvent;
11 import java.util.regex.Pattern;
12 import java.util.Iterator;
13 import java.util.List;
15 import com.jgoodies.forms.builder.DefaultFormBuilder;
16 import com.jgoodies.forms.layout.FormLayout;
19 * This class defines the warning that can be offered when opening a pre-2.3
20 * JabRef file into a later version. This warning mentions the new external file
21 * link system in this version of JabRef, and offers to:
23 * * upgrade old-style PDF/PS links into the "file" field
24 * * modify General fields to show "file" instead of "pdf" / "ps"
25 * * modify table column settings to show "file" instead of "pdf" / "ps"
27 public class FileLinksUpgradeWarning implements PostOpenAction {
29 private static final String[] FIELDS_TO_LOOK_FOR = new String[] {"pdf", "ps"};
32 * This method should be performed if the major/minor versions recorded in the ParserResult
33 * are less than or equal to 2.2.
35 * @return true if the file was written by a jabref version <=2.2
37 public boolean isActionNecessary(ParserResult pr) {
38 // First check if this warning is disabled:
39 if (!Globals.prefs.getBoolean("showFileLinksUpgradeWarning"))
41 if (pr.getJabrefMajorVersion() < 0)
42 return false; // non-JabRef file
43 if (pr.getJabrefMajorVersion() < 2)
45 if (pr.getJabrefMajorVersion() > 2)
46 return false; // wow, did we ever reach version 3?
47 return (pr.getJabrefMinorVersion() <= 2);
51 * This method presents a dialog box explaining and offering to make the
52 * changes. If the user confirms, the changes are performed.
56 public void performAction(BasePanel panel, ParserResult pr) {
57 // Find out which actions should be offered:
58 // Only offer to change Preferences if file column is not already visible:
59 boolean offerChangeSettings = !Globals.prefs.getBoolean("fileColumn") || !showsFileInGenFields();
60 // Only offer to upgrade links if the pdf/ps fields are used:
61 boolean offerChangeDatabase = linksFound(pr.getDatabase(), FIELDS_TO_LOOK_FOR);
62 // If the "file" directory is not set, offer to migrate pdf/ps dir:
63 boolean offerSetFileDir = !Globals.prefs.hasKey(GUIGlobals.FILE_FIELD+"Directory")
64 && (Globals.prefs.hasKey("pdfDirectory") || Globals.prefs.hasKey("psDirectory"));
66 if (!offerChangeDatabase && !offerChangeSettings && !offerSetFileDir)
67 return; // Nothing to do, just return.
69 JCheckBox changeSettings = new JCheckBox(Globals.lang("Change table column and General fields settings to use the new feature"),
71 JCheckBox changeDatabase = new JCheckBox(Globals.lang("Upgrade old external file links to use the new feature"),
73 JCheckBox setFileDir = new JCheckBox(Globals.lang("Set main external file directory")+":", offerSetFileDir);
74 JTextField fileDir = new JTextField(30);
75 JCheckBox doNotShowDialog = new JCheckBox(Globals.lang("Do not show these options in the future"),
78 StringBuilder sb = new StringBuilder("<html>");
79 sb.append(Globals.lang("This database was written using an older version of JabRef."));
81 sb.append(Globals.lang("The current version features a new way of handling links to external files.<br>"
82 +"To take advantage of this, your links must be changed into the new format, and<br>"
83 +"JabRef must be configured to show the new links."));
85 sb.append(Globals.lang("Do you want JabRef to do the following operations?"));
88 JPanel message = new JPanel();
89 DefaultFormBuilder b = new DefaultFormBuilder(message,
90 new FormLayout("left:pref", ""));
91 b.append(new JLabel(sb.toString()));
93 if (offerChangeSettings) {
94 b.append(changeSettings);
97 if (offerChangeDatabase) {
98 b.append(changeDatabase);
101 if (offerSetFileDir) {
102 if (Globals.prefs.hasKey("pdfDirectory"))
103 fileDir.setText(Globals.prefs.get("pdfDirectory"));
105 fileDir.setText(Globals.prefs.get("psDirectory"));
106 JPanel pan = new JPanel();
109 JButton browse = new JButton(Globals.lang("Browse"));
110 browse.addActionListener(new BrowseAction(null, fileDir, true));
117 b.append(doNotShowDialog);
119 int answer = JOptionPane.showConfirmDialog(panel.frame(),
120 message, Globals.lang("Upgrade file"), JOptionPane.YES_NO_OPTION);
121 if (doNotShowDialog.isSelected())
122 Globals.prefs.putBoolean("showFileLinksUpgradeWarning", false);
124 if (answer == JOptionPane.YES_OPTION)
125 makeChanges(panel, pr, changeSettings.isSelected(), changeDatabase.isSelected(),
126 setFileDir.isSelected() ? fileDir.getText() : null);
130 * Check the database to find out whether any of a set of fields are used
131 * for any of the entries.
132 * @param database The bib database.
133 * @param fields The set of fields to look for.
134 * @return true if at least one of the given fields is set in at least one entry,
137 public boolean linksFound(BibtexDatabase database, String[] fields) {
138 for (Iterator iterator = database.getEntries().iterator(); iterator.hasNext();) {
139 BibtexEntry entry = (BibtexEntry)iterator.next();
140 for (int i = 0; i < fields.length; i++) {
141 if (entry.getField(fields[i]) != null)
149 * This method performs the actual changes.
152 * @param fileDir The path to the file directory to set, or null if it should not be set.
154 public void makeChanges(BasePanel panel, ParserResult pr, boolean upgradePrefs,
155 boolean upgradeDatabase, String fileDir) {
157 if (upgradeDatabase) {
158 // Update file links links in the database:
159 NamedCompound ce = Util.upgradePdfPsToFile(pr.getDatabase(), FIELDS_TO_LOOK_FOR);
160 panel.undoManager.addEdit(ce);
161 panel.markBaseChanged();
164 if (fileDir != null) {
165 Globals.prefs.put(GUIGlobals.FILE_FIELD+"Directory", fileDir);
169 // Exchange table columns:
170 Globals.prefs.putBoolean("pdfColumn", Boolean.FALSE);
171 Globals.prefs.putBoolean("fileColumn", Boolean.TRUE);
173 // Modify General fields if necessary:
174 // If we don't find the file field, insert it at the bottom of the first tab:
175 if (!showsFileInGenFields()) {
176 String gfs = Globals.prefs.get(Globals.prefs.CUSTOM_TAB_FIELDS+"0");
177 //System.out.println(gfs);
178 StringBuffer sb = new StringBuffer(gfs);
179 if (gfs.length() > 0)
181 sb.append(GUIGlobals.FILE_FIELD);
182 Globals.prefs.put(Globals.prefs.CUSTOM_TAB_FIELDS+"0", sb.toString());
183 Globals.prefs.updateEntryEditorTabList();
184 panel.frame().removeCachedEntryEditors();
186 panel.frame().setupAllTables();
190 private boolean showsFileInGenFields() {
191 boolean found = false;
192 EntryEditorTabList tabList = Globals.prefs.getEntryEditorTabList();
193 outer: for (int i=0; i<tabList.getTabCount(); i++) {
194 List fields = tabList.getTabFields(i);
195 for (Iterator j=fields.iterator(); j.hasNext();) {
196 String field = (String)j.next();
197 if (field.equals(GUIGlobals.FILE_FIELD)) {