package org.jabref.gui.actions;

import java.util.List;

import org.jabref.Globals;
import org.jabref.gui.BasePanel;
import org.jabref.gui.DialogService;
import org.jabref.gui.undo.NamedCompound;
import org.jabref.gui.undo.UndoableKeyChange;
import org.jabref.gui.util.BackgroundTask;
import org.jabref.logic.bibtexkeypattern.BibtexKeyGenerator;
import org.jabref.logic.l10n.Localization;
import org.jabref.model.entry.BibEntry;
import org.jabref.preferences.JabRefPreferences;

public class GenerateBibtexKeyAction implements BaseAction {
    private final DialogService dialogService;
    private BasePanel basePanel;
    private List<BibEntry> entries;
    private boolean isCanceled;

    public GenerateBibtexKeyAction(BasePanel basePanel, DialogService dialogService) {
        this.basePanel = basePanel;
        this.dialogService = dialogService;
    }

    public void init() {
        entries = basePanel.getSelectedEntries();

        if (entries.isEmpty()) {
            dialogService.showWarningDialogAndWait(Localization.lang("Autogenerate BibTeX keys"),
                    Localization.lang("First select the entries you want keys to be generated for."));
            return;
        }
        basePanel.output(formatOutputMessage(Localization.lang("Generating BibTeX key for"), entries.size()));
    }

    public static boolean confirmOverwriteKeys(DialogService dialogService) {
        if (Globals.prefs.getBoolean(JabRefPreferences.WARN_BEFORE_OVERWRITING_KEY)) {
            return dialogService.showConfirmationDialogWithOptOutAndWait(
                    Localization.lang("Overwrite keys"),
                    Localization.lang("One or more keys will be overwritten. Continue?"),
                    Localization.lang("Overwrite keys"),
                    Localization.lang("Cancel"),
                    Localization.lang("Disable this confirmation dialog"),
                    optOut -> Globals.prefs.putBoolean(JabRefPreferences.WARN_BEFORE_OVERWRITING_KEY, !optOut));
        } else {
            // Always overwrite keys by default
            return true;
        }
    }

    private void generateKeys() {
        // We don't want to generate keys for entries which already have one thus remove the entries
        if (Globals.prefs.getBoolean(JabRefPreferences.AVOID_OVERWRITING_KEY)) {
            entries.removeIf(BibEntry::hasCiteKey);
            // if we're going to override some cite keys warn the user about it
        } else if (entries.parallelStream().anyMatch(BibEntry::hasCiteKey)) {
            boolean overwriteKeys = confirmOverwriteKeys(dialogService);

            // The user doesn't want to override cite keys
            if (!overwriteKeys) {
                isCanceled = true;
                return;
            }
        }

        // generate the new cite keys for each entry
        final NamedCompound compound = new NamedCompound(Localization.lang("Autogenerate BibTeX keys"));
        BibtexKeyGenerator keyGenerator = new BibtexKeyGenerator(basePanel.getBibDatabaseContext(), Globals.prefs.getBibtexKeyPatternPreferences());
        for (BibEntry entry : entries) {
            keyGenerator.generateAndSetKey(entry)
                        .ifPresent(fieldChange -> compound.addEdit(new UndoableKeyChange(fieldChange)));
        }
        compound.end();

        // register the undo event only if new cite keys were generated
        if (compound.hasEdits()) {
            basePanel.getUndoManager().addEdit(compound);
        }

        if (isCanceled) {
            return;
        }
        basePanel.markBaseChanged();
        basePanel.output(formatOutputMessage(Localization.lang("Generated BibTeX key for"), entries.size()));
    }

    private String formatOutputMessage(String start, int count) {
        return String.format("%s %d %s.", start, count,
                (count > 1 ? Localization.lang("entries") : Localization.lang("entry")));
    }

    @Override
    public void action() {
        init();
        BackgroundTask.wrap(this::generateKeys)
                      .executeWith(Globals.TASK_EXECUTOR);
    }
}

@@ -533,16 +533,17 @@
 ction %7B%0A
+%0A
     priv
@@ -593,16 +593,22 @@
 private 
+final 
 BasePane
@@ -1062,32 +1062,63 @@
  BibTeX keys%22),%0A
+                               
                 
@@ -1591,16 +1591,69 @@
 ndWait(%0A
+                                                     
         
@@ -1693,32 +1693,85 @@
 erwrite keys%22),%0A
+                                                     
                 
@@ -1840,24 +1840,77 @@
 ontinue?%22),%0A
+                                                     
             
@@ -1946,32 +1946,85 @@
 erwrite keys%22),%0A
+                                                     
                 
@@ -2052,24 +2052,77 @@
 (%22Cancel%22),%0A
+                                                     
             
@@ -2180,24 +2180,77 @@
 n dialog%22),%0A
+                                                     
             
@@ -2346,24 +2346,25 @@
  !optOut));%0A
+%0A
         %7D el
@@ -2475,28 +2475,40 @@
 te void 
-generateKeys
+checkOverwriteKeysChosen
 () %7B%0A   
@@ -3138,32 +3138,128 @@
     %7D%0A        %7D%0A
+    %7D%0A%0A    private void generateKeys() %7B%0A        if (isCanceled) %7B%0A            return;%0A        %7D
 %0A        // gene
@@ -3961,64 +3961,8 @@
  %7D%0A%0A
-        if (isCanceled) %7B%0A            return;%0A        %7D%0A
     
@@ -4249,16 +4249,29 @@
         
+             
 (count %3E
@@ -4396,24 +4396,60 @@
     init();%0A
+        checkOverwriteKeysChosen();%0A
         Back

Fix generate bibtex key overwrite warning dialog (#4418)