package org.jabref.gui.specialfields; import java.util.List; import java.util.Objects; import org.jabref.Globals; import org.jabref.gui.JabRefFrame; import org.jabref.gui.actions.BaseAction; import org.jabref.gui.undo.NamedCompound; import org.jabref.gui.undo.UndoableFieldChange; import org.jabref.logic.l10n.Localization; import org.jabref.logic.specialfields.SpecialFieldsUtils; import org.jabref.model.FieldChange; import org.jabref.model.entry.BibEntry; import org.jabref.model.entry.specialfields.SpecialField; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class SpecialFieldAction implements BaseAction { private static final Log LOGGER = LogFactory.getLog(SpecialFieldAction.class); private final JabRefFrame frame; private final SpecialField specialField; private final String value; private final boolean nullFieldIfValueIsTheSame; private final String undoText; /** * @param nullFieldIfValueIsTheSame - false also causes that doneTextPattern has two place holders %0 for the value and %1 for the sum of entries */ public SpecialFieldAction( JabRefFrame frame, SpecialField specialField, String value, boolean nullFieldIfValueIsTheSame, String undoText) { this.frame = frame; this.specialField = specialField; this.value = value; this.nullFieldIfValueIsTheSame = nullFieldIfValueIsTheSame; this.undoText = undoText; } @Override public void action() { try { List<BibEntry> bes = frame.getCurrentBasePanel().getSelectedEntries(); if ((bes == null) || bes.isEmpty()) { return; } NamedCompound ce = new NamedCompound(undoText); for (BibEntry be : bes) { // if (value==null) and then call nullField has been omitted as updatefield also handles value==null List<FieldChange> changes = SpecialFieldsUtils.updateField(specialField, value, be, nullFieldIfValueIsTheSame, Globals.prefs.isKeywordSyncEnabled(), Globals.prefs.getKeywordDelimiter()); for (FieldChange change: changes) { ce.addEdit(new UndoableFieldChange(change)); } } ce.end(); if (ce.hasEdits()) { frame.getCurrentBasePanel().getUndoManager().addEdit(ce); frame.getCurrentBasePanel().markBaseChanged(); frame.getCurrentBasePanel().updateEntryEditorIfShowing(); String outText; if (nullFieldIfValueIsTheSame || value == null) { outText = getTextDone(specialField, Integer.toString(bes.size())); } else { outText = getTextDone(specialField, value, Integer.toString(bes.size())); } frame.output(outText); } else { // if user does not change anything with his action, we do not do anything either // even no output message } } catch (Throwable ex) { LOGGER.error("Problem setting special fields", ex); } } private String getTextDone(SpecialField field, String... params) { Objects.requireNonNull(params); SpecialFieldViewModel viewModel = new SpecialFieldViewModel(field); if (field.isSingleValueField() && (params.length == 1) && (params[0] != null)) { // Single value fields can be toggled only return Localization.lang("Toggled '%0' for %1 entries", viewModel.getLocalization(), params[0]); } else if (!field.isSingleValueField() && (params.length == 2) && (params[0] != null) && (params[1] != null)) { // setting a multi value special field - the setted value is displayed, too String[] allParams = {viewModel.getLocalization(), params[0], params[1]}; return Localization.lang("Set '%0' to '%1' for %2 entries", allParams); } else if (!field.isSingleValueField() && (params.length == 1) && (params[0] != null)) { // clearing a multi value specialfield return Localization.lang("Cleared '%0' for %1 entries", viewModel.getLocalization(), params[0]); } else { // invalid usage LOGGER.info("Creation of special field status change message failed: illegal argument combination."); return ""; } } }