1 package net.sf.jabref.external;
3 import java.awt.BorderLayout;
5 import java.awt.Dimension;
6 import java.awt.event.ActionEvent;
7 import java.awt.event.ActionListener;
10 import javax.swing.AbstractAction;
11 import javax.swing.ActionMap;
12 import javax.swing.BorderFactory;
13 import javax.swing.InputMap;
14 import javax.swing.JButton;
15 import javax.swing.JComponent;
16 import javax.swing.JDialog;
17 import javax.swing.JFrame;
18 import javax.swing.JOptionPane;
19 import javax.swing.JPanel;
20 import javax.swing.JScrollPane;
21 import javax.swing.JTextArea;
23 import net.sf.jabref.AbstractWorker;
24 import net.sf.jabref.BasePanel;
25 import net.sf.jabref.BibtexDatabase;
26 import net.sf.jabref.BibtexEntry;
27 import net.sf.jabref.FocusRequester;
28 import net.sf.jabref.Globals;
29 import net.sf.jabref.Util;
30 import net.sf.jabref.util.XMPUtil;
32 import com.jgoodies.forms.builder.ButtonBarBuilder;
36 * This action goes through all selected entries in the BasePanel, and attempts
37 * to write the XMP data to the external pdf.
39 * @author $Author: coezbek $
40 * @version $Revision: 2110 $ ($Date: 2007-06-13 03:39:51 +0200 (Wed, 13 Jun 2007) $)
43 public class WriteXMPAction extends AbstractWorker {
47 BibtexEntry[] entries;
49 BibtexDatabase database;
51 OptionsDialog optDiag;
55 int skipped, entriesChanged, errors;
57 public WriteXMPAction(BasePanel panel) {
63 // Get entries and check if it makes sense to perform this operation
64 entries = panel.getSelectedEntries();
66 if (entries.length == 0) {
68 database = panel.getDatabase();
69 entries = database.getEntries().toArray(new BibtexEntry[]{});
71 if (entries.length == 0) {
73 JOptionPane.showMessageDialog(panel, Globals
74 .lang("This operation requires at least one entry."), Globals
75 .lang("Write XMP-metadata"), JOptionPane.ERROR_MESSAGE);
81 int response = JOptionPane.showConfirmDialog(panel, Globals
82 .lang("Write XMP-metadata for all PDFs in current database?"), Globals
83 .lang("Write XMP-metadata"), JOptionPane.YES_NO_CANCEL_OPTION,
84 JOptionPane.QUESTION_MESSAGE);
86 if (response != JOptionPane.YES_OPTION) {
93 errors = entriesChanged = skipped = 0;
95 if (optDiag == null) {
96 optDiag = new OptionsDialog(panel.frame());
100 panel.output(Globals.lang("Writing XMP metadata..."));
108 for (int i = 0; i < entries.length; i++) {
110 BibtexEntry entry = entries[i];
112 String pdf = (String) entry.getField("pdf");
114 String dir = panel.metaData().getFileDirectory("pdf");
116 File file = Util.expandFilename(pdf, new String[]{dir,"."});
118 optDiag.progressArea.append(entry.getCiteKey() + "\n");
122 optDiag.progressArea.append(" " + Globals.lang("Skipped - No PDF linked") + ".\n");
123 } else if (!file.exists()) {
125 optDiag.progressArea.append(" " + Globals.lang("Skipped - PDF does not exist")
127 optDiag.progressArea.append(" " + file.getPath() + "\n");
130 XMPUtil.writeXMP(file, entry, database);
131 optDiag.progressArea.append(" " + Globals.lang("Ok") + ".\n");
133 } catch (Exception e) {
134 optDiag.progressArea.append(" " + Globals.lang("Error while writing") + " '"
135 + file.getPath() + "':\n");
136 optDiag.progressArea.append(" " + e.getLocalizedMessage() + "\n");
140 if (optDiag.canceled){
141 optDiag.progressArea.append("\n"
142 + Globals.lang("Operation canceled.\n"));
146 optDiag.progressArea.append("\n"
147 + Globals.lang("Finished writing XMP for %0 file (%1 skipped, %2 errors).", String
148 .valueOf(entriesChanged), String.valueOf(skipped), String.valueOf(errors)));
152 public void update() {
156 panel.output(Globals.lang("Finished writing XMP for %0 file (%1 skipped, %2 errors).",
157 String.valueOf(entriesChanged), String.valueOf(skipped), String.valueOf(errors)));
160 class OptionsDialog extends JDialog {
162 private static final long serialVersionUID = 7459164400811785958L;
164 JButton okButton = new JButton(Globals.lang("Ok")), cancelButton = new JButton(Globals
169 JTextArea progressArea;
171 public OptionsDialog(JFrame parent) {
172 super(parent, Globals.lang("Writing XMP metadata for selected entries..."), false);
173 okButton.setEnabled(false);
175 okButton.addActionListener(new ActionListener() {
176 public void actionPerformed(ActionEvent e) {
181 AbstractAction cancel = new AbstractAction() {
182 private static final long serialVersionUID = -338601477652815366L;
184 public void actionPerformed(ActionEvent e) {
188 cancelButton.addActionListener(cancel);
190 InputMap im = cancelButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
191 ActionMap am = cancelButton.getActionMap();
192 im.put(Globals.prefs.getKey("Close dialog"), "close");
193 am.put("close", cancel);
195 progressArea = new JTextArea(15, 60);
197 JScrollPane scrollPane = new JScrollPane(progressArea,
198 JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
199 Dimension d = progressArea.getPreferredSize();
200 d.height += scrollPane.getHorizontalScrollBar().getHeight() + 15;
201 d.width += scrollPane.getVerticalScrollBar().getWidth() + 15;
205 progressArea.setBackground(Color.WHITE);
206 progressArea.setEditable(false);
207 progressArea.setBorder(BorderFactory.createEmptyBorder(3, 3, 3,
209 progressArea.setText("");
211 JPanel panel = new JPanel();
212 panel.setBorder(BorderFactory.createEmptyBorder(3, 2, 3, 2));
213 panel.add(scrollPane);
217 // progressArea.setPreferredSize(new Dimension(300, 300));
219 ButtonBarBuilder bb = new ButtonBarBuilder();
221 bb.addGridded(okButton);
223 bb.addGridded(cancelButton);
225 JPanel bbPanel = bb.getPanel();
226 bbPanel.setBorder(BorderFactory.createEmptyBorder(0, 3, 3, 3));
227 getContentPane().add(panel, BorderLayout.CENTER);
228 getContentPane().add(bbPanel, BorderLayout.SOUTH);
231 this.setResizable(false);
236 okButton.setEnabled(true);
237 cancelButton.setEnabled(false);
241 progressArea.setText("");
243 Util.placeDialog(optDiag, panel.frame());
245 okButton.setEnabled(false);
246 cancelButton.setEnabled(true);
248 new FocusRequester(okButton);
250 optDiag.setVisible(true);