use of org.jabref.model.entry.BibEntry in project jabref by JabRef.
the class AutoSetLinks method autoSetLinks.
/**
* Automatically add links for this set of entries, based on the globally stored list of external file types. The
* entries are modified, and corresponding UndoEdit elements added to the NamedCompound given as argument.
* Furthermore, all entries which are modified are added to the Set of entries given as an argument.
* <p>
* The entries' bibtex keys must have been set - entries lacking key are ignored. The operation is done in a new
* thread, which is returned for the caller to wait for if needed.
*
* @param entries A collection of BibEntry objects to find links for.
* @param ce A NamedCompound to add UndoEdit elements to.
* @param changedEntries MODIFIED, optional. A Set of BibEntry objects to which all modified entries is added.
* This is used for status output and debugging
* @param singleTableModel UGLY HACK. The table model to insert links into. Already existing links are not
* duplicated or removed. This parameter has to be null if entries.count() != 1. The hack has been
* introduced as a bibtexentry does not (yet) support the function getListTableModel() and the
* FileListEntryEditor editor holds an instance of that table model and does not reconstruct it after the
* search has succeeded.
* @param databaseContext The database providing the relevant file directory, if any.
* @param callback An ActionListener that is notified (on the event dispatch thread) when the search is finished.
* The ActionEvent has id=0 if no new links were added, and id=1 if one or more links were added. This
* parameter can be null, which means that no callback will be notified.
* @param diag An instantiated modal JDialog which will be used to display the progress of the automatically setting. This
* parameter can be null, which means that no progress update will be shown.
* @return the thread performing the automatically setting
*/
public static Runnable autoSetLinks(final List<BibEntry> entries, final NamedCompound ce, final Set<BibEntry> changedEntries, final FileListTableModel singleTableModel, final BibDatabaseContext databaseContext, final ActionListener callback, final JDialog diag) {
final Collection<ExternalFileType> types = ExternalFileTypes.getInstance().getExternalFileTypeSelection();
if (diag != null) {
final JProgressBar prog = new JProgressBar(SwingConstants.HORIZONTAL, 0, types.size() - 1);
final JLabel label = new JLabel(Localization.lang("Searching for files"));
prog.setIndeterminate(true);
prog.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
diag.setTitle(Localization.lang("Automatically setting file links"));
diag.getContentPane().add(prog, BorderLayout.CENTER);
diag.getContentPane().add(label, BorderLayout.SOUTH);
diag.pack();
diag.setLocationRelativeTo(diag.getParent());
}
Runnable r = new Runnable() {
@Override
public void run() {
// determine directories to search in
final List<Path> dirs = databaseContext.getFileDirectoriesAsPaths(Globals.prefs.getFileDirectoryPreferences());
// determine extensions
final List<String> extensions = types.stream().map(ExternalFileType::getExtension).collect(Collectors.toList());
// Run the search operation:
FileFinder fileFinder = FileFinders.constructFromConfiguration(Globals.prefs.getAutoLinkPreferences());
Map<BibEntry, List<Path>> result = fileFinder.findAssociatedFiles(entries, dirs, extensions);
boolean foundAny = false;
// Iterate over the entries:
for (Entry<BibEntry, List<Path>> entryFilePair : result.entrySet()) {
FileListTableModel tableModel;
Optional<String> oldVal = entryFilePair.getKey().getField(FieldName.FILE);
if (singleTableModel == null) {
tableModel = new FileListTableModel();
oldVal.ifPresent(tableModel::setContent);
} else {
assert entries.size() == 1;
tableModel = singleTableModel;
}
List<Path> files = entryFilePair.getValue();
for (Path f : files) {
f = FileUtil.shortenFileName(f, dirs);
boolean alreadyHas = false;
//System.out.println("File: "+f.getPath());
for (int j = 0; j < tableModel.getRowCount(); j++) {
FileListEntry existingEntry = tableModel.getEntry(j);
//System.out.println("Comp: "+existingEntry.getLink());
if (Paths.get(existingEntry.getLink()).equals(f)) {
alreadyHas = true;
foundAny = true;
break;
}
}
if (!alreadyHas) {
foundAny = true;
Optional<ExternalFileType> type;
Optional<String> extension = FileHelper.getFileExtension(f);
if (extension.isPresent()) {
type = ExternalFileTypes.getInstance().getExternalFileTypeByExt(extension.get());
} else {
type = Optional.of(new UnknownExternalFileType(""));
}
FileListEntry flEntry = new FileListEntry(f.getFileName().toString(), f.toString(), type);
tableModel.addEntry(tableModel.getRowCount(), flEntry);
String newVal = tableModel.getStringRepresentation();
if (newVal.isEmpty()) {
newVal = null;
}
if (ce != null) {
// store undo information
UndoableFieldChange change = new UndoableFieldChange(entryFilePair.getKey(), FieldName.FILE, oldVal.orElse(null), newVal);
ce.addEdit(change);
}
// hack: if table model is given, do NOT modify entry
if (singleTableModel == null) {
entryFilePair.getKey().setField(FieldName.FILE, newVal);
}
if (changedEntries != null) {
changedEntries.add(entryFilePair.getKey());
}
}
}
}
// handle callbacks and dialog
// FIXME: The ID signals if action was successful :/
final int id = foundAny ? 1 : 0;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
if (diag != null) {
diag.dispose();
}
if (callback != null) {
callback.actionPerformed(new ActionEvent(this, id, ""));
}
}
});
}
};
SwingUtilities.invokeLater(() -> {
// show dialog which will be hidden when the task is done
if (diag != null) {
diag.setVisible(true);
}
});
return r;
}
use of org.jabref.model.entry.BibEntry in project jabref by JabRef.
the class SynchronizeFileField method run.
@Override
public void run() {
if (!goOn) {
panel.output(Localization.lang("This operation requires one or more entries to be selected."));
return;
}
entriesChangedCount = 0;
panel.frame().setProgressBarValue(0);
panel.frame().setProgressBarVisible(true);
// autoSet takes 10 (?) times longer than checkExisting
int weightAutoSet = 10;
int progressBarMax = (autoSet ? weightAutoSet * sel.size() : 0) + (checkExisting ? sel.size() : 0);
panel.frame().setProgressBarMaximum(progressBarMax);
int progress = 0;
final NamedCompound ce = new NamedCompound(Localization.lang("Automatically set file links"));
Set<BibEntry> changedEntries = new HashSet<>();
// First we try to autoset fields
if (autoSet) {
List<BibEntry> entries = new ArrayList<>(sel);
// Start the automatically setting process:
Runnable r = AutoSetLinks.autoSetLinks(entries, ce, changedEntries, null, panel.getBibDatabaseContext(), null, null);
JabRefExecutorService.INSTANCE.executeAndWait(r);
}
progress += sel.size() * weightAutoSet;
panel.frame().setProgressBarValue(progress);
// The following loop checks all external links that are already set.
if (checkExisting) {
boolean removeAllBroken = false;
mainLoop: for (BibEntry aSel : sel) {
panel.frame().setProgressBarValue(progress++);
final Optional<String> old = aSel.getField(FieldName.FILE);
// Check if a extension is set:
if (old.isPresent() && !(old.get().isEmpty())) {
FileListTableModel tableModel = new FileListTableModel();
tableModel.setContentDontGuessTypes(old.get());
for (int j = 0; j < tableModel.getRowCount(); j++) {
FileListEntry flEntry = tableModel.getEntry(j);
LinkedFile field = flEntry.toParsedFileField();
// See if the link looks like an URL:
if (field.isOnlineLink()) {
// Don't check the remote file.
continue;
// TODO: should there be an option to check remote links?
}
// A variable to keep track of whether this link gets deleted:
boolean deleted = false;
// Get an absolute path representation:
Optional<Path> file = field.findIn(panel.getBibDatabaseContext(), Globals.prefs.getFileDirectoryPreferences());
if ((!file.isPresent()) || !Files.exists(file.get())) {
int answer;
if (removeAllBroken) {
// We should delete this link.
answer = 2;
} else {
answer = JOptionPane.showOptionDialog(panel.frame(), Localization.lang("<HTML>Could not find file '%0'<BR>linked from entry '%1'</HTML>", flEntry.getLink(), aSel.getCiteKeyOptional().orElse(Localization.lang("undefined"))), Localization.lang("Broken link"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, brokenLinkOptions, brokenLinkOptions[0]);
}
switch(answer) {
case 1:
// Assign new file.
FileListEntryEditor flEditor = new FileListEntryEditor(panel.frame(), flEntry, false, true, panel.getBibDatabaseContext());
flEditor.setVisible(true, true);
break;
case 2:
// Clear field:
tableModel.removeEntry(j);
// Make sure we don't investigate this link further.
deleted = true;
// Step back in the iteration, because we removed an entry.
j--;
break;
case 3:
// Clear field:
tableModel.removeEntry(j);
// Make sure we don't investigate this link further.
deleted = true;
// Step back in the iteration, because we removed an entry.
j--;
// Notify for further cases.
removeAllBroken = true;
break;
default:
// Cancel
break mainLoop;
}
}
// Unless we deleted this link, see if its file type is recognized:
if (!deleted && flEntry.getType().isPresent() && (flEntry.getType().get() instanceof UnknownExternalFileType)) {
String[] options = new String[] { Localization.lang("Define '%0'", flEntry.getType().get().getName()), Localization.lang("Change file type"), Localization.lang("Cancel") };
String defOption = options[0];
int answer = JOptionPane.showOptionDialog(panel.frame(), Localization.lang("One or more file links are of the type '%0', which is undefined. What do you want to do?", flEntry.getType().get().getName()), Localization.lang("Undefined file type"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, defOption);
if (answer == JOptionPane.CANCEL_OPTION) {
// User doesn't want to handle this unknown link type.
} else if (answer == JOptionPane.YES_OPTION) {
// User wants to define the new file type. Show the dialog:
ExternalFileType newType = new ExternalFileType(flEntry.getType().get().getName(), "", "", "", "new", IconTheme.JabRefIcon.FILE.getSmallIcon());
ExternalFileTypeEntryEditor editor = new ExternalFileTypeEntryEditor(panel.frame(), newType);
editor.setVisible(true);
if (editor.okPressed()) {
// Get the old list of types, add this one, and update the list in prefs:
List<ExternalFileType> fileTypes = new ArrayList<>(ExternalFileTypes.getInstance().getExternalFileTypeSelection());
fileTypes.add(newType);
Collections.sort(fileTypes);
ExternalFileTypes.getInstance().setExternalFileTypes(fileTypes);
panel.getMainTable().repaint();
}
} else {
// User wants to change the type of this link.
// First get a model of all file links for this entry:
FileListEntryEditor editor = new FileListEntryEditor(panel.frame(), flEntry, false, true, panel.getBibDatabaseContext());
editor.setVisible(true, false);
}
}
}
if (!tableModel.getStringRepresentation().equals(old.orElse(null))) {
// The table has been modified. Store the change:
String toSet = tableModel.getStringRepresentation();
if (toSet.isEmpty()) {
ce.addEdit(new UndoableFieldChange(aSel, FieldName.FILE, old.orElse(null), null));
aSel.clearField(FieldName.FILE);
} else {
ce.addEdit(new UndoableFieldChange(aSel, FieldName.FILE, old.orElse(null), toSet));
aSel.setField(FieldName.FILE, toSet);
}
changedEntries.add(aSel);
}
}
}
}
if (!changedEntries.isEmpty()) {
// Add the undo edit:
ce.end();
panel.getUndoManager().addEdit(ce);
panel.markBaseChanged();
entriesChangedCount = changedEntries.size();
}
}
use of org.jabref.model.entry.BibEntry in project jabref by JabRef.
the class DroppedFileHandler method showLinkMoveCopyRenameDialog.
//
// @return true if user pushed "OK", false otherwise
//
private boolean showLinkMoveCopyRenameDialog(String linkFileName, ExternalFileType fileType, BibEntry entry, BibDatabase database) {
String dialogTitle = Localization.lang("Link to file %0", linkFileName);
Optional<Path> dir = panel.getBibDatabaseContext().getFirstExistingFileDir(Globals.prefs.getFileDirectoryPreferences());
if (!dir.isPresent()) {
destDirLabel.setText(Localization.lang("File directory is not set or does not exist!"));
copyRadioButton.setEnabled(false);
moveRadioButton.setEnabled(false);
renameToTextBox.setEnabled(false);
renameCheckBox.setEnabled(false);
linkInPlace.setSelected(true);
} else {
destDirLabel.setText(Localization.lang("File directory is '%0':", dir.get().toString()));
copyRadioButton.setEnabled(true);
moveRadioButton.setEnabled(true);
renameToTextBox.setEnabled(true);
renameCheckBox.setEnabled(true);
}
ChangeListener cl = arg0 -> {
renameCheckBox.setEnabled(!linkInPlace.isSelected());
renameToTextBox.setEnabled(!linkInPlace.isSelected());
};
linkInPlace.setText(Localization.lang("Leave file in its current directory"));
copyRadioButton.setText(Localization.lang("Copy file to file directory"));
moveRadioButton.setText(Localization.lang("Move file to file directory"));
renameCheckBox.setText(Localization.lang("Rename file to").concat(": "));
LayoutFormatterPreferences layoutPrefs = Globals.prefs.getLayoutFormatterPreferences(Globals.journalAbbreviationLoader);
// Determine which name to suggest:
String targetName = FileUtil.createFileNameFromPattern(database, entry, Globals.prefs.get(JabRefPreferences.IMPORT_FILENAMEPATTERN), layoutPrefs);
String fileDirPattern = Globals.prefs.get(JabRefPreferences.IMPORT_FILEDIRPATTERN);
String targetDirName = "";
if (!fileDirPattern.isEmpty()) {
targetDirName = FileUtil.createFileNameFromPattern(database, entry, fileDirPattern, layoutPrefs);
}
if (targetDirName.isEmpty()) {
renameToTextBox.setText(targetName.concat(".").concat(fileType.getExtension()));
} else {
renameToTextBox.setText(targetDirName.concat("/").concat(targetName.concat(".").concat(fileType.getExtension())));
}
linkInPlace.setSelected(frame.prefs().getBoolean(JabRefPreferences.DROPPEDFILEHANDLER_LEAVE));
copyRadioButton.setSelected(frame.prefs().getBoolean(JabRefPreferences.DROPPEDFILEHANDLER_COPY));
moveRadioButton.setSelected(frame.prefs().getBoolean(JabRefPreferences.DROPPEDFILEHANDLER_MOVE));
renameCheckBox.setSelected(frame.prefs().getBoolean(JabRefPreferences.DROPPEDFILEHANDLER_RENAME));
linkInPlace.addChangeListener(cl);
cl.stateChanged(new ChangeEvent(linkInPlace));
try {
Object[] messages = { Localization.lang("How would you like to link to '%0'?", linkFileName), optionsPanel };
int reply = JOptionPane.showConfirmDialog(frame, messages, dialogTitle, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
if (reply == JOptionPane.OK_OPTION) {
// store user's choice
frame.prefs().putBoolean(JabRefPreferences.DROPPEDFILEHANDLER_LEAVE, linkInPlace.isSelected());
frame.prefs().putBoolean(JabRefPreferences.DROPPEDFILEHANDLER_COPY, copyRadioButton.isSelected());
frame.prefs().putBoolean(JabRefPreferences.DROPPEDFILEHANDLER_MOVE, moveRadioButton.isSelected());
frame.prefs().putBoolean(JabRefPreferences.DROPPEDFILEHANDLER_RENAME, renameCheckBox.isSelected());
return true;
} else {
return false;
}
} finally {
linkInPlace.removeChangeListener(cl);
}
}
use of org.jabref.model.entry.BibEntry in project jabref by JabRef.
the class WriteXMPEntryEditorAction method actionPerformed.
@Override
public void actionPerformed(ActionEvent actionEvent) {
setEnabled(false);
panel.output(Localization.lang("Writing XMP-metadata..."));
panel.frame().setProgressBarIndeterminate(true);
panel.frame().setProgressBarVisible(true);
BibEntry entry = editor.getEntry();
// Make a list of all PDFs linked from this entry:
List<Path> files = entry.getFiles().stream().filter(file -> file.getFileType().equalsIgnoreCase("pdf")).map(file -> file.findIn(panel.getBibDatabaseContext(), Globals.prefs.getFileDirectoryPreferences())).filter(Optional::isPresent).map(Optional::get).collect(Collectors.toList());
// 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);
}
use of org.jabref.model.entry.BibEntry in project jabref by JabRef.
the class DroppedFileHandler method handleDroppedfile.
/**
* Offer copy/move/linking options for a dragged external file. Perform the
* chosen operation, if any.
*
* @param fileName The name of the dragged file.
* @param fileType The FileType associated with the file.
* @param mainTable The MainTable the file was dragged to.
* @param dropRow The row where the file was dropped.
*/
public void handleDroppedfile(String fileName, ExternalFileType fileType, MainTable mainTable, int dropRow) {
BibEntry entry = mainTable.getEntryAt(dropRow);
handleDroppedfile(fileName, fileType, entry);
}
Aggregations