use of org.jabref.model.entry.LinkedFile in project jabref by JabRef.
the class LinkedFilesEditorViewModel method fromFile.
/**
* Creates an instance of {@link LinkedFile} based on the given file.
* We try to guess the file type and relativize the path against the given file directories.
*
* TODO: Move this method to {@link LinkedFile} as soon as {@link ExternalFileType} lives in model.
*/
private static LinkedFile fromFile(Path file, List<Path> fileDirectories) {
String fileExtension = FileHelper.getFileExtension(file).orElse("");
ExternalFileType suggestedFileType = ExternalFileTypes.getInstance().getExternalFileTypeByExt(fileExtension).orElse(new UnknownExternalFileType(fileExtension));
Path relativePath = FileUtil.shortenFileName(file, fileDirectories);
return new LinkedFile("", relativePath.toString(), suggestedFileType.getName());
}
use of org.jabref.model.entry.LinkedFile in project jabref by JabRef.
the class MoveFileAction method actionPerformed.
@Override
public void actionPerformed(ActionEvent event) {
int selected = editor.getSelectedRow();
if (selected == -1) {
return;
}
FileListEntry entry = editor.getTableModel().getEntry(selected);
LinkedFile field = entry.toParsedFileField();
if (field.isOnlineLink()) {
// TODO: notify that this operation cannot be done on remote links
return;
}
// Get an absolute path representation:
Optional<Path> fileDir = frame.getCurrentBasePanel().getBibDatabaseContext().getFirstExistingFileDir(Globals.prefs.getFileDirectoryPreferences());
if (!fileDir.isPresent()) {
JOptionPane.showMessageDialog(frame, Localization.lang("File directory is not set or does not exist!"), Localization.lang("Move file"), JOptionPane.ERROR_MESSAGE);
return;
}
// Check if the current file exists:
Optional<Path> file = field.findIn(frame.getCurrentBasePanel().getBibDatabaseContext(), Globals.prefs.getFileDirectoryPreferences());
if ((file.isPresent()) && Files.exists(file.get())) {
MoveFilesCleanup moveFiles = new MoveFilesCleanup(frame.getCurrentBasePanel().getBibDatabaseContext(), Globals.prefs.getCleanupPreferences(Globals.journalAbbreviationLoader).getFileDirPattern(), Globals.prefs.getFileDirectoryPreferences(), Globals.prefs.getLayoutFormatterPreferences(Globals.journalAbbreviationLoader), field);
String[] options = { Localization.lang("Move file"), Localization.lang("Cancel") };
int dialogResult = JOptionPane.showOptionDialog(frame, Localization.lang("Move file to file directory?") + " " + fileDir.get(), Localization.lang("Move file"), JOptionPane.INFORMATION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION, null, options, options[0]);
if (dialogResult == JOptionPane.YES_OPTION) {
moveFiles.cleanup((eEditor.getEntry()));
}
} else {
// File doesn't exist, so we can't move it.
JOptionPane.showMessageDialog(frame, Localization.lang("Could not find file '%0'.", entry.getLink()), Localization.lang("File not found"), JOptionPane.ERROR_MESSAGE);
}
}
use of org.jabref.model.entry.LinkedFile in project jabref by JabRef.
the class RenameFileAction method actionPerformed.
@Override
public void actionPerformed(ActionEvent e) {
int selected = editor.getSelectedRow();
if (selected == -1) {
return;
}
FileListEntry entry = editor.getTableModel().getEntry(selected);
LinkedFile field = entry.toParsedFileField();
// Check if the current file exists:
if (field.isOnlineLink()) {
// TODO: notify that this operation cannot be done on remote links
return;
}
Optional<Path> fileDir = frame.getCurrentBasePanel().getBibDatabaseContext().getFirstExistingFileDir(Globals.prefs.getFileDirectoryPreferences());
if (!fileDir.isPresent()) {
JOptionPane.showMessageDialog(frame, Localization.lang("File directory is not set or does not exist!"), Localization.lang("Rename file"), JOptionPane.ERROR_MESSAGE);
return;
}
Optional<Path> file = field.findIn(frame.getCurrentBasePanel().getBibDatabaseContext(), Globals.prefs.getFileDirectoryPreferences());
if ((file.isPresent()) && Files.exists(file.get())) {
RenamePdfCleanup pdfCleanup = new RenamePdfCleanup(false, frame.getCurrentBasePanel().getBibDatabaseContext(), Globals.prefs.getCleanupPreferences(Globals.journalAbbreviationLoader).getFileNamePattern(), Globals.prefs.getLayoutFormatterPreferences(Globals.journalAbbreviationLoader), Globals.prefs.getFileDirectoryPreferences(), field);
String targetFileName = pdfCleanup.getTargetFileName(field, eEditor.getEntry());
String[] options = { Localization.lang("Rename file"), Localization.lang("Cancel") };
int dialogResult = JOptionPane.showOptionDialog(frame, Localization.lang("Rename file to") + " " + targetFileName, Localization.lang("Rename file"), JOptionPane.INFORMATION_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION, null, options, options[0]);
//indicates Rename pressed
if (dialogResult == JOptionPane.YES_OPTION) {
pdfCleanup.cleanup(eEditor.getEntry());
}
}
}
use of org.jabref.model.entry.LinkedFile 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.LinkedFile in project jabref by JabRef.
the class RenamePdfCleanup method cleanup.
@Override
public List<FieldChange> cleanup(BibEntry entry) {
List<LinkedFile> newFileList;
List<LinkedFile> fileList;
if (singleFieldCleanup != null) {
fileList = Arrays.asList(singleFieldCleanup);
newFileList = entry.getFiles().stream().filter(x -> !x.equals(singleFieldCleanup)).collect(Collectors.toList());
} else {
newFileList = new ArrayList<>();
fileList = entry.getFiles();
}
boolean changed = false;
for (LinkedFile flEntry : fileList) {
String realOldFilename = flEntry.getLink();
if (onlyRelativePaths && Paths.get(realOldFilename).isAbsolute()) {
newFileList.add(flEntry);
continue;
}
//old path and old filename
Optional<Path> expandedOldFile = flEntry.findIn(databaseContext, fileDirectoryPreferences);
if ((!expandedOldFile.isPresent()) || (expandedOldFile.get().getParent() == null)) {
// something went wrong. Just skip this entry
newFileList.add(flEntry);
continue;
}
String targetFileName = getTargetFileName(flEntry, entry);
Path newPath = expandedOldFile.get().getParent().resolve(targetFileName);
String expandedOldFilePath = expandedOldFile.get().toString();
boolean pathsDifferOnlyByCase = newPath.toString().equalsIgnoreCase(expandedOldFilePath) && !newPath.toString().equals(expandedOldFilePath);
if (Files.exists(newPath) && !pathsDifferOnlyByCase) {
// we do not overwrite files
// Since File.exists is sometimes not case-sensitive, the check pathsDifferOnlyByCase ensures that we
// nonetheless rename files to a new name which just differs by case.
// TODO: we could check here if the newPath file is linked with the current entry. And if not, we could add a link
LOGGER.debug("There already exists a file with that name " + newPath.getFileName() + " so I won't rename it");
newFileList.add(flEntry);
continue;
}
try {
if (!Files.exists(newPath)) {
Files.createDirectories(newPath);
}
} catch (IOException e) {
LOGGER.error("Could not create necessary target directoires for renaming", e);
}
boolean renameSuccessful = FileUtil.renameFile(Paths.get(expandedOldFilePath), newPath, true);
if (renameSuccessful) {
changed = true;
//Change the path for this entry
String description = flEntry.getDescription();
String type = flEntry.getFileType();
//We use the file directory (if none is set - then bib file) to create relative file links
Optional<Path> settingsDir = databaseContext.getFirstExistingFileDir(fileDirectoryPreferences);
if (settingsDir.isPresent()) {
Path parent = settingsDir.get();
String newFileEntryFileName;
if (parent == null) {
newFileEntryFileName = targetFileName;
} else {
newFileEntryFileName = parent.relativize(newPath).toString();
}
newFileList.add(new LinkedFile(description, newFileEntryFileName, type));
}
} else {
unsuccessfulRenames++;
}
}
if (changed) {
Optional<FieldChange> change = entry.setFiles(newFileList);
//if we put a null undo object here, the change by "doMakePathsRelative" would overwrite the field value nevertheless.
if (change.isPresent()) {
return Collections.singletonList(change.get());
} else {
return Collections.emptyList();
}
}
return Collections.emptyList();
}
Aggregations