07ba4d09bc1f6926802e5086bf0c028ce7874e3f
[debian/jabref.git] / src / java / net / sf / jabref / external / WriteXMPAction.java
1 package net.sf.jabref.external;
2
3 import java.awt.BorderLayout;
4 import java.awt.Color;
5 import java.awt.Dimension;
6 import java.awt.event.ActionEvent;
7 import java.awt.event.ActionListener;
8 import java.io.File;
9
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;
22
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;
31
32 import com.jgoodies.forms.builder.ButtonBarBuilder;
33
34 /**
35  * 
36  * This action goes through all selected entries in the BasePanel, and attempts
37  * to write the XMP data to the external pdf.
38  * 
39  * @author $Author: coezbek $
40  * @version $Revision: 2110 $ ($Date: 2007-06-13 03:39:51 +0200 (Wed, 13 Jun 2007) $)
41  * 
42  */
43 public class WriteXMPAction extends AbstractWorker {
44
45         BasePanel panel;
46
47         BibtexEntry[] entries;
48         
49         BibtexDatabase database;
50
51         OptionsDialog optDiag;
52
53         boolean goOn = true;
54
55         int skipped, entriesChanged, errors;
56
57         public WriteXMPAction(BasePanel panel) {
58                 this.panel = panel;
59         }
60
61         public void init() {
62
63                 // Get entries and check if it makes sense to perform this operation
64                 entries = panel.getSelectedEntries();
65
66                 if (entries.length == 0) {
67
68                         database = panel.getDatabase();
69                         entries = database.getEntries().toArray(new BibtexEntry[]{});
70
71                         if (entries.length == 0) {
72
73                                 JOptionPane.showMessageDialog(panel, Globals
74                                         .lang("This operation requires at least one entry."), Globals
75                                         .lang("Write XMP-metadata"), JOptionPane.ERROR_MESSAGE);
76                                 goOn = false;
77                                 return;
78
79                         } else {
80
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);
85
86                                 if (response != JOptionPane.YES_OPTION) {
87                                         goOn = false;
88                                         return;
89                                 }
90                         }
91                 }
92
93                 errors = entriesChanged = skipped = 0;
94
95                 if (optDiag == null) {
96                         optDiag = new OptionsDialog(panel.frame());
97                 }
98                 optDiag.open();
99
100                 panel.output(Globals.lang("Writing XMP metadata..."));
101         }
102
103         public void run() {
104
105                 if (!goOn)
106                         return;
107
108                 for (int i = 0; i < entries.length; i++) {
109
110                         BibtexEntry entry = entries[i];
111
112                         String pdf = (String) entry.getField("pdf");
113
114                         String dir = panel.metaData().getFileDirectory("pdf");
115
116                         File file = Util.expandFilename(pdf, new String[]{dir,"."});
117
118                         optDiag.progressArea.append(entry.getCiteKey() + "\n");
119
120                         if (file == null) {
121                                 skipped++;
122                                 optDiag.progressArea.append("  " + Globals.lang("Skipped - No PDF linked") + ".\n");
123                         } else if (!file.exists()) {
124                                 skipped++;
125                                 optDiag.progressArea.append("  " + Globals.lang("Skipped - PDF does not exist")
126                                         + ":\n");
127                                 optDiag.progressArea.append("    " + file.getPath() + "\n");
128                         } else {
129                                 try {
130                                         XMPUtil.writeXMP(file, entry, database);
131                                         optDiag.progressArea.append("  " + Globals.lang("Ok") + ".\n");
132                                         entriesChanged++;
133                                 } catch (Exception e) {
134                                         optDiag.progressArea.append("  " + Globals.lang("Error while writing") + " '"
135                                                 + file.getPath() + "':\n");
136                                         optDiag.progressArea.append("    " + e.getLocalizedMessage() + "\n");
137                                         errors++;
138                                 }
139                         }
140                         if (optDiag.canceled){
141                                 optDiag.progressArea.append("\n"
142                                         + Globals.lang("Operation canceled.\n"));
143                                 break;          
144                         }
145                 }
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)));
149                 optDiag.done();
150         }
151
152         public void update() {
153                 if (!goOn)
154                         return;
155
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)));
158         }
159
160         class OptionsDialog extends JDialog {
161
162                 private static final long serialVersionUID = 7459164400811785958L;
163
164                 JButton okButton = new JButton(Globals.lang("Ok")), cancelButton = new JButton(Globals
165                         .lang("Cancel"));
166
167                 boolean canceled;
168
169                 JTextArea progressArea;
170
171                 public OptionsDialog(JFrame parent) {
172                         super(parent, Globals.lang("Writing XMP metadata for selected entries..."), false);
173                         okButton.setEnabled(false);
174
175                         okButton.addActionListener(new ActionListener() {
176                                 public void actionPerformed(ActionEvent e) {
177                                         dispose();
178                                 }
179                         });
180
181                         AbstractAction cancel = new AbstractAction() {
182                                 private static final long serialVersionUID = -338601477652815366L;
183
184                                 public void actionPerformed(ActionEvent e) {
185                                         canceled = true;
186                                 }
187                         };
188                         cancelButton.addActionListener(cancel);
189
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);
194
195                         progressArea = new JTextArea(15, 60);
196
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;
202                         
203                         panel.setSize(d);
204
205                         progressArea.setBackground(Color.WHITE);
206                         progressArea.setEditable(false);
207                         progressArea.setBorder(BorderFactory.createEmptyBorder(3, 3, 3,
208                                 3));
209                         progressArea.setText("");
210
211                         JPanel panel = new JPanel();
212                         panel.setBorder(BorderFactory.createEmptyBorder(3, 2, 3, 2));
213                         panel.add(scrollPane);
214
215                         
216
217                         // progressArea.setPreferredSize(new Dimension(300, 300));
218
219                         ButtonBarBuilder bb = new ButtonBarBuilder();
220                         bb.addGlue();
221                         bb.addGridded(okButton);
222                         bb.addRelatedGap();
223                         bb.addGridded(cancelButton);
224                         bb.addGlue();
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);
229
230                         pack();
231                         this.setResizable(false);
232
233                 }
234
235                 public void done() {
236                         okButton.setEnabled(true);
237                         cancelButton.setEnabled(false);
238                 }
239
240                 public void open() {
241                         progressArea.setText("");
242                         canceled = false;
243                         Util.placeDialog(optDiag, panel.frame());
244
245                         okButton.setEnabled(false);
246                         cancelButton.setEnabled(true);
247
248                         new FocusRequester(okButton);
249
250                         optDiag.setVisible(true);
251                 }
252         }
253 }