/* Copyright (C) 2003-2011 JabRef contributors.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package net.sf.jabref.external;
import net.sf.jabref.*;
import net.sf.jabref.util.XMPUtil;
import net.sf.jabref.gui.FileListTableModel;
import net.sf.jabref.gui.FileListEntry;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.io.File;
import java.util.List;
import java.util.ArrayList;
/**
* Write XMP action for EntryEditor toolbar.
*/
public class WriteXMPEntryEditorAction extends AbstractAction {
private BasePanel panel;
private EntryEditor editor;
private String message = null;
public WriteXMPEntryEditorAction(BasePanel panel, EntryEditor editor) {
this.panel = panel;
this.editor = editor;
putValue(NAME, Globals.lang("Write XMP")); // normally, this call should be without "Globals.lang". However, the string "Write XMP" is also used in non-menu places and therefore, the translation must be also available at Globals.lang()
putValue(SMALL_ICON, GUIGlobals.getImage("pdfSmall"));
putValue(SHORT_DESCRIPTION, Globals.lang("Write BibtexEntry as XMP-metadata to PDF."));
}
public void actionPerformed(ActionEvent actionEvent) {
setEnabled(false);
panel.output(Globals.lang("Writing XMP metadata..."));
panel.frame().setProgressBarIndeterminate(true);
panel.frame().setProgressBarVisible(true);
BibtexEntry entry = editor.getEntry();
// Make a list of all PDFs linked from this entry:
List<File> files = new ArrayList<File>();
// First check the (legacy) "pdf" field:
String pdf = entry.getField("pdf");
String[] dirs = panel.metaData().getFileDirectory("pdf");
File f = Util.expandFilename(pdf, dirs);
if (f != null)
files.add(f);
// Then check the "file" field:
dirs = panel.metaData().getFileDirectory(GUIGlobals.FILE_FIELD);
String field = entry.getField(GUIGlobals.FILE_FIELD);
if (field != null) {
FileListTableModel tm = new FileListTableModel();
tm.setContent(field);
for (int j = 0; j < tm.getRowCount(); j++) {
FileListEntry flEntry = tm.getEntry(j);
if ((flEntry.getType() != null) && (flEntry.getType().getName().toLowerCase().equals("pdf"))) {
f = Util.expandFilename(flEntry.getLink(), dirs);
if (f != null)
files.add(f);
}
}
}
// We want to offload the actual work to a background thread, so we have a worker
// thread:
AbstractWorker worker = new WriteXMPWorker(files, entry);
// Using Spin, we get a thread that gets synchronously offloaded to a new thread,
// blocking the execution of this method:
worker.getWorker().run();
// After the worker thread finishes, we are unblocked and ready to print the
// status message:
panel.output(message);
panel.frame().setProgressBarVisible(false);
setEnabled(true);
}
class WriteXMPWorker extends AbstractWorker {
private List<File> files;
private BibtexEntry entry;
public WriteXMPWorker(List<File> files, BibtexEntry entry) {
this.files = files;
this.entry = entry;
}
public void run() {
if (files.size() == 0) {
message = Globals.lang("No PDF linked") + ".\n";
} else {
int written = 0, error = 0;
for (File file : files) {
if (!file.exists()) {
if (files.size() == 1)
message = Globals.lang("PDF does not exist");
error++;
} else {
try {
XMPUtil.writeXMP(file, entry, panel.database());
if (files.size() == 1)
message = Globals.lang("Wrote XMP-metadata");
written++;
} catch (Exception e) {
if (files.size() == 1)
message = Globals.lang("Error while writing") + " '" + file.getPath() + "'";
error++;
}
}
}
if (files.size() > 1) {
StringBuilder sb = new StringBuilder();
sb.append(Globals.lang("Finished writing XMP-metadata. Wrote to %0 file(s).",
String.valueOf(written)));
if (error > 0)
sb.append(" " + Globals.lang("Error writing to %0 file(s).", String.valueOf(error)));
message = sb.toString();
}
}
}
}
}