1 /* Copyright (C) 2003-2011 JabRef contributors.
2 This program is free software; you can redistribute it and/or modify
3 it under the terms of the GNU General Public License as published by
4 the Free Software Foundation; either version 2 of the License, or
5 (at your option) any later version.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License along
13 with this program; if not, write to the Free Software Foundation, Inc.,
14 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 package net.sf.jabref.external;
18 import java.util.List;
22 import net.sf.jabref.*;
23 import net.sf.jabref.imports.ParserResult;
24 import net.sf.jabref.imports.PostOpenAction;
25 import net.sf.jabref.undo.NamedCompound;
27 import com.jgoodies.forms.builder.DefaultFormBuilder;
28 import com.jgoodies.forms.layout.FormLayout;
31 * This class defines the warning that can be offered when opening a pre-2.3
32 * JabRef file into a later version. This warning mentions the new external file
33 * link system in this version of JabRef, and offers to:
35 * * upgrade old-style PDF/PS links into the "file" field
36 * * modify General fields to show "file" instead of "pdf" / "ps"
37 * * modify table column settings to show "file" instead of "pdf" / "ps"
39 public class FileLinksUpgradeWarning implements PostOpenAction {
41 private static final String[] FIELDS_TO_LOOK_FOR = new String[] {"pdf", "ps"};
44 * This method should be performed if the major/minor versions recorded in the ParserResult
45 * are less than or equal to 2.2.
47 * @return true if the file was written by a jabref version <=2.2
49 public boolean isActionNecessary(ParserResult pr) {
50 // First check if this warning is disabled:
51 if (!Globals.prefs.getBoolean("showFileLinksUpgradeWarning"))
53 if (pr.getJabrefMajorVersion() < 0)
54 return false; // non-JabRef file
55 if (pr.getJabrefMajorVersion() < 2)
57 if (pr.getJabrefMajorVersion() > 2)
58 return false; // wow, did we ever reach version 3?
59 return (pr.getJabrefMinorVersion() <= 2);
63 * This method presents a dialog box explaining and offering to make the
64 * changes. If the user confirms, the changes are performed.
68 public void performAction(BasePanel panel, ParserResult pr) {
69 // Find out which actions should be offered:
70 // Only offer to change Preferences if file column is not already visible:
71 boolean offerChangeSettings = !Globals.prefs.getBoolean("fileColumn") || !showsFileInGenFields();
72 // Only offer to upgrade links if the pdf/ps fields are used:
73 boolean offerChangeDatabase = linksFound(pr.getDatabase(), FIELDS_TO_LOOK_FOR);
74 // If the "file" directory is not set, offer to migrate pdf/ps dir:
75 boolean offerSetFileDir = !Globals.prefs.hasKey(GUIGlobals.FILE_FIELD+"Directory")
76 && (Globals.prefs.hasKey("pdfDirectory") || Globals.prefs.hasKey("psDirectory"));
78 if (!offerChangeDatabase && !offerChangeSettings && !offerSetFileDir)
79 return; // Nothing to do, just return.
81 JCheckBox changeSettings = new JCheckBox(Globals.lang("Change table column and General fields settings to use the new feature"),
83 JCheckBox changeDatabase = new JCheckBox(Globals.lang("Upgrade old external file links to use the new feature"),
85 JCheckBox setFileDir = new JCheckBox(Globals.lang("Set main external file directory")+":", offerSetFileDir);
86 JTextField fileDir = new JTextField(30);
87 JCheckBox doNotShowDialog = new JCheckBox(Globals.lang("Do not show these options in the future"),
90 JPanel message = new JPanel();
91 DefaultFormBuilder b = new DefaultFormBuilder(new FormLayout("left:pref", ""), message);
92 b.append(new JLabel("<html>" + Globals.lang("This database was written using an older version of JabRef.") + "<br>" + Globals.lang("The current version features a new way of handling links to external files.<br>"
93 + "To take advantage of this, your links must be changed into the new format, and<br>"
94 + "JabRef must be configured to show the new links.") + "<p>" + Globals.lang("Do you want JabRef to do the following operations?") + "</html>"));
96 if (offerChangeSettings) {
97 b.append(changeSettings);
100 if (offerChangeDatabase) {
101 b.append(changeDatabase);
104 if (offerSetFileDir) {
105 if (Globals.prefs.hasKey("pdfDirectory"))
106 fileDir.setText(Globals.prefs.get("pdfDirectory"));
108 fileDir.setText(Globals.prefs.get("psDirectory"));
109 JPanel pan = new JPanel();
112 JButton browse = new JButton(Globals.lang("Browse"));
113 browse.addActionListener(new BrowseAction(null, fileDir, true));
120 b.append(doNotShowDialog);
122 int answer = JOptionPane.showConfirmDialog(panel.frame(),
123 message, Globals.lang("Upgrade file"), JOptionPane.YES_NO_OPTION);
124 if (doNotShowDialog.isSelected())
125 Globals.prefs.putBoolean("showFileLinksUpgradeWarning", false);
127 if (answer == JOptionPane.YES_OPTION)
128 makeChanges(panel, pr, changeSettings.isSelected(), changeDatabase.isSelected(),
129 setFileDir.isSelected() ? fileDir.getText() : null);
133 * Check the database to find out whether any of a set of fields are used
134 * for any of the entries.
135 * @param database The bib database.
136 * @param fields The set of fields to look for.
137 * @return true if at least one of the given fields is set in at least one entry,
140 public boolean linksFound(BibtexDatabase database, String[] fields) {
141 for (BibtexEntry entry : database.getEntries()){
142 for (String field : fields) {
143 if (entry.getField(field) != null)
151 * This method performs the actual changes.
154 * @param fileDir The path to the file directory to set, or null if it should not be set.
156 public void makeChanges(BasePanel panel, ParserResult pr, boolean upgradePrefs,
157 boolean upgradeDatabase, String fileDir) {
159 if (upgradeDatabase) {
160 // Update file links links in the database:
161 NamedCompound ce = Util.upgradePdfPsToFile(pr.getDatabase(), FIELDS_TO_LOOK_FOR);
162 panel.undoManager.addEdit(ce);
163 panel.markBaseChanged();
166 if (fileDir != null) {
167 Globals.prefs.put(GUIGlobals.FILE_FIELD+"Directory", fileDir);
171 // Exchange table columns:
172 Globals.prefs.putBoolean("pdfColumn", Boolean.FALSE);
173 Globals.prefs.putBoolean("fileColumn", Boolean.TRUE);
175 // Modify General fields if necessary:
176 // If we don't find the file field, insert it at the bottom of the first tab:
177 if (!showsFileInGenFields()) {
178 String gfs = Globals.prefs.get(JabRefPreferences.CUSTOM_TAB_FIELDS +"0");
179 //System.out.println(gfs);
180 StringBuffer sb = new StringBuffer(gfs);
181 if (gfs.length() > 0)
183 sb.append(GUIGlobals.FILE_FIELD);
184 Globals.prefs.put(JabRefPreferences.CUSTOM_TAB_FIELDS +"0", sb.toString());
185 Globals.prefs.updateEntryEditorTabList();
186 panel.frame().removeCachedEntryEditors();
188 panel.frame().setupAllTables();
192 private boolean showsFileInGenFields() {
193 boolean found = false;
194 EntryEditorTabList tabList = Globals.prefs.getEntryEditorTabList();
195 outer: for (int i=0; i<tabList.getTabCount(); i++) {
196 List<String> fields = tabList.getTabFields(i);
197 for (String field : fields) {
198 if (field.equals(GUIGlobals.FILE_FIELD)) {