Skip to content

Fix for issue #2721 append to a field #3395

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#
- We increased performance and decreased the memory footprint of the entry editor drastically. [#3331](https://github.com/JabRef/jabref/pull/3331)
- Late initialization of the context menus in the entry editor. This improves performance and memory footprint further [#3340](https://github.com/JabRef/jabref/pull/3340)
- We added a dialog to show that JabRef is working on checking integrity. [#3358](https://github.com/JabRef/jabref/issues/3358)
- We added an option to mass append to fields via the Quality -> set/clear/append/rename fields dialog. [#2721](https://github.com/JabRef/jabref/issues/2721)

### Fixed
- We fixed the translation of \textendash in the entry preview [#3307](https://github.com/JabRef/jabref/issues/3307)
Expand Down
129 changes: 88 additions & 41 deletions src/main/java/org/jabref/gui/actions/MassSetFieldAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,28 +53,32 @@ public class MassSetFieldAction extends MnemonicAwareAction {
private JRadioButton selected;
private JRadioButton clear;
private JRadioButton set;
private JRadioButton append;
private JRadioButton rename;
private JComboBox<String> field;
private JTextField text;
private JTextField renameTo;
private JTextField textFieldSet;
private JTextField textFieldAppend;
private JTextField textFieldRename;
private boolean canceled = true;
private JCheckBox overwrite;


public MassSetFieldAction(JabRefFrame frame) {
putValue(Action.NAME, Localization.menuTitle("Set/clear/rename fields") + "...");
putValue(Action.NAME, Localization.menuTitle("Set/clear/append/rename fields") + "...");
this.frame = frame;
}

private void createDialog() {
diag = new JDialog(frame, Localization.lang("Set/clear/rename fields"), true);
diag = new JDialog(frame, Localization.lang("Set/clear/append/rename fields"), true);

field = new JComboBox<>();
field.setEditable(true);
text = new JTextField();
text.setEnabled(false);
renameTo = new JTextField();
renameTo.setEnabled(false);
textFieldSet = new JTextField();
textFieldSet.setEnabled(false);
textFieldAppend = new JTextField();
textFieldAppend.setEnabled(false);
textFieldRename = new JTextField();
textFieldRename.setEnabled(false);

JButton ok = new JButton(Localization.lang("OK"));
JButton cancel = new JButton(Localization.lang("Cancel"));
Expand All @@ -83,6 +87,7 @@ private void createDialog() {
selected = new JRadioButton(Localization.lang("Selected entries"));
clear = new JRadioButton(Localization.lang("Clear fields"));
set = new JRadioButton(Localization.lang("Set fields"));
append = new JRadioButton(Localization.lang("Append to fields"));
rename = new JRadioButton(Localization.lang("Rename field to") + ":");
rename.setToolTipText(Localization.lang("Move contents of a field into a field with a different name"));

Expand All @@ -93,16 +98,23 @@ private void createDialog() {
}

set.addChangeListener(e ->
// Entering a text is only relevant if we are setting, not clearing:
text.setEnabled(set.isSelected()));
// Entering a setText is only relevant if we are setting, not clearing:
textFieldSet.setEnabled(set.isSelected()));

append.addChangeListener(e -> {
// Text to append is only required if we are appending:
textFieldAppend.setEnabled(append.isSelected());
// Overwrite protection makes no sense if we are appending to a field:
overwrite.setEnabled(!clear.isSelected() && !append.isSelected());
});

clear.addChangeListener(e ->
// Overwrite protection makes no sense if we are clearing the field:
overwrite.setEnabled(!clear.isSelected()));
// Overwrite protection makes no sense if we are clearing the field:
overwrite.setEnabled(!clear.isSelected() && !append.isSelected()));

rename.addChangeListener(e ->
// Entering a text is only relevant if we are renaming
renameTo.setEnabled(rename.isSelected()));
// Entering a setText is only relevant if we are renaming
textFieldRename.setEnabled(rename.isSelected()));

overwrite = new JCheckBox(Localization.lang("Overwrite existing field values"), true);
ButtonGroup bg = new ButtonGroup();
Expand All @@ -111,9 +123,10 @@ private void createDialog() {
bg = new ButtonGroup();
bg.add(clear);
bg.add(set);
bg.add(append);
bg.add(rename);
FormBuilder builder = FormBuilder.create().layout(new FormLayout(
"left:pref, 4dlu, fill:100dlu:grow", "pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref"));
"left:pref, 4dlu, fill:100dlu:grow", "pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref, 2dlu, pref"));
builder.addSeparator(Localization.lang("Field name")).xyw(1, 1, 3);
builder.add(Localization.lang("Field name")).xy(1, 3);
builder.add(field).xy(3, 3);
Expand All @@ -122,11 +135,13 @@ private void createDialog() {
builder.add(selected).xyw(1, 9, 3);
builder.addSeparator(Localization.lang("New field value")).xyw(1, 11, 3);
builder.add(set).xy(1, 13);
builder.add(text).xy(3, 13);
builder.add(textFieldSet).xy(3, 13);
builder.add(clear).xyw(1, 15, 3);
builder.add(rename).xy(1, 17);
builder.add(renameTo).xy(3, 17);
builder.add(overwrite).xyw(1, 19, 3);
builder.add(append).xy(1, 17);
builder.add(textFieldAppend).xy(3, 17);
builder.add(rename).xy(1, 19);
builder.add(textFieldRename).xy(3, 19);
builder.add(overwrite).xyw(1, 21, 3);

ButtonBarBuilder bb = new ButtonBarBuilder();
bb.addGlue();
Expand Down Expand Up @@ -219,31 +234,36 @@ public void actionPerformed(ActionEvent e) {
} else {
entryList = entries;
}
String toSet = text.getText();

String toSet = textFieldSet.getText();
if (toSet.isEmpty()) {
toSet = null;
}

String[] fields = getFieldNames(((String) field.getSelectedItem()).trim().toLowerCase(Locale.ROOT));
NamedCompound ce = new NamedCompound(Localization.lang("Set field"));
NamedCompound compoundEdit = new NamedCompound(Localization.lang("Set field"));
if (rename.isSelected()) {
if (fields.length > 1) {
JOptionPane.showMessageDialog(diag, Localization.lang("You can only rename one field at a time"), "",
JOptionPane.ERROR_MESSAGE);
return; // Do not close the dialog.
} else {
ce.addEdit(MassSetFieldAction.massRenameField(entryList, fields[0], renameTo.getText(),
compoundEdit.addEdit(MassSetFieldAction.massRenameField(entryList, fields[0], textFieldRename.getText(),
overwrite.isSelected()));
}
} else if (append.isSelected()) {
for (String field : fields) {
compoundEdit.addEdit(MassSetFieldAction.massAppendField(entryList, field, textFieldAppend.getText()));
}
} else {
for (String field1 : fields) {
ce.addEdit(MassSetFieldAction.massSetField(entryList, field1,
for (String field : fields) {
compoundEdit.addEdit(MassSetFieldAction.massSetField(entryList, field,
set.isSelected() ? toSet : null,
overwrite.isSelected()));
}
}
ce.end();
bp.getUndoManager().addEdit(ce);
compoundEdit.end();
bp.getUndoManager().addEdit(compoundEdit);
bp.markBaseChanged();
}

Expand All @@ -253,31 +273,58 @@ public void actionPerformed(ActionEvent e) {
*
* @param entries The entries to set the field for.
* @param field The name of the field to set.
* @param text The value to set. This value can be null, indicating that the field should be cleared.
* @param textToSet The value to set. This value can be null, indicating that the field should be cleared.
* @param overwriteValues Indicate whether the value should be set even if an entry already has the field set.
* @return A CompoundEdit for the entire operation.
*/
private static UndoableEdit massSetField(Collection<BibEntry> entries, String field, String text,
private static UndoableEdit massSetField(Collection<BibEntry> entries, String field, String textToSet,
boolean overwriteValues) {

NamedCompound ce = new NamedCompound(Localization.lang("Set field"));
NamedCompound compoundEdit = new NamedCompound(Localization.lang("Set field"));
for (BibEntry entry : entries) {
Optional<String> oldVal = entry.getField(field);
Optional<String> oldValue = entry.getField(field);
// If we are not allowed to overwrite values, check if there is a
// nonempty
// value already for this entry:
if (!overwriteValues && (oldVal.isPresent()) && !oldVal.get().isEmpty()) {
if (!overwriteValues && (oldValue.isPresent()) && !oldValue.get().isEmpty()) {
continue;
}
if (text == null) {
if (textToSet == null) {
entry.clearField(field);
} else {
entry.setField(field, text);
entry.setField(field, textToSet);
}
ce.addEdit(new UndoableFieldChange(entry, field, oldVal.orElse(null), text));
compoundEdit.addEdit(new UndoableFieldChange(entry, field, oldValue.orElse(null), textToSet));
}
compoundEdit.end();
return compoundEdit;
}

/**
* Append a given value to a given field for all entries in a Collection. This method DOES NOT update any UndoManager,
* but returns a relevant CompoundEdit that should be registered by the caller.
*
* @param entries The entries to process the operation for.
* @param field The name of the field to append to.
* @param textToAppend The value to set. A null in this case will simply preserve the current field state.
* @return A CompoundEdit for the entire operation.
*/
private static UndoableEdit massAppendField(Collection<BibEntry> entries, String field, String textToAppend) {

String newValue = "";

if (textToAppend != null) {
newValue = textToAppend;
}

NamedCompound compoundEdit = new NamedCompound(Localization.lang("Append field"));
for (BibEntry entry : entries) {
Optional<String> oldValue = entry.getField(field);
entry.setField(field, oldValue.orElse("") + newValue);
compoundEdit.addEdit(new UndoableFieldChange(entry, field, oldValue.orElse(null), newValue));
}
ce.end();
return ce;
compoundEdit.end();
return compoundEdit;
}

/**
Expand All @@ -292,7 +339,7 @@ private static UndoableEdit massSetField(Collection<BibEntry> entries, String fi
*/
private static UndoableEdit massRenameField(Collection<BibEntry> entries, String field, String newField,
boolean overwriteValues) {
NamedCompound ce = new NamedCompound(Localization.lang("Rename field"));
NamedCompound compoundEdit = new NamedCompound(Localization.lang("Rename field"));
for (BibEntry entry : entries) {
Optional<String> valToMove = entry.getField(field);
// If there is no value, do nothing:
Expand All @@ -307,12 +354,12 @@ private static UndoableEdit massRenameField(Collection<BibEntry> entries, String
}

entry.setField(newField, valToMove.get());
ce.addEdit(new UndoableFieldChange(entry, newField, valInNewField.orElse(null), valToMove.get()));
compoundEdit.addEdit(new UndoableFieldChange(entry, newField, valInNewField.orElse(null), valToMove.get()));
entry.clearField(field);
ce.addEdit(new UndoableFieldChange(entry, field, valToMove.get(), null));
compoundEdit.addEdit(new UndoableFieldChange(entry, field, valToMove.get(), null));
}
ce.end();
return ce;
compoundEdit.end();
return compoundEdit;
}

private static String[] getFieldNames(String s) {
Expand Down
4 changes: 3 additions & 1 deletion src/main/resources/l10n/JabRef_da.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1375,7 +1375,9 @@ Full_text_document_download_failed=Download_af_fuldtekst-dokument_mislykkedes
Update_to_current_column_order=Brug_nuværende_kolonnerækkefølge
Download_from_URL=
Rename_field=Omdøb_felt
Set/clear/rename_fields=Sæt/ryd/omdøb_felter
Set/clear/append/rename_fields=Sæt/ryd/omdøb_felter
Append_field=
Append_to_fields=
Rename_field_to=Omdøb_felt_til
Move_contents_of_a_field_into_a_field_with_a_different_name=Flyt_indhold_af_et_felt_til_et_felt_med_et_andet_navn
You_can_only_rename_one_field_at_a_time=Du_kan_kun_omdøbe_et_felt_ad_gangen
Expand Down
4 changes: 3 additions & 1 deletion src/main/resources/l10n/JabRef_de.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1375,7 +1375,9 @@ Full_text_document_download_failed=Herunterladen_des_Volltext-Beitrags_fehlgesch
Update_to_current_column_order=Aktuelle_Spaltenanordnung_verwenden
Download_from_URL=Download_von_URL
Rename_field=Feld_umbenennen
Set/clear/rename_fields=Felder_setzen/löschen/umbenennen
Set/clear/append/rename_fields=Felder_setzen/löschen/umbenennen
Append_field=
Append_to_fields=
Rename_field_to=Feld_umbenennen
Move_contents_of_a_field_into_a_field_with_a_different_name=Inhalt_eines_Felds_in_ein_Feld_mit_anderem_Namen_verschieben
You_can_only_rename_one_field_at_a_time=Sie_können_nur_eine_Datei_auf_einmal_umbenennen
Expand Down
4 changes: 3 additions & 1 deletion src/main/resources/l10n/JabRef_el.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1375,7 +1375,9 @@ Full_text_document_download_failed=
Update_to_current_column_order=
Download_from_URL=
Rename_field=
Set/clear/rename_fields=
Set/clear/append/rename_fields=Ρύθμιση/καθαρισμός/μετονομασία_πεδίων
Append_field=
Append_to_fields=
Rename_field_to=
Move_contents_of_a_field_into_a_field_with_a_different_name=
You_can_only_rename_one_field_at_a_time=
Expand Down
4 changes: 3 additions & 1 deletion src/main/resources/l10n/JabRef_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1375,7 +1375,9 @@ Full_text_document_download_failed=Full_text_document_download_failed
Update_to_current_column_order=Update_to_current_column_order
Download_from_URL=Download_from_URL
Rename_field=Rename_field
Set/clear/rename_fields=Set/clear/rename_fields
Set/clear/append/rename_fields=Set/clear/append/rename_fields
Append_field=Append_field
Append_to_fields=Append_to_fields
Rename_field_to=Rename_field_to
Move_contents_of_a_field_into_a_field_with_a_different_name=Move_contents_of_a_field_into_a_field_with_a_different_name
You_can_only_rename_one_field_at_a_time=You_can_only_rename_one_field_at_a_time
Expand Down
4 changes: 3 additions & 1 deletion src/main/resources/l10n/JabRef_es.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1375,7 +1375,9 @@ Full_text_document_download_failed=Falló_la_descarga_del_texto_completo_del_art
Update_to_current_column_order=Actualizar_al_orden_de_columnas_actual
Download_from_URL=Descargar_desde_URL
Rename_field=Renombrar_campo
Set/clear/rename_fields=Establecer/limpiar/renombrar_campos
Set/clear/append/rename_fields=Establecer/limpiar/renombrar_campos
Append_field=
Append_to_fields=
Rename_field_to=Renombrar_campo_a
Move_contents_of_a_field_into_a_field_with_a_different_name=Mover_contenidos_de_un_campo_en_un_campo_con_nombre_diferente
You_can_only_rename_one_field_at_a_time=Sólo_puede_renombrar_un_campo_a_la_vez
Expand Down
4 changes: 3 additions & 1 deletion src/main/resources/l10n/JabRef_fa.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1375,7 +1375,9 @@ Full_text_document_download_failed=
Update_to_current_column_order=
Download_from_URL=
Rename_field=
Set/clear/rename_fields=
Set/clear/append/rename_fields=تنظیم/حذف/تغییرنام_حوزه‌ها
Append_field=
Append_to_fields=
Rename_field_to=
Move_contents_of_a_field_into_a_field_with_a_different_name=
You_can_only_rename_one_field_at_a_time=
Expand Down
5 changes: 3 additions & 2 deletions src/main/resources/l10n/JabRef_fr.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1375,7 +1375,9 @@ Full_text_document_download_failed=Echec_du_téléchargement_du_document_cité
Update_to_current_column_order=Enregistrer_l'ordre_actuel_des_colonnes
Download_from_URL=Télécharger_depuis_l'URL
Rename_field=Renommer_le_champ
Set/clear/rename_fields=Définir/vider/renommer_les_champs
Set/clear/append/rename_fields=Définir/vider/renommer_les_champs
Append_field=
Append_to_fields=
Rename_field_to=Renommer_le_champ_en
Move_contents_of_a_field_into_a_field_with_a_different_name=Déplacer_le_contenu_d'un_champ_vers_un_champ_d'un_nom_différent
You_can_only_rename_one_field_at_a_time=Vou_pouvez_supprimer_uniquement_un_champ_à_la_fois
Expand Down Expand Up @@ -2341,7 +2343,6 @@ Copying_file_%0_of_entry_%1=
Finished_copying=
Could_not_copy_file=
Copied_%0_files_of_%1_sucessfully_to_%2==

Rename_failed=Échec_du_renommage
JabRef_cannot_access_the_file_because_it_is_being_used_by_another_process.=JabRef_ne_peut_pas_accéder_au_fichier_parce_qu'il_est_utilisé_par_un_autre_processus.
Show_console_output_(only_necessary_when_the_launcher_is_used)=Afficher_la_sortie_de_la_console_(uniquement_nécessaire_quand_le_lanceur_est_utilisé)
Expand Down
4 changes: 3 additions & 1 deletion src/main/resources/l10n/JabRef_in.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1375,7 +1375,9 @@ Full_text_document_download_failed=Gagal_muaturun_artikel_teks_lengkap
Update_to_current_column_order=Perbarui_sebuai_urutan_kolom_sekarang
Download_from_URL=
Rename_field=Ganti_nama_bidang
Set/clear/rename_fields=Pilih/hapus/namai_ulang_bidang
Set/clear/append/rename_fields=Pilih/hapus/namai_ulang_bidang
Append_field=
Append_to_fields=
Rename_field_to=Ganti_nama_bidang_menjadi
Move_contents_of_a_field_into_a_field_with_a_different_name=Pindah_isi_dari_bidang_ke_bidang_lain_dengan_nama_lain
You_can_only_rename_one_field_at_a_time=Anda_bisa_mengganti_nama_satu_bidang_dalam_satu_waktu
Expand Down
4 changes: 3 additions & 1 deletion src/main/resources/l10n/JabRef_it.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1375,7 +1375,9 @@ Full_text_document_download_failed=Fallito_il_download_del_documento_citato
Update_to_current_column_order=Salvare_l'ordine_delle_colonne_attuale
Download_from_URL=Scarica_dall'URL
Rename_field=Rinomina_il_campo
Set/clear/rename_fields=Imposta/svuota/rinomina_i_campi
Set/clear/append/rename_fields=Imposta/svuota/rinomina_i_campi
Append_field=
Append_to_fields=
Rename_field_to=Rinomina_il_campo_in
Move_contents_of_a_field_into_a_field_with_a_different_name=Sposta_il_contenuto_di_un_campo_in_un_campo_con_nome_diverso
You_can_only_rename_one_field_at_a_time=È_possibile_rinominare_solo_un_campo_per_volta
Expand Down
4 changes: 3 additions & 1 deletion src/main/resources/l10n/JabRef_ja.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1375,7 +1375,9 @@ Full_text_document_download_failed=論文本体のダウンロードに失敗し
Update_to_current_column_order=現在の列順に更新
Download_from_URL=URLからダウンロード
Rename_field=フィールドを改名しました
Set/clear/rename_fields=フィールドを設定/消去/名称変更
Set/clear/append/rename_fields=フィールドを設定/消去/名称変更
Append_field=
Append_to_fields=
Rename_field_to=フィールド名を以下に変更
Move_contents_of_a_field_into_a_field_with_a_different_name=フィールドの内容を別名のフィールドに移動する
You_can_only_rename_one_field_at_a_time=一度に改名できるのはひとつのフィールドだけです
Expand Down
4 changes: 3 additions & 1 deletion src/main/resources/l10n/JabRef_nl.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1375,7 +1375,9 @@ Full_text_document_download_failed=
Update_to_current_column_order=
Download_from_URL=
Rename_field=
Set/clear/rename_fields=
Set/clear/append/rename_fields=Instellen/wissen/hernoemen_van_velden
Append_field=
Append_to_fields=
Rename_field_to=
Move_contents_of_a_field_into_a_field_with_a_different_name=
You_can_only_rename_one_field_at_a_time=
Expand Down
4 changes: 3 additions & 1 deletion src/main/resources/l10n/JabRef_no.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1375,7 +1375,9 @@ Full_text_document_download_failed=Kunne_ikke_laste_ned_fulltekstdokument
Update_to_current_column_order=Oppdater_til_n\u00e5v\u00e6rende_rekkef\u00b8lge_p\u00e5_kolonner
Download_from_URL=
Rename_field=Endre_navn_p\u00e5_felt
Set/clear/rename_fields=Sett/slett/endre_navn_p\u00e5_felt
Set/clear/append/rename_fields=Sett/slett/endre_navn_p\u00e5_felt
Append_field=
Append_to_fields=
Rename_field_to=Endre_navn_p\u00e5_felt_til
Move_contents_of_a_field_into_a_field_with_a_different_name=Flytt_innholdet_i_et_felt_til_et_annet_felt
You_can_only_rename_one_field_at_a_time=Du_kan_bare_endre_navn_p\u00e5_ett_felt_av_gangen
Expand Down
Loading