Skip to content
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

Refactor context menu entry types changing #8957

Merged
merged 3 commits into from
Jul 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 13 additions & 10 deletions src/main/java/org/jabref/gui/entryeditor/EntryEditor.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import javafx.scene.layout.BorderPane;

import org.jabref.gui.DialogService;
import org.jabref.gui.Globals;
import org.jabref.gui.LibraryTab;
import org.jabref.gui.StateManager;
import org.jabref.gui.citationkeypattern.GenerateCitationKeySingleAction;
Expand All @@ -39,6 +38,7 @@
import org.jabref.gui.help.HelpAction;
import org.jabref.gui.importer.GrobidOptInDialogHelper;
import org.jabref.gui.keyboard.KeyBinding;
import org.jabref.gui.keyboard.KeyBindingRepository;
import org.jabref.gui.menus.ChangeEntryTypeMenu;
import org.jabref.gui.mergeentries.FetchAndMergeEntry;
import org.jabref.gui.theme.ThemeManager;
Expand All @@ -50,6 +50,7 @@
import org.jabref.logic.importer.EntryBasedFetcher;
import org.jabref.logic.importer.WebFetchers;
import org.jabref.logic.importer.fileformat.PdfMergeMetadataImporter;
import org.jabref.logic.journals.JournalAbbreviationRepository;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.BibEntryTypesManager;
Expand Down Expand Up @@ -107,6 +108,8 @@ public class EntryEditor extends BorderPane {
@Inject private FileUpdateMonitor fileMonitor;
@Inject private CountingUndoManager undoManager;
@Inject private BibEntryTypesManager bibEntryTypesManager;
@Inject private KeyBindingRepository keyBindingRepository;
@Inject private JournalAbbreviationRepository journalAbbreviationRepository;

private final List<EntryEditorTab> entryEditorTabs = new LinkedList<>();

Expand Down Expand Up @@ -173,7 +176,7 @@ public EntryEditor(LibraryTab libraryTab, ExternalFileTypes externalFileTypes) {
*/
private void setupKeyBindings() {
this.addEventHandler(KeyEvent.KEY_PRESSED, event -> {
Optional<KeyBinding> keyBinding = Globals.getKeyPrefs().mapToKeyBinding(event);
Optional<KeyBinding> keyBinding = keyBindingRepository.mapToKeyBinding(event);
if (keyBinding.isPresent()) {
switch (keyBinding.get()) {
case ENTRY_EDITOR_NEXT_PANEL:
Expand Down Expand Up @@ -242,19 +245,19 @@ private List<EntryEditorTab> createTabs() {
entryEditorTabs.add(new PreviewTab(databaseContext, dialogService, preferencesService, stateManager, themeManager, libraryTab.getIndexingTaskManager(), ExternalFileTypes.getInstance()));

// Required fields
entryEditorTabs.add(new RequiredFieldsTab(databaseContext, libraryTab.getSuggestionProviders(), undoManager, dialogService, preferencesService, stateManager, themeManager, libraryTab.getIndexingTaskManager(), bibEntryTypesManager, ExternalFileTypes.getInstance(), taskExecutor, Globals.journalAbbreviationRepository));
entryEditorTabs.add(new RequiredFieldsTab(databaseContext, libraryTab.getSuggestionProviders(), undoManager, dialogService, preferencesService, stateManager, themeManager, libraryTab.getIndexingTaskManager(), bibEntryTypesManager, ExternalFileTypes.getInstance(), taskExecutor, journalAbbreviationRepository));

// Optional fields
entryEditorTabs.add(new OptionalFieldsTab(databaseContext, libraryTab.getSuggestionProviders(), undoManager, dialogService, preferencesService, stateManager, themeManager, libraryTab.getIndexingTaskManager(), bibEntryTypesManager, ExternalFileTypes.getInstance(), taskExecutor, Globals.journalAbbreviationRepository));
entryEditorTabs.add(new OptionalFields2Tab(databaseContext, libraryTab.getSuggestionProviders(), undoManager, dialogService, preferencesService, stateManager, themeManager, libraryTab.getIndexingTaskManager(), bibEntryTypesManager, ExternalFileTypes.getInstance(), taskExecutor, Globals.journalAbbreviationRepository));
entryEditorTabs.add(new DeprecatedFieldsTab(databaseContext, libraryTab.getSuggestionProviders(), undoManager, dialogService, preferencesService, stateManager, themeManager, libraryTab.getIndexingTaskManager(), bibEntryTypesManager, ExternalFileTypes.getInstance(), taskExecutor, Globals.journalAbbreviationRepository));
entryEditorTabs.add(new OptionalFieldsTab(databaseContext, libraryTab.getSuggestionProviders(), undoManager, dialogService, preferencesService, stateManager, themeManager, libraryTab.getIndexingTaskManager(), bibEntryTypesManager, ExternalFileTypes.getInstance(), taskExecutor, journalAbbreviationRepository));
entryEditorTabs.add(new OptionalFields2Tab(databaseContext, libraryTab.getSuggestionProviders(), undoManager, dialogService, preferencesService, stateManager, themeManager, libraryTab.getIndexingTaskManager(), bibEntryTypesManager, ExternalFileTypes.getInstance(), taskExecutor, journalAbbreviationRepository));
entryEditorTabs.add(new DeprecatedFieldsTab(databaseContext, libraryTab.getSuggestionProviders(), undoManager, dialogService, preferencesService, stateManager, themeManager, libraryTab.getIndexingTaskManager(), bibEntryTypesManager, ExternalFileTypes.getInstance(), taskExecutor, journalAbbreviationRepository));

// Other fields
entryEditorTabs.add(new OtherFieldsTab(databaseContext, libraryTab.getSuggestionProviders(), undoManager, dialogService, preferencesService, stateManager, themeManager, libraryTab.getIndexingTaskManager(), bibEntryTypesManager, ExternalFileTypes.getInstance(), taskExecutor, Globals.journalAbbreviationRepository));
entryEditorTabs.add(new OtherFieldsTab(databaseContext, libraryTab.getSuggestionProviders(), undoManager, dialogService, preferencesService, stateManager, themeManager, libraryTab.getIndexingTaskManager(), bibEntryTypesManager, ExternalFileTypes.getInstance(), taskExecutor, journalAbbreviationRepository));

// General fields from preferences
for (Map.Entry<String, Set<Field>> tab : entryEditorPreferences.getEntryEditorTabList().entrySet()) {
entryEditorTabs.add(new UserDefinedFieldsTab(tab.getKey(), tab.getValue(), databaseContext, libraryTab.getSuggestionProviders(), undoManager, dialogService, preferencesService, stateManager, themeManager, libraryTab.getIndexingTaskManager(), bibEntryTypesManager, ExternalFileTypes.getInstance(), taskExecutor, Globals.journalAbbreviationRepository));
entryEditorTabs.add(new UserDefinedFieldsTab(tab.getKey(), tab.getValue(), databaseContext, libraryTab.getSuggestionProviders(), undoManager, dialogService, preferencesService, stateManager, themeManager, libraryTab.getIndexingTaskManager(), bibEntryTypesManager, ExternalFileTypes.getInstance(), taskExecutor, journalAbbreviationRepository));
}

// Special tabs
Expand All @@ -271,7 +274,7 @@ private List<EntryEditorTab> createTabs() {
fileMonitor,
dialogService,
stateManager,
Globals.getKeyPrefs());
keyBindingRepository);
entryEditorTabs.add(sourceTab);

// LaTeX citations tab
Expand Down Expand Up @@ -361,7 +364,7 @@ private void setupToolBar() {
typeLabel.setText(typedEntry.getTypeForDisplay());

// Add type change menu
ContextMenu typeMenu = new ChangeEntryTypeMenu().getChangeEntryTypePopupMenu(Collections.singletonList(entry), databaseContext, undoManager);
ContextMenu typeMenu = new ChangeEntryTypeMenu(Collections.singletonList(entry), databaseContext, undoManager, keyBindingRepository, bibEntryTypesManager).asContextMenu();
typeLabel.setOnMouseClicked(event -> typeMenu.show(typeLabel, Side.RIGHT, 0, 0));
typeChangeButton.setOnMouseClicked(event -> typeMenu.show(typeChangeButton, Side.RIGHT, 0, 0));

Expand Down
3 changes: 2 additions & 1 deletion src/main/java/org/jabref/gui/maintable/MainTable.java
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ public MainTable(MainTableDataModel model,
preferencesService,
undoManager,
Globals.getClipboardManager(),
Globals.TASK_EXECUTOR))
Globals.TASK_EXECUTOR,
Globals.entryTypesManager))
.setOnDragDetected(this::handleOnDragDetected)
.setOnDragDropped(this::handleOnDragDropped)
.setOnDragOver(this::handleOnDragOver)
Expand Down
6 changes: 4 additions & 2 deletions src/main/java/org/jabref/gui/maintable/RightClickMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.jabref.gui.util.TaskExecutor;
import org.jabref.logic.citationstyle.CitationStyleOutputFormat;
import org.jabref.logic.citationstyle.CitationStylePreviewLayout;
import org.jabref.model.entry.BibEntryTypesManager;
import org.jabref.model.entry.field.SpecialField;
import org.jabref.preferences.PreferencesService;
import org.jabref.preferences.PreviewPreferences;
Expand All @@ -41,7 +42,8 @@ public static ContextMenu create(BibEntryTableViewModel entry,
PreferencesService preferencesService,
UndoManager undoManager,
ClipBoardManager clipBoardManager,
TaskExecutor taskExecutor) {
TaskExecutor taskExecutor,
BibEntryTypesManager entryTypesManager) {
ActionFactory factory = new ActionFactory(keyBindingRepository);
ContextMenu contextMenu = new ContextMenu();

Expand Down Expand Up @@ -76,7 +78,7 @@ public static ContextMenu create(BibEntryTableViewModel entry,

new SeparatorMenuItem(),

new ChangeEntryTypeMenu().getChangeEntryTypeMenu(libraryTab.getSelectedEntries(), libraryTab.getBibDatabaseContext(), libraryTab.getUndoManager()),
new ChangeEntryTypeMenu(libraryTab.getSelectedEntries(), libraryTab.getBibDatabaseContext(), libraryTab.getUndoManager(), keyBindingRepository, entryTypesManager).asSubMenu(),
factory.createMenuItem(StandardActions.MERGE_WITH_FETCHED_ENTRY, new MergeWithFetchedEntryAction(libraryTab, dialogService, stateManager))
);

Expand Down
49 changes: 49 additions & 0 deletions src/main/java/org/jabref/gui/menus/ChangeEntryTypeAction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package org.jabref.gui.menus;

import java.util.List;

import javax.swing.undo.UndoManager;

import javafx.beans.property.ReadOnlyStringProperty;
import javafx.beans.property.ReadOnlyStringWrapper;

import org.jabref.gui.EntryTypeView;
import org.jabref.gui.actions.SimpleCommand;
import org.jabref.gui.undo.NamedCompound;
import org.jabref.gui.undo.UndoableChangeType;
import org.jabref.logic.l10n.Localization;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.types.EntryType;

public class ChangeEntryTypeAction extends SimpleCommand {

private final EntryType type;
private final List<BibEntry> entries;
private final UndoManager undoManager;
private final ReadOnlyStringWrapper statusMessageProperty;

public ChangeEntryTypeAction(EntryType type, List<BibEntry> entries, UndoManager undoManager) {
this.type = type;
this.entries = entries;
this.undoManager = undoManager;
this.statusMessageProperty = new ReadOnlyStringWrapper(EntryTypeView.getDescription(type));
}

@Override
public void execute() {
NamedCompound compound = new NamedCompound(Localization.lang("Change entry type"));
entries.forEach(e -> e.setType(type)
.ifPresent(change -> compound.addEdit(new UndoableChangeType(change))));
undoManager.addEdit(compound);
}

@Override
public String getStatusMessage() {
return statusMessage.get();
}

@Override
public ReadOnlyStringProperty statusMessageProperty() {
return statusMessageProperty.getReadOnlyProperty();
}
}
112 changes: 60 additions & 52 deletions src/main/java/org/jabref/gui/menus/ChangeEntryTypeMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,103 +2,111 @@

import java.util.Collection;
import java.util.List;
import java.util.Optional;

import javax.swing.undo.UndoManager;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.CustomMenuItem;
import javafx.scene.control.Label;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.SeparatorMenuItem;
import javafx.scene.control.Tooltip;

import org.jabref.gui.EntryTypeView;
import org.jabref.gui.Globals;
import org.jabref.gui.undo.CountingUndoManager;
import org.jabref.gui.undo.NamedCompound;
import org.jabref.gui.undo.UndoableChangeType;
import org.jabref.gui.actions.ActionFactory;
import org.jabref.gui.keyboard.KeyBindingRepository;
import org.jabref.logic.l10n.Localization;
import org.jabref.model.database.BibDatabaseContext;
import org.jabref.model.database.BibDatabaseMode;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.BibEntryType;
import org.jabref.model.entry.BibEntryTypesManager;
import org.jabref.model.entry.types.BibtexEntryTypeDefinitions;
import org.jabref.model.entry.types.EntryType;
import org.jabref.model.entry.types.IEEETranEntryTypeDefinitions;
import org.jabref.model.strings.StringUtil;

public class ChangeEntryTypeMenu {

public ChangeEntryTypeMenu() {
private final List<BibEntry> entries;
private final BibDatabaseContext bibDatabaseContext;
private final UndoManager undoManager;
private final ActionFactory factory;
private final BibEntryTypesManager entryTypesManager;

public ChangeEntryTypeMenu(List<BibEntry> entries,
BibDatabaseContext bibDatabaseContext,
UndoManager undoManager,
KeyBindingRepository keyBindingRepository,
BibEntryTypesManager entryTypesManager) {
this.entries = entries;
this.bibDatabaseContext = bibDatabaseContext;
this.undoManager = undoManager;
this.entryTypesManager = entryTypesManager;
this.factory = new ActionFactory(keyBindingRepository);
}

public static MenuItem createMenuItem(EntryType type, List<BibEntry> entries, UndoManager undoManager) {
CustomMenuItem menuItem = new CustomMenuItem(new Label(type.getDisplayName()));
menuItem.setOnAction(event -> {
NamedCompound compound = new NamedCompound(Localization.lang("Change entry type"));
entries.forEach(e -> e.setType(type)
.ifPresent(change -> compound.addEdit(new UndoableChangeType(change))));
undoManager.addEdit(compound);
});
String description = EntryTypeView.getDescription(type);
if (StringUtil.isNotBlank(description)) {
Tooltip tooltip = new Tooltip(description);
Tooltip.install(menuItem.getContent(), tooltip);
}
return menuItem;
}

public ContextMenu getChangeEntryTypePopupMenu(List<BibEntry> entries, BibDatabaseContext bibDatabaseContext, CountingUndoManager undoManager) {
public ContextMenu asContextMenu() {
ContextMenu menu = new ContextMenu();
populateComplete(menu.getItems(), entries, bibDatabaseContext, undoManager);
menu.getItems().setAll(getMenuItems(entries, bibDatabaseContext, undoManager));
return menu;
}

public Menu getChangeEntryTypeMenu(List<BibEntry> entries, BibDatabaseContext bibDatabaseContext, CountingUndoManager undoManager) {
Menu menu = new Menu();
menu.setText(Localization.lang("Change entry type"));
populateComplete(menu.getItems(), entries, bibDatabaseContext, undoManager);
public Menu asSubMenu() {
Menu menu = new Menu(Localization.lang("Change entry type"));
menu.getItems().setAll(getMenuItems(entries, bibDatabaseContext, undoManager));
return menu;
}

private void populateComplete(ObservableList<MenuItem> items, List<BibEntry> entries, BibDatabaseContext bibDatabaseContext, CountingUndoManager undoManager) {
private ObservableList<MenuItem> getMenuItems(List<BibEntry> entries, BibDatabaseContext bibDatabaseContext, UndoManager undoManager) {
ObservableList<MenuItem> items = FXCollections.observableArrayList();

if (bibDatabaseContext.isBiblatexMode()) {
// Default BibLaTeX
populate(items, Globals.entryTypesManager.getAllTypes(BibDatabaseMode.BIBLATEX), entries, undoManager);
items.addAll(fromEntryTypes(entryTypesManager.getAllTypes(BibDatabaseMode.BIBLATEX), entries, undoManager));

// Custom types
populateSubMenu(items, Localization.lang("Custom"), Globals.entryTypesManager.getAllCustomTypes(BibDatabaseMode.BIBLATEX), entries, undoManager);
createSubMenu(Localization.lang("Custom"), entryTypesManager.getAllCustomTypes(BibDatabaseMode.BIBLATEX), entries, undoManager)
.ifPresent(subMenu ->
items.addAll(new SeparatorMenuItem(),
subMenu
));
} else {
// Default BibTeX
populateSubMenu(items, BibDatabaseMode.BIBTEX.getFormattedName(), BibtexEntryTypeDefinitions.ALL, entries, undoManager);
items.remove(0); // Remove separator
createSubMenu(BibDatabaseMode.BIBTEX.getFormattedName(), BibtexEntryTypeDefinitions.ALL, entries, undoManager)
.ifPresent(items::add);

// IEEETran
populateSubMenu(items, "IEEETran", IEEETranEntryTypeDefinitions.ALL, entries, undoManager);
createSubMenu("IEEETran", IEEETranEntryTypeDefinitions.ALL, entries, undoManager)
.ifPresent(subMenu -> items.addAll(
new SeparatorMenuItem(),
subMenu
));

// Custom types
populateSubMenu(items, Localization.lang("Custom"), Globals.entryTypesManager.getAllCustomTypes(BibDatabaseMode.BIBTEX), entries, undoManager);
createSubMenu(Localization.lang("Custom"), entryTypesManager.getAllCustomTypes(BibDatabaseMode.BIBTEX), entries, undoManager)
.ifPresent(subMenu -> items.addAll(
new SeparatorMenuItem(),
subMenu
));
}

return items;
}

private void populateSubMenu(ObservableList<MenuItem> items, String text, List<BibEntryType> entryTypes, List<BibEntry> entries, CountingUndoManager undoManager) {
private Optional<Menu> createSubMenu(String text, List<BibEntryType> entryTypes, List<BibEntry> entries, UndoManager undoManager) {
Menu subMenu = null;

if (!entryTypes.isEmpty()) {
items.add(new SeparatorMenuItem());
Menu custom = new Menu(text);
populate(custom, entryTypes, entries, undoManager);
items.add(custom);
subMenu = factory.createMenu(() -> text);
subMenu.getItems().addAll(fromEntryTypes(entryTypes, entries, undoManager));
}
}

private void populate(ObservableList<MenuItem> items, Collection<BibEntryType> types, List<BibEntry> entries, UndoManager undoManager) {
for (BibEntryType type : types) {
items.add(createMenuItem(type.getType(), entries, undoManager));
}
return Optional.ofNullable(subMenu);
}

private void populate(Menu menu, Collection<BibEntryType> types, List<BibEntry> entries, UndoManager undoManager) {
populate(menu.getItems(), types, entries, undoManager);
private List<MenuItem> fromEntryTypes(Collection<BibEntryType> types, List<BibEntry> entries, UndoManager undoManager) {
return types.stream()
.map(BibEntryType::getType)
.map(type -> factory.createMenuItem(type::getDisplayName, new ChangeEntryTypeAction(type, entries, undoManager)))
.toList();
}
}