da26695c7008e77404b74bcae058fa805330a0d0
[debian/jabref.git] / src / main / java / net / sf / jabref / external / FileLinksUpgradeWarning.java
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.
6
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.
11
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.
15 */
16 package net.sf.jabref.external;
17
18 import java.util.List;
19
20 import javax.swing.*;
21
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;
26
27 import com.jgoodies.forms.builder.DefaultFormBuilder;
28 import com.jgoodies.forms.layout.FormLayout;
29
30 /**
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:
34  *
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"
38  */
39 public class FileLinksUpgradeWarning implements PostOpenAction {
40
41     private static final String[] FIELDS_TO_LOOK_FOR = new String[] {"pdf", "ps"};
42
43     /**
44      * This method should be performed if the major/minor versions recorded in the ParserResult
45      * are less than or equal to 2.2.
46      * @param pr
47      * @return true if the file was written by a jabref version <=2.2
48      */
49     public boolean isActionNecessary(ParserResult pr) {
50         // First check if this warning is disabled:
51         if (!Globals.prefs.getBoolean("showFileLinksUpgradeWarning"))
52             return false;
53         if (pr.getJabrefMajorVersion() < 0)
54             return false; // non-JabRef file
55         if (pr.getJabrefMajorVersion() < 2)
56             return true; // old
57         if (pr.getJabrefMajorVersion() > 2)
58             return false; // wow, did we ever reach version 3?
59         return (pr.getJabrefMinorVersion() <= 2);
60     }
61
62     /**
63      * This method presents a dialog box explaining and offering to make the
64      * changes. If the user confirms, the changes are performed.
65      * @param panel
66      * @param pr
67      */
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"));
77
78         if (!offerChangeDatabase && !offerChangeSettings && !offerSetFileDir)
79                     return; // Nothing to do, just return.
80                 
81         JCheckBox changeSettings = new JCheckBox(Globals.lang("Change table column and General fields settings to use the new feature"),
82                 offerChangeSettings);
83         JCheckBox changeDatabase = new JCheckBox(Globals.lang("Upgrade old external file links to use the new feature"),
84                 offerChangeDatabase);
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"),
88                 false);
89
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>"));
95         b.nextLine();
96         if (offerChangeSettings) {
97             b.append(changeSettings);
98             b.nextLine();
99         }
100         if (offerChangeDatabase) {
101             b.append(changeDatabase);
102             b.nextLine();
103         }
104         if (offerSetFileDir) {
105             if (Globals.prefs.hasKey("pdfDirectory"))
106                 fileDir.setText(Globals.prefs.get("pdfDirectory"));
107             else
108                 fileDir.setText(Globals.prefs.get("psDirectory"));
109             JPanel pan = new JPanel();
110             pan.add(setFileDir);
111             pan.add(fileDir);
112             JButton browse = new JButton(Globals.lang("Browse"));
113             browse.addActionListener(new BrowseAction(null, fileDir, true));
114             pan.add(browse);
115             b.append(pan);
116             b.nextLine();
117         }
118         b.append("");
119         b.nextLine();
120         b.append(doNotShowDialog);
121
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);
126
127         if (answer == JOptionPane.YES_OPTION)
128             makeChanges(panel, pr, changeSettings.isSelected(), changeDatabase.isSelected(),
129                     setFileDir.isSelected() ? fileDir.getText() : null);
130     }
131
132     /**
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,
138      *  false otherwise.
139      */
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)
144                     return true;
145             }
146         }
147         return false;
148     }
149
150     /**
151      * This method performs the actual changes.
152      * @param panel
153      * @param pr
154      * @param fileDir The path to the file directory to set, or null if it should not be set.
155      */
156     public void makeChanges(BasePanel panel, ParserResult pr, boolean upgradePrefs,
157                             boolean upgradeDatabase, String fileDir) {
158
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();
164         }
165
166         if (fileDir != null) {
167             Globals.prefs.put(GUIGlobals.FILE_FIELD+"Directory", fileDir);
168         }
169
170         if (upgradePrefs) {
171             // Exchange table columns:
172             Globals.prefs.putBoolean("pdfColumn", Boolean.FALSE);
173             Globals.prefs.putBoolean("fileColumn", Boolean.TRUE);
174
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)
182                     sb.append(";");
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();
187             }
188             panel.frame().setupAllTables();
189         }
190     }
191
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)) {
199                     found = true;
200                     break outer;
201                 }
202             }
203         }
204         return found;
205     }
206
207 }